diff --git a/.ci.yaml b/.ci.yaml index 2ddc8a1cca69..94780f2513cb 100644 --- a/.ci.yaml +++ b/.ci.yaml @@ -31,7 +31,7 @@ platform_properties: {"dependency": "android_sdk", "version": "version:33v6"}, {"dependency": "open_jdk", "version": "version:17"}, {"dependency": "curl", "version": "version:7.64.0"}, - {"dependency": "avd_cipd_version", "version": "build_id:8759428741582061553"} + {"dependency": "avd_cipd_version", "version": "build_id:8739520057779466577"} ] linux_android_legacy: properties: @@ -44,7 +44,7 @@ platform_properties: {"dependency": "open_jdk", "version": "version:17"}, {"dependency": "curl", "version": "version:7.64.0"}, {"dependency": "android_virtual_device", "version": "generic_android22.textpb"}, - {"dependency": "avd_cipd_version", "version": "build_id:8759428741582061553"} + {"dependency": "avd_cipd_version", "version": "build_id:8739520057779466577"} ] linux_desktop: properties: @@ -65,7 +65,7 @@ platform_properties: device_type: none dependencies: >- [ - {"dependency": "chrome_and_driver", "version": "version:114.0"} + {"dependency": "chrome_and_driver", "version": "version:125.0.6422.141"} ] windows_arm64: properties: @@ -292,10 +292,10 @@ targets: timeout: 30 properties: target_file: analyze_legacy.yaml - channel: "3.22.0" + channel: "3.22.3" env_variables: >- { - "CHANNEL": "3.22.0" + "CHANNEL": "3.22.3" } - name: Linux analyze_legacy N-2 @@ -303,10 +303,10 @@ targets: timeout: 30 properties: target_file: analyze_legacy.yaml - channel: "3.16.9" + channel: "3.19.6" env_variables: >- { - "CHANNEL": "3.16.9" + "CHANNEL": "3.19.6" } - name: Linux_android custom_package_tests master @@ -327,7 +327,7 @@ targets: {"dependency": "clang", "version": "git_revision:5d5aba78dbbee75508f01bcaa69aedb2ab79065a"}, {"dependency": "cmake", "version": "build_id:8787856497187628321"}, {"dependency": "ninja", "version": "version:1.9.0"}, - {"dependency": "chrome_and_driver", "version": "version:114.0"} + {"dependency": "chrome_and_driver", "version": "version:125.0.6422.141"} ] channel: master env_variables: >- @@ -350,7 +350,7 @@ targets: {"dependency": "clang", "version": "git_revision:5d5aba78dbbee75508f01bcaa69aedb2ab79065a"}, {"dependency": "cmake", "version": "build_id:8787856497187628321"}, {"dependency": "ninja", "version": "version:1.9.0"}, - {"dependency": "chrome_and_driver", "version": "version:114.0"} + {"dependency": "chrome_and_driver", "version": "version:125.0.6422.141"} ] channel: stable env_variables: >- @@ -364,7 +364,24 @@ targets: timeout: 30 properties: version_file: flutter_master.version - target_file: android_build_all_packages.yaml + # This builds the all_packages app only in a current JDK. + target_file: android_build_all_packages_jdk17.yaml + channel: master + env_variables: >- + { + "CHANNEL": "master" + } + + - name: Linux_android android_build_all_packages_legacy master + recipe: packages/packages + timeout: 30 + properties: + version_file: flutter_master.version + # TODO(stuartmorgan): Once stable requires JDK 17, and the + # legacy project is updated accordingly, this entire target + # can be merged back into android_build_all_packages. + # This file only builds a *legacy* version of the project. + target_file: android_build_all_packages_legacy.yaml channel: master # The legacy project build requires an older JDK. dependencies: >- @@ -382,7 +399,21 @@ targets: properties: add_recipes_cq: "true" version_file: flutter_stable.version - target_file: android_build_all_packages.yaml + # This builds the all_packages app only in a current JDK. + target_file: android_build_all_packages_jdk17.yaml + channel: stable + env_variables: >- + { + "CHANNEL": "stable" + } + + - name: Linux_android android_build_all_packages_legacy stable + recipe: packages/packages + timeout: 30 + properties: + version_file: flutter_stable.version + # This file only builds a *legacy* version of the project. + target_file: android_build_all_packages_legacy.yaml channel: stable # The legacy project build requires an older JDK. dependencies: >- @@ -935,7 +966,7 @@ targets: # Install Chrome as a default handler for schemes for url_launcher. dependencies: >- [ - {"dependency": "chrome_and_driver", "version": "version:114.0"} + {"dependency": "chrome_and_driver", "version": "version:125.0.6422.141"} ] env_variables: >- { @@ -953,7 +984,7 @@ targets: # Install Chrome as a default handler for schemes for url_launcher. dependencies: >- [ - {"dependency": "chrome_and_driver", "version": "version:114.0"} + {"dependency": "chrome_and_driver", "version": "version:125.0.6422.141"} ] env_variables: >- { diff --git a/.ci/flutter_master.version b/.ci/flutter_master.version index e026bf29a252..09ac9592c510 100644 --- a/.ci/flutter_master.version +++ b/.ci/flutter_master.version @@ -1 +1 @@ -6c06abbb557672866de5b8ca53f0699dd5af94aa +73546b3b71a73bce38dcc45012c5fd585a6ec55d diff --git a/.ci/flutter_stable.version b/.ci/flutter_stable.version index 60e33a4667dc..a4fc9715437c 100644 --- a/.ci/flutter_stable.version +++ b/.ci/flutter_stable.version @@ -1 +1 @@ -761747bfc538b5af34aa0d3fac380f1bc331ec49 +603104015dd692ea3403755b55d07813d5cf8965 diff --git a/.ci/legacy_project/all_packages/android/.gitignore b/.ci/legacy_project/all_packages/android/.gitignore index 0a741cb43d66..8e599af9f211 100644 --- a/.ci/legacy_project/all_packages/android/.gitignore +++ b/.ci/legacy_project/all_packages/android/.gitignore @@ -7,5 +7,5 @@ gradle-wrapper.jar GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. -# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +# See https://flutter.dev/to/reference-keystore key.properties diff --git a/.ci/legacy_project/all_packages/android/app/build.gradle b/.ci/legacy_project/all_packages/android/app/build.gradle index 2170e19cea13..ce520a90d1f5 100644 --- a/.ci/legacy_project/all_packages/android/app/build.gradle +++ b/.ci/legacy_project/all_packages/android/app/build.gradle @@ -25,6 +25,7 @@ apply plugin: 'com.android.application' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { + namespace = "com.example.all_packages" compileSdkVersion 33 defaultConfig { diff --git a/.ci/scripts/create_all_packages_app.sh b/.ci/scripts/create_all_packages_app.sh index 4440dfe2608a..a0ff3ad89d4e 100755 --- a/.ci/scripts/create_all_packages_app.sh +++ b/.ci/scripts/create_all_packages_app.sh @@ -4,5 +4,16 @@ # found in the LICENSE file. set -e +# The base exclusion file for all_packages app. +exclusions=("script/configs/exclude_all_packages_app.yaml") + +# Add a wasm-specific exclusion file if "--wasm" is specified. +if [[ "$1" == "--wasm" ]]; then + exclusions+=",script/configs/exclude_all_packages_app_wasm.yaml" +fi + +# Delete ./all_packages if it exists already +rm -rf ./all_packages + dart ./script/tool/bin/flutter_plugin_tools.dart create-all-packages-app \ - --output-dir=. --exclude script/configs/exclude_all_packages_app.yaml + --output-dir=. --exclude "$exclusions" diff --git a/.ci/scripts/plugin_tools_format.sh b/.ci/scripts/plugin_tools_format.sh new file mode 100644 index 000000000000..6effea097c43 --- /dev/null +++ b/.ci/scripts/plugin_tools_format.sh @@ -0,0 +1,8 @@ +#!/bin/bash +# 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. +set -e + +cd script/tool +dart format --set-exit-if-changed . diff --git a/.ci/targets/android_build_all_packages_jdk17.yaml b/.ci/targets/android_build_all_packages_jdk17.yaml new file mode 100644 index 000000000000..4843669b894f --- /dev/null +++ b/.ci/targets/android_build_all_packages_jdk17.yaml @@ -0,0 +1,14 @@ +# This only builds the modern all_packages app, which requires jdk17+ +tasks: + - name: prepare tool + script: .ci/scripts/prepare_tool.sh + infra_step: true # Note infra steps failing prevents "always" from running. + - name: create all_packages app + script: .ci/scripts/create_all_packages_app.sh + infra_step: true # Note infra steps failing prevents "always" from running. + - name: build all_packages for Android debug + script: .ci/scripts/build_all_packages_app.sh + args: ["apk", "debug"] + - name: build all_packages for Android release + script: .ci/scripts/build_all_packages_app.sh + args: ["apk", "release"] diff --git a/.ci/targets/android_build_all_packages.yaml b/.ci/targets/android_build_all_packages_legacy.yaml similarity index 65% rename from .ci/targets/android_build_all_packages.yaml rename to .ci/targets/android_build_all_packages_legacy.yaml index 5343cfb17961..6c62e0c3d2a4 100644 --- a/.ci/targets/android_build_all_packages.yaml +++ b/.ci/targets/android_build_all_packages_legacy.yaml @@ -1,16 +1,8 @@ +# This only builds the legacy all_packages app, which requires jdk11 tasks: - name: prepare tool script: .ci/scripts/prepare_tool.sh infra_step: true # Note infra steps failing prevents "always" from running. - - name: create all_packages app - script: .ci/scripts/create_all_packages_app.sh - infra_step: true # Note infra steps failing prevents "always" from running. - - name: build all_packages for Android debug - script: .ci/scripts/build_all_packages_app.sh - args: ["apk", "debug"] - - name: build all_packages for Android release - script: .ci/scripts/build_all_packages_app.sh - args: ["apk", "release"] - name: create all_packages app - legacy version script: .ci/scripts/create_all_packages_app_legacy.sh # Output dir; must match the final argument to build_all_packages_app_legacy diff --git a/.ci/targets/ios_platform_tests.yaml b/.ci/targets/ios_platform_tests.yaml index e679834961f1..bc962e41ecea 100644 --- a/.ci/targets/ios_platform_tests.yaml +++ b/.ci/targets/ios_platform_tests.yaml @@ -18,7 +18,7 @@ tasks: - name: xcode analyze deprecation # Ensure we don't accidentally introduce deprecated code. script: .ci/scripts/tool_runner.sh - args: ["xcode-analyze", "--ios", "--ios-min-version=13.0"] + args: ["xcode-analyze", "--ios", "--ios-min-version=14.0", "--exclude=script/configs/exclude_xcode_deprecation.yaml"] - name: native test script: .ci/scripts/tool_runner.sh # Simulator name and version must match name and version in create_simulator.sh diff --git a/.ci/targets/macos_platform_tests.yaml b/.ci/targets/macos_platform_tests.yaml index 1dd105f109f9..c3a5d83b11e2 100644 --- a/.ci/targets/macos_platform_tests.yaml +++ b/.ci/targets/macos_platform_tests.yaml @@ -15,7 +15,7 @@ tasks: - name: xcode analyze deprecation # Ensure we don't accidentally introduce deprecated code. script: .ci/scripts/tool_runner.sh - args: ["xcode-analyze", "--macos", "--macos-min-version=12.3"] + args: ["xcode-analyze", "--macos", "--macos-min-version=14.0", "--exclude=script/configs/exclude_xcode_deprecation.yaml"] - name: native test script: .ci/scripts/tool_runner.sh args: ["native-test", "--macos"] diff --git a/.ci/targets/repo_checks.yaml b/.ci/targets/repo_checks.yaml index a63240a4ebe8..be48143733f0 100644 --- a/.ci/targets/repo_checks.yaml +++ b/.ci/targets/repo_checks.yaml @@ -4,6 +4,8 @@ tasks: infra_step: true # Note infra steps failing prevents "always" from running. - name: tool unit tests script: .ci/scripts/plugin_tools_tests.sh + - name: tool format + script: .ci/scripts/plugin_tools_format.sh - name: format script: .ci/scripts/tool_runner.sh # Skip Swift formatting on Linux builders. @@ -19,7 +21,7 @@ tasks: script: .ci/scripts/tool_runner.sh args: - "pubspec-check" - - "--min-min-flutter-version=3.16.0" + - "--min-min-flutter-version=3.19.0" - "--allow-dependencies=script/configs/allowed_unpinned_deps.yaml" - "--allow-pinned-dependencies=script/configs/allowed_pinned_deps.yaml" always: true diff --git a/.ci/targets/web_build_all_packages.yaml b/.ci/targets/web_build_all_packages.yaml index 1be790f62d5f..bb782c560d2e 100644 --- a/.ci/targets/web_build_all_packages.yaml +++ b/.ci/targets/web_build_all_packages.yaml @@ -10,3 +10,10 @@ tasks: - name: build all_packages app for Web release script: .ci/scripts/build_all_packages_app.sh args: ["web", "release"] + - name: (Wasm) create all_packages app + script: .ci/scripts/create_all_packages_app.sh + args: ["--wasm"] + infra_step: true # Note infra steps failing prevents "always" from running. + - name: (Wasm) build all_packages app for Web release + script: .ci/scripts/build_all_packages_app.sh + args: ["web", "release", "--wasm"] diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 9681048365d6..1f31d7198f59 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -886,3 +886,14 @@ updates: ignore: - dependency-name: "*" update-types: ["version-update:semver-minor", "version-update:semver-patch"] + + - package-ecosystem: "gradle" + directory: "/third_party/packages/flutter_svg/example/android/app" + commit-message: + prefix: "[flutter_svg]" + schedule: + interval: "weekly" + open-pull-requests-limit: 10 + ignore: + - dependency-name: "*" + update-types: ["version-update:semver-minor", "version-update:semver-patch"] diff --git a/.github/labeler.yml b/.github/labeler.yml index d44cb1298ec0..c7d1a1d531e6 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -68,6 +68,12 @@ - any-glob-to-any-file: - packages/flutter_plugin_android_lifecycle/**/* +'p: flutter_svg': + - changed-files: + - any-glob-to-any-file: + - third_party/packages/flutter_svg/**/* + - third_party/packages/flutter_svg_test/**/* + 'p: flutter_template_images': - changed-files: - any-glob-to-any-file: @@ -108,6 +114,11 @@ - any-glob-to-any-file: - packages/in_app_purchase/**/* +'p: interactive_media_ads': + - changed-files: + - any-glob-to-any-file: + - packages/interactive_media_ads/**/* + 'p: ios_platform_images': - changed-files: - any-glob-to-any-file: @@ -133,6 +144,11 @@ - any-glob-to-any-file: - packages/palette_generator/**/* +'p: path_parsing': + - changed-files: + - any-glob-to-any-file: + - third_party/packages/path_parsing/**/* + 'p: path_provider': - changed-files: - any-glob-to-any-file: @@ -178,6 +194,13 @@ - any-glob-to-any-file: - packages/url_launcher/**/* +'p: vector_graphics': + - changed-files: + - any-glob-to-any-file: + - packages/vector_graphics/**/* + - packages/vector_graphics_codec/**/* + - packages/vector_graphics_compiler/**/* + 'p: video_player': - changed-files: - any-glob-to-any-file: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 341585fb967c..b8b866e72f34 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,12 +31,12 @@ jobs: # the change if it doesn't. run: | cd $HOME - git clone https://github.com/flutter/flutter.git --depth 1 -b 3.22.0 _flutter + git clone https://github.com/flutter/flutter.git --depth 1 -b 3.24.0 _flutter echo "$HOME/_flutter/bin" >> $GITHUB_PATH cd $GITHUB_WORKSPACE # Checks out a copy of the repo. - name: Check out code - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 with: fetch-depth: 0 # Fetch all history so the tool can get all the tags to determine version. - name: Set up tools diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml deleted file mode 100644 index d6b81d959321..000000000000 --- a/.github/workflows/scorecards-analysis.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: Scorecards supply-chain security -on: - push: - branches: - - main - -# Declare default permissions as read only. -permissions: read-all - -jobs: - analysis: - name: Scorecards analysis - runs-on: ubuntu-latest - permissions: - # Needed to upload the results to code-scanning dashboard. - security-events: write - actions: read - contents: read - # Needed to access OIDC token. - id-token: write - - steps: - - name: "Checkout code" - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v2.4.0 - with: - persist-credentials: false - - - name: "Run analysis" - uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.0.3 - with: - results_file: results.sarif - results_format: sarif - # Read-only PAT token. To create it, - # follow the steps in https://github.com/ossf/scorecard-action#pat-token-creation. - repo_token: ${{ secrets.SCORECARD_READ_TOKEN }} - # Publish the results to enable scorecard badges. For more details, see - # https://github.com/ossf/scorecard-action#publishing-results. - # For private repositories, `publish_results` will automatically be set to `false`, - # regardless of the value entered here. - publish_results: true - - # Upload the results as artifacts (optional). - - name: "Upload artifact" - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v2.3.1 - with: - name: SARIF file - path: results.sarif - retention-days: 5 - - # Upload the results to GitHub's code scanning dashboard. - - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@9fdb3e49720b44c48891d036bb502feb25684276 # v1.0.26 - with: - sarif_file: results.sarif diff --git a/AUTHORS b/AUTHORS index 6ea7eeec4f51..be6c57cfb161 100644 --- a/AUTHORS +++ b/AUTHORS @@ -75,5 +75,6 @@ Amir Panahandeh Daniele Cambi Michele Benedetti Taskulu LDA +Alexander Rabin LinXunFeng Hashir Shoaib diff --git a/CODEOWNERS b/CODEOWNERS index cb9966fa3ae6..5a5749661927 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -40,11 +40,18 @@ packages/shared_preferences/** @tarrinneal packages/standard_message_codec/** @jonahwilliams packages/two_dimensional_scrollables/** @Piinks packages/url_launcher/** @stuartmorgan +packages/vector_graphics/** @jonahwilliams +packages/vector_graphics_codec/** @jonahwilliams +packages/vector_graphics_compiler/** @jonahwilliams packages/video_player/** @tarrinneal packages/web_benchmarks/** @yjbanov packages/webview_flutter/** @bparrishMines packages/xdg_directories/** @stuartmorgan third_party/packages/cupertino_icons/** @MitchellGoodwin +third_party/packages/cupertino_icons/test/goldens/** @LongCatIsLooong +third_party/packages/flutter_svg/** @domesticmouse +third_party/packages/flutter_svg_test/** @domesticmouse +third_party/packages/path_parsing/** @domesticmouse # Plugin platform implementation rules. These should stay last, since the last # matching entry takes precedence. @@ -76,7 +83,7 @@ packages/path_provider/path_provider_android/** @camsim99 packages/quick_actions/quick_actions_android/** @camsim99 packages/shared_preferences/shared_preferences_android/** @reidbaker packages/url_launcher/url_launcher_android/** @gmackall -packages/video_player/video_player_android/** @camsim99 +packages/video_player/video_player_android/** @camsim99 @matanlurey # Owned by ecosystem team for now during the wrapper evaluation. packages/webview_flutter/webview_flutter_android/** @bparrishMines diff --git a/README.md b/README.md index efbdb9794eef..2d728c32ac11 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@ [![Release Status](https://github.com/flutter/packages/actions/workflows/release.yml/badge.svg)](https://github.com/flutter/packages/actions/workflows/release.yml) [![Flutter CI Status](https://flutter-dashboard.appspot.com/api/public/build-status-badge?repo=packages)](https://flutter-dashboard.appspot.com/#/build?repo=packages) -[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/flutter/packages/badge)](https://deps.dev/project/github/flutter%2Fpackages) This repo is a companion repo to the main [flutter repo]( https://github.com/flutter/flutter). It contains the source code for Flutter's @@ -21,10 +20,10 @@ Issues pertaining to this repository are [labeled ## Contributing If you wish to contribute a new package to the Flutter ecosystem, please -see the documentation for [developing packages](https://flutter.io/developing-packages/). You can store +see the documentation for [developing packages](https://flutter.dev/to/develop-packages). You can store your package source code in any GitHub repository (the present repo is only intended for packages developed by the core Flutter team). Once your package -is ready you can [publish](https://flutter.io/developing-packages/#publish) +is ready you can [publish](https://flutter.dev/to/develop-packages#publish) to the [pub repository](https://pub.dev/). If you wish to contribute a change to any of the existing packages in this repo, @@ -50,6 +49,8 @@ These are the packages hosted in this repository: | [flutter\_lints](./packages/flutter_lints/) | [![pub package](https://img.shields.io/pub/v/flutter_lints.svg)](https://pub.dev/packages/flutter_lints) | [![pub points](https://img.shields.io/pub/points/flutter_lints)](https://pub.dev/packages/flutter_lints/score) | [![popularity](https://img.shields.io/pub/popularity/flutter_lints)](https://pub.dev/packages/flutter_lints/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20flutter_lints?label=)](https://github.com/flutter/flutter/labels/p%3A%20flutter_lints) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20flutter_lints?label=)](https://github.com/flutter/packages/labels/p%3A%20flutter_lints) | | [flutter\_markdown](./packages/flutter_markdown/) | [![pub package](https://img.shields.io/pub/v/flutter_markdown.svg)](https://pub.dev/packages/flutter_markdown) | [![pub points](https://img.shields.io/pub/points/flutter_markdown)](https://pub.dev/packages/flutter_markdown/score) | [![popularity](https://img.shields.io/pub/popularity/flutter_markdown)](https://pub.dev/packages/flutter_markdown/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20flutter_markdown?label=)](https://github.com/flutter/flutter/labels/p%3A%20flutter_markdown) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20flutter_markdown?label=)](https://github.com/flutter/packages/labels/p%3A%20flutter_markdown) | | [flutter\_plugin\_android\_lifecycle](./packages/flutter_plugin_android_lifecycle/) | [![pub package](https://img.shields.io/pub/v/flutter_plugin_android_lifecycle.svg)](https://pub.dev/packages/flutter_plugin_android_lifecycle) | [![pub points](https://img.shields.io/pub/points/flutter_plugin_android_lifecycle)](https://pub.dev/packages/flutter_plugin_android_lifecycle/score) | [![popularity](https://img.shields.io/pub/popularity/flutter_plugin_android_lifecycle)](https://pub.dev/packages/flutter_plugin_android_lifecycle/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20flutter_plugin_android_lifecycle?label=)](https://github.com/flutter/flutter/labels/p%3A%20flutter_plugin_android_lifecycle) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20flutter_plugin_android_lifecycle?label=)](https://github.com/flutter/packages/labels/p%3A%20flutter_plugin_android_lifecycle) | +| [flutter\_svg](./third_party/packages/flutter_svg/) | [![pub package](https://img.shields.io/pub/v/flutter_svg.svg)](https://pub.dev/packages/flutter_svg) | [![pub points](https://img.shields.io/pub/points/flutter_svg)](https://pub.dev/packages/flutter_svg/score) | [![popularity](https://img.shields.io/pub/popularity/flutter_svg)](https://pub.dev/packages/flutter_svg/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20flutter_svg?label=)](https://github.com/flutter/flutter/labels/p%3A%20flutter_svg) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20flutter_svg?label=)](https://github.com/flutter/packages/labels/p%3A%20flutter_svg) | +| [flutter\_svg\_test](./third_party/packages/flutter_svg_test/) | [![pub package](https://img.shields.io/pub/v/flutter_svg_test.svg)](https://pub.dev/packages/flutter_svg_test) | [![pub points](https://img.shields.io/pub/points/flutter_svg_test)](https://pub.dev/packages/flutter_svg_test/score) | [![popularity](https://img.shields.io/pub/popularity/flutter_svg_test)](https://pub.dev/packages/flutter_svg_test/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20flutter_svg_test?label=)](https://github.com/flutter/flutter/labels/p%3A%20flutter_svg_test) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20flutter_svg_test?label=)](https://github.com/flutter/packages/labels/p%3A%20flutter_svg_test) | | [flutter\_template\_images](./packages/flutter_template_images/) | [![pub package](https://img.shields.io/pub/v/flutter_template_images.svg)](https://pub.dev/packages/flutter_template_images) | [![pub points](https://img.shields.io/pub/points/flutter_template_images)](https://pub.dev/packages/flutter_template_images/score) | [![popularity](https://img.shields.io/pub/popularity/flutter_template_images)](https://pub.dev/packages/flutter_template_images/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20flutter_template_images?label=)](https://github.com/flutter/flutter/labels/p%3A%20flutter_template_images) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20flutter_template_images?label=)](https://github.com/flutter/packages/labels/p%3A%20flutter_template_images) | | [go\_router](./packages/go_router/) | [![pub package](https://img.shields.io/pub/v/go_router.svg)](https://pub.dev/packages/go_router) | [![pub points](https://img.shields.io/pub/points/go_router)](https://pub.dev/packages/go_router/score) | [![popularity](https://img.shields.io/pub/popularity/go_router)](https://pub.dev/packages/go_router/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20go_router?label=)](https://github.com/flutter/flutter/labels/p%3A%20go_router) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20go_router?label=)](https://github.com/flutter/packages/labels/p%3A%20go_router) | | [go\_router\_builder](./packages/go_router_builder/) | [![pub package](https://img.shields.io/pub/v/go_router_builder.svg)](https://pub.dev/packages/go_router_builder) | [![pub points](https://img.shields.io/pub/points/go_router_builder)](https://pub.dev/packages/go_router_builder/score) | [![popularity](https://img.shields.io/pub/popularity/go_router_builder)](https://pub.dev/packages/go_router_builder/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20go_router_builder?label=)](https://github.com/flutter/flutter/labels/p%3A%20go_router_builder) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20go_router_builder?label=)](https://github.com/flutter/packages/labels/p%3A%20go_router_builder) | @@ -63,6 +64,7 @@ These are the packages hosted in this repository: | [metrics\_center](./packages/metrics_center/) | [![pub package](https://img.shields.io/pub/v/metrics_center.svg)](https://pub.dev/packages/metrics_center) | [![pub points](https://img.shields.io/pub/points/metrics_center)](https://pub.dev/packages/metrics_center/score) | [![popularity](https://img.shields.io/pub/popularity/metrics_center)](https://pub.dev/packages/metrics_center/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20metrics_center?label=)](https://github.com/flutter/flutter/labels/p%3A%20metrics_center) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20metrics_center?label=)](https://github.com/flutter/packages/labels/p%3A%20metrics_center) | | [multicast\_dns](./packages/multicast_dns/) | [![pub package](https://img.shields.io/pub/v/multicast_dns.svg)](https://pub.dev/packages/multicast_dns) | [![pub points](https://img.shields.io/pub/points/multicast_dns)](https://pub.dev/packages/multicast_dns/score) | [![popularity](https://img.shields.io/pub/popularity/multicast_dns)](https://pub.dev/packages/multicast_dns/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20multicast_dns?label=)](https://github.com/flutter/flutter/labels/p%3A%20multicast_dns) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20multicast_dns?label=)](https://github.com/flutter/packages/labels/p%3A%20multicast_dns) | | [palette\_generator](./packages/palette_generator/) | [![pub package](https://img.shields.io/pub/v/palette_generator.svg)](https://pub.dev/packages/palette_generator) | [![pub points](https://img.shields.io/pub/points/palette_generator)](https://pub.dev/packages/palette_generator/score) | [![popularity](https://img.shields.io/pub/popularity/palette_generator)](https://pub.dev/packages/palette_generator/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20palette_generator?label=)](https://github.com/flutter/flutter/labels/p%3A%20palette_generator) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20palette_generator?label=)](https://github.com/flutter/packages/labels/p%3A%20palette_generator) | +| [path\_parsing](./third_party/packages/path_parsing/) | [![pub package](https://img.shields.io/pub/v/path_parsing.svg)](https://pub.dev/packages/path_parsing) | [![pub points](https://img.shields.io/pub/points/path_parsing)](https://pub.dev/packages/path_parsing/score) | [![popularity](https://img.shields.io/pub/popularity/path_parsing)](https://pub.dev/packages/path_parsing/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20path_parsing?label=)](https://github.com/flutter/flutter/labels/p%3A%20path_parsing) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20path_parsing?label=)](https://github.com/flutter/packages/labels/p%3A%20path_parsing) | | [path\_provider](./packages/path_provider/) | [![pub package](https://img.shields.io/pub/v/path_provider.svg)](https://pub.dev/packages/path_provider) | [![pub points](https://img.shields.io/pub/points/path_provider)](https://pub.dev/packages/path_provider/score) | [![popularity](https://img.shields.io/pub/popularity/path_provider)](https://pub.dev/packages/path_provider/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20path_provider?label=)](https://github.com/flutter/flutter/labels/p%3A%20path_provider) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20path_provider?label=)](https://github.com/flutter/packages/labels/p%3A%20path_provider) | | [pigeon](./packages/pigeon/) | [![pub package](https://img.shields.io/pub/v/pigeon.svg)](https://pub.dev/packages/pigeon) | [![pub points](https://img.shields.io/pub/points/pigeon)](https://pub.dev/packages/pigeon/score) | [![popularity](https://img.shields.io/pub/popularity/pigeon)](https://pub.dev/packages/pigeon/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20pigeon?label=)](https://github.com/flutter/flutter/labels/p%3A%20pigeon) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20pigeon?label=)](https://github.com/flutter/packages/labels/p%3A%20pigeon) | | [pointer\_interceptor](./packages/pointer_interceptor/) | [![pub package](https://img.shields.io/pub/v/pointer_interceptor.svg)](https://pub.dev/packages/pointer_interceptor) | [![pub points](https://img.shields.io/pub/points/pointer_interceptor)](https://pub.dev/packages/pointer_interceptor/score) | [![popularity](https://img.shields.io/pub/popularity/pointer_interceptor)](https://pub.dev/packages/pointer_interceptor/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20pointer_interceptor?label=)](https://github.com/flutter/flutter/labels/p%3A%20pointer_interceptor) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20pointer_interceptor?label=)](https://github.com/flutter/packages/labels/p%3A%20pointer_interceptor) | @@ -75,6 +77,9 @@ These are the packages hosted in this repository: | [standard\_message\_codec](./packages/standard_message_codec/) | [![pub package](https://img.shields.io/pub/v/standard_message_codec.svg)](https://pub.dev/packages/standard_message_codec) | [![pub points](https://img.shields.io/pub/points/standard_message_codec)](https://pub.dev/packages/standard_message_codec/score) | [![popularity](https://img.shields.io/pub/popularity/standard_message_codec)](https://pub.dev/packages/standard_message_codec/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20standard_message_codec?label=)](https://github.com/flutter/flutter/labels/p%3A%20standard_message_codec) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20standard_message_codec?label=)](https://github.com/flutter/packages/labels/p%3A%20standard_message_codec) | | [two\_dimensional\_scrollables](./packages/two_dimensional_scrollables/) | [![pub package](https://img.shields.io/pub/v/two_dimensional_scrollables.svg)](https://pub.dev/packages/two_dimensional_scrollables) | [![pub points](https://img.shields.io/pub/points/two_dimensional_scrollables)](https://pub.dev/packages/two_dimensional_scrollables/score) | [![popularity](https://img.shields.io/pub/popularity/two_dimensional_scrollables)](https://pub.dev/packages/two_dimensional_scrollables/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20two_dimensional_scrollables?label=)](https://github.com/flutter/flutter/labels/p%3A%20two_dimensional_scrollables) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20two_dimensional_scrollables?label=)](https://github.com/flutter/packages/labels/p%3A%20two_dimensional_scrollables) | | [url\_launcher](./packages/url_launcher/) | [![pub package](https://img.shields.io/pub/v/url_launcher.svg)](https://pub.dev/packages/url_launcher) | [![pub points](https://img.shields.io/pub/points/url_launcher)](https://pub.dev/packages/url_launcher/score) | [![popularity](https://img.shields.io/pub/popularity/url_launcher)](https://pub.dev/packages/url_launcher/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20url_launcher?label=)](https://github.com/flutter/flutter/labels/p%3A%20url_launcher) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20url_launcher?label=)](https://github.com/flutter/packages/labels/p%3A%20url_launcher) | +| [vector\_graphics](./packages/vector_graphics/) | [![pub package](https://img.shields.io/pub/v/vector_graphics.svg)](https://pub.dev/packages/vector_graphics) | [![pub points](https://img.shields.io/pub/points/vector_graphics)](https://pub.dev/packages/vector_graphics/score) | [![popularity](https://img.shields.io/pub/popularity/vector_graphics)](https://pub.dev/packages/vector_graphics/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20vector_graphics?label=)](https://github.com/flutter/flutter/labels/p%3A%20vector_graphics) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20vector_graphics?label=)](https://github.com/flutter/packages/labels/p%3A%20vector_graphics) | +| [vector\_graphics\_codec](./packages/vector_graphics_codec/) | [![pub package](https://img.shields.io/pub/v/vector_graphics_codec.svg)](https://pub.dev/packages/vector_graphics_codec) | [![pub points](https://img.shields.io/pub/points/vector_graphics_codec)](https://pub.dev/packages/vector_graphics_codec/score) | [![popularity](https://img.shields.io/pub/popularity/vector_graphics_codec)](https://pub.dev/packages/vector_graphics_codec/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20vector_graphics_codec?label=)](https://github.com/flutter/flutter/labels/p%3A%20vector_graphics_codec) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20vector_graphics_codec?label=)](https://github.com/flutter/packages/labels/p%3A%20vector_graphics_codec) | +| [vector\_graphics\_compiler](./packages/vector_graphics_compiler/) | [![pub package](https://img.shields.io/pub/v/vector_graphics_compiler.svg)](https://pub.dev/packages/vector_graphics_compiler) | [![pub points](https://img.shields.io/pub/points/vector_graphics_compiler)](https://pub.dev/packages/vector_graphics_compiler/score) | [![popularity](https://img.shields.io/pub/popularity/vector_graphics_compiler)](https://pub.dev/packages/vector_graphics_compiler/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20vector_graphics_compiler?label=)](https://github.com/flutter/flutter/labels/p%3A%20vector_graphics_compiler) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20vector_graphics_compiler?label=)](https://github.com/flutter/packages/labels/p%3A%20vector_graphics_compiler) | | [video\_player](./packages/video_player/) | [![pub package](https://img.shields.io/pub/v/video_player.svg)](https://pub.dev/packages/video_player) | [![pub points](https://img.shields.io/pub/points/video_player)](https://pub.dev/packages/video_player/score) | [![popularity](https://img.shields.io/pub/popularity/video_player)](https://pub.dev/packages/video_player/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20video_player?label=)](https://github.com/flutter/flutter/labels/p%3A%20video_player) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20video_player?label=)](https://github.com/flutter/packages/labels/p%3A%20video_player) | | [web\_benchmarks](./packages/web_benchmarks/) | [![pub package](https://img.shields.io/pub/v/web_benchmarks.svg)](https://pub.dev/packages/web_benchmarks) | [![pub points](https://img.shields.io/pub/points/web_benchmarks)](https://pub.dev/packages/web_benchmarks/score) | [![popularity](https://img.shields.io/pub/popularity/web_benchmarks)](https://pub.dev/packages/web_benchmarks/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20web_benchmarks?label=)](https://github.com/flutter/flutter/labels/p%3A%20web_benchmarks) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20web_benchmarks?label=)](https://github.com/flutter/packages/labels/p%3A%20web_benchmarks) | | [webview\_flutter](./packages/webview_flutter/) | [![pub package](https://img.shields.io/pub/v/webview_flutter.svg)](https://pub.dev/packages/webview_flutter) | [![pub points](https://img.shields.io/pub/points/webview_flutter)](https://pub.dev/packages/webview_flutter/score) | [![popularity](https://img.shields.io/pub/popularity/webview_flutter)](https://pub.dev/packages/webview_flutter/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20webview?label=)](https://github.com/flutter/flutter/labels/p%3A%20webview) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20webview_flutter?label=)](https://github.com/flutter/packages/labels/p%3A%20webview_flutter) | diff --git a/analysis_options.yaml b/analysis_options.yaml index 3f27cc6e1119..736235588ba5 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -48,7 +48,6 @@ linter: - avoid_init_to_null - avoid_js_rounded_ints # - avoid_multiple_declarations_per_line # seems to be a stylistic choice we don't subscribe to - - avoid_null_checks_in_equality_operators # - avoid_positional_boolean_parameters # would have been nice to enable this but by now there's too many places that break it - avoid_print # - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356) @@ -112,6 +111,7 @@ linter: # - lines_longer_than_80_chars # not required by flutter style - literal_only_boolean_expressions # - matching_super_parameters # blocked on https://github.com/dart-lang/language/issues/2509 + - missing_code_block_language_in_doc_comment - missing_whitespace_between_adjacent_strings - no_adjacent_strings_in_list - no_default_cases @@ -131,7 +131,7 @@ linter: # - one_member_abstracts # too many false positives - only_throw_errors # this does get disabled in a few places where we have legacy code that uses strings et al - overridden_fields - - package_api_docs + # - package_api_docs # Deprecated (https://github.com/dart-lang/linter/issues/5107) - package_names - package_prefixed_library_names # - parameter_assignments # we do this commonly @@ -219,7 +219,6 @@ linter: - unnecessary_to_list_in_spreads - unreachable_from_main - unrelated_type_equality_checks - - unsafe_html - use_build_context_synchronously - use_colored_box # - use_decorated_box # leads to bugs: DecoratedBox and Container are not equivalent (Container inserts extra padding) diff --git a/packages/animations/CHANGELOG.md b/packages/animations/CHANGELOG.md index 2d6a0425fdd6..76db6b8ed283 100644 --- a/packages/animations/CHANGELOG.md +++ b/packages/animations/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 2.0.11 diff --git a/packages/animations/example/android/app/build.gradle b/packages/animations/example/android/app/build.gradle index f807599056dc..19d11f91e671 100644 --- a/packages/animations/example/android/app/build.gradle +++ b/packages/animations/example/android/app/build.gradle @@ -29,6 +29,15 @@ android { namespace 'dev.flutter.packages.animations.example' compileSdk flutter.compileSdkVersion + compileOptions { + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 + } + + kotlinOptions { + jvmTarget = '11' + } + sourceSets { main.java.srcDirs += 'src/main/kotlin' } diff --git a/packages/animations/example/android/build.gradle b/packages/animations/example/android/build.gradle index d13ef556e261..4a9ad584b421 100644 --- a/packages/animations/example/android/build.gradle +++ b/packages/animations/example/android/build.gradle @@ -1,12 +1,12 @@ buildscript { - ext.kotlin_version = '1.7.10' + ext.kotlin_version = '1.9.0' repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath 'com.android.tools.build:gradle:8.5.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/packages/animations/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/animations/example/android/gradle/wrapper/gradle-wrapper.properties index aeaff6f869f3..7aeeb11c6ee5 100644 --- a/packages/animations/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/animations/example/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/animations/example/pubspec.yaml b/packages/animations/example/pubspec.yaml index 2b9660aa4eb1..812702238da7 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: animations: diff --git a/packages/animations/example/web/index.html b/packages/animations/example/web/index.html index 7fb138cc90fa..956b11f49f7a 100644 --- a/packages/animations/example/web/index.html +++ b/packages/animations/example/web/index.html @@ -8,6 +8,6 @@ example - + diff --git a/packages/animations/pubspec.yaml b/packages/animations/pubspec.yaml index 2c06adf64cd7..bc208969964e 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.2.0 <4.0.0" - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/animations/test/open_container_test.dart b/packages/animations/test/open_container_test.dart index 4b7f2f854671..5d4ae9614180 100644 --- a/packages/animations/test/open_container_test.dart +++ b/packages/animations/test/open_container_test.dart @@ -37,7 +37,7 @@ void main() { )); // Closed container has the expected properties. - final StatefulElement srcMaterialElement = tester.firstElement( + final Element srcMaterialElement = tester.firstElement( find.ancestor( of: find.text('Closed'), matching: find.byType(Material), @@ -62,7 +62,7 @@ void main() { await tester.pump(); // On the first frame of the animation everything still looks like before. - final StatefulElement destMaterialElement = tester.firstElement( + final Element destMaterialElement = tester.firstElement( find.ancestor( of: find.text('Closed'), matching: find.byType(Material), @@ -162,7 +162,7 @@ void main() { await tester.pump(const Duration(milliseconds: 1)); expect(find.text('Closed'), findsNothing); // No longer in the tree. expect(find.text('Open'), findsOneWidget); - final StatefulElement finalMaterialElement = tester.firstElement( + final Element finalMaterialElement = tester.firstElement( find.ancestor( of: find.text('Open'), matching: find.byType(Material), @@ -213,7 +213,7 @@ void main() { // Open container has the expected properties. expect(find.text('Closed'), findsNothing); expect(find.text('Open'), findsOneWidget); - final StatefulElement initialMaterialElement = tester.firstElement( + final Element initialMaterialElement = tester.firstElement( find.ancestor( of: find.text('Open'), matching: find.byType(Material), @@ -237,7 +237,7 @@ void main() { expect(find.text('Closed'), findsOneWidget); expect(find.text('Open'), findsOneWidget); - final StatefulElement materialElement = tester.firstElement( + final Element materialElement = tester.firstElement( find.ancestor( of: find.text('Open'), matching: find.byType(Material), @@ -328,7 +328,7 @@ void main() { await tester.pump(const Duration(milliseconds: 1)); expect(find.text('Open'), findsNothing); // No longer in the tree. expect(find.text('Closed'), findsOneWidget); - final StatefulElement finalMaterialElement = tester.firstElement( + final Element finalMaterialElement = tester.firstElement( find.ancestor( of: find.text('Closed'), matching: find.byType(Material), @@ -380,7 +380,7 @@ void main() { )); // Closed container has the expected properties. - final StatefulElement srcMaterialElement = tester.firstElement( + final Element srcMaterialElement = tester.firstElement( find.ancestor( of: find.text('Closed'), matching: find.byType(Material), @@ -405,7 +405,7 @@ void main() { await tester.pump(); // On the first frame of the animation everything still looks like before. - final StatefulElement destMaterialElement = tester.firstElement( + final Element destMaterialElement = tester.firstElement( find.ancestor( of: find.text('Closed'), matching: find.byType(Material), @@ -509,7 +509,7 @@ void main() { await tester.pump(const Duration(milliseconds: 1)); expect(find.text('Closed'), findsNothing); // No longer in the tree. expect(find.text('Open'), findsOneWidget); - final StatefulElement finalMaterialElement = tester.firstElement( + final Element finalMaterialElement = tester.firstElement( find.ancestor( of: find.text('Open'), matching: find.byType(Material), @@ -558,7 +558,7 @@ void main() { // Open container has the expected properties. expect(find.text('Closed'), findsNothing); expect(find.text('Open'), findsOneWidget); - final StatefulElement initialMaterialElement = tester.firstElement( + final Element initialMaterialElement = tester.firstElement( find.ancestor( of: find.text('Open'), matching: find.byType(Material), @@ -583,7 +583,7 @@ void main() { expect(find.text('Closed'), findsOneWidget); expect(find.text('Open'), findsOneWidget); - final StatefulElement materialElement = tester.firstElement( + final Element materialElement = tester.firstElement( find.ancestor( of: find.text('Open'), matching: find.byType(Material), @@ -684,7 +684,7 @@ void main() { await tester.pump(const Duration(milliseconds: 1)); expect(find.text('Open'), findsNothing); // No longer in the tree. expect(find.text('Closed'), findsOneWidget); - final StatefulElement finalMaterialElement = tester.firstElement( + final Element finalMaterialElement = tester.firstElement( find.ancestor( of: find.text('Closed'), matching: find.byType(Material), diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 53a6c4ca1ad8..d018f4941993 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.11.0+2 + +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + ## 0.11.0+1 * Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. diff --git a/packages/camera/camera/README.md b/packages/camera/camera/README.md index a07c4ebbda9a..1ebac1e02f07 100644 --- a/packages/camera/camera/README.md +++ b/packages/camera/camera/README.md @@ -17,9 +17,7 @@ A Flutter plugin for iOS, Android and Web allowing access to the device cameras. * Record video. * Add access to the image stream from Dart. -## Installation - -First, add `camera` as a [dependency in your pubspec.yaml file](https://flutter.dev/using-packages/). +## Setup ### iOS diff --git a/packages/camera/camera/example/android/app/build.gradle b/packages/camera/camera/example/android/app/build.gradle index a6e00fd38961..9e2d6373e872 100644 --- a/packages/camera/camera/example/android/app/build.gradle +++ b/packages/camera/camera/example/android/app/build.gradle @@ -31,7 +31,7 @@ android { defaultConfig { applicationId "io.flutter.plugins.cameraexample" - minSdkVersion 21 + minSdkVersion flutter.minSdkVersion targetSdkVersion 28 versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/packages/camera/camera/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/camera/camera/example/android/app/gradle/wrapper/gradle-wrapper.properties index 609ab8e6c8b5..d951fac2bf31 100644 --- a/packages/camera/camera/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ b/packages/camera/camera/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/packages/camera/camera/example/android/build.gradle b/packages/camera/camera/example/android/build.gradle index cec92de922cf..6104b2634228 100644 --- a/packages/camera/camera/example/android/build.gradle +++ b/packages/camera/camera/example/android/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath 'com.android.tools.build:gradle:8.5.1' } } diff --git a/packages/camera/camera/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/camera/camera/example/android/gradle/wrapper/gradle-wrapper.properties index e1ca574ef017..3c85cfe057a1 100644 --- a/packages/camera/camera/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/camera/camera/example/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/camera/camera/example/integration_test/camera_test.dart b/packages/camera/camera/example/integration_test/camera_test.dart index e1fe14a6132e..1c5c8526c733 100644 --- a/packages/camera/camera/example/integration_test/camera_test.dart +++ b/packages/camera/camera/example/integration_test/camera_test.dart @@ -13,6 +13,10 @@ import 'package:integration_test/integration_test.dart'; import 'package:path_provider/path_provider.dart'; import 'package:video_player/video_player.dart'; +// Skip due to video_player error. +// See https://github.com/flutter/flutter/issues/157181 +bool skipFor157181 = Platform.isAndroid; + void main() { late Directory testDir; @@ -177,7 +181,7 @@ void main() { await videoController.dispose(); expect(duration, lessThan(recordingTime)); - }); + }, skip: skipFor157181); testWidgets('Pause and resume video recording', (WidgetTester tester) async { final List cameras = await availableCameras(); @@ -225,7 +229,7 @@ void main() { await videoController.dispose(); expect(duration, lessThan(recordingTime - timePaused)); - }, skip: !Platform.isAndroid); + }, skip: !Platform.isAndroid || skipFor157181); testWidgets( 'Android image streaming', diff --git a/packages/camera/camera/example/lib/main.dart b/packages/camera/camera/example/lib/main.dart index f7b209a768b3..d048fc794f28 100644 --- a/packages/camera/camera/example/lib/main.dart +++ b/packages/camera/camera/example/lib/main.dart @@ -534,7 +534,7 @@ class _CameraExampleHomeState extends State onPressed: cameraController != null && cameraController.value.isInitialized && cameraController.value.isRecordingVideo - ? (cameraController.value.isRecordingPaused) + ? cameraController.value.isRecordingPaused ? onResumeButtonPressed : onPauseButtonPressed : null, @@ -689,7 +689,6 @@ class _CameraExampleHomeState extends State showInSnackBar('Audio access is restricted.'); default: _showCameraException(e); - break; } } diff --git a/packages/camera/camera/example/pubspec.yaml b/packages/camera/camera/example/pubspec.yaml index f3b240b56c24..5dd02b696866 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: camera: @@ -28,5 +28,9 @@ dev_dependencies: integration_test: sdk: flutter +dependency_overrides: + camera_web: + path: ../../camera_web + flutter: uses-material-design: true diff --git a/packages/camera/camera/example/web/index.html b/packages/camera/camera/example/web/index.html index 2a3117d29362..0dd4a04db410 100644 --- a/packages/camera/camera/example/web/index.html +++ b/packages/camera/camera/example/web/index.html @@ -3,8 +3,9 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> - + + @@ -16,24 +17,12 @@ - + Camera Web Example - - - - + - - \ No newline at end of file + diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index f00a7e798f01..0b8ebb4a3b5c 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -4,11 +4,11 @@ description: A Flutter plugin for controlling the camera. Supports previewing Dart. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.11.0+1 +version: 0.11.0+2 environment: - sdk: ^3.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -32,7 +32,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 plugin_platform_interface: ^2.1.7 topics: diff --git a/packages/camera/camera/test/camera_image_stream_test.dart b/packages/camera/camera/test/camera_image_stream_test.dart index 6ac27e513fca..c89e4acaa726 100644 --- a/packages/camera/camera/test/camera_image_stream_test.dart +++ b/packages/camera/camera/test/camera_image_stream_test.dart @@ -215,11 +215,10 @@ class MockStreamingCameraPlatform extends MockCameraPlatform { } @override - Future startVideoRecording(int cameraId, - {Duration? maxVideoDuration}) { + Future startVideoRecording(int cameraId, {Duration? maxVideoDuration}) { streamCallLog.add('startVideoRecording'); - return super - .startVideoRecording(cameraId, maxVideoDuration: maxVideoDuration); + // Ignore maxVideoDuration, as it is unimplemented and deprecated. + return super.startVideoRecording(cameraId); } @override diff --git a/packages/camera/camera/test/camera_test.dart b/packages/camera/camera/test/camera_test.dart index f10015334d52..0c6a319397e0 100644 --- a/packages/camera/camera/test/camera_test.dart +++ b/packages/camera/camera/test/camera_test.dart @@ -1511,14 +1511,17 @@ class MockCameraPlatform extends Mock super.noSuchMethod(Invocation.method(#prepareForVideoRecording, null)); @override - Future startVideoRecording(int cameraId, - {Duration? maxVideoDuration}) => - Future.value(mockVideoRecordingXFile); + Future startVideoRecording(int cameraId, {Duration? maxVideoDuration}) { + // Ignore maxVideoDuration, as it is unimplemented and deprecated. + return startVideoCapturing(VideoCaptureOptions(cameraId)); + } + + @override + Future startVideoCapturing(VideoCaptureOptions options) async {} @override - Future startVideoCapturing(VideoCaptureOptions options) { - return startVideoRecording(options.cameraId, - maxVideoDuration: options.maxDuration); + Future stopVideoRecording(int cameraId) { + return Future.value(mockVideoRecordingXFile); } @override diff --git a/packages/camera/camera_android/CHANGELOG.md b/packages/camera/camera_android/CHANGELOG.md index 1e46c7c96e61..c844cc61abbf 100644 --- a/packages/camera/camera_android/CHANGELOG.md +++ b/packages/camera/camera_android/CHANGELOG.md @@ -1,3 +1,44 @@ +## 0.10.9+16 + +* Updates annotations lib to 1.9.0. + +## 0.10.9+15 + +* Converts Dart to native platform calls to Pigeon. + +## 0.10.9+14 + +* Converts native to Dart platform calls to Pigeon. + +## 0.10.9+13 + +* Converts `getAvailableCameras` to Pigeon. + +## 0.10.9+12 + +* Updates Java compatibility version to 11. +* Updates minimum supported SDK version to Flutter 3.24/Dart 3.5. + +## 0.10.9+11 + +* Updates annotations lib to 1.8.2. + +## 0.10.9+10 + +* Updates annotations lib to 1.8.1. + +## 0.10.9+9 + +* Updates lint checks to ignore NewerVersionAvailable. + +## 0.10.9+8 + +* Removes unused code related to `maxVideoDuration`. + +## 0.10.9+7 + +* Updates Android Gradle plugin to 8.5.0. + ## 0.10.9+6 * Reverts changes to support Impeller. diff --git a/packages/camera/camera_android/README.md b/packages/camera/camera_android/README.md index 486db6743284..36f1dd5c3c04 100644 --- a/packages/camera/camera_android/README.md +++ b/packages/camera/camera_android/README.md @@ -17,7 +17,7 @@ when recording a video with sound enabled and trying to play it back, the durati you will only see the first frame. [1]: https://pub.dev/packages/camera -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin [3]: https://pub.dev/packages/camera_android_camerax [4]: https://developer.android.com/media/camera/camera2 [5]: https://developer.android.com/reference/android/media/MediaRecorder diff --git a/packages/camera/camera_android/android/build.gradle b/packages/camera/camera_android/android/build.gradle index 2caee412af17..cbe399571dcd 100644 --- a/packages/camera/camera_android/android/build.gradle +++ b/packages/camera/camera_android/android/build.gradle @@ -9,7 +9,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.3.0' + classpath 'com.android.tools.build:gradle:8.5.0' } } @@ -30,10 +30,7 @@ android { buildFeatures { buildConfig true } - // Conditional for compatibility with AGP <4.2. - if (project.android.hasProperty("namespace")) { - namespace 'io.flutter.plugins.camera' - } + namespace 'io.flutter.plugins.camera' compileSdk 34 defaultConfig { @@ -43,17 +40,21 @@ buildFeatures { lintOptions { checkAllWarnings true warningsAsErrors true - disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency' + disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency', 'NewerVersionAvailable' } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } testOptions { unitTests.includeAndroidResources = true unitTests.returnDefaultValues = true unitTests.all { + // The org.gradle.jvmargs property that may be set in gradle.properties does not impact + // the Java heap size when running the Android unit tests. The following property here + // sets the heap size to a size large enough to run the robolectric tests across + // multiple SDK levels. jvmArgs "-Xmx1g" testLogging { events "passed", "skipped", "failed", "standardOut", "standardError" @@ -65,7 +66,7 @@ buildFeatures { } dependencies { - implementation 'androidx.annotation:annotation:1.8.0' + implementation 'androidx.annotation:annotation:1.9.0' testImplementation 'junit:junit:4.13.2' testImplementation 'org.mockito:mockito-inline:5.0.0' testImplementation 'androidx.test:core:1.4.0' diff --git a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/Camera.java index 7668ec97eec7..cfddf2d3bc34 100644 --- a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -39,8 +39,6 @@ import io.flutter.BuildConfig; import io.flutter.embedding.engine.systemchannels.PlatformChannel; import io.flutter.plugin.common.EventChannel; -import io.flutter.plugin.common.MethodChannel; -import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugins.camera.features.CameraFeature; import io.flutter.plugins.camera.features.CameraFeatureFactory; import io.flutter.plugins.camera.features.CameraFeatures; @@ -68,7 +66,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.concurrent.Executors; @@ -83,23 +80,13 @@ class Camera ImageReader.OnImageAvailableListener { private static final String TAG = "Camera"; - private static final HashMap supportedImageFormats; - - // Current supported outputs. - static { - supportedImageFormats = new HashMap<>(); - supportedImageFormats.put("yuv420", ImageFormat.YUV_420_888); - supportedImageFormats.put("jpeg", ImageFormat.JPEG); - supportedImageFormats.put("nv21", ImageFormat.NV21); - } - /** * Holds all of the camera features/settings and will be used to update the request builder when * one changes. */ CameraFeatures cameraFeatures; - private String imageFormatGroup; + private int imageFormatGroup; /** * Takes an input/output surface and orients the recording correctly. This is needed because @@ -148,7 +135,7 @@ class Camera /** Holds the last known capture properties */ private CameraCaptureProperties captureProps; - MethodChannel.Result flutterResult; + Messages.Result flutterResult; /** A CameraDeviceWrapper implementation that forwards calls to a CameraDevice. */ private class DefaultCameraDeviceWrapper implements CameraDeviceWrapper { @@ -340,7 +327,7 @@ private void prepareMediaRecorder(String outputFilePath) throws IOException { } @SuppressLint("MissingPermission") - public void open(String imageFormatGroup) throws CameraAccessException { + public void open(Integer imageFormatGroup) throws CameraAccessException { this.imageFormatGroup = imageFormatGroup; final ResolutionFeature resolutionFeature = cameraFeatures.getResolution(); @@ -363,17 +350,11 @@ public void open(String imageFormatGroup) throws CameraAccessException { ImageFormat.JPEG, 1); - // For image streaming, use the provided image format or fall back to YUV420. - Integer imageFormat = supportedImageFormats.get(imageFormatGroup); - if (imageFormat == null) { - Log.w(TAG, "The selected imageFormatGroup is not supported by Android. Defaulting to yuv420"); - imageFormat = ImageFormat.YUV_420_888; - } imageStreamReader = new ImageStreamReader( resolutionFeature.getPreviewSize().getWidth(), resolutionFeature.getPreviewSize().getHeight(), - imageFormat, + this.imageFormatGroup, 1); // Open the camera. @@ -396,10 +377,14 @@ public void onOpened(@NonNull CameraDevice device) { cameraFeatures.getFocusPoint().checkIsSupported()); } } catch (Exception e) { + String message = + (e.getMessage() == null) + ? (e.getClass().getName() + " occurred while opening camera.") + : e.getMessage(); if (BuildConfig.DEBUG) { - Log.i(TAG, "open | onOpened error: " + e.getMessage()); + Log.i(TAG, "open | onOpened error: " + message); } - dartMessenger.sendCameraErrorEvent(e.getMessage()); + dartMessenger.sendCameraErrorEvent(message); close(); } } @@ -618,10 +603,12 @@ private void startCapture(boolean record, boolean stream) throws CameraAccessExc CameraDevice.TEMPLATE_RECORD, successCallback, surfaces.toArray(new Surface[0])); } - public void takePicture(@NonNull final Result result) { + public void takePicture(@NonNull final Messages.Result result) { // Only take one picture at a time. if (cameraCaptureCallback.getCameraState() != CameraState.STATE_PREVIEW) { - result.error("captureAlreadyActive", "Picture is currently already being captured", null); + result.error( + new Messages.FlutterError( + "captureAlreadyActive", "Picture is currently already being captured", null)); return; } @@ -792,7 +779,11 @@ private void lockAutoFocus() { try { captureSession.capture(previewRequestBuilder.build(), null, backgroundHandler); } catch (CameraAccessException e) { - dartMessenger.sendCameraErrorEvent(e.getMessage()); + String message = + (e.getMessage() == null) + ? "CameraAccessException occurred while locking autofocus." + : e.getMessage(); + dartMessenger.sendCameraErrorEvent(message); } } @@ -815,7 +806,11 @@ void unlockAutoFocus() { captureSession.capture(previewRequestBuilder.build(), null, backgroundHandler); } catch (CameraAccessException e) { - dartMessenger.sendCameraErrorEvent(e.getMessage()); + String message = + (e.getMessage() == null) + ? "CameraAccessException occurred while unlocking autofocus." + : e.getMessage(); + dartMessenger.sendCameraErrorEvent(message); return; } @@ -825,9 +820,8 @@ void unlockAutoFocus() { dartMessenger.error(flutterResult, errorCode, errorMessage, null)); } - public void startVideoRecording( - @NonNull Result result, @Nullable EventChannel imageStreamChannel) { - prepareRecording(result); + public void startVideoRecording(@Nullable EventChannel imageStreamChannel) { + prepareRecording(); if (imageStreamChannel != null) { setStreamHandler(imageStreamChannel); @@ -836,11 +830,10 @@ public void startVideoRecording( recordingVideo = true; try { startCapture(true, imageStreamChannel != null); - result.success(null); } catch (CameraAccessException e) { recordingVideo = false; captureFile = null; - result.error("videoRecordingFailed", e.getMessage(), null); + throw new Messages.FlutterError("videoRecordingFailed", e.getMessage(), null); } } @@ -851,10 +844,9 @@ private void closeRenderer() { } } - public void stopVideoRecording(@NonNull final Result result) { + public String stopVideoRecording() { if (!recordingVideo) { - result.success(null); - return; + return ""; } // Re-create autofocus feature so it's using continuous capture focus mode now. cameraFeatures.setAutoFocus( @@ -871,16 +863,15 @@ public void stopVideoRecording(@NonNull final Result result) { try { startPreview(); } catch (CameraAccessException | IllegalStateException | InterruptedException e) { - result.error("videoRecordingFailed", e.getMessage(), null); - return; + throw new Messages.FlutterError("videoRecordingFailed", e.getMessage(), null); } - result.success(captureFile.getAbsolutePath()); + String path = captureFile.getAbsolutePath(); captureFile = null; + return path; } - public void pauseVideoRecording(@NonNull final Result result) { + public void pauseVideoRecording() { if (!recordingVideo) { - result.success(null); return; } @@ -888,20 +879,16 @@ public void pauseVideoRecording(@NonNull final Result result) { if (SdkCapabilityChecker.supportsVideoPause()) { mediaRecorder.pause(); } else { - result.error("videoRecordingFailed", "pauseVideoRecording requires Android API +24.", null); - return; + throw new Messages.FlutterError( + "videoRecordingFailed", "pauseVideoRecording requires Android API +24.", null); } } catch (IllegalStateException e) { - result.error("videoRecordingFailed", e.getMessage(), null); - return; + throw new Messages.FlutterError("videoRecordingFailed", e.getMessage(), null); } - - result.success(null); } - public void resumeVideoRecording(@NonNull final Result result) { + public void resumeVideoRecording() { if (!recordingVideo) { - result.success(null); return; } @@ -909,16 +896,12 @@ public void resumeVideoRecording(@NonNull final Result result) { if (SdkCapabilityChecker.supportsVideoPause()) { mediaRecorder.resume(); } else { - result.error( + throw new Messages.FlutterError( "videoRecordingFailed", "resumeVideoRecording requires Android API +24.", null); - return; } } catch (IllegalStateException e) { - result.error("videoRecordingFailed", e.getMessage(), null); - return; + throw new Messages.FlutterError("videoRecordingFailed", e.getMessage(), null); } - - result.success(null); } /** @@ -927,15 +910,18 @@ public void resumeVideoRecording(@NonNull final Result result) { * @param result Flutter result. * @param newMode new mode. */ - public void setFlashMode(@NonNull final Result result, @NonNull FlashMode newMode) { + public void setFlashMode(@NonNull final Messages.VoidResult result, @NonNull FlashMode newMode) { // Save the new flash mode setting. final FlashFeature flashFeature = cameraFeatures.getFlash(); flashFeature.setValue(newMode); flashFeature.updateBuilder(previewRequestBuilder); refreshPreviewCaptureSession( - () -> result.success(null), - (code, message) -> result.error("setFlashModeFailed", "Could not set flash mode.", null)); + result::success, + (code, message) -> + result.error( + new Messages.FlutterError( + "setFlashModeFailed", "Could not set flash mode.", null))); } /** @@ -944,15 +930,18 @@ public void setFlashMode(@NonNull final Result result, @NonNull FlashMode newMod * @param result Flutter result. * @param newMode new mode. */ - public void setExposureMode(@NonNull final Result result, @NonNull ExposureMode newMode) { + public void setExposureMode( + @NonNull final Messages.VoidResult result, @NonNull ExposureMode newMode) { final ExposureLockFeature exposureLockFeature = cameraFeatures.getExposureLock(); exposureLockFeature.setValue(newMode); exposureLockFeature.updateBuilder(previewRequestBuilder); refreshPreviewCaptureSession( - () -> result.success(null), + result::success, (code, message) -> - result.error("setExposureModeFailed", "Could not set exposure mode.", null)); + result.error( + new Messages.FlutterError( + "setExposureModeFailed", "Could not set exposure mode.", null))); } /** @@ -961,15 +950,17 @@ public void setExposureMode(@NonNull final Result result, @NonNull ExposureMode * @param result Flutter result. * @param point The exposure point. */ - public void setExposurePoint(@NonNull final Result result, @Nullable Point point) { + public void setExposurePoint(@NonNull final Messages.VoidResult result, @Nullable Point point) { final ExposurePointFeature exposurePointFeature = cameraFeatures.getExposurePoint(); exposurePointFeature.setValue(point); exposurePointFeature.updateBuilder(previewRequestBuilder); refreshPreviewCaptureSession( - () -> result.success(null), + result::success, (code, message) -> - result.error("setExposurePointFailed", "Could not set exposure point.", null)); + result.error( + new Messages.FlutterError( + "setExposurePointFailed", "Could not set exposure point.", null))); } /** Return the max exposure offset value supported by the camera to dart. */ @@ -990,10 +981,9 @@ public double getExposureOffsetStepSize() { /** * Sets new focus mode from dart. * - * @param result Flutter result. * @param newMode New mode. */ - public void setFocusMode(final Result result, @NonNull FocusMode newMode) { + public void setFocusMode(@NonNull FocusMode newMode) { final AutoFocusFeature autoFocusFeature = cameraFeatures.getAutoFocus(); autoFocusFeature.setValue(newMode); autoFocusFeature.updateBuilder(previewRequestBuilder); @@ -1020,11 +1010,8 @@ public void setFocusMode(final Result result, @NonNull FocusMode newMode) { captureSession.setRepeatingRequest( previewRequestBuilder.build(), null, backgroundHandler); } catch (CameraAccessException e) { - if (result != null) { - result.error( - "setFocusModeFailed", "Error setting focus mode: " + e.getMessage(), null); - } - return; + throw new Messages.FlutterError( + "setFocusModeFailed", "Error setting focus mode: " + e.getMessage(), null); } break; case auto: @@ -1033,10 +1020,6 @@ public void setFocusMode(final Result result, @NonNull FocusMode newMode) { break; } } - - if (result != null) { - result.success(null); - } } /** @@ -1045,16 +1028,19 @@ public void setFocusMode(final Result result, @NonNull FocusMode newMode) { * @param result Flutter result. * @param point the new coordinates. */ - public void setFocusPoint(@NonNull final Result result, @Nullable Point point) { + public void setFocusPoint(@NonNull final Messages.VoidResult result, @Nullable Point point) { final FocusPointFeature focusPointFeature = cameraFeatures.getFocusPoint(); focusPointFeature.setValue(point); focusPointFeature.updateBuilder(previewRequestBuilder); refreshPreviewCaptureSession( - () -> result.success(null), - (code, message) -> result.error("setFocusPointFailed", "Could not set focus point.", null)); + result::success, + (code, message) -> + result.error( + new Messages.FlutterError( + "setFocusPointFailed", "Could not set focus point.", null))); - this.setFocusMode(null, cameraFeatures.getAutoFocus().getValue()); + this.setFocusMode(cameraFeatures.getAutoFocus().getValue()); } /** @@ -1064,7 +1050,7 @@ public void setFocusPoint(@NonNull final Result result, @Nullable Point point) { * @param result flutter result. * @param offset new value. */ - public void setExposureOffset(@NonNull final Result result, double offset) { + public void setExposureOffset(@NonNull final Messages.Result result, double offset) { final ExposureOffsetFeature exposureOffsetFeature = cameraFeatures.getExposureOffset(); exposureOffsetFeature.setValue(offset); exposureOffsetFeature.updateBuilder(previewRequestBuilder); @@ -1072,7 +1058,9 @@ public void setExposureOffset(@NonNull final Result result, double offset) { refreshPreviewCaptureSession( () -> result.success(exposureOffsetFeature.getValue()), (code, message) -> - result.error("setExposureOffsetFailed", "Could not set exposure offset.", null)); + result.error( + new Messages.FlutterError( + "setExposureOffsetFailed", "Could not set exposure offset.", null))); } public float getMaxZoomLevel() { @@ -1103,7 +1091,7 @@ DeviceOrientationManager getDeviceOrientationManager() { * @param result Flutter result. * @param zoom new value. */ - public void setZoomLevel(@NonNull final Result result, float zoom) throws CameraAccessException { + public void setZoomLevel(@NonNull final Messages.VoidResult result, float zoom) { final ZoomLevelFeature zoomLevel = cameraFeatures.getZoomLevel(); float maxZoom = zoomLevel.getMaximumZoomLevel(); float minZoom = zoomLevel.getMinimumZoomLevel(); @@ -1115,7 +1103,7 @@ public void setZoomLevel(@NonNull final Result result, float zoom) throws Camera "Zoom level out of bounds (zoom level should be between %f and %f).", minZoom, maxZoom); - result.error("ZOOM_ERROR", errorMessage, null); + result.error(new Messages.FlutterError("ZOOM_ERROR", errorMessage, null)); return; } @@ -1123,8 +1111,11 @@ public void setZoomLevel(@NonNull final Result result, float zoom) throws Camera zoomLevel.updateBuilder(previewRequestBuilder); refreshPreviewCaptureSession( - () -> result.success(null), - (code, message) -> result.error("setZoomLevelFailed", "Could not set zoom level.", null)); + result::success, + (code, message) -> + result.error( + new Messages.FlutterError( + "setZoomLevelFailed", "Could not set zoom level.", null))); } /** @@ -1231,12 +1222,12 @@ public void onImageAvailable(ImageReader reader) { captureFile, new ImageSaver.Callback() { @Override - public void onComplete(String absolutePath) { + public void onComplete(@NonNull String absolutePath) { dartMessenger.finish(flutterResult, absolutePath); } @Override - public void onError(String errorCode, String errorMessage) { + public void onError(@NonNull String errorCode, @NonNull String errorMessage) { dartMessenger.error(flutterResult, errorCode, errorMessage, null); } })); @@ -1244,21 +1235,19 @@ public void onError(String errorCode, String errorMessage) { } @VisibleForTesting - void prepareRecording(@NonNull Result result) { + void prepareRecording() { final File outputDir = applicationContext.getCacheDir(); try { captureFile = File.createTempFile("REC", ".mp4", outputDir); } catch (IOException | SecurityException e) { - result.error("cannotCreateFile", e.getMessage(), null); - return; + throw new Messages.FlutterError("cannotCreateFile", e.getMessage(), null); } try { prepareMediaRecorder(captureFile.getAbsolutePath()); } catch (IOException e) { recordingVideo = false; captureFile = null; - result.error("videoRecordingFailed", e.getMessage(), null); - return; + throw new Messages.FlutterError("videoRecordingFailed", e.getMessage(), null); } // Re-create autofocus feature so it's using video focus mode now. cameraFeatures.setAutoFocus( @@ -1359,21 +1348,19 @@ public void uncaughtException(Thread thread, Throwable ex) { videoRendererUncaughtExceptionHandler); } - public void setDescriptionWhileRecording( - @NonNull final Result result, CameraProperties properties) { + public void setDescriptionWhileRecording(CameraProperties properties) { if (!recordingVideo) { - result.error("setDescriptionWhileRecordingFailed", "Device was not recording", null); - return; + throw new Messages.FlutterError( + "setDescriptionWhileRecordingFailed", "Device was not recording", null); } // See VideoRenderer.java; support for this EGL extension is required to switch camera while recording. if (!SdkCapabilityChecker.supportsEglRecordableAndroid()) { - result.error( + throw new Messages.FlutterError( "setDescriptionWhileRecordingFailed", "Device does not support switching the camera while recording", null); - return; } stopAndReleaseCamera(); @@ -1391,9 +1378,8 @@ public void setDescriptionWhileRecording( try { open(imageFormatGroup); } catch (CameraAccessException e) { - result.error("setDescriptionWhileRecordingFailed", e.getMessage(), null); + throw new Messages.FlutterError("setDescriptionWhileRecordingFailed", e.getMessage(), null); } - result.success(null); } public void dispose() { diff --git a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/CameraApiImpl.java b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/CameraApiImpl.java new file mode 100644 index 000000000000..552a7ddfa3f5 --- /dev/null +++ b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/CameraApiImpl.java @@ -0,0 +1,352 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.camera; + +import android.app.Activity; +import android.hardware.camera2.CameraAccessException; +import android.os.Handler; +import android.os.Looper; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; +import io.flutter.plugin.common.BinaryMessenger; +import io.flutter.plugin.common.EventChannel; +import io.flutter.plugins.camera.CameraPermissions.PermissionsRegistry; +import io.flutter.plugins.camera.features.CameraFeatureFactoryImpl; +import io.flutter.plugins.camera.features.Point; +import io.flutter.plugins.camera.features.exposurelock.ExposureMode; +import io.flutter.plugins.camera.features.flash.FlashMode; +import io.flutter.plugins.camera.features.resolution.ResolutionPreset; +import io.flutter.view.TextureRegistry; +import java.util.Collections; +import java.util.List; + +final class CameraApiImpl implements Messages.CameraApi { + private final Activity activity; + private final BinaryMessenger messenger; + private final CameraPermissions cameraPermissions; + private final PermissionsRegistry permissionsRegistry; + private final TextureRegistry textureRegistry; + private final EventChannel imageStreamChannel; + @VisibleForTesting @Nullable Camera camera; + + CameraApiImpl( + Activity activity, + BinaryMessenger messenger, + CameraPermissions cameraPermissions, + PermissionsRegistry permissionsAdder, + TextureRegistry textureRegistry) { + this.activity = activity; + this.messenger = messenger; + this.cameraPermissions = cameraPermissions; + this.permissionsRegistry = permissionsAdder; + this.textureRegistry = textureRegistry; + + imageStreamChannel = + new EventChannel(messenger, "plugins.flutter.io/camera_android/imageStream"); + Messages.CameraApi.setUp(messenger, this); + } + + void tearDownMessageHandler() { + Messages.CameraApi.setUp(messenger, null); + } + + private Long instantiateCamera(String cameraName, Messages.PlatformMediaSettings settings) + throws CameraAccessException { + TextureRegistry.SurfaceTextureEntry flutterSurfaceTexture = + textureRegistry.createSurfaceTexture(); + long cameraId = flutterSurfaceTexture.id(); + DartMessenger dartMessenger = + new DartMessenger( + new Handler(Looper.getMainLooper()), + new Messages.CameraGlobalEventApi(messenger), + new Messages.CameraEventApi(messenger, String.valueOf(cameraId))); + CameraProperties cameraProperties = + new CameraPropertiesImpl(cameraName, CameraUtils.getCameraManager(activity)); + Integer fps = (settings.getFps() == null) ? null : settings.getFps().intValue(); + Integer videoBitrate = + (settings.getVideoBitrate() == null) ? null : settings.getVideoBitrate().intValue(); + Integer audioBitrate = + (settings.getAudioBitrate() == null) ? null : settings.getAudioBitrate().intValue(); + ResolutionPreset resolutionPreset = + CameraUtils.resolutionPresetFromPigeon(settings.getResolutionPreset()); + + camera = + new Camera( + activity, + flutterSurfaceTexture, + new CameraFeatureFactoryImpl(), + dartMessenger, + cameraProperties, + new Camera.VideoCaptureSettings( + resolutionPreset, settings.getEnableAudio(), fps, videoBitrate, audioBitrate)); + + return flutterSurfaceTexture.id(); + } + + // We move catching CameraAccessException out of onMethodCall because it causes a crash + // on plugin registration for sdks incompatible with Camera2 (< 21). We want this plugin to + // to be able to compile with <21 sdks for apps that want the camera and support earlier version. + @SuppressWarnings("ConstantConditions") + private void handleException(Exception exception, Messages.Result result) { + // The code below exactly preserves the format of the native exceptions generated by pre-Pigeon + // code. Since `camera` currently leaks the raw platform exceptions to clients, there may be client + // code that relies on specific string values here, so these should not be changed. See + // https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#platform-exception-handling + // for longer-term solutions to this. + if (exception instanceof CameraAccessException) { + result.error(new Messages.FlutterError("CameraAccess", exception.getMessage(), null)); + return; + } + result.error(new Messages.FlutterError("error", exception.getMessage(), null)); + } + + private void handleException(Exception exception, Messages.VoidResult result) { + // The code below exactly preserves the format of the native exceptions generated by pre-Pigeon + // code. Since `camera` currently leaks the raw platform exceptions to clients, there may be client + // code that relies on specific string values here, so these should not be changed. See + // https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#platform-exception-handling + // for longer-term solutions to this. + if (exception instanceof CameraAccessException) { + result.error(new Messages.FlutterError("CameraAccess", exception.getMessage(), null)); + return; + } + result.error(new Messages.FlutterError("error", exception.getMessage(), null)); + } + + @NonNull + @Override + public List getAvailableCameras() { + if (activity == null) { + return Collections.emptyList(); + } + try { + return CameraUtils.getAvailableCameras(activity); + } catch (CameraAccessException e) { + throw new RuntimeException(e); + } + } + + @Override + public void create( + @NonNull String cameraName, + @NonNull Messages.PlatformMediaSettings settings, + @NonNull Messages.Result result) { + if (camera != null) { + camera.close(); + } + + cameraPermissions.requestPermissions( + activity, + permissionsRegistry, + settings.getEnableAudio(), + (String errCode, String errDesc) -> { + if (errCode == null) { + try { + result.success(instantiateCamera(cameraName, settings)); + } catch (Exception e) { + handleException(e, result); + } + } else { + result.error(new Messages.FlutterError(errCode, errDesc, null)); + } + }); + } + + @Override + public void initialize(@NonNull Messages.PlatformImageFormatGroup imageFormat) { + if (camera == null) { + throw new Messages.FlutterError( + "cameraNotFound", + "Camera not found. Please call the 'create' method before calling 'initialize'.", + null); + } + try { + camera.open(CameraUtils.imageFormatGroupFromPigeon(imageFormat)); + } catch (CameraAccessException e) { + throw new Messages.FlutterError("CameraAccessException", e.getMessage(), null); + } + } + + @Override + public void takePicture(@NonNull Messages.Result result) { + camera.takePicture(result); + } + + @Override + public void startVideoRecording(@NonNull Boolean enableStream) { + camera.startVideoRecording(enableStream ? imageStreamChannel : null); + } + + @NonNull + @Override + public String stopVideoRecording() { + return camera.stopVideoRecording(); + } + + @Override + public void pauseVideoRecording() { + camera.pauseVideoRecording(); + } + + @Override + public void resumeVideoRecording() { + camera.resumeVideoRecording(); + } + + @Override + public void setFlashMode( + @NonNull Messages.PlatformFlashMode flashMode, @NonNull Messages.VoidResult result) { + FlashMode mode = CameraUtils.flashModeFromPigeon(flashMode); + try { + camera.setFlashMode(result, mode); + } catch (Exception e) { + handleException(e, result); + } + } + + @Override + public void setExposureMode( + @NonNull Messages.PlatformExposureMode exposureMode, @NonNull Messages.VoidResult result) { + ExposureMode mode = CameraUtils.exposureModeFromPigeon(exposureMode); + try { + camera.setExposureMode(result, mode); + } catch (Exception e) { + handleException(e, result); + } + } + + @Override + public void setExposurePoint( + @Nullable Messages.PlatformPoint point, @NonNull Messages.VoidResult result) { + try { + camera.setExposurePoint(result, point == null ? null : new Point(point.getX(), point.getY())); + } catch (Exception e) { + handleException(e, result); + } + } + + @NonNull + @Override + public Double getMinExposureOffset() { + return camera.getMinExposureOffset(); + } + + @NonNull + @Override + public Double getMaxExposureOffset() { + return camera.getMaxExposureOffset(); + } + + @NonNull + @Override + public Double getExposureOffsetStepSize() { + return camera.getExposureOffsetStepSize(); + } + + @Override + public void setExposureOffset(@NonNull Double offset, @NonNull Messages.Result result) { + try { + camera.setExposureOffset(result, offset); + } catch (Exception e) { + handleException(e, result); + } + } + + @Override + public void setFocusMode(@NonNull Messages.PlatformFocusMode focusMode) { + camera.setFocusMode(CameraUtils.focusModeFromPigeon(focusMode)); + } + + @Override + public void setFocusPoint( + @Nullable Messages.PlatformPoint point, @NonNull Messages.VoidResult result) { + try { + camera.setFocusPoint(result, point == null ? null : new Point(point.getX(), point.getY())); + } catch (Exception e) { + handleException(e, result); + } + } + + @Override + public void startImageStream() { + try { + camera.startPreviewWithImageStream(imageStreamChannel); + } catch (CameraAccessException e) { + throw new Messages.FlutterError("CameraAccessException", e.getMessage(), null); + } + } + + @Override + public void stopImageStream() { + try { + camera.startPreview(); + } catch (Exception e) { + throw new Messages.FlutterError(e.getClass().getName(), e.getMessage(), null); + } + } + + @NonNull + @Override + public Double getMaxZoomLevel() { + assert camera != null; + return (double) camera.getMaxZoomLevel(); + } + + @NonNull + @Override + public Double getMinZoomLevel() { + assert camera != null; + return (double) camera.getMinZoomLevel(); + } + + @Override + public void setZoomLevel(@NonNull Double zoom, @NonNull Messages.VoidResult result) { + assert camera != null; + camera.setZoomLevel(result, zoom.floatValue()); + } + + @Override + public void lockCaptureOrientation( + @NonNull Messages.PlatformDeviceOrientation platformOrientation) { + camera.lockCaptureOrientation(CameraUtils.orientationFromPigeon(platformOrientation)); + } + + @Override + public void unlockCaptureOrientation() { + camera.unlockCaptureOrientation(); + } + + @Override + public void pausePreview() { + try { + camera.pausePreview(); + } catch (CameraAccessException e) { + throw new Messages.FlutterError("CameraAccessException", e.getMessage(), null); + } + } + + @Override + public void resumePreview() { + camera.resumePreview(); + } + + @Override + public void setDescriptionWhileRecording(@NonNull String cameraName) { + try { + camera.setDescriptionWhileRecording( + new CameraPropertiesImpl(cameraName, CameraUtils.getCameraManager(activity))); + } catch (CameraAccessException e) { + throw new Messages.FlutterError("CameraAccessException", e.getMessage(), null); + } + } + + @Override + public void dispose() { + if (camera != null) { + camera.dispose(); + } + } +} diff --git a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java index aff225e2c35a..e7f6a56a976f 100644 --- a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java +++ b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java @@ -24,7 +24,7 @@ public final class CameraPlugin implements FlutterPlugin, ActivityAware { private static final String TAG = "CameraPlugin"; private @Nullable FlutterPluginBinding flutterPluginBinding; - private @Nullable MethodCallHandlerImpl methodCallHandler; + private @Nullable CameraApiImpl cameraApi; /** * Initialize this within the {@code #configureFlutterEngine} of a Flutter activity or fragment. @@ -55,9 +55,9 @@ public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) { @Override public void onDetachedFromActivity() { // Could be on too low of an SDK to have started listening originally. - if (methodCallHandler != null) { - methodCallHandler.stopListening(); - methodCallHandler = null; + if (cameraApi != null) { + cameraApi.tearDownMessageHandler(); + cameraApi = null; } } @@ -76,8 +76,8 @@ private void maybeStartListening( BinaryMessenger messenger, PermissionsRegistry permissionsRegistry, TextureRegistry textureRegistry) { - methodCallHandler = - new MethodCallHandlerImpl( + cameraApi = + new CameraApiImpl( activity, messenger, new CameraPermissions(), permissionsRegistry, textureRegistry); } } diff --git a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java index d98984cbf2f5..c5f077c9e184 100644 --- a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java +++ b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java @@ -6,16 +6,19 @@ import android.app.Activity; import android.content.Context; +import android.graphics.ImageFormat; import android.hardware.camera2.CameraAccessException; import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CameraManager; import android.hardware.camera2.CameraMetadata; import androidx.annotation.NonNull; import io.flutter.embedding.engine.systemchannels.PlatformChannel; +import io.flutter.plugins.camera.features.autofocus.FocusMode; +import io.flutter.plugins.camera.features.exposurelock.ExposureMode; +import io.flutter.plugins.camera.features.flash.FlashMode; +import io.flutter.plugins.camera.features.resolution.ResolutionPreset; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; /** Provides various utilities for camera. */ public final class CameraUtils { @@ -33,56 +36,24 @@ static CameraManager getCameraManager(Context context) { } /** - * Serializes the {@link PlatformChannel.DeviceOrientation} to a string value. + * Converts a raw integer to a PlatformCameraLensDirection enum. * - * @param orientation The orientation to serialize. - * @return The serialized orientation. - * @throws UnsupportedOperationException when the provided orientation not have a corresponding - * string value. + * @param lensDirection One of CameraMetadata.LENS_FACING_FRONT, LENS_FACING_BACK, or + * LENS_FACING_EXTERNAL. + * @return One of Messages.PlatformCameraLensDirection.FRONT, BACK, or EXTERNAL. */ - static String serializeDeviceOrientation(PlatformChannel.DeviceOrientation orientation) { - if (orientation == null) - throw new UnsupportedOperationException("Could not serialize null device orientation."); - switch (orientation) { - case PORTRAIT_UP: - return "portraitUp"; - case PORTRAIT_DOWN: - return "portraitDown"; - case LANDSCAPE_LEFT: - return "landscapeLeft"; - case LANDSCAPE_RIGHT: - return "landscapeRight"; - default: - throw new UnsupportedOperationException( - "Could not serialize device orientation: " + orientation.toString()); - } - } - - /** - * Deserializes a string value to its corresponding {@link PlatformChannel.DeviceOrientation} - * value. - * - * @param orientation The string value to deserialize. - * @return The deserialized orientation. - * @throws UnsupportedOperationException when the provided string value does not have a - * corresponding {@link PlatformChannel.DeviceOrientation}. - */ - static PlatformChannel.DeviceOrientation deserializeDeviceOrientation(String orientation) { - if (orientation == null) - throw new UnsupportedOperationException("Could not deserialize null device orientation."); - switch (orientation) { - case "portraitUp": - return PlatformChannel.DeviceOrientation.PORTRAIT_UP; - case "portraitDown": - return PlatformChannel.DeviceOrientation.PORTRAIT_DOWN; - case "landscapeLeft": - return PlatformChannel.DeviceOrientation.LANDSCAPE_LEFT; - case "landscapeRight": - return PlatformChannel.DeviceOrientation.LANDSCAPE_RIGHT; - default: - throw new UnsupportedOperationException( - "Could not deserialize device orientation: " + orientation); + static Messages.PlatformCameraLensDirection lensDirectionFromInteger(int lensDirection) { + switch (lensDirection) { + case CameraMetadata.LENS_FACING_FRONT: + return Messages.PlatformCameraLensDirection.FRONT; + case CameraMetadata.LENS_FACING_BACK: + return Messages.PlatformCameraLensDirection.BACK; + case CameraMetadata.LENS_FACING_EXTERNAL: + return Messages.PlatformCameraLensDirection.EXTERNAL; } + // CameraMetadata is defined in the Android API. In the event that a new value is added, a + // default fallback value of FRONT is returned. + return Messages.PlatformCameraLensDirection.FRONT; } /** @@ -93,11 +64,11 @@ static PlatformChannel.DeviceOrientation deserializeDeviceOrientation(String ori * @throws CameraAccessException when the camera could not be accessed. */ @NonNull - public static List> getAvailableCameras(@NonNull Activity activity) - throws CameraAccessException { + public static List getAvailableCameras( + @NonNull Activity activity) throws CameraAccessException { CameraManager cameraManager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE); String[] cameraNames = cameraManager.getCameraIdList(); - List> cameras = new ArrayList<>(); + List cameras = new ArrayList<>(); for (String cameraName : cameraNames) { int cameraId; try { @@ -109,26 +80,201 @@ public static List> getAvailableCameras(@NonNull Activity ac continue; } - HashMap details = new HashMap<>(); CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraName); - details.put("name", cameraName); int sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION); - details.put("sensorOrientation", sensorOrientation); int lensFacing = characteristics.get(CameraCharacteristics.LENS_FACING); - switch (lensFacing) { - case CameraMetadata.LENS_FACING_FRONT: - details.put("lensFacing", "front"); - break; - case CameraMetadata.LENS_FACING_BACK: - details.put("lensFacing", "back"); - break; - case CameraMetadata.LENS_FACING_EXTERNAL: - details.put("lensFacing", "external"); - break; - } + Messages.PlatformCameraLensDirection lensDirection = lensDirectionFromInteger(lensFacing); + Messages.PlatformCameraDescription details = + new Messages.PlatformCameraDescription.Builder() + .setName(cameraName) + .setSensorOrientation((long) sensorOrientation) + .setLensDirection(lensDirection) + .build(); cameras.add(details); } return cameras; } + + /** + * Converts a DeviceOrientation from the systemchannels package to a PlatformDeviceOrientation + * from Pigeon. + * + * @param orientation A DeviceOrientation. + * @return The corresponding PlatformDeviceOrientation. + */ + @NonNull + public static Messages.PlatformDeviceOrientation orientationToPigeon( + @NonNull PlatformChannel.DeviceOrientation orientation) { + switch (orientation) { + case PORTRAIT_UP: + return Messages.PlatformDeviceOrientation.PORTRAIT_UP; + case PORTRAIT_DOWN: + return Messages.PlatformDeviceOrientation.PORTRAIT_DOWN; + case LANDSCAPE_LEFT: + return Messages.PlatformDeviceOrientation.LANDSCAPE_LEFT; + case LANDSCAPE_RIGHT: + return Messages.PlatformDeviceOrientation.LANDSCAPE_RIGHT; + } + return Messages.PlatformDeviceOrientation.PORTRAIT_UP; + } + + /** + * Converts a PlatformDeviceOrientation from Pigeon to DeviceOrientation from PlatformChannel. + * + * @param orientation A PlatformDeviceOrientation + * @return The corresponding DeviceOrientation. Defaults to PORTRAIT_UP. + */ + @NonNull + public static PlatformChannel.DeviceOrientation orientationFromPigeon( + @NonNull Messages.PlatformDeviceOrientation orientation) { + switch (orientation) { + case PORTRAIT_UP: + return PlatformChannel.DeviceOrientation.PORTRAIT_UP; + case PORTRAIT_DOWN: + return PlatformChannel.DeviceOrientation.PORTRAIT_DOWN; + case LANDSCAPE_LEFT: + return PlatformChannel.DeviceOrientation.LANDSCAPE_LEFT; + case LANDSCAPE_RIGHT: + return PlatformChannel.DeviceOrientation.LANDSCAPE_RIGHT; + } + throw new IllegalStateException("Unreachable code"); + } + + /** + * Converts a FocusMode from the autofocus package to a PlatformFocusMode from Pigeon. + * + * @param focusMode A FocusMode. + * @return The corresponding PlatformFocusMode. + */ + @NonNull + public static Messages.PlatformFocusMode focusModeToPigeon(@NonNull FocusMode focusMode) { + switch (focusMode) { + case auto: + return Messages.PlatformFocusMode.AUTO; + case locked: + return Messages.PlatformFocusMode.LOCKED; + } + return Messages.PlatformFocusMode.AUTO; + } + + /** + * Converts a PlatformFocusMode from Pigeon to a FocusMode from the autofocus package. + * + * @param focusMode A PlatformFocusMode. + * @return The corresponding FocusMode. + */ + @NonNull + public static FocusMode focusModeFromPigeon(@NonNull Messages.PlatformFocusMode focusMode) { + switch (focusMode) { + case AUTO: + return FocusMode.auto; + case LOCKED: + return FocusMode.locked; + } + throw new IllegalStateException("Unreachable code"); + } + + /** + * Converts an ExposureMode from the exposurelock package to a PlatformExposureMode from Pigeon. + * + * @param exposureMode An ExposureMode. + * @return The corresponding PlatformExposureMode. + */ + @NonNull + public static Messages.PlatformExposureMode exposureModeToPigeon( + @NonNull ExposureMode exposureMode) { + switch (exposureMode) { + case auto: + return Messages.PlatformExposureMode.AUTO; + case locked: + return Messages.PlatformExposureMode.LOCKED; + } + return Messages.PlatformExposureMode.AUTO; + } + + /** + * Converts a PlatformExposureMode to ExposureMode from the exposurelock package. + * + * @param mode A PlatformExposureMode. + * @return The corresponding ExposureMode. + */ + @NonNull + public static ExposureMode exposureModeFromPigeon(@NonNull Messages.PlatformExposureMode mode) { + switch (mode) { + case AUTO: + return ExposureMode.auto; + case LOCKED: + return ExposureMode.locked; + } + throw new IllegalStateException("Unreachable code"); + } + + /** + * Converts a PlatformResolutionPreset from Pigeon to a ResolutionPreset from the resolution + * package. + * + * @param preset A PlatformResolutionPreset. + * @return The corresponding ResolutionPreset. + */ + @NonNull + public static ResolutionPreset resolutionPresetFromPigeon( + @NonNull Messages.PlatformResolutionPreset preset) { + switch (preset) { + case LOW: + return ResolutionPreset.low; + case MEDIUM: + return ResolutionPreset.medium; + case HIGH: + return ResolutionPreset.high; + case VERY_HIGH: + return ResolutionPreset.veryHigh; + case ULTRA_HIGH: + return ResolutionPreset.ultraHigh; + case MAX: + return ResolutionPreset.max; + } + throw new IllegalStateException("Unreachable code"); + } + + /** + * Converts a PlatformImageFormatGroup from Pigeon to an Integer representing an image format. + * + * @param format A PlatformImageFormatGroup. + * @return The corresponding integer code. Defaults to YUV_420_888. + */ + @NonNull + public static Integer imageFormatGroupFromPigeon( + @NonNull Messages.PlatformImageFormatGroup format) { + switch (format) { + case YUV420: + return ImageFormat.YUV_420_888; + case JPEG: + return ImageFormat.JPEG; + case NV21: + return ImageFormat.NV21; + } + throw new IllegalStateException("Unreachable code"); + } + + /** + * Converts a PlatformFlashMode from Pigeon to a FlashMode from the flash package. + * + * @param mode A PlatformFlashMode. + * @return The corresponding FlashMode. + */ + @NonNull + public static FlashMode flashModeFromPigeon(@NonNull Messages.PlatformFlashMode mode) { + switch (mode) { + case AUTO: + return FlashMode.auto; + case OFF: + return FlashMode.off; + case ALWAYS: + return FlashMode.always; + case TORCH: + return FlashMode.torch; + } + throw new IllegalStateException("Unreachable code"); + } } diff --git a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java index e2b2ef80820d..800e823346b8 100644 --- a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java +++ b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java @@ -5,69 +5,36 @@ package io.flutter.plugins.camera; import android.os.Handler; -import android.text.TextUtils; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import io.flutter.embedding.engine.systemchannels.PlatformChannel; -import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugins.camera.features.autofocus.FocusMode; import io.flutter.plugins.camera.features.exposurelock.ExposureMode; -import java.util.HashMap; -import java.util.Map; /** Utility class that facilitates communication to the Flutter client */ public class DartMessenger { @NonNull private final Handler handler; - @Nullable MethodChannel cameraChannel; - @Nullable MethodChannel deviceChannel; - - /** Specifies the different device related message types. */ - enum DeviceEventType { - /** Indicates the device's orientation has changed. */ - ORIENTATION_CHANGED("orientation_changed"); - final String method; - - DeviceEventType(String method) { - this.method = method; - } - } - - /** Specifies the different camera related message types. */ - enum CameraEventType { - /** Indicates that an error occurred while interacting with the camera. */ - ERROR("error"), - /** Indicates that the camera is closing. */ - CLOSING("camera_closing"), - /** Indicates that the camera is initialized. */ - INITIALIZED("initialized"); - - final String method; - - /** - * Converts the supplied method name to the matching {@link CameraEventType}. - * - * @param method name to be converted into a {@link CameraEventType}. - */ - CameraEventType(String method) { - this.method = method; - } - } + Messages.CameraGlobalEventApi globalEventApi; + Messages.CameraEventApi eventApi; /** * Creates a new instance of the {@link DartMessenger} class. * - * @param messenger is the {@link BinaryMessenger} that is used to communicate with Flutter. - * @param cameraId identifies the camera which is the source of the communication. * @param handler the handler used to manage the thread's message queue. This should always be a * handler managing the main thread since communication with Flutter should always happen on * the main thread. The handler is mainly supplied so it will be easier test this class. + * @param globalEventApi the API used to consume calls to dart that are not tied to a specific + * camera instance. + * @param eventApi the API used to consume calls to dart that are tied to this specific camera. */ - DartMessenger(BinaryMessenger messenger, long cameraId, @NonNull Handler handler) { - cameraChannel = - new MethodChannel(messenger, "plugins.flutter.io/camera_android/camera" + cameraId); - deviceChannel = new MethodChannel(messenger, "plugins.flutter.io/camera_android/fromPlatform"); + DartMessenger( + @NonNull Handler handler, + Messages.CameraGlobalEventApi globalEventApi, + Messages.CameraEventApi eventApi) { this.handler = handler; + this.globalEventApi = globalEventApi; + this.eventApi = eventApi; } /** @@ -77,13 +44,10 @@ enum CameraEventType { */ public void sendDeviceOrientationChangeEvent( @NonNull PlatformChannel.DeviceOrientation orientation) { - this.send( - DeviceEventType.ORIENTATION_CHANGED, - new HashMap() { - { - put("orientation", CameraUtils.serializeDeviceOrientation(orientation)); - } - }); + handler.post( + () -> + globalEventApi.deviceOrientationChanged( + CameraUtils.orientationToPigeon(orientation), new NoOpVoidResult())); } /** @@ -109,23 +73,26 @@ void sendCameraInitializedEvent( assert (focusMode != null); assert (exposurePointSupported != null); assert (focusPointSupported != null); - this.send( - CameraEventType.INITIALIZED, - new HashMap() { - { - put("previewWidth", previewWidth.doubleValue()); - put("previewHeight", previewHeight.doubleValue()); - put("exposureMode", exposureMode.toString()); - put("focusMode", focusMode.toString()); - put("exposurePointSupported", exposurePointSupported); - put("focusPointSupported", focusPointSupported); - } - }); + handler.post( + () -> + eventApi.initialized( + new Messages.PlatformCameraState.Builder() + .setPreviewSize( + new Messages.PlatformSize.Builder() + .setWidth(previewWidth.doubleValue()) + .setHeight(previewHeight.doubleValue()) + .build()) + .setExposurePointSupported(exposurePointSupported) + .setFocusPointSupported(focusPointSupported) + .setExposureMode(CameraUtils.exposureModeToPigeon(exposureMode)) + .setFocusMode(CameraUtils.focusModeToPigeon(focusMode)) + .build(), + new NoOpVoidResult())); } /** Sends a message to the Flutter client informing that the camera is closing. */ void sendCameraClosingEvent() { - send(CameraEventType.CLOSING); + handler.post(() -> eventApi.closed(new NoOpVoidResult())); } /** @@ -134,44 +101,8 @@ void sendCameraClosingEvent() { * * @param description contains details regarding the error that occurred. */ - void sendCameraErrorEvent(@Nullable String description) { - this.send( - CameraEventType.ERROR, - new HashMap() { - { - if (!TextUtils.isEmpty(description)) put("description", description); - } - }); - } - - private void send(CameraEventType eventType) { - send(eventType, new HashMap<>()); - } - - private void send(CameraEventType eventType, Map args) { - if (cameraChannel == null) { - return; - } - - handler.post( - new Runnable() { - @Override - public void run() { - cameraChannel.invokeMethod(eventType.method, args); - } - }); - } - - private void send(DeviceEventType eventType) { - send(eventType, new HashMap<>()); - } - - private void send(DeviceEventType eventType, Map args) { - if (deviceChannel == null) { - return; - } - - handler.post(() -> deviceChannel.invokeMethod(eventType.method, args)); + void sendCameraErrorEvent(@NonNull String description) { + handler.post(() -> eventApi.error(description, new NoOpVoidResult())); } /** @@ -179,7 +110,7 @@ private void send(DeviceEventType eventType, Map args) { * * @param payload The payload to send. */ - public void finish(@NonNull MethodChannel.Result result, @Nullable Object payload) { + public void finish(@NonNull Messages.Result result, @NonNull T payload) { handler.post(() -> result.success(payload)); } @@ -190,11 +121,12 @@ public void finish(@NonNull MethodChannel.Result result, @Nullable Object payloa * @param errorMessage error message. * @param errorDetails error details. */ - public void error( - @NonNull MethodChannel.Result result, + public void error( + @NonNull Messages.Result result, @NonNull String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { - handler.post(() -> result.error(errorCode, errorMessage, errorDetails)); + handler.post( + () -> result.error(new Messages.FlutterError(errorCode, errorMessage, errorDetails))); } } diff --git a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/Messages.java b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/Messages.java new file mode 100644 index 000000000000..bdb6e2b41387 --- /dev/null +++ b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/Messages.java @@ -0,0 +1,1926 @@ +// 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 (v22.4.1), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +package io.flutter.plugins.camera; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.CLASS; + +import android.util.Log; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import io.flutter.plugin.common.BasicMessageChannel; +import io.flutter.plugin.common.BinaryMessenger; +import io.flutter.plugin.common.MessageCodec; +import io.flutter.plugin.common.StandardMessageCodec; +import java.io.ByteArrayOutputStream; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +/** Generated class from Pigeon. */ +@SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression", "serial"}) +public class Messages { + + /** Error class for passing custom error details to Flutter via a thrown PlatformException. */ + public static class FlutterError extends RuntimeException { + + /** The error code. */ + public final String code; + + /** The error details. Must be a datatype supported by the api codec. */ + public final Object details; + + public FlutterError(@NonNull String code, @Nullable String message, @Nullable Object details) { + super(message); + this.code = code; + this.details = details; + } + } + + @NonNull + protected static ArrayList wrapError(@NonNull Throwable exception) { + ArrayList errorList = new ArrayList<>(3); + if (exception instanceof FlutterError) { + FlutterError error = (FlutterError) exception; + errorList.add(error.code); + errorList.add(error.getMessage()); + errorList.add(error.details); + } else { + errorList.add(exception.toString()); + errorList.add(exception.getClass().getSimpleName()); + errorList.add( + "Cause: " + exception.getCause() + ", Stacktrace: " + Log.getStackTraceString(exception)); + } + return errorList; + } + + @NonNull + protected static FlutterError createConnectionError(@NonNull String channelName) { + return new FlutterError( + "channel-error", "Unable to establish connection on channel: " + channelName + ".", ""); + } + + @Target(METHOD) + @Retention(CLASS) + @interface CanIgnoreReturnValue {} + + /** Pigeon equivalent of [CameraLensDirection]. */ + public enum PlatformCameraLensDirection { + FRONT(0), + BACK(1), + EXTERNAL(2); + + final int index; + + PlatformCameraLensDirection(final int index) { + this.index = index; + } + } + + /** Pigeon equivalent of [DeviceOrientation]. */ + public enum PlatformDeviceOrientation { + PORTRAIT_UP(0), + PORTRAIT_DOWN(1), + LANDSCAPE_LEFT(2), + LANDSCAPE_RIGHT(3); + + final int index; + + PlatformDeviceOrientation(final int index) { + this.index = index; + } + } + + /** Pigeon equivalent of [ExposureMode]. */ + public enum PlatformExposureMode { + AUTO(0), + LOCKED(1); + + final int index; + + PlatformExposureMode(final int index) { + this.index = index; + } + } + + /** Pigeon equivalent of [FocusMode]. */ + public enum PlatformFocusMode { + AUTO(0), + LOCKED(1); + + final int index; + + PlatformFocusMode(final int index) { + this.index = index; + } + } + + /** Pigeon equivalent of [ResolutionPreset]. */ + public enum PlatformResolutionPreset { + LOW(0), + MEDIUM(1), + HIGH(2), + VERY_HIGH(3), + ULTRA_HIGH(4), + MAX(5); + + final int index; + + PlatformResolutionPreset(final int index) { + this.index = index; + } + } + + /** Pigeon equivalent of [ImageFormatGroup]. */ + public enum PlatformImageFormatGroup { + /** The default for Android. */ + YUV420(0), + JPEG(1), + NV21(2); + + final int index; + + PlatformImageFormatGroup(final int index) { + this.index = index; + } + } + + /** Pigeon equivalent of [FlashMode]. */ + public enum PlatformFlashMode { + OFF(0), + AUTO(1), + ALWAYS(2), + TORCH(3); + + final int index; + + PlatformFlashMode(final int index) { + this.index = index; + } + } + + /** + * Pigeon equivalent of [CameraDescription]. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformCameraDescription { + private @NonNull String name; + + public @NonNull String getName() { + return name; + } + + public void setName(@NonNull String setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"name\" is null."); + } + this.name = setterArg; + } + + private @NonNull PlatformCameraLensDirection lensDirection; + + public @NonNull PlatformCameraLensDirection getLensDirection() { + return lensDirection; + } + + public void setLensDirection(@NonNull PlatformCameraLensDirection setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"lensDirection\" is null."); + } + this.lensDirection = setterArg; + } + + private @NonNull Long sensorOrientation; + + public @NonNull Long getSensorOrientation() { + return sensorOrientation; + } + + public void setSensorOrientation(@NonNull Long setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"sensorOrientation\" is null."); + } + this.sensorOrientation = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformCameraDescription() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformCameraDescription that = (PlatformCameraDescription) o; + return name.equals(that.name) + && lensDirection.equals(that.lensDirection) + && sensorOrientation.equals(that.sensorOrientation); + } + + @Override + public int hashCode() { + return Objects.hash(name, lensDirection, sensorOrientation); + } + + public static final class Builder { + + private @Nullable String name; + + @CanIgnoreReturnValue + public @NonNull Builder setName(@NonNull String setterArg) { + this.name = setterArg; + return this; + } + + private @Nullable PlatformCameraLensDirection lensDirection; + + @CanIgnoreReturnValue + public @NonNull Builder setLensDirection(@NonNull PlatformCameraLensDirection setterArg) { + this.lensDirection = setterArg; + return this; + } + + private @Nullable Long sensorOrientation; + + @CanIgnoreReturnValue + public @NonNull Builder setSensorOrientation(@NonNull Long setterArg) { + this.sensorOrientation = setterArg; + return this; + } + + public @NonNull PlatformCameraDescription build() { + PlatformCameraDescription pigeonReturn = new PlatformCameraDescription(); + pigeonReturn.setName(name); + pigeonReturn.setLensDirection(lensDirection); + pigeonReturn.setSensorOrientation(sensorOrientation); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(3); + toListResult.add(name); + toListResult.add(lensDirection); + toListResult.add(sensorOrientation); + return toListResult; + } + + static @NonNull PlatformCameraDescription fromList(@NonNull ArrayList pigeonVar_list) { + PlatformCameraDescription pigeonResult = new PlatformCameraDescription(); + Object name = pigeonVar_list.get(0); + pigeonResult.setName((String) name); + Object lensDirection = pigeonVar_list.get(1); + pigeonResult.setLensDirection((PlatformCameraLensDirection) lensDirection); + Object sensorOrientation = pigeonVar_list.get(2); + pigeonResult.setSensorOrientation((Long) sensorOrientation); + return pigeonResult; + } + } + + /** + * Data needed for [CameraInitializedEvent]. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformCameraState { + private @NonNull PlatformSize previewSize; + + public @NonNull PlatformSize getPreviewSize() { + return previewSize; + } + + public void setPreviewSize(@NonNull PlatformSize setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"previewSize\" is null."); + } + this.previewSize = setterArg; + } + + private @NonNull PlatformExposureMode exposureMode; + + public @NonNull PlatformExposureMode getExposureMode() { + return exposureMode; + } + + public void setExposureMode(@NonNull PlatformExposureMode setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"exposureMode\" is null."); + } + this.exposureMode = setterArg; + } + + private @NonNull PlatformFocusMode focusMode; + + public @NonNull PlatformFocusMode getFocusMode() { + return focusMode; + } + + public void setFocusMode(@NonNull PlatformFocusMode setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"focusMode\" is null."); + } + this.focusMode = setterArg; + } + + private @NonNull Boolean exposurePointSupported; + + public @NonNull Boolean getExposurePointSupported() { + return exposurePointSupported; + } + + public void setExposurePointSupported(@NonNull Boolean setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"exposurePointSupported\" is null."); + } + this.exposurePointSupported = setterArg; + } + + private @NonNull Boolean focusPointSupported; + + public @NonNull Boolean getFocusPointSupported() { + return focusPointSupported; + } + + public void setFocusPointSupported(@NonNull Boolean setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"focusPointSupported\" is null."); + } + this.focusPointSupported = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformCameraState() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformCameraState that = (PlatformCameraState) o; + return previewSize.equals(that.previewSize) + && exposureMode.equals(that.exposureMode) + && focusMode.equals(that.focusMode) + && exposurePointSupported.equals(that.exposurePointSupported) + && focusPointSupported.equals(that.focusPointSupported); + } + + @Override + public int hashCode() { + return Objects.hash( + previewSize, exposureMode, focusMode, exposurePointSupported, focusPointSupported); + } + + public static final class Builder { + + private @Nullable PlatformSize previewSize; + + @CanIgnoreReturnValue + public @NonNull Builder setPreviewSize(@NonNull PlatformSize setterArg) { + this.previewSize = setterArg; + return this; + } + + private @Nullable PlatformExposureMode exposureMode; + + @CanIgnoreReturnValue + public @NonNull Builder setExposureMode(@NonNull PlatformExposureMode setterArg) { + this.exposureMode = setterArg; + return this; + } + + private @Nullable PlatformFocusMode focusMode; + + @CanIgnoreReturnValue + public @NonNull Builder setFocusMode(@NonNull PlatformFocusMode setterArg) { + this.focusMode = setterArg; + return this; + } + + private @Nullable Boolean exposurePointSupported; + + @CanIgnoreReturnValue + public @NonNull Builder setExposurePointSupported(@NonNull Boolean setterArg) { + this.exposurePointSupported = setterArg; + return this; + } + + private @Nullable Boolean focusPointSupported; + + @CanIgnoreReturnValue + public @NonNull Builder setFocusPointSupported(@NonNull Boolean setterArg) { + this.focusPointSupported = setterArg; + return this; + } + + public @NonNull PlatformCameraState build() { + PlatformCameraState pigeonReturn = new PlatformCameraState(); + pigeonReturn.setPreviewSize(previewSize); + pigeonReturn.setExposureMode(exposureMode); + pigeonReturn.setFocusMode(focusMode); + pigeonReturn.setExposurePointSupported(exposurePointSupported); + pigeonReturn.setFocusPointSupported(focusPointSupported); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(5); + toListResult.add(previewSize); + toListResult.add(exposureMode); + toListResult.add(focusMode); + toListResult.add(exposurePointSupported); + toListResult.add(focusPointSupported); + return toListResult; + } + + static @NonNull PlatformCameraState fromList(@NonNull ArrayList pigeonVar_list) { + PlatformCameraState pigeonResult = new PlatformCameraState(); + Object previewSize = pigeonVar_list.get(0); + pigeonResult.setPreviewSize((PlatformSize) previewSize); + Object exposureMode = pigeonVar_list.get(1); + pigeonResult.setExposureMode((PlatformExposureMode) exposureMode); + Object focusMode = pigeonVar_list.get(2); + pigeonResult.setFocusMode((PlatformFocusMode) focusMode); + Object exposurePointSupported = pigeonVar_list.get(3); + pigeonResult.setExposurePointSupported((Boolean) exposurePointSupported); + Object focusPointSupported = pigeonVar_list.get(4); + pigeonResult.setFocusPointSupported((Boolean) focusPointSupported); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of [Size]. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformSize { + private @NonNull Double width; + + public @NonNull Double getWidth() { + return width; + } + + public void setWidth(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"width\" is null."); + } + this.width = setterArg; + } + + private @NonNull Double height; + + public @NonNull Double getHeight() { + return height; + } + + public void setHeight(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"height\" is null."); + } + this.height = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformSize() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformSize that = (PlatformSize) o; + return width.equals(that.width) && height.equals(that.height); + } + + @Override + public int hashCode() { + return Objects.hash(width, height); + } + + public static final class Builder { + + private @Nullable Double width; + + @CanIgnoreReturnValue + public @NonNull Builder setWidth(@NonNull Double setterArg) { + this.width = setterArg; + return this; + } + + private @Nullable Double height; + + @CanIgnoreReturnValue + public @NonNull Builder setHeight(@NonNull Double setterArg) { + this.height = setterArg; + return this; + } + + public @NonNull PlatformSize build() { + PlatformSize pigeonReturn = new PlatformSize(); + pigeonReturn.setWidth(width); + pigeonReturn.setHeight(height); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(2); + toListResult.add(width); + toListResult.add(height); + return toListResult; + } + + static @NonNull PlatformSize fromList(@NonNull ArrayList pigeonVar_list) { + PlatformSize pigeonResult = new PlatformSize(); + Object width = pigeonVar_list.get(0); + pigeonResult.setWidth((Double) width); + Object height = pigeonVar_list.get(1); + pigeonResult.setHeight((Double) height); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of [Point]. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformPoint { + private @NonNull Double x; + + public @NonNull Double getX() { + return x; + } + + public void setX(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"x\" is null."); + } + this.x = setterArg; + } + + private @NonNull Double y; + + public @NonNull Double getY() { + return y; + } + + public void setY(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"y\" is null."); + } + this.y = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformPoint() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformPoint that = (PlatformPoint) o; + return x.equals(that.x) && y.equals(that.y); + } + + @Override + public int hashCode() { + return Objects.hash(x, y); + } + + public static final class Builder { + + private @Nullable Double x; + + @CanIgnoreReturnValue + public @NonNull Builder setX(@NonNull Double setterArg) { + this.x = setterArg; + return this; + } + + private @Nullable Double y; + + @CanIgnoreReturnValue + public @NonNull Builder setY(@NonNull Double setterArg) { + this.y = setterArg; + return this; + } + + public @NonNull PlatformPoint build() { + PlatformPoint pigeonReturn = new PlatformPoint(); + pigeonReturn.setX(x); + pigeonReturn.setY(y); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(2); + toListResult.add(x); + toListResult.add(y); + return toListResult; + } + + static @NonNull PlatformPoint fromList(@NonNull ArrayList pigeonVar_list) { + PlatformPoint pigeonResult = new PlatformPoint(); + Object x = pigeonVar_list.get(0); + pigeonResult.setX((Double) x); + Object y = pigeonVar_list.get(1); + pigeonResult.setY((Double) y); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of [MediaSettings]. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformMediaSettings { + private @NonNull PlatformResolutionPreset resolutionPreset; + + public @NonNull PlatformResolutionPreset getResolutionPreset() { + return resolutionPreset; + } + + public void setResolutionPreset(@NonNull PlatformResolutionPreset setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"resolutionPreset\" is null."); + } + this.resolutionPreset = setterArg; + } + + private @Nullable Long fps; + + public @Nullable Long getFps() { + return fps; + } + + public void setFps(@Nullable Long setterArg) { + this.fps = setterArg; + } + + private @Nullable Long videoBitrate; + + public @Nullable Long getVideoBitrate() { + return videoBitrate; + } + + public void setVideoBitrate(@Nullable Long setterArg) { + this.videoBitrate = setterArg; + } + + private @Nullable Long audioBitrate; + + public @Nullable Long getAudioBitrate() { + return audioBitrate; + } + + public void setAudioBitrate(@Nullable Long setterArg) { + this.audioBitrate = setterArg; + } + + private @NonNull Boolean enableAudio; + + public @NonNull Boolean getEnableAudio() { + return enableAudio; + } + + public void setEnableAudio(@NonNull Boolean setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"enableAudio\" is null."); + } + this.enableAudio = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformMediaSettings() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformMediaSettings that = (PlatformMediaSettings) o; + return resolutionPreset.equals(that.resolutionPreset) + && Objects.equals(fps, that.fps) + && Objects.equals(videoBitrate, that.videoBitrate) + && Objects.equals(audioBitrate, that.audioBitrate) + && enableAudio.equals(that.enableAudio); + } + + @Override + public int hashCode() { + return Objects.hash(resolutionPreset, fps, videoBitrate, audioBitrate, enableAudio); + } + + public static final class Builder { + + private @Nullable PlatformResolutionPreset resolutionPreset; + + @CanIgnoreReturnValue + public @NonNull Builder setResolutionPreset(@NonNull PlatformResolutionPreset setterArg) { + this.resolutionPreset = setterArg; + return this; + } + + private @Nullable Long fps; + + @CanIgnoreReturnValue + public @NonNull Builder setFps(@Nullable Long setterArg) { + this.fps = setterArg; + return this; + } + + private @Nullable Long videoBitrate; + + @CanIgnoreReturnValue + public @NonNull Builder setVideoBitrate(@Nullable Long setterArg) { + this.videoBitrate = setterArg; + return this; + } + + private @Nullable Long audioBitrate; + + @CanIgnoreReturnValue + public @NonNull Builder setAudioBitrate(@Nullable Long setterArg) { + this.audioBitrate = setterArg; + return this; + } + + private @Nullable Boolean enableAudio; + + @CanIgnoreReturnValue + public @NonNull Builder setEnableAudio(@NonNull Boolean setterArg) { + this.enableAudio = setterArg; + return this; + } + + public @NonNull PlatformMediaSettings build() { + PlatformMediaSettings pigeonReturn = new PlatformMediaSettings(); + pigeonReturn.setResolutionPreset(resolutionPreset); + pigeonReturn.setFps(fps); + pigeonReturn.setVideoBitrate(videoBitrate); + pigeonReturn.setAudioBitrate(audioBitrate); + pigeonReturn.setEnableAudio(enableAudio); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(5); + toListResult.add(resolutionPreset); + toListResult.add(fps); + toListResult.add(videoBitrate); + toListResult.add(audioBitrate); + toListResult.add(enableAudio); + return toListResult; + } + + static @NonNull PlatformMediaSettings fromList(@NonNull ArrayList pigeonVar_list) { + PlatformMediaSettings pigeonResult = new PlatformMediaSettings(); + Object resolutionPreset = pigeonVar_list.get(0); + pigeonResult.setResolutionPreset((PlatformResolutionPreset) resolutionPreset); + Object fps = pigeonVar_list.get(1); + pigeonResult.setFps((Long) fps); + Object videoBitrate = pigeonVar_list.get(2); + pigeonResult.setVideoBitrate((Long) videoBitrate); + Object audioBitrate = pigeonVar_list.get(3); + pigeonResult.setAudioBitrate((Long) audioBitrate); + Object enableAudio = pigeonVar_list.get(4); + pigeonResult.setEnableAudio((Boolean) enableAudio); + return pigeonResult; + } + } + + private static class PigeonCodec extends StandardMessageCodec { + public static final PigeonCodec INSTANCE = new PigeonCodec(); + + private PigeonCodec() {} + + @Override + protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { + switch (type) { + case (byte) 129: + { + Object value = readValue(buffer); + return value == null + ? null + : PlatformCameraLensDirection.values()[((Long) value).intValue()]; + } + case (byte) 130: + { + Object value = readValue(buffer); + return value == null + ? null + : PlatformDeviceOrientation.values()[((Long) value).intValue()]; + } + case (byte) 131: + { + Object value = readValue(buffer); + return value == null ? null : PlatformExposureMode.values()[((Long) value).intValue()]; + } + case (byte) 132: + { + Object value = readValue(buffer); + return value == null ? null : PlatformFocusMode.values()[((Long) value).intValue()]; + } + case (byte) 133: + { + Object value = readValue(buffer); + return value == null + ? null + : PlatformResolutionPreset.values()[((Long) value).intValue()]; + } + case (byte) 134: + { + Object value = readValue(buffer); + return value == null + ? null + : PlatformImageFormatGroup.values()[((Long) value).intValue()]; + } + case (byte) 135: + { + Object value = readValue(buffer); + return value == null ? null : PlatformFlashMode.values()[((Long) value).intValue()]; + } + case (byte) 136: + return PlatformCameraDescription.fromList((ArrayList) readValue(buffer)); + case (byte) 137: + return PlatformCameraState.fromList((ArrayList) readValue(buffer)); + case (byte) 138: + return PlatformSize.fromList((ArrayList) readValue(buffer)); + case (byte) 139: + return PlatformPoint.fromList((ArrayList) readValue(buffer)); + case (byte) 140: + return PlatformMediaSettings.fromList((ArrayList) readValue(buffer)); + default: + return super.readValueOfType(type, buffer); + } + } + + @Override + protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { + if (value instanceof PlatformCameraLensDirection) { + stream.write(129); + writeValue(stream, value == null ? null : ((PlatformCameraLensDirection) value).index); + } else if (value instanceof PlatformDeviceOrientation) { + stream.write(130); + writeValue(stream, value == null ? null : ((PlatformDeviceOrientation) value).index); + } else if (value instanceof PlatformExposureMode) { + stream.write(131); + writeValue(stream, value == null ? null : ((PlatformExposureMode) value).index); + } else if (value instanceof PlatformFocusMode) { + stream.write(132); + writeValue(stream, value == null ? null : ((PlatformFocusMode) value).index); + } else if (value instanceof PlatformResolutionPreset) { + stream.write(133); + writeValue(stream, value == null ? null : ((PlatformResolutionPreset) value).index); + } else if (value instanceof PlatformImageFormatGroup) { + stream.write(134); + writeValue(stream, value == null ? null : ((PlatformImageFormatGroup) value).index); + } else if (value instanceof PlatformFlashMode) { + stream.write(135); + writeValue(stream, value == null ? null : ((PlatformFlashMode) value).index); + } else if (value instanceof PlatformCameraDescription) { + stream.write(136); + writeValue(stream, ((PlatformCameraDescription) value).toList()); + } else if (value instanceof PlatformCameraState) { + stream.write(137); + writeValue(stream, ((PlatformCameraState) value).toList()); + } else if (value instanceof PlatformSize) { + stream.write(138); + writeValue(stream, ((PlatformSize) value).toList()); + } else if (value instanceof PlatformPoint) { + stream.write(139); + writeValue(stream, ((PlatformPoint) value).toList()); + } else if (value instanceof PlatformMediaSettings) { + stream.write(140); + writeValue(stream, ((PlatformMediaSettings) value).toList()); + } else { + super.writeValue(stream, value); + } + } + } + + /** Asynchronous error handling return type for non-nullable API method returns. */ + public interface Result { + /** Success case callback method for handling returns. */ + void success(@NonNull T result); + + /** Failure case callback method for handling errors. */ + void error(@NonNull Throwable error); + } + /** Asynchronous error handling return type for nullable API method returns. */ + public interface NullableResult { + /** Success case callback method for handling returns. */ + void success(@Nullable T result); + + /** Failure case callback method for handling errors. */ + void error(@NonNull Throwable error); + } + /** Asynchronous error handling return type for void API method returns. */ + public interface VoidResult { + /** Success case callback method for handling returns. */ + void success(); + + /** Failure case callback method for handling errors. */ + void error(@NonNull Throwable error); + } + /** + * Handles calls from Dart to the native side. + * + *

Generated interface from Pigeon that represents a handler of messages from Flutter. + */ + public interface CameraApi { + /** Returns the list of available cameras. */ + @NonNull + List getAvailableCameras(); + /** Creates a new camera with the given name and settings and returns its ID. */ + void create( + @NonNull String cameraName, + @NonNull PlatformMediaSettings mediaSettings, + @NonNull Result result); + /** Initializes the camera with the given ID for the given image format. */ + void initialize(@NonNull PlatformImageFormatGroup imageFormat); + /** Disposes of the camera with the given ID. */ + void dispose(); + /** Locks the camera with the given ID to the given orientation. */ + void lockCaptureOrientation(@NonNull PlatformDeviceOrientation orientation); + /** Unlocks the orientation for the camera with the given ID. */ + void unlockCaptureOrientation(); + /** Takes a picture on the camera with the given ID and returns a path to the resulting file. */ + void takePicture(@NonNull Result result); + /** Starts recording a video on the camera with the given ID. */ + void startVideoRecording(@NonNull Boolean enableStream); + /** + * Ends video recording on the camera with the given ID and returns the path to the resulting + * file. + */ + @NonNull + String stopVideoRecording(); + /** Pauses video recording on the camera with the given ID. */ + void pauseVideoRecording(); + /** Resumes previously paused video recording on the camera with the given ID. */ + void resumeVideoRecording(); + /** Begins streaming frames from the camera. */ + void startImageStream(); + /** Stops streaming frames from the camera. */ + void stopImageStream(); + /** Sets the flash mode of the camera with the given ID. */ + void setFlashMode(@NonNull PlatformFlashMode flashMode, @NonNull VoidResult result); + /** Sets the exposure mode of the camera with the given ID. */ + void setExposureMode(@NonNull PlatformExposureMode exposureMode, @NonNull VoidResult result); + /** + * Sets the exposure point of the camera with the given ID. + * + *

A null value resets to the default exposure point. + */ + void setExposurePoint(@Nullable PlatformPoint point, @NonNull VoidResult result); + /** Returns the minimum exposure offset of the camera with the given ID. */ + @NonNull + Double getMinExposureOffset(); + /** Returns the maximum exposure offset of the camera with the given ID. */ + @NonNull + Double getMaxExposureOffset(); + /** Returns the exposure step size of the camera with the given ID. */ + @NonNull + Double getExposureOffsetStepSize(); + /** + * Sets the exposure offset of the camera with the given ID and returns the actual exposure + * offset. + */ + void setExposureOffset(@NonNull Double offset, @NonNull Result result); + /** Sets the focus mode of the camera with the given ID. */ + void setFocusMode(@NonNull PlatformFocusMode focusMode); + /** + * Sets the focus point of the camera with the given ID. + * + *

A null value resets to the default focus point. + */ + void setFocusPoint(@Nullable PlatformPoint point, @NonNull VoidResult result); + /** Returns the maximum zoom level of the camera with the given ID. */ + @NonNull + Double getMaxZoomLevel(); + /** Returns the minimum zoom level of the camera with the given ID. */ + @NonNull + Double getMinZoomLevel(); + /** Sets the zoom level of the camera with the given ID. */ + void setZoomLevel(@NonNull Double zoom, @NonNull VoidResult result); + /** Pauses streaming of preview frames. */ + void pausePreview(); + /** Resumes previously paused streaming of preview frames. */ + void resumePreview(); + /** + * Changes the camera while recording video. + * + *

This should be called only while video recording is active. + */ + void setDescriptionWhileRecording(@NonNull String description); + + /** The codec used by CameraApi. */ + static @NonNull MessageCodec getCodec() { + return PigeonCodec.INSTANCE; + } + /** Sets up an instance of `CameraApi` to handle messages through the `binaryMessenger`. */ + static void setUp(@NonNull BinaryMessenger binaryMessenger, @Nullable CameraApi api) { + setUp(binaryMessenger, "", api); + } + + static void setUp( + @NonNull BinaryMessenger binaryMessenger, + @NonNull String messageChannelSuffix, + @Nullable CameraApi api) { + messageChannelSuffix = messageChannelSuffix.isEmpty() ? "" : "." + messageChannelSuffix; + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.getAvailableCameras" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + try { + List output = api.getAvailableCameras(); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.create" + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + String cameraNameArg = (String) args.get(0); + PlatformMediaSettings mediaSettingsArg = (PlatformMediaSettings) args.get(1); + Result resultCallback = + new Result() { + public void success(Long result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.create(cameraNameArg, mediaSettingsArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.initialize" + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + PlatformImageFormatGroup imageFormatArg = (PlatformImageFormatGroup) args.get(0); + try { + api.initialize(imageFormatArg); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.dispose" + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + try { + api.dispose(); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.lockCaptureOrientation" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + PlatformDeviceOrientation orientationArg = (PlatformDeviceOrientation) args.get(0); + try { + api.lockCaptureOrientation(orientationArg); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.unlockCaptureOrientation" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + try { + api.unlockCaptureOrientation(); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.takePicture" + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + Result resultCallback = + new Result() { + public void success(String result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.takePicture(resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.startVideoRecording" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Boolean enableStreamArg = (Boolean) args.get(0); + try { + api.startVideoRecording(enableStreamArg); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.stopVideoRecording" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + try { + String output = api.stopVideoRecording(); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.pauseVideoRecording" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + try { + api.pauseVideoRecording(); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.resumeVideoRecording" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + try { + api.resumeVideoRecording(); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.startImageStream" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + try { + api.startImageStream(); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.stopImageStream" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + try { + api.stopImageStream(); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.setFlashMode" + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + PlatformFlashMode flashModeArg = (PlatformFlashMode) args.get(0); + VoidResult resultCallback = + new VoidResult() { + public void success() { + wrapped.add(0, null); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.setFlashMode(flashModeArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.setExposureMode" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + PlatformExposureMode exposureModeArg = (PlatformExposureMode) args.get(0); + VoidResult resultCallback = + new VoidResult() { + public void success() { + wrapped.add(0, null); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.setExposureMode(exposureModeArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.setExposurePoint" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + PlatformPoint pointArg = (PlatformPoint) args.get(0); + VoidResult resultCallback = + new VoidResult() { + public void success() { + wrapped.add(0, null); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.setExposurePoint(pointArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.getMinExposureOffset" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + try { + Double output = api.getMinExposureOffset(); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.getMaxExposureOffset" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + try { + Double output = api.getMaxExposureOffset(); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.getExposureOffsetStepSize" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + try { + Double output = api.getExposureOffsetStepSize(); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.setExposureOffset" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Double offsetArg = (Double) args.get(0); + Result resultCallback = + new Result() { + public void success(Double result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.setExposureOffset(offsetArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.setFocusMode" + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + PlatformFocusMode focusModeArg = (PlatformFocusMode) args.get(0); + try { + api.setFocusMode(focusModeArg); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.setFocusPoint" + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + PlatformPoint pointArg = (PlatformPoint) args.get(0); + VoidResult resultCallback = + new VoidResult() { + public void success() { + wrapped.add(0, null); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.setFocusPoint(pointArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.getMaxZoomLevel" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + try { + Double output = api.getMaxZoomLevel(); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.getMinZoomLevel" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + try { + Double output = api.getMinZoomLevel(); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.setZoomLevel" + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Double zoomArg = (Double) args.get(0); + VoidResult resultCallback = + new VoidResult() { + public void success() { + wrapped.add(0, null); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.setZoomLevel(zoomArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.pausePreview" + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + try { + api.pausePreview(); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.resumePreview" + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + try { + api.resumePreview(); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.setDescriptionWhileRecording" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + String descriptionArg = (String) args.get(0); + try { + api.setDescriptionWhileRecording(descriptionArg); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + } + } + /** + * Handles calls from native side to Dart that are not camera-specific. + * + *

Generated class from Pigeon that represents Flutter messages that can be called from Java. + */ + public static class CameraGlobalEventApi { + private final @NonNull BinaryMessenger binaryMessenger; + private final String messageChannelSuffix; + + public CameraGlobalEventApi(@NonNull BinaryMessenger argBinaryMessenger) { + this(argBinaryMessenger, ""); + } + + public CameraGlobalEventApi( + @NonNull BinaryMessenger argBinaryMessenger, @NonNull String messageChannelSuffix) { + this.binaryMessenger = argBinaryMessenger; + this.messageChannelSuffix = messageChannelSuffix.isEmpty() ? "" : "." + messageChannelSuffix; + } + + /** Public interface for sending reply. The codec used by CameraGlobalEventApi. */ + static @NonNull MessageCodec getCodec() { + return PigeonCodec.INSTANCE; + } + /** Called when the device's physical orientation changes. */ + public void deviceOrientationChanged( + @NonNull PlatformDeviceOrientation orientationArg, @NonNull VoidResult result) { + final String channelName = + "dev.flutter.pigeon.camera_android.CameraGlobalEventApi.deviceOrientationChanged" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(orientationArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else { + result.success(); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + } + /** + * Handles device-specific calls from native side to Dart. + * + *

Generated class from Pigeon that represents Flutter messages that can be called from Java. + */ + public static class CameraEventApi { + private final @NonNull BinaryMessenger binaryMessenger; + private final String messageChannelSuffix; + + public CameraEventApi(@NonNull BinaryMessenger argBinaryMessenger) { + this(argBinaryMessenger, ""); + } + + public CameraEventApi( + @NonNull BinaryMessenger argBinaryMessenger, @NonNull String messageChannelSuffix) { + this.binaryMessenger = argBinaryMessenger; + this.messageChannelSuffix = messageChannelSuffix.isEmpty() ? "" : "." + messageChannelSuffix; + } + + /** Public interface for sending reply. The codec used by CameraEventApi. */ + static @NonNull MessageCodec getCodec() { + return PigeonCodec.INSTANCE; + } + /** Called when the camera is initialized. */ + public void initialized( + @NonNull PlatformCameraState initialStateArg, @NonNull VoidResult result) { + final String channelName = + "dev.flutter.pigeon.camera_android.CameraEventApi.initialized" + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(initialStateArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else { + result.success(); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Called when an error occurs in the camera. */ + public void error(@NonNull String messageArg, @NonNull VoidResult result) { + final String channelName = + "dev.flutter.pigeon.camera_android.CameraEventApi.error" + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(messageArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else { + result.success(); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Called when the camera closes. */ + public void closed(@NonNull VoidResult result) { + final String channelName = + "dev.flutter.pigeon.camera_android.CameraEventApi.closed" + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + null, + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else { + result.success(); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + } +} diff --git a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java deleted file mode 100644 index eae8c650fe60..000000000000 --- a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java +++ /dev/null @@ -1,433 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package io.flutter.plugins.camera; - -import android.app.Activity; -import android.hardware.camera2.CameraAccessException; -import android.os.Handler; -import android.os.Looper; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; -import io.flutter.embedding.engine.systemchannels.PlatformChannel; -import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.EventChannel; -import io.flutter.plugin.common.MethodCall; -import io.flutter.plugin.common.MethodChannel; -import io.flutter.plugin.common.MethodChannel.Result; -import io.flutter.plugins.camera.CameraPermissions.PermissionsRegistry; -import io.flutter.plugins.camera.features.CameraFeatureFactoryImpl; -import io.flutter.plugins.camera.features.Point; -import io.flutter.plugins.camera.features.autofocus.FocusMode; -import io.flutter.plugins.camera.features.exposurelock.ExposureMode; -import io.flutter.plugins.camera.features.flash.FlashMode; -import io.flutter.plugins.camera.features.resolution.ResolutionPreset; -import io.flutter.view.TextureRegistry; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -final class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler { - private final Activity activity; - private final BinaryMessenger messenger; - private final CameraPermissions cameraPermissions; - private final PermissionsRegistry permissionsRegistry; - private final TextureRegistry textureRegistry; - private final MethodChannel methodChannel; - private final EventChannel imageStreamChannel; - @VisibleForTesting @Nullable Camera camera; - - MethodCallHandlerImpl( - Activity activity, - BinaryMessenger messenger, - CameraPermissions cameraPermissions, - PermissionsRegistry permissionsAdder, - TextureRegistry textureRegistry) { - this.activity = activity; - this.messenger = messenger; - this.cameraPermissions = cameraPermissions; - this.permissionsRegistry = permissionsAdder; - this.textureRegistry = textureRegistry; - - methodChannel = new MethodChannel(messenger, "plugins.flutter.io/camera_android"); - imageStreamChannel = - new EventChannel(messenger, "plugins.flutter.io/camera_android/imageStream"); - methodChannel.setMethodCallHandler(this); - } - - @Override - public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) { - switch (call.method) { - case "availableCameras": - try { - result.success(CameraUtils.getAvailableCameras(activity)); - } catch (Exception e) { - handleException(e, result); - } - break; - case "create": - { - if (camera != null) { - camera.close(); - } - - cameraPermissions.requestPermissions( - activity, - permissionsRegistry, - call.argument("enableAudio"), - (String errCode, String errDesc) -> { - if (errCode == null) { - try { - instantiateCamera(call, result); - } catch (Exception e) { - handleException(e, result); - } - } else { - result.error(errCode, errDesc, null); - } - }); - break; - } - case "initialize": - { - if (camera != null) { - try { - camera.open(call.argument("imageFormatGroup")); - result.success(null); - } catch (Exception e) { - handleException(e, result); - } - } else { - result.error( - "cameraNotFound", - "Camera not found. Please call the 'create' method before calling 'initialize'.", - null); - } - break; - } - case "takePicture": - { - camera.takePicture(result); - break; - } - case "prepareForVideoRecording": - { - // This optimization is not required for Android. - result.success(null); - break; - } - case "startVideoRecording": - { - camera.startVideoRecording( - result, - Objects.equals(call.argument("enableStream"), true) ? imageStreamChannel : null); - break; - } - case "stopVideoRecording": - { - camera.stopVideoRecording(result); - break; - } - case "pauseVideoRecording": - { - camera.pauseVideoRecording(result); - break; - } - case "resumeVideoRecording": - { - camera.resumeVideoRecording(result); - break; - } - case "setFlashMode": - { - String modeStr = call.argument("mode"); - FlashMode mode = FlashMode.getValueForString(modeStr); - if (mode == null) { - result.error("setFlashModeFailed", "Unknown flash mode " + modeStr, null); - return; - } - try { - camera.setFlashMode(result, mode); - } catch (Exception e) { - handleException(e, result); - } - break; - } - case "setExposureMode": - { - String modeStr = call.argument("mode"); - ExposureMode mode = ExposureMode.getValueForString(modeStr); - if (mode == null) { - result.error("setExposureModeFailed", "Unknown exposure mode " + modeStr, null); - return; - } - try { - camera.setExposureMode(result, mode); - } catch (Exception e) { - handleException(e, result); - } - break; - } - case "setExposurePoint": - { - Boolean reset = call.argument("reset"); - Double x = null; - Double y = null; - if (reset == null || !reset) { - x = call.argument("x"); - y = call.argument("y"); - } - try { - camera.setExposurePoint(result, new Point(x, y)); - } catch (Exception e) { - handleException(e, result); - } - break; - } - case "getMinExposureOffset": - { - try { - result.success(camera.getMinExposureOffset()); - } catch (Exception e) { - handleException(e, result); - } - break; - } - case "getMaxExposureOffset": - { - try { - result.success(camera.getMaxExposureOffset()); - } catch (Exception e) { - handleException(e, result); - } - break; - } - case "getExposureOffsetStepSize": - { - try { - result.success(camera.getExposureOffsetStepSize()); - } catch (Exception e) { - handleException(e, result); - } - break; - } - case "setExposureOffset": - { - try { - camera.setExposureOffset(result, call.argument("offset")); - } catch (Exception e) { - handleException(e, result); - } - break; - } - case "setFocusMode": - { - String modeStr = call.argument("mode"); - FocusMode mode = FocusMode.getValueForString(modeStr); - if (mode == null) { - result.error("setFocusModeFailed", "Unknown focus mode " + modeStr, null); - return; - } - try { - camera.setFocusMode(result, mode); - } catch (Exception e) { - handleException(e, result); - } - break; - } - case "setFocusPoint": - { - Boolean reset = call.argument("reset"); - Double x = null; - Double y = null; - if (reset == null || !reset) { - x = call.argument("x"); - y = call.argument("y"); - } - try { - camera.setFocusPoint(result, new Point(x, y)); - } catch (Exception e) { - handleException(e, result); - } - break; - } - case "startImageStream": - { - try { - camera.startPreviewWithImageStream(imageStreamChannel); - result.success(null); - } catch (Exception e) { - handleException(e, result); - } - break; - } - case "stopImageStream": - { - try { - camera.startPreview(); - result.success(null); - } catch (Exception e) { - handleException(e, result); - } - break; - } - case "getMaxZoomLevel": - { - assert camera != null; - - try { - float maxZoomLevel = camera.getMaxZoomLevel(); - result.success(maxZoomLevel); - } catch (Exception e) { - handleException(e, result); - } - break; - } - case "getMinZoomLevel": - { - assert camera != null; - - try { - float minZoomLevel = camera.getMinZoomLevel(); - result.success(minZoomLevel); - } catch (Exception e) { - handleException(e, result); - } - break; - } - case "setZoomLevel": - { - assert camera != null; - - Double zoom = call.argument("zoom"); - - if (zoom == null) { - result.error( - "ZOOM_ERROR", "setZoomLevel is called without specifying a zoom level.", null); - return; - } - - try { - camera.setZoomLevel(result, zoom.floatValue()); - } catch (Exception e) { - handleException(e, result); - } - break; - } - case "lockCaptureOrientation": - { - PlatformChannel.DeviceOrientation orientation = - CameraUtils.deserializeDeviceOrientation(call.argument("orientation")); - - try { - camera.lockCaptureOrientation(orientation); - result.success(null); - } catch (Exception e) { - handleException(e, result); - } - break; - } - case "unlockCaptureOrientation": - { - try { - camera.unlockCaptureOrientation(); - result.success(null); - } catch (Exception e) { - handleException(e, result); - } - break; - } - case "pausePreview": - { - try { - camera.pausePreview(); - result.success(null); - } catch (Exception e) { - handleException(e, result); - } - break; - } - case "resumePreview": - { - camera.resumePreview(); - result.success(null); - break; - } - case "setDescriptionWhileRecording": - { - try { - String cameraName = call.argument("cameraName"); - CameraProperties cameraProperties = - new CameraPropertiesImpl(cameraName, CameraUtils.getCameraManager(activity)); - camera.setDescriptionWhileRecording(result, cameraProperties); - } catch (Exception e) { - handleException(e, result); - } - break; - } - case "dispose": - { - if (camera != null) { - camera.dispose(); - } - result.success(null); - break; - } - default: - result.notImplemented(); - break; - } - } - - void stopListening() { - methodChannel.setMethodCallHandler(null); - } - - private void instantiateCamera(MethodCall call, Result result) throws CameraAccessException { - String cameraName = call.argument("cameraName"); - String preset = call.argument("resolutionPreset"); - boolean enableAudio = call.argument("enableAudio"); - Integer fps = call.argument("fps"); - Integer videoBitrate = call.argument("videoBitrate"); - Integer audioBitrate = call.argument("audioBitrate"); - - TextureRegistry.SurfaceTextureEntry flutterSurfaceTexture = - textureRegistry.createSurfaceTexture(); - DartMessenger dartMessenger = - new DartMessenger( - messenger, flutterSurfaceTexture.id(), new Handler(Looper.getMainLooper())); - CameraProperties cameraProperties = - new CameraPropertiesImpl(cameraName, CameraUtils.getCameraManager(activity)); - ResolutionPreset resolutionPreset = ResolutionPreset.valueOf(preset); - - camera = - new Camera( - activity, - flutterSurfaceTexture, - new CameraFeatureFactoryImpl(), - dartMessenger, - cameraProperties, - new Camera.VideoCaptureSettings( - resolutionPreset, enableAudio, fps, videoBitrate, audioBitrate)); - - Map reply = new HashMap<>(); - reply.put("cameraId", flutterSurfaceTexture.id()); - result.success(reply); - } - - // We move catching CameraAccessException out of onMethodCall because it causes a crash - // on plugin registration for sdks incompatible with Camera2 (< 21). We want this plugin to - // to be able to compile with <21 sdks for apps that want the camera and support earlier version. - @SuppressWarnings("ConstantConditions") - private void handleException(Exception exception, Result result) { - if (exception instanceof CameraAccessException) { - result.error("CameraAccess", exception.getMessage(), null); - return; - } - - // CameraAccessException can not be cast to a RuntimeException. - throw (RuntimeException) exception; - } -} diff --git a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/NoOpVoidResult.java b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/NoOpVoidResult.java new file mode 100644 index 000000000000..2ce29e95851d --- /dev/null +++ b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/NoOpVoidResult.java @@ -0,0 +1,20 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.camera; + +import androidx.annotation.NonNull; + +/** + * A convenience class for results of a Pigeon Flutter API method call that perform no action. + * + *

Longer term, any call using this is likely a good candidate to migrate to event channels. + */ +public class NoOpVoidResult implements Messages.VoidResult { + @Override + public void success() {} + + @Override + public void error(@NonNull Throwable error) {} +} diff --git a/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/MethodCallHandlerImplTest.java b/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/CameraApiImplTest.java similarity index 69% rename from packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/MethodCallHandlerImplTest.java rename to packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/CameraApiImplTest.java index e4ab82d9eda5..88430530142d 100644 --- a/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/MethodCallHandlerImplTest.java +++ b/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/CameraApiImplTest.java @@ -5,6 +5,7 @@ package io.flutter.plugins.camera; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; @@ -14,35 +15,33 @@ import android.hardware.camera2.CameraAccessException; import androidx.lifecycle.LifecycleObserver; import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.MethodCall; -import io.flutter.plugin.common.MethodChannel; import io.flutter.view.TextureRegistry; import org.junit.Before; import org.junit.Test; -public class MethodCallHandlerImplTest { +public class CameraApiImplTest { - MethodCallHandlerImpl handler; - MethodChannel.Result mockResult; + CameraApiImpl handler; + Messages.VoidResult mockResult; Camera mockCamera; @Before public void setUp() { handler = - new MethodCallHandlerImpl( + new CameraApiImpl( mock(Activity.class), mock(BinaryMessenger.class), mock(CameraPermissions.class), mock(CameraPermissions.PermissionsRegistry.class), mock(TextureRegistry.class)); - mockResult = mock(MethodChannel.Result.class); + mockResult = mock(Messages.VoidResult.class); mockCamera = mock(Camera.class); handler.camera = mockCamera; } @Test public void shouldNotImplementLifecycleObserverInterface() { - Class methodCallHandlerClass = MethodCallHandlerImpl.class; + Class methodCallHandlerClass = CameraApiImpl.class; assertFalse(LifecycleObserver.class.isAssignableFrom(methodCallHandlerClass)); } @@ -50,10 +49,9 @@ public void shouldNotImplementLifecycleObserverInterface() { @Test public void onMethodCall_pausePreview_shouldPausePreviewAndSendSuccessResult() throws CameraAccessException { - handler.onMethodCall(new MethodCall("pausePreview", null), mockResult); + handler.pausePreview(); verify(mockCamera, times(1)).pausePreview(); - verify(mockResult, times(1)).success(null); } @Test @@ -61,16 +59,13 @@ public void onMethodCall_pausePreview_shouldSendErrorResultOnCameraAccessExcepti throws CameraAccessException { doThrow(new CameraAccessException(0)).when(mockCamera).pausePreview(); - handler.onMethodCall(new MethodCall("pausePreview", null), mockResult); - - verify(mockResult, times(1)).error("CameraAccess", null, null); + assertThrows(Messages.FlutterError.class, () -> handler.pausePreview()); } @Test public void onMethodCall_resumePreview_shouldResumePreviewAndSendSuccessResult() { - handler.onMethodCall(new MethodCall("resumePreview", null), mockResult); + handler.resumePreview(); verify(mockCamera, times(1)).resumePreview(); - verify(mockResult, times(1)).success(null); } } diff --git a/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/CameraTest.java b/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/CameraTest.java index d2d90b7beca6..56a3a4562adc 100644 --- a/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/CameraTest.java +++ b/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/CameraTest.java @@ -7,6 +7,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.*; @@ -30,7 +31,6 @@ import androidx.lifecycle.LifecycleObserver; import io.flutter.embedding.engine.systemchannels.PlatformChannel; import io.flutter.plugin.common.EventChannel; -import io.flutter.plugin.common.MethodChannel; import io.flutter.plugins.camera.features.CameraFeatureFactory; import io.flutter.plugins.camera.features.CameraFeatures; import io.flutter.plugins.camera.features.Point; @@ -59,13 +59,39 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.mockito.ArgumentMatcher; import org.mockito.MockedConstruction; import org.mockito.MockedStatic; import org.mockito.Mockito; +/** + * As Pigeon-generated class, including FlutterError, do not implement equality, this helper class + * simplifies matching arguments passed to Result/VoidResult.error in unit tests. + */ +class FlutterErrorMatcher implements ArgumentMatcher { + + FlutterErrorMatcher(String code, String message, Object details) { + this.code = code; + this.message = message; + this.details = details; + } + + final String code; + final String message; + final Object details; + + @Override + public boolean matches(Messages.FlutterError argument) { + return Objects.equals(code, argument.code) + && Objects.equals(message, argument.getMessage()) + && Objects.equals(details, argument.details); + } +} + class FakeCameraDeviceWrapper implements CameraDeviceWrapper { final List captureRequests; @Nullable final CameraCaptureSession session; @@ -324,21 +350,21 @@ public void getMinZoomLevel() { public void setExposureMode_shouldUpdateExposureLockFeature() { ExposureLockFeature mockExposureLockFeature = mockCameraFeatureFactory.createExposureLockFeature(mockCameraProperties); - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); + Messages.VoidResult mockResult = mock(Messages.VoidResult.class); ExposureMode exposureMode = ExposureMode.locked; camera.setExposureMode(mockResult, exposureMode); verify(mockExposureLockFeature, times(1)).setValue(exposureMode); - verify(mockResult, never()).error(any(), any(), any()); - verify(mockResult, times(1)).success(null); + verify(mockResult, never()).error(any()); + verify(mockResult, times(1)).success(); } @Test public void setExposureMode_shouldUpdateBuilder() { ExposureLockFeature mockExposureLockFeature = mockCameraFeatureFactory.createExposureLockFeature(mockCameraProperties); - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); + Messages.VoidResult mockResult = mock(Messages.VoidResult.class); ExposureMode exposureMode = ExposureMode.locked; camera.setExposureMode(mockResult, exposureMode); @@ -349,16 +375,19 @@ public void setExposureMode_shouldUpdateBuilder() { @Test public void setExposureMode_shouldCallErrorOnResultOnCameraAccessException() throws CameraAccessException { - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); + Messages.VoidResult mockResult = mock(Messages.VoidResult.class); ExposureMode exposureMode = ExposureMode.locked; when(mockCaptureSession.setRepeatingRequest(any(), any(), any())) .thenThrow(new CameraAccessException(0, "")); camera.setExposureMode(mockResult, exposureMode); - verify(mockResult, never()).success(any()); + verify(mockResult, never()).success(); verify(mockResult, times(1)) - .error("setExposureModeFailed", "Could not set exposure mode.", null); + .error( + argThat( + new FlutterErrorMatcher( + "setExposureModeFailed", "Could not set exposure mode.", null))); } @Test @@ -367,14 +396,14 @@ public void setExposurePoint_shouldUpdateExposurePointFeature() { ExposurePointFeature mockExposurePointFeature = mockCameraFeatureFactory.createExposurePointFeature( mockCameraProperties, mockSensorOrientationFeature); - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); + Messages.VoidResult mockResult = mock(Messages.VoidResult.class); Point point = new Point(42d, 42d); camera.setExposurePoint(mockResult, point); verify(mockExposurePointFeature, times(1)).setValue(point); - verify(mockResult, never()).error(any(), any(), any()); - verify(mockResult, times(1)).success(null); + verify(mockResult, never()).error(any()); + verify(mockResult, times(1)).success(); } @Test @@ -383,7 +412,7 @@ public void setExposurePoint_shouldUpdateBuilder() { ExposurePointFeature mockExposurePointFeature = mockCameraFeatureFactory.createExposurePointFeature( mockCameraProperties, mockSensorOrientationFeature); - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); + Messages.VoidResult mockResult = mock(Messages.VoidResult.class); Point point = new Point(42d, 42d); camera.setExposurePoint(mockResult, point); @@ -394,37 +423,40 @@ public void setExposurePoint_shouldUpdateBuilder() { @Test public void setExposurePoint_shouldCallErrorOnResultOnCameraAccessException() throws CameraAccessException { - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); + Messages.VoidResult mockResult = mock(Messages.VoidResult.class); Point point = new Point(42d, 42d); when(mockCaptureSession.setRepeatingRequest(any(), any(), any())) .thenThrow(new CameraAccessException(0, "")); camera.setExposurePoint(mockResult, point); - verify(mockResult, never()).success(any()); + verify(mockResult, never()).success(); verify(mockResult, times(1)) - .error("setExposurePointFailed", "Could not set exposure point.", null); + .error( + argThat( + new FlutterErrorMatcher( + "setExposurePointFailed", "Could not set exposure point.", null))); } @Test public void setFlashMode_shouldUpdateFlashFeature() { FlashFeature mockFlashFeature = mockCameraFeatureFactory.createFlashFeature(mockCameraProperties); - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); + Messages.VoidResult mockResult = mock(Messages.VoidResult.class); FlashMode flashMode = FlashMode.always; camera.setFlashMode(mockResult, flashMode); verify(mockFlashFeature, times(1)).setValue(flashMode); - verify(mockResult, never()).error(any(), any(), any()); - verify(mockResult, times(1)).success(null); + verify(mockResult, never()).error(any()); + verify(mockResult, times(1)).success(); } @Test public void setFlashMode_shouldUpdateBuilder() { FlashFeature mockFlashFeature = mockCameraFeatureFactory.createFlashFeature(mockCameraProperties); - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); + Messages.VoidResult mockResult = mock(Messages.VoidResult.class); FlashMode flashMode = FlashMode.always; camera.setFlashMode(mockResult, flashMode); @@ -435,15 +467,18 @@ public void setFlashMode_shouldUpdateBuilder() { @Test public void setFlashMode_shouldCallErrorOnResultOnCameraAccessException() throws CameraAccessException { - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); + Messages.VoidResult mockResult = mock(Messages.VoidResult.class); FlashMode flashMode = FlashMode.always; when(mockCaptureSession.setRepeatingRequest(any(), any(), any())) .thenThrow(new CameraAccessException(0, "")); camera.setFlashMode(mockResult, flashMode); - verify(mockResult, never()).success(any()); - verify(mockResult, times(1)).error("setFlashModeFailed", "Could not set flash mode.", null); + verify(mockResult, never()).success(); + verify(mockResult, times(1)) + .error( + argThat( + new FlutterErrorMatcher("setFlashModeFailed", "Could not set flash mode.", null))); } @Test @@ -454,15 +489,15 @@ public void setFocusPoint_shouldUpdateFocusPointFeature() { mockCameraProperties, mockSensorOrientationFeature); AutoFocusFeature mockAutoFocusFeature = mockCameraFeatureFactory.createAutoFocusFeature(mockCameraProperties, false); - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); + Messages.VoidResult mockResult = mock(Messages.VoidResult.class); Point point = new Point(42d, 42d); when(mockAutoFocusFeature.getValue()).thenReturn(FocusMode.auto); camera.setFocusPoint(mockResult, point); verify(mockFocusPointFeature, times(1)).setValue(point); - verify(mockResult, never()).error(any(), any(), any()); - verify(mockResult, times(1)).success(null); + verify(mockResult, never()).error(any()); + verify(mockResult, times(1)).success(); } @Test @@ -473,7 +508,7 @@ public void setFocusPoint_shouldUpdateBuilder() { mockCameraProperties, mockSensorOrientationFeature); AutoFocusFeature mockAutoFocusFeature = mockCameraFeatureFactory.createAutoFocusFeature(mockCameraProperties, false); - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); + Messages.VoidResult mockResult = mock(Messages.VoidResult.class); Point point = new Point(42d, 42d); when(mockAutoFocusFeature.getValue()).thenReturn(FocusMode.auto); @@ -487,7 +522,7 @@ public void setFocusPoint_shouldCallErrorOnResultOnCameraAccessException() throws CameraAccessException { AutoFocusFeature mockAutoFocusFeature = mockCameraFeatureFactory.createAutoFocusFeature(mockCameraProperties, false); - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); + Messages.VoidResult mockResult = mock(Messages.VoidResult.class); Point point = new Point(42d, 42d); when(mockAutoFocusFeature.getValue()).thenReturn(FocusMode.auto); when(mockCaptureSession.setRepeatingRequest(any(), any(), any())) @@ -495,15 +530,19 @@ public void setFocusPoint_shouldCallErrorOnResultOnCameraAccessException() camera.setFocusPoint(mockResult, point); - verify(mockResult, never()).success(any()); - verify(mockResult, times(1)).error("setFocusPointFailed", "Could not set focus point.", null); + verify(mockResult, never()).success(); + verify(mockResult, times(1)) + .error( + argThat( + new FlutterErrorMatcher( + "setFocusPointFailed", "Could not set focus point.", null))); } @Test public void setZoomLevel_shouldUpdateZoomLevelFeature() throws CameraAccessException { ZoomLevelFeature mockZoomLevelFeature = mockCameraFeatureFactory.createZoomLevelFeature(mockCameraProperties); - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); + Messages.VoidResult mockResult = mock(Messages.VoidResult.class); float zoomLevel = 1.0f; when(mockZoomLevelFeature.getValue()).thenReturn(zoomLevel); @@ -513,15 +552,15 @@ public void setZoomLevel_shouldUpdateZoomLevelFeature() throws CameraAccessExcep camera.setZoomLevel(mockResult, zoomLevel); verify(mockZoomLevelFeature, times(1)).setValue(zoomLevel); - verify(mockResult, never()).error(any(), any(), any()); - verify(mockResult, times(1)).success(null); + verify(mockResult, never()).error(any()); + verify(mockResult, times(1)).success(); } @Test public void setZoomLevel_shouldUpdateBuilder() throws CameraAccessException { ZoomLevelFeature mockZoomLevelFeature = mockCameraFeatureFactory.createZoomLevelFeature(mockCameraProperties); - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); + Messages.VoidResult mockResult = mock(Messages.VoidResult.class); float zoomLevel = 1.0f; when(mockZoomLevelFeature.getValue()).thenReturn(zoomLevel); @@ -538,7 +577,7 @@ public void setZoomLevel_shouldCallErrorOnResultOnCameraAccessException() throws CameraAccessException { ZoomLevelFeature mockZoomLevelFeature = mockCameraFeatureFactory.createZoomLevelFeature(mockCameraProperties); - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); + Messages.VoidResult mockResult = mock(Messages.VoidResult.class); float zoomLevel = 1.0f; when(mockZoomLevelFeature.getValue()).thenReturn(zoomLevel); @@ -549,47 +588,38 @@ public void setZoomLevel_shouldCallErrorOnResultOnCameraAccessException() camera.setZoomLevel(mockResult, zoomLevel); - verify(mockResult, never()).success(any()); - verify(mockResult, times(1)).error("setZoomLevelFailed", "Could not set zoom level.", null); + verify(mockResult, never()).success(); + verify(mockResult, times(1)) + .error( + argThat( + new FlutterErrorMatcher("setZoomLevelFailed", "Could not set zoom level.", null))); } @Test - public void pauseVideoRecording_shouldSendNullResultWhenNotRecording() { + public void pauseVideoRecording_shouldNotThrowWhenNotRecording() { camera.recordingVideo = false; - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); - - camera.pauseVideoRecording(mockResult); - verify(mockResult, times(1)).success(null); - verify(mockResult, never()).error(any(), any(), any()); + camera.pauseVideoRecording(); } @Test public void pauseVideoRecording_shouldCallPauseWhenRecordingAndOnAPIN() { - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); MediaRecorder mockMediaRecorder = mock(MediaRecorder.class); camera.mediaRecorder = mockMediaRecorder; camera.recordingVideo = true; SdkCapabilityChecker.SDK_VERSION = 24; - camera.pauseVideoRecording(mockResult); + camera.pauseVideoRecording(); verify(mockMediaRecorder, times(1)).pause(); - verify(mockResult, times(1)).success(null); - verify(mockResult, never()).error(any(), any(), any()); } @Test public void pauseVideoRecording_shouldSendVideoRecordingFailedErrorWhenVersionCodeSmallerThenN() { camera.recordingVideo = true; SdkCapabilityChecker.SDK_VERSION = 23; - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); - camera.pauseVideoRecording(mockResult); - - verify(mockResult, times(1)) - .error("videoRecordingFailed", "pauseVideoRecording requires Android API +24.", null); - verify(mockResult, never()).success(any()); + assertThrows(Messages.FlutterError.class, camera::pauseVideoRecording); } @Test @@ -604,43 +634,30 @@ public void pauseVideoRecording_shouldSendVideoRecordingFailedErrorWhenVersionCo doThrow(expectedException).when(mockMediaRecorder).pause(); - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); - - camera.pauseVideoRecording(mockResult); - - verify(mockResult, times(1)).error("videoRecordingFailed", "Test error message", null); - verify(mockResult, never()).success(any()); + assertThrows(Messages.FlutterError.class, camera::pauseVideoRecording); } @Test - public void resumeVideoRecording_shouldSendNullResultWhenNotRecording() { - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); + public void resumeVideoRecording_shouldNotThrowWhenNotRecording() { camera.recordingVideo = false; - camera.resumeVideoRecording(mockResult); - - verify(mockResult, times(1)).success(null); - verify(mockResult, never()).error(any(), any(), any()); + camera.resumeVideoRecording(); } @Test public void resumeVideoRecording_shouldCallPauseWhenRecordingAndOnAPIN() { - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); MediaRecorder mockMediaRecorder = mock(MediaRecorder.class); camera.mediaRecorder = mockMediaRecorder; camera.recordingVideo = true; SdkCapabilityChecker.SDK_VERSION = 24; - camera.resumeVideoRecording(mockResult); + camera.resumeVideoRecording(); verify(mockMediaRecorder, times(1)).resume(); - verify(mockResult, times(1)).success(null); - verify(mockResult, never()).error(any(), any(), any()); } @Test public void setDescriptionWhileRecording_errorsWhenUnsupported() { - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); MediaRecorder mockMediaRecorder = mock(MediaRecorder.class); VideoRenderer mockVideoRenderer = mock(VideoRenderer.class); camera.mediaRecorder = mockMediaRecorder; @@ -649,18 +666,13 @@ public void setDescriptionWhileRecording_errorsWhenUnsupported() { SdkCapabilityChecker.SDK_VERSION = Build.VERSION_CODES.LOLLIPOP; final CameraProperties newCameraProperties = mock(CameraProperties.class); - camera.setDescriptionWhileRecording(mockResult, newCameraProperties); - - verify(mockResult, times(1)) - .error( - eq("setDescriptionWhileRecordingFailed"), - eq("Device does not support switching the camera while recording"), - eq(null)); + assertThrows( + Messages.FlutterError.class, + () -> camera.setDescriptionWhileRecording(newCameraProperties)); } @Test public void setDescriptionWhileRecording_succeedsWhenSupported() { - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); MediaRecorder mockMediaRecorder = mock(MediaRecorder.class); VideoRenderer mockVideoRenderer = mock(VideoRenderer.class); camera.mediaRecorder = mockMediaRecorder; @@ -669,10 +681,7 @@ public void setDescriptionWhileRecording_succeedsWhenSupported() { SdkCapabilityChecker.SDK_VERSION = Build.VERSION_CODES.O; final CameraProperties newCameraProperties = mock(CameraProperties.class); - camera.setDescriptionWhileRecording(mockResult, newCameraProperties); - - verify(mockResult, times(1)).success(null); - verify(mockResult, never()).error(any(), any(), any()); + camera.setDescriptionWhileRecording(newCameraProperties); } @Test @@ -784,14 +793,11 @@ public void startPreviewWithImageStream_shouldPullStreamsFromImageReaders() @Test public void setDescriptionWhileRecording_shouldErrorWhenNotRecording() { - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); camera.recordingVideo = false; final CameraProperties newCameraProperties = mock(CameraProperties.class); - camera.setDescriptionWhileRecording(mockResult, newCameraProperties); - - verify(mockResult, times(1)) - .error("setDescriptionWhileRecordingFailed", "Device was not recording", null); - verify(mockResult, never()).success(any()); + assertThrows( + Messages.FlutterError.class, + () -> camera.setDescriptionWhileRecording(newCameraProperties)); } @Test @@ -800,13 +806,7 @@ public void setDescriptionWhileRecording_shouldErrorWhenNotRecording() { camera.recordingVideo = true; SdkCapabilityChecker.SDK_VERSION = 23; - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); - - camera.resumeVideoRecording(mockResult); - - verify(mockResult, times(1)) - .error("videoRecordingFailed", "resumeVideoRecording requires Android API +24.", null); - verify(mockResult, never()).success(any()); + assertThrows(Messages.FlutterError.class, camera::resumeVideoRecording); } @Test @@ -821,41 +821,32 @@ public void setDescriptionWhileRecording_shouldErrorWhenNotRecording() { doThrow(expectedException).when(mockMediaRecorder).resume(); - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); - - camera.resumeVideoRecording(mockResult); - - verify(mockResult, times(1)).error("videoRecordingFailed", "Test error message", null); - verify(mockResult, never()).success(any()); + assertThrows(Messages.FlutterError.class, camera::resumeVideoRecording); } @Test public void setFocusMode_shouldUpdateAutoFocusFeature() { AutoFocusFeature mockAutoFocusFeature = mockCameraFeatureFactory.createAutoFocusFeature(mockCameraProperties, false); - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); - camera.setFocusMode(mockResult, FocusMode.auto); + camera.setFocusMode(FocusMode.auto); verify(mockAutoFocusFeature, times(1)).setValue(FocusMode.auto); - verify(mockResult, never()).error(any(), any(), any()); - verify(mockResult, times(1)).success(null); } @Test public void setFocusMode_shouldUpdateBuilder() { AutoFocusFeature mockAutoFocusFeature = mockCameraFeatureFactory.createAutoFocusFeature(mockCameraProperties, false); - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); - camera.setFocusMode(mockResult, FocusMode.auto); + camera.setFocusMode(FocusMode.auto); verify(mockAutoFocusFeature, times(1)).updateBuilder(any()); } @Test public void setFocusMode_shouldUnlockAutoFocusForAutoMode() { - camera.setFocusMode(mock(MethodChannel.Result.class), FocusMode.auto); + camera.setFocusMode(FocusMode.auto); verify(mockPreviewRequestBuilder, times(1)) .set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL); verify(mockPreviewRequestBuilder, times(1)) @@ -865,7 +856,7 @@ public void setFocusMode_shouldUnlockAutoFocusForAutoMode() { @Test public void setFocusMode_shouldSkipUnlockAutoFocusWhenNullCaptureSession() { camera.captureSession = null; - camera.setFocusMode(mock(MethodChannel.Result.class), FocusMode.auto); + camera.setFocusMode(FocusMode.auto); verify(mockPreviewRequestBuilder, never()) .set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL); verify(mockPreviewRequestBuilder, never()) @@ -877,7 +868,7 @@ public void setFocusMode_shouldSendErrorEventOnUnlockAutoFocusCameraAccessExcept throws CameraAccessException { when(mockCaptureSession.capture(any(), any(), any())) .thenThrow(new CameraAccessException(0, "")); - camera.setFocusMode(mock(MethodChannel.Result.class), FocusMode.auto); + camera.setFocusMode(FocusMode.auto); verify(mockDartMessenger, times(1)).sendCameraErrorEvent(any()); } @@ -896,16 +887,15 @@ public void startVideoRecording_shouldPullStreamsFromMediaRecorderAndImageReader cameraSpy.pictureImageReader = mockPictureImageReader; CameraDeviceWrapper fakeCamera = new FakeCameraDeviceWrapper(mockRequestBuilders); cameraSpy.cameraDevice = fakeCamera; - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); TextureRegistry.SurfaceTextureEntry cameraFlutterTexture = cameraSpy.flutterTexture; ResolutionFeature resolutionFeature = mockCameraFeatureFactory.mockResolutionFeature; when(cameraFlutterTexture.surfaceTexture()).thenReturn(mockSurfaceTexture); when(resolutionFeature.getPreviewSize()).thenReturn(mockSize); - doNothing().when(cameraSpy).prepareRecording(mockResult); + doNothing().when(cameraSpy).prepareRecording(); - cameraSpy.startVideoRecording(mockResult, null); + cameraSpy.startVideoRecording(null); verify(mockMediaRecorder, times(1)) .getSurface(); // stream pulled from media recorder's surface. verify( @@ -916,7 +906,7 @@ public void startVideoRecording_shouldPullStreamsFromMediaRecorderAndImageReader @Test public void setFocusMode_shouldLockAutoFocusForLockedMode() throws CameraAccessException { - camera.setFocusMode(mock(MethodChannel.Result.class), FocusMode.locked); + camera.setFocusMode(FocusMode.locked); verify(mockPreviewRequestBuilder, times(1)) .set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START); verify(mockCaptureSession, times(1)).capture(any(), any(), any()); @@ -926,7 +916,7 @@ public void setFocusMode_shouldLockAutoFocusForLockedMode() throws CameraAccessE @Test public void setFocusMode_shouldSkipLockAutoFocusWhenNullCaptureSession() { camera.captureSession = null; - camera.setFocusMode(mock(MethodChannel.Result.class), FocusMode.locked); + camera.setFocusMode(FocusMode.locked); verify(mockPreviewRequestBuilder, never()) .set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_START); } @@ -936,36 +926,32 @@ public void setFocusMode_shouldSendErrorEventOnLockAutoFocusCameraAccessExceptio throws CameraAccessException { when(mockCaptureSession.capture(any(), any(), any())) .thenThrow(new CameraAccessException(0, "")); - camera.setFocusMode(mock(MethodChannel.Result.class), FocusMode.locked); + camera.setFocusMode(FocusMode.locked); verify(mockDartMessenger, times(1)).sendCameraErrorEvent(any()); } @Test public void setFocusMode_shouldCallErrorOnResultOnCameraAccessException() throws CameraAccessException { - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); when(mockCaptureSession.setRepeatingRequest(any(), any(), any())) .thenThrow(new CameraAccessException(0, "")); - camera.setFocusMode(mockResult, FocusMode.locked); - - verify(mockResult, never()).success(any()); - verify(mockResult, times(1)) - .error("setFocusModeFailed", "Error setting focus mode: null", null); + assertThrows(Messages.FlutterError.class, () -> camera.setFocusMode(FocusMode.locked)); } @Test public void setExposureOffset_shouldUpdateExposureOffsetFeature() { ExposureOffsetFeature mockExposureOffsetFeature = mockCameraFeatureFactory.createExposureOffsetFeature(mockCameraProperties); - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); + @SuppressWarnings("unchecked") + Messages.Result mockResult = mock(Messages.Result.class); when(mockExposureOffsetFeature.getValue()).thenReturn(1.0); camera.setExposureOffset(mockResult, 1.0); verify(mockExposureOffsetFeature, times(1)).setValue(1.0); - verify(mockResult, never()).error(any(), any(), any()); + verify(mockResult, never()).error(any()); verify(mockResult, times(1)).success(1.0); } @@ -973,7 +959,8 @@ public void setExposureOffset_shouldUpdateExposureOffsetFeature() { public void setExposureOffset_shouldAndUpdateBuilder() { ExposureOffsetFeature mockExposureOffsetFeature = mockCameraFeatureFactory.createExposureOffsetFeature(mockCameraProperties); - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); + @SuppressWarnings("unchecked") + Messages.Result mockResult = mock(Messages.Result.class); camera.setExposureOffset(mockResult, 1.0); @@ -983,7 +970,8 @@ public void setExposureOffset_shouldAndUpdateBuilder() { @Test public void setExposureOffset_shouldCallErrorOnResultOnCameraAccessException() throws CameraAccessException { - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); + @SuppressWarnings("unchecked") + Messages.Result mockResult = mock(Messages.Result.class); when(mockCaptureSession.setRepeatingRequest(any(), any(), any())) .thenThrow(new CameraAccessException(0, "")); @@ -991,7 +979,10 @@ public void setExposureOffset_shouldCallErrorOnResultOnCameraAccessException() verify(mockResult, never()).success(any()); verify(mockResult, times(1)) - .error("setExposureOffsetFailed", "Could not set exposure offset.", null); + .error( + argThat( + new FlutterErrorMatcher( + "setExposureOffsetFailed", "Could not set exposure offset.", null))); } @Test @@ -1253,7 +1244,6 @@ public void startVideoRecording_shouldApplySettingsToMediaRecorder() new FakeCameraDeviceWrapper(mockRequestBuilders, mockCaptureSession); camera.cameraDevice = fakeCamera; - MethodChannel.Result mockResult = mock(MethodChannel.Result.class); TextureRegistry.SurfaceTextureEntry cameraFlutterTexture = camera.flutterTexture; @@ -1265,7 +1255,7 @@ public void startVideoRecording_shouldApplySettingsToMediaRecorder() assertNotNull(resolutionFeature); when(resolutionFeature.getPreviewSize()).thenReturn(mockSize); - camera.startVideoRecording(mockResult, null); + camera.startVideoRecording(null); //region Check that FPS parameter affects AE range at which the camera captures frames. assertEquals(camera.cameraFeatures.getFpsRange().getValue().getLower(), Integer.valueOf(fps)); diff --git a/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/CameraUtilsTest.java b/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/CameraUtilsTest.java index e59b05bf4fe3..fb3588e45894 100644 --- a/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/CameraUtilsTest.java +++ b/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/CameraUtilsTest.java @@ -12,59 +12,21 @@ import android.app.Activity; import android.content.Context; +import android.graphics.ImageFormat; import android.hardware.camera2.CameraAccessException; import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CameraManager; import android.hardware.camera2.CameraMetadata; import io.flutter.embedding.engine.systemchannels.PlatformChannel; +import io.flutter.plugins.camera.features.autofocus.FocusMode; +import io.flutter.plugins.camera.features.exposurelock.ExposureMode; +import io.flutter.plugins.camera.features.flash.FlashMode; +import io.flutter.plugins.camera.features.resolution.ResolutionPreset; import java.util.List; -import java.util.Map; import org.junit.Test; public class CameraUtilsTest { - @Test - public void serializeDeviceOrientation_serializesCorrectly() { - assertEquals( - "portraitUp", - CameraUtils.serializeDeviceOrientation(PlatformChannel.DeviceOrientation.PORTRAIT_UP)); - assertEquals( - "portraitDown", - CameraUtils.serializeDeviceOrientation(PlatformChannel.DeviceOrientation.PORTRAIT_DOWN)); - assertEquals( - "landscapeLeft", - CameraUtils.serializeDeviceOrientation(PlatformChannel.DeviceOrientation.LANDSCAPE_LEFT)); - assertEquals( - "landscapeRight", - CameraUtils.serializeDeviceOrientation(PlatformChannel.DeviceOrientation.LANDSCAPE_RIGHT)); - } - - @Test(expected = UnsupportedOperationException.class) - public void serializeDeviceOrientation_throws_for_null() { - CameraUtils.serializeDeviceOrientation(null); - } - - @Test - public void deserializeDeviceOrientation_deserializesCorrectly() { - assertEquals( - PlatformChannel.DeviceOrientation.PORTRAIT_UP, - CameraUtils.deserializeDeviceOrientation("portraitUp")); - assertEquals( - PlatformChannel.DeviceOrientation.PORTRAIT_DOWN, - CameraUtils.deserializeDeviceOrientation("portraitDown")); - assertEquals( - PlatformChannel.DeviceOrientation.LANDSCAPE_LEFT, - CameraUtils.deserializeDeviceOrientation("landscapeLeft")); - assertEquals( - PlatformChannel.DeviceOrientation.LANDSCAPE_RIGHT, - CameraUtils.deserializeDeviceOrientation("landscapeRight")); - } - - @Test(expected = UnsupportedOperationException.class) - public void deserializeDeviceOrientation_throwsForNull() { - CameraUtils.deserializeDeviceOrientation(null); - } - @Test public void getAvailableCameras_retrievesValidCameras() throws CameraAccessException, NumberFormatException { @@ -87,14 +49,126 @@ public void getAvailableCameras_retrievesValidCameras() .thenReturn(mockSensorOrientation2) .thenReturn(mockLensFacing2); - List> availableCameras = CameraUtils.getAvailableCameras(mockActivity); + List availableCameras = + CameraUtils.getAvailableCameras(mockActivity); assertEquals(availableCameras.size(), 2); - assertEquals(availableCameras.get(0).get("name"), "1394902"); - assertEquals(availableCameras.get(0).get("sensorOrientation"), mockSensorOrientation0); - assertEquals(availableCameras.get(0).get("lensFacing"), "front"); - assertEquals(availableCameras.get(1).get("name"), "0283835"); - assertEquals(availableCameras.get(1).get("sensorOrientation"), mockSensorOrientation2); - assertEquals(availableCameras.get(1).get("lensFacing"), "external"); + assertEquals(availableCameras.get(0).getName(), "1394902"); + assertEquals(availableCameras.get(0).getSensorOrientation().intValue(), mockSensorOrientation0); + assertEquals( + availableCameras.get(0).getLensDirection(), Messages.PlatformCameraLensDirection.FRONT); + assertEquals(availableCameras.get(1).getName(), "0283835"); + assertEquals(availableCameras.get(1).getSensorOrientation().intValue(), mockSensorOrientation2); + assertEquals( + availableCameras.get(1).getLensDirection(), Messages.PlatformCameraLensDirection.EXTERNAL); + } + + @Test + public void orientationToPigeonTest() { + assertEquals( + CameraUtils.orientationToPigeon(PlatformChannel.DeviceOrientation.PORTRAIT_UP), + Messages.PlatformDeviceOrientation.PORTRAIT_UP); + assertEquals( + CameraUtils.orientationToPigeon(PlatformChannel.DeviceOrientation.PORTRAIT_DOWN), + Messages.PlatformDeviceOrientation.PORTRAIT_DOWN); + assertEquals( + CameraUtils.orientationToPigeon(PlatformChannel.DeviceOrientation.LANDSCAPE_LEFT), + Messages.PlatformDeviceOrientation.LANDSCAPE_LEFT); + assertEquals( + CameraUtils.orientationToPigeon(PlatformChannel.DeviceOrientation.LANDSCAPE_RIGHT), + Messages.PlatformDeviceOrientation.LANDSCAPE_RIGHT); + } + + @Test + public void orientationFromPigeonTest() { + assertEquals( + CameraUtils.orientationFromPigeon(Messages.PlatformDeviceOrientation.PORTRAIT_UP), + PlatformChannel.DeviceOrientation.PORTRAIT_UP); + assertEquals( + CameraUtils.orientationFromPigeon(Messages.PlatformDeviceOrientation.PORTRAIT_DOWN), + PlatformChannel.DeviceOrientation.PORTRAIT_DOWN); + assertEquals( + CameraUtils.orientationFromPigeon(Messages.PlatformDeviceOrientation.LANDSCAPE_LEFT), + PlatformChannel.DeviceOrientation.LANDSCAPE_LEFT); + assertEquals( + CameraUtils.orientationFromPigeon(Messages.PlatformDeviceOrientation.LANDSCAPE_RIGHT), + PlatformChannel.DeviceOrientation.LANDSCAPE_RIGHT); + } + + @Test + public void focusModeToPigeonTest() { + assertEquals(CameraUtils.focusModeToPigeon(FocusMode.auto), Messages.PlatformFocusMode.AUTO); + assertEquals( + CameraUtils.focusModeToPigeon(FocusMode.locked), Messages.PlatformFocusMode.LOCKED); + } + + @Test + public void focusModeFromPigeonTest() { + assertEquals(CameraUtils.focusModeFromPigeon(Messages.PlatformFocusMode.AUTO), FocusMode.auto); + assertEquals( + CameraUtils.focusModeFromPigeon(Messages.PlatformFocusMode.LOCKED), FocusMode.locked); + } + + @Test + public void exposureModeToPigeonTest() { + assertEquals( + CameraUtils.exposureModeToPigeon(ExposureMode.auto), Messages.PlatformExposureMode.AUTO); + assertEquals( + CameraUtils.exposureModeToPigeon(ExposureMode.locked), + Messages.PlatformExposureMode.LOCKED); + } + + @Test + public void exposureModeFromPigeonTest() { + assertEquals( + CameraUtils.exposureModeFromPigeon(Messages.PlatformExposureMode.AUTO), ExposureMode.auto); + assertEquals( + CameraUtils.exposureModeFromPigeon(Messages.PlatformExposureMode.LOCKED), + ExposureMode.locked); + } + + @Test + public void resolutionPresetFromPigeonTest() { + assertEquals( + CameraUtils.resolutionPresetFromPigeon(Messages.PlatformResolutionPreset.LOW), + ResolutionPreset.low); + assertEquals( + CameraUtils.resolutionPresetFromPigeon(Messages.PlatformResolutionPreset.MEDIUM), + ResolutionPreset.medium); + assertEquals( + CameraUtils.resolutionPresetFromPigeon(Messages.PlatformResolutionPreset.HIGH), + ResolutionPreset.high); + assertEquals( + CameraUtils.resolutionPresetFromPigeon(Messages.PlatformResolutionPreset.VERY_HIGH), + ResolutionPreset.veryHigh); + assertEquals( + CameraUtils.resolutionPresetFromPigeon(Messages.PlatformResolutionPreset.ULTRA_HIGH), + ResolutionPreset.ultraHigh); + assertEquals( + CameraUtils.resolutionPresetFromPigeon(Messages.PlatformResolutionPreset.MAX), + ResolutionPreset.max); + } + + @Test + public void imageFormatGroupFromPigeonTest() { + assertEquals( + CameraUtils.imageFormatGroupFromPigeon(Messages.PlatformImageFormatGroup.YUV420).intValue(), + ImageFormat.YUV_420_888); + assertEquals( + CameraUtils.imageFormatGroupFromPigeon(Messages.PlatformImageFormatGroup.JPEG).intValue(), + ImageFormat.JPEG); + assertEquals( + CameraUtils.imageFormatGroupFromPigeon(Messages.PlatformImageFormatGroup.NV21).intValue(), + ImageFormat.NV21); + } + + @Test + public void flashModeFromPigeonTest() { + assertEquals(CameraUtils.flashModeFromPigeon(Messages.PlatformFlashMode.AUTO), FlashMode.auto); + assertEquals( + CameraUtils.flashModeFromPigeon(Messages.PlatformFlashMode.ALWAYS), FlashMode.always); + assertEquals(CameraUtils.flashModeFromPigeon(Messages.PlatformFlashMode.OFF), FlashMode.off); + assertEquals( + CameraUtils.flashModeFromPigeon(Messages.PlatformFlashMode.TORCH), FlashMode.torch); } } diff --git a/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java b/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java index 0a2fc43d03cb..a053d937b918 100644 --- a/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java +++ b/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java @@ -4,132 +4,116 @@ package io.flutter.plugins.camera; -import static junit.framework.TestCase.assertNull; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import android.os.Handler; -import androidx.annotation.NonNull; import io.flutter.embedding.engine.systemchannels.PlatformChannel; -import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.MethodCall; -import io.flutter.plugin.common.StandardMethodCodec; import io.flutter.plugins.camera.features.autofocus.FocusMode; import io.flutter.plugins.camera.features.exposurelock.ExposureMode; -import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; import org.junit.Before; import org.junit.Test; import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; public class DartMessengerTest { - /** A {@link BinaryMessenger} implementation that does nothing but save its messages. */ - private static class FakeBinaryMessenger implements BinaryMessenger { - private final List sentMessages = new ArrayList<>(); - @Override - public void send(@NonNull String channel, ByteBuffer message) { - sentMessages.add(message); - } - - @Override - public void send(@NonNull String channel, ByteBuffer message, BinaryReply callback) { - send(channel, message); - } - - @Override - public void setMessageHandler(@NonNull String channel, BinaryMessageHandler handler) {} - - List getMessages() { - return new ArrayList<>(sentMessages); - } - } - - private Handler mockHandler; private DartMessenger dartMessenger; - private FakeBinaryMessenger fakeBinaryMessenger; + private Messages.CameraGlobalEventApi mockGlobalEventApi; + private Messages.CameraEventApi mockEventApi; @Before public void setUp() { - mockHandler = mock(Handler.class); - fakeBinaryMessenger = new FakeBinaryMessenger(); - dartMessenger = new DartMessenger(fakeBinaryMessenger, 0, mockHandler); + Handler mockHandler = mock(Handler.class); + doAnswer( + (InvocationOnMock invocation) -> { + Runnable r = invocation.getArgument(0); + if (r != null) { + r.run(); + } + return true; + }) + .when(mockHandler) + .post(any(Runnable.class)); + mockGlobalEventApi = mock(Messages.CameraGlobalEventApi.class); + mockEventApi = mock(Messages.CameraEventApi.class); + dartMessenger = new DartMessenger(mockHandler, mockGlobalEventApi, mockEventApi); } @Test public void sendCameraErrorEvent_includesErrorDescriptions() { - doAnswer(createPostHandlerAnswer()).when(mockHandler).post(any(Runnable.class)); + final List errorsList = new ArrayList<>(); + doAnswer( + (InvocationOnMock invocation) -> { + String description = invocation.getArgument(0); + errorsList.add(description); + return null; + }) + .when(mockEventApi) + .error(any(), any()); dartMessenger.sendCameraErrorEvent("error description"); - List sentMessages = fakeBinaryMessenger.getMessages(); - assertEquals(1, sentMessages.size()); - MethodCall call = decodeSentMessage(sentMessages.get(0)); - assertEquals("error", call.method); - assertEquals("error description", call.argument("description")); + assertEquals(1, errorsList.size()); + assertEquals("error description", errorsList.get(0)); } @Test public void sendCameraInitializedEvent_includesPreviewSize() { - doAnswer(createPostHandlerAnswer()).when(mockHandler).post(any(Runnable.class)); + final List statesList = new ArrayList<>(); + doAnswer( + (InvocationOnMock invocation) -> { + Messages.PlatformCameraState state = invocation.getArgument(0); + statesList.add(state); + return null; + }) + .when(mockEventApi) + .initialized(any(), any()); dartMessenger.sendCameraInitializedEvent(0, 0, ExposureMode.auto, FocusMode.auto, true, true); - List sentMessages = fakeBinaryMessenger.getMessages(); - assertEquals(1, sentMessages.size()); - MethodCall call = decodeSentMessage(sentMessages.get(0)); - assertEquals("initialized", call.method); - assertEquals(0, (double) call.argument("previewWidth"), 0); - assertEquals(0, (double) call.argument("previewHeight"), 0); - assertEquals("ExposureMode auto", call.argument("exposureMode"), "auto"); - assertEquals("FocusMode continuous", call.argument("focusMode"), "auto"); - assertEquals("exposurePointSupported", call.argument("exposurePointSupported"), true); - assertEquals("focusPointSupported", call.argument("focusPointSupported"), true); + assertEquals(1, statesList.size()); + Messages.PlatformCameraState state = statesList.get(0); + assertEquals(0, state.getPreviewSize().getWidth(), 0); + assertEquals(0, state.getPreviewSize().getHeight(), 0); + assertEquals("ExposureMode auto", Messages.PlatformExposureMode.AUTO, state.getExposureMode()); + assertEquals("FocusMode continuous", Messages.PlatformFocusMode.AUTO, state.getFocusMode()); + assertEquals("exposurePointSupported", true, state.getExposurePointSupported()); + assertEquals("focusPointSupported", true, state.getFocusPointSupported()); } @Test public void sendCameraClosingEvent() { - doAnswer(createPostHandlerAnswer()).when(mockHandler).post(any(Runnable.class)); + final List calls = new ArrayList<>(); + doAnswer( + (InvocationOnMock invocation) -> { + calls.add(1); + return null; + }) + .when(mockEventApi) + .closed(any()); dartMessenger.sendCameraClosingEvent(); - List sentMessages = fakeBinaryMessenger.getMessages(); - assertEquals(1, sentMessages.size()); - MethodCall call = decodeSentMessage(sentMessages.get(0)); - assertEquals("camera_closing", call.method); - assertNull(call.argument("description")); + assertEquals(1, calls.size()); + assertEquals(1, calls.get(0).intValue()); } @Test public void sendDeviceOrientationChangedEvent() { - doAnswer(createPostHandlerAnswer()).when(mockHandler).post(any(Runnable.class)); + final List eventsList = new ArrayList<>(); + doAnswer( + (InvocationOnMock invocation) -> { + Messages.PlatformDeviceOrientation orientation = invocation.getArgument(0); + eventsList.add(orientation); + return null; + }) + .when(mockGlobalEventApi) + .deviceOrientationChanged(any(), any()); dartMessenger.sendDeviceOrientationChangeEvent(PlatformChannel.DeviceOrientation.PORTRAIT_UP); - List sentMessages = fakeBinaryMessenger.getMessages(); - assertEquals(1, sentMessages.size()); - MethodCall call = decodeSentMessage(sentMessages.get(0)); - assertEquals("orientation_changed", call.method); - assertEquals(call.argument("orientation"), "portraitUp"); - } - - private static Answer createPostHandlerAnswer() { - return new Answer() { - @Override - public Boolean answer(InvocationOnMock invocation) throws Throwable { - Runnable runnable = invocation.getArgument(0, Runnable.class); - if (runnable != null) { - runnable.run(); - } - return true; - } - }; - } - - private MethodCall decodeSentMessage(ByteBuffer sentMessage) { - sentMessage.position(0); - - return StandardMethodCodec.INSTANCE.decodeMethodCall(sentMessage); + assertEquals(1, eventsList.size()); + assertEquals(Messages.PlatformDeviceOrientation.PORTRAIT_UP, eventsList.get(0)); } } diff --git a/packages/camera/camera_android/example/android/app/build.gradle b/packages/camera/camera_android/example/android/app/build.gradle index a6e00fd38961..9e2d6373e872 100644 --- a/packages/camera/camera_android/example/android/app/build.gradle +++ b/packages/camera/camera_android/example/android/app/build.gradle @@ -31,7 +31,7 @@ android { defaultConfig { applicationId "io.flutter.plugins.cameraexample" - minSdkVersion 21 + minSdkVersion flutter.minSdkVersion targetSdkVersion 28 versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/packages/camera/camera_android/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/camera/camera_android/example/android/app/gradle/wrapper/gradle-wrapper.properties index 609ab8e6c8b5..d951fac2bf31 100644 --- a/packages/camera/camera_android/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ b/packages/camera/camera_android/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/packages/camera/camera_android/example/android/build.gradle b/packages/camera/camera_android/example/android/build.gradle index d38534d066af..f127ef59c24b 100644 --- a/packages/camera/camera_android/example/android/build.gradle +++ b/packages/camera/camera_android/example/android/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:8.1.1' + classpath 'com.android.tools.build:gradle:8.5.2' } } diff --git a/packages/camera/camera_android/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/camera/camera_android/example/android/gradle/wrapper/gradle-wrapper.properties index cb086a5fcff7..3c85cfe057a1 100644 --- a/packages/camera/camera_android/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/camera/camera_android/example/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/camera/camera_android/example/lib/main.dart b/packages/camera/camera_android/example/lib/main.dart index 830052e351f4..47c40c7d20d1 100644 --- a/packages/camera/camera_android/example/lib/main.dart +++ b/packages/camera/camera_android/example/lib/main.dart @@ -540,7 +540,7 @@ class _CameraExampleHomeState extends State onPressed: cameraController != null && cameraController.value.isInitialized && cameraController.value.isRecordingVideo - ? (cameraController.value.isRecordingPaused) + ? cameraController.value.isRecordingPaused ? onResumeButtonPressed : onPauseButtonPressed : null, @@ -699,7 +699,6 @@ class _CameraExampleHomeState extends State showInSnackBar('Unknown permission error.'); default: _showCameraException(e); - break; } } diff --git a/packages/camera/camera_android/example/pubspec.yaml b/packages/camera/camera_android/example/pubspec.yaml index cd212825d74b..9c8f8476d0b5 100644 --- a/packages/camera/camera_android/example/pubspec.yaml +++ b/packages/camera/camera_android/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the camera plugin. publish_to: none environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" dependencies: camera_android: diff --git a/packages/camera/camera_android/lib/src/android_camera.dart b/packages/camera/camera_android/lib/src/android_camera.dart index ce0af1715626..975c6c9be022 100644 --- a/packages/camera/camera_android/lib/src/android_camera.dart +++ b/packages/camera/camera_android/lib/src/android_camera.dart @@ -6,25 +6,26 @@ import 'dart:async'; import 'dart:math'; import 'package:camera_platform_interface/camera_platform_interface.dart'; -import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:stream_transform/stream_transform.dart'; +import 'messages.g.dart'; import 'type_conversion.dart'; import 'utils.dart'; -const MethodChannel _channel = - MethodChannel('plugins.flutter.io/camera_android'); - /// The Android implementation of [CameraPlatform] that uses method channels. class AndroidCamera extends CameraPlatform { + /// Creates a new [CameraPlatform] instance. + AndroidCamera({@visibleForTesting CameraApi? hostApi}) + : _hostApi = hostApi ?? CameraApi(); + /// Registers this class as the default instance of [CameraPlatform]. static void registerWith() { CameraPlatform.instance = AndroidCamera(); } - final Map _channels = {}; + final CameraApi _hostApi; /// The name of the channel that device events from the platform side are /// sent on. @@ -43,20 +44,15 @@ class AndroidCamera extends CameraPlatform { final StreamController cameraEventStreamController = StreamController.broadcast(); - /// The controller we need to broadcast the different events coming - /// from handleMethodCall, specific to general device events. - /// - /// It is a `broadcast` because multiple controllers will connect to - /// different stream views of this Controller. - late final StreamController _deviceEventStreamController = - _createDeviceEventStreamController(); + /// Handler for device-level callbacks from the native side. + @visibleForTesting + late final HostDeviceMessageHandler hostHandler = HostDeviceMessageHandler(); - StreamController _createDeviceEventStreamController() { - // Set up the method handler lazily. - const MethodChannel channel = MethodChannel(deviceEventChannelName); - channel.setMethodCallHandler(_handleDeviceMethodCall); - return StreamController.broadcast(); - } + /// Map of camera IDs to camera-level callback handlers listening to their + /// respective platform channels. + @visibleForTesting + final Map hostCameraHandlers = + {}; // The stream to receive frames from the native code. StreamSubscription? _platformImageStreamSubscription; @@ -71,20 +67,15 @@ class AndroidCamera extends CameraPlatform { @override Future> availableCameras() async { try { - final List>? cameras = await _channel - .invokeListMethod>('availableCameras'); - - if (cameras == null) { - return []; - } - - return cameras.map((Map camera) { + final List cameraDescriptions = + await _hostApi.getAvailableCameras(); + return cameraDescriptions + .map((PlatformCameraDescription cameraDescription) { return CameraDescription( - name: camera['name']! as String, - lensDirection: - parseCameraLensDirection(camera['lensFacing']! as String), - sensorOrientation: camera['sensorOrientation']! as int, - ); + name: cameraDescription.name, + lensDirection: cameraLensDirectionFromPlatform( + cameraDescription.lensDirection), + sensorOrientation: cameraDescription.sensorOrientation); }).toList(); } on PlatformException catch (e) { throw CameraException(e.code, e.message); @@ -110,22 +101,8 @@ class AndroidCamera extends CameraPlatform { MediaSettings? mediaSettings, ) async { try { - final ResolutionPreset? resolutionPreset = - mediaSettings?.resolutionPreset; - - final Map? reply = await _channel - .invokeMapMethod('create', { - 'cameraName': cameraDescription.name, - 'resolutionPreset': resolutionPreset != null - ? _serializeResolutionPreset(resolutionPreset) - : null, - 'fps': mediaSettings?.fps, - 'videoBitrate': mediaSettings?.videoBitrate, - 'audioBitrate': mediaSettings?.audioBitrate, - 'enableAudio': mediaSettings?.enableAudio ?? false, - }); - - return reply!['cameraId']! as int; + return await _hostApi.create( + cameraDescription.name, mediaSettingsToPlatform(mediaSettings)); } on PlatformException catch (e) { throw CameraException(e.code, e.message); } @@ -135,59 +112,34 @@ class AndroidCamera extends CameraPlatform { Future initializeCamera( int cameraId, { ImageFormatGroup imageFormatGroup = ImageFormatGroup.unknown, - }) { - _channels.putIfAbsent(cameraId, () { - final MethodChannel channel = - MethodChannel('plugins.flutter.io/camera_android/camera$cameraId'); - channel.setMethodCallHandler( - (MethodCall call) => handleCameraMethodCall(call, cameraId)); - return channel; - }); + }) async { + hostCameraHandlers.putIfAbsent(cameraId, + () => HostCameraMessageHandler(cameraId, cameraEventStreamController)); final Completer completer = Completer(); - onCameraInitialized(cameraId).first.then((CameraInitializedEvent value) { + unawaited(onCameraInitialized(cameraId) + .first + .then((CameraInitializedEvent value) { completer.complete(); - }); + })); - _channel.invokeMapMethod( - 'initialize', - { - 'cameraId': cameraId, - 'imageFormatGroup': imageFormatGroup.name(), - }, - ).catchError( - // TODO(srawlins): This should return a value of the future's type. This - // will fail upcoming analysis checks with - // https://github.com/flutter/flutter/issues/105750. - // ignore: body_might_complete_normally_catch_error - (Object error, StackTrace stackTrace) { - if (error is! PlatformException) { - // ignore: only_throw_errors - throw error; - } - completer.completeError( - CameraException(error.code, error.message), - stackTrace, - ); - }, - ); + try { + await _hostApi.initialize(imageFormatGroupToPlatform(imageFormatGroup)); + } on PlatformException catch (e, s) { + completer.completeError(CameraException(e.code, e.message), s); + } return completer.future; } @override Future dispose(int cameraId) async { - if (_channels.containsKey(cameraId)) { - final MethodChannel? cameraChannel = _channels[cameraId]; - cameraChannel?.setMethodCallHandler(null); - _channels.remove(cameraId); - } + final HostCameraMessageHandler? handler = + hostCameraHandlers.remove(cameraId); + handler?.dispose(); - await _channel.invokeMethod( - 'dispose', - {'cameraId': cameraId}, - ); + await _hostApi.dispose(); } @override @@ -217,7 +169,7 @@ class AndroidCamera extends CameraPlatform { @override Stream onDeviceOrientationChanged() { - return _deviceEventStreamController.stream + return hostHandler.deviceEventStreamController.stream .whereType(); } @@ -226,61 +178,35 @@ class AndroidCamera extends CameraPlatform { int cameraId, DeviceOrientation orientation, ) async { - await _channel.invokeMethod( - 'lockCaptureOrientation', - { - 'cameraId': cameraId, - 'orientation': serializeDeviceOrientation(orientation) - }, - ); + await _hostApi + .lockCaptureOrientation(deviceOrientationToPlatform(orientation)); } @override Future unlockCaptureOrientation(int cameraId) async { - await _channel.invokeMethod( - 'unlockCaptureOrientation', - {'cameraId': cameraId}, - ); + await _hostApi.unlockCaptureOrientation(); } @override Future takePicture(int cameraId) async { - final String? path = await _channel.invokeMethod( - 'takePicture', - {'cameraId': cameraId}, - ); - - if (path == null) { - throw CameraException( - 'INVALID_PATH', - 'The platform "$defaultTargetPlatform" did not return a path while reporting success. The platform should always return a valid path or report an error.', - ); - } - + final String path = await _hostApi.takePicture(); return XFile(path); } + // This optimization is unnecessary on Android. @override - Future prepareForVideoRecording() => - _channel.invokeMethod('prepareForVideoRecording'); + Future prepareForVideoRecording() async {} @override Future startVideoRecording(int cameraId, {Duration? maxVideoDuration}) async { - return startVideoCapturing( - VideoCaptureOptions(cameraId, maxDuration: maxVideoDuration)); + // Ignore maxVideoDuration, as it is unimplemented and deprecated. + return startVideoCapturing(VideoCaptureOptions(cameraId)); } @override Future startVideoCapturing(VideoCaptureOptions options) async { - await _channel.invokeMethod( - 'startVideoRecording', - { - 'cameraId': options.cameraId, - 'maxVideoDuration': options.maxDuration?.inMilliseconds, - 'enableStream': options.streamCallback != null, - }, - ); + await _hostApi.startVideoRecording(options.streamCallback != null); if (options.streamCallback != null) { _installStreamController().stream.listen(options.streamCallback); @@ -290,33 +216,17 @@ class AndroidCamera extends CameraPlatform { @override Future stopVideoRecording(int cameraId) async { - final String? path = await _channel.invokeMethod( - 'stopVideoRecording', - {'cameraId': cameraId}, - ); - - if (path == null) { - throw CameraException( - 'INVALID_PATH', - 'The platform "$defaultTargetPlatform" did not return a path while reporting success. The platform should always return a valid path or report an error.', - ); - } - + final String path = await _hostApi.stopVideoRecording(); return XFile(path); } @override - Future pauseVideoRecording(int cameraId) => _channel.invokeMethod( - 'pauseVideoRecording', - {'cameraId': cameraId}, - ); + Future pauseVideoRecording(int cameraId) => + _hostApi.pauseVideoRecording(); @override Future resumeVideoRecording(int cameraId) => - _channel.invokeMethod( - 'resumeVideoRecording', - {'cameraId': cameraId}, - ); + _hostApi.resumeVideoRecording(); @override Stream onStreamedFrameAvailable(int cameraId, @@ -341,7 +251,7 @@ class AndroidCamera extends CameraPlatform { } Future _startPlatformStream() async { - await _channel.invokeMethod('startImageStream'); + await _hostApi.startImageStream(); _startStreamListener(); } @@ -356,7 +266,7 @@ class AndroidCamera extends CameraPlatform { } FutureOr _onFrameStreamCancel() async { - await _channel.invokeMethod('stopImageStream'); + await _hostApi.stopImageStream(); await _platformImageStreamSubscription?.cancel(); _platformImageStreamSubscription = null; _frameStreamController = null; @@ -369,139 +279,66 @@ class AndroidCamera extends CameraPlatform { @override Future setFlashMode(int cameraId, FlashMode mode) => - _channel.invokeMethod( - 'setFlashMode', - { - 'cameraId': cameraId, - 'mode': _serializeFlashMode(mode), - }, - ); + _hostApi.setFlashMode(flashModeToPlatform(mode)); @override Future setExposureMode(int cameraId, ExposureMode mode) => - _channel.invokeMethod( - 'setExposureMode', - { - 'cameraId': cameraId, - 'mode': serializeExposureMode(mode), - }, - ); + _hostApi.setExposureMode(exposureModeToPlatform(mode)); @override Future setExposurePoint(int cameraId, Point? point) { assert(point == null || point.x >= 0 && point.x <= 1); assert(point == null || point.y >= 0 && point.y <= 1); - return _channel.invokeMethod( - 'setExposurePoint', - { - 'cameraId': cameraId, - 'reset': point == null, - 'x': point?.x, - 'y': point?.y, - }, - ); + return _hostApi.setExposurePoint(pointToPlatform(point)); } @override Future getMinExposureOffset(int cameraId) async { - final double? minExposureOffset = await _channel.invokeMethod( - 'getMinExposureOffset', - {'cameraId': cameraId}, - ); - - return minExposureOffset!; + return _hostApi.getMinExposureOffset(); } @override Future getMaxExposureOffset(int cameraId) async { - final double? maxExposureOffset = await _channel.invokeMethod( - 'getMaxExposureOffset', - {'cameraId': cameraId}, - ); - - return maxExposureOffset!; + return _hostApi.getMaxExposureOffset(); } @override Future getExposureOffsetStepSize(int cameraId) async { - final double? stepSize = await _channel.invokeMethod( - 'getExposureOffsetStepSize', - {'cameraId': cameraId}, - ); - - return stepSize!; + return _hostApi.getExposureOffsetStepSize(); } @override Future setExposureOffset(int cameraId, double offset) async { - final double? appliedOffset = await _channel.invokeMethod( - 'setExposureOffset', - { - 'cameraId': cameraId, - 'offset': offset, - }, - ); - - return appliedOffset!; + return _hostApi.setExposureOffset(offset); } @override Future setFocusMode(int cameraId, FocusMode mode) => - _channel.invokeMethod( - 'setFocusMode', - { - 'cameraId': cameraId, - 'mode': serializeFocusMode(mode), - }, - ); + _hostApi.setFocusMode(focusModeToPlatform(mode)); @override Future setFocusPoint(int cameraId, Point? point) { assert(point == null || point.x >= 0 && point.x <= 1); assert(point == null || point.y >= 0 && point.y <= 1); - return _channel.invokeMethod( - 'setFocusPoint', - { - 'cameraId': cameraId, - 'reset': point == null, - 'x': point?.x, - 'y': point?.y, - }, - ); + return _hostApi.setFocusPoint(pointToPlatform(point)); } @override Future getMaxZoomLevel(int cameraId) async { - final double? maxZoomLevel = await _channel.invokeMethod( - 'getMaxZoomLevel', - {'cameraId': cameraId}, - ); - - return maxZoomLevel!; + return _hostApi.getMaxZoomLevel(); } @override Future getMinZoomLevel(int cameraId) async { - final double? minZoomLevel = await _channel.invokeMethod( - 'getMinZoomLevel', - {'cameraId': cameraId}, - ); - - return minZoomLevel!; + return _hostApi.getMinZoomLevel(); } @override Future setZoomLevel(int cameraId, double zoom) async { try { - await _channel.invokeMethod( - 'setZoomLevel', - { - 'cameraId': cameraId, - 'zoom': zoom, - }, - ); + await _hostApi.setZoomLevel(zoom); } on PlatformException catch (e) { throw CameraException(e.code, e.message); } @@ -509,148 +346,81 @@ class AndroidCamera extends CameraPlatform { @override Future pausePreview(int cameraId) async { - await _channel.invokeMethod( - 'pausePreview', - {'cameraId': cameraId}, - ); + await _hostApi.pausePreview(); } @override Future resumePreview(int cameraId) async { - await _channel.invokeMethod( - 'resumePreview', - {'cameraId': cameraId}, - ); + await _hostApi.resumePreview(); } @override Future setDescriptionWhileRecording( CameraDescription description) async { - await _channel.invokeMethod( - 'setDescriptionWhileRecording', - { - 'cameraName': description.name, - }, - ); + await _hostApi.setDescriptionWhileRecording(description.name); } @override Widget buildPreview(int cameraId) { return Texture(textureId: cameraId); } +} - /// Returns the flash mode as a String. - String _serializeFlashMode(FlashMode flashMode) { - switch (flashMode) { - case FlashMode.off: - return 'off'; - case FlashMode.auto: - return 'auto'; - case FlashMode.always: - return 'always'; - case FlashMode.torch: - return 'torch'; - } - // The enum comes from a different package, which could get a new value at - // any time, so provide a fallback that ensures this won't break when used - // with a version that contains new values. This is deliberately outside - // the switch rather than a `default` so that the linter will flag the - // switch as needing an update. - // ignore: dead_code - return 'off'; - } - - /// Returns the resolution preset as a String. - String _serializeResolutionPreset(ResolutionPreset resolutionPreset) { - switch (resolutionPreset) { - case ResolutionPreset.max: - return 'max'; - case ResolutionPreset.ultraHigh: - return 'ultraHigh'; - case ResolutionPreset.veryHigh: - return 'veryHigh'; - case ResolutionPreset.high: - return 'high'; - case ResolutionPreset.medium: - return 'medium'; - case ResolutionPreset.low: - return 'low'; - } - // The enum comes from a different package, which could get a new value at - // any time, so provide a fallback that ensures this won't break when used - // with a version that contains new values. This is deliberately outside - // the switch rather than a `default` so that the linter will flag the - // switch as needing an update. - // ignore: dead_code - return 'max'; - } - - /// Converts messages received from the native platform into device events. - Future _handleDeviceMethodCall(MethodCall call) async { - switch (call.method) { - case 'orientation_changed': - final Map arguments = _getArgumentDictionary(call); - _deviceEventStreamController.add(DeviceOrientationChangedEvent( - deserializeDeviceOrientation(arguments['orientation']! as String))); - default: - throw MissingPluginException(); - } +/// Handles callbacks from the platform host that are not camera-specific. +@visibleForTesting +class HostDeviceMessageHandler implements CameraGlobalEventApi { + /// Creates a new handler and registers it to listen to the global event platform channel. + HostDeviceMessageHandler() { + CameraGlobalEventApi.setUp(this); } - /// Converts messages received from the native platform into camera events. - /// - /// This is only exposed for test purposes. It shouldn't be used by clients of - /// the plugin as it may break or change at any time. - @visibleForTesting - Future handleCameraMethodCall(MethodCall call, int cameraId) async { - switch (call.method) { - case 'initialized': - final Map arguments = _getArgumentDictionary(call); - cameraEventStreamController.add(CameraInitializedEvent( - cameraId, - arguments['previewWidth']! as double, - arguments['previewHeight']! as double, - deserializeExposureMode(arguments['exposureMode']! as String), - arguments['exposurePointSupported']! as bool, - deserializeFocusMode(arguments['focusMode']! as String), - arguments['focusPointSupported']! as bool, - )); - case 'resolution_changed': - final Map arguments = _getArgumentDictionary(call); - cameraEventStreamController.add(CameraResolutionChangedEvent( - cameraId, - arguments['captureWidth']! as double, - arguments['captureHeight']! as double, - )); - case 'camera_closing': - cameraEventStreamController.add(CameraClosingEvent( - cameraId, - )); - case 'video_recorded': - final Map arguments = _getArgumentDictionary(call); - cameraEventStreamController.add(VideoRecordedEvent( - cameraId, - XFile(arguments['path']! as String), - arguments['maxVideoDuration'] != null - ? Duration(milliseconds: arguments['maxVideoDuration']! as int) - : null, - )); - case 'error': - final Map arguments = _getArgumentDictionary(call); - cameraEventStreamController.add(CameraErrorEvent( - cameraId, - arguments['description']! as String, - )); - default: - throw MissingPluginException(); - } + /// The controller that broadcasts device events coming from the host platform. + final StreamController deviceEventStreamController = + StreamController.broadcast(); + @override + void deviceOrientationChanged(PlatformDeviceOrientation orientation) { + deviceEventStreamController.add(DeviceOrientationChangedEvent( + deviceOrientationFromPlatform(orientation))); } +} - /// Returns the arguments of [call] as typed string-keyed Map. - /// - /// This does not do any type validation, so is only safe to call if the - /// arguments are known to be a map. - Map _getArgumentDictionary(MethodCall call) { - return (call.arguments as Map).cast(); +/// Handles camera-specific callbacks from the platform host. +@visibleForTesting +class HostCameraMessageHandler implements CameraEventApi { + /// Creates a new handler and registers it to listen to its camera's platform channel. + HostCameraMessageHandler(this.cameraId, this.cameraEventStreamController) { + CameraEventApi.setUp(this, messageChannelSuffix: '$cameraId'); + } + + /// Removes this handler from its platform channel. + void dispose() { + CameraEventApi.setUp(null, messageChannelSuffix: '$cameraId'); + } + + /// The ID of the camera for which this handler listens for events. + final int cameraId; + + /// The controller which broadcasts camera events from the host platform. + final StreamController cameraEventStreamController; + @override + void error(String message) { + cameraEventStreamController.add(CameraErrorEvent(cameraId, message)); + } + + @override + void initialized(PlatformCameraState initialState) { + cameraEventStreamController.add(CameraInitializedEvent( + cameraId, + initialState.previewSize.width, + initialState.previewSize.height, + exposureModeFromPlatform(initialState.exposureMode), + initialState.exposurePointSupported, + focusModeFromPlatform(initialState.focusMode), + initialState.focusPointSupported)); + } + + @override + void closed() { + cameraEventStreamController.add(CameraClosingEvent(cameraId)); } } diff --git a/packages/camera/camera_android/lib/src/messages.g.dart b/packages/camera/camera_android/lib/src/messages.g.dart new file mode 100644 index 000000000000..81e21a01da3f --- /dev/null +++ b/packages/camera/camera_android/lib/src/messages.g.dart @@ -0,0 +1,1272 @@ +// 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 (v22.4.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 + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; + +import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/services.dart'; + +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); +} + +List wrapResponse( + {Object? result, PlatformException? error, bool empty = false}) { + if (empty) { + return []; + } + if (error == null) { + return [result]; + } + return [error.code, error.message, error.details]; +} + +/// Pigeon equivalent of [CameraLensDirection]. +enum PlatformCameraLensDirection { + front, + back, + external, +} + +/// Pigeon equivalent of [DeviceOrientation]. +enum PlatformDeviceOrientation { + portraitUp, + portraitDown, + landscapeLeft, + landscapeRight, +} + +/// Pigeon equivalent of [ExposureMode]. +enum PlatformExposureMode { + auto, + locked, +} + +/// Pigeon equivalent of [FocusMode]. +enum PlatformFocusMode { + auto, + locked, +} + +/// Pigeon equivalent of [ResolutionPreset]. +enum PlatformResolutionPreset { + low, + medium, + high, + veryHigh, + ultraHigh, + max, +} + +/// Pigeon equivalent of [ImageFormatGroup]. +enum PlatformImageFormatGroup { + /// The default for Android. + yuv420, + jpeg, + nv21, +} + +/// Pigeon equivalent of [FlashMode]. +enum PlatformFlashMode { + off, + auto, + always, + torch, +} + +/// Pigeon equivalent of [CameraDescription]. +class PlatformCameraDescription { + PlatformCameraDescription({ + required this.name, + required this.lensDirection, + required this.sensorOrientation, + }); + + String name; + + PlatformCameraLensDirection lensDirection; + + int sensorOrientation; + + Object encode() { + return [ + name, + lensDirection, + sensorOrientation, + ]; + } + + static PlatformCameraDescription decode(Object result) { + result as List; + return PlatformCameraDescription( + name: result[0]! as String, + lensDirection: result[1]! as PlatformCameraLensDirection, + sensorOrientation: result[2]! as int, + ); + } +} + +/// Data needed for [CameraInitializedEvent]. +class PlatformCameraState { + PlatformCameraState({ + required this.previewSize, + required this.exposureMode, + required this.focusMode, + required this.exposurePointSupported, + required this.focusPointSupported, + }); + + PlatformSize previewSize; + + PlatformExposureMode exposureMode; + + PlatformFocusMode focusMode; + + bool exposurePointSupported; + + bool focusPointSupported; + + Object encode() { + return [ + previewSize, + exposureMode, + focusMode, + exposurePointSupported, + focusPointSupported, + ]; + } + + static PlatformCameraState decode(Object result) { + result as List; + return PlatformCameraState( + previewSize: result[0]! as PlatformSize, + exposureMode: result[1]! as PlatformExposureMode, + focusMode: result[2]! as PlatformFocusMode, + exposurePointSupported: result[3]! as bool, + focusPointSupported: result[4]! as bool, + ); + } +} + +/// Pigeon equivalent of [Size]. +class PlatformSize { + PlatformSize({ + required this.width, + required this.height, + }); + + double width; + + double height; + + Object encode() { + return [ + width, + height, + ]; + } + + static PlatformSize decode(Object result) { + result as List; + return PlatformSize( + width: result[0]! as double, + height: result[1]! as double, + ); + } +} + +/// Pigeon equivalent of [Point]. +class PlatformPoint { + PlatformPoint({ + required this.x, + required this.y, + }); + + double x; + + double y; + + Object encode() { + return [ + x, + y, + ]; + } + + static PlatformPoint decode(Object result) { + result as List; + return PlatformPoint( + x: result[0]! as double, + y: result[1]! as double, + ); + } +} + +/// Pigeon equivalent of [MediaSettings]. +class PlatformMediaSettings { + PlatformMediaSettings({ + required this.resolutionPreset, + this.fps, + this.videoBitrate, + this.audioBitrate, + required this.enableAudio, + }); + + PlatformResolutionPreset resolutionPreset; + + int? fps; + + int? videoBitrate; + + int? audioBitrate; + + bool enableAudio; + + Object encode() { + return [ + resolutionPreset, + fps, + videoBitrate, + audioBitrate, + enableAudio, + ]; + } + + static PlatformMediaSettings decode(Object result) { + result as List; + return PlatformMediaSettings( + resolutionPreset: result[0]! as PlatformResolutionPreset, + fps: result[1] as int?, + videoBitrate: result[2] as int?, + audioBitrate: result[3] as int?, + enableAudio: result[4]! as bool, + ); + } +} + +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is PlatformCameraLensDirection) { + buffer.putUint8(129); + writeValue(buffer, value.index); + } else if (value is PlatformDeviceOrientation) { + buffer.putUint8(130); + writeValue(buffer, value.index); + } else if (value is PlatformExposureMode) { + buffer.putUint8(131); + writeValue(buffer, value.index); + } else if (value is PlatformFocusMode) { + buffer.putUint8(132); + writeValue(buffer, value.index); + } else if (value is PlatformResolutionPreset) { + buffer.putUint8(133); + writeValue(buffer, value.index); + } else if (value is PlatformImageFormatGroup) { + buffer.putUint8(134); + writeValue(buffer, value.index); + } else if (value is PlatformFlashMode) { + buffer.putUint8(135); + writeValue(buffer, value.index); + } else if (value is PlatformCameraDescription) { + buffer.putUint8(136); + writeValue(buffer, value.encode()); + } else if (value is PlatformCameraState) { + buffer.putUint8(137); + writeValue(buffer, value.encode()); + } else if (value is PlatformSize) { + buffer.putUint8(138); + writeValue(buffer, value.encode()); + } else if (value is PlatformPoint) { + buffer.putUint8(139); + writeValue(buffer, value.encode()); + } else if (value is PlatformMediaSettings) { + buffer.putUint8(140); + writeValue(buffer, value.encode()); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 129: + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformCameraLensDirection.values[value]; + case 130: + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformDeviceOrientation.values[value]; + case 131: + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformExposureMode.values[value]; + case 132: + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformFocusMode.values[value]; + case 133: + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformResolutionPreset.values[value]; + case 134: + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformImageFormatGroup.values[value]; + case 135: + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformFlashMode.values[value]; + case 136: + return PlatformCameraDescription.decode(readValue(buffer)!); + case 137: + return PlatformCameraState.decode(readValue(buffer)!); + case 138: + return PlatformSize.decode(readValue(buffer)!); + case 139: + return PlatformPoint.decode(readValue(buffer)!); + case 140: + return PlatformMediaSettings.decode(readValue(buffer)!); + default: + return super.readValueOfType(type, buffer); + } + } +} + +/// Handles calls from Dart to the native side. +class CameraApi { + /// Constructor for [CameraApi]. 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. + CameraApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String pigeonVar_messageChannelSuffix; + + /// Returns the list of available cameras. + Future> getAvailableCameras() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.getAvailableCameras$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as List?)! + .cast(); + } + } + + /// Creates a new camera with the given name and settings and returns its ID. + Future create( + String cameraName, PlatformMediaSettings mediaSettings) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.create$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([cameraName, mediaSettings]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as int?)!; + } + } + + /// Initializes the camera with the given ID for the given image format. + Future initialize(PlatformImageFormatGroup imageFormat) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.initialize$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([imageFormat]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Disposes of the camera with the given ID. + Future dispose() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.dispose$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Locks the camera with the given ID to the given orientation. + Future lockCaptureOrientation( + PlatformDeviceOrientation orientation) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.lockCaptureOrientation$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([orientation]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Unlocks the orientation for the camera with the given ID. + Future unlockCaptureOrientation() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.unlockCaptureOrientation$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Takes a picture on the camera with the given ID and returns a path to the + /// resulting file. + Future takePicture() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.takePicture$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as String?)!; + } + } + + /// Starts recording a video on the camera with the given ID. + Future startVideoRecording(bool enableStream) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.startVideoRecording$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([enableStream]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Ends video recording on the camera with the given ID and returns the path + /// to the resulting file. + Future stopVideoRecording() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.stopVideoRecording$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as String?)!; + } + } + + /// Pauses video recording on the camera with the given ID. + Future pauseVideoRecording() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.pauseVideoRecording$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Resumes previously paused video recording on the camera with the given ID. + Future resumeVideoRecording() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.resumeVideoRecording$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Begins streaming frames from the camera. + Future startImageStream() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.startImageStream$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Stops streaming frames from the camera. + Future stopImageStream() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.stopImageStream$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Sets the flash mode of the camera with the given ID. + Future setFlashMode(PlatformFlashMode flashMode) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.setFlashMode$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([flashMode]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Sets the exposure mode of the camera with the given ID. + Future setExposureMode(PlatformExposureMode exposureMode) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.setExposureMode$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([exposureMode]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Sets the exposure point of the camera with the given ID. + /// + /// A null value resets to the default exposure point. + Future setExposurePoint(PlatformPoint? point) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.setExposurePoint$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([point]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Returns the minimum exposure offset of the camera with the given ID. + Future getMinExposureOffset() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.getMinExposureOffset$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as double?)!; + } + } + + /// Returns the maximum exposure offset of the camera with the given ID. + Future getMaxExposureOffset() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.getMaxExposureOffset$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as double?)!; + } + } + + /// Returns the exposure step size of the camera with the given ID. + Future getExposureOffsetStepSize() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.getExposureOffsetStepSize$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as double?)!; + } + } + + /// Sets the exposure offset of the camera with the given ID and returns the + /// actual exposure offset. + Future setExposureOffset(double offset) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.setExposureOffset$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([offset]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as double?)!; + } + } + + /// Sets the focus mode of the camera with the given ID. + Future setFocusMode(PlatformFocusMode focusMode) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.setFocusMode$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([focusMode]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Sets the focus point of the camera with the given ID. + /// + /// A null value resets to the default focus point. + Future setFocusPoint(PlatformPoint? point) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.setFocusPoint$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([point]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Returns the maximum zoom level of the camera with the given ID. + Future getMaxZoomLevel() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.getMaxZoomLevel$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as double?)!; + } + } + + /// Returns the minimum zoom level of the camera with the given ID. + Future getMinZoomLevel() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.getMinZoomLevel$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as double?)!; + } + } + + /// Sets the zoom level of the camera with the given ID. + Future setZoomLevel(double zoom) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.setZoomLevel$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([zoom]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Pauses streaming of preview frames. + Future pausePreview() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.pausePreview$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Resumes previously paused streaming of preview frames. + Future resumePreview() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.resumePreview$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Changes the camera while recording video. + /// + /// This should be called only while video recording is active. + Future setDescriptionWhileRecording(String description) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_android.CameraApi.setDescriptionWhileRecording$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([description]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } +} + +/// Handles calls from native side to Dart that are not camera-specific. +abstract class CameraGlobalEventApi { + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + /// Called when the device's physical orientation changes. + void deviceOrientationChanged(PlatformDeviceOrientation orientation); + + static void setUp( + CameraGlobalEventApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.camera_android.CameraGlobalEventApi.deviceOrientationChanged$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.camera_android.CameraGlobalEventApi.deviceOrientationChanged was null.'); + final List args = (message as List?)!; + final PlatformDeviceOrientation? arg_orientation = + (args[0] as PlatformDeviceOrientation?); + assert(arg_orientation != null, + 'Argument for dev.flutter.pigeon.camera_android.CameraGlobalEventApi.deviceOrientationChanged was null, expected non-null PlatformDeviceOrientation.'); + try { + api.deviceOrientationChanged(arg_orientation!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } +} + +/// Handles device-specific calls from native side to Dart. +abstract class CameraEventApi { + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + /// Called when the camera is initialized. + void initialized(PlatformCameraState initialState); + + /// Called when an error occurs in the camera. + void error(String message); + + /// Called when the camera closes. + void closed(); + + static void setUp( + CameraEventApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.camera_android.CameraEventApi.initialized$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.camera_android.CameraEventApi.initialized was null.'); + final List args = (message as List?)!; + final PlatformCameraState? arg_initialState = + (args[0] as PlatformCameraState?); + assert(arg_initialState != null, + 'Argument for dev.flutter.pigeon.camera_android.CameraEventApi.initialized was null, expected non-null PlatformCameraState.'); + try { + api.initialized(arg_initialState!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.camera_android.CameraEventApi.error$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.camera_android.CameraEventApi.error was null.'); + final List args = (message as List?)!; + final String? arg_message = (args[0] as String?); + assert(arg_message != null, + 'Argument for dev.flutter.pigeon.camera_android.CameraEventApi.error was null, expected non-null String.'); + try { + api.error(arg_message!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.camera_android.CameraEventApi.closed$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + try { + api.closed(); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } +} diff --git a/packages/camera/camera_android/lib/src/utils.dart b/packages/camera/camera_android/lib/src/utils.dart index 8d58f7fe1297..1b3d2809e2c8 100644 --- a/packages/camera/camera_android/lib/src/utils.dart +++ b/packages/camera/camera_android/lib/src/utils.dart @@ -2,55 +2,160 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:math'; + import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:flutter/services.dart'; -/// Parses a string into a corresponding CameraLensDirection. -CameraLensDirection parseCameraLensDirection(String string) { - switch (string) { - case 'front': - return CameraLensDirection.front; - case 'back': - return CameraLensDirection.back; - case 'external': - return CameraLensDirection.external; - } - throw ArgumentError('Unknown CameraLensDirection value'); -} +import 'messages.g.dart'; + +/// Converts a [PlatformCameraLensDirection] to [CameraLensDirection]. +CameraLensDirection cameraLensDirectionFromPlatform( + PlatformCameraLensDirection direction) => + switch (direction) { + PlatformCameraLensDirection.front => CameraLensDirection.front, + PlatformCameraLensDirection.back => CameraLensDirection.back, + PlatformCameraLensDirection.external => CameraLensDirection.external, + }; -/// Returns the device orientation as a String. -String serializeDeviceOrientation(DeviceOrientation orientation) { +/// Converts a [PlatformDeviceOrientation] to [DeviceOrientation]. +DeviceOrientation deviceOrientationFromPlatform( + PlatformDeviceOrientation orientation) => + switch (orientation) { + PlatformDeviceOrientation.portraitUp => DeviceOrientation.portraitUp, + PlatformDeviceOrientation.portraitDown => DeviceOrientation.portraitDown, + PlatformDeviceOrientation.landscapeLeft => + DeviceOrientation.landscapeLeft, + PlatformDeviceOrientation.landscapeRight => + DeviceOrientation.landscapeRight, + }; + +/// Converts a [DeviceOrientation] to [PlatformDeviceOrientation]. +PlatformDeviceOrientation deviceOrientationToPlatform( + DeviceOrientation orientation) { switch (orientation) { case DeviceOrientation.portraitUp: - return 'portraitUp'; + return PlatformDeviceOrientation.portraitUp; case DeviceOrientation.portraitDown: - return 'portraitDown'; - case DeviceOrientation.landscapeRight: - return 'landscapeRight'; + return PlatformDeviceOrientation.portraitDown; case DeviceOrientation.landscapeLeft: - return 'landscapeLeft'; + return PlatformDeviceOrientation.landscapeLeft; + case DeviceOrientation.landscapeRight: + return PlatformDeviceOrientation.landscapeRight; } - // The enum comes from a different package, which could get a new value at - // any time, so provide a fallback that ensures this won't break when used - // with a version that contains new values. This is deliberately outside - // the switch rather than a `default` so that the linter will flag the - // switch as needing an update. + // This enum is defined outside of this package. This fall-through case + // ensures that the code does not break if a new value is ever added. // ignore: dead_code - return 'portraitUp'; + return PlatformDeviceOrientation.portraitUp; } -/// Returns the device orientation for a given String. -DeviceOrientation deserializeDeviceOrientation(String str) { - switch (str) { - case 'portraitUp': - return DeviceOrientation.portraitUp; - case 'portraitDown': - return DeviceOrientation.portraitDown; - case 'landscapeRight': - return DeviceOrientation.landscapeRight; - case 'landscapeLeft': - return DeviceOrientation.landscapeLeft; - default: - throw ArgumentError('"$str" is not a valid DeviceOrientation value'); +/// Converts a [PlatformExposureMode] to [ExposureMode]. +ExposureMode exposureModeFromPlatform(PlatformExposureMode exposureMode) => + switch (exposureMode) { + PlatformExposureMode.auto => ExposureMode.auto, + PlatformExposureMode.locked => ExposureMode.locked, + }; + +/// Converts a [ExposureMode] to [PlatformExposureMode]. +PlatformExposureMode exposureModeToPlatform(ExposureMode exposureMode) { + switch (exposureMode) { + case ExposureMode.auto: + return PlatformExposureMode.auto; + case ExposureMode.locked: + return PlatformExposureMode.locked; } + // This enum is defined outside of this package. This fall-through case + // ensures that the code does not break if a new value is ever added. + // ignore: dead_code + return PlatformExposureMode.auto; } + +/// Converts a [PlatformFocusMode] to [FocusMode]. +FocusMode focusModeFromPlatform(PlatformFocusMode focusMode) => + switch (focusMode) { + PlatformFocusMode.auto => FocusMode.auto, + PlatformFocusMode.locked => FocusMode.locked, + }; + +/// Converts a [FocusMode] to [PlatformFocusMode]. +PlatformFocusMode focusModeToPlatform(FocusMode focusMode) { + switch (focusMode) { + case FocusMode.auto: + return PlatformFocusMode.auto; + case FocusMode.locked: + return PlatformFocusMode.locked; + } + // This enum is defined outside of this package. This fall-through case + // ensures that the code does not break if a new value is ever added. + // ignore: dead_code + return PlatformFocusMode.auto; +} + +/// Converts a [ResolutionPreset] to [PlatformResolutionPreset]. +PlatformResolutionPreset resolutionPresetToPlatform(ResolutionPreset? preset) => + switch (preset) { + ResolutionPreset.low => PlatformResolutionPreset.low, + ResolutionPreset.medium => PlatformResolutionPreset.medium, + ResolutionPreset.high => PlatformResolutionPreset.high, + ResolutionPreset.veryHigh => PlatformResolutionPreset.veryHigh, + ResolutionPreset.ultraHigh => PlatformResolutionPreset.ultraHigh, + ResolutionPreset.max => PlatformResolutionPreset.max, + _ => PlatformResolutionPreset.high, + }; + +/// Converts a [MediaSettings] to [PlatformMediaSettings]. +PlatformMediaSettings mediaSettingsToPlatform(MediaSettings? settings) => + PlatformMediaSettings( + resolutionPreset: + resolutionPresetToPlatform(settings?.resolutionPreset), + enableAudio: settings?.enableAudio ?? false, + videoBitrate: settings?.videoBitrate, + audioBitrate: settings?.audioBitrate, + fps: settings?.fps); + +/// Converts an [ImageFormatGroup] to [PlatformImageFormatGroup]. +/// +/// [ImageFormatGroup.unknown] and [ImageFormatGroup.bgra8888] default to +/// [PlatformImageFormatGroup.yuv420], which is the default on Android. +PlatformImageFormatGroup imageFormatGroupToPlatform(ImageFormatGroup format) { + switch (format) { + case ImageFormatGroup.unknown: + return PlatformImageFormatGroup.yuv420; + case ImageFormatGroup.yuv420: + return PlatformImageFormatGroup.yuv420; + case ImageFormatGroup.bgra8888: + return PlatformImageFormatGroup.yuv420; + case ImageFormatGroup.jpeg: + return PlatformImageFormatGroup.jpeg; + case ImageFormatGroup.nv21: + return PlatformImageFormatGroup.nv21; + } + // This enum is defined outside of this package. This fall-through case + // ensures that the code does not break if a new value is ever added. + // ignore: dead_code + return PlatformImageFormatGroup.yuv420; +} + +/// Converts a [FlashMode] to [PlatformFlashMode]. +PlatformFlashMode flashModeToPlatform(FlashMode mode) { + switch (mode) { + case FlashMode.auto: + return PlatformFlashMode.auto; + case FlashMode.off: + return PlatformFlashMode.off; + case FlashMode.always: + return PlatformFlashMode.always; + case FlashMode.torch: + return PlatformFlashMode.torch; + } + // This enum is defined outside of this package. This fall-through case + // ensures that the code does not break if a new value is ever added. + // ignore: dead_code + return PlatformFlashMode.auto; +} + +/// Converts a [Point] to [PlatformPoint]. +/// +/// Null becomes null. +PlatformPoint? pointToPlatform(Point? point) => + (point != null) ? PlatformPoint(x: point.x, y: point.y) : null; diff --git a/packages/camera/camera_android/pigeons/copyright.txt b/packages/camera/camera_android/pigeons/copyright.txt new file mode 100644 index 000000000000..fb682b1ab965 --- /dev/null +++ b/packages/camera/camera_android/pigeons/copyright.txt @@ -0,0 +1,3 @@ +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. \ No newline at end of file diff --git a/packages/camera/camera_android/pigeons/messages.dart b/packages/camera/camera_android/pigeons/messages.dart new file mode 100644 index 000000000000..6031ac3d5a3d --- /dev/null +++ b/packages/camera/camera_android/pigeons/messages.dart @@ -0,0 +1,248 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +import 'package:pigeon/pigeon.dart'; + +@ConfigurePigeon(PigeonOptions( + dartOut: 'lib/src/messages.g.dart', + javaOptions: JavaOptions(package: 'io.flutter.plugins.camera'), + javaOut: 'android/src/main/java/io/flutter/plugins/camera/Messages.java', + copyrightHeader: 'pigeons/copyright.txt', +)) + +/// Pigeon equivalent of [CameraLensDirection]. +enum PlatformCameraLensDirection { + front, + back, + external, +} + +/// Pigeon equivalent of [CameraDescription]. +class PlatformCameraDescription { + PlatformCameraDescription( + {required this.name, + required this.lensDirection, + required this.sensorOrientation}); + + final String name; + final PlatformCameraLensDirection lensDirection; + final int sensorOrientation; +} + +/// Pigeon equivalent of [DeviceOrientation]. +enum PlatformDeviceOrientation { + portraitUp, + portraitDown, + landscapeLeft, + landscapeRight, +} + +/// Pigeon equivalent of [ExposureMode]. +enum PlatformExposureMode { + auto, + locked, +} + +/// Pigeon equivalent of [FocusMode]. +enum PlatformFocusMode { + auto, + locked, +} + +/// Data needed for [CameraInitializedEvent]. +class PlatformCameraState { + PlatformCameraState( + {required this.previewSize, + required this.exposureMode, + required this.focusMode, + required this.exposurePointSupported, + required this.focusPointSupported}); + + final PlatformSize previewSize; + final PlatformExposureMode exposureMode; + final PlatformFocusMode focusMode; + final bool exposurePointSupported; + final bool focusPointSupported; +} + +/// Pigeon equivalent of [Size]. +class PlatformSize { + PlatformSize({required this.width, required this.height}); + + final double width; + final double height; +} + +/// Pigeon equivalent of [Point]. +class PlatformPoint { + PlatformPoint({required this.x, required this.y}); + + final double x; + final double y; +} + +/// Pigeon equivalent of [ResolutionPreset]. +enum PlatformResolutionPreset { + low, + medium, + high, + veryHigh, + ultraHigh, + max, +} + +/// Pigeon equivalent of [MediaSettings]. +class PlatformMediaSettings { + PlatformMediaSettings( + {required this.resolutionPreset, + required this.enableAudio, + this.fps, + this.videoBitrate, + this.audioBitrate}); + final PlatformResolutionPreset resolutionPreset; + final int? fps; + final int? videoBitrate; + final int? audioBitrate; + final bool enableAudio; +} + +/// Pigeon equivalent of [ImageFormatGroup]. +enum PlatformImageFormatGroup { + /// The default for Android. + yuv420, + jpeg, + nv21, +} + +/// Pigeon equivalent of [FlashMode]. +enum PlatformFlashMode { + off, + auto, + always, + torch, +} + +/// Handles calls from Dart to the native side. +@HostApi() +abstract class CameraApi { + /// Returns the list of available cameras. + List getAvailableCameras(); + + /// Creates a new camera with the given name and settings and returns its ID. + @async + int create(String cameraName, PlatformMediaSettings mediaSettings); + + /// Initializes the camera with the given ID for the given image format. + void initialize(PlatformImageFormatGroup imageFormat); + + /// Disposes of the camera with the given ID. + void dispose(); + + /// Locks the camera with the given ID to the given orientation. + void lockCaptureOrientation(PlatformDeviceOrientation orientation); + + /// Unlocks the orientation for the camera with the given ID. + void unlockCaptureOrientation(); + + /// Takes a picture on the camera with the given ID and returns a path to the + /// resulting file. + @async + String takePicture(); + + /// Starts recording a video on the camera with the given ID. + void startVideoRecording(bool enableStream); + + /// Ends video recording on the camera with the given ID and returns the path + /// to the resulting file. + String stopVideoRecording(); + + /// Pauses video recording on the camera with the given ID. + void pauseVideoRecording(); + + /// Resumes previously paused video recording on the camera with the given ID. + void resumeVideoRecording(); + + /// Begins streaming frames from the camera. + void startImageStream(); + + /// Stops streaming frames from the camera. + void stopImageStream(); + + /// Sets the flash mode of the camera with the given ID. + @async + void setFlashMode(PlatformFlashMode flashMode); + + /// Sets the exposure mode of the camera with the given ID. + @async + void setExposureMode(PlatformExposureMode exposureMode); + + /// Sets the exposure point of the camera with the given ID. + /// + /// A null value resets to the default exposure point. + @async + void setExposurePoint(PlatformPoint? point); + + /// Returns the minimum exposure offset of the camera with the given ID. + double getMinExposureOffset(); + + /// Returns the maximum exposure offset of the camera with the given ID. + double getMaxExposureOffset(); + + /// Returns the exposure step size of the camera with the given ID. + double getExposureOffsetStepSize(); + + /// Sets the exposure offset of the camera with the given ID and returns the + /// actual exposure offset. + @async + double setExposureOffset(double offset); + + /// Sets the focus mode of the camera with the given ID. + void setFocusMode(PlatformFocusMode focusMode); + + /// Sets the focus point of the camera with the given ID. + /// + /// A null value resets to the default focus point. + @async + void setFocusPoint(PlatformPoint? point); + + /// Returns the maximum zoom level of the camera with the given ID. + double getMaxZoomLevel(); + + /// Returns the minimum zoom level of the camera with the given ID. + double getMinZoomLevel(); + + /// Sets the zoom level of the camera with the given ID. + @async + void setZoomLevel(double zoom); + + /// Pauses streaming of preview frames. + void pausePreview(); + + /// Resumes previously paused streaming of preview frames. + void resumePreview(); + + /// Changes the camera while recording video. + /// + /// This should be called only while video recording is active. + void setDescriptionWhileRecording(String description); +} + +/// Handles calls from native side to Dart that are not camera-specific. +@FlutterApi() +abstract class CameraGlobalEventApi { + /// Called when the device's physical orientation changes. + void deviceOrientationChanged(PlatformDeviceOrientation orientation); +} + +/// Handles device-specific calls from native side to Dart. +@FlutterApi() +abstract class CameraEventApi { + /// Called when the camera is initialized. + void initialized(PlatformCameraState initialState); + + /// Called when an error occurs in the camera. + void error(String message); + + /// Called when the camera closes. + void closed(); +} diff --git a/packages/camera/camera_android/pubspec.yaml b/packages/camera/camera_android/pubspec.yaml index 178c15de795b..6bc18c3c7c63 100644 --- a/packages/camera/camera_android/pubspec.yaml +++ b/packages/camera/camera_android/pubspec.yaml @@ -3,11 +3,11 @@ description: Android implementation of the camera plugin. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.10.9+6 +version: 0.10.9+16 environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" flutter: plugin: @@ -27,8 +27,11 @@ dependencies: dev_dependencies: async: ^2.5.0 + build_runner: ^2.4.11 flutter_test: sdk: flutter + mockito: ^5.4.4 + pigeon: ^22.4.1 topics: - camera diff --git a/packages/camera/camera_android/test/android_camera_test.dart b/packages/camera/camera_android/test/android_camera_test.dart index 87acd2c0c721..7c6d55c485b8 100644 --- a/packages/camera/camera_android/test/android_camera_test.dart +++ b/packages/camera/camera_android/test/android_camera_test.dart @@ -7,16 +7,18 @@ import 'dart:math'; import 'package:async/async.dart'; import 'package:camera_android/src/android_camera.dart'; +import 'package:camera_android/src/messages.g.dart'; import 'package:camera_android/src/utils.dart'; import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; -import 'method_channel_mock.dart'; - -const String _channelName = 'plugins.flutter.io/camera_android'; +import 'android_camera_test.mocks.dart'; +@GenerateNiceMocks(>[MockSpec()]) void main() { TestWidgetsFlutterBinding.ensureInitialized(); @@ -44,17 +46,19 @@ void main() { }); group('Creation, Initialization & Disposal Tests', () { + late MockCameraApi mockCameraApi; + setUp(() { + mockCameraApi = MockCameraApi(); + }); + test('Should send creation data and receive back a camera id', () async { // Arrange - final MethodChannelMock cameraMockChannel = MethodChannelMock( - channelName: _channelName, - methods: { - 'create': { - 'cameraId': 1, - 'imageFormatGroup': 'unknown', - } - }); - final AndroidCamera camera = AndroidCamera(); + final AndroidCamera camera = AndroidCamera(hostApi: mockCameraApi); + when(mockCameraApi.create( + 'Test', + argThat(predicate((PlatformMediaSettings settings) => + settings.resolutionPreset == PlatformResolutionPreset.high && + !settings.enableAudio)))).thenAnswer((_) async => 1); // Act final int cameraId = await camera.createCamera( @@ -66,19 +70,6 @@ void main() { ); // Assert - expect(cameraMockChannel.log, [ - isMethodCall( - 'create', - arguments: { - 'cameraName': 'Test', - 'resolutionPreset': 'high', - 'enableAudio': false, - 'fps': null, - 'videoBitrate': null, - 'audioBitrate': null, - }, - ), - ]); expect(cameraId, 1); }); @@ -86,15 +77,15 @@ void main() { 'Should send creation data and receive back a camera id using createCameraWithSettings', () async { // Arrange - final MethodChannelMock cameraMockChannel = MethodChannelMock( - channelName: _channelName, - methods: { - 'create': { - 'cameraId': 1, - 'imageFormatGroup': 'unknown', - } - }); - final AndroidCamera camera = AndroidCamera(); + final AndroidCamera camera = AndroidCamera(hostApi: mockCameraApi); + when(mockCameraApi.create( + 'Test', + argThat(predicate((PlatformMediaSettings settings) => + settings.resolutionPreset == PlatformResolutionPreset.low && + !settings.enableAudio && + settings.fps == 15 && + settings.videoBitrate == 200000 && + settings.audioBitrate == 32000)))).thenAnswer((_) async => 1); // Act final int cameraId = await camera.createCameraWithSettings( @@ -111,63 +102,19 @@ void main() { ); // Assert - expect(cameraMockChannel.log, [ - isMethodCall( - 'create', - arguments: { - 'cameraName': 'Test', - 'resolutionPreset': 'low', - 'fps': 15, - 'videoBitrate': 200000, - 'audioBitrate': 32000, - 'enableAudio': false - }, - ), - ]); expect(cameraId, 1); }); test('Should throw CameraException when create throws a PlatformException', () { // Arrange - MethodChannelMock(channelName: _channelName, methods: { - 'create': PlatformException( - code: 'TESTING_ERROR_CODE', - message: 'Mock error message used during testing.', - ) - }); - final AndroidCamera camera = AndroidCamera(); - - // Act - expect( - () => camera.createCamera( - const CameraDescription( - name: 'Test', - lensDirection: CameraLensDirection.back, - sensorOrientation: 0, - ), - ResolutionPreset.high, - ), - throwsA( - isA() - .having( - (CameraException e) => e.code, 'code', 'TESTING_ERROR_CODE') - .having((CameraException e) => e.description, 'description', - 'Mock error message used during testing.'), - ), - ); - }); - - test('Should throw CameraException when create throws a PlatformException', - () { - // Arrange - MethodChannelMock(channelName: _channelName, methods: { - 'create': PlatformException( - code: 'TESTING_ERROR_CODE', - message: 'Mock error message used during testing.', - ) - }); - final AndroidCamera camera = AndroidCamera(); + final AndroidCamera camera = AndroidCamera(hostApi: mockCameraApi); + when(mockCameraApi.create( + 'Test', + argThat(predicate((PlatformMediaSettings settings) => + settings.resolutionPreset == PlatformResolutionPreset.high && + !settings.enableAudio)))).thenThrow(CameraException( + 'TESTING_ERROR_CODE', 'Mock error message used during testing.')); // Act expect( @@ -193,16 +140,10 @@ void main() { 'Should throw CameraException when initialize throws a PlatformException', () { // Arrange - MethodChannelMock( - channelName: _channelName, - methods: { - 'initialize': PlatformException( - code: 'TESTING_ERROR_CODE', - message: 'Mock error message used during testing.', - ) - }, - ); - final AndroidCamera camera = AndroidCamera(); + final AndroidCamera camera = AndroidCamera(hostApi: mockCameraApi); + when(mockCameraApi.initialize(PlatformImageFormatGroup.yuv420)) + .thenThrow(CameraException('TESTING_ERROR_CODE', + 'Mock error message used during testing.')); // Act expect( @@ -223,16 +164,13 @@ void main() { test('Should send initialization data', () async { // Arrange - final MethodChannelMock cameraMockChannel = MethodChannelMock( - channelName: _channelName, - methods: { - 'create': { - 'cameraId': 1, - 'imageFormatGroup': 'unknown', - }, - 'initialize': null - }); - final AndroidCamera camera = AndroidCamera(); + final AndroidCamera camera = AndroidCamera(hostApi: mockCameraApi); + when(mockCameraApi.create( + 'Test', + argThat(predicate((PlatformMediaSettings settings) => + settings.resolutionPreset == PlatformResolutionPreset.high && + !settings.enableAudio)))).thenAnswer((_) async => 1); + final int cameraId = await camera.createCamera( const CameraDescription( name: 'Test', @@ -257,29 +195,18 @@ void main() { // Assert expect(cameraId, 1); - expect(cameraMockChannel.log, [ - anything, - isMethodCall( - 'initialize', - arguments: { - 'cameraId': 1, - 'imageFormatGroup': 'unknown', - }, - ), - ]); + verify(mockCameraApi.initialize(PlatformImageFormatGroup.yuv420)) + .called(1); }); test('Should send a disposal call on dispose', () async { // Arrange - final MethodChannelMock cameraMockChannel = MethodChannelMock( - channelName: _channelName, - methods: { - 'create': {'cameraId': 1}, - 'initialize': null, - 'dispose': {'cameraId': 1} - }); - - final AndroidCamera camera = AndroidCamera(); + final AndroidCamera camera = AndroidCamera(hostApi: mockCameraApi); + when(mockCameraApi.create( + 'Test', + argThat(predicate((PlatformMediaSettings settings) => + settings.resolutionPreset == PlatformResolutionPreset.high && + !settings.enableAudio)))).thenAnswer((_) async => 1); final int cameraId = await camera.createCamera( const CameraDescription( name: 'Test', @@ -305,29 +232,17 @@ void main() { // Assert expect(cameraId, 1); - expect(cameraMockChannel.log, [ - anything, - anything, - isMethodCall( - 'dispose', - arguments: {'cameraId': 1}, - ), - ]); + verify(mockCameraApi.dispose()).called(1); }); }); group('Event Tests', () { late AndroidCamera camera; late int cameraId; + late MockCameraApi mockCameraApi; setUp(() async { - MethodChannelMock( - channelName: _channelName, - methods: { - 'create': {'cameraId': 1}, - 'initialize': null - }, - ); - camera = AndroidCamera(); + mockCameraApi = MockCameraApi(); + camera = AndroidCamera(hostApi: mockCameraApi); cameraId = await camera.createCamera( const CameraDescription( name: 'Test', @@ -357,17 +272,22 @@ void main() { StreamQueue(eventStream); // Emit test events + final PlatformSize previewSize = PlatformSize(width: 3840, height: 2160); final CameraInitializedEvent event = CameraInitializedEvent( cameraId, - 3840, - 2160, + previewSize.width, + previewSize.height, ExposureMode.auto, true, FocusMode.auto, true, ); - await camera.handleCameraMethodCall( - MethodCall('initialized', event.toJson()), cameraId); + camera.hostCameraHandlers[cameraId]!.initialized(PlatformCameraState( + previewSize: previewSize, + exposureMode: PlatformExposureMode.auto, + focusMode: PlatformFocusMode.auto, + exposurePointSupported: true, + focusPointSupported: true)); // Assert expect(await streamQueue.next, event); @@ -376,37 +296,6 @@ void main() { await streamQueue.cancel(); }); - test('Should receive resolution changes', () async { - // Act - final Stream resolutionStream = - camera.onCameraResolutionChanged(cameraId); - final StreamQueue streamQueue = - StreamQueue(resolutionStream); - - // Emit test events - final CameraResolutionChangedEvent fhdEvent = - CameraResolutionChangedEvent(cameraId, 1920, 1080); - final CameraResolutionChangedEvent uhdEvent = - CameraResolutionChangedEvent(cameraId, 3840, 2160); - await camera.handleCameraMethodCall( - MethodCall('resolution_changed', fhdEvent.toJson()), cameraId); - await camera.handleCameraMethodCall( - MethodCall('resolution_changed', uhdEvent.toJson()), cameraId); - await camera.handleCameraMethodCall( - MethodCall('resolution_changed', fhdEvent.toJson()), cameraId); - await camera.handleCameraMethodCall( - MethodCall('resolution_changed', uhdEvent.toJson()), cameraId); - - // Assert - expect(await streamQueue.next, fhdEvent); - expect(await streamQueue.next, uhdEvent); - expect(await streamQueue.next, fhdEvent); - expect(await streamQueue.next, uhdEvent); - - // Clean up - await streamQueue.cancel(); - }); - test('Should receive camera closing events', () async { // Act final Stream eventStream = @@ -416,12 +305,9 @@ void main() { // Emit test events final CameraClosingEvent event = CameraClosingEvent(cameraId); - await camera.handleCameraMethodCall( - MethodCall('camera_closing', event.toJson()), cameraId); - await camera.handleCameraMethodCall( - MethodCall('camera_closing', event.toJson()), cameraId); - await camera.handleCameraMethodCall( - MethodCall('camera_closing', event.toJson()), cameraId); + for (int i = 0; i < 3; i++) { + camera.hostCameraHandlers[cameraId]!.closed(); + } // Assert expect(await streamQueue.next, event); @@ -442,12 +328,9 @@ void main() { // Emit test events final CameraErrorEvent event = CameraErrorEvent(cameraId, 'Error Description'); - await camera.handleCameraMethodCall( - MethodCall('error', event.toJson()), cameraId); - await camera.handleCameraMethodCall( - MethodCall('error', event.toJson()), cameraId); - await camera.handleCameraMethodCall( - MethodCall('error', event.toJson()), cameraId); + for (int i = 0; i < 3; i++) { + camera.hostCameraHandlers[cameraId]!.error('Error Description'); + } // Assert expect(await streamQueue.next, event); @@ -469,12 +352,8 @@ void main() { const DeviceOrientationChangedEvent event = DeviceOrientationChangedEvent(DeviceOrientation.portraitUp); for (int i = 0; i < 3; i++) { - await TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .handlePlatformMessage( - AndroidCamera.deviceEventChannelName, - const StandardMethodCodec().encodeMethodCall( - MethodCall('orientation_changed', event.toJson())), - null); + camera.hostHandler + .deviceOrientationChanged(PlatformDeviceOrientation.portraitUp); } // Assert @@ -490,16 +369,11 @@ void main() { group('Function Tests', () { late AndroidCamera camera; late int cameraId; + late MockCameraApi mockCameraApi; setUp(() async { - MethodChannelMock( - channelName: _channelName, - methods: { - 'create': {'cameraId': 1}, - 'initialize': null - }, - ); - camera = AndroidCamera(); + mockCameraApi = MockCameraApi(); + camera = AndroidCamera(hostApi: mockCameraApi); cameraId = await camera.createCamera( const CameraDescription( name: 'Test', @@ -526,40 +400,33 @@ void main() { test('Should fetch CameraDescription instances for available cameras', () async { // Arrange - final List returnData = [ - { - 'name': 'Test 1', - 'lensFacing': 'front', - 'sensorOrientation': 1 - }, - { - 'name': 'Test 2', - 'lensFacing': 'back', - 'sensorOrientation': 2 - } + final List returnData = + [ + PlatformCameraDescription( + name: 'Test 1', + lensDirection: PlatformCameraLensDirection.front, + sensorOrientation: 1), + PlatformCameraDescription( + name: 'Test 2', + lensDirection: PlatformCameraLensDirection.back, + sensorOrientation: 2), ]; - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'availableCameras': returnData}, - ); + when(mockCameraApi.getAvailableCameras()) + .thenAnswer((_) async => returnData); // Act final List cameras = await camera.availableCameras(); // Assert - expect(channel.log, [ - isMethodCall('availableCameras', arguments: null), - ]); expect(cameras.length, returnData.length); for (int i = 0; i < returnData.length; i++) { - final Map typedData = - (returnData[i] as Map).cast(); + final PlatformCameraDescription platformCameraDescription = + returnData[i]; final CameraDescription cameraDescription = CameraDescription( - name: typedData['name']! as String, - lensDirection: - parseCameraLensDirection(typedData['lensFacing']! as String), - sensorOrientation: typedData['sensorOrientation']! as int, - ); + name: platformCameraDescription.name, + lensDirection: cameraLensDirectionFromPlatform( + platformCameraDescription.lensDirection), + sensorOrientation: platformCameraDescription.sensorOrientation); expect(cameras[i], cameraDescription); } }); @@ -568,12 +435,9 @@ void main() { 'Should throw CameraException when availableCameras throws a PlatformException', () { // Arrange - MethodChannelMock(channelName: _channelName, methods: { - 'availableCameras': PlatformException( + when(mockCameraApi.getAvailableCameras()).thenThrow(PlatformException( code: 'TESTING_ERROR_CODE', - message: 'Mock error message used during testing.', - ) - }); + message: 'Mock error message used during testing.')); // Act expect( @@ -590,91 +454,29 @@ void main() { test('Should take a picture and return an XFile instance', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'takePicture': '/test/path.jpg'}); + when(mockCameraApi.takePicture()) + .thenAnswer((_) async => '/test/path.jpg'); // Act final XFile file = await camera.takePicture(cameraId); // Assert - expect(channel.log, [ - isMethodCall('takePicture', arguments: { - 'cameraId': cameraId, - }), - ]); expect(file.path, '/test/path.jpg'); }); - test('Should prepare for video recording', () async { - // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'prepareForVideoRecording': null}, - ); - - // Act - await camera.prepareForVideoRecording(); - - // Assert - expect(channel.log, [ - isMethodCall('prepareForVideoRecording', arguments: null), - ]); - }); - test('Should start recording a video', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'startVideoRecording': null}, - ); - // Act await camera.startVideoRecording(cameraId); // Assert - expect(channel.log, [ - isMethodCall('startVideoRecording', arguments: { - 'cameraId': cameraId, - 'maxVideoDuration': null, - 'enableStream': false, - }), - ]); - }); - - test('Should pass maxVideoDuration when starting recording a video', - () async { - // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'startVideoRecording': null}, - ); - - // Act - await camera.startVideoRecording( - cameraId, - maxVideoDuration: const Duration(seconds: 10), - ); - - // Assert - expect(channel.log, [ - isMethodCall('startVideoRecording', arguments: { - 'cameraId': cameraId, - 'maxVideoDuration': 10000, - 'enableStream': false, - }), - ]); + verify(mockCameraApi.startVideoRecording(false)).called(1); }); test( 'Should pass enableStream if callback is passed when starting recording a video', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'startVideoRecording': null}, - ); - // Act await camera.startVideoCapturing( VideoCaptureOptions(cameraId, @@ -682,76 +484,41 @@ void main() { ); // Assert - expect(channel.log, [ - isMethodCall('startVideoRecording', arguments: { - 'cameraId': cameraId, - 'maxVideoDuration': null, - 'enableStream': true, - }), - ]); + verify(mockCameraApi.startVideoRecording(true)).called(1); }); test('Should stop a video recording and return the file', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'stopVideoRecording': '/test/path.mp4'}, - ); + when(mockCameraApi.stopVideoRecording()) + .thenAnswer((_) async => '/test/path.mp4'); // Act final XFile file = await camera.stopVideoRecording(cameraId); // Assert - expect(channel.log, [ - isMethodCall('stopVideoRecording', arguments: { - 'cameraId': cameraId, - }), - ]); expect(file.path, '/test/path.mp4'); }); test('Should pause a video recording', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'pauseVideoRecording': null}, - ); - // Act await camera.pauseVideoRecording(cameraId); // Assert - expect(channel.log, [ - isMethodCall('pauseVideoRecording', arguments: { - 'cameraId': cameraId, - }), - ]); + verify(mockCameraApi.pauseVideoRecording()).called(1); }); test('Should resume a video recording', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'resumeVideoRecording': null}, - ); - // Act await camera.resumeVideoRecording(cameraId); // Assert - expect(channel.log, [ - isMethodCall('resumeVideoRecording', arguments: { - 'cameraId': cameraId, - }), - ]); + verify(mockCameraApi.resumeVideoRecording()).called(1); }); test('Should set the description while recording', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'setDescriptionWhileRecording': null}, - ); const CameraDescription camera2Description = CameraDescription( name: 'Test2', lensDirection: CameraLensDirection.front, @@ -761,21 +528,13 @@ void main() { await camera.setDescriptionWhileRecording(camera2Description); // Assert - expect(channel.log, [ - isMethodCall('setDescriptionWhileRecording', - arguments: { - 'cameraName': camera2Description.name, - }), - ]); + verify(mockCameraApi + .setDescriptionWhileRecording(camera2Description.name)) + .called(1); }); test('Should set the flash mode', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'setFlashMode': null}, - ); - // Act await camera.setFlashMode(cameraId, FlashMode.torch); await camera.setFlashMode(cameraId, FlashMode.always); @@ -783,78 +542,41 @@ void main() { await camera.setFlashMode(cameraId, FlashMode.off); // Assert - expect(channel.log, [ - isMethodCall('setFlashMode', arguments: { - 'cameraId': cameraId, - 'mode': 'torch' - }), - isMethodCall('setFlashMode', arguments: { - 'cameraId': cameraId, - 'mode': 'always' - }), - isMethodCall('setFlashMode', - arguments: {'cameraId': cameraId, 'mode': 'auto'}), - isMethodCall('setFlashMode', - arguments: {'cameraId': cameraId, 'mode': 'off'}), - ]); + verify(mockCameraApi.setFlashMode(PlatformFlashMode.torch)).called(1); + verify(mockCameraApi.setFlashMode(PlatformFlashMode.always)).called(1); + verify(mockCameraApi.setFlashMode(PlatformFlashMode.auto)).called(1); + verify(mockCameraApi.setFlashMode(PlatformFlashMode.off)).called(1); }); test('Should set the exposure mode', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'setExposureMode': null}, - ); - // Act await camera.setExposureMode(cameraId, ExposureMode.auto); await camera.setExposureMode(cameraId, ExposureMode.locked); // Assert - expect(channel.log, [ - isMethodCall('setExposureMode', - arguments: {'cameraId': cameraId, 'mode': 'auto'}), - isMethodCall('setExposureMode', arguments: { - 'cameraId': cameraId, - 'mode': 'locked' - }), - ]); + verify(mockCameraApi.setExposureMode(PlatformExposureMode.auto)) + .called(1); + verify(mockCameraApi.setExposureMode(PlatformExposureMode.locked)) + .called(1); }); test('Should set the exposure point', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'setExposurePoint': null}, - ); - // Act - await camera.setExposurePoint(cameraId, const Point(0.5, 0.5)); + await camera.setExposurePoint(cameraId, const Point(0.4, 0.5)); await camera.setExposurePoint(cameraId, null); // Assert - expect(channel.log, [ - isMethodCall('setExposurePoint', arguments: { - 'cameraId': cameraId, - 'x': 0.5, - 'y': 0.5, - 'reset': false - }), - isMethodCall('setExposurePoint', arguments: { - 'cameraId': cameraId, - 'x': null, - 'y': null, - 'reset': true - }), - ]); + verify(mockCameraApi.setExposurePoint(argThat(predicate( + (PlatformPoint point) => point.x == 0.4 && point.y == 0.5)))) + .called(1); + verify(mockCameraApi.setExposurePoint(null)).called(1); }); test('Should get the min exposure offset', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'getMinExposureOffset': 2.0}, - ); + when(mockCameraApi.getMinExposureOffset()).thenAnswer((_) async => 2.0); // Act final double minExposureOffset = @@ -862,19 +584,11 @@ void main() { // Assert expect(minExposureOffset, 2.0); - expect(channel.log, [ - isMethodCall('getMinExposureOffset', arguments: { - 'cameraId': cameraId, - }), - ]); }); test('Should get the max exposure offset', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'getMaxExposureOffset': 2.0}, - ); + when(mockCameraApi.getMaxExposureOffset()).thenAnswer((_) async => 2.0); // Act final double maxExposureOffset = @@ -882,100 +596,40 @@ void main() { // Assert expect(maxExposureOffset, 2.0); - expect(channel.log, [ - isMethodCall('getMaxExposureOffset', arguments: { - 'cameraId': cameraId, - }), - ]); }); test('Should get the exposure offset step size', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'getExposureOffsetStepSize': 0.25}, - ); + when(mockCameraApi.getExposureOffsetStepSize()) + .thenAnswer((_) async => 0.25); // Act final double stepSize = await camera.getExposureOffsetStepSize(cameraId); // Assert expect(stepSize, 0.25); - expect(channel.log, [ - isMethodCall('getExposureOffsetStepSize', arguments: { - 'cameraId': cameraId, - }), - ]); }); test('Should set the exposure offset', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'setExposureOffset': 0.6}, - ); + when(mockCameraApi.setExposureOffset(0.5)).thenAnswer((_) async => 0.6); // Act final double actualOffset = await camera.setExposureOffset(cameraId, 0.5); // Assert expect(actualOffset, 0.6); - expect(channel.log, [ - isMethodCall('setExposureOffset', arguments: { - 'cameraId': cameraId, - 'offset': 0.5, - }), - ]); }); test('Should set the focus mode', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'setFocusMode': null}, - ); - // Act await camera.setFocusMode(cameraId, FocusMode.auto); await camera.setFocusMode(cameraId, FocusMode.locked); // Assert - expect(channel.log, [ - isMethodCall('setFocusMode', - arguments: {'cameraId': cameraId, 'mode': 'auto'}), - isMethodCall('setFocusMode', arguments: { - 'cameraId': cameraId, - 'mode': 'locked' - }), - ]); - }); - - test('Should set the exposure point', () async { - // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'setFocusPoint': null}, - ); - - // Act - await camera.setFocusPoint(cameraId, const Point(0.5, 0.5)); - await camera.setFocusPoint(cameraId, null); - - // Assert - expect(channel.log, [ - isMethodCall('setFocusPoint', arguments: { - 'cameraId': cameraId, - 'x': 0.5, - 'y': 0.5, - 'reset': false - }), - isMethodCall('setFocusPoint', arguments: { - 'cameraId': cameraId, - 'x': null, - 'y': null, - 'reset': true - }), - ]); + verify(mockCameraApi.setFocusMode(PlatformFocusMode.auto)).called(1); + verify(mockCameraApi.setFocusMode(PlatformFocusMode.locked)).called(1); }); test('Should build a texture widget as preview widget', () async { @@ -987,83 +641,42 @@ void main() { expect((widget as Texture).textureId, cameraId); }); - test('Should throw MissingPluginException when handling unknown method', - () { - final AndroidCamera camera = AndroidCamera(); - - expect( - () => camera.handleCameraMethodCall( - const MethodCall('unknown_method'), 1), - throwsA(isA())); - }); - test('Should get the max zoom level', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'getMaxZoomLevel': 10.0}, - ); + when(mockCameraApi.getMaxZoomLevel()).thenAnswer((_) async => 10.0); // Act final double maxZoomLevel = await camera.getMaxZoomLevel(cameraId); // Assert expect(maxZoomLevel, 10.0); - expect(channel.log, [ - isMethodCall('getMaxZoomLevel', arguments: { - 'cameraId': cameraId, - }), - ]); }); test('Should get the min zoom level', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'getMinZoomLevel': 1.0}, - ); + when(mockCameraApi.getMinZoomLevel()).thenAnswer((_) async => 1.0); // Act final double maxZoomLevel = await camera.getMinZoomLevel(cameraId); // Assert expect(maxZoomLevel, 1.0); - expect(channel.log, [ - isMethodCall('getMinZoomLevel', arguments: { - 'cameraId': cameraId, - }), - ]); }); test('Should set the zoom level', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'setZoomLevel': null}, - ); - // Act await camera.setZoomLevel(cameraId, 2.0); // Assert - expect(channel.log, [ - isMethodCall('setZoomLevel', - arguments: {'cameraId': cameraId, 'zoom': 2.0}), - ]); + verify(mockCameraApi.setZoomLevel(2.0)).called(1); }); test('Should throw CameraException when illegal zoom level is supplied', () async { // Arrange - MethodChannelMock( - channelName: _channelName, - methods: { - 'setZoomLevel': PlatformException( - code: 'ZOOM_ERROR', - message: 'Illegal zoom error', - ) - }, - ); + when(mockCameraApi.setZoomLevel(-1.0)).thenThrow( + PlatformException(code: 'ZOOM_ERROR', message: 'Illegal zoom error')); // Act & assert expect( @@ -1076,108 +689,58 @@ void main() { test('Should lock the capture orientation', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'lockCaptureOrientation': null}, - ); - // Act await camera.lockCaptureOrientation( cameraId, DeviceOrientation.portraitUp); // Assert - expect(channel.log, [ - isMethodCall('lockCaptureOrientation', arguments: { - 'cameraId': cameraId, - 'orientation': 'portraitUp' - }), - ]); + verify(mockCameraApi + .lockCaptureOrientation(PlatformDeviceOrientation.portraitUp)) + .called(1); }); test('Should unlock the capture orientation', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'unlockCaptureOrientation': null}, - ); - // Act await camera.unlockCaptureOrientation(cameraId); // Assert - expect(channel.log, [ - isMethodCall('unlockCaptureOrientation', - arguments: {'cameraId': cameraId}), - ]); + verify(mockCameraApi.unlockCaptureOrientation()).called(1); }); test('Should pause the camera preview', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'pausePreview': null}, - ); - // Act await camera.pausePreview(cameraId); // Assert - expect(channel.log, [ - isMethodCall('pausePreview', - arguments: {'cameraId': cameraId}), - ]); + verify(mockCameraApi.pausePreview()).called(1); }); test('Should resume the camera preview', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'resumePreview': null}, - ); - // Act await camera.resumePreview(cameraId); // Assert - expect(channel.log, [ - isMethodCall('resumePreview', - arguments: {'cameraId': cameraId}), - ]); + verify(mockCameraApi.resumePreview()).called(1); }); test('Should start streaming', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: { - 'startImageStream': null, - 'stopImageStream': null, - }, - ); - // Act final StreamSubscription subscription = camera .onStreamedFrameAvailable(cameraId) .listen((CameraImageData imageData) {}); // Assert - expect(channel.log, [ - isMethodCall('startImageStream', arguments: null), - ]); + verify(mockCameraApi.startImageStream()).called(1); await subscription.cancel(); }); test('Should stop streaming', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: { - 'startImageStream': null, - 'stopImageStream': null, - }, - ); - // Act final StreamSubscription subscription = camera .onStreamedFrameAvailable(cameraId) @@ -1185,10 +748,8 @@ void main() { await subscription.cancel(); // Assert - expect(channel.log, [ - isMethodCall('startImageStream', arguments: null), - isMethodCall('stopImageStream', arguments: null), - ]); + verify(mockCameraApi.startImageStream()).called(1); + verify(mockCameraApi.stopImageStream()).called(1); }); }); } diff --git a/packages/camera/camera_android/test/android_camera_test.mocks.dart b/packages/camera/camera_android/test/android_camera_test.mocks.dart new file mode 100644 index 000000000000..6be1c98ad573 --- /dev/null +++ b/packages/camera/camera_android/test/android_camera_test.mocks.dart @@ -0,0 +1,368 @@ +// Mocks generated by Mockito 5.4.4 from annotations +// in camera_android/test/android_camera_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i4; + +import 'package:camera_android/src/messages.g.dart' as _i2; +import 'package:mockito/mockito.dart' as _i1; +import 'package:mockito/src/dummies.dart' as _i3; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +/// A class which mocks [CameraApi]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockCameraApi extends _i1.Mock implements _i2.CameraApi { + @override + String get pigeonVar_messageChannelSuffix => (super.noSuchMethod( + Invocation.getter(#pigeonVar_messageChannelSuffix), + returnValue: _i3.dummyValue( + this, + Invocation.getter(#pigeonVar_messageChannelSuffix), + ), + returnValueForMissingStub: _i3.dummyValue( + this, + Invocation.getter(#pigeonVar_messageChannelSuffix), + ), + ) as String); + + @override + _i4.Future> getAvailableCameras() => + (super.noSuchMethod( + Invocation.method( + #getAvailableCameras, + [], + ), + returnValue: _i4.Future>.value( + <_i2.PlatformCameraDescription>[]), + returnValueForMissingStub: + _i4.Future>.value( + <_i2.PlatformCameraDescription>[]), + ) as _i4.Future>); + + @override + _i4.Future create( + String? cameraName, + _i2.PlatformMediaSettings? mediaSettings, + ) => + (super.noSuchMethod( + Invocation.method( + #create, + [ + cameraName, + mediaSettings, + ], + ), + returnValue: _i4.Future.value(0), + returnValueForMissingStub: _i4.Future.value(0), + ) as _i4.Future); + + @override + _i4.Future initialize(_i2.PlatformImageFormatGroup? imageFormat) => + (super.noSuchMethod( + Invocation.method( + #initialize, + [imageFormat], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future dispose() => (super.noSuchMethod( + Invocation.method( + #dispose, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future lockCaptureOrientation( + _i2.PlatformDeviceOrientation? orientation) => + (super.noSuchMethod( + Invocation.method( + #lockCaptureOrientation, + [orientation], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future unlockCaptureOrientation() => (super.noSuchMethod( + Invocation.method( + #unlockCaptureOrientation, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future takePicture() => (super.noSuchMethod( + Invocation.method( + #takePicture, + [], + ), + returnValue: _i4.Future.value(_i3.dummyValue( + this, + Invocation.method( + #takePicture, + [], + ), + )), + returnValueForMissingStub: + _i4.Future.value(_i3.dummyValue( + this, + Invocation.method( + #takePicture, + [], + ), + )), + ) as _i4.Future); + + @override + _i4.Future startVideoRecording(bool? enableStream) => + (super.noSuchMethod( + Invocation.method( + #startVideoRecording, + [enableStream], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future stopVideoRecording() => (super.noSuchMethod( + Invocation.method( + #stopVideoRecording, + [], + ), + returnValue: _i4.Future.value(_i3.dummyValue( + this, + Invocation.method( + #stopVideoRecording, + [], + ), + )), + returnValueForMissingStub: + _i4.Future.value(_i3.dummyValue( + this, + Invocation.method( + #stopVideoRecording, + [], + ), + )), + ) as _i4.Future); + + @override + _i4.Future pauseVideoRecording() => (super.noSuchMethod( + Invocation.method( + #pauseVideoRecording, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future resumeVideoRecording() => (super.noSuchMethod( + Invocation.method( + #resumeVideoRecording, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future startImageStream() => (super.noSuchMethod( + Invocation.method( + #startImageStream, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future stopImageStream() => (super.noSuchMethod( + Invocation.method( + #stopImageStream, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setFlashMode(_i2.PlatformFlashMode? flashMode) => + (super.noSuchMethod( + Invocation.method( + #setFlashMode, + [flashMode], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setExposureMode(_i2.PlatformExposureMode? exposureMode) => + (super.noSuchMethod( + Invocation.method( + #setExposureMode, + [exposureMode], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setExposurePoint(_i2.PlatformPoint? point) => + (super.noSuchMethod( + Invocation.method( + #setExposurePoint, + [point], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future getMinExposureOffset() => (super.noSuchMethod( + Invocation.method( + #getMinExposureOffset, + [], + ), + returnValue: _i4.Future.value(0.0), + returnValueForMissingStub: _i4.Future.value(0.0), + ) as _i4.Future); + + @override + _i4.Future getMaxExposureOffset() => (super.noSuchMethod( + Invocation.method( + #getMaxExposureOffset, + [], + ), + returnValue: _i4.Future.value(0.0), + returnValueForMissingStub: _i4.Future.value(0.0), + ) as _i4.Future); + + @override + _i4.Future getExposureOffsetStepSize() => (super.noSuchMethod( + Invocation.method( + #getExposureOffsetStepSize, + [], + ), + returnValue: _i4.Future.value(0.0), + returnValueForMissingStub: _i4.Future.value(0.0), + ) as _i4.Future); + + @override + _i4.Future setExposureOffset(double? offset) => (super.noSuchMethod( + Invocation.method( + #setExposureOffset, + [offset], + ), + returnValue: _i4.Future.value(0.0), + returnValueForMissingStub: _i4.Future.value(0.0), + ) as _i4.Future); + + @override + _i4.Future setFocusMode(_i2.PlatformFocusMode? focusMode) => + (super.noSuchMethod( + Invocation.method( + #setFocusMode, + [focusMode], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setFocusPoint(_i2.PlatformPoint? point) => + (super.noSuchMethod( + Invocation.method( + #setFocusPoint, + [point], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future getMaxZoomLevel() => (super.noSuchMethod( + Invocation.method( + #getMaxZoomLevel, + [], + ), + returnValue: _i4.Future.value(0.0), + returnValueForMissingStub: _i4.Future.value(0.0), + ) as _i4.Future); + + @override + _i4.Future getMinZoomLevel() => (super.noSuchMethod( + Invocation.method( + #getMinZoomLevel, + [], + ), + returnValue: _i4.Future.value(0.0), + returnValueForMissingStub: _i4.Future.value(0.0), + ) as _i4.Future); + + @override + _i4.Future setZoomLevel(double? zoom) => (super.noSuchMethod( + Invocation.method( + #setZoomLevel, + [zoom], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future pausePreview() => (super.noSuchMethod( + Invocation.method( + #pausePreview, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future resumePreview() => (super.noSuchMethod( + Invocation.method( + #resumePreview, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setDescriptionWhileRecording(String? description) => + (super.noSuchMethod( + Invocation.method( + #setDescriptionWhileRecording, + [description], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); +} diff --git a/packages/camera/camera_android/test/utils_test.dart b/packages/camera/camera_android/test/utils_test.dart index 6f426bc90f6f..ebcac58d2c69 100644 --- a/packages/camera/camera_android/test/utils_test.dart +++ b/packages/camera/camera_android/test/utils_test.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:camera_android/src/messages.g.dart'; import 'package:camera_android/src/utils.dart'; import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:flutter/services.dart'; @@ -13,48 +14,46 @@ void main() { 'Should return CameraLensDirection when valid value is supplied when parsing camera lens direction', () { expect( - parseCameraLensDirection('back'), + cameraLensDirectionFromPlatform(PlatformCameraLensDirection.back), CameraLensDirection.back, ); expect( - parseCameraLensDirection('front'), + cameraLensDirectionFromPlatform(PlatformCameraLensDirection.front), CameraLensDirection.front, ); expect( - parseCameraLensDirection('external'), + cameraLensDirectionFromPlatform(PlatformCameraLensDirection.external), CameraLensDirection.external, ); }); - test( - 'Should throw ArgumentException when invalid value is supplied when parsing camera lens direction', - () { + test('deviceOrientationFromPlatform() should convert correctly', () { expect( - () => parseCameraLensDirection('test'), - throwsA(isArgumentError), - ); - }); - - test('serializeDeviceOrientation() should serialize correctly', () { - expect(serializeDeviceOrientation(DeviceOrientation.portraitUp), - 'portraitUp'); - expect(serializeDeviceOrientation(DeviceOrientation.portraitDown), - 'portraitDown'); - expect(serializeDeviceOrientation(DeviceOrientation.landscapeRight), - 'landscapeRight'); - expect(serializeDeviceOrientation(DeviceOrientation.landscapeLeft), - 'landscapeLeft'); - }); - - test('deserializeDeviceOrientation() should deserialize correctly', () { - expect(deserializeDeviceOrientation('portraitUp'), + deviceOrientationFromPlatform(PlatformDeviceOrientation.portraitUp), DeviceOrientation.portraitUp); - expect(deserializeDeviceOrientation('portraitDown'), + expect( + deviceOrientationFromPlatform(PlatformDeviceOrientation.portraitDown), DeviceOrientation.portraitDown); - expect(deserializeDeviceOrientation('landscapeRight'), + expect( + deviceOrientationFromPlatform( + PlatformDeviceOrientation.landscapeRight), DeviceOrientation.landscapeRight); - expect(deserializeDeviceOrientation('landscapeLeft'), + expect( + deviceOrientationFromPlatform( + PlatformDeviceOrientation.landscapeLeft), DeviceOrientation.landscapeLeft); }); + + test('exposureModeFromPlatform() should convert correctly', () { + expect(exposureModeFromPlatform(PlatformExposureMode.auto), + ExposureMode.auto); + expect(exposureModeFromPlatform(PlatformExposureMode.locked), + ExposureMode.locked); + }); + + test('focusModeFromPlatform() should convert correctly', () { + expect(focusModeFromPlatform(PlatformFocusMode.auto), FocusMode.auto); + expect(focusModeFromPlatform(PlatformFocusMode.locked), FocusMode.locked); + }); }); } diff --git a/packages/camera/camera_android_camerax/CHANGELOG.md b/packages/camera/camera_android_camerax/CHANGELOG.md index 8307d7077d8a..18218256feea 100644 --- a/packages/camera/camera_android_camerax/CHANGELOG.md +++ b/packages/camera/camera_android_camerax/CHANGELOG.md @@ -1,3 +1,60 @@ +## 0.6.10 + +* Removes logic that explicitly removes `READ_EXTERNAL_STORAGE` permission that may be implied + from `WRITE_EXTERNAL_STORAGE` and updates the README to tell users how to manually + remove it from their app's merged manifest if they wish. + +## 0.6.9+2 + +* Updates Java compatibility version to 11. + +## 0.6.9+1 + +* Bumps `com.google.guava:guava` from `33.3.0` to `33.3.1`. + +## 0.6.9 + +* Corrects assumption about automatic preview correction happening on API >= 29 to API > 29, + based on the fact that the `ImageReader` Impeller backend is not used for the most part on + devices running API 29+. + +## 0.6.8+3 + +* Removes dependency on org.jetbrains.kotlin:kotlin-bom. +* Updates minimum supported SDK version to Flutter 3.24/Dart 3.5. + +## 0.6.8+2 + +* Marks uses of `Camera2Interop` with `@OptIn` annotation. + +## 0.6.8+1 + +* Re-lands support for Impeller. + +## 0.6.8 + +* Updates Guava version to 33.3.0. + +## 0.6.7+2 + +* Updates lint checks to ignore NewerVersionAvailable. + +## 0.6.7+1 + +* Updates README to remove references to `maxVideoDuration`, as it was never + visible to app-facing clients, nor was it implemented in `camera_android`. + +## 0.6.7 + +* Updates AGP version to 8.5.0. + +## 0.6.6 + +* Adds logic to support building a camera preview with Android `Surface`s not backed by a `SurfaceTexture` + to which CameraX cannot not automatically apply the transformation required to achieve the correct rotation. +* Adds fix for incorrect camera preview rotation on naturally landscape-oriented devices. +* Updates example app's minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 0.6.5+6 * Updates Guava version to 33.2.1. diff --git a/packages/camera/camera_android_camerax/README.md b/packages/camera/camera_android_camerax/README.md index 1e40f53eb591..d6eb0cc36c08 100644 --- a/packages/camera/camera_android_camerax/README.md +++ b/packages/camera/camera_android_camerax/README.md @@ -4,7 +4,7 @@ The Android implementation of [`camera`][1] built with the [CameraX library][2]. *Note*: If any of [the limitations](#limitations) prevent you from using using `camera_android_camerax` or if you run into any problems, please report -report these issues under [`flutter/flutter`][5] with `[camerax]` in the title. +these issues under [`flutter/flutter`][5] with `[camerax]` in the title. You may also opt back into the [`camera_android`][9] implementation if you need. ## Usage @@ -44,12 +44,12 @@ due to this not currently being supported by CameraX. the plugin will fall back to target 480p (`ResolutionPreset.medium`) if configured with `ResolutionPreset.low`. -### Setting maximum duration and stream options for video capture +### Setting stream options for video capture Calling `startVideoCapturing` with `VideoCaptureOptions` configured with -`maxVideoDuration` and `streamOptions` is currently unsupported do to the -limitations of the CameraX library and the platform interface, respectively, -and thus, those parameters will silently be ignored. +`streamOptions` is currently unsupported do to +limitations of the platform interface, +and thus that parameter will silently be ignored. ## What requires Android permissions @@ -57,8 +57,21 @@ and thus, those parameters will silently be ignored. In order to save captured images and videos to files on Android 10 and below, CameraX requires specifying the `WRITE_EXTERNAL_STORAGE` permission (see [the CameraX documentation][10]). -This is already done in the plugin, so no further action is required on your end. To understand -the implications of specificying this permission, see [the `WRITE_EXTERNAL_STORAGE` documentation][11]. +This is already done in the plugin, so no further action is required on your end. + +To understand the privacy impact of specifying the `WRITE_EXTERNAL_STORAGE` permission, see the +[`WRITE_EXTERNAL_STORAGE` documentation][11]. We have seen apps also have the [`READ_EXTERNAL_STORAGE`][13] +permission automatically added to the merged Android manifest; it appears to be implied from +`WRITE_EXTERNAL_STORAGE`. If you do not want the `READ_EXTERNAL_STORAGE` permission to be included +in the merged Android manifest of your app, then take the following steps to remove it: + +1. Ensure that your app nor any of the plugins that it depends on require the `READ_EXTERNAL_STORAGE` permission. +2. Add the following to your app's `your_app/android/app/src/main/AndroidManifest.xml`: + +```xml + +``` ### Allowing image streaming in the background @@ -81,7 +94,7 @@ For more information on contributing to this plugin, see [`CONTRIBUTING.md`](CON [1]: https://pub.dev/packages/camera [2]: https://developer.android.com/training/camerax -[3]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[3]: https://flutter.dev/to/endorsed-federated-plugin [4]: https://pub.dev/packages/camera_android [5]: https://github.com/flutter/flutter/issues/new/choose [6]: https://developer.android.com/media/camera/camerax/architecture#combine-use-cases @@ -91,4 +104,5 @@ For more information on contributing to this plugin, see [`CONTRIBUTING.md`](CON [10]: https://developer.android.com/media/camera/camerax/architecture#permissions [11]: https://developer.android.com/reference/android/Manifest.permission#WRITE_EXTERNAL_STORAGE [12]: https://developer.android.com/reference/android/Manifest.permission#FOREGROUND_SERVICE_CAMERA +[13]: https://developer.android.com/reference/android/Manifest.permission#READ_EXTERNAL_STORAGE [148013]: https://github.com/flutter/flutter/issues/148013 diff --git a/packages/camera/camera_android_camerax/android/build.gradle b/packages/camera/camera_android_camerax/android/build.gradle index 71d87a7522e0..55a89f610715 100644 --- a/packages/camera/camera_android_camerax/android/build.gradle +++ b/packages/camera/camera_android_camerax/android/build.gradle @@ -8,7 +8,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.3.0' + classpath 'com.android.tools.build:gradle:8.5.0' } } @@ -22,16 +22,13 @@ rootProject.allprojects { apply plugin: 'com.android.library' android { - // Conditional for compatibility with AGP <4.2. - if (project.android.hasProperty("namespace")) { - namespace 'io.flutter.plugins.camerax' - } + namespace 'io.flutter.plugins.camerax' // CameraX dependencies require compilation against version 33 or later. compileSdk 34 compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } defaultConfig { @@ -55,7 +52,7 @@ android { lintOptions { checkAllWarnings true warningsAsErrors true - disable 'AndroidGradlePluginVersion', 'GradleDependency', 'InvalidPackage' + disable 'AndroidGradlePluginVersion', 'GradleDependency', 'InvalidPackage', 'NewerVersionAvailable' } } @@ -66,13 +63,9 @@ dependencies { implementation "androidx.camera:camera-camera2:${camerax_version}" implementation "androidx.camera:camera-lifecycle:${camerax_version}" implementation "androidx.camera:camera-video:${camerax_version}" - implementation 'com.google.guava:guava:33.2.1-android' + implementation 'com.google.guava:guava:33.3.1-android' testImplementation 'junit:junit:4.13.2' testImplementation 'org.mockito:mockito-inline:5.0.0' testImplementation 'androidx.test:core:1.4.0' testImplementation 'org.robolectric:robolectric:4.10.3' - - // org.jetbrains.kotlin:kotlin-bom artifact purpose is to align kotlin stdlib and related code versions. - // See: https://youtrack.jetbrains.com/issue/KT-55297/kotlin-stdlib-should-declare-constraints-on-kotlin-stdlib-jdk8-and-kotlin-stdlib-jdk7 - implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.10")) } diff --git a/packages/camera/camera_android_camerax/android/src/main/AndroidManifest.xml b/packages/camera/camera_android_camerax/android/src/main/AndroidManifest.xml index e1629a607c3a..52012aaa6915 100644 --- a/packages/camera/camera_android_camerax/android/src/main/AndroidManifest.xml +++ b/packages/camera/camera_android_camerax/android/src/main/AndroidManifest.xml @@ -1,11 +1,8 @@ - diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/Camera2CameraControlHostApiImpl.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/Camera2CameraControlHostApiImpl.java index 8d10005f7d75..300310d6c9d4 100644 --- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/Camera2CameraControlHostApiImpl.java +++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/Camera2CameraControlHostApiImpl.java @@ -10,6 +10,7 @@ import androidx.annotation.VisibleForTesting; import androidx.camera.camera2.interop.Camera2CameraControl; import androidx.camera.camera2.interop.CaptureRequestOptions; +import androidx.camera.camera2.interop.ExperimentalCamera2Interop; import androidx.camera.core.CameraControl; import androidx.core.content.ContextCompat; import com.google.common.util.concurrent.FutureCallback; @@ -134,6 +135,7 @@ public void addCaptureRequestOptions( * Retrieves the {@link Camera2CameraControl} instance associated with the specified {@code * identifier}. */ + @OptIn(markerClass = ExperimentalCamera2Interop.class) private Camera2CameraControl getCamera2CameraControlInstance(@NonNull Long identifier) { return Objects.requireNonNull(instanceManager.getInstance(identifier)); } diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/Camera2CameraInfoFlutterApiImpl.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/Camera2CameraInfoFlutterApiImpl.java index 398fc38049a4..58769ab400fa 100644 --- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/Camera2CameraInfoFlutterApiImpl.java +++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/Camera2CameraInfoFlutterApiImpl.java @@ -6,7 +6,9 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.OptIn; import androidx.camera.camera2.interop.Camera2CameraInfo; +import androidx.camera.camera2.interop.ExperimentalCamera2Interop; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugins.camerax.GeneratedCameraXLibrary.Camera2CameraInfoFlutterApi; @@ -19,6 +21,7 @@ public Camera2CameraInfoFlutterApiImpl( this.instanceManager = instanceManager; } + @OptIn(markerClass = ExperimentalCamera2Interop.class) void create(@NonNull Camera2CameraInfo camera2CameraInfo, @Nullable Reply reply) { if (!instanceManager.containsInstance(camera2CameraInfo)) { create(instanceManager.addHostCreatedInstance(camera2CameraInfo), reply); diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/Camera2CameraInfoHostApiImpl.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/Camera2CameraInfoHostApiImpl.java index 43fd0a383b00..983e9e0c674c 100644 --- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/Camera2CameraInfoHostApiImpl.java +++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/Camera2CameraInfoHostApiImpl.java @@ -29,26 +29,30 @@ public class Camera2CameraInfoHostApiImpl implements Camera2CameraInfoHostApi { /** Proxy for methods of {@link Camera2CameraInfo}. */ @VisibleForTesting + @OptIn(markerClass = ExperimentalCamera2Interop.class) public static class Camera2CameraInfoProxy { @NonNull - @OptIn(markerClass = ExperimentalCamera2Interop.class) public Camera2CameraInfo createFrom(@NonNull CameraInfo cameraInfo) { return Camera2CameraInfo.from(cameraInfo); } @NonNull - @OptIn(markerClass = ExperimentalCamera2Interop.class) public Integer getSupportedHardwareLevel(@NonNull Camera2CameraInfo camera2CameraInfo) { return camera2CameraInfo.getCameraCharacteristic( CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL); } @NonNull - @OptIn(markerClass = ExperimentalCamera2Interop.class) public String getCameraId(@NonNull Camera2CameraInfo camera2CameraInfo) { return camera2CameraInfo.getCameraId(); } + + @NonNull + public Long getSensorOrientation(@NonNull Camera2CameraInfo camera2CameraInfo) { + return Long.valueOf( + camera2CameraInfo.getCameraCharacteristic(CameraCharacteristics.SENSOR_ORIENTATION)); + } } /** @@ -80,6 +84,7 @@ public Camera2CameraInfoHostApiImpl( this.proxy = proxy; } + @OptIn(markerClass = ExperimentalCamera2Interop.class) @Override @NonNull public Long createFrom(@NonNull Long cameraInfoIdentifier) { @@ -105,6 +110,13 @@ public String getCameraId(@NonNull Long identifier) { return proxy.getCameraId(getCamera2CameraInfoInstance(identifier)); } + @Override + @NonNull + public Long getSensorOrientation(@NonNull Long identifier) { + return proxy.getSensorOrientation(getCamera2CameraInfoInstance(identifier)); + } + + @OptIn(markerClass = ExperimentalCamera2Interop.class) private Camera2CameraInfo getCamera2CameraInfoInstance(@NonNull Long identifier) { return Objects.requireNonNull(instanceManager.getInstance(identifier)); } diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraXProxy.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraXProxy.java index af7fdc36a721..e749940200a6 100644 --- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraXProxy.java +++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraXProxy.java @@ -5,9 +5,7 @@ package io.flutter.plugins.camerax; import android.app.Activity; -import android.graphics.SurfaceTexture; import android.util.Size; -import android.view.Surface; import androidx.annotation.NonNull; import androidx.camera.core.CameraSelector; import androidx.camera.core.ImageAnalysis; @@ -51,11 +49,6 @@ public class CameraXProxy { return new Preview.Builder(); } - /** Creates a {@link Surface} instance from the specified {@link SurfaceTexture}. */ - public @NonNull Surface createSurface(@NonNull SurfaceTexture surfaceTexture) { - return new Surface(surfaceTexture); - } - /** * Creates an instance of the {@link SystemServicesFlutterApiImpl}. * diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/DeviceOrientationManager.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/DeviceOrientationManager.java index b5281179d728..a8ad257a2bc4 100644 --- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/DeviceOrientationManager.java +++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/DeviceOrientationManager.java @@ -52,8 +52,7 @@ interface DeviceOrientationChangeCallback { * Starts listening to the device's sensors or UI for orientation updates. * *

When orientation information is updated, the callback method of the {@link - * DeviceOrientationChangeCallback} is called with the new orientation. This latest value can also - * be retrieved through the {@link #getVideoOrientation()} accessor. + * DeviceOrientationChangeCallback} is called with the new orientation. * *

If the device's ACCELEROMETER_ROTATION setting is enabled the {@link * DeviceOrientationManager} will report orientation updates based on the sensor information. If @@ -124,7 +123,7 @@ static void handleOrientationChange( */ // Configuration.ORIENTATION_SQUARE is deprecated. @SuppressWarnings("deprecation") - @VisibleForTesting + @NonNull PlatformChannel.DeviceOrientation getUIOrientation() { final int rotation = getDefaultRotation(); final int orientation = activity.getResources().getConfiguration().orientation; diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/DeviceOrientationManagerHostApiImpl.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/DeviceOrientationManagerHostApiImpl.java index 22bba48e1bad..363bc39b2780 100644 --- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/DeviceOrientationManagerHostApiImpl.java +++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/DeviceOrientationManagerHostApiImpl.java @@ -95,7 +95,8 @@ public void stopListeningForDeviceOrientationChange() { * for instance for more information on how this default value is used. */ @Override - public @NonNull Long getDefaultDisplayRotation() { + @NonNull + public Long getDefaultDisplayRotation() { int defaultRotation; try { defaultRotation = deviceOrientationManager.getDefaultRotation(); @@ -106,4 +107,11 @@ public void stopListeningForDeviceOrientationChange() { return Long.valueOf(defaultRotation); } + + /** Gets current UI orientation based on the current device orientation and rotation. */ + @Override + @NonNull + public String getUiOrientation() { + return serializeDeviceOrientation(deviceOrientationManager.getUIOrientation()); + } } diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/GeneratedCameraXLibrary.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/GeneratedCameraXLibrary.java index cbfc36f35cbd..7adf02595ad9 100644 --- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/GeneratedCameraXLibrary.java +++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/GeneratedCameraXLibrary.java @@ -1441,6 +1441,9 @@ void requestCameraPermissions( @NonNull String getTempFilePath(@NonNull String prefix, @NonNull String suffix); + @NonNull + Boolean isPreviewPreTransformed(); + /** The codec used by SystemServicesHostApi. */ static @NonNull MessageCodec getCodec() { return SystemServicesHostApiCodec.INSTANCE; @@ -1508,6 +1511,29 @@ public void error(Throwable error) { channel.setMessageHandler(null); } } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.SystemServicesHostApi.isPreviewPreTransformed", + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList(); + try { + Boolean output = api.isPreviewPreTransformed(); + wrapped.add(0, output); + } catch (Throwable exception) { + ArrayList wrappedError = wrapError(exception); + wrapped = wrappedError; + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } } } /** Generated class from Pigeon that represents Flutter messages that can be called from Java. */ @@ -1550,6 +1576,9 @@ void startListeningForDeviceOrientationChange( @NonNull Long getDefaultDisplayRotation(); + @NonNull + String getUiOrientation(); + /** The codec used by DeviceOrientationManagerHostApi. */ static @NonNull MessageCodec getCodec() { return new StandardMessageCodec(); @@ -1634,6 +1663,29 @@ static void setup( channel.setMessageHandler(null); } } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.DeviceOrientationManagerHostApi.getUiOrientation", + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList(); + try { + String output = api.getUiOrientation(); + wrapped.add(0, output); + } catch (Throwable exception) { + ArrayList wrappedError = wrapError(exception); + wrapped = wrappedError; + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } } } /** Generated class from Pigeon that represents Flutter messages that can be called from Java. */ @@ -4389,6 +4441,9 @@ public interface Camera2CameraInfoHostApi { @NonNull String getCameraId(@NonNull Long identifier); + @NonNull + Long getSensorOrientation(@NonNull Long identifier); + /** The codec used by Camera2CameraInfoHostApi. */ static @NonNull MessageCodec getCodec() { return new StandardMessageCodec(); @@ -4481,6 +4536,33 @@ static void setup( channel.setMessageHandler(null); } } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.Camera2CameraInfoHostApi.getSensorOrientation", + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number identifierArg = (Number) args.get(0); + try { + Long output = + api.getSensorOrientation( + (identifierArg == null) ? null : identifierArg.longValue()); + wrapped.add(0, output); + } catch (Throwable exception) { + ArrayList wrappedError = wrapError(exception); + wrapped = wrappedError; + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } } } /** Generated class from Pigeon that represents Flutter messages that can be called from Java. */ diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/PreviewHostApiImpl.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/PreviewHostApiImpl.java index 7b1ba1214cdb..e9b7b0d89ac6 100644 --- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/PreviewHostApiImpl.java +++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/PreviewHostApiImpl.java @@ -4,7 +4,6 @@ package io.flutter.plugins.camerax; -import android.graphics.SurfaceTexture; import android.util.Size; import android.view.Surface; import androidx.annotation.NonNull; @@ -25,7 +24,7 @@ public class PreviewHostApiImpl implements PreviewHostApi { private final TextureRegistry textureRegistry; @VisibleForTesting public @NonNull CameraXProxy cameraXProxy = new CameraXProxy(); - @VisibleForTesting public @Nullable TextureRegistry.SurfaceTextureEntry flutterSurfaceTexture; + @VisibleForTesting public @Nullable TextureRegistry.SurfaceProducer flutterSurfaceProducer; public PreviewHostApiImpl( @NonNull BinaryMessenger binaryMessenger, @@ -62,12 +61,11 @@ public void create( @Override public @NonNull Long setSurfaceProvider(@NonNull Long identifier) { Preview preview = getPreviewInstance(identifier); - flutterSurfaceTexture = textureRegistry.createSurfaceTexture(); - SurfaceTexture surfaceTexture = flutterSurfaceTexture.surfaceTexture(); - Preview.SurfaceProvider surfaceProvider = createSurfaceProvider(surfaceTexture); + flutterSurfaceProducer = textureRegistry.createSurfaceProducer(); + Preview.SurfaceProvider surfaceProvider = createSurfaceProvider(flutterSurfaceProducer); preview.setSurfaceProvider(surfaceProvider); - return flutterSurfaceTexture.id(); + return flutterSurfaceProducer.id(); } /** @@ -76,13 +74,35 @@ public void create( */ @VisibleForTesting public @NonNull Preview.SurfaceProvider createSurfaceProvider( - @NonNull SurfaceTexture surfaceTexture) { + @NonNull TextureRegistry.SurfaceProducer surfaceProducer) { return new Preview.SurfaceProvider() { @Override public void onSurfaceRequested(@NonNull SurfaceRequest request) { - surfaceTexture.setDefaultBufferSize( + // Set callback for surfaceProducer to invalidate Surfaces that it produces when they + // get destroyed. + surfaceProducer.setCallback( + new TextureRegistry.SurfaceProducer.Callback() { + @Override + // TODO(matanlurey): Replace with onSurfaceAvailable once available on stable; + // https://github.com/flutter/flutter/issues/155131. + @SuppressWarnings({"deprecation", "removal"}) + public void onSurfaceCreated() { + // Do nothing. The Preview.SurfaceProvider will handle this whenever a new + // Surface is needed. + } + + @Override + public void onSurfaceDestroyed() { + // Invalidate the SurfaceRequest so that CameraX knows to to make a new request + // for a surface. + request.invalidate(); + } + }); + + // Provide surface. + surfaceProducer.setSize( request.getResolution().getWidth(), request.getResolution().getHeight()); - Surface flutterSurface = cameraXProxy.createSurface(surfaceTexture); + Surface flutterSurface = surfaceProducer.getSurface(); request.provideSurface( flutterSurface, Executors.newSingleThreadExecutor(), @@ -133,8 +153,8 @@ String getProvideSurfaceErrorDescription(int resultCode) { */ @Override public void releaseFlutterSurfaceTexture() { - if (flutterSurfaceTexture != null) { - flutterSurfaceTexture.release(); + if (flutterSurfaceProducer != null) { + flutterSurfaceProducer.release(); } } diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/SystemServicesHostApiImpl.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/SystemServicesHostApiImpl.java index d058d62fe224..138e9259e025 100644 --- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/SystemServicesHostApiImpl.java +++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/SystemServicesHostApiImpl.java @@ -6,6 +6,7 @@ import android.app.Activity; import android.content.Context; +import android.os.Build; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; @@ -103,4 +104,18 @@ public String getTempFilePath(@NonNull String prefix, @NonNull String suffix) { null); } } + + /** + * Returns whether or not Impeller uses an {@code ImageReader} backend to provide a {@code + * Surface} to CameraX to build the preview. If it is backed by an {@code ImageReader}, then + * CameraX will not automatically apply the transformation needed to correct the preview. + * + *

This is determined by the engine, which approximately uses {@code SurfaceTexture}s on + * Android SDKs below 29. + */ + @Override + @NonNull + public Boolean isPreviewPreTransformed() { + return Build.VERSION.SDK_INT < 29; + } } diff --git a/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/DeviceOrientationManagerWrapperTest.java b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/DeviceOrientationManagerWrapperTest.java index 26cfd77f1265..ba7335971f1d 100644 --- a/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/DeviceOrientationManagerWrapperTest.java +++ b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/DeviceOrientationManagerWrapperTest.java @@ -93,4 +93,16 @@ public void getDefaultDisplayRotation_returnsExpectedRotation() { assertEquals(hostApi.getDefaultDisplayRotation(), Long.valueOf(defaultRotation)); } + + @Test + public void getUiOrientation_returnsExpectedOrientation() { + final DeviceOrientationManagerHostApiImpl hostApi = + new DeviceOrientationManagerHostApiImpl(mockBinaryMessenger, mockInstanceManager); + final DeviceOrientation uiOrientation = DeviceOrientation.LANDSCAPE_LEFT; + + hostApi.deviceOrientationManager = mockDeviceOrientationManager; + when(mockDeviceOrientationManager.getUIOrientation()).thenReturn(uiOrientation); + + assertEquals(hostApi.getUiOrientation(), uiOrientation.toString()); + } } diff --git a/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/PreviewTest.java b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/PreviewTest.java index 81b455d7a867..83ccb1edd9c5 100644 --- a/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/PreviewTest.java +++ b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/PreviewTest.java @@ -11,9 +11,9 @@ import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; -import android.graphics.SurfaceTexture; import android.util.Size; import android.view.Surface; import androidx.camera.core.Preview; @@ -83,37 +83,67 @@ public void create_createsPreviewWithCorrectConfiguration() { } @Test - public void setSurfaceProviderTest_createsSurfaceProviderAndReturnsTextureEntryId() { + public void setSurfaceProvider_createsSurfaceProviderAndReturnsTextureEntryId() { final PreviewHostApiImpl previewHostApi = spy(new PreviewHostApiImpl(mockBinaryMessenger, testInstanceManager, mockTextureRegistry)); - final TextureRegistry.SurfaceTextureEntry mockSurfaceTextureEntry = - mock(TextureRegistry.SurfaceTextureEntry.class); - final SurfaceTexture mockSurfaceTexture = mock(SurfaceTexture.class); + final TextureRegistry.SurfaceProducer mockSurfaceProducer = + mock(TextureRegistry.SurfaceProducer.class); final Long previewIdentifier = 5L; - final Long surfaceTextureEntryId = 120L; + final Long surfaceProducerEntryId = 120L; previewHostApi.cameraXProxy = mockCameraXProxy; testInstanceManager.addDartCreatedInstance(mockPreview, previewIdentifier); - when(mockTextureRegistry.createSurfaceTexture()).thenReturn(mockSurfaceTextureEntry); - when(mockSurfaceTextureEntry.surfaceTexture()).thenReturn(mockSurfaceTexture); - when(mockSurfaceTextureEntry.id()).thenReturn(surfaceTextureEntryId); + when(mockTextureRegistry.createSurfaceProducer()).thenReturn(mockSurfaceProducer); + when(mockSurfaceProducer.id()).thenReturn(surfaceProducerEntryId); final ArgumentCaptor surfaceProviderCaptor = ArgumentCaptor.forClass(Preview.SurfaceProvider.class); - final ArgumentCaptor surfaceCaptor = ArgumentCaptor.forClass(Surface.class); // Test that surface provider was set and the surface texture ID was returned. - assertEquals(previewHostApi.setSurfaceProvider(previewIdentifier), surfaceTextureEntryId); + assertEquals(previewHostApi.setSurfaceProvider(previewIdentifier), surfaceProducerEntryId); verify(mockPreview).setSurfaceProvider(surfaceProviderCaptor.capture()); - verify(previewHostApi).createSurfaceProvider(mockSurfaceTexture); + verify(previewHostApi).createSurfaceProvider(mockSurfaceProducer); + } + + @Test + public void createSurfaceProducer_setsExpectedSurfaceProducerCallback() { + final PreviewHostApiImpl previewHostApi = + new PreviewHostApiImpl(mockBinaryMessenger, testInstanceManager, mockTextureRegistry); + final TextureRegistry.SurfaceProducer mockSurfaceProducer = + mock(TextureRegistry.SurfaceProducer.class); + final SurfaceRequest mockSurfaceRequest = mock(SurfaceRequest.class); + final ArgumentCaptor callbackCaptor = + ArgumentCaptor.forClass(TextureRegistry.SurfaceProducer.Callback.class); + + when(mockSurfaceRequest.getResolution()).thenReturn(new Size(5, 6)); + when(mockSurfaceProducer.getSurface()).thenReturn(mock(Surface.class)); + + Preview.SurfaceProvider previewSurfaceProvider = + previewHostApi.createSurfaceProvider(mockSurfaceProducer); + previewSurfaceProvider.onSurfaceRequested(mockSurfaceRequest); + + verify(mockSurfaceProducer).setCallback(callbackCaptor.capture()); + + TextureRegistry.SurfaceProducer.Callback callback = callbackCaptor.getValue(); + + // Verify callback's onSurfaceDestroyed invalidates SurfaceRequest. + callback.onSurfaceDestroyed(); + verify(mockSurfaceRequest).invalidate(); + + reset(mockSurfaceRequest); + + // Verify callback's onSurfaceCreated does not interact with the SurfaceRequest. + simulateSurfaceCreation(callback); + verifyNoMoreInteractions(mockSurfaceRequest); } @Test public void createSurfaceProvider_createsExpectedPreviewSurfaceProvider() { final PreviewHostApiImpl previewHostApi = new PreviewHostApiImpl(mockBinaryMessenger, testInstanceManager, mockTextureRegistry); - final SurfaceTexture mockSurfaceTexture = mock(SurfaceTexture.class); + final TextureRegistry.SurfaceProducer mockSurfaceProducer = + mock(TextureRegistry.SurfaceProducer.class); final Surface mockSurface = mock(Surface.class); final SurfaceRequest mockSurfaceRequest = mock(SurfaceRequest.class); final SurfaceRequest.Result mockSurfaceRequestResult = mock(SurfaceRequest.Result.class); @@ -121,13 +151,14 @@ public void createSurfaceProvider_createsExpectedPreviewSurfaceProvider() { mock(SystemServicesFlutterApiImpl.class); final int resolutionWidth = 200; final int resolutionHeight = 500; + final Long surfaceProducerEntryId = 120L; previewHostApi.cameraXProxy = mockCameraXProxy; - when(mockCameraXProxy.createSurface(mockSurfaceTexture)).thenReturn(mockSurface); when(mockSurfaceRequest.getResolution()) .thenReturn(new Size(resolutionWidth, resolutionHeight)); when(mockCameraXProxy.createSystemServicesFlutterApiImpl(mockBinaryMessenger)) .thenReturn(mockSystemServicesFlutterApi); + when(mockSurfaceProducer.getSurface()).thenReturn(mockSurface); final ArgumentCaptor surfaceCaptor = ArgumentCaptor.forClass(Surface.class); @SuppressWarnings("unchecked") @@ -135,10 +166,10 @@ public void createSurfaceProvider_createsExpectedPreviewSurfaceProvider() { ArgumentCaptor.forClass(Consumer.class); Preview.SurfaceProvider previewSurfaceProvider = - previewHostApi.createSurfaceProvider(mockSurfaceTexture); + previewHostApi.createSurfaceProvider(mockSurfaceProducer); previewSurfaceProvider.onSurfaceRequested(mockSurfaceRequest); - verify(mockSurfaceTexture).setDefaultBufferSize(resolutionWidth, resolutionHeight); + verify(mockSurfaceProducer).setSize(resolutionWidth, resolutionHeight); verify(mockSurfaceRequest) .provideSurface(surfaceCaptor.capture(), any(Executor.class), consumerCaptor.capture()); @@ -189,13 +220,13 @@ public void createSurfaceProvider_createsExpectedPreviewSurfaceProvider() { public void releaseFlutterSurfaceTexture_makesCallToReleaseFlutterSurfaceTexture() { final PreviewHostApiImpl previewHostApi = new PreviewHostApiImpl(mockBinaryMessenger, testInstanceManager, mockTextureRegistry); - final TextureRegistry.SurfaceTextureEntry mockSurfaceTextureEntry = - mock(TextureRegistry.SurfaceTextureEntry.class); + final TextureRegistry.SurfaceProducer mockSurfaceProducer = + mock(TextureRegistry.SurfaceProducer.class); - previewHostApi.flutterSurfaceTexture = mockSurfaceTextureEntry; + previewHostApi.flutterSurfaceProducer = mockSurfaceProducer; previewHostApi.releaseFlutterSurfaceTexture(); - verify(mockSurfaceTextureEntry).release(); + verify(mockSurfaceProducer).release(); } @Test @@ -231,4 +262,12 @@ public void setTargetRotation_makesCallToSetTargetRotation() { verify(mockPreview).setTargetRotation(targetRotation); } + + // TODO(matanlurey): Replace with inline calls to onSurfaceAvailable once + // available on stable; see https://github.com/flutter/flutter/issues/155131. + // This seperate method only exists to scope the suppression. + @SuppressWarnings({"deprecation", "removal"}) + void simulateSurfaceCreation(TextureRegistry.SurfaceProducer.Callback producerLifecycle) { + producerLifecycle.onSurfaceCreated(); + } } diff --git a/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/SystemServicesTest.java b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/SystemServicesTest.java index 3636629e75f7..52d02e67f653 100644 --- a/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/SystemServicesTest.java +++ b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/SystemServicesTest.java @@ -5,7 +5,9 @@ package io.flutter.plugins.camerax; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mockStatic; @@ -24,12 +26,16 @@ import java.io.IOException; import org.junit.Rule; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockedStatic; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; +@RunWith(RobolectricTestRunner.class) public class SystemServicesTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); @@ -130,4 +136,28 @@ public void getTempFilePath_throwsRuntimeExceptionOnIOException() { mockedStaticFile.close(); } + + @Test + @Config(sdk = 28) + public void isPreviewPreTransformed_returnsTrueWhenRunningBelowSdk29() { + final SystemServicesHostApiImpl systemServicesHostApi = + new SystemServicesHostApiImpl(mockBinaryMessenger, mockInstanceManager, mockContext); + assertTrue(systemServicesHostApi.isPreviewPreTransformed()); + } + + @Test + @Config(sdk = 28) + public void isPreviewPreTransformed_returnsTrueWhenRunningSdk28() { + final SystemServicesHostApiImpl systemServicesHostApi = + new SystemServicesHostApiImpl(mockBinaryMessenger, mockInstanceManager, mockContext); + assertTrue(systemServicesHostApi.isPreviewPreTransformed()); + } + + @Test + @Config(sdk = 29) + public void isPreviewPreTransformed_returnsFalseWhenRunningAboveSdk28() { + final SystemServicesHostApiImpl systemServicesHostApi = + new SystemServicesHostApiImpl(mockBinaryMessenger, mockInstanceManager, mockContext); + assertFalse(systemServicesHostApi.isPreviewPreTransformed()); + } } 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 c9117991074d..2094aa796f4c 100644 --- a/packages/camera/camera_android_camerax/example/android/app/build.gradle +++ b/packages/camera/camera_android_camerax/example/android/app/build.gradle @@ -31,16 +31,13 @@ android { ndkVersion flutter.ndkVersion compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "io.flutter.plugins.cameraxexample" - // You can update the following values to match your application needs. - // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. - minSdkVersion 21 + minSdkVersion flutter.minSdkVersion targetSdkVersion 30 versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/packages/camera/camera_android_camerax/example/android/app/src/androidTest/java/io/flutter/plugins/cameraxexample/InstanceManagerTest.java b/packages/camera/camera_android_camerax/example/android/app/src/androidTest/java/io/flutter/plugins/cameraxexample/InstanceManagerTest.java index 5e4454de80d3..fe15629b6d72 100644 --- a/packages/camera/camera_android_camerax/example/android/app/src/androidTest/java/io/flutter/plugins/cameraxexample/InstanceManagerTest.java +++ b/packages/camera/camera_android_camerax/example/android/app/src/androidTest/java/io/flutter/plugins/cameraxexample/InstanceManagerTest.java @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package io.flutter.plugins.cameraexample; +package io.flutter.plugins.cameraxexample; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; 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 2a0066ccab4e..1a0da4432332 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 @@ -1,5 +1,4 @@ - + cameras = await availableCameras(); @@ -255,5 +259,5 @@ void main() { await videoController.dispose(); expect(duration, lessThan(recordingTime - timePaused)); - }); + }, skip: skipFor157181); } diff --git a/packages/camera/camera_android_camerax/example/lib/main.dart b/packages/camera/camera_android_camerax/example/lib/main.dart index 567d400d992c..9eee18c45738 100644 --- a/packages/camera/camera_android_camerax/example/lib/main.dart +++ b/packages/camera/camera_android_camerax/example/lib/main.dart @@ -698,7 +698,6 @@ class _CameraExampleHomeState extends State showInSnackBar('Audio access is restricted.'); default: _showCameraException(e); - break; } } diff --git a/packages/camera/camera_android_camerax/example/pubspec.yaml b/packages/camera/camera_android_camerax/example/pubspec.yaml index f16b8d5433b1..627360153368 100644 --- a/packages/camera/camera_android_camerax/example/pubspec.yaml +++ b/packages/camera/camera_android_camerax/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the camera_android_camerax plugin. publish_to: 'none' environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" dependencies: camera_android_camerax: @@ -20,7 +20,7 @@ dependencies: video_player: ^2.7.0 dev_dependencies: - espresso: ^0.2.0 + espresso: ^0.4.0 flutter_test: sdk: flutter integration_test: diff --git a/packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart b/packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart index edf24bab37a0..1d068eb24f1f 100644 --- a/packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart +++ b/packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart @@ -10,7 +10,7 @@ import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:flutter/services.dart' show DeviceOrientation, PlatformException; import 'package:flutter/widgets.dart' - show Size, Texture, Widget, visibleForTesting; + show RotatedBox, Size, Texture, Widget, visibleForTesting; import 'package:stream_transform/stream_transform.dart'; import 'analyzer.dart'; @@ -233,6 +233,34 @@ class AndroidCameraCameraX extends CameraPlatform { static const String exposureCompensationNotSupported = 'exposureCompensationNotSupported'; + /// Whether or not the created camera is front facing. + @visibleForTesting + late bool cameraIsFrontFacing; + + /// Whether or not the Surface used to create the camera preview is backed + /// by a SurfaceTexture. + @visibleForTesting + late bool isPreviewPreTransformed; + + /// The initial orientation of the device. + /// + /// The camera preview will use this orientation as the natural orientation + /// to correct its rotation with respect to, if necessary. + @visibleForTesting + DeviceOrientation? naturalOrientation; + + /// The camera sensor orientation. + @visibleForTesting + late int sensorOrientation; + + /// The current orientation of the device. + @visibleForTesting + DeviceOrientation? currentDeviceOrientation; + + /// Subscription for listening to changes in device orientation. + StreamSubscription? + _subscriptionForDeviceOrientationChanges; + /// Returns list of all available cameras and their descriptions. @override Future> availableCameras() async { @@ -321,7 +349,7 @@ class AndroidCameraCameraX extends CameraPlatform { // Save CameraSelector that matches cameraDescription. final int cameraSelectorLensDirection = _getCameraSelectorLensDirection(cameraDescription.lensDirection); - final bool cameraIsFrontFacing = + cameraIsFrontFacing = cameraSelectorLensDirection == CameraSelector.lensFacingFront; cameraSelector = proxy.createCameraSelector(cameraSelectorLensDirection); // Start listening for device orientation changes preceding camera creation. @@ -366,6 +394,26 @@ class AndroidCameraCameraX extends CameraPlatform { previewInitiallyBound = true; _previewIsPaused = false; + // Retrieve info required for correcting the rotation of the camera preview + // if necessary. + + final Camera2CameraInfo camera2CameraInfo = + await proxy.getCamera2CameraInfo(cameraInfo!); + await Future.wait(>[ + SystemServices.isPreviewPreTransformed() + .then((bool value) => isPreviewPreTransformed = value), + proxy + .getSensorOrientation(camera2CameraInfo) + .then((int value) => sensorOrientation = value), + proxy + .getUiOrientation() + .then((DeviceOrientation value) => naturalOrientation ??= value), + ]); + _subscriptionForDeviceOrientationChanges = onDeviceOrientationChanged() + .listen((DeviceOrientationChangedEvent event) { + currentDeviceOrientation = event.orientation; + }); + return flutterSurfaceTextureId; } @@ -425,6 +473,7 @@ class AndroidCameraCameraX extends CameraPlatform { await liveCameraState?.removeObservers(); processCameraProvider?.unbindAll(); await imageAnalysis?.clearAnalyzer(); + await _subscriptionForDeviceOrientationChanges?.cancel(); } /// The camera has been initialized. @@ -815,7 +864,69 @@ class AndroidCameraCameraX extends CameraPlatform { "Camera not found. Please call the 'create' method before calling 'buildPreview'", ); } - return Texture(textureId: cameraId); + + final Widget cameraPreview = Texture(textureId: cameraId); + final Map degreesForDeviceOrientation = + { + DeviceOrientation.portraitUp: 0, + DeviceOrientation.landscapeRight: 90, + DeviceOrientation.portraitDown: 180, + DeviceOrientation.landscapeLeft: 270, + }; + int naturalDeviceOrientationDegrees = + degreesForDeviceOrientation[naturalOrientation]!; + + if (isPreviewPreTransformed) { + // If the camera preview is backed by a SurfaceTexture, the transformation + // needed to correctly rotate the preview has already been applied. + // However, we may need to correct the camera preview rotation if the + // device is naturally landscape-oriented. + if (naturalOrientation == DeviceOrientation.landscapeLeft || + naturalOrientation == DeviceOrientation.landscapeRight) { + final int quarterTurnsToCorrectForLandscape = + (-naturalDeviceOrientationDegrees + 360) ~/ 4; + return RotatedBox( + quarterTurns: quarterTurnsToCorrectForLandscape, + child: cameraPreview); + } + return cameraPreview; + } + + // Fix for the rotation of the camera preview not backed by a SurfaceTexture + // with respect to the naturalOrientation of the device: + + final int signForCameraDirection = cameraIsFrontFacing ? 1 : -1; + + if (signForCameraDirection == 1 && + (currentDeviceOrientation == DeviceOrientation.landscapeLeft || + currentDeviceOrientation == DeviceOrientation.landscapeRight)) { + // For front-facing cameras, the image buffer is rotated counterclockwise, + // so we determine the rotation needed to correct the camera preview with + // respect to the naturalOrientation of the device based on the inverse of + // naturalOrientation. + naturalDeviceOrientationDegrees += 180; + } + + // See https://developer.android.com/media/camera/camera2/camera-preview#orientation_calculation + // for more context on this formula. + final double rotation = (sensorOrientation + + naturalDeviceOrientationDegrees * signForCameraDirection + + 360) % + 360; + int quarterTurnsToCorrectPreview = rotation ~/ 90; + + if (naturalOrientation == DeviceOrientation.landscapeLeft || + naturalOrientation == DeviceOrientation.landscapeRight) { + // We may need to correct the camera preview rotation if the device is + // naturally landscape-oriented. + quarterTurnsToCorrectPreview += + (-naturalDeviceOrientationDegrees + 360) ~/ 4; + return RotatedBox( + quarterTurns: quarterTurnsToCorrectPreview, child: cameraPreview); + } + + return RotatedBox( + quarterTurns: quarterTurnsToCorrectPreview, child: cameraPreview); } /// Captures an image and returns the file where it was saved. @@ -902,16 +1013,15 @@ class AndroidCameraCameraX extends CameraPlatform { @override Future startVideoRecording(int cameraId, {Duration? maxVideoDuration}) async { - return startVideoCapturing( - VideoCaptureOptions(cameraId, maxDuration: maxVideoDuration)); + // Ignore maxVideoDuration, as it is unimplemented and deprecated. + return startVideoCapturing(VideoCaptureOptions(cameraId)); } /// Starts a video recording and/or streaming session. /// /// Please see [VideoCaptureOptions] for documentation on the - /// configuration options. Currently, maxVideoDuration and streamOptions - /// are unsupported due to the limitations of CameraX and the platform - /// interface, respectively. + /// configuration options. Currently streamOptions are unsupported due to + /// limitations of the platform interface. @override Future startVideoCapturing(VideoCaptureOptions options) async { if (recording != null) { diff --git a/packages/camera/camera_android_camerax/lib/src/camera2_camera_info.dart b/packages/camera/camera_android_camerax/lib/src/camera2_camera_info.dart index fafb90f0ecb5..88b44238f3b9 100644 --- a/packages/camera/camera_android_camerax/lib/src/camera2_camera_info.dart +++ b/packages/camera/camera_android_camerax/lib/src/camera2_camera_info.dart @@ -53,6 +53,10 @@ class Camera2CameraInfo extends JavaObject { /// The ID may change based on the internal configuration of the camera to which /// this instances pertains. Future getCameraId() => _api.getCameraIdFromInstance(this); + + /// Retrieves the orientation of the camera sensor. + Future getSensorOrientation() => + _api.getSensorOrientationFromInstance(this); } /// Host API implementation of [Camera2CameraInfo]. @@ -91,6 +95,11 @@ class _Camera2CameraInfoHostApiImpl extends Camera2CameraInfoHostApi { final int? identifier = instanceManager.getIdentifier(instance); return getCameraId(identifier!); } + + Future getSensorOrientationFromInstance(Camera2CameraInfo instance) { + final int? identifier = instanceManager.getIdentifier(instance); + return getSensorOrientation(identifier!); + } } /// Flutter API Implementation of [Camera2CameraInfo]. diff --git a/packages/camera/camera_android_camerax/lib/src/camera_state_error.dart b/packages/camera/camera_android_camerax/lib/src/camera_state_error.dart index 2f33d513aa02..fedb85c9e8ad 100644 --- a/packages/camera/camera_android_camerax/lib/src/camera_state_error.dart +++ b/packages/camera/camera_android_camerax/lib/src/camera_state_error.dart @@ -59,7 +59,6 @@ class CameraStateError extends JavaObject { default: description = 'There was an unspecified issue with the current camera state.'; - break; } return '$code : $description'; diff --git a/packages/camera/camera_android_camerax/lib/src/camerax_library.g.dart b/packages/camera/camera_android_camerax/lib/src/camerax_library.g.dart index e63a7a6afaf9..a9461eaaae03 100644 --- a/packages/camera/camera_android_camerax/lib/src/camerax_library.g.dart +++ b/packages/camera/camera_android_camerax/lib/src/camerax_library.g.dart @@ -1003,6 +1003,33 @@ class SystemServicesHostApi { return (replyList[0] as String?)!; } } + + Future isPreviewPreTransformed() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.SystemServicesHostApi.isPreviewPreTransformed', + codec, + binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(null) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as bool?)!; + } + } } abstract class SystemServicesFlutterApi { @@ -1117,6 +1144,33 @@ class DeviceOrientationManagerHostApi { return (replyList[0] as int?)!; } } + + Future getUiOrientation() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.DeviceOrientationManagerHostApi.getUiOrientation', + codec, + binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(null) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as String?)!; + } + } } abstract class DeviceOrientationManagerFlutterApi { @@ -3575,6 +3629,34 @@ class Camera2CameraInfoHostApi { return (replyList[0] as String?)!; } } + + Future getSensorOrientation(int arg_identifier) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.Camera2CameraInfoHostApi.getSensorOrientation', + codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_identifier]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as int?)!; + } + } } abstract class Camera2CameraInfoFlutterApi { diff --git a/packages/camera/camera_android_camerax/lib/src/camerax_proxy.dart b/packages/camera/camera_android_camerax/lib/src/camerax_proxy.dart index d81d1c761c6a..feae868ac40c 100644 --- a/packages/camera/camera_android_camerax/lib/src/camerax_proxy.dart +++ b/packages/camera/camera_android_camerax/lib/src/camerax_proxy.dart @@ -4,6 +4,8 @@ import 'dart:ui' show Size; +import 'package:flutter/services.dart' show DeviceOrientation; + import 'analyzer.dart'; import 'aspect_ratio_strategy.dart'; import 'camera2_camera_control.dart'; @@ -66,6 +68,8 @@ class CameraXProxy { this.createResolutionFilterWithOnePreferredSize = _createAttachedResolutionFilterWithOnePreferredSize, this.getCamera2CameraInfo = _getCamera2CameraInfo, + this.getUiOrientation = _getUiOrientation, + this.getSensorOrientation = _getSensorOrientation, }); /// Returns a [ProcessCameraProvider] instance. @@ -189,6 +193,13 @@ class CameraXProxy { Future Function(CameraInfo cameraInfo) getCamera2CameraInfo; + /// Gets current UI orientation based on device orientation and rotation. + Future Function() getUiOrientation; + + /// Gets camera sensor orientation from [camera2CameraInfo]. + Future Function(Camera2CameraInfo camera2CameraInfo) + getSensorOrientation; + static Future _getProcessCameraProvider() { return ProcessCameraProvider.getInstance(); } @@ -335,4 +346,13 @@ class CameraXProxy { CameraInfo cameraInfo) async { return Camera2CameraInfo.from(cameraInfo); } + + static Future _getUiOrientation() async { + return DeviceOrientationManager.getUiOrientation(); + } + + static Future _getSensorOrientation( + Camera2CameraInfo camera2CameraInfo) async { + return camera2CameraInfo.getSensorOrientation(); + } } diff --git a/packages/camera/camera_android_camerax/lib/src/capture_request_options.dart b/packages/camera/camera_android_camerax/lib/src/capture_request_options.dart index 777d4a43370f..8c3de00845ed 100644 --- a/packages/camera/camera_android_camerax/lib/src/capture_request_options.dart +++ b/packages/camera/camera_android_camerax/lib/src/capture_request_options.dart @@ -115,7 +115,7 @@ class _CaptureRequestOptionsHostApiImpl extends CaptureRequestOptionsHostApi { // This ignore statement is safe beause this error will be useful when // a new CaptureRequestKeySupportedType is being added, but the logic in // this method has not yet been updated. - // ignore: no_default_cases + // ignore: no_default_cases, unreachable_switch_default default: throw ArgumentError(CaptureRequestOptions .getUnsupportedCaptureRequestKeyTypeErrorMessage(key)); diff --git a/packages/camera/camera_android_camerax/lib/src/device_orientation_manager.dart b/packages/camera/camera_android_camerax/lib/src/device_orientation_manager.dart index 10f20232485b..aacddc5788a0 100644 --- a/packages/camera/camera_android_camerax/lib/src/device_orientation_manager.dart +++ b/packages/camera/camera_android_camerax/lib/src/device_orientation_manager.dart @@ -67,6 +67,16 @@ class DeviceOrientationManager { return api.getDefaultDisplayRotation(); } + /// Retrieves the current UI orientation based on the current device + /// orientation and screen rotation. + static Future getUiOrientation( + {BinaryMessenger? binaryMessenger}) async { + final DeviceOrientationManagerHostApi api = + DeviceOrientationManagerHostApi(binaryMessenger: binaryMessenger); + + return deserializeDeviceOrientation(await api.getUiOrientation()); + } + /// Serializes [DeviceOrientation] into a [String]. static String serializeDeviceOrientation(DeviceOrientation orientation) { switch (orientation) { @@ -80,6 +90,24 @@ class DeviceOrientationManager { return 'PORTRAIT_UP'; } } + + /// Deserializes device orientation in [String] format into a + /// [DeviceOrientation]. + static DeviceOrientation deserializeDeviceOrientation(String orientation) { + switch (orientation) { + case 'LANDSCAPE_LEFT': + return DeviceOrientation.landscapeLeft; + case 'LANDSCAPE_RIGHT': + return DeviceOrientation.landscapeRight; + case 'PORTRAIT_DOWN': + return DeviceOrientation.portraitDown; + case 'PORTRAIT_UP': + return DeviceOrientation.portraitUp; + default: + throw ArgumentError( + '"$orientation" is not a valid DeviceOrientation value'); + } + } } /// Flutter API implementation of [DeviceOrientationManager]. @@ -96,26 +124,8 @@ class DeviceOrientationManagerFlutterApiImpl @override void onDeviceOrientationChanged(String orientation) { final DeviceOrientation deviceOrientation = - deserializeDeviceOrientation(orientation); + DeviceOrientationManager.deserializeDeviceOrientation(orientation); DeviceOrientationManager.deviceOrientationChangedStreamController .add(DeviceOrientationChangedEvent(deviceOrientation)); } - - /// Deserializes device orientation in [String] format into a - /// [DeviceOrientation]. - DeviceOrientation deserializeDeviceOrientation(String orientation) { - switch (orientation) { - case 'LANDSCAPE_LEFT': - return DeviceOrientation.landscapeLeft; - case 'LANDSCAPE_RIGHT': - return DeviceOrientation.landscapeRight; - case 'PORTRAIT_DOWN': - return DeviceOrientation.portraitDown; - case 'PORTRAIT_UP': - return DeviceOrientation.portraitUp; - default: - throw ArgumentError( - '"$orientation" is not a valid DeviceOrientation value'); - } - } } diff --git a/packages/camera/camera_android_camerax/lib/src/live_data.dart b/packages/camera/camera_android_camerax/lib/src/live_data.dart index 9659a2068eee..1931e8169ca1 100644 --- a/packages/camera/camera_android_camerax/lib/src/live_data.dart +++ b/packages/camera/camera_android_camerax/lib/src/live_data.dart @@ -185,7 +185,7 @@ class LiveDataFlutterApiImpl implements LiveDataFlutterApi { // This ignore statement is safe beause this error will be useful when // a new LiveDataSupportedType is being added, but the logic in this method // has not yet been updated. - // ignore: no_default_cases + // ignore: no_default_cases, unreachable_switch_default default: throw ArgumentError(LiveData.unsupportedLiveDataTypeErrorMessage); } diff --git a/packages/camera/camera_android_camerax/lib/src/system_services.dart b/packages/camera/camera_android_camerax/lib/src/system_services.dart index b75a1cb98035..5f59bd2f4c60 100644 --- a/packages/camera/camera_android_camerax/lib/src/system_services.dart +++ b/packages/camera/camera_android_camerax/lib/src/system_services.dart @@ -48,6 +48,21 @@ class SystemServices { SystemServicesHostApi(binaryMessenger: binaryMessenger); return api.getTempFilePath(prefix, suffix); } + + /// Returns whether or not the Android Surface used to display the camera + /// preview is backed by a SurfaceTexture, to which the transformation to + /// correctly rotate the preview has been applied. + /// + /// This is used to determine the correct rotation of the camera preview + /// because Surfaces not backed by a SurfaceTexture are not transformed by + /// CameraX to the expected rotation based on that of the device and must + /// be corrected by the plugin. + static Future isPreviewPreTransformed( + {BinaryMessenger? binaryMessenger}) { + final SystemServicesHostApi api = + SystemServicesHostApi(binaryMessenger: binaryMessenger); + return api.isPreviewPreTransformed(); + } } /// Host API implementation of [SystemServices]. diff --git a/packages/camera/camera_android_camerax/pigeons/camerax_library.dart b/packages/camera/camera_android_camerax/pigeons/camerax_library.dart index 872c3a622390..949830db3e83 100644 --- a/packages/camera/camera_android_camerax/pigeons/camerax_library.dart +++ b/packages/camera/camera_android_camerax/pigeons/camerax_library.dart @@ -260,6 +260,8 @@ abstract class SystemServicesHostApi { CameraPermissionsErrorData? requestCameraPermissions(bool enableAudio); String getTempFilePath(String prefix, String suffix); + + bool isPreviewPreTransformed(); } @FlutterApi() @@ -275,6 +277,8 @@ abstract class DeviceOrientationManagerHostApi { void stopListeningForDeviceOrientationChange(); int getDefaultDisplayRotation(); + + String getUiOrientation(); } @FlutterApi() @@ -562,6 +566,8 @@ abstract class Camera2CameraInfoHostApi { int getSupportedHardwareLevel(int identifier); String getCameraId(int identifier); + + int getSensorOrientation(int identifier); } @FlutterApi() diff --git a/packages/camera/camera_android_camerax/pubspec.yaml b/packages/camera/camera_android_camerax/pubspec.yaml index eb94986cbe9e..51d18c6aaa07 100644 --- a/packages/camera/camera_android_camerax/pubspec.yaml +++ b/packages/camera/camera_android_camerax/pubspec.yaml @@ -2,11 +2,11 @@ name: camera_android_camerax description: Android implementation of the camera plugin using the CameraX library. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_android_camerax issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.6.5+6 +version: 0.6.10 environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" flutter: plugin: @@ -31,7 +31,7 @@ dev_dependencies: sdk: flutter integration_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 pigeon: ^9.1.0 topics: diff --git a/packages/camera/camera_android_camerax/test/android_camera_camerax_test.dart b/packages/camera/camera_android_camerax/test/android_camera_camerax_test.dart index aa33254ac14a..1f9ea762ce23 100644 --- a/packages/camera/camera_android_camerax/test/android_camera_camerax_test.dart +++ b/packages/camera/camera_android_camerax/test/android_camera_camerax_test.dart @@ -50,7 +50,8 @@ import 'package:camera_android_camerax/src/zoom_state.dart'; import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:flutter/services.dart' show DeviceOrientation, PlatformException, Uint8List; -import 'package:flutter/widgets.dart' show BuildContext, Size, Texture, Widget; +import 'package:flutter/widgets.dart' + show BuildContext, RotatedBox, Size, Texture, Widget; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; @@ -197,6 +198,10 @@ void main() { (Size preferredResolution) => ResolutionFilter.onePreferredSizeDetached( preferredResolution: preferredResolution), + getCamera2CameraInfo: (_) => + Future.value(MockCamera2CameraInfo()), + getUiOrientation: () => + Future.value(DeviceOrientation.portraitUp), ); /// CameraXProxy for testing exposure and focus related controls. @@ -338,6 +343,10 @@ void main() { final MockCamera mockCamera = MockCamera(); final MockCameraInfo mockCameraInfo = MockCameraInfo(); final MockLiveCameraState mockLiveCameraState = MockLiveCameraState(); + final TestSystemServicesHostApi mockSystemServicesApi = + MockTestSystemServicesHostApi(); + TestSystemServicesHostApi.setup(mockSystemServicesApi); + bool cameraPermissionsRequested = false; bool startedListeningForDeviceOrientationChanges = false; @@ -385,6 +394,10 @@ void main() { }, createAspectRatioStrategy: (_, __) => MockAspectRatioStrategy(), createResolutionFilterWithOnePreferredSize: (_) => MockResolutionFilter(), + getCamera2CameraInfo: (_) => + Future.value(MockCamera2CameraInfo()), + getUiOrientation: () => + Future.value(DeviceOrientation.portraitUp), ); camera.processCameraProvider = mockProcessCameraProvider; @@ -467,6 +480,10 @@ void main() { final MockCamera mockCamera = MockCamera(); final MockCameraInfo mockCameraInfo = MockCameraInfo(); final MockCameraControl mockCameraControl = MockCameraControl(); + final MockCamera2CameraInfo mockCamera2CameraInfo = MockCamera2CameraInfo(); + final TestSystemServicesHostApi mockSystemServicesApi = + MockTestSystemServicesHostApi(); + TestSystemServicesHostApi.setup(mockSystemServicesApi); // Tell plugin to create mock/detached objects and stub method calls for the // testing of createCamera. @@ -507,6 +524,12 @@ void main() { startListeningForDeviceOrientationChange: (_, __) {}, createAspectRatioStrategy: (_, __) => MockAspectRatioStrategy(), createResolutionFilterWithOnePreferredSize: (_) => MockResolutionFilter(), + getCamera2CameraInfo: (CameraInfo cameraInfo) => + cameraInfo == mockCameraInfo + ? Future.value(mockCamera2CameraInfo) + : Future.value(MockCamera2CameraInfo()), + getUiOrientation: () => + Future.value(DeviceOrientation.portraitUp), ); when(mockProcessCameraProvider.bindToLifecycle(mockBackCameraSelector, @@ -517,6 +540,7 @@ void main() { .thenAnswer((_) async => MockLiveCameraState()); when(mockCamera.getCameraControl()) .thenAnswer((_) async => mockCameraControl); + camera.processCameraProvider = mockProcessCameraProvider; await camera.createCameraWithSettings( @@ -562,6 +586,9 @@ void main() { final MockProcessCameraProvider mockProcessCameraProvider = MockProcessCameraProvider(); final MockCameraInfo mockCameraInfo = MockCameraInfo(); + final TestSystemServicesHostApi mockSystemServicesApi = + MockTestSystemServicesHostApi(); + TestSystemServicesHostApi.setup(mockSystemServicesApi); // Tell plugin to create mock/detached objects for testing createCamera // as needed. @@ -893,6 +920,65 @@ void main() { expect(camera.recorder!.qualitySelector, isNull); }); + test( + 'createCamera sets sensor and device orientations needed to correct preview rotation as expected', + () async { + final AndroidCameraCameraX camera = AndroidCameraCameraX(); + const CameraLensDirection testLensDirection = CameraLensDirection.back; + const int testSensorOrientation = 270; + const CameraDescription testCameraDescription = CameraDescription( + name: 'cameraName', + lensDirection: testLensDirection, + sensorOrientation: testSensorOrientation); + const bool enableAudio = true; + const ResolutionPreset testResolutionPreset = ResolutionPreset.veryHigh; + const DeviceOrientation testUiOrientation = DeviceOrientation.portraitDown; + const DeviceOrientation testCurrentOrientation = + DeviceOrientation.portraitUp; + + // Mock/Detached objects for (typically attached) objects created by + // createCamera. + final MockCamera mockCamera = MockCamera(); + final MockProcessCameraProvider mockProcessCameraProvider = + MockProcessCameraProvider(); + final MockCameraInfo mockCameraInfo = MockCameraInfo(); + final TestSystemServicesHostApi mockSystemServicesApi = + MockTestSystemServicesHostApi(); + TestSystemServicesHostApi.setup(mockSystemServicesApi); + + // The proxy needed for this test is the same as testing resolution + // presets except for mocking the retrievall of the sensor and current + // UI orientation. + camera.proxy = + getProxyForTestingResolutionPreset(mockProcessCameraProvider); + camera.proxy.getSensorOrientation = + (_) async => Future.value(testSensorOrientation); + camera.proxy.getUiOrientation = + () async => Future.value(testUiOrientation); + + when(mockProcessCameraProvider.bindToLifecycle(any, any)) + .thenAnswer((_) async => mockCamera); + when(mockCamera.getCameraInfo()).thenAnswer((_) async => mockCameraInfo); + when(mockCameraInfo.getCameraState()) + .thenAnswer((_) async => MockLiveCameraState()); + + await camera.createCamera(testCameraDescription, testResolutionPreset, + enableAudio: enableAudio); + + const DeviceOrientationChangedEvent testEvent = + DeviceOrientationChangedEvent(testCurrentOrientation); + + DeviceOrientationManager.deviceOrientationChangedStreamController + .add(testEvent); + + // Wait for currentDeviceOrientation to update. + await Future.value(); + + expect(camera.naturalOrientation, testUiOrientation); + expect(camera.sensorOrientation, testSensorOrientation); + expect(camera.currentDeviceOrientation, testCurrentOrientation); + }); + test( 'initializeCamera throws a CameraException when createCamera has not been called before initializedCamera', () async { @@ -927,6 +1013,9 @@ void main() { final MockPreview mockPreview = MockPreview(); final MockImageCapture mockImageCapture = MockImageCapture(); final MockImageAnalysis mockImageAnalysis = MockImageAnalysis(); + final TestSystemServicesHostApi mockSystemServicesApi = + MockTestSystemServicesHostApi(); + TestSystemServicesHostApi.setup(mockSystemServicesApi); // Tell plugin to create mock/detached objects for testing createCamera // as needed. @@ -967,6 +1056,10 @@ void main() { startListeningForDeviceOrientationChange: (_, __) {}, createAspectRatioStrategy: (_, __) => MockAspectRatioStrategy(), createResolutionFilterWithOnePreferredSize: (_) => MockResolutionFilter(), + getCamera2CameraInfo: (_) => + Future.value(MockCamera2CameraInfo()), + getUiOrientation: () => + Future.value(DeviceOrientation.portraitUp), ); final CameraInitializedEvent testCameraInitializedEvent = @@ -1234,7 +1327,7 @@ void main() { }); test( - 'buildPreview returns a Texture once the preview is bound to the lifecycle', + 'buildPreview returns a Texture once the preview is bound to the lifecycle if it is backed by a SurfaceTexture', () async { final AndroidCameraCameraX camera = AndroidCameraCameraX(); const int cameraId = 37; @@ -1243,12 +1336,148 @@ void main() { // bound to the lifecycle of the camera. camera.previewInitiallyBound = true; + // Tell camera the Surface used to build camera preview is backed by a + // SurfaceTexture. + camera.isPreviewPreTransformed = true; + + camera.naturalOrientation = DeviceOrientation.portraitDown; + final Widget widget = camera.buildPreview(cameraId); expect(widget is Texture, isTrue); expect((widget as Texture).textureId, cameraId); }); + test( + 'buildPreview returns preview with expected rotation if camera is not front facing and the preview is not backed by a SurfaceTexture', + () async { + final AndroidCameraCameraX camera = AndroidCameraCameraX(); + const int cameraId = 33; + + // Tell camera that createCamera has been called and thus, preview has been + // bound to the lifecycle of the camera. + camera.previewInitiallyBound = true; + + // Tell camera the Surface used to build camera preview is not backed by a + // SurfaceTexture. + camera.isPreviewPreTransformed = false; + + // Mock sensor and device orientation. + camera.sensorOrientation = 270; + camera.cameraIsFrontFacing = false; + camera.naturalOrientation = DeviceOrientation.portraitUp; + + final double expectedRotation = (camera.sensorOrientation + + 0 /* the natural orientation in clockwise degrees */ * + -1 /* camera is not front facing */ + + 360) % + 360; + final int expectedQuarterTurns = (expectedRotation / 90).toInt(); + + final Widget widget = camera.buildPreview(cameraId); + + expect(widget is RotatedBox, isTrue); + expect((widget as RotatedBox).quarterTurns, expectedQuarterTurns); + expect(widget.child is Texture, isTrue); + expect((widget.child! as Texture).textureId, cameraId); + }); + + test( + 'buildPreview returns preview with expected rotation if camera is front facing, the current orientation is landscape, and the preview is not backed by a SurfaceTexture', + () async { + final AndroidCameraCameraX camera = AndroidCameraCameraX(); + const int cameraId = 7; + + // Tell camera that createCamera has been called and thus, preview has been + // bound to the lifecycle of the camera. + camera.previewInitiallyBound = true; + + // Tell camera the Surface used to build camera preview is not backed by a + // SurfaceTexture. + camera.isPreviewPreTransformed = false; + + // Mock sensor and device orientation. + camera.sensorOrientation = 270; + camera.naturalOrientation = DeviceOrientation.portraitUp; + camera.cameraIsFrontFacing = true; + + // Calculate expected rotation with offset due to counter-clockwise rotation + // of the image with th efront camera in use. + final double expectedRotation = ((camera.sensorOrientation + + 0 /* the natural orientation in clockwise degrees */ * + 1 /* camera is front facing */ + + 360) % + 360) + + 180; + final int expectedQuarterTurns = (expectedRotation / 90).toInt() % 4; + + // Test landscape left. + camera.currentDeviceOrientation = DeviceOrientation.landscapeLeft; + Widget widget = camera.buildPreview(cameraId); + + expect(widget is RotatedBox, isTrue); + expect((widget as RotatedBox).quarterTurns, expectedQuarterTurns); + expect(widget.child is Texture, isTrue); + expect((widget.child! as Texture).textureId, cameraId); + + // Test landscape right. + camera.currentDeviceOrientation = DeviceOrientation.landscapeRight; + widget = camera.buildPreview(cameraId); + + expect(widget is RotatedBox, isTrue); + expect((widget as RotatedBox).quarterTurns, expectedQuarterTurns); + expect(widget.child is Texture, isTrue); + expect((widget.child! as Texture).textureId, cameraId); + }); + + test( + 'buildPreview returns preview with expected rotation if camera is front facing, the current orientation is not landscape, and the preview is not backed by a SurfaceTexture', + () async { + final AndroidCameraCameraX camera = AndroidCameraCameraX(); + const int cameraId = 733; + + // Tell camera that createCamera has been called and thus, preview has been + // bound to the lifecycle of the camera. + camera.previewInitiallyBound = true; + + // Tell camera the Surface used to build camera preview is not backed by a + // SurfaceTexture. + camera.isPreviewPreTransformed = false; + + // Mock sensor and device orientation. + camera.sensorOrientation = 270; + camera.naturalOrientation = DeviceOrientation.portraitUp; + camera.cameraIsFrontFacing = true; + + // Calculate expected rotation without offset needed for landscape orientations + // due to counter-clockwise rotation of the image with th efront camera in use. + final double expectedRotation = (camera.sensorOrientation + + 0 /* the natural orientation in clockwise degrees */ * + 1 /* camera is front facing */ + + 360) % + 360; + + final int expectedQuarterTurns = (expectedRotation / 90).toInt() % 4; + + // Test portrait up. + camera.currentDeviceOrientation = DeviceOrientation.portraitUp; + Widget widget = camera.buildPreview(cameraId); + + expect(widget is RotatedBox, isTrue); + expect((widget as RotatedBox).quarterTurns, expectedQuarterTurns); + expect(widget.child is Texture, isTrue); + expect((widget.child! as Texture).textureId, cameraId); + + // Test portrait down. + camera.currentDeviceOrientation = DeviceOrientation.portraitDown; + widget = camera.buildPreview(cameraId); + + expect(widget is RotatedBox, isTrue); + expect((widget as RotatedBox).quarterTurns, expectedQuarterTurns); + expect(widget.child is Texture, isTrue); + expect((widget.child! as Texture).textureId, cameraId); + }); + group('video recording', () { test( 'startVideoCapturing binds video capture use case, updates saved camera instance and its properties, and starts the recording', diff --git a/packages/camera/camera_android_camerax/test/android_camera_camerax_test.mocks.dart b/packages/camera/camera_android_camerax/test/android_camera_camerax_test.mocks.dart index 0bdfc06af92b..316b12759692 100644 --- a/packages/camera/camera_android_camerax/test/android_camera_camerax_test.mocks.dart +++ b/packages/camera/camera_android_camerax/test/android_camera_camerax_test.mocks.dart @@ -729,6 +729,16 @@ class MockCamera2CameraInfo extends _i1.Mock implements _i26.Camera2CameraInfo { ), )), ) as _i17.Future); + + @override + _i17.Future getSensorOrientation() => (super.noSuchMethod( + Invocation.method( + #getSensorOrientation, + [], + ), + returnValue: _i17.Future.value(0), + returnValueForMissingStub: _i17.Future.value(0), + ) as _i17.Future); } /// A class which mocks [CameraImageData]. @@ -1400,6 +1410,16 @@ class MockTestSystemServicesHostApi extends _i1.Mock ), ), ) as String); + + @override + bool isPreviewPreTransformed() => (super.noSuchMethod( + Invocation.method( + #isPreviewPreTransformed, + [], + ), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); } /// A class which mocks [VideoCapture]. diff --git a/packages/camera/camera_android_camerax/test/camera2_camera_info_test.mocks.dart b/packages/camera/camera_android_camerax/test/camera2_camera_info_test.mocks.dart index 9060c51874ac..88b219f28cf1 100644 --- a/packages/camera/camera_android_camerax/test/camera2_camera_info_test.mocks.dart +++ b/packages/camera/camera_android_camerax/test/camera2_camera_info_test.mocks.dart @@ -90,6 +90,15 @@ class MockTestCamera2CameraInfoHostApi extends _i1.Mock ), ), ) as String); + + @override + int getSensorOrientation(int? identifier) => (super.noSuchMethod( + Invocation.method( + #getSensorOrientation, + [identifier], + ), + returnValue: 0, + ) as int); } /// A class which mocks [TestInstanceManagerHostApi]. diff --git a/packages/camera/camera_android_camerax/test/capture_request_options_test.dart b/packages/camera/camera_android_camerax/test/capture_request_options_test.dart index 3649369c934b..5649151af92b 100644 --- a/packages/camera/camera_android_camerax/test/capture_request_options_test.dart +++ b/packages/camera/camera_android_camerax/test/capture_request_options_test.dart @@ -132,7 +132,7 @@ void main() { // This ignore statement is safe beause this will test when // a new CaptureRequestKeySupportedType is being added, but the logic in // in the CaptureRequestOptions class has not yet been updated. - // ignore: no_default_cases + // ignore: no_default_cases, unreachable_switch_default default: fail( 'Option $option contains unrecognized CaptureRequestKeySupportedType key ${option.$1}'); diff --git a/packages/camera/camera_android_camerax/test/device_orientation_manager_test.dart b/packages/camera/camera_android_camerax/test/device_orientation_manager_test.dart index de24bb0b3f45..2555302f4092 100644 --- a/packages/camera/camera_android_camerax/test/device_orientation_manager_test.dart +++ b/packages/camera/camera_android_camerax/test/device_orientation_manager_test.dart @@ -61,6 +61,20 @@ void main() { verify(mockApi.getDefaultDisplayRotation()); }); + test('getUiOrientation returns expected orientation', () async { + final MockTestDeviceOrientationManagerHostApi mockApi = + MockTestDeviceOrientationManagerHostApi(); + TestDeviceOrientationManagerHostApi.setup(mockApi); + const DeviceOrientation expectedOrientation = + DeviceOrientation.landscapeRight; + + when(mockApi.getUiOrientation()).thenReturn('LANDSCAPE_RIGHT'); + + expect(await DeviceOrientationManager.getUiOrientation(), + equals(expectedOrientation)); + verify(mockApi.getUiOrientation()); + }); + test('onDeviceOrientationChanged adds new orientation to stream', () { DeviceOrientationManager.deviceOrientationChangedStreamController.stream .listen((DeviceOrientationChangedEvent event) { diff --git a/packages/camera/camera_android_camerax/test/device_orientation_manager_test.mocks.dart b/packages/camera/camera_android_camerax/test/device_orientation_manager_test.mocks.dart index 6f74ad42958d..9d166bc39e19 100644 --- a/packages/camera/camera_android_camerax/test/device_orientation_manager_test.mocks.dart +++ b/packages/camera/camera_android_camerax/test/device_orientation_manager_test.mocks.dart @@ -4,6 +4,7 @@ // ignore_for_file: no_leading_underscores_for_library_prefixes import 'package:mockito/mockito.dart' as _i1; +import 'package:mockito/src/dummies.dart' as _i3; import 'test_camerax_library.g.dart' as _i2; @@ -81,4 +82,19 @@ class MockTestDeviceOrientationManagerHostApi extends _i1.Mock ), returnValue: 0, ) as int); + + @override + String getUiOrientation() => (super.noSuchMethod( + Invocation.method( + #getUiOrientation, + [], + ), + returnValue: _i3.dummyValue( + this, + Invocation.method( + #getUiOrientation, + [], + ), + ), + ) as String); } diff --git a/packages/camera/camera_android_camerax/test/system_services_test.dart b/packages/camera/camera_android_camerax/test/system_services_test.dart index 030f9aee5b26..d1725515e2f8 100644 --- a/packages/camera/camera_android_camerax/test/system_services_test.dart +++ b/packages/camera/camera_android_camerax/test/system_services_test.dart @@ -85,4 +85,16 @@ void main() { verify(mockApi.getTempFilePath(testPrefix, testSuffix)); }); }); + + test('isPreviewPreTransformed returns expected answer', () async { + final MockTestSystemServicesHostApi mockApi = + MockTestSystemServicesHostApi(); + TestSystemServicesHostApi.setup(mockApi); + const bool isPreviewPreTransformed = true; + + when(mockApi.isPreviewPreTransformed()).thenReturn(isPreviewPreTransformed); + + expect(await SystemServices.isPreviewPreTransformed(), isTrue); + verify(mockApi.isPreviewPreTransformed()); + }); } diff --git a/packages/camera/camera_android_camerax/test/system_services_test.mocks.dart b/packages/camera/camera_android_camerax/test/system_services_test.mocks.dart index ec97625adb94..9abb64c39bb4 100644 --- a/packages/camera/camera_android_camerax/test/system_services_test.mocks.dart +++ b/packages/camera/camera_android_camerax/test/system_services_test.mocks.dart @@ -87,4 +87,13 @@ class MockTestSystemServicesHostApi extends _i1.Mock ), ), ) as String); + + @override + bool isPreviewPreTransformed() => (super.noSuchMethod( + Invocation.method( + #isPreviewPreTransformed, + [], + ), + returnValue: false, + ) as bool); } diff --git a/packages/camera/camera_android_camerax/test/test_camerax_library.g.dart b/packages/camera/camera_android_camerax/test/test_camerax_library.g.dart index 105447e52689..32235b878f39 100644 --- a/packages/camera/camera_android_camerax/test/test_camerax_library.g.dart +++ b/packages/camera/camera_android_camerax/test/test_camerax_library.g.dart @@ -510,6 +510,8 @@ abstract class TestSystemServicesHostApi { String getTempFilePath(String prefix, String suffix); + bool isPreviewPreTransformed(); + static void setup(TestSystemServicesHostApi? api, {BinaryMessenger? binaryMessenger}) { { @@ -561,6 +563,24 @@ abstract class TestSystemServicesHostApi { }); } } + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.SystemServicesHostApi.isPreviewPreTransformed', + codec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { + // ignore message + final bool output = api.isPreviewPreTransformed(); + return [output]; + }); + } + } } } @@ -576,6 +596,8 @@ abstract class TestDeviceOrientationManagerHostApi { int getDefaultDisplayRotation(); + String getUiOrientation(); + static void setup(TestDeviceOrientationManagerHostApi? api, {BinaryMessenger? binaryMessenger}) { { @@ -641,6 +663,24 @@ abstract class TestDeviceOrientationManagerHostApi { }); } } + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.DeviceOrientationManagerHostApi.getUiOrientation', + codec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { + // ignore message + final String output = api.getUiOrientation(); + return [output]; + }); + } + } } } @@ -2445,6 +2485,8 @@ abstract class TestCamera2CameraInfoHostApi { String getCameraId(int identifier); + int getSensorOrientation(int identifier); + static void setup(TestCamera2CameraInfoHostApi? api, {BinaryMessenger? binaryMessenger}) { { @@ -2514,5 +2556,28 @@ abstract class TestCamera2CameraInfoHostApi { }); } } + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.Camera2CameraInfoHostApi.getSensorOrientation', + codec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.Camera2CameraInfoHostApi.getSensorOrientation was null.'); + final List args = (message as List?)!; + final int? arg_identifier = (args[0] as int?); + assert(arg_identifier != null, + 'Argument for dev.flutter.pigeon.Camera2CameraInfoHostApi.getSensorOrientation was null, expected non-null int.'); + final int output = api.getSensorOrientation(arg_identifier!); + return [output]; + }); + } + } } } diff --git a/packages/camera/camera_avfoundation/CHANGELOG.md b/packages/camera/camera_avfoundation/CHANGELOG.md index 5012f7d965b4..a1b18e61ed4c 100644 --- a/packages/camera/camera_avfoundation/CHANGELOG.md +++ b/packages/camera/camera_avfoundation/CHANGELOG.md @@ -1,3 +1,40 @@ +## 0.9.17+5 + +* Adds ability to use any supported FPS and fixes crash when using unsupported FPS. + +## 0.9.17+4 + +* Updates Pigeon for non-nullable collection type support. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + +## 0.9.17+3 + +* Fixes deallocation of camera on dispose. + +## 0.9.17+2 + +* Fixes stopVideoRecording waiting indefinitely and lag at start of video. + +## 0.9.17+1 + +* Fixes a crash due to appending sample buffers when readyForMoreMediaData is NO. + +## 0.9.17 + +* Adds Swift Package Manager compatibility. + +## 0.9.16+3 + +* Removes unused `maxVideoDuration` code. + +## 0.9.16+2 + +* Fixes regression taking a picture in torch mode. + +## 0.9.16+1 + +* Fixes sample times not being numeric after pause/resume. + ## 0.9.16 * Converts Dart-to-host communcation to Pigeon. diff --git a/packages/camera/camera_avfoundation/README.md b/packages/camera/camera_avfoundation/README.md index 970450c59da6..459211b046cb 100644 --- a/packages/camera/camera_avfoundation/README.md +++ b/packages/camera/camera_avfoundation/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/camera -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/camera/camera_avfoundation/example/ios/Podfile b/packages/camera/camera_avfoundation/example/ios/Podfile index d20d11ee5ab9..bcdae34190c9 100644 --- a/packages/camera/camera_avfoundation/example/ios/Podfile +++ b/packages/camera/camera_avfoundation/example/ios/Podfile @@ -32,8 +32,6 @@ target 'Runner' do target 'RunnerTests' do inherit! :search_paths - # Pods for testing - pod 'OCMock', '~> 3.8.1' end end diff --git a/packages/camera/camera_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj b/packages/camera/camera_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj index 3ca0527f6015..3a1ce1ee25e2 100644 --- a/packages/camera/camera_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/camera/camera_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj @@ -14,6 +14,7 @@ 25C3919135C3D981E6F800D0 /* libPods-RunnerTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1944D8072499F3B5E7653D44 /* libPods-RunnerTests.a */; }; 334733EA2668111C00DCC49E /* CameraOrientationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 03BB767226653ABE00CE5A93 /* CameraOrientationTests.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 408D7A792C3C9CD000B71F9A /* OCMock in Frameworks */ = {isa = PBXBuildFile; productRef = 408D7A782C3C9CD000B71F9A /* OCMock */; }; 43ED1537282570DE00EB00DE /* AvailableCamerasTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 43ED1536282570DE00EB00DE /* AvailableCamerasTest.m */; }; 788A065A27B0E02900533D74 /* StreamingTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 788A065927B0E02900533D74 /* StreamingTest.m */; }; 7D5FCCD42AEF9D0200FB7108 /* CameraSettingsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D5FCCD32AEF9D0200FB7108 /* CameraSettingsTests.m */; }; @@ -106,6 +107,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 408D7A792C3C9CD000B71F9A /* OCMock in Frameworks */, 25C3919135C3D981E6F800D0 /* libPods-RunnerTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -241,6 +243,9 @@ 03BB766E2665316900CE5A93 /* PBXTargetDependency */, ); name = RunnerTests; + packageProductDependencies = ( + 408D7A782C3C9CD000B71F9A /* OCMock */, + ); productName = camera_exampleTests; productReference = 03BB76682665316900CE5A93 /* RunnerTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; @@ -295,6 +300,9 @@ Base, ); mainGroup = 97C146E51CF9000F007C117D; + packageReferences = ( + 408D7A772C3C9CD000B71F9A /* XCRemoteSwiftPackageReference "ocmock" */, + ); productRefGroup = 97C146EF1CF9000F007C117D /* Products */; projectDirPath = ""; projectRoot = ""; @@ -733,6 +741,25 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 408D7A772C3C9CD000B71F9A /* XCRemoteSwiftPackageReference "ocmock" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/erikdoe/ocmock"; + requirement = { + kind = revision; + revision = fe1661a3efed11831a6452f4b1a0c5e6ddc08c3d; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 408D7A782C3C9CD000B71F9A /* OCMock */ = { + isa = XCSwiftPackageProductDependency; + package = 408D7A772C3C9CD000B71F9A /* XCRemoteSwiftPackageReference "ocmock" */; + productName = OCMock; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 97C146E61CF9000F007C117D /* Project object */; } diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/AvailableCamerasTest.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/AvailableCamerasTest.m index af7855afa857..f26a8dc48f16 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/AvailableCamerasTest.m +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/AvailableCamerasTest.m @@ -3,7 +3,9 @@ // found in the LICENSE file. @import camera_avfoundation; +#if __has_include() @import camera_avfoundation.Test; +#endif @import XCTest; @import AVFoundation; #import diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraCaptureSessionQueueRaceConditionTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraCaptureSessionQueueRaceConditionTests.m index 226d6bfb1a5a..5892e1d4b797 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraCaptureSessionQueueRaceConditionTests.m +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraCaptureSessionQueueRaceConditionTests.m @@ -3,7 +3,9 @@ // found in the LICENSE file. @import camera_avfoundation; +#if __has_include() @import camera_avfoundation.Test; +#endif @import XCTest; @interface CameraCaptureSessionQueueRaceConditionTests : XCTestCase diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraFocusTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraFocusTests.m index d13f5a77ceda..0cb8333345ab 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraFocusTests.m +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraFocusTests.m @@ -3,7 +3,9 @@ // found in the LICENSE file. @import camera_avfoundation; +#if __has_include() @import camera_avfoundation.Test; +#endif @import XCTest; @import AVFoundation; #import diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraMethodChannelTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraMethodChannelTests.m index 55fc44e10cb8..4df1994699df 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraMethodChannelTests.m +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraMethodChannelTests.m @@ -3,7 +3,9 @@ // found in the LICENSE file. @import camera_avfoundation; +#if __has_include() @import camera_avfoundation.Test; +#endif @import XCTest; @import AVFoundation; #import @@ -48,4 +50,42 @@ - (void)testCreate_ShouldCallResultOnMainThread { XCTAssertNotNil(resultValue); } +- (void)testDisposeShouldDeallocCamera { + CameraPlugin *camera = [[CameraPlugin alloc] initWithRegistry:nil messenger:nil]; + + id avCaptureDeviceInputMock = OCMClassMock([AVCaptureDeviceInput class]); + OCMStub([avCaptureDeviceInputMock deviceInputWithDevice:[OCMArg any] error:[OCMArg anyObjectRef]]) + .andReturn([AVCaptureInput alloc]); + + id avCaptureSessionMock = OCMClassMock([AVCaptureSession class]); + OCMStub([avCaptureSessionMock alloc]).andReturn(avCaptureSessionMock); + OCMStub([avCaptureSessionMock canSetSessionPreset:[OCMArg any]]).andReturn(YES); + + XCTestExpectation *createExpectation = + [self expectationWithDescription:@"create's result block must be called"]; + [camera createCameraOnSessionQueueWithName:@"acamera" + settings:[FCPPlatformMediaSettings + makeWithResolutionPreset: + FCPPlatformResolutionPresetMedium + framesPerSecond:nil + videoBitrate:nil + audioBitrate:nil + enableAudio:YES] + completion:^(NSNumber *_Nullable result, + FlutterError *_Nullable error) { + [createExpectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:30 handler:nil]; + XCTAssertNotNil(camera.camera); + + XCTestExpectation *disposeExpectation = + [self expectationWithDescription:@"dispose's result block must be called"]; + [camera disposeCamera:0 + completion:^(FlutterError *_Nullable error) { + [disposeExpectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:30 handler:nil]; + XCTAssertNil(camera.camera, @"camera should be deallocated after dispose"); +} + @end diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraOrientationTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraOrientationTests.m index 57787a968a2d..e6ce8d48bc5b 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraOrientationTests.m +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraOrientationTests.m @@ -3,7 +3,9 @@ // found in the LICENSE file. @import camera_avfoundation; +#if __has_include() @import camera_avfoundation.Test; +#endif @import XCTest; @import Flutter; diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPermissionTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPermissionTests.m index 24ca5b6525c9..02a610affaa5 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPermissionTests.m +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPermissionTests.m @@ -3,7 +3,9 @@ // found in the LICENSE file. @import camera_avfoundation; +#if __has_include() @import camera_avfoundation.Test; +#endif @import AVFoundation; @import XCTest; #import diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPreviewPauseTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPreviewPauseTests.m index 96ae19ff14d0..04bdd0795dab 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPreviewPauseTests.m +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPreviewPauseTests.m @@ -3,7 +3,9 @@ // found in the LICENSE file. @import camera_avfoundation; +#if __has_include() @import camera_avfoundation.Test; +#endif @import XCTest; @import AVFoundation; #import diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPropertiesTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPropertiesTests.m index 5b865d464dc9..6778efb4132f 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPropertiesTests.m +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPropertiesTests.m @@ -3,7 +3,9 @@ // found in the LICENSE file. @import camera_avfoundation; +#if __has_include() @import camera_avfoundation.Test; +#endif @import AVFoundation; @import XCTest; diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSessionPresetsTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSessionPresetsTests.m index 28f8d5de4e93..08cba70bf3a2 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSessionPresetsTests.m +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSessionPresetsTests.m @@ -3,7 +3,9 @@ // found in the LICENSE file. @import camera_avfoundation; +#if __has_include() @import camera_avfoundation.Test; +#endif @import AVFoundation; @import XCTest; diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSettingsTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSettingsTests.m index 1962a6b74579..9bed6bea4883 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSettingsTests.m +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSettingsTests.m @@ -3,7 +3,9 @@ // found in the LICENSE file. @import camera_avfoundation; +#if __has_include() @import camera_avfoundation.Test; +#endif @import XCTest; @import AVFoundation; #import @@ -142,7 +144,7 @@ - (void)testSettings_shouldPassConfigurationToCameraDeviceAndWriter { [[TestMediaSettingsAVWrapper alloc] initWithTestCase:self]; FLTCam *camera = FLTCreateCamWithCaptureSessionQueueAndMediaSettings( - dispatch_queue_create("test", NULL), settings, injectedWrapper); + dispatch_queue_create("test", NULL), settings, injectedWrapper, nil); // Expect FPS configuration is passed to camera device. [self waitForExpectations:@[ @@ -200,4 +202,20 @@ - (void)testSettings_ShouldBeSupportedByMethodCall { XCTAssertNotNil(resultValue); } +- (void)testSettings_ShouldSelectFormatWhichSupports60FPS { + FCPPlatformMediaSettings *settings = + [FCPPlatformMediaSettings makeWithResolutionPreset:gTestResolutionPreset + framesPerSecond:@(60) + videoBitrate:@(gTestVideoBitrate) + audioBitrate:@(gTestAudioBitrate) + enableAudio:gTestEnableAudio]; + + FLTCam *camera = FLTCreateCamWithCaptureSessionQueueAndMediaSettings( + dispatch_queue_create("test", NULL), settings, nil, nil); + + AVFrameRateRange *range = camera.captureDevice.activeFormat.videoSupportedFrameRateRanges[0]; + XCTAssertLessThanOrEqual(range.minFrameRate, 60); + XCTAssertGreaterThanOrEqual(range.maxFrameRate, 60); +} + @end diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraTestUtils.h b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraTestUtils.h index eded154995ec..2bbb56c51a79 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraTestUtils.h +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraTestUtils.h @@ -3,7 +3,9 @@ // found in the LICENSE file. @import camera_avfoundation; +#if __has_include() @import camera_avfoundation.Test; +#endif NS_ASSUME_NONNULL_BEGIN @@ -12,11 +14,13 @@ NS_ASSUME_NONNULL_BEGIN /// @param mediaSettings media settings configuration parameters /// @param mediaSettingsAVWrapper provider to perform media settings operations (for unit test /// dependency injection). +/// @param captureDeviceFactory a callback to create capture device instances /// @return an FLTCam object. extern FLTCam *_Nullable FLTCreateCamWithCaptureSessionQueueAndMediaSettings( dispatch_queue_t _Nullable captureSessionQueue, FCPPlatformMediaSettings *_Nullable mediaSettings, - FLTCamMediaSettingsAVWrapper *_Nullable mediaSettingsAVWrapper); + FLTCamMediaSettingsAVWrapper *_Nullable mediaSettingsAVWrapper, + CaptureDeviceFactory _Nullable captureDeviceFactory); extern FLTCam *FLTCreateCamWithCaptureSessionQueue(dispatch_queue_t captureSessionQueue); diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraTestUtils.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraTestUtils.m index 0dac5c4a59bf..503a5c255c59 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraTestUtils.m +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraTestUtils.m @@ -18,12 +18,13 @@ } FLTCam *FLTCreateCamWithCaptureSessionQueue(dispatch_queue_t captureSessionQueue) { - return FLTCreateCamWithCaptureSessionQueueAndMediaSettings(captureSessionQueue, nil, nil); + return FLTCreateCamWithCaptureSessionQueueAndMediaSettings(captureSessionQueue, nil, nil, nil); } FLTCam *FLTCreateCamWithCaptureSessionQueueAndMediaSettings( dispatch_queue_t captureSessionQueue, FCPPlatformMediaSettings *mediaSettings, - FLTCamMediaSettingsAVWrapper *mediaSettingsAVWrapper) { + FLTCamMediaSettingsAVWrapper *mediaSettingsAVWrapper, + CaptureDeviceFactory captureDeviceFactory) { if (!mediaSettings) { mediaSettings = FCPGetDefaultMediaSettings(FCPPlatformResolutionPresetMedium); } @@ -51,14 +52,49 @@ OCMStub([audioSessionMock addInputWithNoConnections:[OCMArg any]]); OCMStub([audioSessionMock canSetSessionPreset:[OCMArg any]]).andReturn(YES); - id fltCam = [[FLTCam alloc] initWithCameraName:@"camera" - mediaSettings:mediaSettings - mediaSettingsAVWrapper:mediaSettingsAVWrapper - orientation:UIDeviceOrientationPortrait + id frameRateRangeMock1 = OCMClassMock([AVFrameRateRange class]); + OCMStub([frameRateRangeMock1 minFrameRate]).andReturn(3); + OCMStub([frameRateRangeMock1 maxFrameRate]).andReturn(30); + id captureDeviceFormatMock1 = OCMClassMock([AVCaptureDeviceFormat class]); + OCMStub([captureDeviceFormatMock1 videoSupportedFrameRateRanges]).andReturn(@[ + frameRateRangeMock1 + ]); + + id frameRateRangeMock2 = OCMClassMock([AVFrameRateRange class]); + OCMStub([frameRateRangeMock2 minFrameRate]).andReturn(3); + OCMStub([frameRateRangeMock2 maxFrameRate]).andReturn(60); + id captureDeviceFormatMock2 = OCMClassMock([AVCaptureDeviceFormat class]); + OCMStub([captureDeviceFormatMock2 videoSupportedFrameRateRanges]).andReturn(@[ + frameRateRangeMock2 + ]); + + id captureDeviceMock = OCMClassMock([AVCaptureDevice class]); + OCMStub([captureDeviceMock lockForConfiguration:[OCMArg setTo:nil]]).andReturn(YES); + OCMStub([captureDeviceMock formats]).andReturn((@[ + captureDeviceFormatMock1, captureDeviceFormatMock2 + ])); + __block AVCaptureDeviceFormat *format = captureDeviceFormatMock1; + OCMStub([captureDeviceMock setActiveFormat:[OCMArg any]]).andDo(^(NSInvocation *invocation) { + [invocation retainArguments]; + [invocation getArgument:&format atIndex:2]; + }); + OCMStub([captureDeviceMock activeFormat]).andDo(^(NSInvocation *invocation) { + [invocation setReturnValue:&format]; + }); + + id fltCam = [[FLTCam alloc] initWithMediaSettings:mediaSettings + mediaSettingsAVWrapper:mediaSettingsAVWrapper + orientation:UIDeviceOrientationPortrait videoCaptureSession:videoSessionMock audioCaptureSession:audioSessionMock captureSessionQueue:captureSessionQueue - error:nil]; + captureDeviceFactory:captureDeviceFactory ?: ^AVCaptureDevice *(void) { + return captureDeviceMock; + } + videoDimensionsForFormat:^CMVideoDimensions(AVCaptureDeviceFormat *format) { + return CMVideoFormatDescriptionGetDimensions(format.formatDescription); + } + error:nil]; id captureVideoDataOutputMock = [OCMockObject niceMockForClass:[AVCaptureVideoDataOutput class]]; diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamPhotoCaptureTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamPhotoCaptureTests.m index f81625f849f5..7f17e39a6b0b 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamPhotoCaptureTests.m +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamPhotoCaptureTests.m @@ -3,7 +3,9 @@ // found in the LICENSE file. @import camera_avfoundation; +#if __has_include() @import camera_avfoundation.Test; +#endif @import AVFoundation; @import XCTest; #import @@ -169,4 +171,56 @@ - (void)testCaptureToFile_mustReportFileExtensionWithJpgWhenHEVCNotAvailableAndF }); [self waitForExpectationsWithTimeout:1 handler:nil]; } + +- (void)testCaptureToFile_handlesTorchMode { + XCTestExpectation *pathExpectation = + [self expectationWithDescription: + @"Must send file path to result if save photo delegate completes with file path."]; + + id captureDeviceMock = OCMClassMock([AVCaptureDevice class]); + OCMStub([captureDeviceMock hasTorch]).andReturn(YES); + OCMStub([captureDeviceMock isTorchAvailable]).andReturn(YES); + OCMStub([captureDeviceMock torchMode]).andReturn(AVCaptureTorchModeAuto); + OCMExpect([captureDeviceMock setTorchMode:AVCaptureTorchModeOn]); + + dispatch_queue_t captureSessionQueue = dispatch_queue_create("capture_session_queue", NULL); + dispatch_queue_set_specific(captureSessionQueue, FLTCaptureSessionQueueSpecific, + (void *)FLTCaptureSessionQueueSpecific, NULL); + + FLTCam *cam = FLTCreateCamWithCaptureSessionQueueAndMediaSettings(captureSessionQueue, nil, nil, + ^AVCaptureDevice *(void) { + return captureDeviceMock; + }); + + AVCapturePhotoSettings *settings = [AVCapturePhotoSettings photoSettings]; + id mockSettings = OCMClassMock([AVCapturePhotoSettings class]); + OCMStub([mockSettings photoSettings]).andReturn(settings); + + NSString *filePath = @"test"; + + id mockOutput = OCMClassMock([AVCapturePhotoOutput class]); + OCMStub([mockOutput capturePhotoWithSettings:OCMOCK_ANY delegate:OCMOCK_ANY]) + .andDo(^(NSInvocation *invocation) { + FLTSavePhotoDelegate *delegate = cam.inProgressSavePhotoDelegates[@(settings.uniqueID)]; + // Completion runs on IO queue. + dispatch_queue_t ioQueue = dispatch_queue_create("io_queue", NULL); + dispatch_async(ioQueue, ^{ + delegate.completionHandler(filePath, nil); + }); + }); + cam.capturePhotoOutput = mockOutput; + + // `FLTCam::captureToFile` runs on capture session queue. + dispatch_async(captureSessionQueue, ^{ + [cam setFlashMode:FCPPlatformFlashModeTorch + withCompletion:^(FlutterError *_){ + }]; + [cam captureToFileWithCompletion:^(NSString *result, FlutterError *error) { + XCTAssertEqual(result, filePath); + [pathExpectation fulfill]; + }]; + }); + [self waitForExpectationsWithTimeout:1 handler:nil]; + OCMVerifyAll(captureDeviceMock); +} @end diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSampleBufferTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSampleBufferTests.m index cba488dfe5b4..b6b78f2dab28 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSampleBufferTests.m +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSampleBufferTests.m @@ -3,7 +3,9 @@ // found in the LICENSE file. @import camera_avfoundation; +#if __has_include() @import camera_avfoundation.Test; +#endif @import AVFoundation; @import XCTest; #import @@ -92,22 +94,21 @@ - (void)testDidOutputSampleBufferIgnoreAudioSamplesBeforeVideoSamples { __block NSArray *writtenSamples = @[]; - id videoMock = OCMClassMock([AVAssetWriterInputPixelBufferAdaptor class]); - OCMStub([videoMock assetWriterInputPixelBufferAdaptorWithAssetWriterInput:OCMOCK_ANY - sourcePixelBufferAttributes:OCMOCK_ANY]) - .andReturn(videoMock); - OCMStub([videoMock appendPixelBuffer:[OCMArg anyPointer] withPresentationTime:kCMTimeZero]) + id adaptorMock = OCMClassMock([AVAssetWriterInputPixelBufferAdaptor class]); + OCMStub([adaptorMock assetWriterInputPixelBufferAdaptorWithAssetWriterInput:OCMOCK_ANY + sourcePixelBufferAttributes:OCMOCK_ANY]) + .andReturn(adaptorMock); + OCMStub([adaptorMock appendPixelBuffer:[OCMArg anyPointer] withPresentationTime:kCMTimeZero]) .ignoringNonObjectArgs() .andDo(^(NSInvocation *invocation) { writtenSamples = [writtenSamples arrayByAddingObject:@"video"]; }); - id audioMock = OCMClassMock([AVAssetWriterInput class]); - OCMStub([audioMock assetWriterInputWithMediaType:[OCMArg isEqual:AVMediaTypeAudio] - outputSettings:OCMOCK_ANY]) - .andReturn(audioMock); - OCMStub([audioMock isReadyForMoreMediaData]).andReturn(YES); - OCMStub([audioMock appendSampleBuffer:[OCMArg anyPointer]]).andDo(^(NSInvocation *invocation) { + id inputMock = OCMClassMock([AVAssetWriterInput class]); + OCMStub([inputMock assetWriterInputWithMediaType:OCMOCK_ANY outputSettings:OCMOCK_ANY]) + .andReturn(inputMock); + OCMStub([inputMock isReadyForMoreMediaData]).andReturn(YES); + OCMStub([inputMock appendSampleBuffer:[OCMArg anyPointer]]).andDo(^(NSInvocation *invocation) { writtenSamples = [writtenSamples arrayByAddingObject:@"audio"]; }); @@ -130,4 +131,211 @@ - (void)testDidOutputSampleBufferIgnoreAudioSamplesBeforeVideoSamples { CFRelease(audioSample); } +- (void)testDidOutputSampleBufferSampleTimesMustBeNumericAfterPauseResume { + FLTCam *cam = FLTCreateCamWithCaptureSessionQueue(dispatch_queue_create("testing", NULL)); + CMSampleBufferRef videoSample = FLTCreateTestSampleBuffer(); + CMSampleBufferRef audioSample = FLTCreateTestAudioSampleBuffer(); + + id connectionMock = OCMClassMock([AVCaptureConnection class]); + + id writerMock = OCMClassMock([AVAssetWriter class]); + OCMStub([writerMock alloc]).andReturn(writerMock); + OCMStub([writerMock initWithURL:OCMOCK_ANY fileType:OCMOCK_ANY error:[OCMArg setTo:nil]]) + .andReturn(writerMock); + __block AVAssetWriterStatus status = AVAssetWriterStatusUnknown; + OCMStub([writerMock startWriting]).andDo(^(NSInvocation *invocation) { + status = AVAssetWriterStatusWriting; + }); + OCMStub([writerMock status]).andDo(^(NSInvocation *invocation) { + [invocation setReturnValue:&status]; + }); + + __block BOOL videoAppended = NO; + id adaptorMock = OCMClassMock([AVAssetWriterInputPixelBufferAdaptor class]); + OCMStub([adaptorMock assetWriterInputPixelBufferAdaptorWithAssetWriterInput:OCMOCK_ANY + sourcePixelBufferAttributes:OCMOCK_ANY]) + .andReturn(adaptorMock); + OCMStub([adaptorMock appendPixelBuffer:[OCMArg anyPointer] withPresentationTime:kCMTimeZero]) + .ignoringNonObjectArgs() + .andDo(^(NSInvocation *invocation) { + CMTime presentationTime; + [invocation getArgument:&presentationTime atIndex:3]; + XCTAssert(CMTIME_IS_NUMERIC(presentationTime)); + videoAppended = YES; + }); + + __block BOOL audioAppended = NO; + id inputMock = OCMClassMock([AVAssetWriterInput class]); + OCMStub([inputMock assetWriterInputWithMediaType:OCMOCK_ANY outputSettings:OCMOCK_ANY]) + .andReturn(inputMock); + OCMStub([inputMock isReadyForMoreMediaData]).andReturn(YES); + OCMStub([inputMock appendSampleBuffer:[OCMArg anyPointer]]).andDo(^(NSInvocation *invocation) { + CMSampleBufferRef sampleBuffer; + [invocation getArgument:&sampleBuffer atIndex:2]; + CMTime sampleTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); + XCTAssert(CMTIME_IS_NUMERIC(sampleTime)); + audioAppended = YES; + }); + + [cam + startVideoRecordingWithCompletion:^(FlutterError *_Nullable error) { + } + messengerForStreaming:nil]; + + [cam pauseVideoRecording]; + [cam resumeVideoRecording]; + + [cam captureOutput:cam.captureVideoOutput + didOutputSampleBuffer:videoSample + fromConnection:connectionMock]; + [cam captureOutput:nil didOutputSampleBuffer:audioSample fromConnection:connectionMock]; + [cam captureOutput:cam.captureVideoOutput + didOutputSampleBuffer:videoSample + fromConnection:connectionMock]; + [cam captureOutput:nil didOutputSampleBuffer:audioSample fromConnection:connectionMock]; + XCTAssert(videoAppended && audioAppended, @"Video or audio was not appended."); + + CFRelease(videoSample); + CFRelease(audioSample); +} + +- (void)testDidOutputSampleBufferMustNotAppendSampleWhenReadyForMoreMediaDataIsNo { + FLTCam *cam = FLTCreateCamWithCaptureSessionQueue(dispatch_queue_create("testing", NULL)); + CMSampleBufferRef videoSample = FLTCreateTestSampleBuffer(); + + id connectionMock = OCMClassMock([AVCaptureConnection class]); + + id writerMock = OCMClassMock([AVAssetWriter class]); + OCMStub([writerMock alloc]).andReturn(writerMock); + OCMStub([writerMock initWithURL:OCMOCK_ANY fileType:OCMOCK_ANY error:[OCMArg setTo:nil]]) + .andReturn(writerMock); + + __block BOOL sampleAppended = NO; + id adaptorMock = OCMClassMock([AVAssetWriterInputPixelBufferAdaptor class]); + OCMStub([adaptorMock assetWriterInputPixelBufferAdaptorWithAssetWriterInput:OCMOCK_ANY + sourcePixelBufferAttributes:OCMOCK_ANY]) + .andReturn(adaptorMock); + OCMStub([adaptorMock appendPixelBuffer:[OCMArg anyPointer] withPresentationTime:kCMTimeZero]) + .ignoringNonObjectArgs() + .andDo(^(NSInvocation *invocation) { + sampleAppended = YES; + }); + + __block BOOL readyForMoreMediaData = NO; + id inputMock = OCMClassMock([AVAssetWriterInput class]); + OCMStub([inputMock assetWriterInputWithMediaType:OCMOCK_ANY outputSettings:OCMOCK_ANY]) + .andReturn(inputMock); + OCMStub([inputMock isReadyForMoreMediaData]).andDo(^(NSInvocation *invocation) { + [invocation setReturnValue:&readyForMoreMediaData]; + }); + + [cam + startVideoRecordingWithCompletion:^(FlutterError *_Nullable error) { + } + messengerForStreaming:nil]; + + readyForMoreMediaData = YES; + sampleAppended = NO; + [cam captureOutput:cam.captureVideoOutput + didOutputSampleBuffer:videoSample + fromConnection:connectionMock]; + XCTAssertTrue(sampleAppended, @"Sample was not appended."); + + readyForMoreMediaData = NO; + sampleAppended = NO; + [cam captureOutput:cam.captureVideoOutput + didOutputSampleBuffer:videoSample + fromConnection:connectionMock]; + XCTAssertFalse(sampleAppended, @"Sample cannot be appended when readyForMoreMediaData is NO."); + + CFRelease(videoSample); +} + +- (void)testStopVideoRecordingWithCompletionMustCallCompletion { + FLTCam *cam = FLTCreateCamWithCaptureSessionQueue(dispatch_queue_create("testing", NULL)); + + id writerMock = OCMClassMock([AVAssetWriter class]); + OCMStub([writerMock alloc]).andReturn(writerMock); + OCMStub([writerMock initWithURL:OCMOCK_ANY fileType:OCMOCK_ANY error:[OCMArg setTo:nil]]) + .andReturn(writerMock); + __block AVAssetWriterStatus status = AVAssetWriterStatusUnknown; + OCMStub([writerMock startWriting]).andDo(^(NSInvocation *invocation) { + status = AVAssetWriterStatusWriting; + }); + OCMStub([writerMock status]).andDo(^(NSInvocation *invocation) { + [invocation setReturnValue:&status]; + }); + + OCMStub([writerMock finishWritingWithCompletionHandler:[OCMArg checkWithBlock:^(id param) { + XCTAssert(status == AVAssetWriterStatusWriting, + @"Cannot call finishWritingWithCompletionHandler when status is " + @"not AVAssetWriterStatusWriting."); + void (^handler)(void) = param; + handler(); + return YES; + }]]); + + [cam + startVideoRecordingWithCompletion:^(FlutterError *_Nullable error) { + } + messengerForStreaming:nil]; + + __block BOOL completionCalled = NO; + [cam stopVideoRecordingWithCompletion:^(NSString *_Nullable path, FlutterError *_Nullable error) { + completionCalled = YES; + }]; + XCTAssert(completionCalled, @"Completion was not called."); +} + +- (void)testStartWritingShouldNotBeCalledBetweenSampleCreationAndAppending { + FLTCam *cam = FLTCreateCamWithCaptureSessionQueue(dispatch_queue_create("testing", NULL)); + CMSampleBufferRef videoSample = FLTCreateTestSampleBuffer(); + + id connectionMock = OCMClassMock([AVCaptureConnection class]); + + id writerMock = OCMClassMock([AVAssetWriter class]); + OCMStub([writerMock alloc]).andReturn(writerMock); + OCMStub([writerMock initWithURL:OCMOCK_ANY fileType:OCMOCK_ANY error:[OCMArg setTo:nil]]) + .andReturn(writerMock); + __block BOOL startWritingCalled = NO; + OCMStub([writerMock startWriting]).andDo(^(NSInvocation *invocation) { + startWritingCalled = YES; + }); + + __block BOOL videoAppended = NO; + id adaptorMock = OCMClassMock([AVAssetWriterInputPixelBufferAdaptor class]); + OCMStub([adaptorMock assetWriterInputPixelBufferAdaptorWithAssetWriterInput:OCMOCK_ANY + sourcePixelBufferAttributes:OCMOCK_ANY]) + .andReturn(adaptorMock); + OCMStub([adaptorMock appendPixelBuffer:[OCMArg anyPointer] withPresentationTime:kCMTimeZero]) + .ignoringNonObjectArgs() + .andDo(^(NSInvocation *invocation) { + videoAppended = YES; + }); + + id inputMock = OCMClassMock([AVAssetWriterInput class]); + OCMStub([inputMock assetWriterInputWithMediaType:OCMOCK_ANY outputSettings:OCMOCK_ANY]) + .andReturn(inputMock); + OCMStub([inputMock isReadyForMoreMediaData]).andReturn(YES); + + [cam + startVideoRecordingWithCompletion:^(FlutterError *_Nullable error) { + } + messengerForStreaming:nil]; + + BOOL startWritingCalledBefore = startWritingCalled; + [cam captureOutput:cam.captureVideoOutput + didOutputSampleBuffer:videoSample + fromConnection:connectionMock]; + XCTAssert((startWritingCalledBefore && videoAppended) || (startWritingCalled && !videoAppended), + @"The startWriting was called between sample creation and appending."); + + [cam captureOutput:cam.captureVideoOutput + didOutputSampleBuffer:videoSample + fromConnection:connectionMock]; + XCTAssert(videoAppended, @"Video was not appended."); + + CFRelease(videoSample); +} + @end diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTSavePhotoDelegateTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTSavePhotoDelegateTests.m index f7633591ccb6..c92d824e4696 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTSavePhotoDelegateTests.m +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTSavePhotoDelegateTests.m @@ -3,7 +3,9 @@ // found in the LICENSE file. @import camera_avfoundation; +#if __has_include() @import camera_avfoundation.Test; +#endif @import AVFoundation; @import XCTest; #import diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/QueueUtilsTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/QueueUtilsTests.m index 128b47b9089d..57b508093d9f 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/QueueUtilsTests.m +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/QueueUtilsTests.m @@ -3,7 +3,9 @@ // found in the LICENSE file. @import camera_avfoundation; +#if __has_include() @import camera_avfoundation.Test; +#endif @import XCTest; @interface QueueUtilsTests : XCTestCase diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/StreamingTest.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/StreamingTest.m index 14a611852dcc..53c7c1da2c70 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/StreamingTest.m +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/StreamingTest.m @@ -3,7 +3,9 @@ // found in the LICENSE file. @import camera_avfoundation; +#if __has_include() @import camera_avfoundation.Test; +#endif @import XCTest; @import AVFoundation; #import diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/ThreadSafeEventChannelTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/ThreadSafeEventChannelTests.m index e445697d8053..169b75ddfbb1 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/ThreadSafeEventChannelTests.m +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/ThreadSafeEventChannelTests.m @@ -3,7 +3,9 @@ // found in the LICENSE file. @import camera_avfoundation; +#if __has_include() @import camera_avfoundation.Test; +#endif @import XCTest; #import diff --git a/packages/camera/camera_avfoundation/example/lib/main.dart b/packages/camera/camera_avfoundation/example/lib/main.dart index 9b8b9759f320..f0ebf7b7865f 100644 --- a/packages/camera/camera_avfoundation/example/lib/main.dart +++ b/packages/camera/camera_avfoundation/example/lib/main.dart @@ -540,7 +540,7 @@ class _CameraExampleHomeState extends State onPressed: cameraController != null && cameraController.value.isInitialized && cameraController.value.isRecordingVideo - ? (cameraController.value.isRecordingPaused) + ? cameraController.value.isRecordingPaused ? onResumeButtonPressed : onPauseButtonPressed : null, @@ -698,7 +698,6 @@ class _CameraExampleHomeState extends State showInSnackBar('Unknown permission error.'); default: _showCameraException(e); - break; } } diff --git a/packages/camera/camera_avfoundation/example/pubspec.yaml b/packages/camera/camera_avfoundation/example/pubspec.yaml index 6cdd9cbf72f0..d855135a5c8f 100644 --- a/packages/camera/camera_avfoundation/example/pubspec.yaml +++ b/packages/camera/camera_avfoundation/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the camera plugin. publish_to: none environment: - sdk: ^3.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: camera_avfoundation: diff --git a/packages/camera/camera_avfoundation/ios/Assets/.gitkeep b/packages/camera/camera_avfoundation/ios/Assets/.gitkeep deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/packages/camera/camera_avfoundation/ios/camera_avfoundation.podspec b/packages/camera/camera_avfoundation/ios/camera_avfoundation.podspec index db0c87951c63..74594ff30e6c 100644 --- a/packages/camera/camera_avfoundation/ios/camera_avfoundation.podspec +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation.podspec @@ -13,12 +13,12 @@ A Flutter plugin to use the camera from your Flutter app. s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } s.source = { :http => 'https://github.com/flutter/packages/tree/main/packages/camera_avfoundation' } s.documentation_url = 'https://pub.dev/packages/camera_avfoundation' - s.source_files = 'Classes/**/*.{h,m}' - s.public_header_files = 'Classes/**/*.h' - s.module_map = 'Classes/CameraPlugin.modulemap' + s.source_files = 'camera_avfoundation/Sources/camera_avfoundation/**/*.{h,m}' + s.public_header_files = 'camera_avfoundation/Sources/camera_avfoundation/include/**/*.h' + s.module_map = 'camera_avfoundation/Sources/camera_avfoundation/include/CameraPlugin.modulemap' s.dependency 'Flutter' s.platform = :ios, '12.0' s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } - s.resource_bundles = {'camera_avfoundation_privacy' => ['Resources/PrivacyInfo.xcprivacy']} + s.resource_bundles = {'camera_avfoundation_privacy' => ['camera_avfoundation/Sources/camera_avfoundation/Resources/PrivacyInfo.xcprivacy']} end diff --git a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Package.swift b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Package.swift new file mode 100644 index 000000000000..48050b6b788b --- /dev/null +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Package.swift @@ -0,0 +1,31 @@ +// swift-tools-version: 5.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. + +import PackageDescription + +let package = Package( + name: "camera_avfoundation", + platforms: [ + .iOS("12.0") + ], + products: [ + .library(name: "camera-avfoundation", targets: ["camera_avfoundation"]) + ], + dependencies: [], + targets: [ + .target( + name: "camera_avfoundation", + dependencies: [], + exclude: ["include/camera_avfoundation-umbrella.h", "include/CameraPlugin.modulemap"], + resources: [ + .process("Resources") + ], + cSettings: [ + .headerSearchPath("include/camera_avfoundation") + ] + ) + ] +) diff --git a/packages/camera/camera_avfoundation/ios/Classes/CameraPermissionUtils.m b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/CameraPermissionUtils.m similarity index 98% rename from packages/camera/camera_avfoundation/ios/Classes/CameraPermissionUtils.m rename to packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/CameraPermissionUtils.m index 098265a6b74d..b63a1d684e00 100644 --- a/packages/camera/camera_avfoundation/ios/Classes/CameraPermissionUtils.m +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/CameraPermissionUtils.m @@ -3,7 +3,7 @@ // found in the LICENSE file. @import AVFoundation; -#import "CameraPermissionUtils.h" +#import "./include/camera_avfoundation/CameraPermissionUtils.h" void FLTRequestPermission(BOOL forAudio, FLTCameraPermissionRequestCompletionHandler handler) { AVMediaType mediaType; diff --git a/packages/camera/camera_avfoundation/ios/Classes/CameraPlugin.m b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/CameraPlugin.m similarity index 97% rename from packages/camera/camera_avfoundation/ios/Classes/CameraPlugin.m rename to packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/CameraPlugin.m index de89aecce224..de208fd560ef 100644 --- a/packages/camera/camera_avfoundation/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/CameraPlugin.m @@ -2,18 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "CameraPlugin.h" -#import "CameraPlugin_Test.h" +#import "./include/camera_avfoundation/CameraPlugin.h" +#import "./include/camera_avfoundation/CameraPlugin_Test.h" @import AVFoundation; @import Flutter; -#import "CameraPermissionUtils.h" -#import "CameraProperties.h" -#import "FLTCam.h" -#import "FLTThreadSafeEventChannel.h" -#import "QueueUtils.h" -#import "messages.g.h" +#import "./include/camera_avfoundation/CameraPermissionUtils.h" +#import "./include/camera_avfoundation/CameraProperties.h" +#import "./include/camera_avfoundation/FLTCam.h" +#import "./include/camera_avfoundation/FLTThreadSafeEventChannel.h" +#import "./include/camera_avfoundation/QueueUtils.h" +#import "./include/camera_avfoundation/messages.g.h" static FlutterError *FlutterErrorFromNSError(NSError *error) { return [FlutterError errorWithCode:[NSString stringWithFormat:@"Error %d", (int)error.code] @@ -416,6 +416,7 @@ - (void)disposeCamera:(NSInteger)cameraId __weak typeof(self) weakSelf = self; dispatch_async(self.captureSessionQueue, ^{ [weakSelf.camera close]; + weakSelf.camera = nil; completion(nil); }); } diff --git a/packages/camera/camera_avfoundation/ios/Classes/CameraProperties.m b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/CameraProperties.m similarity index 97% rename from packages/camera/camera_avfoundation/ios/Classes/CameraProperties.m rename to packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/CameraProperties.m index 5aa1f25bb037..8ef61b43fc85 100644 --- a/packages/camera/camera_avfoundation/ios/Classes/CameraProperties.m +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/CameraProperties.m @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "CameraProperties.h" +#import "./include/camera_avfoundation/CameraProperties.h" AVCaptureFlashMode FCPGetAVCaptureFlashModeForPigeonFlashMode(FCPPlatformFlashMode mode) { switch (mode) { diff --git a/packages/camera/camera_avfoundation/ios/Classes/FLTCam.m b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/FLTCam.m similarity index 89% rename from packages/camera/camera_avfoundation/ios/Classes/FLTCam.m rename to packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/FLTCam.m index 45ab3e08e667..0b065026f10e 100644 --- a/packages/camera/camera_avfoundation/ios/Classes/FLTCam.m +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/FLTCam.m @@ -2,17 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FLTCam.h" -#import "FLTCam_Test.h" +#import "./include/camera_avfoundation/FLTCam.h" +#import "./include/camera_avfoundation/FLTCam_Test.h" @import CoreMotion; @import Flutter; #import -#import "FLTSavePhotoDelegate.h" -#import "FLTThreadSafeEventChannel.h" -#import "QueueUtils.h" -#import "messages.g.h" +#import "./include/camera_avfoundation/FLTSavePhotoDelegate.h" +#import "./include/camera_avfoundation/FLTThreadSafeEventChannel.h" +#import "./include/camera_avfoundation/QueueUtils.h" +#import "./include/camera_avfoundation/messages.g.h" static FlutterError *FlutterErrorFromNSError(NSError *error) { return [FlutterError errorWithCode:[NSString stringWithFormat:@"Error %d", (int)error.code] @@ -69,6 +69,7 @@ @interface FLTCam () maxPixelCount) { - maxPixelCount = pixelCount; + FourCharCode subType = CMFormatDescriptionGetMediaSubType(format.formatDescription); + BOOL isSubTypePreferred = subType == preferredSubType; + if (pixelCount > maxPixelCount || + (pixelCount == maxPixelCount && isSubTypePreferred && !isBestSubTypePreferred)) { bestFormat = format; + maxPixelCount = pixelCount; + isBestSubTypePreferred = isSubTypePreferred; } } return bestFormat; @@ -663,15 +716,19 @@ - (void)captureOutput:(AVCaptureOutput *)output // ignore audio samples until the first video sample arrives to avoid black frames // https://github.com/flutter/flutter/issues/57831 - if (_videoWriter.status != AVAssetWriterStatusWriting && output != _captureVideoOutput) { + if (_isFirstVideoSample && output != _captureVideoOutput) { return; } CMTime currentSampleTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); - if (_videoWriter.status != AVAssetWriterStatusWriting) { - [_videoWriter startWriting]; + if (_isFirstVideoSample) { [_videoWriter startSessionAtSourceTime:currentSampleTime]; + // fix sample times not being numeric when pause/resume happens before first sample buffer + // arrives https://github.com/flutter/flutter/issues/132014 + _lastVideoSampleTime = currentSampleTime; + _lastAudioSampleTime = currentSampleTime; + _isFirstVideoSample = NO; } if (output == _captureVideoOutput) { @@ -692,7 +749,11 @@ - (void)captureOutput:(AVCaptureOutput *)output CVPixelBufferRef nextBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); CMTime nextSampleTime = CMTimeSubtract(_lastVideoSampleTime, _videoTimeOffset); - [_videoAdaptor appendPixelBuffer:nextBuffer withPresentationTime:nextSampleTime]; + // do not append sample buffer when readyForMoreMediaData is NO to avoid crash + // https://github.com/flutter/flutter/issues/132073 + if (_videoWriterInput.readyForMoreMediaData) { + [_videoAdaptor appendPixelBuffer:nextBuffer withPresentationTime:nextSampleTime]; + } } else { CMTime dur = CMSampleBufferGetDuration(sampleBuffer); @@ -826,6 +887,14 @@ - (void)startVideoRecordingWithCompletion:(void (^)(FlutterError *_Nullable))com details:nil]); return; } + // startWriting should not be called in didOutputSampleBuffer where it can cause state + // in which _isRecording is YES but _videoWriter.status is AVAssetWriterStatusUnknown + // in stopVideoRecording if it is called after startVideoRecording but before + // didOutputSampleBuffer had chance to call startWriting and lag at start of video + // https://github.com/flutter/flutter/issues/132016 + // https://github.com/flutter/flutter/issues/151319 + [_videoWriter startWriting]; + _isFirstVideoSample = YES; _isRecording = YES; _isRecordingPaused = NO; _videoTimeOffset = CMTimeMake(0, 1); @@ -845,19 +914,21 @@ - (void)stopVideoRecordingWithCompletion:(void (^)(NSString *_Nullable, if (_isRecording) { _isRecording = NO; - if (_videoWriter.status != AVAssetWriterStatusUnknown) { - [_videoWriter finishWritingWithCompletionHandler:^{ - if (self->_videoWriter.status == AVAssetWriterStatusCompleted) { - [self updateOrientation]; - completion(self->_videoRecordingPath, nil); - self->_videoRecordingPath = nil; - } else { - completion(nil, [FlutterError errorWithCode:@"IOError" - message:@"AVAssetWriter could not finish writing!" - details:nil]); - } - }]; - } + // when _isRecording is YES startWriting was already called so _videoWriter.status + // is always either AVAssetWriterStatusWriting or AVAssetWriterStatusFailed and + // finishWritingWithCompletionHandler does not throw exception so there is no need + // to check _videoWriter.status + [_videoWriter finishWritingWithCompletionHandler:^{ + if (self->_videoWriter.status == AVAssetWriterStatusCompleted) { + [self updateOrientation]; + completion(self->_videoRecordingPath, nil); + self->_videoRecordingPath = nil; + } else { + completion(nil, [FlutterError errorWithCode:@"IOError" + message:@"AVAssetWriter could not finish writing!" + details:nil]); + } + }]; } else { NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain diff --git a/packages/camera/camera_avfoundation/ios/Classes/FLTCamMediaSettingsAVWrapper.m b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/FLTCamMediaSettingsAVWrapper.m similarity index 96% rename from packages/camera/camera_avfoundation/ios/Classes/FLTCamMediaSettingsAVWrapper.m rename to packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/FLTCamMediaSettingsAVWrapper.m index 636b5c7bf4c3..b975daa4b5c2 100644 --- a/packages/camera/camera_avfoundation/ios/Classes/FLTCamMediaSettingsAVWrapper.m +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/FLTCamMediaSettingsAVWrapper.m @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FLTCamMediaSettingsAVWrapper.h" +#import "./include/camera_avfoundation/FLTCamMediaSettingsAVWrapper.h" @implementation FLTCamMediaSettingsAVWrapper diff --git a/packages/camera/camera_avfoundation/ios/Classes/FLTSavePhotoDelegate.m b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/FLTSavePhotoDelegate.m similarity index 93% rename from packages/camera/camera_avfoundation/ios/Classes/FLTSavePhotoDelegate.m rename to packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/FLTSavePhotoDelegate.m index 436c9f8f3b57..5b45f93c221c 100644 --- a/packages/camera/camera_avfoundation/ios/Classes/FLTSavePhotoDelegate.m +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/FLTSavePhotoDelegate.m @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FLTSavePhotoDelegate.h" -#import "FLTSavePhotoDelegate_Test.h" +#import "./include/camera_avfoundation/FLTSavePhotoDelegate.h" +#import "./include/camera_avfoundation/FLTSavePhotoDelegate_Test.h" @interface FLTSavePhotoDelegate () /// The file path for the captured photo. diff --git a/packages/camera/camera_avfoundation/ios/Classes/FLTThreadSafeEventChannel.m b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/FLTThreadSafeEventChannel.m similarity index 90% rename from packages/camera/camera_avfoundation/ios/Classes/FLTThreadSafeEventChannel.m rename to packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/FLTThreadSafeEventChannel.m index 57d154c595ec..53c7273a5901 100644 --- a/packages/camera/camera_avfoundation/ios/Classes/FLTThreadSafeEventChannel.m +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/FLTThreadSafeEventChannel.m @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FLTThreadSafeEventChannel.h" -#import "QueueUtils.h" +#import "./include/camera_avfoundation/FLTThreadSafeEventChannel.h" +#import "./include/camera_avfoundation/QueueUtils.h" @interface FLTThreadSafeEventChannel () @property(nonatomic, strong) FlutterEventChannel *channel; diff --git a/packages/camera/camera_avfoundation/ios/Classes/QueueUtils.m b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/QueueUtils.m similarity index 88% rename from packages/camera/camera_avfoundation/ios/Classes/QueueUtils.m rename to packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/QueueUtils.m index 1fd54cd52cb3..8ea83ede2b71 100644 --- a/packages/camera/camera_avfoundation/ios/Classes/QueueUtils.m +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/QueueUtils.m @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "QueueUtils.h" +#import "./include/camera_avfoundation/QueueUtils.h" const char *FLTCaptureSessionQueueSpecific = "capture_session_queue"; diff --git a/packages/camera/camera_avfoundation/ios/Resources/PrivacyInfo.xcprivacy b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/Resources/PrivacyInfo.xcprivacy similarity index 100% rename from packages/camera/camera_avfoundation/ios/Resources/PrivacyInfo.xcprivacy rename to packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/Resources/PrivacyInfo.xcprivacy diff --git a/packages/camera/camera_avfoundation/ios/Classes/CameraPlugin.modulemap b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/CameraPlugin.modulemap similarity index 100% rename from packages/camera/camera_avfoundation/ios/Classes/CameraPlugin.modulemap rename to packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/CameraPlugin.modulemap diff --git a/packages/camera/camera_avfoundation/ios/Classes/camera_avfoundation-umbrella.h b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation-umbrella.h similarity index 100% rename from packages/camera/camera_avfoundation/ios/Classes/camera_avfoundation-umbrella.h rename to packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation-umbrella.h diff --git a/packages/camera/camera_avfoundation/ios/Classes/CameraPermissionUtils.h b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/CameraPermissionUtils.h similarity index 100% rename from packages/camera/camera_avfoundation/ios/Classes/CameraPermissionUtils.h rename to packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/CameraPermissionUtils.h diff --git a/packages/camera/camera_avfoundation/ios/Classes/CameraPlugin.h b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/CameraPlugin.h similarity index 100% rename from packages/camera/camera_avfoundation/ios/Classes/CameraPlugin.h rename to packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/CameraPlugin.h diff --git a/packages/camera/camera_avfoundation/ios/Classes/CameraPlugin_Test.h b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/CameraPlugin_Test.h similarity index 100% rename from packages/camera/camera_avfoundation/ios/Classes/CameraPlugin_Test.h rename to packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/CameraPlugin_Test.h diff --git a/packages/camera/camera_avfoundation/ios/Classes/CameraProperties.h b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/CameraProperties.h similarity index 98% rename from packages/camera/camera_avfoundation/ios/Classes/CameraProperties.h rename to packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/CameraProperties.h index ea7a4a3438a5..a46e4f04b657 100644 --- a/packages/camera/camera_avfoundation/ios/Classes/CameraProperties.h +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/CameraProperties.h @@ -4,6 +4,7 @@ @import AVFoundation; @import Foundation; +@import UIKit; #import "messages.g.h" diff --git a/packages/camera/camera_avfoundation/ios/Classes/FLTCam.h b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/FLTCam.h similarity index 100% rename from packages/camera/camera_avfoundation/ios/Classes/FLTCam.h rename to packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/FLTCam.h diff --git a/packages/camera/camera_avfoundation/ios/Classes/FLTCamMediaSettingsAVWrapper.h b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/FLTCamMediaSettingsAVWrapper.h similarity index 100% rename from packages/camera/camera_avfoundation/ios/Classes/FLTCamMediaSettingsAVWrapper.h rename to packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/FLTCamMediaSettingsAVWrapper.h diff --git a/packages/camera/camera_avfoundation/ios/Classes/FLTCam_Test.h b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/FLTCam_Test.h similarity index 100% rename from packages/camera/camera_avfoundation/ios/Classes/FLTCam_Test.h rename to packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/FLTCam_Test.h diff --git a/packages/camera/camera_avfoundation/ios/Classes/FLTSavePhotoDelegate.h b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/FLTSavePhotoDelegate.h similarity index 100% rename from packages/camera/camera_avfoundation/ios/Classes/FLTSavePhotoDelegate.h rename to packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/FLTSavePhotoDelegate.h diff --git a/packages/camera/camera_avfoundation/ios/Classes/FLTSavePhotoDelegate_Test.h b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/FLTSavePhotoDelegate_Test.h similarity index 100% rename from packages/camera/camera_avfoundation/ios/Classes/FLTSavePhotoDelegate_Test.h rename to packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/FLTSavePhotoDelegate_Test.h diff --git a/packages/camera/camera_avfoundation/ios/Classes/FLTThreadSafeEventChannel.h b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/FLTThreadSafeEventChannel.h similarity index 100% rename from packages/camera/camera_avfoundation/ios/Classes/FLTThreadSafeEventChannel.h rename to packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/FLTThreadSafeEventChannel.h diff --git a/packages/camera/camera_avfoundation/ios/Classes/QueueUtils.h b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/QueueUtils.h similarity index 100% rename from packages/camera/camera_avfoundation/ios/Classes/QueueUtils.h rename to packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/QueueUtils.h diff --git a/packages/camera/camera_avfoundation/ios/Classes/messages.g.h b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/messages.g.h similarity index 97% rename from packages/camera/camera_avfoundation/ios/Classes/messages.g.h rename to packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/messages.g.h index 8e3dd431443a..2f1d8646afac 100644 --- a/packages/camera/camera_avfoundation/ios/Classes/messages.g.h +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/messages.g.h @@ -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 (v18.0.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.2), do not edit directly. // See also: https://pub.dev/packages/pigeon #import @@ -182,8 +182,8 @@ typedef NS_ENUM(NSUInteger, FCPPlatformResolutionPreset) { @property(nonatomic, assign) double height; @end -/// The codec used by FCPCameraApi. -NSObject *FCPCameraApiGetCodec(void); +/// The codec used by all APIs. +NSObject *FCPGetMessagesCodec(void); @protocol FCPCameraApi /// Returns the list of available cameras. @@ -284,9 +284,6 @@ extern void SetUpFCPCameraApiWithSuffix(id binaryMesseng NSObject *_Nullable api, NSString *messageChannelSuffix); -/// The codec used by FCPCameraGlobalEventApi. -NSObject *FCPCameraGlobalEventApiGetCodec(void); - /// Handler for native callbacks that are not tied to a specific camera ID. @interface FCPCameraGlobalEventApi : NSObject - (instancetype)initWithBinaryMessenger:(id)binaryMessenger; @@ -297,9 +294,6 @@ NSObject *FCPCameraGlobalEventApiGetCodec(void); completion:(void (^)(FlutterError *_Nullable))completion; @end -/// The codec used by FCPCameraEventApi. -NSObject *FCPCameraEventApiGetCodec(void); - /// Handler for native callbacks that are tied to a specific camera ID. /// /// This is intended to be initialized with the camera ID as a suffix. diff --git a/packages/camera/camera_avfoundation/ios/Classes/messages.g.m b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/messages.g.m similarity index 80% rename from packages/camera/camera_avfoundation/ios/Classes/messages.g.m rename to packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/messages.g.m index d90b63d7a011..0164b4d6c6cc 100644 --- a/packages/camera/camera_avfoundation/ios/Classes/messages.g.m +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/messages.g.m @@ -1,10 +1,10 @@ // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v18.0.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.2), do not edit directly. // See also: https://pub.dev/packages/pigeon -#import "messages.g.h" +#import "./include/camera_avfoundation/messages.g.h" #if TARGET_OS_OSX #import @@ -16,7 +16,7 @@ #error File requires ARC to be enabled. #endif -static NSArray *wrapResult(id result, FlutterError *error) { +static NSArray *wrapResult(id result, FlutterError *error) { if (error) { return @[ error.code ?: [NSNull null], error.message ?: [NSNull null], error.details ?: [NSNull null] @@ -34,7 +34,7 @@ details:@""]; } -static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) { +static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) { id result = array[key]; return (result == [NSNull null]) ? nil : result; } @@ -121,33 +121,33 @@ - (instancetype)initWithValue:(FCPPlatformResolutionPreset)value { @end @interface FCPPlatformCameraDescription () -+ (FCPPlatformCameraDescription *)fromList:(NSArray *)list; -+ (nullable FCPPlatformCameraDescription *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; ++ (FCPPlatformCameraDescription *)fromList:(NSArray *)list; ++ (nullable FCPPlatformCameraDescription *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; @end @interface FCPPlatformCameraState () -+ (FCPPlatformCameraState *)fromList:(NSArray *)list; -+ (nullable FCPPlatformCameraState *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; ++ (FCPPlatformCameraState *)fromList:(NSArray *)list; ++ (nullable FCPPlatformCameraState *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; @end @interface FCPPlatformMediaSettings () -+ (FCPPlatformMediaSettings *)fromList:(NSArray *)list; -+ (nullable FCPPlatformMediaSettings *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; ++ (FCPPlatformMediaSettings *)fromList:(NSArray *)list; ++ (nullable FCPPlatformMediaSettings *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; @end @interface FCPPlatformPoint () -+ (FCPPlatformPoint *)fromList:(NSArray *)list; -+ (nullable FCPPlatformPoint *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; ++ (FCPPlatformPoint *)fromList:(NSArray *)list; ++ (nullable FCPPlatformPoint *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; @end @interface FCPPlatformSize () -+ (FCPPlatformSize *)fromList:(NSArray *)list; -+ (nullable FCPPlatformSize *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; ++ (FCPPlatformSize *)fromList:(NSArray *)list; ++ (nullable FCPPlatformSize *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; @end @implementation FCPPlatformCameraDescription @@ -158,19 +158,21 @@ + (instancetype)makeWithName:(NSString *)name pigeonResult.lensDirection = lensDirection; return pigeonResult; } -+ (FCPPlatformCameraDescription *)fromList:(NSArray *)list { ++ (FCPPlatformCameraDescription *)fromList:(NSArray *)list { FCPPlatformCameraDescription *pigeonResult = [[FCPPlatformCameraDescription alloc] init]; pigeonResult.name = GetNullableObjectAtIndex(list, 0); - pigeonResult.lensDirection = [GetNullableObjectAtIndex(list, 1) integerValue]; + FCPPlatformCameraLensDirectionBox *boxedFCPPlatformCameraLensDirection = + GetNullableObjectAtIndex(list, 1); + pigeonResult.lensDirection = boxedFCPPlatformCameraLensDirection.value; return pigeonResult; } -+ (nullable FCPPlatformCameraDescription *)nullableFromList:(NSArray *)list { ++ (nullable FCPPlatformCameraDescription *)nullableFromList:(NSArray *)list { return (list) ? [FCPPlatformCameraDescription fromList:list] : nil; } -- (NSArray *)toList { +- (NSArray *)toList { return @[ self.name ?: [NSNull null], - @(self.lensDirection), + [[FCPPlatformCameraLensDirectionBox alloc] initWithValue:self.lensDirection], ]; } @end @@ -189,23 +191,25 @@ + (instancetype)makeWithPreviewSize:(FCPPlatformSize *)previewSize pigeonResult.focusPointSupported = focusPointSupported; return pigeonResult; } -+ (FCPPlatformCameraState *)fromList:(NSArray *)list { ++ (FCPPlatformCameraState *)fromList:(NSArray *)list { FCPPlatformCameraState *pigeonResult = [[FCPPlatformCameraState alloc] init]; - pigeonResult.previewSize = [FCPPlatformSize nullableFromList:(GetNullableObjectAtIndex(list, 0))]; - pigeonResult.exposureMode = [GetNullableObjectAtIndex(list, 1) integerValue]; - pigeonResult.focusMode = [GetNullableObjectAtIndex(list, 2) integerValue]; + pigeonResult.previewSize = GetNullableObjectAtIndex(list, 0); + FCPPlatformExposureModeBox *boxedFCPPlatformExposureMode = GetNullableObjectAtIndex(list, 1); + pigeonResult.exposureMode = boxedFCPPlatformExposureMode.value; + FCPPlatformFocusModeBox *boxedFCPPlatformFocusMode = GetNullableObjectAtIndex(list, 2); + pigeonResult.focusMode = boxedFCPPlatformFocusMode.value; pigeonResult.exposurePointSupported = [GetNullableObjectAtIndex(list, 3) boolValue]; pigeonResult.focusPointSupported = [GetNullableObjectAtIndex(list, 4) boolValue]; return pigeonResult; } -+ (nullable FCPPlatformCameraState *)nullableFromList:(NSArray *)list { ++ (nullable FCPPlatformCameraState *)nullableFromList:(NSArray *)list { return (list) ? [FCPPlatformCameraState fromList:list] : nil; } -- (NSArray *)toList { +- (NSArray *)toList { return @[ - (self.previewSize ? [self.previewSize toList] : [NSNull null]), - @(self.exposureMode), - @(self.focusMode), + self.previewSize ?: [NSNull null], + [[FCPPlatformExposureModeBox alloc] initWithValue:self.exposureMode], + [[FCPPlatformFocusModeBox alloc] initWithValue:self.focusMode], @(self.exposurePointSupported), @(self.focusPointSupported), ]; @@ -226,21 +230,23 @@ + (instancetype)makeWithResolutionPreset:(FCPPlatformResolutionPreset)resolution pigeonResult.enableAudio = enableAudio; return pigeonResult; } -+ (FCPPlatformMediaSettings *)fromList:(NSArray *)list { ++ (FCPPlatformMediaSettings *)fromList:(NSArray *)list { FCPPlatformMediaSettings *pigeonResult = [[FCPPlatformMediaSettings alloc] init]; - pigeonResult.resolutionPreset = [GetNullableObjectAtIndex(list, 0) integerValue]; + FCPPlatformResolutionPresetBox *boxedFCPPlatformResolutionPreset = + GetNullableObjectAtIndex(list, 0); + pigeonResult.resolutionPreset = boxedFCPPlatformResolutionPreset.value; pigeonResult.framesPerSecond = GetNullableObjectAtIndex(list, 1); pigeonResult.videoBitrate = GetNullableObjectAtIndex(list, 2); pigeonResult.audioBitrate = GetNullableObjectAtIndex(list, 3); pigeonResult.enableAudio = [GetNullableObjectAtIndex(list, 4) boolValue]; return pigeonResult; } -+ (nullable FCPPlatformMediaSettings *)nullableFromList:(NSArray *)list { ++ (nullable FCPPlatformMediaSettings *)nullableFromList:(NSArray *)list { return (list) ? [FCPPlatformMediaSettings fromList:list] : nil; } -- (NSArray *)toList { +- (NSArray *)toList { return @[ - @(self.resolutionPreset), + [[FCPPlatformResolutionPresetBox alloc] initWithValue:self.resolutionPreset], self.framesPerSecond ?: [NSNull null], self.videoBitrate ?: [NSNull null], self.audioBitrate ?: [NSNull null], @@ -256,16 +262,16 @@ + (instancetype)makeWithX:(double)x y:(double)y { pigeonResult.y = y; return pigeonResult; } -+ (FCPPlatformPoint *)fromList:(NSArray *)list { ++ (FCPPlatformPoint *)fromList:(NSArray *)list { FCPPlatformPoint *pigeonResult = [[FCPPlatformPoint alloc] init]; pigeonResult.x = [GetNullableObjectAtIndex(list, 0) doubleValue]; pigeonResult.y = [GetNullableObjectAtIndex(list, 1) doubleValue]; return pigeonResult; } -+ (nullable FCPPlatformPoint *)nullableFromList:(NSArray *)list { ++ (nullable FCPPlatformPoint *)nullableFromList:(NSArray *)list { return (list) ? [FCPPlatformPoint fromList:list] : nil; } -- (NSArray *)toList { +- (NSArray *)toList { return @[ @(self.x), @(self.y), @@ -280,16 +286,16 @@ + (instancetype)makeWithWidth:(double)width height:(double)height { pigeonResult.height = height; return pigeonResult; } -+ (FCPPlatformSize *)fromList:(NSArray *)list { ++ (FCPPlatformSize *)fromList:(NSArray *)list { FCPPlatformSize *pigeonResult = [[FCPPlatformSize alloc] init]; pigeonResult.width = [GetNullableObjectAtIndex(list, 0) doubleValue]; pigeonResult.height = [GetNullableObjectAtIndex(list, 1) doubleValue]; return pigeonResult; } -+ (nullable FCPPlatformSize *)nullableFromList:(NSArray *)list { ++ (nullable FCPPlatformSize *)nullableFromList:(NSArray *)list { return (list) ? [FCPPlatformSize fromList:list] : nil; } -- (NSArray *)toList { +- (NSArray *)toList { return @[ @(self.width), @(self.height), @@ -297,35 +303,125 @@ - (NSArray *)toList { } @end -@interface FCPCameraApiCodecReader : FlutterStandardReader +@interface FCPMessagesPigeonCodecReader : FlutterStandardReader @end -@implementation FCPCameraApiCodecReader +@implementation FCPMessagesPigeonCodecReader - (nullable id)readValueOfType:(UInt8)type { switch (type) { - case 128: + case 129: { + NSNumber *enumAsNumber = [self readValue]; + return enumAsNumber == nil ? nil + : [[FCPPlatformCameraLensDirectionBox alloc] + initWithValue:[enumAsNumber integerValue]]; + } + case 130: { + NSNumber *enumAsNumber = [self readValue]; + return enumAsNumber == nil ? nil + : [[FCPPlatformDeviceOrientationBox alloc] + initWithValue:[enumAsNumber integerValue]]; + } + case 131: { + NSNumber *enumAsNumber = [self readValue]; + return enumAsNumber == nil + ? nil + : [[FCPPlatformExposureModeBox alloc] initWithValue:[enumAsNumber integerValue]]; + } + case 132: { + NSNumber *enumAsNumber = [self readValue]; + return enumAsNumber == nil + ? nil + : [[FCPPlatformFlashModeBox alloc] initWithValue:[enumAsNumber integerValue]]; + } + case 133: { + NSNumber *enumAsNumber = [self readValue]; + return enumAsNumber == nil + ? nil + : [[FCPPlatformFocusModeBox alloc] initWithValue:[enumAsNumber integerValue]]; + } + case 134: { + NSNumber *enumAsNumber = [self readValue]; + return enumAsNumber == nil ? nil + : [[FCPPlatformImageFileFormatBox alloc] + initWithValue:[enumAsNumber integerValue]]; + } + case 135: { + NSNumber *enumAsNumber = [self readValue]; + return enumAsNumber == nil ? nil + : [[FCPPlatformImageFormatGroupBox alloc] + initWithValue:[enumAsNumber integerValue]]; + } + case 136: { + NSNumber *enumAsNumber = [self readValue]; + return enumAsNumber == nil ? nil + : [[FCPPlatformResolutionPresetBox alloc] + initWithValue:[enumAsNumber integerValue]]; + } + case 137: return [FCPPlatformCameraDescription fromList:[self readValue]]; - case 129: + case 138: + return [FCPPlatformCameraState fromList:[self readValue]]; + case 139: return [FCPPlatformMediaSettings fromList:[self readValue]]; - case 130: + case 140: return [FCPPlatformPoint fromList:[self readValue]]; + case 141: + return [FCPPlatformSize fromList:[self readValue]]; default: return [super readValueOfType:type]; } } @end -@interface FCPCameraApiCodecWriter : FlutterStandardWriter +@interface FCPMessagesPigeonCodecWriter : FlutterStandardWriter @end -@implementation FCPCameraApiCodecWriter +@implementation FCPMessagesPigeonCodecWriter - (void)writeValue:(id)value { - if ([value isKindOfClass:[FCPPlatformCameraDescription class]]) { - [self writeByte:128]; + if ([value isKindOfClass:[FCPPlatformCameraLensDirectionBox class]]) { + FCPPlatformCameraLensDirectionBox *box = (FCPPlatformCameraLensDirectionBox *)value; + [self writeByte:129]; + [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; + } else if ([value isKindOfClass:[FCPPlatformDeviceOrientationBox class]]) { + FCPPlatformDeviceOrientationBox *box = (FCPPlatformDeviceOrientationBox *)value; + [self writeByte:130]; + [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; + } else if ([value isKindOfClass:[FCPPlatformExposureModeBox class]]) { + FCPPlatformExposureModeBox *box = (FCPPlatformExposureModeBox *)value; + [self writeByte:131]; + [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; + } else if ([value isKindOfClass:[FCPPlatformFlashModeBox class]]) { + FCPPlatformFlashModeBox *box = (FCPPlatformFlashModeBox *)value; + [self writeByte:132]; + [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; + } else if ([value isKindOfClass:[FCPPlatformFocusModeBox class]]) { + FCPPlatformFocusModeBox *box = (FCPPlatformFocusModeBox *)value; + [self writeByte:133]; + [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; + } else if ([value isKindOfClass:[FCPPlatformImageFileFormatBox class]]) { + FCPPlatformImageFileFormatBox *box = (FCPPlatformImageFileFormatBox *)value; + [self writeByte:134]; + [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; + } else if ([value isKindOfClass:[FCPPlatformImageFormatGroupBox class]]) { + FCPPlatformImageFormatGroupBox *box = (FCPPlatformImageFormatGroupBox *)value; + [self writeByte:135]; + [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; + } else if ([value isKindOfClass:[FCPPlatformResolutionPresetBox class]]) { + FCPPlatformResolutionPresetBox *box = (FCPPlatformResolutionPresetBox *)value; + [self writeByte:136]; + [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; + } else if ([value isKindOfClass:[FCPPlatformCameraDescription class]]) { + [self writeByte:137]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FCPPlatformCameraState class]]) { + [self writeByte:138]; [self writeValue:[value toList]]; } else if ([value isKindOfClass:[FCPPlatformMediaSettings class]]) { - [self writeByte:129]; + [self writeByte:139]; [self writeValue:[value toList]]; } else if ([value isKindOfClass:[FCPPlatformPoint class]]) { - [self writeByte:130]; + [self writeByte:140]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FCPPlatformSize class]]) { + [self writeByte:141]; [self writeValue:[value toList]]; } else { [super writeValue:value]; @@ -333,27 +429,27 @@ - (void)writeValue:(id)value { } @end -@interface FCPCameraApiCodecReaderWriter : FlutterStandardReaderWriter +@interface FCPMessagesPigeonCodecReaderWriter : FlutterStandardReaderWriter @end -@implementation FCPCameraApiCodecReaderWriter +@implementation FCPMessagesPigeonCodecReaderWriter - (FlutterStandardWriter *)writerWithData:(NSMutableData *)data { - return [[FCPCameraApiCodecWriter alloc] initWithData:data]; + return [[FCPMessagesPigeonCodecWriter alloc] initWithData:data]; } - (FlutterStandardReader *)readerWithData:(NSData *)data { - return [[FCPCameraApiCodecReader alloc] initWithData:data]; + return [[FCPMessagesPigeonCodecReader alloc] initWithData:data]; } @end -NSObject *FCPCameraApiGetCodec(void) { +NSObject *FCPGetMessagesCodec(void) { static FlutterStandardMessageCodec *sSharedObject = nil; static dispatch_once_t sPred = 0; dispatch_once(&sPred, ^{ - FCPCameraApiCodecReaderWriter *readerWriter = [[FCPCameraApiCodecReaderWriter alloc] init]; + FCPMessagesPigeonCodecReaderWriter *readerWriter = + [[FCPMessagesPigeonCodecReaderWriter alloc] init]; sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter]; }); return sSharedObject; } - void SetUpFCPCameraApi(id binaryMessenger, NSObject *api) { SetUpFCPCameraApiWithSuffix(binaryMessenger, api, @""); } @@ -371,7 +467,7 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"CameraApi.getAvailableCameras", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert( [api respondsToSelector:@selector(availableCamerasWithCompletion:)], @@ -396,14 +492,14 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"dev.flutter.pigeon.camera_avfoundation.CameraApi.create", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(createCameraWithName:settings:completion:)], @"FCPCameraApi api (%@) doesn't respond to " @"@selector(createCameraWithName:settings:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; NSString *arg_cameraName = GetNullableObjectAtIndex(args, 0); FCPPlatformMediaSettings *arg_settings = GetNullableObjectAtIndex(args, 1); [api createCameraWithName:arg_cameraName @@ -425,17 +521,18 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"dev.flutter.pigeon.camera_avfoundation.CameraApi.initialize", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(initializeCamera:withImageFormat:completion:)], @"FCPCameraApi api (%@) doesn't respond to " @"@selector(initializeCamera:withImageFormat:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; NSInteger arg_cameraId = [GetNullableObjectAtIndex(args, 0) integerValue]; - FCPPlatformImageFormatGroup arg_imageFormat = - [GetNullableObjectAtIndex(args, 1) integerValue]; + FCPPlatformImageFormatGroupBox *boxedFCPPlatformImageFormatGroup = + GetNullableObjectAtIndex(args, 1); + FCPPlatformImageFormatGroup arg_imageFormat = boxedFCPPlatformImageFormatGroup.value; [api initializeCamera:arg_cameraId withImageFormat:arg_imageFormat completion:^(FlutterError *_Nullable error) { @@ -454,7 +551,7 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"CameraApi.startImageStream", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert( [api respondsToSelector:@selector(startImageStreamWithCompletion:)], @@ -478,7 +575,7 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"dev.flutter.pigeon.camera_avfoundation.CameraApi.stopImageStream", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert( [api respondsToSelector:@selector(stopImageStreamWithCompletion:)], @@ -504,7 +601,7 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"CameraApi.receivedImageStreamData", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(receivedImageStreamDataWithCompletion:)], @"FCPCameraApi api (%@) doesn't respond to " @@ -528,13 +625,13 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"dev.flutter.pigeon.camera_avfoundation.CameraApi.dispose", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(disposeCamera:completion:)], @"FCPCameraApi api (%@) doesn't respond to @selector(disposeCamera:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; NSInteger arg_cameraId = [GetNullableObjectAtIndex(args, 0) integerValue]; [api disposeCamera:arg_cameraId completion:^(FlutterError *_Nullable error) { @@ -553,16 +650,17 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"CameraApi.lockCaptureOrientation", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert( [api respondsToSelector:@selector(lockCaptureOrientation:completion:)], @"FCPCameraApi api (%@) doesn't respond to @selector(lockCaptureOrientation:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - FCPPlatformDeviceOrientation arg_orientation = - [GetNullableObjectAtIndex(args, 0) integerValue]; + NSArray *args = message; + FCPPlatformDeviceOrientationBox *boxedFCPPlatformDeviceOrientation = + GetNullableObjectAtIndex(args, 0); + FCPPlatformDeviceOrientation arg_orientation = boxedFCPPlatformDeviceOrientation.value; [api lockCaptureOrientation:arg_orientation completion:^(FlutterError *_Nullable error) { callback(wrapResult(nil, error)); @@ -581,7 +679,7 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"CameraApi.unlockCaptureOrientation", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(unlockCaptureOrientationWithCompletion:)], @"FCPCameraApi api (%@) doesn't respond to " @@ -606,7 +704,7 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"dev.flutter.pigeon.camera_avfoundation.CameraApi.takePicture", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(takePictureWithCompletion:)], @"FCPCameraApi api (%@) doesn't respond to @selector(takePictureWithCompletion:)", @@ -629,7 +727,7 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"CameraApi.prepareForVideoRecording", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(prepareForVideoRecordingWithCompletion:)], @"FCPCameraApi api (%@) doesn't respond to " @@ -653,14 +751,14 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"CameraApi.startVideoRecording", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(startVideoRecordingWithStreaming:completion:)], @"FCPCameraApi api (%@) doesn't respond to " @"@selector(startVideoRecordingWithStreaming:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; BOOL arg_enableStream = [GetNullableObjectAtIndex(args, 0) boolValue]; [api startVideoRecordingWithStreaming:arg_enableStream completion:^(FlutterError *_Nullable error) { @@ -679,7 +777,7 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"CameraApi.stopVideoRecording", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert( [api respondsToSelector:@selector(stopVideoRecordingWithCompletion:)], @@ -703,7 +801,7 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"CameraApi.pauseVideoRecording", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert( [api respondsToSelector:@selector(pauseVideoRecordingWithCompletion:)], @@ -726,7 +824,7 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"CameraApi.resumeVideoRecording", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(resumeVideoRecordingWithCompletion:)], @"FCPCameraApi api (%@) doesn't respond to " @@ -750,14 +848,15 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"dev.flutter.pigeon.camera_avfoundation.CameraApi.setFlashMode", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(setFlashMode:completion:)], @"FCPCameraApi api (%@) doesn't respond to @selector(setFlashMode:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - FCPPlatformFlashMode arg_mode = [GetNullableObjectAtIndex(args, 0) integerValue]; + NSArray *args = message; + FCPPlatformFlashModeBox *boxedFCPPlatformFlashMode = GetNullableObjectAtIndex(args, 0); + FCPPlatformFlashMode arg_mode = boxedFCPPlatformFlashMode.value; [api setFlashMode:arg_mode completion:^(FlutterError *_Nullable error) { callback(wrapResult(nil, error)); @@ -776,14 +875,16 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"dev.flutter.pigeon.camera_avfoundation.CameraApi.setExposureMode", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(setExposureMode:completion:)], @"FCPCameraApi api (%@) doesn't respond to @selector(setExposureMode:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - FCPPlatformExposureMode arg_mode = [GetNullableObjectAtIndex(args, 0) integerValue]; + NSArray *args = message; + FCPPlatformExposureModeBox *boxedFCPPlatformExposureMode = + GetNullableObjectAtIndex(args, 0); + FCPPlatformExposureMode arg_mode = boxedFCPPlatformExposureMode.value; [api setExposureMode:arg_mode completion:^(FlutterError *_Nullable error) { callback(wrapResult(nil, error)); @@ -803,13 +904,13 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"CameraApi.setExposurePoint", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(setExposurePoint:completion:)], @"FCPCameraApi api (%@) doesn't respond to @selector(setExposurePoint:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; FCPPlatformPoint *arg_point = GetNullableObjectAtIndex(args, 0); [api setExposurePoint:arg_point completion:^(FlutterError *_Nullable error) { @@ -828,7 +929,7 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"CameraApi.getMinExposureOffset", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(getMinimumExposureOffset:)], @"FCPCameraApi api (%@) doesn't respond to @selector(getMinimumExposureOffset:)", @@ -850,7 +951,7 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"CameraApi.getMaxExposureOffset", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(getMaximumExposureOffset:)], @"FCPCameraApi api (%@) doesn't respond to @selector(getMaximumExposureOffset:)", @@ -872,14 +973,14 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"CameraApi.setExposureOffset", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert( [api respondsToSelector:@selector(setExposureOffset:completion:)], @"FCPCameraApi api (%@) doesn't respond to @selector(setExposureOffset:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; double arg_offset = [GetNullableObjectAtIndex(args, 0) doubleValue]; [api setExposureOffset:arg_offset completion:^(FlutterError *_Nullable error) { @@ -899,14 +1000,15 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"dev.flutter.pigeon.camera_avfoundation.CameraApi.setFocusMode", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(setFocusMode:completion:)], @"FCPCameraApi api (%@) doesn't respond to @selector(setFocusMode:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - FCPPlatformFocusMode arg_mode = [GetNullableObjectAtIndex(args, 0) integerValue]; + NSArray *args = message; + FCPPlatformFocusModeBox *boxedFCPPlatformFocusMode = GetNullableObjectAtIndex(args, 0); + FCPPlatformFocusMode arg_mode = boxedFCPPlatformFocusMode.value; [api setFocusMode:arg_mode completion:^(FlutterError *_Nullable error) { callback(wrapResult(nil, error)); @@ -927,13 +1029,13 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"dev.flutter.pigeon.camera_avfoundation.CameraApi.setFocusPoint", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(setFocusPoint:completion:)], @"FCPCameraApi api (%@) doesn't respond to @selector(setFocusPoint:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; FCPPlatformPoint *arg_point = GetNullableObjectAtIndex(args, 0); [api setFocusPoint:arg_point completion:^(FlutterError *_Nullable error) { @@ -953,7 +1055,7 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"dev.flutter.pigeon.camera_avfoundation.CameraApi.getMinZoomLevel", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(getMinimumZoomLevel:)], @"FCPCameraApi api (%@) doesn't respond to @selector(getMinimumZoomLevel:)", api); @@ -975,7 +1077,7 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"dev.flutter.pigeon.camera_avfoundation.CameraApi.getMaxZoomLevel", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(getMaximumZoomLevel:)], @"FCPCameraApi api (%@) doesn't respond to @selector(getMaximumZoomLevel:)", api); @@ -997,13 +1099,13 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"dev.flutter.pigeon.camera_avfoundation.CameraApi.setZoomLevel", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(setZoomLevel:completion:)], @"FCPCameraApi api (%@) doesn't respond to @selector(setZoomLevel:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; double arg_zoom = [GetNullableObjectAtIndex(args, 0) doubleValue]; [api setZoomLevel:arg_zoom completion:^(FlutterError *_Nullable error) { @@ -1023,7 +1125,7 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"dev.flutter.pigeon.camera_avfoundation.CameraApi.pausePreview", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(pausePreviewWithCompletion:)], @"FCPCameraApi api (%@) doesn't respond to @selector(pausePreviewWithCompletion:)", @@ -1046,7 +1148,7 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"dev.flutter.pigeon.camera_avfoundation.CameraApi.resumePreview", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(resumePreviewWithCompletion:)], @"FCPCameraApi api (%@) doesn't respond to @selector(resumePreviewWithCompletion:)", @@ -1070,7 +1172,7 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"CameraApi.updateDescriptionWhileRecording", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(updateDescriptionWhileRecordingCameraName: completion:)], @@ -1078,7 +1180,7 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"@selector(updateDescriptionWhileRecordingCameraName:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; NSString *arg_cameraName = GetNullableObjectAtIndex(args, 0); [api updateDescriptionWhileRecordingCameraName:arg_cameraName completion:^(FlutterError *_Nullable error) { @@ -1097,15 +1199,17 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, @"CameraApi.setImageFileFormat", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FCPCameraApiGetCodec()]; + codec:FCPGetMessagesCodec()]; if (api) { NSCAssert( [api respondsToSelector:@selector(setImageFileFormat:completion:)], @"FCPCameraApi api (%@) doesn't respond to @selector(setImageFileFormat:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - FCPPlatformImageFileFormat arg_format = [GetNullableObjectAtIndex(args, 0) integerValue]; + NSArray *args = message; + FCPPlatformImageFileFormatBox *boxedFCPPlatformImageFileFormat = + GetNullableObjectAtIndex(args, 0); + FCPPlatformImageFileFormat arg_format = boxedFCPPlatformImageFileFormat.value; [api setImageFileFormat:arg_format completion:^(FlutterError *_Nullable error) { callback(wrapResult(nil, error)); @@ -1116,12 +1220,6 @@ void SetUpFCPCameraApiWithSuffix(id binaryMessenger, } } } -NSObject *FCPCameraGlobalEventApiGetCodec(void) { - static FlutterStandardMessageCodec *sSharedObject = nil; - sSharedObject = [FlutterStandardMessageCodec sharedInstance]; - return sSharedObject; -} - @interface FCPCameraGlobalEventApi () @property(nonatomic, strong) NSObject *binaryMessenger; @property(nonatomic, strong) NSString *messageChannelSuffix; @@ -1153,8 +1251,8 @@ - (void)deviceOrientationChangedOrientation:(FCPPlatformDeviceOrientation)arg_or FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:FCPCameraGlobalEventApiGetCodec()]; - [channel sendMessage:@[ [NSNumber numberWithInteger:arg_orientation] ] + codec:FCPGetMessagesCodec()]; + [channel sendMessage:@[ [[FCPPlatformDeviceOrientationBox alloc] initWithValue:arg_orientation] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -1171,59 +1269,6 @@ - (void)deviceOrientationChangedOrientation:(FCPPlatformDeviceOrientation)arg_or } @end -@interface FCPCameraEventApiCodecReader : FlutterStandardReader -@end -@implementation FCPCameraEventApiCodecReader -- (nullable id)readValueOfType:(UInt8)type { - switch (type) { - case 128: - return [FCPPlatformCameraState fromList:[self readValue]]; - case 129: - return [FCPPlatformSize fromList:[self readValue]]; - default: - return [super readValueOfType:type]; - } -} -@end - -@interface FCPCameraEventApiCodecWriter : FlutterStandardWriter -@end -@implementation FCPCameraEventApiCodecWriter -- (void)writeValue:(id)value { - if ([value isKindOfClass:[FCPPlatformCameraState class]]) { - [self writeByte:128]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FCPPlatformSize class]]) { - [self writeByte:129]; - [self writeValue:[value toList]]; - } else { - [super writeValue:value]; - } -} -@end - -@interface FCPCameraEventApiCodecReaderWriter : FlutterStandardReaderWriter -@end -@implementation FCPCameraEventApiCodecReaderWriter -- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data { - return [[FCPCameraEventApiCodecWriter alloc] initWithData:data]; -} -- (FlutterStandardReader *)readerWithData:(NSData *)data { - return [[FCPCameraEventApiCodecReader alloc] initWithData:data]; -} -@end - -NSObject *FCPCameraEventApiGetCodec(void) { - static FlutterStandardMessageCodec *sSharedObject = nil; - static dispatch_once_t sPred = 0; - dispatch_once(&sPred, ^{ - FCPCameraEventApiCodecReaderWriter *readerWriter = - [[FCPCameraEventApiCodecReaderWriter alloc] init]; - sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter]; - }); - return sSharedObject; -} - @interface FCPCameraEventApi () @property(nonatomic, strong) NSObject *binaryMessenger; @property(nonatomic, strong) NSString *messageChannelSuffix; @@ -1254,7 +1299,7 @@ - (void)initializedWithState:(FCPPlatformCameraState *)arg_initialState FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:FCPCameraEventApiGetCodec()]; + codec:FCPGetMessagesCodec()]; [channel sendMessage:@[ arg_initialState ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { @@ -1278,7 +1323,7 @@ - (void)reportError:(NSString *)arg_message FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:FCPCameraEventApiGetCodec()]; + codec:FCPGetMessagesCodec()]; [channel sendMessage:@[ arg_message ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { diff --git a/packages/camera/camera_avfoundation/lib/src/avfoundation_camera.dart b/packages/camera/camera_avfoundation/lib/src/avfoundation_camera.dart index 6f947863a3c0..286e01940bfa 100644 --- a/packages/camera/camera_avfoundation/lib/src/avfoundation_camera.dart +++ b/packages/camera/camera_avfoundation/lib/src/avfoundation_camera.dart @@ -68,8 +68,6 @@ class AVFoundationCamera extends CameraPlatform { Future> availableCameras() async { try { return (await _hostApi.getAvailableCameras()) - // See comment in messages.dart for why this is safe. - .map((PlatformCameraDescription? c) => c!) .map(cameraDescriptionFromPlatform) .toList(); } on PlatformException catch (e) { @@ -207,8 +205,8 @@ class AVFoundationCamera extends CameraPlatform { @override Future startVideoRecording(int cameraId, {Duration? maxVideoDuration}) async { - return startVideoCapturing( - VideoCaptureOptions(cameraId, maxDuration: maxVideoDuration)); + // Ignore maxVideoDuration, as it is unimplemented and deprecated. + return startVideoCapturing(VideoCaptureOptions(cameraId)); } @override diff --git a/packages/camera/camera_avfoundation/lib/src/messages.g.dart b/packages/camera/camera_avfoundation/lib/src/messages.g.dart index 4290eb02ed2e..535f03e34c2e 100644 --- a/packages/camera/camera_avfoundation/lib/src/messages.g.dart +++ b/packages/camera/camera_avfoundation/lib/src/messages.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 (v18.0.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.2), 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 @@ -99,7 +99,7 @@ class PlatformCameraDescription { Object encode() { return [ name, - lensDirection.index, + lensDirection, ]; } @@ -107,7 +107,7 @@ class PlatformCameraDescription { result as List; return PlatformCameraDescription( name: result[0]! as String, - lensDirection: PlatformCameraLensDirection.values[result[1]! as int], + lensDirection: result[1]! as PlatformCameraLensDirection, ); } } @@ -138,9 +138,9 @@ class PlatformCameraState { Object encode() { return [ - previewSize.encode(), - exposureMode.index, - focusMode.index, + previewSize, + exposureMode, + focusMode, exposurePointSupported, focusPointSupported, ]; @@ -149,9 +149,9 @@ class PlatformCameraState { static PlatformCameraState decode(Object result) { result as List; return PlatformCameraState( - previewSize: PlatformSize.decode(result[0]! as List), - exposureMode: PlatformExposureMode.values[result[1]! as int], - focusMode: PlatformFocusMode.values[result[2]! as int], + previewSize: result[0]! as PlatformSize, + exposureMode: result[1]! as PlatformExposureMode, + focusMode: result[2]! as PlatformFocusMode, exposurePointSupported: result[3]! as bool, focusPointSupported: result[4]! as bool, ); @@ -179,7 +179,7 @@ class PlatformMediaSettings { Object encode() { return [ - resolutionPreset.index, + resolutionPreset, framesPerSecond, videoBitrate, audioBitrate, @@ -190,7 +190,7 @@ class PlatformMediaSettings { static PlatformMediaSettings decode(Object result) { result as List; return PlatformMediaSettings( - resolutionPreset: PlatformResolutionPreset.values[result[0]! as int], + resolutionPreset: result[0]! as PlatformResolutionPreset, framesPerSecond: result[1] as int?, videoBitrate: result[2] as int?, audioBitrate: result[3] as int?, @@ -251,18 +251,51 @@ class PlatformSize { } } -class _CameraApiCodec extends StandardMessageCodec { - const _CameraApiCodec(); +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is PlatformCameraDescription) { - buffer.putUint8(128); + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is PlatformCameraLensDirection) { + buffer.putUint8(129); + writeValue(buffer, value.index); + } else if (value is PlatformDeviceOrientation) { + buffer.putUint8(130); + writeValue(buffer, value.index); + } else if (value is PlatformExposureMode) { + buffer.putUint8(131); + writeValue(buffer, value.index); + } else if (value is PlatformFlashMode) { + buffer.putUint8(132); + writeValue(buffer, value.index); + } else if (value is PlatformFocusMode) { + buffer.putUint8(133); + writeValue(buffer, value.index); + } else if (value is PlatformImageFileFormat) { + buffer.putUint8(134); + writeValue(buffer, value.index); + } else if (value is PlatformImageFormatGroup) { + buffer.putUint8(135); + writeValue(buffer, value.index); + } else if (value is PlatformResolutionPreset) { + buffer.putUint8(136); + writeValue(buffer, value.index); + } else if (value is PlatformCameraDescription) { + buffer.putUint8(137); + writeValue(buffer, value.encode()); + } else if (value is PlatformCameraState) { + buffer.putUint8(138); writeValue(buffer, value.encode()); } else if (value is PlatformMediaSettings) { - buffer.putUint8(129); + buffer.putUint8(139); writeValue(buffer, value.encode()); } else if (value is PlatformPoint) { - buffer.putUint8(130); + buffer.putUint8(140); + writeValue(buffer, value.encode()); + } else if (value is PlatformSize) { + buffer.putUint8(141); writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); @@ -272,12 +305,40 @@ class _CameraApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: - return PlatformCameraDescription.decode(readValue(buffer)!); case 129: - return PlatformMediaSettings.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformCameraLensDirection.values[value]; case 130: + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformDeviceOrientation.values[value]; + case 131: + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformExposureMode.values[value]; + case 132: + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformFlashMode.values[value]; + case 133: + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformFocusMode.values[value]; + case 134: + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformImageFileFormat.values[value]; + case 135: + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformImageFormatGroup.values[value]; + case 136: + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformResolutionPreset.values[value]; + case 137: + return PlatformCameraDescription.decode(readValue(buffer)!); + case 138: + return PlatformCameraState.decode(readValue(buffer)!); + case 139: + return PlatformMediaSettings.decode(readValue(buffer)!); + case 140: return PlatformPoint.decode(readValue(buffer)!); + case 141: + return PlatformSize.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -290,96 +351,96 @@ class CameraApi { /// BinaryMessenger will be used which routes to the host platform. CameraApi( {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : __pigeon_binaryMessenger = binaryMessenger, - __pigeon_messageChannelSuffix = + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; - final BinaryMessenger? __pigeon_binaryMessenger; + final BinaryMessenger? pigeonVar_binaryMessenger; - static const MessageCodec pigeonChannelCodec = _CameraApiCodec(); + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - final String __pigeon_messageChannelSuffix; + final String pigeonVar_messageChannelSuffix; /// Returns the list of available cameras. - Future> getAvailableCameras() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.getAvailableCameras$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + Future> getAvailableCameras() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.getAvailableCameras$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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(); } } /// Create a new camera with the given settings, and returns its ID. Future create(String cameraName, PlatformMediaSettings settings) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.create$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.create$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([cameraName, settings]) 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 int?)!; + return (pigeonVar_replyList[0] as int?)!; } } /// Initializes the camera with the given ID. Future initialize( int cameraId, PlatformImageFormatGroup imageFormat) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.initialize$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.initialize$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([cameraId, imageFormat.index]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([cameraId, imageFormat]) 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; @@ -388,23 +449,23 @@ class CameraApi { /// Begins streaming frames from the camera. Future startImageStream() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.startImageStream$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.startImageStream$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; @@ -413,23 +474,23 @@ class CameraApi { /// Stops streaming frames from the camera. Future stopImageStream() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.stopImageStream$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.stopImageStream$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; @@ -441,23 +502,23 @@ class CameraApi { /// /// This is used to throttle sending frames across the channel. Future receivedImageStreamData() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.receivedImageStreamData$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.receivedImageStreamData$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; @@ -467,23 +528,23 @@ class CameraApi { /// Indicates that the given camera is no longer being used on the Dart side, /// and any associated resources can be cleaned up. Future dispose(int cameraId) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.dispose$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.dispose$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([cameraId]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([cameraId]) 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; @@ -493,23 +554,23 @@ class CameraApi { /// Locks the camera capture to the current device orientation. Future lockCaptureOrientation( PlatformDeviceOrientation orientation) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.lockCaptureOrientation$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.lockCaptureOrientation$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([orientation.index]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([orientation]) 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; @@ -519,23 +580,23 @@ class CameraApi { /// Unlocks camera capture orientation, allowing it to automatically adapt to /// device orientation. Future unlockCaptureOrientation() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.unlockCaptureOrientation$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.unlockCaptureOrientation$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; @@ -545,53 +606,53 @@ class CameraApi { /// Takes a picture with the current settings, and returns the path to the /// resulting file. Future takePicture() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.takePicture$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.takePicture$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 String?)!; + return (pigeonVar_replyList[0] as String?)!; } } /// Does any preprocessing necessary before beginning to record video. Future prepareForVideoRecording() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.prepareForVideoRecording$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.prepareForVideoRecording$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; @@ -601,23 +662,23 @@ class CameraApi { /// Begins recording video, optionally enabling streaming to Dart at the same /// time. Future startVideoRecording(bool enableStream) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.startVideoRecording$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.startVideoRecording$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([enableStream]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([enableStream]) 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; @@ -626,53 +687,53 @@ class CameraApi { /// Stops recording video, and results the path to the resulting file. Future stopVideoRecording() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.stopVideoRecording$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.stopVideoRecording$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 String?)!; + return (pigeonVar_replyList[0] as String?)!; } } /// Pauses video recording. Future pauseVideoRecording() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.pauseVideoRecording$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.pauseVideoRecording$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; @@ -681,23 +742,23 @@ class CameraApi { /// Resumes a previously paused video recording. Future resumeVideoRecording() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.resumeVideoRecording$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.resumeVideoRecording$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; @@ -706,23 +767,23 @@ class CameraApi { /// Switches the camera to the given flash mode. Future setFlashMode(PlatformFlashMode mode) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setFlashMode$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setFlashMode$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([mode.index]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([mode]) 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; @@ -731,23 +792,23 @@ class CameraApi { /// Switches the camera to the given exposure mode. Future setExposureMode(PlatformExposureMode mode) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setExposureMode$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setExposureMode$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([mode.index]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([mode]) 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; @@ -758,23 +819,23 @@ class CameraApi { /// /// A null value resets to the default exposure point. Future setExposurePoint(PlatformPoint? point) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setExposurePoint$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setExposurePoint$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([point]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([point]) 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; @@ -783,83 +844,83 @@ class CameraApi { /// Returns the minimum exposure offset supported by the camera. Future getMinExposureOffset() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.getMinExposureOffset$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.getMinExposureOffset$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 double?)!; + return (pigeonVar_replyList[0] as double?)!; } } /// Returns the maximum exposure offset supported by the camera. Future getMaxExposureOffset() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.getMaxExposureOffset$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.getMaxExposureOffset$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 double?)!; + return (pigeonVar_replyList[0] as double?)!; } } /// Sets the exposure offset manually to the given value. Future setExposureOffset(double offset) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setExposureOffset$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setExposureOffset$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([offset]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([offset]) 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; @@ -868,23 +929,23 @@ class CameraApi { /// Switches the camera to the given focus mode. Future setFocusMode(PlatformFocusMode mode) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setFocusMode$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setFocusMode$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([mode.index]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([mode]) 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; @@ -895,23 +956,23 @@ class CameraApi { /// /// A null value resets to the default focus point. Future setFocusPoint(PlatformPoint? point) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setFocusPoint$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setFocusPoint$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([point]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([point]) 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; @@ -920,83 +981,83 @@ class CameraApi { /// Returns the minimum zoom level supported by the camera. Future getMinZoomLevel() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.getMinZoomLevel$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.getMinZoomLevel$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 double?)!; + return (pigeonVar_replyList[0] as double?)!; } } /// Returns the maximum zoom level supported by the camera. Future getMaxZoomLevel() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.getMaxZoomLevel$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.getMaxZoomLevel$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 double?)!; + return (pigeonVar_replyList[0] as double?)!; } } /// Sets the zoom factor. Future setZoomLevel(double zoom) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setZoomLevel$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setZoomLevel$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([zoom]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([zoom]) 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; @@ -1005,23 +1066,23 @@ class CameraApi { /// Pauses streaming of preview frames. Future pausePreview() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.pausePreview$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.pausePreview$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; @@ -1030,23 +1091,23 @@ class CameraApi { /// Resumes a previously paused preview stream. Future resumePreview() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.resumePreview$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.resumePreview$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; @@ -1057,23 +1118,23 @@ class CameraApi { /// /// This should only be called while video recording is active. Future updateDescriptionWhileRecording(String cameraName) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.updateDescriptionWhileRecording$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.updateDescriptionWhileRecording$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([cameraName]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([cameraName]) 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; @@ -1082,23 +1143,23 @@ class CameraApi { /// Sets the file format used for taking pictures. Future setImageFileFormat(PlatformImageFileFormat format) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setImageFileFormat$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setImageFileFormat$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([format.index]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([format]) 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; @@ -1108,8 +1169,7 @@ class CameraApi { /// Handler for native callbacks that are not tied to a specific camera ID. abstract class CameraGlobalEventApi { - static const MessageCodec pigeonChannelCodec = - StandardMessageCodec(); + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); /// Called when the device's physical orientation changes. void deviceOrientationChanged(PlatformDeviceOrientation orientation); @@ -1122,21 +1182,21 @@ abstract class CameraGlobalEventApi { messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.camera_avfoundation.CameraGlobalEventApi.deviceOrientationChanged$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.camera_avfoundation.CameraGlobalEventApi.deviceOrientationChanged was null.'); final List args = (message as List?)!; - final PlatformDeviceOrientation? arg_orientation = args[0] == null - ? null - : PlatformDeviceOrientation.values[args[0]! as int]; + final PlatformDeviceOrientation? arg_orientation = + (args[0] as PlatformDeviceOrientation?); assert(arg_orientation != null, 'Argument for dev.flutter.pigeon.camera_avfoundation.CameraGlobalEventApi.deviceOrientationChanged was null, expected non-null PlatformDeviceOrientation.'); try { @@ -1154,40 +1214,11 @@ abstract class CameraGlobalEventApi { } } -class _CameraEventApiCodec extends StandardMessageCodec { - const _CameraEventApiCodec(); - @override - void writeValue(WriteBuffer buffer, Object? value) { - if (value is PlatformCameraState) { - buffer.putUint8(128); - writeValue(buffer, value.encode()); - } else if (value is PlatformSize) { - buffer.putUint8(129); - writeValue(buffer, value.encode()); - } else { - super.writeValue(buffer, value); - } - } - - @override - Object? readValueOfType(int type, ReadBuffer buffer) { - switch (type) { - case 128: - return PlatformCameraState.decode(readValue(buffer)!); - case 129: - return PlatformSize.decode(readValue(buffer)!); - default: - return super.readValueOfType(type, buffer); - } - } -} - /// Handler for native callbacks that are tied to a specific camera ID. /// /// This is intended to be initialized with the camera ID as a suffix. abstract class CameraEventApi { - static const MessageCodec pigeonChannelCodec = - _CameraEventApiCodec(); + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); /// Called when the camera is inialitized for use. void initialized(PlatformCameraState initialState); @@ -1206,15 +1237,16 @@ abstract class CameraEventApi { messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.camera_avfoundation.CameraEventApi.initialized$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.camera_avfoundation.CameraEventApi.initialized was null.'); final List args = (message as List?)!; @@ -1235,15 +1267,16 @@ abstract class CameraEventApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.camera_avfoundation.CameraEventApi.error$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.camera_avfoundation.CameraEventApi.error was null.'); final List args = (message as List?)!; diff --git a/packages/camera/camera_avfoundation/pigeons/messages.dart b/packages/camera/camera_avfoundation/pigeons/messages.dart index f99e03f2a4df..272ea288960d 100644 --- a/packages/camera/camera_avfoundation/pigeons/messages.dart +++ b/packages/camera/camera_avfoundation/pigeons/messages.dart @@ -6,9 +6,14 @@ import 'package:pigeon/pigeon.dart'; @ConfigurePigeon(PigeonOptions( dartOut: 'lib/src/messages.g.dart', - objcHeaderOut: 'ios/Classes/messages.g.h', - objcSourceOut: 'ios/Classes/messages.g.m', - objcOptions: ObjcOptions(prefix: 'FCP'), + objcHeaderOut: + 'ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/messages.g.h', + objcSourceOut: + 'ios/camera_avfoundation/Sources/camera_avfoundation/messages.g.m', + objcOptions: ObjcOptions( + prefix: 'FCP', + headerIncludePath: './include/camera_avfoundation/messages.g.h', + ), copyrightHeader: 'pigeons/copyright.txt', )) @@ -155,7 +160,7 @@ abstract class CameraApi { // The consuming code treats it as non-nullable. @async @ObjCSelector('availableCamerasWithCompletion') - List getAvailableCameras(); + List getAvailableCameras(); /// Create a new camera with the given settings, and returns its ID. @async diff --git a/packages/camera/camera_avfoundation/pubspec.yaml b/packages/camera/camera_avfoundation/pubspec.yaml index b91fe76ae3f3..6ceb0b934f6e 100644 --- a/packages/camera/camera_avfoundation/pubspec.yaml +++ b/packages/camera/camera_avfoundation/pubspec.yaml @@ -2,11 +2,11 @@ name: camera_avfoundation description: iOS implementation of the camera plugin. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_avfoundation issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.9.16 +version: 0.9.17+5 environment: - sdk: ^3.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -27,8 +27,8 @@ dev_dependencies: build_runner: ^2.4.9 flutter_test: sdk: flutter - mockito: 5.4.4 - pigeon: ^18.0.0 + mockito: ^5.4.4 + pigeon: ^22.4.2 topics: - camera diff --git a/packages/camera/camera_avfoundation/test/avfoundation_camera_test.mocks.dart b/packages/camera/camera_avfoundation/test/avfoundation_camera_test.mocks.dart index 729b39f7f283..b1118578a169 100644 --- a/packages/camera/camera_avfoundation/test/avfoundation_camera_test.mocks.dart +++ b/packages/camera/camera_avfoundation/test/avfoundation_camera_test.mocks.dart @@ -3,11 +3,11 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i3; +import 'dart:async' as _i4; import 'package:camera_avfoundation/src/messages.g.dart' as _i2; import 'package:mockito/mockito.dart' as _i1; -import 'package:mockito/src/dummies.dart' as _i4; +import 'package:mockito/src/dummies.dart' as _i3; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -27,21 +27,34 @@ import 'package:mockito/src/dummies.dart' as _i4; /// See the documentation for Mockito's code generation for more information. class MockCameraApi extends _i1.Mock implements _i2.CameraApi { @override - _i3.Future> getAvailableCameras() => + String get pigeonVar_messageChannelSuffix => (super.noSuchMethod( + Invocation.getter(#pigeonVar_messageChannelSuffix), + returnValue: _i3.dummyValue( + this, + Invocation.getter(#pigeonVar_messageChannelSuffix), + ), + returnValueForMissingStub: _i3.dummyValue( + this, + Invocation.getter(#pigeonVar_messageChannelSuffix), + ), + ) as String); + + @override + _i4.Future> getAvailableCameras() => (super.noSuchMethod( Invocation.method( #getAvailableCameras, [], ), - returnValue: _i3.Future>.value( - <_i2.PlatformCameraDescription?>[]), + returnValue: _i4.Future>.value( + <_i2.PlatformCameraDescription>[]), returnValueForMissingStub: - _i3.Future>.value( - <_i2.PlatformCameraDescription?>[]), - ) as _i3.Future>); + _i4.Future>.value( + <_i2.PlatformCameraDescription>[]), + ) as _i4.Future>); @override - _i3.Future create( + _i4.Future create( String? cameraName, _i2.PlatformMediaSettings? settings, ) => @@ -53,12 +66,12 @@ class MockCameraApi extends _i1.Mock implements _i2.CameraApi { settings, ], ), - returnValue: _i3.Future.value(0), - returnValueForMissingStub: _i3.Future.value(0), - ) as _i3.Future); + returnValue: _i4.Future.value(0), + returnValueForMissingStub: _i4.Future.value(0), + ) as _i4.Future); @override - _i3.Future initialize( + _i4.Future initialize( int? cameraId, _i2.PlatformImageFormatGroup? imageFormat, ) => @@ -70,79 +83,79 @@ class MockCameraApi extends _i1.Mock implements _i2.CameraApi { imageFormat, ], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future startImageStream() => (super.noSuchMethod( + _i4.Future startImageStream() => (super.noSuchMethod( Invocation.method( #startImageStream, [], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future stopImageStream() => (super.noSuchMethod( + _i4.Future stopImageStream() => (super.noSuchMethod( Invocation.method( #stopImageStream, [], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future receivedImageStreamData() => (super.noSuchMethod( + _i4.Future receivedImageStreamData() => (super.noSuchMethod( Invocation.method( #receivedImageStreamData, [], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future dispose(int? cameraId) => (super.noSuchMethod( + _i4.Future dispose(int? cameraId) => (super.noSuchMethod( Invocation.method( #dispose, [cameraId], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future lockCaptureOrientation( + _i4.Future lockCaptureOrientation( _i2.PlatformDeviceOrientation? orientation) => (super.noSuchMethod( Invocation.method( #lockCaptureOrientation, [orientation], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future unlockCaptureOrientation() => (super.noSuchMethod( + _i4.Future unlockCaptureOrientation() => (super.noSuchMethod( Invocation.method( #unlockCaptureOrientation, [], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future takePicture() => (super.noSuchMethod( + _i4.Future takePicture() => (super.noSuchMethod( Invocation.method( #takePicture, [], ), - returnValue: _i3.Future.value(_i4.dummyValue( + returnValue: _i4.Future.value(_i3.dummyValue( this, Invocation.method( #takePicture, @@ -150,43 +163,43 @@ class MockCameraApi extends _i1.Mock implements _i2.CameraApi { ), )), returnValueForMissingStub: - _i3.Future.value(_i4.dummyValue( + _i4.Future.value(_i3.dummyValue( this, Invocation.method( #takePicture, [], ), )), - ) as _i3.Future); + ) as _i4.Future); @override - _i3.Future prepareForVideoRecording() => (super.noSuchMethod( + _i4.Future prepareForVideoRecording() => (super.noSuchMethod( Invocation.method( #prepareForVideoRecording, [], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future startVideoRecording(bool? enableStream) => + _i4.Future startVideoRecording(bool? enableStream) => (super.noSuchMethod( Invocation.method( #startVideoRecording, [enableStream], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future stopVideoRecording() => (super.noSuchMethod( + _i4.Future stopVideoRecording() => (super.noSuchMethod( Invocation.method( #stopVideoRecording, [], ), - returnValue: _i3.Future.value(_i4.dummyValue( + returnValue: _i4.Future.value(_i3.dummyValue( this, Invocation.method( #stopVideoRecording, @@ -194,189 +207,189 @@ class MockCameraApi extends _i1.Mock implements _i2.CameraApi { ), )), returnValueForMissingStub: - _i3.Future.value(_i4.dummyValue( + _i4.Future.value(_i3.dummyValue( this, Invocation.method( #stopVideoRecording, [], ), )), - ) as _i3.Future); + ) as _i4.Future); @override - _i3.Future pauseVideoRecording() => (super.noSuchMethod( + _i4.Future pauseVideoRecording() => (super.noSuchMethod( Invocation.method( #pauseVideoRecording, [], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future resumeVideoRecording() => (super.noSuchMethod( + _i4.Future resumeVideoRecording() => (super.noSuchMethod( Invocation.method( #resumeVideoRecording, [], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future setFlashMode(_i2.PlatformFlashMode? mode) => + _i4.Future setFlashMode(_i2.PlatformFlashMode? mode) => (super.noSuchMethod( Invocation.method( #setFlashMode, [mode], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future setExposureMode(_i2.PlatformExposureMode? mode) => + _i4.Future setExposureMode(_i2.PlatformExposureMode? mode) => (super.noSuchMethod( Invocation.method( #setExposureMode, [mode], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future setExposurePoint(_i2.PlatformPoint? point) => + _i4.Future setExposurePoint(_i2.PlatformPoint? point) => (super.noSuchMethod( Invocation.method( #setExposurePoint, [point], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future getMinExposureOffset() => (super.noSuchMethod( + _i4.Future getMinExposureOffset() => (super.noSuchMethod( Invocation.method( #getMinExposureOffset, [], ), - returnValue: _i3.Future.value(0.0), - returnValueForMissingStub: _i3.Future.value(0.0), - ) as _i3.Future); + returnValue: _i4.Future.value(0.0), + returnValueForMissingStub: _i4.Future.value(0.0), + ) as _i4.Future); @override - _i3.Future getMaxExposureOffset() => (super.noSuchMethod( + _i4.Future getMaxExposureOffset() => (super.noSuchMethod( Invocation.method( #getMaxExposureOffset, [], ), - returnValue: _i3.Future.value(0.0), - returnValueForMissingStub: _i3.Future.value(0.0), - ) as _i3.Future); + returnValue: _i4.Future.value(0.0), + returnValueForMissingStub: _i4.Future.value(0.0), + ) as _i4.Future); @override - _i3.Future setExposureOffset(double? offset) => (super.noSuchMethod( + _i4.Future setExposureOffset(double? offset) => (super.noSuchMethod( Invocation.method( #setExposureOffset, [offset], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future setFocusMode(_i2.PlatformFocusMode? mode) => + _i4.Future setFocusMode(_i2.PlatformFocusMode? mode) => (super.noSuchMethod( Invocation.method( #setFocusMode, [mode], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future setFocusPoint(_i2.PlatformPoint? point) => + _i4.Future setFocusPoint(_i2.PlatformPoint? point) => (super.noSuchMethod( Invocation.method( #setFocusPoint, [point], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future getMinZoomLevel() => (super.noSuchMethod( + _i4.Future getMinZoomLevel() => (super.noSuchMethod( Invocation.method( #getMinZoomLevel, [], ), - returnValue: _i3.Future.value(0.0), - returnValueForMissingStub: _i3.Future.value(0.0), - ) as _i3.Future); + returnValue: _i4.Future.value(0.0), + returnValueForMissingStub: _i4.Future.value(0.0), + ) as _i4.Future); @override - _i3.Future getMaxZoomLevel() => (super.noSuchMethod( + _i4.Future getMaxZoomLevel() => (super.noSuchMethod( Invocation.method( #getMaxZoomLevel, [], ), - returnValue: _i3.Future.value(0.0), - returnValueForMissingStub: _i3.Future.value(0.0), - ) as _i3.Future); + returnValue: _i4.Future.value(0.0), + returnValueForMissingStub: _i4.Future.value(0.0), + ) as _i4.Future); @override - _i3.Future setZoomLevel(double? zoom) => (super.noSuchMethod( + _i4.Future setZoomLevel(double? zoom) => (super.noSuchMethod( Invocation.method( #setZoomLevel, [zoom], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future pausePreview() => (super.noSuchMethod( + _i4.Future pausePreview() => (super.noSuchMethod( Invocation.method( #pausePreview, [], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future resumePreview() => (super.noSuchMethod( + _i4.Future resumePreview() => (super.noSuchMethod( Invocation.method( #resumePreview, [], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future updateDescriptionWhileRecording(String? cameraName) => + _i4.Future updateDescriptionWhileRecording(String? cameraName) => (super.noSuchMethod( Invocation.method( #updateDescriptionWhileRecording, [cameraName], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future setImageFileFormat(_i2.PlatformImageFileFormat? format) => + _i4.Future setImageFileFormat(_i2.PlatformImageFileFormat? format) => (super.noSuchMethod( Invocation.method( #setImageFileFormat, [format], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); } diff --git a/packages/camera/camera_platform_interface/CHANGELOG.md b/packages/camera/camera_platform_interface/CHANGELOG.md index a51a5a0d491e..4ae1a540978c 100644 --- a/packages/camera/camera_platform_interface/CHANGELOG.md +++ b/packages/camera/camera_platform_interface/CHANGELOG.md @@ -1,5 +1,11 @@ ## NEXT +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + +## 2.8.0 + +* Deprecates `maxVideoDuration`/`maxDuration`, as it was never implemented on + most platforms, and there is no plan to implement it in the future. * Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. ## 2.7.4 diff --git a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart index c791d030ca2c..218de02c6358 100644 --- a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart +++ b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart @@ -140,14 +140,13 @@ abstract class CameraPlatform extends PlatformInterface { /// Starts a video recording. /// - /// The length of the recording can be limited by specifying the [maxVideoDuration]. - /// By default no maximum duration is specified, - /// meaning the recording will continue until manually stopped. - /// With [maxVideoDuration] set the video is returned in a [VideoRecordedEvent] - /// through the [onVideoRecordedEvent] stream when the set duration is reached. - /// /// This method is deprecated in favour of [startVideoCapturing]. - Future startVideoRecording(int cameraId, {Duration? maxVideoDuration}) { + Future startVideoRecording( + int cameraId, { + @Deprecated( + 'This parameter is unused, and will be ignored on all platforms') + Duration? maxVideoDuration, + }) { throw UnimplementedError('startVideoRecording() is not implemented.'); } @@ -156,8 +155,7 @@ abstract class CameraPlatform extends PlatformInterface { /// Please see [VideoCaptureOptions] for documentation on the /// configuration options. Future startVideoCapturing(VideoCaptureOptions options) { - return startVideoRecording(options.cameraId, - maxVideoDuration: options.maxDuration); + return startVideoRecording(options.cameraId); } /// Stops the video recording and returns the file where it was saved. diff --git a/packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart b/packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart index 7a10b3b87c35..66ee5357d30d 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart @@ -12,6 +12,8 @@ class VideoCaptureOptions { /// Constructs a new instance. const VideoCaptureOptions( this.cameraId, { + @Deprecated( + 'This parameter is unused, and will be ignored on all platforms') this.maxDuration, this.streamCallback, this.streamOptions, @@ -24,8 +26,9 @@ class VideoCaptureOptions { final int cameraId; /// The maximum time to perform capturing for. - /// - /// By default there is no maximum on the capture time. + @Deprecated('This parameter is unused, and will be ignored on all platforms') + // Platform implementations should not implement this, as it will never be + // passed from the app-facing layer. final Duration? maxDuration; /// An optional callback to enable streaming. diff --git a/packages/camera/camera_platform_interface/pubspec.yaml b/packages/camera/camera_platform_interface/pubspec.yaml index 50a6a9b4af53..8ed6c9e70c61 100644 --- a/packages/camera/camera_platform_interface/pubspec.yaml +++ b/packages/camera/camera_platform_interface/pubspec.yaml @@ -4,11 +4,11 @@ repository: https://github.com/flutter/packages/tree/main/packages/camera/camera issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.7.4 +version: 2.8.0 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: cross_file: ^0.3.1 diff --git a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart index 7cf878b8c385..063633255c99 100644 --- a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart +++ b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart @@ -643,30 +643,6 @@ void main() { ]); }); - test('Should pass maxVideoDuration when starting recording a video', - () async { - // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: 'plugins.flutter.io/camera', - methods: {'startVideoRecording': null}, - ); - - // Act - await camera.startVideoRecording( - cameraId, - maxVideoDuration: const Duration(seconds: 10), - ); - - // Assert - expect(channel.log, [ - isMethodCall('startVideoRecording', arguments: { - 'cameraId': cameraId, - 'maxVideoDuration': 10000, - 'enableStream': false, - }), - ]); - }); - test('Should stop a video recording and return the file', () async { // Arrange final MethodChannelMock channel = MethodChannelMock( diff --git a/packages/camera/camera_web/CHANGELOG.md b/packages/camera/camera_web/CHANGELOG.md index 9788191de351..fe5ec3a9d1d9 100644 --- a/packages/camera/camera_web/CHANGELOG.md +++ b/packages/camera/camera_web/CHANGELOG.md @@ -1,5 +1,17 @@ ## NEXT +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + +## 0.3.5 + +* Migrates to package:web to support WASM +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + +## 0.3.4 + +* Removes `maxVideoDuration`/`maxDuration`, as the feature was never exposed at + the app-facing package level, and is deprecated at the platform interface + level. * Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. ## 0.3.3 diff --git a/packages/camera/camera_web/README.md b/packages/camera/camera_web/README.md index 6ebf24e9bb53..1d20e9a88fcb 100644 --- a/packages/camera/camera_web/README.md +++ b/packages/camera/camera_web/README.md @@ -8,7 +8,7 @@ The web implementation of [`camera`][camera]. ### Depend on the package -This package is [endorsed](https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin), +This package is [endorsed](https://flutter.dev/to/endorsed-federated-plugin), which means you can simply use `camera` normally. This package will be automatically included in your app when you do, so you do not need to add it to your `pubspec.yaml`. diff --git a/packages/camera/camera_web/example/README.md b/packages/camera/camera_web/example/README.md index 4a01887de7fb..932e9f227cbe 100644 --- a/packages/camera/camera_web/example/README.md +++ b/packages/camera/camera_web/example/README.md @@ -15,5 +15,5 @@ This package uses `package:integration_test` to run its tests in a web browser. See [Plugin Tests > Web Tests](https://github.com/flutter/flutter/blob/master/docs/ecosystem/testing/Plugin-Tests.md#web-tests) in the Flutter documentation for instructions to set up and run the tests in this package. -Check [flutter.dev > Integration testing](https://flutter.dev/docs/testing/integration-tests) +Check [flutter.dev > Integration testing](https://docs.flutter.dev/testing/integration-tests) for more info. diff --git a/packages/camera/camera_web/example/integration_test/camera_bitrate_test.dart b/packages/camera/camera_web/example/integration_test/camera_bitrate_test.dart index 3bf946029c27..3e2c9bd40c99 100644 --- a/packages/camera/camera_web/example/integration_test/camera_bitrate_test.dart +++ b/packages/camera/camera_web/example/integration_test/camera_bitrate_test.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. -import 'dart:html'; +import 'dart:js_interop'; import 'dart:math'; import 'dart:ui'; @@ -13,6 +13,7 @@ import 'package:camera_web/src/types/types.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:mocktail/mocktail.dart'; +import 'package:web/web.dart'; import 'helpers/helpers.dart'; @@ -22,7 +23,7 @@ void main() { const Size videoSize = Size(320, 240); /// Draw some seconds of random video frames on canvas in realtime. - Future simulateCamera(CanvasElement canvasElement) async { + Future simulateCamera(HTMLCanvasElement canvasElement) async { const int fps = 15; const int seconds = 3; const int frameDuration = 1000 ~/ fps; @@ -34,8 +35,10 @@ void main() { final int h = videoSize.height ~/ 20; for (int y = 0; y < videoSize.height; y += h) { for (int x = 0; x < videoSize.width; x += w) { - canvasElement.context2D.setFillColorRgb( - random.nextInt(255), random.nextInt(255), random.nextInt(255)); + final int r = random.nextInt(255); + final int g = random.nextInt(255); + final int b = random.nextInt(255); + canvasElement.context2D.fillStyle = 'rgba($r, $g, $b, 1)'.toJS; canvasElement.context2D.fillRect(x, y, w, h); } } @@ -53,19 +56,25 @@ void main() { bool isVideoTypeSupported(String type) => type == supportedVideoType; Future recordVideo(int videoBitrate) async { - final Window window = MockWindow(); - final Navigator navigator = MockNavigator(); - final MediaDevices mediaDevices = MockMediaDevices(); + final MockWindow mockWindow = MockWindow(); + final MockNavigator mockNavigator = MockNavigator(); + final MockMediaDevices mockMediaDevices = MockMediaDevices(); - when(() => window.navigator).thenReturn(navigator); - when(() => navigator.mediaDevices).thenReturn(mediaDevices); + final Window window = createJSInteropWrapper(mockWindow) as Window; + final Navigator navigator = + createJSInteropWrapper(mockNavigator) as Navigator; + final MediaDevices mediaDevices = + createJSInteropWrapper(mockMediaDevices) as MediaDevices; - final CanvasElement canvasElement = CanvasElement( - width: videoSize.width.toInt(), - height: videoSize.height.toInt(), - )..context2D.clearRect(0, 0, videoSize.width, videoSize.height); + mockWindow.navigator = navigator; + mockNavigator.mediaDevices = mediaDevices; - final VideoElement videoElement = VideoElement(); + final HTMLCanvasElement canvasElement = HTMLCanvasElement() + ..width = videoSize.width.toInt() + ..height = videoSize.height.toInt() + ..context2D.clearRect(0, 0, videoSize.width, videoSize.height); + + final HTMLVideoElement videoElement = HTMLVideoElement(); final MockCameraService cameraService = MockCameraService(); diff --git a/packages/camera/camera_web/example/integration_test/camera_error_code_test.dart b/packages/camera/camera_web/example/integration_test/camera_error_code_test.dart index 6bd86b0fe8e5..4adb5cc40468 100644 --- a/packages/camera/camera_web/example/integration_test/camera_error_code_test.dart +++ b/packages/camera/camera_web/example/integration_test/camera_error_code_test.dart @@ -2,12 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:html'; - // ignore: implementation_imports +import 'dart:js_interop'; + import 'package:camera_web/src/types/types.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; +import 'package:web/web.dart'; import 'helpers/helpers.dart'; @@ -132,7 +133,8 @@ void main() { testWidgets('with aborted error code', (WidgetTester tester) async { expect( CameraErrorCode.fromMediaError( - FakeMediaError(MediaError.MEDIA_ERR_ABORTED), + createJSInteropWrapper( + FakeMediaError(MediaError.MEDIA_ERR_ABORTED)) as MediaError, ).toString(), equals('mediaErrorAborted'), ); @@ -141,7 +143,8 @@ void main() { testWidgets('with network error code', (WidgetTester tester) async { expect( CameraErrorCode.fromMediaError( - FakeMediaError(MediaError.MEDIA_ERR_NETWORK), + createJSInteropWrapper( + FakeMediaError(MediaError.MEDIA_ERR_NETWORK)) as MediaError, ).toString(), equals('mediaErrorNetwork'), ); @@ -150,7 +153,8 @@ void main() { testWidgets('with decode error code', (WidgetTester tester) async { expect( CameraErrorCode.fromMediaError( - FakeMediaError(MediaError.MEDIA_ERR_DECODE), + createJSInteropWrapper( + FakeMediaError(MediaError.MEDIA_ERR_DECODE)) as MediaError, ).toString(), equals('mediaErrorDecode'), ); @@ -160,7 +164,9 @@ void main() { (WidgetTester tester) async { expect( CameraErrorCode.fromMediaError( - FakeMediaError(MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED), + createJSInteropWrapper( + FakeMediaError(MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED)) + as MediaError, ).toString(), equals('mediaErrorSourceNotSupported'), ); @@ -169,7 +175,7 @@ void main() { testWidgets('with unknown error code', (WidgetTester tester) async { expect( CameraErrorCode.fromMediaError( - FakeMediaError(5), + createJSInteropWrapper(FakeMediaError(5)) as MediaError, ).toString(), equals('mediaErrorUnknown'), ); diff --git a/packages/camera/camera_web/example/integration_test/camera_options_test.dart b/packages/camera/camera_web/example/integration_test/camera_options_test.dart index 7dd25e375561..66f4a6bd1eb8 100644 --- a/packages/camera/camera_web/example/integration_test/camera_options_test.dart +++ b/packages/camera/camera_web/example/integration_test/camera_options_test.dart @@ -3,6 +3,8 @@ // found in the LICENSE file. // ignore: implementation_imports +import 'dart:js_interop'; + import 'package:camera_web/src/types/types.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; @@ -20,10 +22,10 @@ void main() { ); expect( - cameraOptions.toJson(), + cameraOptions.toMediaStreamConstraints().dartify(), equals({ - 'audio': cameraOptions.audio.toJson(), - 'video': cameraOptions.video.toJson(), + 'audio': cameraOptions.audio.toMediaStreamConstraints().dartify()!, + 'video': cameraOptions.video.toMediaStreamConstraints().dartify()!, }), ); }); @@ -61,8 +63,8 @@ void main() { group('AudioConstraints', () { testWidgets('serializes correctly', (WidgetTester tester) async { expect( - const AudioConstraints(enabled: true).toJson(), - equals(true), + const AudioConstraints(enabled: true).toMediaStreamConstraints(), + true.toJS, ); }); @@ -84,7 +86,7 @@ void main() { ); expect( - videoConstraints.toJson(), + videoConstraints.toMediaStreamConstraints().dartify(), equals({ 'facingMode': videoConstraints.facingMode!.toJson(), 'width': videoConstraints.width!.toJson(), diff --git a/packages/camera/camera_web/example/integration_test/camera_service_test.dart b/packages/camera/camera_web/example/integration_test/camera_service_test.dart index fb2279a09421..2ed0c54e6339 100644 --- a/packages/camera/camera_web/example/integration_test/camera_service_test.dart +++ b/packages/camera/camera_web/example/integration_test/camera_service_test.dart @@ -2,8 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:html'; -import 'dart:js_util' as js_util; +// ignore_for_file: only_throw_errors + +import 'dart:js_interop'; +import 'dart:js_interop_unsafe'; import 'package:camera_platform_interface/camera_platform_interface.dart'; // ignore_for_file: implementation_imports @@ -15,6 +17,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:mocktail/mocktail.dart'; +import 'package:web/web.dart' as web; import 'helpers/helpers.dart'; @@ -24,27 +27,40 @@ void main() { group('CameraService', () { const int cameraId = 1; - late Window window; - late Navigator navigator; - late MediaDevices mediaDevices; - late CameraService cameraService; + late MockWindow mockWindow; + late MockNavigator mockNavigator; + late MockMediaDevices mockMediaDevices; + + late web.Window window; + late web.Navigator navigator; + late web.MediaDevices mediaDevices; + late JsUtil jsUtil; + late CameraService cameraService; + setUp(() async { - window = MockWindow(); - navigator = MockNavigator(); - mediaDevices = MockMediaDevices(); + mockWindow = MockWindow(); + mockNavigator = MockNavigator(); + mockMediaDevices = MockMediaDevices(); + + window = createJSInteropWrapper(mockWindow) as web.Window; + navigator = createJSInteropWrapper(mockNavigator) as web.Navigator; + mediaDevices = + createJSInteropWrapper(mockMediaDevices) as web.MediaDevices; + + mockWindow.navigator = navigator; + mockNavigator.mediaDevices = mediaDevices; + jsUtil = MockJsUtil(); - when(() => window.navigator).thenReturn(navigator); - when(() => navigator.mediaDevices).thenReturn(mediaDevices); + registerFallbackValue(createJSInteropWrapper(MockWindow())); // Mock JsUtil to return the real getProperty from dart:js_util. when(() => jsUtil.getProperty(any(), any())).thenAnswer( - (Invocation invocation) => js_util.getProperty( - invocation.positionalArguments[0] as Object, - invocation.positionalArguments[1] as Object, - ), + (Invocation invocation) => + (invocation.positionalArguments[0] as JSObject) + .getProperty(invocation.positionalArguments[1] as JSAny), ); cameraService = CameraService()..window = window; @@ -54,8 +70,15 @@ void main() { testWidgets( 'calls MediaDevices.getUserMedia ' 'with provided options', (WidgetTester tester) async { - when(() => mediaDevices.getUserMedia(any())) - .thenAnswer((_) async => FakeMediaStream([])); + late final web.MediaStreamConstraints? capturedConstraints; + mockMediaDevices.getUserMedia = + ([web.MediaStreamConstraints? constraints]) { + capturedConstraints = constraints; + final web.MediaStream stream = + createJSInteropWrapper(FakeMediaStream([])) + as web.MediaStream; + return Future.value(stream).toJS; + }.toJS; final CameraOptions options = CameraOptions( video: VideoConstraints( @@ -66,26 +89,13 @@ void main() { await cameraService.getMediaStreamForOptions(options); - verify( - () => mediaDevices.getUserMedia(options.toJson()), - ).called(1); - }); - - testWidgets( - 'throws PlatformException ' - 'with notSupported error ' - 'when there are no media devices', (WidgetTester tester) async { - when(() => navigator.mediaDevices).thenReturn(null); - expect( - () => cameraService.getMediaStreamForOptions(const CameraOptions()), - throwsA( - isA().having( - (PlatformException e) => e.code, - 'code', - CameraErrorCode.notSupported.toString(), - ), - ), + capturedConstraints?.video.dartify(), + equals(options.video.toMediaStreamConstraints().dartify()), + ); + expect( + capturedConstraints?.audio.dartify(), + equals(options.audio.toMediaStreamConstraints().dartify()), ); }); @@ -94,8 +104,11 @@ void main() { 'with notFound error ' 'when MediaDevices.getUserMedia throws DomException ' 'with NotFoundError', (WidgetTester tester) async { - when(() => mediaDevices.getUserMedia(any())) - .thenThrow(FakeDomException('NotFoundError')); + mockMediaDevices.getUserMedia = ([web.MediaStreamConstraints? _]) { + throw web.DOMException('', 'NotFoundError'); + // ignore: dead_code + return Future.value(web.MediaStream()).toJS; + }.toJS; expect( () => cameraService.getMediaStreamForOptions( @@ -116,8 +129,11 @@ void main() { 'with notFound error ' 'when MediaDevices.getUserMedia throws DomException ' 'with DevicesNotFoundError', (WidgetTester tester) async { - when(() => mediaDevices.getUserMedia(any())) - .thenThrow(FakeDomException('DevicesNotFoundError')); + mockMediaDevices.getUserMedia = ([web.MediaStreamConstraints? _]) { + throw web.DOMException('', 'DevicesNotFoundError'); + // ignore: dead_code + return Future.value(web.MediaStream()).toJS; + }.toJS; expect( () => cameraService.getMediaStreamForOptions( @@ -138,9 +154,11 @@ void main() { 'with notReadable error ' 'when MediaDevices.getUserMedia throws DomException ' 'with NotReadableError', (WidgetTester tester) async { - when(() => mediaDevices.getUserMedia(any())) - .thenThrow(FakeDomException('NotReadableError')); - + mockMediaDevices.getUserMedia = ([web.MediaStreamConstraints? _]) { + throw web.DOMException('', 'NotReadableError'); + // ignore: dead_code + return Future.value(web.MediaStream()).toJS; + }.toJS; expect( () => cameraService.getMediaStreamForOptions( const CameraOptions(), @@ -160,8 +178,11 @@ void main() { 'with notReadable error ' 'when MediaDevices.getUserMedia throws DomException ' 'with TrackStartError', (WidgetTester tester) async { - when(() => mediaDevices.getUserMedia(any())) - .thenThrow(FakeDomException('TrackStartError')); + mockMediaDevices.getUserMedia = ([web.MediaStreamConstraints? _]) { + throw web.DOMException('', 'TrackStartError'); + // ignore: dead_code + return Future.value(web.MediaStream()).toJS; + }.toJS; expect( () => cameraService.getMediaStreamForOptions( @@ -182,8 +203,11 @@ void main() { 'with overconstrained error ' 'when MediaDevices.getUserMedia throws DomException ' 'with OverconstrainedError', (WidgetTester tester) async { - when(() => mediaDevices.getUserMedia(any())) - .thenThrow(FakeDomException('OverconstrainedError')); + mockMediaDevices.getUserMedia = ([web.MediaStreamConstraints? _]) { + throw web.DOMException('', 'OverconstrainedError'); + // ignore: dead_code + return Future.value(web.MediaStream()).toJS; + }.toJS; expect( () => cameraService.getMediaStreamForOptions( @@ -204,8 +228,11 @@ void main() { 'with overconstrained error ' 'when MediaDevices.getUserMedia throws DomException ' 'with ConstraintNotSatisfiedError', (WidgetTester tester) async { - when(() => mediaDevices.getUserMedia(any())) - .thenThrow(FakeDomException('ConstraintNotSatisfiedError')); + mockMediaDevices.getUserMedia = ([web.MediaStreamConstraints? _]) { + throw web.DOMException('', 'ConstraintNotSatisfiedError'); + // ignore: dead_code + return Future.value(web.MediaStream()).toJS; + }.toJS; expect( () => cameraService.getMediaStreamForOptions( @@ -226,8 +253,11 @@ void main() { 'with permissionDenied error ' 'when MediaDevices.getUserMedia throws DomException ' 'with NotAllowedError', (WidgetTester tester) async { - when(() => mediaDevices.getUserMedia(any())) - .thenThrow(FakeDomException('NotAllowedError')); + mockMediaDevices.getUserMedia = ([web.MediaStreamConstraints? _]) { + throw web.DOMException('', 'NotAllowedError'); + // ignore: dead_code + return Future.value(web.MediaStream()).toJS; + }.toJS; expect( () => cameraService.getMediaStreamForOptions( @@ -248,8 +278,11 @@ void main() { 'with permissionDenied error ' 'when MediaDevices.getUserMedia throws DomException ' 'with PermissionDeniedError', (WidgetTester tester) async { - when(() => mediaDevices.getUserMedia(any())) - .thenThrow(FakeDomException('PermissionDeniedError')); + mockMediaDevices.getUserMedia = ([web.MediaStreamConstraints? _]) { + throw web.DOMException('', 'PermissionDeniedError'); + // ignore: dead_code + return Future.value(web.MediaStream()).toJS; + }.toJS; expect( () => cameraService.getMediaStreamForOptions( @@ -270,8 +303,11 @@ void main() { 'with type error ' 'when MediaDevices.getUserMedia throws DomException ' 'with TypeError', (WidgetTester tester) async { - when(() => mediaDevices.getUserMedia(any())) - .thenThrow(FakeDomException('TypeError')); + mockMediaDevices.getUserMedia = ([web.MediaStreamConstraints? _]) { + throw web.DOMException('', 'TypeError'); + // ignore: dead_code + return Future.value(web.MediaStream()).toJS; + }.toJS; expect( () => cameraService.getMediaStreamForOptions( @@ -292,8 +328,11 @@ void main() { 'with abort error ' 'when MediaDevices.getUserMedia throws DomException ' 'with AbortError', (WidgetTester tester) async { - when(() => mediaDevices.getUserMedia(any())) - .thenThrow(FakeDomException('AbortError')); + mockMediaDevices.getUserMedia = ([web.MediaStreamConstraints? _]) { + throw web.DOMException('', 'AbortError'); + // ignore: dead_code + return Future.value(web.MediaStream()).toJS; + }.toJS; expect( () => cameraService.getMediaStreamForOptions( @@ -314,8 +353,11 @@ void main() { 'with security error ' 'when MediaDevices.getUserMedia throws DomException ' 'with SecurityError', (WidgetTester tester) async { - when(() => mediaDevices.getUserMedia(any())) - .thenThrow(FakeDomException('SecurityError')); + mockMediaDevices.getUserMedia = ([web.MediaStreamConstraints? _]) { + throw web.DOMException('', 'SecurityError'); + // ignore: dead_code + return Future.value(web.MediaStream()).toJS; + }.toJS; expect( () => cameraService.getMediaStreamForOptions( @@ -336,8 +378,11 @@ void main() { 'with unknown error ' 'when MediaDevices.getUserMedia throws DomException ' 'with an unknown error', (WidgetTester tester) async { - when(() => mediaDevices.getUserMedia(any())) - .thenThrow(FakeDomException('Unknown')); + mockMediaDevices.getUserMedia = ([web.MediaStreamConstraints? _]) { + throw web.DOMException('', 'Unknown'); + // ignore: dead_code + return Future.value(web.MediaStream()).toJS; + }.toJS; expect( () => cameraService.getMediaStreamForOptions( @@ -358,7 +403,11 @@ void main() { 'with unknown error ' 'when MediaDevices.getUserMedia throws an unknown exception', (WidgetTester tester) async { - when(() => mediaDevices.getUserMedia(any())).thenThrow(Exception()); + mockMediaDevices.getUserMedia = ([web.MediaStreamConstraints? _]) { + throw Exception(); + // ignore: dead_code + return Future.value(web.MediaStream()).toJS; + }.toJS; expect( () => cameraService.getMediaStreamForOptions( @@ -379,17 +428,23 @@ void main() { group('getZoomLevelCapabilityForCamera', () { late Camera camera; - late List videoTracks; + late MockMediaStreamTrack mockVideoTrack; + late List videoTracks; setUp(() { camera = MockCamera(); - videoTracks = [ - MockMediaStreamTrack(), - MockMediaStreamTrack() + mockVideoTrack = MockMediaStreamTrack(); + videoTracks = [ + createJSInteropWrapper(mockVideoTrack) as web.MediaStreamTrack, + createJSInteropWrapper(MockMediaStreamTrack()) + as web.MediaStreamTrack, ]; when(() => camera.textureId).thenReturn(0); - when(() => camera.stream).thenReturn(FakeMediaStream(videoTracks)); + when(() => camera.stream).thenReturn( + createJSInteropWrapper(FakeMediaStream(videoTracks)) + as web.MediaStream, + ); cameraService.jsUtil = jsUtil; }); @@ -397,18 +452,15 @@ void main() { testWidgets( 'returns the zoom level capability ' 'based on the first video track', (WidgetTester tester) async { - when(mediaDevices.getSupportedConstraints) - .thenReturn({ - 'zoom': true, - }); + mockMediaDevices.getSupportedConstraints = () { + return web.MediaTrackSupportedConstraints(zoom: true); + }.toJS; - when(videoTracks.first.getCapabilities).thenReturn({ - 'zoom': js_util.jsify({ - 'min': 100, - 'max': 400, - 'step': 2, - }), - }); + mockVideoTrack.getCapabilities = () { + return web.MediaTrackCapabilities( + zoom: web.MediaSettingsRange(min: 100, max: 400, step: 2), + ); + }.toJS; final ZoomLevelCapability zoomLevelCapability = cameraService.getZoomLevelCapabilityForCamera(camera); @@ -419,75 +471,19 @@ void main() { }); group('throws CameraWebException', () { - testWidgets( - 'with zoomLevelNotSupported error ' - 'when there are no media devices', (WidgetTester tester) async { - when(() => navigator.mediaDevices).thenReturn(null); - - expect( - () => cameraService.getZoomLevelCapabilityForCamera(camera), - throwsA( - isA() - .having( - (CameraWebException e) => e.cameraId, - 'cameraId', - camera.textureId, - ) - .having( - (CameraWebException e) => e.code, - 'code', - CameraErrorCode.zoomLevelNotSupported, - ), - ), - ); - }); - testWidgets( 'with zoomLevelNotSupported error ' 'when the zoom level is not supported ' 'in the browser', (WidgetTester tester) async { - when(mediaDevices.getSupportedConstraints) - .thenReturn({ - 'zoom': false, - }); - - when(videoTracks.first.getCapabilities).thenReturn({ - 'zoom': { - 'min': 100, - 'max': 400, - 'step': 2, - }, - }); - - expect( - () => cameraService.getZoomLevelCapabilityForCamera(camera), - throwsA( - isA() - .having( - (CameraWebException e) => e.cameraId, - 'cameraId', - camera.textureId, - ) - .having( - (CameraWebException e) => e.code, - 'code', - CameraErrorCode.zoomLevelNotSupported, - ), - ), - ); - }); - - testWidgets( - 'with zoomLevelNotSupported error ' - 'when the zoom level is not supported ' - 'by the camera', (WidgetTester tester) async { - when(mediaDevices.getSupportedConstraints) - .thenReturn({ - 'zoom': true, - }); + mockMediaDevices.getSupportedConstraints = () { + return web.MediaTrackSupportedConstraints(zoom: false); + }.toJS; - when(videoTracks.first.getCapabilities) - .thenReturn({}); + mockVideoTrack.getCapabilities = () { + return web.MediaTrackCapabilities( + zoom: web.MediaSettingsRange(min: 100, max: 400, step: 2), + ); + }.toJS; expect( () => cameraService.getZoomLevelCapabilityForCamera(camera), @@ -511,14 +507,15 @@ void main() { 'with notStarted error ' 'when the camera stream has not been initialized', (WidgetTester tester) async { - when(mediaDevices.getSupportedConstraints) - .thenReturn({ - 'zoom': true, - }); + mockMediaDevices.getSupportedConstraints = () { + return web.MediaTrackSupportedConstraints(zoom: true); + }.toJS; // Create a camera stream with no video tracks. - when(() => camera.stream) - .thenReturn(FakeMediaStream([])); + when(() => camera.stream).thenReturn( + createJSInteropWrapper(FakeMediaStream([])) + as web.MediaStream, + ); expect( () => cameraService.getZoomLevelCapabilityForCamera(camera), @@ -545,59 +542,44 @@ void main() { cameraService.jsUtil = jsUtil; }); - testWidgets( - 'throws PlatformException ' - 'with notSupported error ' - 'when there are no media devices', (WidgetTester tester) async { - when(() => navigator.mediaDevices).thenReturn(null); - - expect( - () => - cameraService.getFacingModeForVideoTrack(MockMediaStreamTrack()), - throwsA( - isA().having( - (PlatformException e) => e.code, - 'code', - CameraErrorCode.notSupported.toString(), - ), - ), - ); - }); - testWidgets( 'returns null ' 'when the facing mode is not supported', (WidgetTester tester) async { - when(mediaDevices.getSupportedConstraints) - .thenReturn({ - 'facingMode': false, - }); + mockMediaDevices.getSupportedConstraints = () { + return web.MediaTrackSupportedConstraints(facingMode: false); + }.toJS; - final String? facingMode = - cameraService.getFacingModeForVideoTrack(MockMediaStreamTrack()); + final String? facingMode = cameraService.getFacingModeForVideoTrack( + createJSInteropWrapper(MockMediaStreamTrack()) + as web.MediaStreamTrack, + ); expect(facingMode, isNull); }); group('when the facing mode is supported', () { - late MediaStreamTrack videoTrack; + late MockMediaStreamTrack mockVideoTrack; + late web.MediaStreamTrack videoTrack; setUp(() { - videoTrack = MockMediaStreamTrack(); + mockVideoTrack = MockMediaStreamTrack(); + videoTrack = + createJSInteropWrapper(mockVideoTrack) as web.MediaStreamTrack; - when(() => jsUtil.hasProperty(videoTrack, 'getCapabilities')) + when(() => jsUtil.hasProperty(videoTrack, 'getCapabilities'.toJS)) .thenReturn(true); - when(mediaDevices.getSupportedConstraints) - .thenReturn({ - 'facingMode': true, - }); + mockMediaDevices.getSupportedConstraints = () { + return web.MediaTrackSupportedConstraints(facingMode: true); + }.toJS; }); testWidgets( 'returns an appropriate facing mode ' 'based on the video track settings', (WidgetTester tester) async { - when(videoTrack.getSettings) - .thenReturn({'facingMode': 'user'}); + mockVideoTrack.getSettings = () { + return web.MediaTrackSettings(facingMode: 'user'); + }.toJS; final String? facingMode = cameraService.getFacingModeForVideoTrack(videoTrack); @@ -610,12 +592,16 @@ void main() { 'based on the video track capabilities ' 'when the facing mode setting is empty', (WidgetTester tester) async { - when(videoTrack.getSettings).thenReturn({}); - when(videoTrack.getCapabilities).thenReturn({ - 'facingMode': ['environment', 'left'] - }); - - when(() => jsUtil.hasProperty(videoTrack, 'getCapabilities')) + mockVideoTrack.getSettings = () { + return web.MediaTrackSettings(facingMode: ''); + }.toJS; + mockVideoTrack.getCapabilities = () { + return web.MediaTrackCapabilities( + facingMode: ['environment'.toJS, 'left'.toJS].toJS, + ); + }.toJS; + + when(() => jsUtil.hasProperty(videoTrack, 'getCapabilities'.toJS)) .thenReturn(true); final String? facingMode = @@ -628,9 +614,12 @@ void main() { 'returns null ' 'when the facing mode setting ' 'and capabilities are empty', (WidgetTester tester) async { - when(videoTrack.getSettings).thenReturn({}); - when(videoTrack.getCapabilities) - .thenReturn({'facingMode': []}); + mockVideoTrack.getSettings = () { + return web.MediaTrackSettings(facingMode: ''); + }.toJS; + mockVideoTrack.getCapabilities = () { + return web.MediaTrackCapabilities(facingMode: [].toJS); + }.toJS; final String? facingMode = cameraService.getFacingModeForVideoTrack(videoTrack); @@ -643,9 +632,11 @@ void main() { 'when the facing mode setting is empty and ' 'the video track capabilities are not supported', (WidgetTester tester) async { - when(videoTrack.getSettings).thenReturn({}); + mockVideoTrack.getSettings = () { + return web.MediaTrackSettings(facingMode: ''); + }.toJS; - when(() => jsUtil.hasProperty(videoTrack, 'getCapabilities')) + when(() => jsUtil.hasProperty(videoTrack, 'getCapabilities'.toJS)) .thenReturn(false); final String? facingMode = diff --git a/packages/camera/camera_web/example/integration_test/camera_test.dart b/packages/camera/camera_web/example/integration_test/camera_test.dart index 412ce7148bcf..e953a06b0e8a 100644 --- a/packages/camera/camera_web/example/integration_test/camera_test.dart +++ b/packages/camera/camera_web/example/integration_test/camera_test.dart @@ -3,7 +3,8 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:html'; +import 'dart:js_interop'; +import 'dart:js_interop_unsafe'; import 'dart:ui'; import 'package:async/async.dart'; @@ -15,6 +16,7 @@ import 'package:camera_web/src/types/types.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:mocktail/mocktail.dart'; +import 'package:web/web.dart'; import 'helpers/helpers.dart'; @@ -24,6 +26,10 @@ void main() { group('Camera', () { const int textureId = 1; + late MockWindow mockWindow; + late MockNavigator mockNavigator; + late MockMediaDevices mockMediaDevices; + late Window window; late Navigator navigator; late MediaDevices mediaDevices; @@ -32,16 +38,20 @@ void main() { late CameraService cameraService; setUp(() { - window = MockWindow(); - navigator = MockNavigator(); - mediaDevices = MockMediaDevices(); + mockWindow = MockWindow(); + mockNavigator = MockNavigator(); + mockMediaDevices = MockMediaDevices(); + + window = createJSInteropWrapper(mockWindow) as Window; + navigator = createJSInteropWrapper(mockNavigator) as Navigator; + mediaDevices = createJSInteropWrapper(mockMediaDevices) as MediaDevices; - when(() => window.navigator).thenReturn(navigator); - when(() => navigator.mediaDevices).thenReturn(mediaDevices); + mockWindow.navigator = navigator; + mockNavigator.mediaDevices = mediaDevices; cameraService = MockCameraService(); - final VideoElement videoElement = + final HTMLVideoElement videoElement = getVideoElementWithBlankStream(const Size(10, 10)); mediaStream = videoElement.captureStream(); @@ -110,7 +120,8 @@ void main() { expect(camera.videoElement.autoplay, isFalse); expect(camera.videoElement.muted, isTrue); expect(camera.videoElement.srcObject, mediaStream); - expect(camera.videoElement.attributes.keys, contains('playsinline')); + expect(camera.videoElement.attributes.getNamedItem('playsinline'), + isNotNull); expect( camera.videoElement.style.transformOrigin, equals('center center')); @@ -154,7 +165,10 @@ void main() { expect(camera.divElement, isNotNull); expect(camera.divElement.style.objectFit, equals('cover')); - expect(camera.divElement.children, contains(camera.videoElement)); + final JSArray? array = (globalContext['Array']! as JSObject) + .callMethod('from'.toJS, camera.divElement.children) + as JSArray?; + expect(array?.toDart, contains(camera.videoElement)); }); testWidgets('initializes the camera stream', (WidgetTester tester) async { @@ -303,26 +317,26 @@ void main() { group( 'enables the torch mode ' 'when taking a picture', () { + late MockMediaStreamTrack mockVideoTrack; late List videoTracks; late MediaStream videoStream; - late VideoElement videoElement; + late HTMLVideoElement videoElement; setUp(() { + mockVideoTrack = MockMediaStreamTrack(); videoTracks = [ - MockMediaStreamTrack(), - MockMediaStreamTrack() + createJSInteropWrapper(mockVideoTrack) as MediaStreamTrack, + createJSInteropWrapper(MockMediaStreamTrack()) as MediaStreamTrack, ]; - videoStream = FakeMediaStream(videoTracks); + videoStream = createJSInteropWrapper(FakeMediaStream(videoTracks)) + as MediaStream; videoElement = getVideoElementWithBlankStream(const Size(100, 100)) ..muted = true; - when(() => videoTracks.first.applyConstraints(any())) - .thenAnswer((_) async => {}); - - when(videoTracks.first.getCapabilities).thenReturn({ - 'torch': true, - }); + mockVideoTrack.getCapabilities = () { + return MediaTrackCapabilities(torch: [true.toJS].toJS); + }.toJS; }); testWidgets('if the flash mode is auto', (WidgetTester tester) async { @@ -337,27 +351,22 @@ void main() { await camera.play(); + final List capturedConstraints = + []; + mockVideoTrack.applyConstraints = ([ + MediaTrackConstraints? constraints, + ]) { + if (constraints != null) { + capturedConstraints.add(constraints); + } + return Future.value().toJS; + }.toJS; + final XFile _ = await camera.takePicture(); - verify( - () => videoTracks.first.applyConstraints({ - 'advanced': [ - { - 'torch': true, - } - ] - }), - ).called(1); - - verify( - () => videoTracks.first.applyConstraints({ - 'advanced': [ - { - 'torch': false, - } - ] - }), - ).called(1); + expect(capturedConstraints.length, 2); + expect(capturedConstraints[0].torch.dartify(), true); + expect(capturedConstraints[1].torch.dartify(), false); }); testWidgets('if the flash mode is always', (WidgetTester tester) async { @@ -372,27 +381,22 @@ void main() { await camera.play(); + final List capturedConstraints = + []; + mockVideoTrack.applyConstraints = ([ + MediaTrackConstraints? constraints, + ]) { + if (constraints != null) { + capturedConstraints.add(constraints); + } + return Future.value().toJS; + }.toJS; + final XFile _ = await camera.takePicture(); - verify( - () => videoTracks.first.applyConstraints({ - 'advanced': [ - { - 'torch': true, - } - ] - }), - ).called(1); - - verify( - () => videoTracks.first.applyConstraints({ - 'advanced': [ - { - 'torch': false, - } - ] - }), - ).called(1); + expect(capturedConstraints.length, 2); + expect(capturedConstraints[0].torch.dartify(), true); + expect(capturedConstraints[1].torch.dartify(), false); }); }); }); @@ -404,7 +408,7 @@ void main() { (WidgetTester tester) async { const Size videoSize = Size(1280, 720); - final VideoElement videoElement = + final HTMLVideoElement videoElement = getVideoElementWithBlankStream(videoSize); mediaStream = videoElement.captureStream(); @@ -425,7 +429,7 @@ void main() { 'returns Size.zero ' 'if the camera is missing video tracks', (WidgetTester tester) async { // Create a video stream with no video tracks. - final VideoElement videoElement = VideoElement(); + final HTMLVideoElement videoElement = HTMLVideoElement(); mediaStream = videoElement.captureStream(); final Camera camera = Camera( @@ -443,32 +447,38 @@ void main() { }); group('setFlashMode', () { + late MockMediaStreamTrack mockVideoTrack; late List videoTracks; late MediaStream videoStream; setUp(() { + mockVideoTrack = MockMediaStreamTrack(); videoTracks = [ - MockMediaStreamTrack(), - MockMediaStreamTrack() + createJSInteropWrapper(mockVideoTrack) as MediaStreamTrack, + createJSInteropWrapper(MockMediaStreamTrack()) as MediaStreamTrack, ]; - videoStream = FakeMediaStream(videoTracks); - - when(() => videoTracks.first.applyConstraints(any())) - .thenAnswer((_) async => {}); - - when(videoTracks.first.getCapabilities) - .thenReturn({}); + videoStream = + createJSInteropWrapper(FakeMediaStream(videoTracks)) as MediaStream; + + mockVideoTrack.applyConstraints = ([ + MediaTrackConstraints? constraints, + ]) { + return Future.value().toJS; + }.toJS; + + mockVideoTrack.getCapabilities = () { + return MediaTrackCapabilities(); + }.toJS; }); testWidgets('sets the camera flash mode', (WidgetTester tester) async { - when(mediaDevices.getSupportedConstraints) - .thenReturn({ - 'torch': true, - }); + mockMediaDevices.getSupportedConstraints = () { + return MediaTrackSupportedConstraints(torch: true); + }.toJS; - when(videoTracks.first.getCapabilities).thenReturn({ - 'torch': true, - }); + mockVideoTrack.getCapabilities = () { + return MediaTrackCapabilities(torch: [true.toJS].toJS); + }.toJS; final Camera camera = Camera( textureId: textureId, @@ -490,14 +500,13 @@ void main() { testWidgets( 'enables the torch mode ' 'if the flash mode is torch', (WidgetTester tester) async { - when(mediaDevices.getSupportedConstraints) - .thenReturn({ - 'torch': true, - }); + mockMediaDevices.getSupportedConstraints = () { + return MediaTrackSupportedConstraints(torch: true); + }.toJS; - when(videoTracks.first.getCapabilities).thenReturn({ - 'torch': true, - }); + mockVideoTrack.getCapabilities = () { + return MediaTrackCapabilities(torch: [true.toJS].toJS); + }.toJS; final Camera camera = Camera( textureId: textureId, @@ -506,30 +515,33 @@ void main() { ..window = window ..stream = videoStream; + final List capturedConstraints = + []; + mockVideoTrack.applyConstraints = ([ + MediaTrackConstraints? constraints, + ]) { + if (constraints != null) { + capturedConstraints.add(constraints); + } + return Future.value().toJS; + }.toJS; + camera.setFlashMode(FlashMode.torch); - verify( - () => videoTracks.first.applyConstraints({ - 'advanced': [ - { - 'torch': true, - } - ] - }), - ).called(1); + expect(capturedConstraints.length, 1); + expect(capturedConstraints[0].torch.dartify(), true); }); testWidgets( 'disables the torch mode ' 'if the flash mode is not torch', (WidgetTester tester) async { - when(mediaDevices.getSupportedConstraints) - .thenReturn({ - 'torch': true, - }); + mockMediaDevices.getSupportedConstraints = () { + return MediaTrackSupportedConstraints(torch: true); + }.toJS; - when(videoTracks.first.getCapabilities).thenReturn({ - 'torch': true, - }); + mockVideoTrack.getCapabilities = () { + return MediaTrackCapabilities(torch: [true.toJS].toJS); + }.toJS; final Camera camera = Camera( textureId: textureId, @@ -538,62 +550,35 @@ void main() { ..window = window ..stream = videoStream; + final List capturedConstraints = + []; + mockVideoTrack.applyConstraints = ([ + MediaTrackConstraints? constraints, + ]) { + if (constraints != null) { + capturedConstraints.add(constraints); + } + return Future.value().toJS; + }.toJS; + camera.setFlashMode(FlashMode.auto); - verify( - () => videoTracks.first.applyConstraints({ - 'advanced': [ - { - 'torch': false, - } - ] - }), - ).called(1); + expect(capturedConstraints.length, 1); + expect(capturedConstraints[0].torch.dartify(), false); }); group('throws a CameraWebException', () { - testWidgets( - 'with torchModeNotSupported error ' - 'when there are no media devices', (WidgetTester tester) async { - when(() => navigator.mediaDevices).thenReturn(null); - - final Camera camera = Camera( - textureId: textureId, - cameraService: cameraService, - ) - ..window = window - ..stream = videoStream; - - expect( - () => camera.setFlashMode(FlashMode.always), - throwsA( - isA() - .having( - (CameraWebException e) => e.cameraId, - 'cameraId', - textureId, - ) - .having( - (CameraWebException e) => e.code, - 'code', - CameraErrorCode.torchModeNotSupported, - ), - ), - ); - }); - testWidgets( 'with torchModeNotSupported error ' 'when the torch mode is not supported ' 'in the browser', (WidgetTester tester) async { - when(mediaDevices.getSupportedConstraints) - .thenReturn({ - 'torch': false, - }); + mockMediaDevices.getSupportedConstraints = () { + return MediaTrackSupportedConstraints(torch: false); + }.toJS; - when(videoTracks.first.getCapabilities).thenReturn({ - 'torch': true, - }); + mockVideoTrack.getCapabilities = () { + return MediaTrackCapabilities(torch: [true.toJS].toJS); + }.toJS; final Camera camera = Camera( textureId: textureId, @@ -624,14 +609,13 @@ void main() { 'with torchModeNotSupported error ' 'when the torch mode is not supported ' 'by the camera', (WidgetTester tester) async { - when(mediaDevices.getSupportedConstraints) - .thenReturn({ - 'torch': true, - }); + mockMediaDevices.getSupportedConstraints = () { + return MediaTrackSupportedConstraints(torch: true); + }.toJS; - when(videoTracks.first.getCapabilities).thenReturn({ - 'torch': false, - }); + mockVideoTrack.getCapabilities = () { + return MediaTrackCapabilities(torch: [false.toJS].toJS); + }.toJS; final Camera camera = Camera( textureId: textureId, @@ -662,14 +646,13 @@ void main() { 'with notStarted error ' 'when the camera stream has not been initialized', (WidgetTester tester) async { - when(mediaDevices.getSupportedConstraints) - .thenReturn({ - 'torch': true, - }); + mockMediaDevices.getSupportedConstraints = () { + return MediaTrackSupportedConstraints(torch: true); + }.toJS; - when(videoTracks.first.getCapabilities).thenReturn({ - 'torch': true, - }); + mockVideoTrack.getCapabilities = () { + return MediaTrackCapabilities(torch: [true.toJS].toJS); + }.toJS; final Camera camera = Camera( textureId: textureId, @@ -710,7 +693,8 @@ void main() { final ZoomLevelCapability zoomLevelCapability = ZoomLevelCapability( minimum: 50.0, maximum: 100.0, - videoTrack: MockMediaStreamTrack(), + videoTrack: createJSInteropWrapper(MockMediaStreamTrack()) + as MediaStreamTrack, ); when(() => cameraService.getZoomLevelCapabilityForCamera(camera)) @@ -741,7 +725,8 @@ void main() { final ZoomLevelCapability zoomLevelCapability = ZoomLevelCapability( minimum: 50.0, maximum: 100.0, - videoTrack: MockMediaStreamTrack(), + videoTrack: createJSInteropWrapper(MockMediaStreamTrack()) + as MediaStreamTrack, ); when(() => cameraService.getZoomLevelCapabilityForCamera(camera)) @@ -769,7 +754,9 @@ void main() { cameraService: cameraService, ); - final MockMediaStreamTrack videoTrack = MockMediaStreamTrack(); + final MockMediaStreamTrack mockVideoTrack = MockMediaStreamTrack(); + final MediaStreamTrack videoTrack = + createJSInteropWrapper(mockVideoTrack) as MediaStreamTrack; final ZoomLevelCapability zoomLevelCapability = ZoomLevelCapability( minimum: 50.0, @@ -777,8 +764,16 @@ void main() { videoTrack: videoTrack, ); - when(() => videoTrack.applyConstraints(any())) - .thenAnswer((_) async {}); + final List capturedConstraints = + []; + mockVideoTrack.applyConstraints = ([ + MediaTrackConstraints? constraints, + ]) { + if (constraints != null) { + capturedConstraints.add(constraints); + } + return Future.value().toJS; + }.toJS; when(() => cameraService.getZoomLevelCapabilityForCamera(camera)) .thenReturn(zoomLevelCapability); @@ -787,15 +782,8 @@ void main() { camera.setZoomLevel(zoom); - verify( - () => videoTrack.applyConstraints({ - 'advanced': [ - { - ZoomLevelCapability.constraintName: zoom, - } - ] - }), - ).called(1); + expect(capturedConstraints.length, 1); + expect(capturedConstraints[0].zoom.dartify(), zoom); }); group('throws a CameraWebException', () { @@ -811,7 +799,8 @@ void main() { final ZoomLevelCapability zoomLevelCapability = ZoomLevelCapability( minimum: 50.0, maximum: 100.0, - videoTrack: MockMediaStreamTrack(), + videoTrack: createJSInteropWrapper(MockMediaStreamTrack()) + as MediaStreamTrack, ); when(() => cameraService.getZoomLevelCapabilityForCamera(camera)) @@ -846,7 +835,8 @@ void main() { final ZoomLevelCapability zoomLevelCapability = ZoomLevelCapability( minimum: 50.0, maximum: 100.0, - videoTrack: MockMediaStreamTrack(), + videoTrack: createJSInteropWrapper(MockMediaStreamTrack()) + as MediaStreamTrack, ); when(() => cameraService.getZoomLevelCapabilityForCamera(camera)) @@ -878,7 +868,9 @@ void main() { 'returns a lens direction ' 'based on the first video track settings', (WidgetTester tester) async { - final MockVideoElement videoElement = MockVideoElement(); + final MockVideoElement mockVideoElement = MockVideoElement(); + final HTMLVideoElement videoElement = + createJSInteropWrapper(mockVideoElement) as HTMLVideoElement; final Camera camera = Camera( textureId: textureId, @@ -887,15 +879,19 @@ void main() { final MockMediaStreamTrack firstVideoTrack = MockMediaStreamTrack(); - when(() => videoElement.srcObject).thenReturn( - FakeMediaStream([ - firstVideoTrack, - MockMediaStreamTrack(), - ]), - ); + mockVideoElement.srcObject = createJSInteropWrapper( + FakeMediaStream( + [ + createJSInteropWrapper(firstVideoTrack) as MediaStreamTrack, + createJSInteropWrapper(MockMediaStreamTrack()) + as MediaStreamTrack, + ], + ), + ) as MediaStream; - when(firstVideoTrack.getSettings) - .thenReturn({'facingMode': 'environment'}); + firstVideoTrack.getSettings = () { + return MediaTrackSettings(facingMode: 'environment'); + }.toJS; when(() => cameraService.mapFacingModeToLensDirection('environment')) .thenReturn(CameraLensDirection.external); @@ -910,7 +906,9 @@ void main() { 'returns null ' 'if the first video track is missing the facing mode', (WidgetTester tester) async { - final MockVideoElement videoElement = MockVideoElement(); + final MockVideoElement mockVideoElement = MockVideoElement(); + final HTMLVideoElement videoElement = + createJSInteropWrapper(mockVideoElement) as HTMLVideoElement; final Camera camera = Camera( textureId: textureId, @@ -919,14 +917,19 @@ void main() { final MockMediaStreamTrack firstVideoTrack = MockMediaStreamTrack(); - when(() => videoElement.srcObject).thenReturn( - FakeMediaStream([ - firstVideoTrack, - MockMediaStreamTrack(), - ]), - ); + videoElement.srcObject = createJSInteropWrapper( + FakeMediaStream( + [ + createJSInteropWrapper(firstVideoTrack) as MediaStreamTrack, + createJSInteropWrapper(MockMediaStreamTrack()) + as MediaStreamTrack, + ], + ), + ) as MediaStream; - when(firstVideoTrack.getSettings).thenReturn({}); + firstVideoTrack.getSettings = () { + return MediaTrackSettings(); + }.toJS; expect( camera.getLensDirection(), @@ -938,7 +941,7 @@ void main() { 'returns null ' 'if the camera is missing video tracks', (WidgetTester tester) async { // Create a video stream with no video tracks. - final VideoElement videoElement = VideoElement(); + final HTMLVideoElement videoElement = HTMLVideoElement(); mediaStream = videoElement.captureStream(); final Camera camera = Camera( @@ -974,15 +977,15 @@ void main() { group('video recording', () { const String supportedVideoType = 'video/webm'; + late MockMediaRecorder mockMediaRecorder; late MediaRecorder mediaRecorder; bool isVideoTypeSupported(String type) => type == supportedVideoType; setUp(() { - mediaRecorder = MockMediaRecorder(); - - when(() => mediaRecorder.onError) - .thenAnswer((_) => const Stream.empty()); + mockMediaRecorder = MockMediaRecorder(); + mediaRecorder = + createJSInteropWrapper(mockMediaRecorder) as MediaRecorder; }); group('startVideoRecording', () { @@ -1027,11 +1030,21 @@ void main() { await camera.initialize(); await camera.play(); + final List capturedEvents = []; + mockMediaRecorder.addEventListener = ( + String type, + EventListener? callback, [ + JSAny? options, + ]) { + capturedEvents.add(type); + }.toJS; + await camera.startVideoRecording(); - verify( - () => mediaRecorder.addEventListener('dataavailable', any()), - ).called(1); + expect( + capturedEvents.where((String e) => e == 'dataavailable').length, + 1, + ); }); testWidgets('listens to the media recorder stop events', @@ -1046,11 +1059,21 @@ void main() { await camera.initialize(); await camera.play(); + final List capturedEvents = []; + mockMediaRecorder.addEventListener = ( + String type, + EventListener? callback, [ + JSAny? options, + ]) { + capturedEvents.add(type); + }.toJS; + await camera.startVideoRecording(); - verify( - () => mediaRecorder.addEventListener('stop', any()), - ).called(1); + expect( + capturedEvents.where((String e) => e == 'stop').length, + 1, + ); }); testWidgets('starts a video recording', (WidgetTester tester) async { @@ -1064,65 +1087,17 @@ void main() { await camera.initialize(); await camera.play(); - await camera.startVideoRecording(); - - verify(mediaRecorder.start).called(1); - }); - - testWidgets( - 'starts a video recording ' - 'with maxVideoDuration', (WidgetTester tester) async { - const Duration maxVideoDuration = Duration(hours: 1); - - final Camera camera = Camera( - textureId: 1, - cameraService: cameraService, - ) - ..mediaRecorder = mediaRecorder - ..isVideoTypeSupported = isVideoTypeSupported; - - await camera.initialize(); - await camera.play(); + final List capturedStarts = []; + mockMediaRecorder.start = ([int? timeslice]) { + capturedStarts.add(timeslice); + }.toJS; - await camera.startVideoRecording(maxVideoDuration: maxVideoDuration); + await camera.startVideoRecording(); - verify(() => mediaRecorder.start(maxVideoDuration.inMilliseconds)) - .called(1); + expect(capturedStarts.length, 1); }); group('throws a CameraWebException', () { - testWidgets( - 'with notSupported error ' - 'when maxVideoDuration is 0 milliseconds or less', - (WidgetTester tester) async { - final Camera camera = Camera( - textureId: 1, - cameraService: cameraService, - ) - ..mediaRecorder = mediaRecorder - ..isVideoTypeSupported = isVideoTypeSupported; - - await camera.initialize(); - await camera.play(); - - expect( - () => camera.startVideoRecording(maxVideoDuration: Duration.zero), - throwsA( - isA() - .having( - (CameraWebException e) => e.cameraId, - 'cameraId', - textureId, - ) - .having( - (CameraWebException e) => e.code, - 'code', - CameraErrorCode.notSupported, - ), - ), - ); - }); - testWidgets( 'with notSupported error ' 'when no video types are supported', (WidgetTester tester) async { @@ -1161,9 +1136,14 @@ void main() { cameraService: cameraService, )..mediaRecorder = mediaRecorder; + int pauses = 0; + mockMediaRecorder.pause = () { + pauses++; + }.toJS; + await camera.pauseVideoRecording(); - verify(mediaRecorder.pause).called(1); + expect(pauses, 1); }); testWidgets( @@ -1202,9 +1182,14 @@ void main() { cameraService: cameraService, )..mediaRecorder = mediaRecorder; + int resumes = 0; + mockMediaRecorder.resume = () { + resumes++; + }.toJS; + await camera.resumeVideoRecording(); - verify(mediaRecorder.resume).called(1); + expect(resumes, 1); }); testWidgets( @@ -1251,50 +1236,62 @@ void main() { await camera.initialize(); await camera.play(); - late void Function(Event) videoDataAvailableListener; - late void Function(Event) videoRecordingStoppedListener; - - when( - () => mediaRecorder.addEventListener('dataavailable', any()), - ).thenAnswer((Invocation invocation) { - videoDataAvailableListener = - invocation.positionalArguments[1] as void Function(Event); - }); - - when( - () => mediaRecorder.addEventListener('stop', any()), - ).thenAnswer((Invocation invocation) { - videoRecordingStoppedListener = - invocation.positionalArguments[1] as void Function(Event); - }); + late EventListener videoDataAvailableListener; + late EventListener videoRecordingStoppedListener; + + mockMediaRecorder.addEventListener = ( + String type, + EventListener? callback, [ + JSAny? options, + ]) { + if (type == 'dataavailable') { + videoDataAvailableListener = callback!; + } else if (type == 'stop') { + videoRecordingStoppedListener = callback!; + } + }.toJS; Blob? finalVideo; List? videoParts; camera.blobBuilder = (List blobs, String videoType) { videoParts = [...blobs]; - finalVideo = Blob(blobs, videoType); + finalVideo = Blob(blobs.toJS, BlobPropertyBag(type: videoType)); return finalVideo!; }; await camera.startVideoRecording(); + + int stops = 0; + mockMediaRecorder.stop = () { + stops++; + }.toJS; + final Future videoFileFuture = camera.stopVideoRecording(); - final Blob capturedVideoPartOne = Blob([]); - final Blob capturedVideoPartTwo = Blob([]); + final Blob capturedVideoPartOne = Blob([].toJS); + final Blob capturedVideoPartTwo = Blob([].toJS); final List capturedVideoParts = [ capturedVideoPartOne, capturedVideoPartTwo, ]; - videoDataAvailableListener(FakeBlobEvent(capturedVideoPartOne)); - videoDataAvailableListener(FakeBlobEvent(capturedVideoPartTwo)); + videoDataAvailableListener.callAsFunction( + null, + createJSInteropWrapper(FakeBlobEvent(capturedVideoPartOne)) + as BlobEvent, + ); + videoDataAvailableListener.callAsFunction( + null, + createJSInteropWrapper(FakeBlobEvent(capturedVideoPartTwo)) + as BlobEvent, + ); - videoRecordingStoppedListener(Event('stop')); + videoRecordingStoppedListener.callAsFunction(null, Event('stop')); final XFile videoFile = await videoFileFuture; - verify(mediaRecorder.stop).called(1); + expect(stops, 1); expect( videoFile, @@ -1346,56 +1343,19 @@ void main() { }); }); - group('on video data available', () { - late void Function(Event) videoDataAvailableListener; - - setUp(() { - when( - () => mediaRecorder.addEventListener('dataavailable', any()), - ).thenAnswer((Invocation invocation) { - videoDataAvailableListener = - invocation.positionalArguments[1] as void Function(Event); - }); - }); - - testWidgets( - 'stops a video recording ' - 'if maxVideoDuration is given and ' - 'the recording was not stopped manually', - (WidgetTester tester) async { - const Duration maxVideoDuration = Duration(hours: 1); - - final Camera camera = Camera( - textureId: 1, - cameraService: cameraService, - ) - ..mediaRecorder = mediaRecorder - ..isVideoTypeSupported = isVideoTypeSupported; - - await camera.initialize(); - await camera.play(); - await camera.startVideoRecording(maxVideoDuration: maxVideoDuration); - - when(() => mediaRecorder.state).thenReturn('recording'); - - videoDataAvailableListener(FakeBlobEvent(Blob([]))); - - await Future.microtask(() {}); - - verify(mediaRecorder.stop).called(1); - }); - }); - group('on video recording stopped', () { - late void Function(Event) videoRecordingStoppedListener; + late EventListener videoRecordingStoppedListener; setUp(() { - when( - () => mediaRecorder.addEventListener('stop', any()), - ).thenAnswer((Invocation invocation) { - videoRecordingStoppedListener = - invocation.positionalArguments[1] as void Function(Event); - }); + mockMediaRecorder.addEventListener = ( + String type, + EventListener? callback, [ + JSAny? options, + ]) { + if (type == 'stop') { + videoRecordingStoppedListener = callback!; + } + }.toJS; }); testWidgets('stops listening to the media recorder data events', @@ -1412,13 +1372,23 @@ void main() { await camera.startVideoRecording(); - videoRecordingStoppedListener(Event('stop')); + final List capturedEvents = []; + mockMediaRecorder.removeEventListener = ( + String type, + EventListener? callback, [ + JSAny? options, + ]) { + capturedEvents.add(type); + }.toJS; + + videoRecordingStoppedListener.callAsFunction(null, Event('stop')); await Future.microtask(() {}); - verify( - () => mediaRecorder.removeEventListener('dataavailable', any()), - ).called(1); + expect( + capturedEvents.where((String e) => e == 'dataavailable').length, + 1, + ); }); testWidgets('stops listening to the media recorder stop events', @@ -1435,28 +1405,41 @@ void main() { await camera.startVideoRecording(); - videoRecordingStoppedListener(Event('stop')); + final List capturedEvents = []; + mockMediaRecorder.removeEventListener = ( + String type, + EventListener? callback, [ + JSAny? options, + ]) { + capturedEvents.add(type); + }.toJS; + + videoRecordingStoppedListener.callAsFunction(null, Event('stop')); await Future.microtask(() {}); - verify( - () => mediaRecorder.removeEventListener('stop', any()), - ).called(1); + expect( + capturedEvents.where((String e) => e == 'stop').length, + 1, + ); }); testWidgets('stops listening to the media recorder errors', (WidgetTester tester) async { final StreamController onErrorStreamController = StreamController(); + final MockEventStreamProvider provider = + MockEventStreamProvider(); final Camera camera = Camera( textureId: 1, cameraService: cameraService, ) ..mediaRecorder = mediaRecorder - ..isVideoTypeSupported = isVideoTypeSupported; + ..isVideoTypeSupported = isVideoTypeSupported + ..mediaRecorderOnErrorProvider = provider; - when(() => mediaRecorder.onError) + when(() => provider.forTarget(mediaRecorder)) .thenAnswer((_) => onErrorStreamController.stream); await camera.initialize(); @@ -1464,7 +1447,7 @@ void main() { await camera.startVideoRecording(); - videoRecordingStoppedListener(Event('stop')); + videoRecordingStoppedListener.callAsFunction(null, Event('stop')); await Future.microtask(() {}); @@ -1543,12 +1526,11 @@ void main() { testWidgets( 'emits a VideoRecordedEvent ' 'when a video recording is created', (WidgetTester tester) async { - const Duration maxVideoDuration = Duration(hours: 1); const String supportedVideoType = 'video/webm'; - final MockMediaRecorder mediaRecorder = MockMediaRecorder(); - when(() => mediaRecorder.onError) - .thenAnswer((_) => const Stream.empty()); + final MockMediaRecorder mockMediaRecorder = MockMediaRecorder(); + final MediaRecorder mediaRecorder = + createJSInteropWrapper(mockMediaRecorder) as MediaRecorder; final Camera camera = Camera( textureId: 1, @@ -1560,36 +1542,37 @@ void main() { await camera.initialize(); await camera.play(); - late void Function(Event) videoDataAvailableListener; - late void Function(Event) videoRecordingStoppedListener; - - when( - () => mediaRecorder.addEventListener('dataavailable', any()), - ).thenAnswer((Invocation invocation) { - videoDataAvailableListener = - invocation.positionalArguments[1] as void Function(Event); - }); - - when( - () => mediaRecorder.addEventListener('stop', any()), - ).thenAnswer((Invocation invocation) { - videoRecordingStoppedListener = - invocation.positionalArguments[1] as void Function(Event); - }); + late EventListener videoDataAvailableListener; + late EventListener videoRecordingStoppedListener; + + mockMediaRecorder.addEventListener = ( + String type, + EventListener? callback, [ + JSAny? options, + ]) { + if (type == 'dataavailable') { + videoDataAvailableListener = callback!; + } else if (type == 'stop') { + videoRecordingStoppedListener = callback!; + } + }.toJS; final StreamQueue streamQueue = StreamQueue(camera.onVideoRecordedEvent); - await camera.startVideoRecording(maxVideoDuration: maxVideoDuration); + await camera.startVideoRecording(); Blob? finalVideo; camera.blobBuilder = (List blobs, String videoType) { - finalVideo = Blob(blobs, videoType); + finalVideo = Blob(blobs.toJS, BlobPropertyBag(type: videoType)); return finalVideo!; }; - videoDataAvailableListener(FakeBlobEvent(Blob([]))); - videoRecordingStoppedListener(Event('stop')); + videoDataAvailableListener.callAsFunction( + null, + createJSInteropWrapper(FakeBlobEvent(Blob([].toJS))), + ); + videoRecordingStoppedListener.callAsFunction(null, Event('stop')); expect( await streamQueue.next, @@ -1614,11 +1597,6 @@ void main() { 'name', finalVideo.hashCode.toString(), ), - ) - .having( - (VideoRecordedEvent e) => e.maxVideoDuration, - 'maxVideoDuration', - maxVideoDuration, ), ), ); @@ -1642,7 +1620,7 @@ void main() { await camera.initialize(); final List videoTracks = - camera.stream!.getVideoTracks(); + camera.stream!.getVideoTracks().toDart; final MediaStreamTrack defaultVideoTrack = videoTracks.first; defaultVideoTrack.dispatchEvent(Event('ended')); @@ -1669,7 +1647,7 @@ void main() { await camera.initialize(); final List videoTracks = - camera.stream!.getVideoTracks(); + camera.stream!.getVideoTracks().toDart; final MediaStreamTrack defaultVideoTrack = videoTracks.first; camera.stop(); @@ -1688,16 +1666,22 @@ void main() { 'emits an ErrorEvent ' 'when the media recorder fails ' 'when recording a video', (WidgetTester tester) async { - final MockMediaRecorder mediaRecorder = MockMediaRecorder(); + final MockMediaRecorder mockMediaRecorder = MockMediaRecorder(); + final MediaRecorder mediaRecorder = + createJSInteropWrapper(mockMediaRecorder) as MediaRecorder; final StreamController errorController = StreamController(); + final MockEventStreamProvider provider = + MockEventStreamProvider(); final Camera camera = Camera( textureId: textureId, cameraService: cameraService, - )..mediaRecorder = mediaRecorder; + ) + ..mediaRecorder = mediaRecorder + ..mediaRecorderOnErrorProvider = provider; - when(() => mediaRecorder.onError) + when(() => provider.forTarget(mediaRecorder)) .thenAnswer((_) => errorController.stream); final StreamQueue streamQueue = diff --git a/packages/camera/camera_web/example/integration_test/camera_web_test.dart b/packages/camera/camera_web/example/integration_test/camera_web_test.dart index cfce6c4f5a9d..ac31979eb176 100644 --- a/packages/camera/camera_web/example/integration_test/camera_web_test.dart +++ b/packages/camera/camera_web/example/integration_test/camera_web_test.dart @@ -2,8 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// ignore_for_file: only_throw_errors + import 'dart:async'; -import 'dart:html'; +import 'dart:js_interop'; +import 'dart:math'; import 'package:async/async.dart'; import 'package:camera_platform_interface/camera_platform_interface.dart'; @@ -17,6 +20,7 @@ import 'package:flutter/widgets.dart' as widgets; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:mocktail/mocktail.dart'; +import 'package:web/web.dart' hide MediaDeviceKind, OrientationType; import 'helpers/helpers.dart'; @@ -26,41 +30,67 @@ void main() { group('CameraPlugin', () { const int cameraId = 1; + late MockWindow mockWindow; + late MockNavigator mockNavigator; + late MockMediaDevices mockMediaDevices; + late Window window; late Navigator navigator; late MediaDevices mediaDevices; - late VideoElement videoElement; + + late HTMLVideoElement videoElement; + + late MockScreen mockScreen; + late MockScreenOrientation mockScreenOrientation; + late Screen screen; late ScreenOrientation screenOrientation; + + late MockDocument mockDocument; + late MockElement mockDocumentElement; + late Document document; late Element documentElement; late CameraService cameraService; setUp(() async { - window = MockWindow(); - navigator = MockNavigator(); - mediaDevices = MockMediaDevices(); + mockWindow = MockWindow(); + mockNavigator = MockNavigator(); + mockMediaDevices = MockMediaDevices(); + + window = createJSInteropWrapper(mockWindow) as Window; + navigator = createJSInteropWrapper(mockNavigator) as Navigator; + mediaDevices = createJSInteropWrapper(mockMediaDevices) as MediaDevices; + + mockWindow.navigator = navigator; + mockNavigator.mediaDevices = mediaDevices; videoElement = getVideoElementWithBlankStream(const Size(10, 10)); - when(() => window.navigator).thenReturn(navigator); - when(() => navigator.mediaDevices).thenReturn(mediaDevices); + mockScreen = MockScreen(); + mockScreenOrientation = MockScreenOrientation(); - screen = MockScreen(); - screenOrientation = MockScreenOrientation(); + screen = createJSInteropWrapper(mockScreen) as Screen; + screenOrientation = + createJSInteropWrapper(mockScreenOrientation) as ScreenOrientation; - when(() => screen.orientation).thenReturn(screenOrientation); - when(() => window.screen).thenReturn(screen); + mockScreen.orientation = screenOrientation; + mockWindow.screen = screen; - document = MockDocument(); - documentElement = MockElement(); + mockDocument = MockDocument(); + mockDocumentElement = MockElement(); - when(() => document.documentElement).thenReturn(documentElement); - when(() => window.document).thenReturn(document); + document = createJSInteropWrapper(mockDocument) as Document; + documentElement = createJSInteropWrapper(mockDocumentElement) as Element; + + mockDocument.documentElement = documentElement; + mockWindow.document = document; cameraService = MockCameraService(); + registerFallbackValue(createJSInteropWrapper(MockWindow())); + when( () => cameraService.getMediaStreamForOptions( any(), @@ -94,9 +124,11 @@ void main() { ), ).thenReturn(null); - when(mediaDevices.enumerateDevices).thenAnswer( - (_) async => [], - ); + mockMediaDevices.enumerateDevices = () { + return Future>.value( + [].toJS, + ).toJS; + }.toJS; }); testWidgets('requests video permissions', (WidgetTester tester) async { @@ -111,18 +143,22 @@ void main() { testWidgets( 'releases the camera stream ' 'used to request video permissions', (WidgetTester tester) async { - final MockMediaStreamTrack videoTrack = MockMediaStreamTrack(); + final MockMediaStreamTrack mockVideoTrack = MockMediaStreamTrack(); + final MediaStreamTrack videoTrack = + createJSInteropWrapper(mockVideoTrack) as MediaStreamTrack; bool videoTrackStopped = false; - when(videoTrack.stop).thenAnswer((Invocation _) { + mockVideoTrack.stop = () { videoTrackStopped = true; - }); + }.toJS; when( () => cameraService.getMediaStreamForOptions(const CameraOptions()), ).thenAnswer( (_) => Future.value( - FakeMediaStream([videoTrack]), + createJSInteropWrapper( + FakeMediaStream([videoTrack]), + ) as MediaStream, ), ); @@ -135,15 +171,19 @@ void main() { testWidgets( 'gets a video stream ' 'for a video input device', (WidgetTester tester) async { - final FakeMediaDeviceInfo videoDevice = FakeMediaDeviceInfo( - '1', - 'Camera 1', - MediaDeviceKind.videoInput, - ); + final MediaDeviceInfo videoDevice = createJSInteropWrapper( + FakeMediaDeviceInfo( + '1', + 'Camera 1', + MediaDeviceKind.videoInput, + ), + ) as MediaDeviceInfo; - when(mediaDevices.enumerateDevices).thenAnswer( - (_) => Future>.value([videoDevice]), - ); + mockMediaDevices.enumerateDevices = () { + return Future>.value( + [videoDevice].toJS) + .toJS; + }.toJS; final List _ = await CameraPlatform.instance.availableCameras(); @@ -163,15 +203,19 @@ void main() { 'does not get a video stream ' 'for the video input device ' 'with an empty device id', (WidgetTester tester) async { - final FakeMediaDeviceInfo videoDevice = FakeMediaDeviceInfo( - '', - 'Camera 1', - MediaDeviceKind.videoInput, - ); + final MediaDeviceInfo videoDevice = createJSInteropWrapper( + FakeMediaDeviceInfo( + '', + 'Camera 1', + MediaDeviceKind.videoInput, + ), + ) as MediaDeviceInfo; - when(mediaDevices.enumerateDevices).thenAnswer( - (_) => Future>.value([videoDevice]), - ); + mockMediaDevices.enumerateDevices = () { + return Future>.value( + [videoDevice].toJS) + .toJS; + }.toJS; final List _ = await CameraPlatform.instance.availableCameras(); @@ -191,14 +235,24 @@ void main() { 'gets the facing mode ' 'from the first available video track ' 'of the video input device', (WidgetTester tester) async { - final FakeMediaDeviceInfo videoDevice = FakeMediaDeviceInfo( - '1', - 'Camera 1', - MediaDeviceKind.videoInput, - ); - - final FakeMediaStream videoStream = FakeMediaStream( - [MockMediaStreamTrack(), MockMediaStreamTrack()]); + final MediaDeviceInfo videoDevice = createJSInteropWrapper( + FakeMediaDeviceInfo( + '1', + 'Camera 1', + MediaDeviceKind.videoInput, + ), + ) as MediaDeviceInfo; + + final MediaStream videoStream = createJSInteropWrapper( + FakeMediaStream( + [ + createJSInteropWrapper(MockMediaStreamTrack()) + as MediaStreamTrack, + createJSInteropWrapper(MockMediaStreamTrack()) + as MediaStreamTrack, + ], + ), + ) as MediaStream; when( () => cameraService.getMediaStreamForOptions( @@ -208,16 +262,18 @@ void main() { ), ).thenAnswer((Invocation _) => Future.value(videoStream)); - when(mediaDevices.enumerateDevices).thenAnswer( - (_) => Future>.value([videoDevice]), - ); + mockMediaDevices.enumerateDevices = () { + return Future>.value( + [videoDevice].toJS) + .toJS; + }.toJS; final List _ = await CameraPlatform.instance.availableCameras(); verify( () => cameraService.getFacingModeForVideoTrack( - videoStream.getVideoTracks().first, + videoStream.getVideoTracks().toDart.first, ), ).called(1); }); @@ -226,44 +282,68 @@ void main() { 'returns appropriate camera descriptions ' 'for multiple video devices ' 'based on video streams', (WidgetTester tester) async { - final FakeMediaDeviceInfo firstVideoDevice = FakeMediaDeviceInfo( - '1', - 'Camera 1', - MediaDeviceKind.videoInput, - ); + final MediaDeviceInfo firstVideoDevice = createJSInteropWrapper( + FakeMediaDeviceInfo( + '1', + 'Camera 1', + MediaDeviceKind.videoInput, + ), + ) as MediaDeviceInfo; - final FakeMediaDeviceInfo secondVideoDevice = FakeMediaDeviceInfo( - '4', - 'Camera 4', - MediaDeviceKind.videoInput, - ); + final MediaDeviceInfo secondVideoDevice = createJSInteropWrapper( + FakeMediaDeviceInfo( + '4', + 'Camera 4', + MediaDeviceKind.videoInput, + ), + ) as MediaDeviceInfo; // Create a video stream for the first video device. - final FakeMediaStream firstVideoStream = FakeMediaStream( - [MockMediaStreamTrack(), MockMediaStreamTrack()]); + final MediaStream firstVideoStream = createJSInteropWrapper( + FakeMediaStream( + [ + createJSInteropWrapper(MockMediaStreamTrack()) + as MediaStreamTrack, + createJSInteropWrapper(MockMediaStreamTrack()) + as MediaStreamTrack, + ], + ), + ) as MediaStream; // Create a video stream for the second video device. - final FakeMediaStream secondVideoStream = - FakeMediaStream([MockMediaStreamTrack()]); + final MediaStream secondVideoStream = createJSInteropWrapper( + FakeMediaStream( + [ + createJSInteropWrapper(MockMediaStreamTrack()) + as MediaStreamTrack, + ], + ), + ) as MediaStream; // Mock media devices to return two video input devices // and two audio devices. - when(mediaDevices.enumerateDevices).thenAnswer( - (_) => Future>.value([ - firstVideoDevice, - FakeMediaDeviceInfo( - '2', - 'Audio Input 2', - MediaDeviceKind.audioInput, - ), - FakeMediaDeviceInfo( - '3', - 'Audio Output 3', - MediaDeviceKind.audioOutput, - ), - secondVideoDevice, - ]), - ); + mockMediaDevices.enumerateDevices = () { + return Future>.value( + [ + firstVideoDevice, + createJSInteropWrapper( + FakeMediaDeviceInfo( + '2', + 'Audio Input 2', + MediaDeviceKind.audioInput, + ), + ) as MediaDeviceInfo, + createJSInteropWrapper( + FakeMediaDeviceInfo( + '3', + 'Audio Output 3', + MediaDeviceKind.audioOutput, + ), + ) as MediaDeviceInfo, + secondVideoDevice, + ].toJS, + ).toJS; + }.toJS; // Mock camera service to return the first video stream // for the first video device. @@ -291,7 +371,7 @@ void main() { // for the first video stream. when( () => cameraService.getFacingModeForVideoTrack( - firstVideoStream.getVideoTracks().first, + firstVideoStream.getVideoTracks().toDart.first, ), ).thenReturn('user'); @@ -302,7 +382,7 @@ void main() { // for the second video stream. when( () => cameraService.getFacingModeForVideoTrack( - secondVideoStream.getVideoTracks().first, + secondVideoStream.getVideoTracks().toDart.first, ), ).thenReturn('environment'); @@ -317,12 +397,12 @@ void main() { cameras, equals([ CameraDescription( - name: firstVideoDevice.label!, + name: firstVideoDevice.label, lensDirection: CameraLensDirection.front, sensorOrientation: 0, ), CameraDescription( - name: secondVideoDevice.label!, + name: secondVideoDevice.label, lensDirection: CameraLensDirection.back, sensorOrientation: 0, ) @@ -333,18 +413,30 @@ void main() { testWidgets( 'sets camera metadata ' 'for the camera description', (WidgetTester tester) async { - final FakeMediaDeviceInfo videoDevice = FakeMediaDeviceInfo( - '1', - 'Camera 1', - MediaDeviceKind.videoInput, - ); - - final FakeMediaStream videoStream = FakeMediaStream( - [MockMediaStreamTrack(), MockMediaStreamTrack()]); + final MediaDeviceInfo videoDevice = createJSInteropWrapper( + FakeMediaDeviceInfo( + '1', + 'Camera 1', + MediaDeviceKind.videoInput, + ), + ) as MediaDeviceInfo; + + final MediaStream videoStream = createJSInteropWrapper( + FakeMediaStream( + [ + createJSInteropWrapper(MockMediaStreamTrack()) + as MediaStreamTrack, + createJSInteropWrapper(MockMediaStreamTrack()) + as MediaStreamTrack, + ], + ), + ) as MediaStream; - when(mediaDevices.enumerateDevices).thenAnswer( - (_) => Future>.value([videoDevice]), - ); + mockMediaDevices.enumerateDevices = () { + return Future>.value( + [videoDevice].toJS) + .toJS; + }.toJS; when( () => cameraService.getMediaStreamForOptions( @@ -356,7 +448,7 @@ void main() { when( () => cameraService.getFacingModeForVideoTrack( - videoStream.getVideoTracks().first, + videoStream.getVideoTracks().toDart.first, ), ).thenReturn('left'); @@ -370,7 +462,7 @@ void main() { (CameraPlatform.instance as CameraPlugin).camerasMetadata, equals({ camera: CameraMetadata( - deviceId: videoDevice.deviceId!, + deviceId: videoDevice.deviceId, facingMode: 'left', ) }), @@ -380,18 +472,32 @@ void main() { testWidgets( 'releases the video stream ' 'of a video input device', (WidgetTester tester) async { - final FakeMediaDeviceInfo videoDevice = FakeMediaDeviceInfo( - '1', - 'Camera 1', - MediaDeviceKind.videoInput, - ); + final MediaDeviceInfo videoDevice = createJSInteropWrapper( + FakeMediaDeviceInfo( + '1', + 'Camera 1', + MediaDeviceKind.videoInput, + ), + ) as MediaDeviceInfo; + + final List tracks = []; + final List stops = List.generate(2, (_) => false); + for (int i = 0; i < stops.length; i++) { + final MockMediaStreamTrack track = MockMediaStreamTrack(); + track.stop = () { + stops[i] = true; + }.toJS; + tracks.add(createJSInteropWrapper(track) as MediaStreamTrack); + } - final FakeMediaStream videoStream = FakeMediaStream( - [MockMediaStreamTrack(), MockMediaStreamTrack()]); + final MediaStream videoStream = + createJSInteropWrapper(FakeMediaStream(tracks)) as MediaStream; - when(mediaDevices.enumerateDevices).thenAnswer( - (_) => Future>.value([videoDevice]), - ); + mockMediaDevices.enumerateDevices = () { + return Future>.value( + [videoDevice].toJS) + .toJS; + }.toJS; when( () => cameraService.getMediaStreamForOptions( @@ -404,36 +510,21 @@ void main() { final List _ = await CameraPlatform.instance.availableCameras(); - for (final MediaStreamTrack videoTrack - in videoStream.getVideoTracks()) { - verify(videoTrack.stop).called(1); - } + expect(stops.every((bool e) => e), isTrue); }); group('throws CameraException', () { - testWidgets( - 'with notSupported error ' - 'when there are no media devices', (WidgetTester tester) async { - when(() => navigator.mediaDevices).thenReturn(null); - - expect( - () => CameraPlatform.instance.availableCameras(), - throwsA( - isA().having( - (CameraException e) => e.code, - 'code', - CameraErrorCode.notSupported.toString(), - ), - ), - ); - }); - testWidgets('when MediaDevices.enumerateDevices throws DomException', (WidgetTester tester) async { - final FakeDomException exception = - FakeDomException(DomException.UNKNOWN); + final DOMException exception = DOMException('UnknownError'); - when(mediaDevices.enumerateDevices).thenThrow(exception); + mockMediaDevices.enumerateDevices = () { + throw exception; + // ignore: dead_code + return Future>.value( + [].toJS, + ).toJS; + }.toJS; expect( () => CameraPlatform.instance.availableCameras(), @@ -700,14 +791,17 @@ void main() { group('initializeCamera', () { late Camera camera; - late VideoElement videoElement; + late MockVideoElement mockVideoElement; + late HTMLVideoElement videoElement; late StreamController errorStreamController, abortStreamController; late StreamController endedStreamController; setUp(() { camera = MockCamera(); - videoElement = MockVideoElement(); + mockVideoElement = MockVideoElement(); + videoElement = + createJSInteropWrapper(mockVideoElement) as HTMLVideoElement; errorStreamController = StreamController(); abortStreamController = StreamController(); @@ -719,10 +813,23 @@ void main() { when(camera.play).thenAnswer((Invocation _) => Future.value()); when(() => camera.videoElement).thenReturn(videoElement); - when(() => videoElement.onError).thenAnswer((Invocation _) => - FakeElementStream(errorStreamController.stream)); - when(() => videoElement.onAbort).thenAnswer((Invocation _) => - FakeElementStream(abortStreamController.stream)); + + final MockEventStreamProvider errorProvider = + MockEventStreamProvider(); + final MockEventStreamProvider abortProvider = + MockEventStreamProvider(); + + (CameraPlatform.instance as CameraPlugin).videoElementOnErrorProvider = + errorProvider; + (CameraPlatform.instance as CameraPlugin).videoElementOnAbortProvider = + abortProvider; + + when(() => errorProvider.forElement(videoElement)).thenAnswer( + (_) => FakeElementStream(errorStreamController.stream), + ); + when(() => abortProvider.forElement(videoElement)).thenAnswer( + (_) => FakeElementStream(abortStreamController.stream), + ); when(() => camera.onEnded) .thenAnswer((Invocation _) => endedStreamController.stream); @@ -808,8 +915,7 @@ void main() { testWidgets('when camera throws DomException', (WidgetTester tester) async { - final FakeDomException exception = - FakeDomException(DomException.NOT_ALLOWED); + final DOMException exception = DOMException('NotAllowedError'); when(camera.initialize) .thenAnswer((Invocation _) => Future.value()); @@ -834,6 +940,7 @@ void main() { group('lockCaptureOrientation', () { setUp(() { + registerFallbackValue(DeviceOrientation.portraitUp); when( () => cameraService.mapDeviceOrientationToOrientationType(any()), ).thenReturn(OrientationType.portraitPrimary); @@ -842,12 +949,18 @@ void main() { testWidgets( 'requests full-screen mode ' 'on documentElement', (WidgetTester tester) async { + int fullscreenCalls = 0; + mockDocumentElement.requestFullscreen = ([FullscreenOptions? options]) { + fullscreenCalls++; + return Future.value().toJS; + }.toJS; + await CameraPlatform.instance.lockCaptureOrientation( cameraId, DeviceOrientation.portraitUp, ); - verify(documentElement.requestFullscreen).called(1); + expect(fullscreenCalls, 1); }); testWidgets( @@ -859,6 +972,12 @@ void main() { ), ).thenReturn(OrientationType.landscapeSecondary); + final List capturedTypes = []; + mockScreenOrientation.lock = (OrientationLockType orientation) { + capturedTypes.add(orientation); + return Future.value().toJS; + }.toJS; + await CameraPlatform.instance.lockCaptureOrientation( cameraId, DeviceOrientation.landscapeRight, @@ -870,60 +989,16 @@ void main() { ), ).called(1); - verify( - () => screenOrientation.lock( - OrientationType.landscapeSecondary, - ), - ).called(1); + expect(capturedTypes.length, 1); + expect(capturedTypes[0], OrientationType.landscapeSecondary); }); group('throws PlatformException', () { - testWidgets( - 'with orientationNotSupported error ' - 'when screen is not supported', (WidgetTester tester) async { - when(() => window.screen).thenReturn(null); - - expect( - () => CameraPlatform.instance.lockCaptureOrientation( - cameraId, - DeviceOrientation.portraitUp, - ), - throwsA( - isA().having( - (PlatformException e) => e.code, - 'code', - CameraErrorCode.orientationNotSupported.toString(), - ), - ), - ); - }); - - testWidgets( - 'with orientationNotSupported error ' - 'when screen orientation is not supported', - (WidgetTester tester) async { - when(() => screen.orientation).thenReturn(null); - - expect( - () => CameraPlatform.instance.lockCaptureOrientation( - cameraId, - DeviceOrientation.portraitUp, - ), - throwsA( - isA().having( - (PlatformException e) => e.code, - 'code', - CameraErrorCode.orientationNotSupported.toString(), - ), - ), - ); - }); - testWidgets( 'with orientationNotSupported error ' 'when documentElement is not available', (WidgetTester tester) async { - when(() => document.documentElement).thenReturn(null); + mockDocument.documentElement = null; expect( () => CameraPlatform.instance.lockCaptureOrientation( @@ -938,14 +1013,19 @@ void main() { ), ), ); + + mockDocument.documentElement = documentElement; }); testWidgets('when lock throws DomException', (WidgetTester tester) async { - final FakeDomException exception = - FakeDomException(DomException.NOT_ALLOWED); + final DOMException exception = DOMException('NotAllowedError'); - when(() => screenOrientation.lock(any())).thenThrow(exception); + mockScreenOrientation.lock = (OrientationLockType orientation) { + throw exception; + // ignore: dead_code + return Future.value().toJS; + }.toJS; expect( () => CameraPlatform.instance.lockCaptureOrientation( @@ -973,58 +1053,24 @@ void main() { testWidgets('unlocks the capture orientation', (WidgetTester tester) async { + int unlocks = 0; + mockScreenOrientation.unlock = () { + unlocks++; + }.toJS; + await CameraPlatform.instance.unlockCaptureOrientation( cameraId, ); - verify(screenOrientation.unlock).called(1); + expect(unlocks, 1); }); group('throws PlatformException', () { - testWidgets( - 'with orientationNotSupported error ' - 'when screen is not supported', (WidgetTester tester) async { - when(() => window.screen).thenReturn(null); - - expect( - () => CameraPlatform.instance.unlockCaptureOrientation( - cameraId, - ), - throwsA( - isA().having( - (PlatformException e) => e.code, - 'code', - CameraErrorCode.orientationNotSupported.toString(), - ), - ), - ); - }); - - testWidgets( - 'with orientationNotSupported error ' - 'when screen orientation is not supported', - (WidgetTester tester) async { - when(() => screen.orientation).thenReturn(null); - - expect( - () => CameraPlatform.instance.unlockCaptureOrientation( - cameraId, - ), - throwsA( - isA().having( - (PlatformException e) => e.code, - 'code', - CameraErrorCode.orientationNotSupported.toString(), - ), - ), - ); - }); - testWidgets( 'with orientationNotSupported error ' 'when documentElement is not available', (WidgetTester tester) async { - when(() => document.documentElement).thenReturn(null); + mockDocument.documentElement = null; expect( () => CameraPlatform.instance.unlockCaptureOrientation( @@ -1038,14 +1084,19 @@ void main() { ), ), ); + + mockDocument.documentElement = documentElement; }); testWidgets('when unlock throws DomException', (WidgetTester tester) async { - final FakeDomException exception = - FakeDomException(DomException.NOT_ALLOWED); + final DOMException exception = DOMException('NotAllowedError'); - when(screenOrientation.unlock).thenThrow(exception); + mockScreenOrientation.unlock = () { + throw exception; + // ignore: dead_code + return Future.value().toJS; + }.toJS; expect( () => CameraPlatform.instance.unlockCaptureOrientation( @@ -1066,10 +1117,10 @@ void main() { group('takePicture', () { testWidgets('captures a picture', (WidgetTester tester) async { final MockCamera camera = MockCamera(); - final MockXFile capturedPicture = MockXFile(); + final XFile capturedPicture = XFile('/bogus/test'); when(camera.takePicture) - .thenAnswer((Invocation _) => Future.value(capturedPicture)); + .thenAnswer((Invocation _) async => capturedPicture); // Save the camera in the camera plugin. (CameraPlatform.instance as CameraPlugin).cameras[cameraId] = camera; @@ -1101,8 +1152,7 @@ void main() { testWidgets('when takePicture throws DomException', (WidgetTester tester) async { final MockCamera camera = MockCamera(); - final FakeDomException exception = - FakeDomException(DomException.NOT_SUPPORTED); + final DOMException exception = DOMException('NotSupportedError'); when(camera.takePicture).thenThrow(exception); @@ -1207,8 +1257,7 @@ void main() { testWidgets('when startVideoRecording throws DomException', (WidgetTester tester) async { - final FakeDomException exception = - FakeDomException(DomException.INVALID_STATE); + final DOMException exception = DOMException('InvalidStateError'); when(camera.startVideoRecording).thenThrow(exception); @@ -1284,10 +1333,10 @@ void main() { group('stopVideoRecording', () { testWidgets('stops a video recording', (WidgetTester tester) async { final MockCamera camera = MockCamera(); - final MockXFile capturedVideo = MockXFile(); + final XFile capturedVideo = XFile('/bogus/test'); when(camera.stopVideoRecording) - .thenAnswer((Invocation _) => Future.value(capturedVideo)); + .thenAnswer((Invocation _) async => capturedVideo); // Save the camera in the camera plugin. (CameraPlatform.instance as CameraPlugin).cameras[cameraId] = camera; @@ -1305,11 +1354,12 @@ void main() { final MockCamera camera = MockCamera(); final StreamController videoRecordingErrorController = StreamController(); + final XFile capturedVideo = XFile('/bogus/test'); when(camera.startVideoRecording).thenAnswer((Invocation _) async {}); when(camera.stopVideoRecording) - .thenAnswer((Invocation _) => Future.value(MockXFile())); + .thenAnswer((Invocation _) async => capturedVideo); when(() => camera.onVideoRecordingError) .thenAnswer((Invocation _) => videoRecordingErrorController.stream); @@ -1346,8 +1396,7 @@ void main() { testWidgets('when stopVideoRecording throws DomException', (WidgetTester tester) async { final MockCamera camera = MockCamera(); - final FakeDomException exception = - FakeDomException(DomException.INVALID_STATE); + final DOMException exception = DOMException('InvalidStateError'); when(camera.stopVideoRecording).thenThrow(exception); @@ -1427,8 +1476,7 @@ void main() { testWidgets('when pauseVideoRecording throws DomException', (WidgetTester tester) async { final MockCamera camera = MockCamera(); - final FakeDomException exception = - FakeDomException(DomException.INVALID_STATE); + final DOMException exception = DOMException('InvalidStateError'); when(camera.pauseVideoRecording).thenThrow(exception); @@ -1508,8 +1556,7 @@ void main() { testWidgets('when resumeVideoRecording throws DomException', (WidgetTester tester) async { final MockCamera camera = MockCamera(); - final FakeDomException exception = - FakeDomException(DomException.INVALID_STATE); + final DOMException exception = DOMException('InvalidStateError'); when(camera.resumeVideoRecording).thenThrow(exception); @@ -1595,8 +1642,7 @@ void main() { testWidgets('when setFlashMode throws DomException', (WidgetTester tester) async { final MockCamera camera = MockCamera(); - final FakeDomException exception = - FakeDomException(DomException.NOT_SUPPORTED); + final DOMException exception = DOMException('NotSupportedError'); when(() => camera.setFlashMode(any())).thenThrow(exception); @@ -1770,8 +1816,7 @@ void main() { testWidgets('when getMaxZoomLevel throws DomException', (WidgetTester tester) async { final MockCamera camera = MockCamera(); - final FakeDomException exception = - FakeDomException(DomException.NOT_SUPPORTED); + final DOMException exception = DOMException('NotSupportedError'); when(camera.getMaxZoomLevel).thenThrow(exception); @@ -1864,8 +1909,7 @@ void main() { testWidgets('when getMinZoomLevel throws DomException', (WidgetTester tester) async { final MockCamera camera = MockCamera(); - final FakeDomException exception = - FakeDomException(DomException.NOT_SUPPORTED); + final DOMException exception = DOMException('NotSupportedError'); when(camera.getMinZoomLevel).thenThrow(exception); @@ -1953,8 +1997,7 @@ void main() { testWidgets('when setZoomLevel throws DomException', (WidgetTester tester) async { final MockCamera camera = MockCamera(); - final FakeDomException exception = - FakeDomException(DomException.NOT_SUPPORTED); + final DOMException exception = DOMException('NotSupportedError'); when(() => camera.setZoomLevel(any())).thenThrow(exception); @@ -2066,8 +2109,7 @@ void main() { testWidgets('when pause throws DomException', (WidgetTester tester) async { final MockCamera camera = MockCamera(); - final FakeDomException exception = - FakeDomException(DomException.NOT_SUPPORTED); + final DOMException exception = DOMException('NotSupportedError'); when(camera.pause).thenThrow(exception); @@ -2121,8 +2163,7 @@ void main() { testWidgets('when play throws DomException', (WidgetTester tester) async { final MockCamera camera = MockCamera(); - final FakeDomException exception = - FakeDomException(DomException.NOT_SUPPORTED); + final DOMException exception = DOMException('NotSupportedError'); when(camera.play).thenThrow(exception); @@ -2192,7 +2233,8 @@ void main() { group('dispose', () { late Camera camera; - late VideoElement videoElement; + late MockVideoElement mockVideoElement; + late HTMLVideoElement videoElement; late StreamController errorStreamController, abortStreamController; late StreamController endedStreamController; @@ -2200,7 +2242,9 @@ void main() { setUp(() { camera = MockCamera(); - videoElement = MockVideoElement(); + mockVideoElement = MockVideoElement(); + videoElement = + createJSInteropWrapper(mockVideoElement) as HTMLVideoElement; errorStreamController = StreamController(); abortStreamController = StreamController(); @@ -2214,10 +2258,23 @@ void main() { when(camera.dispose).thenAnswer((Invocation _) => Future.value()); when(() => camera.videoElement).thenReturn(videoElement); - when(() => videoElement.onError).thenAnswer((Invocation _) => - FakeElementStream(errorStreamController.stream)); - when(() => videoElement.onAbort).thenAnswer((Invocation _) => - FakeElementStream(abortStreamController.stream)); + + final MockEventStreamProvider errorProvider = + MockEventStreamProvider(); + final MockEventStreamProvider abortProvider = + MockEventStreamProvider(); + + (CameraPlatform.instance as CameraPlugin).videoElementOnErrorProvider = + errorProvider; + (CameraPlatform.instance as CameraPlugin).videoElementOnAbortProvider = + abortProvider; + + when(() => errorProvider.forElement(videoElement)).thenAnswer( + (_) => FakeElementStream(errorStreamController.stream), + ); + when(() => abortProvider.forElement(videoElement)).thenAnswer( + (_) => FakeElementStream(abortStreamController.stream), + ); when(() => camera.onEnded) .thenAnswer((Invocation _) => endedStreamController.stream); @@ -2316,8 +2373,7 @@ void main() { testWidgets('when dispose throws DomException', (WidgetTester tester) async { final MockCamera camera = MockCamera(); - final FakeDomException exception = - FakeDomException(DomException.INVALID_ACCESS); + final DOMException exception = DOMException('InvalidAccessError'); when(camera.dispose).thenThrow(exception); @@ -2373,7 +2429,8 @@ void main() { group('events', () { late Camera camera; - late VideoElement videoElement; + late MockVideoElement mockVideoElement; + late HTMLVideoElement videoElement; late StreamController errorStreamController, abortStreamController; late StreamController endedStreamController; @@ -2381,7 +2438,9 @@ void main() { setUp(() { camera = MockCamera(); - videoElement = MockVideoElement(); + mockVideoElement = MockVideoElement(); + videoElement = + createJSInteropWrapper(mockVideoElement) as HTMLVideoElement; errorStreamController = StreamController(); abortStreamController = StreamController(); @@ -2394,10 +2453,23 @@ void main() { when(camera.play).thenAnswer((Invocation _) => Future.value()); when(() => camera.videoElement).thenReturn(videoElement); - when(() => videoElement.onError).thenAnswer((Invocation _) => - FakeElementStream(errorStreamController.stream)); - when(() => videoElement.onAbort).thenAnswer((Invocation _) => - FakeElementStream(abortStreamController.stream)); + + final MockEventStreamProvider errorProvider = + MockEventStreamProvider(); + final MockEventStreamProvider abortProvider = + MockEventStreamProvider(); + + (CameraPlatform.instance as CameraPlugin).videoElementOnErrorProvider = + errorProvider; + (CameraPlatform.instance as CameraPlugin).videoElementOnAbortProvider = + abortProvider; + + when(() => errorProvider.forElement(any())).thenAnswer( + (_) => FakeElementStream(errorStreamController.stream), + ); + when(() => abortProvider.forElement(any())).thenAnswer( + (_) => FakeElementStream(abortStreamController.stream), + ); when(() => camera.onEnded) .thenAnswer((Invocation _) => endedStreamController.stream); @@ -2405,8 +2477,7 @@ void main() { when(() => camera.onVideoRecordingError) .thenAnswer((Invocation _) => videoRecordingErrorController.stream); - when(() => camera.startVideoRecording()) - .thenAnswer((Invocation _) async {}); + when(camera.startVideoRecording).thenAnswer((Invocation _) async {}); }); testWidgets( @@ -2479,7 +2550,9 @@ void main() { await CameraPlatform.instance.initializeCamera(cameraId); - endedStreamController.add(MockMediaStreamTrack()); + endedStreamController.add( + createJSInteropWrapper(MockMediaStreamTrack()) as MediaStreamTrack, + ); expect( await streamQueue.next, @@ -2509,16 +2582,17 @@ void main() { await CameraPlatform.instance.initializeCamera(cameraId); - final FakeMediaError error = FakeMediaError( - MediaError.MEDIA_ERR_NETWORK, - 'A network error occurred.', - ); + final MediaError error = createJSInteropWrapper( + FakeMediaError( + MediaError.MEDIA_ERR_NETWORK, + 'A network error occurred.', + ), + ) as MediaError; final CameraErrorCode errorCode = CameraErrorCode.fromMediaError(error); - when(() => videoElement.error).thenReturn(error); - + mockVideoElement.error = error; errorStreamController.add(Event('error')); expect( @@ -2546,13 +2620,13 @@ void main() { await CameraPlatform.instance.initializeCamera(cameraId); - final FakeMediaError error = - FakeMediaError(MediaError.MEDIA_ERR_NETWORK); + final MediaError error = createJSInteropWrapper( + FakeMediaError(MediaError.MEDIA_ERR_NETWORK), + ) as MediaError; final CameraErrorCode errorCode = CameraErrorCode.fromMediaError(error); - when(() => videoElement.error).thenReturn(error); - + mockVideoElement.error = error; errorStreamController.add(Event('error')); expect( @@ -2839,9 +2913,7 @@ void main() { .thenAnswer((Invocation _) => const Stream.empty()); when( - () => camera.startVideoRecording( - maxVideoDuration: any(named: 'maxVideoDuration'), - ), + () => camera.startVideoRecording(), ).thenThrow(exception); final Stream eventStream = @@ -2883,7 +2955,9 @@ void main() { await CameraPlatform.instance.initializeCamera(cameraId); await CameraPlatform.instance.startVideoRecording(cameraId); - final FakeErrorEvent errorEvent = FakeErrorEvent('type', 'message'); + final ErrorEvent errorEvent = + createJSInteropWrapper(FakeErrorEvent('type', 'message')) + as ErrorEvent; videoRecordingErrorController.add(errorEvent); @@ -3015,7 +3089,7 @@ void main() { testWidgets('onVideoRecordedEvent emits a VideoRecordedEvent', (WidgetTester tester) async { final MockCamera camera = MockCamera(); - final MockXFile capturedVideo = MockXFile(); + final XFile capturedVideo = XFile('/bogus/test'); final Stream stream = Stream.value( VideoRecordedEvent(cameraId, capturedVideo, Duration.zero)); @@ -3038,24 +3112,16 @@ void main() { }); group('onDeviceOrientationChanged', () { - group('emits an empty stream', () { - testWidgets('when screen is not supported', - (WidgetTester tester) async { - when(() => window.screen).thenReturn(null); - - final Stream stream = - CameraPlatform.instance.onDeviceOrientationChanged(); - expect(await stream.isEmpty, isTrue); - }); + final StreamController eventStreamController = + StreamController(); - testWidgets('when screen orientation is not supported', - (WidgetTester tester) async { - when(() => screen.orientation).thenReturn(null); - - final Stream stream = - CameraPlatform.instance.onDeviceOrientationChanged(); - expect(await stream.isEmpty, isTrue); - }); + setUp(() { + final MockEventStreamProvider provider = + MockEventStreamProvider(); + (CameraPlatform.instance as CameraPlugin) + .orientationOnChangeProvider = provider; + when(() => provider.forTarget(any())) + .thenAnswer((_) => eventStreamController.stream); }); testWidgets('emits the initial DeviceOrientationChangedEvent', @@ -3067,14 +3133,7 @@ void main() { ).thenReturn(DeviceOrientation.portraitUp); // Set the initial screen orientation to portraitPrimary. - when(() => screenOrientation.type) - .thenReturn(OrientationType.portraitPrimary); - - final StreamController eventStreamController = - StreamController(); - - when(() => screenOrientation.onChange) - .thenAnswer((Invocation _) => eventStreamController.stream); + mockScreenOrientation.type = OrientationType.portraitPrimary; final Stream eventStream = CameraPlatform.instance.onDeviceOrientationChanged(); @@ -3110,12 +3169,6 @@ void main() { ), ).thenReturn(DeviceOrientation.portraitDown); - final StreamController eventStreamController = - StreamController(); - - when(() => screenOrientation.onChange) - .thenAnswer((Invocation _) => eventStreamController.stream); - final Stream eventStream = CameraPlatform.instance.onDeviceOrientationChanged(); @@ -3124,8 +3177,7 @@ void main() { // Change the screen orientation to landscapePrimary and // emit an event on the screenOrientation.onChange stream. - when(() => screenOrientation.type) - .thenReturn(OrientationType.landscapePrimary); + mockScreenOrientation.type = OrientationType.landscapePrimary; eventStreamController.add(Event('change')); @@ -3140,8 +3192,7 @@ void main() { // Change the screen orientation to portraitSecondary and // emit an event on the screenOrientation.onChange stream. - when(() => screenOrientation.type) - .thenReturn(OrientationType.portraitSecondary); + mockScreenOrientation.type = OrientationType.portraitSecondary; eventStreamController.add(Event('change')); diff --git a/packages/camera/camera_web/example/integration_test/helpers/mocks.dart b/packages/camera/camera_web/example/integration_test/helpers/mocks.dart index d1fbdd574ba4..e4852843d1ff 100644 --- a/packages/camera/camera_web/example/integration_test/helpers/mocks.dart +++ b/packages/camera/camera_web/example/integration_test/helpers/mocks.dart @@ -5,7 +5,7 @@ // ignore_for_file: avoid_implementing_value_types import 'dart:async'; -import 'dart:html'; +import 'dart:js_interop'; import 'dart:ui'; // ignore_for_file: implementation_imports @@ -13,103 +13,155 @@ import 'package:camera_web/src/camera.dart'; import 'package:camera_web/src/camera_service.dart'; import 'package:camera_web/src/shims/dart_js_util.dart'; import 'package:camera_web/src/types/types.dart'; -import 'package:cross_file/cross_file.dart'; import 'package:mocktail/mocktail.dart'; +// TODO(srujzs): This is exported in `package:web` 0.6.0. Remove this when it is available. +import 'package:web/src/helpers/events/streams.dart'; +import 'package:web/web.dart' as web; + +@JSExport() +class MockWindow { + late web.Navigator navigator; + late web.Screen screen; + late web.Document document; +} + +@JSExport() +class MockScreen { + late web.ScreenOrientation orientation; +} -class MockWindow extends Mock implements Window {} +@JSExport() +class MockScreenOrientation { + /// JSPromise Function(web.OrientationLockType orientation) + JSFunction lock = (web.OrientationLockType orientation) { + return Future.value().toJS; + }.toJS; -class MockScreen extends Mock implements Screen {} + /// void Function() + late JSFunction unlock; + late web.OrientationType type; +} + +@JSExport() +class MockDocument { + web.Element? documentElement; +} -class MockScreenOrientation extends Mock implements ScreenOrientation {} +@JSExport() +class MockElement { + /// JSPromise Function([FullscreenOptions options]) + JSFunction requestFullscreen = ([web.FullscreenOptions? options]) { + return Future.value().toJS; + }.toJS; +} -class MockDocument extends Mock implements Document {} +@JSExport() +class MockNavigator { + late web.MediaDevices mediaDevices; +} -class MockElement extends Mock implements Element {} +@JSExport() +class MockMediaDevices { + /// JSPromise Function([web.MediaStreamConstraints? constraints]) + late JSFunction getUserMedia; -class MockNavigator extends Mock implements Navigator {} + /// web.MediaTrackSupportedConstraints Function() + late JSFunction getSupportedConstraints; -class MockMediaDevices extends Mock implements MediaDevices {} + /// JSPromise> Function() + late JSFunction enumerateDevices; +} class MockCameraService extends Mock implements CameraService {} -class MockMediaStreamTrack extends Mock implements MediaStreamTrack {} +@JSExport() +class MockMediaStreamTrack { + /// web.MediaTrackCapabilities Function(); + late JSFunction getCapabilities; -class MockCamera extends Mock implements Camera {} + /// web.MediaTrackSettings Function() + JSFunction getSettings = () { + return web.MediaTrackSettings(); + }.toJS; -class MockCameraOptions extends Mock implements CameraOptions {} + /// JSPromise Function([web.MediaTrackConstraints? constraints]) + late JSFunction applyConstraints; -class MockVideoElement extends Mock implements VideoElement {} + /// void Function() + JSFunction stop = () {}.toJS; +} -class MockXFile extends Mock implements XFile {} +class MockCamera extends Mock implements Camera {} -class MockJsUtil extends Mock implements JsUtil {} +class MockCameraOptions extends Mock implements CameraOptions {} -class MockMediaRecorder extends Mock implements MediaRecorder {} +@JSExport() +class MockVideoElement { + web.MediaProvider? srcObject; + web.MediaError? error; +} -/// A fake [MediaStream] that returns the provided [_videoTracks]. -class FakeMediaStream extends Fake implements MediaStream { - FakeMediaStream(this._videoTracks); +class MockJsUtil extends Mock implements JsUtil {} - final List _videoTracks; +@JSExport() +class MockMediaRecorder { + /// void Function(String type, web.EventListener? callback, [JSAny options]) + JSFunction addEventListener = + (String type, web.EventListener? callback, [JSAny? options]) {}.toJS; - @override - List getVideoTracks() => _videoTracks; -} + /// void Function(String type, web.EventListener? callback, [JSAny options]) + JSFunction removeEventListener = + (String type, web.EventListener? callback, [JSAny? options]) {}.toJS; -/// A fake [MediaDeviceInfo] that returns the provided [_deviceId], [_label] and [_kind]. -class FakeMediaDeviceInfo extends Fake implements MediaDeviceInfo { - FakeMediaDeviceInfo(this._deviceId, this._label, this._kind); + /// void Function([int timeslice]) + JSFunction start = ([int? timeslice]) {}.toJS; - final String _deviceId; - final String _label; - final String _kind; + /// void Function() + JSFunction pause = () {}.toJS; - @override - String? get deviceId => _deviceId; + /// void Function() + JSFunction resume = () {}.toJS; - @override - String? get label => _label; + /// void Function() + JSFunction stop = () {}.toJS; - @override - String? get kind => _kind; + web.RecordingState state = 'inactive'; } -/// A fake [MediaError] that returns the provided error [_code] and [_message]. -class FakeMediaError extends Fake implements MediaError { - FakeMediaError( - this._code, [ - String message = '', - ]) : _message = message; - - final int _code; - final String _message; +/// A fake [MediaStream] that returns the provided [_videoTracks]. +@JSExport() +class FakeMediaStream { + FakeMediaStream(this._videoTracks); - @override - int get code => _code; + final List _videoTracks; - @override - String? get message => _message; + List getVideoTracks() => _videoTracks; } -/// A fake [DomException] that returns the provided error [_name] and [_message]. -class FakeDomException extends Fake implements DomException { - FakeDomException( - this._name, [ - String? message, - ]) : _message = message; +/// A fake [MediaDeviceInfo] that returns the provided [_deviceId], [_label] and [_kind]. +@JSExport() +class FakeMediaDeviceInfo { + FakeMediaDeviceInfo(this.deviceId, this.label, this.kind); - final String _name; - final String? _message; + final String deviceId; + final String label; + final String kind; +} - @override - String get name => _name; +/// A fake [MediaError] that returns the provided error [_code] and [_message]. +@JSExport() +class FakeMediaError { + FakeMediaError( + this.code, [ + this.message = '', + ]); - @override - String? get message => _message; + final int code; + final String message; } /// A fake [ElementStream] that listens to the provided [_stream] on [listen]. -class FakeElementStream extends Fake +class FakeElementStream extends Fake implements ElementStream { FakeElementStream(this._stream); @@ -128,31 +180,23 @@ class FakeElementStream extends Fake } /// A fake [BlobEvent] that returns the provided blob [data]. -class FakeBlobEvent extends Fake implements BlobEvent { - FakeBlobEvent(this._blob); - - final Blob? _blob; +@JSExport() +class FakeBlobEvent { + FakeBlobEvent(this.data); - @override - Blob? get data => _blob; + final web.Blob? data; } /// A fake [DomException] that returns the provided error [_name] and [_message]. -class FakeErrorEvent extends Fake implements ErrorEvent { +@JSExport() +class FakeErrorEvent { FakeErrorEvent( - String type, [ - String? message, - ]) : _type = type, - _message = message; + this.type, [ + this.message = '', + ]); - final String _type; - final String? _message; - - @override - String get type => _type; - - @override - String? get message => _message; + final String type; + final String message; } /// Returns a video element with a blank stream of size [videoSize]. @@ -162,14 +206,17 @@ class FakeErrorEvent extends Fake implements ErrorEvent { /// final videoElement = getVideoElementWithBlankStream(Size(100, 100)); /// final videoStream = videoElement.captureStream(); /// ``` -VideoElement getVideoElementWithBlankStream(Size videoSize) { - final CanvasElement canvasElement = CanvasElement( - width: videoSize.width.toInt(), - height: videoSize.height.toInt(), - )..context2D.fillRect(0, 0, videoSize.width, videoSize.height); +web.HTMLVideoElement getVideoElementWithBlankStream(Size videoSize) { + final web.HTMLCanvasElement canvasElement = web.HTMLCanvasElement() + ..width = videoSize.width.toInt() + ..height = videoSize.height.toInt() + ..context2D.fillRect(0, 0, videoSize.width, videoSize.height); - final VideoElement videoElement = VideoElement() + final web.HTMLVideoElement videoElement = web.HTMLVideoElement() ..srcObject = canvasElement.captureStream(); return videoElement; } + +class MockEventStreamProvider extends Mock + implements web.EventStreamProvider {} diff --git a/packages/camera/camera_web/example/integration_test/zoom_level_capability_test.dart b/packages/camera/camera_web/example/integration_test/zoom_level_capability_test.dart index d93b42690e5e..3a2145e39ec6 100644 --- a/packages/camera/camera_web/example/integration_test/zoom_level_capability_test.dart +++ b/packages/camera/camera_web/example/integration_test/zoom_level_capability_test.dart @@ -3,9 +3,12 @@ // found in the LICENSE file. // ignore: implementation_imports +import 'dart:js_interop'; + import 'package:camera_web/src/types/types.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; +import 'package:web/web.dart'; import 'helpers/helpers.dart'; @@ -16,7 +19,8 @@ void main() { testWidgets('sets all properties', (WidgetTester tester) async { const double minimum = 100.0; const double maximum = 400.0; - final MockMediaStreamTrack videoTrack = MockMediaStreamTrack(); + final MediaStreamTrack videoTrack = + createJSInteropWrapper(MockMediaStreamTrack()) as MediaStreamTrack; final ZoomLevelCapability capability = ZoomLevelCapability( minimum: minimum, @@ -30,7 +34,8 @@ void main() { }); testWidgets('supports value equality', (WidgetTester tester) async { - final MockMediaStreamTrack videoTrack = MockMediaStreamTrack(); + final MediaStreamTrack videoTrack = + createJSInteropWrapper(MockMediaStreamTrack()) as MediaStreamTrack; expect( ZoomLevelCapability( diff --git a/packages/camera/camera_web/example/pubspec.yaml b/packages/camera/camera_web/example/pubspec.yaml index 5cf64e1c5ced..8305d8434abf 100644 --- a/packages/camera/camera_web/example/pubspec.yaml +++ b/packages/camera/camera_web/example/pubspec.yaml @@ -2,8 +2,8 @@ name: camera_web_integration_tests publish_to: none environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: camera_platform_interface: ^2.6.0 @@ -16,6 +16,7 @@ dependencies: path: ../ flutter: sdk: flutter + web: ^1.0.0 dev_dependencies: async: ^2.5.0 @@ -25,4 +26,3 @@ dev_dependencies: integration_test: sdk: flutter mocktail: 0.3.0 - diff --git a/packages/camera/camera_web/example/web/index.html b/packages/camera/camera_web/example/web/index.html index f3c6a5e8a8e3..d11c45a766b9 100644 --- a/packages/camera/camera_web/example/web/index.html +++ b/packages/camera/camera_web/example/web/index.html @@ -7,6 +7,6 @@ Browser Tests - + diff --git a/packages/camera/camera_web/lib/src/camera.dart b/packages/camera/camera_web/lib/src/camera.dart index acf5ceef888b..124f595fecff 100644 --- a/packages/camera/camera_web/lib/src/camera.dart +++ b/packages/camera/camera_web/lib/src/camera.dart @@ -3,14 +3,17 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:html' as html; +import 'dart:js_interop'; import 'dart:ui'; import 'dart:ui_web' as ui_web; import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:flutter/foundation.dart'; +import 'package:web/web.dart' as web; +import 'package:web/web.dart'; import 'camera_service.dart'; +import 'pkg_web_tweaks.dart'; import 'types/types.dart'; String _getViewType(int cameraId) => 'plugins.flutter.io/camera_$cameraId'; @@ -48,10 +51,6 @@ class Camera { this.recorderOptions = const (audioBitrate: null, videoBitrate: null), }) : _cameraService = cameraService; - // A torch mode constraint name. - // See: https://w3c.github.io/mediacapture-image/#dom-mediatracksupportedconstraints-torch - static const String _torchModeKey = 'torch'; - /// The texture id used to register the camera view. final int textureId; @@ -63,16 +62,16 @@ class Camera { /// The video element that displays the camera stream. /// Initialized in [initialize]. - late final html.VideoElement videoElement; + late final web.HTMLVideoElement videoElement; /// The wrapping element for the [videoElement] to avoid overriding /// the custom styles applied in [_applyDefaultVideoStyles]. /// Initialized in [initialize]. - late final html.DivElement divElement; + late final web.HTMLDivElement divElement; /// The camera stream displayed in the [videoElement]. /// Initialized in [initialize] and [play], reset in [stop]. - html.MediaStream? stream; + web.MediaStream? stream; /// The stream of the camera video tracks that have ended playing. /// @@ -82,14 +81,14 @@ class Camera { /// /// MediaStreamTrack.onended: /// https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamTrack/onended - Stream get onEnded => onEndedController.stream; + Stream get onEnded => onEndedController.stream; /// The stream controller for the [onEnded] stream. @visibleForTesting - final StreamController onEndedController = - StreamController.broadcast(); + final StreamController onEndedController = + StreamController.broadcast(); - StreamSubscription? _onEndedSubscription; + StreamSubscription? _onEndedSubscription; /// The stream of the camera video recording errors. /// @@ -98,15 +97,20 @@ class Camera { /// /// MediaRecorder.error: /// https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/error_event - Stream get onVideoRecordingError => + Stream get onVideoRecordingError => videoRecordingErrorController.stream; + /// The stream provider for [MediaRecorder] error events. + @visibleForTesting + EventStreamProvider mediaRecorderOnErrorProvider = + EventStreamProviders.errorMediaRecorderEvent; + /// The stream controller for the [onVideoRecordingError] stream. @visibleForTesting - final StreamController videoRecordingErrorController = - StreamController.broadcast(); + final StreamController videoRecordingErrorController = + StreamController.broadcast(); - StreamSubscription? _onVideoRecordingErrorSubscription; + StreamSubscription? _onVideoRecordingErrorSubscription; /// The camera flash mode. @visibleForTesting @@ -117,36 +121,34 @@ class Camera { /// The current browser window used to access media devices. @visibleForTesting - html.Window? window = html.window; + web.Window window = web.window; /// The recorder used to record a video from the camera. @visibleForTesting - html.MediaRecorder? mediaRecorder; + web.MediaRecorder? mediaRecorder; /// Whether the video of the given type is supported. @visibleForTesting bool Function(String) isVideoTypeSupported = - html.MediaRecorder.isTypeSupported; + (String type) => web.MediaRecorder.isTypeSupported(type); /// The list of consecutive video data files recorded with [mediaRecorder]. - final List _videoData = []; + final List _videoData = []; /// Completes when the video recording is stopped/finished. Completer? _videoAvailableCompleter; /// A data listener fired when a new part of video data is available. - void Function(html.Event)? _videoDataAvailableListener; + void Function(web.BlobEvent)? _videoDataAvailableListener; /// A listener fired when a video recording is stopped. - void Function(html.Event)? _videoRecordingStoppedListener; + void Function(web.Event)? _videoRecordingStoppedListener; /// A builder to merge a list of blobs into a single blob. @visibleForTesting - // TODO(stuartmorgan): Remove this 'ignore' once we don't analyze using 2.10 - // any more. It's a false positive that is fixed in later versions. - // ignore: prefer_function_declarations_over_variables - html.Blob Function(List blobs, String type) blobBuilder = - (List blobs, String type) => html.Blob(blobs, type); + web.Blob Function(List blobs, String type) blobBuilder = + (List blobs, String type) => + web.Blob(blobs.toJS, web.BlobPropertyBag(type: type)); /// The stream that emits a [VideoRecordedEvent] when a video recording is created. Stream get onVideoRecordedEvent => @@ -166,10 +168,12 @@ class Camera { cameraId: textureId, ); - videoElement = html.VideoElement(); + videoElement = web.HTMLVideoElement(); - divElement = html.DivElement() + divElement = web.HTMLDivElement() ..style.setProperty('object-fit', 'cover') + ..style.setProperty('height', '100%') + ..style.setProperty('width', '100%') ..append(videoElement); ui_web.platformViewRegistry.registerViewFactory( @@ -185,12 +189,14 @@ class Camera { _applyDefaultVideoStyles(videoElement); - final List videoTracks = stream!.getVideoTracks(); + final List videoTracks = + stream!.getVideoTracks().toDart; if (videoTracks.isNotEmpty) { - final html.MediaStreamTrack defaultVideoTrack = videoTracks.first; - - _onEndedSubscription = defaultVideoTrack.onEnded.listen((html.Event _) { + final web.MediaStreamTrack defaultVideoTrack = videoTracks.first; + _onEndedSubscription = EventStreamProviders.endedEvent + .forTarget(defaultVideoTrack) + .listen((web.Event _) { onEndedController.add(defaultVideoTrack); }); } @@ -207,7 +213,7 @@ class Camera { ); videoElement.srcObject = stream; } - await videoElement.play(); + await videoElement.play().toDart; } /// Pauses the camera stream on the current frame. @@ -217,14 +223,15 @@ class Camera { /// Stops the camera stream and resets the camera source. void stop() { - final List videoTracks = stream!.getVideoTracks(); + final List videoTracks = + stream!.getVideoTracks().toDart; if (videoTracks.isNotEmpty) { onEndedController.add(videoTracks.first); } - final List? tracks = stream?.getTracks(); + final List? tracks = stream?.getTracks().toDart; if (tracks != null) { - for (final html.MediaStreamTrack track in tracks) { + for (final web.MediaStreamTrack track in tracks) { track.stop(); } } @@ -246,8 +253,9 @@ class Camera { final int videoWidth = videoElement.videoWidth; final int videoHeight = videoElement.videoHeight; - final html.CanvasElement canvas = - html.CanvasElement(width: videoWidth, height: videoHeight); + final web.HTMLCanvasElement canvas = web.HTMLCanvasElement() + ..width = videoWidth + ..height = videoHeight; final bool isBackCamera = getLensDirection() == CameraLensDirection.back; // Flip the picture horizontally if it is not taken from a back camera. @@ -257,16 +265,28 @@ class Camera { ..scale(-1, 1); } - canvas.context2D - .drawImageScaled(videoElement, 0, 0, videoWidth, videoHeight); + canvas.context2D.drawImageScaled( + videoElement, + 0, + 0, + videoWidth.toDouble(), + videoHeight.toDouble(), + ); - final html.Blob blob = await canvas.toBlob('image/jpeg'); + final Completer blobCompleter = Completer(); + canvas.toBlob( + (web.Blob blob) { + blobCompleter.complete(blob); + }.toJS, + 'image/jpeg', + ); + final web.Blob blob = await blobCompleter.future; if (shouldEnableTorchMode) { _setTorchMode(enabled: false); } - return XFile(html.Url.createObjectUrl(blob)); + return XFile(web.URL.createObjectURL(blob)); } /// Returns a size of the camera video based on its first video track size. @@ -274,25 +294,23 @@ class Camera { /// Returns [Size.zero] if the camera is missing a video track or /// the video track does not include the width or height setting. Size getVideoSize() { - final List videoTracks = - videoElement.srcObject?.getVideoTracks() ?? []; + final List videoTracks = + (videoElement.srcObject as web.MediaStream?)?.getVideoTracks().toDart ?? + []; if (videoTracks.isEmpty) { return Size.zero; } - final html.MediaStreamTrack defaultVideoTrack = videoTracks.first; - final Map defaultVideoTrackSettings = + final web.MediaStreamTrack defaultVideoTrack = videoTracks.first; + + final web.MediaTrackSettings defaultVideoTrackSettings = defaultVideoTrack.getSettings(); - final double? width = defaultVideoTrackSettings['width'] as double?; - final double? height = defaultVideoTrackSettings['height'] as double?; + final int width = defaultVideoTrackSettings.width; + final int height = defaultVideoTrackSettings.height; - if (width != null && height != null) { - return Size(width, height); - } else { - return Size.zero; - } + return Size(width.toDouble(), height.toDouble()); } /// Sets the camera flash mode to [mode] by modifying the camera @@ -307,11 +325,10 @@ class Camera { /// Throws a [CameraWebException] if the torch mode is not supported /// or the camera has not been initialized or started. void setFlashMode(FlashMode mode) { - final html.MediaDevices? mediaDevices = window?.navigator.mediaDevices; - final Map? supportedConstraints = - mediaDevices?.getSupportedConstraints(); - final bool torchModeSupported = - supportedConstraints?[_torchModeKey] as bool? ?? false; + final web.MediaDevices mediaDevices = window.navigator.mediaDevices; + final web.MediaTrackSupportedConstraints supportedConstraints = + mediaDevices.getSupportedConstraints(); + final bool torchModeSupported = supportedConstraints.torchNullable ?? false; if (!torchModeSupported) { throw CameraWebException( @@ -333,23 +350,22 @@ class Camera { /// Throws a [CameraWebException] if the torch mode is not supported /// or the camera has not been initialized or started. void _setTorchMode({required bool enabled}) { - final List videoTracks = - stream?.getVideoTracks() ?? []; + final List videoTracks = + stream?.getVideoTracks().toDart ?? []; if (videoTracks.isNotEmpty) { - final html.MediaStreamTrack defaultVideoTrack = videoTracks.first; - - final bool canEnableTorchMode = - defaultVideoTrack.getCapabilities()[_torchModeKey] as bool? ?? false; + final web.MediaStreamTrack defaultVideoTrack = videoTracks.first; + final bool canEnableTorchMode = defaultVideoTrack + .getCapabilities() + .torchNullable + ?.toDart + .first + .toDart ?? + false; if (canEnableTorchMode) { - defaultVideoTrack.applyConstraints({ - 'advanced': [ - { - _torchModeKey: enabled, - } - ] - }); + defaultVideoTrack.applyWebTweakConstraints( + WebTweakMediaTrackConstraints(torch: enabled.toJS)); } else { throw CameraWebException( textureId, @@ -397,13 +413,8 @@ class Camera { ); } - zoomLevelCapability.videoTrack.applyConstraints({ - 'advanced': [ - { - ZoomLevelCapability.constraintName: zoom, - } - ] - }); + zoomLevelCapability.videoTrack.applyWebTweakConstraints( + WebTweakMediaTrackConstraints(zoom: zoom.toJS)); } /// Returns a lens direction of this camera. @@ -411,21 +422,21 @@ class Camera { /// Returns null if the camera is missing a video track or /// the video track does not include the facing mode setting. CameraLensDirection? getLensDirection() { - final List videoTracks = - videoElement.srcObject?.getVideoTracks() ?? []; + final List videoTracks = + (videoElement.srcObject as web.MediaStream?)?.getVideoTracks().toDart ?? + []; if (videoTracks.isEmpty) { return null; } - final html.MediaStreamTrack defaultVideoTrack = videoTracks.first; - final Map defaultVideoTrackSettings = + final web.MediaStreamTrack defaultVideoTrack = videoTracks.first; + final web.MediaTrackSettings defaultVideoTrackSettings = defaultVideoTrack.getSettings(); - final String? facingMode = - defaultVideoTrackSettings['facingMode'] as String?; + final String? facingMode = defaultVideoTrackSettings.facingModeNullable; - if (facingMode != null) { + if (facingMode != null && facingMode.isNotEmpty) { return _cameraService.mapFacingModeToLensDirection(facingMode); } else { return null; @@ -435,98 +446,72 @@ class Camera { /// Returns the registered view type of the camera. String getViewType() => _getViewType(textureId); - /// Starts a new video recording using [html.MediaRecorder]. + /// Starts a new video recording using [web.MediaRecorder]. /// - /// Throws a [CameraWebException] if the provided maximum video duration is invalid - /// or the browser does not support any of the available video mime types - /// from [_videoMimeType]. - Future startVideoRecording({Duration? maxVideoDuration}) async { - if (maxVideoDuration != null && maxVideoDuration.inMilliseconds <= 0) { - throw CameraWebException( - textureId, - CameraErrorCode.notSupported, - 'The maximum video duration must be greater than 0 milliseconds.', - ); + /// Throws a [CameraWebException] if the browser does not support any of the + /// available video mime types from [_videoMimeType]. + Future startVideoRecording() async { + final web.MediaRecorderOptions options = + web.MediaRecorderOptions(mimeType: _videoMimeType); + if (recorderOptions.audioBitrate != null) { + options.audioBitsPerSecond = recorderOptions.audioBitrate!; + } + if (recorderOptions.videoBitrate != null) { + options.videoBitsPerSecond = recorderOptions.videoBitrate!; } mediaRecorder ??= - html.MediaRecorder(videoElement.srcObject!, { - 'mimeType': _videoMimeType, - if (recorderOptions.audioBitrate != null) - 'audioBitsPerSecond': recorderOptions.audioBitrate!, - if (recorderOptions.videoBitrate != null) - 'videoBitsPerSecond': recorderOptions.videoBitrate!, - }); + web.MediaRecorder(videoElement.srcObject! as web.MediaStream, options); _videoAvailableCompleter = Completer(); _videoDataAvailableListener = - (html.Event event) => _onVideoDataAvailable(event, maxVideoDuration); + (web.BlobEvent event) => _onVideoDataAvailable(event); _videoRecordingStoppedListener = - (html.Event event) => _onVideoRecordingStopped(event, maxVideoDuration); + (web.Event event) => _onVideoRecordingStopped(event); mediaRecorder!.addEventListener( 'dataavailable', - _videoDataAvailableListener, + _videoDataAvailableListener?.toJS, ); mediaRecorder!.addEventListener( 'stop', - _videoRecordingStoppedListener, + _videoRecordingStoppedListener?.toJS, ); - _onVideoRecordingErrorSubscription = - mediaRecorder!.onError.listen((html.Event event) { - final html.ErrorEvent error = event as html.ErrorEvent; + _onVideoRecordingErrorSubscription = mediaRecorderOnErrorProvider + .forTarget(mediaRecorder) + .listen((web.Event event) { + final web.ErrorEvent error = event as web.ErrorEvent; videoRecordingErrorController.add(error); }); - if (maxVideoDuration != null) { - mediaRecorder!.start(maxVideoDuration.inMilliseconds); - } else { - // Don't pass the null duration as that will fire a `dataavailable` event directly. - mediaRecorder!.start(); - } + mediaRecorder!.start(); } - void _onVideoDataAvailable( - html.Event event, [ - Duration? maxVideoDuration, - ]) { - final html.Blob? blob = (event as html.BlobEvent).data; - + void _onVideoDataAvailable(web.BlobEvent event) { // Append the recorded part of the video to the list of all video data files. - if (blob != null) { - _videoData.add(blob); - } - - // Stop the recorder if the video has a maxVideoDuration - // and the recording was not stopped manually. - if (maxVideoDuration != null && mediaRecorder!.state == 'recording') { - mediaRecorder!.stop(); - } + _videoData.add(event.data); } - Future _onVideoRecordingStopped( - html.Event event, [ - Duration? maxVideoDuration, - ]) async { + Future _onVideoRecordingStopped(web.Event event) async { if (_videoData.isNotEmpty) { // Concatenate all video data files into a single blob. final String videoType = _videoData.first.type; - final html.Blob videoBlob = blobBuilder(_videoData, videoType); + final web.Blob videoBlob = blobBuilder(_videoData, videoType); // Create a file containing the video blob. final XFile file = XFile( - html.Url.createObjectUrl(videoBlob), + web.URL.createObjectURL(videoBlob), mimeType: _videoMimeType, name: videoBlob.hashCode.toString(), ); // Emit an event containing the recorded video file. videoRecorderController.add( - VideoRecordedEvent(textureId, file, maxVideoDuration), + VideoRecordedEvent(textureId, file, null), ); _videoAvailableCompleter?.complete(file); @@ -535,12 +520,12 @@ class Camera { // Clean up the media recorder with its event listeners and video data. mediaRecorder!.removeEventListener( 'dataavailable', - _videoDataAvailableListener, + _videoDataAvailableListener?.toJS, ); mediaRecorder!.removeEventListener( 'stop', - _videoDataAvailableListener, + _videoDataAvailableListener?.toJS, ); await _onVideoRecordingErrorSubscription?.cancel(); @@ -638,7 +623,7 @@ class Camera { ); /// Applies default styles to the video [element]. - void _applyDefaultVideoStyles(html.VideoElement element) { + void _applyDefaultVideoStyles(web.HTMLVideoElement element) { final bool isBackCamera = getLensDirection() == CameraLensDirection.back; // Flip the video horizontally if it is not taken from a back camera. diff --git a/packages/camera/camera_web/lib/src/camera_service.dart b/packages/camera/camera_web/lib/src/camera_service.dart index 8ac40ff33ee6..072fe06859f0 100644 --- a/packages/camera/camera_web/lib/src/camera_service.dart +++ b/packages/camera/camera_web/lib/src/camera_service.dart @@ -2,25 +2,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:html' as html; +import 'dart:js_interop'; import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; +import 'package:web/web.dart' as web; import 'camera.dart'; +import 'pkg_web_tweaks.dart'; import 'shims/dart_js_util.dart'; import 'types/types.dart'; /// A service to fetch, map camera settings and /// obtain the camera stream. class CameraService { - // A facing mode constraint name. - static const String _facingModeKey = 'facingMode'; - /// The current browser window used to access media devices. @visibleForTesting - html.Window? window = html.window; + web.Window window = web.window; /// The utility to manipulate JavaScript interop objects. @visibleForTesting @@ -28,25 +27,19 @@ class CameraService { /// Returns a media stream associated with the camera device /// with [cameraId] and constrained by [options]. - Future getMediaStreamForOptions( + Future getMediaStreamForOptions( CameraOptions options, { int cameraId = 0, }) async { - final html.MediaDevices? mediaDevices = window?.navigator.mediaDevices; - - // Throw a not supported exception if the current browser window - // does not support any media devices. - if (mediaDevices == null) { - throw PlatformException( - code: CameraErrorCode.notSupported.toString(), - message: 'The camera is not supported on this device.', - ); - } + final web.MediaDevices mediaDevices = window.navigator.mediaDevices; try { - final Map constraints = options.toJson(); - return await mediaDevices.getUserMedia(constraints); - } on html.DomException catch (e) { + return await mediaDevices + .getUserMedia( + options.toMediaStreamConstraints(), + ) + .toDart; + } on web.DOMException catch (e) { switch (e.name) { case 'NotFoundError': case 'DevicesNotFoundError': @@ -120,12 +113,10 @@ class CameraService { ZoomLevelCapability getZoomLevelCapabilityForCamera( Camera camera, ) { - final html.MediaDevices? mediaDevices = window?.navigator.mediaDevices; - final Map? supportedConstraints = - mediaDevices?.getSupportedConstraints(); - final bool zoomLevelSupported = - supportedConstraints?[ZoomLevelCapability.constraintName] as bool? ?? - false; + final web.MediaDevices mediaDevices = window.navigator.mediaDevices; + final web.MediaTrackSupportedConstraints supportedConstraints = + mediaDevices.getSupportedConstraints(); + final bool zoomLevelSupported = supportedConstraints.zoomNullable ?? false; if (!zoomLevelSupported) { throw CameraWebException( @@ -135,31 +126,21 @@ class CameraService { ); } - final List videoTracks = - camera.stream?.getVideoTracks() ?? []; + final List videoTracks = + camera.stream?.getVideoTracks().toDart ?? []; if (videoTracks.isNotEmpty) { - final html.MediaStreamTrack defaultVideoTrack = videoTracks.first; + final web.MediaStreamTrack defaultVideoTrack = videoTracks.first; /// The zoom level capability is represented by MediaSettingsRange. /// See: https://developer.mozilla.org/en-US/docs/Web/API/MediaSettingsRange - final Object zoomLevelCapability = defaultVideoTrack - .getCapabilities()[ZoomLevelCapability.constraintName] - as Object? ?? - {}; - - // The zoom level capability is a nested JS object, therefore - // we need to access its properties with the js_util library. - // See: https://api.dart.dev/stable/2.13.4/dart-js_util/getProperty.html - final num? minimumZoomLevel = - jsUtil.getProperty(zoomLevelCapability, 'min') as num?; - final num? maximumZoomLevel = - jsUtil.getProperty(zoomLevelCapability, 'max') as num?; - - if (minimumZoomLevel != null && maximumZoomLevel != null) { + final WebTweakMediaSettingsRange? zoomLevelCapability = + defaultVideoTrack.getCapabilities().zoomNullable; + + if (zoomLevelCapability != null) { return ZoomLevelCapability( - minimum: minimumZoomLevel.toDouble(), - maximum: maximumZoomLevel.toDouble(), + minimum: zoomLevelCapability.min, + maximum: zoomLevelCapability.max, videoTrack: defaultVideoTrack, ); } else { @@ -180,26 +161,15 @@ class CameraService { /// Returns a facing mode of the [videoTrack] /// (null if the facing mode is not available). - String? getFacingModeForVideoTrack(html.MediaStreamTrack videoTrack) { - final html.MediaDevices? mediaDevices = window?.navigator.mediaDevices; - - // Throw a not supported exception if the current browser window - // does not support any media devices. - if (mediaDevices == null) { - throw PlatformException( - code: CameraErrorCode.notSupported.toString(), - message: 'The camera is not supported on this device.', - ); - } + String? getFacingModeForVideoTrack(web.MediaStreamTrack videoTrack) { + final web.MediaDevices mediaDevices = window.navigator.mediaDevices; // Check if the camera facing mode is supported by the current browser. - final Map supportedConstraints = + final web.MediaTrackSupportedConstraints supportedConstraints = mediaDevices.getSupportedConstraints(); - final bool facingModeSupported = - supportedConstraints[_facingModeKey] as bool? ?? false; // Return null if the facing mode is not supported. - if (!facingModeSupported) { + if (!supportedConstraints.facingMode) { return null; } @@ -209,10 +179,10 @@ class CameraService { // // MediaTrackSettings: // https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackSettings - final Map videoTrackSettings = videoTrack.getSettings(); - final String? facingMode = videoTrackSettings[_facingModeKey] as String?; + final web.MediaTrackSettings videoTrackSettings = videoTrack.getSettings(); + final String? facingMode = videoTrackSettings.facingModeNullable; - if (facingMode == null) { + if (facingMode == null || facingMode.isEmpty) { // If the facing mode does not exist in the video track settings, // check for the facing mode in the video track capabilities. // @@ -223,20 +193,20 @@ class CameraService { // // The method may not be supported on Firefox. // See: https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamTrack/getCapabilities#browser_compatibility - if (!jsUtil.hasProperty(videoTrack, 'getCapabilities')) { + if (!jsUtil.hasProperty(videoTrack, 'getCapabilities'.toJS)) { // Return null if the video track capabilities are not supported. return null; } - final Map videoTrackCapabilities = + final web.MediaTrackCapabilities videoTrackCapabilities = videoTrack.getCapabilities(); // A list of facing mode capabilities as // the camera may support multiple facing modes. - final List facingModeCapabilities = List.from( - (videoTrackCapabilities[_facingModeKey] as List?) - ?.cast() ?? - []); + final List facingModeCapabilities = videoTrackCapabilities + .facingMode.toDart + .map((JSString e) => e.toDart) + .toList(); if (facingModeCapabilities.isNotEmpty) { final String facingModeCapability = facingModeCapabilities.first; diff --git a/packages/camera/camera_web/lib/src/camera_web.dart b/packages/camera/camera_web/lib/src/camera_web.dart index 900d1c706fef..11d14316971f 100644 --- a/packages/camera/camera_web/lib/src/camera_web.dart +++ b/packages/camera/camera_web/lib/src/camera_web.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:html' as html; +import 'dart:js_interop'; import 'dart:math'; import 'package:camera_platform_interface/camera_platform_interface.dart'; @@ -11,9 +11,11 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; import 'package:stream_transform/stream_transform.dart'; +import 'package:web/web.dart' as web; import 'camera.dart'; import 'camera_service.dart'; +import 'pkg_web_tweaks.dart'; import 'types/types.dart'; // The default error message, when the error is an empty string. @@ -58,81 +60,86 @@ class CameraPlugin extends CameraPlatform { final StreamController cameraEventStreamController = StreamController.broadcast(); - final Map> - _cameraVideoErrorSubscriptions = >{}; + /// The stream provider for [web.HTMLVideoElement] error events. + @visibleForTesting + web.EventStreamProvider videoElementOnErrorProvider = + web.EventStreamProviders.errorElementEvent; + + final Map> _cameraVideoErrorSubscriptions = + >{}; - final Map> - _cameraVideoAbortSubscriptions = >{}; + /// The stream provider for [web.HTMLVideoElement] abort events. + @visibleForTesting + web.EventStreamProvider videoElementOnAbortProvider = + web.EventStreamProviders.errorElementEvent; - final Map> + final Map> _cameraVideoAbortSubscriptions = + >{}; + + final Map> _cameraEndedSubscriptions = - >{}; + >{}; - final Map> + final Map> _cameraVideoRecordingErrorSubscriptions = - >{}; + >{}; /// Returns a stream of camera events for the given [cameraId]. Stream _cameraEvents(int cameraId) => cameraEventStreamController.stream .where((CameraEvent event) => event.cameraId == cameraId); + /// The stream provider for [web.ScreenOrientation] change events. + @visibleForTesting + web.EventStreamProvider orientationOnChangeProvider = + web.EventStreamProviders.changeEvent; + /// The current browser window used to access media devices. @visibleForTesting - html.Window? window = html.window; + web.Window window = web.window; @override Future> availableCameras() async { try { - final html.MediaDevices? mediaDevices = window?.navigator.mediaDevices; + final web.MediaDevices mediaDevices = window.navigator.mediaDevices; final List cameras = []; - // Throw a not supported exception if the current browser window - // does not support any media devices. - if (mediaDevices == null) { - throw PlatformException( - code: CameraErrorCode.notSupported.toString(), - message: 'The camera is not supported on this device.', - ); - } - // Request video permissions only. - final html.MediaStream cameraStream = + final web.MediaStream cameraStream = await _cameraService.getMediaStreamForOptions(const CameraOptions()); // Release the camera stream used to request video permissions. cameraStream .getVideoTracks() - .forEach((html.MediaStreamTrack videoTrack) => videoTrack.stop()); + .toDart + .forEach((web.MediaStreamTrack videoTrack) => videoTrack.stop()); // Request available media devices. - final List devices = await mediaDevices.enumerateDevices(); + final List devices = + (await mediaDevices.enumerateDevices().toDart).toDart; // Filter video input devices. - final Iterable videoInputDevices = devices - .whereType() - .where((html.MediaDeviceInfo device) => - device.kind == MediaDeviceKind.videoInput) + final Iterable videoInputDevices = devices + .where( + (web.MediaDeviceInfo device) => + device.kind == MediaDeviceKind.videoInput, + ) /// The device id property is currently not supported on Internet Explorer: /// https://developer.mozilla.org/en-US/docs/Web/API/MediaDeviceInfo/deviceId#browser_compatibility - .where( - (html.MediaDeviceInfo device) => - device.deviceId != null && device.deviceId!.isNotEmpty, - ); + .where((web.MediaDeviceInfo device) => device.deviceId.isNotEmpty); // Map video input devices to camera descriptions. - for (final html.MediaDeviceInfo videoInputDevice in videoInputDevices) { + for (final web.MediaDeviceInfo videoInputDevice in videoInputDevices) { // Get the video stream for the current video input device // to later use for the available video tracks. - final html.MediaStream videoStream = await _getVideoStreamForDevice( - videoInputDevice.deviceId!, - ); + final web.MediaStream videoStream = + await _getVideoStreamForDevice(videoInputDevice.deviceId); // Get all video tracks in the video stream // to later extract the lens direction from the first track. - final List videoTracks = - videoStream.getVideoTracks(); + final List videoTracks = + videoStream.getVideoTracks().toDart; if (videoTracks.isNotEmpty) { // Get the facing mode from the first available video track. @@ -155,15 +162,14 @@ class CameraPlugin extends CameraPlatform { // https://developer.mozilla.org/en-US/docs/Web/API/MediaDeviceInfo/label // // Sensor orientation is currently not supported. - final String cameraLabel = videoInputDevice.label ?? ''; final CameraDescription camera = CameraDescription( - name: cameraLabel, + name: videoInputDevice.label, lensDirection: lensDirection, sensorOrientation: 0, ); final CameraMetadata cameraMetadata = CameraMetadata( - deviceId: videoInputDevice.deviceId!, + deviceId: videoInputDevice.deviceId, facingMode: facingMode, ); @@ -172,7 +178,7 @@ class CameraPlugin extends CameraPlatform { camerasMetadata[camera] = cameraMetadata; // Release the camera stream of the current video input device. - for (final html.MediaStreamTrack videoTrack in videoTracks) { + for (final web.MediaStreamTrack videoTrack in videoTracks) { videoTrack.stop(); } } else { @@ -182,7 +188,7 @@ class CameraPlugin extends CameraPlatform { } return cameras; - } on html.DomException catch (e) { + } on web.DOMException catch (e) { throw CameraException(e.name, e.message); } on PlatformException catch (e) { throw CameraException(e.code, e.message); @@ -278,14 +284,15 @@ class CameraPlugin extends CameraPlatform { // Add camera's video error events to the camera events stream. // The error event fires when the video element's source has failed to load, or can't be used. - _cameraVideoErrorSubscriptions[cameraId] = - camera.videoElement.onError.listen((html.Event _) { + _cameraVideoErrorSubscriptions[cameraId] = videoElementOnErrorProvider + .forElement(camera.videoElement) + .listen((web.Event _) { // The Event itself (_) doesn't contain information about the actual error. // We need to look at the HTMLMediaElement.error. // See: https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/error - final html.MediaError error = camera.videoElement.error!; + final web.MediaError error = camera.videoElement.error!; final CameraErrorCode errorCode = CameraErrorCode.fromMediaError(error); - final String? errorMessage = + final String errorMessage = error.message != '' ? error.message : _kDefaultErrorMessage; cameraEventStreamController.add( @@ -298,8 +305,9 @@ class CameraPlugin extends CameraPlatform { // Add camera's video abort events to the camera events stream. // The abort event fires when the video element's source has not fully loaded. - _cameraVideoAbortSubscriptions[cameraId] = - camera.videoElement.onAbort.listen((html.Event _) { + _cameraVideoAbortSubscriptions[cameraId] = videoElementOnAbortProvider + .forElement(camera.videoElement) + .listen((web.Event _) { cameraEventStreamController.add( CameraErrorEvent( cameraId, @@ -313,7 +321,7 @@ class CameraPlugin extends CameraPlatform { // Add camera's closing events to the camera events stream. // The onEnded stream fires when there is no more camera stream data. _cameraEndedSubscriptions[cameraId] = - camera.onEnded.listen((html.MediaStreamTrack _) { + camera.onEnded.listen((web.MediaStreamTrack _) { cameraEventStreamController.add( CameraClosingEvent(cameraId), ); @@ -334,7 +342,7 @@ class CameraPlugin extends CameraPlatform { false, ), ); - } on html.DomException catch (e) { + } on web.DOMException catch (e) { throw PlatformException(code: e.name, message: e.message); } on CameraWebException catch (e) { _addCameraErrorEvent(e); @@ -374,23 +382,22 @@ class CameraPlugin extends CameraPlatform { @override Stream onDeviceOrientationChanged() { - final html.ScreenOrientation? orientation = window?.screen?.orientation; - - if (orientation != null) { - // Create an initial orientation event that emits the device orientation - // as soon as subscribed to this stream. - final html.Event initialOrientationEvent = html.Event('change'); - - return orientation.onChange.startWith(initialOrientationEvent).map( - (html.Event _) { - final DeviceOrientation deviceOrientation = _cameraService - .mapOrientationTypeToDeviceOrientation(orientation.type!); - return DeviceOrientationChangedEvent(deviceOrientation); - }, - ); - } else { - return const Stream.empty(); - } + final web.ScreenOrientation orientation = window.screen.orientation; + + // Create an initial orientation event that emits the device orientation + // as soon as subscribed to this stream. + final web.Event initialOrientationEvent = web.Event('change'); + + return orientationOnChangeProvider + .forTarget(orientation) + .startWith(initialOrientationEvent) + .map( + (web.Event _) { + final DeviceOrientation deviceOrientation = _cameraService + .mapOrientationTypeToDeviceOrientation(orientation.type); + return DeviceOrientationChangedEvent(deviceOrientation); + }, + ); } @override @@ -399,11 +406,10 @@ class CameraPlugin extends CameraPlatform { DeviceOrientation orientation, ) async { try { - final html.ScreenOrientation? screenOrientation = - window?.screen?.orientation; - final html.Element? documentElement = window?.document.documentElement; + final web.ScreenOrientation screenOrientation = window.screen.orientation; + final web.Element? documentElement = window.document.documentElement; - if (screenOrientation != null && documentElement != null) { + if (documentElement != null) { final String orientationType = _cameraService.mapDeviceOrientationToOrientationType(orientation); @@ -411,16 +417,16 @@ class CameraPlugin extends CameraPlatform { // See: https://w3c.github.io/screen-orientation/#interaction-with-fullscreen-api // Recent versions of Dart changed requestFullscreen to return a Future instead of void. // This wrapper allows use of both the old and new APIs. - dynamic fullScreen() => documentElement.requestFullscreen(); + dynamic fullScreen() => documentElement.requestFullScreenTweak(); await fullScreen(); - await screenOrientation.lock(orientationType); + await screenOrientation.lock(orientationType).toDart; } else { throw PlatformException( code: CameraErrorCode.orientationNotSupported.toString(), message: 'Orientation is not supported in the current browser.', ); } - } on html.DomException catch (e) { + } on web.DOMException catch (e) { throw PlatformException(code: e.name, message: e.message); } } @@ -428,10 +434,10 @@ class CameraPlugin extends CameraPlatform { @override Future unlockCaptureOrientation(int cameraId) async { try { - final html.ScreenOrientation? orientation = window?.screen?.orientation; - final html.Element? documentElement = window?.document.documentElement; + final web.ScreenOrientation orientation = window.screen.orientation; + final web.Element? documentElement = window.document.documentElement; - if (orientation != null && documentElement != null) { + if (documentElement != null) { orientation.unlock(); } else { throw PlatformException( @@ -439,7 +445,7 @@ class CameraPlugin extends CameraPlatform { message: 'Orientation is not supported in the current browser.', ); } - } on html.DomException catch (e) { + } on web.DOMException catch (e) { throw PlatformException(code: e.name, message: e.message); } } @@ -448,7 +454,7 @@ class CameraPlugin extends CameraPlatform { Future takePicture(int cameraId) { try { return getCamera(cameraId).takePicture(); - } on html.DomException catch (e) { + } on web.DOMException catch (e) { throw PlatformException(code: e.name, message: e.message); } on CameraWebException catch (e) { _addCameraErrorEvent(e); @@ -463,8 +469,8 @@ class CameraPlugin extends CameraPlatform { @override Future startVideoRecording(int cameraId, {Duration? maxVideoDuration}) { - return startVideoCapturing( - VideoCaptureOptions(cameraId, maxDuration: maxVideoDuration)); + // Ignore maxVideoDuration, as it is deprecated. + return startVideoCapturing(VideoCaptureOptions(cameraId)); } @override @@ -480,7 +486,7 @@ class CameraPlugin extends CameraPlatform { // The error event fires when the video recording is not allowed or an unsupported // codec is used. _cameraVideoRecordingErrorSubscriptions[options.cameraId] = - camera.onVideoRecordingError.listen((html.ErrorEvent errorEvent) { + camera.onVideoRecordingError.listen((web.ErrorEvent errorEvent) { cameraEventStreamController.add( CameraErrorEvent( options.cameraId, @@ -489,8 +495,8 @@ class CameraPlugin extends CameraPlatform { ); }); - return camera.startVideoRecording(maxVideoDuration: options.maxDuration); - } on html.DomException catch (e) { + return camera.startVideoRecording(); + } on web.DOMException catch (e) { throw PlatformException(code: e.name, message: e.message); } on CameraWebException catch (e) { _addCameraErrorEvent(e); @@ -505,7 +511,7 @@ class CameraPlugin extends CameraPlatform { await getCamera(cameraId).stopVideoRecording(); await _cameraVideoRecordingErrorSubscriptions[cameraId]?.cancel(); return videoRecording; - } on html.DomException catch (e) { + } on web.DOMException catch (e) { throw PlatformException(code: e.name, message: e.message); } on CameraWebException catch (e) { _addCameraErrorEvent(e); @@ -517,7 +523,7 @@ class CameraPlugin extends CameraPlatform { Future pauseVideoRecording(int cameraId) { try { return getCamera(cameraId).pauseVideoRecording(); - } on html.DomException catch (e) { + } on web.DOMException catch (e) { throw PlatformException(code: e.name, message: e.message); } on CameraWebException catch (e) { _addCameraErrorEvent(e); @@ -529,7 +535,7 @@ class CameraPlugin extends CameraPlatform { Future resumeVideoRecording(int cameraId) { try { return getCamera(cameraId).resumeVideoRecording(); - } on html.DomException catch (e) { + } on web.DOMException catch (e) { throw PlatformException(code: e.name, message: e.message); } on CameraWebException catch (e) { _addCameraErrorEvent(e); @@ -541,7 +547,7 @@ class CameraPlugin extends CameraPlatform { Future setFlashMode(int cameraId, FlashMode mode) async { try { getCamera(cameraId).setFlashMode(mode); - } on html.DomException catch (e) { + } on web.DOMException catch (e) { throw PlatformException(code: e.name, message: e.message); } on CameraWebException catch (e) { _addCameraErrorEvent(e); @@ -593,7 +599,7 @@ class CameraPlugin extends CameraPlatform { Future getMaxZoomLevel(int cameraId) async { try { return getCamera(cameraId).getMaxZoomLevel(); - } on html.DomException catch (e) { + } on web.DOMException catch (e) { throw PlatformException(code: e.name, message: e.message); } on CameraWebException catch (e) { _addCameraErrorEvent(e); @@ -605,7 +611,7 @@ class CameraPlugin extends CameraPlatform { Future getMinZoomLevel(int cameraId) async { try { return getCamera(cameraId).getMinZoomLevel(); - } on html.DomException catch (e) { + } on web.DOMException catch (e) { throw PlatformException(code: e.name, message: e.message); } on CameraWebException catch (e) { _addCameraErrorEvent(e); @@ -617,7 +623,7 @@ class CameraPlugin extends CameraPlatform { Future setZoomLevel(int cameraId, double zoom) async { try { getCamera(cameraId).setZoomLevel(zoom); - } on html.DomException catch (e) { + } on web.DOMException catch (e) { throw CameraException(e.name, e.message); } on PlatformException catch (e) { throw CameraException(e.code, e.message); @@ -631,7 +637,7 @@ class CameraPlugin extends CameraPlatform { Future pausePreview(int cameraId) async { try { getCamera(cameraId).pause(); - } on html.DomException catch (e) { + } on web.DOMException catch (e) { throw PlatformException(code: e.name, message: e.message); } } @@ -640,7 +646,7 @@ class CameraPlugin extends CameraPlatform { Future resumePreview(int cameraId) async { try { await getCamera(cameraId).play(); - } on html.DomException catch (e) { + } on web.DOMException catch (e) { throw PlatformException(code: e.name, message: e.message); } on CameraWebException catch (e) { _addCameraErrorEvent(e); @@ -661,6 +667,7 @@ class CameraPlugin extends CameraPlatform { await getCamera(cameraId).dispose(); await _cameraVideoErrorSubscriptions[cameraId]?.cancel(); await _cameraVideoAbortSubscriptions[cameraId]?.cancel(); + await _cameraEndedSubscriptions[cameraId]?.cancel(); await _cameraVideoRecordingErrorSubscriptions[cameraId]?.cancel(); @@ -668,13 +675,13 @@ class CameraPlugin extends CameraPlatform { _cameraVideoErrorSubscriptions.remove(cameraId); _cameraVideoAbortSubscriptions.remove(cameraId); _cameraEndedSubscriptions.remove(cameraId); - } on html.DomException catch (e) { + } on web.DOMException catch (e) { throw PlatformException(code: e.name, message: e.message); } } /// Returns a media video stream for the device with the given [deviceId]. - Future _getVideoStreamForDevice( + Future _getVideoStreamForDevice( String deviceId, ) { // Create camera options with the desired device id. diff --git a/packages/camera/camera_web/lib/src/pkg_web_tweaks.dart b/packages/camera/camera_web/lib/src/pkg_web_tweaks.dart new file mode 100644 index 000000000000..fb0e84ef3774 --- /dev/null +++ b/packages/camera/camera_web/lib/src/pkg_web_tweaks.dart @@ -0,0 +1,74 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// ignore_for_file: public_member_api_docs + +import 'dart:js_interop'; + +import 'package:web/web.dart'; + +/// Adds missing fields to [Element]. +extension FullScreenSupportMethods on Element { + @JS('requestFullscreen') + external JSPromise requestFullScreenTweak([JSAny options]); +} + +/// Adds missing fields to [MediaTrackSupportedConstraints]. +extension NonStandardFieldsOnMediaTrackSupportedConstraints + on MediaTrackSupportedConstraints { + @JS('zoom') + external bool? get zoomNullable; + + @JS('torch') + external bool? get torchNullable; +} + +/// Adds missing fields to [MediaTrackCapabilities]. +extension NonStandardFieldsOnMediaTrackCapabilities on MediaTrackCapabilities { + @JS('zoom') + external WebTweakMediaSettingsRange? get zoomNullable; + + @JS('torch') + external JSArray? get torchNullable; +} + +/// Adds missing fields to [MediaTrackSettings] +extension NonStandardFieldsOnMediaTrackSettings on MediaTrackSettings { + @JS('facingMode') + external String? get facingModeNullable; +} + +/// Brought over from package:web 1.0.0 +extension type WebTweakMediaSettingsRange._(JSObject _) implements JSObject { + @JS('MediaSettingsRange') + external factory WebTweakMediaSettingsRange({ + num max, + num min, + num step, + }); + + external double get max; + external set max(num value); + external double get min; + external set min(num value); + external double get step; + external set step(num value); +} + +/// Adds an applyConstraints method that accepts the WebTweakMediaTrackConstraints. +extension WebTweakMethodVersions on MediaStreamTrack { + @JS('applyConstraints') + external JSPromise applyWebTweakConstraints( + [WebTweakMediaTrackConstraints constraints]); +} + +/// Allows creating the MediaTrackConstraints that are needed. +/// Brought over from package:web 1.0.0 +extension type WebTweakMediaTrackConstraints._(JSObject _) implements JSObject { + @JS('MediaTrackConstraints') + external factory WebTweakMediaTrackConstraints({ + JSAny zoom, + ConstrainBoolean torch, + }); +} diff --git a/packages/camera/camera_web/lib/src/shims/dart_js_util.dart b/packages/camera/camera_web/lib/src/shims/dart_js_util.dart index 7d766e8c269e..50cda211725f 100644 --- a/packages/camera/camera_web/lib/src/shims/dart_js_util.dart +++ b/packages/camera/camera_web/lib/src/shims/dart_js_util.dart @@ -2,14 +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_util' as js_util; +import 'dart:js_interop'; +import 'dart:js_interop_unsafe'; -/// A utility that shims dart:js_util to manipulate JavaScript interop objects. +/// A utility that shims dart:js_interop to manipulate JavaScript interop objects. class JsUtil { /// Returns true if the object [o] has the property [name]. - bool hasProperty(Object o, Object name) => js_util.hasProperty(o, name); + bool hasProperty(JSObject o, JSAny name) => o.hasProperty(name).toDart; /// Returns the value of the property [name] in the object [o]. - dynamic getProperty(Object o, Object name) => - js_util.getProperty(o, name); + JSAny? getProperty(JSObject o, JSAny name) => o.getProperty(name); } diff --git a/packages/camera/camera_web/lib/src/types/camera_error_code.dart b/packages/camera/camera_web/lib/src/types/camera_error_code.dart index 8f1831f79cf5..6619e5fb388b 100644 --- a/packages/camera/camera_web/lib/src/types/camera_error_code.dart +++ b/packages/camera/camera_web/lib/src/types/camera_error_code.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. -import 'dart:html' as html; +import 'package:web/web.dart' as web; /// Error codes that may occur during the camera initialization, /// configuration or video streaming. @@ -78,18 +78,17 @@ class CameraErrorCode { /// Returns a camera error code based on the media error. /// /// See: https://developer.mozilla.org/en-US/docs/Web/API/MediaError/code - static CameraErrorCode fromMediaError(html.MediaError error) { - switch (error.code) { - case html.MediaError.MEDIA_ERR_ABORTED: - return const CameraErrorCode._('mediaErrorAborted'); - case html.MediaError.MEDIA_ERR_NETWORK: - return const CameraErrorCode._('mediaErrorNetwork'); - case html.MediaError.MEDIA_ERR_DECODE: - return const CameraErrorCode._('mediaErrorDecode'); - case html.MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED: - return const CameraErrorCode._('mediaErrorSourceNotSupported'); - default: - return const CameraErrorCode._('mediaErrorUnknown'); + static CameraErrorCode fromMediaError(web.MediaError error) { + if (error.code == web.MediaError.MEDIA_ERR_ABORTED) { + return const CameraErrorCode._('mediaErrorAborted'); + } else if (error.code == web.MediaError.MEDIA_ERR_NETWORK) { + return const CameraErrorCode._('mediaErrorNetwork'); + } else if (error.code == web.MediaError.MEDIA_ERR_DECODE) { + return const CameraErrorCode._('mediaErrorDecode'); + } else if (error.code == web.MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED) { + return const CameraErrorCode._('mediaErrorSourceNotSupported'); + } else { + return const CameraErrorCode._('mediaErrorUnknown'); } } } diff --git a/packages/camera/camera_web/lib/src/types/camera_options.dart b/packages/camera/camera_web/lib/src/types/camera_options.dart index ecb729d74544..45b446215a89 100644 --- a/packages/camera/camera_web/lib/src/types/camera_options.dart +++ b/packages/camera/camera_web/lib/src/types/camera_options.dart @@ -2,7 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:js_interop'; + import 'package:flutter/foundation.dart'; +import 'package:web/web.dart' as web; /// Options used to create a camera with the given /// [audio] and [video] media constraints. @@ -28,12 +31,12 @@ class CameraOptions { /// The video constraints for the camera. final VideoConstraints video; - /// Converts the current instance to a Map. - Map toJson() { - return { - 'audio': audio.toJson(), - 'video': video.toJson(), - }; + /// Converts `this` to something that can be used by the browser. + web.MediaStreamConstraints toMediaStreamConstraints() { + return web.MediaStreamConstraints( + audio: audio.toMediaStreamConstraints(), + video: video.toMediaStreamConstraints(), + ); } @override @@ -63,8 +66,8 @@ class AudioConstraints { /// Whether the audio track should be enabled. final bool enabled; - /// Converts the current instance to a Map. - Object toJson() => enabled; + /// Convert `this` to something that can be used on the browser. + JSAny toMediaStreamConstraints() => enabled.toJS; @override bool operator ==(Object other) { @@ -104,24 +107,15 @@ class VideoConstraints { /// The device id of the video track. final String? deviceId; - /// Converts the current instance to a Map. - Object toJson() { - final Map json = {}; - - if (width != null) { - json['width'] = width!.toJson(); - } - if (height != null) { - json['height'] = height!.toJson(); - } - if (facingMode != null) { - json['facingMode'] = facingMode!.toJson(); - } - if (deviceId != null) { - json['deviceId'] = {'exact': deviceId!}; - } - - return json; + // TODO(dit): package:web has a class for this. Use it instead of jsify and toJson. + /// Convert `this` to something that can be used on the browser. + JSAny toMediaStreamConstraints() { + return { + if (width != null) 'width': width!.toJson(), + if (height != null) 'height': height!.toJson(), + if (facingMode != null) 'facingMode': facingMode!.toJson(), + if (deviceId != null) 'deviceId': {'exact': deviceId!}, + }.jsify()!; } @override @@ -162,6 +156,7 @@ enum CameraType { String toString() => _type; } +// TODO(dit): package:web has a class for this. Use it instead of toJson. /// Indicates the direction in which the desired camera should be pointing. @immutable class FacingModeConstraint { @@ -191,6 +186,7 @@ class FacingModeConstraint { /// the desired facing [type] to be considered acceptable. final CameraType? exact; + // TODO(dit): package:web has a class for this. Use it instead of toJson. /// Converts the current instance to a Map. Object toJson() { return { @@ -214,6 +210,7 @@ class FacingModeConstraint { int get hashCode => Object.hash(ideal, exact); } +// TODO(dit): package:web has a class for this. Use it instead of toJson. /// The size of the requested video track used in /// [VideoConstraints.width] and [VideoConstraints.height]. /// @@ -240,6 +237,7 @@ class VideoSizeConstraint { /// The maximum video size. final int? maximum; + // TODO(dit): package:web has a class for this. Use it instead of toJson. /// Converts the current instance to a Map. Object toJson() { final Map json = {}; diff --git a/packages/camera/camera_web/lib/src/types/zoom_level_capability.dart b/packages/camera/camera_web/lib/src/types/zoom_level_capability.dart index d20bd25108bb..71e250b3a8a8 100644 --- a/packages/camera/camera_web/lib/src/types/zoom_level_capability.dart +++ b/packages/camera/camera_web/lib/src/types/zoom_level_capability.dart @@ -2,9 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:html' as html; - import 'package:flutter/foundation.dart'; +import 'package:web/web.dart' as web; /// The possible range of values for the zoom level configurable /// on the camera video track. @@ -30,7 +29,7 @@ class ZoomLevelCapability { final double maximum; /// The video track capable of configuring the zoom level. - final html.MediaStreamTrack videoTrack; + final web.MediaStreamTrack videoTrack; @override bool operator ==(Object other) { diff --git a/packages/camera/camera_web/pubspec.yaml b/packages/camera/camera_web/pubspec.yaml index 8e47d50a09a3..4052a701b86b 100644 --- a/packages/camera/camera_web/pubspec.yaml +++ b/packages/camera/camera_web/pubspec.yaml @@ -2,11 +2,11 @@ name: camera_web description: A Flutter plugin for getting information about and controlling the camera on Web. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.3.3 +version: 0.3.5 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: @@ -23,6 +23,7 @@ dependencies: flutter_web_plugins: sdk: flutter stream_transform: ^2.0.0 + web: ">=0.5.1 <2.0.0" dev_dependencies: flutter_test: diff --git a/packages/camera/camera_windows/CHANGELOG.md b/packages/camera/camera_windows/CHANGELOG.md index 9efbd0fd10f6..3479db4ae26a 100644 --- a/packages/camera/camera_windows/CHANGELOG.md +++ b/packages/camera/camera_windows/CHANGELOG.md @@ -1,5 +1,30 @@ -## NEXT +## 0.2.6 +* Reverts streaming frame support, as the implementation was incorrect and never + exposed. + +## 0.2.5+1 + +* Updates C++ to Dart communication to use Pigeon. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + +## 0.2.5 + +* Adds support for streaming frames. + +## 0.2.4+1 + +* Updates to pigeon 21. + +## 0.2.4 + +* Removes `maxVideoDuration`/`maxDuration`, as the feature was never exposed at + the app-facing package level, and is deprecated at the platform interface + level. + +## 0.2.3 + +* Converts native platform calls to Pigeon. * Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. ## 0.2.2 diff --git a/packages/camera/camera_windows/README.md b/packages/camera/camera_windows/README.md index 4b66ad3dfe32..429e1f6e47fe 100644 --- a/packages/camera/camera_windows/README.md +++ b/packages/camera/camera_windows/README.md @@ -61,7 +61,7 @@ disposing of the camera is the only way to reset the situation. [camera]: https://pub.dev/packages/camera -[endorsed-federated-plugin]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[endorsed-federated-plugin]: https://flutter.dev/to/endorsed-federated-plugin [install]: https://pub.dev/packages/camera_windows/install [camera-control-issue]: https://github.com/flutter/flutter/issues/97537 [device-orientation-issue]: https://github.com/flutter/flutter/issues/97540 diff --git a/packages/camera/camera_windows/example/pubspec.yaml b/packages/camera/camera_windows/example/pubspec.yaml index 6e94a03e4ae5..201cf9df581e 100644 --- a/packages/camera/camera_windows/example/pubspec.yaml +++ b/packages/camera/camera_windows/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the camera_windows plugin. publish_to: 'none' environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: camera_platform_interface: ^2.6.0 diff --git a/packages/camera/camera_windows/lib/camera_windows.dart b/packages/camera/camera_windows/lib/camera_windows.dart index fc4ce3b09c81..523b41b69751 100644 --- a/packages/camera/camera_windows/lib/camera_windows.dart +++ b/packages/camera/camera_windows/lib/camera_windows.dart @@ -10,20 +10,27 @@ import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:stream_transform/stream_transform.dart'; +import 'src/messages.g.dart'; + /// An implementation of [CameraPlatform] for Windows. class CameraWindows extends CameraPlatform { + /// Creates a new Windows [CameraPlatform] implementation instance. + CameraWindows({@visibleForTesting CameraApi? api}) + : _hostApi = api ?? CameraApi(); + /// Registers the Windows implementation of CameraPlatform. static void registerWith() { CameraPlatform.instance = CameraWindows(); } - /// The method channel used to interact with the native platform. - @visibleForTesting - final MethodChannel pluginChannel = - const MethodChannel('plugins.flutter.io/camera_windows'); + /// Interface for calling host-side code. + final CameraApi _hostApi; - /// Camera specific method channels to allow communicating with specific cameras. - final Map _cameraChannels = {}; + /// The per-camera handlers for messages that should be rebroadcast to + /// clients as [CameraEvent]s. + @visibleForTesting + final Map hostCameraHandlers = + {}; /// The controller that broadcasts events coming from handleCameraMethodCall /// @@ -43,19 +50,18 @@ class CameraWindows extends CameraPlatform { @override Future> availableCameras() async { try { - final List>? cameras = await pluginChannel - .invokeListMethod>('availableCameras'); - - if (cameras == null) { - return []; - } + final List cameras = await _hostApi.getAvailableCameras(); - return cameras.map((Map camera) { + return cameras.map((String? cameraName) { return CameraDescription( - name: camera['name'] as String, - lensDirection: - parseCameraLensDirection(camera['lensFacing'] as String), - sensorOrientation: camera['sensorOrientation'] as int, + // This type is only nullable due to Pigeon limitations, see + // https://github.com/flutter/flutter/issues/97848. The native code + // will never return null. + name: cameraName!, + // TODO(stuartmorgan): Implement these; see + // https://github.com/flutter/flutter/issues/97540. + lensDirection: CameraLensDirection.front, + sensorOrientation: 0, ); }).toList(); } on PlatformException catch (e) { @@ -83,23 +89,8 @@ class CameraWindows extends CameraPlatform { ) async { try { // If resolutionPreset is not specified, plugin selects the highest resolution possible. - final Map? reply = await pluginChannel - .invokeMapMethod('create', { - 'cameraName': cameraDescription.name, - 'resolutionPreset': null != mediaSettings?.resolutionPreset - ? _serializeResolutionPreset(mediaSettings!.resolutionPreset) - : null, - 'fps': mediaSettings?.fps, - 'videoBitrate': mediaSettings?.videoBitrate, - 'audioBitrate': mediaSettings?.audioBitrate, - 'enableAudio': mediaSettings?.enableAudio ?? true, - }); - - if (reply == null) { - throw CameraException('System', 'Cannot create camera'); - } - - return reply['cameraId']! as int; + return await _hostApi.create( + cameraDescription.name, _pigeonMediaSettings(mediaSettings)); } on PlatformException catch (e) { throw CameraException(e.code, e.message); } @@ -110,35 +101,21 @@ class CameraWindows extends CameraPlatform { int cameraId, { ImageFormatGroup imageFormatGroup = ImageFormatGroup.unknown, }) async { - final int requestedCameraId = cameraId; - - /// Creates channel for camera events. - _cameraChannels.putIfAbsent(requestedCameraId, () { - final MethodChannel channel = MethodChannel( - 'plugins.flutter.io/camera_windows/camera$requestedCameraId'); - channel.setMethodCallHandler( - (MethodCall call) => handleCameraMethodCall(call, requestedCameraId), - ); - return channel; - }); - - final Map? reply; + hostCameraHandlers.putIfAbsent(cameraId, + () => HostCameraMessageHandler(cameraId, cameraEventStreamController)); + + final PlatformSize reply; try { - reply = await pluginChannel.invokeMapMethod( - 'initialize', - { - 'cameraId': requestedCameraId, - }, - ); + reply = await _hostApi.initialize(cameraId); } on PlatformException catch (e) { throw CameraException(e.code, e.message); } cameraEventStreamController.add( CameraInitializedEvent( - requestedCameraId, - reply!['previewWidth']!, - reply['previewHeight']!, + cameraId, + reply.width, + reply.height, ExposureMode.auto, false, FocusMode.auto, @@ -149,17 +126,10 @@ class CameraWindows extends CameraPlatform { @override Future dispose(int cameraId) async { - await pluginChannel.invokeMethod( - 'dispose', - {'cameraId': cameraId}, - ); + await _hostApi.dispose(cameraId); // Destroy method channel after camera is disposed to be able to handle last messages. - if (_cameraChannels.containsKey(cameraId)) { - final MethodChannel? cameraChannel = _cameraChannels[cameraId]; - cameraChannel?.setMethodCallHandler(null); - _cameraChannels.remove(cameraId); - } + hostCameraHandlers.remove(cameraId)?.dispose(); } @override @@ -217,24 +187,21 @@ class CameraWindows extends CameraPlatform { @override Future takePicture(int cameraId) async { - final String? path; - path = await pluginChannel.invokeMethod( - 'takePicture', - {'cameraId': cameraId}, - ); + final String path = await _hostApi.takePicture(cameraId); - return XFile(path!); + return XFile(path); } @override - Future prepareForVideoRecording() => - pluginChannel.invokeMethod('prepareForVideoRecording'); + Future prepareForVideoRecording() async { + // No-op. + } @override Future startVideoRecording(int cameraId, {Duration? maxVideoDuration}) async { - return startVideoCapturing( - VideoCaptureOptions(cameraId, maxDuration: maxVideoDuration)); + // Ignore maxVideoDuration, as it is unimplemented and deprecated. + return startVideoCapturing(VideoCaptureOptions(cameraId)); } @override @@ -244,25 +211,15 @@ class CameraWindows extends CameraPlatform { 'Streaming is not currently supported on Windows'); } - await pluginChannel.invokeMethod( - 'startVideoRecording', - { - 'cameraId': options.cameraId, - 'maxVideoDuration': options.maxDuration?.inMilliseconds, - }, - ); + // Currently none of `options` is supported on Windows, so it's not passed. + await _hostApi.startVideoRecording(options.cameraId); } @override Future stopVideoRecording(int cameraId) async { - final String? path; + final String path = await _hostApi.stopVideoRecording(cameraId); - path = await pluginChannel.invokeMethod( - 'stopVideoRecording', - {'cameraId': cameraId}, - ); - - return XFile(path!); + return XFile(path); } @override @@ -362,18 +319,12 @@ class CameraWindows extends CameraPlatform { @override Future pausePreview(int cameraId) async { - await pluginChannel.invokeMethod( - 'pausePreview', - {'cameraId': cameraId}, - ); + await _hostApi.pausePreview(cameraId); } @override Future resumePreview(int cameraId) async { - await pluginChannel.invokeMethod( - 'resumePreview', - {'cameraId': cameraId}, - ); + await _hostApi.resumePreview(cameraId); } @override @@ -381,76 +332,77 @@ class CameraWindows extends CameraPlatform { return Texture(textureId: cameraId); } - /// Returns the resolution preset as a nullable String. - String? _serializeResolutionPreset(ResolutionPreset? resolutionPreset) { + /// Returns a [MediaSettings]'s Pigeon representation. + PlatformMediaSettings _pigeonMediaSettings(MediaSettings? settings) { + return PlatformMediaSettings( + resolutionPreset: _pigeonResolutionPreset(settings?.resolutionPreset), + enableAudio: settings?.enableAudio ?? true, + framesPerSecond: settings?.fps, + videoBitrate: settings?.videoBitrate, + audioBitrate: settings?.audioBitrate, + ); + } + + /// Returns a [ResolutionPreset]'s Pigeon representation. + PlatformResolutionPreset _pigeonResolutionPreset( + ResolutionPreset? resolutionPreset) { + if (resolutionPreset == null) { + // Provide a default if one isn't provided, since the native side needs + // to set something. + return PlatformResolutionPreset.max; + } switch (resolutionPreset) { - case null: - return null; case ResolutionPreset.max: - return 'max'; + return PlatformResolutionPreset.max; case ResolutionPreset.ultraHigh: - return 'ultraHigh'; + return PlatformResolutionPreset.ultraHigh; case ResolutionPreset.veryHigh: - return 'veryHigh'; + return PlatformResolutionPreset.veryHigh; case ResolutionPreset.high: - return 'high'; + return PlatformResolutionPreset.high; case ResolutionPreset.medium: - return 'medium'; + return PlatformResolutionPreset.medium; case ResolutionPreset.low: - return 'low'; + return PlatformResolutionPreset.low; } + // The enum comes from a different package, which could get a new value at + // any time, so provide a fallback that ensures this won't break when used + // with a version that contains new values. This is deliberately outside + // the switch rather than a `default` so that the linter will flag the + // switch as needing an update. + // ignore: dead_code + return PlatformResolutionPreset.max; } +} - /// Converts messages received from the native platform into camera events. - /// - /// This is only exposed for test purposes. It shouldn't be used by clients - /// of the plugin as it may break or change at any time. - @visibleForTesting - Future handleCameraMethodCall(MethodCall call, int cameraId) async { - switch (call.method) { - case 'camera_closing': - cameraEventStreamController.add( - CameraClosingEvent( - cameraId, - ), - ); - case 'video_recorded': - final Map arguments = - (call.arguments as Map).cast(); - final int? maxDuration = arguments['maxVideoDuration'] as int?; - // This is called if maxVideoDuration was given on record start. - cameraEventStreamController.add( - VideoRecordedEvent( - cameraId, - XFile(arguments['path']! as String), - maxDuration != null ? Duration(milliseconds: maxDuration) : null, - ), - ); - case 'error': - final Map arguments = - (call.arguments as Map).cast(); - cameraEventStreamController.add( - CameraErrorEvent( - cameraId, - arguments['description']! as String, - ), - ); - default: - throw UnimplementedError(); - } +/// Callback handler for camera-level events from the platform host. +@visibleForTesting +class HostCameraMessageHandler implements CameraEventApi { + /// Creates a new handler that listens for events from camera [cameraId], and + /// broadcasts them to [streamController]. + HostCameraMessageHandler(this.cameraId, this.streamController) { + CameraEventApi.setUp(this, messageChannelSuffix: cameraId.toString()); } - /// Parses string presentation of the camera lens direction and returns enum value. - @visibleForTesting - CameraLensDirection parseCameraLensDirection(String string) { - switch (string) { - case 'front': - return CameraLensDirection.front; - case 'back': - return CameraLensDirection.back; - case 'external': - return CameraLensDirection.external; - } - throw ArgumentError('Unknown CameraLensDirection value'); + /// Removes the handler for native messages. + void dispose() { + CameraEventApi.setUp(null, messageChannelSuffix: cameraId.toString()); + } + + /// The camera ID this handler listens for events from. + final int cameraId; + + /// The controller used to broadcast camera events coming from the + /// host platform. + final StreamController streamController; + + @override + void error(String message) { + streamController.add(CameraErrorEvent(cameraId, message)); + } + + @override + void cameraClosing() { + streamController.add(CameraClosingEvent(cameraId)); } } diff --git a/packages/camera/camera_windows/lib/src/messages.g.dart b/packages/camera/camera_windows/lib/src/messages.g.dart new file mode 100644 index 000000000000..a351d6d9cee6 --- /dev/null +++ b/packages/camera/camera_windows/lib/src/messages.g.dart @@ -0,0 +1,485 @@ +// 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 (v22.6.0), 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 + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; + +import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/services.dart'; + +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); +} + +List wrapResponse( + {Object? result, PlatformException? error, bool empty = false}) { + if (empty) { + return []; + } + if (error == null) { + return [result]; + } + return [error.code, error.message, error.details]; +} + +/// Pigeon version of platform interface's ResolutionPreset. +enum PlatformResolutionPreset { + low, + medium, + high, + veryHigh, + ultraHigh, + max, +} + +/// Pigeon version of MediaSettings. +class PlatformMediaSettings { + PlatformMediaSettings({ + required this.resolutionPreset, + this.framesPerSecond, + this.videoBitrate, + this.audioBitrate, + required this.enableAudio, + }); + + PlatformResolutionPreset resolutionPreset; + + int? framesPerSecond; + + int? videoBitrate; + + int? audioBitrate; + + bool enableAudio; + + Object encode() { + return [ + resolutionPreset, + framesPerSecond, + videoBitrate, + audioBitrate, + enableAudio, + ]; + } + + static PlatformMediaSettings decode(Object result) { + result as List; + return PlatformMediaSettings( + resolutionPreset: result[0]! as PlatformResolutionPreset, + framesPerSecond: result[1] as int?, + videoBitrate: result[2] as int?, + audioBitrate: result[3] as int?, + enableAudio: result[4]! as bool, + ); + } +} + +/// A representation of a size from the native camera APIs. +class PlatformSize { + PlatformSize({ + required this.width, + required this.height, + }); + + double width; + + double height; + + Object encode() { + return [ + width, + height, + ]; + } + + static PlatformSize decode(Object result) { + result as List; + return PlatformSize( + width: result[0]! as double, + height: result[1]! as double, + ); + } +} + +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is PlatformResolutionPreset) { + buffer.putUint8(129); + writeValue(buffer, value.index); + } else if (value is PlatformMediaSettings) { + buffer.putUint8(130); + writeValue(buffer, value.encode()); + } else if (value is PlatformSize) { + buffer.putUint8(131); + writeValue(buffer, value.encode()); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 129: + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformResolutionPreset.values[value]; + case 130: + return PlatformMediaSettings.decode(readValue(buffer)!); + case 131: + return PlatformSize.decode(readValue(buffer)!); + default: + return super.readValueOfType(type, buffer); + } + } +} + +class CameraApi { + /// Constructor for [CameraApi]. 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. + CameraApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String pigeonVar_messageChannelSuffix; + + /// Returns the names of all of the available capture devices. + Future> getAvailableCameras() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_windows.CameraApi.getAvailableCameras$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as List?)!.cast(); + } + } + + /// Creates a camera instance for the given device name and settings. + Future create(String cameraName, PlatformMediaSettings settings) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_windows.CameraApi.create$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([cameraName, settings]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as int?)!; + } + } + + /// Initializes a camera, and returns the size of its preview. + Future initialize(int cameraId) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_windows.CameraApi.initialize$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([cameraId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as PlatformSize?)!; + } + } + + /// Disposes a camera that is no longer in use. + Future dispose(int cameraId) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_windows.CameraApi.dispose$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([cameraId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Takes a picture with the given camera, and returns the path to the + /// resulting file. + Future takePicture(int cameraId) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_windows.CameraApi.takePicture$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([cameraId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as String?)!; + } + } + + /// Starts recording video with the given camera. + Future startVideoRecording(int cameraId) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_windows.CameraApi.startVideoRecording$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([cameraId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Finishes recording video with the given camera, and returns the path to + /// the resulting file. + Future stopVideoRecording(int cameraId) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_windows.CameraApi.stopVideoRecording$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([cameraId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as String?)!; + } + } + + /// Starts the preview stream for the given camera. + Future pausePreview(int cameraId) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_windows.CameraApi.pausePreview$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([cameraId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Resumes the preview stream for the given camera. + Future resumePreview(int cameraId) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_windows.CameraApi.resumePreview$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([cameraId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } +} + +abstract class CameraEventApi { + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + /// Called when the camera instance is closing on the native side. + void cameraClosing(); + + /// Called when a camera error occurs on the native side. + void error(String errorMessage); + + static void setUp( + CameraEventApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.camera_windows.CameraEventApi.cameraClosing$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + try { + api.cameraClosing(); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.camera_windows.CameraEventApi.error$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.camera_windows.CameraEventApi.error was null.'); + final List args = (message as List?)!; + final String? arg_errorMessage = (args[0] as String?); + assert(arg_errorMessage != null, + 'Argument for dev.flutter.pigeon.camera_windows.CameraEventApi.error was null, expected non-null String.'); + try { + api.error(arg_errorMessage!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } +} diff --git a/packages/camera/camera_windows/pigeons/copyright.txt b/packages/camera/camera_windows/pigeons/copyright.txt new file mode 100644 index 000000000000..1236b63caf3a --- /dev/null +++ b/packages/camera/camera_windows/pigeons/copyright.txt @@ -0,0 +1,3 @@ +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. diff --git a/packages/camera/camera_windows/pigeons/messages.dart b/packages/camera/camera_windows/pigeons/messages.dart new file mode 100644 index 000000000000..cb70021a0ef1 --- /dev/null +++ b/packages/camera/camera_windows/pigeons/messages.dart @@ -0,0 +1,89 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:pigeon/pigeon.dart'; + +@ConfigurePigeon(PigeonOptions( + dartOut: 'lib/src/messages.g.dart', + cppOptions: CppOptions(namespace: 'camera_windows'), + cppHeaderOut: 'windows/messages.g.h', + cppSourceOut: 'windows/messages.g.cpp', + copyrightHeader: 'pigeons/copyright.txt', +)) + +/// Pigeon version of platform interface's ResolutionPreset. +enum PlatformResolutionPreset { low, medium, high, veryHigh, ultraHigh, max } + +/// Pigeon version of MediaSettings. +class PlatformMediaSettings { + PlatformMediaSettings({ + required this.resolutionPreset, + required this.framesPerSecond, + required this.videoBitrate, + required this.audioBitrate, + required this.enableAudio, + }); + + final PlatformResolutionPreset resolutionPreset; + final int? framesPerSecond; + final int? videoBitrate; + final int? audioBitrate; + final bool enableAudio; +} + +/// A representation of a size from the native camera APIs. +class PlatformSize { + PlatformSize({required this.width, required this.height}); + + final double width; + final double height; +} + +@HostApi() +abstract class CameraApi { + /// Returns the names of all of the available capture devices. + List getAvailableCameras(); + + /// Creates a camera instance for the given device name and settings. + @async + int create(String cameraName, PlatformMediaSettings settings); + + /// Initializes a camera, and returns the size of its preview. + @async + PlatformSize initialize(int cameraId); + + /// Disposes a camera that is no longer in use. + void dispose(int cameraId); + + /// Takes a picture with the given camera, and returns the path to the + /// resulting file. + @async + String takePicture(int cameraId); + + /// Starts recording video with the given camera. + @async + void startVideoRecording(int cameraId); + + /// Finishes recording video with the given camera, and returns the path to + /// the resulting file. + @async + String stopVideoRecording(int cameraId); + + /// Starts the preview stream for the given camera. + @async + void pausePreview(int cameraId); + + /// Resumes the preview stream for the given camera. + @async + void resumePreview(int cameraId); +} + +@FlutterApi() +abstract class CameraEventApi { + /// Called when the camera instance is closing on the native side. + void cameraClosing(); + + /// Called when a camera error occurs on the native side. + void error(String errorMessage); +} diff --git a/packages/camera/camera_windows/pubspec.yaml b/packages/camera/camera_windows/pubspec.yaml index 6fc2e8a9c7da..ae1336971a58 100644 --- a/packages/camera/camera_windows/pubspec.yaml +++ b/packages/camera/camera_windows/pubspec.yaml @@ -2,11 +2,11 @@ name: camera_windows description: A Flutter plugin for getting information about and controlling the camera on Windows. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_windows issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.2.2 +version: 0.2.6 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -25,8 +25,11 @@ dependencies: dev_dependencies: async: ^2.5.0 + build_runner: ^2.4.9 flutter_test: sdk: flutter + mockito: ^5.4.4 + pigeon: ^22.6.0 topics: - camera diff --git a/packages/camera/camera_windows/test/camera_windows_test.dart b/packages/camera/camera_windows/test/camera_windows_test.dart index 228cae2c952b..7d21af5f7824 100644 --- a/packages/camera/camera_windows/test/camera_windows_test.dart +++ b/packages/camera/camera_windows/test/camera_windows_test.dart @@ -5,14 +5,17 @@ import 'package:async/async.dart'; import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:camera_windows/camera_windows.dart'; +import 'package:camera_windows/src/messages.g.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; -import './utils/method_channel_mock.dart'; +import 'camera_windows_test.mocks.dart'; +@GenerateNiceMocks(>[MockSpec()]) void main() { - const String pluginChannelName = 'plugins.flutter.io/camera_windows'; TestWidgetsFlutterBinding.ensureInitialized(); group('$CameraWindows()', () { @@ -24,20 +27,15 @@ void main() { group('Creation, Initialization & Disposal Tests', () { test('Should send creation data and receive back a camera id', () async { // Arrange - final MethodChannelMock cameraMockChannel = MethodChannelMock( - channelName: pluginChannelName, - methods: { - 'create': { - 'cameraId': 1, - 'imageFormatGroup': 'unknown', - } - }); - final CameraWindows plugin = CameraWindows(); + final MockCameraApi mockApi = MockCameraApi(); + when(mockApi.create(any, any)).thenAnswer((_) async => 1); + final CameraWindows plugin = CameraWindows(api: mockApi); + const String cameraName = 'Test'; // Act final int cameraId = await plugin.createCameraWithSettings( const CameraDescription( - name: 'Test', + name: cameraName, lensDirection: CameraLensDirection.front, sensorOrientation: 0), const MediaSettings( @@ -49,19 +47,13 @@ void main() { ); // Assert - expect(cameraMockChannel.log, [ - isMethodCall( - 'create', - arguments: { - 'cameraName': 'Test', - 'resolutionPreset': 'low', - 'fps': 15, - 'videoBitrate': 200000, - 'audioBitrate': 32000, - 'enableAudio': false - }, - ), - ]); + final VerificationResult verification = + verify(mockApi.create(captureAny, captureAny)); + expect(verification.captured[0], cameraName); + final PlatformMediaSettings? settings = + verification.captured[1] as PlatformMediaSettings?; + expect(settings, isNotNull); + expect(settings?.resolutionPreset, PlatformResolutionPreset.low); expect(cameraId, 1); }); @@ -69,38 +61,31 @@ void main() { 'Should throw CameraException when create throws a PlatformException', () { // Arrange - MethodChannelMock( - channelName: pluginChannelName, - methods: { - 'create': PlatformException( - code: 'TESTING_ERROR_CODE', - message: 'Mock error message used during testing.', - ) - }); - final CameraWindows plugin = CameraWindows(); + const String exceptionCode = 'TESTING_ERROR_CODE'; + const String exceptionMessage = + 'Mock error message used during testing.'; + final MockCameraApi mockApi = MockCameraApi(); + when(mockApi.create(any, any)).thenAnswer((_) async { + throw PlatformException( + code: exceptionCode, message: exceptionMessage); + }); + final CameraWindows camera = CameraWindows(api: mockApi); // Act expect( - () => plugin.createCameraWithSettings( + () => camera.createCamera( const CameraDescription( name: 'Test', lensDirection: CameraLensDirection.back, sensorOrientation: 0, ), - const MediaSettings( - resolutionPreset: ResolutionPreset.low, - fps: 15, - videoBitrate: 200000, - audioBitrate: 32000, - enableAudio: true, - ), + ResolutionPreset.high, ), throwsA( isA() - .having( - (CameraException e) => e.code, 'code', 'TESTING_ERROR_CODE') + .having((CameraException e) => e.code, 'code', exceptionCode) .having((CameraException e) => e.description, 'description', - 'Mock error message used during testing.'), + exceptionMessage), ), ); }); @@ -109,16 +94,15 @@ void main() { 'Should throw CameraException when initialize throws a PlatformException', () { // Arrange - MethodChannelMock( - channelName: pluginChannelName, - methods: { - 'initialize': PlatformException( - code: 'TESTING_ERROR_CODE', - message: 'Mock error message used during testing.', - ) - }, - ); - final CameraWindows plugin = CameraWindows(); + const String exceptionCode = 'TESTING_ERROR_CODE'; + const String exceptionMessage = + 'Mock error message used during testing.'; + final MockCameraApi mockApi = MockCameraApi(); + when(mockApi.initialize(any)).thenAnswer((_) async { + throw PlatformException( + code: exceptionCode, message: exceptionMessage); + }); + final CameraWindows plugin = CameraWindows(api: mockApi); // Act expect( @@ -139,19 +123,10 @@ void main() { test('Should send initialization data', () async { // Arrange - final MethodChannelMock cameraMockChannel = MethodChannelMock( - channelName: pluginChannelName, - methods: { - 'create': { - 'cameraId': 1, - 'imageFormatGroup': 'unknown', - }, - 'initialize': { - 'previewWidth': 1920.toDouble(), - 'previewHeight': 1080.toDouble() - }, - }); - final CameraWindows plugin = CameraWindows(); + final MockCameraApi mockApi = MockCameraApi(); + when(mockApi.initialize(any)) + .thenAnswer((_) async => PlatformSize(width: 1920, height: 1080)); + final CameraWindows plugin = CameraWindows(api: mockApi); final int cameraId = await plugin.createCameraWithSettings( const CameraDescription( name: 'Test', @@ -171,30 +146,17 @@ void main() { await plugin.initializeCamera(cameraId); // Assert - expect(cameraId, 1); - expect(cameraMockChannel.log, [ - anything, - isMethodCall( - 'initialize', - arguments: {'cameraId': 1}, - ), - ]); + final VerificationResult verification = + verify(mockApi.initialize(captureAny)); + expect(verification.captured[0], cameraId); }); test('Should send a disposal call on dispose', () async { // Arrange - final MethodChannelMock cameraMockChannel = MethodChannelMock( - channelName: pluginChannelName, - methods: { - 'create': {'cameraId': 1}, - 'initialize': { - 'previewWidth': 1920.toDouble(), - 'previewHeight': 1080.toDouble() - }, - 'dispose': {'cameraId': 1} - }); - - final CameraWindows plugin = CameraWindows(); + final MockCameraApi mockApi = MockCameraApi(); + when(mockApi.initialize(any)) + .thenAnswer((_) async => PlatformSize(width: 1920, height: 1080)); + final CameraWindows plugin = CameraWindows(api: mockApi); final int cameraId = await plugin.createCameraWithSettings( const CameraDescription( name: 'Test', @@ -215,15 +177,9 @@ void main() { await plugin.dispose(cameraId); // Assert - expect(cameraId, 1); - expect(cameraMockChannel.log, [ - anything, - anything, - isMethodCall( - 'dispose', - arguments: {'cameraId': 1}, - ), - ]); + final VerificationResult verification = + verify(mockApi.dispose(captureAny)); + expect(verification.captured[0], cameraId); }); }); @@ -231,18 +187,11 @@ void main() { late CameraWindows plugin; late int cameraId; setUp(() async { - MethodChannelMock( - channelName: pluginChannelName, - methods: { - 'create': {'cameraId': 1}, - 'initialize': { - 'previewWidth': 1920.toDouble(), - 'previewHeight': 1080.toDouble() - }, - }, - ); - - plugin = CameraWindows(); + final MockCameraApi mockApi = MockCameraApi(); + when(mockApi.create(any, any)).thenAnswer((_) async => 1); + when(mockApi.initialize(any)) + .thenAnswer((_) async => PlatformSize(width: 1920, height: 1080)); + plugin = CameraWindows(api: mockApi); cameraId = await plugin.createCameraWithSettings( const CameraDescription( name: 'Test', @@ -269,12 +218,9 @@ void main() { // Emit test events final CameraClosingEvent event = CameraClosingEvent(cameraId); - await plugin.handleCameraMethodCall( - MethodCall('camera_closing', event.toJson()), cameraId); - await plugin.handleCameraMethodCall( - MethodCall('camera_closing', event.toJson()), cameraId); - await plugin.handleCameraMethodCall( - MethodCall('camera_closing', event.toJson()), cameraId); + plugin.hostCameraHandlers[cameraId]!.cameraClosing(); + plugin.hostCameraHandlers[cameraId]!.cameraClosing(); + plugin.hostCameraHandlers[cameraId]!.cameraClosing(); // Assert expect(await streamQueue.next, event); @@ -293,14 +239,11 @@ void main() { StreamQueue(errorStream); // Emit test events - final CameraErrorEvent event = - CameraErrorEvent(cameraId, 'Error Description'); - await plugin.handleCameraMethodCall( - MethodCall('error', event.toJson()), cameraId); - await plugin.handleCameraMethodCall( - MethodCall('error', event.toJson()), cameraId); - await plugin.handleCameraMethodCall( - MethodCall('error', event.toJson()), cameraId); + const String errorMessage = 'Error Description'; + final CameraErrorEvent event = CameraErrorEvent(cameraId, errorMessage); + plugin.hostCameraHandlers[cameraId]!.error(errorMessage); + plugin.hostCameraHandlers[cameraId]!.error(errorMessage); + plugin.hostCameraHandlers[cameraId]!.error(errorMessage); // Assert expect(await streamQueue.next, event); @@ -313,21 +256,16 @@ void main() { }); group('Function Tests', () { + late MockCameraApi mockApi; late CameraWindows plugin; late int cameraId; setUp(() async { - MethodChannelMock( - channelName: pluginChannelName, - methods: { - 'create': {'cameraId': 1}, - 'initialize': { - 'previewWidth': 1920.toDouble(), - 'previewHeight': 1080.toDouble() - }, - }, - ); - plugin = CameraWindows(); + mockApi = MockCameraApi(); + when(mockApi.create(any, any)).thenAnswer((_) async => 1); + when(mockApi.initialize(any)) + .thenAnswer((_) async => PlatformSize(width: 1920, height: 1080)); + plugin = CameraWindows(api: mockApi); cameraId = await plugin.createCameraWithSettings( const CameraDescription( name: 'Test', @@ -343,46 +281,29 @@ void main() { ), ); await plugin.initializeCamera(cameraId); + clearInteractions(mockApi); }); test('Should fetch CameraDescription instances for available cameras', () async { // Arrange - final List returnData = [ - { - 'name': 'Test 1', - 'lensFacing': 'front', - 'sensorOrientation': 1 - }, - { - 'name': 'Test 2', - 'lensFacing': 'back', - 'sensorOrientation': 2 - } + final List returnData = [ + 'Test 1', + 'Test 2', ]; - final MethodChannelMock channel = MethodChannelMock( - channelName: pluginChannelName, - methods: {'availableCameras': returnData}, - ); + when(mockApi.getAvailableCameras()).thenAnswer((_) async => returnData); // Act final List cameras = await plugin.availableCameras(); // Assert - expect(channel.log, [ - isMethodCall('availableCameras', arguments: null), - ]); expect(cameras.length, returnData.length); for (int i = 0; i < returnData.length; i++) { - final Map typedData = - (returnData[i] as Map).cast(); - final CameraDescription cameraDescription = CameraDescription( - name: typedData['name']! as String, - lensDirection: plugin - .parseCameraLensDirection(typedData['lensFacing']! as String), - sensorOrientation: typedData['sensorOrientation']! as int, - ); - expect(cameras[i], cameraDescription); + expect(cameras[i].name, returnData[i]); + // This value isn't provided by the platform, so is hard-coded to front. + expect(cameras[i].lensDirection, CameraLensDirection.front); + // This value isn't provided by the platform, so is hard-coded to 0. + expect(cameras[i].sensorOrientation, 0); } }); @@ -390,14 +311,10 @@ void main() { 'Should throw CameraException when availableCameras throws a PlatformException', () { // Arrange - MethodChannelMock( - channelName: pluginChannelName, - methods: { - 'availableCameras': PlatformException( - code: 'TESTING_ERROR_CODE', - message: 'Mock error message used during testing.', - ) - }); + const String code = 'TESTING_ERROR_CODE'; + const String message = 'Mock error message used during testing.'; + when(mockApi.getAvailableCameras()).thenAnswer( + (_) async => throw PlatformException(code: code, message: message)); // Act expect( @@ -414,78 +331,30 @@ void main() { test('Should take a picture and return an XFile instance', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: pluginChannelName, - methods: {'takePicture': '/test/path.jpg'}); + const String stubPath = '/test/path.jpg'; + when(mockApi.takePicture(any)).thenAnswer((_) async => stubPath); // Act final XFile file = await plugin.takePicture(cameraId); // Assert - expect(channel.log, [ - isMethodCall('takePicture', arguments: { - 'cameraId': cameraId, - }), - ]); expect(file.path, '/test/path.jpg'); }); - test('Should prepare for video recording', () async { - // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: pluginChannelName, - methods: {'prepareForVideoRecording': null}, - ); - + test('prepare for video recording should no-op', () async { // Act await plugin.prepareForVideoRecording(); // Assert - expect(channel.log, [ - isMethodCall('prepareForVideoRecording', arguments: null), - ]); + verifyNoMoreInteractions(mockApi); }); test('Should start recording a video', () async { - // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: pluginChannelName, - methods: {'startVideoRecording': null}, - ); - // Act await plugin.startVideoRecording(cameraId); // Assert - expect(channel.log, [ - isMethodCall('startVideoRecording', arguments: { - 'cameraId': cameraId, - 'maxVideoDuration': null, - }), - ]); - }); - - test('Should pass maxVideoDuration when starting recording a video', - () async { - // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: pluginChannelName, - methods: {'startVideoRecording': null}, - ); - - // Act - await plugin.startVideoRecording( - cameraId, - maxVideoDuration: const Duration(seconds: 10), - ); - - // Assert - expect(channel.log, [ - isMethodCall('startVideoRecording', arguments: { - 'cameraId': cameraId, - 'maxVideoDuration': 10000 - }), - ]); + verify(mockApi.startVideoRecording(any)); }); test('capturing fails if trying to stream', () async { @@ -499,20 +368,13 @@ void main() { test('Should stop a video recording and return the file', () async { // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: pluginChannelName, - methods: {'stopVideoRecording': '/test/path.mp4'}, - ); + const String stubPath = '/test/path.mp4'; + when(mockApi.stopVideoRecording(any)).thenAnswer((_) async => stubPath); // Act final XFile file = await plugin.stopVideoRecording(cameraId); // Assert - expect(channel.log, [ - isMethodCall('stopVideoRecording', arguments: { - 'cameraId': cameraId, - }), - ]); expect(file.path, '/test/path.mp4'); }); @@ -623,15 +485,6 @@ void main() { expect((widget as Texture).textureId, cameraId); }); - test('Should throw UnimplementedError when handling unknown method', () { - final CameraWindows plugin = CameraWindows(); - - expect( - () => plugin.handleCameraMethodCall( - const MethodCall('unknown_method'), 1), - throwsA(isA())); - }); - test('Should get the max zoom level', () async { // Act final double maxZoomLevel = await plugin.getMaxZoomLevel(cameraId); @@ -677,37 +530,23 @@ void main() { }); test('Should pause the camera preview', () async { - // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: pluginChannelName, - methods: {'pausePreview': null}, - ); - // Act await plugin.pausePreview(cameraId); // Assert - expect(channel.log, [ - isMethodCall('pausePreview', - arguments: {'cameraId': cameraId}), - ]); + final VerificationResult verification = + verify(mockApi.pausePreview(captureAny)); + expect(verification.captured[0], cameraId); }); test('Should resume the camera preview', () async { - // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: pluginChannelName, - methods: {'resumePreview': null}, - ); - // Act await plugin.resumePreview(cameraId); // Assert - expect(channel.log, [ - isMethodCall('resumePreview', - arguments: {'cameraId': cameraId}), - ]); + final VerificationResult verification = + verify(mockApi.resumePreview(captureAny)); + expect(verification.captured[0], cameraId); }); }); }); diff --git a/packages/camera/camera_windows/test/camera_windows_test.mocks.dart b/packages/camera/camera_windows/test/camera_windows_test.mocks.dart new file mode 100644 index 000000000000..7e22e1739188 --- /dev/null +++ b/packages/camera/camera_windows/test/camera_windows_test.mocks.dart @@ -0,0 +1,207 @@ +// Mocks generated by Mockito 5.4.4 from annotations +// in camera_windows/test/camera_windows_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i4; + +import 'package:camera_windows/src/messages.g.dart' as _i2; +import 'package:mockito/mockito.dart' as _i1; +import 'package:mockito/src/dummies.dart' as _i3; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakePlatformSize_0 extends _i1.SmartFake implements _i2.PlatformSize { + _FakePlatformSize_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [CameraApi]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockCameraApi extends _i1.Mock implements _i2.CameraApi { + @override + String get pigeonVar_messageChannelSuffix => (super.noSuchMethod( + Invocation.getter(#pigeonVar_messageChannelSuffix), + returnValue: _i3.dummyValue( + this, + Invocation.getter(#pigeonVar_messageChannelSuffix), + ), + returnValueForMissingStub: _i3.dummyValue( + this, + Invocation.getter(#pigeonVar_messageChannelSuffix), + ), + ) as String); + + @override + _i4.Future> getAvailableCameras() => (super.noSuchMethod( + Invocation.method( + #getAvailableCameras, + [], + ), + returnValue: _i4.Future>.value([]), + returnValueForMissingStub: _i4.Future>.value([]), + ) as _i4.Future>); + + @override + _i4.Future create( + String? cameraName, + _i2.PlatformMediaSettings? settings, + ) => + (super.noSuchMethod( + Invocation.method( + #create, + [ + cameraName, + settings, + ], + ), + returnValue: _i4.Future.value(0), + returnValueForMissingStub: _i4.Future.value(0), + ) as _i4.Future); + + @override + _i4.Future<_i2.PlatformSize> initialize(int? cameraId) => (super.noSuchMethod( + Invocation.method( + #initialize, + [cameraId], + ), + returnValue: _i4.Future<_i2.PlatformSize>.value(_FakePlatformSize_0( + this, + Invocation.method( + #initialize, + [cameraId], + ), + )), + returnValueForMissingStub: + _i4.Future<_i2.PlatformSize>.value(_FakePlatformSize_0( + this, + Invocation.method( + #initialize, + [cameraId], + ), + )), + ) as _i4.Future<_i2.PlatformSize>); + + @override + _i4.Future dispose(int? cameraId) => (super.noSuchMethod( + Invocation.method( + #dispose, + [cameraId], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future takePicture(int? cameraId) => (super.noSuchMethod( + Invocation.method( + #takePicture, + [cameraId], + ), + returnValue: _i4.Future.value(_i3.dummyValue( + this, + Invocation.method( + #takePicture, + [cameraId], + ), + )), + returnValueForMissingStub: + _i4.Future.value(_i3.dummyValue( + this, + Invocation.method( + #takePicture, + [cameraId], + ), + )), + ) as _i4.Future); + + @override + _i4.Future startVideoRecording(int? cameraId) => (super.noSuchMethod( + Invocation.method( + #startVideoRecording, + [cameraId], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future stopVideoRecording(int? cameraId) => (super.noSuchMethod( + Invocation.method( + #stopVideoRecording, + [cameraId], + ), + returnValue: _i4.Future.value(_i3.dummyValue( + this, + Invocation.method( + #stopVideoRecording, + [cameraId], + ), + )), + returnValueForMissingStub: + _i4.Future.value(_i3.dummyValue( + this, + Invocation.method( + #stopVideoRecording, + [cameraId], + ), + )), + ) as _i4.Future); + + @override + _i4.Future startImageStream(int? cameraId) => (super.noSuchMethod( + Invocation.method( + #startImageStream, + [cameraId], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future stopImageStream(int? cameraId) => (super.noSuchMethod( + Invocation.method( + #stopImageStream, + [cameraId], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future pausePreview(int? cameraId) => (super.noSuchMethod( + Invocation.method( + #pausePreview, + [cameraId], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future resumePreview(int? cameraId) => (super.noSuchMethod( + Invocation.method( + #resumePreview, + [cameraId], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); +} diff --git a/packages/camera/camera_windows/test/utils/method_channel_mock.dart b/packages/camera/camera_windows/test/utils/method_channel_mock.dart deleted file mode 100644 index 357eec370bc1..000000000000 --- a/packages/camera/camera_windows/test/utils/method_channel_mock.dart +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart'; - -/// A mock [MethodChannel] implementation for use in tests. -class MethodChannelMock { - /// Creates a new instance with the specified channel name. - /// - /// This method channel will handle all method invocations specified by - /// returning the value mapped to the method name key. If a delay is - /// specified, results are returned after the delay has elapsed. - MethodChannelMock({ - required String channelName, - this.delay, - required this.methods, - }) : methodChannel = MethodChannel(channelName) { - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(methodChannel, _handler); - } - - final Duration? delay; - final MethodChannel methodChannel; - final Map methods; - final List log = []; - - Future _handler(MethodCall methodCall) async { - log.add(methodCall); - - if (!methods.containsKey(methodCall.method)) { - throw MissingPluginException('No TEST implementation found for method ' - '${methodCall.method} on channel ${methodChannel.name}'); - } - - return Future.delayed(delay ?? Duration.zero, () { - final dynamic result = methods[methodCall.method]; - if (result is Exception) { - throw result; - } - - return Future.value(result); - }); - } -} diff --git a/packages/camera/camera_windows/windows/CMakeLists.txt b/packages/camera/camera_windows/windows/CMakeLists.txt index 534372fd31b0..e209a22ec0fe 100644 --- a/packages/camera/camera_windows/windows/CMakeLists.txt +++ b/packages/camera/camera_windows/windows/CMakeLists.txt @@ -22,6 +22,8 @@ list(APPEND PLUGIN_SOURCES "string_utils.cpp" "capture_device_info.h" "capture_device_info.cpp" + "messages.g.h" + "messages.g.cpp" "preview_handler.h" "preview_handler.cpp" "record_handler.h" diff --git a/packages/camera/camera_windows/windows/camera.cpp b/packages/camera/camera_windows/windows/camera.cpp index 94a0ed89ac46..13bf3b3efae3 100644 --- a/packages/camera/camera_windows/windows/camera.cpp +++ b/packages/camera/camera_windows/windows/camera.cpp @@ -5,16 +5,6 @@ #include "camera.h" namespace camera_windows { -using flutter::EncodableList; -using flutter::EncodableMap; -using flutter::EncodableValue; - -// Camera channel events. -constexpr char kCameraMethodChannelBaseName[] = - "plugins.flutter.io/camera_windows/camera"; -constexpr char kVideoRecordedEvent[] = "video_recorded"; -constexpr char kCameraClosingEvent[] = "camera_closing"; -constexpr char kErrorEvent[] = "error"; // Camera error codes constexpr char kCameraAccessDenied[] = "CameraAccessDenied"; @@ -49,34 +39,63 @@ CameraImpl::~CameraImpl() { bool CameraImpl::InitCamera(flutter::TextureRegistrar* texture_registrar, flutter::BinaryMessenger* messenger, - ResolutionPreset resolution_preset, - const RecordSettings& record_settings) { + const PlatformMediaSettings& media_settings) { auto capture_controller_factory = std::make_unique(); return InitCamera(std::move(capture_controller_factory), texture_registrar, - messenger, resolution_preset, record_settings); + messenger, media_settings); } bool CameraImpl::InitCamera( std::unique_ptr capture_controller_factory, flutter::TextureRegistrar* texture_registrar, - flutter::BinaryMessenger* messenger, ResolutionPreset resolution_preset, - const RecordSettings& record_settings) { + flutter::BinaryMessenger* messenger, + const PlatformMediaSettings& media_settings) { assert(!device_id_.empty()); messenger_ = messenger; capture_controller_ = capture_controller_factory->CreateCaptureController(this); - return capture_controller_->InitCaptureDevice( - texture_registrar, device_id_, resolution_preset, record_settings); + return capture_controller_->InitCaptureDevice(texture_registrar, device_id_, + media_settings); +} + +bool CameraImpl::AddPendingVoidResult( + PendingResultType type, + std::function reply)> result) { + assert(result); + return AddPendingResult(type, result); +} + +bool CameraImpl::AddPendingIntResult( + PendingResultType type, + std::function reply)> result) { + assert(result); + return AddPendingResult(type, result); +} + +bool CameraImpl::AddPendingStringResult( + PendingResultType type, + std::function reply)> result) { + assert(result); + return AddPendingResult(type, result); } -bool CameraImpl::AddPendingResult( - PendingResultType type, std::unique_ptr> result) { +bool CameraImpl::AddPendingSizeResult( + PendingResultType type, + std::function reply)> result) { assert(result); + return AddPendingResult(type, result); +} +bool CameraImpl::AddPendingResult(PendingResultType type, + CameraImpl::AsyncResult result) { auto it = pending_results_.find(type); if (it != pending_results_.end()) { - result->Error("Duplicate request", "Method handler already called"); + std::visit( + [](auto&& r) { + r(FlutterError("Duplicate request", "Method handler already called")); + }, + result); return false; } @@ -84,204 +103,219 @@ bool CameraImpl::AddPendingResult( return true; } -std::unique_ptr> CameraImpl::GetPendingResultByType( +std::function reply)> +CameraImpl::GetPendingVoidResultByType(PendingResultType type) { + std::optional result = GetPendingResultByType(type); + if (!result) { + return nullptr; + } + return std::get)>>( + result.value()); +} + +std::function reply)> +CameraImpl::GetPendingIntResultByType(PendingResultType type) { + std::optional result = GetPendingResultByType(type); + if (!result) { + return nullptr; + } + return std::get)>>(result.value()); +} + +std::function reply)> +CameraImpl::GetPendingStringResultByType(PendingResultType type) { + std::optional result = GetPendingResultByType(type); + if (!result) { + return nullptr; + } + return std::get)>>(result.value()); +} + +std::function reply)> +CameraImpl::GetPendingSizeResultByType(PendingResultType type) { + std::optional result = GetPendingResultByType(type); + if (!result) { + return nullptr; + } + return std::get)>>(result.value()); +} + +std::optional CameraImpl::GetPendingResultByType( PendingResultType type) { auto it = pending_results_.find(type); if (it == pending_results_.end()) { - return nullptr; + return std::nullopt; } - auto result = std::move(it->second); + CameraImpl::AsyncResult result = std::move(it->second); pending_results_.erase(it); return result; } bool CameraImpl::HasPendingResultByType(PendingResultType type) const { auto it = pending_results_.find(type); - if (it == pending_results_.end()) { - return false; - } - return it->second != nullptr; + return it != pending_results_.end(); } void CameraImpl::SendErrorForPendingResults(const std::string& error_code, const std::string& description) { for (const auto& pending_result : pending_results_) { - pending_result.second->Error(error_code, description); + std::visit( + [&error_code, &description](auto&& result) { + result(FlutterError(error_code, description)); + }, + pending_result.second); } pending_results_.clear(); } -MethodChannel<>* CameraImpl::GetMethodChannel() { +CameraEventApi* CameraImpl::GetEventApi() { assert(messenger_); assert(camera_id_); - // Use existing channel if initialized - if (camera_channel_) { - return camera_channel_.get(); + if (!event_api_) { + std::string suffix = std::to_string(camera_id_); + event_api_ = std::make_unique(messenger_, suffix); } - auto channel_name = - std::string(kCameraMethodChannelBaseName) + std::to_string(camera_id_); - - camera_channel_ = std::make_unique>( - messenger_, channel_name, &flutter::StandardMethodCodec::GetInstance()); - - return camera_channel_.get(); + return event_api_.get(); } void CameraImpl::OnCreateCaptureEngineSucceeded(int64_t texture_id) { // Use texture id as camera id camera_id_ = texture_id; auto pending_result = - GetPendingResultByType(PendingResultType::kCreateCamera); + GetPendingIntResultByType(PendingResultType::kCreateCamera); if (pending_result) { - pending_result->Success(EncodableMap( - {{EncodableValue("cameraId"), EncodableValue(texture_id)}})); + pending_result(texture_id); } } void CameraImpl::OnCreateCaptureEngineFailed(CameraResult result, const std::string& error) { auto pending_result = - GetPendingResultByType(PendingResultType::kCreateCamera); + GetPendingIntResultByType(PendingResultType::kCreateCamera); if (pending_result) { std::string error_code = GetErrorCode(result); - pending_result->Error(error_code, error); + pending_result(FlutterError(error_code, error)); } } void CameraImpl::OnStartPreviewSucceeded(int32_t width, int32_t height) { - auto pending_result = GetPendingResultByType(PendingResultType::kInitialize); + auto pending_result = + GetPendingSizeResultByType(PendingResultType::kInitialize); if (pending_result) { - pending_result->Success(EncodableValue(EncodableMap({ - {EncodableValue("previewWidth"), - EncodableValue(static_cast(width))}, - {EncodableValue("previewHeight"), - EncodableValue(static_cast(height))}, - }))); + pending_result( + PlatformSize(static_cast(width), static_cast(height))); } }; void CameraImpl::OnStartPreviewFailed(CameraResult result, const std::string& error) { - auto pending_result = GetPendingResultByType(PendingResultType::kInitialize); + auto pending_result = + GetPendingSizeResultByType(PendingResultType::kInitialize); if (pending_result) { std::string error_code = GetErrorCode(result); - pending_result->Error(error_code, error); + pending_result(FlutterError(error_code, error)); } }; void CameraImpl::OnResumePreviewSucceeded() { auto pending_result = - GetPendingResultByType(PendingResultType::kResumePreview); + GetPendingVoidResultByType(PendingResultType::kResumePreview); if (pending_result) { - pending_result->Success(); + pending_result(std::nullopt); } } void CameraImpl::OnResumePreviewFailed(CameraResult result, const std::string& error) { auto pending_result = - GetPendingResultByType(PendingResultType::kResumePreview); + GetPendingVoidResultByType(PendingResultType::kResumePreview); if (pending_result) { std::string error_code = GetErrorCode(result); - pending_result->Error(error_code, error); + pending_result(FlutterError(error_code, error)); } } void CameraImpl::OnPausePreviewSucceeded() { auto pending_result = - GetPendingResultByType(PendingResultType::kPausePreview); + GetPendingVoidResultByType(PendingResultType::kPausePreview); if (pending_result) { - pending_result->Success(); + pending_result(std::nullopt); } } void CameraImpl::OnPausePreviewFailed(CameraResult result, const std::string& error) { auto pending_result = - GetPendingResultByType(PendingResultType::kPausePreview); + GetPendingVoidResultByType(PendingResultType::kPausePreview); if (pending_result) { std::string error_code = GetErrorCode(result); - pending_result->Error(error_code, error); + pending_result(FlutterError(error_code, error)); } } void CameraImpl::OnStartRecordSucceeded() { - auto pending_result = GetPendingResultByType(PendingResultType::kStartRecord); + auto pending_result = + GetPendingVoidResultByType(PendingResultType::kStartRecord); if (pending_result) { - pending_result->Success(); + pending_result(std::nullopt); } }; void CameraImpl::OnStartRecordFailed(CameraResult result, const std::string& error) { - auto pending_result = GetPendingResultByType(PendingResultType::kStartRecord); + auto pending_result = + GetPendingVoidResultByType(PendingResultType::kStartRecord); if (pending_result) { std::string error_code = GetErrorCode(result); - pending_result->Error(error_code, error); + pending_result(FlutterError(error_code, error)); } }; void CameraImpl::OnStopRecordSucceeded(const std::string& file_path) { - auto pending_result = GetPendingResultByType(PendingResultType::kStopRecord); + auto pending_result = + GetPendingStringResultByType(PendingResultType::kStopRecord); if (pending_result) { - pending_result->Success(EncodableValue(file_path)); + pending_result(file_path); } }; void CameraImpl::OnStopRecordFailed(CameraResult result, const std::string& error) { - auto pending_result = GetPendingResultByType(PendingResultType::kStopRecord); + auto pending_result = + GetPendingStringResultByType(PendingResultType::kStopRecord); if (pending_result) { std::string error_code = GetErrorCode(result); - pending_result->Error(error_code, error); + pending_result(FlutterError(error_code, error)); } }; void CameraImpl::OnTakePictureSucceeded(const std::string& file_path) { - auto pending_result = GetPendingResultByType(PendingResultType::kTakePicture); + auto pending_result = + GetPendingStringResultByType(PendingResultType::kTakePicture); if (pending_result) { - pending_result->Success(EncodableValue(file_path)); + pending_result(file_path); } }; void CameraImpl::OnTakePictureFailed(CameraResult result, const std::string& error) { auto pending_take_picture_result = - GetPendingResultByType(PendingResultType::kTakePicture); + GetPendingStringResultByType(PendingResultType::kTakePicture); if (pending_take_picture_result) { std::string error_code = GetErrorCode(result); - pending_take_picture_result->Error(error_code, error); + pending_take_picture_result(FlutterError(error_code, error)); } }; -void CameraImpl::OnVideoRecordSucceeded(const std::string& file_path, - int64_t video_duration_ms) { - if (messenger_ && camera_id_ >= 0) { - auto channel = GetMethodChannel(); - - std::unique_ptr message_data = - std::make_unique( - EncodableMap({{EncodableValue("path"), EncodableValue(file_path)}, - {EncodableValue("maxVideoDuration"), - EncodableValue(video_duration_ms)}})); - - channel->InvokeMethod(kVideoRecordedEvent, std::move(message_data)); - } -} - -void CameraImpl::OnVideoRecordFailed(CameraResult result, - const std::string& error){}; - void CameraImpl::OnCaptureError(CameraResult result, const std::string& error) { if (messenger_ && camera_id_ >= 0) { - auto channel = GetMethodChannel(); - - std::unique_ptr message_data = - std::make_unique(EncodableMap( - {{EncodableValue("description"), EncodableValue(error)}})); - channel->InvokeMethod(kErrorEvent, std::move(message_data)); + GetEventApi()->Error( + error, + // TODO(stuartmorgan): Replace with an event channel, since that's how + // these calls are used. Given that use case, ignore responses. + []() {}, [](const FlutterError& error) {}); } std::string error_code = GetErrorCode(result); @@ -290,9 +324,9 @@ void CameraImpl::OnCaptureError(CameraResult result, const std::string& error) { void CameraImpl::OnCameraClosing() { if (messenger_ && camera_id_ >= 0) { - auto channel = GetMethodChannel(); - channel->InvokeMethod(kCameraClosingEvent, - std::move(std::make_unique())); + // TODO(stuartmorgan): Replace with an event channel, since that's how + // these calls are used. Given that use case, ignore responses. + GetEventApi()->CameraClosing([]() {}, [](const FlutterError& error) {}); } } diff --git a/packages/camera/camera_windows/windows/camera.h b/packages/camera/camera_windows/windows/camera.h index 50ec6a75e74b..44e9fcde5883 100644 --- a/packages/camera/camera_windows/windows/camera.h +++ b/packages/camera/camera_windows/windows/camera.h @@ -5,20 +5,15 @@ #ifndef PACKAGES_CAMERA_CAMERA_WINDOWS_WINDOWS_CAMERA_H_ #define PACKAGES_CAMERA_CAMERA_WINDOWS_WINDOWS_CAMERA_H_ -#include -#include - #include #include +#include #include "capture_controller.h" +#include "messages.g.h" namespace camera_windows { -using flutter::EncodableMap; -using flutter::MethodChannel; -using flutter::MethodResult; - // A set of result types that are stored // for processing asynchronous commands. enum class PendingResultType { @@ -50,11 +45,33 @@ class Camera : public CaptureControllerListener { // Tests if this camera has the specified camera ID. virtual bool HasCameraId(int64_t camera_id) const = 0; - // Adds a pending result. + // Adds a pending result for a void return. + // + // Returns an error result if the result has already been added. + virtual bool AddPendingVoidResult( + PendingResultType type, + std::function reply)> result) = 0; + + // Adds a pending result for a string return. + // + // Returns an error result if the result has already been added. + virtual bool AddPendingIntResult( + PendingResultType type, + std::function reply)> result) = 0; + + // Adds a pending result for a string return. // // Returns an error result if the result has already been added. - virtual bool AddPendingResult(PendingResultType type, - std::unique_ptr> result) = 0; + virtual bool AddPendingStringResult( + PendingResultType type, + std::function reply)> result) = 0; + + // Adds a pending result for a size return. + // + // Returns an error result if the result has already been added. + virtual bool AddPendingSizeResult( + PendingResultType type, + std::function reply)> result) = 0; // Checks if a pending result of the specified type already exists. virtual bool HasPendingResultByType(PendingResultType type) const = 0; @@ -68,8 +85,7 @@ class Camera : public CaptureControllerListener { // Returns false if initialization fails. virtual bool InitCamera(flutter::TextureRegistrar* texture_registrar, flutter::BinaryMessenger* messenger, - ResolutionPreset resolution_preset, - const RecordSettings& record_settings) = 0; + const PlatformMediaSettings& media_settings) = 0; }; // Concrete implementation of the |Camera| interface. @@ -108,10 +124,6 @@ class CameraImpl : public Camera { void OnTakePictureSucceeded(const std::string& file_path) override; void OnTakePictureFailed(CameraResult result, const std::string& error) override; - void OnVideoRecordSucceeded(const std::string& file_path, - int64_t video_duration) override; - void OnVideoRecordFailed(CameraResult result, - const std::string& error) override; void OnCaptureError(CameraResult result, const std::string& error) override; // Camera @@ -121,16 +133,25 @@ class CameraImpl : public Camera { bool HasCameraId(int64_t camera_id) const override { return camera_id_ == camera_id; } - bool AddPendingResult(PendingResultType type, - std::unique_ptr> result) override; + bool AddPendingVoidResult( + PendingResultType type, + std::function reply)> result) override; + bool AddPendingIntResult( + PendingResultType type, + std::function reply)> result) override; + bool AddPendingStringResult( + PendingResultType type, + std::function reply)> result) override; + bool AddPendingSizeResult( + PendingResultType type, + std::function reply)> result) override; bool HasPendingResultByType(PendingResultType type) const override; camera_windows::CaptureController* GetCaptureController() override { return capture_controller_.get(); } bool InitCamera(flutter::TextureRegistrar* texture_registrar, flutter::BinaryMessenger* messenger, - ResolutionPreset resolution_preset, - const RecordSettings& record_settings) override; + const PlatformMediaSettings& media_settings) override; // Initializes the camera and its associated capture controller. // @@ -141,10 +162,17 @@ class CameraImpl : public Camera { bool InitCamera( std::unique_ptr capture_controller_factory, flutter::TextureRegistrar* texture_registrar, - flutter::BinaryMessenger* messenger, ResolutionPreset resolution_preset, - const RecordSettings& record_settings); + flutter::BinaryMessenger* messenger, + const PlatformMediaSettings& media_settings); private: + // A generic type for any pending asyncronous result. + using AsyncResult = + std::variant reply)>, + std::function reply)>, + std::function reply)>, + std::function reply)>>; + // Loops through all pending results and calls their error handler with given // error ID and description. Pending results are cleared in the process. // @@ -157,17 +185,50 @@ class CameraImpl : public Camera { // Sends camera closing message to the cameras method channel. void OnCameraClosing(); - // Initializes method channel instance and returns pointer it. - MethodChannel<>* GetMethodChannel(); + // Returns the FlutterApi instance used to communicate camera events. + CameraEventApi* GetEventApi(); - // Finds pending result by type. - // Returns nullptr if type is not present. - std::unique_ptr> GetPendingResultByType( + // Finds pending void result by type. + // + // Returns an empty function if type is not present. + std::function reply)> + GetPendingVoidResultByType(PendingResultType type); + + // Finds pending int result by type. + // + // Returns an empty function if type is not present. + std::function reply)> GetPendingIntResultByType( + PendingResultType type); + + // Finds pending string result by type. + // + // Returns an empty function if type is not present. + std::function reply)> GetPendingStringResultByType( + PendingResultType type); + + // Finds pending size result by type. + // + // Returns an empty function if type is not present. + std::function reply)> GetPendingSizeResultByType( PendingResultType type); - std::map>> pending_results_; + // Finds pending result by type. + // + // Returns a nullopt if type is not present. + // + // This should not be used directly in most code, it's just a helper for the + // typed versions above. + std::optional GetPendingResultByType(PendingResultType type); + + // Adds pending result by type. + // + // This should not be used directly in most code, it's just a helper for the + // typed versions in the public interface. + bool AddPendingResult(PendingResultType type, AsyncResult result); + + std::map pending_results_; std::unique_ptr capture_controller_; - std::unique_ptr> camera_channel_; + std::unique_ptr event_api_; flutter::BinaryMessenger* messenger_ = nullptr; int64_t camera_id_ = -1; std::string device_id_; diff --git a/packages/camera/camera_windows/windows/camera_plugin.cpp b/packages/camera/camera_windows/windows/camera_plugin.cpp index c99565dd49c8..089aa28c7222 100644 --- a/packages/camera/camera_windows/windows/camera_plugin.cpp +++ b/packages/camera/camera_windows/windows/camera_plugin.cpp @@ -20,6 +20,7 @@ #include "capture_device_info.h" #include "com_heap_ptr.h" +#include "messages.g.h" #include "string_utils.h" namespace camera_windows { @@ -29,86 +30,9 @@ using flutter::EncodableValue; namespace { -// Channel events -constexpr char kChannelName[] = "plugins.flutter.io/camera_windows"; - -constexpr char kAvailableCamerasMethod[] = "availableCameras"; -constexpr char kCreateMethod[] = "create"; -constexpr char kInitializeMethod[] = "initialize"; -constexpr char kTakePictureMethod[] = "takePicture"; -constexpr char kStartVideoRecordingMethod[] = "startVideoRecording"; -constexpr char kStopVideoRecordingMethod[] = "stopVideoRecording"; -constexpr char kPausePreview[] = "pausePreview"; -constexpr char kResumePreview[] = "resumePreview"; -constexpr char kDisposeMethod[] = "dispose"; - -constexpr char kCameraNameKey[] = "cameraName"; -constexpr char kResolutionPresetKey[] = "resolutionPreset"; -constexpr char kFpsKey[] = "fps"; -constexpr char kVideoBitrateKey[] = "videoBitrate"; -constexpr char kAudioBitrateKey[] = "audioBitrate"; -constexpr char kEnableAudioKey[] = "enableAudio"; - -constexpr char kCameraIdKey[] = "cameraId"; -constexpr char kMaxVideoDurationKey[] = "maxVideoDuration"; - -constexpr char kResolutionPresetValueLow[] = "low"; -constexpr char kResolutionPresetValueMedium[] = "medium"; -constexpr char kResolutionPresetValueHigh[] = "high"; -constexpr char kResolutionPresetValueVeryHigh[] = "veryHigh"; -constexpr char kResolutionPresetValueUltraHigh[] = "ultraHigh"; -constexpr char kResolutionPresetValueMax[] = "max"; - const std::string kPictureCaptureExtension = "jpeg"; const std::string kVideoCaptureExtension = "mp4"; -// Looks for |key| in |map|, returning the associated value if it is present, or -// a nullptr if not. -const EncodableValue* ValueOrNull(const EncodableMap& map, const char* key) { - auto it = map.find(EncodableValue(key)); - if (it == map.end()) { - return nullptr; - } - return &(it->second); -} - -// Looks for |key| in |map|, returning the associated int64 value if it is -// present, or std::nullopt if not. -std::optional GetInt64ValueOrNull(const EncodableMap& map, - const char* key) { - auto value = ValueOrNull(map, key); - if (!value) { - return std::nullopt; - } - - if (std::holds_alternative(*value)) { - return static_cast(std::get(*value)); - } - auto val64 = std::get_if(value); - if (!val64) { - return std::nullopt; - } - return *val64; -} - -// Parses resolution preset argument to enum value. -ResolutionPreset ParseResolutionPreset(const std::string& resolution_preset) { - if (resolution_preset.compare(kResolutionPresetValueLow) == 0) { - return ResolutionPreset::kLow; - } else if (resolution_preset.compare(kResolutionPresetValueMedium) == 0) { - return ResolutionPreset::kMedium; - } else if (resolution_preset.compare(kResolutionPresetValueHigh) == 0) { - return ResolutionPreset::kHigh; - } else if (resolution_preset.compare(kResolutionPresetValueVeryHigh) == 0) { - return ResolutionPreset::kVeryHigh; - } else if (resolution_preset.compare(kResolutionPresetValueUltraHigh) == 0) { - return ResolutionPreset::kUltraHigh; - } else if (resolution_preset.compare(kResolutionPresetValueMax) == 0) { - return ResolutionPreset::kMax; - } - return ResolutionPreset::kAuto; -} - // Builds CaptureDeviceInfo object from given device holding device name and id. std::unique_ptr GetDeviceInfo(IMFActivate* device) { assert(device); @@ -195,17 +119,10 @@ std::optional GetFilePathForVideo() { // static void CameraPlugin::RegisterWithRegistrar( flutter::PluginRegistrarWindows* registrar) { - auto channel = std::make_unique>( - registrar->messenger(), kChannelName, - &flutter::StandardMethodCodec::GetInstance()); - std::unique_ptr plugin = std::make_unique( registrar->texture_registrar(), registrar->messenger()); - channel->SetMethodCallHandler( - [plugin_pointer = plugin.get()](const auto& call, auto result) { - plugin_pointer->HandleMethodCall(call, std::move(result)); - }); + CameraApi::SetUp(registrar->messenger(), plugin.get()); registrar->AddPlugin(std::move(plugin)); } @@ -225,66 +142,6 @@ CameraPlugin::CameraPlugin(flutter::TextureRegistrar* texture_registrar, CameraPlugin::~CameraPlugin() {} -void CameraPlugin::HandleMethodCall( - const flutter::MethodCall<>& method_call, - std::unique_ptr> result) { - const std::string& method_name = method_call.method_name(); - - if (method_name.compare(kAvailableCamerasMethod) == 0) { - return AvailableCamerasMethodHandler(std::move(result)); - } else if (method_name.compare(kCreateMethod) == 0) { - const auto* arguments = - std::get_if(method_call.arguments()); - assert(arguments); - - return CreateMethodHandler(*arguments, std::move(result)); - } else if (method_name.compare(kInitializeMethod) == 0) { - const auto* arguments = - std::get_if(method_call.arguments()); - assert(arguments); - - return this->InitializeMethodHandler(*arguments, std::move(result)); - } else if (method_name.compare(kTakePictureMethod) == 0) { - const auto* arguments = - std::get_if(method_call.arguments()); - assert(arguments); - - return TakePictureMethodHandler(*arguments, std::move(result)); - } else if (method_name.compare(kStartVideoRecordingMethod) == 0) { - const auto* arguments = - std::get_if(method_call.arguments()); - assert(arguments); - - return StartVideoRecordingMethodHandler(*arguments, std::move(result)); - } else if (method_name.compare(kStopVideoRecordingMethod) == 0) { - const auto* arguments = - std::get_if(method_call.arguments()); - assert(arguments); - - return StopVideoRecordingMethodHandler(*arguments, std::move(result)); - } else if (method_name.compare(kPausePreview) == 0) { - const auto* arguments = - std::get_if(method_call.arguments()); - assert(arguments); - - return PausePreviewMethodHandler(*arguments, std::move(result)); - } else if (method_name.compare(kResumePreview) == 0) { - const auto* arguments = - std::get_if(method_call.arguments()); - assert(arguments); - - return ResumePreviewMethodHandler(*arguments, std::move(result)); - } else if (method_name.compare(kDisposeMethod) == 0) { - const auto* arguments = - std::get_if(method_call.arguments()); - assert(arguments); - - return DisposeMethodHandler(*arguments, std::move(result)); - } else { - result->NotImplemented(); - } -} - Camera* CameraPlugin::GetCameraByDeviceId(std::string& device_id) { for (auto it = begin(cameras_); it != end(cameras_); ++it) { if ((*it)->HasDeviceId(device_id)) { @@ -312,20 +169,13 @@ void CameraPlugin::DisposeCameraByCameraId(int64_t camera_id) { } } -void CameraPlugin::AvailableCamerasMethodHandler( - std::unique_ptr> result) { +ErrorOr CameraPlugin::GetAvailableCameras() { // Enumerate devices. ComHeapPtr devices; UINT32 count = 0; if (!this->EnumerateVideoCaptureDeviceSources(&devices, &count)) { - result->Error("System error", "Failed to get available cameras"); - // No need to free devices here, cos allocation failed. - return; - } - - if (count == 0) { - result->Success(EncodableValue(EncodableList())); - return; + // No need to free devices here, since allocation failed. + return FlutterError("System error", "Failed to get available cameras"); } // Format found devices to the response. @@ -334,14 +184,10 @@ void CameraPlugin::AvailableCamerasMethodHandler( auto device_info = GetDeviceInfo(devices[i]); auto deviceName = device_info->GetUniqueDeviceName(); - devices_list.push_back(EncodableMap({ - {EncodableValue("name"), EncodableValue(deviceName)}, - {EncodableValue("lensFacing"), EncodableValue("front")}, - {EncodableValue("sensorOrientation"), EncodableValue(0)}, - })); + devices_list.push_back(EncodableValue(deviceName)); } - result->Success(std::move(EncodableValue(devices_list))); + return devices_list; } bool CameraPlugin::EnumerateVideoCaptureDeviceSources(IMFActivate*** devices, @@ -350,267 +196,180 @@ bool CameraPlugin::EnumerateVideoCaptureDeviceSources(IMFActivate*** devices, count); } -void CameraPlugin::CreateMethodHandler( - const EncodableMap& args, std::unique_ptr> result) { - // Parse enableAudio argument. - const auto* record_audio = - std::get_if(ValueOrNull(args, kEnableAudioKey)); - if (!record_audio) { - return result->Error("argument_error", - std::string(kEnableAudioKey) + " argument missing"); - } - - // Parse cameraName argument. - const auto* camera_name = - std::get_if(ValueOrNull(args, kCameraNameKey)); - if (!camera_name) { - return result->Error("argument_error", - std::string(kCameraNameKey) + " argument missing"); - } - +void CameraPlugin::Create(const std::string& camera_name, + const PlatformMediaSettings& settings, + std::function reply)> result) { auto device_info = std::make_unique(); - if (!device_info->ParseDeviceInfoFromCameraName(*camera_name)) { - return result->Error( - "camera_error", "Cannot parse argument " + std::string(kCameraNameKey)); + if (!device_info->ParseDeviceInfoFromCameraName(camera_name)) { + return result(FlutterError("camera_error", + "Cannot parse device info from " + camera_name)); } auto device_id = device_info->GetDeviceId(); if (GetCameraByDeviceId(device_id)) { - return result->Error("camera_error", - "Camera with given device id already exists. Existing " - "camera must be disposed before creating it again."); + return result( + FlutterError("camera_error", + "Camera with given device id already exists. Existing " + "camera must be disposed before creating it again.")); } std::unique_ptr camera = camera_factory_->CreateCamera(device_id); if (camera->HasPendingResultByType(PendingResultType::kCreateCamera)) { - return result->Error("camera_error", - "Pending camera creation request exists"); - } - - if (camera->AddPendingResult(PendingResultType::kCreateCamera, - std::move(result))) { - // Parse resolution preset argument. - const auto* resolution_preset_argument = - std::get_if(ValueOrNull(args, kResolutionPresetKey)); - ResolutionPreset resolution_preset; - if (resolution_preset_argument) { - resolution_preset = ParseResolutionPreset(*resolution_preset_argument); - } else { - resolution_preset = ResolutionPreset::kAuto; - } + return result( + FlutterError("camera_error", "Pending camera creation request exists")); + } - const auto* fps_argument = std::get_if(ValueOrNull(args, kFpsKey)); - const auto* video_bitrate_argument = - std::get_if(ValueOrNull(args, kVideoBitrateKey)); - const auto* audio_bitrate_argument = - std::get_if(ValueOrNull(args, kAudioBitrateKey)); - - RecordSettings record_settings; - record_settings.record_audio = *record_audio; - record_settings.fps = - fps_argument ? std::make_optional(*fps_argument) : std::nullopt; - record_settings.video_bitrate = - video_bitrate_argument ? std::make_optional(*video_bitrate_argument) - : std::nullopt; - record_settings.audio_bitrate = - audio_bitrate_argument ? std::make_optional(*audio_bitrate_argument) - : std::nullopt; - - bool initialized = camera->InitCamera(texture_registrar_, messenger_, - resolution_preset, record_settings); + if (camera->AddPendingIntResult(PendingResultType::kCreateCamera, + std::move(result))) { + bool initialized = + camera->InitCamera(texture_registrar_, messenger_, settings); if (initialized) { cameras_.push_back(std::move(camera)); } } } -void CameraPlugin::InitializeMethodHandler( - const EncodableMap& args, std::unique_ptr> result) { - auto camera_id = GetInt64ValueOrNull(args, kCameraIdKey); - if (!camera_id) { - return result->Error("argument_error", - std::string(kCameraIdKey) + " missing"); - } - - auto camera = GetCameraByCameraId(*camera_id); +void CameraPlugin::Initialize( + int64_t camera_id, + std::function reply)> result) { + auto camera = GetCameraByCameraId(camera_id); if (!camera) { - return result->Error("camera_error", "Camera not created"); + return result(FlutterError("camera_error", "Camera not created")); } if (camera->HasPendingResultByType(PendingResultType::kInitialize)) { - return result->Error("camera_error", - "Pending initialization request exists"); + return result( + FlutterError("camera_error", "Pending initialization request exists")); } - if (camera->AddPendingResult(PendingResultType::kInitialize, - std::move(result))) { + if (camera->AddPendingSizeResult(PendingResultType::kInitialize, + std::move(result))) { auto cc = camera->GetCaptureController(); assert(cc); cc->StartPreview(); } } -void CameraPlugin::PausePreviewMethodHandler( - const EncodableMap& args, std::unique_ptr> result) { - auto camera_id = GetInt64ValueOrNull(args, kCameraIdKey); - if (!camera_id) { - return result->Error("argument_error", - std::string(kCameraIdKey) + " missing"); - } - - auto camera = GetCameraByCameraId(*camera_id); +void CameraPlugin::PausePreview( + int64_t camera_id, + std::function reply)> result) { + auto camera = GetCameraByCameraId(camera_id); if (!camera) { - return result->Error("camera_error", "Camera not created"); + return result(FlutterError("camera_error", "Camera not created")); } if (camera->HasPendingResultByType(PendingResultType::kPausePreview)) { - return result->Error("camera_error", - "Pending pause preview request exists"); + return result( + FlutterError("camera_error", "Pending pause preview request exists")); } - if (camera->AddPendingResult(PendingResultType::kPausePreview, - std::move(result))) { + if (camera->AddPendingVoidResult(PendingResultType::kPausePreview, + std::move(result))) { auto cc = camera->GetCaptureController(); assert(cc); cc->PausePreview(); } } -void CameraPlugin::ResumePreviewMethodHandler( - const EncodableMap& args, std::unique_ptr> result) { - auto camera_id = GetInt64ValueOrNull(args, kCameraIdKey); - if (!camera_id) { - return result->Error("argument_error", - std::string(kCameraIdKey) + " missing"); - } - - auto camera = GetCameraByCameraId(*camera_id); +void CameraPlugin::ResumePreview( + int64_t camera_id, + std::function reply)> result) { + auto camera = GetCameraByCameraId(camera_id); if (!camera) { - return result->Error("camera_error", "Camera not created"); + return result(FlutterError("camera_error", "Camera not created")); } if (camera->HasPendingResultByType(PendingResultType::kResumePreview)) { - return result->Error("camera_error", - "Pending resume preview request exists"); + return result( + FlutterError("camera_error", "Pending resume preview request exists")); } - if (camera->AddPendingResult(PendingResultType::kResumePreview, - std::move(result))) { + if (camera->AddPendingVoidResult(PendingResultType::kResumePreview, + std::move(result))) { auto cc = camera->GetCaptureController(); assert(cc); cc->ResumePreview(); } } -void CameraPlugin::StartVideoRecordingMethodHandler( - const EncodableMap& args, std::unique_ptr> result) { - auto camera_id = GetInt64ValueOrNull(args, kCameraIdKey); - if (!camera_id) { - return result->Error("argument_error", - std::string(kCameraIdKey) + " missing"); - } - - auto camera = GetCameraByCameraId(*camera_id); +void CameraPlugin::StartVideoRecording( + int64_t camera_id, + std::function reply)> result) { + auto camera = GetCameraByCameraId(camera_id); if (!camera) { - return result->Error("camera_error", "Camera not created"); + return result(FlutterError("camera_error", "Camera not created")); } if (camera->HasPendingResultByType(PendingResultType::kStartRecord)) { - return result->Error("camera_error", - "Pending start recording request exists"); - } - - int64_t max_video_duration_ms = -1; - auto requested_max_video_duration_ms = - std::get_if(ValueOrNull(args, kMaxVideoDurationKey)); - - if (requested_max_video_duration_ms != nullptr) { - max_video_duration_ms = *requested_max_video_duration_ms; + return result( + FlutterError("camera_error", "Pending start recording request exists")); } std::optional path = GetFilePathForVideo(); if (path) { - if (camera->AddPendingResult(PendingResultType::kStartRecord, - std::move(result))) { + if (camera->AddPendingVoidResult(PendingResultType::kStartRecord, + std::move(result))) { auto cc = camera->GetCaptureController(); assert(cc); - cc->StartRecord(*path, max_video_duration_ms); + cc->StartRecord(*path); } } else { - return result->Error("system_error", - "Failed to get path for video capture"); + return result( + FlutterError("system_error", "Failed to get path for video capture")); } } -void CameraPlugin::StopVideoRecordingMethodHandler( - const EncodableMap& args, std::unique_ptr> result) { - auto camera_id = GetInt64ValueOrNull(args, kCameraIdKey); - if (!camera_id) { - return result->Error("argument_error", - std::string(kCameraIdKey) + " missing"); - } - - auto camera = GetCameraByCameraId(*camera_id); +void CameraPlugin::StopVideoRecording( + int64_t camera_id, std::function reply)> result) { + auto camera = GetCameraByCameraId(camera_id); if (!camera) { - return result->Error("camera_error", "Camera not created"); + return result(FlutterError("camera_error", "Camera not created")); } if (camera->HasPendingResultByType(PendingResultType::kStopRecord)) { - return result->Error("camera_error", - "Pending stop recording request exists"); + return result( + FlutterError("camera_error", "Pending stop recording request exists")); } - if (camera->AddPendingResult(PendingResultType::kStopRecord, - std::move(result))) { + if (camera->AddPendingStringResult(PendingResultType::kStopRecord, + std::move(result))) { auto cc = camera->GetCaptureController(); assert(cc); cc->StopRecord(); } } -void CameraPlugin::TakePictureMethodHandler( - const EncodableMap& args, std::unique_ptr> result) { - auto camera_id = GetInt64ValueOrNull(args, kCameraIdKey); - if (!camera_id) { - return result->Error("argument_error", - std::string(kCameraIdKey) + " missing"); - } - - auto camera = GetCameraByCameraId(*camera_id); +void CameraPlugin::TakePicture( + int64_t camera_id, std::function reply)> result) { + auto camera = GetCameraByCameraId(camera_id); if (!camera) { - return result->Error("camera_error", "Camera not created"); + return result(FlutterError("camera_error", "Camera not created")); } if (camera->HasPendingResultByType(PendingResultType::kTakePicture)) { - return result->Error("camera_error", "Pending take picture request exists"); + return result( + FlutterError("camera_error", "Pending take picture request exists")); } std::optional path = GetFilePathForPicture(); if (path) { - if (camera->AddPendingResult(PendingResultType::kTakePicture, - std::move(result))) { + if (camera->AddPendingStringResult(PendingResultType::kTakePicture, + std::move(result))) { auto cc = camera->GetCaptureController(); assert(cc); cc->TakePicture(*path); } } else { - return result->Error("system_error", - "Failed to get capture path for picture"); + return result( + FlutterError("system_error", "Failed to get capture path for picture")); } } -void CameraPlugin::DisposeMethodHandler( - const EncodableMap& args, std::unique_ptr> result) { - auto camera_id = GetInt64ValueOrNull(args, kCameraIdKey); - if (!camera_id) { - return result->Error("argument_error", - std::string(kCameraIdKey) + " missing"); - } - - DisposeCameraByCameraId(*camera_id); - result->Success(); +std::optional CameraPlugin::Dispose(int64_t camera_id) { + DisposeCameraByCameraId(camera_id); + return std::nullopt; } } // namespace camera_windows diff --git a/packages/camera/camera_windows/windows/camera_plugin.h b/packages/camera/camera_windows/windows/camera_plugin.h index 1baa2477beb5..422f5c92b365 100644 --- a/packages/camera/camera_windows/windows/camera_plugin.h +++ b/packages/camera/camera_windows/windows/camera_plugin.h @@ -15,6 +15,7 @@ #include "camera.h" #include "capture_controller.h" #include "capture_controller_listener.h" +#include "messages.g.h" namespace camera_windows { using flutter::MethodResult; @@ -27,6 +28,7 @@ class MockCameraPlugin; } // namespace test class CameraPlugin : public flutter::Plugin, + public CameraApi, public VideoCaptureDeviceEnumerator { public: static void RegisterWithRegistrar(flutter::PluginRegistrarWindows* registrar); @@ -46,9 +48,30 @@ class CameraPlugin : public flutter::Plugin, CameraPlugin(const CameraPlugin&) = delete; CameraPlugin& operator=(const CameraPlugin&) = delete; - // Called when a method is called on plugin channel. - void HandleMethodCall(const flutter::MethodCall<>& method_call, - std::unique_ptr> result); + // CameraApi: + ErrorOr GetAvailableCameras() override; + void Create(const std::string& camera_name, + const PlatformMediaSettings& settings, + std::function reply)> result) override; + void Initialize( + int64_t camera_id, + std::function reply)> result) override; + void PausePreview( + int64_t camera_id, + std::function reply)> result) override; + void ResumePreview( + int64_t camera_id, + std::function reply)> result) override; + void StartVideoRecording( + int64_t camera_id, + std::function reply)> result) override; + void StopVideoRecording( + int64_t camera_id, + std::function reply)> result) override; + void TakePicture( + int64_t camera_id, + std::function reply)> result) override; + std::optional Dispose(int64_t camera_id) override; private: // Loops through cameras and returns camera @@ -66,59 +89,6 @@ class CameraPlugin : public flutter::Plugin, bool EnumerateVideoCaptureDeviceSources(IMFActivate*** devices, UINT32* count) override; - // Handles availableCameras method calls. - // Enumerates video capture devices and - // returns list of available camera devices. - void AvailableCamerasMethodHandler( - std::unique_ptr> result); - - // Handles create method calls. - // Creates camera and initializes capture controller for requested device. - // Stores result object to be handled after request is processed. - void CreateMethodHandler(const EncodableMap& args, - std::unique_ptr> result); - - // Handles initialize method calls. - // Requests existing camera controller to start preview. - // Stores result object to be handled after request is processed. - void InitializeMethodHandler(const EncodableMap& args, - std::unique_ptr> result); - - // Handles takePicture method calls. - // Requests existing camera controller to take photo. - // Stores result object to be handled after request is processed. - void TakePictureMethodHandler(const EncodableMap& args, - std::unique_ptr> result); - - // Handles startVideoRecording method calls. - // Requests existing camera controller to start recording. - // Stores result object to be handled after request is processed. - void StartVideoRecordingMethodHandler(const EncodableMap& args, - std::unique_ptr> result); - - // Handles stopVideoRecording method calls. - // Requests existing camera controller to stop recording. - // Stores result object to be handled after request is processed. - void StopVideoRecordingMethodHandler(const EncodableMap& args, - std::unique_ptr> result); - - // Handles pausePreview method calls. - // Requests existing camera controller to pause recording. - // Stores result object to be handled after request is processed. - void PausePreviewMethodHandler(const EncodableMap& args, - std::unique_ptr> result); - - // Handles resumePreview method calls. - // Requests existing camera controller to resume preview. - // Stores result object to be handled after request is processed. - void ResumePreviewMethodHandler(const EncodableMap& args, - std::unique_ptr> result); - - // Handles dsipose method calls. - // Disposes camera if exists. - void DisposeMethodHandler(const EncodableMap& args, - std::unique_ptr> result); - std::unique_ptr camera_factory_; flutter::TextureRegistrar* texture_registrar_; flutter::BinaryMessenger* messenger_; diff --git a/packages/camera/camera_windows/windows/capture_controller.cpp b/packages/camera/camera_windows/windows/capture_controller.cpp index 0c06f69a4a4a..44df84374374 100644 --- a/packages/camera/camera_windows/windows/capture_controller.cpp +++ b/packages/camera/camera_windows/windows/capture_controller.cpp @@ -33,7 +33,10 @@ CameraResult GetCameraResult(HRESULT hr) { CaptureControllerImpl::CaptureControllerImpl( CaptureControllerListener* listener) - : capture_controller_listener_(listener), CaptureController(){}; + : capture_controller_listener_(listener), + media_settings_( + PlatformMediaSettings(PlatformResolutionPreset::kMax, true)), + CaptureController() {} CaptureControllerImpl::~CaptureControllerImpl() { ResetCaptureController(); @@ -217,7 +220,7 @@ HRESULT CaptureControllerImpl::CreateCaptureEngine() { } // Creates audio source only if not already initialized by test framework - if (media_settings_.record_audio && !audio_source_) { + if (media_settings_.enable_audio() && !audio_source_) { hr = CreateDefaultAudioCaptureSource(); if (FAILED(hr)) { return hr; @@ -241,7 +244,7 @@ HRESULT CaptureControllerImpl::CreateCaptureEngine() { } hr = attributes->SetUINT32(MF_CAPTURE_ENGINE_USE_VIDEO_DEVICE_ONLY, - !media_settings_.record_audio); + !media_settings_.enable_audio()); if (FAILED(hr)) { return hr; } @@ -256,11 +259,7 @@ HRESULT CaptureControllerImpl::CreateCaptureEngine() { void CaptureControllerImpl::ResetCaptureController() { if (record_handler_ && record_handler_->CanStop()) { - if (record_handler_->IsContinuousRecording()) { - StopRecord(); - } else if (record_handler_->IsTimedRecording()) { - StopTimedRecord(); - } + StopRecord(); } if (preview_handler_) { @@ -301,7 +300,7 @@ void CaptureControllerImpl::ResetCaptureController() { bool CaptureControllerImpl::InitCaptureDevice( flutter::TextureRegistrar* texture_registrar, const std::string& device_id, - ResolutionPreset resolution_preset, const RecordSettings& record_settings) { + const PlatformMediaSettings& media_settings) { assert(capture_controller_listener_); if (IsInitialized()) { @@ -315,8 +314,7 @@ bool CaptureControllerImpl::InitCaptureDevice( } capture_engine_state_ = CaptureEngineState::kInitializing; - resolution_preset_ = resolution_preset; - media_settings_ = record_settings; + media_settings_ = media_settings; texture_registrar_ = texture_registrar; video_device_id_ = device_id; @@ -382,28 +380,21 @@ void CaptureControllerImpl::TakePicture(const std::string& file_path) { } uint32_t CaptureControllerImpl::GetMaxPreviewHeight() const { - switch (resolution_preset_) { - case ResolutionPreset::kLow: + switch (media_settings_.resolution_preset()) { + case PlatformResolutionPreset::kLow: return 240; - break; - case ResolutionPreset::kMedium: + case PlatformResolutionPreset::kMedium: return 480; - break; - case ResolutionPreset::kHigh: + case PlatformResolutionPreset::kHigh: return 720; - break; - case ResolutionPreset::kVeryHigh: + case PlatformResolutionPreset::kVeryHigh: return 1080; - break; - case ResolutionPreset::kUltraHigh: + case PlatformResolutionPreset::kUltraHigh: return 2160; - break; - case ResolutionPreset::kMax: - case ResolutionPreset::kAuto: + case PlatformResolutionPreset::kMax: default: // no limit. return 0xffffffff; - break; } } @@ -496,8 +487,7 @@ HRESULT CaptureControllerImpl::FindBaseMediaTypes() { return S_OK; } -void CaptureControllerImpl::StartRecord(const std::string& file_path, - int64_t max_video_duration_ms) { +void CaptureControllerImpl::StartRecord(const std::string& file_path) { assert(capture_engine_); if (!IsInitialized()) { @@ -528,8 +518,7 @@ void CaptureControllerImpl::StartRecord(const std::string& file_path, // Check MF_CAPTURE_ENGINE_RECORD_STARTED event handling for response // process. - hr = record_handler_->StartRecord(file_path, max_video_duration_ms, - capture_engine_.Get(), + hr = record_handler_->StartRecord(file_path, capture_engine_.Get(), base_capture_media_type_.Get()); if (FAILED(hr)) { // Destroy record handler on error cases to make sure state is resetted. @@ -562,23 +551,6 @@ void CaptureControllerImpl::StopRecord() { } } -// Stops timed recording. Called internally when requested time is passed. -// Check MF_CAPTURE_ENGINE_RECORD_STOPPED event handling for response process. -void CaptureControllerImpl::StopTimedRecord() { - assert(capture_controller_listener_); - if (!record_handler_ || !record_handler_->IsTimedRecording()) { - return; - } - - HRESULT hr = record_handler_->StopRecord(capture_engine_.Get()); - if (FAILED(hr)) { - // Destroy record handler on error cases to make sure state is resetted. - record_handler_ = nullptr; - return capture_controller_listener_->OnVideoRecordFailed( - GetCameraResult(hr), "Failed to record video"); - } -} - // Starts capturing preview frames using preview handler // After first frame is captured, OnPreviewStarted is called void CaptureControllerImpl::StartPreview() { @@ -850,15 +822,8 @@ void CaptureControllerImpl::OnRecordStopped(CameraResult result, if (result == CameraResult::kSuccess) { std::string path = record_handler_->GetRecordPath(); capture_controller_listener_->OnStopRecordSucceeded(path); - if (record_handler_->IsTimedRecording()) { - capture_controller_listener_->OnVideoRecordSucceeded( - path, (record_handler_->GetRecordedDuration() / 1000)); - } } else { capture_controller_listener_->OnStopRecordFailed(result, error); - if (record_handler_->IsTimedRecording()) { - capture_controller_listener_->OnVideoRecordFailed(result, error); - } } } @@ -882,7 +847,6 @@ bool CaptureControllerImpl::UpdateBuffer(uint8_t* buffer, } // Handles capture time update from each processed frame. -// Stops timed recordings if requested recording duration has passed. // Called via IMFCaptureEngineOnSampleCallback implementation. // Implements CaptureEngineObserver::UpdateCaptureTime. void CaptureControllerImpl::UpdateCaptureTime(uint64_t capture_time_us) { @@ -895,14 +859,6 @@ void CaptureControllerImpl::UpdateCaptureTime(uint64_t capture_time_us) { // started. OnPreviewStarted(CameraResult::kSuccess, ""); } - - // Checks if max_video_duration_ms is passed. - if (record_handler_) { - record_handler_->UpdateRecordingTime(capture_time_us); - if (record_handler_->ShouldStopTimedRecording()) { - StopTimedRecord(); - } - } } } // namespace camera_windows diff --git a/packages/camera/camera_windows/windows/capture_controller.h b/packages/camera/camera_windows/windows/capture_controller.h index c6807002e589..8dd541421f74 100644 --- a/packages/camera/camera_windows/windows/capture_controller.h +++ b/packages/camera/camera_windows/windows/capture_controller.h @@ -20,6 +20,7 @@ #include "capture_controller_listener.h" #include "capture_engine_listener.h" +#include "messages.g.h" #include "photo_handler.h" #include "preview_handler.h" #include "record_handler.h" @@ -29,24 +30,6 @@ namespace camera_windows { using flutter::TextureRegistrar; using Microsoft::WRL::ComPtr; -// Camera resolution presets. Used to request a capture resolution. -enum class ResolutionPreset { - // Automatic resolution, uses the highest resolution available. - kAuto, - // 240p (320x240) - kLow, - // 480p (720x480) - kMedium, - // 720p (1280x720) - kHigh, - // 1080p (1920x1080) - kVeryHigh, - // 2160p (4096x2160) - kUltraHigh, - // The highest resolution available. - kMax, -}; - // Camera capture engine state. // // On creation, |CaptureControllers| start in state |kNotInitialized|. @@ -83,13 +66,10 @@ class CaptureController { // register texture for capture preview. // device_id: A string that holds information of camera device id to // be captured. - // record_audio: A boolean value telling if audio should be captured on - // video recording. - // resolution_preset: Maximum capture resolution height. - virtual bool InitCaptureDevice(TextureRegistrar* texture_registrar, - const std::string& device_id, - ResolutionPreset resolution_preset, - const RecordSettings& record_settings) = 0; + // media_settings: Settings controlling capture behavior. + virtual bool InitCaptureDevice( + TextureRegistrar* texture_registrar, const std::string& device_id, + const PlatformMediaSettings& media_settings) = 0; // Returns preview frame width virtual uint32_t GetPreviewWidth() const = 0; @@ -107,8 +87,7 @@ class CaptureController { virtual void ResumePreview() = 0; // Starts recording video. - virtual void StartRecord(const std::string& file_path, - int64_t max_video_duration_ms) = 0; + virtual void StartRecord(const std::string& file_path) = 0; // Stops the current video recording. virtual void StopRecord() = 0; @@ -138,15 +117,13 @@ class CaptureControllerImpl : public CaptureController, // CaptureController bool InitCaptureDevice(TextureRegistrar* texture_registrar, const std::string& device_id, - ResolutionPreset resolution_preset, - const RecordSettings& record_settings) override; + const PlatformMediaSettings& media_settings) override; uint32_t GetPreviewWidth() const override { return preview_frame_width_; } uint32_t GetPreviewHeight() const override { return preview_frame_height_; } void StartPreview() override; void PausePreview() override; void ResumePreview() override; - void StartRecord(const std::string& file_path, - int64_t max_video_duration_ms) override; + void StartRecord(const std::string& file_path) override; void StopRecord() override; void TakePicture(const std::string& file_path) override; @@ -204,10 +181,6 @@ class CaptureControllerImpl : public CaptureController, // for preview and video capture. HRESULT FindBaseMediaTypes(); - // Stops timed video record. Called internally when record handler when max - // recording time is exceeded. - void StopTimedRecord(); - // Stops preview. Called internally on camera reset and dispose. HRESULT StopPreview(); @@ -247,8 +220,7 @@ class CaptureControllerImpl : public CaptureController, std::string video_device_id_; CaptureEngineState capture_engine_state_ = CaptureEngineState::kNotInitialized; - ResolutionPreset resolution_preset_ = ResolutionPreset::kMedium; - RecordSettings media_settings_; + PlatformMediaSettings media_settings_; ComPtr capture_engine_; ComPtr capture_engine_callback_handler_; ComPtr dxgi_device_manager_; diff --git a/packages/camera/camera_windows/windows/capture_controller_listener.h b/packages/camera/camera_windows/windows/capture_controller_listener.h index bc7a173925a8..4567f52edc78 100644 --- a/packages/camera/camera_windows/windows/capture_controller_listener.h +++ b/packages/camera/camera_windows/windows/capture_controller_listener.h @@ -106,20 +106,6 @@ class CaptureControllerListener { virtual void OnTakePictureFailed(CameraResult result, const std::string& error) = 0; - // Called by CaptureController when timed recording is successfully recorded. - // - // file_path: Filesystem path of the captured image. - // video_duration: Duration of recorded video in milliseconds. - virtual void OnVideoRecordSucceeded(const std::string& file_path, - int64_t video_duration_ms) = 0; - - // Called by CaptureController if timed recording fails. - // - // result: The kind of result. - // error: A string describing the error. - virtual void OnVideoRecordFailed(CameraResult result, - const std::string& error) = 0; - // Called by CaptureController if capture engine returns error. // For example when camera is disconnected while on use. // diff --git a/packages/camera/camera_windows/windows/messages.g.cpp b/packages/camera/camera_windows/windows/messages.g.cpp new file mode 100644 index 000000000000..541ca97d0182 --- /dev/null +++ b/packages/camera/camera_windows/windows/messages.g.cpp @@ -0,0 +1,671 @@ +// 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 (v22.6.0), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +#undef _HAS_EXCEPTIONS + +#include "messages.g.h" + +#include +#include +#include +#include + +#include +#include +#include + +namespace camera_windows { +using flutter::BasicMessageChannel; +using flutter::CustomEncodableValue; +using flutter::EncodableList; +using flutter::EncodableMap; +using flutter::EncodableValue; + +FlutterError CreateConnectionError(const std::string channel_name) { + return FlutterError( + "channel-error", + "Unable to establish connection on channel: '" + channel_name + "'.", + EncodableValue("")); +} + +// PlatformMediaSettings + +PlatformMediaSettings::PlatformMediaSettings( + const PlatformResolutionPreset& resolution_preset, bool enable_audio) + : resolution_preset_(resolution_preset), enable_audio_(enable_audio) {} + +PlatformMediaSettings::PlatformMediaSettings( + const PlatformResolutionPreset& resolution_preset, + const int64_t* frames_per_second, const int64_t* video_bitrate, + const int64_t* audio_bitrate, bool enable_audio) + : resolution_preset_(resolution_preset), + frames_per_second_(frames_per_second + ? std::optional(*frames_per_second) + : std::nullopt), + video_bitrate_(video_bitrate ? std::optional(*video_bitrate) + : std::nullopt), + audio_bitrate_(audio_bitrate ? std::optional(*audio_bitrate) + : std::nullopt), + enable_audio_(enable_audio) {} + +const PlatformResolutionPreset& PlatformMediaSettings::resolution_preset() + const { + return resolution_preset_; +} + +void PlatformMediaSettings::set_resolution_preset( + const PlatformResolutionPreset& value_arg) { + resolution_preset_ = value_arg; +} + +const int64_t* PlatformMediaSettings::frames_per_second() const { + return frames_per_second_ ? &(*frames_per_second_) : nullptr; +} + +void PlatformMediaSettings::set_frames_per_second(const int64_t* value_arg) { + frames_per_second_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void PlatformMediaSettings::set_frames_per_second(int64_t value_arg) { + frames_per_second_ = value_arg; +} + +const int64_t* PlatformMediaSettings::video_bitrate() const { + return video_bitrate_ ? &(*video_bitrate_) : nullptr; +} + +void PlatformMediaSettings::set_video_bitrate(const int64_t* value_arg) { + video_bitrate_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void PlatformMediaSettings::set_video_bitrate(int64_t value_arg) { + video_bitrate_ = value_arg; +} + +const int64_t* PlatformMediaSettings::audio_bitrate() const { + return audio_bitrate_ ? &(*audio_bitrate_) : nullptr; +} + +void PlatformMediaSettings::set_audio_bitrate(const int64_t* value_arg) { + audio_bitrate_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void PlatformMediaSettings::set_audio_bitrate(int64_t value_arg) { + audio_bitrate_ = value_arg; +} + +bool PlatformMediaSettings::enable_audio() const { return enable_audio_; } + +void PlatformMediaSettings::set_enable_audio(bool value_arg) { + enable_audio_ = value_arg; +} + +EncodableList PlatformMediaSettings::ToEncodableList() const { + EncodableList list; + list.reserve(5); + list.push_back(CustomEncodableValue(resolution_preset_)); + list.push_back(frames_per_second_ ? EncodableValue(*frames_per_second_) + : EncodableValue()); + list.push_back(video_bitrate_ ? EncodableValue(*video_bitrate_) + : EncodableValue()); + list.push_back(audio_bitrate_ ? EncodableValue(*audio_bitrate_) + : EncodableValue()); + list.push_back(EncodableValue(enable_audio_)); + return list; +} + +PlatformMediaSettings PlatformMediaSettings::FromEncodableList( + const EncodableList& list) { + PlatformMediaSettings decoded(std::any_cast( + std::get(list[0])), + std::get(list[4])); + auto& encodable_frames_per_second = list[1]; + if (!encodable_frames_per_second.IsNull()) { + decoded.set_frames_per_second( + std::get(encodable_frames_per_second)); + } + auto& encodable_video_bitrate = list[2]; + if (!encodable_video_bitrate.IsNull()) { + decoded.set_video_bitrate(std::get(encodable_video_bitrate)); + } + auto& encodable_audio_bitrate = list[3]; + if (!encodable_audio_bitrate.IsNull()) { + decoded.set_audio_bitrate(std::get(encodable_audio_bitrate)); + } + return decoded; +} + +// PlatformSize + +PlatformSize::PlatformSize(double width, double height) + : width_(width), height_(height) {} + +double PlatformSize::width() const { return width_; } + +void PlatformSize::set_width(double value_arg) { width_ = value_arg; } + +double PlatformSize::height() const { return height_; } + +void PlatformSize::set_height(double value_arg) { height_ = value_arg; } + +EncodableList PlatformSize::ToEncodableList() const { + EncodableList list; + list.reserve(2); + list.push_back(EncodableValue(width_)); + list.push_back(EncodableValue(height_)); + return list; +} + +PlatformSize PlatformSize::FromEncodableList(const EncodableList& list) { + PlatformSize decoded(std::get(list[0]), std::get(list[1])); + return decoded; +} + +PigeonInternalCodecSerializer::PigeonInternalCodecSerializer() {} + +EncodableValue PigeonInternalCodecSerializer::ReadValueOfType( + uint8_t type, flutter::ByteStreamReader* stream) const { + switch (type) { + case 129: { + const auto& encodable_enum_arg = ReadValue(stream); + const int64_t enum_arg_value = + encodable_enum_arg.IsNull() ? 0 : encodable_enum_arg.LongValue(); + return encodable_enum_arg.IsNull() + ? EncodableValue() + : CustomEncodableValue( + static_cast(enum_arg_value)); + } + case 130: { + return CustomEncodableValue(PlatformMediaSettings::FromEncodableList( + std::get(ReadValue(stream)))); + } + case 131: { + return CustomEncodableValue(PlatformSize::FromEncodableList( + std::get(ReadValue(stream)))); + } + default: + return flutter::StandardCodecSerializer::ReadValueOfType(type, stream); + } +} + +void PigeonInternalCodecSerializer::WriteValue( + const EncodableValue& value, flutter::ByteStreamWriter* stream) const { + if (const CustomEncodableValue* custom_value = + std::get_if(&value)) { + if (custom_value->type() == typeid(PlatformResolutionPreset)) { + stream->WriteByte(129); + WriteValue(EncodableValue(static_cast( + std::any_cast(*custom_value))), + stream); + return; + } + if (custom_value->type() == typeid(PlatformMediaSettings)) { + stream->WriteByte(130); + WriteValue( + EncodableValue(std::any_cast(*custom_value) + .ToEncodableList()), + stream); + return; + } + if (custom_value->type() == typeid(PlatformSize)) { + stream->WriteByte(131); + WriteValue( + EncodableValue( + std::any_cast(*custom_value).ToEncodableList()), + stream); + return; + } + } + flutter::StandardCodecSerializer::WriteValue(value, stream); +} + +/// The codec used by CameraApi. +const flutter::StandardMessageCodec& CameraApi::GetCodec() { + return flutter::StandardMessageCodec::GetInstance( + &PigeonInternalCodecSerializer::GetInstance()); +} + +// Sets up an instance of `CameraApi` to handle messages through the +// `binary_messenger`. +void CameraApi::SetUp(flutter::BinaryMessenger* binary_messenger, + CameraApi* api) { + CameraApi::SetUp(binary_messenger, api, ""); +} + +void CameraApi::SetUp(flutter::BinaryMessenger* binary_messenger, + CameraApi* api, + const std::string& message_channel_suffix) { + const std::string prepended_suffix = + message_channel_suffix.length() > 0 + ? std::string(".") + message_channel_suffix + : ""; + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.camera_windows.CameraApi.getAvailableCameras" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + ErrorOr output = api->GetAvailableCameras(); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back(EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.camera_windows.CameraApi.create" + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_camera_name_arg = args.at(0); + if (encodable_camera_name_arg.IsNull()) { + reply(WrapError("camera_name_arg unexpectedly null.")); + return; + } + const auto& camera_name_arg = + std::get(encodable_camera_name_arg); + const auto& encodable_settings_arg = args.at(1); + if (encodable_settings_arg.IsNull()) { + reply(WrapError("settings_arg unexpectedly null.")); + return; + } + const auto& settings_arg = + std::any_cast( + std::get(encodable_settings_arg)); + api->Create(camera_name_arg, settings_arg, + [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.camera_windows.CameraApi.initialize" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_camera_id_arg = args.at(0); + if (encodable_camera_id_arg.IsNull()) { + reply(WrapError("camera_id_arg unexpectedly null.")); + return; + } + const int64_t camera_id_arg = encodable_camera_id_arg.LongValue(); + api->Initialize( + camera_id_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + CustomEncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.camera_windows.CameraApi.dispose" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_camera_id_arg = args.at(0); + if (encodable_camera_id_arg.IsNull()) { + reply(WrapError("camera_id_arg unexpectedly null.")); + return; + } + const int64_t camera_id_arg = encodable_camera_id_arg.LongValue(); + std::optional output = api->Dispose(camera_id_arg); + if (output.has_value()) { + reply(WrapError(output.value())); + return; + } + EncodableList wrapped; + wrapped.push_back(EncodableValue()); + reply(EncodableValue(std::move(wrapped))); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.camera_windows.CameraApi.takePicture" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_camera_id_arg = args.at(0); + if (encodable_camera_id_arg.IsNull()) { + reply(WrapError("camera_id_arg unexpectedly null.")); + return; + } + const int64_t camera_id_arg = encodable_camera_id_arg.LongValue(); + api->TakePicture( + camera_id_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.camera_windows.CameraApi.startVideoRecording" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_camera_id_arg = args.at(0); + if (encodable_camera_id_arg.IsNull()) { + reply(WrapError("camera_id_arg unexpectedly null.")); + return; + } + const int64_t camera_id_arg = encodable_camera_id_arg.LongValue(); + api->StartVideoRecording( + camera_id_arg, [reply](std::optional&& output) { + if (output.has_value()) { + reply(WrapError(output.value())); + return; + } + EncodableList wrapped; + wrapped.push_back(EncodableValue()); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.camera_windows.CameraApi.stopVideoRecording" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_camera_id_arg = args.at(0); + if (encodable_camera_id_arg.IsNull()) { + reply(WrapError("camera_id_arg unexpectedly null.")); + return; + } + const int64_t camera_id_arg = encodable_camera_id_arg.LongValue(); + api->StopVideoRecording( + camera_id_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.camera_windows.CameraApi.pausePreview" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_camera_id_arg = args.at(0); + if (encodable_camera_id_arg.IsNull()) { + reply(WrapError("camera_id_arg unexpectedly null.")); + return; + } + const int64_t camera_id_arg = encodable_camera_id_arg.LongValue(); + api->PausePreview(camera_id_arg, + [reply](std::optional&& output) { + if (output.has_value()) { + reply(WrapError(output.value())); + return; + } + EncodableList wrapped; + wrapped.push_back(EncodableValue()); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.camera_windows.CameraApi.resumePreview" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_camera_id_arg = args.at(0); + if (encodable_camera_id_arg.IsNull()) { + reply(WrapError("camera_id_arg unexpectedly null.")); + return; + } + const int64_t camera_id_arg = encodable_camera_id_arg.LongValue(); + api->ResumePreview(camera_id_arg, + [reply](std::optional&& output) { + if (output.has_value()) { + reply(WrapError(output.value())); + return; + } + EncodableList wrapped; + wrapped.push_back(EncodableValue()); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } +} + +EncodableValue CameraApi::WrapError(std::string_view error_message) { + return EncodableValue( + EncodableList{EncodableValue(std::string(error_message)), + EncodableValue("Error"), EncodableValue()}); +} + +EncodableValue CameraApi::WrapError(const FlutterError& error) { + return EncodableValue(EncodableList{EncodableValue(error.code()), + EncodableValue(error.message()), + error.details()}); +} + +// Generated class from Pigeon that represents Flutter messages that can be +// called from C++. +CameraEventApi::CameraEventApi(flutter::BinaryMessenger* binary_messenger) + : binary_messenger_(binary_messenger), message_channel_suffix_("") {} + +CameraEventApi::CameraEventApi(flutter::BinaryMessenger* binary_messenger, + const std::string& message_channel_suffix) + : binary_messenger_(binary_messenger), + message_channel_suffix_(message_channel_suffix.length() > 0 + ? std::string(".") + message_channel_suffix + : "") {} + +const flutter::StandardMessageCodec& CameraEventApi::GetCodec() { + return flutter::StandardMessageCodec::GetInstance( + &PigeonInternalCodecSerializer::GetInstance()); +} + +void CameraEventApi::CameraClosing( + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.camera_windows.CameraEventApi.cameraClosing" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + on_success(); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void CameraEventApi::Error( + const std::string& error_message_arg, + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.camera_windows.CameraEventApi.error" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + EncodableValue(error_message_arg), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + on_success(); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +} // namespace camera_windows diff --git a/packages/camera/camera_windows/windows/messages.g.h b/packages/camera/camera_windows/windows/messages.g.h new file mode 100644 index 000000000000..a85c692e5b03 --- /dev/null +++ b/packages/camera/camera_windows/windows/messages.g.h @@ -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. +// Autogenerated from Pigeon (v22.6.0), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +#ifndef PIGEON_MESSAGES_G_H_ +#define PIGEON_MESSAGES_G_H_ +#include +#include +#include +#include + +#include +#include +#include + +namespace camera_windows { + +// Generated class from Pigeon. + +class FlutterError { + public: + explicit FlutterError(const std::string& code) : code_(code) {} + explicit FlutterError(const std::string& code, const std::string& message) + : code_(code), message_(message) {} + explicit FlutterError(const std::string& code, const std::string& message, + const flutter::EncodableValue& details) + : code_(code), message_(message), details_(details) {} + + const std::string& code() const { return code_; } + const std::string& message() const { return message_; } + const flutter::EncodableValue& details() const { return details_; } + + private: + std::string code_; + std::string message_; + flutter::EncodableValue details_; +}; + +template +class ErrorOr { + public: + ErrorOr(const T& rhs) : v_(rhs) {} + ErrorOr(const T&& rhs) : v_(std::move(rhs)) {} + ErrorOr(const FlutterError& rhs) : v_(rhs) {} + ErrorOr(const FlutterError&& rhs) : v_(std::move(rhs)) {} + + bool has_error() const { return std::holds_alternative(v_); } + const T& value() const { return std::get(v_); }; + const FlutterError& error() const { return std::get(v_); }; + + private: + friend class CameraApi; + friend class CameraEventApi; + ErrorOr() = default; + T TakeValue() && { return std::get(std::move(v_)); } + + std::variant v_; +}; + +// Pigeon version of platform interface's ResolutionPreset. +enum class PlatformResolutionPreset { + kLow = 0, + kMedium = 1, + kHigh = 2, + kVeryHigh = 3, + kUltraHigh = 4, + kMax = 5 +}; + +// Pigeon version of MediaSettings. +// +// Generated class from Pigeon that represents data sent in messages. +class PlatformMediaSettings { + public: + // Constructs an object setting all non-nullable fields. + explicit PlatformMediaSettings( + const PlatformResolutionPreset& resolution_preset, bool enable_audio); + + // Constructs an object setting all fields. + explicit PlatformMediaSettings( + const PlatformResolutionPreset& resolution_preset, + const int64_t* frames_per_second, const int64_t* video_bitrate, + const int64_t* audio_bitrate, bool enable_audio); + + const PlatformResolutionPreset& resolution_preset() const; + void set_resolution_preset(const PlatformResolutionPreset& value_arg); + + const int64_t* frames_per_second() const; + void set_frames_per_second(const int64_t* value_arg); + void set_frames_per_second(int64_t value_arg); + + const int64_t* video_bitrate() const; + void set_video_bitrate(const int64_t* value_arg); + void set_video_bitrate(int64_t value_arg); + + const int64_t* audio_bitrate() const; + void set_audio_bitrate(const int64_t* value_arg); + void set_audio_bitrate(int64_t value_arg); + + bool enable_audio() const; + void set_enable_audio(bool value_arg); + + private: + static PlatformMediaSettings FromEncodableList( + const flutter::EncodableList& list); + flutter::EncodableList ToEncodableList() const; + friend class CameraApi; + friend class CameraEventApi; + friend class PigeonInternalCodecSerializer; + PlatformResolutionPreset resolution_preset_; + std::optional frames_per_second_; + std::optional video_bitrate_; + std::optional audio_bitrate_; + bool enable_audio_; +}; + +// A representation of a size from the native camera APIs. +// +// Generated class from Pigeon that represents data sent in messages. +class PlatformSize { + public: + // Constructs an object setting all fields. + explicit PlatformSize(double width, double height); + + double width() const; + void set_width(double value_arg); + + double height() const; + void set_height(double value_arg); + + private: + static PlatformSize FromEncodableList(const flutter::EncodableList& list); + flutter::EncodableList ToEncodableList() const; + friend class CameraApi; + friend class CameraEventApi; + friend class PigeonInternalCodecSerializer; + double width_; + double height_; +}; + +class PigeonInternalCodecSerializer : public flutter::StandardCodecSerializer { + public: + PigeonInternalCodecSerializer(); + inline static PigeonInternalCodecSerializer& GetInstance() { + static PigeonInternalCodecSerializer sInstance; + return sInstance; + } + + void WriteValue(const flutter::EncodableValue& value, + flutter::ByteStreamWriter* stream) const override; + + protected: + flutter::EncodableValue ReadValueOfType( + uint8_t type, flutter::ByteStreamReader* stream) const override; +}; + +// Generated interface from Pigeon that represents a handler of messages from +// Flutter. +class CameraApi { + public: + CameraApi(const CameraApi&) = delete; + CameraApi& operator=(const CameraApi&) = delete; + virtual ~CameraApi() {} + // Returns the names of all of the available capture devices. + virtual ErrorOr GetAvailableCameras() = 0; + // Creates a camera instance for the given device name and settings. + virtual void Create(const std::string& camera_name, + const PlatformMediaSettings& settings, + std::function reply)> result) = 0; + // Initializes a camera, and returns the size of its preview. + virtual void Initialize( + int64_t camera_id, + std::function reply)> result) = 0; + // Disposes a camera that is no longer in use. + virtual std::optional Dispose(int64_t camera_id) = 0; + // Takes a picture with the given camera, and returns the path to the + // resulting file. + virtual void TakePicture( + int64_t camera_id, + std::function reply)> result) = 0; + // Starts recording video with the given camera. + virtual void StartVideoRecording( + int64_t camera_id, + std::function reply)> result) = 0; + // Finishes recording video with the given camera, and returns the path to + // the resulting file. + virtual void StopVideoRecording( + int64_t camera_id, + std::function reply)> result) = 0; + // Starts the preview stream for the given camera. + virtual void PausePreview( + int64_t camera_id, + std::function reply)> result) = 0; + // Resumes the preview stream for the given camera. + virtual void ResumePreview( + int64_t camera_id, + std::function reply)> result) = 0; + + // The codec used by CameraApi. + static const flutter::StandardMessageCodec& GetCodec(); + // Sets up an instance of `CameraApi` to handle messages through the + // `binary_messenger`. + static void SetUp(flutter::BinaryMessenger* binary_messenger, CameraApi* api); + static void SetUp(flutter::BinaryMessenger* binary_messenger, CameraApi* api, + const std::string& message_channel_suffix); + static flutter::EncodableValue WrapError(std::string_view error_message); + static flutter::EncodableValue WrapError(const FlutterError& error); + + protected: + CameraApi() = default; +}; +// Generated class from Pigeon that represents Flutter messages that can be +// called from C++. +class CameraEventApi { + public: + CameraEventApi(flutter::BinaryMessenger* binary_messenger); + CameraEventApi(flutter::BinaryMessenger* binary_messenger, + const std::string& message_channel_suffix); + static const flutter::StandardMessageCodec& GetCodec(); + // Called when the camera instance is closing on the native side. + void CameraClosing(std::function&& on_success, + std::function&& on_error); + // Called when a camera error occurs on the native side. + void Error(const std::string& error_message, + std::function&& on_success, + std::function&& on_error); + + private: + flutter::BinaryMessenger* binary_messenger_; + std::string message_channel_suffix_; +}; + +} // namespace camera_windows +#endif // PIGEON_MESSAGES_G_H_ diff --git a/packages/camera/camera_windows/windows/record_handler.cpp b/packages/camera/camera_windows/windows/record_handler.cpp index 6e1cb78d94f1..f857c146efc0 100644 --- a/packages/camera/camera_windows/windows/record_handler.cpp +++ b/packages/camera/camera_windows/windows/record_handler.cpp @@ -176,15 +176,16 @@ HRESULT RecordHandler::InitRecordSink(IMFCaptureEngine* capture_engine, return hr; } - if (media_settings_.fps.has_value()) { - assert(media_settings_.fps.value() > 0); - SetFrameRate(video_record_media_type.Get(), media_settings_.fps.value(), 1); + if (media_settings_.frames_per_second()) { + assert(*media_settings_.frames_per_second() > 0); + SetFrameRate(video_record_media_type.Get(), + static_cast(*media_settings_.frames_per_second()), 1); } - if (media_settings_.video_bitrate.has_value()) { - assert(media_settings_.video_bitrate.value() > 0); + if (media_settings_.video_bitrate()) { + assert(*media_settings_.video_bitrate() > 0); SetVideoBitrate(video_record_media_type.Get(), - media_settings_.video_bitrate.value()); + static_cast(*media_settings_.video_bitrate())); } DWORD video_record_sink_stream_index; @@ -195,17 +196,17 @@ HRESULT RecordHandler::InitRecordSink(IMFCaptureEngine* capture_engine, return hr; } - if (media_settings_.record_audio) { + if (media_settings_.enable_audio()) { ComPtr audio_record_media_type; HRESULT audio_capture_hr = S_OK; audio_capture_hr = BuildMediaTypeForAudioCapture(audio_record_media_type.GetAddressOf()); if (SUCCEEDED(audio_capture_hr)) { - if (media_settings_.audio_bitrate.has_value()) { - assert(media_settings_.audio_bitrate.value() > 0); + if (media_settings_.audio_bitrate()) { + assert(*media_settings_.audio_bitrate() > 0); SetAudioBitrate(audio_record_media_type.Get(), - media_settings_.audio_bitrate.value()); + static_cast(*media_settings_.audio_bitrate())); } DWORD audio_record_sink_stream_index; @@ -226,15 +227,12 @@ HRESULT RecordHandler::InitRecordSink(IMFCaptureEngine* capture_engine, } HRESULT RecordHandler::StartRecord(const std::string& file_path, - int64_t max_duration, IMFCaptureEngine* capture_engine, IMFMediaType* base_media_type) { assert(!file_path.empty()); assert(capture_engine); assert(base_media_type); - type_ = max_duration < 0 ? RecordingType::kContinuous : RecordingType::kTimed; - max_video_duration_ms_ = max_duration; file_path_ = file_path; recording_start_timestamp_us_ = -1; recording_duration_us_ = 0; @@ -267,9 +265,7 @@ void RecordHandler::OnRecordStopped() { file_path_ = ""; recording_start_timestamp_us_ = -1; recording_duration_us_ = 0; - max_video_duration_ms_ = -1; recording_state_ = RecordState::kNotStarted; - type_ = RecordingType::kNone; } } @@ -281,12 +277,4 @@ void RecordHandler::UpdateRecordingTime(uint64_t timestamp) { recording_duration_us_ = (timestamp - recording_start_timestamp_us_); } -bool RecordHandler::ShouldStopTimedRecording() const { - return type_ == RecordingType::kTimed && - recording_state_ == RecordState::kRunning && - max_video_duration_ms_ > 0 && - recording_duration_us_ >= - (static_cast(max_video_duration_ms_) * 1000); -} - } // namespace camera_windows diff --git a/packages/camera/camera_windows/windows/record_handler.h b/packages/camera/camera_windows/windows/record_handler.h index 612e14a4eee9..faed3e8ef9cb 100644 --- a/packages/camera/camera_windows/windows/record_handler.h +++ b/packages/camera/camera_windows/windows/record_handler.h @@ -14,65 +14,24 @@ #include #include +#include "messages.g.h" + namespace camera_windows { using Microsoft::WRL::ComPtr; -enum class RecordingType { - // Camera is not recording. - kNone, - // Recording continues until it is stopped with a separate stop command. - kContinuous, - // Recording stops automatically after requested record time is passed. - kTimed -}; - // States that the record handler can be in. // // When created, the handler starts in |kNotStarted| state and transtions in // sequential order through the states. enum class RecordState { kNotStarted, kStarting, kRunning, kStopping }; -// Recording media settings. -// -// Used in [Camera::InitCamera]. -// Allows to tune recorded video parameters, such as resolution, frame rate, -// bitrate. If [fps], [video_bitrate] or [audio_bitrate] are passed, they must -// be greater than zero. -struct RecordSettings { - explicit RecordSettings( - const bool record_audio = false, - const std::optional& fps = std::nullopt, - const std::optional& video_bitrate = std::nullopt, - const std::optional& audio_bitrate = std::nullopt) - : record_audio(record_audio), - fps(fps), - video_bitrate(video_bitrate), - audio_bitrate(audio_bitrate) { - assert(!fps.has_value() || fps.value() > 0); - assert(!video_bitrate.has_value() || video_bitrate.value() > 0); - assert(!audio_bitrate.has_value() || audio_bitrate.value() > 0); - } - - // Controls audio presence in recorded video. - bool record_audio{false}; - - // Rate at which frames should be captured by the camera in frames per second. - std::optional fps{std::nullopt}; - - // The video encoding bit rate for recording. - std::optional video_bitrate{std::nullopt}; - - // The audio encoding bit rate for recording. - std::optional audio_bitrate{std::nullopt}; -}; - // Handler for video recording via the camera. // // Handles record sink initialization and manages the state of video recording. class RecordHandler { public: - explicit RecordHandler(const RecordSettings& record_settings) - : media_settings_(record_settings) {} + explicit RecordHandler(const PlatformMediaSettings& media_settings) + : media_settings_(media_settings) {} virtual ~RecordHandler() = default; @@ -85,14 +44,11 @@ class RecordHandler { // Sets record state to: starting. // // file_path: A string that hold file path for video capture. - // max_duration: A int64 value of maximun recording duration. - // If value is -1 video recording is considered as - // a continuous recording. // capture_engine: A pointer to capture engine instance. Used to start // the actual recording. // base_media_type: A pointer to base media type used as a base // for the actual video capture media type. - HRESULT StartRecord(const std::string& file_path, int64_t max_duration, + HRESULT StartRecord(const std::string& file_path, IMFCaptureEngine* capture_engine, IMFMediaType* base_media_type); @@ -109,14 +65,6 @@ class RecordHandler { // sets recording state to: not started. void OnRecordStopped(); - // Returns true if recording type is continuous recording. - bool IsContinuousRecording() const { - return type_ == RecordingType::kContinuous; - } - - // Returns true if recording type is timed recording. - bool IsTimedRecording() const { return type_ == RecordingType::kTimed; } - // Returns true if new recording can be started. bool CanStart() const { return recording_state_ == RecordState::kNotStarted; } @@ -132,22 +80,16 @@ class RecordHandler { // Calculates new recording time from capture timestamp. void UpdateRecordingTime(uint64_t timestamp); - // Returns true if recording time has exceeded the maximum duration for timed - // recordings. - bool ShouldStopTimedRecording() const; - private: // Initializes record sink for video file capture. HRESULT InitRecordSink(IMFCaptureEngine* capture_engine, IMFMediaType* base_media_type); - const RecordSettings media_settings_; - int64_t max_video_duration_ms_ = -1; + const PlatformMediaSettings media_settings_; int64_t recording_start_timestamp_us_ = -1; uint64_t recording_duration_us_ = 0; std::string file_path_; RecordState recording_state_ = RecordState::kNotStarted; - RecordingType type_ = RecordingType::kNone; ComPtr record_sink_; }; diff --git a/packages/camera/camera_windows/windows/test/camera_plugin_test.cpp b/packages/camera/camera_windows/windows/test/camera_plugin_test.cpp index 7a9a3cdbde7b..2680ae26c0e3 100644 --- a/packages/camera/camera_windows/windows/test/camera_plugin_test.cpp +++ b/packages/camera/camera_windows/windows/test/camera_plugin_test.cpp @@ -37,11 +37,11 @@ void MockInitCamera(MockCamera* camera, bool success) { .WillOnce(Return(false)); EXPECT_CALL(*camera, - AddPendingResult(Eq(PendingResultType::kCreateCamera), _)) + AddPendingIntResult(Eq(PendingResultType::kCreateCamera), _)) .Times(1) .WillOnce([camera](PendingResultType type, - std::unique_ptr> result) { - camera->pending_result_ = std::move(result); + std::function reply)> result) { + camera->pending_int_result_ = result; return true; }); @@ -52,14 +52,14 @@ void MockInitCamera(MockCamera* camera, bool success) { .Times(1) .WillOnce([camera, success](flutter::TextureRegistrar* texture_registrar, flutter::BinaryMessenger* messenger, - ResolutionPreset resolution_preset, - const RecordSettings& record_settings) { - assert(camera->pending_result_); + const PlatformMediaSettings& media_settings) { + assert(camera->pending_int_result_); if (success) { - camera->pending_result_->Success(EncodableValue(1)); + camera->pending_int_result_(1); return true; } else { - camera->pending_result_->Error("camera_error", "InitCamera failed."); + camera->pending_int_result_( + FlutterError("camera_error", "InitCamera failed.")); return false; } }); @@ -72,8 +72,6 @@ TEST(CameraPlugin, AvailableCamerasHandlerSuccessIfNoCameras) { std::make_unique(); std::unique_ptr camera_factory_ = std::make_unique(); - std::unique_ptr result = - std::make_unique(); MockCameraPlugin plugin(texture_registrar_.get(), messenger_.get(), std::move(camera_factory_)); @@ -87,13 +85,10 @@ TEST(CameraPlugin, AvailableCamerasHandlerSuccessIfNoCameras) { return true; }); - EXPECT_CALL(*result, ErrorInternal).Times(0); - EXPECT_CALL(*result, SuccessInternal).Times(1); + ErrorOr result = plugin.GetAvailableCameras(); - plugin.HandleMethodCall( - flutter::MethodCall("availableCameras", - std::make_unique()), - std::move(result)); + EXPECT_FALSE(result.has_error()); + EXPECT_EQ(result.value().size(), 0); } TEST(CameraPlugin, AvailableCamerasHandlerErrorIfFailsToEnumerateDevices) { @@ -103,8 +98,6 @@ TEST(CameraPlugin, AvailableCamerasHandlerErrorIfFailsToEnumerateDevices) { std::make_unique(); std::unique_ptr camera_factory_ = std::make_unique(); - std::unique_ptr result = - std::make_unique(); MockCameraPlugin plugin(texture_registrar_.get(), messenger_.get(), std::move(camera_factory_)); @@ -113,18 +106,12 @@ TEST(CameraPlugin, AvailableCamerasHandlerErrorIfFailsToEnumerateDevices) { .Times(1) .WillOnce([](IMFActivate*** devices, UINT32* count) { return false; }); - EXPECT_CALL(*result, ErrorInternal).Times(1); - EXPECT_CALL(*result, SuccessInternal).Times(0); + ErrorOr result = plugin.GetAvailableCameras(); - plugin.HandleMethodCall( - flutter::MethodCall("availableCameras", - std::make_unique()), - std::move(result)); + EXPECT_TRUE(result.has_error()); } TEST(CameraPlugin, CreateHandlerCallsInitCamera) { - std::unique_ptr result = - std::make_unique(); std::unique_ptr texture_registrar_ = std::make_unique(); std::unique_ptr messenger_ = @@ -142,26 +129,26 @@ TEST(CameraPlugin, CreateHandlerCallsInitCamera) { EXPECT_CALL(*camera_factory_, CreateCamera(MOCK_DEVICE_ID)); - EXPECT_CALL(*result, ErrorInternal).Times(0); - EXPECT_CALL(*result, SuccessInternal(Pointee(EncodableValue(1)))); - CameraPlugin plugin(texture_registrar_.get(), messenger_.get(), std::move(camera_factory_)); - EncodableMap args = { - {EncodableValue("cameraName"), EncodableValue(MOCK_CAMERA_NAME)}, - {EncodableValue("resolutionPreset"), EncodableValue(nullptr)}, - {EncodableValue("enableAudio"), EncodableValue(true)}, - }; - - plugin.HandleMethodCall( - flutter::MethodCall("create", - std::make_unique(EncodableMap(args))), - std::move(result)); + + bool result_called = false; + std::function)> create_result = + [&result_called](ErrorOr reply) { + EXPECT_FALSE(result_called); // Ensure only one reply call. + result_called = true; + EXPECT_FALSE(reply.has_error()); + EXPECT_EQ(reply.value(), 1); + }; + + plugin.Create(MOCK_CAMERA_NAME, + PlatformMediaSettings(PlatformResolutionPreset::kMax, true), + std::move(create_result)); + + EXPECT_TRUE(result_called); } TEST(CameraPlugin, CreateHandlerErrorOnInvalidDeviceId) { - std::unique_ptr result = - std::make_unique(); std::unique_ptr texture_registrar_ = std::make_unique(); std::unique_ptr messenger_ = @@ -171,25 +158,23 @@ TEST(CameraPlugin, CreateHandlerErrorOnInvalidDeviceId) { CameraPlugin plugin(texture_registrar_.get(), messenger_.get(), std::move(camera_factory_)); - EncodableMap args = { - {EncodableValue("cameraName"), EncodableValue(MOCK_INVALID_CAMERA_NAME)}, - {EncodableValue("resolutionPreset"), EncodableValue(nullptr)}, - {EncodableValue("enableAudio"), EncodableValue(true)}, - }; - - EXPECT_CALL(*result, ErrorInternal).Times(1); - - plugin.HandleMethodCall( - flutter::MethodCall("create", - std::make_unique(EncodableMap(args))), - std::move(result)); + + bool result_called = false; + std::function)> create_result = + [&result_called](ErrorOr reply) { + EXPECT_FALSE(result_called); // Ensure only one reply call. + result_called = true; + EXPECT_TRUE(reply.has_error()); + }; + + plugin.Create(MOCK_INVALID_CAMERA_NAME, + PlatformMediaSettings(PlatformResolutionPreset::kMax, true), + std::move(create_result)); + + EXPECT_TRUE(result_called); } TEST(CameraPlugin, CreateHandlerErrorOnExistingDeviceId) { - std::unique_ptr first_create_result = - std::make_unique(); - std::unique_ptr second_create_result = - std::make_unique(); std::unique_ptr texture_registrar_ = std::make_unique(); std::unique_ptr messenger_ = @@ -207,37 +192,39 @@ TEST(CameraPlugin, CreateHandlerErrorOnExistingDeviceId) { EXPECT_CALL(*camera_factory_, CreateCamera(MOCK_DEVICE_ID)); - EXPECT_CALL(*first_create_result, ErrorInternal).Times(0); - EXPECT_CALL(*first_create_result, - SuccessInternal(Pointee(EncodableValue(1)))); - CameraPlugin plugin(texture_registrar_.get(), messenger_.get(), std::move(camera_factory_)); - EncodableMap args = { - {EncodableValue("cameraName"), EncodableValue(MOCK_CAMERA_NAME)}, - {EncodableValue("resolutionPreset"), EncodableValue(nullptr)}, - {EncodableValue("enableAudio"), EncodableValue(true)}, - }; - - plugin.HandleMethodCall( - flutter::MethodCall("create", - std::make_unique(EncodableMap(args))), - std::move(first_create_result)); - - EXPECT_CALL(*second_create_result, ErrorInternal).Times(1); - EXPECT_CALL(*second_create_result, SuccessInternal).Times(0); - - plugin.HandleMethodCall( - flutter::MethodCall("create", - std::make_unique(EncodableMap(args))), - std::move(second_create_result)); + + bool first_result_called = false; + std::function)> first_create_result = + [&first_result_called](ErrorOr reply) { + EXPECT_FALSE(first_result_called); // Ensure only one reply call. + first_result_called = true; + EXPECT_FALSE(reply.has_error()); + EXPECT_EQ(reply.value(), 1); + }; + + PlatformMediaSettings media_settings(PlatformResolutionPreset::kMax, true); + plugin.Create(MOCK_CAMERA_NAME, media_settings, + std::move(first_create_result)); + + EXPECT_TRUE(first_result_called); + + bool second_result_called = false; + std::function)> second_create_result = + [&second_result_called](ErrorOr reply) { + EXPECT_FALSE(second_result_called); // Ensure only one reply call. + second_result_called = true; + EXPECT_TRUE(reply.has_error()); + }; + + plugin.Create(MOCK_CAMERA_NAME, media_settings, + std::move(second_create_result)); + + EXPECT_TRUE(second_result_called); } TEST(CameraPlugin, CreateHandlerAllowsRetry) { - std::unique_ptr first_create_result = - std::make_unique(); - std::unique_ptr second_create_result = - std::make_unique(); std::unique_ptr texture_registrar_ = std::make_unique(); std::unique_ptr messenger_ = @@ -265,38 +252,41 @@ TEST(CameraPlugin, CreateHandlerAllowsRetry) { return second_camera; }); - EXPECT_CALL(*first_create_result, ErrorInternal).Times(1); - EXPECT_CALL(*first_create_result, SuccessInternal).Times(0); - CameraPlugin plugin(texture_registrar_.get(), messenger_.get(), std::move(camera_factory_)); - EncodableMap args = { - {EncodableValue("cameraName"), EncodableValue(MOCK_CAMERA_NAME)}, - {EncodableValue("resolutionPreset"), EncodableValue(nullptr)}, - {EncodableValue("enableAudio"), EncodableValue(true)}, - }; - - plugin.HandleMethodCall( - flutter::MethodCall("create", - std::make_unique(EncodableMap(args))), - std::move(first_create_result)); - - EXPECT_CALL(*second_create_result, ErrorInternal).Times(0); - EXPECT_CALL(*second_create_result, - SuccessInternal(Pointee(EncodableValue(1)))); - - plugin.HandleMethodCall( - flutter::MethodCall("create", - std::make_unique(EncodableMap(args))), - std::move(second_create_result)); + + bool first_result_called = false; + std::function)> first_create_result = + [&first_result_called](ErrorOr reply) { + EXPECT_FALSE(first_result_called); // Ensure only one reply call. + first_result_called = true; + EXPECT_TRUE(reply.has_error()); + }; + + PlatformMediaSettings media_settings(PlatformResolutionPreset::kMax, true); + plugin.Create(MOCK_CAMERA_NAME, media_settings, + std::move(first_create_result)); + + EXPECT_TRUE(first_result_called); + + bool second_result_called = false; + std::function)> second_create_result = + [&second_result_called](ErrorOr reply) { + EXPECT_FALSE(second_result_called); // Ensure only one reply call. + second_result_called = true; + EXPECT_FALSE(reply.has_error()); + EXPECT_EQ(reply.value(), 1); + }; + + plugin.Create(MOCK_CAMERA_NAME, media_settings, + std::move(second_create_result)); + + EXPECT_TRUE(second_result_called); } TEST(CameraPlugin, InitializeHandlerCallStartPreview) { int64_t mock_camera_id = 1234; - std::unique_ptr initialize_result = - std::make_unique(); - std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); @@ -314,26 +304,28 @@ TEST(CameraPlugin, InitializeHandlerCallStartPreview) { .Times(1) .WillOnce(Return(false)); - EXPECT_CALL(*camera, AddPendingResult(Eq(PendingResultType::kInitialize), _)) + EXPECT_CALL(*camera, + AddPendingSizeResult(Eq(PendingResultType::kInitialize), _)) .Times(1) - .WillOnce([cam = camera.get()](PendingResultType type, - std::unique_ptr> result) { - cam->pending_result_ = std::move(result); + .WillOnce([cam = camera.get()]( + PendingResultType type, + std::function)> result) { + cam->pending_size_result_ = std::move(result); return true; }); EXPECT_CALL(*camera, GetCaptureController) .Times(1) .WillOnce([cam = camera.get()]() { - assert(cam->pending_result_); + assert(cam->pending_size_result_); return cam->capture_controller_.get(); }); EXPECT_CALL(*capture_controller, StartPreview()) .Times(1) .WillOnce([cam = camera.get()]() { - assert(cam->pending_result_); - return cam->pending_result_->Success(); + assert(cam->pending_size_result_); + return cam->pending_size_result_(PlatformSize(800, 600)); }); camera->camera_id_ = mock_camera_id; @@ -346,26 +338,23 @@ TEST(CameraPlugin, InitializeHandlerCallStartPreview) { // Add mocked camera to plugins camera list. plugin.AddCamera(std::move(camera)); - EXPECT_CALL(*initialize_result, ErrorInternal).Times(0); - EXPECT_CALL(*initialize_result, SuccessInternal).Times(1); + bool result_called = false; + std::function)> initialize_result = + [&result_called](ErrorOr reply) { + EXPECT_FALSE(result_called); // Ensure only one reply call. + result_called = true; + EXPECT_FALSE(reply.has_error()); + }; - EncodableMap args = { - {EncodableValue("cameraId"), EncodableValue(mock_camera_id)}, - }; + plugin.Initialize(mock_camera_id, std::move(initialize_result)); - plugin.HandleMethodCall( - flutter::MethodCall("initialize", - std::make_unique(EncodableMap(args))), - std::move(initialize_result)); + EXPECT_TRUE(result_called); } TEST(CameraPlugin, InitializeHandlerErrorOnInvalidCameraId) { int64_t mock_camera_id = 1234; int64_t missing_camera_id = 5678; - std::unique_ptr initialize_result = - std::make_unique(); - std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); @@ -379,7 +368,7 @@ TEST(CameraPlugin, InitializeHandlerErrorOnInvalidCameraId) { }); EXPECT_CALL(*camera, HasPendingResultByType).Times(0); - EXPECT_CALL(*camera, AddPendingResult).Times(0); + EXPECT_CALL(*camera, AddPendingSizeResult).Times(0); EXPECT_CALL(*camera, GetCaptureController).Times(0); EXPECT_CALL(*capture_controller, StartPreview).Times(0); @@ -392,25 +381,22 @@ TEST(CameraPlugin, InitializeHandlerErrorOnInvalidCameraId) { // Add mocked camera to plugins camera list. plugin.AddCamera(std::move(camera)); - EXPECT_CALL(*initialize_result, ErrorInternal).Times(1); - EXPECT_CALL(*initialize_result, SuccessInternal).Times(0); + bool result_called = false; + std::function)> initialize_result = + [&result_called](ErrorOr reply) { + EXPECT_FALSE(result_called); // Ensure only one reply call. + result_called = true; + EXPECT_TRUE(reply.has_error()); + }; - EncodableMap args = { - {EncodableValue("cameraId"), EncodableValue(missing_camera_id)}, - }; + plugin.Initialize(missing_camera_id, std::move(initialize_result)); - plugin.HandleMethodCall( - flutter::MethodCall("initialize", - std::make_unique(EncodableMap(args))), - std::move(initialize_result)); + EXPECT_TRUE(result_called); } TEST(CameraPlugin, TakePictureHandlerCallsTakePictureWithPath) { int64_t mock_camera_id = 1234; - std::unique_ptr initialize_result = - std::make_unique(); - std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); @@ -428,26 +414,28 @@ TEST(CameraPlugin, TakePictureHandlerCallsTakePictureWithPath) { .Times(1) .WillOnce(Return(false)); - EXPECT_CALL(*camera, AddPendingResult(Eq(PendingResultType::kTakePicture), _)) + EXPECT_CALL(*camera, + AddPendingStringResult(Eq(PendingResultType::kTakePicture), _)) .Times(1) - .WillOnce([cam = camera.get()](PendingResultType type, - std::unique_ptr> result) { - cam->pending_result_ = std::move(result); + .WillOnce([cam = camera.get()]( + PendingResultType type, + std::function)> result) { + cam->pending_string_result_ = std::move(result); return true; }); EXPECT_CALL(*camera, GetCaptureController) .Times(1) .WillOnce([cam = camera.get()]() { - assert(cam->pending_result_); + assert(cam->pending_string_result_); return cam->capture_controller_.get(); }); EXPECT_CALL(*capture_controller, TakePicture(EndsWith(".jpeg"))) .Times(1) .WillOnce([cam = camera.get()](const std::string& file_path) { - assert(cam->pending_result_); - return cam->pending_result_->Success(); + assert(cam->pending_string_result_); + return cam->pending_string_result_(file_path); }); camera->camera_id_ = mock_camera_id; @@ -460,26 +448,23 @@ TEST(CameraPlugin, TakePictureHandlerCallsTakePictureWithPath) { // Add mocked camera to plugins camera list. plugin.AddCamera(std::move(camera)); - EXPECT_CALL(*initialize_result, ErrorInternal).Times(0); - EXPECT_CALL(*initialize_result, SuccessInternal).Times(1); + bool result_called = false; + std::function)> take_picture_result = + [&result_called](ErrorOr reply) { + EXPECT_FALSE(result_called); // Ensure only one reply call. + result_called = true; + EXPECT_FALSE(reply.has_error()); + }; - EncodableMap args = { - {EncodableValue("cameraId"), EncodableValue(mock_camera_id)}, - }; + plugin.TakePicture(mock_camera_id, std::move(take_picture_result)); - plugin.HandleMethodCall( - flutter::MethodCall("takePicture", - std::make_unique(EncodableMap(args))), - std::move(initialize_result)); + EXPECT_TRUE(result_called); } TEST(CameraPlugin, TakePictureHandlerErrorOnInvalidCameraId) { int64_t mock_camera_id = 1234; int64_t missing_camera_id = 5678; - std::unique_ptr initialize_result = - std::make_unique(); - std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); @@ -493,7 +478,7 @@ TEST(CameraPlugin, TakePictureHandlerErrorOnInvalidCameraId) { }); EXPECT_CALL(*camera, HasPendingResultByType).Times(0); - EXPECT_CALL(*camera, AddPendingResult).Times(0); + EXPECT_CALL(*camera, AddPendingStringResult).Times(0); EXPECT_CALL(*camera, GetCaptureController).Times(0); EXPECT_CALL(*capture_controller, TakePicture).Times(0); @@ -506,25 +491,22 @@ TEST(CameraPlugin, TakePictureHandlerErrorOnInvalidCameraId) { // Add mocked camera to plugins camera list. plugin.AddCamera(std::move(camera)); - EXPECT_CALL(*initialize_result, ErrorInternal).Times(1); - EXPECT_CALL(*initialize_result, SuccessInternal).Times(0); + bool result_called = false; + std::function)> take_picture_result = + [&result_called](ErrorOr reply) { + EXPECT_FALSE(result_called); // Ensure only one reply call. + result_called = true; + EXPECT_TRUE(reply.has_error()); + }; - EncodableMap args = { - {EncodableValue("cameraId"), EncodableValue(missing_camera_id)}, - }; + plugin.TakePicture(missing_camera_id, std::move(take_picture_result)); - plugin.HandleMethodCall( - flutter::MethodCall("takePicture", - std::make_unique(EncodableMap(args))), - std::move(initialize_result)); + EXPECT_TRUE(result_called); } TEST(CameraPlugin, StartVideoRecordingHandlerCallsStartRecordWithPath) { int64_t mock_camera_id = 1234; - std::unique_ptr initialize_result = - std::make_unique(); - std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); @@ -542,99 +524,28 @@ TEST(CameraPlugin, StartVideoRecordingHandlerCallsStartRecordWithPath) { .Times(1) .WillOnce(Return(false)); - EXPECT_CALL(*camera, AddPendingResult(Eq(PendingResultType::kStartRecord), _)) - .Times(1) - .WillOnce([cam = camera.get()](PendingResultType type, - std::unique_ptr> result) { - cam->pending_result_ = std::move(result); - return true; - }); - - EXPECT_CALL(*camera, GetCaptureController) - .Times(1) - .WillOnce([cam = camera.get()]() { - assert(cam->pending_result_); - return cam->capture_controller_.get(); - }); - - EXPECT_CALL(*capture_controller, StartRecord(EndsWith(".mp4"), -1)) - .Times(1) - .WillOnce([cam = camera.get()](const std::string& file_path, - int64_t max_video_duration_ms) { - assert(cam->pending_result_); - return cam->pending_result_->Success(); - }); - - camera->camera_id_ = mock_camera_id; - camera->capture_controller_ = std::move(capture_controller); - - MockCameraPlugin plugin(std::make_unique().get(), - std::make_unique().get(), - std::make_unique()); - - // Add mocked camera to plugins camera list. - plugin.AddCamera(std::move(camera)); - - EXPECT_CALL(*initialize_result, ErrorInternal).Times(0); - EXPECT_CALL(*initialize_result, SuccessInternal).Times(1); - - EncodableMap args = { - {EncodableValue("cameraId"), EncodableValue(mock_camera_id)}, - }; - - plugin.HandleMethodCall( - flutter::MethodCall("startVideoRecording", - std::make_unique(EncodableMap(args))), - std::move(initialize_result)); -} - -TEST(CameraPlugin, - StartVideoRecordingHandlerCallsStartRecordWithPathAndCaptureDuration) { - int64_t mock_camera_id = 1234; - int32_t mock_video_duration = 100000; - - std::unique_ptr initialize_result = - std::make_unique(); - - std::unique_ptr camera = - std::make_unique(MOCK_DEVICE_ID); - - std::unique_ptr capture_controller = - std::make_unique(); - - EXPECT_CALL(*camera, HasCameraId(Eq(mock_camera_id))) - .Times(1) - .WillOnce([cam = camera.get()](int64_t camera_id) { - return cam->camera_id_ == camera_id; - }); - EXPECT_CALL(*camera, - HasPendingResultByType(Eq(PendingResultType::kStartRecord))) + AddPendingVoidResult(Eq(PendingResultType::kStartRecord), _)) .Times(1) - .WillOnce(Return(false)); - - EXPECT_CALL(*camera, AddPendingResult(Eq(PendingResultType::kStartRecord), _)) - .Times(1) - .WillOnce([cam = camera.get()](PendingResultType type, - std::unique_ptr> result) { - cam->pending_result_ = std::move(result); + .WillOnce([cam = camera.get()]( + PendingResultType type, + std::function)> result) { + cam->pending_void_result_ = std::move(result); return true; }); EXPECT_CALL(*camera, GetCaptureController) .Times(1) .WillOnce([cam = camera.get()]() { - assert(cam->pending_result_); + assert(cam->pending_void_result_); return cam->capture_controller_.get(); }); - EXPECT_CALL(*capture_controller, - StartRecord(EndsWith(".mp4"), Eq(mock_video_duration))) + EXPECT_CALL(*capture_controller, StartRecord(EndsWith(".mp4"))) .Times(1) - .WillOnce([cam = camera.get()](const std::string& file_path, - int64_t max_video_duration_ms) { - assert(cam->pending_result_); - return cam->pending_result_->Success(); + .WillOnce([cam = camera.get()](const std::string& file_path) { + assert(cam->pending_void_result_); + return cam->pending_void_result_(std::nullopt); }); camera->camera_id_ = mock_camera_id; @@ -647,27 +558,23 @@ TEST(CameraPlugin, // Add mocked camera to plugins camera list. plugin.AddCamera(std::move(camera)); - EXPECT_CALL(*initialize_result, ErrorInternal).Times(0); - EXPECT_CALL(*initialize_result, SuccessInternal).Times(1); + bool result_called = false; + std::function)> start_video_result = + [&result_called](std::optional reply) { + EXPECT_FALSE(result_called); // Ensure only one reply call. + result_called = true; + EXPECT_FALSE(reply); + }; - EncodableMap args = { - {EncodableValue("cameraId"), EncodableValue(mock_camera_id)}, - {EncodableValue("maxVideoDuration"), EncodableValue(mock_video_duration)}, - }; + plugin.StartVideoRecording(mock_camera_id, std::move(start_video_result)); - plugin.HandleMethodCall( - flutter::MethodCall("startVideoRecording", - std::make_unique(EncodableMap(args))), - std::move(initialize_result)); + EXPECT_TRUE(result_called); } TEST(CameraPlugin, StartVideoRecordingHandlerErrorOnInvalidCameraId) { int64_t mock_camera_id = 1234; int64_t missing_camera_id = 5678; - std::unique_ptr initialize_result = - std::make_unique(); - std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); @@ -681,9 +588,9 @@ TEST(CameraPlugin, StartVideoRecordingHandlerErrorOnInvalidCameraId) { }); EXPECT_CALL(*camera, HasPendingResultByType).Times(0); - EXPECT_CALL(*camera, AddPendingResult).Times(0); + EXPECT_CALL(*camera, AddPendingVoidResult).Times(0); EXPECT_CALL(*camera, GetCaptureController).Times(0); - EXPECT_CALL(*capture_controller, StartRecord(_, -1)).Times(0); + EXPECT_CALL(*capture_controller, StartRecord(_)).Times(0); camera->camera_id_ = mock_camera_id; @@ -694,24 +601,22 @@ TEST(CameraPlugin, StartVideoRecordingHandlerErrorOnInvalidCameraId) { // Add mocked camera to plugins camera list. plugin.AddCamera(std::move(camera)); - EXPECT_CALL(*initialize_result, ErrorInternal).Times(1); - EXPECT_CALL(*initialize_result, SuccessInternal).Times(0); + bool result_called = false; + std::function)> start_video_result = + [&result_called](std::optional reply) { + EXPECT_FALSE(result_called); // Ensure only one reply call. + result_called = true; + EXPECT_TRUE(reply); + }; - EncodableMap args = { - {EncodableValue("cameraId"), EncodableValue(missing_camera_id)}, - }; + plugin.StartVideoRecording(missing_camera_id, std::move(start_video_result)); - plugin.HandleMethodCall( - flutter::MethodCall("startVideoRecording", - std::make_unique(EncodableMap(args))), - std::move(initialize_result)); + EXPECT_TRUE(result_called); } TEST(CameraPlugin, StopVideoRecordingHandlerCallsStopRecord) { int64_t mock_camera_id = 1234; - - std::unique_ptr initialize_result = - std::make_unique(); + std::string mock_video_path = "path/to/video.mpeg"; std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); @@ -730,26 +635,28 @@ TEST(CameraPlugin, StopVideoRecordingHandlerCallsStopRecord) { .Times(1) .WillOnce(Return(false)); - EXPECT_CALL(*camera, AddPendingResult(Eq(PendingResultType::kStopRecord), _)) + EXPECT_CALL(*camera, + AddPendingStringResult(Eq(PendingResultType::kStopRecord), _)) .Times(1) - .WillOnce([cam = camera.get()](PendingResultType type, - std::unique_ptr> result) { - cam->pending_result_ = std::move(result); + .WillOnce([cam = camera.get()]( + PendingResultType type, + std::function)> result) { + cam->pending_string_result_ = std::move(result); return true; }); EXPECT_CALL(*camera, GetCaptureController) .Times(1) .WillOnce([cam = camera.get()]() { - assert(cam->pending_result_); + assert(cam->pending_string_result_); return cam->capture_controller_.get(); }); EXPECT_CALL(*capture_controller, StopRecord) .Times(1) - .WillOnce([cam = camera.get()]() { - assert(cam->pending_result_); - return cam->pending_result_->Success(); + .WillOnce([cam = camera.get(), mock_video_path]() { + assert(cam->pending_string_result_); + return cam->pending_string_result_(mock_video_path); }); camera->camera_id_ = mock_camera_id; @@ -762,26 +669,24 @@ TEST(CameraPlugin, StopVideoRecordingHandlerCallsStopRecord) { // Add mocked camera to plugins camera list. plugin.AddCamera(std::move(camera)); - EXPECT_CALL(*initialize_result, ErrorInternal).Times(0); - EXPECT_CALL(*initialize_result, SuccessInternal).Times(1); + bool result_called = false; + std::function)> stop_recording_result = + [&result_called, mock_video_path](ErrorOr reply) { + EXPECT_FALSE(result_called); // Ensure only one reply call. + result_called = true; + EXPECT_FALSE(reply.has_error()); + EXPECT_EQ(reply.value(), mock_video_path); + }; - EncodableMap args = { - {EncodableValue("cameraId"), EncodableValue(mock_camera_id)}, - }; + plugin.StopVideoRecording(mock_camera_id, std::move(stop_recording_result)); - plugin.HandleMethodCall( - flutter::MethodCall("stopVideoRecording", - std::make_unique(EncodableMap(args))), - std::move(initialize_result)); + EXPECT_TRUE(result_called); } TEST(CameraPlugin, StopVideoRecordingHandlerErrorOnInvalidCameraId) { int64_t mock_camera_id = 1234; int64_t missing_camera_id = 5678; - std::unique_ptr initialize_result = - std::make_unique(); - std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); @@ -795,7 +700,7 @@ TEST(CameraPlugin, StopVideoRecordingHandlerErrorOnInvalidCameraId) { }); EXPECT_CALL(*camera, HasPendingResultByType).Times(0); - EXPECT_CALL(*camera, AddPendingResult).Times(0); + EXPECT_CALL(*camera, AddPendingStringResult).Times(0); EXPECT_CALL(*camera, GetCaptureController).Times(0); EXPECT_CALL(*capture_controller, StopRecord).Times(0); @@ -808,25 +713,23 @@ TEST(CameraPlugin, StopVideoRecordingHandlerErrorOnInvalidCameraId) { // Add mocked camera to plugins camera list. plugin.AddCamera(std::move(camera)); - EXPECT_CALL(*initialize_result, ErrorInternal).Times(1); - EXPECT_CALL(*initialize_result, SuccessInternal).Times(0); + bool result_called = false; + std::function)> stop_recording_result = + [&result_called](ErrorOr reply) { + EXPECT_FALSE(result_called); // Ensure only one reply call. + result_called = true; + EXPECT_TRUE(reply.has_error()); + }; - EncodableMap args = { - {EncodableValue("cameraId"), EncodableValue(missing_camera_id)}, - }; + plugin.StopVideoRecording(missing_camera_id, + std::move(stop_recording_result)); - plugin.HandleMethodCall( - flutter::MethodCall("stopVideoRecording", - std::make_unique(EncodableMap(args))), - std::move(initialize_result)); + EXPECT_TRUE(result_called); } TEST(CameraPlugin, ResumePreviewHandlerCallsResumePreview) { int64_t mock_camera_id = 1234; - std::unique_ptr initialize_result = - std::make_unique(); - std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); @@ -845,26 +748,27 @@ TEST(CameraPlugin, ResumePreviewHandlerCallsResumePreview) { .WillOnce(Return(false)); EXPECT_CALL(*camera, - AddPendingResult(Eq(PendingResultType::kResumePreview), _)) + AddPendingVoidResult(Eq(PendingResultType::kResumePreview), _)) .Times(1) - .WillOnce([cam = camera.get()](PendingResultType type, - std::unique_ptr> result) { - cam->pending_result_ = std::move(result); + .WillOnce([cam = camera.get()]( + PendingResultType type, + std::function)> result) { + cam->pending_void_result_ = std::move(result); return true; }); EXPECT_CALL(*camera, GetCaptureController) .Times(1) .WillOnce([cam = camera.get()]() { - assert(cam->pending_result_); + assert(cam->pending_void_result_); return cam->capture_controller_.get(); }); EXPECT_CALL(*capture_controller, ResumePreview) .Times(1) .WillOnce([cam = camera.get()]() { - assert(cam->pending_result_); - return cam->pending_result_->Success(); + assert(cam->pending_void_result_); + return cam->pending_void_result_(std::nullopt); }); camera->camera_id_ = mock_camera_id; @@ -877,26 +781,23 @@ TEST(CameraPlugin, ResumePreviewHandlerCallsResumePreview) { // Add mocked camera to plugins camera list. plugin.AddCamera(std::move(camera)); - EXPECT_CALL(*initialize_result, ErrorInternal).Times(0); - EXPECT_CALL(*initialize_result, SuccessInternal).Times(1); + bool result_called = false; + std::function)> resume_preview_result = + [&result_called](std::optional reply) { + EXPECT_FALSE(result_called); // Ensure only one reply call. + result_called = true; + EXPECT_FALSE(reply); + }; - EncodableMap args = { - {EncodableValue("cameraId"), EncodableValue(mock_camera_id)}, - }; + plugin.ResumePreview(mock_camera_id, std::move(resume_preview_result)); - plugin.HandleMethodCall( - flutter::MethodCall("resumePreview", - std::make_unique(EncodableMap(args))), - std::move(initialize_result)); + EXPECT_TRUE(result_called); } TEST(CameraPlugin, ResumePreviewHandlerErrorOnInvalidCameraId) { int64_t mock_camera_id = 1234; int64_t missing_camera_id = 5678; - std::unique_ptr initialize_result = - std::make_unique(); - std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); @@ -910,7 +811,7 @@ TEST(CameraPlugin, ResumePreviewHandlerErrorOnInvalidCameraId) { }); EXPECT_CALL(*camera, HasPendingResultByType).Times(0); - EXPECT_CALL(*camera, AddPendingResult).Times(0); + EXPECT_CALL(*camera, AddPendingVoidResult).Times(0); EXPECT_CALL(*camera, GetCaptureController).Times(0); EXPECT_CALL(*capture_controller, ResumePreview).Times(0); @@ -923,25 +824,22 @@ TEST(CameraPlugin, ResumePreviewHandlerErrorOnInvalidCameraId) { // Add mocked camera to plugins camera list. plugin.AddCamera(std::move(camera)); - EXPECT_CALL(*initialize_result, ErrorInternal).Times(1); - EXPECT_CALL(*initialize_result, SuccessInternal).Times(0); + bool result_called = false; + std::function)> resume_preview_result = + [&result_called](std::optional reply) { + EXPECT_FALSE(result_called); // Ensure only one reply call. + result_called = true; + EXPECT_TRUE(reply); + }; - EncodableMap args = { - {EncodableValue("cameraId"), EncodableValue(missing_camera_id)}, - }; + plugin.ResumePreview(missing_camera_id, std::move(resume_preview_result)); - plugin.HandleMethodCall( - flutter::MethodCall("resumePreview", - std::make_unique(EncodableMap(args))), - std::move(initialize_result)); + EXPECT_TRUE(result_called); } TEST(CameraPlugin, PausePreviewHandlerCallsPausePreview) { int64_t mock_camera_id = 1234; - std::unique_ptr initialize_result = - std::make_unique(); - std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); @@ -960,26 +858,27 @@ TEST(CameraPlugin, PausePreviewHandlerCallsPausePreview) { .WillOnce(Return(false)); EXPECT_CALL(*camera, - AddPendingResult(Eq(PendingResultType::kPausePreview), _)) + AddPendingVoidResult(Eq(PendingResultType::kPausePreview), _)) .Times(1) - .WillOnce([cam = camera.get()](PendingResultType type, - std::unique_ptr> result) { - cam->pending_result_ = std::move(result); + .WillOnce([cam = camera.get()]( + PendingResultType type, + std::function)> result) { + cam->pending_void_result_ = std::move(result); return true; }); EXPECT_CALL(*camera, GetCaptureController) .Times(1) .WillOnce([cam = camera.get()]() { - assert(cam->pending_result_); + assert(cam->pending_void_result_); return cam->capture_controller_.get(); }); EXPECT_CALL(*capture_controller, PausePreview) .Times(1) .WillOnce([cam = camera.get()]() { - assert(cam->pending_result_); - return cam->pending_result_->Success(); + assert(cam->pending_void_result_); + return cam->pending_void_result_(std::nullopt); }); camera->camera_id_ = mock_camera_id; @@ -992,26 +891,23 @@ TEST(CameraPlugin, PausePreviewHandlerCallsPausePreview) { // Add mocked camera to plugins camera list. plugin.AddCamera(std::move(camera)); - EXPECT_CALL(*initialize_result, ErrorInternal).Times(0); - EXPECT_CALL(*initialize_result, SuccessInternal).Times(1); + bool result_called = false; + std::function)> pause_preview_result = + [&result_called](std::optional reply) { + EXPECT_FALSE(result_called); // Ensure only one reply call. + result_called = true; + EXPECT_FALSE(reply); + }; - EncodableMap args = { - {EncodableValue("cameraId"), EncodableValue(mock_camera_id)}, - }; + plugin.PausePreview(mock_camera_id, std::move(pause_preview_result)); - plugin.HandleMethodCall( - flutter::MethodCall("pausePreview", - std::make_unique(EncodableMap(args))), - std::move(initialize_result)); + EXPECT_TRUE(result_called); } TEST(CameraPlugin, PausePreviewHandlerErrorOnInvalidCameraId) { int64_t mock_camera_id = 1234; int64_t missing_camera_id = 5678; - std::unique_ptr initialize_result = - std::make_unique(); - std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); @@ -1025,7 +921,7 @@ TEST(CameraPlugin, PausePreviewHandlerErrorOnInvalidCameraId) { }); EXPECT_CALL(*camera, HasPendingResultByType).Times(0); - EXPECT_CALL(*camera, AddPendingResult).Times(0); + EXPECT_CALL(*camera, AddPendingVoidResult).Times(0); EXPECT_CALL(*camera, GetCaptureController).Times(0); EXPECT_CALL(*capture_controller, PausePreview).Times(0); @@ -1038,17 +934,17 @@ TEST(CameraPlugin, PausePreviewHandlerErrorOnInvalidCameraId) { // Add mocked camera to plugins camera list. plugin.AddCamera(std::move(camera)); - EXPECT_CALL(*initialize_result, ErrorInternal).Times(1); - EXPECT_CALL(*initialize_result, SuccessInternal).Times(0); + bool result_called = false; + std::function)> pause_preview_result = + [&result_called](std::optional reply) { + EXPECT_FALSE(result_called); // Ensure only one reply call. + result_called = true; + EXPECT_TRUE(reply); + }; - EncodableMap args = { - {EncodableValue("cameraId"), EncodableValue(missing_camera_id)}, - }; + plugin.PausePreview(missing_camera_id, std::move(pause_preview_result)); - plugin.HandleMethodCall( - flutter::MethodCall("pausePreview", - std::make_unique(EncodableMap(args))), - std::move(initialize_result)); + EXPECT_TRUE(result_called); } } // namespace test diff --git a/packages/camera/camera_windows/windows/test/camera_test.cpp b/packages/camera/camera_windows/windows/test/camera_test.cpp index 9ab81897254d..3aa199345c21 100644 --- a/packages/camera/camera_windows/windows/test/camera_test.cpp +++ b/packages/camera/camera_windows/windows/test/camera_test.cpp @@ -16,6 +16,7 @@ #include #include +#include "messages.g.h" #include "mocks.h" namespace camera_windows { @@ -48,17 +49,13 @@ TEST(Camera, InitCameraCreatesCaptureController) { EXPECT_TRUE(camera->GetCaptureController() == nullptr); - RecordSettings record_settings(false); - record_settings.fps = 5; - record_settings.video_bitrate = 200000; - record_settings.audio_bitrate = 32000; + PlatformMediaSettings media_settings(PlatformResolutionPreset::kMax, false); // Init camera with mock capture controller factory - bool result = - camera->InitCamera(std::move(capture_controller_factory), - std::make_unique().get(), - std::make_unique().get(), - ResolutionPreset::kAuto, record_settings); + bool result = camera->InitCamera( + std::move(capture_controller_factory), + std::make_unique().get(), + std::make_unique().get(), media_settings); EXPECT_TRUE(result); EXPECT_TRUE(camera->GetCaptureController() != nullptr); } @@ -84,438 +81,538 @@ TEST(Camera, InitCameraReportsFailure) { EXPECT_TRUE(camera->GetCaptureController() == nullptr); - RecordSettings record_settings(false); - record_settings.fps = 5; - record_settings.video_bitrate = 200000; - record_settings.audio_bitrate = 32000; + PlatformMediaSettings media_settings(PlatformResolutionPreset::kMax, false); // Init camera with mock capture controller factory - bool result = - camera->InitCamera(std::move(capture_controller_factory), - std::make_unique().get(), - std::make_unique().get(), - ResolutionPreset::kAuto, record_settings); + bool result = camera->InitCamera( + std::move(capture_controller_factory), + std::make_unique().get(), + std::make_unique().get(), media_settings); EXPECT_FALSE(result); EXPECT_TRUE(camera->GetCaptureController() != nullptr); } -TEST(Camera, AddPendingResultReturnsErrorForDuplicates) { +TEST(Camera, AddPendingVoidResultReturnsErrorForDuplicates) { std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); - std::unique_ptr first_pending_result = - std::make_unique(); - std::unique_ptr second_pending_result = - std::make_unique(); - - EXPECT_CALL(*first_pending_result, ErrorInternal).Times(0); - EXPECT_CALL(*first_pending_result, SuccessInternal); - EXPECT_CALL(*second_pending_result, ErrorInternal).Times(1); + bool first_result_called = false; + std::function)> first_pending_result = + [&first_result_called](std::optional reply) { + first_result_called = true; + }; + bool second_result_called = false; + std::function)> second_pending_result = + [&second_result_called](std::optional reply) { + second_result_called = true; + EXPECT_TRUE(reply); + }; + + camera->AddPendingVoidResult(PendingResultType::kStartRecord, + std::move(first_pending_result)); + camera->AddPendingVoidResult(PendingResultType::kStartRecord, + std::move(second_pending_result)); + + EXPECT_FALSE(first_result_called); + EXPECT_TRUE(second_result_called); +} - camera->AddPendingResult(PendingResultType::kCreateCamera, - std::move(first_pending_result)); +TEST(Camera, AddPendingIntResultReturnsErrorForDuplicates) { + std::unique_ptr camera = + std::make_unique(MOCK_DEVICE_ID); + bool first_result_called = false; + std::function)> first_pending_result = + [&first_result_called](ErrorOr reply) { + first_result_called = true; + }; + bool second_result_called = false; + std::function)> second_pending_result = + [&second_result_called](ErrorOr reply) { + second_result_called = true; + EXPECT_TRUE(reply.has_error()); + }; + + camera->AddPendingIntResult(PendingResultType::kCreateCamera, + std::move(first_pending_result)); + camera->AddPendingIntResult(PendingResultType::kCreateCamera, + std::move(second_pending_result)); + + EXPECT_FALSE(first_result_called); + EXPECT_TRUE(second_result_called); +} - // This should fail - camera->AddPendingResult(PendingResultType::kCreateCamera, - std::move(second_pending_result)); +TEST(Camera, AddPendingStringResultReturnsErrorForDuplicates) { + std::unique_ptr camera = + std::make_unique(MOCK_DEVICE_ID); + bool first_result_called = false; + std::function)> first_pending_result = + [&first_result_called](ErrorOr reply) { + first_result_called = true; + }; + bool second_result_called = false; + std::function)> second_pending_result = + [&second_result_called](ErrorOr reply) { + second_result_called = true; + EXPECT_TRUE(reply.has_error()); + }; + + camera->AddPendingStringResult(PendingResultType::kStopRecord, + std::move(first_pending_result)); + camera->AddPendingStringResult(PendingResultType::kStopRecord, + std::move(second_pending_result)); + + EXPECT_FALSE(first_result_called); + EXPECT_TRUE(second_result_called); +} - // Mark pending result as succeeded - camera->OnCreateCaptureEngineSucceeded(0); +TEST(Camera, AddPendingSizeResultReturnsErrorForDuplicates) { + std::unique_ptr camera = + std::make_unique(MOCK_DEVICE_ID); + bool first_result_called = false; + std::function)> first_pending_result = + [&first_result_called](ErrorOr reply) { + first_result_called = true; + }; + bool second_result_called = false; + std::function)> second_pending_result = + [&second_result_called](ErrorOr reply) { + second_result_called = true; + EXPECT_TRUE(reply.has_error()); + }; + + camera->AddPendingSizeResult(PendingResultType::kInitialize, + std::move(first_pending_result)); + camera->AddPendingSizeResult(PendingResultType::kInitialize, + std::move(second_pending_result)); + + EXPECT_FALSE(first_result_called); + EXPECT_TRUE(second_result_called); } TEST(Camera, OnCreateCaptureEngineSucceededReturnsCameraId) { std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); - std::unique_ptr result = - std::make_unique(); const int64_t texture_id = 12345; - EXPECT_CALL(*result, ErrorInternal).Times(0); - EXPECT_CALL( - *result, - SuccessInternal(Pointee(EncodableValue(EncodableMap( - {{EncodableValue("cameraId"), EncodableValue(texture_id)}}))))); - - camera->AddPendingResult(PendingResultType::kCreateCamera, std::move(result)); + bool result_called = false; + camera->AddPendingIntResult( + PendingResultType::kCreateCamera, + [&result_called, texture_id](ErrorOr reply) { + result_called = true; + EXPECT_FALSE(reply.has_error()); + EXPECT_EQ(reply.value(), texture_id); + }); camera->OnCreateCaptureEngineSucceeded(texture_id); + + EXPECT_TRUE(result_called); } TEST(Camera, CreateCaptureEngineReportsError) { std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); - std::unique_ptr result = - std::make_unique(); const std::string error_text = "error_text"; - EXPECT_CALL(*result, SuccessInternal).Times(0); - EXPECT_CALL(*result, ErrorInternal(Eq("camera_error"), Eq(error_text), _)); - - camera->AddPendingResult(PendingResultType::kCreateCamera, std::move(result)); + bool result_called = false; + camera->AddPendingIntResult( + PendingResultType::kCreateCamera, + [&result_called, error_text](ErrorOr reply) { + result_called = true; + EXPECT_TRUE(reply.has_error()); + EXPECT_EQ(reply.error().code(), "camera_error"); + EXPECT_EQ(reply.error().message(), error_text); + }); camera->OnCreateCaptureEngineFailed(CameraResult::kError, error_text); + + EXPECT_TRUE(result_called); } TEST(Camera, CreateCaptureEngineReportsAccessDenied) { std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); - std::unique_ptr result = - std::make_unique(); const std::string error_text = "error_text"; - EXPECT_CALL(*result, SuccessInternal).Times(0); - EXPECT_CALL(*result, - ErrorInternal(Eq("CameraAccessDenied"), Eq(error_text), _)); - - camera->AddPendingResult(PendingResultType::kCreateCamera, std::move(result)); + bool result_called = false; + camera->AddPendingIntResult( + PendingResultType::kCreateCamera, + [&result_called, error_text](ErrorOr reply) { + result_called = true; + EXPECT_TRUE(reply.has_error()); + EXPECT_EQ(reply.error().code(), "CameraAccessDenied"); + EXPECT_EQ(reply.error().message(), error_text); + }); camera->OnCreateCaptureEngineFailed(CameraResult::kAccessDenied, error_text); + + EXPECT_TRUE(result_called); } TEST(Camera, OnStartPreviewSucceededReturnsFrameSize) { std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); - std::unique_ptr result = - std::make_unique(); const int32_t width = 123; const int32_t height = 456; - EXPECT_CALL(*result, ErrorInternal).Times(0); - EXPECT_CALL( - *result, - SuccessInternal(Pointee(EncodableValue(EncodableMap({ - {EncodableValue("previewWidth"), EncodableValue((float)width)}, - {EncodableValue("previewHeight"), EncodableValue((float)height)}, - }))))); - - camera->AddPendingResult(PendingResultType::kInitialize, std::move(result)); + bool result_called = false; + camera->AddPendingSizeResult( + PendingResultType::kInitialize, + [&result_called, width, height](ErrorOr reply) { + result_called = true; + EXPECT_FALSE(reply.has_error()); + EXPECT_EQ(reply.value().width(), width); + EXPECT_EQ(reply.value().height(), height); + }); camera->OnStartPreviewSucceeded(width, height); + + EXPECT_TRUE(result_called); } TEST(Camera, StartPreviewReportsError) { std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); - std::unique_ptr result = - std::make_unique(); const std::string error_text = "error_text"; - EXPECT_CALL(*result, SuccessInternal).Times(0); - EXPECT_CALL(*result, ErrorInternal(Eq("camera_error"), Eq(error_text), _)); - - camera->AddPendingResult(PendingResultType::kInitialize, std::move(result)); + bool result_called = false; + camera->AddPendingSizeResult( + PendingResultType::kInitialize, + [&result_called, error_text](ErrorOr reply) { + result_called = true; + EXPECT_TRUE(reply.has_error()); + EXPECT_EQ(reply.error().code(), "camera_error"); + EXPECT_EQ(reply.error().message(), error_text); + }); camera->OnStartPreviewFailed(CameraResult::kError, error_text); + + EXPECT_TRUE(result_called); } TEST(Camera, StartPreviewReportsAccessDenied) { std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); - std::unique_ptr result = - std::make_unique(); const std::string error_text = "error_text"; - EXPECT_CALL(*result, SuccessInternal).Times(0); - EXPECT_CALL(*result, - ErrorInternal(Eq("CameraAccessDenied"), Eq(error_text), _)); - - camera->AddPendingResult(PendingResultType::kInitialize, std::move(result)); + bool result_called = false; + camera->AddPendingSizeResult( + PendingResultType::kInitialize, + [&result_called, error_text](ErrorOr reply) { + result_called = true; + EXPECT_TRUE(reply.has_error()); + EXPECT_EQ(reply.error().code(), "CameraAccessDenied"); + EXPECT_EQ(reply.error().message(), error_text); + }); camera->OnStartPreviewFailed(CameraResult::kAccessDenied, error_text); + + EXPECT_TRUE(result_called); } TEST(Camera, OnPausePreviewSucceededReturnsSuccess) { std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); - std::unique_ptr result = - std::make_unique(); - - EXPECT_CALL(*result, ErrorInternal).Times(0); - EXPECT_CALL(*result, SuccessInternal(nullptr)); - camera->AddPendingResult(PendingResultType::kPausePreview, std::move(result)); + bool result_called = false; + camera->AddPendingVoidResult( + PendingResultType::kPausePreview, + [&result_called](std::optional reply) { + result_called = true; + EXPECT_FALSE(reply); + }); camera->OnPausePreviewSucceeded(); + + EXPECT_TRUE(result_called); } TEST(Camera, PausePreviewReportsError) { std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); - std::unique_ptr result = - std::make_unique(); const std::string error_text = "error_text"; - EXPECT_CALL(*result, SuccessInternal).Times(0); - EXPECT_CALL(*result, ErrorInternal(Eq("camera_error"), Eq(error_text), _)); - - camera->AddPendingResult(PendingResultType::kPausePreview, std::move(result)); + bool result_called = false; + camera->AddPendingVoidResult( + PendingResultType::kPausePreview, + [&result_called, error_text](std::optional reply) { + result_called = true; + EXPECT_TRUE(reply); + EXPECT_EQ(reply.value().code(), "camera_error"); + EXPECT_EQ(reply.value().message(), error_text); + }); camera->OnPausePreviewFailed(CameraResult::kError, error_text); + + EXPECT_TRUE(result_called); } TEST(Camera, PausePreviewReportsAccessDenied) { std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); - std::unique_ptr result = - std::make_unique(); const std::string error_text = "error_text"; - EXPECT_CALL(*result, SuccessInternal).Times(0); - EXPECT_CALL(*result, - ErrorInternal(Eq("CameraAccessDenied"), Eq(error_text), _)); - - camera->AddPendingResult(PendingResultType::kPausePreview, std::move(result)); + bool result_called = false; + camera->AddPendingVoidResult( + PendingResultType::kPausePreview, + [&result_called, error_text](std::optional reply) { + result_called = true; + EXPECT_TRUE(reply); + EXPECT_EQ(reply.value().code(), "CameraAccessDenied"); + EXPECT_EQ(reply.value().message(), error_text); + }); camera->OnPausePreviewFailed(CameraResult::kAccessDenied, error_text); + + EXPECT_TRUE(result_called); } TEST(Camera, OnResumePreviewSucceededReturnsSuccess) { std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); - std::unique_ptr result = - std::make_unique(); - EXPECT_CALL(*result, ErrorInternal).Times(0); - EXPECT_CALL(*result, SuccessInternal(nullptr)); - - camera->AddPendingResult(PendingResultType::kResumePreview, - std::move(result)); + bool result_called = false; + camera->AddPendingVoidResult( + PendingResultType::kResumePreview, + [&result_called](std::optional reply) { + result_called = true; + EXPECT_FALSE(reply); + }); camera->OnResumePreviewSucceeded(); + + EXPECT_TRUE(result_called); } TEST(Camera, ResumePreviewReportsError) { std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); - std::unique_ptr result = - std::make_unique(); const std::string error_text = "error_text"; - EXPECT_CALL(*result, SuccessInternal).Times(0); - EXPECT_CALL(*result, ErrorInternal(Eq("camera_error"), Eq(error_text), _)); - - camera->AddPendingResult(PendingResultType::kResumePreview, - std::move(result)); + bool result_called = false; + camera->AddPendingVoidResult( + PendingResultType::kResumePreview, + [&result_called, error_text](std::optional reply) { + result_called = true; + EXPECT_TRUE(reply); + EXPECT_EQ(reply.value().code(), "camera_error"); + EXPECT_EQ(reply.value().message(), error_text); + }); camera->OnResumePreviewFailed(CameraResult::kError, error_text); + + EXPECT_TRUE(result_called); } TEST(Camera, OnResumePreviewPermissionFailureReturnsError) { std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); - std::unique_ptr result = - std::make_unique(); const std::string error_text = "error_text"; - EXPECT_CALL(*result, SuccessInternal).Times(0); - EXPECT_CALL(*result, - ErrorInternal(Eq("CameraAccessDenied"), Eq(error_text), _)); - - camera->AddPendingResult(PendingResultType::kResumePreview, - std::move(result)); + bool result_called = false; + camera->AddPendingVoidResult( + PendingResultType::kResumePreview, + [&result_called, error_text](std::optional reply) { + result_called = true; + EXPECT_TRUE(reply); + EXPECT_EQ(reply.value().code(), "CameraAccessDenied"); + EXPECT_EQ(reply.value().message(), error_text); + }); camera->OnResumePreviewFailed(CameraResult::kAccessDenied, error_text); + + EXPECT_TRUE(result_called); } TEST(Camera, OnStartRecordSucceededReturnsSuccess) { std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); - std::unique_ptr result = - std::make_unique(); - - EXPECT_CALL(*result, ErrorInternal).Times(0); - EXPECT_CALL(*result, SuccessInternal(nullptr)); - camera->AddPendingResult(PendingResultType::kStartRecord, std::move(result)); + bool result_called = false; + camera->AddPendingVoidResult( + PendingResultType::kStartRecord, + [&result_called](std::optional reply) { + result_called = true; + EXPECT_FALSE(reply); + }); camera->OnStartRecordSucceeded(); + + EXPECT_TRUE(result_called); } TEST(Camera, StartRecordReportsError) { std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); - std::unique_ptr result = - std::make_unique(); const std::string error_text = "error_text"; - EXPECT_CALL(*result, SuccessInternal).Times(0); - EXPECT_CALL(*result, ErrorInternal(Eq("camera_error"), Eq(error_text), _)); - - camera->AddPendingResult(PendingResultType::kStartRecord, std::move(result)); + bool result_called = false; + camera->AddPendingVoidResult( + PendingResultType::kStartRecord, + [&result_called, error_text](std::optional reply) { + result_called = true; + EXPECT_TRUE(reply); + EXPECT_EQ(reply.value().code(), "camera_error"); + EXPECT_EQ(reply.value().message(), error_text); + }); camera->OnStartRecordFailed(CameraResult::kError, error_text); + + EXPECT_TRUE(result_called); } TEST(Camera, StartRecordReportsAccessDenied) { std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); - std::unique_ptr result = - std::make_unique(); const std::string error_text = "error_text"; - EXPECT_CALL(*result, SuccessInternal).Times(0); - EXPECT_CALL(*result, - ErrorInternal(Eq("CameraAccessDenied"), Eq(error_text), _)); - - camera->AddPendingResult(PendingResultType::kStartRecord, std::move(result)); + bool result_called = false; + camera->AddPendingVoidResult( + PendingResultType::kStartRecord, + [&result_called, error_text](std::optional reply) { + result_called = true; + EXPECT_TRUE(reply); + EXPECT_EQ(reply.value().code(), "CameraAccessDenied"); + EXPECT_EQ(reply.value().message(), error_text); + }); camera->OnStartRecordFailed(CameraResult::kAccessDenied, error_text); + + EXPECT_TRUE(result_called); } TEST(Camera, OnStopRecordSucceededReturnsSuccess) { std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); - std::unique_ptr result = - std::make_unique(); const std::string file_path = "C:\temp\filename.mp4"; - EXPECT_CALL(*result, ErrorInternal).Times(0); - EXPECT_CALL(*result, SuccessInternal(Pointee(EncodableValue(file_path)))); - - camera->AddPendingResult(PendingResultType::kStopRecord, std::move(result)); + bool result_called = false; + camera->AddPendingStringResult( + PendingResultType::kStopRecord, + [&result_called, file_path](ErrorOr reply) { + result_called = true; + EXPECT_FALSE(reply.has_error()); + EXPECT_EQ(reply.value(), file_path); + }); camera->OnStopRecordSucceeded(file_path); + + EXPECT_TRUE(result_called); } TEST(Camera, StopRecordReportsError) { std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); - std::unique_ptr result = - std::make_unique(); const std::string error_text = "error_text"; - EXPECT_CALL(*result, SuccessInternal).Times(0); - EXPECT_CALL(*result, ErrorInternal(Eq("camera_error"), Eq(error_text), _)); - - camera->AddPendingResult(PendingResultType::kStopRecord, std::move(result)); + bool result_called = false; + camera->AddPendingStringResult( + PendingResultType::kStopRecord, + [&result_called, error_text](ErrorOr reply) { + result_called = true; + EXPECT_TRUE(reply.has_error()); + EXPECT_EQ(reply.error().code(), "camera_error"); + EXPECT_EQ(reply.error().message(), error_text); + }); camera->OnStopRecordFailed(CameraResult::kError, error_text); + + EXPECT_TRUE(result_called); } TEST(Camera, StopRecordReportsAccessDenied) { std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); - std::unique_ptr result = - std::make_unique(); const std::string error_text = "error_text"; - EXPECT_CALL(*result, SuccessInternal).Times(0); - EXPECT_CALL(*result, - ErrorInternal(Eq("CameraAccessDenied"), Eq(error_text), _)); - - camera->AddPendingResult(PendingResultType::kStopRecord, std::move(result)); + bool result_called = false; + camera->AddPendingStringResult( + PendingResultType::kStopRecord, + [&result_called, error_text](ErrorOr reply) { + result_called = true; + EXPECT_TRUE(reply.has_error()); + EXPECT_EQ(reply.error().code(), "CameraAccessDenied"); + EXPECT_EQ(reply.error().message(), error_text); + }); camera->OnStopRecordFailed(CameraResult::kAccessDenied, error_text); + + EXPECT_TRUE(result_called); } TEST(Camera, OnTakePictureSucceededReturnsSuccess) { std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); - std::unique_ptr result = - std::make_unique(); const std::string file_path = "C:\\temp\\filename.jpeg"; - EXPECT_CALL(*result, ErrorInternal).Times(0); - EXPECT_CALL(*result, SuccessInternal(Pointee(EncodableValue(file_path)))); - - camera->AddPendingResult(PendingResultType::kTakePicture, std::move(result)); + bool result_called = false; + camera->AddPendingStringResult( + PendingResultType::kTakePicture, + [&result_called, file_path](ErrorOr reply) { + result_called = true; + EXPECT_FALSE(reply.has_error()); + EXPECT_EQ(reply.value(), file_path); + }); camera->OnTakePictureSucceeded(file_path); + + EXPECT_TRUE(result_called); } TEST(Camera, TakePictureReportsError) { std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); - std::unique_ptr result = - std::make_unique(); const std::string error_text = "error_text"; - EXPECT_CALL(*result, SuccessInternal).Times(0); - EXPECT_CALL(*result, ErrorInternal(Eq("camera_error"), Eq(error_text), _)); - - camera->AddPendingResult(PendingResultType::kTakePicture, std::move(result)); + bool result_called = false; + camera->AddPendingStringResult( + PendingResultType::kTakePicture, + [&result_called, error_text](ErrorOr reply) { + result_called = true; + EXPECT_TRUE(reply.has_error()); + EXPECT_EQ(reply.error().code(), "camera_error"); + EXPECT_EQ(reply.error().message(), error_text); + }); camera->OnTakePictureFailed(CameraResult::kError, error_text); + + EXPECT_TRUE(result_called); } TEST(Camera, TakePictureReportsAccessDenied) { std::unique_ptr camera = std::make_unique(MOCK_DEVICE_ID); - std::unique_ptr result = - std::make_unique(); const std::string error_text = "error_text"; - EXPECT_CALL(*result, SuccessInternal).Times(0); - EXPECT_CALL(*result, - ErrorInternal(Eq("CameraAccessDenied"), Eq(error_text), _)); - - camera->AddPendingResult(PendingResultType::kTakePicture, std::move(result)); + bool result_called = false; + camera->AddPendingStringResult( + PendingResultType::kTakePicture, + [&result_called, error_text](ErrorOr reply) { + result_called = true; + EXPECT_TRUE(reply.has_error()); + EXPECT_EQ(reply.error().code(), "CameraAccessDenied"); + EXPECT_EQ(reply.error().message(), error_text); + }); camera->OnTakePictureFailed(CameraResult::kAccessDenied, error_text); -} - -TEST(Camera, OnVideoRecordSucceededInvokesCameraChannelEvent) { - std::unique_ptr camera = - std::make_unique(MOCK_DEVICE_ID); - std::unique_ptr capture_controller_factory = - std::make_unique(); - - std::unique_ptr binary_messenger = - std::make_unique(); - - const std::string file_path = "C:\\temp\\filename.mp4"; - const int64_t camera_id = 12345; - std::string camera_channel = - std::string("plugins.flutter.io/camera_windows/camera") + - std::to_string(camera_id); - const int64_t video_duration = 1000000; - - EXPECT_CALL(*capture_controller_factory, CreateCaptureController) - .Times(1) - .WillOnce( - []() { return std::make_unique>(); }); - - // TODO: test binary content. - // First time is video record success message, - // and second is camera closing message. - EXPECT_CALL(*binary_messenger, Send(Eq(camera_channel), _, _, _)).Times(2); - - RecordSettings record_settings; - record_settings.record_audio = false; - record_settings.fps = 5; - record_settings.video_bitrate = 200000; - record_settings.audio_bitrate = 32000; - - // Init camera with mock capture controller factory - camera->InitCamera(std::move(capture_controller_factory), - std::make_unique().get(), - binary_messenger.get(), ResolutionPreset::kAuto, - record_settings); - - // Pass camera id for camera - camera->OnCreateCaptureEngineSucceeded(camera_id); - - camera->OnVideoRecordSucceeded(file_path, video_duration); - // Dispose camera before message channel. - camera = nullptr; + EXPECT_TRUE(result_called); } } // namespace test diff --git a/packages/camera/camera_windows/windows/test/capture_controller_test.cpp b/packages/camera/camera_windows/windows/test/capture_controller_test.cpp index 145879bae97b..aa0b5469b851 100644 --- a/packages/camera/camera_windows/windows/test/capture_controller_test.cpp +++ b/packages/camera/camera_windows/windows/test/capture_controller_test.cpp @@ -33,7 +33,8 @@ void MockInitCaptureController( CaptureControllerImpl* capture_controller, MockTextureRegistrar* texture_registrar, MockCaptureEngine* engine, MockCamera* camera, int64_t mock_texture_id, - const RecordSettings record_settings = RecordSettings(true)) { + const PlatformMediaSettings media_settings = + PlatformMediaSettings(PlatformResolutionPreset::kMax, true)) { ComPtr video_source = new MockMediaSource(); ComPtr audio_source = new MockMediaSource(); @@ -61,8 +62,7 @@ void MockInitCaptureController( EXPECT_CALL(*engine, Initialize).Times(1); bool result = capture_controller->InitCaptureDevice( - texture_registrar, MOCK_DEVICE_ID, ResolutionPreset::kAuto, - record_settings); + texture_registrar, MOCK_DEVICE_ID, media_settings); EXPECT_TRUE(result); @@ -213,7 +213,7 @@ void MockRecordStart(CaptureControllerImpl* capture_controller, EXPECT_CALL(*record_sink, AddStream).Times(2).WillRepeatedly(Return(S_OK)); EXPECT_CALL(*record_sink, SetOutputFileName).Times(1).WillOnce(Return(S_OK)); - capture_controller->StartRecord(mock_path_to_video, -1); + capture_controller->StartRecord(mock_path_to_video); EXPECT_CALL(*camera, OnStartRecordSucceeded()).Times(1); engine->CreateFakeEvent(S_OK, MF_CAPTURE_ENGINE_RECORD_STARTED); @@ -260,8 +260,8 @@ TEST(CaptureController, InitCaptureEngineCanOnlyBeCalledOnce) { EXPECT_CALL(*camera, OnCreateCaptureEngineFailed).Times(1); bool result = capture_controller->InitCaptureDevice( - texture_registrar.get(), MOCK_DEVICE_ID, ResolutionPreset::kAuto, - RecordSettings(true)); + texture_registrar.get(), MOCK_DEVICE_ID, + PlatformMediaSettings(PlatformResolutionPreset::kMax, true)); EXPECT_FALSE(result); @@ -302,8 +302,8 @@ TEST(CaptureController, InitCaptureEngineReportsFailure) { .Times(1); bool result = capture_controller->InitCaptureDevice( - texture_registrar.get(), MOCK_DEVICE_ID, ResolutionPreset::kAuto, - RecordSettings(true)); + texture_registrar.get(), MOCK_DEVICE_ID, + PlatformMediaSettings(PlatformResolutionPreset::kMax, true)); EXPECT_FALSE(result); EXPECT_FALSE(engine->initialized_); @@ -347,8 +347,8 @@ TEST(CaptureController, InitCaptureEngineReportsAccessDenied) { .Times(1); bool result = capture_controller->InitCaptureDevice( - texture_registrar.get(), MOCK_DEVICE_ID, ResolutionPreset::kAuto, - RecordSettings(true)); + texture_registrar.get(), MOCK_DEVICE_ID, + PlatformMediaSettings(PlatformResolutionPreset::kMax, true)); EXPECT_FALSE(result); EXPECT_FALSE(engine->initialized_); @@ -734,16 +734,15 @@ TEST(CaptureController, StartRecordWithSettingsSuccess) { const auto kVideoBitrate = 200000; const auto kAudioBitrate = 32000; - RecordSettings record_settings; - record_settings.record_audio = true; - record_settings.fps = kFps; - record_settings.video_bitrate = kVideoBitrate; - record_settings.audio_bitrate = kAudioBitrate; + PlatformMediaSettings media_settings(PlatformResolutionPreset::kMax, true); + media_settings.set_frames_per_second(kFps); + media_settings.set_video_bitrate(kVideoBitrate); + media_settings.set_audio_bitrate(kAudioBitrate); // Initialize capture controller to be able to start preview MockInitCaptureController(capture_controller.get(), texture_registrar.get(), engine.Get(), camera.get(), mock_texture_id, - record_settings); + media_settings); ComPtr capture_source = new MockCaptureSource(); @@ -790,7 +789,7 @@ TEST(CaptureController, StartRecordWithSettingsSuccess) { .Times(1) .WillOnce(Return(S_OK)); - capture_controller->StartRecord(mock_path_to_video, -1); + capture_controller->StartRecord(mock_path_to_video); EXPECT_CALL(*camera, OnStartRecordSucceeded()).Times(1); engine->CreateFakeEvent(S_OK, MF_CAPTURE_ENGINE_RECORD_STARTED); @@ -840,7 +839,7 @@ TEST(CaptureController, ReportsStartRecordError) { Eq("Failed to start video recording"))) .Times(1); - capture_controller->StartRecord("mock_path", -1); + capture_controller->StartRecord("mock_path"); capture_controller = nullptr; texture_registrar = nullptr; @@ -881,7 +880,7 @@ TEST(CaptureController, ReportsStartRecordAccessDenied) { Eq("Failed to start video recording"))) .Times(1); - capture_controller->StartRecord("mock_path", -1); + capture_controller->StartRecord("mock_path"); capture_controller = nullptr; texture_registrar = nullptr; @@ -934,7 +933,7 @@ TEST(CaptureController, ReportsStartRecordErrorEvent) { .Times(1) .WillOnce(Return(S_OK)); - capture_controller->StartRecord(mock_path_to_video, -1); + capture_controller->StartRecord(mock_path_to_video); // Send a start record failed event EXPECT_CALL(*camera, OnStartRecordSucceeded).Times(0); @@ -1000,7 +999,7 @@ TEST(CaptureController, ReportsStartRecordAccessDeniedEvent) { .WillOnce(Return(S_OK)); // Send a start record failed event - capture_controller->StartRecord(mock_path_to_video, -1); + capture_controller->StartRecord(mock_path_to_video); EXPECT_CALL(*camera, OnStartRecordSucceeded).Times(0); EXPECT_CALL(*camera, OnStartRecordFailed(Eq(CameraResult::kAccessDenied), diff --git a/packages/camera/camera_windows/windows/test/mocks.h b/packages/camera/camera_windows/windows/test/mocks.h index 1f71a0e4d5dc..4a05ef822969 100644 --- a/packages/camera/camera_windows/windows/test/mocks.h +++ b/packages/camera/camera_windows/windows/test/mocks.h @@ -13,6 +13,8 @@ #include #include +#include + #include "camera.h" #include "camera_plugin.h" #include "capture_controller.h" @@ -28,19 +30,6 @@ using flutter::EncodableMap; using flutter::EncodableValue; using ::testing::_; -class MockMethodResult : public flutter::MethodResult<> { - public: - ~MockMethodResult() = default; - - MOCK_METHOD(void, SuccessInternal, (const EncodableValue* result), - (override)); - MOCK_METHOD(void, ErrorInternal, - (const std::string& error_code, const std::string& error_message, - const EncodableValue* details), - (override)); - MOCK_METHOD(void, NotImplementedInternal, (), (override)); -}; - class MockBinaryMessenger : public flutter::BinaryMessenger { public: ~MockBinaryMessenger() = default; @@ -141,7 +130,7 @@ class MockCameraFactory : public CameraFactory { class MockCamera : public Camera { public: MockCamera(const std::string& device_id) - : device_id_(device_id), Camera(device_id){}; + : device_id_(device_id), Camera(device_id) {} ~MockCamera() = default; @@ -183,19 +172,27 @@ class MockCamera : public Camera { MOCK_METHOD(void, OnTakePictureFailed, (CameraResult result, const std::string& error), (override)); - MOCK_METHOD(void, OnVideoRecordSucceeded, - (const std::string& file_path, int64_t video_duration), - (override)); - MOCK_METHOD(void, OnVideoRecordFailed, - (CameraResult result, const std::string& error), (override)); MOCK_METHOD(void, OnCaptureError, (CameraResult result, const std::string& error), (override)); MOCK_METHOD(bool, HasDeviceId, (std::string & device_id), (const override)); MOCK_METHOD(bool, HasCameraId, (int64_t camera_id), (const override)); - MOCK_METHOD(bool, AddPendingResult, - (PendingResultType type, std::unique_ptr> result), + MOCK_METHOD(bool, AddPendingVoidResult, + (PendingResultType type, + std::function reply)> result), + (override)); + MOCK_METHOD(bool, AddPendingIntResult, + (PendingResultType type, + std::function reply)> result), + (override)); + MOCK_METHOD(bool, AddPendingStringResult, + (PendingResultType type, + std::function reply)> result), + (override)); + MOCK_METHOD(bool, AddPendingSizeResult, + (PendingResultType type, + std::function reply)> result), (override)); MOCK_METHOD(bool, HasPendingResultByType, (PendingResultType type), (const override)); @@ -206,19 +203,21 @@ class MockCamera : public Camera { MOCK_METHOD(bool, InitCamera, (flutter::TextureRegistrar * texture_registrar, flutter::BinaryMessenger* messenger, - ResolutionPreset resolution_preset, - const RecordSettings& record_settings), + const PlatformMediaSettings& media_settings), (override)); std::unique_ptr capture_controller_; - std::unique_ptr> pending_result_; + std::function reply)> pending_void_result_; + std::function reply)> pending_int_result_; + std::function reply)> pending_string_result_; + std::function reply)> pending_size_result_; std::string device_id_; int64_t camera_id_ = -1; }; class MockCaptureControllerFactory : public CaptureControllerFactory { public: - MockCaptureControllerFactory(){}; + MockCaptureControllerFactory() {} virtual ~MockCaptureControllerFactory() = default; // Disallow copy and move. @@ -236,8 +235,8 @@ class MockCaptureController : public CaptureController { MOCK_METHOD(bool, InitCaptureDevice, (flutter::TextureRegistrar * texture_registrar, - const std::string& device_id, ResolutionPreset resolution_preset, - const RecordSettings& record_settings), + const std::string& device_id, + const PlatformMediaSettings& media_settings), (override)); MOCK_METHOD(uint32_t, GetPreviewWidth, (), (const override)); @@ -247,9 +246,7 @@ class MockCaptureController : public CaptureController { MOCK_METHOD(void, StartPreview, (), (override)); MOCK_METHOD(void, ResumePreview, (), (override)); MOCK_METHOD(void, PausePreview, (), (override)); - MOCK_METHOD(void, StartRecord, - (const std::string& file_path, int64_t max_video_duration_ms), - (override)); + MOCK_METHOD(void, StartRecord, (const std::string& file_path), (override)); MOCK_METHOD(void, StopRecord, (), (override)); MOCK_METHOD(void, TakePicture, (const std::string& file_path), (override)); }; @@ -261,14 +258,14 @@ class MockCameraPlugin : public CameraPlugin { public: MockCameraPlugin(flutter::TextureRegistrar* texture_registrar, flutter::BinaryMessenger* messenger) - : CameraPlugin(texture_registrar, messenger){}; + : CameraPlugin(texture_registrar, messenger) {} // Creates a plugin instance with the given CameraFactory instance. // Exists for unit testing with mock implementations. MockCameraPlugin(flutter::TextureRegistrar* texture_registrar, flutter::BinaryMessenger* messenger, std::unique_ptr camera_factory) - : CameraPlugin(texture_registrar, messenger, std::move(camera_factory)){}; + : CameraPlugin(texture_registrar, messenger, std::move(camera_factory)) {} ~MockCameraPlugin() = default; @@ -288,7 +285,7 @@ class MockCameraPlugin : public CameraPlugin { class MockCaptureSource : public IMFCaptureSource { public: - MockCaptureSource(){}; + MockCaptureSource() {} ~MockCaptureSource() = default; // IUnknown @@ -355,7 +352,7 @@ class MockCaptureSource : public IMFCaptureSource { // Uses IMFMediaSourceEx which has SetD3DManager method. class MockMediaSource : public IMFMediaSourceEx { public: - MockMediaSource(){}; + MockMediaSource() {} ~MockMediaSource() = default; // IUnknown @@ -851,7 +848,7 @@ class FakeMediaType : public FakeIMFAttributesBase { : major_type_(major_type), sub_type_(sub_type), width_(width), - height_(height){}; + height_(height) {} // IMFAttributes HRESULT GetUINT64(REFGUID key, UINT64* value) override { diff --git a/packages/cross_file/CHANGELOG.md b/packages/cross_file/CHANGELOG.md index 1ca705da8a33..016abd18b62a 100644 --- a/packages/cross_file/CHANGELOG.md +++ b/packages/cross_file/CHANGELOG.md @@ -1,6 +1,10 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + +## 0.3.4+2 + +* Adds support for `web: ^1.0.0`. ## 0.3.4+1 diff --git a/packages/cross_file/example/pubspec.yaml b/packages/cross_file/example/pubspec.yaml index cfcc8e3a9a5a..5e12d44dc13f 100644 --- a/packages/cross_file/example/pubspec.yaml +++ b/packages/cross_file/example/pubspec.yaml @@ -3,7 +3,7 @@ description: Demonstrates how to use cross files. publish_to: none environment: - sdk: ^3.2.0 + sdk: ^3.3.0 dependencies: cross_file: diff --git a/packages/cross_file/pubspec.yaml b/packages/cross_file/pubspec.yaml index cf8f9ca7d447..0de3c0cfa24a 100644 --- a/packages/cross_file/pubspec.yaml +++ b/packages/cross_file/pubspec.yaml @@ -2,14 +2,14 @@ name: cross_file description: An abstraction to allow working with files across multiple platforms. repository: https://github.com/flutter/packages/tree/main/packages/cross_file issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+cross_file%22 -version: 0.3.4+1 +version: 0.3.4+2 environment: sdk: ^3.3.0 dependencies: meta: ^1.3.0 - web: ^0.5.0 + web: ">=0.5.1 <2.0.0" dev_dependencies: path: ^1.8.1 diff --git a/packages/css_colors/CHANGELOG.md b/packages/css_colors/CHANGELOG.md index abcb748b9470..5f464a2c0730 100644 --- a/packages/css_colors/CHANGELOG.md +++ b/packages/css_colors/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 1.1.5 diff --git a/packages/css_colors/pubspec.yaml b/packages/css_colors/pubspec.yaml index 962c5279a945..a8e646c95b8e 100644 --- a/packages/css_colors/pubspec.yaml +++ b/packages/css_colors/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 1.1.5 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/espresso/CHANGELOG.md b/packages/espresso/CHANGELOG.md index ef94d473802c..aedffb8547c1 100644 --- a/packages/espresso/CHANGELOG.md +++ b/packages/espresso/CHANGELOG.md @@ -1,3 +1,22 @@ +## 0.4.0+3 + +* Updates Java compatibility version to 11. +* Updates minimum supported SDK version to Flutter 3.24/Dart 3.5. + +## 0.4.0+2 + +* Bumps `com.google.guava:guava` from `31.1` to `33.3.1`. + +## 0.4.0+1 + +* Updates lint checks to ignore NewerVersionAvailable. + +## 0.4.0 + +* Updates androidx.test.espresso version to 3.6.1. +* Updates androidx.test to 1.6.1. +* Removes androidx.test.annotation.ExperimentalTestApi. + ## 0.3.0+10 * Removes additional references to v1 Android embedding. diff --git a/packages/espresso/README.md b/packages/espresso/README.md index 95c72e334423..0e0d7880a9dc 100644 --- a/packages/espresso/README.md +++ b/packages/espresso/README.md @@ -19,9 +19,9 @@ Add the following dependencies in android/app/build.gradle: ```groovy dependencies { testImplementation 'junit:junit:4.13.2' - testImplementation "com.google.truth:truth:1.0" - androidTestImplementation 'androidx.test:runner:1.1.1' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' + testImplementation "com.google.truth:truth:1.1.3" + androidTestImplementation 'androidx.test:runner:1.6.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' api 'androidx.test:core:1.2.0' } ``` diff --git a/packages/espresso/android/build.gradle b/packages/espresso/android/build.gradle index 18f4f6bb2e9e..9f54c535f0af 100644 --- a/packages/espresso/android/build.gradle +++ b/packages/espresso/android/build.gradle @@ -22,10 +22,7 @@ rootProject.allprojects { apply plugin: 'com.android.library' android { - // Conditional for compatibility with AGP <4.2. - if (project.android.hasProperty("namespace")) { - namespace 'com.example.espresso' - } + namespace 'com.example.espresso' compileSdk 34 defaultConfig { @@ -34,14 +31,14 @@ android { } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } lintOptions { checkAllWarnings true warningsAsErrors true - disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency' + disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency', 'NewerVersionAvailable' baseline file("lint-baseline.xml") } @@ -60,41 +57,40 @@ android { } dependencies { - implementation 'com.google.guava:guava:31.1-android' + implementation 'com.google.guava:guava:33.3.1-android' implementation 'com.squareup.okhttp3:okhttp:4.11.0' implementation 'com.google.code.gson:gson:2.10.1' androidTestImplementation 'org.hamcrest:hamcrest:2.2' testImplementation 'junit:junit:4.13.2' testImplementation "com.google.truth:truth:1.1.3" - api 'androidx.test:runner:1.1.1' - api 'androidx.test.espresso:espresso-core:3.5.1' + api 'androidx.test.espresso:espresso-core:3.6.1' // Core library - api 'androidx.test:core:1.0.0' + api 'androidx.test:core:1.6.1' // AndroidJUnitRunner and JUnit Rules - api 'androidx.test:runner:1.1.0' - api 'androidx.test:rules:1.1.0' + api 'androidx.test:runner:1.6.1' + api 'androidx.test:rules:1.6.1' // Assertions - api 'androidx.test.ext:junit:1.1.5' - api 'androidx.test.ext:truth:1.5.0' + api 'androidx.test.ext:junit:1.2.1' + api 'androidx.test.ext:truth:1.6.0' api 'com.google.truth:truth:1.1.3' // Espresso dependencies - api 'androidx.test.espresso:espresso-core:3.5.1' - api 'androidx.test.espresso:espresso-contrib:3.5.1' - api 'androidx.test.espresso:espresso-intents:3.5.1' - api 'androidx.test.espresso:espresso-accessibility:3.5.1' - api 'androidx.test.espresso:espresso-web:3.5.1' - api 'androidx.test.espresso.idling:idling-concurrent:3.5.1' + api 'androidx.test.espresso:espresso-core:3.6.1' + api 'androidx.test.espresso:espresso-contrib:3.6.1' + api 'androidx.test.espresso:espresso-intents:3.6.1' + api 'androidx.test.espresso:espresso-accessibility:3.6.1' + api 'androidx.test.espresso:espresso-web:3.6.1' + api 'androidx.test.espresso.idling:idling-concurrent:3.6.1' // The following Espresso dependency can be either "implementation" // or "androidTestImplementation", depending on whether you want the // dependency to appear on your APK's compile classpath or the test APK // classpath. - api 'androidx.test.espresso:espresso-idling-resource:3.5.1' + api 'androidx.test.espresso:espresso-idling-resource:3.6.1' } diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/EspressoFlutter.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/EspressoFlutter.java index f8644a8e5488..d809d760c6bb 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/EspressoFlutter.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/EspressoFlutter.java @@ -12,7 +12,6 @@ import android.util.Log; import android.view.View; -import androidx.test.annotation.ExperimentalTestApi; import androidx.test.espresso.UiController; import androidx.test.espresso.ViewAction; import androidx.test.espresso.flutter.action.FlutterViewAction; @@ -100,7 +99,6 @@ private WidgetInteraction( * @param widgetActions one or more actions that shall be performed. Cannot be {@code null}. * @return this interaction for further perform/verification calls. */ - @ExperimentalTestApi() public WidgetInteraction perform(@Nonnull final WidgetAction... widgetActions) { checkNotNull(widgetActions); for (WidgetAction widgetAction : widgetActions) { @@ -117,7 +115,6 @@ public WidgetInteraction perform(@Nonnull final WidgetAction... widgetActions) { * @param assertion a widget assertion that shall be made on the matched Flutter widget. Cannot * be {@code null}. */ - @ExperimentalTestApi() public WidgetInteraction check(@Nonnull WidgetAssertion assertion) { checkNotNull( assertion, @@ -133,7 +130,6 @@ public WidgetInteraction check(@Nonnull WidgetAssertion assertion) { return this; } - @ExperimentalTestApi() @SuppressWarnings("unchecked") private T performInternal(FlutterAction flutterAction) { checkNotNull( diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterActions.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterActions.java index 1bc41f01fa60..2f0c171e780d 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterActions.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterActions.java @@ -4,7 +4,6 @@ package androidx.test.espresso.flutter.action; -import androidx.test.annotation.ExperimentalTestApi; import androidx.test.espresso.flutter.api.WidgetAction; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -44,7 +43,6 @@ public static WidgetAction click() { * by directly injecting key events to the Android system. Uses this {@link #syntheticClick()} * only when there are special cases that {@link #click()} cannot handle properly. */ - @ExperimentalTestApi() public static WidgetAction syntheticClick() { return new SyntheticClickAction(); } diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterViewAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterViewAction.java index d18ced460268..ce7f49610275 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterViewAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterViewAction.java @@ -13,7 +13,6 @@ import android.os.Looper; import android.view.View; -import androidx.test.annotation.ExperimentalTestApi; import androidx.test.espresso.IdlingRegistry; import androidx.test.espresso.IdlingResource; import androidx.test.espresso.UiController; @@ -96,7 +95,6 @@ public String getDescription() { "Perform a %s action on the Flutter widget matched %s.", widgetAction, widgetMatcher); } - @ExperimentalTestApi @Override public void perform(UiController uiController, View view) { checkNotNull(view, "The Flutter View instance cannot be null."); @@ -143,7 +141,6 @@ public ListenableFuture apply(Void readyResult) { } } - @ExperimentalTestApi @VisibleForTesting void perform( View flutterView, FlutterTestingProtocol flutterTestingProtocol, UiController uiController) { diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/SyntheticClickAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/SyntheticClickAction.java index 270d4e43b880..54d7d8012847 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/SyntheticClickAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/SyntheticClickAction.java @@ -5,7 +5,6 @@ package androidx.test.espresso.flutter.action; import android.view.View; -import androidx.test.annotation.ExperimentalTestApi; import androidx.test.espresso.UiController; import androidx.test.espresso.flutter.api.FlutterTestingProtocol; import androidx.test.espresso.flutter.api.SyntheticAction; @@ -23,7 +22,6 @@ */ public final class SyntheticClickAction implements WidgetAction { - @ExperimentalTestApi @Override public Future perform( @Nullable WidgetMatcher targetWidget, diff --git a/packages/espresso/example/android/app/build.gradle b/packages/espresso/example/android/app/build.gradle index 6deacadd65c6..84b682fdb760 100644 --- a/packages/espresso/example/android/app/build.gradle +++ b/packages/espresso/example/android/app/build.gradle @@ -32,11 +32,10 @@ android { defaultConfig { minSdkVersion flutter.minSdkVersion - targetSdkVersion 29 + targetSdkVersion 34 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - multiDexEnabled true } buildTypes { @@ -62,28 +61,28 @@ dependencies { implementation "androidx.multidex:multidex:2.0.1" // Core library - api 'androidx.test:core:1.2.0' + api 'androidx.test:core:1.6.1' // AndroidJUnitRunner and JUnit Rules - androidTestImplementation 'androidx.test:runner:1.2.0' - androidTestImplementation 'androidx.test:rules:1.1.0' + androidTestImplementation 'androidx.test:runner:1.6.1' + androidTestImplementation 'androidx.test:rules:1.6.1' // Assertions - androidTestImplementation 'androidx.test.ext:junit:1.0.0' - androidTestImplementation 'androidx.test.ext:truth:1.0.0' + androidTestImplementation 'androidx.test.ext:junit:1.2.1' + androidTestImplementation 'androidx.test.ext:truth:1.6.0' androidTestImplementation 'com.google.truth:truth:1.1.3' // Espresso dependencies - androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' - androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.1.0' - androidTestImplementation 'androidx.test.espresso:espresso-intents:3.1.0' - androidTestImplementation 'androidx.test.espresso:espresso-accessibility:3.1.0' - androidTestImplementation 'androidx.test.espresso:espresso-web:3.1.0' - androidTestImplementation 'androidx.test.espresso.idling:idling-concurrent:3.1.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' + androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.6.1' + androidTestImplementation 'androidx.test.espresso:espresso-intents:3.6.1' + androidTestImplementation 'androidx.test.espresso:espresso-accessibility:3.6.1' + androidTestImplementation 'androidx.test.espresso:espresso-web:3.6.1' + androidTestImplementation 'androidx.test.espresso.idling:idling-concurrent:3.6.1' // The following Espresso dependency can be either "implementation" // or "androidTestImplementation", depending on whether you want the // dependency to appear on your APK's compile classpath or the test APK // classpath. - androidTestImplementation 'androidx.test.espresso:espresso-idling-resource:3.1.0' + androidTestImplementation 'androidx.test.espresso:espresso-idling-resource:3.6.1' } diff --git a/packages/espresso/example/android/app/src/main/AndroidManifest.xml b/packages/espresso/example/android/app/src/main/AndroidManifest.xml index 0c7891fd04ef..0ed1d9e02dba 100644 --- a/packages/espresso/example/android/app/src/main/AndroidManifest.xml +++ b/packages/espresso/example/android/app/src/main/AndroidManifest.xml @@ -5,6 +5,7 @@ android:icon="@mipmap/ic_launcher"> =3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" dependencies: flutter: diff --git a/packages/espresso/pubspec.yaml b/packages/espresso/pubspec.yaml index 1bf409772086..57e25352ea96 100644 --- a/packages/espresso/pubspec.yaml +++ b/packages/espresso/pubspec.yaml @@ -3,11 +3,11 @@ description: Java classes for testing Flutter apps using Espresso. Allows driving Flutter widgets from a native Espresso test. repository: https://github.com/flutter/packages/tree/main/packages/espresso issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+espresso%22 -version: 0.3.0+10 +version: 0.4.0+3 environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" flutter: plugin: diff --git a/packages/extension_google_sign_in_as_googleapis_auth/CHANGELOG.md b/packages/extension_google_sign_in_as_googleapis_auth/CHANGELOG.md index 4e959fec76b4..50c7ff16dc9d 100644 --- a/packages/extension_google_sign_in_as_googleapis_auth/CHANGELOG.md +++ b/packages/extension_google_sign_in_as_googleapis_auth/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 2.0.12 diff --git a/packages/extension_google_sign_in_as_googleapis_auth/example/android/.gitignore b/packages/extension_google_sign_in_as_googleapis_auth/example/android/.gitignore index 6f568019d3c6..55afd919c659 100644 --- a/packages/extension_google_sign_in_as_googleapis_auth/example/android/.gitignore +++ b/packages/extension_google_sign_in_as_googleapis_auth/example/android/.gitignore @@ -7,7 +7,7 @@ gradle-wrapper.jar GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. -# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +# See https://flutter.dev/to/reference-keystore key.properties **/*.keystore **/*.jks diff --git a/packages/extension_google_sign_in_as_googleapis_auth/example/android/app/build.gradle b/packages/extension_google_sign_in_as_googleapis_auth/example/android/app/build.gradle index 497c231a3aba..03fe48c2210b 100644 --- a/packages/extension_google_sign_in_as_googleapis_auth/example/android/app/build.gradle +++ b/packages/extension_google_sign_in_as_googleapis_auth/example/android/app/build.gradle @@ -29,8 +29,8 @@ android { compileSdk flutter.compileSdkVersion compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } defaultConfig { diff --git a/packages/extension_google_sign_in_as_googleapis_auth/example/android/build.gradle b/packages/extension_google_sign_in_as_googleapis_auth/example/android/build.gradle index adcf25704467..92088245cb0e 100644 --- a/packages/extension_google_sign_in_as_googleapis_auth/example/android/build.gradle +++ b/packages/extension_google_sign_in_as_googleapis_auth/example/android/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath 'com.android.tools.build:gradle:8.5.2' classpath 'com.google.gms:google-services:4.3.15' } } diff --git a/packages/extension_google_sign_in_as_googleapis_auth/example/android/gradle.properties b/packages/extension_google_sign_in_as_googleapis_auth/example/android/gradle.properties index 94adc3a3f97a..598d13fee446 100644 --- a/packages/extension_google_sign_in_as_googleapis_auth/example/android/gradle.properties +++ b/packages/extension_google_sign_in_as_googleapis_auth/example/android/gradle.properties @@ -1,3 +1,3 @@ -org.gradle.jvmargs=-Xmx1536M +org.gradle.jvmargs=-Xmx4G android.useAndroidX=true android.enableJetifier=true diff --git a/packages/extension_google_sign_in_as_googleapis_auth/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/extension_google_sign_in_as_googleapis_auth/example/android/gradle/wrapper/gradle-wrapper.properties index aeaff6f869f3..7aeeb11c6ee5 100644 --- a/packages/extension_google_sign_in_as_googleapis_auth/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/extension_google_sign_in_as_googleapis_auth/example/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml b/packages/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml index 36b33867f64d..c8de67d9e71b 100644 --- a/packages/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml +++ b/packages/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Example of Google Sign-In plugin and googleapis. publish_to: none environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: extension_google_sign_in_as_googleapis_auth: @@ -17,7 +17,7 @@ dependencies: flutter: sdk: flutter google_sign_in: ^6.0.0 - googleapis: ^10.1.0 + googleapis: ">=10.1.0 <14.0.0" googleapis_auth: ^1.1.0 dev_dependencies: diff --git a/packages/extension_google_sign_in_as_googleapis_auth/example/web/index.html b/packages/extension_google_sign_in_as_googleapis_auth/example/web/index.html index 1d72ec5daa75..e178d6751c21 100644 --- a/packages/extension_google_sign_in_as_googleapis_auth/example/web/index.html +++ b/packages/extension_google_sign_in_as_googleapis_auth/example/web/index.html @@ -38,29 +38,8 @@ Google Sign In + googleapis - - - - - + diff --git a/packages/extension_google_sign_in_as_googleapis_auth/pubspec.yaml b/packages/extension_google_sign_in_as_googleapis_auth/pubspec.yaml index 2903d635e797..6e03593de6d1 100644 --- a/packages/extension_google_sign_in_as_googleapis_auth/pubspec.yaml +++ b/packages/extension_google_sign_in_as_googleapis_auth/pubspec.yaml @@ -11,8 +11,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 2.0.12 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/file_selector/file_selector/CHANGELOG.md b/packages/file_selector/file_selector/CHANGELOG.md index 09449fe67fdd..a4a62d47790a 100644 --- a/packages/file_selector/file_selector/CHANGELOG.md +++ b/packages/file_selector/file_selector/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 1.0.3 diff --git a/packages/file_selector/file_selector/README.md b/packages/file_selector/file_selector/README.md index 798c9e9c7bc8..b316a4687133 100644 --- a/packages/file_selector/file_selector/README.md +++ b/packages/file_selector/file_selector/README.md @@ -10,9 +10,7 @@ A Flutter plugin that manages files and interactions with file dialogs. |-------------|---------|---------|-------|--------|-----|-------------| | **Support** | SDK 19+ | iOS 12+ | Any | 10.14+ | Any | Windows 10+ | -## Usage - -To use this plugin, add `file_selector` as a [dependency in your pubspec.yaml file](https://flutter.dev/platform-plugins/). +## Setup ### macOS diff --git a/packages/file_selector/file_selector/example/android/.gitignore b/packages/file_selector/file_selector/example/android/.gitignore index 6f568019d3c6..55afd919c659 100644 --- a/packages/file_selector/file_selector/example/android/.gitignore +++ b/packages/file_selector/file_selector/example/android/.gitignore @@ -7,7 +7,7 @@ gradle-wrapper.jar GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. -# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +# See https://flutter.dev/to/reference-keystore key.properties **/*.keystore **/*.jks diff --git a/packages/file_selector/file_selector/example/android/app/build.gradle b/packages/file_selector/file_selector/example/android/app/build.gradle index 4728b6c2863a..1dbd8c483a98 100644 --- a/packages/file_selector/file_selector/example/android/app/build.gradle +++ b/packages/file_selector/file_selector/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,22 +22,18 @@ 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.plugins.file_selector_example" compileSdk flutter.compileSdkVersion ndkVersion flutter.ndkVersion compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '11' } sourceSets { @@ -47,7 +44,7 @@ android { applicationId "dev.flutter.plugins.file_selector_example" // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. - minSdkVersion 19 + minSdkVersion flutter.minSdkVersion targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName @@ -65,7 +62,3 @@ android { flutter { source '../..' } - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" -} diff --git a/packages/file_selector/file_selector/example/android/build.gradle b/packages/file_selector/file_selector/example/android/build.gradle index fdf447f8a7e6..b9db5700753a 100644 --- a/packages/file_selector/file_selector/example/android/build.gradle +++ b/packages/file_selector/file_selector/example/android/build.gradle @@ -1,16 +1,3 @@ -buildscript { - ext.kotlin_version = '1.7.10' - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:7.3.0' - 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/file_selector/file_selector/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/file_selector/file_selector/example/android/gradle/wrapper/gradle-wrapper.properties index e1ca574ef017..3c85cfe057a1 100644 --- a/packages/file_selector/file_selector/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/file_selector/file_selector/example/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/file_selector/file_selector/example/android/settings.gradle b/packages/file_selector/file_selector/example/android/settings.gradle index f246a74091be..d056e4db3665 100644 --- a/packages/file_selector/file_selector/example/android/settings.gradle +++ b/packages/file_selector/file_selector/example/android/settings.gradle @@ -1,24 +1,27 @@ -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/file_selector/file_selector/example/ios/Podfile b/packages/file_selector/file_selector/example/ios/Podfile index 279576f3884f..01d4aa611bb9 100644 --- a/packages/file_selector/file_selector/example/ios/Podfile +++ b/packages/file_selector/file_selector/example/ios/Podfile @@ -29,7 +29,6 @@ flutter_ios_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) end diff --git a/packages/file_selector/file_selector/example/macos/Podfile b/packages/file_selector/file_selector/example/macos/Podfile index 049abe295427..ae77cc1d4269 100644 --- a/packages/file_selector/file_selector/example/macos/Podfile +++ b/packages/file_selector/file_selector/example/macos/Podfile @@ -28,7 +28,6 @@ flutter_macos_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) end diff --git a/packages/file_selector/file_selector/example/pubspec.yaml b/packages/file_selector/file_selector/example/pubspec.yaml index 0fa95e0baf58..6cf19c83de6c 100644 --- a/packages/file_selector/file_selector/example/pubspec.yaml +++ b/packages/file_selector/file_selector/example/pubspec.yaml @@ -5,8 +5,8 @@ publish_to: none version: 1.0.0+1 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: file_selector: diff --git a/packages/file_selector/file_selector/example/web/index.html b/packages/file_selector/file_selector/example/web/index.html index c6fa1623be95..1fb8a6286811 100644 --- a/packages/file_selector/file_selector/example/web/index.html +++ b/packages/file_selector/file_selector/example/web/index.html @@ -21,16 +21,6 @@ - - - + diff --git a/packages/file_selector/file_selector/pubspec.yaml b/packages/file_selector/file_selector/pubspec.yaml index c1c105c6a520..9825bd4af478 100644 --- a/packages/file_selector/file_selector/pubspec.yaml +++ b/packages/file_selector/file_selector/pubspec.yaml @@ -6,8 +6,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 1.0.3 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: diff --git a/packages/file_selector/file_selector_android/CHANGELOG.md b/packages/file_selector/file_selector_android/CHANGELOG.md index f7827e7bf562..8c1f93d36d32 100644 --- a/packages/file_selector/file_selector_android/CHANGELOG.md +++ b/packages/file_selector/file_selector_android/CHANGELOG.md @@ -1,5 +1,36 @@ -## NEXT +## 0.5.1+10 +* Bumps androidx.annotation:annotation from 1.8.2 to 1.9.0. + +## 0.5.1+9 + +* Updates Java compatibility version to 11. + +## 0.5.1+8 + +* Updates Pigeon for non-nullable collection type support. + +## 0.5.1+7 + +* Removes dependency on org.jetbrains.kotlin:kotlin-bom. +* Updates minimum supported SDK version to Flutter 3.24/Dart 3.5. + +## 0.5.1+6 + +* Bumps androidx.annotation:annotation from 1.8.1 to 1.8.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + +## 0.5.1+5 + +* Bumps androidx.annotation:annotation from 1.8.0 to 1.8.1. + +## 0.5.1+4 + +* Updates lint checks to ignore NewerVersionAvailable. + +## 0.5.1+3 + +* Bumps com.android.tools.build:gradle from 7.3.0 to 8.5.1. * Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 0.5.1+2 diff --git a/packages/file_selector/file_selector_android/README.md b/packages/file_selector/file_selector_android/README.md index 0a24663376dd..c52b5c2a8602 100644 --- a/packages/file_selector/file_selector_android/README.md +++ b/packages/file_selector/file_selector_android/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/file_selector -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/file_selector/file_selector_android/android/build.gradle b/packages/file_selector/file_selector_android/android/build.gradle index 247f4b0c02ac..144e667a2d63 100644 --- a/packages/file_selector/file_selector_android/android/build.gradle +++ b/packages/file_selector/file_selector_android/android/build.gradle @@ -8,7 +8,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.3.0' + classpath 'com.android.tools.build:gradle:8.5.1' } } @@ -22,15 +22,12 @@ rootProject.allprojects { apply plugin: 'com.android.library' android { - // Conditional for compatibility with AGP <4.2. - if (project.android.hasProperty("namespace")) { - namespace 'dev.flutter.packages.file_selector_android' - } + namespace 'dev.flutter.packages.file_selector_android' compileSdk 34 compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } defaultConfig { @@ -38,21 +35,17 @@ android { } dependencies { - implementation 'androidx.annotation:annotation:1.8.0' + implementation 'androidx.annotation:annotation:1.9.0' testImplementation 'junit:junit:4.13.2' testImplementation 'org.mockito:mockito-inline:5.1.0' testImplementation 'androidx.test:core:1.3.0' testImplementation "org.robolectric:robolectric:4.12.1" - - // org.jetbrains.kotlin:kotlin-bom artifact purpose is to align kotlin stdlib and related code versions. - // See: https://youtrack.jetbrains.com/issue/KT-55297/kotlin-stdlib-should-declare-constraints-on-kotlin-stdlib-jdk8-and-kotlin-stdlib-jdk7 - implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.10")) } lintOptions { checkAllWarnings true warningsAsErrors true - disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency' + disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency', 'NewerVersionAvailable' } testOptions { diff --git a/packages/file_selector/file_selector_android/android/src/main/java/dev/flutter/packages/file_selector_android/FileSelectorAndroidPlugin.java b/packages/file_selector/file_selector_android/android/src/main/java/dev/flutter/packages/file_selector_android/FileSelectorAndroidPlugin.java index 27b79068ea12..f7fce0fdd95b 100644 --- a/packages/file_selector/file_selector_android/android/src/main/java/dev/flutter/packages/file_selector_android/FileSelectorAndroidPlugin.java +++ b/packages/file_selector/file_selector_android/android/src/main/java/dev/flutter/packages/file_selector_android/FileSelectorAndroidPlugin.java @@ -28,7 +28,7 @@ public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { @Override public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) { fileSelectorApi = new FileSelectorApiImpl(binding); - GeneratedFileSelectorApi.FileSelectorApi.setup( + GeneratedFileSelectorApi.FileSelectorApi.setUp( pluginBinding.getBinaryMessenger(), fileSelectorApi); } @@ -45,7 +45,7 @@ public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBindin fileSelectorApi.setActivityPluginBinding(binding); } else { fileSelectorApi = new FileSelectorApiImpl(binding); - GeneratedFileSelectorApi.FileSelectorApi.setup( + GeneratedFileSelectorApi.FileSelectorApi.setUp( pluginBinding.getBinaryMessenger(), fileSelectorApi); } } diff --git a/packages/file_selector/file_selector_android/android/src/main/java/dev/flutter/packages/file_selector_android/FileSelectorApiImpl.java b/packages/file_selector/file_selector_android/android/src/main/java/dev/flutter/packages/file_selector_android/FileSelectorApiImpl.java index a20ab00e58eb..555318b29959 100644 --- a/packages/file_selector/file_selector_android/android/src/main/java/dev/flutter/packages/file_selector_android/FileSelectorApiImpl.java +++ b/packages/file_selector/file_selector_android/android/src/main/java/dev/flutter/packages/file_selector_android/FileSelectorApiImpl.java @@ -91,7 +91,8 @@ public FileSelectorApiImpl(@NonNull ActivityPluginBinding activityPluginBinding) public void openFile( @Nullable String initialDirectory, @NonNull GeneratedFileSelectorApi.FileTypes allowedTypes, - @NonNull GeneratedFileSelectorApi.Result result) { + @NonNull + GeneratedFileSelectorApi.NullableResult result) { final Intent intent = objectFactory.newIntent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); @@ -192,7 +193,8 @@ public void onResult(int resultCode, @Nullable Intent data) { @Override @TargetApi(21) public void getDirectoryPath( - @Nullable String initialDirectory, @NonNull GeneratedFileSelectorApi.Result result) { + @Nullable String initialDirectory, + @NonNull GeneratedFileSelectorApi.NullableResult result) { if (!sdkChecker.sdkIsAtLeast(android.os.Build.VERSION_CODES.LOLLIPOP)) { result.error( new UnsupportedOperationException( diff --git a/packages/file_selector/file_selector_android/android/src/main/java/dev/flutter/packages/file_selector_android/GeneratedFileSelectorApi.java b/packages/file_selector/file_selector_android/android/src/main/java/dev/flutter/packages/file_selector_android/GeneratedFileSelectorApi.java index 5f4261563bb5..de595ef85847 100644 --- a/packages/file_selector/file_selector_android/android/src/main/java/dev/flutter/packages/file_selector_android/GeneratedFileSelectorApi.java +++ b/packages/file_selector/file_selector_android/android/src/main/java/dev/flutter/packages/file_selector_android/GeneratedFileSelectorApi.java @@ -1,11 +1,14 @@ // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v9.2.5), do not edit directly. +// Autogenerated from Pigeon (v22.4.2), do not edit directly. // See also: https://pub.dev/packages/pigeon package dev.flutter.packages.file_selector_android; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.CLASS; + import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -14,9 +17,13 @@ import io.flutter.plugin.common.MessageCodec; import io.flutter.plugin.common.StandardMessageCodec; import java.io.ByteArrayOutputStream; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Objects; /** Generated class from Pigeon. */ @SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression", "serial"}) @@ -40,7 +47,7 @@ public FlutterError(@NonNull String code, @Nullable String message, @Nullable Ob @NonNull protected static ArrayList wrapError(@NonNull Throwable exception) { - ArrayList errorList = new ArrayList(3); + ArrayList errorList = new ArrayList<>(3); if (exception instanceof FlutterError) { FlutterError error = (FlutterError) exception; errorList.add(error.code); @@ -55,6 +62,10 @@ protected static ArrayList wrapError(@NonNull Throwable exception) { return errorList; } + @Target(METHOD) + @Retention(CLASS) + @interface CanIgnoreReturnValue {} + /** Generated class from Pigeon that represents data sent in messages. */ public static final class FileResponse { private @NonNull String path; @@ -119,10 +130,34 @@ public void setBytes(@NonNull byte[] setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ FileResponse() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + FileResponse that = (FileResponse) o; + return path.equals(that.path) + && Objects.equals(mimeType, that.mimeType) + && Objects.equals(name, that.name) + && size.equals(that.size) + && Arrays.equals(bytes, that.bytes); + } + + @Override + public int hashCode() { + int pigeonVar_result = Objects.hash(path, mimeType, name, size); + pigeonVar_result = 31 * pigeonVar_result + Arrays.hashCode(bytes); + return pigeonVar_result; + } + public static final class Builder { private @Nullable String path; + @CanIgnoreReturnValue public @NonNull Builder setPath(@NonNull String setterArg) { this.path = setterArg; return this; @@ -130,6 +165,7 @@ public static final class Builder { private @Nullable String mimeType; + @CanIgnoreReturnValue public @NonNull Builder setMimeType(@Nullable String setterArg) { this.mimeType = setterArg; return this; @@ -137,6 +173,7 @@ public static final class Builder { private @Nullable String name; + @CanIgnoreReturnValue public @NonNull Builder setName(@Nullable String setterArg) { this.name = setterArg; return this; @@ -144,6 +181,7 @@ public static final class Builder { private @Nullable Long size; + @CanIgnoreReturnValue public @NonNull Builder setSize(@NonNull Long setterArg) { this.size = setterArg; return this; @@ -151,6 +189,7 @@ public static final class Builder { private @Nullable byte[] bytes; + @CanIgnoreReturnValue public @NonNull Builder setBytes(@NonNull byte[] setterArg) { this.bytes = setterArg; return this; @@ -169,7 +208,7 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(5); + ArrayList toListResult = new ArrayList<>(5); toListResult.add(path); toListResult.add(mimeType); toListResult.add(name); @@ -178,18 +217,17 @@ ArrayList toList() { return toListResult; } - static @NonNull FileResponse fromList(@NonNull ArrayList list) { + static @NonNull FileResponse fromList(@NonNull ArrayList pigeonVar_list) { FileResponse pigeonResult = new FileResponse(); - Object path = list.get(0); + Object path = pigeonVar_list.get(0); pigeonResult.setPath((String) path); - Object mimeType = list.get(1); + Object mimeType = pigeonVar_list.get(1); pigeonResult.setMimeType((String) mimeType); - Object name = list.get(2); + Object name = pigeonVar_list.get(2); pigeonResult.setName((String) name); - Object size = list.get(3); - pigeonResult.setSize( - (size == null) ? null : ((size instanceof Integer) ? (Integer) size : (Long) size)); - Object bytes = list.get(4); + Object size = pigeonVar_list.get(3); + pigeonResult.setSize((Long) size); + Object bytes = pigeonVar_list.get(4); pigeonResult.setBytes((byte[]) bytes); return pigeonResult; } @@ -226,10 +264,28 @@ public void setExtensions(@NonNull List setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ FileTypes() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + FileTypes that = (FileTypes) o; + return mimeTypes.equals(that.mimeTypes) && extensions.equals(that.extensions); + } + + @Override + public int hashCode() { + return Objects.hash(mimeTypes, extensions); + } + public static final class Builder { private @Nullable List mimeTypes; + @CanIgnoreReturnValue public @NonNull Builder setMimeTypes(@NonNull List setterArg) { this.mimeTypes = setterArg; return this; @@ -237,6 +293,7 @@ public static final class Builder { private @Nullable List extensions; + @CanIgnoreReturnValue public @NonNull Builder setExtensions(@NonNull List setterArg) { this.extensions = setterArg; return this; @@ -252,40 +309,33 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(2); + ArrayList toListResult = new ArrayList<>(2); toListResult.add(mimeTypes); toListResult.add(extensions); return toListResult; } - static @NonNull FileTypes fromList(@NonNull ArrayList list) { + static @NonNull FileTypes fromList(@NonNull ArrayList pigeonVar_list) { FileTypes pigeonResult = new FileTypes(); - Object mimeTypes = list.get(0); + Object mimeTypes = pigeonVar_list.get(0); pigeonResult.setMimeTypes((List) mimeTypes); - Object extensions = list.get(1); + Object extensions = pigeonVar_list.get(1); pigeonResult.setExtensions((List) extensions); return pigeonResult; } } - public interface Result { - @SuppressWarnings("UnknownNullness") - void success(T result); + private static class PigeonCodec extends StandardMessageCodec { + public static final PigeonCodec INSTANCE = new PigeonCodec(); - void error(@NonNull Throwable error); - } - - private static class FileSelectorApiCodec extends StandardMessageCodec { - public static final FileSelectorApiCodec INSTANCE = new FileSelectorApiCodec(); - - private FileSelectorApiCodec() {} + private PigeonCodec() {} @Override protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { switch (type) { - case (byte) 128: - return FileResponse.fromList((ArrayList) readValue(buffer)); case (byte) 129: + return FileResponse.fromList((ArrayList) readValue(buffer)); + case (byte) 130: return FileTypes.fromList((ArrayList) readValue(buffer)); default: return super.readValueOfType(type, buffer); @@ -295,10 +345,10 @@ protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { @Override protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { if (value instanceof FileResponse) { - stream.write(128); + stream.write(129); writeValue(stream, ((FileResponse) value).toList()); } else if (value instanceof FileTypes) { - stream.write(129); + stream.write(130); writeValue(stream, ((FileTypes) value).toList()); } else { super.writeValue(stream, value); @@ -306,6 +356,30 @@ protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { } } + /** Asynchronous error handling return type for non-nullable API method returns. */ + public interface Result { + /** Success case callback method for handling returns. */ + void success(@NonNull T result); + + /** Failure case callback method for handling errors. */ + void error(@NonNull Throwable error); + } + /** Asynchronous error handling return type for nullable API method returns. */ + public interface NullableResult { + /** Success case callback method for handling returns. */ + void success(@Nullable T result); + + /** Failure case callback method for handling errors. */ + void error(@NonNull Throwable error); + } + /** Asynchronous error handling return type for void API method returns. */ + public interface VoidResult { + /** Success case callback method for handling returns. */ + void success(); + + /** Failure case callback method for handling errors. */ + void error(@NonNull Throwable error); + } /** * An API to call to native code to select files or directories. * @@ -320,7 +394,7 @@ public interface FileSelectorApi { void openFile( @Nullable String initialDirectory, @NonNull FileTypes allowedTypes, - @NonNull Result result); + @NonNull NullableResult result); /** * Opens a file dialog for loading files and returns a list of file responses chosen by the * user. @@ -334,29 +408,41 @@ void openFiles( * *

Returns `null` if user cancels the operation. */ - void getDirectoryPath(@Nullable String initialDirectory, @NonNull Result result); + void getDirectoryPath( + @Nullable String initialDirectory, @NonNull NullableResult result); /** The codec used by FileSelectorApi. */ static @NonNull MessageCodec getCodec() { - return FileSelectorApiCodec.INSTANCE; + return PigeonCodec.INSTANCE; } /** * Sets up an instance of `FileSelectorApi` to handle messages through the `binaryMessenger`. */ - static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable FileSelectorApi api) { + static void setUp(@NonNull BinaryMessenger binaryMessenger, @Nullable FileSelectorApi api) { + setUp(binaryMessenger, "", api); + } + + static void setUp( + @NonNull BinaryMessenger binaryMessenger, + @NonNull String messageChannelSuffix, + @Nullable FileSelectorApi api) { + messageChannelSuffix = messageChannelSuffix.isEmpty() ? "" : "." + messageChannelSuffix; { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.FileSelectorApi.openFile", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.file_selector_android.FileSelectorApi.openFile" + + messageChannelSuffix, + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; String initialDirectoryArg = (String) args.get(0); FileTypes allowedTypesArg = (FileTypes) args.get(1); - Result resultCallback = - new Result() { + NullableResult resultCallback = + new NullableResult() { public void success(FileResponse result) { wrapped.add(0, result); reply.reply(wrapped); @@ -377,11 +463,14 @@ public void error(Throwable error) { { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.FileSelectorApi.openFiles", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.file_selector_android.FileSelectorApi.openFiles" + + messageChannelSuffix, + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; String initialDirectoryArg = (String) args.get(0); FileTypes allowedTypesArg = (FileTypes) args.get(1); @@ -407,15 +496,18 @@ public void error(Throwable error) { { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.FileSelectorApi.getDirectoryPath", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.file_selector_android.FileSelectorApi.getDirectoryPath" + + messageChannelSuffix, + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; String initialDirectoryArg = (String) args.get(0); - Result resultCallback = - new Result() { + NullableResult resultCallback = + new NullableResult() { public void success(String result) { wrapped.add(0, result); reply.reply(wrapped); diff --git a/packages/file_selector/file_selector_android/android/src/test/java/dev/flutter/packages/file_selector_android/FileSelectorAndroidPluginTest.java b/packages/file_selector/file_selector_android/android/src/test/java/dev/flutter/packages/file_selector_android/FileSelectorAndroidPluginTest.java index dd4f74e0a287..00533c282640 100644 --- a/packages/file_selector/file_selector_android/android/src/test/java/dev/flutter/packages/file_selector_android/FileSelectorAndroidPluginTest.java +++ b/packages/file_selector/file_selector_android/android/src/test/java/dev/flutter/packages/file_selector_android/FileSelectorAndroidPluginTest.java @@ -95,8 +95,8 @@ public void openFileReturnsSuccessfully() throws FileNotFoundException { mockObjectFactory, (version) -> Build.VERSION.SDK_INT >= version); - final GeneratedFileSelectorApi.Result mockResult = - mock(GeneratedFileSelectorApi.Result.class); + final GeneratedFileSelectorApi.NullableResult mockResult = + mock(GeneratedFileSelectorApi.NullableResult.class); fileSelectorApi.openFile( null, new GeneratedFileSelectorApi.FileTypes.Builder() @@ -243,8 +243,8 @@ public void getDirectoryPathReturnsSuccessfully() { mockObjectFactory, (version) -> Build.VERSION_CODES.LOLLIPOP >= version); - final GeneratedFileSelectorApi.Result mockResult = - mock(GeneratedFileSelectorApi.Result.class); + final GeneratedFileSelectorApi.NullableResult mockResult = + mock(GeneratedFileSelectorApi.NullableResult.class); fileSelectorApi.getDirectoryPath(null, mockResult); verify(mockActivity).startActivityForResult(mockIntent, 223); @@ -273,8 +273,8 @@ public void getDirectoryPath_errorsForUnsupportedVersion() { (version) -> Build.VERSION_CODES.KITKAT >= version); @SuppressWarnings("unchecked") - final GeneratedFileSelectorApi.Result mockResult = - mock(GeneratedFileSelectorApi.Result.class); + final GeneratedFileSelectorApi.NullableResult mockResult = + mock(GeneratedFileSelectorApi.NullableResult.class); fileSelectorApi.getDirectoryPath(null, mockResult); verify(mockResult).error(any()); diff --git a/packages/file_selector/file_selector_android/example/android/app/build.gradle b/packages/file_selector/file_selector_android/example/android/app/build.gradle index a0a7ccb1e244..8a820df9ccf7 100644 --- a/packages/file_selector/file_selector_android/example/android/app/build.gradle +++ b/packages/file_selector/file_selector_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,27 +22,20 @@ 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.packages.file_selector_android_example" compileSdk flutter.compileSdkVersion ndkVersion flutter.ndkVersion compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "dev.flutter.packages.file_selector_android_example" - // You can update the following values to match your application needs. - // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. - minSdkVersion 21 - targetSdkVersion 33 + minSdkVersion flutter.minSdkVersion + targetSdkVersion 34 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/packages/file_selector/file_selector_android/example/android/build.gradle b/packages/file_selector/file_selector_android/example/android/build.gradle index 6e01a69f49a2..e4986fb81ee6 100644 --- a/packages/file_selector/file_selector_android/example/android/build.gradle +++ b/packages/file_selector/file_selector_android/example/android/build.gradle @@ -1,16 +1,3 @@ -buildscript { - ext.kotlin_version = '1.7.10' - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:7.3.0' - 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/file_selector/file_selector_android/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/file_selector/file_selector_android/example/android/gradle/wrapper/gradle-wrapper.properties index e1ca574ef017..3c85cfe057a1 100644 --- a/packages/file_selector/file_selector_android/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/file_selector/file_selector_android/example/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/file_selector/file_selector_android/example/android/settings.gradle b/packages/file_selector/file_selector_android/example/android/settings.gradle index f246a74091be..74d52ff12f4f 100644 --- a/packages/file_selector/file_selector_android/example/android/settings.gradle +++ b/packages/file_selector/file_selector_android/example/android/settings.gradle @@ -1,24 +1,27 @@ -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.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" +} + +include ":app" diff --git a/packages/file_selector/file_selector_android/example/pubspec.yaml b/packages/file_selector/file_selector_android/example/pubspec.yaml index d9ad24cfc44f..c003ee1fc493 100644 --- a/packages/file_selector/file_selector_android/example/pubspec.yaml +++ b/packages/file_selector/file_selector_android/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the file_selector_android plugin. publish_to: 'none' environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" dependencies: file_selector_android: @@ -21,7 +21,7 @@ dependencies: sdk: flutter dev_dependencies: - espresso: ^0.2.0 + espresso: ^0.4.0 flutter_test: sdk: flutter integration_test: diff --git a/packages/file_selector/file_selector_android/lib/src/file_selector_android.dart b/packages/file_selector/file_selector_android/lib/src/file_selector_android.dart index a4ff20323615..bc11695265c2 100644 --- a/packages/file_selector/file_selector_android/lib/src/file_selector_android.dart +++ b/packages/file_selector/file_selector_android/lib/src/file_selector_android.dart @@ -40,14 +40,11 @@ class FileSelectorAndroid extends FileSelectorPlatform { String? initialDirectory, String? confirmButtonText, }) async { - final List files = await _api.openFiles( + final List files = await _api.openFiles( initialDirectory, _fileTypesFromTypeGroups(acceptedTypeGroups), ); - return files - .cast() - .map(_xFileFromFileResponse) - .toList(); + return files.map(_xFileFromFileResponse).toList(); } @override diff --git a/packages/file_selector/file_selector_android/lib/src/file_selector_api.g.dart b/packages/file_selector/file_selector_android/lib/src/file_selector_api.g.dart index 2f3611ecdd4a..558ab5f557f4 100644 --- a/packages/file_selector/file_selector_android/lib/src/file_selector_api.g.dart +++ b/packages/file_selector/file_selector_android/lib/src/file_selector_api.g.dart @@ -1,9 +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 (v9.2.5), do not edit directly. +// Autogenerated from Pigeon (v22.4.2), 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 +// 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 import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; @@ -11,6 +11,13 @@ import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; import 'package:flutter/services.dart'; +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); +} + class FileResponse { FileResponse({ required this.path, @@ -58,9 +65,9 @@ class FileTypes { required this.extensions, }); - List mimeTypes; + List mimeTypes; - List extensions; + List extensions; Object encode() { return [ @@ -72,21 +79,24 @@ class FileTypes { static FileTypes decode(Object result) { result as List; return FileTypes( - mimeTypes: (result[0] as List?)!.cast(), - extensions: (result[1] as List?)!.cast(), + mimeTypes: (result[0] as List?)!.cast(), + extensions: (result[1] as List?)!.cast(), ); } } -class _FileSelectorApiCodec extends StandardMessageCodec { - const _FileSelectorApiCodec(); +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is FileResponse) { - buffer.putUint8(128); + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is FileResponse) { + buffer.putUint8(129); writeValue(buffer, value.encode()); } else if (value is FileTypes) { - buffer.putUint8(129); + buffer.putUint8(130); writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); @@ -96,9 +106,9 @@ class _FileSelectorApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: - return FileResponse.decode(readValue(buffer)!); case 129: + return FileResponse.decode(readValue(buffer)!); + case 130: return FileTypes.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -111,92 +121,101 @@ class FileSelectorApi { /// Constructor for [FileSelectorApi]. 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. - FileSelectorApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; + FileSelectorApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; - static const MessageCodec codec = _FileSelectorApiCodec(); + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String pigeonVar_messageChannelSuffix; /// Opens a file dialog for loading files and returns a file path. /// /// Returns `null` if user cancels the operation. Future openFile( - String? arg_initialDirectory, FileTypes arg_allowedTypes) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.FileSelectorApi.openFile', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_initialDirectory, arg_allowedTypes]) - as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + String? initialDirectory, FileTypes allowedTypes) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.file_selector_android.FileSelectorApi.openFile$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([initialDirectory, allowedTypes]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { - return (replyList[0] as FileResponse?); + return (pigeonVar_replyList[0] as FileResponse?); } } /// Opens a file dialog for loading files and returns a list of file responses /// chosen by the user. - Future> openFiles( - String? arg_initialDirectory, FileTypes arg_allowedTypes) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.FileSelectorApi.openFiles', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_initialDirectory, arg_allowedTypes]) - as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future> openFiles( + String? initialDirectory, FileTypes allowedTypes) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.file_selector_android.FileSelectorApi.openFiles$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([initialDirectory, allowedTypes]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 (replyList[0] as List?)!.cast(); + return (pigeonVar_replyList[0] as List?)!.cast(); } } /// Opens a file dialog for loading directories and returns a directory path. /// /// Returns `null` if user cancels the operation. - Future getDirectoryPath(String? arg_initialDirectory) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.FileSelectorApi.getDirectoryPath', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_initialDirectory]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future getDirectoryPath(String? initialDirectory) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.file_selector_android.FileSelectorApi.getDirectoryPath$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([initialDirectory]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { - return (replyList[0] as String?); + return (pigeonVar_replyList[0] as String?); } } } diff --git a/packages/file_selector/file_selector_android/pigeons/file_selector_api.dart b/packages/file_selector/file_selector_android/pigeons/file_selector_api.dart index 440805019a77..3a6c5228a4b4 100644 --- a/packages/file_selector/file_selector_android/pigeons/file_selector_api.dart +++ b/packages/file_selector/file_selector_android/pigeons/file_selector_api.dart @@ -25,8 +25,8 @@ class FileResponse { } class FileTypes { - late List mimeTypes; - late List extensions; + late List mimeTypes; + late List extensions; } /// An API to call to native code to select files or directories. @@ -41,7 +41,7 @@ abstract class FileSelectorApi { /// Opens a file dialog for loading files and returns a list of file responses /// chosen by the user. @async - List openFiles( + List openFiles( String? initialDirectory, FileTypes allowedTypes, ); diff --git a/packages/file_selector/file_selector_android/pubspec.yaml b/packages/file_selector/file_selector_android/pubspec.yaml index db12e1998806..389fa903eb0b 100644 --- a/packages/file_selector/file_selector_android/pubspec.yaml +++ b/packages/file_selector/file_selector_android/pubspec.yaml @@ -2,11 +2,11 @@ name: file_selector_android description: Android implementation of the file_selector package. repository: https://github.com/flutter/packages/tree/main/packages/file_selector/file_selector_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+file_selector%22 -version: 0.5.1+2 +version: 0.5.1+10 environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" flutter: plugin: @@ -27,8 +27,8 @@ dev_dependencies: build_runner: ^2.1.4 flutter_test: sdk: flutter - mockito: 5.4.4 - pigeon: ^9.2.4 + mockito: ^5.4.4 + pigeon: ^22.4.2 topics: - files diff --git a/packages/file_selector/file_selector_android/test/file_selector_android_test.mocks.dart b/packages/file_selector/file_selector_android/test/file_selector_android_test.mocks.dart index 1e7d9745ebe5..8f465c9a79ac 100644 --- a/packages/file_selector/file_selector_android/test/file_selector_android_test.mocks.dart +++ b/packages/file_selector/file_selector_android/test/file_selector_android_test.mocks.dart @@ -3,10 +3,11 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i3; +import 'dart:async' as _i4; import 'package:file_selector_android/src/file_selector_api.g.dart' as _i2; import 'package:mockito/mockito.dart' as _i1; +import 'package:mockito/src/dummies.dart' as _i3; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -30,45 +31,54 @@ class MockFileSelectorApi extends _i1.Mock implements _i2.FileSelectorApi { } @override - _i3.Future<_i2.FileResponse?> openFile( - String? arg_initialDirectory, - _i2.FileTypes? arg_allowedTypes, + String get pigeonVar_messageChannelSuffix => (super.noSuchMethod( + Invocation.getter(#pigeonVar_messageChannelSuffix), + returnValue: _i3.dummyValue( + this, + Invocation.getter(#pigeonVar_messageChannelSuffix), + ), + ) as String); + + @override + _i4.Future<_i2.FileResponse?> openFile( + String? initialDirectory, + _i2.FileTypes? allowedTypes, ) => (super.noSuchMethod( Invocation.method( #openFile, [ - arg_initialDirectory, - arg_allowedTypes, + initialDirectory, + allowedTypes, ], ), - returnValue: _i3.Future<_i2.FileResponse?>.value(), - ) as _i3.Future<_i2.FileResponse?>); + returnValue: _i4.Future<_i2.FileResponse?>.value(), + ) as _i4.Future<_i2.FileResponse?>); @override - _i3.Future> openFiles( - String? arg_initialDirectory, - _i2.FileTypes? arg_allowedTypes, + _i4.Future> openFiles( + String? initialDirectory, + _i2.FileTypes? allowedTypes, ) => (super.noSuchMethod( Invocation.method( #openFiles, [ - arg_initialDirectory, - arg_allowedTypes, + initialDirectory, + allowedTypes, ], ), returnValue: - _i3.Future>.value(<_i2.FileResponse?>[]), - ) as _i3.Future>); + _i4.Future>.value(<_i2.FileResponse>[]), + ) as _i4.Future>); @override - _i3.Future getDirectoryPath(String? arg_initialDirectory) => + _i4.Future getDirectoryPath(String? initialDirectory) => (super.noSuchMethod( Invocation.method( #getDirectoryPath, - [arg_initialDirectory], + [initialDirectory], ), - returnValue: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + ) as _i4.Future); } diff --git a/packages/file_selector/file_selector_ios/CHANGELOG.md b/packages/file_selector/file_selector_ios/CHANGELOG.md index 5ee388e7a030..ea488f88a0b0 100644 --- a/packages/file_selector/file_selector_ios/CHANGELOG.md +++ b/packages/file_selector/file_selector_ios/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.5.3+1 + +* Updates Pigeon for non-nullable collection type support. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + ## 0.5.3 * Converts implementation to Swift. diff --git a/packages/file_selector/file_selector_ios/README.md b/packages/file_selector/file_selector_ios/README.md index 104d05c6e470..8acef6503733 100644 --- a/packages/file_selector/file_selector_ios/README.md +++ b/packages/file_selector/file_selector_ios/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/file_selector -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/file_selector/file_selector_ios/example/ios/Podfile b/packages/file_selector/file_selector_ios/example/ios/Podfile index d97f17e223fb..e549ee22f3b0 100644 --- a/packages/file_selector/file_selector_ios/example/ios/Podfile +++ b/packages/file_selector/file_selector_ios/example/ios/Podfile @@ -29,7 +29,6 @@ flutter_ios_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) target 'RunnerTests' do diff --git a/packages/file_selector/file_selector_ios/example/pubspec.yaml b/packages/file_selector/file_selector_ios/example/pubspec.yaml index 4e05cf1c6867..b4fd81c7de2a 100644 --- a/packages/file_selector/file_selector_ios/example/pubspec.yaml +++ b/packages/file_selector/file_selector_ios/example/pubspec.yaml @@ -4,8 +4,8 @@ publish_to: 'none' version: 1.0.0 environment: - sdk: ^3.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: # The following adds the Cupertino Icons font to your application. diff --git a/packages/file_selector/file_selector_ios/ios/file_selector_ios/Sources/file_selector_ios/FileSelectorPlugin.swift b/packages/file_selector/file_selector_ios/ios/file_selector_ios/Sources/file_selector_ios/FileSelectorPlugin.swift index f1f72cc2e281..35135ddc824e 100644 --- a/packages/file_selector/file_selector_ios/ios/file_selector_ios/Sources/file_selector_ios/FileSelectorPlugin.swift +++ b/packages/file_selector/file_selector_ios/ios/file_selector_ios/Sources/file_selector_ios/FileSelectorPlugin.swift @@ -59,8 +59,7 @@ public class FileSelectorPlugin: NSObject, FlutterPlugin, FileSelectorApi { let documentPicker = documentPickerViewControllerOverride ?? UIDocumentPickerViewController( - // See comment in messages.dart for why this is safe. - documentTypes: config.utis as! [String], + documentTypes: config.utis, in: .import) documentPicker.allowsMultipleSelection = config.allowMultiSelection documentPicker.delegate = completionBridge diff --git a/packages/file_selector/file_selector_ios/ios/file_selector_ios/Sources/file_selector_ios/messages.g.swift b/packages/file_selector/file_selector_ios/ios/file_selector_ios/Sources/file_selector_ios/messages.g.swift index 43f1bffeac8c..3d20e5a697b2 100644 --- a/packages/file_selector/file_selector_ios/ios/file_selector_ios/Sources/file_selector_ios/messages.g.swift +++ b/packages/file_selector/file_selector_ios/ios/file_selector_ios/Sources/file_selector_ios/messages.g.swift @@ -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 (v19.0.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.1), do not edit directly. // See also: https://pub.dev/packages/pigeon import Foundation @@ -69,13 +69,13 @@ private func nilOrValue(_ value: Any?) -> T? { /// Generated class from Pigeon that represents data sent in messages. struct FileSelectorConfig { - var utis: [String?] + var utis: [String] var allowMultiSelection: Bool // swift-format-ignore: AlwaysUseLowerCamelCase - static func fromList(_ __pigeon_list: [Any?]) -> FileSelectorConfig? { - let utis = __pigeon_list[0] as! [String?] - let allowMultiSelection = __pigeon_list[1] as! Bool + static func fromList(_ pigeonVar_list: [Any?]) -> FileSelectorConfig? { + let utis = pigeonVar_list[0] as! [String] + let allowMultiSelection = pigeonVar_list[1] as! Bool return FileSelectorConfig( utis: utis, @@ -90,10 +90,10 @@ struct FileSelectorConfig { } } -private class FileSelectorApiCodecReader: FlutterStandardReader { +private class messagesPigeonCodecReader: FlutterStandardReader { override func readValue(ofType type: UInt8) -> Any? { switch type { - case 128: + case 129: return FileSelectorConfig.fromList(self.readValue() as! [Any?]) default: return super.readValue(ofType: type) @@ -101,10 +101,10 @@ private class FileSelectorApiCodecReader: FlutterStandardReader { } } -private class FileSelectorApiCodecWriter: FlutterStandardWriter { +private class messagesPigeonCodecWriter: FlutterStandardWriter { override func writeValue(_ value: Any) { if let value = value as? FileSelectorConfig { - super.writeByte(128) + super.writeByte(129) super.writeValue(value.toList()) } else { super.writeValue(value) @@ -112,18 +112,18 @@ private class FileSelectorApiCodecWriter: FlutterStandardWriter { } } -private class FileSelectorApiCodecReaderWriter: FlutterStandardReaderWriter { +private class messagesPigeonCodecReaderWriter: FlutterStandardReaderWriter { override func reader(with data: Data) -> FlutterStandardReader { - return FileSelectorApiCodecReader(data: data) + return messagesPigeonCodecReader(data: data) } override func writer(with data: NSMutableData) -> FlutterStandardWriter { - return FileSelectorApiCodecWriter(data: data) + return messagesPigeonCodecWriter(data: data) } } -class FileSelectorApiCodec: FlutterStandardMessageCodec { - static let shared = FileSelectorApiCodec(readerWriter: FileSelectorApiCodecReaderWriter()) +class messagesPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable { + static let shared = messagesPigeonCodec(readerWriter: messagesPigeonCodecReaderWriter()) } /// Generated protocol from Pigeon that represents a handler of messages from Flutter. @@ -133,8 +133,7 @@ protocol FileSelectorApi { /// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. class FileSelectorApiSetup { - /// The codec used by FileSelectorApi. - static var codec: FlutterStandardMessageCodec { FileSelectorApiCodec.shared } + static var codec: FlutterStandardMessageCodec { messagesPigeonCodec.shared } /// Sets up an instance of `FileSelectorApi` to handle messages through the `binaryMessenger`. static func setUp( binaryMessenger: FlutterBinaryMessenger, api: FileSelectorApi?, diff --git a/packages/file_selector/file_selector_ios/lib/file_selector_ios.dart b/packages/file_selector/file_selector_ios/lib/file_selector_ios.dart index d0eb22762bc9..a1ee201937ad 100644 --- a/packages/file_selector/file_selector_ios/lib/file_selector_ios.dart +++ b/packages/file_selector/file_selector_ios/lib/file_selector_ios.dart @@ -21,9 +21,8 @@ class FileSelectorIOS extends FileSelectorPlatform { String? initialDirectory, String? confirmButtonText, }) async { - final List path = (await _hostApi.openFile(FileSelectorConfig( - utis: _allowedUtiListFromTypeGroups(acceptedTypeGroups)))) - .cast(); + final List path = await _hostApi.openFile(FileSelectorConfig( + utis: _allowedUtiListFromTypeGroups(acceptedTypeGroups))); return path.isEmpty ? null : XFile(path.first); } @@ -33,10 +32,9 @@ class FileSelectorIOS extends FileSelectorPlatform { String? initialDirectory, String? confirmButtonText, }) async { - final List pathList = (await _hostApi.openFile(FileSelectorConfig( - utis: _allowedUtiListFromTypeGroups(acceptedTypeGroups), - allowMultiSelection: true))) - .cast(); + final List pathList = await _hostApi.openFile(FileSelectorConfig( + utis: _allowedUtiListFromTypeGroups(acceptedTypeGroups), + allowMultiSelection: true)); return pathList.map((String path) => XFile(path)).toList(); } diff --git a/packages/file_selector/file_selector_ios/lib/src/messages.g.dart b/packages/file_selector/file_selector_ios/lib/src/messages.g.dart index e86dd9c90572..c9c8d6cdbc4d 100644 --- a/packages/file_selector/file_selector_ios/lib/src/messages.g.dart +++ b/packages/file_selector/file_selector_ios/lib/src/messages.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 (v19.0.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.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 @@ -31,11 +31,11 @@ List wrapResponse( class FileSelectorConfig { FileSelectorConfig({ - this.utis = const [], + this.utis = const [], this.allowMultiSelection = false, }); - List utis; + List utis; bool allowMultiSelection; @@ -49,18 +49,21 @@ class FileSelectorConfig { static FileSelectorConfig decode(Object result) { result as List; return FileSelectorConfig( - utis: (result[0] as List?)!.cast(), + utis: (result[0] as List?)!.cast(), allowMultiSelection: result[1]! as bool, ); } } -class _FileSelectorApiCodec extends StandardMessageCodec { - const _FileSelectorApiCodec(); +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is FileSelectorConfig) { - buffer.putUint8(128); + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is FileSelectorConfig) { + buffer.putUint8(129); writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); @@ -70,7 +73,7 @@ class _FileSelectorApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: + case 129: return FileSelectorConfig.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -84,42 +87,41 @@ class FileSelectorApi { /// BinaryMessenger will be used which routes to the host platform. FileSelectorApi( {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : __pigeon_binaryMessenger = binaryMessenger, - __pigeon_messageChannelSuffix = + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; - final BinaryMessenger? __pigeon_binaryMessenger; + final BinaryMessenger? pigeonVar_binaryMessenger; - static const MessageCodec pigeonChannelCodec = - _FileSelectorApiCodec(); + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - final String __pigeon_messageChannelSuffix; + final String pigeonVar_messageChannelSuffix; - Future> openFile(FileSelectorConfig config) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.file_selector_ios.FileSelectorApi.openFile$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + Future> openFile(FileSelectorConfig config) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.file_selector_ios.FileSelectorApi.openFile$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([config]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([config]) 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 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/file_selector/file_selector_ios/pigeons/messages.dart b/packages/file_selector/file_selector_ios/pigeons/messages.dart index a793a2af5a98..ade4b17835c4 100644 --- a/packages/file_selector/file_selector_ios/pigeons/messages.dart +++ b/packages/file_selector/file_selector_ios/pigeons/messages.dart @@ -12,11 +12,8 @@ import 'package:pigeon/pigeon.dart'; )) class FileSelectorConfig { FileSelectorConfig( - {this.utis = const [], this.allowMultiSelection = false}); - // TODO(stuartmorgan): Declare these as non-nullable generics once - // https://github.com/flutter/flutter/issues/97848 is fixed. In practice, - // the values will never be null, and the native implementation assumes that. - List utis; + {this.utis = const [], this.allowMultiSelection = false}); + List utis; bool allowMultiSelection; } diff --git a/packages/file_selector/file_selector_ios/pubspec.yaml b/packages/file_selector/file_selector_ios/pubspec.yaml index 24c0d84231b6..d86a09d9d7fd 100644 --- a/packages/file_selector/file_selector_ios/pubspec.yaml +++ b/packages/file_selector/file_selector_ios/pubspec.yaml @@ -2,11 +2,11 @@ name: file_selector_ios description: iOS implementation of the file_selector plugin. repository: https://github.com/flutter/packages/tree/main/packages/file_selector/file_selector_ios issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+file_selector%22 -version: 0.5.3 +version: 0.5.3+1 environment: - sdk: ^3.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -25,8 +25,8 @@ dev_dependencies: build_runner: ^2.3.0 flutter_test: sdk: flutter - mockito: 5.4.4 - pigeon: ^19.0.0 + mockito: ^5.4.4 + pigeon: ^22.4.1 topics: - files diff --git a/packages/file_selector/file_selector_ios/test/file_selector_ios_test.mocks.dart b/packages/file_selector/file_selector_ios/test/file_selector_ios_test.mocks.dart index f39e0ff4b618..713bd3f29ba5 100644 --- a/packages/file_selector/file_selector_ios/test/file_selector_ios_test.mocks.dart +++ b/packages/file_selector/file_selector_ios/test/file_selector_ios_test.mocks.dart @@ -33,12 +33,12 @@ class MockTestFileSelectorApi extends _i1.Mock } @override - _i3.Future> openFile(_i4.FileSelectorConfig? config) => + _i3.Future> openFile(_i4.FileSelectorConfig? config) => (super.noSuchMethod( Invocation.method( #openFile, [config], ), - returnValue: _i3.Future>.value([]), - ) as _i3.Future>); + returnValue: _i3.Future>.value([]), + ) as _i3.Future>); } diff --git a/packages/file_selector/file_selector_ios/test/test_api.g.dart b/packages/file_selector/file_selector_ios/test/test_api.g.dart index db24932f71a3..fbe4e1acd920 100644 --- a/packages/file_selector/file_selector_ios/test/test_api.g.dart +++ b/packages/file_selector/file_selector_ios/test/test_api.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 (v19.0.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.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, unnecessary_import, no_leading_underscores_for_local_identifiers // ignore_for_file: avoid_relative_lib_imports @@ -13,12 +13,15 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:file_selector_ios/src/messages.g.dart'; -class _TestFileSelectorApiCodec extends StandardMessageCodec { - const _TestFileSelectorApiCodec(); +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is FileSelectorConfig) { - buffer.putUint8(128); + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is FileSelectorConfig) { + buffer.putUint8(129); writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); @@ -28,7 +31,7 @@ class _TestFileSelectorApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: + case 129: return FileSelectorConfig.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -39,10 +42,9 @@ class _TestFileSelectorApiCodec extends StandardMessageCodec { abstract class TestFileSelectorApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec pigeonChannelCodec = - _TestFileSelectorApiCodec(); + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - Future> openFile(FileSelectorConfig config); + Future> openFile(FileSelectorConfig config); static void setUp( TestFileSelectorApi? api, { @@ -52,17 +54,18 @@ abstract class TestFileSelectorApi { messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.file_selector_ios.FileSelectorApi.openFile$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.file_selector_ios.FileSelectorApi.openFile was null.'); @@ -72,7 +75,7 @@ abstract class TestFileSelectorApi { assert(arg_config != null, 'Argument for dev.flutter.pigeon.file_selector_ios.FileSelectorApi.openFile was null, expected non-null FileSelectorConfig.'); try { - final List output = await api.openFile(arg_config!); + final List output = await api.openFile(arg_config!); return [output]; } on PlatformException catch (e) { return wrapResponse(error: e); diff --git a/packages/file_selector/file_selector_linux/CHANGELOG.md b/packages/file_selector/file_selector_linux/CHANGELOG.md index 938cf91c72b0..74a5f6edc7d2 100644 --- a/packages/file_selector/file_selector_linux/CHANGELOG.md +++ b/packages/file_selector/file_selector_linux/CHANGELOG.md @@ -1,6 +1,7 @@ -## NEXT +## 0.9.3 -* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. +* Updates method channel implementation to use Pigeon. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 0.9.2+1 diff --git a/packages/file_selector/file_selector_linux/README.md b/packages/file_selector/file_selector_linux/README.md index f3c2d30c424c..aa0653238c56 100644 --- a/packages/file_selector/file_selector_linux/README.md +++ b/packages/file_selector/file_selector_linux/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/file_selector -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/file_selector/file_selector_linux/example/pubspec.yaml b/packages/file_selector/file_selector_linux/example/pubspec.yaml index 1e20e859cfa3..d29d3dac64c5 100644 --- a/packages/file_selector/file_selector_linux/example/pubspec.yaml +++ b/packages/file_selector/file_selector_linux/example/pubspec.yaml @@ -4,8 +4,8 @@ publish_to: 'none' version: 1.0.0+1 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: file_selector_linux: diff --git a/packages/file_selector/file_selector_linux/lib/file_selector_linux.dart b/packages/file_selector/file_selector_linux/lib/file_selector_linux.dart index b06523b27d32..3a05243c3110 100644 --- a/packages/file_selector/file_selector_linux/lib/file_selector_linux.dart +++ b/packages/file_selector/file_selector_linux/lib/file_selector_linux.dart @@ -4,30 +4,17 @@ import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; import 'package:flutter/foundation.dart' show visibleForTesting; -import 'package:flutter/services.dart'; -const MethodChannel _channel = - MethodChannel('plugins.flutter.dev/file_selector_linux'); - -const String _typeGroupLabelKey = 'label'; -const String _typeGroupExtensionsKey = 'extensions'; -const String _typeGroupMimeTypesKey = 'mimeTypes'; - -const String _openFileMethod = 'openFile'; -const String _getSavePathMethod = 'getSavePath'; -const String _getDirectoryPathMethod = 'getDirectoryPath'; - -const String _acceptedTypeGroupsKey = 'acceptedTypeGroups'; -const String _confirmButtonTextKey = 'confirmButtonText'; -const String _initialDirectoryKey = 'initialDirectory'; -const String _multipleKey = 'multiple'; -const String _suggestedNameKey = 'suggestedName'; +import 'src/messages.g.dart'; /// An implementation of [FileSelectorPlatform] for Linux. class FileSelectorLinux extends FileSelectorPlatform { - /// The MethodChannel that is being used by this implementation of the plugin. - @visibleForTesting - MethodChannel get channel => _channel; + /// Creates a new plugin implementation instance. + FileSelectorLinux({ + @visibleForTesting FileSelectorApi? api, + }) : _hostApi = api ?? FileSelectorApi(); + + final FileSelectorApi _hostApi; /// Registers the Linux implementation. static void registerWith() { @@ -40,19 +27,16 @@ class FileSelectorLinux extends FileSelectorPlatform { String? initialDirectory, String? confirmButtonText, }) async { - final List> serializedTypeGroups = - _serializeTypeGroups(acceptedTypeGroups); - final List? path = await _channel.invokeListMethod( - _openFileMethod, - { - if (serializedTypeGroups.isNotEmpty) - _acceptedTypeGroupsKey: serializedTypeGroups, - 'initialDirectory': initialDirectory, - _confirmButtonTextKey: confirmButtonText, - _multipleKey: false, - }, - ); - return path == null ? null : XFile(path.first); + final List paths = await _hostApi.showFileChooser( + PlatformFileChooserActionType.open, + PlatformFileChooserOptions( + allowedFileTypes: + _platformTypeGroupsFromXTypeGroups(acceptedTypeGroups), + currentFolderPath: initialDirectory, + acceptButtonLabel: confirmButtonText, + selectMultiple: false, + )); + return paths.isEmpty ? null : XFile(paths.first); } @override @@ -61,19 +45,16 @@ class FileSelectorLinux extends FileSelectorPlatform { String? initialDirectory, String? confirmButtonText, }) async { - final List> serializedTypeGroups = - _serializeTypeGroups(acceptedTypeGroups); - final List? pathList = await _channel.invokeListMethod( - _openFileMethod, - { - if (serializedTypeGroups.isNotEmpty) - _acceptedTypeGroupsKey: serializedTypeGroups, - _initialDirectoryKey: initialDirectory, - _confirmButtonTextKey: confirmButtonText, - _multipleKey: true, - }, - ); - return pathList?.map((String path) => XFile(path)).toList() ?? []; + final List paths = await _hostApi.showFileChooser( + PlatformFileChooserActionType.open, + PlatformFileChooserOptions( + allowedFileTypes: + _platformTypeGroupsFromXTypeGroups(acceptedTypeGroups), + currentFolderPath: initialDirectory, + acceptButtonLabel: confirmButtonText, + selectMultiple: true, + )); + return paths.map((String path) => XFile(path)).toList(); } @override @@ -98,21 +79,18 @@ class FileSelectorLinux extends FileSelectorPlatform { List? acceptedTypeGroups, SaveDialogOptions options = const SaveDialogOptions(), }) async { - final List> serializedTypeGroups = - _serializeTypeGroups(acceptedTypeGroups); // TODO(stuartmorgan): Add the selected type group here and return it. See // https://github.com/flutter/flutter/issues/107093 - final String? path = await _channel.invokeMethod( - _getSavePathMethod, - { - if (serializedTypeGroups.isNotEmpty) - _acceptedTypeGroupsKey: serializedTypeGroups, - _initialDirectoryKey: options.initialDirectory, - _suggestedNameKey: options.suggestedName, - _confirmButtonTextKey: options.confirmButtonText, - }, - ); - return path == null ? null : FileSaveLocation(path); + final List paths = await _hostApi.showFileChooser( + PlatformFileChooserActionType.save, + PlatformFileChooserOptions( + allowedFileTypes: + _platformTypeGroupsFromXTypeGroups(acceptedTypeGroups), + currentFolderPath: options.initialDirectory, + currentName: options.suggestedName, + acceptButtonLabel: options.confirmButtonText, + )); + return paths.isEmpty ? null : FileSaveLocation(paths.first); } @override @@ -120,12 +98,14 @@ class FileSelectorLinux extends FileSelectorPlatform { String? initialDirectory, String? confirmButtonText, }) async { - final List? path = await _channel - .invokeListMethod(_getDirectoryPathMethod, { - _initialDirectoryKey: initialDirectory, - _confirmButtonTextKey: confirmButtonText, - }); - return path?.first; + final List paths = await _hostApi.showFileChooser( + PlatformFileChooserActionType.chooseDirectory, + PlatformFileChooserOptions( + currentFolderPath: initialDirectory, + acceptButtonLabel: confirmButtonText, + selectMultiple: false, + )); + return paths.isEmpty ? null : paths.first; } @override @@ -133,43 +113,42 @@ class FileSelectorLinux extends FileSelectorPlatform { String? initialDirectory, String? confirmButtonText, }) async { - final List? pathList = await _channel - .invokeListMethod(_getDirectoryPathMethod, { - _initialDirectoryKey: initialDirectory, - _confirmButtonTextKey: confirmButtonText, - _multipleKey: true, - }); - return pathList ?? []; + return _hostApi.showFileChooser( + PlatformFileChooserActionType.chooseDirectory, + PlatformFileChooserOptions( + currentFolderPath: initialDirectory, + acceptButtonLabel: confirmButtonText, + selectMultiple: true, + )); } } -List> _serializeTypeGroups(List? groups) { - return (groups ?? []).map(_serializeTypeGroup).toList(); +List? _platformTypeGroupsFromXTypeGroups( + List? groups) { + return groups?.map(_platformTypeGroupFromXTypeGroup).toList(); } -Map _serializeTypeGroup(XTypeGroup group) { - final Map serialization = { - _typeGroupLabelKey: group.label ?? '', - }; +PlatformTypeGroup _platformTypeGroupFromXTypeGroup(XTypeGroup group) { + final String label = group.label ?? ''; if (group.allowsAny) { - serialization[_typeGroupExtensionsKey] = ['*']; - } else { - if ((group.extensions?.isEmpty ?? true) && - (group.mimeTypes?.isEmpty ?? true)) { - throw ArgumentError('Provided type group $group does not allow ' - 'all files, but does not set any of the Linux-supported filter ' - 'categories. "extensions" or "mimeTypes" must be non-empty for Linux ' - 'if anything is non-empty.'); - } - if (group.extensions?.isNotEmpty ?? false) { - serialization[_typeGroupExtensionsKey] = group.extensions + return PlatformTypeGroup( + label: label, + extensions: ['*'], + ); + } + if ((group.extensions?.isEmpty ?? true) && + (group.mimeTypes?.isEmpty ?? true)) { + throw ArgumentError('Provided type group $group does not allow ' + 'all files, but does not set any of the Linux-supported filter ' + 'categories. "extensions" or "mimeTypes" must be non-empty for Linux ' + 'if anything is non-empty.'); + } + return PlatformTypeGroup( + label: label, + // Covert to GtkFileFilter's *. format. + extensions: group.extensions ?.map((String extension) => '*.$extension') .toList() ?? - []; - } - if (group.mimeTypes?.isNotEmpty ?? false) { - serialization[_typeGroupMimeTypesKey] = group.mimeTypes ?? []; - } - } - return serialization; + [], + mimeTypes: group.mimeTypes ?? []); } diff --git a/packages/file_selector/file_selector_linux/lib/src/messages.g.dart b/packages/file_selector/file_selector_linux/lib/src/messages.g.dart new file mode 100644 index 000000000000..7a91c769716b --- /dev/null +++ b/packages/file_selector/file_selector_linux/lib/src/messages.g.dart @@ -0,0 +1,195 @@ +// 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 (v22.4.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 + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; + +import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/services.dart'; + +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); +} + +/// A Pigeon representation of the GTK_FILE_CHOOSER_ACTION_* options. +enum PlatformFileChooserActionType { + open, + chooseDirectory, + save, +} + +/// A Pigeon representation of the Linux portion of an `XTypeGroup`. +class PlatformTypeGroup { + PlatformTypeGroup({ + this.label = '', + this.extensions = const [], + this.mimeTypes = const [], + }); + + String label; + + List extensions; + + List mimeTypes; + + Object encode() { + return [ + label, + extensions, + mimeTypes, + ]; + } + + static PlatformTypeGroup decode(Object result) { + result as List; + return PlatformTypeGroup( + label: result[0]! as String, + extensions: (result[1] as List?)!.cast(), + mimeTypes: (result[2] as List?)!.cast(), + ); + } +} + +/// Options for GKT file chooser. +/// +/// These correspond to gtk_file_chooser_set_* options. +class PlatformFileChooserOptions { + PlatformFileChooserOptions({ + this.allowedFileTypes, + this.currentFolderPath, + this.currentName, + this.acceptButtonLabel, + this.selectMultiple, + }); + + List? allowedFileTypes; + + String? currentFolderPath; + + String? currentName; + + String? acceptButtonLabel; + + /// Whether to allow multiple file selection. + /// + /// Nullable because it does not apply to the "save" action. + bool? selectMultiple; + + Object encode() { + return [ + allowedFileTypes, + currentFolderPath, + currentName, + acceptButtonLabel, + selectMultiple, + ]; + } + + static PlatformFileChooserOptions decode(Object result) { + result as List; + return PlatformFileChooserOptions( + allowedFileTypes: + (result[0] as List?)?.cast(), + currentFolderPath: result[1] as String?, + currentName: result[2] as String?, + acceptButtonLabel: result[3] as String?, + selectMultiple: result[4] as bool?, + ); + } +} + +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is PlatformFileChooserActionType) { + buffer.putUint8(129); + writeValue(buffer, value.index); + } else if (value is PlatformTypeGroup) { + buffer.putUint8(130); + writeValue(buffer, value.encode()); + } else if (value is PlatformFileChooserOptions) { + buffer.putUint8(131); + writeValue(buffer, value.encode()); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 129: + final int? value = readValue(buffer) as int?; + return value == null + ? null + : PlatformFileChooserActionType.values[value]; + case 130: + return PlatformTypeGroup.decode(readValue(buffer)!); + case 131: + return PlatformFileChooserOptions.decode(readValue(buffer)!); + default: + return super.readValueOfType(type, buffer); + } + } +} + +class FileSelectorApi { + /// Constructor for [FileSelectorApi]. 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. + FileSelectorApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String pigeonVar_messageChannelSuffix; + + /// Shows an file chooser with the given [type] and [options], returning the + /// list of selected paths. + /// + /// An empty list corresponds to a cancelled selection. + Future> showFileChooser(PlatformFileChooserActionType type, + PlatformFileChooserOptions options) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.file_selector_linux.FileSelectorApi.showFileChooser$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([type, options]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as List?)!.cast(); + } + } +} diff --git a/packages/file_selector/file_selector_linux/linux/CMakeLists.txt b/packages/file_selector/file_selector_linux/linux/CMakeLists.txt index 1b1af0790de7..148819dc3c5d 100644 --- a/packages/file_selector/file_selector_linux/linux/CMakeLists.txt +++ b/packages/file_selector/file_selector_linux/linux/CMakeLists.txt @@ -8,10 +8,11 @@ set(PLUGIN_NAME "${PROJECT_NAME}_plugin") list(APPEND PLUGIN_SOURCES "file_selector_plugin.cc" + "messages.g.cc" ) add_library(${PLUGIN_NAME} SHARED - "file_selector_plugin.cc" + ${PLUGIN_SOURCES} ) apply_standard_settings(${PLUGIN_NAME}) set_target_properties(${PLUGIN_NAME} PROPERTIES diff --git a/packages/file_selector/file_selector_linux/linux/file_selector_plugin.cc b/packages/file_selector/file_selector_linux/linux/file_selector_plugin.cc index 5a8cc2132595..db27d38c80c2 100644 --- a/packages/file_selector/file_selector_linux/linux/file_selector_plugin.cc +++ b/packages/file_selector/file_selector_linux/linux/file_selector_plugin.cc @@ -8,25 +8,9 @@ #include #include "file_selector_plugin_private.h" +#include "messages.g.h" -// From file_selector_linux.dart -const char kChannelName[] = "plugins.flutter.dev/file_selector_linux"; - -const char kOpenFileMethod[] = "openFile"; -const char kGetSavePathMethod[] = "getSavePath"; -const char kGetDirectoryPathMethod[] = "getDirectoryPath"; - -const char kAcceptedTypeGroupsKey[] = "acceptedTypeGroups"; -const char kConfirmButtonTextKey[] = "confirmButtonText"; -const char kInitialDirectoryKey[] = "initialDirectory"; -const char kMultipleKey[] = "multiple"; -const char kSuggestedNameKey[] = "suggestedName"; - -const char kTypeGroupLabelKey[] = "label"; -const char kTypeGroupExtensionsKey[] = "extensions"; -const char kTypeGroupMimeTypesKey[] = "mimeTypes"; - -// Errors +// Error codes. const char kBadArgumentsError[] = "Bad Arguments"; const char kNoScreenError[] = "No Screen"; @@ -34,39 +18,28 @@ struct _FlFileSelectorPlugin { GObject parent_instance; FlPluginRegistrar* registrar; - - // Connection to Flutter engine. - FlMethodChannel* channel; }; G_DEFINE_TYPE(FlFileSelectorPlugin, fl_file_selector_plugin, G_TYPE_OBJECT) // Converts a type group received from Flutter into a GTK file filter. -static GtkFileFilter* type_group_to_filter(FlValue* value) { +static GtkFileFilter* type_group_to_filter(FfsPlatformTypeGroup* group) { g_autoptr(GtkFileFilter) filter = gtk_file_filter_new(); - FlValue* label = fl_value_lookup_string(value, kTypeGroupLabelKey); - if (label != nullptr && fl_value_get_type(label) == FL_VALUE_TYPE_STRING) { - gtk_file_filter_set_name(filter, fl_value_get_string(label)); - } + const gchar* label = ffs_platform_type_group_get_label(group); + gtk_file_filter_set_name(filter, label); - FlValue* extensions = fl_value_lookup_string(value, kTypeGroupExtensionsKey); - if (extensions != nullptr && - fl_value_get_type(extensions) == FL_VALUE_TYPE_LIST) { - for (size_t i = 0; i < fl_value_get_length(extensions); i++) { - FlValue* v = fl_value_get_list_value(extensions, i); - const gchar* pattern = fl_value_get_string(v); - gtk_file_filter_add_pattern(filter, pattern); - } + FlValue* extensions = ffs_platform_type_group_get_extensions(group); + for (size_t i = 0; i < fl_value_get_length(extensions); i++) { + FlValue* v = fl_value_get_list_value(extensions, i); + const gchar* pattern = fl_value_get_string(v); + gtk_file_filter_add_pattern(filter, pattern); } - FlValue* mime_types = fl_value_lookup_string(value, kTypeGroupMimeTypesKey); - if (mime_types != nullptr && - fl_value_get_type(mime_types) == FL_VALUE_TYPE_LIST) { - for (size_t i = 0; i < fl_value_get_length(mime_types); i++) { - FlValue* v = fl_value_get_list_value(mime_types, i); - const gchar* pattern = fl_value_get_string(v); - gtk_file_filter_add_mime_type(filter, pattern); - } + FlValue* mime_types = ffs_platform_type_group_get_mime_types(group); + for (size_t i = 0; i < fl_value_get_length(mime_types); i++) { + FlValue* v = fl_value_get_list_value(mime_types, i); + const gchar* pattern = fl_value_get_string(v); + gtk_file_filter_add_mime_type(filter, pattern); } return GTK_FILE_FILTER(g_object_ref(filter)); @@ -75,39 +48,45 @@ static GtkFileFilter* type_group_to_filter(FlValue* value) { // Creates a GtkFileChooserNative for the given method call details. static GtkFileChooserNative* create_dialog( GtkWindow* window, GtkFileChooserAction action, const gchar* title, - const gchar* default_confirm_button_text, FlValue* properties) { - const gchar* confirm_button_text = default_confirm_button_text; - FlValue* value = fl_value_lookup_string(properties, kConfirmButtonTextKey); - if (value != nullptr && fl_value_get_type(value) == FL_VALUE_TYPE_STRING) - confirm_button_text = fl_value_get_string(value); + const gchar* default_confirm_button_text, + FfsPlatformFileChooserOptions* options) { + const gchar* confirm_button_text = + ffs_platform_file_chooser_options_get_accept_button_label(options); + if (confirm_button_text == nullptr) { + confirm_button_text = default_confirm_button_text; + } g_autoptr(GtkFileChooserNative) dialog = GTK_FILE_CHOOSER_NATIVE(gtk_file_chooser_native_new( title, window, action, confirm_button_text, "_Cancel")); - value = fl_value_lookup_string(properties, kMultipleKey); - if (value != nullptr && fl_value_get_type(value) == FL_VALUE_TYPE_BOOL) { + const gboolean* select_multiple = + ffs_platform_file_chooser_options_get_select_multiple(options); + if (select_multiple != nullptr) { gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), - fl_value_get_bool(value)); + *select_multiple); } - value = fl_value_lookup_string(properties, kInitialDirectoryKey); - if (value != nullptr && fl_value_get_type(value) == FL_VALUE_TYPE_STRING) { + const gchar* current_folder = + ffs_platform_file_chooser_options_get_current_folder_path(options); + if (current_folder != nullptr) { gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), - fl_value_get_string(value)); + current_folder); } - value = fl_value_lookup_string(properties, kSuggestedNameKey); - if (value != nullptr && fl_value_get_type(value) == FL_VALUE_TYPE_STRING) { - gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), - fl_value_get_string(value)); + const gchar* current_name = + ffs_platform_file_chooser_options_get_current_name(options); + if (current_name != nullptr) { + gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), current_name); } - value = fl_value_lookup_string(properties, kAcceptedTypeGroupsKey); - if (value != nullptr && fl_value_get_type(value) == FL_VALUE_TYPE_LIST) { - for (size_t i = 0; i < fl_value_get_length(value); i++) { - FlValue* type_group = fl_value_get_list_value(value, i); - GtkFileFilter* filter = type_group_to_filter(type_group); + FlValue* type_groups = + ffs_platform_file_chooser_options_get_allowed_file_types(options); + if (type_groups != nullptr) { + for (size_t i = 0; i < fl_value_get_length(type_groups); i++) { + FlValue* type_group = fl_value_get_list_value(type_groups, i); + GtkFileFilter* filter = type_group_to_filter(FFS_PLATFORM_TYPE_GROUP( + fl_value_get_custom_value_object(type_group))); if (filter == nullptr) { return nullptr; } @@ -118,99 +97,65 @@ static GtkFileChooserNative* create_dialog( return GTK_FILE_CHOOSER_NATIVE(g_object_ref(dialog)); } -// TODO(stuartmorgan): Move this logic back into method_call_cb once -// https://github.com/flutter/flutter/issues/88724 is fixed, and test -// through the public API instead. This only exists to move as much -// logic as possible behind the private entry point used by unit tests. -GtkFileChooserNative* create_dialog_for_method(GtkWindow* window, - const gchar* method, - FlValue* properties) { - if (strcmp(method, kOpenFileMethod) == 0) { - return create_dialog(window, GTK_FILE_CHOOSER_ACTION_OPEN, "Open File", - "_Open", properties); - } else if (strcmp(method, kGetDirectoryPathMethod) == 0) { - return create_dialog(window, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, - "Choose Directory", "_Open", properties); - } else if (strcmp(method, kGetSavePathMethod) == 0) { - return create_dialog(window, GTK_FILE_CHOOSER_ACTION_SAVE, "Save File", - "_Save", properties); +GtkFileChooserNative* create_dialog_of_type( + GtkWindow* window, FfsPlatformFileChooserActionType type, + FfsPlatformFileChooserOptions* options) { + switch (type) { + case FILE_SELECTOR_LINUX_PLATFORM_FILE_CHOOSER_ACTION_TYPE_OPEN: + return create_dialog(window, GTK_FILE_CHOOSER_ACTION_OPEN, "Open File", + "_Open", options); + case FILE_SELECTOR_LINUX_PLATFORM_FILE_CHOOSER_ACTION_TYPE_CHOOSE_DIRECTORY: + return create_dialog(window, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, + "Choose Directory", "_Open", options); + case FILE_SELECTOR_LINUX_PLATFORM_FILE_CHOOSER_ACTION_TYPE_SAVE: + return create_dialog(window, GTK_FILE_CHOOSER_ACTION_SAVE, "Save File", + "_Save", options); } return nullptr; } // Shows the requested dialog type. -static FlMethodResponse* show_dialog(FlFileSelectorPlugin* self, - const gchar* method, FlValue* properties, - bool return_list) { - if (fl_value_get_type(properties) != FL_VALUE_TYPE_MAP) { - return FL_METHOD_RESPONSE(fl_method_error_response_new( - kBadArgumentsError, "Argument map missing or malformed", nullptr)); - } +static FfsFileSelectorApiShowFileChooserResponse* handle_show_file_chooser( + FfsPlatformFileChooserActionType type, + FfsPlatformFileChooserOptions* options, gpointer user_data) { + FlFileSelectorPlugin* self = FL_FILE_SELECTOR_PLUGIN(user_data); FlView* view = fl_plugin_registrar_get_view(self->registrar); if (view == nullptr) { - return FL_METHOD_RESPONSE( - fl_method_error_response_new(kNoScreenError, nullptr, nullptr)); + return ffs_file_selector_api_show_file_chooser_response_new_error( + kNoScreenError, nullptr, nullptr); } GtkWindow* window = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(view))); g_autoptr(GtkFileChooserNative) dialog = - create_dialog_for_method(window, method, properties); + create_dialog_of_type(window, type, options); if (dialog == nullptr) { - return FL_METHOD_RESPONSE(fl_method_error_response_new( - kBadArgumentsError, "Unable to create dialog from arguments", nullptr)); + return ffs_file_selector_api_show_file_chooser_response_new_error( + kBadArgumentsError, "Unable to create dialog from arguments", nullptr); } gint response = gtk_native_dialog_run(GTK_NATIVE_DIALOG(dialog)); g_autoptr(FlValue) result = nullptr; if (response == GTK_RESPONSE_ACCEPT) { - if (return_list) { - result = fl_value_new_list(); - g_autoptr(GSList) filenames = - gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog)); - for (GSList* link = filenames; link != nullptr; link = link->next) { - g_autofree gchar* filename = static_cast(link->data); - fl_value_append_take(result, fl_value_new_string(filename)); - } - } else { - g_autofree gchar* filename = - gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - result = fl_value_new_string(filename); + result = fl_value_new_list(); + g_autoptr(GSList) filenames = + gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog)); + for (GSList* link = filenames; link != nullptr; link = link->next) { + g_autofree gchar* filename = static_cast(link->data); + fl_value_append_take(result, fl_value_new_string(filename)); } } - return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); -} - -// Called when a method call is received from Flutter. -static void method_call_cb(FlMethodChannel* channel, FlMethodCall* method_call, - gpointer user_data) { - FlFileSelectorPlugin* self = FL_FILE_SELECTOR_PLUGIN(user_data); - - const gchar* method = fl_method_call_get_name(method_call); - FlValue* args = fl_method_call_get_args(method_call); - - g_autoptr(FlMethodResponse) response = nullptr; - if (strcmp(method, kOpenFileMethod) == 0 || - strcmp(method, kGetDirectoryPathMethod) == 0) { - response = show_dialog(self, method, args, true); - } else if (strcmp(method, kGetSavePathMethod) == 0) { - response = show_dialog(self, method, args, false); - } else { - response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new()); - } - - g_autoptr(GError) error = nullptr; - if (!fl_method_call_respond(method_call, response, &error)) - g_warning("Failed to send method call response: %s", error->message); + return ffs_file_selector_api_show_file_chooser_response_new(result); } static void fl_file_selector_plugin_dispose(GObject* object) { FlFileSelectorPlugin* self = FL_FILE_SELECTOR_PLUGIN(object); + ffs_file_selector_api_clear_method_handlers( + fl_plugin_registrar_get_messenger(self->registrar), nullptr); g_clear_object(&self->registrar); - g_clear_object(&self->channel); G_OBJECT_CLASS(fl_file_selector_plugin_parent_class)->dispose(object); } @@ -229,12 +174,12 @@ FlFileSelectorPlugin* fl_file_selector_plugin_new( self->registrar = FL_PLUGIN_REGISTRAR(g_object_ref(registrar)); - g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new(); - self->channel = - fl_method_channel_new(fl_plugin_registrar_get_messenger(registrar), - kChannelName, FL_METHOD_CODEC(codec)); - fl_method_channel_set_method_call_handler(self->channel, method_call_cb, - g_object_ref(self), g_object_unref); + static FfsFileSelectorApiVTable api_vtable = { + .show_file_chooser = handle_show_file_chooser, + }; + ffs_file_selector_api_set_method_handlers( + fl_plugin_registrar_get_messenger(registrar), nullptr, &api_vtable, + g_object_ref(self), g_object_unref); return self; } diff --git a/packages/file_selector/file_selector_linux/linux/file_selector_plugin_private.h b/packages/file_selector/file_selector_linux/linux/file_selector_plugin_private.h index e58a78ccda37..d8ee91bdd8a7 100644 --- a/packages/file_selector/file_selector_linux/linux/file_selector_plugin_private.h +++ b/packages/file_selector/file_selector_linux/linux/file_selector_plugin_private.h @@ -5,8 +5,15 @@ #include #include "include/file_selector_linux/file_selector_plugin.h" +#include "messages.g.h" // Creates a GtkFileChooserNative for the given method call. -GtkFileChooserNative* create_dialog_for_method(GtkWindow* window, - const gchar* method, - FlValue* properties); +// +// TODO(stuartmorgan): Make this private/static once the tests are restructured +// as descibed in the file_selector_plugin_test.cc TODOs, and then test through +// the Pigeon API handler instead (making that non-static). This only exists to +// move as much logic as possible behind an entry point currently callable by +// unit tests. +GtkFileChooserNative* create_dialog_of_type( + GtkWindow* window, FfsPlatformFileChooserActionType type, + FfsPlatformFileChooserOptions* options); diff --git a/packages/file_selector/file_selector_linux/linux/messages.g.cc b/packages/file_selector/file_selector_linux/linux/messages.g.cc new file mode 100644 index 000000000000..cdcc18b27a26 --- /dev/null +++ b/packages/file_selector/file_selector_linux/linux/messages.g.cc @@ -0,0 +1,545 @@ +// 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 (v22.4.1), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +#include "messages.g.h" + +struct _FfsPlatformTypeGroup { + GObject parent_instance; + + gchar* label; + FlValue* extensions; + FlValue* mime_types; +}; + +G_DEFINE_TYPE(FfsPlatformTypeGroup, ffs_platform_type_group, G_TYPE_OBJECT) + +static void ffs_platform_type_group_dispose(GObject* object) { + FfsPlatformTypeGroup* self = FFS_PLATFORM_TYPE_GROUP(object); + g_clear_pointer(&self->label, g_free); + g_clear_pointer(&self->extensions, fl_value_unref); + g_clear_pointer(&self->mime_types, fl_value_unref); + G_OBJECT_CLASS(ffs_platform_type_group_parent_class)->dispose(object); +} + +static void ffs_platform_type_group_init(FfsPlatformTypeGroup* self) {} + +static void ffs_platform_type_group_class_init( + FfsPlatformTypeGroupClass* klass) { + G_OBJECT_CLASS(klass)->dispose = ffs_platform_type_group_dispose; +} + +FfsPlatformTypeGroup* ffs_platform_type_group_new(const gchar* label, + FlValue* extensions, + FlValue* mime_types) { + FfsPlatformTypeGroup* self = FFS_PLATFORM_TYPE_GROUP( + g_object_new(ffs_platform_type_group_get_type(), nullptr)); + self->label = g_strdup(label); + self->extensions = fl_value_ref(extensions); + self->mime_types = fl_value_ref(mime_types); + return self; +} + +const gchar* ffs_platform_type_group_get_label(FfsPlatformTypeGroup* self) { + g_return_val_if_fail(FFS_IS_PLATFORM_TYPE_GROUP(self), nullptr); + return self->label; +} + +FlValue* ffs_platform_type_group_get_extensions(FfsPlatformTypeGroup* self) { + g_return_val_if_fail(FFS_IS_PLATFORM_TYPE_GROUP(self), nullptr); + return self->extensions; +} + +FlValue* ffs_platform_type_group_get_mime_types(FfsPlatformTypeGroup* self) { + g_return_val_if_fail(FFS_IS_PLATFORM_TYPE_GROUP(self), nullptr); + return self->mime_types; +} + +static FlValue* ffs_platform_type_group_to_list(FfsPlatformTypeGroup* self) { + FlValue* values = fl_value_new_list(); + fl_value_append_take(values, fl_value_new_string(self->label)); + fl_value_append_take(values, fl_value_ref(self->extensions)); + fl_value_append_take(values, fl_value_ref(self->mime_types)); + return values; +} + +static FfsPlatformTypeGroup* ffs_platform_type_group_new_from_list( + FlValue* values) { + FlValue* value0 = fl_value_get_list_value(values, 0); + const gchar* label = fl_value_get_string(value0); + FlValue* value1 = fl_value_get_list_value(values, 1); + FlValue* extensions = value1; + FlValue* value2 = fl_value_get_list_value(values, 2); + FlValue* mime_types = value2; + return ffs_platform_type_group_new(label, extensions, mime_types); +} + +struct _FfsPlatformFileChooserOptions { + GObject parent_instance; + + FlValue* allowed_file_types; + gchar* current_folder_path; + gchar* current_name; + gchar* accept_button_label; + gboolean* select_multiple; +}; + +G_DEFINE_TYPE(FfsPlatformFileChooserOptions, ffs_platform_file_chooser_options, + G_TYPE_OBJECT) + +static void ffs_platform_file_chooser_options_dispose(GObject* object) { + FfsPlatformFileChooserOptions* self = + FFS_PLATFORM_FILE_CHOOSER_OPTIONS(object); + g_clear_pointer(&self->allowed_file_types, fl_value_unref); + g_clear_pointer(&self->current_folder_path, g_free); + g_clear_pointer(&self->current_name, g_free); + g_clear_pointer(&self->accept_button_label, g_free); + g_clear_pointer(&self->select_multiple, g_free); + G_OBJECT_CLASS(ffs_platform_file_chooser_options_parent_class) + ->dispose(object); +} + +static void ffs_platform_file_chooser_options_init( + FfsPlatformFileChooserOptions* self) {} + +static void ffs_platform_file_chooser_options_class_init( + FfsPlatformFileChooserOptionsClass* klass) { + G_OBJECT_CLASS(klass)->dispose = ffs_platform_file_chooser_options_dispose; +} + +FfsPlatformFileChooserOptions* ffs_platform_file_chooser_options_new( + FlValue* allowed_file_types, const gchar* current_folder_path, + const gchar* current_name, const gchar* accept_button_label, + gboolean* select_multiple) { + FfsPlatformFileChooserOptions* self = FFS_PLATFORM_FILE_CHOOSER_OPTIONS( + g_object_new(ffs_platform_file_chooser_options_get_type(), nullptr)); + if (allowed_file_types != nullptr) { + self->allowed_file_types = fl_value_ref(allowed_file_types); + } else { + self->allowed_file_types = nullptr; + } + if (current_folder_path != nullptr) { + self->current_folder_path = g_strdup(current_folder_path); + } else { + self->current_folder_path = nullptr; + } + if (current_name != nullptr) { + self->current_name = g_strdup(current_name); + } else { + self->current_name = nullptr; + } + if (accept_button_label != nullptr) { + self->accept_button_label = g_strdup(accept_button_label); + } else { + self->accept_button_label = nullptr; + } + if (select_multiple != nullptr) { + self->select_multiple = static_cast(malloc(sizeof(gboolean))); + *self->select_multiple = *select_multiple; + } else { + self->select_multiple = nullptr; + } + return self; +} + +FlValue* ffs_platform_file_chooser_options_get_allowed_file_types( + FfsPlatformFileChooserOptions* self) { + g_return_val_if_fail(FFS_IS_PLATFORM_FILE_CHOOSER_OPTIONS(self), nullptr); + return self->allowed_file_types; +} + +const gchar* ffs_platform_file_chooser_options_get_current_folder_path( + FfsPlatformFileChooserOptions* self) { + g_return_val_if_fail(FFS_IS_PLATFORM_FILE_CHOOSER_OPTIONS(self), nullptr); + return self->current_folder_path; +} + +const gchar* ffs_platform_file_chooser_options_get_current_name( + FfsPlatformFileChooserOptions* self) { + g_return_val_if_fail(FFS_IS_PLATFORM_FILE_CHOOSER_OPTIONS(self), nullptr); + return self->current_name; +} + +const gchar* ffs_platform_file_chooser_options_get_accept_button_label( + FfsPlatformFileChooserOptions* self) { + g_return_val_if_fail(FFS_IS_PLATFORM_FILE_CHOOSER_OPTIONS(self), nullptr); + return self->accept_button_label; +} + +gboolean* ffs_platform_file_chooser_options_get_select_multiple( + FfsPlatformFileChooserOptions* self) { + g_return_val_if_fail(FFS_IS_PLATFORM_FILE_CHOOSER_OPTIONS(self), nullptr); + return self->select_multiple; +} + +static FlValue* ffs_platform_file_chooser_options_to_list( + FfsPlatformFileChooserOptions* self) { + FlValue* values = fl_value_new_list(); + fl_value_append_take(values, self->allowed_file_types != nullptr + ? fl_value_ref(self->allowed_file_types) + : fl_value_new_null()); + fl_value_append_take(values, + self->current_folder_path != nullptr + ? fl_value_new_string(self->current_folder_path) + : fl_value_new_null()); + fl_value_append_take(values, self->current_name != nullptr + ? fl_value_new_string(self->current_name) + : fl_value_new_null()); + fl_value_append_take(values, + self->accept_button_label != nullptr + ? fl_value_new_string(self->accept_button_label) + : fl_value_new_null()); + fl_value_append_take(values, self->select_multiple != nullptr + ? fl_value_new_bool(*self->select_multiple) + : fl_value_new_null()); + return values; +} + +static FfsPlatformFileChooserOptions* +ffs_platform_file_chooser_options_new_from_list(FlValue* values) { + FlValue* value0 = fl_value_get_list_value(values, 0); + FlValue* allowed_file_types = nullptr; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + allowed_file_types = value0; + } + FlValue* value1 = fl_value_get_list_value(values, 1); + const gchar* current_folder_path = nullptr; + if (fl_value_get_type(value1) != FL_VALUE_TYPE_NULL) { + current_folder_path = fl_value_get_string(value1); + } + FlValue* value2 = fl_value_get_list_value(values, 2); + const gchar* current_name = nullptr; + if (fl_value_get_type(value2) != FL_VALUE_TYPE_NULL) { + current_name = fl_value_get_string(value2); + } + FlValue* value3 = fl_value_get_list_value(values, 3); + const gchar* accept_button_label = nullptr; + if (fl_value_get_type(value3) != FL_VALUE_TYPE_NULL) { + accept_button_label = fl_value_get_string(value3); + } + FlValue* value4 = fl_value_get_list_value(values, 4); + gboolean* select_multiple = nullptr; + gboolean select_multiple_value; + if (fl_value_get_type(value4) != FL_VALUE_TYPE_NULL) { + select_multiple_value = fl_value_get_bool(value4); + select_multiple = &select_multiple_value; + } + return ffs_platform_file_chooser_options_new( + allowed_file_types, current_folder_path, current_name, + accept_button_label, select_multiple); +} + +G_DECLARE_FINAL_TYPE(FfsMessageCodec, ffs_message_codec, FFS, MESSAGE_CODEC, + FlStandardMessageCodec) + +struct _FfsMessageCodec { + FlStandardMessageCodec parent_instance; +}; + +G_DEFINE_TYPE(FfsMessageCodec, ffs_message_codec, + fl_standard_message_codec_get_type()) + +static gboolean ffs_message_codec_write_ffs_platform_file_chooser_action_type( + FlStandardMessageCodec* codec, GByteArray* buffer, FlValue* value, + GError** error) { + uint8_t type = 129; + g_byte_array_append(buffer, &type, sizeof(uint8_t)); + return fl_standard_message_codec_write_value(codec, buffer, value, error); +} + +static gboolean ffs_message_codec_write_ffs_platform_type_group( + FlStandardMessageCodec* codec, GByteArray* buffer, + FfsPlatformTypeGroup* value, GError** error) { + uint8_t type = 130; + g_byte_array_append(buffer, &type, sizeof(uint8_t)); + g_autoptr(FlValue) values = ffs_platform_type_group_to_list(value); + return fl_standard_message_codec_write_value(codec, buffer, values, error); +} + +static gboolean ffs_message_codec_write_ffs_platform_file_chooser_options( + FlStandardMessageCodec* codec, GByteArray* buffer, + FfsPlatformFileChooserOptions* value, GError** error) { + uint8_t type = 131; + g_byte_array_append(buffer, &type, sizeof(uint8_t)); + g_autoptr(FlValue) values = ffs_platform_file_chooser_options_to_list(value); + return fl_standard_message_codec_write_value(codec, buffer, values, error); +} + +static gboolean ffs_message_codec_write_value(FlStandardMessageCodec* codec, + GByteArray* buffer, + FlValue* value, GError** error) { + if (fl_value_get_type(value) == FL_VALUE_TYPE_CUSTOM) { + switch (fl_value_get_custom_type(value)) { + case 129: + return ffs_message_codec_write_ffs_platform_file_chooser_action_type( + codec, buffer, + reinterpret_cast( + const_cast(fl_value_get_custom_value(value))), + error); + case 130: + return ffs_message_codec_write_ffs_platform_type_group( + codec, buffer, + FFS_PLATFORM_TYPE_GROUP(fl_value_get_custom_value_object(value)), + error); + case 131: + return ffs_message_codec_write_ffs_platform_file_chooser_options( + codec, buffer, + FFS_PLATFORM_FILE_CHOOSER_OPTIONS( + fl_value_get_custom_value_object(value)), + error); + } + } + + return FL_STANDARD_MESSAGE_CODEC_CLASS(ffs_message_codec_parent_class) + ->write_value(codec, buffer, value, error); +} + +static FlValue* ffs_message_codec_read_ffs_platform_file_chooser_action_type( + FlStandardMessageCodec* codec, GBytes* buffer, size_t* offset, + GError** error) { + return fl_value_new_custom( + 129, fl_standard_message_codec_read_value(codec, buffer, offset, error), + (GDestroyNotify)fl_value_unref); +} + +static FlValue* ffs_message_codec_read_ffs_platform_type_group( + FlStandardMessageCodec* codec, GBytes* buffer, size_t* offset, + GError** error) { + g_autoptr(FlValue) values = + fl_standard_message_codec_read_value(codec, buffer, offset, error); + if (values == nullptr) { + return nullptr; + } + + g_autoptr(FfsPlatformTypeGroup) value = + ffs_platform_type_group_new_from_list(values); + if (value == nullptr) { + g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED, + "Invalid data received for MessageData"); + return nullptr; + } + + return fl_value_new_custom_object(130, G_OBJECT(value)); +} + +static FlValue* ffs_message_codec_read_ffs_platform_file_chooser_options( + FlStandardMessageCodec* codec, GBytes* buffer, size_t* offset, + GError** error) { + g_autoptr(FlValue) values = + fl_standard_message_codec_read_value(codec, buffer, offset, error); + if (values == nullptr) { + return nullptr; + } + + g_autoptr(FfsPlatformFileChooserOptions) value = + ffs_platform_file_chooser_options_new_from_list(values); + if (value == nullptr) { + g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED, + "Invalid data received for MessageData"); + return nullptr; + } + + return fl_value_new_custom_object(131, G_OBJECT(value)); +} + +static FlValue* ffs_message_codec_read_value_of_type( + FlStandardMessageCodec* codec, GBytes* buffer, size_t* offset, int type, + GError** error) { + switch (type) { + case 129: + return ffs_message_codec_read_ffs_platform_file_chooser_action_type( + codec, buffer, offset, error); + case 130: + return ffs_message_codec_read_ffs_platform_type_group(codec, buffer, + offset, error); + case 131: + return ffs_message_codec_read_ffs_platform_file_chooser_options( + codec, buffer, offset, error); + default: + return FL_STANDARD_MESSAGE_CODEC_CLASS(ffs_message_codec_parent_class) + ->read_value_of_type(codec, buffer, offset, type, error); + } +} + +static void ffs_message_codec_init(FfsMessageCodec* self) {} + +static void ffs_message_codec_class_init(FfsMessageCodecClass* klass) { + FL_STANDARD_MESSAGE_CODEC_CLASS(klass)->write_value = + ffs_message_codec_write_value; + FL_STANDARD_MESSAGE_CODEC_CLASS(klass)->read_value_of_type = + ffs_message_codec_read_value_of_type; +} + +static FfsMessageCodec* ffs_message_codec_new() { + FfsMessageCodec* self = + FFS_MESSAGE_CODEC(g_object_new(ffs_message_codec_get_type(), nullptr)); + return self; +} + +struct _FfsFileSelectorApiShowFileChooserResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE(FfsFileSelectorApiShowFileChooserResponse, + ffs_file_selector_api_show_file_chooser_response, G_TYPE_OBJECT) + +static void ffs_file_selector_api_show_file_chooser_response_dispose( + GObject* object) { + FfsFileSelectorApiShowFileChooserResponse* self = + FFS_FILE_SELECTOR_API_SHOW_FILE_CHOOSER_RESPONSE(object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS(ffs_file_selector_api_show_file_chooser_response_parent_class) + ->dispose(object); +} + +static void ffs_file_selector_api_show_file_chooser_response_init( + FfsFileSelectorApiShowFileChooserResponse* self) {} + +static void ffs_file_selector_api_show_file_chooser_response_class_init( + FfsFileSelectorApiShowFileChooserResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + ffs_file_selector_api_show_file_chooser_response_dispose; +} + +FfsFileSelectorApiShowFileChooserResponse* +ffs_file_selector_api_show_file_chooser_response_new(FlValue* return_value) { + FfsFileSelectorApiShowFileChooserResponse* self = + FFS_FILE_SELECTOR_API_SHOW_FILE_CHOOSER_RESPONSE(g_object_new( + ffs_file_selector_api_show_file_chooser_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +FfsFileSelectorApiShowFileChooserResponse* +ffs_file_selector_api_show_file_chooser_response_new_error(const gchar* code, + const gchar* message, + FlValue* details) { + FfsFileSelectorApiShowFileChooserResponse* self = + FFS_FILE_SELECTOR_API_SHOW_FILE_CHOOSER_RESPONSE(g_object_new( + ffs_file_selector_api_show_file_chooser_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE(FfsFileSelectorApi, ffs_file_selector_api, FFS, + FILE_SELECTOR_API, GObject) + +struct _FfsFileSelectorApi { + GObject parent_instance; + + const FfsFileSelectorApiVTable* vtable; + gpointer user_data; + GDestroyNotify user_data_free_func; +}; + +G_DEFINE_TYPE(FfsFileSelectorApi, ffs_file_selector_api, G_TYPE_OBJECT) + +static void ffs_file_selector_api_dispose(GObject* object) { + FfsFileSelectorApi* self = FFS_FILE_SELECTOR_API(object); + if (self->user_data != nullptr) { + self->user_data_free_func(self->user_data); + } + self->user_data = nullptr; + G_OBJECT_CLASS(ffs_file_selector_api_parent_class)->dispose(object); +} + +static void ffs_file_selector_api_init(FfsFileSelectorApi* self) {} + +static void ffs_file_selector_api_class_init(FfsFileSelectorApiClass* klass) { + G_OBJECT_CLASS(klass)->dispose = ffs_file_selector_api_dispose; +} + +static FfsFileSelectorApi* ffs_file_selector_api_new( + const FfsFileSelectorApiVTable* vtable, gpointer user_data, + GDestroyNotify user_data_free_func) { + FfsFileSelectorApi* self = FFS_FILE_SELECTOR_API( + g_object_new(ffs_file_selector_api_get_type(), nullptr)); + self->vtable = vtable; + self->user_data = user_data; + self->user_data_free_func = user_data_free_func; + return self; +} + +static void ffs_file_selector_api_show_file_chooser_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + FfsFileSelectorApi* self = FFS_FILE_SELECTOR_API(user_data); + + if (self->vtable == nullptr || self->vtable->show_file_chooser == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FfsPlatformFileChooserActionType type = + static_cast( + fl_value_get_int(reinterpret_cast( + const_cast(fl_value_get_custom_value(value0))))); + FlValue* value1 = fl_value_get_list_value(message_, 1); + FfsPlatformFileChooserOptions* options = FFS_PLATFORM_FILE_CHOOSER_OPTIONS( + fl_value_get_custom_value_object(value1)); + g_autoptr(FfsFileSelectorApiShowFileChooserResponse) response = + self->vtable->show_file_chooser(type, options, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "FileSelectorApi", + "showFileChooser"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "FileSelectorApi", + "showFileChooser", error->message); + } +} + +void ffs_file_selector_api_set_method_handlers( + FlBinaryMessenger* messenger, const gchar* suffix, + const FfsFileSelectorApiVTable* vtable, gpointer user_data, + GDestroyNotify user_data_free_func) { + g_autofree gchar* dot_suffix = + suffix != nullptr ? g_strdup_printf(".%s", suffix) : g_strdup(""); + g_autoptr(FfsFileSelectorApi) api_data = + ffs_file_selector_api_new(vtable, user_data, user_data_free_func); + + g_autoptr(FfsMessageCodec) codec = ffs_message_codec_new(); + g_autofree gchar* show_file_chooser_channel_name = g_strdup_printf( + "dev.flutter.pigeon.file_selector_linux.FileSelectorApi.showFileChooser%" + "s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) show_file_chooser_channel = + fl_basic_message_channel_new(messenger, show_file_chooser_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + show_file_chooser_channel, ffs_file_selector_api_show_file_chooser_cb, + g_object_ref(api_data), g_object_unref); +} + +void ffs_file_selector_api_clear_method_handlers(FlBinaryMessenger* messenger, + const gchar* suffix) { + g_autofree gchar* dot_suffix = + suffix != nullptr ? g_strdup_printf(".%s", suffix) : g_strdup(""); + + g_autoptr(FfsMessageCodec) codec = ffs_message_codec_new(); + g_autofree gchar* show_file_chooser_channel_name = g_strdup_printf( + "dev.flutter.pigeon.file_selector_linux.FileSelectorApi.showFileChooser%" + "s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) show_file_chooser_channel = + fl_basic_message_channel_new(messenger, show_file_chooser_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(show_file_chooser_channel, + nullptr, nullptr, nullptr); +} diff --git a/packages/file_selector/file_selector_linux/linux/messages.g.h b/packages/file_selector/file_selector_linux/linux/messages.g.h new file mode 100644 index 000000000000..2f6251987132 --- /dev/null +++ b/packages/file_selector/file_selector_linux/linux/messages.g.h @@ -0,0 +1,238 @@ +// 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 (v22.4.1), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +#ifndef PIGEON_MESSAGES_G_H_ +#define PIGEON_MESSAGES_G_H_ + +#include + +G_BEGIN_DECLS + +/** + * FfsPlatformFileChooserActionType: + * FILE_SELECTOR_LINUX_PLATFORM_FILE_CHOOSER_ACTION_TYPE_OPEN: + * FILE_SELECTOR_LINUX_PLATFORM_FILE_CHOOSER_ACTION_TYPE_CHOOSE_DIRECTORY: + * FILE_SELECTOR_LINUX_PLATFORM_FILE_CHOOSER_ACTION_TYPE_SAVE: + * + * A Pigeon representation of the GTK_FILE_CHOOSER_ACTION_* options. + */ +typedef enum { + FILE_SELECTOR_LINUX_PLATFORM_FILE_CHOOSER_ACTION_TYPE_OPEN = 0, + FILE_SELECTOR_LINUX_PLATFORM_FILE_CHOOSER_ACTION_TYPE_CHOOSE_DIRECTORY = 1, + FILE_SELECTOR_LINUX_PLATFORM_FILE_CHOOSER_ACTION_TYPE_SAVE = 2 +} FfsPlatformFileChooserActionType; + +/** + * FfsPlatformTypeGroup: + * + * A Pigeon representation of the Linux portion of an `XTypeGroup`. + */ + +G_DECLARE_FINAL_TYPE(FfsPlatformTypeGroup, ffs_platform_type_group, FFS, + PLATFORM_TYPE_GROUP, GObject) + +/** + * ffs_platform_type_group_new: + * label: field in this object. + * extensions: field in this object. + * mime_types: field in this object. + * + * Creates a new #PlatformTypeGroup object. + * + * Returns: a new #FfsPlatformTypeGroup + */ +FfsPlatformTypeGroup* ffs_platform_type_group_new(const gchar* label, + FlValue* extensions, + FlValue* mime_types); + +/** + * ffs_platform_type_group_get_label + * @object: a #FfsPlatformTypeGroup. + * + * Gets the value of the label field of @object. + * + * Returns: the field value. + */ +const gchar* ffs_platform_type_group_get_label(FfsPlatformTypeGroup* object); + +/** + * ffs_platform_type_group_get_extensions + * @object: a #FfsPlatformTypeGroup. + * + * Gets the value of the extensions field of @object. + * + * Returns: the field value. + */ +FlValue* ffs_platform_type_group_get_extensions(FfsPlatformTypeGroup* object); + +/** + * ffs_platform_type_group_get_mime_types + * @object: a #FfsPlatformTypeGroup. + * + * Gets the value of the mimeTypes field of @object. + * + * Returns: the field value. + */ +FlValue* ffs_platform_type_group_get_mime_types(FfsPlatformTypeGroup* object); + +/** + * FfsPlatformFileChooserOptions: + * + * Options for GKT file chooser. + * + * These correspond to gtk_file_chooser_set_* options. + */ + +G_DECLARE_FINAL_TYPE(FfsPlatformFileChooserOptions, + ffs_platform_file_chooser_options, FFS, + PLATFORM_FILE_CHOOSER_OPTIONS, GObject) + +/** + * ffs_platform_file_chooser_options_new: + * allowed_file_types: field in this object. + * current_folder_path: field in this object. + * current_name: field in this object. + * accept_button_label: field in this object. + * select_multiple: field in this object. + * + * Creates a new #PlatformFileChooserOptions object. + * + * Returns: a new #FfsPlatformFileChooserOptions + */ +FfsPlatformFileChooserOptions* ffs_platform_file_chooser_options_new( + FlValue* allowed_file_types, const gchar* current_folder_path, + const gchar* current_name, const gchar* accept_button_label, + gboolean* select_multiple); + +/** + * ffs_platform_file_chooser_options_get_allowed_file_types + * @object: a #FfsPlatformFileChooserOptions. + * + * Gets the value of the allowedFileTypes field of @object. + * + * Returns: the field value. + */ +FlValue* ffs_platform_file_chooser_options_get_allowed_file_types( + FfsPlatformFileChooserOptions* object); + +/** + * ffs_platform_file_chooser_options_get_current_folder_path + * @object: a #FfsPlatformFileChooserOptions. + * + * Gets the value of the currentFolderPath field of @object. + * + * Returns: the field value. + */ +const gchar* ffs_platform_file_chooser_options_get_current_folder_path( + FfsPlatformFileChooserOptions* object); + +/** + * ffs_platform_file_chooser_options_get_current_name + * @object: a #FfsPlatformFileChooserOptions. + * + * Gets the value of the currentName field of @object. + * + * Returns: the field value. + */ +const gchar* ffs_platform_file_chooser_options_get_current_name( + FfsPlatformFileChooserOptions* object); + +/** + * ffs_platform_file_chooser_options_get_accept_button_label + * @object: a #FfsPlatformFileChooserOptions. + * + * Gets the value of the acceptButtonLabel field of @object. + * + * Returns: the field value. + */ +const gchar* ffs_platform_file_chooser_options_get_accept_button_label( + FfsPlatformFileChooserOptions* object); + +/** + * ffs_platform_file_chooser_options_get_select_multiple + * @object: a #FfsPlatformFileChooserOptions. + * + * Whether to allow multiple file selection. + * + * Nullable because it does not apply to the "save" action. + * + * Returns: the field value. + */ +gboolean* ffs_platform_file_chooser_options_get_select_multiple( + FfsPlatformFileChooserOptions* object); + +G_DECLARE_FINAL_TYPE(FfsFileSelectorApiShowFileChooserResponse, + ffs_file_selector_api_show_file_chooser_response, FFS, + FILE_SELECTOR_API_SHOW_FILE_CHOOSER_RESPONSE, GObject) + +/** + * ffs_file_selector_api_show_file_chooser_response_new: + * + * Creates a new response to FileSelectorApi.showFileChooser. + * + * Returns: a new #FfsFileSelectorApiShowFileChooserResponse + */ +FfsFileSelectorApiShowFileChooserResponse* +ffs_file_selector_api_show_file_chooser_response_new(FlValue* return_value); + +/** + * ffs_file_selector_api_show_file_chooser_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to FileSelectorApi.showFileChooser. + * + * Returns: a new #FfsFileSelectorApiShowFileChooserResponse + */ +FfsFileSelectorApiShowFileChooserResponse* +ffs_file_selector_api_show_file_chooser_response_new_error(const gchar* code, + const gchar* message, + FlValue* details); + +/** + * FfsFileSelectorApiVTable: + * + * Table of functions exposed by FileSelectorApi to be implemented by the API + * provider. + */ +typedef struct { + FfsFileSelectorApiShowFileChooserResponse* (*show_file_chooser)( + FfsPlatformFileChooserActionType type, + FfsPlatformFileChooserOptions* options, gpointer user_data); +} FfsFileSelectorApiVTable; + +/** + * ffs_file_selector_api_set_method_handlers: + * + * @messenger: an #FlBinaryMessenger. + * @suffix: (allow-none): a suffix to add to the API or %NULL for none. + * @vtable: implementations of the methods in this API. + * @user_data: (closure): user data to pass to the functions in @vtable. + * @user_data_free_func: (allow-none): a function which gets called to free + * @user_data, or %NULL. + * + * Connects the method handlers in the FileSelectorApi API. + */ +void ffs_file_selector_api_set_method_handlers( + FlBinaryMessenger* messenger, const gchar* suffix, + const FfsFileSelectorApiVTable* vtable, gpointer user_data, + GDestroyNotify user_data_free_func); + +/** + * ffs_file_selector_api_clear_method_handlers: + * + * @messenger: an #FlBinaryMessenger. + * @suffix: (allow-none): a suffix to add to the API or %NULL for none. + * + * Clears the method handlers in the FileSelectorApi API. + */ +void ffs_file_selector_api_clear_method_handlers(FlBinaryMessenger* messenger, + const gchar* suffix); + +G_END_DECLS + +#endif // PIGEON_MESSAGES_G_H_ diff --git a/packages/file_selector/file_selector_linux/linux/test/file_selector_plugin_test.cc b/packages/file_selector/file_selector_linux/linux/test/file_selector_plugin_test.cc index 8762b4a5f9f6..bbd285a7ca12 100644 --- a/packages/file_selector/file_selector_linux/linux/test/file_selector_plugin_test.cc +++ b/packages/file_selector/file_selector_linux/linux/test/file_selector_plugin_test.cc @@ -9,6 +9,7 @@ #include #include "file_selector_plugin_private.h" +#include "messages.g.h" // TODO(stuartmorgan): Restructure the helper to take a callback for showing // the dialog, so that the tests can mock out that callback with something @@ -18,11 +19,20 @@ // gtk_file_chooser_native_new to allow for testing values that are given as // construction paramaters and can't be queried later. +// TODO(stuartmorgan): Remove this once +// https://github.com/flutter/flutter/issues/156100 is fixed. For now, this may +// need to be updated to make unit tests pass again any time the +// Pigeon-generated files are updated. +static const int platform_type_group_object_id = 130; + TEST(FileSelectorPlugin, TestOpenSimple) { - g_autoptr(FlValue) args = fl_value_new_map(); + g_autoptr(FfsPlatformFileChooserOptions) options = + ffs_platform_file_chooser_options_new(nullptr, nullptr, nullptr, nullptr, + nullptr); - g_autoptr(GtkFileChooserNative) dialog = - create_dialog_for_method(nullptr, "openFile", args); + g_autoptr(GtkFileChooserNative) dialog = create_dialog_of_type( + nullptr, FILE_SELECTOR_LINUX_PLATFORM_FILE_CHOOSER_ACTION_TYPE_OPEN, + options); ASSERT_NE(dialog, nullptr); EXPECT_EQ(gtk_file_chooser_get_action(GTK_FILE_CHOOSER(dialog)), @@ -32,11 +42,14 @@ TEST(FileSelectorPlugin, TestOpenSimple) { } TEST(FileSelectorPlugin, TestOpenMultiple) { - g_autoptr(FlValue) args = fl_value_new_map(); - fl_value_set_string_take(args, "multiple", fl_value_new_bool(true)); + gboolean select_multiple = true; + g_autoptr(FfsPlatformFileChooserOptions) options = + ffs_platform_file_chooser_options_new(nullptr, nullptr, nullptr, nullptr, + &select_multiple); - g_autoptr(GtkFileChooserNative) dialog = - create_dialog_for_method(nullptr, "openFile", args); + g_autoptr(GtkFileChooserNative) dialog = create_dialog_of_type( + nullptr, FILE_SELECTOR_LINUX_PLATFORM_FILE_CHOOSER_ACTION_TYPE_OPEN, + options); ASSERT_NE(dialog, nullptr); EXPECT_EQ(gtk_file_chooser_get_action(GTK_FILE_CHOOSER(dialog)), @@ -49,42 +62,54 @@ TEST(FileSelectorPlugin, TestOpenWithFilter) { g_autoptr(FlValue) type_groups = fl_value_new_list(); { + g_autoptr(FlValue) text_group_extensions = fl_value_new_list(); + g_autoptr(FlValue) text_group_mime_types = fl_value_new_list(); fl_value_append_take(text_group_mime_types, fl_value_new_string("text/plain")); - g_autoptr(FlValue) text_group = fl_value_new_map(); - fl_value_set_string_take(text_group, "label", fl_value_new_string("Text")); - fl_value_set_string(text_group, "mimeTypes", text_group_mime_types); - fl_value_append(type_groups, text_group); + + g_autoptr(FfsPlatformTypeGroup) text_group = ffs_platform_type_group_new( + "Text", text_group_extensions, text_group_mime_types); + fl_value_append_take( + type_groups, fl_value_new_custom_object(platform_type_group_object_id, + G_OBJECT(text_group))); } { g_autoptr(FlValue) image_group_extensions = fl_value_new_list(); fl_value_append_take(image_group_extensions, fl_value_new_string("*.png")); fl_value_append_take(image_group_extensions, fl_value_new_string("*.gif")); - fl_value_append_take(image_group_extensions, - fl_value_new_string("*.jgpeg")); - g_autoptr(FlValue) image_group = fl_value_new_map(); - fl_value_set_string_take(image_group, "label", - fl_value_new_string("Images")); - fl_value_set_string(image_group, "extensions", image_group_extensions); - fl_value_append(type_groups, image_group); + fl_value_append_take(image_group_extensions, fl_value_new_string("*.jpeg")); + + g_autoptr(FlValue) image_group_mime_types = fl_value_new_list(); + + g_autoptr(FfsPlatformTypeGroup) image_group = ffs_platform_type_group_new( + "Images", image_group_extensions, image_group_mime_types); + fl_value_append_take( + type_groups, fl_value_new_custom_object(platform_type_group_object_id, + G_OBJECT(image_group))); } { g_autoptr(FlValue) any_group_extensions = fl_value_new_list(); fl_value_append_take(any_group_extensions, fl_value_new_string("*")); - g_autoptr(FlValue) any_group = fl_value_new_map(); - fl_value_set_string_take(any_group, "label", fl_value_new_string("Any")); - fl_value_set_string(any_group, "extensions", any_group_extensions); - fl_value_append(type_groups, any_group); + + g_autoptr(FlValue) any_group_mime_types = fl_value_new_list(); + + g_autoptr(FfsPlatformTypeGroup) any_group = ffs_platform_type_group_new( + "Any", any_group_extensions, any_group_mime_types); + fl_value_append_take( + type_groups, fl_value_new_custom_object(platform_type_group_object_id, + G_OBJECT(any_group))); } - g_autoptr(FlValue) args = fl_value_new_map(); - fl_value_set_string(args, "acceptedTypeGroups", type_groups); + g_autoptr(FfsPlatformFileChooserOptions) options = + ffs_platform_file_chooser_options_new(type_groups, nullptr, nullptr, + nullptr, nullptr); - g_autoptr(GtkFileChooserNative) dialog = - create_dialog_for_method(nullptr, "openFile", args); + g_autoptr(GtkFileChooserNative) dialog = create_dialog_of_type( + nullptr, FILE_SELECTOR_LINUX_PLATFORM_FILE_CHOOSER_ACTION_TYPE_OPEN, + options); ASSERT_NE(dialog, nullptr); EXPECT_EQ(gtk_file_chooser_get_action(GTK_FILE_CHOOSER(dialog)), @@ -122,10 +147,13 @@ TEST(FileSelectorPlugin, TestOpenWithFilter) { } TEST(FileSelectorPlugin, TestSaveSimple) { - g_autoptr(FlValue) args = fl_value_new_map(); + g_autoptr(FfsPlatformFileChooserOptions) options = + ffs_platform_file_chooser_options_new(nullptr, nullptr, nullptr, nullptr, + nullptr); - g_autoptr(GtkFileChooserNative) dialog = - create_dialog_for_method(nullptr, "getSavePath", args); + g_autoptr(GtkFileChooserNative) dialog = create_dialog_of_type( + nullptr, FILE_SELECTOR_LINUX_PLATFORM_FILE_CHOOSER_ACTION_TYPE_SAVE, + options); ASSERT_NE(dialog, nullptr); EXPECT_EQ(gtk_file_chooser_get_action(GTK_FILE_CHOOSER(dialog)), @@ -135,14 +163,13 @@ TEST(FileSelectorPlugin, TestSaveSimple) { } TEST(FileSelectorPlugin, TestSaveWithArguments) { - g_autoptr(FlValue) args = fl_value_new_map(); - fl_value_set_string_take(args, "initialDirectory", - fl_value_new_string("/tmp")); - fl_value_set_string_take(args, "suggestedName", - fl_value_new_string("foo.txt")); + g_autoptr(FfsPlatformFileChooserOptions) options = + ffs_platform_file_chooser_options_new(nullptr, "/tmp", "foo.txt", nullptr, + nullptr); - g_autoptr(GtkFileChooserNative) dialog = - create_dialog_for_method(nullptr, "getSavePath", args); + g_autoptr(GtkFileChooserNative) dialog = create_dialog_of_type( + nullptr, FILE_SELECTOR_LINUX_PLATFORM_FILE_CHOOSER_ACTION_TYPE_SAVE, + options); ASSERT_NE(dialog, nullptr); EXPECT_EQ(gtk_file_chooser_get_action(GTK_FILE_CHOOSER(dialog)), @@ -158,10 +185,14 @@ TEST(FileSelectorPlugin, TestSaveWithArguments) { } TEST(FileSelectorPlugin, TestGetDirectory) { - g_autoptr(FlValue) args = fl_value_new_map(); + g_autoptr(FfsPlatformFileChooserOptions) options = + ffs_platform_file_chooser_options_new(nullptr, nullptr, nullptr, nullptr, + nullptr); - g_autoptr(GtkFileChooserNative) dialog = - create_dialog_for_method(nullptr, "getDirectoryPath", args); + g_autoptr(GtkFileChooserNative) dialog = create_dialog_of_type( + nullptr, + FILE_SELECTOR_LINUX_PLATFORM_FILE_CHOOSER_ACTION_TYPE_CHOOSE_DIRECTORY, + options); ASSERT_NE(dialog, nullptr); EXPECT_EQ(gtk_file_chooser_get_action(GTK_FILE_CHOOSER(dialog)), @@ -171,11 +202,15 @@ TEST(FileSelectorPlugin, TestGetDirectory) { } TEST(FileSelectorPlugin, TestGetMultipleDirectories) { - g_autoptr(FlValue) args = fl_value_new_map(); - fl_value_set_string_take(args, "multiple", fl_value_new_bool(true)); - - g_autoptr(GtkFileChooserNative) dialog = - create_dialog_for_method(nullptr, "getDirectoryPath", args); + gboolean select_multiple = true; + g_autoptr(FfsPlatformFileChooserOptions) options = + ffs_platform_file_chooser_options_new(nullptr, nullptr, nullptr, nullptr, + &select_multiple); + + g_autoptr(GtkFileChooserNative) dialog = create_dialog_of_type( + nullptr, + FILE_SELECTOR_LINUX_PLATFORM_FILE_CHOOSER_ACTION_TYPE_CHOOSE_DIRECTORY, + options); ASSERT_NE(dialog, nullptr); EXPECT_EQ(gtk_file_chooser_get_action(GTK_FILE_CHOOSER(dialog)), diff --git a/packages/file_selector/file_selector_linux/pigeons/copyright.txt b/packages/file_selector/file_selector_linux/pigeons/copyright.txt new file mode 100644 index 000000000000..1236b63caf3a --- /dev/null +++ b/packages/file_selector/file_selector_linux/pigeons/copyright.txt @@ -0,0 +1,3 @@ +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. diff --git a/packages/file_selector/file_selector_linux/pigeons/messages.dart b/packages/file_selector/file_selector_linux/pigeons/messages.dart new file mode 100644 index 000000000000..f10d67cd515e --- /dev/null +++ b/packages/file_selector/file_selector_linux/pigeons/messages.dart @@ -0,0 +1,62 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +import 'package:pigeon/pigeon.dart'; + +@ConfigurePigeon(PigeonOptions( + input: 'pigeons/messages.dart', + gobjectHeaderOut: 'linux/messages.g.h', + gobjectSourceOut: 'linux/messages.g.cc', + gobjectOptions: GObjectOptions(module: 'Ffs'), + dartOut: 'lib/src/messages.g.dart', + copyrightHeader: 'pigeons/copyright.txt', +)) + +/// A Pigeon representation of the GTK_FILE_CHOOSER_ACTION_* options. +enum PlatformFileChooserActionType { open, chooseDirectory, save } + +/// A Pigeon representation of the Linux portion of an `XTypeGroup`. +class PlatformTypeGroup { + const PlatformTypeGroup({ + this.label = '', + this.extensions = const [], + this.mimeTypes = const [], + }); + + final String label; + final List extensions; + final List mimeTypes; +} + +/// Options for GKT file chooser. +/// +/// These correspond to gtk_file_chooser_set_* options. +class PlatformFileChooserOptions { + PlatformFileChooserOptions({ + required this.allowedFileTypes, + required this.currentFolderPath, + required this.currentName, + required this.acceptButtonLabel, + this.selectMultiple, + }); + + final List? allowedFileTypes; + final String? currentFolderPath; + final String? currentName; + final String? acceptButtonLabel; + + /// Whether to allow multiple file selection. + /// + /// Nullable because it does not apply to the "save" action. + final bool? selectMultiple; +} + +@HostApi(dartHostTestHandler: 'TestFileSelectorApi') +abstract class FileSelectorApi { + /// Shows an file chooser with the given [type] and [options], returning the + /// list of selected paths. + /// + /// An empty list corresponds to a cancelled selection. + List showFileChooser( + PlatformFileChooserActionType type, PlatformFileChooserOptions options); +} diff --git a/packages/file_selector/file_selector_linux/pubspec.yaml b/packages/file_selector/file_selector_linux/pubspec.yaml index 4470f4650694..8a9d48b9ad0f 100644 --- a/packages/file_selector/file_selector_linux/pubspec.yaml +++ b/packages/file_selector/file_selector_linux/pubspec.yaml @@ -2,11 +2,11 @@ name: file_selector_linux description: Liunx implementation of the file_selector plugin. repository: https://github.com/flutter/packages/tree/main/packages/file_selector/file_selector_linux issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+file_selector%22 -version: 0.9.2+1 +version: 0.9.3 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -25,6 +25,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter + pigeon: ^22.4.1 topics: - files diff --git a/packages/file_selector/file_selector_linux/test/file_selector_linux_test.dart b/packages/file_selector/file_selector_linux/test/file_selector_linux_test.dart index 8370a3820a84..dbf4bcf4bc3b 100644 --- a/packages/file_selector/file_selector_linux/test/file_selector_linux_test.dart +++ b/packages/file_selector/file_selector_linux/test/file_selector_linux_test.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'package:file_selector_linux/file_selector_linux.dart'; +import 'package:file_selector_linux/src/messages.g.dart'; import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -10,20 +11,12 @@ import 'package:flutter_test/flutter_test.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); + late FakeFileSelectorApi api; late FileSelectorLinux plugin; - late List log; setUp(() { - plugin = FileSelectorLinux(); - log = []; - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler( - plugin.channel, - (MethodCall methodCall) async { - log.add(methodCall); - return null; - }, - ); + api = FakeFileSelectorApi(); + plugin = FileSelectorLinux(api: api); }); test('registers instance', () { @@ -32,6 +25,22 @@ void main() { }); group('openFile', () { + test('passes the core flags correctly', () async { + const String path = '/foo/bar'; + api.result = [path]; + + expect((await plugin.openFile())?.path, path); + + expect(api.passedType, PlatformFileChooserActionType.open); + expect(api.passedOptions?.selectMultiple, false); + }); + + test('handles empty return for cancel', () async { + api.result = []; + + expect(await plugin.openFile(), null); + }); + test('passes the accepted type groups correctly', () async { const XTypeGroup group = XTypeGroup( label: 'text', @@ -47,55 +56,31 @@ void main() { await plugin.openFile(acceptedTypeGroups: [group, groupTwo]); - expectMethodCall( - log, - 'openFile', - arguments: { - 'acceptedTypeGroups': >[ - { - 'label': 'text', - 'extensions': ['*.txt'], - 'mimeTypes': ['text/plain'], - }, - { - 'label': 'image', - 'extensions': ['*.jpg'], - 'mimeTypes': ['image/jpg'], - }, - ], - 'initialDirectory': null, - 'confirmButtonText': null, - 'multiple': false, - }, - ); + expect(api.passedOptions?.allowedFileTypes?[0].label, group.label); + // Extensions should be converted to *. format. + expect(api.passedOptions?.allowedFileTypes?[0].extensions, + ['*.txt']); + expect( + api.passedOptions?.allowedFileTypes?[0].mimeTypes, group.mimeTypes); + expect(api.passedOptions?.allowedFileTypes?[1].label, groupTwo.label); + expect(api.passedOptions?.allowedFileTypes?[1].extensions, + ['*.jpg']); + expect(api.passedOptions?.allowedFileTypes?[1].mimeTypes, + groupTwo.mimeTypes); }); test('passes initialDirectory correctly', () async { - await plugin.openFile(initialDirectory: '/example/directory'); - - expectMethodCall( - log, - 'openFile', - arguments: { - 'initialDirectory': '/example/directory', - 'confirmButtonText': null, - 'multiple': false, - }, - ); + const String path = '/example/directory'; + await plugin.openFile(initialDirectory: path); + + expect(api.passedOptions?.currentFolderPath, path); }); test('passes confirmButtonText correctly', () async { - await plugin.openFile(confirmButtonText: 'Open File'); - - expectMethodCall( - log, - 'openFile', - arguments: { - 'initialDirectory': null, - 'confirmButtonText': 'Open File', - 'multiple': false, - }, - ); + const String button = 'Open File'; + await plugin.openFile(confirmButtonText: button); + + expect(api.passedOptions?.acceptButtonLabel, button); }); test('throws for a type group that does not support Linux', () async { @@ -116,25 +101,24 @@ void main() { await plugin.openFile(acceptedTypeGroups: [group]); - expectMethodCall( - log, - 'openFile', - arguments: { - 'acceptedTypeGroups': >[ - { - 'label': 'any', - 'extensions': ['*'], - }, - ], - 'initialDirectory': null, - 'confirmButtonText': null, - 'multiple': false, - }, - ); + expect(api.passedOptions?.allowedFileTypes?[0].extensions, ['*']); }); }); group('openFiles', () { + test('passes the core flags correctly', () async { + api.result = ['/foo/bar', 'baz']; + + final List files = await plugin.openFiles(); + + expect(files.length, 2); + expect(files[0].path, api.result[0]); + expect(files[1].path, api.result[1]); + + expect(api.passedType, PlatformFileChooserActionType.open); + expect(api.passedOptions?.selectMultiple, true); + }); + test('passes the accepted type groups correctly', () async { const XTypeGroup group = XTypeGroup( label: 'text', @@ -150,55 +134,31 @@ void main() { await plugin.openFiles(acceptedTypeGroups: [group, groupTwo]); - expectMethodCall( - log, - 'openFile', - arguments: { - 'acceptedTypeGroups': >[ - { - 'label': 'text', - 'extensions': ['*.txt'], - 'mimeTypes': ['text/plain'], - }, - { - 'label': 'image', - 'extensions': ['*.jpg'], - 'mimeTypes': ['image/jpg'], - }, - ], - 'initialDirectory': null, - 'confirmButtonText': null, - 'multiple': true, - }, - ); + expect(api.passedOptions?.allowedFileTypes?[0].label, group.label); + // Extensions should be converted to *. format. + expect(api.passedOptions?.allowedFileTypes?[0].extensions, + ['*.txt']); + expect( + api.passedOptions?.allowedFileTypes?[0].mimeTypes, group.mimeTypes); + expect(api.passedOptions?.allowedFileTypes?[1].label, groupTwo.label); + expect(api.passedOptions?.allowedFileTypes?[1].extensions, + ['*.jpg']); + expect(api.passedOptions?.allowedFileTypes?[1].mimeTypes, + groupTwo.mimeTypes); }); test('passes initialDirectory correctly', () async { - await plugin.openFiles(initialDirectory: '/example/directory'); - - expectMethodCall( - log, - 'openFile', - arguments: { - 'initialDirectory': '/example/directory', - 'confirmButtonText': null, - 'multiple': true, - }, - ); + const String path = '/example/directory'; + await plugin.openFiles(initialDirectory: path); + + expect(api.passedOptions?.currentFolderPath, path); }); test('passes confirmButtonText correctly', () async { - await plugin.openFiles(confirmButtonText: 'Open File'); - - expectMethodCall( - log, - 'openFile', - arguments: { - 'initialDirectory': null, - 'confirmButtonText': 'Open File', - 'multiple': true, - }, - ); + const String button = 'Open File'; + await plugin.openFiles(confirmButtonText: button); + + expect(api.passedOptions?.acceptButtonLabel, button); }); test('throws for a type group that does not support Linux', () async { @@ -219,25 +179,20 @@ void main() { await plugin.openFiles(acceptedTypeGroups: [group]); - expectMethodCall( - log, - 'openFile', - arguments: { - 'acceptedTypeGroups': >[ - { - 'label': 'any', - 'extensions': ['*'], - }, - ], - 'initialDirectory': null, - 'confirmButtonText': null, - 'multiple': true, - }, - ); + expect(api.passedOptions?.allowedFileTypes?[0].extensions, ['*']); }); }); group('getSaveLocation', () { + test('passes the core flags correctly', () async { + const String path = '/foo/bar'; + api.result = [path]; + + expect((await plugin.getSaveLocation())?.path, path); + + expect(api.passedType, PlatformFileChooserActionType.save); + }); + test('passes the accepted type groups correctly', () async { const XTypeGroup group = XTypeGroup( label: 'text', @@ -254,58 +209,33 @@ void main() { await plugin .getSaveLocation(acceptedTypeGroups: [group, groupTwo]); - expectMethodCall( - log, - 'getSavePath', - arguments: { - 'acceptedTypeGroups': >[ - { - 'label': 'text', - 'extensions': ['*.txt'], - 'mimeTypes': ['text/plain'], - }, - { - 'label': 'image', - 'extensions': ['*.jpg'], - 'mimeTypes': ['image/jpg'], - }, - ], - 'initialDirectory': null, - 'suggestedName': null, - 'confirmButtonText': null, - }, - ); + expect(api.passedOptions?.allowedFileTypes?[0].label, group.label); + // Extensions should be converted to *. format. + expect(api.passedOptions?.allowedFileTypes?[0].extensions, + ['*.txt']); + expect( + api.passedOptions?.allowedFileTypes?[0].mimeTypes, group.mimeTypes); + expect(api.passedOptions?.allowedFileTypes?[1].label, groupTwo.label); + expect(api.passedOptions?.allowedFileTypes?[1].extensions, + ['*.jpg']); + expect(api.passedOptions?.allowedFileTypes?[1].mimeTypes, + groupTwo.mimeTypes); }); test('passes initialDirectory correctly', () async { + const String path = '/example/directory'; await plugin.getSaveLocation( - options: - const SaveDialogOptions(initialDirectory: '/example/directory')); - - expectMethodCall( - log, - 'getSavePath', - arguments: { - 'initialDirectory': '/example/directory', - 'suggestedName': null, - 'confirmButtonText': null, - }, - ); + options: const SaveDialogOptions(initialDirectory: path)); + + expect(api.passedOptions?.currentFolderPath, path); }); test('passes confirmButtonText correctly', () async { + const String button = 'Open File'; await plugin.getSaveLocation( - options: const SaveDialogOptions(confirmButtonText: 'Open File')); - - expectMethodCall( - log, - 'getSavePath', - arguments: { - 'initialDirectory': null, - 'suggestedName': null, - 'confirmButtonText': 'Open File', - }, - ); + options: const SaveDialogOptions(confirmButtonText: button)); + + expect(api.passedOptions?.acceptButtonLabel, button); }); test('throws for a type group that does not support Linux', () async { @@ -326,25 +256,20 @@ void main() { await plugin.getSaveLocation(acceptedTypeGroups: [group]); - expectMethodCall( - log, - 'getSavePath', - arguments: { - 'acceptedTypeGroups': >[ - { - 'label': 'any', - 'extensions': ['*'], - }, - ], - 'initialDirectory': null, - 'suggestedName': null, - 'confirmButtonText': null, - }, - ); + expect(api.passedOptions?.allowedFileTypes?[0].extensions, ['*']); }); }); group('getSavePath (deprecated)', () { + test('passes the core flags correctly', () async { + const String path = '/foo/bar'; + api.result = [path]; + + expect(await plugin.getSavePath(), path); + + expect(api.passedType, PlatformFileChooserActionType.save); + }); + test('passes the accepted type groups correctly', () async { const XTypeGroup group = XTypeGroup( label: 'text', @@ -361,55 +286,31 @@ void main() { await plugin .getSavePath(acceptedTypeGroups: [group, groupTwo]); - expectMethodCall( - log, - 'getSavePath', - arguments: { - 'acceptedTypeGroups': >[ - { - 'label': 'text', - 'extensions': ['*.txt'], - 'mimeTypes': ['text/plain'], - }, - { - 'label': 'image', - 'extensions': ['*.jpg'], - 'mimeTypes': ['image/jpg'], - }, - ], - 'initialDirectory': null, - 'suggestedName': null, - 'confirmButtonText': null, - }, - ); + expect(api.passedOptions?.allowedFileTypes?[0].label, group.label); + // Extensions should be converted to *. format. + expect(api.passedOptions?.allowedFileTypes?[0].extensions, + ['*.txt']); + expect( + api.passedOptions?.allowedFileTypes?[0].mimeTypes, group.mimeTypes); + expect(api.passedOptions?.allowedFileTypes?[1].label, groupTwo.label); + expect(api.passedOptions?.allowedFileTypes?[1].extensions, + ['*.jpg']); + expect(api.passedOptions?.allowedFileTypes?[1].mimeTypes, + groupTwo.mimeTypes); }); test('passes initialDirectory correctly', () async { - await plugin.getSavePath(initialDirectory: '/example/directory'); - - expectMethodCall( - log, - 'getSavePath', - arguments: { - 'initialDirectory': '/example/directory', - 'suggestedName': null, - 'confirmButtonText': null, - }, - ); + const String path = '/example/directory'; + await plugin.getSavePath(initialDirectory: path); + + expect(api.passedOptions?.currentFolderPath, path); }); test('passes confirmButtonText correctly', () async { - await plugin.getSavePath(confirmButtonText: 'Open File'); - - expectMethodCall( - log, - 'getSavePath', - arguments: { - 'initialDirectory': null, - 'suggestedName': null, - 'confirmButtonText': 'Open File', - }, - ); + const String button = 'Open File'; + await plugin.getSavePath(confirmButtonText: button); + + expect(api.passedOptions?.acceptButtonLabel, button); }); test('throws for a type group that does not support Linux', () async { @@ -430,99 +331,87 @@ void main() { await plugin.getSavePath(acceptedTypeGroups: [group]); - expectMethodCall( - log, - 'getSavePath', - arguments: { - 'acceptedTypeGroups': >[ - { - 'label': 'any', - 'extensions': ['*'], - }, - ], - 'initialDirectory': null, - 'suggestedName': null, - 'confirmButtonText': null, - }, - ); + expect(api.passedOptions?.allowedFileTypes?[0].extensions, ['*']); }); }); group('getDirectoryPath', () { + test('passes the core flags correctly', () async { + const String path = '/foo/bar'; + api.result = [path]; + + expect(await plugin.getDirectoryPath(), path); + + expect(api.passedType, PlatformFileChooserActionType.chooseDirectory); + expect(api.passedOptions?.selectMultiple, false); + }); + test('passes initialDirectory correctly', () async { - await plugin.getDirectoryPath(initialDirectory: '/example/directory'); - - expectMethodCall( - log, - 'getDirectoryPath', - arguments: { - 'initialDirectory': '/example/directory', - 'confirmButtonText': null, - }, - ); + const String path = '/example/directory'; + await plugin.getDirectoryPath(initialDirectory: path); + + expect(api.passedOptions?.currentFolderPath, path); }); + test('passes confirmButtonText correctly', () async { - await plugin.getDirectoryPath(confirmButtonText: 'Select Folder'); - - expectMethodCall( - log, - 'getDirectoryPath', - arguments: { - 'initialDirectory': null, - 'confirmButtonText': 'Select Folder', - }, - ); + const String button = 'Select Folder'; + await plugin.getDirectoryPath(confirmButtonText: button); + + expect(api.passedOptions?.acceptButtonLabel, button); }); }); group('getDirectoryPaths', () { + test('passes the core flags correctly', () async { + api.result = ['/foo/bar', 'baz']; + + expect(await plugin.getDirectoryPaths(), api.result); + + expect(api.passedType, PlatformFileChooserActionType.chooseDirectory); + expect(api.passedOptions?.selectMultiple, true); + }); + test('passes initialDirectory correctly', () async { - await plugin.getDirectoryPaths(initialDirectory: '/example/directory'); - - expectMethodCall( - log, - 'getDirectoryPath', - arguments: { - 'initialDirectory': '/example/directory', - 'confirmButtonText': null, - 'multiple': true, - }, - ); + const String path = '/example/directory'; + await plugin.getDirectoryPaths(initialDirectory: path); + + expect(api.passedOptions?.currentFolderPath, path); }); + test('passes confirmButtonText correctly', () async { - await plugin.getDirectoryPaths( - confirmButtonText: 'Select one or mode folders'); - - expectMethodCall( - log, - 'getDirectoryPath', - arguments: { - 'initialDirectory': null, - 'confirmButtonText': 'Select one or mode folders', - 'multiple': true, - }, - ); + const String button = 'Select one or mode folders'; + await plugin.getDirectoryPaths(confirmButtonText: button); + + expect(api.passedOptions?.acceptButtonLabel, button); }); + test('passes multiple flag correctly', () async { await plugin.getDirectoryPaths(); - expectMethodCall( - log, - 'getDirectoryPath', - arguments: { - 'initialDirectory': null, - 'confirmButtonText': null, - 'multiple': true, - }, - ); + expect(api.passedOptions?.selectMultiple, true); }); }); } -void expectMethodCall( - List log, - String methodName, { - Map? arguments, -}) { - expect(log, [isMethodCall(methodName, arguments: arguments)]); +/// Fake implementation that stores arguments and provides a canned response. +class FakeFileSelectorApi implements FileSelectorApi { + List result = []; + PlatformFileChooserActionType? passedType; + PlatformFileChooserOptions? passedOptions; + + @override + Future> showFileChooser(PlatformFileChooserActionType type, + PlatformFileChooserOptions options) async { + passedType = type; + passedOptions = options; + return result; + } + + @override + // ignore: non_constant_identifier_names + BinaryMessenger? get pigeonVar_binaryMessenger => null; + + @override + // ignore: non_constant_identifier_names + String get pigeonVar_messageChannelSuffix => ''; } diff --git a/packages/file_selector/file_selector_macos/CHANGELOG.md b/packages/file_selector/file_selector_macos/CHANGELOG.md index a48b7ff16bbd..c2c48c5f8485 100644 --- a/packages/file_selector/file_selector_macos/CHANGELOG.md +++ b/packages/file_selector/file_selector_macos/CHANGELOG.md @@ -1,6 +1,11 @@ -## NEXT +## 0.9.4+2 -* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. +* Updates Pigeon for non-nullable collection type support. + +## 0.9.4+1 + +* Adds privacy manifest. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 0.9.4 diff --git a/packages/file_selector/file_selector_macos/README.md b/packages/file_selector/file_selector_macos/README.md index 6fcca5a34bd4..ce243a811f88 100644 --- a/packages/file_selector/file_selector_macos/README.md +++ b/packages/file_selector/file_selector_macos/README.md @@ -26,5 +26,5 @@ or read/write access: depending on your use case. [1]: https://pub.dev/packages/file_selector -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin [3]: https://flutter.dev/desktop#entitlements-and-the-app-sandbox diff --git a/packages/file_selector/file_selector_macos/example/macos/Podfile b/packages/file_selector/file_selector_macos/example/macos/Podfile index 049abe295427..ae77cc1d4269 100644 --- a/packages/file_selector/file_selector_macos/example/macos/Podfile +++ b/packages/file_selector/file_selector_macos/example/macos/Podfile @@ -28,7 +28,6 @@ flutter_macos_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) end diff --git a/packages/file_selector/file_selector_macos/example/pubspec.yaml b/packages/file_selector/file_selector_macos/example/pubspec.yaml index c240f271d7be..70e64c7a83b9 100644 --- a/packages/file_selector/file_selector_macos/example/pubspec.yaml +++ b/packages/file_selector/file_selector_macos/example/pubspec.yaml @@ -4,8 +4,8 @@ publish_to: 'none' version: 1.0.0 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: file_selector_macos: diff --git a/packages/file_selector/file_selector_macos/lib/src/messages.g.dart b/packages/file_selector/file_selector_macos/lib/src/messages.g.dart index cbf8dd10007a..d1d45a2777e5 100644 --- a/packages/file_selector/file_selector_macos/lib/src/messages.g.dart +++ b/packages/file_selector/file_selector_macos/lib/src/messages.g.dart @@ -1,9 +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 (v10.1.3), do not edit directly. +// Autogenerated from Pigeon (v22.4.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 +// 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 import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; @@ -11,19 +11,37 @@ import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; import 'package:flutter/services.dart'; +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); +} + +List wrapResponse( + {Object? result, PlatformException? error, bool empty = false}) { + if (empty) { + return []; + } + if (error == null) { + return [result]; + } + return [error.code, error.message, error.details]; +} + /// A Pigeon representation of the macOS portion of an `XTypeGroup`. class AllowedTypes { AllowedTypes({ - required this.extensions, - required this.mimeTypes, - required this.utis, + this.extensions = const [], + this.mimeTypes = const [], + this.utis = const [], }); - List extensions; + List extensions; - List mimeTypes; + List mimeTypes; - List utis; + List utis; Object encode() { return [ @@ -36,9 +54,9 @@ class AllowedTypes { static AllowedTypes decode(Object result) { result as List; return AllowedTypes( - extensions: (result[0] as List?)!.cast(), - mimeTypes: (result[1] as List?)!.cast(), - utis: (result[2] as List?)!.cast(), + extensions: (result[0] as List?)!.cast(), + mimeTypes: (result[1] as List?)!.cast(), + utis: (result[2] as List?)!.cast(), ); } } @@ -65,7 +83,7 @@ class SavePanelOptions { Object encode() { return [ - allowedFileTypes?.encode(), + allowedFileTypes, directoryPath, nameFieldStringValue, prompt, @@ -75,9 +93,7 @@ class SavePanelOptions { static SavePanelOptions decode(Object result) { result as List; return SavePanelOptions( - allowedFileTypes: result[0] != null - ? AllowedTypes.decode(result[0]! as List) - : null, + allowedFileTypes: result[0] as AllowedTypes?, directoryPath: result[1] as String?, nameFieldStringValue: result[2] as String?, prompt: result[3] as String?, @@ -109,7 +125,7 @@ class OpenPanelOptions { allowsMultipleSelection, canChooseDirectories, canChooseFiles, - baseOptions.encode(), + baseOptions, ]; } @@ -119,24 +135,27 @@ class OpenPanelOptions { allowsMultipleSelection: result[0]! as bool, canChooseDirectories: result[1]! as bool, canChooseFiles: result[2]! as bool, - baseOptions: SavePanelOptions.decode(result[3]! as List), + baseOptions: result[3]! as SavePanelOptions, ); } } -class _FileSelectorApiCodec extends StandardMessageCodec { - const _FileSelectorApiCodec(); +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is AllowedTypes) { - buffer.putUint8(128); - writeValue(buffer, value.encode()); - } else if (value is OpenPanelOptions) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is AllowedTypes) { buffer.putUint8(129); writeValue(buffer, value.encode()); } else if (value is SavePanelOptions) { buffer.putUint8(130); writeValue(buffer, value.encode()); + } else if (value is OpenPanelOptions) { + buffer.putUint8(131); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -145,12 +164,12 @@ class _FileSelectorApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: - return AllowedTypes.decode(readValue(buffer)!); case 129: - return OpenPanelOptions.decode(readValue(buffer)!); + return AllowedTypes.decode(readValue(buffer)!); case 130: return SavePanelOptions.decode(readValue(buffer)!); + case 131: + return OpenPanelOptions.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -161,65 +180,74 @@ class FileSelectorApi { /// Constructor for [FileSelectorApi]. 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. - FileSelectorApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; + FileSelectorApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; - static const MessageCodec codec = _FileSelectorApiCodec(); + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String pigeonVar_messageChannelSuffix; /// Shows an open panel with the given [options], returning the list of /// selected paths. /// /// An empty list corresponds to a cancelled selection. - Future> displayOpenPanel(OpenPanelOptions arg_options) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.FileSelectorApi.displayOpenPanel', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_options]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future> displayOpenPanel(OpenPanelOptions options) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.file_selector_macos.FileSelectorApi.displayOpenPanel$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([options]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 (replyList[0] as List?)!.cast(); + return (pigeonVar_replyList[0] as List?)!.cast(); } } /// Shows a save panel with the given [options], returning the selected path. /// /// A null return corresponds to a cancelled save. - Future displaySavePanel(SavePanelOptions arg_options) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.FileSelectorApi.displaySavePanel', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_options]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future displaySavePanel(SavePanelOptions options) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.file_selector_macos.FileSelectorApi.displaySavePanel$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([options]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { - return (replyList[0] as String?); + return (pigeonVar_replyList[0] as String?); } } } diff --git a/packages/file_selector/file_selector_macos/macos/file_selector_macos.podspec b/packages/file_selector/file_selector_macos/macos/file_selector_macos.podspec index bb4bffee9e00..e4b8a622d6aa 100644 --- a/packages/file_selector/file_selector_macos/macos/file_selector_macos.podspec +++ b/packages/file_selector/file_selector_macos/macos/file_selector_macos.podspec @@ -13,6 +13,7 @@ Displays native macOS open and save panels. s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } s.source = { :http => 'https://github.com/flutter/packages/tree/main/packages/file_selector/file_selector_macos' } s.source_files = 'file_selector_macos/Sources/file_selector_macos/**/*.swift' + s.resource_bundles = {'file_selector_macos_privacy' => ['file_selector_macos/Sources/file_selector_macos/Resources/PrivacyInfo.xcprivacy']} s.dependency 'FlutterMacOS' s.platform = :osx, '10.14' diff --git a/packages/file_selector/file_selector_macos/macos/file_selector_macos/Package.swift b/packages/file_selector/file_selector_macos/macos/file_selector_macos/Package.swift index 97bd0cd8d5dc..d4bc3e313df1 100644 --- a/packages/file_selector/file_selector_macos/macos/file_selector_macos/Package.swift +++ b/packages/file_selector/file_selector_macos/macos/file_selector_macos/Package.swift @@ -19,7 +19,10 @@ let package = Package( targets: [ .target( name: "file_selector_macos", - dependencies: [] + dependencies: [], + resources: [ + .process("Resources") + ] ) ] ) diff --git a/packages/file_selector/file_selector_macos/macos/file_selector_macos/Sources/file_selector_macos/FileSelectorPlugin.swift b/packages/file_selector/file_selector_macos/macos/file_selector_macos/Sources/file_selector_macos/FileSelectorPlugin.swift index c90d69d4609c..e54e91203975 100644 --- a/packages/file_selector/file_selector_macos/macos/file_selector_macos/Sources/file_selector_macos/FileSelectorPlugin.swift +++ b/packages/file_selector/file_selector_macos/macos/file_selector_macos/Sources/file_selector_macos/FileSelectorPlugin.swift @@ -64,7 +64,7 @@ public class FileSelectorPlugin: NSObject, FlutterPlugin, FileSelectorApi { } func displayOpenPanel( - options: OpenPanelOptions, completion: @escaping (Result<[String?], Error>) -> Void + options: OpenPanelOptions, completion: @escaping (Result<[String], Error>) -> Void ) { let panel = NSOpenPanel() configure(openPanel: panel, with: options) @@ -101,26 +101,22 @@ public class FileSelectorPlugin: NSObject, FlutterPlugin, FileSelectorApi { if let acceptedTypes = options.allowedFileTypes { if #available(macOS 11, *), !forceLegacyTypes { var allowedTypes: [UTType] = [] - // The array values are non-null by convention even though Pigeon can't currently express - // that via the types; see messages.dart and https://github.com/flutter/flutter/issues/97848 - allowedTypes.append(contentsOf: acceptedTypes.utis.compactMap({ UTType($0!) })) + allowedTypes.append(contentsOf: acceptedTypes.utis.compactMap({ UTType($0) })) allowedTypes.append( contentsOf: acceptedTypes.extensions.compactMap({ - UTType.init(filenameExtension: $0!) + UTType.init(filenameExtension: $0) })) allowedTypes.append( contentsOf: acceptedTypes.mimeTypes.compactMap({ - UTType.init(mimeType: $0!) + UTType.init(mimeType: $0) })) if !allowedTypes.isEmpty { panel.allowedContentTypes = allowedTypes } } else { var allowedTypes: [String] = [] - // The array values are non-null by convention even though Pigeon can't currently express - // that via the types; see messages.dart and https://github.com/flutter/flutter/issues/97848 - allowedTypes.append(contentsOf: acceptedTypes.extensions.map({ $0! })) - allowedTypes.append(contentsOf: acceptedTypes.utis.map({ $0! })) + allowedTypes.append(contentsOf: acceptedTypes.extensions.map({ $0 })) + allowedTypes.append(contentsOf: acceptedTypes.utis.map({ $0 })) if !allowedTypes.isEmpty { panel.allowedFileTypes = allowedTypes } diff --git a/packages/file_selector/file_selector_macos/macos/file_selector_macos/Sources/file_selector_macos/Resources/PrivacyInfo.xcprivacy b/packages/file_selector/file_selector_macos/macos/file_selector_macos/Sources/file_selector_macos/Resources/PrivacyInfo.xcprivacy new file mode 100644 index 000000000000..918d80be4306 --- /dev/null +++ b/packages/file_selector/file_selector_macos/macos/file_selector_macos/Sources/file_selector_macos/Resources/PrivacyInfo.xcprivacy @@ -0,0 +1,12 @@ + + + + + NSPrivacyTrackingDomains + + NSPrivacyCollectedDataTypes + + NSPrivacyTracking + + + diff --git a/packages/file_selector/file_selector_macos/macos/file_selector_macos/Sources/file_selector_macos/messages.g.swift b/packages/file_selector/file_selector_macos/macos/file_selector_macos/Sources/file_selector_macos/messages.g.swift index 7cff0d721df8..62590d1a46e2 100644 --- a/packages/file_selector/file_selector_macos/macos/file_selector_macos/Sources/file_selector_macos/messages.g.swift +++ b/packages/file_selector/file_selector_macos/macos/file_selector_macos/Sources/file_selector_macos/messages.g.swift @@ -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 (v10.1.3), do not edit directly. +// Autogenerated from Pigeon (v22.4.1), do not edit directly. // See also: https://pub.dev/packages/pigeon import Foundation @@ -14,11 +14,36 @@ import Foundation #error("Unsupported platform.") #endif +/// Error class for passing custom error details to Dart side. +final class PigeonError: Error { + let code: String + let message: String? + let details: Any? + + init(code: String, message: String?, details: Any?) { + self.code = code + self.message = message + self.details = details + } + + var localizedDescription: String { + return + "PigeonError(code: \(code), message: \(message ?? ""), details: \(details ?? "")" + } +} + private func wrapResult(_ result: Any?) -> [Any?] { return [result] } private func wrapError(_ error: Any) -> [Any?] { + if let pigeonError = error as? PigeonError { + return [ + pigeonError.code, + pigeonError.message, + pigeonError.details, + ] + } if let flutterError = error as? FlutterError { return [ flutterError.code, @@ -33,6 +58,10 @@ private func wrapError(_ error: Any) -> [Any?] { ] } +private func isNullish(_ value: Any?) -> Bool { + return value is NSNull || value == nil +} + private func nilOrValue(_ value: Any?) -> T? { if value is NSNull { return nil } return value as! T? @@ -42,14 +71,15 @@ private func nilOrValue(_ value: Any?) -> T? { /// /// Generated class from Pigeon that represents data sent in messages. struct AllowedTypes { - var extensions: [String?] - var mimeTypes: [String?] - var utis: [String?] + var extensions: [String] + var mimeTypes: [String] + var utis: [String] - static func fromList(_ list: [Any?]) -> AllowedTypes? { - let extensions = list[0] as! [String?] - let mimeTypes = list[1] as! [String?] - let utis = list[2] as! [String?] + // swift-format-ignore: AlwaysUseLowerCamelCase + static func fromList(_ pigeonVar_list: [Any?]) -> AllowedTypes? { + let extensions = pigeonVar_list[0] as! [String] + let mimeTypes = pigeonVar_list[1] as! [String] + let utis = pigeonVar_list[2] as! [String] return AllowedTypes( extensions: extensions, @@ -78,14 +108,12 @@ struct SavePanelOptions { var nameFieldStringValue: String? = nil var prompt: String? = nil - static func fromList(_ list: [Any?]) -> SavePanelOptions? { - var allowedFileTypes: AllowedTypes? = nil - if let allowedFileTypesList: [Any?] = nilOrValue(list[0]) { - allowedFileTypes = AllowedTypes.fromList(allowedFileTypesList) - } - let directoryPath: String? = nilOrValue(list[1]) - let nameFieldStringValue: String? = nilOrValue(list[2]) - let prompt: String? = nilOrValue(list[3]) + // swift-format-ignore: AlwaysUseLowerCamelCase + static func fromList(_ pigeonVar_list: [Any?]) -> SavePanelOptions? { + let allowedFileTypes: AllowedTypes? = nilOrValue(pigeonVar_list[0]) + let directoryPath: String? = nilOrValue(pigeonVar_list[1]) + let nameFieldStringValue: String? = nilOrValue(pigeonVar_list[2]) + let prompt: String? = nilOrValue(pigeonVar_list[3]) return SavePanelOptions( allowedFileTypes: allowedFileTypes, @@ -96,7 +124,7 @@ struct SavePanelOptions { } func toList() -> [Any?] { return [ - allowedFileTypes?.toList(), + allowedFileTypes, directoryPath, nameFieldStringValue, prompt, @@ -115,11 +143,12 @@ struct OpenPanelOptions { var canChooseFiles: Bool var baseOptions: SavePanelOptions - static func fromList(_ list: [Any?]) -> OpenPanelOptions? { - let allowsMultipleSelection = list[0] as! Bool - let canChooseDirectories = list[1] as! Bool - let canChooseFiles = list[2] as! Bool - let baseOptions = SavePanelOptions.fromList(list[3] as! [Any?])! + // swift-format-ignore: AlwaysUseLowerCamelCase + static func fromList(_ pigeonVar_list: [Any?]) -> OpenPanelOptions? { + let allowsMultipleSelection = pigeonVar_list[0] as! Bool + let canChooseDirectories = pigeonVar_list[1] as! Bool + let canChooseFiles = pigeonVar_list[2] as! Bool + let baseOptions = pigeonVar_list[3] as! SavePanelOptions return OpenPanelOptions( allowsMultipleSelection: allowsMultipleSelection, @@ -133,55 +162,55 @@ struct OpenPanelOptions { allowsMultipleSelection, canChooseDirectories, canChooseFiles, - baseOptions.toList(), + baseOptions, ] } } -private class FileSelectorApiCodecReader: FlutterStandardReader { +private class messagesPigeonCodecReader: FlutterStandardReader { override func readValue(ofType type: UInt8) -> Any? { switch type { - case 128: - return AllowedTypes.fromList(self.readValue() as! [Any?]) case 129: - return OpenPanelOptions.fromList(self.readValue() as! [Any?]) + return AllowedTypes.fromList(self.readValue() as! [Any?]) case 130: return SavePanelOptions.fromList(self.readValue() as! [Any?]) + case 131: + return OpenPanelOptions.fromList(self.readValue() as! [Any?]) default: return super.readValue(ofType: type) } } } -private class FileSelectorApiCodecWriter: FlutterStandardWriter { +private class messagesPigeonCodecWriter: FlutterStandardWriter { override func writeValue(_ value: Any) { if let value = value as? AllowedTypes { - super.writeByte(128) - super.writeValue(value.toList()) - } else if let value = value as? OpenPanelOptions { super.writeByte(129) super.writeValue(value.toList()) } else if let value = value as? SavePanelOptions { super.writeByte(130) super.writeValue(value.toList()) + } else if let value = value as? OpenPanelOptions { + super.writeByte(131) + super.writeValue(value.toList()) } else { super.writeValue(value) } } } -private class FileSelectorApiCodecReaderWriter: FlutterStandardReaderWriter { +private class messagesPigeonCodecReaderWriter: FlutterStandardReaderWriter { override func reader(with data: Data) -> FlutterStandardReader { - return FileSelectorApiCodecReader(data: data) + return messagesPigeonCodecReader(data: data) } override func writer(with data: NSMutableData) -> FlutterStandardWriter { - return FileSelectorApiCodecWriter(data: data) + return messagesPigeonCodecWriter(data: data) } } -class FileSelectorApiCodec: FlutterStandardMessageCodec { - static let shared = FileSelectorApiCodec(readerWriter: FileSelectorApiCodecReaderWriter()) +class messagesPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable { + static let shared = messagesPigeonCodec(readerWriter: messagesPigeonCodecReaderWriter()) } /// Generated protocol from Pigeon that represents a handler of messages from Flutter. @@ -191,7 +220,7 @@ protocol FileSelectorApi { /// /// An empty list corresponds to a cancelled selection. func displayOpenPanel( - options: OpenPanelOptions, completion: @escaping (Result<[String?], Error>) -> Void) + options: OpenPanelOptions, completion: @escaping (Result<[String], Error>) -> Void) /// Shows a save panel with the given [options], returning the selected path. /// /// A null return corresponds to a cancelled save. @@ -201,17 +230,21 @@ protocol FileSelectorApi { /// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. class FileSelectorApiSetup { - /// The codec used by FileSelectorApi. - static var codec: FlutterStandardMessageCodec { FileSelectorApiCodec.shared } + static var codec: FlutterStandardMessageCodec { messagesPigeonCodec.shared } /// Sets up an instance of `FileSelectorApi` to handle messages through the `binaryMessenger`. - static func setUp(binaryMessenger: FlutterBinaryMessenger, api: FileSelectorApi?) { + static func setUp( + binaryMessenger: FlutterBinaryMessenger, api: FileSelectorApi?, + messageChannelSuffix: String = "" + ) { + let channelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : "" /// Shows an open panel with the given [options], returning the list of /// selected paths. /// /// An empty list corresponds to a cancelled selection. let displayOpenPanelChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.FileSelectorApi.displayOpenPanel", binaryMessenger: binaryMessenger, - codec: codec) + name: + "dev.flutter.pigeon.file_selector_macos.FileSelectorApi.displayOpenPanel\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) if let api = api { displayOpenPanelChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -232,8 +265,9 @@ class FileSelectorApiSetup { /// /// A null return corresponds to a cancelled save. let displaySavePanelChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.FileSelectorApi.displaySavePanel", binaryMessenger: binaryMessenger, - codec: codec) + name: + "dev.flutter.pigeon.file_selector_macos.FileSelectorApi.displaySavePanel\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) if let api = api { displaySavePanelChannel.setMessageHandler { message, reply in let args = message as! [Any?] diff --git a/packages/file_selector/file_selector_macos/pigeons/messages.dart b/packages/file_selector/file_selector_macos/pigeons/messages.dart index 698ebcfc1002..6b80c3d29c48 100644 --- a/packages/file_selector/file_selector_macos/pigeons/messages.dart +++ b/packages/file_selector/file_selector_macos/pigeons/messages.dart @@ -20,12 +20,9 @@ class AllowedTypes { this.utis = const [], }); - // TODO(stuartmorgan): Declare these as non-nullable generics once - // https://github.com/flutter/flutter/issues/97848 is fixed. In practice, - // the values will never be null, and the native implementation assumes that. - final List extensions; - final List mimeTypes; - final List utis; + final List extensions; + final List mimeTypes; + final List utis; } /// Options for save panels. @@ -50,10 +47,10 @@ class SavePanelOptions { /// These correspond to NSOpenPanel properties. class OpenPanelOptions extends SavePanelOptions { const OpenPanelOptions({ - this.allowsMultipleSelection = false, - this.canChooseDirectories = false, - this.canChooseFiles = true, - this.baseOptions = const SavePanelOptions(), + required this.allowsMultipleSelection, + required this.canChooseDirectories, + required this.canChooseFiles, + required this.baseOptions, }); final bool allowsMultipleSelection; final bool canChooseDirectories; @@ -71,11 +68,8 @@ abstract class FileSelectorApi { /// selected paths. /// /// An empty list corresponds to a cancelled selection. - // TODO(stuartmorgan): Declare this return as a non-nullable generic once - // https://github.com/flutter/flutter/issues/97848 is fixed. In practice, - // the values will never be null, and the calling code assumes that. @async - List displayOpenPanel(OpenPanelOptions options); + List displayOpenPanel(OpenPanelOptions options); /// Shows a save panel with the given [options], returning the selected path. /// diff --git a/packages/file_selector/file_selector_macos/pubspec.yaml b/packages/file_selector/file_selector_macos/pubspec.yaml index 00d738d20a34..580eca085ee7 100644 --- a/packages/file_selector/file_selector_macos/pubspec.yaml +++ b/packages/file_selector/file_selector_macos/pubspec.yaml @@ -2,11 +2,11 @@ name: file_selector_macos description: macOS implementation of the file_selector plugin. repository: https://github.com/flutter/packages/tree/main/packages/file_selector/file_selector_macos issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+file_selector%22 -version: 0.9.4 +version: 0.9.4+2 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -26,8 +26,8 @@ dev_dependencies: build_runner: ^2.3.2 flutter_test: sdk: flutter - mockito: 5.4.4 - pigeon: ^10.1.3 + mockito: ^5.4.4 + pigeon: ^22.4.1 topics: - files diff --git a/packages/file_selector/file_selector_macos/test/file_selector_macos_test.dart b/packages/file_selector/file_selector_macos/test/file_selector_macos_test.dart index c7268a6be891..39534230f010 100644 --- a/packages/file_selector/file_selector_macos/test/file_selector_macos_test.dart +++ b/packages/file_selector/file_selector_macos/test/file_selector_macos_test.dart @@ -22,12 +22,12 @@ void main() { setUp(() { plugin = FileSelectorMacOS(); mockApi = MockTestFileSelectorApi(); - TestFileSelectorApi.setup(mockApi); + TestFileSelectorApi.setUp(mockApi); // Set default stubs for tests that don't expect a specific return value, // so calls don't throw. Tests that `expect` return values should override // these locally. - when(mockApi.displayOpenPanel(any)).thenAnswer((_) async => []); + when(mockApi.displayOpenPanel(any)).thenAnswer((_) async => []); when(mockApi.displaySavePanel(any)).thenAnswer((_) async => null); }); @@ -39,7 +39,7 @@ void main() { group('openFile', () { test('works as expected with no arguments', () async { when(mockApi.displayOpenPanel(any)) - .thenAnswer((_) async => ['foo']); + .thenAnswer((_) async => ['foo']); final XFile? file = await plugin.openFile(); @@ -57,7 +57,7 @@ void main() { }); test('handles cancel', () async { - when(mockApi.displayOpenPanel(any)).thenAnswer((_) async => []); + when(mockApi.displayOpenPanel(any)).thenAnswer((_) async => []); final XFile? file = await plugin.openFile(); @@ -134,7 +134,7 @@ void main() { group('openFiles', () { test('works as expected with no arguments', () async { when(mockApi.displayOpenPanel(any)) - .thenAnswer((_) async => ['foo', 'bar']); + .thenAnswer((_) async => ['foo', 'bar']); final List files = await plugin.openFiles(); @@ -153,7 +153,7 @@ void main() { }); test('handles cancel', () async { - when(mockApi.displayOpenPanel(any)).thenAnswer((_) async => []); + when(mockApi.displayOpenPanel(any)).thenAnswer((_) async => []); final List files = await plugin.openFiles(); @@ -467,7 +467,7 @@ void main() { group('getDirectoryPath', () { test('works as expected with no arguments', () async { when(mockApi.displayOpenPanel(any)) - .thenAnswer((_) async => ['foo']); + .thenAnswer((_) async => ['foo']); final String? path = await plugin.getDirectoryPath(); @@ -485,7 +485,7 @@ void main() { }); test('handles cancel', () async { - when(mockApi.displayOpenPanel(any)).thenAnswer((_) async => []); + when(mockApi.displayOpenPanel(any)).thenAnswer((_) async => []); final String? path = await plugin.getDirectoryPath(); @@ -533,7 +533,7 @@ void main() { }); test('handles cancel', () async { - when(mockApi.displayOpenPanel(any)).thenAnswer((_) async => []); + when(mockApi.displayOpenPanel(any)).thenAnswer((_) async => []); final List paths = await plugin.getDirectoryPaths(); diff --git a/packages/file_selector/file_selector_macos/test/file_selector_macos_test.mocks.dart b/packages/file_selector/file_selector_macos/test/file_selector_macos_test.mocks.dart index 6743cfa138ea..63ade67d21a3 100644 --- a/packages/file_selector/file_selector_macos/test/file_selector_macos_test.mocks.dart +++ b/packages/file_selector/file_selector_macos/test/file_selector_macos_test.mocks.dart @@ -33,14 +33,14 @@ class MockTestFileSelectorApi extends _i1.Mock } @override - _i3.Future> displayOpenPanel(_i4.OpenPanelOptions? options) => + _i3.Future> displayOpenPanel(_i4.OpenPanelOptions? options) => (super.noSuchMethod( Invocation.method( #displayOpenPanel, [options], ), - returnValue: _i3.Future>.value([]), - ) as _i3.Future>); + returnValue: _i3.Future>.value([]), + ) as _i3.Future>); @override _i3.Future displaySavePanel(_i4.SavePanelOptions? options) => diff --git a/packages/file_selector/file_selector_macos/test/messages_test.g.dart b/packages/file_selector/file_selector_macos/test/messages_test.g.dart index 893161f8e811..98f1e560b9e0 100644 --- a/packages/file_selector/file_selector_macos/test/messages_test.g.dart +++ b/packages/file_selector/file_selector_macos/test/messages_test.g.dart @@ -1,9 +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 (v10.1.3), do not edit directly. +// Autogenerated from Pigeon (v22.4.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, unnecessary_import +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import, no_leading_underscores_for_local_identifiers // ignore_for_file: avoid_relative_lib_imports import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; @@ -13,19 +13,22 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:file_selector_macos/src/messages.g.dart'; -class _TestFileSelectorApiCodec extends StandardMessageCodec { - const _TestFileSelectorApiCodec(); +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is AllowedTypes) { - buffer.putUint8(128); - writeValue(buffer, value.encode()); - } else if (value is OpenPanelOptions) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is AllowedTypes) { buffer.putUint8(129); writeValue(buffer, value.encode()); } else if (value is SavePanelOptions) { buffer.putUint8(130); writeValue(buffer, value.encode()); + } else if (value is OpenPanelOptions) { + buffer.putUint8(131); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -34,12 +37,12 @@ class _TestFileSelectorApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: - return AllowedTypes.decode(readValue(buffer)!); case 129: - return OpenPanelOptions.decode(readValue(buffer)!); + return AllowedTypes.decode(readValue(buffer)!); case 130: return SavePanelOptions.decode(readValue(buffer)!); + case 131: + return OpenPanelOptions.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -49,62 +52,88 @@ class _TestFileSelectorApiCodec extends StandardMessageCodec { abstract class TestFileSelectorApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec codec = _TestFileSelectorApiCodec(); + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); /// Shows an open panel with the given [options], returning the list of /// selected paths. /// /// An empty list corresponds to a cancelled selection. - Future> displayOpenPanel(OpenPanelOptions options); + Future> displayOpenPanel(OpenPanelOptions options); /// Shows a save panel with the given [options], returning the selected path. /// /// A null return corresponds to a cancelled save. Future displaySavePanel(SavePanelOptions options); - static void setup(TestFileSelectorApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + TestFileSelectorApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.FileSelectorApi.displayOpenPanel', codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.file_selector_macos.FileSelectorApi.displayOpenPanel$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.FileSelectorApi.displayOpenPanel was null.'); + 'Argument for dev.flutter.pigeon.file_selector_macos.FileSelectorApi.displayOpenPanel was null.'); final List args = (message as List?)!; final OpenPanelOptions? arg_options = (args[0] as OpenPanelOptions?); assert(arg_options != null, - 'Argument for dev.flutter.pigeon.FileSelectorApi.displayOpenPanel was null, expected non-null OpenPanelOptions.'); - final List output = await api.displayOpenPanel(arg_options!); - return [output]; + 'Argument for dev.flutter.pigeon.file_selector_macos.FileSelectorApi.displayOpenPanel was null, expected non-null OpenPanelOptions.'); + try { + final List output = + await api.displayOpenPanel(arg_options!); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.FileSelectorApi.displaySavePanel', codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.file_selector_macos.FileSelectorApi.displaySavePanel$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.FileSelectorApi.displaySavePanel was null.'); + 'Argument for dev.flutter.pigeon.file_selector_macos.FileSelectorApi.displaySavePanel was null.'); final List args = (message as List?)!; final SavePanelOptions? arg_options = (args[0] as SavePanelOptions?); assert(arg_options != null, - 'Argument for dev.flutter.pigeon.FileSelectorApi.displaySavePanel was null, expected non-null SavePanelOptions.'); - final String? output = await api.displaySavePanel(arg_options!); - return [output]; + 'Argument for dev.flutter.pigeon.file_selector_macos.FileSelectorApi.displaySavePanel was null, expected non-null SavePanelOptions.'); + try { + final String? output = await api.displaySavePanel(arg_options!); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } diff --git a/packages/file_selector/file_selector_platform_interface/CHANGELOG.md b/packages/file_selector/file_selector_platform_interface/CHANGELOG.md index 073092d3171c..0f90a92eda3c 100644 --- a/packages/file_selector/file_selector_platform_interface/CHANGELOG.md +++ b/packages/file_selector/file_selector_platform_interface/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 2.6.2 diff --git a/packages/file_selector/file_selector_platform_interface/pubspec.yaml b/packages/file_selector/file_selector_platform_interface/pubspec.yaml index d432a511644d..e34e752c31da 100644 --- a/packages/file_selector/file_selector_platform_interface/pubspec.yaml +++ b/packages/file_selector/file_selector_platform_interface/pubspec.yaml @@ -7,8 +7,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 2.6.2 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: cross_file: ^0.3.0 diff --git a/packages/file_selector/file_selector_web/CHANGELOG.md b/packages/file_selector/file_selector_web/CHANGELOG.md index 692d1da7589a..df4f3be17f37 100644 --- a/packages/file_selector/file_selector_web/CHANGELOG.md +++ b/packages/file_selector/file_selector_web/CHANGELOG.md @@ -1,3 +1,11 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + +## 0.9.4+2 + +* Adds support for `web: ^1.0.0`. + ## 0.9.4+1 * Removes a few deprecated API usages. @@ -5,7 +13,7 @@ ## 0.9.4 * Updates web code to package `web: ^0.5.0`. -* Updates SDK version to Dart `^3.3.0`. Flutter `^3.16.0`. +* Updates SDK version to Dart `^3.3.0`. Flutter `^3.19.0`. ## 0.9.3 diff --git a/packages/file_selector/file_selector_web/README.md b/packages/file_selector/file_selector_web/README.md index 3906b2f50825..9c5f94a8ef4b 100644 --- a/packages/file_selector/file_selector_web/README.md +++ b/packages/file_selector/file_selector_web/README.md @@ -12,7 +12,7 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/file_selector -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin ## Limitations on the Web platform diff --git a/packages/file_selector/file_selector_web/example/README.md b/packages/file_selector/file_selector_web/example/README.md index 4a01887de7fb..932e9f227cbe 100644 --- a/packages/file_selector/file_selector_web/example/README.md +++ b/packages/file_selector/file_selector_web/example/README.md @@ -15,5 +15,5 @@ This package uses `package:integration_test` to run its tests in a web browser. See [Plugin Tests > Web Tests](https://github.com/flutter/flutter/blob/master/docs/ecosystem/testing/Plugin-Tests.md#web-tests) in the Flutter documentation for instructions to set up and run the tests in this package. -Check [flutter.dev > Integration testing](https://flutter.dev/docs/testing/integration-tests) +Check [flutter.dev > Integration testing](https://docs.flutter.dev/testing/integration-tests) for more info. diff --git a/packages/file_selector/file_selector_web/example/pubspec.yaml b/packages/file_selector/file_selector_web/example/pubspec.yaml index 689ab97657e7..fef0a1368557 100644 --- a/packages/file_selector/file_selector_web/example/pubspec.yaml +++ b/packages/file_selector/file_selector_web/example/pubspec.yaml @@ -2,8 +2,8 @@ name: file_selector_web_integration_tests publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: file_selector_platform_interface: ^2.6.0 @@ -11,7 +11,7 @@ dependencies: path: ../ flutter: sdk: flutter - web: ^0.5.0 + web: ^1.0.0 dev_dependencies: flutter_test: diff --git a/packages/file_selector/file_selector_web/example/web/index.html b/packages/file_selector/file_selector_web/example/web/index.html index dc9f89762aec..7836d612c4e0 100644 --- a/packages/file_selector/file_selector_web/example/web/index.html +++ b/packages/file_selector/file_selector_web/example/web/index.html @@ -7,6 +7,6 @@ Browser Tests - + diff --git a/packages/file_selector/file_selector_web/pubspec.yaml b/packages/file_selector/file_selector_web/pubspec.yaml index 2b4dc5cd7d9d..1a68fbd0e806 100644 --- a/packages/file_selector/file_selector_web/pubspec.yaml +++ b/packages/file_selector/file_selector_web/pubspec.yaml @@ -2,11 +2,11 @@ name: file_selector_web description: Web platform implementation of file_selector repository: https://github.com/flutter/packages/tree/main/packages/file_selector/file_selector_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+file_selector%22 -version: 0.9.4+1 +version: 0.9.4+2 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: @@ -22,7 +22,7 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - web: ^0.5.0 + web: ">=0.5.1 <2.0.0" dev_dependencies: flutter_test: diff --git a/packages/file_selector/file_selector_windows/CHANGELOG.md b/packages/file_selector/file_selector_windows/CHANGELOG.md index 7d50124560ae..77b5c11c4754 100644 --- a/packages/file_selector/file_selector_windows/CHANGELOG.md +++ b/packages/file_selector/file_selector_windows/CHANGELOG.md @@ -1,5 +1,11 @@ -## NEXT +## 0.9.3+3 +* Updates Pigeon for non-nullable collection type support. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + +## 0.9.3+2 + +* Updates to pigeon 21. * Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. ## 0.9.3+1 diff --git a/packages/file_selector/file_selector_windows/README.md b/packages/file_selector/file_selector_windows/README.md index 7c6ddff34e4b..cf2b722b1a5b 100644 --- a/packages/file_selector/file_selector_windows/README.md +++ b/packages/file_selector/file_selector_windows/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/file_selector -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/file_selector/file_selector_windows/example/pubspec.yaml b/packages/file_selector/file_selector_windows/example/pubspec.yaml index b3c5f8123c46..6d0a226b5128 100644 --- a/packages/file_selector/file_selector_windows/example/pubspec.yaml +++ b/packages/file_selector/file_selector_windows/example/pubspec.yaml @@ -4,8 +4,8 @@ publish_to: 'none' version: 1.0.0 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: file_selector_platform_interface: ^2.6.0 diff --git a/packages/file_selector/file_selector_windows/lib/file_selector_windows.dart b/packages/file_selector/file_selector_windows/lib/file_selector_windows.dart index b96886bd0df6..150e165fd215 100644 --- a/packages/file_selector/file_selector_windows/lib/file_selector_windows.dart +++ b/packages/file_selector/file_selector_windows/lib/file_selector_windows.dart @@ -23,13 +23,11 @@ class FileSelectorWindows extends FileSelectorPlatform { }) async { final FileDialogResult result = await _hostApi.showOpenDialog( SelectionOptions( - allowMultiple: false, - selectFolders: false, allowedTypes: _typeGroupsFromXTypeGroups(acceptedTypeGroups), ), initialDirectory, confirmButtonText); - return result.paths.isEmpty ? null : XFile(result.paths.first!); + return result.paths.isEmpty ? null : XFile(result.paths.first); } @override @@ -41,7 +39,6 @@ class FileSelectorWindows extends FileSelectorPlatform { final FileDialogResult result = await _hostApi.showOpenDialog( SelectionOptions( allowMultiple: true, - selectFolders: false, allowedTypes: _typeGroupsFromXTypeGroups(acceptedTypeGroups), ), initialDirectory, @@ -73,8 +70,6 @@ class FileSelectorWindows extends FileSelectorPlatform { }) async { final FileDialogResult result = await _hostApi.showSaveDialog( SelectionOptions( - allowMultiple: false, - selectFolders: false, allowedTypes: _typeGroupsFromXTypeGroups(acceptedTypeGroups), ), options.initialDirectory, @@ -83,7 +78,7 @@ class FileSelectorWindows extends FileSelectorPlatform { final int? groupIndex = result.typeGroupIndex; return result.paths.isEmpty ? null - : FileSaveLocation(result.paths.first!, + : FileSaveLocation(result.paths.first, activeFilter: groupIndex == null ? null : acceptedTypeGroups?[groupIndex]); } @@ -95,13 +90,12 @@ class FileSelectorWindows extends FileSelectorPlatform { }) async { final FileDialogResult result = await _hostApi.showOpenDialog( SelectionOptions( - allowMultiple: false, selectFolders: true, allowedTypes: [], ), initialDirectory, confirmButtonText); - return result.paths.isEmpty ? null : result.paths.first!; + return result.paths.isEmpty ? null : result.paths.first; } @override diff --git a/packages/file_selector/file_selector_windows/lib/src/messages.g.dart b/packages/file_selector/file_selector_windows/lib/src/messages.g.dart index b5b4a7943888..6ec5eee613cd 100644 --- a/packages/file_selector/file_selector_windows/lib/src/messages.g.dart +++ b/packages/file_selector/file_selector_windows/lib/src/messages.g.dart @@ -1,9 +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 (v10.0.1), do not edit directly. +// Autogenerated from Pigeon (v22.4.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 +// 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 import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; @@ -11,6 +11,24 @@ import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; import 'package:flutter/services.dart'; +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); +} + +List wrapResponse( + {Object? result, PlatformException? error, bool empty = false}) { + if (empty) { + return []; + } + if (error == null) { + return [result]; + } + return [error.code, error.message, error.details]; +} + class TypeGroup { TypeGroup({ required this.label, @@ -19,7 +37,7 @@ class TypeGroup { String label; - List extensions; + List extensions; Object encode() { return [ @@ -32,23 +50,23 @@ class TypeGroup { result as List; return TypeGroup( label: result[0]! as String, - extensions: (result[1] as List?)!.cast(), + extensions: (result[1] as List?)!.cast(), ); } } class SelectionOptions { SelectionOptions({ - required this.allowMultiple, - required this.selectFolders, - required this.allowedTypes, + this.allowMultiple = false, + this.selectFolders = false, + this.allowedTypes = const [], }); bool allowMultiple; bool selectFolders; - List allowedTypes; + List allowedTypes; Object encode() { return [ @@ -63,7 +81,7 @@ class SelectionOptions { return SelectionOptions( allowMultiple: result[0]! as bool, selectFolders: result[1]! as bool, - allowedTypes: (result[2] as List?)!.cast(), + allowedTypes: (result[2] as List?)!.cast(), ); } } @@ -78,7 +96,7 @@ class FileDialogResult { /// The selected paths. /// /// Empty if the dialog was canceled. - List paths; + List paths; /// The type group index (into the list provided in [SelectionOptions]) of /// the group that was selected when the dialog was confirmed. @@ -96,25 +114,28 @@ class FileDialogResult { static FileDialogResult decode(Object result) { result as List; return FileDialogResult( - paths: (result[0] as List?)!.cast(), + paths: (result[0] as List?)!.cast(), typeGroupIndex: result[1] as int?, ); } } -class _FileSelectorApiCodec extends StandardMessageCodec { - const _FileSelectorApiCodec(); +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is FileDialogResult) { - buffer.putUint8(128); - writeValue(buffer, value.encode()); - } else if (value is SelectionOptions) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is TypeGroup) { buffer.putUint8(129); writeValue(buffer, value.encode()); - } else if (value is TypeGroup) { + } else if (value is SelectionOptions) { buffer.putUint8(130); writeValue(buffer, value.encode()); + } else if (value is FileDialogResult) { + buffer.putUint8(131); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -123,12 +144,12 @@ class _FileSelectorApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: - return FileDialogResult.decode(readValue(buffer)!); case 129: - return SelectionOptions.decode(readValue(buffer)!); - case 130: return TypeGroup.decode(readValue(buffer)!); + case 130: + return SelectionOptions.decode(readValue(buffer)!); + case 131: + return FileDialogResult.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -139,73 +160,83 @@ class FileSelectorApi { /// Constructor for [FileSelectorApi]. 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. - FileSelectorApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; - - static const MessageCodec codec = _FileSelectorApiCodec(); - - Future showOpenDialog(SelectionOptions arg_options, - String? arg_initialDirectory, String? arg_confirmButtonText) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.FileSelectorApi.showOpenDialog', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send( - [arg_options, arg_initialDirectory, arg_confirmButtonText]) + FileSelectorApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String pigeonVar_messageChannelSuffix; + + Future showOpenDialog(SelectionOptions options, + String? initialDirectory, String? confirmButtonText) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.file_selector_windows.FileSelectorApi.showOpenDialog$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([options, initialDirectory, confirmButtonText]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 (replyList[0] as FileDialogResult?)!; + return (pigeonVar_replyList[0] as FileDialogResult?)!; } } Future showSaveDialog( - SelectionOptions arg_options, - String? arg_initialDirectory, - String? arg_suggestedName, - String? arg_confirmButtonText) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.FileSelectorApi.showSaveDialog', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send([ - arg_options, - arg_initialDirectory, - arg_suggestedName, - arg_confirmButtonText + SelectionOptions options, + String? initialDirectory, + String? suggestedName, + String? confirmButtonText) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.file_selector_windows.FileSelectorApi.showSaveDialog$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([ + options, + initialDirectory, + suggestedName, + confirmButtonText ]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 (replyList[0] as FileDialogResult?)!; + return (pigeonVar_replyList[0] as FileDialogResult?)!; } } } diff --git a/packages/file_selector/file_selector_windows/pigeons/messages.dart b/packages/file_selector/file_selector_windows/pigeons/messages.dart index 8f82aec0b838..75ba308dc14e 100644 --- a/packages/file_selector/file_selector_windows/pigeons/messages.dart +++ b/packages/file_selector/file_selector_windows/pigeons/messages.dart @@ -16,25 +16,18 @@ class TypeGroup { TypeGroup(this.label, {required this.extensions}); String label; - // TODO(stuartmorgan): Make the generic type non-nullable once supported. - // https://github.com/flutter/flutter/issues/97848 - // The C++ code treats all of it as non-nullable. - List extensions; + List extensions; } class SelectionOptions { SelectionOptions({ this.allowMultiple = false, this.selectFolders = false, - this.allowedTypes = const [], + this.allowedTypes = const [], }); bool allowMultiple; bool selectFolders; - - // TODO(stuartmorgan): Make the generic type non-nullable once supported. - // https://github.com/flutter/flutter/issues/97848 - // The C++ code treats the values as non-nullable. - List allowedTypes; + List allowedTypes; } /// The result from an open or save dialog. @@ -44,10 +37,7 @@ class FileDialogResult { /// The selected paths. /// /// Empty if the dialog was canceled. - // TODO(stuartmorgan): Make the generic type non-nullable once supported. - // https://github.com/flutter/flutter/issues/97848 - // The Dart code treats the values as non-nullable. - List paths; + List paths; /// The type group index (into the list provided in [SelectionOptions]) of /// the group that was selected when the dialog was confirmed. diff --git a/packages/file_selector/file_selector_windows/pubspec.yaml b/packages/file_selector/file_selector_windows/pubspec.yaml index 93159d888fd1..f2631787d6fe 100644 --- a/packages/file_selector/file_selector_windows/pubspec.yaml +++ b/packages/file_selector/file_selector_windows/pubspec.yaml @@ -2,11 +2,11 @@ name: file_selector_windows description: Windows implementation of the file_selector plugin. repository: https://github.com/flutter/packages/tree/main/packages/file_selector/file_selector_windows issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+file_selector%22 -version: 0.9.3+1 +version: 0.9.3+3 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -26,8 +26,8 @@ dev_dependencies: build_runner: ^2.3.0 flutter_test: sdk: flutter - mockito: 5.4.4 - pigeon: ^10.0.0 + mockito: ^5.4.4 + pigeon: ^22.4.1 topics: - files diff --git a/packages/file_selector/file_selector_windows/test/file_selector_windows_test.dart b/packages/file_selector/file_selector_windows/test/file_selector_windows_test.dart index 4f455ee3088b..3a4510672f29 100644 --- a/packages/file_selector/file_selector_windows/test/file_selector_windows_test.dart +++ b/packages/file_selector/file_selector_windows/test/file_selector_windows_test.dart @@ -22,7 +22,7 @@ void main() { setUp(() { mockApi = MockTestFileSelectorApi(); - TestFileSelectorApi.setup(mockApi); + TestFileSelectorApi.setUp(mockApi); }); test('registered instance', () { @@ -33,7 +33,7 @@ void main() { group('openFile', () { setUp(() { when(mockApi.showOpenDialog(any, any, any)) - .thenReturn(FileDialogResult(paths: ['foo'])); + .thenReturn(FileDialogResult(paths: ['foo'])); }); test('simple call works', () async { @@ -109,7 +109,7 @@ void main() { group('openFiles', () { setUp(() { when(mockApi.showOpenDialog(any, any, any)) - .thenReturn(FileDialogResult(paths: ['foo', 'bar'])); + .thenReturn(FileDialogResult(paths: ['foo', 'bar'])); }); test('simple call works', () async { @@ -186,7 +186,7 @@ void main() { group('getDirectoryPath', () { setUp(() { when(mockApi.showOpenDialog(any, any, any)) - .thenReturn(FileDialogResult(paths: ['foo'])); + .thenReturn(FileDialogResult(paths: ['foo'])); }); test('simple call works', () async { @@ -216,11 +216,11 @@ void main() { group('getDirectoryPaths', () { setUp(() { when(mockApi.showOpenDialog(any, any, any)) - .thenReturn(FileDialogResult(paths: ['foo', 'bar'])); + .thenReturn(FileDialogResult(paths: ['foo', 'bar'])); }); test('simple call works', () async { - final List paths = await plugin.getDirectoryPaths(); + final List paths = await plugin.getDirectoryPaths(); expect(paths[0], 'foo'); expect(paths[1], 'bar'); @@ -247,7 +247,7 @@ void main() { group('getSaveLocation', () { setUp(() { when(mockApi.showSaveDialog(any, any, any, any)) - .thenReturn(FileDialogResult(paths: ['foo'])); + .thenReturn(FileDialogResult(paths: ['foo'])); }); test('simple call works', () async { @@ -291,7 +291,7 @@ void main() { test('returns the selected type group correctly', () async { when(mockApi.showSaveDialog(any, any, any, any)).thenReturn( - FileDialogResult(paths: ['foo'], typeGroupIndex: 1)); + FileDialogResult(paths: ['foo'], typeGroupIndex: 1)); const XTypeGroup group = XTypeGroup( label: 'text', extensions: ['txt'], @@ -359,7 +359,7 @@ void main() { group('getSavePath (deprecated)', () { setUp(() { when(mockApi.showSaveDialog(any, any, any, any)) - .thenReturn(FileDialogResult(paths: ['foo'])); + .thenReturn(FileDialogResult(paths: ['foo'])); }); test('simple call works', () async { diff --git a/packages/file_selector/file_selector_windows/test/test_api.g.dart b/packages/file_selector/file_selector_windows/test/test_api.g.dart index 778ae4fc16c3..018f425bf1d8 100644 --- a/packages/file_selector/file_selector_windows/test/test_api.g.dart +++ b/packages/file_selector/file_selector_windows/test/test_api.g.dart @@ -1,9 +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 (v10.0.1), do not edit directly. +// Autogenerated from Pigeon (v22.4.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, unnecessary_import +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import, no_leading_underscores_for_local_identifiers // ignore_for_file: avoid_relative_lib_imports import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; @@ -13,19 +13,22 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:file_selector_windows/src/messages.g.dart'; -class _TestFileSelectorApiCodec extends StandardMessageCodec { - const _TestFileSelectorApiCodec(); +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is FileDialogResult) { - buffer.putUint8(128); - writeValue(buffer, value.encode()); - } else if (value is SelectionOptions) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is TypeGroup) { buffer.putUint8(129); writeValue(buffer, value.encode()); - } else if (value is TypeGroup) { + } else if (value is SelectionOptions) { buffer.putUint8(130); writeValue(buffer, value.encode()); + } else if (value is FileDialogResult) { + buffer.putUint8(131); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -34,12 +37,12 @@ class _TestFileSelectorApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: - return FileDialogResult.decode(readValue(buffer)!); case 129: - return SelectionOptions.decode(readValue(buffer)!); - case 130: return TypeGroup.decode(readValue(buffer)!); + case 130: + return SelectionOptions.decode(readValue(buffer)!); + case 131: + return FileDialogResult.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -49,7 +52,7 @@ class _TestFileSelectorApiCodec extends StandardMessageCodec { abstract class TestFileSelectorApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec codec = _TestFileSelectorApiCodec(); + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); FileDialogResult showOpenDialog(SelectionOptions options, String? initialDirectory, String? confirmButtonText); @@ -60,56 +63,81 @@ abstract class TestFileSelectorApi { String? suggestedName, String? confirmButtonText); - static void setup(TestFileSelectorApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + TestFileSelectorApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.FileSelectorApi.showOpenDialog', codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.file_selector_windows.FileSelectorApi.showOpenDialog$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.FileSelectorApi.showOpenDialog was null.'); + 'Argument for dev.flutter.pigeon.file_selector_windows.FileSelectorApi.showOpenDialog was null.'); final List args = (message as List?)!; final SelectionOptions? arg_options = (args[0] as SelectionOptions?); assert(arg_options != null, - 'Argument for dev.flutter.pigeon.FileSelectorApi.showOpenDialog was null, expected non-null SelectionOptions.'); + 'Argument for dev.flutter.pigeon.file_selector_windows.FileSelectorApi.showOpenDialog was null, expected non-null SelectionOptions.'); final String? arg_initialDirectory = (args[1] as String?); final String? arg_confirmButtonText = (args[2] as String?); - final FileDialogResult output = api.showOpenDialog( - arg_options!, arg_initialDirectory, arg_confirmButtonText); - return [output]; + try { + final FileDialogResult output = api.showOpenDialog( + arg_options!, arg_initialDirectory, arg_confirmButtonText); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.FileSelectorApi.showSaveDialog', codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.file_selector_windows.FileSelectorApi.showSaveDialog$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.FileSelectorApi.showSaveDialog was null.'); + 'Argument for dev.flutter.pigeon.file_selector_windows.FileSelectorApi.showSaveDialog was null.'); final List args = (message as List?)!; final SelectionOptions? arg_options = (args[0] as SelectionOptions?); assert(arg_options != null, - 'Argument for dev.flutter.pigeon.FileSelectorApi.showSaveDialog was null, expected non-null SelectionOptions.'); + 'Argument for dev.flutter.pigeon.file_selector_windows.FileSelectorApi.showSaveDialog was null, expected non-null SelectionOptions.'); final String? arg_initialDirectory = (args[1] as String?); final String? arg_suggestedName = (args[2] as String?); final String? arg_confirmButtonText = (args[3] as String?); - final FileDialogResult output = api.showSaveDialog(arg_options!, - arg_initialDirectory, arg_suggestedName, arg_confirmButtonText); - return [output]; + try { + final FileDialogResult output = api.showSaveDialog(arg_options!, + arg_initialDirectory, arg_suggestedName, arg_confirmButtonText); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } diff --git a/packages/file_selector/file_selector_windows/windows/messages.g.cpp b/packages/file_selector/file_selector_windows/windows/messages.g.cpp index a60fd92a974c..f831e50ead39 100644 --- a/packages/file_selector/file_selector_windows/windows/messages.g.cpp +++ b/packages/file_selector/file_selector_windows/windows/messages.g.cpp @@ -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 (v10.0.1), do not edit directly. +// Autogenerated from Pigeon (v22.4.1), do not edit directly. // See also: https://pub.dev/packages/pigeon #undef _HAS_EXCEPTIONS @@ -24,6 +24,13 @@ using flutter::EncodableList; using flutter::EncodableMap; using flutter::EncodableValue; +FlutterError CreateConnectionError(const std::string channel_name) { + return FlutterError( + "channel-error", + "Unable to establish connection on channel: '" + channel_name + "'.", + EncodableValue("")); +} + // TypeGroup TypeGroup::TypeGroup(const std::string& label, const EncodableList& extensions) @@ -142,55 +149,58 @@ FileDialogResult FileDialogResult::FromEncodableList( FileDialogResult decoded(std::get(list[0])); auto& encodable_type_group_index = list[1]; if (!encodable_type_group_index.IsNull()) { - decoded.set_type_group_index(encodable_type_group_index.LongValue()); + decoded.set_type_group_index(std::get(encodable_type_group_index)); } return decoded; } -FileSelectorApiCodecSerializer::FileSelectorApiCodecSerializer() {} +PigeonInternalCodecSerializer::PigeonInternalCodecSerializer() {} -EncodableValue FileSelectorApiCodecSerializer::ReadValueOfType( +EncodableValue PigeonInternalCodecSerializer::ReadValueOfType( uint8_t type, flutter::ByteStreamReader* stream) const { switch (type) { - case 128: - return CustomEncodableValue(FileDialogResult::FromEncodableList( + case 129: { + return CustomEncodableValue(TypeGroup::FromEncodableList( std::get(ReadValue(stream)))); - case 129: + } + case 130: { return CustomEncodableValue(SelectionOptions::FromEncodableList( std::get(ReadValue(stream)))); - case 130: - return CustomEncodableValue(TypeGroup::FromEncodableList( + } + case 131: { + return CustomEncodableValue(FileDialogResult::FromEncodableList( std::get(ReadValue(stream)))); + } default: return flutter::StandardCodecSerializer::ReadValueOfType(type, stream); } } -void FileSelectorApiCodecSerializer::WriteValue( +void PigeonInternalCodecSerializer::WriteValue( const EncodableValue& value, flutter::ByteStreamWriter* stream) const { if (const CustomEncodableValue* custom_value = std::get_if(&value)) { - if (custom_value->type() == typeid(FileDialogResult)) { - stream->WriteByte(128); - WriteValue( - EncodableValue( - std::any_cast(*custom_value).ToEncodableList()), - stream); + if (custom_value->type() == typeid(TypeGroup)) { + stream->WriteByte(129); + WriteValue(EncodableValue( + std::any_cast(*custom_value).ToEncodableList()), + stream); return; } if (custom_value->type() == typeid(SelectionOptions)) { - stream->WriteByte(129); + stream->WriteByte(130); WriteValue( EncodableValue( std::any_cast(*custom_value).ToEncodableList()), stream); return; } - if (custom_value->type() == typeid(TypeGroup)) { - stream->WriteByte(130); - WriteValue(EncodableValue( - std::any_cast(*custom_value).ToEncodableList()), - stream); + if (custom_value->type() == typeid(FileDialogResult)) { + stream->WriteByte(131); + WriteValue( + EncodableValue( + std::any_cast(*custom_value).ToEncodableList()), + stream); return; } } @@ -200,19 +210,31 @@ void FileSelectorApiCodecSerializer::WriteValue( /// The codec used by FileSelectorApi. const flutter::StandardMessageCodec& FileSelectorApi::GetCodec() { return flutter::StandardMessageCodec::GetInstance( - &FileSelectorApiCodecSerializer::GetInstance()); + &PigeonInternalCodecSerializer::GetInstance()); } // Sets up an instance of `FileSelectorApi` to handle messages through the // `binary_messenger`. void FileSelectorApi::SetUp(flutter::BinaryMessenger* binary_messenger, FileSelectorApi* api) { + FileSelectorApi::SetUp(binary_messenger, api, ""); +} + +void FileSelectorApi::SetUp(flutter::BinaryMessenger* binary_messenger, + FileSelectorApi* api, + const std::string& message_channel_suffix) { + const std::string prepended_suffix = + message_channel_suffix.length() > 0 + ? std::string(".") + message_channel_suffix + : ""; { - auto channel = std::make_unique>( - binary_messenger, "dev.flutter.pigeon.FileSelectorApi.showOpenDialog", - &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.file_selector_windows." + "FileSelectorApi.showOpenDialog" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { - channel->SetMessageHandler( + channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { @@ -245,15 +267,17 @@ void FileSelectorApi::SetUp(flutter::BinaryMessenger* binary_messenger, } }); } else { - channel->SetMessageHandler(nullptr); + channel.SetMessageHandler(nullptr); } } { - auto channel = std::make_unique>( - binary_messenger, "dev.flutter.pigeon.FileSelectorApi.showSaveDialog", - &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.file_selector_windows." + "FileSelectorApi.showSaveDialog" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { - channel->SetMessageHandler( + channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { @@ -290,7 +314,7 @@ void FileSelectorApi::SetUp(flutter::BinaryMessenger* binary_messenger, } }); } else { - channel->SetMessageHandler(nullptr); + channel.SetMessageHandler(nullptr); } } } diff --git a/packages/file_selector/file_selector_windows/windows/messages.g.h b/packages/file_selector/file_selector_windows/windows/messages.g.h index ab8afd7d703b..edd0865d78c3 100644 --- a/packages/file_selector/file_selector_windows/windows/messages.g.h +++ b/packages/file_selector/file_selector_windows/windows/messages.g.h @@ -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 (v10.0.1), do not edit directly. +// Autogenerated from Pigeon (v22.4.1), do not edit directly. // See also: https://pub.dev/packages/pigeon #ifndef PIGEON_MESSAGES_G_H_ @@ -75,7 +75,7 @@ class TypeGroup { static TypeGroup FromEncodableList(const flutter::EncodableList& list); flutter::EncodableList ToEncodableList() const; friend class FileSelectorApi; - friend class FileSelectorApiCodecSerializer; + friend class PigeonInternalCodecSerializer; std::string label_; flutter::EncodableList extensions_; }; @@ -100,7 +100,7 @@ class SelectionOptions { static SelectionOptions FromEncodableList(const flutter::EncodableList& list); flutter::EncodableList ToEncodableList() const; friend class FileSelectorApi; - friend class FileSelectorApiCodecSerializer; + friend class PigeonInternalCodecSerializer; bool allow_multiple_; bool select_folders_; flutter::EncodableList allowed_types_; @@ -136,16 +136,16 @@ class FileDialogResult { static FileDialogResult FromEncodableList(const flutter::EncodableList& list); flutter::EncodableList ToEncodableList() const; friend class FileSelectorApi; - friend class FileSelectorApiCodecSerializer; + friend class PigeonInternalCodecSerializer; flutter::EncodableList paths_; std::optional type_group_index_; }; -class FileSelectorApiCodecSerializer : public flutter::StandardCodecSerializer { +class PigeonInternalCodecSerializer : public flutter::StandardCodecSerializer { public: - FileSelectorApiCodecSerializer(); - inline static FileSelectorApiCodecSerializer& GetInstance() { - static FileSelectorApiCodecSerializer sInstance; + PigeonInternalCodecSerializer(); + inline static PigeonInternalCodecSerializer& GetInstance() { + static PigeonInternalCodecSerializer sInstance; return sInstance; } @@ -178,6 +178,9 @@ class FileSelectorApi { // `binary_messenger`. static void SetUp(flutter::BinaryMessenger* binary_messenger, FileSelectorApi* api); + static void SetUp(flutter::BinaryMessenger* binary_messenger, + FileSelectorApi* api, + const std::string& message_channel_suffix); static flutter::EncodableValue WrapError(std::string_view error_message); static flutter::EncodableValue WrapError(const FlutterError& error); diff --git a/packages/flutter_adaptive_scaffold/CHANGELOG.md b/packages/flutter_adaptive_scaffold/CHANGELOG.md index 43cdac63da7b..69ffdcd0a516 100644 --- a/packages/flutter_adaptive_scaffold/CHANGELOG.md +++ b/packages/flutter_adaptive_scaffold/CHANGELOG.md @@ -1,3 +1,63 @@ +## 0.3.1 + +* Use improved MediaQuery methods. + +## 0.3.0 + +* Adds `inDuration`, `outDuration`, `inCurve`, and `outCurve` parameters for +configuring additional `SlotLayoutConfig` animation behavior. +* **BREAKING CHANGES**: + * Removes `duration` parameter from `SlotLayoutConfig`. + +## 0.2.6 + +* Add new sample for using AdaptiveScaffold with GoRouter. + +## 0.2.5 + +* Fix breakpoint not being active in certain cases like foldables. + +## 0.2.4 + +* Compare breakpoints to each other using operators. + +## 0.2.3 + +* Update the spacing and margins to the latest material m3 specs. +* Add `margin`, `spacing`, `padding`, `recommendedPanes` and `maxPanes` with their Material value to `Breakpoint`. + +## 0.2.2 + +* Fix a bug where landscape would not show body when using `andUp`. + +## 0.2.1 + +* Add `Breakpoint.activeBreakpointOf(context)` to find the currently active breakpoint. +* Don't check for height on Desktop platforms. + +## 0.2.0 + +* Add breakpoints for mediumLarge and extraLarge. +* Add height and orientation based breakpoint checks. +* **BREAKING CHANGES**: + * Removes `WidthPlatformBreakpoint` + * Breakpoints can now be constructed directly with `Breakpoint` + * Checks for `andUp` or `platform` can be done as parameter: `Breakpoint.small(andUp: true, platform: Breakpoint.mobile)` + +## 0.1.12 + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Expose `labelType` for NavigationRails. +* Add `navigationRailDestinationBuilder` to apply custom Destinations. +* Add `groupAlignment` property to change alignment. +* Set `navRailTheme` when using the Drawer just like the other NavigationRails. + +## 0.1.11+1 + +* Allows custom animation duration for the NavigationRail and + BottomNavigationBar transitions. [flutter/flutter#112938](https://github.com/flutter/flutter/issues/112938) + ## 0.1.11 * Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. diff --git a/packages/flutter_adaptive_scaffold/README.md b/packages/flutter_adaptive_scaffold/README.md index 3dda09753536..45fa01a241c8 100644 --- a/packages/flutter_adaptive_scaffold/README.md +++ b/packages/flutter_adaptive_scaffold/README.md @@ -1,5 +1,3 @@ - - # Adaptive Scaffold `AdaptiveScaffold` reacts to input from users, devices and screen elements and @@ -17,23 +15,23 @@ flutter run --release ## AdaptiveScaffold -AdaptiveScaffold implements the basic visual layout structure for Material +`AdaptiveScaffold` implements the basic visual layout structure for Material Design 3 that adapts to a variety of screens. It provides a preset of layout, including positions and animations, by handling macro changes in navigational elements and bodies based on the current features of the screen, namely screen width and platform. For example, the navigational elements would be a -BottomNavigationBar on a small mobile device and a NavigationRail on larger +`BottomNavigationBar` on a small mobile device and a `NavigationRail` on larger devices. The body is the primary screen that takes up the space left by the navigational elements. The secondaryBody acts as an option to split the space between two panes for purposes such as having a detail view. There is some automatic functionality with foldables to handle the split between panels -properly. AdaptiveScaffold is much simpler to use but is not the best if you +properly. `AdaptiveScaffold` is much simpler to use but is not the best if you would like high customizability. Apps that would like more refined layout and/or -animation should use AdaptiveLayout. +animation should use `AdaptiveLayout`. ### Example Usage - + ```dart @override Widget build(BuildContext context) { @@ -52,10 +50,12 @@ Widget build(BuildContext context) { // An option to override the default transition duration. transitionDuration: Duration(milliseconds: _transitionDuration), // An option to override the default breakpoints used for small, medium, - // and large. - smallBreakpoint: const WidthPlatformBreakpoint(end: 700), - mediumBreakpoint: const WidthPlatformBreakpoint(begin: 700, end: 1000), - largeBreakpoint: const WidthPlatformBreakpoint(begin: 1000), + // mediumLarge, large, and extraLarge. + smallBreakpoint: const Breakpoint(endWidth: 700), + mediumBreakpoint: const Breakpoint(beginWidth: 700, endWidth: 1000), + mediumLargeBreakpoint: const Breakpoint(beginWidth: 1000, endWidth: 1200), + largeBreakpoint: const Breakpoint(beginWidth: 1200, endWidth: 1600), + extraLargeBreakpoint: const Breakpoint(beginWidth: 1600), useDrawer: false, selectedIndex: _selectedTab, onSelectedIndexChange: (int index) { @@ -90,19 +90,33 @@ Widget build(BuildContext context) { label: 'Inbox', ), ], - body: (_) => GridView.count(crossAxisCount: 2, children: children), smallBody: (_) => ListView.builder( itemCount: children.length, itemBuilder: (_, int idx) => children[idx], ), + body: (_) => GridView.count(crossAxisCount: 2, children: children), + mediumLargeBody: (_) => + GridView.count(crossAxisCount: 3, children: children), + largeBody: (_) => GridView.count(crossAxisCount: 4, children: children), + extraLargeBody: (_) => + GridView.count(crossAxisCount: 5, children: children), // Define a default secondaryBody. - secondaryBody: (_) => Container( - color: const Color.fromARGB(255, 234, 158, 192), - ), // Override the default secondaryBody during the smallBreakpoint to be // empty. Must use AdaptiveScaffold.emptyBuilder to ensure it is properly // overridden. smallSecondaryBody: AdaptiveScaffold.emptyBuilder, + secondaryBody: (_) => Container( + color: const Color.fromARGB(255, 234, 158, 192), + ), + mediumLargeSecondaryBody: (_) => Container( + color: const Color.fromARGB(255, 234, 158, 192), + ), + largeSecondaryBody: (_) => Container( + color: const Color.fromARGB(255, 234, 158, 192), + ), + extraLargeSecondaryBody: (_) => Container( + color: const Color.fromARGB(255, 234, 158, 192), + ), ); } ``` @@ -112,19 +126,139 @@ Widget build(BuildContext context) { These are the set of widgets that are used on a lower level and offer more customizability at a cost of more lines of code. +### Breakpoint + +A `Breakpoint` controls the responsive behavior at different screens and configurations. + +You can either use a predefined Material3 breakpoint or create your own. + + +```dart +/// Returns a const [Breakpoint] with the given constraints. +const Breakpoint({ + this.beginWidth, + this.endWidth, + this.beginHeight, + this.endHeight, + this.andUp = false, + this.platform, + this.spacing = kMaterialMediumAndUpSpacing, + this.margin = kMaterialMediumAndUpMargin, + this.padding = kMaterialPadding, + this.recommendedPanes = 1, + this.maxPanes = 1, +}); + +/// Returns a [Breakpoint] that can be used as a fallthrough in the +/// case that no other breakpoint is active. +const Breakpoint.standard({this.platform}) + : beginWidth = -1, + endWidth = null, + beginHeight = null, + endHeight = null, + spacing = kMaterialMediumAndUpSpacing, + margin = kMaterialMediumAndUpMargin, + padding = kMaterialPadding, + recommendedPanes = 1, + maxPanes = 1, + andUp = true; + +/// Returns a [Breakpoint] with the given constraints for a small screen. +const Breakpoint.small({this.andUp = false, this.platform}) + : beginWidth = 0, + endWidth = 600, + beginHeight = null, + endHeight = 480, + spacing = kMaterialCompactSpacing, + margin = kMaterialCompactMargin, + padding = kMaterialPadding, + recommendedPanes = 1, + maxPanes = 1; + +/// Returns a [Breakpoint] with the given constraints for a medium screen. +const Breakpoint.medium({this.andUp = false, this.platform}) + : beginWidth = 600, + endWidth = 840, + beginHeight = 480, + endHeight = 900, + spacing = kMaterialMediumAndUpSpacing, + margin = kMaterialMediumAndUpMargin, + padding = kMaterialPadding * 2, + recommendedPanes = 1, + maxPanes = 2; + +/// Returns a [Breakpoint] with the given constraints for a mediumLarge screen. +const Breakpoint.mediumLarge({this.andUp = false, this.platform}) + : beginWidth = 840, + endWidth = 1200, + beginHeight = 900, + endHeight = null, + spacing = kMaterialMediumAndUpSpacing, + margin = kMaterialMediumAndUpMargin, + padding = kMaterialPadding * 3, + recommendedPanes = 2, + maxPanes = 2; + +/// Returns a [Breakpoint] with the given constraints for a large screen. +const Breakpoint.large({this.andUp = false, this.platform}) + : beginWidth = 1200, + endWidth = 1600, + beginHeight = 900, + endHeight = null, + spacing = kMaterialMediumAndUpSpacing, + margin = kMaterialMediumAndUpMargin, + padding = kMaterialPadding * 4, + recommendedPanes = 2, + maxPanes = 2; + +/// Returns a [Breakpoint] with the given constraints for an extraLarge screen. +const Breakpoint.extraLarge({this.andUp = false, this.platform}) + : beginWidth = 1600, + endWidth = null, + beginHeight = 900, + endHeight = null, + spacing = kMaterialMediumAndUpSpacing, + margin = kMaterialMediumAndUpMargin, + padding = kMaterialPadding * 5, + recommendedPanes = 2, + maxPanes = 3; +``` + +It is possible to compare Breakpoints: + + +```dart +/// Returns true if this [Breakpoint] is greater than the given [Breakpoint]. +bool operator >(Breakpoint breakpoint) +// ··· +/// Returns true if this [Breakpoint] is less than the given [Breakpoint]. +bool operator <(Breakpoint breakpoint) +// ··· +/// Returns true if this [Breakpoint] is greater than or equal to the +/// given [Breakpoint]. +bool operator >=(Breakpoint breakpoint) +// ··· +/// Returns true if this [Breakpoint] is less than or equal to the +/// given [Breakpoint]. +bool operator <=(Breakpoint breakpoint) +// ··· +/// Returns true if this [Breakpoint] is between the given [Breakpoint]s. +bool between(Breakpoint lower, Breakpoint upper) +``` + ### AdaptiveLayout !["AdaptiveLayout's Assigned Slots Displayed on Screen"](example/demo_files/screenSlots.png) -AdaptiveLayout is the top-level widget class that arranges the layout of the +`AdaptiveLayout` is the top-level widget class that arranges the layout of the slots and their animation, similar to Scaffold. It takes in several LayoutSlots -and returns an appropriate layout based on the diagram above. AdaptiveScaffold -is built upon AdaptiveLayout internally but abstracts some of the complexity +and returns an appropriate layout based on the diagram above. `AdaptiveScaffold` +is built upon `AdaptiveLayout` internally but abstracts some of the complexity with presets based on the Material 3 Design specification. ### SlotLayout -SlotLayout handles the adaptivity or the changes between widgets at certain -Breakpoints. It also holds the logic for animating between breakpoints. It takes +`SlotLayout` handles the adaptivity or the changes between widgets at certain +`Breakpoints`. It also holds the logic for animating between breakpoints. It takes SlotLayoutConfigs mapped to Breakpoints in a config and displays a widget based on that information. @@ -135,7 +269,7 @@ displayed and the entrance animation and exit animation. ### Example Usage - + ```dart // AdaptiveLayout has a number of slots that take SlotLayouts and these // SlotLayouts' configs take maps of Breakpoints to SlotLayoutConfigs. @@ -169,6 +303,39 @@ return AdaptiveLayout( unSelectedLabelTextStyle: navRailTheme.unselectedLabelTextStyle, ), ), + Breakpoints.mediumLarge: SlotLayout.from( + key: const Key('Primary Navigation MediumLarge'), + inAnimation: AdaptiveScaffold.leftOutIn, + builder: (_) => AdaptiveScaffold.standardNavigationRail( + selectedIndex: selectedNavigation, + onDestinationSelected: (int newIndex) { + setState(() { + selectedNavigation = newIndex; + }); + }, + extended: true, + leading: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Text( + 'REPLY', + style: headerColor, + ), + const Icon(Icons.menu_open) + ], + ), + destinations: destinations + .map((NavigationDestination destination) => + AdaptiveScaffold.toRailDestination(destination)) + .toList(), + trailing: trailingNavRail, + backgroundColor: navRailTheme.backgroundColor, + selectedIconTheme: navRailTheme.selectedIconTheme, + unselectedIconTheme: navRailTheme.unselectedIconTheme, + selectedLabelTextStyle: navRailTheme.selectedLabelTextStyle, + unSelectedLabelTextStyle: navRailTheme.unselectedLabelTextStyle, + ), + ), Breakpoints.large: SlotLayout.from( key: const Key('Primary Navigation Large'), inAnimation: AdaptiveScaffold.leftOutIn, @@ -180,14 +347,47 @@ return AdaptiveLayout( }); }, extended: true, - leading: const Row( + leading: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Text( + 'REPLY', + style: headerColor, + ), + const Icon(Icons.menu_open) + ], + ), + destinations: destinations + .map((NavigationDestination destination) => + AdaptiveScaffold.toRailDestination(destination)) + .toList(), + trailing: trailingNavRail, + backgroundColor: navRailTheme.backgroundColor, + selectedIconTheme: navRailTheme.selectedIconTheme, + unselectedIconTheme: navRailTheme.unselectedIconTheme, + selectedLabelTextStyle: navRailTheme.selectedLabelTextStyle, + unSelectedLabelTextStyle: navRailTheme.unselectedLabelTextStyle, + ), + ), + Breakpoints.extraLarge: SlotLayout.from( + key: const Key('Primary Navigation ExtraLarge'), + inAnimation: AdaptiveScaffold.leftOutIn, + builder: (_) => AdaptiveScaffold.standardNavigationRail( + selectedIndex: selectedNavigation, + onDestinationSelected: (int newIndex) { + setState(() { + selectedNavigation = newIndex; + }); + }, + extended: true, + leading: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Text( 'REPLY', - style: TextStyle(color: Color.fromARGB(255, 255, 201, 197)), + style: headerColor, ), - Icon(Icons.menu_open) + const Icon(Icons.menu_open) ], ), destinations: destinations @@ -215,11 +415,26 @@ return AdaptiveLayout( itemBuilder: (BuildContext context, int index) => children[index], ), ), - Breakpoints.mediumAndUp: SlotLayout.from( + Breakpoints.medium: SlotLayout.from( key: const Key('Body Medium'), builder: (_) => GridView.count(crossAxisCount: 2, children: children), - ) + ), + Breakpoints.mediumLarge: SlotLayout.from( + key: const Key('Body MediumLarge'), + builder: (_) => + GridView.count(crossAxisCount: 3, children: children), + ), + Breakpoints.large: SlotLayout.from( + key: const Key('Body Large'), + builder: (_) => + GridView.count(crossAxisCount: 4, children: children), + ), + Breakpoints.extraLarge: SlotLayout.from( + key: const Key('Body ExtraLarge'), + builder: (_) => + GridView.count(crossAxisCount: 5, children: children), + ), }, ), // BottomNavigation is only active in small views defined as under 600 dp diff --git a/packages/flutter_adaptive_scaffold/example/README.md b/packages/flutter_adaptive_scaffold/example/README.md index 035288f0155e..a0ab2f7aad58 100644 --- a/packages/flutter_adaptive_scaffold/example/README.md +++ b/packages/flutter_adaptive_scaffold/example/README.md @@ -1,4 +1,5 @@ # Examples + There are several examples listed in this directory: You can run the following commands in the example directory to see the appropriate demos: @@ -7,3 +8,5 @@ You can run the following commands in the example directory to see the appropria `flutter run lib/adaptive_layout_demo.dart` to see a simple usage of AdaptiveLayout. `flutter run lib/adaptive_scaffold_demo.dart` to see a simple usage of AdaptiveScaffold. + +`flutter run lib/go_router_demo.dart` to see usage of AdaptiveScaffold with GoRouter and some advanced scenarios like auth handling and branches. diff --git a/packages/flutter_adaptive_scaffold/example/android/.gitignore b/packages/flutter_adaptive_scaffold/example/android/.gitignore index 6f568019d3c6..55afd919c659 100644 --- a/packages/flutter_adaptive_scaffold/example/android/.gitignore +++ b/packages/flutter_adaptive_scaffold/example/android/.gitignore @@ -7,7 +7,7 @@ gradle-wrapper.jar GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. -# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +# See https://flutter.dev/to/reference-keystore key.properties **/*.keystore **/*.jks diff --git a/packages/flutter_adaptive_scaffold/example/android/app/build.gradle b/packages/flutter_adaptive_scaffold/example/android/app/build.gradle index 9d27f54fdcb2..1eafa2f094de 100644 --- a/packages/flutter_adaptive_scaffold/example/android/app/build.gradle +++ b/packages/flutter_adaptive_scaffold/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,21 +22,17 @@ 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 { compileSdk flutter.compileSdkVersion ndkVersion flutter.ndkVersion compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '11' } sourceSets { @@ -66,7 +63,3 @@ android { flutter { source '../..' } - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" -} diff --git a/packages/flutter_adaptive_scaffold/example/android/build.gradle b/packages/flutter_adaptive_scaffold/example/android/build.gradle index d13ef556e261..b9db5700753a 100644 --- a/packages/flutter_adaptive_scaffold/example/android/build.gradle +++ b/packages/flutter_adaptive_scaffold/example/android/build.gradle @@ -1,16 +1,3 @@ -buildscript { - ext.kotlin_version = '1.7.10' - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' - 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/flutter_adaptive_scaffold/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/flutter_adaptive_scaffold/example/android/gradle/wrapper/gradle-wrapper.properties index e1ca574ef017..3c85cfe057a1 100644 --- a/packages/flutter_adaptive_scaffold/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/flutter_adaptive_scaffold/example/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/flutter_adaptive_scaffold/example/android/settings.gradle b/packages/flutter_adaptive_scaffold/example/android/settings.gradle index f246a74091be..74d52ff12f4f 100644 --- a/packages/flutter_adaptive_scaffold/example/android/settings.gradle +++ b/packages/flutter_adaptive_scaffold/example/android/settings.gradle @@ -1,24 +1,27 @@ -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.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" +} + +include ":app" diff --git a/packages/flutter_adaptive_scaffold/example/lib/adaptive_layout_demo.dart b/packages/flutter_adaptive_scaffold/example/lib/adaptive_layout_demo.dart index a99ffb0a2338..451c99d8c08e 100644 --- a/packages/flutter_adaptive_scaffold/example/lib/adaptive_layout_demo.dart +++ b/packages/flutter_adaptive_scaffold/example/lib/adaptive_layout_demo.dart @@ -48,6 +48,9 @@ class _MyHomePageState extends State { }); } + final TextStyle headerColor = + const TextStyle(color: Color.fromARGB(255, 255, 201, 197)); + @override Widget build(BuildContext context) { final NavigationRailThemeData navRailTheme = @@ -200,6 +203,39 @@ class _MyHomePageState extends State { unSelectedLabelTextStyle: navRailTheme.unselectedLabelTextStyle, ), ), + Breakpoints.mediumLarge: SlotLayout.from( + key: const Key('Primary Navigation MediumLarge'), + inAnimation: AdaptiveScaffold.leftOutIn, + builder: (_) => AdaptiveScaffold.standardNavigationRail( + selectedIndex: selectedNavigation, + onDestinationSelected: (int newIndex) { + setState(() { + selectedNavigation = newIndex; + }); + }, + extended: true, + leading: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Text( + 'REPLY', + style: headerColor, + ), + const Icon(Icons.menu_open) + ], + ), + destinations: destinations + .map((NavigationDestination destination) => + AdaptiveScaffold.toRailDestination(destination)) + .toList(), + trailing: trailingNavRail, + backgroundColor: navRailTheme.backgroundColor, + selectedIconTheme: navRailTheme.selectedIconTheme, + unselectedIconTheme: navRailTheme.unselectedIconTheme, + selectedLabelTextStyle: navRailTheme.selectedLabelTextStyle, + unSelectedLabelTextStyle: navRailTheme.unselectedLabelTextStyle, + ), + ), Breakpoints.large: SlotLayout.from( key: const Key('Primary Navigation Large'), inAnimation: AdaptiveScaffold.leftOutIn, @@ -211,14 +247,47 @@ class _MyHomePageState extends State { }); }, extended: true, - leading: const Row( + leading: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Text( 'REPLY', - style: TextStyle(color: Color.fromARGB(255, 255, 201, 197)), + style: headerColor, ), - Icon(Icons.menu_open) + const Icon(Icons.menu_open) + ], + ), + destinations: destinations + .map((NavigationDestination destination) => + AdaptiveScaffold.toRailDestination(destination)) + .toList(), + trailing: trailingNavRail, + backgroundColor: navRailTheme.backgroundColor, + selectedIconTheme: navRailTheme.selectedIconTheme, + unselectedIconTheme: navRailTheme.unselectedIconTheme, + selectedLabelTextStyle: navRailTheme.selectedLabelTextStyle, + unSelectedLabelTextStyle: navRailTheme.unselectedLabelTextStyle, + ), + ), + Breakpoints.extraLarge: SlotLayout.from( + key: const Key('Primary Navigation ExtraLarge'), + inAnimation: AdaptiveScaffold.leftOutIn, + builder: (_) => AdaptiveScaffold.standardNavigationRail( + selectedIndex: selectedNavigation, + onDestinationSelected: (int newIndex) { + setState(() { + selectedNavigation = newIndex; + }); + }, + extended: true, + leading: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Text( + 'REPLY', + style: headerColor, + ), + const Icon(Icons.menu_open) ], ), destinations: destinations @@ -246,11 +315,26 @@ class _MyHomePageState extends State { itemBuilder: (BuildContext context, int index) => children[index], ), ), - Breakpoints.mediumAndUp: SlotLayout.from( + Breakpoints.medium: SlotLayout.from( key: const Key('Body Medium'), builder: (_) => GridView.count(crossAxisCount: 2, children: children), - ) + ), + Breakpoints.mediumLarge: SlotLayout.from( + key: const Key('Body MediumLarge'), + builder: (_) => + GridView.count(crossAxisCount: 3, children: children), + ), + Breakpoints.large: SlotLayout.from( + key: const Key('Body Large'), + builder: (_) => + GridView.count(crossAxisCount: 4, children: children), + ), + Breakpoints.extraLarge: SlotLayout.from( + key: const Key('Body ExtraLarge'), + builder: (_) => + GridView.count(crossAxisCount: 5, children: children), + ), }, ), // BottomNavigation is only active in small views defined as under 600 dp diff --git a/packages/flutter_adaptive_scaffold/example/lib/adaptive_scaffold_demo.dart b/packages/flutter_adaptive_scaffold/example/lib/adaptive_scaffold_demo.dart index ff7e25683b46..600037955a6e 100644 --- a/packages/flutter_adaptive_scaffold/example/lib/adaptive_scaffold_demo.dart +++ b/packages/flutter_adaptive_scaffold/example/lib/adaptive_scaffold_demo.dart @@ -85,10 +85,12 @@ class _MyHomePageState extends State { // An option to override the default transition duration. transitionDuration: Duration(milliseconds: _transitionDuration), // An option to override the default breakpoints used for small, medium, - // and large. - smallBreakpoint: const WidthPlatformBreakpoint(end: 700), - mediumBreakpoint: const WidthPlatformBreakpoint(begin: 700, end: 1000), - largeBreakpoint: const WidthPlatformBreakpoint(begin: 1000), + // mediumLarge, large, and extraLarge. + smallBreakpoint: const Breakpoint(endWidth: 700), + mediumBreakpoint: const Breakpoint(beginWidth: 700, endWidth: 1000), + mediumLargeBreakpoint: const Breakpoint(beginWidth: 1000, endWidth: 1200), + largeBreakpoint: const Breakpoint(beginWidth: 1200, endWidth: 1600), + extraLargeBreakpoint: const Breakpoint(beginWidth: 1600), useDrawer: false, selectedIndex: _selectedTab, onSelectedIndexChange: (int index) { @@ -123,19 +125,33 @@ class _MyHomePageState extends State { label: 'Inbox', ), ], - body: (_) => GridView.count(crossAxisCount: 2, children: children), smallBody: (_) => ListView.builder( itemCount: children.length, itemBuilder: (_, int idx) => children[idx], ), + body: (_) => GridView.count(crossAxisCount: 2, children: children), + mediumLargeBody: (_) => + GridView.count(crossAxisCount: 3, children: children), + largeBody: (_) => GridView.count(crossAxisCount: 4, children: children), + extraLargeBody: (_) => + GridView.count(crossAxisCount: 5, children: children), // Define a default secondaryBody. - secondaryBody: (_) => Container( - color: const Color.fromARGB(255, 234, 158, 192), - ), // Override the default secondaryBody during the smallBreakpoint to be // empty. Must use AdaptiveScaffold.emptyBuilder to ensure it is properly // overridden. smallSecondaryBody: AdaptiveScaffold.emptyBuilder, + secondaryBody: (_) => Container( + color: const Color.fromARGB(255, 234, 158, 192), + ), + mediumLargeSecondaryBody: (_) => Container( + color: const Color.fromARGB(255, 234, 158, 192), + ), + largeSecondaryBody: (_) => Container( + color: const Color.fromARGB(255, 234, 158, 192), + ), + extraLargeSecondaryBody: (_) => Container( + color: const Color.fromARGB(255, 234, 158, 192), + ), ); } // #enddocregion Example diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo.dart new file mode 100644 index 000000000000..5918197d3765 --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo.dart @@ -0,0 +1,33 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +import 'go_router_demo/app_router.dart'; + +void main() { + runApp(const MyApp()); +} + +/// The main application widget for this example. +class MyApp extends StatelessWidget { + /// Creates a const main application widget. + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp.router( + restorationScopeId: 'demo', + routerConfig: AppRouter.router, + theme: ThemeData( + colorScheme: ColorScheme.fromSeed( + seedColor: Colors.blue, + dynamicSchemeVariant: DynamicSchemeVariant.vibrant, + primary: Colors.blue, + ), + useMaterial3: true, + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/app_router.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/app_router.dart new file mode 100644 index 000000000000..ddb36662370c --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/app_router.dart @@ -0,0 +1,197 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; + +import 'pages/pages.dart'; +import 'scaffold_shell.dart'; + +/// The root navigator key for the main router of the app. +final GlobalKey rootNavigatorKey = + GlobalKey(debugLabel: 'root'); + +final GlobalKey _homeNavigatorKey = + GlobalKey(debugLabel: 'home'); +final GlobalKey _counterNavigatorKey = + GlobalKey(debugLabel: 'counter'); +final GlobalKey _moreNavigatorKey = + GlobalKey(debugLabel: 'more'); + +/// The [AppRouter] maintains the main route configuration for the app. +/// +/// Routes that are `fullScreenDialogs` should also set `_rootNavigatorKey` as +/// the `parentNavigatorKey` to ensure that the dialog is displayed correctly. +class AppRouter { + /// The authentication status of the user. + static ValueNotifier authenticatedNotifier = ValueNotifier(false); + + /// The router with the routes of pages that should be displayed. + static final GoRouter router = GoRouter( + navigatorKey: rootNavigatorKey, + debugLogDiagnostics: true, + errorPageBuilder: (BuildContext context, GoRouterState state) { + return const MaterialPage(child: NavigationErrorPage()); + }, + redirect: (BuildContext context, GoRouterState state) { + if (state.uri.path == '/') { + return HomePage.path; + } + return null; + }, + refreshListenable: authenticatedNotifier, + routes: [ + _unauthenticatedRoutes, + _authenticatedRoutes, + ..._openRoutes, + ], + ); + + static final GoRoute _unauthenticatedRoutes = GoRoute( + name: LoginPage.name, + path: LoginPage.path, + pageBuilder: (BuildContext context, GoRouterState state) { + return const MaterialPage(child: LoginPage()); + }, + redirect: (BuildContext context, GoRouterState state) { + if (authenticatedNotifier.value) { + return HomePage.path; + } + return null; + }, + routes: [ + GoRoute( + name: ForgotPasswordPage.name, + path: ForgotPasswordPage.path, + pageBuilder: (BuildContext context, GoRouterState state) { + return const MaterialPage( + child: ForgotPasswordPage(), + ); + }, + ), + ], + ); + + static final StatefulShellRoute _authenticatedRoutes = + StatefulShellRoute.indexedStack( + parentNavigatorKey: rootNavigatorKey, + builder: ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + return ScaffoldShell(navigationShell: navigationShell); + }, + redirect: (BuildContext context, GoRouterState state) { + if (!authenticatedNotifier.value) { + return LoginPage.path; + } + return null; + }, + branches: [ + StatefulShellBranch( + navigatorKey: _homeNavigatorKey, + routes: [ + GoRoute( + name: HomePage.name, + path: HomePage.path, + pageBuilder: (BuildContext context, GoRouterState state) { + return const NoTransitionPage( + child: HomePage(), + ); + }, + routes: [ + GoRoute( + name: DetailOverviewPage.name, + path: DetailOverviewPage.path, + pageBuilder: (BuildContext context, GoRouterState state) { + return const MaterialPage( + child: DetailOverviewPage(), + ); + }, + routes: [ + GoRoute( + name: DetailPage.name, + path: DetailPage.path, + pageBuilder: (BuildContext context, GoRouterState state) { + return MaterialPage( + child: DetailPage( + itemName: state.uri.queryParameters['itemName']!), + ); + }, + ), + ]), + GoRoute( + name: DetailModalPage.name, + path: DetailModalPage.path, + parentNavigatorKey: rootNavigatorKey, + pageBuilder: (BuildContext context, GoRouterState state) { + return const MaterialPage( + fullscreenDialog: true, + child: DetailModalPage(), + ); + }, + ), + ], + ), + ], + ), + StatefulShellBranch( + navigatorKey: _counterNavigatorKey, + routes: [ + GoRoute( + name: CounterPage.name, + path: CounterPage.path, + pageBuilder: (BuildContext context, GoRouterState state) { + return const NoTransitionPage(child: CounterPage()); + }, + ), + ], + ), + StatefulShellBranch( + navigatorKey: _moreNavigatorKey, + routes: [ + GoRoute( + name: MorePage.name, + path: MorePage.path, + pageBuilder: (BuildContext context, GoRouterState state) { + return const NoTransitionPage( + key: ValueKey(MorePage.name), + child: MorePage(), + ); + }, + routes: [ + GoRoute( + path: ProfilePage.path, + name: ProfilePage.name, + pageBuilder: (BuildContext context, GoRouterState state) { + return const MaterialPage(child: ProfilePage()); + }, + ), + GoRoute( + name: SettingsPage.name, + path: SettingsPage.path, + pageBuilder: (BuildContext context, GoRouterState state) { + return const MaterialPage(child: SettingsPage()); + }, + ), + ], + ), + ], + ), + ], + ); + + static final List _openRoutes = [ + GoRoute( + name: LanguagePage.name, + path: LanguagePage.path, + pageBuilder: (BuildContext context, GoRouterState state) { + return const MaterialPage( + child: LanguagePage(), + ); + }, + ), + ]; +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/counter_page.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/counter_page.dart new file mode 100644 index 000000000000..59b5400a1459 --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/counter_page.dart @@ -0,0 +1,29 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +/// The counter page. +class CounterPage extends StatelessWidget { + /// Construct the counter page. + const CounterPage({super.key}); + + /// The path for the counter page. + static const String path = '/counter'; + + /// The name for the counter page. + static const String name = 'Counter'; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Counter Page'), + ), + body: const Center( + child: Text('Counter Page'), + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/detail_modal_page.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/detail_modal_page.dart new file mode 100644 index 000000000000..6ce2d75a64ba --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/detail_modal_page.dart @@ -0,0 +1,29 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +/// The detail modal page. +class DetailModalPage extends StatelessWidget { + /// Construct the detail modal page. + const DetailModalPage({super.key}); + + /// The path for the detail modal page. + static const String path = 'detail-modal'; + + /// The name for the detail modal page. + static const String name = 'DetailModal'; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Detail Modal Page'), + ), + body: const Center( + child: Text('Detail modal Page'), + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/detail_overview_page.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/detail_overview_page.dart new file mode 100644 index 000000000000..941338e4f128 --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/detail_overview_page.dart @@ -0,0 +1,43 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; + +import 'detail_page.dart'; + +/// The detail overview page. +class DetailOverviewPage extends StatelessWidget { + /// Construct the detail overview page. + const DetailOverviewPage({super.key}); + + /// The path for the detail page. + static const String path = 'detail-overview'; + + /// The name for the detail page. + static const String name = 'DetailOverview'; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Detail Overview Page'), + ), + body: ListView.builder( + itemCount: 10, + itemBuilder: (BuildContext context, int index) { + return ListTile( + title: Text('Item $index'), + onTap: () { + context.goNamed( + DetailPage.name, + queryParameters: {'itemName': '$index'}, + ); + }, + ); + }, + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/detail_page.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/detail_page.dart new file mode 100644 index 000000000000..0abc77f0ee61 --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/detail_page.dart @@ -0,0 +1,32 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +/// The detail page. +class DetailPage extends StatelessWidget { + /// Construct the detail page. + const DetailPage({super.key, required this.itemName}); + + /// The path for the detail page. + static const String path = 'detail'; + + /// The name for the detail page. + static const String name = 'Detail'; + + /// The item name for the detail page. + final String itemName; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Detail Page'), + ), + body: Center( + child: Text('Detail Page: $itemName'), + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/forgot_password_page.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/forgot_password_page.dart new file mode 100644 index 000000000000..a680f5c55b24 --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/forgot_password_page.dart @@ -0,0 +1,29 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +/// The forgot password page. +class ForgotPasswordPage extends StatelessWidget { + /// Construct the forgot password page. + const ForgotPasswordPage({super.key}); + + /// The path for the forgot password page. + static const String path = 'forgot_password'; + + /// The name for the forgot password page. + static const String name = 'ForgotPassword'; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Forgot Password'), + ), + body: const Center( + child: Text('ForgotPassword Page'), + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/home_page.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/home_page.dart new file mode 100644 index 000000000000..05dbbad56f6c --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/home_page.dart @@ -0,0 +1,50 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:flutter_adaptive_scaffold/flutter_adaptive_scaffold.dart'; +import 'package:go_router/go_router.dart'; + +import 'pages.dart'; + +/// The home page. +class HomePage extends StatelessWidget { + /// Construct the home page. + const HomePage({super.key}); + + /// The path for the home page. + static const String path = '/home'; + + /// The name for the home page. + static const String name = 'Home'; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Home Page'), + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: () => { + context.goNamed(DetailOverviewPage.name), + }, + child: const Text('Detail page'), + ), + const SizedBox(height: kMaterialMediumAndUpMargin), + ElevatedButton( + onPressed: () => { + context.goNamed(DetailModalPage.name), + }, + child: const Text('Detail modal page'), + ), + ], + ), + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/language_page.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/language_page.dart new file mode 100644 index 000000000000..ee160726199e --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/language_page.dart @@ -0,0 +1,29 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +/// The language page. +class LanguagePage extends StatelessWidget { + /// Construct the language page. + const LanguagePage({super.key}); + + /// The path for the language page. + static const String path = '/language'; + + /// The name for the language page. + static const String name = 'Language'; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Language'), + ), + body: const Center( + child: Text('Language Page'), + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/login_page.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/login_page.dart new file mode 100644 index 000000000000..32084550c618 --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/login_page.dart @@ -0,0 +1,40 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +import '../app_router.dart'; + +/// The login page. +class LoginPage extends StatelessWidget { + /// Construct the login page. + const LoginPage({super.key}); + + /// The path for the login page. + static const String path = '/login'; + + /// The name for the login page. + static const String name = 'Login'; + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text('Login Page'), + const SizedBox(height: 16), + ElevatedButton( + onPressed: () => { + AppRouter.authenticatedNotifier.value = true, + }, + child: const Text('Login'), + ), + ], + ), + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/more_page.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/more_page.dart new file mode 100644 index 000000000000..3eca08c7f2af --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/more_page.dart @@ -0,0 +1,46 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:flutter_adaptive_scaffold/flutter_adaptive_scaffold.dart'; +import 'package:go_router/go_router.dart'; + +import 'pages.dart'; + +/// The more page. +class MorePage extends StatelessWidget { + /// Construct the more page. + const MorePage({super.key}); + + /// The path for the more page. + static const String path = '/more'; + + /// The name for the more page. + static const String name = 'More'; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('More Page'), + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: () => context.goNamed(ProfilePage.name), + child: const Text('Profile'), + ), + const SizedBox(height: kMaterialMediumAndUpMargin), + ElevatedButton( + onPressed: () => context.goNamed(SettingsPage.name), + child: const Text('Settings'), + ), + ], + ), + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/navigation_error_page.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/navigation_error_page.dart new file mode 100644 index 000000000000..c50a61e6ac9c --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/navigation_error_page.dart @@ -0,0 +1,26 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +/// The error page for navigation errors. +class NavigationErrorPage extends StatelessWidget { + /// Creates a new instance of the [NavigationErrorPage]. + const NavigationErrorPage({super.key}); + + /// The path for the error page. + static const String path = '/error'; + + /// The name for the error page. + static const String name = 'Error'; + + @override + Widget build(BuildContext context) { + return const Scaffold( + body: Center( + child: Text('Error Page'), + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/pages.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/pages.dart new file mode 100644 index 000000000000..e7d498f9652f --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/pages.dart @@ -0,0 +1,16 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +export 'counter_page.dart'; +export 'detail_modal_page.dart'; +export 'detail_overview_page.dart'; +export 'detail_page.dart'; +export 'forgot_password_page.dart'; +export 'home_page.dart'; +export 'language_page.dart'; +export 'login_page.dart'; +export 'more_page.dart'; +export 'navigation_error_page.dart'; +export 'profile_page.dart'; +export 'settings_page.dart'; diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/profile_page.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/profile_page.dart new file mode 100644 index 000000000000..a5d2ee69e699 --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/profile_page.dart @@ -0,0 +1,41 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +import '../app_router.dart'; + +/// The profile page. +class ProfilePage extends StatelessWidget { + /// Construct the profile page. + const ProfilePage({super.key}); + + /// The path for the profile page. + static const String path = 'profile'; + + /// The name for the profile page. + static const String name = 'Profile'; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Profile Page'), + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: () => { + AppRouter.authenticatedNotifier.value = false, + }, + child: const Text('Sign Out'), + ), + ], + ), + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/settings_page.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/settings_page.dart new file mode 100644 index 000000000000..8357e3cdebd3 --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/settings_page.dart @@ -0,0 +1,29 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +/// The settings page. +class SettingsPage extends StatelessWidget { + /// Construct the settings page. + const SettingsPage({super.key}); + + /// The path for the settings page. + static const String path = 'settings'; + + /// The name for the settings page. + static const String name = 'Settings'; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Settings Page'), + ), + body: const Center( + child: Text('Settings Page'), + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/scaffold_shell.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/scaffold_shell.dart new file mode 100644 index 000000000000..aa070a82c4a0 --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/scaffold_shell.dart @@ -0,0 +1,52 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:flutter_adaptive_scaffold/flutter_adaptive_scaffold.dart'; +import 'package:go_router/go_router.dart'; + +import 'pages/pages.dart'; + +/// The [ScaffoldShell] is a [StatelessWidget] that uses the [AdaptiveScaffold] +/// to create a shell for the application. +class ScaffoldShell extends StatelessWidget { + /// Create a new instance of [AppScaffoldShell] + const ScaffoldShell({ + required this.navigationShell, + super.key, + }); + + /// The navigation shell to use with the navigation. + final StatefulNavigationShell navigationShell; + + @override + Widget build(BuildContext context) { + return AdaptiveScaffold( + useDrawer: false, + body: (BuildContext context) => navigationShell, + selectedIndex: navigationShell.currentIndex, + onSelectedIndexChange: (int index) { + navigationShell.goBranch( + index, + initialLocation: index == navigationShell.currentIndex, + ); + }, + destinations: navigationShell.route.branches.map( + (StatefulShellBranch e) { + return switch (e.defaultRoute?.name) { + HomePage.name => const NavigationDestination( + icon: Icon(Icons.home), label: 'Home'), + CounterPage.name => const NavigationDestination( + icon: Icon(Icons.add), label: 'Counter'), + MorePage.name => const NavigationDestination( + icon: Icon(Icons.account_circle), label: 'More'), + _ => throw UnimplementedError( + 'The route ${e.defaultRoute?.name} is not implemented.', + ), + }; + }, + ).toList(), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/main.dart b/packages/flutter_adaptive_scaffold/example/lib/main.dart index 13a6418973da..7793e32335df 100644 --- a/packages/flutter_adaptive_scaffold/example/lib/main.dart +++ b/packages/flutter_adaptive_scaffold/example/lib/main.dart @@ -299,6 +299,26 @@ class _MyHomePageState extends State ); }, ), + Breakpoints.mediumLarge: SlotLayout.from( + key: const Key('MediumLarge primaryNavigation'), + // The AdaptiveScaffold builder here greatly simplifies + // navigational elements. + builder: (_) => AdaptiveScaffold.standardNavigationRail( + leading: const _LargeComposeIcon(), + onDestinationSelected: (int index) { + setState(() { + _navigationIndex = index; + }); + }, + selectedIndex: _navigationIndex, + trailing: trailingNavRail, + extended: true, + destinations: + destinations.map((NavigationDestination destination) { + return AdaptiveScaffold.toRailDestination(destination); + }).toList(), + ), + ), Breakpoints.large: SlotLayout.from( key: const Key('Large primaryNavigation'), // The AdaptiveScaffold builder here greatly simplifies @@ -319,6 +339,26 @@ class _MyHomePageState extends State }).toList(), ), ), + Breakpoints.extraLarge: SlotLayout.from( + key: const Key('ExtraLarge primaryNavigation'), + // The AdaptiveScaffold builder here greatly simplifies + // navigational elements. + builder: (_) => AdaptiveScaffold.standardNavigationRail( + leading: const _LargeComposeIcon(), + onDestinationSelected: (int index) { + setState(() { + _navigationIndex = index; + }); + }, + selectedIndex: _navigationIndex, + trailing: trailingNavRail, + extended: true, + destinations: + destinations.map((NavigationDestination destination) { + return AdaptiveScaffold.toRailDestination(destination); + }).toList(), + ), + ), }, ), body: SlotLayout( @@ -653,7 +693,7 @@ class _ItemListTile extends StatelessWidget { style: Theme.of(context).textTheme.bodyLarge), const SizedBox(height: 9), SizedBox( - width: MediaQuery.of(context).size.width, + width: MediaQuery.sizeOf(context).width, child: (email.bodyImage != '') ? Image.asset(email.bodyImage) : Container(), @@ -677,7 +717,7 @@ class _DetailTile extends StatelessWidget { return Padding( padding: const EdgeInsets.all(8.0), child: SizedBox( - height: MediaQuery.of(context).size.height, + height: MediaQuery.sizeOf(context).height, child: Container( decoration: const BoxDecoration( color: Color.fromARGB(255, 245, 241, 248), @@ -851,7 +891,7 @@ class _EmailTile extends StatelessWidget { color: Colors.grey[700], height: 1.35, fontSize: 14.5)), const SizedBox(height: 9), SizedBox( - width: MediaQuery.of(context).size.width, + width: MediaQuery.sizeOf(context).width, child: (bodyImage != '') ? Image.asset(bodyImage) : Container()), const SizedBox(height: 10), diff --git a/packages/flutter_adaptive_scaffold/example/pubspec.yaml b/packages/flutter_adaptive_scaffold/example/pubspec.yaml index 8f424d78ce5c..3f82e2ca20e4 100644 --- a/packages/flutter_adaptive_scaffold/example/pubspec.yaml +++ b/packages/flutter_adaptive_scaffold/example/pubspec.yaml @@ -4,17 +4,18 @@ publish_to: 'none' version: 0.0.1 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: sdk: flutter flutter_adaptive_scaffold: path: .. + go_router: ^14.2.7 dev_dependencies: - build_runner: ^2.1.10 + build_runner: ^2.4.12 flutter_test: sdk: flutter diff --git a/packages/flutter_adaptive_scaffold/example/test/adaptive_layout_demo_test.dart b/packages/flutter_adaptive_scaffold/example/test/adaptive_layout_demo_test.dart index 77d0e0b759e2..13ce917738af 100644 --- a/packages/flutter_adaptive_scaffold/example/test/adaptive_layout_demo_test.dart +++ b/packages/flutter_adaptive_scaffold/example/test/adaptive_layout_demo_test.dart @@ -24,7 +24,7 @@ void main() { ); Future updateScreen(double width, WidgetTester tester) async { - await tester.binding.setSurfaceSize(Size(width, 800)); + await tester.binding.setSurfaceSize(Size(width, 2000)); await tester.pumpWidget( MaterialApp( theme: ThemeData.light().copyWith( @@ -35,7 +35,7 @@ void main() { ), ), home: MediaQuery( - data: MediaQueryData(size: Size(width, 800)), + data: MediaQueryData(size: Size(width, 2000)), child: const example.MyHomePage(), ), ), @@ -51,15 +51,62 @@ void main() { expect(find.byKey(const Key('Primary Navigation Medium')), findsNothing); expect(find.byKey(const Key('Bottom Navigation Small')), findsOneWidget); expect(find.byKey(const Key('Body Medium')), findsNothing); + expect(find.byKey(const Key('Primary Navigation MediumLarge')), + findsNothing); expect(find.byKey(const Key('Primary Navigation Large')), findsNothing); + expect( + find.byKey(const Key('Primary Navigation ExtraLarge')), findsNothing); await updateScreen(700, tester); - expect(find.byKey(const Key('Body')), findsNothing); + expect(find.byKey(const Key('Body Small')), findsNothing); expect(find.byKey(const Key('Bottom Navigation Small')), findsNothing); expect(find.byKey(const Key('Body Medium')), findsOneWidget); expect( find.byKey(const Key('Primary Navigation Medium')), findsOneWidget); + expect(find.byKey(const Key('Primary Navigation MediumLarge')), + findsNothing); + expect(find.byKey(const Key('Primary Navigation Large')), findsNothing); + expect( + find.byKey(const Key('Primary Navigation ExtraLarge')), findsNothing); + + await updateScreen(860, tester); + expect(find.byKey(const Key('Body Small')), findsNothing); + expect(find.byKey(const Key('Bottom Navigation Small')), findsNothing); + expect(find.byKey(const Key('Body Medium')), findsNothing); + expect(find.byKey(const Key('Body MediumLarge')), findsOneWidget); + expect(find.byKey(const Key('Primary Navigation Medium')), findsNothing); + expect(find.byKey(const Key('Primary Navigation MediumLarge')), + findsOneWidget); + expect(find.byKey(const Key('Primary Navigation Large')), findsNothing); + expect( + find.byKey(const Key('Primary Navigation ExtraLarge')), findsNothing); + + await updateScreen(1200, tester); + expect(find.byKey(const Key('Body Small')), findsNothing); + expect(find.byKey(const Key('Bottom Navigation Small')), findsNothing); + expect(find.byKey(const Key('Body Medium')), findsNothing); + expect(find.byKey(const Key('Body MediumLarge')), findsNothing); + expect(find.byKey(const Key('Body Large')), findsOneWidget); + expect(find.byKey(const Key('Primary Navigation Medium')), findsNothing); + expect(find.byKey(const Key('Primary Navigation MediumLarge')), + findsNothing); + expect(find.byKey(const Key('Primary Navigation Large')), findsOneWidget); + expect( + find.byKey(const Key('Primary Navigation ExtraLarge')), findsNothing); + + await updateScreen(1600, tester); + expect(find.byKey(const Key('Body Small')), findsNothing); + expect(find.byKey(const Key('Bottom Navigation Small')), findsNothing); + expect(find.byKey(const Key('Body Medium')), findsNothing); + expect(find.byKey(const Key('Body MediumLarge')), findsNothing); + expect(find.byKey(const Key('Body Large')), findsNothing); + expect(find.byKey(const Key('Body ExtraLarge')), findsOneWidget); + expect(find.byKey(const Key('Primary Navigation Medium')), findsNothing); + expect(find.byKey(const Key('Primary Navigation MediumLarge')), + findsNothing); expect(find.byKey(const Key('Primary Navigation Large')), findsNothing); + expect(find.byKey(const Key('Primary Navigation ExtraLarge')), + findsOneWidget); }, ); @@ -105,8 +152,8 @@ void main() { 'adaptive layout displays children in correct places', (WidgetTester tester) async { await updateScreen(400, tester); - expect(tester.getBottomLeft(bottomNavigation), const Offset(0, 800)); - expect(tester.getBottomRight(bottomNavigation), const Offset(400, 800)); + expect(tester.getBottomLeft(bottomNavigation), const Offset(0, 2000)); + expect(tester.getBottomRight(bottomNavigation), const Offset(400, 2000)); expect(tester.getTopRight(body), const Offset(400, 0)); expect(tester.getTopLeft(body), Offset.zero); }, @@ -119,7 +166,7 @@ void main() { await updateScreen(690, tester); expect(tester.getTopLeft(bodyMedium), const Offset(88, 0)); - expect(tester.getBottomRight(bodyMedium), const Offset(690, 800)); + expect(tester.getBottomRight(bodyMedium), const Offset(690, 2000)); }, ); @@ -165,13 +212,55 @@ void main() { }, ); + testWidgets( + 'when view in medium large screen, navigation rail must be visible as per theme data values.', + (WidgetTester tester) async { + final Finder primaryNavigationMediumLarge = find.byKey( + const Key('Primary Navigation MediumLarge'), + ); + await updateScreen(860, tester); + expect(primaryNavigationMediumLarge, findsOneWidget); + + final Finder navigationRailFinder = find.descendant( + of: primaryNavigationMediumLarge, + matching: find.byType(NavigationRail), + ); + expect(navigationRailFinder, findsOneWidget); + + final NavigationRail navigationRailView = tester.firstWidget( + navigationRailFinder, + ); + expect(navigationRailView, isNotNull); + expect( + navigationRailView.backgroundColor, + navigationRailThemeBgColor, + ); + expect( + navigationRailView.selectedIconTheme?.size, + selectedIconThemeData.size, + ); + expect( + navigationRailView.selectedIconTheme?.color, + selectedIconThemeData.color, + ); + expect( + navigationRailView.unselectedIconTheme?.size, + unSelectedIconThemeData.size, + ); + expect( + navigationRailView.unselectedIconTheme?.color, + unSelectedIconThemeData.color, + ); + }, + ); + testWidgets( 'when view in large screen, navigation rail must be visible as per theme data values.', (WidgetTester tester) async { final Finder primaryNavigationLarge = find.byKey( const Key('Primary Navigation Large'), ); - await updateScreen(860, tester); + await updateScreen(1200, tester); expect(primaryNavigationLarge, findsOneWidget); final Finder navigationRailFinder = find.descendant( @@ -206,4 +295,46 @@ void main() { ); }, ); + + testWidgets( + 'when view in extraLarge screen, navigation rail must be visible as per theme data values.', + (WidgetTester tester) async { + final Finder primaryNavigationExtraLarge = find.byKey( + const Key('Primary Navigation ExtraLarge'), + ); + await updateScreen(1600, tester); + expect(primaryNavigationExtraLarge, findsOneWidget); + + final Finder navigationRailFinder = find.descendant( + of: primaryNavigationExtraLarge, + matching: find.byType(NavigationRail), + ); + expect(navigationRailFinder, findsOneWidget); + + final NavigationRail navigationRailView = tester.firstWidget( + navigationRailFinder, + ); + expect(navigationRailView, isNotNull); + expect( + navigationRailView.backgroundColor, + navigationRailThemeBgColor, + ); + expect( + navigationRailView.selectedIconTheme?.size, + selectedIconThemeData.size, + ); + expect( + navigationRailView.selectedIconTheme?.color, + selectedIconThemeData.color, + ); + expect( + navigationRailView.unselectedIconTheme?.size, + unSelectedIconThemeData.size, + ); + expect( + navigationRailView.unselectedIconTheme?.color, + unSelectedIconThemeData.color, + ); + }, + ); } diff --git a/packages/flutter_adaptive_scaffold/example/test/adaptive_scaffold_demo_test.dart b/packages/flutter_adaptive_scaffold/example/test/adaptive_scaffold_demo_test.dart index d08a34c2c96d..7631d36e35b2 100644 --- a/packages/flutter_adaptive_scaffold/example/test/adaptive_scaffold_demo_test.dart +++ b/packages/flutter_adaptive_scaffold/example/test/adaptive_scaffold_demo_test.dart @@ -10,18 +10,22 @@ import 'package:flutter_test/flutter_test.dart'; void main() { final Finder smallBody = find.byKey(const Key('smallBody')); final Finder body = find.byKey(const Key('body')); + final Finder mediumLargeBody = find.byKey(const Key('mediumLargeBody')); final Finder largeBody = find.byKey(const Key('largeBody')); + final Finder extraLargeBody = find.byKey(const Key('extraLargeBody')); final Finder bnav = find.byKey(const Key('bottomNavigation')); final Finder pnav = find.byKey(const Key('primaryNavigation')); final Finder pnav1 = find.byKey(const Key('primaryNavigation1')); + final Finder pnav2 = find.byKey(const Key('primaryNavigation2')); + final Finder pnav3 = find.byKey(const Key('primaryNavigation3')); Future updateScreen(double width, WidgetTester tester, {int transitionDuration = 1000}) async { - await tester.binding.setSurfaceSize(Size(width, 800)); + await tester.binding.setSurfaceSize(Size(width, 2000)); await tester.pumpWidget( MaterialApp( home: MediaQuery( - data: MediaQueryData(size: Size(width, 800)), + data: MediaQueryData(size: Size(width, 2000)), child: example.MyHomePage( transitionDuration: transitionDuration, )), @@ -29,38 +33,88 @@ void main() { ); } - testWidgets('dislays correct item of config based on screen width', + testWidgets('displays correct item of config based on screen width', (WidgetTester tester) async { + // Small await updateScreen(300, tester); await tester.pumpAndSettle(); expect(smallBody, findsOneWidget); expect(bnav, findsOneWidget); expect(tester.getTopLeft(smallBody), Offset.zero); - expect(tester.getTopLeft(bnav), const Offset(0, 720)); + expect(tester.getTopLeft(bnav), const Offset(0, 1920)); expect(body, findsNothing); + expect(mediumLargeBody, findsNothing); expect(largeBody, findsNothing); + expect(extraLargeBody, findsNothing); expect(pnav, findsNothing); expect(pnav1, findsNothing); + expect(pnav2, findsNothing); + expect(pnav3, findsNothing); + // Medium await updateScreen(800, tester); await tester.pumpAndSettle(); expect(body, findsOneWidget); - expect(tester.getTopLeft(body), const Offset(88, 0)); - expect(body, findsOneWidget); - expect(bnav, findsNothing); - expect(largeBody, findsNothing); expect(pnav, findsOneWidget); + expect(tester.getTopLeft(body), const Offset(88, 0)); expect(tester.getTopLeft(pnav), Offset.zero); - expect(tester.getBottomRight(pnav), const Offset(88, 800)); + expect(smallBody, findsNothing); + expect(mediumLargeBody, findsNothing); + expect(largeBody, findsNothing); + expect(extraLargeBody, findsNothing); + expect(bnav, findsNothing); expect(pnav1, findsNothing); + expect(pnav2, findsNothing); + expect(pnav3, findsNothing); + // Medium Large await updateScreen(1100, tester); await tester.pumpAndSettle(); - expect(body, findsOneWidget); - expect(pnav, findsNothing); + expect(mediumLargeBody, findsOneWidget); expect(pnav1, findsOneWidget); + expect(tester.getTopLeft(mediumLargeBody), const Offset(208, 0)); expect(tester.getTopLeft(pnav1), Offset.zero); - expect(tester.getBottomRight(pnav1), const Offset(208, 800)); + expect(smallBody, findsNothing); + expect(body, findsNothing); + expect(largeBody, findsNothing); + expect(extraLargeBody, findsNothing); + expect(bnav, findsNothing); + expect(pnav, findsNothing); + expect(pnav2, findsNothing); + expect(pnav3, findsNothing); + + // Large + await updateScreen(1400, tester); + await tester.pumpAndSettle(); + expect(largeBody, findsOneWidget); + expect(mediumLargeBody, findsNothing); + expect(pnav2, findsOneWidget); + expect(tester.getTopLeft(largeBody), const Offset(208, 0)); + expect(tester.getTopLeft(pnav2), Offset.zero); + expect(smallBody, findsNothing); + expect(body, findsNothing); + expect(mediumLargeBody, findsNothing); + expect(extraLargeBody, findsNothing); + expect(bnav, findsNothing); + expect(pnav, findsNothing); + expect(pnav1, findsNothing); + expect(pnav3, findsNothing); + + // Extra Large + await updateScreen(1700, tester); + await tester.pumpAndSettle(); + expect(extraLargeBody, findsOneWidget); + expect(pnav3, findsOneWidget); + expect(tester.getTopLeft(extraLargeBody), const Offset(208, 0)); + expect(tester.getTopLeft(pnav3), Offset.zero); + expect(smallBody, findsNothing); + expect(body, findsNothing); + expect(mediumLargeBody, findsNothing); + expect(largeBody, findsNothing); + expect(bnav, findsNothing); + expect(pnav, findsNothing); + expect(pnav1, findsNothing); + expect(pnav2, findsNothing); }); testWidgets('adaptive scaffold animations work correctly', @@ -76,30 +130,30 @@ void main() { expect(tester.getTopLeft(b), const Offset(17.6, 0)); expect(tester.getBottomRight(b), - offsetMoreOrLessEquals(const Offset(778.2, 736), epsilon: 1.0)); + offsetMoreOrLessEquals(const Offset(778.2, 1936), epsilon: 1.0)); expect(tester.getTopLeft(sBody), offsetMoreOrLessEquals(const Offset(778.2, 0), epsilon: 1.0)); expect(tester.getBottomRight(sBody), - offsetMoreOrLessEquals(const Offset(1178.2, 736), epsilon: 1.0)); + offsetMoreOrLessEquals(const Offset(1178.2, 1936), epsilon: 1.0)); await tester.pump(); await tester.pump(const Duration(milliseconds: 600)); expect(tester.getTopLeft(b), const Offset(70.4, 0)); expect(tester.getBottomRight(b), - offsetMoreOrLessEquals(const Offset(416.0, 784), epsilon: 1.0)); + offsetMoreOrLessEquals(const Offset(416.0, 1984), epsilon: 1.0)); expect(tester.getTopLeft(sBody), offsetMoreOrLessEquals(const Offset(416, 0), epsilon: 1.0)); expect(tester.getBottomRight(sBody), - offsetMoreOrLessEquals(const Offset(816, 784), epsilon: 1.0)); + offsetMoreOrLessEquals(const Offset(816, 1984), epsilon: 1.0)); await tester.pump(); await tester.pump(const Duration(milliseconds: 200)); expect(tester.getTopLeft(b), const Offset(88, 0)); - expect(tester.getBottomRight(b), const Offset(400, 800)); + expect(tester.getBottomRight(b), const Offset(400, 2000)); expect(tester.getTopLeft(sBody), const Offset(400, 0)); - expect(tester.getBottomRight(sBody), const Offset(800, 800)); + expect(tester.getBottomRight(sBody), const Offset(800, 2000)); }); testWidgets('animation plays correctly in declared duration', @@ -114,8 +168,8 @@ void main() { await tester.pump(const Duration(milliseconds: 500)); expect(tester.getTopLeft(b), const Offset(88, 0)); - expect(tester.getBottomRight(b), const Offset(400, 800)); + expect(tester.getBottomRight(b), const Offset(400, 2000)); expect(tester.getTopLeft(sBody), const Offset(400, 0)); - expect(tester.getBottomRight(sBody), const Offset(800, 800)); + expect(tester.getBottomRight(sBody), const Offset(800, 2000)); }); } diff --git a/packages/flutter_adaptive_scaffold/example/test/main_test.dart b/packages/flutter_adaptive_scaffold/example/test/main_test.dart index 13e703105b69..26e03899e1b6 100644 --- a/packages/flutter_adaptive_scaffold/example/test/main_test.dart +++ b/packages/flutter_adaptive_scaffold/example/test/main_test.dart @@ -8,44 +8,126 @@ import 'package:flutter_adaptive_scaffold_example/adaptive_scaffold_demo.dart' import 'package:flutter_test/flutter_test.dart'; void main() { + final Finder smallBody = find.byKey(const Key('smallBody')); final Finder body = find.byKey(const Key('body')); + final Finder mediumLargeBody = find.byKey(const Key('mediumLargeBody')); + final Finder largeBody = find.byKey(const Key('largeBody')); + final Finder extraLargeBody = find.byKey(const Key('extraLargeBody')); + + final Finder smallSBody = find.byKey(const Key('smallSBody')); final Finder sBody = find.byKey(const Key('sBody')); + final Finder mediumLargeSBody = find.byKey(const Key('mediumLargeSBody')); + final Finder largeSBody = find.byKey(const Key('largeSBody')); + final Finder extraLargeSBody = find.byKey(const Key('extraLargeSBody')); + final Finder bnav = find.byKey(const Key('bottomNavigation')); final Finder pnav = find.byKey(const Key('primaryNavigation')); final Finder pnav1 = find.byKey(const Key('primaryNavigation1')); + final Finder pnav2 = find.byKey(const Key('primaryNavigation2')); + final Finder pnav3 = find.byKey(const Key('primaryNavigation3')); Future updateScreen(double width, WidgetTester tester) async { - await tester.binding.setSurfaceSize(Size(width, 800)); + await tester.binding.setSurfaceSize(Size(width, 2000)); await tester.pumpWidget( MaterialApp( home: MediaQuery( - data: MediaQueryData(size: Size(width, 800)), + data: MediaQueryData(size: Size(width, 2000)), child: const example.MyHomePage()), ), ); await tester.pumpAndSettle(); } - testWidgets('dislays correct item of config based on screen width', + testWidgets('displays correct item of config based on screen width', (WidgetTester tester) async { await updateScreen(300, tester); + expect(smallBody, findsOneWidget); + expect(body, findsNothing); + expect(mediumLargeBody, findsNothing); + expect(largeBody, findsNothing); + expect(extraLargeBody, findsNothing); + expect(smallSBody, findsNothing); expect(sBody, findsNothing); + expect(mediumLargeSBody, findsNothing); + expect(largeSBody, findsNothing); + expect(extraLargeSBody, findsNothing); expect(bnav, findsOneWidget); expect(body, findsNothing); expect(pnav, findsNothing); expect(pnav1, findsNothing); + expect(pnav2, findsNothing); + expect(pnav3, findsNothing); await updateScreen(800, tester); + expect(smallBody, findsNothing); expect(body, findsOneWidget); - expect(body, findsOneWidget); - expect(bnav, findsNothing); + expect(mediumLargeBody, findsNothing); + expect(largeBody, findsNothing); + expect(extraLargeBody, findsNothing); + expect(smallSBody, findsNothing); expect(sBody, findsOneWidget); + expect(mediumLargeSBody, findsNothing); + expect(largeSBody, findsNothing); + expect(extraLargeSBody, findsNothing); + expect(bnav, findsNothing); + expect(body, findsOneWidget); expect(pnav, findsOneWidget); expect(pnav1, findsNothing); + expect(pnav2, findsNothing); + expect(pnav3, findsNothing); await updateScreen(1100, tester); - expect(body, findsOneWidget); + expect(smallBody, findsNothing); + expect(body, findsNothing); + expect(mediumLargeBody, findsOneWidget); + expect(largeBody, findsNothing); + expect(extraLargeBody, findsNothing); + expect(smallSBody, findsNothing); + expect(sBody, findsNothing); + expect(mediumLargeSBody, findsOneWidget); + expect(largeSBody, findsNothing); + expect(extraLargeSBody, findsNothing); + expect(bnav, findsNothing); + expect(body, findsNothing); expect(pnav, findsNothing); expect(pnav1, findsOneWidget); + expect(pnav2, findsNothing); + expect(pnav3, findsNothing); + + await updateScreen(1400, tester); + expect(smallBody, findsNothing); + expect(body, findsNothing); + expect(mediumLargeBody, findsNothing); + expect(largeBody, findsOneWidget); + expect(extraLargeBody, findsNothing); + expect(smallSBody, findsNothing); + expect(sBody, findsNothing); + expect(mediumLargeSBody, findsNothing); + expect(largeSBody, findsOneWidget); + expect(extraLargeSBody, findsNothing); + expect(bnav, findsNothing); + expect(body, findsNothing); + expect(pnav, findsNothing); + expect(pnav1, findsNothing); + expect(pnav2, findsOneWidget); + expect(pnav3, findsNothing); + + await updateScreen(1800, tester); + expect(smallBody, findsNothing); + expect(body, findsNothing); + expect(mediumLargeBody, findsNothing); + expect(largeBody, findsNothing); + expect(extraLargeBody, findsOneWidget); + expect(smallSBody, findsNothing); + expect(sBody, findsNothing); + expect(mediumLargeSBody, findsNothing); + expect(largeSBody, findsNothing); + expect(extraLargeSBody, findsOneWidget); + expect(bnav, findsNothing); + expect(body, findsNothing); + expect(pnav, findsNothing); + expect(pnav1, findsNothing); + expect(pnav2, findsNothing); + expect(pnav3, findsOneWidget); }); } diff --git a/packages/flutter_adaptive_scaffold/example/web/index.html b/packages/flutter_adaptive_scaffold/example/web/index.html index 9be0ff0a763a..064d7a356f47 100644 --- a/packages/flutter_adaptive_scaffold/example/web/index.html +++ b/packages/flutter_adaptive_scaffold/example/web/index.html @@ -34,29 +34,8 @@ example - - - - - + diff --git a/packages/flutter_adaptive_scaffold/lib/src/adaptive_layout.dart b/packages/flutter_adaptive_scaffold/lib/src/adaptive_layout.dart index 9f6cc78a96d5..50fd625917c0 100644 --- a/packages/flutter_adaptive_scaffold/lib/src/adaptive_layout.dart +++ b/packages/flutter_adaptive_scaffold/lib/src/adaptive_layout.dart @@ -58,8 +58,8 @@ enum _SlotIds { /// key: const Key('Primary Navigation Medium'), /// builder: (_) => AdaptiveScaffold.toNavigationRail(destinations: destinations), /// ), -/// Breakpoints.large: SlotLayout.from( -/// key: const Key('Primary Navigation Large'), +/// Breakpoints.mediumLarge: SlotLayout.from( +/// key: const Key('Primary Navigation MediumLarge'), /// inAnimation: leftOutIn, /// builder: (_) => AdaptiveScaffold.toNavigationRail(extended: true, destinations: destinations), /// ), @@ -293,7 +293,7 @@ class _AdaptiveLayoutState extends State }); Rect? hinge; - for (final DisplayFeature e in MediaQuery.of(context).displayFeatures) { + for (final DisplayFeature e in MediaQuery.displayFeaturesOf(context)) { if (e.type == DisplayFeatureType.hinge || e.type == DisplayFeatureType.fold) { if (e.bounds.left != 0) { diff --git a/packages/flutter_adaptive_scaffold/lib/src/adaptive_scaffold.dart b/packages/flutter_adaptive_scaffold/lib/src/adaptive_scaffold.dart index c2a2e68327bf..e8b8832054a8 100644 --- a/packages/flutter_adaptive_scaffold/lib/src/adaptive_scaffold.dart +++ b/packages/flutter_adaptive_scaffold/lib/src/adaptive_scaffold.dart @@ -8,21 +8,32 @@ import 'adaptive_layout.dart'; import 'breakpoints.dart'; import 'slot_layout.dart'; -/// Gutter value between different parts of the body slot depending on -/// material 3 design spec. -const double kMaterialGutterValue = 8; +/// Spacing value of the compact breakpoint according to +/// the material 3 design spec. +const double kMaterialCompactSpacing = 0; -/// Margin value of the compact breakpoint layout according to the material +/// Spacing value of the medium and up breakpoint according to +/// the material 3 design spec. +const double kMaterialMediumAndUpSpacing = 24; + +/// Margin value of the compact breakpoint according to the material /// design 3 spec. -const double kMaterialCompactMinMargin = 8; +const double kMaterialCompactMargin = 16; -/// Margin value of the medium breakpoint layout according to the material +/// Margin value of the medium breakpoint according to the material /// design 3 spec. -const double kMaterialMediumMinMargin = 12; +const double kMaterialMediumAndUpMargin = 24; -//// Margin value of the expanded breakpoint layout according to the material +/// Padding value of the compact breakpoint according to the material /// design 3 spec. -const double kMaterialExpandedMinMargin = 32; +const double kMaterialPadding = 4; + +/// Signature for a builder used by [AdaptiveScaffold.navigationRailDestinationBuilder] that converts a +/// [NavigationDestination] to a [NavigationRailDestination]. +typedef NavigationRailDestinationBuilder = NavigationRailDestination Function( + int index, + NavigationDestination destination, +); /// Implements the basic visual layout structure for /// [Material Design 3](https://m3.material.io/foundations/adaptive-design/overview) @@ -85,14 +96,20 @@ class AdaptiveScaffold extends StatefulWidget { this.trailingNavRail, this.smallBody, this.body, + this.mediumLargeBody, this.largeBody, + this.extraLargeBody, this.smallSecondaryBody, this.secondaryBody, + this.mediumLargeSecondaryBody, this.largeSecondaryBody, + this.extraLargeSecondaryBody, this.bodyRatio, this.smallBreakpoint = Breakpoints.small, this.mediumBreakpoint = Breakpoints.medium, + this.mediumLargeBreakpoint = Breakpoints.mediumLarge, this.largeBreakpoint = Breakpoints.large, + this.extraLargeBreakpoint = Breakpoints.extraLarge, this.drawerBreakpoint = Breakpoints.smallDesktop, this.internalAnimations = true, this.transitionDuration = const Duration(seconds: 1), @@ -103,6 +120,8 @@ class AdaptiveScaffold extends StatefulWidget { this.navigationRailWidth = 72, this.extendedNavigationRailWidth = 192, this.appBarBreakpoint, + this.navigationRailDestinationBuilder, + this.groupAlignment, }) : assert( destinations.length >= 2, 'At least two destinations are required', @@ -129,6 +148,9 @@ class AdaptiveScaffold extends StatefulWidget { /// navigation rail at the largest breakpoint. final Widget? trailingNavRail; + /// The alignment of the destinations in the navigation rail. + final double? groupAlignment; + /// Widget to be displayed in the body slot at the smallest breakpoint. /// /// If nothing is entered for this property, then the default [body] is @@ -136,19 +158,33 @@ class AdaptiveScaffold extends StatefulWidget { /// empty. final WidgetBuilder? smallBody; - /// Widget to be displayed in the body slot at the middle breakpoint. + /// Widget to be displayed in the body slot at the medium breakpoint. /// /// The default displayed body. final WidgetBuilder? body; - /// Widget to be displayed in the body slot at the largest breakpoint. + /// Widget to be displayed in the body slot at the mediumLarge breakpoint. + /// + /// If nothing is entered for this property, then the default [body] is + /// displayed in the slot. If null is entered for this slot, the slot stays + /// empty. + final WidgetBuilder? mediumLargeBody; + + /// Widget to be displayed in the body slot at the large breakpoint. /// /// If nothing is entered for this property, then the default [body] is /// displayed in the slot. If null is entered for this slot, the slot stays /// empty. final WidgetBuilder? largeBody; - /// Widget to be displayed in the secondaryBody slot at the smallest + /// Widget to be displayed in the body slot at the extraLarge breakpoint. + /// + /// If nothing is entered for this property, then the default [body] is + /// displayed in the slot. If null is entered for this slot, the slot stays + /// empty. + final WidgetBuilder? extraLargeBody; + + /// Widget to be displayed in the secondaryBody slot at the compact /// breakpoint. /// /// If nothing is entered for this property, then the default [secondaryBody] @@ -156,12 +192,20 @@ class AdaptiveScaffold extends StatefulWidget { /// empty. final WidgetBuilder? smallSecondaryBody; - /// Widget to be displayed in the secondaryBody slot at the middle breakpoint. + /// Widget to be displayed in the secondaryBody slot at the medium breakpoint. /// /// The default displayed secondaryBody. final WidgetBuilder? secondaryBody; - /// Widget to be displayed in the secondaryBody slot at the largest + /// Widget to be displayed in the secondaryBody slot at the mediumLarge + /// breakpoint. + /// + /// If nothing is entered for this property, then the default [secondaryBody] + /// is displayed in the slot. If null is entered for this slot, the slot stays + /// empty. + final WidgetBuilder? mediumLargeSecondaryBody; + + /// Widget to be displayed in the secondaryBody slot at the large /// breakpoint. /// /// If nothing is entered for this property, then the default [secondaryBody] @@ -169,6 +213,14 @@ class AdaptiveScaffold extends StatefulWidget { /// empty. final WidgetBuilder? largeSecondaryBody; + /// Widget to be displayed in the secondaryBody slot at the extraLarge + /// breakpoint. + /// + /// If nothing is entered for this property, then the default [secondaryBody] + /// is displayed in the slot. If null is entered for this slot, the slot stays + /// empty. + final WidgetBuilder? extraLargeSecondaryBody; + /// Defines the fractional ratio of body to the secondaryBody. /// /// For example 0.3 would mean body takes up 30% of the available space and @@ -178,7 +230,7 @@ class AdaptiveScaffold extends StatefulWidget { /// the center of the screen. final double? bodyRatio; - /// The breakpoint defined for the small size, associated with mobile-like + /// The breakpoint defined for the compact size, associated with mobile-like /// features. /// /// Defaults to [Breakpoints.small]. @@ -187,15 +239,27 @@ class AdaptiveScaffold extends StatefulWidget { /// The breakpoint defined for the medium size, associated with tablet-like /// features. /// - /// Defaults to [Breakpoints.mediumBreakpoint]. + /// Defaults to [Breakpoints.medium]. final Breakpoint mediumBreakpoint; + /// The breakpoint defined for the mediumLarge size, associated with desktop-like + /// features. + /// + /// Defaults to [Breakpoints.mediumLarge]. + final Breakpoint mediumLargeBreakpoint; + /// The breakpoint defined for the large size, associated with desktop-like /// features. /// - /// Defaults to [Breakpoints.largeBreakpoint]. + /// Defaults to [Breakpoints.large]. final Breakpoint largeBreakpoint; + /// The breakpoint defined for the extraLarge size, associated with ultra-wide + /// features. + /// + /// Defaults to [Breakpoints.extraLarge]. + final Breakpoint extraLargeBreakpoint; + /// Whether or not the developer wants the smooth entering slide transition on /// secondaryBody. /// @@ -246,6 +310,9 @@ class AdaptiveScaffold extends StatefulWidget { /// [Breakpoint]. final double extendedNavigationRailWidth; + /// Used to map NavigationDestination to NavigationRailDestination. + final NavigationRailDestinationBuilder? navigationRailDestinationBuilder; + /// Callback function for when the index of a [NavigationRail] changes. static WidgetBuilder emptyBuilder = (_) => const SizedBox(); @@ -267,6 +334,9 @@ class AdaptiveScaffold extends StatefulWidget { /// Takes in a [selectedIndex] property for the current selected item in /// the [NavigationRail] and [extended] for whether the [NavigationRail] /// is extended or not. + /// + /// If [labelType] is null, then the default value is + /// [NavigationRailLabelType.none]. static Builder standardNavigationRail({ required List destinations, double width = 72, @@ -282,7 +352,7 @@ class AdaptiveScaffold extends StatefulWidget { IconThemeData? unselectedIconTheme, TextStyle? selectedLabelTextStyle, TextStyle? unSelectedLabelTextStyle, - NavigationRailLabelType labelType = NavigationRailLabelType.none, + NavigationRailLabelType? labelType = NavigationRailLabelType.none, }) { if (extended && width == 72) { width = 192; @@ -292,7 +362,7 @@ class AdaptiveScaffold extends StatefulWidget { padding: padding, child: SizedBox( width: width, - height: MediaQuery.of(context).size.height, + height: MediaQuery.sizeOf(context).height, child: LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { return SingleChildScrollView( @@ -363,38 +433,19 @@ class AdaptiveScaffold extends StatefulWidget { /// Public helper method to be used for creating a staggered grid following m3 /// specs from a list of [Widget]s static Builder toMaterialGrid({ - List thisWidgets = const [], - List breakpoints = const [ - Breakpoints.small, - Breakpoints.medium, - Breakpoints.large, - ], - double margin = 8, - int itemColumns = 1, - required BuildContext context, + List widgets = const [], + List breakpoints = Breakpoints.all, + double? margin, + int? itemColumns, }) { return Builder(builder: (BuildContext context) { - Breakpoint? currentBreakpoint; - for (final Breakpoint breakpoint in breakpoints) { - if (breakpoint.isActive(context)) { - currentBreakpoint = breakpoint; - } - } - double? thisMargin = margin; + final Breakpoint? currentBreakpoint = + Breakpoint.activeBreakpointIn(context, breakpoints); + final double thisMargin = + margin ?? currentBreakpoint?.margin ?? kMaterialCompactMargin; + final int thisColumns = + itemColumns ?? currentBreakpoint?.recommendedPanes ?? 1; - if (currentBreakpoint == Breakpoints.small) { - if (thisMargin < kMaterialCompactMinMargin) { - thisMargin = kMaterialCompactMinMargin; - } - } else if (currentBreakpoint == Breakpoints.medium) { - if (thisMargin < kMaterialMediumMinMargin) { - thisMargin = kMaterialMediumMinMargin; - } - } else if (currentBreakpoint == Breakpoints.large) { - if (thisMargin < kMaterialExpandedMinMargin) { - thisMargin = kMaterialExpandedMinMargin; - } - } return CustomScrollView( primary: false, controller: ScrollController(), @@ -405,11 +456,10 @@ class AdaptiveScaffold extends StatefulWidget { child: Padding( padding: EdgeInsets.all(thisMargin), child: _BrickLayout( - columns: itemColumns, - columnSpacing: kMaterialGutterValue, - itemPadding: - const EdgeInsets.only(bottom: kMaterialGutterValue), - children: thisWidgets, + columns: thisColumns, + columnSpacing: thisMargin, + itemPadding: EdgeInsets.only(bottom: thisMargin), + children: widgets, ), ), ), @@ -513,6 +563,13 @@ class _AdaptiveScaffoldState extends State { final NavigationRailThemeData navRailTheme = Theme.of(context).navigationRailTheme; + final List destinations = widget.destinations + .map((NavigationDestination destination) => + widget.navigationRailDestinationBuilder + ?.call(widget.destinations.indexOf(destination), destination) ?? + AdaptiveScaffold.toRailDestination(destination)) + .toList(); + return Scaffold( key: _scaffoldKey, appBar: widget.drawerBreakpoint.isActive(context) && widget.useDrawer || @@ -526,11 +583,15 @@ class _AdaptiveScaffoldState extends State { leading: widget.leadingExtendedNavRail, trailing: widget.trailingNavRail, selectedIndex: widget.selectedIndex, - destinations: widget.destinations - .map((NavigationDestination destination) => - AdaptiveScaffold.toRailDestination(destination)) - .toList(), + destinations: destinations, onDestinationSelected: _onDrawerDestinationSelected, + backgroundColor: navRailTheme.backgroundColor, + selectedIconTheme: navRailTheme.selectedIconTheme, + unselectedIconTheme: navRailTheme.unselectedIconTheme, + selectedLabelTextStyle: navRailTheme.selectedLabelTextStyle, + unselectedLabelTextStyle: navRailTheme.unselectedLabelTextStyle, + groupAlignment: widget.groupAlignment, + labelType: navRailTheme.labelType, ), ) : null, @@ -548,6 +609,44 @@ class _AdaptiveScaffoldState extends State { leading: widget.leadingUnextendedNavRail, trailing: widget.trailingNavRail, selectedIndex: widget.selectedIndex, + destinations: destinations, + onDestinationSelected: widget.onSelectedIndexChange, + backgroundColor: navRailTheme.backgroundColor, + selectedIconTheme: navRailTheme.selectedIconTheme, + unselectedIconTheme: navRailTheme.unselectedIconTheme, + selectedLabelTextStyle: navRailTheme.selectedLabelTextStyle, + unSelectedLabelTextStyle: navRailTheme.unselectedLabelTextStyle, + labelType: navRailTheme.labelType, + groupAlignment: widget.groupAlignment, + ), + ), + widget.mediumLargeBreakpoint: SlotLayout.from( + key: const Key('primaryNavigation1'), + builder: (_) => AdaptiveScaffold.standardNavigationRail( + width: widget.extendedNavigationRailWidth, + extended: true, + leading: widget.leadingExtendedNavRail, + trailing: widget.trailingNavRail, + selectedIndex: widget.selectedIndex, + destinations: destinations, + onDestinationSelected: widget.onSelectedIndexChange, + backgroundColor: navRailTheme.backgroundColor, + selectedIconTheme: navRailTheme.selectedIconTheme, + unselectedIconTheme: navRailTheme.unselectedIconTheme, + selectedLabelTextStyle: navRailTheme.selectedLabelTextStyle, + unSelectedLabelTextStyle: navRailTheme.unselectedLabelTextStyle, + labelType: navRailTheme.labelType, + groupAlignment: widget.groupAlignment, + ), + ), + widget.largeBreakpoint: SlotLayout.from( + key: const Key('primaryNavigation2'), + builder: (_) => AdaptiveScaffold.standardNavigationRail( + width: widget.extendedNavigationRailWidth, + extended: true, + leading: widget.leadingExtendedNavRail, + trailing: widget.trailingNavRail, + selectedIndex: widget.selectedIndex, destinations: widget.destinations .map((NavigationDestination destination) => AdaptiveScaffold.toRailDestination(destination)) @@ -560,8 +659,8 @@ class _AdaptiveScaffoldState extends State { unSelectedLabelTextStyle: navRailTheme.unselectedLabelTextStyle, ), ), - widget.largeBreakpoint: SlotLayout.from( - key: const Key('primaryNavigation1'), + widget.extraLargeBreakpoint: SlotLayout.from( + key: const Key('primaryNavigation3'), builder: (_) => AdaptiveScaffold.standardNavigationRail( width: widget.extendedNavigationRailWidth, extended: true, @@ -626,6 +725,16 @@ class _AdaptiveScaffoldState extends State { builder: widget.body, ) : null, + if (widget.mediumLargeBody != null) + widget.mediumLargeBreakpoint: + (widget.mediumLargeBody != AdaptiveScaffold.emptyBuilder) + ? SlotLayout.from( + key: const Key('mediumLargeBody'), + inAnimation: AdaptiveScaffold.fadeIn, + outAnimation: AdaptiveScaffold.fadeOut, + builder: widget.mediumLargeBody, + ) + : null, if (widget.largeBody != null) widget.largeBreakpoint: (widget.largeBody != AdaptiveScaffold.emptyBuilder) @@ -636,6 +745,16 @@ class _AdaptiveScaffoldState extends State { builder: widget.largeBody, ) : null, + if (widget.extraLargeBody != null) + widget.extraLargeBreakpoint: + (widget.extraLargeBody != AdaptiveScaffold.emptyBuilder) + ? SlotLayout.from( + key: const Key('extraLargeBody'), + inAnimation: AdaptiveScaffold.fadeIn, + outAnimation: AdaptiveScaffold.fadeOut, + builder: widget.extraLargeBody, + ) + : null, }, ), secondaryBody: SlotLayout( @@ -663,6 +782,15 @@ class _AdaptiveScaffoldState extends State { builder: widget.secondaryBody, ) : null, + if (widget.mediumLargeSecondaryBody != null) + widget.mediumLargeBreakpoint: (widget.mediumLargeSecondaryBody != + AdaptiveScaffold.emptyBuilder) + ? SlotLayout.from( + key: const Key('mediumLargeSBody'), + outAnimation: AdaptiveScaffold.stayOnScreen, + builder: widget.mediumLargeSecondaryBody, + ) + : null, if (widget.largeSecondaryBody != null) widget.largeBreakpoint: (widget.largeSecondaryBody != AdaptiveScaffold.emptyBuilder) @@ -672,6 +800,15 @@ class _AdaptiveScaffoldState extends State { builder: widget.largeSecondaryBody, ) : null, + if (widget.extraLargeSecondaryBody != null) + widget.extraLargeBreakpoint: (widget.extraLargeSecondaryBody != + AdaptiveScaffold.emptyBuilder) + ? SlotLayout.from( + key: const Key('extraLargeSBody'), + outAnimation: AdaptiveScaffold.stayOnScreen, + builder: widget.extraLargeSecondaryBody, + ) + : null, }, ), ), diff --git a/packages/flutter_adaptive_scaffold/lib/src/breakpoints.dart b/packages/flutter_adaptive_scaffold/lib/src/breakpoints.dart index 5a7bcfe579b4..91568cedeac8 100644 --- a/packages/flutter_adaptive_scaffold/lib/src/breakpoints.dart +++ b/packages/flutter_adaptive_scaffold/lib/src/breakpoints.dart @@ -4,17 +4,7 @@ import 'package:flutter/material.dart'; -const Set _desktop = { - TargetPlatform.linux, - TargetPlatform.macOS, - TargetPlatform.windows -}; - -const Set _mobile = { - TargetPlatform.android, - TargetPlatform.fuchsia, - TargetPlatform.iOS, -}; +import '../flutter_adaptive_scaffold.dart'; /// A group of standard breakpoints built according to the material /// specifications for screen width size. @@ -27,83 +17,102 @@ class Breakpoints { /// case that no other breakpoint is active. /// /// It is active from a width of -1 dp to infinity. - static const Breakpoint standard = WidthPlatformBreakpoint(begin: -1); + static const Breakpoint standard = Breakpoint.standard(); /// A window whose width is less than 600 dp and greater than 0 dp. - static const Breakpoint small = WidthPlatformBreakpoint(begin: 0, end: 600); + static const Breakpoint small = Breakpoint.small(); /// A window whose width is greater than 0 dp. - static const Breakpoint smallAndUp = WidthPlatformBreakpoint(begin: 0); + static const Breakpoint smallAndUp = Breakpoint.small(andUp: true); /// A desktop screen whose width is less than 600 dp and greater than 0 dp. static const Breakpoint smallDesktop = - WidthPlatformBreakpoint(begin: 0, end: 600, platform: _desktop); + Breakpoint.small(platform: Breakpoint.desktop); /// A mobile screen whose width is less than 600 dp and greater than 0 dp. static const Breakpoint smallMobile = - WidthPlatformBreakpoint(begin: 0, end: 600, platform: _mobile); + Breakpoint.small(platform: Breakpoint.mobile); /// A window whose width is between 600 dp and 840 dp. - static const Breakpoint medium = - WidthPlatformBreakpoint(begin: 600, end: 840); + static const Breakpoint medium = Breakpoint.medium(); /// A window whose width is greater than 600 dp. - static const Breakpoint mediumAndUp = WidthPlatformBreakpoint(begin: 600); + static const Breakpoint mediumAndUp = Breakpoint.medium(andUp: true); /// A desktop window whose width is between 600 dp and 840 dp. static const Breakpoint mediumDesktop = - WidthPlatformBreakpoint(begin: 600, end: 840, platform: _desktop); + Breakpoint.medium(platform: Breakpoint.desktop); /// A mobile window whose width is between 600 dp and 840 dp. static const Breakpoint mediumMobile = - WidthPlatformBreakpoint(begin: 600, end: 840, platform: _mobile); + Breakpoint.medium(platform: Breakpoint.mobile); + + /// A window whose width is between 840 dp and 1200 dp. + static const Breakpoint mediumLarge = Breakpoint.mediumLarge(); /// A window whose width is greater than 840 dp. - static const Breakpoint large = WidthPlatformBreakpoint(begin: 840); + static const Breakpoint mediumLargeAndUp = + Breakpoint.mediumLarge(andUp: true); - /// A desktop window whose width is greater than 840 dp. - static const Breakpoint largeDesktop = - WidthPlatformBreakpoint(begin: 840, platform: _desktop); + /// A desktop window whose width is between 840 dp and 1200 dp. + static const Breakpoint mediumLargeDesktop = + Breakpoint.mediumLarge(platform: Breakpoint.desktop); - /// A mobile window whose width is greater than 840 dp. - static const Breakpoint largeMobile = - WidthPlatformBreakpoint(begin: 840, platform: _mobile); -} + /// A mobile window whose width is between 840 dp and 1200 dp. + static const Breakpoint mediumLargeMobile = + Breakpoint.mediumLarge(platform: Breakpoint.mobile); -/// A class that can be used to quickly generate [Breakpoint]s that depend on -/// the screen width and the platform. -class WidthPlatformBreakpoint extends Breakpoint { - /// Returns a const [Breakpoint] with the given constraints. - const WidthPlatformBreakpoint({this.begin, this.end, this.platform}); + /// A window whose width is between 1200 dp and 1600 dp. + static const Breakpoint large = Breakpoint.large(); - /// The beginning width dp value. If left null then the [Breakpoint] will have - /// no lower bound. - final double? begin; + /// A window whose width is greater than 1200 dp. + static const Breakpoint largeAndUp = Breakpoint.large(andUp: true); - /// The end width dp value. If left null then the [Breakpoint] will have no - /// upper bound. - final double? end; + /// A desktop window whose width is between 1200 dp and 1600 dp. + static const Breakpoint largeDesktop = + Breakpoint.large(platform: Breakpoint.desktop); - /// A Set of [TargetPlatform]s that the [Breakpoint] will be active on. If - /// left null then it will be active on all platforms. - final Set? platform; + /// A mobile window whose width is between 1200 dp and 1600 dp. + static const Breakpoint largeMobile = + Breakpoint.large(platform: Breakpoint.mobile); - @override - bool isActive(BuildContext context) { - final TargetPlatform host = Theme.of(context).platform; - final bool isRightPlatform = platform?.contains(host) ?? true; + /// A window whose width is greater than 1600 dp. + static const Breakpoint extraLarge = Breakpoint.extraLarge(); - // Null boundaries are unbounded, assign the max/min of their associated - // direction on a number line. - final double width = MediaQuery.sizeOf(context).width; - final double lowerBound = begin ?? double.negativeInfinity; - final double upperBound = end ?? double.infinity; + /// A desktop window whose width is greater than 1600 dp. + static const Breakpoint extraLargeDesktop = + Breakpoint.extraLarge(platform: Breakpoint.desktop); - return width >= lowerBound && width < upperBound && isRightPlatform; - } + /// A mobile window whose width is greater than 1600 dp. + static const Breakpoint extraLargeMobile = + Breakpoint.extraLarge(platform: Breakpoint.mobile); + + /// A list of all the standard breakpoints. + static const List all = [ + smallDesktop, + smallMobile, + small, + mediumDesktop, + mediumMobile, + medium, + mediumLargeDesktop, + mediumLargeMobile, + mediumLarge, + largeDesktop, + largeMobile, + large, + extraLargeDesktop, + extraLargeMobile, + extraLarge, + smallAndUp, + mediumAndUp, + mediumLargeAndUp, + largeAndUp, + standard, + ]; } -/// An interface to define the conditions that distinguish between types of +/// A class to define the conditions that distinguish between types of /// screens. /// /// Adaptive apps usually display differently depending on the screen type: a @@ -121,11 +130,298 @@ class WidthPlatformBreakpoint extends Breakpoint { /// /// * [SlotLayout.config], which uses breakpoints to dictate the layout of the /// screen. -abstract class Breakpoint { - /// Returns a const [Breakpoint]. - const Breakpoint(); +class Breakpoint { + // #docregion Breakpoints + /// Returns a const [Breakpoint] with the given constraints. + const Breakpoint({ + this.beginWidth, + this.endWidth, + this.beginHeight, + this.endHeight, + this.andUp = false, + this.platform, + this.spacing = kMaterialMediumAndUpSpacing, + this.margin = kMaterialMediumAndUpMargin, + this.padding = kMaterialPadding, + this.recommendedPanes = 1, + this.maxPanes = 1, + }); + + /// Returns a [Breakpoint] that can be used as a fallthrough in the + /// case that no other breakpoint is active. + const Breakpoint.standard({this.platform}) + : beginWidth = -1, + endWidth = null, + beginHeight = null, + endHeight = null, + spacing = kMaterialMediumAndUpSpacing, + margin = kMaterialMediumAndUpMargin, + padding = kMaterialPadding, + recommendedPanes = 1, + maxPanes = 1, + andUp = true; + + /// Returns a [Breakpoint] with the given constraints for a small screen. + const Breakpoint.small({this.andUp = false, this.platform}) + : beginWidth = 0, + endWidth = 600, + beginHeight = null, + endHeight = 480, + spacing = kMaterialCompactSpacing, + margin = kMaterialCompactMargin, + padding = kMaterialPadding, + recommendedPanes = 1, + maxPanes = 1; + + /// Returns a [Breakpoint] with the given constraints for a medium screen. + const Breakpoint.medium({this.andUp = false, this.platform}) + : beginWidth = 600, + endWidth = 840, + beginHeight = 480, + endHeight = 900, + spacing = kMaterialMediumAndUpSpacing, + margin = kMaterialMediumAndUpMargin, + padding = kMaterialPadding * 2, + recommendedPanes = 1, + maxPanes = 2; + + /// Returns a [Breakpoint] with the given constraints for a mediumLarge screen. + const Breakpoint.mediumLarge({this.andUp = false, this.platform}) + : beginWidth = 840, + endWidth = 1200, + beginHeight = 900, + endHeight = null, + spacing = kMaterialMediumAndUpSpacing, + margin = kMaterialMediumAndUpMargin, + padding = kMaterialPadding * 3, + recommendedPanes = 2, + maxPanes = 2; + + /// Returns a [Breakpoint] with the given constraints for a large screen. + const Breakpoint.large({this.andUp = false, this.platform}) + : beginWidth = 1200, + endWidth = 1600, + beginHeight = 900, + endHeight = null, + spacing = kMaterialMediumAndUpSpacing, + margin = kMaterialMediumAndUpMargin, + padding = kMaterialPadding * 4, + recommendedPanes = 2, + maxPanes = 2; + + /// Returns a [Breakpoint] with the given constraints for an extraLarge screen. + const Breakpoint.extraLarge({this.andUp = false, this.platform}) + : beginWidth = 1600, + endWidth = null, + beginHeight = 900, + endHeight = null, + spacing = kMaterialMediumAndUpSpacing, + margin = kMaterialMediumAndUpMargin, + padding = kMaterialPadding * 5, + recommendedPanes = 2, + maxPanes = 3; + // #enddocregion Breakpoints + + /// A set of [TargetPlatform]s that the [Breakpoint] will be active on desktop. + static const Set desktop = { + TargetPlatform.linux, + TargetPlatform.macOS, + TargetPlatform.windows + }; + + /// A set of [TargetPlatform]s that the [Breakpoint] will be active on mobile. + static const Set mobile = { + TargetPlatform.android, + TargetPlatform.fuchsia, + TargetPlatform.iOS, + }; + + /// When set to true, it will include any size above the set width and set height. + final bool andUp; + + /// The beginning width dp value. If left null then the [Breakpoint] will have + /// no lower bound. + final double? beginWidth; + + /// The end width dp value. If left null then the [Breakpoint] will have no + /// upper bound. + final double? endWidth; + + /// The beginning height dp value. If left null then the [Breakpoint] will have + /// no lower bound. + final double? beginHeight; + + /// The end height dp value. If left null then the [Breakpoint] will have no + /// upper bound. + final double? endHeight; + + /// A Set of [TargetPlatform]s that the [Breakpoint] will be active on. If + /// left null then it will be active on all platforms. + final Set? platform; + + /// The default material spacing for the [Breakpoint]. + final double spacing; + + /// The default material margin for the [Breakpoint]. + final double margin; + + /// The default material padding for the [Breakpoint]. + final double padding; + + /// The material recommended number of panes for the [Breakpoint]. + final int recommendedPanes; + + /// The material maximum number of panes that can be displayed on the [Breakpoint]. + final int maxPanes; /// A method that returns true based on conditions related to the context of - /// the screen such as MediaQuery.sizeOf(context).width. - bool isActive(BuildContext context); + /// the screen such as MediaQuery.sizeOf(context).width, MediaQuery.sizeOf(context).height + /// and MediaQuery.orientationOf(context). + bool isActive(BuildContext context) { + final TargetPlatform host = Theme.of(context).platform; + final bool isRightPlatform = platform?.contains(host) ?? true; + + final double width = MediaQuery.sizeOf(context).width; + final double height = MediaQuery.sizeOf(context).height; + final Orientation orientation = MediaQuery.orientationOf(context); + final bool isPortrait = orientation == Orientation.portrait; + + final double lowerBoundWidth = beginWidth ?? double.negativeInfinity; + final double upperBoundWidth = endWidth ?? double.infinity; + + final double lowerBoundHeight = beginHeight ?? double.negativeInfinity; + final double upperBoundHeight = endHeight ?? double.infinity; + + final bool isWidthActive = andUp + ? width >= lowerBoundWidth + : width >= lowerBoundWidth && width < upperBoundWidth; + + final bool isHeightActive = isPortrait || isWidthActive || andUp + ? isWidthActive || height >= lowerBoundHeight + : height >= lowerBoundHeight && height < upperBoundHeight; + + return isWidthActive && isHeightActive && isRightPlatform; + } + + /// Returns the currently active [Breakpoint] based on the [SlotLayout] in the + /// context. + static Breakpoint? maybeActiveBreakpointFromSlotLayout(BuildContext context) { + final SlotLayout? slotLayout = + context.findAncestorWidgetOfExactType(); + + return slotLayout != null + ? activeBreakpointIn(context, slotLayout.config.keys.toList()) + : null; + } + + /// Returns the default [Breakpoint] based on the [BuildContext]. + static Breakpoint defaultBreakpointOf(BuildContext context) { + return activeBreakpointIn(context, Breakpoints.all) ?? Breakpoints.standard; + } + + /// Returns the currently active [Breakpoint]. + static Breakpoint activeBreakpointOf(BuildContext context) { + return maybeActiveBreakpointFromSlotLayout(context) ?? + defaultBreakpointOf(context); + } + + /// Returns the currently active [Breakpoint] based on the [BuildContext] and + /// a list of [Breakpoint]s. + static Breakpoint? activeBreakpointIn( + BuildContext context, List breakpoints) { + Breakpoint? currentBreakpoint; + + for (final Breakpoint breakpoint in breakpoints) { + if (breakpoint.isActive(context)) { + if (breakpoint.platform != null) { + // Prioritize platform-specific breakpoints. + return breakpoint; + } else { + // Fallback to non-platform-specific. + currentBreakpoint = breakpoint; + } + } + } + return currentBreakpoint; + } + + /// Returns true if the current platform is Desktop. + static bool isDesktop(BuildContext context) { + return Breakpoint.desktop.contains(Theme.of(context).platform); + } + + /// Returns true if the current platform is Mobile. + static bool isMobile(BuildContext context) { + return Breakpoint.mobile.contains(Theme.of(context).platform); + } + + // #docregion Breakpoint operators + /// Returns true if this [Breakpoint] is greater than the given [Breakpoint]. + bool operator >(Breakpoint breakpoint) + // #enddocregion Breakpoint operators + { + return (beginWidth ?? double.negativeInfinity) > + (breakpoint.beginWidth ?? double.negativeInfinity) && + (endWidth ?? double.infinity) > + (breakpoint.endWidth ?? double.infinity) && + (beginHeight ?? double.negativeInfinity) > + (breakpoint.beginHeight ?? double.negativeInfinity) && + (endHeight ?? double.infinity) > + (breakpoint.endHeight ?? double.infinity); + } + + // #docregion Breakpoint operators + /// Returns true if this [Breakpoint] is less than the given [Breakpoint]. + bool operator <(Breakpoint breakpoint) + // #enddocregion Breakpoint operators + { + return (endWidth ?? double.infinity) < + (breakpoint.endWidth ?? double.infinity) && + (beginWidth ?? double.negativeInfinity) < + (breakpoint.beginWidth ?? double.negativeInfinity) && + (endHeight ?? double.infinity) < + (breakpoint.endHeight ?? double.infinity) && + (beginHeight ?? double.negativeInfinity) < + (breakpoint.beginHeight ?? double.negativeInfinity); + } + + // #docregion Breakpoint operators + /// Returns true if this [Breakpoint] is greater than or equal to the + /// given [Breakpoint]. + bool operator >=(Breakpoint breakpoint) + // #enddocregion Breakpoint operators + { + return (beginWidth ?? double.negativeInfinity) >= + (breakpoint.beginWidth ?? double.negativeInfinity) && + (endWidth ?? double.infinity) >= + (breakpoint.endWidth ?? double.infinity) && + (beginHeight ?? double.negativeInfinity) >= + (breakpoint.beginHeight ?? double.negativeInfinity) && + (endHeight ?? double.infinity) >= + (breakpoint.endHeight ?? double.infinity); + } + + // #docregion Breakpoint operators + /// Returns true if this [Breakpoint] is less than or equal to the + /// given [Breakpoint]. + bool operator <=(Breakpoint breakpoint) + // #enddocregion Breakpoint operators + { + return (endWidth ?? double.infinity) <= + (breakpoint.endWidth ?? double.infinity) && + (beginWidth ?? double.negativeInfinity) <= + (breakpoint.beginWidth ?? double.negativeInfinity) && + (endHeight ?? double.infinity) <= + (breakpoint.endHeight ?? double.infinity) && + (beginHeight ?? double.negativeInfinity) <= + (breakpoint.beginHeight ?? double.negativeInfinity); + } + + // #docregion Breakpoint operators + /// Returns true if this [Breakpoint] is between the given [Breakpoint]s. + bool between(Breakpoint lower, Breakpoint upper) + // #enddocregion Breakpoint operators + { + return this >= lower && this < upper; + } } diff --git a/packages/flutter_adaptive_scaffold/lib/src/slot_layout.dart b/packages/flutter_adaptive_scaffold/lib/src/slot_layout.dart index ce3f5a374c41..0bb8ef4dc95a 100644 --- a/packages/flutter_adaptive_scaffold/lib/src/slot_layout.dart +++ b/packages/flutter_adaptive_scaffold/lib/src/slot_layout.dart @@ -15,17 +15,15 @@ class SlotLayout extends StatefulWidget { /// Creates a [SlotLayout] widget. const SlotLayout({required this.config, super.key}); - /// Given a context and a config, it returns the [SlotLayoutConfig] that will g + /// Given a context and a config, it returns the [SlotLayoutConfig] that will /// be chosen from the config under the context's conditions. static SlotLayoutConfig? pickWidget( BuildContext context, Map config) { - SlotLayoutConfig? chosenWidget; - config.forEach((Breakpoint breakpoint, SlotLayoutConfig? pickedWidget) { - if (breakpoint.isActive(context)) { - chosenWidget = pickedWidget; - } - }); - return chosenWidget; + final Breakpoint? breakpoint = + Breakpoint.activeBreakpointIn(context, config.keys.toList()); + return breakpoint != null && config.containsKey(breakpoint) + ? config[breakpoint] + : null; } /// Maps [Breakpoint]s to [SlotLayoutConfig]s to determine what Widget to @@ -74,12 +72,20 @@ class SlotLayout extends StatefulWidget { WidgetBuilder? builder, Widget Function(Widget, Animation)? inAnimation, Widget Function(Widget, Animation)? outAnimation, + Duration? inDuration, + Duration? outDuration, + Curve? inCurve, + Curve? outCurve, required Key key, }) => SlotLayoutConfig._( builder: builder, inAnimation: inAnimation, outAnimation: outAnimation, + inDuration: inDuration, + outDuration: outDuration, + inCurve: inCurve, + outCurve: outCurve, key: key, ); @@ -96,7 +102,11 @@ class _SlotLayoutState extends State chosenWidget = SlotLayout.pickWidget(context, widget.config); bool hasAnimation = false; return AnimatedSwitcher( - duration: const Duration(milliseconds: 1000), + duration: + chosenWidget?.inDuration ?? const Duration(milliseconds: 1000), + reverseDuration: chosenWidget?.outDuration, + switchInCurve: chosenWidget?.inCurve ?? Curves.linear, + switchOutCurve: chosenWidget?.outCurve ?? Curves.linear, layoutBuilder: (Widget? currentChild, List previousChildren) { final Stack elements = Stack( children: [ @@ -137,6 +147,10 @@ class SlotLayoutConfig extends StatelessWidget { required this.builder, this.inAnimation, this.outAnimation, + this.inDuration, + this.outDuration, + this.inCurve, + this.outCurve, }); /// The child Widget that [SlotLayout] eventually returns with an animation. @@ -160,6 +174,22 @@ class SlotLayoutConfig extends StatelessWidget { /// as the returned widget. final Widget Function(Widget, Animation)? outAnimation; + /// The duration of the transition from the old child to the new one during + /// a switch in [SlotLayout]. + final Duration? inDuration; + + /// The duration of the transition from the new child to the old one during + /// a switch in [SlotLayout]. + final Duration? outDuration; + + /// The animation curve to use when transitioning in a new child during a + /// switch in [SlotLayout]. + final Curve? inCurve; + + /// The animation curve to use when transitioning a previous slot out during + /// a switch in [SlotLayout]. + final Curve? outCurve; + /// An empty [SlotLayoutConfig] to be placed in a slot to indicate that the slot /// should show nothing. static SlotLayoutConfig empty() { diff --git a/packages/flutter_adaptive_scaffold/pubspec.yaml b/packages/flutter_adaptive_scaffold/pubspec.yaml index ed61991cf35f..258d9bcc6a7d 100644 --- a/packages/flutter_adaptive_scaffold/pubspec.yaml +++ b/packages/flutter_adaptive_scaffold/pubspec.yaml @@ -1,12 +1,12 @@ name: flutter_adaptive_scaffold description: Widgets to easily build adaptive layouts, including navigation elements. -version: 0.1.11 +version: 0.3.1 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_adaptive_scaffold%22 repository: https://github.com/flutter/packages/tree/main/packages/flutter_adaptive_scaffold environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: @@ -19,3 +19,5 @@ dev_dependencies: topics: - layout - ui + - adaptive + - responsive diff --git a/packages/flutter_adaptive_scaffold/test/adaptive_layout_test.dart b/packages/flutter_adaptive_scaffold/test/adaptive_layout_test.dart index 5924f0a8a749..d2104e3640f0 100644 --- a/packages/flutter_adaptive_scaffold/test/adaptive_layout_test.dart +++ b/packages/flutter_adaptive_scaffold/test/adaptive_layout_test.dart @@ -15,7 +15,7 @@ void main() { MediaQuery slot(double width) { return MediaQuery( data: MediaQueryData.fromView(tester.view) - .copyWith(size: Size(width, 800)), + .copyWith(size: Size(width, 2000)), child: Directionality( textDirection: TextDirection.ltr, child: SlotLayout( @@ -26,6 +26,10 @@ void main() { key: const Key('400'), builder: (_) => const SizedBox()), TestBreakpoint800(): SlotLayout.from( key: const Key('800'), builder: (_) => const SizedBox()), + TestBreakpoint1200(): SlotLayout.from( + key: const Key('1200'), builder: (_) => const SizedBox()), + TestBreakpoint1600(): SlotLayout.from( + key: const Key('1600'), builder: (_) => const SizedBox()), }, ), ), @@ -36,16 +40,36 @@ void main() { expect(find.byKey(const Key('0')), findsOneWidget); expect(find.byKey(const Key('400')), findsNothing); expect(find.byKey(const Key('800')), findsNothing); + expect(find.byKey(const Key('1200')), findsNothing); + expect(find.byKey(const Key('1600')), findsNothing); await tester.pumpWidget(slot(500)); expect(find.byKey(const Key('0')), findsNothing); expect(find.byKey(const Key('400')), findsOneWidget); expect(find.byKey(const Key('800')), findsNothing); + expect(find.byKey(const Key('1200')), findsNothing); + expect(find.byKey(const Key('1600')), findsNothing); await tester.pumpWidget(slot(1000)); expect(find.byKey(const Key('0')), findsNothing); expect(find.byKey(const Key('400')), findsNothing); expect(find.byKey(const Key('800')), findsOneWidget); + expect(find.byKey(const Key('1200')), findsNothing); + expect(find.byKey(const Key('1600')), findsNothing); + + await tester.pumpWidget(slot(1400)); + expect(find.byKey(const Key('0')), findsNothing); + expect(find.byKey(const Key('400')), findsNothing); + expect(find.byKey(const Key('800')), findsNothing); + expect(find.byKey(const Key('1200')), findsOneWidget); + expect(find.byKey(const Key('1600')), findsNothing); + + await tester.pumpWidget(slot(1800)); + expect(find.byKey(const Key('0')), findsNothing); + expect(find.byKey(const Key('400')), findsNothing); + expect(find.byKey(const Key('800')), findsNothing); + expect(find.byKey(const Key('1200')), findsNothing); + expect(find.byKey(const Key('1600')), findsOneWidget); }); testWidgets('adaptive layout displays children in correct places', @@ -55,12 +79,12 @@ void main() { expect(tester.getTopLeft(topNavigation), Offset.zero); expect(tester.getTopLeft(secondaryNavigation), const Offset(390, 10)); expect(tester.getTopLeft(primaryNavigation), const Offset(0, 10)); - expect(tester.getTopLeft(bottomNavigation), const Offset(0, 790)); + expect(tester.getTopLeft(bottomNavigation), const Offset(0, 1990)); expect(tester.getTopLeft(testBreakpoint), const Offset(10, 10)); - expect(tester.getBottomRight(testBreakpoint), const Offset(200, 790)); + expect(tester.getBottomRight(testBreakpoint), const Offset(200, 1990)); expect(tester.getTopLeft(secondaryTestBreakpoint), const Offset(200, 10)); - expect( - tester.getBottomRight(secondaryTestBreakpoint), const Offset(390, 790)); + expect(tester.getBottomRight(secondaryTestBreakpoint), + const Offset(390, 1990)); }); testWidgets('adaptive layout correct layout when body vertical', @@ -71,12 +95,12 @@ void main() { expect(tester.getTopLeft(topNavigation), Offset.zero); expect(tester.getTopLeft(secondaryNavigation), const Offset(390, 10)); expect(tester.getTopLeft(primaryNavigation), const Offset(0, 10)); - expect(tester.getTopLeft(bottomNavigation), const Offset(0, 790)); + expect(tester.getTopLeft(bottomNavigation), const Offset(0, 1990)); expect(tester.getTopLeft(testBreakpoint), const Offset(10, 10)); - expect(tester.getBottomRight(testBreakpoint), const Offset(390, 400)); - expect(tester.getTopLeft(secondaryTestBreakpoint), const Offset(10, 400)); - expect( - tester.getBottomRight(secondaryTestBreakpoint), const Offset(390, 790)); + expect(tester.getBottomRight(testBreakpoint), const Offset(390, 1000)); + expect(tester.getTopLeft(secondaryTestBreakpoint), const Offset(10, 1000)); + expect(tester.getBottomRight(secondaryTestBreakpoint), + const Offset(390, 1990)); }); testWidgets('adaptive layout correct layout when rtl', @@ -87,12 +111,12 @@ void main() { expect(tester.getTopLeft(topNavigation), Offset.zero); expect(tester.getTopLeft(secondaryNavigation), const Offset(0, 10)); expect(tester.getTopLeft(primaryNavigation), const Offset(390, 10)); - expect(tester.getTopLeft(bottomNavigation), const Offset(0, 790)); + expect(tester.getTopLeft(bottomNavigation), const Offset(0, 1990)); expect(tester.getTopLeft(testBreakpoint), const Offset(200, 10)); - expect(tester.getBottomRight(testBreakpoint), const Offset(390, 790)); + expect(tester.getBottomRight(testBreakpoint), const Offset(390, 1990)); expect(tester.getTopLeft(secondaryTestBreakpoint), const Offset(10, 10)); - expect( - tester.getBottomRight(secondaryTestBreakpoint), const Offset(200, 790)); + expect(tester.getBottomRight(secondaryTestBreakpoint), + const Offset(200, 1990)); }); testWidgets('adaptive layout correct layout when body ratio not default', @@ -103,28 +127,34 @@ void main() { expect(tester.getTopLeft(topNavigation), Offset.zero); expect(tester.getTopLeft(secondaryNavigation), const Offset(390, 10)); expect(tester.getTopLeft(primaryNavigation), const Offset(0, 10)); - expect(tester.getTopLeft(bottomNavigation), const Offset(0, 790)); + expect(tester.getTopLeft(bottomNavigation), const Offset(0, 1990)); expect(tester.getTopLeft(testBreakpoint), const Offset(10, 10)); expect(tester.getBottomRight(testBreakpoint), - offsetMoreOrLessEquals(const Offset(136.7, 790), epsilon: 1.0)); + offsetMoreOrLessEquals(const Offset(136.7, 1990), epsilon: 1.0)); expect(tester.getTopLeft(secondaryTestBreakpoint), offsetMoreOrLessEquals(const Offset(136.7, 10), epsilon: 1.0)); - expect( - tester.getBottomRight(secondaryTestBreakpoint), const Offset(390, 790)); + expect(tester.getBottomRight(secondaryTestBreakpoint), + const Offset(390, 1990)); }); final Finder begin = find.byKey(const Key('0')); final Finder end = find.byKey(const Key('400')); + final Finder large = find.byKey(const Key('1200')); + final Finder extraLarge = find.byKey(const Key('1600')); + Finder slideIn(String key) => find.byKey(Key('in-${Key(key)}')); Finder slideOut(String key) => find.byKey(Key('out-${Key(key)}')); + testWidgets( 'slot layout properly switches between items with the appropriate animation', (WidgetTester tester) async { - await tester.pumpWidget(slot(300, tester)); + await tester + .pumpWidget(slot(300, const Duration(milliseconds: 1000), tester)); expect(begin, findsOneWidget); expect(end, findsNothing); - await tester.pumpWidget(slot(500, tester)); + await tester + .pumpWidget(slot(500, const Duration(milliseconds: 1000), tester)); await tester.pump(); await tester.pump(const Duration(milliseconds: 500)); expect(tester.widget(slideOut('0')).position.value, @@ -141,12 +171,50 @@ void main() { await tester.pumpAndSettle(); expect(begin, findsNothing); expect(end, findsOneWidget); + + await tester + .pumpWidget(slot(1300, const Duration(milliseconds: 1000), tester)); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 500)); + expect(tester.widget(slideOut('400')).position.value, + const Offset(-0.5, 0)); + expect(tester.widget(slideIn('1200')).position.value, + const Offset(-0.5, 0)); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 500)); + expect(tester.widget(slideOut('400')).position.value, + const Offset(-1.0, 0)); + expect(tester.widget(slideIn('1200')).position.value, + Offset.zero); + + await tester.pumpAndSettle(); + expect(end, findsNothing); + expect(large, findsOneWidget); + + await tester + .pumpWidget(slot(1700, const Duration(milliseconds: 1000), tester)); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 500)); + expect(tester.widget(slideOut('1200')).position.value, + const Offset(-0.5, 0)); + expect(tester.widget(slideIn('1600')).position.value, + const Offset(-0.5, 0)); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 500)); + expect(tester.widget(slideOut('1200')).position.value, + const Offset(-1.0, 0)); + expect(tester.widget(slideIn('1600')).position.value, + Offset.zero); + + await tester.pumpAndSettle(); + expect(large, findsNothing); + expect(extraLarge, findsOneWidget); }); testWidgets('AnimatedSwitcher does not spawn duplicate keys on rapid resize', (WidgetTester tester) async { // Populate the smaller slot layout and let the animation settle. - await tester.pumpWidget(slot(300, tester)); + await tester.pumpWidget(slot(300, const Duration(seconds: 1), tester)); await tester.pumpAndSettle(); expect(begin, findsOneWidget); expect(end, findsNothing); @@ -157,12 +225,12 @@ void main() { for (int i = 0; i < 2; i++) { // Resize between the two slot layouts, but do not pump the animation // until completion. - await tester.pumpWidget(slot(500, tester)); + await tester.pumpWidget(slot(500, const Duration(seconds: 1), tester)); await tester.pump(const Duration(milliseconds: 100)); expect(begin, findsOneWidget); expect(end, findsOneWidget); - await tester.pumpWidget(slot(300, tester)); + await tester.pumpWidget(slot(300, const Duration(seconds: 1), tester)); await tester.pump(const Duration(milliseconds: 100)); expect(begin, findsOneWidget); expect(end, findsOneWidget); @@ -171,18 +239,18 @@ void main() { testWidgets('slot layout can tolerate rapid changes in breakpoints', (WidgetTester tester) async { - await tester.pumpWidget(slot(300, tester)); + await tester.pumpWidget(slot(300, const Duration(seconds: 1), tester)); expect(begin, findsOneWidget); expect(end, findsNothing); - await tester.pumpWidget(slot(500, tester)); + await tester.pumpWidget(slot(500, const Duration(seconds: 1), tester)); await tester.pump(); await tester.pump(const Duration(milliseconds: 100)); expect(tester.widget(slideOut('0')).position.value, offsetMoreOrLessEquals(const Offset(-0.1, 0), epsilon: 0.05)); expect(tester.widget(slideIn('400')).position.value, offsetMoreOrLessEquals(const Offset(-0.9, 0), epsilon: 0.05)); - await tester.pumpWidget(slot(300, tester)); + await tester.pumpWidget(slot(300, const Duration(seconds: 1), tester)); await tester.pumpAndSettle(); expect(begin, findsOneWidget); expect(end, findsNothing); @@ -205,49 +273,73 @@ void main() { expect(tester.getTopLeft(testBreakpoint), const Offset(1, 1)); expect(tester.getBottomRight(testBreakpoint), - offsetMoreOrLessEquals(const Offset(395.8, 799), epsilon: 1.0)); + offsetMoreOrLessEquals(const Offset(395.8, 1999), epsilon: 1.0)); expect(tester.getTopLeft(secondaryTestBreakpoint), offsetMoreOrLessEquals(const Offset(395.8, 1.0), epsilon: 1.0)); expect(tester.getBottomRight(secondaryTestBreakpoint), - offsetMoreOrLessEquals(const Offset(594.8, 799.0), epsilon: 1.0)); + offsetMoreOrLessEquals(const Offset(594.8, 1999.0), epsilon: 1.0)); await tester.pump(); await tester.pump(const Duration(milliseconds: 400)); expect(tester.getTopLeft(testBreakpoint), const Offset(5, 5)); expect(tester.getBottomRight(testBreakpoint), - offsetMoreOrLessEquals(const Offset(294.2, 795), epsilon: 1.0)); + offsetMoreOrLessEquals(const Offset(294.2, 1995), epsilon: 1.0)); expect(tester.getTopLeft(secondaryTestBreakpoint), offsetMoreOrLessEquals(const Offset(294.2, 5.0), epsilon: 1.0)); expect(tester.getBottomRight(secondaryTestBreakpoint), - offsetMoreOrLessEquals(const Offset(489.2, 795.0), epsilon: 1.0)); + offsetMoreOrLessEquals(const Offset(489.2, 1995.0), epsilon: 1.0)); await tester.pump(); await tester.pump(const Duration(milliseconds: 400)); expect(tester.getTopLeft(testBreakpoint), const Offset(9, 9)); expect(tester.getBottomRight(testBreakpoint), - offsetMoreOrLessEquals(const Offset(201.7, 791), epsilon: 1.0)); + offsetMoreOrLessEquals(const Offset(201.7, 1991), epsilon: 1.0)); expect(tester.getTopLeft(secondaryTestBreakpoint), offsetMoreOrLessEquals(const Offset(201.7, 9.0), epsilon: 1.0)); expect(tester.getBottomRight(secondaryTestBreakpoint), - offsetMoreOrLessEquals(const Offset(392.7, 791), epsilon: 1.0)); + offsetMoreOrLessEquals(const Offset(392.7, 1991), epsilon: 1.0)); await tester.pump(); await tester.pump(const Duration(milliseconds: 100)); expect(tester.getTopLeft(testBreakpoint), const Offset(10, 10)); - expect(tester.getBottomRight(testBreakpoint), const Offset(200, 790)); + expect(tester.getBottomRight(testBreakpoint), const Offset(200, 1990)); expect(tester.getTopLeft(secondaryTestBreakpoint), const Offset(200, 10)); - expect( - tester.getBottomRight(secondaryTestBreakpoint), const Offset(390, 790)); + expect(tester.getBottomRight(secondaryTestBreakpoint), + const Offset(390, 1990)); + }); + + testWidgets('adaptive layout can adjust animation duration', + (WidgetTester tester) async { + // Populate the smaller slot layout and let the animation settle. + await tester + .pumpWidget(slot(300, const Duration(milliseconds: 100), tester)); + await tester.pumpAndSettle(); + expect(begin, findsOneWidget); + expect(end, findsNothing); + + // expand in 1/5 second. + await tester + .pumpWidget(slot(500, const Duration(milliseconds: 200), tester)); + + // after 100ms, we expect both widgets to be present. + await tester.pump(const Duration(milliseconds: 50)); + expect(begin, findsOneWidget); + expect(end, findsOneWidget); + + // After 1/5 second, all animations should be done. + await tester.pump(const Duration(milliseconds: 200)); + expect(begin, findsNothing); + expect(end, findsOneWidget); + + await tester.pumpAndSettle(); }); testWidgets('adaptive layout does not animate when animations off', (WidgetTester tester) async { final Finder testBreakpoint = find.byKey(const Key('Test Breakpoint')); - final Finder secondaryTestBreakpoint = - find.byKey(const Key('Secondary Test Breakpoint')); await tester.pumpWidget( await layout(width: 400, tester: tester, animations: false)); @@ -256,31 +348,130 @@ void main() { await tester.pump(const Duration(milliseconds: 100)); expect(tester.getTopLeft(testBreakpoint), const Offset(10, 10)); - expect(tester.getBottomRight(testBreakpoint), const Offset(200, 790)); - expect(tester.getTopLeft(secondaryTestBreakpoint), const Offset(200, 10)); - expect( - tester.getBottomRight(secondaryTestBreakpoint), const Offset(390, 790)); + expect(tester.getBottomRight(testBreakpoint), const Offset(200, 1990)); + + await tester.pumpWidget( + await layout(width: 800, tester: tester, animations: false)); + + await tester.pump(); + await tester.pump(const Duration(milliseconds: 100)); + + expect(tester.getTopLeft(testBreakpoint400), const Offset(10, 10)); + expect(tester.getBottomRight(testBreakpoint400), const Offset(400, 1990)); + + await tester.pumpWidget( + await layout(width: 1000, tester: tester, animations: false)); + + await tester.pump(); + await tester.pump(const Duration(milliseconds: 100)); + + expect(tester.getTopLeft(testBreakpoint800), const Offset(10, 10)); + expect(tester.getBottomRight(testBreakpoint800), const Offset(500, 1990)); + + await tester.pumpWidget( + await layout(width: 1300, tester: tester, animations: false)); + + await tester.pump(); + await tester.pump(const Duration(milliseconds: 100)); + + expect(tester.getTopLeft(testBreakpoint1200), const Offset(10, 10)); + expect(tester.getBottomRight(testBreakpoint1200), const Offset(650, 1990)); + + await tester.pumpWidget( + await layout(width: 1700, tester: tester, animations: false)); + + await tester.pump(); + await tester.pump(const Duration(milliseconds: 100)); + + expect(tester.getTopLeft(testBreakpoint1600), const Offset(10, 10)); + expect(tester.getBottomRight(testBreakpoint1600), const Offset(850, 1990)); + }); + + testWidgets( + 'adaptive layout handles internal animations correctly for additional breakpoints', + (WidgetTester tester) async { + await tester.pumpWidget(await layout(width: 800, tester: tester)); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 100)); + + expect(tester.getTopLeft(testBreakpoint400), const Offset(1, 1)); + expect(tester.getBottomRight(testBreakpoint400), + offsetMoreOrLessEquals(const Offset(792.6, 1999), epsilon: 1.0)); + expect(tester.getTopLeft(secondaryTestBreakpoint400), + offsetMoreOrLessEquals(const Offset(792.6, 1.0), epsilon: 1.0)); + expect(tester.getBottomRight(secondaryTestBreakpoint400), + offsetMoreOrLessEquals(const Offset(1191.6, 1999.0), epsilon: 1.0)); + + await tester.pumpWidget(await layout(width: 1000, tester: tester)); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 400)); + + expect(tester.getTopLeft(testBreakpoint800), const Offset(10, 10)); + expect(tester.getBottomRight(testBreakpoint800), + offsetMoreOrLessEquals(const Offset(855.3, 1990.0), epsilon: 1.0)); + expect(tester.getTopLeft(secondaryTestBreakpoint800), + offsetMoreOrLessEquals(const Offset(855.3, 10.0), epsilon: 1.0)); + expect(tester.getBottomRight(secondaryTestBreakpoint800), + offsetMoreOrLessEquals(const Offset(1345.3, 1990.0), epsilon: 1.0)); + + await tester.pumpWidget(await layout(width: 1300, tester: tester)); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 400)); + + expect(tester.getTopLeft(testBreakpoint1200), const Offset(10, 10)); + expect(tester.getBottomRight(testBreakpoint1200), + offsetMoreOrLessEquals(const Offset(1114.0, 1990.0), epsilon: 1.0)); + expect(tester.getTopLeft(secondaryTestBreakpoint1200), + offsetMoreOrLessEquals(const Offset(1114.0, 10.0), epsilon: 1.0)); + expect(tester.getBottomRight(secondaryTestBreakpoint1200), + offsetMoreOrLessEquals(const Offset(1754.0, 1990.0), epsilon: 1.0)); + + await tester.pumpWidget(await layout(width: 1700, tester: tester)); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 400)); + + expect(tester.getTopLeft(testBreakpoint1600), const Offset(10, 10)); + expect(tester.getBottomRight(testBreakpoint1600), + offsetMoreOrLessEquals(const Offset(1459.1, 1990.0), epsilon: 1.0)); + expect(tester.getTopLeft(secondaryTestBreakpoint1600), + offsetMoreOrLessEquals(const Offset(1459.1, 10.0), epsilon: 1.0)); + expect(tester.getBottomRight(secondaryTestBreakpoint1600), + offsetMoreOrLessEquals(const Offset(2299.1, 1990.0), epsilon: 1.0)); }); } class TestBreakpoint0 extends Breakpoint { @override bool isActive(BuildContext context) { - return MediaQuery.of(context).size.width >= 0; + return MediaQuery.sizeOf(context).width >= 0; } } class TestBreakpoint400 extends Breakpoint { @override bool isActive(BuildContext context) { - return MediaQuery.of(context).size.width > 400; + return MediaQuery.sizeOf(context).width > 400; } } class TestBreakpoint800 extends Breakpoint { @override bool isActive(BuildContext context) { - return MediaQuery.of(context).size.width > 800; + return MediaQuery.sizeOf(context).width > 800; + } +} + +class TestBreakpoint1200 extends Breakpoint { + @override + bool isActive(BuildContext context) { + return MediaQuery.sizeOf(context).width > 1200; + } +} + +class TestBreakpoint1600 extends Breakpoint { + @override + bool isActive(BuildContext context) { + return MediaQuery.sizeOf(context).width > 1600; } } @@ -292,8 +483,21 @@ final Finder primaryNavigation = final Finder bottomNavigation = find.byKey(const Key('Bottom Navigation Small')); final Finder testBreakpoint = find.byKey(const Key('Test Breakpoint')); +final Finder testBreakpoint400 = find.byKey(const Key('Test Breakpoint 400')); +final Finder testBreakpoint800 = find.byKey(const Key('Test Breakpoint 800')); +final Finder testBreakpoint1200 = find.byKey(const Key('Test Breakpoint 1200')); +final Finder testBreakpoint1600 = find.byKey(const Key('Test Breakpoint 1600')); + final Finder secondaryTestBreakpoint = find.byKey(const Key('Secondary Test Breakpoint')); +final Finder secondaryTestBreakpoint400 = + find.byKey(const Key('Secondary Test Breakpoint 400')); +final Finder secondaryTestBreakpoint800 = + find.byKey(const Key('Secondary Test Breakpoint 800')); +final Finder secondaryTestBreakpoint1200 = + find.byKey(const Key('Secondary Test Breakpoint 1200')); +final Finder secondaryTestBreakpoint1600 = + find.byKey(const Key('Secondary Test Breakpoint 1600')); Widget on(BuildContext _) { return const SizedBox(width: 10, height: 10); @@ -306,10 +510,11 @@ Future layout({ TextDirection directionality = TextDirection.ltr, double? bodyRatio, bool animations = true, + int durationMs = 1000, }) async { - await tester.binding.setSurfaceSize(Size(width, 800)); + await tester.binding.setSurfaceSize(Size(width, 2000)); return MediaQuery( - data: MediaQueryData(size: Size(width, 800)), + data: MediaQueryData(size: Size(width, 2000)), child: Directionality( textDirection: directionality, child: AdaptiveLayout( @@ -323,7 +528,11 @@ Future layout({ TestBreakpoint400(): SlotLayout.from( key: const Key('Primary Navigation Medium'), builder: on), TestBreakpoint800(): SlotLayout.from( + key: const Key('Primary Navigation MediumLarge'), builder: on), + TestBreakpoint1200(): SlotLayout.from( key: const Key('Primary Navigation Large'), builder: on), + TestBreakpoint1600(): SlotLayout.from( + key: const Key('Primary Navigation ExtraLarge'), builder: on), }, ), secondaryNavigation: SlotLayout( @@ -333,7 +542,12 @@ Future layout({ TestBreakpoint400(): SlotLayout.from( key: const Key('Secondary Navigation Medium'), builder: on), TestBreakpoint800(): SlotLayout.from( + key: const Key('Secondary Navigation MediumLarge'), + builder: on), + TestBreakpoint1200(): SlotLayout.from( key: const Key('Secondary Navigation Large'), builder: on), + TestBreakpoint1600(): SlotLayout.from( + key: const Key('Secondary Navigation ExtraLarge'), builder: on), }, ), topNavigation: SlotLayout( @@ -344,6 +558,10 @@ Future layout({ SlotLayout.from(key: const Key('Top Navigation1'), builder: on), TestBreakpoint800(): SlotLayout.from(key: const Key('Top Navigation2'), builder: on), + TestBreakpoint1200(): + SlotLayout.from(key: const Key('Top Navigation3'), builder: on), + TestBreakpoint1600(): + SlotLayout.from(key: const Key('Top Navigation4'), builder: on), }, ), bottomNavigation: SlotLayout( @@ -354,6 +572,10 @@ Future layout({ SlotLayout.from(key: const Key('bnav1'), builder: on), TestBreakpoint800(): SlotLayout.from(key: const Key('bnav2'), builder: on), + TestBreakpoint1200(): + SlotLayout.from(key: const Key('bnav3'), builder: on), + TestBreakpoint1600(): + SlotLayout.from(key: const Key('bnav4'), builder: on), }, ), body: SlotLayout( @@ -363,11 +585,19 @@ Future layout({ builder: (_) => Container(color: Colors.red), ), TestBreakpoint400(): SlotLayout.from( - key: const Key('Test Breakpoint 1'), + key: const Key('Test Breakpoint 400'), builder: (_) => Container(color: Colors.red), ), TestBreakpoint800(): SlotLayout.from( - key: const Key('Test Breakpoint 2'), + key: const Key('Test Breakpoint 800'), + builder: (_) => Container(color: Colors.red), + ), + TestBreakpoint1200(): SlotLayout.from( + key: const Key('Test Breakpoint 1200'), + builder: (_) => Container(color: Colors.red), + ), + TestBreakpoint1600(): SlotLayout.from( + key: const Key('Test Breakpoint 1600'), builder: (_) => Container(color: Colors.red), ), }, @@ -379,11 +609,19 @@ Future layout({ builder: (_) => Container(color: Colors.blue), ), TestBreakpoint400(): SlotLayout.from( - key: const Key('Secondary Test Breakpoint 1'), + key: const Key('Secondary Test Breakpoint 400'), builder: (_) => Container(color: Colors.blue), ), TestBreakpoint800(): SlotLayout.from( - key: const Key('Secondary Test Breakpoint 2'), + key: const Key('Secondary Test Breakpoint 800'), + builder: (_) => Container(color: Colors.blue), + ), + TestBreakpoint1200(): SlotLayout.from( + key: const Key('Secondary Test Breakpoint 1200'), + builder: (_) => Container(color: Colors.blue), + ), + TestBreakpoint1600(): SlotLayout.from( + key: const Key('Secondary Test Breakpoint 1600'), builder: (_) => Container(color: Colors.blue), ), }, @@ -415,9 +653,10 @@ AnimatedWidget leftInOut(Widget child, Animation animation) { ); } -MediaQuery slot(double width, WidgetTester tester) { +MediaQuery slot(double width, Duration duration, WidgetTester tester) { return MediaQuery( - data: MediaQueryData.fromView(tester.view).copyWith(size: Size(width, 800)), + data: + MediaQueryData.fromView(tester.view).copyWith(size: Size(width, 2000)), child: Directionality( textDirection: TextDirection.ltr, child: SlotLayout( @@ -425,15 +664,38 @@ MediaQuery slot(double width, WidgetTester tester) { TestBreakpoint0(): SlotLayout.from( inAnimation: leftOutIn, outAnimation: leftInOut, + inDuration: duration, key: const Key('0'), builder: (_) => const SizedBox(width: 10, height: 10), ), TestBreakpoint400(): SlotLayout.from( inAnimation: leftOutIn, outAnimation: leftInOut, + inDuration: duration, key: const Key('400'), builder: (_) => const SizedBox(width: 10, height: 10), ), + TestBreakpoint800(): SlotLayout.from( + inAnimation: leftOutIn, + outAnimation: leftInOut, + inDuration: duration, + key: const Key('800'), + builder: (_) => const SizedBox(width: 10, height: 10), + ), + TestBreakpoint1200(): SlotLayout.from( + inAnimation: leftOutIn, + outAnimation: leftInOut, + inDuration: duration, + key: const Key('1200'), + builder: (_) => const SizedBox(width: 10, height: 10), + ), + TestBreakpoint1600(): SlotLayout.from( + inAnimation: leftOutIn, + outAnimation: leftInOut, + inDuration: duration, + key: const Key('1600'), + builder: (_) => const SizedBox(width: 10, height: 10), + ), }, ), ), diff --git a/packages/flutter_adaptive_scaffold/test/adaptive_scaffold_test.dart b/packages/flutter_adaptive_scaffold/test/adaptive_scaffold_test.dart index 8dcaf2d5a0a4..b7864392d690 100644 --- a/packages/flutter_adaptive_scaffold/test/adaptive_scaffold_test.dart +++ b/packages/flutter_adaptive_scaffold/test/adaptive_scaffold_test.dart @@ -14,16 +14,24 @@ void main() { (WidgetTester tester) async { final Finder smallBody = find.byKey(const Key('smallBody')); final Finder body = find.byKey(const Key('body')); + final Finder mediumLargeBody = find.byKey(const Key('mediumLargeBody')); final Finder largeBody = find.byKey(const Key('largeBody')); + final Finder extraLargeBody = find.byKey(const Key('extraLargeBody')); + final Finder smallSBody = find.byKey(const Key('smallSBody')); final Finder sBody = find.byKey(const Key('sBody')); + final Finder mediumLargeSBody = find.byKey(const Key('mediumLargeSBody')); final Finder largeSBody = find.byKey(const Key('largeSBody')); + final Finder extraLargeSBody = find.byKey(const Key('extraLargeSBody')); + final Finder bottomNav = find.byKey(const Key('bottomNavigation')); final Finder primaryNav = find.byKey(const Key('primaryNavigation')); final Finder primaryNav1 = find.byKey(const Key('primaryNavigation1')); + final Finder primaryNav2 = find.byKey(const Key('primaryNavigation2')); + final Finder primaryNav3 = find.byKey(const Key('primaryNavigation3')); await tester.binding.setSurfaceSize(SimulatedLayout.small.size); - await tester.pumpWidget(SimulatedLayout.small.app()); + await tester.pumpWidget(SimulatedLayout.small.scaffold(tester)); await tester.pumpAndSettle(); expect(smallBody, findsOneWidget); @@ -33,10 +41,10 @@ void main() { expect(tester.getTopLeft(smallBody), Offset.zero); expect(tester.getTopLeft(smallSBody), const Offset(200, 0)); - expect(tester.getTopLeft(bottomNav), const Offset(0, 720)); + expect(tester.getTopLeft(bottomNav), const Offset(0, 1920)); await tester.binding.setSurfaceSize(SimulatedLayout.medium.size); - await tester.pumpWidget(SimulatedLayout.medium.app()); + await tester.pumpWidget(SimulatedLayout.medium.scaffold(tester)); await tester.pumpAndSettle(); expect(smallBody, findsNothing); @@ -49,23 +57,55 @@ void main() { expect(tester.getTopLeft(body), const Offset(88, 0)); expect(tester.getTopLeft(sBody), const Offset(400, 0)); expect(tester.getTopLeft(primaryNav), Offset.zero); - expect(tester.getBottomRight(primaryNav), const Offset(88, 800)); + expect(tester.getBottomRight(primaryNav), const Offset(88, 2000)); - await tester.binding.setSurfaceSize(SimulatedLayout.large.size); - await tester.pumpWidget(SimulatedLayout.large.app()); + await tester.binding.setSurfaceSize(SimulatedLayout.mediumLarge.size); + await tester.pumpWidget(SimulatedLayout.mediumLarge.scaffold(tester)); await tester.pumpAndSettle(); expect(body, findsNothing); - expect(largeBody, findsOneWidget); + expect(mediumLargeBody, findsOneWidget); expect(sBody, findsNothing); - expect(largeSBody, findsOneWidget); + expect(mediumLargeSBody, findsOneWidget); expect(primaryNav, findsNothing); expect(primaryNav1, findsOneWidget); - expect(tester.getTopLeft(largeBody), const Offset(208, 0)); - expect(tester.getTopLeft(largeSBody), const Offset(550, 0)); + expect(tester.getTopLeft(mediumLargeBody), const Offset(208, 0)); + expect(tester.getTopLeft(mediumLargeSBody), const Offset(500, 0)); expect(tester.getTopLeft(primaryNav1), Offset.zero); - expect(tester.getBottomRight(primaryNav1), const Offset(208, 800)); + expect(tester.getBottomRight(primaryNav1), const Offset(208, 2000)); + + await tester.binding.setSurfaceSize(SimulatedLayout.large.size); + await tester.pumpWidget(SimulatedLayout.large.scaffold(tester)); + await tester.pumpAndSettle(); + + expect(mediumLargeBody, findsNothing); + expect(largeBody, findsOneWidget); + expect(mediumLargeSBody, findsNothing); + expect(largeSBody, findsOneWidget); + expect(primaryNav1, findsNothing); + expect(primaryNav2, findsOneWidget); + + expect(tester.getTopLeft(largeBody), const Offset(208, 0)); + expect(tester.getTopLeft(largeSBody), const Offset(600, 0)); + expect(tester.getTopLeft(primaryNav2), Offset.zero); + expect(tester.getBottomRight(primaryNav2), const Offset(208, 2000)); + + await tester.binding.setSurfaceSize(SimulatedLayout.extraLarge.size); + await tester.pumpWidget(SimulatedLayout.extraLarge.scaffold(tester)); + await tester.pumpAndSettle(); + + expect(largeBody, findsNothing); + expect(extraLargeBody, findsOneWidget); + expect(largeSBody, findsNothing); + expect(extraLargeSBody, findsOneWidget); + expect(primaryNav2, findsNothing); + expect(primaryNav3, findsOneWidget); + + expect(tester.getTopLeft(extraLargeBody), const Offset(208, 0)); + expect(tester.getTopLeft(extraLargeSBody), const Offset(800, 0)); + expect(tester.getTopLeft(primaryNav3), Offset.zero); + expect(tester.getBottomRight(primaryNav3), const Offset(208, 2000)); }); testWidgets('adaptive scaffold animations work correctly', @@ -74,39 +114,39 @@ void main() { final Finder sBody = find.byKey(const Key('sBody')); await tester.binding.setSurfaceSize(SimulatedLayout.small.size); - await tester.pumpWidget(SimulatedLayout.small.app()); + await tester.pumpWidget(SimulatedLayout.small.scaffold(tester)); await tester.binding.setSurfaceSize(SimulatedLayout.medium.size); - await tester.pumpWidget(SimulatedLayout.medium.app()); + await tester.pumpWidget(SimulatedLayout.medium.scaffold(tester)); await tester.pump(); await tester.pump(const Duration(milliseconds: 200)); expect(tester.getTopLeft(b), const Offset(17.6, 0)); expect(tester.getBottomRight(b), - offsetMoreOrLessEquals(const Offset(778.2, 736), epsilon: 1.0)); + offsetMoreOrLessEquals(const Offset(778.2, 1936), epsilon: 1.0)); expect(tester.getTopLeft(sBody), offsetMoreOrLessEquals(const Offset(778.2, 0), epsilon: 1.0)); expect(tester.getBottomRight(sBody), - offsetMoreOrLessEquals(const Offset(1178.2, 736), epsilon: 1.0)); + offsetMoreOrLessEquals(const Offset(1178.2, 1936), epsilon: 1.0)); await tester.pump(); await tester.pump(const Duration(milliseconds: 600)); expect(tester.getTopLeft(b), const Offset(70.4, 0)); expect(tester.getBottomRight(b), - offsetMoreOrLessEquals(const Offset(416.0, 784), epsilon: 1.0)); + offsetMoreOrLessEquals(const Offset(416.0, 1984), epsilon: 1.0)); expect(tester.getTopLeft(sBody), offsetMoreOrLessEquals(const Offset(416, 0), epsilon: 1.0)); expect(tester.getBottomRight(sBody), - offsetMoreOrLessEquals(const Offset(816, 784), epsilon: 1.0)); + offsetMoreOrLessEquals(const Offset(816, 1984), epsilon: 1.0)); await tester.pump(); await tester.pump(const Duration(milliseconds: 200)); expect(tester.getTopLeft(b), const Offset(88.0, 0)); - expect(tester.getBottomRight(b), const Offset(400, 800)); + expect(tester.getBottomRight(b), const Offset(400, 2000)); expect(tester.getTopLeft(sBody), const Offset(400, 0)); - expect(tester.getBottomRight(sBody), const Offset(800, 800)); + expect(tester.getBottomRight(sBody), const Offset(800, 2000)); }); testWidgets('adaptive scaffold animations can be disabled', @@ -115,18 +155,20 @@ void main() { final Finder sBody = find.byKey(const Key('sBody')); await tester.binding.setSurfaceSize(SimulatedLayout.small.size); - await tester.pumpWidget(SimulatedLayout.small.app(animations: false)); + await tester + .pumpWidget(SimulatedLayout.small.scaffold(tester, animations: false)); await tester.binding.setSurfaceSize(SimulatedLayout.medium.size); - await tester.pumpWidget(SimulatedLayout.medium.app(animations: false)); + await tester + .pumpWidget(SimulatedLayout.medium.scaffold(tester, animations: false)); await tester.pump(); await tester.pump(const Duration(milliseconds: 200)); expect(tester.getTopLeft(b), const Offset(88.0, 0)); - expect(tester.getBottomRight(b), const Offset(400, 800)); + expect(tester.getBottomRight(b), const Offset(400, 2000)); expect(tester.getTopLeft(sBody), const Offset(400, 0)); - expect(tester.getBottomRight(sBody), const Offset(800, 800)); + expect(tester.getBottomRight(sBody), const Offset(800, 2000)); }); // The goal of this test is to run through each of the navigation elements @@ -139,7 +181,8 @@ void main() { await Future.forEach(SimulatedLayout.values, (SimulatedLayout region) async { int selectedIndex = 0; - final MaterialApp app = region.app(initialIndex: selectedIndex); + final MaterialApp app = + region.scaffold(tester, initialIndex: selectedIndex); await tester.binding.setSurfaceSize(region.size); await tester.pumpWidget(app); await tester.pumpAndSettle(); @@ -202,12 +245,12 @@ void main() { (WidgetTester tester) async { await Future.forEach(SimulatedLayout.values, (SimulatedLayout region) async { - final MaterialApp app = region.app(); + final MaterialApp app = region.scaffold(tester); await tester.binding.setSurfaceSize(region.size); await tester.pumpWidget(app); await tester.pumpAndSettle(); - if (region.size == SimulatedLayout.large.size) { + if (region.size == SimulatedLayout.mediumLarge.size) { expect(find.text('leading_extended'), findsOneWidget); expect(find.text('leading_unextended'), findsNothing); expect(find.text('trailing'), findsOneWidget); @@ -232,7 +275,8 @@ void main() { await Future.forEach(SimulatedLayout.values, (SimulatedLayout region) async { int? selectedIndex; - final MaterialApp app = region.app(initialIndex: selectedIndex); + final MaterialApp app = + region.scaffold(tester, initialIndex: selectedIndex); await tester.binding.setSurfaceSize(region.size); await tester.pumpWidget(app); await tester.pumpAndSettle(); @@ -413,7 +457,7 @@ void main() { 'when view in medium screen, navigation rail must be visible as per theme data values.', (WidgetTester tester) async { await tester.binding.setSurfaceSize(SimulatedLayout.medium.size); - await tester.pumpWidget(SimulatedLayout.medium.app()); + await tester.pumpWidget(SimulatedLayout.medium.scaffold(tester)); await tester.pumpAndSettle(); final Finder primaryNavigationMedium = find.byKey( @@ -456,19 +500,19 @@ void main() { ); testWidgets( - 'when view in large screen, navigation rail must be visible as per theme data values.', + 'when view in mediumLarge screen, navigation rail must be visible as per theme data values.', (WidgetTester tester) async { - await tester.binding.setSurfaceSize(SimulatedLayout.large.size); - await tester.pumpWidget(SimulatedLayout.large.app()); + await tester.binding.setSurfaceSize(SimulatedLayout.mediumLarge.size); + await tester.pumpWidget(SimulatedLayout.mediumLarge.scaffold(tester)); await tester.pumpAndSettle(); - final Finder primaryNavigationLarge = find.byKey( + final Finder primaryNavigationMediumLarge = find.byKey( const Key('primaryNavigation1'), ); - expect(primaryNavigationLarge, findsOneWidget); + expect(primaryNavigationMediumLarge, findsOneWidget); final Finder navigationRailFinder = find.descendant( - of: primaryNavigationLarge, + of: primaryNavigationMediumLarge, matching: find.byType(NavigationRail), ); expect(navigationRailFinder, findsOneWidget); @@ -618,45 +662,45 @@ void main() { // creates a NavigationRail widget as expected with groupAlignment provided, // and checks whether the NavigationRail's groupAlignment matches the expected value. testWidgets( - 'groupAligment parameter of AdaptiveScaffold.standardNavigationRail works correctly', - (WidgetTester tester) async { - const List destinations = - [ - NavigationRailDestination( - icon: Icon(Icons.home), - label: Text('Home'), - ), - NavigationRailDestination( - icon: Icon(Icons.account_circle), - label: Text('Profile'), - ), - NavigationRailDestination( - icon: Icon(Icons.settings), - label: Text('Settings'), - ), - ]; + 'groupAligment parameter of AdaptiveScaffold.standardNavigationRail works correctly', + (WidgetTester tester) async { + const List destinations = + [ + NavigationRailDestination( + icon: Icon(Icons.home), + label: Text('Home'), + ), + NavigationRailDestination( + icon: Icon(Icons.account_circle), + label: Text('Profile'), + ), + NavigationRailDestination( + icon: Icon(Icons.settings), + label: Text('Settings'), + ), + ]; - // Align to bottom. - const double groupAlignment = 1.0; + const double groupAlignment = 1.0; - await tester.pumpWidget( - MaterialApp( - home: Scaffold( - body: Builder( - builder: (BuildContext context) { - return AdaptiveScaffold.standardNavigationRail( - destinations: destinations, - groupAlignment: groupAlignment, - ); - }, + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: Builder( + builder: (BuildContext context) { + return AdaptiveScaffold.standardNavigationRail( + destinations: destinations, + groupAlignment: groupAlignment, + ); + }, + ), ), ), - ), - ); - final NavigationRail rail = - tester.widget(find.byType(NavigationRail)); - expect(rail.groupAlignment, equals(groupAlignment)); - }); + ); + final NavigationRail rail = + tester.widget(find.byType(NavigationRail)); + expect(rail.groupAlignment, equals(groupAlignment)); + }, + ); testWidgets( "doesn't override Directionality", @@ -700,7 +744,7 @@ void main() { (WidgetTester tester) async { await tester.binding.setSurfaceSize(SimulatedLayout.medium.size); await tester.pumpWidget(SimulatedLayout.medium - .app(appBarBreakpoint: AppBarAlwaysOnBreakpoint())); + .scaffold(tester, appBarBreakpoint: AppBarAlwaysOnBreakpoint())); await tester.pumpAndSettle(); final Finder appBar = find.byType(AppBar); @@ -708,9 +752,9 @@ void main() { expect(appBar, findsOneWidget); expect(drawer, findsNothing); - await tester.binding.setSurfaceSize(SimulatedLayout.large.size); - await tester.pumpWidget(SimulatedLayout.large - .app(appBarBreakpoint: AppBarAlwaysOnBreakpoint())); + await tester.binding.setSurfaceSize(SimulatedLayout.mediumLarge.size); + await tester.pumpWidget(SimulatedLayout.mediumLarge + .scaffold(tester, appBarBreakpoint: AppBarAlwaysOnBreakpoint())); expect(drawer, findsNothing); await tester.pumpAndSettle(); @@ -744,6 +788,81 @@ void main() { ); }, ); + + // Test for navigationRailDestinationBuilder parameter. + testWidgets('adaptive scaffold custom navigation rail destination mapping', + (WidgetTester tester) async { + const List destinations = [ + NavigationDestination( + icon: Icon(Icons.home), + label: 'Home', + ), + NavigationDestination( + icon: Icon(Icons.account_circle), + label: 'Profile', + ), + ]; + + NavigationRailDestination customMapping( + int index, NavigationDestination destination) { + return NavigationRailDestination( + icon: destination.icon, + label: Text('Custom ${destination.label}'), + ); + } + + await tester.pumpWidget( + MaterialApp( + home: MediaQuery( + data: const MediaQueryData(size: Size(800, 600)), + child: AdaptiveScaffold( + destinations: destinations, + navigationRailDestinationBuilder: customMapping, + ), + ), + ), + ); + + expect(find.text('Custom Home'), findsOneWidget); + expect(find.text('Custom Profile'), findsOneWidget); + }); + + // Test for labelType setting through the navigation rail theme. + testWidgets( + 'adaptive scaffold respects NavigationRailLabelType from theme', + (WidgetTester tester) async { + const List destinations = [ + NavigationDestination( + icon: Icon(Icons.home), + label: 'Home', + ), + NavigationDestination( + icon: Icon(Icons.account_circle), + label: 'Profile', + ), + ]; + + await tester.pumpWidget( + MaterialApp( + theme: ThemeData( + navigationRailTheme: const NavigationRailThemeData( + labelType: NavigationRailLabelType.all, + ), + ), + home: MediaQuery( + data: const MediaQueryData(size: Size(800, 600)), + child: AdaptiveScaffold( + destinations: destinations, + ), + ), + ), + ); + + final NavigationRail rail = + tester.widget(find.byType(NavigationRail)); + expect(rail.labelType, NavigationRailLabelType.all); + }, + ); } /// An empty widget that implements [PreferredSizeWidget] to ensure that diff --git a/packages/flutter_adaptive_scaffold/test/breakpoint_test.dart b/packages/flutter_adaptive_scaffold/test/breakpoint_test.dart index c0975092db64..978582a32075 100644 --- a/packages/flutter_adaptive_scaffold/test/breakpoint_test.dart +++ b/packages/flutter_adaptive_scaffold/test/breakpoint_test.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; -import 'package:flutter_adaptive_scaffold/src/breakpoints.dart'; +import 'package:flutter_adaptive_scaffold/flutter_adaptive_scaffold.dart'; import 'package:flutter_test/flutter_test.dart'; import 'simulated_layout.dart'; @@ -17,17 +17,33 @@ void main() { expect(find.byKey(const Key('Breakpoints.smallMobile')), findsOneWidget); expect(find.byKey(const Key('Breakpoints.smallDesktop')), findsNothing); - // Do the same with a medium layout on a mobile + // Do the same with a medium layout on a mobile. await tester.pumpWidget(SimulatedLayout.medium.slot(tester)); await tester.pumpAndSettle(); expect(find.byKey(const Key('Breakpoints.mediumMobile')), findsOneWidget); expect(find.byKey(const Key('Breakpoints.mediumDesktop')), findsNothing); - // Large layout on mobile + // Do the same with an mediumLarge layout on a mobile. + await tester.pumpWidget(SimulatedLayout.mediumLarge.slot(tester)); + await tester.pumpAndSettle(); + expect( + find.byKey(const Key('Breakpoints.mediumLargeMobile')), findsOneWidget); + expect( + find.byKey(const Key('Breakpoints.mediumLargeDesktop')), findsNothing); + + // Do the same with an large layout on a mobile. await tester.pumpWidget(SimulatedLayout.large.slot(tester)); await tester.pumpAndSettle(); expect(find.byKey(const Key('Breakpoints.largeMobile')), findsOneWidget); expect(find.byKey(const Key('Breakpoints.largeDesktop')), findsNothing); + + // Do the same with an extraLarge layout on a mobile. + await tester.pumpWidget(SimulatedLayout.extraLarge.slot(tester)); + await tester.pumpAndSettle(); + expect( + find.byKey(const Key('Breakpoints.extraLargeMobile')), findsOneWidget); + expect( + find.byKey(const Key('Breakpoints.extraLargeDesktop')), findsNothing); }, variant: TargetPlatformVariant.mobile()); testWidgets('Mobile breakpoints do not show on desktop device', @@ -45,34 +61,1069 @@ void main() { expect(find.byKey(const Key('Breakpoints.mediumDesktop')), findsOneWidget); expect(find.byKey(const Key('Breakpoints.mediumMobile')), findsNothing); + // Do the same with an mediumLarge layout on a desktop. + await tester.pumpWidget(SimulatedLayout.mediumLarge.slot(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.mediumLargeDesktop')), + findsOneWidget); + expect( + find.byKey(const Key('Breakpoints.mediumLargeMobile')), findsNothing); + // Large layout on desktop await tester.pumpWidget(SimulatedLayout.large.slot(tester)); await tester.pumpAndSettle(); expect(find.byKey(const Key('Breakpoints.largeDesktop')), findsOneWidget); expect(find.byKey(const Key('Breakpoints.largeMobile')), findsNothing); + + await tester.pumpWidget(SimulatedLayout.extraLarge.slot(tester)); + await tester.pumpAndSettle(); + expect( + find.byKey(const Key('Breakpoints.extraLargeDesktop')), findsOneWidget); + expect(find.byKey(const Key('Breakpoints.extraLargeMobile')), findsNothing); }, variant: TargetPlatformVariant.desktop()); testWidgets('Breakpoint.isActive should not trigger unnecessary rebuilds', (WidgetTester tester) async { - await tester.pumpWidget(const DymmyWidget()); + await tester.pumpWidget(const DummyWidget()); expect(find.byKey(const Key('button')), findsOneWidget); // First build. - expect(DymmyWidget.built, isTrue); + expect(DummyWidget.built, isTrue); // Invoke `isActive` method. await tester.tap(find.byKey(const Key('button'))); - DymmyWidget.built = false; + DummyWidget.built = false; // Should not rebuild after modifying any property in `MediaQuery`. tester.platformDispatcher.textScaleFactorTestValue = 2; await tester.pumpAndSettle(); - expect(DymmyWidget.built, isFalse); + expect(DummyWidget.built, isFalse); + }); + +// Test the `maybeActiveBreakpointFromSlotLayout` method. + group('maybeActiveBreakpointFromSlotLayout', () { + testWidgets('returns correct breakpoint from SlotLayout on mobile devices', + (WidgetTester tester) async { + // Small layout on mobile. + await tester.pumpWidget(SimulatedLayout.small.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.maybeActiveBreakpointFromSlotLayout( + tester.element(find.byKey(const Key('Breakpoints.smallMobile')))), + Breakpoints.smallMobile); + + // Medium layout on mobile. + await tester.pumpWidget(SimulatedLayout.medium.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.maybeActiveBreakpointFromSlotLayout(tester + .element(find.byKey(const Key('Breakpoints.mediumMobile')))), + Breakpoints.mediumMobile); + + // Large layout on mobile. + await tester.pumpWidget(SimulatedLayout.large.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.maybeActiveBreakpointFromSlotLayout( + tester.element(find.byKey(const Key('Breakpoints.largeMobile')))), + Breakpoints.largeMobile); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets('returns correct breakpoint from SlotLayout on desktop devices', + (WidgetTester tester) async { + // Small layout on desktop. + await tester.pumpWidget(SimulatedLayout.small.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.maybeActiveBreakpointFromSlotLayout(tester + .element(find.byKey(const Key('Breakpoints.smallDesktop')))), + Breakpoints.smallDesktop); + + // Medium layout on desktop. + await tester.pumpWidget(SimulatedLayout.medium.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.maybeActiveBreakpointFromSlotLayout(tester + .element(find.byKey(const Key('Breakpoints.mediumDesktop')))), + Breakpoints.mediumDesktop); + + // Large layout on desktop. + await tester.pumpWidget(SimulatedLayout.large.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.maybeActiveBreakpointFromSlotLayout(tester + .element(find.byKey(const Key('Breakpoints.largeDesktop')))), + Breakpoints.largeDesktop); + }, variant: TargetPlatformVariant.desktop()); + }); + + // Test the `defaultBreakpointOf` method. + group('defaultBreakpointOf', () { + testWidgets('returns correct default breakpoint on mobile devices', + (WidgetTester tester) async { + // Small layout on mobile. + await tester.pumpWidget(SimulatedLayout.small.slot(tester)); + await tester.pumpAndSettle(); + expect(Breakpoint.defaultBreakpointOf(tester.element(find.byType(Theme))), + Breakpoints.smallMobile); + + // Medium layout on mobile. + await tester.pumpWidget(SimulatedLayout.medium.slot(tester)); + await tester.pumpAndSettle(); + expect(Breakpoint.defaultBreakpointOf(tester.element(find.byType(Theme))), + Breakpoints.mediumMobile); + + // Large layout on mobile. + await tester.pumpWidget(SimulatedLayout.large.slot(tester)); + await tester.pumpAndSettle(); + expect(Breakpoint.defaultBreakpointOf(tester.element(find.byType(Theme))), + Breakpoints.largeMobile); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets('returns correct default breakpoint on desktop devices', + (WidgetTester tester) async { + // Small layout on desktop. + await tester.pumpWidget(SimulatedLayout.small.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.defaultBreakpointOf( + tester.element(find.byType(Directionality))), + Breakpoints.smallDesktop); + + // Medium layout on desktop. + await tester.pumpWidget(SimulatedLayout.medium.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.defaultBreakpointOf( + tester.element(find.byType(Directionality))), + Breakpoints.mediumDesktop); + + // Large layout on desktop. + await tester.pumpWidget(SimulatedLayout.large.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.defaultBreakpointOf( + tester.element(find.byType(Directionality))), + Breakpoints.largeDesktop); + }, variant: TargetPlatformVariant.desktop()); + }); + + // Test the `activeBreakpointOf` method. + group('activeBreakpointOf', () { + testWidgets('returns correct active breakpoint on mobile devices', + (WidgetTester tester) async { + // Small layout on mobile. + await tester.pumpWidget(SimulatedLayout.small.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf( + tester.element(find.byKey(const Key('Breakpoints.smallMobile')))), + Breakpoints.smallMobile); + + // Medium layout on mobile. + await tester.pumpWidget(SimulatedLayout.medium.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester + .element(find.byKey(const Key('Breakpoints.mediumMobile')))), + Breakpoints.mediumMobile); + + // Large layout on mobile. + await tester.pumpWidget(SimulatedLayout.large.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf( + tester.element(find.byKey(const Key('Breakpoints.largeMobile')))), + Breakpoints.largeMobile); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets('returns correct active breakpoint on desktop devices', + (WidgetTester tester) async { + // Small layout on desktop. + await tester.pumpWidget(SimulatedLayout.small.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester + .element(find.byKey(const Key('Breakpoints.smallDesktop')))), + Breakpoints.smallDesktop); + + // Medium layout on desktop. + await tester.pumpWidget(SimulatedLayout.medium.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester + .element(find.byKey(const Key('Breakpoints.mediumDesktop')))), + Breakpoints.mediumDesktop); + + // Large layout on desktop. + await tester.pumpWidget(SimulatedLayout.large.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester + .element(find.byKey(const Key('Breakpoints.largeDesktop')))), + Breakpoints.largeDesktop); + }, variant: TargetPlatformVariant.desktop()); + }); + + group('Landscape Layout Tests', () { + testWidgets('Desktop breakpoints do not show on mobile device (landscape)', + (WidgetTester tester) async { + // Small landscape layout on a mobile device. + await tester.pumpWidget(SimulatedLayout.smallLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.smallMobile')), findsOneWidget); + expect(find.byKey(const Key('Breakpoints.smallDesktop')), findsNothing); + + // Medium landscape layout on a mobile. + await tester.pumpWidget(SimulatedLayout.mediumLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.mediumMobile')), findsOneWidget); + expect(find.byKey(const Key('Breakpoints.mediumDesktop')), findsNothing); + + // MediumLarge landscape layout on a mobile. + await tester + .pumpWidget(SimulatedLayout.mediumLargeLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.mediumLargeMobile')), + findsOneWidget); + expect(find.byKey(const Key('Breakpoints.mediumLargeDesktop')), + findsNothing); + + // Large landscape layout on a mobile. + await tester.pumpWidget(SimulatedLayout.largeLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.largeMobile')), findsOneWidget); + expect(find.byKey(const Key('Breakpoints.largeDesktop')), findsNothing); + + // ExtraLarge landscape layout on a mobile. + await tester.pumpWidget(SimulatedLayout.extraLargeLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.extraLargeMobile')), + findsOneWidget); + expect( + find.byKey(const Key('Breakpoints.extraLargeDesktop')), findsNothing); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets('Mobile breakpoints do not show on desktop device (landscape)', + (WidgetTester tester) async { + // Small landscape layout on a desktop device. + await tester.pumpWidget(SimulatedLayout.smallLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.smallDesktop')), findsOneWidget); + expect(find.byKey(const Key('Breakpoints.smallMobile')), findsNothing); + + // Medium landscape layout on a desktop. + await tester.pumpWidget(SimulatedLayout.mediumLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect( + find.byKey(const Key('Breakpoints.mediumDesktop')), findsOneWidget); + expect(find.byKey(const Key('Breakpoints.mediumMobile')), findsNothing); + + // MediumLarge landscape layout on a desktop. + await tester + .pumpWidget(SimulatedLayout.mediumLargeLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.mediumLargeDesktop')), + findsOneWidget); + expect( + find.byKey(const Key('Breakpoints.mediumLargeMobile')), findsNothing); + + // Large landscape layout on a desktop. + await tester.pumpWidget(SimulatedLayout.largeLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.largeDesktop')), findsOneWidget); + expect(find.byKey(const Key('Breakpoints.largeMobile')), findsNothing); + + await tester.pumpWidget(SimulatedLayout.extraLargeLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.extraLargeDesktop')), + findsOneWidget); + expect( + find.byKey(const Key('Breakpoints.extraLargeMobile')), findsNothing); + }, variant: TargetPlatformVariant.desktop()); + + // Additional landscape tests for `maybeActiveBreakpointFromSlotLayout`. + testWidgets( + 'maybeActiveBreakpointFromSlotLayout returns correct breakpoint on mobile (landscape)', + (WidgetTester tester) async { + // Small landscape layout on mobile. + await tester.pumpWidget(SimulatedLayout.smallLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.maybeActiveBreakpointFromSlotLayout( + tester.element(find.byKey(const Key('Breakpoints.smallMobile')))), + Breakpoints.smallMobile); + + // Medium landscape layout on mobile. + await tester.pumpWidget(SimulatedLayout.mediumLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.maybeActiveBreakpointFromSlotLayout(tester + .element(find.byKey(const Key('Breakpoints.mediumMobile')))), + Breakpoints.mediumMobile); + + // Large landscape layout on mobile. + await tester.pumpWidget(SimulatedLayout.largeLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.maybeActiveBreakpointFromSlotLayout( + tester.element(find.byKey(const Key('Breakpoints.largeMobile')))), + Breakpoints.largeMobile); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets( + 'maybeActiveBreakpointFromSlotLayout returns correct breakpoint on desktop (landscape)', + (WidgetTester tester) async { + // Small landscape layout on desktop. + await tester.pumpWidget(SimulatedLayout.smallLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.maybeActiveBreakpointFromSlotLayout(tester + .element(find.byKey(const Key('Breakpoints.smallDesktop')))), + Breakpoints.smallDesktop); + + // Medium landscape layout on desktop. + await tester.pumpWidget(SimulatedLayout.mediumLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.maybeActiveBreakpointFromSlotLayout(tester + .element(find.byKey(const Key('Breakpoints.mediumDesktop')))), + Breakpoints.mediumDesktop); + + // Large landscape layout on desktop. + await tester.pumpWidget(SimulatedLayout.largeLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.maybeActiveBreakpointFromSlotLayout(tester + .element(find.byKey(const Key('Breakpoints.largeDesktop')))), + Breakpoints.largeDesktop); + }, variant: TargetPlatformVariant.desktop()); + + // Additional landscape tests for `defaultBreakpointOf`. + testWidgets( + 'defaultBreakpointOf returns correct default breakpoint on mobile (landscape)', + (WidgetTester tester) async { + // Small landscape layout on mobile. + await tester.pumpWidget(SimulatedLayout.smallLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect(Breakpoint.defaultBreakpointOf(tester.element(find.byType(Theme))), + Breakpoints.smallMobile); + + // Medium landscape layout on mobile. + await tester.pumpWidget(SimulatedLayout.mediumLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect(Breakpoint.defaultBreakpointOf(tester.element(find.byType(Theme))), + Breakpoints.mediumMobile); + + // Large landscape layout on mobile. + await tester.pumpWidget(SimulatedLayout.largeLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect(Breakpoint.defaultBreakpointOf(tester.element(find.byType(Theme))), + Breakpoints.largeMobile); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets( + 'defaultBreakpointOf returns correct default breakpoint on desktop (landscape)', + (WidgetTester tester) async { + // Small landscape layout on desktop. + await tester.pumpWidget(SimulatedLayout.smallLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.defaultBreakpointOf( + tester.element(find.byType(Directionality))), + Breakpoints.smallDesktop); + + // Medium landscape layout on desktop. + await tester.pumpWidget(SimulatedLayout.mediumLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.defaultBreakpointOf( + tester.element(find.byType(Directionality))), + Breakpoints.mediumDesktop); + + // Large landscape layout on desktop. + await tester.pumpWidget(SimulatedLayout.largeLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.defaultBreakpointOf( + tester.element(find.byType(Directionality))), + Breakpoints.largeDesktop); + }, variant: TargetPlatformVariant.desktop()); + + // Additional landscape tests for `activeBreakpointOf`. + testWidgets( + 'activeBreakpointOf returns correct active breakpoint on mobile (landscape)', + (WidgetTester tester) async { + // Small landscape layout on mobile. + await tester.pumpWidget(SimulatedLayout.smallLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf( + tester.element(find.byKey(const Key('Breakpoints.smallMobile')))), + Breakpoints.smallMobile); + + // Medium landscape layout on mobile. + await tester.pumpWidget(SimulatedLayout.mediumLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester + .element(find.byKey(const Key('Breakpoints.mediumMobile')))), + Breakpoints.mediumMobile); + + // Large landscape layout on mobile. + await tester.pumpWidget(SimulatedLayout.largeLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf( + tester.element(find.byKey(const Key('Breakpoints.largeMobile')))), + Breakpoints.largeMobile); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets( + 'activeBreakpointOf returns correct active breakpoint on desktop (landscape)', + (WidgetTester tester) async { + // Small landscape layout on desktop. + await tester.pumpWidget(SimulatedLayout.smallLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester + .element(find.byKey(const Key('Breakpoints.smallDesktop')))), + Breakpoints.smallDesktop); + + // Medium landscape layout on desktop. + await tester.pumpWidget(SimulatedLayout.mediumLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester + .element(find.byKey(const Key('Breakpoints.mediumDesktop')))), + Breakpoints.mediumDesktop); + + // Large landscape layout on desktop. + await tester.pumpWidget(SimulatedLayout.largeLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester + .element(find.byKey(const Key('Breakpoints.largeDesktop')))), + Breakpoints.largeDesktop); + }, variant: TargetPlatformVariant.desktop()); + }); + + group('Portrait and Landscape Mixed Layout Tests', () { + testWidgets( + 'Layout for smallPortraitMediumLandscape shows correct slot configuration', + (WidgetTester tester) async { + await tester.pumpWidget( + SimulatedLayout.smallPortraitMediumLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.smallMobile')), findsOneWidget); + expect(find.byKey(const Key('Breakpoints.mediumMobile')), findsNothing); + expect(find.byKey(const Key('Breakpoints.small')), findsNothing); + expect(find.byKey(const Key('Breakpoints.smallDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.medium')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumLarge')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.mediumLargeMobile')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumLargeDesktop')), + findsNothing); + expect(find.byKey(const Key('Breakpoints.large')), findsNothing); + expect(find.byKey(const Key('Breakpoints.largeMobile')), findsNothing); + expect(find.byKey(const Key('Breakpoints.largeDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.extraLarge')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.extraLargeMobile')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.extraLargeDesktop')), findsNothing); + }); + + testWidgets( + 'Layout for smallLandscapeMediumPortrait shows correct slot configuration', + (WidgetTester tester) async { + await tester.pumpWidget( + SimulatedLayout.smallLandscapeMediumPortrait.slot(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.smallMobile')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumMobile')), findsOneWidget); + expect(find.byKey(const Key('Breakpoints.small')), findsNothing); + expect(find.byKey(const Key('Breakpoints.smallDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.medium')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumLarge')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.mediumLargeMobile')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumLargeDesktop')), + findsNothing); + expect(find.byKey(const Key('Breakpoints.large')), findsNothing); + expect(find.byKey(const Key('Breakpoints.largeMobile')), findsNothing); + expect(find.byKey(const Key('Breakpoints.largeDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.extraLarge')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.extraLargeMobile')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.extraLargeDesktop')), findsNothing); + }); + + testWidgets( + 'Layout for smallPortraitMediumLargeLandscape shows correct slot configuration', + (WidgetTester tester) async { + await tester.pumpWidget( + SimulatedLayout.smallPortraitMediumLargeLandscape.slot(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.smallMobile')), findsOneWidget); + expect(find.byKey(const Key('Breakpoints.largeMobile')), findsNothing); + expect(find.byKey(const Key('Breakpoints.small')), findsNothing); + expect(find.byKey(const Key('Breakpoints.smallDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.medium')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumLarge')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.mediumLargeMobile')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumLargeDesktop')), + findsNothing); + expect(find.byKey(const Key('Breakpoints.large')), findsNothing); + expect(find.byKey(const Key('Breakpoints.largeDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.extraLarge')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.extraLargeMobile')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.extraLargeDesktop')), findsNothing); + }); + + testWidgets( + 'Layout for smallLandscapeMediumLargePortrait shows correct slot configuration', + (WidgetTester tester) async { + await tester.pumpWidget( + SimulatedLayout.smallLandscapeMediumLargePortrait.slot(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.smallMobile')), findsNothing); + expect(find.byKey(const Key('Breakpoints.largeMobile')), findsNothing); + expect(find.byKey(const Key('Breakpoints.small')), findsNothing); + expect(find.byKey(const Key('Breakpoints.smallDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.medium')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumLarge')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumLargeMobile')), + findsOneWidget); + expect(find.byKey(const Key('Breakpoints.mediumLargeDesktop')), + findsNothing); + expect(find.byKey(const Key('Breakpoints.large')), findsNothing); + expect(find.byKey(const Key('Breakpoints.largeDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.extraLarge')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.extraLargeMobile')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.extraLargeDesktop')), findsNothing); + }); + + testWidgets( + 'Layout for mediumLargeLandscapeMediumPortrait shows correct slot configuration', + (WidgetTester tester) async { + await tester.pumpWidget( + SimulatedLayout.mediumLargeLandscapeMediumPortrait.slot(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.smallMobile')), findsNothing); + expect(find.byKey(const Key('Breakpoints.largeMobile')), findsNothing); + expect(find.byKey(const Key('Breakpoints.small')), findsNothing); + expect(find.byKey(const Key('Breakpoints.smallDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.medium')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumLarge')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumLargeMobile')), + findsOneWidget); + expect(find.byKey(const Key('Breakpoints.mediumLargeDesktop')), + findsNothing); + expect(find.byKey(const Key('Breakpoints.large')), findsNothing); + expect(find.byKey(const Key('Breakpoints.largeDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.extraLarge')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.extraLargeMobile')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.extraLargeDesktop')), findsNothing); + }); + }); + + group('Slot And Up Layout Tests', () { + testWidgets('slotAndUp shows correct slot for small layout', + (WidgetTester tester) async { + // Small layout should only show the small slot. + await tester.pumpWidget(SimulatedLayout.small.slotAndUp(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.small')), findsOneWidget); + expect(find.byKey(const Key('Breakpoints.mediumAndUp')), findsNothing); + }); + + testWidgets('slotAndUp shows correct slot for medium layout and up', + (WidgetTester tester) async { + // Medium layout should show the mediumAndUp slot. + await tester.pumpWidget(SimulatedLayout.medium.slotAndUp(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.mediumAndUp')), findsOneWidget); + expect(find.byKey(const Key('Breakpoints.small')), findsNothing); + + // MediumLarge layout should also show the mediumAndUp slot. + await tester.pumpWidget(SimulatedLayout.mediumLarge.slotAndUp(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.mediumAndUp')), findsOneWidget); + expect(find.byKey(const Key('Breakpoints.small')), findsNothing); + + // Large layout should also show the mediumAndUp slot. + await tester.pumpWidget(SimulatedLayout.large.slotAndUp(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.mediumAndUp')), findsOneWidget); + expect(find.byKey(const Key('Breakpoints.small')), findsNothing); + + // ExtraLarge layout should also show the mediumAndUp slot. + await tester.pumpWidget(SimulatedLayout.extraLarge.slotAndUp(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.mediumAndUp')), findsOneWidget); + expect(find.byKey(const Key('Breakpoints.small')), findsNothing); + }); + + testWidgets('slotAndUp shows correct slot for small landscape layout', + (WidgetTester tester) async { + // Small landscape layout should only show the small slot. + await tester.pumpWidget(SimulatedLayout.smallLandscape.slotAndUp(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.small')), findsOneWidget); + expect(find.byKey(const Key('Breakpoints.mediumAndUp')), findsNothing); + }); + + testWidgets( + 'slotAndUp shows correct slot for medium and larger landscape layouts', + (WidgetTester tester) async { + // Medium landscape layout should show the mediumAndUp slot. + await tester + .pumpWidget(SimulatedLayout.mediumLandscape.slotAndUp(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.mediumAndUp')), findsOneWidget); + expect(find.byKey(const Key('Breakpoints.small')), findsNothing); + + // MediumLarge landscape layout should also show the mediumAndUp slot. + await tester + .pumpWidget(SimulatedLayout.mediumLargeLandscape.slotAndUp(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.mediumAndUp')), findsOneWidget); + expect(find.byKey(const Key('Breakpoints.small')), findsNothing); + + // Large landscape layout should also show the mediumAndUp slot. + await tester.pumpWidget(SimulatedLayout.largeLandscape.slotAndUp(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.mediumAndUp')), findsOneWidget); + expect(find.byKey(const Key('Breakpoints.small')), findsNothing); + + // ExtraLarge landscape layout should also show the mediumAndUp slot. + await tester + .pumpWidget(SimulatedLayout.extraLargeLandscape.slotAndUp(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.mediumAndUp')), findsOneWidget); + expect(find.byKey(const Key('Breakpoints.small')), findsNothing); + }); + }); + + group('Slot And Up Layout Tests with Portrait and Landscape Mixed Layout', + () { + testWidgets( + 'slotAndUp shows correct slot for smallPortraitMediumLandscape layout', + (WidgetTester tester) async { + // smallPortraitMediumLandscape layout should only show the small slot. + await tester.pumpWidget( + SimulatedLayout.smallPortraitMediumLandscape.slotAndUp(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.small')), findsOneWidget); + expect(find.byKey(const Key('Breakpoints.mediumAndUp')), findsNothing); + }); + + testWidgets( + 'slotAndUp shows correct slot for smallLandscapeMediumPortrait layout', + (WidgetTester tester) async { + // smallLandscapeMediumPortrait layout should show the small slot. + await tester.pumpWidget( + SimulatedLayout.smallLandscapeMediumPortrait.slotAndUp(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.small')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumAndUp')), findsOneWidget); + }); + + testWidgets( + 'slotAndUp shows correct slot for smallPortraitMediumLargeLandscape layout', + (WidgetTester tester) async { + // smallPortraitMediumLargeLandscape layout should show the small slot. + await tester.pumpWidget( + SimulatedLayout.smallPortraitMediumLargeLandscape.slotAndUp(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.small')), findsOneWidget); + expect(find.byKey(const Key('Breakpoints.mediumAndUp')), findsNothing); + }); + + testWidgets( + 'slotAndUp shows correct slot for smallLandscapeMediumLargePortrait layout', + (WidgetTester tester) async { + // smallLandscapeMediumLargePortrait layout should show the small slot. + await tester.pumpWidget( + SimulatedLayout.smallLandscapeMediumLargePortrait.slotAndUp(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.small')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumAndUp')), findsOneWidget); + }); + + testWidgets( + 'slotAndUp shows correct slot for mediumLargeLandscapeMediumPortrait layout', + (WidgetTester tester) async { + // mediumLargeLandscapeMediumPortrait layout should show the mediumAndUp slot. + await tester.pumpWidget( + SimulatedLayout.mediumLargeLandscapeMediumPortrait.slotAndUp(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.small')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumAndUp')), findsOneWidget); + }); + }); + + // Test for `spacing`. + group('spacing property', () { + testWidgets('returns kMaterialCompactSpacing for small breakpoint', + (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.small.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester + .element(find.byKey(const Key('Breakpoints.smallMobile')))) + .spacing, + kMaterialCompactSpacing); + }); + + testWidgets('returns kMaterialMediumAndUpSpacing for medium breakpoint', + (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.medium.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester + .element(find.byKey(const Key('Breakpoints.mediumMobile')))) + .spacing, + kMaterialMediumAndUpSpacing); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets( + 'returns kMaterialMediumAndUpSpacing for mediumLarge breakpoint', + (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.mediumLarge.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester.element( + find.byKey(const Key('Breakpoints.mediumLargeMobile')))) + .spacing, + kMaterialMediumAndUpSpacing); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets('returns kMaterialMediumAndUpSpacing for large breakpoint', + (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.large.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester + .element(find.byKey(const Key('Breakpoints.largeMobile')))) + .spacing, + kMaterialMediumAndUpSpacing); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets('returns kMaterialMediumAndUpSpacing for extraLarge breakpoint', + (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.extraLarge.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester.element( + find.byKey(const Key('Breakpoints.extraLargeMobile')))) + .spacing, + kMaterialMediumAndUpSpacing); + }, variant: TargetPlatformVariant.mobile()); + }); + + // Test for `margin`. + group('margin property', () { + testWidgets('returns kMaterialCompactMargin for small breakpoint', + (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.small.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester + .element(find.byKey(const Key('Breakpoints.smallMobile')))) + .margin, + kMaterialCompactMargin); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets('returns kMaterialMediumAndUpMargin for medium breakpoint', + (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.medium.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester + .element(find.byKey(const Key('Breakpoints.mediumMobile')))) + .margin, + kMaterialMediumAndUpMargin); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets('returns kMaterialMediumAndUpMargin for mediumLarge breakpoint', + (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.mediumLarge.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester.element( + find.byKey(const Key('Breakpoints.mediumLargeMobile')))) + .margin, + kMaterialMediumAndUpMargin); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets('returns kMaterialMediumAndUpMargin for large breakpoint', + (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.large.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester + .element(find.byKey(const Key('Breakpoints.largeMobile')))) + .margin, + kMaterialMediumAndUpMargin); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets('returns kMaterialMediumAndUpMargin for extraLarge breakpoint', + (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.extraLarge.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester.element( + find.byKey(const Key('Breakpoints.extraLargeMobile')))) + .margin, + kMaterialMediumAndUpMargin); + }, variant: TargetPlatformVariant.mobile()); + }); + + // Test for `padding`. + group('padding property', () { + testWidgets('returns kMaterialPadding for small breakpoint', + (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.small.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester + .element(find.byKey(const Key('Breakpoints.smallMobile')))) + .padding, + kMaterialPadding); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets('returns kMaterialPadding * 2 for medium breakpoint', + (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.medium.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester + .element(find.byKey(const Key('Breakpoints.mediumMobile')))) + .padding, + kMaterialPadding * 2); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets('returns kMaterialPadding * 3 for mediumLarge breakpoint', + (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.mediumLarge.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester.element( + find.byKey(const Key('Breakpoints.mediumLargeMobile')))) + .padding, + kMaterialPadding * 3); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets('returns kMaterialPadding * 4 for large breakpoint', + (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.large.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester + .element(find.byKey(const Key('Breakpoints.largeMobile')))) + .padding, + kMaterialPadding * 4); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets('returns kMaterialPadding * 5 for extraLarge breakpoint', + (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.extraLarge.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester.element( + find.byKey(const Key('Breakpoints.extraLargeMobile')))) + .padding, + kMaterialPadding * 5); + }, variant: TargetPlatformVariant.mobile()); + }); + + // Test for `recommendedPanes`. + group('recommendedPanes property', () { + testWidgets('returns 1 for small breakpoint', (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.small.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester + .element(find.byKey(const Key('Breakpoints.smallMobile')))) + .recommendedPanes, + 1); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets('returns 1 for medium breakpoint', (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.medium.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester + .element(find.byKey(const Key('Breakpoints.mediumMobile')))) + .recommendedPanes, + 1); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets('returns 2 for mediumLarge breakpoint', + (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.mediumLarge.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester.element( + find.byKey(const Key('Breakpoints.mediumLargeMobile')))) + .recommendedPanes, + 2); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets('returns 2 for large breakpoint', (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.large.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester + .element(find.byKey(const Key('Breakpoints.largeMobile')))) + .recommendedPanes, + 2); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets('returns 2 for extraLarge breakpoint', + (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.extraLarge.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester.element( + find.byKey(const Key('Breakpoints.extraLargeMobile')))) + .recommendedPanes, + 2); + }, variant: TargetPlatformVariant.mobile()); + }); + + // Test for `maxPanes`. + group('maxPanes property', () { + testWidgets('returns 1 for small breakpoint', (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.small.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester + .element(find.byKey(const Key('Breakpoints.smallMobile')))) + .maxPanes, + 1); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets('returns 2 for medium breakpoint', (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.medium.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester + .element(find.byKey(const Key('Breakpoints.mediumMobile')))) + .maxPanes, + 2); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets('returns 2 for mediumLarge breakpoint', + (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.mediumLarge.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester.element( + find.byKey(const Key('Breakpoints.mediumLargeMobile')))) + .maxPanes, + 2); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets('returns 2 for large breakpoint', (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.large.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester + .element(find.byKey(const Key('Breakpoints.largeMobile')))) + .maxPanes, + 2); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets('returns 3 for extraLarge breakpoint', + (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.extraLarge.slot(tester)); + await tester.pumpAndSettle(); + expect( + Breakpoint.activeBreakpointOf(tester.element( + find.byKey(const Key('Breakpoints.extraLargeMobile')))) + .maxPanes, + 3); + }, variant: TargetPlatformVariant.mobile()); + }); + + group('Breakpoint method tests', () { + testWidgets('isMobile returns true on mobile platforms', + (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.medium.scaffold(tester)); + await tester.pumpAndSettle(); + + expect(Breakpoint.isMobile(tester.element(find.byType(TestScaffold))), + isTrue); + + expect(Breakpoint.isDesktop(tester.element(find.byType(TestScaffold))), + isFalse); + }, variant: TargetPlatformVariant.mobile()); + + testWidgets('isDesktop returns true on desktop platforms', + (WidgetTester tester) async { + await tester.pumpWidget(SimulatedLayout.medium.scaffold(tester)); + await tester.pumpAndSettle(); + + expect(Breakpoint.isDesktop(tester.element(find.byType(TestScaffold))), + isTrue); + + expect(Breakpoint.isMobile(tester.element(find.byType(TestScaffold))), + isFalse); + }, variant: TargetPlatformVariant.desktop()); + + test('Breakpoint comparison operators work correctly', () { + const Breakpoint small = Breakpoints.small; + const Breakpoint medium = Breakpoints.medium; + const Breakpoint large = Breakpoints.large; + + expect(small < medium, isTrue); + expect(large > medium, isTrue); + expect(small <= Breakpoints.small, isTrue); + expect(large >= medium, isTrue); + }); + + test('Breakpoint equality and hashCode', () { + const Breakpoint small1 = Breakpoints.small; + const Breakpoint small2 = Breakpoints.small; + const Breakpoint medium = Breakpoints.medium; + + expect(small1 == small2, isTrue); + expect(small1 == medium, isFalse); + expect(small1.hashCode == small2.hashCode, isTrue); + expect(small1.hashCode == medium.hashCode, isFalse); + }); + + test('Breakpoint between method works correctly', () { + const Breakpoint small = Breakpoints.small; + const Breakpoint medium = Breakpoints.medium; + const Breakpoint large = Breakpoints.large; + + expect(medium.between(small, large), isTrue); + expect(small.between(medium, large), isFalse); + expect(large.between(small, medium), isFalse); + }); }); } -class DymmyWidget extends StatelessWidget { - const DymmyWidget({super.key}); +class DummyWidget extends StatelessWidget { + const DummyWidget({super.key}); static bool built = false; @override diff --git a/packages/flutter_adaptive_scaffold/test/simulated_layout.dart b/packages/flutter_adaptive_scaffold/test/simulated_layout.dart index 706883d997db..01fba796b6c5 100644 --- a/packages/flutter_adaptive_scaffold/test/simulated_layout.dart +++ b/packages/flutter_adaptive_scaffold/test/simulated_layout.dart @@ -82,14 +82,20 @@ class TestScaffoldState extends State { internalAnimations: widget.isAnimated, smallBreakpoint: TestBreakpoint0(), mediumBreakpoint: TestBreakpoint800(), - largeBreakpoint: TestBreakpoint1000(), + mediumLargeBreakpoint: TestBreakpoint1000(), + largeBreakpoint: TestBreakpoint1200(), + extraLargeBreakpoint: TestBreakpoint1600(), destinations: TestScaffold.destinations, smallBody: (_) => Container(color: Colors.red), body: (_) => Container(color: Colors.green), - largeBody: (_) => Container(color: Colors.blue), + mediumLargeBody: (_) => Container(color: Colors.blue), + largeBody: (_) => Container(color: Colors.yellow), + extraLargeBody: (_) => Container(color: Colors.purple), smallSecondaryBody: (_) => Container(color: Colors.red), secondaryBody: (_) => Container(color: Colors.green), - largeSecondaryBody: (_) => Container(color: Colors.blue), + mediumLargeSecondaryBody: (_) => Container(color: Colors.blue), + largeSecondaryBody: (_) => Container(color: Colors.yellow), + extraLargeSecondaryBody: (_) => Container(color: Colors.purple), leadingExtendedNavRail: const Text('leading_extended'), leadingUnextendedNavRail: const Text('leading_unextended'), trailingNavRail: const Text('trailing'), @@ -100,15 +106,36 @@ class TestScaffoldState extends State { enum SimulatedLayout { small(width: 400, navSlotKey: 'bottomNavigation'), medium(width: 800, navSlotKey: 'primaryNavigation'), - large(width: 1100, navSlotKey: 'primaryNavigation1'); + mediumLarge(width: 1000, navSlotKey: 'primaryNavigation1'), + large(width: 1200, navSlotKey: 'primaryNavigation2'), + extraLarge(width: 1600, navSlotKey: 'primaryNavigation3'), + smallLandscape(width: 500, height: 400, navSlotKey: 'bottomNavigation'), + mediumLandscape(width: 800, height: 600, navSlotKey: 'primaryNavigation'), + mediumLargeLandscape( + width: 1100, height: 900, navSlotKey: 'primaryNavigation1'), + largeLandscape(width: 1400, height: 1000, navSlotKey: 'primaryNavigation2'), + extraLargeLandscape( + width: 1700, height: 1000, navSlotKey: 'primaryNavigation3'), + smallPortraitMediumLandscape( + width: 360, height: 650, navSlotKey: 'bottomNavigation'), + smallLandscapeMediumPortrait( + width: 650, height: 360, navSlotKey: 'bottomNavigation'), + smallPortraitMediumLargeLandscape( + width: 360, height: 900, navSlotKey: 'bottomNavigation'), + smallLandscapeMediumLargePortrait( + width: 900, height: 360, navSlotKey: 'primaryNavigation'), + mediumLargeLandscapeMediumPortrait( + width: 841, height: 668, navSlotKey: 'primaryNavigation'); const SimulatedLayout({ required double width, + double height = 2000, required this.navSlotKey, - }) : _width = width; + }) : _width = width, + _height = height; final double _width; - final double _height = 800; + final double _height; final String navSlotKey; static const Color navigationRailThemeBgColor = Colors.white; @@ -123,11 +150,7 @@ enum SimulatedLayout { Size get size => Size(_width, _height); - MaterialApp app({ - int? initialIndex, - bool animations = true, - Breakpoint? appBarBreakpoint, - }) { + MaterialApp app(WidgetTester tester, {required Widget child}) { return MaterialApp( theme: ThemeData.light().copyWith( navigationRailTheme: const NavigationRailThemeData( @@ -137,15 +160,27 @@ enum SimulatedLayout { ), ), home: MediaQuery( - data: MediaQueryData( - size: size, + data: MediaQueryData.fromView(tester.view).copyWith( + size: Size(_width, _height), padding: const EdgeInsets.only(top: 30), ), - child: TestScaffold( - initialIndex: initialIndex, - isAnimated: animations, - appBarBreakpoint: appBarBreakpoint, - ), + child: child, + ), + ); + } + + MaterialApp scaffold( + WidgetTester tester, { + int? initialIndex, + bool animations = true, + Breakpoint? appBarBreakpoint, + }) { + return app( + tester, + child: TestScaffold( + initialIndex: initialIndex, + isAnimated: animations, + appBarBreakpoint: appBarBreakpoint, ), ); } @@ -184,6 +219,18 @@ enum SimulatedLayout { key: const Key('Breakpoints.mediumDesktop'), builder: (BuildContext context) => Container(), ), + Breakpoints.mediumLarge: SlotLayout.from( + key: const Key('Breakpoints.mediumLarge'), + builder: (BuildContext context) => Container(), + ), + Breakpoints.mediumLargeMobile: SlotLayout.from( + key: const Key('Breakpoints.mediumLargeMobile'), + builder: (BuildContext context) => Container(), + ), + Breakpoints.mediumLargeDesktop: SlotLayout.from( + key: const Key('Breakpoints.mediumLargeDesktop'), + builder: (BuildContext context) => Container(), + ), Breakpoints.large: SlotLayout.from( key: const Key('Breakpoints.large'), builder: (BuildContext context) => Container(), @@ -196,6 +243,43 @@ enum SimulatedLayout { key: const Key('Breakpoints.largeDesktop'), builder: (BuildContext context) => Container(), ), + Breakpoints.extraLarge: SlotLayout.from( + key: const Key('Breakpoints.extraLarge'), + builder: (BuildContext context) => Container(), + ), + Breakpoints.extraLargeMobile: SlotLayout.from( + key: const Key('Breakpoints.extraLargeMobile'), + builder: (BuildContext context) => Container(), + ), + Breakpoints.extraLargeDesktop: SlotLayout.from( + key: const Key('Breakpoints.extraLargeDesktop'), + builder: (BuildContext context) => Container(), + ), + }, + ), + ), + ), + ); + } + + MediaQuery slotAndUp(WidgetTester tester) { + return MediaQuery( + data: MediaQueryData.fromView(tester.view) + .copyWith(size: Size(_width, _height)), + child: Theme( + data: ThemeData(), + child: Directionality( + textDirection: TextDirection.ltr, + child: SlotLayout( + config: { + Breakpoints.small: SlotLayout.from( + key: const Key('Breakpoints.small'), + builder: (BuildContext context) => Container(), + ), + Breakpoints.mediumAndUp: SlotLayout.from( + key: const Key('Breakpoints.mediumAndUp'), + builder: (BuildContext context) => Container(), + ), }, ), ), diff --git a/packages/flutter_adaptive_scaffold/test/slot_layout_test.dart b/packages/flutter_adaptive_scaffold/test/slot_layout_test.dart new file mode 100644 index 000000000000..f2a8005a3618 --- /dev/null +++ b/packages/flutter_adaptive_scaffold/test/slot_layout_test.dart @@ -0,0 +1,185 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_adaptive_scaffold/src/breakpoints.dart'; +import 'package:flutter_adaptive_scaffold/src/slot_layout.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + testWidgets( + 'SlotLayout displays correct widget based on screen width', + (WidgetTester tester) async { + MediaQuery slot(double width) { + return MediaQuery( + data: MediaQueryData(size: Size(width, 2000)), + child: Directionality( + textDirection: TextDirection.ltr, + child: SlotLayout( + config: { + Breakpoints.smallAndUp: SlotLayout.from( + key: const Key('0'), builder: (_) => const Text('Small')), + Breakpoints.mediumAndUp: SlotLayout.from( + key: const Key('400'), + builder: (_) => const Text('Medium')), + Breakpoints.largeAndUp: SlotLayout.from( + key: const Key('800'), builder: (_) => const Text('Large')), + }, + ), + ), + ); + } + + await tester.pumpWidget(slot(300)); + expect(find.text('Small'), findsOneWidget); + expect(find.text('Medium'), findsNothing); + expect(find.text('Large'), findsNothing); + + await tester.pumpWidget(slot(600)); + expect(find.text('Small'), findsNothing); + expect(find.text('Medium'), findsOneWidget); + expect(find.text('Large'), findsNothing); + + await tester.pumpWidget(slot(1200)); + expect(find.text('Small'), findsNothing); + expect(find.text('Medium'), findsNothing); + expect(find.text('Large'), findsOneWidget); + }, + ); + + testWidgets( + 'SlotLayout handles null configurations gracefully', + (WidgetTester tester) async { + await tester.pumpWidget( + MediaQuery( + data: MediaQueryData.fromView(tester.view) + .copyWith(size: const Size(500, 2000)), + child: Directionality( + textDirection: TextDirection.ltr, + child: SlotLayout( + config: { + Breakpoints.smallAndUp: SlotLayout.from( + key: const Key('0'), + builder: (BuildContext context) => Container(), + ), + Breakpoints.mediumAndUp: null, + Breakpoints.largeAndUp: SlotLayout.from( + key: const Key('800'), + builder: (BuildContext context) => Container(), + ), + }, + ), + ), + ), + ); + + expect(find.byKey(const Key('0')), findsOneWidget); + expect(find.byKey(const Key('400')), findsNothing); + expect(find.byKey(const Key('800')), findsNothing); + }, + ); + + testWidgets( + 'SlotLayout builder generates widgets correctly', + (WidgetTester tester) async { + await tester.pumpWidget( + MediaQuery( + data: const MediaQueryData(size: Size(600, 2000)), + child: Directionality( + textDirection: TextDirection.ltr, + child: SlotLayout( + config: { + Breakpoints.mediumAndUp: SlotLayout.from( + key: const Key('0'), + builder: (_) => const Text('Builder Test')), + }, + ), + ), + ), + ); + + expect(find.text('Builder Test'), findsOneWidget); + }, + ); + + testWidgets( + 'SlotLayout applies inAnimation and outAnimation correctly when changing breakpoints', + (WidgetTester tester) async { + // Define a SlotLayout with custom animations. + Widget buildSlotLayout(double width) { + return MediaQuery( + data: MediaQueryData(size: Size(width, 2000)), + child: Directionality( + textDirection: TextDirection.ltr, + child: SlotLayout( + config: { + Breakpoints.smallAndUp: SlotLayout.from( + key: const Key('small'), + builder: (_) => const SizedBox( + key: Key('smallBox'), width: 100, height: 100), + inAnimation: (Widget widget, Animation animation) => + ScaleTransition( + scale: animation, + child: widget, + ), + outAnimation: (Widget widget, Animation animation) => + FadeTransition( + opacity: animation, + child: widget, + ), + inDuration: const Duration(seconds: 1), + outDuration: const Duration(seconds: 2), + inCurve: Curves.easeIn, + outCurve: Curves.easeOut, + ), + Breakpoints.mediumAndUp: SlotLayout.from( + key: const Key('medium'), + builder: (_) => const SizedBox( + key: Key('mediumBox'), width: 200, height: 200), + inAnimation: (Widget widget, Animation animation) => + ScaleTransition( + scale: animation, + child: widget, + ), + outAnimation: (Widget widget, Animation animation) => + FadeTransition( + opacity: animation, + child: widget, + ), + inDuration: const Duration(seconds: 1), + outDuration: const Duration(seconds: 2), + inCurve: Curves.easeIn, + outCurve: Curves.easeOut, + ), + }, + ), + ), + ); + } + + // Pump the widget with the SlotLayout at small breakpoint. + await tester.pumpWidget(buildSlotLayout(300)); + expect(find.byKey(const Key('smallBox')), findsOneWidget); + expect(find.byKey(const Key('mediumBox')), findsNothing); + + // Change to medium breakpoint to trigger outAnimation for small and inAnimation for medium. + await tester.pumpWidget(buildSlotLayout(600)); + await tester.pump(); // Start the animation. + await tester.pump(const Duration( + milliseconds: 1000)); // Halfway through the outDuration. + + // Verify that the outAnimation is in progress for smallBox. + final FadeTransition fadeTransitionMid = + tester.widget(find.byType(FadeTransition)); + expect(fadeTransitionMid.opacity.value, lessThan(1.0)); + expect(fadeTransitionMid.opacity.value, greaterThan(0.0)); + + // Complete the animation. + await tester.pumpAndSettle(); + expect(find.byKey(const Key('smallBox')), findsNothing); + expect(find.byKey(const Key('mediumBox')), findsOneWidget); + }, + ); +} diff --git a/packages/flutter_adaptive_scaffold/test/test_breakpoints.dart b/packages/flutter_adaptive_scaffold/test/test_breakpoints.dart index 2a54acd6b5cf..ea51ca637e8d 100644 --- a/packages/flutter_adaptive_scaffold/test/test_breakpoints.dart +++ b/packages/flutter_adaptive_scaffold/test/test_breakpoints.dart @@ -8,30 +8,46 @@ import 'package:flutter_adaptive_scaffold/src/breakpoints.dart'; class TestBreakpoint0 extends Breakpoint { @override bool isActive(BuildContext context) { - return MediaQuery.of(context).size.width >= 0 && - MediaQuery.of(context).size.width < 800; + return MediaQuery.sizeOf(context).width >= 0 && + MediaQuery.sizeOf(context).width < 800; } } class TestBreakpoint400 extends Breakpoint { @override bool isActive(BuildContext context) { - return MediaQuery.of(context).size.width > 400; + return MediaQuery.sizeOf(context).width > 400; } } class TestBreakpoint800 extends Breakpoint { @override bool isActive(BuildContext context) { - return MediaQuery.of(context).size.width >= 800 && - MediaQuery.of(context).size.width < 1000; + return MediaQuery.sizeOf(context).width >= 800 && + MediaQuery.sizeOf(context).width < 1000; } } class TestBreakpoint1000 extends Breakpoint { @override bool isActive(BuildContext context) { - return MediaQuery.of(context).size.width >= 1000; + return MediaQuery.sizeOf(context).width >= 1000 && + MediaQuery.sizeOf(context).width < 1200; + } +} + +class TestBreakpoint1200 extends Breakpoint { + @override + bool isActive(BuildContext context) { + return MediaQuery.sizeOf(context).width >= 1200 && + MediaQuery.sizeOf(context).width < 1600; + } +} + +class TestBreakpoint1600 extends Breakpoint { + @override + bool isActive(BuildContext context) { + return MediaQuery.sizeOf(context).width >= 1600; } } diff --git a/packages/flutter_image/CHANGELOG.md b/packages/flutter_image/CHANGELOG.md index c2553510b651..89538cfc0dde 100644 --- a/packages/flutter_image/CHANGELOG.md +++ b/packages/flutter_image/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 4.1.11 diff --git a/packages/flutter_image/example/android/.gitignore b/packages/flutter_image/example/android/.gitignore index 6f568019d3c6..55afd919c659 100644 --- a/packages/flutter_image/example/android/.gitignore +++ b/packages/flutter_image/example/android/.gitignore @@ -7,7 +7,7 @@ gradle-wrapper.jar GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. -# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +# See https://flutter.dev/to/reference-keystore key.properties **/*.keystore **/*.jks diff --git a/packages/flutter_image/example/android/app/build.gradle b/packages/flutter_image/example/android/app/build.gradle index dc2df2c455ef..c6be519fd577 100644 --- a/packages/flutter_image/example/android/app/build.gradle +++ b/packages/flutter_image/example/android/app/build.gradle @@ -31,12 +31,12 @@ android { ndkVersion flutter.ndkVersion compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '11' } sourceSets { diff --git a/packages/flutter_image/example/android/build.gradle b/packages/flutter_image/example/android/build.gradle index fdf447f8a7e6..4a9ad584b421 100644 --- a/packages/flutter_image/example/android/build.gradle +++ b/packages/flutter_image/example/android/build.gradle @@ -1,12 +1,12 @@ buildscript { - ext.kotlin_version = '1.7.10' + ext.kotlin_version = '1.9.0' repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.3.0' + classpath 'com.android.tools.build:gradle:8.5.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/packages/flutter_image/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/flutter_image/example/android/gradle/wrapper/gradle-wrapper.properties index e1ca574ef017..3c85cfe057a1 100644 --- a/packages/flutter_image/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/flutter_image/example/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/flutter_image/example/ios/Podfile b/packages/flutter_image/example/ios/Podfile index 279576f3884f..01d4aa611bb9 100644 --- a/packages/flutter_image/example/ios/Podfile +++ b/packages/flutter_image/example/ios/Podfile @@ -29,7 +29,6 @@ flutter_ios_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) end diff --git a/packages/flutter_image/example/macos/Podfile b/packages/flutter_image/example/macos/Podfile index 049abe295427..ae77cc1d4269 100644 --- a/packages/flutter_image/example/macos/Podfile +++ b/packages/flutter_image/example/macos/Podfile @@ -28,7 +28,6 @@ flutter_macos_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) end diff --git a/packages/flutter_image/example/pubspec.yaml b/packages/flutter_image/example/pubspec.yaml index cf8774613052..a7a03cb89c89 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: cupertino_icons: ^1.0.2 @@ -17,7 +17,6 @@ dependencies: path: "../" dev_dependencies: - flutter_lints: ^2.0.0 flutter_test: sdk: flutter integration_test: diff --git a/packages/flutter_image/example/web/index.html b/packages/flutter_image/example/web/index.html index e080bd4889aa..29f72bf6f773 100644 --- a/packages/flutter_image/example/web/index.html +++ b/packages/flutter_image/example/web/index.html @@ -35,29 +35,8 @@ example - - - - - + diff --git a/packages/flutter_image/pubspec.yaml b/packages/flutter_image/pubspec.yaml index 3507a03e6f2a..d721eb89c37d 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/flutter_lints/CHANGELOG.md b/packages/flutter_lints/CHANGELOG.md index f3cfed6ed689..a65e7e221228 100644 --- a/packages/flutter_lints/CHANGELOG.md +++ b/packages/flutter_lints/CHANGELOG.md @@ -1,6 +1,14 @@ -## NEXT - -* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. +## 5.0.0 + +* Updates `package:lints` dependency to version 5.0.0, with the following changes: + * adds `invalid_runtime_check_with_js_interop_types` + * adds `unnecessary_library_name` + * removes `avoid_null_checks_in_equality_operators` +* Removes the following lints (see https://github.com/dart-lang/lints/issues/205): + * `prefer_const_constructors` + * `prefer_const_declarations` + * `prefer_const_literals_to_create_immutables` +* Updates minimum supported SDK version to Flutter 3.24/Dart 3.5. ## 4.0.0 diff --git a/packages/flutter_lints/example/pubspec.yaml b/packages/flutter_lints/example/pubspec.yaml index f6575cc56e07..472307f440dd 100644 --- a/packages/flutter_lints/example/pubspec.yaml +++ b/packages/flutter_lints/example/pubspec.yaml @@ -4,10 +4,10 @@ description: A project that showcases how to enable the recommended lints for Fl publish_to: none environment: - sdk: ^3.2.0 + sdk: ^3.3.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` # file located next to this `pubspec.yaml` file. dev_dependencies: - flutter_lints: ^1.0.0 # Check https://pub.dev/packages/flutter_lints for latest version number. + flutter_lints: ^4.0.0 # Check https://pub.dev/packages/flutter_lints for latest version number. diff --git a/packages/flutter_lints/lib/flutter.yaml b/packages/flutter_lints/lib/flutter.yaml index bcad70fc1087..8c108e2b5b44 100644 --- a/packages/flutter_lints/lib/flutter.yaml +++ b/packages/flutter_lints/lib/flutter.yaml @@ -8,10 +8,7 @@ linter: - avoid_unnecessary_containers - avoid_web_libraries_in_flutter - no_logic_in_create_state - - prefer_const_constructors - prefer_const_constructors_in_immutables - - prefer_const_declarations - - prefer_const_literals_to_create_immutables - sized_box_for_whitespace - sort_child_properties_last - use_build_context_synchronously diff --git a/packages/flutter_lints/pubspec.yaml b/packages/flutter_lints/pubspec.yaml index b1a931bec31a..3aa9f13622ac 100644 --- a/packages/flutter_lints/pubspec.yaml +++ b/packages/flutter_lints/pubspec.yaml @@ -2,13 +2,13 @@ name: flutter_lints description: Recommended lints for Flutter apps, packages, and plugins to encourage good coding practices. repository: https://github.com/flutter/packages/tree/main/packages/flutter_lints issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_lints%22 -version: 4.0.0 +version: 5.0.0 environment: - sdk: ^3.2.0 + sdk: ^3.5.0 dependencies: - lints: ^4.0.0 + lints: ^5.0.0 # Code is not allowed in this package. Do not add any dependencies or dev_dependencies. topics: diff --git a/packages/flutter_markdown/CHANGELOG.md b/packages/flutter_markdown/CHANGELOG.md index f787fabbc054..002d6d150abd 100644 --- a/packages/flutter_markdown/CHANGELOG.md +++ b/packages/flutter_markdown/CHANGELOG.md @@ -1,3 +1,25 @@ +## 0.7.4+1 + +* Makes it so that custom blocks are not limited to being a Column or + SizedBox. + +## 0.7.4 + +* Makes paragraphs in blockquotes soft-wrap like a normal `
` instead of hard-wrapping like a `
` block.
+
+## 0.7.3+2
+
+* Resolves an issue where code blocks in markdown were not highlighted during selection.
+
+## 0.7.3+1
+
+* Fixes issue with table column alignments not being respected.
+* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3.
+
+## 0.7.3
+
+* Adds horizontal scrolling for table when using `tableColumnWidth: FixedColumnWidth(width)`.
+
 ## 0.7.2+1
 
 * Fixes a crash caused by text selection when `selectable` is true and `onSelectionChanged` is null.
diff --git a/packages/flutter_markdown/example/android/.gitignore b/packages/flutter_markdown/example/android/.gitignore
index 0a741cb43d66..8e599af9f211 100644
--- a/packages/flutter_markdown/example/android/.gitignore
+++ b/packages/flutter_markdown/example/android/.gitignore
@@ -7,5 +7,5 @@ gradle-wrapper.jar
 GeneratedPluginRegistrant.java
 
 # Remember to never publicly share your keystore.
-# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
+# See https://flutter.dev/to/reference-keystore
 key.properties
diff --git a/packages/flutter_markdown/example/android/app/build.gradle b/packages/flutter_markdown/example/android/app/build.gradle
index e542c8f72cb3..6b8f51a79916 100644
--- a/packages/flutter_markdown/example/android/app/build.gradle
+++ b/packages/flutter_markdown/example/android/app/build.gradle
@@ -28,6 +28,15 @@ apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
 android {
     compileSdk flutter.compileSdkVersion
 
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_11
+        targetCompatibility JavaVersion.VERSION_11
+    }
+
+    kotlinOptions {
+        jvmTarget = '11'
+    }
+
     sourceSets {
         main.java.srcDirs += 'src/main/kotlin'
     }
diff --git a/packages/flutter_markdown/example/android/build.gradle b/packages/flutter_markdown/example/android/build.gradle
index d13ef556e261..6f6453aefc39 100644
--- a/packages/flutter_markdown/example/android/build.gradle
+++ b/packages/flutter_markdown/example/android/build.gradle
@@ -1,12 +1,12 @@
 buildscript {
-    ext.kotlin_version = '1.7.10'
+    ext.kotlin_version = '1.9.0'
     repositories {
         google()
         mavenCentral()
     }
 
     dependencies {
-        classpath 'com.android.tools.build:gradle:7.4.2'
+        classpath 'com.android.tools.build:gradle:8.1.0'
         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
     }
 }
diff --git a/packages/flutter_markdown/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/flutter_markdown/example/android/gradle/wrapper/gradle-wrapper.properties
index aeaff6f869f3..7aeeb11c6ee5 100644
--- a/packages/flutter_markdown/example/android/gradle/wrapper/gradle-wrapper.properties
+++ b/packages/flutter_markdown/example/android/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip
diff --git a/packages/flutter_markdown/example/pubspec.yaml b/packages/flutter_markdown/example/pubspec.yaml
index c536ac0ce8d5..390eb0d27f26 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.2.0
-  flutter: ">=3.16.0"
+  sdk: ^3.3.0
+  flutter: ">=3.19.0"
 
 dependencies:
   flutter:
diff --git a/packages/flutter_markdown/example/web/index.html b/packages/flutter_markdown/example/web/index.html
index 97bf470a8359..f0596549e11d 100644
--- a/packages/flutter_markdown/example/web/index.html
+++ b/packages/flutter_markdown/example/web/index.html
@@ -33,16 +33,6 @@
   
 
 
-  
-  
-  
+  
 
 
diff --git a/packages/flutter_markdown/lib/src/builder.dart b/packages/flutter_markdown/lib/src/builder.dart
index 8e7c98abdc26..ea9af16acfbe 100644
--- a/packages/flutter_markdown/lib/src/builder.dart
+++ b/packages/flutter_markdown/lib/src/builder.dart
@@ -362,7 +362,7 @@ class MarkdownBuilder implements md.NodeVisitor {
           style: _isInBlockquote
               ? styleSheet.blockquote!.merge(_inlines.last.style)
               : _inlines.last.style,
-          text: _isInBlockquote ? text.text : trimText(text.text),
+          text: trimText(text.text),
           recognizer: _linkHandlers.isNotEmpty ? _linkHandlers.last : null,
         ),
         textAlign: _textAlignForBlockTag(_currentBlockTag),
@@ -383,20 +383,29 @@ class MarkdownBuilder implements md.NodeVisitor {
       _addAnonymousBlockIfNeeded();
 
       final _BlockElement current = _blocks.removeLast();
-      Widget child;
 
-      if (current.children.isNotEmpty) {
-        child = Column(
-          mainAxisSize: MainAxisSize.min,
-          crossAxisAlignment: fitContent
-              ? CrossAxisAlignment.start
-              : CrossAxisAlignment.stretch,
-          children: current.children,
-        );
-      } else {
-        child = const SizedBox();
+      Widget defaultChild() {
+        if (current.children.isNotEmpty) {
+          return Column(
+            mainAxisSize: MainAxisSize.min,
+            crossAxisAlignment: fitContent
+                ? CrossAxisAlignment.start
+                : CrossAxisAlignment.stretch,
+            children: current.children,
+          );
+        } else {
+          return const SizedBox();
+        }
       }
 
+      Widget child = builders[tag]?.visitElementAfterWithContext(
+            delegate.context,
+            element,
+            styleSheet.styles[tag],
+            _inlines.isNotEmpty ? _inlines.last.style : null,
+          ) ??
+          defaultChild();
+
       if (_isListTag(tag)) {
         assert(_listIndents.isNotEmpty);
         _listIndents.removeLast();
@@ -438,12 +447,20 @@ class MarkdownBuilder implements md.NodeVisitor {
           );
         }
       } else if (tag == 'table') {
-        child = Table(
-          defaultColumnWidth: styleSheet.tableColumnWidth!,
-          defaultVerticalAlignment: styleSheet.tableVerticalAlignment,
-          border: styleSheet.tableBorder,
-          children: _tables.removeLast().rows,
-        );
+        if (styleSheet.tableColumnWidth is FixedColumnWidth) {
+          final ScrollController tableScrollController = ScrollController();
+          child = Scrollbar(
+            controller: tableScrollController,
+            child: SingleChildScrollView(
+              controller: tableScrollController,
+              scrollDirection: Axis.horizontal,
+              padding: styleSheet.tablePadding,
+              child: _buildTable(),
+            ),
+          );
+        } else {
+          child = _buildTable();
+        }
       } else if (tag == 'blockquote') {
         _isInBlockquote = false;
         child = DecoratedBox(
@@ -558,6 +575,15 @@ class MarkdownBuilder implements md.NodeVisitor {
     _lastVisitedTag = tag;
   }
 
+  Table _buildTable() {
+    return Table(
+      defaultColumnWidth: styleSheet.tableColumnWidth!,
+      defaultVerticalAlignment: styleSheet.tableVerticalAlignment,
+      border: styleSheet.tableBorder,
+      children: _tables.removeLast().rows,
+    );
+  }
+
   Widget _buildImage(String src, String? title, String? alt) {
     final List parts = src.split('#');
     if (parts.isEmpty) {
@@ -653,7 +679,15 @@ class MarkdownBuilder implements md.NodeVisitor {
         child: DefaultTextStyle(
           style: styleSheet.tableBody!,
           textAlign: textAlign,
-          child: Wrap(children: children as List),
+          child: Wrap(
+            alignment: switch (textAlign) {
+              TextAlign.left => WrapAlignment.start,
+              TextAlign.center => WrapAlignment.center,
+              TextAlign.right => WrapAlignment.end,
+              _ => WrapAlignment.start,
+            },
+            children: children as List,
+          ),
         ),
       ),
     );
diff --git a/packages/flutter_markdown/lib/src/style_sheet.dart b/packages/flutter_markdown/lib/src/style_sheet.dart
index f3b570aeb914..0a6b1b430e72 100644
--- a/packages/flutter_markdown/lib/src/style_sheet.dart
+++ b/packages/flutter_markdown/lib/src/style_sheet.dart
@@ -38,6 +38,7 @@ class MarkdownStyleSheet {
     this.tableHead,
     this.tableBody,
     this.tableHeadAlign,
+    this.tablePadding,
     this.tableBorder,
     this.tableColumnWidth,
     this.tableCellsPadding,
@@ -103,7 +104,7 @@ class MarkdownStyleSheet {
       p: theme.textTheme.bodyMedium,
       pPadding: EdgeInsets.zero,
       code: theme.textTheme.bodyMedium!.copyWith(
-        backgroundColor: theme.cardTheme.color ?? theme.cardColor,
+        backgroundColor: theme.cardTheme.color,
         fontFamily: 'monospace',
         fontSize: theme.textTheme.bodyMedium!.fontSize! * 0.85,
       ),
@@ -134,6 +135,7 @@ class MarkdownStyleSheet {
       tableHead: const TextStyle(fontWeight: FontWeight.w600),
       tableBody: theme.textTheme.bodyMedium,
       tableHeadAlign: TextAlign.center,
+      tablePadding: const EdgeInsets.only(bottom: 4.0),
       tableBorder: TableBorder.all(
         color: theme.dividerColor,
       ),
@@ -173,9 +175,6 @@ class MarkdownStyleSheet {
       p: theme.textTheme.textStyle,
       pPadding: EdgeInsets.zero,
       code: theme.textTheme.textStyle.copyWith(
-        backgroundColor: theme.brightness == Brightness.dark
-            ? CupertinoColors.systemGrey6.darkColor
-            : CupertinoColors.systemGrey6.color,
         fontFamily: 'monospace',
         fontSize: theme.textTheme.textStyle.fontSize! * 0.85,
       ),
@@ -231,6 +230,7 @@ class MarkdownStyleSheet {
       ),
       tableBody: theme.textTheme.textStyle,
       tableHeadAlign: TextAlign.center,
+      tablePadding: const EdgeInsets.only(bottom: 8),
       tableBorder: TableBorder.all(color: CupertinoColors.separator, width: 0),
       tableColumnWidth: const FlexColumnWidth(),
       tableCellsPadding: const EdgeInsets.fromLTRB(16, 8, 16, 8),
@@ -281,7 +281,7 @@ class MarkdownStyleSheet {
       p: theme.textTheme.bodyMedium,
       pPadding: EdgeInsets.zero,
       code: theme.textTheme.bodyMedium!.copyWith(
-        backgroundColor: theme.cardTheme.color ?? theme.cardColor,
+        backgroundColor: theme.cardTheme.color,
         fontFamily: 'monospace',
         fontSize: theme.textTheme.bodyMedium!.fontSize! * 0.85,
       ),
@@ -312,6 +312,7 @@ class MarkdownStyleSheet {
       tableHead: const TextStyle(fontWeight: FontWeight.w600),
       tableBody: theme.textTheme.bodyMedium,
       tableHeadAlign: TextAlign.center,
+      tablePadding: const EdgeInsets.only(bottom: 4.0),
       tableBorder: TableBorder.all(
         color: theme.dividerColor,
       ),
@@ -371,6 +372,7 @@ class MarkdownStyleSheet {
     TextStyle? tableHead,
     TextStyle? tableBody,
     TextAlign? tableHeadAlign,
+    EdgeInsets? tablePadding,
     TableBorder? tableBorder,
     TableColumnWidth? tableColumnWidth,
     EdgeInsets? tableCellsPadding,
@@ -436,6 +438,7 @@ class MarkdownStyleSheet {
       tableHead: tableHead ?? this.tableHead,
       tableBody: tableBody ?? this.tableBody,
       tableHeadAlign: tableHeadAlign ?? this.tableHeadAlign,
+      tablePadding: tablePadding ?? this.tablePadding,
       tableBorder: tableBorder ?? this.tableBorder,
       tableColumnWidth: tableColumnWidth ?? this.tableColumnWidth,
       tableCellsPadding: tableCellsPadding ?? this.tableCellsPadding,
@@ -502,6 +505,7 @@ class MarkdownStyleSheet {
       tableHead: tableHead!.merge(other.tableHead),
       tableBody: tableBody!.merge(other.tableBody),
       tableHeadAlign: other.tableHeadAlign,
+      tablePadding: other.tablePadding,
       tableBorder: other.tableBorder,
       tableColumnWidth: other.tableColumnWidth,
       tableCellsPadding: other.tableCellsPadding,
@@ -620,6 +624,9 @@ class MarkdownStyleSheet {
   /// The [TextAlign] to use for `th` elements.
   final TextAlign? tableHeadAlign;
 
+  /// The padding to use for `table` elements.
+  final EdgeInsets? tablePadding;
+
   /// The [TableBorder] to use for `table` elements.
   final TableBorder? tableBorder;
 
@@ -740,6 +747,7 @@ class MarkdownStyleSheet {
         other.tableHead == tableHead &&
         other.tableBody == tableBody &&
         other.tableHeadAlign == tableHeadAlign &&
+        other.tablePadding == tablePadding &&
         other.tableBorder == tableBorder &&
         other.tableColumnWidth == tableColumnWidth &&
         other.tableCellsPadding == tableCellsPadding &&
@@ -798,6 +806,7 @@ class MarkdownStyleSheet {
       tableHead,
       tableBody,
       tableHeadAlign,
+      tablePadding,
       tableBorder,
       tableColumnWidth,
       tableCellsPadding,
diff --git a/packages/flutter_markdown/pubspec.yaml b/packages/flutter_markdown/pubspec.yaml
index f7b58ed28888..5f743a8b032a 100644
--- a/packages/flutter_markdown/pubspec.yaml
+++ b/packages/flutter_markdown/pubspec.yaml
@@ -4,7 +4,7 @@ description: A Markdown renderer for Flutter. Create rich text output,
   formatted with simple Markdown tags.
 repository: https://github.com/flutter/packages/tree/main/packages/flutter_markdown
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_markdown%22
-version: 0.7.2+1
+version: 0.7.4+1
 
 environment:
   sdk: ^3.3.0
@@ -20,7 +20,7 @@ dependencies:
 dev_dependencies:
   flutter_test:
     sdk: flutter
-  mockito: 5.4.4
+  mockito: ^5.4.4
   standard_message_codec: ^0.0.1+3
 
 topics:
diff --git a/packages/flutter_markdown/test/assets/images/golden/image_test/custom_builder_asset_logo_old.png b/packages/flutter_markdown/test/assets/images/golden/image_test/custom_builder_asset_logo_old.png
deleted file mode 100644
index cbf90d457504..000000000000
Binary files a/packages/flutter_markdown/test/assets/images/golden/image_test/custom_builder_asset_logo_old.png and /dev/null differ
diff --git a/packages/flutter_markdown/test/assets/images/golden/image_test/resource_asset_logo_old.png b/packages/flutter_markdown/test/assets/images/golden/image_test/resource_asset_logo_old.png
deleted file mode 100644
index cbf90d457504..000000000000
Binary files a/packages/flutter_markdown/test/assets/images/golden/image_test/resource_asset_logo_old.png and /dev/null differ
diff --git a/packages/flutter_markdown/test/blockquote_test.dart b/packages/flutter_markdown/test/blockquote_test.dart
index 2d1fa3e30a4c..07e88f4c9e09 100644
--- a/packages/flutter_markdown/test/blockquote_test.dart
+++ b/packages/flutter_markdown/test/blockquote_test.dart
@@ -25,6 +25,20 @@ void defineTests() {
       },
     );
 
+    testWidgets(
+      'soft wrapping in blockquote',
+      (WidgetTester tester) async {
+        await tester.pumpWidget(
+          boilerplate(
+            const MarkdownBody(data: '> soft\n> wrap'),
+          ),
+        );
+
+        final Iterable widgets = tester.allWidgets;
+        expectTextStrings(widgets, ['soft wrap']);
+      },
+    );
+
     testWidgets(
       'should work with styling',
       (WidgetTester tester) async {
diff --git a/packages/flutter_markdown/test/custom_syntax_test.dart b/packages/flutter_markdown/test/custom_syntax_test.dart
index 28d55cdfd0b5..8dc0c806e51f 100644
--- a/packages/flutter_markdown/test/custom_syntax_test.dart
+++ b/packages/flutter_markdown/test/custom_syntax_test.dart
@@ -59,6 +59,35 @@ void defineTests() {
       },
     );
 
+    testWidgets(
+      'Block with custom tag',
+      (WidgetTester tester) async {
+        const String textBefore = 'Before ';
+        const String textAfter = ' After';
+        const String blockContent = 'Custom content rendered in a ColoredBox';
+
+        await tester.pumpWidget(
+          boilerplate(
+            Markdown(
+              data:
+                  '$textBefore\n{{custom}}\n$blockContent\n{{/custom}}\n$textAfter',
+              extensionSet: md.ExtensionSet.none,
+              blockSyntaxes: [CustomTagBlockSyntax()],
+              builders: {
+                'custom': CustomTagBlockBuilder(),
+              },
+            ),
+          ),
+        );
+
+        final ColoredBox container =
+            tester.widgetList(find.byType(ColoredBox)).first as ColoredBox;
+        expect(container.color, Colors.red);
+        expect(container.child, isInstanceOf());
+        expect((container.child! as Text).data, blockContent);
+      },
+    );
+
     testWidgets(
       'link for wikistyle',
       (WidgetTester tester) async {
@@ -380,3 +409,54 @@ class NoteSyntax extends md.BlockSyntax {
   @override
   RegExp get pattern => RegExp(r'^\[!NOTE] ');
 }
+
+class CustomTagBlockBuilder extends MarkdownElementBuilder {
+  @override
+  bool isBlockElement() => true;
+
+  @override
+  Widget visitElementAfterWithContext(
+    BuildContext context,
+    md.Element element,
+    TextStyle? preferredStyle,
+    TextStyle? parentStyle,
+  ) {
+    if (element.tag == 'custom') {
+      final String content = element.attributes['content']!;
+      return ColoredBox(
+          color: Colors.red, child: Text(content, style: preferredStyle));
+    }
+    return const SizedBox.shrink();
+  }
+}
+
+class CustomTagBlockSyntax extends md.BlockSyntax {
+  @override
+  bool canParse(md.BlockParser parser) {
+    return parser.current.content.startsWith('{{custom}}');
+  }
+
+  @override
+  RegExp get pattern => RegExp(r'\{\{custom\}\}([\s\S]*?)\{\{/custom\}\}');
+
+  @override
+  md.Node parse(md.BlockParser parser) {
+    parser.advance();
+
+    final StringBuffer buffer = StringBuffer();
+    while (
+        !parser.current.content.startsWith('{{/custom}}') && !parser.isDone) {
+      buffer.writeln(parser.current.content);
+      parser.advance();
+    }
+
+    if (!parser.isDone) {
+      parser.advance();
+    }
+
+    final String content = buffer.toString().trim();
+    final md.Element element = md.Element.empty('custom');
+    element.attributes['content'] = content;
+    return element;
+  }
+}
diff --git a/packages/flutter_markdown/test/image_test.dart b/packages/flutter_markdown/test/image_test.dart
index c6f448eb8a68..00677f1b7284 100644
--- a/packages/flutter_markdown/test/image_test.dart
+++ b/packages/flutter_markdown/test/image_test.dart
@@ -13,8 +13,6 @@ import 'package:flutter_test/flutter_test.dart';
 import 'image_test_mocks.dart';
 import 'utils.dart';
 
-bool isRunningInStable = io.Platform.environment['CHANNEL'] == 'stable';
-
 void main() => defineTests();
 
 void defineTests() {
@@ -169,9 +167,8 @@ void defineTests() {
 
         await expectLater(
             find.byType(Container),
-            matchesGoldenFile(isRunningInStable
-                ? 'assets/images/golden/image_test/resource_asset_logo_old.png'
-                : 'assets/images/golden/image_test/resource_asset_logo.png'));
+            matchesGoldenFile(
+                'assets/images/golden/image_test/resource_asset_logo.png'));
       },
       skip: kIsWeb, // Goldens are platform-specific.
     );
@@ -416,9 +413,8 @@ void defineTests() {
 
         await expectLater(
             find.byType(Container),
-            matchesGoldenFile(isRunningInStable
-                ? 'assets/images/golden/image_test/custom_builder_asset_logo_old.png'
-                : 'assets/images/golden/image_test/custom_builder_asset_logo.png'));
+            matchesGoldenFile(
+                'assets/images/golden/image_test/custom_builder_asset_logo.png'));
       },
       skip: kIsWeb, // Goldens are platform-specific.
     );
diff --git a/packages/flutter_markdown/test/scrollable_test.dart b/packages/flutter_markdown/test/scrollable_test.dart
index 23092328f00d..1042a6fa98a8 100644
--- a/packages/flutter_markdown/test/scrollable_test.dart
+++ b/packages/flutter_markdown/test/scrollable_test.dart
@@ -110,5 +110,69 @@ void defineTests() {
         ]);
       },
     );
+
+    testWidgets(
+      'table',
+      (WidgetTester tester) async {
+        const String data = '|Header 1|Header 2|Header 3|'
+            '\n|-----|-----|-----|'
+            '\n|Col 1|Col 2|Col 3|';
+        await tester.pumpWidget(
+          boilerplate(
+            MediaQuery(
+              data: const MediaQueryData(),
+              child: MarkdownBody(
+                data: data,
+                styleSheet: MarkdownStyleSheet(
+                  tableColumnWidth: const FixedColumnWidth(150),
+                ),
+              ),
+            ),
+          ),
+        );
+
+        final Iterable widgets = tester.allWidgets;
+        final Iterable scrollViews =
+            widgets.whereType();
+        expect(scrollViews, isNotEmpty);
+        expect(scrollViews.first.controller, isNotNull);
+      },
+    );
+
+    testWidgets(
+      'two tables use different scroll controllers',
+      (WidgetTester tester) async {
+        const String data = '|Header 1|Header 2|Header 3|'
+            '\n|-----|-----|-----|'
+            '\n|Col 1|Col 2|Col 3|'
+            '\n'
+            '\n|Header 1|Header 2|Header 3|'
+            '\n|-----|-----|-----|'
+            '\n|Col 1|Col 2|Col 3|';
+
+        await tester.pumpWidget(
+          boilerplate(
+            MediaQuery(
+              data: const MediaQueryData(),
+              child: MarkdownBody(
+                data: data,
+                styleSheet: MarkdownStyleSheet(
+                  tableColumnWidth: const FixedColumnWidth(150),
+                ),
+              ),
+            ),
+          ),
+        );
+
+        final Iterable widgets = tester.allWidgets;
+        final Iterable scrollViews =
+            widgets.whereType();
+        expect(scrollViews, hasLength(2));
+        expect(scrollViews.first.controller, isNotNull);
+        expect(scrollViews.last.controller, isNotNull);
+        expect(scrollViews.first.controller,
+            isNot(equals(scrollViews.last.controller)));
+      },
+    );
   });
 }
diff --git a/packages/flutter_markdown/test/style_sheet_test.dart b/packages/flutter_markdown/test/style_sheet_test.dart
index b48465a415a0..30f071a15940 100644
--- a/packages/flutter_markdown/test/style_sheet_test.dart
+++ b/packages/flutter_markdown/test/style_sheet_test.dart
@@ -62,8 +62,6 @@ void defineTests() {
         expect(
             style.code!.fontSize, cTheme.textTheme.textStyle.fontSize! * 0.85);
         expect(style.code!.fontFamily, 'monospace');
-        expect(
-            style.code!.backgroundColor, CupertinoColors.systemGrey6.darkColor);
 
         // H1
         expect(style.h1!.color, cTheme.textTheme.textStyle.color);
@@ -152,7 +150,7 @@ void defineTests() {
         expect(
             style.code!.fontSize, theme.textTheme.bodyMedium!.fontSize! * 0.85);
         expect(style.code!.fontFamily, 'monospace');
-        expect(style.code!.backgroundColor, theme.cardColor);
+        expect(style.code!.backgroundColor, theme.cardTheme.color);
 
         // H1
         expect(style.h1, theme.textTheme.headlineSmall);
diff --git a/packages/flutter_markdown/test/table_test.dart b/packages/flutter_markdown/test/table_test.dart
index c67944ee0c3d..9a7a4daf87e5 100644
--- a/packages/flutter_markdown/test/table_test.dart
+++ b/packages/flutter_markdown/test/table_test.dart
@@ -63,6 +63,25 @@ void defineTests() {
       },
     );
 
+    testWidgets(
+      'should work with table alignments',
+      (WidgetTester tester) async {
+        const String data =
+            '|Header 1|Header 2|Header 3|\n|:----|:----:|----:|\n|Col 1|Col 2|Col 3|';
+        await tester.pumpWidget(
+          boilerplate(
+            const MarkdownBody(data: data),
+          ),
+        );
+
+        final Iterable wraps = tester.widgetList(find.byType(Wrap));
+
+        expect(wraps.first.alignment, WrapAlignment.start);
+        expect(wraps.elementAt(1).alignment, WrapAlignment.center);
+        expect(wraps.last.alignment, WrapAlignment.end);
+      },
+    );
+
     testWidgets(
       'should work with styling',
       (WidgetTester tester) async {
diff --git a/packages/flutter_migrate/CHANGELOG.md b/packages/flutter_migrate/CHANGELOG.md
index 84ae083e470c..2d132e53fc13 100644
--- a/packages/flutter_migrate/CHANGELOG.md
+++ b/packages/flutter_migrate/CHANGELOG.md
@@ -1,6 +1,7 @@
-## NEXT
+## 0.0.1+4
 
-* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2.
+* Adds `missing_code_block_language_in_doc_comment` lint.
+* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3.
 
 ## 0.0.1+3
 
diff --git a/packages/flutter_migrate/lib/src/base/common.dart b/packages/flutter_migrate/lib/src/base/common.dart
index 6612e3a30ee0..1bf38431b523 100644
--- a/packages/flutter_migrate/lib/src/base/common.dart
+++ b/packages/flutter_migrate/lib/src/base/common.dart
@@ -63,7 +63,7 @@ String getEnumName(dynamic enumItem) {
 /// Rationale:
 ///
 /// Consider the following snippet:
-/// ```
+/// ```dart
 /// try {
 ///   await foo();
 ///   ...
@@ -87,7 +87,7 @@ String getEnumName(dynamic enumItem) {
 /// [asyncGuard] is intended to wrap awaited expressions occurring in a `try`
 /// block. The behavior described above gives the behavior that users
 /// intuitively expect from `await`. Consider the snippet:
-/// ```
+/// ```dart
 /// try {
 ///   await asyncGuard(() async {
 ///     var c = Completer();
diff --git a/packages/flutter_migrate/lib/src/base/logger.dart b/packages/flutter_migrate/lib/src/base/logger.dart
index 70ff228a3901..92ba372c611a 100644
--- a/packages/flutter_migrate/lib/src/base/logger.dart
+++ b/packages/flutter_migrate/lib/src/base/logger.dart
@@ -1125,7 +1125,7 @@ class SpinnerStatus extends AnonymousSpinnerStatus {
 /// ```
 ///
 /// yields:
-/// ```
+/// ```none
 ///   Usage: app main_command 
 ///          [arguments]
 /// ```
diff --git a/packages/flutter_migrate/pubspec.yaml b/packages/flutter_migrate/pubspec.yaml
index 4b4090b80aeb..f1aafdf48cf0 100644
--- a/packages/flutter_migrate/pubspec.yaml
+++ b/packages/flutter_migrate/pubspec.yaml
@@ -1,26 +1,26 @@
 name: flutter_migrate
 description: A tool to migrate legacy flutter projects to modern versions.
-version: 0.0.1+3
+version: 0.0.1+4
 repository: https://github.com/flutter/packages/tree/main/packages/flutter_migrate
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3Ap%3A%20flutter_migrate
 publish_to: none
 
 environment:
-  sdk: ^3.2.0
+  sdk: ^3.3.0
 
 dependencies:
   args: ^2.3.1
-  convert: 3.0.2
-  file: 6.1.4
-  intl: 0.17.0
-  meta: 1.8.0
+  convert: ^3.0.2
+  file:  ">=6.0.0 <8.0.0"
+  intl: ">=0.17.0 <0.20.0"
+  meta: ^1.8.0
   path: ^1.8.0
-  process: 4.2.4
-  vm_service: 9.3.0
-  yaml: 3.1.1
+  process: ^4.2.4
+  vm_service: ^9.3.0
+  yaml: ^3.1.1
 
 dev_dependencies:
-  collection: 1.16.0
-  file_testing: 3.0.0
+  collection: ^1.16.0
+  file_testing: ^3.0.0
   lints: ^2.0.0
   test: ^1.16.0
diff --git a/packages/flutter_migrate/test/base/terminal_test.dart b/packages/flutter_migrate/test/base/terminal_test.dart
index 6686ec269bbe..6dec484d59bc 100644
--- a/packages/flutter_migrate/test/base/terminal_test.dart
+++ b/packages/flutter_migrate/test/base/terminal_test.dart
@@ -19,7 +19,7 @@ void main() {
       );
       bufferLogger.printStatus('0123456789' * 8);
 
-      expect(bufferLogger.statusText, equals(('${'0123456789' * 4}\n') * 2));
+      expect(bufferLogger.statusText, equals('${'0123456789' * 4}\n' * 2));
     });
 
     testWithoutContext('can turn off wrapping', () async {
diff --git a/packages/flutter_migrate/test/migrate_test.dart b/packages/flutter_migrate/test/migrate_test.dart
index beeddb329c86..f07085bfbd5c 100644
--- a/packages/flutter_migrate/test/migrate_test.dart
+++ b/packages/flutter_migrate/test/migrate_test.dart
@@ -382,10 +382,10 @@ flutter:
     - images/a_dot_ham.jpeg
 
   # An image asset can refer to one or more resolution-specific "variants", see
-  # https://flutter.dev/assets-and-images/#resolution-aware.
+  # https://flutter.dev/to/resolution-aware-images.
 
   # For details regarding adding assets from package dependencies, see
-  # https://flutter.dev/assets-and-images/#from-packages
+  # https://flutter.dev/to/asset-from-package
 
   # To add custom fonts to your application, add a fonts section here,
   # in this "flutter" section. Each entry in this list should have a
@@ -405,7 +405,7 @@ flutter:
   #         weight: 700
   #
   # For details regarding fonts from package dependencies,
-  # see https://flutter.dev/custom-fonts/#from-packages
+  # see https://flutter.dev/to/font-from-package
 
 ''', flush: true);
 
diff --git a/packages/flutter_migrate/test/test_data/migrate_project.dart b/packages/flutter_migrate/test/test_data/migrate_project.dart
index 4f3b4023e2c9..2590834a4c55 100644
--- a/packages/flutter_migrate/test/test_data/migrate_project.dart
+++ b/packages/flutter_migrate/test/test_data/migrate_project.dart
@@ -278,10 +278,10 @@ flutter:
     - images/a_dot_ham.jpeg
 
   # An image asset can refer to one or more resolution-specific "variants", see
-  # https://flutter.dev/assets-and-images/#resolution-aware.
+  # https://flutter.dev/to/resolution-aware-images.
 
   # For details regarding adding assets from package dependencies, see
-  # https://flutter.dev/assets-and-images/#from-packages
+  # https://flutter.dev/to/asset-from-package
 
   # To add custom fonts to your application, add a fonts section here,
   # in this "flutter" section. Each entry in this list should have a
@@ -301,7 +301,7 @@ flutter:
   #         weight: 700
   #
   # For details regarding fonts from package dependencies,
-  # see https://flutter.dev/custom-fonts/#from-packages
+  # see https://flutter.dev/to/font-from-package
 
 ''';
 }
diff --git a/packages/flutter_plugin_android_lifecycle/CHANGELOG.md b/packages/flutter_plugin_android_lifecycle/CHANGELOG.md
index b7082c02255f..f9c8ebd2d9c8 100644
--- a/packages/flutter_plugin_android_lifecycle/CHANGELOG.md
+++ b/packages/flutter_plugin_android_lifecycle/CHANGELOG.md
@@ -1,3 +1,16 @@
+## 2.0.23
+
+* Updates Java compatibility version to 11.
+* Updates minimum supported SDK version to Flutter 3.24/Dart 3.5.
+
+## 2.0.22
+
+* Bumps `com.android.tools.build:gradle` from 7.2.1 to 8.5.1.
+
+## 2.0.21
+
+* Updates lint checks to ignore NewerVersionAvailable.
+
 ## 2.0.20
 
 * Updates minimum supported SDK version to Flutter 3.22/Dart 3.4.
diff --git a/packages/flutter_plugin_android_lifecycle/README.md b/packages/flutter_plugin_android_lifecycle/README.md
index 6db96fb85e78..69a5be88f9df 100644
--- a/packages/flutter_plugin_android_lifecycle/README.md
+++ b/packages/flutter_plugin_android_lifecycle/README.md
@@ -13,10 +13,6 @@ major version of the Android `Lifecycle` API they expect.
 |-------------|---------|
 | **Support** | SDK 16+ |
 
-## Installation
-
-Add `flutter_plugin_android_lifecycle` as a [dependency in your pubspec.yaml file](https://flutter.dev/using-packages/).
-
 ## Example
 
 Use a `FlutterLifecycleAdapter` within another Flutter plugin's Android implementation, as shown
diff --git a/packages/flutter_plugin_android_lifecycle/android/build.gradle b/packages/flutter_plugin_android_lifecycle/android/build.gradle
index 2c4cce6f17be..6f897eed0f51 100644
--- a/packages/flutter_plugin_android_lifecycle/android/build.gradle
+++ b/packages/flutter_plugin_android_lifecycle/android/build.gradle
@@ -8,7 +8,7 @@ buildscript {
     }
 
     dependencies {
-        classpath 'com.android.tools.build:gradle:7.2.1'
+        classpath 'com.android.tools.build:gradle:8.5.1'
     }
 }
 
@@ -22,10 +22,7 @@ rootProject.allprojects {
 apply plugin: 'com.android.library'
 
 android {
-    // Conditional for compatibility with AGP <4.2.
-    if (project.android.hasProperty("namespace")) {
-        namespace 'io.flutter.plugins.flutter_plugin_android_lifecycle'
-    }
+    namespace 'io.flutter.plugins.flutter_plugin_android_lifecycle'
     compileSdk 34
 
     defaultConfig {
@@ -35,14 +32,14 @@ android {
     }
 
     compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_8
-        targetCompatibility JavaVersion.VERSION_1_8
+        sourceCompatibility JavaVersion.VERSION_11
+        targetCompatibility JavaVersion.VERSION_11
     }
 
     lintOptions {
         checkAllWarnings true
         warningsAsErrors true
-        disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency'
+        disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency', 'NewerVersionAvailable'
     }
 
     dependencies {
diff --git a/packages/flutter_plugin_android_lifecycle/example/android/app/build.gradle b/packages/flutter_plugin_android_lifecycle/example/android/app/build.gradle
index 19689e74b474..91563f97f794 100644
--- a/packages/flutter_plugin_android_lifecycle/example/android/app/build.gradle
+++ b/packages/flutter_plugin_android_lifecycle/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,8 +22,6 @@ if (flutterVersionName == null) {
     flutterVersionName = '1.0'
 }
 
-apply plugin: 'com.android.application'
-apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
 
 android {
     compileSdk flutter.compileSdkVersion
@@ -32,7 +31,7 @@ android {
         // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
         applicationId "io.flutter.plugins.flutter_plugin_android_lifecycle_example"
         minSdkVersion flutter.minSdkVersion
-        targetSdkVersion 28
+        targetSdkVersion 34
         versionCode flutterVersionCode.toInteger()
         versionName flutterVersionName
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
diff --git a/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/AndroidManifest.xml b/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/AndroidManifest.xml
index b203b2d8e214..64dfbc097ffd 100644
--- a/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/AndroidManifest.xml
+++ b/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/AndroidManifest.xml
@@ -4,6 +4,7 @@
         android:icon="@mipmap/ic_launcher">
          plugins.load(reader) }
-}
-
-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/"
+    repositories {
+        maven {
+            url "https://plugins.gradle.org/m2/"
+        }
+    }
+    dependencies {
+        classpath "gradle.plugin.com.google.cloud.artifactregistry:artifactregistry-gradle-plugin:2.2.1"
     }
-  }
-  dependencies {
-    classpath "gradle.plugin.com.google.cloud.artifactregistry:artifactregistry-gradle-plugin:2.2.1"
-  }
 }
-apply plugin: "com.google.cloud.artifactregistry.gradle-plugin"
+
+plugins {
+    id "dev.flutter.flutter-plugin-loader" version "1.0.0"
+    id "com.android.application" version "8.1.0" apply false
+    id "org.jetbrains.kotlin.android" version "1.7.10" apply false
+    id "com.google.cloud.artifactregistry.gradle-plugin" version "2.2.1"
+}
+
+include ":app"
diff --git a/packages/flutter_plugin_android_lifecycle/example/pubspec.yaml b/packages/flutter_plugin_android_lifecycle/example/pubspec.yaml
index 98ca0aebd4dc..82c37c6e77c1 100644
--- a/packages/flutter_plugin_android_lifecycle/example/pubspec.yaml
+++ b/packages/flutter_plugin_android_lifecycle/example/pubspec.yaml
@@ -3,8 +3,8 @@ description: Demonstrates how to use the flutter_plugin_android_lifecycle plugin
 publish_to: none
 
 environment:
-  sdk: ^3.4.0
-  flutter: ">=3.22.0"
+  sdk: ^3.5.0
+  flutter: ">=3.24.0"
 
 dependencies:
   flutter:
diff --git a/packages/flutter_plugin_android_lifecycle/pubspec.yaml b/packages/flutter_plugin_android_lifecycle/pubspec.yaml
index 30e358ac15b7..0e8bb6653a43 100644
--- a/packages/flutter_plugin_android_lifecycle/pubspec.yaml
+++ b/packages/flutter_plugin_android_lifecycle/pubspec.yaml
@@ -2,11 +2,11 @@ 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.20
+version: 2.0.23
 
 environment:
-  sdk: ^3.4.0
-  flutter: ">=3.22.0"
+  sdk: ^3.5.0
+  flutter: ">=3.24.0"
 
 flutter:
   plugin:
diff --git a/packages/flutter_template_images/CHANGELOG.md b/packages/flutter_template_images/CHANGELOG.md
index 69b55d397003..6cf915b7ff90 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.16/Dart 3.2.
+* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3.
 
 ## 4.2.1
 
diff --git a/packages/flutter_template_images/pubspec.yaml b/packages/flutter_template_images/pubspec.yaml
index b046675efae0..411d285db25d 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.2.0
+  sdk: ^3.3.0
 
 topics:
   - assets
diff --git a/packages/go_router/CHANGELOG.md b/packages/go_router/CHANGELOG.md
index c8eaab75a704..78abc879a9e9 100644
--- a/packages/go_router/CHANGELOG.md
+++ b/packages/go_router/CHANGELOG.md
@@ -1,3 +1,52 @@
+## 14.4.1
+
+- Adds `missing_code_block_language_in_doc_comment` lint.
+
+## 14.4.0
+
+- Adds current state getter on `GoRouter` that returns the current `GoRouterState`.
+
+## 14.3.0
+
+- Adds missing implementation for the routerNeglect parameter in GoRouter.
+
+## 14.2.9
+
+- Relaxes route path requirements. Both root and child routes can now start with or without '/'.
+
+## 14.2.8
+
+- Updated custom_stateful_shell_route example to better support swiping in TabView as well as demonstration of the use of PageView. 
+
+## 14.2.7
+
+- Fixes issue so that the parseRouteInformationWithContext can handle non-http Uris.
+
+## 14.2.6
+
+- Fixes replace and pushReplacement uri when only one route match in current route match list.
+
+## 14.2.5
+
+- Fixes an issue where android back button pops pages in the wrong order.
+
+## 14.2.4
+
+- Updates minimum supported SDK version to Flutter 3.19/Dart 3.3.
+- Fix GoRouter configuration in `upgrading.md`
+
+## 14.2.3
+
+- Fixes redirect example's signature in `route.dart`.
+
+## 14.2.2
+
+- Adds section for "Stateful nested navigation" to configuration.md.
+
+## 14.2.1
+
+- Makes GoRouterState lookup more robust.
+
 ## 14.2.0
 
 - Added proper `redirect` handling for `ShellRoute.$route` and `StatefulShellRoute.$route` for proper redirection handling in case of code generation.
diff --git a/packages/go_router/doc/configuration.md b/packages/go_router/doc/configuration.md
index bb3dba5e6ec5..6c4f1ec6ee4d 100644
--- a/packages/go_router/doc/configuration.md
+++ b/packages/go_router/doc/configuration.md
@@ -152,6 +152,105 @@ For a complete example, see the [ShellRoute
 sample](https://github.com/flutter/packages/tree/main/packages/go_router/example/lib/shell_route.dart)
 in the example/ directory.
 
+# Stateful nested navigation
+In addition to using nested navigation with for instance a BottomNavigationBar,
+many apps also require that state is maintained when navigating between 
+destinations. To accomplish this, use [StatefulShellRoute][] instead of 
+`ShellRoute`.
+
+StatefulShellRoute creates separate `Navigator`s for each of its nested [branches](https://pub.dev/documentation/go_router/latest/go_router/StatefulShellBranch-class.html)
+(i.e. parallel navigation trees), making it possible to build an app with 
+stateful nested navigation. The constructor [StatefulShellRoute.indexedStack](https://pub.dev/documentation/go_router/latest/go_router/StatefulShellRoute/StatefulShellRoute.indexedStack.html)
+provides a default implementation for managing the branch navigators, using an 
+`IndexedStack`. 
+
+When using StatefulShellRoute, routes aren't configured on the shell route 
+itself. Instead, they are configured for each of the branches. Example:
+
+
+```dart
+branches: [
+  // The route branch for the first tab of the bottom navigation bar.
+  StatefulShellBranch(
+    navigatorKey: _sectionANavigatorKey,
+    routes: [
+      GoRoute(
+        // The screen to display as the root in the first tab of the
+        // bottom navigation bar.
+        path: '/a',
+        builder: (BuildContext context, GoRouterState state) =>
+            const RootScreen(label: 'A', detailsPath: '/a/details'),
+        routes: [
+          // The details screen to display stacked on navigator of the
+          // first tab. This will cover screen A but not the application
+          // shell (bottom navigation bar).
+          GoRoute(
+            path: 'details',
+            builder: (BuildContext context, GoRouterState state) =>
+                const DetailsScreen(label: 'A'),
+          ),
+        ],
+      ),
+    ],
+  ),
+```
+
+Similar to ShellRoute, a builder must be provided to build the actual shell 
+Widget that encapsulates the branch navigation container. The latter is 
+implemented by the class [StatefulNavigationShell](https://pub.dev/documentation/go_router/latest/go_router/StatefulNavigationShell-class.html), 
+which is passed as the last argument to the builder function. Example:
+
+
+```dart
+StatefulShellRoute.indexedStack(
+  builder: (BuildContext context, GoRouterState state,
+      StatefulNavigationShell navigationShell) {
+    // Return the widget that implements the custom shell (in this case
+    // using a BottomNavigationBar). The StatefulNavigationShell is passed
+    // to be able access the state of the shell and to navigate to other
+    // branches in a stateful way.
+    return ScaffoldWithNavBar(navigationShell: navigationShell);
+  },
+```
+
+Within the custom shell widget, the StatefulNavigationShell is first and 
+foremost used as the child, or body, of the shell. Secondly, it is also used for   
+handling stateful switching between branches, as well as providing the currently 
+active branch index. Example:
+
+
+```dart
+@override
+Widget build(BuildContext context) {
+  return Scaffold(
+    // The StatefulNavigationShell from the associated StatefulShellRoute is
+    // directly passed as the body of the Scaffold.
+    body: navigationShell,
+    bottomNavigationBar: BottomNavigationBar(
+      // Here, the items of BottomNavigationBar are hard coded. In a real
+      // world scenario, the items would most likely be generated from the
+      // branches of the shell route, which can be fetched using
+      // `navigationShell.route.branches`.
+      items: const [
+        BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Section A'),
+        BottomNavigationBarItem(icon: Icon(Icons.work), label: 'Section B'),
+        BottomNavigationBarItem(icon: Icon(Icons.tab), label: 'Section C'),
+      ],
+      currentIndex: navigationShell.currentIndex,
+      // Navigate to the current location of the branch at the provided index
+      // when tapping an item in the BottomNavigationBar.
+      onTap: (int index) => navigationShell.goBranch(index),
+    ),
+  );
+}
+```
+
+For a complete example, see the [Stateful Nested 
+Navigation](https://github.com/flutter/packages/blob/main/packages/go_router/example/lib/stateful_shell_route.dart)
+in the example/ directory. 
+For further details, see the [StatefulShellRoute API
+documentation](https://pub.dev/documentation/go_router/latest/go_router/StatefulShellRoute-class.html).
+
 # Initial location
 
 The initial location is shown when the app first opens and there is no deep link
@@ -181,3 +280,4 @@ final _router = GoRouter(
 [GoRoute]: https://pub.dev/documentation/go_router/latest/go_router/GoRoute-class.html
 [GoRouterState]: https://pub.dev/documentation/go_router/latest/go_router/GoRouterState-class.html
 [ShellRoute]: https://pub.dev/documentation/go_router/latest/go_router/ShellRoute-class.html
+[StatefulShellRoute]: https://pub.dev/documentation/go_router/latest/go_router/StatefulShellRoute-class.html
diff --git a/packages/go_router/doc/navigation.md b/packages/go_router/doc/navigation.md
index af7d1b3bb1ae..efe667f706d1 100644
--- a/packages/go_router/doc/navigation.md
+++ b/packages/go_router/doc/navigation.md
@@ -49,6 +49,32 @@ widget.
 See [issue #102408](https://github.com/flutter/flutter/issues/102408)
 for details on what such an API might look like in go_router.
 
+## Disable browser history tracking when navigating 
+
+To disable browser history tracking when navigating, use the `neglect` method 
+of the `Router` class:
+
+```dart
+ElevatedButton(
+  onPressed: () => Router.neglect(
+    context,
+    () => context.go('/destination'),
+  ),
+  child: ...
+),
+```
+
+To disable browser history tracking for the **entire** application, set the 
+`routerNeglect` property of the `GoRouter` widget to `true`:
+```dart
+final _router = GoRouter(
+  routerNeglect: true,
+  routes: [
+    ...
+  ],
+);
+```
+
 ## Imperative navigation with Navigator
 You can continue using the Navigator to push and pop pages. Pages displayed in
 this way are not deep-linkable and will be replaced if any parent page that is
diff --git a/packages/go_router/doc/upgrading.md b/packages/go_router/doc/upgrading.md
index 72af6b91137f..418c994e412b 100644
--- a/packages/go_router/doc/upgrading.md
+++ b/packages/go_router/doc/upgrading.md
@@ -3,6 +3,7 @@ home screen and creating a GoRoute for each screen you would like to be
 deep-linkable.
 
 # Upgrade an app that uses Navigator
+
 To upgrade an app that is already using the Navigator for routing, start with
 a single route for the home screen:
 
@@ -37,6 +38,7 @@ aren't deep-linkable. You can gradually add more routes to the GoRouter
 configuration.
 
 # Upgrade an app that uses named routes
+
 An app that uses named routes can be migrated to go_router by changing each
 entry in the map to a GoRoute object and changing any calls to
 `Navigator.of(context).pushNamed` to `context.go()`.
@@ -57,7 +59,7 @@ Then the GoRouter configuration would look like this:
 
 ```dart
 GoRouter(
-  initialRoute: '/details',
+  initialLocation: '/details',
   routes: [
     GoRoute(
       path: '/',
diff --git a/packages/go_router/example/README.md b/packages/go_router/example/README.md
index cac540fa0f87..0d552507e463 100644
--- a/packages/go_router/example/README.md
+++ b/packages/go_router/example/README.md
@@ -31,7 +31,7 @@ An example to demonstrate how to use redirect to handle a synchronous sign-in fl
 An example to demonstrate how to use handle a sign-in flow with a stream authentication service.
 
 ## [Stateful Nested Navigation](https://github.com/flutter/packages/blob/main/packages/go_router/example/lib/stateful_shell_route.dart)
-`flutter run lib/stacked_shell_route.dart`
+`flutter run lib/stateful_shell_route.dart`
 
 An example to demonstrate how to use a `StatefulShellRoute` to create stateful nested navigation, with a
 `BottomNavigationBar`.
@@ -49,4 +49,4 @@ An example to demonstrate how to use a complex object as extra.
 ## [Books app](https://github.com/flutter/packages/blob/main/packages/go_router/example/lib/books)
 `flutter run lib/books/main.dart`
 
-A fully fledged example that showcases various go_router APIs.
\ No newline at end of file
+A fully fledged example that showcases various go_router APIs.
diff --git a/packages/go_router/example/android/.gitignore b/packages/go_router/example/android/.gitignore
index 6f568019d3c6..55afd919c659 100644
--- a/packages/go_router/example/android/.gitignore
+++ b/packages/go_router/example/android/.gitignore
@@ -7,7 +7,7 @@ gradle-wrapper.jar
 GeneratedPluginRegistrant.java
 
 # Remember to never publicly share your keystore.
-# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
+# See https://flutter.dev/to/reference-keystore
 key.properties
 **/*.keystore
 **/*.jks
diff --git a/packages/go_router/example/android/app/build.gradle b/packages/go_router/example/android/app/build.gradle
index 5ea125183af6..6453592dd8ba 100644
--- a/packages/go_router/example/android/app/build.gradle
+++ b/packages/go_router/example/android/app/build.gradle
@@ -29,12 +29,12 @@ android {
     compileSdk flutter.compileSdkVersion
 
     compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_8
-        targetCompatibility JavaVersion.VERSION_1_8
+        sourceCompatibility JavaVersion.VERSION_11
+        targetCompatibility JavaVersion.VERSION_11
     }
 
     kotlinOptions {
-        jvmTarget = '1.8'
+        jvmTarget = '11'
     }
 
     sourceSets {
diff --git a/packages/go_router/example/android/build.gradle b/packages/go_router/example/android/build.gradle
index 8a2e9e183dd7..ab596dbe21c5 100644
--- a/packages/go_router/example/android/build.gradle
+++ b/packages/go_router/example/android/build.gradle
@@ -1,12 +1,12 @@
 buildscript {
-    ext.kotlin_version = '1.7.10'
+    ext.kotlin_version = '1.9.0'
     repositories {
         google()
         mavenCentral()
     }
 
     dependencies {
-        classpath 'com.android.tools.build:gradle:7.4.2'
+        classpath 'com.android.tools.build:gradle:8.1.0'
         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
     }
 }
diff --git a/packages/go_router/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/go_router/example/android/gradle/wrapper/gradle-wrapper.properties
index aeaff6f869f3..7aeeb11c6ee5 100644
--- a/packages/go_router/example/android/gradle/wrapper/gradle-wrapper.properties
+++ b/packages/go_router/example/android/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip
diff --git a/packages/go_router/example/ios/Podfile b/packages/go_router/example/ios/Podfile
index 279576f3884f..01d4aa611bb9 100644
--- a/packages/go_router/example/ios/Podfile
+++ b/packages/go_router/example/ios/Podfile
@@ -29,7 +29,6 @@ flutter_ios_podfile_setup
 
 target 'Runner' do
   use_frameworks!
-  use_modular_headers!
 
   flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
 end
diff --git a/packages/go_router/example/lib/books/src/screens/books.dart b/packages/go_router/example/lib/books/src/screens/books.dart
index c3d8dc8083b3..57fb60f645e3 100644
--- a/packages/go_router/example/lib/books/src/screens/books.dart
+++ b/packages/go_router/example/lib/books/src/screens/books.dart
@@ -107,7 +107,6 @@ class _BooksScreenState extends State
       case 0:
       default:
         context.go('/books/popular');
-        break;
     }
   }
 }
diff --git a/packages/go_router/example/lib/others/custom_stateful_shell_route.dart b/packages/go_router/example/lib/others/custom_stateful_shell_route.dart
index 5af1504234ac..49c040cf2a63 100644
--- a/packages/go_router/example/lib/others/custom_stateful_shell_route.dart
+++ b/packages/go_router/example/lib/others/custom_stateful_shell_route.dart
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 import 'package:collection/collection.dart';
+import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:go_router/go_router.dart';
 
@@ -10,6 +11,10 @@ final GlobalKey _rootNavigatorKey =
     GlobalKey(debugLabel: 'root');
 final GlobalKey _tabANavigatorKey =
     GlobalKey(debugLabel: 'tabANav');
+@visibleForTesting
+// ignore: public_member_api_docs
+final GlobalKey tabbedRootScreenKey =
+    GlobalKey(debugLabel: 'TabbedRootScreen');
 
 // This example demonstrates how to setup nested navigation using a
 // BottomNavigationBar, where each bar item uses its own persistent navigator,
@@ -52,6 +57,8 @@ class NestedTabNavigationExampleApp extends StatelessWidget {
           // are managed (using AnimatedBranchContainer).
           return ScaffoldWithNavBar(
               navigationShell: navigationShell, children: children);
+          // NOTE: To use a Cupertino version of ScaffoldWithNavBar, replace
+          // ScaffoldWithNavBar above with CupertinoScaffoldWithNavBar.
         },
         branches: [
           // The route branch for the first tab of the bottom navigation bar.
@@ -78,13 +85,13 @@ class NestedTabNavigationExampleApp extends StatelessWidget {
             ],
           ),
 
-          // The route branch for the third tab of the bottom navigation bar.
+          // The route branch for the second tab of the bottom navigation bar.
           StatefulShellBranch(
             // StatefulShellBranch will automatically use the first descendant
             // GoRoute as the initial location of the branch. If another route
             // is desired, specify the location of it using the defaultLocation
             // parameter.
-            // defaultLocation: '/c2',
+            // defaultLocation: '/b2',
             routes: [
               StatefulShellRoute(
                 builder: (BuildContext context, GoRouterState state,
@@ -102,7 +109,12 @@ class NestedTabNavigationExampleApp extends StatelessWidget {
                   // See TabbedRootScreen for more details on how the children
                   // are managed (in a TabBarView).
                   return TabbedRootScreen(
-                      navigationShell: navigationShell, children: children);
+                    navigationShell: navigationShell,
+                    key: tabbedRootScreenKey,
+                    children: children,
+                  );
+                  // NOTE: To use a PageView version of TabbedRootScreen,
+                  // replace TabbedRootScreen above with PagedRootScreen.
                 },
                 // This bottom tab uses a nested shell, wrapping sub routes in a
                 // top TabBar.
@@ -222,6 +234,70 @@ class ScaffoldWithNavBar extends StatelessWidget {
   }
 }
 
+/// Alternative version of [ScaffoldWithNavBar], using a [CupertinoTabScaffold].
+// ignore: unused_element, unreachable_from_main
+class CupertinoScaffoldWithNavBar extends StatefulWidget {
+  /// Constructs an [ScaffoldWithNavBar].
+  // ignore: unreachable_from_main
+  const CupertinoScaffoldWithNavBar({
+    required this.navigationShell,
+    required this.children,
+    Key? key,
+  }) : super(key: key ?? const ValueKey('ScaffoldWithNavBar'));
+
+  /// The navigation shell and container for the branch Navigators.
+  // ignore: unreachable_from_main
+  final StatefulNavigationShell navigationShell;
+
+  /// The children (branch Navigators) to display in a custom container
+  /// ([AnimatedBranchContainer]).
+  // ignore: unreachable_from_main
+  final List children;
+
+  @override
+  State createState() => _CupertinoScaffoldWithNavBarState();
+}
+
+class _CupertinoScaffoldWithNavBarState
+    extends State {
+  late final CupertinoTabController tabController =
+      CupertinoTabController(initialIndex: widget.navigationShell.currentIndex);
+
+  @override
+  void dispose() {
+    tabController.dispose();
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return CupertinoTabScaffold(
+      controller: tabController,
+      tabBar: CupertinoTabBar(
+        items: const [
+          BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Section A'),
+          BottomNavigationBarItem(icon: Icon(Icons.work), label: 'Section B'),
+        ],
+        currentIndex: widget.navigationShell.currentIndex,
+        onTap: (int index) => _onTap(context, index),
+      ),
+      // Note: It is common to use CupertinoTabView for the tabBuilder when
+      // using CupertinoTabScaffold and CupertinoTabBar. This would however be
+      // redundant when using StatefulShellRoute, since a separate Navigator is
+      // already created for each branch, meaning we can simply use the branch
+      // Navigator Widgets (i.e. widget.children) directly.
+      tabBuilder: (BuildContext context, int index) => widget.children[index],
+    );
+  }
+
+  void _onTap(BuildContext context, int index) {
+    widget.navigationShell.goBranch(
+      index,
+      initialLocation: index == widget.navigationShell.currentIndex,
+    );
+  }
+}
+
 /// Custom branch Navigator container that provides animated transitions
 /// when switching branches.
 class AnimatedBranchContainer extends StatelessWidget {
@@ -271,7 +347,7 @@ class RootScreenA extends StatelessWidget {
   Widget build(BuildContext context) {
     return Scaffold(
       appBar: AppBar(
-        title: const Text('Root of section A'),
+        title: const Text('Section A root'),
       ),
       body: Center(
         child: Column(
@@ -386,20 +462,43 @@ class TabbedRootScreen extends StatefulWidget {
   final List children;
 
   @override
-  State createState() => _TabbedRootScreenState();
+  State createState() => TabbedRootScreenState();
 }
 
-class _TabbedRootScreenState extends State
+@visibleForTesting
+// ignore: public_member_api_docs
+class TabbedRootScreenState extends State
     with SingleTickerProviderStateMixin {
-  late final TabController _tabController = TabController(
+  @visibleForTesting
+  // ignore: public_member_api_docs
+  late final TabController tabController = TabController(
       length: widget.children.length,
       vsync: this,
       initialIndex: widget.navigationShell.currentIndex);
 
+  void _switchedTab() {
+    if (tabController.index != widget.navigationShell.currentIndex) {
+      widget.navigationShell.goBranch(tabController.index);
+    }
+  }
+
+  @override
+  void initState() {
+    super.initState();
+    tabController.addListener(_switchedTab);
+  }
+
+  @override
+  void dispose() {
+    tabController.removeListener(_switchedTab);
+    tabController.dispose();
+    super.dispose();
+  }
+
   @override
   void didUpdateWidget(covariant TabbedRootScreen oldWidget) {
     super.didUpdateWidget(oldWidget);
-    _tabController.index = widget.navigationShell.currentIndex;
+    tabController.index = widget.navigationShell.currentIndex;
   }
 
   @override
@@ -410,14 +509,15 @@ class _TabbedRootScreenState extends State
 
     return Scaffold(
       appBar: AppBar(
-          title: const Text('Root of Section B (nested TabBar shell)'),
+          title: Text(
+              'Section B root (tab: ${widget.navigationShell.currentIndex + 1})'),
           bottom: TabBar(
-            controller: _tabController,
+            controller: tabController,
             tabs: tabs,
             onTap: (int tappedIndex) => _onTabTap(context, tappedIndex),
           )),
       body: TabBarView(
-        controller: _tabController,
+        controller: tabController,
         children: widget.children,
       ),
     );
@@ -428,6 +528,84 @@ class _TabbedRootScreenState extends State
   }
 }
 
+/// Alternative implementation of TabbedRootScreen, demonstrating the use of
+/// a [PageView].
+// ignore: unreachable_from_main
+class PagedRootScreen extends StatefulWidget {
+  /// Constructs a PagedRootScreen
+  // ignore: unreachable_from_main
+  const PagedRootScreen(
+      {required this.navigationShell, required this.children, super.key});
+
+  /// The current state of the parent StatefulShellRoute.
+  // ignore: unreachable_from_main
+  final StatefulNavigationShell navigationShell;
+
+  /// The children (branch Navigators) to display in the [TabBarView].
+  // ignore: unreachable_from_main
+  final List children;
+
+  @override
+  State createState() => _PagedRootScreenState();
+}
+
+/// Alternative implementation _TabbedRootScreenState, demonstrating the use of
+/// a PageView.
+class _PagedRootScreenState extends State {
+  late final PageController _pageController = PageController(
+    initialPage: widget.navigationShell.currentIndex,
+  );
+
+  @override
+  void dispose() {
+    _pageController.dispose();
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: Text(
+            'Section B root (tab ${widget.navigationShell.currentIndex + 1})'),
+      ),
+      body: Column(
+        children: [
+          Row(
+              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+              children: [
+                ElevatedButton(
+                  onPressed: () => _animateToPage(0),
+                  child: const Text('Tab 1'),
+                ),
+                ElevatedButton(
+                  onPressed: () => _animateToPage(1),
+                  child: const Text('Tab 2'),
+                ),
+              ]),
+          Expanded(
+            child: PageView(
+              onPageChanged: (int i) => widget.navigationShell.goBranch(i),
+              controller: _pageController,
+              children: widget.children,
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+
+  void _animateToPage(int index) {
+    if (_pageController.hasClients) {
+      _pageController.animateToPage(
+        index,
+        duration: const Duration(milliseconds: 500),
+        curve: Curves.bounceOut,
+      );
+    }
+  }
+}
+
 /// Widget for the pages in the top tab bar.
 class TabScreen extends StatelessWidget {
   /// Creates a RootScreen
diff --git a/packages/go_router/example/lib/others/router_neglect.dart b/packages/go_router/example/lib/others/router_neglect.dart
index 75686a1df594..6660f0ee2708 100644
--- a/packages/go_router/example/lib/others/router_neglect.dart
+++ b/packages/go_router/example/lib/others/router_neglect.dart
@@ -22,8 +22,9 @@ class App extends StatelessWidget {
       );
 
   final GoRouter _router = GoRouter(
-    // turn off history tracking in the browser for this navigation
-    routerNeglect: true,
+    // To turn off history tracking in the browser for the entire application,
+    // set routerNeglect to true:
+    // routerNeglect: true,
     routes: [
       GoRoute(
         path: '/',
diff --git a/packages/go_router/example/lib/stateful_shell_route.dart b/packages/go_router/example/lib/stateful_shell_route.dart
index 9901619d7ce9..e6f0e7a1c0c6 100644
--- a/packages/go_router/example/lib/stateful_shell_route.dart
+++ b/packages/go_router/example/lib/stateful_shell_route.dart
@@ -28,6 +28,7 @@ class NestedTabNavigationExampleApp extends StatelessWidget {
     navigatorKey: _rootNavigatorKey,
     initialLocation: '/a',
     routes: [
+      // #docregion configuration-builder
       StatefulShellRoute.indexedStack(
         builder: (BuildContext context, GoRouterState state,
             StatefulNavigationShell navigationShell) {
@@ -37,6 +38,8 @@ class NestedTabNavigationExampleApp extends StatelessWidget {
           // branches in a stateful way.
           return ScaffoldWithNavBar(navigationShell: navigationShell);
         },
+        // #enddocregion configuration-builder
+        // #docregion configuration-branches
         branches: [
           // The route branch for the first tab of the bottom navigation bar.
           StatefulShellBranch(
@@ -61,6 +64,7 @@ class NestedTabNavigationExampleApp extends StatelessWidget {
               ),
             ],
           ),
+          // #enddocregion configuration-branches
 
           // The route branch for the second tab of the bottom navigation bar.
           StatefulShellBranch(
@@ -145,9 +149,12 @@ class ScaffoldWithNavBar extends StatelessWidget {
   /// The navigation shell and container for the branch Navigators.
   final StatefulNavigationShell navigationShell;
 
+  // #docregion configuration-custom-shell
   @override
   Widget build(BuildContext context) {
     return Scaffold(
+      // The StatefulNavigationShell from the associated StatefulShellRoute is
+      // directly passed as the body of the Scaffold.
       body: navigationShell,
       bottomNavigationBar: BottomNavigationBar(
         // Here, the items of BottomNavigationBar are hard coded. In a real
@@ -160,13 +167,18 @@ class ScaffoldWithNavBar extends StatelessWidget {
           BottomNavigationBarItem(icon: Icon(Icons.tab), label: 'Section C'),
         ],
         currentIndex: navigationShell.currentIndex,
-        onTap: (int index) => _onTap(context, index),
+        // Navigate to the current location of the branch at the provided index
+        // when tapping an item in the BottomNavigationBar.
+        onTap: (int index) => navigationShell.goBranch(index),
       ),
     );
   }
+  // #enddocregion configuration-custom-shell
 
-  /// Navigate to the current location of the branch at the provided index when
-  /// tapping an item in the BottomNavigationBar.
+  /// NOTE: For a slightly more sophisticated branch switching, change the onTap
+  /// handler on the BottomNavigationBar above to the following:
+  /// `onTap: (int index) => _onTap(context, index),`
+  // ignore: unused_element
   void _onTap(BuildContext context, int index) {
     // When navigating to a new branch, it's recommended to use the goBranch
     // method, as doing so makes sure the last navigation state of the
diff --git a/packages/go_router/example/macos/Podfile b/packages/go_router/example/macos/Podfile
index 049abe295427..ae77cc1d4269 100644
--- a/packages/go_router/example/macos/Podfile
+++ b/packages/go_router/example/macos/Podfile
@@ -28,7 +28,6 @@ flutter_macos_podfile_setup
 
 target 'Runner' do
   use_frameworks!
-  use_modular_headers!
 
   flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))
 end
diff --git a/packages/go_router/example/pubspec.yaml b/packages/go_router/example/pubspec.yaml
index eb4fd432ea46..40a65efc4311 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.2.0
-  flutter: ">=3.16.0"
+  sdk: ^3.3.0
+  flutter: ">=3.19.0"
 
 dependencies:
   adaptive_navigation: ^0.0.4
diff --git a/packages/go_router/example/test/custom_stateful_shell_route_test.dart b/packages/go_router/example/test/custom_stateful_shell_route_test.dart
new file mode 100644
index 000000000000..4a001a9dc562
--- /dev/null
+++ b/packages/go_router/example/test/custom_stateful_shell_route_test.dart
@@ -0,0 +1,32 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:go_router_examples/others/custom_stateful_shell_route.dart';
+
+void main() {
+  testWidgets(
+      'Changing active tab in TabController of TabbedRootScreen (root screen '
+      'of branch/section B) correctly navigates to appropriate screen',
+      (WidgetTester tester) async {
+    await tester.pumpWidget(NestedTabNavigationExampleApp());
+    expect(find.text('Screen A'), findsOneWidget);
+
+    // navigate to ScreenB
+    await tester.tap(find.text('Section B'));
+    await tester.pumpAndSettle();
+    expect(find.text('Screen B1'), findsOneWidget);
+
+    // Get TabController from TabbedRootScreen (root screen of branch/section B)
+    final TabController? tabController =
+        tabbedRootScreenKey.currentState?.tabController;
+    expect(tabController, isNotNull);
+
+    // Simulate swiping TabView to change active tab in TabController
+    tabbedRootScreenKey.currentState?.tabController.index = 1;
+    await tester.pumpAndSettle();
+    expect(find.text('Screen B2'), findsOneWidget);
+  });
+}
diff --git a/packages/go_router/example/web/index.html b/packages/go_router/example/web/index.html
index 26266a4f3870..0bebdc353df0 100644
--- a/packages/go_router/example/web/index.html
+++ b/packages/go_router/example/web/index.html
@@ -30,72 +30,6 @@
   
 
 
-  
-  
+  
 
 
diff --git a/packages/go_router/lib/fix_data.yaml b/packages/go_router/lib/fix_data.yaml
index 6a20a7de55ab..9770fd40004b 100644
--- a/packages/go_router/lib/fix_data.yaml
+++ b/packages/go_router/lib/fix_data.yaml
@@ -3,7 +3,7 @@
 # found in the LICENSE file.
 
 # For details regarding the *Flutter Fix* feature, see
-# https://flutter.dev/docs/development/tools/flutter-fix
+# https://flutter.dev/to/flutter-fix
 
 # Please add new fixes to the top of the file, separated by one blank line
 # from other fixes. In a comment, include a link to the PR where the change
diff --git a/packages/go_router/lib/src/builder.dart b/packages/go_router/lib/src/builder.dart
index 49b6372c6933..01c9b8c21977 100644
--- a/packages/go_router/lib/src/builder.dart
+++ b/packages/go_router/lib/src/builder.dart
@@ -98,7 +98,8 @@ class RouteBuilder {
   Widget build(
     BuildContext context,
     RouteMatchList matchList,
-    bool routerNeglect,
+    bool routerNeglect, // TODO(tolo): This parameter is not used and should be
+    // removed in the next major version.
   ) {
     if (matchList.isEmpty && !matchList.isError) {
       // The build method can be called before async redirect finishes. Build a
diff --git a/packages/go_router/lib/src/configuration.dart b/packages/go_router/lib/src/configuration.dart
index d1cca5ce61f4..cc671066218d 100644
--- a/packages/go_router/lib/src/configuration.dart
+++ b/packages/go_router/lib/src/configuration.dart
@@ -36,12 +36,9 @@ class RouteConfiguration {
     for (final RouteBase route in routes) {
       late bool subRouteIsTopLevel;
       if (route is GoRoute) {
-        if (isTopLevel) {
-          assert(route.path.startsWith('/'),
-              'top-level path must start with "/": $route');
-        } else {
-          assert(!route.path.startsWith('/') && !route.path.endsWith('/'),
-              'sub-route path may not start or end with "/": $route');
+        if (route.path != '/') {
+          assert(!route.path.endsWith('/'),
+              'route path may not end with "/" except for the top "/" route. Found: $route');
         }
         subRouteIsTopLevel = false;
       } else if (route is ShellRouteBase) {
@@ -150,7 +147,8 @@ class RouteConfiguration {
                 'The default location of a StatefulShellBranch cannot be '
                 'a parameterized route');
           } else {
-            final RouteMatchList matchList = findMatch(branch.initialLocation!);
+            final RouteMatchList matchList =
+                findMatch(Uri.parse(branch.initialLocation!));
             assert(
                 !matchList.isError,
                 'initialLocation (${matchList.uri}) of StatefulShellBranch must '
@@ -292,9 +290,7 @@ class RouteConfiguration {
   }
 
   /// Finds the routes that matched the given URL.
-  RouteMatchList findMatch(String location, {Object? extra}) {
-    final Uri uri = Uri.parse(canonicalUri(location));
-
+  RouteMatchList findMatch(Uri uri, {Object? extra}) {
     final Map pathParameters = {};
     final List matches =
         _getLocRouteMatches(uri, pathParameters);
@@ -315,14 +311,13 @@ class RouteConfiguration {
 
   /// Reparse the input RouteMatchList
   RouteMatchList reparse(RouteMatchList matchList) {
-    RouteMatchList result =
-        findMatch(matchList.uri.toString(), extra: matchList.extra);
+    RouteMatchList result = findMatch(matchList.uri, extra: matchList.extra);
 
     for (final ImperativeRouteMatch imperativeMatch
         in matchList.matches.whereType()) {
       final ImperativeRouteMatch match = ImperativeRouteMatch(
           pageKey: imperativeMatch.pageKey,
-          matches: findMatch(imperativeMatch.matches.uri.toString(),
+          matches: findMatch(imperativeMatch.matches.uri,
               extra: imperativeMatch.matches.extra),
           completer: imperativeMatch.completer);
       result = result.push(match);
@@ -461,7 +456,7 @@ class RouteConfiguration {
     List redirectHistory,
   ) {
     try {
-      final RouteMatchList newMatch = findMatch(newLocation);
+      final RouteMatchList newMatch = findMatch(Uri.parse(newLocation));
       _addRedirect(redirectHistory, newMatch, previousLocation);
       return newMatch;
     } on GoException catch (e) {
diff --git a/packages/go_router/lib/src/delegate.dart b/packages/go_router/lib/src/delegate.dart
index eba3ef0c8011..94496657ed78 100644
--- a/packages/go_router/lib/src/delegate.dart
+++ b/packages/go_router/lib/src/delegate.dart
@@ -13,6 +13,7 @@ import 'configuration.dart';
 import 'match.dart';
 import 'misc/errors.dart';
 import 'route.dart';
+import 'state.dart';
 
 /// GoRouter implementation of [RouterDelegate].
 class GoRouterDelegate extends RouterDelegate
@@ -46,27 +47,15 @@ class GoRouterDelegate extends RouterDelegate
   late final RouteBuilder builder;
 
   /// Set to true to disable creating history entries on the web.
+  // TODO(tolo): This field is obsolete and should be removed in the next major
+  // version.
   final bool routerNeglect;
 
   final RouteConfiguration _configuration;
 
   @override
   Future popRoute() async {
-    NavigatorState? state = navigatorKey.currentState;
-    if (state == null) {
-      return false;
-    }
-    if (!state.canPop()) {
-      state = null;
-    }
-    RouteMatchBase walker = currentConfiguration.matches.last;
-    while (walker is ShellRouteMatch) {
-      if (walker.navigatorKey.currentState?.canPop() ?? false) {
-        state = walker.navigatorKey.currentState;
-      }
-      walker = walker.matches.last;
-    }
-    assert(walker is RouteMatch);
+    final NavigatorState? state = _findCurrentNavigator();
     if (state != null) {
       return state.maybePop();
     }
@@ -75,7 +64,8 @@ class GoRouterDelegate extends RouterDelegate
     if (lastRoute.onExit != null && navigatorKey.currentContext != null) {
       return !(await lastRoute.onExit!(
         navigatorKey.currentContext!,
-        walker.buildState(_configuration, currentConfiguration),
+        currentConfiguration.last
+            .buildState(_configuration, currentConfiguration),
       ));
     }
     return false;
@@ -98,21 +88,33 @@ class GoRouterDelegate extends RouterDelegate
 
   /// Pops the top-most route.
   void pop([T? result]) {
+    final NavigatorState? state = _findCurrentNavigator();
+    if (state == null) {
+      throw GoError('There is nothing to pop');
+    }
+    state.pop(result);
+  }
+
+  NavigatorState? _findCurrentNavigator() {
     NavigatorState? state;
     if (navigatorKey.currentState?.canPop() ?? false) {
       state = navigatorKey.currentState;
     }
     RouteMatchBase walker = currentConfiguration.matches.last;
     while (walker is ShellRouteMatch) {
-      if (walker.navigatorKey.currentState?.canPop() ?? false) {
+      final NavigatorState potentialCandidate =
+          walker.navigatorKey.currentState!;
+      if (!ModalRoute.of(potentialCandidate.context)!.isCurrent) {
+        // There is a pageless route on top of the shell route. it needs to be
+        // popped first.
+        break;
+      }
+      if (potentialCandidate.canPop()) {
         state = walker.navigatorKey.currentState;
       }
       walker = walker.matches.last;
     }
-    if (state == null) {
-      throw GoError('There is nothing to pop');
-    }
-    state.pop(result);
+    return state;
   }
 
   void _debugAssertMatchListNotEmpty() {
@@ -168,6 +170,11 @@ class GoRouterDelegate extends RouterDelegate
     }());
   }
 
+  /// The top [GoRouterState], the state of the route that was
+  /// last used in either [GoRouter.go] or [GoRouter.push].
+  GoRouterState? get state => currentConfiguration.last
+      .buildState(_configuration, currentConfiguration);
+
   /// For use by the Router architecture as part of the RouterDelegate.
   GlobalKey get navigatorKey => _configuration.navigatorKey;
 
diff --git a/packages/go_router/lib/src/information_provider.dart b/packages/go_router/lib/src/information_provider.dart
index dc979193b325..75d9dec01137 100644
--- a/packages/go_router/lib/src/information_provider.dart
+++ b/packages/go_router/lib/src/information_provider.dart
@@ -79,18 +79,22 @@ class GoRouteInformationProvider extends RouteInformationProvider
     required String initialLocation,
     required Object? initialExtra,
     Listenable? refreshListenable,
+    bool routerNeglect = false,
   })  : _refreshListenable = refreshListenable,
         _value = RouteInformation(
           uri: Uri.parse(initialLocation),
           state: RouteInformationState(
               extra: initialExtra, type: NavigatingType.go),
         ),
-        _valueInEngine = _kEmptyRouteInformation {
+        _valueInEngine = _kEmptyRouteInformation,
+        _routerNeglect = routerNeglect {
     _refreshListenable?.addListener(notifyListeners);
   }
 
   final Listenable? _refreshListenable;
 
+  final bool _routerNeglect;
+
   static WidgetsBinding get _binding => WidgetsBinding.instance;
   static final RouteInformation _kEmptyRouteInformation =
       RouteInformation(uri: Uri.parse(''));
@@ -120,7 +124,7 @@ class GoRouteInformationProvider extends RouteInformationProvider
     SystemNavigator.routeInformationUpdated(
       uri: routeInformation.uri,
       state: routeInformation.state,
-      replace: replace,
+      replace: _routerNeglect || replace,
     );
     _value = _valueInEngine = routeInformation;
   }
diff --git a/packages/go_router/lib/src/match.dart b/packages/go_router/lib/src/match.dart
index fba08f838656..696f9d4c50d9 100644
--- a/packages/go_router/lib/src/match.dart
+++ b/packages/go_router/lib/src/match.dart
@@ -203,6 +203,7 @@ abstract class RouteMatchBase with Diagnosticable {
 
     final RegExpMatch? regExpMatch =
         route.matchPatternAsPrefix(remainingLocation);
+
     if (regExpMatch == null) {
       return _empty;
     }
@@ -555,13 +556,9 @@ class RouteMatchList with Diagnosticable {
   /// [RouteMatchA(), RouteMatchB(), RouteMatchC()]
   /// ```
   static String _generateFullPath(Iterable matches) {
-    final StringBuffer buffer = StringBuffer();
-    bool addsSlash = false;
+    String fullPath = '';
     for (final RouteMatchBase match in matches
         .where((RouteMatchBase match) => match is! ImperativeRouteMatch)) {
-      if (addsSlash) {
-        buffer.write('/');
-      }
       final String pathSegment;
       if (match is RouteMatch) {
         pathSegment = match.route.path;
@@ -571,10 +568,9 @@ class RouteMatchList with Diagnosticable {
         assert(false, 'Unexpected match type: $match');
         continue;
       }
-      buffer.write(pathSegment);
-      addsSlash = pathSegment.isNotEmpty && (addsSlash || pathSegment != '/');
+      fullPath = concatenatePaths(fullPath, pathSegment);
     }
-    return buffer.toString();
+    return fullPath;
   }
 
   /// Returns true if there are no matches.
@@ -944,7 +940,7 @@ class _RouteMatchListDecoder
           ?.decode(encodedExtra[RouteMatchListCodec._encodedKey]);
     }
     RouteMatchList matchList =
-        configuration.findMatch(rootLocation, extra: extra);
+        configuration.findMatch(Uri.parse(rootLocation), extra: extra);
 
     final List? imperativeMatches =
         input[RouteMatchListCodec._imperativeMatchesKey] as List?;
diff --git a/packages/go_router/lib/src/parser.dart b/packages/go_router/lib/src/parser.dart
index b4115a1fca19..d1981898a8bb 100644
--- a/packages/go_router/lib/src/parser.dart
+++ b/packages/go_router/lib/src/parser.dart
@@ -80,25 +80,17 @@ class GoRouteInformationParser extends RouteInformationParser {
       });
     }
 
-    late final RouteMatchList initialMatches;
-    if (routeInformation.uri.hasEmptyPath) {
-      String newUri = '${routeInformation.uri.origin}/';
-      if (routeInformation.uri.hasQuery) {
-        newUri += '?${routeInformation.uri.query}';
-      }
-      if (routeInformation.uri.hasFragment) {
-        newUri += '#${routeInformation.uri.fragment}';
-      }
-      initialMatches = configuration.findMatch(
-        newUri,
-        extra: state.extra,
-      );
-    } else {
-      initialMatches = configuration.findMatch(
-        routeInformation.uri.toString(),
-        extra: state.extra,
-      );
+    Uri uri = routeInformation.uri;
+    if (uri.hasEmptyPath) {
+      uri = uri.replace(path: '/');
+    } else if (uri.path.length > 1 && uri.path.endsWith('/')) {
+      // Remove trailing `/`.
+      uri = uri.replace(path: uri.path.substring(0, uri.path.length - 1));
     }
+    final RouteMatchList initialMatches = configuration.findMatch(
+      uri,
+      extra: state.extra,
+    );
     if (initialMatches.isError) {
       log('No initial matches: ${routeInformation.uri.path}');
     }
@@ -160,7 +152,6 @@ class GoRouteInformationParser extends RouteInformationParser {
         location = safeRoute.matches.uri.toString();
       }
     }
-
     return RouteInformation(
       uri: Uri.parse(location ?? configuration.uri.toString()),
       state: _routeMatchListCodec.encode(configuration),
@@ -194,22 +185,30 @@ class GoRouteInformationParser extends RouteInformationParser {
         );
       case NavigatingType.pushReplacement:
         final RouteMatch routeMatch = baseRouteMatchList!.last;
-        return baseRouteMatchList.remove(routeMatch).push(
-              ImperativeRouteMatch(
-                pageKey: _getUniqueValueKey(),
-                completer: completer!,
-                matches: newMatchList,
-              ),
-            );
+        baseRouteMatchList = baseRouteMatchList.remove(routeMatch);
+        if (baseRouteMatchList.isEmpty) {
+          return newMatchList;
+        }
+        return baseRouteMatchList.push(
+          ImperativeRouteMatch(
+            pageKey: _getUniqueValueKey(),
+            completer: completer!,
+            matches: newMatchList,
+          ),
+        );
       case NavigatingType.replace:
         final RouteMatch routeMatch = baseRouteMatchList!.last;
-        return baseRouteMatchList.remove(routeMatch).push(
-              ImperativeRouteMatch(
-                pageKey: routeMatch.pageKey,
-                completer: completer!,
-                matches: newMatchList,
-              ),
-            );
+        baseRouteMatchList = baseRouteMatchList.remove(routeMatch);
+        if (baseRouteMatchList.isEmpty) {
+          return newMatchList;
+        }
+        return baseRouteMatchList.push(
+          ImperativeRouteMatch(
+            pageKey: routeMatch.pageKey,
+            completer: completer!,
+            matches: newMatchList,
+          ),
+        );
       case NavigatingType.go:
         return newMatchList;
       case NavigatingType.restore:
diff --git a/packages/go_router/lib/src/path_utils.dart b/packages/go_router/lib/src/path_utils.dart
index 49a7b33b3ebc..4684c75badc4 100644
--- a/packages/go_router/lib/src/path_utils.dart
+++ b/packages/go_router/lib/src/path_utils.dart
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'misc/errors.dart';
 import 'route.dart';
 
 final RegExp _parameterRegExp = RegExp(r':(\w+)(\((?:\\.|[^\\()])+\))?');
@@ -103,55 +102,14 @@ Map extractPathParameters(
 
 /// Concatenates two paths.
 ///
-/// e.g: pathA = /a, pathB = c/d,  concatenatePaths(pathA, pathB) = /a/c/d.
+/// e.g: pathA = /a, pathB = /c/d, concatenatePaths(pathA, pathB) = /a/c/d.
+/// or: pathA = a, pathB = c/d, concatenatePaths(pathA, pathB) = /a/c/d.
 String concatenatePaths(String parentPath, String childPath) {
-  // at the root, just return the path
-  if (parentPath.isEmpty) {
-    assert(childPath.startsWith('/'));
-    assert(childPath == '/' || !childPath.endsWith('/'));
-    return childPath;
-  }
-
-  // not at the root, so append the parent path
-  assert(childPath.isNotEmpty);
-  assert(!childPath.startsWith('/'));
-  assert(!childPath.endsWith('/'));
-  return '${parentPath == '/' ? '' : parentPath}/$childPath';
-}
-
-/// Normalizes the location string.
-String canonicalUri(String loc) {
-  if (loc.isEmpty) {
-    throw GoException('Location cannot be empty.');
-  }
-  String canon = Uri.parse(loc).toString();
-  canon = canon.endsWith('?') ? canon.substring(0, canon.length - 1) : canon;
-  final Uri uri = Uri.parse(canon);
-
-  // remove trailing slash except for when you shouldn't, e.g.
-  // /profile/ => /profile
-  // / => /
-  // /login?from=/ => /login?from=/
-  canon = uri.path.endsWith('/') &&
-          uri.path != '/' &&
-          !uri.hasQuery &&
-          !uri.hasFragment
-      ? canon.substring(0, canon.length - 1)
-      : canon;
-
-  // replace '/?', except for first occurrence, from path only
-  // /login/?from=/ => /login?from=/
-  // /?from=/ => /?from=/
-  final int pathStartIndex = uri.host.isNotEmpty
-      ? uri.toString().indexOf(uri.host) + uri.host.length
-      : uri.hasScheme
-          ? uri.toString().indexOf(uri.scheme) + uri.scheme.length
-          : 0;
-  if (pathStartIndex < canon.length) {
-    canon = canon.replaceFirst('/?', '?', pathStartIndex + 1);
-  }
-
-  return canon;
+  final Iterable segments = [
+    ...parentPath.split('/'),
+    ...childPath.split('/')
+  ].where((String segment) => segment.isNotEmpty);
+  return '/${segments.join('/')}';
 }
 
 /// Builds an absolute path for the provided route.
diff --git a/packages/go_router/lib/src/route.dart b/packages/go_router/lib/src/route.dart
index 8b23e54f31a5..a5dcc734d054 100644
--- a/packages/go_router/lib/src/route.dart
+++ b/packages/go_router/lib/src/route.dart
@@ -77,7 +77,7 @@ typedef ExitCallback = FutureOr Function(
 /// with the sub routes.
 ///
 /// For example these routes:
-/// ```
+/// ```none
 /// /         => HomePage()
 ///   family/f1 => FamilyPage('f1')
 ///     person/p2 => PersonPage('f1', 'p2') ← showing this page, Back pops ↑
@@ -85,7 +85,7 @@ typedef ExitCallback = FutureOr Function(
 ///
 /// Can be represented as:
 ///
-/// ```
+/// ```dart
 /// final GoRouter _router = GoRouter(
 ///   routes: [
 ///     GoRoute(
@@ -122,17 +122,19 @@ typedef ExitCallback = FutureOr Function(
 ///     ),
 ///   ],
 /// );
+/// ```
 ///
 /// If there are multiple routes that match the location, the first match is used.
 /// To make predefined routes to take precedence over dynamic routes eg. '/:id'
-/// consider adding the dynamic route at the end of the routes
+/// consider adding the dynamic route at the end of the routes.
+///
 /// For example:
-/// ```
+/// ```dart
 /// final GoRouter _router = GoRouter(
 ///   routes: [
 ///     GoRoute(
 ///       path: '/',
-///       redirect: (_) => '/family/${Families.data[0].id}',
+///       redirect: (_, __) => '/family/${Families.data[0].id}',
 ///     ),
 ///     GoRoute(
 ///       path: '/family',
@@ -145,9 +147,10 @@ typedef ExitCallback = FutureOr Function(
 ///   ],
 /// );
 /// ```
-/// In the above example, if /family route is matched, it will be used.
-/// else /:username route will be used.
-/// ///
+///
+/// In the above example, if `/family` route is matched, it will be used.
+/// else `/:username` route will be used.
+///
 /// See [main.dart](https://github.com/flutter/packages/blob/main/packages/go_router/example/lib/main.dart)
 @immutable
 abstract class RouteBase with Diagnosticable {
@@ -164,12 +167,12 @@ abstract class RouteBase with Diagnosticable {
   /// the GoRoute constructor.
   ///
   /// For example:
-  /// ```
+  /// ```dart
   /// final GoRouter _router = GoRouter(
   ///   routes: [
   ///     GoRoute(
   ///       path: '/',
-  ///       redirect: (_) => '/family/${Families.data[0].id}',
+  ///       redirect: (_, __) => '/family/${Families.data[0].id}',
   ///     ),
   ///     GoRoute(
   ///       path: '/family/:fid',
@@ -183,16 +186,16 @@ abstract class RouteBase with Diagnosticable {
   /// redirect takes priority over sub-route's.
   ///
   /// For example:
-  /// ```
+  /// ```dart
   /// final GoRouter _router = GoRouter(
   ///   routes: [
   ///     GoRoute(
   ///       path: '/',
-  ///       redirect: (_) => '/page1', // this takes priority over the sub-route.
+  ///       redirect: (_, __) => '/page1', // this takes priority over the sub-route.
   ///       routes: [
   ///         GoRoute(
   ///           path: 'child',
-  ///           redirect: (_) => '/page2',
+  ///           redirect: (_, __) => '/page2',
   ///         ),
   ///       ],
   ///     ),
@@ -327,7 +330,7 @@ class GoRoute extends RouteBase {
   /// The path of this go route.
   ///
   /// For example:
-  /// ```
+  /// ```dart
   /// GoRoute(
   ///   path: '/',
   ///   pageBuilder: (BuildContext context, GoRouterState state) => MaterialPage(
@@ -352,7 +355,7 @@ class GoRoute extends RouteBase {
   /// A page builder for this route.
   ///
   /// Typically a MaterialPage, as in:
-  /// ```
+  /// ```dart
   /// GoRoute(
   ///   path: '/',
   ///   pageBuilder: (BuildContext context, GoRouterState state) => MaterialPage(
@@ -369,7 +372,7 @@ class GoRoute extends RouteBase {
   /// A custom builder for this route.
   ///
   /// For example:
-  /// ```
+  /// ```dart
   /// GoRoute(
   ///   path: '/',
   ///   builder: (BuildContext context, GoRouterState state) => FamilyPage(
@@ -391,7 +394,7 @@ class GoRoute extends RouteBase {
   /// This method can be useful it one wants to launch a dialog for user to
   /// confirm if they want to exit the screen.
   ///
-  /// ```
+  /// ```dart
   /// final GoRouter _router = GoRouter(
   ///   routes: [
   ///     GoRoute(
@@ -432,8 +435,10 @@ class GoRoute extends RouteBase {
 
   // TODO(chunhtai): move all regex related help methods to path_utils.dart.
   /// Match this route against a location.
-  RegExpMatch? matchPatternAsPrefix(String loc) =>
-      _pathRE.matchAsPrefix(loc) as RegExpMatch?;
+  RegExpMatch? matchPatternAsPrefix(String loc) {
+    return _pathRE.matchAsPrefix('/$loc') as RegExpMatch? ??
+        _pathRE.matchAsPrefix(loc) as RegExpMatch?;
+  }
 
   /// Extract the path parameters from a match.
   Map extractPathParams(RegExpMatch match) =>
@@ -540,7 +545,7 @@ class ShellRouteContext {
 /// passed to the /b/details route so that it displays on the root Navigator
 /// instead of the ShellRoute's Navigator:
 ///
-/// ```
+/// ```dart
 /// final GlobalKey _rootNavigatorKey =
 ///     GlobalKey();
 ///
@@ -599,7 +604,7 @@ class ShellRouteContext {
 ///
 /// For example:
 ///
-/// ```
+/// ```dart
 /// ShellRoute(
 ///   builder: (BuildContext context, GoRouterState state, Widget child) {
 ///     return Scaffold(
@@ -737,7 +742,7 @@ class ShellRoute extends ShellRouteBase {
 /// accomplished by using the method [StatefulNavigationShell.goBranch], for
 /// example:
 ///
-/// ```
+/// ```dart
 /// void _onItemTapped(int index) {
 ///   navigationShell.goBranch(index: index);
 /// }
@@ -777,6 +782,8 @@ class ShellRoute extends ShellRouteBase {
 /// * [Custom StatefulShellRoute example](https://github.com/flutter/packages/blob/main/packages/go_router/example/lib/others/custom_stateful_shell_route.dart)
 /// which demonstrates how to customize the container for the branch Navigators
 /// and how to implement animated transitions when switching branches.
+///
+/// {@category Configuration}
 class StatefulShellRoute extends ShellRouteBase {
   /// Constructs a [StatefulShellRoute] from a list of [StatefulShellBranch]es,
   /// each representing a separate nested navigation tree (branch).
@@ -1055,7 +1062,7 @@ typedef ShellNavigationContainerBuilder = Widget Function(BuildContext context,
 /// where the List of Widgets represent the Navigators for each branch.
 ///
 /// Example:
-/// ```
+/// ```dart
 /// builder: (BuildContext context, GoRouterState state,
 ///     StatefulNavigationShell navigationShell) {
 ///   return StatefulNavigationShell(
diff --git a/packages/go_router/lib/src/router.dart b/packages/go_router/lib/src/router.dart
index dc6d88057eb0..11f40f505cac 100644
--- a/packages/go_router/lib/src/router.dart
+++ b/packages/go_router/lib/src/router.dart
@@ -199,7 +199,7 @@ class GoRouter implements RouterConfig {
     setLogging(enabled: debugLogDiagnostics);
     WidgetsFlutterBinding.ensureInitialized();
 
-    navigatorKey ??= GlobalKey();
+    navigatorKey ??= GlobalKey(debugLabel: 'root');
 
     _routingConfig.addListener(_handleRoutingConfigChanged);
     configuration = RouteConfiguration(
@@ -230,6 +230,7 @@ class GoRouter implements RouterConfig {
       initialLocation: _effectiveInitialLocation(initialLocation),
       initialExtra: initialExtra,
       refreshListenable: refreshListenable,
+      routerNeglect: routerNeglect,
     );
 
     routerDelegate = GoRouterDelegate(
@@ -254,6 +255,14 @@ class GoRouter implements RouterConfig {
     }());
   }
 
+  /// The top [GoRouterState], the state of the route that was
+  /// last used in either [GoRouter.go] or [GoRouter.push].
+  ///
+  /// Accessing this property via GoRouter.of(context).state will not
+  /// cause rebuild if the state has changed, consider using
+  /// GoRouterState.of(context) instead.
+  GoRouterState? get state => routerDelegate.state;
+
   /// Whether the imperative API affects browser URL bar.
   ///
   /// The Imperative APIs refer to [push], [pushReplacement], or [replace].
diff --git a/packages/go_router/lib/src/state.dart b/packages/go_router/lib/src/state.dart
index 09f1cceaf1d0..0a1fb54ba79b 100644
--- a/packages/go_router/lib/src/state.dart
+++ b/packages/go_router/lib/src/state.dart
@@ -98,11 +98,11 @@ class GoRouterState {
   ///
   /// This method cannot be called during [GoRoute.pageBuilder] or
   /// [ShellRoute.pageBuilder] since there is no [GoRouterState] to be
-  /// associated with.
+  /// associated with yet.
   ///
   /// To access GoRouterState from a widget.
   ///
-  /// ```
+  /// ```dart
   /// GoRoute(
   ///   path: '/:id'
   ///   builder: (_, __) => MyWidget(),
@@ -116,26 +116,41 @@ class GoRouterState {
   /// }
   /// ```
   static GoRouterState of(BuildContext context) {
-    final ModalRoute? route = ModalRoute.of(context);
-    if (route == null) {
-      throw GoError('There is no modal route above the current context.');
-    }
-    final RouteSettings settings = route.settings;
-    if (settings is! Page) {
-      throw GoError(
-          'The parent route must be a page route to have a GoRouterState');
-    }
-    final GoRouterStateRegistryScope? scope = context
-        .dependOnInheritedWidgetOfExactType();
-    if (scope == null) {
-      throw GoError(
-          'There is no GoRouterStateRegistryScope above the current context.');
+    ModalRoute? route;
+    GoRouterStateRegistryScope? scope;
+    while (true) {
+      route = ModalRoute.of(context);
+      if (route == null) {
+        throw _noGoRouterStateError;
+      }
+      final RouteSettings settings = route.settings;
+      if (settings is Page) {
+        scope = context
+            .dependOnInheritedWidgetOfExactType();
+        if (scope == null) {
+          throw _noGoRouterStateError;
+        }
+        final GoRouterState? state = scope.notifier!
+            ._createPageRouteAssociation(
+                route.settings as Page, route);
+        if (state != null) {
+          return state;
+        }
+      }
+      final NavigatorState? state = Navigator.maybeOf(context);
+      if (state == null) {
+        throw _noGoRouterStateError;
+      }
+      context = state.context;
     }
-    final GoRouterState state =
-        scope.notifier!._createPageRouteAssociation(settings, route);
-    return state;
   }
 
+  static GoError get _noGoRouterStateError => GoError(
+        'There is no GoRouterState above the current context. '
+        'This method should only be called under the sub tree of a '
+        'RouteBase.builder.',
+      );
+
   /// Get a location from route name and parameters.
   /// This is useful for redirecting to a named location.
   String namedLocation(
@@ -207,10 +222,12 @@ class GoRouterStateRegistry extends ChangeNotifier {
   final Map, Page> _routePageAssociation =
       , Page>{};
 
-  GoRouterState _createPageRouteAssociation(
+  GoRouterState? _createPageRouteAssociation(
       Page page, ModalRoute route) {
     assert(route.settings == page);
-    assert(registry.containsKey(page));
+    if (!registry.containsKey(page)) {
+      return null;
+    }
     final Page? oldPage = _routePageAssociation[route];
     if (oldPage == null) {
       // This is a new association.
diff --git a/packages/go_router/pubspec.yaml b/packages/go_router/pubspec.yaml
index eec6806cf6da..7bfc3f9297f6 100644
--- a/packages/go_router/pubspec.yaml
+++ b/packages/go_router/pubspec.yaml
@@ -1,13 +1,13 @@
 name: go_router
 description: A declarative router for Flutter based on Navigation 2 supporting
   deep linking, data-driven routes and more
-version: 14.2.0
+version: 14.4.1
 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.2.0 <4.0.0"
-  flutter: ">=3.16.0"
+  sdk: ^3.3.0
+  flutter: ">=3.19.0"
 
 dependencies:
   collection: ^1.15.0
@@ -22,6 +22,7 @@ dev_dependencies:
   flutter_test:
     sdk: flutter
   io: ^1.0.4
+  leak_tracker_flutter_testing: any
   path: ^1.8.2
 
 topics:
diff --git a/packages/go_router/test/extension_test.dart b/packages/go_router/test/extension_test.dart
index 0f314edbf66e..c13a47de002f 100644
--- a/packages/go_router/test/extension_test.dart
+++ b/packages/go_router/test/extension_test.dart
@@ -38,9 +38,7 @@ void main() {
       final GoRouter router = await createGoRouter(tester);
       await tester.tap(find.text('Settings'));
       await tester.pumpAndSettle();
-      final ImperativeRouteMatch routeMatch = router
-          .routerDelegate.currentConfiguration.last as ImperativeRouteMatch;
-      expect(routeMatch.matches.uri.toString(),
+      expect(router.routerDelegate.currentConfiguration.uri.toString(),
           '/page-0/settings?search=notification');
     });
   });
diff --git a/packages/go_router/test/extra_codec_test.dart b/packages/go_router/test/extra_codec_test.dart
index 35291db978d8..0005d1d535ff 100644
--- a/packages/go_router/test/extra_codec_test.dart
+++ b/packages/go_router/test/extra_codec_test.dart
@@ -74,6 +74,7 @@ void main() {
     expect(find.text(initialString), findsOneWidget);
 
     await tester.restartAndRestore();
+    addTearDown(tester.binding.restorationManager.dispose);
 
     await tester.pumpAndSettle();
     expect(find.text(initialString), findsOneWidget);
diff --git a/packages/go_router/test/flutter_test_config.dart b/packages/go_router/test/flutter_test_config.dart
new file mode 100644
index 000000000000..9907e578b84b
--- /dev/null
+++ b/packages/go_router/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/go_router/test/go_router_state_test.dart b/packages/go_router/test/go_router_state_test.dart
index 69364f2aa801..4c588177eb2f 100644
--- a/packages/go_router/test/go_router_state_test.dart
+++ b/packages/go_router/test/go_router_state_test.dart
@@ -185,6 +185,39 @@ void main() {
       expect(find.byKey(key), findsNothing);
     });
 
+    testWidgets(
+        'GoRouterState look up should be resilient when there is a nested navigator.',
+        (WidgetTester tester) async {
+      final List routes = [
+        GoRoute(
+          path: '/',
+          builder: (_, __) {
+            return Scaffold(
+              appBar: AppBar(),
+              body: Navigator(
+                pages: >[
+                  MaterialPage(
+                    child: Builder(
+                      builder: (BuildContext context) {
+                        return Center(
+                          child: Text(GoRouterState.of(context).uri.toString()),
+                        );
+                      },
+                    ),
+                  ),
+                ],
+                onPopPage: (Route route, Object? result) {
+                  throw UnimplementedError();
+                },
+              ),
+            );
+          },
+        )
+      ];
+      await createRouter(routes, tester);
+      expect(find.text('/'), findsOneWidget);
+    });
+
     testWidgets('GoRouterState topRoute accessible from StatefulShellRoute',
         (WidgetTester tester) async {
       final GlobalKey rootNavigatorKey =
diff --git a/packages/go_router/test/go_router_test.dart b/packages/go_router/test/go_router_test.dart
index f395faf906fd..f2c0a69bd267 100644
--- a/packages/go_router/test/go_router_test.dart
+++ b/packages/go_router/test/go_router_test.dart
@@ -68,28 +68,31 @@ void main() {
       expect(find.byType(DummyScreen), findsOneWidget);
     });
 
-    test('empty path', () {
-      expect(() {
-        GoRoute(path: '');
-      }, throwsA(isAssertionError));
+    testWidgets('pushReplacement and replace when only one matches',
+        (WidgetTester tester) async {
+      final List routes = [
+        GoRoute(name: '1', path: '/', builder: dummy),
+        GoRoute(name: '2', path: '/a', builder: dummy),
+        GoRoute(name: '3', path: '/b', builder: dummy),
+      ];
+
+      final GoRouter router = await createRouter(routes, tester);
+      expect(router.routerDelegate.currentConfiguration.uri.path, '/');
+
+      router.replace('/a');
+      await tester.pumpAndSettle();
+      // When the imperative match is the only match in the route match list,
+      // it should update the uri.
+      expect(router.routerDelegate.currentConfiguration.uri.path, '/a');
+
+      router.pushReplacement('/b');
+      await tester.pumpAndSettle();
+      expect(router.routerDelegate.currentConfiguration.uri.path, '/b');
     });
 
-    test('leading / on sub-route', () {
+    test('empty path', () {
       expect(() {
-        GoRouter(
-          routes: [
-            GoRoute(
-              path: '/',
-              builder: dummy,
-              routes: [
-                GoRoute(
-                  path: '/foo',
-                  builder: dummy,
-                ),
-              ],
-            ),
-          ],
-        );
+        GoRoute(path: '');
       }, throwsA(isAssertionError));
     });
 
@@ -112,16 +115,6 @@ void main() {
       }, throwsA(isAssertionError));
     });
 
-    testWidgets('lack of leading / on top-level route',
-        (WidgetTester tester) async {
-      await expectLater(() async {
-        final List routes = [
-          GoRoute(path: 'foo', builder: dummy),
-        ];
-        await createRouter(routes, tester);
-      }, throwsA(isAssertionError));
-    });
-
     testWidgets('match no routes', (WidgetTester tester) async {
       final List routes = [
         GoRoute(path: '/', builder: dummy),
@@ -398,6 +391,67 @@ void main() {
       expect(find.byKey(settings), findsOneWidget);
     });
 
+    testWidgets('android back button pop in correct order',
+        (WidgetTester tester) async {
+      // Regression test for https://github.com/flutter/flutter/issues/141906.
+      final List routes = [
+        GoRoute(
+            path: '/',
+            builder: (_, __) => const Text('home'),
+            routes: [
+              ShellRoute(
+                builder: (
+                  BuildContext context,
+                  GoRouterState state,
+                  Widget child,
+                ) {
+                  return Column(
+                    children: [
+                      const Text('shell'),
+                      child,
+                    ],
+                  );
+                },
+                routes: [
+                  GoRoute(
+                    path: 'page',
+                    builder: (BuildContext context, __) {
+                      return TextButton(
+                        onPressed: () {
+                          Navigator.of(context, rootNavigator: true).push(
+                            MaterialPageRoute(
+                                builder: (BuildContext context) {
+                              return const Text('pageless');
+                            }),
+                          );
+                        },
+                        child: const Text('page'),
+                      );
+                    },
+                  ),
+                ],
+              ),
+            ]),
+      ];
+      final GoRouter router =
+          await createRouter(routes, tester, initialLocation: '/page');
+      expect(find.text('shell'), findsOneWidget);
+      expect(find.text('page'), findsOneWidget);
+
+      await tester.tap(find.text('page'));
+      await tester.pumpAndSettle();
+      expect(find.text('shell'), findsNothing);
+      expect(find.text('page'), findsNothing);
+      expect(find.text('pageless'), findsOneWidget);
+
+      final bool result = await router.routerDelegate.popRoute();
+      expect(result, isTrue);
+      await tester.pumpAndSettle();
+      expect(find.text('shell'), findsOneWidget);
+      expect(find.text('page'), findsOneWidget);
+      expect(find.text('pageless'), findsNothing);
+    });
+
     testWidgets('can correctly pop stacks of repeated pages',
         (WidgetTester tester) async {
       // Regression test for https://github.com/flutter/flutter/issues/#132229.
@@ -5404,6 +5458,7 @@ void main() {
         ),
       ],
     );
+    addTearDown(router.dispose);
     await tester.pumpWidget(
       MaterialApp.router(
         key: UniqueKey(),
@@ -5419,6 +5474,166 @@ void main() {
       ),
     );
   });
+
+  testWidgets(
+      'should return the current GoRouterState when router.currentState is called',
+      (WidgetTester tester) async {
+    final List routes = [
+      GoRoute(
+          name: 'home',
+          path: '/',
+          builder: (BuildContext context, GoRouterState state) =>
+              const HomeScreen()),
+      GoRoute(
+          name: 'books',
+          path: '/books',
+          builder: (BuildContext context, GoRouterState state) =>
+              const Text('books')),
+      GoRoute(
+          name: 'boats',
+          path: '/boats',
+          builder: (BuildContext context, GoRouterState state) =>
+              const Text('boats')),
+      ShellRoute(
+        builder: (BuildContext context, GoRouterState state, Widget child) =>
+            child,
+        routes: [
+          GoRoute(
+            name: 'tulips',
+            path: '/tulips',
+            builder: (BuildContext context, GoRouterState state) =>
+                const Text('tulips'),
+          ),
+        ],
+      )
+    ];
+
+    final GoRouter router = await createRouter(routes, tester);
+    await tester.pumpAndSettle();
+
+    GoRouterState? state = router.state;
+    expect(state?.name, 'home');
+    expect(state?.fullPath, '/');
+
+    router.go('/books');
+    await tester.pumpAndSettle();
+    state = router.state;
+    expect(state?.name, 'books');
+    expect(state?.fullPath, '/books');
+
+    router.push('/boats');
+    await tester.pumpAndSettle();
+    state = router.state;
+    expect(state?.name, 'boats');
+    expect(state?.fullPath, '/boats');
+
+    router.pop();
+    await tester.pumpAndSettle();
+    state = router.state;
+    expect(state?.name, 'books');
+    expect(state?.fullPath, '/books');
+
+    router.go('/tulips');
+    await tester.pumpAndSettle();
+    state = router.state;
+    expect(state?.name, 'tulips');
+    expect(state?.fullPath, '/tulips');
+
+    router.go('/books');
+    router.push('/tulips');
+    await tester.pumpAndSettle();
+    state = router.state;
+    expect(state?.name, 'tulips');
+    expect(state?.fullPath, '/tulips');
+  });
+
+  testWidgets('should allow route paths without leading /',
+      (WidgetTester tester) async {
+    final List routes = [
+      GoRoute(
+        path: '/', // root cannot be empty (existing assert)
+        builder: (BuildContext context, GoRouterState state) =>
+            const HomeScreen(),
+        routes: [
+          GoRoute(
+            path: 'child-route',
+            builder: (BuildContext context, GoRouterState state) =>
+                const Text('/child-route'),
+            routes: [
+              GoRoute(
+                path: 'grand-child-route',
+                builder: (BuildContext context, GoRouterState state) =>
+                    const Text('/grand-child-route'),
+              ),
+              GoRoute(
+                path: 'redirected-grand-child-route',
+                redirect: (BuildContext context, GoRouterState state) =>
+                    '/child-route',
+              ),
+            ],
+          )
+        ],
+      ),
+    ];
+
+    final GoRouter router = await createRouter(routes, tester,
+        initialLocation: '/child-route/grand-child-route');
+    RouteMatchList matches = router.routerDelegate.currentConfiguration;
+    expect(matches.matches, hasLength(3));
+    expect(matches.uri.toString(), '/child-route/grand-child-route');
+    expect(find.text('/grand-child-route'), findsOneWidget);
+
+    router.go('/child-route/redirected-grand-child-route');
+    await tester.pumpAndSettle();
+    matches = router.routerDelegate.currentConfiguration;
+    expect(matches.matches, hasLength(2));
+    expect(matches.uri.toString(), '/child-route');
+    expect(find.text('/child-route'), findsOneWidget);
+  });
+
+  testWidgets('should allow route paths with leading /',
+      (WidgetTester tester) async {
+    final List routes = [
+      GoRoute(
+        path: '/',
+        builder: (BuildContext context, GoRouterState state) =>
+            const HomeScreen(),
+        routes: [
+          GoRoute(
+            path: '/child-route',
+            builder: (BuildContext context, GoRouterState state) =>
+                const Text('/child-route'),
+            routes: [
+              GoRoute(
+                path: '/grand-child-route',
+                builder: (BuildContext context, GoRouterState state) =>
+                    const Text('/grand-child-route'),
+              ),
+              GoRoute(
+                path: '/redirected-grand-child-route',
+                redirect: (BuildContext context, GoRouterState state) =>
+                    '/child-route',
+              ),
+            ],
+          )
+        ],
+      ),
+    ];
+
+    final GoRouter router = await createRouter(routes, tester,
+        initialLocation: '/child-route/grand-child-route');
+    RouteMatchList matches = router.routerDelegate.currentConfiguration;
+    expect(matches.matches, hasLength(3));
+    expect(matches.uri.toString(), '/child-route/grand-child-route');
+    expect(find.text('/grand-child-route'), findsOneWidget);
+
+    router.go('/child-route/redirected-grand-child-route');
+    await tester.pumpAndSettle();
+    matches = router.routerDelegate.currentConfiguration;
+    expect(matches.matches, hasLength(2));
+    expect(matches.uri.toString(), '/child-route');
+    expect(find.text('/child-route'), findsOneWidget);
+  });
 }
 
 class TestInheritedNotifier extends InheritedNotifier> {
diff --git a/packages/go_router/test/information_provider_test.dart b/packages/go_router/test/information_provider_test.dart
index 52629587bac0..2bdb0e6178f9 100644
--- a/packages/go_router/test/information_provider_test.dart
+++ b/packages/go_router/test/information_provider_test.dart
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'package:flutter/services.dart';
 import 'package:flutter/widgets.dart';
 import 'package:flutter_test/flutter_test.dart';
 import 'package:go_router/go_router.dart';
@@ -16,6 +17,7 @@ void main() {
       late final GoRouteInformationProvider provider =
           GoRouteInformationProvider(
               initialLocation: initialRoute, initialExtra: null);
+      addTearDown(provider.dispose);
       provider.addListener(expectAsync0(() {}));
       provider.go(newRoute);
     });
@@ -25,6 +27,7 @@ void main() {
       late final GoRouteInformationProvider provider =
           GoRouteInformationProvider(
               initialLocation: initialRoute, initialExtra: null);
+      addTearDown(provider.dispose);
       provider.addListener(expectAsync0(() {}));
       provider
           .didPushRouteInformation(RouteInformation(uri: Uri.parse(newRoute)));
@@ -40,6 +43,7 @@ void main() {
       late final GoRouteInformationProvider provider =
           GoRouteInformationProvider(
               initialLocation: initialRoute, initialExtra: null);
+      addTearDown(provider.dispose);
       provider.addListener(expectAsync0(() {}));
       provider.didPushRouteInformation(
           RouteInformation(uri: Uri.parse(expectedUriString)));
@@ -59,6 +63,7 @@ void main() {
       late final GoRouteInformationProvider provider =
           GoRouteInformationProvider(
               initialLocation: initialRoute, initialExtra: null);
+      addTearDown(provider.dispose);
       provider.addListener(expectAsync0(() {}));
       provider.didPushRouteInformation(
           RouteInformation(uri: Uri.parse(expectedUriString)));
@@ -67,5 +72,61 @@ void main() {
       expect(provider.value.uri.path, '/some/path');
       expect(provider.value.uri.toString(), expectedUriString);
     });
+
+    testWidgets('Route is correctly neglected when routerNeglect is true',
+        (WidgetTester tester) async {
+      final _SystemChannelsNavigationMock systemChannelsMock =
+          _SystemChannelsNavigationMock();
+      late final GoRouteInformationProvider provider =
+          GoRouteInformationProvider(
+              initialLocation: initialRoute,
+              initialExtra: null,
+              routerNeglect: true);
+      addTearDown(provider.dispose);
+      provider.addListener(expectAsync0(() {}));
+      provider.go(newRoute);
+      provider.routerReportsNewRouteInformation(
+          RouteInformation(
+              uri: Uri.parse(newRoute), state: {}),
+          type: RouteInformationReportingType.navigate);
+      expect(systemChannelsMock.uriIsNeglected[newRoute], true);
+    });
+
+    testWidgets('Route is NOT neglected when routerNeglect is false',
+        (WidgetTester tester) async {
+      final _SystemChannelsNavigationMock systemChannelsMock =
+          _SystemChannelsNavigationMock();
+      late final GoRouteInformationProvider provider =
+          GoRouteInformationProvider(
+              initialLocation: initialRoute, initialExtra: null);
+      addTearDown(provider.dispose);
+      provider.addListener(expectAsync0(() {}));
+      provider.go(newRoute);
+      provider.routerReportsNewRouteInformation(
+          RouteInformation(
+              uri: Uri.parse(newRoute), state: {}),
+          type: RouteInformationReportingType.navigate);
+      expect(systemChannelsMock.uriIsNeglected[newRoute], false);
+    });
   });
 }
+
+class _SystemChannelsNavigationMock {
+  _SystemChannelsNavigationMock() {
+    TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
+        .setMockMethodCallHandler(SystemChannels.navigation,
+            (MethodCall methodCall) async {
+      if (methodCall.method == 'routeInformationUpdated' &&
+          methodCall.arguments is Map) {
+        final Map args =
+            methodCall.arguments as Map;
+        final String? uri =
+            args['location'] as String? ?? args['uri'] as String?;
+        uriIsNeglected[uri ?? ''] = args['replace'] as bool;
+      }
+      return null;
+    });
+  }
+
+  Map uriIsNeglected = {};
+}
diff --git a/packages/go_router/test/matching_test.dart b/packages/go_router/test/matching_test.dart
index 89cbccb8a5ee..f2dffbd3de1c 100644
--- a/packages/go_router/test/matching_test.dart
+++ b/packages/go_router/test/matching_test.dart
@@ -92,8 +92,8 @@ void main() {
     );
     final RouteMatchListCodec codec = RouteMatchListCodec(configuration);
 
-    final RouteMatchList list1 = configuration.findMatch('/a');
-    final RouteMatchList list2 = configuration.findMatch('/b');
+    final RouteMatchList list1 = configuration.findMatch(Uri.parse('/a'));
+    final RouteMatchList list2 = configuration.findMatch(Uri.parse('/b'));
     list1.push(ImperativeRouteMatch(
         pageKey: const ValueKey('/b-p0'),
         matches: list2,
diff --git a/packages/go_router/test/parser_test.dart b/packages/go_router/test/parser_test.dart
index 31b8a50e5699..9cb4aa2a071f 100644
--- a/packages/go_router/test/parser_test.dart
+++ b/packages/go_router/test/parser_test.dart
@@ -81,6 +81,68 @@ void main() {
     expect(matches[1].route, routes[0].routes[0]);
   });
 
+  testWidgets('GoRouteInformationParser can handle empty path for non http uri',
+      (WidgetTester tester) async {
+    final List routes = [
+      GoRoute(
+        path: '/',
+        builder: (_, __) => const Placeholder(),
+        routes: [
+          GoRoute(
+            path: 'abc',
+            builder: (_, __) => const Placeholder(),
+          ),
+        ],
+      ),
+    ];
+    final GoRouteInformationParser parser = await createParser(
+      tester,
+      routes: routes,
+      redirectLimit: 100,
+      redirect: (_, __) => null,
+    );
+
+    final BuildContext context = tester.element(find.byType(Router));
+
+    final RouteMatchList matchesObj =
+        await parser.parseRouteInformationWithDependencies(
+            createRouteInformation('elbaapp://domain'), context);
+    final List matches = matchesObj.matches;
+    expect(matches.length, 1);
+    expect(matchesObj.uri.toString(), 'elbaapp://domain/');
+  });
+
+  testWidgets('GoRouteInformationParser cleans up uri',
+      (WidgetTester tester) async {
+    final List routes = [
+      GoRoute(
+        path: '/',
+        builder: (_, __) => const Placeholder(),
+        routes: [
+          GoRoute(
+            path: 'abc',
+            builder: (_, __) => const Placeholder(),
+          ),
+        ],
+      ),
+    ];
+    final GoRouteInformationParser parser = await createParser(
+      tester,
+      routes: routes,
+      redirectLimit: 100,
+      redirect: (_, __) => null,
+    );
+
+    final BuildContext context = tester.element(find.byType(Router));
+
+    final RouteMatchList matchesObj =
+        await parser.parseRouteInformationWithDependencies(
+            createRouteInformation('http://domain/abc/?query=bde'), context);
+    final List matches = matchesObj.matches;
+    expect(matches.length, 2);
+    expect(matchesObj.uri.toString(), 'http://domain/abc?query=bde');
+  });
+
   testWidgets(
       "GoRouteInformationParser can parse deeplink root route and maintain uri's scheme, host, query and fragment",
       (WidgetTester tester) async {
diff --git a/packages/go_router/test/path_utils_test.dart b/packages/go_router/test/path_utils_test.dart
index 5a656df135eb..5b0b1234329b 100644
--- a/packages/go_router/test/path_utils_test.dart
+++ b/packages/go_router/test/path_utils_test.dart
@@ -79,38 +79,11 @@ void main() {
       expect(result, expected);
     }
 
-    void verifyThrows(String pathA, String pathB) {
-      expect(
-          () => concatenatePaths(pathA, pathB), throwsA(isA()));
-    }
-
     verify('/a', 'b/c', '/a/b/c');
     verify('/', 'b', '/b');
-    verifyThrows('/a', '/b');
-    verifyThrows('/a', '/');
-    verifyThrows('/', '/');
-    verifyThrows('/', '');
-    verifyThrows('', '');
-  });
-
-  test('canonicalUri', () {
-    void verify(String path, String expected) =>
-        expect(canonicalUri(path), expected);
-    verify('/a', '/a');
-    verify('/a/', '/a');
-    verify('/', '/');
-    verify('/a/b/', '/a/b');
-    verify('https://www.example.com/', 'https://www.example.com/');
-    verify('https://www.example.com/a', 'https://www.example.com/a');
-    verify('https://www.example.com/a/', 'https://www.example.com/a');
-    verify('https://www.example.com/a/b/', 'https://www.example.com/a/b');
-    verify('https://www.example.com/?', 'https://www.example.com/');
-    verify('https://www.example.com/?a=b', 'https://www.example.com/?a=b');
-    verify('https://www.example.com/?a=/', 'https://www.example.com/?a=/');
-    verify('https://www.example.com/a/?b=c', 'https://www.example.com/a?b=c');
-    verify('https://www.example.com/#a/', 'https://www.example.com/#a/');
-
-    expect(() => canonicalUri('::::'), throwsA(isA()));
-    expect(() => canonicalUri(''), throwsA(anything));
+    verify('/a', '/b/c/', '/a/b/c');
+    verify('/a', 'b/c', '/a/b/c');
+    verify('/', '/', '/');
+    verify('', '', '/');
   });
 }
diff --git a/packages/go_router_builder/CHANGELOG.md b/packages/go_router_builder/CHANGELOG.md
index 3332a70e1b8d..9367f706ae68 100644
--- a/packages/go_router_builder/CHANGELOG.md
+++ b/packages/go_router_builder/CHANGELOG.md
@@ -1,3 +1,11 @@
+## NEXT
+
+* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3.
+
+## 2.7.1
+
+- Fixes readme typos and uses code excerpts.
+
 ## 2.7.0
 
 - Adds an example and a test with `onExit`.
diff --git a/packages/go_router_builder/README.md b/packages/go_router_builder/README.md
index 73faf973937c..5d90b22f2851 100644
--- a/packages/go_router_builder/README.md
+++ b/packages/go_router_builder/README.md
@@ -23,10 +23,11 @@ Along with importing the `go_router.dart` library, it's essential to also
 include a `part` directive that references the generated Dart file. The
 generated file will always have the name `[source_file].g.dart`.
 
+
 ```dart
 import 'package:go_router/go_router.dart';
 
-part 'this_file.g.dart';
+part 'readme_excerpts.g.dart';
 ```
 
 ### Running `build_runner`
@@ -34,7 +35,7 @@ part 'this_file.g.dart';
 To do a one-time build:
 
 ```console
-flutter pub run build_runner build
+dart run build_runner build
 ```
 
 Read more about using
@@ -50,23 +51,26 @@ via the `pathParameters` and `queryParameters` properties of the `GoRouterState`
 often the page builder must first parse the parameters into types that aren't
 `String`s, e.g.
 
+
 ```dart
 GoRoute(
-  path: ':authorId',
-  builder: (context, state) {
-    // require the authorId to be present and be an integer
-    final authorId = int.parse(state.pathParameters['authorId']!);
-    return AuthorDetailsScreen(authorId: authorId);
+  path: ':familyId',
+  builder: (BuildContext context, GoRouterState state) {
+    // Require the familyId to be present and be an integer.
+    final int familyId = int.parse(state.pathParameters['familyId']!);
+    return FamilyScreen(familyId);
   },
-),
+);
 ```
 
-In this example, the `authorId` parameter is a) required and b) must be an
+In this example, the `familyId` parameter is a) required and b) must be an
 `int`. However, neither of these requirements are checked until run-time, making
 it easy to write code that is not type-safe, e.g.
 
+
 ```dart
-void _tap() => context.go('/author/a42'); // error: `a42` is not an `int`
+void tap() =>
+    context.go('/familyId/a42'); // This is an error: `a42` is not an `int`.
 ```
 
 Dart's type system allows mistakes to be caught at compile-time instead of
@@ -80,6 +84,7 @@ boilerplate code implementations ourselves.
 Define each route as a class extending `GoRouteData` and overriding the `build`
 method.
 
+
 ```dart
 class HomeRoute extends GoRouteData {
   const HomeRoute();
@@ -93,24 +98,41 @@ class HomeRoute extends GoRouteData {
 
 The tree of routes is defined as an attribute on each of the top-level routes:
 
+
 ```dart
 @TypedGoRoute(
   path: '/',
   routes: >[
     TypedGoRoute(
-      path: 'family/:familyId',
-    )
+      path: 'family/:fid',
+    ),
   ],
 )
 class HomeRoute extends GoRouteData {
   const HomeRoute();
 
   @override
-  Widget build(BuildContext context, GoRouterState state) => HomeScreen(families: familyData);
+  Widget build(BuildContext context, GoRouterState state) => const HomeScreen();
+}
+
+class RedirectRoute extends GoRouteData {
+  // There is no need to implement [build] when this [redirect] is unconditional.
+  @override
+  String? redirect(BuildContext context, GoRouterState state) {
+    return const HomeRoute().location;
+  }
 }
 
 @TypedGoRoute(path: '/login')
-class LoginRoute extends GoRouteData {...}
+class LoginRoute extends GoRouteData {
+  LoginRoute({this.from});
+  final String? from;
+
+  @override
+  Widget build(BuildContext context, GoRouterState state) {
+    return LoginScreen(from: from);
+  }
+}
 ```
 
 ## `GoRouter` initialization
@@ -118,30 +140,37 @@ class LoginRoute extends GoRouteData {...}
 The code generator aggregates all top-level routes into a single list called
 `$appRoutes` for use in initializing the `GoRouter` instance:
 
+
 ```dart
-final _router = GoRouter(routes: $appRoutes);
+final GoRouter router = GoRouter(routes: $appRoutes);
 ```
 
 ## Error builder
 
 One can use typed routes to provide an error builder as well:
 
+
 ```dart
 class ErrorRoute extends GoRouteData {
   ErrorRoute({required this.error});
   final Exception error;
 
   @override
-  Widget build(BuildContext context, GoRouterState state) => ErrorScreen(error: error);
+  Widget build(BuildContext context, GoRouterState state) {
+    return ErrorScreen(error: error);
+  }
 }
 ```
 
 With this in place, you can provide the `errorBuilder` parameter like so:
 
+
 ```dart
-final _router = GoRouter(
+final GoRouter routerWithErrorBuilder = GoRouter(
   routes: $appRoutes,
-  errorBuilder: (c, s) => ErrorRoute(s.error!).build(c),
+  errorBuilder: (BuildContext context, GoRouterState state) {
+    return ErrorRoute(error: state.error!).build(context, state);
+  },
 );
 ```
 
@@ -149,15 +178,17 @@ final _router = GoRouter(
 
 Navigate using the `go` or `push` methods provided by the code generator:
 
+
 ```dart
-void _tap() => PersonRoute(fid: 'f2', pid: 'p1').go(context);
+void onTap() => const FamilyRoute(fid: 'f2').go(context);
 ```
 
 If you get this wrong, the compiler will complain:
 
+
 ```dart
-// error: missing required parameter 'fid'
-void _tap() => PersonRoute(pid: 'p1').go(context);
+// This is an error: missing required parameter 'fid'.
+void errorTap() => const FamilyRoute().go(context);
 ```
 
 This is the point of typed routing: the error is found statically.
@@ -167,24 +198,27 @@ This is the point of typed routing: the error is found statically.
 Starting from `go_router` 6.5.0, pushing a route and subsequently popping it, can produce
 a return value. The generated routes also follow this functionality.
 
+
 ```dart
-void _tap() async {
-  final result = await PersonRoute(pid: 'p1').go(context);
-}
+final bool? result =
+    await const FamilyRoute(fid: 'John').push(context);
 ```
 
 ## Query parameters
 
 Parameters (named or positional) not listed in the path of `TypedGoRoute` indicate query parameters:
 
+
 ```dart
-@TypedGoRoute(path: '/login')
+@TypedGoRoute(path: '/login')
 class LoginRoute extends GoRouteData {
   LoginRoute({this.from});
   final String? from;
 
   @override
-  Widget build(BuildContext context, GoRouterState state) => LoginScreen(from: from);
+  Widget build(BuildContext context, GoRouterState state) {
+    return LoginScreen(from: from);
+  }
 }
 ```
 
@@ -192,14 +226,17 @@ class LoginRoute extends GoRouteData {
 
 For query parameters with a **non-nullable** type, you can define a default value:
 
+
 ```dart
-@TypedGoRoute(path: '/my-route')
+@TypedGoRoute(path: '/my-route')
 class MyRoute extends GoRouteData {
   MyRoute({this.queryParameter = 'defaultValue'});
   final String queryParameter;
 
   @override
-  Widget build(BuildContext context, GoRouterState state) => MyScreen(queryParameter: queryParameter);
+  Widget build(BuildContext context, GoRouterState state) {
+    return MyScreen(queryParameter: queryParameter);
+  }
 }
 ```
 
@@ -211,20 +248,26 @@ A query parameter that equals to its default value is not included in the locati
 A route can consume an extra parameter by taking it as a typed constructor
 parameter with the special name `$extra`:
 
+
 ```dart
 class PersonRouteWithExtra extends GoRouteData {
-  PersonRouteWithExtra({this.$extra});
-  final int? $extra;
+  PersonRouteWithExtra(this.$extra);
+  final Person? $extra;
 
   @override
-  Widget build(BuildContext context, GoRouterState state) => PersonScreen(personId: $extra);
+  Widget build(BuildContext context, GoRouterState state) {
+    return PersonScreen($extra);
+  }
 }
 ```
 
 Pass the extra param as a typed object:
 
+
 ```dart
-void _tap() => PersonRouteWithExtra(Person(name: 'Marvin', age: 42)).go(context);
+void tapWithExtra() {
+  PersonRouteWithExtra(Person(id: 1, name: 'Marvin', age: 42)).go(context);
+}
 ```
 
 The `$extra` parameter is still passed outside the location, still defeats
@@ -235,16 +278,19 @@ recommended when targeting Flutter web.
 
 You can, of course, combine the use of path, query and $extra parameters:
 
+
 ```dart
 @TypedGoRoute(path: '/:ketchup')
 class HotdogRouteWithEverything extends GoRouteData {
   HotdogRouteWithEverything(this.ketchup, this.mustard, this.$extra);
-  final bool ketchup; // required path parameter
-  final String? mustard; // optional query parameter
-  final Sauce $extra; // special $extra parameter
+  final bool ketchup; // A required path parameter.
+  final String? mustard; // An optional query parameter.
+  final Sauce $extra; // A special $extra parameter.
 
   @override
-  Widget build(BuildContext context, GoRouterState state) => HotdogScreen(ketchup, mustard, $extra);
+  Widget build(BuildContext context, GoRouterState state) {
+    return HotdogScreen(ketchup, mustard, $extra);
+  }
 }
 ```
 
@@ -255,25 +301,33 @@ This seems kinda silly, but it works.
 Redirect using the `location` property on a route provided by the code
 generator:
 
+
 ```dart
-redirect: (state) {
-  final loggedIn = loginInfo.loggedIn;
-  final loggingIn = state.matchedLocation == LoginRoute().location;
-  if( !loggedIn && !loggingIn ) return LoginRoute(from: state.matchedLocation).location;
-  if( loggedIn && loggingIn ) return HomeRoute().location;
+redirect: (BuildContext context, GoRouterState state) {
+  final bool loggedIn = loginInfo.loggedIn;
+  final bool loggingIn = state.matchedLocation == LoginRoute().location;
+  if (!loggedIn && !loggingIn) {
+    return LoginRoute(from: state.matchedLocation).location;
+  }
+  if (loggedIn && loggingIn) {
+    return const HomeRoute().location;
+  }
   return null;
-}
+},
 ```
 
 ## Route-level redirection
 
 Handle route-level redirects by implementing the `redirect` method on the route:
 
+
 ```dart
-class HomeRoute extends GoRouteData {
-  // no need to implement [build] when this [redirect] is unconditional
+class RedirectRoute extends GoRouteData {
+  // There is no need to implement [build] when this [redirect] is unconditional.
   @override
-  String? redirect(BuildContext context, GoRouterState state) => BooksRoute().location;
+  String? redirect(BuildContext context, GoRouterState state) {
+    return const HomeRoute().location;
+  }
 }
 ```
 
@@ -282,6 +336,7 @@ class HomeRoute extends GoRouteData {
 The code generator can convert simple types like `int` and `enum` to/from the
 `String` type of the underlying pathParameters:
 
+
 ```dart
 enum BookKind { all, popular, recent }
 
@@ -290,7 +345,9 @@ class BooksRoute extends GoRouteData {
   final BookKind kind;
 
   @override
-  Widget build(BuildContext context, GoRouterState state) => BooksScreen(kind: kind);
+  Widget build(BuildContext context, GoRouterState state) {
+    return BooksScreen(kind: kind);
+  }
 }
 ```
 
@@ -310,15 +367,17 @@ type, pass non-default parameters when creating the page (like a custom key) or
 access the `GoRouteState` object, you can override the `buildPage`
 method of the base class instead of the `build` method:
 
+
 ```dart
 class MyMaterialRouteWithKey extends GoRouteData {
-  static final _key = LocalKey('my-route-with-key');
+  static const LocalKey _key = ValueKey('my-route-with-key');
   @override
-  MaterialPage buildPage(BuildContext context, GoRouterState state) =>
-    MaterialPage(
+  MaterialPage buildPage(BuildContext context, GoRouterState state) {
+    return const MaterialPage(
       key: _key,
       child: MyPage(),
     );
+  }
 }
 ```
 
@@ -326,16 +385,22 @@ class MyMaterialRouteWithKey extends GoRouteData {
 
 Overriding the `buildPage` method is also useful for custom transitions:
 
+
 ```dart
 class FancyRoute extends GoRouteData {
   @override
-  MaterialPage buildPage(BuildContext context, GoRouterState state) =>
-    CustomTransitionPage(
-      key: state.pageKey,
-      child: FancyPage(),
-      transitionsBuilder: (context, animation, animation2, child) =>
-          RotationTransition(turns: animation, child: child),
-    ),
+  CustomTransitionPage buildPage(
+    BuildContext context,
+    GoRouterState state,
+  ) {
+    return CustomTransitionPage(
+        key: state.pageKey,
+        child: const MyPage(),
+        transitionsBuilder: (BuildContext context, Animation animation,
+            Animation secondaryAnimation, Widget child) {
+          return RotationTransition(turns: animation, child: child);
+        });
+  }
 }
 ```
 
@@ -350,9 +415,10 @@ different navigator. This kind of scenarios can be achieved by declaring a
 
 Example:
 
+
 ```dart
-// For ShellRoutes:
 final GlobalKey shellNavigatorKey = GlobalKey();
+final GlobalKey rootNavigatorKey = GlobalKey();
 
 class MyShellRouteData extends ShellRouteData {
   const MyShellRouteData();
@@ -361,7 +427,7 @@ class MyShellRouteData extends ShellRouteData {
 
   @override
   Widget builder(BuildContext context, GoRouterState state, Widget navigator) {
-    // ...
+    return MyShellRoutePage(navigator);
   }
 }
 
@@ -372,9 +438,7 @@ class MyGoRouteData extends GoRouteData {
   static final GlobalKey $parentNavigatorKey = rootNavigatorKey;
 
   @override
-  Widget build(BuildContext context, GoRouterState state) {
-    // ...
-  }
+  Widget build(BuildContext context, GoRouterState state) => const MyPage();
 }
 ```
 
@@ -384,4 +448,4 @@ An example is available [here](https://github.com/flutter/packages/blob/main/pac
 
 To run unit tests, run command `dart tool/run_tests.dart` from `packages/go_router_builder/`.
 
-To run tests in examples, run `flutter test` from `packages/go_router_builder/example`.
\ No newline at end of file
+To run tests in examples, run `flutter test` from `packages/go_router_builder/example`.
diff --git a/packages/go_router_builder/example/lib/readme_excerpts.dart b/packages/go_router_builder/example/lib/readme_excerpts.dart
new file mode 100644
index 000000000000..28eabdf1fa52
--- /dev/null
+++ b/packages/go_router_builder/example/lib/readme_excerpts.dart
@@ -0,0 +1,417 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// ignore_for_file: public_member_api_docs, unreachable_from_main, avoid_print, unused_element, unused_local_variable, directives_ordering
+
+import 'package:flutter/material.dart';
+import 'shared/data.dart';
+// #docregion import
+import 'package:go_router/go_router.dart';
+
+part 'readme_excerpts.g.dart';
+// #enddocregion import
+
+void otherDoc(BuildContext context) {
+  // #docregion GoRoute
+  GoRoute(
+    path: ':familyId',
+    builder: (BuildContext context, GoRouterState state) {
+      // Require the familyId to be present and be an integer.
+      final int familyId = int.parse(state.pathParameters['familyId']!);
+      return FamilyScreen(familyId);
+    },
+  );
+  // #enddocregion GoRoute
+
+  // #docregion GoWrong
+  void tap() =>
+      context.go('/familyId/a42'); // This is an error: `a42` is not an `int`.
+  // #enddocregion GoWrong
+
+  // #docregion GoRouter
+  final GoRouter router = GoRouter(routes: $appRoutes);
+  // #enddocregion GoRouter
+
+  // #docregion routerWithErrorBuilder
+  final GoRouter routerWithErrorBuilder = GoRouter(
+    routes: $appRoutes,
+    errorBuilder: (BuildContext context, GoRouterState state) {
+      return ErrorRoute(error: state.error!).build(context, state);
+    },
+  );
+  // #enddocregion routerWithErrorBuilder
+
+  // #docregion go
+  void onTap() => const FamilyRoute(fid: 'f2').go(context);
+  // #enddocregion go
+
+  // #docregion goError
+  // This is an error: missing required parameter 'fid'.
+  void errorTap() => const FamilyRoute().go(context);
+  // #enddocregion goError
+
+  // #docregion tapWithExtra
+  void tapWithExtra() {
+    PersonRouteWithExtra(Person(id: 1, name: 'Marvin', age: 42)).go(context);
+  }
+  // #enddocregion tapWithExtra
+
+  final LoginInfo loginInfo = LoginInfo();
+
+  final GoRouter routerWithRedirect = GoRouter(
+    routes: $appRoutes,
+    // #docregion redirect
+    redirect: (BuildContext context, GoRouterState state) {
+      final bool loggedIn = loginInfo.loggedIn;
+      final bool loggingIn = state.matchedLocation == LoginRoute().location;
+      if (!loggedIn && !loggingIn) {
+        return LoginRoute(from: state.matchedLocation).location;
+      }
+      if (loggedIn && loggingIn) {
+        return const HomeRoute().location;
+      }
+      return null;
+    },
+    // #enddocregion redirect
+  );
+}
+
+// #docregion TypedGoRouteHomeRoute
+@TypedGoRoute(
+  path: '/',
+  routes: >[
+    TypedGoRoute(
+      path: 'family/:fid',
+    ),
+  ],
+)
+// #docregion HomeRoute
+class HomeRoute extends GoRouteData {
+  const HomeRoute();
+
+  @override
+  Widget build(BuildContext context, GoRouterState state) => const HomeScreen();
+}
+// #enddocregion HomeRoute
+
+// #docregion RedirectRoute
+class RedirectRoute extends GoRouteData {
+  // There is no need to implement [build] when this [redirect] is unconditional.
+  @override
+  String? redirect(BuildContext context, GoRouterState state) {
+    return const HomeRoute().location;
+  }
+}
+// #enddocregion RedirectRoute
+
+// #docregion login
+@TypedGoRoute(path: '/login')
+class LoginRoute extends GoRouteData {
+  LoginRoute({this.from});
+  final String? from;
+
+  @override
+  Widget build(BuildContext context, GoRouterState state) {
+    return LoginScreen(from: from);
+  }
+}
+// #enddocregion login
+// #enddocregion TypedGoRouteHomeRoute
+
+class HomeScreen extends StatelessWidget {
+  const HomeScreen({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: const Text('home'),
+      ),
+      body: TextButton(
+        onPressed: () async {
+          // #docregion awaitPush
+          final bool? result =
+              await const FamilyRoute(fid: 'John').push(context);
+          // #enddocregion awaitPush
+          print('result is $result');
+        },
+        child: const Text('push'),
+      ),
+    );
+  }
+}
+
+class FamilyRoute extends GoRouteData {
+  const FamilyRoute({this.fid});
+
+  final String? fid;
+
+  @override
+  Widget build(BuildContext context, GoRouterState state) {
+    return FamilyScreen(int.parse(fid!));
+  }
+}
+
+class FamilyScreen extends StatelessWidget {
+  const FamilyScreen(this.fid, {super.key});
+
+  final int fid;
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: const Text('family'),
+      ),
+      body: TextButton(
+        onPressed: () {
+          context.pop(true);
+        },
+        child: const Text('pop with true'),
+      ),
+    );
+  }
+}
+
+// #docregion ErrorRoute
+class ErrorRoute extends GoRouteData {
+  ErrorRoute({required this.error});
+  final Exception error;
+
+  @override
+  Widget build(BuildContext context, GoRouterState state) {
+    return ErrorScreen(error: error);
+  }
+}
+// #enddocregion ErrorRoute
+
+class ErrorScreen extends StatelessWidget {
+  const ErrorScreen({required this.error, super.key});
+
+  final Exception error;
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: const Text('Error'),
+      ),
+      body: Text(error.toString()),
+    );
+  }
+}
+
+class LoginScreen extends StatelessWidget {
+  const LoginScreen({required this.from, super.key});
+  final String? from;
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: const Text('Login'),
+      ),
+    );
+  }
+}
+
+// #docregion MyRoute
+@TypedGoRoute(path: '/my-route')
+class MyRoute extends GoRouteData {
+  MyRoute({this.queryParameter = 'defaultValue'});
+  final String queryParameter;
+
+  @override
+  Widget build(BuildContext context, GoRouterState state) {
+    return MyScreen(queryParameter: queryParameter);
+  }
+}
+// #enddocregion MyRoute
+
+class MyScreen extends StatelessWidget {
+  const MyScreen({required this.queryParameter, super.key});
+  final String queryParameter;
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: const Text('MyScreen'),
+      ),
+    );
+  }
+}
+
+@TypedGoRoute(path: '/person')
+// #docregion PersonRouteWithExtra
+class PersonRouteWithExtra extends GoRouteData {
+  PersonRouteWithExtra(this.$extra);
+  final Person? $extra;
+
+  @override
+  Widget build(BuildContext context, GoRouterState state) {
+    return PersonScreen($extra);
+  }
+}
+// #enddocregion PersonRouteWithExtra
+
+class PersonScreen extends StatelessWidget {
+  const PersonScreen(this.person, {super.key});
+  final Person? person;
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: const Text('PersonScreen'),
+      ),
+    );
+  }
+}
+
+// #docregion HotdogRouteWithEverything
+@TypedGoRoute(path: '/:ketchup')
+class HotdogRouteWithEverything extends GoRouteData {
+  HotdogRouteWithEverything(this.ketchup, this.mustard, this.$extra);
+  final bool ketchup; // A required path parameter.
+  final String? mustard; // An optional query parameter.
+  final Sauce $extra; // A special $extra parameter.
+
+  @override
+  Widget build(BuildContext context, GoRouterState state) {
+    return HotdogScreen(ketchup, mustard, $extra);
+  }
+}
+// #enddocregion HotdogRouteWithEverything
+
+class Sauce {}
+
+class HotdogScreen extends StatelessWidget {
+  const HotdogScreen(this.ketchup, this.mustard, this.extra, {super.key});
+  final bool ketchup;
+  final String? mustard;
+  final Sauce extra;
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: const Text('Hotdog'),
+      ),
+    );
+  }
+}
+
+// #docregion BookKind
+enum BookKind { all, popular, recent }
+
+class BooksRoute extends GoRouteData {
+  BooksRoute({this.kind = BookKind.popular});
+  final BookKind kind;
+
+  @override
+  Widget build(BuildContext context, GoRouterState state) {
+    return BooksScreen(kind: kind);
+  }
+}
+// #enddocregion BookKind
+
+class BooksScreen extends StatelessWidget {
+  const BooksScreen({required this.kind, super.key});
+  final BookKind kind;
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: const Text('BooksScreen'),
+      ),
+    );
+  }
+}
+
+// #docregion MyMaterialRouteWithKey
+class MyMaterialRouteWithKey extends GoRouteData {
+  static const LocalKey _key = ValueKey('my-route-with-key');
+  @override
+  MaterialPage buildPage(BuildContext context, GoRouterState state) {
+    return const MaterialPage(
+      key: _key,
+      child: MyPage(),
+    );
+  }
+}
+// #enddocregion MyMaterialRouteWithKey
+
+class MyPage extends StatelessWidget {
+  const MyPage({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: const Text('MyPage'),
+      ),
+    );
+  }
+}
+
+class MyShellRoutePage extends StatelessWidget {
+  const MyShellRoutePage(this.child, {super.key});
+  final Widget child;
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: const Text('MyShellRoutePage'),
+      ),
+      body: child,
+    );
+  }
+}
+
+// #docregion FancyRoute
+class FancyRoute extends GoRouteData {
+  @override
+  CustomTransitionPage buildPage(
+    BuildContext context,
+    GoRouterState state,
+  ) {
+    return CustomTransitionPage(
+        key: state.pageKey,
+        child: const MyPage(),
+        transitionsBuilder: (BuildContext context, Animation animation,
+            Animation secondaryAnimation, Widget child) {
+          return RotationTransition(turns: animation, child: child);
+        });
+  }
+}
+// #enddocregion FancyRoute
+
+// #docregion MyShellRouteData
+final GlobalKey shellNavigatorKey = GlobalKey();
+final GlobalKey rootNavigatorKey = GlobalKey();
+
+class MyShellRouteData extends ShellRouteData {
+  const MyShellRouteData();
+
+  static final GlobalKey $navigatorKey = shellNavigatorKey;
+
+  @override
+  Widget builder(BuildContext context, GoRouterState state, Widget navigator) {
+    return MyShellRoutePage(navigator);
+  }
+}
+
+// For GoRoutes:
+class MyGoRouteData extends GoRouteData {
+  const MyGoRouteData();
+
+  static final GlobalKey $parentNavigatorKey = rootNavigatorKey;
+
+  @override
+  Widget build(BuildContext context, GoRouterState state) => const MyPage();
+}
+// #enddocregion MyShellRouteData
diff --git a/packages/go_router_builder/example/lib/readme_excerpts.g.dart b/packages/go_router_builder/example/lib/readme_excerpts.g.dart
new file mode 100644
index 000000000000..f6ec99f9d2c2
--- /dev/null
+++ b/packages/go_router_builder/example/lib/readme_excerpts.g.dart
@@ -0,0 +1,190 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+// ignore_for_file: always_specify_types, public_member_api_docs
+
+part of 'readme_excerpts.dart';
+
+// **************************************************************************
+// GoRouterGenerator
+// **************************************************************************
+
+List get $appRoutes => [
+      $homeRoute,
+      $loginRoute,
+      $myRoute,
+      $personRouteWithExtra,
+      $hotdogRouteWithEverything,
+    ];
+
+RouteBase get $homeRoute => GoRouteData.$route(
+      path: '/',
+      factory: $HomeRouteExtension._fromState,
+      routes: [
+        GoRouteData.$route(
+          path: 'family/:fid',
+          factory: $FamilyRouteExtension._fromState,
+        ),
+      ],
+    );
+
+extension $HomeRouteExtension on HomeRoute {
+  static HomeRoute _fromState(GoRouterState state) => const HomeRoute();
+
+  String get location => GoRouteData.$location(
+        '/',
+      );
+
+  void go(BuildContext context) => context.go(location);
+
+  Future push(BuildContext context) => context.push(location);
+
+  void pushReplacement(BuildContext context) =>
+      context.pushReplacement(location);
+
+  void replace(BuildContext context) => context.replace(location);
+}
+
+extension $FamilyRouteExtension on FamilyRoute {
+  static FamilyRoute _fromState(GoRouterState state) => FamilyRoute(
+        fid: state.pathParameters['fid']!,
+      );
+
+  String get location => GoRouteData.$location(
+        '/family/${Uri.encodeComponent(fid)}',
+      );
+
+  void go(BuildContext context) => context.go(location);
+
+  Future push(BuildContext context) => context.push(location);
+
+  void pushReplacement(BuildContext context) =>
+      context.pushReplacement(location);
+
+  void replace(BuildContext context) => context.replace(location);
+}
+
+RouteBase get $loginRoute => GoRouteData.$route(
+      path: '/login',
+      factory: $LoginRouteExtension._fromState,
+    );
+
+extension $LoginRouteExtension on LoginRoute {
+  static LoginRoute _fromState(GoRouterState state) => LoginRoute(
+        from: state.uri.queryParameters['from'],
+      );
+
+  String get location => GoRouteData.$location(
+        '/login',
+        queryParams: {
+          if (from != null) 'from': from,
+        },
+      );
+
+  void go(BuildContext context) => context.go(location);
+
+  Future push(BuildContext context) => context.push(location);
+
+  void pushReplacement(BuildContext context) =>
+      context.pushReplacement(location);
+
+  void replace(BuildContext context) => context.replace(location);
+}
+
+RouteBase get $myRoute => GoRouteData.$route(
+      path: '/my-route',
+      factory: $MyRouteExtension._fromState,
+    );
+
+extension $MyRouteExtension on MyRoute {
+  static MyRoute _fromState(GoRouterState state) => MyRoute(
+        queryParameter:
+            state.uri.queryParameters['query-parameter'] ?? 'defaultValue',
+      );
+
+  String get location => GoRouteData.$location(
+        '/my-route',
+        queryParams: {
+          if (queryParameter != 'defaultValue')
+            'query-parameter': queryParameter,
+        },
+      );
+
+  void go(BuildContext context) => context.go(location);
+
+  Future push(BuildContext context) => context.push(location);
+
+  void pushReplacement(BuildContext context) =>
+      context.pushReplacement(location);
+
+  void replace(BuildContext context) => context.replace(location);
+}
+
+RouteBase get $personRouteWithExtra => GoRouteData.$route(
+      path: '/person',
+      factory: $PersonRouteWithExtraExtension._fromState,
+    );
+
+extension $PersonRouteWithExtraExtension on PersonRouteWithExtra {
+  static PersonRouteWithExtra _fromState(GoRouterState state) =>
+      PersonRouteWithExtra(
+        state.extra as Person?,
+      );
+
+  String get location => GoRouteData.$location(
+        '/person',
+      );
+
+  void go(BuildContext context) => context.go(location, extra: $extra);
+
+  Future push(BuildContext context) =>
+      context.push(location, extra: $extra);
+
+  void pushReplacement(BuildContext context) =>
+      context.pushReplacement(location, extra: $extra);
+
+  void replace(BuildContext context) =>
+      context.replace(location, extra: $extra);
+}
+
+RouteBase get $hotdogRouteWithEverything => GoRouteData.$route(
+      path: '/:ketchup',
+      factory: $HotdogRouteWithEverythingExtension._fromState,
+    );
+
+extension $HotdogRouteWithEverythingExtension on HotdogRouteWithEverything {
+  static HotdogRouteWithEverything _fromState(GoRouterState state) =>
+      HotdogRouteWithEverything(
+        _$boolConverter(state.pathParameters['ketchup']!),
+        state.uri.queryParameters['mustard'],
+        state.extra as Sauce,
+      );
+
+  String get location => GoRouteData.$location(
+        '/${Uri.encodeComponent(ketchup.toString())}',
+        queryParams: {
+          if (mustard != null) 'mustard': mustard,
+        },
+      );
+
+  void go(BuildContext context) => context.go(location, extra: $extra);
+
+  Future push(BuildContext context) =>
+      context.push(location, extra: $extra);
+
+  void pushReplacement(BuildContext context) =>
+      context.pushReplacement(location, extra: $extra);
+
+  void replace(BuildContext context) =>
+      context.replace(location, extra: $extra);
+}
+
+bool _$boolConverter(String value) {
+  switch (value) {
+    case 'true':
+      return true;
+    case 'false':
+      return false;
+    default:
+      throw UnsupportedError('Cannot convert "$value" into a bool.');
+  }
+}
diff --git a/packages/go_router_builder/example/pubspec.yaml b/packages/go_router_builder/example/pubspec.yaml
index bc02b13402eb..a4d0efc279db 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.2.0
+  sdk: ^3.3.0
 
 dependencies:
   collection: ^1.15.0
diff --git a/packages/go_router_builder/pubspec.yaml b/packages/go_router_builder/pubspec.yaml
index 0e6e10b6b3d6..6686ec3ba126 100644
--- a/packages/go_router_builder/pubspec.yaml
+++ b/packages/go_router_builder/pubspec.yaml
@@ -2,13 +2,13 @@ name: go_router_builder
 description: >-
   A builder that supports generated strongly-typed route helpers for
   package:go_router
-version: 2.7.0
+version: 2.7.1
 repository: https://github.com/flutter/packages/tree/main/packages/go_router_builder
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+go_router_builder%22
 
 environment:
-  sdk: ^3.2.0
-  flutter: ">=3.16.0"
+  sdk: ^3.3.0
+  flutter: ">=3.19.0"
 
 dependencies:
   analyzer: ">=5.2.0 <7.0.0"
diff --git a/packages/google_identity_services_web/CHANGELOG.md b/packages/google_identity_services_web/CHANGELOG.md
index d7ed98a3c8cd..8f476099fc4d 100644
--- a/packages/google_identity_services_web/CHANGELOG.md
+++ b/packages/google_identity_services_web/CHANGELOG.md
@@ -1,3 +1,23 @@
+## 0.3.1+5
+
+* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4.
+* Cleans up documentation of callbacks in `CodeClientConfig`,
+  `TokenClientConfig`, `onGoogleLibraryLoad`, and `revoke` to indicate they only
+  accept Dart functions and not JS functions.
+
+## 0.3.1+4
+
+* Restores support for Dart `^3.3.0`.
+
+## 0.3.1+3
+
+* Updates `README.md` to reflect modern `index.html` script tag placement.
+
+## 0.3.1+2
+
+* Adds support for `web: ^1.0.0`.
+* Updates SDK version to Dart `^3.4.0`. Flutter `^3.22.0`.
+
 ## 0.3.1+1
 
 * Uses `TrustedTypes` from `web: ^0.5.1`.
diff --git a/packages/google_identity_services_web/README.md b/packages/google_identity_services_web/README.md
index 65214000a74d..733644af5ba0 100644
--- a/packages/google_identity_services_web/README.md
+++ b/packages/google_identity_services_web/README.md
@@ -24,8 +24,7 @@ There are two ways to load the JS SDK in your app.
 
 The most performant way is to modify your `web/index.html` file to insert a
 script tag [as recommended](https://developers.google.com/identity/gsi/web/guides/client-library).
-Place the `script` tag in the `` of your site, next to the script tag that
-loads `flutter.js`, so the browser can downloaded both in parallel:
+Place the `script` tag in the `` of your site:
 
 
 ```html
@@ -33,8 +32,6 @@ loads `flutter.js`, so the browser can downloaded both in parallel:
 
   
   
-  
-  
 
 ```
 
diff --git a/packages/google_identity_services_web/example/integration_test/js_interop_oauth_test.dart b/packages/google_identity_services_web/example/integration_test/js_interop_oauth_test.dart
index c197b1116dc6..cf243b0859e7 100644
--- a/packages/google_identity_services_web/example/integration_test/js_interop_oauth_test.dart
+++ b/packages/google_identity_services_web/example/integration_test/js_interop_oauth_test.dart
@@ -26,7 +26,7 @@ void main() async {
     testWidgets('TokenClientConfig', (_) async {
       final TokenClientConfig config = TokenClientConfig(
         client_id: 'testing_1-2-3',
-        callback: (_) {},
+        callback: (TokenResponse _) {},
         scope: ['one', 'two', 'three'],
         include_granted_scopes: true,
         prompt: 'some-prompt',
@@ -34,7 +34,7 @@ void main() async {
         login_hint: 'login-hint@example.com',
         hd: 'hd_value',
         state: 'some-state',
-        error_callback: (_) {},
+        error_callback: (GoogleIdentityServicesError? _) {},
       );
 
       final utils.ExpectConfigValueFn expectConfigValue =
@@ -79,14 +79,14 @@ void main() async {
         scope: ['one', 'two', 'three'],
         include_granted_scopes: true,
         redirect_uri: Uri.parse('https://www.example.com/login'),
-        callback: (_) {},
+        callback: (CodeResponse _) {},
         state: 'some-state',
         enable_granular_consent: true,
         login_hint: 'login-hint@example.com',
         hd: 'hd_value',
         ux_mode: UxMode.popup,
         select_account: true,
-        error_callback: (_) {},
+        error_callback: (GoogleIdentityServicesError? _) {},
       );
 
       final utils.ExpectConfigValueFn expectConfigValue =
@@ -110,7 +110,7 @@ void main() async {
     testWidgets('returns a tokenClient', (_) async {
       final TokenClient client = oauth2.initTokenClient(TokenClientConfig(
         client_id: 'for-tests',
-        callback: (_) {},
+        callback: (TokenResponse _) {},
         scope: ['some_scope', 'for_tests', 'not_real'],
       ));
 
diff --git a/packages/google_identity_services_web/example/pubspec.yaml b/packages/google_identity_services_web/example/pubspec.yaml
index fa625a5edd69..e2011307e939 100644
--- a/packages/google_identity_services_web/example/pubspec.yaml
+++ b/packages/google_identity_services_web/example/pubspec.yaml
@@ -3,16 +3,16 @@ description: An example for the google_identity_services_web package, OneTap.
 publish_to: 'none'
 
 environment:
-  sdk: ^3.3.0
-  flutter: ">=3.19.0"
+  sdk: ^3.4.0
+  flutter: ">=3.22.0"
 
 dependencies:
   flutter:
     sdk: flutter
   google_identity_services_web:
     path: ../
-  http: ">=0.13.0 <2.0.0"
-  web: ^0.5.1
+  http: ^1.2.2
+  web: ^1.0.0
 
 dev_dependencies:
   build_runner: ^2.1.10 # To extract README excerpts only.
diff --git a/packages/google_identity_services_web/example/web/index-with-script-tag.html b/packages/google_identity_services_web/example/web/index-with-script-tag.html
index 07441f7a5d44..bae6382acfa6 100644
--- a/packages/google_identity_services_web/example/web/index-with-script-tag.html
+++ b/packages/google_identity_services_web/example/web/index-with-script-tag.html
@@ -24,30 +24,12 @@
   Authentication Example
   
 
-  
 
   
   
-  
-  
 
 
 
-  
+  
 
 
diff --git a/packages/google_identity_services_web/example/web/index.html b/packages/google_identity_services_web/example/web/index.html
index 5727323c8dbd..4c6fa80e71be 100644
--- a/packages/google_identity_services_web/example/web/index.html
+++ b/packages/google_identity_services_web/example/web/index.html
@@ -22,30 +22,12 @@
   Authentication Example
   
 
-  
   
   
   
   
-  
-  
 
 
-  
+  
 
 
diff --git a/packages/google_identity_services_web/lib/src/js_interop/google_accounts_id.dart b/packages/google_identity_services_web/lib/src/js_interop/google_accounts_id.dart
index 8467854640e8..99bc70690a4a 100644
--- a/packages/google_identity_services_web/lib/src/js_interop/google_accounts_id.dart
+++ b/packages/google_identity_services_web/lib/src/js_interop/google_accounts_id.dart
@@ -164,7 +164,8 @@ extension GoogleAccountsIdExtension on GoogleAccountsId {
   /// ID is the `sub` property of the [CredentialResponse.credential] payload.
   ///
   /// The optional [callback] is a function that gets called to report on the
-  /// success of the revocation call.
+  /// success of the revocation call. It must be a Dart function and not a JS
+  /// function.
   ///
   /// Method: google.accounts.id.revoke
   /// https://developers.google.com/identity/gsi/web/reference/js-reference#google.accounts.id.revoke
diff --git a/packages/google_identity_services_web/lib/src/js_interop/google_accounts_oauth2.dart b/packages/google_identity_services_web/lib/src/js_interop/google_accounts_oauth2.dart
index 9c97ba43b6aa..30a843b07e05 100644
--- a/packages/google_identity_services_web/lib/src/js_interop/google_accounts_oauth2.dart
+++ b/packages/google_identity_services_web/lib/src/js_interop/google_accounts_oauth2.dart
@@ -73,7 +73,7 @@ extension GoogleAccountsOauth2Extension on GoogleAccountsOauth2 {
   /// A valid [accessToken] is required to revoke permissions.
   ///
   /// The [done] callback is called once the revoke action is done. It must be
-  /// manually wrapped in [allowInterop] before being passed to this method.
+  /// a Dart function and not a JS function.
   ///
   /// Method: google.accounts.oauth2.revoke
   /// https://developers.google.com/identity/oauth2/web/reference/js-reference#google.accounts.oauth2.revoke
@@ -103,8 +103,7 @@ extension GoogleAccountsOauth2Extension on GoogleAccountsOauth2 {
 abstract class CodeClientConfig {
   /// Constructs a CodeClientConfig object in JavaScript.
   ///
-  /// The [callback] property must be wrapped in [allowInterop] before it's
-  /// passed to this constructor.
+  /// The [callback] property must be a Dart function and not a JS function.
   factory CodeClientConfig({
     required String client_id,
     required List scope,
@@ -230,8 +229,7 @@ typedef CodeClientCallbackFn = void Function(CodeResponse response);
 abstract class TokenClientConfig {
   /// Constructs a TokenClientConfig object in JavaScript.
   ///
-  /// The [callback] property must be wrapped in [allowInterop] before it's
-  /// passed to this constructor.
+  /// The [callback] property must be a Dart function and not a JS function.
   factory TokenClientConfig({
     required String client_id,
     required TokenClientCallbackFn callback,
@@ -315,9 +313,6 @@ extension TokenClientExtension on TokenClient {
 @staticInterop
 abstract class OverridableTokenClientConfig {
   /// Constructs an OverridableTokenClientConfig object in JavaScript.
-  ///
-  /// The [callback] property must be wrapped in [allowInterop] before it's
-  /// passed to this constructor.
   factory OverridableTokenClientConfig({
     /// A list of scopes that identify the resources that your application could
     /// access on the user's behalf. These values inform the consent screen that
diff --git a/packages/google_identity_services_web/lib/src/js_interop/load_callback.dart b/packages/google_identity_services_web/lib/src/js_interop/load_callback.dart
index 7df615017f7f..23b08447b8b6 100644
--- a/packages/google_identity_services_web/lib/src/js_interop/load_callback.dart
+++ b/packages/google_identity_services_web/lib/src/js_interop/load_callback.dart
@@ -23,8 +23,7 @@ external set _onGoogleLibraryLoad(JSFunction callback);
 
 /// Method called after the Sign In With Google JavaScript library is loaded.
 ///
-/// The [callback] parameter must be manually wrapped in [allowInterop]
-/// before being set to the [onGoogleLibraryLoad] property.
+/// The [function] parameter must be a Dart function and not a JS function.
 set onGoogleLibraryLoad(VoidFn function) {
   _onGoogleLibraryLoad = function.toJS;
 }
diff --git a/packages/google_identity_services_web/pubspec.yaml b/packages/google_identity_services_web/pubspec.yaml
index 0c61580d79e2..21f6a0c3d583 100644
--- a/packages/google_identity_services_web/pubspec.yaml
+++ b/packages/google_identity_services_web/pubspec.yaml
@@ -2,14 +2,14 @@ name: google_identity_services_web
 description: A Dart JS-interop layer for Google Identity Services. Google's new sign-in SDK for Web that supports multiple types of credentials.
 repository: https://github.com/flutter/packages/tree/main/packages/google_identity_services_web
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+google_identiy_services_web%22
-version: 0.3.1+1
+version: 0.3.1+5
 
 environment:
-  sdk: ^3.3.0
+  sdk: ^3.4.0
 
 dependencies:
   meta: ^1.3.0
-  web: ^0.5.1
+  web: ">=0.5.1 <2.0.0"
 
 dev_dependencies:
   path: ^1.8.1
diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md
index c92f63deb0eb..c809dfb10f86 100644
--- a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md
+++ b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md
@@ -1,3 +1,19 @@
+## NEXT
+
+* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3.
+
+## 2.9.0
+
+* Adds clustering support.
+
+## 2.8.0
+
+* Adds support for heatmap layers.
+
+## 2.7.1
+
+* Updates the example app to use TLHC mode, per current package guidance.
+
 ## 2.7.0
 
 * Adds support for BitmapDescriptor classes `AssetMapBitmap` and `BytesMapBitmap`.
diff --git a/packages/google_maps_flutter/google_maps_flutter/README.md b/packages/google_maps_flutter/google_maps_flutter/README.md
index 0a9dd2fce995..1f1f68a73443 100644
--- a/packages/google_maps_flutter/google_maps_flutter/README.md
+++ b/packages/google_maps_flutter/google_maps_flutter/README.md
@@ -12,10 +12,6 @@ A Flutter plugin that provides a [Google Maps](https://developers.google.com/map
 
 [web-support]: https://docs.flutter.dev/reference/supported-platforms
 
-## Usage
-
-To use this plugin, add `google_maps_flutter` as a [dependency in your pubspec.yaml file](https://flutter.dev/docs/development/platform-integration/platform-channels).
-
 ## Getting Started
 
 * Get an API key at .
@@ -58,7 +54,7 @@ This means that app will only be available for users that run Android SDK 20 or
 #### Display Mode
 
 The Android implementation supports multiple
-[platform view display modes](https://flutter.dev/docs/development/platform-integration/platform-views).
+[platform view display modes](https://docs.flutter.dev/platform-integration/android/platform-views).
 For details, see [the Android README](https://pub.dev/packages/google_maps_flutter_android#display-mode).
 
 #### Cloud-based map styling
diff --git a/packages/google_maps_flutter/google_maps_flutter/example/android/app/build.gradle b/packages/google_maps_flutter/google_maps_flutter/example/android/app/build.gradle
index a1ea94ae55cd..1a7aa24663aa 100644
--- a/packages/google_maps_flutter/google_maps_flutter/example/android/app/build.gradle
+++ b/packages/google_maps_flutter/google_maps_flutter/example/android/app/build.gradle
@@ -30,9 +30,8 @@ android {
 
     defaultConfig {
         applicationId "io.flutter.plugins.googlemapsexample"
-        minSdkVersion 20
+        minSdkVersion flutter.minSdkVersion
         targetSdkVersion 28
-        multiDexEnabled true
         versionCode flutterVersionCode.toInteger()
         versionName flutterVersionName
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
diff --git a/packages/google_maps_flutter/google_maps_flutter/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/google_maps_flutter/google_maps_flutter/example/android/app/gradle/wrapper/gradle-wrapper.properties
index 609ab8e6c8b5..d951fac2bf31 100644
--- a/packages/google_maps_flutter/google_maps_flutter/example/android/app/gradle/wrapper/gradle-wrapper.properties
+++ b/packages/google_maps_flutter/google_maps_flutter/example/android/app/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
diff --git a/packages/google_maps_flutter/google_maps_flutter/example/android/build.gradle b/packages/google_maps_flutter/google_maps_flutter/example/android/build.gradle
index cec92de922cf..0bed8906c094 100644
--- a/packages/google_maps_flutter/google_maps_flutter/example/android/build.gradle
+++ b/packages/google_maps_flutter/google_maps_flutter/example/android/build.gradle
@@ -5,7 +5,7 @@ buildscript {
     }
 
     dependencies {
-        classpath 'com.android.tools.build:gradle:7.4.2'
+        classpath 'com.android.tools.build:gradle:8.5.2'
     }
 }
 
diff --git a/packages/google_maps_flutter/google_maps_flutter/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/google_maps_flutter/google_maps_flutter/example/android/gradle/wrapper/gradle-wrapper.properties
index 068cdb2dc260..48c0a02ca419 100644
--- a/packages/google_maps_flutter/google_maps_flutter/example/android/gradle/wrapper/gradle-wrapper.properties
+++ b/packages/google_maps_flutter/google_maps_flutter/example/android/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
diff --git a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/src/maps_inspector.dart b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/src/maps_inspector.dart
index efa4baaea696..dc6973a5e8ff 100644
--- a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/src/maps_inspector.dart
+++ b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/src/maps_inspector.dart
@@ -533,4 +533,106 @@ void runTests() {
       expect(myLocationButtonEnabled, true);
     });
   }, skip: !isIOS);
+
+  testWidgets('marker clustering', (WidgetTester tester) async {
+    final Key key = GlobalKey();
+    const int clusterManagersAmount = 2;
+    const int markersPerClusterManager = 5;
+    final Map markers = {};
+    final Set clusterManagers = {};
+
+    for (int i = 0; i < clusterManagersAmount; i++) {
+      final ClusterManagerId clusterManagerId =
+          ClusterManagerId('cluster_manager_$i');
+      final ClusterManager clusterManager =
+          ClusterManager(clusterManagerId: clusterManagerId);
+      clusterManagers.add(clusterManager);
+    }
+
+    for (final ClusterManager cm in clusterManagers) {
+      for (int i = 0; i < markersPerClusterManager; i++) {
+        final MarkerId markerId =
+            MarkerId('${cm.clusterManagerId.value}_marker_$i');
+        final Marker marker = Marker(
+            markerId: markerId,
+            clusterManagerId: cm.clusterManagerId,
+            position: LatLng(
+                kInitialMapCenter.latitude + i, kInitialMapCenter.longitude));
+        markers[markerId] = marker;
+      }
+    }
+
+    final Completer controllerCompleter =
+        Completer();
+
+    await pumpMap(
+      tester,
+      GoogleMap(
+        key: key,
+        initialCameraPosition: kInitialCameraPosition,
+        clusterManagers: clusterManagers,
+        markers: Set.of(markers.values),
+        onMapCreated: (GoogleMapController googleMapController) {
+          controllerCompleter.complete(googleMapController);
+        },
+      ),
+    );
+
+    final GoogleMapController controller = await controllerCompleter.future;
+
+    final GoogleMapsInspectorPlatform inspector =
+        GoogleMapsInspectorPlatform.instance!;
+
+    for (final ClusterManager cm in clusterManagers) {
+      final List clusters = await inspector.getClusters(
+          mapId: controller.mapId, clusterManagerId: cm.clusterManagerId);
+      final int markersAmountForClusterManager = clusters
+          .map((Cluster cluster) => cluster.count)
+          .reduce((int value, int element) => value + element);
+      expect(markersAmountForClusterManager, markersPerClusterManager);
+    }
+
+    // Remove markers from clusterManagers and test that clusterManagers are empty.
+    for (final MapEntry entry in markers.entries) {
+      markers[entry.key] = _copyMarkerWithClusterManagerId(entry.value, null);
+    }
+
+    await pumpMap(
+      tester,
+      GoogleMap(
+          key: key,
+          initialCameraPosition: kInitialCameraPosition,
+          clusterManagers: clusterManagers,
+          markers: Set.of(markers.values)),
+    );
+
+    for (final ClusterManager cm in clusterManagers) {
+      final List clusters = await inspector.getClusters(
+          mapId: controller.mapId, clusterManagerId: cm.clusterManagerId);
+      expect(clusters.length, 0);
+    }
+  });
+}
+
+Marker _copyMarkerWithClusterManagerId(
+    Marker marker, ClusterManagerId? clusterManagerId) {
+  return Marker(
+    markerId: marker.markerId,
+    alpha: marker.alpha,
+    anchor: marker.anchor,
+    consumeTapEvents: marker.consumeTapEvents,
+    draggable: marker.draggable,
+    flat: marker.flat,
+    icon: marker.icon,
+    infoWindow: marker.infoWindow,
+    position: marker.position,
+    rotation: marker.rotation,
+    visible: marker.visible,
+    zIndex: marker.zIndex,
+    onTap: marker.onTap,
+    onDragStart: marker.onDragStart,
+    onDrag: marker.onDrag,
+    onDragEnd: marker.onDragEnd,
+    clusterManagerId: clusterManagerId,
+  );
 }
diff --git a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/src/tiles_inspector.dart b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/src/tiles_inspector.dart
index 9c9914d8935d..d115257c07b4 100644
--- a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/src/tiles_inspector.dart
+++ b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/src/tiles_inspector.dart
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 import 'dart:async';
+import 'dart:io';
 import 'dart:ui' as ui;
 
 import 'package:flutter/foundation.dart';
@@ -21,6 +22,8 @@ void main() {
 }
 
 void runTests() {
+  const double floatTolerance = 1e-8;
+
   GoogleMapsFlutterPlatform.instance.enableDebugInspection();
 
   final GoogleMapsInspectorPlatform inspector =
@@ -204,6 +207,271 @@ void runTests() {
       },
     );
   }, skip: isWeb /* Tiles not supported on the web */);
+
+  /// Check that two lists of [WeightedLatLng] are more or less equal.
+  void expectHeatmapDataMoreOrLessEquals(
+    List data1,
+    List data2,
+  ) {
+    expect(data1.length, data2.length);
+    for (int i = 0; i < data1.length; i++) {
+      final WeightedLatLng wll1 = data1[i];
+      final WeightedLatLng wll2 = data2[i];
+      expect(wll1.weight, wll2.weight);
+      expect(wll1.point.latitude, moreOrLessEquals(wll2.point.latitude));
+      expect(wll1.point.longitude, moreOrLessEquals(wll2.point.longitude));
+    }
+  }
+
+  /// Check that two [HeatmapGradient]s are more or less equal.
+  void expectHeatmapGradientMoreOrLessEquals(
+    HeatmapGradient? gradient1,
+    HeatmapGradient? gradient2,
+  ) {
+    if (gradient1 == null || gradient2 == null) {
+      expect(gradient1, gradient2);
+      return;
+    }
+    expect(gradient2, isNotNull);
+
+    expect(gradient1.colors.length, gradient2.colors.length);
+    for (int i = 0; i < gradient1.colors.length; i++) {
+      final HeatmapGradientColor color1 = gradient1.colors[i];
+      final HeatmapGradientColor color2 = gradient2.colors[i];
+      expect(color1.color, color2.color);
+      expect(
+        color1.startPoint,
+        moreOrLessEquals(color2.startPoint, epsilon: floatTolerance),
+      );
+    }
+
+    expect(gradient1.colorMapSize, gradient2.colorMapSize);
+  }
+
+  void expectHeatmapEquals(Heatmap heatmap1, Heatmap heatmap2) {
+    expectHeatmapDataMoreOrLessEquals(heatmap1.data, heatmap2.data);
+    expectHeatmapGradientMoreOrLessEquals(heatmap1.gradient, heatmap2.gradient);
+
+    // Only Android supports `maxIntensity`
+    // so the platform value is undefined on others.
+    bool canHandleMaxIntensity() {
+      return Platform.isAndroid;
+    }
+
+    // Only iOS supports `minimumZoomIntensity` and `maximumZoomIntensity`
+    // so the platform value is undefined on others.
+    bool canHandleZoomIntensity() {
+      return Platform.isIOS;
+    }
+
+    if (canHandleMaxIntensity()) {
+      expect(heatmap1.maxIntensity, heatmap2.maxIntensity);
+    }
+    expect(
+      heatmap1.opacity,
+      moreOrLessEquals(heatmap2.opacity, epsilon: floatTolerance),
+    );
+    expect(heatmap1.radius, heatmap2.radius);
+    if (canHandleZoomIntensity()) {
+      expect(heatmap1.minimumZoomIntensity, heatmap2.minimumZoomIntensity);
+      expect(heatmap1.maximumZoomIntensity, heatmap2.maximumZoomIntensity);
+    }
+  }
+
+  const Heatmap heatmap1 = Heatmap(
+    heatmapId: HeatmapId('heatmap_1'),
+    data: [
+      WeightedLatLng(LatLng(37.782, -122.447)),
+      WeightedLatLng(LatLng(37.782, -122.445)),
+      WeightedLatLng(LatLng(37.782, -122.443)),
+      WeightedLatLng(LatLng(37.782, -122.441)),
+      WeightedLatLng(LatLng(37.782, -122.439)),
+      WeightedLatLng(LatLng(37.782, -122.437)),
+      WeightedLatLng(LatLng(37.782, -122.435)),
+      WeightedLatLng(LatLng(37.785, -122.447)),
+      WeightedLatLng(LatLng(37.785, -122.445)),
+      WeightedLatLng(LatLng(37.785, -122.443)),
+      WeightedLatLng(LatLng(37.785, -122.441)),
+      WeightedLatLng(LatLng(37.785, -122.439)),
+      WeightedLatLng(LatLng(37.785, -122.437)),
+      WeightedLatLng(LatLng(37.785, -122.435), weight: 2)
+    ],
+    dissipating: false,
+    gradient: HeatmapGradient(
+      [
+        HeatmapGradientColor(
+          Color.fromARGB(255, 0, 255, 255),
+          0.2,
+        ),
+        HeatmapGradientColor(
+          Color.fromARGB(255, 0, 63, 255),
+          0.4,
+        ),
+        HeatmapGradientColor(
+          Color.fromARGB(255, 0, 0, 191),
+          0.6,
+        ),
+        HeatmapGradientColor(
+          Color.fromARGB(255, 63, 0, 91),
+          0.8,
+        ),
+        HeatmapGradientColor(
+          Color.fromARGB(255, 255, 0, 0),
+          1,
+        ),
+      ],
+    ),
+    maxIntensity: 1,
+    opacity: 0.5,
+    radius: HeatmapRadius.fromPixels(40),
+    minimumZoomIntensity: 1,
+    maximumZoomIntensity: 20,
+  );
+
+  testWidgets('set heatmap correctly', (WidgetTester tester) async {
+    final Completer mapIdCompleter = Completer();
+    final Heatmap heatmap2 = Heatmap(
+      heatmapId: const HeatmapId('heatmap_2'),
+      data: heatmap1.data,
+      dissipating: heatmap1.dissipating,
+      gradient: heatmap1.gradient,
+      maxIntensity: heatmap1.maxIntensity,
+      opacity: heatmap1.opacity - 0.1,
+      radius: heatmap1.radius,
+      minimumZoomIntensity: heatmap1.minimumZoomIntensity,
+      maximumZoomIntensity: heatmap1.maximumZoomIntensity,
+    );
+
+    await tester.pumpWidget(
+      Directionality(
+        textDirection: TextDirection.ltr,
+        child: GoogleMap(
+          initialCameraPosition: kInitialCameraPosition,
+          heatmaps: {heatmap1, heatmap2},
+          onMapCreated: (GoogleMapController controller) {
+            mapIdCompleter.complete(controller.mapId);
+          },
+        ),
+      ),
+    );
+    await tester.pumpAndSettle(const Duration(seconds: 3));
+
+    final int mapId = await mapIdCompleter.future;
+    final GoogleMapsInspectorPlatform inspector =
+        GoogleMapsInspectorPlatform.instance!;
+
+    if (inspector.supportsGettingHeatmapInfo()) {
+      final Heatmap heatmapInfo1 =
+          (await inspector.getHeatmapInfo(heatmap1.mapsId, mapId: mapId))!;
+      final Heatmap heatmapInfo2 =
+          (await inspector.getHeatmapInfo(heatmap2.mapsId, mapId: mapId))!;
+
+      expectHeatmapEquals(heatmap1, heatmapInfo1);
+      expectHeatmapEquals(heatmap2, heatmapInfo2);
+    }
+  });
+
+  testWidgets('update heatmaps correctly', (WidgetTester tester) async {
+    final Completer mapIdCompleter = Completer();
+    final Key key = GlobalKey();
+
+    await tester.pumpWidget(
+      Directionality(
+        textDirection: TextDirection.ltr,
+        child: GoogleMap(
+          key: key,
+          initialCameraPosition: kInitialCameraPosition,
+          heatmaps: {heatmap1},
+          onMapCreated: (GoogleMapController controller) {
+            mapIdCompleter.complete(controller.mapId);
+          },
+        ),
+      ),
+    );
+
+    final int mapId = await mapIdCompleter.future;
+    final GoogleMapsInspectorPlatform inspector =
+        GoogleMapsInspectorPlatform.instance!;
+
+    final Heatmap heatmap1New = heatmap1.copyWith(
+      dataParam: heatmap1.data.sublist(5),
+      dissipatingParam: !heatmap1.dissipating,
+      gradientParam: heatmap1.gradient,
+      maxIntensityParam: heatmap1.maxIntensity! + 1,
+      opacityParam: heatmap1.opacity - 0.1,
+      radiusParam: HeatmapRadius.fromPixels(heatmap1.radius.radius + 1),
+      minimumZoomIntensityParam: heatmap1.minimumZoomIntensity + 1,
+      maximumZoomIntensityParam: heatmap1.maximumZoomIntensity + 1,
+    );
+
+    await tester.pumpWidget(
+      Directionality(
+        textDirection: TextDirection.ltr,
+        child: GoogleMap(
+          key: key,
+          initialCameraPosition: kInitialCameraPosition,
+          heatmaps: {heatmap1New},
+          onMapCreated: (GoogleMapController controller) {
+            fail('update: OnMapCreated should get called only once.');
+          },
+        ),
+      ),
+    );
+
+    await tester.pumpAndSettle(const Duration(seconds: 3));
+
+    if (inspector.supportsGettingHeatmapInfo()) {
+      final Heatmap heatmapInfo1 =
+          (await inspector.getHeatmapInfo(heatmap1.mapsId, mapId: mapId))!;
+
+      expectHeatmapEquals(heatmap1New, heatmapInfo1);
+    }
+  });
+
+  testWidgets('remove heatmaps correctly', (WidgetTester tester) async {
+    final Completer mapIdCompleter = Completer();
+    final Key key = GlobalKey();
+
+    await tester.pumpWidget(
+      Directionality(
+        textDirection: TextDirection.ltr,
+        child: GoogleMap(
+          key: key,
+          initialCameraPosition: kInitialCameraPosition,
+          heatmaps: {heatmap1},
+          onMapCreated: (GoogleMapController controller) {
+            mapIdCompleter.complete(controller.mapId);
+          },
+        ),
+      ),
+    );
+
+    final int mapId = await mapIdCompleter.future;
+    final GoogleMapsInspectorPlatform inspector =
+        GoogleMapsInspectorPlatform.instance!;
+
+    await tester.pumpWidget(
+      Directionality(
+        textDirection: TextDirection.ltr,
+        child: GoogleMap(
+          key: key,
+          initialCameraPosition: kInitialCameraPosition,
+          onMapCreated: (GoogleMapController controller) {
+            fail('OnMapCreated should get called only once.');
+          },
+        ),
+      ),
+    );
+
+    await tester.pumpAndSettle(const Duration(seconds: 3));
+
+    if (inspector.supportsGettingHeatmapInfo()) {
+      final Heatmap? heatmapInfo1 =
+          await inspector.getHeatmapInfo(heatmap1.mapsId, mapId: mapId);
+
+      expect(heatmapInfo1, isNull);
+    }
+  });
 }
 
 class _DebugTileProvider implements TileProvider {
diff --git a/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner.xcodeproj/project.pbxproj b/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner.xcodeproj/project.pbxproj
index 3e067e9f7632..6271f61d4504 100644
--- a/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner.xcodeproj/project.pbxproj
+++ b/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner.xcodeproj/project.pbxproj
@@ -34,7 +34,6 @@
 		1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
 		1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
 		3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
-		68E472692836FF0C00BDDDAC /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.0.sdk/System/iOSSupport/System/Library/Frameworks/MapKit.framework; sourceTree = DEVELOPER_DIR; };
 		7755F8F4BABC3D6A0BD4048B /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
 		7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
 		7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
@@ -66,7 +65,6 @@
 		1E7CF0857EFC88FC263CF3B2 /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
-				68E472692836FF0C00BDDDAC /* MapKit.framework */,
 				7755F8F4BABC3D6A0BD4048B /* libPods-Runner.a */,
 			);
 			name = Frameworks;
@@ -263,12 +261,12 @@
 			);
 			inputPaths = (
 				"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh",
-				"${PODS_ROOT}/GoogleMaps/Maps/Frameworks/GoogleMaps.framework/Resources/GoogleMaps.bundle",
+				"${PODS_CONFIGURATION_BUILD_DIR}/GoogleMaps/GoogleMapsResources.bundle",
 				"${PODS_CONFIGURATION_BUILD_DIR}/google_maps_flutter_ios/google_maps_flutter_ios_privacy.bundle",
 			);
 			name = "[CP] Copy Pods Resources";
 			outputPaths = (
-				"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleMaps.bundle",
+				"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleMapsResources.bundle",
 				"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/google_maps_flutter_ios_privacy.bundle",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/clustering.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/clustering.dart
new file mode 100644
index 000000000000..5c06a61b2a1e
--- /dev/null
+++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/clustering.dart
@@ -0,0 +1,278 @@
+// 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:math';
+
+import 'package:flutter/material.dart';
+import 'package:google_maps_flutter/google_maps_flutter.dart';
+
+import 'page.dart';
+
+/// Page for demonstrating marker clustering support.
+class ClusteringPage extends GoogleMapExampleAppPage {
+  /// Default Constructor.
+  const ClusteringPage({Key? key})
+      : super(const Icon(Icons.place), 'Manage clustering', key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return const ClusteringBody();
+  }
+}
+
+/// Body of the clustering page.
+class ClusteringBody extends StatefulWidget {
+  /// Default Constructor.
+  const ClusteringBody({super.key});
+
+  @override
+  State createState() => ClusteringBodyState();
+}
+
+/// State of the clustering page.
+class ClusteringBodyState extends State {
+  /// Default Constructor.
+  ClusteringBodyState();
+
+  /// Starting point from where markers are added.
+  static const LatLng center = LatLng(-33.86, 151.1547171);
+
+  /// Marker offset factor for randomizing marker placing.
+  static const double _markerOffsetFactor = 0.05;
+
+  /// Offset for longitude when placing markers to different cluster managers.
+  static const double _clusterManagerLongitudeOffset = 0.1;
+
+  /// Maximum amount of cluster managers.
+  static const int _clusterManagerMaxCount = 3;
+
+  /// Amount of markers to be added to the cluster manager at once.
+  static const int _markersToAddToClusterManagerCount = 10;
+
+  /// Fully visible alpha value.
+  static const double _fullyVisibleAlpha = 1.0;
+
+  /// Half visible alpha value.
+  static const double _halfVisibleAlpha = 0.5;
+
+  /// Google map controller.
+  GoogleMapController? controller;
+
+  /// Map of clusterManagers with identifier as the key.
+  Map clusterManagers =
+      {};
+
+  /// Map of markers with identifier as the key.
+  Map markers = {};
+
+  /// Id of the currently selected marker.
+  MarkerId? selectedMarker;
+
+  /// Counter for added cluster manager ids.
+  int _clusterManagerIdCounter = 1;
+
+  /// Counter for added markers ids.
+  int _markerIdCounter = 1;
+
+  /// Cluster that was tapped most recently.
+  Cluster? lastCluster;
+
+  void _onMapCreated(GoogleMapController controllerParam) {
+    setState(() {
+      controller = controllerParam;
+    });
+  }
+
+  @override
+  void dispose() {
+    super.dispose();
+  }
+
+  void _onMarkerTapped(MarkerId markerId) {
+    final Marker? tappedMarker = markers[markerId];
+    if (tappedMarker != null) {
+      setState(() {
+        final MarkerId? previousMarkerId = selectedMarker;
+        if (previousMarkerId != null && markers.containsKey(previousMarkerId)) {
+          final Marker resetOld = markers[previousMarkerId]!
+              .copyWith(iconParam: BitmapDescriptor.defaultMarker);
+          markers[previousMarkerId] = resetOld;
+        }
+        selectedMarker = markerId;
+        final Marker newMarker = tappedMarker.copyWith(
+          iconParam: BitmapDescriptor.defaultMarkerWithHue(
+            BitmapDescriptor.hueGreen,
+          ),
+        );
+        markers[markerId] = newMarker;
+      });
+    }
+  }
+
+  void _addClusterManager() {
+    if (clusterManagers.length == _clusterManagerMaxCount) {
+      return;
+    }
+
+    final String clusterManagerIdVal =
+        'cluster_manager_id_$_clusterManagerIdCounter';
+    _clusterManagerIdCounter++;
+    final ClusterManagerId clusterManagerId =
+        ClusterManagerId(clusterManagerIdVal);
+
+    final ClusterManager clusterManager = ClusterManager(
+      clusterManagerId: clusterManagerId,
+      onClusterTap: (Cluster cluster) => setState(() {
+        lastCluster = cluster;
+      }),
+    );
+
+    setState(() {
+      clusterManagers[clusterManagerId] = clusterManager;
+    });
+    _addMarkersToCluster(clusterManager);
+  }
+
+  void _removeClusterManager(ClusterManager clusterManager) {
+    setState(() {
+      // Remove markers managed by cluster manager to be removed.
+      markers.removeWhere((MarkerId key, Marker marker) =>
+          marker.clusterManagerId == clusterManager.clusterManagerId);
+      // Remove cluster manager.
+      clusterManagers.remove(clusterManager.clusterManagerId);
+    });
+  }
+
+  void _addMarkersToCluster(ClusterManager clusterManager) {
+    for (int i = 0; i < _markersToAddToClusterManagerCount; i++) {
+      final String markerIdVal =
+          '${clusterManager.clusterManagerId.value}_marker_id_$_markerIdCounter';
+      _markerIdCounter++;
+      final MarkerId markerId = MarkerId(markerIdVal);
+
+      final int clusterManagerIndex =
+          clusterManagers.values.toList().indexOf(clusterManager);
+
+      // Add additional offset to longitude for each cluster manager to space
+      // out markers in different cluster managers.
+      final double clusterManagerLongitudeOffset =
+          clusterManagerIndex * _clusterManagerLongitudeOffset;
+
+      final Marker marker = Marker(
+        clusterManagerId: clusterManager.clusterManagerId,
+        markerId: markerId,
+        position: LatLng(
+          center.latitude + _getRandomOffset(),
+          center.longitude + _getRandomOffset() + clusterManagerLongitudeOffset,
+        ),
+        infoWindow: InfoWindow(title: markerIdVal, snippet: '*'),
+        onTap: () => _onMarkerTapped(markerId),
+      );
+      markers[markerId] = marker;
+    }
+    setState(() {});
+  }
+
+  double _getRandomOffset() {
+    return (Random().nextDouble() - 0.5) * _markerOffsetFactor;
+  }
+
+  void _remove(MarkerId markerId) {
+    setState(() {
+      if (markers.containsKey(markerId)) {
+        markers.remove(markerId);
+      }
+    });
+  }
+
+  void _changeMarkersAlpha() {
+    for (final MarkerId markerId in markers.keys) {
+      final Marker marker = markers[markerId]!;
+      final double current = marker.alpha;
+      markers[markerId] = marker.copyWith(
+        alphaParam: current == _fullyVisibleAlpha
+            ? _halfVisibleAlpha
+            : _fullyVisibleAlpha,
+      );
+    }
+    setState(() {});
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    final MarkerId? selectedId = selectedMarker;
+    return Column(
+      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+      children: [
+        SizedBox(
+          height: 300.0,
+          child: GoogleMap(
+            onMapCreated: _onMapCreated,
+            initialCameraPosition: const CameraPosition(
+              target: LatLng(-33.852, 151.25),
+              zoom: 11.0,
+            ),
+            markers: Set.of(markers.values),
+            clusterManagers: Set.of(clusterManagers.values),
+          ),
+        ),
+        Column(children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+            children: [
+              TextButton(
+                onPressed: clusterManagers.length >= _clusterManagerMaxCount
+                    ? null
+                    : () => _addClusterManager(),
+                child: const Text('Add cluster manager'),
+              ),
+              TextButton(
+                onPressed: clusterManagers.isEmpty
+                    ? null
+                    : () => _removeClusterManager(clusterManagers.values.last),
+                child: const Text('Remove cluster manager'),
+              ),
+            ],
+          ),
+          Wrap(
+            alignment: WrapAlignment.spaceEvenly,
+            children: [
+              for (final MapEntry clusterEntry
+                  in clusterManagers.entries)
+                TextButton(
+                  onPressed: () => _addMarkersToCluster(clusterEntry.value),
+                  child: Text('Add markers to ${clusterEntry.key.value}'),
+                ),
+            ],
+          ),
+          Wrap(
+            alignment: WrapAlignment.spaceEvenly,
+            children: [
+              TextButton(
+                onPressed: selectedId == null
+                    ? null
+                    : () {
+                        _remove(selectedId);
+                        setState(() {
+                          selectedMarker = null;
+                        });
+                      },
+                child: const Text('Remove selected marker'),
+              ),
+              TextButton(
+                onPressed: markers.isEmpty ? null : () => _changeMarkersAlpha(),
+                child: const Text('Change all markers alpha'),
+              ),
+            ],
+          ),
+          if (lastCluster != null)
+            Padding(
+                padding: const EdgeInsets.all(10),
+                child: Text(
+                    'Cluster with ${lastCluster!.count} markers clicked at ${lastCluster!.position}')),
+        ]),
+      ],
+    );
+  }
+}
diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/heatmap.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/heatmap.dart
new file mode 100644
index 000000000000..956a0a49e1b3
--- /dev/null
+++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/heatmap.dart
@@ -0,0 +1,166 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// ignore_for_file: public_member_api_docs
+
+import 'package:flutter/foundation.dart';
+import 'package:flutter/material.dart';
+import 'package:google_maps_flutter/google_maps_flutter.dart';
+import 'page.dart';
+
+class HeatmapPage extends GoogleMapExampleAppPage {
+  const HeatmapPage({Key? key})
+      : super(const Icon(Icons.map), 'Heatmaps', key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return const HeatmapBody();
+  }
+}
+
+class HeatmapBody extends StatefulWidget {
+  const HeatmapBody({super.key});
+
+  @override
+  State createState() => HeatmapBodyState();
+}
+
+class HeatmapBodyState extends State {
+  static const LatLng sanFrancisco = LatLng(37.774546, -122.433523);
+
+  List enabledPoints = [
+    const WeightedLatLng(LatLng(37.782, -122.447)),
+    const WeightedLatLng(LatLng(37.782, -122.445)),
+    const WeightedLatLng(LatLng(37.782, -122.443)),
+    const WeightedLatLng(LatLng(37.782, -122.441)),
+    const WeightedLatLng(LatLng(37.782, -122.439)),
+    const WeightedLatLng(LatLng(37.782, -122.437)),
+    const WeightedLatLng(LatLng(37.782, -122.435)),
+    const WeightedLatLng(LatLng(37.785, -122.447)),
+    const WeightedLatLng(LatLng(37.785, -122.445)),
+    const WeightedLatLng(LatLng(37.785, -122.443)),
+    const WeightedLatLng(LatLng(37.785, -122.441)),
+    const WeightedLatLng(LatLng(37.785, -122.439)),
+    const WeightedLatLng(LatLng(37.785, -122.437)),
+    const WeightedLatLng(LatLng(37.785, -122.435))
+  ];
+
+  List disabledPoints = [];
+
+  void _addPoint() {
+    if (disabledPoints.isEmpty) {
+      return;
+    }
+
+    final WeightedLatLng point = disabledPoints.first;
+    disabledPoints.removeAt(0);
+
+    setState(() => enabledPoints.add(point));
+  }
+
+  void _removePoint() {
+    if (enabledPoints.isEmpty) {
+      return;
+    }
+
+    final WeightedLatLng point = enabledPoints.first;
+    enabledPoints.removeAt(0);
+
+    setState(() => disabledPoints.add(point));
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    // The Google Maps SDK handles radius differently across platforms.
+    // It is the developer's responsibility to ensure proper behavior on
+    // each platform.
+    final int radius;
+    if (kIsWeb) {
+      radius = 10;
+    } else {
+      radius = switch (defaultTargetPlatform) {
+        TargetPlatform.android => 20,
+        TargetPlatform.iOS => 40,
+        _ => 20,
+      };
+    }
+
+    return Column(
+      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+      crossAxisAlignment: CrossAxisAlignment.stretch,
+      children: [
+        Center(
+          child: SizedBox(
+            width: 350.0,
+            height: 300.0,
+            child: GoogleMap(
+                initialCameraPosition: const CameraPosition(
+                  target: sanFrancisco,
+                  zoom: 13,
+                ),
+                heatmaps: {
+                  Heatmap(
+                    heatmapId: const HeatmapId('test'),
+                    data: enabledPoints,
+                    gradient: const HeatmapGradient(
+                      [
+                        HeatmapGradientColor(
+                          Color.fromARGB(255, 0, 255, 255),
+                          0.2,
+                        ),
+                        HeatmapGradientColor(
+                          Color.fromARGB(255, 0, 63, 255),
+                          0.4,
+                        ),
+                        HeatmapGradientColor(
+                          Color.fromARGB(255, 0, 0, 191),
+                          0.6,
+                        ),
+                        HeatmapGradientColor(
+                          Color.fromARGB(255, 63, 0, 91),
+                          0.8,
+                        ),
+                        HeatmapGradientColor(
+                          Color.fromARGB(255, 255, 0, 0),
+                          1,
+                        ),
+                      ],
+                    ),
+                    maxIntensity: 1,
+                    radius: HeatmapRadius.fromPixels(radius),
+                  )
+                }),
+          ),
+        ),
+        Expanded(
+          child: SingleChildScrollView(
+            child: Row(
+              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+              children: [
+                Row(
+                  children: [
+                    Column(
+                      children: [
+                        TextButton(
+                          onPressed:
+                              disabledPoints.isNotEmpty ? _addPoint : null,
+                          child: const Text('Add point'),
+                        ),
+                        TextButton(
+                          onPressed:
+                              enabledPoints.isNotEmpty ? _removePoint : null,
+                          child: const Text('Remove point'),
+                        ),
+                      ],
+                    )
+                  ],
+                )
+              ],
+            ),
+          ),
+        ),
+      ],
+    );
+  }
+}
diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/main.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/main.dart
index a0060e1c7254..73a47db723e8 100644
--- a/packages/google_maps_flutter/google_maps_flutter/example/lib/main.dart
+++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/main.dart
@@ -9,6 +9,8 @@ import 'package:google_maps_flutter_android/google_maps_flutter_android.dart';
 import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
 
 import 'animate_camera.dart';
+import 'clustering.dart';
+import 'heatmap.dart';
 import 'lite_mode.dart';
 import 'map_click.dart';
 import 'map_coordinates.dart';
@@ -42,7 +44,9 @@ final List _allPages = [
   const SnapshotPage(),
   const LiteModePage(),
   const TileOverlayPage(),
+  const ClusteringPage(),
   const MapIdPage(),
+  const HeatmapPage(),
 ];
 
 /// MapsDemo is the Main Application.
@@ -78,7 +82,6 @@ void main() {
   final GoogleMapsFlutterPlatform mapsImplementation =
       GoogleMapsFlutterPlatform.instance;
   if (mapsImplementation is GoogleMapsFlutterAndroid) {
-    mapsImplementation.useAndroidViewSurface = true;
     initializeMapRenderer();
   }
   runApp(const MaterialApp(home: MapsDemo()));
diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart
index e18d088ed313..11b3ed6e0bb5 100644
--- a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart
+++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart
@@ -225,7 +225,7 @@ class PlacePolygonBodyState extends State {
                         TextButton(
                           onPressed: (selectedId == null)
                               ? null
-                              : ((polygons[selectedId]!.holes.isNotEmpty)
+                              : (polygons[selectedId]!.holes.isNotEmpty
                                   ? null
                                   : () => _addHoles(selectedId)),
                           child: const Text('add holes'),
@@ -233,7 +233,7 @@ class PlacePolygonBodyState extends State {
                         TextButton(
                           onPressed: (selectedId == null)
                               ? null
-                              : ((polygons[selectedId]!.holes.isEmpty)
+                              : (polygons[selectedId]!.holes.isEmpty
                                   ? null
                                   : () => _removeHoles(selectedId)),
                           child: const Text('remove holes'),
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 4911beb65792..3326cbae3e5e 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.2.0
-  flutter: ">=3.16.0"
+  sdk: ^3.3.0
+  flutter: ">=3.19.0"
 
 dependencies:
   cupertino_icons: ^1.0.5
@@ -23,7 +23,7 @@ dependencies:
 
 dev_dependencies:
   build_runner: ^2.1.10
-  espresso: ^0.2.0
+  espresso: ^0.4.0
   flutter_test:
     sdk: flutter
   integration_test:
diff --git a/packages/google_maps_flutter/google_maps_flutter/example/web/index.html b/packages/google_maps_flutter/google_maps_flutter/example/web/index.html
index 58522ba720c3..e9ce66f9a870 100644
--- a/packages/google_maps_flutter/google_maps_flutter/example/web/index.html
+++ b/packages/google_maps_flutter/google_maps_flutter/example/web/index.html
@@ -37,30 +37,10 @@
   
 
   
-  
-    
-  
-  
-  
+  
+  
 
 
-  
+  
 
 
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart b/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart
index 7eb4af947318..5c3bb49133c8 100644
--- a/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart
+++ b/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart
@@ -27,6 +27,14 @@ export 'package:google_maps_flutter_platform_interface/google_maps_flutter_platf
         Cap,
         Circle,
         CircleId,
+        Cluster,
+        ClusterManager,
+        ClusterManagerId,
+        Heatmap,
+        HeatmapGradient,
+        HeatmapGradientColor,
+        HeatmapId,
+        HeatmapRadius,
         InfoWindow,
         JointType,
         LatLng,
@@ -47,7 +55,8 @@ export 'package:google_maps_flutter_platform_interface/google_maps_flutter_platf
         TileOverlay,
         TileOverlayId,
         TileProvider,
-        WebGestureHandling;
+        WebGestureHandling,
+        WeightedLatLng;
 
 part 'src/controller.dart';
 part 'src/google_map.dart';
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart
index 393288a6165f..5dd1cfdfd2ad 100644
--- a/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart
+++ b/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart
@@ -79,6 +79,9 @@ class GoogleMapController {
         .listen((MapTapEvent e) => _googleMapState.onTap(e.position));
     GoogleMapsFlutterPlatform.instance.onLongPress(mapId: mapId).listen(
         (MapLongPressEvent e) => _googleMapState.onLongPress(e.position));
+    GoogleMapsFlutterPlatform.instance
+        .onClusterTap(mapId: mapId)
+        .listen((ClusterTapEvent e) => _googleMapState.onClusterTap(e.value));
   }
 
   /// Updates configuration options of the map user interface.
@@ -103,6 +106,18 @@ class GoogleMapController {
         .updateMarkers(markerUpdates, mapId: mapId);
   }
 
+  /// Updates cluster manager configuration.
+  ///
+  /// Change listeners are notified once the update has been made on the
+  /// platform side.
+  ///
+  /// The returned [Future] completes after listeners have been notified.
+  Future _updateClusterManagers(
+      ClusterManagerUpdates clusterManagerUpdates) {
+    return GoogleMapsFlutterPlatform.instance
+        .updateClusterManagers(clusterManagerUpdates, mapId: mapId);
+  }
+
   /// Updates polygon configuration.
   ///
   /// Change listeners are notified once the update has been made on the
@@ -136,6 +151,17 @@ class GoogleMapController {
         .updateCircles(circleUpdates, mapId: mapId);
   }
 
+  /// Updates heatmap configuration.
+  ///
+  /// Change listeners are notified once the update has been made on the
+  /// platform side.
+  ///
+  /// The returned [Future] completes after listeners have been notified.
+  Future _updateHeatmaps(HeatmapUpdates heatmapUpdates) {
+    return GoogleMapsFlutterPlatform.instance
+        .updateHeatmaps(heatmapUpdates, mapId: mapId);
+  }
+
   /// Updates tile overlays configuration.
   ///
   /// Change listeners are notified once the update has been made on the
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart
index c50ffccfa634..d93a9c9cc1af 100644
--- a/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart
+++ b/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart
@@ -52,7 +52,7 @@ class AndroidGoogleMapsFlutter {
   /// This implementation uses hybrid composition to render the Google Maps
   /// Widget on Android. This comes at the cost of some performance on Android
   /// versions below 10. See
-  /// https://flutter.dev/docs/development/platform-integration/platform-views#performance for more
+  /// https://docs.flutter.dev/platform-integration/android/platform-views#performance for more
   /// information.
   @Deprecated(
       'See https://pub.dev/packages/google_maps_flutter_android#display-mode')
@@ -70,7 +70,7 @@ class AndroidGoogleMapsFlutter {
   /// This implementation uses hybrid composition to render the Google Maps
   /// Widget on Android. This comes at the cost of some performance on Android
   /// versions below 10. See
-  /// https://flutter.dev/docs/development/platform-integration/platform-views#performance for more
+  /// https://docs.flutter.dev/platform-integration/android/platform-views#performance for more
   /// information.
   @Deprecated(
       'See https://pub.dev/packages/google_maps_flutter_android#display-mode')
@@ -120,6 +120,8 @@ class GoogleMap extends StatefulWidget {
     this.polygons = const {},
     this.polylines = const {},
     this.circles = const {},
+    this.clusterManagers = const {},
+    this.heatmaps = const {},
     this.onCameraMoveStarted,
     this.tileOverlays = const {},
     this.onCameraMove,
@@ -214,9 +216,15 @@ class GoogleMap extends StatefulWidget {
   /// Circles to be placed on the map.
   final Set circles;
 
+  /// Heatmaps to show on the map.
+  final Set heatmaps;
+
   /// Tile overlays to be placed on the map.
   final Set tileOverlays;
 
+  /// Cluster Managers to be initialized for the map.
+  final Set clusterManagers;
+
   /// Called when the camera starts moving.
   ///
   /// This can be initiated by the following:
@@ -328,6 +336,9 @@ class _GoogleMapState extends State {
   Map _polygons = {};
   Map _polylines = {};
   Map _circles = {};
+  Map _clusterManagers =
+      {};
+  Map _heatmaps = {};
   late MapConfiguration _mapConfiguration;
 
   @override
@@ -347,6 +358,8 @@ class _GoogleMapState extends State {
         polygons: widget.polygons,
         polylines: widget.polylines,
         circles: widget.circles,
+        clusterManagers: widget.clusterManagers,
+        heatmaps: widget.heatmaps,
       ),
       mapConfiguration: _mapConfiguration,
     );
@@ -356,10 +369,12 @@ class _GoogleMapState extends State {
   void initState() {
     super.initState();
     _mapConfiguration = _configurationFromMapWidget(widget);
+    _clusterManagers = keyByClusterManagerId(widget.clusterManagers);
     _markers = keyByMarkerId(widget.markers);
     _polygons = keyByPolygonId(widget.polygons);
     _polylines = keyByPolylineId(widget.polylines);
     _circles = keyByCircleId(widget.circles);
+    _heatmaps = keyByHeatmapId(widget.heatmaps);
   }
 
   @override
@@ -377,10 +392,12 @@ class _GoogleMapState extends State {
   void didUpdateWidget(GoogleMap oldWidget) {
     super.didUpdateWidget(oldWidget);
     _updateOptions();
+    _updateClusterManagers();
     _updateMarkers();
     _updatePolygons();
     _updatePolylines();
     _updateCircles();
+    _updateHeatmaps();
     _updateTileOverlays();
   }
 
@@ -402,6 +419,13 @@ class _GoogleMapState extends State {
     _markers = keyByMarkerId(widget.markers);
   }
 
+  Future _updateClusterManagers() async {
+    final GoogleMapController controller = await _controller.future;
+    unawaited(controller._updateClusterManagers(ClusterManagerUpdates.from(
+        _clusterManagers.values.toSet(), widget.clusterManagers)));
+    _clusterManagers = keyByClusterManagerId(widget.clusterManagers);
+  }
+
   Future _updatePolygons() async {
     final GoogleMapController controller = await _controller.future;
     unawaited(controller._updatePolygons(
@@ -423,6 +447,16 @@ class _GoogleMapState extends State {
     _circles = keyByCircleId(widget.circles);
   }
 
+  Future _updateHeatmaps() async {
+    final GoogleMapController controller = await _controller.future;
+    unawaited(
+      controller._updateHeatmaps(
+        HeatmapUpdates.from(_heatmaps.values.toSet(), widget.heatmaps),
+      ),
+    );
+    _heatmaps = keyByHeatmapId(widget.heatmaps);
+  }
+
   Future _updateTileOverlays() async {
     final GoogleMapController controller = await _controller.future;
     unawaited(controller._updateTileOverlays(widget.tileOverlays));
@@ -543,6 +577,19 @@ class _GoogleMapState extends State {
       onLongPress(position);
     }
   }
+
+  void onClusterTap(Cluster cluster) {
+    final ClusterManager? clusterManager =
+        _clusterManagers[cluster.clusterManagerId];
+    if (clusterManager == null) {
+      throw UnknownMapObjectIdError(
+          'clusterManager', cluster.clusterManagerId, 'onClusterTap');
+    }
+    final ArgumentCallback? onClusterTap = clusterManager.onClusterTap;
+    if (onClusterTap != null) {
+      onClusterTap(cluster);
+    }
+  }
 }
 
 /// Builds a [MapConfiguration] from the given [map].
diff --git a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml
index 3ab5430b0955..00a533874875 100644
--- a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml
+++ b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml
@@ -2,7 +2,7 @@ name: google_maps_flutter
 description: A Flutter plugin for integrating Google Maps in iOS and Android applications.
 repository: https://github.com/flutter/packages/tree/main/packages/google_maps_flutter/google_maps_flutter
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22
-version: 2.7.0
+version: 2.9.0
 
 environment:
   sdk: ^3.4.0
@@ -21,10 +21,10 @@ flutter:
 dependencies:
   flutter:
     sdk: flutter
-  google_maps_flutter_android: ^2.9.0
-  google_maps_flutter_ios: ^2.7.0
-  google_maps_flutter_platform_interface: ^2.7.0
-  google_maps_flutter_web: ^0.5.8
+  google_maps_flutter_android: ^2.13.0
+  google_maps_flutter_ios: ^2.12.0
+  google_maps_flutter_platform_interface: ^2.9.0
+  google_maps_flutter_web: ^0.5.10
 
 dev_dependencies:
   flutter_test:
diff --git a/packages/google_maps_flutter/google_maps_flutter/test/clustermanager_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/clustermanager_updates_test.dart
new file mode 100644
index 000000000000..fee29e1fb67b
--- /dev/null
+++ b/packages/google_maps_flutter/google_maps_flutter/test/clustermanager_updates_test.dart
@@ -0,0 +1,188 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/widgets.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:google_maps_flutter/google_maps_flutter.dart';
+import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
+
+import 'fake_google_maps_flutter_platform.dart';
+
+Widget _mapWithClusterManagers(Set clusterManagers) {
+  return Directionality(
+    textDirection: TextDirection.ltr,
+    child: GoogleMap(
+      initialCameraPosition: const CameraPosition(target: LatLng(10.0, 15.0)),
+      clusterManagers: clusterManagers,
+    ),
+  );
+}
+
+void main() {
+  late FakeGoogleMapsFlutterPlatform platform;
+
+  setUp(() {
+    platform = FakeGoogleMapsFlutterPlatform();
+    GoogleMapsFlutterPlatform.instance = platform;
+  });
+
+  testWidgets('Initializing a cluster manager', (WidgetTester tester) async {
+    const ClusterManager cm1 = ClusterManager(
+      clusterManagerId: ClusterManagerId('cm_1'),
+    );
+    await tester.pumpWidget(_mapWithClusterManagers({cm1}));
+
+    final PlatformMapStateRecorder map = platform.lastCreatedMap;
+    expect(map.clusterManagerUpdates.last.clusterManagersToAdd.length, 1);
+
+    final ClusterManager initializedHeatmap =
+        map.clusterManagerUpdates.last.clusterManagersToAdd.first;
+    expect(initializedHeatmap, equals(cm1));
+    expect(
+        map.clusterManagerUpdates.last.clusterManagerIdsToRemove.isEmpty, true);
+    expect(
+        map.clusterManagerUpdates.last.clusterManagersToChange.isEmpty, true);
+  });
+
+  testWidgets('Adding a cluster manager', (WidgetTester tester) async {
+    const ClusterManager cm1 = ClusterManager(
+      clusterManagerId: ClusterManagerId('cm_1'),
+    );
+    const ClusterManager cm2 = ClusterManager(
+      clusterManagerId: ClusterManagerId('cm_2'),
+    );
+
+    await tester.pumpWidget(_mapWithClusterManagers({cm1}));
+    await tester
+        .pumpWidget(_mapWithClusterManagers({cm1, cm2}));
+
+    final PlatformMapStateRecorder map = platform.lastCreatedMap;
+    expect(map.clusterManagerUpdates.last.clusterManagersToAdd.length, 1);
+
+    final ClusterManager addedClusterManager =
+        map.clusterManagerUpdates.last.clusterManagersToAdd.first;
+    expect(addedClusterManager, equals(cm2));
+
+    expect(
+        map.clusterManagerUpdates.last.clusterManagerIdsToRemove.isEmpty, true);
+
+    expect(
+        map.clusterManagerUpdates.last.clusterManagersToChange.isEmpty, true);
+  });
+
+  testWidgets('Removing a cluster manager', (WidgetTester tester) async {
+    const ClusterManager cm1 = ClusterManager(
+      clusterManagerId: ClusterManagerId('cm_1'),
+    );
+
+    await tester.pumpWidget(_mapWithClusterManagers({cm1}));
+    await tester.pumpWidget(_mapWithClusterManagers({}));
+
+    final PlatformMapStateRecorder map = platform.lastCreatedMap;
+    expect(map.clusterManagerUpdates.last.clusterManagerIdsToRemove.length, 1);
+    expect(map.clusterManagerUpdates.last.clusterManagerIdsToRemove.first,
+        equals(cm1.clusterManagerId));
+
+    expect(
+        map.clusterManagerUpdates.last.clusterManagersToChange.isEmpty, true);
+    expect(map.clusterManagerUpdates.last.clusterManagersToAdd.isEmpty, true);
+  });
+
+  // This test checks that the cluster manager is not added again or changed
+  // when the data remains the same. Since [ClusterManager] does not have any
+  // properties to change, it should not trigger any updates. If new properties
+  // are added to [ClusterManager] in the future, this test will need to be
+  // updated accordingly to check that changes are triggered.
+  testWidgets('Updating a cluster manager with same data',
+      (WidgetTester tester) async {
+    const ClusterManager cm1 = ClusterManager(
+      clusterManagerId: ClusterManagerId('cm_1'),
+    );
+    const ClusterManager cm2 = ClusterManager(
+      clusterManagerId: ClusterManagerId('cm_1'),
+    );
+
+    await tester.pumpWidget(_mapWithClusterManagers({cm1}));
+    await tester.pumpWidget(_mapWithClusterManagers({cm2}));
+
+    final PlatformMapStateRecorder map = platform.lastCreatedMap;
+
+    // As cluster manager does not have any properties to change,
+    // it should not populate the clusterManagersToChange set.
+    expect(
+        map.clusterManagerUpdates.last.clusterManagersToChange.isEmpty, true);
+    expect(
+        map.clusterManagerUpdates.last.clusterManagerIdsToRemove.isEmpty, true);
+    expect(map.clusterManagerUpdates.last.clusterManagersToAdd.isEmpty, true);
+  });
+
+  // This test checks that the cluster manager is not added again or changed
+  // when the data remains the same. Since [ClusterManager] does not have any
+  // properties to change, it should not trigger any updates. If new properties
+  // are added to [ClusterManager] in the future, this test will need to be
+  // updated accordingly to check that changes are triggered.
+  testWidgets('Multi update with same data', (WidgetTester tester) async {
+    ClusterManager cm1 = const ClusterManager(
+      clusterManagerId: ClusterManagerId('cm_1'),
+    );
+    ClusterManager cm2 = const ClusterManager(
+      clusterManagerId: ClusterManagerId('cm_2'),
+    );
+    final Set prev = {cm1, cm2};
+    cm1 = const ClusterManager(
+      clusterManagerId: ClusterManagerId('cm_1'),
+    );
+    cm2 = const ClusterManager(
+      clusterManagerId: ClusterManagerId('cm_2'),
+    );
+    final Set cur = {cm1, cm2};
+
+    await tester.pumpWidget(_mapWithClusterManagers(prev));
+    await tester.pumpWidget(_mapWithClusterManagers(cur));
+
+    final PlatformMapStateRecorder map = platform.lastCreatedMap;
+
+    // As cluster manager does not have any properties to change,
+    // it should not populate the clusterManagersToChange set.
+    expect(map.clusterManagerUpdates.last.clusterManagersToAdd.isEmpty, true);
+    expect(
+        map.clusterManagerUpdates.last.clusterManagerIdsToRemove.isEmpty, true);
+    expect(map.clusterManagerUpdates.last.clusterManagersToAdd.isEmpty, true);
+  });
+
+  // This test checks that the cluster manager is not added again or changed
+  // when the data remains the same. Since [ClusterManager] does not have any
+  // properties to change, it should not trigger any updates. If new properties
+  // are added to [ClusterManager] in the future, this test will need to be
+  // updated accordingly to check that changes are triggered.
+  testWidgets('Partial update with same data', (WidgetTester tester) async {
+    const ClusterManager cm1 = ClusterManager(
+      clusterManagerId: ClusterManagerId('heatmap_1'),
+    );
+    const ClusterManager cm2 = ClusterManager(
+      clusterManagerId: ClusterManagerId('heatmap_2'),
+    );
+    ClusterManager cm3 = const ClusterManager(
+      clusterManagerId: ClusterManagerId('heatmap_3'),
+    );
+    final Set prev = {cm1, cm2, cm3};
+    cm3 = const ClusterManager(
+      clusterManagerId: ClusterManagerId('heatmap_3'),
+    );
+    final Set cur = {cm1, cm2, cm3};
+
+    await tester.pumpWidget(_mapWithClusterManagers(prev));
+    await tester.pumpWidget(_mapWithClusterManagers(cur));
+
+    final PlatformMapStateRecorder map = platform.lastCreatedMap;
+
+    // As cluster manager does not have any properties to change,
+    // it should not populate the clusterManagersToChange set.
+    expect(
+        map.clusterManagerUpdates.last.clusterManagersToChange.isEmpty, true);
+    expect(
+        map.clusterManagerUpdates.last.clusterManagerIdsToRemove.isEmpty, true);
+    expect(map.clusterManagerUpdates.last.clusterManagersToAdd.isEmpty, true);
+  });
+}
diff --git a/packages/google_maps_flutter/google_maps_flutter/test/fake_google_maps_flutter_platform.dart b/packages/google_maps_flutter/google_maps_flutter/test/fake_google_maps_flutter_platform.dart
index 22447ba5ecad..df83400c416b 100644
--- a/packages/google_maps_flutter/google_maps_flutter/test/fake_google_maps_flutter_platform.dart
+++ b/packages/google_maps_flutter/google_maps_flutter/test/fake_google_maps_flutter_platform.dart
@@ -85,6 +85,15 @@ class FakeGoogleMapsFlutterPlatform extends GoogleMapsFlutterPlatform {
     await _fakeDelay();
   }
 
+  @override
+  Future updateHeatmaps(
+    HeatmapUpdates heatmapUpdates, {
+    required int mapId,
+  }) async {
+    mapInstances[mapId]?.heatmapUpdates.add(heatmapUpdates);
+    await _fakeDelay();
+  }
+
   @override
   Future updateTileOverlays({
     required Set newTileOverlays,
@@ -94,6 +103,15 @@ class FakeGoogleMapsFlutterPlatform extends GoogleMapsFlutterPlatform {
     await _fakeDelay();
   }
 
+  @override
+  Future updateClusterManagers(
+    ClusterManagerUpdates clusterManagerUpdates, {
+    required int mapId,
+  }) async {
+    mapInstances[mapId]?.clusterManagerUpdates.add(clusterManagerUpdates);
+    await _fakeDelay();
+  }
+
   @override
   Future clearTileCache(
     TileOverlayId tileOverlayId, {
@@ -241,6 +259,11 @@ class FakeGoogleMapsFlutterPlatform extends GoogleMapsFlutterPlatform {
     return mapEventStreamController.stream.whereType();
   }
 
+  @override
+  Stream onClusterTap({required int mapId}) {
+    return mapEventStreamController.stream.whereType();
+  }
+
   @override
   void dispose({required int mapId}) {
     disposed = true;
@@ -282,12 +305,16 @@ class PlatformMapStateRecorder {
     this.mapObjects = const MapObjects(),
     this.mapConfiguration = const MapConfiguration(),
   }) {
+    clusterManagerUpdates.add(ClusterManagerUpdates.from(
+        const {}, mapObjects.clusterManagers));
     markerUpdates.add(MarkerUpdates.from(const {}, mapObjects.markers));
     polygonUpdates
         .add(PolygonUpdates.from(const {}, mapObjects.polygons));
     polylineUpdates
         .add(PolylineUpdates.from(const {}, mapObjects.polylines));
     circleUpdates.add(CircleUpdates.from(const {}, mapObjects.circles));
+    heatmapUpdates
+        .add(HeatmapUpdates.from(const {}, mapObjects.heatmaps));
     tileOverlaySets.add(mapObjects.tileOverlays);
   }
 
@@ -299,5 +326,8 @@ class PlatformMapStateRecorder {
   final List polygonUpdates = [];
   final List polylineUpdates = [];
   final List circleUpdates = [];
+  final List heatmapUpdates = [];
   final List> tileOverlaySets = >[];
+  final List clusterManagerUpdates =
+      [];
 }
diff --git a/packages/google_maps_flutter/google_maps_flutter/test/heatmap_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/heatmap_updates_test.dart
new file mode 100644
index 000000000000..b9cb250c8564
--- /dev/null
+++ b/packages/google_maps_flutter/google_maps_flutter/test/heatmap_updates_test.dart
@@ -0,0 +1,265 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/widgets.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:google_maps_flutter/google_maps_flutter.dart';
+import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
+
+import 'fake_google_maps_flutter_platform.dart';
+
+Widget _mapWithHeatmaps(Set heatmaps) {
+  return Directionality(
+    textDirection: TextDirection.ltr,
+    child: GoogleMap(
+      initialCameraPosition: const CameraPosition(target: LatLng(10.0, 15.0)),
+      heatmaps: heatmaps,
+    ),
+  );
+}
+
+const List _heatmapPoints = [
+  WeightedLatLng(LatLng(37.782, -122.447)),
+  WeightedLatLng(LatLng(37.782, -122.445)),
+  WeightedLatLng(LatLng(37.782, -122.443)),
+  WeightedLatLng(LatLng(37.782, -122.441)),
+  WeightedLatLng(LatLng(37.782, -122.439)),
+  WeightedLatLng(LatLng(37.782, -122.437)),
+  WeightedLatLng(LatLng(37.782, -122.435)),
+  WeightedLatLng(LatLng(37.785, -122.447)),
+  WeightedLatLng(LatLng(37.785, -122.445)),
+  WeightedLatLng(LatLng(37.785, -122.443)),
+  WeightedLatLng(LatLng(37.785, -122.441)),
+  WeightedLatLng(LatLng(37.785, -122.439)),
+  WeightedLatLng(LatLng(37.785, -122.437)),
+  WeightedLatLng(LatLng(37.785, -122.435))
+];
+
+void main() {
+  late FakeGoogleMapsFlutterPlatform platform;
+
+  setUp(() {
+    platform = FakeGoogleMapsFlutterPlatform();
+    GoogleMapsFlutterPlatform.instance = platform;
+  });
+
+  testWidgets('Initializing a heatmap', (WidgetTester tester) async {
+    const Heatmap h1 = Heatmap(
+      heatmapId: HeatmapId('heatmap_1'),
+      data: _heatmapPoints,
+      radius: HeatmapRadius.fromPixels(20),
+    );
+    await tester.pumpWidget(_mapWithHeatmaps({h1}));
+
+    final PlatformMapStateRecorder map = platform.lastCreatedMap;
+    expect(map.heatmapUpdates.last.heatmapsToAdd.length, 1);
+
+    final Heatmap initializedHeatmap =
+        map.heatmapUpdates.last.heatmapsToAdd.first;
+    expect(initializedHeatmap, equals(h1));
+    expect(map.heatmapUpdates.last.heatmapIdsToRemove.isEmpty, true);
+    expect(map.heatmapUpdates.last.heatmapsToChange.isEmpty, true);
+  });
+
+  testWidgets('Adding a heatmap', (WidgetTester tester) async {
+    const Heatmap h1 = Heatmap(
+      heatmapId: HeatmapId('heatmap_1'),
+      data: _heatmapPoints,
+      radius: HeatmapRadius.fromPixels(20),
+    );
+    const Heatmap h2 = Heatmap(
+      heatmapId: HeatmapId('heatmap_2'),
+      data: _heatmapPoints,
+      radius: HeatmapRadius.fromPixels(20),
+    );
+
+    await tester.pumpWidget(_mapWithHeatmaps({h1}));
+    await tester.pumpWidget(_mapWithHeatmaps({h1, h2}));
+
+    final PlatformMapStateRecorder map = platform.lastCreatedMap;
+    expect(map.heatmapUpdates.last.heatmapsToAdd.length, 1);
+
+    final Heatmap addedHeatmap = map.heatmapUpdates.last.heatmapsToAdd.first;
+    expect(addedHeatmap, equals(h2));
+
+    expect(map.heatmapUpdates.last.heatmapIdsToRemove.isEmpty, true);
+
+    expect(map.heatmapUpdates.last.heatmapsToChange.isEmpty, true);
+  });
+
+  testWidgets('Removing a heatmap', (WidgetTester tester) async {
+    const Heatmap h1 = Heatmap(
+      heatmapId: HeatmapId('heatmap_1'),
+      data: _heatmapPoints,
+      radius: HeatmapRadius.fromPixels(20),
+    );
+
+    await tester.pumpWidget(_mapWithHeatmaps({h1}));
+    await tester.pumpWidget(_mapWithHeatmaps({}));
+
+    final PlatformMapStateRecorder map = platform.lastCreatedMap;
+    expect(map.heatmapUpdates.last.heatmapIdsToRemove.length, 1);
+    expect(
+        map.heatmapUpdates.last.heatmapIdsToRemove.first, equals(h1.heatmapId));
+
+    expect(map.heatmapUpdates.last.heatmapsToChange.isEmpty, true);
+    expect(map.heatmapUpdates.last.heatmapsToAdd.isEmpty, true);
+  });
+
+  testWidgets('Updating a heatmap', (WidgetTester tester) async {
+    const Heatmap h1 = Heatmap(
+      heatmapId: HeatmapId('heatmap_1'),
+      data: _heatmapPoints,
+      radius: HeatmapRadius.fromPixels(20),
+    );
+    const Heatmap h2 = Heatmap(
+      heatmapId: HeatmapId('heatmap_1'),
+      data: _heatmapPoints,
+      radius: HeatmapRadius.fromPixels(10),
+    );
+
+    await tester.pumpWidget(_mapWithHeatmaps({h1}));
+    await tester.pumpWidget(_mapWithHeatmaps({h2}));
+
+    final PlatformMapStateRecorder map = platform.lastCreatedMap;
+    expect(map.heatmapUpdates.last.heatmapsToChange.length, 1);
+    expect(map.heatmapUpdates.last.heatmapsToChange.first, equals(h2));
+
+    expect(map.heatmapUpdates.last.heatmapIdsToRemove.isEmpty, true);
+    expect(map.heatmapUpdates.last.heatmapsToAdd.isEmpty, true);
+  });
+
+  testWidgets('Updating a heatmap', (WidgetTester tester) async {
+    const Heatmap h1 = Heatmap(
+      heatmapId: HeatmapId('heatmap_1'),
+      data: _heatmapPoints,
+      radius: HeatmapRadius.fromPixels(20),
+    );
+    const Heatmap h2 = Heatmap(
+      heatmapId: HeatmapId('heatmap_1'),
+      data: _heatmapPoints,
+      radius: HeatmapRadius.fromPixels(10),
+    );
+
+    await tester.pumpWidget(_mapWithHeatmaps({h1}));
+    await tester.pumpWidget(_mapWithHeatmaps({h2}));
+
+    final PlatformMapStateRecorder map = platform.lastCreatedMap;
+    expect(map.heatmapUpdates.last.heatmapsToChange.length, 1);
+
+    final Heatmap update = map.heatmapUpdates.last.heatmapsToChange.first;
+    expect(update, equals(h2));
+    expect(update.radius.radius, 10);
+  });
+
+  testWidgets('Multi Update', (WidgetTester tester) async {
+    Heatmap h1 = const Heatmap(
+      heatmapId: HeatmapId('heatmap_1'),
+      data: _heatmapPoints,
+      radius: HeatmapRadius.fromPixels(20),
+    );
+    Heatmap h2 = const Heatmap(
+      heatmapId: HeatmapId('heatmap_2'),
+      data: _heatmapPoints,
+      radius: HeatmapRadius.fromPixels(20),
+    );
+    final Set prev = {h1, h2};
+    h1 = const Heatmap(
+      heatmapId: HeatmapId('heatmap_1'),
+      data: _heatmapPoints,
+      dissipating: false,
+      radius: HeatmapRadius.fromPixels(20),
+    );
+    h2 = const Heatmap(
+      heatmapId: HeatmapId('heatmap_2'),
+      data: _heatmapPoints,
+      radius: HeatmapRadius.fromPixels(10),
+    );
+    final Set cur = {h1, h2};
+
+    await tester.pumpWidget(_mapWithHeatmaps(prev));
+    await tester.pumpWidget(_mapWithHeatmaps(cur));
+
+    final PlatformMapStateRecorder map = platform.lastCreatedMap;
+
+    expect(map.heatmapUpdates.last.heatmapsToChange, cur);
+    expect(map.heatmapUpdates.last.heatmapIdsToRemove.isEmpty, true);
+    expect(map.heatmapUpdates.last.heatmapsToAdd.isEmpty, true);
+  });
+
+  testWidgets('Multi Update', (WidgetTester tester) async {
+    Heatmap h2 = const Heatmap(
+      heatmapId: HeatmapId('heatmap_2'),
+      data: _heatmapPoints,
+      radius: HeatmapRadius.fromPixels(20),
+    );
+    const Heatmap h3 = Heatmap(
+      heatmapId: HeatmapId('heatmap_3'),
+      data: _heatmapPoints,
+      radius: HeatmapRadius.fromPixels(20),
+    );
+    final Set prev = {h2, h3};
+
+    // h1 is added, h2 is updated, h3 is removed.
+    const Heatmap h1 = Heatmap(
+      heatmapId: HeatmapId('heatmap_1'),
+      data: _heatmapPoints,
+      radius: HeatmapRadius.fromPixels(20),
+    );
+    h2 = const Heatmap(
+      heatmapId: HeatmapId('heatmap_2'),
+      data: _heatmapPoints,
+      radius: HeatmapRadius.fromPixels(10),
+    );
+    final Set cur = {h1, h2};
+
+    await tester.pumpWidget(_mapWithHeatmaps(prev));
+    await tester.pumpWidget(_mapWithHeatmaps(cur));
+
+    final PlatformMapStateRecorder map = platform.lastCreatedMap;
+
+    expect(map.heatmapUpdates.last.heatmapsToChange.length, 1);
+    expect(map.heatmapUpdates.last.heatmapsToAdd.length, 1);
+    expect(map.heatmapUpdates.last.heatmapIdsToRemove.length, 1);
+
+    expect(map.heatmapUpdates.last.heatmapsToChange.first, equals(h2));
+    expect(map.heatmapUpdates.last.heatmapsToAdd.first, equals(h1));
+    expect(
+        map.heatmapUpdates.last.heatmapIdsToRemove.first, equals(h3.heatmapId));
+  });
+
+  testWidgets('Partial Update', (WidgetTester tester) async {
+    const Heatmap h1 = Heatmap(
+      heatmapId: HeatmapId('heatmap_1'),
+      data: _heatmapPoints,
+      radius: HeatmapRadius.fromPixels(20),
+    );
+    const Heatmap h2 = Heatmap(
+      heatmapId: HeatmapId('heatmap_2'),
+      data: _heatmapPoints,
+      radius: HeatmapRadius.fromPixels(20),
+    );
+    Heatmap h3 = const Heatmap(
+      heatmapId: HeatmapId('heatmap_3'),
+      data: _heatmapPoints,
+      radius: HeatmapRadius.fromPixels(20),
+    );
+    final Set prev = {h1, h2, h3};
+    h3 = const Heatmap(
+      heatmapId: HeatmapId('heatmap_3'),
+      data: _heatmapPoints,
+      radius: HeatmapRadius.fromPixels(10),
+    );
+    final Set cur = {h1, h2, h3};
+
+    await tester.pumpWidget(_mapWithHeatmaps(prev));
+    await tester.pumpWidget(_mapWithHeatmaps(cur));
+
+    final PlatformMapStateRecorder map = platform.lastCreatedMap;
+
+    expect(map.heatmapUpdates.last.heatmapsToChange, {h3});
+    expect(map.heatmapUpdates.last.heatmapIdsToRemove.isEmpty, true);
+    expect(map.heatmapUpdates.last.heatmapsToAdd.isEmpty, true);
+  });
+}
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_android/CHANGELOG.md
index 2291ed28c475..88b105370005 100644
--- a/packages/google_maps_flutter/google_maps_flutter_android/CHANGELOG.md
+++ b/packages/google_maps_flutter/google_maps_flutter_android/CHANGELOG.md
@@ -1,3 +1,77 @@
+## 2.14.11
+
+* Updates internal Pigeon API to use newer features.
+
+## 2.14.10
+
+* Adds 'PlatformBitmap' type.
+* Updates type unsafe implementations.
+
+## 2.14.9
+
+* Adds `PlatformCap` for `PlatformPolyline.startCap` and `endCap`.
+
+## 2.14.8
+
+* Updates Java compatibility version to 11.
+* Updates minimum supported SDK version to Flutter 3.24/Dart 3.5.
+
+## 2.14.7
+
+* Adds `PlatformPatternItem` pigeon class to convert `PlatformPolyline.pattern`.
+
+## 2.14.6
+
+* Converts 'PlatformCameraUpdate' to pigeon.
+
+## 2.14.5
+
+* Converts `JointType` to enum.
+
+## 2.14.4
+
+* Converts 'PlatformTileOverlay' to pigeon.
+
+## 2.14.3
+
+* Converts `PlatformPolygon` and `PlatformPolyline` to pigeon.
+
+## 2.14.2
+
+* Bumps `com.android.tools.build:gradle` from 7.3.1 to 8.5.1.
+
+## 2.14.1
+
+* Converts `PlatformCircle` and `PlatformMarker` to pigeon.
+
+## 2.14.0
+
+* Updates map configuration and platform view creation parameters to use Pigeon.
+
+## 2.13.0
+
+* Adds support for heatmap layers.
+
+## 2.12.2
+
+* Updates the example app to use TLHC mode, per current package guidance.
+
+## 2.12.1
+
+* Updates lint checks to ignore NewerVersionAvailable.
+
+## 2.12.0
+
+* Converts Java->Dart calls to Pigeon.
+
+## 2.11.1
+
+* Fixes handling of Circle updates.
+
+## 2.11.0
+
+* Converts additional platform calls to Pigeon.
+
 ## 2.10.0
 
 * Converts some platform calls to Pigeon.
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/README.md b/packages/google_maps_flutter/google_maps_flutter_android/README.md
index 8c482864dfdf..a4f0ff5a3486 100644
--- a/packages/google_maps_flutter/google_maps_flutter_android/README.md
+++ b/packages/google_maps_flutter/google_maps_flutter_android/README.md
@@ -78,8 +78,18 @@ Google Play the latest renderer will not be available and the legacy renderer wi
 WARNING: `AndroidMapRenderer.legacy` is known to crash apps and is no longer supported by the Google Maps team
 and therefore cannot be supported by the Flutter team.
 
+## Supported Heatmap Options
+
+| Field                        | Supported |
+| ---------------------------- | :-------: |
+| Heatmap.dissipating          |     x     |
+| Heatmap.maxIntensity         |     ✓     |
+| Heatmap.minimumZoomIntensity |     x     |
+| Heatmap.maximumZoomIntensity |     x     |
+| HeatmapGradient.colorMapSize |     ✓     |
+
 [1]: https://pub.dev/packages/google_maps_flutter
-[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin
+[2]: https://flutter.dev/to/endorsed-federated-plugin
 [3]: https://docs.flutter.dev/development/platform-integration/android/platform-views
 [4]: https://github.com/flutter/flutter/issues/103686
 [5]: https://developers.google.com/maps/documentation/android-sdk/renderer
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/build.gradle b/packages/google_maps_flutter/google_maps_flutter_android/android/build.gradle
index 00781bb77184..4a1dc709b445 100644
--- a/packages/google_maps_flutter/google_maps_flutter_android/android/build.gradle
+++ b/packages/google_maps_flutter/google_maps_flutter_android/android/build.gradle
@@ -8,7 +8,7 @@ buildscript {
     }
 
     dependencies {
-        classpath 'com.android.tools.build:gradle:7.3.1'
+        classpath 'com.android.tools.build:gradle:8.5.1'
     }
 }
 
@@ -22,10 +22,7 @@ rootProject.allprojects {
 apply plugin: 'com.android.library'
 
 android {
-    // Conditional for compatibility with AGP <4.2.
-    if (project.android.hasProperty("namespace")) {
-        namespace 'io.flutter.plugins.googlemaps'
-    }
+    namespace 'io.flutter.plugins.googlemaps'
     compileSdk 34
 
     defaultConfig {
@@ -35,7 +32,7 @@ android {
     lintOptions {
         checkAllWarnings true
         warningsAsErrors true
-        disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency'
+        disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency', 'NewerVersionAvailable'
     }
 
     dependencies {
@@ -44,7 +41,7 @@ android {
         implementation 'com.google.maps.android:android-maps-utils:3.6.0'
         androidTestImplementation 'androidx.test:runner:1.2.0'
         androidTestImplementation 'androidx.test:rules:1.4.0'
-        androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
+        androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
         testImplementation 'junit:junit:4.13.2'
         testImplementation 'org.mockito:mockito-core:5.1.1'
         testImplementation 'androidx.test:core:1.2.0'
@@ -52,8 +49,8 @@ android {
     }
 
     compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_8
-        targetCompatibility JavaVersion.VERSION_1_8
+        sourceCompatibility JavaVersion.VERSION_11
+        targetCompatibility JavaVersion.VERSION_11
     }
 
     testOptions {
@@ -65,6 +62,11 @@ android {
                outputs.upToDateWhen {false}
                showStandardStreams = true
             }
+            // The org.gradle.jvmargs property that may be set in gradle.properties does not impact
+            // the Java heap size when running the Android unit tests. The following property here
+            // sets the heap size to a size large enough to run the robolectric tests across
+            // multiple SDK levels.
+            jvmArgs "-Xmx1g"
         }
     }
 }
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/CirclesController.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/CirclesController.java
index d128d9544b1f..d768b7da8576 100644
--- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/CirclesController.java
+++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/CirclesController.java
@@ -4,26 +4,27 @@
 
 package io.flutter.plugins.googlemaps;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
 import com.google.android.gms.maps.GoogleMap;
 import com.google.android.gms.maps.model.Circle;
 import com.google.android.gms.maps.model.CircleOptions;
-import io.flutter.plugin.common.MethodChannel;
+import io.flutter.plugins.googlemaps.Messages.MapsCallbackApi;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
 class CirclesController {
-
-  private final Map circleIdToController;
+  @VisibleForTesting final Map circleIdToController;
   private final Map googleMapsCircleIdToDartCircleId;
-  private final MethodChannel methodChannel;
+  private final @NonNull MapsCallbackApi flutterApi;
   private final float density;
   private GoogleMap googleMap;
 
-  CirclesController(MethodChannel methodChannel, float density) {
+  CirclesController(@NonNull MapsCallbackApi flutterApi, float density) {
     this.circleIdToController = new HashMap<>();
     this.googleMapsCircleIdToDartCircleId = new HashMap<>();
-    this.methodChannel = methodChannel;
+    this.flutterApi = flutterApi;
     this.density = density;
   }
 
@@ -31,31 +32,20 @@ void setGoogleMap(GoogleMap googleMap) {
     this.googleMap = googleMap;
   }
 
-  void addCircles(List circlesToAdd) {
-    if (circlesToAdd != null) {
-      for (Object circleToAdd : circlesToAdd) {
-        addCircle(circleToAdd);
-      }
+  void addCircles(@NonNull List circlesToAdd) {
+    for (Messages.PlatformCircle circleToAdd : circlesToAdd) {
+      addCircle(circleToAdd);
     }
   }
 
-  void changeCircles(List circlesToChange) {
-    if (circlesToChange != null) {
-      for (Object circleToChange : circlesToChange) {
-        changeCircle(circleToChange);
-      }
+  void changeCircles(@NonNull List circlesToChange) {
+    for (Messages.PlatformCircle circleToChange : circlesToChange) {
+      changeCircle(circleToChange);
     }
   }
 
-  void removeCircles(List circleIdsToRemove) {
-    if (circleIdsToRemove == null) {
-      return;
-    }
-    for (Object rawCircleId : circleIdsToRemove) {
-      if (rawCircleId == null) {
-        continue;
-      }
-      String circleId = (String) rawCircleId;
+  void removeCircles(@NonNull List circleIdsToRemove) {
+    for (String circleId : circleIdsToRemove) {
       final CircleController circleController = circleIdToController.remove(circleId);
       if (circleController != null) {
         circleController.remove();
@@ -69,7 +59,7 @@ boolean onCircleTap(String googleCircleId) {
     if (circleId == null) {
       return false;
     }
-    methodChannel.invokeMethod("circle#onTap", Convert.circleIdToJson(circleId));
+    flutterApi.onCircleTap(circleId, new NoOpVoidResult());
     CircleController circleController = circleIdToController.get(circleId);
     if (circleController != null) {
       return circleController.consumeTapEvents();
@@ -77,10 +67,7 @@ boolean onCircleTap(String googleCircleId) {
     return false;
   }
 
-  private void addCircle(Object circle) {
-    if (circle == null) {
-      return;
-    }
+  void addCircle(@NonNull Messages.PlatformCircle circle) {
     CircleBuilder circleBuilder = new CircleBuilder(density);
     String circleId = Convert.interpretCircleOptions(circle, circleBuilder);
     CircleOptions options = circleBuilder.build();
@@ -94,20 +81,11 @@ private void addCircle(String circleId, CircleOptions circleOptions, boolean con
     googleMapsCircleIdToDartCircleId.put(circle.getId(), circleId);
   }
 
-  private void changeCircle(Object circle) {
-    if (circle == null) {
-      return;
-    }
-    String circleId = getCircleId(circle);
+  private void changeCircle(@NonNull Messages.PlatformCircle circle) {
+    String circleId = circle.getCircleId();
     CircleController circleController = circleIdToController.get(circleId);
     if (circleController != null) {
       Convert.interpretCircleOptions(circle, circleController);
     }
   }
-
-  @SuppressWarnings("unchecked")
-  private static String getCircleId(Object circle) {
-    Map circleMap = (Map) circle;
-    return (String) circleMap.get("circleId");
-  }
 }
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/ClusterManagersController.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/ClusterManagersController.java
index 09ee5d2416f8..cd81eba7940a 100644
--- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/ClusterManagersController.java
+++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/ClusterManagersController.java
@@ -15,7 +15,7 @@
 import com.google.maps.android.clustering.ClusterManager;
 import com.google.maps.android.clustering.view.DefaultClusterRenderer;
 import com.google.maps.android.collections.MarkerManager;
-import io.flutter.plugin.common.MethodChannel;
+import io.flutter.plugins.googlemaps.Messages.MapsCallbackApi;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -30,7 +30,7 @@ class ClusterManagersController
         ClusterManager.OnClusterClickListener {
   @NonNull private final Context context;
   @NonNull private final HashMap> clusterManagerIdToManager;
-  @NonNull private final MethodChannel methodChannel;
+  @NonNull private final MapsCallbackApi flutterApi;
   @Nullable private MarkerManager markerManager;
   @Nullable private GoogleMap googleMap;
 
@@ -41,10 +41,10 @@ class ClusterManagersController
   private ClusterManagersController.OnClusterItemRendered
       clusterItemRenderedListener;
 
-  ClusterManagersController(MethodChannel methodChannel, Context context) {
+  ClusterManagersController(@NonNull MapsCallbackApi flutterApi, Context context) {
     this.clusterManagerIdToManager = new HashMap<>();
     this.context = context;
-    this.methodChannel = methodChannel;
+    this.flutterApi = flutterApi;
   }
 
   void init(GoogleMap googleMap, MarkerManager markerManager) {
@@ -79,18 +79,14 @@ private void initListenersForClusterManager(
   }
 
   /** Adds new ClusterManagers to the controller. */
-  void addClusterManagers(@NonNull List clusterManagersToAdd) {
-    for (Object clusterToAdd : clusterManagersToAdd) {
-      addClusterManager(clusterToAdd);
+  void addClusterManagers(@NonNull List clusterManagersToAdd) {
+    for (Messages.PlatformClusterManager clusterToAdd : clusterManagersToAdd) {
+      addClusterManager(clusterToAdd.getIdentifier());
     }
   }
 
   /** Adds new ClusterManager to the controller. */
-  void addClusterManager(Object clusterManagerData) {
-    String clusterManagerId = getClusterManagerId(clusterManagerData);
-    if (clusterManagerId == null) {
-      throw new IllegalArgumentException("clusterManagerId was null");
-    }
+  void addClusterManager(String clusterManagerId) {
     ClusterManager clusterManager =
         new ClusterManager(context, googleMap, markerManager);
     ClusterRenderer clusterRenderer =
@@ -101,12 +97,8 @@ void addClusterManager(Object clusterManagerData) {
   }
 
   /** Removes ClusterManagers by given cluster manager IDs from the controller. */
-  public void removeClusterManagers(@NonNull List clusterManagerIdsToRemove) {
-    for (Object rawClusterManagerId : clusterManagerIdsToRemove) {
-      if (rawClusterManagerId == null) {
-        continue;
-      }
-      String clusterManagerId = (String) rawClusterManagerId;
+  public void removeClusterManagers(@NonNull List clusterManagerIdsToRemove) {
+    for (String clusterManagerId : clusterManagerIdsToRemove) {
       removeClusterManager(clusterManagerId);
     }
   }
@@ -194,7 +186,8 @@ public boolean onClusterClick(Cluster cluster) {
     if (cluster.getSize() > 0) {
       MarkerBuilder[] builders = cluster.getItems().toArray(new MarkerBuilder[0]);
       String clusterManagerId = builders[0].clusterManagerId();
-      methodChannel.invokeMethod("cluster#onTap", Convert.clusterToJson(clusterManagerId, cluster));
+      flutterApi.onClusterTap(
+          Convert.clusterToPigeon(clusterManagerId, cluster), new NoOpVoidResult());
     }
 
     // Return false to allow the default behavior of the cluster click event to occur.
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java
index e1817597f16c..5701825f12d9 100644
--- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java
+++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java
@@ -4,14 +4,22 @@
 
 package io.flutter.plugins.googlemaps;
 
+import static com.google.android.gms.maps.GoogleMap.MAP_TYPE_HYBRID;
+import static com.google.android.gms.maps.GoogleMap.MAP_TYPE_NONE;
+import static com.google.android.gms.maps.GoogleMap.MAP_TYPE_NORMAL;
+import static com.google.android.gms.maps.GoogleMap.MAP_TYPE_SATELLITE;
+import static com.google.android.gms.maps.GoogleMap.MAP_TYPE_TERRAIN;
+
 import android.content.res.AssetManager;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Point;
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 import com.google.android.gms.maps.CameraUpdate;
 import com.google.android.gms.maps.CameraUpdateFactory;
+import com.google.android.gms.maps.MapsInitializer;
 import com.google.android.gms.maps.model.BitmapDescriptor;
 import com.google.android.gms.maps.model.BitmapDescriptorFactory;
 import com.google.android.gms.maps.model.ButtCap;
@@ -21,6 +29,7 @@
 import com.google.android.gms.maps.model.Dash;
 import com.google.android.gms.maps.model.Dot;
 import com.google.android.gms.maps.model.Gap;
+import com.google.android.gms.maps.model.JointType;
 import com.google.android.gms.maps.model.LatLng;
 import com.google.android.gms.maps.model.LatLngBounds;
 import com.google.android.gms.maps.model.PatternItem;
@@ -28,106 +37,106 @@
 import com.google.android.gms.maps.model.SquareCap;
 import com.google.android.gms.maps.model.Tile;
 import com.google.maps.android.clustering.Cluster;
+import com.google.maps.android.heatmaps.Gradient;
+import com.google.maps.android.heatmaps.WeightedLatLng;
 import io.flutter.FlutterInjector;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
 /** Conversions between JSON-like values and GoogleMaps data types. */
 class Convert {
+  // These constants must match the corresponding constants in serialization.dart
+  public static final String HEATMAP_ID_KEY = "heatmapId";
+  public static final String HEATMAP_DATA_KEY = "data";
+  public static final String HEATMAP_GRADIENT_KEY = "gradient";
+  public static final String HEATMAP_MAX_INTENSITY_KEY = "maxIntensity";
+  public static final String HEATMAP_OPACITY_KEY = "opacity";
+  public static final String HEATMAP_RADIUS_KEY = "radius";
+  public static final String HEATMAP_GRADIENT_COLORS_KEY = "colors";
+  public static final String HEATMAP_GRADIENT_START_POINTS_KEY = "startPoints";
+  public static final String HEATMAP_GRADIENT_COLOR_MAP_SIZE_KEY = "colorMapSize";
 
   private static BitmapDescriptor toBitmapDescriptor(
-      Object o, AssetManager assetManager, float density) {
-    final List data = toList(o);
-    final String descriptorType = toString(data.get(0));
-    switch (descriptorType) {
-      case "defaultMarker":
-        if (data.size() == 1) {
-          return BitmapDescriptorFactory.defaultMarker();
-        } else {
-          final float hue = toFloat(data.get(1));
-          return BitmapDescriptorFactory.defaultMarker(hue);
-        }
-      case "fromAsset":
-        final String assetPath = toString(data.get(1));
-        if (data.size() == 2) {
-          return BitmapDescriptorFactory.fromAsset(
-              FlutterInjector.instance().flutterLoader().getLookupKeyForAsset(assetPath));
-        } else {
-          final String assetPackage = toString(data.get(2));
-          return BitmapDescriptorFactory.fromAsset(
-              FlutterInjector.instance()
-                  .flutterLoader()
-                  .getLookupKeyForAsset(assetPath, assetPackage));
-        }
-      case "fromAssetImage":
-        final String assetImagePath = toString(data.get(1));
-        if (data.size() == 3) {
-          return BitmapDescriptorFactory.fromAsset(
-              FlutterInjector.instance().flutterLoader().getLookupKeyForAsset(assetImagePath));
-        } else {
-          throw new IllegalArgumentException(
-              "'fromAssetImage' Expected exactly 3 arguments, got: " + data.size());
-        }
-      case "fromBytes":
-        return getBitmapFromBytesLegacy(data);
-      case "asset":
-        if (!(data.get(1) instanceof Map)) {
-          throw new IllegalArgumentException("'asset' expected a map as the second parameter");
-        }
-        final Map assetData = toMap(data.get(1));
-        return getBitmapFromAsset(
-            assetData,
-            assetManager,
-            density,
-            new BitmapDescriptorFactoryWrapper(),
-            new FlutterInjectorWrapper());
-      case "bytes":
-        if (!(data.get(1) instanceof Map)) {
-          throw new IllegalArgumentException("'bytes' expected a map as the second parameter");
-        }
-        final Map byteData = toMap(data.get(1));
-        return getBitmapFromBytes(byteData, density, new BitmapDescriptorFactoryWrapper());
-      default:
-        throw new IllegalArgumentException("Cannot interpret " + o + " as BitmapDescriptor");
+      Messages.PlatformBitmap platformBitmap, AssetManager assetManager, float density) {
+    return toBitmapDescriptor(
+        platformBitmap, assetManager, density, new BitmapDescriptorFactoryWrapper());
+  }
+
+  private static BitmapDescriptor toBitmapDescriptor(
+      Messages.PlatformBitmap platformBitmap,
+      AssetManager assetManager,
+      float density,
+      BitmapDescriptorFactoryWrapper wrapper) {
+    Object bitmap = platformBitmap.getBitmap();
+    if (bitmap instanceof Messages.PlatformBitmapDefaultMarker) {
+      Messages.PlatformBitmapDefaultMarker typedBitmap =
+          (Messages.PlatformBitmapDefaultMarker) bitmap;
+      if (typedBitmap.getHue() == null) {
+        return BitmapDescriptorFactory.defaultMarker();
+      } else {
+        final float hue = typedBitmap.getHue().floatValue();
+        return BitmapDescriptorFactory.defaultMarker(hue);
+      }
     }
+    if (bitmap instanceof Messages.PlatformBitmapAsset) {
+      Messages.PlatformBitmapAsset typedBitmap = (Messages.PlatformBitmapAsset) bitmap;
+      final String assetPath = typedBitmap.getName();
+      final String assetPackage = typedBitmap.getPkg();
+      if (assetPackage == null) {
+        return BitmapDescriptorFactory.fromAsset(
+            FlutterInjector.instance().flutterLoader().getLookupKeyForAsset(assetPath));
+      } else {
+        return BitmapDescriptorFactory.fromAsset(
+            FlutterInjector.instance()
+                .flutterLoader()
+                .getLookupKeyForAsset(assetPath, assetPackage));
+      }
+    }
+    if (bitmap instanceof Messages.PlatformBitmapAssetImage) {
+      Messages.PlatformBitmapAssetImage typedBitmap = (Messages.PlatformBitmapAssetImage) bitmap;
+      final String assetImagePath = typedBitmap.getName();
+      return BitmapDescriptorFactory.fromAsset(
+          FlutterInjector.instance().flutterLoader().getLookupKeyForAsset(assetImagePath));
+    }
+    if (bitmap instanceof Messages.PlatformBitmapBytes) {
+      Messages.PlatformBitmapBytes typedBitmap = (Messages.PlatformBitmapBytes) bitmap;
+      return getBitmapFromBytesLegacy(typedBitmap);
+    }
+    if (bitmap instanceof Messages.PlatformBitmapAssetMap) {
+      Messages.PlatformBitmapAssetMap typedBitmap = (Messages.PlatformBitmapAssetMap) bitmap;
+      return getBitmapFromAsset(
+          typedBitmap, assetManager, density, wrapper, new FlutterInjectorWrapper());
+    }
+    if (bitmap instanceof Messages.PlatformBitmapBytesMap) {
+      Messages.PlatformBitmapBytesMap typedBitmap = (Messages.PlatformBitmapBytesMap) bitmap;
+      return getBitmapFromBytes(typedBitmap, density, wrapper);
+    }
+    throw new IllegalArgumentException("PlatformBitmap did not contain a supported subtype.");
   }
 
   // Used for deprecated fromBytes bitmap descriptor.
   // Can be removed after support for "fromBytes" bitmap descriptor type is
   // removed.
-  private static BitmapDescriptor getBitmapFromBytesLegacy(List data) {
-    if (data.size() == 2) {
-      try {
-        Bitmap bitmap = toBitmap(data.get(1));
-        return BitmapDescriptorFactory.fromBitmap(bitmap);
-      } catch (Exception e) {
-        throw new IllegalArgumentException("Unable to interpret bytes as a valid image.", e);
-      }
-    } else {
-      throw new IllegalArgumentException(
-          "fromBytes should have exactly one argument, interpretTileOverlayOptions the bytes. Got: "
-              + data.size());
+  private static BitmapDescriptor getBitmapFromBytesLegacy(
+      Messages.PlatformBitmapBytes bitmapBytes) {
+    try {
+      Bitmap bitmap = toBitmap(bitmapBytes.getByteData());
+      return BitmapDescriptorFactory.fromBitmap(bitmap);
+    } catch (Exception e) {
+      throw new IllegalArgumentException("Unable to interpret bytes as a valid image.", e);
     }
   }
 
   /**
    * Creates a BitmapDescriptor object from bytes data.
    *
-   * 

This method requires the `byteData` map to contain specific keys: 'byteData' for image - * bytes, 'bitmapScaling' for scaling mode, and 'imagePixelRatio' for scale ratio. It may - * optionally include 'width' and/or 'height' for explicit image dimensions. - * - * @param byteData a map containing the byte data and scaling instructions. Expected keys are: - * 'byteData': the actual bytes of the image, 'bitmapScaling': the scaling mode, either 'auto' - * or 'none', 'imagePixelRatio': used with 'auto' bitmapScaling if width or height are not - * provided, 'width' (optional): the desired width, which affects scaling if 'height' is not - * provided, 'height' (optional): the desired height, which affects scaling if 'width' is not - * provided + * @param bytesMap a [PlatformBitmapBytesMap] containing the byte data from which to construct a + * [BitmapDescriptor] and a bitmap scaling mode. The optional `width` affects scaling when + * `height` is `null`, and the optional `height` affects scaling when `width` is `null. * @param density the density of the display, used to calculate pixel dimensions. * @param bitmapDescriptorFactory is an instance of the BitmapDescriptorFactoryWrapper. * @return BitmapDescriptor object from bytes data. @@ -136,34 +145,16 @@ private static BitmapDescriptor getBitmapFromBytesLegacy(List data) { */ @VisibleForTesting public static BitmapDescriptor getBitmapFromBytes( - Map byteData, float density, BitmapDescriptorFactoryWrapper bitmapDescriptorFactory) { - - final String byteDataKey = "byteData"; - final String bitmapScalingKey = "bitmapScaling"; - final String imagePixelRatioKey = "imagePixelRatio"; - - if (!byteData.containsKey(byteDataKey)) { - throw new IllegalArgumentException("'bytes' requires '" + byteDataKey + "' key."); - } - if (!byteData.containsKey(bitmapScalingKey)) { - throw new IllegalArgumentException("'bytes' requires '" + bitmapScalingKey + "' key."); - } - if (!byteData.containsKey(imagePixelRatioKey)) { - throw new IllegalArgumentException("'bytes' requires '" + imagePixelRatioKey + "' key."); - } - + Messages.PlatformBitmapBytesMap bytesMap, + float density, + BitmapDescriptorFactoryWrapper bitmapDescriptorFactory) { try { - Bitmap bitmap = toBitmap(byteData.get(byteDataKey)); - String scalingMode = toString(byteData.get(bitmapScalingKey)); + Bitmap bitmap = toBitmap(bytesMap.getByteData()); + Messages.PlatformMapBitmapScaling scalingMode = bytesMap.getBitmapScaling(); switch (scalingMode) { - case "auto": - final String widthKey = "width"; - final String heightKey = "height"; - - final Double width = - byteData.containsKey(widthKey) ? toDouble(byteData.get(widthKey)) : null; - final Double height = - byteData.containsKey(heightKey) ? toDouble(byteData.get(heightKey)) : null; + case AUTO: + final Double width = bytesMap.getWidth(); + final Double height = bytesMap.getHeight(); if (width != null || height != null) { int targetWidth = width != null ? toInt(width * density) : bitmap.getWidth(); @@ -182,10 +173,10 @@ public static BitmapDescriptor getBitmapFromBytes( toScaledBitmap(bitmap, targetWidth, targetHeight)); } else { // Scale image using given scale ratio - final float scale = density / toFloat(byteData.get(imagePixelRatioKey)); + final float scale = density / bytesMap.getImagePixelRatio().floatValue(); return bitmapDescriptorFactory.fromBitmap(toScaledBitmap(bitmap, scale)); } - case "none": + case NONE: break; } return bitmapDescriptorFactory.fromBitmap(bitmap); @@ -198,15 +189,13 @@ public static BitmapDescriptor getBitmapFromBytes( * Creates a BitmapDescriptor object from asset, using given details and density. * *

This method processes an asset specified by name and applies scaling based on the provided - * parameters. The `assetDetails` map must contain the keys 'assetName', 'bitmapScaling', and - * 'imagePixelRatio', and may optionally include 'width' and/or 'height' to explicitly set the - * dimensions of the output image. + * parameters. The `assetMap` object provides the asset name, bitmap scaling mode, and image pixel + * ratio, and may optionally include 'width' and/or 'height' to explicitly set the dimensions of + * the output image. * - * @param assetDetails a map containing the asset details and scaling instructions, with keys - * 'assetName': the name of the asset file, 'bitmapScaling': the scaling mode, either 'auto' - * or 'none', 'imagePixelRatio': used with 'auto' scaling to compute the scale ratio, 'width' - * (optional): the desired width, which affects scaling if 'height' is not provided, 'height' - * (optional): the desired height, which affects scaling if 'width' is not provided + * @param assetMap a [PlatformBitmapAssetMap] containing the asset name from which to construct a + * [BitmapDescriptor] and a bitmap scaling mode. The optional `width` affects scaling when + * `height` is `null`, and the optional `height` affects scaling when `width` is `null. * @param assetManager assetManager An instance of Android's AssetManager, which provides access * to any raw asset files stored in the application's assets directory. * @param density density the density of the display, used to calculate pixel dimensions. @@ -218,39 +207,19 @@ public static BitmapDescriptor getBitmapFromBytes( */ @VisibleForTesting public static BitmapDescriptor getBitmapFromAsset( - Map assetDetails, + Messages.PlatformBitmapAssetMap assetMap, AssetManager assetManager, float density, BitmapDescriptorFactoryWrapper bitmapDescriptorFactory, FlutterInjectorWrapper flutterInjector) { - - final String assetNameKey = "assetName"; - final String bitmapScalingKey = "bitmapScaling"; - final String imagePixelRatioKey = "imagePixelRatio"; - - if (!assetDetails.containsKey(assetNameKey)) { - throw new IllegalArgumentException("'asset' requires '" + assetNameKey + "' key."); - } - if (!assetDetails.containsKey(bitmapScalingKey)) { - throw new IllegalArgumentException("'asset' requires '" + bitmapScalingKey + "' key."); - } - if (!assetDetails.containsKey(imagePixelRatioKey)) { - throw new IllegalArgumentException("'asset' requires '" + imagePixelRatioKey + "' key."); - } - - final String assetName = toString(assetDetails.get(assetNameKey)); + final String assetName = assetMap.getAssetName(); final String assetKey = flutterInjector.getLookupKeyForAsset(assetName); - String scalingMode = toString(assetDetails.get(bitmapScalingKey)); + Messages.PlatformMapBitmapScaling scalingMode = assetMap.getBitmapScaling(); switch (scalingMode) { - case "auto": - final String widthKey = "width"; - final String heightKey = "height"; - - final Double width = - assetDetails.containsKey(widthKey) ? toDouble(assetDetails.get(widthKey)) : null; - final Double height = - assetDetails.containsKey(heightKey) ? toDouble(assetDetails.get(heightKey)) : null; + case AUTO: + final Double width = assetMap.getWidth(); + final Double height = assetMap.getHeight(); InputStream inputStream = null; try { inputStream = assetManager.open(assetKey); @@ -273,7 +242,7 @@ public static BitmapDescriptor getBitmapFromAsset( toScaledBitmap(bitmap, targetWidth, targetHeight)); } else { // Scale image using given scale. - final float scale = density / toFloat(assetDetails.get(imagePixelRatioKey)); + final float scale = density / assetMap.getImagePixelRatio().floatValue(); return bitmapDescriptorFactory.fromBitmap(toScaledBitmap(bitmap, scale)); } } catch (Exception e) { @@ -287,58 +256,74 @@ public static BitmapDescriptor getBitmapFromAsset( } } } - case "none": + case NONE: break; } return bitmapDescriptorFactory.fromAsset(assetKey); } - private static boolean toBoolean(Object o) { - return (Boolean) o; - } - - static CameraPosition toCameraPosition(Object o) { - final Map data = toMap(o); + static @NonNull CameraPosition cameraPositionFromPigeon( + @NonNull Messages.PlatformCameraPosition position) { final CameraPosition.Builder builder = CameraPosition.builder(); - builder.bearing(toFloat(data.get("bearing"))); - builder.target(toLatLng(data.get("target"))); - builder.tilt(toFloat(data.get("tilt"))); - builder.zoom(toFloat(data.get("zoom"))); + builder.bearing(position.getBearing().floatValue()); + builder.target(latLngFromPigeon(position.getTarget())); + builder.tilt(position.getTilt().floatValue()); + builder.zoom(position.getZoom().floatValue()); return builder.build(); } - static CameraUpdate toCameraUpdate(Object o, float density) { - final List data = toList(o); - switch (toString(data.get(0))) { - case "newCameraPosition": - return CameraUpdateFactory.newCameraPosition(toCameraPosition(data.get(1))); - case "newLatLng": - return CameraUpdateFactory.newLatLng(toLatLng(data.get(1))); - case "newLatLngBounds": - return CameraUpdateFactory.newLatLngBounds( - toLatLngBounds(data.get(1)), toPixels(data.get(2), density)); - case "newLatLngZoom": - return CameraUpdateFactory.newLatLngZoom(toLatLng(data.get(1)), toFloat(data.get(2))); - case "scrollBy": - return CameraUpdateFactory.scrollBy( // - toFractionalPixels(data.get(1), density), // - toFractionalPixels(data.get(2), density)); - case "zoomBy": - if (data.size() == 2) { - return CameraUpdateFactory.zoomBy(toFloat(data.get(1))); - } else { - return CameraUpdateFactory.zoomBy(toFloat(data.get(1)), toPoint(data.get(2), density)); - } - case "zoomIn": - return CameraUpdateFactory.zoomIn(); - case "zoomOut": - return CameraUpdateFactory.zoomOut(); - case "zoomTo": - return CameraUpdateFactory.zoomTo(toFloat(data.get(1))); - default: - throw new IllegalArgumentException("Cannot interpret " + o + " as CameraUpdate"); - } + static CameraUpdate cameraUpdateFromPigeon(Messages.PlatformCameraUpdate update, float density) { + Object cameraUpdate = update.getCameraUpdate(); + if (cameraUpdate instanceof Messages.PlatformCameraUpdateNewCameraPosition) { + Messages.PlatformCameraUpdateNewCameraPosition newCameraPosition = + (Messages.PlatformCameraUpdateNewCameraPosition) cameraUpdate; + return CameraUpdateFactory.newCameraPosition( + cameraPositionFromPigeon(newCameraPosition.getCameraPosition())); + } + if (cameraUpdate instanceof Messages.PlatformCameraUpdateNewLatLng) { + Messages.PlatformCameraUpdateNewLatLng newLatLng = + (Messages.PlatformCameraUpdateNewLatLng) cameraUpdate; + return CameraUpdateFactory.newLatLng(latLngFromPigeon(newLatLng.getLatLng())); + } + if (cameraUpdate instanceof Messages.PlatformCameraUpdateNewLatLngZoom) { + Messages.PlatformCameraUpdateNewLatLngZoom newLatLngZoom = + (Messages.PlatformCameraUpdateNewLatLngZoom) cameraUpdate; + return CameraUpdateFactory.newLatLngZoom( + latLngFromPigeon(newLatLngZoom.getLatLng()), newLatLngZoom.getZoom().floatValue()); + } + if (cameraUpdate instanceof Messages.PlatformCameraUpdateNewLatLngBounds) { + Messages.PlatformCameraUpdateNewLatLngBounds newLatLngBounds = + (Messages.PlatformCameraUpdateNewLatLngBounds) cameraUpdate; + return CameraUpdateFactory.newLatLngBounds( + latLngBoundsFromPigeon(newLatLngBounds.getBounds()), + (int) (newLatLngBounds.getPadding() * density)); + } + if (cameraUpdate instanceof Messages.PlatformCameraUpdateScrollBy) { + Messages.PlatformCameraUpdateScrollBy scrollBy = + (Messages.PlatformCameraUpdateScrollBy) cameraUpdate; + return CameraUpdateFactory.scrollBy( + scrollBy.getDx().floatValue() * density, scrollBy.getDy().floatValue() * density); + } + if (cameraUpdate instanceof Messages.PlatformCameraUpdateZoomBy) { + Messages.PlatformCameraUpdateZoomBy zoomBy = + (Messages.PlatformCameraUpdateZoomBy) cameraUpdate; + final Point focus = pointFromPigeon(zoomBy.getFocus(), density); + return (focus != null) + ? CameraUpdateFactory.zoomBy(zoomBy.getAmount().floatValue(), focus) + : CameraUpdateFactory.zoomBy(zoomBy.getAmount().floatValue()); + } + if (cameraUpdate instanceof Messages.PlatformCameraUpdateZoomTo) { + Messages.PlatformCameraUpdateZoomTo zoomTo = + (Messages.PlatformCameraUpdateZoomTo) cameraUpdate; + return CameraUpdateFactory.zoomTo(zoomTo.getZoom().floatValue()); + } + if (cameraUpdate instanceof Messages.PlatformCameraUpdateZoom) { + Messages.PlatformCameraUpdateZoom zoom = (Messages.PlatformCameraUpdateZoom) cameraUpdate; + return (zoom.getOut()) ? CameraUpdateFactory.zoomOut() : CameraUpdateFactory.zoomIn(); + } + throw new IllegalArgumentException( + "PlatformCameraUpdate's cameraUpdate field must be one of the PlatformCameraUpdate... case classes."); } private static double toDouble(Object o) { @@ -349,31 +334,52 @@ private static float toFloat(Object o) { return ((Number) o).floatValue(); } - private static Float toFloatWrapper(Object o) { - return (o == null) ? null : toFloat(o); + private static @Nullable Float nullableDoubleToFloat(@Nullable Double d) { + return (d == null) ? null : d.floatValue(); } private static int toInt(Object o) { return ((Number) o).intValue(); } - static Object cameraPositionToJson(CameraPosition position) { - if (position == null) { + static int toMapType(@NonNull Messages.PlatformMapType type) { + switch (type) { + case NONE: + return MAP_TYPE_NONE; + case NORMAL: + return MAP_TYPE_NORMAL; + case SATELLITE: + return MAP_TYPE_SATELLITE; + case TERRAIN: + return MAP_TYPE_TERRAIN; + case HYBRID: + return MAP_TYPE_HYBRID; + } + return MAP_TYPE_NORMAL; + } + + static @Nullable MapsInitializer.Renderer toMapRendererType( + @Nullable Messages.PlatformRendererType type) { + if (type == null) { return null; } - final Map data = new HashMap<>(); - data.put("bearing", position.bearing); - data.put("target", latLngToJson(position.target)); - data.put("tilt", position.tilt); - data.put("zoom", position.zoom); - return data; + switch (type) { + case LATEST: + return MapsInitializer.Renderer.LATEST; + case LEGACY: + return MapsInitializer.Renderer.LEGACY; + } + return null; } - static Object latLngBoundsToJson(LatLngBounds latLngBounds) { - final Map arguments = new HashMap<>(2); - arguments.put("southwest", latLngToJson(latLngBounds.southwest)); - arguments.put("northeast", latLngToJson(latLngBounds.northeast)); - return arguments; + static @NonNull Messages.PlatformCameraPosition cameraPositionToPigeon( + @NonNull CameraPosition position) { + return new Messages.PlatformCameraPosition.Builder() + .setBearing((double) position.bearing) + .setTarget(latLngToPigeon(position.target)) + .setTilt((double) position.tilt) + .setZoom((double) position.zoom) + .build(); } static Messages.PlatformLatLngBounds latLngBoundsToPigeon(LatLngBounds latLngBounds) { @@ -383,58 +389,10 @@ static Messages.PlatformLatLngBounds latLngBoundsToPigeon(LatLngBounds latLngBou .build(); } - static Object markerIdToJson(String markerId) { - if (markerId == null) { - return null; - } - final Map data = new HashMap<>(1); - data.put("markerId", markerId); - return data; - } - - static Object polygonIdToJson(String polygonId) { - if (polygonId == null) { - return null; - } - final Map data = new HashMap<>(1); - data.put("polygonId", polygonId); - return data; - } - - static Object polylineIdToJson(String polylineId) { - if (polylineId == null) { - return null; - } - final Map data = new HashMap<>(1); - data.put("polylineId", polylineId); - return data; - } - - static Object circleIdToJson(String circleId) { - if (circleId == null) { - return null; - } - final Map data = new HashMap<>(1); - data.put("circleId", circleId); - return data; - } - - static Map tileOverlayArgumentsToJson( - String tileOverlayId, int x, int y, int zoom) { - - if (tileOverlayId == null) { - return null; - } - final Map data = new HashMap<>(4); - data.put("tileOverlayId", tileOverlayId); - data.put("x", x); - data.put("y", y); - data.put("zoom", zoom); - return data; - } - - static Object latLngToJson(LatLng latLng) { - return Arrays.asList(latLng.latitude, latLng.longitude); + static @NonNull LatLngBounds latLngBoundsFromPigeon( + @NonNull Messages.PlatformLatLngBounds bounds) { + return new LatLngBounds( + latLngFromPigeon(bounds.getSouthwest()), latLngFromPigeon(bounds.getNortheast())); } static Messages.PlatformLatLng latLngToPigeon(LatLng latLng) { @@ -448,36 +406,6 @@ static LatLng latLngFromPigeon(Messages.PlatformLatLng latLng) { return new LatLng(latLng.getLatitude(), latLng.getLongitude()); } - static Object clusterToJson(String clusterManagerId, Cluster cluster) { - int clusterSize = cluster.getSize(); - LatLngBounds.Builder latLngBoundsBuilder = LatLngBounds.builder(); - - String[] markerIds = new String[clusterSize]; - MarkerBuilder[] markerBuilders = cluster.getItems().toArray(new MarkerBuilder[clusterSize]); - - // Loops though cluster items and reads markers position for the LatLngBounds - // builder - // and also builds list of marker ids on the cluster. - for (int i = 0; i < clusterSize; i++) { - MarkerBuilder markerBuilder = markerBuilders[i]; - latLngBoundsBuilder.include(markerBuilder.getPosition()); - markerIds[i] = markerBuilder.markerId(); - } - - Object position = latLngToJson(cluster.getPosition()); - Object bounds = latLngBoundsToJson(latLngBoundsBuilder.build()); - - final Map data = new HashMap<>(4); - - // For dart side implementation see parseCluster method at - // packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_maps_flutter_android.dart - data.put("clusterManagerId", clusterManagerId); - data.put("position", position); - data.put("bounds", bounds); - data.put("markerIds", Arrays.asList(markerIds)); - return data; - } - static Messages.PlatformCluster clusterToPigeon( String clusterManagerId, Cluster cluster) { int clusterSize = cluster.getSize(); @@ -504,20 +432,31 @@ static LatLng toLatLng(Object o) { return new LatLng(toDouble(data.get(0)), toDouble(data.get(1))); } - static Point pointFromPigeon(Messages.PlatformPoint point) { - return new Point(point.getX().intValue(), point.getY().intValue()); + /** + * Converts a list of serialized weighted lat/lng to a list of WeightedLatLng. + * + * @param o The serialized list of weighted lat/lng. + * @return The list of WeightedLatLng. + */ + static WeightedLatLng toWeightedLatLng(Object o) { + final List data = toList(o); + return new WeightedLatLng(toLatLng(data.get(0)), toDouble(data.get(1))); } - static Messages.PlatformPoint pointToPigeon(Point point) { - return new Messages.PlatformPoint.Builder().setX((long) point.x).setY((long) point.y).build(); + static Point pointFromPigeon(Messages.PlatformPoint point) { + return new Point(point.getX().intValue(), point.getY().intValue()); } - private static LatLngBounds toLatLngBounds(Object o) { - if (o == null) { + @Nullable + static Point pointFromPigeon(@Nullable Messages.PlatformDoublePair point, float density) { + if (point == null) { return null; } - final List data = toList(o); - return new LatLngBounds(toLatLng(data.get(0)), toLatLng(data.get(1))); + return new Point((int) (point.getX() * density), (int) (point.getY() * density)); + } + + static Messages.PlatformPoint pointToPigeon(Point point) { + return new Messages.PlatformPoint.Builder().setX((long) point.x).setY((long) point.y).build(); } private static List toList(Object o) { @@ -528,28 +467,7 @@ private static List toList(Object o) { return (Map) o; } - private static Map toObjectMap(Object o) { - Map hashMap = new HashMap<>(); - Map map = (Map) o; - for (Object key : map.keySet()) { - Object object = map.get(key); - if (object != null) { - hashMap.put((String) key, object); - } - } - return hashMap; - } - - private static float toFractionalPixels(Object o, float density) { - return toFloat(o) * density; - } - - private static int toPixels(Object o, float density) { - return (int) toFractionalPixels(o, density); - } - - private static Bitmap toBitmap(Object o) { - byte[] bmpData = (byte[]) o; + private static Bitmap toBitmap(byte[] bmpData) { Bitmap bitmap = BitmapFactory.decodeByteArray(bmpData, 0, bmpData.length); if (bitmap == null) { throw new IllegalArgumentException("Unable to decode bytes as a valid bitmap."); @@ -577,422 +495,360 @@ private static Bitmap toScaledBitmap(Bitmap bitmap, int width, int height) { return bitmap; } - private static Point toPoint(Object o, float density) { - final List data = toList(o); - return new Point(toPixels(data.get(0), density), toPixels(data.get(1), density)); - } - - private static String toString(Object o) { - return (String) o; - } - - static void interpretGoogleMapOptions(Object o, GoogleMapOptionsSink sink) { - final Map data = toMap(o); - final Object cameraTargetBounds = data.get("cameraTargetBounds"); + static void interpretMapConfiguration( + @NonNull Messages.PlatformMapConfiguration config, @NonNull GoogleMapOptionsSink sink) { + final Messages.PlatformCameraTargetBounds cameraTargetBounds = config.getCameraTargetBounds(); if (cameraTargetBounds != null) { - final List targetData = toList(cameraTargetBounds); - sink.setCameraTargetBounds(toLatLngBounds(targetData.get(0))); + final @Nullable Messages.PlatformLatLngBounds bounds = cameraTargetBounds.getBounds(); + sink.setCameraTargetBounds(bounds == null ? null : latLngBoundsFromPigeon(bounds)); } - final Object compassEnabled = data.get("compassEnabled"); + final Boolean compassEnabled = config.getCompassEnabled(); if (compassEnabled != null) { - sink.setCompassEnabled(toBoolean(compassEnabled)); + sink.setCompassEnabled(compassEnabled); } - final Object mapToolbarEnabled = data.get("mapToolbarEnabled"); + final Boolean mapToolbarEnabled = config.getMapToolbarEnabled(); if (mapToolbarEnabled != null) { - sink.setMapToolbarEnabled(toBoolean(mapToolbarEnabled)); + sink.setMapToolbarEnabled(mapToolbarEnabled); } - final Object mapType = data.get("mapType"); + final Messages.PlatformMapType mapType = config.getMapType(); if (mapType != null) { - sink.setMapType(toInt(mapType)); + sink.setMapType(toMapType(mapType)); } - final Object minMaxZoomPreference = data.get("minMaxZoomPreference"); + final Messages.PlatformZoomRange minMaxZoomPreference = config.getMinMaxZoomPreference(); if (minMaxZoomPreference != null) { - final List zoomPreferenceData = toList(minMaxZoomPreference); - sink.setMinMaxZoomPreference( // - toFloatWrapper(zoomPreferenceData.get(0)), // - toFloatWrapper(zoomPreferenceData.get(1))); + sink.setMinMaxZoomPreference( + nullableDoubleToFloat(minMaxZoomPreference.getMin()), + nullableDoubleToFloat(minMaxZoomPreference.getMax())); } - final Object padding = data.get("padding"); + final Messages.PlatformEdgeInsets padding = config.getPadding(); if (padding != null) { - final List paddingData = toList(padding); sink.setPadding( - toFloat(paddingData.get(0)), - toFloat(paddingData.get(1)), - toFloat(paddingData.get(2)), - toFloat(paddingData.get(3))); + padding.getTop().floatValue(), + padding.getLeft().floatValue(), + padding.getBottom().floatValue(), + padding.getRight().floatValue()); } - final Object rotateGesturesEnabled = data.get("rotateGesturesEnabled"); + final Boolean rotateGesturesEnabled = config.getRotateGesturesEnabled(); if (rotateGesturesEnabled != null) { - sink.setRotateGesturesEnabled(toBoolean(rotateGesturesEnabled)); + sink.setRotateGesturesEnabled(rotateGesturesEnabled); } - final Object scrollGesturesEnabled = data.get("scrollGesturesEnabled"); + final Boolean scrollGesturesEnabled = config.getScrollGesturesEnabled(); if (scrollGesturesEnabled != null) { - sink.setScrollGesturesEnabled(toBoolean(scrollGesturesEnabled)); + sink.setScrollGesturesEnabled(scrollGesturesEnabled); } - final Object tiltGesturesEnabled = data.get("tiltGesturesEnabled"); + final Boolean tiltGesturesEnabled = config.getTiltGesturesEnabled(); if (tiltGesturesEnabled != null) { - sink.setTiltGesturesEnabled(toBoolean(tiltGesturesEnabled)); + sink.setTiltGesturesEnabled(tiltGesturesEnabled); } - final Object trackCameraPosition = data.get("trackCameraPosition"); + final Boolean trackCameraPosition = config.getTrackCameraPosition(); if (trackCameraPosition != null) { - sink.setTrackCameraPosition(toBoolean(trackCameraPosition)); + sink.setTrackCameraPosition(trackCameraPosition); } - final Object zoomGesturesEnabled = data.get("zoomGesturesEnabled"); + final Boolean zoomGesturesEnabled = config.getZoomGesturesEnabled(); if (zoomGesturesEnabled != null) { - sink.setZoomGesturesEnabled(toBoolean(zoomGesturesEnabled)); + sink.setZoomGesturesEnabled(zoomGesturesEnabled); } - final Object liteModeEnabled = data.get("liteModeEnabled"); + final Boolean liteModeEnabled = config.getLiteModeEnabled(); if (liteModeEnabled != null) { - sink.setLiteModeEnabled(toBoolean(liteModeEnabled)); + sink.setLiteModeEnabled(liteModeEnabled); } - final Object myLocationEnabled = data.get("myLocationEnabled"); + final Boolean myLocationEnabled = config.getMyLocationEnabled(); if (myLocationEnabled != null) { - sink.setMyLocationEnabled(toBoolean(myLocationEnabled)); + sink.setMyLocationEnabled(myLocationEnabled); } - final Object zoomControlsEnabled = data.get("zoomControlsEnabled"); + final Boolean zoomControlsEnabled = config.getZoomControlsEnabled(); if (zoomControlsEnabled != null) { - sink.setZoomControlsEnabled(toBoolean(zoomControlsEnabled)); + sink.setZoomControlsEnabled(zoomControlsEnabled); } - final Object myLocationButtonEnabled = data.get("myLocationButtonEnabled"); + final Boolean myLocationButtonEnabled = config.getMyLocationButtonEnabled(); if (myLocationButtonEnabled != null) { - sink.setMyLocationButtonEnabled(toBoolean(myLocationButtonEnabled)); + sink.setMyLocationButtonEnabled(myLocationButtonEnabled); } - final Object indoorEnabled = data.get("indoorEnabled"); + final Boolean indoorEnabled = config.getIndoorViewEnabled(); if (indoorEnabled != null) { - sink.setIndoorEnabled(toBoolean(indoorEnabled)); + sink.setIndoorEnabled(indoorEnabled); } - final Object trafficEnabled = data.get("trafficEnabled"); + final Boolean trafficEnabled = config.getTrafficEnabled(); if (trafficEnabled != null) { - sink.setTrafficEnabled(toBoolean(trafficEnabled)); + sink.setTrafficEnabled(trafficEnabled); } - final Object buildingsEnabled = data.get("buildingsEnabled"); + final Boolean buildingsEnabled = config.getBuildingsEnabled(); if (buildingsEnabled != null) { - sink.setBuildingsEnabled(toBoolean(buildingsEnabled)); + sink.setBuildingsEnabled(buildingsEnabled); } - final Object style = data.get("style"); + final String style = config.getStyle(); if (style != null) { - sink.setMapStyle(toString(style)); + sink.setMapStyle(style); } } /** Set the options in the given object to marker options sink. */ static void interpretMarkerOptions( - Object o, MarkerOptionsSink sink, AssetManager assetManager, float density) { - final Map data = toMap(o); - final Object alpha = data.get("alpha"); - if (alpha != null) { - sink.setAlpha(toFloat(alpha)); - } - final Object anchor = data.get("anchor"); - if (anchor != null) { - final List anchorData = toList(anchor); - sink.setAnchor(toFloat(anchorData.get(0)), toFloat(anchorData.get(1))); - } - final Object consumeTapEvents = data.get("consumeTapEvents"); - if (consumeTapEvents != null) { - sink.setConsumeTapEvents(toBoolean(consumeTapEvents)); - } - final Object draggable = data.get("draggable"); - if (draggable != null) { - sink.setDraggable(toBoolean(draggable)); - } - final Object flat = data.get("flat"); - if (flat != null) { - sink.setFlat(toBoolean(flat)); - } - final Object icon = data.get("icon"); - if (icon != null) { - sink.setIcon(toBitmapDescriptor(icon, assetManager, density)); - } - - final Object infoWindow = data.get("infoWindow"); - if (infoWindow != null) { - interpretInfoWindowOptions(sink, toObjectMap(infoWindow)); - } - final Object position = data.get("position"); - if (position != null) { - sink.setPosition(toLatLng(position)); - } - final Object rotation = data.get("rotation"); - if (rotation != null) { - sink.setRotation(toFloat(rotation)); - } - final Object visible = data.get("visible"); - if (visible != null) { - sink.setVisible(toBoolean(visible)); - } - final Object zIndex = data.get("zIndex"); - if (zIndex != null) { - sink.setZIndex(toFloat(zIndex)); - } + Messages.PlatformMarker marker, + MarkerOptionsSink sink, + AssetManager assetManager, + float density, + BitmapDescriptorFactoryWrapper wrapper) { + sink.setAlpha(marker.getAlpha().floatValue()); + sink.setAnchor(marker.getAnchor().getX().floatValue(), marker.getAnchor().getY().floatValue()); + sink.setConsumeTapEvents(marker.getConsumeTapEvents()); + sink.setDraggable(marker.getDraggable()); + sink.setFlat(marker.getFlat()); + sink.setIcon(toBitmapDescriptor(marker.getIcon(), assetManager, density, wrapper)); + interpretInfoWindowOptions(sink, marker.getInfoWindow()); + sink.setPosition(toLatLng(marker.getPosition().toList())); + sink.setRotation(marker.getRotation().floatValue()); + sink.setVisible(marker.getVisible()); + sink.setZIndex(marker.getZIndex().floatValue()); } private static void interpretInfoWindowOptions( - MarkerOptionsSink sink, Map infoWindow) { - String title = (String) infoWindow.get("title"); - String snippet = (String) infoWindow.get("snippet"); - // snippet is nullable. + MarkerOptionsSink sink, Messages.PlatformInfoWindow infoWindow) { + String title = infoWindow.getTitle(); if (title != null) { - sink.setInfoWindowText(title, snippet); - } - Object infoWindowAnchor = infoWindow.get("anchor"); - if (infoWindowAnchor != null) { - final List anchorData = toList(infoWindowAnchor); - sink.setInfoWindowAnchor(toFloat(anchorData.get(0)), toFloat(anchorData.get(1))); + sink.setInfoWindowText(title, infoWindow.getSnippet()); } + Messages.PlatformDoublePair infoWindowAnchor = infoWindow.getAnchor(); + sink.setInfoWindowAnchor( + infoWindowAnchor.getX().floatValue(), infoWindowAnchor.getY().floatValue()); } - static String interpretPolygonOptions(Object o, PolygonOptionsSink sink) { - final Map data = toMap(o); - final Object consumeTapEvents = data.get("consumeTapEvents"); - if (consumeTapEvents != null) { - sink.setConsumeTapEvents(toBoolean(consumeTapEvents)); - } - final Object geodesic = data.get("geodesic"); - if (geodesic != null) { - sink.setGeodesic(toBoolean(geodesic)); - } - final Object visible = data.get("visible"); - if (visible != null) { - sink.setVisible(toBoolean(visible)); - } - final Object fillColor = data.get("fillColor"); - if (fillColor != null) { - sink.setFillColor(toInt(fillColor)); - } - final Object strokeColor = data.get("strokeColor"); - if (strokeColor != null) { - sink.setStrokeColor(toInt(strokeColor)); - } - final Object strokeWidth = data.get("strokeWidth"); - if (strokeWidth != null) { - sink.setStrokeWidth(toInt(strokeWidth)); - } - final Object zIndex = data.get("zIndex"); - if (zIndex != null) { - sink.setZIndex(toFloat(zIndex)); - } - final Object points = data.get("points"); - if (points != null) { - sink.setPoints(toPoints(points)); - } - final Object holes = data.get("holes"); - if (holes != null) { - sink.setHoles(toHoles(holes)); - } - final String polygonId = (String) data.get("polygonId"); - if (polygonId == null) { - throw new IllegalArgumentException("polygonId was null"); - } else { - return polygonId; + static String interpretPolygonOptions(Messages.PlatformPolygon polygon, PolygonOptionsSink sink) { + sink.setConsumeTapEvents(polygon.getConsumesTapEvents()); + sink.setGeodesic(polygon.getGeodesic()); + sink.setVisible(polygon.getVisible()); + sink.setFillColor(polygon.getFillColor().intValue()); + sink.setStrokeColor(polygon.getStrokeColor().intValue()); + sink.setStrokeWidth(polygon.getStrokeWidth()); + sink.setZIndex(polygon.getZIndex()); + sink.setPoints(pointsFromPigeon(polygon.getPoints())); + sink.setHoles(toHoles(polygon.getHoles())); + return polygon.getPolygonId(); + } + + static int jointTypeFromPigeon(Messages.PlatformJointType jointType) { + switch (jointType) { + case MITERED: + return JointType.DEFAULT; + case BEVEL: + return JointType.BEVEL; + case ROUND: + return JointType.ROUND; } + return JointType.DEFAULT; } static String interpretPolylineOptions( - Object o, PolylineOptionsSink sink, AssetManager assetManager, float density) { - final Map data = toMap(o); - final Object consumeTapEvents = data.get("consumeTapEvents"); - if (consumeTapEvents != null) { - sink.setConsumeTapEvents(toBoolean(consumeTapEvents)); - } - final Object color = data.get("color"); - if (color != null) { - sink.setColor(toInt(color)); - } - final Object endCap = data.get("endCap"); - if (endCap != null) { - sink.setEndCap(toCap(endCap, assetManager, density)); - } - final Object geodesic = data.get("geodesic"); - if (geodesic != null) { - sink.setGeodesic(toBoolean(geodesic)); - } - final Object jointType = data.get("jointType"); - if (jointType != null) { - sink.setJointType(toInt(jointType)); - } - final Object startCap = data.get("startCap"); - if (startCap != null) { - sink.setStartCap(toCap(startCap, assetManager, density)); - } - final Object visible = data.get("visible"); - if (visible != null) { - sink.setVisible(toBoolean(visible)); - } - final Object width = data.get("width"); - if (width != null) { - sink.setWidth(toInt(width)); - } - final Object zIndex = data.get("zIndex"); - if (zIndex != null) { - sink.setZIndex(toFloat(zIndex)); - } - final Object points = data.get("points"); - if (points != null) { - sink.setPoints(toPoints(points)); - } - final Object pattern = data.get("pattern"); - if (pattern != null) { - sink.setPattern(toPattern(pattern)); - } - final String polylineId = (String) data.get("polylineId"); - if (polylineId == null) { - throw new IllegalArgumentException("polylineId was null"); - } else { - return polylineId; - } + Messages.PlatformPolyline polyline, + PolylineOptionsSink sink, + AssetManager assetManager, + float density) { + sink.setConsumeTapEvents(polyline.getConsumesTapEvents()); + sink.setColor(polyline.getColor().intValue()); + sink.setEndCap(capFromPigeon(polyline.getEndCap(), assetManager, density)); + sink.setStartCap(capFromPigeon(polyline.getStartCap(), assetManager, density)); + sink.setGeodesic(polyline.getGeodesic()); + sink.setJointType(jointTypeFromPigeon(polyline.getJointType())); + sink.setVisible(polyline.getVisible()); + sink.setWidth(polyline.getWidth()); + sink.setZIndex(polyline.getZIndex()); + sink.setPoints(pointsFromPigeon(polyline.getPoints())); + sink.setPattern(patternFromPigeon(polyline.getPatterns())); + return polyline.getPolylineId(); + } + + static String interpretCircleOptions(Messages.PlatformCircle circle, CircleOptionsSink sink) { + sink.setConsumeTapEvents(circle.getConsumeTapEvents()); + sink.setFillColor(circle.getFillColor().intValue()); + sink.setStrokeColor(circle.getStrokeColor().intValue()); + sink.setStrokeWidth(circle.getStrokeWidth()); + sink.setZIndex(circle.getZIndex().floatValue()); + sink.setCenter(toLatLng(circle.getCenter().toList())); + sink.setRadius(circle.getRadius()); + sink.setVisible(circle.getVisible()); + return circle.getCircleId(); } - static String interpretCircleOptions(Object o, CircleOptionsSink sink) { - final Map data = toMap(o); - final Object consumeTapEvents = data.get("consumeTapEvents"); - if (consumeTapEvents != null) { - sink.setConsumeTapEvents(toBoolean(consumeTapEvents)); - } - final Object fillColor = data.get("fillColor"); - if (fillColor != null) { - sink.setFillColor(toInt(fillColor)); - } - final Object strokeColor = data.get("strokeColor"); - if (strokeColor != null) { - sink.setStrokeColor(toInt(strokeColor)); - } - final Object visible = data.get("visible"); - if (visible != null) { - sink.setVisible(toBoolean(visible)); + /** + * Set the options in the given heatmap object to the given sink. + * + * @param data the object expected to be a Map containing the heatmap options. The options map is + * expected to have the following structure: + *

{@code
+   * {
+   *   "heatmapId": String,
+   *   "data": List, // List of serialized weighted lat/lng
+   *   "gradient": Map, // Serialized heatmap gradient
+   *   "maxIntensity": Double,
+   *   "opacity": Double,
+   *   "radius": Integer
+   * }
+   * }
+ * + * @param sink the HeatmapOptionsSink where the options will be set. + * @return the heatmapId. + * @throws IllegalArgumentException if heatmapId is null. + */ + static String interpretHeatmapOptions(Map data, HeatmapOptionsSink sink) { + final Object rawWeightedData = data.get(HEATMAP_DATA_KEY); + if (rawWeightedData != null) { + sink.setWeightedData(toWeightedData(rawWeightedData)); } - final Object strokeWidth = data.get("strokeWidth"); - if (strokeWidth != null) { - sink.setStrokeWidth(toInt(strokeWidth)); + final Object gradient = data.get(HEATMAP_GRADIENT_KEY); + if (gradient != null) { + sink.setGradient(toGradient(gradient)); } - final Object zIndex = data.get("zIndex"); - if (zIndex != null) { - sink.setZIndex(toFloat(zIndex)); + final Object maxIntensity = data.get(HEATMAP_MAX_INTENSITY_KEY); + if (maxIntensity != null) { + sink.setMaxIntensity(toDouble(maxIntensity)); } - final Object center = data.get("center"); - if (center != null) { - sink.setCenter(toLatLng(center)); + final Object opacity = data.get(HEATMAP_OPACITY_KEY); + if (opacity != null) { + sink.setOpacity(toDouble(opacity)); } - final Object radius = data.get("radius"); + final Object radius = data.get(HEATMAP_RADIUS_KEY); if (radius != null) { - sink.setRadius(toDouble(radius)); + sink.setRadius(toInt(radius)); } - final String circleId = (String) data.get("circleId"); - if (circleId == null) { - throw new IllegalArgumentException("circleId was null"); + final String heatmapId = (String) data.get(HEATMAP_ID_KEY); + if (heatmapId == null) { + throw new IllegalArgumentException("heatmapId was null"); } else { - return circleId; + return heatmapId; } } - @VisibleForTesting - static List toPoints(Object o) { - final List data = toList(o); + static List pointsFromPigeon(List data) { final List points = new ArrayList<>(data.size()); - for (Object rawPoint : data) { - final List point = toList(rawPoint); - points.add(new LatLng(toDouble(point.get(0)), toDouble(point.get(1)))); + for (Messages.PlatformLatLng rawPoint : data) { + points.add(new LatLng(rawPoint.getLatitude(), rawPoint.getLongitude())); } return points; } - private static List> toHoles(Object o) { + /** + * Converts the given object to a list of WeightedLatLng objects. + * + * @param o the object to convert. The object is expected to be a List of serialized weighted + * lat/lng. + * @return a list of WeightedLatLng objects. + */ + @VisibleForTesting + static List toWeightedData(Object o) { final List data = toList(o); - final List> holes = new ArrayList<>(data.size()); + final List weightedData = new ArrayList<>(data.size()); - for (Object rawHole : data) { - holes.add(toPoints(rawHole)); + for (Object rawWeightedPoint : data) { + weightedData.add(toWeightedLatLng(rawWeightedPoint)); } - return holes; + return weightedData; } - private static List toPattern(Object o) { - final List data = toList(o); + /** + * Converts the given object to a Gradient object. + * + * @param o the object to convert. The object is expected to be a Map containing the gradient + * options. The gradient map is expected to have the following structure: + *
{@code
+   * {
+   *   "colors": List,
+   *   "startPoints": List,
+   *   "colorMapSize": Integer
+   * }
+   * }
+ * + * @return a Gradient object. + */ + @VisibleForTesting + static Gradient toGradient(Object o) { + final Map data = toMap(o); - if (data.isEmpty()) { - return null; + final List colorData = toList(data.get(HEATMAP_GRADIENT_COLORS_KEY)); + assert colorData != null; + final int[] colors = new int[colorData.size()]; + for (int i = 0; i < colorData.size(); i++) { + colors[i] = toInt(colorData.get(i)); } - final List pattern = new ArrayList<>(data.size()); + final List startPointData = toList(data.get(HEATMAP_GRADIENT_START_POINTS_KEY)); + assert startPointData != null; + final float[] startPoints = new float[startPointData.size()]; + for (int i = 0; i < startPointData.size(); i++) { + startPoints[i] = toFloat(startPointData.get(i)); + } + + final int colorMapSize = toInt(data.get(HEATMAP_GRADIENT_COLOR_MAP_SIZE_KEY)); + + return new Gradient(colors, startPoints, colorMapSize); + } + + private static List> toHoles(List> data) { + final List> holes = new ArrayList<>(data.size()); + + for (List hole : data) { + holes.add(pointsFromPigeon(hole)); + } + return holes; + } - for (Object ob : data) { - final List patternItem = toList(ob); - switch (toString(patternItem.get(0))) { - case "dot": + private static List patternFromPigeon( + List patternItems) { + if (patternItems.isEmpty()) { + return null; + } + final List pattern = new ArrayList<>(); + for (Messages.PlatformPatternItem patternItem : patternItems) { + switch (patternItem.getType()) { + case DOT: pattern.add(new Dot()); break; - case "dash": - pattern.add(new Dash(toFloat(patternItem.get(1)))); + case DASH: + assert patternItem.getLength() != null; + pattern.add(new Dash(patternItem.getLength().floatValue())); break; - case "gap": - pattern.add(new Gap(toFloat(patternItem.get(1)))); + case GAP: + assert patternItem.getLength() != null; + pattern.add(new Gap(patternItem.getLength().floatValue())); break; - default: - throw new IllegalArgumentException("Cannot interpret " + pattern + " as PatternItem"); } } - return pattern; } - private static Cap toCap(Object o, AssetManager assetManager, float density) { - final List data = toList(o); - switch (toString(data.get(0))) { - case "buttCap": + private static Cap capFromPigeon( + Messages.PlatformCap cap, AssetManager assetManager, float density) { + switch (cap.getType()) { + case BUTT_CAP: return new ButtCap(); - case "roundCap": + case ROUND_CAP: return new RoundCap(); - case "squareCap": + case SQUARE_CAP: return new SquareCap(); - case "customCap": - if (data.size() == 2) { - return new CustomCap(toBitmapDescriptor(data.get(1), assetManager, density)); - } else { - return new CustomCap( - toBitmapDescriptor(data.get(1), assetManager, density), toFloat(data.get(2))); + case CUSTOM_CAP: + if (cap.getRefWidth() == null) { + throw new IllegalArgumentException("A Custom Cap must specify a refWidth value."); } - default: - throw new IllegalArgumentException("Cannot interpret " + o + " as Cap"); + return new CustomCap( + toBitmapDescriptor(cap.getBitmapDescriptor(), assetManager, density), + cap.getRefWidth().floatValue()); } + throw new IllegalArgumentException("Unrecognized PlatformCap type: " + cap.getType()); } - static String interpretTileOverlayOptions(Map data, TileOverlaySink sink) { - final Object fadeIn = data.get("fadeIn"); - if (fadeIn != null) { - sink.setFadeIn(toBoolean(fadeIn)); - } - final Object transparency = data.get("transparency"); - if (transparency != null) { - sink.setTransparency(toFloat(transparency)); - } - final Object zIndex = data.get("zIndex"); - if (zIndex != null) { - sink.setZIndex(toFloat(zIndex)); - } - final Object visible = data.get("visible"); - if (visible != null) { - sink.setVisible(toBoolean(visible)); - } - final String tileOverlayId = (String) data.get("tileOverlayId"); - if (tileOverlayId == null) { - throw new IllegalArgumentException("tileOverlayId was null"); - } else { - return tileOverlayId; - } + static String interpretTileOverlayOptions( + Messages.PlatformTileOverlay tileOverlay, TileOverlaySink sink) { + sink.setFadeIn(tileOverlay.getFadeIn()); + sink.setTransparency(tileOverlay.getTransparency().floatValue()); + sink.setZIndex(tileOverlay.getZIndex()); + sink.setVisible(tileOverlay.getVisible()); + return tileOverlay.getTileOverlayId(); } - static Tile interpretTile(Map data) { - int width = toInt(data.get("width")); - int height = toInt(data.get("height")); - byte[] dataArray = null; - if (data.get("data") != null) { - dataArray = (byte[]) data.get("data"); - } - return new Tile(width, height, dataArray); + static Tile tileFromPigeon(Messages.PlatformTile tile) { + return new Tile(tile.getWidth().intValue(), tile.getHeight().intValue(), tile.getData()); } - @VisibleForTesting static class BitmapDescriptorFactoryWrapper { /** * Creates a BitmapDescriptor from the provided asset key using the {@link diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java index 02477418d425..c7abcb2ff942 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java @@ -6,13 +6,13 @@ import android.content.Context; import android.graphics.Rect; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.google.android.gms.maps.GoogleMapOptions; import com.google.android.gms.maps.model.CameraPosition; import com.google.android.gms.maps.model.LatLngBounds; import io.flutter.plugin.common.BinaryMessenger; import java.util.List; -import java.util.Map; class GoogleMapBuilder implements GoogleMapOptionsSink { private final GoogleMapOptions options = new GoogleMapOptions(); @@ -22,12 +22,13 @@ class GoogleMapBuilder implements GoogleMapOptionsSink { private boolean indoorEnabled = true; private boolean trafficEnabled = false; private boolean buildingsEnabled = true; - private Object initialMarkers; - private Object initialClusterManagers; - private Object initialPolygons; - private Object initialPolylines; - private Object initialCircles; - private List> initialTileOverlays; + private List initialMarkers; + private List initialClusterManagers; + private List initialPolygons; + private List initialPolylines; + private List initialCircles; + private List initialHeatmaps; + private List initialTileOverlays; private Rect padding = new Rect(0, 0, 0, 0); private @Nullable String style; @@ -50,6 +51,7 @@ GoogleMapController build( controller.setInitialPolygons(initialPolygons); controller.setInitialPolylines(initialPolylines); controller.setInitialCircles(initialCircles); + controller.setInitialHeatmaps(initialHeatmaps); controller.setPadding(padding.top, padding.left, padding.bottom, padding.right); controller.setInitialTileOverlays(initialTileOverlays); controller.setMapStyle(style); @@ -160,32 +162,38 @@ public void setMyLocationButtonEnabled(boolean myLocationButtonEnabled) { } @Override - public void setInitialMarkers(Object initialMarkers) { + public void setInitialMarkers(@NonNull List initialMarkers) { this.initialMarkers = initialMarkers; } @Override - public void setInitialClusterManagers(Object initialClusterManagers) { + public void setInitialClusterManagers( + @NonNull List initialClusterManagers) { this.initialClusterManagers = initialClusterManagers; } @Override - public void setInitialPolygons(Object initialPolygons) { + public void setInitialPolygons(@NonNull List initialPolygons) { this.initialPolygons = initialPolygons; } @Override - public void setInitialPolylines(Object initialPolylines) { + public void setInitialPolylines(@NonNull List initialPolylines) { this.initialPolylines = initialPolylines; } @Override - public void setInitialCircles(Object initialCircles) { + public void setInitialCircles(@NonNull List initialCircles) { this.initialCircles = initialCircles; } @Override - public void setInitialTileOverlays(List> initialTileOverlays) { + public void setInitialHeatmaps(@NonNull List initialHeatmaps) { + this.initialHeatmaps = initialHeatmaps; + } + + public void setInitialTileOverlays( + @NonNull List initialTileOverlays) { this.initialTileOverlays = initialTileOverlays; } diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java index e3eee3bc1a79..140938ea047c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java @@ -26,12 +26,10 @@ import androidx.lifecycle.DefaultLifecycleObserver; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleOwner; -import com.google.android.gms.maps.CameraUpdate; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.GoogleMapOptions; import com.google.android.gms.maps.MapView; import com.google.android.gms.maps.OnMapReadyCallback; -import com.google.android.gms.maps.model.CameraPosition; import com.google.android.gms.maps.model.Circle; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.LatLngBounds; @@ -45,18 +43,14 @@ import com.google.maps.android.collections.MarkerManager; import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.MethodCall; -import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.platform.PlatformView; import io.flutter.plugins.googlemaps.Messages.FlutterError; import io.flutter.plugins.googlemaps.Messages.MapsApi; +import io.flutter.plugins.googlemaps.Messages.MapsCallbackApi; import io.flutter.plugins.googlemaps.Messages.MapsInspectorApi; import java.io.ByteArrayOutputStream; import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.Set; @@ -70,13 +64,12 @@ class GoogleMapController GoogleMapOptionsSink, MapsApi, MapsInspectorApi, - MethodChannel.MethodCallHandler, OnMapReadyCallback, PlatformView { private static final String TAG = "GoogleMapController"; private final int id; - private final MethodChannel methodChannel; + private final MapsCallbackApi flutterApi; private final BinaryMessenger binaryMessenger; private final GoogleMapOptions options; @Nullable private MapView mapView; @@ -98,15 +91,17 @@ class GoogleMapController private final PolygonsController polygonsController; private final PolylinesController polylinesController; private final CirclesController circlesController; + private final HeatmapsController heatmapsController; private final TileOverlaysController tileOverlaysController; private MarkerManager markerManager; private MarkerManager.Collection markerCollection; - private List initialMarkers; - private List initialClusterManagers; - private List initialPolygons; - private List initialPolylines; - private List initialCircles; - private List> initialTileOverlays; + private @Nullable List initialMarkers; + private @Nullable List initialClusterManagers; + private @Nullable List initialPolygons; + private @Nullable List initialPolylines; + private @Nullable List initialCircles; + private @Nullable List initialHeatmaps; + private @Nullable List initialTileOverlays; // Null except between initialization and onMapReady. private @Nullable String initialMapStyle; private boolean lastSetStyleSucceeded; @@ -124,20 +119,24 @@ class GoogleMapController this.mapView = new MapView(context, options); this.density = context.getResources().getDisplayMetrics().density; this.binaryMessenger = binaryMessenger; - methodChannel = - new MethodChannel(binaryMessenger, "plugins.flutter.dev/google_maps_android_" + id); - methodChannel.setMethodCallHandler(this); + flutterApi = new MapsCallbackApi(binaryMessenger, Integer.toString(id)); MapsApi.setUp(binaryMessenger, Integer.toString(id), this); MapsInspectorApi.setUp(binaryMessenger, Integer.toString(id), this); AssetManager assetManager = context.getAssets(); this.lifecycleProvider = lifecycleProvider; - this.clusterManagersController = new ClusterManagersController(methodChannel, context); + this.clusterManagersController = new ClusterManagersController(flutterApi, context); this.markersController = - new MarkersController(methodChannel, clusterManagersController, assetManager, density); - this.polygonsController = new PolygonsController(methodChannel, density); - this.polylinesController = new PolylinesController(methodChannel, assetManager, density); - this.circlesController = new CirclesController(methodChannel, density); - this.tileOverlaysController = new TileOverlaysController(methodChannel); + new MarkersController( + flutterApi, + clusterManagersController, + assetManager, + density, + new Convert.BitmapDescriptorFactoryWrapper()); + this.polygonsController = new PolygonsController(flutterApi, density); + this.polylinesController = new PolylinesController(flutterApi, assetManager, density); + this.circlesController = new CirclesController(flutterApi, density); + this.heatmapsController = new HeatmapsController(); + this.tileOverlaysController = new TileOverlaysController(flutterApi); } // Constructor for testing purposes only @@ -146,7 +145,7 @@ class GoogleMapController int id, Context context, BinaryMessenger binaryMessenger, - MethodChannel methodChannel, + MapsCallbackApi flutterApi, LifecycleProvider lifecycleProvider, GoogleMapOptions options, ClusterManagersController clusterManagersController, @@ -154,11 +153,12 @@ class GoogleMapController PolygonsController polygonsController, PolylinesController polylinesController, CirclesController circlesController, + HeatmapsController heatmapController, TileOverlaysController tileOverlaysController) { this.id = id; this.context = context; this.binaryMessenger = binaryMessenger; - this.methodChannel = methodChannel; + this.flutterApi = flutterApi; this.options = options; this.mapView = new MapView(context, options); this.density = context.getResources().getDisplayMetrics().density; @@ -168,6 +168,7 @@ class GoogleMapController this.polygonsController = polygonsController; this.polylinesController = polylinesController; this.circlesController = circlesController; + this.heatmapsController = heatmapController; this.tileOverlaysController = tileOverlaysController; } @@ -186,18 +187,6 @@ void init() { mapView.getMapAsync(this); } - private void moveCamera(CameraUpdate cameraUpdate) { - googleMap.moveCamera(cameraUpdate); - } - - private void animateCamera(CameraUpdate cameraUpdate) { - googleMap.animateCamera(cameraUpdate); - } - - private CameraPosition getCameraPosition() { - return trackCameraPosition ? googleMap.getCameraPosition() : null; - } - @Override public void onMapReady(@NonNull GoogleMap googleMap) { this.googleMap = googleMap; @@ -218,6 +207,7 @@ public void onMapReady(@NonNull GoogleMap googleMap) { polygonsController.setGoogleMap(googleMap); polylinesController.setGoogleMap(googleMap); circlesController.setGoogleMap(googleMap); + heatmapsController.setGoogleMap(googleMap); tileOverlaysController.setGoogleMap(googleMap); setMarkerCollectionListener(this); setClusterItemClickListener(this); @@ -227,6 +217,7 @@ public void onMapReady(@NonNull GoogleMap googleMap) { updateInitialPolygons(); updateInitialPolylines(); updateInitialCircles(); + updateInitialHeatmaps(); updateInitialTileOverlays(); if (initialPadding != null && initialPadding.size() == 4) { setPadding( @@ -308,124 +299,19 @@ public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) { }); } - @Override - public void onMethodCall(MethodCall call, @NonNull MethodChannel.Result result) { - switch (call.method) { - case "map#update": - { - Convert.interpretGoogleMapOptions(call.argument("options"), this); - result.success(Convert.cameraPositionToJson(getCameraPosition())); - break; - } - case "camera#move": - { - final CameraUpdate cameraUpdate = - Convert.toCameraUpdate(call.argument("cameraUpdate"), density); - moveCamera(cameraUpdate); - result.success(null); - break; - } - case "camera#animate": - { - final CameraUpdate cameraUpdate = - Convert.toCameraUpdate(call.argument("cameraUpdate"), density); - animateCamera(cameraUpdate); - result.success(null); - break; - } - case "markers#update": - { - List markersToAdd = call.argument("markersToAdd"); - markersController.addMarkers(markersToAdd); - List markersToChange = call.argument("markersToChange"); - markersController.changeMarkers(markersToChange); - List markerIdsToRemove = call.argument("markerIdsToRemove"); - markersController.removeMarkers(markerIdsToRemove); - result.success(null); - break; - } - case "clusterManagers#update": - { - List clusterManagersToAdd = call.argument("clusterManagersToAdd"); - if (clusterManagersToAdd != null) { - clusterManagersController.addClusterManagers(clusterManagersToAdd); - } - List clusterManagerIdsToRemove = call.argument("clusterManagerIdsToRemove"); - if (clusterManagerIdsToRemove != null) { - clusterManagersController.removeClusterManagers(clusterManagerIdsToRemove); - } - result.success(null); - break; - } - case "polygons#update": - { - List polygonsToAdd = call.argument("polygonsToAdd"); - polygonsController.addPolygons(polygonsToAdd); - List polygonsToChange = call.argument("polygonsToChange"); - polygonsController.changePolygons(polygonsToChange); - List polygonIdsToRemove = call.argument("polygonIdsToRemove"); - polygonsController.removePolygons(polygonIdsToRemove); - result.success(null); - break; - } - case "polylines#update": - { - List polylinesToAdd = call.argument("polylinesToAdd"); - polylinesController.addPolylines(polylinesToAdd); - List polylinesToChange = call.argument("polylinesToChange"); - polylinesController.changePolylines(polylinesToChange); - List polylineIdsToRemove = call.argument("polylineIdsToRemove"); - polylinesController.removePolylines(polylineIdsToRemove); - result.success(null); - break; - } - case "circles#update": - { - List circlesToAdd = call.argument("circlesToAdd"); - circlesController.addCircles(circlesToAdd); - List circlesToChange = call.argument("circlesToChange"); - circlesController.changeCircles(circlesToChange); - List circleIdsToRemove = call.argument("circleIdsToRemove"); - circlesController.removeCircles(circleIdsToRemove); - result.success(null); - break; - } - case "tileOverlays#update": - { - List> tileOverlaysToAdd = call.argument("tileOverlaysToAdd"); - tileOverlaysController.addTileOverlays(tileOverlaysToAdd); - List> tileOverlaysToChange = call.argument("tileOverlaysToChange"); - tileOverlaysController.changeTileOverlays(tileOverlaysToChange); - List tileOverlaysToRemove = call.argument("tileOverlayIdsToRemove"); - tileOverlaysController.removeTileOverlays(tileOverlaysToRemove); - result.success(null); - break; - } - default: - result.notImplemented(); - } - } - @Override public void onMapClick(@NonNull LatLng latLng) { - final Map arguments = new HashMap<>(2); - arguments.put("position", Convert.latLngToJson(latLng)); - methodChannel.invokeMethod("map#onTap", arguments); + flutterApi.onTap(Convert.latLngToPigeon(latLng), new NoOpVoidResult()); } @Override public void onMapLongClick(@NonNull LatLng latLng) { - final Map arguments = new HashMap<>(2); - arguments.put("position", Convert.latLngToJson(latLng)); - methodChannel.invokeMethod("map#onLongPress", arguments); + flutterApi.onLongPress(Convert.latLngToPigeon(latLng), new NoOpVoidResult()); } @Override public void onCameraMoveStarted(int reason) { - final Map arguments = new HashMap<>(2); - boolean isGesture = reason == GoogleMap.OnCameraMoveStartedListener.REASON_GESTURE; - arguments.put("isGesture", isGesture); - methodChannel.invokeMethod("camera#onMoveStarted", arguments); + flutterApi.onCameraMoveStarted(new NoOpVoidResult()); } @Override @@ -438,15 +324,14 @@ public void onCameraMove() { if (!trackCameraPosition) { return; } - final Map arguments = new HashMap<>(2); - arguments.put("position", Convert.cameraPositionToJson(googleMap.getCameraPosition())); - methodChannel.invokeMethod("camera#onMove", arguments); + flutterApi.onCameraMove( + Convert.cameraPositionToPigeon(googleMap.getCameraPosition()), new NoOpVoidResult()); } @Override public void onCameraIdle() { clusterManagersController.onCameraIdle(); - methodChannel.invokeMethod("camera#onIdle", Collections.singletonMap("map", id)); + flutterApi.onCameraIdle(new NoOpVoidResult()); } @Override @@ -490,7 +375,6 @@ public void dispose() { return; } disposed = true; - methodChannel.setMethodCallHandler(null); MapsApi.setUp(binaryMessenger, Integer.toString(id), null); MapsInspectorApi.setUp(binaryMessenger, Integer.toString(id), null); setGoogleMapListener(null); @@ -744,22 +628,23 @@ public void setZoomControlsEnabled(boolean zoomControlsEnabled) { } @Override - public void setInitialMarkers(Object initialMarkers) { - ArrayList markers = (ArrayList) initialMarkers; - this.initialMarkers = markers != null ? new ArrayList<>(markers) : null; + public void setInitialMarkers(@NonNull List initialMarkers) { + this.initialMarkers = initialMarkers; if (googleMap != null) { updateInitialMarkers(); } } private void updateInitialMarkers() { - markersController.addMarkers(initialMarkers); + if (initialMarkers != null) { + markersController.addMarkers(initialMarkers); + } } @Override - public void setInitialClusterManagers(Object initialClusterManagers) { - ArrayList clusterManagers = (ArrayList) initialClusterManagers; - this.initialClusterManagers = clusterManagers != null ? new ArrayList<>(clusterManagers) : null; + public void setInitialClusterManagers( + @NonNull List initialClusterManagers) { + this.initialClusterManagers = initialClusterManagers; if (googleMap != null) { updateInitialClusterManagers(); } @@ -772,46 +657,64 @@ private void updateInitialClusterManagers() { } @Override - public void setInitialPolygons(Object initialPolygons) { - ArrayList polygons = (ArrayList) initialPolygons; - this.initialPolygons = polygons != null ? new ArrayList<>(polygons) : null; + public void setInitialPolygons(@NonNull List initialPolygons) { + this.initialPolygons = initialPolygons; if (googleMap != null) { updateInitialPolygons(); } } private void updateInitialPolygons() { - polygonsController.addPolygons(initialPolygons); + if (initialPolygons != null) { + polygonsController.addPolygons(initialPolygons); + } } @Override - public void setInitialPolylines(Object initialPolylines) { - ArrayList polylines = (ArrayList) initialPolylines; - this.initialPolylines = polylines != null ? new ArrayList<>(polylines) : null; + public void setInitialPolylines(@NonNull List initialPolylines) { + this.initialPolylines = initialPolylines; if (googleMap != null) { updateInitialPolylines(); } } private void updateInitialPolylines() { - polylinesController.addPolylines(initialPolylines); + if (initialPolylines != null) { + polylinesController.addPolylines(initialPolylines); + } } @Override - public void setInitialCircles(Object initialCircles) { - ArrayList circles = (ArrayList) initialCircles; - this.initialCircles = circles != null ? new ArrayList<>(circles) : null; + public void setInitialCircles(@NonNull List initialCircles) { + this.initialCircles = initialCircles; if (googleMap != null) { updateInitialCircles(); } } + @Override + public void setInitialHeatmaps(@NonNull List initialHeatmaps) { + this.initialHeatmaps = initialHeatmaps; + if (googleMap != null) { + updateInitialHeatmaps(); + } + } + private void updateInitialCircles() { - circlesController.addCircles(initialCircles); + if (initialCircles != null) { + circlesController.addCircles(initialCircles); + } + } + + private void updateInitialHeatmaps() { + if (initialHeatmaps != null) { + heatmapsController.addHeatmaps(initialHeatmaps); + } } @Override - public void setInitialTileOverlays(List> initialTileOverlays) { + public void setInitialTileOverlays( + @NonNull List initialTileOverlays) { this.initialTileOverlays = initialTileOverlays; if (googleMap != null) { updateInitialTileOverlays(); @@ -819,7 +722,9 @@ public void setInitialTileOverlays(List> initialTileOverlays) { } private void updateInitialTileOverlays() { - tileOverlaysController.addTileOverlays(initialTileOverlays); + if (initialTileOverlays != null) { + tileOverlaysController.addTileOverlays(initialTileOverlays); + } } @SuppressLint("MissingPermission") @@ -914,6 +819,78 @@ public void waitForMap(@NonNull Messages.VoidResult result) { } } + @Override + public void updateMapConfiguration(@NonNull Messages.PlatformMapConfiguration configuration) { + Convert.interpretMapConfiguration(configuration, this); + } + + @Override + public void updateCircles( + @NonNull List toAdd, + @NonNull List toChange, + @NonNull List idsToRemove) { + circlesController.addCircles(toAdd); + circlesController.changeCircles(toChange); + circlesController.removeCircles(idsToRemove); + } + + @Override + public void updateHeatmaps( + @NonNull List toAdd, + @NonNull List toChange, + @NonNull List idsToRemove) { + heatmapsController.addHeatmaps(toAdd); + heatmapsController.changeHeatmaps(toChange); + heatmapsController.removeHeatmaps(idsToRemove); + } + + @Override + public void updateClusterManagers( + @NonNull List toAdd, @NonNull List idsToRemove) { + clusterManagersController.addClusterManagers(toAdd); + clusterManagersController.removeClusterManagers(idsToRemove); + } + + @Override + public void updateMarkers( + @NonNull List toAdd, + @NonNull List toChange, + @NonNull List idsToRemove) { + markersController.addMarkers(toAdd); + markersController.changeMarkers(toChange); + markersController.removeMarkers(idsToRemove); + } + + @Override + public void updatePolygons( + @NonNull List toAdd, + @NonNull List toChange, + @NonNull List idsToRemove) { + polygonsController.addPolygons(toAdd); + polygonsController.changePolygons(toChange); + polygonsController.removePolygons(idsToRemove); + } + + @Override + public void updatePolylines( + @NonNull List toAdd, + @NonNull List toChange, + @NonNull List idsToRemove) { + polylinesController.addPolylines(toAdd); + polylinesController.changePolylines(toChange); + polylinesController.removePolylines(idsToRemove); + } + + @Override + public void updateTileOverlays( + @NonNull List toAdd, + @NonNull List toChange, + @NonNull List idsToRemove) { + tileOverlaysController.addTileOverlays(toAdd); + tileOverlaysController.changeTileOverlays(toChange); + tileOverlaysController.removeTileOverlays(idsToRemove); + } + @Override public @NonNull Messages.PlatformPoint getScreenCoordinate( @NonNull Messages.PlatformLatLng latLng) { @@ -950,6 +927,24 @@ public void waitForMap(@NonNull Messages.VoidResult result) { return Convert.latLngBoundsToPigeon(latLngBounds); } + @Override + public void moveCamera(@NonNull Messages.PlatformCameraUpdate cameraUpdate) { + if (googleMap == null) { + throw new FlutterError( + "GoogleMap uninitialized", "moveCamera called prior to map initialization", null); + } + googleMap.moveCamera(Convert.cameraUpdateFromPigeon(cameraUpdate, density)); + } + + @Override + public void animateCamera(@NonNull Messages.PlatformCameraUpdate cameraUpdate) { + if (googleMap == null) { + throw new FlutterError( + "GoogleMap uninitialized", "animateCamera called prior to map initialization", null); + } + googleMap.animateCamera(Convert.cameraUpdateFromPigeon(cameraUpdate, density)); + } + @Override public @NonNull Double getZoomLevel() { if (googleMap == null) { diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java index b8d6485d35eb..c1a3496e7f47 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java @@ -9,11 +9,9 @@ import androidx.annotation.Nullable; import com.google.android.gms.maps.model.CameraPosition; import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.StandardMessageCodec; import io.flutter.plugin.platform.PlatformView; import io.flutter.plugin.platform.PlatformViewFactory; -import java.util.List; -import java.util.Map; +import java.util.Objects; public class GoogleMapFactory extends PlatformViewFactory { @@ -23,47 +21,35 @@ public class GoogleMapFactory extends PlatformViewFactory { GoogleMapFactory( BinaryMessenger binaryMessenger, Context context, LifecycleProvider lifecycleProvider) { - super(StandardMessageCodec.INSTANCE); + super(Messages.MapsApi.getCodec()); this.binaryMessenger = binaryMessenger; this.lifecycleProvider = lifecycleProvider; this.googleMapInitializer = new GoogleMapInitializer(context, binaryMessenger); } - @SuppressWarnings("unchecked") @Override @NonNull public PlatformView create(@NonNull Context context, int id, @Nullable Object args) { - Map params = (Map) args; + final Messages.PlatformMapViewCreationParams params = + Objects.requireNonNull((Messages.PlatformMapViewCreationParams) args); final GoogleMapBuilder builder = new GoogleMapBuilder(); - final Object options = params.get("options"); - Convert.interpretGoogleMapOptions(options, builder); - if (params.containsKey("initialCameraPosition")) { - CameraPosition position = Convert.toCameraPosition(params.get("initialCameraPosition")); - builder.setInitialCameraPosition(position); - } - if (params.containsKey("clusterManagersToAdd")) { - builder.setInitialClusterManagers(params.get("clusterManagersToAdd")); - } - if (params.containsKey("markersToAdd")) { - builder.setInitialMarkers(params.get("markersToAdd")); - } - if (params.containsKey("polygonsToAdd")) { - builder.setInitialPolygons(params.get("polygonsToAdd")); - } - if (params.containsKey("polylinesToAdd")) { - builder.setInitialPolylines(params.get("polylinesToAdd")); - } - if (params.containsKey("circlesToAdd")) { - builder.setInitialCircles(params.get("circlesToAdd")); - } - if (params.containsKey("tileOverlaysToAdd")) { - builder.setInitialTileOverlays((List>) params.get("tileOverlaysToAdd")); - } - final Object cloudMapId = ((Map) options).get("cloudMapId"); + final Messages.PlatformMapConfiguration mapConfig = params.getMapConfiguration(); + Convert.interpretMapConfiguration(mapConfig, builder); + CameraPosition position = Convert.cameraPositionFromPigeon(params.getInitialCameraPosition()); + builder.setInitialCameraPosition(position); + builder.setInitialClusterManagers(params.getInitialClusterManagers()); + builder.setInitialMarkers(params.getInitialMarkers()); + builder.setInitialPolygons(params.getInitialPolygons()); + builder.setInitialPolylines(params.getInitialPolylines()); + builder.setInitialCircles(params.getInitialCircles()); + builder.setInitialHeatmaps(params.getInitialHeatmaps()); + builder.setInitialTileOverlays(params.getInitialTileOverlays()); + + final String cloudMapId = mapConfig.getCloudMapId(); if (cloudMapId != null) { - builder.setMapId((String) cloudMapId); + builder.setMapId(cloudMapId); } return builder.build(id, context, binaryMessenger, lifecycleProvider); diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapInitializer.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapInitializer.java index a113c0a1c4c3..e4bea6b8ffa7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapInitializer.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapInitializer.java @@ -5,74 +5,39 @@ package io.flutter.plugins.googlemaps; import android.content.Context; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import com.google.android.gms.maps.MapsInitializer; -import com.google.android.gms.maps.MapsInitializer.Renderer; import com.google.android.gms.maps.OnMapsSdkInitializedCallback; import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.MethodCall; -import io.flutter.plugin.common.MethodChannel; /** GoogleMaps initializer used to initialize the Google Maps SDK with preferred settings. */ final class GoogleMapInitializer - implements OnMapsSdkInitializedCallback, MethodChannel.MethodCallHandler { - private final MethodChannel methodChannel; + implements OnMapsSdkInitializedCallback, Messages.MapsInitializerApi { private final Context context; - private static MethodChannel.Result initializationResult; + private static Messages.Result initializationResult; private boolean rendererInitialized = false; GoogleMapInitializer(Context context, BinaryMessenger binaryMessenger) { this.context = context; - methodChannel = - new MethodChannel(binaryMessenger, "plugins.flutter.dev/google_maps_android_initializer"); - methodChannel.setMethodCallHandler(this); + Messages.MapsInitializerApi.setUp(binaryMessenger, this); } @Override - public void onMethodCall(MethodCall call, MethodChannel.Result result) { - switch (call.method) { - case "initializer#preferRenderer": - { - String preferredRenderer = (String) call.argument("value"); - initializeWithPreferredRenderer(preferredRenderer, result); - break; - } - default: - result.notImplemented(); - } - } - - /** - * Initializes map renderer to with preferred renderer type. Renderer can be initialized only once - * per application context. - * - *

Supported renderer types are "latest", "legacy" and "default". - */ - private void initializeWithPreferredRenderer( - String preferredRenderer, MethodChannel.Result result) { + public void initializeWithPreferredRenderer( + @Nullable Messages.PlatformRendererType type, + @NonNull Messages.Result result) { if (rendererInitialized || initializationResult != null) { result.error( - "Renderer already initialized", "Renderer initialization called multiple times", null); + new Messages.FlutterError( + "Renderer already initialized", + "Renderer initialization called multiple times", + null)); } else { initializationResult = result; - switch (preferredRenderer) { - case "latest": - initializeWithRendererRequest(Renderer.LATEST); - break; - case "legacy": - initializeWithRendererRequest(Renderer.LEGACY); - break; - case "default": - initializeWithRendererRequest(null); - break; - default: - initializationResult.error( - "Invalid renderer type", - "Renderer initialization called with invalid renderer type", - null); - initializationResult = null; - } + initializeWithRendererRequest(Convert.toMapRendererType(type)); } } @@ -83,25 +48,28 @@ private void initializeWithPreferredRenderer( * class. */ @VisibleForTesting - public void initializeWithRendererRequest(MapsInitializer.Renderer renderer) { + public void initializeWithRendererRequest(@Nullable MapsInitializer.Renderer renderer) { MapsInitializer.initialize(context, renderer, this); } /** Is called by Google Maps SDK to determine which version of the renderer was initialized. */ @Override - public void onMapsSdkInitialized(MapsInitializer.Renderer renderer) { + public void onMapsSdkInitialized(@NonNull MapsInitializer.Renderer renderer) { rendererInitialized = true; if (initializationResult != null) { switch (renderer) { case LATEST: - initializationResult.success("latest"); + initializationResult.success(Messages.PlatformRendererType.LATEST); break; case LEGACY: - initializationResult.success("legacy"); + initializationResult.success(Messages.PlatformRendererType.LEGACY); break; default: initializationResult.error( - "Unknown renderer type", "Initialized with unknown renderer type", null); + new Messages.FlutterError( + "Unknown renderer type", + "Initialized with unknown renderer type", + renderer.name())); } initializationResult = null; } diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java index 9f744a653b3c..457508e83c5e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java @@ -4,10 +4,10 @@ package io.flutter.plugins.googlemaps; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.google.android.gms.maps.model.LatLngBounds; import java.util.List; -import java.util.Map; /** Receiver of GoogleMap configuration options. */ interface GoogleMapOptionsSink { @@ -47,17 +47,20 @@ interface GoogleMapOptionsSink { void setBuildingsEnabled(boolean buildingsEnabled); - void setInitialMarkers(Object initialMarkers); + void setInitialMarkers(@NonNull List initialMarkers); - void setInitialClusterManagers(Object initialClusterManagers); + void setInitialClusterManagers( + @NonNull List initialClusterManagers); - void setInitialPolygons(Object initialPolygons); + void setInitialPolygons(@NonNull List initialPolygons); - void setInitialPolylines(Object initialPolylines); + void setInitialPolylines(@NonNull List initialPolylines); - void setInitialCircles(Object initialCircles); + void setInitialCircles(@NonNull List initialCircles); - void setInitialTileOverlays(List> initialTileOverlays); + void setInitialHeatmaps(@NonNull List initialHeatmaps); + + void setInitialTileOverlays(@NonNull List initialTileOverlays); void setMapStyle(@Nullable String style); } diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/HeatmapBuilder.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/HeatmapBuilder.java new file mode 100644 index 000000000000..8b335951958b --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/HeatmapBuilder.java @@ -0,0 +1,51 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.googlemaps; + +import androidx.annotation.NonNull; +import com.google.maps.android.heatmaps.Gradient; +import com.google.maps.android.heatmaps.HeatmapTileProvider; +import com.google.maps.android.heatmaps.WeightedLatLng; +import java.util.List; + +/** Builder of a single Heatmap on the map. */ +public class HeatmapBuilder implements HeatmapOptionsSink { + private final HeatmapTileProvider.Builder heatmapOptions; + + /** Construct a HeatmapBuilder. */ + HeatmapBuilder() { + this.heatmapOptions = new HeatmapTileProvider.Builder(); + } + + /** Build the HeatmapTileProvider with the given options. */ + HeatmapTileProvider build() { + return heatmapOptions.build(); + } + + @Override + public void setWeightedData(@NonNull List weightedData) { + heatmapOptions.weightedData(weightedData); + } + + @Override + public void setGradient(@NonNull Gradient gradient) { + heatmapOptions.gradient(gradient); + } + + @Override + public void setMaxIntensity(double maxIntensity) { + heatmapOptions.maxIntensity(maxIntensity); + } + + @Override + public void setOpacity(double opacity) { + heatmapOptions.opacity(opacity); + } + + @Override + public void setRadius(int radius) { + heatmapOptions.radius(radius); + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/HeatmapController.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/HeatmapController.java new file mode 100644 index 000000000000..a2990e234293 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/HeatmapController.java @@ -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. + +package io.flutter.plugins.googlemaps; + +import androidx.annotation.NonNull; +import com.google.android.gms.maps.model.TileOverlay; +import com.google.maps.android.heatmaps.Gradient; +import com.google.maps.android.heatmaps.HeatmapTileProvider; +import com.google.maps.android.heatmaps.WeightedLatLng; +import java.util.List; + +/** Controller of a single Heatmap on the map. */ +public class HeatmapController implements HeatmapOptionsSink { + private final @NonNull HeatmapTileProvider heatmap; + private final @NonNull TileOverlay heatmapTileOverlay; + + /** Construct a HeatmapController with the given heatmap and heatmapTileOverlay. */ + HeatmapController(@NonNull HeatmapTileProvider heatmap, @NonNull TileOverlay heatmapTileOverlay) { + this.heatmap = heatmap; + this.heatmapTileOverlay = heatmapTileOverlay; + } + + /** Remove the heatmap from the map. */ + void remove() { + heatmapTileOverlay.remove(); + } + + /** Clear the tile cache of the heatmap in order to update the heatmap. */ + void clearTileCache() { + heatmapTileOverlay.clearTileCache(); + } + + @Override + public void setWeightedData(@NonNull List weightedData) { + heatmap.setWeightedData(weightedData); + } + + @Override + public void setGradient(@NonNull Gradient gradient) { + heatmap.setGradient(gradient); + } + + @Override + public void setMaxIntensity(double maxIntensity) { + heatmap.setMaxIntensity(maxIntensity); + } + + @Override + public void setOpacity(double opacity) { + heatmap.setOpacity(opacity); + } + + @Override + public void setRadius(int radius) { + heatmap.setRadius(radius); + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/HeatmapOptionsSink.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/HeatmapOptionsSink.java new file mode 100644 index 000000000000..fc571665c7d2 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/HeatmapOptionsSink.java @@ -0,0 +1,28 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.googlemaps; + +import androidx.annotation.NonNull; +import com.google.maps.android.heatmaps.Gradient; +import com.google.maps.android.heatmaps.WeightedLatLng; +import java.util.List; + +/** Receiver of Heatmap configuration options. */ +interface HeatmapOptionsSink { + /** Set the weighted data to be used to generate the heatmap. */ + void setWeightedData(@NonNull List weightedData); + + /** Set the gradient to be used to color the heatmap. */ + void setGradient(@NonNull Gradient gradient); + + /** Set the maximum intensity for the heatmap. */ + void setMaxIntensity(double maxIntensity); + + /** Set the opacity of the heatmap. */ + void setOpacity(double opacity); + + /** Set the radius of the heatmap. */ + void setRadius(int radius); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/HeatmapsController.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/HeatmapsController.java new file mode 100644 index 000000000000..4bb85fbbe8f0 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/HeatmapsController.java @@ -0,0 +1,103 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.googlemaps; + +import static io.flutter.plugins.googlemaps.Convert.HEATMAP_ID_KEY; + +import androidx.annotation.NonNull; +import androidx.annotation.VisibleForTesting; +import com.google.android.gms.maps.GoogleMap; +import com.google.android.gms.maps.model.TileOverlay; +import com.google.android.gms.maps.model.TileOverlayOptions; +import com.google.maps.android.heatmaps.HeatmapTileProvider; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** Controller of multiple Heatmaps on the map. */ +public class HeatmapsController { + /** Mapping from Heatmap ID to HeatmapController. */ + private final Map heatmapIdToController; + /** The GoogleMap to which the heatmaps are added. */ + private GoogleMap googleMap; + + /** Constructs a HeatmapsController. */ + HeatmapsController() { + this.heatmapIdToController = new HashMap<>(); + } + + /** Sets the GoogleMap to which the heatmaps are added. */ + void setGoogleMap(GoogleMap googleMap) { + this.googleMap = googleMap; + } + + /** Adds heatmaps to the map. */ + void addHeatmaps(@NonNull List heatmapsToAdd) { + for (Messages.PlatformHeatmap heatmapToAdd : heatmapsToAdd) { + addJsonHeatmap(heatmapToAdd.getJson()); + } + } + + /** Updates the given heatmaps on the map. */ + void changeHeatmaps(@NonNull List heatmapsToChange) { + for (Messages.PlatformHeatmap heatmapToChange : heatmapsToChange) { + changeJsonHeatmap(heatmapToChange.getJson()); + } + } + + /** Removes heatmaps with the given ids from the map. */ + void removeHeatmaps(@NonNull List heatmapIdsToRemove) { + for (String heatmapId : heatmapIdsToRemove) { + HeatmapController heatmapController = heatmapIdToController.remove(heatmapId); + if (heatmapController != null) { + heatmapController.remove(); + heatmapIdToController.remove(heatmapId); + } + } + } + + /** Builds the heatmap. This method exists to allow mocking the HeatmapTileProvider in tests. */ + @VisibleForTesting + public @NonNull HeatmapTileProvider buildHeatmap(@NonNull HeatmapBuilder builder) { + return builder.build(); + } + + /** Adds a heatmap to the map from json data. */ + private void addJsonHeatmap(Map heatmap) { + if (heatmap == null) { + return; + } + HeatmapBuilder heatmapBuilder = new HeatmapBuilder(); + String heatmapId = Convert.interpretHeatmapOptions(heatmap, heatmapBuilder); + HeatmapTileProvider options = buildHeatmap(heatmapBuilder); + addHeatmap(heatmapId, options); + } + + /** Adds a heatmap to the map. */ + private void addHeatmap(String heatmapId, HeatmapTileProvider options) { + TileOverlay heatmapTileOverlay = + googleMap.addTileOverlay(new TileOverlayOptions().tileProvider(options)); + HeatmapController heatmapController = new HeatmapController(options, heatmapTileOverlay); + heatmapIdToController.put(heatmapId, heatmapController); + } + + /** Updates the given heatmap on the map. */ + private void changeJsonHeatmap(Map heatmap) { + if (heatmap == null) { + return; + } + String heatmapId = getHeatmapId(heatmap); + HeatmapController heatmapController = heatmapIdToController.get(heatmapId); + if (heatmapController != null) { + Convert.interpretHeatmapOptions(heatmap, heatmapController); + heatmapController.clearTileCache(); + } + } + + /** Returns the heatmap id from the given heatmap data. */ + private static String getHeatmapId(Map heatmap) { + return (String) heatmap.get(HEATMAP_ID_KEY); + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/MarkersController.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/MarkersController.java index 0f47fecaa500..24326fe53056 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/MarkersController.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/MarkersController.java @@ -5,69 +5,61 @@ package io.flutter.plugins.googlemaps; import android.content.res.AssetManager; +import androidx.annotation.NonNull; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.MarkerOptions; import com.google.maps.android.collections.MarkerManager; -import io.flutter.plugin.common.MethodChannel; +import io.flutter.plugins.googlemaps.Messages.MapsCallbackApi; import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Objects; class MarkersController { private final HashMap markerIdToMarkerBuilder; private final HashMap markerIdToController; private final HashMap googleMapsMarkerIdToDartMarkerId; - private final MethodChannel methodChannel; + private final @NonNull MapsCallbackApi flutterApi; private MarkerManager.Collection markerCollection; private final ClusterManagersController clusterManagersController; private final AssetManager assetManager; private final float density; + private final Convert.BitmapDescriptorFactoryWrapper bitmapDescriptorFactoryWrapper; MarkersController( - MethodChannel methodChannel, + @NonNull MapsCallbackApi flutterApi, ClusterManagersController clusterManagersController, AssetManager assetManager, - float density) { + float density, + Convert.BitmapDescriptorFactoryWrapper bitmapDescriptorFactoryWrapper) { this.markerIdToMarkerBuilder = new HashMap<>(); this.markerIdToController = new HashMap<>(); this.googleMapsMarkerIdToDartMarkerId = new HashMap<>(); - this.methodChannel = methodChannel; + this.flutterApi = flutterApi; this.clusterManagersController = clusterManagersController; this.assetManager = assetManager; this.density = density; + this.bitmapDescriptorFactoryWrapper = bitmapDescriptorFactoryWrapper; } void setCollection(MarkerManager.Collection markerCollection) { this.markerCollection = markerCollection; } - void addMarkers(List markersToAdd) { - if (markersToAdd != null) { - for (Object markerToAdd : markersToAdd) { - addMarker(markerToAdd); - } + void addMarkers(@NonNull List markersToAdd) { + for (Messages.PlatformMarker markerToAdd : markersToAdd) { + addMarker(markerToAdd); } } - void changeMarkers(List markersToChange) { - if (markersToChange != null) { - for (Object markerToChange : markersToChange) { - changeMarker(markerToChange); - } + void changeMarkers(@NonNull List markersToChange) { + for (Messages.PlatformMarker markerToChange : markersToChange) { + changeMarker(markerToChange); } } - void removeMarkers(List markerIdsToRemove) { - if (markerIdsToRemove == null) { - return; - } - for (Object rawMarkerId : markerIdsToRemove) { - if (rawMarkerId == null) { - continue; - } - String markerId = (String) rawMarkerId; + void removeMarkers(@NonNull List markerIdsToRemove) { + for (String markerId : markerIdsToRemove) { removeMarker(markerId); } } @@ -128,7 +120,7 @@ boolean onMapsMarkerTap(String googleMarkerId) { } boolean onMarkerTap(String markerId) { - methodChannel.invokeMethod("marker#onTap", Convert.markerIdToJson(markerId)); + flutterApi.onMarkerTap(markerId, new NoOpVoidResult()); MarkerController markerController = markerIdToController.get(markerId); if (markerController != null) { return markerController.consumeTapEvents(); @@ -141,10 +133,7 @@ void onMarkerDragStart(String googleMarkerId, LatLng latLng) { if (markerId == null) { return; } - final Map data = new HashMap<>(); - data.put("markerId", markerId); - data.put("position", Convert.latLngToJson(latLng)); - methodChannel.invokeMethod("marker#onDragStart", data); + flutterApi.onMarkerDragStart(markerId, Convert.latLngToPigeon(latLng), new NoOpVoidResult()); } void onMarkerDrag(String googleMarkerId, LatLng latLng) { @@ -152,10 +141,7 @@ void onMarkerDrag(String googleMarkerId, LatLng latLng) { if (markerId == null) { return; } - final Map data = new HashMap<>(); - data.put("markerId", markerId); - data.put("position", Convert.latLngToJson(latLng)); - methodChannel.invokeMethod("marker#onDrag", data); + flutterApi.onMarkerDrag(markerId, Convert.latLngToPigeon(latLng), new NoOpVoidResult()); } void onMarkerDragEnd(String googleMarkerId, LatLng latLng) { @@ -163,10 +149,7 @@ void onMarkerDragEnd(String googleMarkerId, LatLng latLng) { if (markerId == null) { return; } - final Map data = new HashMap<>(); - data.put("markerId", markerId); - data.put("position", Convert.latLngToJson(latLng)); - methodChannel.invokeMethod("marker#onDragEnd", data); + flutterApi.onMarkerDragEnd(markerId, Convert.latLngToPigeon(latLng), new NoOpVoidResult()); } void onInfoWindowTap(String googleMarkerId) { @@ -174,7 +157,7 @@ void onInfoWindowTap(String googleMarkerId) { if (markerId == null) { return; } - methodChannel.invokeMethod("infoWindow#onTap", Convert.markerIdToJson(markerId)); + flutterApi.onInfoWindowTap(markerId, new NoOpVoidResult()); } /** @@ -188,17 +171,12 @@ public void onClusterItemRendered(MarkerBuilder markerBuilder, Marker marker) { } } - private void addMarker(Object marker) { - if (marker == null) { - return; - } - String markerId = getMarkerId(marker); - if (markerId == null) { - throw new IllegalArgumentException("markerId was null"); - } - String clusterManagerId = getClusterManagerId(marker); + private void addMarker(@NonNull Messages.PlatformMarker marker) { + String markerId = marker.getMarkerId(); + String clusterManagerId = marker.getClusterManagerId(); MarkerBuilder markerBuilder = new MarkerBuilder(markerId, clusterManagerId); - Convert.interpretMarkerOptions(marker, markerBuilder, assetManager, density); + Convert.interpretMarkerOptions( + marker, markerBuilder, assetManager, density, bitmapDescriptorFactoryWrapper); addMarker(markerBuilder); } @@ -234,18 +212,15 @@ private void createControllerForMarker(String markerId, Marker marker, boolean c googleMapsMarkerIdToDartMarkerId.put(marker.getId(), markerId); } - private void changeMarker(Object marker) { - if (marker == null) { - return; - } - String markerId = getMarkerId(marker); + private void changeMarker(@NonNull Messages.PlatformMarker marker) { + String markerId = marker.getMarkerId(); MarkerBuilder markerBuilder = markerIdToMarkerBuilder.get(markerId); if (markerBuilder == null) { return; } - String clusterManagerId = getClusterManagerId(marker); + String clusterManagerId = marker.getClusterManagerId(); String oldClusterManagerId = markerBuilder.clusterManagerId(); // If the cluster ID on the updated marker has changed, the marker needs to @@ -257,24 +232,14 @@ private void changeMarker(Object marker) { } // Update marker builder. - Convert.interpretMarkerOptions(marker, markerBuilder, assetManager, density); + Convert.interpretMarkerOptions( + marker, markerBuilder, assetManager, density, bitmapDescriptorFactoryWrapper); // Update existing marker on map. MarkerController markerController = markerIdToController.get(markerId); if (markerController != null) { - Convert.interpretMarkerOptions(marker, markerController, assetManager, density); + Convert.interpretMarkerOptions( + marker, markerController, assetManager, density, bitmapDescriptorFactoryWrapper); } } - - @SuppressWarnings("unchecked") - private static String getMarkerId(Object marker) { - Map markerMap = (Map) marker; - return (String) markerMap.get("markerId"); - } - - @SuppressWarnings("unchecked") - private static String getClusterManagerId(Object marker) { - Map markerMap = (Map) marker; - return (String) markerMap.get("clusterManagerId"); - } } diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/Messages.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/Messages.java index 5c537c9c3bf4..4a9afeed6d04 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/Messages.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/Messages.java @@ -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 (v20.0.1), do not edit directly. +// Autogenerated from Pigeon (v22.6.0), do not edit directly. // See also: https://pub.dev/packages/pigeon package io.flutter.plugins.googlemaps; @@ -21,7 +21,11 @@ import java.lang.annotation.Target; import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.Objects; /** Generated class from Pigeon. */ @SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression", "serial"}) @@ -45,7 +49,7 @@ public FlutterError(@NonNull String code, @Nullable String message, @Nullable Ob @NonNull protected static ArrayList wrapError(@NonNull Throwable exception) { - ArrayList errorList = new ArrayList(3); + ArrayList errorList = new ArrayList<>(3); if (exception instanceof FlutterError) { FlutterError error = (FlutterError) exception; errorList.add(error.code); @@ -60,200 +64,476 @@ protected static ArrayList wrapError(@NonNull Throwable exception) { return errorList; } + @NonNull + protected static FlutterError createConnectionError(@NonNull String channelName) { + return new FlutterError( + "channel-error", "Unable to establish connection on channel: " + channelName + ".", ""); + } + @Target(METHOD) @Retention(CLASS) @interface CanIgnoreReturnValue {} + /** Pigeon equivalent of MapType */ + public enum PlatformMapType { + NONE(0), + NORMAL(1), + SATELLITE(2), + TERRAIN(3), + HYBRID(4); + + final int index; + + PlatformMapType(final int index) { + this.index = index; + } + } + + public enum PlatformRendererType { + LEGACY(0), + LATEST(1); + + final int index; + + PlatformRendererType(final int index) { + this.index = index; + } + } + + /** Join types for polyline joints. */ + public enum PlatformJointType { + MITERED(0), + BEVEL(1), + ROUND(2); + + final int index; + + PlatformJointType(final int index) { + this.index = index; + } + } + /** - * Pigeon equivalent of LatLng. + * Enumeration of possible types of PlatformCap, corresponding to the subclasses of Cap in the + * Google Maps Android SDK. See + * https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/Cap. + */ + public enum PlatformCapType { + BUTT_CAP(0), + ROUND_CAP(1), + SQUARE_CAP(2), + CUSTOM_CAP(3); + + final int index; + + PlatformCapType(final int index) { + this.index = index; + } + } + + /** Enumeration of possible types for PatternItem. */ + public enum PlatformPatternItemType { + DOT(0), + DASH(1), + GAP(2); + + final int index; + + PlatformPatternItemType(final int index) { + this.index = index; + } + } + + /** Pigeon equivalent of [MapBitmapScaling]. */ + public enum PlatformMapBitmapScaling { + AUTO(0), + NONE(1); + + final int index; + + PlatformMapBitmapScaling(final int index) { + this.index = index; + } + } + + /** + * Pigeon representatation of a CameraPosition. * *

Generated class from Pigeon that represents data sent in messages. */ - public static final class PlatformLatLng { - private @NonNull Double latitude; + public static final class PlatformCameraPosition { + private @NonNull Double bearing; - public @NonNull Double getLatitude() { - return latitude; + public @NonNull Double getBearing() { + return bearing; } - public void setLatitude(@NonNull Double setterArg) { + public void setBearing(@NonNull Double setterArg) { if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"latitude\" is null."); + throw new IllegalStateException("Nonnull field \"bearing\" is null."); } - this.latitude = setterArg; + this.bearing = setterArg; } - private @NonNull Double longitude; + private @NonNull PlatformLatLng target; - public @NonNull Double getLongitude() { - return longitude; + public @NonNull PlatformLatLng getTarget() { + return target; } - public void setLongitude(@NonNull Double setterArg) { + public void setTarget(@NonNull PlatformLatLng setterArg) { if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"longitude\" is null."); + throw new IllegalStateException("Nonnull field \"target\" is null."); } - this.longitude = setterArg; + this.target = setterArg; + } + + private @NonNull Double tilt; + + public @NonNull Double getTilt() { + return tilt; + } + + public void setTilt(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"tilt\" is null."); + } + this.tilt = setterArg; + } + + private @NonNull Double zoom; + + public @NonNull Double getZoom() { + return zoom; + } + + public void setZoom(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"zoom\" is null."); + } + this.zoom = setterArg; } /** Constructor is non-public to enforce null safety; use Builder. */ - PlatformLatLng() {} + PlatformCameraPosition() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformCameraPosition that = (PlatformCameraPosition) o; + return bearing.equals(that.bearing) + && target.equals(that.target) + && tilt.equals(that.tilt) + && zoom.equals(that.zoom); + } + + @Override + public int hashCode() { + return Objects.hash(bearing, target, tilt, zoom); + } public static final class Builder { - private @Nullable Double latitude; + private @Nullable Double bearing; @CanIgnoreReturnValue - public @NonNull Builder setLatitude(@NonNull Double setterArg) { - this.latitude = setterArg; + public @NonNull Builder setBearing(@NonNull Double setterArg) { + this.bearing = setterArg; return this; } - private @Nullable Double longitude; + private @Nullable PlatformLatLng target; @CanIgnoreReturnValue - public @NonNull Builder setLongitude(@NonNull Double setterArg) { - this.longitude = setterArg; + public @NonNull Builder setTarget(@NonNull PlatformLatLng setterArg) { + this.target = setterArg; return this; } - public @NonNull PlatformLatLng build() { - PlatformLatLng pigeonReturn = new PlatformLatLng(); - pigeonReturn.setLatitude(latitude); - pigeonReturn.setLongitude(longitude); + private @Nullable Double tilt; + + @CanIgnoreReturnValue + public @NonNull Builder setTilt(@NonNull Double setterArg) { + this.tilt = setterArg; + return this; + } + + private @Nullable Double zoom; + + @CanIgnoreReturnValue + public @NonNull Builder setZoom(@NonNull Double setterArg) { + this.zoom = setterArg; + return this; + } + + public @NonNull PlatformCameraPosition build() { + PlatformCameraPosition pigeonReturn = new PlatformCameraPosition(); + pigeonReturn.setBearing(bearing); + pigeonReturn.setTarget(target); + pigeonReturn.setTilt(tilt); + pigeonReturn.setZoom(zoom); return pigeonReturn; } } @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(2); - toListResult.add(latitude); - toListResult.add(longitude); + ArrayList toListResult = new ArrayList<>(4); + toListResult.add(bearing); + toListResult.add(target); + toListResult.add(tilt); + toListResult.add(zoom); return toListResult; } - static @NonNull PlatformLatLng fromList(@NonNull ArrayList __pigeon_list) { - PlatformLatLng pigeonResult = new PlatformLatLng(); - Object latitude = __pigeon_list.get(0); - pigeonResult.setLatitude((Double) latitude); - Object longitude = __pigeon_list.get(1); - pigeonResult.setLongitude((Double) longitude); + static @NonNull PlatformCameraPosition fromList(@NonNull ArrayList pigeonVar_list) { + PlatformCameraPosition pigeonResult = new PlatformCameraPosition(); + Object bearing = pigeonVar_list.get(0); + pigeonResult.setBearing((Double) bearing); + Object target = pigeonVar_list.get(1); + pigeonResult.setTarget((PlatformLatLng) target); + Object tilt = pigeonVar_list.get(2); + pigeonResult.setTilt((Double) tilt); + Object zoom = pigeonVar_list.get(3); + pigeonResult.setZoom((Double) zoom); return pigeonResult; } } /** - * Pigeon equivalent of LatLngBounds. + * Pigeon representation of a CameraUpdate. * *

Generated class from Pigeon that represents data sent in messages. */ - public static final class PlatformLatLngBounds { - private @NonNull PlatformLatLng northeast; + public static final class PlatformCameraUpdate { + /** + * This Object shall be any of the below classes prefixed with PlatformCameraUpdate. Each such + * class represents a different type of camera update, and each holds a different set of data, + * preventing the use of a single unified class. Pigeon does not support inheritance, which + * prevents a more strict type bound. See https://github.com/flutter/flutter/issues/117819. + */ + private @NonNull Object cameraUpdate; - public @NonNull PlatformLatLng getNortheast() { - return northeast; + public @NonNull Object getCameraUpdate() { + return cameraUpdate; } - public void setNortheast(@NonNull PlatformLatLng setterArg) { + public void setCameraUpdate(@NonNull Object setterArg) { if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"northeast\" is null."); + throw new IllegalStateException("Nonnull field \"cameraUpdate\" is null."); } - this.northeast = setterArg; + this.cameraUpdate = setterArg; } - private @NonNull PlatformLatLng southwest; - - public @NonNull PlatformLatLng getSouthwest() { - return southwest; - } + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformCameraUpdate() {} - public void setSouthwest(@NonNull PlatformLatLng setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"southwest\" is null."); + @Override + public boolean equals(Object o) { + if (this == o) { + return true; } - this.southwest = setterArg; + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformCameraUpdate that = (PlatformCameraUpdate) o; + return cameraUpdate.equals(that.cameraUpdate); } - /** Constructor is non-public to enforce null safety; use Builder. */ - PlatformLatLngBounds() {} + @Override + public int hashCode() { + return Objects.hash(cameraUpdate); + } public static final class Builder { - private @Nullable PlatformLatLng northeast; + private @Nullable Object cameraUpdate; @CanIgnoreReturnValue - public @NonNull Builder setNortheast(@NonNull PlatformLatLng setterArg) { - this.northeast = setterArg; + public @NonNull Builder setCameraUpdate(@NonNull Object setterArg) { + this.cameraUpdate = setterArg; return this; } - private @Nullable PlatformLatLng southwest; + public @NonNull PlatformCameraUpdate build() { + PlatformCameraUpdate pigeonReturn = new PlatformCameraUpdate(); + pigeonReturn.setCameraUpdate(cameraUpdate); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(1); + toListResult.add(cameraUpdate); + return toListResult; + } + + static @NonNull PlatformCameraUpdate fromList(@NonNull ArrayList pigeonVar_list) { + PlatformCameraUpdate pigeonResult = new PlatformCameraUpdate(); + Object cameraUpdate = pigeonVar_list.get(0); + pigeonResult.setCameraUpdate(cameraUpdate); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of NewCameraPosition + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformCameraUpdateNewCameraPosition { + private @NonNull PlatformCameraPosition cameraPosition; + + public @NonNull PlatformCameraPosition getCameraPosition() { + return cameraPosition; + } + + public void setCameraPosition(@NonNull PlatformCameraPosition setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"cameraPosition\" is null."); + } + this.cameraPosition = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformCameraUpdateNewCameraPosition() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformCameraUpdateNewCameraPosition that = (PlatformCameraUpdateNewCameraPosition) o; + return cameraPosition.equals(that.cameraPosition); + } + + @Override + public int hashCode() { + return Objects.hash(cameraPosition); + } + + public static final class Builder { + + private @Nullable PlatformCameraPosition cameraPosition; @CanIgnoreReturnValue - public @NonNull Builder setSouthwest(@NonNull PlatformLatLng setterArg) { - this.southwest = setterArg; + public @NonNull Builder setCameraPosition(@NonNull PlatformCameraPosition setterArg) { + this.cameraPosition = setterArg; return this; } - public @NonNull PlatformLatLngBounds build() { - PlatformLatLngBounds pigeonReturn = new PlatformLatLngBounds(); - pigeonReturn.setNortheast(northeast); - pigeonReturn.setSouthwest(southwest); + public @NonNull PlatformCameraUpdateNewCameraPosition build() { + PlatformCameraUpdateNewCameraPosition pigeonReturn = + new PlatformCameraUpdateNewCameraPosition(); + pigeonReturn.setCameraPosition(cameraPosition); return pigeonReturn; } } @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(2); - toListResult.add(northeast); - toListResult.add(southwest); + ArrayList toListResult = new ArrayList<>(1); + toListResult.add(cameraPosition); return toListResult; } - static @NonNull PlatformLatLngBounds fromList(@NonNull ArrayList __pigeon_list) { - PlatformLatLngBounds pigeonResult = new PlatformLatLngBounds(); - Object northeast = __pigeon_list.get(0); - pigeonResult.setNortheast((PlatformLatLng) northeast); - Object southwest = __pigeon_list.get(1); - pigeonResult.setSouthwest((PlatformLatLng) southwest); + static @NonNull PlatformCameraUpdateNewCameraPosition fromList( + @NonNull ArrayList pigeonVar_list) { + PlatformCameraUpdateNewCameraPosition pigeonResult = + new PlatformCameraUpdateNewCameraPosition(); + Object cameraPosition = pigeonVar_list.get(0); + pigeonResult.setCameraPosition((PlatformCameraPosition) cameraPosition); return pigeonResult; } } /** - * Pigeon equivalent of Cluster. + * Pigeon equivalent of NewLatLng * *

Generated class from Pigeon that represents data sent in messages. */ - public static final class PlatformCluster { - private @NonNull String clusterManagerId; + public static final class PlatformCameraUpdateNewLatLng { + private @NonNull PlatformLatLng latLng; - public @NonNull String getClusterManagerId() { - return clusterManagerId; + public @NonNull PlatformLatLng getLatLng() { + return latLng; } - public void setClusterManagerId(@NonNull String setterArg) { + public void setLatLng(@NonNull PlatformLatLng setterArg) { if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"clusterManagerId\" is null."); + throw new IllegalStateException("Nonnull field \"latLng\" is null."); } - this.clusterManagerId = setterArg; + this.latLng = setterArg; } - private @NonNull PlatformLatLng position; + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformCameraUpdateNewLatLng() {} - public @NonNull PlatformLatLng getPosition() { - return position; + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformCameraUpdateNewLatLng that = (PlatformCameraUpdateNewLatLng) o; + return latLng.equals(that.latLng); } - public void setPosition(@NonNull PlatformLatLng setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"position\" is null."); + @Override + public int hashCode() { + return Objects.hash(latLng); + } + + public static final class Builder { + + private @Nullable PlatformLatLng latLng; + + @CanIgnoreReturnValue + public @NonNull Builder setLatLng(@NonNull PlatformLatLng setterArg) { + this.latLng = setterArg; + return this; } - this.position = setterArg; + + public @NonNull PlatformCameraUpdateNewLatLng build() { + PlatformCameraUpdateNewLatLng pigeonReturn = new PlatformCameraUpdateNewLatLng(); + pigeonReturn.setLatLng(latLng); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(1); + toListResult.add(latLng); + return toListResult; + } + + static @NonNull PlatformCameraUpdateNewLatLng fromList( + @NonNull ArrayList pigeonVar_list) { + PlatformCameraUpdateNewLatLng pigeonResult = new PlatformCameraUpdateNewLatLng(); + Object latLng = pigeonVar_list.get(0); + pigeonResult.setLatLng((PlatformLatLng) latLng); + return pigeonResult; } + } + /** + * Pigeon equivalent of NewLatLngBounds + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformCameraUpdateNewLatLngBounds { private @NonNull PlatformLatLngBounds bounds; public @NonNull PlatformLatLngBounds getBounds() { @@ -267,39 +547,40 @@ public void setBounds(@NonNull PlatformLatLngBounds setterArg) { this.bounds = setterArg; } - private @NonNull List markerIds; + private @NonNull Double padding; - public @NonNull List getMarkerIds() { - return markerIds; + public @NonNull Double getPadding() { + return padding; } - public void setMarkerIds(@NonNull List setterArg) { + public void setPadding(@NonNull Double setterArg) { if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"markerIds\" is null."); + throw new IllegalStateException("Nonnull field \"padding\" is null."); } - this.markerIds = setterArg; + this.padding = setterArg; } /** Constructor is non-public to enforce null safety; use Builder. */ - PlatformCluster() {} + PlatformCameraUpdateNewLatLngBounds() {} - public static final class Builder { - - private @Nullable String clusterManagerId; - - @CanIgnoreReturnValue - public @NonNull Builder setClusterManagerId(@NonNull String setterArg) { - this.clusterManagerId = setterArg; - return this; + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; } + PlatformCameraUpdateNewLatLngBounds that = (PlatformCameraUpdateNewLatLngBounds) o; + return bounds.equals(that.bounds) && padding.equals(that.padding); + } - private @Nullable PlatformLatLng position; + @Override + public int hashCode() { + return Objects.hash(bounds, padding); + } - @CanIgnoreReturnValue - public @NonNull Builder setPosition(@NonNull PlatformLatLng setterArg) { - this.position = setterArg; - return this; - } + public static final class Builder { private @Nullable PlatformLatLngBounds bounds; @@ -309,331 +590,5232 @@ public static final class Builder { return this; } - private @Nullable List markerIds; + private @Nullable Double padding; @CanIgnoreReturnValue - public @NonNull Builder setMarkerIds(@NonNull List setterArg) { - this.markerIds = setterArg; + public @NonNull Builder setPadding(@NonNull Double setterArg) { + this.padding = setterArg; return this; } - public @NonNull PlatformCluster build() { - PlatformCluster pigeonReturn = new PlatformCluster(); - pigeonReturn.setClusterManagerId(clusterManagerId); - pigeonReturn.setPosition(position); + public @NonNull PlatformCameraUpdateNewLatLngBounds build() { + PlatformCameraUpdateNewLatLngBounds pigeonReturn = + new PlatformCameraUpdateNewLatLngBounds(); pigeonReturn.setBounds(bounds); - pigeonReturn.setMarkerIds(markerIds); + pigeonReturn.setPadding(padding); return pigeonReturn; } } @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(4); - toListResult.add(clusterManagerId); - toListResult.add(position); + ArrayList toListResult = new ArrayList<>(2); toListResult.add(bounds); - toListResult.add(markerIds); + toListResult.add(padding); return toListResult; } - static @NonNull PlatformCluster fromList(@NonNull ArrayList __pigeon_list) { - PlatformCluster pigeonResult = new PlatformCluster(); - Object clusterManagerId = __pigeon_list.get(0); - pigeonResult.setClusterManagerId((String) clusterManagerId); - Object position = __pigeon_list.get(1); - pigeonResult.setPosition((PlatformLatLng) position); - Object bounds = __pigeon_list.get(2); + static @NonNull PlatformCameraUpdateNewLatLngBounds fromList( + @NonNull ArrayList pigeonVar_list) { + PlatformCameraUpdateNewLatLngBounds pigeonResult = new PlatformCameraUpdateNewLatLngBounds(); + Object bounds = pigeonVar_list.get(0); pigeonResult.setBounds((PlatformLatLngBounds) bounds); - Object markerIds = __pigeon_list.get(3); - pigeonResult.setMarkerIds((List) markerIds); + Object padding = pigeonVar_list.get(1); + pigeonResult.setPadding((Double) padding); return pigeonResult; } } /** - * Pigeon representation of an x,y coordinate. + * Pigeon equivalent of NewLatLngZoom * *

Generated class from Pigeon that represents data sent in messages. */ - public static final class PlatformPoint { - private @NonNull Long x; + public static final class PlatformCameraUpdateNewLatLngZoom { + private @NonNull PlatformLatLng latLng; - public @NonNull Long getX() { - return x; + public @NonNull PlatformLatLng getLatLng() { + return latLng; } - public void setX(@NonNull Long setterArg) { + public void setLatLng(@NonNull PlatformLatLng setterArg) { if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"x\" is null."); + throw new IllegalStateException("Nonnull field \"latLng\" is null."); } - this.x = setterArg; + this.latLng = setterArg; } - private @NonNull Long y; + private @NonNull Double zoom; - public @NonNull Long getY() { - return y; + public @NonNull Double getZoom() { + return zoom; } - public void setY(@NonNull Long setterArg) { + public void setZoom(@NonNull Double setterArg) { if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"y\" is null."); + throw new IllegalStateException("Nonnull field \"zoom\" is null."); } - this.y = setterArg; + this.zoom = setterArg; } /** Constructor is non-public to enforce null safety; use Builder. */ - PlatformPoint() {} + PlatformCameraUpdateNewLatLngZoom() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformCameraUpdateNewLatLngZoom that = (PlatformCameraUpdateNewLatLngZoom) o; + return latLng.equals(that.latLng) && zoom.equals(that.zoom); + } + + @Override + public int hashCode() { + return Objects.hash(latLng, zoom); + } + + public static final class Builder { + + private @Nullable PlatformLatLng latLng; + + @CanIgnoreReturnValue + public @NonNull Builder setLatLng(@NonNull PlatformLatLng setterArg) { + this.latLng = setterArg; + return this; + } + + private @Nullable Double zoom; + + @CanIgnoreReturnValue + public @NonNull Builder setZoom(@NonNull Double setterArg) { + this.zoom = setterArg; + return this; + } + + public @NonNull PlatformCameraUpdateNewLatLngZoom build() { + PlatformCameraUpdateNewLatLngZoom pigeonReturn = new PlatformCameraUpdateNewLatLngZoom(); + pigeonReturn.setLatLng(latLng); + pigeonReturn.setZoom(zoom); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(2); + toListResult.add(latLng); + toListResult.add(zoom); + return toListResult; + } + + static @NonNull PlatformCameraUpdateNewLatLngZoom fromList( + @NonNull ArrayList pigeonVar_list) { + PlatformCameraUpdateNewLatLngZoom pigeonResult = new PlatformCameraUpdateNewLatLngZoom(); + Object latLng = pigeonVar_list.get(0); + pigeonResult.setLatLng((PlatformLatLng) latLng); + Object zoom = pigeonVar_list.get(1); + pigeonResult.setZoom((Double) zoom); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of ScrollBy + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformCameraUpdateScrollBy { + private @NonNull Double dx; + + public @NonNull Double getDx() { + return dx; + } + + public void setDx(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"dx\" is null."); + } + this.dx = setterArg; + } + + private @NonNull Double dy; + + public @NonNull Double getDy() { + return dy; + } + + public void setDy(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"dy\" is null."); + } + this.dy = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformCameraUpdateScrollBy() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformCameraUpdateScrollBy that = (PlatformCameraUpdateScrollBy) o; + return dx.equals(that.dx) && dy.equals(that.dy); + } + + @Override + public int hashCode() { + return Objects.hash(dx, dy); + } + + public static final class Builder { + + private @Nullable Double dx; + + @CanIgnoreReturnValue + public @NonNull Builder setDx(@NonNull Double setterArg) { + this.dx = setterArg; + return this; + } + + private @Nullable Double dy; + + @CanIgnoreReturnValue + public @NonNull Builder setDy(@NonNull Double setterArg) { + this.dy = setterArg; + return this; + } + + public @NonNull PlatformCameraUpdateScrollBy build() { + PlatformCameraUpdateScrollBy pigeonReturn = new PlatformCameraUpdateScrollBy(); + pigeonReturn.setDx(dx); + pigeonReturn.setDy(dy); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(2); + toListResult.add(dx); + toListResult.add(dy); + return toListResult; + } + + static @NonNull PlatformCameraUpdateScrollBy fromList( + @NonNull ArrayList pigeonVar_list) { + PlatformCameraUpdateScrollBy pigeonResult = new PlatformCameraUpdateScrollBy(); + Object dx = pigeonVar_list.get(0); + pigeonResult.setDx((Double) dx); + Object dy = pigeonVar_list.get(1); + pigeonResult.setDy((Double) dy); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of ZoomBy + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformCameraUpdateZoomBy { + private @NonNull Double amount; + + public @NonNull Double getAmount() { + return amount; + } + + public void setAmount(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"amount\" is null."); + } + this.amount = setterArg; + } + + private @Nullable PlatformDoublePair focus; + + public @Nullable PlatformDoublePair getFocus() { + return focus; + } + + public void setFocus(@Nullable PlatformDoublePair setterArg) { + this.focus = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformCameraUpdateZoomBy() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformCameraUpdateZoomBy that = (PlatformCameraUpdateZoomBy) o; + return amount.equals(that.amount) && Objects.equals(focus, that.focus); + } + + @Override + public int hashCode() { + return Objects.hash(amount, focus); + } + + public static final class Builder { + + private @Nullable Double amount; + + @CanIgnoreReturnValue + public @NonNull Builder setAmount(@NonNull Double setterArg) { + this.amount = setterArg; + return this; + } + + private @Nullable PlatformDoublePair focus; + + @CanIgnoreReturnValue + public @NonNull Builder setFocus(@Nullable PlatformDoublePair setterArg) { + this.focus = setterArg; + return this; + } + + public @NonNull PlatformCameraUpdateZoomBy build() { + PlatformCameraUpdateZoomBy pigeonReturn = new PlatformCameraUpdateZoomBy(); + pigeonReturn.setAmount(amount); + pigeonReturn.setFocus(focus); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(2); + toListResult.add(amount); + toListResult.add(focus); + return toListResult; + } + + static @NonNull PlatformCameraUpdateZoomBy fromList(@NonNull ArrayList pigeonVar_list) { + PlatformCameraUpdateZoomBy pigeonResult = new PlatformCameraUpdateZoomBy(); + Object amount = pigeonVar_list.get(0); + pigeonResult.setAmount((Double) amount); + Object focus = pigeonVar_list.get(1); + pigeonResult.setFocus((PlatformDoublePair) focus); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of ZoomIn/ZoomOut + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformCameraUpdateZoom { + private @NonNull Boolean out; + + public @NonNull Boolean getOut() { + return out; + } + + public void setOut(@NonNull Boolean setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"out\" is null."); + } + this.out = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformCameraUpdateZoom() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformCameraUpdateZoom that = (PlatformCameraUpdateZoom) o; + return out.equals(that.out); + } + + @Override + public int hashCode() { + return Objects.hash(out); + } + + public static final class Builder { + + private @Nullable Boolean out; + + @CanIgnoreReturnValue + public @NonNull Builder setOut(@NonNull Boolean setterArg) { + this.out = setterArg; + return this; + } + + public @NonNull PlatformCameraUpdateZoom build() { + PlatformCameraUpdateZoom pigeonReturn = new PlatformCameraUpdateZoom(); + pigeonReturn.setOut(out); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(1); + toListResult.add(out); + return toListResult; + } + + static @NonNull PlatformCameraUpdateZoom fromList(@NonNull ArrayList pigeonVar_list) { + PlatformCameraUpdateZoom pigeonResult = new PlatformCameraUpdateZoom(); + Object out = pigeonVar_list.get(0); + pigeonResult.setOut((Boolean) out); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of ZoomTo + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformCameraUpdateZoomTo { + private @NonNull Double zoom; + + public @NonNull Double getZoom() { + return zoom; + } + + public void setZoom(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"zoom\" is null."); + } + this.zoom = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformCameraUpdateZoomTo() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformCameraUpdateZoomTo that = (PlatformCameraUpdateZoomTo) o; + return zoom.equals(that.zoom); + } + + @Override + public int hashCode() { + return Objects.hash(zoom); + } public static final class Builder { - private @Nullable Long x; + private @Nullable Double zoom; + + @CanIgnoreReturnValue + public @NonNull Builder setZoom(@NonNull Double setterArg) { + this.zoom = setterArg; + return this; + } + + public @NonNull PlatformCameraUpdateZoomTo build() { + PlatformCameraUpdateZoomTo pigeonReturn = new PlatformCameraUpdateZoomTo(); + pigeonReturn.setZoom(zoom); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(1); + toListResult.add(zoom); + return toListResult; + } + + static @NonNull PlatformCameraUpdateZoomTo fromList(@NonNull ArrayList pigeonVar_list) { + PlatformCameraUpdateZoomTo pigeonResult = new PlatformCameraUpdateZoomTo(); + Object zoom = pigeonVar_list.get(0); + pigeonResult.setZoom((Double) zoom); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of the Circle class. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformCircle { + private @NonNull Boolean consumeTapEvents; + + public @NonNull Boolean getConsumeTapEvents() { + return consumeTapEvents; + } + + public void setConsumeTapEvents(@NonNull Boolean setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"consumeTapEvents\" is null."); + } + this.consumeTapEvents = setterArg; + } + + private @NonNull Long fillColor; + + public @NonNull Long getFillColor() { + return fillColor; + } + + public void setFillColor(@NonNull Long setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"fillColor\" is null."); + } + this.fillColor = setterArg; + } + + private @NonNull Long strokeColor; + + public @NonNull Long getStrokeColor() { + return strokeColor; + } + + public void setStrokeColor(@NonNull Long setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"strokeColor\" is null."); + } + this.strokeColor = setterArg; + } + + private @NonNull Boolean visible; + + public @NonNull Boolean getVisible() { + return visible; + } + + public void setVisible(@NonNull Boolean setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"visible\" is null."); + } + this.visible = setterArg; + } + + private @NonNull Long strokeWidth; + + public @NonNull Long getStrokeWidth() { + return strokeWidth; + } + + public void setStrokeWidth(@NonNull Long setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"strokeWidth\" is null."); + } + this.strokeWidth = setterArg; + } + + private @NonNull Double zIndex; + + public @NonNull Double getZIndex() { + return zIndex; + } + + public void setZIndex(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"zIndex\" is null."); + } + this.zIndex = setterArg; + } + + private @NonNull PlatformLatLng center; + + public @NonNull PlatformLatLng getCenter() { + return center; + } + + public void setCenter(@NonNull PlatformLatLng setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"center\" is null."); + } + this.center = setterArg; + } + + private @NonNull Double radius; + + public @NonNull Double getRadius() { + return radius; + } + + public void setRadius(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"radius\" is null."); + } + this.radius = setterArg; + } + + private @NonNull String circleId; + + public @NonNull String getCircleId() { + return circleId; + } + + public void setCircleId(@NonNull String setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"circleId\" is null."); + } + this.circleId = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformCircle() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformCircle that = (PlatformCircle) o; + return consumeTapEvents.equals(that.consumeTapEvents) + && fillColor.equals(that.fillColor) + && strokeColor.equals(that.strokeColor) + && visible.equals(that.visible) + && strokeWidth.equals(that.strokeWidth) + && zIndex.equals(that.zIndex) + && center.equals(that.center) + && radius.equals(that.radius) + && circleId.equals(that.circleId); + } + + @Override + public int hashCode() { + return Objects.hash( + consumeTapEvents, + fillColor, + strokeColor, + visible, + strokeWidth, + zIndex, + center, + radius, + circleId); + } + + public static final class Builder { + + private @Nullable Boolean consumeTapEvents; + + @CanIgnoreReturnValue + public @NonNull Builder setConsumeTapEvents(@NonNull Boolean setterArg) { + this.consumeTapEvents = setterArg; + return this; + } + + private @Nullable Long fillColor; + + @CanIgnoreReturnValue + public @NonNull Builder setFillColor(@NonNull Long setterArg) { + this.fillColor = setterArg; + return this; + } + + private @Nullable Long strokeColor; + + @CanIgnoreReturnValue + public @NonNull Builder setStrokeColor(@NonNull Long setterArg) { + this.strokeColor = setterArg; + return this; + } + + private @Nullable Boolean visible; + + @CanIgnoreReturnValue + public @NonNull Builder setVisible(@NonNull Boolean setterArg) { + this.visible = setterArg; + return this; + } + + private @Nullable Long strokeWidth; + + @CanIgnoreReturnValue + public @NonNull Builder setStrokeWidth(@NonNull Long setterArg) { + this.strokeWidth = setterArg; + return this; + } + + private @Nullable Double zIndex; + + @CanIgnoreReturnValue + public @NonNull Builder setZIndex(@NonNull Double setterArg) { + this.zIndex = setterArg; + return this; + } + + private @Nullable PlatformLatLng center; + + @CanIgnoreReturnValue + public @NonNull Builder setCenter(@NonNull PlatformLatLng setterArg) { + this.center = setterArg; + return this; + } + + private @Nullable Double radius; + + @CanIgnoreReturnValue + public @NonNull Builder setRadius(@NonNull Double setterArg) { + this.radius = setterArg; + return this; + } + + private @Nullable String circleId; + + @CanIgnoreReturnValue + public @NonNull Builder setCircleId(@NonNull String setterArg) { + this.circleId = setterArg; + return this; + } + + public @NonNull PlatformCircle build() { + PlatformCircle pigeonReturn = new PlatformCircle(); + pigeonReturn.setConsumeTapEvents(consumeTapEvents); + pigeonReturn.setFillColor(fillColor); + pigeonReturn.setStrokeColor(strokeColor); + pigeonReturn.setVisible(visible); + pigeonReturn.setStrokeWidth(strokeWidth); + pigeonReturn.setZIndex(zIndex); + pigeonReturn.setCenter(center); + pigeonReturn.setRadius(radius); + pigeonReturn.setCircleId(circleId); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(9); + toListResult.add(consumeTapEvents); + toListResult.add(fillColor); + toListResult.add(strokeColor); + toListResult.add(visible); + toListResult.add(strokeWidth); + toListResult.add(zIndex); + toListResult.add(center); + toListResult.add(radius); + toListResult.add(circleId); + return toListResult; + } + + static @NonNull PlatformCircle fromList(@NonNull ArrayList pigeonVar_list) { + PlatformCircle pigeonResult = new PlatformCircle(); + Object consumeTapEvents = pigeonVar_list.get(0); + pigeonResult.setConsumeTapEvents((Boolean) consumeTapEvents); + Object fillColor = pigeonVar_list.get(1); + pigeonResult.setFillColor((Long) fillColor); + Object strokeColor = pigeonVar_list.get(2); + pigeonResult.setStrokeColor((Long) strokeColor); + Object visible = pigeonVar_list.get(3); + pigeonResult.setVisible((Boolean) visible); + Object strokeWidth = pigeonVar_list.get(4); + pigeonResult.setStrokeWidth((Long) strokeWidth); + Object zIndex = pigeonVar_list.get(5); + pigeonResult.setZIndex((Double) zIndex); + Object center = pigeonVar_list.get(6); + pigeonResult.setCenter((PlatformLatLng) center); + Object radius = pigeonVar_list.get(7); + pigeonResult.setRadius((Double) radius); + Object circleId = pigeonVar_list.get(8); + pigeonResult.setCircleId((String) circleId); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of the Heatmap class. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformHeatmap { + /** + * The heatmap data, as JSON. This should only be set from Heatmap.toJson, and the native code + * must interpret it according to the internal implementation details of that method. + */ + private @NonNull Map json; + + public @NonNull Map getJson() { + return json; + } + + public void setJson(@NonNull Map setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"json\" is null."); + } + this.json = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformHeatmap() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformHeatmap that = (PlatformHeatmap) o; + return json.equals(that.json); + } + + @Override + public int hashCode() { + return Objects.hash(json); + } + + public static final class Builder { + + private @Nullable Map json; + + @CanIgnoreReturnValue + public @NonNull Builder setJson(@NonNull Map setterArg) { + this.json = setterArg; + return this; + } + + public @NonNull PlatformHeatmap build() { + PlatformHeatmap pigeonReturn = new PlatformHeatmap(); + pigeonReturn.setJson(json); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(1); + toListResult.add(json); + return toListResult; + } + + static @NonNull PlatformHeatmap fromList(@NonNull ArrayList pigeonVar_list) { + PlatformHeatmap pigeonResult = new PlatformHeatmap(); + Object json = pigeonVar_list.get(0); + pigeonResult.setJson((Map) json); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of the ClusterManager class. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformClusterManager { + private @NonNull String identifier; + + public @NonNull String getIdentifier() { + return identifier; + } + + public void setIdentifier(@NonNull String setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"identifier\" is null."); + } + this.identifier = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformClusterManager() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformClusterManager that = (PlatformClusterManager) o; + return identifier.equals(that.identifier); + } + + @Override + public int hashCode() { + return Objects.hash(identifier); + } + + public static final class Builder { + + private @Nullable String identifier; + + @CanIgnoreReturnValue + public @NonNull Builder setIdentifier(@NonNull String setterArg) { + this.identifier = setterArg; + return this; + } + + public @NonNull PlatformClusterManager build() { + PlatformClusterManager pigeonReturn = new PlatformClusterManager(); + pigeonReturn.setIdentifier(identifier); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(1); + toListResult.add(identifier); + return toListResult; + } + + static @NonNull PlatformClusterManager fromList(@NonNull ArrayList pigeonVar_list) { + PlatformClusterManager pigeonResult = new PlatformClusterManager(); + Object identifier = pigeonVar_list.get(0); + pigeonResult.setIdentifier((String) identifier); + return pigeonResult; + } + } + + /** + * Pair of double values, such as for an offset or size. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformDoublePair { + private @NonNull Double x; + + public @NonNull Double getX() { + return x; + } + + public void setX(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"x\" is null."); + } + this.x = setterArg; + } + + private @NonNull Double y; + + public @NonNull Double getY() { + return y; + } + + public void setY(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"y\" is null."); + } + this.y = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformDoublePair() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformDoublePair that = (PlatformDoublePair) o; + return x.equals(that.x) && y.equals(that.y); + } + + @Override + public int hashCode() { + return Objects.hash(x, y); + } + + public static final class Builder { + + private @Nullable Double x; + + @CanIgnoreReturnValue + public @NonNull Builder setX(@NonNull Double setterArg) { + this.x = setterArg; + return this; + } + + private @Nullable Double y; + + @CanIgnoreReturnValue + public @NonNull Builder setY(@NonNull Double setterArg) { + this.y = setterArg; + return this; + } + + public @NonNull PlatformDoublePair build() { + PlatformDoublePair pigeonReturn = new PlatformDoublePair(); + pigeonReturn.setX(x); + pigeonReturn.setY(y); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(2); + toListResult.add(x); + toListResult.add(y); + return toListResult; + } + + static @NonNull PlatformDoublePair fromList(@NonNull ArrayList pigeonVar_list) { + PlatformDoublePair pigeonResult = new PlatformDoublePair(); + Object x = pigeonVar_list.get(0); + pigeonResult.setX((Double) x); + Object y = pigeonVar_list.get(1); + pigeonResult.setY((Double) y); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of the InfoWindow class. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformInfoWindow { + private @Nullable String title; + + public @Nullable String getTitle() { + return title; + } + + public void setTitle(@Nullable String setterArg) { + this.title = setterArg; + } + + private @Nullable String snippet; + + public @Nullable String getSnippet() { + return snippet; + } + + public void setSnippet(@Nullable String setterArg) { + this.snippet = setterArg; + } + + private @NonNull PlatformDoublePair anchor; + + public @NonNull PlatformDoublePair getAnchor() { + return anchor; + } + + public void setAnchor(@NonNull PlatformDoublePair setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"anchor\" is null."); + } + this.anchor = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformInfoWindow() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformInfoWindow that = (PlatformInfoWindow) o; + return Objects.equals(title, that.title) + && Objects.equals(snippet, that.snippet) + && anchor.equals(that.anchor); + } + + @Override + public int hashCode() { + return Objects.hash(title, snippet, anchor); + } + + public static final class Builder { + + private @Nullable String title; + + @CanIgnoreReturnValue + public @NonNull Builder setTitle(@Nullable String setterArg) { + this.title = setterArg; + return this; + } + + private @Nullable String snippet; + + @CanIgnoreReturnValue + public @NonNull Builder setSnippet(@Nullable String setterArg) { + this.snippet = setterArg; + return this; + } + + private @Nullable PlatformDoublePair anchor; + + @CanIgnoreReturnValue + public @NonNull Builder setAnchor(@NonNull PlatformDoublePair setterArg) { + this.anchor = setterArg; + return this; + } + + public @NonNull PlatformInfoWindow build() { + PlatformInfoWindow pigeonReturn = new PlatformInfoWindow(); + pigeonReturn.setTitle(title); + pigeonReturn.setSnippet(snippet); + pigeonReturn.setAnchor(anchor); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(3); + toListResult.add(title); + toListResult.add(snippet); + toListResult.add(anchor); + return toListResult; + } + + static @NonNull PlatformInfoWindow fromList(@NonNull ArrayList pigeonVar_list) { + PlatformInfoWindow pigeonResult = new PlatformInfoWindow(); + Object title = pigeonVar_list.get(0); + pigeonResult.setTitle((String) title); + Object snippet = pigeonVar_list.get(1); + pigeonResult.setSnippet((String) snippet); + Object anchor = pigeonVar_list.get(2); + pigeonResult.setAnchor((PlatformDoublePair) anchor); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of the Marker class. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformMarker { + private @NonNull Double alpha; + + public @NonNull Double getAlpha() { + return alpha; + } + + public void setAlpha(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"alpha\" is null."); + } + this.alpha = setterArg; + } + + private @NonNull PlatformDoublePair anchor; + + public @NonNull PlatformDoublePair getAnchor() { + return anchor; + } + + public void setAnchor(@NonNull PlatformDoublePair setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"anchor\" is null."); + } + this.anchor = setterArg; + } + + private @NonNull Boolean consumeTapEvents; + + public @NonNull Boolean getConsumeTapEvents() { + return consumeTapEvents; + } + + public void setConsumeTapEvents(@NonNull Boolean setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"consumeTapEvents\" is null."); + } + this.consumeTapEvents = setterArg; + } + + private @NonNull Boolean draggable; + + public @NonNull Boolean getDraggable() { + return draggable; + } + + public void setDraggable(@NonNull Boolean setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"draggable\" is null."); + } + this.draggable = setterArg; + } + + private @NonNull Boolean flat; + + public @NonNull Boolean getFlat() { + return flat; + } + + public void setFlat(@NonNull Boolean setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"flat\" is null."); + } + this.flat = setterArg; + } + + private @NonNull PlatformBitmap icon; + + public @NonNull PlatformBitmap getIcon() { + return icon; + } + + public void setIcon(@NonNull PlatformBitmap setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"icon\" is null."); + } + this.icon = setterArg; + } + + private @NonNull PlatformInfoWindow infoWindow; + + public @NonNull PlatformInfoWindow getInfoWindow() { + return infoWindow; + } + + public void setInfoWindow(@NonNull PlatformInfoWindow setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"infoWindow\" is null."); + } + this.infoWindow = setterArg; + } + + private @NonNull PlatformLatLng position; + + public @NonNull PlatformLatLng getPosition() { + return position; + } + + public void setPosition(@NonNull PlatformLatLng setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"position\" is null."); + } + this.position = setterArg; + } + + private @NonNull Double rotation; + + public @NonNull Double getRotation() { + return rotation; + } + + public void setRotation(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"rotation\" is null."); + } + this.rotation = setterArg; + } + + private @NonNull Boolean visible; + + public @NonNull Boolean getVisible() { + return visible; + } + + public void setVisible(@NonNull Boolean setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"visible\" is null."); + } + this.visible = setterArg; + } + + private @NonNull Double zIndex; + + public @NonNull Double getZIndex() { + return zIndex; + } + + public void setZIndex(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"zIndex\" is null."); + } + this.zIndex = setterArg; + } + + private @NonNull String markerId; + + public @NonNull String getMarkerId() { + return markerId; + } + + public void setMarkerId(@NonNull String setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"markerId\" is null."); + } + this.markerId = setterArg; + } + + private @Nullable String clusterManagerId; + + public @Nullable String getClusterManagerId() { + return clusterManagerId; + } + + public void setClusterManagerId(@Nullable String setterArg) { + this.clusterManagerId = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformMarker() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformMarker that = (PlatformMarker) o; + return alpha.equals(that.alpha) + && anchor.equals(that.anchor) + && consumeTapEvents.equals(that.consumeTapEvents) + && draggable.equals(that.draggable) + && flat.equals(that.flat) + && icon.equals(that.icon) + && infoWindow.equals(that.infoWindow) + && position.equals(that.position) + && rotation.equals(that.rotation) + && visible.equals(that.visible) + && zIndex.equals(that.zIndex) + && markerId.equals(that.markerId) + && Objects.equals(clusterManagerId, that.clusterManagerId); + } + + @Override + public int hashCode() { + return Objects.hash( + alpha, + anchor, + consumeTapEvents, + draggable, + flat, + icon, + infoWindow, + position, + rotation, + visible, + zIndex, + markerId, + clusterManagerId); + } + + public static final class Builder { + + private @Nullable Double alpha; + + @CanIgnoreReturnValue + public @NonNull Builder setAlpha(@NonNull Double setterArg) { + this.alpha = setterArg; + return this; + } + + private @Nullable PlatformDoublePair anchor; + + @CanIgnoreReturnValue + public @NonNull Builder setAnchor(@NonNull PlatformDoublePair setterArg) { + this.anchor = setterArg; + return this; + } + + private @Nullable Boolean consumeTapEvents; + + @CanIgnoreReturnValue + public @NonNull Builder setConsumeTapEvents(@NonNull Boolean setterArg) { + this.consumeTapEvents = setterArg; + return this; + } + + private @Nullable Boolean draggable; + + @CanIgnoreReturnValue + public @NonNull Builder setDraggable(@NonNull Boolean setterArg) { + this.draggable = setterArg; + return this; + } + + private @Nullable Boolean flat; + + @CanIgnoreReturnValue + public @NonNull Builder setFlat(@NonNull Boolean setterArg) { + this.flat = setterArg; + return this; + } + + private @Nullable PlatformBitmap icon; + + @CanIgnoreReturnValue + public @NonNull Builder setIcon(@NonNull PlatformBitmap setterArg) { + this.icon = setterArg; + return this; + } + + private @Nullable PlatformInfoWindow infoWindow; + + @CanIgnoreReturnValue + public @NonNull Builder setInfoWindow(@NonNull PlatformInfoWindow setterArg) { + this.infoWindow = setterArg; + return this; + } + + private @Nullable PlatformLatLng position; + + @CanIgnoreReturnValue + public @NonNull Builder setPosition(@NonNull PlatformLatLng setterArg) { + this.position = setterArg; + return this; + } + + private @Nullable Double rotation; + + @CanIgnoreReturnValue + public @NonNull Builder setRotation(@NonNull Double setterArg) { + this.rotation = setterArg; + return this; + } + + private @Nullable Boolean visible; + + @CanIgnoreReturnValue + public @NonNull Builder setVisible(@NonNull Boolean setterArg) { + this.visible = setterArg; + return this; + } + + private @Nullable Double zIndex; + + @CanIgnoreReturnValue + public @NonNull Builder setZIndex(@NonNull Double setterArg) { + this.zIndex = setterArg; + return this; + } + + private @Nullable String markerId; + + @CanIgnoreReturnValue + public @NonNull Builder setMarkerId(@NonNull String setterArg) { + this.markerId = setterArg; + return this; + } + + private @Nullable String clusterManagerId; + + @CanIgnoreReturnValue + public @NonNull Builder setClusterManagerId(@Nullable String setterArg) { + this.clusterManagerId = setterArg; + return this; + } + + public @NonNull PlatformMarker build() { + PlatformMarker pigeonReturn = new PlatformMarker(); + pigeonReturn.setAlpha(alpha); + pigeonReturn.setAnchor(anchor); + pigeonReturn.setConsumeTapEvents(consumeTapEvents); + pigeonReturn.setDraggable(draggable); + pigeonReturn.setFlat(flat); + pigeonReturn.setIcon(icon); + pigeonReturn.setInfoWindow(infoWindow); + pigeonReturn.setPosition(position); + pigeonReturn.setRotation(rotation); + pigeonReturn.setVisible(visible); + pigeonReturn.setZIndex(zIndex); + pigeonReturn.setMarkerId(markerId); + pigeonReturn.setClusterManagerId(clusterManagerId); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(13); + toListResult.add(alpha); + toListResult.add(anchor); + toListResult.add(consumeTapEvents); + toListResult.add(draggable); + toListResult.add(flat); + toListResult.add(icon); + toListResult.add(infoWindow); + toListResult.add(position); + toListResult.add(rotation); + toListResult.add(visible); + toListResult.add(zIndex); + toListResult.add(markerId); + toListResult.add(clusterManagerId); + return toListResult; + } + + static @NonNull PlatformMarker fromList(@NonNull ArrayList pigeonVar_list) { + PlatformMarker pigeonResult = new PlatformMarker(); + Object alpha = pigeonVar_list.get(0); + pigeonResult.setAlpha((Double) alpha); + Object anchor = pigeonVar_list.get(1); + pigeonResult.setAnchor((PlatformDoublePair) anchor); + Object consumeTapEvents = pigeonVar_list.get(2); + pigeonResult.setConsumeTapEvents((Boolean) consumeTapEvents); + Object draggable = pigeonVar_list.get(3); + pigeonResult.setDraggable((Boolean) draggable); + Object flat = pigeonVar_list.get(4); + pigeonResult.setFlat((Boolean) flat); + Object icon = pigeonVar_list.get(5); + pigeonResult.setIcon((PlatformBitmap) icon); + Object infoWindow = pigeonVar_list.get(6); + pigeonResult.setInfoWindow((PlatformInfoWindow) infoWindow); + Object position = pigeonVar_list.get(7); + pigeonResult.setPosition((PlatformLatLng) position); + Object rotation = pigeonVar_list.get(8); + pigeonResult.setRotation((Double) rotation); + Object visible = pigeonVar_list.get(9); + pigeonResult.setVisible((Boolean) visible); + Object zIndex = pigeonVar_list.get(10); + pigeonResult.setZIndex((Double) zIndex); + Object markerId = pigeonVar_list.get(11); + pigeonResult.setMarkerId((String) markerId); + Object clusterManagerId = pigeonVar_list.get(12); + pigeonResult.setClusterManagerId((String) clusterManagerId); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of the Polygon class. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformPolygon { + private @NonNull String polygonId; + + public @NonNull String getPolygonId() { + return polygonId; + } + + public void setPolygonId(@NonNull String setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"polygonId\" is null."); + } + this.polygonId = setterArg; + } + + private @NonNull Boolean consumesTapEvents; + + public @NonNull Boolean getConsumesTapEvents() { + return consumesTapEvents; + } + + public void setConsumesTapEvents(@NonNull Boolean setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"consumesTapEvents\" is null."); + } + this.consumesTapEvents = setterArg; + } + + private @NonNull Long fillColor; + + public @NonNull Long getFillColor() { + return fillColor; + } + + public void setFillColor(@NonNull Long setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"fillColor\" is null."); + } + this.fillColor = setterArg; + } + + private @NonNull Boolean geodesic; + + public @NonNull Boolean getGeodesic() { + return geodesic; + } + + public void setGeodesic(@NonNull Boolean setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"geodesic\" is null."); + } + this.geodesic = setterArg; + } + + private @NonNull List points; + + public @NonNull List getPoints() { + return points; + } + + public void setPoints(@NonNull List setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"points\" is null."); + } + this.points = setterArg; + } + + private @NonNull List> holes; + + public @NonNull List> getHoles() { + return holes; + } + + public void setHoles(@NonNull List> setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"holes\" is null."); + } + this.holes = setterArg; + } + + private @NonNull Boolean visible; + + public @NonNull Boolean getVisible() { + return visible; + } + + public void setVisible(@NonNull Boolean setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"visible\" is null."); + } + this.visible = setterArg; + } + + private @NonNull Long strokeColor; + + public @NonNull Long getStrokeColor() { + return strokeColor; + } + + public void setStrokeColor(@NonNull Long setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"strokeColor\" is null."); + } + this.strokeColor = setterArg; + } + + private @NonNull Long strokeWidth; + + public @NonNull Long getStrokeWidth() { + return strokeWidth; + } + + public void setStrokeWidth(@NonNull Long setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"strokeWidth\" is null."); + } + this.strokeWidth = setterArg; + } + + private @NonNull Long zIndex; + + public @NonNull Long getZIndex() { + return zIndex; + } + + public void setZIndex(@NonNull Long setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"zIndex\" is null."); + } + this.zIndex = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformPolygon() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformPolygon that = (PlatformPolygon) o; + return polygonId.equals(that.polygonId) + && consumesTapEvents.equals(that.consumesTapEvents) + && fillColor.equals(that.fillColor) + && geodesic.equals(that.geodesic) + && points.equals(that.points) + && holes.equals(that.holes) + && visible.equals(that.visible) + && strokeColor.equals(that.strokeColor) + && strokeWidth.equals(that.strokeWidth) + && zIndex.equals(that.zIndex); + } + + @Override + public int hashCode() { + return Objects.hash( + polygonId, + consumesTapEvents, + fillColor, + geodesic, + points, + holes, + visible, + strokeColor, + strokeWidth, + zIndex); + } + + public static final class Builder { + + private @Nullable String polygonId; + + @CanIgnoreReturnValue + public @NonNull Builder setPolygonId(@NonNull String setterArg) { + this.polygonId = setterArg; + return this; + } + + private @Nullable Boolean consumesTapEvents; + + @CanIgnoreReturnValue + public @NonNull Builder setConsumesTapEvents(@NonNull Boolean setterArg) { + this.consumesTapEvents = setterArg; + return this; + } + + private @Nullable Long fillColor; + + @CanIgnoreReturnValue + public @NonNull Builder setFillColor(@NonNull Long setterArg) { + this.fillColor = setterArg; + return this; + } + + private @Nullable Boolean geodesic; + + @CanIgnoreReturnValue + public @NonNull Builder setGeodesic(@NonNull Boolean setterArg) { + this.geodesic = setterArg; + return this; + } + + private @Nullable List points; + + @CanIgnoreReturnValue + public @NonNull Builder setPoints(@NonNull List setterArg) { + this.points = setterArg; + return this; + } + + private @Nullable List> holes; + + @CanIgnoreReturnValue + public @NonNull Builder setHoles(@NonNull List> setterArg) { + this.holes = setterArg; + return this; + } + + private @Nullable Boolean visible; + + @CanIgnoreReturnValue + public @NonNull Builder setVisible(@NonNull Boolean setterArg) { + this.visible = setterArg; + return this; + } + + private @Nullable Long strokeColor; + + @CanIgnoreReturnValue + public @NonNull Builder setStrokeColor(@NonNull Long setterArg) { + this.strokeColor = setterArg; + return this; + } + + private @Nullable Long strokeWidth; + + @CanIgnoreReturnValue + public @NonNull Builder setStrokeWidth(@NonNull Long setterArg) { + this.strokeWidth = setterArg; + return this; + } + + private @Nullable Long zIndex; + + @CanIgnoreReturnValue + public @NonNull Builder setZIndex(@NonNull Long setterArg) { + this.zIndex = setterArg; + return this; + } + + public @NonNull PlatformPolygon build() { + PlatformPolygon pigeonReturn = new PlatformPolygon(); + pigeonReturn.setPolygonId(polygonId); + pigeonReturn.setConsumesTapEvents(consumesTapEvents); + pigeonReturn.setFillColor(fillColor); + pigeonReturn.setGeodesic(geodesic); + pigeonReturn.setPoints(points); + pigeonReturn.setHoles(holes); + pigeonReturn.setVisible(visible); + pigeonReturn.setStrokeColor(strokeColor); + pigeonReturn.setStrokeWidth(strokeWidth); + pigeonReturn.setZIndex(zIndex); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(10); + toListResult.add(polygonId); + toListResult.add(consumesTapEvents); + toListResult.add(fillColor); + toListResult.add(geodesic); + toListResult.add(points); + toListResult.add(holes); + toListResult.add(visible); + toListResult.add(strokeColor); + toListResult.add(strokeWidth); + toListResult.add(zIndex); + return toListResult; + } + + static @NonNull PlatformPolygon fromList(@NonNull ArrayList pigeonVar_list) { + PlatformPolygon pigeonResult = new PlatformPolygon(); + Object polygonId = pigeonVar_list.get(0); + pigeonResult.setPolygonId((String) polygonId); + Object consumesTapEvents = pigeonVar_list.get(1); + pigeonResult.setConsumesTapEvents((Boolean) consumesTapEvents); + Object fillColor = pigeonVar_list.get(2); + pigeonResult.setFillColor((Long) fillColor); + Object geodesic = pigeonVar_list.get(3); + pigeonResult.setGeodesic((Boolean) geodesic); + Object points = pigeonVar_list.get(4); + pigeonResult.setPoints((List) points); + Object holes = pigeonVar_list.get(5); + pigeonResult.setHoles((List>) holes); + Object visible = pigeonVar_list.get(6); + pigeonResult.setVisible((Boolean) visible); + Object strokeColor = pigeonVar_list.get(7); + pigeonResult.setStrokeColor((Long) strokeColor); + Object strokeWidth = pigeonVar_list.get(8); + pigeonResult.setStrokeWidth((Long) strokeWidth); + Object zIndex = pigeonVar_list.get(9); + pigeonResult.setZIndex((Long) zIndex); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of the Polyline class. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformPolyline { + private @NonNull String polylineId; + + public @NonNull String getPolylineId() { + return polylineId; + } + + public void setPolylineId(@NonNull String setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"polylineId\" is null."); + } + this.polylineId = setterArg; + } + + private @NonNull Boolean consumesTapEvents; + + public @NonNull Boolean getConsumesTapEvents() { + return consumesTapEvents; + } + + public void setConsumesTapEvents(@NonNull Boolean setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"consumesTapEvents\" is null."); + } + this.consumesTapEvents = setterArg; + } + + private @NonNull Long color; + + public @NonNull Long getColor() { + return color; + } + + public void setColor(@NonNull Long setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"color\" is null."); + } + this.color = setterArg; + } + + private @NonNull Boolean geodesic; + + public @NonNull Boolean getGeodesic() { + return geodesic; + } + + public void setGeodesic(@NonNull Boolean setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"geodesic\" is null."); + } + this.geodesic = setterArg; + } + + /** The joint type. */ + private @NonNull PlatformJointType jointType; + + public @NonNull PlatformJointType getJointType() { + return jointType; + } + + public void setJointType(@NonNull PlatformJointType setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"jointType\" is null."); + } + this.jointType = setterArg; + } + + /** The pattern data, as a list of pattern items. */ + private @NonNull List patterns; + + public @NonNull List getPatterns() { + return patterns; + } + + public void setPatterns(@NonNull List setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"patterns\" is null."); + } + this.patterns = setterArg; + } + + private @NonNull List points; + + public @NonNull List getPoints() { + return points; + } + + public void setPoints(@NonNull List setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"points\" is null."); + } + this.points = setterArg; + } + + /** + * The cap at the start and end vertex of a polyline. See + * https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/Cap. + */ + private @NonNull PlatformCap startCap; + + public @NonNull PlatformCap getStartCap() { + return startCap; + } + + public void setStartCap(@NonNull PlatformCap setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"startCap\" is null."); + } + this.startCap = setterArg; + } + + private @NonNull PlatformCap endCap; + + public @NonNull PlatformCap getEndCap() { + return endCap; + } + + public void setEndCap(@NonNull PlatformCap setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"endCap\" is null."); + } + this.endCap = setterArg; + } + + private @NonNull Boolean visible; + + public @NonNull Boolean getVisible() { + return visible; + } + + public void setVisible(@NonNull Boolean setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"visible\" is null."); + } + this.visible = setterArg; + } + + private @NonNull Long width; + + public @NonNull Long getWidth() { + return width; + } + + public void setWidth(@NonNull Long setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"width\" is null."); + } + this.width = setterArg; + } + + private @NonNull Long zIndex; + + public @NonNull Long getZIndex() { + return zIndex; + } + + public void setZIndex(@NonNull Long setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"zIndex\" is null."); + } + this.zIndex = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformPolyline() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformPolyline that = (PlatformPolyline) o; + return polylineId.equals(that.polylineId) + && consumesTapEvents.equals(that.consumesTapEvents) + && color.equals(that.color) + && geodesic.equals(that.geodesic) + && jointType.equals(that.jointType) + && patterns.equals(that.patterns) + && points.equals(that.points) + && startCap.equals(that.startCap) + && endCap.equals(that.endCap) + && visible.equals(that.visible) + && width.equals(that.width) + && zIndex.equals(that.zIndex); + } + + @Override + public int hashCode() { + return Objects.hash( + polylineId, + consumesTapEvents, + color, + geodesic, + jointType, + patterns, + points, + startCap, + endCap, + visible, + width, + zIndex); + } + + public static final class Builder { + + private @Nullable String polylineId; + + @CanIgnoreReturnValue + public @NonNull Builder setPolylineId(@NonNull String setterArg) { + this.polylineId = setterArg; + return this; + } + + private @Nullable Boolean consumesTapEvents; + + @CanIgnoreReturnValue + public @NonNull Builder setConsumesTapEvents(@NonNull Boolean setterArg) { + this.consumesTapEvents = setterArg; + return this; + } + + private @Nullable Long color; + + @CanIgnoreReturnValue + public @NonNull Builder setColor(@NonNull Long setterArg) { + this.color = setterArg; + return this; + } + + private @Nullable Boolean geodesic; + + @CanIgnoreReturnValue + public @NonNull Builder setGeodesic(@NonNull Boolean setterArg) { + this.geodesic = setterArg; + return this; + } + + private @Nullable PlatformJointType jointType; + + @CanIgnoreReturnValue + public @NonNull Builder setJointType(@NonNull PlatformJointType setterArg) { + this.jointType = setterArg; + return this; + } + + private @Nullable List patterns; + + @CanIgnoreReturnValue + public @NonNull Builder setPatterns(@NonNull List setterArg) { + this.patterns = setterArg; + return this; + } + + private @Nullable List points; + + @CanIgnoreReturnValue + public @NonNull Builder setPoints(@NonNull List setterArg) { + this.points = setterArg; + return this; + } + + private @Nullable PlatformCap startCap; + + @CanIgnoreReturnValue + public @NonNull Builder setStartCap(@NonNull PlatformCap setterArg) { + this.startCap = setterArg; + return this; + } + + private @Nullable PlatformCap endCap; + + @CanIgnoreReturnValue + public @NonNull Builder setEndCap(@NonNull PlatformCap setterArg) { + this.endCap = setterArg; + return this; + } + + private @Nullable Boolean visible; + + @CanIgnoreReturnValue + public @NonNull Builder setVisible(@NonNull Boolean setterArg) { + this.visible = setterArg; + return this; + } + + private @Nullable Long width; + + @CanIgnoreReturnValue + public @NonNull Builder setWidth(@NonNull Long setterArg) { + this.width = setterArg; + return this; + } + + private @Nullable Long zIndex; + + @CanIgnoreReturnValue + public @NonNull Builder setZIndex(@NonNull Long setterArg) { + this.zIndex = setterArg; + return this; + } + + public @NonNull PlatformPolyline build() { + PlatformPolyline pigeonReturn = new PlatformPolyline(); + pigeonReturn.setPolylineId(polylineId); + pigeonReturn.setConsumesTapEvents(consumesTapEvents); + pigeonReturn.setColor(color); + pigeonReturn.setGeodesic(geodesic); + pigeonReturn.setJointType(jointType); + pigeonReturn.setPatterns(patterns); + pigeonReturn.setPoints(points); + pigeonReturn.setStartCap(startCap); + pigeonReturn.setEndCap(endCap); + pigeonReturn.setVisible(visible); + pigeonReturn.setWidth(width); + pigeonReturn.setZIndex(zIndex); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(12); + toListResult.add(polylineId); + toListResult.add(consumesTapEvents); + toListResult.add(color); + toListResult.add(geodesic); + toListResult.add(jointType); + toListResult.add(patterns); + toListResult.add(points); + toListResult.add(startCap); + toListResult.add(endCap); + toListResult.add(visible); + toListResult.add(width); + toListResult.add(zIndex); + return toListResult; + } + + static @NonNull PlatformPolyline fromList(@NonNull ArrayList pigeonVar_list) { + PlatformPolyline pigeonResult = new PlatformPolyline(); + Object polylineId = pigeonVar_list.get(0); + pigeonResult.setPolylineId((String) polylineId); + Object consumesTapEvents = pigeonVar_list.get(1); + pigeonResult.setConsumesTapEvents((Boolean) consumesTapEvents); + Object color = pigeonVar_list.get(2); + pigeonResult.setColor((Long) color); + Object geodesic = pigeonVar_list.get(3); + pigeonResult.setGeodesic((Boolean) geodesic); + Object jointType = pigeonVar_list.get(4); + pigeonResult.setJointType((PlatformJointType) jointType); + Object patterns = pigeonVar_list.get(5); + pigeonResult.setPatterns((List) patterns); + Object points = pigeonVar_list.get(6); + pigeonResult.setPoints((List) points); + Object startCap = pigeonVar_list.get(7); + pigeonResult.setStartCap((PlatformCap) startCap); + Object endCap = pigeonVar_list.get(8); + pigeonResult.setEndCap((PlatformCap) endCap); + Object visible = pigeonVar_list.get(9); + pigeonResult.setVisible((Boolean) visible); + Object width = pigeonVar_list.get(10); + pigeonResult.setWidth((Long) width); + Object zIndex = pigeonVar_list.get(11); + pigeonResult.setZIndex((Long) zIndex); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of Cap from the platform interface. + * https://github.com/flutter/packages/blob/main/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/cap.dart + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformCap { + private @NonNull PlatformCapType type; + + public @NonNull PlatformCapType getType() { + return type; + } + + public void setType(@NonNull PlatformCapType setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"type\" is null."); + } + this.type = setterArg; + } + + private @Nullable PlatformBitmap bitmapDescriptor; + + public @Nullable PlatformBitmap getBitmapDescriptor() { + return bitmapDescriptor; + } + + public void setBitmapDescriptor(@Nullable PlatformBitmap setterArg) { + this.bitmapDescriptor = setterArg; + } + + private @Nullable Double refWidth; + + public @Nullable Double getRefWidth() { + return refWidth; + } + + public void setRefWidth(@Nullable Double setterArg) { + this.refWidth = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformCap() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformCap that = (PlatformCap) o; + return type.equals(that.type) + && Objects.equals(bitmapDescriptor, that.bitmapDescriptor) + && Objects.equals(refWidth, that.refWidth); + } + + @Override + public int hashCode() { + return Objects.hash(type, bitmapDescriptor, refWidth); + } + + public static final class Builder { + + private @Nullable PlatformCapType type; + + @CanIgnoreReturnValue + public @NonNull Builder setType(@NonNull PlatformCapType setterArg) { + this.type = setterArg; + return this; + } + + private @Nullable PlatformBitmap bitmapDescriptor; + + @CanIgnoreReturnValue + public @NonNull Builder setBitmapDescriptor(@Nullable PlatformBitmap setterArg) { + this.bitmapDescriptor = setterArg; + return this; + } + + private @Nullable Double refWidth; + + @CanIgnoreReturnValue + public @NonNull Builder setRefWidth(@Nullable Double setterArg) { + this.refWidth = setterArg; + return this; + } + + public @NonNull PlatformCap build() { + PlatformCap pigeonReturn = new PlatformCap(); + pigeonReturn.setType(type); + pigeonReturn.setBitmapDescriptor(bitmapDescriptor); + pigeonReturn.setRefWidth(refWidth); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(3); + toListResult.add(type); + toListResult.add(bitmapDescriptor); + toListResult.add(refWidth); + return toListResult; + } + + static @NonNull PlatformCap fromList(@NonNull ArrayList pigeonVar_list) { + PlatformCap pigeonResult = new PlatformCap(); + Object type = pigeonVar_list.get(0); + pigeonResult.setType((PlatformCapType) type); + Object bitmapDescriptor = pigeonVar_list.get(1); + pigeonResult.setBitmapDescriptor((PlatformBitmap) bitmapDescriptor); + Object refWidth = pigeonVar_list.get(2); + pigeonResult.setRefWidth((Double) refWidth); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of the PatternItem class. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformPatternItem { + private @NonNull PlatformPatternItemType type; + + public @NonNull PlatformPatternItemType getType() { + return type; + } + + public void setType(@NonNull PlatformPatternItemType setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"type\" is null."); + } + this.type = setterArg; + } + + private @Nullable Double length; + + public @Nullable Double getLength() { + return length; + } + + public void setLength(@Nullable Double setterArg) { + this.length = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformPatternItem() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformPatternItem that = (PlatformPatternItem) o; + return type.equals(that.type) && Objects.equals(length, that.length); + } + + @Override + public int hashCode() { + return Objects.hash(type, length); + } + + public static final class Builder { + + private @Nullable PlatformPatternItemType type; + + @CanIgnoreReturnValue + public @NonNull Builder setType(@NonNull PlatformPatternItemType setterArg) { + this.type = setterArg; + return this; + } + + private @Nullable Double length; + + @CanIgnoreReturnValue + public @NonNull Builder setLength(@Nullable Double setterArg) { + this.length = setterArg; + return this; + } + + public @NonNull PlatformPatternItem build() { + PlatformPatternItem pigeonReturn = new PlatformPatternItem(); + pigeonReturn.setType(type); + pigeonReturn.setLength(length); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(2); + toListResult.add(type); + toListResult.add(length); + return toListResult; + } + + static @NonNull PlatformPatternItem fromList(@NonNull ArrayList pigeonVar_list) { + PlatformPatternItem pigeonResult = new PlatformPatternItem(); + Object type = pigeonVar_list.get(0); + pigeonResult.setType((PlatformPatternItemType) type); + Object length = pigeonVar_list.get(1); + pigeonResult.setLength((Double) length); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of the Tile class. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformTile { + private @NonNull Long width; + + public @NonNull Long getWidth() { + return width; + } + + public void setWidth(@NonNull Long setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"width\" is null."); + } + this.width = setterArg; + } + + private @NonNull Long height; + + public @NonNull Long getHeight() { + return height; + } + + public void setHeight(@NonNull Long setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"height\" is null."); + } + this.height = setterArg; + } + + private @Nullable byte[] data; + + public @Nullable byte[] getData() { + return data; + } + + public void setData(@Nullable byte[] setterArg) { + this.data = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformTile() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformTile that = (PlatformTile) o; + return width.equals(that.width) + && height.equals(that.height) + && Arrays.equals(data, that.data); + } + + @Override + public int hashCode() { + int pigeonVar_result = Objects.hash(width, height); + pigeonVar_result = 31 * pigeonVar_result + Arrays.hashCode(data); + return pigeonVar_result; + } + + public static final class Builder { + + private @Nullable Long width; + + @CanIgnoreReturnValue + public @NonNull Builder setWidth(@NonNull Long setterArg) { + this.width = setterArg; + return this; + } + + private @Nullable Long height; + + @CanIgnoreReturnValue + public @NonNull Builder setHeight(@NonNull Long setterArg) { + this.height = setterArg; + return this; + } + + private @Nullable byte[] data; + + @CanIgnoreReturnValue + public @NonNull Builder setData(@Nullable byte[] setterArg) { + this.data = setterArg; + return this; + } + + public @NonNull PlatformTile build() { + PlatformTile pigeonReturn = new PlatformTile(); + pigeonReturn.setWidth(width); + pigeonReturn.setHeight(height); + pigeonReturn.setData(data); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(3); + toListResult.add(width); + toListResult.add(height); + toListResult.add(data); + return toListResult; + } + + static @NonNull PlatformTile fromList(@NonNull ArrayList pigeonVar_list) { + PlatformTile pigeonResult = new PlatformTile(); + Object width = pigeonVar_list.get(0); + pigeonResult.setWidth((Long) width); + Object height = pigeonVar_list.get(1); + pigeonResult.setHeight((Long) height); + Object data = pigeonVar_list.get(2); + pigeonResult.setData((byte[]) data); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of the TileOverlay class. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformTileOverlay { + private @NonNull String tileOverlayId; + + public @NonNull String getTileOverlayId() { + return tileOverlayId; + } + + public void setTileOverlayId(@NonNull String setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"tileOverlayId\" is null."); + } + this.tileOverlayId = setterArg; + } + + private @NonNull Boolean fadeIn; + + public @NonNull Boolean getFadeIn() { + return fadeIn; + } + + public void setFadeIn(@NonNull Boolean setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"fadeIn\" is null."); + } + this.fadeIn = setterArg; + } + + private @NonNull Double transparency; + + public @NonNull Double getTransparency() { + return transparency; + } + + public void setTransparency(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"transparency\" is null."); + } + this.transparency = setterArg; + } + + private @NonNull Long zIndex; + + public @NonNull Long getZIndex() { + return zIndex; + } + + public void setZIndex(@NonNull Long setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"zIndex\" is null."); + } + this.zIndex = setterArg; + } + + private @NonNull Boolean visible; + + public @NonNull Boolean getVisible() { + return visible; + } + + public void setVisible(@NonNull Boolean setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"visible\" is null."); + } + this.visible = setterArg; + } + + private @NonNull Long tileSize; + + public @NonNull Long getTileSize() { + return tileSize; + } + + public void setTileSize(@NonNull Long setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"tileSize\" is null."); + } + this.tileSize = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformTileOverlay() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformTileOverlay that = (PlatformTileOverlay) o; + return tileOverlayId.equals(that.tileOverlayId) + && fadeIn.equals(that.fadeIn) + && transparency.equals(that.transparency) + && zIndex.equals(that.zIndex) + && visible.equals(that.visible) + && tileSize.equals(that.tileSize); + } + + @Override + public int hashCode() { + return Objects.hash(tileOverlayId, fadeIn, transparency, zIndex, visible, tileSize); + } + + public static final class Builder { + + private @Nullable String tileOverlayId; + + @CanIgnoreReturnValue + public @NonNull Builder setTileOverlayId(@NonNull String setterArg) { + this.tileOverlayId = setterArg; + return this; + } + + private @Nullable Boolean fadeIn; + + @CanIgnoreReturnValue + public @NonNull Builder setFadeIn(@NonNull Boolean setterArg) { + this.fadeIn = setterArg; + return this; + } + + private @Nullable Double transparency; + + @CanIgnoreReturnValue + public @NonNull Builder setTransparency(@NonNull Double setterArg) { + this.transparency = setterArg; + return this; + } + + private @Nullable Long zIndex; + + @CanIgnoreReturnValue + public @NonNull Builder setZIndex(@NonNull Long setterArg) { + this.zIndex = setterArg; + return this; + } + + private @Nullable Boolean visible; + + @CanIgnoreReturnValue + public @NonNull Builder setVisible(@NonNull Boolean setterArg) { + this.visible = setterArg; + return this; + } + + private @Nullable Long tileSize; + + @CanIgnoreReturnValue + public @NonNull Builder setTileSize(@NonNull Long setterArg) { + this.tileSize = setterArg; + return this; + } + + public @NonNull PlatformTileOverlay build() { + PlatformTileOverlay pigeonReturn = new PlatformTileOverlay(); + pigeonReturn.setTileOverlayId(tileOverlayId); + pigeonReturn.setFadeIn(fadeIn); + pigeonReturn.setTransparency(transparency); + pigeonReturn.setZIndex(zIndex); + pigeonReturn.setVisible(visible); + pigeonReturn.setTileSize(tileSize); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(6); + toListResult.add(tileOverlayId); + toListResult.add(fadeIn); + toListResult.add(transparency); + toListResult.add(zIndex); + toListResult.add(visible); + toListResult.add(tileSize); + return toListResult; + } + + static @NonNull PlatformTileOverlay fromList(@NonNull ArrayList pigeonVar_list) { + PlatformTileOverlay pigeonResult = new PlatformTileOverlay(); + Object tileOverlayId = pigeonVar_list.get(0); + pigeonResult.setTileOverlayId((String) tileOverlayId); + Object fadeIn = pigeonVar_list.get(1); + pigeonResult.setFadeIn((Boolean) fadeIn); + Object transparency = pigeonVar_list.get(2); + pigeonResult.setTransparency((Double) transparency); + Object zIndex = pigeonVar_list.get(3); + pigeonResult.setZIndex((Long) zIndex); + Object visible = pigeonVar_list.get(4); + pigeonResult.setVisible((Boolean) visible); + Object tileSize = pigeonVar_list.get(5); + pigeonResult.setTileSize((Long) tileSize); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of Flutter's EdgeInsets. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformEdgeInsets { + private @NonNull Double top; + + public @NonNull Double getTop() { + return top; + } + + public void setTop(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"top\" is null."); + } + this.top = setterArg; + } + + private @NonNull Double bottom; + + public @NonNull Double getBottom() { + return bottom; + } + + public void setBottom(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"bottom\" is null."); + } + this.bottom = setterArg; + } + + private @NonNull Double left; + + public @NonNull Double getLeft() { + return left; + } + + public void setLeft(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"left\" is null."); + } + this.left = setterArg; + } + + private @NonNull Double right; + + public @NonNull Double getRight() { + return right; + } + + public void setRight(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"right\" is null."); + } + this.right = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformEdgeInsets() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformEdgeInsets that = (PlatformEdgeInsets) o; + return top.equals(that.top) + && bottom.equals(that.bottom) + && left.equals(that.left) + && right.equals(that.right); + } + + @Override + public int hashCode() { + return Objects.hash(top, bottom, left, right); + } + + public static final class Builder { + + private @Nullable Double top; + + @CanIgnoreReturnValue + public @NonNull Builder setTop(@NonNull Double setterArg) { + this.top = setterArg; + return this; + } + + private @Nullable Double bottom; + + @CanIgnoreReturnValue + public @NonNull Builder setBottom(@NonNull Double setterArg) { + this.bottom = setterArg; + return this; + } + + private @Nullable Double left; + + @CanIgnoreReturnValue + public @NonNull Builder setLeft(@NonNull Double setterArg) { + this.left = setterArg; + return this; + } + + private @Nullable Double right; + + @CanIgnoreReturnValue + public @NonNull Builder setRight(@NonNull Double setterArg) { + this.right = setterArg; + return this; + } + + public @NonNull PlatformEdgeInsets build() { + PlatformEdgeInsets pigeonReturn = new PlatformEdgeInsets(); + pigeonReturn.setTop(top); + pigeonReturn.setBottom(bottom); + pigeonReturn.setLeft(left); + pigeonReturn.setRight(right); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(4); + toListResult.add(top); + toListResult.add(bottom); + toListResult.add(left); + toListResult.add(right); + return toListResult; + } + + static @NonNull PlatformEdgeInsets fromList(@NonNull ArrayList pigeonVar_list) { + PlatformEdgeInsets pigeonResult = new PlatformEdgeInsets(); + Object top = pigeonVar_list.get(0); + pigeonResult.setTop((Double) top); + Object bottom = pigeonVar_list.get(1); + pigeonResult.setBottom((Double) bottom); + Object left = pigeonVar_list.get(2); + pigeonResult.setLeft((Double) left); + Object right = pigeonVar_list.get(3); + pigeonResult.setRight((Double) right); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of LatLng. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformLatLng { + private @NonNull Double latitude; + + public @NonNull Double getLatitude() { + return latitude; + } + + public void setLatitude(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"latitude\" is null."); + } + this.latitude = setterArg; + } + + private @NonNull Double longitude; + + public @NonNull Double getLongitude() { + return longitude; + } + + public void setLongitude(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"longitude\" is null."); + } + this.longitude = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformLatLng() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformLatLng that = (PlatformLatLng) o; + return latitude.equals(that.latitude) && longitude.equals(that.longitude); + } + + @Override + public int hashCode() { + return Objects.hash(latitude, longitude); + } + + public static final class Builder { + + private @Nullable Double latitude; + + @CanIgnoreReturnValue + public @NonNull Builder setLatitude(@NonNull Double setterArg) { + this.latitude = setterArg; + return this; + } + + private @Nullable Double longitude; + + @CanIgnoreReturnValue + public @NonNull Builder setLongitude(@NonNull Double setterArg) { + this.longitude = setterArg; + return this; + } + + public @NonNull PlatformLatLng build() { + PlatformLatLng pigeonReturn = new PlatformLatLng(); + pigeonReturn.setLatitude(latitude); + pigeonReturn.setLongitude(longitude); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(2); + toListResult.add(latitude); + toListResult.add(longitude); + return toListResult; + } + + static @NonNull PlatformLatLng fromList(@NonNull ArrayList pigeonVar_list) { + PlatformLatLng pigeonResult = new PlatformLatLng(); + Object latitude = pigeonVar_list.get(0); + pigeonResult.setLatitude((Double) latitude); + Object longitude = pigeonVar_list.get(1); + pigeonResult.setLongitude((Double) longitude); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of LatLngBounds. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformLatLngBounds { + private @NonNull PlatformLatLng northeast; + + public @NonNull PlatformLatLng getNortheast() { + return northeast; + } + + public void setNortheast(@NonNull PlatformLatLng setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"northeast\" is null."); + } + this.northeast = setterArg; + } + + private @NonNull PlatformLatLng southwest; + + public @NonNull PlatformLatLng getSouthwest() { + return southwest; + } + + public void setSouthwest(@NonNull PlatformLatLng setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"southwest\" is null."); + } + this.southwest = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformLatLngBounds() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformLatLngBounds that = (PlatformLatLngBounds) o; + return northeast.equals(that.northeast) && southwest.equals(that.southwest); + } + + @Override + public int hashCode() { + return Objects.hash(northeast, southwest); + } + + public static final class Builder { + + private @Nullable PlatformLatLng northeast; + + @CanIgnoreReturnValue + public @NonNull Builder setNortheast(@NonNull PlatformLatLng setterArg) { + this.northeast = setterArg; + return this; + } + + private @Nullable PlatformLatLng southwest; + + @CanIgnoreReturnValue + public @NonNull Builder setSouthwest(@NonNull PlatformLatLng setterArg) { + this.southwest = setterArg; + return this; + } + + public @NonNull PlatformLatLngBounds build() { + PlatformLatLngBounds pigeonReturn = new PlatformLatLngBounds(); + pigeonReturn.setNortheast(northeast); + pigeonReturn.setSouthwest(southwest); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(2); + toListResult.add(northeast); + toListResult.add(southwest); + return toListResult; + } + + static @NonNull PlatformLatLngBounds fromList(@NonNull ArrayList pigeonVar_list) { + PlatformLatLngBounds pigeonResult = new PlatformLatLngBounds(); + Object northeast = pigeonVar_list.get(0); + pigeonResult.setNortheast((PlatformLatLng) northeast); + Object southwest = pigeonVar_list.get(1); + pigeonResult.setSouthwest((PlatformLatLng) southwest); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of Cluster. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformCluster { + private @NonNull String clusterManagerId; + + public @NonNull String getClusterManagerId() { + return clusterManagerId; + } + + public void setClusterManagerId(@NonNull String setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"clusterManagerId\" is null."); + } + this.clusterManagerId = setterArg; + } + + private @NonNull PlatformLatLng position; + + public @NonNull PlatformLatLng getPosition() { + return position; + } + + public void setPosition(@NonNull PlatformLatLng setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"position\" is null."); + } + this.position = setterArg; + } + + private @NonNull PlatformLatLngBounds bounds; + + public @NonNull PlatformLatLngBounds getBounds() { + return bounds; + } + + public void setBounds(@NonNull PlatformLatLngBounds setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"bounds\" is null."); + } + this.bounds = setterArg; + } + + private @NonNull List markerIds; + + public @NonNull List getMarkerIds() { + return markerIds; + } + + public void setMarkerIds(@NonNull List setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"markerIds\" is null."); + } + this.markerIds = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformCluster() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformCluster that = (PlatformCluster) o; + return clusterManagerId.equals(that.clusterManagerId) + && position.equals(that.position) + && bounds.equals(that.bounds) + && markerIds.equals(that.markerIds); + } + + @Override + public int hashCode() { + return Objects.hash(clusterManagerId, position, bounds, markerIds); + } + + public static final class Builder { + + private @Nullable String clusterManagerId; + + @CanIgnoreReturnValue + public @NonNull Builder setClusterManagerId(@NonNull String setterArg) { + this.clusterManagerId = setterArg; + return this; + } + + private @Nullable PlatformLatLng position; + + @CanIgnoreReturnValue + public @NonNull Builder setPosition(@NonNull PlatformLatLng setterArg) { + this.position = setterArg; + return this; + } + + private @Nullable PlatformLatLngBounds bounds; + + @CanIgnoreReturnValue + public @NonNull Builder setBounds(@NonNull PlatformLatLngBounds setterArg) { + this.bounds = setterArg; + return this; + } + + private @Nullable List markerIds; + + @CanIgnoreReturnValue + public @NonNull Builder setMarkerIds(@NonNull List setterArg) { + this.markerIds = setterArg; + return this; + } + + public @NonNull PlatformCluster build() { + PlatformCluster pigeonReturn = new PlatformCluster(); + pigeonReturn.setClusterManagerId(clusterManagerId); + pigeonReturn.setPosition(position); + pigeonReturn.setBounds(bounds); + pigeonReturn.setMarkerIds(markerIds); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(4); + toListResult.add(clusterManagerId); + toListResult.add(position); + toListResult.add(bounds); + toListResult.add(markerIds); + return toListResult; + } + + static @NonNull PlatformCluster fromList(@NonNull ArrayList pigeonVar_list) { + PlatformCluster pigeonResult = new PlatformCluster(); + Object clusterManagerId = pigeonVar_list.get(0); + pigeonResult.setClusterManagerId((String) clusterManagerId); + Object position = pigeonVar_list.get(1); + pigeonResult.setPosition((PlatformLatLng) position); + Object bounds = pigeonVar_list.get(2); + pigeonResult.setBounds((PlatformLatLngBounds) bounds); + Object markerIds = pigeonVar_list.get(3); + pigeonResult.setMarkerIds((List) markerIds); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of CameraTargetBounds. + * + *

As with the Dart version, it exists to distinguish between not setting a a target, and + * having an explicitly unbounded target (null [bounds]). + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformCameraTargetBounds { + private @Nullable PlatformLatLngBounds bounds; + + public @Nullable PlatformLatLngBounds getBounds() { + return bounds; + } + + public void setBounds(@Nullable PlatformLatLngBounds setterArg) { + this.bounds = setterArg; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformCameraTargetBounds that = (PlatformCameraTargetBounds) o; + return Objects.equals(bounds, that.bounds); + } + + @Override + public int hashCode() { + return Objects.hash(bounds); + } + + public static final class Builder { + + private @Nullable PlatformLatLngBounds bounds; + + @CanIgnoreReturnValue + public @NonNull Builder setBounds(@Nullable PlatformLatLngBounds setterArg) { + this.bounds = setterArg; + return this; + } + + public @NonNull PlatformCameraTargetBounds build() { + PlatformCameraTargetBounds pigeonReturn = new PlatformCameraTargetBounds(); + pigeonReturn.setBounds(bounds); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(1); + toListResult.add(bounds); + return toListResult; + } + + static @NonNull PlatformCameraTargetBounds fromList(@NonNull ArrayList pigeonVar_list) { + PlatformCameraTargetBounds pigeonResult = new PlatformCameraTargetBounds(); + Object bounds = pigeonVar_list.get(0); + pigeonResult.setBounds((PlatformLatLngBounds) bounds); + return pigeonResult; + } + } + + /** + * Information passed to the platform view creation. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformMapViewCreationParams { + private @NonNull PlatformCameraPosition initialCameraPosition; + + public @NonNull PlatformCameraPosition getInitialCameraPosition() { + return initialCameraPosition; + } + + public void setInitialCameraPosition(@NonNull PlatformCameraPosition setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"initialCameraPosition\" is null."); + } + this.initialCameraPosition = setterArg; + } + + private @NonNull PlatformMapConfiguration mapConfiguration; + + public @NonNull PlatformMapConfiguration getMapConfiguration() { + return mapConfiguration; + } + + public void setMapConfiguration(@NonNull PlatformMapConfiguration setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"mapConfiguration\" is null."); + } + this.mapConfiguration = setterArg; + } + + private @NonNull List initialCircles; + + public @NonNull List getInitialCircles() { + return initialCircles; + } + + public void setInitialCircles(@NonNull List setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"initialCircles\" is null."); + } + this.initialCircles = setterArg; + } + + private @NonNull List initialMarkers; + + public @NonNull List getInitialMarkers() { + return initialMarkers; + } + + public void setInitialMarkers(@NonNull List setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"initialMarkers\" is null."); + } + this.initialMarkers = setterArg; + } + + private @NonNull List initialPolygons; + + public @NonNull List getInitialPolygons() { + return initialPolygons; + } + + public void setInitialPolygons(@NonNull List setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"initialPolygons\" is null."); + } + this.initialPolygons = setterArg; + } + + private @NonNull List initialPolylines; + + public @NonNull List getInitialPolylines() { + return initialPolylines; + } + + public void setInitialPolylines(@NonNull List setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"initialPolylines\" is null."); + } + this.initialPolylines = setterArg; + } + + private @NonNull List initialHeatmaps; + + public @NonNull List getInitialHeatmaps() { + return initialHeatmaps; + } + + public void setInitialHeatmaps(@NonNull List setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"initialHeatmaps\" is null."); + } + this.initialHeatmaps = setterArg; + } + + private @NonNull List initialTileOverlays; + + public @NonNull List getInitialTileOverlays() { + return initialTileOverlays; + } + + public void setInitialTileOverlays(@NonNull List setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"initialTileOverlays\" is null."); + } + this.initialTileOverlays = setterArg; + } + + private @NonNull List initialClusterManagers; + + public @NonNull List getInitialClusterManagers() { + return initialClusterManagers; + } + + public void setInitialClusterManagers(@NonNull List setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"initialClusterManagers\" is null."); + } + this.initialClusterManagers = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformMapViewCreationParams() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformMapViewCreationParams that = (PlatformMapViewCreationParams) o; + return initialCameraPosition.equals(that.initialCameraPosition) + && mapConfiguration.equals(that.mapConfiguration) + && initialCircles.equals(that.initialCircles) + && initialMarkers.equals(that.initialMarkers) + && initialPolygons.equals(that.initialPolygons) + && initialPolylines.equals(that.initialPolylines) + && initialHeatmaps.equals(that.initialHeatmaps) + && initialTileOverlays.equals(that.initialTileOverlays) + && initialClusterManagers.equals(that.initialClusterManagers); + } + + @Override + public int hashCode() { + return Objects.hash( + initialCameraPosition, + mapConfiguration, + initialCircles, + initialMarkers, + initialPolygons, + initialPolylines, + initialHeatmaps, + initialTileOverlays, + initialClusterManagers); + } + + public static final class Builder { + + private @Nullable PlatformCameraPosition initialCameraPosition; + + @CanIgnoreReturnValue + public @NonNull Builder setInitialCameraPosition(@NonNull PlatformCameraPosition setterArg) { + this.initialCameraPosition = setterArg; + return this; + } + + private @Nullable PlatformMapConfiguration mapConfiguration; + + @CanIgnoreReturnValue + public @NonNull Builder setMapConfiguration(@NonNull PlatformMapConfiguration setterArg) { + this.mapConfiguration = setterArg; + return this; + } + + private @Nullable List initialCircles; + + @CanIgnoreReturnValue + public @NonNull Builder setInitialCircles(@NonNull List setterArg) { + this.initialCircles = setterArg; + return this; + } + + private @Nullable List initialMarkers; + + @CanIgnoreReturnValue + public @NonNull Builder setInitialMarkers(@NonNull List setterArg) { + this.initialMarkers = setterArg; + return this; + } + + private @Nullable List initialPolygons; + + @CanIgnoreReturnValue + public @NonNull Builder setInitialPolygons(@NonNull List setterArg) { + this.initialPolygons = setterArg; + return this; + } + + private @Nullable List initialPolylines; + + @CanIgnoreReturnValue + public @NonNull Builder setInitialPolylines(@NonNull List setterArg) { + this.initialPolylines = setterArg; + return this; + } + + private @Nullable List initialHeatmaps; + + @CanIgnoreReturnValue + public @NonNull Builder setInitialHeatmaps(@NonNull List setterArg) { + this.initialHeatmaps = setterArg; + return this; + } + + private @Nullable List initialTileOverlays; + + @CanIgnoreReturnValue + public @NonNull Builder setInitialTileOverlays(@NonNull List setterArg) { + this.initialTileOverlays = setterArg; + return this; + } + + private @Nullable List initialClusterManagers; + + @CanIgnoreReturnValue + public @NonNull Builder setInitialClusterManagers( + @NonNull List setterArg) { + this.initialClusterManagers = setterArg; + return this; + } + + public @NonNull PlatformMapViewCreationParams build() { + PlatformMapViewCreationParams pigeonReturn = new PlatformMapViewCreationParams(); + pigeonReturn.setInitialCameraPosition(initialCameraPosition); + pigeonReturn.setMapConfiguration(mapConfiguration); + pigeonReturn.setInitialCircles(initialCircles); + pigeonReturn.setInitialMarkers(initialMarkers); + pigeonReturn.setInitialPolygons(initialPolygons); + pigeonReturn.setInitialPolylines(initialPolylines); + pigeonReturn.setInitialHeatmaps(initialHeatmaps); + pigeonReturn.setInitialTileOverlays(initialTileOverlays); + pigeonReturn.setInitialClusterManagers(initialClusterManagers); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(9); + toListResult.add(initialCameraPosition); + toListResult.add(mapConfiguration); + toListResult.add(initialCircles); + toListResult.add(initialMarkers); + toListResult.add(initialPolygons); + toListResult.add(initialPolylines); + toListResult.add(initialHeatmaps); + toListResult.add(initialTileOverlays); + toListResult.add(initialClusterManagers); + return toListResult; + } + + static @NonNull PlatformMapViewCreationParams fromList( + @NonNull ArrayList pigeonVar_list) { + PlatformMapViewCreationParams pigeonResult = new PlatformMapViewCreationParams(); + Object initialCameraPosition = pigeonVar_list.get(0); + pigeonResult.setInitialCameraPosition((PlatformCameraPosition) initialCameraPosition); + Object mapConfiguration = pigeonVar_list.get(1); + pigeonResult.setMapConfiguration((PlatformMapConfiguration) mapConfiguration); + Object initialCircles = pigeonVar_list.get(2); + pigeonResult.setInitialCircles((List) initialCircles); + Object initialMarkers = pigeonVar_list.get(3); + pigeonResult.setInitialMarkers((List) initialMarkers); + Object initialPolygons = pigeonVar_list.get(4); + pigeonResult.setInitialPolygons((List) initialPolygons); + Object initialPolylines = pigeonVar_list.get(5); + pigeonResult.setInitialPolylines((List) initialPolylines); + Object initialHeatmaps = pigeonVar_list.get(6); + pigeonResult.setInitialHeatmaps((List) initialHeatmaps); + Object initialTileOverlays = pigeonVar_list.get(7); + pigeonResult.setInitialTileOverlays((List) initialTileOverlays); + Object initialClusterManagers = pigeonVar_list.get(8); + pigeonResult.setInitialClusterManagers((List) initialClusterManagers); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of MapConfiguration. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformMapConfiguration { + private @Nullable Boolean compassEnabled; + + public @Nullable Boolean getCompassEnabled() { + return compassEnabled; + } + + public void setCompassEnabled(@Nullable Boolean setterArg) { + this.compassEnabled = setterArg; + } + + private @Nullable PlatformCameraTargetBounds cameraTargetBounds; + + public @Nullable PlatformCameraTargetBounds getCameraTargetBounds() { + return cameraTargetBounds; + } + + public void setCameraTargetBounds(@Nullable PlatformCameraTargetBounds setterArg) { + this.cameraTargetBounds = setterArg; + } + + private @Nullable PlatformMapType mapType; + + public @Nullable PlatformMapType getMapType() { + return mapType; + } + + public void setMapType(@Nullable PlatformMapType setterArg) { + this.mapType = setterArg; + } + + private @Nullable PlatformZoomRange minMaxZoomPreference; + + public @Nullable PlatformZoomRange getMinMaxZoomPreference() { + return minMaxZoomPreference; + } + + public void setMinMaxZoomPreference(@Nullable PlatformZoomRange setterArg) { + this.minMaxZoomPreference = setterArg; + } + + private @Nullable Boolean mapToolbarEnabled; + + public @Nullable Boolean getMapToolbarEnabled() { + return mapToolbarEnabled; + } + + public void setMapToolbarEnabled(@Nullable Boolean setterArg) { + this.mapToolbarEnabled = setterArg; + } + + private @Nullable Boolean rotateGesturesEnabled; + + public @Nullable Boolean getRotateGesturesEnabled() { + return rotateGesturesEnabled; + } + + public void setRotateGesturesEnabled(@Nullable Boolean setterArg) { + this.rotateGesturesEnabled = setterArg; + } + + private @Nullable Boolean scrollGesturesEnabled; + + public @Nullable Boolean getScrollGesturesEnabled() { + return scrollGesturesEnabled; + } + + public void setScrollGesturesEnabled(@Nullable Boolean setterArg) { + this.scrollGesturesEnabled = setterArg; + } + + private @Nullable Boolean tiltGesturesEnabled; + + public @Nullable Boolean getTiltGesturesEnabled() { + return tiltGesturesEnabled; + } + + public void setTiltGesturesEnabled(@Nullable Boolean setterArg) { + this.tiltGesturesEnabled = setterArg; + } + + private @Nullable Boolean trackCameraPosition; + + public @Nullable Boolean getTrackCameraPosition() { + return trackCameraPosition; + } + + public void setTrackCameraPosition(@Nullable Boolean setterArg) { + this.trackCameraPosition = setterArg; + } + + private @Nullable Boolean zoomControlsEnabled; + + public @Nullable Boolean getZoomControlsEnabled() { + return zoomControlsEnabled; + } + + public void setZoomControlsEnabled(@Nullable Boolean setterArg) { + this.zoomControlsEnabled = setterArg; + } + + private @Nullable Boolean zoomGesturesEnabled; + + public @Nullable Boolean getZoomGesturesEnabled() { + return zoomGesturesEnabled; + } + + public void setZoomGesturesEnabled(@Nullable Boolean setterArg) { + this.zoomGesturesEnabled = setterArg; + } + + private @Nullable Boolean myLocationEnabled; + + public @Nullable Boolean getMyLocationEnabled() { + return myLocationEnabled; + } + + public void setMyLocationEnabled(@Nullable Boolean setterArg) { + this.myLocationEnabled = setterArg; + } + + private @Nullable Boolean myLocationButtonEnabled; + + public @Nullable Boolean getMyLocationButtonEnabled() { + return myLocationButtonEnabled; + } + + public void setMyLocationButtonEnabled(@Nullable Boolean setterArg) { + this.myLocationButtonEnabled = setterArg; + } + + private @Nullable PlatformEdgeInsets padding; + + public @Nullable PlatformEdgeInsets getPadding() { + return padding; + } + + public void setPadding(@Nullable PlatformEdgeInsets setterArg) { + this.padding = setterArg; + } + + private @Nullable Boolean indoorViewEnabled; + + public @Nullable Boolean getIndoorViewEnabled() { + return indoorViewEnabled; + } + + public void setIndoorViewEnabled(@Nullable Boolean setterArg) { + this.indoorViewEnabled = setterArg; + } + + private @Nullable Boolean trafficEnabled; + + public @Nullable Boolean getTrafficEnabled() { + return trafficEnabled; + } + + public void setTrafficEnabled(@Nullable Boolean setterArg) { + this.trafficEnabled = setterArg; + } + + private @Nullable Boolean buildingsEnabled; + + public @Nullable Boolean getBuildingsEnabled() { + return buildingsEnabled; + } + + public void setBuildingsEnabled(@Nullable Boolean setterArg) { + this.buildingsEnabled = setterArg; + } + + private @Nullable Boolean liteModeEnabled; + + public @Nullable Boolean getLiteModeEnabled() { + return liteModeEnabled; + } + + public void setLiteModeEnabled(@Nullable Boolean setterArg) { + this.liteModeEnabled = setterArg; + } + + private @Nullable String cloudMapId; + + public @Nullable String getCloudMapId() { + return cloudMapId; + } + + public void setCloudMapId(@Nullable String setterArg) { + this.cloudMapId = setterArg; + } + + private @Nullable String style; + + public @Nullable String getStyle() { + return style; + } + + public void setStyle(@Nullable String setterArg) { + this.style = setterArg; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformMapConfiguration that = (PlatformMapConfiguration) o; + return Objects.equals(compassEnabled, that.compassEnabled) + && Objects.equals(cameraTargetBounds, that.cameraTargetBounds) + && Objects.equals(mapType, that.mapType) + && Objects.equals(minMaxZoomPreference, that.minMaxZoomPreference) + && Objects.equals(mapToolbarEnabled, that.mapToolbarEnabled) + && Objects.equals(rotateGesturesEnabled, that.rotateGesturesEnabled) + && Objects.equals(scrollGesturesEnabled, that.scrollGesturesEnabled) + && Objects.equals(tiltGesturesEnabled, that.tiltGesturesEnabled) + && Objects.equals(trackCameraPosition, that.trackCameraPosition) + && Objects.equals(zoomControlsEnabled, that.zoomControlsEnabled) + && Objects.equals(zoomGesturesEnabled, that.zoomGesturesEnabled) + && Objects.equals(myLocationEnabled, that.myLocationEnabled) + && Objects.equals(myLocationButtonEnabled, that.myLocationButtonEnabled) + && Objects.equals(padding, that.padding) + && Objects.equals(indoorViewEnabled, that.indoorViewEnabled) + && Objects.equals(trafficEnabled, that.trafficEnabled) + && Objects.equals(buildingsEnabled, that.buildingsEnabled) + && Objects.equals(liteModeEnabled, that.liteModeEnabled) + && Objects.equals(cloudMapId, that.cloudMapId) + && Objects.equals(style, that.style); + } + + @Override + public int hashCode() { + return Objects.hash( + compassEnabled, + cameraTargetBounds, + mapType, + minMaxZoomPreference, + mapToolbarEnabled, + rotateGesturesEnabled, + scrollGesturesEnabled, + tiltGesturesEnabled, + trackCameraPosition, + zoomControlsEnabled, + zoomGesturesEnabled, + myLocationEnabled, + myLocationButtonEnabled, + padding, + indoorViewEnabled, + trafficEnabled, + buildingsEnabled, + liteModeEnabled, + cloudMapId, + style); + } + + public static final class Builder { + + private @Nullable Boolean compassEnabled; + + @CanIgnoreReturnValue + public @NonNull Builder setCompassEnabled(@Nullable Boolean setterArg) { + this.compassEnabled = setterArg; + return this; + } + + private @Nullable PlatformCameraTargetBounds cameraTargetBounds; + + @CanIgnoreReturnValue + public @NonNull Builder setCameraTargetBounds( + @Nullable PlatformCameraTargetBounds setterArg) { + this.cameraTargetBounds = setterArg; + return this; + } + + private @Nullable PlatformMapType mapType; + + @CanIgnoreReturnValue + public @NonNull Builder setMapType(@Nullable PlatformMapType setterArg) { + this.mapType = setterArg; + return this; + } + + private @Nullable PlatformZoomRange minMaxZoomPreference; + + @CanIgnoreReturnValue + public @NonNull Builder setMinMaxZoomPreference(@Nullable PlatformZoomRange setterArg) { + this.minMaxZoomPreference = setterArg; + return this; + } + + private @Nullable Boolean mapToolbarEnabled; + + @CanIgnoreReturnValue + public @NonNull Builder setMapToolbarEnabled(@Nullable Boolean setterArg) { + this.mapToolbarEnabled = setterArg; + return this; + } + + private @Nullable Boolean rotateGesturesEnabled; + + @CanIgnoreReturnValue + public @NonNull Builder setRotateGesturesEnabled(@Nullable Boolean setterArg) { + this.rotateGesturesEnabled = setterArg; + return this; + } + + private @Nullable Boolean scrollGesturesEnabled; + + @CanIgnoreReturnValue + public @NonNull Builder setScrollGesturesEnabled(@Nullable Boolean setterArg) { + this.scrollGesturesEnabled = setterArg; + return this; + } + + private @Nullable Boolean tiltGesturesEnabled; + + @CanIgnoreReturnValue + public @NonNull Builder setTiltGesturesEnabled(@Nullable Boolean setterArg) { + this.tiltGesturesEnabled = setterArg; + return this; + } + + private @Nullable Boolean trackCameraPosition; + + @CanIgnoreReturnValue + public @NonNull Builder setTrackCameraPosition(@Nullable Boolean setterArg) { + this.trackCameraPosition = setterArg; + return this; + } + + private @Nullable Boolean zoomControlsEnabled; + + @CanIgnoreReturnValue + public @NonNull Builder setZoomControlsEnabled(@Nullable Boolean setterArg) { + this.zoomControlsEnabled = setterArg; + return this; + } + + private @Nullable Boolean zoomGesturesEnabled; + + @CanIgnoreReturnValue + public @NonNull Builder setZoomGesturesEnabled(@Nullable Boolean setterArg) { + this.zoomGesturesEnabled = setterArg; + return this; + } + + private @Nullable Boolean myLocationEnabled; + + @CanIgnoreReturnValue + public @NonNull Builder setMyLocationEnabled(@Nullable Boolean setterArg) { + this.myLocationEnabled = setterArg; + return this; + } + + private @Nullable Boolean myLocationButtonEnabled; + + @CanIgnoreReturnValue + public @NonNull Builder setMyLocationButtonEnabled(@Nullable Boolean setterArg) { + this.myLocationButtonEnabled = setterArg; + return this; + } + + private @Nullable PlatformEdgeInsets padding; + + @CanIgnoreReturnValue + public @NonNull Builder setPadding(@Nullable PlatformEdgeInsets setterArg) { + this.padding = setterArg; + return this; + } + + private @Nullable Boolean indoorViewEnabled; + + @CanIgnoreReturnValue + public @NonNull Builder setIndoorViewEnabled(@Nullable Boolean setterArg) { + this.indoorViewEnabled = setterArg; + return this; + } + + private @Nullable Boolean trafficEnabled; + + @CanIgnoreReturnValue + public @NonNull Builder setTrafficEnabled(@Nullable Boolean setterArg) { + this.trafficEnabled = setterArg; + return this; + } + + private @Nullable Boolean buildingsEnabled; + + @CanIgnoreReturnValue + public @NonNull Builder setBuildingsEnabled(@Nullable Boolean setterArg) { + this.buildingsEnabled = setterArg; + return this; + } + + private @Nullable Boolean liteModeEnabled; + + @CanIgnoreReturnValue + public @NonNull Builder setLiteModeEnabled(@Nullable Boolean setterArg) { + this.liteModeEnabled = setterArg; + return this; + } + + private @Nullable String cloudMapId; + + @CanIgnoreReturnValue + public @NonNull Builder setCloudMapId(@Nullable String setterArg) { + this.cloudMapId = setterArg; + return this; + } + + private @Nullable String style; + + @CanIgnoreReturnValue + public @NonNull Builder setStyle(@Nullable String setterArg) { + this.style = setterArg; + return this; + } + + public @NonNull PlatformMapConfiguration build() { + PlatformMapConfiguration pigeonReturn = new PlatformMapConfiguration(); + pigeonReturn.setCompassEnabled(compassEnabled); + pigeonReturn.setCameraTargetBounds(cameraTargetBounds); + pigeonReturn.setMapType(mapType); + pigeonReturn.setMinMaxZoomPreference(minMaxZoomPreference); + pigeonReturn.setMapToolbarEnabled(mapToolbarEnabled); + pigeonReturn.setRotateGesturesEnabled(rotateGesturesEnabled); + pigeonReturn.setScrollGesturesEnabled(scrollGesturesEnabled); + pigeonReturn.setTiltGesturesEnabled(tiltGesturesEnabled); + pigeonReturn.setTrackCameraPosition(trackCameraPosition); + pigeonReturn.setZoomControlsEnabled(zoomControlsEnabled); + pigeonReturn.setZoomGesturesEnabled(zoomGesturesEnabled); + pigeonReturn.setMyLocationEnabled(myLocationEnabled); + pigeonReturn.setMyLocationButtonEnabled(myLocationButtonEnabled); + pigeonReturn.setPadding(padding); + pigeonReturn.setIndoorViewEnabled(indoorViewEnabled); + pigeonReturn.setTrafficEnabled(trafficEnabled); + pigeonReturn.setBuildingsEnabled(buildingsEnabled); + pigeonReturn.setLiteModeEnabled(liteModeEnabled); + pigeonReturn.setCloudMapId(cloudMapId); + pigeonReturn.setStyle(style); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(20); + toListResult.add(compassEnabled); + toListResult.add(cameraTargetBounds); + toListResult.add(mapType); + toListResult.add(minMaxZoomPreference); + toListResult.add(mapToolbarEnabled); + toListResult.add(rotateGesturesEnabled); + toListResult.add(scrollGesturesEnabled); + toListResult.add(tiltGesturesEnabled); + toListResult.add(trackCameraPosition); + toListResult.add(zoomControlsEnabled); + toListResult.add(zoomGesturesEnabled); + toListResult.add(myLocationEnabled); + toListResult.add(myLocationButtonEnabled); + toListResult.add(padding); + toListResult.add(indoorViewEnabled); + toListResult.add(trafficEnabled); + toListResult.add(buildingsEnabled); + toListResult.add(liteModeEnabled); + toListResult.add(cloudMapId); + toListResult.add(style); + return toListResult; + } + + static @NonNull PlatformMapConfiguration fromList(@NonNull ArrayList pigeonVar_list) { + PlatformMapConfiguration pigeonResult = new PlatformMapConfiguration(); + Object compassEnabled = pigeonVar_list.get(0); + pigeonResult.setCompassEnabled((Boolean) compassEnabled); + Object cameraTargetBounds = pigeonVar_list.get(1); + pigeonResult.setCameraTargetBounds((PlatformCameraTargetBounds) cameraTargetBounds); + Object mapType = pigeonVar_list.get(2); + pigeonResult.setMapType((PlatformMapType) mapType); + Object minMaxZoomPreference = pigeonVar_list.get(3); + pigeonResult.setMinMaxZoomPreference((PlatformZoomRange) minMaxZoomPreference); + Object mapToolbarEnabled = pigeonVar_list.get(4); + pigeonResult.setMapToolbarEnabled((Boolean) mapToolbarEnabled); + Object rotateGesturesEnabled = pigeonVar_list.get(5); + pigeonResult.setRotateGesturesEnabled((Boolean) rotateGesturesEnabled); + Object scrollGesturesEnabled = pigeonVar_list.get(6); + pigeonResult.setScrollGesturesEnabled((Boolean) scrollGesturesEnabled); + Object tiltGesturesEnabled = pigeonVar_list.get(7); + pigeonResult.setTiltGesturesEnabled((Boolean) tiltGesturesEnabled); + Object trackCameraPosition = pigeonVar_list.get(8); + pigeonResult.setTrackCameraPosition((Boolean) trackCameraPosition); + Object zoomControlsEnabled = pigeonVar_list.get(9); + pigeonResult.setZoomControlsEnabled((Boolean) zoomControlsEnabled); + Object zoomGesturesEnabled = pigeonVar_list.get(10); + pigeonResult.setZoomGesturesEnabled((Boolean) zoomGesturesEnabled); + Object myLocationEnabled = pigeonVar_list.get(11); + pigeonResult.setMyLocationEnabled((Boolean) myLocationEnabled); + Object myLocationButtonEnabled = pigeonVar_list.get(12); + pigeonResult.setMyLocationButtonEnabled((Boolean) myLocationButtonEnabled); + Object padding = pigeonVar_list.get(13); + pigeonResult.setPadding((PlatformEdgeInsets) padding); + Object indoorViewEnabled = pigeonVar_list.get(14); + pigeonResult.setIndoorViewEnabled((Boolean) indoorViewEnabled); + Object trafficEnabled = pigeonVar_list.get(15); + pigeonResult.setTrafficEnabled((Boolean) trafficEnabled); + Object buildingsEnabled = pigeonVar_list.get(16); + pigeonResult.setBuildingsEnabled((Boolean) buildingsEnabled); + Object liteModeEnabled = pigeonVar_list.get(17); + pigeonResult.setLiteModeEnabled((Boolean) liteModeEnabled); + Object cloudMapId = pigeonVar_list.get(18); + pigeonResult.setCloudMapId((String) cloudMapId); + Object style = pigeonVar_list.get(19); + pigeonResult.setStyle((String) style); + return pigeonResult; + } + } + + /** + * Pigeon representation of an x,y coordinate. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformPoint { + private @NonNull Long x; + + public @NonNull Long getX() { + return x; + } + + public void setX(@NonNull Long setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"x\" is null."); + } + this.x = setterArg; + } + + private @NonNull Long y; + + public @NonNull Long getY() { + return y; + } + + public void setY(@NonNull Long setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"y\" is null."); + } + this.y = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformPoint() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformPoint that = (PlatformPoint) o; + return x.equals(that.x) && y.equals(that.y); + } + + @Override + public int hashCode() { + return Objects.hash(x, y); + } + + public static final class Builder { + + private @Nullable Long x; + + @CanIgnoreReturnValue + public @NonNull Builder setX(@NonNull Long setterArg) { + this.x = setterArg; + return this; + } + + private @Nullable Long y; + + @CanIgnoreReturnValue + public @NonNull Builder setY(@NonNull Long setterArg) { + this.y = setterArg; + return this; + } + + public @NonNull PlatformPoint build() { + PlatformPoint pigeonReturn = new PlatformPoint(); + pigeonReturn.setX(x); + pigeonReturn.setY(y); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(2); + toListResult.add(x); + toListResult.add(y); + return toListResult; + } + + static @NonNull PlatformPoint fromList(@NonNull ArrayList pigeonVar_list) { + PlatformPoint pigeonResult = new PlatformPoint(); + Object x = pigeonVar_list.get(0); + pigeonResult.setX((Long) x); + Object y = pigeonVar_list.get(1); + pigeonResult.setY((Long) y); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of native TileOverlay properties. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformTileLayer { + private @NonNull Boolean visible; + + public @NonNull Boolean getVisible() { + return visible; + } + + public void setVisible(@NonNull Boolean setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"visible\" is null."); + } + this.visible = setterArg; + } + + private @NonNull Boolean fadeIn; + + public @NonNull Boolean getFadeIn() { + return fadeIn; + } + + public void setFadeIn(@NonNull Boolean setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"fadeIn\" is null."); + } + this.fadeIn = setterArg; + } + + private @NonNull Double transparency; + + public @NonNull Double getTransparency() { + return transparency; + } + + public void setTransparency(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"transparency\" is null."); + } + this.transparency = setterArg; + } + + private @NonNull Double zIndex; + + public @NonNull Double getZIndex() { + return zIndex; + } + + public void setZIndex(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"zIndex\" is null."); + } + this.zIndex = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformTileLayer() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformTileLayer that = (PlatformTileLayer) o; + return visible.equals(that.visible) + && fadeIn.equals(that.fadeIn) + && transparency.equals(that.transparency) + && zIndex.equals(that.zIndex); + } + + @Override + public int hashCode() { + return Objects.hash(visible, fadeIn, transparency, zIndex); + } + + public static final class Builder { + + private @Nullable Boolean visible; + + @CanIgnoreReturnValue + public @NonNull Builder setVisible(@NonNull Boolean setterArg) { + this.visible = setterArg; + return this; + } + + private @Nullable Boolean fadeIn; + + @CanIgnoreReturnValue + public @NonNull Builder setFadeIn(@NonNull Boolean setterArg) { + this.fadeIn = setterArg; + return this; + } + + private @Nullable Double transparency; + + @CanIgnoreReturnValue + public @NonNull Builder setTransparency(@NonNull Double setterArg) { + this.transparency = setterArg; + return this; + } + + private @Nullable Double zIndex; + + @CanIgnoreReturnValue + public @NonNull Builder setZIndex(@NonNull Double setterArg) { + this.zIndex = setterArg; + return this; + } + + public @NonNull PlatformTileLayer build() { + PlatformTileLayer pigeonReturn = new PlatformTileLayer(); + pigeonReturn.setVisible(visible); + pigeonReturn.setFadeIn(fadeIn); + pigeonReturn.setTransparency(transparency); + pigeonReturn.setZIndex(zIndex); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(4); + toListResult.add(visible); + toListResult.add(fadeIn); + toListResult.add(transparency); + toListResult.add(zIndex); + return toListResult; + } + + static @NonNull PlatformTileLayer fromList(@NonNull ArrayList pigeonVar_list) { + PlatformTileLayer pigeonResult = new PlatformTileLayer(); + Object visible = pigeonVar_list.get(0); + pigeonResult.setVisible((Boolean) visible); + Object fadeIn = pigeonVar_list.get(1); + pigeonResult.setFadeIn((Boolean) fadeIn); + Object transparency = pigeonVar_list.get(2); + pigeonResult.setTransparency((Double) transparency); + Object zIndex = pigeonVar_list.get(3); + pigeonResult.setZIndex((Double) zIndex); + return pigeonResult; + } + } + + /** + * Possible outcomes of launching a URL. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformZoomRange { + private @Nullable Double min; + + public @Nullable Double getMin() { + return min; + } + + public void setMin(@Nullable Double setterArg) { + this.min = setterArg; + } + + private @Nullable Double max; + + public @Nullable Double getMax() { + return max; + } + + public void setMax(@Nullable Double setterArg) { + this.max = setterArg; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformZoomRange that = (PlatformZoomRange) o; + return Objects.equals(min, that.min) && Objects.equals(max, that.max); + } + + @Override + public int hashCode() { + return Objects.hash(min, max); + } + + public static final class Builder { + + private @Nullable Double min; + + @CanIgnoreReturnValue + public @NonNull Builder setMin(@Nullable Double setterArg) { + this.min = setterArg; + return this; + } + + private @Nullable Double max; + + @CanIgnoreReturnValue + public @NonNull Builder setMax(@Nullable Double setterArg) { + this.max = setterArg; + return this; + } + + public @NonNull PlatformZoomRange build() { + PlatformZoomRange pigeonReturn = new PlatformZoomRange(); + pigeonReturn.setMin(min); + pigeonReturn.setMax(max); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(2); + toListResult.add(min); + toListResult.add(max); + return toListResult; + } + + static @NonNull PlatformZoomRange fromList(@NonNull ArrayList pigeonVar_list) { + PlatformZoomRange pigeonResult = new PlatformZoomRange(); + Object min = pigeonVar_list.get(0); + pigeonResult.setMin((Double) min); + Object max = pigeonVar_list.get(1); + pigeonResult.setMax((Double) max); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of [BitmapDescriptor]. As there are multiple disjoint types of + * [BitmapDescriptor], [PlatformBitmap] contains a single field which may hold the pigeon + * equivalent type of any of them. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformBitmap { + /** + * One of [PlatformBitmapAssetMap], [PlatformBitmapAsset], [PlatformBitmapAssetImage], + * [PlatformBitmapBytesMap], [PlatformBitmapBytes], or [PlatformBitmapDefaultMarker]. As Pigeon + * does not currently support data class inheritance, this approach allows for the different + * bitmap implementations to be valid argument and return types of the API methods. See + * https://github.com/flutter/flutter/issues/117819. + */ + private @NonNull Object bitmap; + + public @NonNull Object getBitmap() { + return bitmap; + } + + public void setBitmap(@NonNull Object setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"bitmap\" is null."); + } + this.bitmap = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformBitmap() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformBitmap that = (PlatformBitmap) o; + return bitmap.equals(that.bitmap); + } + + @Override + public int hashCode() { + return Objects.hash(bitmap); + } + + public static final class Builder { + + private @Nullable Object bitmap; + + @CanIgnoreReturnValue + public @NonNull Builder setBitmap(@NonNull Object setterArg) { + this.bitmap = setterArg; + return this; + } + + public @NonNull PlatformBitmap build() { + PlatformBitmap pigeonReturn = new PlatformBitmap(); + pigeonReturn.setBitmap(bitmap); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(1); + toListResult.add(bitmap); + return toListResult; + } + + static @NonNull PlatformBitmap fromList(@NonNull ArrayList pigeonVar_list) { + PlatformBitmap pigeonResult = new PlatformBitmap(); + Object bitmap = pigeonVar_list.get(0); + pigeonResult.setBitmap(bitmap); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of [DefaultMarker]. See + * https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/BitmapDescriptorFactory#defaultMarker(float) + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformBitmapDefaultMarker { + private @Nullable Double hue; + + public @Nullable Double getHue() { + return hue; + } + + public void setHue(@Nullable Double setterArg) { + this.hue = setterArg; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformBitmapDefaultMarker that = (PlatformBitmapDefaultMarker) o; + return Objects.equals(hue, that.hue); + } + + @Override + public int hashCode() { + return Objects.hash(hue); + } + + public static final class Builder { + + private @Nullable Double hue; + + @CanIgnoreReturnValue + public @NonNull Builder setHue(@Nullable Double setterArg) { + this.hue = setterArg; + return this; + } + + public @NonNull PlatformBitmapDefaultMarker build() { + PlatformBitmapDefaultMarker pigeonReturn = new PlatformBitmapDefaultMarker(); + pigeonReturn.setHue(hue); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(1); + toListResult.add(hue); + return toListResult; + } + + static @NonNull PlatformBitmapDefaultMarker fromList( + @NonNull ArrayList pigeonVar_list) { + PlatformBitmapDefaultMarker pigeonResult = new PlatformBitmapDefaultMarker(); + Object hue = pigeonVar_list.get(0); + pigeonResult.setHue((Double) hue); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of [BytesBitmap]. See + * https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/BitmapDescriptorFactory#fromBitmap(android.graphics.Bitmap) + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformBitmapBytes { + private @NonNull byte[] byteData; + + public @NonNull byte[] getByteData() { + return byteData; + } + + public void setByteData(@NonNull byte[] setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"byteData\" is null."); + } + this.byteData = setterArg; + } + + private @Nullable PlatformDoublePair size; + + public @Nullable PlatformDoublePair getSize() { + return size; + } + + public void setSize(@Nullable PlatformDoublePair setterArg) { + this.size = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformBitmapBytes() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformBitmapBytes that = (PlatformBitmapBytes) o; + return Arrays.equals(byteData, that.byteData) && Objects.equals(size, that.size); + } + + @Override + public int hashCode() { + int pigeonVar_result = Objects.hash(size); + pigeonVar_result = 31 * pigeonVar_result + Arrays.hashCode(byteData); + return pigeonVar_result; + } + + public static final class Builder { + + private @Nullable byte[] byteData; + + @CanIgnoreReturnValue + public @NonNull Builder setByteData(@NonNull byte[] setterArg) { + this.byteData = setterArg; + return this; + } + + private @Nullable PlatformDoublePair size; + + @CanIgnoreReturnValue + public @NonNull Builder setSize(@Nullable PlatformDoublePair setterArg) { + this.size = setterArg; + return this; + } + + public @NonNull PlatformBitmapBytes build() { + PlatformBitmapBytes pigeonReturn = new PlatformBitmapBytes(); + pigeonReturn.setByteData(byteData); + pigeonReturn.setSize(size); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(2); + toListResult.add(byteData); + toListResult.add(size); + return toListResult; + } + + static @NonNull PlatformBitmapBytes fromList(@NonNull ArrayList pigeonVar_list) { + PlatformBitmapBytes pigeonResult = new PlatformBitmapBytes(); + Object byteData = pigeonVar_list.get(0); + pigeonResult.setByteData((byte[]) byteData); + Object size = pigeonVar_list.get(1); + pigeonResult.setSize((PlatformDoublePair) size); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of [AssetBitmap]. See + * https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/BitmapDescriptorFactory#public-static-bitmapdescriptor-fromasset-string-assetname + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformBitmapAsset { + private @NonNull String name; + + public @NonNull String getName() { + return name; + } + + public void setName(@NonNull String setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"name\" is null."); + } + this.name = setterArg; + } + + private @Nullable String pkg; + + public @Nullable String getPkg() { + return pkg; + } + + public void setPkg(@Nullable String setterArg) { + this.pkg = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformBitmapAsset() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformBitmapAsset that = (PlatformBitmapAsset) o; + return name.equals(that.name) && Objects.equals(pkg, that.pkg); + } + + @Override + public int hashCode() { + return Objects.hash(name, pkg); + } + + public static final class Builder { + + private @Nullable String name; + + @CanIgnoreReturnValue + public @NonNull Builder setName(@NonNull String setterArg) { + this.name = setterArg; + return this; + } + + private @Nullable String pkg; + + @CanIgnoreReturnValue + public @NonNull Builder setPkg(@Nullable String setterArg) { + this.pkg = setterArg; + return this; + } + + public @NonNull PlatformBitmapAsset build() { + PlatformBitmapAsset pigeonReturn = new PlatformBitmapAsset(); + pigeonReturn.setName(name); + pigeonReturn.setPkg(pkg); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(2); + toListResult.add(name); + toListResult.add(pkg); + return toListResult; + } + + static @NonNull PlatformBitmapAsset fromList(@NonNull ArrayList pigeonVar_list) { + PlatformBitmapAsset pigeonResult = new PlatformBitmapAsset(); + Object name = pigeonVar_list.get(0); + pigeonResult.setName((String) name); + Object pkg = pigeonVar_list.get(1); + pigeonResult.setPkg((String) pkg); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of [AssetImageBitmap]. See + * https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/BitmapDescriptorFactory#public-static-bitmapdescriptor-fromasset-string-assetname + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformBitmapAssetImage { + private @NonNull String name; + + public @NonNull String getName() { + return name; + } + + public void setName(@NonNull String setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"name\" is null."); + } + this.name = setterArg; + } + + private @NonNull Double scale; + + public @NonNull Double getScale() { + return scale; + } + + public void setScale(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"scale\" is null."); + } + this.scale = setterArg; + } + + private @Nullable PlatformDoublePair size; + + public @Nullable PlatformDoublePair getSize() { + return size; + } + + public void setSize(@Nullable PlatformDoublePair setterArg) { + this.size = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformBitmapAssetImage() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformBitmapAssetImage that = (PlatformBitmapAssetImage) o; + return name.equals(that.name) && scale.equals(that.scale) && Objects.equals(size, that.size); + } + + @Override + public int hashCode() { + return Objects.hash(name, scale, size); + } + + public static final class Builder { + + private @Nullable String name; + + @CanIgnoreReturnValue + public @NonNull Builder setName(@NonNull String setterArg) { + this.name = setterArg; + return this; + } + + private @Nullable Double scale; @CanIgnoreReturnValue - public @NonNull Builder setX(@NonNull Long setterArg) { - this.x = setterArg; + public @NonNull Builder setScale(@NonNull Double setterArg) { + this.scale = setterArg; return this; } - private @Nullable Long y; + private @Nullable PlatformDoublePair size; @CanIgnoreReturnValue - public @NonNull Builder setY(@NonNull Long setterArg) { - this.y = setterArg; + public @NonNull Builder setSize(@Nullable PlatformDoublePair setterArg) { + this.size = setterArg; return this; } - public @NonNull PlatformPoint build() { - PlatformPoint pigeonReturn = new PlatformPoint(); - pigeonReturn.setX(x); - pigeonReturn.setY(y); + public @NonNull PlatformBitmapAssetImage build() { + PlatformBitmapAssetImage pigeonReturn = new PlatformBitmapAssetImage(); + pigeonReturn.setName(name); + pigeonReturn.setScale(scale); + pigeonReturn.setSize(size); return pigeonReturn; } } @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(2); - toListResult.add(x); - toListResult.add(y); + ArrayList toListResult = new ArrayList<>(3); + toListResult.add(name); + toListResult.add(scale); + toListResult.add(size); return toListResult; } - static @NonNull PlatformPoint fromList(@NonNull ArrayList __pigeon_list) { - PlatformPoint pigeonResult = new PlatformPoint(); - Object x = __pigeon_list.get(0); - pigeonResult.setX((x == null) ? null : ((x instanceof Integer) ? (Integer) x : (Long) x)); - Object y = __pigeon_list.get(1); - pigeonResult.setY((y == null) ? null : ((y instanceof Integer) ? (Integer) y : (Long) y)); + static @NonNull PlatformBitmapAssetImage fromList(@NonNull ArrayList pigeonVar_list) { + PlatformBitmapAssetImage pigeonResult = new PlatformBitmapAssetImage(); + Object name = pigeonVar_list.get(0); + pigeonResult.setName((String) name); + Object scale = pigeonVar_list.get(1); + pigeonResult.setScale((Double) scale); + Object size = pigeonVar_list.get(2); + pigeonResult.setSize((PlatformDoublePair) size); return pigeonResult; } } /** - * Pigeon equivalent of native TileOverlay properties. + * Pigeon equivalent of [AssetMapBitmap]. See + * https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/BitmapDescriptorFactory#public-static-bitmapdescriptor-fromasset-string-assetname * *

Generated class from Pigeon that represents data sent in messages. */ - public static final class PlatformTileLayer { - private @NonNull Boolean visible; + public static final class PlatformBitmapAssetMap { + private @NonNull String assetName; - public @NonNull Boolean getVisible() { - return visible; + public @NonNull String getAssetName() { + return assetName; } - public void setVisible(@NonNull Boolean setterArg) { + public void setAssetName(@NonNull String setterArg) { if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"visible\" is null."); + throw new IllegalStateException("Nonnull field \"assetName\" is null."); } - this.visible = setterArg; + this.assetName = setterArg; } - private @NonNull Boolean fadeIn; + private @NonNull PlatformMapBitmapScaling bitmapScaling; - public @NonNull Boolean getFadeIn() { - return fadeIn; + public @NonNull PlatformMapBitmapScaling getBitmapScaling() { + return bitmapScaling; } - public void setFadeIn(@NonNull Boolean setterArg) { + public void setBitmapScaling(@NonNull PlatformMapBitmapScaling setterArg) { if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"fadeIn\" is null."); + throw new IllegalStateException("Nonnull field \"bitmapScaling\" is null."); } - this.fadeIn = setterArg; + this.bitmapScaling = setterArg; } - private @NonNull Double transparency; + private @NonNull Double imagePixelRatio; - public @NonNull Double getTransparency() { - return transparency; + public @NonNull Double getImagePixelRatio() { + return imagePixelRatio; } - public void setTransparency(@NonNull Double setterArg) { + public void setImagePixelRatio(@NonNull Double setterArg) { if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"transparency\" is null."); + throw new IllegalStateException("Nonnull field \"imagePixelRatio\" is null."); } - this.transparency = setterArg; + this.imagePixelRatio = setterArg; } - private @NonNull Double zIndex; + private @Nullable Double width; - public @NonNull Double getZIndex() { - return zIndex; + public @Nullable Double getWidth() { + return width; } - public void setZIndex(@NonNull Double setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"zIndex\" is null."); - } - this.zIndex = setterArg; + public void setWidth(@Nullable Double setterArg) { + this.width = setterArg; + } + + private @Nullable Double height; + + public @Nullable Double getHeight() { + return height; + } + + public void setHeight(@Nullable Double setterArg) { + this.height = setterArg; } /** Constructor is non-public to enforce null safety; use Builder. */ - PlatformTileLayer() {} + PlatformBitmapAssetMap() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformBitmapAssetMap that = (PlatformBitmapAssetMap) o; + return assetName.equals(that.assetName) + && bitmapScaling.equals(that.bitmapScaling) + && imagePixelRatio.equals(that.imagePixelRatio) + && Objects.equals(width, that.width) + && Objects.equals(height, that.height); + } + + @Override + public int hashCode() { + return Objects.hash(assetName, bitmapScaling, imagePixelRatio, width, height); + } public static final class Builder { - private @Nullable Boolean visible; + private @Nullable String assetName; @CanIgnoreReturnValue - public @NonNull Builder setVisible(@NonNull Boolean setterArg) { - this.visible = setterArg; + public @NonNull Builder setAssetName(@NonNull String setterArg) { + this.assetName = setterArg; return this; } - private @Nullable Boolean fadeIn; + private @Nullable PlatformMapBitmapScaling bitmapScaling; @CanIgnoreReturnValue - public @NonNull Builder setFadeIn(@NonNull Boolean setterArg) { - this.fadeIn = setterArg; + public @NonNull Builder setBitmapScaling(@NonNull PlatformMapBitmapScaling setterArg) { + this.bitmapScaling = setterArg; return this; } - private @Nullable Double transparency; + private @Nullable Double imagePixelRatio; @CanIgnoreReturnValue - public @NonNull Builder setTransparency(@NonNull Double setterArg) { - this.transparency = setterArg; + public @NonNull Builder setImagePixelRatio(@NonNull Double setterArg) { + this.imagePixelRatio = setterArg; return this; } - private @Nullable Double zIndex; + private @Nullable Double width; @CanIgnoreReturnValue - public @NonNull Builder setZIndex(@NonNull Double setterArg) { - this.zIndex = setterArg; + public @NonNull Builder setWidth(@Nullable Double setterArg) { + this.width = setterArg; return this; } - public @NonNull PlatformTileLayer build() { - PlatformTileLayer pigeonReturn = new PlatformTileLayer(); - pigeonReturn.setVisible(visible); - pigeonReturn.setFadeIn(fadeIn); - pigeonReturn.setTransparency(transparency); - pigeonReturn.setZIndex(zIndex); + private @Nullable Double height; + + @CanIgnoreReturnValue + public @NonNull Builder setHeight(@Nullable Double setterArg) { + this.height = setterArg; + return this; + } + + public @NonNull PlatformBitmapAssetMap build() { + PlatformBitmapAssetMap pigeonReturn = new PlatformBitmapAssetMap(); + pigeonReturn.setAssetName(assetName); + pigeonReturn.setBitmapScaling(bitmapScaling); + pigeonReturn.setImagePixelRatio(imagePixelRatio); + pigeonReturn.setWidth(width); + pigeonReturn.setHeight(height); return pigeonReturn; } } @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(4); - toListResult.add(visible); - toListResult.add(fadeIn); - toListResult.add(transparency); - toListResult.add(zIndex); + ArrayList toListResult = new ArrayList<>(5); + toListResult.add(assetName); + toListResult.add(bitmapScaling); + toListResult.add(imagePixelRatio); + toListResult.add(width); + toListResult.add(height); return toListResult; } - static @NonNull PlatformTileLayer fromList(@NonNull ArrayList __pigeon_list) { - PlatformTileLayer pigeonResult = new PlatformTileLayer(); - Object visible = __pigeon_list.get(0); - pigeonResult.setVisible((Boolean) visible); - Object fadeIn = __pigeon_list.get(1); - pigeonResult.setFadeIn((Boolean) fadeIn); - Object transparency = __pigeon_list.get(2); - pigeonResult.setTransparency((Double) transparency); - Object zIndex = __pigeon_list.get(3); - pigeonResult.setZIndex((Double) zIndex); + static @NonNull PlatformBitmapAssetMap fromList(@NonNull ArrayList pigeonVar_list) { + PlatformBitmapAssetMap pigeonResult = new PlatformBitmapAssetMap(); + Object assetName = pigeonVar_list.get(0); + pigeonResult.setAssetName((String) assetName); + Object bitmapScaling = pigeonVar_list.get(1); + pigeonResult.setBitmapScaling((PlatformMapBitmapScaling) bitmapScaling); + Object imagePixelRatio = pigeonVar_list.get(2); + pigeonResult.setImagePixelRatio((Double) imagePixelRatio); + Object width = pigeonVar_list.get(3); + pigeonResult.setWidth((Double) width); + Object height = pigeonVar_list.get(4); + pigeonResult.setHeight((Double) height); return pigeonResult; } } /** - * Possible outcomes of launching a URL. + * Pigeon equivalent of [BytesMapBitmap]. See + * https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/BitmapDescriptorFactory#public-static-bitmapdescriptor-frombitmap-bitmap-image * *

Generated class from Pigeon that represents data sent in messages. */ - public static final class PlatformZoomRange { - private @NonNull Double min; + public static final class PlatformBitmapBytesMap { + private @NonNull byte[] byteData; - public @NonNull Double getMin() { - return min; + public @NonNull byte[] getByteData() { + return byteData; } - public void setMin(@NonNull Double setterArg) { + public void setByteData(@NonNull byte[] setterArg) { if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"min\" is null."); + throw new IllegalStateException("Nonnull field \"byteData\" is null."); } - this.min = setterArg; + this.byteData = setterArg; } - private @NonNull Double max; + private @NonNull PlatformMapBitmapScaling bitmapScaling; - public @NonNull Double getMax() { - return max; + public @NonNull PlatformMapBitmapScaling getBitmapScaling() { + return bitmapScaling; } - public void setMax(@NonNull Double setterArg) { + public void setBitmapScaling(@NonNull PlatformMapBitmapScaling setterArg) { if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"max\" is null."); + throw new IllegalStateException("Nonnull field \"bitmapScaling\" is null."); } - this.max = setterArg; + this.bitmapScaling = setterArg; + } + + private @NonNull Double imagePixelRatio; + + public @NonNull Double getImagePixelRatio() { + return imagePixelRatio; + } + + public void setImagePixelRatio(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"imagePixelRatio\" is null."); + } + this.imagePixelRatio = setterArg; + } + + private @Nullable Double width; + + public @Nullable Double getWidth() { + return width; + } + + public void setWidth(@Nullable Double setterArg) { + this.width = setterArg; + } + + private @Nullable Double height; + + public @Nullable Double getHeight() { + return height; + } + + public void setHeight(@Nullable Double setterArg) { + this.height = setterArg; } /** Constructor is non-public to enforce null safety; use Builder. */ - PlatformZoomRange() {} + PlatformBitmapBytesMap() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformBitmapBytesMap that = (PlatformBitmapBytesMap) o; + return Arrays.equals(byteData, that.byteData) + && bitmapScaling.equals(that.bitmapScaling) + && imagePixelRatio.equals(that.imagePixelRatio) + && Objects.equals(width, that.width) + && Objects.equals(height, that.height); + } + + @Override + public int hashCode() { + int pigeonVar_result = Objects.hash(bitmapScaling, imagePixelRatio, width, height); + pigeonVar_result = 31 * pigeonVar_result + Arrays.hashCode(byteData); + return pigeonVar_result; + } public static final class Builder { - private @Nullable Double min; + private @Nullable byte[] byteData; @CanIgnoreReturnValue - public @NonNull Builder setMin(@NonNull Double setterArg) { - this.min = setterArg; + public @NonNull Builder setByteData(@NonNull byte[] setterArg) { + this.byteData = setterArg; return this; } - private @Nullable Double max; + private @Nullable PlatformMapBitmapScaling bitmapScaling; @CanIgnoreReturnValue - public @NonNull Builder setMax(@NonNull Double setterArg) { - this.max = setterArg; + public @NonNull Builder setBitmapScaling(@NonNull PlatformMapBitmapScaling setterArg) { + this.bitmapScaling = setterArg; return this; } - public @NonNull PlatformZoomRange build() { - PlatformZoomRange pigeonReturn = new PlatformZoomRange(); - pigeonReturn.setMin(min); - pigeonReturn.setMax(max); + private @Nullable Double imagePixelRatio; + + @CanIgnoreReturnValue + public @NonNull Builder setImagePixelRatio(@NonNull Double setterArg) { + this.imagePixelRatio = setterArg; + return this; + } + + private @Nullable Double width; + + @CanIgnoreReturnValue + public @NonNull Builder setWidth(@Nullable Double setterArg) { + this.width = setterArg; + return this; + } + + private @Nullable Double height; + + @CanIgnoreReturnValue + public @NonNull Builder setHeight(@Nullable Double setterArg) { + this.height = setterArg; + return this; + } + + public @NonNull PlatformBitmapBytesMap build() { + PlatformBitmapBytesMap pigeonReturn = new PlatformBitmapBytesMap(); + pigeonReturn.setByteData(byteData); + pigeonReturn.setBitmapScaling(bitmapScaling); + pigeonReturn.setImagePixelRatio(imagePixelRatio); + pigeonReturn.setWidth(width); + pigeonReturn.setHeight(height); return pigeonReturn; } } @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(2); - toListResult.add(min); - toListResult.add(max); + ArrayList toListResult = new ArrayList<>(5); + toListResult.add(byteData); + toListResult.add(bitmapScaling); + toListResult.add(imagePixelRatio); + toListResult.add(width); + toListResult.add(height); return toListResult; } - static @NonNull PlatformZoomRange fromList(@NonNull ArrayList __pigeon_list) { - PlatformZoomRange pigeonResult = new PlatformZoomRange(); - Object min = __pigeon_list.get(0); - pigeonResult.setMin((Double) min); - Object max = __pigeon_list.get(1); - pigeonResult.setMax((Double) max); + static @NonNull PlatformBitmapBytesMap fromList(@NonNull ArrayList pigeonVar_list) { + PlatformBitmapBytesMap pigeonResult = new PlatformBitmapBytesMap(); + Object byteData = pigeonVar_list.get(0); + pigeonResult.setByteData((byte[]) byteData); + Object bitmapScaling = pigeonVar_list.get(1); + pigeonResult.setBitmapScaling((PlatformMapBitmapScaling) bitmapScaling); + Object imagePixelRatio = pigeonVar_list.get(2); + pigeonResult.setImagePixelRatio((Double) imagePixelRatio); + Object width = pigeonVar_list.get(3); + pigeonResult.setWidth((Double) width); + Object height = pigeonVar_list.get(4); + pigeonResult.setHeight((Double) height); return pigeonResult; } } @@ -647,17 +5829,119 @@ private PigeonCodec() {} protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { switch (type) { case (byte) 129: - return PlatformLatLng.fromList((ArrayList) readValue(buffer)); + { + Object value = readValue(buffer); + return value == null ? null : PlatformMapType.values()[((Long) value).intValue()]; + } case (byte) 130: - return PlatformLatLngBounds.fromList((ArrayList) readValue(buffer)); + { + Object value = readValue(buffer); + return value == null ? null : PlatformRendererType.values()[((Long) value).intValue()]; + } case (byte) 131: - return PlatformCluster.fromList((ArrayList) readValue(buffer)); + { + Object value = readValue(buffer); + return value == null ? null : PlatformJointType.values()[((Long) value).intValue()]; + } case (byte) 132: - return PlatformPoint.fromList((ArrayList) readValue(buffer)); + { + Object value = readValue(buffer); + return value == null ? null : PlatformCapType.values()[((Long) value).intValue()]; + } case (byte) 133: - return PlatformTileLayer.fromList((ArrayList) readValue(buffer)); + { + Object value = readValue(buffer); + return value == null + ? null + : PlatformPatternItemType.values()[((Long) value).intValue()]; + } case (byte) 134: + { + Object value = readValue(buffer); + return value == null + ? null + : PlatformMapBitmapScaling.values()[((Long) value).intValue()]; + } + case (byte) 135: + return PlatformCameraPosition.fromList((ArrayList) readValue(buffer)); + case (byte) 136: + return PlatformCameraUpdate.fromList((ArrayList) readValue(buffer)); + case (byte) 137: + return PlatformCameraUpdateNewCameraPosition.fromList( + (ArrayList) readValue(buffer)); + case (byte) 138: + return PlatformCameraUpdateNewLatLng.fromList((ArrayList) readValue(buffer)); + case (byte) 139: + return PlatformCameraUpdateNewLatLngBounds.fromList( + (ArrayList) readValue(buffer)); + case (byte) 140: + return PlatformCameraUpdateNewLatLngZoom.fromList((ArrayList) readValue(buffer)); + case (byte) 141: + return PlatformCameraUpdateScrollBy.fromList((ArrayList) readValue(buffer)); + case (byte) 142: + return PlatformCameraUpdateZoomBy.fromList((ArrayList) readValue(buffer)); + case (byte) 143: + return PlatformCameraUpdateZoom.fromList((ArrayList) readValue(buffer)); + case (byte) 144: + return PlatformCameraUpdateZoomTo.fromList((ArrayList) readValue(buffer)); + case (byte) 145: + return PlatformCircle.fromList((ArrayList) readValue(buffer)); + case (byte) 146: + return PlatformHeatmap.fromList((ArrayList) readValue(buffer)); + case (byte) 147: + return PlatformClusterManager.fromList((ArrayList) readValue(buffer)); + case (byte) 148: + return PlatformDoublePair.fromList((ArrayList) readValue(buffer)); + case (byte) 149: + return PlatformInfoWindow.fromList((ArrayList) readValue(buffer)); + case (byte) 150: + return PlatformMarker.fromList((ArrayList) readValue(buffer)); + case (byte) 151: + return PlatformPolygon.fromList((ArrayList) readValue(buffer)); + case (byte) 152: + return PlatformPolyline.fromList((ArrayList) readValue(buffer)); + case (byte) 153: + return PlatformCap.fromList((ArrayList) readValue(buffer)); + case (byte) 154: + return PlatformPatternItem.fromList((ArrayList) readValue(buffer)); + case (byte) 155: + return PlatformTile.fromList((ArrayList) readValue(buffer)); + case (byte) 156: + return PlatformTileOverlay.fromList((ArrayList) readValue(buffer)); + case (byte) 157: + return PlatformEdgeInsets.fromList((ArrayList) readValue(buffer)); + case (byte) 158: + return PlatformLatLng.fromList((ArrayList) readValue(buffer)); + case (byte) 159: + return PlatformLatLngBounds.fromList((ArrayList) readValue(buffer)); + case (byte) 160: + return PlatformCluster.fromList((ArrayList) readValue(buffer)); + case (byte) 161: + return PlatformCameraTargetBounds.fromList((ArrayList) readValue(buffer)); + case (byte) 162: + return PlatformMapViewCreationParams.fromList((ArrayList) readValue(buffer)); + case (byte) 163: + return PlatformMapConfiguration.fromList((ArrayList) readValue(buffer)); + case (byte) 164: + return PlatformPoint.fromList((ArrayList) readValue(buffer)); + case (byte) 165: + return PlatformTileLayer.fromList((ArrayList) readValue(buffer)); + case (byte) 166: return PlatformZoomRange.fromList((ArrayList) readValue(buffer)); + case (byte) 167: + return PlatformBitmap.fromList((ArrayList) readValue(buffer)); + case (byte) 168: + return PlatformBitmapDefaultMarker.fromList((ArrayList) readValue(buffer)); + case (byte) 169: + return PlatformBitmapBytes.fromList((ArrayList) readValue(buffer)); + case (byte) 170: + return PlatformBitmapAsset.fromList((ArrayList) readValue(buffer)); + case (byte) 171: + return PlatformBitmapAssetImage.fromList((ArrayList) readValue(buffer)); + case (byte) 172: + return PlatformBitmapAssetMap.fromList((ArrayList) readValue(buffer)); + case (byte) 173: + return PlatformBitmapBytesMap.fromList((ArrayList) readValue(buffer)); default: return super.readValueOfType(type, buffer); } @@ -665,24 +5949,141 @@ protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { @Override protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { - if (value instanceof PlatformLatLng) { + if (value instanceof PlatformMapType) { stream.write(129); + writeValue(stream, value == null ? null : ((PlatformMapType) value).index); + } else if (value instanceof PlatformRendererType) { + stream.write(130); + writeValue(stream, value == null ? null : ((PlatformRendererType) value).index); + } else if (value instanceof PlatformJointType) { + stream.write(131); + writeValue(stream, value == null ? null : ((PlatformJointType) value).index); + } else if (value instanceof PlatformCapType) { + stream.write(132); + writeValue(stream, value == null ? null : ((PlatformCapType) value).index); + } else if (value instanceof PlatformPatternItemType) { + stream.write(133); + writeValue(stream, value == null ? null : ((PlatformPatternItemType) value).index); + } else if (value instanceof PlatformMapBitmapScaling) { + stream.write(134); + writeValue(stream, value == null ? null : ((PlatformMapBitmapScaling) value).index); + } else if (value instanceof PlatformCameraPosition) { + stream.write(135); + writeValue(stream, ((PlatformCameraPosition) value).toList()); + } else if (value instanceof PlatformCameraUpdate) { + stream.write(136); + writeValue(stream, ((PlatformCameraUpdate) value).toList()); + } else if (value instanceof PlatformCameraUpdateNewCameraPosition) { + stream.write(137); + writeValue(stream, ((PlatformCameraUpdateNewCameraPosition) value).toList()); + } else if (value instanceof PlatformCameraUpdateNewLatLng) { + stream.write(138); + writeValue(stream, ((PlatformCameraUpdateNewLatLng) value).toList()); + } else if (value instanceof PlatformCameraUpdateNewLatLngBounds) { + stream.write(139); + writeValue(stream, ((PlatformCameraUpdateNewLatLngBounds) value).toList()); + } else if (value instanceof PlatformCameraUpdateNewLatLngZoom) { + stream.write(140); + writeValue(stream, ((PlatformCameraUpdateNewLatLngZoom) value).toList()); + } else if (value instanceof PlatformCameraUpdateScrollBy) { + stream.write(141); + writeValue(stream, ((PlatformCameraUpdateScrollBy) value).toList()); + } else if (value instanceof PlatformCameraUpdateZoomBy) { + stream.write(142); + writeValue(stream, ((PlatformCameraUpdateZoomBy) value).toList()); + } else if (value instanceof PlatformCameraUpdateZoom) { + stream.write(143); + writeValue(stream, ((PlatformCameraUpdateZoom) value).toList()); + } else if (value instanceof PlatformCameraUpdateZoomTo) { + stream.write(144); + writeValue(stream, ((PlatformCameraUpdateZoomTo) value).toList()); + } else if (value instanceof PlatformCircle) { + stream.write(145); + writeValue(stream, ((PlatformCircle) value).toList()); + } else if (value instanceof PlatformHeatmap) { + stream.write(146); + writeValue(stream, ((PlatformHeatmap) value).toList()); + } else if (value instanceof PlatformClusterManager) { + stream.write(147); + writeValue(stream, ((PlatformClusterManager) value).toList()); + } else if (value instanceof PlatformDoublePair) { + stream.write(148); + writeValue(stream, ((PlatformDoublePair) value).toList()); + } else if (value instanceof PlatformInfoWindow) { + stream.write(149); + writeValue(stream, ((PlatformInfoWindow) value).toList()); + } else if (value instanceof PlatformMarker) { + stream.write(150); + writeValue(stream, ((PlatformMarker) value).toList()); + } else if (value instanceof PlatformPolygon) { + stream.write(151); + writeValue(stream, ((PlatformPolygon) value).toList()); + } else if (value instanceof PlatformPolyline) { + stream.write(152); + writeValue(stream, ((PlatformPolyline) value).toList()); + } else if (value instanceof PlatformCap) { + stream.write(153); + writeValue(stream, ((PlatformCap) value).toList()); + } else if (value instanceof PlatformPatternItem) { + stream.write(154); + writeValue(stream, ((PlatformPatternItem) value).toList()); + } else if (value instanceof PlatformTile) { + stream.write(155); + writeValue(stream, ((PlatformTile) value).toList()); + } else if (value instanceof PlatformTileOverlay) { + stream.write(156); + writeValue(stream, ((PlatformTileOverlay) value).toList()); + } else if (value instanceof PlatformEdgeInsets) { + stream.write(157); + writeValue(stream, ((PlatformEdgeInsets) value).toList()); + } else if (value instanceof PlatformLatLng) { + stream.write(158); writeValue(stream, ((PlatformLatLng) value).toList()); } else if (value instanceof PlatformLatLngBounds) { - stream.write(130); + stream.write(159); writeValue(stream, ((PlatformLatLngBounds) value).toList()); } else if (value instanceof PlatformCluster) { - stream.write(131); + stream.write(160); writeValue(stream, ((PlatformCluster) value).toList()); + } else if (value instanceof PlatformCameraTargetBounds) { + stream.write(161); + writeValue(stream, ((PlatformCameraTargetBounds) value).toList()); + } else if (value instanceof PlatformMapViewCreationParams) { + stream.write(162); + writeValue(stream, ((PlatformMapViewCreationParams) value).toList()); + } else if (value instanceof PlatformMapConfiguration) { + stream.write(163); + writeValue(stream, ((PlatformMapConfiguration) value).toList()); } else if (value instanceof PlatformPoint) { - stream.write(132); + stream.write(164); writeValue(stream, ((PlatformPoint) value).toList()); } else if (value instanceof PlatformTileLayer) { - stream.write(133); + stream.write(165); writeValue(stream, ((PlatformTileLayer) value).toList()); } else if (value instanceof PlatformZoomRange) { - stream.write(134); + stream.write(166); writeValue(stream, ((PlatformZoomRange) value).toList()); + } else if (value instanceof PlatformBitmap) { + stream.write(167); + writeValue(stream, ((PlatformBitmap) value).toList()); + } else if (value instanceof PlatformBitmapDefaultMarker) { + stream.write(168); + writeValue(stream, ((PlatformBitmapDefaultMarker) value).toList()); + } else if (value instanceof PlatformBitmapBytes) { + stream.write(169); + writeValue(stream, ((PlatformBitmapBytes) value).toList()); + } else if (value instanceof PlatformBitmapAsset) { + stream.write(170); + writeValue(stream, ((PlatformBitmapAsset) value).toList()); + } else if (value instanceof PlatformBitmapAssetImage) { + stream.write(171); + writeValue(stream, ((PlatformBitmapAssetImage) value).toList()); + } else if (value instanceof PlatformBitmapAssetMap) { + stream.write(172); + writeValue(stream, ((PlatformBitmapAssetMap) value).toList()); + } else if (value instanceof PlatformBitmapBytesMap) { + stream.write(173); + writeValue(stream, ((PlatformBitmapBytesMap) value).toList()); } else { super.writeValue(stream, value); } @@ -723,6 +6124,46 @@ public interface VoidResult { public interface MapsApi { /** Returns once the map instance is available. */ void waitForMap(@NonNull VoidResult result); + /** + * Updates the map's configuration options. + * + *

Only non-null configuration values will result in updates; options with null values will + * remain unchanged. + */ + void updateMapConfiguration(@NonNull PlatformMapConfiguration configuration); + /** Updates the set of circles on the map. */ + void updateCircles( + @NonNull List toAdd, + @NonNull List toChange, + @NonNull List idsToRemove); + /** Updates the set of heatmaps on the map. */ + void updateHeatmaps( + @NonNull List toAdd, + @NonNull List toChange, + @NonNull List idsToRemove); + /** Updates the set of custer managers for clusters on the map. */ + void updateClusterManagers( + @NonNull List toAdd, @NonNull List idsToRemove); + /** Updates the set of markers on the map. */ + void updateMarkers( + @NonNull List toAdd, + @NonNull List toChange, + @NonNull List idsToRemove); + /** Updates the set of polygonss on the map. */ + void updatePolygons( + @NonNull List toAdd, + @NonNull List toChange, + @NonNull List idsToRemove); + /** Updates the set of polylines on the map. */ + void updatePolylines( + @NonNull List toAdd, + @NonNull List toChange, + @NonNull List idsToRemove); + /** Updates the set of tile overlays on the map. */ + void updateTileOverlays( + @NonNull List toAdd, + @NonNull List toChange, + @NonNull List idsToRemove); /** Gets the screen coordinate for the given map location. */ @NonNull PlatformPoint getScreenCoordinate(@NonNull PlatformLatLng latLng); @@ -732,6 +6173,10 @@ public interface MapsApi { /** Gets the map region currently displayed on the map. */ @NonNull PlatformLatLngBounds getVisibleRegion(); + /** Moves the camera according to [cameraUpdate] immediately, with no animation. */ + void moveCamera(@NonNull PlatformCameraUpdate cameraUpdate); + /** Moves the camera according to [cameraUpdate], animating the update. */ + void animateCamera(@NonNull PlatformCameraUpdate cameraUpdate); /** Gets the current map zoom level. */ @NonNull Double getZoomLevel(); @@ -782,27 +6227,240 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.google_maps_flutter_android.MapsApi.waitForMap" + "dev.flutter.pigeon.google_maps_flutter_android.MapsApi.waitForMap" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + VoidResult resultCallback = + new VoidResult() { + public void success() { + wrapped.add(0, null); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.waitForMap(resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.google_maps_flutter_android.MapsApi.updateMapConfiguration" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + PlatformMapConfiguration configurationArg = (PlatformMapConfiguration) args.get(0); + try { + api.updateMapConfiguration(configurationArg); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.google_maps_flutter_android.MapsApi.updateCircles" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List toAddArg = (List) args.get(0); + List toChangeArg = (List) args.get(1); + List idsToRemoveArg = (List) args.get(2); + try { + api.updateCircles(toAddArg, toChangeArg, idsToRemoveArg); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.google_maps_flutter_android.MapsApi.updateHeatmaps" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List toAddArg = (List) args.get(0); + List toChangeArg = (List) args.get(1); + List idsToRemoveArg = (List) args.get(2); + try { + api.updateHeatmaps(toAddArg, toChangeArg, idsToRemoveArg); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.google_maps_flutter_android.MapsApi.updateClusterManagers" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); - VoidResult resultCallback = - new VoidResult() { - public void success() { - wrapped.add(0, null); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.waitForMap(resultCallback); + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List toAddArg = (List) args.get(0); + List idsToRemoveArg = (List) args.get(1); + try { + api.updateClusterManagers(toAddArg, idsToRemoveArg); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.google_maps_flutter_android.MapsApi.updateMarkers" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List toAddArg = (List) args.get(0); + List toChangeArg = (List) args.get(1); + List idsToRemoveArg = (List) args.get(2); + try { + api.updateMarkers(toAddArg, toChangeArg, idsToRemoveArg); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.google_maps_flutter_android.MapsApi.updatePolygons" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List toAddArg = (List) args.get(0); + List toChangeArg = (List) args.get(1); + List idsToRemoveArg = (List) args.get(2); + try { + api.updatePolygons(toAddArg, toChangeArg, idsToRemoveArg); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.google_maps_flutter_android.MapsApi.updatePolylines" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List toAddArg = (List) args.get(0); + List toChangeArg = (List) args.get(1); + List idsToRemoveArg = (List) args.get(2); + try { + api.updatePolylines(toAddArg, toChangeArg, idsToRemoveArg); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.google_maps_flutter_android.MapsApi.updateTileOverlays" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List toAddArg = (List) args.get(0); + List toChangeArg = (List) args.get(1); + List idsToRemoveArg = (List) args.get(2); + try { + api.updateTileOverlays(toAddArg, toChangeArg, idsToRemoveArg); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -818,15 +6476,14 @@ public void error(Throwable error) { if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; PlatformLatLng latLngArg = (PlatformLatLng) args.get(0); try { PlatformPoint output = api.getScreenCoordinate(latLngArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -844,15 +6501,14 @@ public void error(Throwable error) { if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; PlatformPoint screenCoordinateArg = (PlatformPoint) args.get(0); try { PlatformLatLng output = api.getLatLng(screenCoordinateArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -870,13 +6526,62 @@ public void error(Throwable error) { if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { PlatformLatLngBounds output = api.getVisibleRegion(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.google_maps_flutter_android.MapsApi.moveCamera" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + PlatformCameraUpdate cameraUpdateArg = (PlatformCameraUpdate) args.get(0); + try { + api.moveCamera(cameraUpdateArg); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.google_maps_flutter_android.MapsApi.animateCamera" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + PlatformCameraUpdate cameraUpdateArg = (PlatformCameraUpdate) args.get(0); + try { + api.animateCamera(cameraUpdateArg); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -894,13 +6599,12 @@ public void error(Throwable error) { if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { Double output = api.getZoomLevel(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -918,15 +6622,14 @@ public void error(Throwable error) { if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; String markerIdArg = (String) args.get(0); try { api.showInfoWindow(markerIdArg); wrapped.add(0, null); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -944,15 +6647,14 @@ public void error(Throwable error) { if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; String markerIdArg = (String) args.get(0); try { api.hideInfoWindow(markerIdArg); wrapped.add(0, null); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -970,15 +6672,14 @@ public void error(Throwable error) { if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; String markerIdArg = (String) args.get(0); try { Boolean output = api.isInfoWindowShown(markerIdArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -996,15 +6697,14 @@ public void error(Throwable error) { if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; String styleArg = (String) args.get(0); try { Boolean output = api.setStyle(styleArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -1022,13 +6722,12 @@ public void error(Throwable error) { if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { Boolean output = api.didLastStyleSucceed(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -1046,15 +6745,14 @@ public void error(Throwable error) { if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; String tileOverlayIdArg = (String) args.get(0); try { api.clearTileCache(tileOverlayIdArg); wrapped.add(0, null); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -1072,7 +6770,7 @@ public void error(Throwable error) { if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); Result resultCallback = new Result() { public void success(byte[] result) { @@ -1094,6 +6792,528 @@ public void error(Throwable error) { } } } + /** Generated class from Pigeon that represents Flutter messages that can be called from Java. */ + public static class MapsCallbackApi { + private final @NonNull BinaryMessenger binaryMessenger; + private final String messageChannelSuffix; + + public MapsCallbackApi(@NonNull BinaryMessenger argBinaryMessenger) { + this(argBinaryMessenger, ""); + } + + public MapsCallbackApi( + @NonNull BinaryMessenger argBinaryMessenger, @NonNull String messageChannelSuffix) { + this.binaryMessenger = argBinaryMessenger; + this.messageChannelSuffix = messageChannelSuffix.isEmpty() ? "" : "." + messageChannelSuffix; + } + + /** Public interface for sending reply. The codec used by MapsCallbackApi. */ + static @NonNull MessageCodec getCodec() { + return PigeonCodec.INSTANCE; + } + /** Called when the map camera starts moving. */ + public void onCameraMoveStarted(@NonNull VoidResult result) { + final String channelName = + "dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onCameraMoveStarted" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + null, + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else { + result.success(); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Called when the map camera moves. */ + public void onCameraMove( + @NonNull PlatformCameraPosition cameraPositionArg, @NonNull VoidResult result) { + final String channelName = + "dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onCameraMove" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(cameraPositionArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else { + result.success(); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Called when the map camera stops moving. */ + public void onCameraIdle(@NonNull VoidResult result) { + final String channelName = + "dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onCameraIdle" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + null, + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else { + result.success(); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Called when the map, not a specifc map object, is tapped. */ + public void onTap(@NonNull PlatformLatLng positionArg, @NonNull VoidResult result) { + final String channelName = + "dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onTap" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(positionArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else { + result.success(); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Called when the map, not a specifc map object, is long pressed. */ + public void onLongPress(@NonNull PlatformLatLng positionArg, @NonNull VoidResult result) { + final String channelName = + "dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onLongPress" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(positionArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else { + result.success(); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Called when a marker is tapped. */ + public void onMarkerTap(@NonNull String markerIdArg, @NonNull VoidResult result) { + final String channelName = + "dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onMarkerTap" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(markerIdArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else { + result.success(); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Called when a marker drag starts. */ + public void onMarkerDragStart( + @NonNull String markerIdArg, + @NonNull PlatformLatLng positionArg, + @NonNull VoidResult result) { + final String channelName = + "dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onMarkerDragStart" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Arrays.asList(markerIdArg, positionArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else { + result.success(); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Called when a marker drag updates. */ + public void onMarkerDrag( + @NonNull String markerIdArg, + @NonNull PlatformLatLng positionArg, + @NonNull VoidResult result) { + final String channelName = + "dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onMarkerDrag" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Arrays.asList(markerIdArg, positionArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else { + result.success(); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Called when a marker drag ends. */ + public void onMarkerDragEnd( + @NonNull String markerIdArg, + @NonNull PlatformLatLng positionArg, + @NonNull VoidResult result) { + final String channelName = + "dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onMarkerDragEnd" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Arrays.asList(markerIdArg, positionArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else { + result.success(); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Called when a marker's info window is tapped. */ + public void onInfoWindowTap(@NonNull String markerIdArg, @NonNull VoidResult result) { + final String channelName = + "dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onInfoWindowTap" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(markerIdArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else { + result.success(); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Called when a circle is tapped. */ + public void onCircleTap(@NonNull String circleIdArg, @NonNull VoidResult result) { + final String channelName = + "dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onCircleTap" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(circleIdArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else { + result.success(); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Called when a marker cluster is tapped. */ + public void onClusterTap(@NonNull PlatformCluster clusterArg, @NonNull VoidResult result) { + final String channelName = + "dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onClusterTap" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(clusterArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else { + result.success(); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Called when a polygon is tapped. */ + public void onPolygonTap(@NonNull String polygonIdArg, @NonNull VoidResult result) { + final String channelName = + "dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onPolygonTap" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(polygonIdArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else { + result.success(); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Called when a polyline is tapped. */ + public void onPolylineTap(@NonNull String polylineIdArg, @NonNull VoidResult result) { + final String channelName = + "dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onPolylineTap" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(polylineIdArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else { + result.success(); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Called to get data for a map tile. */ + public void getTileOverlayTile( + @NonNull String tileOverlayIdArg, + @NonNull PlatformPoint locationArg, + @NonNull Long zoomArg, + @NonNull Result result) { + final String channelName = + "dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.getTileOverlayTile" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Arrays.asList(tileOverlayIdArg, locationArg, zoomArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); + } else { + @SuppressWarnings("ConstantConditions") + PlatformTile output = (PlatformTile) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + } + /** + * Interface for global SDK initialization. + * + *

Generated interface from Pigeon that represents a handler of messages from Flutter. + */ + public interface MapsInitializerApi { + /** + * Initializes the Google Maps SDK with the given renderer preference. + * + *

A null renderer preference will result in the default renderer. + * + *

Calling this more than once in the lifetime of an application will result in an error. + */ + void initializeWithPreferredRenderer( + @Nullable PlatformRendererType type, @NonNull Result result); + + /** The codec used by MapsInitializerApi. */ + static @NonNull MessageCodec getCodec() { + return PigeonCodec.INSTANCE; + } + /** + * Sets up an instance of `MapsInitializerApi` to handle messages through the `binaryMessenger`. + */ + static void setUp(@NonNull BinaryMessenger binaryMessenger, @Nullable MapsInitializerApi api) { + setUp(binaryMessenger, "", api); + } + + static void setUp( + @NonNull BinaryMessenger binaryMessenger, + @NonNull String messageChannelSuffix, + @Nullable MapsInitializerApi api) { + messageChannelSuffix = messageChannelSuffix.isEmpty() ? "" : "." + messageChannelSuffix; + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.google_maps_flutter_android.MapsInitializerApi.initializeWithPreferredRenderer" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + PlatformRendererType typeArg = (PlatformRendererType) args.get(0); + Result resultCallback = + new Result() { + public void success(PlatformRendererType result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.initializeWithPreferredRenderer(typeArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + } + } + /** + * Dummy interface to force generation of the platform view creation params, which are not used in + * any Pigeon calls, only the platform view creation call made internally by Flutter. + * + *

Generated interface from Pigeon that represents a handler of messages from Flutter. + */ + public interface MapsPlatformViewApi { + + void createView(@Nullable PlatformMapViewCreationParams type); + + /** The codec used by MapsPlatformViewApi. */ + static @NonNull MessageCodec getCodec() { + return PigeonCodec.INSTANCE; + } + /** + * Sets up an instance of `MapsPlatformViewApi` to handle messages through the + * `binaryMessenger`. + */ + static void setUp(@NonNull BinaryMessenger binaryMessenger, @Nullable MapsPlatformViewApi api) { + setUp(binaryMessenger, "", api); + } + + static void setUp( + @NonNull BinaryMessenger binaryMessenger, + @NonNull String messageChannelSuffix, + @Nullable MapsPlatformViewApi api) { + messageChannelSuffix = messageChannelSuffix.isEmpty() ? "" : "." + messageChannelSuffix; + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.google_maps_flutter_android.MapsPlatformViewApi.createView" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + PlatformMapViewCreationParams typeArg = (PlatformMapViewCreationParams) args.get(0); + try { + api.createView(typeArg); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + } + } /** * Inspector API only intended for use in integration tests. * @@ -1169,13 +7389,12 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { Boolean output = api.areBuildingsEnabled(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -1193,13 +7412,12 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { Boolean output = api.areRotateGesturesEnabled(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -1217,13 +7435,12 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { Boolean output = api.areZoomControlsEnabled(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -1241,13 +7458,12 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { Boolean output = api.areScrollGesturesEnabled(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -1265,13 +7481,12 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { Boolean output = api.areTiltGesturesEnabled(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -1289,13 +7504,12 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { Boolean output = api.areZoomGesturesEnabled(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -1313,13 +7527,12 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { Boolean output = api.isCompassEnabled(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -1337,13 +7550,12 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { Boolean output = api.isLiteModeEnabled(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -1361,13 +7573,12 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { Boolean output = api.isMapToolbarEnabled(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -1385,13 +7596,12 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { Boolean output = api.isMyLocationButtonEnabled(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -1409,13 +7619,12 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { Boolean output = api.isTrafficEnabled(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -1433,15 +7642,14 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; String tileOverlayIdArg = (String) args.get(0); try { PlatformTileLayer output = api.getTileOverlayInfo(tileOverlayIdArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -1459,13 +7667,12 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { PlatformZoomRange output = api.getZoomRange(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -1483,15 +7690,14 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; String clusterManagerIdArg = (String) args.get(0); try { List output = api.getClusters(clusterManagerIdArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/NoOpVoidResult.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/NoOpVoidResult.java new file mode 100644 index 000000000000..2b8ee23e9a36 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/NoOpVoidResult.java @@ -0,0 +1,22 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.googlemaps; + +import androidx.annotation.NonNull; + +/** + * Response handler for calls to Dart that don't require any error handling, such as event + * notifications where if the Dart side has been torn down, silently dropping the message is the + * desired behavior. + * + *

Longer term, any call using this is likely a good candidate to migrate to event channels. + */ +public class NoOpVoidResult implements Messages.VoidResult { + @Override + public void success() {} + + @Override + public void error(@NonNull Throwable error) {} +} diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/PolygonsController.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/PolygonsController.java index 6f855db07996..98a43477765f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/PolygonsController.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/PolygonsController.java @@ -4,10 +4,11 @@ package io.flutter.plugins.googlemaps; +import androidx.annotation.NonNull; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.model.Polygon; import com.google.android.gms.maps.model.PolygonOptions; -import io.flutter.plugin.common.MethodChannel; +import io.flutter.plugins.googlemaps.Messages.MapsCallbackApi; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -16,14 +17,14 @@ class PolygonsController { private final Map polygonIdToController; private final Map googleMapsPolygonIdToDartPolygonId; - private final MethodChannel methodChannel; + private final @NonNull MapsCallbackApi flutterApi; private final float density; private GoogleMap googleMap; - PolygonsController(MethodChannel methodChannel, float density) { + PolygonsController(@NonNull MapsCallbackApi flutterApi, float density) { this.polygonIdToController = new HashMap<>(); this.googleMapsPolygonIdToDartPolygonId = new HashMap<>(); - this.methodChannel = methodChannel; + this.flutterApi = flutterApi; this.density = density; } @@ -31,31 +32,20 @@ void setGoogleMap(GoogleMap googleMap) { this.googleMap = googleMap; } - void addPolygons(List polygonsToAdd) { - if (polygonsToAdd != null) { - for (Object polygonToAdd : polygonsToAdd) { - addPolygon(polygonToAdd); - } + void addPolygons(@NonNull List polygonsToAdd) { + for (Messages.PlatformPolygon polygonToAdd : polygonsToAdd) { + addPolygon(polygonToAdd); } } - void changePolygons(List polygonsToChange) { - if (polygonsToChange != null) { - for (Object polygonToChange : polygonsToChange) { - changePolygon(polygonToChange); - } + void changePolygons(@NonNull List polygonsToChange) { + for (Messages.PlatformPolygon polygonToChange : polygonsToChange) { + changePolygon(polygonToChange); } } - void removePolygons(List polygonIdsToRemove) { - if (polygonIdsToRemove == null) { - return; - } - for (Object rawPolygonId : polygonIdsToRemove) { - if (rawPolygonId == null) { - continue; - } - String polygonId = (String) rawPolygonId; + void removePolygons(@NonNull List polygonIdsToRemove) { + for (String polygonId : polygonIdsToRemove) { final PolygonController polygonController = polygonIdToController.remove(polygonId); if (polygonController != null) { polygonController.remove(); @@ -69,7 +59,7 @@ boolean onPolygonTap(String googlePolygonId) { if (polygonId == null) { return false; } - methodChannel.invokeMethod("polygon#onTap", Convert.polygonIdToJson(polygonId)); + flutterApi.onPolygonTap(polygonId, new NoOpVoidResult()); PolygonController polygonController = polygonIdToController.get(polygonId); if (polygonController != null) { return polygonController.consumeTapEvents(); @@ -77,10 +67,7 @@ boolean onPolygonTap(String googlePolygonId) { return false; } - private void addPolygon(Object polygon) { - if (polygon == null) { - return; - } + private void addPolygon(@NonNull Messages.PlatformPolygon polygon) { PolygonBuilder polygonBuilder = new PolygonBuilder(density); String polygonId = Convert.interpretPolygonOptions(polygon, polygonBuilder); PolygonOptions options = polygonBuilder.build(); @@ -95,20 +82,14 @@ private void addPolygon( googleMapsPolygonIdToDartPolygonId.put(polygon.getId(), polygonId); } - private void changePolygon(Object polygon) { - if (polygon == null) { - return; - } - String polygonId = getPolygonId(polygon); - PolygonController polygonController = polygonIdToController.get(polygonId); + private void changePolygon(@NonNull Messages.PlatformPolygon polygon) { + PolygonController polygonController = polygonIdToController.get(polygon.getPolygonId()); if (polygonController != null) { Convert.interpretPolygonOptions(polygon, polygonController); } } - @SuppressWarnings("unchecked") - private static String getPolygonId(Object polygon) { - Map polygonMap = (Map) polygon; - return (String) polygonMap.get("polygonId"); + private static String getPolygonId(Map polygon) { + return (String) polygon.get("polygonId"); } } diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/PolylinesController.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/PolylinesController.java index 2dbad98fcfea..65b53eb7e070 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/PolylinesController.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/PolylinesController.java @@ -5,10 +5,11 @@ package io.flutter.plugins.googlemaps; import android.content.res.AssetManager; +import androidx.annotation.NonNull; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.model.Polyline; import com.google.android.gms.maps.model.PolylineOptions; -import io.flutter.plugin.common.MethodChannel; +import io.flutter.plugins.googlemaps.Messages.MapsCallbackApi; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -17,16 +18,17 @@ class PolylinesController { private final Map polylineIdToController; private final Map googleMapsPolylineIdToDartPolylineId; - private final MethodChannel methodChannel; + private final @NonNull MapsCallbackApi flutterApi; private GoogleMap googleMap; private final float density; private final AssetManager assetManager; - PolylinesController(MethodChannel methodChannel, AssetManager assetManager, float density) { + PolylinesController( + @NonNull MapsCallbackApi flutterApi, AssetManager assetManager, float density) { this.assetManager = assetManager; this.polylineIdToController = new HashMap<>(); this.googleMapsPolylineIdToDartPolylineId = new HashMap<>(); - this.methodChannel = methodChannel; + this.flutterApi = flutterApi; this.density = density; } @@ -34,31 +36,20 @@ void setGoogleMap(GoogleMap googleMap) { this.googleMap = googleMap; } - void addPolylines(List polylinesToAdd) { - if (polylinesToAdd != null) { - for (Object polylineToAdd : polylinesToAdd) { - addPolyline(polylineToAdd); - } + void addPolylines(@NonNull List polylinesToAdd) { + for (Messages.PlatformPolyline polylineToAdd : polylinesToAdd) { + addPolyline(polylineToAdd); } } - void changePolylines(List polylinesToChange) { - if (polylinesToChange != null) { - for (Object polylineToChange : polylinesToChange) { - changePolyline(polylineToChange); - } + void changePolylines(@NonNull List polylinesToChange) { + for (Messages.PlatformPolyline polylineToChange : polylinesToChange) { + changePolyline(polylineToChange); } } - void removePolylines(List polylineIdsToRemove) { - if (polylineIdsToRemove == null) { - return; - } - for (Object rawPolylineId : polylineIdsToRemove) { - if (rawPolylineId == null) { - continue; - } - String polylineId = (String) rawPolylineId; + void removePolylines(@NonNull List polylineIdsToRemove) { + for (String polylineId : polylineIdsToRemove) { final PolylineController polylineController = polylineIdToController.remove(polylineId); if (polylineController != null) { polylineController.remove(); @@ -72,7 +63,7 @@ boolean onPolylineTap(String googlePolylineId) { if (polylineId == null) { return false; } - methodChannel.invokeMethod("polyline#onTap", Convert.polylineIdToJson(polylineId)); + flutterApi.onPolylineTap(polylineId, new NoOpVoidResult()); PolylineController polylineController = polylineIdToController.get(polylineId); if (polylineController != null) { return polylineController.consumeTapEvents(); @@ -80,10 +71,7 @@ boolean onPolylineTap(String googlePolylineId) { return false; } - private void addPolyline(Object polyline) { - if (polyline == null) { - return; - } + private void addPolyline(@NonNull Messages.PlatformPolyline polyline) { PolylineBuilder polylineBuilder = new PolylineBuilder(density); String polylineId = Convert.interpretPolylineOptions(polyline, polylineBuilder, assetManager, density); @@ -99,20 +87,15 @@ private void addPolyline( googleMapsPolylineIdToDartPolylineId.put(polyline.getId(), polylineId); } - private void changePolyline(Object polyline) { - if (polyline == null) { - return; - } - String polylineId = getPolylineId(polyline); + private void changePolyline(@NonNull Messages.PlatformPolyline polyline) { + String polylineId = polyline.getPolylineId(); PolylineController polylineController = polylineIdToController.get(polylineId); if (polylineController != null) { Convert.interpretPolylineOptions(polyline, polylineController, assetManager, density); } } - @SuppressWarnings("unchecked") - private static String getPolylineId(Object polyline) { - Map polylineMap = (Map) polyline; - return (String) polylineMap.get("polylineId"); + private static String getPolylineId(Map polyline) { + return (String) polyline.get("polylineId"); } } diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaysController.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaysController.java index 52b9d1e6bc99..2ee8dcac8572 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaysController.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaysController.java @@ -4,11 +4,12 @@ package io.flutter.plugins.googlemaps; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.model.TileOverlay; import com.google.android.gms.maps.model.TileOverlayOptions; -import io.flutter.plugin.common.MethodChannel; +import io.flutter.plugins.googlemaps.Messages.MapsCallbackApi; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -16,32 +17,26 @@ class TileOverlaysController { private final Map tileOverlayIdToController; - private final MethodChannel methodChannel; + private final MapsCallbackApi flutterApi; private GoogleMap googleMap; - TileOverlaysController(MethodChannel methodChannel) { + TileOverlaysController(MapsCallbackApi flutterApi) { this.tileOverlayIdToController = new HashMap<>(); - this.methodChannel = methodChannel; + this.flutterApi = flutterApi; } void setGoogleMap(GoogleMap googleMap) { this.googleMap = googleMap; } - void addTileOverlays(List> tileOverlaysToAdd) { - if (tileOverlaysToAdd == null) { - return; - } - for (Map tileOverlayToAdd : tileOverlaysToAdd) { + void addTileOverlays(@NonNull List tileOverlaysToAdd) { + for (Messages.PlatformTileOverlay tileOverlayToAdd : tileOverlaysToAdd) { addTileOverlay(tileOverlayToAdd); } } - void changeTileOverlays(List> tileOverlaysToChange) { - if (tileOverlaysToChange == null) { - return; - } - for (Map tileOverlayToChange : tileOverlaysToChange) { + void changeTileOverlays(@NonNull List tileOverlaysToChange) { + for (Messages.PlatformTileOverlay tileOverlayToChange : tileOverlaysToChange) { changeTileOverlay(tileOverlayToChange); } } @@ -80,15 +75,12 @@ TileOverlay getTileOverlay(String tileOverlayId) { return tileOverlayController.getTileOverlay(); } - private void addTileOverlay(Map tileOverlayOptions) { - if (tileOverlayOptions == null) { - return; - } + private void addTileOverlay(@NonNull Messages.PlatformTileOverlay platformTileOverlay) { TileOverlayBuilder tileOverlayOptionsBuilder = new TileOverlayBuilder(); String tileOverlayId = - Convert.interpretTileOverlayOptions(tileOverlayOptions, tileOverlayOptionsBuilder); + Convert.interpretTileOverlayOptions(platformTileOverlay, tileOverlayOptionsBuilder); TileProviderController tileProviderController = - new TileProviderController(methodChannel, tileOverlayId); + new TileProviderController(flutterApi, tileOverlayId); tileOverlayOptionsBuilder.setTileProvider(tileProviderController); TileOverlayOptions options = tileOverlayOptionsBuilder.build(); TileOverlay tileOverlay = googleMap.addTileOverlay(options); @@ -96,14 +88,11 @@ private void addTileOverlay(Map tileOverlayOptions) { tileOverlayIdToController.put(tileOverlayId, tileOverlayController); } - private void changeTileOverlay(Map tileOverlayOptions) { - if (tileOverlayOptions == null) { - return; - } - String tileOverlayId = getTileOverlayId(tileOverlayOptions); + private void changeTileOverlay(@NonNull Messages.PlatformTileOverlay platformTileOverlay) { + String tileOverlayId = platformTileOverlay.getTileOverlayId(); TileOverlayController tileOverlayController = tileOverlayIdToController.get(tileOverlayId); if (tileOverlayController != null) { - Convert.interpretTileOverlayOptions(tileOverlayOptions, tileOverlayController); + Convert.interpretTileOverlayOptions(platformTileOverlay, tileOverlayController); } } diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/TileProviderController.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/TileProviderController.java index 434512c17fc9..ea3fb8fc5c64 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/TileProviderController.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/TileProviderController.java @@ -8,10 +8,11 @@ import android.os.Looper; import android.util.Log; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.google.android.gms.maps.model.Tile; import com.google.android.gms.maps.model.TileProvider; -import io.flutter.plugin.common.MethodChannel; -import java.util.Map; +import io.flutter.plugins.googlemaps.Messages.FlutterError; +import io.flutter.plugins.googlemaps.Messages.MapsCallbackApi; import java.util.concurrent.CountDownLatch; class TileProviderController implements TileProvider { @@ -19,12 +20,12 @@ class TileProviderController implements TileProvider { private static final String TAG = "TileProviderController"; protected final String tileOverlayId; - protected final MethodChannel methodChannel; + protected final @NonNull MapsCallbackApi flutterApi; protected final Handler handler = new Handler(Looper.getMainLooper()); - TileProviderController(MethodChannel methodChannel, String tileOverlayId) { + TileProviderController(@NonNull MapsCallbackApi flutterApi, String tileOverlayId) { this.tileOverlayId = tileOverlayId; - this.methodChannel = methodChannel; + this.flutterApi = flutterApi; } @Override @@ -33,13 +34,13 @@ public Tile getTile(final int x, final int y, final int zoom) { return worker.getTile(); } - private final class Worker implements MethodChannel.Result { + private final class Worker implements Messages.Result { private final CountDownLatch countDownLatch = new CountDownLatch(1); private final int x; private final int y; private final int zoom; - private Map result; + private @Nullable Messages.PlatformTile result; Worker(int x, int y, int zoom) { this.x = x; @@ -49,14 +50,11 @@ private final class Worker implements MethodChannel.Result { @NonNull Tile getTile() { - handler.post( - () -> - methodChannel.invokeMethod( - "tileOverlay#getTile", - Convert.tileOverlayArgumentsToJson(tileOverlayId, x, y, zoom), - this)); + final Messages.PlatformPoint location = + new Messages.PlatformPoint.Builder().setX((long) x).setY((long) y).build(); + handler.post(() -> flutterApi.getTileOverlayTile(tileOverlayId, location, (long) zoom, this)); try { - // Because `methodChannel.invokeMethod` is async, we use a `countDownLatch` make it synchronized. + // `flutterApi.getTileOverlayTile` is async, so use a `countDownLatch` to make it synchronized. countDownLatch.await(); } catch (InterruptedException e) { Log.e( @@ -66,7 +64,14 @@ Tile getTile() { return TileProvider.NO_TILE; } try { - return Convert.interpretTile(result); + if (result == null) { + Log.e( + TAG, + String.format( + "Did not receive tile data for tile: x = %d, y= %d, zoom = %d", x, y, zoom)); + return TileProvider.NO_TILE; + } + return Convert.tileFromPigeon(result); } catch (Exception e) { Log.e(TAG, "Can't parse tile data", e); return TileProvider.NO_TILE; @@ -74,29 +79,26 @@ Tile getTile() { } @Override - @SuppressWarnings("unchecked") - public void success(Object data) { - result = (Map) data; + public void success(@NonNull Messages.PlatformTile result) { + this.result = result; countDownLatch.countDown(); } @Override - public void error(String errorCode, String errorMessage, Object data) { - Log.e( - TAG, - "Can't get tile: errorCode = " - + errorCode - + ", errorMessage = " - + errorCode - + ", date = " - + data); - result = null; - countDownLatch.countDown(); - } - - @Override - public void notImplemented() { - Log.e(TAG, "Can't get tile: notImplemented"); + public void error(@NonNull Throwable error) { + if (error instanceof FlutterError) { + FlutterError flutterError = (FlutterError) error; + Log.e( + TAG, + "Can't get tile: errorCode = " + + flutterError.code + + ", errorMessage = " + + flutterError.getMessage() + + ", date = " + + flutterError.details); + } else { + Log.e(TAG, "Can't get tile: " + error); + } result = null; countDownLatch.countDown(); } diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/CirclesControllerTest.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/CirclesControllerTest.java new file mode 100644 index 000000000000..6d09d704722f --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/CirclesControllerTest.java @@ -0,0 +1,73 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.googlemaps; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.android.gms.internal.maps.zzl; +import com.google.android.gms.maps.GoogleMap; +import com.google.android.gms.maps.model.Circle; +import com.google.android.gms.maps.model.CircleOptions; +import java.util.Collections; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +public class CirclesControllerTest { + @Mock GoogleMap mockGoogleMap; + AutoCloseable mockCloseable; + + @Before + public void setUp() { + mockCloseable = MockitoAnnotations.openMocks(this); + } + + @After + public void tearDown() throws Exception { + mockCloseable.close(); + } + + @Test + public void controller_changeCircles_updatesExistingCircle() { + final zzl z = mock(zzl.class); + final Circle circle = spy(new Circle(z)); + when(mockGoogleMap.addCircle(any(CircleOptions.class))).thenReturn(circle); + + final CirclesController controller = new CirclesController(null, 1.0f); + controller.setGoogleMap(mockGoogleMap); + + final String id = "a_circle"; + + final Messages.PlatformCircle.Builder builder = new Messages.PlatformCircle.Builder(); + builder + .setCircleId(id) + .setConsumeTapEvents(false) + .setFillColor(0L) + .setCenter(new Messages.PlatformLatLng.Builder().setLatitude(0.0).setLongitude(0.0).build()) + .setRadius(1.0) + .setStrokeColor(0L) + .setStrokeWidth(1L) + .setVisible(true) + .setZIndex(0.0); + + controller.addCircles(Collections.singletonList(builder.build())); + // There should be exactly one circle. + Assert.assertEquals(1, controller.circleIdToController.size()); + + builder.setConsumeTapEvents(true); + controller.changeCircles(Collections.singletonList(builder.build())); + // There should still only be one circle, and it should be updated. + Assert.assertEquals(1, controller.circleIdToController.size()); + verify(circle, times(1)).setClickable(true); + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/ClusterManagersControllerTest.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/ClusterManagersControllerTest.java index bc80627c35f7..df4208df5e67 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/ClusterManagersControllerTest.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/ClusterManagersControllerTest.java @@ -8,12 +8,14 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.content.Context; import android.content.res.AssetManager; +import android.graphics.Bitmap; import android.os.Build; import androidx.test.core.app.ApplicationProvider; import com.google.android.gms.maps.GoogleMap; @@ -23,52 +25,58 @@ import com.google.maps.android.clustering.algo.StaticCluster; import com.google.maps.android.collections.MarkerManager; import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.MethodChannel; -import io.flutter.plugin.common.MethodCodec; +import io.flutter.plugins.googlemaps.Messages.MapsCallbackApi; +import java.io.ByteArrayOutputStream; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Set; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentMatchers; +import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; @RunWith(RobolectricTestRunner.class) -@Config(sdk = Build.VERSION_CODES.P) +@Config(minSdk = Build.VERSION_CODES.LOLLIPOP) public class ClusterManagersControllerTest { private Context context; - private MethodChannel methodChannel; + private MapsCallbackApi flutterApi; private ClusterManagersController controller; private GoogleMap googleMap; private MarkerManager markerManager; - private MarkerManager.Collection markerCollection; private AssetManager assetManager; private final float density = 1; + @Mock Convert.BitmapDescriptorFactoryWrapper bitmapFactory; + + private AutoCloseable mocksClosable; + @Before public void setUp() { - MockitoAnnotations.openMocks(this); + mocksClosable = MockitoAnnotations.openMocks(this); context = ApplicationProvider.getApplicationContext(); assetManager = context.getAssets(); - methodChannel = - spy(new MethodChannel(mock(BinaryMessenger.class), "no-name", mock(MethodCodec.class))); - controller = spy(new ClusterManagersController(methodChannel, context)); + flutterApi = spy(new MapsCallbackApi(mock(BinaryMessenger.class))); + controller = spy(new ClusterManagersController(flutterApi, context)); googleMap = mock(GoogleMap.class); markerManager = new MarkerManager(googleMap); - markerCollection = markerManager.newCollection(); controller.init(googleMap, markerManager); } + @After + public void close() throws Exception { + mocksClosable.close(); + } + @Test - @SuppressWarnings("unchecked") - public void AddClusterManagersAndMarkers() throws InterruptedException { + public void AddClusterManagersAndMarkers() { final String clusterManagerId = "cm_1"; final String markerId1 = "mid_1"; final String markerId2 = "mid_2"; @@ -86,22 +94,24 @@ public void AddClusterManagersAndMarkers() throws InterruptedException { when(googleMap.getCameraPosition()) .thenReturn(CameraPosition.builder().target(new LatLng(0, 0)).build()); - Map initialClusterManager = new HashMap<>(); - initialClusterManager.put("clusterManagerId", clusterManagerId); - List clusterManagersToAdd = new ArrayList<>(); + Messages.PlatformClusterManager initialClusterManager = + new Messages.PlatformClusterManager.Builder().setIdentifier(clusterManagerId).build(); + List clusterManagersToAdd = new ArrayList<>(); clusterManagersToAdd.add(initialClusterManager); controller.addClusterManagers(clusterManagersToAdd); MarkerBuilder markerBuilder1 = new MarkerBuilder(markerId1, clusterManagerId); MarkerBuilder markerBuilder2 = new MarkerBuilder(markerId2, clusterManagerId); - final Map markerData1 = - createMarkerData(markerId1, location1, clusterManagerId); - final Map markerData2 = - createMarkerData(markerId2, location2, clusterManagerId); + final Messages.PlatformMarker markerData1 = + createPlatformMarker(markerId1, location1, clusterManagerId); + final Messages.PlatformMarker markerData2 = + createPlatformMarker(markerId2, location2, clusterManagerId); - Convert.interpretMarkerOptions(markerData1, markerBuilder1, assetManager, density); - Convert.interpretMarkerOptions(markerData2, markerBuilder2, assetManager, density); + Convert.interpretMarkerOptions( + markerData1, markerBuilder1, assetManager, density, bitmapFactory); + Convert.interpretMarkerOptions( + markerData2, markerBuilder2, assetManager, density, bitmapFactory); controller.addItem(markerBuilder1); controller.addItem(markerBuilder2); @@ -122,8 +132,7 @@ public void AddClusterManagersAndMarkers() throws InterruptedException { } @Test - @SuppressWarnings("unchecked") - public void OnClusterClickCallsMethodChannel() throws InterruptedException { + public void OnClusterClickCallsMethodChannel() { String clusterManagerId = "cm_1"; LatLng clusterPosition = new LatLng(43.00, -87.90); LatLng markerPosition1 = new LatLng(43.05, -87.95); @@ -140,8 +149,9 @@ public void OnClusterClickCallsMethodChannel() throws InterruptedException { cluster.add(marker2); controller.onClusterClick(cluster); - Mockito.verify(methodChannel) - .invokeMethod("cluster#onTap", Convert.clusterToJson(clusterManagerId, cluster)); + Mockito.verify(flutterApi) + .onClusterTap( + eq(Convert.clusterToPigeon(clusterManagerId, cluster)), ArgumentMatchers.any()); } @Test @@ -150,9 +160,9 @@ public void RemoveClusterManagers() { when(googleMap.getCameraPosition()) .thenReturn(CameraPosition.builder().target(new LatLng(0, 0)).build()); - Map initialClusterManager = new HashMap<>(); - initialClusterManager.put("clusterManagerId", clusterManagerId); - List clusterManagersToAdd = new ArrayList<>(); + Messages.PlatformClusterManager initialClusterManager = + new Messages.PlatformClusterManager.Builder().setIdentifier(clusterManagerId).build(); + List clusterManagersToAdd = new ArrayList<>(); clusterManagersToAdd.add(initialClusterManager); controller.addClusterManagers(clusterManagersToAdd); @@ -166,12 +176,41 @@ public void RemoveClusterManagers() { () -> controller.getClustersWithClusterManagerId(clusterManagerId)); } - private Map createMarkerData( + private Messages.PlatformMarker createPlatformMarker( String markerId, List location, String clusterManagerId) { - Map markerData = new HashMap<>(); - markerData.put("markerId", markerId); - markerData.put("position", location); - markerData.put("clusterManagerId", clusterManagerId); - return markerData; + Bitmap fakeBitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + fakeBitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream); + byte[] byteArray = byteArrayOutputStream.toByteArray(); + Messages.PlatformBitmap icon = + new Messages.PlatformBitmap.Builder() + .setBitmap( + new Messages.PlatformBitmapBytesMap.Builder() + .setByteData(byteArray) + .setImagePixelRatio(1.0) + .setBitmapScaling(Messages.PlatformMapBitmapScaling.NONE) + .build()) + .build(); + Messages.PlatformDoublePair anchor = + new Messages.PlatformDoublePair.Builder().setX(0.0).setY(0.0).build(); + return new Messages.PlatformMarker.Builder() + .setMarkerId(markerId) + .setConsumeTapEvents(false) + .setIcon(icon) + .setAlpha(1.0) + .setDraggable(false) + .setFlat(false) + .setVisible(true) + .setRotation(0.0) + .setZIndex(0.0) + .setPosition( + new Messages.PlatformLatLng.Builder() + .setLatitude(location.get(0)) + .setLongitude(location.get(1)) + .build()) + .setClusterManagerId(clusterManagerId) + .setAnchor(anchor) + .setInfoWindow(new Messages.PlatformInfoWindow.Builder().setAnchor(anchor).build()) + .build(); } } diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/ConvertTest.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/ConvertTest.java index 3680d918e2f1..a2733980559d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/ConvertTest.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/ConvertTest.java @@ -4,10 +4,22 @@ package io.flutter.plugins.googlemaps; +import static com.google.android.gms.maps.GoogleMap.MAP_TYPE_HYBRID; +import static io.flutter.plugins.googlemaps.Convert.HEATMAP_DATA_KEY; +import static io.flutter.plugins.googlemaps.Convert.HEATMAP_GRADIENT_COLORS_KEY; +import static io.flutter.plugins.googlemaps.Convert.HEATMAP_GRADIENT_COLOR_MAP_SIZE_KEY; +import static io.flutter.plugins.googlemaps.Convert.HEATMAP_GRADIENT_KEY; +import static io.flutter.plugins.googlemaps.Convert.HEATMAP_GRADIENT_START_POINTS_KEY; +import static io.flutter.plugins.googlemaps.Convert.HEATMAP_ID_KEY; +import static io.flutter.plugins.googlemaps.Convert.HEATMAP_MAX_INTENSITY_KEY; +import static io.flutter.plugins.googlemaps.Convert.HEATMAP_OPACITY_KEY; +import static io.flutter.plugins.googlemaps.Convert.HEATMAP_RADIUS_KEY; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; import android.content.res.AssetManager; @@ -17,16 +29,21 @@ import android.graphics.Paint; import android.os.Build; import android.util.Base64; +import androidx.annotation.NonNull; import com.google.android.gms.maps.model.BitmapDescriptor; import com.google.android.gms.maps.model.LatLng; +import com.google.android.gms.maps.model.LatLngBounds; import com.google.maps.android.clustering.algo.StaticCluster; +import com.google.maps.android.geometry.Point; +import com.google.maps.android.heatmaps.Gradient; +import com.google.maps.android.heatmaps.WeightedLatLng; +import com.google.maps.android.projection.SphericalMercatorProjection; import io.flutter.plugins.googlemaps.Convert.BitmapDescriptorFactoryWrapper; import io.flutter.plugins.googlemaps.Convert.FlutterInjectorWrapper; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; +import java.util.Collections; import java.util.List; import java.util.Map; import org.junit.After; @@ -40,7 +57,7 @@ import org.robolectric.annotation.Config; @RunWith(RobolectricTestRunner.class) -@Config(minSdk = Build.VERSION_CODES.P) +@Config(minSdk = Build.VERSION_CODES.LOLLIPOP) public class ConvertTest { @Mock private AssetManager assetManager; @@ -50,10 +67,12 @@ public class ConvertTest { @Mock private FlutterInjectorWrapper flutterInjectorWrapper; + @Mock private GoogleMapOptionsSink optionsSink; + AutoCloseable mockCloseable; // A 1x1 pixel (#8080ff) PNG image encoded in base64 - private String base64Image = generateBase64Image(); + private final String base64Image = generateBase64Image(); @Before public void before() { @@ -66,22 +85,19 @@ public void tearDown() throws Exception { } @Test - public void ConvertToPointsConvertsThePointsWithFullPrecision() { + public void ConvertPointsFromPigeonConvertsThePointsWithFullPrecision() { double latitude = 43.03725568057; double longitude = -87.90466904649; - ArrayList point = new ArrayList(); - point.add(latitude); - point.add(longitude); - ArrayList> pointsList = new ArrayList<>(); - pointsList.add(point); - List latLngs = Convert.toPoints(pointsList); + Messages.PlatformLatLng platLng = + new Messages.PlatformLatLng.Builder().setLatitude(latitude).setLongitude(longitude).build(); + List latLngs = Convert.pointsFromPigeon(Collections.singletonList(platLng)); LatLng latLng = latLngs.get(0); Assert.assertEquals(latitude, latLng.latitude, 1e-15); Assert.assertEquals(longitude, latLng.longitude, 1e-15); } @Test - public void ConvertClusterToJsonReturnsCorrectData() { + public void ConvertClusterToPigeonReturnsCorrectData() { String clusterManagerId = "cm_1"; LatLng clusterPosition = new LatLng(43.00, -87.90); LatLng markerPosition1 = new LatLng(43.05, -87.95); @@ -97,60 +113,50 @@ public void ConvertClusterToJsonReturnsCorrectData() { marker2.setPosition(markerPosition2); cluster.add(marker2); - Object result = Convert.clusterToJson(clusterManagerId, cluster); - Map clusterData = (Map) result; - Assert.assertEquals(clusterManagerId, clusterData.get("clusterManagerId")); - - List position = (List) clusterData.get("position"); - Assert.assertTrue(position instanceof List); - Assert.assertEquals(clusterPosition.latitude, (double) position.get(0), 1e-15); - Assert.assertEquals(clusterPosition.longitude, (double) position.get(1), 1e-15); + Messages.PlatformCluster result = Convert.clusterToPigeon(clusterManagerId, cluster); + Assert.assertEquals(clusterManagerId, result.getClusterManagerId()); - Map bounds = (Map) clusterData.get("bounds"); - Assert.assertTrue(bounds instanceof Map); - List southwest = (List) bounds.get("southwest"); - List northeast = (List) bounds.get("northeast"); - Assert.assertTrue(southwest instanceof List); - Assert.assertTrue(northeast instanceof List); + Messages.PlatformLatLng position = result.getPosition(); + Assert.assertEquals(clusterPosition.latitude, position.getLatitude(), 1e-15); + Assert.assertEquals(clusterPosition.longitude, position.getLongitude(), 1e-15); + Messages.PlatformLatLngBounds bounds = result.getBounds(); + Messages.PlatformLatLng southwest = bounds.getSouthwest(); + Messages.PlatformLatLng northeast = bounds.getNortheast(); // bounding data should combine data from marker positions markerPosition1 and markerPosition2 - Assert.assertEquals(markerPosition2.latitude, (double) southwest.get(0), 1e-15); - Assert.assertEquals(markerPosition1.longitude, (double) southwest.get(1), 1e-15); - Assert.assertEquals(markerPosition1.latitude, (double) northeast.get(0), 1e-15); - Assert.assertEquals(markerPosition2.longitude, (double) northeast.get(1), 1e-15); - - Object markerIds = clusterData.get("markerIds"); - Assert.assertTrue(markerIds instanceof List); - List markerIdList = (List) markerIds; - Assert.assertEquals(2, markerIdList.size()); - Assert.assertEquals(marker1.markerId(), markerIdList.get(0)); - Assert.assertEquals(marker2.markerId(), markerIdList.get(1)); + Assert.assertEquals(markerPosition2.latitude, southwest.getLatitude(), 1e-15); + Assert.assertEquals(markerPosition1.longitude, southwest.getLongitude(), 1e-15); + Assert.assertEquals(markerPosition1.latitude, northeast.getLatitude(), 1e-15); + Assert.assertEquals(markerPosition2.longitude, northeast.getLongitude(), 1e-15); + + List markerIds = result.getMarkerIds(); + Assert.assertEquals(2, markerIds.size()); + Assert.assertEquals(marker1.markerId(), markerIds.get(0)); + Assert.assertEquals(marker2.markerId(), markerIds.get(1)); } @Test public void GetBitmapFromAssetAuto() throws Exception { String fakeAssetName = "fake_asset_name"; String fakeAssetKey = "fake_asset_key"; - Map assetDetails = new HashMap<>(); - assetDetails.put("assetName", fakeAssetName); - assetDetails.put("bitmapScaling", "auto"); - assetDetails.put("width", 15.0f); - assetDetails.put("height", 15.0f); - assetDetails.put("imagePixelRatio", 2.0f); when(flutterInjectorWrapper.getLookupKeyForAsset(fakeAssetName)).thenReturn(fakeAssetKey); when(assetManager.open(fakeAssetKey)).thenReturn(buildImageInputStream()); when(bitmapDescriptorFactoryWrapper.fromBitmap(any())).thenReturn(mockBitmapDescriptor); + Messages.PlatformBitmapAssetMap bitmap = + new Messages.PlatformBitmapAssetMap.Builder() + .setBitmapScaling(Messages.PlatformMapBitmapScaling.AUTO) + .setWidth(15.0) + .setHeight(15.0) + .setImagePixelRatio(2.0) + .setAssetName(fakeAssetName) + .build(); BitmapDescriptor result = Convert.getBitmapFromAsset( - assetDetails, - assetManager, - 1.0f, - bitmapDescriptorFactoryWrapper, - flutterInjectorWrapper); + bitmap, assetManager, 1.0f, bitmapDescriptorFactoryWrapper, flutterInjectorWrapper); Assert.assertEquals(mockBitmapDescriptor, result); } @@ -160,25 +166,22 @@ public void GetBitmapFromAssetAutoAndWidth() throws Exception { String fakeAssetName = "fake_asset_name"; String fakeAssetKey = "fake_asset_key"; - Map assetDetails = new HashMap<>(); - assetDetails.put("assetName", fakeAssetName); - assetDetails.put("bitmapScaling", "auto"); - assetDetails.put("width", 15.0f); - assetDetails.put("imagePixelRatio", 2.0f); - when(flutterInjectorWrapper.getLookupKeyForAsset(fakeAssetName)).thenReturn(fakeAssetKey); when(assetManager.open(fakeAssetKey)).thenReturn(buildImageInputStream()); when(bitmapDescriptorFactoryWrapper.fromBitmap(any())).thenReturn(mockBitmapDescriptor); + Messages.PlatformBitmapAssetMap bitmap = + new Messages.PlatformBitmapAssetMap.Builder() + .setAssetName(fakeAssetName) + .setWidth(15.0) + .setImagePixelRatio(2.0) + .setBitmapScaling(Messages.PlatformMapBitmapScaling.AUTO) + .build(); BitmapDescriptor result = Convert.getBitmapFromAsset( - assetDetails, - assetManager, - 1.0f, - bitmapDescriptorFactoryWrapper, - flutterInjectorWrapper); + bitmap, assetManager, 1.0f, bitmapDescriptorFactoryWrapper, flutterInjectorWrapper); Assert.assertEquals(mockBitmapDescriptor, result); } @@ -188,25 +191,22 @@ public void GetBitmapFromAssetAutoAndHeight() throws Exception { String fakeAssetName = "fake_asset_name"; String fakeAssetKey = "fake_asset_key"; - Map assetDetails = new HashMap<>(); - assetDetails.put("assetName", fakeAssetName); - assetDetails.put("bitmapScaling", "auto"); - assetDetails.put("height", 15.0f); - assetDetails.put("imagePixelRatio", 2.0f); - when(flutterInjectorWrapper.getLookupKeyForAsset(fakeAssetName)).thenReturn(fakeAssetKey); when(assetManager.open(fakeAssetKey)).thenReturn(buildImageInputStream()); when(bitmapDescriptorFactoryWrapper.fromBitmap(any())).thenReturn(mockBitmapDescriptor); + Messages.PlatformBitmapAssetMap bitmap = + new Messages.PlatformBitmapAssetMap.Builder() + .setBitmapScaling(Messages.PlatformMapBitmapScaling.AUTO) + .setHeight(15.0) + .setImagePixelRatio(2.0) + .setAssetName(fakeAssetName) + .build(); BitmapDescriptor result = Convert.getBitmapFromAsset( - assetDetails, - assetManager, - 1.0f, - bitmapDescriptorFactoryWrapper, - flutterInjectorWrapper); + bitmap, assetManager, 1.0f, bitmapDescriptorFactoryWrapper, flutterInjectorWrapper); Assert.assertEquals(mockBitmapDescriptor, result); } @@ -216,11 +216,6 @@ public void GetBitmapFromAssetNoScaling() throws Exception { String fakeAssetName = "fake_asset_name"; String fakeAssetKey = "fake_asset_key"; - Map assetDetails = new HashMap<>(); - assetDetails.put("assetName", fakeAssetName); - assetDetails.put("bitmapScaling", "noScaling"); - assetDetails.put("imagePixelRatio", 2.0f); - when(flutterInjectorWrapper.getLookupKeyForAsset(fakeAssetName)).thenReturn(fakeAssetKey); when(assetManager.open(fakeAssetKey)).thenReturn(buildImageInputStream()); @@ -228,102 +223,110 @@ public void GetBitmapFromAssetNoScaling() throws Exception { when(bitmapDescriptorFactoryWrapper.fromAsset(any())).thenReturn(mockBitmapDescriptor); verify(bitmapDescriptorFactoryWrapper, never()).fromBitmap(any()); + Messages.PlatformBitmapAssetMap bitmap = + new Messages.PlatformBitmapAssetMap.Builder() + .setBitmapScaling(Messages.PlatformMapBitmapScaling.NONE) + .setImagePixelRatio(2.0) + .setAssetName(fakeAssetName) + .build(); BitmapDescriptor result = Convert.getBitmapFromAsset( - assetDetails, - assetManager, - 1.0f, - bitmapDescriptorFactoryWrapper, - flutterInjectorWrapper); + bitmap, assetManager, 1.0f, bitmapDescriptorFactoryWrapper, flutterInjectorWrapper); Assert.assertEquals(mockBitmapDescriptor, result); } @Test - public void GetBitmapFromBytesAuto() throws Exception { + public void GetBitmapFromBytesAuto() { byte[] bmpData = Base64.decode(base64Image, Base64.DEFAULT); - Map assetDetails = new HashMap<>(); - assetDetails.put("byteData", bmpData); - assetDetails.put("bitmapScaling", "auto"); - assetDetails.put("imagePixelRatio", 2.0f); - when(bitmapDescriptorFactoryWrapper.fromBitmap(any())).thenReturn(mockBitmapDescriptor); + Messages.PlatformBitmapBytesMap bitmap = + new Messages.PlatformBitmapBytesMap.Builder() + .setBitmapScaling(Messages.PlatformMapBitmapScaling.AUTO) + .setImagePixelRatio(2.0) + .setByteData(bmpData) + .build(); + BitmapDescriptor result = - Convert.getBitmapFromBytes(assetDetails, 1f, bitmapDescriptorFactoryWrapper); + Convert.getBitmapFromBytes(bitmap, 1f, bitmapDescriptorFactoryWrapper); Assert.assertEquals(mockBitmapDescriptor, result); } @Test - public void GetBitmapFromBytesAutoAndWidth() throws Exception { + public void GetBitmapFromBytesAutoAndWidth() { byte[] bmpData = Base64.decode(base64Image, Base64.DEFAULT); - Map assetDetails = new HashMap<>(); - assetDetails.put("byteData", bmpData); - assetDetails.put("bitmapScaling", "auto"); - assetDetails.put("imagePixelRatio", 2.0f); - assetDetails.put("width", 15.0f); - when(bitmapDescriptorFactoryWrapper.fromBitmap(any())).thenReturn(mockBitmapDescriptor); + Messages.PlatformBitmapBytesMap bitmap = + new Messages.PlatformBitmapBytesMap.Builder() + .setBitmapScaling(Messages.PlatformMapBitmapScaling.AUTO) + .setImagePixelRatio(2.0) + .setByteData(bmpData) + .setWidth(15.0) + .build(); BitmapDescriptor result = - Convert.getBitmapFromBytes(assetDetails, 1f, bitmapDescriptorFactoryWrapper); + Convert.getBitmapFromBytes(bitmap, 1f, bitmapDescriptorFactoryWrapper); Assert.assertEquals(mockBitmapDescriptor, result); } @Test - public void GetBitmapFromBytesAutoAndHeight() throws Exception { + public void GetBitmapFromBytesAutoAndHeight() { byte[] bmpData = Base64.decode(base64Image, Base64.DEFAULT); - Map assetDetails = new HashMap<>(); - assetDetails.put("byteData", bmpData); - assetDetails.put("bitmapScaling", "auto"); - assetDetails.put("imagePixelRatio", 2.0f); - assetDetails.put("height", 15.0f); - when(bitmapDescriptorFactoryWrapper.fromBitmap(any())).thenReturn(mockBitmapDescriptor); + Messages.PlatformBitmapBytesMap bitmap = + new Messages.PlatformBitmapBytesMap.Builder() + .setBitmapScaling(Messages.PlatformMapBitmapScaling.AUTO) + .setImagePixelRatio(2.0) + .setByteData(bmpData) + .setHeight(15.0) + .build(); BitmapDescriptor result = - Convert.getBitmapFromBytes(assetDetails, 1f, bitmapDescriptorFactoryWrapper); + Convert.getBitmapFromBytes(bitmap, 1f, bitmapDescriptorFactoryWrapper); Assert.assertEquals(mockBitmapDescriptor, result); } @Test - public void GetBitmapFromBytesNoScaling() throws Exception { + public void GetBitmapFromBytesNoScaling() { byte[] bmpData = Base64.decode(base64Image, Base64.DEFAULT); - Map assetDetails = new HashMap<>(); - assetDetails.put("byteData", bmpData); - assetDetails.put("bitmapScaling", "noScaling"); - assetDetails.put("imagePixelRatio", 2.0f); - when(bitmapDescriptorFactoryWrapper.fromBitmap(any())).thenReturn(mockBitmapDescriptor); + Messages.PlatformBitmapBytesMap bitmap = + new Messages.PlatformBitmapBytesMap.Builder() + .setBitmapScaling(Messages.PlatformMapBitmapScaling.NONE) + .setImagePixelRatio(2.0) + .setByteData(bmpData) + .build(); BitmapDescriptor result = - Convert.getBitmapFromBytes(assetDetails, 1f, bitmapDescriptorFactoryWrapper); + Convert.getBitmapFromBytes(bitmap, 1f, bitmapDescriptorFactoryWrapper); Assert.assertEquals(mockBitmapDescriptor, result); } @Test(expected = IllegalArgumentException.class) // Expecting an IllegalArgumentException - public void GetBitmapFromBytesThrowsErrorIfInvalidImageData() throws Exception { + public void GetBitmapFromBytesThrowsErrorIfInvalidImageData() { String invalidBase64Image = "not valid image data"; byte[] bmpData = Base64.decode(invalidBase64Image, Base64.DEFAULT); - Map assetDetails = new HashMap<>(); - assetDetails.put("byteData", bmpData); - assetDetails.put("bitmapScaling", "noScaling"); - assetDetails.put("imagePixelRatio", 2.0f); - verify(bitmapDescriptorFactoryWrapper, never()).fromBitmap(any()); + Messages.PlatformBitmapBytesMap bitmap = + new Messages.PlatformBitmapBytesMap.Builder() + .setBitmapScaling(Messages.PlatformMapBitmapScaling.NONE) + .setImagePixelRatio(2.0) + .setByteData(bmpData) + .build(); try { - Convert.getBitmapFromBytes(assetDetails, 1f, bitmapDescriptorFactoryWrapper); + Convert.getBitmapFromBytes(bitmap, 1f, bitmapDescriptorFactoryWrapper); } catch (IllegalArgumentException e) { Assert.assertEquals(e.getMessage(), "Unable to interpret bytes as a valid image."); throw e; // rethrow the exception @@ -332,13 +335,342 @@ public void GetBitmapFromBytesThrowsErrorIfInvalidImageData() throws Exception { fail("Expected an IllegalArgumentException to be thrown"); } + @Test + public void interpretMapConfiguration_handlesNulls() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().build(); + Convert.interpretMapConfiguration(config, optionsSink); + verifyNoInteractions(optionsSink); + } + + @Test + public void interpretMapConfiguration_handlesCompassEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setCompassEnabled(false).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setCompassEnabled(false); + } + + @Test + public void interpretMapConfiguration_handlesMapToolbarEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setMapToolbarEnabled(true).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setMapToolbarEnabled(true); + } + + @Test + public void interpretMapConfiguration_handlesRotateGesturesEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setRotateGesturesEnabled(false).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setRotateGesturesEnabled(false); + } + + @Test + public void interpretMapConfiguration_handlesScrollGesturesEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setScrollGesturesEnabled(true).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setScrollGesturesEnabled(true); + } + + @Test + public void interpretMapConfiguration_handlesTiltGesturesEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setTiltGesturesEnabled(false).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setTiltGesturesEnabled(false); + } + + @Test + public void interpretMapConfiguration_handlesTrackCameraPosition() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setTrackCameraPosition(true).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setTrackCameraPosition(true); + } + + @Test + public void interpretMapConfiguration_handlesZoomControlsEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setZoomControlsEnabled(false).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setZoomControlsEnabled(false); + } + + @Test + public void interpretMapConfiguration_handlesZoomGesturesEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setZoomGesturesEnabled(true).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setZoomGesturesEnabled(true); + } + + @Test + public void interpretMapConfiguration_handlesMyLocationEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setMyLocationEnabled(false).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setMyLocationEnabled(false); + } + + @Test + public void interpretMapConfiguration_handlesMyLocationButtonEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setMyLocationButtonEnabled(true).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setMyLocationButtonEnabled(true); + } + + @Test + public void interpretMapConfiguration_handlesIndoorViewEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setIndoorViewEnabled(false).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setIndoorEnabled(false); + } + + @Test + public void interpretMapConfiguration_handlesTrafficEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setTrafficEnabled(true).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setTrafficEnabled(true); + } + + @Test + public void interpretMapConfiguration_handlesBuildingsEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setBuildingsEnabled(false).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setBuildingsEnabled(false); + } + + @Test + public void interpretMapConfiguration_handlesLiteModeEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setLiteModeEnabled(true).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setLiteModeEnabled(true); + } + + @Test + public void interpretMapConfiguration_handlesStyle() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setStyle("foo").build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setMapStyle("foo"); + } + + @Test + public void interpretMapConfiguration_handlesUnboundedCameraTargetBounds() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder() + .setCameraTargetBounds(new Messages.PlatformCameraTargetBounds.Builder().build()) + .build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setCameraTargetBounds(null); + } + + @Test + public void interpretMapConfiguration_handlesBoundedCameraTargetBounds() { + LatLngBounds bounds = new LatLngBounds(new LatLng(10, 20), new LatLng(30, 40)); + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder() + .setCameraTargetBounds( + new Messages.PlatformCameraTargetBounds.Builder() + .setBounds( + new Messages.PlatformLatLngBounds.Builder() + .setSouthwest( + new Messages.PlatformLatLng.Builder() + .setLatitude(bounds.southwest.latitude) + .setLongitude(bounds.southwest.longitude) + .build()) + .setNortheast( + new Messages.PlatformLatLng.Builder() + .setLatitude(bounds.northeast.latitude) + .setLongitude(bounds.northeast.longitude) + .build()) + .build()) + .build()) + .build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setCameraTargetBounds(bounds); + } + + @Test + public void interpretMapConfiguration_handlesMapType() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder() + .setMapType(Messages.PlatformMapType.HYBRID) + .build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setMapType(MAP_TYPE_HYBRID); + } + + @Test + public void interpretMapConfiguration_handlesPadding() { + final double top = 1.0; + final double bottom = 2.0; + final double left = 3.0; + final double right = 4.0; + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder() + .setPadding( + new Messages.PlatformEdgeInsets.Builder() + .setTop(top) + .setBottom(bottom) + .setLeft(left) + .setRight(right) + .build()) + .build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)) + .setPadding((float) top, (float) left, (float) bottom, (float) right); + } + + @Test + public void interpretMapConfiguration_handlesMinMaxZoomPreference() { + final double min = 1.0; + final double max = 2.0; + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder() + .setMinMaxZoomPreference( + new Messages.PlatformZoomRange.Builder().setMin(min).setMax(max).build()) + .build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setMinMaxZoomPreference((float) min, (float) max); + } + + private static final SphericalMercatorProjection sProjection = new SphericalMercatorProjection(1); + + @Test() + public void ConvertToWeightedLatLngReturnsCorrectData() { + final double intensity = 3.3; + final Object data = List.of(List.of(1.1, 2.2), intensity); + final Point point = sProjection.toPoint(new LatLng(1.1, 2.2)); + + final WeightedLatLng result = Convert.toWeightedLatLng(data); + + Assert.assertEquals(point.x, result.getPoint().x, 0); + Assert.assertEquals(point.y, result.getPoint().y, 0); + Assert.assertEquals(intensity, result.getIntensity(), 0); + } + + @Test() + public void ConvertToWeightedDataReturnsCorrectData() { + final double intensity = 3.3; + final List data = List.of(List.of(List.of(1.1, 2.2), intensity)); + final Point point = sProjection.toPoint(new LatLng(1.1, 2.2)); + + final List result = Convert.toWeightedData(data); + + Assert.assertEquals(1, result.size()); + Assert.assertEquals(point.x, result.get(0).getPoint().x, 0); + Assert.assertEquals(point.y, result.get(0).getPoint().y, 0); + Assert.assertEquals(intensity, result.get(0).getIntensity(), 0); + } + + @Test() + public void ConvertToGradientReturnsCorrectData() { + final int color1 = 0; + final int color2 = 1; + final int color3 = 2; + final List colorData = List.of(color1, color2, color3); + final double startPoint1 = 0.0; + final double startPoint2 = 1.0; + final double startPoint3 = 2.0; + List startPointData = List.of(startPoint1, startPoint2, startPoint3); + final int colorMapSize = 3; + final Map data = + Map.of( + HEATMAP_GRADIENT_COLORS_KEY, colorData, + HEATMAP_GRADIENT_START_POINTS_KEY, startPointData, + HEATMAP_GRADIENT_COLOR_MAP_SIZE_KEY, colorMapSize); + + final Gradient result = Convert.toGradient(data); + + Assert.assertEquals(3, result.mColors.length); + Assert.assertEquals(color1, result.mColors[0]); + Assert.assertEquals(color2, result.mColors[1]); + Assert.assertEquals(color3, result.mColors[2]); + Assert.assertEquals(3, result.mStartPoints.length); + Assert.assertEquals(startPoint1, result.mStartPoints[0], 0); + Assert.assertEquals(startPoint2, result.mStartPoints[1], 0); + Assert.assertEquals(startPoint3, result.mStartPoints[2], 0); + Assert.assertEquals(colorMapSize, result.mColorMapSize); + } + + @Test() + public void ConvertInterpretHeatmapOptionsReturnsCorrectData() { + final double intensity = 3.3; + final List dataData = List.of(List.of(List.of(1.1, 2.2), intensity)); + final Point point = sProjection.toPoint(new LatLng(1.1, 2.2)); + + final int color1 = 0; + final int color2 = 1; + final int color3 = 2; + final List colorData = List.of(color1, color2, color3); + final double startPoint1 = 0.0; + final double startPoint2 = 1.0; + final double startPoint3 = 2.0; + List startPointData = List.of(startPoint1, startPoint2, startPoint3); + final int colorMapSize = 3; + final Map gradientData = + Map.of( + HEATMAP_GRADIENT_COLORS_KEY, colorData, + HEATMAP_GRADIENT_START_POINTS_KEY, startPointData, + HEATMAP_GRADIENT_COLOR_MAP_SIZE_KEY, colorMapSize); + + final double maxIntensity = 4.4; + final double opacity = 5.5; + final int radius = 6; + final String idData = "heatmap_1"; + + final Map data = + Map.of( + HEATMAP_DATA_KEY, + dataData, + HEATMAP_GRADIENT_KEY, + gradientData, + HEATMAP_MAX_INTENSITY_KEY, + maxIntensity, + HEATMAP_OPACITY_KEY, + opacity, + HEATMAP_RADIUS_KEY, + radius, + HEATMAP_ID_KEY, + idData); + + final MockHeatmapBuilder builder = new MockHeatmapBuilder(); + final String id = Convert.interpretHeatmapOptions(data, builder); + + Assert.assertEquals(1, builder.getWeightedData().size()); + Assert.assertEquals(point.x, builder.getWeightedData().get(0).getPoint().x, 0); + Assert.assertEquals(point.y, builder.getWeightedData().get(0).getPoint().y, 0); + Assert.assertEquals(intensity, builder.getWeightedData().get(0).getIntensity(), 0); + Assert.assertEquals(3, builder.getGradient().mColors.length); + Assert.assertEquals(color1, builder.getGradient().mColors[0]); + Assert.assertEquals(color2, builder.getGradient().mColors[1]); + Assert.assertEquals(color3, builder.getGradient().mColors[2]); + Assert.assertEquals(3, builder.getGradient().mStartPoints.length); + Assert.assertEquals(startPoint1, builder.getGradient().mStartPoints[0], 0); + Assert.assertEquals(startPoint2, builder.getGradient().mStartPoints[1], 0); + Assert.assertEquals(startPoint3, builder.getGradient().mStartPoints[2], 0); + Assert.assertEquals(colorMapSize, builder.getGradient().mColorMapSize); + Assert.assertEquals(maxIntensity, builder.getMaxIntensity(), 0); + Assert.assertEquals(opacity, builder.getOpacity(), 0); + Assert.assertEquals(radius, builder.getRadius()); + Assert.assertEquals(idData, id); + } + private InputStream buildImageInputStream() { Bitmap fakeBitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); fakeBitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream); byte[] byteArray = byteArrayOutputStream.toByteArray(); - InputStream fakeStream = new ByteArrayInputStream(byteArray); - return fakeStream; + return new ByteArrayInputStream(byteArray); } // Helper method to generate 1x1 pixel base64 encoded png test image @@ -359,8 +691,59 @@ private String generateBase64Image() { byte[] pngBytes = outputStream.toByteArray(); // Encode the PNG bytes as a base64 string - String base64Image = Base64.encodeToString(pngBytes, Base64.DEFAULT); + return Base64.encodeToString(pngBytes, Base64.DEFAULT); + } +} + +class MockHeatmapBuilder implements HeatmapOptionsSink { + private List weightedData; + private Gradient gradient; + private double maxIntensity; + private double opacity; + private int radius; + + public List getWeightedData() { + return weightedData; + } + + public Gradient getGradient() { + return gradient; + } + + public double getMaxIntensity() { + return maxIntensity; + } + + public double getOpacity() { + return opacity; + } + + public int getRadius() { + return radius; + } + + @Override + public void setWeightedData(@NonNull List weightedData) { + this.weightedData = weightedData; + } + + @Override + public void setGradient(@NonNull Gradient gradient) { + this.gradient = gradient; + } + + @Override + public void setMaxIntensity(double maxIntensity) { + this.maxIntensity = maxIntensity; + } + + @Override + public void setOpacity(double opacity) { + this.opacity = opacity; + } - return base64Image; + @Override + public void setRadius(int radius) { + this.radius = radius; } } diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/GoogleMapControllerTest.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/GoogleMapControllerTest.java index 3459b9b3139f..48d8b619bebc 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/GoogleMapControllerTest.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/GoogleMapControllerTest.java @@ -6,7 +6,6 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; @@ -21,11 +20,8 @@ import com.google.android.gms.maps.model.Marker; import com.google.maps.android.clustering.ClusterManager; import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.MethodChannel; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -38,7 +34,7 @@ import org.robolectric.annotation.Config; @RunWith(RobolectricTestRunner.class) -@Config(sdk = Build.VERSION_CODES.P) +@Config(minSdk = Build.VERSION_CODES.LOLLIPOP) public class GoogleMapControllerTest { private Context context; @@ -47,12 +43,13 @@ public class GoogleMapControllerTest { AutoCloseable mockCloseable; @Mock BinaryMessenger mockMessenger; @Mock GoogleMap mockGoogleMap; - @Mock MethodChannel mockMethodChannel; + @Mock Messages.MapsCallbackApi flutterApi; @Mock ClusterManagersController mockClusterManagersController; @Mock MarkersController mockMarkersController; @Mock PolygonsController mockPolygonsController; @Mock PolylinesController mockPolylinesController; @Mock CirclesController mockCirclesController; + @Mock HeatmapsController mockHeatmapsController; @Mock TileOverlaysController mockTileOverlaysController; @Before @@ -78,7 +75,7 @@ public GoogleMapController getGoogleMapControllerWithMockedDependencies() { 0, context, mockMessenger, - mockMethodChannel, + flutterApi, activity::getLifecycle, null, mockClusterManagersController, @@ -86,6 +83,7 @@ public GoogleMapController getGoogleMapControllerWithMockedDependencies() { mockPolygonsController, mockPolylinesController, mockCirclesController, + mockHeatmapsController, mockTileOverlaysController); googleMapController.init(); return googleMapController; @@ -104,19 +102,19 @@ public void tearDown() throws Exception { } @Test - public void DisposeReleaseTheMap() throws InterruptedException { + public void DisposeReleaseTheMap() { GoogleMapController googleMapController = getGoogleMapController(); googleMapController.onMapReady(mockGoogleMap); - assertTrue(googleMapController != null); + assertNotNull(googleMapController); googleMapController.dispose(); assertNull(googleMapController.getView()); } @Test - public void OnDestroyReleaseTheMap() throws InterruptedException { + public void OnDestroyReleaseTheMap() { GoogleMapController googleMapController = getGoogleMapController(); googleMapController.onMapReady(mockGoogleMap); - assertTrue(googleMapController != null); + assertNotNull(googleMapController); googleMapController.onDestroy(activity); assertNull(googleMapController.getView()); } @@ -195,9 +193,9 @@ public void OnMapReadySetsClusterItemRenderedListener() { @Test public void SetInitialClusterManagers() { GoogleMapController googleMapController = getGoogleMapControllerWithMockedDependencies(); - Map initialClusterManager = new HashMap<>(); - initialClusterManager.put("clusterManagerId", "cm_1"); - List initialClusterManagers = new ArrayList<>(); + Messages.PlatformClusterManager initialClusterManager = + new Messages.PlatformClusterManager.Builder().setIdentifier("cm_1").build(); + List initialClusterManagers = new ArrayList<>(); initialClusterManagers.add(initialClusterManager); googleMapController.setInitialClusterManagers(initialClusterManagers); googleMapController.onMapReady(mockGoogleMap); @@ -223,4 +221,31 @@ public void OnClusterItemClickCallsMarkersController() { googleMapController.onClusterItemClick(markerBuilder); verify(mockMarkersController, times(1)).onMarkerTap(markerBuilder.markerId()); } + + @Test + public void SetInitialHeatmaps() { + GoogleMapController googleMapController = getGoogleMapControllerWithMockedDependencies(); + + List initialHeatmaps = List.of(new Messages.PlatformHeatmap()); + googleMapController.setInitialHeatmaps(initialHeatmaps); + googleMapController.onMapReady(mockGoogleMap); + + // Verify if the HeatmapsController.addHeatmaps method is called with initial heatmaps. + verify(mockHeatmapsController, times(1)).addHeatmaps(initialHeatmaps); + } + + @Test + public void UpdateHeatmaps() { + GoogleMapController googleMapController = getGoogleMapControllerWithMockedDependencies(); + + final List toAdd = List.of(new Messages.PlatformHeatmap()); + final List toChange = List.of(new Messages.PlatformHeatmap()); + final List idsToRemove = List.of("hm_1"); + + googleMapController.updateHeatmaps(toAdd, toChange, idsToRemove); + + verify(mockHeatmapsController, times(1)).addHeatmaps(toAdd); + verify(mockHeatmapsController, times(1)).changeHeatmaps(toChange); + verify(mockHeatmapsController, times(1)).removeHeatmaps(idsToRemove); + } } diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/GoogleMapInitializerTest.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/GoogleMapInitializerTest.java index 2f9f5e5619fd..302e48cb720a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/GoogleMapInitializerTest.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/GoogleMapInitializerTest.java @@ -6,7 +6,6 @@ import static org.mockito.Mockito.any; import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; @@ -18,9 +17,6 @@ import androidx.test.core.app.ApplicationProvider; import com.google.android.gms.maps.MapsInitializer.Renderer; import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.MethodCall; -import io.flutter.plugin.common.MethodChannel; -import java.util.HashMap; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -30,7 +26,7 @@ import org.robolectric.annotation.Config; @RunWith(RobolectricTestRunner.class) -@Config(sdk = Build.VERSION_CODES.P) +@Config(minSdk = Build.VERSION_CODES.LOLLIPOP) public class GoogleMapInitializerTest { private GoogleMapInitializer googleMapInitializer; @@ -46,53 +42,33 @@ public void before() { @Test public void initializer_OnMapsSdkInitializedWithLatestRenderer() { doNothing().when(googleMapInitializer).initializeWithRendererRequest(Renderer.LATEST); - MethodChannel.Result result = mock(MethodChannel.Result.class); - googleMapInitializer.onMethodCall( - new MethodCall( - "initializer#preferRenderer", - new HashMap() { - { - put("value", "latest"); - } - }), - result); + @SuppressWarnings("unchecked") + Messages.Result result = mock(Messages.Result.class); + googleMapInitializer.initializeWithPreferredRenderer( + Messages.PlatformRendererType.LATEST, result); googleMapInitializer.onMapsSdkInitialized(Renderer.LATEST); - verify(result, times(1)).success("latest"); - verify(result, never()).error(any(), any(), any()); + verify(result, times(1)).success(Messages.PlatformRendererType.LATEST); + verify(result, never()).error(any()); } @Test public void initializer_OnMapsSdkInitializedWithLegacyRenderer() { doNothing().when(googleMapInitializer).initializeWithRendererRequest(Renderer.LEGACY); - MethodChannel.Result result = mock(MethodChannel.Result.class); - googleMapInitializer.onMethodCall( - new MethodCall( - "initializer#preferRenderer", - new HashMap() { - { - put("value", "legacy"); - } - }), - result); + @SuppressWarnings("unchecked") + Messages.Result result = mock(Messages.Result.class); + googleMapInitializer.initializeWithPreferredRenderer( + Messages.PlatformRendererType.LEGACY, result); googleMapInitializer.onMapsSdkInitialized(Renderer.LEGACY); - verify(result, times(1)).success("legacy"); - verify(result, never()).error(any(), any(), any()); + verify(result, times(1)).success(Messages.PlatformRendererType.LEGACY); + verify(result, never()).error(any()); } @Test - public void initializer_onMethodCallWithUnknownRenderer() { - doNothing().when(googleMapInitializer).initializeWithRendererRequest(Renderer.LEGACY); - MethodChannel.Result result = mock(MethodChannel.Result.class); - googleMapInitializer.onMethodCall( - new MethodCall( - "initializer#preferRenderer", - new HashMap() { - { - put("value", "wrong_renderer"); - } - }), - result); - verify(result, never()).success(any()); - verify(result, times(1)).error(eq("Invalid renderer type"), any(), any()); + public void initializer_onMethodCallWithNoRendererPreference() { + doNothing().when(googleMapInitializer).initializeWithRendererRequest(null); + @SuppressWarnings("unchecked") + Messages.Result result = mock(Messages.Result.class); + googleMapInitializer.initializeWithPreferredRenderer(null, result); + verify(result, never()).error(any()); } } diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/HeatmapsControllerTest.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/HeatmapsControllerTest.java new file mode 100644 index 000000000000..59c4560f97d4 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/HeatmapsControllerTest.java @@ -0,0 +1,105 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.googlemaps; + +import static io.flutter.plugins.googlemaps.Convert.HEATMAP_DATA_KEY; +import static io.flutter.plugins.googlemaps.Convert.HEATMAP_ID_KEY; +import static io.flutter.plugins.googlemaps.Convert.HEATMAP_OPACITY_KEY; +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; + +import android.os.Build; +import com.google.android.gms.maps.GoogleMap; +import com.google.android.gms.maps.model.TileOverlay; +import com.google.android.gms.maps.model.TileOverlayOptions; +import com.google.maps.android.heatmaps.HeatmapTileProvider; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +@RunWith(RobolectricTestRunner.class) +@Config(minSdk = Build.VERSION_CODES.LOLLIPOP) +public class HeatmapsControllerTest { + private HeatmapsController controller; + private GoogleMap googleMap; + + @Before + public void setUp() { + controller = spy(new HeatmapsController()); + googleMap = mock(GoogleMap.class); + controller.setGoogleMap(googleMap); + } + + @Test(expected = IllegalArgumentException.class) + public void controller_AddHeatmapThrowsErrorIfHeatmapIdIsNull() { + final Map heatmapOptions = new HashMap<>(); + + final List heatmaps = + Collections.singletonList( + new Messages.PlatformHeatmap.Builder().setJson(heatmapOptions).build()); + try { + controller.addHeatmaps(heatmaps); + } catch (IllegalArgumentException e) { + assertEquals("heatmapId was null", e.getMessage()); + throw e; + } + } + + @Test + public void controller_AddChangeAndRemoveHeatmap() { + final TileOverlay tileOverlay = mock(TileOverlay.class); + final HeatmapTileProvider heatmap = mock(HeatmapTileProvider.class); + + final String googleHeatmapId = "abc123"; + final Object heatmapData = + Collections.singletonList(Arrays.asList(Arrays.asList(1.1, 2.2), 3.3)); + + when(googleMap.addTileOverlay(any(TileOverlayOptions.class))).thenReturn(tileOverlay); + doReturn(heatmap).when(controller).buildHeatmap(any(HeatmapBuilder.class)); + + final Map heatmapOptions1 = new HashMap<>(); + heatmapOptions1.put(HEATMAP_ID_KEY, googleHeatmapId); + heatmapOptions1.put(HEATMAP_DATA_KEY, heatmapData); + + final List heatmaps = + Collections.singletonList( + new Messages.PlatformHeatmap.Builder().setJson(heatmapOptions1).build()); + controller.addHeatmaps(heatmaps); + + Mockito.verify(googleMap, times(1)) + .addTileOverlay( + Mockito.argThat(argument -> argument.getTileProvider() instanceof HeatmapTileProvider)); + + final float opacity = 0.1f; + final Map heatmapOptions2 = new HashMap<>(); + heatmapOptions2.put(HEATMAP_ID_KEY, googleHeatmapId); + heatmapOptions2.put(HEATMAP_DATA_KEY, heatmapData); + heatmapOptions2.put(HEATMAP_OPACITY_KEY, opacity); + + final List heatmapUpdates = + Collections.singletonList( + new Messages.PlatformHeatmap.Builder().setJson(heatmapOptions2).build()); + + controller.changeHeatmaps(heatmapUpdates); + Mockito.verify(heatmap, times(1)).setOpacity(opacity); + + controller.removeHeatmaps(Collections.singletonList(googleHeatmapId)); + + Mockito.verify(tileOverlay, times(1)).remove(); + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/MarkersControllerTest.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/MarkersControllerTest.java index 116f8381bce3..1540ebccf69c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/MarkersControllerTest.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/MarkersControllerTest.java @@ -6,6 +6,7 @@ import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; @@ -13,6 +14,7 @@ import android.content.Context; import android.content.res.AssetManager; +import android.graphics.Bitmap; import android.os.Build; import androidx.test.core.app.ApplicationProvider; import com.google.android.gms.maps.GoogleMap; @@ -21,27 +23,26 @@ import com.google.android.gms.maps.model.MarkerOptions; import com.google.maps.android.collections.MarkerManager; import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.MethodChannel; -import io.flutter.plugin.common.MethodCodec; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; +import io.flutter.plugins.googlemaps.Messages.MapsCallbackApi; +import java.io.ByteArrayOutputStream; +import java.util.Collections; import java.util.List; -import java.util.Map; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; @RunWith(RobolectricTestRunner.class) -@Config(sdk = Build.VERSION_CODES.P) +@Config(minSdk = Build.VERSION_CODES.LOLLIPOP) public class MarkersControllerTest { private Context context; - private MethodChannel methodChannel; + private MapsCallbackApi flutterApi; private ClusterManagersController clusterManagersController; private MarkersController controller; private GoogleMap googleMap; @@ -49,17 +50,57 @@ public class MarkersControllerTest { private MarkerManager.Collection markerCollection; private AssetManager assetManager; private final float density = 1; + private AutoCloseable mocksClosable; + + @Mock private Convert.BitmapDescriptorFactoryWrapper bitmapDescriptorFactoryWrapper; + + private static Messages.PlatformMarker.Builder defaultMarkerBuilder() { + Bitmap fakeBitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + fakeBitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream); + byte[] byteArray = byteArrayOutputStream.toByteArray(); + Messages.PlatformBitmap icon = + new Messages.PlatformBitmap.Builder() + .setBitmap( + new Messages.PlatformBitmapBytesMap.Builder() + .setByteData(byteArray) + .setImagePixelRatio(1.0) + .setBitmapScaling(Messages.PlatformMapBitmapScaling.NONE) + .build()) + .build(); + Messages.PlatformDoublePair anchor = + new Messages.PlatformDoublePair.Builder().setX(0.5).setY(0.0).build(); + Messages.PlatformInfoWindow infoWindow = + new Messages.PlatformInfoWindow.Builder().setAnchor(anchor).build(); + return new Messages.PlatformMarker.Builder() + .setPosition( + new Messages.PlatformLatLng.Builder().setLatitude(0.0).setLongitude(0.0).build()) + .setAnchor(new Messages.PlatformDoublePair.Builder().setX(0.0).setY(0.0).build()) + .setFlat(false) + .setDraggable(false) + .setVisible(true) + .setAlpha(1.0) + .setRotation(0.0) + .setZIndex(0.0) + .setConsumeTapEvents(false) + .setIcon(icon) + .setInfoWindow(infoWindow); + } @Before public void setUp() { - MockitoAnnotations.openMocks(this); + mocksClosable = MockitoAnnotations.openMocks(this); assetManager = ApplicationProvider.getApplicationContext().getAssets(); context = ApplicationProvider.getApplicationContext(); - methodChannel = - spy(new MethodChannel(mock(BinaryMessenger.class), "no-name", mock(MethodCodec.class))); - clusterManagersController = spy(new ClusterManagersController(methodChannel, context)); + flutterApi = spy(new MapsCallbackApi(mock(BinaryMessenger.class))); + clusterManagersController = spy(new ClusterManagersController(flutterApi, context)); controller = - new MarkersController(methodChannel, clusterManagersController, assetManager, density); + new MarkersController( + flutterApi, + clusterManagersController, + assetManager, + density, + bitmapDescriptorFactoryWrapper); googleMap = mock(GoogleMap.class); markerManager = new MarkerManager(googleMap); markerCollection = markerManager.newCollection(); @@ -67,6 +108,11 @@ public void setUp() { clusterManagersController.init(googleMap, markerManager); } + @After + public void close() throws Exception { + mocksClosable.close(); + } + @Test public void controller_OnMarkerDragStart() { final Marker marker = mock(Marker.class); @@ -77,21 +123,14 @@ public void controller_OnMarkerDragStart() { when(googleMap.addMarker(any(MarkerOptions.class))).thenReturn(marker); final LatLng latLng = new LatLng(1.1, 2.2); - final Map markerOptions = new HashMap<>(); - markerOptions.put("markerId", googleMarkerId); - final List markers = Arrays.asList(markerOptions); + final List markers = + Collections.singletonList(defaultMarkerBuilder().setMarkerId(googleMarkerId).build()); controller.addMarkers(markers); controller.onMarkerDragStart(googleMarkerId, latLng); - final List points = new ArrayList<>(); - points.add(latLng.latitude); - points.add(latLng.longitude); - - final Map data = new HashMap<>(); - data.put("markerId", googleMarkerId); - data.put("position", points); - Mockito.verify(methodChannel).invokeMethod("marker#onDragStart", data); + Mockito.verify(flutterApi) + .onMarkerDragStart(eq(googleMarkerId), eq(Convert.latLngToPigeon(latLng)), any()); } @Test @@ -104,21 +143,14 @@ public void controller_OnMarkerDragEnd() { when(googleMap.addMarker(any(MarkerOptions.class))).thenReturn(marker); final LatLng latLng = new LatLng(1.1, 2.2); - final Map markerOptions = new HashMap<>(); - markerOptions.put("markerId", googleMarkerId); - final List markers = Arrays.asList(markerOptions); + final List markers = + Collections.singletonList(defaultMarkerBuilder().setMarkerId(googleMarkerId).build()); controller.addMarkers(markers); controller.onMarkerDragEnd(googleMarkerId, latLng); - final List points = new ArrayList<>(); - points.add(latLng.latitude); - points.add(latLng.longitude); - - final Map data = new HashMap<>(); - data.put("markerId", googleMarkerId); - data.put("position", points); - Mockito.verify(methodChannel).invokeMethod("marker#onDragEnd", data); + Mockito.verify(flutterApi) + .onMarkerDragEnd(eq(googleMarkerId), eq(Convert.latLngToPigeon(latLng)), any()); } @Test @@ -131,31 +163,24 @@ public void controller_OnMarkerDrag() { when(googleMap.addMarker(any(MarkerOptions.class))).thenReturn(marker); final LatLng latLng = new LatLng(1.1, 2.2); - final Map markerOptions = new HashMap<>(); - markerOptions.put("markerId", googleMarkerId); - final List markers = Arrays.asList(markerOptions); + final List markers = + Collections.singletonList(defaultMarkerBuilder().setMarkerId(googleMarkerId).build()); + controller.addMarkers(markers); controller.onMarkerDrag(googleMarkerId, latLng); - final List points = new ArrayList<>(); - points.add(latLng.latitude); - points.add(latLng.longitude); - - final Map data = new HashMap<>(); - data.put("markerId", googleMarkerId); - data.put("position", points); - Mockito.verify(methodChannel).invokeMethod("marker#onDrag", data); + Mockito.verify(flutterApi) + .onMarkerDrag(eq(googleMarkerId), eq(Convert.latLngToPigeon(latLng)), any()); } - @Test(expected = IllegalArgumentException.class) + @Test(expected = IllegalStateException.class) public void controller_AddMarkerThrowsErrorIfMarkerIdIsNull() { - final Map markerOptions = new HashMap<>(); - - final List markers = Arrays.asList(markerOptions); + final List markers = + Collections.singletonList(defaultMarkerBuilder().build()); try { controller.addMarkers(markers); - } catch (IllegalArgumentException e) { + } catch (IllegalStateException e) { assertEquals("markerId was null", e.getMessage()); throw e; } @@ -168,22 +193,17 @@ public void controller_AddChangeAndRemoveMarkerWithClusterManagerId() { final String googleMarkerId = "abc123"; final String clusterManagerId = "cm123"; - when(marker.getId()).thenReturn(googleMarkerId); - - final LatLng latLng1 = new LatLng(1.1, 2.2); - final List location1 = new ArrayList<>(); - location1.add(latLng1.latitude); - location1.add(latLng1.longitude); + final Messages.PlatformMarker.Builder builder = defaultMarkerBuilder(); + builder + .setMarkerId(googleMarkerId) + .setClusterManagerId(clusterManagerId) + .setPosition( + new Messages.PlatformLatLng.Builder().setLatitude(1.1).setLongitude(2.2).build()); - final Map markerOptions1 = new HashMap<>(); - markerOptions1.put("markerId", googleMarkerId); - markerOptions1.put("position", location1); - markerOptions1.put("clusterManagerId", clusterManagerId); - - final List markers = Arrays.asList(markerOptions1); + when(marker.getId()).thenReturn(googleMarkerId); // Add marker and capture the markerBuilder - controller.addMarkers(markers); + controller.addMarkers(Collections.singletonList(builder.build())); ArgumentCaptor captor = ArgumentCaptor.forClass(MarkerBuilder.class); Mockito.verify(clusterManagersController, times(1)).addItem(captor.capture()); MarkerBuilder capturedMarkerBuilder = captor.getValue(); @@ -194,21 +214,19 @@ public void controller_AddChangeAndRemoveMarkerWithClusterManagerId() { // Change marker to test that markerController is created and the marker can be updated final LatLng latLng2 = new LatLng(3.3, 4.4); - final List location2 = new ArrayList<>(); - location2.add(latLng2.latitude); - location2.add(latLng2.longitude); - final Map markerOptions2 = new HashMap<>(); - markerOptions2.put("markerId", googleMarkerId); - markerOptions2.put("position", location2); - markerOptions2.put("clusterManagerId", clusterManagerId); - final List updatedMarkers = Arrays.asList(markerOptions2); + builder.setPosition( + new Messages.PlatformLatLng.Builder() + .setLatitude(latLng2.latitude) + .setLongitude(latLng2.longitude) + .build()); + final List updatedMarkers = Collections.singletonList(builder.build()); controller.changeMarkers(updatedMarkers); Mockito.verify(marker, times(1)).setPosition(latLng2); // Remove marker - controller.removeMarkers(Arrays.asList(googleMarkerId)); + controller.removeMarkers(Collections.singletonList(googleMarkerId)); Mockito.verify(clusterManagersController, times(1)) .removeItem( @@ -228,11 +246,9 @@ public void controller_AddChangeAndRemoveMarkerWithoutClusterManagerId() { when(marker.getId()).thenReturn(googleMarkerId); when(googleMap.addMarker(any(MarkerOptions.class))).thenReturn(marker); - final Map markerOptions1 = new HashMap<>(); - markerOptions1.put("markerId", googleMarkerId); - - final List markers = Arrays.asList(markerOptions1); - controller.addMarkers(markers); + final Messages.PlatformMarker.Builder builder = defaultMarkerBuilder(); + builder.setMarkerId(googleMarkerId); + controller.addMarkers(Collections.singletonList(builder.build())); // clusterManagersController should not be called when adding the marker Mockito.verify(clusterManagersController, times(0)).addItem(any()); @@ -240,15 +256,13 @@ public void controller_AddChangeAndRemoveMarkerWithoutClusterManagerId() { Mockito.verify(spyMarkerCollection, times(1)).addMarker(any(MarkerOptions.class)); final float alpha = 0.1f; - final Map markerOptions2 = new HashMap<>(); - markerOptions2.put("markerId", googleMarkerId); - markerOptions2.put("alpha", alpha); - final List markerUpdates = Arrays.asList(markerOptions2); + final List markerUpdates = + Collections.singletonList(builder.setAlpha((double) alpha).build()); controller.changeMarkers(markerUpdates); Mockito.verify(marker, times(1)).setAlpha(alpha); - controller.removeMarkers(Arrays.asList(googleMarkerId)); + controller.removeMarkers(Collections.singletonList(googleMarkerId)); // clusterManagersController should not be called when removing the marker Mockito.verify(clusterManagersController, times(0)).removeItem(any()); diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/android/app/build.gradle b/packages/google_maps_flutter/google_maps_flutter_android/example/android/app/build.gradle index 6ab57de08264..8107f238eb47 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/example/android/app/build.gradle +++ b/packages/google_maps_flutter/google_maps_flutter_android/example/android/app/build.gradle @@ -32,8 +32,7 @@ android { defaultConfig { applicationId "io.flutter.plugins.googlemapsexample" minSdkVersion flutter.minSdkVersion - targetSdkVersion 28 - multiDexEnabled true + targetSdkVersion 34 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/google_maps_flutter/google_maps_flutter_android/example/android/app/gradle/wrapper/gradle-wrapper.properties index 609ab8e6c8b5..d951fac2bf31 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ b/packages/google_maps_flutter/google_maps_flutter_android/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/android/app/src/main/AndroidManifest.xml b/packages/google_maps_flutter/google_maps_flutter_android/example/android/app/src/main/AndroidManifest.xml index 2055ca8d25ee..9dce53b155c2 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/example/android/app/src/main/AndroidManifest.xml +++ b/packages/google_maps_flutter/google_maps_flutter_android/example/android/app/src/main/AndroidManifest.xml @@ -1,11 +1,13 @@ - + - @@ -13,6 +15,7 @@ android:name="com.google.android.geo.API_KEY" android:value="${mapsApiKey}" /> { TextButton( onPressed: (selectedId == null) ? null - : ((polygons[selectedId]!.holes.isNotEmpty) + : (polygons[selectedId]!.holes.isNotEmpty ? null : () => _addHoles(selectedId)), child: const Text('add holes'), @@ -234,7 +234,7 @@ class PlacePolygonBodyState extends State { TextButton( onPressed: (selectedId == null) ? null - : ((polygons[selectedId]!.holes.isEmpty) + : (polygons[selectedId]!.holes.isEmpty ? null : () => _removeHoles(selectedId)), child: const Text('remove holes'), diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_android/example/pubspec.yaml index ddac3d7b231c..4aac17d849b7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_android/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the google_maps_flutter plugin. publish_to: none environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" dependencies: cupertino_icons: ^1.0.5 @@ -18,11 +18,11 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - google_maps_flutter_platform_interface: ^2.7.0 + google_maps_flutter_platform_interface: ^2.9.2 dev_dependencies: build_runner: ^2.1.10 - espresso: ^0.2.0 + espresso: ^0.4.0 flutter_test: sdk: flutter integration_test: diff --git a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_map_inspector_android.dart b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_map_inspector_android.dart index abe361566b67..76b8a8ce75d0 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_map_inspector_android.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_map_inspector_android.dart @@ -75,6 +75,9 @@ class GoogleMapsInspectorAndroid extends GoogleMapsInspectorPlatform { ); } + @override + bool supportsGettingHeatmapInfo() => false; + @override Future isCompassEnabled({required int mapId}) async { return _inspectorProvider(mapId)!.isCompassEnabled(); diff --git a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_maps_flutter_android.dart b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_maps_flutter_android.dart index 0664ae3accd5..038d5fe16d41 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_maps_flutter_android.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_maps_flutter_android.dart @@ -14,7 +14,7 @@ import 'package:stream_transform/stream_transform.dart'; import 'google_map_inspector_android.dart'; import 'messages.g.dart'; -import 'utils/cluster_manager_utils.dart'; +import 'serialization.dart'; // TODO(stuartmorgan): Remove the dependency on platform interface toJson // methods. Channel serialization details should all be package-internal. @@ -70,27 +70,15 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { GoogleMapsFlutterPlatform.instance = GoogleMapsFlutterAndroid(); } - /// The method channel used to initialize the native Google Maps SDK. - final MethodChannel _initializerChannel = const MethodChannel( - 'plugins.flutter.dev/google_maps_android_initializer'); - - // Keep a collection of id -> channel - // Every method call passes the int mapId - final Map _channels = {}; - final Map _hostMaps = {}; // A method to create MapsApi instances, which can be overridden for testing. final MapsApi Function(int mapId) _apiProvider; - /// Accesses the MethodChannel associated to the passed mapId. - MethodChannel _channel(int mapId) { - final MethodChannel? channel = _channels[mapId]; - if (channel == null) { - throw UnknownMapIDError(mapId); - } - return channel; - } + /// The per-map handlers for callbacks from the host side. + @visibleForTesting + final Map hostMapHandlers = + {}; /// Accesses the MapsApi associated to the passed mapId. MapsApi _hostApi(int mapId) { @@ -105,17 +93,23 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { final Map> _tileOverlays = >{}; - /// Returns the channel for [mapId], creating it if it doesn't already exist. + /// Returns the handler for [mapId], creating it if it doesn't already exist. @visibleForTesting - MethodChannel ensureChannelInitialized(int mapId) { - MethodChannel? channel = _channels[mapId]; - if (channel == null) { - channel = MethodChannel('plugins.flutter.dev/google_maps_android_$mapId'); - channel.setMethodCallHandler( - (MethodCall call) => _handleMethodCall(call, mapId)); - _channels[mapId] = channel; + HostMapMessageHandler ensureHandlerInitialized(int mapId) { + HostMapMessageHandler? handler = hostMapHandlers[mapId]; + if (handler == null) { + handler = HostMapMessageHandler( + mapId, + _mapEventStreamController, + tileOverlayProvider: (TileOverlayId tileOverlayId) { + final Map? tileOverlaysForMap = + _tileOverlays[mapId]; + return tileOverlaysForMap?[tileOverlayId]; + }, + ); + hostMapHandlers[mapId] = handler; } - return channel; + return handler; } /// Returns the API instance for [mapId], creating it if it doesn't already @@ -132,7 +126,7 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { @override Future init(int mapId) { - ensureChannelInitialized(mapId); + ensureHandlerInitialized(mapId); final MapsApi hostApi = ensureApiInitialized(mapId); return hostApi.waitForMap(); } @@ -225,120 +219,13 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { return _events(mapId).whereType(); } - Future _handleMethodCall(MethodCall call, int mapId) async { - switch (call.method) { - case 'camera#onMoveStarted': - _mapEventStreamController.add(CameraMoveStartedEvent(mapId)); - case 'camera#onMove': - final Map arguments = _getArgumentDictionary(call); - _mapEventStreamController.add(CameraMoveEvent( - mapId, - CameraPosition.fromMap(arguments['position'])!, - )); - case 'camera#onIdle': - _mapEventStreamController.add(CameraIdleEvent(mapId)); - case 'marker#onTap': - final Map arguments = _getArgumentDictionary(call); - _mapEventStreamController.add(MarkerTapEvent( - mapId, - MarkerId(arguments['markerId']! as String), - )); - case 'marker#onDragStart': - final Map arguments = _getArgumentDictionary(call); - _mapEventStreamController.add(MarkerDragStartEvent( - mapId, - LatLng.fromJson(arguments['position'])!, - MarkerId(arguments['markerId']! as String), - )); - case 'marker#onDrag': - final Map arguments = _getArgumentDictionary(call); - _mapEventStreamController.add(MarkerDragEvent( - mapId, - LatLng.fromJson(arguments['position'])!, - MarkerId(arguments['markerId']! as String), - )); - case 'marker#onDragEnd': - final Map arguments = _getArgumentDictionary(call); - _mapEventStreamController.add(MarkerDragEndEvent( - mapId, - LatLng.fromJson(arguments['position'])!, - MarkerId(arguments['markerId']! as String), - )); - case 'infoWindow#onTap': - final Map arguments = _getArgumentDictionary(call); - _mapEventStreamController.add(InfoWindowTapEvent( - mapId, - MarkerId(arguments['markerId']! as String), - )); - case 'polyline#onTap': - final Map arguments = _getArgumentDictionary(call); - _mapEventStreamController.add(PolylineTapEvent( - mapId, - PolylineId(arguments['polylineId']! as String), - )); - case 'polygon#onTap': - final Map arguments = _getArgumentDictionary(call); - _mapEventStreamController.add(PolygonTapEvent( - mapId, - PolygonId(arguments['polygonId']! as String), - )); - case 'circle#onTap': - final Map arguments = _getArgumentDictionary(call); - _mapEventStreamController.add(CircleTapEvent( - mapId, - CircleId(arguments['circleId']! as String), - )); - case 'map#onTap': - final Map arguments = _getArgumentDictionary(call); - _mapEventStreamController.add(MapTapEvent( - mapId, - LatLng.fromJson(arguments['position'])!, - )); - case 'map#onLongPress': - final Map arguments = _getArgumentDictionary(call); - _mapEventStreamController.add(MapLongPressEvent( - mapId, - LatLng.fromJson(arguments['position'])!, - )); - case 'tileOverlay#getTile': - final Map arguments = _getArgumentDictionary(call); - final Map? tileOverlaysForThisMap = - _tileOverlays[mapId]; - final String tileOverlayId = arguments['tileOverlayId']! as String; - final TileOverlay? tileOverlay = - tileOverlaysForThisMap?[TileOverlayId(tileOverlayId)]; - final TileProvider? tileProvider = tileOverlay?.tileProvider; - if (tileProvider == null) { - return TileProvider.noTile.toJson(); - } - final Tile tile = await tileProvider.getTile( - arguments['x']! as int, - arguments['y']! as int, - arguments['zoom'] as int?, - ); - return tile.toJson(); - case 'cluster#onTap': - final Map arguments = _getArgumentDictionary(call); - final Cluster cluster = parseCluster( - arguments['clusterManagerId']! as String, - arguments['position']!, - arguments['bounds']! as Map, - arguments['markerIds']! as List); - _mapEventStreamController.add(ClusterTapEvent( - mapId, - cluster, - )); - default: - throw MissingPluginException(); - } - } - - /// Returns the arguments of [call] as typed string-keyed Map. - /// - /// This does not do any type validation, so is only safe to call if the - /// arguments are known to be a map. - Map _getArgumentDictionary(MethodCall call) { - return (call.arguments as Map).cast(); + @override + Future updateMapConfiguration( + MapConfiguration configuration, { + required int mapId, + }) { + return _hostApi(mapId).updateMapConfiguration( + _platformMapConfigurationFromMapConfiguration(configuration)); } @override @@ -346,12 +233,8 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { Map optionsUpdate, { required int mapId, }) { - return _channel(mapId).invokeMethod( - 'map#update', - { - 'options': optionsUpdate, - }, - ); + return _hostApi(mapId).updateMapConfiguration( + _platformMapConfigurationFromOptionsJson(optionsUpdate)); } @override @@ -359,9 +242,10 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { MarkerUpdates markerUpdates, { required int mapId, }) { - return _channel(mapId).invokeMethod( - 'markers#update', - markerUpdates.toJson(), + return _hostApi(mapId).updateMarkers( + markerUpdates.markersToAdd.map(_platformMarkerFromMarker).toList(), + markerUpdates.markersToChange.map(_platformMarkerFromMarker).toList(), + markerUpdates.markerIdsToRemove.map((MarkerId id) => id.value).toList(), ); } @@ -370,9 +254,12 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { PolygonUpdates polygonUpdates, { required int mapId, }) { - return _channel(mapId).invokeMethod( - 'polygons#update', - polygonUpdates.toJson(), + return _hostApi(mapId).updatePolygons( + polygonUpdates.polygonsToAdd.map(_platformPolygonFromPolygon).toList(), + polygonUpdates.polygonsToChange.map(_platformPolygonFromPolygon).toList(), + polygonUpdates.polygonIdsToRemove + .map((PolygonId id) => id.value) + .toList(), ); } @@ -381,9 +268,16 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { PolylineUpdates polylineUpdates, { required int mapId, }) { - return _channel(mapId).invokeMethod( - 'polylines#update', - polylineUpdates.toJson(), + return _hostApi(mapId).updatePolylines( + polylineUpdates.polylinesToAdd + .map(_platformPolylineFromPolyline) + .toList(), + polylineUpdates.polylinesToChange + .map(_platformPolylineFromPolyline) + .toList(), + polylineUpdates.polylineIdsToRemove + .map((PolylineId id) => id.value) + .toList(), ); } @@ -392,9 +286,24 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { CircleUpdates circleUpdates, { required int mapId, }) { - return _channel(mapId).invokeMethod( - 'circles#update', - circleUpdates.toJson(), + return _hostApi(mapId).updateCircles( + circleUpdates.circlesToAdd.map(_platformCircleFromCircle).toList(), + circleUpdates.circlesToChange.map(_platformCircleFromCircle).toList(), + circleUpdates.circleIdsToRemove.map((CircleId id) => id.value).toList(), + ); + } + + @override + Future updateHeatmaps( + HeatmapUpdates heatmapUpdates, { + required int mapId, + }) { + return _hostApi(mapId).updateHeatmaps( + heatmapUpdates.heatmapsToAdd.map(_platformHeatmapFromHeatmap).toList(), + heatmapUpdates.heatmapsToChange.map(_platformHeatmapFromHeatmap).toList(), + heatmapUpdates.heatmapIdsToRemove + .map((HeatmapId id) => id.value) + .toList(), ); } @@ -411,9 +320,16 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { final _TileOverlayUpdates updates = _TileOverlayUpdates.from(previousSet, newTileOverlays); _tileOverlays[mapId] = keyTileOverlayId(newTileOverlays); - return _channel(mapId).invokeMethod( - 'tileOverlays#update', - updates.toJson(), + return _hostApi(mapId).updateTileOverlays( + updates.tileOverlaysToAdd + .map(_platformTileOverlayFromTileOverlay) + .toList(), + updates.tileOverlaysToChange + .map(_platformTileOverlayFromTileOverlay) + .toList(), + updates.tileOverlayIdsToRemove + .map((TileOverlayId id) => id.value) + .toList(), ); } @@ -422,9 +338,13 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { ClusterManagerUpdates clusterManagerUpdates, { required int mapId, }) { - return _channel(mapId).invokeMethod( - 'clusterManagers#update', - serializeClusterManagerUpdates(clusterManagerUpdates), + return _hostApi(mapId).updateClusterManagers( + clusterManagerUpdates.clusterManagersToAdd + .map(_platformClusterManagerFromClusterManager) + .toList(), + clusterManagerUpdates.clusterManagerIdsToRemove + .map((ClusterManagerId id) => id.value) + .toList(), ); } @@ -441,10 +361,8 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { CameraUpdate cameraUpdate, { required int mapId, }) { - return _channel(mapId) - .invokeMethod('camera#animate', { - 'cameraUpdate': cameraUpdate.toJson(), - }); + return _hostApi(mapId) + .animateCamera(_platformCameraUpdateFromCameraUpdate(cameraUpdate)); } @override @@ -452,9 +370,8 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { CameraUpdate cameraUpdate, { required int mapId, }) { - return _channel(mapId).invokeMethod('camera#move', { - 'cameraUpdate': cameraUpdate.toJson(), - }); + return _hostApi(mapId) + .moveCamera(_platformCameraUpdateFromCameraUpdate(cameraUpdate)); } @override @@ -561,56 +478,56 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { /// Initialized [AndroidMapRenderer] type is returned. Future initializeWithRenderer( AndroidMapRenderer? rendererType) async { - String preferredRenderer; + PlatformRendererType? preferredRenderer; switch (rendererType) { case AndroidMapRenderer.latest: - preferredRenderer = 'latest'; + preferredRenderer = PlatformRendererType.latest; case AndroidMapRenderer.legacy: - preferredRenderer = 'legacy'; + preferredRenderer = PlatformRendererType.legacy; case AndroidMapRenderer.platformDefault: case null: - preferredRenderer = 'default'; + preferredRenderer = null; } - final String? initializedRenderer = await _initializerChannel - .invokeMethod('initializer#preferRenderer', - {'value': preferredRenderer}); + final MapsInitializerApi hostApi = MapsInitializerApi(); + final PlatformRendererType initializedRenderer = + await hostApi.initializeWithPreferredRenderer(preferredRenderer); - if (initializedRenderer == null) { - throw AndroidMapRendererException('Failed to initialize map renderer.'); - } - - // Returns mapped [AndroidMapRenderer] enum type. - switch (initializedRenderer) { - case 'latest': - return AndroidMapRenderer.latest; - case 'legacy': - return AndroidMapRenderer.legacy; - default: - throw AndroidMapRendererException( - 'Failed to initialize latest or legacy renderer, got $initializedRenderer.'); - } + return switch (initializedRenderer) { + PlatformRendererType.latest => AndroidMapRenderer.latest, + PlatformRendererType.legacy => AndroidMapRenderer.legacy, + }; } Widget _buildView( int creationId, PlatformViewCreatedCallback onPlatformViewCreated, { + required PlatformMapConfiguration mapConfiguration, required MapWidgetConfiguration widgetConfiguration, MapObjects mapObjects = const MapObjects(), - Map mapOptions = const {}, }) { - final Map creationParams = { - 'initialCameraPosition': - widgetConfiguration.initialCameraPosition.toMap(), - 'options': mapOptions, - 'markersToAdd': serializeMarkerSet(mapObjects.markers), - 'polygonsToAdd': serializePolygonSet(mapObjects.polygons), - 'polylinesToAdd': serializePolylineSet(mapObjects.polylines), - 'circlesToAdd': serializeCircleSet(mapObjects.circles), - 'tileOverlaysToAdd': serializeTileOverlaySet(mapObjects.tileOverlays), - 'clusterManagersToAdd': - serializeClusterManagerSet(mapObjects.clusterManagers), - }; + final PlatformMapViewCreationParams creationParams = + PlatformMapViewCreationParams( + initialCameraPosition: _platformCameraPositionFromCameraPosition( + widgetConfiguration.initialCameraPosition), + mapConfiguration: mapConfiguration, + initialMarkers: + mapObjects.markers.map(_platformMarkerFromMarker).toList(), + initialPolygons: + mapObjects.polygons.map(_platformPolygonFromPolygon).toList(), + initialPolylines: + mapObjects.polylines.map(_platformPolylineFromPolyline).toList(), + initialCircles: + mapObjects.circles.map(_platformCircleFromCircle).toList(), + initialHeatmaps: + mapObjects.heatmaps.map(_platformHeatmapFromHeatmap).toList(), + initialTileOverlays: mapObjects.tileOverlays + .map(_platformTileOverlayFromTileOverlay) + .toList(), + initialClusterManagers: mapObjects.clusterManagers + .map(_platformClusterManagerFromClusterManager) + .toList(), + ); const String viewType = 'plugins.flutter.dev/google_maps_android'; if (useAndroidViewSurface) { @@ -633,7 +550,7 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { viewType: viewType, layoutDirection: widgetConfiguration.textDirection, creationParams: creationParams, - creationParamsCodec: const StandardMessageCodec(), + creationParamsCodec: MapsApi.pigeonChannelCodec, onFocus: () => params.onFocusChanged(true), ); controller.addOnPlatformViewCreatedListener( @@ -654,7 +571,7 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { gestureRecognizers: widgetConfiguration.gestureRecognizers, layoutDirection: widgetConfiguration.textDirection, creationParams: creationParams, - creationParamsCodec: const StandardMessageCodec(), + creationParamsCodec: MapsApi.pigeonChannelCodec, ); } } @@ -672,7 +589,8 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { onPlatformViewCreated, widgetConfiguration: widgetConfiguration, mapObjects: mapObjects, - mapOptions: _jsonForMapConfiguration(mapConfiguration), + mapConfiguration: + _platformMapConfigurationFromMapConfiguration(mapConfiguration), ); } @@ -704,7 +622,7 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { circles: circles, clusterManagers: clusterManagers, tileOverlays: tileOverlays), - mapOptions: mapOptions, + mapConfiguration: _platformMapConfigurationFromOptionsJson(mapOptions), ); } @@ -746,38 +664,6 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { MapsInspectorApi(messageChannelSuffix: mapId.toString())); } - /// Parses cluster data from dynamic json objects and returns [Cluster] object. - /// Used by the `cluster#onTap` method call handler and the - /// [GoogleMapsInspectorAndroid.getClusters] response parser. - static Cluster parseCluster( - String clusterManagerIdString, - Object positionObject, - Map boundsMap, - List markerIdsList) { - final ClusterManagerId clusterManagerId = - ClusterManagerId(clusterManagerIdString); - final LatLng position = LatLng.fromJson(positionObject)!; - - final Map> latLngData = boundsMap.map( - (dynamic key, dynamic object) => MapEntry>( - key as String, object as List)); - - final LatLngBounds bounds = LatLngBounds( - northeast: LatLng.fromJson(latLngData['northeast'])!, - southwest: LatLng.fromJson(latLngData['southwest'])!); - - final List markerIds = markerIdsList - .map((dynamic markerId) => MarkerId(markerId as String)) - .toList(); - - return Cluster( - clusterManagerId, - markerIds, - position: position, - bounds: bounds, - ); - } - /// Converts a Pigeon [PlatformCluster] to the corresponding [Cluster]. static Cluster clusterFromPlatformCluster(PlatformCluster cluster) { return Cluster( @@ -790,15 +676,19 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { bounds: _latLngBoundsFromPlatformLatLngBounds(cluster.bounds)); } - static LatLng _latLngFromPlatformLatLng(PlatformLatLng latLng) { - return LatLng(latLng.latitude, latLng.longitude); - } - static PlatformLatLng _platformLatLngFromLatLng(LatLng latLng) { return PlatformLatLng( latitude: latLng.latitude, longitude: latLng.longitude); } + static PlatformDoublePair _platformPairFromOffset(Offset offset) { + return PlatformDoublePair(x: offset.dx, y: offset.dy); + } + + static PlatformDoublePair _platformPairFromSize(Size size) { + return PlatformDoublePair(x: size.width, y: size.height); + } + static ScreenCoordinate _screenCoordinateFromPlatformPoint( PlatformPoint point) { return ScreenCoordinate(x: point.x, y: point.y); @@ -809,60 +699,646 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { return PlatformPoint(x: coordinate.x, y: coordinate.y); } - static LatLngBounds _latLngBoundsFromPlatformLatLngBounds( - PlatformLatLngBounds bounds) { - return LatLngBounds( - southwest: _latLngFromPlatformLatLng(bounds.southwest), - northeast: _latLngFromPlatformLatLng(bounds.northeast)); + static PlatformCircle _platformCircleFromCircle(Circle circle) { + return PlatformCircle( + consumeTapEvents: circle.consumeTapEvents, + fillColor: circle.fillColor.value, + strokeColor: circle.strokeColor.value, + visible: circle.visible, + strokeWidth: circle.strokeWidth, + zIndex: circle.zIndex.toDouble(), + center: _platformLatLngFromLatLng(circle.center), + radius: circle.radius, + circleId: circle.circleId.value, + ); + } + + static PlatformHeatmap _platformHeatmapFromHeatmap(Heatmap heatmap) { + return PlatformHeatmap(json: serializeHeatmap(heatmap)); + } + + static PlatformClusterManager _platformClusterManagerFromClusterManager( + ClusterManager clusterManager) { + return PlatformClusterManager( + identifier: clusterManager.clusterManagerId.value); + } + + static PlatformInfoWindow _platformInfoWindowFromInfoWindow( + InfoWindow window) { + return PlatformInfoWindow( + title: window.title, + snippet: window.snippet, + anchor: _platformPairFromOffset(window.anchor)); + } + + static PlatformMarker _platformMarkerFromMarker(Marker marker) { + return PlatformMarker( + alpha: marker.alpha, + anchor: _platformPairFromOffset(marker.anchor), + consumeTapEvents: marker.consumeTapEvents, + draggable: marker.draggable, + flat: marker.flat, + icon: platformBitmapFromBitmapDescriptor(marker.icon), + infoWindow: _platformInfoWindowFromInfoWindow(marker.infoWindow), + position: _platformLatLngFromLatLng(marker.position), + rotation: marker.rotation, + visible: marker.visible, + zIndex: marker.zIndex, + markerId: marker.markerId.value, + clusterManagerId: marker.clusterManagerId?.value, + ); + } + + static PlatformPolygon _platformPolygonFromPolygon(Polygon polygon) { + final List points = + polygon.points.map(_platformLatLngFromLatLng).toList(); + final List> holes = + polygon.holes.map((List hole) { + return hole.map(_platformLatLngFromLatLng).toList(); + }).toList(); + return PlatformPolygon( + polygonId: polygon.polygonId.value, + fillColor: polygon.fillColor.value, + geodesic: polygon.geodesic, + consumesTapEvents: polygon.consumeTapEvents, + points: points, + holes: holes, + strokeColor: polygon.strokeColor.value, + strokeWidth: polygon.strokeWidth, + zIndex: polygon.zIndex, + visible: polygon.visible, + ); + } + + static PlatformPolyline _platformPolylineFromPolyline(Polyline polyline) { + final List points = + polyline.points.map(_platformLatLngFromLatLng).toList(); + final List pattern = + polyline.patterns.map(platformPatternItemFromPatternItem).toList(); + return PlatformPolyline( + polylineId: polyline.polylineId.value, + consumesTapEvents: polyline.consumeTapEvents, + color: polyline.color.value, + startCap: platformCapFromCap(polyline.startCap), + endCap: platformCapFromCap(polyline.endCap), + geodesic: polyline.geodesic, + visible: polyline.visible, + width: polyline.width, + zIndex: polyline.zIndex, + points: points, + jointType: platformJointTypeFromJointType(polyline.jointType), + patterns: pattern, + ); + } + + static PlatformTileOverlay _platformTileOverlayFromTileOverlay( + TileOverlay tileOverlay) { + return PlatformTileOverlay( + tileOverlayId: tileOverlay.tileOverlayId.value, + fadeIn: tileOverlay.fadeIn, + transparency: tileOverlay.transparency, + zIndex: tileOverlay.zIndex, + visible: tileOverlay.visible, + tileSize: tileOverlay.tileSize, + ); + } + + static PlatformCameraUpdate _platformCameraUpdateFromCameraUpdate( + CameraUpdate update) { + switch (update.updateType) { + case CameraUpdateType.newCameraPosition: + update as CameraUpdateNewCameraPosition; + return PlatformCameraUpdate( + cameraUpdate: PlatformCameraUpdateNewCameraPosition( + cameraPosition: _platformCameraPositionFromCameraPosition( + update.cameraPosition))); + case CameraUpdateType.newLatLng: + update as CameraUpdateNewLatLng; + return PlatformCameraUpdate( + cameraUpdate: PlatformCameraUpdateNewLatLng( + latLng: _platformLatLngFromLatLng(update.latLng))); + case CameraUpdateType.newLatLngZoom: + update as CameraUpdateNewLatLngZoom; + return PlatformCameraUpdate( + cameraUpdate: PlatformCameraUpdateNewLatLngZoom( + latLng: _platformLatLngFromLatLng(update.latLng), + zoom: update.zoom)); + case CameraUpdateType.newLatLngBounds: + update as CameraUpdateNewLatLngBounds; + return PlatformCameraUpdate( + cameraUpdate: PlatformCameraUpdateNewLatLngBounds( + bounds: _platformLatLngBoundsFromLatLngBounds(update.bounds)!, + padding: update.padding)); + case CameraUpdateType.zoomTo: + update as CameraUpdateZoomTo; + return PlatformCameraUpdate( + cameraUpdate: PlatformCameraUpdateZoomTo(zoom: update.zoom)); + case CameraUpdateType.zoomBy: + update as CameraUpdateZoomBy; + return PlatformCameraUpdate( + cameraUpdate: PlatformCameraUpdateZoomBy( + amount: update.amount, + focus: update.focus == null + ? null + : _platformPairFromOffset(update.focus!))); + case CameraUpdateType.zoomIn: + update as CameraUpdateZoomIn; + return PlatformCameraUpdate( + cameraUpdate: PlatformCameraUpdateZoom(out: false)); + case CameraUpdateType.zoomOut: + update as CameraUpdateZoomOut; + return PlatformCameraUpdate( + cameraUpdate: PlatformCameraUpdateZoom(out: true)); + case CameraUpdateType.scrollBy: + update as CameraUpdateScrollBy; + return PlatformCameraUpdate( + cameraUpdate: + PlatformCameraUpdateScrollBy(dx: update.dx, dy: update.dy)); + } + } + + /// Convert [MapBitmapScaling] from platform interface to [PlatformMapBitmapScaling] Pigeon. + @visibleForTesting + static PlatformMapBitmapScaling platformMapBitmapScalingFromScaling( + MapBitmapScaling scaling) { + switch (scaling) { + case MapBitmapScaling.auto: + return PlatformMapBitmapScaling.auto; + case MapBitmapScaling.none: + return PlatformMapBitmapScaling.none; + } + + // The enum comes from a different package, which could get a new value at + // any time, so provide a fallback that ensures this won't break when used + // with a version that contains new values. This is deliberately outside + // the switch rather than a `default` so that the linter will flag the + // switch as needing an update. + // ignore: dead_code + return PlatformMapBitmapScaling.auto; + } + + /// Convert [BitmapDescriptor] from platform interface to [PlatformBitmap] pigeon. + @visibleForTesting + static PlatformBitmap platformBitmapFromBitmapDescriptor( + BitmapDescriptor bitmap) { + switch (bitmap) { + case final DefaultMarker marker: + return PlatformBitmap( + bitmap: PlatformBitmapDefaultMarker(hue: marker.hue?.toDouble())); + case final BytesBitmap bytes: + return PlatformBitmap( + bitmap: PlatformBitmapBytes( + byteData: bytes.byteData, + size: (bytes.size == null) + ? null + : _platformPairFromSize(bytes.size!))); + case final AssetBitmap asset: + return PlatformBitmap( + bitmap: PlatformBitmapAsset(name: asset.name, pkg: asset.package)); + case final AssetImageBitmap asset: + return PlatformBitmap( + bitmap: PlatformBitmapAssetImage( + name: asset.name, + scale: asset.scale, + size: (asset.size == null) + ? null + : _platformPairFromSize(asset.size!))); + case final AssetMapBitmap asset: + return PlatformBitmap( + bitmap: PlatformBitmapAssetMap( + assetName: asset.assetName, + bitmapScaling: + platformMapBitmapScalingFromScaling(asset.bitmapScaling), + imagePixelRatio: asset.imagePixelRatio, + width: asset.width, + height: asset.height)); + case final BytesMapBitmap bytes: + return PlatformBitmap( + bitmap: PlatformBitmapBytesMap( + byteData: bytes.byteData, + bitmapScaling: + platformMapBitmapScalingFromScaling(bytes.bitmapScaling), + imagePixelRatio: bytes.imagePixelRatio, + width: bytes.width, + height: bytes.height)); + default: + throw ArgumentError( + 'Unrecognized type of bitmap ${bitmap.runtimeType}', 'bitmap'); + } + } + + /// Convert [Cap] from platform interface to [PlatformCap] pigeon. + @visibleForTesting + static PlatformCap platformCapFromCap(Cap cap) { + switch (cap.type) { + case CapType.butt: + return PlatformCap(type: PlatformCapType.buttCap); + case CapType.square: + return PlatformCap(type: PlatformCapType.squareCap); + case CapType.round: + return PlatformCap(type: PlatformCapType.roundCap); + case CapType.custom: + cap as CustomCap; + return PlatformCap( + type: PlatformCapType.customCap, + bitmapDescriptor: + platformBitmapFromBitmapDescriptor(cap.bitmapDescriptor), + refWidth: cap.refWidth); + } + } +} + +/// Callback handler for map events from the platform host. +@visibleForTesting +class HostMapMessageHandler implements MapsCallbackApi { + /// Creates a new handler that listens for events from map [mapId], and + /// broadcasts them to [streamController]. + HostMapMessageHandler( + this.mapId, + this.streamController, { + required this.tileOverlayProvider, + }) { + MapsCallbackApi.setUp(this, messageChannelSuffix: mapId.toString()); + } + + /// Removes the handler for native messages. + void dispose() { + MapsCallbackApi.setUp(null, messageChannelSuffix: mapId.toString()); + } + + /// The map ID this handler listens for events from. + final int mapId; + + /// The controller used to broadcast map events coming from the + /// host platform. + final StreamController> streamController; + + /// The callback to get a tile overlay for the corresponding map. + final TileOverlay? Function(TileOverlayId tileOverlayId) tileOverlayProvider; + + @override + Future getTileOverlayTile( + String tileOverlayId, + PlatformPoint location, + int zoom, + ) async { + final TileOverlay? tileOverlay = + tileOverlayProvider(TileOverlayId(tileOverlayId)); + final TileProvider? tileProvider = tileOverlay?.tileProvider; + final Tile tile = tileProvider == null + ? TileProvider.noTile + : await tileProvider.getTile(location.x, location.y, zoom); + return _platformTileFromTile(tile); + } + + @override + void onCameraIdle() { + streamController.add(CameraIdleEvent(mapId)); + } + + @override + void onCameraMove(PlatformCameraPosition cameraPosition) { + streamController.add(CameraMoveEvent( + mapId, + CameraPosition( + target: _latLngFromPlatformLatLng(cameraPosition.target), + bearing: cameraPosition.bearing, + tilt: cameraPosition.tilt, + zoom: cameraPosition.zoom, + ), + )); + } + + @override + void onCameraMoveStarted() { + streamController.add(CameraMoveStartedEvent(mapId)); + } + + @override + void onCircleTap(String circleId) { + streamController.add(CircleTapEvent(mapId, CircleId(circleId))); + } + + @override + void onClusterTap(PlatformCluster cluster) { + streamController.add(ClusterTapEvent( + mapId, + Cluster( + ClusterManagerId(cluster.clusterManagerId), + // See comment in messages.dart for why this is force-unwrapped. + cluster.markerIds.map((String? id) => MarkerId(id!)).toList(), + position: _latLngFromPlatformLatLng(cluster.position), + bounds: _latLngBoundsFromPlatformLatLngBounds(cluster.bounds), + ), + )); + } + + @override + void onInfoWindowTap(String markerId) { + streamController.add(InfoWindowTapEvent(mapId, MarkerId(markerId))); + } + + @override + void onLongPress(PlatformLatLng position) { + streamController + .add(MapLongPressEvent(mapId, _latLngFromPlatformLatLng(position))); + } + + @override + void onMarkerDrag(String markerId, PlatformLatLng position) { + streamController.add(MarkerDragEvent( + mapId, _latLngFromPlatformLatLng(position), MarkerId(markerId))); + } + + @override + void onMarkerDragStart(String markerId, PlatformLatLng position) { + streamController.add(MarkerDragStartEvent( + mapId, _latLngFromPlatformLatLng(position), MarkerId(markerId))); + } + + @override + void onMarkerDragEnd(String markerId, PlatformLatLng position) { + streamController.add(MarkerDragEndEvent( + mapId, _latLngFromPlatformLatLng(position), MarkerId(markerId))); + } + + @override + void onMarkerTap(String markerId) { + streamController.add(MarkerTapEvent(mapId, MarkerId(markerId))); + } + + @override + void onPolygonTap(String polygonId) { + streamController.add(PolygonTapEvent(mapId, PolygonId(polygonId))); + } + + @override + void onPolylineTap(String polylineId) { + streamController.add(PolylineTapEvent(mapId, PolylineId(polylineId))); + } + + @override + void onTap(PlatformLatLng position) { + streamController + .add(MapTapEvent(mapId, _latLngFromPlatformLatLng(position))); + } +} + +LatLng _latLngFromPlatformLatLng(PlatformLatLng latLng) { + return LatLng(latLng.latitude, latLng.longitude); +} + +LatLngBounds _latLngBoundsFromPlatformLatLngBounds( + PlatformLatLngBounds bounds) { + return LatLngBounds( + southwest: _latLngFromPlatformLatLng(bounds.southwest), + northeast: _latLngFromPlatformLatLng(bounds.northeast)); +} + +PlatformTile _platformTileFromTile(Tile tile) { + return PlatformTile(width: tile.width, height: tile.height, data: tile.data); +} + +PlatformLatLng _platformLatLngFromLatLng(LatLng latLng) { + return PlatformLatLng(latitude: latLng.latitude, longitude: latLng.longitude); +} + +PlatformLatLngBounds? _platformLatLngBoundsFromLatLngBounds( + LatLngBounds? bounds) { + if (bounds == null) { + return null; } + return PlatformLatLngBounds( + northeast: _platformLatLngFromLatLng(bounds.northeast), + southwest: _platformLatLngFromLatLng(bounds.southwest)); +} + +PlatformCameraTargetBounds? _platformCameraTargetBoundsFromCameraTargetBounds( + CameraTargetBounds? bounds) { + return bounds == null + ? null + : PlatformCameraTargetBounds( + bounds: _platformLatLngBoundsFromLatLngBounds(bounds.bounds)); +} + +PlatformMapType? _platformMapTypeFromMapType(MapType? type) { + switch (type) { + case null: + return null; + case MapType.none: + return PlatformMapType.none; + case MapType.normal: + return PlatformMapType.normal; + case MapType.satellite: + return PlatformMapType.satellite; + case MapType.terrain: + return PlatformMapType.terrain; + case MapType.hybrid: + return PlatformMapType.hybrid; + } + // The enum comes from a different package, which could get a new value at + // any time, so provide a fallback that ensures this won't break when used + // with a version that contains new values. This is deliberately outside + // the switch rather than a `default` so that the linter will flag the + // switch as needing an update. + // ignore: dead_code + return PlatformMapType.normal; +} + +PlatformZoomRange? _platformZoomRangeFromMinMaxZoomPreference( + MinMaxZoomPreference? zoomPref) { + return zoomPref == null + ? null + : PlatformZoomRange(min: zoomPref.minZoom, max: zoomPref.maxZoom); +} + +PlatformEdgeInsets? _platformEdgeInsetsFromEdgeInsets(EdgeInsets? insets) { + return insets == null + ? null + : PlatformEdgeInsets( + top: insets.top, + bottom: insets.bottom, + left: insets.left, + right: insets.right); +} + +PlatformMapConfiguration _platformMapConfigurationFromMapConfiguration( + MapConfiguration config) { + return PlatformMapConfiguration( + compassEnabled: config.compassEnabled, + cameraTargetBounds: _platformCameraTargetBoundsFromCameraTargetBounds( + config.cameraTargetBounds), + mapType: _platformMapTypeFromMapType(config.mapType), + minMaxZoomPreference: + _platformZoomRangeFromMinMaxZoomPreference(config.minMaxZoomPreference), + mapToolbarEnabled: config.mapToolbarEnabled, + rotateGesturesEnabled: config.rotateGesturesEnabled, + scrollGesturesEnabled: config.scrollGesturesEnabled, + tiltGesturesEnabled: config.tiltGesturesEnabled, + trackCameraPosition: config.trackCameraPosition, + zoomControlsEnabled: config.zoomControlsEnabled, + zoomGesturesEnabled: config.zoomGesturesEnabled, + myLocationEnabled: config.myLocationEnabled, + myLocationButtonEnabled: config.myLocationButtonEnabled, + padding: _platformEdgeInsetsFromEdgeInsets(config.padding), + indoorViewEnabled: config.indoorViewEnabled, + trafficEnabled: config.trafficEnabled, + buildingsEnabled: config.buildingsEnabled, + liteModeEnabled: config.liteModeEnabled, + cloudMapId: config.cloudMapId, + style: config.style, + ); } -Map _jsonForMapConfiguration(MapConfiguration config) { - final EdgeInsets? padding = config.padding; - return { - if (config.compassEnabled != null) 'compassEnabled': config.compassEnabled!, - if (config.mapToolbarEnabled != null) - 'mapToolbarEnabled': config.mapToolbarEnabled!, - if (config.cameraTargetBounds != null) - 'cameraTargetBounds': config.cameraTargetBounds!.toJson(), - if (config.mapType != null) 'mapType': config.mapType!.index, - if (config.minMaxZoomPreference != null) - 'minMaxZoomPreference': config.minMaxZoomPreference!.toJson(), - if (config.rotateGesturesEnabled != null) - 'rotateGesturesEnabled': config.rotateGesturesEnabled!, - if (config.scrollGesturesEnabled != null) - 'scrollGesturesEnabled': config.scrollGesturesEnabled!, - if (config.tiltGesturesEnabled != null) - 'tiltGesturesEnabled': config.tiltGesturesEnabled!, - if (config.zoomControlsEnabled != null) - 'zoomControlsEnabled': config.zoomControlsEnabled!, - if (config.zoomGesturesEnabled != null) - 'zoomGesturesEnabled': config.zoomGesturesEnabled!, - if (config.liteModeEnabled != null) - 'liteModeEnabled': config.liteModeEnabled!, - if (config.trackCameraPosition != null) - 'trackCameraPosition': config.trackCameraPosition!, - if (config.myLocationEnabled != null) - 'myLocationEnabled': config.myLocationEnabled!, - if (config.myLocationButtonEnabled != null) - 'myLocationButtonEnabled': config.myLocationButtonEnabled!, - if (padding != null) - 'padding': [ - padding.top, - padding.left, - padding.bottom, - padding.right, - ], - if (config.indoorViewEnabled != null) - 'indoorEnabled': config.indoorViewEnabled!, - if (config.trafficEnabled != null) 'trafficEnabled': config.trafficEnabled!, - if (config.buildingsEnabled != null) - 'buildingsEnabled': config.buildingsEnabled!, - if (config.cloudMapId != null) 'cloudMapId': config.cloudMapId!, - if (config.style != null) 'style': config.style!, +// For supporting the deprecated updateMapOptions API. +PlatformMapConfiguration _platformMapConfigurationFromOptionsJson( + Map options) { + // All of these hard-coded values and structures come from + // google_maps_flutter_platform_interface/lib/src/types/utils/map_configuration_serialization.dart + // to support this legacy API that relied on cross-package magic strings. + final List? padding = + (options['padding'] as List?)?.cast(); + final int? mapType = options['mapType'] as int?; + return PlatformMapConfiguration( + compassEnabled: options['compassEnabled'] as bool?, + cameraTargetBounds: _platformCameraTargetBoundsFromCameraTargetBoundsJson( + options['cameraTargetBounds']), + mapType: mapType == null ? null : _platformMapTypeFromMapTypeIndex(mapType), + minMaxZoomPreference: _platformZoomRangeFromMinMaxZoomPreferenceJson( + options['minMaxZoomPreference']), + mapToolbarEnabled: options['mapToolbarEnabled'] as bool?, + rotateGesturesEnabled: options['rotateGesturesEnabled'] as bool?, + scrollGesturesEnabled: options['scrollGesturesEnabled'] as bool?, + tiltGesturesEnabled: options['tiltGesturesEnabled'] as bool?, + trackCameraPosition: options['trackCameraPosition'] as bool?, + zoomControlsEnabled: options['zoomControlsEnabled'] as bool?, + zoomGesturesEnabled: options['zoomGesturesEnabled'] as bool?, + myLocationEnabled: options['myLocationEnabled'] as bool?, + myLocationButtonEnabled: options['myLocationButtonEnabled'] as bool?, + padding: padding == null + ? null + : PlatformEdgeInsets( + top: padding[0], + left: padding[1], + bottom: padding[2], + right: padding[3]), + indoorViewEnabled: options['indoorEnabled'] as bool?, + trafficEnabled: options['trafficEnabled'] as bool?, + buildingsEnabled: options['buildingsEnabled'] as bool?, + liteModeEnabled: options['liteModeEnabled'] as bool?, + cloudMapId: options['cloudMapId'] as String?, + style: options['style'] as String?, + ); +} + +PlatformCameraPosition _platformCameraPositionFromCameraPosition( + CameraPosition position) { + return PlatformCameraPosition( + bearing: position.bearing, + target: _platformLatLngFromLatLng(position.target), + tilt: position.tilt, + zoom: position.zoom); +} + +PlatformMapType _platformMapTypeFromMapTypeIndex(int index) { + // This is inherently fragile, but see comment in updateMapOptions. + return switch (index) { + 0 => PlatformMapType.none, + 1 => PlatformMapType.normal, + 2 => PlatformMapType.satellite, + 3 => PlatformMapType.terrain, + 4 => PlatformMapType.hybrid, + // For a new, unsupported type, just use normal. + _ => PlatformMapType.normal, }; } +PlatformLatLng _platformLatLngFromLatLngJson(Object latLngJson) { + // See `LatLng.toJson`. + final List list = (latLngJson as List).cast(); + return PlatformLatLng(latitude: list[0], longitude: list[1]); +} + +PlatformLatLngBounds? _platformLatLngBoundsFromLatLngBoundsJson( + Object? boundsJson) { + if (boundsJson == null) { + return null; + } + // See `LatLngBounds.toJson`. + final List boundsList = (boundsJson as List).cast(); + return PlatformLatLngBounds( + southwest: _platformLatLngFromLatLngJson(boundsList[0]), + northeast: _platformLatLngFromLatLngJson(boundsList[1])); +} + +PlatformCameraTargetBounds? + _platformCameraTargetBoundsFromCameraTargetBoundsJson(Object? targetJson) { + if (targetJson == null) { + return null; + } + // See `CameraTargetBounds.toJson`. + return PlatformCameraTargetBounds( + bounds: _platformLatLngBoundsFromLatLngBoundsJson( + (targetJson as List)[0])); +} + +PlatformZoomRange? _platformZoomRangeFromMinMaxZoomPreferenceJson( + Object? zoomPrefsJson) { + if (zoomPrefsJson == null) { + return null; + } + // See `MinMaxZoomPreference.toJson`. + final List minMaxZoom = + (zoomPrefsJson as List).cast(); + return PlatformZoomRange(min: minMaxZoom[0], max: minMaxZoom[1]); +} + +/// Converts platform interface's JointType to Pigeon's PlatformJointType. +@visibleForTesting +PlatformJointType platformJointTypeFromJointType(JointType jointType) { + switch (jointType) { + case JointType.mitered: + return PlatformJointType.mitered; + case JointType.bevel: + return PlatformJointType.bevel; + case JointType.round: + return PlatformJointType.round; + } + // The enum comes from a different package, which could get a new value at + // any time, so provide a fallback that ensures this won't break when used + // with a version that contains new values. This is deliberately outside + // the switch rather than a `default` so that the linter will flag the + // switch as needing an update. + // ignore: dead_code + return PlatformJointType.mitered; +} + +/// Converts a PatternItem to Pigeon's PlatformPatternItem for PlatformPolyline +/// pattern member. +@visibleForTesting +PlatformPatternItem platformPatternItemFromPatternItem(PatternItem item) { + switch (item.type) { + case PatternItemType.dot: + return PlatformPatternItem(type: PlatformPatternItemType.dot); + case PatternItemType.dash: + final double length = (item as VariableLengthPatternItem).length; + return PlatformPatternItem( + type: PlatformPatternItemType.dash, length: length); + case PatternItemType.gap: + final double length = (item as VariableLengthPatternItem).length; + return PlatformPatternItem( + type: PlatformPatternItemType.gap, length: length); + } + + // The enum comes from a different package, which could get a new value at + // any time, so provide a fallback that ensures this won't break when used + // with a version that contains new values. This is deliberately outside + // the switch rather than a `default` so that the linter will flag the + // switch as needing an update. + // ignore: dead_code + return PlatformPatternItem(type: PlatformPatternItemType.dot); +} + /// Update specification for a set of [TileOverlay]s. // TODO(stuartmorgan): Fix the missing export of this class in the platform // interface, and remove this copy. diff --git a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/messages.g.dart b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/messages.g.dart index fa7445f748fe..d5cc589f22e1 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/messages.g.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/messages.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 (v20.0.1), do not edit directly. +// Autogenerated from Pigeon (v22.6.0), 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 @@ -18,6 +18,896 @@ PlatformException _createConnectionError(String channelName) { ); } +List wrapResponse( + {Object? result, PlatformException? error, bool empty = false}) { + if (empty) { + return []; + } + if (error == null) { + return [result]; + } + return [error.code, error.message, error.details]; +} + +/// Pigeon equivalent of MapType +enum PlatformMapType { + none, + normal, + satellite, + terrain, + hybrid, +} + +enum PlatformRendererType { + legacy, + latest, +} + +/// Join types for polyline joints. +enum PlatformJointType { + mitered, + bevel, + round, +} + +/// Enumeration of possible types of PlatformCap, corresponding to the +/// subclasses of Cap in the Google Maps Android SDK. +/// See https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/Cap. +enum PlatformCapType { + buttCap, + roundCap, + squareCap, + customCap, +} + +/// Enumeration of possible types for PatternItem. +enum PlatformPatternItemType { + dot, + dash, + gap, +} + +/// Pigeon equivalent of [MapBitmapScaling]. +enum PlatformMapBitmapScaling { + auto, + none, +} + +/// Pigeon representatation of a CameraPosition. +class PlatformCameraPosition { + PlatformCameraPosition({ + required this.bearing, + required this.target, + required this.tilt, + required this.zoom, + }); + + double bearing; + + PlatformLatLng target; + + double tilt; + + double zoom; + + Object encode() { + return [ + bearing, + target, + tilt, + zoom, + ]; + } + + static PlatformCameraPosition decode(Object result) { + result as List; + return PlatformCameraPosition( + bearing: result[0]! as double, + target: result[1]! as PlatformLatLng, + tilt: result[2]! as double, + zoom: result[3]! as double, + ); + } +} + +/// Pigeon representation of a CameraUpdate. +class PlatformCameraUpdate { + PlatformCameraUpdate({ + required this.cameraUpdate, + }); + + /// This Object shall be any of the below classes prefixed with + /// PlatformCameraUpdate. Each such class represents a different type of + /// camera update, and each holds a different set of data, preventing the + /// use of a single unified class. Pigeon does not support inheritance, which + /// prevents a more strict type bound. + /// See https://github.com/flutter/flutter/issues/117819. + Object cameraUpdate; + + Object encode() { + return [ + cameraUpdate, + ]; + } + + static PlatformCameraUpdate decode(Object result) { + result as List; + return PlatformCameraUpdate( + cameraUpdate: result[0]!, + ); + } +} + +/// Pigeon equivalent of NewCameraPosition +class PlatformCameraUpdateNewCameraPosition { + PlatformCameraUpdateNewCameraPosition({ + required this.cameraPosition, + }); + + PlatformCameraPosition cameraPosition; + + Object encode() { + return [ + cameraPosition, + ]; + } + + static PlatformCameraUpdateNewCameraPosition decode(Object result) { + result as List; + return PlatformCameraUpdateNewCameraPosition( + cameraPosition: result[0]! as PlatformCameraPosition, + ); + } +} + +/// Pigeon equivalent of NewLatLng +class PlatformCameraUpdateNewLatLng { + PlatformCameraUpdateNewLatLng({ + required this.latLng, + }); + + PlatformLatLng latLng; + + Object encode() { + return [ + latLng, + ]; + } + + static PlatformCameraUpdateNewLatLng decode(Object result) { + result as List; + return PlatformCameraUpdateNewLatLng( + latLng: result[0]! as PlatformLatLng, + ); + } +} + +/// Pigeon equivalent of NewLatLngBounds +class PlatformCameraUpdateNewLatLngBounds { + PlatformCameraUpdateNewLatLngBounds({ + required this.bounds, + required this.padding, + }); + + PlatformLatLngBounds bounds; + + double padding; + + Object encode() { + return [ + bounds, + padding, + ]; + } + + static PlatformCameraUpdateNewLatLngBounds decode(Object result) { + result as List; + return PlatformCameraUpdateNewLatLngBounds( + bounds: result[0]! as PlatformLatLngBounds, + padding: result[1]! as double, + ); + } +} + +/// Pigeon equivalent of NewLatLngZoom +class PlatformCameraUpdateNewLatLngZoom { + PlatformCameraUpdateNewLatLngZoom({ + required this.latLng, + required this.zoom, + }); + + PlatformLatLng latLng; + + double zoom; + + Object encode() { + return [ + latLng, + zoom, + ]; + } + + static PlatformCameraUpdateNewLatLngZoom decode(Object result) { + result as List; + return PlatformCameraUpdateNewLatLngZoom( + latLng: result[0]! as PlatformLatLng, + zoom: result[1]! as double, + ); + } +} + +/// Pigeon equivalent of ScrollBy +class PlatformCameraUpdateScrollBy { + PlatformCameraUpdateScrollBy({ + required this.dx, + required this.dy, + }); + + double dx; + + double dy; + + Object encode() { + return [ + dx, + dy, + ]; + } + + static PlatformCameraUpdateScrollBy decode(Object result) { + result as List; + return PlatformCameraUpdateScrollBy( + dx: result[0]! as double, + dy: result[1]! as double, + ); + } +} + +/// Pigeon equivalent of ZoomBy +class PlatformCameraUpdateZoomBy { + PlatformCameraUpdateZoomBy({ + required this.amount, + this.focus, + }); + + double amount; + + PlatformDoublePair? focus; + + Object encode() { + return [ + amount, + focus, + ]; + } + + static PlatformCameraUpdateZoomBy decode(Object result) { + result as List; + return PlatformCameraUpdateZoomBy( + amount: result[0]! as double, + focus: result[1] as PlatformDoublePair?, + ); + } +} + +/// Pigeon equivalent of ZoomIn/ZoomOut +class PlatformCameraUpdateZoom { + PlatformCameraUpdateZoom({ + required this.out, + }); + + bool out; + + Object encode() { + return [ + out, + ]; + } + + static PlatformCameraUpdateZoom decode(Object result) { + result as List; + return PlatformCameraUpdateZoom( + out: result[0]! as bool, + ); + } +} + +/// Pigeon equivalent of ZoomTo +class PlatformCameraUpdateZoomTo { + PlatformCameraUpdateZoomTo({ + required this.zoom, + }); + + double zoom; + + Object encode() { + return [ + zoom, + ]; + } + + static PlatformCameraUpdateZoomTo decode(Object result) { + result as List; + return PlatformCameraUpdateZoomTo( + zoom: result[0]! as double, + ); + } +} + +/// Pigeon equivalent of the Circle class. +class PlatformCircle { + PlatformCircle({ + this.consumeTapEvents = false, + this.fillColor = 0x00000000, + this.strokeColor = 0xFF000000, + this.visible = true, + this.strokeWidth = 10, + this.zIndex = 0.0, + required this.center, + this.radius = 0, + required this.circleId, + }); + + bool consumeTapEvents; + + int fillColor; + + int strokeColor; + + bool visible; + + int strokeWidth; + + double zIndex; + + PlatformLatLng center; + + double radius; + + String circleId; + + Object encode() { + return [ + consumeTapEvents, + fillColor, + strokeColor, + visible, + strokeWidth, + zIndex, + center, + radius, + circleId, + ]; + } + + static PlatformCircle decode(Object result) { + result as List; + return PlatformCircle( + consumeTapEvents: result[0]! as bool, + fillColor: result[1]! as int, + strokeColor: result[2]! as int, + visible: result[3]! as bool, + strokeWidth: result[4]! as int, + zIndex: result[5]! as double, + center: result[6]! as PlatformLatLng, + radius: result[7]! as double, + circleId: result[8]! as String, + ); + } +} + +/// Pigeon equivalent of the Heatmap class. +class PlatformHeatmap { + PlatformHeatmap({ + required this.json, + }); + + /// The heatmap data, as JSON. This should only be set from + /// Heatmap.toJson, and the native code must interpret it according to the + /// internal implementation details of that method. + Map json; + + Object encode() { + return [ + json, + ]; + } + + static PlatformHeatmap decode(Object result) { + result as List; + return PlatformHeatmap( + json: (result[0] as Map?)!.cast(), + ); + } +} + +/// Pigeon equivalent of the ClusterManager class. +class PlatformClusterManager { + PlatformClusterManager({ + required this.identifier, + }); + + String identifier; + + Object encode() { + return [ + identifier, + ]; + } + + static PlatformClusterManager decode(Object result) { + result as List; + return PlatformClusterManager( + identifier: result[0]! as String, + ); + } +} + +/// Pair of double values, such as for an offset or size. +class PlatformDoublePair { + PlatformDoublePair({ + required this.x, + required this.y, + }); + + double x; + + double y; + + Object encode() { + return [ + x, + y, + ]; + } + + static PlatformDoublePair decode(Object result) { + result as List; + return PlatformDoublePair( + x: result[0]! as double, + y: result[1]! as double, + ); + } +} + +/// Pigeon equivalent of the InfoWindow class. +class PlatformInfoWindow { + PlatformInfoWindow({ + this.title, + this.snippet, + required this.anchor, + }); + + String? title; + + String? snippet; + + PlatformDoublePair anchor; + + Object encode() { + return [ + title, + snippet, + anchor, + ]; + } + + static PlatformInfoWindow decode(Object result) { + result as List; + return PlatformInfoWindow( + title: result[0] as String?, + snippet: result[1] as String?, + anchor: result[2]! as PlatformDoublePair, + ); + } +} + +/// Pigeon equivalent of the Marker class. +class PlatformMarker { + PlatformMarker({ + this.alpha = 1.0, + required this.anchor, + this.consumeTapEvents = false, + this.draggable = false, + this.flat = false, + required this.icon, + required this.infoWindow, + required this.position, + this.rotation = 0.0, + this.visible = true, + this.zIndex = 0.0, + required this.markerId, + this.clusterManagerId, + }); + + double alpha; + + PlatformDoublePair anchor; + + bool consumeTapEvents; + + bool draggable; + + bool flat; + + PlatformBitmap icon; + + PlatformInfoWindow infoWindow; + + PlatformLatLng position; + + double rotation; + + bool visible; + + double zIndex; + + String markerId; + + String? clusterManagerId; + + Object encode() { + return [ + alpha, + anchor, + consumeTapEvents, + draggable, + flat, + icon, + infoWindow, + position, + rotation, + visible, + zIndex, + markerId, + clusterManagerId, + ]; + } + + static PlatformMarker decode(Object result) { + result as List; + return PlatformMarker( + alpha: result[0]! as double, + anchor: result[1]! as PlatformDoublePair, + consumeTapEvents: result[2]! as bool, + draggable: result[3]! as bool, + flat: result[4]! as bool, + icon: result[5]! as PlatformBitmap, + infoWindow: result[6]! as PlatformInfoWindow, + position: result[7]! as PlatformLatLng, + rotation: result[8]! as double, + visible: result[9]! as bool, + zIndex: result[10]! as double, + markerId: result[11]! as String, + clusterManagerId: result[12] as String?, + ); + } +} + +/// Pigeon equivalent of the Polygon class. +class PlatformPolygon { + PlatformPolygon({ + required this.polygonId, + required this.consumesTapEvents, + required this.fillColor, + required this.geodesic, + required this.points, + required this.holes, + required this.visible, + required this.strokeColor, + required this.strokeWidth, + required this.zIndex, + }); + + String polygonId; + + bool consumesTapEvents; + + int fillColor; + + bool geodesic; + + List points; + + List> holes; + + bool visible; + + int strokeColor; + + int strokeWidth; + + int zIndex; + + Object encode() { + return [ + polygonId, + consumesTapEvents, + fillColor, + geodesic, + points, + holes, + visible, + strokeColor, + strokeWidth, + zIndex, + ]; + } + + static PlatformPolygon decode(Object result) { + result as List; + return PlatformPolygon( + polygonId: result[0]! as String, + consumesTapEvents: result[1]! as bool, + fillColor: result[2]! as int, + geodesic: result[3]! as bool, + points: (result[4] as List?)!.cast(), + holes: (result[5] as List?)!.cast>(), + visible: result[6]! as bool, + strokeColor: result[7]! as int, + strokeWidth: result[8]! as int, + zIndex: result[9]! as int, + ); + } +} + +/// Pigeon equivalent of the Polyline class. +class PlatformPolyline { + PlatformPolyline({ + required this.polylineId, + required this.consumesTapEvents, + required this.color, + required this.geodesic, + required this.jointType, + required this.patterns, + required this.points, + required this.startCap, + required this.endCap, + required this.visible, + required this.width, + required this.zIndex, + }); + + String polylineId; + + bool consumesTapEvents; + + int color; + + bool geodesic; + + /// The joint type. + PlatformJointType jointType; + + /// The pattern data, as a list of pattern items. + List patterns; + + List points; + + /// The cap at the start and end vertex of a polyline. + /// See https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/Cap. + PlatformCap startCap; + + PlatformCap endCap; + + bool visible; + + int width; + + int zIndex; + + Object encode() { + return [ + polylineId, + consumesTapEvents, + color, + geodesic, + jointType, + patterns, + points, + startCap, + endCap, + visible, + width, + zIndex, + ]; + } + + static PlatformPolyline decode(Object result) { + result as List; + return PlatformPolyline( + polylineId: result[0]! as String, + consumesTapEvents: result[1]! as bool, + color: result[2]! as int, + geodesic: result[3]! as bool, + jointType: result[4]! as PlatformJointType, + patterns: (result[5] as List?)!.cast(), + points: (result[6] as List?)!.cast(), + startCap: result[7]! as PlatformCap, + endCap: result[8]! as PlatformCap, + visible: result[9]! as bool, + width: result[10]! as int, + zIndex: result[11]! as int, + ); + } +} + +/// Pigeon equivalent of Cap from the platform interface. +/// https://github.com/flutter/packages/blob/main/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/cap.dart +class PlatformCap { + PlatformCap({ + required this.type, + this.bitmapDescriptor, + this.refWidth, + }); + + PlatformCapType type; + + PlatformBitmap? bitmapDescriptor; + + double? refWidth; + + Object encode() { + return [ + type, + bitmapDescriptor, + refWidth, + ]; + } + + static PlatformCap decode(Object result) { + result as List; + return PlatformCap( + type: result[0]! as PlatformCapType, + bitmapDescriptor: result[1] as PlatformBitmap?, + refWidth: result[2] as double?, + ); + } +} + +/// Pigeon equivalent of the PatternItem class. +class PlatformPatternItem { + PlatformPatternItem({ + required this.type, + this.length, + }); + + PlatformPatternItemType type; + + double? length; + + Object encode() { + return [ + type, + length, + ]; + } + + static PlatformPatternItem decode(Object result) { + result as List; + return PlatformPatternItem( + type: result[0]! as PlatformPatternItemType, + length: result[1] as double?, + ); + } +} + +/// Pigeon equivalent of the Tile class. +class PlatformTile { + PlatformTile({ + required this.width, + required this.height, + this.data, + }); + + int width; + + int height; + + Uint8List? data; + + Object encode() { + return [ + width, + height, + data, + ]; + } + + static PlatformTile decode(Object result) { + result as List; + return PlatformTile( + width: result[0]! as int, + height: result[1]! as int, + data: result[2] as Uint8List?, + ); + } +} + +/// Pigeon equivalent of the TileOverlay class. +class PlatformTileOverlay { + PlatformTileOverlay({ + required this.tileOverlayId, + required this.fadeIn, + required this.transparency, + required this.zIndex, + required this.visible, + required this.tileSize, + }); + + String tileOverlayId; + + bool fadeIn; + + double transparency; + + int zIndex; + + bool visible; + + int tileSize; + + Object encode() { + return [ + tileOverlayId, + fadeIn, + transparency, + zIndex, + visible, + tileSize, + ]; + } + + static PlatformTileOverlay decode(Object result) { + result as List; + return PlatformTileOverlay( + tileOverlayId: result[0]! as String, + fadeIn: result[1]! as bool, + transparency: result[2]! as double, + zIndex: result[3]! as int, + visible: result[4]! as bool, + tileSize: result[5]! as int, + ); + } +} + +/// Pigeon equivalent of Flutter's EdgeInsets. +class PlatformEdgeInsets { + PlatformEdgeInsets({ + required this.top, + required this.bottom, + required this.left, + required this.right, + }); + + double top; + + double bottom; + + double left; + + double right; + + Object encode() { + return [ + top, + bottom, + left, + right, + ]; + } + + static PlatformEdgeInsets decode(Object result) { + result as List; + return PlatformEdgeInsets( + top: result[0]! as double, + bottom: result[1]! as double, + left: result[2]! as double, + right: result[3]! as double, + ); + } +} + /// Pigeon equivalent of LatLng. class PlatformLatLng { PlatformLatLng({ @@ -87,7 +977,7 @@ class PlatformCluster { PlatformLatLngBounds bounds; - List markerIds; + List markerIds; Object encode() { return [ @@ -104,7 +994,213 @@ class PlatformCluster { clusterManagerId: result[0]! as String, position: result[1]! as PlatformLatLng, bounds: result[2]! as PlatformLatLngBounds, - markerIds: (result[3] as List?)!.cast(), + markerIds: (result[3] as List?)!.cast(), + ); + } +} + +/// Pigeon equivalent of CameraTargetBounds. +/// +/// As with the Dart version, it exists to distinguish between not setting a +/// a target, and having an explicitly unbounded target (null [bounds]). +class PlatformCameraTargetBounds { + PlatformCameraTargetBounds({ + this.bounds, + }); + + PlatformLatLngBounds? bounds; + + Object encode() { + return [ + bounds, + ]; + } + + static PlatformCameraTargetBounds decode(Object result) { + result as List; + return PlatformCameraTargetBounds( + bounds: result[0] as PlatformLatLngBounds?, + ); + } +} + +/// Information passed to the platform view creation. +class PlatformMapViewCreationParams { + PlatformMapViewCreationParams({ + required this.initialCameraPosition, + required this.mapConfiguration, + required this.initialCircles, + required this.initialMarkers, + required this.initialPolygons, + required this.initialPolylines, + required this.initialHeatmaps, + required this.initialTileOverlays, + required this.initialClusterManagers, + }); + + PlatformCameraPosition initialCameraPosition; + + PlatformMapConfiguration mapConfiguration; + + List initialCircles; + + List initialMarkers; + + List initialPolygons; + + List initialPolylines; + + List initialHeatmaps; + + List initialTileOverlays; + + List initialClusterManagers; + + Object encode() { + return [ + initialCameraPosition, + mapConfiguration, + initialCircles, + initialMarkers, + initialPolygons, + initialPolylines, + initialHeatmaps, + initialTileOverlays, + initialClusterManagers, + ]; + } + + static PlatformMapViewCreationParams decode(Object result) { + result as List; + return PlatformMapViewCreationParams( + initialCameraPosition: result[0]! as PlatformCameraPosition, + mapConfiguration: result[1]! as PlatformMapConfiguration, + initialCircles: (result[2] as List?)!.cast(), + initialMarkers: (result[3] as List?)!.cast(), + initialPolygons: (result[4] as List?)!.cast(), + initialPolylines: (result[5] as List?)!.cast(), + initialHeatmaps: (result[6] as List?)!.cast(), + initialTileOverlays: + (result[7] as List?)!.cast(), + initialClusterManagers: + (result[8] as List?)!.cast(), + ); + } +} + +/// Pigeon equivalent of MapConfiguration. +class PlatformMapConfiguration { + PlatformMapConfiguration({ + this.compassEnabled, + this.cameraTargetBounds, + this.mapType, + this.minMaxZoomPreference, + this.mapToolbarEnabled, + this.rotateGesturesEnabled, + this.scrollGesturesEnabled, + this.tiltGesturesEnabled, + this.trackCameraPosition, + this.zoomControlsEnabled, + this.zoomGesturesEnabled, + this.myLocationEnabled, + this.myLocationButtonEnabled, + this.padding, + this.indoorViewEnabled, + this.trafficEnabled, + this.buildingsEnabled, + this.liteModeEnabled, + this.cloudMapId, + this.style, + }); + + bool? compassEnabled; + + PlatformCameraTargetBounds? cameraTargetBounds; + + PlatformMapType? mapType; + + PlatformZoomRange? minMaxZoomPreference; + + bool? mapToolbarEnabled; + + bool? rotateGesturesEnabled; + + bool? scrollGesturesEnabled; + + bool? tiltGesturesEnabled; + + bool? trackCameraPosition; + + bool? zoomControlsEnabled; + + bool? zoomGesturesEnabled; + + bool? myLocationEnabled; + + bool? myLocationButtonEnabled; + + PlatformEdgeInsets? padding; + + bool? indoorViewEnabled; + + bool? trafficEnabled; + + bool? buildingsEnabled; + + bool? liteModeEnabled; + + String? cloudMapId; + + String? style; + + Object encode() { + return [ + compassEnabled, + cameraTargetBounds, + mapType, + minMaxZoomPreference, + mapToolbarEnabled, + rotateGesturesEnabled, + scrollGesturesEnabled, + tiltGesturesEnabled, + trackCameraPosition, + zoomControlsEnabled, + zoomGesturesEnabled, + myLocationEnabled, + myLocationButtonEnabled, + padding, + indoorViewEnabled, + trafficEnabled, + buildingsEnabled, + liteModeEnabled, + cloudMapId, + style, + ]; + } + + static PlatformMapConfiguration decode(Object result) { + result as List; + return PlatformMapConfiguration( + compassEnabled: result[0] as bool?, + cameraTargetBounds: result[1] as PlatformCameraTargetBounds?, + mapType: result[2] as PlatformMapType?, + minMaxZoomPreference: result[3] as PlatformZoomRange?, + mapToolbarEnabled: result[4] as bool?, + rotateGesturesEnabled: result[5] as bool?, + scrollGesturesEnabled: result[6] as bool?, + tiltGesturesEnabled: result[7] as bool?, + trackCameraPosition: result[8] as bool?, + zoomControlsEnabled: result[9] as bool?, + zoomGesturesEnabled: result[10] as bool?, + myLocationEnabled: result[11] as bool?, + myLocationButtonEnabled: result[12] as bool?, + padding: result[13] as PlatformEdgeInsets?, + indoorViewEnabled: result[14] as bool?, + trafficEnabled: result[15] as bool?, + buildingsEnabled: result[16] as bool?, + liteModeEnabled: result[17] as bool?, + cloudMapId: result[18] as String?, + style: result[19] as String?, ); } } @@ -118,84 +1214,313 @@ class PlatformPoint { int x; - int y; + int y; + + Object encode() { + return [ + x, + y, + ]; + } + + static PlatformPoint decode(Object result) { + result as List; + return PlatformPoint( + x: result[0]! as int, + y: result[1]! as int, + ); + } +} + +/// Pigeon equivalent of native TileOverlay properties. +class PlatformTileLayer { + PlatformTileLayer({ + required this.visible, + required this.fadeIn, + required this.transparency, + required this.zIndex, + }); + + bool visible; + + bool fadeIn; + + double transparency; + + double zIndex; + + Object encode() { + return [ + visible, + fadeIn, + transparency, + zIndex, + ]; + } + + static PlatformTileLayer decode(Object result) { + result as List; + return PlatformTileLayer( + visible: result[0]! as bool, + fadeIn: result[1]! as bool, + transparency: result[2]! as double, + zIndex: result[3]! as double, + ); + } +} + +/// Possible outcomes of launching a URL. +class PlatformZoomRange { + PlatformZoomRange({ + this.min, + this.max, + }); + + double? min; + + double? max; + + Object encode() { + return [ + min, + max, + ]; + } + + static PlatformZoomRange decode(Object result) { + result as List; + return PlatformZoomRange( + min: result[0] as double?, + max: result[1] as double?, + ); + } +} + +/// Pigeon equivalent of [BitmapDescriptor]. As there are multiple disjoint +/// types of [BitmapDescriptor], [PlatformBitmap] contains a single field which +/// may hold the pigeon equivalent type of any of them. +class PlatformBitmap { + PlatformBitmap({ + required this.bitmap, + }); + + /// One of [PlatformBitmapAssetMap], [PlatformBitmapAsset], + /// [PlatformBitmapAssetImage], [PlatformBitmapBytesMap], + /// [PlatformBitmapBytes], or [PlatformBitmapDefaultMarker]. + /// As Pigeon does not currently support data class inheritance, this + /// approach allows for the different bitmap implementations to be valid + /// argument and return types of the API methods. See + /// https://github.com/flutter/flutter/issues/117819. + Object bitmap; + + Object encode() { + return [ + bitmap, + ]; + } + + static PlatformBitmap decode(Object result) { + result as List; + return PlatformBitmap( + bitmap: result[0]!, + ); + } +} + +/// Pigeon equivalent of [DefaultMarker]. See +/// https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/BitmapDescriptorFactory#defaultMarker(float) +class PlatformBitmapDefaultMarker { + PlatformBitmapDefaultMarker({ + this.hue, + }); + + double? hue; + + Object encode() { + return [ + hue, + ]; + } + + static PlatformBitmapDefaultMarker decode(Object result) { + result as List; + return PlatformBitmapDefaultMarker( + hue: result[0] as double?, + ); + } +} + +/// Pigeon equivalent of [BytesBitmap]. See +/// https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/BitmapDescriptorFactory#fromBitmap(android.graphics.Bitmap) +class PlatformBitmapBytes { + PlatformBitmapBytes({ + required this.byteData, + this.size, + }); + + Uint8List byteData; + + PlatformDoublePair? size; + + Object encode() { + return [ + byteData, + size, + ]; + } + + static PlatformBitmapBytes decode(Object result) { + result as List; + return PlatformBitmapBytes( + byteData: result[0]! as Uint8List, + size: result[1] as PlatformDoublePair?, + ); + } +} + +/// Pigeon equivalent of [AssetBitmap]. See +/// https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/BitmapDescriptorFactory#public-static-bitmapdescriptor-fromasset-string-assetname +class PlatformBitmapAsset { + PlatformBitmapAsset({ + required this.name, + this.pkg, + }); + + String name; + + String? pkg; + + Object encode() { + return [ + name, + pkg, + ]; + } + + static PlatformBitmapAsset decode(Object result) { + result as List; + return PlatformBitmapAsset( + name: result[0]! as String, + pkg: result[1] as String?, + ); + } +} + +/// Pigeon equivalent of [AssetImageBitmap]. See +/// https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/BitmapDescriptorFactory#public-static-bitmapdescriptor-fromasset-string-assetname +class PlatformBitmapAssetImage { + PlatformBitmapAssetImage({ + required this.name, + required this.scale, + this.size, + }); + + String name; + + double scale; + + PlatformDoublePair? size; Object encode() { return [ - x, - y, + name, + scale, + size, ]; } - static PlatformPoint decode(Object result) { + static PlatformBitmapAssetImage decode(Object result) { result as List; - return PlatformPoint( - x: result[0]! as int, - y: result[1]! as int, + return PlatformBitmapAssetImage( + name: result[0]! as String, + scale: result[1]! as double, + size: result[2] as PlatformDoublePair?, ); } } -/// Pigeon equivalent of native TileOverlay properties. -class PlatformTileLayer { - PlatformTileLayer({ - required this.visible, - required this.fadeIn, - required this.transparency, - required this.zIndex, +/// Pigeon equivalent of [AssetMapBitmap]. See +/// https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/BitmapDescriptorFactory#public-static-bitmapdescriptor-fromasset-string-assetname +class PlatformBitmapAssetMap { + PlatformBitmapAssetMap({ + required this.assetName, + required this.bitmapScaling, + required this.imagePixelRatio, + this.width, + this.height, }); - bool visible; + String assetName; - bool fadeIn; + PlatformMapBitmapScaling bitmapScaling; - double transparency; + double imagePixelRatio; - double zIndex; + double? width; + + double? height; Object encode() { return [ - visible, - fadeIn, - transparency, - zIndex, + assetName, + bitmapScaling, + imagePixelRatio, + width, + height, ]; } - static PlatformTileLayer decode(Object result) { + static PlatformBitmapAssetMap decode(Object result) { result as List; - return PlatformTileLayer( - visible: result[0]! as bool, - fadeIn: result[1]! as bool, - transparency: result[2]! as double, - zIndex: result[3]! as double, + return PlatformBitmapAssetMap( + assetName: result[0]! as String, + bitmapScaling: result[1]! as PlatformMapBitmapScaling, + imagePixelRatio: result[2]! as double, + width: result[3] as double?, + height: result[4] as double?, ); } } -/// Possible outcomes of launching a URL. -class PlatformZoomRange { - PlatformZoomRange({ - required this.min, - required this.max, +/// Pigeon equivalent of [BytesMapBitmap]. See +/// https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/BitmapDescriptorFactory#public-static-bitmapdescriptor-frombitmap-bitmap-image +class PlatformBitmapBytesMap { + PlatformBitmapBytesMap({ + required this.byteData, + required this.bitmapScaling, + required this.imagePixelRatio, + this.width, + this.height, }); - double min; + Uint8List byteData; - double max; + PlatformMapBitmapScaling bitmapScaling; + + double imagePixelRatio; + + double? width; + + double? height; Object encode() { return [ - min, - max, + byteData, + bitmapScaling, + imagePixelRatio, + width, + height, ]; } - static PlatformZoomRange decode(Object result) { + static PlatformBitmapBytesMap decode(Object result) { result as List; - return PlatformZoomRange( - min: result[0]! as double, - max: result[1]! as double, + return PlatformBitmapBytesMap( + byteData: result[0]! as Uint8List, + bitmapScaling: result[1]! as PlatformMapBitmapScaling, + imagePixelRatio: result[2]! as double, + width: result[3] as double?, + height: result[4] as double?, ); } } @@ -204,23 +1529,143 @@ class _PigeonCodec extends StandardMessageCodec { const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is PlatformLatLng) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is PlatformMapType) { buffer.putUint8(129); + writeValue(buffer, value.index); + } else if (value is PlatformRendererType) { + buffer.putUint8(130); + writeValue(buffer, value.index); + } else if (value is PlatformJointType) { + buffer.putUint8(131); + writeValue(buffer, value.index); + } else if (value is PlatformCapType) { + buffer.putUint8(132); + writeValue(buffer, value.index); + } else if (value is PlatformPatternItemType) { + buffer.putUint8(133); + writeValue(buffer, value.index); + } else if (value is PlatformMapBitmapScaling) { + buffer.putUint8(134); + writeValue(buffer, value.index); + } else if (value is PlatformCameraPosition) { + buffer.putUint8(135); + writeValue(buffer, value.encode()); + } else if (value is PlatformCameraUpdate) { + buffer.putUint8(136); + writeValue(buffer, value.encode()); + } else if (value is PlatformCameraUpdateNewCameraPosition) { + buffer.putUint8(137); + writeValue(buffer, value.encode()); + } else if (value is PlatformCameraUpdateNewLatLng) { + buffer.putUint8(138); + writeValue(buffer, value.encode()); + } else if (value is PlatformCameraUpdateNewLatLngBounds) { + buffer.putUint8(139); + writeValue(buffer, value.encode()); + } else if (value is PlatformCameraUpdateNewLatLngZoom) { + buffer.putUint8(140); + writeValue(buffer, value.encode()); + } else if (value is PlatformCameraUpdateScrollBy) { + buffer.putUint8(141); + writeValue(buffer, value.encode()); + } else if (value is PlatformCameraUpdateZoomBy) { + buffer.putUint8(142); + writeValue(buffer, value.encode()); + } else if (value is PlatformCameraUpdateZoom) { + buffer.putUint8(143); + writeValue(buffer, value.encode()); + } else if (value is PlatformCameraUpdateZoomTo) { + buffer.putUint8(144); + writeValue(buffer, value.encode()); + } else if (value is PlatformCircle) { + buffer.putUint8(145); + writeValue(buffer, value.encode()); + } else if (value is PlatformHeatmap) { + buffer.putUint8(146); + writeValue(buffer, value.encode()); + } else if (value is PlatformClusterManager) { + buffer.putUint8(147); + writeValue(buffer, value.encode()); + } else if (value is PlatformDoublePair) { + buffer.putUint8(148); + writeValue(buffer, value.encode()); + } else if (value is PlatformInfoWindow) { + buffer.putUint8(149); + writeValue(buffer, value.encode()); + } else if (value is PlatformMarker) { + buffer.putUint8(150); + writeValue(buffer, value.encode()); + } else if (value is PlatformPolygon) { + buffer.putUint8(151); + writeValue(buffer, value.encode()); + } else if (value is PlatformPolyline) { + buffer.putUint8(152); + writeValue(buffer, value.encode()); + } else if (value is PlatformCap) { + buffer.putUint8(153); + writeValue(buffer, value.encode()); + } else if (value is PlatformPatternItem) { + buffer.putUint8(154); + writeValue(buffer, value.encode()); + } else if (value is PlatformTile) { + buffer.putUint8(155); + writeValue(buffer, value.encode()); + } else if (value is PlatformTileOverlay) { + buffer.putUint8(156); + writeValue(buffer, value.encode()); + } else if (value is PlatformEdgeInsets) { + buffer.putUint8(157); + writeValue(buffer, value.encode()); + } else if (value is PlatformLatLng) { + buffer.putUint8(158); writeValue(buffer, value.encode()); } else if (value is PlatformLatLngBounds) { - buffer.putUint8(130); + buffer.putUint8(159); writeValue(buffer, value.encode()); } else if (value is PlatformCluster) { - buffer.putUint8(131); + buffer.putUint8(160); + writeValue(buffer, value.encode()); + } else if (value is PlatformCameraTargetBounds) { + buffer.putUint8(161); + writeValue(buffer, value.encode()); + } else if (value is PlatformMapViewCreationParams) { + buffer.putUint8(162); + writeValue(buffer, value.encode()); + } else if (value is PlatformMapConfiguration) { + buffer.putUint8(163); writeValue(buffer, value.encode()); } else if (value is PlatformPoint) { - buffer.putUint8(132); + buffer.putUint8(164); writeValue(buffer, value.encode()); } else if (value is PlatformTileLayer) { - buffer.putUint8(133); + buffer.putUint8(165); writeValue(buffer, value.encode()); } else if (value is PlatformZoomRange) { - buffer.putUint8(134); + buffer.putUint8(166); + writeValue(buffer, value.encode()); + } else if (value is PlatformBitmap) { + buffer.putUint8(167); + writeValue(buffer, value.encode()); + } else if (value is PlatformBitmapDefaultMarker) { + buffer.putUint8(168); + writeValue(buffer, value.encode()); + } else if (value is PlatformBitmapBytes) { + buffer.putUint8(169); + writeValue(buffer, value.encode()); + } else if (value is PlatformBitmapAsset) { + buffer.putUint8(170); + writeValue(buffer, value.encode()); + } else if (value is PlatformBitmapAssetImage) { + buffer.putUint8(171); + writeValue(buffer, value.encode()); + } else if (value is PlatformBitmapAssetMap) { + buffer.putUint8(172); + writeValue(buffer, value.encode()); + } else if (value is PlatformBitmapBytesMap) { + buffer.putUint8(173); writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); @@ -231,17 +1676,101 @@ class _PigeonCodec extends StandardMessageCodec { Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { case 129: - return PlatformLatLng.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformMapType.values[value]; case 130: - return PlatformLatLngBounds.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformRendererType.values[value]; case 131: - return PlatformCluster.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformJointType.values[value]; case 132: - return PlatformPoint.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformCapType.values[value]; case 133: - return PlatformTileLayer.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformPatternItemType.values[value]; case 134: + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformMapBitmapScaling.values[value]; + case 135: + return PlatformCameraPosition.decode(readValue(buffer)!); + case 136: + return PlatformCameraUpdate.decode(readValue(buffer)!); + case 137: + return PlatformCameraUpdateNewCameraPosition.decode(readValue(buffer)!); + case 138: + return PlatformCameraUpdateNewLatLng.decode(readValue(buffer)!); + case 139: + return PlatformCameraUpdateNewLatLngBounds.decode(readValue(buffer)!); + case 140: + return PlatformCameraUpdateNewLatLngZoom.decode(readValue(buffer)!); + case 141: + return PlatformCameraUpdateScrollBy.decode(readValue(buffer)!); + case 142: + return PlatformCameraUpdateZoomBy.decode(readValue(buffer)!); + case 143: + return PlatformCameraUpdateZoom.decode(readValue(buffer)!); + case 144: + return PlatformCameraUpdateZoomTo.decode(readValue(buffer)!); + case 145: + return PlatformCircle.decode(readValue(buffer)!); + case 146: + return PlatformHeatmap.decode(readValue(buffer)!); + case 147: + return PlatformClusterManager.decode(readValue(buffer)!); + case 148: + return PlatformDoublePair.decode(readValue(buffer)!); + case 149: + return PlatformInfoWindow.decode(readValue(buffer)!); + case 150: + return PlatformMarker.decode(readValue(buffer)!); + case 151: + return PlatformPolygon.decode(readValue(buffer)!); + case 152: + return PlatformPolyline.decode(readValue(buffer)!); + case 153: + return PlatformCap.decode(readValue(buffer)!); + case 154: + return PlatformPatternItem.decode(readValue(buffer)!); + case 155: + return PlatformTile.decode(readValue(buffer)!); + case 156: + return PlatformTileOverlay.decode(readValue(buffer)!); + case 157: + return PlatformEdgeInsets.decode(readValue(buffer)!); + case 158: + return PlatformLatLng.decode(readValue(buffer)!); + case 159: + return PlatformLatLngBounds.decode(readValue(buffer)!); + case 160: + return PlatformCluster.decode(readValue(buffer)!); + case 161: + return PlatformCameraTargetBounds.decode(readValue(buffer)!); + case 162: + return PlatformMapViewCreationParams.decode(readValue(buffer)!); + case 163: + return PlatformMapConfiguration.decode(readValue(buffer)!); + case 164: + return PlatformPoint.decode(readValue(buffer)!); + case 165: + return PlatformTileLayer.decode(readValue(buffer)!); + case 166: return PlatformZoomRange.decode(readValue(buffer)!); + case 167: + return PlatformBitmap.decode(readValue(buffer)!); + case 168: + return PlatformBitmapDefaultMarker.decode(readValue(buffer)!); + case 169: + return PlatformBitmapBytes.decode(readValue(buffer)!); + case 170: + return PlatformBitmapAsset.decode(readValue(buffer)!); + case 171: + return PlatformBitmapAssetImage.decode(readValue(buffer)!); + case 172: + return PlatformBitmapAssetMap.decode(readValue(buffer)!); + case 173: + return PlatformBitmapBytesMap.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -256,34 +1785,245 @@ class MapsApi { /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. MapsApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : __pigeon_binaryMessenger = binaryMessenger, - __pigeon_messageChannelSuffix = + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; - final BinaryMessenger? __pigeon_binaryMessenger; + final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - final String __pigeon_messageChannelSuffix; + final String pigeonVar_messageChannelSuffix; /// Returns once the map instance is available. Future waitForMap() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.waitForMap$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.waitForMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Updates the map's configuration options. + /// + /// Only non-null configuration values will result in updates; options with + /// null values will remain unchanged. + Future updateMapConfiguration( + PlatformMapConfiguration configuration) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.updateMapConfiguration$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([configuration]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Updates the set of circles on the map. + Future updateCircles(List toAdd, + List toChange, List idsToRemove) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.updateCircles$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([toAdd, toChange, idsToRemove]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Updates the set of heatmaps on the map. + Future updateHeatmaps(List toAdd, + List toChange, List idsToRemove) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.updateHeatmaps$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([toAdd, toChange, idsToRemove]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Updates the set of custer managers for clusters on the map. + Future updateClusterManagers( + List toAdd, List idsToRemove) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.updateClusterManagers$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([toAdd, idsToRemove]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Updates the set of markers on the map. + Future updateMarkers(List toAdd, + List toChange, List idsToRemove) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.updateMarkers$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([toAdd, toChange, idsToRemove]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Updates the set of polygonss on the map. + Future updatePolygons(List toAdd, + List toChange, List idsToRemove) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.updatePolygons$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([toAdd, toChange, idsToRemove]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Updates the set of polylines on the map. + Future updatePolylines(List toAdd, + List toChange, List idsToRemove) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.updatePolylines$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([toAdd, toChange, idsToRemove]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Updates the set of tile overlays on the map. + Future updateTileOverlays(List toAdd, + List toChange, List idsToRemove) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.updateTileOverlays$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([toAdd, toChange, idsToRemove]) 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; @@ -292,143 +2032,194 @@ class MapsApi { /// Gets the screen coordinate for the given map location. Future getScreenCoordinate(PlatformLatLng latLng) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.getScreenCoordinate$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.getScreenCoordinate$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([latLng]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([latLng]) 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 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 PlatformPoint?)!; + return (pigeonVar_replyList[0] as PlatformPoint?)!; } } /// Gets the map location for the given screen coordinate. Future getLatLng(PlatformPoint screenCoordinate) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.getLatLng$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.getLatLng$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([screenCoordinate]) 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 PlatformLatLng?)!; + return (pigeonVar_replyList[0] as PlatformLatLng?)!; } } /// Gets the map region currently displayed on the map. Future getVisibleRegion() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.getVisibleRegion$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.getVisibleRegion$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 PlatformLatLngBounds?)!; + return (pigeonVar_replyList[0] as PlatformLatLngBounds?)!; + } + } + + /// Moves the camera according to [cameraUpdate] immediately, with no + /// animation. + Future moveCamera(PlatformCameraUpdate cameraUpdate) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.moveCamera$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([cameraUpdate]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Moves the camera according to [cameraUpdate], animating the update. + Future animateCamera(PlatformCameraUpdate cameraUpdate) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.animateCamera$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([cameraUpdate]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; } } /// Gets the current map zoom level. Future getZoomLevel() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.getZoomLevel$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.getZoomLevel$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 double?)!; + return (pigeonVar_replyList[0] as double?)!; } } /// Show the info window for the marker with the given ID. Future showInfoWindow(String markerId) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.showInfoWindow$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.showInfoWindow$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([markerId]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([markerId]) 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; @@ -437,23 +2228,23 @@ class MapsApi { /// Hide the info window for the marker with the given ID. Future hideInfoWindow(String markerId) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.hideInfoWindow$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.hideInfoWindow$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([markerId]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([markerId]) 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; @@ -463,31 +2254,31 @@ class MapsApi { /// Returns true if the marker with the given ID is currently displaying its /// info window. Future isInfoWindowShown(String markerId) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.isInfoWindowShown$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.isInfoWindowShown$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([markerId]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([markerId]) 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 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 bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } @@ -497,31 +2288,31 @@ class MapsApi { /// Returns false if there was an error setting the style, such as an invalid /// style string. Future setStyle(String style) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.setStyle$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.setStyle$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([style]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([style]) 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 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 bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } @@ -531,53 +2322,53 @@ class MapsApi { /// This allows checking asynchronously for initial style failures, as there /// is no way to return failures from map initialization. Future didLastStyleSucceed() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.didLastStyleSucceed$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.didLastStyleSucceed$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } /// Clears the cache of tiles previously requseted from the tile provider. Future clearTileCache(String tileOverlayId) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.clearTileCache$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.clearTileCache$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([tileOverlayId]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([tileOverlayId]) 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; @@ -586,31 +2377,626 @@ class MapsApi { /// Takes a snapshot of the map and returns its image data. Future takeSnapshot() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.takeSnapshot$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.takeSnapshot$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as Uint8List?)!; + } + } +} + +abstract class MapsCallbackApi { + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + /// Called when the map camera starts moving. + void onCameraMoveStarted(); + + /// Called when the map camera moves. + void onCameraMove(PlatformCameraPosition cameraPosition); + + /// Called when the map camera stops moving. + void onCameraIdle(); + + /// Called when the map, not a specifc map object, is tapped. + void onTap(PlatformLatLng position); + + /// Called when the map, not a specifc map object, is long pressed. + void onLongPress(PlatformLatLng position); + + /// Called when a marker is tapped. + void onMarkerTap(String markerId); + + /// Called when a marker drag starts. + void onMarkerDragStart(String markerId, PlatformLatLng position); + + /// Called when a marker drag updates. + void onMarkerDrag(String markerId, PlatformLatLng position); + + /// Called when a marker drag ends. + void onMarkerDragEnd(String markerId, PlatformLatLng position); + + /// Called when a marker's info window is tapped. + void onInfoWindowTap(String markerId); + + /// Called when a circle is tapped. + void onCircleTap(String circleId); + + /// Called when a marker cluster is tapped. + void onClusterTap(PlatformCluster cluster); + + /// Called when a polygon is tapped. + void onPolygonTap(String polygonId); + + /// Called when a polyline is tapped. + void onPolylineTap(String polylineId); + + /// Called to get data for a map tile. + Future getTileOverlayTile( + String tileOverlayId, PlatformPoint location, int zoom); + + static void setUp( + MapsCallbackApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onCameraMoveStarted$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + try { + api.onCameraMoveStarted(); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onCameraMove$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onCameraMove was null.'); + final List args = (message as List?)!; + final PlatformCameraPosition? arg_cameraPosition = + (args[0] as PlatformCameraPosition?); + assert(arg_cameraPosition != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onCameraMove was null, expected non-null PlatformCameraPosition.'); + try { + api.onCameraMove(arg_cameraPosition!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onCameraIdle$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + try { + api.onCameraIdle(); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onTap$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onTap was null.'); + final List args = (message as List?)!; + final PlatformLatLng? arg_position = (args[0] as PlatformLatLng?); + assert(arg_position != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onTap was null, expected non-null PlatformLatLng.'); + try { + api.onTap(arg_position!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onLongPress$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onLongPress was null.'); + final List args = (message as List?)!; + final PlatformLatLng? arg_position = (args[0] as PlatformLatLng?); + assert(arg_position != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onLongPress was null, expected non-null PlatformLatLng.'); + try { + api.onLongPress(arg_position!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onMarkerTap$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onMarkerTap was null.'); + final List args = (message as List?)!; + final String? arg_markerId = (args[0] as String?); + assert(arg_markerId != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onMarkerTap was null, expected non-null String.'); + try { + api.onMarkerTap(arg_markerId!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onMarkerDragStart$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onMarkerDragStart was null.'); + final List args = (message as List?)!; + final String? arg_markerId = (args[0] as String?); + assert(arg_markerId != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onMarkerDragStart was null, expected non-null String.'); + final PlatformLatLng? arg_position = (args[1] as PlatformLatLng?); + assert(arg_position != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onMarkerDragStart was null, expected non-null PlatformLatLng.'); + try { + api.onMarkerDragStart(arg_markerId!, arg_position!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onMarkerDrag$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onMarkerDrag was null.'); + final List args = (message as List?)!; + final String? arg_markerId = (args[0] as String?); + assert(arg_markerId != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onMarkerDrag was null, expected non-null String.'); + final PlatformLatLng? arg_position = (args[1] as PlatformLatLng?); + assert(arg_position != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onMarkerDrag was null, expected non-null PlatformLatLng.'); + try { + api.onMarkerDrag(arg_markerId!, arg_position!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onMarkerDragEnd$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onMarkerDragEnd was null.'); + final List args = (message as List?)!; + final String? arg_markerId = (args[0] as String?); + assert(arg_markerId != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onMarkerDragEnd was null, expected non-null String.'); + final PlatformLatLng? arg_position = (args[1] as PlatformLatLng?); + assert(arg_position != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onMarkerDragEnd was null, expected non-null PlatformLatLng.'); + try { + api.onMarkerDragEnd(arg_markerId!, arg_position!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onInfoWindowTap$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onInfoWindowTap was null.'); + final List args = (message as List?)!; + final String? arg_markerId = (args[0] as String?); + assert(arg_markerId != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onInfoWindowTap was null, expected non-null String.'); + try { + api.onInfoWindowTap(arg_markerId!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onCircleTap$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onCircleTap was null.'); + final List args = (message as List?)!; + final String? arg_circleId = (args[0] as String?); + assert(arg_circleId != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onCircleTap was null, expected non-null String.'); + try { + api.onCircleTap(arg_circleId!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onClusterTap$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onClusterTap was null.'); + final List args = (message as List?)!; + final PlatformCluster? arg_cluster = (args[0] as PlatformCluster?); + assert(arg_cluster != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onClusterTap was null, expected non-null PlatformCluster.'); + try { + api.onClusterTap(arg_cluster!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onPolygonTap$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onPolygonTap was null.'); + final List args = (message as List?)!; + final String? arg_polygonId = (args[0] as String?); + assert(arg_polygonId != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onPolygonTap was null, expected non-null String.'); + try { + api.onPolygonTap(arg_polygonId!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onPolylineTap$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onPolylineTap was null.'); + final List args = (message as List?)!; + final String? arg_polylineId = (args[0] as String?); + assert(arg_polylineId != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onPolylineTap was null, expected non-null String.'); + try { + api.onPolylineTap(arg_polylineId!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.getTileOverlayTile$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.getTileOverlayTile was null.'); + final List args = (message as List?)!; + final String? arg_tileOverlayId = (args[0] as String?); + assert(arg_tileOverlayId != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.getTileOverlayTile was null, expected non-null String.'); + final PlatformPoint? arg_location = (args[1] as PlatformPoint?); + assert(arg_location != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.getTileOverlayTile was null, expected non-null PlatformPoint.'); + final int? arg_zoom = (args[2] as int?); + assert(arg_zoom != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.getTileOverlayTile was null, expected non-null int.'); + try { + final PlatformTile output = await api.getTileOverlayTile( + arg_tileOverlayId!, arg_location!, arg_zoom!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } +} + +/// Interface for global SDK initialization. +class MapsInitializerApi { + /// Constructor for [MapsInitializerApi]. 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. + MapsInitializerApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String pigeonVar_messageChannelSuffix; + + /// Initializes the Google Maps SDK with the given renderer preference. + /// + /// A null renderer preference will result in the default renderer. + /// + /// Calling this more than once in the lifetime of an application will result + /// in an error. + Future initializeWithPreferredRenderer( + PlatformRendererType? type) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsInitializerApi.initializeWithPreferredRenderer$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([type]) 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 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 Uint8List?)!; + return (pigeonVar_replyList[0] as PlatformRendererType?)!; + } + } +} + +/// Dummy interface to force generation of the platform view creation params, +/// which are not used in any Pigeon calls, only the platform view creation +/// call made internally by Flutter. +class MapsPlatformViewApi { + /// Constructor for [MapsPlatformViewApi]. 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. + MapsPlatformViewApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String pigeonVar_messageChannelSuffix; + + Future createView(PlatformMapViewCreationParams? type) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsPlatformViewApi.createView$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([type]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; } } } @@ -622,409 +3008,409 @@ class MapsInspectorApi { /// BinaryMessenger will be used which routes to the host platform. MapsInspectorApi( {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : __pigeon_binaryMessenger = binaryMessenger, - __pigeon_messageChannelSuffix = + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; - final BinaryMessenger? __pigeon_binaryMessenger; + final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - final String __pigeon_messageChannelSuffix; + final String pigeonVar_messageChannelSuffix; Future areBuildingsEnabled() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.areBuildingsEnabled$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.areBuildingsEnabled$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } Future areRotateGesturesEnabled() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.areRotateGesturesEnabled$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.areRotateGesturesEnabled$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } Future areZoomControlsEnabled() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.areZoomControlsEnabled$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.areZoomControlsEnabled$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } Future areScrollGesturesEnabled() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.areScrollGesturesEnabled$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.areScrollGesturesEnabled$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } Future areTiltGesturesEnabled() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.areTiltGesturesEnabled$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.areTiltGesturesEnabled$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } Future areZoomGesturesEnabled() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.areZoomGesturesEnabled$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.areZoomGesturesEnabled$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } Future isCompassEnabled() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.isCompassEnabled$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.isCompassEnabled$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } Future isLiteModeEnabled() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.isLiteModeEnabled$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.isLiteModeEnabled$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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?); } } Future isMapToolbarEnabled() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.isMapToolbarEnabled$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.isMapToolbarEnabled$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } Future isMyLocationButtonEnabled() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.isMyLocationButtonEnabled$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.isMyLocationButtonEnabled$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } Future isTrafficEnabled() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.isTrafficEnabled$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.isTrafficEnabled$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } Future getTileOverlayInfo(String tileOverlayId) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.getTileOverlayInfo$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.getTileOverlayInfo$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([tileOverlayId]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([tileOverlayId]) 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 PlatformTileLayer?); + return (pigeonVar_replyList[0] as PlatformTileLayer?); } } Future getZoomRange() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.getZoomRange$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.getZoomRange$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 PlatformZoomRange?)!; + return (pigeonVar_replyList[0] as PlatformZoomRange?)!; } } - Future> getClusters(String clusterManagerId) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.getClusters$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + Future> getClusters(String clusterManagerId) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsInspectorApi.getClusters$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([clusterManagerId]) 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/google_maps_flutter/google_maps_flutter_android/lib/src/serialization.dart b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/serialization.dart new file mode 100644 index 000000000000..fee4828fe716 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/serialization.dart @@ -0,0 +1,121 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; + +// These constants must match the corresponding constants in Convert.java +const String _heatmapIdKey = 'heatmapId'; +const String _heatmapDataKey = 'data'; +const String _heatmapGradientKey = 'gradient'; +const String _heatmapMaxIntensityKey = 'maxIntensity'; +const String _heatmapOpacityKey = 'opacity'; +const String _heatmapRadiusKey = 'radius'; +const String _heatmapGradientColorsKey = 'colors'; +const String _heatmapGradientStartPointsKey = 'startPoints'; +const String _heatmapGradientColorMapSizeKey = 'colorMapSize'; + +void _addIfNonNull(Map map, String fieldName, Object? value) { + if (value != null) { + map[fieldName] = value; + } +} + +/// Serialize [Heatmap] +Map serializeHeatmap(Heatmap heatmap) { + final Map json = {}; + + _addIfNonNull(json, _heatmapIdKey, heatmap.heatmapId.value); + _addIfNonNull( + json, + _heatmapDataKey, + heatmap.data.map(serializeWeightedLatLng).toList(), + ); + + final HeatmapGradient? gradient = heatmap.gradient; + if (gradient != null) { + _addIfNonNull( + json, _heatmapGradientKey, serializeHeatmapGradient(gradient)); + } + _addIfNonNull(json, _heatmapMaxIntensityKey, heatmap.maxIntensity); + _addIfNonNull(json, _heatmapOpacityKey, heatmap.opacity); + _addIfNonNull(json, _heatmapRadiusKey, heatmap.radius.radius); + + return json; +} + +/// Serialize [WeightedLatLng] +Object serializeWeightedLatLng(WeightedLatLng wll) { + return [serializeLatLng(wll.point), wll.weight]; +} + +/// Deserialize [WeightedLatLng] +WeightedLatLng? deserializeWeightedLatLng(Object? json) { + if (json == null) { + return null; + } + assert(json is List && json.length == 2); + final List list = json as List; + final LatLng latLng = deserializeLatLng(list[0])!; + return WeightedLatLng(latLng, weight: list[1] as double); +} + +/// Serialize [LatLng] +Object serializeLatLng(LatLng latLng) { + return [latLng.latitude, latLng.longitude]; +} + +/// Deserialize [LatLng] +LatLng? deserializeLatLng(Object? json) { + if (json == null) { + return null; + } + assert(json is List && json.length == 2); + final List list = json as List; + return LatLng(list[0]! as double, list[1]! as double); +} + +/// Serialize [HeatmapGradient] +Object serializeHeatmapGradient(HeatmapGradient gradient) { + final Map json = {}; + + _addIfNonNull( + json, + _heatmapGradientColorsKey, + gradient.colors.map((HeatmapGradientColor e) => e.color.value).toList(), + ); + _addIfNonNull( + json, + _heatmapGradientStartPointsKey, + gradient.colors.map((HeatmapGradientColor e) => e.startPoint).toList(), + ); + _addIfNonNull(json, _heatmapGradientColorMapSizeKey, gradient.colorMapSize); + + return json; +} + +/// Deserialize [HeatmapGradient] +HeatmapGradient? deserializeHeatmapGradient(Object? json) { + if (json == null) { + return null; + } + assert(json is Map); + final Map map = (json as Map).cast(); + final List colors = (map[_heatmapGradientColorsKey]! as List) + .whereType() + .map((int e) => Color(e)) + .toList(); + final List startPoints = + (map[_heatmapGradientStartPointsKey]! as List) + .whereType() + .toList(); + final List gradientColors = []; + for (int i = 0; i < colors.length; i++) { + gradientColors.add(HeatmapGradientColor(colors[i], startPoints[i])); + } + return HeatmapGradient( + gradientColors, + colorMapSize: map[_heatmapGradientColorMapSizeKey] as int? ?? 256, + ); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/utils/cluster_manager_utils.dart b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/utils/cluster_manager_utils.dart deleted file mode 100644 index cdb1d2c9244a..000000000000 --- a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/utils/cluster_manager_utils.dart +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; - -/// Converts a Set of Cluster Managers into object serializable in JSON. -Object serializeClusterManagerSet(Set clusterManagers) { - return clusterManagers - .map((ClusterManager cm) => _serializeClusterManager(cm)) - .toList(); -} - -/// Converts a Cluster Manager into object serializable in JSON. -Object _serializeClusterManager(ClusterManager clusterManager) { - final Map json = {}; - json['clusterManagerId'] = clusterManager.clusterManagerId.value; - return json; -} - -/// Converts a Cluster Manager updates into object serializable in JSON. -Object serializeClusterManagerUpdates( - ClusterManagerUpdates clusterManagerUpdates) { - final Map updateMap = {}; - - updateMap['clusterManagersToAdd'] = - serializeClusterManagerSet(clusterManagerUpdates.objectsToAdd); - updateMap['clusterManagerIdsToRemove'] = clusterManagerUpdates - .objectIdsToRemove - .map((MapsObjectId id) => id.value) - .toList(); - - return updateMap; -} diff --git a/packages/google_maps_flutter/google_maps_flutter_android/pigeons/messages.dart b/packages/google_maps_flutter/google_maps_flutter_android/pigeons/messages.dart index 1a50204c5805..9db93e753140 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/pigeons/messages.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/pigeons/messages.dart @@ -11,6 +11,349 @@ import 'package:pigeon/pigeon.dart'; copyrightHeader: 'pigeons/copyright.txt', )) +/// Pigeon equivalent of MapType +enum PlatformMapType { + none, + normal, + satellite, + terrain, + hybrid, +} + +// Pigeon equivalent of the Java MapsInitializer.Renderer. +enum PlatformRendererType { legacy, latest } + +/// Pigeon representatation of a CameraPosition. +class PlatformCameraPosition { + PlatformCameraPosition({ + required this.bearing, + required this.target, + required this.tilt, + required this.zoom, + }); + + final double bearing; + final PlatformLatLng target; + final double tilt; + final double zoom; +} + +/// Pigeon representation of a CameraUpdate. +class PlatformCameraUpdate { + PlatformCameraUpdate({required this.cameraUpdate}); + + /// This Object shall be any of the below classes prefixed with + /// PlatformCameraUpdate. Each such class represents a different type of + /// camera update, and each holds a different set of data, preventing the + /// use of a single unified class. Pigeon does not support inheritance, which + /// prevents a more strict type bound. + /// See https://github.com/flutter/flutter/issues/117819. + final Object cameraUpdate; +} + +/// Pigeon equivalent of NewCameraPosition +class PlatformCameraUpdateNewCameraPosition { + PlatformCameraUpdateNewCameraPosition(this.cameraPosition); + final PlatformCameraPosition cameraPosition; +} + +/// Pigeon equivalent of NewLatLng +class PlatformCameraUpdateNewLatLng { + PlatformCameraUpdateNewLatLng(this.latLng); + final PlatformLatLng latLng; +} + +/// Pigeon equivalent of NewLatLngBounds +class PlatformCameraUpdateNewLatLngBounds { + PlatformCameraUpdateNewLatLngBounds(this.bounds, this.padding); + final PlatformLatLngBounds bounds; + final double padding; +} + +/// Pigeon equivalent of NewLatLngZoom +class PlatformCameraUpdateNewLatLngZoom { + PlatformCameraUpdateNewLatLngZoom(this.latLng, this.zoom); + final PlatformLatLng latLng; + final double zoom; +} + +/// Pigeon equivalent of ScrollBy +class PlatformCameraUpdateScrollBy { + PlatformCameraUpdateScrollBy(this.dx, this.dy); + final double dx; + final double dy; +} + +/// Pigeon equivalent of ZoomBy +class PlatformCameraUpdateZoomBy { + PlatformCameraUpdateZoomBy(this.amount, [this.focus]); + final double amount; + final PlatformDoublePair? focus; +} + +/// Pigeon equivalent of ZoomIn/ZoomOut +class PlatformCameraUpdateZoom { + PlatformCameraUpdateZoom(this.out); + final bool out; +} + +/// Pigeon equivalent of ZoomTo +class PlatformCameraUpdateZoomTo { + PlatformCameraUpdateZoomTo(this.zoom); + final double zoom; +} + +/// Pigeon equivalent of the Circle class. +class PlatformCircle { + PlatformCircle({ + required this.circleId, + required this.center, + this.consumeTapEvents = false, + this.fillColor = 0x00000000, + this.strokeColor = 0xFF000000, + this.visible = true, + this.strokeWidth = 10, + this.zIndex = 0.0, + this.radius = 0, + }); + + final bool consumeTapEvents; + final int fillColor; + final int strokeColor; + final bool visible; + final int strokeWidth; + final double zIndex; + final PlatformLatLng center; + final double radius; + final String circleId; +} + +/// Pigeon equivalent of the Heatmap class. +class PlatformHeatmap { + PlatformHeatmap(this.json); + + /// The heatmap data, as JSON. This should only be set from + /// Heatmap.toJson, and the native code must interpret it according to the + /// internal implementation details of that method. + // TODO(stuartmorgan): Replace this with structured data. This exists only to + // allow incremental migration to Pigeon. + final Map json; +} + +/// Pigeon equivalent of the ClusterManager class. +class PlatformClusterManager { + PlatformClusterManager({required this.identifier}); + + final String identifier; +} + +/// Pair of double values, such as for an offset or size. +class PlatformDoublePair { + PlatformDoublePair(this.x, this.y); + + final double x; + final double y; +} + +/// Pigeon equivalent of the InfoWindow class. +class PlatformInfoWindow { + PlatformInfoWindow({ + required this.anchor, + this.title, + this.snippet, + }); + + final String? title; + final String? snippet; + final PlatformDoublePair anchor; +} + +/// Pigeon equivalent of the Marker class. +class PlatformMarker { + PlatformMarker({ + required this.markerId, + required this.icon, + this.alpha = 1.0, + required this.anchor, + this.consumeTapEvents = false, + this.draggable = false, + this.flat = false, + required this.infoWindow, + required this.position, + this.rotation = 0.0, + this.visible = true, + this.zIndex = 0.0, + this.clusterManagerId, + }); + + final double alpha; + final PlatformDoublePair anchor; + final bool consumeTapEvents; + final bool draggable; + final bool flat; + + final PlatformBitmap icon; + final PlatformInfoWindow infoWindow; + final PlatformLatLng position; + final double rotation; + final bool visible; + final double zIndex; + final String markerId; + final String? clusterManagerId; +} + +/// Pigeon equivalent of the Polygon class. +class PlatformPolygon { + PlatformPolygon({ + required this.polygonId, + required this.consumesTapEvents, + required this.fillColor, + required this.geodesic, + required this.points, + required this.holes, + required this.visible, + required this.strokeColor, + required this.strokeWidth, + required this.zIndex, + }); + + final String polygonId; + final bool consumesTapEvents; + final int fillColor; + final bool geodesic; + final List points; + final List> holes; + final bool visible; + final int strokeColor; + final int strokeWidth; + final int zIndex; +} + +/// Join types for polyline joints. +enum PlatformJointType { + mitered, + bevel, + round, +} + +/// Pigeon equivalent of the Polyline class. +class PlatformPolyline { + PlatformPolyline({ + required this.polylineId, + required this.consumesTapEvents, + required this.color, + required this.geodesic, + required this.jointType, + required this.patterns, + required this.points, + required this.startCap, + required this.endCap, + required this.visible, + required this.width, + required this.zIndex, + }); + + final String polylineId; + final bool consumesTapEvents; + final int color; + final bool geodesic; + + /// The joint type. + final PlatformJointType jointType; + + /// The pattern data, as a list of pattern items. + final List patterns; + final List points; + + /// The cap at the start and end vertex of a polyline. + /// See https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/Cap. + final PlatformCap startCap; + final PlatformCap endCap; + + final bool visible; + final int width; + final int zIndex; +} + +/// Enumeration of possible types of PlatformCap, corresponding to the +/// subclasses of Cap in the Google Maps Android SDK. +/// See https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/Cap. +enum PlatformCapType { + buttCap, + roundCap, + squareCap, + customCap, +} + +/// Pigeon equivalent of Cap from the platform interface. +/// https://github.com/flutter/packages/blob/main/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/cap.dart +class PlatformCap { + PlatformCap({required this.type, this.bitmapDescriptor, this.refWidth}); + + final PlatformCapType type; + + final PlatformBitmap? bitmapDescriptor; + final double? refWidth; +} + +/// Enumeration of possible types for PatternItem. +enum PlatformPatternItemType { + dot, + dash, + gap, +} + +/// Pigeon equivalent of the PatternItem class. +class PlatformPatternItem { + PlatformPatternItem({required this.type, this.length}); + + final PlatformPatternItemType type; + final double? length; +} + +/// Pigeon equivalent of the Tile class. +class PlatformTile { + PlatformTile({required this.width, required this.height, required this.data}); + + final int width; + final int height; + final Uint8List? data; +} + +/// Pigeon equivalent of the TileOverlay class. +class PlatformTileOverlay { + PlatformTileOverlay({ + required this.tileOverlayId, + required this.fadeIn, + required this.transparency, + required this.zIndex, + required this.visible, + required this.tileSize, + }); + + final String tileOverlayId; + final bool fadeIn; + final double transparency; + final int zIndex; + final bool visible; + final int tileSize; +} + +/// Pigeon equivalent of Flutter's EdgeInsets. +class PlatformEdgeInsets { + PlatformEdgeInsets({ + required this.top, + required this.bottom, + required this.left, + required this.right, + }); + + final double top; + final double bottom; + final double left; + final double right; +} + /// Pigeon equivalent of LatLng. class PlatformLatLng { PlatformLatLng({required this.latitude, required this.longitude}); @@ -39,10 +382,89 @@ class PlatformCluster { final String clusterManagerId; final PlatformLatLng position; final PlatformLatLngBounds bounds; - // TODO(stuartmorgan): Make the generic type non-nullable once supported. - // https://github.com/flutter/flutter/issues/97848 - // The consuming code treats the entries as non-nullable. - final List markerIds; + final List markerIds; +} + +/// Pigeon equivalent of CameraTargetBounds. +/// +/// As with the Dart version, it exists to distinguish between not setting a +/// a target, and having an explicitly unbounded target (null [bounds]). +class PlatformCameraTargetBounds { + PlatformCameraTargetBounds({required this.bounds}); + + final PlatformLatLngBounds? bounds; +} + +/// Information passed to the platform view creation. +class PlatformMapViewCreationParams { + PlatformMapViewCreationParams({ + required this.initialCameraPosition, + required this.mapConfiguration, + required this.initialCircles, + required this.initialMarkers, + required this.initialPolygons, + required this.initialPolylines, + required this.initialHeatmaps, + required this.initialTileOverlays, + required this.initialClusterManagers, + }); + + final PlatformCameraPosition initialCameraPosition; + final PlatformMapConfiguration mapConfiguration; + final List initialCircles; + final List initialMarkers; + final List initialPolygons; + final List initialPolylines; + final List initialHeatmaps; + final List initialTileOverlays; + final List initialClusterManagers; +} + +/// Pigeon equivalent of MapConfiguration. +class PlatformMapConfiguration { + PlatformMapConfiguration({ + required this.compassEnabled, + required this.cameraTargetBounds, + required this.mapType, + required this.minMaxZoomPreference, + required this.mapToolbarEnabled, + required this.rotateGesturesEnabled, + required this.scrollGesturesEnabled, + required this.tiltGesturesEnabled, + required this.trackCameraPosition, + required this.zoomControlsEnabled, + required this.zoomGesturesEnabled, + required this.myLocationEnabled, + required this.myLocationButtonEnabled, + required this.padding, + required this.indoorViewEnabled, + required this.trafficEnabled, + required this.buildingsEnabled, + required this.liteModeEnabled, + required this.cloudMapId, + required this.style, + }); + + final bool? compassEnabled; + final PlatformCameraTargetBounds? cameraTargetBounds; + final PlatformMapType? mapType; + final PlatformZoomRange? minMaxZoomPreference; + final bool? mapToolbarEnabled; + final bool? rotateGesturesEnabled; + final bool? scrollGesturesEnabled; + final bool? tiltGesturesEnabled; + final bool? trackCameraPosition; + final bool? zoomControlsEnabled; + final bool? zoomGesturesEnabled; + final bool? myLocationEnabled; + final bool? myLocationButtonEnabled; + final PlatformEdgeInsets? padding; + final bool? indoorViewEnabled; + final bool? trafficEnabled; + final bool? buildingsEnabled; + final bool? liteModeEnabled; + final String? cloudMapId; + final String? style; } /// Pigeon representation of an x,y coordinate. @@ -72,8 +494,98 @@ class PlatformTileLayer { class PlatformZoomRange { PlatformZoomRange({required this.min, required this.max}); - final double min; - final double max; + final double? min; + final double? max; +} + +/// Pigeon equivalent of [BitmapDescriptor]. As there are multiple disjoint +/// types of [BitmapDescriptor], [PlatformBitmap] contains a single field which +/// may hold the pigeon equivalent type of any of them. +class PlatformBitmap { + PlatformBitmap({required this.bitmap}); + + /// One of [PlatformBitmapAssetMap], [PlatformBitmapAsset], + /// [PlatformBitmapAssetImage], [PlatformBitmapBytesMap], + /// [PlatformBitmapBytes], or [PlatformBitmapDefaultMarker]. + /// As Pigeon does not currently support data class inheritance, this + /// approach allows for the different bitmap implementations to be valid + /// argument and return types of the API methods. See + /// https://github.com/flutter/flutter/issues/117819. + final Object bitmap; +} + +/// Pigeon equivalent of [DefaultMarker]. See +/// https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/BitmapDescriptorFactory#defaultMarker(float) +class PlatformBitmapDefaultMarker { + PlatformBitmapDefaultMarker({this.hue}); + + final double? hue; +} + +/// Pigeon equivalent of [BytesBitmap]. See +/// https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/BitmapDescriptorFactory#fromBitmap(android.graphics.Bitmap) +class PlatformBitmapBytes { + PlatformBitmapBytes({required this.byteData, this.size}); + + final Uint8List byteData; + final PlatformDoublePair? size; +} + +/// Pigeon equivalent of [AssetBitmap]. See +/// https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/BitmapDescriptorFactory#public-static-bitmapdescriptor-fromasset-string-assetname +class PlatformBitmapAsset { + PlatformBitmapAsset({required this.name, this.pkg}); + + final String name; + final String? pkg; +} + +/// Pigeon equivalent of [AssetImageBitmap]. See +/// https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/BitmapDescriptorFactory#public-static-bitmapdescriptor-fromasset-string-assetname +class PlatformBitmapAssetImage { + PlatformBitmapAssetImage( + {required this.name, required this.scale, this.size}); + final String name; + final double scale; + final PlatformDoublePair? size; +} + +/// Pigeon equivalent of [MapBitmapScaling]. +enum PlatformMapBitmapScaling { + auto, + none, +} + +/// Pigeon equivalent of [AssetMapBitmap]. See +/// https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/BitmapDescriptorFactory#public-static-bitmapdescriptor-fromasset-string-assetname +class PlatformBitmapAssetMap { + PlatformBitmapAssetMap( + {required this.assetName, + required this.bitmapScaling, + required this.imagePixelRatio, + this.width, + this.height}); + final String assetName; + final PlatformMapBitmapScaling bitmapScaling; + final double imagePixelRatio; + final double? width; + final double? height; +} + +/// Pigeon equivalent of [BytesMapBitmap]. See +/// https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/BitmapDescriptorFactory#public-static-bitmapdescriptor-frombitmap-bitmap-image +class PlatformBitmapBytesMap { + PlatformBitmapBytesMap( + {required this.byteData, + required this.bitmapScaling, + required this.imagePixelRatio, + this.width, + this.height}); + final Uint8List byteData; + final PlatformMapBitmapScaling bitmapScaling; + final double imagePixelRatio; + final double? width; + final double? height; } /// Interface for non-test interactions with the native SDK. @@ -85,6 +597,40 @@ abstract class MapsApi { @async void waitForMap(); + /// Updates the map's configuration options. + /// + /// Only non-null configuration values will result in updates; options with + /// null values will remain unchanged. + void updateMapConfiguration(PlatformMapConfiguration configuration); + + /// Updates the set of circles on the map. + void updateCircles(List toAdd, List toChange, + List idsToRemove); + + /// Updates the set of heatmaps on the map. + void updateHeatmaps(List toAdd, + List toChange, List idsToRemove); + + /// Updates the set of custer managers for clusters on the map. + void updateClusterManagers( + List toAdd, List idsToRemove); + + /// Updates the set of markers on the map. + void updateMarkers(List toAdd, List toChange, + List idsToRemove); + + /// Updates the set of polygonss on the map. + void updatePolygons(List toAdd, + List toChange, List idsToRemove); + + /// Updates the set of polylines on the map. + void updatePolylines(List toAdd, + List toChange, List idsToRemove); + + /// Updates the set of tile overlays on the map. + void updateTileOverlays(List toAdd, + List toChange, List idsToRemove); + /// Gets the screen coordinate for the given map location. PlatformPoint getScreenCoordinate(PlatformLatLng latLng); @@ -94,6 +640,13 @@ abstract class MapsApi { /// Gets the map region currently displayed on the map. PlatformLatLngBounds getVisibleRegion(); + /// Moves the camera according to [cameraUpdate] immediately, with no + /// animation. + void moveCamera(PlatformCameraUpdate cameraUpdate); + + /// Moves the camera according to [cameraUpdate], animating the update. + void animateCamera(PlatformCameraUpdate cameraUpdate); + /// Gets the current map zoom level. double getZoomLevel(); @@ -129,6 +682,79 @@ abstract class MapsApi { Uint8List takeSnapshot(); } +@FlutterApi() +abstract class MapsCallbackApi { + /// Called when the map camera starts moving. + void onCameraMoveStarted(); + + /// Called when the map camera moves. + void onCameraMove(PlatformCameraPosition cameraPosition); + + /// Called when the map camera stops moving. + void onCameraIdle(); + + /// Called when the map, not a specifc map object, is tapped. + void onTap(PlatformLatLng position); + + /// Called when the map, not a specifc map object, is long pressed. + void onLongPress(PlatformLatLng position); + + /// Called when a marker is tapped. + void onMarkerTap(String markerId); + + /// Called when a marker drag starts. + void onMarkerDragStart(String markerId, PlatformLatLng position); + + /// Called when a marker drag updates. + void onMarkerDrag(String markerId, PlatformLatLng position); + + /// Called when a marker drag ends. + void onMarkerDragEnd(String markerId, PlatformLatLng position); + + /// Called when a marker's info window is tapped. + void onInfoWindowTap(String markerId); + + /// Called when a circle is tapped. + void onCircleTap(String circleId); + + /// Called when a marker cluster is tapped. + void onClusterTap(PlatformCluster cluster); + + /// Called when a polygon is tapped. + void onPolygonTap(String polygonId); + + /// Called when a polyline is tapped. + void onPolylineTap(String polylineId); + + /// Called to get data for a map tile. + @async + PlatformTile getTileOverlayTile( + String tileOverlayId, PlatformPoint location, int zoom); +} + +/// Interface for global SDK initialization. +@HostApi() +abstract class MapsInitializerApi { + /// Initializes the Google Maps SDK with the given renderer preference. + /// + /// A null renderer preference will result in the default renderer. + /// + /// Calling this more than once in the lifetime of an application will result + /// in an error. + @async + PlatformRendererType initializeWithPreferredRenderer( + PlatformRendererType? type); +} + +/// Dummy interface to force generation of the platform view creation params, +/// which are not used in any Pigeon calls, only the platform view creation +/// call made internally by Flutter. +@HostApi() +abstract class MapsPlatformViewApi { + // This is never actually called. + void createView(PlatformMapViewCreationParams? type); +} + /// Inspector API only intended for use in integration tests. @HostApi() abstract class MapsInspectorApi { @@ -145,8 +771,5 @@ abstract class MapsInspectorApi { bool isTrafficEnabled(); PlatformTileLayer? getTileOverlayInfo(String tileOverlayId); PlatformZoomRange getZoomRange(); - // TODO(stuartmorgan): Make the generic type non-nullable once supported. - // https://github.com/flutter/flutter/issues/97848 - // The consuming code treats the entries as non-nullable. - List getClusters(String clusterManagerId); + List getClusters(String clusterManagerId); } diff --git a/packages/google_maps_flutter/google_maps_flutter_android/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_android/pubspec.yaml index 087914e6b3e5..19c0751c5db5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_android/pubspec.yaml @@ -2,11 +2,11 @@ name: google_maps_flutter_android description: Android implementation of the google_maps_flutter plugin. repository: https://github.com/flutter/packages/tree/main/packages/google_maps_flutter/google_maps_flutter_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22 -version: 2.10.0 +version: 2.14.11 environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" flutter: plugin: @@ -21,7 +21,7 @@ dependencies: flutter: sdk: flutter flutter_plugin_android_lifecycle: ^2.0.1 - google_maps_flutter_platform_interface: ^2.7.0 + google_maps_flutter_platform_interface: ^2.9.5 stream_transform: ^2.0.0 dev_dependencies: @@ -29,8 +29,8 @@ dev_dependencies: build_runner: ^2.3.3 flutter_test: sdk: flutter - mockito: 5.4.4 - pigeon: ^20.0.1 + mockito: ^5.4.4 + pigeon: ^22.6.0 plugin_platform_interface: ^2.1.7 topics: diff --git a/packages/google_maps_flutter/google_maps_flutter_android/test/cluster_manager_utils_test.dart b/packages/google_maps_flutter/google_maps_flutter_android/test/cluster_manager_utils_test.dart deleted file mode 100644 index 56963ddbdd91..000000000000 --- a/packages/google_maps_flutter/google_maps_flutter_android/test/cluster_manager_utils_test.dart +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -import 'package:flutter_test/flutter_test.dart'; -import 'package:google_maps_flutter_android/src/utils/cluster_manager_utils.dart'; -import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; - -void main() { - test('serializeClusterManagerUpdates', () async { - const ClusterManagerId clusterManagerId1 = ClusterManagerId('cm1'); - const ClusterManagerId clusterManagerId2 = ClusterManagerId('cm2'); - - const ClusterManager clusterManager1 = ClusterManager( - clusterManagerId: clusterManagerId1, - ); - const ClusterManager clusterManager2 = ClusterManager( - clusterManagerId: clusterManagerId2, - ); - - final Set clusterManagersSet1 = {}; - final Set clusterManagersSet2 = { - clusterManager1, - clusterManager2 - }; - final Set clusterManagersSet3 = { - clusterManager1 - }; - - final ClusterManagerUpdates clusterManagerUpdates1 = - ClusterManagerUpdates.from(clusterManagersSet1, clusterManagersSet2); - final Map serializedData1 = - serializeClusterManagerUpdates(clusterManagerUpdates1) - as Map; - expect(serializedData1['clusterManagersToAdd'], isNotNull); - final List clusterManagersToAdd1 = - serializedData1['clusterManagersToAdd']! as List; - expect(clusterManagersToAdd1.length, 2); - expect(serializedData1['clusterManagerIdsToRemove'], isNotNull); - final List clusterManagersToRemove1 = - serializedData1['clusterManagerIdsToRemove']! as List; - expect(clusterManagersToRemove1.length, 0); - - final ClusterManagerUpdates clusterManagerUpdates2 = - ClusterManagerUpdates.from(clusterManagersSet2, clusterManagersSet3); - serializeClusterManagerUpdates(clusterManagerUpdates2); - final Map serializedData2 = - serializeClusterManagerUpdates(clusterManagerUpdates2) - as Map; - expect(serializedData2['clusterManagersToAdd'], isNotNull); - final List clusterManagersToAdd2 = - serializedData2['clusterManagersToAdd']! as List; - expect(clusterManagersToAdd2.length, 0); - expect(serializedData1['clusterManagerIdsToRemove'], isNotNull); - final List clusterManagersToRemove2 = - serializedData2['clusterManagerIdsToRemove']! as List; - expect(clusterManagersToRemove2.length, 1); - expect(clusterManagersToRemove2.first as String, equals('cm2')); - }); -} diff --git a/packages/google_maps_flutter/google_maps_flutter_android/test/google_maps_flutter_android_test.dart b/packages/google_maps_flutter/google_maps_flutter_android/test/google_maps_flutter_android_test.dart index 109b9411a32e..7104d01e163d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/test/google_maps_flutter_android_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/test/google_maps_flutter_android_test.dart @@ -27,15 +27,6 @@ void main() { return (maps, api); } - Future sendPlatformMessage( - int mapId, String method, Map data) async { - final ByteData byteData = - const StandardMethodCodec().encodeMethodCall(MethodCall(method, data)); - await TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .handlePlatformMessage('plugins.flutter.dev/google_maps_android_$mapId', - byteData, (ByteData? data) {}); - } - test('registers instance', () async { GoogleMapsFlutterAndroid.registerWith(); expect(GoogleMapsFlutterPlatform.instance, isA()); @@ -113,6 +104,43 @@ void main() { expect(bounds, expectedBounds); }); + test('moveCamera calls through with expected scrollBy', () async { + const int mapId = 1; + final (GoogleMapsFlutterAndroid maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + final CameraUpdate update = CameraUpdate.scrollBy(10, 20); + await maps.moveCamera(update, mapId: mapId); + + final VerificationResult verification = verify(api.moveCamera(captureAny)); + final PlatformCameraUpdate passedUpdate = + verification.captured[0] as PlatformCameraUpdate; + final PlatformCameraUpdateScrollBy scroll = + passedUpdate.cameraUpdate as PlatformCameraUpdateScrollBy; + update as CameraUpdateScrollBy; + expect(scroll.dx, update.dx); + expect(scroll.dy, update.dy); + }); + + test('animateCamera calls through with expected scrollBy', () async { + const int mapId = 1; + final (GoogleMapsFlutterAndroid maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + final CameraUpdate update = CameraUpdate.scrollBy(10, 20); + await maps.animateCamera(update, mapId: mapId); + + final VerificationResult verification = + verify(api.animateCamera(captureAny)); + final PlatformCameraUpdate passedUpdate = + verification.captured[0] as PlatformCameraUpdate; + final PlatformCameraUpdateScrollBy scroll = + passedUpdate.cameraUpdate as PlatformCameraUpdateScrollBy; + update as CameraUpdateScrollBy; + expect(scroll.dx, update.dx); + expect(scroll.dy, update.dy); + }); + test('getZoomLevel passes values correctly', () async { const int mapId = 1; final (GoogleMapsFlutterAndroid maps, MockMapsApi api) = @@ -183,26 +211,467 @@ void main() { verify(api.clearTileCache(tileOverlayId)); }); - test('markers send drag event to correct streams', () async { + test('updateMapConfiguration passes expected arguments', () async { const int mapId = 1; - final Map jsonMarkerDragStartEvent = { - 'mapId': mapId, - 'markerId': 'drag-start-marker', - 'position': [1.0, 1.0] - }; - final Map jsonMarkerDragEvent = { - 'mapId': mapId, - 'markerId': 'drag-marker', - 'position': [1.0, 1.0] - }; - final Map jsonMarkerDragEndEvent = { - 'mapId': mapId, - 'markerId': 'drag-end-marker', - 'position': [1.0, 1.0] + final (GoogleMapsFlutterAndroid maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + // Set some arbitrary options. + final CameraTargetBounds cameraBounds = CameraTargetBounds(LatLngBounds( + southwest: const LatLng(10, 20), northeast: const LatLng(30, 40))); + final MapConfiguration config = MapConfiguration( + compassEnabled: true, + mapType: MapType.terrain, + cameraTargetBounds: cameraBounds, + ); + await maps.updateMapConfiguration(config, mapId: mapId); + + final VerificationResult verification = + verify(api.updateMapConfiguration(captureAny)); + final PlatformMapConfiguration passedConfig = + verification.captured[0] as PlatformMapConfiguration; + // Each set option should be present. + expect(passedConfig.compassEnabled, true); + expect(passedConfig.mapType, PlatformMapType.terrain); + expect(passedConfig.cameraTargetBounds?.bounds?.northeast.latitude, + cameraBounds.bounds?.northeast.latitude); + expect(passedConfig.cameraTargetBounds?.bounds?.northeast.longitude, + cameraBounds.bounds?.northeast.longitude); + expect(passedConfig.cameraTargetBounds?.bounds?.southwest.latitude, + cameraBounds.bounds?.southwest.latitude); + expect(passedConfig.cameraTargetBounds?.bounds?.southwest.longitude, + cameraBounds.bounds?.southwest.longitude); + // Spot-check that unset options are not be present. + expect(passedConfig.myLocationEnabled, isNull); + expect(passedConfig.minMaxZoomPreference, isNull); + expect(passedConfig.padding, isNull); + }); + + test('updateMapOptions passes expected arguments', () async { + const int mapId = 1; + final (GoogleMapsFlutterAndroid maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + // Set some arbitrary options. + final CameraTargetBounds cameraBounds = CameraTargetBounds(LatLngBounds( + southwest: const LatLng(10, 20), northeast: const LatLng(30, 40))); + final Map config = { + 'compassEnabled': true, + 'mapType': MapType.terrain.index, + 'cameraTargetBounds': cameraBounds.toJson(), }; + await maps.updateMapOptions(config, mapId: mapId); + + final VerificationResult verification = + verify(api.updateMapConfiguration(captureAny)); + final PlatformMapConfiguration passedConfig = + verification.captured[0] as PlatformMapConfiguration; + // Each set option should be present. + expect(passedConfig.compassEnabled, true); + expect(passedConfig.mapType, PlatformMapType.terrain); + expect(passedConfig.cameraTargetBounds?.bounds?.northeast.latitude, + cameraBounds.bounds?.northeast.latitude); + expect(passedConfig.cameraTargetBounds?.bounds?.northeast.longitude, + cameraBounds.bounds?.northeast.longitude); + expect(passedConfig.cameraTargetBounds?.bounds?.southwest.latitude, + cameraBounds.bounds?.southwest.latitude); + expect(passedConfig.cameraTargetBounds?.bounds?.southwest.longitude, + cameraBounds.bounds?.southwest.longitude); + // Spot-check that unset options are not be present. + expect(passedConfig.myLocationEnabled, isNull); + expect(passedConfig.minMaxZoomPreference, isNull); + expect(passedConfig.padding, isNull); + }); + + test('updateCircles passes expected arguments', () async { + const int mapId = 1; + final (GoogleMapsFlutterAndroid maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + const Circle object1 = Circle(circleId: CircleId('1')); + const Circle object2old = Circle(circleId: CircleId('2')); + final Circle object2new = object2old.copyWith(radiusParam: 42); + const Circle object3 = Circle(circleId: CircleId('3')); + await maps.updateCircles( + CircleUpdates.from( + {object1, object2old}, {object2new, object3}), + mapId: mapId); + + final VerificationResult verification = + verify(api.updateCircles(captureAny, captureAny, captureAny)); + final List toAdd = + verification.captured[0] as List; + final List toChange = + verification.captured[1] as List; + final List toRemove = verification.captured[2] as List; + // Object one should be removed. + expect(toRemove.length, 1); + expect(toRemove.first, object1.circleId.value); + // Object two should be changed. + { + expect(toChange.length, 1); + final List? encoded = toChange.first.encode() as List?; + expect(encoded?.getRange(0, 6), [ + object2new.consumeTapEvents, + object2new.fillColor.value, + object2new.strokeColor.value, + object2new.visible, + object2new.strokeWidth, + object2new.zIndex.toDouble(), + ]); + final PlatformLatLng? latLng = encoded?[6] as PlatformLatLng?; + expect(latLng?.latitude, object2new.center.latitude); + expect(latLng?.longitude, object2new.center.longitude); + expect(encoded?.getRange(7, 9), [ + object2new.radius, + object2new.circleId.value, + ]); + } + // Object 3 should be added. + expect(toAdd.length, 1); + { + expect(toAdd.length, 1); + final List? encoded = toAdd.first.encode() as List?; + expect(encoded?.getRange(0, 6), [ + object3.consumeTapEvents, + object3.fillColor.value, + object3.strokeColor.value, + object3.visible, + object3.strokeWidth, + object3.zIndex.toDouble(), + ]); + final PlatformLatLng? latLng = encoded?[6] as PlatformLatLng?; + expect(latLng?.latitude, object3.center.latitude); + expect(latLng?.longitude, object3.center.longitude); + expect(encoded?.getRange(7, 9), [ + object3.radius, + object3.circleId.value, + ]); + } + }); + + test('updateClusterManagers passes expected arguments', () async { + const int mapId = 1; + final (GoogleMapsFlutterAndroid maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + const ClusterManager object1 = + ClusterManager(clusterManagerId: ClusterManagerId('1')); + const ClusterManager object3 = + ClusterManager(clusterManagerId: ClusterManagerId('3')); + await maps.updateClusterManagers( + ClusterManagerUpdates.from( + {object1}, {object3}), + mapId: mapId); + + final VerificationResult verification = + verify(api.updateClusterManagers(captureAny, captureAny)); + final List toAdd = + verification.captured[0] as List; + final List toRemove = verification.captured[1] as List; + // Object one should be removed. + expect(toRemove.length, 1); + expect(toRemove.first, object1.clusterManagerId.value); + // Unlike other map object types, changes are not possible for cluster + // managers, since they have no non-ID properties. + // Object 3 should be added. + expect(toAdd.length, 1); + expect(toAdd.first.identifier, object3.clusterManagerId.value); + }); + + test('updateMarkers passes expected arguments', () async { + const int mapId = 1; + final (GoogleMapsFlutterAndroid maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + const Marker object1 = Marker(markerId: MarkerId('1')); + const Marker object2old = Marker(markerId: MarkerId('2')); + final Marker object2new = object2old.copyWith(rotationParam: 42); + const Marker object3 = Marker(markerId: MarkerId('3')); + await maps.updateMarkers( + MarkerUpdates.from( + {object1, object2old}, {object2new, object3}), + mapId: mapId); + + final VerificationResult verification = + verify(api.updateMarkers(captureAny, captureAny, captureAny)); + final List toAdd = + verification.captured[0] as List; + final List toChange = + verification.captured[1] as List; + final List toRemove = verification.captured[2] as List; + // Object one should be removed. + expect(toRemove.length, 1); + expect(toRemove.first, object1.markerId.value); + // Object two should be changed. + { + expect(toChange.length, 1); + final List? encoded = toChange.first.encode() as List?; + expect(encoded?[0], object2new.alpha); + final PlatformDoublePair? offset = encoded?[1] as PlatformDoublePair?; + expect(offset?.x, object2new.anchor.dx); + expect(offset?.y, object2new.anchor.dy); + expect(encoded?.getRange(2, 5).toList(), [ + object2new.consumeTapEvents, + object2new.draggable, + object2new.flat, + ]); + expect( + (encoded?[5] as PlatformBitmap?)?.bitmap.runtimeType, + GoogleMapsFlutterAndroid.platformBitmapFromBitmapDescriptor( + object2new.icon) + .bitmap + .runtimeType); + final PlatformInfoWindow? window = encoded?[6] as PlatformInfoWindow?; + expect(window?.title, object2new.infoWindow.title); + expect(window?.snippet, object2new.infoWindow.snippet); + expect(window?.anchor.x, object2new.infoWindow.anchor.dx); + expect(window?.anchor.y, object2new.infoWindow.anchor.dy); + final PlatformLatLng? latLng = encoded?[7] as PlatformLatLng?; + expect(latLng?.latitude, object2new.position.latitude); + expect(latLng?.longitude, object2new.position.longitude); + expect(encoded?.getRange(8, 13), [ + object2new.rotation, + object2new.visible, + object2new.zIndex, + object2new.markerId.value, + object2new.clusterManagerId?.value, + ]); + } + // Object 3 should be added. + { + expect(toAdd.length, 1); + final List? encoded = toAdd.first.encode() as List?; + expect(encoded?[0], object3.alpha); + final PlatformDoublePair? offset = encoded?[1] as PlatformDoublePair?; + expect(offset?.x, object3.anchor.dx); + expect(offset?.y, object3.anchor.dy); + expect(encoded?.getRange(2, 5).toList(), [ + object3.consumeTapEvents, + object3.draggable, + object3.flat, + ]); + expect( + (encoded?[5] as PlatformBitmap?)?.bitmap.runtimeType, + GoogleMapsFlutterAndroid.platformBitmapFromBitmapDescriptor( + object3.icon) + .bitmap + .runtimeType); + final PlatformInfoWindow? window = encoded?[6] as PlatformInfoWindow?; + expect(window?.title, object3.infoWindow.title); + expect(window?.snippet, object3.infoWindow.snippet); + expect(window?.anchor.x, object3.infoWindow.anchor.dx); + expect(window?.anchor.y, object3.infoWindow.anchor.dy); + final PlatformLatLng? latLng = encoded?[7] as PlatformLatLng?; + expect(latLng?.latitude, object3.position.latitude); + expect(latLng?.longitude, object3.position.longitude); + expect(encoded?.getRange(8, 13), [ + object3.rotation, + object3.visible, + object3.zIndex, + object3.markerId.value, + object3.clusterManagerId?.value, + ]); + } + }); + + test('updatePolygons passes expected arguments', () async { + const int mapId = 1; + final (GoogleMapsFlutterAndroid maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + const Polygon object1 = Polygon(polygonId: PolygonId('1')); + const Polygon object2old = Polygon(polygonId: PolygonId('2')); + final Polygon object2new = object2old.copyWith(strokeWidthParam: 42); + const Polygon object3 = Polygon(polygonId: PolygonId('3')); + await maps.updatePolygons( + PolygonUpdates.from( + {object1, object2old}, {object2new, object3}), + mapId: mapId); + + final VerificationResult verification = + verify(api.updatePolygons(captureAny, captureAny, captureAny)); + final List toAdd = + verification.captured[0] as List; + final List toChange = + verification.captured[1] as List; + final List toRemove = verification.captured[2] as List; + // Object one should be removed. + expect(toRemove.length, 1); + expect(toRemove.first, object1.polygonId.value); + void expectPolygon(PlatformPolygon actual, Polygon expected) { + final List encoded = actual.encode() as List; + expect(encoded.sublist(0, 4), [ + expected.polygonId.value, + expected.consumeTapEvents, + expected.fillColor.value, + expected.geodesic, + ]); + expect(actual.points.length, expected.points.length); + for (final (int i, PlatformLatLng? point) in actual.points.indexed) { + expect(point?.latitude, actual.points[i].latitude); + expect(point?.longitude, actual.points[i].longitude); + } + expect(actual.holes.length, expected.holes.length); + for (final (int i, List? hole) in actual.holes.indexed) { + final List expectedHole = expected.holes[i]; + for (final (int j, PlatformLatLng? point) in hole!.indexed) { + expect(point?.latitude, expectedHole[j].latitude); + expect(point?.longitude, expectedHole[j].longitude); + } + } + expect(encoded.sublist(6), [ + expected.visible, + expected.strokeColor.value, + expected.strokeWidth, + expected.zIndex, + ]); + } + + // Object two should be changed. + expect(toChange.length, 1); + expectPolygon(toChange.first, object2new); + // Object 3 should be added. + expect(toAdd.length, 1); + expectPolygon(toAdd.first, object3); + }); + + test('updatePolylines passes expected arguments', () async { + const int mapId = 1; + final (GoogleMapsFlutterAndroid maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + const Polyline object1 = Polyline(polylineId: PolylineId('1')); + const Polyline object2old = Polyline(polylineId: PolylineId('2')); + final Polyline object2new = object2old.copyWith( + widthParam: 42, startCapParam: Cap.squareCap, endCapParam: Cap.buttCap); + final Cap customCap = + Cap.customCapFromBitmap(BitmapDescriptor.defaultMarker, refWidth: 15); + final Polyline object3 = Polyline( + polylineId: const PolylineId('3'), + startCap: customCap, + endCap: Cap.roundCap); + await maps.updatePolylines( + PolylineUpdates.from( + {object1, object2old}, {object2new, object3}), + mapId: mapId); + + final VerificationResult verification = + verify(api.updatePolylines(captureAny, captureAny, captureAny)); + final List toAdd = + verification.captured[0] as List; + final List toChange = + verification.captured[1] as List; + final List toRemove = verification.captured[2] as List; + void expectPolyline(PlatformPolyline actual, Polyline expected) { + final List encoded = actual.encode() as List; + expect(encoded.sublist(0, 5), [ + expected.polylineId.value, + expected.consumeTapEvents, + expected.color.value, + expected.geodesic, + platformJointTypeFromJointType(expected.jointType), + ]); + expect(encoded.sublist(9), [ + expected.visible, + expected.width, + expected.zIndex, + ]); + expect(actual.points.length, expected.points.length); + for (final (int i, PlatformLatLng? point) in actual.points.indexed) { + expect(point?.latitude, actual.points[i].latitude); + expect(point?.longitude, actual.points[i].longitude); + } + expect(actual.patterns.length, expected.patterns.length); + for (final (int i, PlatformPatternItem? pattern) + in actual.patterns.indexed) { + expect(pattern?.encode(), + platformPatternItemFromPatternItem(expected.patterns[i]).encode()); + } + final PlatformCap expectedStartCap = + GoogleMapsFlutterAndroid.platformCapFromCap(expected.startCap); + final PlatformCap expectedEndCap = + GoogleMapsFlutterAndroid.platformCapFromCap(expected.endCap); + expect(actual.startCap.type, expectedStartCap.type); + expect(actual.startCap.refWidth, expectedStartCap.refWidth); + expect(actual.startCap.bitmapDescriptor?.bitmap.runtimeType, + expectedStartCap.bitmapDescriptor?.bitmap.runtimeType); + expect(actual.endCap.type, expectedEndCap.type); + expect(actual.endCap.refWidth, expectedEndCap.refWidth); + expect(actual.endCap.bitmapDescriptor?.bitmap.runtimeType, + expectedEndCap.bitmapDescriptor?.bitmap.runtimeType); + } + + // Object one should be removed. + expect(toRemove.length, 1); + expect(toRemove.first, object1.polylineId.value); + // Object two should be changed. + expect(toChange.length, 1); + expectPolyline(toChange.first, object2new); + // Object 3 should be added. + expect(toAdd.length, 1); + expectPolyline(toAdd.first, object3); + }); + + test('updateTileOverlays passes expected arguments', () async { + const int mapId = 1; + final (GoogleMapsFlutterAndroid maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + const TileOverlay object1 = TileOverlay(tileOverlayId: TileOverlayId('1')); + const TileOverlay object2old = + TileOverlay(tileOverlayId: TileOverlayId('2')); + final TileOverlay object2new = object2old.copyWith(zIndexParam: 42); + const TileOverlay object3 = TileOverlay(tileOverlayId: TileOverlayId('3')); + // Pre-set the initial state, since this update method doesn't take the old + // state. + await maps.updateTileOverlays( + newTileOverlays: {object1, object2old}, mapId: mapId); + clearInteractions(api); + + await maps.updateTileOverlays( + newTileOverlays: {object2new, object3}, mapId: mapId); + + final VerificationResult verification = + verify(api.updateTileOverlays(captureAny, captureAny, captureAny)); + final List toAdd = + verification.captured[0] as List; + final List toChange = + verification.captured[1] as List; + final List toRemove = verification.captured[2] as List; + void expectTileOverlay(PlatformTileOverlay? actual, TileOverlay expected) { + expect(actual?.encode(), [ + expected.tileOverlayId.value, + expected.fadeIn, + expected.transparency, + expected.zIndex, + expected.visible, + expected.tileSize, + ]); + } + + // Object one should be removed. + expect(toRemove.length, 1); + expect(toRemove.first, object1.tileOverlayId.value); + // Object two should be changed. + expect(toChange.length, 1); + expectTileOverlay(toChange.first, object2new); + // Object 3 should be added. + expect(toAdd.length, 1); + expectTileOverlay(toAdd.first, object3); + }); + + test('markers send drag event to correct streams', () async { + const int mapId = 1; + const String dragStartId = 'drag-start-marker'; + const String dragId = 'drag-marker'; + const String dragEndId = 'drag-end-marker'; + final PlatformLatLng fakePosition = + PlatformLatLng(latitude: 1.0, longitude: 1.0); final GoogleMapsFlutterAndroid maps = GoogleMapsFlutterAndroid(); - maps.ensureChannelInitialized(mapId); + final HostMapMessageHandler callbackHandler = + maps.ensureHandlerInitialized(mapId); final StreamQueue markerDragStartStream = StreamQueue(maps.onMarkerDragStart(mapId: mapId)); @@ -211,17 +680,121 @@ void main() { final StreamQueue markerDragEndStream = StreamQueue(maps.onMarkerDragEnd(mapId: mapId)); - await sendPlatformMessage( - mapId, 'marker#onDragStart', jsonMarkerDragStartEvent); - await sendPlatformMessage(mapId, 'marker#onDrag', jsonMarkerDragEvent); - await sendPlatformMessage( - mapId, 'marker#onDragEnd', jsonMarkerDragEndEvent); + // Simulate messages from the native side. + callbackHandler.onMarkerDragStart(dragStartId, fakePosition); + callbackHandler.onMarkerDrag(dragId, fakePosition); + callbackHandler.onMarkerDragEnd(dragEndId, fakePosition); + + expect((await markerDragStartStream.next).value.value, equals(dragStartId)); + expect((await markerDragStream.next).value.value, equals(dragId)); + expect((await markerDragEndStream.next).value.value, equals(dragEndId)); + }); + + test('markers send tap events to correct stream', () async { + const int mapId = 1; + const String objectId = 'object-id'; + + final GoogleMapsFlutterAndroid maps = GoogleMapsFlutterAndroid(); + final HostMapMessageHandler callbackHandler = + maps.ensureHandlerInitialized(mapId); + + final StreamQueue stream = + StreamQueue(maps.onMarkerTap(mapId: mapId)); + + // Simulate message from the native side. + callbackHandler.onMarkerTap(objectId); + + expect((await stream.next).value.value, equals(objectId)); + }); + + test('circles send tap events to correct stream', () async { + const int mapId = 1; + const String objectId = 'object-id'; + + final GoogleMapsFlutterAndroid maps = GoogleMapsFlutterAndroid(); + final HostMapMessageHandler callbackHandler = + maps.ensureHandlerInitialized(mapId); + + final StreamQueue stream = + StreamQueue(maps.onCircleTap(mapId: mapId)); + + // Simulate message from the native side. + callbackHandler.onCircleTap(objectId); + + expect((await stream.next).value.value, equals(objectId)); + }); + + test('clusters send tap events to correct stream', () async { + const int mapId = 1; + const String managerId = 'manager-id'; + final PlatformLatLng fakePosition = + PlatformLatLng(latitude: 10, longitude: 20); + final PlatformLatLngBounds fakeBounds = PlatformLatLngBounds( + southwest: PlatformLatLng(latitude: 30, longitude: 40), + northeast: PlatformLatLng(latitude: 50, longitude: 60)); + const List markerIds = ['marker-1', 'marker-2']; + final PlatformCluster cluster = PlatformCluster( + clusterManagerId: managerId, + position: fakePosition, + bounds: fakeBounds, + markerIds: markerIds); + + final GoogleMapsFlutterAndroid maps = GoogleMapsFlutterAndroid(); + final HostMapMessageHandler callbackHandler = + maps.ensureHandlerInitialized(mapId); + + final StreamQueue stream = + StreamQueue(maps.onClusterTap(mapId: mapId)); - expect((await markerDragStartStream.next).value.value, - equals('drag-start-marker')); - expect((await markerDragStream.next).value.value, equals('drag-marker')); - expect((await markerDragEndStream.next).value.value, - equals('drag-end-marker')); + // Simulate message from the native side. + callbackHandler.onClusterTap(cluster); + + final Cluster eventValue = (await stream.next).value; + expect(eventValue.clusterManagerId.value, managerId); + expect(eventValue.position.latitude, fakePosition.latitude); + expect(eventValue.position.longitude, fakePosition.longitude); + expect(eventValue.bounds.southwest.latitude, fakeBounds.southwest.latitude); + expect( + eventValue.bounds.southwest.longitude, fakeBounds.southwest.longitude); + expect(eventValue.bounds.northeast.latitude, fakeBounds.northeast.latitude); + expect( + eventValue.bounds.northeast.longitude, fakeBounds.northeast.longitude); + expect(eventValue.markerIds.length, markerIds.length); + expect(eventValue.markerIds.first.value, markerIds.first); + }); + + test('polygons send tap events to correct stream', () async { + const int mapId = 1; + const String objectId = 'object-id'; + + final GoogleMapsFlutterAndroid maps = GoogleMapsFlutterAndroid(); + final HostMapMessageHandler callbackHandler = + maps.ensureHandlerInitialized(mapId); + + final StreamQueue stream = + StreamQueue(maps.onPolygonTap(mapId: mapId)); + + // Simulate message from the native side. + callbackHandler.onPolygonTap(objectId); + + expect((await stream.next).value.value, equals(objectId)); + }); + + test('polylines send tap events to correct stream', () async { + const int mapId = 1; + const String objectId = 'object-id'; + + final GoogleMapsFlutterAndroid maps = GoogleMapsFlutterAndroid(); + final HostMapMessageHandler callbackHandler = + maps.ensureHandlerInitialized(mapId); + + final StreamQueue stream = + StreamQueue(maps.onPolylineTap(mapId: mapId)); + + // Simulate message from the native side. + callbackHandler.onPolylineTap(objectId); + + expect((await stream.next).value.value, equals(objectId)); }); test( @@ -239,6 +812,233 @@ void main() { }, ); + test('moveCamera calls through with expected newCameraPosition', () async { + const int mapId = 1; + final (GoogleMapsFlutterAndroid maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + const LatLng latLng = LatLng(10.0, 20.0); + const CameraPosition position = CameraPosition(target: latLng); + final CameraUpdate update = CameraUpdate.newCameraPosition(position); + await maps.moveCamera(update, mapId: mapId); + + final VerificationResult verification = verify(api.moveCamera(captureAny)); + final PlatformCameraUpdate passedUpdate = + verification.captured[0] as PlatformCameraUpdate; + final PlatformCameraUpdateNewCameraPosition typedUpdate = + passedUpdate.cameraUpdate as PlatformCameraUpdateNewCameraPosition; + update as CameraUpdateNewCameraPosition; + expect(typedUpdate.cameraPosition.target.latitude, + update.cameraPosition.target.latitude); + expect(typedUpdate.cameraPosition.target.longitude, + update.cameraPosition.target.longitude); + }); + + test('moveCamera calls through with expected newLatLng', () async { + const int mapId = 1; + final (GoogleMapsFlutterAndroid maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + const LatLng latLng = LatLng(10.0, 20.0); + final CameraUpdate update = CameraUpdate.newLatLng(latLng); + await maps.moveCamera(update, mapId: mapId); + + final VerificationResult verification = verify(api.moveCamera(captureAny)); + final PlatformCameraUpdate passedUpdate = + verification.captured[0] as PlatformCameraUpdate; + final PlatformCameraUpdateNewLatLng typedUpdate = + passedUpdate.cameraUpdate as PlatformCameraUpdateNewLatLng; + update as CameraUpdateNewLatLng; + expect(typedUpdate.latLng.latitude, update.latLng.latitude); + expect(typedUpdate.latLng.longitude, update.latLng.longitude); + }); + + test('moveCamera calls through with expected newLatLngBounds', () async { + const int mapId = 1; + final (GoogleMapsFlutterAndroid maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + final LatLngBounds latLng = LatLngBounds( + northeast: const LatLng(10.0, 20.0), + southwest: const LatLng(9.0, 21.0)); + final CameraUpdate update = CameraUpdate.newLatLngBounds(latLng, 1.0); + await maps.moveCamera(update, mapId: mapId); + + final VerificationResult verification = verify(api.moveCamera(captureAny)); + final PlatformCameraUpdate passedUpdate = + verification.captured[0] as PlatformCameraUpdate; + final PlatformCameraUpdateNewLatLngBounds typedUpdate = + passedUpdate.cameraUpdate as PlatformCameraUpdateNewLatLngBounds; + update as CameraUpdateNewLatLngBounds; + expect(typedUpdate.bounds.northeast.latitude, + update.bounds.northeast.latitude); + expect(typedUpdate.bounds.northeast.longitude, + update.bounds.northeast.longitude); + expect(typedUpdate.bounds.southwest.latitude, + update.bounds.southwest.latitude); + expect(typedUpdate.bounds.southwest.longitude, + update.bounds.southwest.longitude); + expect(typedUpdate.padding, update.padding); + }); + + test('moveCamera calls through with expected newLatLngZoom', () async { + const int mapId = 1; + final (GoogleMapsFlutterAndroid maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + const LatLng latLng = LatLng(10.0, 20.0); + final CameraUpdate update = CameraUpdate.newLatLngZoom(latLng, 2.0); + await maps.moveCamera(update, mapId: mapId); + + final VerificationResult verification = verify(api.moveCamera(captureAny)); + final PlatformCameraUpdate passedUpdate = + verification.captured[0] as PlatformCameraUpdate; + final PlatformCameraUpdateNewLatLngZoom typedUpdate = + passedUpdate.cameraUpdate as PlatformCameraUpdateNewLatLngZoom; + update as CameraUpdateNewLatLngZoom; + expect(typedUpdate.latLng.latitude, update.latLng.latitude); + expect(typedUpdate.latLng.longitude, update.latLng.longitude); + expect(typedUpdate.zoom, update.zoom); + }); + + test('moveCamera calls through with expected zoomBy', () async { + const int mapId = 1; + final (GoogleMapsFlutterAndroid maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + const Offset focus = Offset(10.0, 20.0); + final CameraUpdate update = CameraUpdate.zoomBy(2.0, focus); + await maps.moveCamera(update, mapId: mapId); + + final VerificationResult verification = verify(api.moveCamera(captureAny)); + final PlatformCameraUpdate passedUpdate = + verification.captured[0] as PlatformCameraUpdate; + final PlatformCameraUpdateZoomBy typedUpdate = + passedUpdate.cameraUpdate as PlatformCameraUpdateZoomBy; + update as CameraUpdateZoomBy; + expect(typedUpdate.focus?.x, update.focus?.dx); + expect(typedUpdate.focus?.y, update.focus?.dy); + expect(typedUpdate.amount, update.amount); + }); + + test('moveCamera calls through with expected zoomTo', () async { + const int mapId = 1; + final (GoogleMapsFlutterAndroid maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + final CameraUpdate update = CameraUpdate.zoomTo(2.0); + await maps.moveCamera(update, mapId: mapId); + + final VerificationResult verification = verify(api.moveCamera(captureAny)); + final PlatformCameraUpdate passedUpdate = + verification.captured[0] as PlatformCameraUpdate; + final PlatformCameraUpdateZoomTo typedUpdate = + passedUpdate.cameraUpdate as PlatformCameraUpdateZoomTo; + update as CameraUpdateZoomTo; + expect(typedUpdate.zoom, update.zoom); + }); + + test('moveCamera calls through with expected zoomIn', () async { + const int mapId = 1; + final (GoogleMapsFlutterAndroid maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + final CameraUpdate update = CameraUpdate.zoomIn(); + await maps.moveCamera(update, mapId: mapId); + + final VerificationResult verification = verify(api.moveCamera(captureAny)); + final PlatformCameraUpdate passedUpdate = + verification.captured[0] as PlatformCameraUpdate; + final PlatformCameraUpdateZoom typedUpdate = + passedUpdate.cameraUpdate as PlatformCameraUpdateZoom; + expect(typedUpdate.out, false); + }); + + test('moveCamera calls through with expected zoomOut', () async { + const int mapId = 1; + final (GoogleMapsFlutterAndroid maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + final CameraUpdate update = CameraUpdate.zoomOut(); + await maps.moveCamera(update, mapId: mapId); + + final VerificationResult verification = verify(api.moveCamera(captureAny)); + final PlatformCameraUpdate passedUpdate = + verification.captured[0] as PlatformCameraUpdate; + final PlatformCameraUpdateZoom typedUpdate = + passedUpdate.cameraUpdate as PlatformCameraUpdateZoom; + expect(typedUpdate.out, true); + }); + + test('MapBitmapScaling to PlatformMapBitmapScaling', () { + expect( + GoogleMapsFlutterAndroid.platformMapBitmapScalingFromScaling( + MapBitmapScaling.auto), + PlatformMapBitmapScaling.auto); + expect( + GoogleMapsFlutterAndroid.platformMapBitmapScalingFromScaling( + MapBitmapScaling.none), + PlatformMapBitmapScaling.none); + }); + + test('DefaultMarker bitmap to PlatformBitmap', () { + final BitmapDescriptor bitmap = BitmapDescriptor.defaultMarkerWithHue(10.0); + final PlatformBitmap platformBitmap = + GoogleMapsFlutterAndroid.platformBitmapFromBitmapDescriptor(bitmap); + expect(platformBitmap.bitmap, isA()); + final PlatformBitmapDefaultMarker typedBitmap = + platformBitmap.bitmap as PlatformBitmapDefaultMarker; + expect(typedBitmap.hue, 10.0); + }); + + test('BytesMapBitmap bitmap to PlatformBitmap', () { + final Uint8List data = Uint8List.fromList([1, 2, 3, 4]); + final BytesMapBitmap bitmap = BitmapDescriptor.bytes(data, + imagePixelRatio: 2.0, width: 100.0, height: 200.0); + final PlatformBitmap platformBitmap = + GoogleMapsFlutterAndroid.platformBitmapFromBitmapDescriptor(bitmap); + expect(platformBitmap.bitmap, isA()); + final PlatformBitmapBytesMap typedBitmap = + platformBitmap.bitmap as PlatformBitmapBytesMap; + expect(typedBitmap.byteData, data); + expect(typedBitmap.bitmapScaling, PlatformMapBitmapScaling.auto); + expect(typedBitmap.imagePixelRatio, 2.0); + expect(typedBitmap.width, 100.0); + expect(typedBitmap.height, 200.0); + }); + + test('AssetMapBitmap bitmap to PlatformBitmap', () { + const String assetName = 'fake_asset_name'; + final AssetMapBitmap bitmap = AssetMapBitmap(assetName, + imagePixelRatio: 2.0, width: 100.0, height: 200.0); + final PlatformBitmap platformBitmap = + GoogleMapsFlutterAndroid.platformBitmapFromBitmapDescriptor(bitmap); + expect(platformBitmap.bitmap, isA()); + final PlatformBitmapAssetMap typedBitmap = + platformBitmap.bitmap as PlatformBitmapAssetMap; + expect(typedBitmap.assetName, assetName); + expect(typedBitmap.bitmapScaling, PlatformMapBitmapScaling.auto); + expect(typedBitmap.imagePixelRatio, 2.0); + expect(typedBitmap.width, 100.0); + expect(typedBitmap.height, 200.0); + }); + + test('Cap to PlatformCap', () { + expect(GoogleMapsFlutterAndroid.platformCapFromCap(Cap.buttCap).encode(), + PlatformCap(type: PlatformCapType.buttCap).encode()); + expect(GoogleMapsFlutterAndroid.platformCapFromCap(Cap.roundCap).encode(), + PlatformCap(type: PlatformCapType.roundCap).encode()); + expect(GoogleMapsFlutterAndroid.platformCapFromCap(Cap.squareCap).encode(), + PlatformCap(type: PlatformCapType.squareCap).encode()); + + const BitmapDescriptor bitmap = BitmapDescriptor.defaultMarker; + const CustomCap customCap = CustomCap(bitmap, refWidth: 15.0); + final PlatformCap platformCap = + GoogleMapsFlutterAndroid.platformCapFromCap(customCap); + expect(platformCap.type, PlatformCapType.customCap); + expect(customCap.refWidth, 15.0); + }); + testWidgets('Use PlatformViewLink when using surface view', (WidgetTester tester) async { final GoogleMapsFlutterAndroid maps = GoogleMapsFlutterAndroid(); @@ -278,17 +1078,15 @@ void main() { methodCall.arguments as Map); if (args.containsKey('params')) { final Uint8List paramsUint8List = args['params'] as Uint8List; - const StandardMessageCodec codec = StandardMessageCodec(); final ByteData byteData = ByteData.sublistView(paramsUint8List); - final Map creationParams = - Map.from( - codec.decodeMessage(byteData) as Map); - if (creationParams.containsKey('options')) { - final Map options = Map.from( - creationParams['options'] as Map); - if (options.containsKey('cloudMapId')) { - passedCloudMapIdCompleter - .complete(options['cloudMapId'] as String); + final PlatformMapViewCreationParams? creationParams = + MapsApi.pigeonChannelCodec.decodeMessage(byteData) + as PlatformMapViewCreationParams?; + if (creationParams != null) { + final String? passedMapId = + creationParams.mapConfiguration.cloudMapId; + if (passedMapId != null) { + passedCloudMapIdCompleter.complete(passedMapId); } } } diff --git a/packages/google_maps_flutter/google_maps_flutter_android/test/google_maps_flutter_android_test.mocks.dart b/packages/google_maps_flutter/google_maps_flutter_android/test/google_maps_flutter_android_test.mocks.dart index f819660e2137..e0fbdd574215 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/test/google_maps_flutter_android_test.mocks.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/test/google_maps_flutter_android_test.mocks.dart @@ -68,6 +68,149 @@ class MockMapsApi extends _i1.Mock implements _i2.MapsApi { returnValueForMissingStub: _i3.Future.value(), ) as _i3.Future); + @override + _i3.Future updateMapConfiguration( + _i2.PlatformMapConfiguration? configuration) => + (super.noSuchMethod( + Invocation.method( + #updateMapConfiguration, + [configuration], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future updateCircles( + List<_i2.PlatformCircle?>? toAdd, + List<_i2.PlatformCircle?>? toChange, + List? idsToRemove, + ) => + (super.noSuchMethod( + Invocation.method( + #updateCircles, + [ + toAdd, + toChange, + idsToRemove, + ], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future updateHeatmaps( + List<_i2.PlatformHeatmap?>? toAdd, + List<_i2.PlatformHeatmap?>? toChange, + List? idsToRemove, + ) => + (super.noSuchMethod( + Invocation.method( + #updateHeatmaps, + [ + toAdd, + toChange, + idsToRemove, + ], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future updateClusterManagers( + List<_i2.PlatformClusterManager?>? toAdd, + List? idsToRemove, + ) => + (super.noSuchMethod( + Invocation.method( + #updateClusterManagers, + [ + toAdd, + idsToRemove, + ], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future updateMarkers( + List<_i2.PlatformMarker?>? toAdd, + List<_i2.PlatformMarker?>? toChange, + List? idsToRemove, + ) => + (super.noSuchMethod( + Invocation.method( + #updateMarkers, + [ + toAdd, + toChange, + idsToRemove, + ], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future updatePolygons( + List<_i2.PlatformPolygon?>? toAdd, + List<_i2.PlatformPolygon?>? toChange, + List? idsToRemove, + ) => + (super.noSuchMethod( + Invocation.method( + #updatePolygons, + [ + toAdd, + toChange, + idsToRemove, + ], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future updatePolylines( + List<_i2.PlatformPolyline?>? toAdd, + List<_i2.PlatformPolyline?>? toChange, + List? idsToRemove, + ) => + (super.noSuchMethod( + Invocation.method( + #updatePolylines, + [ + toAdd, + toChange, + idsToRemove, + ], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future updateTileOverlays( + List<_i2.PlatformTileOverlay?>? toAdd, + List<_i2.PlatformTileOverlay?>? toChange, + List? idsToRemove, + ) => + (super.noSuchMethod( + Invocation.method( + #updateTileOverlays, + [ + toAdd, + toChange, + idsToRemove, + ], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + @override _i3.Future<_i2.PlatformPoint> getScreenCoordinate( _i2.PlatformLatLng? latLng) => @@ -143,6 +286,28 @@ class MockMapsApi extends _i1.Mock implements _i2.MapsApi { )), ) as _i3.Future<_i2.PlatformLatLngBounds>); + @override + _i3.Future moveCamera(_i2.PlatformCameraUpdate? cameraUpdate) => + (super.noSuchMethod( + Invocation.method( + #moveCamera, + [cameraUpdate], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future animateCamera(_i2.PlatformCameraUpdate? cameraUpdate) => + (super.noSuchMethod( + Invocation.method( + #animateCamera, + [cameraUpdate], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + @override _i3.Future getZoomLevel() => (super.noSuchMethod( Invocation.method( 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 6fc61e8eefcb..5f962bb978d6 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,36 @@ +## 2.13.1 + +* Updates Pigeon for non-nullable collection type support. + +## 2.13.0 + +* Updates map configuration and platform view creation parameters to use Pigeon. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + +## 2.12.0 + +* Adds support for marker clustering. + +## 2.11.0 + +* Adds support for heatmap layers. + +## 2.10.0 + +* Converts Obj-C->Dart calls to Pigeon. + +## 2.9.0 + +* Converts additional platform calls to Pigeon. + +## 2.8.2 + +* Converts inspector interface platform calls to Pigeon. + +## 2.8.1 + +* Improves Objective-C type handling. + ## 2.8.0 * Adds compatibility with SDK version 9.x for apps targetting iOS 15+. diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/README.md b/packages/google_maps_flutter/google_maps_flutter_ios/README.md index 5594c6f2bfee..20fae87c8855 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/README.md +++ b/packages/google_maps_flutter/google_maps_flutter_ios/README.md @@ -11,5 +11,15 @@ your app when you do, 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. +## Supported Heatmap Options + +| Field | Supported | +| ---------------------------- | :-------: | +| Heatmap.dissipating | x | +| Heatmap.maxIntensity | x | +| Heatmap.minimumZoomIntensity | ✓ | +| Heatmap.maximumZoomIntensity | ✓ | +| HeatmapGradient.colorMapSize | ✓ | + [1]: https://pub.dev/packages/google_maps_flutter -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/integration_test/google_maps_test.dart b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/integration_test/google_maps_test.dart index db8b39567635..d3ea025d99c9 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/integration_test/google_maps_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/integration_test/google_maps_test.dart @@ -1030,6 +1030,85 @@ void main() { }, ); + testWidgets('marker clustering', (WidgetTester tester) async { + final Key key = GlobalKey(); + const int clusterManagersAmount = 2; + const int markersPerClusterManager = 5; + final Map markers = {}; + final Set clusterManagers = {}; + + for (int i = 0; i < clusterManagersAmount; i++) { + final ClusterManagerId clusterManagerId = + ClusterManagerId('cluster_manager_$i'); + final ClusterManager clusterManager = + ClusterManager(clusterManagerId: clusterManagerId); + clusterManagers.add(clusterManager); + } + + for (final ClusterManager cm in clusterManagers) { + for (int i = 0; i < markersPerClusterManager; i++) { + final MarkerId markerId = + MarkerId('${cm.clusterManagerId.value}_marker_$i'); + final Marker marker = Marker( + markerId: markerId, + clusterManagerId: cm.clusterManagerId, + position: LatLng( + _kInitialMapCenter.latitude + i, _kInitialMapCenter.longitude)); + markers[markerId] = marker; + } + } + + final Completer controllerCompleter = + Completer(); + + final GoogleMapsInspectorPlatform inspector = + GoogleMapsInspectorPlatform.instance!; + + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: ExampleGoogleMap( + key: key, + initialCameraPosition: _kInitialCameraPosition, + clusterManagers: clusterManagers, + markers: Set.of(markers.values), + onMapCreated: (ExampleGoogleMapController googleMapController) { + controllerCompleter.complete(googleMapController); + }, + ), + )); + + final ExampleGoogleMapController controller = + await controllerCompleter.future; + + for (final ClusterManager cm in clusterManagers) { + final List clusters = await inspector.getClusters( + mapId: controller.mapId, clusterManagerId: cm.clusterManagerId); + final int markersAmountForClusterManager = clusters + .map((Cluster cluster) => cluster.count) + .reduce((int value, int element) => value + element); + expect(markersAmountForClusterManager, markersPerClusterManager); + } + + // Remove markers from clusterManagers and test that clusterManagers are empty. + for (final MapEntry entry in markers.entries) { + markers[entry.key] = _copyMarkerWithClusterManagerId(entry.value, null); + } + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: ExampleGoogleMap( + key: key, + initialCameraPosition: _kInitialCameraPosition, + clusterManagers: clusterManagers, + markers: Set.of(markers.values)), + )); + + for (final ClusterManager cm in clusterManagers) { + final List clusters = await inspector.getClusters( + mapId: controller.mapId, clusterManagerId: cm.clusterManagerId); + expect(clusters.length, 0); + } + }); + testWidgets('testSetStyleMapId', (WidgetTester tester) async { final Key key = GlobalKey(); @@ -1254,3 +1333,26 @@ class _DebugTileProvider implements TileProvider { return Tile(width, height, byteData); } } + +Marker _copyMarkerWithClusterManagerId( + Marker marker, ClusterManagerId? clusterManagerId) { + return Marker( + markerId: marker.markerId, + alpha: marker.alpha, + anchor: marker.anchor, + consumeTapEvents: marker.consumeTapEvents, + draggable: marker.draggable, + flat: marker.flat, + icon: marker.icon, + infoWindow: marker.infoWindow, + position: marker.position, + rotation: marker.rotation, + visible: marker.visible, + zIndex: marker.zIndex, + onTap: marker.onTap, + onDragStart: marker.onDragStart, + onDrag: marker.onDrag, + onDragEnd: marker.onDragEnd, + clusterManagerId: clusterManagerId, + ); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/Podfile b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/Podfile index a5cfb3f7bfbb..391330adc7d6 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/Podfile +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/Podfile @@ -28,6 +28,8 @@ require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelpe flutter_ios_podfile_setup target 'Runner' do + use_frameworks! + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) target 'RunnerTests' do inherit! :search_paths diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/Runner.xcodeproj/project.pbxproj b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/Runner.xcodeproj/project.pbxproj index 10545d750ed3..34e5636692e0 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/Runner.xcodeproj/project.pbxproj @@ -9,22 +9,22 @@ /* Begin PBXBuildFile section */ 0DD7B6C32B744EEF00E857FD /* FLTTileProviderControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DD7B6C22B744EEF00E857FD /* FLTTileProviderControllerTests.m */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 2BDE99378062AE3E60B40021 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3ACE0AFE8D82CD5962486AFD /* Pods_RunnerTests.framework */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 4510D964F3B1259FEDD3ABA6 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7755F8F4BABC3D6A0BD4048B /* libPods-Runner.a */; }; 478116522BEF8F47002F593E /* GoogleMapsPolylinesControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 478116512BEF8F47002F593E /* GoogleMapsPolylinesControllerTests.m */; }; + 528F16832C62941000148160 /* FGMClusterManagersControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 528F16822C62941000148160 /* FGMClusterManagersControllerTests.m */; }; + 528F16872C62952700148160 /* ExtractIconFromDataTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 528F16862C62952700148160 /* ExtractIconFromDataTests.m */; }; 6851F3562835BC180032B7C8 /* FLTGoogleMapJSONConversionsConversionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6851F3552835BC180032B7C8 /* FLTGoogleMapJSONConversionsConversionTests.m */; }; - 521AB0032B876A76005F460D /* ExtractIconFromDataTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 521AB0022B876A76005F460D /* ExtractIconFromDataTests.m */; }; - 68E4726A2836FF0C00BDDDAC /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 68E472692836FF0C00BDDDAC /* MapKit.framework */; }; 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 982F2A6C27BADE17003C81F4 /* PartiallyMockedMapView.m in Sources */ = {isa = PBXBuildFile; fileRef = 982F2A6B27BADE17003C81F4 /* PartiallyMockedMapView.m */; }; + B3A7FA04ABB7B84780729949 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61A9A8623F5CA9BBC813DC6B /* Pods_Runner.framework */; }; F269303B2BB389BF00BF17C4 /* assets in Resources */ = {isa = PBXBuildFile; fileRef = F269303A2BB389BF00BF17C4 /* assets */; }; F7151F13265D7ED70028CB91 /* GoogleMapsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F7151F12265D7ED70028CB91 /* GoogleMapsTests.m */; }; F7151F21265D7EE50028CB91 /* GoogleMapsUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = F7151F20265D7EE50028CB91 /* GoogleMapsUITests.m */; }; - FC8F35FC8CD533B128950487 /* libPods-RunnerTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F267F68029D1A4E2E4C572A7 /* libPods-RunnerTests.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -61,13 +61,14 @@ 0DD7B6C22B744EEF00E857FD /* FLTTileProviderControllerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FLTTileProviderControllerTests.m; sourceTree = ""; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3ACE0AFE8D82CD5962486AFD /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 478116512BEF8F47002F593E /* GoogleMapsPolylinesControllerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GoogleMapsPolylinesControllerTests.m; sourceTree = ""; }; + 528F16822C62941000148160 /* FGMClusterManagersControllerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FGMClusterManagersControllerTests.m; sourceTree = ""; }; + 528F16862C62952700148160 /* ExtractIconFromDataTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ExtractIconFromDataTests.m; sourceTree = ""; }; + 61A9A8623F5CA9BBC813DC6B /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 6851F3552835BC180032B7C8 /* FLTGoogleMapJSONConversionsConversionTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLTGoogleMapJSONConversionsConversionTests.m; sourceTree = ""; }; - 521AB0022B876A76005F460D /* ExtractIconFromDataTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExtractIconFromDataTests.m; sourceTree = ""; }; - 68E472692836FF0C00BDDDAC /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.0.sdk/System/iOSSupport/System/Library/Frameworks/MapKit.framework; sourceTree = DEVELOPER_DIR; }; 733AFAB37683A9DA7512F09C /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; - 7755F8F4BABC3D6A0BD4048B /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; @@ -84,7 +85,6 @@ B7AFC65E3DD5AC60D834D83D /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; E52C6A6210A56F027C582EF9 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; EA0E91726245EDC22B97E8B9 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - F267F68029D1A4E2E4C572A7 /* libPods-RunnerTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RunnerTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; F269303A2BB389BF00BF17C4 /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; path = assets; sourceTree = ""; }; F7151F10265D7ED70028CB91 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; F7151F12265D7ED70028CB91 /* GoogleMapsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GoogleMapsTests.m; sourceTree = ""; }; @@ -99,7 +99,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4510D964F3B1259FEDD3ABA6 /* libPods-Runner.a in Frameworks */, + B3A7FA04ABB7B84780729949 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -107,8 +107,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 68E4726A2836FF0C00BDDDAC /* MapKit.framework in Frameworks */, - FC8F35FC8CD533B128950487 /* libPods-RunnerTests.a in Frameworks */, + 2BDE99378062AE3E60B40021 /* Pods_RunnerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -125,9 +124,8 @@ 1E7CF0857EFC88FC263CF3B2 /* Frameworks */ = { isa = PBXGroup; children = ( - 68E472692836FF0C00BDDDAC /* MapKit.framework */, - 7755F8F4BABC3D6A0BD4048B /* libPods-Runner.a */, - F267F68029D1A4E2E4C572A7 /* libPods-RunnerTests.a */, + 61A9A8623F5CA9BBC813DC6B /* Pods_Runner.framework */, + 3ACE0AFE8D82CD5962486AFD /* Pods_RunnerTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -205,14 +203,15 @@ isa = PBXGroup; children = ( F269303A2BB389BF00BF17C4 /* assets */, + 528F16862C62952700148160 /* ExtractIconFromDataTests.m */, + 528F16822C62941000148160 /* FGMClusterManagersControllerTests.m */, 6851F3552835BC180032B7C8 /* FLTGoogleMapJSONConversionsConversionTests.m */, - 521AB0022B876A76005F460D /* ExtractIconFromDataTests.m */, + 0DD7B6C22B744EEF00E857FD /* FLTTileProviderControllerTests.m */, F7151F12265D7ED70028CB91 /* GoogleMapsTests.m */, 478116512BEF8F47002F593E /* GoogleMapsPolylinesControllerTests.m */, 982F2A6A27BADE17003C81F4 /* PartiallyMockedMapView.h */, 982F2A6B27BADE17003C81F4 /* PartiallyMockedMapView.m */, F7151F14265D7ED70028CB91 /* Info.plist */, - 0DD7B6C22B744EEF00E857FD /* FLTTileProviderControllerTests.m */, ); path = RunnerTests; sourceTree = ""; @@ -241,6 +240,7 @@ 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, BB6BD9A1101E970BEF85B6D2 /* [CP] Copy Pods Resources */, + A7D3A643E249522B15BA2B1D /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -259,6 +259,7 @@ F7151F0C265D7ED70028CB91 /* Sources */, F7151F0D265D7ED70028CB91 /* Frameworks */, F7151F0E265D7ED70028CB91 /* Resources */, + DF182F6A1B9E41DA05BFCB87 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -411,6 +412,24 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; + A7D3A643E249522B15BA2B1D /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/integration_test/integration_test.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/integration_test.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; BB6BD9A1101E970BEF85B6D2 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -453,6 +472,24 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; + DF182F6A1B9E41DA05BFCB87 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-RunnerTests/Pods-RunnerTests-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/OCMock/OCMock.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OCMock.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RunnerTests/Pods-RunnerTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -470,12 +507,13 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 528F16832C62941000148160 /* FGMClusterManagersControllerTests.m in Sources */, F7151F13265D7ED70028CB91 /* GoogleMapsTests.m in Sources */, 6851F3562835BC180032B7C8 /* FLTGoogleMapJSONConversionsConversionTests.m in Sources */, 982F2A6C27BADE17003C81F4 /* PartiallyMockedMapView.m in Sources */, 478116522BEF8F47002F593E /* GoogleMapsPolylinesControllerTests.m in Sources */, 0DD7B6C32B744EEF00E857FD /* FLTTileProviderControllerTests.m in Sources */, - 521AB0032B876A76005F460D /* ExtractIconFromDataTests.m in Sources */, + 528F16872C62952700148160 /* ExtractIconFromDataTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/FGMClusterManagersControllerTests.m b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/FGMClusterManagersControllerTests.m new file mode 100644 index 000000000000..6fdcccf468dd --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/FGMClusterManagersControllerTests.m @@ -0,0 +1,123 @@ +// 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 google_maps_flutter_ios; +@import google_maps_flutter_ios.Test; +@import XCTest; +@import GoogleMaps; + +#import +#import +#import "PartiallyMockedMapView.h" + +@interface FGMClusterManagersControllerTests : XCTestCase +@end + +@implementation FGMClusterManagersControllerTests + +- (void)testClustering { + NSObject *registrar = OCMProtocolMock(@protocol(FlutterPluginRegistrar)); + CGRect frame = CGRectMake(0, 0, 100, 100); + + GMSMapViewOptions *mapViewOptions = [[GMSMapViewOptions alloc] init]; + mapViewOptions.frame = frame; + mapViewOptions.camera = [[GMSCameraPosition alloc] initWithLatitude:0 longitude:0 zoom:0]; + + PartiallyMockedMapView *mapView = [[PartiallyMockedMapView alloc] initWithOptions:mapViewOptions]; + + id handler = OCMClassMock([FGMMapsCallbackApi class]); + + FGMClusterManagersController *clusterManagersController = + [[FGMClusterManagersController alloc] initWithMapView:mapView callbackHandler:handler]; + + FLTMarkersController *markersController = + [[FLTMarkersController alloc] initWithMapView:mapView + callbackHandler:handler + clusterManagersController:clusterManagersController + registrar:registrar]; + + // Add cluster managers. + NSString *clusterManagerId = @"cm"; + FGMPlatformClusterManager *clusterManagerToAdd = + [FGMPlatformClusterManager makeWithIdentifier:clusterManagerId]; + [clusterManagersController addClusterManagers:@[ clusterManagerToAdd ]]; + + // Verify that cluster managers are available + GMUClusterManager *clusterManager = + [clusterManagersController clusterManagerWithIdentifier:clusterManagerId]; + XCTAssertNotNil(clusterManager, @"Cluster Manager should not be nil"); + + // Add markers + NSString *markerId1 = @"m1"; + NSString *markerId2 = @"m2"; + + FGMPlatformMarker *marker1 = [FGMPlatformMarker makeWithJson:@{ + @"markerId" : markerId1, + @"position" : @[ @0, @0 ], + @"clusterManagerId" : clusterManagerId + }]; + FGMPlatformMarker *marker2 = [FGMPlatformMarker makeWithJson:@{ + @"markerId" : markerId2, + @"position" : @[ @0, @0 ], + @"clusterManagerId" : clusterManagerId + }]; + + [markersController addMarkers:@[ marker1, marker2 ]]; + + FlutterError *error = nil; + + // Invoke clustering + [clusterManagersController invokeClusteringForEachClusterManager]; + + // Verify that the markers were added to the cluster manager + NSArray *clusters1 = + [clusterManagersController clustersWithIdentifier:clusterManagerId error:&error]; + XCTAssertNil(error, @"Error should be nil"); + for (FGMPlatformCluster *cluster in clusters1) { + NSString *cmId = cluster.clusterManagerId; + XCTAssertNotNil(cmId, @"Cluster Manager Identifier should not be nil"); + if ([cmId isEqualToString:clusterManagerId]) { + NSArray *markerIds = cluster.markerIds; + XCTAssertEqual(markerIds.count, 2, @"Cluster should contain two marker"); + XCTAssertTrue([markerIds containsObject:markerId1], @"Cluster should contain markerId1"); + XCTAssertTrue([markerIds containsObject:markerId2], @"Cluster should contain markerId2"); + return; + } + } + + [markersController removeMarkersWithIdentifiers:@[ markerId2 ]]; + + // Verify that the marker2 is removed from the clusterManager + NSArray *clusters2 = + [clusterManagersController clustersWithIdentifier:clusterManagerId error:&error]; + XCTAssertNil(error, @"Error should be nil"); + + for (FGMPlatformCluster *cluster in clusters2) { + NSString *cmId = cluster.clusterManagerId; + XCTAssertNotNil(cmId, @"Cluster Manager ID should not be nil"); + if ([cmId isEqualToString:clusterManagerId]) { + NSArray *markerIds = cluster.markerIds; + XCTAssertEqual(markerIds.count, 1, @"Cluster should contain one marker"); + XCTAssertTrue([markerIds containsObject:markerId1], @"Cluster should contain markerId1"); + return; + } + } + + [markersController removeMarkersWithIdentifiers:@[ markerId1 ]]; + + // Verify that all markers are removed from clusterManager + NSArray *clusters3 = + [clusterManagersController clustersWithIdentifier:clusterManagerId error:&error]; + XCTAssertNil(error, @"Error should be nil"); + XCTAssertEqual(clusters3.count, 0, @"Cluster Manager should not contain any clusters"); + + // Remove cluster manager + [clusterManagersController removeClusterManagersWithIdentifiers:@[ clusterManagerId ]]; + + // Verify that the cluster manager is removed + clusterManager = [clusterManagersController clusterManagerWithIdentifier:clusterManagerId]; + XCTAssertNil(clusterManager, @"Cluster Manager should be nil"); +} + +@end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/FLTGoogleMapJSONConversionsConversionTests.m b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/FLTGoogleMapJSONConversionsConversionTests.m index cc654606d8c0..c66698c6834e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/FLTGoogleMapJSONConversionsConversionTests.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/FLTGoogleMapJSONConversionsConversionTests.m @@ -5,7 +5,6 @@ @import google_maps_flutter_ios; @import google_maps_flutter_ios.Test; @import XCTest; -@import MapKit; @import GoogleMaps; #import @@ -16,6 +15,28 @@ @interface FLTGoogleMapJSONConversionsTests : XCTestCase @implementation FLTGoogleMapJSONConversionsTests +- (void)testGetValueOrNilWithValue { + NSString *key = @"key"; + NSString *value = @"value"; + NSDictionary *dict = @{key : value}; + + XCTAssertEqual(FGMGetValueOrNilFromDict(dict, key), value); +} + +- (void)testGetValueOrNilWithNoEntry { + NSString *key = @"key"; + NSDictionary *dict = @{}; + + XCTAssertNil(FGMGetValueOrNilFromDict(dict, key)); +} + +- (void)testGetValueOrNilWithNSNull { + NSString *key = @"key"; + NSDictionary *dict = @{key : [NSNull null]}; + + XCTAssertNil(FGMGetValueOrNilFromDict(dict, key)); +} + - (void)testLocationFromLatLong { NSArray *latlong = @[ @1, @2 ]; CLLocationCoordinate2D location = [FLTGoogleMapJSONConversions locationFromLatLong:latlong]; @@ -76,40 +97,41 @@ - (void)testHolesFromPointsArray { XCTAssertEqual(holes[1][1].coordinate.longitude, 8); } -- (void)testDictionaryFromPosition { - id mockPosition = OCMClassMock([GMSCameraPosition class]); - NSValue *locationValue = [NSValue valueWithMKCoordinate:CLLocationCoordinate2DMake(1, 2)]; - [(GMSCameraPosition *)[[mockPosition stub] andReturnValue:locationValue] target]; - [[[mockPosition stub] andReturnValue:@(2.0)] zoom]; - [[[mockPosition stub] andReturnValue:@(3.0)] bearing]; - [[[mockPosition stub] andReturnValue:@(75.0)] viewingAngle]; - NSDictionary *dictionary = [FLTGoogleMapJSONConversions dictionaryFromPosition:mockPosition]; - NSArray *targetArray = @[ @1, @2 ]; - XCTAssertEqualObjects(dictionary[@"target"], targetArray); - XCTAssertEqualObjects(dictionary[@"zoom"], @2.0); - XCTAssertEqualObjects(dictionary[@"bearing"], @3.0); - XCTAssertEqualObjects(dictionary[@"tilt"], @75.0); +- (void)testGetPigeonCameraPositionForPosition { + GMSCameraPosition *position = + [[GMSCameraPosition alloc] initWithTarget:CLLocationCoordinate2DMake(1, 2) + zoom:2.0 + bearing:3.0 + viewingAngle:75.0]; + FGMPlatformCameraPosition *pigeonPosition = FGMGetPigeonCameraPositionForPosition(position); + XCTAssertEqualWithAccuracy(pigeonPosition.target.latitude, position.target.latitude, DBL_EPSILON); + XCTAssertEqualWithAccuracy(pigeonPosition.target.longitude, position.target.longitude, + DBL_EPSILON); + XCTAssertEqualWithAccuracy(pigeonPosition.zoom, position.zoom, DBL_EPSILON); + XCTAssertEqualWithAccuracy(pigeonPosition.bearing, position.bearing, DBL_EPSILON); + XCTAssertEqualWithAccuracy(pigeonPosition.tilt, position.viewingAngle, DBL_EPSILON); } -- (void)testDictionaryFromPoint { +- (void)testPigeonPointForGCPoint { CGPoint point = CGPointMake(10, 20); - NSDictionary *dictionary = [FLTGoogleMapJSONConversions dictionaryFromPoint:point]; - const CGFloat accuracy = 0.0001; - XCTAssertEqualWithAccuracy([dictionary[@"x"] floatValue], point.x, accuracy); - XCTAssertEqualWithAccuracy([dictionary[@"y"] floatValue], point.y, accuracy); + FGMPlatformPoint *pigeonPoint = FGMGetPigeonPointForCGPoint(point); + XCTAssertEqualWithAccuracy(pigeonPoint.x, point.x, DBL_EPSILON); + XCTAssertEqualWithAccuracy(pigeonPoint.y, point.y, DBL_EPSILON); } -- (void)testDictionaryFromCoordinateBounds { - XCTAssertNil([FLTGoogleMapJSONConversions dictionaryFromCoordinateBounds:nil]); - +- (void)testPigeonLatLngBoundsForCoordinateBounds { GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] initWithCoordinate:CLLocationCoordinate2DMake(10, 20) coordinate:CLLocationCoordinate2DMake(30, 40)]; - NSDictionary *dictionary = [FLTGoogleMapJSONConversions dictionaryFromCoordinateBounds:bounds]; - NSArray *southwest = @[ @10, @20 ]; - NSArray *northeast = @[ @30, @40 ]; - XCTAssertEqualObjects(dictionary[@"southwest"], southwest); - XCTAssertEqualObjects(dictionary[@"northeast"], northeast); + FGMPlatformLatLngBounds *pigeonBounds = FGMGetPigeonLatLngBoundsForCoordinateBounds(bounds); + XCTAssertEqualWithAccuracy(pigeonBounds.southwest.latitude, bounds.southWest.latitude, + DBL_EPSILON); + XCTAssertEqualWithAccuracy(pigeonBounds.southwest.longitude, bounds.southWest.longitude, + DBL_EPSILON); + XCTAssertEqualWithAccuracy(pigeonBounds.northeast.latitude, bounds.northEast.latitude, + DBL_EPSILON); + XCTAssertEqualWithAccuracy(pigeonBounds.northeast.longitude, bounds.northEast.longitude, + DBL_EPSILON); } - (void)testCameraPostionFromDictionary { @@ -129,19 +151,32 @@ - (void)testCameraPostionFromDictionary { XCTAssertEqualWithAccuracy(cameraPosition.viewingAngle, 5, accuracy); } -- (void)testPointFromDictionary { - XCTAssertNil([FLTGoogleMapJSONConversions cameraPostionFromDictionary:nil]); +- (void)testGetCameraPostionForPigeonCameraPosition { + FGMPlatformCameraPosition *pigeonCameraPosition = [FGMPlatformCameraPosition + makeWithBearing:1.0 + target:[FGMPlatformLatLng makeWithLatitude:2.0 longitude:3.0] + tilt:4.0 + zoom:5.0]; - NSDictionary *dictionary = @{ - @"x" : @1, - @"y" : @2, - }; + GMSCameraPosition *cameraPosition = + FGMGetCameraPositionForPigeonCameraPosition(pigeonCameraPosition); + + XCTAssertEqualWithAccuracy(cameraPosition.target.latitude, pigeonCameraPosition.target.latitude, + DBL_EPSILON); + XCTAssertEqualWithAccuracy(cameraPosition.target.longitude, pigeonCameraPosition.target.longitude, + DBL_EPSILON); + XCTAssertEqualWithAccuracy(cameraPosition.zoom, pigeonCameraPosition.zoom, DBL_EPSILON); + XCTAssertEqualWithAccuracy(cameraPosition.bearing, pigeonCameraPosition.bearing, DBL_EPSILON); + XCTAssertEqualWithAccuracy(cameraPosition.viewingAngle, pigeonCameraPosition.tilt, DBL_EPSILON); +} - CGPoint point = [FLTGoogleMapJSONConversions pointFromDictionary:dictionary]; +- (void)testCGPointForPigeonPoint { + FGMPlatformPoint *pigeonPoint = [FGMPlatformPoint makeWithX:1.0 y:2.0]; - const CGFloat accuracy = 0.001; - XCTAssertEqualWithAccuracy(point.x, 1, accuracy); - XCTAssertEqualWithAccuracy(point.y, 2, accuracy); + CGPoint point = FGMGetCGPointForPigeonPoint(pigeonPoint); + + XCTAssertEqualWithAccuracy(pigeonPoint.x, point.x, DBL_EPSILON); + XCTAssertEqualWithAccuracy(pigeonPoint.y, point.y, DBL_EPSILON); } - (void)testCoordinateBoundsFromLatLongs { @@ -158,26 +193,26 @@ - (void)testCoordinateBoundsFromLatLongs { XCTAssertEqualWithAccuracy(bounds.northEast.longitude, 4, accuracy); } -- (void)testMapViewTypeFromTypeValue { - XCTAssertEqual(kGMSTypeNormal, [FLTGoogleMapJSONConversions mapViewTypeFromTypeValue:@1]); - XCTAssertEqual(kGMSTypeSatellite, [FLTGoogleMapJSONConversions mapViewTypeFromTypeValue:@2]); - XCTAssertEqual(kGMSTypeTerrain, [FLTGoogleMapJSONConversions mapViewTypeFromTypeValue:@3]); - XCTAssertEqual(kGMSTypeHybrid, [FLTGoogleMapJSONConversions mapViewTypeFromTypeValue:@4]); - XCTAssertEqual(kGMSTypeNone, [FLTGoogleMapJSONConversions mapViewTypeFromTypeValue:@5]); +- (void)testMapViewTypeFromPigeonType { + XCTAssertEqual(kGMSTypeNormal, FGMGetMapViewTypeForPigeonMapType(FGMPlatformMapTypeNormal)); + XCTAssertEqual(kGMSTypeSatellite, FGMGetMapViewTypeForPigeonMapType(FGMPlatformMapTypeSatellite)); + XCTAssertEqual(kGMSTypeTerrain, FGMGetMapViewTypeForPigeonMapType(FGMPlatformMapTypeTerrain)); + XCTAssertEqual(kGMSTypeHybrid, FGMGetMapViewTypeForPigeonMapType(FGMPlatformMapTypeHybrid)); + XCTAssertEqual(kGMSTypeNone, FGMGetMapViewTypeForPigeonMapType(FGMPlatformMapTypeNone)); } -- (void)testCameraUpdateFromChannelValueNewCameraPosition { +- (void)testCameraUpdateFromArrayNewCameraPosition { NSArray *channelValue = @[ @"newCameraPosition", @{@"target" : @[ @1, @2 ], @"zoom" : @3, @"bearing" : @4, @"tilt" : @5} ]; id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); - [FLTGoogleMapJSONConversions cameraUpdateFromChannelValue:channelValue]; + [FLTGoogleMapJSONConversions cameraUpdateFromArray:channelValue]; [[classMockCameraUpdate expect] setCamera:[FLTGoogleMapJSONConversions cameraPostionFromDictionary:channelValue[1]]]; [classMockCameraUpdate stopMocking]; } -// TODO(cyanglaz): Fix the test for CameraUpdateFromChannelValue with the "NewLatlng" key. +// TODO(cyanglaz): Fix the test for cameraUpdateFromArray with the "NewLatlng" key. // 2 approaches have been tried and neither worked for the tests. // // 1. Use OCMock to vefiry that [GMSCameraUpdate setTarget:] is triggered with the correct value. @@ -191,10 +226,10 @@ - (void)testCameraUpdateFromChannelValueNewCameraPosition { // verified. // // The code in below test uses the 2nd approach. -- (void)skip_testCameraUpdateFromChannelValueNewLatLong { +- (void)skip_testCameraUpdateFromArrayNewLatLong { NSArray *channelValue = @[ @"newLatLng", @[ @1, @2 ] ]; - GMSCameraUpdate *update = [FLTGoogleMapJSONConversions cameraUpdateFromChannelValue:channelValue]; + GMSCameraUpdate *update = [FLTGoogleMapJSONConversions cameraUpdateFromArray:channelValue]; GMSMapViewOptions *options = [[GMSMapViewOptions alloc] init]; options.frame = CGRectZero; @@ -208,7 +243,7 @@ - (void)skip_testCameraUpdateFromChannelValueNewLatLong { accuracy); // mapView.camera.target.longitude is still 6. } -- (void)testCameraUpdateFromChannelValueNewLatLngBounds { +- (void)testCameraUpdateFromArrayNewLatLngBounds { NSArray *latlong1 = @[ @1, @2 ]; NSArray *latlong2 = @[ @(3), @(4) ]; GMSCoordinateBounds *bounds = @@ -216,73 +251,73 @@ - (void)testCameraUpdateFromChannelValueNewLatLngBounds { NSArray *channelValue = @[ @"newLatLngBounds", @[ latlong1, latlong2 ], @20 ]; id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); - [FLTGoogleMapJSONConversions cameraUpdateFromChannelValue:channelValue]; + [FLTGoogleMapJSONConversions cameraUpdateFromArray:channelValue]; [[classMockCameraUpdate expect] fitBounds:bounds withPadding:20]; [classMockCameraUpdate stopMocking]; } -- (void)testCameraUpdateFromChannelValueNewLatLngZoom { +- (void)testCameraUpdateFromArrayNewLatLngZoom { NSArray *channelValue = @[ @"newLatLngZoom", @[ @1, @2 ], @3 ]; id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); - [FLTGoogleMapJSONConversions cameraUpdateFromChannelValue:channelValue]; + [FLTGoogleMapJSONConversions cameraUpdateFromArray:channelValue]; [[classMockCameraUpdate expect] setTarget:CLLocationCoordinate2DMake(1, 2) zoom:3]; [classMockCameraUpdate stopMocking]; } -- (void)testCameraUpdateFromChannelValueScrollBy { +- (void)testCameraUpdateFromArrayScrollBy { NSArray *channelValue = @[ @"scrollBy", @1, @2 ]; id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); - [FLTGoogleMapJSONConversions cameraUpdateFromChannelValue:channelValue]; + [FLTGoogleMapJSONConversions cameraUpdateFromArray:channelValue]; [[classMockCameraUpdate expect] scrollByX:1 Y:2]; [classMockCameraUpdate stopMocking]; } -- (void)testCameraUpdateFromChannelValueZoomBy { +- (void)testCameraUpdateFromArrayZoomBy { NSArray *channelValueNoPoint = @[ @"zoomBy", @1 ]; id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); - [FLTGoogleMapJSONConversions cameraUpdateFromChannelValue:channelValueNoPoint]; + [FLTGoogleMapJSONConversions cameraUpdateFromArray:channelValueNoPoint]; [[classMockCameraUpdate expect] zoomBy:1]; NSArray *channelValueWithPoint = @[ @"zoomBy", @1, @[ @2, @3 ] ]; - [FLTGoogleMapJSONConversions cameraUpdateFromChannelValue:channelValueWithPoint]; + [FLTGoogleMapJSONConversions cameraUpdateFromArray:channelValueWithPoint]; [[classMockCameraUpdate expect] zoomBy:1 atPoint:CGPointMake(2, 3)]; [classMockCameraUpdate stopMocking]; } -- (void)testCameraUpdateFromChannelValueZoomIn { +- (void)testCameraUpdateFromArrayZoomIn { NSArray *channelValueNoPoint = @[ @"zoomIn" ]; id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); - [FLTGoogleMapJSONConversions cameraUpdateFromChannelValue:channelValueNoPoint]; + [FLTGoogleMapJSONConversions cameraUpdateFromArray:channelValueNoPoint]; [[classMockCameraUpdate expect] zoomIn]; [classMockCameraUpdate stopMocking]; } -- (void)testCameraUpdateFromChannelValueZoomOut { +- (void)testCameraUpdateFromArrayZoomOut { NSArray *channelValueNoPoint = @[ @"zoomOut" ]; id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); - [FLTGoogleMapJSONConversions cameraUpdateFromChannelValue:channelValueNoPoint]; + [FLTGoogleMapJSONConversions cameraUpdateFromArray:channelValueNoPoint]; [[classMockCameraUpdate expect] zoomOut]; [classMockCameraUpdate stopMocking]; } -- (void)testCameraUpdateFromChannelValueZoomTo { +- (void)testCameraUpdateFromArrayZoomTo { NSArray *channelValueNoPoint = @[ @"zoomTo", @1 ]; id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); - [FLTGoogleMapJSONConversions cameraUpdateFromChannelValue:channelValueNoPoint]; + [FLTGoogleMapJSONConversions cameraUpdateFromArray:channelValueNoPoint]; [[classMockCameraUpdate expect] zoomTo:1]; [classMockCameraUpdate stopMocking]; @@ -302,4 +337,54 @@ - (void)testLengthsFromPatterns { XCTAssertEqual(secondSpanLength.doubleValue, 6.4); } +- (void)testWeightedLatLngFromArray { + NSArray *weightedLatLng = @[ @[ @1, @2 ], @3 ]; + + GMUWeightedLatLng *weightedLocation = + [FLTGoogleMapJSONConversions weightedLatLngFromArray:weightedLatLng]; + + // The location gets projected to different values + XCTAssertEqual([weightedLocation intensity], 3); +} + +- (void)testWeightedLatLngFromArrayThrowsForInvalidInput { + NSArray *weightedLatLng = @[]; + + XCTAssertThrows([FLTGoogleMapJSONConversions weightedLatLngFromArray:weightedLatLng]); +} + +- (void)testWeightedDataFromArray { + NSNumber *intensity1 = @3; + NSNumber *intensity2 = @6; + NSArray *data = @[ @[ @[ @1, @2 ], intensity1 ], @[ @[ @4, @5 ], intensity2 ] ]; + + NSArray *weightedData = + [FLTGoogleMapJSONConversions weightedDataFromArray:data]; + XCTAssertEqual([weightedData[0] intensity], [intensity1 floatValue]); + XCTAssertEqual([weightedData[1] intensity], [intensity2 floatValue]); +} + +- (void)testGradientFromDictionary { + NSNumber *startPoint = @0.6; + NSNumber *colorMapSize = @200; + NSDictionary *gradientData = @{ + @"colors" : @[ + // Color.fromARGB(255, 0, 255, 255) + @4278255615, + ], + @"startPoints" : @[ startPoint ], + @"colorMapSize" : colorMapSize, + }; + + GMUGradient *gradient = [FLTGoogleMapJSONConversions gradientFromDictionary:gradientData]; + CGFloat red, green, blue, alpha; + [[gradient colors][0] getRed:&red green:&green blue:&blue alpha:&alpha]; + XCTAssertEqual(red, 0); + XCTAssertEqual(green, 1); + XCTAssertEqual(blue, 1); + XCTAssertEqual(alpha, 1); + XCTAssertEqualWithAccuracy([[gradient startPoints][0] doubleValue], [startPoint doubleValue], 0); + XCTAssertEqual([gradient mapSize], [colorMapSize intValue]); +} + @end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/FLTTileProviderControllerTests.m b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/FLTTileProviderControllerTests.m index d42174a906f5..f4b6ba8d195c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/FLTTileProviderControllerTests.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/FLTTileProviderControllerTests.m @@ -8,18 +8,24 @@ #import +#import "messages.g.h" + @interface FLTTileProviderControllerTests : XCTestCase @end @implementation FLTTileProviderControllerTests - (void)testCallChannelOnPlatformThread { - id channel = OCMClassMock(FlutterMethodChannel.class); - FLTTileProviderController *controller = [[FLTTileProviderController alloc] init:channel - withTileOverlayIdentifier:@"foo"]; + id handler = OCMClassMock([FGMMapsCallbackApi class]); + FLTTileProviderController *controller = + [[FLTTileProviderController alloc] initWithTileOverlayIdentifier:@"foo" + callbackHandler:handler]; XCTAssertNotNil(controller); XCTestExpectation *expectation = [self expectationWithDescription:@"invokeMethod"]; - OCMStub([channel invokeMethod:[OCMArg any] arguments:[OCMArg any] result:[OCMArg any]]) + OCMStub([handler tileWithOverlayIdentifier:[OCMArg any] + location:[OCMArg any] + zoom:0 + completion:[OCMArg any]]) .andDo(^(NSInvocation *invocation) { XCTAssertTrue([[NSThread currentThread] isMainThread]); [expectation fulfill]; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/GoogleMapsPolylinesControllerTests.m b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/GoogleMapsPolylinesControllerTests.m index 84714f17c7f6..0ce0f53e00c4 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/GoogleMapsPolylinesControllerTests.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/GoogleMapsPolylinesControllerTests.m @@ -41,9 +41,9 @@ - (FLTGoogleMapPolylineController *)polylineControllerWithMockedMap { NSString *identifier = polyline[@"polylineId"]; FLTGoogleMapPolylineController *polylineControllerWithMockedMap = - [[FLTGoogleMapPolylineController alloc] initPolylineWithPath:path - identifier:identifier - mapView:mapView]; + [[FLTGoogleMapPolylineController alloc] initWithPath:path + identifier:identifier + mapView:mapView]; return polylineControllerWithMockedMap; } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/GoogleMapsTests.m b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/GoogleMapsTests.m index b3ac89e2441d..c175550dd2cf 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/GoogleMapsTests.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/GoogleMapsTests.m @@ -40,10 +40,11 @@ - (void)testFrameObserver { initWithFrame:frame camera:[[GMSCameraPosition alloc] initWithLatitude:0 longitude:0 zoom:0]]; #pragma clang diagnostic pop - FLTGoogleMapController *controller = [[FLTGoogleMapController alloc] initWithMapView:mapView - viewIdentifier:0 - arguments:nil - registrar:registrar]; + FLTGoogleMapController *controller = + [[FLTGoogleMapController alloc] initWithMapView:mapView + viewIdentifier:0 + creationParameters:[self emptyCreationParameters] + registrar:registrar]; for (NSInteger i = 0; i < 10; ++i) { [controller view]; @@ -85,4 +86,24 @@ - (void)testHandleResultTileDownsamplesWideGamutImages { XCTAssert(bitsPerComponent == 8); } +/// Creates an empty creation paramaters object for tests where the values don't matter, just that +/// there's a valid object to pass in. +- (FGMPlatformMapViewCreationParams *)emptyCreationParameters { + return [FGMPlatformMapViewCreationParams + makeWithInitialCameraPosition:[FGMPlatformCameraPosition + makeWithBearing:0.0 + target:[FGMPlatformLatLng makeWithLatitude:0.0 + longitude:0.0] + tilt:0.0 + zoom:0.0] + mapConfiguration:[[FGMPlatformMapConfiguration alloc] init] + initialCircles:@[] + initialMarkers:@[] + initialPolygons:@[] + initialPolylines:@[] + initialHeatmaps:@[] + initialTileOverlays:@[] + initialClusterManagers:@[]]; +} + @end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerUITests/GoogleMapsUITests.m b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerUITests/GoogleMapsUITests.m index 3a1191bdb39e..cfb509a3c744 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerUITests/GoogleMapsUITests.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerUITests/GoogleMapsUITests.m @@ -8,6 +8,9 @@ static const NSTimeInterval kWaitTime = 60; +// TODO(bparrishMines): Remove once https://github.com/flutter/flutter/issues/154641 is fixed. +static const BOOL skipFor154641 = YES; + @interface GoogleMapsUITests : XCTestCase @property(nonatomic, strong) XCUIApplication *app; @end @@ -46,6 +49,8 @@ - (void)setUp { } - (void)testUserInterface { + XCTSkipIf(skipFor154641); + XCUIApplication *app = self.app; XCUIElement *userInteface = app.staticTexts[@"User interface"]; if (![userInteface waitForExistenceWithTimeout:kWaitTime]) { @@ -77,6 +82,8 @@ - (void)testUserInterface { } - (void)testMapCoordinatesPage { + XCTSkipIf(skipFor154641); + XCUIApplication *app = self.app; XCUIElement *mapCoordinates = app.staticTexts[@"Map coordinates"]; if (![mapCoordinates waitForExistenceWithTimeout:kWaitTime]) { @@ -168,6 +175,8 @@ - (void)validateVisibleRegion:(NSString *)label } - (void)testMapClickPage { + XCTSkipIf(skipFor154641); + XCUIApplication *app = self.app; XCUIElement *mapClick = app.staticTexts[@"Map click"]; if (![mapClick waitForExistenceWithTimeout:kWaitTime]) { @@ -212,6 +221,8 @@ - (void)forceTap:(XCUIElement *)button { } - (void)testMarkerDraggingCallbacks { + XCTSkipIf(skipFor154641); + XCUIApplication *application = [[XCUIApplication alloc] init]; [application launch]; XCUIElement *placeMarkerButton = application.staticTexts[@"Place marker"]; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/lib/main.dart b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/lib/main.dart index 09fa814fdcf8..3144c2aff5e6 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/lib/main.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/lib/main.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:maps_example_dart/animate_camera.dart'; +import 'package:maps_example_dart/clustering.dart'; import 'package:maps_example_dart/lite_mode.dart'; import 'package:maps_example_dart/map_click.dart'; import 'package:maps_example_dart/map_coordinates.dart'; @@ -40,6 +41,7 @@ void main() { SnapshotPage(), LiteModePage(), TileOverlayPage(), + ClusteringPage(), MapIdPage(), ]))); } 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 0c50df87f12e..a130acf4b348 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.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: cupertino_icons: ^1.0.5 @@ -18,7 +18,7 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../../ - google_maps_flutter_platform_interface: ^2.7.0 + google_maps_flutter_platform_interface: ^2.9.0 maps_example_dart: path: ../shared/maps_example_dart/ diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/ios/Podfile b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/ios/Podfile index 833aacf78d38..37d20e51d606 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/ios/Podfile +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/ios/Podfile @@ -28,6 +28,8 @@ require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelpe flutter_ios_podfile_setup target 'Runner' do + use_frameworks! + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) target 'RunnerTests' do inherit! :search_paths diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/ios/Runner.xcodeproj/project.pbxproj b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/ios/Runner.xcodeproj/project.pbxproj index dc2ad2532b9e..04a00376c7aa 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/ios/Runner.xcodeproj/project.pbxproj @@ -9,17 +9,16 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 4510D964F3B1259FEDD3ABA6 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7755F8F4BABC3D6A0BD4048B /* libPods-Runner.a */; }; - 68E4726A2836FF0C00BDDDAC /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 68E472692836FF0C00BDDDAC /* MapKit.framework */; }; + 5B5EF9A6C72A03092BDA553E /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28D4666EF03E57DB7D03E916 /* Pods_RunnerTests.framework */; }; 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 982F2A6C27BADE17003C81F4 /* PartiallyMockedMapView.m in Sources */ = {isa = PBXBuildFile; fileRef = 982F2A6B27BADE17003C81F4 /* PartiallyMockedMapView.m */; }; + AF2E6994ED025F4BCE652A48 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0D457E156D08F0B45EA2F6FF /* Pods_Runner.framework */; }; F269303B2BB389BF00BF17C4 /* assets in Resources */ = {isa = PBXBuildFile; fileRef = F269303A2BB389BF00BF17C4 /* assets */; }; F7151F13265D7ED70028CB91 /* GoogleMapsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F7151F12265D7ED70028CB91 /* GoogleMapsTests.m */; }; - FC8F35FC8CD533B128950487 /* libPods-RunnerTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F267F68029D1A4E2E4C572A7 /* libPods-RunnerTests.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -46,12 +45,12 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 0D457E156D08F0B45EA2F6FF /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 28D4666EF03E57DB7D03E916 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 68E472692836FF0C00BDDDAC /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.0.sdk/System/iOSSupport/System/Library/Frameworks/MapKit.framework; sourceTree = DEVELOPER_DIR; }; 733AFAB37683A9DA7512F09C /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; - 7755F8F4BABC3D6A0BD4048B /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; @@ -68,7 +67,6 @@ B7AFC65E3DD5AC60D834D83D /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; E52C6A6210A56F027C582EF9 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; EA0E91726245EDC22B97E8B9 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - F267F68029D1A4E2E4C572A7 /* libPods-RunnerTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RunnerTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; F269303A2BB389BF00BF17C4 /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; path = assets; sourceTree = ""; }; F7151F10265D7ED70028CB91 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; F7151F12265D7ED70028CB91 /* GoogleMapsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GoogleMapsTests.m; sourceTree = ""; }; @@ -80,7 +78,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4510D964F3B1259FEDD3ABA6 /* libPods-Runner.a in Frameworks */, + AF2E6994ED025F4BCE652A48 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -88,8 +86,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 68E4726A2836FF0C00BDDDAC /* MapKit.framework in Frameworks */, - FC8F35FC8CD533B128950487 /* libPods-RunnerTests.a in Frameworks */, + 5B5EF9A6C72A03092BDA553E /* Pods_RunnerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -99,9 +96,8 @@ 1E7CF0857EFC88FC263CF3B2 /* Frameworks */ = { isa = PBXGroup; children = ( - 68E472692836FF0C00BDDDAC /* MapKit.framework */, - 7755F8F4BABC3D6A0BD4048B /* libPods-Runner.a */, - F267F68029D1A4E2E4C572A7 /* libPods-RunnerTests.a */, + 0D457E156D08F0B45EA2F6FF /* Pods_Runner.framework */, + 28D4666EF03E57DB7D03E916 /* Pods_RunnerTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -200,6 +196,7 @@ 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, BB6BD9A1101E970BEF85B6D2 /* [CP] Copy Pods Resources */, + 851CD952D11C6D91E216A90F /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -218,6 +215,7 @@ F7151F0C265D7ED70028CB91 /* Sources */, F7151F0D265D7ED70028CB91 /* Frameworks */, F7151F0E265D7ED70028CB91 /* Resources */, + 7862D82E36C37F9B7558DA5E /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -324,6 +322,42 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; + 7862D82E36C37F9B7558DA5E /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-RunnerTests/Pods-RunnerTests-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/OCMock/OCMock.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OCMock.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RunnerTests/Pods-RunnerTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 851CD952D11C6D91E216A90F /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/integration_test/integration_test.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/integration_test.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/ios/RunnerTests/GoogleMapsTests.m b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/ios/RunnerTests/GoogleMapsTests.m index b3ac89e2441d..c175550dd2cf 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/ios/RunnerTests/GoogleMapsTests.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/ios/RunnerTests/GoogleMapsTests.m @@ -40,10 +40,11 @@ - (void)testFrameObserver { initWithFrame:frame camera:[[GMSCameraPosition alloc] initWithLatitude:0 longitude:0 zoom:0]]; #pragma clang diagnostic pop - FLTGoogleMapController *controller = [[FLTGoogleMapController alloc] initWithMapView:mapView - viewIdentifier:0 - arguments:nil - registrar:registrar]; + FLTGoogleMapController *controller = + [[FLTGoogleMapController alloc] initWithMapView:mapView + viewIdentifier:0 + creationParameters:[self emptyCreationParameters] + registrar:registrar]; for (NSInteger i = 0; i < 10; ++i) { [controller view]; @@ -85,4 +86,24 @@ - (void)testHandleResultTileDownsamplesWideGamutImages { XCTAssert(bitsPerComponent == 8); } +/// Creates an empty creation paramaters object for tests where the values don't matter, just that +/// there's a valid object to pass in. +- (FGMPlatformMapViewCreationParams *)emptyCreationParameters { + return [FGMPlatformMapViewCreationParams + makeWithInitialCameraPosition:[FGMPlatformCameraPosition + makeWithBearing:0.0 + target:[FGMPlatformLatLng makeWithLatitude:0.0 + longitude:0.0] + tilt:0.0 + zoom:0.0] + mapConfiguration:[[FGMPlatformMapConfiguration alloc] init] + initialCircles:@[] + initialMarkers:@[] + initialPolygons:@[] + initialPolylines:@[] + initialHeatmaps:@[] + initialTileOverlays:@[] + initialClusterManagers:@[]]; +} + @end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/lib/main.dart b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/lib/main.dart index 09fa814fdcf8..3144c2aff5e6 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/lib/main.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/lib/main.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:maps_example_dart/animate_camera.dart'; +import 'package:maps_example_dart/clustering.dart'; import 'package:maps_example_dart/lite_mode.dart'; import 'package:maps_example_dart/map_click.dart'; import 'package:maps_example_dart/map_coordinates.dart'; @@ -40,6 +41,7 @@ void main() { SnapshotPage(), LiteModePage(), TileOverlayPage(), + ClusteringPage(), MapIdPage(), ]))); } 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 0c50df87f12e..a130acf4b348 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.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: cupertino_icons: ^1.0.5 @@ -18,7 +18,7 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../../ - google_maps_flutter_platform_interface: ^2.7.0 + google_maps_flutter_platform_interface: ^2.9.0 maps_example_dart: path: ../shared/maps_example_dart/ diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/clustering.dart b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/clustering.dart new file mode 100644 index 000000000000..f6860f7bf42e --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/clustering.dart @@ -0,0 +1,278 @@ +// 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:math'; + +import 'package:flutter/material.dart'; +import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; + +import 'example_google_map.dart'; +import 'page.dart'; + +/// Page for demonstrating marker clustering support. +class ClusteringPage extends GoogleMapExampleAppPage { + /// Default Constructor. + const ClusteringPage({Key? key}) + : super(const Icon(Icons.place), 'Manage clustering', key: key); + + @override + Widget build(BuildContext context) { + return const ClusteringBody(); + } +} + +/// Body of the clustering page. +class ClusteringBody extends StatefulWidget { + /// Default Constructor. + const ClusteringBody({super.key}); + + @override + State createState() => ClusteringBodyState(); +} + +/// State of the clustering page. +class ClusteringBodyState extends State { + /// Default Constructor. + ClusteringBodyState(); + + /// Starting point from where markers are added. + static const LatLng center = LatLng(-33.86, 151.1547171); + + /// Marker offset factor for randomizing marker placing. + static const double _markerOffsetFactor = 0.05; + + /// Offset for longitude when placing markers to different cluster managers. + static const double _clusterManagerLongitudeOffset = 0.1; + + /// Maximum amount of cluster managers. + static const int _clusterManagerMaxCount = 3; + + /// Amount of markers to be added to the cluster manager at once. + static const int _markersToAddToClusterManagerCount = 10; + + /// Fully visible alpha value. + static const double _fullyVisibleAlpha = 1.0; + + /// Half visible alpha value. + static const double _halfVisibleAlpha = 0.5; + + /// Google map controller. + ExampleGoogleMapController? controller; + + /// Map of clusterManagers with identifier as the key. + Map clusterManagers = + {}; + + /// Map of markers with identifier as the key. + Map markers = {}; + + /// Id of the currently selected marker. + MarkerId? selectedMarker; + + /// Counter for added cluster manager ids. + int _clusterManagerIdCounter = 1; + + /// Counter for added markers ids. + int _markerIdCounter = 1; + + /// Cluster that was tapped most recently. + Cluster? lastCluster; + + // ignore: use_setters_to_change_properties + void _onMapCreated(ExampleGoogleMapController controller) { + this.controller = controller; + } + + @override + void dispose() { + super.dispose(); + } + + void _onMarkerTapped(MarkerId markerId) { + final Marker? tappedMarker = markers[markerId]; + if (tappedMarker != null) { + setState(() { + final MarkerId? previousMarkerId = selectedMarker; + if (previousMarkerId != null && markers.containsKey(previousMarkerId)) { + final Marker resetOld = markers[previousMarkerId]! + .copyWith(iconParam: BitmapDescriptor.defaultMarker); + markers[previousMarkerId] = resetOld; + } + selectedMarker = markerId; + final Marker newMarker = tappedMarker.copyWith( + iconParam: BitmapDescriptor.defaultMarkerWithHue( + BitmapDescriptor.hueGreen, + ), + ); + markers[markerId] = newMarker; + }); + } + } + + void _addClusterManager() { + if (clusterManagers.length == _clusterManagerMaxCount) { + return; + } + + final String clusterManagerIdVal = + 'cluster_manager_id_$_clusterManagerIdCounter'; + _clusterManagerIdCounter++; + final ClusterManagerId clusterManagerId = + ClusterManagerId(clusterManagerIdVal); + + final ClusterManager clusterManager = ClusterManager( + clusterManagerId: clusterManagerId, + onClusterTap: (Cluster cluster) => setState(() { + lastCluster = cluster; + }), + ); + + setState(() { + clusterManagers[clusterManagerId] = clusterManager; + }); + _addMarkersToCluster(clusterManager); + } + + void _removeClusterManager(ClusterManager clusterManager) { + setState(() { + // Remove markers managed by cluster manager to be removed. + markers.removeWhere((MarkerId key, Marker marker) => + marker.clusterManagerId == clusterManager.clusterManagerId); + // Remove cluster manager. + clusterManagers.remove(clusterManager.clusterManagerId); + }); + } + + void _addMarkersToCluster(ClusterManager clusterManager) { + for (int i = 0; i < _markersToAddToClusterManagerCount; i++) { + final String markerIdVal = + '${clusterManager.clusterManagerId.value}_marker_id_$_markerIdCounter'; + _markerIdCounter++; + final MarkerId markerId = MarkerId(markerIdVal); + + final int clusterManagerIndex = + clusterManagers.values.toList().indexOf(clusterManager); + + // Add additional offset to longitude for each cluster manager to space + // out markers in different cluster managers. + final double clusterManagerLongitudeOffset = + clusterManagerIndex * _clusterManagerLongitudeOffset; + + final Marker marker = Marker( + clusterManagerId: clusterManager.clusterManagerId, + markerId: markerId, + position: LatLng( + center.latitude + _getRandomOffset(), + center.longitude + _getRandomOffset() + clusterManagerLongitudeOffset, + ), + infoWindow: InfoWindow(title: markerIdVal, snippet: '*'), + onTap: () => _onMarkerTapped(markerId), + ); + markers[markerId] = marker; + } + setState(() {}); + } + + double _getRandomOffset() { + return (Random().nextDouble() - 0.5) * _markerOffsetFactor; + } + + void _remove(MarkerId markerId) { + setState(() { + if (markers.containsKey(markerId)) { + markers.remove(markerId); + } + }); + } + + void _changeMarkersAlpha() { + for (final MarkerId markerId in markers.keys) { + final Marker marker = markers[markerId]!; + final double current = marker.alpha; + markers[markerId] = marker.copyWith( + alphaParam: current == _fullyVisibleAlpha + ? _halfVisibleAlpha + : _fullyVisibleAlpha, + ); + } + setState(() {}); + } + + @override + Widget build(BuildContext context) { + final MarkerId? selectedId = selectedMarker; + return Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox( + height: 300.0, + child: ExampleGoogleMap( + onMapCreated: _onMapCreated, + initialCameraPosition: const CameraPosition( + target: LatLng(-33.852, 151.25), + zoom: 11.0, + ), + markers: Set.of(markers.values), + clusterManagers: Set.of(clusterManagers.values), + ), + ), + Column(children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + TextButton( + onPressed: clusterManagers.length >= _clusterManagerMaxCount + ? null + : () => _addClusterManager(), + child: const Text('Add cluster manager'), + ), + TextButton( + onPressed: clusterManagers.isEmpty + ? null + : () => _removeClusterManager(clusterManagers.values.last), + child: const Text('Remove cluster manager'), + ), + ], + ), + Wrap( + alignment: WrapAlignment.spaceEvenly, + children: [ + for (final MapEntry clusterEntry + in clusterManagers.entries) + TextButton( + onPressed: () => _addMarkersToCluster(clusterEntry.value), + child: Text('Add markers to ${clusterEntry.key.value}'), + ), + ], + ), + Wrap( + alignment: WrapAlignment.spaceEvenly, + children: [ + TextButton( + onPressed: selectedId == null + ? null + : () { + _remove(selectedId); + setState(() { + selectedMarker = null; + }); + }, + child: const Text('Remove selected marker'), + ), + TextButton( + onPressed: markers.isEmpty ? null : () => _changeMarkersAlpha(), + child: const Text('Change all markers alpha'), + ), + ], + ), + if (lastCluster != null) + Padding( + padding: const EdgeInsets.all(10), + child: Text( + 'Cluster with ${lastCluster!.count} markers clicked at ${lastCluster!.position}')), + ]), + ], + ); + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/example_google_map.dart b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/example_google_map.dart index 0734731af7c3..a8e19e29e7d2 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/example_google_map.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/example_google_map.dart @@ -87,6 +87,9 @@ class ExampleGoogleMapController { .listen((MapTapEvent e) => _googleMapState.onTap(e.position)); GoogleMapsFlutterPlatform.instance.onLongPress(mapId: mapId).listen( (MapLongPressEvent e) => _googleMapState.onLongPress(e.position)); + GoogleMapsFlutterPlatform.instance + .onClusterTap(mapId: mapId) + .listen((ClusterTapEvent e) => _googleMapState.onClusterTap(e.value)); } /// Updates configuration options of the map user interface. @@ -101,6 +104,13 @@ class ExampleGoogleMapController { .updateMarkers(markerUpdates, mapId: mapId); } + /// Updates cluster manager configuration. + Future _updateClusterManagers( + ClusterManagerUpdates clusterManagerUpdates) { + return GoogleMapsFlutterPlatform.instance + .updateClusterManagers(clusterManagerUpdates, mapId: mapId); + } + /// Updates polygon configuration. Future _updatePolygons(PolygonUpdates polygonUpdates) { return GoogleMapsFlutterPlatform.instance @@ -214,7 +224,6 @@ class ExampleGoogleMap extends StatefulWidget { this.onMapCreated, this.gestureRecognizers = const >{}, this.compassEnabled = true, - this.mapToolbarEnabled = true, this.cameraTargetBounds = CameraTargetBounds.unbounded, this.mapType = MapType.normal, this.minMaxZoomPreference = MinMaxZoomPreference.unbounded, @@ -222,7 +231,6 @@ class ExampleGoogleMap extends StatefulWidget { this.scrollGesturesEnabled = true, this.zoomControlsEnabled = true, this.zoomGesturesEnabled = true, - this.liteModeEnabled = false, this.tiltGesturesEnabled = true, this.myLocationEnabled = false, this.myLocationButtonEnabled = true, @@ -237,6 +245,7 @@ class ExampleGoogleMap extends StatefulWidget { this.polygons = const {}, this.polylines = const {}, this.circles = const {}, + this.clusterManagers = const {}, this.onCameraMoveStarted, this.tileOverlays = const {}, this.onCameraMove, @@ -258,9 +267,6 @@ class ExampleGoogleMap extends StatefulWidget { /// True if the map should show a compass when rotated. final bool compassEnabled; - /// True if the map should show a toolbar when you interact with the map. Android only. - final bool mapToolbarEnabled; - /// Geographical bounding box for the camera target. final CameraTargetBounds cameraTargetBounds; @@ -288,9 +294,6 @@ class ExampleGoogleMap extends StatefulWidget { /// True if the map view should respond to zoom gestures. final bool zoomGesturesEnabled; - /// True if the map view should be in lite mode. Android only. - final bool liteModeEnabled; - /// True if the map view should respond to tilt gestures. final bool tiltGesturesEnabled; @@ -312,6 +315,9 @@ class ExampleGoogleMap extends StatefulWidget { /// Tile overlays to be placed on the map. final Set tileOverlays; + /// Cluster Managers to be placed for the map. + final Set clusterManagers; + /// Called when the camera starts moving. final VoidCallback? onCameraMoveStarted; @@ -371,6 +377,8 @@ class _ExampleGoogleMapState extends State { Map _polygons = {}; Map _polylines = {}; Map _circles = {}; + Map _clusterManagers = + {}; late MapConfiguration _mapConfiguration; @override @@ -390,6 +398,7 @@ class _ExampleGoogleMapState extends State { polygons: widget.polygons, polylines: widget.polylines, circles: widget.circles, + clusterManagers: widget.clusterManagers, ), mapConfiguration: _mapConfiguration, ); @@ -399,6 +408,7 @@ class _ExampleGoogleMapState extends State { void initState() { super.initState(); _mapConfiguration = _configurationFromMapWidget(widget); + _clusterManagers = keyByClusterManagerId(widget.clusterManagers); _markers = keyByMarkerId(widget.markers); _polygons = keyByPolygonId(widget.polygons); _polylines = keyByPolylineId(widget.polylines); @@ -416,6 +426,7 @@ class _ExampleGoogleMapState extends State { void didUpdateWidget(ExampleGoogleMap oldWidget) { super.didUpdateWidget(oldWidget); _updateOptions(); + _updateClusterManagers(); _updateMarkers(); _updatePolygons(); _updatePolylines(); @@ -441,6 +452,13 @@ class _ExampleGoogleMapState extends State { _markers = keyByMarkerId(widget.markers); } + Future _updateClusterManagers() async { + final ExampleGoogleMapController controller = await _controller.future; + unawaited(controller._updateClusterManagers(ClusterManagerUpdates.from( + _clusterManagers.values.toSet(), widget.clusterManagers))); + _clusterManagers = keyByClusterManagerId(widget.clusterManagers); + } + Future _updatePolygons() async { final ExampleGoogleMapController controller = await _controller.future; unawaited(controller._updatePolygons( @@ -518,13 +536,18 @@ class _ExampleGoogleMapState extends State { void onLongPress(LatLng position) { widget.onLongPress?.call(position); } + + void onClusterTap(Cluster cluster) { + final ClusterManager? clusterManager = + _clusterManagers[cluster.clusterManagerId]; + clusterManager?.onClusterTap?.call(cluster); + } } /// Builds a [MapConfiguration] from the given [map]. MapConfiguration _configurationFromMapWidget(ExampleGoogleMap map) { return MapConfiguration( compassEnabled: map.compassEnabled, - mapToolbarEnabled: map.mapToolbarEnabled, cameraTargetBounds: map.cameraTargetBounds, mapType: map.mapType, minMaxZoomPreference: map.minMaxZoomPreference, @@ -534,7 +557,6 @@ MapConfiguration _configurationFromMapWidget(ExampleGoogleMap map) { trackCameraPosition: map.onCameraMove != null, zoomControlsEnabled: map.zoomControlsEnabled, zoomGesturesEnabled: map.zoomGesturesEnabled, - liteModeEnabled: map.liteModeEnabled, myLocationEnabled: map.myLocationEnabled, myLocationButtonEnabled: map.myLocationButtonEnabled, padding: map.padding, diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/lite_mode.dart b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/lite_mode.dart index f7bead951f5d..a70ff98a4e7e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/lite_mode.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/lite_mode.dart @@ -37,7 +37,6 @@ class _LiteModeBody extends StatelessWidget { height: 300.0, child: ExampleGoogleMap( initialCameraPosition: _kInitialPosition, - liteModeEnabled: true, ), ), ), diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/map_ui.dart b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/map_ui.dart index 105676da9ed5..0038ec6f3397 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/map_ui.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/map_ui.dart @@ -45,7 +45,6 @@ class MapUiBodyState extends State { bool _isMapCreated = false; final bool _isMoving = false; bool _compassEnabled = true; - bool _mapToolbarEnabled = true; CameraTargetBounds _cameraTargetBounds = CameraTargetBounds.unbounded; MinMaxZoomPreference _minMaxZoomPreference = MinMaxZoomPreference.unbounded; MapType _mapType = MapType.normal; @@ -83,17 +82,6 @@ class MapUiBodyState extends State { ); } - Widget _mapToolbarToggler() { - return TextButton( - child: Text('${_mapToolbarEnabled ? 'disable' : 'enable'} map toolbar'), - onPressed: () { - setState(() { - _mapToolbarEnabled = !_mapToolbarEnabled; - }); - }, - ); - } - Widget _latLngBoundsToggler() { return TextButton( child: Text( @@ -265,7 +253,6 @@ class MapUiBodyState extends State { onMapCreated: onMapCreated, initialCameraPosition: _kInitialPosition, compassEnabled: _compassEnabled, - mapToolbarEnabled: _mapToolbarEnabled, cameraTargetBounds: _cameraTargetBounds, minMaxZoomPreference: _minMaxZoomPreference, mapType: _mapType, @@ -308,7 +295,6 @@ class MapUiBodyState extends State { Text('camera tilt: ${_position.tilt}'), Text(_isMoving ? '(Camera moving)' : '(Camera idle)'), _compassToggler(), - _mapToolbarToggler(), _latLngBoundsToggler(), _mapTypeCycler(), _zoomBoundsToggler(), diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/place_polygon.dart b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/place_polygon.dart index 889c38d6376b..a1fdafd7a31d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/place_polygon.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/place_polygon.dart @@ -226,7 +226,7 @@ class PlacePolygonBodyState extends State { TextButton( onPressed: (selectedId == null) ? null - : ((polygons[selectedId]!.holes.isNotEmpty) + : (polygons[selectedId]!.holes.isNotEmpty ? null : () => _addHoles(selectedId)), child: const Text('add holes'), @@ -234,7 +234,7 @@ class PlacePolygonBodyState extends State { TextButton( onPressed: (selectedId == null) ? null - : ((polygons[selectedId]!.holes.isEmpty) + : (polygons[selectedId]!.holes.isEmpty ? null : () => _removeHoles(selectedId)), child: const Text('remove holes'), 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 810adc8ee21f..47faec4a495f 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.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: cupertino_icons: ^1.0.5 @@ -18,7 +18,7 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../../../ - google_maps_flutter_platform_interface: ^2.7.0 + google_maps_flutter_platform_interface: ^2.9.0 dev_dependencies: flutter_test: diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/test/fake_google_maps_flutter_platform.dart b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/test/fake_google_maps_flutter_platform.dart index 22447ba5ecad..9ac70ab760fe 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/test/fake_google_maps_flutter_platform.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/test/fake_google_maps_flutter_platform.dart @@ -94,6 +94,15 @@ class FakeGoogleMapsFlutterPlatform extends GoogleMapsFlutterPlatform { await _fakeDelay(); } + @override + Future updateClusterManagers( + ClusterManagerUpdates clusterManagerUpdates, { + required int mapId, + }) async { + mapInstances[mapId]?.clusterManagerUpdates.add(clusterManagerUpdates); + await _fakeDelay(); + } + @override Future clearTileCache( TileOverlayId tileOverlayId, { @@ -241,6 +250,11 @@ class FakeGoogleMapsFlutterPlatform extends GoogleMapsFlutterPlatform { return mapEventStreamController.stream.whereType(); } + @override + Stream onClusterTap({required int mapId}) { + return mapEventStreamController.stream.whereType(); + } + @override void dispose({required int mapId}) { disposed = true; @@ -282,6 +296,8 @@ class PlatformMapStateRecorder { this.mapObjects = const MapObjects(), this.mapConfiguration = const MapConfiguration(), }) { + clusterManagerUpdates.add(ClusterManagerUpdates.from( + const {}, mapObjects.clusterManagers)); markerUpdates.add(MarkerUpdates.from(const {}, mapObjects.markers)); polygonUpdates .add(PolygonUpdates.from(const {}, mapObjects.polygons)); @@ -300,4 +316,6 @@ class PlatformMapStateRecorder { final List polylineUpdates = []; final List circleUpdates = []; final List> tileOverlaySets = >[]; + final List clusterManagerUpdates = + []; } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FGMClusterManagersController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FGMClusterManagersController.h new file mode 100644 index 000000000000..346a1ab9f1c8 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FGMClusterManagersController.h @@ -0,0 +1,56 @@ +// 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 +#import +@import GoogleMapsUtils; + +#import "messages.g.h" + +NS_ASSUME_NONNULL_BEGIN + +/// A controller that manages all of the cluster managers on a map. +@interface FGMClusterManagersController : NSObject + +/// Initializes cluster manager controller. +/// +/// @param callbackHandler A callback handler. +/// @param mapView A map view that will be used to display clustered markers. +- (instancetype)initWithMapView:(GMSMapView *)mapView + callbackHandler:(FGMMapsCallbackApi *)callbackHandler; + +/// Creates cluster managers and initializes them. +/// +/// @param clusterManagersToAdd Array of cluster managers to add. +- (void)addClusterManagers:(NSArray *)clusterManagersToAdd; + +/// Removes requested cluster managers from the controller. +/// +/// @param identifiers Array of cluster manager IDs to remove. +- (void)removeClusterManagersWithIdentifiers:(NSArray *)identifiers; + +/// Returns the cluster managers for the given identifier. +/// +/// @param identifier The identifier of the cluster manager. +/// @return A cluster manager if found; otherwise, nil. +- (nullable GMUClusterManager *)clusterManagerWithIdentifier:(NSString *)identifier; + +/// Returns an array of clusters managed by the cluster manager. +/// +/// @param identifier The identifier of the cluster manager whose clusters are to be retrieved. +/// @return An array of clusters. Returns `nil` only if `error` is populated. +- (nullable NSArray *) + clustersWithIdentifier:(NSString *)identifier + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error; + +/// Called when a cluster marker is tapped on the map. +/// +/// @param cluster The cluster that was tapped on. +- (void)didTapCluster:(GMUStaticCluster *)cluster; + +/// Calls the cluster method of all the cluster managers. +- (void)invokeClusteringForEachClusterManager; +@end + +NS_ASSUME_NONNULL_END diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FGMClusterManagersController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FGMClusterManagersController.m new file mode 100644 index 000000000000..26db81693bde --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FGMClusterManagersController.m @@ -0,0 +1,128 @@ +// 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 "FGMClusterManagersController.h" + +#import "FGMMarkerUserData.h" +#import "FLTGoogleMapJSONConversions.h" + +@interface FGMClusterManagersController () + +/// A dictionary mapping unique cluster manager identifiers to their corresponding cluster managers. +@property(strong, nonatomic) + NSMutableDictionary *clusterManagerIdentifierToManagers; + +/// The callback handler interface for calls to Flutter. +@property(strong, nonatomic) FGMMapsCallbackApi *callbackHandler; + +/// The current map instance on which the cluster managers are operating. +@property(strong, nonatomic) GMSMapView *mapView; + +@end + +@implementation FGMClusterManagersController +- (instancetype)initWithMapView:(GMSMapView *)mapView + callbackHandler:(FGMMapsCallbackApi *)callbackHandler { + self = [super init]; + if (self) { + _callbackHandler = callbackHandler; + _mapView = mapView; + _clusterManagerIdentifierToManagers = [[NSMutableDictionary alloc] init]; + } + return self; +} + +- (void)addClusterManagers:(NSArray *)clusterManagersToAdd { + for (FGMPlatformClusterManager *clusterManager in clusterManagersToAdd) { + NSString *identifier = clusterManager.identifier; + [self addClusterManager:identifier]; + } +} + +- (void)addClusterManager:(NSString *)identifier { + id algorithm = [[GMUNonHierarchicalDistanceBasedAlgorithm alloc] init]; + id iconGenerator = [[GMUDefaultClusterIconGenerator alloc] init]; + id renderer = + [[GMUDefaultClusterRenderer alloc] initWithMapView:self.mapView + clusterIconGenerator:iconGenerator]; + self.clusterManagerIdentifierToManagers[identifier] = + [[GMUClusterManager alloc] initWithMap:self.mapView algorithm:algorithm renderer:renderer]; + ; +} + +- (void)removeClusterManagersWithIdentifiers:(NSArray *)identifiers { + for (NSString *identifier in identifiers) { + GMUClusterManager *clusterManager = + [self.clusterManagerIdentifierToManagers objectForKey:identifier]; + if (!clusterManager) { + continue; + } + [clusterManager clearItems]; + [self.clusterManagerIdentifierToManagers removeObjectForKey:identifier]; + } +} + +- (nullable GMUClusterManager *)clusterManagerWithIdentifier:(NSString *)identifier { + return [self.clusterManagerIdentifierToManagers objectForKey:identifier]; +} + +- (void)invokeClusteringForEachClusterManager { + for (GMUClusterManager *clusterManager in [self.clusterManagerIdentifierToManagers allValues]) { + [clusterManager cluster]; + } +} + +- (nullable NSArray *) + clustersWithIdentifier:(NSString *)identifier + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + GMUClusterManager *clusterManager = + [self.clusterManagerIdentifierToManagers objectForKey:identifier]; + + if (!clusterManager) { + *error = [FlutterError + errorWithCode:@"Invalid clusterManagerId" + message:@"getClusters called with invalid clusterManagerId" + details:[NSString stringWithFormat:@"clusterManagerId was: '%@'", identifier]]; + return nil; + } + + // Ref: + // https://github.com/googlemaps/google-maps-ios-utils/blob/0e7ed81f1bbd9d29e4529c40ae39b0791b0a0eb8/src/Clustering/GMUClusterManager.m#L94. + NSUInteger integralZoom = (NSUInteger)floorf(_mapView.camera.zoom + 0.5f); + NSArray> *clusters = [clusterManager.algorithm clustersAtZoom:integralZoom]; + NSMutableArray *response = + [[NSMutableArray alloc] initWithCapacity:clusters.count]; + for (id cluster in clusters) { + FGMPlatformCluster *platFormCluster = FGMGetPigeonCluster(cluster, identifier); + [response addObject:platFormCluster]; + } + return response; +} + +- (void)didTapCluster:(GMUStaticCluster *)cluster { + NSString *clusterManagerId = [self clusterManagerIdentifierForCluster:cluster]; + if (!clusterManagerId) { + return; + } + FGMPlatformCluster *platFormCluster = FGMGetPigeonCluster(cluster, clusterManagerId); + [self.callbackHandler didTapCluster:platFormCluster + completion:^(FlutterError *_Nullable _){ + }]; +} + +#pragma mark - Private methods + +/// Returns the cluster manager identifier for given cluster. +/// +/// @return The cluster manager identifier if found; otherwise, nil. +- (nullable NSString *)clusterManagerIdentifierForCluster:(GMUStaticCluster *)cluster { + if ([cluster.items.firstObject isKindOfClass:[GMSMarker class]]) { + GMSMarker *firstMarker = (GMSMarker *)cluster.items.firstObject; + return FGMGetClusterManagerIdentifierFromMarker(firstMarker); + } + + return nil; +} + +@end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FGMMarkerUserData.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FGMMarkerUserData.h new file mode 100644 index 000000000000..310455a05658 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FGMMarkerUserData.h @@ -0,0 +1,37 @@ +// 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 + +NS_ASSUME_NONNULL_BEGIN + +/// Defines user data object for markers. +@interface FGMMarkerUserData : NSObject + +/// The identifier of the marker. +@property(nonatomic, copy) NSString *markerIdentifier; + +/// The identifier of the cluster manager. +/// This property is set only if the marker is managed by a cluster manager. +@property(nonatomic, copy, nullable) NSString *clusterManagerIdentifier; + +@end + +/// Associates a marker identifier and optionally a cluster manager identifier with a marker's user +/// data. +extern void FGMSetIdentifiersToMarkerUserData(NSString *markerIdentifier, + NSString *_Nullable clusterManagerIdentifier, + GMSMarker *marker); + +/// Get the marker identifier from marker's user data. +/// +/// @return The marker identifier if found; otherwise, nil. +extern NSString *_Nullable FGMGetMarkerIdentifierFromMarker(GMSMarker *marker); + +/// Get the cluster manager identifier from marker's user data. +/// +/// @return The cluster manager identifier if found; otherwise, nil. +extern NSString *_Nullable FGMGetClusterManagerIdentifierFromMarker(GMSMarker *marker); + +NS_ASSUME_NONNULL_END diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FGMMarkerUserData.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FGMMarkerUserData.m new file mode 100644 index 000000000000..4e8e365c1ec0 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FGMMarkerUserData.m @@ -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. + +#import "FGMMarkerUserData.h" + +@implementation FGMMarkerUserData + +@end + +void FGMSetIdentifiersToMarkerUserData(NSString *markerIdentifier, + NSString *_Nullable clusterManagerIdentifier, + GMSMarker *marker) { + FGMMarkerUserData *userData = [[FGMMarkerUserData alloc] init]; + userData.markerIdentifier = markerIdentifier; + userData.clusterManagerIdentifier = clusterManagerIdentifier; + marker.userData = userData; +}; + +NSString *_Nullable FGMGetMarkerIdentifierFromMarker(GMSMarker *marker) { + if ([marker.userData isKindOfClass:[FGMMarkerUserData class]]) { + FGMMarkerUserData *userData = (FGMMarkerUserData *)marker.userData; + return userData.markerIdentifier; + } + return nil; +}; + +NSString *_Nullable FGMGetClusterManagerIdentifierFromMarker(GMSMarker *marker) { + if ([marker.userData isKindOfClass:[FGMMarkerUserData class]]) { + FGMMarkerUserData *userData = (FGMMarkerUserData *)marker.userData; + return userData.clusterManagerIdentifier; + } + return nil; +}; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapHeatmapController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapHeatmapController.h new file mode 100644 index 000000000000..fb516ad99e73 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapHeatmapController.h @@ -0,0 +1,74 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import +#import +@import GoogleMapsUtils; + +#import "messages.g.h" + +NS_ASSUME_NONNULL_BEGIN + +/// Controller of a single Heatmap on the map. +@interface FLTGoogleMapHeatmapController : NSObject + +/// Initializes an instance of this class with a heatmap tile layer, a map view, and additional +/// configuration options. +/// +/// @param heatmapTileLayer The heatmap tile layer (of type GMUHeatmapTileLayer) that will be used +/// to display heatmap data on the map. +/// @param mapView The map view (of type GMSMapView) where the heatmap layer will be overlaid. +/// @param options A dictionary (NSDictionary) containing any additional options or configuration +/// settings for customizing the heatmap layer. The options dictionary is expected to have the +/// following structure: +/// +/// @code +/// { +/// "heatmapId": NSString, +/// "data": NSArray, // Array of serialized weighted lat/lng +/// "gradient": NSDictionary?, // Serialized heatmap gradient +/// "opacity": NSNumber, +/// "radius": NSNumber, +/// "minimumZoomIntensity": NSNumber, +/// "maximumZoomIntensity": NSNumber +/// } +/// @endcode +/// +/// @return An initialized instance of this class, configured with the specified heatmap tile layer, +/// map view, and additional options. +- (instancetype)initWithHeatmapTileLayer:(GMUHeatmapTileLayer *)heatmapTileLayer + mapView:(GMSMapView *)mapView + options:(NSDictionary *)options; + +/// Removes this heatmap from the map. +- (void)removeHeatmap; + +/// Clears the tile cache in order to visually udpate this heatmap. +- (void)clearTileCache; +@end + +/// Controller of multiple Heatmaps on the map. +@interface FLTHeatmapsController : NSObject + +/// Initializes the controller with a GMSMapView. +- (instancetype)initWithMapView:(GMSMapView *)mapView; + +/// Adds heatmaps to the map. +- (void)addHeatmaps:(NSArray *)heatmapsToAdd; + +/// Updates heatmaps on the map. +- (void)changeHeatmaps:(NSArray *)heatmapsToChange; + +/// Removes heatmaps from the map. +- (void)removeHeatmapsWithIdentifiers:(NSArray *)identifiers; + +/// Returns true if a heatmap with the given identifier exists on the map. +- (BOOL)hasHeatmapWithIdentifier:(NSString *)identifier; + +/// Returns the JSON data of the heatmap with the given identifier. The JSON structure is equivalent +/// to the `options` parameter above. +- (nullable NSDictionary *)heatmapInfoWithIdentifier:(NSString *)identifier; +@end + +NS_ASSUME_NONNULL_END diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapHeatmapController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapHeatmapController.m new file mode 100644 index 000000000000..e3f6aab0274b --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapHeatmapController.m @@ -0,0 +1,166 @@ +// 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 "FLTGoogleMapHeatmapController.h" +#import "FLTGoogleMapJSONConversions.h" +@import GoogleMapsUtils; + +@interface FLTGoogleMapHeatmapController () + +/// The heatmap tile layer this controller handles. +@property(nonatomic, strong) GMUHeatmapTileLayer *heatmapTileLayer; + +/// The GMSMapView to which the heatmaps are added. +@property(nonatomic, weak) GMSMapView *mapView; + +@end + +@implementation FLTGoogleMapHeatmapController +- (instancetype)initWithHeatmapTileLayer:(GMUHeatmapTileLayer *)heatmapTileLayer + mapView:(GMSMapView *)mapView + options:(NSDictionary *)options { + self = [super init]; + if (self) { + _heatmapTileLayer = heatmapTileLayer; + _mapView = mapView; + + [FLTGoogleMapHeatmapController interpretHeatmapOptions:_heatmapTileLayer + mapView:_mapView + options:options]; + } + return self; +} + +- (void)removeHeatmap { + _heatmapTileLayer.map = nil; +} + +- (void)clearTileCache { + [_heatmapTileLayer clearTileCache]; +} + +- (void)interpretHeatmapOptions:(NSDictionary *)data { + [FLTGoogleMapHeatmapController interpretHeatmapOptions:_heatmapTileLayer + mapView:_mapView + options:data]; +} + ++ (void)interpretHeatmapOptions:(GMUHeatmapTileLayer *)heatmapTileLayer + mapView:(GMSMapView *)mapView + options:(NSDictionary *)options { + id weightedData = options[kHeatmapDataKey]; + if ([weightedData isKindOfClass:[NSArray class]]) { + heatmapTileLayer.weightedData = + [FLTGoogleMapJSONConversions weightedDataFromArray:weightedData]; + } + + id gradient = options[kHeatmapGradientKey]; + if ([gradient isKindOfClass:[NSDictionary class]]) { + heatmapTileLayer.gradient = [FLTGoogleMapJSONConversions gradientFromDictionary:gradient]; + } + + id opacity = options[kHeatmapOpacityKey]; + if ([opacity isKindOfClass:[NSNumber class]]) { + heatmapTileLayer.opacity = [opacity doubleValue]; + } + + id radius = options[kHeatmapRadiusKey]; + if ([radius isKindOfClass:[NSNumber class]]) { + heatmapTileLayer.radius = [radius intValue]; + } + + id minimumZoomIntensity = options[kHeatmapMinimumZoomIntensityKey]; + if ([minimumZoomIntensity isKindOfClass:[NSNumber class]]) { + heatmapTileLayer.minimumZoomIntensity = [minimumZoomIntensity intValue]; + } + + id maximumZoomIntensity = options[kHeatmapMaximumZoomIntensityKey]; + if ([maximumZoomIntensity isKindOfClass:[NSNumber class]]) { + heatmapTileLayer.maximumZoomIntensity = [maximumZoomIntensity intValue]; + } + + // The map must be set each time for options to update. + heatmapTileLayer.map = mapView; +} +@end + +@interface FLTHeatmapsController () + +/// A map from heatmapId to the controller that manages it. +@property(nonatomic, strong) + NSMutableDictionary *heatmapIdToController; + +/// The map view owned by GoogmeMapController. +@property(nonatomic, weak) GMSMapView *mapView; + +@end + +@implementation FLTHeatmapsController +- (instancetype)initWithMapView:(GMSMapView *)mapView { + self = [super init]; + if (self) { + _mapView = mapView; + _heatmapIdToController = [NSMutableDictionary dictionary]; + } + return self; +} + +- (void)addHeatmaps:(NSArray *)heatmapsToAdd { + for (FGMPlatformHeatmap *heatmap in heatmapsToAdd) { + NSString *heatmapId = [FLTHeatmapsController identifierForHeatmap:heatmap.json]; + GMUHeatmapTileLayer *heatmapTileLayer = [[GMUHeatmapTileLayer alloc] init]; + FLTGoogleMapHeatmapController *controller = + [[FLTGoogleMapHeatmapController alloc] initWithHeatmapTileLayer:heatmapTileLayer + mapView:_mapView + options:heatmap.json]; + _heatmapIdToController[heatmapId] = controller; + } +} + +- (void)changeHeatmaps:(NSArray *)heatmapsToChange { + for (FGMPlatformHeatmap *heatmap in heatmapsToChange) { + NSString *heatmapId = [FLTHeatmapsController identifierForHeatmap:heatmap.json]; + FLTGoogleMapHeatmapController *controller = _heatmapIdToController[heatmapId]; + + [controller interpretHeatmapOptions:heatmap.json]; + [controller clearTileCache]; + } +} + +- (void)removeHeatmapsWithIdentifiers:(NSArray *)identifiers { + for (NSString *heatmapId in identifiers) { + FLTGoogleMapHeatmapController *controller = _heatmapIdToController[heatmapId]; + if (!controller) { + continue; + } + [controller removeHeatmap]; + [_heatmapIdToController removeObjectForKey:heatmapId]; + } +} + +- (BOOL)hasHeatmapWithIdentifier:(NSString *)identifier { + return _heatmapIdToController[identifier] != nil; +} + +- (nullable NSDictionary *)heatmapInfoWithIdentifier:(NSString *)identifier { + FLTGoogleMapHeatmapController *heatmapController = self.heatmapIdToController[identifier]; + if (heatmapController) { + return @{ + kHeatmapDataKey : [FLTGoogleMapJSONConversions + arrayFromWeightedData:heatmapController.heatmapTileLayer.weightedData], + kHeatmapGradientKey : [FLTGoogleMapJSONConversions + dictionaryFromGradient:heatmapController.heatmapTileLayer.gradient], + kHeatmapOpacityKey : @(heatmapController.heatmapTileLayer.opacity), + kHeatmapRadiusKey : @(heatmapController.heatmapTileLayer.radius), + kHeatmapMinimumZoomIntensityKey : @(heatmapController.heatmapTileLayer.minimumZoomIntensity), + kHeatmapMaximumZoomIntensityKey : @(heatmapController.heatmapTileLayer.maximumZoomIntensity) + }; + } + return nil; +} + ++ (NSString *)identifierForHeatmap:(NSDictionary *)heatmap { + return heatmap[kHeatmapIdKey]; +} +@end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapJSONConversions.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapJSONConversions.h index 1fc8d003d914..ba68ca7a5b5b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapJSONConversions.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapJSONConversions.h @@ -3,27 +3,82 @@ // found in the LICENSE file. #import +#import #import +@import GoogleMapsUtils; + +#import "messages.g.h" NS_ASSUME_NONNULL_BEGIN +/// Returns dict[key], or nil if dict[key] is NSNull. +extern id _Nullable FGMGetValueOrNilFromDict(NSDictionary *dict, NSString *key); + +/// Creates a CGPoint from its Pigeon equivalent. +extern CGPoint FGMGetCGPointForPigeonPoint(FGMPlatformPoint *point); + +/// Converts a CGPoint to its Pigeon equivalent. +extern FGMPlatformPoint *FGMGetPigeonPointForCGPoint(CGPoint point); + +/// Creates a CLLocationCoordinate2D from its Pigeon representation. +extern CLLocationCoordinate2D FGMGetCoordinateForPigeonLatLng(FGMPlatformLatLng *latLng); + +/// Converts a CLLocationCoordinate2D to its Pigeon representation. +extern FGMPlatformLatLng *FGMGetPigeonLatLngForCoordinate(CLLocationCoordinate2D coord); + +/// Creates a GMSCoordinateBounds from its Pigeon representation. +extern GMSCoordinateBounds *FGMGetCoordinateBoundsForPigeonLatLngBounds( + FGMPlatformLatLngBounds *bounds); + +/// Converts a GMSCoordinateBounds to its Pigeon representation. +extern FGMPlatformLatLngBounds *FGMGetPigeonLatLngBoundsForCoordinateBounds( + GMSCoordinateBounds *bounds); + +/// Converts a GMSCameraPosition to its Pigeon representation. +extern FGMPlatformCameraPosition *FGMGetPigeonCameraPositionForPosition( + GMSCameraPosition *position); + +/// Creates a GMSCameraPosition from its Pigeon representation. +extern GMSCameraPosition *FGMGetCameraPositionForPigeonCameraPosition( + FGMPlatformCameraPosition *position); + +/// Creates a GMSMapViewType from its Pigeon representation. +extern GMSMapViewType FGMGetMapViewTypeForPigeonMapType(FGMPlatformMapType type); + +/// Converts a GMUStaticCluster to its Pigeon representation. +extern FGMPlatformCluster *FGMGetPigeonCluster(GMUStaticCluster *cluster, + NSString *clusterManagerIdentifier); + @interface FLTGoogleMapJSONConversions : NSObject +extern NSString *const kHeatmapsToAddKey; +extern NSString *const kHeatmapIdKey; +extern NSString *const kHeatmapDataKey; +extern NSString *const kHeatmapGradientKey; +extern NSString *const kHeatmapOpacityKey; +extern NSString *const kHeatmapRadiusKey; +extern NSString *const kHeatmapMinimumZoomIntensityKey; +extern NSString *const kHeatmapMaximumZoomIntensityKey; +extern NSString *const kHeatmapGradientColorsKey; +extern NSString *const kHeatmapGradientStartPointsKey; +extern NSString *const kHeatmapGradientColorMapSizeKey; + + (CLLocationCoordinate2D)locationFromLatLong:(NSArray *)latlong; + (CGPoint)pointFromArray:(NSArray *)array; + (NSArray *)arrayFromLocation:(CLLocationCoordinate2D)location; + (UIColor *)colorFromRGBA:(NSNumber *)data; ++ (NSNumber *)RGBAFromColor:(UIColor *)color; + (NSArray *)pointsFromLatLongs:(NSArray *)data; + (NSArray *> *)holesFromPointsArray:(NSArray *)data; -+ (nullable NSDictionary *)dictionaryFromPosition: - (nullable GMSCameraPosition *)position; -+ (NSDictionary *)dictionaryFromPoint:(CGPoint)point; -+ (nullable NSDictionary *)dictionaryFromCoordinateBounds:(nullable GMSCoordinateBounds *)bounds; + (nullable GMSCameraPosition *)cameraPostionFromDictionary:(nullable NSDictionary *)channelValue; -+ (CGPoint)pointFromDictionary:(NSDictionary *)dictionary; + (GMSCoordinateBounds *)coordinateBoundsFromLatLongs:(NSArray *)latlongs; -+ (GMSMapViewType)mapViewTypeFromTypeValue:(NSNumber *)value; -+ (nullable GMSCameraUpdate *)cameraUpdateFromChannelValue:(NSArray *)channelValue; ++ (nullable GMSCameraUpdate *)cameraUpdateFromArray:(NSArray *)channelValue; ++ (nullable GMUWeightedLatLng *)weightedLatLngFromArray:(NSArray *)data; ++ (NSArray *)arrayFromWeightedLatLng:(GMUWeightedLatLng *)weightedLatLng; ++ (NSArray *)weightedDataFromArray:(NSArray *> *)data; ++ (NSArray *> *)arrayFromWeightedData:(NSArray *)weightedData; ++ (GMUGradient *)gradientFromDictionary:(NSDictionary *)data; ++ (NSDictionary *)dictionaryFromGradient:(GMUGradient *)gradient; /// Return GMS strokestyle object array populated using the patterns and stroke colors passed in. /// diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapJSONConversions.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapJSONConversions.m index 28307182f2c9..99439c48dd2d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapJSONConversions.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapJSONConversions.m @@ -3,9 +3,104 @@ // found in the LICENSE file. #import "FLTGoogleMapJSONConversions.h" +#import "FGMMarkerUserData.h" + +/// Returns dict[key], or nil if dict[key] is NSNull. +id FGMGetValueOrNilFromDict(NSDictionary *dict, NSString *key) { + id value = dict[key]; + return value == [NSNull null] ? nil : value; +} + +CGPoint FGMGetCGPointForPigeonPoint(FGMPlatformPoint *point) { + return CGPointMake(point.x, point.y); +} + +FGMPlatformPoint *FGMGetPigeonPointForCGPoint(CGPoint point) { + return [FGMPlatformPoint makeWithX:point.x y:point.y]; +} + +CLLocationCoordinate2D FGMGetCoordinateForPigeonLatLng(FGMPlatformLatLng *latLng) { + return CLLocationCoordinate2DMake(latLng.latitude, latLng.longitude); +} + +FGMPlatformLatLng *FGMGetPigeonLatLngForCoordinate(CLLocationCoordinate2D coord) { + return [FGMPlatformLatLng makeWithLatitude:coord.latitude longitude:coord.longitude]; +} + +GMSCoordinateBounds *FGMGetCoordinateBoundsForPigeonLatLngBounds(FGMPlatformLatLngBounds *bounds) { + return [[GMSCoordinateBounds alloc] + initWithCoordinate:FGMGetCoordinateForPigeonLatLng(bounds.northeast) + coordinate:FGMGetCoordinateForPigeonLatLng(bounds.southwest)]; +} + +FGMPlatformLatLngBounds *FGMGetPigeonLatLngBoundsForCoordinateBounds(GMSCoordinateBounds *bounds) { + return + [FGMPlatformLatLngBounds makeWithNortheast:FGMGetPigeonLatLngForCoordinate(bounds.northEast) + southwest:FGMGetPigeonLatLngForCoordinate(bounds.southWest)]; +} + +FGMPlatformCameraPosition *FGMGetPigeonCameraPositionForPosition(GMSCameraPosition *position) { + return [FGMPlatformCameraPosition makeWithBearing:position.bearing + target:FGMGetPigeonLatLngForCoordinate(position.target) + tilt:position.viewingAngle + zoom:position.zoom]; +} + +GMSCameraPosition *FGMGetCameraPositionForPigeonCameraPosition( + FGMPlatformCameraPosition *position) { + return [GMSCameraPosition cameraWithTarget:FGMGetCoordinateForPigeonLatLng(position.target) + zoom:position.zoom + bearing:position.bearing + viewingAngle:position.tilt]; +} + +extern GMSMapViewType FGMGetMapViewTypeForPigeonMapType(FGMPlatformMapType type) { + switch (type) { + case FGMPlatformMapTypeNone: + return kGMSTypeNone; + case FGMPlatformMapTypeNormal: + return kGMSTypeNormal; + case FGMPlatformMapTypeSatellite: + return kGMSTypeSatellite; + case FGMPlatformMapTypeTerrain: + return kGMSTypeTerrain; + case FGMPlatformMapTypeHybrid: + return kGMSTypeHybrid; + } +} + +FGMPlatformCluster *FGMGetPigeonCluster(GMUStaticCluster *cluster, + NSString *clusterManagerIdentifier) { + NSMutableArray *markerIDs = [[NSMutableArray alloc] initWithCapacity:cluster.items.count]; + GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] init]; + + for (GMSMarker *marker in cluster.items) { + [markerIDs addObject:FGMGetMarkerIdentifierFromMarker(marker)]; + bounds = [bounds includingCoordinate:marker.position]; + } + + return [FGMPlatformCluster + makeWithClusterManagerId:clusterManagerIdentifier + position:FGMGetPigeonLatLngForCoordinate(cluster.position) + bounds:FGMGetPigeonLatLngBoundsForCoordinateBounds(bounds) + markerIds:markerIDs]; +} @implementation FLTGoogleMapJSONConversions +// These constants must match the corresponding constants in serialization.dart +NSString *const kHeatmapsToAddKey = @"heatmapsToAdd"; +NSString *const kHeatmapIdKey = @"heatmapId"; +NSString *const kHeatmapDataKey = @"data"; +NSString *const kHeatmapGradientKey = @"gradient"; +NSString *const kHeatmapOpacityKey = @"opacity"; +NSString *const kHeatmapRadiusKey = @"radius"; +NSString *const kHeatmapMinimumZoomIntensityKey = @"minimumZoomIntensity"; +NSString *const kHeatmapMaximumZoomIntensityKey = @"maximumZoomIntensity"; +NSString *const kHeatmapGradientColorsKey = @"colors"; +NSString *const kHeatmapGradientStartPointsKey = @"startPoints"; +NSString *const kHeatmapGradientColorMapSizeKey = @"colorMapSize"; + + (CLLocationCoordinate2D)locationFromLatLong:(NSArray *)latlong { return CLLocationCoordinate2DMake([latlong[0] doubleValue], [latlong[1] doubleValue]); } @@ -26,6 +121,14 @@ + (UIColor *)colorFromRGBA:(NSNumber *)numberColor { alpha:((float)((value & 0xFF000000) >> 24)) / 255.0]; } ++ (NSNumber *)RGBAFromColor:(UIColor *)color { + CGFloat red, green, blue, alpha; + [color getRed:&red green:&green blue:&blue alpha:&alpha]; + unsigned long value = ((unsigned long)(alpha * 255) << 24) | ((unsigned long)(red * 255) << 16) | + ((unsigned long)(green * 255) << 8) | ((unsigned long)(blue * 255)); + return @(value); +} + + (NSArray *)pointsFromLatLongs:(NSArray *)data { NSMutableArray *points = [[NSMutableArray alloc] init]; for (unsigned i = 0; i < [data count]; i++) { @@ -49,35 +152,6 @@ + (UIColor *)colorFromRGBA:(NSNumber *)numberColor { return holes; } -+ (nullable NSDictionary *)dictionaryFromPosition:(GMSCameraPosition *)position { - if (!position) { - return nil; - } - return @{ - @"target" : [FLTGoogleMapJSONConversions arrayFromLocation:[position target]], - @"zoom" : @([position zoom]), - @"bearing" : @([position bearing]), - @"tilt" : @([position viewingAngle]), - }; -} - -+ (NSDictionary *)dictionaryFromPoint:(CGPoint)point { - return @{ - @"x" : @(lroundf(point.x)), - @"y" : @(lroundf(point.y)), - }; -} - -+ (nullable NSDictionary *)dictionaryFromCoordinateBounds:(GMSCoordinateBounds *)bounds { - if (!bounds) { - return nil; - } - return @{ - @"southwest" : [FLTGoogleMapJSONConversions arrayFromLocation:[bounds southWest]], - @"northeast" : [FLTGoogleMapJSONConversions arrayFromLocation:[bounds northEast]], - }; -} - + (nullable GMSCameraPosition *)cameraPostionFromDictionary:(nullable NSDictionary *)data { if (!data) { return nil; @@ -89,24 +163,13 @@ + (nullable GMSCameraPosition *)cameraPostionFromDictionary:(nullable NSDictiona viewingAngle:[data[@"tilt"] doubleValue]]; } -+ (CGPoint)pointFromDictionary:(NSDictionary *)dictionary { - double x = [dictionary[@"x"] doubleValue]; - double y = [dictionary[@"y"] doubleValue]; - return CGPointMake(x, y); -} - + (GMSCoordinateBounds *)coordinateBoundsFromLatLongs:(NSArray *)latlongs { return [[GMSCoordinateBounds alloc] initWithCoordinate:[FLTGoogleMapJSONConversions locationFromLatLong:latlongs[0]] coordinate:[FLTGoogleMapJSONConversions locationFromLatLong:latlongs[1]]]; } -+ (GMSMapViewType)mapViewTypeFromTypeValue:(NSNumber *)typeValue { - int value = [typeValue intValue]; - return (GMSMapViewType)(value == 0 ? 5 : value); -} - -+ (nullable GMSCameraUpdate *)cameraUpdateFromChannelValue:(NSArray *)channelValue { ++ (nullable GMSCameraUpdate *)cameraUpdateFromArray:(NSArray *)channelValue { NSString *update = channelValue[0]; if ([update isEqualToString:@"newCameraPosition"]) { return [GMSCameraUpdate @@ -163,4 +226,69 @@ + (nullable GMSCameraUpdate *)cameraUpdateFromChannelValue:(NSArray *)channelVal return lengths; } + ++ (GMUWeightedLatLng *)weightedLatLngFromArray:(NSArray *)data { + NSAssert(data.count == 2, @"WeightedLatLng data must have length of 2"); + if (data.count != 2) { + return nil; + } + return [[GMUWeightedLatLng alloc] + initWithCoordinate:[FLTGoogleMapJSONConversions locationFromLatLong:data[0]] + intensity:[data[1] doubleValue]]; +} + ++ (NSArray *)arrayFromWeightedLatLng:(GMUWeightedLatLng *)weightedLatLng { + GMSMapPoint point = {weightedLatLng.point.x, weightedLatLng.point.y}; + return @[ + [FLTGoogleMapJSONConversions arrayFromLocation:GMSUnproject(point)], @(weightedLatLng.intensity) + ]; +} + ++ (NSArray *)weightedDataFromArray:(NSArray *> *)data { + NSMutableArray *weightedData = + [[NSMutableArray alloc] initWithCapacity:data.count]; + for (NSArray *item in data) { + GMUWeightedLatLng *weightedLatLng = [FLTGoogleMapJSONConversions weightedLatLngFromArray:item]; + if (weightedLatLng == nil) continue; + [weightedData addObject:weightedLatLng]; + } + + return weightedData; +} + ++ (NSArray *> *)arrayFromWeightedData:(NSArray *)weightedData { + NSMutableArray *data = [[NSMutableArray alloc] initWithCapacity:weightedData.count]; + for (GMUWeightedLatLng *weightedLatLng in weightedData) { + [data addObject:[FLTGoogleMapJSONConversions arrayFromWeightedLatLng:weightedLatLng]]; + } + + return data; +} + ++ (GMUGradient *)gradientFromDictionary:(NSDictionary *)data { + NSArray *colorData = data[kHeatmapGradientColorsKey]; + NSMutableArray *colors = [[NSMutableArray alloc] initWithCapacity:colorData.count]; + for (NSNumber *colorCode in colorData) { + [colors addObject:[FLTGoogleMapJSONConversions colorFromRGBA:colorCode]]; + } + + return [[GMUGradient alloc] initWithColors:colors + startPoints:data[kHeatmapGradientStartPointsKey] + colorMapSize:[data[kHeatmapGradientColorMapSizeKey] intValue]]; +} + ++ (NSDictionary *)dictionaryFromGradient:(GMUGradient *)gradient { + NSMutableArray *colorCodes = + [[NSMutableArray alloc] initWithCapacity:gradient.colors.count]; + for (UIColor *color in gradient.colors) { + [colorCodes addObject:[FLTGoogleMapJSONConversions RGBAFromColor:color]]; + } + + return @{ + kHeatmapGradientColorsKey : colorCodes, + kHeatmapGradientStartPointsKey : gradient.startPoints, + kHeatmapGradientColorMapSizeKey : @(gradient.mapSize) + }; +} + @end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.h index 5dcc66594f18..223de202bfc8 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.h @@ -5,32 +5,36 @@ #import #import +#import "messages.g.h" + NS_ASSUME_NONNULL_BEGIN @interface FLTGoogleMapTileOverlayController : NSObject +/// The layer managed by this controller instance. +@property(readonly, nonatomic) GMSTileLayer *layer; + - (instancetype)initWithTileLayer:(GMSTileLayer *)tileLayer mapView:(GMSMapView *)mapView options:(NSDictionary *)optionsData; - (void)removeTileOverlay; - (void)clearTileCache; -- (NSDictionary *)getTileOverlayInfo; @end @interface FLTTileProviderController : GMSTileLayer @property(copy, nonatomic, readonly) NSString *tileOverlayIdentifier; -- (instancetype)init:(FlutterMethodChannel *)methodChannel - withTileOverlayIdentifier:(NSString *)identifier; +- (instancetype)initWithTileOverlayIdentifier:(NSString *)identifier + callbackHandler:(FGMMapsCallbackApi *)callbackHandler; @end @interface FLTTileOverlaysController : NSObject -- (instancetype)init:(FlutterMethodChannel *)methodChannel - mapView:(GMSMapView *)mapView - registrar:(NSObject *)registrar; -- (void)addTileOverlays:(NSArray *)tileOverlaysToAdd; -- (void)changeTileOverlays:(NSArray *)tileOverlaysToChange; -- (void)removeTileOverlayWithIdentifiers:(NSArray *)identifiers; +- (instancetype)initWithMapView:(GMSMapView *)mapView + callbackHandler:(FGMMapsCallbackApi *)callbackHandler + registrar:(NSObject *)registrar; +- (void)addTileOverlays:(NSArray *)tileOverlaysToAdd; +- (void)changeTileOverlays:(NSArray *)tileOverlaysToChange; +- (void)removeTileOverlayWithIdentifiers:(NSArray *)identifiers; - (void)clearTileCacheWithIdentifier:(NSString *)identifier; -- (nullable NSDictionary *)tileOverlayInfoWithIdentifier:(NSString *)identifier; +- (nullable FLTGoogleMapTileOverlayController *)tileOverlayWithIdentifier:(NSString *)identifier; @end NS_ASSUME_NONNULL_END diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.m index 73eab6c1eadb..9897cd93da64 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.m @@ -34,17 +34,6 @@ - (void)clearTileCache { [self.layer clearTileCache]; } -- (NSDictionary *)getTileOverlayInfo { - NSMutableDictionary *info = [[NSMutableDictionary alloc] init]; - BOOL visible = self.layer.map != nil; - info[@"visible"] = @(visible); - info[@"fadeIn"] = @(self.layer.fadeIn); - float transparency = 1.0 - self.layer.opacity; - info[@"transparency"] = @(transparency); - info[@"zIndex"] = @(self.layer.zIndex); - return info; -} - - (void)setFadeIn:(BOOL)fadeIn { self.layer.fadeIn = fadeIn; } @@ -70,28 +59,28 @@ - (void)interpretTileOverlayOptions:(NSDictionary *)data { if (!data) { return; } - NSNumber *visible = data[@"visible"]; - if (visible != nil && visible != (id)[NSNull null]) { + NSNumber *visible = FGMGetValueOrNilFromDict(data, @"visible"); + if (visible) { [self setVisible:visible.boolValue]; } - NSNumber *transparency = data[@"transparency"]; - if (transparency != nil && transparency != (id)[NSNull null]) { + NSNumber *transparency = FGMGetValueOrNilFromDict(data, @"transparency"); + if (transparency) { [self setTransparency:transparency.floatValue]; } - NSNumber *zIndex = data[@"zIndex"]; - if (zIndex != nil && zIndex != (id)[NSNull null]) { + NSNumber *zIndex = FGMGetValueOrNilFromDict(data, @"zIndex"); + if (zIndex) { [self setZIndex:zIndex.intValue]; } - NSNumber *fadeIn = data[@"fadeIn"]; - if (fadeIn != nil && fadeIn != (id)[NSNull null]) { + NSNumber *fadeIn = FGMGetValueOrNilFromDict(data, @"fadeIn"); + if (fadeIn) { [self setFadeIn:fadeIn.boolValue]; } - NSNumber *tileSize = data[@"tileSize"]; - if (tileSize != nil && tileSize != (id)[NSNull null]) { + NSNumber *tileSize = FGMGetValueOrNilFromDict(data, @"tileSize"); + if (tileSize) { [self setTileSize:tileSize.integerValue]; } } @@ -100,17 +89,17 @@ - (void)interpretTileOverlayOptions:(NSDictionary *)data { @interface FLTTileProviderController () -@property(strong, nonatomic) FlutterMethodChannel *methodChannel; +@property(strong, nonatomic) FGMMapsCallbackApi *callbackHandler; @end @implementation FLTTileProviderController -- (instancetype)init:(FlutterMethodChannel *)methodChannel - withTileOverlayIdentifier:(NSString *)identifier { +- (instancetype)initWithTileOverlayIdentifier:(NSString *)identifier + callbackHandler:(FGMMapsCallbackApi *)callbackHandler { self = [super init]; if (self) { - _methodChannel = methodChannel; + _callbackHandler = callbackHandler; _tileOverlayIdentifier = identifier; } return self; @@ -146,35 +135,23 @@ - (void)requestTileForX:(NSUInteger)x zoom:(NSUInteger)zoom receiver:(id)receiver { dispatch_async(dispatch_get_main_queue(), ^{ - [self.methodChannel invokeMethod:@"tileOverlay#getTile" - arguments:@{ - @"tileOverlayId" : self.tileOverlayIdentifier, - @"x" : @(x), - @"y" : @(y), - @"zoom" : @(zoom) - } - result:^(id _Nullable result) { - UIImage *tileImage; - if ([result isKindOfClass:[NSDictionary class]]) { - FlutterStandardTypedData *typedData = (FlutterStandardTypedData *)result[@"data"]; - if (typedData == nil) { - tileImage = kGMSTileLayerNoTile; - } else { - tileImage = [self handleResultTile:[UIImage imageWithData:typedData.data]]; - } - } else { - if ([result isKindOfClass:[FlutterError class]]) { - FlutterError *error = (FlutterError *)result; - NSLog(@"Can't get tile: errorCode = %@, errorMessage = %@, details = %@", - [error code], [error message], [error details]); - } - if ([result isKindOfClass:[FlutterMethodNotImplemented class]]) { - NSLog(@"Can't get tile: notImplemented"); - } - tileImage = kGMSTileLayerNoTile; - } - [receiver receiveTileWithX:x y:y zoom:zoom image:tileImage]; - }]; + [self.callbackHandler + tileWithOverlayIdentifier:self.tileOverlayIdentifier + location:[FGMPlatformPoint makeWithX:x y:y] + zoom:zoom + completion:^(FGMPlatformTile *_Nullable tile, + FlutterError *_Nullable error) { + FlutterStandardTypedData *typedData = tile.data; + UIImage *tileImage = + typedData + ? [self handleResultTile:[UIImage imageWithData:typedData.data]] + : kGMSTileLayerNoTile; + if (error) { + NSLog(@"Can't get tile: errorCode = %@, errorMessage = %@, details = %@", + [error code], [error message], [error details]); + } + [receiver receiveTileWithX:x y:y zoom:zoom image:tileImage]; + }]; }); } @@ -182,52 +159,50 @@ - (void)requestTileForX:(NSUInteger)x @interface FLTTileOverlaysController () -@property(strong, nonatomic) NSMutableDictionary *tileOverlayIdentifierToController; -@property(strong, nonatomic) FlutterMethodChannel *methodChannel; +@property(strong, nonatomic) NSMutableDictionary + *tileOverlayIdentifierToController; +@property(strong, nonatomic) FGMMapsCallbackApi *callbackHandler; @property(weak, nonatomic) GMSMapView *mapView; @end @implementation FLTTileOverlaysController -- (instancetype)init:(FlutterMethodChannel *)methodChannel - mapView:(GMSMapView *)mapView - registrar:(NSObject *)registrar { +- (instancetype)initWithMapView:(GMSMapView *)mapView + callbackHandler:(FGMMapsCallbackApi *)callbackHandler + registrar:(NSObject *)registrar { self = [super init]; if (self) { - _methodChannel = methodChannel; + _callbackHandler = callbackHandler; _mapView = mapView; _tileOverlayIdentifierToController = [[NSMutableDictionary alloc] init]; } return self; } -- (void)addTileOverlays:(NSArray *)tileOverlaysToAdd { - for (NSDictionary *tileOverlay in tileOverlaysToAdd) { - NSString *identifier = [FLTTileOverlaysController identifierForTileOverlay:tileOverlay]; +- (void)addTileOverlays:(NSArray *)tileOverlaysToAdd { + for (FGMPlatformTileOverlay *tileOverlay in tileOverlaysToAdd) { + NSString *identifier = [FLTTileOverlaysController identifierForTileOverlay:tileOverlay.json]; FLTTileProviderController *tileProvider = - [[FLTTileProviderController alloc] init:self.methodChannel - withTileOverlayIdentifier:identifier]; + [[FLTTileProviderController alloc] initWithTileOverlayIdentifier:identifier + callbackHandler:self.callbackHandler]; FLTGoogleMapTileOverlayController *controller = [[FLTGoogleMapTileOverlayController alloc] initWithTileLayer:tileProvider mapView:self.mapView - options:tileOverlay]; + options:tileOverlay.json]; self.tileOverlayIdentifierToController[identifier] = controller; } } -- (void)changeTileOverlays:(NSArray *)tileOverlaysToChange { - for (NSDictionary *tileOverlay in tileOverlaysToChange) { - NSString *identifier = [FLTTileOverlaysController identifierForTileOverlay:tileOverlay]; +- (void)changeTileOverlays:(NSArray *)tileOverlaysToChange { + for (FGMPlatformTileOverlay *tileOverlay in tileOverlaysToChange) { + NSString *identifier = [FLTTileOverlaysController identifierForTileOverlay:tileOverlay.json]; FLTGoogleMapTileOverlayController *controller = self.tileOverlayIdentifierToController[identifier]; - if (!controller) { - continue; - } - [controller interpretTileOverlayOptions:tileOverlay]; + [controller interpretTileOverlayOptions:tileOverlay.json]; } } -- (void)removeTileOverlayWithIdentifiers:(NSArray *)identifiers { +- (void)removeTileOverlayWithIdentifiers:(NSArray *)identifiers { for (NSString *identifier in identifiers) { FLTGoogleMapTileOverlayController *controller = self.tileOverlayIdentifierToController[identifier]; @@ -242,17 +217,11 @@ - (void)removeTileOverlayWithIdentifiers:(NSArray *)identifiers { - (void)clearTileCacheWithIdentifier:(NSString *)identifier { FLTGoogleMapTileOverlayController *controller = self.tileOverlayIdentifierToController[identifier]; - if (!controller) { - return; - } [controller clearTileCache]; } -- (nullable NSDictionary *)tileOverlayInfoWithIdentifier:(NSString *)identifier { - if (self.tileOverlayIdentifierToController[identifier] == nil) { - return nil; - } - return [self.tileOverlayIdentifierToController[identifier] getTileOverlayInfo]; +- (nullable FLTGoogleMapTileOverlayController *)tileOverlayWithIdentifier:(NSString *)identifier { + return self.tileOverlayIdentifierToController[identifier]; } + (NSString *)identifierForTileOverlay:(NSDictionary *)tileOverlay { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapsPlugin.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapsPlugin.h index 26f69eaf3882..cc69bcd39f2e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapsPlugin.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapsPlugin.h @@ -4,6 +4,8 @@ #import #import + +#import "FGMClusterManagersController.h" #import "GoogleMapCircleController.h" #import "GoogleMapController.h" #import "GoogleMapMarkerController.h" diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapCircleController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapCircleController.h index 6b67760fdaff..c40340e08db4 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapCircleController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapCircleController.h @@ -5,6 +5,8 @@ #import #import +#import "messages.g.h" + // Defines circle controllable by Flutter. @interface FLTGoogleMapCircleController : NSObject - (instancetype)initCircleWithPosition:(CLLocationCoordinate2D)position @@ -16,12 +18,12 @@ @end @interface FLTCirclesController : NSObject -- (instancetype)init:(FlutterMethodChannel *)methodChannel - mapView:(GMSMapView *)mapView - registrar:(NSObject *)registrar; -- (void)addCircles:(NSArray *)circlesToAdd; -- (void)changeCircles:(NSArray *)circlesToChange; -- (void)removeCircleWithIdentifiers:(NSArray *)identifiers; +- (instancetype)initWithMapView:(GMSMapView *)mapView + callbackHandler:(FGMMapsCallbackApi *)callbackHandler + registrar:(NSObject *)registrar; +- (void)addCircles:(NSArray *)circlesToAdd; +- (void)changeCircles:(NSArray *)circlesToChange; +- (void)removeCirclesWithIdentifiers:(NSArray *)identifiers; - (void)didTapCircleWithIdentifier:(NSString *)identifier; - (bool)hasCircleWithIdentifier:(NSString *)identifier; @end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapCircleController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapCircleController.m index 53bf69075c95..ca71d3150221 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapCircleController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapCircleController.m @@ -60,43 +60,43 @@ - (void)setFillColor:(UIColor *)color { } - (void)interpretCircleOptions:(NSDictionary *)data { - NSNumber *consumeTapEvents = data[@"consumeTapEvents"]; - if (consumeTapEvents && consumeTapEvents != (id)[NSNull null]) { + NSNumber *consumeTapEvents = FGMGetValueOrNilFromDict(data, @"consumeTapEvents"); + if (consumeTapEvents) { [self setConsumeTapEvents:consumeTapEvents.boolValue]; } - NSNumber *visible = data[@"visible"]; - if (visible && visible != (id)[NSNull null]) { + NSNumber *visible = FGMGetValueOrNilFromDict(data, @"visible"); + if (visible) { [self setVisible:[visible boolValue]]; } - NSNumber *zIndex = data[@"zIndex"]; - if (zIndex && zIndex != (id)[NSNull null]) { + NSNumber *zIndex = FGMGetValueOrNilFromDict(data, @"zIndex"); + if (zIndex) { [self setZIndex:[zIndex intValue]]; } - NSArray *center = data[@"center"]; - if (center && center != (id)[NSNull null]) { + NSArray *center = FGMGetValueOrNilFromDict(data, @"center"); + if (center) { [self setCenter:[FLTGoogleMapJSONConversions locationFromLatLong:center]]; } - NSNumber *radius = data[@"radius"]; - if (radius && radius != (id)[NSNull null]) { + NSNumber *radius = FGMGetValueOrNilFromDict(data, @"radius"); + if (radius) { [self setRadius:[radius floatValue]]; } - NSNumber *strokeColor = data[@"strokeColor"]; - if (strokeColor && strokeColor != (id)[NSNull null]) { + NSNumber *strokeColor = FGMGetValueOrNilFromDict(data, @"strokeColor"); + if (strokeColor) { [self setStrokeColor:[FLTGoogleMapJSONConversions colorFromRGBA:strokeColor]]; } - NSNumber *strokeWidth = data[@"strokeWidth"]; - if (strokeWidth && strokeWidth != (id)[NSNull null]) { + NSNumber *strokeWidth = FGMGetValueOrNilFromDict(data, @"strokeWidth"); + if (strokeWidth) { [self setStrokeWidth:[strokeWidth intValue]]; } - NSNumber *fillColor = data[@"fillColor"]; - if (fillColor && fillColor != (id)[NSNull null]) { + NSNumber *fillColor = FGMGetValueOrNilFromDict(data, @"fillColor"); + if (fillColor) { [self setFillColor:[FLTGoogleMapJSONConversions colorFromRGBA:fillColor]]; } } @@ -105,7 +105,7 @@ - (void)interpretCircleOptions:(NSDictionary *)data { @interface FLTCirclesController () -@property(strong, nonatomic) FlutterMethodChannel *methodChannel; +@property(strong, nonatomic) FGMMapsCallbackApi *callbackHandler; @property(weak, nonatomic) GMSMapView *mapView; @property(strong, nonatomic) NSMutableDictionary *circleIdToController; @@ -113,45 +113,42 @@ @interface FLTCirclesController () @implementation FLTCirclesController -- (instancetype)init:(FlutterMethodChannel *)methodChannel - mapView:(GMSMapView *)mapView - registrar:(NSObject *)registrar { +- (instancetype)initWithMapView:(GMSMapView *)mapView + callbackHandler:(FGMMapsCallbackApi *)callbackHandler + registrar:(NSObject *)registrar { self = [super init]; if (self) { - _methodChannel = methodChannel; + _callbackHandler = callbackHandler; _mapView = mapView; _circleIdToController = [NSMutableDictionary dictionaryWithCapacity:1]; } return self; } -- (void)addCircles:(NSArray *)circlesToAdd { - for (NSDictionary *circle in circlesToAdd) { - CLLocationCoordinate2D position = [FLTCirclesController getPosition:circle]; - CLLocationDistance radius = [FLTCirclesController getRadius:circle]; - NSString *circleId = [FLTCirclesController getCircleId:circle]; +- (void)addCircles:(NSArray *)circlesToAdd { + for (FGMPlatformCircle *circle in circlesToAdd) { + CLLocationCoordinate2D position = [FLTCirclesController getPosition:circle.json]; + CLLocationDistance radius = [FLTCirclesController getRadius:circle.json]; + NSString *circleId = [FLTCirclesController getCircleId:circle.json]; FLTGoogleMapCircleController *controller = [[FLTGoogleMapCircleController alloc] initCircleWithPosition:position radius:radius circleId:circleId mapView:self.mapView - options:circle]; + options:circle.json]; self.circleIdToController[circleId] = controller; } } -- (void)changeCircles:(NSArray *)circlesToChange { - for (NSDictionary *circle in circlesToChange) { - NSString *circleId = [FLTCirclesController getCircleId:circle]; +- (void)changeCircles:(NSArray *)circlesToChange { + for (FGMPlatformCircle *circle in circlesToChange) { + NSString *circleId = [FLTCirclesController getCircleId:circle.json]; FLTGoogleMapCircleController *controller = self.circleIdToController[circleId]; - if (!controller) { - continue; - } - [controller interpretCircleOptions:circle]; + [controller interpretCircleOptions:circle.json]; } } -- (void)removeCircleWithIdentifiers:(NSArray *)identifiers { +- (void)removeCirclesWithIdentifiers:(NSArray *)identifiers { for (NSString *identifier in identifiers) { FLTGoogleMapCircleController *controller = self.circleIdToController[identifier]; if (!controller) { @@ -177,7 +174,9 @@ - (void)didTapCircleWithIdentifier:(NSString *)identifier { if (!controller) { return; } - [self.methodChannel invokeMethod:@"circle#onTap" arguments:@{@"circleId" : identifier}]; + [self.callbackHandler didTapCircleWithIdentifier:identifier + completion:^(FlutterError *_Nullable _){ + }]; } + (CLLocationCoordinate2D)getPosition:(NSDictionary *)circle { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.h index d1069ac16b39..a2b75d74c75d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.h @@ -4,10 +4,13 @@ #import #import + +#import "FGMClusterManagersController.h" #import "GoogleMapCircleController.h" #import "GoogleMapMarkerController.h" #import "GoogleMapPolygonController.h" #import "GoogleMapPolylineController.h" +#import "messages.g.h" NS_ASSUME_NONNULL_BEGIN @@ -15,12 +18,10 @@ NS_ASSUME_NONNULL_BEGIN @interface FLTGoogleMapController : NSObject - (instancetype)initWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId - arguments:(nullable id)args + creationParameters:(FGMPlatformMapViewCreationParams *)creationParameters registrar:(NSObject *)registrar; - (void)showAtOrigin:(CGPoint)origin; - (void)hide; -- (void)animateWithCameraUpdate:(GMSCameraUpdate *)cameraUpdate; -- (void)moveWithCameraUpdate:(GMSCameraUpdate *)cameraUpdate; - (nullable GMSCameraPosition *)cameraPosition; @end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.m index 4c747f3eeba0..8f913c464219 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.m @@ -2,9 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +@import GoogleMapsUtils; + #import "GoogleMapController.h" + +#import "FGMMarkerUserData.h" +#import "FLTGoogleMapHeatmapController.h" #import "FLTGoogleMapJSONConversions.h" #import "FLTGoogleMapTileOverlayController.h" +#import "messages.g.h" #pragma mark - Conversion of JSON-like values sent via platform channels. Forward declarations. @@ -28,7 +34,7 @@ - (instancetype)initWithRegistrar:(NSObject *)registrar } - (NSObject *)createArgsCodec { - return [FlutterStandardMessageCodec sharedInstance]; + return FGMGetMessagesCodec(); } - (NSObject *)createWithFrame:(CGRect)frame @@ -40,7 +46,7 @@ - (instancetype)initWithRegistrar:(NSObject *)registrar return [[FLTGoogleMapController alloc] initWithFrame:frame viewIdentifier:viewId - arguments:args + creationParameters:args registrar:self.registrar]; } @@ -56,22 +62,82 @@ - (instancetype)initWithRegistrar:(NSObject *)registrar @end +#pragma mark - + +/// Implementation of the Pigeon maps API. +/// +/// This is a separate object from the maps controller because the Pigeon API registration keeps a +/// strong reference to the implementor, but as the FlutterPlatformView, the lifetime of the +/// FLTGoogleMapController instance is what needs to trigger Pigeon unregistration, so can't be +/// the target of the registration. +@interface FGMMapCallHandler : NSObject +- (instancetype)initWithMapController:(nonnull FLTGoogleMapController *)controller + messenger:(NSObject *)messenger + pigeonSuffix:(NSString *)suffix; +@end + +/// Private declarations. +// This is separate in case the above is made public in the future (e.g., for unit testing). +@interface FGMMapCallHandler () +/// The map controller this inspector corresponds to. +@property(nonatomic, weak) FLTGoogleMapController *controller; +/// The messenger this instance was registered with by Pigeon. +@property(nonatomic, copy) NSObject *messenger; +/// The suffix this instance was registered under with Pigeon. +@property(nonatomic, copy) NSString *pigeonSuffix; +@end + +#pragma mark - + +/// Implementation of the Pigeon maps inspector API. +/// +/// This is a separate object from the maps controller because the Pigeon API registration keeps a +/// strong reference to the implementor, but as the FlutterPlatformView, the lifetime of the +/// FLTGoogleMapController instance is what needs to trigger Pigeon unregistration, so can't be +/// the target of the registration. +@interface FGMMapInspector : NSObject +- (instancetype)initWithMapController:(nonnull FLTGoogleMapController *)controller + messenger:(NSObject *)messenger + pigeonSuffix:(NSString *)suffix; +@end + +/// Private declarations. +// This is separate in case the above is made public in the future (e.g., for unit testing). +@interface FGMMapInspector () +/// The map controller this inspector corresponds to. +@property(nonatomic, weak) FLTGoogleMapController *controller; +/// The messenger this instance was registered with by Pigeon. +@property(nonatomic, copy) NSObject *messenger; +/// The suffix this instance was registered under with Pigeon. +@property(nonatomic, copy) NSString *pigeonSuffix; +@end + +#pragma mark - + @interface FLTGoogleMapController () @property(nonatomic, strong) GMSMapView *mapView; -@property(nonatomic, strong) FlutterMethodChannel *channel; +@property(nonatomic, strong) FGMMapsCallbackApi *dartCallbackHandler; @property(nonatomic, assign) BOOL trackCameraPosition; @property(nonatomic, weak) NSObject *registrar; +@property(nonatomic, strong) FGMClusterManagersController *clusterManagersController; @property(nonatomic, strong) FLTMarkersController *markersController; @property(nonatomic, strong) FLTPolygonsController *polygonsController; @property(nonatomic, strong) FLTPolylinesController *polylinesController; @property(nonatomic, strong) FLTCirclesController *circlesController; + +// The controller that handles heatmaps +@property(nonatomic, strong) FLTHeatmapsController *heatmapsController; @property(nonatomic, strong) FLTTileOverlaysController *tileOverlaysController; // The resulting error message, if any, from the last attempt to set the map style. // This is used to provide access to errors after the fact, since the map style is generally set at // creation time and there's no mechanism to return non-fatal error details during platform view // initialization. @property(nonatomic, copy) NSString *styleError; +// The main Pigeon API implementation, separate to avoid lifetime extension. +@property(nonatomic, strong) FGMMapCallHandler *callHandler; +// The inspector API implementation, separate to avoid lifetime extension. +@property(nonatomic, strong) FGMMapInspector *inspector; @end @@ -79,27 +145,30 @@ @implementation FLTGoogleMapController - (instancetype)initWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId - arguments:(id _Nullable)args + creationParameters:(FGMPlatformMapViewCreationParams *)creationParameters registrar:(NSObject *)registrar { GMSCameraPosition *camera = - [FLTGoogleMapJSONConversions cameraPostionFromDictionary:args[@"initialCameraPosition"]]; + FGMGetCameraPositionForPigeonCameraPosition(creationParameters.initialCameraPosition); GMSMapViewOptions *options = [[GMSMapViewOptions alloc] init]; options.frame = frame; options.camera = camera; - NSString *cloudMapId = args[@"options"][@"cloudMapId"]; + NSString *cloudMapId = creationParameters.mapConfiguration.cloudMapId; if (cloudMapId) { options.mapID = [GMSMapID mapIDWithIdentifier:cloudMapId]; } GMSMapView *mapView = [[GMSMapView alloc] initWithOptions:options]; - return [self initWithMapView:mapView viewIdentifier:viewId arguments:args registrar:registrar]; + return [self initWithMapView:mapView + viewIdentifier:viewId + creationParameters:creationParameters + registrar:registrar]; } - (instancetype)initWithMapView:(GMSMapView *_Nonnull)mapView viewIdentifier:(int64_t)viewId - arguments:(id _Nullable)args + creationParameters:(FGMPlatformMapViewCreationParams *)creationParameters registrar:(NSObject *_Nonnull)registrar { if (self = [super init]) { _mapView = mapView; @@ -107,61 +176,66 @@ - (instancetype)initWithMapView:(GMSMapView *_Nonnull)mapView _mapView.accessibilityElementsHidden = NO; // TODO(cyanglaz): avoid sending message to self in the middle of the init method. // https://github.com/flutter/flutter/issues/104121 - [self interpretMapOptions:args[@"options"]]; - NSString *channelName = - [NSString stringWithFormat:@"plugins.flutter.dev/google_maps_ios_%lld", viewId]; - _channel = [FlutterMethodChannel methodChannelWithName:channelName - binaryMessenger:registrar.messenger]; - __weak __typeof__(self) weakSelf = self; - [_channel setMethodCallHandler:^(FlutterMethodCall *call, FlutterResult result) { - if (weakSelf) { - [weakSelf onMethodCall:call result:result]; - } - }]; - _mapView.delegate = weakSelf; + [self interpretMapConfiguration:creationParameters.mapConfiguration]; + NSString *pigeonSuffix = [NSString stringWithFormat:@"%lld", viewId]; + _dartCallbackHandler = [[FGMMapsCallbackApi alloc] initWithBinaryMessenger:registrar.messenger + messageChannelSuffix:pigeonSuffix]; + _mapView.delegate = self; _mapView.paddingAdjustmentBehavior = kGMSMapViewPaddingAdjustmentBehaviorNever; _registrar = registrar; - _markersController = [[FLTMarkersController alloc] initWithMethodChannel:_channel - mapView:_mapView - registrar:registrar]; - _polygonsController = [[FLTPolygonsController alloc] init:_channel - mapView:_mapView - registrar:registrar]; - _polylinesController = [[FLTPolylinesController alloc] init:_channel - mapView:_mapView - registrar:registrar]; - _circlesController = [[FLTCirclesController alloc] init:_channel - mapView:_mapView - registrar:registrar]; - _tileOverlaysController = [[FLTTileOverlaysController alloc] init:_channel - mapView:_mapView - registrar:registrar]; - id markersToAdd = args[@"markersToAdd"]; - if ([markersToAdd isKindOfClass:[NSArray class]]) { - [_markersController addMarkers:markersToAdd]; - } - id polygonsToAdd = args[@"polygonsToAdd"]; - if ([polygonsToAdd isKindOfClass:[NSArray class]]) { - [_polygonsController addPolygons:polygonsToAdd]; - } - id polylinesToAdd = args[@"polylinesToAdd"]; - if ([polylinesToAdd isKindOfClass:[NSArray class]]) { - [_polylinesController addPolylines:polylinesToAdd]; - } - id circlesToAdd = args[@"circlesToAdd"]; - if ([circlesToAdd isKindOfClass:[NSArray class]]) { - [_circlesController addCircles:circlesToAdd]; - } - id tileOverlaysToAdd = args[@"tileOverlaysToAdd"]; - if ([tileOverlaysToAdd isKindOfClass:[NSArray class]]) { - [_tileOverlaysController addTileOverlays:tileOverlaysToAdd]; - } + _clusterManagersController = + [[FGMClusterManagersController alloc] initWithMapView:_mapView + callbackHandler:_dartCallbackHandler]; + _markersController = [[FLTMarkersController alloc] initWithMapView:_mapView + callbackHandler:_dartCallbackHandler + clusterManagersController:_clusterManagersController + registrar:registrar]; + _polygonsController = [[FLTPolygonsController alloc] initWithMapView:_mapView + callbackHandler:_dartCallbackHandler + registrar:registrar]; + _polylinesController = [[FLTPolylinesController alloc] initWithMapView:_mapView + callbackHandler:_dartCallbackHandler + registrar:registrar]; + _circlesController = [[FLTCirclesController alloc] initWithMapView:_mapView + callbackHandler:_dartCallbackHandler + registrar:registrar]; + _heatmapsController = [[FLTHeatmapsController alloc] initWithMapView:_mapView]; + _tileOverlaysController = + [[FLTTileOverlaysController alloc] initWithMapView:_mapView + callbackHandler:_dartCallbackHandler + registrar:registrar]; + [_clusterManagersController addClusterManagers:creationParameters.initialClusterManagers]; + [_markersController addMarkers:creationParameters.initialMarkers]; + [_polygonsController addPolygons:creationParameters.initialPolygons]; + [_polylinesController addPolylines:creationParameters.initialPolylines]; + [_circlesController addCircles:creationParameters.initialCircles]; + [_heatmapsController addHeatmaps:creationParameters.initialHeatmaps]; + [_tileOverlaysController addTileOverlays:creationParameters.initialTileOverlays]; + + // Invoke clustering after markers are added. + [_clusterManagersController invokeClusteringForEachClusterManager]; [_mapView addObserver:self forKeyPath:@"frame" options:0 context:nil]; + + _callHandler = [[FGMMapCallHandler alloc] initWithMapController:self + messenger:registrar.messenger + pigeonSuffix:pigeonSuffix]; + SetUpFGMMapsApiWithSuffix(registrar.messenger, _callHandler, pigeonSuffix); + _inspector = [[FGMMapInspector alloc] initWithMapController:self + messenger:registrar.messenger + pigeonSuffix:pigeonSuffix]; + SetUpFGMMapsInspectorApiWithSuffix(registrar.messenger, _inspector, pigeonSuffix); } return self; } +- (void)dealloc { + // Unregister the API implementations so that they can be released; the registration created an + // owning reference. + SetUpFGMMapsApiWithSuffix(_callHandler.messenger, nil, _callHandler.pigeonSuffix); + SetUpFGMMapsInspectorApiWithSuffix(_inspector.messenger, nil, _inspector.pigeonSuffix); +} + - (UIView *)view { return self.mapView; } @@ -187,228 +261,6 @@ - (void)observeValueForKeyPath:(NSString *)keyPath } } -- (void)onMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { - if ([call.method isEqualToString:@"map#show"]) { - [self showAtOrigin:CGPointMake([call.arguments[@"x"] doubleValue], - [call.arguments[@"y"] doubleValue])]; - result(nil); - } else if ([call.method isEqualToString:@"map#hide"]) { - [self hide]; - result(nil); - } else if ([call.method isEqualToString:@"camera#animate"]) { - [self - animateWithCameraUpdate:[FLTGoogleMapJSONConversions - cameraUpdateFromChannelValue:call.arguments[@"cameraUpdate"]]]; - result(nil); - } else if ([call.method isEqualToString:@"camera#move"]) { - [self moveWithCameraUpdate:[FLTGoogleMapJSONConversions - cameraUpdateFromChannelValue:call.arguments[@"cameraUpdate"]]]; - result(nil); - } else if ([call.method isEqualToString:@"map#update"]) { - [self interpretMapOptions:call.arguments[@"options"]]; - result([FLTGoogleMapJSONConversions dictionaryFromPosition:[self cameraPosition]]); - } else if ([call.method isEqualToString:@"map#getVisibleRegion"]) { - if (self.mapView != nil) { - GMSVisibleRegion visibleRegion = self.mapView.projection.visibleRegion; - GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] initWithRegion:visibleRegion]; - result([FLTGoogleMapJSONConversions dictionaryFromCoordinateBounds:bounds]); - } else { - result([FlutterError errorWithCode:@"GoogleMap uninitialized" - message:@"getVisibleRegion called prior to map initialization" - details:nil]); - } - } else if ([call.method isEqualToString:@"map#getScreenCoordinate"]) { - if (self.mapView != nil) { - CLLocationCoordinate2D location = - [FLTGoogleMapJSONConversions locationFromLatLong:call.arguments]; - CGPoint point = [self.mapView.projection pointForCoordinate:location]; - result([FLTGoogleMapJSONConversions dictionaryFromPoint:point]); - } else { - result([FlutterError errorWithCode:@"GoogleMap uninitialized" - message:@"getScreenCoordinate called prior to map initialization" - details:nil]); - } - } else if ([call.method isEqualToString:@"map#getLatLng"]) { - if (self.mapView != nil && call.arguments) { - CGPoint point = [FLTGoogleMapJSONConversions pointFromDictionary:call.arguments]; - CLLocationCoordinate2D latlng = [self.mapView.projection coordinateForPoint:point]; - result([FLTGoogleMapJSONConversions arrayFromLocation:latlng]); - } else { - result([FlutterError errorWithCode:@"GoogleMap uninitialized" - message:@"getLatLng called prior to map initialization" - details:nil]); - } - } else if ([call.method isEqualToString:@"map#waitForMap"]) { - result(nil); - } else if ([call.method isEqualToString:@"map#takeSnapshot"]) { - if (self.mapView != nil) { - UIGraphicsImageRenderer *renderer = - [[UIGraphicsImageRenderer alloc] initWithSize:self.mapView.bounds.size]; - // For some unknown reason mapView.layer::renderInContext API returns a blank image on iOS 17. - // So we have to use drawViewHierarchyInRect API. - UIImage *image = [renderer imageWithActions:^(UIGraphicsImageRendererContext *context) { - [self.mapView drawViewHierarchyInRect:self.mapView.bounds afterScreenUpdates:YES]; - }]; - result([FlutterStandardTypedData typedDataWithBytes:UIImagePNGRepresentation(image)]); - } else { - result([FlutterError errorWithCode:@"GoogleMap uninitialized" - message:@"takeSnapshot called prior to map initialization" - details:nil]); - } - } else if ([call.method isEqualToString:@"markers#update"]) { - id markersToAdd = call.arguments[@"markersToAdd"]; - if ([markersToAdd isKindOfClass:[NSArray class]]) { - [self.markersController addMarkers:markersToAdd]; - } - id markersToChange = call.arguments[@"markersToChange"]; - if ([markersToChange isKindOfClass:[NSArray class]]) { - [self.markersController changeMarkers:markersToChange]; - } - id markerIdsToRemove = call.arguments[@"markerIdsToRemove"]; - if ([markerIdsToRemove isKindOfClass:[NSArray class]]) { - [self.markersController removeMarkersWithIdentifiers:markerIdsToRemove]; - } - result(nil); - } else if ([call.method isEqualToString:@"markers#showInfoWindow"]) { - id markerId = call.arguments[@"markerId"]; - if ([markerId isKindOfClass:[NSString class]]) { - [self.markersController showMarkerInfoWindowWithIdentifier:markerId result:result]; - } else { - result([FlutterError errorWithCode:@"Invalid markerId" - message:@"showInfoWindow called with invalid markerId" - details:nil]); - } - } else if ([call.method isEqualToString:@"markers#hideInfoWindow"]) { - id markerId = call.arguments[@"markerId"]; - if ([markerId isKindOfClass:[NSString class]]) { - [self.markersController hideMarkerInfoWindowWithIdentifier:markerId result:result]; - } else { - result([FlutterError errorWithCode:@"Invalid markerId" - message:@"hideInfoWindow called with invalid markerId" - details:nil]); - } - } else if ([call.method isEqualToString:@"markers#isInfoWindowShown"]) { - id markerId = call.arguments[@"markerId"]; - if ([markerId isKindOfClass:[NSString class]]) { - [self.markersController isInfoWindowShownForMarkerWithIdentifier:markerId result:result]; - } else { - result([FlutterError errorWithCode:@"Invalid markerId" - message:@"isInfoWindowShown called with invalid markerId" - details:nil]); - } - } else if ([call.method isEqualToString:@"polygons#update"]) { - id polygonsToAdd = call.arguments[@"polygonsToAdd"]; - if ([polygonsToAdd isKindOfClass:[NSArray class]]) { - [self.polygonsController addPolygons:polygonsToAdd]; - } - id polygonsToChange = call.arguments[@"polygonsToChange"]; - if ([polygonsToChange isKindOfClass:[NSArray class]]) { - [self.polygonsController changePolygons:polygonsToChange]; - } - id polygonIdsToRemove = call.arguments[@"polygonIdsToRemove"]; - if ([polygonIdsToRemove isKindOfClass:[NSArray class]]) { - [self.polygonsController removePolygonWithIdentifiers:polygonIdsToRemove]; - } - result(nil); - } else if ([call.method isEqualToString:@"polylines#update"]) { - id polylinesToAdd = call.arguments[@"polylinesToAdd"]; - if ([polylinesToAdd isKindOfClass:[NSArray class]]) { - [self.polylinesController addPolylines:polylinesToAdd]; - } - id polylinesToChange = call.arguments[@"polylinesToChange"]; - if ([polylinesToChange isKindOfClass:[NSArray class]]) { - [self.polylinesController changePolylines:polylinesToChange]; - } - id polylineIdsToRemove = call.arguments[@"polylineIdsToRemove"]; - if ([polylineIdsToRemove isKindOfClass:[NSArray class]]) { - [self.polylinesController removePolylineWithIdentifiers:polylineIdsToRemove]; - } - result(nil); - } else if ([call.method isEqualToString:@"circles#update"]) { - id circlesToAdd = call.arguments[@"circlesToAdd"]; - if ([circlesToAdd isKindOfClass:[NSArray class]]) { - [self.circlesController addCircles:circlesToAdd]; - } - id circlesToChange = call.arguments[@"circlesToChange"]; - if ([circlesToChange isKindOfClass:[NSArray class]]) { - [self.circlesController changeCircles:circlesToChange]; - } - id circleIdsToRemove = call.arguments[@"circleIdsToRemove"]; - if ([circleIdsToRemove isKindOfClass:[NSArray class]]) { - [self.circlesController removeCircleWithIdentifiers:circleIdsToRemove]; - } - result(nil); - } else if ([call.method isEqualToString:@"tileOverlays#update"]) { - id tileOverlaysToAdd = call.arguments[@"tileOverlaysToAdd"]; - if ([tileOverlaysToAdd isKindOfClass:[NSArray class]]) { - [self.tileOverlaysController addTileOverlays:tileOverlaysToAdd]; - } - id tileOverlaysToChange = call.arguments[@"tileOverlaysToChange"]; - if ([tileOverlaysToChange isKindOfClass:[NSArray class]]) { - [self.tileOverlaysController changeTileOverlays:tileOverlaysToChange]; - } - id tileOverlayIdsToRemove = call.arguments[@"tileOverlayIdsToRemove"]; - if ([tileOverlayIdsToRemove isKindOfClass:[NSArray class]]) { - [self.tileOverlaysController removeTileOverlayWithIdentifiers:tileOverlayIdsToRemove]; - } - result(nil); - } else if ([call.method isEqualToString:@"tileOverlays#clearTileCache"]) { - id rawTileOverlayId = call.arguments[@"tileOverlayId"]; - [self.tileOverlaysController clearTileCacheWithIdentifier:rawTileOverlayId]; - result(nil); - } else if ([call.method isEqualToString:@"map#isCompassEnabled"]) { - NSNumber *isCompassEnabled = @(self.mapView.settings.compassButton); - result(isCompassEnabled); - } else if ([call.method isEqualToString:@"map#isMapToolbarEnabled"]) { - NSNumber *isMapToolbarEnabled = @NO; - result(isMapToolbarEnabled); - } else if ([call.method isEqualToString:@"map#getMinMaxZoomLevels"]) { - NSArray *zoomLevels = @[ @(self.mapView.minZoom), @(self.mapView.maxZoom) ]; - result(zoomLevels); - } else if ([call.method isEqualToString:@"map#getZoomLevel"]) { - result(@(self.mapView.camera.zoom)); - } else if ([call.method isEqualToString:@"map#isZoomGesturesEnabled"]) { - NSNumber *isZoomGesturesEnabled = @(self.mapView.settings.zoomGestures); - result(isZoomGesturesEnabled); - } else if ([call.method isEqualToString:@"map#isZoomControlsEnabled"]) { - NSNumber *isZoomControlsEnabled = @NO; - result(isZoomControlsEnabled); - } else if ([call.method isEqualToString:@"map#isTiltGesturesEnabled"]) { - NSNumber *isTiltGesturesEnabled = @(self.mapView.settings.tiltGestures); - result(isTiltGesturesEnabled); - } else if ([call.method isEqualToString:@"map#isRotateGesturesEnabled"]) { - NSNumber *isRotateGesturesEnabled = @(self.mapView.settings.rotateGestures); - result(isRotateGesturesEnabled); - } else if ([call.method isEqualToString:@"map#isScrollGesturesEnabled"]) { - NSNumber *isScrollGesturesEnabled = @(self.mapView.settings.scrollGestures); - result(isScrollGesturesEnabled); - } else if ([call.method isEqualToString:@"map#isMyLocationButtonEnabled"]) { - NSNumber *isMyLocationButtonEnabled = @(self.mapView.settings.myLocationButton); - result(isMyLocationButtonEnabled); - } else if ([call.method isEqualToString:@"map#isTrafficEnabled"]) { - NSNumber *isTrafficEnabled = @(self.mapView.trafficEnabled); - result(isTrafficEnabled); - } else if ([call.method isEqualToString:@"map#isBuildingsEnabled"]) { - NSNumber *isBuildingsEnabled = @(self.mapView.buildingsEnabled); - result(isBuildingsEnabled); - } else if ([call.method isEqualToString:@"map#setStyle"]) { - id mapStyle = [call arguments]; - self.styleError = [self setMapStyle:(mapStyle == [NSNull null] ? nil : mapStyle)]; - if (self.styleError == nil) { - result(@[ @(YES) ]); - } else { - result(@[ @(NO), self.styleError ]); - } - } else if ([call.method isEqualToString:@"map#getStyleError"]) { - result(self.styleError); - } else if ([call.method isEqualToString:@"map#getTileOverlayInfo"]) { - NSString *rawTileOverlayId = call.arguments[@"tileOverlayId"]; - result([self.tileOverlaysController tileOverlayInfoWithIdentifier:rawTileOverlayId]); - } else { - result(FlutterMethodNotImplemented); - } -} - - (void)showAtOrigin:(CGPoint)origin { CGRect frame = {origin, self.mapView.frame.size}; self.mapView.frame = frame; @@ -419,14 +271,6 @@ - (void)hide { self.mapView.hidden = YES; } -- (void)animateWithCameraUpdate:(GMSCameraUpdate *)cameraUpdate { - [self.mapView animateWithCameraUpdate:cameraUpdate]; -} - -- (void)moveWithCameraUpdate:(GMSCameraUpdate *)cameraUpdate { - [self.mapView moveCamera:cameraUpdate]; -} - - (GMSCameraPosition *)cameraPosition { if (self.trackCameraPosition) { return self.mapView.camera; @@ -499,63 +343,77 @@ - (void)setMyLocationButtonEnabled:(BOOL)enabled { self.mapView.settings.myLocationButton = enabled; } +/// Sets the map style, returing any error string as well as storing that error in `mapStyle` for +/// later access. - (NSString *)setMapStyle:(NSString *)mapStyle { + NSString *errorString = nil; if (mapStyle.length == 0) { self.mapView.mapStyle = nil; - return nil; - } - NSError *error; - GMSMapStyle *style = [GMSMapStyle styleWithJSONString:mapStyle error:&error]; - if (!style) { - return [error localizedDescription]; } else { - self.mapView.mapStyle = style; - return nil; + NSError *error; + GMSMapStyle *style = [GMSMapStyle styleWithJSONString:mapStyle error:&error]; + if (style) { + self.mapView.mapStyle = style; + } else { + errorString = [error localizedDescription]; + } } + self.styleError = errorString; + return errorString; } #pragma mark - GMSMapViewDelegate methods - (void)mapView:(GMSMapView *)mapView willMove:(BOOL)gesture { - [self.channel invokeMethod:@"camera#onMoveStarted" arguments:@{@"isGesture" : @(gesture)}]; + [self.dartCallbackHandler didStartCameraMoveWithCompletion:^(FlutterError *_Nullable _){ + }]; } - (void)mapView:(GMSMapView *)mapView didChangeCameraPosition:(GMSCameraPosition *)position { if (self.trackCameraPosition) { - [self.channel invokeMethod:@"camera#onMove" - arguments:@{ - @"position" : [FLTGoogleMapJSONConversions dictionaryFromPosition:position] + [self.dartCallbackHandler + didMoveCameraToPosition:FGMGetPigeonCameraPositionForPosition(position) + completion:^(FlutterError *_Nullable _){ }]; } } - (void)mapView:(GMSMapView *)mapView idleAtCameraPosition:(GMSCameraPosition *)position { - [self.channel invokeMethod:@"camera#onIdle" arguments:@{}]; + [self.dartCallbackHandler didIdleCameraWithCompletion:^(FlutterError *_Nullable _){ + }]; } - (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker { - NSString *markerId = marker.userData[0]; - return [self.markersController didTapMarkerWithIdentifier:markerId]; + if ([marker.userData isKindOfClass:[GMUStaticCluster class]]) { + GMUStaticCluster *cluster = marker.userData; + [self.clusterManagersController didTapCluster:cluster]; + // When NO is returned, the map will focus on the cluster. + return NO; + } + return + [self.markersController didTapMarkerWithIdentifier:FGMGetMarkerIdentifierFromMarker(marker)]; } - (void)mapView:(GMSMapView *)mapView didEndDraggingMarker:(GMSMarker *)marker { - NSString *markerId = marker.userData[0]; - [self.markersController didEndDraggingMarkerWithIdentifier:markerId location:marker.position]; + [self.markersController + didEndDraggingMarkerWithIdentifier:FGMGetMarkerIdentifierFromMarker(marker) + location:marker.position]; } - (void)mapView:(GMSMapView *)mapView didBeginDraggingMarker:(GMSMarker *)marker { - NSString *markerId = marker.userData[0]; - [self.markersController didStartDraggingMarkerWithIdentifier:markerId location:marker.position]; + [self.markersController + didStartDraggingMarkerWithIdentifier:FGMGetMarkerIdentifierFromMarker(marker) + location:marker.position]; } - (void)mapView:(GMSMapView *)mapView didDragMarker:(GMSMarker *)marker { - NSString *markerId = marker.userData[0]; - [self.markersController didDragMarkerWithIdentifier:markerId location:marker.position]; + [self.markersController didDragMarkerWithIdentifier:FGMGetMarkerIdentifierFromMarker(marker) + location:marker.position]; } - (void)mapView:(GMSMapView *)mapView didTapInfoWindowOfMarker:(GMSMarker *)marker { - NSString *markerId = marker.userData[0]; - [self.markersController didTapInfoWindowOfMarkerWithIdentifier:markerId]; + [self.markersController + didTapInfoWindowOfMarkerWithIdentifier:FGMGetMarkerIdentifierFromMarker(marker)]; } - (void)mapView:(GMSMapView *)mapView didTapOverlay:(GMSOverlay *)overlay { NSString *overlayId = overlay.userData[0]; @@ -569,93 +427,399 @@ - (void)mapView:(GMSMapView *)mapView didTapOverlay:(GMSOverlay *)overlay { } - (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate { - [self.channel - invokeMethod:@"map#onTap" - arguments:@{@"position" : [FLTGoogleMapJSONConversions arrayFromLocation:coordinate]}]; + [self.dartCallbackHandler didTapAtPosition:FGMGetPigeonLatLngForCoordinate(coordinate) + completion:^(FlutterError *_Nullable _){ + }]; } - (void)mapView:(GMSMapView *)mapView didLongPressAtCoordinate:(CLLocationCoordinate2D)coordinate { - [self.channel - invokeMethod:@"map#onLongPress" - arguments:@{@"position" : [FLTGoogleMapJSONConversions arrayFromLocation:coordinate]}]; -} - -- (void)interpretMapOptions:(NSDictionary *)data { - NSArray *cameraTargetBounds = data[@"cameraTargetBounds"]; - if (cameraTargetBounds && cameraTargetBounds != (id)[NSNull null]) { - [self - setCameraTargetBounds:cameraTargetBounds.count > 0 && cameraTargetBounds[0] != [NSNull null] - ? [FLTGoogleMapJSONConversions - coordinateBoundsFromLatLongs:cameraTargetBounds.firstObject] - : nil]; - } - NSNumber *compassEnabled = data[@"compassEnabled"]; - if (compassEnabled && compassEnabled != (id)[NSNull null]) { - [self setCompassEnabled:[compassEnabled boolValue]]; - } - id indoorEnabled = data[@"indoorEnabled"]; - if (indoorEnabled && indoorEnabled != [NSNull null]) { - [self setIndoorEnabled:[indoorEnabled boolValue]]; - } - id trafficEnabled = data[@"trafficEnabled"]; - if (trafficEnabled && trafficEnabled != [NSNull null]) { - [self setTrafficEnabled:[trafficEnabled boolValue]]; - } - id buildingsEnabled = data[@"buildingsEnabled"]; - if (buildingsEnabled && buildingsEnabled != [NSNull null]) { - [self setBuildingsEnabled:[buildingsEnabled boolValue]]; - } - id mapType = data[@"mapType"]; - if (mapType && mapType != [NSNull null]) { - [self setMapType:[FLTGoogleMapJSONConversions mapViewTypeFromTypeValue:mapType]]; - } - NSArray *zoomData = data[@"minMaxZoomPreference"]; - if (zoomData && zoomData != (id)[NSNull null]) { - float minZoom = (zoomData[0] == [NSNull null]) ? kGMSMinZoomLevel : [zoomData[0] floatValue]; - float maxZoom = (zoomData[1] == [NSNull null]) ? kGMSMaxZoomLevel : [zoomData[1] floatValue]; + [self.dartCallbackHandler didLongPressAtPosition:FGMGetPigeonLatLngForCoordinate(coordinate) + completion:^(FlutterError *_Nullable _){ + }]; +} + +- (void)interpretMapConfiguration:(FGMPlatformMapConfiguration *)config { + FGMPlatformCameraTargetBounds *cameraTargetBounds = config.cameraTargetBounds; + if (cameraTargetBounds) { + [self setCameraTargetBounds:cameraTargetBounds.bounds + ? FGMGetCoordinateBoundsForPigeonLatLngBounds( + cameraTargetBounds.bounds) + : nil]; + } + NSNumber *compassEnabled = config.compassEnabled; + if (compassEnabled) { + [self setCompassEnabled:compassEnabled.boolValue]; + } + NSNumber *indoorEnabled = config.indoorViewEnabled; + if (indoorEnabled) { + [self setIndoorEnabled:indoorEnabled.boolValue]; + } + NSNumber *trafficEnabled = config.trafficEnabled; + if (trafficEnabled) { + [self setTrafficEnabled:trafficEnabled.boolValue]; + } + NSNumber *buildingsEnabled = config.buildingsEnabled; + if (buildingsEnabled) { + [self setBuildingsEnabled:buildingsEnabled.boolValue]; + } + FGMPlatformMapTypeBox *mapType = config.mapType; + if (mapType) { + [self setMapType:FGMGetMapViewTypeForPigeonMapType(mapType.value)]; + } + FGMPlatformZoomRange *zoomData = config.minMaxZoomPreference; + if (zoomData) { + float minZoom = zoomData.min ? zoomData.min.floatValue : kGMSMinZoomLevel; + float maxZoom = zoomData.max ? zoomData.max.floatValue : kGMSMaxZoomLevel; [self setMinZoom:minZoom maxZoom:maxZoom]; } - NSArray *paddingData = data[@"padding"]; - if (paddingData) { - float top = (paddingData[0] == [NSNull null]) ? 0 : [paddingData[0] floatValue]; - float left = (paddingData[1] == [NSNull null]) ? 0 : [paddingData[1] floatValue]; - float bottom = (paddingData[2] == [NSNull null]) ? 0 : [paddingData[2] floatValue]; - float right = (paddingData[3] == [NSNull null]) ? 0 : [paddingData[3] floatValue]; - [self setPaddingTop:top left:left bottom:bottom right:right]; + FGMPlatformEdgeInsets *padding = config.padding; + if (padding) { + [self setPaddingTop:padding.top left:padding.left bottom:padding.bottom right:padding.right]; } - NSNumber *rotateGesturesEnabled = data[@"rotateGesturesEnabled"]; - if (rotateGesturesEnabled && rotateGesturesEnabled != (id)[NSNull null]) { - [self setRotateGesturesEnabled:[rotateGesturesEnabled boolValue]]; + NSNumber *rotateGesturesEnabled = config.rotateGesturesEnabled; + if (rotateGesturesEnabled) { + [self setRotateGesturesEnabled:rotateGesturesEnabled.boolValue]; } - NSNumber *scrollGesturesEnabled = data[@"scrollGesturesEnabled"]; - if (scrollGesturesEnabled && scrollGesturesEnabled != (id)[NSNull null]) { - [self setScrollGesturesEnabled:[scrollGesturesEnabled boolValue]]; + NSNumber *scrollGesturesEnabled = config.scrollGesturesEnabled; + if (scrollGesturesEnabled) { + [self setScrollGesturesEnabled:scrollGesturesEnabled.boolValue]; } - NSNumber *tiltGesturesEnabled = data[@"tiltGesturesEnabled"]; - if (tiltGesturesEnabled && tiltGesturesEnabled != (id)[NSNull null]) { - [self setTiltGesturesEnabled:[tiltGesturesEnabled boolValue]]; + NSNumber *tiltGesturesEnabled = config.tiltGesturesEnabled; + if (tiltGesturesEnabled) { + [self setTiltGesturesEnabled:tiltGesturesEnabled.boolValue]; } - NSNumber *trackCameraPosition = data[@"trackCameraPosition"]; - if (trackCameraPosition && trackCameraPosition != (id)[NSNull null]) { - [self setTrackCameraPosition:[trackCameraPosition boolValue]]; + NSNumber *trackCameraPosition = config.trackCameraPosition; + if (trackCameraPosition) { + [self setTrackCameraPosition:trackCameraPosition.boolValue]; } - NSNumber *zoomGesturesEnabled = data[@"zoomGesturesEnabled"]; - if (zoomGesturesEnabled && zoomGesturesEnabled != (id)[NSNull null]) { - [self setZoomGesturesEnabled:[zoomGesturesEnabled boolValue]]; + NSNumber *zoomGesturesEnabled = config.zoomGesturesEnabled; + if (zoomGesturesEnabled) { + [self setZoomGesturesEnabled:zoomGesturesEnabled.boolValue]; } - NSNumber *myLocationEnabled = data[@"myLocationEnabled"]; - if (myLocationEnabled && myLocationEnabled != (id)[NSNull null]) { - [self setMyLocationEnabled:[myLocationEnabled boolValue]]; + NSNumber *myLocationEnabled = config.myLocationEnabled; + if (myLocationEnabled) { + [self setMyLocationEnabled:myLocationEnabled.boolValue]; } - NSNumber *myLocationButtonEnabled = data[@"myLocationButtonEnabled"]; - if (myLocationButtonEnabled && myLocationButtonEnabled != (id)[NSNull null]) { - [self setMyLocationButtonEnabled:[myLocationButtonEnabled boolValue]]; + NSNumber *myLocationButtonEnabled = config.myLocationButtonEnabled; + if (myLocationButtonEnabled) { + [self setMyLocationButtonEnabled:myLocationButtonEnabled.boolValue]; } - NSString *style = data[@"style"]; + NSString *style = config.style; if (style) { - self.styleError = [self setMapStyle:style]; + [self setMapStyle:style]; + } +} + +@end + +#pragma mark - + +@implementation FGMMapCallHandler + +- (instancetype)initWithMapController:(nonnull FLTGoogleMapController *)controller + messenger:(NSObject *)messenger + pigeonSuffix:(NSString *)suffix { + self = [super init]; + if (self) { + _controller = controller; + _messenger = messenger; + _pigeonSuffix = suffix; + } + return self; +} + +- (void)waitForMapWithError:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + // No-op; this call just ensures synchronization with the platform thread. +} + +- (void)updateCirclesByAdding:(nonnull NSArray *)toAdd + changing:(nonnull NSArray *)toChange + removing:(nonnull NSArray *)idsToRemove + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + [self.controller.circlesController addCircles:toAdd]; + [self.controller.circlesController changeCircles:toChange]; + [self.controller.circlesController removeCirclesWithIdentifiers:idsToRemove]; +} + +- (void)updateHeatmapsByAdding:(nonnull NSArray *)toAdd + changing:(nonnull NSArray *)toChange + removing:(nonnull NSArray *)idsToRemove + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + [self.controller.heatmapsController addHeatmaps:toAdd]; + [self.controller.heatmapsController changeHeatmaps:toChange]; + [self.controller.heatmapsController removeHeatmapsWithIdentifiers:idsToRemove]; +} + +- (void)updateWithMapConfiguration:(nonnull FGMPlatformMapConfiguration *)configuration + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + [self.controller interpretMapConfiguration:configuration]; +} + +- (void)updateMarkersByAdding:(nonnull NSArray *)toAdd + changing:(nonnull NSArray *)toChange + removing:(nonnull NSArray *)idsToRemove + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + [self.controller.markersController addMarkers:toAdd]; + [self.controller.markersController changeMarkers:toChange]; + [self.controller.markersController removeMarkersWithIdentifiers:idsToRemove]; + + // Invoke clustering after markers are added. + [self.controller.clusterManagersController invokeClusteringForEachClusterManager]; +} + +- (void)updateClusterManagersByAdding:(nonnull NSArray *)toAdd + removing:(nonnull NSArray *)idsToRemove + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + [self.controller.clusterManagersController addClusterManagers:toAdd]; + [self.controller.clusterManagersController removeClusterManagersWithIdentifiers:idsToRemove]; +} + +- (void)updatePolygonsByAdding:(nonnull NSArray *)toAdd + changing:(nonnull NSArray *)toChange + removing:(nonnull NSArray *)idsToRemove + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + [self.controller.polygonsController addPolygons:toAdd]; + [self.controller.polygonsController changePolygons:toChange]; + [self.controller.polygonsController removePolygonWithIdentifiers:idsToRemove]; +} + +- (void)updatePolylinesByAdding:(nonnull NSArray *)toAdd + changing:(nonnull NSArray *)toChange + removing:(nonnull NSArray *)idsToRemove + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + [self.controller.polylinesController addPolylines:toAdd]; + [self.controller.polylinesController changePolylines:toChange]; + [self.controller.polylinesController removePolylineWithIdentifiers:idsToRemove]; +} + +- (void)updateTileOverlaysByAdding:(nonnull NSArray *)toAdd + changing:(nonnull NSArray *)toChange + removing:(nonnull NSArray *)idsToRemove + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + [self.controller.tileOverlaysController addTileOverlays:toAdd]; + [self.controller.tileOverlaysController changeTileOverlays:toChange]; + [self.controller.tileOverlaysController removeTileOverlayWithIdentifiers:idsToRemove]; +} + +- (nullable FGMPlatformLatLng *) + latLngForScreenCoordinate:(nonnull FGMPlatformPoint *)screenCoordinate + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + if (!self.controller.mapView) { + *error = [FlutterError errorWithCode:@"GoogleMap uninitialized" + message:@"getLatLng called prior to map initialization" + details:nil]; + return nil; } + CGPoint point = FGMGetCGPointForPigeonPoint(screenCoordinate); + CLLocationCoordinate2D latlng = [self.controller.mapView.projection coordinateForPoint:point]; + return FGMGetPigeonLatLngForCoordinate(latlng); +} + +- (nullable FGMPlatformPoint *) + screenCoordinatesForLatLng:(nonnull FGMPlatformLatLng *)latLng + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + if (!self.controller.mapView) { + *error = [FlutterError errorWithCode:@"GoogleMap uninitialized" + message:@"getScreenCoordinate called prior to map initialization" + details:nil]; + return nil; + } + CLLocationCoordinate2D location = FGMGetCoordinateForPigeonLatLng(latLng); + CGPoint point = [self.controller.mapView.projection pointForCoordinate:location]; + return FGMGetPigeonPointForCGPoint(point); +} + +- (nullable FGMPlatformLatLngBounds *)visibleMapRegion: + (FlutterError *_Nullable __autoreleasing *_Nonnull)error { + if (!self.controller.mapView) { + *error = [FlutterError errorWithCode:@"GoogleMap uninitialized" + message:@"getVisibleRegion called prior to map initialization" + details:nil]; + return nil; + } + GMSVisibleRegion visibleRegion = self.controller.mapView.projection.visibleRegion; + GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] initWithRegion:visibleRegion]; + return FGMGetPigeonLatLngBoundsForCoordinateBounds(bounds); +} + +- (void)moveCameraWithUpdate:(nonnull FGMPlatformCameraUpdate *)cameraUpdate + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + GMSCameraUpdate *update = [FLTGoogleMapJSONConversions cameraUpdateFromArray:cameraUpdate.json]; + if (!update) { + *error = [FlutterError errorWithCode:@"Invalid update" + message:@"Unrecognized camera update" + details:cameraUpdate.json]; + return; + } + [self.controller.mapView moveCamera:update]; +} + +- (void)animateCameraWithUpdate:(nonnull FGMPlatformCameraUpdate *)cameraUpdate + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + GMSCameraUpdate *update = [FLTGoogleMapJSONConversions cameraUpdateFromArray:cameraUpdate.json]; + if (!update) { + *error = [FlutterError errorWithCode:@"Invalid update" + message:@"Unrecognized camera update" + details:cameraUpdate.json]; + return; + } + [self.controller.mapView animateWithCameraUpdate:update]; +} + +- (nullable NSNumber *)currentZoomLevel:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return @(self.controller.mapView.camera.zoom); +} + +- (void)showInfoWindowForMarkerWithIdentifier:(nonnull NSString *)markerId + error:(FlutterError *_Nullable __autoreleasing *_Nonnull) + error { + [self.controller.markersController showMarkerInfoWindowWithIdentifier:markerId error:error]; +} + +- (void)hideInfoWindowForMarkerWithIdentifier:(nonnull NSString *)markerId + error:(FlutterError *_Nullable __autoreleasing *_Nonnull) + error { + [self.controller.markersController hideMarkerInfoWindowWithIdentifier:markerId error:error]; +} + +- (nullable NSNumber *) + isShowingInfoWindowForMarkerWithIdentifier:(nonnull NSString *)markerId + error:(FlutterError *_Nullable __autoreleasing *_Nonnull) + error { + return [self.controller.markersController isInfoWindowShownForMarkerWithIdentifier:markerId + error:error]; +} + +- (nullable NSString *)setStyle:(nonnull NSString *)style + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return [self.controller setMapStyle:style]; +} + +- (nullable NSString *)lastStyleError:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return self.controller.styleError; +} + +- (void)clearTileCacheForOverlayWithIdentifier:(nonnull NSString *)tileOverlayId + error:(FlutterError *_Nullable __autoreleasing *_Nonnull) + error { + [self.controller.tileOverlaysController clearTileCacheWithIdentifier:tileOverlayId]; +} + +- (nullable FlutterStandardTypedData *)takeSnapshotWithError: + (FlutterError *_Nullable __autoreleasing *_Nonnull)error { + GMSMapView *mapView = self.controller.mapView; + if (!mapView) { + *error = [FlutterError errorWithCode:@"GoogleMap uninitialized" + message:@"takeSnapshot called prior to map initialization" + details:nil]; + return nil; + } + UIGraphicsImageRenderer *renderer = + [[UIGraphicsImageRenderer alloc] initWithSize:mapView.bounds.size]; + // For some unknown reason mapView.layer::renderInContext API returns a blank image on iOS 17. + // So we have to use drawViewHierarchyInRect API. + UIImage *image = [renderer imageWithActions:^(UIGraphicsImageRendererContext *context) { + [mapView drawViewHierarchyInRect:mapView.bounds afterScreenUpdates:YES]; + }]; + NSData *imageData = UIImagePNGRepresentation(image); + return imageData ? [FlutterStandardTypedData typedDataWithBytes:imageData] : nil; +} + +@end + +#pragma mark - + +@implementation FGMMapInspector + +- (instancetype)initWithMapController:(nonnull FLTGoogleMapController *)controller + messenger:(NSObject *)messenger + pigeonSuffix:(NSString *)suffix { + self = [super init]; + if (self) { + _controller = controller; + _messenger = messenger; + _pigeonSuffix = suffix; + } + return self; +} + +- (nullable NSNumber *)areBuildingsEnabledWithError: + (FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return @(self.controller.mapView.buildingsEnabled); +} + +- (nullable NSNumber *)areRotateGesturesEnabledWithError: + (FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return @(self.controller.mapView.settings.rotateGestures); +} + +- (nullable NSNumber *)areScrollGesturesEnabledWithError: + (FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return @(self.controller.mapView.settings.scrollGestures); +} + +- (nullable NSNumber *)areTiltGesturesEnabledWithError: + (FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return @(self.controller.mapView.settings.tiltGestures); +} + +- (nullable NSNumber *)areZoomGesturesEnabledWithError: + (FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return @(self.controller.mapView.settings.zoomGestures); +} + +- (nullable FGMPlatformTileLayer *) + tileOverlayWithIdentifier:(nonnull NSString *)tileOverlayId + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + GMSTileLayer *layer = + [self.controller.tileOverlaysController tileOverlayWithIdentifier:tileOverlayId].layer; + if (!layer) { + return nil; + } + return [FGMPlatformTileLayer makeWithVisible:(layer.map != nil) + fadeIn:layer.fadeIn + opacity:layer.opacity + zIndex:layer.zIndex]; +} + +- (nullable FGMPlatformHeatmap *) + heatmapWithIdentifier:(nonnull NSString *)heatmapId + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + NSDictionary *heatmapInfo = + [self.controller.heatmapsController heatmapInfoWithIdentifier:heatmapId]; + if (!heatmapInfo) { + return nil; + } + return [FGMPlatformHeatmap makeWithJson:heatmapInfo]; +} + +- (nullable NSArray *) + clustersWithIdentifier:(NSString *)clusterManagerId + error:(FlutterError *_Nullable *_Nonnull)error { + return [self.controller.clusterManagersController clustersWithIdentifier:clusterManagerId + error:error]; +} + +- (nullable NSNumber *)isCompassEnabledWithError: + (FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return @(self.controller.mapView.settings.compassButton); +} + +- (nullable NSNumber *)isMyLocationButtonEnabledWithError: + (FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return @(self.controller.mapView.settings.myLocationButton); +} + +- (nullable NSNumber *)isTrafficEnabledWithError: + (FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return @(self.controller.mapView.trafficEnabled); +} + +- (nullable FGMPlatformZoomRange *)zoomRange: + (FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return [FGMPlatformZoomRange makeWithMin:@(self.controller.mapView.minZoom) + max:@(self.controller.mapView.maxZoom)]; } @end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController_Test.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController_Test.h index 1377b68e9b6e..da4da303ff7c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController_Test.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController_Test.h @@ -13,11 +13,11 @@ NS_ASSUME_NONNULL_BEGIN /// /// @param mapView A map view that will be displayed by the controller /// @param viewId A unique identifier for the controller. -/// @param args Parameters for initialising the map view. +/// @param creationParameters Parameters for initialising the map view. /// @param registrar The plugin registrar passed from Flutter. - (instancetype)initWithMapView:(GMSMapView *)mapView viewIdentifier:(int64_t)viewId - arguments:(id _Nullable)args + creationParameters:(FGMPlatformMapViewCreationParams *)creationParameters registrar:(NSObject *)registrar; @end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapMarkerController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapMarkerController.h index a33d48073dd2..3b090a3ed028 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapMarkerController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapMarkerController.h @@ -4,16 +4,20 @@ #import #import + +#import "FGMClusterManagersController.h" #import "GoogleMapController.h" +#import "messages.g.h" NS_ASSUME_NONNULL_BEGIN // Defines marker controllable by Flutter. @interface FLTGoogleMapMarkerController : NSObject @property(assign, nonatomic, readonly) BOOL consumeTapEvents; -- (instancetype)initMarkerWithPosition:(CLLocationCoordinate2D)position - identifier:(NSString *)identifier - mapView:(GMSMapView *)mapView; +- (instancetype)initWithMarker:(GMSMarker *)marker + markerIdentifier:(NSString *)markerIdentifier + clusterManagerIdentifier:(nullable NSString *)clusterManagerIdentifier + mapView:(GMSMapView *)mapView; - (void)showInfoWindow; - (void)hideInfoWindow; - (BOOL)isInfoWindowShown; @@ -21,12 +25,13 @@ NS_ASSUME_NONNULL_BEGIN @end @interface FLTMarkersController : NSObject -- (instancetype)initWithMethodChannel:(FlutterMethodChannel *)methodChannel - mapView:(GMSMapView *)mapView - registrar:(NSObject *)registrar; -- (void)addMarkers:(NSArray *)markersToAdd; -- (void)changeMarkers:(NSArray *)markersToChange; -- (void)removeMarkersWithIdentifiers:(NSArray *)identifiers; +- (instancetype)initWithMapView:(GMSMapView *)mapView + callbackHandler:(FGMMapsCallbackApi *)callbackHandler + clusterManagersController:(nullable FGMClusterManagersController *)clusterManagersController + registrar:(NSObject *)registrar; +- (void)addMarkers:(NSArray *)markersToAdd; +- (void)changeMarkers:(NSArray *)markersToChange; +- (void)removeMarkersWithIdentifiers:(NSArray *)identifiers; - (BOOL)didTapMarkerWithIdentifier:(NSString *)identifier; - (void)didStartDraggingMarkerWithIdentifier:(NSString *)identifier location:(CLLocationCoordinate2D)coordinate; @@ -35,10 +40,17 @@ NS_ASSUME_NONNULL_BEGIN - (void)didDragMarkerWithIdentifier:(NSString *)identifier location:(CLLocationCoordinate2D)coordinate; - (void)didTapInfoWindowOfMarkerWithIdentifier:(NSString *)identifier; -- (void)showMarkerInfoWindowWithIdentifier:(NSString *)identifier result:(FlutterResult)result; -- (void)hideMarkerInfoWindowWithIdentifier:(NSString *)identifier result:(FlutterResult)result; -- (void)isInfoWindowShownForMarkerWithIdentifier:(NSString *)identifier - result:(FlutterResult)result; +- (void)showMarkerInfoWindowWithIdentifier:(NSString *)identifier + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error; +- (void)hideMarkerInfoWindowWithIdentifier:(NSString *)identifier + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error; +/// Returns whether or not the info window for the marker with the given identifier is shown. +/// +/// If there is no such marker, returns nil and sets error. +- (nullable NSNumber *) + isInfoWindowShownForMarkerWithIdentifier:(NSString *)identifier + error: + (FlutterError *_Nullable __autoreleasing *_Nonnull)error; @end NS_ASSUME_NONNULL_END diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapMarkerController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapMarkerController.m index b816e7ee9144..648ac9f37330 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapMarkerController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapMarkerController.m @@ -3,6 +3,8 @@ // found in the LICENSE file. #import "GoogleMapMarkerController.h" + +#import "FGMMarkerUserData.h" #import "FLTGoogleMapJSONConversions.h" @interface FLTGoogleMapMarkerController () @@ -10,19 +12,26 @@ @interface FLTGoogleMapMarkerController () @property(strong, nonatomic) GMSMarker *marker; @property(weak, nonatomic) GMSMapView *mapView; @property(assign, nonatomic, readwrite) BOOL consumeTapEvents; +/// The unique identifier for the cluster manager. +@property(copy, nonatomic, nullable) NSString *clusterManagerIdentifier; +/// The unique identifier for the marker. +@property(copy, nonatomic) NSString *markerIdentifier; @end @implementation FLTGoogleMapMarkerController -- (instancetype)initMarkerWithPosition:(CLLocationCoordinate2D)position - identifier:(NSString *)identifier - mapView:(GMSMapView *)mapView { +- (instancetype)initWithMarker:(GMSMarker *)marker + markerIdentifier:(NSString *)markerIdentifier + clusterManagerIdentifier:(nullable NSString *)clusterManagerIdentifier + mapView:(GMSMapView *)mapView { self = [super init]; if (self) { - _marker = [GMSMarker markerWithPosition:position]; + _marker = marker; + _markerIdentifier = [markerIdentifier copy]; + _clusterManagerIdentifier = [clusterManagerIdentifier copy]; _mapView = mapView; - _marker.userData = @[ identifier ]; + FGMSetIdentifiersToMarkerUserData(_markerIdentifier, _clusterManagerIdentifier, _marker); } return self; } @@ -83,7 +92,14 @@ - (void)setRotation:(CLLocationDegrees)rotation { } - (void)setVisible:(BOOL)visible { - self.marker.map = visible ? self.mapView : nil; + // If marker belongs the cluster manager, visibility need to be controlled with the opacity + // as the cluster manager controls when marker is on the map and when not. + // Alpha value for marker must always be interpreted before visibility value. + if (self.clusterManagerIdentifier) { + self.marker.opacity = visible ? self.marker.opacity : 0.0f; + } else { + self.marker.map = visible ? self.mapView : nil; + } } - (void)setZIndex:(int)zIndex { @@ -93,60 +109,60 @@ - (void)setZIndex:(int)zIndex { - (void)interpretMarkerOptions:(NSDictionary *)data registrar:(NSObject *)registrar screenScale:(CGFloat)screenScale { - NSNumber *alpha = data[@"alpha"]; - if (alpha && alpha != (id)[NSNull null]) { + NSNumber *alpha = FGMGetValueOrNilFromDict(data, @"alpha"); + if (alpha) { [self setAlpha:[alpha floatValue]]; } - NSArray *anchor = data[@"anchor"]; - if (anchor && anchor != (id)[NSNull null]) { + NSArray *anchor = FGMGetValueOrNilFromDict(data, @"anchor"); + if (anchor) { [self setAnchor:[FLTGoogleMapJSONConversions pointFromArray:anchor]]; } - NSNumber *draggable = data[@"draggable"]; - if (draggable && draggable != (id)[NSNull null]) { + NSNumber *draggable = FGMGetValueOrNilFromDict(data, @"draggable"); + if (draggable) { [self setDraggable:[draggable boolValue]]; } - NSArray *icon = data[@"icon"]; - if (icon && icon != (id)[NSNull null]) { + NSArray *icon = FGMGetValueOrNilFromDict(data, @"icon"); + if (icon) { UIImage *image = [self extractIconFromData:icon registrar:registrar screenScale:screenScale]; [self setIcon:image]; } - NSNumber *flat = data[@"flat"]; - if (flat && flat != (id)[NSNull null]) { + NSNumber *flat = FGMGetValueOrNilFromDict(data, @"flat"); + if (flat) { [self setFlat:[flat boolValue]]; } - NSNumber *consumeTapEvents = data[@"consumeTapEvents"]; - if (consumeTapEvents && consumeTapEvents != (id)[NSNull null]) { + NSNumber *consumeTapEvents = FGMGetValueOrNilFromDict(data, @"consumeTapEvents"); + if (consumeTapEvents) { [self setConsumeTapEvents:[consumeTapEvents boolValue]]; } [self interpretInfoWindow:data]; - NSArray *position = data[@"position"]; - if (position && position != (id)[NSNull null]) { + NSArray *position = FGMGetValueOrNilFromDict(data, @"position"); + if (position) { [self setPosition:[FLTGoogleMapJSONConversions locationFromLatLong:position]]; } - NSNumber *rotation = data[@"rotation"]; - if (rotation && rotation != (id)[NSNull null]) { + NSNumber *rotation = FGMGetValueOrNilFromDict(data, @"rotation"); + if (rotation) { [self setRotation:[rotation doubleValue]]; } - NSNumber *visible = data[@"visible"]; - if (visible && visible != (id)[NSNull null]) { + NSNumber *visible = FGMGetValueOrNilFromDict(data, @"visible"); + if (visible) { [self setVisible:[visible boolValue]]; } - NSNumber *zIndex = data[@"zIndex"]; - if (zIndex && zIndex != (id)[NSNull null]) { + NSNumber *zIndex = FGMGetValueOrNilFromDict(data, @"zIndex"); + if (zIndex) { [self setZIndex:[zIndex intValue]]; } } - (void)interpretInfoWindow:(NSDictionary *)data { - NSDictionary *infoWindow = data[@"infoWindow"]; - if (infoWindow && infoWindow != (id)[NSNull null]) { - NSString *title = infoWindow[@"title"]; - NSString *snippet = infoWindow[@"snippet"]; - if (title && title != (id)[NSNull null]) { + NSDictionary *infoWindow = FGMGetValueOrNilFromDict(data, @"infoWindow"); + if (infoWindow) { + NSString *title = FGMGetValueOrNilFromDict(infoWindow, @"title"); + NSString *snippet = FGMGetValueOrNilFromDict(infoWindow, @"snippet"); + if (title) { [self setInfoWindowTitle:title snippet:snippet]; } NSArray *infoWindowAnchor = infoWindow[@"infoWindowAnchor"]; - if (infoWindowAnchor && infoWindowAnchor != (id)[NSNull null]) { + if (infoWindowAnchor) { [self setInfoWindowAnchor:[FLTGoogleMapJSONConversions pointFromArray:infoWindowAnchor]]; } } @@ -221,15 +237,16 @@ - (UIImage *)extractIconFromData:(NSArray *)iconData @throw exception; } - NSString *assetName = assetData[@"assetName"]; - NSString *scalingMode = assetData[@"bitmapScaling"]; + NSString *assetName = FGMGetValueOrNilFromDict(assetData, @"assetName"); + NSString *scalingMode = FGMGetValueOrNilFromDict(assetData, @"bitmapScaling"); image = [UIImage imageNamed:[registrar lookupKeyForAsset:assetName]]; if ([scalingMode isEqualToString:@"auto"]) { - NSNumber *width = assetData[@"width"]; - NSNumber *height = assetData[@"height"]; - CGFloat imagePixelRatio = [assetData[@"imagePixelRatio"] doubleValue]; + NSNumber *width = FGMGetValueOrNilFromDict(assetData, @"width"); + NSNumber *height = FGMGetValueOrNilFromDict(assetData, @"height"); + CGFloat imagePixelRatio = + [FGMGetValueOrNilFromDict(assetData, @"imagePixelRatio") doubleValue]; if (width || height) { image = [FLTGoogleMapMarkerController scaledImage:image withScale:screenScale]; @@ -252,15 +269,16 @@ - (UIImage *)extractIconFromData:(NSArray *)iconData @throw exception; } - FlutterStandardTypedData *bytes = byteData[@"byteData"]; - NSString *scalingMode = byteData[@"bitmapScaling"]; + FlutterStandardTypedData *bytes = FGMGetValueOrNilFromDict(byteData, @"byteData"); + NSString *scalingMode = FGMGetValueOrNilFromDict(byteData, @"bitmapScaling"); @try { image = [UIImage imageWithData:[bytes data] scale:screenScale]; if ([scalingMode isEqualToString:@"auto"]) { - NSNumber *width = byteData[@"width"]; - NSNumber *height = byteData[@"height"]; - CGFloat imagePixelRatio = [byteData[@"imagePixelRatio"] doubleValue]; + NSNumber *width = FGMGetValueOrNilFromDict(byteData, @"width"); + NSNumber *height = FGMGetValueOrNilFromDict(byteData, @"height"); + CGFloat imagePixelRatio = + [FGMGetValueOrNilFromDict(byteData, @"imagePixelRatio") doubleValue]; if (width || height) { // Before scaling the image, image must be in screenScale @@ -429,7 +447,9 @@ + (BOOL)isScalableWithScaleFactorFromSize:(CGSize)originalSize toSize:(CGSize)ta @interface FLTMarkersController () @property(strong, nonatomic) NSMutableDictionary *markerIdentifierToController; -@property(strong, nonatomic) FlutterMethodChannel *methodChannel; +@property(strong, nonatomic) FGMMapsCallbackApi *callbackHandler; +/// Controller for adding/removing/fetching cluster managers +@property(weak, nonatomic, nullable) FGMClusterManagersController *clusterManagersController; @property(weak, nonatomic) NSObject *registrar; @property(weak, nonatomic) GMSMapView *mapView; @@ -437,56 +457,95 @@ @interface FLTMarkersController () @implementation FLTMarkersController -- (instancetype)initWithMethodChannel:(FlutterMethodChannel *)methodChannel - mapView:(GMSMapView *)mapView - registrar:(NSObject *)registrar { +- (instancetype)initWithMapView:(GMSMapView *)mapView + callbackHandler:(FGMMapsCallbackApi *)callbackHandler + clusterManagersController:(nullable FGMClusterManagersController *)clusterManagersController + registrar:(NSObject *)registrar { self = [super init]; if (self) { - _methodChannel = methodChannel; + _callbackHandler = callbackHandler; _mapView = mapView; + _clusterManagersController = clusterManagersController; _markerIdentifierToController = [[NSMutableDictionary alloc] init]; _registrar = registrar; } return self; } -- (void)addMarkers:(NSArray *)markersToAdd { - for (NSDictionary *marker in markersToAdd) { - CLLocationCoordinate2D position = [FLTMarkersController getPosition:marker]; - NSString *identifier = marker[@"markerId"]; - FLTGoogleMapMarkerController *controller = - [[FLTGoogleMapMarkerController alloc] initMarkerWithPosition:position - identifier:identifier - mapView:self.mapView]; - [controller interpretMarkerOptions:marker - registrar:self.registrar - screenScale:[self getScreenScale]]; - self.markerIdentifierToController[identifier] = controller; +- (void)addMarkers:(NSArray *)markersToAdd { + for (FGMPlatformMarker *marker in markersToAdd) { + [self addJSONMarker:marker.json]; + } +} + +- (void)addJSONMarker:(NSDictionary *)markerToAdd { + CLLocationCoordinate2D position = [FLTMarkersController getPosition:markerToAdd]; + NSString *markerIdentifier = markerToAdd[@"markerId"]; + NSString *clusterManagerIdentifier = markerToAdd[@"clusterManagerId"]; + GMSMarker *marker = [GMSMarker markerWithPosition:position]; + FLTGoogleMapMarkerController *controller = + [[FLTGoogleMapMarkerController alloc] initWithMarker:marker + markerIdentifier:markerIdentifier + clusterManagerIdentifier:clusterManagerIdentifier + mapView:self.mapView]; + [controller interpretMarkerOptions:markerToAdd + registrar:self.registrar + screenScale:[self getScreenScale]]; + if (clusterManagerIdentifier) { + GMUClusterManager *clusterManager = + [_clusterManagersController clusterManagerWithIdentifier:clusterManagerIdentifier]; + if ([marker conformsToProtocol:@protocol(GMUClusterItem)]) { + [clusterManager addItem:(id)marker]; + } } + self.markerIdentifierToController[markerIdentifier] = controller; } -- (void)changeMarkers:(NSArray *)markersToChange { - for (NSDictionary *marker in markersToChange) { - NSString *identifier = marker[@"markerId"]; - FLTGoogleMapMarkerController *controller = self.markerIdentifierToController[identifier]; - if (!controller) { - continue; - } - [controller interpretMarkerOptions:marker +- (void)changeMarkers:(NSArray *)markersToChange { + for (FGMPlatformMarker *marker in markersToChange) { + [self changeMarker:marker]; + } +} + +- (void)changeMarker:(FGMPlatformMarker *)markerToChange { + NSString *markerIdentifier = markerToChange.json[@"markerId"]; + NSString *clusterManagerIdentifier = markerToChange.json[@"clusterManagerId"]; + + FLTGoogleMapMarkerController *controller = self.markerIdentifierToController[markerIdentifier]; + if (!controller) { + return; + } + NSString *previousClusterManagerIdentifier = [controller clusterManagerIdentifier]; + if (![previousClusterManagerIdentifier isEqualToString:clusterManagerIdentifier]) { + [self removeMarker:markerIdentifier]; + [self addJSONMarker:markerToChange.json]; + } else { + [controller interpretMarkerOptions:markerToChange.json registrar:self.registrar screenScale:[self getScreenScale]]; } } -- (void)removeMarkersWithIdentifiers:(NSArray *)identifiers { +- (void)removeMarkersWithIdentifiers:(NSArray *)identifiers { for (NSString *identifier in identifiers) { - FLTGoogleMapMarkerController *controller = self.markerIdentifierToController[identifier]; - if (!controller) { - continue; - } + [self removeMarker:identifier]; + } +} + +- (void)removeMarker:(NSString *)identifier { + FLTGoogleMapMarkerController *controller = self.markerIdentifierToController[identifier]; + if (!controller) { + return; + } + NSString *clusterManagerIdentifier = [controller clusterManagerIdentifier]; + if (clusterManagerIdentifier) { + GMUClusterManager *clusterManager = + [_clusterManagersController clusterManagerWithIdentifier:clusterManagerIdentifier]; + [clusterManager removeItem:(id)controller.marker]; + } else { [controller removeMarker]; - [self.markerIdentifierToController removeObjectForKey:identifier]; } + [self.markerIdentifierToController removeObjectForKey:identifier]; } - (BOOL)didTapMarkerWithIdentifier:(NSString *)identifier { @@ -497,7 +556,9 @@ - (BOOL)didTapMarkerWithIdentifier:(NSString *)identifier { if (!controller) { return NO; } - [self.methodChannel invokeMethod:@"marker#onTap" arguments:@{@"markerId" : identifier}]; + [self.callbackHandler didTapMarkerWithIdentifier:identifier + completion:^(FlutterError *_Nullable _){ + }]; return controller.consumeTapEvents; } @@ -510,11 +571,11 @@ - (void)didStartDraggingMarkerWithIdentifier:(NSString *)identifier if (!controller) { return; } - [self.methodChannel invokeMethod:@"marker#onDragStart" - arguments:@{ - @"markerId" : identifier, - @"position" : [FLTGoogleMapJSONConversions arrayFromLocation:location] - }]; + [self.callbackHandler + didStartDragForMarkerWithIdentifier:identifier + atPosition:FGMGetPigeonLatLngForCoordinate(location) + completion:^(FlutterError *_Nullable _){ + }]; } - (void)didDragMarkerWithIdentifier:(NSString *)identifier @@ -526,11 +587,10 @@ - (void)didDragMarkerWithIdentifier:(NSString *)identifier if (!controller) { return; } - [self.methodChannel invokeMethod:@"marker#onDrag" - arguments:@{ - @"markerId" : identifier, - @"position" : [FLTGoogleMapJSONConversions arrayFromLocation:location] - }]; + [self.callbackHandler didDragMarkerWithIdentifier:identifier + atPosition:FGMGetPigeonLatLngForCoordinate(location) + completion:^(FlutterError *_Nullable _){ + }]; } - (void)didEndDraggingMarkerWithIdentifier:(NSString *)identifier @@ -539,52 +599,58 @@ - (void)didEndDraggingMarkerWithIdentifier:(NSString *)identifier if (!controller) { return; } - [self.methodChannel invokeMethod:@"marker#onDragEnd" - arguments:@{ - @"markerId" : identifier, - @"position" : [FLTGoogleMapJSONConversions arrayFromLocation:location] - }]; + [self.callbackHandler didEndDragForMarkerWithIdentifier:identifier + atPosition:FGMGetPigeonLatLngForCoordinate(location) + completion:^(FlutterError *_Nullable _){ + }]; } - (void)didTapInfoWindowOfMarkerWithIdentifier:(NSString *)identifier { if (identifier && self.markerIdentifierToController[identifier]) { - [self.methodChannel invokeMethod:@"infoWindow#onTap" arguments:@{@"markerId" : identifier}]; + [self.callbackHandler didTapInfoWindowOfMarkerWithIdentifier:identifier + completion:^(FlutterError *_Nullable _){ + }]; } } -- (void)showMarkerInfoWindowWithIdentifier:(NSString *)identifier result:(FlutterResult)result { +- (void)showMarkerInfoWindowWithIdentifier:(NSString *)identifier + error: + (FlutterError *_Nullable __autoreleasing *_Nonnull)error { FLTGoogleMapMarkerController *controller = self.markerIdentifierToController[identifier]; if (controller) { [controller showInfoWindow]; - result(nil); } else { - result([FlutterError errorWithCode:@"Invalid markerId" - message:@"showInfoWindow called with invalid markerId" - details:nil]); + *error = [FlutterError errorWithCode:@"Invalid markerId" + message:@"showInfoWindow called with invalid markerId" + details:nil]; } } -- (void)hideMarkerInfoWindowWithIdentifier:(NSString *)identifier result:(FlutterResult)result { +- (void)hideMarkerInfoWindowWithIdentifier:(NSString *)identifier + error: + (FlutterError *_Nullable __autoreleasing *_Nonnull)error { FLTGoogleMapMarkerController *controller = self.markerIdentifierToController[identifier]; if (controller) { [controller hideInfoWindow]; - result(nil); } else { - result([FlutterError errorWithCode:@"Invalid markerId" - message:@"hideInfoWindow called with invalid markerId" - details:nil]); + *error = [FlutterError errorWithCode:@"Invalid markerId" + message:@"hideInfoWindow called with invalid markerId" + details:nil]; } } -- (void)isInfoWindowShownForMarkerWithIdentifier:(NSString *)identifier - result:(FlutterResult)result { +- (nullable NSNumber *) + isInfoWindowShownForMarkerWithIdentifier:(NSString *)identifier + error:(FlutterError *_Nullable __autoreleasing *_Nonnull) + error { FLTGoogleMapMarkerController *controller = self.markerIdentifierToController[identifier]; if (controller) { - result(@([controller isInfoWindowShown])); + return @([controller isInfoWindowShown]); } else { - result([FlutterError errorWithCode:@"Invalid markerId" - message:@"isInfoWindowShown called with invalid markerId" - details:nil]); + *error = [FlutterError errorWithCode:@"Invalid markerId" + message:@"isInfoWindowShown called with invalid markerId" + details:nil]; + return nil; } } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolygonController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolygonController.h index bd0c9110200e..afc8024d2b53 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolygonController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolygonController.h @@ -5,21 +5,23 @@ #import #import +#import "messages.g.h" + // Defines polygon controllable by Flutter. @interface FLTGoogleMapPolygonController : NSObject -- (instancetype)initPolygonWithPath:(GMSMutablePath *)path - identifier:(NSString *)identifier - mapView:(GMSMapView *)mapView; +- (instancetype)initWithPath:(GMSMutablePath *)path + identifier:(NSString *)identifier + mapView:(GMSMapView *)mapView; - (void)removePolygon; @end @interface FLTPolygonsController : NSObject -- (instancetype)init:(FlutterMethodChannel *)methodChannel - mapView:(GMSMapView *)mapView - registrar:(NSObject *)registrar; -- (void)addPolygons:(NSArray *)polygonsToAdd; -- (void)changePolygons:(NSArray *)polygonsToChange; -- (void)removePolygonWithIdentifiers:(NSArray *)identifiers; +- (instancetype)initWithMapView:(GMSMapView *)mapView + callbackHandler:(FGMMapsCallbackApi *)callbackHandler + registrar:(NSObject *)registrar; +- (void)addPolygons:(NSArray *)polygonsToAdd; +- (void)changePolygons:(NSArray *)polygonsToChange; +- (void)removePolygonWithIdentifiers:(NSArray *)identifiers; - (void)didTapPolygonWithIdentifier:(NSString *)identifier; - (bool)hasPolygonWithIdentifier:(NSString *)identifier; @end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolygonController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolygonController.m index 398adfcacecb..a66b7f5d39d7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolygonController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolygonController.m @@ -14,9 +14,9 @@ @interface FLTGoogleMapPolygonController () @implementation FLTGoogleMapPolygonController -- (instancetype)initPolygonWithPath:(GMSMutablePath *)path - identifier:(NSString *)identifier - mapView:(GMSMapView *)mapView { +- (instancetype)initWithPath:(GMSMutablePath *)path + identifier:(NSString *)identifier + mapView:(GMSMapView *)mapView { self = [super init]; if (self) { _polygon = [GMSPolygon polygonWithPath:path]; @@ -73,43 +73,43 @@ - (void)setStrokeWidth:(CGFloat)width { - (void)interpretPolygonOptions:(NSDictionary *)data registrar:(NSObject *)registrar { - NSNumber *consumeTapEvents = data[@"consumeTapEvents"]; - if (consumeTapEvents && consumeTapEvents != (id)[NSNull null]) { + NSNumber *consumeTapEvents = FGMGetValueOrNilFromDict(data, @"consumeTapEvents"); + if (consumeTapEvents) { [self setConsumeTapEvents:[consumeTapEvents boolValue]]; } - NSNumber *visible = data[@"visible"]; - if (visible && visible != (id)[NSNull null]) { + NSNumber *visible = FGMGetValueOrNilFromDict(data, @"visible"); + if (visible) { [self setVisible:[visible boolValue]]; } - NSNumber *zIndex = data[@"zIndex"]; - if (zIndex && zIndex != (id)[NSNull null]) { + NSNumber *zIndex = FGMGetValueOrNilFromDict(data, @"zIndex"); + if (zIndex) { [self setZIndex:[zIndex intValue]]; } - NSArray *points = data[@"points"]; - if (points && points != (id)[NSNull null]) { + NSArray *points = FGMGetValueOrNilFromDict(data, @"points"); + if (points) { [self setPoints:[FLTGoogleMapJSONConversions pointsFromLatLongs:points]]; } - NSArray *holes = data[@"holes"]; - if (holes && holes != (id)[NSNull null]) { + NSArray *holes = FGMGetValueOrNilFromDict(data, @"holes"); + if (holes) { [self setHoles:[FLTGoogleMapJSONConversions holesFromPointsArray:holes]]; } - NSNumber *fillColor = data[@"fillColor"]; - if (fillColor && fillColor != (id)[NSNull null]) { + NSNumber *fillColor = FGMGetValueOrNilFromDict(data, @"fillColor"); + if (fillColor) { [self setFillColor:[FLTGoogleMapJSONConversions colorFromRGBA:fillColor]]; } - NSNumber *strokeColor = data[@"strokeColor"]; - if (strokeColor && strokeColor != (id)[NSNull null]) { + NSNumber *strokeColor = FGMGetValueOrNilFromDict(data, @"strokeColor"); + if (strokeColor) { [self setStrokeColor:[FLTGoogleMapJSONConversions colorFromRGBA:strokeColor]]; } - NSNumber *strokeWidth = data[@"strokeWidth"]; - if (strokeWidth && strokeWidth != (id)[NSNull null]) { + NSNumber *strokeWidth = FGMGetValueOrNilFromDict(data, @"strokeWidth"); + if (strokeWidth) { [self setStrokeWidth:[strokeWidth intValue]]; } } @@ -119,7 +119,7 @@ - (void)interpretPolygonOptions:(NSDictionary *)data @interface FLTPolygonsController () @property(strong, nonatomic) NSMutableDictionary *polygonIdentifierToController; -@property(strong, nonatomic) FlutterMethodChannel *methodChannel; +@property(strong, nonatomic) FGMMapsCallbackApi *callbackHandler; @property(weak, nonatomic) NSObject *registrar; @property(weak, nonatomic) GMSMapView *mapView; @@ -127,12 +127,12 @@ @interface FLTPolygonsController () @implementation FLTPolygonsController -- (instancetype)init:(FlutterMethodChannel *)methodChannel - mapView:(GMSMapView *)mapView - registrar:(NSObject *)registrar { +- (instancetype)initWithMapView:(GMSMapView *)mapView + callbackHandler:(FGMMapsCallbackApi *)callbackHandler + registrar:(NSObject *)registrar { self = [super init]; if (self) { - _methodChannel = methodChannel; + _callbackHandler = callbackHandler; _mapView = mapView; _polygonIdentifierToController = [NSMutableDictionary dictionaryWithCapacity:1]; _registrar = registrar; @@ -140,31 +140,28 @@ - (instancetype)init:(FlutterMethodChannel *)methodChannel return self; } -- (void)addPolygons:(NSArray *)polygonsToAdd { - for (NSDictionary *polygon in polygonsToAdd) { - GMSMutablePath *path = [FLTPolygonsController getPath:polygon]; - NSString *identifier = polygon[@"polygonId"]; +- (void)addPolygons:(NSArray *)polygonsToAdd { + for (FGMPlatformPolygon *polygon in polygonsToAdd) { + GMSMutablePath *path = [FLTPolygonsController getPath:polygon.json]; + NSString *identifier = polygon.json[@"polygonId"]; FLTGoogleMapPolygonController *controller = - [[FLTGoogleMapPolygonController alloc] initPolygonWithPath:path - identifier:identifier - mapView:self.mapView]; - [controller interpretPolygonOptions:polygon registrar:self.registrar]; + [[FLTGoogleMapPolygonController alloc] initWithPath:path + identifier:identifier + mapView:self.mapView]; + [controller interpretPolygonOptions:polygon.json registrar:self.registrar]; self.polygonIdentifierToController[identifier] = controller; } } -- (void)changePolygons:(NSArray *)polygonsToChange { - for (NSDictionary *polygon in polygonsToChange) { - NSString *identifier = polygon[@"polygonId"]; +- (void)changePolygons:(NSArray *)polygonsToChange { + for (FGMPlatformPolygon *polygon in polygonsToChange) { + NSString *identifier = polygon.json[@"polygonId"]; FLTGoogleMapPolygonController *controller = self.polygonIdentifierToController[identifier]; - if (!controller) { - continue; - } - [controller interpretPolygonOptions:polygon registrar:self.registrar]; + [controller interpretPolygonOptions:polygon.json registrar:self.registrar]; } } -- (void)removePolygonWithIdentifiers:(NSArray *)identifiers { +- (void)removePolygonWithIdentifiers:(NSArray *)identifiers { for (NSString *identifier in identifiers) { FLTGoogleMapPolygonController *controller = self.polygonIdentifierToController[identifier]; if (!controller) { @@ -183,7 +180,9 @@ - (void)didTapPolygonWithIdentifier:(NSString *)identifier { if (!controller) { return; } - [self.methodChannel invokeMethod:@"polygon#onTap" arguments:@{@"polygonId" : identifier}]; + [self.callbackHandler didTapPolygonWithIdentifier:identifier + completion:^(FlutterError *_Nullable _){ + }]; } - (bool)hasPolygonWithIdentifier:(NSString *)identifier { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolylineController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolylineController.h index 63061392e5ad..da86f41b8193 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolylineController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolylineController.h @@ -5,11 +5,13 @@ #import #import +#import "messages.g.h" + // Defines polyline controllable by Flutter. @interface FLTGoogleMapPolylineController : NSObject -- (instancetype)initPolylineWithPath:(GMSMutablePath *)path - identifier:(NSString *)identifier - mapView:(GMSMapView *)mapView; +- (instancetype)initWithPath:(GMSMutablePath *)path + identifier:(NSString *)identifier + mapView:(GMSMapView *)mapView; - (void)removePolyline; /// Sets the pattern on polyline controller @@ -20,12 +22,12 @@ @end @interface FLTPolylinesController : NSObject -- (instancetype)init:(FlutterMethodChannel *)methodChannel - mapView:(GMSMapView *)mapView - registrar:(NSObject *)registrar; -- (void)addPolylines:(NSArray *)polylinesToAdd; -- (void)changePolylines:(NSArray *)polylinesToChange; -- (void)removePolylineWithIdentifiers:(NSArray *)identifiers; +- (instancetype)initWithMapView:(GMSMapView *)mapView + callbackHandler:(FGMMapsCallbackApi *)callbackHandler + registrar:(NSObject *)registrar; +- (void)addPolylines:(NSArray *)polylinesToAdd; +- (void)changePolylines:(NSArray *)polylinesToChange; +- (void)removePolylineWithIdentifiers:(NSArray *)identifiers; - (void)didTapPolylineWithIdentifier:(NSString *)identifier; - (bool)hasPolylineWithIdentifier:(NSString *)identifier; @end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolylineController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolylineController.m index 47334576b1c7..44a31b18b531 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolylineController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolylineController.m @@ -12,17 +12,11 @@ @interface FLTGoogleMapPolylineController () @end -/// Returns dict[key], or nil if dict[key] is NSNull. -static id GetValueOrNilFromDict(NSDictionary *dict, NSString *key) { - id value = dict[key]; - return value == [NSNull null] ? nil : value; -} - @implementation FLTGoogleMapPolylineController -- (instancetype)initPolylineWithPath:(GMSMutablePath *)path - identifier:(NSString *)identifier - mapView:(GMSMapView *)mapView { +- (instancetype)initWithPath:(GMSMutablePath *)path + identifier:(NSString *)identifier + mapView:(GMSMapView *)mapView { self = [super init]; if (self) { _polyline = [GMSPolyline polylineWithPath:path]; @@ -71,42 +65,42 @@ - (void)setPattern:(NSArray *)styles lengths:(NSArray *)registrar { - NSNumber *consumeTapEvents = GetValueOrNilFromDict(data, @"consumeTapEvents"); + NSNumber *consumeTapEvents = FGMGetValueOrNilFromDict(data, @"consumeTapEvents"); if (consumeTapEvents) { [self setConsumeTapEvents:[consumeTapEvents boolValue]]; } - NSNumber *visible = GetValueOrNilFromDict(data, @"visible"); + NSNumber *visible = FGMGetValueOrNilFromDict(data, @"visible"); if (visible) { [self setVisible:[visible boolValue]]; } - NSNumber *zIndex = GetValueOrNilFromDict(data, @"zIndex"); + NSNumber *zIndex = FGMGetValueOrNilFromDict(data, @"zIndex"); if (zIndex) { [self setZIndex:[zIndex intValue]]; } - NSArray *points = GetValueOrNilFromDict(data, @"points"); + NSArray *points = FGMGetValueOrNilFromDict(data, @"points"); if (points) { [self setPoints:[FLTGoogleMapJSONConversions pointsFromLatLongs:points]]; } - NSNumber *strokeColor = GetValueOrNilFromDict(data, @"color"); + NSNumber *strokeColor = FGMGetValueOrNilFromDict(data, @"color"); if (strokeColor) { [self setColor:[FLTGoogleMapJSONConversions colorFromRGBA:strokeColor]]; } - NSNumber *strokeWidth = GetValueOrNilFromDict(data, @"width"); + NSNumber *strokeWidth = FGMGetValueOrNilFromDict(data, @"width"); if (strokeWidth) { [self setStrokeWidth:[strokeWidth intValue]]; } - NSNumber *geodesic = GetValueOrNilFromDict(data, @"geodesic"); + NSNumber *geodesic = FGMGetValueOrNilFromDict(data, @"geodesic"); if (geodesic) { [self setGeodesic:geodesic.boolValue]; } - NSArray *patterns = GetValueOrNilFromDict(data, @"pattern"); + NSArray *patterns = FGMGetValueOrNilFromDict(data, @"pattern"); if (patterns) { [self setPattern:[FLTGoogleMapJSONConversions strokeStylesFromPatterns:patterns @@ -120,7 +114,7 @@ - (void)interpretPolylineOptions:(NSDictionary *)data @interface FLTPolylinesController () @property(strong, nonatomic) NSMutableDictionary *polylineIdentifierToController; -@property(strong, nonatomic) FlutterMethodChannel *methodChannel; +@property(strong, nonatomic) FGMMapsCallbackApi *callbackHandler; @property(weak, nonatomic) NSObject *registrar; @property(weak, nonatomic) GMSMapView *mapView; @@ -129,41 +123,41 @@ @interface FLTPolylinesController () @implementation FLTPolylinesController -- (instancetype)init:(FlutterMethodChannel *)methodChannel - mapView:(GMSMapView *)mapView - registrar:(NSObject *)registrar { +- (instancetype)initWithMapView:(GMSMapView *)mapView + callbackHandler:(FGMMapsCallbackApi *)callbackHandler + registrar:(NSObject *)registrar { self = [super init]; if (self) { - _methodChannel = methodChannel; + _callbackHandler = callbackHandler; _mapView = mapView; _polylineIdentifierToController = [NSMutableDictionary dictionaryWithCapacity:1]; _registrar = registrar; } return self; } -- (void)addPolylines:(NSArray *)polylinesToAdd { - for (NSDictionary *polyline in polylinesToAdd) { - GMSMutablePath *path = [FLTPolylinesController pathForPolyline:polyline]; - NSString *identifier = polyline[@"polylineId"]; + +- (void)addPolylines:(NSArray *)polylinesToAdd { + for (FGMPlatformPolyline *polyline in polylinesToAdd) { + GMSMutablePath *path = [FLTPolylinesController pathForPolyline:polyline.json]; + NSString *identifier = polyline.json[@"polylineId"]; FLTGoogleMapPolylineController *controller = - [[FLTGoogleMapPolylineController alloc] initPolylineWithPath:path - identifier:identifier - mapView:self.mapView]; - [controller interpretPolylineOptions:polyline registrar:self.registrar]; + [[FLTGoogleMapPolylineController alloc] initWithPath:path + identifier:identifier + mapView:self.mapView]; + [controller interpretPolylineOptions:polyline.json registrar:self.registrar]; self.polylineIdentifierToController[identifier] = controller; } } -- (void)changePolylines:(NSArray *)polylinesToChange { - for (NSDictionary *polyline in polylinesToChange) { - NSString *identifier = polyline[@"polylineId"]; + +- (void)changePolylines:(NSArray *)polylinesToChange { + for (FGMPlatformPolyline *polyline in polylinesToChange) { + NSString *identifier = polyline.json[@"polylineId"]; FLTGoogleMapPolylineController *controller = self.polylineIdentifierToController[identifier]; - if (!controller) { - continue; - } - [controller interpretPolylineOptions:polyline registrar:self.registrar]; + [controller interpretPolylineOptions:polyline.json registrar:self.registrar]; } } -- (void)removePolylineWithIdentifiers:(NSArray *)identifiers { + +- (void)removePolylineWithIdentifiers:(NSArray *)identifiers { for (NSString *identifier in identifiers) { FLTGoogleMapPolylineController *controller = self.polylineIdentifierToController[identifier]; if (!controller) { @@ -173,6 +167,7 @@ - (void)removePolylineWithIdentifiers:(NSArray *)identifiers { [self.polylineIdentifierToController removeObjectForKey:identifier]; } } + - (void)didTapPolylineWithIdentifier:(NSString *)identifier { if (!identifier) { return; @@ -181,14 +176,18 @@ - (void)didTapPolylineWithIdentifier:(NSString *)identifier { if (!controller) { return; } - [self.methodChannel invokeMethod:@"polyline#onTap" arguments:@{@"polylineId" : identifier}]; + [self.callbackHandler didTapPolylineWithIdentifier:identifier + completion:^(FlutterError *_Nullable _){ + }]; } + - (bool)hasPolylineWithIdentifier:(NSString *)identifier { if (!identifier) { return false; } return self.polylineIdentifierToController[identifier] != nil; } + + (GMSMutablePath *)pathForPolyline:(NSDictionary *)polyline { NSArray *pointArray = polyline[@"points"]; NSArray *points = [FLTGoogleMapJSONConversions pointsFromLatLongs:pointArray]; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/google_maps_flutter_ios-umbrella.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/google_maps_flutter_ios-umbrella.h index 4f331de069b4..c88ee79c7a0d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/google_maps_flutter_ios-umbrella.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/google_maps_flutter_ios-umbrella.h @@ -3,6 +3,8 @@ // found in the LICENSE file. #import +#import +#import #import #import #import diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/messages.g.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/messages.g.h new file mode 100644 index 000000000000..088b8a657147 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/messages.g.h @@ -0,0 +1,532 @@ +// 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 (v22.4.2), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +#import + +@protocol FlutterBinaryMessenger; +@protocol FlutterMessageCodec; +@class FlutterError; +@class FlutterStandardTypedData; + +NS_ASSUME_NONNULL_BEGIN + +/// Pigeon equivalent of MapType +typedef NS_ENUM(NSUInteger, FGMPlatformMapType) { + FGMPlatformMapTypeNone = 0, + FGMPlatformMapTypeNormal = 1, + FGMPlatformMapTypeSatellite = 2, + FGMPlatformMapTypeTerrain = 3, + FGMPlatformMapTypeHybrid = 4, +}; + +/// Wrapper for FGMPlatformMapType to allow for nullability. +@interface FGMPlatformMapTypeBox : NSObject +@property(nonatomic, assign) FGMPlatformMapType value; +- (instancetype)initWithValue:(FGMPlatformMapType)value; +@end + +@class FGMPlatformCameraPosition; +@class FGMPlatformCameraUpdate; +@class FGMPlatformCircle; +@class FGMPlatformHeatmap; +@class FGMPlatformCluster; +@class FGMPlatformClusterManager; +@class FGMPlatformMarker; +@class FGMPlatformPolygon; +@class FGMPlatformPolyline; +@class FGMPlatformTile; +@class FGMPlatformTileOverlay; +@class FGMPlatformEdgeInsets; +@class FGMPlatformLatLng; +@class FGMPlatformLatLngBounds; +@class FGMPlatformCameraTargetBounds; +@class FGMPlatformMapViewCreationParams; +@class FGMPlatformMapConfiguration; +@class FGMPlatformPoint; +@class FGMPlatformTileLayer; +@class FGMPlatformZoomRange; + +/// Pigeon representatation of a CameraPosition. +@interface FGMPlatformCameraPosition : NSObject +/// `init` unavailable to enforce nonnull fields, see the `make` class method. +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)makeWithBearing:(double)bearing + target:(FGMPlatformLatLng *)target + tilt:(double)tilt + zoom:(double)zoom; +@property(nonatomic, assign) double bearing; +@property(nonatomic, strong) FGMPlatformLatLng *target; +@property(nonatomic, assign) double tilt; +@property(nonatomic, assign) double zoom; +@end + +/// Pigeon representation of a CameraUpdate. +@interface FGMPlatformCameraUpdate : NSObject +/// `init` unavailable to enforce nonnull fields, see the `make` class method. +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)makeWithJson:(id)json; +/// The update data, as JSON. This should only be set from +/// CameraUpdate.toJson, and the native code must interpret it according to the +/// internal implementation details of the CameraUpdate class. +@property(nonatomic, strong) id json; +@end + +/// Pigeon equivalent of the Circle class. +@interface FGMPlatformCircle : NSObject +/// `init` unavailable to enforce nonnull fields, see the `make` class method. +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)makeWithJson:(id)json; +/// The circle data, as JSON. This should only be set from +/// Circle.toJson, and the native code must interpret it according to the +/// internal implementation details of that method. +@property(nonatomic, strong) id json; +@end + +/// Pigeon equivalent of the Heatmap class. +@interface FGMPlatformHeatmap : NSObject +/// `init` unavailable to enforce nonnull fields, see the `make` class method. +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)makeWithJson:(id)json; +/// The heatmap data, as JSON. This should only be set from +/// Heatmap.toJson, and the native code must interpret it according to the +/// internal implementation details of that method. +@property(nonatomic, strong) id json; +@end + +/// Pigeon equivalent of Cluster. +@interface FGMPlatformCluster : NSObject +/// `init` unavailable to enforce nonnull fields, see the `make` class method. +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)makeWithClusterManagerId:(NSString *)clusterManagerId + position:(FGMPlatformLatLng *)position + bounds:(FGMPlatformLatLngBounds *)bounds + markerIds:(NSArray *)markerIds; +@property(nonatomic, copy) NSString *clusterManagerId; +@property(nonatomic, strong) FGMPlatformLatLng *position; +@property(nonatomic, strong) FGMPlatformLatLngBounds *bounds; +@property(nonatomic, copy) NSArray *markerIds; +@end + +/// Pigeon equivalent of the ClusterManager class. +@interface FGMPlatformClusterManager : NSObject +/// `init` unavailable to enforce nonnull fields, see the `make` class method. +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)makeWithIdentifier:(NSString *)identifier; +@property(nonatomic, copy) NSString *identifier; +@end + +/// Pigeon equivalent of the Marker class. +@interface FGMPlatformMarker : NSObject +/// `init` unavailable to enforce nonnull fields, see the `make` class method. +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)makeWithJson:(id)json; +/// The marker data, as JSON. This should only be set from +/// Marker.toJson, and the native code must interpret it according to the +/// internal implementation details of that method. +@property(nonatomic, strong) id json; +@end + +/// Pigeon equivalent of the Polygon class. +@interface FGMPlatformPolygon : NSObject +/// `init` unavailable to enforce nonnull fields, see the `make` class method. +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)makeWithJson:(id)json; +/// The polygon data, as JSON. This should only be set from +/// Polygon.toJson, and the native code must interpret it according to the +/// internal implementation details of that method. +@property(nonatomic, strong) id json; +@end + +/// Pigeon equivalent of the Polyline class. +@interface FGMPlatformPolyline : NSObject +/// `init` unavailable to enforce nonnull fields, see the `make` class method. +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)makeWithJson:(id)json; +/// The polyline data, as JSON. This should only be set from +/// Polyline.toJson, and the native code must interpret it according to the +/// internal implementation details of that method. +@property(nonatomic, strong) id json; +@end + +/// Pigeon equivalent of the Tile class. +@interface FGMPlatformTile : NSObject +/// `init` unavailable to enforce nonnull fields, see the `make` class method. +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)makeWithWidth:(NSInteger)width + height:(NSInteger)height + data:(nullable FlutterStandardTypedData *)data; +@property(nonatomic, assign) NSInteger width; +@property(nonatomic, assign) NSInteger height; +@property(nonatomic, strong, nullable) FlutterStandardTypedData *data; +@end + +/// Pigeon equivalent of the TileOverlay class. +@interface FGMPlatformTileOverlay : NSObject +/// `init` unavailable to enforce nonnull fields, see the `make` class method. +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)makeWithJson:(id)json; +/// The tile overlay data, as JSON. This should only be set from +/// TileOverlay.toJson, and the native code must interpret it according to the +/// internal implementation details of that method. +@property(nonatomic, strong) id json; +@end + +/// Pigeon equivalent of Flutter's EdgeInsets. +@interface FGMPlatformEdgeInsets : NSObject +/// `init` unavailable to enforce nonnull fields, see the `make` class method. +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)makeWithTop:(double)top bottom:(double)bottom left:(double)left right:(double)right; +@property(nonatomic, assign) double top; +@property(nonatomic, assign) double bottom; +@property(nonatomic, assign) double left; +@property(nonatomic, assign) double right; +@end + +/// Pigeon equivalent of LatLng. +@interface FGMPlatformLatLng : NSObject +/// `init` unavailable to enforce nonnull fields, see the `make` class method. +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)makeWithLatitude:(double)latitude longitude:(double)longitude; +@property(nonatomic, assign) double latitude; +@property(nonatomic, assign) double longitude; +@end + +/// Pigeon equivalent of LatLngBounds. +@interface FGMPlatformLatLngBounds : NSObject +/// `init` unavailable to enforce nonnull fields, see the `make` class method. +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)makeWithNortheast:(FGMPlatformLatLng *)northeast + southwest:(FGMPlatformLatLng *)southwest; +@property(nonatomic, strong) FGMPlatformLatLng *northeast; +@property(nonatomic, strong) FGMPlatformLatLng *southwest; +@end + +/// Pigeon equivalent of CameraTargetBounds. +/// +/// As with the Dart version, it exists to distinguish between not setting a +/// a target, and having an explicitly unbounded target (null [bounds]). +@interface FGMPlatformCameraTargetBounds : NSObject ++ (instancetype)makeWithBounds:(nullable FGMPlatformLatLngBounds *)bounds; +@property(nonatomic, strong, nullable) FGMPlatformLatLngBounds *bounds; +@end + +/// Information passed to the platform view creation. +@interface FGMPlatformMapViewCreationParams : NSObject +/// `init` unavailable to enforce nonnull fields, see the `make` class method. +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype) + makeWithInitialCameraPosition:(FGMPlatformCameraPosition *)initialCameraPosition + mapConfiguration:(FGMPlatformMapConfiguration *)mapConfiguration + initialCircles:(NSArray *)initialCircles + initialMarkers:(NSArray *)initialMarkers + initialPolygons:(NSArray *)initialPolygons + initialPolylines:(NSArray *)initialPolylines + initialHeatmaps:(NSArray *)initialHeatmaps + initialTileOverlays:(NSArray *)initialTileOverlays + initialClusterManagers:(NSArray *)initialClusterManagers; +@property(nonatomic, strong) FGMPlatformCameraPosition *initialCameraPosition; +@property(nonatomic, strong) FGMPlatformMapConfiguration *mapConfiguration; +@property(nonatomic, copy) NSArray *initialCircles; +@property(nonatomic, copy) NSArray *initialMarkers; +@property(nonatomic, copy) NSArray *initialPolygons; +@property(nonatomic, copy) NSArray *initialPolylines; +@property(nonatomic, copy) NSArray *initialHeatmaps; +@property(nonatomic, copy) NSArray *initialTileOverlays; +@property(nonatomic, copy) NSArray *initialClusterManagers; +@end + +/// Pigeon equivalent of MapConfiguration. +@interface FGMPlatformMapConfiguration : NSObject ++ (instancetype)makeWithCompassEnabled:(nullable NSNumber *)compassEnabled + cameraTargetBounds:(nullable FGMPlatformCameraTargetBounds *)cameraTargetBounds + mapType:(nullable FGMPlatformMapTypeBox *)mapType + minMaxZoomPreference:(nullable FGMPlatformZoomRange *)minMaxZoomPreference + rotateGesturesEnabled:(nullable NSNumber *)rotateGesturesEnabled + scrollGesturesEnabled:(nullable NSNumber *)scrollGesturesEnabled + tiltGesturesEnabled:(nullable NSNumber *)tiltGesturesEnabled + trackCameraPosition:(nullable NSNumber *)trackCameraPosition + zoomGesturesEnabled:(nullable NSNumber *)zoomGesturesEnabled + myLocationEnabled:(nullable NSNumber *)myLocationEnabled + myLocationButtonEnabled:(nullable NSNumber *)myLocationButtonEnabled + padding:(nullable FGMPlatformEdgeInsets *)padding + indoorViewEnabled:(nullable NSNumber *)indoorViewEnabled + trafficEnabled:(nullable NSNumber *)trafficEnabled + buildingsEnabled:(nullable NSNumber *)buildingsEnabled + cloudMapId:(nullable NSString *)cloudMapId + style:(nullable NSString *)style; +@property(nonatomic, strong, nullable) NSNumber *compassEnabled; +@property(nonatomic, strong, nullable) FGMPlatformCameraTargetBounds *cameraTargetBounds; +@property(nonatomic, strong, nullable) FGMPlatformMapTypeBox *mapType; +@property(nonatomic, strong, nullable) FGMPlatformZoomRange *minMaxZoomPreference; +@property(nonatomic, strong, nullable) NSNumber *rotateGesturesEnabled; +@property(nonatomic, strong, nullable) NSNumber *scrollGesturesEnabled; +@property(nonatomic, strong, nullable) NSNumber *tiltGesturesEnabled; +@property(nonatomic, strong, nullable) NSNumber *trackCameraPosition; +@property(nonatomic, strong, nullable) NSNumber *zoomGesturesEnabled; +@property(nonatomic, strong, nullable) NSNumber *myLocationEnabled; +@property(nonatomic, strong, nullable) NSNumber *myLocationButtonEnabled; +@property(nonatomic, strong, nullable) FGMPlatformEdgeInsets *padding; +@property(nonatomic, strong, nullable) NSNumber *indoorViewEnabled; +@property(nonatomic, strong, nullable) NSNumber *trafficEnabled; +@property(nonatomic, strong, nullable) NSNumber *buildingsEnabled; +@property(nonatomic, copy, nullable) NSString *cloudMapId; +@property(nonatomic, copy, nullable) NSString *style; +@end + +/// Pigeon representation of an x,y coordinate. +@interface FGMPlatformPoint : NSObject +/// `init` unavailable to enforce nonnull fields, see the `make` class method. +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)makeWithX:(double)x y:(double)y; +@property(nonatomic, assign) double x; +@property(nonatomic, assign) double y; +@end + +/// Pigeon equivalent of GMSTileLayer properties. +@interface FGMPlatformTileLayer : NSObject +/// `init` unavailable to enforce nonnull fields, see the `make` class method. +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)makeWithVisible:(BOOL)visible + fadeIn:(BOOL)fadeIn + opacity:(double)opacity + zIndex:(NSInteger)zIndex; +@property(nonatomic, assign) BOOL visible; +@property(nonatomic, assign) BOOL fadeIn; +@property(nonatomic, assign) double opacity; +@property(nonatomic, assign) NSInteger zIndex; +@end + +/// Pigeon equivalent of MinMaxZoomPreference. +@interface FGMPlatformZoomRange : NSObject ++ (instancetype)makeWithMin:(nullable NSNumber *)min max:(nullable NSNumber *)max; +@property(nonatomic, strong, nullable) NSNumber *min; +@property(nonatomic, strong, nullable) NSNumber *max; +@end + +/// The codec used by all APIs. +NSObject *FGMGetMessagesCodec(void); + +/// Interface for non-test interactions with the native SDK. +/// +/// For test-only state queries, see [MapsInspectorApi]. +@protocol FGMMapsApi +/// Returns once the map instance is available. +- (void)waitForMapWithError:(FlutterError *_Nullable *_Nonnull)error; +/// Updates the map's configuration options. +/// +/// Only non-null configuration values will result in updates; options with +/// null values will remain unchanged. +- (void)updateWithMapConfiguration:(FGMPlatformMapConfiguration *)configuration + error:(FlutterError *_Nullable *_Nonnull)error; +/// Updates the set of circles on the map. +- (void)updateCirclesByAdding:(NSArray *)toAdd + changing:(NSArray *)toChange + removing:(NSArray *)idsToRemove + error:(FlutterError *_Nullable *_Nonnull)error; +/// Updates the set of heatmaps on the map. +- (void)updateHeatmapsByAdding:(NSArray *)toAdd + changing:(NSArray *)toChange + removing:(NSArray *)idsToRemove + error:(FlutterError *_Nullable *_Nonnull)error; +/// Updates the set of custer managers for clusters on the map. +- (void)updateClusterManagersByAdding:(NSArray *)toAdd + removing:(NSArray *)idsToRemove + error:(FlutterError *_Nullable *_Nonnull)error; +/// Updates the set of markers on the map. +- (void)updateMarkersByAdding:(NSArray *)toAdd + changing:(NSArray *)toChange + removing:(NSArray *)idsToRemove + error:(FlutterError *_Nullable *_Nonnull)error; +/// Updates the set of polygonss on the map. +- (void)updatePolygonsByAdding:(NSArray *)toAdd + changing:(NSArray *)toChange + removing:(NSArray *)idsToRemove + error:(FlutterError *_Nullable *_Nonnull)error; +/// Updates the set of polylines on the map. +- (void)updatePolylinesByAdding:(NSArray *)toAdd + changing:(NSArray *)toChange + removing:(NSArray *)idsToRemove + error:(FlutterError *_Nullable *_Nonnull)error; +/// Updates the set of tile overlays on the map. +- (void)updateTileOverlaysByAdding:(NSArray *)toAdd + changing:(NSArray *)toChange + removing:(NSArray *)idsToRemove + error:(FlutterError *_Nullable *_Nonnull)error; +/// Gets the screen coordinate for the given map location. +/// +/// @return `nil` only when `error != nil`. +- (nullable FGMPlatformPoint *)screenCoordinatesForLatLng:(FGMPlatformLatLng *)latLng + error:(FlutterError *_Nullable *_Nonnull)error; +/// Gets the map location for the given screen coordinate. +/// +/// @return `nil` only when `error != nil`. +- (nullable FGMPlatformLatLng *)latLngForScreenCoordinate:(FGMPlatformPoint *)screenCoordinate + error:(FlutterError *_Nullable *_Nonnull)error; +/// Gets the map region currently displayed on the map. +/// +/// @return `nil` only when `error != nil`. +- (nullable FGMPlatformLatLngBounds *)visibleMapRegion:(FlutterError *_Nullable *_Nonnull)error; +/// Moves the camera according to [cameraUpdate] immediately, with no +/// animation. +- (void)moveCameraWithUpdate:(FGMPlatformCameraUpdate *)cameraUpdate + error:(FlutterError *_Nullable *_Nonnull)error; +/// Moves the camera according to [cameraUpdate], animating the update. +- (void)animateCameraWithUpdate:(FGMPlatformCameraUpdate *)cameraUpdate + error:(FlutterError *_Nullable *_Nonnull)error; +/// Gets the current map zoom level. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSNumber *)currentZoomLevel:(FlutterError *_Nullable *_Nonnull)error; +/// Show the info window for the marker with the given ID. +- (void)showInfoWindowForMarkerWithIdentifier:(NSString *)markerId + error:(FlutterError *_Nullable *_Nonnull)error; +/// Hide the info window for the marker with the given ID. +- (void)hideInfoWindowForMarkerWithIdentifier:(NSString *)markerId + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns true if the marker with the given ID is currently displaying its +/// info window. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSNumber *) + isShowingInfoWindowForMarkerWithIdentifier:(NSString *)markerId + error:(FlutterError *_Nullable *_Nonnull)error; +/// Sets the style to the given map style string, where an empty string +/// indicates that the style should be cleared. +/// +/// If there was an error setting the style, such as an invalid style string, +/// returns the error message. +- (nullable NSString *)setStyle:(NSString *)style error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the error string from the last attempt to set the map style, if +/// any. +/// +/// This allows checking asynchronously for initial style failures, as there +/// is no way to return failures from map initialization. +- (nullable NSString *)lastStyleError:(FlutterError *_Nullable *_Nonnull)error; +/// Clears the cache of tiles previously requseted from the tile provider. +- (void)clearTileCacheForOverlayWithIdentifier:(NSString *)tileOverlayId + error:(FlutterError *_Nullable *_Nonnull)error; +/// Takes a snapshot of the map and returns its image data. +- (nullable FlutterStandardTypedData *)takeSnapshotWithError: + (FlutterError *_Nullable *_Nonnull)error; +@end + +extern void SetUpFGMMapsApi(id binaryMessenger, + NSObject *_Nullable api); + +extern void SetUpFGMMapsApiWithSuffix(id binaryMessenger, + NSObject *_Nullable api, + NSString *messageChannelSuffix); + +/// Interface for calls from the native SDK to Dart. +@interface FGMMapsCallbackApi : NSObject +- (instancetype)initWithBinaryMessenger:(id)binaryMessenger; +- (instancetype)initWithBinaryMessenger:(id)binaryMessenger + messageChannelSuffix:(nullable NSString *)messageChannelSuffix; +/// Called when the map camera starts moving. +- (void)didStartCameraMoveWithCompletion:(void (^)(FlutterError *_Nullable))completion; +/// Called when the map camera moves. +- (void)didMoveCameraToPosition:(FGMPlatformCameraPosition *)cameraPosition + completion:(void (^)(FlutterError *_Nullable))completion; +/// Called when the map camera stops moving. +- (void)didIdleCameraWithCompletion:(void (^)(FlutterError *_Nullable))completion; +/// Called when the map, not a specifc map object, is tapped. +- (void)didTapAtPosition:(FGMPlatformLatLng *)position + completion:(void (^)(FlutterError *_Nullable))completion; +/// Called when the map, not a specifc map object, is long pressed. +- (void)didLongPressAtPosition:(FGMPlatformLatLng *)position + completion:(void (^)(FlutterError *_Nullable))completion; +/// Called when a marker is tapped. +- (void)didTapMarkerWithIdentifier:(NSString *)markerId + completion:(void (^)(FlutterError *_Nullable))completion; +/// Called when a marker drag starts. +- (void)didStartDragForMarkerWithIdentifier:(NSString *)markerId + atPosition:(FGMPlatformLatLng *)position + completion:(void (^)(FlutterError *_Nullable))completion; +/// Called when a marker drag updates. +- (void)didDragMarkerWithIdentifier:(NSString *)markerId + atPosition:(FGMPlatformLatLng *)position + completion:(void (^)(FlutterError *_Nullable))completion; +/// Called when a marker drag ends. +- (void)didEndDragForMarkerWithIdentifier:(NSString *)markerId + atPosition:(FGMPlatformLatLng *)position + completion:(void (^)(FlutterError *_Nullable))completion; +/// Called when a marker's info window is tapped. +- (void)didTapInfoWindowOfMarkerWithIdentifier:(NSString *)markerId + completion:(void (^)(FlutterError *_Nullable))completion; +/// Called when a circle is tapped. +- (void)didTapCircleWithIdentifier:(NSString *)circleId + completion:(void (^)(FlutterError *_Nullable))completion; +/// Called when a marker cluster is tapped. +- (void)didTapCluster:(FGMPlatformCluster *)cluster + completion:(void (^)(FlutterError *_Nullable))completion; +/// Called when a polygon is tapped. +- (void)didTapPolygonWithIdentifier:(NSString *)polygonId + completion:(void (^)(FlutterError *_Nullable))completion; +/// Called when a polyline is tapped. +- (void)didTapPolylineWithIdentifier:(NSString *)polylineId + completion:(void (^)(FlutterError *_Nullable))completion; +/// Called to get data for a map tile. +- (void)tileWithOverlayIdentifier:(NSString *)tileOverlayId + location:(FGMPlatformPoint *)location + zoom:(NSInteger)zoom + completion:(void (^)(FGMPlatformTile *_Nullable, + FlutterError *_Nullable))completion; +@end + +/// Dummy interface to force generation of the platform view creation params, +/// which are not used in any Pigeon calls, only the platform view creation +/// call made internally by Flutter. +@protocol FGMMapsPlatformViewApi +- (void)createViewType:(nullable FGMPlatformMapViewCreationParams *)type + error:(FlutterError *_Nullable *_Nonnull)error; +@end + +extern void SetUpFGMMapsPlatformViewApi(id binaryMessenger, + NSObject *_Nullable api); + +extern void SetUpFGMMapsPlatformViewApiWithSuffix(id binaryMessenger, + NSObject *_Nullable api, + NSString *messageChannelSuffix); + +/// Inspector API only intended for use in integration tests. +@protocol FGMMapsInspectorApi +/// @return `nil` only when `error != nil`. +- (nullable NSNumber *)areBuildingsEnabledWithError:(FlutterError *_Nullable *_Nonnull)error; +/// @return `nil` only when `error != nil`. +- (nullable NSNumber *)areRotateGesturesEnabledWithError:(FlutterError *_Nullable *_Nonnull)error; +/// @return `nil` only when `error != nil`. +- (nullable NSNumber *)areScrollGesturesEnabledWithError:(FlutterError *_Nullable *_Nonnull)error; +/// @return `nil` only when `error != nil`. +- (nullable NSNumber *)areTiltGesturesEnabledWithError:(FlutterError *_Nullable *_Nonnull)error; +/// @return `nil` only when `error != nil`. +- (nullable NSNumber *)areZoomGesturesEnabledWithError:(FlutterError *_Nullable *_Nonnull)error; +/// @return `nil` only when `error != nil`. +- (nullable NSNumber *)isCompassEnabledWithError:(FlutterError *_Nullable *_Nonnull)error; +/// @return `nil` only when `error != nil`. +- (nullable NSNumber *)isMyLocationButtonEnabledWithError:(FlutterError *_Nullable *_Nonnull)error; +/// @return `nil` only when `error != nil`. +- (nullable NSNumber *)isTrafficEnabledWithError:(FlutterError *_Nullable *_Nonnull)error; +- (nullable FGMPlatformTileLayer *)tileOverlayWithIdentifier:(NSString *)tileOverlayId + error: + (FlutterError *_Nullable *_Nonnull)error; +- (nullable FGMPlatformHeatmap *)heatmapWithIdentifier:(NSString *)heatmapId + error:(FlutterError *_Nullable *_Nonnull)error; +/// @return `nil` only when `error != nil`. +- (nullable FGMPlatformZoomRange *)zoomRange:(FlutterError *_Nullable *_Nonnull)error; +/// @return `nil` only when `error != nil`. +- (nullable NSArray *) + clustersWithIdentifier:(NSString *)clusterManagerId + error:(FlutterError *_Nullable *_Nonnull)error; +@end + +extern void SetUpFGMMapsInspectorApi(id binaryMessenger, + NSObject *_Nullable api); + +extern void SetUpFGMMapsInspectorApiWithSuffix(id binaryMessenger, + NSObject *_Nullable api, + NSString *messageChannelSuffix); + +NS_ASSUME_NONNULL_END diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/messages.g.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/messages.g.m new file mode 100644 index 000000000000..73072d76dc70 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/messages.g.m @@ -0,0 +1,2227 @@ +// 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 (v22.4.2), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +#import "messages.g.h" + +#if TARGET_OS_OSX +#import +#else +#import +#endif + +#if !__has_feature(objc_arc) +#error File requires ARC to be enabled. +#endif + +static NSArray *wrapResult(id result, FlutterError *error) { + if (error) { + return @[ + error.code ?: [NSNull null], error.message ?: [NSNull null], error.details ?: [NSNull null] + ]; + } + return @[ result ?: [NSNull null] ]; +} + +static FlutterError *createConnectionError(NSString *channelName) { + return [FlutterError + errorWithCode:@"channel-error" + message:[NSString stringWithFormat:@"%@/%@/%@", + @"Unable to establish connection on channel: '", + channelName, @"'."] + details:@""]; +} + +static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) { + id result = array[key]; + return (result == [NSNull null]) ? nil : result; +} + +/// Pigeon equivalent of MapType +@implementation FGMPlatformMapTypeBox +- (instancetype)initWithValue:(FGMPlatformMapType)value { + self = [super init]; + if (self) { + _value = value; + } + return self; +} +@end + +@interface FGMPlatformCameraPosition () ++ (FGMPlatformCameraPosition *)fromList:(NSArray *)list; ++ (nullable FGMPlatformCameraPosition *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + +@interface FGMPlatformCameraUpdate () ++ (FGMPlatformCameraUpdate *)fromList:(NSArray *)list; ++ (nullable FGMPlatformCameraUpdate *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + +@interface FGMPlatformCircle () ++ (FGMPlatformCircle *)fromList:(NSArray *)list; ++ (nullable FGMPlatformCircle *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + +@interface FGMPlatformHeatmap () ++ (FGMPlatformHeatmap *)fromList:(NSArray *)list; ++ (nullable FGMPlatformHeatmap *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + +@interface FGMPlatformCluster () ++ (FGMPlatformCluster *)fromList:(NSArray *)list; ++ (nullable FGMPlatformCluster *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + +@interface FGMPlatformClusterManager () ++ (FGMPlatformClusterManager *)fromList:(NSArray *)list; ++ (nullable FGMPlatformClusterManager *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + +@interface FGMPlatformMarker () ++ (FGMPlatformMarker *)fromList:(NSArray *)list; ++ (nullable FGMPlatformMarker *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + +@interface FGMPlatformPolygon () ++ (FGMPlatformPolygon *)fromList:(NSArray *)list; ++ (nullable FGMPlatformPolygon *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + +@interface FGMPlatformPolyline () ++ (FGMPlatformPolyline *)fromList:(NSArray *)list; ++ (nullable FGMPlatformPolyline *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + +@interface FGMPlatformTile () ++ (FGMPlatformTile *)fromList:(NSArray *)list; ++ (nullable FGMPlatformTile *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + +@interface FGMPlatformTileOverlay () ++ (FGMPlatformTileOverlay *)fromList:(NSArray *)list; ++ (nullable FGMPlatformTileOverlay *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + +@interface FGMPlatformEdgeInsets () ++ (FGMPlatformEdgeInsets *)fromList:(NSArray *)list; ++ (nullable FGMPlatformEdgeInsets *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + +@interface FGMPlatformLatLng () ++ (FGMPlatformLatLng *)fromList:(NSArray *)list; ++ (nullable FGMPlatformLatLng *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + +@interface FGMPlatformLatLngBounds () ++ (FGMPlatformLatLngBounds *)fromList:(NSArray *)list; ++ (nullable FGMPlatformLatLngBounds *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + +@interface FGMPlatformCameraTargetBounds () ++ (FGMPlatformCameraTargetBounds *)fromList:(NSArray *)list; ++ (nullable FGMPlatformCameraTargetBounds *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + +@interface FGMPlatformMapViewCreationParams () ++ (FGMPlatformMapViewCreationParams *)fromList:(NSArray *)list; ++ (nullable FGMPlatformMapViewCreationParams *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + +@interface FGMPlatformMapConfiguration () ++ (FGMPlatformMapConfiguration *)fromList:(NSArray *)list; ++ (nullable FGMPlatformMapConfiguration *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + +@interface FGMPlatformPoint () ++ (FGMPlatformPoint *)fromList:(NSArray *)list; ++ (nullable FGMPlatformPoint *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + +@interface FGMPlatformTileLayer () ++ (FGMPlatformTileLayer *)fromList:(NSArray *)list; ++ (nullable FGMPlatformTileLayer *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + +@interface FGMPlatformZoomRange () ++ (FGMPlatformZoomRange *)fromList:(NSArray *)list; ++ (nullable FGMPlatformZoomRange *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + +@implementation FGMPlatformCameraPosition ++ (instancetype)makeWithBearing:(double)bearing + target:(FGMPlatformLatLng *)target + tilt:(double)tilt + zoom:(double)zoom { + FGMPlatformCameraPosition *pigeonResult = [[FGMPlatformCameraPosition alloc] init]; + pigeonResult.bearing = bearing; + pigeonResult.target = target; + pigeonResult.tilt = tilt; + pigeonResult.zoom = zoom; + return pigeonResult; +} ++ (FGMPlatformCameraPosition *)fromList:(NSArray *)list { + FGMPlatformCameraPosition *pigeonResult = [[FGMPlatformCameraPosition alloc] init]; + pigeonResult.bearing = [GetNullableObjectAtIndex(list, 0) doubleValue]; + pigeonResult.target = GetNullableObjectAtIndex(list, 1); + pigeonResult.tilt = [GetNullableObjectAtIndex(list, 2) doubleValue]; + pigeonResult.zoom = [GetNullableObjectAtIndex(list, 3) doubleValue]; + return pigeonResult; +} ++ (nullable FGMPlatformCameraPosition *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformCameraPosition fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + @(self.bearing), + self.target ?: [NSNull null], + @(self.tilt), + @(self.zoom), + ]; +} +@end + +@implementation FGMPlatformCameraUpdate ++ (instancetype)makeWithJson:(id)json { + FGMPlatformCameraUpdate *pigeonResult = [[FGMPlatformCameraUpdate alloc] init]; + pigeonResult.json = json; + return pigeonResult; +} ++ (FGMPlatformCameraUpdate *)fromList:(NSArray *)list { + FGMPlatformCameraUpdate *pigeonResult = [[FGMPlatformCameraUpdate alloc] init]; + pigeonResult.json = GetNullableObjectAtIndex(list, 0); + return pigeonResult; +} ++ (nullable FGMPlatformCameraUpdate *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformCameraUpdate fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + self.json ?: [NSNull null], + ]; +} +@end + +@implementation FGMPlatformCircle ++ (instancetype)makeWithJson:(id)json { + FGMPlatformCircle *pigeonResult = [[FGMPlatformCircle alloc] init]; + pigeonResult.json = json; + return pigeonResult; +} ++ (FGMPlatformCircle *)fromList:(NSArray *)list { + FGMPlatformCircle *pigeonResult = [[FGMPlatformCircle alloc] init]; + pigeonResult.json = GetNullableObjectAtIndex(list, 0); + return pigeonResult; +} ++ (nullable FGMPlatformCircle *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformCircle fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + self.json ?: [NSNull null], + ]; +} +@end + +@implementation FGMPlatformHeatmap ++ (instancetype)makeWithJson:(id)json { + FGMPlatformHeatmap *pigeonResult = [[FGMPlatformHeatmap alloc] init]; + pigeonResult.json = json; + return pigeonResult; +} ++ (FGMPlatformHeatmap *)fromList:(NSArray *)list { + FGMPlatformHeatmap *pigeonResult = [[FGMPlatformHeatmap alloc] init]; + pigeonResult.json = GetNullableObjectAtIndex(list, 0); + return pigeonResult; +} ++ (nullable FGMPlatformHeatmap *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformHeatmap fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + self.json ?: [NSNull null], + ]; +} +@end + +@implementation FGMPlatformCluster ++ (instancetype)makeWithClusterManagerId:(NSString *)clusterManagerId + position:(FGMPlatformLatLng *)position + bounds:(FGMPlatformLatLngBounds *)bounds + markerIds:(NSArray *)markerIds { + FGMPlatformCluster *pigeonResult = [[FGMPlatformCluster alloc] init]; + pigeonResult.clusterManagerId = clusterManagerId; + pigeonResult.position = position; + pigeonResult.bounds = bounds; + pigeonResult.markerIds = markerIds; + return pigeonResult; +} ++ (FGMPlatformCluster *)fromList:(NSArray *)list { + FGMPlatformCluster *pigeonResult = [[FGMPlatformCluster alloc] init]; + pigeonResult.clusterManagerId = GetNullableObjectAtIndex(list, 0); + pigeonResult.position = GetNullableObjectAtIndex(list, 1); + pigeonResult.bounds = GetNullableObjectAtIndex(list, 2); + pigeonResult.markerIds = GetNullableObjectAtIndex(list, 3); + return pigeonResult; +} ++ (nullable FGMPlatformCluster *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformCluster fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + self.clusterManagerId ?: [NSNull null], + self.position ?: [NSNull null], + self.bounds ?: [NSNull null], + self.markerIds ?: [NSNull null], + ]; +} +@end + +@implementation FGMPlatformClusterManager ++ (instancetype)makeWithIdentifier:(NSString *)identifier { + FGMPlatformClusterManager *pigeonResult = [[FGMPlatformClusterManager alloc] init]; + pigeonResult.identifier = identifier; + return pigeonResult; +} ++ (FGMPlatformClusterManager *)fromList:(NSArray *)list { + FGMPlatformClusterManager *pigeonResult = [[FGMPlatformClusterManager alloc] init]; + pigeonResult.identifier = GetNullableObjectAtIndex(list, 0); + return pigeonResult; +} ++ (nullable FGMPlatformClusterManager *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformClusterManager fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + self.identifier ?: [NSNull null], + ]; +} +@end + +@implementation FGMPlatformMarker ++ (instancetype)makeWithJson:(id)json { + FGMPlatformMarker *pigeonResult = [[FGMPlatformMarker alloc] init]; + pigeonResult.json = json; + return pigeonResult; +} ++ (FGMPlatformMarker *)fromList:(NSArray *)list { + FGMPlatformMarker *pigeonResult = [[FGMPlatformMarker alloc] init]; + pigeonResult.json = GetNullableObjectAtIndex(list, 0); + return pigeonResult; +} ++ (nullable FGMPlatformMarker *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformMarker fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + self.json ?: [NSNull null], + ]; +} +@end + +@implementation FGMPlatformPolygon ++ (instancetype)makeWithJson:(id)json { + FGMPlatformPolygon *pigeonResult = [[FGMPlatformPolygon alloc] init]; + pigeonResult.json = json; + return pigeonResult; +} ++ (FGMPlatformPolygon *)fromList:(NSArray *)list { + FGMPlatformPolygon *pigeonResult = [[FGMPlatformPolygon alloc] init]; + pigeonResult.json = GetNullableObjectAtIndex(list, 0); + return pigeonResult; +} ++ (nullable FGMPlatformPolygon *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformPolygon fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + self.json ?: [NSNull null], + ]; +} +@end + +@implementation FGMPlatformPolyline ++ (instancetype)makeWithJson:(id)json { + FGMPlatformPolyline *pigeonResult = [[FGMPlatformPolyline alloc] init]; + pigeonResult.json = json; + return pigeonResult; +} ++ (FGMPlatformPolyline *)fromList:(NSArray *)list { + FGMPlatformPolyline *pigeonResult = [[FGMPlatformPolyline alloc] init]; + pigeonResult.json = GetNullableObjectAtIndex(list, 0); + return pigeonResult; +} ++ (nullable FGMPlatformPolyline *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformPolyline fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + self.json ?: [NSNull null], + ]; +} +@end + +@implementation FGMPlatformTile ++ (instancetype)makeWithWidth:(NSInteger)width + height:(NSInteger)height + data:(nullable FlutterStandardTypedData *)data { + FGMPlatformTile *pigeonResult = [[FGMPlatformTile alloc] init]; + pigeonResult.width = width; + pigeonResult.height = height; + pigeonResult.data = data; + return pigeonResult; +} ++ (FGMPlatformTile *)fromList:(NSArray *)list { + FGMPlatformTile *pigeonResult = [[FGMPlatformTile alloc] init]; + pigeonResult.width = [GetNullableObjectAtIndex(list, 0) integerValue]; + pigeonResult.height = [GetNullableObjectAtIndex(list, 1) integerValue]; + pigeonResult.data = GetNullableObjectAtIndex(list, 2); + return pigeonResult; +} ++ (nullable FGMPlatformTile *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformTile fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + @(self.width), + @(self.height), + self.data ?: [NSNull null], + ]; +} +@end + +@implementation FGMPlatformTileOverlay ++ (instancetype)makeWithJson:(id)json { + FGMPlatformTileOverlay *pigeonResult = [[FGMPlatformTileOverlay alloc] init]; + pigeonResult.json = json; + return pigeonResult; +} ++ (FGMPlatformTileOverlay *)fromList:(NSArray *)list { + FGMPlatformTileOverlay *pigeonResult = [[FGMPlatformTileOverlay alloc] init]; + pigeonResult.json = GetNullableObjectAtIndex(list, 0); + return pigeonResult; +} ++ (nullable FGMPlatformTileOverlay *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformTileOverlay fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + self.json ?: [NSNull null], + ]; +} +@end + +@implementation FGMPlatformEdgeInsets ++ (instancetype)makeWithTop:(double)top + bottom:(double)bottom + left:(double)left + right:(double)right { + FGMPlatformEdgeInsets *pigeonResult = [[FGMPlatformEdgeInsets alloc] init]; + pigeonResult.top = top; + pigeonResult.bottom = bottom; + pigeonResult.left = left; + pigeonResult.right = right; + return pigeonResult; +} ++ (FGMPlatformEdgeInsets *)fromList:(NSArray *)list { + FGMPlatformEdgeInsets *pigeonResult = [[FGMPlatformEdgeInsets alloc] init]; + pigeonResult.top = [GetNullableObjectAtIndex(list, 0) doubleValue]; + pigeonResult.bottom = [GetNullableObjectAtIndex(list, 1) doubleValue]; + pigeonResult.left = [GetNullableObjectAtIndex(list, 2) doubleValue]; + pigeonResult.right = [GetNullableObjectAtIndex(list, 3) doubleValue]; + return pigeonResult; +} ++ (nullable FGMPlatformEdgeInsets *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformEdgeInsets fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + @(self.top), + @(self.bottom), + @(self.left), + @(self.right), + ]; +} +@end + +@implementation FGMPlatformLatLng ++ (instancetype)makeWithLatitude:(double)latitude longitude:(double)longitude { + FGMPlatformLatLng *pigeonResult = [[FGMPlatformLatLng alloc] init]; + pigeonResult.latitude = latitude; + pigeonResult.longitude = longitude; + return pigeonResult; +} ++ (FGMPlatformLatLng *)fromList:(NSArray *)list { + FGMPlatformLatLng *pigeonResult = [[FGMPlatformLatLng alloc] init]; + pigeonResult.latitude = [GetNullableObjectAtIndex(list, 0) doubleValue]; + pigeonResult.longitude = [GetNullableObjectAtIndex(list, 1) doubleValue]; + return pigeonResult; +} ++ (nullable FGMPlatformLatLng *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformLatLng fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + @(self.latitude), + @(self.longitude), + ]; +} +@end + +@implementation FGMPlatformLatLngBounds ++ (instancetype)makeWithNortheast:(FGMPlatformLatLng *)northeast + southwest:(FGMPlatformLatLng *)southwest { + FGMPlatformLatLngBounds *pigeonResult = [[FGMPlatformLatLngBounds alloc] init]; + pigeonResult.northeast = northeast; + pigeonResult.southwest = southwest; + return pigeonResult; +} ++ (FGMPlatformLatLngBounds *)fromList:(NSArray *)list { + FGMPlatformLatLngBounds *pigeonResult = [[FGMPlatformLatLngBounds alloc] init]; + pigeonResult.northeast = GetNullableObjectAtIndex(list, 0); + pigeonResult.southwest = GetNullableObjectAtIndex(list, 1); + return pigeonResult; +} ++ (nullable FGMPlatformLatLngBounds *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformLatLngBounds fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + self.northeast ?: [NSNull null], + self.southwest ?: [NSNull null], + ]; +} +@end + +@implementation FGMPlatformCameraTargetBounds ++ (instancetype)makeWithBounds:(nullable FGMPlatformLatLngBounds *)bounds { + FGMPlatformCameraTargetBounds *pigeonResult = [[FGMPlatformCameraTargetBounds alloc] init]; + pigeonResult.bounds = bounds; + return pigeonResult; +} ++ (FGMPlatformCameraTargetBounds *)fromList:(NSArray *)list { + FGMPlatformCameraTargetBounds *pigeonResult = [[FGMPlatformCameraTargetBounds alloc] init]; + pigeonResult.bounds = GetNullableObjectAtIndex(list, 0); + return pigeonResult; +} ++ (nullable FGMPlatformCameraTargetBounds *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformCameraTargetBounds fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + self.bounds ?: [NSNull null], + ]; +} +@end + +@implementation FGMPlatformMapViewCreationParams ++ (instancetype) + makeWithInitialCameraPosition:(FGMPlatformCameraPosition *)initialCameraPosition + mapConfiguration:(FGMPlatformMapConfiguration *)mapConfiguration + initialCircles:(NSArray *)initialCircles + initialMarkers:(NSArray *)initialMarkers + initialPolygons:(NSArray *)initialPolygons + initialPolylines:(NSArray *)initialPolylines + initialHeatmaps:(NSArray *)initialHeatmaps + initialTileOverlays:(NSArray *)initialTileOverlays + initialClusterManagers:(NSArray *)initialClusterManagers { + FGMPlatformMapViewCreationParams *pigeonResult = [[FGMPlatformMapViewCreationParams alloc] init]; + pigeonResult.initialCameraPosition = initialCameraPosition; + pigeonResult.mapConfiguration = mapConfiguration; + pigeonResult.initialCircles = initialCircles; + pigeonResult.initialMarkers = initialMarkers; + pigeonResult.initialPolygons = initialPolygons; + pigeonResult.initialPolylines = initialPolylines; + pigeonResult.initialHeatmaps = initialHeatmaps; + pigeonResult.initialTileOverlays = initialTileOverlays; + pigeonResult.initialClusterManagers = initialClusterManagers; + return pigeonResult; +} ++ (FGMPlatformMapViewCreationParams *)fromList:(NSArray *)list { + FGMPlatformMapViewCreationParams *pigeonResult = [[FGMPlatformMapViewCreationParams alloc] init]; + pigeonResult.initialCameraPosition = GetNullableObjectAtIndex(list, 0); + pigeonResult.mapConfiguration = GetNullableObjectAtIndex(list, 1); + pigeonResult.initialCircles = GetNullableObjectAtIndex(list, 2); + pigeonResult.initialMarkers = GetNullableObjectAtIndex(list, 3); + pigeonResult.initialPolygons = GetNullableObjectAtIndex(list, 4); + pigeonResult.initialPolylines = GetNullableObjectAtIndex(list, 5); + pigeonResult.initialHeatmaps = GetNullableObjectAtIndex(list, 6); + pigeonResult.initialTileOverlays = GetNullableObjectAtIndex(list, 7); + pigeonResult.initialClusterManagers = GetNullableObjectAtIndex(list, 8); + return pigeonResult; +} ++ (nullable FGMPlatformMapViewCreationParams *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformMapViewCreationParams fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + self.initialCameraPosition ?: [NSNull null], + self.mapConfiguration ?: [NSNull null], + self.initialCircles ?: [NSNull null], + self.initialMarkers ?: [NSNull null], + self.initialPolygons ?: [NSNull null], + self.initialPolylines ?: [NSNull null], + self.initialHeatmaps ?: [NSNull null], + self.initialTileOverlays ?: [NSNull null], + self.initialClusterManagers ?: [NSNull null], + ]; +} +@end + +@implementation FGMPlatformMapConfiguration ++ (instancetype)makeWithCompassEnabled:(nullable NSNumber *)compassEnabled + cameraTargetBounds:(nullable FGMPlatformCameraTargetBounds *)cameraTargetBounds + mapType:(nullable FGMPlatformMapTypeBox *)mapType + minMaxZoomPreference:(nullable FGMPlatformZoomRange *)minMaxZoomPreference + rotateGesturesEnabled:(nullable NSNumber *)rotateGesturesEnabled + scrollGesturesEnabled:(nullable NSNumber *)scrollGesturesEnabled + tiltGesturesEnabled:(nullable NSNumber *)tiltGesturesEnabled + trackCameraPosition:(nullable NSNumber *)trackCameraPosition + zoomGesturesEnabled:(nullable NSNumber *)zoomGesturesEnabled + myLocationEnabled:(nullable NSNumber *)myLocationEnabled + myLocationButtonEnabled:(nullable NSNumber *)myLocationButtonEnabled + padding:(nullable FGMPlatformEdgeInsets *)padding + indoorViewEnabled:(nullable NSNumber *)indoorViewEnabled + trafficEnabled:(nullable NSNumber *)trafficEnabled + buildingsEnabled:(nullable NSNumber *)buildingsEnabled + cloudMapId:(nullable NSString *)cloudMapId + style:(nullable NSString *)style { + FGMPlatformMapConfiguration *pigeonResult = [[FGMPlatformMapConfiguration alloc] init]; + pigeonResult.compassEnabled = compassEnabled; + pigeonResult.cameraTargetBounds = cameraTargetBounds; + pigeonResult.mapType = mapType; + pigeonResult.minMaxZoomPreference = minMaxZoomPreference; + pigeonResult.rotateGesturesEnabled = rotateGesturesEnabled; + pigeonResult.scrollGesturesEnabled = scrollGesturesEnabled; + pigeonResult.tiltGesturesEnabled = tiltGesturesEnabled; + pigeonResult.trackCameraPosition = trackCameraPosition; + pigeonResult.zoomGesturesEnabled = zoomGesturesEnabled; + pigeonResult.myLocationEnabled = myLocationEnabled; + pigeonResult.myLocationButtonEnabled = myLocationButtonEnabled; + pigeonResult.padding = padding; + pigeonResult.indoorViewEnabled = indoorViewEnabled; + pigeonResult.trafficEnabled = trafficEnabled; + pigeonResult.buildingsEnabled = buildingsEnabled; + pigeonResult.cloudMapId = cloudMapId; + pigeonResult.style = style; + return pigeonResult; +} ++ (FGMPlatformMapConfiguration *)fromList:(NSArray *)list { + FGMPlatformMapConfiguration *pigeonResult = [[FGMPlatformMapConfiguration alloc] init]; + pigeonResult.compassEnabled = GetNullableObjectAtIndex(list, 0); + pigeonResult.cameraTargetBounds = GetNullableObjectAtIndex(list, 1); + pigeonResult.mapType = GetNullableObjectAtIndex(list, 2); + pigeonResult.minMaxZoomPreference = GetNullableObjectAtIndex(list, 3); + pigeonResult.rotateGesturesEnabled = GetNullableObjectAtIndex(list, 4); + pigeonResult.scrollGesturesEnabled = GetNullableObjectAtIndex(list, 5); + pigeonResult.tiltGesturesEnabled = GetNullableObjectAtIndex(list, 6); + pigeonResult.trackCameraPosition = GetNullableObjectAtIndex(list, 7); + pigeonResult.zoomGesturesEnabled = GetNullableObjectAtIndex(list, 8); + pigeonResult.myLocationEnabled = GetNullableObjectAtIndex(list, 9); + pigeonResult.myLocationButtonEnabled = GetNullableObjectAtIndex(list, 10); + pigeonResult.padding = GetNullableObjectAtIndex(list, 11); + pigeonResult.indoorViewEnabled = GetNullableObjectAtIndex(list, 12); + pigeonResult.trafficEnabled = GetNullableObjectAtIndex(list, 13); + pigeonResult.buildingsEnabled = GetNullableObjectAtIndex(list, 14); + pigeonResult.cloudMapId = GetNullableObjectAtIndex(list, 15); + pigeonResult.style = GetNullableObjectAtIndex(list, 16); + return pigeonResult; +} ++ (nullable FGMPlatformMapConfiguration *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformMapConfiguration fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + self.compassEnabled ?: [NSNull null], + self.cameraTargetBounds ?: [NSNull null], + self.mapType ?: [NSNull null], + self.minMaxZoomPreference ?: [NSNull null], + self.rotateGesturesEnabled ?: [NSNull null], + self.scrollGesturesEnabled ?: [NSNull null], + self.tiltGesturesEnabled ?: [NSNull null], + self.trackCameraPosition ?: [NSNull null], + self.zoomGesturesEnabled ?: [NSNull null], + self.myLocationEnabled ?: [NSNull null], + self.myLocationButtonEnabled ?: [NSNull null], + self.padding ?: [NSNull null], + self.indoorViewEnabled ?: [NSNull null], + self.trafficEnabled ?: [NSNull null], + self.buildingsEnabled ?: [NSNull null], + self.cloudMapId ?: [NSNull null], + self.style ?: [NSNull null], + ]; +} +@end + +@implementation FGMPlatformPoint ++ (instancetype)makeWithX:(double)x y:(double)y { + FGMPlatformPoint *pigeonResult = [[FGMPlatformPoint alloc] init]; + pigeonResult.x = x; + pigeonResult.y = y; + return pigeonResult; +} ++ (FGMPlatformPoint *)fromList:(NSArray *)list { + FGMPlatformPoint *pigeonResult = [[FGMPlatformPoint alloc] init]; + pigeonResult.x = [GetNullableObjectAtIndex(list, 0) doubleValue]; + pigeonResult.y = [GetNullableObjectAtIndex(list, 1) doubleValue]; + return pigeonResult; +} ++ (nullable FGMPlatformPoint *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformPoint fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + @(self.x), + @(self.y), + ]; +} +@end + +@implementation FGMPlatformTileLayer ++ (instancetype)makeWithVisible:(BOOL)visible + fadeIn:(BOOL)fadeIn + opacity:(double)opacity + zIndex:(NSInteger)zIndex { + FGMPlatformTileLayer *pigeonResult = [[FGMPlatformTileLayer alloc] init]; + pigeonResult.visible = visible; + pigeonResult.fadeIn = fadeIn; + pigeonResult.opacity = opacity; + pigeonResult.zIndex = zIndex; + return pigeonResult; +} ++ (FGMPlatformTileLayer *)fromList:(NSArray *)list { + FGMPlatformTileLayer *pigeonResult = [[FGMPlatformTileLayer alloc] init]; + pigeonResult.visible = [GetNullableObjectAtIndex(list, 0) boolValue]; + pigeonResult.fadeIn = [GetNullableObjectAtIndex(list, 1) boolValue]; + pigeonResult.opacity = [GetNullableObjectAtIndex(list, 2) doubleValue]; + pigeonResult.zIndex = [GetNullableObjectAtIndex(list, 3) integerValue]; + return pigeonResult; +} ++ (nullable FGMPlatformTileLayer *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformTileLayer fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + @(self.visible), + @(self.fadeIn), + @(self.opacity), + @(self.zIndex), + ]; +} +@end + +@implementation FGMPlatformZoomRange ++ (instancetype)makeWithMin:(nullable NSNumber *)min max:(nullable NSNumber *)max { + FGMPlatformZoomRange *pigeonResult = [[FGMPlatformZoomRange alloc] init]; + pigeonResult.min = min; + pigeonResult.max = max; + return pigeonResult; +} ++ (FGMPlatformZoomRange *)fromList:(NSArray *)list { + FGMPlatformZoomRange *pigeonResult = [[FGMPlatformZoomRange alloc] init]; + pigeonResult.min = GetNullableObjectAtIndex(list, 0); + pigeonResult.max = GetNullableObjectAtIndex(list, 1); + return pigeonResult; +} ++ (nullable FGMPlatformZoomRange *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformZoomRange fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + self.min ?: [NSNull null], + self.max ?: [NSNull null], + ]; +} +@end + +@interface FGMMessagesPigeonCodecReader : FlutterStandardReader +@end +@implementation FGMMessagesPigeonCodecReader +- (nullable id)readValueOfType:(UInt8)type { + switch (type) { + case 129: { + NSNumber *enumAsNumber = [self readValue]; + return enumAsNumber == nil + ? nil + : [[FGMPlatformMapTypeBox alloc] initWithValue:[enumAsNumber integerValue]]; + } + case 130: + return [FGMPlatformCameraPosition fromList:[self readValue]]; + case 131: + return [FGMPlatformCameraUpdate fromList:[self readValue]]; + case 132: + return [FGMPlatformCircle fromList:[self readValue]]; + case 133: + return [FGMPlatformHeatmap fromList:[self readValue]]; + case 134: + return [FGMPlatformCluster fromList:[self readValue]]; + case 135: + return [FGMPlatformClusterManager fromList:[self readValue]]; + case 136: + return [FGMPlatformMarker fromList:[self readValue]]; + case 137: + return [FGMPlatformPolygon fromList:[self readValue]]; + case 138: + return [FGMPlatformPolyline fromList:[self readValue]]; + case 139: + return [FGMPlatformTile fromList:[self readValue]]; + case 140: + return [FGMPlatformTileOverlay fromList:[self readValue]]; + case 141: + return [FGMPlatformEdgeInsets fromList:[self readValue]]; + case 142: + return [FGMPlatformLatLng fromList:[self readValue]]; + case 143: + return [FGMPlatformLatLngBounds fromList:[self readValue]]; + case 144: + return [FGMPlatformCameraTargetBounds fromList:[self readValue]]; + case 145: + return [FGMPlatformMapViewCreationParams fromList:[self readValue]]; + case 146: + return [FGMPlatformMapConfiguration fromList:[self readValue]]; + case 147: + return [FGMPlatformPoint fromList:[self readValue]]; + case 148: + return [FGMPlatformTileLayer fromList:[self readValue]]; + case 149: + return [FGMPlatformZoomRange fromList:[self readValue]]; + default: + return [super readValueOfType:type]; + } +} +@end + +@interface FGMMessagesPigeonCodecWriter : FlutterStandardWriter +@end +@implementation FGMMessagesPigeonCodecWriter +- (void)writeValue:(id)value { + if ([value isKindOfClass:[FGMPlatformMapTypeBox class]]) { + FGMPlatformMapTypeBox *box = (FGMPlatformMapTypeBox *)value; + [self writeByte:129]; + [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; + } else if ([value isKindOfClass:[FGMPlatformCameraPosition class]]) { + [self writeByte:130]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FGMPlatformCameraUpdate class]]) { + [self writeByte:131]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FGMPlatformCircle class]]) { + [self writeByte:132]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FGMPlatformHeatmap class]]) { + [self writeByte:133]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FGMPlatformCluster class]]) { + [self writeByte:134]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FGMPlatformClusterManager class]]) { + [self writeByte:135]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FGMPlatformMarker class]]) { + [self writeByte:136]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FGMPlatformPolygon class]]) { + [self writeByte:137]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FGMPlatformPolyline class]]) { + [self writeByte:138]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FGMPlatformTile class]]) { + [self writeByte:139]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FGMPlatformTileOverlay class]]) { + [self writeByte:140]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FGMPlatformEdgeInsets class]]) { + [self writeByte:141]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FGMPlatformLatLng class]]) { + [self writeByte:142]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FGMPlatformLatLngBounds class]]) { + [self writeByte:143]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FGMPlatformCameraTargetBounds class]]) { + [self writeByte:144]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FGMPlatformMapViewCreationParams class]]) { + [self writeByte:145]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FGMPlatformMapConfiguration class]]) { + [self writeByte:146]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FGMPlatformPoint class]]) { + [self writeByte:147]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FGMPlatformTileLayer class]]) { + [self writeByte:148]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FGMPlatformZoomRange class]]) { + [self writeByte:149]; + [self writeValue:[value toList]]; + } else { + [super writeValue:value]; + } +} +@end + +@interface FGMMessagesPigeonCodecReaderWriter : FlutterStandardReaderWriter +@end +@implementation FGMMessagesPigeonCodecReaderWriter +- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data { + return [[FGMMessagesPigeonCodecWriter alloc] initWithData:data]; +} +- (FlutterStandardReader *)readerWithData:(NSData *)data { + return [[FGMMessagesPigeonCodecReader alloc] initWithData:data]; +} +@end + +NSObject *FGMGetMessagesCodec(void) { + static FlutterStandardMessageCodec *sSharedObject = nil; + static dispatch_once_t sPred = 0; + dispatch_once(&sPred, ^{ + FGMMessagesPigeonCodecReaderWriter *readerWriter = + [[FGMMessagesPigeonCodecReaderWriter alloc] init]; + sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter]; + }); + return sSharedObject; +} +void SetUpFGMMapsApi(id binaryMessenger, NSObject *api) { + SetUpFGMMapsApiWithSuffix(binaryMessenger, api, @""); +} + +void SetUpFGMMapsApiWithSuffix(id binaryMessenger, + NSObject *api, NSString *messageChannelSuffix) { + messageChannelSuffix = messageChannelSuffix.length > 0 + ? [NSString stringWithFormat:@".%@", messageChannelSuffix] + : @""; + /// Returns once the map instance is available. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.waitForMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(waitForMapWithError:)], + @"FGMMapsApi api (%@) doesn't respond to @selector(waitForMapWithError:)", api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + FlutterError *error; + [api waitForMapWithError:&error]; + callback(wrapResult(nil, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Updates the map's configuration options. + /// + /// Only non-null configuration values will result in updates; options with + /// null values will remain unchanged. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsApi.updateMapConfiguration", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert( + [api respondsToSelector:@selector(updateWithMapConfiguration:error:)], + @"FGMMapsApi api (%@) doesn't respond to @selector(updateWithMapConfiguration:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FGMPlatformMapConfiguration *arg_configuration = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + [api updateWithMapConfiguration:arg_configuration error:&error]; + callback(wrapResult(nil, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Updates the set of circles on the map. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.updateCircles", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(updateCirclesByAdding:changing:removing:error:)], + @"FGMMapsApi api (%@) doesn't respond to " + @"@selector(updateCirclesByAdding:changing:removing:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_toAdd = GetNullableObjectAtIndex(args, 0); + NSArray *arg_toChange = GetNullableObjectAtIndex(args, 1); + NSArray *arg_idsToRemove = GetNullableObjectAtIndex(args, 2); + FlutterError *error; + [api updateCirclesByAdding:arg_toAdd + changing:arg_toChange + removing:arg_idsToRemove + error:&error]; + callback(wrapResult(nil, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Updates the set of heatmaps on the map. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsApi.updateHeatmaps", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(updateHeatmapsByAdding:changing:removing:error:)], + @"FGMMapsApi api (%@) doesn't respond to " + @"@selector(updateHeatmapsByAdding:changing:removing:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_toAdd = GetNullableObjectAtIndex(args, 0); + NSArray *arg_toChange = GetNullableObjectAtIndex(args, 1); + NSArray *arg_idsToRemove = GetNullableObjectAtIndex(args, 2); + FlutterError *error; + [api updateHeatmapsByAdding:arg_toAdd + changing:arg_toChange + removing:arg_idsToRemove + error:&error]; + callback(wrapResult(nil, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Updates the set of custer managers for clusters on the map. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsApi.updateClusterManagers", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(updateClusterManagersByAdding:removing:error:)], + @"FGMMapsApi api (%@) doesn't respond to " + @"@selector(updateClusterManagersByAdding:removing:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_toAdd = GetNullableObjectAtIndex(args, 0); + NSArray *arg_idsToRemove = GetNullableObjectAtIndex(args, 1); + FlutterError *error; + [api updateClusterManagersByAdding:arg_toAdd removing:arg_idsToRemove error:&error]; + callback(wrapResult(nil, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Updates the set of markers on the map. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.updateMarkers", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(updateMarkersByAdding:changing:removing:error:)], + @"FGMMapsApi api (%@) doesn't respond to " + @"@selector(updateMarkersByAdding:changing:removing:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_toAdd = GetNullableObjectAtIndex(args, 0); + NSArray *arg_toChange = GetNullableObjectAtIndex(args, 1); + NSArray *arg_idsToRemove = GetNullableObjectAtIndex(args, 2); + FlutterError *error; + [api updateMarkersByAdding:arg_toAdd + changing:arg_toChange + removing:arg_idsToRemove + error:&error]; + callback(wrapResult(nil, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Updates the set of polygonss on the map. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsApi.updatePolygons", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(updatePolygonsByAdding:changing:removing:error:)], + @"FGMMapsApi api (%@) doesn't respond to " + @"@selector(updatePolygonsByAdding:changing:removing:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_toAdd = GetNullableObjectAtIndex(args, 0); + NSArray *arg_toChange = GetNullableObjectAtIndex(args, 1); + NSArray *arg_idsToRemove = GetNullableObjectAtIndex(args, 2); + FlutterError *error; + [api updatePolygonsByAdding:arg_toAdd + changing:arg_toChange + removing:arg_idsToRemove + error:&error]; + callback(wrapResult(nil, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Updates the set of polylines on the map. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsApi.updatePolylines", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(updatePolylinesByAdding: + changing:removing:error:)], + @"FGMMapsApi api (%@) doesn't respond to " + @"@selector(updatePolylinesByAdding:changing:removing:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_toAdd = GetNullableObjectAtIndex(args, 0); + NSArray *arg_toChange = GetNullableObjectAtIndex(args, 1); + NSArray *arg_idsToRemove = GetNullableObjectAtIndex(args, 2); + FlutterError *error; + [api updatePolylinesByAdding:arg_toAdd + changing:arg_toChange + removing:arg_idsToRemove + error:&error]; + callback(wrapResult(nil, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Updates the set of tile overlays on the map. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsApi.updateTileOverlays", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(updateTileOverlaysByAdding: + changing:removing:error:)], + @"FGMMapsApi api (%@) doesn't respond to " + @"@selector(updateTileOverlaysByAdding:changing:removing:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_toAdd = GetNullableObjectAtIndex(args, 0); + NSArray *arg_toChange = GetNullableObjectAtIndex(args, 1); + NSArray *arg_idsToRemove = GetNullableObjectAtIndex(args, 2); + FlutterError *error; + [api updateTileOverlaysByAdding:arg_toAdd + changing:arg_toChange + removing:arg_idsToRemove + error:&error]; + callback(wrapResult(nil, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Gets the screen coordinate for the given map location. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsApi.getScreenCoordinate", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert( + [api respondsToSelector:@selector(screenCoordinatesForLatLng:error:)], + @"FGMMapsApi api (%@) doesn't respond to @selector(screenCoordinatesForLatLng:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FGMPlatformLatLng *arg_latLng = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + FGMPlatformPoint *output = [api screenCoordinatesForLatLng:arg_latLng error:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Gets the map location for the given screen coordinate. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.getLatLng", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert( + [api respondsToSelector:@selector(latLngForScreenCoordinate:error:)], + @"FGMMapsApi api (%@) doesn't respond to @selector(latLngForScreenCoordinate:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FGMPlatformPoint *arg_screenCoordinate = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + FGMPlatformLatLng *output = [api latLngForScreenCoordinate:arg_screenCoordinate + error:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Gets the map region currently displayed on the map. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsApi.getVisibleRegion", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(visibleMapRegion:)], + @"FGMMapsApi api (%@) doesn't respond to @selector(visibleMapRegion:)", api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + FlutterError *error; + FGMPlatformLatLngBounds *output = [api visibleMapRegion:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Moves the camera according to [cameraUpdate] immediately, with no + /// animation. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.moveCamera", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(moveCameraWithUpdate:error:)], + @"FGMMapsApi api (%@) doesn't respond to @selector(moveCameraWithUpdate:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FGMPlatformCameraUpdate *arg_cameraUpdate = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + [api moveCameraWithUpdate:arg_cameraUpdate error:&error]; + callback(wrapResult(nil, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Moves the camera according to [cameraUpdate], animating the update. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.animateCamera", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(animateCameraWithUpdate:error:)], + @"FGMMapsApi api (%@) doesn't respond to @selector(animateCameraWithUpdate:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FGMPlatformCameraUpdate *arg_cameraUpdate = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + [api animateCameraWithUpdate:arg_cameraUpdate error:&error]; + callback(wrapResult(nil, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Gets the current map zoom level. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.getZoomLevel", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(currentZoomLevel:)], + @"FGMMapsApi api (%@) doesn't respond to @selector(currentZoomLevel:)", api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + FlutterError *error; + NSNumber *output = [api currentZoomLevel:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Show the info window for the marker with the given ID. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsApi.showInfoWindow", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(showInfoWindowForMarkerWithIdentifier:error:)], + @"FGMMapsApi api (%@) doesn't respond to " + @"@selector(showInfoWindowForMarkerWithIdentifier:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_markerId = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + [api showInfoWindowForMarkerWithIdentifier:arg_markerId error:&error]; + callback(wrapResult(nil, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Hide the info window for the marker with the given ID. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsApi.hideInfoWindow", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(hideInfoWindowForMarkerWithIdentifier:error:)], + @"FGMMapsApi api (%@) doesn't respond to " + @"@selector(hideInfoWindowForMarkerWithIdentifier:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_markerId = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + [api hideInfoWindowForMarkerWithIdentifier:arg_markerId error:&error]; + callback(wrapResult(nil, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns true if the marker with the given ID is currently displaying its + /// info window. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsApi.isInfoWindowShown", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(isShowingInfoWindowForMarkerWithIdentifier: + error:)], + @"FGMMapsApi api (%@) doesn't respond to " + @"@selector(isShowingInfoWindowForMarkerWithIdentifier:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_markerId = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSNumber *output = [api isShowingInfoWindowForMarkerWithIdentifier:arg_markerId + error:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Sets the style to the given map style string, where an empty string + /// indicates that the style should be cleared. + /// + /// If there was an error setting the style, such as an invalid style string, + /// returns the error message. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.setStyle", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(setStyle:error:)], + @"FGMMapsApi api (%@) doesn't respond to @selector(setStyle:error:)", api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_style = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSString *output = [api setStyle:arg_style error:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the error string from the last attempt to set the map style, if + /// any. + /// + /// This allows checking asynchronously for initial style failures, as there + /// is no way to return failures from map initialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsApi.getLastStyleError", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(lastStyleError:)], + @"FGMMapsApi api (%@) doesn't respond to @selector(lastStyleError:)", api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + FlutterError *error; + NSString *output = [api lastStyleError:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Clears the cache of tiles previously requseted from the tile provider. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsApi.clearTileCache", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(clearTileCacheForOverlayWithIdentifier:error:)], + @"FGMMapsApi api (%@) doesn't respond to " + @"@selector(clearTileCacheForOverlayWithIdentifier:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_tileOverlayId = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + [api clearTileCacheForOverlayWithIdentifier:arg_tileOverlayId error:&error]; + callback(wrapResult(nil, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Takes a snapshot of the map and returns its image data. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.takeSnapshot", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(takeSnapshotWithError:)], + @"FGMMapsApi api (%@) doesn't respond to @selector(takeSnapshotWithError:)", api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + FlutterError *error; + FlutterStandardTypedData *output = [api takeSnapshotWithError:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } +} +@interface FGMMapsCallbackApi () +@property(nonatomic, strong) NSObject *binaryMessenger; +@property(nonatomic, strong) NSString *messageChannelSuffix; +@end + +@implementation FGMMapsCallbackApi + +- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger { + return [self initWithBinaryMessenger:binaryMessenger messageChannelSuffix:@""]; +} +- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger + messageChannelSuffix:(nullable NSString *)messageChannelSuffix { + self = [self init]; + if (self) { + _binaryMessenger = binaryMessenger; + _messageChannelSuffix = [messageChannelSuffix length] == 0 + ? @"" + : [NSString stringWithFormat:@".%@", messageChannelSuffix]; + } + return self; +} +- (void)didStartCameraMoveWithCompletion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onCameraMoveStarted", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FGMGetMessagesCodec()]; + [channel sendMessage:nil + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; +} +- (void)didMoveCameraToPosition:(FGMPlatformCameraPosition *)arg_cameraPosition + completion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onCameraMove", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FGMGetMessagesCodec()]; + [channel sendMessage:@[ arg_cameraPosition ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; +} +- (void)didIdleCameraWithCompletion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onCameraIdle", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FGMGetMessagesCodec()]; + [channel sendMessage:nil + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; +} +- (void)didTapAtPosition:(FGMPlatformLatLng *)arg_position + completion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat:@"%@%@", @"dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onTap", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FGMGetMessagesCodec()]; + [channel sendMessage:@[ arg_position ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; +} +- (void)didLongPressAtPosition:(FGMPlatformLatLng *)arg_position + completion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onLongPress", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FGMGetMessagesCodec()]; + [channel sendMessage:@[ arg_position ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; +} +- (void)didTapMarkerWithIdentifier:(NSString *)arg_markerId + completion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onMarkerTap", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FGMGetMessagesCodec()]; + [channel sendMessage:@[ arg_markerId ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; +} +- (void)didStartDragForMarkerWithIdentifier:(NSString *)arg_markerId + atPosition:(FGMPlatformLatLng *)arg_position + completion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", @"dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onMarkerDragStart", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FGMGetMessagesCodec()]; + [channel sendMessage:@[ arg_markerId ?: [NSNull null], arg_position ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; +} +- (void)didDragMarkerWithIdentifier:(NSString *)arg_markerId + atPosition:(FGMPlatformLatLng *)arg_position + completion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onMarkerDrag", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FGMGetMessagesCodec()]; + [channel sendMessage:@[ arg_markerId ?: [NSNull null], arg_position ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; +} +- (void)didEndDragForMarkerWithIdentifier:(NSString *)arg_markerId + atPosition:(FGMPlatformLatLng *)arg_position + completion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", @"dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onMarkerDragEnd", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FGMGetMessagesCodec()]; + [channel sendMessage:@[ arg_markerId ?: [NSNull null], arg_position ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; +} +- (void)didTapInfoWindowOfMarkerWithIdentifier:(NSString *)arg_markerId + completion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", @"dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onInfoWindowTap", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FGMGetMessagesCodec()]; + [channel sendMessage:@[ arg_markerId ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; +} +- (void)didTapCircleWithIdentifier:(NSString *)arg_circleId + completion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onCircleTap", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FGMGetMessagesCodec()]; + [channel sendMessage:@[ arg_circleId ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; +} +- (void)didTapCluster:(FGMPlatformCluster *)arg_cluster + completion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onClusterTap", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FGMGetMessagesCodec()]; + [channel sendMessage:@[ arg_cluster ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; +} +- (void)didTapPolygonWithIdentifier:(NSString *)arg_polygonId + completion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onPolygonTap", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FGMGetMessagesCodec()]; + [channel sendMessage:@[ arg_polygonId ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; +} +- (void)didTapPolylineWithIdentifier:(NSString *)arg_polylineId + completion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onPolylineTap", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FGMGetMessagesCodec()]; + [channel sendMessage:@[ arg_polylineId ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; +} +- (void)tileWithOverlayIdentifier:(NSString *)arg_tileOverlayId + location:(FGMPlatformPoint *)arg_location + zoom:(NSInteger)arg_zoom + completion:(void (^)(FGMPlatformTile *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", @"dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.getTileOverlayTile", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FGMGetMessagesCodec()]; + [channel sendMessage:@[ + arg_tileOverlayId ?: [NSNull null], arg_location ?: [NSNull null], @(arg_zoom) + ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + FGMPlatformTile *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +@end + +void SetUpFGMMapsPlatformViewApi(id binaryMessenger, + NSObject *api) { + SetUpFGMMapsPlatformViewApiWithSuffix(binaryMessenger, api, @""); +} + +void SetUpFGMMapsPlatformViewApiWithSuffix(id binaryMessenger, + NSObject *api, + NSString *messageChannelSuffix) { + messageChannelSuffix = messageChannelSuffix.length > 0 + ? [NSString stringWithFormat:@".%@", messageChannelSuffix] + : @""; + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsPlatformViewApi.createView", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert( + [api respondsToSelector:@selector(createViewType:error:)], + @"FGMMapsPlatformViewApi api (%@) doesn't respond to @selector(createViewType:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FGMPlatformMapViewCreationParams *arg_type = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + [api createViewType:arg_type error:&error]; + callback(wrapResult(nil, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } +} +void SetUpFGMMapsInspectorApi(id binaryMessenger, + NSObject *api) { + SetUpFGMMapsInspectorApiWithSuffix(binaryMessenger, api, @""); +} + +void SetUpFGMMapsInspectorApiWithSuffix(id binaryMessenger, + NSObject *api, + NSString *messageChannelSuffix) { + messageChannelSuffix = messageChannelSuffix.length > 0 + ? [NSString stringWithFormat:@".%@", messageChannelSuffix] + : @""; + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsInspectorApi.areBuildingsEnabled", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(areBuildingsEnabledWithError:)], + @"FGMMapsInspectorApi api (%@) doesn't respond to " + @"@selector(areBuildingsEnabledWithError:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + FlutterError *error; + NSNumber *output = [api areBuildingsEnabledWithError:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsInspectorApi.areRotateGesturesEnabled", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(areRotateGesturesEnabledWithError:)], + @"FGMMapsInspectorApi api (%@) doesn't respond to " + @"@selector(areRotateGesturesEnabledWithError:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + FlutterError *error; + NSNumber *output = [api areRotateGesturesEnabledWithError:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsInspectorApi.areScrollGesturesEnabled", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(areScrollGesturesEnabledWithError:)], + @"FGMMapsInspectorApi api (%@) doesn't respond to " + @"@selector(areScrollGesturesEnabledWithError:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + FlutterError *error; + NSNumber *output = [api areScrollGesturesEnabledWithError:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsInspectorApi.areTiltGesturesEnabled", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(areTiltGesturesEnabledWithError:)], + @"FGMMapsInspectorApi api (%@) doesn't respond to " + @"@selector(areTiltGesturesEnabledWithError:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + FlutterError *error; + NSNumber *output = [api areTiltGesturesEnabledWithError:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsInspectorApi.areZoomGesturesEnabled", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(areZoomGesturesEnabledWithError:)], + @"FGMMapsInspectorApi api (%@) doesn't respond to " + @"@selector(areZoomGesturesEnabledWithError:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + FlutterError *error; + NSNumber *output = [api areZoomGesturesEnabledWithError:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsInspectorApi.isCompassEnabled", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert( + [api respondsToSelector:@selector(isCompassEnabledWithError:)], + @"FGMMapsInspectorApi api (%@) doesn't respond to @selector(isCompassEnabledWithError:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + FlutterError *error; + NSNumber *output = [api isCompassEnabledWithError:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsInspectorApi.isMyLocationButtonEnabled", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(isMyLocationButtonEnabledWithError:)], + @"FGMMapsInspectorApi api (%@) doesn't respond to " + @"@selector(isMyLocationButtonEnabledWithError:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + FlutterError *error; + NSNumber *output = [api isMyLocationButtonEnabledWithError:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsInspectorApi.isTrafficEnabled", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert( + [api respondsToSelector:@selector(isTrafficEnabledWithError:)], + @"FGMMapsInspectorApi api (%@) doesn't respond to @selector(isTrafficEnabledWithError:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + FlutterError *error; + NSNumber *output = [api isTrafficEnabledWithError:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsInspectorApi.getTileOverlayInfo", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(tileOverlayWithIdentifier:error:)], + @"FGMMapsInspectorApi api (%@) doesn't respond to " + @"@selector(tileOverlayWithIdentifier:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_tileOverlayId = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + FGMPlatformTileLayer *output = [api tileOverlayWithIdentifier:arg_tileOverlayId + error:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsInspectorApi.getHeatmapInfo", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(heatmapWithIdentifier:error:)], + @"FGMMapsInspectorApi api (%@) doesn't respond to " + @"@selector(heatmapWithIdentifier:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_heatmapId = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + FGMPlatformHeatmap *output = [api heatmapWithIdentifier:arg_heatmapId error:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsInspectorApi.getZoomRange", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(zoomRange:)], + @"FGMMapsInspectorApi api (%@) doesn't respond to @selector(zoomRange:)", api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + FlutterError *error; + FGMPlatformZoomRange *output = [api zoomRange:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsInspectorApi.getClusters", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(clustersWithIdentifier:error:)], + @"FGMMapsInspectorApi api (%@) doesn't respond to " + @"@selector(clustersWithIdentifier:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_clusterManagerId = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSArray *output = [api clustersWithIdentifier:arg_clusterManagerId + error:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios.podspec b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios.podspec index ce652f3b41b8..f744daa68537 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios.podspec +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios.podspec @@ -25,8 +25,17 @@ Downloaded by pub (not CocoaPods). # Versions earlier than 8.4 can't be supported because that's the first version # that supports privacy manifests. s.dependency 'GoogleMaps', '>= 8.4', '< 10.0' + # Google-Maps-iOS-Utils 5.x supports GoogleMaps 8.x and iOS 14.0+ + # Google-Maps-iOS-Utils 6.x supports GoogleMaps 9.x and iOS 15.0+ + s.dependency 'Google-Maps-iOS-Utils', '>= 5.0', '< 7.0' s.static_framework = true s.platform = :ios, '14.0' - s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } + # "Google-Maps-iOS-Utils" is static and contains Swift classes. + # Find the Swift runtime when these plugins are built as libraries without `use_frameworks!` + s.swift_version = '5.9' + s.xcconfig = { + 'LIBRARY_SEARCH_PATHS' => '$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)/ $(SDKROOT)/usr/lib/swift', + 'LD_RUNPATH_SEARCH_PATHS' => '$(inherited) /usr/lib/swift', + } s.resource_bundles = {'google_maps_flutter_ios_privacy' => ['Resources/PrivacyInfo.xcprivacy']} end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_map_inspector_ios.dart b/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_map_inspector_ios.dart index 8fae1a35e316..823e210ce73b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_map_inspector_ios.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_map_inspector_ios.dart @@ -3,111 +3,142 @@ // found in the LICENSE file. import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; +import 'google_maps_flutter_ios.dart'; +import 'messages.g.dart'; +import 'serialization.dart'; + /// An Android of implementation of [GoogleMapsInspectorPlatform]. @visibleForTesting class GoogleMapsInspectorIOS extends GoogleMapsInspectorPlatform { - /// Creates a method-channel-based inspector instance that gets the channel - /// for a given map ID from [channelProvider]. - GoogleMapsInspectorIOS(MethodChannel? Function(int mapId) channelProvider) - : _channelProvider = channelProvider; + /// Creates an inspector API instance for a given map ID from + /// [inspectorProvider]. + GoogleMapsInspectorIOS( + MapsInspectorApi? Function(int mapId) inspectorProvider) + : _inspectorProvider = inspectorProvider; - final MethodChannel? Function(int mapId) _channelProvider; + final MapsInspectorApi? Function(int mapId) _inspectorProvider; @override Future areBuildingsEnabled({required int mapId}) async { - return (await _channelProvider(mapId)! - .invokeMethod('map#isBuildingsEnabled'))!; + return _inspectorProvider(mapId)!.areBuildingsEnabled(); } @override Future areRotateGesturesEnabled({required int mapId}) async { - return (await _channelProvider(mapId)! - .invokeMethod('map#isRotateGesturesEnabled'))!; + return _inspectorProvider(mapId)!.areRotateGesturesEnabled(); } @override Future areScrollGesturesEnabled({required int mapId}) async { - return (await _channelProvider(mapId)! - .invokeMethod('map#isScrollGesturesEnabled'))!; + return _inspectorProvider(mapId)!.areScrollGesturesEnabled(); } @override Future areTiltGesturesEnabled({required int mapId}) async { - return (await _channelProvider(mapId)! - .invokeMethod('map#isTiltGesturesEnabled'))!; + return _inspectorProvider(mapId)!.areTiltGesturesEnabled(); } @override Future areZoomControlsEnabled({required int mapId}) async { - return (await _channelProvider(mapId)! - .invokeMethod('map#isZoomControlsEnabled'))!; + // Does not exist on iOS. + return false; } @override Future areZoomGesturesEnabled({required int mapId}) async { - return (await _channelProvider(mapId)! - .invokeMethod('map#isZoomGesturesEnabled'))!; + return _inspectorProvider(mapId)!.areZoomGesturesEnabled(); } @override Future getMinMaxZoomLevels({required int mapId}) async { - final List zoomLevels = (await _channelProvider(mapId)! - .invokeMethod>('map#getMinMaxZoomLevels'))! - .cast(); - return MinMaxZoomPreference(zoomLevels[0], zoomLevels[1]); + final PlatformZoomRange zoomLevels = + await _inspectorProvider(mapId)!.getZoomRange(); + return MinMaxZoomPreference(zoomLevels.min, zoomLevels.max); } @override Future getTileOverlayInfo(TileOverlayId tileOverlayId, {required int mapId}) async { - final Map? tileInfo = await _channelProvider(mapId)! - .invokeMapMethod( - 'map#getTileOverlayInfo', { - 'tileOverlayId': tileOverlayId.value, - }); + final PlatformTileLayer? tileInfo = await _inspectorProvider(mapId)! + .getTileOverlayInfo(tileOverlayId.value); if (tileInfo == null) { return null; } return TileOverlay( tileOverlayId: tileOverlayId, - fadeIn: tileInfo['fadeIn']! as bool, - transparency: tileInfo['transparency']! as double, - visible: tileInfo['visible']! as bool, - // Android and iOS return different types. - zIndex: (tileInfo['zIndex']! as num).toInt(), + fadeIn: tileInfo.fadeIn, + transparency: 1.0 - tileInfo.opacity, + visible: tileInfo.visible, + zIndex: tileInfo.zIndex, + ); + } + + @override + bool supportsGettingHeatmapInfo() => true; + + @override + Future getHeatmapInfo(HeatmapId heatmapId, + {required int mapId}) async { + final PlatformHeatmap? heatmapInfo = + await _inspectorProvider(mapId)!.getHeatmapInfo(heatmapId.value); + if (heatmapInfo == null) { + return null; + } + + final Map json = + (heatmapInfo.json as Map).cast(); + return Heatmap( + heatmapId: heatmapId, + data: (json['data']! as List) + .map(deserializeWeightedLatLng) + .whereType() + .toList(), + gradient: deserializeHeatmapGradient(json['gradient']), + opacity: json['opacity']! as double, + radius: HeatmapRadius.fromPixels(json['radius']! as int), + minimumZoomIntensity: json['minimumZoomIntensity']! as int, + maximumZoomIntensity: json['maximumZoomIntensity']! as int, ); } @override Future isCompassEnabled({required int mapId}) async { - return (await _channelProvider(mapId)! - .invokeMethod('map#isCompassEnabled'))!; + return _inspectorProvider(mapId)!.isCompassEnabled(); } @override Future isLiteModeEnabled({required int mapId}) async { - return (await _channelProvider(mapId)! - .invokeMethod('map#isLiteModeEnabled'))!; + // Does not exist on iOS. + return false; } @override Future isMapToolbarEnabled({required int mapId}) async { - return (await _channelProvider(mapId)! - .invokeMethod('map#isMapToolbarEnabled'))!; + // Does not exist on iOS. + return false; } @override Future isMyLocationButtonEnabled({required int mapId}) async { - return (await _channelProvider(mapId)! - .invokeMethod('map#isMyLocationButtonEnabled'))!; + return _inspectorProvider(mapId)!.isMyLocationButtonEnabled(); } @override Future isTrafficEnabled({required int mapId}) async { - return (await _channelProvider(mapId)! - .invokeMethod('map#isTrafficEnabled'))!; + return _inspectorProvider(mapId)!.isTrafficEnabled(); + } + + @override + Future> getClusters({ + required int mapId, + required ClusterManagerId clusterManagerId, + }) async { + return (await _inspectorProvider(mapId)! + .getClusters(clusterManagerId.value)) + .map((PlatformCluster cluster) => + GoogleMapsFlutterIOS.clusterFromPlatformCluster(cluster)) + .toList(); } } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_maps_flutter_ios.dart b/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_maps_flutter_ios.dart index 56f3cc5a0794..9af2e061bde1 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_maps_flutter_ios.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_maps_flutter_ios.dart @@ -12,10 +12,17 @@ import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platf import 'package:stream_transform/stream_transform.dart'; import 'google_map_inspector_ios.dart'; +import 'messages.g.dart'; +import 'serialization.dart'; // TODO(stuartmorgan): Remove the dependency on platform interface toJson // methods. Channel serialization details should all be package-internal. +/// The non-test implementation of `_apiProvider`. +MapsApi _productionApiProvider(int mapId) { + return MapsApi(messageChannelSuffix: mapId.toString()); +} + /// Error thrown when an unknown map ID is provided to a method channel API. class UnknownMapIDError extends Error { /// Creates an assertion error with the provided [mapId] and optional @@ -39,45 +46,75 @@ class UnknownMapIDError extends Error { /// An implementation of [GoogleMapsFlutterPlatform] for iOS. class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { + /// Creates a new Android maps implementation instance. + GoogleMapsFlutterIOS({ + @visibleForTesting MapsApi Function(int mapId)? apiProvider, + }) : _apiProvider = apiProvider ?? _productionApiProvider; + /// Registers the iOS implementation of GoogleMapsFlutterPlatform. static void registerWith() { GoogleMapsFlutterPlatform.instance = GoogleMapsFlutterIOS(); } - // Keep a collection of id -> channel - // Every method call passes the int mapId - final Map _channels = {}; + final Map _hostMaps = {}; + + // A method to create MapsApi instances, which can be overridden for testing. + final MapsApi Function(int mapId) _apiProvider; + + /// The per-map handlers for callbacks from the host side. + @visibleForTesting + final Map hostMapHandlers = + {}; - /// Accesses the MethodChannel associated to the passed mapId. - MethodChannel _channel(int mapId) { - final MethodChannel? channel = _channels[mapId]; - if (channel == null) { + /// Accesses the MapsApi associated to the passed mapId. + MapsApi _hostApi(int mapId) { + final MapsApi? api = _hostMaps[mapId]; + if (api == null) { throw UnknownMapIDError(mapId); } - return channel; + return api; } // Keep a collection of mapId to a map of TileOverlays. final Map> _tileOverlays = >{}; - /// Returns the channel for [mapId], creating it if it doesn't already exist. + /// Returns the handler for [mapId], creating it if it doesn't already exist. + @visibleForTesting + HostMapMessageHandler ensureHandlerInitialized(int mapId) { + HostMapMessageHandler? handler = hostMapHandlers[mapId]; + if (handler == null) { + handler = HostMapMessageHandler( + mapId, + _mapEventStreamController, + tileOverlayProvider: (TileOverlayId tileOverlayId) { + final Map? tileOverlaysForMap = + _tileOverlays[mapId]; + return tileOverlaysForMap?[tileOverlayId]; + }, + ); + hostMapHandlers[mapId] = handler; + } + return handler; + } + + /// Returns the API instance for [mapId], creating it if it doesn't already + /// exist. @visibleForTesting - MethodChannel ensureChannelInitialized(int mapId) { - MethodChannel? channel = _channels[mapId]; - if (channel == null) { - channel = MethodChannel('plugins.flutter.dev/google_maps_ios_$mapId'); - channel.setMethodCallHandler( - (MethodCall call) => _handleMethodCall(call, mapId)); - _channels[mapId] = channel; + MapsApi ensureApiInitialized(int mapId) { + MapsApi? api = _hostMaps[mapId]; + if (api == null) { + api = _apiProvider(mapId); + _hostMaps[mapId] ??= api; } - return channel; + return api; } @override Future init(int mapId) { - final MethodChannel channel = ensureChannelInitialized(mapId); - return channel.invokeMethod('map#waitForMap'); + ensureHandlerInitialized(mapId); + final MapsApi hostApi = ensureApiInitialized(mapId); + return hostApi.waitForMap(); } @override @@ -163,109 +200,18 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { return _events(mapId).whereType(); } - Future _handleMethodCall(MethodCall call, int mapId) async { - switch (call.method) { - case 'camera#onMoveStarted': - _mapEventStreamController.add(CameraMoveStartedEvent(mapId)); - case 'camera#onMove': - final Map arguments = _getArgumentDictionary(call); - _mapEventStreamController.add(CameraMoveEvent( - mapId, - CameraPosition.fromMap(arguments['position'])!, - )); - case 'camera#onIdle': - _mapEventStreamController.add(CameraIdleEvent(mapId)); - case 'marker#onTap': - final Map arguments = _getArgumentDictionary(call); - _mapEventStreamController.add(MarkerTapEvent( - mapId, - MarkerId(arguments['markerId']! as String), - )); - case 'marker#onDragStart': - final Map arguments = _getArgumentDictionary(call); - _mapEventStreamController.add(MarkerDragStartEvent( - mapId, - LatLng.fromJson(arguments['position'])!, - MarkerId(arguments['markerId']! as String), - )); - case 'marker#onDrag': - final Map arguments = _getArgumentDictionary(call); - _mapEventStreamController.add(MarkerDragEvent( - mapId, - LatLng.fromJson(arguments['position'])!, - MarkerId(arguments['markerId']! as String), - )); - case 'marker#onDragEnd': - final Map arguments = _getArgumentDictionary(call); - _mapEventStreamController.add(MarkerDragEndEvent( - mapId, - LatLng.fromJson(arguments['position'])!, - MarkerId(arguments['markerId']! as String), - )); - case 'infoWindow#onTap': - final Map arguments = _getArgumentDictionary(call); - _mapEventStreamController.add(InfoWindowTapEvent( - mapId, - MarkerId(arguments['markerId']! as String), - )); - case 'polyline#onTap': - final Map arguments = _getArgumentDictionary(call); - _mapEventStreamController.add(PolylineTapEvent( - mapId, - PolylineId(arguments['polylineId']! as String), - )); - case 'polygon#onTap': - final Map arguments = _getArgumentDictionary(call); - _mapEventStreamController.add(PolygonTapEvent( - mapId, - PolygonId(arguments['polygonId']! as String), - )); - case 'circle#onTap': - final Map arguments = _getArgumentDictionary(call); - _mapEventStreamController.add(CircleTapEvent( - mapId, - CircleId(arguments['circleId']! as String), - )); - case 'map#onTap': - final Map arguments = _getArgumentDictionary(call); - _mapEventStreamController.add(MapTapEvent( - mapId, - LatLng.fromJson(arguments['position'])!, - )); - case 'map#onLongPress': - final Map arguments = _getArgumentDictionary(call); - _mapEventStreamController.add(MapLongPressEvent( - mapId, - LatLng.fromJson(arguments['position'])!, - )); - case 'tileOverlay#getTile': - final Map arguments = _getArgumentDictionary(call); - final Map? tileOverlaysForThisMap = - _tileOverlays[mapId]; - final String tileOverlayId = arguments['tileOverlayId']! as String; - final TileOverlay? tileOverlay = - tileOverlaysForThisMap?[TileOverlayId(tileOverlayId)]; - final TileProvider? tileProvider = tileOverlay?.tileProvider; - if (tileProvider == null) { - return TileProvider.noTile.toJson(); - } - final Tile tile = await tileProvider.getTile( - arguments['x']! as int, - arguments['y']! as int, - arguments['zoom'] as int?, - ); - return tile.toJson(); - default: - throw MissingPluginException(); - } + @override + Stream onClusterTap({required int mapId}) { + return _events(mapId).whereType(); } - /// Returns the arguments of [call] as typed string-keyed Map. - /// - /// This does not do any type validation, so is only safe to call if the - /// arguments are known to be a map. - Map _getArgumentDictionary(MethodCall call) { - return (call.arguments as Map).cast(); + @override + Future updateMapConfiguration( + MapConfiguration configuration, { + required int mapId, + }) { + return _hostApi(mapId).updateMapConfiguration( + _platformMapConfigurationFromMapConfiguration(configuration)); } @override @@ -273,12 +219,8 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { Map optionsUpdate, { required int mapId, }) { - return _channel(mapId).invokeMethod( - 'map#update', - { - 'options': optionsUpdate, - }, - ); + return _hostApi(mapId).updateMapConfiguration( + _platformMapConfigurationFromOptionsJson(optionsUpdate)); } @override @@ -286,9 +228,10 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { MarkerUpdates markerUpdates, { required int mapId, }) { - return _channel(mapId).invokeMethod( - 'markers#update', - markerUpdates.toJson(), + return _hostApi(mapId).updateMarkers( + markerUpdates.markersToAdd.map(_platformMarkerFromMarker).toList(), + markerUpdates.markersToChange.map(_platformMarkerFromMarker).toList(), + markerUpdates.markerIdsToRemove.map((MarkerId id) => id.value).toList(), ); } @@ -297,9 +240,12 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { PolygonUpdates polygonUpdates, { required int mapId, }) { - return _channel(mapId).invokeMethod( - 'polygons#update', - polygonUpdates.toJson(), + return _hostApi(mapId).updatePolygons( + polygonUpdates.polygonsToAdd.map(_platformPolygonFromPolygon).toList(), + polygonUpdates.polygonsToChange.map(_platformPolygonFromPolygon).toList(), + polygonUpdates.polygonIdsToRemove + .map((PolygonId id) => id.value) + .toList(), ); } @@ -308,9 +254,16 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { PolylineUpdates polylineUpdates, { required int mapId, }) { - return _channel(mapId).invokeMethod( - 'polylines#update', - polylineUpdates.toJson(), + return _hostApi(mapId).updatePolylines( + polylineUpdates.polylinesToAdd + .map(_platformPolylineFromPolyline) + .toList(), + polylineUpdates.polylinesToChange + .map(_platformPolylineFromPolyline) + .toList(), + polylineUpdates.polylineIdsToRemove + .map((PolylineId id) => id.value) + .toList(), ); } @@ -319,9 +272,24 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { CircleUpdates circleUpdates, { required int mapId, }) { - return _channel(mapId).invokeMethod( - 'circles#update', - circleUpdates.toJson(), + return _hostApi(mapId).updateCircles( + circleUpdates.circlesToAdd.map(_platformCircleFromCircle).toList(), + circleUpdates.circlesToChange.map(_platformCircleFromCircle).toList(), + circleUpdates.circleIdsToRemove.map((CircleId id) => id.value).toList(), + ); + } + + @override + Future updateHeatmaps( + HeatmapUpdates heatmapUpdates, { + required int mapId, + }) { + return _hostApi(mapId).updateHeatmaps( + heatmapUpdates.heatmapsToAdd.map(_platformHeatmapFromHeatmap).toList(), + heatmapUpdates.heatmapsToChange.map(_platformHeatmapFromHeatmap).toList(), + heatmapUpdates.heatmapIdsToRemove + .map((HeatmapId id) => id.value) + .toList(), ); } @@ -338,9 +306,31 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { final _TileOverlayUpdates updates = _TileOverlayUpdates.from(previousSet, newTileOverlays); _tileOverlays[mapId] = keyTileOverlayId(newTileOverlays); - return _channel(mapId).invokeMethod( - 'tileOverlays#update', - updates.toJson(), + return _hostApi(mapId).updateTileOverlays( + updates.tileOverlaysToAdd + .map(_platformTileOverlayFromTileOverlay) + .toList(), + updates.tileOverlaysToChange + .map(_platformTileOverlayFromTileOverlay) + .toList(), + updates.tileOverlayIdsToRemove + .map((TileOverlayId id) => id.value) + .toList(), + ); + } + + @override + Future updateClusterManagers( + ClusterManagerUpdates clusterManagerUpdates, { + required int mapId, + }) { + return _hostApi(mapId).updateClusterManagers( + clusterManagerUpdates.clusterManagersToAdd + .map(_platformClusterManagerFromClusterManager) + .toList(), + clusterManagerUpdates.clusterManagerIdsToRemove + .map((ClusterManagerId id) => id.value) + .toList(), ); } @@ -349,10 +339,7 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { TileOverlayId tileOverlayId, { required int mapId, }) { - return _channel(mapId) - .invokeMethod('tileOverlays#clearTileCache', { - 'tileOverlayId': tileOverlayId.value, - }); + return _hostApi(mapId).clearTileCache(tileOverlayId.value); } @override @@ -360,10 +347,8 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { CameraUpdate cameraUpdate, { required int mapId, }) { - return _channel(mapId) - .invokeMethod('camera#animate', { - 'cameraUpdate': cameraUpdate.toJson(), - }); + return _hostApi(mapId) + .animateCamera(PlatformCameraUpdate(json: cameraUpdate.toJson())); } @override @@ -371,9 +356,8 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { CameraUpdate cameraUpdate, { required int mapId, }) { - return _channel(mapId).invokeMethod('camera#move', { - 'cameraUpdate': cameraUpdate.toJson(), - }); + return _hostApi(mapId) + .moveCamera(PlatformCameraUpdate(json: cameraUpdate.toJson())); } @override @@ -381,11 +365,10 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { String? mapStyle, { required int mapId, }) async { - final List successAndError = (await _channel(mapId) - .invokeMethod>('map#setStyle', mapStyle))!; - final bool success = successAndError[0] as bool; - if (!success) { - throw MapStyleException(successAndError[1] as String); + final String? errorDescription = + await _hostApi(mapId).setStyle(mapStyle ?? ''); + if (errorDescription != null) { + throw MapStyleException(errorDescription); } } @@ -393,12 +376,8 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { Future getVisibleRegion({ required int mapId, }) async { - final Map latLngBounds = (await _channel(mapId) - .invokeMapMethod('map#getVisibleRegion'))!; - final LatLng southwest = LatLng.fromJson(latLngBounds['southwest'])!; - final LatLng northeast = LatLng.fromJson(latLngBounds['northeast'])!; - - return LatLngBounds(northeast: northeast, southwest: southwest); + return _latLngBoundsFromPlatformLatLngBounds( + await _hostApi(mapId).getVisibleRegion()); } @override @@ -406,11 +385,8 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { LatLng latLng, { required int mapId, }) async { - final Map point = (await _channel(mapId) - .invokeMapMethod( - 'map#getScreenCoordinate', latLng.toJson()))!; - - return ScreenCoordinate(x: point['x']!, y: point['y']!); + return _screenCoordinateFromPlatformPoint(await _hostApi(mapId) + .getScreenCoordinate(_platformLatLngFromLatLng(latLng))); } @override @@ -418,10 +394,8 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { ScreenCoordinate screenCoordinate, { required int mapId, }) async { - final List latLng = (await _channel(mapId) - .invokeMethod>( - 'map#getLatLng', screenCoordinate.toJson()))!; - return LatLng(latLng[0] as double, latLng[1] as double); + return _latLngFromPlatformLatLng(await _hostApi(mapId) + .getLatLng(_platformPointFromScreenCoordinate(screenCoordinate))); } @override @@ -429,8 +403,7 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { MarkerId markerId, { required int mapId, }) { - return _channel(mapId).invokeMethod( - 'markers#showInfoWindow', {'markerId': markerId.value}); + return _hostApi(mapId).showInfoWindow(markerId.value); } @override @@ -438,64 +411,72 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { MarkerId markerId, { required int mapId, }) { - return _channel(mapId).invokeMethod( - 'markers#hideInfoWindow', {'markerId': markerId.value}); + return _hostApi(mapId).hideInfoWindow(markerId.value); } @override Future isMarkerInfoWindowShown( MarkerId markerId, { required int mapId, - }) async { - return (await _channel(mapId).invokeMethod( - 'markers#isInfoWindowShown', - {'markerId': markerId.value}))!; + }) { + return _hostApi(mapId).isInfoWindowShown(markerId.value); } @override Future getZoomLevel({ required int mapId, - }) async { - return (await _channel(mapId).invokeMethod('map#getZoomLevel'))!; + }) { + return _hostApi(mapId).getZoomLevel(); } @override Future takeSnapshot({ required int mapId, }) { - return _channel(mapId).invokeMethod('map#takeSnapshot'); + return _hostApi(mapId).takeSnapshot(); } @override Future getStyleError({required int mapId}) { - final MethodChannel channel = ensureChannelInitialized(mapId); - return channel.invokeMethod('map#getStyleError'); + return _hostApi(mapId).getLastStyleError(); } Widget _buildView( int creationId, PlatformViewCreatedCallback onPlatformViewCreated, { + required PlatformMapConfiguration mapConfiguration, required MapWidgetConfiguration widgetConfiguration, MapObjects mapObjects = const MapObjects(), - Map mapOptions = const {}, }) { - final Map creationParams = { - 'initialCameraPosition': - widgetConfiguration.initialCameraPosition.toMap(), - 'options': mapOptions, - 'markersToAdd': serializeMarkerSet(mapObjects.markers), - 'polygonsToAdd': serializePolygonSet(mapObjects.polygons), - 'polylinesToAdd': serializePolylineSet(mapObjects.polylines), - 'circlesToAdd': serializeCircleSet(mapObjects.circles), - 'tileOverlaysToAdd': serializeTileOverlaySet(mapObjects.tileOverlays), - }; + final PlatformMapViewCreationParams creationParams = + PlatformMapViewCreationParams( + initialCameraPosition: _platformCameraPositionFromCameraPosition( + widgetConfiguration.initialCameraPosition), + mapConfiguration: mapConfiguration, + initialMarkers: + mapObjects.markers.map(_platformMarkerFromMarker).toList(), + initialPolygons: + mapObjects.polygons.map(_platformPolygonFromPolygon).toList(), + initialPolylines: + mapObjects.polylines.map(_platformPolylineFromPolyline).toList(), + initialCircles: + mapObjects.circles.map(_platformCircleFromCircle).toList(), + initialHeatmaps: + mapObjects.heatmaps.map(_platformHeatmapFromHeatmap).toList(), + initialTileOverlays: mapObjects.tileOverlays + .map(_platformTileOverlayFromTileOverlay) + .toList(), + initialClusterManagers: mapObjects.clusterManagers + .map(_platformClusterManagerFromClusterManager) + .toList(), + ); return UiKitView( viewType: 'plugins.flutter.dev/google_maps_ios', onPlatformViewCreated: onPlatformViewCreated, gestureRecognizers: widgetConfiguration.gestureRecognizers, creationParams: creationParams, - creationParamsCodec: const StandardMessageCodec(), + creationParamsCodec: MapsApi.pigeonChannelCodec, ); } @@ -512,7 +493,8 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { onPlatformViewCreated, widgetConfiguration: widgetConfiguration, mapObjects: mapObjects, - mapOptions: _jsonForMapConfiguration(mapConfiguration), + mapConfiguration: + _platformMapConfigurationFromMapConfiguration(mapConfiguration), ); } @@ -542,7 +524,7 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { polylines: polylines, circles: circles, tileOverlays: tileOverlays), - mapOptions: mapOptions, + mapConfiguration: _platformMapConfigurationFromOptionsJson(mapOptions), ); } @@ -577,57 +559,399 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { @override @visibleForTesting void enableDebugInspection() { - GoogleMapsInspectorPlatform.instance = - GoogleMapsInspectorIOS((int mapId) => _channel(mapId)); + GoogleMapsInspectorPlatform.instance = GoogleMapsInspectorIOS((int mapId) => + MapsInspectorApi(messageChannelSuffix: mapId.toString())); + } + + /// Converts a Pigeon [PlatformCluster] to the corresponding [Cluster]. + static Cluster clusterFromPlatformCluster(PlatformCluster cluster) { + return Cluster( + ClusterManagerId(cluster.clusterManagerId), + cluster.markerIds + // See comment in messages.dart for why the force unwrap is okay. + .map((String? markerId) => MarkerId(markerId!)) + .toList(), + position: _latLngFromPlatformLatLng(cluster.position), + bounds: _latLngBoundsFromPlatformLatLngBounds(cluster.bounds)); + } + + static ScreenCoordinate _screenCoordinateFromPlatformPoint( + PlatformPoint point) { + return ScreenCoordinate(x: point.x.round(), y: point.y.round()); + } + + static PlatformPoint _platformPointFromScreenCoordinate( + ScreenCoordinate coordinate) { + return PlatformPoint( + x: coordinate.x.toDouble(), y: coordinate.y.toDouble()); + } + + static PlatformCircle _platformCircleFromCircle(Circle circle) { + return PlatformCircle(json: circle.toJson()); + } + + static PlatformHeatmap _platformHeatmapFromHeatmap(Heatmap heatmap) { + return PlatformHeatmap(json: serializeHeatmap(heatmap)); + } + + static PlatformMarker _platformMarkerFromMarker(Marker marker) { + return PlatformMarker(json: marker.toJson()); + } + + static PlatformPolygon _platformPolygonFromPolygon(Polygon polygon) { + return PlatformPolygon(json: polygon.toJson()); + } + + static PlatformPolyline _platformPolylineFromPolyline(Polyline polyline) { + return PlatformPolyline(json: polyline.toJson()); + } + + static PlatformTileOverlay _platformTileOverlayFromTileOverlay( + TileOverlay tileOverlay) { + return PlatformTileOverlay(json: tileOverlay.toJson()); + } + + static PlatformClusterManager _platformClusterManagerFromClusterManager( + ClusterManager clusterManager) { + return PlatformClusterManager( + identifier: clusterManager.clusterManagerId.value); + } +} + +/// Callback handler for map events from the platform host. +@visibleForTesting +class HostMapMessageHandler implements MapsCallbackApi { + /// Creates a new handler that listens for events from map [mapId], and + /// broadcasts them to [streamController]. + HostMapMessageHandler( + this.mapId, + this.streamController, { + required this.tileOverlayProvider, + }) { + MapsCallbackApi.setUp(this, messageChannelSuffix: mapId.toString()); + } + + /// Removes the handler for native messages. + void dispose() { + MapsCallbackApi.setUp(null, messageChannelSuffix: mapId.toString()); + } + + /// The map ID this handler listens for events from. + final int mapId; + + /// The controller used to broadcast map events coming from the + /// host platform. + final StreamController> streamController; + + /// The callback to get a tile overlay for the corresponding map. + final TileOverlay? Function(TileOverlayId tileOverlayId) tileOverlayProvider; + + @override + Future getTileOverlayTile( + String tileOverlayId, + PlatformPoint location, + int zoom, + ) async { + final TileOverlay? tileOverlay = + tileOverlayProvider(TileOverlayId(tileOverlayId)); + final TileProvider? tileProvider = tileOverlay?.tileProvider; + final Tile tile = tileProvider == null + ? TileProvider.noTile + : await tileProvider.getTile( + location.x.round(), location.y.round(), zoom); + return _platformTileFromTile(tile); + } + + @override + void onCameraIdle() { + streamController.add(CameraIdleEvent(mapId)); + } + + @override + void onCameraMove(PlatformCameraPosition cameraPosition) { + streamController.add(CameraMoveEvent( + mapId, + CameraPosition( + target: _latLngFromPlatformLatLng(cameraPosition.target), + bearing: cameraPosition.bearing, + tilt: cameraPosition.tilt, + zoom: cameraPosition.zoom, + ), + )); + } + + @override + void onCameraMoveStarted() { + streamController.add(CameraMoveStartedEvent(mapId)); + } + + @override + void onCircleTap(String circleId) { + streamController.add(CircleTapEvent(mapId, CircleId(circleId))); + } + + @override + void onClusterTap(PlatformCluster cluster) { + streamController.add(ClusterTapEvent( + mapId, + GoogleMapsFlutterIOS.clusterFromPlatformCluster(cluster), + )); + } + + @override + void onInfoWindowTap(String markerId) { + streamController.add(InfoWindowTapEvent(mapId, MarkerId(markerId))); + } + + @override + void onLongPress(PlatformLatLng position) { + streamController + .add(MapLongPressEvent(mapId, _latLngFromPlatformLatLng(position))); + } + + @override + void onMarkerDrag(String markerId, PlatformLatLng position) { + streamController.add(MarkerDragEvent( + mapId, _latLngFromPlatformLatLng(position), MarkerId(markerId))); + } + + @override + void onMarkerDragStart(String markerId, PlatformLatLng position) { + streamController.add(MarkerDragStartEvent( + mapId, _latLngFromPlatformLatLng(position), MarkerId(markerId))); + } + + @override + void onMarkerDragEnd(String markerId, PlatformLatLng position) { + streamController.add(MarkerDragEndEvent( + mapId, _latLngFromPlatformLatLng(position), MarkerId(markerId))); + } + + @override + void onMarkerTap(String markerId) { + streamController.add(MarkerTapEvent(mapId, MarkerId(markerId))); + } + + @override + void onPolygonTap(String polygonId) { + streamController.add(PolygonTapEvent(mapId, PolygonId(polygonId))); + } + + @override + void onPolylineTap(String polylineId) { + streamController.add(PolylineTapEvent(mapId, PolylineId(polylineId))); + } + + @override + void onTap(PlatformLatLng position) { + streamController + .add(MapTapEvent(mapId, _latLngFromPlatformLatLng(position))); + } +} + +LatLng _latLngFromPlatformLatLng(PlatformLatLng latLng) { + return LatLng(latLng.latitude, latLng.longitude); +} + +LatLngBounds _latLngBoundsFromPlatformLatLngBounds( + PlatformLatLngBounds bounds) { + return LatLngBounds( + southwest: _latLngFromPlatformLatLng(bounds.southwest), + northeast: _latLngFromPlatformLatLng(bounds.northeast)); +} + +PlatformLatLng _platformLatLngFromLatLng(LatLng latLng) { + return PlatformLatLng(latitude: latLng.latitude, longitude: latLng.longitude); +} + +PlatformLatLngBounds? _platformLatLngBoundsFromLatLngBounds( + LatLngBounds? bounds) { + if (bounds == null) { + return null; } + return PlatformLatLngBounds( + northeast: _platformLatLngFromLatLng(bounds.northeast), + southwest: _platformLatLngFromLatLng(bounds.southwest)); } -Map _jsonForMapConfiguration(MapConfiguration config) { - final EdgeInsets? padding = config.padding; - return { - if (config.compassEnabled != null) 'compassEnabled': config.compassEnabled!, - if (config.mapToolbarEnabled != null) - 'mapToolbarEnabled': config.mapToolbarEnabled!, - if (config.cameraTargetBounds != null) - 'cameraTargetBounds': config.cameraTargetBounds!.toJson(), - if (config.mapType != null) 'mapType': config.mapType!.index, - if (config.minMaxZoomPreference != null) - 'minMaxZoomPreference': config.minMaxZoomPreference!.toJson(), - if (config.rotateGesturesEnabled != null) - 'rotateGesturesEnabled': config.rotateGesturesEnabled!, - if (config.scrollGesturesEnabled != null) - 'scrollGesturesEnabled': config.scrollGesturesEnabled!, - if (config.tiltGesturesEnabled != null) - 'tiltGesturesEnabled': config.tiltGesturesEnabled!, - if (config.zoomControlsEnabled != null) - 'zoomControlsEnabled': config.zoomControlsEnabled!, - if (config.zoomGesturesEnabled != null) - 'zoomGesturesEnabled': config.zoomGesturesEnabled!, - if (config.liteModeEnabled != null) - 'liteModeEnabled': config.liteModeEnabled!, - if (config.trackCameraPosition != null) - 'trackCameraPosition': config.trackCameraPosition!, - if (config.myLocationEnabled != null) - 'myLocationEnabled': config.myLocationEnabled!, - if (config.myLocationButtonEnabled != null) - 'myLocationButtonEnabled': config.myLocationButtonEnabled!, - if (padding != null) - 'padding': [ - padding.top, - padding.left, - padding.bottom, - padding.right, - ], - if (config.indoorViewEnabled != null) - 'indoorEnabled': config.indoorViewEnabled!, - if (config.trafficEnabled != null) 'trafficEnabled': config.trafficEnabled!, - if (config.buildingsEnabled != null) - 'buildingsEnabled': config.buildingsEnabled!, - if (config.cloudMapId != null) 'cloudMapId': config.cloudMapId!, - if (config.style != null) 'style': config.style!, +PlatformCameraTargetBounds? _platformCameraTargetBoundsFromCameraTargetBounds( + CameraTargetBounds? bounds) { + return bounds == null + ? null + : PlatformCameraTargetBounds( + bounds: _platformLatLngBoundsFromLatLngBounds(bounds.bounds)); +} + +PlatformTile _platformTileFromTile(Tile tile) { + return PlatformTile(width: tile.width, height: tile.height, data: tile.data); +} + +PlatformMapType? _platformMapTypeFromMapType(MapType? type) { + switch (type) { + case null: + return null; + case MapType.none: + return PlatformMapType.none; + case MapType.normal: + return PlatformMapType.normal; + case MapType.satellite: + return PlatformMapType.satellite; + case MapType.terrain: + return PlatformMapType.terrain; + case MapType.hybrid: + return PlatformMapType.hybrid; + } + // The enum comes from a different package, which could get a new value at + // any time, so provide a fallback that ensures this won't break when used + // with a version that contains new values. This is deliberately outside + // the switch rather than a `default` so that the linter will flag the + // switch as needing an update. + // ignore: dead_code + return PlatformMapType.normal; +} + +PlatformZoomRange? _platformZoomRangeFromMinMaxZoomPreference( + MinMaxZoomPreference? zoomPref) { + return zoomPref == null + ? null + : PlatformZoomRange(min: zoomPref.minZoom, max: zoomPref.maxZoom); +} + +PlatformEdgeInsets? _platformEdgeInsetsFromEdgeInsets(EdgeInsets? insets) { + return insets == null + ? null + : PlatformEdgeInsets( + top: insets.top, + bottom: insets.bottom, + left: insets.left, + right: insets.right); +} + +PlatformMapConfiguration _platformMapConfigurationFromMapConfiguration( + MapConfiguration config) { + return PlatformMapConfiguration( + compassEnabled: config.compassEnabled, + cameraTargetBounds: _platformCameraTargetBoundsFromCameraTargetBounds( + config.cameraTargetBounds), + mapType: _platformMapTypeFromMapType(config.mapType), + minMaxZoomPreference: + _platformZoomRangeFromMinMaxZoomPreference(config.minMaxZoomPreference), + rotateGesturesEnabled: config.rotateGesturesEnabled, + scrollGesturesEnabled: config.scrollGesturesEnabled, + tiltGesturesEnabled: config.tiltGesturesEnabled, + trackCameraPosition: config.trackCameraPosition, + zoomGesturesEnabled: config.zoomGesturesEnabled, + myLocationEnabled: config.myLocationEnabled, + myLocationButtonEnabled: config.myLocationButtonEnabled, + padding: _platformEdgeInsetsFromEdgeInsets(config.padding), + indoorViewEnabled: config.indoorViewEnabled, + trafficEnabled: config.trafficEnabled, + buildingsEnabled: config.buildingsEnabled, + cloudMapId: config.cloudMapId, + style: config.style, + ); +} + +// For supporting the deprecated updateMapOptions API. +PlatformMapConfiguration _platformMapConfigurationFromOptionsJson( + Map options) { + // All of these hard-coded values and structures come from + // google_maps_flutter_platform_interface/lib/src/types/utils/map_configuration_serialization.dart + // to support this legacy API that relied on cross-package magic strings. + final List? padding = + (options['padding'] as List?)?.cast(); + final int? mapType = options['mapType'] as int?; + return PlatformMapConfiguration( + compassEnabled: options['compassEnabled'] as bool?, + cameraTargetBounds: _platformCameraTargetBoundsFromCameraTargetBoundsJson( + options['cameraTargetBounds']), + mapType: mapType == null ? null : _platformMapTypeFromMapTypeIndex(mapType), + minMaxZoomPreference: _platformZoomRangeFromMinMaxZoomPreferenceJson( + options['minMaxZoomPreference']), + rotateGesturesEnabled: options['rotateGesturesEnabled'] as bool?, + scrollGesturesEnabled: options['scrollGesturesEnabled'] as bool?, + tiltGesturesEnabled: options['tiltGesturesEnabled'] as bool?, + trackCameraPosition: options['trackCameraPosition'] as bool?, + zoomGesturesEnabled: options['zoomGesturesEnabled'] as bool?, + myLocationEnabled: options['myLocationEnabled'] as bool?, + myLocationButtonEnabled: options['myLocationButtonEnabled'] as bool?, + padding: padding == null + ? null + : PlatformEdgeInsets( + top: padding[0], + left: padding[1], + bottom: padding[2], + right: padding[3]), + indoorViewEnabled: options['indoorEnabled'] as bool?, + trafficEnabled: options['trafficEnabled'] as bool?, + buildingsEnabled: options['buildingsEnabled'] as bool?, + cloudMapId: options['cloudMapId'] as String?, + style: options['style'] as String?, + ); +} + +PlatformCameraPosition _platformCameraPositionFromCameraPosition( + CameraPosition position) { + return PlatformCameraPosition( + bearing: position.bearing, + target: _platformLatLngFromLatLng(position.target), + tilt: position.tilt, + zoom: position.zoom); +} + +PlatformMapType _platformMapTypeFromMapTypeIndex(int index) { + // This is inherently fragile, but see comment in updateMapOptions. + return switch (index) { + 0 => PlatformMapType.none, + 1 => PlatformMapType.normal, + 2 => PlatformMapType.satellite, + 3 => PlatformMapType.terrain, + 4 => PlatformMapType.hybrid, + // For a new, unsupported type, just use normal. + _ => PlatformMapType.normal, }; } +PlatformLatLng _platformLatLngFromLatLngJson(Object latLngJson) { + // See `LatLng.toJson`. + final List list = (latLngJson as List).cast(); + return PlatformLatLng(latitude: list[0], longitude: list[1]); +} + +PlatformLatLngBounds? _platformLatLngBoundsFromLatLngBoundsJson( + Object? boundsJson) { + if (boundsJson == null) { + return null; + } + // See `LatLngBounds.toJson`. + final List boundsList = (boundsJson as List).cast(); + return PlatformLatLngBounds( + southwest: _platformLatLngFromLatLngJson(boundsList[0]), + northeast: _platformLatLngFromLatLngJson(boundsList[1])); +} + +PlatformCameraTargetBounds? + _platformCameraTargetBoundsFromCameraTargetBoundsJson(Object? targetJson) { + if (targetJson == null) { + return null; + } + // See `CameraTargetBounds.toJson`. + return PlatformCameraTargetBounds( + bounds: _platformLatLngBoundsFromLatLngBoundsJson( + (targetJson as List)[0])); +} + +PlatformZoomRange? _platformZoomRangeFromMinMaxZoomPreferenceJson( + Object? zoomPrefsJson) { + if (zoomPrefsJson == null) { + return null; + } + // See `MinMaxZoomPreference.toJson`. + final List minMaxZoom = + (zoomPrefsJson as List).cast(); + return PlatformZoomRange(min: minMaxZoom[0], max: minMaxZoom[1]); +} + /// Update specification for a set of [TileOverlay]s. // TODO(stuartmorgan): Fix the missing export of this class in the platform // interface, and remove this copy. diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/messages.g.dart b/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/messages.g.dart new file mode 100644 index 000000000000..699d9e4e44af --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/messages.g.dart @@ -0,0 +1,2355 @@ +// 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 (v22.4.2), 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 + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; + +import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/services.dart'; + +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); +} + +List wrapResponse( + {Object? result, PlatformException? error, bool empty = false}) { + if (empty) { + return []; + } + if (error == null) { + return [result]; + } + return [error.code, error.message, error.details]; +} + +/// Pigeon equivalent of MapType +enum PlatformMapType { + none, + normal, + satellite, + terrain, + hybrid, +} + +/// Pigeon representatation of a CameraPosition. +class PlatformCameraPosition { + PlatformCameraPosition({ + required this.bearing, + required this.target, + required this.tilt, + required this.zoom, + }); + + double bearing; + + PlatformLatLng target; + + double tilt; + + double zoom; + + Object encode() { + return [ + bearing, + target, + tilt, + zoom, + ]; + } + + static PlatformCameraPosition decode(Object result) { + result as List; + return PlatformCameraPosition( + bearing: result[0]! as double, + target: result[1]! as PlatformLatLng, + tilt: result[2]! as double, + zoom: result[3]! as double, + ); + } +} + +/// Pigeon representation of a CameraUpdate. +class PlatformCameraUpdate { + PlatformCameraUpdate({ + required this.json, + }); + + /// The update data, as JSON. This should only be set from + /// CameraUpdate.toJson, and the native code must interpret it according to the + /// internal implementation details of the CameraUpdate class. + Object json; + + Object encode() { + return [ + json, + ]; + } + + static PlatformCameraUpdate decode(Object result) { + result as List; + return PlatformCameraUpdate( + json: result[0]!, + ); + } +} + +/// Pigeon equivalent of the Circle class. +class PlatformCircle { + PlatformCircle({ + required this.json, + }); + + /// The circle data, as JSON. This should only be set from + /// Circle.toJson, and the native code must interpret it according to the + /// internal implementation details of that method. + Object json; + + Object encode() { + return [ + json, + ]; + } + + static PlatformCircle decode(Object result) { + result as List; + return PlatformCircle( + json: result[0]!, + ); + } +} + +/// Pigeon equivalent of the Heatmap class. +class PlatformHeatmap { + PlatformHeatmap({ + required this.json, + }); + + /// The heatmap data, as JSON. This should only be set from + /// Heatmap.toJson, and the native code must interpret it according to the + /// internal implementation details of that method. + Object json; + + Object encode() { + return [ + json, + ]; + } + + static PlatformHeatmap decode(Object result) { + result as List; + return PlatformHeatmap( + json: result[0]!, + ); + } +} + +/// Pigeon equivalent of Cluster. +class PlatformCluster { + PlatformCluster({ + required this.clusterManagerId, + required this.position, + required this.bounds, + required this.markerIds, + }); + + String clusterManagerId; + + PlatformLatLng position; + + PlatformLatLngBounds bounds; + + List markerIds; + + Object encode() { + return [ + clusterManagerId, + position, + bounds, + markerIds, + ]; + } + + static PlatformCluster decode(Object result) { + result as List; + return PlatformCluster( + clusterManagerId: result[0]! as String, + position: result[1]! as PlatformLatLng, + bounds: result[2]! as PlatformLatLngBounds, + markerIds: (result[3] as List?)!.cast(), + ); + } +} + +/// Pigeon equivalent of the ClusterManager class. +class PlatformClusterManager { + PlatformClusterManager({ + required this.identifier, + }); + + String identifier; + + Object encode() { + return [ + identifier, + ]; + } + + static PlatformClusterManager decode(Object result) { + result as List; + return PlatformClusterManager( + identifier: result[0]! as String, + ); + } +} + +/// Pigeon equivalent of the Marker class. +class PlatformMarker { + PlatformMarker({ + required this.json, + }); + + /// The marker data, as JSON. This should only be set from + /// Marker.toJson, and the native code must interpret it according to the + /// internal implementation details of that method. + Object json; + + Object encode() { + return [ + json, + ]; + } + + static PlatformMarker decode(Object result) { + result as List; + return PlatformMarker( + json: result[0]!, + ); + } +} + +/// Pigeon equivalent of the Polygon class. +class PlatformPolygon { + PlatformPolygon({ + required this.json, + }); + + /// The polygon data, as JSON. This should only be set from + /// Polygon.toJson, and the native code must interpret it according to the + /// internal implementation details of that method. + Object json; + + Object encode() { + return [ + json, + ]; + } + + static PlatformPolygon decode(Object result) { + result as List; + return PlatformPolygon( + json: result[0]!, + ); + } +} + +/// Pigeon equivalent of the Polyline class. +class PlatformPolyline { + PlatformPolyline({ + required this.json, + }); + + /// The polyline data, as JSON. This should only be set from + /// Polyline.toJson, and the native code must interpret it according to the + /// internal implementation details of that method. + Object json; + + Object encode() { + return [ + json, + ]; + } + + static PlatformPolyline decode(Object result) { + result as List; + return PlatformPolyline( + json: result[0]!, + ); + } +} + +/// Pigeon equivalent of the Tile class. +class PlatformTile { + PlatformTile({ + required this.width, + required this.height, + this.data, + }); + + int width; + + int height; + + Uint8List? data; + + Object encode() { + return [ + width, + height, + data, + ]; + } + + static PlatformTile decode(Object result) { + result as List; + return PlatformTile( + width: result[0]! as int, + height: result[1]! as int, + data: result[2] as Uint8List?, + ); + } +} + +/// Pigeon equivalent of the TileOverlay class. +class PlatformTileOverlay { + PlatformTileOverlay({ + required this.json, + }); + + /// The tile overlay data, as JSON. This should only be set from + /// TileOverlay.toJson, and the native code must interpret it according to the + /// internal implementation details of that method. + Object json; + + Object encode() { + return [ + json, + ]; + } + + static PlatformTileOverlay decode(Object result) { + result as List; + return PlatformTileOverlay( + json: result[0]!, + ); + } +} + +/// Pigeon equivalent of Flutter's EdgeInsets. +class PlatformEdgeInsets { + PlatformEdgeInsets({ + required this.top, + required this.bottom, + required this.left, + required this.right, + }); + + double top; + + double bottom; + + double left; + + double right; + + Object encode() { + return [ + top, + bottom, + left, + right, + ]; + } + + static PlatformEdgeInsets decode(Object result) { + result as List; + return PlatformEdgeInsets( + top: result[0]! as double, + bottom: result[1]! as double, + left: result[2]! as double, + right: result[3]! as double, + ); + } +} + +/// Pigeon equivalent of LatLng. +class PlatformLatLng { + PlatformLatLng({ + required this.latitude, + required this.longitude, + }); + + double latitude; + + double longitude; + + Object encode() { + return [ + latitude, + longitude, + ]; + } + + static PlatformLatLng decode(Object result) { + result as List; + return PlatformLatLng( + latitude: result[0]! as double, + longitude: result[1]! as double, + ); + } +} + +/// Pigeon equivalent of LatLngBounds. +class PlatformLatLngBounds { + PlatformLatLngBounds({ + required this.northeast, + required this.southwest, + }); + + PlatformLatLng northeast; + + PlatformLatLng southwest; + + Object encode() { + return [ + northeast, + southwest, + ]; + } + + static PlatformLatLngBounds decode(Object result) { + result as List; + return PlatformLatLngBounds( + northeast: result[0]! as PlatformLatLng, + southwest: result[1]! as PlatformLatLng, + ); + } +} + +/// Pigeon equivalent of CameraTargetBounds. +/// +/// As with the Dart version, it exists to distinguish between not setting a +/// a target, and having an explicitly unbounded target (null [bounds]). +class PlatformCameraTargetBounds { + PlatformCameraTargetBounds({ + this.bounds, + }); + + PlatformLatLngBounds? bounds; + + Object encode() { + return [ + bounds, + ]; + } + + static PlatformCameraTargetBounds decode(Object result) { + result as List; + return PlatformCameraTargetBounds( + bounds: result[0] as PlatformLatLngBounds?, + ); + } +} + +/// Information passed to the platform view creation. +class PlatformMapViewCreationParams { + PlatformMapViewCreationParams({ + required this.initialCameraPosition, + required this.mapConfiguration, + required this.initialCircles, + required this.initialMarkers, + required this.initialPolygons, + required this.initialPolylines, + required this.initialHeatmaps, + required this.initialTileOverlays, + required this.initialClusterManagers, + }); + + PlatformCameraPosition initialCameraPosition; + + PlatformMapConfiguration mapConfiguration; + + List initialCircles; + + List initialMarkers; + + List initialPolygons; + + List initialPolylines; + + List initialHeatmaps; + + List initialTileOverlays; + + List initialClusterManagers; + + Object encode() { + return [ + initialCameraPosition, + mapConfiguration, + initialCircles, + initialMarkers, + initialPolygons, + initialPolylines, + initialHeatmaps, + initialTileOverlays, + initialClusterManagers, + ]; + } + + static PlatformMapViewCreationParams decode(Object result) { + result as List; + return PlatformMapViewCreationParams( + initialCameraPosition: result[0]! as PlatformCameraPosition, + mapConfiguration: result[1]! as PlatformMapConfiguration, + initialCircles: (result[2] as List?)!.cast(), + initialMarkers: (result[3] as List?)!.cast(), + initialPolygons: (result[4] as List?)!.cast(), + initialPolylines: (result[5] as List?)!.cast(), + initialHeatmaps: (result[6] as List?)!.cast(), + initialTileOverlays: + (result[7] as List?)!.cast(), + initialClusterManagers: + (result[8] as List?)!.cast(), + ); + } +} + +/// Pigeon equivalent of MapConfiguration. +class PlatformMapConfiguration { + PlatformMapConfiguration({ + this.compassEnabled, + this.cameraTargetBounds, + this.mapType, + this.minMaxZoomPreference, + this.rotateGesturesEnabled, + this.scrollGesturesEnabled, + this.tiltGesturesEnabled, + this.trackCameraPosition, + this.zoomGesturesEnabled, + this.myLocationEnabled, + this.myLocationButtonEnabled, + this.padding, + this.indoorViewEnabled, + this.trafficEnabled, + this.buildingsEnabled, + this.cloudMapId, + this.style, + }); + + bool? compassEnabled; + + PlatformCameraTargetBounds? cameraTargetBounds; + + PlatformMapType? mapType; + + PlatformZoomRange? minMaxZoomPreference; + + bool? rotateGesturesEnabled; + + bool? scrollGesturesEnabled; + + bool? tiltGesturesEnabled; + + bool? trackCameraPosition; + + bool? zoomGesturesEnabled; + + bool? myLocationEnabled; + + bool? myLocationButtonEnabled; + + PlatformEdgeInsets? padding; + + bool? indoorViewEnabled; + + bool? trafficEnabled; + + bool? buildingsEnabled; + + String? cloudMapId; + + String? style; + + Object encode() { + return [ + compassEnabled, + cameraTargetBounds, + mapType, + minMaxZoomPreference, + rotateGesturesEnabled, + scrollGesturesEnabled, + tiltGesturesEnabled, + trackCameraPosition, + zoomGesturesEnabled, + myLocationEnabled, + myLocationButtonEnabled, + padding, + indoorViewEnabled, + trafficEnabled, + buildingsEnabled, + cloudMapId, + style, + ]; + } + + static PlatformMapConfiguration decode(Object result) { + result as List; + return PlatformMapConfiguration( + compassEnabled: result[0] as bool?, + cameraTargetBounds: result[1] as PlatformCameraTargetBounds?, + mapType: result[2] as PlatformMapType?, + minMaxZoomPreference: result[3] as PlatformZoomRange?, + rotateGesturesEnabled: result[4] as bool?, + scrollGesturesEnabled: result[5] as bool?, + tiltGesturesEnabled: result[6] as bool?, + trackCameraPosition: result[7] as bool?, + zoomGesturesEnabled: result[8] as bool?, + myLocationEnabled: result[9] as bool?, + myLocationButtonEnabled: result[10] as bool?, + padding: result[11] as PlatformEdgeInsets?, + indoorViewEnabled: result[12] as bool?, + trafficEnabled: result[13] as bool?, + buildingsEnabled: result[14] as bool?, + cloudMapId: result[15] as String?, + style: result[16] as String?, + ); + } +} + +/// Pigeon representation of an x,y coordinate. +class PlatformPoint { + PlatformPoint({ + required this.x, + required this.y, + }); + + double x; + + double y; + + Object encode() { + return [ + x, + y, + ]; + } + + static PlatformPoint decode(Object result) { + result as List; + return PlatformPoint( + x: result[0]! as double, + y: result[1]! as double, + ); + } +} + +/// Pigeon equivalent of GMSTileLayer properties. +class PlatformTileLayer { + PlatformTileLayer({ + required this.visible, + required this.fadeIn, + required this.opacity, + required this.zIndex, + }); + + bool visible; + + bool fadeIn; + + double opacity; + + int zIndex; + + Object encode() { + return [ + visible, + fadeIn, + opacity, + zIndex, + ]; + } + + static PlatformTileLayer decode(Object result) { + result as List; + return PlatformTileLayer( + visible: result[0]! as bool, + fadeIn: result[1]! as bool, + opacity: result[2]! as double, + zIndex: result[3]! as int, + ); + } +} + +/// Pigeon equivalent of MinMaxZoomPreference. +class PlatformZoomRange { + PlatformZoomRange({ + this.min, + this.max, + }); + + double? min; + + double? max; + + Object encode() { + return [ + min, + max, + ]; + } + + static PlatformZoomRange decode(Object result) { + result as List; + return PlatformZoomRange( + min: result[0] as double?, + max: result[1] as double?, + ); + } +} + +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is PlatformMapType) { + buffer.putUint8(129); + writeValue(buffer, value.index); + } else if (value is PlatformCameraPosition) { + buffer.putUint8(130); + writeValue(buffer, value.encode()); + } else if (value is PlatformCameraUpdate) { + buffer.putUint8(131); + writeValue(buffer, value.encode()); + } else if (value is PlatformCircle) { + buffer.putUint8(132); + writeValue(buffer, value.encode()); + } else if (value is PlatformHeatmap) { + buffer.putUint8(133); + writeValue(buffer, value.encode()); + } else if (value is PlatformCluster) { + buffer.putUint8(134); + writeValue(buffer, value.encode()); + } else if (value is PlatformClusterManager) { + buffer.putUint8(135); + writeValue(buffer, value.encode()); + } else if (value is PlatformMarker) { + buffer.putUint8(136); + writeValue(buffer, value.encode()); + } else if (value is PlatformPolygon) { + buffer.putUint8(137); + writeValue(buffer, value.encode()); + } else if (value is PlatformPolyline) { + buffer.putUint8(138); + writeValue(buffer, value.encode()); + } else if (value is PlatformTile) { + buffer.putUint8(139); + writeValue(buffer, value.encode()); + } else if (value is PlatformTileOverlay) { + buffer.putUint8(140); + writeValue(buffer, value.encode()); + } else if (value is PlatformEdgeInsets) { + buffer.putUint8(141); + writeValue(buffer, value.encode()); + } else if (value is PlatformLatLng) { + buffer.putUint8(142); + writeValue(buffer, value.encode()); + } else if (value is PlatformLatLngBounds) { + buffer.putUint8(143); + writeValue(buffer, value.encode()); + } else if (value is PlatformCameraTargetBounds) { + buffer.putUint8(144); + writeValue(buffer, value.encode()); + } else if (value is PlatformMapViewCreationParams) { + buffer.putUint8(145); + writeValue(buffer, value.encode()); + } else if (value is PlatformMapConfiguration) { + buffer.putUint8(146); + writeValue(buffer, value.encode()); + } else if (value is PlatformPoint) { + buffer.putUint8(147); + writeValue(buffer, value.encode()); + } else if (value is PlatformTileLayer) { + buffer.putUint8(148); + writeValue(buffer, value.encode()); + } else if (value is PlatformZoomRange) { + buffer.putUint8(149); + writeValue(buffer, value.encode()); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 129: + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformMapType.values[value]; + case 130: + return PlatformCameraPosition.decode(readValue(buffer)!); + case 131: + return PlatformCameraUpdate.decode(readValue(buffer)!); + case 132: + return PlatformCircle.decode(readValue(buffer)!); + case 133: + return PlatformHeatmap.decode(readValue(buffer)!); + case 134: + return PlatformCluster.decode(readValue(buffer)!); + case 135: + return PlatformClusterManager.decode(readValue(buffer)!); + case 136: + return PlatformMarker.decode(readValue(buffer)!); + case 137: + return PlatformPolygon.decode(readValue(buffer)!); + case 138: + return PlatformPolyline.decode(readValue(buffer)!); + case 139: + return PlatformTile.decode(readValue(buffer)!); + case 140: + return PlatformTileOverlay.decode(readValue(buffer)!); + case 141: + return PlatformEdgeInsets.decode(readValue(buffer)!); + case 142: + return PlatformLatLng.decode(readValue(buffer)!); + case 143: + return PlatformLatLngBounds.decode(readValue(buffer)!); + case 144: + return PlatformCameraTargetBounds.decode(readValue(buffer)!); + case 145: + return PlatformMapViewCreationParams.decode(readValue(buffer)!); + case 146: + return PlatformMapConfiguration.decode(readValue(buffer)!); + case 147: + return PlatformPoint.decode(readValue(buffer)!); + case 148: + return PlatformTileLayer.decode(readValue(buffer)!); + case 149: + return PlatformZoomRange.decode(readValue(buffer)!); + default: + return super.readValueOfType(type, buffer); + } + } +} + +/// Interface for non-test interactions with the native SDK. +/// +/// For test-only state queries, see [MapsInspectorApi]. +class MapsApi { + /// Constructor for [MapsApi]. 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. + MapsApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String pigeonVar_messageChannelSuffix; + + /// Returns once the map instance is available. + Future waitForMap() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.waitForMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Updates the map's configuration options. + /// + /// Only non-null configuration values will result in updates; options with + /// null values will remain unchanged. + Future updateMapConfiguration( + PlatformMapConfiguration configuration) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.updateMapConfiguration$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([configuration]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Updates the set of circles on the map. + Future updateCircles(List toAdd, + List toChange, List idsToRemove) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.updateCircles$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([toAdd, toChange, idsToRemove]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Updates the set of heatmaps on the map. + Future updateHeatmaps(List toAdd, + List toChange, List idsToRemove) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.updateHeatmaps$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([toAdd, toChange, idsToRemove]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Updates the set of custer managers for clusters on the map. + Future updateClusterManagers( + List toAdd, List idsToRemove) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.updateClusterManagers$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([toAdd, idsToRemove]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Updates the set of markers on the map. + Future updateMarkers(List toAdd, + List toChange, List idsToRemove) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.updateMarkers$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([toAdd, toChange, idsToRemove]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Updates the set of polygonss on the map. + Future updatePolygons(List toAdd, + List toChange, List idsToRemove) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.updatePolygons$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([toAdd, toChange, idsToRemove]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Updates the set of polylines on the map. + Future updatePolylines(List toAdd, + List toChange, List idsToRemove) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.updatePolylines$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([toAdd, toChange, idsToRemove]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Updates the set of tile overlays on the map. + Future updateTileOverlays(List toAdd, + List toChange, List idsToRemove) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.updateTileOverlays$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([toAdd, toChange, idsToRemove]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Gets the screen coordinate for the given map location. + Future getScreenCoordinate(PlatformLatLng latLng) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.getScreenCoordinate$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([latLng]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as PlatformPoint?)!; + } + } + + /// Gets the map location for the given screen coordinate. + Future getLatLng(PlatformPoint screenCoordinate) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.getLatLng$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([screenCoordinate]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as PlatformLatLng?)!; + } + } + + /// Gets the map region currently displayed on the map. + Future getVisibleRegion() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.getVisibleRegion$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as PlatformLatLngBounds?)!; + } + } + + /// Moves the camera according to [cameraUpdate] immediately, with no + /// animation. + Future moveCamera(PlatformCameraUpdate cameraUpdate) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.moveCamera$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([cameraUpdate]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Moves the camera according to [cameraUpdate], animating the update. + Future animateCamera(PlatformCameraUpdate cameraUpdate) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.animateCamera$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([cameraUpdate]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Gets the current map zoom level. + Future getZoomLevel() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.getZoomLevel$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as double?)!; + } + } + + /// Show the info window for the marker with the given ID. + Future showInfoWindow(String markerId) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.showInfoWindow$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([markerId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Hide the info window for the marker with the given ID. + Future hideInfoWindow(String markerId) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.hideInfoWindow$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([markerId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Returns true if the marker with the given ID is currently displaying its + /// info window. + Future isInfoWindowShown(String markerId) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.isInfoWindowShown$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([markerId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as bool?)!; + } + } + + /// Sets the style to the given map style string, where an empty string + /// indicates that the style should be cleared. + /// + /// If there was an error setting the style, such as an invalid style string, + /// returns the error message. + Future setStyle(String style) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.setStyle$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([style]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as String?); + } + } + + /// Returns the error string from the last attempt to set the map style, if + /// any. + /// + /// This allows checking asynchronously for initial style failures, as there + /// is no way to return failures from map initialization. + Future getLastStyleError() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.getLastStyleError$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as String?); + } + } + + /// Clears the cache of tiles previously requseted from the tile provider. + Future clearTileCache(String tileOverlayId) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.clearTileCache$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([tileOverlayId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Takes a snapshot of the map and returns its image data. + Future takeSnapshot() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsApi.takeSnapshot$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as Uint8List?); + } + } +} + +/// Interface for calls from the native SDK to Dart. +abstract class MapsCallbackApi { + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + /// Called when the map camera starts moving. + void onCameraMoveStarted(); + + /// Called when the map camera moves. + void onCameraMove(PlatformCameraPosition cameraPosition); + + /// Called when the map camera stops moving. + void onCameraIdle(); + + /// Called when the map, not a specifc map object, is tapped. + void onTap(PlatformLatLng position); + + /// Called when the map, not a specifc map object, is long pressed. + void onLongPress(PlatformLatLng position); + + /// Called when a marker is tapped. + void onMarkerTap(String markerId); + + /// Called when a marker drag starts. + void onMarkerDragStart(String markerId, PlatformLatLng position); + + /// Called when a marker drag updates. + void onMarkerDrag(String markerId, PlatformLatLng position); + + /// Called when a marker drag ends. + void onMarkerDragEnd(String markerId, PlatformLatLng position); + + /// Called when a marker's info window is tapped. + void onInfoWindowTap(String markerId); + + /// Called when a circle is tapped. + void onCircleTap(String circleId); + + /// Called when a marker cluster is tapped. + void onClusterTap(PlatformCluster cluster); + + /// Called when a polygon is tapped. + void onPolygonTap(String polygonId); + + /// Called when a polyline is tapped. + void onPolylineTap(String polylineId); + + /// Called to get data for a map tile. + Future getTileOverlayTile( + String tileOverlayId, PlatformPoint location, int zoom); + + static void setUp( + MapsCallbackApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onCameraMoveStarted$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + try { + api.onCameraMoveStarted(); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onCameraMove$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onCameraMove was null.'); + final List args = (message as List?)!; + final PlatformCameraPosition? arg_cameraPosition = + (args[0] as PlatformCameraPosition?); + assert(arg_cameraPosition != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onCameraMove was null, expected non-null PlatformCameraPosition.'); + try { + api.onCameraMove(arg_cameraPosition!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onCameraIdle$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + try { + api.onCameraIdle(); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onTap$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onTap was null.'); + final List args = (message as List?)!; + final PlatformLatLng? arg_position = (args[0] as PlatformLatLng?); + assert(arg_position != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onTap was null, expected non-null PlatformLatLng.'); + try { + api.onTap(arg_position!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onLongPress$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onLongPress was null.'); + final List args = (message as List?)!; + final PlatformLatLng? arg_position = (args[0] as PlatformLatLng?); + assert(arg_position != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onLongPress was null, expected non-null PlatformLatLng.'); + try { + api.onLongPress(arg_position!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onMarkerTap$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onMarkerTap was null.'); + final List args = (message as List?)!; + final String? arg_markerId = (args[0] as String?); + assert(arg_markerId != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onMarkerTap was null, expected non-null String.'); + try { + api.onMarkerTap(arg_markerId!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onMarkerDragStart$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onMarkerDragStart was null.'); + final List args = (message as List?)!; + final String? arg_markerId = (args[0] as String?); + assert(arg_markerId != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onMarkerDragStart was null, expected non-null String.'); + final PlatformLatLng? arg_position = (args[1] as PlatformLatLng?); + assert(arg_position != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onMarkerDragStart was null, expected non-null PlatformLatLng.'); + try { + api.onMarkerDragStart(arg_markerId!, arg_position!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onMarkerDrag$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onMarkerDrag was null.'); + final List args = (message as List?)!; + final String? arg_markerId = (args[0] as String?); + assert(arg_markerId != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onMarkerDrag was null, expected non-null String.'); + final PlatformLatLng? arg_position = (args[1] as PlatformLatLng?); + assert(arg_position != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onMarkerDrag was null, expected non-null PlatformLatLng.'); + try { + api.onMarkerDrag(arg_markerId!, arg_position!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onMarkerDragEnd$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onMarkerDragEnd was null.'); + final List args = (message as List?)!; + final String? arg_markerId = (args[0] as String?); + assert(arg_markerId != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onMarkerDragEnd was null, expected non-null String.'); + final PlatformLatLng? arg_position = (args[1] as PlatformLatLng?); + assert(arg_position != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onMarkerDragEnd was null, expected non-null PlatformLatLng.'); + try { + api.onMarkerDragEnd(arg_markerId!, arg_position!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onInfoWindowTap$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onInfoWindowTap was null.'); + final List args = (message as List?)!; + final String? arg_markerId = (args[0] as String?); + assert(arg_markerId != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onInfoWindowTap was null, expected non-null String.'); + try { + api.onInfoWindowTap(arg_markerId!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onCircleTap$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onCircleTap was null.'); + final List args = (message as List?)!; + final String? arg_circleId = (args[0] as String?); + assert(arg_circleId != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onCircleTap was null, expected non-null String.'); + try { + api.onCircleTap(arg_circleId!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onClusterTap$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onClusterTap was null.'); + final List args = (message as List?)!; + final PlatformCluster? arg_cluster = (args[0] as PlatformCluster?); + assert(arg_cluster != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onClusterTap was null, expected non-null PlatformCluster.'); + try { + api.onClusterTap(arg_cluster!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onPolygonTap$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onPolygonTap was null.'); + final List args = (message as List?)!; + final String? arg_polygonId = (args[0] as String?); + assert(arg_polygonId != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onPolygonTap was null, expected non-null String.'); + try { + api.onPolygonTap(arg_polygonId!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onPolylineTap$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onPolylineTap was null.'); + final List args = (message as List?)!; + final String? arg_polylineId = (args[0] as String?); + assert(arg_polylineId != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.onPolylineTap was null, expected non-null String.'); + try { + api.onPolylineTap(arg_polylineId!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.getTileOverlayTile$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.getTileOverlayTile was null.'); + final List args = (message as List?)!; + final String? arg_tileOverlayId = (args[0] as String?); + assert(arg_tileOverlayId != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.getTileOverlayTile was null, expected non-null String.'); + final PlatformPoint? arg_location = (args[1] as PlatformPoint?); + assert(arg_location != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.getTileOverlayTile was null, expected non-null PlatformPoint.'); + final int? arg_zoom = (args[2] as int?); + assert(arg_zoom != null, + 'Argument for dev.flutter.pigeon.google_maps_flutter_ios.MapsCallbackApi.getTileOverlayTile was null, expected non-null int.'); + try { + final PlatformTile output = await api.getTileOverlayTile( + arg_tileOverlayId!, arg_location!, arg_zoom!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } +} + +/// Dummy interface to force generation of the platform view creation params, +/// which are not used in any Pigeon calls, only the platform view creation +/// call made internally by Flutter. +class MapsPlatformViewApi { + /// Constructor for [MapsPlatformViewApi]. 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. + MapsPlatformViewApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String pigeonVar_messageChannelSuffix; + + Future createView(PlatformMapViewCreationParams? type) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsPlatformViewApi.createView$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([type]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } +} + +/// Inspector API only intended for use in integration tests. +class MapsInspectorApi { + /// Constructor for [MapsInspectorApi]. 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. + MapsInspectorApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String pigeonVar_messageChannelSuffix; + + Future areBuildingsEnabled() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsInspectorApi.areBuildingsEnabled$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as bool?)!; + } + } + + Future areRotateGesturesEnabled() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsInspectorApi.areRotateGesturesEnabled$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as bool?)!; + } + } + + Future areScrollGesturesEnabled() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsInspectorApi.areScrollGesturesEnabled$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as bool?)!; + } + } + + Future areTiltGesturesEnabled() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsInspectorApi.areTiltGesturesEnabled$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as bool?)!; + } + } + + Future areZoomGesturesEnabled() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsInspectorApi.areZoomGesturesEnabled$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as bool?)!; + } + } + + Future isCompassEnabled() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsInspectorApi.isCompassEnabled$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as bool?)!; + } + } + + Future isMyLocationButtonEnabled() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsInspectorApi.isMyLocationButtonEnabled$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as bool?)!; + } + } + + Future isTrafficEnabled() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsInspectorApi.isTrafficEnabled$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as bool?)!; + } + } + + Future getTileOverlayInfo(String tileOverlayId) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsInspectorApi.getTileOverlayInfo$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([tileOverlayId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as PlatformTileLayer?); + } + } + + Future getHeatmapInfo(String heatmapId) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsInspectorApi.getHeatmapInfo$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([heatmapId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as PlatformHeatmap?); + } + } + + Future getZoomRange() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsInspectorApi.getZoomRange$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as PlatformZoomRange?)!; + } + } + + Future> getClusters(String clusterManagerId) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsInspectorApi.getClusters$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([clusterManagerId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as List?)! + .cast(); + } + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/serialization.dart b/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/serialization.dart new file mode 100644 index 000000000000..8c80f19fb616 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/serialization.dart @@ -0,0 +1,125 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; + +// These constants must match the corresponding constants in FLTGoogleMapJSONConversions.m +const String _heatmapIdKey = 'heatmapId'; +const String _heatmapDataKey = 'data'; +const String _heatmapGradientKey = 'gradient'; +const String _heatmapOpacityKey = 'opacity'; +const String _heatmapRadiusKey = 'radius'; +const String _heatmapMinimumZoomIntensityKey = 'minimumZoomIntensity'; +const String _heatmapMaximumZoomIntensityKey = 'maximumZoomIntensity'; +const String _heatmapGradientColorsKey = 'colors'; +const String _heatmapGradientStartPointsKey = 'startPoints'; +const String _heatmapGradientColorMapSizeKey = 'colorMapSize'; + +void _addIfNonNull(Map map, String fieldName, Object? value) { + if (value != null) { + map[fieldName] = value; + } +} + +/// Serialize [Heatmap] +Object serializeHeatmap(Heatmap heatmap) { + final Map json = {}; + + _addIfNonNull(json, _heatmapIdKey, heatmap.heatmapId.value); + _addIfNonNull( + json, + _heatmapDataKey, + heatmap.data.map(serializeWeightedLatLng).toList(), + ); + + final HeatmapGradient? gradient = heatmap.gradient; + if (gradient != null) { + _addIfNonNull( + json, _heatmapGradientKey, serializeHeatmapGradient(gradient)); + } + _addIfNonNull(json, _heatmapOpacityKey, heatmap.opacity); + _addIfNonNull(json, _heatmapRadiusKey, heatmap.radius.radius); + _addIfNonNull( + json, _heatmapMinimumZoomIntensityKey, heatmap.minimumZoomIntensity); + _addIfNonNull( + json, _heatmapMaximumZoomIntensityKey, heatmap.maximumZoomIntensity); + + return json; +} + +/// Serialize [WeightedLatLng] +Object serializeWeightedLatLng(WeightedLatLng wll) { + return [serializeLatLng(wll.point), wll.weight]; +} + +/// Deserialize [WeightedLatLng] +WeightedLatLng? deserializeWeightedLatLng(Object? json) { + if (json == null) { + return null; + } + assert(json is List && json.length == 2); + final List list = json as List; + final LatLng latLng = deserializeLatLng(list[0])!; + return WeightedLatLng(latLng, weight: list[1] as double); +} + +/// Serialize [LatLng] +Object serializeLatLng(LatLng latLng) { + return [latLng.latitude, latLng.longitude]; +} + +/// Deserialize [LatLng] +LatLng? deserializeLatLng(Object? json) { + if (json == null) { + return null; + } + assert(json is List && json.length == 2); + final List list = json as List; + return LatLng(list[0]! as double, list[1]! as double); +} + +/// Serialize [HeatmapGradient] +Object serializeHeatmapGradient(HeatmapGradient gradient) { + final Map json = {}; + + _addIfNonNull( + json, + _heatmapGradientColorsKey, + gradient.colors.map((HeatmapGradientColor e) => e.color.value).toList(), + ); + _addIfNonNull( + json, + _heatmapGradientStartPointsKey, + gradient.colors.map((HeatmapGradientColor e) => e.startPoint).toList(), + ); + _addIfNonNull(json, _heatmapGradientColorMapSizeKey, gradient.colorMapSize); + + return json; +} + +/// Deserialize [HeatmapGradient] +HeatmapGradient? deserializeHeatmapGradient(Object? json) { + if (json == null) { + return null; + } + assert(json is Map); + final Map map = (json as Map).cast(); + final List colors = (map[_heatmapGradientColorsKey]! as List) + .whereType() + .map((int e) => Color(e)) + .toList(); + final List startPoints = + (map[_heatmapGradientStartPointsKey]! as List) + .whereType() + .toList(); + final List gradientColors = []; + for (int i = 0; i < colors.length; i++) { + gradientColors.add(HeatmapGradientColor(colors[i], startPoints[i])); + } + return HeatmapGradient( + gradientColors, + colorMapSize: map[_heatmapGradientColorMapSizeKey] as int? ?? 256, + ); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/pigeons/copyright.txt b/packages/google_maps_flutter/google_maps_flutter_ios/pigeons/copyright.txt new file mode 100644 index 000000000000..1236b63caf3a --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/pigeons/copyright.txt @@ -0,0 +1,3 @@ +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. diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/pigeons/messages.dart b/packages/google_maps_flutter/google_maps_flutter_ios/pigeons/messages.dart new file mode 100644 index 000000000000..8cc612c684c7 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/pigeons/messages.dart @@ -0,0 +1,501 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:pigeon/pigeon.dart'; + +@ConfigurePigeon(PigeonOptions( + dartOut: 'lib/src/messages.g.dart', + objcHeaderOut: 'ios/Classes/messages.g.h', + objcSourceOut: 'ios/Classes/messages.g.m', + objcOptions: ObjcOptions(prefix: 'FGM'), + copyrightHeader: 'pigeons/copyright.txt', +)) + +/// Pigeon equivalent of MapType +enum PlatformMapType { + none, + normal, + satellite, + terrain, + hybrid, +} + +/// Pigeon representatation of a CameraPosition. +class PlatformCameraPosition { + PlatformCameraPosition({ + required this.bearing, + required this.target, + required this.tilt, + required this.zoom, + }); + + final double bearing; + final PlatformLatLng target; + final double tilt; + final double zoom; +} + +/// Pigeon representation of a CameraUpdate. +class PlatformCameraUpdate { + PlatformCameraUpdate(this.json); + + /// The update data, as JSON. This should only be set from + /// CameraUpdate.toJson, and the native code must interpret it according to the + /// internal implementation details of the CameraUpdate class. + // TODO(stuartmorgan): Update the google_maps_platform_interface CameraUpdate + // class to provide a structured representation of an update. Currently it + // uses JSON as its only state, so there is no way to preserve structure. + // This wrapper class exists as a placeholder for now to at least provide + // type safety in the top-level call's arguments. + final Object json; +} + +/// Pigeon equivalent of the Circle class. +class PlatformCircle { + PlatformCircle(this.json); + + /// The circle data, as JSON. This should only be set from + /// Circle.toJson, and the native code must interpret it according to the + /// internal implementation details of that method. + // TODO(stuartmorgan): Replace this with structured data. This exists only to + // allow incremental migration to Pigeon. + final Object json; +} + +/// Pigeon equivalent of the Heatmap class. +class PlatformHeatmap { + PlatformHeatmap(this.json); + + /// The heatmap data, as JSON. This should only be set from + /// Heatmap.toJson, and the native code must interpret it according to the + /// internal implementation details of that method. + // TODO(stuartmorgan): Replace this with structured data. This exists only to + // allow incremental migration to Pigeon. + final Object json; +} + +/// Pigeon equivalent of Cluster. +class PlatformCluster { + PlatformCluster({ + required this.clusterManagerId, + required this.position, + required this.bounds, + required this.markerIds, + }); + + final String clusterManagerId; + final PlatformLatLng position; + final PlatformLatLngBounds bounds; + final List markerIds; +} + +/// Pigeon equivalent of the ClusterManager class. +class PlatformClusterManager { + PlatformClusterManager({required this.identifier}); + + final String identifier; +} + +/// Pigeon equivalent of the Marker class. +class PlatformMarker { + PlatformMarker(this.json); + + /// The marker data, as JSON. This should only be set from + /// Marker.toJson, and the native code must interpret it according to the + /// internal implementation details of that method. + // TODO(stuartmorgan): Replace this with structured data. This exists only to + // allow incremental migration to Pigeon. + final Object json; +} + +/// Pigeon equivalent of the Polygon class. +class PlatformPolygon { + PlatformPolygon(this.json); + + /// The polygon data, as JSON. This should only be set from + /// Polygon.toJson, and the native code must interpret it according to the + /// internal implementation details of that method. + // TODO(stuartmorgan): Replace this with structured data. This exists only to + // allow incremental migration to Pigeon. + final Object json; +} + +/// Pigeon equivalent of the Polyline class. +class PlatformPolyline { + PlatformPolyline(this.json); + + /// The polyline data, as JSON. This should only be set from + /// Polyline.toJson, and the native code must interpret it according to the + /// internal implementation details of that method. + // TODO(stuartmorgan): Replace this with structured data. This exists only to + // allow incremental migration to Pigeon. + final Object json; +} + +/// Pigeon equivalent of the Tile class. +class PlatformTile { + PlatformTile({required this.width, required this.height, required this.data}); + + final int width; + final int height; + final Uint8List? data; +} + +/// Pigeon equivalent of the TileOverlay class. +class PlatformTileOverlay { + PlatformTileOverlay(this.json); + + /// The tile overlay data, as JSON. This should only be set from + /// TileOverlay.toJson, and the native code must interpret it according to the + /// internal implementation details of that method. + // TODO(stuartmorgan): Replace this with structured data. This exists only to + // allow incremental migration to Pigeon. + final Object json; +} + +/// Pigeon equivalent of Flutter's EdgeInsets. +class PlatformEdgeInsets { + PlatformEdgeInsets({ + required this.top, + required this.bottom, + required this.left, + required this.right, + }); + + final double top; + final double bottom; + final double left; + final double right; +} + +/// Pigeon equivalent of LatLng. +class PlatformLatLng { + PlatformLatLng({required this.latitude, required this.longitude}); + + final double latitude; + final double longitude; +} + +/// Pigeon equivalent of LatLngBounds. +class PlatformLatLngBounds { + PlatformLatLngBounds({required this.northeast, required this.southwest}); + + final PlatformLatLng northeast; + final PlatformLatLng southwest; +} + +/// Pigeon equivalent of CameraTargetBounds. +/// +/// As with the Dart version, it exists to distinguish between not setting a +/// a target, and having an explicitly unbounded target (null [bounds]). +class PlatformCameraTargetBounds { + PlatformCameraTargetBounds({required this.bounds}); + + final PlatformLatLngBounds? bounds; +} + +/// Information passed to the platform view creation. +class PlatformMapViewCreationParams { + PlatformMapViewCreationParams({ + required this.initialCameraPosition, + required this.mapConfiguration, + required this.initialCircles, + required this.initialMarkers, + required this.initialPolygons, + required this.initialPolylines, + required this.initialHeatmaps, + required this.initialTileOverlays, + required this.initialClusterManagers, + }); + + final PlatformCameraPosition initialCameraPosition; + final PlatformMapConfiguration mapConfiguration; + final List initialCircles; + final List initialMarkers; + final List initialPolygons; + final List initialPolylines; + final List initialHeatmaps; + final List initialTileOverlays; + final List initialClusterManagers; +} + +/// Pigeon equivalent of MapConfiguration. +class PlatformMapConfiguration { + PlatformMapConfiguration({ + required this.compassEnabled, + required this.cameraTargetBounds, + required this.mapType, + required this.minMaxZoomPreference, + required this.rotateGesturesEnabled, + required this.scrollGesturesEnabled, + required this.tiltGesturesEnabled, + required this.trackCameraPosition, + required this.zoomGesturesEnabled, + required this.myLocationEnabled, + required this.myLocationButtonEnabled, + required this.padding, + required this.indoorViewEnabled, + required this.trafficEnabled, + required this.buildingsEnabled, + required this.cloudMapId, + required this.style, + }); + + final bool? compassEnabled; + final PlatformCameraTargetBounds? cameraTargetBounds; + final PlatformMapType? mapType; + final PlatformZoomRange? minMaxZoomPreference; + final bool? rotateGesturesEnabled; + final bool? scrollGesturesEnabled; + final bool? tiltGesturesEnabled; + final bool? trackCameraPosition; + final bool? zoomGesturesEnabled; + final bool? myLocationEnabled; + final bool? myLocationButtonEnabled; + final PlatformEdgeInsets? padding; + final bool? indoorViewEnabled; + final bool? trafficEnabled; + final bool? buildingsEnabled; + final String? cloudMapId; + final String? style; +} + +/// Pigeon representation of an x,y coordinate. +class PlatformPoint { + PlatformPoint({required this.x, required this.y}); + + final double x; + final double y; +} + +/// Pigeon equivalent of GMSTileLayer properties. +class PlatformTileLayer { + PlatformTileLayer({ + required this.visible, + required this.fadeIn, + required this.opacity, + required this.zIndex, + }); + + final bool visible; + final bool fadeIn; + final double opacity; + final int zIndex; +} + +/// Pigeon equivalent of MinMaxZoomPreference. +class PlatformZoomRange { + PlatformZoomRange({required this.min, required this.max}); + + final double? min; + final double? max; +} + +/// Interface for non-test interactions with the native SDK. +/// +/// For test-only state queries, see [MapsInspectorApi]. +@HostApi() +abstract class MapsApi { + /// Returns once the map instance is available. + void waitForMap(); + + /// Updates the map's configuration options. + /// + /// Only non-null configuration values will result in updates; options with + /// null values will remain unchanged. + @ObjCSelector('updateWithMapConfiguration:') + void updateMapConfiguration(PlatformMapConfiguration configuration); + + /// Updates the set of circles on the map. + @ObjCSelector('updateCirclesByAdding:changing:removing:') + void updateCircles(List toAdd, List toChange, + List idsToRemove); + + /// Updates the set of heatmaps on the map. + @ObjCSelector('updateHeatmapsByAdding:changing:removing:') + void updateHeatmaps(List toAdd, + List toChange, List idsToRemove); + + /// Updates the set of custer managers for clusters on the map. + @ObjCSelector('updateClusterManagersByAdding:removing:') + void updateClusterManagers( + List toAdd, List idsToRemove); + + /// Updates the set of markers on the map. + @ObjCSelector('updateMarkersByAdding:changing:removing:') + void updateMarkers(List toAdd, List toChange, + List idsToRemove); + + /// Updates the set of polygonss on the map. + @ObjCSelector('updatePolygonsByAdding:changing:removing:') + void updatePolygons(List toAdd, + List toChange, List idsToRemove); + + /// Updates the set of polylines on the map. + @ObjCSelector('updatePolylinesByAdding:changing:removing:') + void updatePolylines(List toAdd, + List toChange, List idsToRemove); + + /// Updates the set of tile overlays on the map. + @ObjCSelector('updateTileOverlaysByAdding:changing:removing:') + void updateTileOverlays(List toAdd, + List toChange, List idsToRemove); + + /// Gets the screen coordinate for the given map location. + @ObjCSelector('screenCoordinatesForLatLng:') + PlatformPoint getScreenCoordinate(PlatformLatLng latLng); + + /// Gets the map location for the given screen coordinate. + @ObjCSelector('latLngForScreenCoordinate:') + PlatformLatLng getLatLng(PlatformPoint screenCoordinate); + + /// Gets the map region currently displayed on the map. + @ObjCSelector('visibleMapRegion') + PlatformLatLngBounds getVisibleRegion(); + + /// Moves the camera according to [cameraUpdate] immediately, with no + /// animation. + @ObjCSelector('moveCameraWithUpdate:') + void moveCamera(PlatformCameraUpdate cameraUpdate); + + /// Moves the camera according to [cameraUpdate], animating the update. + @ObjCSelector('animateCameraWithUpdate:') + void animateCamera(PlatformCameraUpdate cameraUpdate); + + /// Gets the current map zoom level. + @ObjCSelector('currentZoomLevel') + double getZoomLevel(); + + /// Show the info window for the marker with the given ID. + @ObjCSelector('showInfoWindowForMarkerWithIdentifier:') + void showInfoWindow(String markerId); + + /// Hide the info window for the marker with the given ID. + @ObjCSelector('hideInfoWindowForMarkerWithIdentifier:') + void hideInfoWindow(String markerId); + + /// Returns true if the marker with the given ID is currently displaying its + /// info window. + @ObjCSelector('isShowingInfoWindowForMarkerWithIdentifier:') + bool isInfoWindowShown(String markerId); + + /// Sets the style to the given map style string, where an empty string + /// indicates that the style should be cleared. + /// + /// If there was an error setting the style, such as an invalid style string, + /// returns the error message. + @ObjCSelector('setStyle:') + String? setStyle(String style); + + /// Returns the error string from the last attempt to set the map style, if + /// any. + /// + /// This allows checking asynchronously for initial style failures, as there + /// is no way to return failures from map initialization. + @ObjCSelector('lastStyleError') + String? getLastStyleError(); + + /// Clears the cache of tiles previously requseted from the tile provider. + @ObjCSelector('clearTileCacheForOverlayWithIdentifier:') + void clearTileCache(String tileOverlayId); + + /// Takes a snapshot of the map and returns its image data. + Uint8List? takeSnapshot(); +} + +/// Interface for calls from the native SDK to Dart. +@FlutterApi() +abstract class MapsCallbackApi { + /// Called when the map camera starts moving. + @ObjCSelector('didStartCameraMoveWithCompletion') + void onCameraMoveStarted(); + + /// Called when the map camera moves. + @ObjCSelector('didMoveCameraToPosition:') + void onCameraMove(PlatformCameraPosition cameraPosition); + + /// Called when the map camera stops moving. + @ObjCSelector('didIdleCameraWithCompletion') + void onCameraIdle(); + + /// Called when the map, not a specifc map object, is tapped. + @ObjCSelector('didTapAtPosition:') + void onTap(PlatformLatLng position); + + /// Called when the map, not a specifc map object, is long pressed. + @ObjCSelector('didLongPressAtPosition:') + void onLongPress(PlatformLatLng position); + + /// Called when a marker is tapped. + @ObjCSelector('didTapMarkerWithIdentifier:') + void onMarkerTap(String markerId); + + /// Called when a marker drag starts. + @ObjCSelector('didStartDragForMarkerWithIdentifier:atPosition:') + void onMarkerDragStart(String markerId, PlatformLatLng position); + + /// Called when a marker drag updates. + @ObjCSelector('didDragMarkerWithIdentifier:atPosition:') + void onMarkerDrag(String markerId, PlatformLatLng position); + + /// Called when a marker drag ends. + @ObjCSelector('didEndDragForMarkerWithIdentifier:atPosition:') + void onMarkerDragEnd(String markerId, PlatformLatLng position); + + /// Called when a marker's info window is tapped. + @ObjCSelector('didTapInfoWindowOfMarkerWithIdentifier:') + void onInfoWindowTap(String markerId); + + /// Called when a circle is tapped. + @ObjCSelector('didTapCircleWithIdentifier:') + void onCircleTap(String circleId); + + /// Called when a marker cluster is tapped. + @ObjCSelector('didTapCluster:') + void onClusterTap(PlatformCluster cluster); + + /// Called when a polygon is tapped. + @ObjCSelector('didTapPolygonWithIdentifier:') + void onPolygonTap(String polygonId); + + /// Called when a polyline is tapped. + @ObjCSelector('didTapPolylineWithIdentifier:') + void onPolylineTap(String polylineId); + + /// Called to get data for a map tile. + @async + @ObjCSelector('tileWithOverlayIdentifier:location:zoom:') + PlatformTile getTileOverlayTile( + String tileOverlayId, PlatformPoint location, int zoom); +} + +/// Dummy interface to force generation of the platform view creation params, +/// which are not used in any Pigeon calls, only the platform view creation +/// call made internally by Flutter. +@HostApi() +abstract class MapsPlatformViewApi { + // This is never actually called. + void createView(PlatformMapViewCreationParams? type); +} + +/// Inspector API only intended for use in integration tests. +@HostApi() +abstract class MapsInspectorApi { + bool areBuildingsEnabled(); + bool areRotateGesturesEnabled(); + bool areScrollGesturesEnabled(); + bool areTiltGesturesEnabled(); + bool areZoomGesturesEnabled(); + bool isCompassEnabled(); + bool isMyLocationButtonEnabled(); + bool isTrafficEnabled(); + @ObjCSelector('tileOverlayWithIdentifier:') + PlatformTileLayer? getTileOverlayInfo(String tileOverlayId); + @ObjCSelector('heatmapWithIdentifier:') + PlatformHeatmap? getHeatmapInfo(String heatmapId); + @ObjCSelector('zoomRange') + PlatformZoomRange getZoomRange(); + @ObjCSelector('clustersWithIdentifier:') + List getClusters(String clusterManagerId); +} 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 e2dc69dd1bb7..9d727a0c46fa 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_ios/pubspec.yaml @@ -2,11 +2,11 @@ name: google_maps_flutter_ios description: iOS implementation of the google_maps_flutter plugin. repository: https://github.com/flutter/packages/tree/main/packages/google_maps_flutter/google_maps_flutter_ios issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22 -version: 2.8.0 +version: 2.13.1 environment: - sdk: ^3.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -19,13 +19,16 @@ flutter: dependencies: flutter: sdk: flutter - google_maps_flutter_platform_interface: ^2.7.0 + google_maps_flutter_platform_interface: ^2.9.0 stream_transform: ^2.0.0 dev_dependencies: async: ^2.5.0 + build_runner: ^2.4.11 flutter_test: sdk: flutter + mockito: ^5.4.4 + pigeon: ^22.4.2 plugin_platform_interface: ^2.1.7 topics: diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/test/google_maps_flutter_ios_test.dart b/packages/google_maps_flutter/google_maps_flutter_ios/test/google_maps_flutter_ios_test.dart index c9f21a79e4ce..7a2f26809dd3 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/test/google_maps_flutter_ios_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/test/google_maps_flutter_ios_test.dart @@ -8,104 +8,449 @@ import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:google_maps_flutter_ios/google_maps_flutter_ios.dart'; +import 'package:google_maps_flutter_ios/src/messages.g.dart'; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; +import 'google_maps_flutter_ios_test.mocks.dart'; + +@GenerateNiceMocks(>[MockSpec()]) void main() { TestWidgetsFlutterBinding.ensureInitialized(); - late List log; + (GoogleMapsFlutterIOS, MockMapsApi) setUpMockMap({required int mapId}) { + final MockMapsApi api = MockMapsApi(); + final GoogleMapsFlutterIOS maps = + GoogleMapsFlutterIOS(apiProvider: (_) => api); + maps.ensureApiInitialized(mapId); + return (maps, api); + } - setUp(() async { - log = []; + test('registers instance', () async { + GoogleMapsFlutterIOS.registerWith(); + expect(GoogleMapsFlutterPlatform.instance, isA()); }); - /// Initializes a map with the given ID and canned responses, logging all - /// calls to [log]. - void configureMockMap( - GoogleMapsFlutterIOS maps, { - required int mapId, - required Future? Function(MethodCall call) handler, - }) { - final MethodChannel channel = maps.ensureChannelInitialized(mapId); - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler( - channel, - (MethodCall methodCall) { - log.add(methodCall.method); - return handler(methodCall); - }, + test('init calls waitForMap', () async { + final MockMapsApi api = MockMapsApi(); + final GoogleMapsFlutterIOS maps = + GoogleMapsFlutterIOS(apiProvider: (_) => api); + + await maps.init(1); + + verify(api.waitForMap()); + }); + + test('getScreenCoordinate converts and passes values correctly', () async { + const int mapId = 1; + final (GoogleMapsFlutterIOS maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + // Arbitrary values that are all different from each other. + const LatLng latLng = LatLng(10, 20); + const ScreenCoordinate expectedCoord = ScreenCoordinate(x: 30, y: 40); + when(api.getScreenCoordinate(any)).thenAnswer((_) async => PlatformPoint( + x: expectedCoord.x.toDouble(), y: expectedCoord.y.toDouble())); + + final ScreenCoordinate coord = + await maps.getScreenCoordinate(latLng, mapId: mapId); + expect(coord, expectedCoord); + final VerificationResult verification = + verify(api.getScreenCoordinate(captureAny)); + final PlatformLatLng passedLatLng = + verification.captured[0] as PlatformLatLng; + expect(passedLatLng.latitude, latLng.latitude); + expect(passedLatLng.longitude, latLng.longitude); + }); + + test('getLatLng converts and passes values correctly', () async { + const int mapId = 1; + final (GoogleMapsFlutterIOS maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + // Arbitrary values that are all different from each other. + const LatLng expectedLatLng = LatLng(10, 20); + const ScreenCoordinate coord = ScreenCoordinate(x: 30, y: 40); + when(api.getLatLng(any)).thenAnswer((_) async => PlatformLatLng( + latitude: expectedLatLng.latitude, + longitude: expectedLatLng.longitude)); + + final LatLng latLng = await maps.getLatLng(coord, mapId: mapId); + expect(latLng, expectedLatLng); + final VerificationResult verification = verify(api.getLatLng(captureAny)); + final PlatformPoint passedCoord = verification.captured[0] as PlatformPoint; + expect(passedCoord.x, coord.x); + expect(passedCoord.y, coord.y); + }); + + test('getVisibleRegion converts and passes values correctly', () async { + const int mapId = 1; + final (GoogleMapsFlutterIOS maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + // Arbitrary values that are all different from each other. + final LatLngBounds expectedBounds = LatLngBounds( + southwest: const LatLng(10, 20), northeast: const LatLng(30, 40)); + when(api.getVisibleRegion()).thenAnswer((_) async => PlatformLatLngBounds( + southwest: PlatformLatLng( + latitude: expectedBounds.southwest.latitude, + longitude: expectedBounds.southwest.longitude), + northeast: PlatformLatLng( + latitude: expectedBounds.northeast.latitude, + longitude: expectedBounds.northeast.longitude))); + + final LatLngBounds bounds = await maps.getVisibleRegion(mapId: mapId); + expect(bounds, expectedBounds); + }); + + test('moveCamera calls through', () async { + const int mapId = 1; + final (GoogleMapsFlutterIOS maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + final CameraUpdate update = CameraUpdate.scrollBy(10, 20); + await maps.moveCamera(update, mapId: mapId); + + final VerificationResult verification = verify(api.moveCamera(captureAny)); + final PlatformCameraUpdate passedUpdate = + verification.captured[0] as PlatformCameraUpdate; + expect(passedUpdate.json, update.toJson()); + }); + + test('animateCamera calls through', () async { + const int mapId = 1; + final (GoogleMapsFlutterIOS maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + final CameraUpdate update = CameraUpdate.scrollBy(10, 20); + await maps.animateCamera(update, mapId: mapId); + + final VerificationResult verification = + verify(api.animateCamera(captureAny)); + final PlatformCameraUpdate passedUpdate = + verification.captured[0] as PlatformCameraUpdate; + expect(passedUpdate.json, update.toJson()); + }); + + test('getZoomLevel passes values correctly', () async { + const int mapId = 1; + final (GoogleMapsFlutterIOS maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + const double expectedZoom = 4.2; + when(api.getZoomLevel()).thenAnswer((_) async => expectedZoom); + + final double zoom = await maps.getZoomLevel(mapId: mapId); + expect(zoom, expectedZoom); + }); + + test('showInfoWindow calls through', () async { + const int mapId = 1; + final (GoogleMapsFlutterIOS maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + const String markedId = 'a_marker'; + await maps.showMarkerInfoWindow(const MarkerId(markedId), mapId: mapId); + + verify(api.showInfoWindow(markedId)); + }); + + test('hideInfoWindow calls through', () async { + const int mapId = 1; + final (GoogleMapsFlutterIOS maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + const String markedId = 'a_marker'; + await maps.hideMarkerInfoWindow(const MarkerId(markedId), mapId: mapId); + + verify(api.hideInfoWindow(markedId)); + }); + + test('isInfoWindowShown calls through', () async { + const int mapId = 1; + final (GoogleMapsFlutterIOS maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + const String markedId = 'a_marker'; + when(api.isInfoWindowShown(markedId)).thenAnswer((_) async => true); + + expect( + await maps.isMarkerInfoWindowShown(const MarkerId(markedId), + mapId: mapId), + true); + }); + + test('takeSnapshot calls through', () async { + const int mapId = 1; + final (GoogleMapsFlutterIOS maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + final Uint8List fakeSnapshot = Uint8List(10); + when(api.takeSnapshot()).thenAnswer((_) async => fakeSnapshot); + + expect(await maps.takeSnapshot(mapId: mapId), fakeSnapshot); + }); + + test('clearTileCache calls through', () async { + const int mapId = 1; + final (GoogleMapsFlutterIOS maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + const String tileOverlayId = 'overlay'; + await maps.clearTileCache(const TileOverlayId(tileOverlayId), mapId: mapId); + + verify(api.clearTileCache(tileOverlayId)); + }); + + test('updateMapConfiguration passes expected arguments', () async { + const int mapId = 1; + final (GoogleMapsFlutterIOS maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + // Set some arbitrary options. + final CameraTargetBounds cameraBounds = CameraTargetBounds(LatLngBounds( + southwest: const LatLng(10, 20), northeast: const LatLng(30, 40))); + final MapConfiguration config = MapConfiguration( + compassEnabled: true, + mapType: MapType.terrain, + cameraTargetBounds: cameraBounds, ); - } + await maps.updateMapConfiguration(config, mapId: mapId); - Future sendPlatformMessage( - int mapId, String method, Map data) async { - final ByteData byteData = - const StandardMethodCodec().encodeMethodCall(MethodCall(method, data)); - await TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .handlePlatformMessage('plugins.flutter.dev/google_maps_ios_$mapId', - byteData, (ByteData? data) {}); - } + final VerificationResult verification = + verify(api.updateMapConfiguration(captureAny)); + final PlatformMapConfiguration passedConfig = + verification.captured[0] as PlatformMapConfiguration; + // Each set option should be present. + expect(passedConfig.compassEnabled, true); + expect(passedConfig.mapType, PlatformMapType.terrain); + expect(passedConfig.cameraTargetBounds?.bounds?.northeast.latitude, + cameraBounds.bounds?.northeast.latitude); + expect(passedConfig.cameraTargetBounds?.bounds?.northeast.longitude, + cameraBounds.bounds?.northeast.longitude); + expect(passedConfig.cameraTargetBounds?.bounds?.southwest.latitude, + cameraBounds.bounds?.southwest.latitude); + expect(passedConfig.cameraTargetBounds?.bounds?.southwest.longitude, + cameraBounds.bounds?.southwest.longitude); + // Spot-check that unset options are not be present. + expect(passedConfig.myLocationEnabled, isNull); + expect(passedConfig.minMaxZoomPreference, isNull); + expect(passedConfig.padding, isNull); + }); - test('registers instance', () async { - GoogleMapsFlutterIOS.registerWith(); - expect(GoogleMapsFlutterPlatform.instance, isA()); + test('updateMapOptions passes expected arguments', () async { + const int mapId = 1; + final (GoogleMapsFlutterIOS maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + // Set some arbitrary options. + final CameraTargetBounds cameraBounds = CameraTargetBounds(LatLngBounds( + southwest: const LatLng(10, 20), northeast: const LatLng(30, 40))); + final Map config = { + 'compassEnabled': true, + 'mapType': MapType.terrain.index, + 'cameraTargetBounds': cameraBounds.toJson(), + }; + await maps.updateMapOptions(config, mapId: mapId); + + final VerificationResult verification = + verify(api.updateMapConfiguration(captureAny)); + final PlatformMapConfiguration passedConfig = + verification.captured[0] as PlatformMapConfiguration; + // Each set option should be present. + expect(passedConfig.compassEnabled, true); + expect(passedConfig.mapType, PlatformMapType.terrain); + expect(passedConfig.cameraTargetBounds?.bounds?.northeast.latitude, + cameraBounds.bounds?.northeast.latitude); + expect(passedConfig.cameraTargetBounds?.bounds?.northeast.longitude, + cameraBounds.bounds?.northeast.longitude); + expect(passedConfig.cameraTargetBounds?.bounds?.southwest.latitude, + cameraBounds.bounds?.southwest.latitude); + expect(passedConfig.cameraTargetBounds?.bounds?.southwest.longitude, + cameraBounds.bounds?.southwest.longitude); + // Spot-check that unset options are not be present. + expect(passedConfig.myLocationEnabled, isNull); + expect(passedConfig.minMaxZoomPreference, isNull); + expect(passedConfig.padding, isNull); }); - // Calls each method that uses invokeMethod with a return type other than - // void to ensure that the casting/nullability handling succeeds. - // - // TODO(stuartmorgan): Remove this once there is real test coverage of - // each method, since that would cover this issue. - test('non-void invokeMethods handle types correctly', () async { - const int mapId = 0; - final GoogleMapsFlutterIOS maps = GoogleMapsFlutterIOS(); - configureMockMap(maps, mapId: mapId, - handler: (MethodCall methodCall) async { - switch (methodCall.method) { - case 'map#getLatLng': - return [1.0, 2.0]; - case 'markers#isInfoWindowShown': - return true; - case 'map#getZoomLevel': - return 2.5; - case 'map#takeSnapshot': - return null; - } - }); - - await maps.getLatLng(const ScreenCoordinate(x: 0, y: 0), mapId: mapId); - await maps.isMarkerInfoWindowShown(const MarkerId(''), mapId: mapId); - await maps.getZoomLevel(mapId: mapId); - await maps.takeSnapshot(mapId: mapId); - // Check that all the invokeMethod calls happened. - expect(log, [ - 'map#getLatLng', - 'markers#isInfoWindowShown', - 'map#getZoomLevel', - 'map#takeSnapshot', - ]); + test('updateCircles passes expected arguments', () async { + const int mapId = 1; + final (GoogleMapsFlutterIOS maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + const Circle object1 = Circle(circleId: CircleId('1')); + const Circle object2old = Circle(circleId: CircleId('2')); + final Circle object2new = object2old.copyWith(radiusParam: 42); + const Circle object3 = Circle(circleId: CircleId('3')); + await maps.updateCircles( + CircleUpdates.from( + {object1, object2old}, {object2new, object3}), + mapId: mapId); + + final VerificationResult verification = + verify(api.updateCircles(captureAny, captureAny, captureAny)); + final List toAdd = + verification.captured[0] as List; + final List toChange = + verification.captured[1] as List; + final List toRemove = verification.captured[2] as List; + // Object one should be removed. + expect(toRemove.length, 1); + expect(toRemove.first, object1.circleId.value); + // Object two should be changed. + expect(toChange.length, 1); + expect(toChange.first?.json, object2new.toJson()); + // Object 3 should be added. + expect(toAdd.length, 1); + expect(toAdd.first?.json, object3.toJson()); + }); + + test('updateMarkers passes expected arguments', () async { + const int mapId = 1; + final (GoogleMapsFlutterIOS maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + const Marker object1 = Marker(markerId: MarkerId('1')); + const Marker object2old = Marker(markerId: MarkerId('2')); + final Marker object2new = object2old.copyWith(rotationParam: 42); + const Marker object3 = Marker(markerId: MarkerId('3')); + await maps.updateMarkers( + MarkerUpdates.from( + {object1, object2old}, {object2new, object3}), + mapId: mapId); + + final VerificationResult verification = + verify(api.updateMarkers(captureAny, captureAny, captureAny)); + final List toAdd = + verification.captured[0] as List; + final List toChange = + verification.captured[1] as List; + final List toRemove = verification.captured[2] as List; + // Object one should be removed. + expect(toRemove.length, 1); + expect(toRemove.first, object1.markerId.value); + // Object two should be changed. + expect(toChange.length, 1); + expect(toChange.first?.json, object2new.toJson()); + // Object 3 should be added. + expect(toAdd.length, 1); + expect(toAdd.first?.json, object3.toJson()); + }); + + test('updatePolygons passes expected arguments', () async { + const int mapId = 1; + final (GoogleMapsFlutterIOS maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + const Polygon object1 = Polygon(polygonId: PolygonId('1')); + const Polygon object2old = Polygon(polygonId: PolygonId('2')); + final Polygon object2new = object2old.copyWith(strokeWidthParam: 42); + const Polygon object3 = Polygon(polygonId: PolygonId('3')); + await maps.updatePolygons( + PolygonUpdates.from( + {object1, object2old}, {object2new, object3}), + mapId: mapId); + + final VerificationResult verification = + verify(api.updatePolygons(captureAny, captureAny, captureAny)); + final List toAdd = + verification.captured[0] as List; + final List toChange = + verification.captured[1] as List; + final List toRemove = verification.captured[2] as List; + // Object one should be removed. + expect(toRemove.length, 1); + expect(toRemove.first, object1.polygonId.value); + // Object two should be changed. + expect(toChange.length, 1); + expect(toChange.first?.json, object2new.toJson()); + // Object 3 should be added. + expect(toAdd.length, 1); + expect(toAdd.first?.json, object3.toJson()); + }); + + test('updatePolylines passes expected arguments', () async { + const int mapId = 1; + final (GoogleMapsFlutterIOS maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + const Polyline object1 = Polyline(polylineId: PolylineId('1')); + const Polyline object2old = Polyline(polylineId: PolylineId('2')); + final Polyline object2new = object2old.copyWith(widthParam: 42); + const Polyline object3 = Polyline(polylineId: PolylineId('3')); + await maps.updatePolylines( + PolylineUpdates.from( + {object1, object2old}, {object2new, object3}), + mapId: mapId); + + final VerificationResult verification = + verify(api.updatePolylines(captureAny, captureAny, captureAny)); + final List toAdd = + verification.captured[0] as List; + final List toChange = + verification.captured[1] as List; + final List toRemove = verification.captured[2] as List; + // Object one should be removed. + expect(toRemove.length, 1); + expect(toRemove.first, object1.polylineId.value); + // Object two should be changed. + expect(toChange.length, 1); + expect(toChange.first?.json, object2new.toJson()); + // Object 3 should be added. + expect(toAdd.length, 1); + expect(toAdd.first?.json, object3.toJson()); + }); + + test('updateTileOverlays passes expected arguments', () async { + const int mapId = 1; + final (GoogleMapsFlutterIOS maps, MockMapsApi api) = + setUpMockMap(mapId: mapId); + + const TileOverlay object1 = TileOverlay(tileOverlayId: TileOverlayId('1')); + const TileOverlay object2old = + TileOverlay(tileOverlayId: TileOverlayId('2')); + final TileOverlay object2new = object2old.copyWith(zIndexParam: 42); + const TileOverlay object3 = TileOverlay(tileOverlayId: TileOverlayId('3')); + // Pre-set the initial state, since this update method doesn't take the old + // state. + await maps.updateTileOverlays( + newTileOverlays: {object1, object2old}, mapId: mapId); + clearInteractions(api); + + await maps.updateTileOverlays( + newTileOverlays: {object2new, object3}, mapId: mapId); + + final VerificationResult verification = + verify(api.updateTileOverlays(captureAny, captureAny, captureAny)); + final List toAdd = + verification.captured[0] as List; + final List toChange = + verification.captured[1] as List; + final List toRemove = verification.captured[2] as List; + // Object one should be removed. + expect(toRemove.length, 1); + expect(toRemove.first, object1.tileOverlayId.value); + // Object two should be changed. + expect(toChange.length, 1); + expect(toChange.first?.json, object2new.toJson()); + // Object 3 should be added. + expect(toAdd.length, 1); + expect(toAdd.first?.json, object3.toJson()); }); test('markers send drag event to correct streams', () async { const int mapId = 1; - final Map jsonMarkerDragStartEvent = { - 'mapId': mapId, - 'markerId': 'drag-start-marker', - 'position': [1.0, 1.0] - }; - final Map jsonMarkerDragEvent = { - 'mapId': mapId, - 'markerId': 'drag-marker', - 'position': [1.0, 1.0] - }; - final Map jsonMarkerDragEndEvent = { - 'mapId': mapId, - 'markerId': 'drag-end-marker', - 'position': [1.0, 1.0] - }; + const String dragStartId = 'drag-start-marker'; + const String dragId = 'drag-marker'; + const String dragEndId = 'drag-end-marker'; + final PlatformLatLng fakePosition = + PlatformLatLng(latitude: 1.0, longitude: 1.0); final GoogleMapsFlutterIOS maps = GoogleMapsFlutterIOS(); - maps.ensureChannelInitialized(mapId); + final HostMapMessageHandler callbackHandler = + maps.ensureHandlerInitialized(mapId); final StreamQueue markerDragStartStream = StreamQueue(maps.onMarkerDragStart(mapId: mapId)); @@ -114,17 +459,82 @@ void main() { final StreamQueue markerDragEndStream = StreamQueue(maps.onMarkerDragEnd(mapId: mapId)); - await sendPlatformMessage( - mapId, 'marker#onDragStart', jsonMarkerDragStartEvent); - await sendPlatformMessage(mapId, 'marker#onDrag', jsonMarkerDragEvent); - await sendPlatformMessage( - mapId, 'marker#onDragEnd', jsonMarkerDragEndEvent); + // Simulate messages from the native side. + callbackHandler.onMarkerDragStart(dragStartId, fakePosition); + callbackHandler.onMarkerDrag(dragId, fakePosition); + callbackHandler.onMarkerDragEnd(dragEndId, fakePosition); + + expect((await markerDragStartStream.next).value.value, equals(dragStartId)); + expect((await markerDragStream.next).value.value, equals(dragId)); + expect((await markerDragEndStream.next).value.value, equals(dragEndId)); + }); + + test('markers send tap events to correct stream', () async { + const int mapId = 1; + const String objectId = 'object-id'; + + final GoogleMapsFlutterIOS maps = GoogleMapsFlutterIOS(); + final HostMapMessageHandler callbackHandler = + maps.ensureHandlerInitialized(mapId); + + final StreamQueue stream = + StreamQueue(maps.onMarkerTap(mapId: mapId)); + + // Simulate message from the native side. + callbackHandler.onMarkerTap(objectId); + + expect((await stream.next).value.value, equals(objectId)); + }); + + test('circles send tap events to correct stream', () async { + const int mapId = 1; + const String objectId = 'object-id'; + + final GoogleMapsFlutterIOS maps = GoogleMapsFlutterIOS(); + final HostMapMessageHandler callbackHandler = + maps.ensureHandlerInitialized(mapId); + + final StreamQueue stream = + StreamQueue(maps.onCircleTap(mapId: mapId)); + + // Simulate message from the native side. + callbackHandler.onCircleTap(objectId); + + expect((await stream.next).value.value, equals(objectId)); + }); + + test('polygons send tap events to correct stream', () async { + const int mapId = 1; + const String objectId = 'object-id'; + + final GoogleMapsFlutterIOS maps = GoogleMapsFlutterIOS(); + final HostMapMessageHandler callbackHandler = + maps.ensureHandlerInitialized(mapId); + + final StreamQueue stream = + StreamQueue(maps.onPolygonTap(mapId: mapId)); + + // Simulate message from the native side. + callbackHandler.onPolygonTap(objectId); + + expect((await stream.next).value.value, equals(objectId)); + }); + + test('polylines send tap events to correct stream', () async { + const int mapId = 1; + const String objectId = 'object-id'; + + final GoogleMapsFlutterIOS maps = GoogleMapsFlutterIOS(); + final HostMapMessageHandler callbackHandler = + maps.ensureHandlerInitialized(mapId); + + final StreamQueue stream = + StreamQueue(maps.onPolylineTap(mapId: mapId)); + + // Simulate message from the native side. + callbackHandler.onPolylineTap(objectId); - expect((await markerDragStartStream.next).value.value, - equals('drag-start-marker')); - expect((await markerDragStream.next).value.value, equals('drag-marker')); - expect((await markerDragEndStream.next).value.value, - equals('drag-end-marker')); + expect((await stream.next).value.value, equals(objectId)); }); testWidgets('cloudMapId is passed', (WidgetTester tester) async { @@ -140,17 +550,15 @@ void main() { methodCall.arguments as Map); if (args.containsKey('params')) { final Uint8List paramsUint8List = args['params'] as Uint8List; - const StandardMessageCodec codec = StandardMessageCodec(); final ByteData byteData = ByteData.sublistView(paramsUint8List); - final Map creationParams = - Map.from( - codec.decodeMessage(byteData) as Map); - if (creationParams.containsKey('options')) { - final Map options = Map.from( - creationParams['options'] as Map); - if (options.containsKey('cloudMapId')) { - passedCloudMapIdCompleter - .complete(options['cloudMapId'] as String); + final PlatformMapViewCreationParams? creationParams = + MapsApi.pigeonChannelCodec.decodeMessage(byteData) + as PlatformMapViewCreationParams?; + if (creationParams != null) { + final String? passedMapId = + creationParams.mapConfiguration.cloudMapId; + if (passedMapId != null) { + passedCloudMapIdCompleter.complete(passedMapId); } } } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/test/google_maps_flutter_ios_test.mocks.dart b/packages/google_maps_flutter/google_maps_flutter_ios/test/google_maps_flutter_ios_test.mocks.dart new file mode 100644 index 000000000000..e94375876150 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/test/google_maps_flutter_ios_test.mocks.dart @@ -0,0 +1,404 @@ +// Mocks generated by Mockito 5.4.4 from annotations +// in google_maps_flutter_ios/test/google_maps_flutter_ios_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i4; +import 'dart:typed_data' as _i5; + +import 'package:google_maps_flutter_ios/src/messages.g.dart' as _i2; +import 'package:mockito/mockito.dart' as _i1; +import 'package:mockito/src/dummies.dart' as _i3; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakePlatformPoint_0 extends _i1.SmartFake implements _i2.PlatformPoint { + _FakePlatformPoint_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakePlatformLatLng_1 extends _i1.SmartFake + implements _i2.PlatformLatLng { + _FakePlatformLatLng_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakePlatformLatLngBounds_2 extends _i1.SmartFake + implements _i2.PlatformLatLngBounds { + _FakePlatformLatLngBounds_2( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [MapsApi]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockMapsApi extends _i1.Mock implements _i2.MapsApi { + @override + String get pigeonVar_messageChannelSuffix => (super.noSuchMethod( + Invocation.getter(#pigeonVar_messageChannelSuffix), + returnValue: _i3.dummyValue( + this, + Invocation.getter(#pigeonVar_messageChannelSuffix), + ), + returnValueForMissingStub: _i3.dummyValue( + this, + Invocation.getter(#pigeonVar_messageChannelSuffix), + ), + ) as String); + + @override + _i4.Future waitForMap() => (super.noSuchMethod( + Invocation.method( + #waitForMap, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future updateMapConfiguration( + _i2.PlatformMapConfiguration? configuration) => + (super.noSuchMethod( + Invocation.method( + #updateMapConfiguration, + [configuration], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future updateCircles( + List<_i2.PlatformCircle>? toAdd, + List<_i2.PlatformCircle>? toChange, + List? idsToRemove, + ) => + (super.noSuchMethod( + Invocation.method( + #updateCircles, + [ + toAdd, + toChange, + idsToRemove, + ], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future updateHeatmaps( + List<_i2.PlatformHeatmap>? toAdd, + List<_i2.PlatformHeatmap>? toChange, + List? idsToRemove, + ) => + (super.noSuchMethod( + Invocation.method( + #updateHeatmaps, + [ + toAdd, + toChange, + idsToRemove, + ], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future updateClusterManagers( + List<_i2.PlatformClusterManager>? toAdd, + List? idsToRemove, + ) => + (super.noSuchMethod( + Invocation.method( + #updateClusterManagers, + [ + toAdd, + idsToRemove, + ], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future updateMarkers( + List<_i2.PlatformMarker>? toAdd, + List<_i2.PlatformMarker>? toChange, + List? idsToRemove, + ) => + (super.noSuchMethod( + Invocation.method( + #updateMarkers, + [ + toAdd, + toChange, + idsToRemove, + ], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future updatePolygons( + List<_i2.PlatformPolygon>? toAdd, + List<_i2.PlatformPolygon>? toChange, + List? idsToRemove, + ) => + (super.noSuchMethod( + Invocation.method( + #updatePolygons, + [ + toAdd, + toChange, + idsToRemove, + ], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future updatePolylines( + List<_i2.PlatformPolyline>? toAdd, + List<_i2.PlatformPolyline>? toChange, + List? idsToRemove, + ) => + (super.noSuchMethod( + Invocation.method( + #updatePolylines, + [ + toAdd, + toChange, + idsToRemove, + ], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future updateTileOverlays( + List<_i2.PlatformTileOverlay>? toAdd, + List<_i2.PlatformTileOverlay>? toChange, + List? idsToRemove, + ) => + (super.noSuchMethod( + Invocation.method( + #updateTileOverlays, + [ + toAdd, + toChange, + idsToRemove, + ], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future<_i2.PlatformPoint> getScreenCoordinate( + _i2.PlatformLatLng? latLng) => + (super.noSuchMethod( + Invocation.method( + #getScreenCoordinate, + [latLng], + ), + returnValue: _i4.Future<_i2.PlatformPoint>.value(_FakePlatformPoint_0( + this, + Invocation.method( + #getScreenCoordinate, + [latLng], + ), + )), + returnValueForMissingStub: + _i4.Future<_i2.PlatformPoint>.value(_FakePlatformPoint_0( + this, + Invocation.method( + #getScreenCoordinate, + [latLng], + ), + )), + ) as _i4.Future<_i2.PlatformPoint>); + + @override + _i4.Future<_i2.PlatformLatLng> getLatLng( + _i2.PlatformPoint? screenCoordinate) => + (super.noSuchMethod( + Invocation.method( + #getLatLng, + [screenCoordinate], + ), + returnValue: _i4.Future<_i2.PlatformLatLng>.value(_FakePlatformLatLng_1( + this, + Invocation.method( + #getLatLng, + [screenCoordinate], + ), + )), + returnValueForMissingStub: + _i4.Future<_i2.PlatformLatLng>.value(_FakePlatformLatLng_1( + this, + Invocation.method( + #getLatLng, + [screenCoordinate], + ), + )), + ) as _i4.Future<_i2.PlatformLatLng>); + + @override + _i4.Future<_i2.PlatformLatLngBounds> getVisibleRegion() => + (super.noSuchMethod( + Invocation.method( + #getVisibleRegion, + [], + ), + returnValue: _i4.Future<_i2.PlatformLatLngBounds>.value( + _FakePlatformLatLngBounds_2( + this, + Invocation.method( + #getVisibleRegion, + [], + ), + )), + returnValueForMissingStub: _i4.Future<_i2.PlatformLatLngBounds>.value( + _FakePlatformLatLngBounds_2( + this, + Invocation.method( + #getVisibleRegion, + [], + ), + )), + ) as _i4.Future<_i2.PlatformLatLngBounds>); + + @override + _i4.Future moveCamera(_i2.PlatformCameraUpdate? cameraUpdate) => + (super.noSuchMethod( + Invocation.method( + #moveCamera, + [cameraUpdate], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future animateCamera(_i2.PlatformCameraUpdate? cameraUpdate) => + (super.noSuchMethod( + Invocation.method( + #animateCamera, + [cameraUpdate], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future getZoomLevel() => (super.noSuchMethod( + Invocation.method( + #getZoomLevel, + [], + ), + returnValue: _i4.Future.value(0.0), + returnValueForMissingStub: _i4.Future.value(0.0), + ) as _i4.Future); + + @override + _i4.Future showInfoWindow(String? markerId) => (super.noSuchMethod( + Invocation.method( + #showInfoWindow, + [markerId], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future hideInfoWindow(String? markerId) => (super.noSuchMethod( + Invocation.method( + #hideInfoWindow, + [markerId], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future isInfoWindowShown(String? markerId) => (super.noSuchMethod( + Invocation.method( + #isInfoWindowShown, + [markerId], + ), + returnValue: _i4.Future.value(false), + returnValueForMissingStub: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future setStyle(String? style) => (super.noSuchMethod( + Invocation.method( + #setStyle, + [style], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future getLastStyleError() => (super.noSuchMethod( + Invocation.method( + #getLastStyleError, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future clearTileCache(String? tileOverlayId) => (super.noSuchMethod( + Invocation.method( + #clearTileCache, + [tileOverlayId], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future<_i5.Uint8List?> takeSnapshot() => (super.noSuchMethod( + Invocation.method( + #takeSnapshot, + [], + ), + returnValue: _i4.Future<_i5.Uint8List?>.value(), + returnValueForMissingStub: _i4.Future<_i5.Uint8List?>.value(), + ) as _i4.Future<_i5.Uint8List?>); +} 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 a137b29112c7..49c12ebbbdab 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,29 @@ +## 2.9.5 + +* Converts `BitmapDescriptor` to typesafe structures. + +## 2.9.4 + +* Converts `PatternItem` to typesafe structure. +* Converts `Cap` to typesafe structure. + +## 2.9.3 + +* Corrects an incorrect comment in polyline.dart file. + +## 2.9.2 + +* Corrects JSON tag for `CameraUpdateNewLatLngBounds`. + +## 2.9.1 + +* Splits CameraUpdate into dervied classes for different update cases. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + +## 2.9.0 + +* Adds support for heatmap layers. + ## 2.8.0 * Deprecates `BitmapDescriptor.fromAssetImage` in favor of `BitmapDescriptor.asset` and `AssetMapBitmap.create`. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart index dd728cf1349d..254a5444dc76 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart @@ -14,6 +14,7 @@ import 'package:stream_transform/stream_transform.dart'; import '../../google_maps_flutter_platform_interface.dart'; import '../types/tile_overlay_updates.dart'; import '../types/utils/map_configuration_serialization.dart'; +import 'serialization.dart'; /// Error thrown when an unknown map ID is provided to a method channel API. class UnknownMapIDError extends Error { @@ -363,6 +364,17 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { ); } + @override + Future updateHeatmaps( + HeatmapUpdates heatmapUpdates, { + required int mapId, + }) { + return channel(mapId).invokeMethod( + 'heatmaps#update', + serializeMapsObjectUpdates(heatmapUpdates, serializeHeatmap), + ); + } + @override Future updateTileOverlays({ required Set newTileOverlays, @@ -518,7 +530,7 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { /// This implementation uses hybrid composition to render the Google Maps /// Widget on Android. This comes at the cost of some performance on Android /// versions below 10. See - /// https://flutter.dev/docs/development/platform-integration/platform-views#performance for more + /// https://docs.flutter.dev/platform-integration/android/platform-views#performance for more /// information. /// /// If set to true, the google map widget should be built with @@ -542,6 +554,7 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { 'polygonsToAdd': serializePolygonSet(mapObjects.polygons), 'polylinesToAdd': serializePolylineSet(mapObjects.polylines), 'circlesToAdd': serializeCircleSet(mapObjects.circles), + 'heatmapsToAdd': serializeHeatmapSet(mapObjects.heatmaps), 'tileOverlaysToAdd': serializeTileOverlaySet(mapObjects.tileOverlays), }; diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/serialization.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/serialization.dart new file mode 100644 index 000000000000..2a82a05565f9 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/serialization.dart @@ -0,0 +1,159 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import '../../google_maps_flutter_platform_interface.dart'; + +String _objectsToAddKey(String name) => '${name}sToAdd'; +String _objectsToChangeKey(String name) => '${name}sToChange'; +String _objectIdsToRemoveKey(String name) => '${name}IdsToRemove'; +const String _heatmapIdKey = 'heatmapId'; +const String _heatmapDataKey = 'data'; +const String _heatmapDissipatingKey = 'dissipating'; +const String _heatmapGradientKey = 'gradient'; +const String _heatmapMaxIntensityKey = 'maxIntensity'; +const String _heatmapOpacityKey = 'opacity'; +const String _heatmapRadiusKey = 'radius'; +const String _heatmapMinimumZoomIntensityKey = 'minimumZoomIntensity'; +const String _heatmapMaximumZoomIntensityKey = 'maximumZoomIntensity'; +const String _heatmapGradientColorsKey = 'colors'; +const String _heatmapGradientStartPointsKey = 'startPoints'; +const String _heatmapGradientColorMapSizeKey = 'colorMapSize'; + +void _addIfNonNull(Map map, String fieldName, Object? value) { + if (value != null) { + map[fieldName] = value; + } +} + +/// Serialize [MapsObjectUpdates] +Object serializeMapsObjectUpdates>( + MapsObjectUpdates updates, + Object Function(T) serialize, +) { + final Map json = {}; + + _addIfNonNull( + json, + _objectsToAddKey(updates.objectName), + updates.objectsToAdd.map(serialize).toList(), + ); + _addIfNonNull( + json, + _objectsToChangeKey(updates.objectName), + updates.objectsToChange.map(serialize).toList(), + ); + _addIfNonNull( + json, + _objectIdsToRemoveKey(updates.objectName), + updates.objectIdsToRemove + .map((MapsObjectId m) => m.value) + .toList(), + ); + + return json; +} + +/// Serialize [Heatmap] +Object serializeHeatmap(Heatmap heatmap) { + final Map json = {}; + + _addIfNonNull(json, _heatmapIdKey, heatmap.heatmapId.value); + _addIfNonNull( + json, + _heatmapDataKey, + heatmap.data.map(serializeWeightedLatLng).toList(), + ); + _addIfNonNull(json, _heatmapDissipatingKey, heatmap.dissipating); + + final HeatmapGradient? gradient = heatmap.gradient; + if (gradient != null) { + _addIfNonNull( + json, _heatmapGradientKey, serializeHeatmapGradient(gradient)); + } + _addIfNonNull(json, _heatmapMaxIntensityKey, heatmap.maxIntensity); + _addIfNonNull(json, _heatmapOpacityKey, heatmap.opacity); + _addIfNonNull(json, _heatmapRadiusKey, heatmap.radius.radius); + _addIfNonNull( + json, _heatmapMinimumZoomIntensityKey, heatmap.minimumZoomIntensity); + _addIfNonNull( + json, _heatmapMaximumZoomIntensityKey, heatmap.maximumZoomIntensity); + + return json; +} + +/// Serialize [WeightedLatLng] +Object serializeWeightedLatLng(WeightedLatLng wll) { + return [serializeLatLng(wll.point), wll.weight]; +} + +/// Deserialize [WeightedLatLng] +WeightedLatLng? deserializeWeightedLatLng(Object? json) { + if (json == null) { + return null; + } + assert(json is List && json.length == 2); + final List list = json as List; + final LatLng latLng = deserializeLatLng(list[0])!; + return WeightedLatLng(latLng, weight: list[1] as double); +} + +/// Serialize [LatLng] +Object serializeLatLng(LatLng latLng) { + return [latLng.latitude, latLng.longitude]; +} + +/// Deserialize [LatLng] +LatLng? deserializeLatLng(Object? json) { + if (json == null) { + return null; + } + assert(json is List && json.length == 2); + final List list = json as List; + return LatLng(list[0]! as double, list[1]! as double); +} + +/// Serialize [HeatmapGradient] +Object serializeHeatmapGradient(HeatmapGradient gradient) { + final Map json = {}; + + _addIfNonNull( + json, + _heatmapGradientColorsKey, + gradient.colors.map((HeatmapGradientColor e) => e.color.value).toList(), + ); + _addIfNonNull( + json, + _heatmapGradientStartPointsKey, + gradient.colors.map((HeatmapGradientColor e) => e.startPoint).toList(), + ); + _addIfNonNull(json, _heatmapGradientColorMapSizeKey, gradient.colorMapSize); + + return json; +} + +/// Deserialize [HeatmapGradient] +HeatmapGradient? deserializeHeatmapGradient(Object? json) { + if (json == null) { + return null; + } + assert(json is Map); + final Map map = (json as Map).cast(); + final List colors = (map[_heatmapGradientColorsKey]! as List) + .whereType() + .map((int e) => Color(e)) + .toList(); + final List startPoints = + (map[_heatmapGradientStartPointsKey]! as List) + .whereType() + .toList(); + final List gradientColors = []; + for (int i = 0; i < colors.length; i++) { + gradientColors.add(HeatmapGradientColor(colors[i], startPoints[i])); + } + return HeatmapGradient( + gradientColors, + colorMapSize: map[_heatmapGradientColorMapSizeKey] as int? ?? 256, + ); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart index 648c6a162d68..a8f8e6d8b329 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart @@ -49,13 +49,13 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface { throw UnimplementedError('init() has not been implemented.'); } - /// Updates configuration options of the map user interface - deprecated, use - /// updateMapConfiguration instead. + /// Updates configuration options of the map user interface. /// /// Change listeners are notified once the update has been made on the /// platform side. /// /// The returned [Future] completes after listeners have been notified. + @Deprecated('Use updateMapConfiguration instead.') Future updateMapOptions( Map optionsUpdate, { required int mapId, @@ -129,6 +129,19 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface { throw UnimplementedError('updateCircles() has not been implemented.'); } + /// Updates heatmap configuration. + /// + /// Change listeners are notified once the update has been made on the + /// platform side. + /// + /// The returned [Future] completes after listeners have been notified. + Future updateHeatmaps( + HeatmapUpdates heatmapUpdates, { + required int mapId, + }) { + throw UnimplementedError('updateHeatmaps() has not been implemented.'); + } + /// Updates tile overlay configuration. /// /// Change listeners are notified once the update has been made on the @@ -387,8 +400,8 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface { return null; } - /// Returns a widget displaying the map view - deprecated, use - /// [buildViewWithConfiguration] instead. + /// Returns a widget displaying the map view. + @Deprecated('Use buildViewWithConfiguration instead.') Widget buildView( int creationId, PlatformViewCreatedCallback onPlatformViewCreated, { @@ -407,8 +420,7 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface { throw UnimplementedError('buildView() has not been implemented.'); } - /// Returns a widget displaying the map view - deprecated, use - /// [buildViewWithConfiguration] instead. + /// Returns a widget displaying the map view. /// /// This method is similar to [buildView], but contains a parameter for /// platforms that require a text direction. @@ -417,6 +429,7 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface { /// [buildView]. This is for backward compatibility with existing /// implementations. Platforms that use the text direction should override /// this as the primary implementation, and delegate to it from buildView. + @Deprecated('Use buildViewWithConfiguration instead.') Widget buildViewWithTextDirection( int creationId, PlatformViewCreatedCallback onPlatformViewCreated, { diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_inspector_platform.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_inspector_platform.dart index 461d38a61616..8bf6f6f89baf 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_inspector_platform.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_inspector_platform.dart @@ -116,6 +116,22 @@ abstract class GoogleMapsInspectorPlatform extends PlatformInterface { throw UnimplementedError('getTileOverlayInfo() has not been implemented.'); } + /// If the platform supports getting information about heatmaps. + bool supportsGettingHeatmapInfo() { + throw UnimplementedError( + 'supportsGettingHeatmapInfo() has not been implemented.', + ); + } + + /// Returns information about the heatmap with the given ID. + /// + /// The returned object will be synthesized from platform data, so will not + /// be the same Dart object as the original [Heatmap] provided to the + /// platform interface with that ID, and not all fields will be populated. + Future getHeatmapInfo(HeatmapId heatmapId, {required int mapId}) { + throw UnimplementedError('getHeatmapInfo() has not been implemented.'); + } + /// Returns current clusters from [ClusterManager]. Future> getClusters( {required int mapId, required ClusterManagerId clusterManagerId}) { diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart index fe3f9d8a0f7e..e25d3c7a2c57 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart @@ -5,7 +5,7 @@ import 'dart:async' show Future; import 'dart:typed_data' show Uint8List; -import 'package:flutter/foundation.dart' show kIsWeb; +import 'package:flutter/foundation.dart' show kIsWeb, visibleForTesting; import 'package:flutter/material.dart' show AssetBundleImageKey, @@ -29,6 +29,14 @@ enum MapBitmapScaling { none, } +/// Convert a string from provided JSON to a MapBitmapScaling enum. +@visibleForTesting +MapBitmapScaling mapBitmapScalingFromString(String mode) => switch (mode) { + 'auto' => MapBitmapScaling.auto, + 'none' => MapBitmapScaling.none, + _ => throw ArgumentError('Unrecognized MapBitmapScaling $mode', 'mode'), + }; + // The default pixel ratio for custom bitmaps. const double _naturalPixelRatio = 1.0; @@ -44,14 +52,14 @@ const double _naturalPixelRatio = 1.0; /// a default marker icon. /// Use the [BitmapDescriptor.defaultMarkerWithHue] to create a /// [BitmapDescriptor] for a default marker icon with a hue value. -class BitmapDescriptor { - const BitmapDescriptor._(this._json); +abstract class BitmapDescriptor { + const BitmapDescriptor._(); /// The inverse of .toJson. // TODO(stuartmorgan): Remove this in the next breaking change. @Deprecated('No longer supported') - BitmapDescriptor.fromJson(Object json) : _json = json { - assert(_json is List); + static BitmapDescriptor fromJson(Object json) { + assert(json is List); final List jsonList = json as List; assert(_validTypes.contains(jsonList[0])); switch (jsonList[0]) { @@ -61,11 +69,14 @@ class BitmapDescriptor { assert(jsonList[1] is num); final num secondElement = jsonList[1] as num; assert(0 <= secondElement && secondElement < 360); + return DefaultMarker(hue: secondElement); } + return const DefaultMarker(); case _fromBytes: assert(jsonList.length == 2); assert(jsonList[1] != null && jsonList[1] is List); assert((jsonList[1] as List).isNotEmpty); + return BytesBitmap(byteData: jsonList[1] as Uint8List); case _fromAsset: assert(jsonList.length <= 3); assert(jsonList[1] != null && jsonList[1] is String); @@ -73,7 +84,10 @@ class BitmapDescriptor { if (jsonList.length == 3) { assert(jsonList[2] != null && jsonList[2] is String); assert((jsonList[2] as String).isNotEmpty); + return AssetBitmap( + name: jsonList[1] as String, package: jsonList[2] as String); } + return AssetBitmap(name: jsonList[1] as String); case _fromAssetImage: assert(jsonList.length <= 4); assert(jsonList[1] != null && jsonList[1] is String); @@ -82,7 +96,15 @@ class BitmapDescriptor { if (jsonList.length == 4) { assert(jsonList[3] != null && jsonList[3] is List); assert((jsonList[3] as List).length == 2); + final List sizeList = jsonList[3] as List; + return AssetImageBitmap( + name: jsonList[1] as String, + scale: jsonList[2] as double, + size: Size((sizeList[0] as num).toDouble(), + (sizeList[1] as num).toDouble())); } + return AssetImageBitmap( + name: jsonList[1] as String, scale: jsonList[2] as double); case AssetMapBitmap.type: assert(jsonList.length == 2); assert(jsonList[1] != null && jsonList[1] is Map); @@ -96,6 +118,16 @@ class BitmapDescriptor { assert(jsonMap['imagePixelRatio'] is double); assert(!jsonMap.containsKey('width') || jsonMap['width'] is double); assert(!jsonMap.containsKey('height') || jsonMap['height'] is double); + final double? width = + jsonMap.containsKey('width') ? jsonMap['width'] as double : null; + final double? height = + jsonMap.containsKey('height') ? jsonMap['height'] as double : null; + return AssetMapBitmap(jsonMap['assetName'] as String, + bitmapScaling: + mapBitmapScalingFromString(jsonMap['bitmapScaling'] as String), + imagePixelRatio: jsonMap['imagePixelRatio'] as double, + width: width, + height: height); case BytesMapBitmap.type: assert(jsonList.length == 2); assert(jsonList[1] != null && jsonList[1] is Map); @@ -109,9 +141,20 @@ class BitmapDescriptor { assert(jsonMap['imagePixelRatio'] is double); assert(!jsonMap.containsKey('width') || jsonMap['width'] is double); assert(!jsonMap.containsKey('height') || jsonMap['height'] is double); + final double? width = + jsonMap.containsKey('width') ? jsonMap['width'] as double : null; + final double? height = + jsonMap.containsKey('height') ? jsonMap['height'] as double : null; + return BytesMapBitmap(jsonMap['byteData'] as Uint8List, + bitmapScaling: + mapBitmapScalingFromString(jsonMap['bitmapScaling'] as String), + width: width, + height: height, + imagePixelRatio: jsonMap['imagePixelRatio'] as double); default: break; } + throw ArgumentError('Unrecognized BitmapDescriptor type ${jsonList[0]}'); } static const String _defaultMarker = 'defaultMarker'; @@ -160,21 +203,20 @@ class BitmapDescriptor { static const double hueRose = 330.0; /// Creates a BitmapDescriptor that refers to the default marker image. - static const BitmapDescriptor defaultMarker = - BitmapDescriptor._([_defaultMarker]); + static const BitmapDescriptor defaultMarker = DefaultMarker(); /// Creates a BitmapDescriptor that refers to a colorization of the default /// marker image. For convenience, there is a predefined set of hue values. /// See e.g. [hueYellow]. static BitmapDescriptor defaultMarkerWithHue(double hue) { assert(0.0 <= hue && hue < 360.0); - return BitmapDescriptor._([_defaultMarker, hue]); + return DefaultMarker(hue: hue); } /// Creates a [BitmapDescriptor] from an asset image. /// /// Asset images in flutter are stored per: - /// https://flutter.dev/docs/development/ui/assets-and-images#declaring-resolution-aware-image-assets + /// https://flutter.dev/to/resolution-aware-images /// This method takes into consideration various asset resolutions /// and scales the images to the right resolution depending on the dpi. /// Set `mipmaps` to false to load the exact dpi version of the image, @@ -189,27 +231,17 @@ class BitmapDescriptor { }) async { final double? devicePixelRatio = configuration.devicePixelRatio; if (!mipmaps && devicePixelRatio != null) { - return BitmapDescriptor._([ - _fromAssetImage, - assetName, - devicePixelRatio, - ]); + return AssetImageBitmap(name: assetName, scale: devicePixelRatio); } final AssetImage assetImage = AssetImage(assetName, package: package, bundle: bundle); final AssetBundleImageKey assetBundleImageKey = await assetImage.obtainKey(configuration); - final Size? size = configuration.size; - return BitmapDescriptor._([ - _fromAssetImage, - assetBundleImageKey.name, - assetBundleImageKey.scale, - if (kIsWeb && size != null) - [ - size.width, - size.height, - ], - ]); + final Size? size = kIsWeb ? configuration.size : null; + return AssetImageBitmap( + name: assetBundleImageKey.name, + scale: assetBundleImageKey.scale, + size: size); } /// Creates a BitmapDescriptor using an array of bytes that must be encoded @@ -222,15 +254,7 @@ class BitmapDescriptor { static BitmapDescriptor fromBytes(Uint8List byteData, {Size? size}) { assert(byteData.isNotEmpty, 'Cannot create BitmapDescriptor with empty byteData'); - return BitmapDescriptor._([ - _fromBytes, - byteData, - if (kIsWeb && size != null) - [ - size.width, - size.height, - ] - ]); + return BytesBitmap(byteData: byteData, size: size); } /// Creates a [BitmapDescriptor] from an asset using [AssetMapBitmap]. @@ -306,10 +330,100 @@ class BitmapDescriptor { ); } - final Object _json; - /// Convert the object to a Json format. - Object toJson() => _json; + Object toJson(); +} + +/// A BitmapDescriptor using the default marker. +class DefaultMarker extends BitmapDescriptor { + /// Provide an optional [hue] for the default marker. + const DefaultMarker({this.hue}) : super._(); + + /// Optional hue of the colorization of the default marker. + final num? hue; + + @override + Object toJson() => (hue == null) + ? const [BitmapDescriptor._defaultMarker] + : [BitmapDescriptor._defaultMarker, hue!]; +} + +/// A BitmapDescriptor using an array of bytes that must be encoded +/// as PNG. +@Deprecated('Use BytesMapBitmap instead') +class BytesBitmap extends BitmapDescriptor { + /// On the web, the [size] parameter represents the *physical size* of the + /// bitmap, regardless of the actual resolution of the encoded PNG. + /// This helps the browser to render High-DPI images at the correct size. + /// `size` is not required (and ignored, if passed) in other platforms. + @Deprecated('Use BytesMapBitmap instead') + const BytesBitmap({required Uint8List byteData, Size? size}) + : this._(byteData, kIsWeb ? size : null); + + @Deprecated('Use BytesMapBitmap instead') + const BytesBitmap._(this.byteData, this.size) : super._(); + + /// Array of bytes encoding a PNG. + final Uint8List byteData; + + /// On web, the physical size of the bitmap. Null on all other platforms. + final Size? size; + + @override + Object toJson() => [ + BitmapDescriptor._fromBytes, + byteData, + if (size != null) [size!.width, size!.height] + ]; +} + +/// A bitmap specified by a name and optional package. +class AssetBitmap extends BitmapDescriptor { + /// Provides an asset name with [name] and optionally a [package]. + const AssetBitmap({required this.name, this.package}) : super._(); + + /// Name of the asset backing the bitmap. + final String name; + + /// Optional package of the asset. + final String? package; + + @override + Object toJson() => [ + BitmapDescriptor._fromAsset, + name, + if (package != null) package! + ]; +} + +/// A [BitmapDescriptor] from an asset image. +@Deprecated('Use AssetMapBitmap instead') +class AssetImageBitmap extends BitmapDescriptor { + /// Creates a [BitmapDescriptor] from an asset image with specified [name] and [scale], and an optional [size]. + /// Asset images in flutter are stored per: + /// https://flutter.dev/to/resolution-aware-images + /// This method takes into consideration various asset resolutions + /// and scales the images to the right resolution depending on the dpi. + @Deprecated('Use AssetMapBitmap instead') + const AssetImageBitmap({required this.name, required this.scale, this.size}) + : super._(); + + /// Name of the image asset. + final String name; + + /// Scaling factor for the asset image. + final double scale; + + /// Size of the image if using mipmaps. + final Size? size; + + @override + Object toJson() => [ + BitmapDescriptor._fromAssetImage, + name, + scale, + if (size != null) [size!.width, size!.height] + ]; } /// Represents a [BitmapDescriptor] base class for map bitmaps. @@ -344,7 +458,7 @@ abstract class MapBitmap extends BitmapDescriptor { required this.imagePixelRatio, this.width, this.height, - }) : super._(const []); + }) : super._(); /// The scaling method of the bitmap. final MapBitmapScaling bitmapScaling; @@ -392,7 +506,7 @@ abstract class MapBitmap extends BitmapDescriptor { /// instances of this class. It dynamically resolves the correct asset version /// based on the device's pixel ratio, ensuring optimal resolution without /// manual configuration. -/// See https://docs.flutter.dev/ui/assets/assets-and-images#resolution-aware +/// See https://flutter.dev/to/resolution-aware-images /// for more information on resolution-aware assets. /// /// Note that it's important to either provide high-resolution diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart index 01126afb869e..a251d2bba8d8 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart @@ -110,22 +110,53 @@ class CameraPosition { 'CameraPosition(bearing: $bearing, target: $target, tilt: $tilt, zoom: $zoom)'; } +/// Indicates which type of camera update this instance represents. +enum CameraUpdateType { + /// New position for camera + newCameraPosition, + + /// New coordinates for camera + newLatLng, + + /// New coordinates bounding box + newLatLngBounds, + + /// New coordinate with zoom level + newLatLngZoom, + + /// Move by a scroll delta + scrollBy, + + /// Zoom by a relative change + zoomBy, + + /// Zoom to an absolute level + zoomTo, + + /// Zoom in + zoomIn, + + /// Zoom out + zoomOut, +} + /// Defines a camera move, supporting absolute moves as well as moves relative /// the current position. -class CameraUpdate { - const CameraUpdate._(this._json); +abstract class CameraUpdate { + const CameraUpdate._(this.updateType); + + /// Indicates which type of camera update this instance represents. + final CameraUpdateType updateType; /// Returns a camera update that moves the camera to the specified position. static CameraUpdate newCameraPosition(CameraPosition cameraPosition) { - return CameraUpdate._( - ['newCameraPosition', cameraPosition.toMap()], - ); + return CameraUpdateNewCameraPosition(cameraPosition); } /// Returns a camera update that moves the camera target to the specified /// geographical location. static CameraUpdate newLatLng(LatLng latLng) { - return CameraUpdate._(['newLatLng', latLng.toJson()]); + return CameraUpdateNewLatLng(latLng); } /// Returns a camera update that transforms the camera so that the specified @@ -133,19 +164,13 @@ class CameraUpdate { /// possible zoom level. A non-zero [padding] insets the bounding box from the /// map view's edges. The camera's new tilt and bearing will both be 0.0. static CameraUpdate newLatLngBounds(LatLngBounds bounds, double padding) { - return CameraUpdate._([ - 'newLatLngBounds', - bounds.toJson(), - padding, - ]); + return CameraUpdateNewLatLngBounds(bounds, padding); } /// Returns a camera update that moves the camera target to the specified /// geographical location and zoom level. static CameraUpdate newLatLngZoom(LatLng latLng, double zoom) { - return CameraUpdate._( - ['newLatLngZoom', latLng.toJson(), zoom], - ); + return CameraUpdateNewLatLngZoom(latLng, zoom); } /// Returns a camera update that moves the camera target the specified screen @@ -155,24 +180,14 @@ class CameraUpdate { /// the camera's target to a geographical location that is 50 to the east and /// 75 to the south of the current location, measured in screen coordinates. static CameraUpdate scrollBy(double dx, double dy) { - return CameraUpdate._( - ['scrollBy', dx, dy], - ); + return CameraUpdateScrollBy(dx, dy); } /// Returns a camera update that modifies the camera zoom level by the /// specified amount. The optional [focus] is a screen point whose underlying /// geographical location should be invariant, if possible, by the movement. static CameraUpdate zoomBy(double amount, [Offset? focus]) { - if (focus == null) { - return CameraUpdate._(['zoomBy', amount]); - } else { - return CameraUpdate._([ - 'zoomBy', - amount, - [focus.dx, focus.dy], - ]); - } + return CameraUpdateZoomBy(amount, focus); } /// Returns a camera update that zooms the camera in, bringing the camera @@ -180,7 +195,7 @@ class CameraUpdate { /// /// Equivalent to the result of calling `zoomBy(1.0)`. static CameraUpdate zoomIn() { - return const CameraUpdate._(['zoomIn']); + return const CameraUpdateZoomIn(); } /// Returns a camera update that zooms the camera out, bringing the camera @@ -188,16 +203,131 @@ class CameraUpdate { /// /// Equivalent to the result of calling `zoomBy(-1.0)`. static CameraUpdate zoomOut() { - return const CameraUpdate._(['zoomOut']); + return const CameraUpdateZoomOut(); } /// Returns a camera update that sets the camera zoom level. static CameraUpdate zoomTo(double zoom) { - return CameraUpdate._(['zoomTo', zoom]); + return CameraUpdateZoomTo(zoom); } - final Object _json; - /// Converts this object to something serializable in JSON. - Object toJson() => _json; + Object toJson(); +} + +/// Defines a camera move to a new position. +class CameraUpdateNewCameraPosition extends CameraUpdate { + /// Creates a camera move. + const CameraUpdateNewCameraPosition(this.cameraPosition) + : super._(CameraUpdateType.newCameraPosition); + + /// The new camera position. + final CameraPosition cameraPosition; + @override + Object toJson() => ['newCameraPosition', cameraPosition.toMap()]; +} + +/// Defines a camera move to a latitude and longitude. +class CameraUpdateNewLatLng extends CameraUpdate { + /// Creates a camera move to latitude and longitude. + const CameraUpdateNewLatLng(this.latLng) + : super._(CameraUpdateType.newLatLng); + + /// New latitude and longitude of the camera.. + final LatLng latLng; + @override + Object toJson() => ['newLatLng', latLng.toJson()]; +} + +/// Defines a camera move to a new bounding latitude and longitude range. +class CameraUpdateNewLatLngBounds extends CameraUpdate { + /// Creates a camera move to a bounding range. + const CameraUpdateNewLatLngBounds(this.bounds, this.padding) + : super._(CameraUpdateType.newLatLngBounds); + + /// The northeast and southwest bounding coordinates. + final LatLngBounds bounds; + + /// The amount of padding by which the view is inset. + final double padding; + @override + Object toJson() => ['newLatLngBounds', bounds.toJson(), padding]; +} + +/// Defines a camera move to new coordinates with a zoom level. +class CameraUpdateNewLatLngZoom extends CameraUpdate { + /// Creates a camera move with coordinates and zoom level. + const CameraUpdateNewLatLngZoom(this.latLng, this.zoom) + : super._(CameraUpdateType.newLatLngZoom); + + /// New coordinates of the camera. + final LatLng latLng; + + /// New zoom level of the camera. + final double zoom; + @override + Object toJson() => ['newLatLngZoom', latLng.toJson(), zoom]; +} + +/// Defines a camera scroll by a certain delta. +class CameraUpdateScrollBy extends CameraUpdate { + /// Creates a camera scroll. + const CameraUpdateScrollBy(this.dx, this.dy) + : super._(CameraUpdateType.scrollBy); + + /// Scroll delta x. + final double dx; + + /// Scroll delta y. + final double dy; + @override + Object toJson() => ['scrollBy', dx, dy]; +} + +/// Defines a relative camera zoom. +class CameraUpdateZoomBy extends CameraUpdate { + /// Creates a relative camera zoom. + const CameraUpdateZoomBy(this.amount, [this.focus]) + : super._(CameraUpdateType.zoomBy); + + /// Change in camera zoom amount. + final double amount; + + /// Optional point around which the zoom is focused. + final Offset? focus; + @override + Object toJson() => (focus == null) + ? ['zoomBy', amount] + : [ + 'zoomBy', + amount, + [focus!.dx, focus!.dy] + ]; +} + +/// Defines a camera zoom in. +class CameraUpdateZoomIn extends CameraUpdate { + /// Zooms in the camera. + const CameraUpdateZoomIn() : super._(CameraUpdateType.zoomIn); + @override + Object toJson() => ['zoomIn']; +} + +/// Defines a camera zoom out. +class CameraUpdateZoomOut extends CameraUpdate { + /// Zooms out the camera. + const CameraUpdateZoomOut() : super._(CameraUpdateType.zoomOut); + @override + Object toJson() => ['zoomOut']; +} + +/// Defines a camera zoom to an absolute zoom. +class CameraUpdateZoomTo extends CameraUpdate { + /// Creates a zoom to an absolute zoom level. + const CameraUpdateZoomTo(this.zoom) : super._(CameraUpdateType.zoomTo); + + /// New zoom level of the camera. + final double zoom; + @override + Object toJson() => ['zoomTo', zoom]; } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/cap.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/cap.dart index 3ca79583d12a..c67439e3e310 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/cap.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/cap.dart @@ -6,10 +6,39 @@ import 'package:flutter/foundation.dart' show immutable; import 'types.dart'; +/// Enumeration of possible types of caps. +enum CapType { + /// Cap that is squared off exactly at the start or end vertex of a [Polyline] + /// with solid stroke pattern, equivalent to having no additional cap beyond + /// the start or end vertex. + butt, + + /// Cap that is a semicircle with radius equal to half the stroke width, + /// centered at the start or end vertex of a [Polyline] with solid stroke + /// pattern. + round, + + /// Cap that is squared off after extending half the stroke width beyond the + /// start or end vertex of a [Polyline] with solid stroke pattern. + square, + + /// CustomCap with a bitmap overlay centered at the start or + /// end vertex of a [Polyline], orientated according to the direction of the line's + /// first or last edge and scaled with respect to the line's stroke width. + custom, +} + +String _capTypeToJson(CapType capType) => switch (capType) { + CapType.butt => 'buttCap', + CapType.round => 'roundCap', + CapType.square => 'squareCap', + CapType.custom => 'customCap', + }; + /// Cap that can be applied at the start or end vertex of a [Polyline]. @immutable class Cap { - const Cap._(this._json); + const Cap._(this.type); /// Cap that is squared off exactly at the start or end vertex of a [Polyline] /// with solid stroke pattern, equivalent to having no additional cap beyond @@ -17,16 +46,16 @@ class Cap { /// /// This is the default cap type at start and end vertices of Polylines with /// solid stroke pattern. - static const Cap buttCap = Cap._(['buttCap']); + static const Cap buttCap = Cap._(CapType.butt); /// Cap that is a semicircle with radius equal to half the stroke width, /// centered at the start or end vertex of a [Polyline] with solid stroke /// pattern. - static const Cap roundCap = Cap._(['roundCap']); + static const Cap roundCap = Cap._(CapType.round); /// Cap that is squared off after extending half the stroke width beyond the /// start or end vertex of a [Polyline] with solid stroke pattern. - static const Cap squareCap = Cap._(['squareCap']); + static const Cap squareCap = Cap._(CapType.square); /// Constructs a new CustomCap with a bitmap overlay centered at the start or /// end vertex of a [Polyline], orientated according to the direction of the line's @@ -44,11 +73,37 @@ class Cap { double refWidth = 10, }) { assert(refWidth > 0.0); - return Cap._(['customCap', bitmapDescriptor.toJson(), refWidth]); + return CustomCap(bitmapDescriptor, refWidth: refWidth); } - final Object _json; + /// The type of rendering used for the cap at a start or end vertex of a + /// [Polyline]. + final CapType type; /// Converts this object to something serializable in JSON. - Object toJson() => _json; + Object toJson() => [_capTypeToJson(type)]; +} + +/// CustomCap with a bitmap overlay centered at the start or +/// end vertex of a [Polyline], orientated according to the direction of the line's +/// first or last edge and scaled with respect to the line's stroke width. +class CustomCap extends Cap { + /// [bitmapDescriptor] must not be null. + /// + /// [refWidth] is the reference stroke width (in pixels) - the stroke width for which + /// the cap bitmap at its native dimension is designed. Must be positive. Default value + /// is 10 pixels. + const CustomCap(this.bitmapDescriptor, {this.refWidth = 10}) + : super._(CapType.custom); + + /// Bitmap overlay centered at the start or end vertex of a [Polyline]. + final BitmapDescriptor bitmapDescriptor; + + /// Reference stroke width in screen pixels. See + /// https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/CustomCap#refWidth + final double refWidth; + + @override + Object toJson() => + [_capTypeToJson(type), bitmapDescriptor.toJson(), refWidth]; } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/heatmap.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/heatmap.dart new file mode 100644 index 000000000000..41b4dcb2abc3 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/heatmap.dart @@ -0,0 +1,372 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/foundation.dart' + show immutable, listEquals, objectRuntimeType; +import 'package:flutter/material.dart' show Color; + +import 'types.dart'; + +/// Uniquely identifies a [Heatmap] among [GoogleMap] heatmaps. +/// +/// This does not have to be globally unique, only unique among the list. +@immutable +class HeatmapId extends MapsObjectId { + /// Creates an immutable identifier for a [Heatmap]. + const HeatmapId(super.value); +} + +/// A wrapper around platform specific behavior for the radius of a [Heatmap]. +/// +/// Currently this class only handles platform-specific values, but in the +/// future it may provide alternate constructors that abstract platform +/// differences in handling of heatmap radius values. +/// +/// See https://github.com/flutter/flutter/issues/145411 +/// +// TODO(stuartmorgan): Add constructor and enum field that informs the platform how to perform the conversion. +@immutable +class HeatmapRadius { + /// Create a [HeatmapRadius] with a radius in pixels. + /// + /// This value will be used verbatim on all platforms. It is up to the + /// developer to ensure that the value is appropriate for the platform. + const HeatmapRadius.fromPixels(this.radius); + + /// The platform-independent value of the radius. + final int radius; + + @override + bool operator ==(Object other) { + if (identical(this, other)) { + return true; + } + if (other.runtimeType != runtimeType) { + return false; + } + return other is HeatmapRadius && other.radius == radius; + } + + @override + int get hashCode => radius.hashCode; +} + +/// Draws a heatmap on the map. +@immutable +class Heatmap implements MapsObject { + /// Creates an immutable representation of a [Heatmap] to draw on + /// [GoogleMap]. + const Heatmap({ + required this.heatmapId, + required this.data, + this.dissipating = true, + this.gradient, + this.maxIntensity, + this.opacity = _defaultOpacity, + required this.radius, + this.minimumZoomIntensity = _defaultMinimumZoomIntensity, + this.maximumZoomIntensity = _defaultMaximumZoomIntensity, + }) : assert(opacity >= 0 && opacity <= 1); + + /// The default heatmap opacity as seen in the Google Maps SDKS: + /// - https://github.com/googlemaps/google-maps-ios-utils/blob/0e7ed81f1bbd9d29e4529c40ae39b0791b0a0eb8/src/Heatmap/GMUHeatmapTileLayer.m#L66 + /// - https://github.com/googlemaps/android-maps-utils/blob/2883d5d471bc04fa0e74f286b7c5beeac634df84/library/src/main/java/com/google/maps/android/heatmaps/HeatmapTileProvider.java#L49 + /// - https://developers.google.com/maps/documentation/javascript/reference/visualization#HeatmapLayerOptions.opacity + /// + /// The default on web is actually 0.6, but to maintain consistency with + /// iOS and Android, we use 0.7. + static const double _defaultOpacity = 0.7; + + /// The minimum and maximum zoom intensity values required to get iOS + /// heatmap rendering to match the other platforms. + /// + /// See: + /// - https://github.com/googlemaps/google-maps-ios-utils/issues/419 + /// - https://github.com/googlemaps/google-maps-ios-utils/issues/371 + /// + /// The values used are respectively the minimum and maximum zoom levels + /// supported by Google Maps. + static const int _defaultMinimumZoomIntensity = 0; + static const int _defaultMaximumZoomIntensity = 21; + + /// Uniquely identifies a [Heatmap]. + final HeatmapId heatmapId; + + @override + HeatmapId get mapsId => heatmapId; + + /// The data points to display. + /// + /// This list must not be empty. + final List data; + + /// Specifies whether the heatmap dissipate on zoom. + /// + /// By default, the radius of influence of a data point is specified by the + /// radius option only. When dissipating is disabled, the radius option is + /// interpreted as a radius at zoom level 0. + final bool dissipating; + + /// The color gradient of the heatmap + final HeatmapGradient? gradient; + + /// The maximum intensity of the heatmap. + /// + /// By default, heatmap colors are dynamically scaled according to the + /// greatest concentration of points at any particular pixel on the map. + /// This property allows you to specify a fixed maximum. + final double? maxIntensity; + + /// The opacity of the heatmap, expressed as a number between 0 and 1. + final double opacity; + + /// The radius of influence for each data point, in pixels. + final HeatmapRadius radius; + + /// The minimum zoom intensity used for normalizing intensities. + final int minimumZoomIntensity; + + /// The maximum zoom intensity used for normalizing intensities. + final int maximumZoomIntensity; + + /// Creates a new [Heatmap] object whose values are the same as this + /// instance, unless overwritten by the specified parameters. + Heatmap copyWith({ + List? dataParam, + bool? dissipatingParam, + HeatmapGradient? gradientParam, + double? maxIntensityParam, + double? opacityParam, + HeatmapRadius? radiusParam, + int? minimumZoomIntensityParam, + int? maximumZoomIntensityParam, + }) { + return Heatmap( + heatmapId: heatmapId, + data: dataParam ?? data, + dissipating: dissipatingParam ?? dissipating, + gradient: gradientParam ?? gradient, + maxIntensity: maxIntensityParam ?? maxIntensity, + opacity: opacityParam ?? opacity, + radius: radiusParam ?? radius, + minimumZoomIntensity: minimumZoomIntensityParam ?? minimumZoomIntensity, + maximumZoomIntensity: maximumZoomIntensityParam ?? maximumZoomIntensity, + ); + } + + /// Creates a new [Heatmap] object whose values are the same as this + /// instance. + @override + Heatmap clone() => copyWith( + dataParam: List.of(data), + gradientParam: gradient?.clone(), + ); + + /// Converts this object to something serializable in JSON. + @override + Object toJson() { + final Map json = {}; + + void addIfPresent(String fieldName, Object? value) { + if (value != null) { + json[fieldName] = value; + } + } + + addIfPresent('heatmapId', heatmapId.value); + addIfPresent('data', data.map((WeightedLatLng e) => e.toJson()).toList()); + addIfPresent('dissipating', dissipating); + addIfPresent('gradient', gradient?.toJson()); + addIfPresent('maxIntensity', maxIntensity); + addIfPresent('opacity', opacity); + addIfPresent('radius', radius.radius); + addIfPresent('minimumZoomIntensity', minimumZoomIntensity); + addIfPresent('maximumZoomIntensity', maximumZoomIntensity); + + return json; + } + + @override + bool operator ==(Object other) { + if (identical(this, other)) { + return true; + } + if (other.runtimeType != runtimeType) { + return false; + } + return other is Heatmap && + heatmapId == other.heatmapId && + listEquals(data, other.data) && + dissipating == other.dissipating && + gradient == other.gradient && + maxIntensity == other.maxIntensity && + opacity == other.opacity && + radius == other.radius && + minimumZoomIntensity == other.minimumZoomIntensity && + maximumZoomIntensity == other.maximumZoomIntensity; + } + + @override + int get hashCode => heatmapId.hashCode; +} + +/// A data point entry for a heatmap. +/// +/// This is a geographical data point with a weight attribute. +@immutable +class WeightedLatLng { + /// Creates a [WeightedLatLng] with the specified [weight] + const WeightedLatLng(this.point, {this.weight = 1.0}); + + /// The geographical data point. + final LatLng point; + + /// The weighting value of the data point. + final double weight; + + /// Converts this object to something serializable in JSON. + Object toJson() { + return [point.toJson(), weight]; + } + + @override + String toString() { + return '${objectRuntimeType(this, 'WeightedLatLng')}($point, $weight)'; + } + + @override + bool operator ==(Object other) { + return other is WeightedLatLng && + other.point == point && + other.weight == weight; + } + + @override + int get hashCode => Object.hash(point, weight); +} + +/// Represents a mapping of intensity to color. +/// +/// Interpolates between given set of intensity and color values to produce a +/// full mapping for the range [0, 1]. +@immutable +class HeatmapGradient { + /// Creates a new [HeatmapGradient] object. + const HeatmapGradient( + this.colors, { + this.colorMapSize = 256, + }); + + /// The gradient colors. + /// + /// Distributed along [startPoint]s or uniformly depending on the platform. + /// Must contain at least one color. + final List colors; + + /// Number of entries in the generated color map. + final int colorMapSize; + + /// Creates a new [HeatmapGradient] object whose values are the same as this + /// instance, unless overwritten by the specified parameters. + HeatmapGradient copyWith({ + List? colorsParam, + int? colorMapSizeParam, + }) { + return HeatmapGradient( + colorsParam ?? colors, + colorMapSize: colorMapSizeParam ?? colorMapSize, + ); + } + + /// Creates a new [HeatmapGradient] object whose values are the same as this + /// instance. + HeatmapGradient clone() => copyWith( + colorsParam: List.of(colors), + ); + + /// Converts this object to something serializable in JSON. + Object toJson() { + final Map json = {}; + + void addIfPresent(String fieldName, Object? value) { + if (value != null) { + json[fieldName] = value; + } + } + + addIfPresent('colors', + colors.map((HeatmapGradientColor e) => e.color.value).toList()); + addIfPresent('startPoints', + colors.map((HeatmapGradientColor e) => e.startPoint).toList()); + addIfPresent('colorMapSize', colorMapSize); + + return json; + } + + @override + bool operator ==(Object other) { + if (identical(this, other)) { + return true; + } + if (other.runtimeType != runtimeType) { + return false; + } + return other is HeatmapGradient && + listEquals(colors, other.colors) && + colorMapSize == other.colorMapSize; + } + + @override + int get hashCode => Object.hash(colors, colorMapSize); +} + +/// A [Color] with a [startPoint] for use in a [HeatmapGradient]. +@immutable +class HeatmapGradientColor { + /// Creates a new [HeatmapGradientColor] object. + const HeatmapGradientColor(this.color, this.startPoint); + + /// The color for this portion of the gradient. + final Color color; + + /// The start point of this color. + final double startPoint; + + /// Creates a new [HeatmapGradientColor] object whose values are the same as + /// this instance, unless overwritten by the specified parameters. + HeatmapGradientColor copyWith({ + Color? colorParam, + double? startPointParam, + }) { + return HeatmapGradientColor( + colorParam ?? color, + startPointParam ?? startPoint, + ); + } + + /// Creates a new [HeatmapGradientColor] object whose values are the same as + /// this instance. + HeatmapGradientColor clone() => copyWith(); + + @override + bool operator ==(Object other) { + if (identical(this, other)) { + return true; + } + if (other.runtimeType != runtimeType) { + return false; + } + return other is HeatmapGradientColor && + color == other.color && + startPoint == other.startPoint; + } + + @override + int get hashCode => Object.hash(color, startPoint); + + @override + String toString() { + return '${objectRuntimeType(this, 'HeatmapGradientColor')}($color, $startPoint)'; + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/heatmap_updates.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/heatmap_updates.dart new file mode 100644 index 000000000000..bd74c6301fc3 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/heatmap_updates.dart @@ -0,0 +1,26 @@ +// 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 'types.dart'; + +/// [Heatmap] update events to be applied to the [GoogleMap]. +/// +/// Used in [GoogleMapController] when the map is updated. +// (Do not re-export) +class HeatmapUpdates extends MapsObjectUpdates { + /// Computes [HeatmapUpdates] given previous and current [Heatmap]s. + HeatmapUpdates.from( + super.previous, + super.current, + ) : super.from(objectName: 'heatmap'); + + /// Set of Heatmaps to be added in this update. + Set get heatmapsToAdd => objectsToAdd; + + /// Set of Heatmaps to be removed in this update. + Set get heatmapIdsToRemove => objectIdsToRemove.cast(); + + /// Set of Heatmaps to be changed in this update. + Set get heatmapsToChange => objectsToChange; +} diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/map_objects.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/map_objects.dart index 009a6a078268..23d605c43eff 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/map_objects.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/map_objects.dart @@ -20,6 +20,7 @@ class MapObjects { this.polygons = const {}, this.polylines = const {}, this.circles = const {}, + this.heatmaps = const {}, this.tileOverlays = const {}, this.clusterManagers = const {}, }); @@ -28,6 +29,7 @@ class MapObjects { final Set polygons; final Set polylines; final Set circles; + final Set heatmaps; final Set tileOverlays; final Set clusterManagers; } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/pattern_item.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/pattern_item.dart index 033210b8c5ae..90adfbc84c6a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/pattern_item.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/pattern_item.dart @@ -4,20 +4,39 @@ import 'package:flutter/foundation.dart' show immutable; +/// Enumeration of types of pattern items. +enum PatternItemType { + /// A dot used in the stroke pattern for a [Polyline]. + dot, + + /// A dash used in the stroke pattern for a [Polyline]. + dash, + + /// A gap used in the stroke pattern for a [Polyline]. + gap, +} + +String _patternItemTypeToJson(PatternItemType itemType) => switch (itemType) { + PatternItemType.dot => 'dot', + PatternItemType.dash => 'dash', + PatternItemType.gap => 'gap', + }; + /// Item used in the stroke pattern for a Polyline. @immutable class PatternItem { - const PatternItem._(this._json); + const PatternItem._(this.type); /// A dot used in the stroke pattern for a [Polyline]. - static const PatternItem dot = PatternItem._(['dot']); + static const PatternItem dot = PatternItem._(PatternItemType.dot); /// A dash used in the stroke pattern for a [Polyline]. /// /// [length] has to be non-negative. static PatternItem dash(double length) { assert(length >= 0.0); - return PatternItem._(['dash', length]); + return VariableLengthPatternItem._( + patternItemType: PatternItemType.dash, length: length); } /// A gap used in the stroke pattern for a [Polyline]. @@ -25,11 +44,33 @@ class PatternItem { /// [length] has to be non-negative. static PatternItem gap(double length) { assert(length >= 0.0); - return PatternItem._(['gap', length]); + return VariableLengthPatternItem._( + patternItemType: PatternItemType.gap, length: length); } - final Object _json; + /// The type of rendering used for an item in a pattern. + final PatternItemType type; + + /// Converts this object to something serializable in JSON. + Object toJson() => [ + _patternItemTypeToJson(type), + ]; +} + +/// A pattern item with a length, i.e. a dash or gap. +@immutable +class VariableLengthPatternItem extends PatternItem { + const VariableLengthPatternItem._( + {required PatternItemType patternItemType, required this.length}) + : super._(patternItemType); + + /// The length in pixels of a dash or gap. + final double length; /// Converts this object to something serializable in JSON. - Object toJson() => _json; + @override + Object toJson() => [ + _patternItemTypeToJson(type), + length, + ]; } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline.dart index d526375cfca3..e590671419e6 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline.dart @@ -96,7 +96,7 @@ class Polyline implements MapsObject { /// Supported on Android only. final Cap endCap; - /// True if the marker is visible. + /// True if the polyline is visible. final bool visible; /// Width of the polyline, used to define the width of the line segment to be drawn. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart index 3ef0e4ab18b5..745e300ff05c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart @@ -12,6 +12,8 @@ export 'circle_updates.dart'; export 'cluster.dart'; export 'cluster_manager.dart'; export 'cluster_manager_updates.dart'; +export 'heatmap.dart'; +export 'heatmap_updates.dart'; export 'joint_type.dart'; export 'location.dart'; export 'map_configuration.dart'; @@ -34,6 +36,7 @@ export 'ui.dart'; // Export the utils used by the Widget export 'utils/circle.dart'; export 'utils/cluster_manager.dart'; +export 'utils/heatmap.dart'; export 'utils/marker.dart'; export 'utils/polygon.dart'; export 'utils/polyline.dart'; diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/heatmap.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/heatmap.dart new file mode 100644 index 000000000000..ff6e7944601f --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/heatmap.dart @@ -0,0 +1,19 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import '../types.dart'; +import 'maps_object.dart'; + +/// Converts an [Iterable] of Heatmaps in a Map of +/// HeatmapId -> Heatmap. +Map keyByHeatmapId( + Iterable heatmaps, +) { + return keyByMapsObjectId(heatmaps).cast(); +} + +/// Converts a Set of Heatmaps into something serializable in JSON. +Object serializeHeatmapSet(Set heatmaps) { + return serializeMapsObjectSet(heatmaps); +} 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 e9d672efb1c2..67e6a64f1c0f 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 @@ -4,11 +4,11 @@ repository: https://github.com/flutter/packages/tree/main/packages/google_maps_f issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22 # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.8.0 +version: 2.9.5 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: collection: ^1.15.0 @@ -21,7 +21,7 @@ dev_dependencies: async: ^2.5.0 flutter_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 topics: - google-maps diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/bitmap_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/bitmap_test.dart index 15a6833e9354..001dbe755e3b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/bitmap_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/bitmap_test.dart @@ -21,10 +21,17 @@ void main() { BitmapDescriptor.fromJson(json); expect(descriptorFromJson, isNot(descriptor)); // New instance - expect(identical(descriptorFromJson.toJson(), json), isTrue); // Same JSON + expect(descriptorFromJson.toJson(), json); }); group('fromBytes constructor', () { + test('returns BytesBitmap', () { + final BitmapDescriptor descriptor = BitmapDescriptor.fromBytes( + Uint8List.fromList([1, 2, 3]), + ); + expect(descriptor, isA()); + }); + test('with empty byte array, throws assertion error', () { expect(() { BitmapDescriptor.fromBytes(Uint8List.fromList([])); @@ -35,13 +42,15 @@ void main() { final BitmapDescriptor descriptor = BitmapDescriptor.fromBytes( Uint8List.fromList([1, 2, 3]), ); - expect(descriptor, isA()); + expect(descriptor, isA()); expect( descriptor.toJson(), equals([ 'fromBytes', [1, 2, 3], ])); + descriptor as BytesBitmap; + expect(descriptor.byteData, Uint8List.fromList([1, 2, 3])); }); test('with size, not on the web, size is ignored', () { @@ -56,6 +65,9 @@ void main() { 'fromBytes', [1, 2, 3], ])); + descriptor as BytesBitmap; + expect(descriptor.byteData, Uint8List.fromList([1, 2, 3])); + expect(descriptor.size, null); }, skip: kIsWeb); test('with size, on the web, size is preserved', () { @@ -71,6 +83,9 @@ void main() { [1, 2, 3], [40, 20], ])); + descriptor as BytesBitmap; + expect(descriptor.byteData, Uint8List.fromList([1, 2, 3])); + expect(descriptor.size, const Size(40, 20)); }, skip: !kIsWeb); }); @@ -78,7 +93,7 @@ void main() { group('type validation', () { test('correct type', () { expect(BitmapDescriptor.fromJson(['defaultMarker']), - isA()); + isA()); }); test('wrong type', () { @@ -90,12 +105,12 @@ void main() { group('defaultMarker', () { test('hue is null', () { expect(BitmapDescriptor.fromJson(['defaultMarker']), - isA()); + isA()); }); test('hue is number', () { expect(BitmapDescriptor.fromJson(['defaultMarker', 158]), - isA()); + isA()); }); test('hue is not number', () { @@ -120,7 +135,7 @@ void main() { 'fromBytes', Uint8List.fromList([1, 2, 3]) ]), - isA()); + isA()); }); test('without bytes', () { @@ -137,7 +152,7 @@ void main() { expect( BitmapDescriptor.fromJson( ['fromAsset', 'some/path.png']), - isA()); + isA()); }); test('name cannot be null or empty', () { @@ -153,7 +168,7 @@ void main() { expect( BitmapDescriptor.fromJson( ['fromAsset', 'some/path.png', 'some_package']), - isA()); + isA()); }); test('package cannot be null or empty', () { @@ -172,7 +187,7 @@ void main() { expect( BitmapDescriptor.fromJson( ['fromAssetImage', 'some/path.png', 1.0]), - isA()); + isA()); }); test('mipmaps determines dpi', () async { @@ -224,7 +239,7 @@ void main() { 1.0, [640, 480] ]), - isA()); + isA()); }); test( @@ -262,7 +277,7 @@ void main() { 'height': 1.0, } ]), - isA()); + isA()); }); test('without bytes', () { @@ -288,7 +303,7 @@ void main() { 'imagePixelRatio': 1.0, } ]), - isA()); + isA()); }); test('name cannot be null or empty', () { @@ -345,7 +360,7 @@ void main() { 'height': 1.0, } ]), - isA()); + isA()); }); test('optional width and height parameters must be in proper format', @@ -428,6 +443,10 @@ void main() { 'imagePixelRatio': 1.0, } ])); + descriptor as AssetMapBitmap; + expect(descriptor.assetName, 'red_square.png'); + expect(descriptor.bitmapScaling, MapBitmapScaling.auto); + expect(descriptor.imagePixelRatio, 1.0); }); test('construct with imagePixelRatio', () async { @@ -435,6 +454,7 @@ void main() { AssetMapBitmap('red_square.png', imagePixelRatio: 1.2345); expect(descriptor, isA()); + expect(descriptor, isA()); expect( descriptor.toJson(), equals([ @@ -445,6 +465,10 @@ void main() { 'imagePixelRatio': 1.2345, } ])); + descriptor as AssetMapBitmap; + expect(descriptor.assetName, 'red_square.png'); + expect(descriptor.bitmapScaling, MapBitmapScaling.auto); + expect(descriptor.imagePixelRatio, 1.2345); }); test('construct with width', () async { @@ -453,6 +477,7 @@ void main() { AssetMapBitmap('red_square.png', width: width); expect(descriptor, isA()); + expect(descriptor, isA()); expect( descriptor.toJson(), equals([ @@ -464,6 +489,11 @@ void main() { 'width': width, } ])); + descriptor as AssetMapBitmap; + expect(descriptor.assetName, 'red_square.png'); + expect(descriptor.bitmapScaling, MapBitmapScaling.auto); + expect(descriptor.imagePixelRatio, 1.0); + expect(descriptor.width, width); }); test('create', () async { @@ -481,6 +511,10 @@ void main() { 'imagePixelRatio': 1.0 } ])); + descriptor as AssetMapBitmap; + expect(descriptor.assetName, 'red_square.png'); + expect(descriptor.bitmapScaling, MapBitmapScaling.auto); + expect(descriptor.imagePixelRatio, 1.0); }, // TODO(stuartmorgan): Investigate timeout on web. skip: kIsWeb); @@ -493,6 +527,7 @@ void main() { await AssetMapBitmap.create(imageConfiguration, 'red_square.png'); expect(descriptor, isA()); + expect(descriptor, isA()); expect( descriptor.toJson(), equals([ @@ -505,7 +540,14 @@ void main() { 'height': 200.0 } ])); + descriptor as AssetMapBitmap; + expect(descriptor.assetName, 'red_square.png'); + expect(descriptor.bitmapScaling, MapBitmapScaling.auto); + expect(descriptor.imagePixelRatio, 1.0); + expect(descriptor.width, 100.0); + expect(descriptor.height, 200.0); }); + test('create with width', () async { const ImageConfiguration imageConfiguration = ImageConfiguration.empty; final BitmapDescriptor descriptor = await AssetMapBitmap.create( @@ -513,6 +555,7 @@ void main() { width: 100); expect(descriptor, isA()); + expect(descriptor, isA()); expect( descriptor.toJson(), equals([ @@ -524,7 +567,13 @@ void main() { 'width': 100.0, } ])); + descriptor as AssetMapBitmap; + expect(descriptor.assetName, 'red_square.png'); + expect(descriptor.bitmapScaling, MapBitmapScaling.auto); + expect(descriptor.imagePixelRatio, 1.0); + expect(descriptor.width, 100.0); }); + test('create with height', () async { const ImageConfiguration imageConfiguration = ImageConfiguration.empty; final BitmapDescriptor descriptor = await AssetMapBitmap.create( @@ -532,6 +581,7 @@ void main() { height: 200); expect(descriptor, isA()); + expect(descriptor, isA()); expect( descriptor.toJson(), equals([ @@ -543,6 +593,11 @@ void main() { 'height': 200.0 } ])); + descriptor as AssetMapBitmap; + expect(descriptor.assetName, 'red_square.png'); + expect(descriptor.bitmapScaling, MapBitmapScaling.auto); + expect(descriptor.imagePixelRatio, 1.0); + expect(descriptor.height, 200.0); }); }, // TODO(stuartmorgan): Investigate timeout on web. @@ -560,6 +615,7 @@ void main() { Uint8List.fromList([1, 2, 3]), ); expect(descriptor, isA()); + expect(descriptor, isA()); expect( descriptor.toJson(), equals([ @@ -570,6 +626,10 @@ void main() { 'imagePixelRatio': 1.0, } ])); + descriptor as BytesMapBitmap; + expect(descriptor.byteData, Uint8List.fromList([1, 2, 3])); + expect(descriptor.bitmapScaling, MapBitmapScaling.auto); + expect(descriptor.imagePixelRatio, 1.0); }); test('construct with width', () { @@ -579,6 +639,7 @@ void main() { width: width, ); + expect(descriptor, isA()); expect( descriptor.toJson(), equals([ @@ -590,6 +651,11 @@ void main() { 'width': 100.0 } ])); + descriptor as BytesMapBitmap; + expect(descriptor.byteData, Uint8List.fromList([1, 2, 3])); + expect(descriptor.bitmapScaling, MapBitmapScaling.auto); + expect(descriptor.imagePixelRatio, 1.0); + expect(descriptor.width, 100.0); }); test('construct with imagePixelRatio', () { @@ -598,6 +664,7 @@ void main() { imagePixelRatio: 1.2345, ); + expect(descriptor, isA()); expect( descriptor.toJson(), equals([ @@ -608,6 +675,16 @@ void main() { 'imagePixelRatio': 1.2345 } ])); + descriptor as BytesMapBitmap; + expect(descriptor.byteData, Uint8List.fromList([1, 2, 3])); + expect(descriptor.bitmapScaling, MapBitmapScaling.auto); + expect(descriptor.imagePixelRatio, 1.2345); }); }); + + test('mapBitmapScaling from String', () { + expect(mapBitmapScalingFromString('auto'), MapBitmapScaling.auto); + expect(mapBitmapScalingFromString('none'), MapBitmapScaling.none); + expect(() => mapBitmapScalingFromString('invalid'), throwsArgumentError); + }); } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart index 70e57aa67ac9..4c4214b2609a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart @@ -20,4 +20,98 @@ void main() { expect(cameraPosition, cameraPositionFromJson); }); + + test('CameraUpdate.newCameraPosition', () { + const CameraPosition cameraPosition = CameraPosition( + target: LatLng(10.0, 15.0), bearing: 0.5, tilt: 30.0, zoom: 1.5); + final CameraUpdate cameraUpdate = + CameraUpdate.newCameraPosition(cameraPosition); + expect(cameraUpdate.runtimeType, CameraUpdateNewCameraPosition); + expect(cameraUpdate.updateType, CameraUpdateType.newCameraPosition); + cameraUpdate as CameraUpdateNewCameraPosition; + expect(cameraUpdate.cameraPosition, cameraPosition); + final List jsonList = cameraUpdate.toJson() as List; + expect(jsonList[0], 'newCameraPosition'); + }); + + test('CameraUpdate.newLatLng', () { + const LatLng latLng = LatLng(1.0, 2.0); + final CameraUpdate cameraUpdate = CameraUpdate.newLatLng(latLng); + expect(cameraUpdate.runtimeType, CameraUpdateNewLatLng); + expect(cameraUpdate.updateType, CameraUpdateType.newLatLng); + cameraUpdate as CameraUpdateNewLatLng; + expect(cameraUpdate.latLng, latLng); + final List jsonList = cameraUpdate.toJson() as List; + expect(jsonList[0], 'newLatLng'); + }); + + test('CameraUpdate.newLatLngBounds', () { + final LatLngBounds latLngBounds = LatLngBounds( + northeast: const LatLng(1.0, 2.0), southwest: const LatLng(-2.0, -3.0)); + const double padding = 1.0; + final CameraUpdate cameraUpdate = + CameraUpdate.newLatLngBounds(latLngBounds, padding); + expect(cameraUpdate.runtimeType, CameraUpdateNewLatLngBounds); + expect(cameraUpdate.updateType, CameraUpdateType.newLatLngBounds); + cameraUpdate as CameraUpdateNewLatLngBounds; + expect(cameraUpdate.bounds, latLngBounds); + expect(cameraUpdate.padding, padding); + final List jsonList = cameraUpdate.toJson() as List; + expect(jsonList[0], 'newLatLngBounds'); + }); + + test('CameraUpdate.newLatLngZoom', () { + const LatLng latLng = LatLng(1.0, 2.0); + const double zoom = 2.0; + final CameraUpdate cameraUpdate = CameraUpdate.newLatLngZoom(latLng, zoom); + expect(cameraUpdate.runtimeType, CameraUpdateNewLatLngZoom); + expect(cameraUpdate.updateType, CameraUpdateType.newLatLngZoom); + cameraUpdate as CameraUpdateNewLatLngZoom; + expect(cameraUpdate.latLng, latLng); + expect(cameraUpdate.zoom, zoom); + final List jsonList = cameraUpdate.toJson() as List; + expect(jsonList[0], 'newLatLngZoom'); + }); + + test('CameraUpdate.scrollBy', () { + const double dx = 2.0; + const double dy = 5.0; + final CameraUpdate cameraUpdate = CameraUpdate.scrollBy(dx, dy); + expect(cameraUpdate.runtimeType, CameraUpdateScrollBy); + expect(cameraUpdate.updateType, CameraUpdateType.scrollBy); + cameraUpdate as CameraUpdateScrollBy; + expect(cameraUpdate.dx, dx); + expect(cameraUpdate.dy, dy); + final List jsonList = cameraUpdate.toJson() as List; + expect(jsonList[0], 'scrollBy'); + }); + + test('CameraUpdate.zoomBy', () { + const double amount = 1.5; + const Offset focus = Offset(-1.0, -2.0); + final CameraUpdate cameraUpdate = CameraUpdate.zoomBy(amount, focus); + expect(cameraUpdate.runtimeType, CameraUpdateZoomBy); + expect(cameraUpdate.updateType, CameraUpdateType.zoomBy); + cameraUpdate as CameraUpdateZoomBy; + expect(cameraUpdate.amount, amount); + expect(cameraUpdate.focus, focus); + final List jsonList = cameraUpdate.toJson() as List; + expect(jsonList[0], 'zoomBy'); + }); + + test('CameraUpdate.zoomIn', () { + final CameraUpdate cameraUpdate = CameraUpdate.zoomIn(); + expect(cameraUpdate.runtimeType, CameraUpdateZoomIn); + expect(cameraUpdate.updateType, CameraUpdateType.zoomIn); + final List jsonList = cameraUpdate.toJson() as List; + expect(jsonList[0], 'zoomIn'); + }); + + test('CameraUpdate.zoomOut', () { + final CameraUpdate cameraUpdate = CameraUpdate.zoomOut(); + expect(cameraUpdate.runtimeType, CameraUpdateZoomOut); + expect(cameraUpdate.updateType, CameraUpdateType.zoomOut); + final List jsonList = cameraUpdate.toJson() as List; + expect(jsonList[0], 'zoomOut'); + }); } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/cap_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/cap_test.dart new file mode 100644 index 000000000000..bdd94018f9a4 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/cap_test.dart @@ -0,0 +1,48 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + test('buttCap', () { + const Cap cap = Cap.buttCap; + expect(cap.toJson(), equals(['buttCap'])); + }); + + test('roundCap', () { + const Cap cap = Cap.roundCap; + expect(cap.toJson(), equals(['roundCap'])); + }); + + test('squareCap', () { + const Cap cap = Cap.squareCap; + expect(cap.toJson(), equals(['squareCap'])); + }); + + test('customCap', () { + final Cap cap = Cap.customCapFromBitmap(BitmapDescriptor.defaultMarker); + expect( + cap.toJson(), + equals([ + 'customCap', + ['defaultMarker'], + 10.0 + ])); + }); + + test('customCapWithWidth', () { + final Cap cap = + Cap.customCapFromBitmap(BitmapDescriptor.defaultMarker, refWidth: 100); + expect( + cap.toJson(), + equals([ + 'customCap', + ['defaultMarker'], + 100.0 + ])); + }); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/heatmap_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/heatmap_test.dart new file mode 100644 index 000000000000..bc7d779d00ad --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/heatmap_test.dart @@ -0,0 +1,402 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group('$HeatmapRadius', () { + test('fromPixels', () { + const HeatmapRadius radius = HeatmapRadius.fromPixels(10); + expect(radius.radius, 10); + }); + + test('==', () { + const HeatmapRadius radius1 = HeatmapRadius.fromPixels(10); + const HeatmapRadius radius2 = HeatmapRadius.fromPixels(10); + const HeatmapRadius radius3 = HeatmapRadius.fromPixels(20); + expect(radius1, radius2); + expect(radius1, isNot(radius3)); + }); + + test('hashCode', () { + const int radius = 10; + const HeatmapRadius heatmapRadius = HeatmapRadius.fromPixels(radius); + expect(heatmapRadius.hashCode, radius.hashCode); + }); + }); + + group('$Heatmap', () { + test('constructor defaults', () { + const HeatmapId id = HeatmapId('heatmap'); + const List data = [ + WeightedLatLng(LatLng(1, 1)), + ]; + const HeatmapRadius radius = HeatmapRadius.fromPixels(10); + const Heatmap heatmap = Heatmap( + heatmapId: id, + data: data, + radius: radius, + ); + + expect(heatmap.heatmapId, id); + expect(heatmap.data, data); + expect(heatmap.dissipating, true); + expect(heatmap.gradient, null); + expect(heatmap.maxIntensity, null); + expect(heatmap.opacity, 0.7); + expect(heatmap.radius, radius); + expect(heatmap.minimumZoomIntensity, 0); + expect(heatmap.maximumZoomIntensity, 21); + + expect(heatmap.heatmapId, heatmap.mapsId); + }); + + test('construct with values', () { + const HeatmapId id = HeatmapId('heatmap'); + const List data = [ + WeightedLatLng(LatLng(1, 1)), + ]; + const HeatmapGradient gradient = HeatmapGradient([ + HeatmapGradientColor(Colors.red, 0.0), + ]); + const double maxIntensity = 1.0; + const double opacity = 0.5; + const HeatmapRadius radius = HeatmapRadius.fromPixels(10); + const int minimumZoomIntensity = 1; + const int maximumZoomIntensity = 20; + const Heatmap heatmap = Heatmap( + heatmapId: id, + data: data, + dissipating: false, + gradient: gradient, + maxIntensity: maxIntensity, + opacity: opacity, + radius: radius, + minimumZoomIntensity: minimumZoomIntensity, + maximumZoomIntensity: maximumZoomIntensity, + ); + + expect(heatmap.heatmapId, id); + expect(heatmap.data, data); + expect(heatmap.dissipating, false); + expect(heatmap.gradient, gradient); + expect(heatmap.maxIntensity, maxIntensity); + expect(heatmap.opacity, opacity); + expect(heatmap.radius, radius); + expect(heatmap.minimumZoomIntensity, minimumZoomIntensity); + expect(heatmap.maximumZoomIntensity, maximumZoomIntensity); + }); + + test('copyWith', () { + const Heatmap heatmap1 = Heatmap( + heatmapId: HeatmapId('heatmap'), + data: [], + radius: HeatmapRadius.fromPixels(10), + ); + + const List data = [ + WeightedLatLng(LatLng(1, 1)), + ]; + const HeatmapGradient gradient = HeatmapGradient([ + HeatmapGradientColor(Colors.red, 0.0), + ]); + const double maxIntensity = 1.0; + const double opacity = 0.5; + const HeatmapRadius radius = HeatmapRadius.fromPixels(20); + const int minimumZoomIntensity = 1; + const int maximumZoomIntensity = 20; + + final Heatmap heatmap2 = heatmap1.copyWith( + dataParam: data, + dissipatingParam: false, + gradientParam: gradient, + maxIntensityParam: maxIntensity, + opacityParam: opacity, + radiusParam: radius, + minimumZoomIntensityParam: minimumZoomIntensity, + maximumZoomIntensityParam: maximumZoomIntensity, + ); + + expect(heatmap2.heatmapId, heatmap1.heatmapId); + expect(heatmap2.data, data); + expect(heatmap2.dissipating, false); + expect(heatmap2.gradient, gradient); + expect(heatmap2.maxIntensity, maxIntensity); + expect(heatmap2.opacity, opacity); + expect(heatmap2.radius, radius); + expect(heatmap2.minimumZoomIntensity, minimumZoomIntensity); + }); + + test('clone', () { + const Heatmap heatmap1 = Heatmap( + heatmapId: HeatmapId('heatmap'), + data: [], + radius: HeatmapRadius.fromPixels(10), + ); + + final Heatmap heatmap2 = heatmap1.clone(); + + expect(heatmap2, heatmap1); + }); + + test('==', () { + const HeatmapId id = HeatmapId('heatmap'); + const List data = [ + WeightedLatLng(LatLng(1, 1)), + ]; + const HeatmapRadius radius = HeatmapRadius.fromPixels(10); + const Heatmap heatmap1 = Heatmap( + heatmapId: id, + data: data, + radius: radius, + ); + const Heatmap heatmap2 = Heatmap( + heatmapId: id, + data: data, + radius: radius, + ); + const Heatmap heatmap3 = Heatmap( + heatmapId: id, + data: data, + radius: HeatmapRadius.fromPixels(20), + ); + + expect(heatmap1, heatmap2); + expect(heatmap1, isNot(heatmap3)); + }); + + test('hashCode', () { + const HeatmapId id = HeatmapId('heatmap'); + const Heatmap heatmap = Heatmap( + heatmapId: id, + data: [], + radius: HeatmapRadius.fromPixels(10), + ); + + expect(heatmap.hashCode, id.hashCode); + }); + }); + + group('$WeightedLatLng', () { + test('constructor defaults', () { + const LatLng point = LatLng(1, 1); + const WeightedLatLng wll = WeightedLatLng(point); + + expect(wll.point, point); + expect(wll.weight, 1.0); + }); + + test('construct with values', () { + const LatLng point = LatLng(1, 1); + const double weight = 2.0; + const WeightedLatLng wll = WeightedLatLng(point, weight: weight); + + expect(wll.point, point); + expect(wll.weight, weight); + }); + + test('toJson', () { + const LatLng point = LatLng(1, 1); + const double weight = 2.0; + const WeightedLatLng wll = WeightedLatLng(point, weight: weight); + + expect(wll.toJson(), [ + [point.latitude, point.longitude], + weight, + ]); + }); + + test('toString', () { + const LatLng point = LatLng(1, 1); + const double weight = 2.0; + const WeightedLatLng wll = WeightedLatLng(point, weight: weight); + + expect(wll.toString(), 'WeightedLatLng($point, $weight)'); + }); + + test('==', () { + const LatLng point = LatLng(1, 1); + const double weight = 2.0; + const WeightedLatLng wll1 = WeightedLatLng(point, weight: weight); + const WeightedLatLng wll2 = WeightedLatLng(point, weight: weight); + const WeightedLatLng wll3 = WeightedLatLng(point, weight: 3.0); + + expect(wll1, wll2); + expect(wll1, isNot(wll3)); + }); + + test('hashCode', () { + const LatLng point = LatLng(1, 1); + const double weight = 2.0; + const WeightedLatLng wll = WeightedLatLng(point, weight: weight); + + expect(wll.hashCode, Object.hash(point, weight)); + }); + }); + + group('$HeatmapGradient', () { + test('constructor defaults', () { + const List colors = [ + HeatmapGradientColor(Colors.red, 0.0), + ]; + const HeatmapGradient gradient = HeatmapGradient(colors); + + expect(gradient.colors, colors); + expect(gradient.colorMapSize, 256); + }); + + test('construct with values', () { + const List colors = [ + HeatmapGradientColor(Colors.red, 0.0), + ]; + const int colorMapSize = 512; + const HeatmapGradient gradient = + HeatmapGradient(colors, colorMapSize: colorMapSize); + + expect(gradient.colors, colors); + expect(gradient.colorMapSize, colorMapSize); + }); + + test('copyWith', () { + const HeatmapGradient gradient1 = HeatmapGradient([ + HeatmapGradientColor(Colors.red, 0.0), + ]); + + const List colors = [ + HeatmapGradientColor(Colors.blue, 0.0), + ]; + const int colorMapSize = 512; + final HeatmapGradient gradient2 = gradient1.copyWith( + colorsParam: colors, + colorMapSizeParam: colorMapSize, + ); + + expect(gradient2.colors, colors); + expect(gradient2.colorMapSize, colorMapSize); + }); + + test('clone', () { + const HeatmapGradient gradient1 = HeatmapGradient( + [HeatmapGradientColor(Colors.red, 0.0)], + colorMapSize: 512, + ); + + final HeatmapGradient gradient2 = gradient1.clone(); + expect(gradient2, gradient1); + }); + + test('toJson', () { + const List colors = [ + HeatmapGradientColor(Colors.red, 0.0), + ]; + const int colorMapSize = 512; + const HeatmapGradient gradient = + HeatmapGradient(colors, colorMapSize: colorMapSize); + + expect(gradient.toJson(), { + 'colors': + colors.map((HeatmapGradientColor e) => e.color.value).toList(), + 'startPoints': + colors.map((HeatmapGradientColor e) => e.startPoint).toList(), + 'colorMapSize': colorMapSize, + }); + }); + + test('==', () { + const List colors = [ + HeatmapGradientColor(Colors.red, 0.0), + ]; + const HeatmapGradient gradient1 = HeatmapGradient(colors); + const HeatmapGradient gradient2 = HeatmapGradient(colors); + const HeatmapGradient gradient3 = HeatmapGradient( + [HeatmapGradientColor(Colors.blue, 0.0)], + colorMapSize: 512); + + expect(gradient1, gradient2); + expect(gradient1, isNot(gradient3)); + }); + + test('hashCode', () { + const List colors = [ + HeatmapGradientColor(Colors.red, 0.0), + ]; + const int colorMapSize = 512; + const HeatmapGradient gradient = + HeatmapGradient(colors, colorMapSize: colorMapSize); + + expect(gradient.hashCode, Object.hash(colors, colorMapSize)); + }); + }); + + group('$HeatmapGradientColor', () { + test('construct with values', () { + const Color color = Colors.red; + const double startPoint = 0.0; + const HeatmapGradientColor gradientColor = + HeatmapGradientColor(color, startPoint); + + expect(gradientColor.color, color); + expect(gradientColor.startPoint, startPoint); + }); + + test('copyWith', () { + const HeatmapGradientColor gradientColor1 = + HeatmapGradientColor(Colors.red, 0.0); + + const Color color = Colors.blue; + const double startPoint = 0.5; + final HeatmapGradientColor gradientColor2 = gradientColor1.copyWith( + colorParam: color, + startPointParam: startPoint, + ); + + expect(gradientColor2.color, color); + expect(gradientColor2.startPoint, startPoint); + }); + + test('clone', () { + const HeatmapGradientColor gradientColor1 = + HeatmapGradientColor(Colors.red, 0.0); + + final HeatmapGradientColor gradientColor2 = gradientColor1.clone(); + expect(gradientColor2, gradientColor1); + }); + + test('==', () { + const HeatmapGradientColor gradientColor1 = + HeatmapGradientColor(Colors.red, 0.0); + const HeatmapGradientColor gradientColor2 = + HeatmapGradientColor(Colors.red, 0.0); + const HeatmapGradientColor gradientColor3 = + HeatmapGradientColor(Colors.blue, 0.0); + + expect(gradientColor1, gradientColor2); + expect(gradientColor1, isNot(gradientColor3)); + }); + + test('hashCode', () { + const HeatmapGradientColor gradientColor = + HeatmapGradientColor(Colors.red, 0.0); + + expect( + gradientColor.hashCode, + Object.hash(gradientColor.color, gradientColor.startPoint), + ); + }); + + test('toString', () { + const HeatmapGradientColor gradientColor = + HeatmapGradientColor(Colors.red, 0.0); + + expect( + gradientColor.toString(), + 'HeatmapGradientColor(${gradientColor.color}, ${gradientColor.startPoint})', + ); + }); + }); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/pattern_item_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/pattern_item_test.dart new file mode 100644 index 000000000000..ebd65a44f3ff --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/pattern_item_test.dart @@ -0,0 +1,27 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + test('dot', () { + const PatternItem item = PatternItem.dot; + expect(item.toJson(), equals(['dot'])); + }); + + test('dash', () { + final PatternItem item = PatternItem.dash(10.0); + expect(item, isA()); + expect(item.toJson(), equals(['dash', 10.0])); + }); + + test('gap', () { + final PatternItem item = PatternItem.gap(20.0); + expect(item, isA()); + expect(item.toJson(), equals(['gap', 20.0])); + }); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md index a519cfc7ada0..b4239c12870e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md @@ -1,3 +1,25 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + +## 0.5.10 + +* Adds support for heatmap layers. + +## 0.5.9+2 + +* Restores support for Dart `^3.3.0` and Flutter `^3.19.0`. + +## 0.5.9+1 + +* Fixes a typo in the formatting of the CHANGELOG. + +## 0.5.9 + +* Updates `package:google_maps` dependency to latest (`^8.0.0`). +* Adds support for `web: ^1.0.0`. +* Updates SDK version to Dart `^3.4.0`. Flutter `^3.22.0`. + ## 0.5.8 * Adds support for BitmapDescriptor classes `AssetMapBitmap` and `BytesMapBitmap`. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/README.md b/packages/google_maps_flutter/google_maps_flutter_web/README.md index 22acc45a8074..e53fe3506b07 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/README.md +++ b/packages/google_maps_flutter/google_maps_flutter_web/README.md @@ -6,7 +6,7 @@ Powered by [a14n](https://github.com/a14n)'s [google_maps](https://pub.dev/packa ## Usage -This package is [endorsed](https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin), +This package is [endorsed](https://flutter.dev/to/endorsed-federated-plugin), which means you can simply use `google_maps_flutter` normally. This package will be automatically included in your app when you do, so you do not need to add it to your `pubspec.yaml`. @@ -59,10 +59,13 @@ If you need marker clustering support, modify the tag to load the [js-mar - + ``` +## Heatmaps +To use heatmaps, add `&libraries=visualization` to the end of the URL. See [the documentation](https://developers.google.com/maps/documentation/javascript/libraries) for more information. + ## Limitations of the web version The following map options are not available in web, because the map doesn't rotate there: @@ -85,3 +88,13 @@ Indoor and building layers are still not available on the web. Traffic is. Only Android supports "[Lite Mode](https://developers.google.com/maps/documentation/android-sdk/lite)", so the `liteModeEnabled` constructor argument can't be set to `true` on web apps. Google Maps for web uses `HtmlElementView` to render maps. When a `GoogleMap` is stacked below other widgets, [`package:pointer_interceptor`](https://www.pub.dev/packages/pointer_interceptor) must be used to capture mouse events on the Flutter overlays. See issue [#73830](https://github.com/flutter/flutter/issues/73830). + +## Supported Heatmap Options + +| Field | Supported | +| ---------------------------- | :-------: | +| Heatmap.dissipating | ✓ | +| Heatmap.maxIntensity | ✓ | +| Heatmap.minimumZoomIntensity | x | +| Heatmap.maximumZoomIntensity | x | +| HeatmapGradient.colorMapSize | x | diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/README.md b/packages/google_maps_flutter/google_maps_flutter_web/example/README.md index 4a01887de7fb..932e9f227cbe 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/README.md +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/README.md @@ -15,5 +15,5 @@ This package uses `package:integration_test` to run its tests in a web browser. See [Plugin Tests > Web Tests](https://github.com/flutter/flutter/blob/master/docs/ecosystem/testing/Plugin-Tests.md#web-tests) in the Flutter documentation for instructions to set up and run the tests in this package. -Check [flutter.dev > Integration testing](https://flutter.dev/docs/testing/integration-tests) +Check [flutter.dev > Integration testing](https://docs.flutter.dev/testing/integration-tests) for more info. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart index d7c9ae288f4d..be68cdf1c714 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart @@ -20,12 +20,27 @@ import 'google_maps_controller_test.mocks.dart'; // LatLng values. const String _kCloudMapId = '000000000000000'; // Dummy map ID. +gmaps.Map mapShim() => throw UnimplementedError(); + @GenerateNiceMocks(>[ - MockSpec(), - MockSpec(), - MockSpec(), - MockSpec(), - MockSpec(), + MockSpec( + fallbackGenerators: {#googleMap: mapShim}, + ), + MockSpec( + fallbackGenerators: {#googleMap: mapShim}, + ), + MockSpec( + fallbackGenerators: {#googleMap: mapShim}, + ), + MockSpec( + fallbackGenerators: {#googleMap: mapShim}, + ), + MockSpec( + fallbackGenerators: {#googleMap: mapShim}, + ), + MockSpec( + fallbackGenerators: {#googleMap: mapShim}, + ), ]) /// Test Google Map Controller @@ -149,6 +164,20 @@ void main() { }, throwsAssertionError); }); + testWidgets('cannot updateHeatmaps after dispose', + (WidgetTester tester) async { + controller.dispose(); + + expect(() { + controller.updateHeatmaps( + HeatmapUpdates.from( + const {}, + const {}, + ), + ); + }, throwsAssertionError); + }); + testWidgets('cannot updatePolygons after dispose', (WidgetTester tester) async { controller.dispose(); @@ -217,19 +246,21 @@ void main() { group('init', () { late MockCirclesController circles; + late MockHeatmapsController heatmaps; late MockMarkersController markers; late MockPolygonsController polygons; late MockPolylinesController polylines; late MockTileOverlaysController tileOverlays; - late gmaps.GMap map; + late gmaps.Map map; setUp(() { circles = MockCirclesController(); + heatmaps = MockHeatmapsController(); markers = MockMarkersController(); polygons = MockPolygonsController(); polylines = MockPolylinesController(); tileOverlays = MockTileOverlaysController(); - map = gmaps.GMap(createDivElement()); + map = gmaps.Map(createDivElement()); }); testWidgets('listens to map events', (WidgetTester tester) async { @@ -237,6 +268,7 @@ void main() { ..debugSetOverrides( createMap: (_, __) => map, circles: circles, + heatmaps: heatmaps, markers: markers, polygons: polygons, polylines: polylines, @@ -246,19 +278,19 @@ void main() { // Trigger events on the map, and verify they've been broadcast to the stream final Stream> capturedEvents = stream.stream.take(5); - gmaps.Event.trigger( + gmaps.event.trigger( map, 'click', - [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)], + gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0), ); - gmaps.Event.trigger( + gmaps.event.trigger( map, 'rightclick', - [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)], + gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0), ); // The following line causes 2 events - gmaps.Event.trigger(map, 'bounds_changed', []); - gmaps.Event.trigger(map, 'idle', []); + gmaps.event.trigger(map, 'bounds_changed'); + gmaps.event.trigger(map, 'idle'); final List> events = await capturedEvents.toList(); @@ -275,6 +307,7 @@ void main() { ..debugSetOverrides( createMap: (_, __) => map, circles: circles, + heatmaps: heatmaps, markers: markers, polygons: polygons, polylines: polylines, @@ -283,6 +316,7 @@ void main() { ..init(); verify(circles.bindToMap(mapId, map)); + verify(heatmaps.bindToMap(mapId, map)); verify(markers.bindToMap(mapId, map)); verify(polygons.bindToMap(mapId, map)); verify(polylines.bindToMap(mapId, map)); @@ -295,6 +329,17 @@ void main() { circleId: CircleId('circle-1'), zIndex: 1234, ), + }, heatmaps: { + const Heatmap( + heatmapId: HeatmapId('heatmap-1'), + data: [ + WeightedLatLng(LatLng(43.355114, -5.851333)), + WeightedLatLng(LatLng(43.354797, -5.851860)), + WeightedLatLng(LatLng(43.354469, -5.851318)), + WeightedLatLng(LatLng(43.354762, -5.850824)), + ], + radius: HeatmapRadius.fromPixels(20), + ), }, markers: { const Marker( markerId: MarkerId('marker-1'), @@ -340,6 +385,7 @@ void main() { controller = createController(mapObjects: mapObjects) ..debugSetOverrides( circles: circles, + heatmaps: heatmaps, markers: markers, polygons: polygons, polylines: polylines, @@ -348,6 +394,7 @@ void main() { ..init(); verify(circles.addCircles(mapObjects.circles)); + verify(heatmaps.addHeatmaps(mapObjects.heatmaps)); verify(markers.addMarkers(mapObjects.markers)); verify(polygons.addPolygons(mapObjects.polygons)); verify(polylines.addPolylines(mapObjects.polylines)); @@ -539,12 +586,12 @@ void main() { }); }); - // These are the methods that are delegated to the gmaps.GMap object, that we can mock... + // These are the methods that are delegated to the gmaps.Map object, that we can mock... group('Map control methods', () { - late gmaps.GMap map; + late gmaps.Map map; setUp(() { - map = gmaps.GMap( + map = gmaps.Map( createDivElement(), gmaps.MapOptions() ..zoom = 10 @@ -604,7 +651,7 @@ void main() { group('viewport getters', () { testWidgets('getVisibleRegion', (WidgetTester tester) async { - final gmaps.LatLng gmCenter = map.center!; + final gmaps.LatLng gmCenter = map.center; final LatLng center = LatLng(gmCenter.lat.toDouble(), gmCenter.lng.toDouble()); @@ -658,6 +705,76 @@ void main() { })); }); + testWidgets('updateHeatmaps', (WidgetTester tester) async { + final MockHeatmapsController mock = MockHeatmapsController(); + controller.debugSetOverrides(heatmaps: mock); + + const List heatmapPoints = [ + WeightedLatLng(LatLng(37.782, -122.447)), + WeightedLatLng(LatLng(37.782, -122.445)), + WeightedLatLng(LatLng(37.782, -122.443)), + WeightedLatLng(LatLng(37.782, -122.441)), + WeightedLatLng(LatLng(37.782, -122.439)), + WeightedLatLng(LatLng(37.782, -122.437)), + WeightedLatLng(LatLng(37.782, -122.435)), + WeightedLatLng(LatLng(37.785, -122.447)), + WeightedLatLng(LatLng(37.785, -122.445)), + WeightedLatLng(LatLng(37.785, -122.443)), + WeightedLatLng(LatLng(37.785, -122.441)), + WeightedLatLng(LatLng(37.785, -122.439)), + WeightedLatLng(LatLng(37.785, -122.437)), + WeightedLatLng(LatLng(37.785, -122.435)) + ]; + + final Set previous = { + const Heatmap( + heatmapId: HeatmapId('to-be-updated'), + data: heatmapPoints, + radius: HeatmapRadius.fromPixels(20), + ), + const Heatmap( + heatmapId: HeatmapId('to-be-removed'), + data: heatmapPoints, + radius: HeatmapRadius.fromPixels(20), + ), + }; + + final Set current = { + const Heatmap( + heatmapId: HeatmapId('to-be-updated'), + data: heatmapPoints, + dissipating: false, + radius: HeatmapRadius.fromPixels(20), + ), + const Heatmap( + heatmapId: HeatmapId('to-be-added'), + data: heatmapPoints, + radius: HeatmapRadius.fromPixels(20), + ), + }; + + controller.updateHeatmaps(HeatmapUpdates.from(previous, current)); + + verify(mock.removeHeatmaps({ + const HeatmapId('to-be-removed'), + })); + verify(mock.addHeatmaps({ + const Heatmap( + heatmapId: HeatmapId('to-be-added'), + data: heatmapPoints, + radius: HeatmapRadius.fromPixels(20), + ), + })); + verify(mock.changeHeatmaps({ + const Heatmap( + heatmapId: HeatmapId('to-be-updated'), + data: heatmapPoints, + dissipating: false, + radius: HeatmapRadius.fromPixels(20), + ), + })); + }); + testWidgets('updateMarkers', (WidgetTester tester) async { final MockMarkersController mock = MockMarkersController(); controller = createController()..debugSetOverrides(markers: mock); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.mocks.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.mocks.dart index aef35cc40466..ca64a2a9d7f3 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.mocks.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.mocks.dart @@ -3,14 +3,16 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i5; +import 'dart:async' as _i6; -import 'package:google_maps/google_maps.dart' as _i2; +import 'package:google_maps/google_maps.dart' as _i4; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart' - as _i4; -import 'package:google_maps_flutter_web/google_maps_flutter_web.dart' as _i3; + as _i3; +import 'package:google_maps_flutter_web/google_maps_flutter_web.dart' as _i2; import 'package:mockito/mockito.dart' as _i1; +import 'google_maps_controller_test.dart' as _i5; + // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values // ignore_for_file: avoid_setters_without_getters @@ -24,52 +26,40 @@ import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class -class _FakeGMap_0 extends _i1.SmartFake implements _i2.GMap { - _FakeGMap_0( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - /// A class which mocks [CirclesController]. /// /// See the documentation for Mockito's code generation for more information. -class MockCirclesController extends _i1.Mock implements _i3.CirclesController { +class MockCirclesController extends _i1.Mock implements _i2.CirclesController { @override - Map<_i4.CircleId, _i3.CircleController> get circles => (super.noSuchMethod( + Map<_i3.CircleId, _i2.CircleController> get circles => (super.noSuchMethod( Invocation.getter(#circles), - returnValue: <_i4.CircleId, _i3.CircleController>{}, - returnValueForMissingStub: <_i4.CircleId, _i3.CircleController>{}, - ) as Map<_i4.CircleId, _i3.CircleController>); + returnValue: <_i3.CircleId, _i2.CircleController>{}, + returnValueForMissingStub: <_i3.CircleId, _i2.CircleController>{}, + ) as Map<_i3.CircleId, _i2.CircleController>); + @override - _i2.GMap get googleMap => (super.noSuchMethod( + _i4.Map get googleMap => (super.noSuchMethod( Invocation.getter(#googleMap), - returnValue: _FakeGMap_0( - this, - Invocation.getter(#googleMap), - ), - returnValueForMissingStub: _FakeGMap_0( - this, - Invocation.getter(#googleMap), - ), - ) as _i2.GMap); + returnValue: _i5.mapShim(), + returnValueForMissingStub: _i5.mapShim(), + ) as _i4.Map); + @override - set googleMap(_i2.GMap? _googleMap) => super.noSuchMethod( + set googleMap(_i4.Map? _googleMap) => super.noSuchMethod( Invocation.setter( #googleMap, _googleMap, ), returnValueForMissingStub: null, ); + @override int get mapId => (super.noSuchMethod( Invocation.getter(#mapId), returnValue: 0, returnValueForMissingStub: 0, ) as int); + @override set mapId(int? _mapId) => super.noSuchMethod( Invocation.setter( @@ -78,24 +68,27 @@ class MockCirclesController extends _i1.Mock implements _i3.CirclesController { ), returnValueForMissingStub: null, ); + @override - void addCircles(Set<_i4.Circle>? circlesToAdd) => super.noSuchMethod( + void addCircles(Set<_i3.Circle>? circlesToAdd) => super.noSuchMethod( Invocation.method( #addCircles, [circlesToAdd], ), returnValueForMissingStub: null, ); + @override - void changeCircles(Set<_i4.Circle>? circlesToChange) => super.noSuchMethod( + void changeCircles(Set<_i3.Circle>? circlesToChange) => super.noSuchMethod( Invocation.method( #changeCircles, [circlesToChange], ), returnValueForMissingStub: null, ); + @override - void removeCircles(Set<_i4.CircleId>? circleIdsToRemove) => + void removeCircles(Set<_i3.CircleId>? circleIdsToRemove) => super.noSuchMethod( Invocation.method( #removeCircles, @@ -103,10 +96,100 @@ class MockCirclesController extends _i1.Mock implements _i3.CirclesController { ), returnValueForMissingStub: null, ); + @override void bindToMap( int? mapId, - _i2.GMap? googleMap, + _i4.Map? googleMap, + ) => + super.noSuchMethod( + Invocation.method( + #bindToMap, + [ + mapId, + googleMap, + ], + ), + returnValueForMissingStub: null, + ); +} + +/// A class which mocks [HeatmapsController]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockHeatmapsController extends _i1.Mock + implements _i2.HeatmapsController { + @override + Map<_i3.HeatmapId, _i2.HeatmapController> get heatmaps => (super.noSuchMethod( + Invocation.getter(#heatmaps), + returnValue: <_i3.HeatmapId, _i2.HeatmapController>{}, + returnValueForMissingStub: <_i3.HeatmapId, _i2.HeatmapController>{}, + ) as Map<_i3.HeatmapId, _i2.HeatmapController>); + + @override + _i4.Map get googleMap => (super.noSuchMethod( + Invocation.getter(#googleMap), + returnValue: _i5.mapShim(), + returnValueForMissingStub: _i5.mapShim(), + ) as _i4.Map); + + @override + set googleMap(_i4.Map? _googleMap) => super.noSuchMethod( + Invocation.setter( + #googleMap, + _googleMap, + ), + returnValueForMissingStub: null, + ); + + @override + int get mapId => (super.noSuchMethod( + Invocation.getter(#mapId), + returnValue: 0, + returnValueForMissingStub: 0, + ) as int); + + @override + set mapId(int? _mapId) => super.noSuchMethod( + Invocation.setter( + #mapId, + _mapId, + ), + returnValueForMissingStub: null, + ); + + @override + void addHeatmaps(Set<_i3.Heatmap>? heatmapsToAdd) => super.noSuchMethod( + Invocation.method( + #addHeatmaps, + [heatmapsToAdd], + ), + returnValueForMissingStub: null, + ); + + @override + void changeHeatmaps(Set<_i3.Heatmap>? heatmapsToChange) => super.noSuchMethod( + Invocation.method( + #changeHeatmaps, + [heatmapsToChange], + ), + returnValueForMissingStub: null, + ); + + @override + void removeHeatmaps(Set<_i3.HeatmapId>? heatmapIdsToRemove) => + super.noSuchMethod( + Invocation.method( + #removeHeatmaps, + [heatmapIdsToRemove], + ), + returnValueForMissingStub: null, + ); + + @override + void bindToMap( + int? mapId, + _i4.Map? googleMap, ) => super.noSuchMethod( Invocation.method( @@ -124,39 +207,37 @@ class MockCirclesController extends _i1.Mock implements _i3.CirclesController { /// /// See the documentation for Mockito's code generation for more information. class MockPolygonsController extends _i1.Mock - implements _i3.PolygonsController { + implements _i2.PolygonsController { @override - Map<_i4.PolygonId, _i3.PolygonController> get polygons => (super.noSuchMethod( + Map<_i3.PolygonId, _i2.PolygonController> get polygons => (super.noSuchMethod( Invocation.getter(#polygons), - returnValue: <_i4.PolygonId, _i3.PolygonController>{}, - returnValueForMissingStub: <_i4.PolygonId, _i3.PolygonController>{}, - ) as Map<_i4.PolygonId, _i3.PolygonController>); + returnValue: <_i3.PolygonId, _i2.PolygonController>{}, + returnValueForMissingStub: <_i3.PolygonId, _i2.PolygonController>{}, + ) as Map<_i3.PolygonId, _i2.PolygonController>); + @override - _i2.GMap get googleMap => (super.noSuchMethod( + _i4.Map get googleMap => (super.noSuchMethod( Invocation.getter(#googleMap), - returnValue: _FakeGMap_0( - this, - Invocation.getter(#googleMap), - ), - returnValueForMissingStub: _FakeGMap_0( - this, - Invocation.getter(#googleMap), - ), - ) as _i2.GMap); + returnValue: _i5.mapShim(), + returnValueForMissingStub: _i5.mapShim(), + ) as _i4.Map); + @override - set googleMap(_i2.GMap? _googleMap) => super.noSuchMethod( + set googleMap(_i4.Map? _googleMap) => super.noSuchMethod( Invocation.setter( #googleMap, _googleMap, ), returnValueForMissingStub: null, ); + @override int get mapId => (super.noSuchMethod( Invocation.getter(#mapId), returnValue: 0, returnValueForMissingStub: 0, ) as int); + @override set mapId(int? _mapId) => super.noSuchMethod( Invocation.setter( @@ -165,24 +246,27 @@ class MockPolygonsController extends _i1.Mock ), returnValueForMissingStub: null, ); + @override - void addPolygons(Set<_i4.Polygon>? polygonsToAdd) => super.noSuchMethod( + void addPolygons(Set<_i3.Polygon>? polygonsToAdd) => super.noSuchMethod( Invocation.method( #addPolygons, [polygonsToAdd], ), returnValueForMissingStub: null, ); + @override - void changePolygons(Set<_i4.Polygon>? polygonsToChange) => super.noSuchMethod( + void changePolygons(Set<_i3.Polygon>? polygonsToChange) => super.noSuchMethod( Invocation.method( #changePolygons, [polygonsToChange], ), returnValueForMissingStub: null, ); + @override - void removePolygons(Set<_i4.PolygonId>? polygonIdsToRemove) => + void removePolygons(Set<_i3.PolygonId>? polygonIdsToRemove) => super.noSuchMethod( Invocation.method( #removePolygons, @@ -190,10 +274,11 @@ class MockPolygonsController extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void bindToMap( int? mapId, - _i2.GMap? googleMap, + _i4.Map? googleMap, ) => super.noSuchMethod( Invocation.method( @@ -211,39 +296,37 @@ class MockPolygonsController extends _i1.Mock /// /// See the documentation for Mockito's code generation for more information. class MockPolylinesController extends _i1.Mock - implements _i3.PolylinesController { + implements _i2.PolylinesController { @override - Map<_i4.PolylineId, _i3.PolylineController> get lines => (super.noSuchMethod( + Map<_i3.PolylineId, _i2.PolylineController> get lines => (super.noSuchMethod( Invocation.getter(#lines), - returnValue: <_i4.PolylineId, _i3.PolylineController>{}, - returnValueForMissingStub: <_i4.PolylineId, _i3.PolylineController>{}, - ) as Map<_i4.PolylineId, _i3.PolylineController>); + returnValue: <_i3.PolylineId, _i2.PolylineController>{}, + returnValueForMissingStub: <_i3.PolylineId, _i2.PolylineController>{}, + ) as Map<_i3.PolylineId, _i2.PolylineController>); + @override - _i2.GMap get googleMap => (super.noSuchMethod( + _i4.Map get googleMap => (super.noSuchMethod( Invocation.getter(#googleMap), - returnValue: _FakeGMap_0( - this, - Invocation.getter(#googleMap), - ), - returnValueForMissingStub: _FakeGMap_0( - this, - Invocation.getter(#googleMap), - ), - ) as _i2.GMap); + returnValue: _i5.mapShim(), + returnValueForMissingStub: _i5.mapShim(), + ) as _i4.Map); + @override - set googleMap(_i2.GMap? _googleMap) => super.noSuchMethod( + set googleMap(_i4.Map? _googleMap) => super.noSuchMethod( Invocation.setter( #googleMap, _googleMap, ), returnValueForMissingStub: null, ); + @override int get mapId => (super.noSuchMethod( Invocation.getter(#mapId), returnValue: 0, returnValueForMissingStub: 0, ) as int); + @override set mapId(int? _mapId) => super.noSuchMethod( Invocation.setter( @@ -252,16 +335,18 @@ class MockPolylinesController extends _i1.Mock ), returnValueForMissingStub: null, ); + @override - void addPolylines(Set<_i4.Polyline>? polylinesToAdd) => super.noSuchMethod( + void addPolylines(Set<_i3.Polyline>? polylinesToAdd) => super.noSuchMethod( Invocation.method( #addPolylines, [polylinesToAdd], ), returnValueForMissingStub: null, ); + @override - void changePolylines(Set<_i4.Polyline>? polylinesToChange) => + void changePolylines(Set<_i3.Polyline>? polylinesToChange) => super.noSuchMethod( Invocation.method( #changePolylines, @@ -269,8 +354,9 @@ class MockPolylinesController extends _i1.Mock ), returnValueForMissingStub: null, ); + @override - void removePolylines(Set<_i4.PolylineId>? polylineIdsToRemove) => + void removePolylines(Set<_i3.PolylineId>? polylineIdsToRemove) => super.noSuchMethod( Invocation.method( #removePolylines, @@ -278,10 +364,11 @@ class MockPolylinesController extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void bindToMap( int? mapId, - _i2.GMap? googleMap, + _i4.Map? googleMap, ) => super.noSuchMethod( Invocation.method( @@ -298,39 +385,37 @@ class MockPolylinesController extends _i1.Mock /// A class which mocks [MarkersController]. /// /// See the documentation for Mockito's code generation for more information. -class MockMarkersController extends _i1.Mock implements _i3.MarkersController { +class MockMarkersController extends _i1.Mock implements _i2.MarkersController { @override - Map<_i4.MarkerId, _i3.MarkerController> get markers => (super.noSuchMethod( + Map<_i3.MarkerId, _i2.MarkerController> get markers => (super.noSuchMethod( Invocation.getter(#markers), - returnValue: <_i4.MarkerId, _i3.MarkerController>{}, - returnValueForMissingStub: <_i4.MarkerId, _i3.MarkerController>{}, - ) as Map<_i4.MarkerId, _i3.MarkerController>); + returnValue: <_i3.MarkerId, _i2.MarkerController>{}, + returnValueForMissingStub: <_i3.MarkerId, _i2.MarkerController>{}, + ) as Map<_i3.MarkerId, _i2.MarkerController>); + @override - _i2.GMap get googleMap => (super.noSuchMethod( + _i4.Map get googleMap => (super.noSuchMethod( Invocation.getter(#googleMap), - returnValue: _FakeGMap_0( - this, - Invocation.getter(#googleMap), - ), - returnValueForMissingStub: _FakeGMap_0( - this, - Invocation.getter(#googleMap), - ), - ) as _i2.GMap); + returnValue: _i5.mapShim(), + returnValueForMissingStub: _i5.mapShim(), + ) as _i4.Map); + @override - set googleMap(_i2.GMap? _googleMap) => super.noSuchMethod( + set googleMap(_i4.Map? _googleMap) => super.noSuchMethod( Invocation.setter( #googleMap, _googleMap, ), returnValueForMissingStub: null, ); + @override int get mapId => (super.noSuchMethod( Invocation.getter(#mapId), returnValue: 0, returnValueForMissingStub: 0, ) as int); + @override set mapId(int? _mapId) => super.noSuchMethod( Invocation.setter( @@ -339,28 +424,31 @@ class MockMarkersController extends _i1.Mock implements _i3.MarkersController { ), returnValueForMissingStub: null, ); + @override - _i5.Future addMarkers(Set<_i4.Marker>? markersToAdd) => + _i6.Future addMarkers(Set<_i3.Marker>? markersToAdd) => (super.noSuchMethod( Invocation.method( #addMarkers, [markersToAdd], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + @override - _i5.Future changeMarkers(Set<_i4.Marker>? markersToChange) => + _i6.Future changeMarkers(Set<_i3.Marker>? markersToChange) => (super.noSuchMethod( Invocation.method( #changeMarkers, [markersToChange], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + @override - void removeMarkers(Set<_i4.MarkerId>? markerIdsToRemove) => + void removeMarkers(Set<_i3.MarkerId>? markerIdsToRemove) => super.noSuchMethod( Invocation.method( #removeMarkers, @@ -368,24 +456,27 @@ class MockMarkersController extends _i1.Mock implements _i3.MarkersController { ), returnValueForMissingStub: null, ); + @override - void showMarkerInfoWindow(_i4.MarkerId? markerId) => super.noSuchMethod( + void showMarkerInfoWindow(_i3.MarkerId? markerId) => super.noSuchMethod( Invocation.method( #showMarkerInfoWindow, [markerId], ), returnValueForMissingStub: null, ); + @override - void hideMarkerInfoWindow(_i4.MarkerId? markerId) => super.noSuchMethod( + void hideMarkerInfoWindow(_i3.MarkerId? markerId) => super.noSuchMethod( Invocation.method( #hideMarkerInfoWindow, [markerId], ), returnValueForMissingStub: null, ); + @override - bool isInfoWindowShown(_i4.MarkerId? markerId) => (super.noSuchMethod( + bool isInfoWindowShown(_i3.MarkerId? markerId) => (super.noSuchMethod( Invocation.method( #isInfoWindowShown, [markerId], @@ -393,10 +484,11 @@ class MockMarkersController extends _i1.Mock implements _i3.MarkersController { returnValue: false, returnValueForMissingStub: false, ) as bool); + @override void bindToMap( int? mapId, - _i2.GMap? googleMap, + _i4.Map? googleMap, ) => super.noSuchMethod( Invocation.method( @@ -414,33 +506,30 @@ class MockMarkersController extends _i1.Mock implements _i3.MarkersController { /// /// See the documentation for Mockito's code generation for more information. class MockTileOverlaysController extends _i1.Mock - implements _i3.TileOverlaysController { + implements _i2.TileOverlaysController { @override - _i2.GMap get googleMap => (super.noSuchMethod( + _i4.Map get googleMap => (super.noSuchMethod( Invocation.getter(#googleMap), - returnValue: _FakeGMap_0( - this, - Invocation.getter(#googleMap), - ), - returnValueForMissingStub: _FakeGMap_0( - this, - Invocation.getter(#googleMap), - ), - ) as _i2.GMap); + returnValue: _i5.mapShim(), + returnValueForMissingStub: _i5.mapShim(), + ) as _i4.Map); + @override - set googleMap(_i2.GMap? _googleMap) => super.noSuchMethod( + set googleMap(_i4.Map? _googleMap) => super.noSuchMethod( Invocation.setter( #googleMap, _googleMap, ), returnValueForMissingStub: null, ); + @override int get mapId => (super.noSuchMethod( Invocation.getter(#mapId), returnValue: 0, returnValueForMissingStub: 0, ) as int); + @override set mapId(int? _mapId) => super.noSuchMethod( Invocation.setter( @@ -449,8 +538,9 @@ class MockTileOverlaysController extends _i1.Mock ), returnValueForMissingStub: null, ); + @override - void addTileOverlays(Set<_i4.TileOverlay>? tileOverlaysToAdd) => + void addTileOverlays(Set<_i3.TileOverlay>? tileOverlaysToAdd) => super.noSuchMethod( Invocation.method( #addTileOverlays, @@ -458,8 +548,9 @@ class MockTileOverlaysController extends _i1.Mock ), returnValueForMissingStub: null, ); + @override - void changeTileOverlays(Set<_i4.TileOverlay>? tileOverlays) => + void changeTileOverlays(Set<_i3.TileOverlay>? tileOverlays) => super.noSuchMethod( Invocation.method( #changeTileOverlays, @@ -467,8 +558,9 @@ class MockTileOverlaysController extends _i1.Mock ), returnValueForMissingStub: null, ); + @override - void removeTileOverlays(Set<_i4.TileOverlayId>? tileOverlayIds) => + void removeTileOverlays(Set<_i3.TileOverlayId>? tileOverlayIds) => super.noSuchMethod( Invocation.method( #removeTileOverlays, @@ -476,18 +568,20 @@ class MockTileOverlaysController extends _i1.Mock ), returnValueForMissingStub: null, ); + @override - void clearTileCache(_i4.TileOverlayId? tileOverlayId) => super.noSuchMethod( + void clearTileCache(_i3.TileOverlayId? tileOverlayId) => super.noSuchMethod( Invocation.method( #clearTileCache, [tileOverlayId], ), returnValueForMissingStub: null, ); + @override void bindToMap( int? mapId, - _i2.GMap? googleMap, + _i4.Map? googleMap, ) => super.noSuchMethod( Invocation.method( diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart index b84b267c0425..1e02f576a089 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart @@ -3,7 +3,8 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:js_util' show getProperty; +import 'dart:js_interop'; +import 'dart:js_interop_unsafe'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -191,8 +192,8 @@ void main() { final gmaps.MapTypeStyle style = styles[0]; expect(style.featureType, 'poi.park'); expect(style.elementType, 'labels.text.fill'); - expect(style.stylers?.length, 1); - expect(getProperty(style.stylers![0]!, 'color'), '#6b9a76'); + expect(style.stylers.length, 1); + expect((style.stylers[0]['color']! as JSString).toDart, '#6b9a76'); }); testWidgets('throws MapStyleException for invalid styles', @@ -262,6 +263,16 @@ void main() { verify(controller.updateCircles(expectedUpdates)); }); + testWidgets('updateHeatmaps', (WidgetTester tester) async { + final HeatmapUpdates expectedUpdates = HeatmapUpdates.from( + const {}, + const {}, + ); + + await plugin.updateHeatmaps(expectedUpdates, mapId: mapId); + + verify(controller.updateHeatmaps(expectedUpdates)); + }); // Tile Overlays testWidgets('updateTileOverlays', (WidgetTester tester) async { final Set expectedOverlays = { diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart index 30d7b46859e0..cf5acfcb813c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart @@ -95,43 +95,49 @@ class MockGoogleMapController extends _i1.Mock Invocation.getter(#configuration), ), ) as _i2.MapConfiguration); + @override - _i3.StreamController<_i2.MapEvent> get stream => (super.noSuchMethod( + _i3.StreamController<_i2.MapEvent> get stream => (super.noSuchMethod( Invocation.getter(#stream), - returnValue: _FakeStreamController_1<_i2.MapEvent>( + returnValue: _FakeStreamController_1<_i2.MapEvent>( this, Invocation.getter(#stream), ), returnValueForMissingStub: - _FakeStreamController_1<_i2.MapEvent>( + _FakeStreamController_1<_i2.MapEvent>( this, Invocation.getter(#stream), ), - ) as _i3.StreamController<_i2.MapEvent>); + ) as _i3.StreamController<_i2.MapEvent>); + @override - _i3.Stream<_i2.MapEvent> get events => (super.noSuchMethod( + _i3.Stream<_i2.MapEvent> get events => (super.noSuchMethod( Invocation.getter(#events), - returnValue: _i3.Stream<_i2.MapEvent>.empty(), - returnValueForMissingStub: _i3.Stream<_i2.MapEvent>.empty(), - ) as _i3.Stream<_i2.MapEvent>); + returnValue: _i3.Stream<_i2.MapEvent>.empty(), + returnValueForMissingStub: _i3.Stream<_i2.MapEvent>.empty(), + ) as _i3.Stream<_i2.MapEvent>); + @override bool get isInitialized => (super.noSuchMethod( Invocation.getter(#isInitialized), returnValue: false, returnValueForMissingStub: false, ) as bool); + @override List<_i5.MapTypeStyle> get styles => (super.noSuchMethod( Invocation.getter(#styles), returnValue: <_i5.MapTypeStyle>[], returnValueForMissingStub: <_i5.MapTypeStyle>[], ) as List<_i5.MapTypeStyle>); + @override void debugSetOverrides({ _i4.DebugCreateMapFunction? createMap, _i4.DebugSetOptionsFunction? setOptions, _i4.MarkersController? markers, _i4.CirclesController? circles, + _i4.HeatmapsController? heatmaps, _i4.PolygonsController? polygons, _i4.PolylinesController? polylines, _i6.ClusterManagersController? clusterManagers, @@ -146,6 +152,7 @@ class MockGoogleMapController extends _i1.Mock #setOptions: setOptions, #markers: markers, #circles: circles, + #heatmaps: heatmaps, #polygons: polygons, #polylines: polylines, #clusterManagers: clusterManagers, @@ -154,6 +161,7 @@ class MockGoogleMapController extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void init() => super.noSuchMethod( Invocation.method( @@ -162,6 +170,7 @@ class MockGoogleMapController extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void updateMapConfiguration(_i2.MapConfiguration? update) => super.noSuchMethod( @@ -171,6 +180,7 @@ class MockGoogleMapController extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void updateStyles(List<_i5.MapTypeStyle>? styles) => super.noSuchMethod( Invocation.method( @@ -179,6 +189,7 @@ class MockGoogleMapController extends _i1.Mock ), returnValueForMissingStub: null, ); + @override _i3.Future<_i2.LatLngBounds> getVisibleRegion() => (super.noSuchMethod( Invocation.method( @@ -201,6 +212,7 @@ class MockGoogleMapController extends _i1.Mock ), )), ) as _i3.Future<_i2.LatLngBounds>); + @override _i3.Future<_i2.ScreenCoordinate> getScreenCoordinate(_i2.LatLng? latLng) => (super.noSuchMethod( @@ -225,6 +237,7 @@ class MockGoogleMapController extends _i1.Mock ), )), ) as _i3.Future<_i2.ScreenCoordinate>); + @override _i3.Future<_i2.LatLng> getLatLng(_i2.ScreenCoordinate? screenCoordinate) => (super.noSuchMethod( @@ -247,6 +260,7 @@ class MockGoogleMapController extends _i1.Mock ), )), ) as _i3.Future<_i2.LatLng>); + @override _i3.Future moveCamera(_i2.CameraUpdate? cameraUpdate) => (super.noSuchMethod( @@ -257,6 +271,7 @@ class MockGoogleMapController extends _i1.Mock returnValue: _i3.Future.value(), returnValueForMissingStub: _i3.Future.value(), ) as _i3.Future); + @override _i3.Future getZoomLevel() => (super.noSuchMethod( Invocation.method( @@ -266,6 +281,7 @@ class MockGoogleMapController extends _i1.Mock returnValue: _i3.Future.value(0.0), returnValueForMissingStub: _i3.Future.value(0.0), ) as _i3.Future); + @override void updateCircles(_i2.CircleUpdates? updates) => super.noSuchMethod( Invocation.method( @@ -274,6 +290,16 @@ class MockGoogleMapController extends _i1.Mock ), returnValueForMissingStub: null, ); + + @override + void updateHeatmaps(_i2.HeatmapUpdates? updates) => super.noSuchMethod( + Invocation.method( + #updateHeatmaps, + [updates], + ), + returnValueForMissingStub: null, + ); + @override void updatePolygons(_i2.PolygonUpdates? updates) => super.noSuchMethod( Invocation.method( @@ -282,6 +308,7 @@ class MockGoogleMapController extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void updatePolylines(_i2.PolylineUpdates? updates) => super.noSuchMethod( Invocation.method( @@ -290,6 +317,7 @@ class MockGoogleMapController extends _i1.Mock ), returnValueForMissingStub: null, ); + @override _i3.Future updateMarkers(_i2.MarkerUpdates? updates) => (super.noSuchMethod( @@ -300,6 +328,7 @@ class MockGoogleMapController extends _i1.Mock returnValue: _i3.Future.value(), returnValueForMissingStub: _i3.Future.value(), ) as _i3.Future); + @override void updateClusterManagers(_i2.ClusterManagerUpdates? updates) => super.noSuchMethod( @@ -309,6 +338,7 @@ class MockGoogleMapController extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void updateTileOverlays(Set<_i2.TileOverlay>? newOverlays) => super.noSuchMethod( @@ -318,6 +348,7 @@ class MockGoogleMapController extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void clearTileCache(_i2.TileOverlayId? id) => super.noSuchMethod( Invocation.method( @@ -326,6 +357,7 @@ class MockGoogleMapController extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void showInfoWindow(_i2.MarkerId? markerId) => super.noSuchMethod( Invocation.method( @@ -334,6 +366,7 @@ class MockGoogleMapController extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void hideInfoWindow(_i2.MarkerId? markerId) => super.noSuchMethod( Invocation.method( @@ -342,6 +375,7 @@ class MockGoogleMapController extends _i1.Mock ), returnValueForMissingStub: null, ); + @override bool isInfoWindowShown(_i2.MarkerId? markerId) => (super.noSuchMethod( Invocation.method( @@ -351,6 +385,7 @@ class MockGoogleMapController extends _i1.Mock returnValue: false, returnValueForMissingStub: false, ) as bool); + @override void dispose() => super.noSuchMethod( Invocation.method( diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart index 0b284cac7663..2859d082b780 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart @@ -56,7 +56,11 @@ void main() { MarkerController(marker: marker, onTap: onTap); // Trigger a click event... - gmaps.Event.trigger(marker, 'click', [gmaps.MapMouseEvent()]); + gmaps.event.trigger( + marker, + 'click', + gmaps.MapMouseEvent(), + ); // The event handling is now truly async. Wait for it... expect(await methodCalled, isTrue); @@ -66,8 +70,11 @@ void main() { MarkerController(marker: marker, onDragStart: onDragStart); // Trigger a drag end event... - gmaps.Event.trigger(marker, 'dragstart', - [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)]); + gmaps.event.trigger( + marker, + 'dragstart', + gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0), + ); expect(await methodCalled, isTrue); }); @@ -76,10 +83,10 @@ void main() { MarkerController(marker: marker, onDrag: onDrag); // Trigger a drag end event... - gmaps.Event.trigger( + gmaps.event.trigger( marker, 'drag', - [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)], + gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0), ); expect(await methodCalled, isTrue); @@ -89,10 +96,10 @@ void main() { MarkerController(marker: marker, onDragEnd: onDragEnd); // Trigger a drag end event... - gmaps.Event.trigger( + gmaps.event.trigger( marker, 'dragend', - [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)], + gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0), ); expect(await methodCalled, isTrue); @@ -104,7 +111,7 @@ void main() { ..draggable = true ..position = gmaps.LatLng(42, 54); - expect(marker.draggable, isNull); + expect(marker.isDraggableDefined(), isFalse); controller.update(options); @@ -124,7 +131,7 @@ void main() { testWidgets('showInfoWindow', (WidgetTester tester) async { final gmaps.InfoWindow infoWindow = gmaps.InfoWindow(); - final gmaps.GMap map = gmaps.GMap(createDivElement()); + final gmaps.Map map = gmaps.Map(createDivElement()); marker.set('map', map); final MarkerController controller = MarkerController( marker: marker, @@ -139,7 +146,7 @@ void main() { testWidgets('hideInfoWindow', (WidgetTester tester) async { final gmaps.InfoWindow infoWindow = gmaps.InfoWindow(); - final gmaps.GMap map = gmaps.GMap(createDivElement()); + final gmaps.Map map = gmaps.Map(createDivElement()); marker.set('map', map); final MarkerController controller = MarkerController( marker: marker, @@ -157,7 +164,7 @@ void main() { setUp(() { final gmaps.InfoWindow infoWindow = gmaps.InfoWindow(); - final gmaps.GMap map = gmaps.GMap(createDivElement()); + final gmaps.Map map = gmaps.Map(createDivElement()); marker.set('map', map); controller = MarkerController(marker: marker, infoWindow: infoWindow); }); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart index f068ec8db307..f76e386b1088 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart @@ -4,6 +4,7 @@ import 'dart:async'; import 'dart:convert'; +import 'dart:js_interop'; import 'dart:typed_data'; import 'package:flutter_test/flutter_test.dart'; @@ -26,7 +27,7 @@ void main() { late StreamController> events; late MarkersController controller; late ClusterManagersController clusterManagersController; - late gmaps.GMap map; + late gmaps.Map map; setUp(() { events = StreamController>(); @@ -34,7 +35,7 @@ void main() { clusterManagersController = ClusterManagersController(stream: events); controller = MarkersController( stream: events, clusterManagersController: clusterManagersController); - map = gmaps.GMap(createDivElement()); + map = gmaps.Map(createDivElement()); clusterManagersController.bindToMap(123, map); controller.bindToMap(123, map); }); @@ -213,7 +214,6 @@ void main() { testWidgets('markers with custom asset icon work', (WidgetTester tester) async { - tester.view.devicePixelRatio = 2.0; final Set markers = { Marker( markerId: const MarkerId('1'), @@ -230,7 +230,7 @@ void main() { controller.markers[const MarkerId('1')]?.marker?.icon as gmaps.Icon?; expect(icon, isNotNull); - final String assetUrl = icon!.url!; + final String assetUrl = icon!.url; expect(assetUrl, startsWith('assets')); final gmaps.Size size = icon.size!; @@ -245,7 +245,6 @@ void main() { testWidgets('markers with custom asset icon and pixelratio work', (WidgetTester tester) async { - tester.view.devicePixelRatio = 2.0; final Set markers = { Marker( markerId: const MarkerId('1'), @@ -262,7 +261,7 @@ void main() { controller.markers[const MarkerId('1')]?.marker?.icon as gmaps.Icon?; expect(icon, isNotNull); - final String assetUrl = icon!.url!; + final String assetUrl = icon!.url; expect(assetUrl, startsWith('assets')); final gmaps.Size size = icon.size!; @@ -277,8 +276,6 @@ void main() { }); testWidgets('markers with custom asset icon with width and height work', (WidgetTester tester) async { - tester.view.devicePixelRatio = 2.0; - final Set markers = { Marker( markerId: const MarkerId('1'), @@ -297,7 +294,7 @@ void main() { controller.markers[const MarkerId('1')]?.marker?.icon as gmaps.Icon?; expect(icon, isNotNull); - final String assetUrl = icon!.url!; + final String assetUrl = icon!.url; expect(assetUrl, startsWith('assets')); final gmaps.Size size = icon.size!; @@ -313,7 +310,6 @@ void main() { testWidgets('markers with missing asset icon should not set size', (WidgetTester tester) async { - tester.view.devicePixelRatio = 2.0; final Set markers = { Marker( markerId: const MarkerId('1'), @@ -330,7 +326,7 @@ void main() { controller.markers[const MarkerId('1')]?.marker?.icon as gmaps.Icon?; expect(icon, isNotNull); - final String assetUrl = icon!.url!; + final String assetUrl = icon!.url; expect(assetUrl, startsWith('assets')); // For invalid assets, the size and scaledSize should be null. @@ -341,7 +337,6 @@ void main() { // https://github.com/flutter/flutter/issues/66622 testWidgets('markers with custom bitmap icon work', (WidgetTester tester) async { - tester.view.devicePixelRatio = 2.0; final Uint8List bytes = const Base64Decoder().convert(iconImageBase64); final Set markers = { Marker( @@ -360,7 +355,7 @@ void main() { controller.markers[const MarkerId('1')]?.marker?.icon as gmaps.Icon?; expect(icon, isNotNull); - final String blobUrl = icon!.url!; + final String blobUrl = icon!.url; expect(blobUrl, startsWith('blob:')); final http.Response response = await http.get(Uri.parse(blobUrl)); @@ -383,7 +378,6 @@ void main() { testWidgets('markers with custom bitmap icon and pixelratio work', (WidgetTester tester) async { - tester.view.devicePixelRatio = 2.0; final Uint8List bytes = const Base64Decoder().convert(iconImageBase64); final Set markers = { Marker( @@ -417,7 +411,6 @@ void main() { // https://github.com/flutter/flutter/issues/73789 testWidgets('markers with custom bitmap icon pass size to sdk', (WidgetTester tester) async { - tester.view.devicePixelRatio = 2.0; final Uint8List bytes = const Base64Decoder().convert(iconImageBase64); final Set markers = { Marker( @@ -464,9 +457,12 @@ void main() { expect(controller.markers.length, 1); final HTMLElement? content = controller .markers[const MarkerId('1')]?.infoWindow?.content as HTMLElement?; - expect(content?.innerHTML, contains('title for test')); + expect(content, isNotNull); + + final String innerHtml = (content!.innerHTML as JSString).toDart; + expect(innerHtml, contains('title for test')); expect( - content?.innerHTML, + innerHtml, contains( 'Go to Google >>>', )); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart index 0724da211275..8d192e183066 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart @@ -41,11 +41,11 @@ void main() { tileOverlay: const TileOverlay(tileOverlayId: id), ); - final gmaps.Size size = controller.gmMapType.tileSize!; + final gmaps.Size size = controller.gmMapType.tileSize; expect(size.width, TileOverlayController.logicalTileSize); expect(size.height, TileOverlayController.logicalTileSize); expect( - controller.gmMapType.getTile!(gmaps.Point(0, 0), 0, document), + controller.gmMapType.getTile(gmaps.Point(0, 0), 0, document), null, ); }); @@ -58,18 +58,17 @@ void main() { ), ); - final HTMLImageElement img = - controller.gmMapType.getTile!(gmaps.Point(0, 0), 0, document)! - as HTMLImageElement; + final HTMLImageElement img = controller.gmMapType + .getTile(gmaps.Point(0, 0), 0, document)! as HTMLImageElement; expect(img.naturalWidth, 0); expect(img.naturalHeight, 0); - expect(img.hidden, true); + expect((img.hidden! as JSBoolean).toDart, true); await img.onLoad.first; await img.decode().toDart; - expect(img.hidden, false); + expect((img.hidden! as JSBoolean).toDart, false); expect(img.naturalWidth, 16); expect(img.naturalHeight, 16); }); @@ -82,9 +81,8 @@ void main() { ), ); { - final HTMLImageElement img = - controller.gmMapType.getTile!(gmaps.Point(0, 0), 0, document)! - as HTMLImageElement; + final HTMLImageElement img = controller.gmMapType + .getTile(gmaps.Point(0, 0), 0, document)! as HTMLImageElement; await null; // let `getTile` `then` complete expect( img.src, @@ -98,9 +96,8 @@ void main() { tileProvider: TestTileProvider(), )); { - final HTMLImageElement img = - controller.gmMapType.getTile!(gmaps.Point(0, 0), 0, document)! - as HTMLImageElement; + final HTMLImageElement img = controller.gmMapType + .getTile(gmaps.Point(0, 0), 0, document)! as HTMLImageElement; await img.onLoad.first; @@ -114,7 +111,7 @@ void main() { controller.update(const TileOverlay(tileOverlayId: id)); { expect( - controller.gmMapType.getTile!(gmaps.Point(0, 0), 0, document), + controller.gmMapType.getTile(gmaps.Point(0, 0), 0, document), null, reason: 'Setting a null tileProvider should work.', ); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlays_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlays_test.dart index c680c97a993a..1b5b8af5f020 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlays_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlays_test.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:js_interop'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -32,21 +33,21 @@ void main() { group('TileOverlaysController', () { late TileOverlaysController controller; - late gmaps.GMap map; + late gmaps.Map map; late List tileProviders; late List tileOverlays; /// Queries the current overlay map types for tiles at x = 0, y = 0, zoom = /// 0. void probeTiles() { - for (final gmaps.MapType? mapType in map.overlayMapTypes!.array!) { - mapType?.getTile!(gmaps.Point(0, 0), 0, document); + for (final gmaps.MapType? mapType in map.overlayMapTypes.array.toDart) { + mapType?.getTile(gmaps.Point(0, 0), 0, document); } } setUp(() { controller = TileOverlaysController(); - map = gmaps.GMap(createDivElement()); + map = gmaps.Map(createDivElement()); controller.googleMap = map; tileProviders = [ diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart index 11af181cffc2..0912fcbaec4d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart @@ -3,9 +3,11 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:js_interop'; import 'package:flutter_test/flutter_test.dart'; import 'package:google_maps/google_maps.dart' as gmaps; +import 'package:google_maps/google_maps_visualization.dart' as visualization; import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; import 'package:integration_test/integration_test.dart'; @@ -35,14 +37,18 @@ void main() { late gmaps.Circle circle; setUp(() { - circle = gmaps.Circle(); + circle = gmaps.Circle(gmaps.CircleOptions()); }); testWidgets('onTap gets called', (WidgetTester tester) async { CircleController(circle: circle, consumeTapEvents: true, onTap: onTap); // Trigger a click event... - gmaps.Event.trigger(circle, 'click', [gmaps.MapMouseEvent()]); + gmaps.event.trigger( + circle, + 'click', + gmaps.MapMouseEvent(), + ); // The event handling is now truly async. Wait for it... expect(await methodCalled, isTrue); @@ -53,7 +59,7 @@ void main() { final gmaps.CircleOptions options = gmaps.CircleOptions() ..draggable = true; - expect(circle.draggable, isNull); + expect(circle.isDraggableDefined(), isFalse); controller.update(options); @@ -98,7 +104,11 @@ void main() { PolygonController(polygon: polygon, consumeTapEvents: true, onTap: onTap); // Trigger a click event... - gmaps.Event.trigger(polygon, 'click', [gmaps.MapMouseEvent()]); + gmaps.event.trigger( + polygon, + 'click', + gmaps.MapMouseEvent(), + ); // The event handling is now truly async. Wait for it... expect(await methodCalled, isTrue); @@ -109,7 +119,7 @@ void main() { final gmaps.PolygonOptions options = gmaps.PolygonOptions() ..draggable = true; - expect(polygon.draggable, isNull); + expect(polygon.isDraggableDefined(), isFalse); controller.update(options); @@ -158,7 +168,11 @@ void main() { ); // Trigger a click event... - gmaps.Event.trigger(polyline, 'click', [gmaps.MapMouseEvent()]); + gmaps.event.trigger( + polyline, + 'click', + gmaps.MapMouseEvent(), + ); // The event handling is now truly async. Wait for it... expect(await methodCalled, isTrue); @@ -171,7 +185,7 @@ void main() { final gmaps.PolylineOptions options = gmaps.PolylineOptions() ..draggable = true; - expect(polyline.draggable, isNull); + expect(polyline.isDraggableDefined(), isFalse); controller.update(options); @@ -204,4 +218,51 @@ void main() { }); }); }); + + group('HeatmapController', () { + late visualization.HeatmapLayer heatmap; + + setUp(() { + heatmap = visualization.HeatmapLayer(); + }); + + testWidgets('update', (WidgetTester tester) async { + final HeatmapController controller = HeatmapController(heatmap: heatmap); + final visualization.HeatmapLayerOptions options = + visualization.HeatmapLayerOptions() + ..data = [gmaps.LatLng(0, 0)].toJS; + + expect(heatmap.data, hasLength(0)); + + controller.update(options); + + expect(heatmap.data, hasLength(1)); + }); + + group('remove', () { + late HeatmapController controller; + + setUp(() { + controller = HeatmapController(heatmap: heatmap); + }); + + testWidgets('drops gmaps instance', (WidgetTester tester) async { + controller.remove(); + + expect(controller.heatmap, isNull); + }); + + testWidgets('cannot call update after remove', + (WidgetTester tester) async { + final visualization.HeatmapLayerOptions options = + visualization.HeatmapLayerOptions()..dissipating = true; + + controller.remove(); + + expect(() { + controller.update(options); + }, throwsAssertionError); + }); + }); + }); } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart index ad3d3d4a8a4f..ec8198679d55 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart @@ -3,11 +3,13 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:js_interop'; import 'dart:ui'; import 'package:flutter_test/flutter_test.dart'; import 'package:google_maps/google_maps.dart' as gmaps; import 'package:google_maps/google_maps_geometry.dart' as geometry; +import 'package:google_maps/google_maps_visualization.dart' as visualization; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; // ignore: implementation_imports @@ -23,10 +25,10 @@ const double _acceptableDelta = 0.01; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - late gmaps.GMap map; + late gmaps.Map map; setUp(() { - map = gmaps.GMap(createDivElement()); + map = gmaps.Map(createDivElement()); }); group('CirclesController', () { @@ -108,10 +110,12 @@ void main() { final gmaps.Circle circle = controller.circles.values.first.circle!; - expect(circle.get('fillColor'), '#fabada'); - expect(circle.get('fillOpacity'), closeTo(0.5, _acceptableDelta)); - expect(circle.get('strokeColor'), '#c0ffee'); - expect(circle.get('strokeOpacity'), closeTo(1, _acceptableDelta)); + expect((circle.get('fillColor')! as JSString).toDart, '#fabada'); + expect((circle.get('fillOpacity')! as JSNumber).toDartDouble, + closeTo(0.5, _acceptableDelta)); + expect((circle.get('strokeColor')! as JSString).toDart, '#c0ffee'); + expect((circle.get('strokeOpacity')! as JSNumber).toDartDouble, + closeTo(1, _acceptableDelta)); }); }); @@ -197,10 +201,12 @@ void main() { final gmaps.Polygon polygon = controller.polygons.values.first.polygon!; - expect(polygon.get('fillColor'), '#fabada'); - expect(polygon.get('fillOpacity'), closeTo(0.5, _acceptableDelta)); - expect(polygon.get('strokeColor'), '#c0ffee'); - expect(polygon.get('strokeOpacity'), closeTo(1, _acceptableDelta)); + expect((polygon.get('fillColor')! as JSString).toDart, '#fabada'); + expect((polygon.get('fillOpacity')! as JSNumber).toDartDouble, + closeTo(0.5, _acceptableDelta)); + expect((polygon.get('strokeColor')! as JSString).toDart, '#c0ffee'); + expect((polygon.get('strokeOpacity')! as JSNumber).toDartDouble, + closeTo(1, _acceptableDelta)); }); testWidgets('Handle Polygons with holes', (WidgetTester tester) async { @@ -253,7 +259,7 @@ void main() { final gmaps.Polygon? polygon = controller.polygons.values.first.polygon; final gmaps.LatLng pointInHole = gmaps.LatLng(28.632, -68.401); - expect(geometry.Poly.containsLocation(pointInHole, polygon), false); + expect(geometry.poly.containsLocation(pointInHole, polygon!), false); }); testWidgets('Hole Path gets reversed to display correctly', @@ -279,7 +285,7 @@ void main() { controller.addPolygons(polygons); final gmaps.MVCArray?> paths = - controller.polygons.values.first.polygon!.paths!; + controller.polygons.values.first.polygon!.paths; expect(paths.getAt(1)?.getAt(0)?.lat, 28.745); expect(paths.getAt(1)?.getAt(1)?.lat, 29.57); @@ -365,8 +371,148 @@ void main() { final gmaps.Polyline line = controller.lines.values.first.line!; - expect(line.get('strokeColor'), '#fabada'); - expect(line.get('strokeOpacity'), closeTo(0.5, _acceptableDelta)); + expect((line.get('strokeColor')! as JSString).toDart, '#fabada'); + expect((line.get('strokeOpacity')! as JSNumber).toDartDouble, + closeTo(0.5, _acceptableDelta)); + }); + }); + + group('HeatmapsController', () { + late HeatmapsController controller; + + const List heatmapPoints = [ + WeightedLatLng(LatLng(37.782, -122.447)), + WeightedLatLng(LatLng(37.782, -122.445)), + WeightedLatLng(LatLng(37.782, -122.443)), + WeightedLatLng(LatLng(37.782, -122.441)), + WeightedLatLng(LatLng(37.782, -122.439)), + WeightedLatLng(LatLng(37.782, -122.437)), + WeightedLatLng(LatLng(37.782, -122.435)), + WeightedLatLng(LatLng(37.785, -122.447)), + WeightedLatLng(LatLng(37.785, -122.445)), + WeightedLatLng(LatLng(37.785, -122.443)), + WeightedLatLng(LatLng(37.785, -122.441)), + WeightedLatLng(LatLng(37.785, -122.439)), + WeightedLatLng(LatLng(37.785, -122.437)), + WeightedLatLng(LatLng(37.785, -122.435)) + ]; + + setUp(() { + controller = HeatmapsController(); + controller.bindToMap(123, map); + }); + + testWidgets('addHeatmaps', (WidgetTester tester) async { + final Set heatmaps = { + const Heatmap( + heatmapId: HeatmapId('1'), + data: heatmapPoints, + radius: HeatmapRadius.fromPixels(20), + ), + const Heatmap( + heatmapId: HeatmapId('2'), + data: heatmapPoints, + radius: HeatmapRadius.fromPixels(20), + ), + }; + + controller.addHeatmaps(heatmaps); + + expect(controller.heatmaps.length, 2); + expect(controller.heatmaps, contains(const HeatmapId('1'))); + expect(controller.heatmaps, contains(const HeatmapId('2'))); + expect(controller.heatmaps, isNot(contains(const HeatmapId('66')))); + }); + + testWidgets('changeHeatmaps', (WidgetTester tester) async { + final Set heatmaps = { + const Heatmap( + heatmapId: HeatmapId('1'), + data: [], + radius: HeatmapRadius.fromPixels(20), + ), + }; + controller.addHeatmaps(heatmaps); + + expect( + controller.heatmaps[const HeatmapId('1')]?.heatmap?.data, + hasLength(0), + ); + + final Set updatedHeatmaps = { + const Heatmap( + heatmapId: HeatmapId('1'), + data: [WeightedLatLng(LatLng(0, 0))], + radius: HeatmapRadius.fromPixels(20), + ), + }; + controller.changeHeatmaps(updatedHeatmaps); + + expect(controller.heatmaps.length, 1); + expect( + controller.heatmaps[const HeatmapId('1')]?.heatmap?.data, + hasLength(1), + ); + }); + + testWidgets('removeHeatmaps', (WidgetTester tester) async { + final Set heatmaps = { + const Heatmap( + heatmapId: HeatmapId('1'), + data: heatmapPoints, + radius: HeatmapRadius.fromPixels(20), + ), + const Heatmap( + heatmapId: HeatmapId('2'), + data: heatmapPoints, + radius: HeatmapRadius.fromPixels(20), + ), + const Heatmap( + heatmapId: HeatmapId('3'), + data: heatmapPoints, + radius: HeatmapRadius.fromPixels(20), + ), + }; + + controller.addHeatmaps(heatmaps); + + expect(controller.heatmaps.length, 3); + + // Remove some polylines... + final Set heatmapIdsToRemove = { + const HeatmapId('1'), + const HeatmapId('3'), + }; + + controller.removeHeatmaps(heatmapIdsToRemove); + + expect(controller.heatmaps.length, 1); + expect(controller.heatmaps, isNot(contains(const HeatmapId('1')))); + expect(controller.heatmaps, contains(const HeatmapId('2'))); + expect(controller.heatmaps, isNot(contains(const HeatmapId('3')))); + }); + + testWidgets('Converts colors to CSS', (WidgetTester tester) async { + final Set heatmaps = { + const Heatmap( + heatmapId: HeatmapId('1'), + data: heatmapPoints, + gradient: HeatmapGradient( + [HeatmapGradientColor(Color(0xFFFABADA), 0)], + ), + radius: HeatmapRadius.fromPixels(20), + ), + }; + + controller.addHeatmaps(heatmaps); + + final visualization.HeatmapLayer heatmap = + controller.heatmaps.values.first.heatmap!; + + expect( + heatmap.get('gradient'), + ['rgba(250, 186, 218, 0.00)', 'rgba(250, 186, 218, 1.00)'], + ); }); }); } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml index 85a89ed5bf96..e4c0cfabb962 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml @@ -1,29 +1,28 @@ name: google_maps_flutter_web_integration_tests publish_to: none -# Tests require flutter beta or greater to run. environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: sdk: flutter - google_maps_flutter_platform_interface: ^2.7.0 + google_maps_flutter_platform_interface: ^2.9.0 google_maps_flutter_web: path: ../ - web: ^0.5.0 + web: ^1.0.0 dev_dependencies: build_runner: ^2.1.1 flutter_test: sdk: flutter - google_maps: ^7.1.0 + google_maps: ^8.0.0 google_maps_flutter: ^2.2.0 # Needed for projection_test.dart - http: ">=0.13.0 <2.0.0" + http: ^1.2.2 integration_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 flutter: assets: diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html b/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html index 9cbd7be791d2..51b7253b8e1f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html @@ -6,10 +6,10 @@ Browser Tests - - + + - + diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart index cda20cf9f526..f56e0b02bd1b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart @@ -16,6 +16,7 @@ import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; import 'package:google_maps/google_maps.dart' as gmaps; +import 'package:google_maps/google_maps_visualization.dart' as visualization; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; import 'package:sanitize_html/sanitize_html.dart'; import 'package:stream_transform/stream_transform.dart'; @@ -34,6 +35,8 @@ part 'src/circles.dart'; part 'src/convert.dart'; part 'src/google_maps_controller.dart'; part 'src/google_maps_flutter_web.dart'; +part 'src/heatmap.dart'; +part 'src/heatmaps.dart'; part 'src/marker.dart'; part 'src/markers.dart'; part 'src/overlay.dart'; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index ee9100ddff01..f6af32046ccd 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -32,6 +32,11 @@ double _getCssOpacity(Color color) { return color.opacity; } +// Converts a [Color] into a valid CSS value rgba(R, G, B, A). +String _getCssColorWithAlpha(Color color) { + return 'rgba(${color.red}, ${color.green}, ${color.blue}, ${(color.alpha / 255).toStringAsFixed(2)})'; +} + // Converts options from the plugin into gmaps.MapOptions that can be used by the JS SDK. // The following options are not handled here, for various reasons: // The following are not available in web, because the map doesn't rotate there: @@ -195,12 +200,13 @@ LatLngBounds gmLatLngBoundsTolatLngBounds(gmaps.LatLngBounds latLngBounds) { ); } -CameraPosition _gmViewportToCameraPosition(gmaps.GMap map) { +CameraPosition _gmViewportToCameraPosition(gmaps.Map map) { return CameraPosition( - target: gmLatLngToLatLng(map.center ?? _nullGmapsLatLng), - bearing: map.heading?.toDouble() ?? 0, - tilt: map.tilt?.toDouble() ?? 0, - zoom: map.zoom?.toDouble() ?? 0, + target: + gmLatLngToLatLng(map.isCenterDefined() ? map.center : _nullGmapsLatLng), + bearing: map.isHeadingDefined() ? map.heading.toDouble() : 0, + tilt: map.isTiltDefined() ? map.tilt.toDouble() : 0, + zoom: map.isZoomDefined() ? map.zoom.toDouble() : 0, ); } @@ -252,8 +258,7 @@ gmaps.InfoWindowOptions? _infoWindowOptionsFromMarker(Marker marker) { // XSS attacks through the contents of the marker InfoWindow. // See: https://pub.dev/documentation/sanitize_html/latest/sanitize_html/sanitizeHtml.html // See: b/159137885, b/159598165 - // ignore: unsafe_html - snippet.innerHTML = sanitizeHtml(markerSnippet); + snippet.innerHTMLString = sanitizeHtml(markerSnippet); } container.appendChild(snippet); @@ -474,8 +479,35 @@ gmaps.CircleOptions _circleOptionsFromCircle(Circle circle) { return circleOptions; } +visualization.HeatmapLayerOptions _heatmapOptionsFromHeatmap(Heatmap heatmap) { + final Iterable? gradientColors = + heatmap.gradient?.colors.map((HeatmapGradientColor e) => e.color); + final visualization.HeatmapLayerOptions heatmapOptions = + visualization.HeatmapLayerOptions() + ..data = heatmap.data + .map( + (WeightedLatLng e) => visualization.WeightedLocation() + ..location = gmaps.LatLng(e.point.latitude, e.point.longitude) + ..weight = e.weight, + ) + .toList() + .toJS + ..dissipating = heatmap.dissipating + ..gradient = gradientColors == null + ? null + : [ + // Web needs a first color with 0 alpha + gradientColors.first.withAlpha(0), + ...gradientColors, + ].map(_getCssColorWithAlpha).toList() + ..maxIntensity = heatmap.maxIntensity + ..opacity = heatmap.opacity + ..radius = heatmap.radius.radius; + return heatmapOptions; +} + gmaps.PolygonOptions _polygonOptionsFromPolygon( - gmaps.GMap googleMap, Polygon polygon) { + gmaps.Map googleMap, Polygon polygon) { // Convert all points to GmLatLng final List path = polygon.points.map(_latLngToGmLatLng).toList(); @@ -496,7 +528,7 @@ gmaps.PolygonOptions _polygonOptionsFromPolygon( } return gmaps.PolygonOptions() - ..paths = paths + ..paths = paths.map((List e) => e.toJS).toList().toJS ..strokeColor = _getCssColor(polygon.strokeColor) ..strokeOpacity = _getCssOpacity(polygon.strokeColor) ..strokeWeight = polygon.strokeWidth @@ -550,12 +582,12 @@ bool _isPolygonClockwise(List path) { } gmaps.PolylineOptions _polylineOptionsFromPolyline( - gmaps.GMap googleMap, Polyline polyline) { + gmaps.Map googleMap, Polyline polyline) { final List paths = polyline.points.map(_latLngToGmLatLng).toList(); return gmaps.PolylineOptions() - ..path = paths + ..path = paths.toJS ..strokeWeight = polyline.width ..strokeColor = _getCssColor(polyline.color) ..strokeOpacity = _getCssOpacity(polyline.color) @@ -569,8 +601,8 @@ gmaps.PolylineOptions _polylineOptionsFromPolyline( // this.width = 10, } -// Translates a [CameraUpdate] into operations on a [gmaps.GMap]. -void _applyCameraUpdate(gmaps.GMap map, CameraUpdate update) { +// Translates a [CameraUpdate] into operations on a [gmaps.Map]. +void _applyCameraUpdate(gmaps.Map map, CameraUpdate update) { // Casts [value] to a JSON dictionary (string -> nullable object). [value] // must be a non-null JSON dictionary. Map asJsonObject(dynamic value) { @@ -587,19 +619,19 @@ void _applyCameraUpdate(gmaps.GMap map, CameraUpdate update) { case 'newCameraPosition': final Map position = asJsonObject(json[1]); final List latLng = asJsonList(position['target']); - map.heading = position['bearing'] as num?; - map.zoom = position['zoom'] as num?; + map.heading = position['bearing']! as num; + map.zoom = position['zoom']! as num; map.panTo( - gmaps.LatLng(latLng[0] as num?, latLng[1] as num?), + gmaps.LatLng(latLng[0]! as num, latLng[1]! as num), ); - map.tilt = position['tilt'] as num?; + map.tilt = position['tilt']! as num; case 'newLatLng': final List latLng = asJsonList(json[1]); - map.panTo(gmaps.LatLng(latLng[0] as num?, latLng[1] as num?)); + map.panTo(gmaps.LatLng(latLng[0]! as num, latLng[1]! as num)); case 'newLatLngZoom': final List latLng = asJsonList(json[1]); - map.zoom = json[2] as num?; - map.panTo(gmaps.LatLng(latLng[0] as num?, latLng[1] as num?)); + map.zoom = json[2]! as num; + map.panTo(gmaps.LatLng(latLng[0]! as num, latLng[1]! as num)); case 'newLatLngBounds': final List latLngPair = asJsonList(json[1]); final List latLng1 = asJsonList(latLngPair[0]); @@ -607,13 +639,13 @@ void _applyCameraUpdate(gmaps.GMap map, CameraUpdate update) { final double padding = json[2] as double; map.fitBounds( gmaps.LatLngBounds( - gmaps.LatLng(latLng1[0] as num?, latLng1[1] as num?), - gmaps.LatLng(latLng2[0] as num?, latLng2[1] as num?), + gmaps.LatLng(latLng1[0]! as num, latLng1[1]! as num), + gmaps.LatLng(latLng2[0]! as num, latLng2[1]! as num), ), - padding, + padding.toJS, ); case 'scrollBy': - map.panBy(json[1] as num?, json[2] as num?); + map.panBy(json[1]! as num, json[2]! as num); case 'zoomBy': gmaps.LatLng? focusLatLng; final double zoomDelta = json[1] as double? ?? 0; @@ -631,44 +663,45 @@ void _applyCameraUpdate(gmaps.GMap map, CameraUpdate update) { // print('Error computing new focus LatLng. JS Error: ' + e.toString()); } } - map.zoom = (map.zoom ?? 0) + newZoomDelta; + map.zoom = (map.isZoomDefined() ? map.zoom : 0) + newZoomDelta; if (focusLatLng != null) { map.panTo(focusLatLng); } case 'zoomIn': - map.zoom = (map.zoom ?? 0) + 1; + map.zoom = (map.isZoomDefined() ? map.zoom : 0) + 1; case 'zoomOut': - map.zoom = (map.zoom ?? 0) - 1; + map.zoom = (map.isZoomDefined() ? map.zoom : 0) - 1; case 'zoomTo': - map.zoom = json[1] as num?; + map.zoom = json[1]! as num; default: throw UnimplementedError('Unimplemented CameraMove: ${json[0]}.'); } } // original JS by: Byron Singh (https://stackoverflow.com/a/30541162) -gmaps.LatLng _pixelToLatLng(gmaps.GMap map, int x, int y) { +gmaps.LatLng _pixelToLatLng(gmaps.Map map, int x, int y) { final gmaps.LatLngBounds? bounds = map.bounds; final gmaps.Projection? projection = map.projection; - final num? zoom = map.zoom; assert( bounds != null, 'Map Bounds required to compute LatLng of screen x/y.'); assert(projection != null, 'Map Projection required to compute LatLng of screen x/y'); - assert(zoom != null, + assert(map.isZoomDefined(), 'Current map zoom level required to compute LatLng of screen x/y'); + final num zoom = map.zoom; + final gmaps.LatLng ne = bounds!.northEast; final gmaps.LatLng sw = bounds.southWest; - final gmaps.Point topRight = projection!.fromLatLngToPoint!(ne)!; - final gmaps.Point bottomLeft = projection.fromLatLngToPoint!(sw)!; + final gmaps.Point topRight = projection!.fromLatLngToPoint(ne)!; + final gmaps.Point bottomLeft = projection.fromLatLngToPoint(sw)!; - final int scale = 1 << (zoom!.toInt()); // 2 ^ zoom + final int scale = 1 << (zoom.toInt()); // 2 ^ zoom final gmaps.Point point = - gmaps.Point((x / scale) + bottomLeft.x!, (y / scale) + topRight.y!); + gmaps.Point((x / scale) + bottomLeft.x, (y / scale) + topRight.y); - return projection.fromPointToLatLng!(point)!; + return projection.fromPointToLatLng(point)!; } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart index 8c75229eb0cb..87aa83041749 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart @@ -31,6 +31,13 @@ extension TrustedInnerHTML on web.HTMLElement { external set trustedInnerHTML(web.TrustedHTML trustedHTML); } +/// This extension allows supporting both web:0.5.1 and web:1.0.0. +/// To be removed once we stop using web:0.5.1. +extension InnerHTMLString on web.HTMLElement { + @JS('innerHTML') + external set innerHTMLString(String value); +} + /// Allows creating a TrustedHTML object from a string, with no arguments. extension CreateHTMLNoArgs on web.TrustedTypePolicy { /// Allows calling `createHTML` with only the `input` argument. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index 37c1e8a2ffff..89f5e33e2387 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -6,14 +6,14 @@ part of '../google_maps_flutter_web.dart'; /// Type used when passing an override to the _createMap function. @visibleForTesting -typedef DebugCreateMapFunction = gmaps.GMap Function( +typedef DebugCreateMapFunction = gmaps.Map Function( HTMLElement div, gmaps.MapOptions options); /// Type used when passing an override to the _setOptions function. @visibleForTesting typedef DebugSetOptionsFunction = void Function(gmaps.MapOptions options); -/// Encapsulates a [gmaps.GMap], its events, and where in the DOM it's rendered. +/// Encapsulates a [gmaps.Map], its events, and where in the DOM it's rendered. class GoogleMapController { /// Initializes the GMap, and the sub-controllers related to it. Wires events. GoogleMapController({ @@ -30,9 +30,11 @@ class GoogleMapController { _polylines = mapObjects.polylines, _circles = mapObjects.circles, _clusterManagers = mapObjects.clusterManagers, + _heatmaps = mapObjects.heatmaps, _tileOverlays = mapObjects.tileOverlays, _lastMapConfiguration = mapConfiguration { _circlesController = CirclesController(stream: _streamController); + _heatmapsController = HeatmapsController(); _polygonsController = PolygonsController(stream: _streamController); _polylinesController = PolylinesController(stream: _streamController); _clusterManagersController = @@ -45,7 +47,7 @@ class GoogleMapController { // Register the view factory that will hold the `_div` that holds the map in the DOM. // The `_div` needs to be created outside of the ViewFactory (and cached!) so we can - // use it to create the [gmaps.GMap] in the `init()` method of this class. + // use it to create the [gmaps.Map] in the `init()` method of this class. _div = createDivElement() ..id = _getViewType(mapId) ..style.width = '100%' @@ -66,6 +68,7 @@ class GoogleMapController { final Set _polylines; final Set _circles; final Set _clusterManagers; + final Set _heatmaps; Set _tileOverlays; // The configuration passed by the user, before converting to gmaps. @@ -108,7 +111,7 @@ class GoogleMapController { gmaps.TrafficLayer? get trafficLayer => _trafficLayer; // The underlying GMap instance. This is the interface with the JS SDK. - gmaps.GMap? _googleMap; + gmaps.Map? _googleMap; // The StreamController used by this controller and the geometry ones. final StreamController> _streamController; @@ -122,6 +125,7 @@ class GoogleMapController { // Geometry controllers, for different features of the map. CirclesController? _circlesController; + HeatmapsController? _heatmapsController; PolygonsController? _polygonsController; PolylinesController? _polylinesController; MarkersController? _markersController; @@ -146,6 +150,7 @@ class GoogleMapController { DebugSetOptionsFunction? setOptions, MarkersController? markers, CirclesController? circles, + HeatmapsController? heatmaps, PolygonsController? polygons, PolylinesController? polylines, ClusterManagersController? clusterManagers, @@ -155,6 +160,7 @@ class GoogleMapController { _overrideSetOptions = setOptions; _markersController = markers ?? _markersController; _circlesController = circles ?? _circlesController; + _heatmapsController = heatmaps ?? _heatmapsController; _polygonsController = polygons ?? _polygonsController; _polylinesController = polylines ?? _polylinesController; _clusterManagersController = clusterManagers ?? _clusterManagersController; @@ -164,11 +170,11 @@ class GoogleMapController { DebugCreateMapFunction? _overrideCreateMap; DebugSetOptionsFunction? _overrideSetOptions; - gmaps.GMap _createMap(HTMLElement div, gmaps.MapOptions options) { + gmaps.Map _createMap(HTMLElement div, gmaps.MapOptions options) { if (_overrideCreateMap != null) { return _overrideCreateMap!(div, options); } - return gmaps.GMap(div, options); + return gmaps.Map(div, options); } /// A flag that returns true if the controller has been initialized or not. @@ -179,7 +185,7 @@ class GoogleMapController { /// /// (Also initializes the geometry/traffic layers.) /// - /// The first part of this method starts the rendering of a [gmaps.GMap] inside + /// The first part of this method starts the rendering of a [gmaps.Map] inside /// of the target [_div], with configuration from `rawOptions`. It then stores /// the created GMap in the [_googleMap] attribute. /// @@ -207,7 +213,7 @@ class GoogleMapController { } // Create the map... - final gmaps.GMap map = _createMap(_div, options); + final gmaps.Map map = _createMap(_div, options); _googleMap = map; _attachMapEvents(map); @@ -221,12 +227,12 @@ class GoogleMapController { } // Funnels map gmap events into the plugin's stream controller. - void _attachMapEvents(gmaps.GMap map) { + void _attachMapEvents(gmaps.Map map) { map.onTilesloaded.first.then((void _) { // Report the map as ready to go the first time the tiles load _streamController.add(WebMapReadyEvent(_mapId)); }); - map.onClick.listen((gmaps.IconMouseEvent event) { + map.onClick.listen((gmaps.MapMouseEventOrIconMouseEvent event) { assert(event.latLng != null); _streamController.add( MapTapEvent(_mapId, gmLatLngToLatLng(event.latLng!)), @@ -254,7 +260,7 @@ class GoogleMapController { } // Binds the Geometry controllers to a map instance - void _attachGeometryControllers(gmaps.GMap map) { + void _attachGeometryControllers(gmaps.Map map) { // Now we can add the initial geometry. // And bind the (ready) map instance to the other geometry controllers. // @@ -263,6 +269,8 @@ class GoogleMapController { // null. assert(_circlesController != null, 'Cannot attach a map to a null CirclesController instance.'); + assert(_heatmapsController != null, + 'Cannot attach a map to a null HeatmapsController instance.'); assert(_polygonsController != null, 'Cannot attach a map to a null PolygonsController instance.'); assert(_polylinesController != null, @@ -275,6 +283,7 @@ class GoogleMapController { 'Cannot attach a map to a null TileOverlaysController instance.'); _circlesController!.bindToMap(_mapId, map); + _heatmapsController!.bindToMap(_mapId, map); _polygonsController!.bindToMap(_mapId, map); _polylinesController!.bindToMap(_mapId, map); _markersController!.bindToMap(_mapId, map); @@ -301,6 +310,7 @@ class GoogleMapController { _markersController!.addMarkers(_markers); _circlesController!.addCircles(_circles); + _heatmapsController!.addHeatmaps(_heatmaps); _polygonsController!.addPolygons(_polygons); _polylinesController!.addPolylines(_polylines); _tileOverlaysController!.addTileOverlays(_tileOverlays); @@ -373,7 +383,7 @@ class GoogleMapController { } // Attaches/detaches a Traffic Layer on the passed `map` if `attach` is true/false. - void _setTrafficLayer(gmaps.GMap map, bool attach) { + void _setTrafficLayer(gmaps.Map map, bool attach) { if (attach && _trafficLayer == null) { _trafficLayer = gmaps.TrafficLayer()..set('map', map); } @@ -405,7 +415,7 @@ class GoogleMapController { final gmaps.Point point = toScreenLocation(_googleMap!, _latLngToGmLatLng(latLng)); - return ScreenCoordinate(x: point.x!.toInt(), y: point.y!.toInt()); + return ScreenCoordinate(x: point.x.toInt(), y: point.y.toInt()); } /// Returns the [LatLng] for a `screenCoordinate` (in pixels) of the viewport. @@ -428,10 +438,10 @@ class GoogleMapController { /// Returns the zoom level of the current viewport. Future getZoomLevel() async { assert(_googleMap != null, 'Cannot get zoom level of a null map.'); - assert(_googleMap!.zoom != null, + assert(_googleMap!.isZoomDefined(), 'Zoom level should not be null. Is the map correctly initialized?'); - return _googleMap!.zoom!.toDouble(); + return _googleMap!.zoom.toDouble(); } // Geometry manipulation @@ -439,12 +449,25 @@ class GoogleMapController { /// Applies [CircleUpdates] to the currently managed circles. void updateCircles(CircleUpdates updates) { assert( - _circlesController != null, 'Cannot update circles after dispose().'); + _circlesController != null, + 'Cannot update circles after dispose().', + ); _circlesController?.addCircles(updates.circlesToAdd); _circlesController?.changeCircles(updates.circlesToChange); _circlesController?.removeCircles(updates.circleIdsToRemove); } + /// Applies [HeatmapUpdates] to the currently managed heatmaps. + void updateHeatmaps(HeatmapUpdates updates) { + assert( + _heatmapsController != null, + 'Cannot update heatmaps after dispose().', + ); + _heatmapsController?.addHeatmaps(updates.heatmapsToAdd); + _heatmapsController?.changeHeatmaps(updates.heatmapsToChange); + _heatmapsController?.removeHeatmaps(updates.heatmapIdsToRemove); + } + /// Applies [PolygonUpdates] to the currently managed polygons. void updatePolygons(PolygonUpdates updates) { assert( @@ -531,6 +554,7 @@ class GoogleMapController { _widget = null; _googleMap = null; _circlesController = null; + _heatmapsController = null; _polygonsController = null; _polylinesController = null; _markersController = null; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart index 16618b59a6e8..c49b5ed67392 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart @@ -90,6 +90,15 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { _map(mapId).updateCircles(circleUpdates); } + /// Applies the passed in `heatmapUpdates` to the `mapId`. + @override + Future updateHeatmaps( + HeatmapUpdates heatmapUpdates, { + required int mapId, + }) async { + _map(mapId).updateHeatmaps(heatmapUpdates); + } + @override Future updateTileOverlays({ required Set newTileOverlays, diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/heatmap.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/heatmap.dart new file mode 100644 index 000000000000..1e792f44ca17 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/heatmap.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. + +part of '../google_maps_flutter_web.dart'; + +/// The `HeatmapController` class wraps a [visualization.HeatmapLayer] and its `onTap` behavior. +class HeatmapController { + /// Creates a `HeatmapController`, which wraps a [visualization.HeatmapLayer] object and its `onTap` behavior. + HeatmapController({required visualization.HeatmapLayer heatmap}) + : _heatmap = heatmap; + + visualization.HeatmapLayer? _heatmap; + + /// Returns the wrapped [visualization.HeatmapLayer]. Only used for testing. + @visibleForTesting + visualization.HeatmapLayer? get heatmap => _heatmap; + + /// Updates the options of the wrapped [visualization.HeatmapLayer] object. + /// + /// This cannot be called after [remove]. + void update(visualization.HeatmapLayerOptions options) { + assert(_heatmap != null, 'Cannot `update` Heatmap after calling `remove`.'); + _heatmap!.options = options; + } + + /// Disposes of the currently wrapped [visualization.HeatmapLayer]. + void remove() { + if (_heatmap != null) { + _heatmap!.map = null; + _heatmap = null; + } + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/heatmaps.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/heatmaps.dart new file mode 100644 index 000000000000..2d235515a297 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/heatmaps.dart @@ -0,0 +1,57 @@ +// 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. + +part of '../google_maps_flutter_web.dart'; + +/// This class manages all the [HeatmapController]s associated to a [GoogleMapController]. +class HeatmapsController extends GeometryController { + /// Initialize the cache + HeatmapsController() + : _heatmapIdToController = {}; + + // A cache of [HeatmapController]s indexed by their [HeatmapId]. + final Map _heatmapIdToController; + + /// Returns the cache of [HeatmapController]s. Test only. + @visibleForTesting + Map get heatmaps => _heatmapIdToController; + + /// Adds a set of [Heatmap] objects to the cache. + /// + /// Wraps each [Heatmap] into its corresponding [HeatmapController]. + void addHeatmaps(Set heatmapsToAdd) { + heatmapsToAdd.forEach(_addHeatmap); + } + + void _addHeatmap(Heatmap heatmap) { + final visualization.HeatmapLayerOptions heatmapOptions = + _heatmapOptionsFromHeatmap(heatmap); + final visualization.HeatmapLayer gmHeatmap = + visualization.HeatmapLayer(heatmapOptions); + gmHeatmap.map = googleMap; + final HeatmapController controller = HeatmapController(heatmap: gmHeatmap); + _heatmapIdToController[heatmap.heatmapId] = controller; + } + + /// Updates a set of [Heatmap] objects with new options. + void changeHeatmaps(Set heatmapsToChange) { + heatmapsToChange.forEach(_changeHeatmap); + } + + void _changeHeatmap(Heatmap heatmap) { + final HeatmapController? heatmapController = + _heatmapIdToController[heatmap.heatmapId]; + heatmapController?.update(_heatmapOptionsFromHeatmap(heatmap)); + } + + /// Removes a set of [HeatmapId]s from the cache. + void removeHeatmaps(Set heatmapIdsToRemove) { + for (final HeatmapId heatmapId in heatmapIdsToRemove) { + final HeatmapController? heatmapController = + _heatmapIdToController[heatmapId]; + heatmapController?.remove(); + _heatmapIdToController.remove(heatmapId); + } + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker_clustering.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker_clustering.dart index d4b5ed3bd70e..8dbb4308ba63 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker_clustering.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker_clustering.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:js_interop'; import 'package:google_maps/google_maps.dart' as gmaps; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; @@ -43,7 +44,7 @@ class ClusterManagersController extends GeometryController { final MarkerClusterer markerClusterer = createMarkerClusterer( googleMap, (gmaps.MapMouseEvent event, MarkerClustererCluster cluster, - gmaps.GMap map) => + gmaps.Map map) => _clusterClicked( clusterManager.clusterManagerId, event, cluster, map)); @@ -109,7 +110,7 @@ class ClusterManagersController extends GeometryController { ClusterManagerId clusterManagerId, gmaps.MapMouseEvent event, MarkerClustererCluster markerClustererCluster, - gmaps.GMap map) { + gmaps.Map map) { if (markerClustererCluster.count > 0 && markerClustererCluster.bounds != null) { final Cluster cluster = @@ -127,7 +128,7 @@ class ClusterManagersController extends GeometryController { final List markerIds = markerClustererCluster.markers .map((gmaps.Marker marker) => - MarkerId(marker.get('markerId')! as String)) + MarkerId((marker.get('markerId')! as JSString).toDart)) .toList(); return Cluster( clusterManagerId, diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker_clustering_js_interop.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker_clustering_js_interop.dart index e3bf42b4e712..80e7e5fc1c1e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker_clustering_js_interop.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker_clustering_js_interop.dart @@ -16,7 +16,7 @@ import 'package:google_maps/google_maps.dart' as gmaps; typedef ClusterClickHandler = void Function( gmaps.MapMouseEvent, MarkerClustererCluster, - gmaps.GMap, + gmaps.Map, ); /// The [MarkerClustererOptions] object used to initialize [MarkerClusterer]. @@ -27,7 +27,7 @@ typedef ClusterClickHandler = void Function( extension type MarkerClustererOptions._(JSObject _) implements JSObject { /// Constructs a new [MarkerClustererOptions] object. factory MarkerClustererOptions({ - gmaps.GMap? map, + gmaps.Map? map, List? markers, ClusterClickHandler? onClusterClick, }) => @@ -37,7 +37,7 @@ extension type MarkerClustererOptions._(JSObject _) implements JSObject { onClusterClick: onClusterClick != null ? ((JSAny event, MarkerClustererCluster cluster, JSAny map) => onClusterClick(event as gmaps.MapMouseEvent, cluster, - map as gmaps.GMap)).toJS + map as gmaps.Map)).toJS : null, ); @@ -47,8 +47,8 @@ extension type MarkerClustererOptions._(JSObject _) implements JSObject { JSFunction? onClusterClick, }); - /// Returns the [gmaps.GMap] object. - gmaps.GMap? get map => _map as gmaps.GMap?; + /// Returns the [gmaps.Map] object. + gmaps.Map? get map => _map as gmaps.Map?; @JS('map') external JSAny? get _map; @@ -152,10 +152,10 @@ extension type MarkerClusterer._(JSObject _) implements JSObject { external void render(); } -/// Creates [MarkerClusterer] object with given [gmaps.GMap] and +/// Creates [MarkerClusterer] object with given [gmaps.Map] and /// [ClusterClickHandler]. MarkerClusterer createMarkerClusterer( - gmaps.GMap map, ClusterClickHandler onClusterClickHandler) { + gmaps.Map map, ClusterClickHandler onClusterClickHandler) { final MarkerClustererOptions options = MarkerClustererOptions( map: map, onClusterClick: onClusterClickHandler, diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart index 8bcf8b7f942d..f5204403528a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart @@ -60,7 +60,7 @@ class MarkersController extends GeometryController { final gmaps.Marker gmMarker = gmaps.Marker(markerOptions); - gmMarker.set('markerId', marker.markerId.value); + gmMarker.set('markerId', marker.markerId.value.toJS); if (marker.clusterManagerId != null) { _clusterManagersController.addItem(marker.clusterManagerId!, gmMarker); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlay.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlay.dart index 29823d00b9f3..1b4de3e9f4c4 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlay.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlay.dart @@ -49,7 +49,7 @@ class TileOverlayController { img.setAttribute('decoding', 'async'); _tileOverlay.tileProvider! - .getTile(tileCoord!.x!.toInt(), tileCoord.y!.toInt(), zoom?.toInt()) + .getTile(tileCoord!.x.toInt(), tileCoord.y.toInt(), zoom?.toInt()) .then((Tile tile) { if (tile.data == null) { return; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlays.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlays.dart index 26c6a7573a4f..59015a4e4b90 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlays.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlays.dart @@ -19,7 +19,7 @@ class TileOverlaysController extends GeometryController { tileOverlayController, (TileOverlayController c) => c.tileOverlay.zIndex); - googleMap.overlayMapTypes!.insertAt(index, tileOverlayController.gmMapType); + googleMap.overlayMapTypes.insertAt(index, tileOverlayController.gmMapType); _visibleTileOverlays.insert(index, tileOverlayController); } @@ -30,7 +30,7 @@ class TileOverlaysController extends GeometryController { return; } - googleMap.overlayMapTypes!.removeAt(index); + googleMap.overlayMapTypes.removeAt(index); _visibleTileOverlays.removeAt(index); } @@ -93,7 +93,7 @@ class TileOverlaysController extends GeometryController { if (controller != null && controller.tileOverlay.visible) { final int i = _visibleTileOverlays.indexOf(controller); // This causes the map to reload the overlay. - googleMap.overlayMapTypes!.setAt(i, controller.gmMapType); + googleMap.overlayMapTypes.setAt(i, controller.gmMapType); } } } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/third_party/to_screen_location/to_screen_location.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/third_party/to_screen_location/to_screen_location.dart index fc25b18b43ec..fc206eb6f912 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/third_party/to_screen_location/to_screen_location.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/third_party/to_screen_location/to_screen_location.dart @@ -28,30 +28,30 @@ import 'package:google_maps/google_maps.dart' as gmaps; /// (not of the whole screen/app). /// /// See: https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/Projection#public-point-toscreenlocation-latlng-location -gmaps.Point toScreenLocation(gmaps.GMap map, gmaps.LatLng coords) { - final num? zoom = map.zoom; - final gmaps.LatLngBounds? bounds = map.bounds; - final gmaps.Projection? projection = map.projection; - - assert( - bounds != null, 'Map Bounds required to compute screen x/y of LatLng.'); - assert(projection != null, +gmaps.Point toScreenLocation(gmaps.Map map, gmaps.LatLng coords) { + assert(map.bounds != null, + 'Map Bounds required to compute screen x/y of LatLng.'); + assert(map.projection != null, 'Map Projection required to compute screen x/y of LatLng.'); - assert(zoom != null, + assert(map.isZoomDefined(), 'Current map zoom level required to compute screen x/y of LatLng.'); - final gmaps.LatLng ne = bounds!.northEast; + final gmaps.LatLngBounds bounds = map.bounds!; + final gmaps.Projection projection = map.projection!; + final num zoom = map.zoom; + + final gmaps.LatLng ne = bounds.northEast; final gmaps.LatLng sw = bounds.southWest; - final gmaps.Point topRight = projection!.fromLatLngToPoint!(ne)!; - final gmaps.Point bottomLeft = projection.fromLatLngToPoint!(sw)!; + final gmaps.Point topRight = projection.fromLatLngToPoint(ne)!; + final gmaps.Point bottomLeft = projection.fromLatLngToPoint(sw)!; - final int scale = 1 << (zoom!.toInt()); // 2 ^ zoom + final int scale = 1 << (zoom.toInt()); // 2 ^ zoom - final gmaps.Point worldPoint = projection.fromLatLngToPoint!(coords)!; + final gmaps.Point worldPoint = projection.fromLatLngToPoint(coords)!; return gmaps.Point( - ((worldPoint.x! - bottomLeft.x!) * scale).toInt(), - ((worldPoint.y! - topRight.y!) * scale).toInt(), + ((worldPoint.x - bottomLeft.x) * scale).toInt(), + ((worldPoint.y - topRight.y) * scale).toInt(), ); } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/types.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/types.dart index d4e87799f4b3..1eec81a4f1e8 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/types.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/types.dart @@ -14,17 +14,17 @@ typedef LatLngCallback = void Function(gmaps.LatLng latLng); /// The base class for all "geometry" group controllers. /// /// This lets all Geometry controllers ([MarkersController], [CirclesController], -/// [PolygonsController], [PolylinesController]) to be bound to a [gmaps.GMap] +/// [PolygonsController], [PolylinesController]) to be bound to a [gmaps.Map] /// instance and our internal `mapId` value. abstract class GeometryController { /// The GMap instance that this controller operates on. - late gmaps.GMap googleMap; + late gmaps.Map googleMap; /// The map ID for events. late int mapId; - /// Binds a `mapId` and the [gmaps.GMap] instance to this controller. - void bindToMap(int mapId, gmaps.GMap googleMap) { + /// Binds a `mapId` and the [gmaps.Map] instance to this controller. + void bindToMap(int mapId, gmaps.Map googleMap) { this.mapId = mapId; this.googleMap = googleMap; } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index 76707dd7c1e9..7ed3d99fed5e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -2,11 +2,11 @@ name: google_maps_flutter_web description: Web platform implementation of google_maps_flutter repository: https://github.com/flutter/packages/tree/main/packages/google_maps_flutter/google_maps_flutter_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22 -version: 0.5.8 +version: 0.5.10 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: @@ -22,11 +22,11 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - google_maps: ^7.1.0 - google_maps_flutter_platform_interface: ^2.7.0 + google_maps: ^8.0.0 + google_maps_flutter_platform_interface: ^2.9.0 sanitize_html: ^2.0.0 stream_transform: ^2.0.0 - web: ^0.5.1 + web: ">=0.5.1 <2.0.0" dev_dependencies: flutter_test: diff --git a/packages/google_sign_in/google_sign_in/CHANGELOG.md b/packages/google_sign_in/google_sign_in/CHANGELOG.md index fa7ffaee5a15..24564442c8f9 100644 --- a/packages/google_sign_in/google_sign_in/CHANGELOG.md +++ b/packages/google_sign_in/google_sign_in/CHANGELOG.md @@ -1,5 +1,7 @@ -## NEXT +## 6.2.2 +* Adds `missing_code_block_language_in_doc_comment` lint. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. * Updates support matrix in README to indicate that iOS 11 is no longer supported. * Clients on versions of Flutter that still support iOS 11 can continue to use this package with iOS 11, but will not receive any further updates to the iOS implementation. diff --git a/packages/google_sign_in/google_sign_in/example/android/app/build.gradle b/packages/google_sign_in/google_sign_in/example/android/app/build.gradle index 422b58cc5199..471d8cfed7c8 100644 --- a/packages/google_sign_in/google_sign_in/example/android/app/build.gradle +++ b/packages/google_sign_in/google_sign_in/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.googlesigninexample' compileSdk flutter.compileSdkVersion @@ -32,8 +30,7 @@ android { defaultConfig { applicationId "io.flutter.plugins.googlesigninexample" minSdkVersion flutter.minSdkVersion - targetSdkVersion 28 - multiDexEnabled true + targetSdkVersion 35 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/packages/google_sign_in/google_sign_in/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/google_sign_in/google_sign_in/example/android/app/gradle/wrapper/gradle-wrapper.properties index 609ab8e6c8b5..d951fac2bf31 100644 --- a/packages/google_sign_in/google_sign_in/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ b/packages/google_sign_in/google_sign_in/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/packages/google_sign_in/google_sign_in/example/android/app/src/main/AndroidManifest.xml b/packages/google_sign_in/google_sign_in/example/android/app/src/main/AndroidManifest.xml index 22a34d7218f7..11d4b6948806 100644 --- a/packages/google_sign_in/google_sign_in/example/android/app/src/main/AndroidManifest.xml +++ b/packages/google_sign_in/google_sign_in/example/android/app/src/main/AndroidManifest.xml @@ -8,6 +8,7 @@ android:theme="@android:style/Theme.Black.NoTitleBar" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection" android:hardwareAccelerated="true" + android:exported="true" android:windowSoftInputMode="adjustResize"> diff --git a/packages/google_sign_in/google_sign_in/example/android/build.gradle b/packages/google_sign_in/google_sign_in/example/android/build.gradle index cec92de922cf..b9db5700753a 100644 --- a/packages/google_sign_in/google_sign_in/example/android/build.gradle +++ b/packages/google_sign_in/google_sign_in/example/android/build.gradle @@ -1,14 +1,3 @@ -buildscript { - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' - } -} - 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/google_sign_in/google_sign_in/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/google_sign_in/google_sign_in/example/android/gradle/wrapper/gradle-wrapper.properties index e1ca574ef017..3c85cfe057a1 100644 --- a/packages/google_sign_in/google_sign_in/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/google_sign_in/google_sign_in/example/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/google_sign_in/google_sign_in/example/android/settings.gradle b/packages/google_sign_in/google_sign_in/example/android/settings.gradle index e54a7e1fd6e5..0667903d5724 100644 --- a/packages/google_sign_in/google_sign_in/example/android/settings.gradle +++ b/packages/google_sign_in/google_sign_in/example/android/settings.gradle @@ -1,28 +1,27 @@ -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 flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") -def plugins = new Properties() -def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') -if (pluginsFile.exists()) { - pluginsFile.withInputStream { stream -> plugins.load(stream) } -} - -plugins.each { name, path -> - def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() - include ":$name" - project(":$name").projectDir = pluginDirectory + 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/google_sign_in/google_sign_in/example/macos/Podfile b/packages/google_sign_in/google_sign_in/example/macos/Podfile index 9ec46f8cd53c..66f6172bbb39 100644 --- a/packages/google_sign_in/google_sign_in/example/macos/Podfile +++ b/packages/google_sign_in/google_sign_in/example/macos/Podfile @@ -28,7 +28,6 @@ flutter_macos_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) end 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 19a6bf6e9462..e4fe3eae18f2 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: @@ -20,7 +20,7 @@ dependencies: http: ">=0.13.0 <2.0.0" dev_dependencies: - espresso: ^0.2.0 + espresso: ^0.4.0 flutter_test: sdk: flutter integration_test: diff --git a/packages/google_sign_in/google_sign_in/example/web/index.html b/packages/google_sign_in/google_sign_in/example/web/index.html index eff8f4effadb..d68026f3d90e 100644 --- a/packages/google_sign_in/google_sign_in/example/web/index.html +++ b/packages/google_sign_in/google_sign_in/example/web/index.html @@ -7,17 +7,8 @@ Google Sign-in Example - - + diff --git a/packages/google_sign_in/google_sign_in/lib/testing.dart b/packages/google_sign_in/google_sign_in/lib/testing.dart index e519b34b199a..23510a2c4a70 100644 --- a/packages/google_sign_in/google_sign_in/lib/testing.dart +++ b/packages/google_sign_in/google_sign_in/lib/testing.dart @@ -10,7 +10,7 @@ import 'package:flutter/services.dart' show MethodCall; /// /// Example usage: /// -/// ``` +/// ```dart /// GoogleSignIn googleSignIn; /// FakeSignInBackend fakeSignInBackend; /// diff --git a/packages/google_sign_in/google_sign_in/pubspec.yaml b/packages/google_sign_in/google_sign_in/pubspec.yaml index f06595a46103..c19b4c2b0974 100644 --- a/packages/google_sign_in/google_sign_in/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in/pubspec.yaml @@ -3,11 +3,11 @@ description: Flutter plugin for Google Sign-In, a secure authentication system for signing in with a Google account. repository: https://github.com/flutter/packages/tree/main/packages/google_sign_in/google_sign_in issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+google_sign_in%22 -version: 6.2.1 +version: 6.2.2 environment: - sdk: ">=3.2.0 <4.0.0" - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -36,7 +36,7 @@ dev_dependencies: http: ">=0.13.0 <2.0.0" integration_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 topics: - authentication diff --git a/packages/google_sign_in/google_sign_in_android/CHANGELOG.md b/packages/google_sign_in/google_sign_in_android/CHANGELOG.md index e0e0bf852627..35af262af528 100644 --- a/packages/google_sign_in/google_sign_in_android/CHANGELOG.md +++ b/packages/google_sign_in/google_sign_in_android/CHANGELOG.md @@ -1,3 +1,32 @@ +## 6.1.33 + +* Updates Pigeon for non-nullable collection type support. + +## 6.1.32 + +* Updates Java compatibility version to 11. +* Updates minimum supported SDK version to Flutter 3.24/Dart 3.5. + +## 6.1.31 + +* Bumps `com.google.guava:guava` from `32.0.1` to `33.3.1`. + +## 6.1.30 + +* Temporarily downgrades Guava from version 33.3.0 to 32.0.1 to fix an R8 related error. + +## 6.1.29 + +* Updates Guava to version 33.3.0. + +## 6.1.28 + +* Updates lint checks to ignore NewerVersionAvailable. + +## 6.1.27 + +* Updates AGP version to 8.5.0. + ## 6.1.26 * Removes additional references to the v1 Android embedding. diff --git a/packages/google_sign_in/google_sign_in_android/README.md b/packages/google_sign_in/google_sign_in_android/README.md index 7a5bcabbb160..aeaeb9df6e93 100644 --- a/packages/google_sign_in/google_sign_in_android/README.md +++ b/packages/google_sign_in/google_sign_in_android/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/google_sign_in -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/google_sign_in/google_sign_in_android/android/build.gradle b/packages/google_sign_in/google_sign_in_android/android/build.gradle index 777d4ef934c1..11fb6c7a7101 100644 --- a/packages/google_sign_in/google_sign_in_android/android/build.gradle +++ b/packages/google_sign_in/google_sign_in_android/android/build.gradle @@ -8,7 +8,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.2.1' + classpath 'com.android.tools.build:gradle:8.5.0' } } @@ -22,10 +22,7 @@ rootProject.allprojects { apply plugin: 'com.android.library' android { - // Conditional for compatibility with AGP <4.2. - if (project.android.hasProperty("namespace")) { - namespace 'io.flutter.plugins.googlesignin' - } + namespace 'io.flutter.plugins.googlesignin' compileSdk 34 defaultConfig { @@ -34,14 +31,14 @@ android { } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } lintOptions { checkAllWarnings true warningsAsErrors true - disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency' + disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency', 'NewerVersionAvailable' } @@ -60,7 +57,7 @@ android { dependencies { implementation 'com.google.android.gms:play-services-auth:21.0.0' - implementation 'com.google.guava:guava:33.2.1-android' + implementation 'com.google.guava:guava:33.3.1-android' testImplementation 'junit:junit:4.13.2' testImplementation 'org.mockito:mockito-inline:5.0.0' } diff --git a/packages/google_sign_in/google_sign_in_android/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java b/packages/google_sign_in/google_sign_in_android/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java index c3f03ab2e90e..301642bce1e8 100644 --- a/packages/google_sign_in/google_sign_in_android/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java +++ b/packages/google_sign_in/google_sign_in_android/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java @@ -56,13 +56,13 @@ public void initInstance( @NonNull GoogleSignInWrapper googleSignInWrapper) { this.messenger = messenger; delegate = new Delegate(context, googleSignInWrapper); - GoogleSignInApi.setup(messenger, delegate); + GoogleSignInApi.setUp(messenger, delegate); } private void dispose() { delegate = null; if (messenger != null) { - GoogleSignInApi.setup(messenger, null); + GoogleSignInApi.setUp(messenger, null); messenger = null; } } @@ -241,6 +241,30 @@ void requestScopes( final @NonNull MethodChannel.Result result, final @NonNull List scopes); } + /** + * Helper class for supporting the legacy IDelegate interface based on raw method channels, which + * handles converting any FlutterErrors (or other {@code Throwable}s in case any non- FlutterError + * exceptions slip through) thrown by the new code paths into {@code error} callbacks. + */ + private abstract static class ErrorConvertingMethodChannelVoidResult + implements Messages.VoidResult { + final @NonNull MethodChannel.Result result; + + public ErrorConvertingMethodChannelVoidResult(@NonNull MethodChannel.Result result) { + this.result = result; + } + + @Override + public void error(@NonNull Throwable error) { + if (error instanceof FlutterError) { + FlutterError flutterError = (FlutterError) error; + result.error(flutterError.code, flutterError.getMessage(), flutterError.details); + } else { + result.error("exception", error.getMessage(), null); + } + } + } + /** * Helper class for supporting the legacy IDelegate interface based on raw method channels, which * handles converting any FlutterErrors (or other {@code Throwable}s in case any non- FlutterError @@ -296,13 +320,13 @@ public void success(Messages.UserData data) { * Helper class for supporting the legacy IDelegate interface based on raw method channels, which * handles converting responses from methods that return {@code Void}. */ - private static class VoidMethodChannelResult extends ErrorConvertingMethodChannelResult { + private static class VoidMethodChannelResult extends ErrorConvertingMethodChannelVoidResult { public VoidMethodChannelResult(MethodChannel.Result result) { super(result); } @Override - public void success(Void unused) { + public void success() { result.success(null); } } @@ -367,7 +391,7 @@ public void setActivity(@Nullable Activity activity) { private void checkAndSetPendingOperation( String method, Messages.Result userDataResult, - Messages.Result voidResult, + Messages.VoidResult voidResult, Messages.Result boolResult, Messages.Result stringResult, Object data) { @@ -385,7 +409,7 @@ private void checkAndSetPendingSignInOperation( } private void checkAndSetPendingVoidOperation( - String method, @NonNull Messages.Result result) { + String method, @NonNull Messages.VoidResult result) { checkAndSetPendingOperation(method, null, result, null, null, null); } @@ -557,7 +581,7 @@ public void signIn(@NonNull MethodChannel.Result result) { * sign back in. */ @Override - public void signOut(@NonNull Messages.Result result) { + public void signOut(@NonNull Messages.VoidResult result) { checkAndSetPendingVoidOperation("signOut", result); signInClient @@ -580,7 +604,7 @@ public void signOut(@NonNull MethodChannel.Result result) { /** Signs the user out, and revokes their credentials. */ @Override - public void disconnect(@NonNull Messages.Result result) { + public void disconnect(@NonNull Messages.VoidResult result) { checkAndSetPendingVoidOperation("disconnect", result); signInClient @@ -705,7 +729,7 @@ private String errorCodeForStatus(int statusCode) { } private void finishWithSuccess() { - Objects.requireNonNull(pendingOperation.voidResult).success(null); + Objects.requireNonNull(pendingOperation.voidResult).success(); pendingOperation = null; } @@ -720,24 +744,27 @@ private void finishWithUserData(Messages.UserData data) { } private void finishWithError(String errorCode, String errorMessage) { - Messages.Result result; - if (pendingOperation.userDataResult != null) { - result = pendingOperation.userDataResult; - } else if (pendingOperation.boolResult != null) { - result = pendingOperation.boolResult; - } else if (pendingOperation.stringResult != null) { - result = pendingOperation.stringResult; + if (pendingOperation.voidResult != null) { + Objects.requireNonNull(pendingOperation.voidResult) + .error(new FlutterError(errorCode, errorMessage, null)); } else { - result = pendingOperation.voidResult; + Messages.Result result; + if (pendingOperation.userDataResult != null) { + result = pendingOperation.userDataResult; + } else if (pendingOperation.boolResult != null) { + result = pendingOperation.boolResult; + } else { + result = pendingOperation.stringResult; + } + Objects.requireNonNull(result).error(new FlutterError(errorCode, errorMessage, null)); } - Objects.requireNonNull(result).error(new FlutterError(errorCode, errorMessage, null)); pendingOperation = null; } private static class PendingOperation { final @NonNull String method; final @Nullable Messages.Result userDataResult; - final @Nullable Messages.Result voidResult; + final @Nullable Messages.VoidResult voidResult; final @Nullable Messages.Result boolResult; final @Nullable Messages.Result stringResult; final @Nullable Object data; @@ -745,7 +772,7 @@ private static class PendingOperation { PendingOperation( @NonNull String method, @Nullable Messages.Result userDataResult, - @Nullable Messages.Result voidResult, + @Nullable Messages.VoidResult voidResult, @Nullable Messages.Result boolResult, @Nullable Messages.Result stringResult, @Nullable Object data) { @@ -764,7 +791,7 @@ private static class PendingOperation { /** Clears the token kept in the client side cache. */ @Override - public void clearAuthCache(@NonNull String token, @NonNull Messages.Result result) { + public void clearAuthCache(@NonNull String token, @NonNull Messages.VoidResult result) { Callable clearTokenTask = () -> { GoogleAuthUtil.clearToken(context, token); @@ -775,7 +802,8 @@ public void clearAuthCache(@NonNull String token, @NonNull Messages.Result clearTokenTask, clearTokenFuture -> { try { - result.success(clearTokenFuture.get()); + clearTokenFuture.get(); + result.success(); } catch (ExecutionException e) { @Nullable Throwable cause = e.getCause(); result.error( diff --git a/packages/google_sign_in/google_sign_in_android/android/src/main/java/io/flutter/plugins/googlesignin/Messages.java b/packages/google_sign_in/google_sign_in_android/android/src/main/java/io/flutter/plugins/googlesignin/Messages.java index aa94bbbf7244..2bf6b6c1e06a 100644 --- a/packages/google_sign_in/google_sign_in_android/android/src/main/java/io/flutter/plugins/googlesignin/Messages.java +++ b/packages/google_sign_in/google_sign_in_android/android/src/main/java/io/flutter/plugins/googlesignin/Messages.java @@ -1,11 +1,14 @@ // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v10.1.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.2), do not edit directly. // See also: https://pub.dev/packages/pigeon package io.flutter.plugins.googlesignin; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.CLASS; + import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -14,9 +17,12 @@ import io.flutter.plugin.common.MessageCodec; import io.flutter.plugin.common.StandardMessageCodec; import java.io.ByteArrayOutputStream; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; +import java.util.Objects; /** Generated class from Pigeon. */ @SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression", "serial"}) @@ -40,7 +46,7 @@ public FlutterError(@NonNull String code, @Nullable String message, @Nullable Ob @NonNull protected static ArrayList wrapError(@NonNull Throwable exception) { - ArrayList errorList = new ArrayList(3); + ArrayList errorList = new ArrayList<>(3); if (exception instanceof FlutterError) { FlutterError error = (FlutterError) exception; errorList.add(error.code); @@ -55,6 +61,10 @@ protected static ArrayList wrapError(@NonNull Throwable exception) { return errorList; } + @Target(METHOD) + @Retention(CLASS) + @interface CanIgnoreReturnValue {} + /** Pigeon version of SignInOption. */ public enum SignInType { /** Default configuration. */ @@ -64,7 +74,7 @@ public enum SignInType { final int index; - private SignInType(final int index) { + SignInType(final int index) { this.index = index; } } @@ -149,10 +159,34 @@ public void setForceCodeForRefreshToken(@NonNull Boolean setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ InitParams() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + InitParams that = (InitParams) o; + return scopes.equals(that.scopes) + && signInType.equals(that.signInType) + && Objects.equals(hostedDomain, that.hostedDomain) + && Objects.equals(clientId, that.clientId) + && Objects.equals(serverClientId, that.serverClientId) + && forceCodeForRefreshToken.equals(that.forceCodeForRefreshToken); + } + + @Override + public int hashCode() { + return Objects.hash( + scopes, signInType, hostedDomain, clientId, serverClientId, forceCodeForRefreshToken); + } + public static final class Builder { private @Nullable List scopes; + @CanIgnoreReturnValue public @NonNull Builder setScopes(@NonNull List setterArg) { this.scopes = setterArg; return this; @@ -160,6 +194,7 @@ public static final class Builder { private @Nullable SignInType signInType; + @CanIgnoreReturnValue public @NonNull Builder setSignInType(@NonNull SignInType setterArg) { this.signInType = setterArg; return this; @@ -167,6 +202,7 @@ public static final class Builder { private @Nullable String hostedDomain; + @CanIgnoreReturnValue public @NonNull Builder setHostedDomain(@Nullable String setterArg) { this.hostedDomain = setterArg; return this; @@ -174,6 +210,7 @@ public static final class Builder { private @Nullable String clientId; + @CanIgnoreReturnValue public @NonNull Builder setClientId(@Nullable String setterArg) { this.clientId = setterArg; return this; @@ -181,6 +218,7 @@ public static final class Builder { private @Nullable String serverClientId; + @CanIgnoreReturnValue public @NonNull Builder setServerClientId(@Nullable String setterArg) { this.serverClientId = setterArg; return this; @@ -188,6 +226,7 @@ public static final class Builder { private @Nullable Boolean forceCodeForRefreshToken; + @CanIgnoreReturnValue public @NonNull Builder setForceCodeForRefreshToken(@NonNull Boolean setterArg) { this.forceCodeForRefreshToken = setterArg; return this; @@ -207,9 +246,9 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(6); + ArrayList toListResult = new ArrayList<>(6); toListResult.add(scopes); - toListResult.add(signInType == null ? null : signInType.index); + toListResult.add(signInType); toListResult.add(hostedDomain); toListResult.add(clientId); toListResult.add(serverClientId); @@ -217,19 +256,19 @@ ArrayList toList() { return toListResult; } - static @NonNull InitParams fromList(@NonNull ArrayList list) { + static @NonNull InitParams fromList(@NonNull ArrayList pigeonVar_list) { InitParams pigeonResult = new InitParams(); - Object scopes = list.get(0); + Object scopes = pigeonVar_list.get(0); pigeonResult.setScopes((List) scopes); - Object signInType = list.get(1); - pigeonResult.setSignInType(signInType == null ? null : SignInType.values()[(int) signInType]); - Object hostedDomain = list.get(2); + Object signInType = pigeonVar_list.get(1); + pigeonResult.setSignInType((SignInType) signInType); + Object hostedDomain = pigeonVar_list.get(2); pigeonResult.setHostedDomain((String) hostedDomain); - Object clientId = list.get(3); + Object clientId = pigeonVar_list.get(3); pigeonResult.setClientId((String) clientId); - Object serverClientId = list.get(4); + Object serverClientId = pigeonVar_list.get(4); pigeonResult.setServerClientId((String) serverClientId); - Object forceCodeForRefreshToken = list.get(5); + Object forceCodeForRefreshToken = pigeonVar_list.get(5); pigeonResult.setForceCodeForRefreshToken((Boolean) forceCodeForRefreshToken); return pigeonResult; } @@ -312,10 +351,33 @@ public void setServerAuthCode(@Nullable String setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ UserData() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UserData that = (UserData) o; + return Objects.equals(displayName, that.displayName) + && email.equals(that.email) + && id.equals(that.id) + && Objects.equals(photoUrl, that.photoUrl) + && Objects.equals(idToken, that.idToken) + && Objects.equals(serverAuthCode, that.serverAuthCode); + } + + @Override + public int hashCode() { + return Objects.hash(displayName, email, id, photoUrl, idToken, serverAuthCode); + } + public static final class Builder { private @Nullable String displayName; + @CanIgnoreReturnValue public @NonNull Builder setDisplayName(@Nullable String setterArg) { this.displayName = setterArg; return this; @@ -323,6 +385,7 @@ public static final class Builder { private @Nullable String email; + @CanIgnoreReturnValue public @NonNull Builder setEmail(@NonNull String setterArg) { this.email = setterArg; return this; @@ -330,6 +393,7 @@ public static final class Builder { private @Nullable String id; + @CanIgnoreReturnValue public @NonNull Builder setId(@NonNull String setterArg) { this.id = setterArg; return this; @@ -337,6 +401,7 @@ public static final class Builder { private @Nullable String photoUrl; + @CanIgnoreReturnValue public @NonNull Builder setPhotoUrl(@Nullable String setterArg) { this.photoUrl = setterArg; return this; @@ -344,6 +409,7 @@ public static final class Builder { private @Nullable String idToken; + @CanIgnoreReturnValue public @NonNull Builder setIdToken(@Nullable String setterArg) { this.idToken = setterArg; return this; @@ -351,6 +417,7 @@ public static final class Builder { private @Nullable String serverAuthCode; + @CanIgnoreReturnValue public @NonNull Builder setServerAuthCode(@Nullable String setterArg) { this.serverAuthCode = setterArg; return this; @@ -370,7 +437,7 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(6); + ArrayList toListResult = new ArrayList<>(6); toListResult.add(displayName); toListResult.add(email); toListResult.add(id); @@ -380,42 +447,40 @@ ArrayList toList() { return toListResult; } - static @NonNull UserData fromList(@NonNull ArrayList list) { + static @NonNull UserData fromList(@NonNull ArrayList pigeonVar_list) { UserData pigeonResult = new UserData(); - Object displayName = list.get(0); + Object displayName = pigeonVar_list.get(0); pigeonResult.setDisplayName((String) displayName); - Object email = list.get(1); + Object email = pigeonVar_list.get(1); pigeonResult.setEmail((String) email); - Object id = list.get(2); + Object id = pigeonVar_list.get(2); pigeonResult.setId((String) id); - Object photoUrl = list.get(3); + Object photoUrl = pigeonVar_list.get(3); pigeonResult.setPhotoUrl((String) photoUrl); - Object idToken = list.get(4); + Object idToken = pigeonVar_list.get(4); pigeonResult.setIdToken((String) idToken); - Object serverAuthCode = list.get(5); + Object serverAuthCode = pigeonVar_list.get(5); pigeonResult.setServerAuthCode((String) serverAuthCode); return pigeonResult; } } - public interface Result { - @SuppressWarnings("UnknownNullness") - void success(T result); + private static class PigeonCodec extends StandardMessageCodec { + public static final PigeonCodec INSTANCE = new PigeonCodec(); - void error(@NonNull Throwable error); - } - - private static class GoogleSignInApiCodec extends StandardMessageCodec { - public static final GoogleSignInApiCodec INSTANCE = new GoogleSignInApiCodec(); - - private GoogleSignInApiCodec() {} + private PigeonCodec() {} @Override protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { switch (type) { - case (byte) 128: - return InitParams.fromList((ArrayList) readValue(buffer)); case (byte) 129: + { + Object value = readValue(buffer); + return value == null ? null : SignInType.values()[((Long) value).intValue()]; + } + case (byte) 130: + return InitParams.fromList((ArrayList) readValue(buffer)); + case (byte) 131: return UserData.fromList((ArrayList) readValue(buffer)); default: return super.readValueOfType(type, buffer); @@ -424,11 +489,14 @@ protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { @Override protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { - if (value instanceof InitParams) { - stream.write(128); + if (value instanceof SignInType) { + stream.write(129); + writeValue(stream, value == null ? null : ((SignInType) value).index); + } else if (value instanceof InitParams) { + stream.write(130); writeValue(stream, ((InitParams) value).toList()); } else if (value instanceof UserData) { - stream.write(129); + stream.write(131); writeValue(stream, ((UserData) value).toList()); } else { super.writeValue(stream, value); @@ -436,6 +504,30 @@ protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { } } + /** Asynchronous error handling return type for non-nullable API method returns. */ + public interface Result { + /** Success case callback method for handling returns. */ + void success(@NonNull T result); + + /** Failure case callback method for handling errors. */ + void error(@NonNull Throwable error); + } + /** Asynchronous error handling return type for nullable API method returns. */ + public interface NullableResult { + /** Success case callback method for handling returns. */ + void success(@Nullable T result); + + /** Failure case callback method for handling errors. */ + void error(@NonNull Throwable error); + } + /** Asynchronous error handling return type for void API method returns. */ + public interface VoidResult { + /** Success case callback method for handling returns. */ + void success(); + + /** Failure case callback method for handling errors. */ + void error(@NonNull Throwable error); + } /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ public interface GoogleSignInApi { /** Initializes a sign in request with the given parameters. */ @@ -448,41 +540,51 @@ public interface GoogleSignInApi { void getAccessToken( @NonNull String email, @NonNull Boolean shouldRecoverAuth, @NonNull Result result); /** Signs out the current user. */ - void signOut(@NonNull Result result); + void signOut(@NonNull VoidResult result); /** Revokes scope grants to the application. */ - void disconnect(@NonNull Result result); + void disconnect(@NonNull VoidResult result); /** Returns whether the user is currently signed in. */ @NonNull Boolean isSignedIn(); /** Clears the authentication caching for the given token, requiring a new sign in. */ - void clearAuthCache(@NonNull String token, @NonNull Result result); + void clearAuthCache(@NonNull String token, @NonNull VoidResult result); /** Requests access to the given scopes. */ void requestScopes(@NonNull List scopes, @NonNull Result result); /** The codec used by GoogleSignInApi. */ static @NonNull MessageCodec getCodec() { - return GoogleSignInApiCodec.INSTANCE; + return PigeonCodec.INSTANCE; } /** * Sets up an instance of `GoogleSignInApi` to handle messages through the `binaryMessenger`. */ - static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable GoogleSignInApi api) { + static void setUp(@NonNull BinaryMessenger binaryMessenger, @Nullable GoogleSignInApi api) { + setUp(binaryMessenger, "", api); + } + + static void setUp( + @NonNull BinaryMessenger binaryMessenger, + @NonNull String messageChannelSuffix, + @Nullable GoogleSignInApi api) { + messageChannelSuffix = messageChannelSuffix.isEmpty() ? "" : "." + messageChannelSuffix; { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.GoogleSignInApi.init", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.google_sign_in_android.GoogleSignInApi.init" + + messageChannelSuffix, + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; InitParams paramsArg = (InitParams) args.get(0); try { api.init(paramsArg); wrapped.add(0, null); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -493,11 +595,14 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable GoogleSign { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.GoogleSignInApi.signInSilently", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.google_sign_in_android.GoogleSignInApi.signInSilently" + + messageChannelSuffix, + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); Result resultCallback = new Result() { public void success(UserData result) { @@ -520,11 +625,14 @@ public void error(Throwable error) { { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.GoogleSignInApi.signIn", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.google_sign_in_android.GoogleSignInApi.signIn" + + messageChannelSuffix, + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); Result resultCallback = new Result() { public void success(UserData result) { @@ -547,11 +655,14 @@ public void error(Throwable error) { { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.GoogleSignInApi.getAccessToken", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.google_sign_in_android.GoogleSignInApi.getAccessToken" + + messageChannelSuffix, + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; String emailArg = (String) args.get(0); Boolean shouldRecoverAuthArg = (Boolean) args.get(1); @@ -577,14 +688,17 @@ public void error(Throwable error) { { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.GoogleSignInApi.signOut", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.google_sign_in_android.GoogleSignInApi.signOut" + + messageChannelSuffix, + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); - Result resultCallback = - new Result() { - public void success(Void result) { + ArrayList wrapped = new ArrayList<>(); + VoidResult resultCallback = + new VoidResult() { + public void success() { wrapped.add(0, null); reply.reply(wrapped); } @@ -604,14 +718,17 @@ public void error(Throwable error) { { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.GoogleSignInApi.disconnect", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.google_sign_in_android.GoogleSignInApi.disconnect" + + messageChannelSuffix, + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); - Result resultCallback = - new Result() { - public void success(Void result) { + ArrayList wrapped = new ArrayList<>(); + VoidResult resultCallback = + new VoidResult() { + public void success() { wrapped.add(0, null); reply.reply(wrapped); } @@ -631,17 +748,19 @@ public void error(Throwable error) { { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.GoogleSignInApi.isSignedIn", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.google_sign_in_android.GoogleSignInApi.isSignedIn" + + messageChannelSuffix, + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { Boolean output = api.isSignedIn(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -652,16 +771,19 @@ public void error(Throwable error) { { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.GoogleSignInApi.clearAuthCache", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.google_sign_in_android.GoogleSignInApi.clearAuthCache" + + messageChannelSuffix, + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; String tokenArg = (String) args.get(0); - Result resultCallback = - new Result() { - public void success(Void result) { + VoidResult resultCallback = + new VoidResult() { + public void success() { wrapped.add(0, null); reply.reply(wrapped); } @@ -681,11 +803,14 @@ public void error(Throwable error) { { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.GoogleSignInApi.requestScopes", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.google_sign_in_android.GoogleSignInApi.requestScopes" + + messageChannelSuffix, + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; List scopesArg = (List) args.get(0); Result resultCallback = diff --git a/packages/google_sign_in/google_sign_in_android/android/src/test/java/io/flutter/plugins/googlesignin/GoogleSignInTest.java b/packages/google_sign_in/google_sign_in_android/android/src/test/java/io/flutter/plugins/googlesignin/GoogleSignInTest.java index 6089a81b3547..45dbae355008 100644 --- a/packages/google_sign_in/google_sign_in_android/android/src/test/java/io/flutter/plugins/googlesignin/GoogleSignInTest.java +++ b/packages/google_sign_in/google_sign_in_android/android/src/test/java/io/flutter/plugins/googlesignin/GoogleSignInTest.java @@ -41,7 +41,7 @@ public class GoogleSignInTest { @Mock Resources mockResources; @Mock Activity mockActivity; @Mock BinaryMessenger mockMessenger; - @Spy Messages.Result voidResult; + @Spy Messages.VoidResult voidResult; @Spy Messages.Result boolResult; @Spy Messages.Result userDataResult; @Mock GoogleSignInWrapper mockGoogleSignIn; diff --git a/packages/google_sign_in/google_sign_in_android/example/android/app/build.gradle b/packages/google_sign_in/google_sign_in_android/example/android/app/build.gradle index 422b58cc5199..36575d65a909 100644 --- a/packages/google_sign_in/google_sign_in_android/example/android/app/build.gradle +++ b/packages/google_sign_in/google_sign_in_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.googlesigninexample' compileSdk flutter.compileSdkVersion @@ -32,8 +30,7 @@ android { defaultConfig { applicationId "io.flutter.plugins.googlesigninexample" minSdkVersion flutter.minSdkVersion - targetSdkVersion 28 - multiDexEnabled true + targetSdkVersion 34 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/packages/google_sign_in/google_sign_in_android/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/google_sign_in/google_sign_in_android/example/android/app/gradle/wrapper/gradle-wrapper.properties index 609ab8e6c8b5..d951fac2bf31 100644 --- a/packages/google_sign_in/google_sign_in_android/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ b/packages/google_sign_in/google_sign_in_android/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/packages/google_sign_in/google_sign_in_android/example/android/app/src/main/AndroidManifest.xml b/packages/google_sign_in/google_sign_in_android/example/android/app/src/main/AndroidManifest.xml index 22a34d7218f7..750ce3cef5fd 100644 --- a/packages/google_sign_in/google_sign_in_android/example/android/app/src/main/AndroidManifest.xml +++ b/packages/google_sign_in/google_sign_in_android/example/android/app/src/main/AndroidManifest.xml @@ -5,7 +5,8 @@ diff --git a/packages/google_sign_in/google_sign_in_android/example/android/build.gradle b/packages/google_sign_in/google_sign_in_android/example/android/build.gradle index dc46ed04d80d..0b6e9f1672f4 100644 --- a/packages/google_sign_in/google_sign_in_android/example/android/build.gradle +++ b/packages/google_sign_in/google_sign_in_android/example/android/build.gradle @@ -1,14 +1,3 @@ -buildscript { - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' - } -} - 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/google_sign_in/google_sign_in_android/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/google_sign_in/google_sign_in_android/example/android/gradle/wrapper/gradle-wrapper.properties index e1ca574ef017..3c85cfe057a1 100644 --- a/packages/google_sign_in/google_sign_in_android/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/google_sign_in/google_sign_in_android/example/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/google_sign_in/google_sign_in_android/example/android/settings.gradle b/packages/google_sign_in/google_sign_in_android/example/android/settings.gradle index e54a7e1fd6e5..078698fe752d 100644 --- a/packages/google_sign_in/google_sign_in_android/example/android/settings.gradle +++ b/packages/google_sign_in/google_sign_in_android/example/android/settings.gradle @@ -1,28 +1,27 @@ -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 flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") -def plugins = new Properties() -def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') -if (pluginsFile.exists()) { - pluginsFile.withInputStream { stream -> plugins.load(stream) } -} - -plugins.each { name, path -> - def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() - include ":$name" - project(":$name").projectDir = pluginDirectory + 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/google_sign_in/google_sign_in_android/example/pubspec.yaml b/packages/google_sign_in/google_sign_in_android/example/pubspec.yaml index 11b6f0742725..0adb6d9f80fc 100644 --- a/packages/google_sign_in/google_sign_in_android/example/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in_android/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Example of Google Sign-In plugin. publish_to: none environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" dependencies: flutter: @@ -20,7 +20,7 @@ dependencies: http: ">=0.13.0 <2.0.0" dev_dependencies: - espresso: ^0.2.0 + espresso: ^0.4.0 flutter_test: sdk: flutter integration_test: diff --git a/packages/google_sign_in/google_sign_in_android/lib/src/messages.g.dart b/packages/google_sign_in/google_sign_in_android/lib/src/messages.g.dart index 14d8cb5fdc90..c5a7367318cd 100644 --- a/packages/google_sign_in/google_sign_in_android/lib/src/messages.g.dart +++ b/packages/google_sign_in/google_sign_in_android/lib/src/messages.g.dart @@ -1,9 +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 (v10.1.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.2), 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 +// 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 import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; @@ -11,6 +11,13 @@ import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; import 'package:flutter/services.dart'; +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); +} + /// Pigeon version of SignInOption. enum SignInType { /// Default configuration. @@ -25,15 +32,15 @@ enum SignInType { /// See SignInInitParams for details. class InitParams { InitParams({ - required this.scopes, - required this.signInType, + this.scopes = const [], + this.signInType = SignInType.standard, this.hostedDomain, this.clientId, this.serverClientId, - required this.forceCodeForRefreshToken, + this.forceCodeForRefreshToken = false, }); - List scopes; + List scopes; SignInType signInType; @@ -48,7 +55,7 @@ class InitParams { Object encode() { return [ scopes, - signInType.index, + signInType, hostedDomain, clientId, serverClientId, @@ -59,8 +66,8 @@ class InitParams { static InitParams decode(Object result) { result as List; return InitParams( - scopes: (result[0] as List?)!.cast(), - signInType: SignInType.values[result[1]! as int], + scopes: (result[0] as List?)!.cast(), + signInType: result[1]! as SignInType, hostedDomain: result[2] as String?, clientId: result[3] as String?, serverClientId: result[4] as String?, @@ -118,15 +125,21 @@ class UserData { } } -class _GoogleSignInApiCodec extends StandardMessageCodec { - const _GoogleSignInApiCodec(); +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is InitParams) { - buffer.putUint8(128); + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is SignInType) { + buffer.putUint8(129); + writeValue(buffer, value.index); + } else if (value is InitParams) { + buffer.putUint8(130); writeValue(buffer, value.encode()); } else if (value is UserData) { - buffer.putUint8(129); + buffer.putUint8(131); writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); @@ -136,9 +149,12 @@ class _GoogleSignInApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: - return InitParams.decode(readValue(buffer)!); case 129: + final int? value = readValue(buffer) as int?; + return value == null ? null : SignInType.values[value]; + case 130: + return InitParams.decode(readValue(buffer)!); + case 131: return UserData.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -150,29 +166,36 @@ class GoogleSignInApi { /// Constructor for [GoogleSignInApi]. 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. - GoogleSignInApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; + GoogleSignInApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - static const MessageCodec codec = _GoogleSignInApiCodec(); + final String pigeonVar_messageChannelSuffix; /// Initializes a sign in request with the given parameters. - Future init(InitParams arg_params) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GoogleSignInApi.init', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_params]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future init(InitParams params) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_sign_in_android.GoogleSignInApi.init$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([params]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; @@ -181,103 +204,113 @@ class GoogleSignInApi { /// Starts a silent sign in. Future signInSilently() async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GoogleSignInApi.signInSilently', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send(null) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_sign_in_android.GoogleSignInApi.signInSilently$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 (replyList[0] as UserData?)!; + return (pigeonVar_replyList[0] as UserData?)!; } } /// Starts a sign in with user interaction. Future signIn() async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GoogleSignInApi.signIn', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send(null) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_sign_in_android.GoogleSignInApi.signIn$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 (replyList[0] as UserData?)!; + return (pigeonVar_replyList[0] as UserData?)!; } } /// Requests the access token for the current sign in. - Future getAccessToken( - String arg_email, bool arg_shouldRecoverAuth) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GoogleSignInApi.getAccessToken', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_email, arg_shouldRecoverAuth]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future getAccessToken(String email, bool shouldRecoverAuth) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_sign_in_android.GoogleSignInApi.getAccessToken$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([email, shouldRecoverAuth]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 (replyList[0] as String?)!; + return (pigeonVar_replyList[0] as String?)!; } } /// Signs out the current user. Future signOut() async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GoogleSignInApi.signOut', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send(null) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_sign_in_android.GoogleSignInApi.signOut$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; @@ -286,20 +319,23 @@ class GoogleSignInApi { /// Revokes scope grants to the application. Future disconnect() async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GoogleSignInApi.disconnect', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send(null) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_sign_in_android.GoogleSignInApi.disconnect$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; @@ -308,49 +344,54 @@ class GoogleSignInApi { /// Returns whether the user is currently signed in. Future isSignedIn() async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GoogleSignInApi.isSignedIn', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send(null) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_sign_in_android.GoogleSignInApi.isSignedIn$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 (replyList[0] as bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } /// Clears the authentication caching for the given token, requiring a /// new sign in. - Future clearAuthCache(String arg_token) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GoogleSignInApi.clearAuthCache', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_token]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future clearAuthCache(String token) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_sign_in_android.GoogleSignInApi.clearAuthCache$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([token]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; @@ -358,30 +399,32 @@ class GoogleSignInApi { } /// Requests access to the given scopes. - Future requestScopes(List arg_scopes) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GoogleSignInApi.requestScopes', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_scopes]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future requestScopes(List scopes) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.google_sign_in_android.GoogleSignInApi.requestScopes$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([scopes]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 (replyList[0] as bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } } diff --git a/packages/google_sign_in/google_sign_in_android/pigeons/messages.dart b/packages/google_sign_in/google_sign_in_android/pigeons/messages.dart index 4804d43eac5c..69a452277dfe 100644 --- a/packages/google_sign_in/google_sign_in_android/pigeons/messages.dart +++ b/packages/google_sign_in/google_sign_in_android/pigeons/messages.dart @@ -35,10 +35,7 @@ class InitParams { this.forceCodeForRefreshToken = false, }); - // TODO(stuartmorgan): Make the generic type non-nullable once supported. - // https://github.com/flutter/flutter/issues/97848 - // The Java code treats the values as non-nullable. - final List scopes; + final List scopes; final SignInType signInType; final String? hostedDomain; final String? clientId; diff --git a/packages/google_sign_in/google_sign_in_android/pubspec.yaml b/packages/google_sign_in/google_sign_in_android/pubspec.yaml index 8d583e406d72..598eeb91a9df 100644 --- a/packages/google_sign_in/google_sign_in_android/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in_android/pubspec.yaml @@ -2,11 +2,11 @@ name: google_sign_in_android description: Android implementation of the google_sign_in plugin. repository: https://github.com/flutter/packages/tree/main/packages/google_sign_in/google_sign_in_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+google_sign_in%22 -version: 6.1.26 +version: 6.1.33 environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" flutter: plugin: @@ -28,8 +28,8 @@ dev_dependencies: sdk: flutter integration_test: sdk: flutter - mockito: 5.4.4 - pigeon: ^10.1.0 + mockito: ^5.4.4 + pigeon: ^22.4.2 topics: - authentication 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 1b4a673e7695..d6ab31e98763 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,12 @@ +## 5.7.8 + +* Updates Pigeon for non-nullable collection type support. + +## 5.7.7 + +* Fixes "callee requires a non-null parameter" analyzer warning. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + ## 5.7.6 * Upgrades GoogleSignIn iOS SDK to 7.1. diff --git a/packages/google_sign_in/google_sign_in_ios/README.md b/packages/google_sign_in/google_sign_in_ios/README.md index 20cf221aeb56..3fe0f7a1307d 100644 --- a/packages/google_sign_in/google_sign_in_ios/README.md +++ b/packages/google_sign_in/google_sign_in_ios/README.md @@ -14,7 +14,7 @@ should add it to your `pubspec.yaml` as usual. ### macOS setup The GoogleSignIn SDK requires keychain sharing to be enabled, by [adding the -following entitlements](https://docs.flutter.dev/platform-integration/macos/building#entitlements-and-the-app-sandbox): +following entitlements](https://flutter.dev/to/macos-entitlements): ```xml keychain-access-groups @@ -27,7 +27,7 @@ Without this step, the plugin will throw a `keychain error` `PlatformException` when trying to sign in. [1]: https://pub.dev/packages/google_sign_in -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin ### iOS integration diff --git a/packages/google_sign_in/google_sign_in_ios/darwin/Classes/FLTGoogleSignInPlugin.m b/packages/google_sign_in/google_sign_in_ios/darwin/Classes/FLTGoogleSignInPlugin.m index 99ee0348f518..7ba4db916089 100644 --- a/packages/google_sign_in/google_sign_in_ios/darwin/Classes/FLTGoogleSignInPlugin.m +++ b/packages/google_sign_in/google_sign_in_ios/darwin/Classes/FLTGoogleSignInPlugin.m @@ -124,7 +124,12 @@ - (void)signInSilentlyWithCompletion:(nonnull void (^)(FSIUserData *_Nullable, FlutterError *_Nullable))completion { [self.signIn restorePreviousSignInWithCompletion:^(GIDGoogleUser *_Nullable user, NSError *_Nullable error) { - [self didSignInForUser:user withServerAuthCode:nil completion:completion error:error]; + if (user != nil) { + [self didSignInForUser:user withServerAuthCode:nil completion:completion]; + } else { + // Forward all errors and let Dart side decide how to handle. + completion(nil, getFlutterError(error)); + } }]; } @@ -152,17 +157,14 @@ - (void)signInWithCompletion:(nonnull void (^)(FSIUserData *_Nullable, [self signInWithHint:nil additionalScopes:self.requestedScopes.allObjects completion:^(GIDSignInResult *_Nullable signInResult, NSError *_Nullable error) { - GIDGoogleUser *user; - NSString *serverAuthCode; if (signInResult) { - user = signInResult.user; - serverAuthCode = signInResult.serverAuthCode; + [self didSignInForUser:signInResult.user + withServerAuthCode:signInResult.serverAuthCode + completion:completion]; + } else { + // Forward all errors and let Dart side decide how to handle. + completion(nil, getFlutterError(error)); } - - [self didSignInForUser:user - withServerAuthCode:serverAuthCode - completion:completion - error:error]; }]; } @catch (NSException *e) { completion(nil, [FlutterError errorWithCode:@"google_sign_in" message:e.reason details:e.name]); @@ -291,30 +293,21 @@ - (GIDConfiguration *)configurationWithClientIdentifier:(NSString *)runtimeClien - (void)didSignInForUser:(GIDGoogleUser *)user withServerAuthCode:(NSString *_Nullable)serverAuthCode - completion:(nonnull void (^)(FSIUserData *_Nullable, - FlutterError *_Nullable))completion - error:(NSError *)error { - if (error != nil) { - // Forward all errors and let Dart side decide how to handle. - completion(nil, getFlutterError(error)); - } else { - NSURL *photoUrl; - if (user.profile.hasImage) { - // Placeholder that will be replaced by on the Dart side based on screen size. - photoUrl = [user.profile imageURLWithDimension:1337]; - } - NSString *idToken; - if (user.idToken) { - idToken = user.idToken.tokenString; - } - completion([FSIUserData makeWithDisplayName:user.profile.name - email:user.profile.email - userId:user.userID - photoUrl:[photoUrl absoluteString] - serverAuthCode:serverAuthCode - idToken:idToken], - nil); + completion: + (nonnull void (^)(FSIUserData *_Nullable, FlutterError *_Nullable))completion { + NSURL *photoUrl; + if (user.profile.hasImage) { + // Placeholder that will be replaced by on the Dart side based on screen size. + photoUrl = [user.profile imageURLWithDimension:1337]; } + + completion([FSIUserData makeWithDisplayName:user.profile.name + email:user.profile.email + userId:user.userID + photoUrl:photoUrl.absoluteString + serverAuthCode:serverAuthCode + idToken:user.idToken.tokenString], + nil); } #if TARGET_OS_IOS diff --git a/packages/google_sign_in/google_sign_in_ios/example/macos/Podfile b/packages/google_sign_in/google_sign_in_ios/example/macos/Podfile index 39a6656a7742..587228d11c23 100644 --- a/packages/google_sign_in/google_sign_in_ios/example/macos/Podfile +++ b/packages/google_sign_in/google_sign_in_ios/example/macos/Podfile @@ -28,7 +28,6 @@ flutter_macos_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) target 'RunnerTests' do 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 0862838b488d..7e9558b3d73a 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.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/google_sign_in/google_sign_in_ios/pigeons/messages.dart b/packages/google_sign_in/google_sign_in_ios/pigeons/messages.dart index c540ee7b60f8..822d06a03a2d 100644 --- a/packages/google_sign_in/google_sign_in_ios/pigeons/messages.dart +++ b/packages/google_sign_in/google_sign_in_ios/pigeons/messages.dart @@ -24,10 +24,7 @@ class InitParams { this.serverClientId, }); - // TODO(stuartmorgan): Make the generic type non-nullable once supported. - // https://github.com/flutter/flutter/issues/97848 - // The Obj-C code treats the values as non-nullable. - final List scopes; + final List scopes; final String? hostedDomain; final String? clientId; final String? serverClientId; 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 f0d7a3358c52..b4d782f97a98 100644 --- a/packages/google_sign_in/google_sign_in_ios/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in_ios/pubspec.yaml @@ -2,11 +2,11 @@ name: google_sign_in_ios description: iOS implementation of the google_sign_in plugin. repository: https://github.com/flutter/packages/tree/main/packages/google_sign_in/google_sign_in_ios issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+google_sign_in%22 -version: 5.7.6 +version: 5.7.8 environment: - sdk: ^3.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -32,8 +32,8 @@ dev_dependencies: sdk: flutter integration_test: sdk: flutter - mockito: 5.4.4 - pigeon: ^11.0.1 + mockito: ^5.4.4 + pigeon: ^22.4.2 topics: - authentication 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 c7ca3e771436..09c84c72eb15 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.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 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 85a11820511b..7826912ca88d 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: @@ -18,7 +18,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 topics: - authentication 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 c8eb27023c72..7c3db8fd4da4 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,11 @@ +## 0.12.4+3 + +* Fixes callback types for `TokenClientConfig`. + +## 0.12.4+2 + +* Adds support for `web: ^1.0.0`. + ## 0.12.4+1 * Fixes README.md typo. diff --git a/packages/google_sign_in/google_sign_in_web/README.md b/packages/google_sign_in/google_sign_in_web/README.md index 3c442a263ed6..f51d1bd63590 100644 --- a/packages/google_sign_in/google_sign_in_web/README.md +++ b/packages/google_sign_in/google_sign_in_web/README.md @@ -145,7 +145,7 @@ The GIS SDK limits authorization token duration to one hour (3600 seconds). ### Import the package -This package is [endorsed](https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin), +This package is [endorsed](https://flutter.dev/to/endorsed-federated-plugin), which means you can simply use `google_sign_in` normally. This package will be automatically included in your app when you do, so you do not need to add it to your `pubspec.yaml`. diff --git a/packages/google_sign_in/google_sign_in_web/example/README.md b/packages/google_sign_in/google_sign_in_web/example/README.md index 5977f3b54a93..9140bb80e8a6 100644 --- a/packages/google_sign_in/google_sign_in_web/example/README.md +++ b/packages/google_sign_in/google_sign_in_web/example/README.md @@ -15,7 +15,7 @@ This package uses `package:integration_test` to run its tests in a web browser. See [Plugin Tests > Web Tests](https://github.com/flutter/flutter/blob/master/docs/ecosystem/testing/Plugin-Tests.md#web-tests) in the Flutter documentation for instructions to set up and run the tests in this package. -Check [flutter.dev > Integration testing](https://flutter.dev/docs/testing/integration-tests) +Check [flutter.dev > Integration testing](https://docs.flutter.dev/testing/integration-tests) for more info. # button_tester.dart 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 e260814e73bb..756f725fe74d 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 @@ -21,8 +21,8 @@ dev_dependencies: http: ">=0.13.0 <2.0.0" integration_test: sdk: flutter - mockito: 5.4.4 - web: ^0.5.0 + mockito: ^5.4.4 + web: ^1.0.0 flutter: uses-material-design: true diff --git a/packages/google_sign_in/google_sign_in_web/example/web/index.html b/packages/google_sign_in/google_sign_in_web/example/web/index.html index 9e1284771b82..0446dcd58ec6 100644 --- a/packages/google_sign_in/google_sign_in_web/example/web/index.html +++ b/packages/google_sign_in/google_sign_in_web/example/web/index.html @@ -7,7 +7,7 @@ Browser Tests - + diff --git a/packages/google_sign_in/google_sign_in_web/lib/src/flexible_size_html_element_view.dart b/packages/google_sign_in/google_sign_in_web/lib/src/flexible_size_html_element_view.dart index 6fa019ed909a..5d05c5115f7a 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/src/flexible_size_html_element_view.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/src/flexible_size_html_element_view.dart @@ -78,6 +78,8 @@ class _FlexHtmlElementView extends State { ) { final web.DOMRectReadOnly rect = resizes.toDart.last.contentRect; if (rect.width > 0 && rect.height > 0) { + // TODO(dit): Remove the following ignore once the repo leaves web:0.5.1 behind. https://github.com/flutter/flutter/issues/152657 + // ignore: noop_primitive_operations _doResize(Size(rect.width.toDouble(), rect.height.toDouble())); } } diff --git a/packages/google_sign_in/google_sign_in_web/lib/src/gis_client.dart b/packages/google_sign_in/google_sign_in_web/lib/src/gis_client.dart index b28796b8d68f..421ce1a187fd 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/src/gis_client.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/src/gis_client.dart @@ -188,9 +188,9 @@ class GisSdkClient { // // Token clients have an additional `error_callback` for miscellaneous // errors, like "popup couldn't open" or "popup closed by user". - void _onTokenError(Object? error) { + void _onTokenError(GoogleIdentityServicesError? error) { if (error != null) { - _tokenResponses.addError((error as GoogleIdentityServicesError).type); + _tokenResponses.addError(error.type); } } @@ -223,9 +223,9 @@ class GisSdkClient { } } - void _onCodeError(Object? error) { + void _onCodeError(GoogleIdentityServicesError? error) { if (error != null) { - _codeResponses.addError((error as GoogleIdentityServicesError).type); + _codeResponses.addError(error.type); } } 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 6c4409cdab39..85aa2ba45a09 100644 --- a/packages/google_sign_in/google_sign_in_web/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in_web/pubspec.yaml @@ -3,7 +3,7 @@ description: Flutter plugin for Google Sign-In, a secure authentication system for signing in with a Google account on Android, iOS and Web. repository: https://github.com/flutter/packages/tree/main/packages/google_sign_in/google_sign_in_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+google_sign_in%22 -version: 0.12.4+1 +version: 0.12.4+3 environment: sdk: ^3.3.0 @@ -25,7 +25,7 @@ dependencies: google_identity_services_web: ^0.3.1 google_sign_in_platform_interface: ^2.4.0 http: ">=0.13.0 <2.0.0" - web: ^0.5.0 + web: ">=0.5.1 <2.0.0" dev_dependencies: flutter_test: diff --git a/packages/image_picker/image_picker/README.md b/packages/image_picker/image_picker/README.md index 1c800b49c8e6..866adf58118e 100755 --- a/packages/image_picker/image_picker/README.md +++ b/packages/image_picker/image_picker/README.md @@ -10,10 +10,7 @@ and taking new pictures with the camera. |-------------|---------|---------|-------|--------|---------------------------------|-------------| | **Support** | SDK 21+ | iOS 12+ | Any | 10.14+ | [See `image_picker_for_web`](https://pub.dev/packages/image_picker_for_web#limitations-on-the-web-platform) | Windows 10+ | -## Installation - -First, add `image_picker` as a -[dependency in your pubspec.yaml file](https://flutter.dev/docs/development/platform-integration/platform-channels). +## Setup ### iOS @@ -158,7 +155,8 @@ encourage the community to build packages that implement Since the macOS implementation uses `file_selector`, you will need to add a filesystem access -[entitlement](https://docs.flutter.dev/platform-integration/macos/building#entitlements-and-the-app-sandbox): +[entitlement](https://flutter.dev/to/macos-entitlements): + ```xml com.apple.security.files.user-selected.read-only diff --git a/packages/image_picker/image_picker/example/android/app/build.gradle b/packages/image_picker/image_picker/example/android/app/build.gradle index e72b68977644..f11653b7fa1e 100755 --- a/packages/image_picker/image_picker/example/android/app/build.gradle +++ b/packages/image_picker/image_picker/example/android/app/build.gradle @@ -34,7 +34,6 @@ android { applicationId "io.flutter.plugins.imagepicker.example" minSdkVersion flutter.minSdkVersion targetSdkVersion 28 - multiDexEnabled true versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/packages/image_picker/image_picker/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/image_picker/image_picker/example/android/app/gradle/wrapper/gradle-wrapper.properties index 609ab8e6c8b5..d951fac2bf31 100644 --- a/packages/image_picker/image_picker/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ b/packages/image_picker/image_picker/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/packages/image_picker/image_picker/example/android/build.gradle b/packages/image_picker/image_picker/example/android/build.gradle index cec92de922cf..0bed8906c094 100755 --- a/packages/image_picker/image_picker/example/android/build.gradle +++ b/packages/image_picker/image_picker/example/android/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath 'com.android.tools.build:gradle:8.5.2' } } diff --git a/packages/image_picker/image_picker/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/image_picker/image_picker/example/android/gradle/wrapper/gradle-wrapper.properties index e1ca574ef017..3c85cfe057a1 100644 --- a/packages/image_picker/image_picker/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/image_picker/image_picker/example/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/image_picker/image_picker/example/macos/Podfile b/packages/image_picker/image_picker/example/macos/Podfile index 049abe295427..ae77cc1d4269 100644 --- a/packages/image_picker/image_picker/example/macos/Podfile +++ b/packages/image_picker/image_picker/example/macos/Podfile @@ -28,7 +28,6 @@ flutter_macos_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) end diff --git a/packages/image_picker/image_picker/example/pubspec.yaml b/packages/image_picker/image_picker/example/pubspec.yaml index b7ca08c97156..12e6350a9523 100644 --- a/packages/image_picker/image_picker/example/pubspec.yaml +++ b/packages/image_picker/image_picker/example/pubspec.yaml @@ -23,7 +23,7 @@ dependencies: dev_dependencies: build_runner: ^2.1.10 - espresso: ^0.2.0 + espresso: ^0.4.0 flutter_test: sdk: flutter integration_test: diff --git a/packages/image_picker/image_picker/example/web/index.html b/packages/image_picker/image_picker/example/web/index.html index b05fdf840323..f61db847241c 100644 --- a/packages/image_picker/image_picker/example/web/index.html +++ b/packages/image_picker/image_picker/example/web/index.html @@ -21,16 +21,6 @@ - - - + diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml index ee854ea43ad5..6c5676a60e0d 100755 --- a/packages/image_picker/image_picker/pubspec.yaml +++ b/packages/image_picker/image_picker/pubspec.yaml @@ -41,7 +41,7 @@ dev_dependencies: cross_file: ^0.3.1+1 # Mockito generates a direct include. flutter_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 plugin_platform_interface: ^2.1.7 topics: diff --git a/packages/image_picker/image_picker_android/CHANGELOG.md b/packages/image_picker/image_picker_android/CHANGELOG.md index dde51eef8103..7616f8f6dce4 100644 --- a/packages/image_picker/image_picker_android/CHANGELOG.md +++ b/packages/image_picker/image_picker_android/CHANGELOG.md @@ -1,3 +1,60 @@ +## 0.8.12+17 + +* Bumps androidx.annotation:annotation from 1.8.2 to 1.9.0. + +## 0.8.12+16 + +* Updates Pigeon for non-nullable collection type support. + +## 0.8.12+15 + +* Updates Java compatibility version to 11. + +## 0.8.12+14 + +* Bumps androidx.activity:activity from 1.9.1 to 1.9.2. + +## 0.8.12+13 + +* Removes dependency on org.jetbrains.kotlin:kotlin-bom. +* Updates minimum supported SDK version to Flutter 3.24/Dart 3.5. + +## 0.8.12+12 + +* Bumps androidx.annotation:annotation from 1.8.1 to 1.8.2. + +## 0.8.12+11 + +* Bumps androidx.annotation:annotation from 1.8.0 to 1.8.1. + +## 0.8.12+10 + +* Bumps androidx.activity:activity from 1.9.0 to 1.9.1. + +## 0.8.12+9 + +* Bumps androidx.annotation:annotation from 1.7.1 to 1.8.0. + +## 0.8.12+8 + +* Updates lint checks to ignore NewerVersionAvailable. + +## 0.8.12+7 + +* Bumps androidx.activity:activity from 1.8.2 to 1.9.0. + +## 0.8.12+6 + +* Bumps androidx.activity:activity from 1.7.2 to 1.8.2. + +## 0.8.12+5 + +* Updates Android Gradle Plugin to 8.5.1. + +## 0.8.12+4 + +* Bumps androidx.core:core from 1.10.1 to 1.13.1. + ## 0.8.12+3 * Update documentation to note that limit is not always supported. diff --git a/packages/image_picker/image_picker_android/README.md b/packages/image_picker/image_picker_android/README.md index 14cbc4891260..a0bcc70294d6 100755 --- a/packages/image_picker/image_picker_android/README.md +++ b/packages/image_picker/image_picker_android/README.md @@ -36,5 +36,5 @@ import 'package:image_picker_platform_interface/image_picker_platform_interface. In addition, `ImagePickerAndroid.useAndroidPhotoPicker` must be set to `true` to use the `limit` functionality. It is implemented based on [`ActivityResultContract`][3], so it can only be ensured to take effect on Android 13 or above. Otherwise, it depends on whether the corresponding system app supports it. [1]: https://pub.dev/packages/image_picker -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin [3]: https://developer.android.google.cn/reference/kotlin/androidx/activity/result/contract/ActivityResultContracts.PickMultipleVisualMedia diff --git a/packages/image_picker/image_picker_android/android/build.gradle b/packages/image_picker/image_picker_android/android/build.gradle index e604f476ecc8..e1d46ee3340c 100644 --- a/packages/image_picker/image_picker_android/android/build.gradle +++ b/packages/image_picker/image_picker_android/android/build.gradle @@ -8,7 +8,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.2.1' + classpath 'com.android.tools.build:gradle:8.5.1' } } @@ -22,10 +22,7 @@ rootProject.allprojects { apply plugin: 'com.android.library' android { - // Conditional for compatibility with AGP <4.2. - if (project.android.hasProperty("namespace")) { - namespace 'io.flutter.plugins.imagepicker' - } + namespace 'io.flutter.plugins.imagepicker' compileSdk 34 defaultConfig { @@ -35,16 +32,13 @@ android { lintOptions { checkAllWarnings true warningsAsErrors true - disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency' + disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency', 'NewerVersionAvailable' } dependencies { - implementation 'androidx.core:core:1.10.1' - implementation 'androidx.annotation:annotation:1.7.1' + implementation 'androidx.core:core:1.13.1' + implementation 'androidx.annotation:annotation:1.9.0' implementation 'androidx.exifinterface:exifinterface:1.3.7' - implementation 'androidx.activity:activity:1.7.2' - // org.jetbrains.kotlin:kotlin-bom artifact purpose is to align kotlin stdlib and related code versions. - // See: https://youtrack.jetbrains.com/issue/KT-55297/kotlin-stdlib-should-declare-constraints-on-kotlin-stdlib-jdk8-and-kotlin-stdlib-jdk7 - implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.22")) + implementation 'androidx.activity:activity:1.9.2' testImplementation 'junit:junit:4.13.2' testImplementation 'org.mockito:mockito-core:5.1.1' @@ -53,8 +47,8 @@ android { } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } testOptions { diff --git a/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/Messages.java b/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/Messages.java index b987a2284a8e..c11f20e228d4 100644 --- a/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/Messages.java +++ b/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/Messages.java @@ -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 (v17.0.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.1), do not edit directly. // See also: https://pub.dev/packages/pigeon package io.flutter.plugins.imagepicker; @@ -22,6 +22,7 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; +import java.util.Objects; /** Generated class from Pigeon. */ @SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression", "serial"}) @@ -45,7 +46,7 @@ public FlutterError(@NonNull String code, @Nullable String message, @Nullable Ob @NonNull protected static ArrayList wrapError(@NonNull Throwable exception) { - ArrayList errorList = new ArrayList(3); + ArrayList errorList = new ArrayList<>(3); if (exception instanceof FlutterError) { FlutterError error = (FlutterError) exception; errorList.add(error.code); @@ -70,7 +71,7 @@ public enum SourceCamera { final int index; - private SourceCamera(final int index) { + SourceCamera(final int index) { this.index = index; } } @@ -81,7 +82,7 @@ public enum SourceType { final int index; - private SourceType(final int index) { + SourceType(final int index) { this.index = index; } } @@ -92,7 +93,7 @@ public enum CacheRetrievalType { final int index; - private CacheRetrievalType(final int index) { + CacheRetrievalType(final int index) { this.index = index; } } @@ -138,6 +139,25 @@ public void setLimit(@Nullable Long setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ GeneralOptions() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + GeneralOptions that = (GeneralOptions) o; + return allowMultiple.equals(that.allowMultiple) + && usePhotoPicker.equals(that.usePhotoPicker) + && Objects.equals(limit, that.limit); + } + + @Override + public int hashCode() { + return Objects.hash(allowMultiple, usePhotoPicker, limit); + } + public static final class Builder { private @Nullable Boolean allowMultiple; @@ -175,22 +195,21 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(3); + ArrayList toListResult = new ArrayList<>(3); toListResult.add(allowMultiple); toListResult.add(usePhotoPicker); toListResult.add(limit); return toListResult; } - static @NonNull GeneralOptions fromList(@NonNull ArrayList list) { + static @NonNull GeneralOptions fromList(@NonNull ArrayList pigeonVar_list) { GeneralOptions pigeonResult = new GeneralOptions(); - Object allowMultiple = list.get(0); + Object allowMultiple = pigeonVar_list.get(0); pigeonResult.setAllowMultiple((Boolean) allowMultiple); - Object usePhotoPicker = list.get(1); + Object usePhotoPicker = pigeonVar_list.get(1); pigeonResult.setUsePhotoPicker((Boolean) usePhotoPicker); - Object limit = list.get(2); - pigeonResult.setLimit( - (limit == null) ? null : ((limit instanceof Integer) ? (Integer) limit : (Long) limit)); + Object limit = pigeonVar_list.get(2); + pigeonResult.setLimit((Long) limit); return pigeonResult; } } @@ -244,6 +263,25 @@ public void setQuality(@NonNull Long setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ ImageSelectionOptions() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ImageSelectionOptions that = (ImageSelectionOptions) o; + return Objects.equals(maxWidth, that.maxWidth) + && Objects.equals(maxHeight, that.maxHeight) + && quality.equals(that.quality); + } + + @Override + public int hashCode() { + return Objects.hash(maxWidth, maxHeight, quality); + } + public static final class Builder { private @Nullable Double maxWidth; @@ -281,24 +319,21 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(3); + ArrayList toListResult = new ArrayList<>(3); toListResult.add(maxWidth); toListResult.add(maxHeight); toListResult.add(quality); return toListResult; } - static @NonNull ImageSelectionOptions fromList(@NonNull ArrayList list) { + static @NonNull ImageSelectionOptions fromList(@NonNull ArrayList pigeonVar_list) { ImageSelectionOptions pigeonResult = new ImageSelectionOptions(); - Object maxWidth = list.get(0); + Object maxWidth = pigeonVar_list.get(0); pigeonResult.setMaxWidth((Double) maxWidth); - Object maxHeight = list.get(1); + Object maxHeight = pigeonVar_list.get(1); pigeonResult.setMaxHeight((Double) maxHeight); - Object quality = list.get(2); - pigeonResult.setQuality( - (quality == null) - ? null - : ((quality instanceof Integer) ? (Integer) quality : (Long) quality)); + Object quality = pigeonVar_list.get(2); + pigeonResult.setQuality((Long) quality); return pigeonResult; } } @@ -321,6 +356,23 @@ public void setImageSelectionOptions(@NonNull ImageSelectionOptions setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ MediaSelectionOptions() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + MediaSelectionOptions that = (MediaSelectionOptions) o; + return imageSelectionOptions.equals(that.imageSelectionOptions); + } + + @Override + public int hashCode() { + return Objects.hash(imageSelectionOptions); + } + public static final class Builder { private @Nullable ImageSelectionOptions imageSelectionOptions; @@ -340,18 +392,15 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(1); - toListResult.add((imageSelectionOptions == null) ? null : imageSelectionOptions.toList()); + ArrayList toListResult = new ArrayList<>(1); + toListResult.add(imageSelectionOptions); return toListResult; } - static @NonNull MediaSelectionOptions fromList(@NonNull ArrayList list) { + static @NonNull MediaSelectionOptions fromList(@NonNull ArrayList pigeonVar_list) { MediaSelectionOptions pigeonResult = new MediaSelectionOptions(); - Object imageSelectionOptions = list.get(0); - pigeonResult.setImageSelectionOptions( - (imageSelectionOptions == null) - ? null - : ImageSelectionOptions.fromList((ArrayList) imageSelectionOptions)); + Object imageSelectionOptions = pigeonVar_list.get(0); + pigeonResult.setImageSelectionOptions((ImageSelectionOptions) imageSelectionOptions); return pigeonResult; } } @@ -373,6 +422,23 @@ public void setMaxDurationSeconds(@Nullable Long setterArg) { this.maxDurationSeconds = setterArg; } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + VideoSelectionOptions that = (VideoSelectionOptions) o; + return Objects.equals(maxDurationSeconds, that.maxDurationSeconds); + } + + @Override + public int hashCode() { + return Objects.hash(maxDurationSeconds); + } + public static final class Builder { private @Nullable Long maxDurationSeconds; @@ -392,20 +458,15 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(1); + ArrayList toListResult = new ArrayList<>(1); toListResult.add(maxDurationSeconds); return toListResult; } - static @NonNull VideoSelectionOptions fromList(@NonNull ArrayList list) { + static @NonNull VideoSelectionOptions fromList(@NonNull ArrayList pigeonVar_list) { VideoSelectionOptions pigeonResult = new VideoSelectionOptions(); - Object maxDurationSeconds = list.get(0); - pigeonResult.setMaxDurationSeconds( - (maxDurationSeconds == null) - ? null - : ((maxDurationSeconds instanceof Integer) - ? (Integer) maxDurationSeconds - : (Long) maxDurationSeconds)); + Object maxDurationSeconds = pigeonVar_list.get(0); + pigeonResult.setMaxDurationSeconds((Long) maxDurationSeconds); return pigeonResult; } } @@ -442,6 +503,23 @@ public void setCamera(@Nullable SourceCamera setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ SourceSpecification() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SourceSpecification that = (SourceSpecification) o; + return type.equals(that.type) && Objects.equals(camera, that.camera); + } + + @Override + public int hashCode() { + return Objects.hash(type, camera); + } + public static final class Builder { private @Nullable SourceType type; @@ -470,18 +548,18 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(2); - toListResult.add(type == null ? null : type.index); - toListResult.add(camera == null ? null : camera.index); + ArrayList toListResult = new ArrayList<>(2); + toListResult.add(type); + toListResult.add(camera); return toListResult; } - static @NonNull SourceSpecification fromList(@NonNull ArrayList list) { + static @NonNull SourceSpecification fromList(@NonNull ArrayList pigeonVar_list) { SourceSpecification pigeonResult = new SourceSpecification(); - Object type = list.get(0); - pigeonResult.setType(SourceType.values()[(int) type]); - Object camera = list.get(1); - pigeonResult.setCamera(camera == null ? null : SourceCamera.values()[(int) camera]); + Object type = pigeonVar_list.get(0); + pigeonResult.setType((SourceType) type); + Object camera = pigeonVar_list.get(1); + pigeonResult.setCamera((SourceCamera) camera); return pigeonResult; } } @@ -520,6 +598,23 @@ public void setMessage(@Nullable String setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ CacheRetrievalError() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CacheRetrievalError that = (CacheRetrievalError) o; + return code.equals(that.code) && Objects.equals(message, that.message); + } + + @Override + public int hashCode() { + return Objects.hash(code, message); + } + public static final class Builder { private @Nullable String code; @@ -548,17 +643,17 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(2); + ArrayList toListResult = new ArrayList<>(2); toListResult.add(code); toListResult.add(message); return toListResult; } - static @NonNull CacheRetrievalError fromList(@NonNull ArrayList list) { + static @NonNull CacheRetrievalError fromList(@NonNull ArrayList pigeonVar_list) { CacheRetrievalError pigeonResult = new CacheRetrievalError(); - Object code = list.get(0); + Object code = pigeonVar_list.get(0); pigeonResult.setCode((String) code); - Object message = list.get(1); + Object message = pigeonVar_list.get(1); pigeonResult.setMessage((String) message); return pigeonResult; } @@ -595,12 +690,7 @@ public void setError(@Nullable CacheRetrievalError setterArg) { this.error = setterArg; } - /** - * The results from the last selection, if any. - * - *

Elements must not be null, by convention. See - * https://github.com/flutter/flutter/issues/97848 - */ + /** The results from the last selection, if any. */ private @NonNull List paths; public @NonNull List getPaths() { @@ -617,6 +707,25 @@ public void setPaths(@NonNull List setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ CacheRetrievalResult() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CacheRetrievalResult that = (CacheRetrievalResult) o; + return type.equals(that.type) + && Objects.equals(error, that.error) + && paths.equals(that.paths); + } + + @Override + public int hashCode() { + return Objects.hash(type, error, paths); + } + public static final class Builder { private @Nullable CacheRetrievalType type; @@ -654,73 +763,62 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(3); - toListResult.add(type == null ? null : type.index); - toListResult.add((error == null) ? null : error.toList()); + ArrayList toListResult = new ArrayList<>(3); + toListResult.add(type); + toListResult.add(error); toListResult.add(paths); return toListResult; } - static @NonNull CacheRetrievalResult fromList(@NonNull ArrayList list) { + static @NonNull CacheRetrievalResult fromList(@NonNull ArrayList pigeonVar_list) { CacheRetrievalResult pigeonResult = new CacheRetrievalResult(); - Object type = list.get(0); - pigeonResult.setType(CacheRetrievalType.values()[(int) type]); - Object error = list.get(1); - pigeonResult.setError( - (error == null) ? null : CacheRetrievalError.fromList((ArrayList) error)); - Object paths = list.get(2); + Object type = pigeonVar_list.get(0); + pigeonResult.setType((CacheRetrievalType) type); + Object error = pigeonVar_list.get(1); + pigeonResult.setError((CacheRetrievalError) error); + Object paths = pigeonVar_list.get(2); pigeonResult.setPaths((List) paths); return pigeonResult; } } - /** Asynchronous error handling return type for non-nullable API method returns. */ - public interface Result { - /** Success case callback method for handling returns. */ - void success(@NonNull T result); + private static class PigeonCodec extends StandardMessageCodec { + public static final PigeonCodec INSTANCE = new PigeonCodec(); - /** Failure case callback method for handling errors. */ - void error(@NonNull Throwable error); - } - /** Asynchronous error handling return type for nullable API method returns. */ - public interface NullableResult { - /** Success case callback method for handling returns. */ - void success(@Nullable T result); - - /** Failure case callback method for handling errors. */ - void error(@NonNull Throwable error); - } - /** Asynchronous error handling return type for void API method returns. */ - public interface VoidResult { - /** Success case callback method for handling returns. */ - void success(); - - /** Failure case callback method for handling errors. */ - void error(@NonNull Throwable error); - } - - private static class ImagePickerApiCodec extends StandardMessageCodec { - public static final ImagePickerApiCodec INSTANCE = new ImagePickerApiCodec(); - - private ImagePickerApiCodec() {} + private PigeonCodec() {} @Override protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { switch (type) { - case (byte) 128: - return CacheRetrievalError.fromList((ArrayList) readValue(buffer)); case (byte) 129: - return CacheRetrievalResult.fromList((ArrayList) readValue(buffer)); + { + Object value = readValue(buffer); + return value == null ? null : SourceCamera.values()[((Long) value).intValue()]; + } case (byte) 130: - return GeneralOptions.fromList((ArrayList) readValue(buffer)); + { + Object value = readValue(buffer); + return value == null ? null : SourceType.values()[((Long) value).intValue()]; + } case (byte) 131: - return ImageSelectionOptions.fromList((ArrayList) readValue(buffer)); + { + Object value = readValue(buffer); + return value == null ? null : CacheRetrievalType.values()[((Long) value).intValue()]; + } case (byte) 132: - return MediaSelectionOptions.fromList((ArrayList) readValue(buffer)); + return GeneralOptions.fromList((ArrayList) readValue(buffer)); case (byte) 133: - return SourceSpecification.fromList((ArrayList) readValue(buffer)); + return ImageSelectionOptions.fromList((ArrayList) readValue(buffer)); case (byte) 134: + return MediaSelectionOptions.fromList((ArrayList) readValue(buffer)); + case (byte) 135: return VideoSelectionOptions.fromList((ArrayList) readValue(buffer)); + case (byte) 136: + return SourceSpecification.fromList((ArrayList) readValue(buffer)); + case (byte) 137: + return CacheRetrievalError.fromList((ArrayList) readValue(buffer)); + case (byte) 138: + return CacheRetrievalResult.fromList((ArrayList) readValue(buffer)); default: return super.readValueOfType(type, buffer); } @@ -728,63 +826,81 @@ protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { @Override protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { - if (value instanceof CacheRetrievalError) { - stream.write(128); - writeValue(stream, ((CacheRetrievalError) value).toList()); - } else if (value instanceof CacheRetrievalResult) { + if (value instanceof SourceCamera) { stream.write(129); - writeValue(stream, ((CacheRetrievalResult) value).toList()); - } else if (value instanceof GeneralOptions) { + writeValue(stream, value == null ? null : ((SourceCamera) value).index); + } else if (value instanceof SourceType) { stream.write(130); + writeValue(stream, value == null ? null : ((SourceType) value).index); + } else if (value instanceof CacheRetrievalType) { + stream.write(131); + writeValue(stream, value == null ? null : ((CacheRetrievalType) value).index); + } else if (value instanceof GeneralOptions) { + stream.write(132); writeValue(stream, ((GeneralOptions) value).toList()); } else if (value instanceof ImageSelectionOptions) { - stream.write(131); + stream.write(133); writeValue(stream, ((ImageSelectionOptions) value).toList()); } else if (value instanceof MediaSelectionOptions) { - stream.write(132); + stream.write(134); writeValue(stream, ((MediaSelectionOptions) value).toList()); - } else if (value instanceof SourceSpecification) { - stream.write(133); - writeValue(stream, ((SourceSpecification) value).toList()); } else if (value instanceof VideoSelectionOptions) { - stream.write(134); + stream.write(135); writeValue(stream, ((VideoSelectionOptions) value).toList()); + } else if (value instanceof SourceSpecification) { + stream.write(136); + writeValue(stream, ((SourceSpecification) value).toList()); + } else if (value instanceof CacheRetrievalError) { + stream.write(137); + writeValue(stream, ((CacheRetrievalError) value).toList()); + } else if (value instanceof CacheRetrievalResult) { + stream.write(138); + writeValue(stream, ((CacheRetrievalResult) value).toList()); } else { super.writeValue(stream, value); } } } + /** Asynchronous error handling return type for non-nullable API method returns. */ + public interface Result { + /** Success case callback method for handling returns. */ + void success(@NonNull T result); + + /** Failure case callback method for handling errors. */ + void error(@NonNull Throwable error); + } + /** Asynchronous error handling return type for nullable API method returns. */ + public interface NullableResult { + /** Success case callback method for handling returns. */ + void success(@Nullable T result); + + /** Failure case callback method for handling errors. */ + void error(@NonNull Throwable error); + } + /** Asynchronous error handling return type for void API method returns. */ + public interface VoidResult { + /** Success case callback method for handling returns. */ + void success(); + + /** Failure case callback method for handling errors. */ + void error(@NonNull Throwable error); + } /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ public interface ImagePickerApi { - /** - * Selects images and returns their paths. - * - *

Elements must not be null, by convention. See - * https://github.com/flutter/flutter/issues/97848 - */ + /** Selects images and returns their paths. */ void pickImages( @NonNull SourceSpecification source, @NonNull ImageSelectionOptions options, @NonNull GeneralOptions generalOptions, @NonNull Result> result); - /** - * Selects video and returns their paths. - * - *

Elements must not be null, by convention. See - * https://github.com/flutter/flutter/issues/97848 - */ + /** Selects video and returns their paths. */ void pickVideos( @NonNull SourceSpecification source, @NonNull VideoSelectionOptions options, @NonNull GeneralOptions generalOptions, @NonNull Result> result); - /** - * Selects images and videos and returns their paths. - * - *

Elements must not be null, by convention. See - * https://github.com/flutter/flutter/issues/97848 - */ + /** Selects images and videos and returns their paths. */ void pickMedia( @NonNull MediaSelectionOptions mediaSelectionOptions, @NonNull GeneralOptions generalOptions, @@ -795,22 +911,31 @@ void pickMedia( /** The codec used by ImagePickerApi. */ static @NonNull MessageCodec getCodec() { - return ImagePickerApiCodec.INSTANCE; + return PigeonCodec.INSTANCE; } /** Sets up an instance of `ImagePickerApi` to handle messages through the `binaryMessenger`. */ static void setUp(@NonNull BinaryMessenger binaryMessenger, @Nullable ImagePickerApi api) { + setUp(binaryMessenger, "", api); + } + + static void setUp( + @NonNull BinaryMessenger binaryMessenger, + @NonNull String messageChannelSuffix, + @Nullable ImagePickerApi api) { + messageChannelSuffix = messageChannelSuffix.isEmpty() ? "" : "." + messageChannelSuffix; { BinaryMessenger.TaskQueue taskQueue = binaryMessenger.makeBackgroundTaskQueue(); BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.image_picker_android.ImagePickerApi.pickImages", + "dev.flutter.pigeon.image_picker_android.ImagePickerApi.pickImages" + + messageChannelSuffix, getCodec(), taskQueue); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; SourceSpecification sourceArg = (SourceSpecification) args.get(0); ImageSelectionOptions optionsArg = (ImageSelectionOptions) args.get(1); @@ -839,13 +964,14 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.image_picker_android.ImagePickerApi.pickVideos", + "dev.flutter.pigeon.image_picker_android.ImagePickerApi.pickVideos" + + messageChannelSuffix, getCodec(), taskQueue); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; SourceSpecification sourceArg = (SourceSpecification) args.get(0); VideoSelectionOptions optionsArg = (VideoSelectionOptions) args.get(1); @@ -873,12 +999,13 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.image_picker_android.ImagePickerApi.pickMedia", + "dev.flutter.pigeon.image_picker_android.ImagePickerApi.pickMedia" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; MediaSelectionOptions mediaSelectionOptionsArg = (MediaSelectionOptions) args.get(0); @@ -907,19 +1034,19 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.image_picker_android.ImagePickerApi.retrieveLostResults", + "dev.flutter.pigeon.image_picker_android.ImagePickerApi.retrieveLostResults" + + messageChannelSuffix, getCodec(), taskQueue); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { CacheRetrievalResult output = api.retrieveLostResults(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); diff --git a/packages/image_picker/image_picker_android/example/android/app/build.gradle b/packages/image_picker/image_picker_android/example/android/app/build.gradle index 1be93f0fa346..8d1665a9de7e 100755 --- a/packages/image_picker/image_picker_android/example/android/app/build.gradle +++ b/packages/image_picker/image_picker_android/example/android/app/build.gradle @@ -33,8 +33,7 @@ android { defaultConfig { applicationId "io.flutter.plugins.imagepicker.example" minSdkVersion flutter.minSdkVersion - targetSdkVersion 33 - multiDexEnabled true + targetSdkVersion 34 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/packages/image_picker/image_picker_android/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/image_picker/image_picker_android/example/android/app/gradle/wrapper/gradle-wrapper.properties index 609ab8e6c8b5..d951fac2bf31 100644 --- a/packages/image_picker/image_picker_android/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ b/packages/image_picker/image_picker_android/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/packages/image_picker/image_picker_android/example/android/build.gradle b/packages/image_picker/image_picker_android/example/android/build.gradle index facf61d83e68..7f029821ad3d 100755 --- a/packages/image_picker/image_picker_android/example/android/build.gradle +++ b/packages/image_picker/image_picker_android/example/android/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath 'com.android.tools.build:gradle:8.5.1' } } diff --git a/packages/image_picker/image_picker_android/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/image_picker/image_picker_android/example/android/gradle/wrapper/gradle-wrapper.properties index e1ca574ef017..3c85cfe057a1 100644 --- a/packages/image_picker/image_picker_android/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/image_picker/image_picker_android/example/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/image_picker/image_picker_android/example/pubspec.yaml b/packages/image_picker/image_picker_android/example/pubspec.yaml index 0c7181f68abe..b3e2931c6986 100644 --- a/packages/image_picker/image_picker_android/example/pubspec.yaml +++ b/packages/image_picker/image_picker_android/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the image_picker plugin. publish_to: none environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" dependencies: flutter: @@ -20,12 +20,12 @@ dependencies: # the parent directory to use the current plugin's version. path: ../ image_picker_platform_interface: ^2.10.0 - mime: ^1.0.4 + mime: ^2.0.0 video_player: ^2.1.4 dev_dependencies: build_runner: ^2.1.10 - espresso: ^0.2.0 + espresso: ^0.4.0 flutter_test: sdk: flutter integration_test: diff --git a/packages/image_picker/image_picker_android/lib/image_picker_android.dart b/packages/image_picker/image_picker_android/lib/image_picker_android.dart index 2bcebe268027..5fa164b2d0f1 100644 --- a/packages/image_picker/image_picker_android/lib/image_picker_android.dart +++ b/packages/image_picker/image_picker_android/lib/image_picker_android.dart @@ -51,7 +51,7 @@ class ImagePickerAndroid extends ImagePickerPlatform { double? maxHeight, int? imageQuality, }) async { - final List paths = await _getMultiImagePath( + final List paths = await _getMultiImagePath( maxWidth: maxWidth, maxHeight: maxHeight, imageQuality: imageQuality, @@ -60,10 +60,10 @@ class ImagePickerAndroid extends ImagePickerPlatform { return null; } - return paths.map((dynamic path) => PickedFile(path as String)).toList(); + return paths.map((String path) => PickedFile(path)).toList(); } - Future> _getMultiImagePath({ + Future> _getMultiImagePath({ double? maxWidth, double? maxHeight, int? imageQuality, @@ -121,7 +121,7 @@ class ImagePickerAndroid extends ImagePickerPlatform { throw ArgumentError.value(maxHeight, 'maxHeight', 'cannot be negative'); } - final List paths = await _hostApi.pickImages( + final List paths = await _hostApi.pickImages( _buildSourceSpec(source, preferredCameraDevice), ImageSelectionOptions( maxWidth: maxWidth, @@ -154,7 +154,7 @@ class ImagePickerAndroid extends ImagePickerPlatform { CameraDevice preferredCameraDevice = CameraDevice.rear, Duration? maxDuration, }) async { - final List paths = await _hostApi.pickVideos( + final List paths = await _hostApi.pickVideos( _buildSourceSpec(source, preferredCameraDevice), VideoSelectionOptions(maxDurationSeconds: maxDuration?.inSeconds), GeneralOptions( @@ -205,7 +205,7 @@ class ImagePickerAndroid extends ImagePickerPlatform { double? maxHeight, int? imageQuality, }) async { - final List paths = await _getMultiImagePath( + final List paths = await _getMultiImagePath( maxWidth: maxWidth, maxHeight: maxHeight, imageQuality: imageQuality, @@ -214,14 +214,14 @@ class ImagePickerAndroid extends ImagePickerPlatform { return null; } - return paths.map((dynamic path) => XFile(path as String)).toList(); + return paths.map((String path) => XFile(path)).toList(); } @override Future> getMultiImageWithOptions({ MultiImagePickerOptions options = const MultiImagePickerOptions(), }) async { - final List paths = await _getMultiImagePath( + final List paths = await _getMultiImagePath( maxWidth: options.imageOptions.maxWidth, maxHeight: options.imageOptions.maxHeight, imageQuality: options.imageOptions.imageQuality, @@ -232,7 +232,7 @@ class ImagePickerAndroid extends ImagePickerPlatform { return []; } - return paths.map((dynamic path) => XFile(path as String)).toList(); + return paths.map((String path) => XFile(path)).toList(); } @override diff --git a/packages/image_picker/image_picker_android/lib/src/messages.g.dart b/packages/image_picker/image_picker_android/lib/src/messages.g.dart index 1466b15aee85..e221123fd800 100644 --- a/packages/image_picker/image_picker_android/lib/src/messages.g.dart +++ b/packages/image_picker/image_picker_android/lib/src/messages.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 (v17.0.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.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 @@ -121,15 +121,14 @@ class MediaSelectionOptions { Object encode() { return [ - imageSelectionOptions.encode(), + imageSelectionOptions, ]; } static MediaSelectionOptions decode(Object result) { result as List; return MediaSelectionOptions( - imageSelectionOptions: - ImageSelectionOptions.decode(result[0]! as List), + imageSelectionOptions: result[0]! as ImageSelectionOptions, ); } } @@ -170,16 +169,16 @@ class SourceSpecification { Object encode() { return [ - type.index, - camera?.index, + type, + camera, ]; } static SourceSpecification decode(Object result) { result as List; return SourceSpecification( - type: SourceType.values[result[0]! as int], - camera: result[1] != null ? SourceCamera.values[result[1]! as int] : null, + type: result[0]! as SourceType, + camera: result[1] as SourceCamera?, ); } } @@ -228,15 +227,12 @@ class CacheRetrievalResult { CacheRetrievalError? error; /// The results from the last selection, if any. - /// - /// Elements must not be null, by convention. See - /// https://github.com/flutter/flutter/issues/97848 - List paths; + List paths; Object encode() { return [ - type.index, - error?.encode(), + type, + error, paths, ]; } @@ -244,39 +240,49 @@ class CacheRetrievalResult { static CacheRetrievalResult decode(Object result) { result as List; return CacheRetrievalResult( - type: CacheRetrievalType.values[result[0]! as int], - error: result[1] != null - ? CacheRetrievalError.decode(result[1]! as List) - : null, - paths: (result[2] as List?)!.cast(), + type: result[0]! as CacheRetrievalType, + error: result[1] as CacheRetrievalError?, + paths: (result[2] as List?)!.cast(), ); } } -class _ImagePickerApiCodec extends StandardMessageCodec { - const _ImagePickerApiCodec(); +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is CacheRetrievalError) { - buffer.putUint8(128); - writeValue(buffer, value.encode()); - } else if (value is CacheRetrievalResult) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is SourceCamera) { buffer.putUint8(129); - writeValue(buffer, value.encode()); - } else if (value is GeneralOptions) { + writeValue(buffer, value.index); + } else if (value is SourceType) { buffer.putUint8(130); + writeValue(buffer, value.index); + } else if (value is CacheRetrievalType) { + buffer.putUint8(131); + writeValue(buffer, value.index); + } else if (value is GeneralOptions) { + buffer.putUint8(132); writeValue(buffer, value.encode()); } else if (value is ImageSelectionOptions) { - buffer.putUint8(131); + buffer.putUint8(133); writeValue(buffer, value.encode()); } else if (value is MediaSelectionOptions) { - buffer.putUint8(132); + buffer.putUint8(134); + writeValue(buffer, value.encode()); + } else if (value is VideoSelectionOptions) { + buffer.putUint8(135); writeValue(buffer, value.encode()); } else if (value is SourceSpecification) { - buffer.putUint8(133); + buffer.putUint8(136); writeValue(buffer, value.encode()); - } else if (value is VideoSelectionOptions) { - buffer.putUint8(134); + } else if (value is CacheRetrievalError) { + buffer.putUint8(137); + writeValue(buffer, value.encode()); + } else if (value is CacheRetrievalResult) { + buffer.putUint8(138); writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); @@ -286,20 +292,29 @@ class _ImagePickerApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: - return CacheRetrievalError.decode(readValue(buffer)!); case 129: - return CacheRetrievalResult.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : SourceCamera.values[value]; case 130: - return GeneralOptions.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : SourceType.values[value]; case 131: - return ImageSelectionOptions.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : CacheRetrievalType.values[value]; case 132: - return MediaSelectionOptions.decode(readValue(buffer)!); + return GeneralOptions.decode(readValue(buffer)!); case 133: - return SourceSpecification.decode(readValue(buffer)!); + return ImageSelectionOptions.decode(readValue(buffer)!); case 134: + return MediaSelectionOptions.decode(readValue(buffer)!); + case 135: return VideoSelectionOptions.decode(readValue(buffer)!); + case 136: + return SourceSpecification.decode(readValue(buffer)!); + case 137: + return CacheRetrievalError.decode(readValue(buffer)!); + case 138: + return CacheRetrievalResult.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -310,138 +325,133 @@ class ImagePickerApi { /// Constructor for [ImagePickerApi]. 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. - ImagePickerApi({BinaryMessenger? binaryMessenger}) - : __pigeon_binaryMessenger = binaryMessenger; - final BinaryMessenger? __pigeon_binaryMessenger; + ImagePickerApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; - static const MessageCodec pigeonChannelCodec = - _ImagePickerApiCodec(); + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String pigeonVar_messageChannelSuffix; /// Selects images and returns their paths. - /// - /// Elements must not be null, by convention. See - /// https://github.com/flutter/flutter/issues/97848 - Future> pickImages(SourceSpecification source, + Future> pickImages(SourceSpecification source, ImageSelectionOptions options, GeneralOptions generalOptions) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.image_picker_android.ImagePickerApi.pickImages'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.image_picker_android.ImagePickerApi.pickImages$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([source, options, generalOptions]) 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(); } } /// Selects video and returns their paths. - /// - /// Elements must not be null, by convention. See - /// https://github.com/flutter/flutter/issues/97848 - Future> pickVideos(SourceSpecification source, + Future> pickVideos(SourceSpecification source, VideoSelectionOptions options, GeneralOptions generalOptions) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.image_picker_android.ImagePickerApi.pickVideos'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.image_picker_android.ImagePickerApi.pickVideos$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([source, options, generalOptions]) 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(); } } /// Selects images and videos and returns their paths. - /// - /// Elements must not be null, by convention. See - /// https://github.com/flutter/flutter/issues/97848 - Future> pickMedia(MediaSelectionOptions mediaSelectionOptions, + Future> pickMedia(MediaSelectionOptions mediaSelectionOptions, GeneralOptions generalOptions) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.image_picker_android.ImagePickerApi.pickMedia'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.image_picker_android.ImagePickerApi.pickMedia$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([mediaSelectionOptions, generalOptions]) 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(); } } /// Returns results from a previous app session, if any. Future retrieveLostResults() async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.image_picker_android.ImagePickerApi.retrieveLostResults'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.image_picker_android.ImagePickerApi.retrieveLostResults$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 CacheRetrievalResult?); + return (pigeonVar_replyList[0] as CacheRetrievalResult?); } } } diff --git a/packages/image_picker/image_picker_android/pigeons/messages.dart b/packages/image_picker/image_picker_android/pigeons/messages.dart index 7f39ae501b62..2d124eb12fdb 100644 --- a/packages/image_picker/image_picker_android/pigeons/messages.dart +++ b/packages/image_picker/image_picker_android/pigeons/messages.dart @@ -89,44 +89,32 @@ class CacheRetrievalResult { final CacheRetrievalError? error; /// The results from the last selection, if any. - /// - /// Elements must not be null, by convention. See - /// https://github.com/flutter/flutter/issues/97848 - final List paths; + final List paths; } @HostApi(dartHostTestHandler: 'TestHostImagePickerApi') abstract class ImagePickerApi { /// Selects images and returns their paths. - /// - /// Elements must not be null, by convention. See - /// https://github.com/flutter/flutter/issues/97848 @TaskQueue(type: TaskQueueType.serialBackgroundThread) @async - List pickImages( + List pickImages( SourceSpecification source, ImageSelectionOptions options, GeneralOptions generalOptions, ); /// Selects video and returns their paths. - /// - /// Elements must not be null, by convention. See - /// https://github.com/flutter/flutter/issues/97848 @TaskQueue(type: TaskQueueType.serialBackgroundThread) @async - List pickVideos( + List pickVideos( SourceSpecification source, VideoSelectionOptions options, GeneralOptions generalOptions, ); /// Selects images and videos and returns their paths. - /// - /// Elements must not be null, by convention. See - /// https://github.com/flutter/flutter/issues/97848 @async - List pickMedia( + List pickMedia( MediaSelectionOptions mediaSelectionOptions, GeneralOptions generalOptions, ); diff --git a/packages/image_picker/image_picker_android/pubspec.yaml b/packages/image_picker/image_picker_android/pubspec.yaml index 1bb91c514db2..605dc0c1585a 100755 --- a/packages/image_picker/image_picker_android/pubspec.yaml +++ b/packages/image_picker/image_picker_android/pubspec.yaml @@ -2,11 +2,11 @@ name: image_picker_android description: Android implementation of the image_picker plugin. repository: https://github.com/flutter/packages/tree/main/packages/image_picker/image_picker_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+image_picker%22 -version: 0.8.12+3 +version: 0.8.12+17 environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" flutter: plugin: @@ -26,8 +26,8 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - mockito: 5.4.4 - pigeon: ^17.0.0 + mockito: ^5.4.4 + pigeon: ^22.4.1 topics: - camera diff --git a/packages/image_picker/image_picker_android/test/image_picker_android_test.dart b/packages/image_picker/image_picker_android/test/image_picker_android_test.dart index 172b135ac0ac..75dc312226b7 100644 --- a/packages/image_picker/image_picker_android/test/image_picker_android_test.dart +++ b/packages/image_picker/image_picker_android/test/image_picker_android_test.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:flutter/src/services/binary_messenger.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:image_picker_android/image_picker_android.dart'; @@ -966,7 +967,7 @@ class _FakeImagePickerApi implements ImagePickerApi { _LastPickType? lastCall; @override - Future> pickImages( + Future> pickImages( SourceSpecification source, ImageSelectionOptions options, GeneralOptions generalOptions, @@ -977,11 +978,11 @@ class _FakeImagePickerApi implements ImagePickerApi { passedAllowMultiple = generalOptions.allowMultiple; passedPhotoPickerFlag = generalOptions.usePhotoPicker; limit = generalOptions.limit; - return returnValue as List? ?? []; + return returnValue as List? ?? []; } @override - Future> pickMedia( + Future> pickMedia( MediaSelectionOptions options, GeneralOptions generalOptions, ) async { @@ -990,11 +991,11 @@ class _FakeImagePickerApi implements ImagePickerApi { passedPhotoPickerFlag = generalOptions.usePhotoPicker; passedAllowMultiple = generalOptions.allowMultiple; limit = generalOptions.limit; - return returnValue as List? ?? []; + return returnValue as List? ?? []; } @override - Future> pickVideos( + Future> pickVideos( SourceSpecification source, VideoSelectionOptions options, GeneralOptions generalOptions, @@ -1004,11 +1005,19 @@ class _FakeImagePickerApi implements ImagePickerApi { passedVideoOptions = options; passedAllowMultiple = generalOptions.allowMultiple; passedPhotoPickerFlag = generalOptions.usePhotoPicker; - return returnValue as List? ?? []; + return returnValue as List? ?? []; } @override Future retrieveLostResults() async { return returnValue as CacheRetrievalResult?; } + + @override + // ignore: non_constant_identifier_names + BinaryMessenger? get pigeonVar_binaryMessenger => null; + + @override + // ignore: non_constant_identifier_names + String get pigeonVar_messageChannelSuffix => ''; } diff --git a/packages/image_picker/image_picker_android/test/test_api.g.dart b/packages/image_picker/image_picker_android/test/test_api.g.dart index 52aefcd0faab..4343c4958436 100644 --- a/packages/image_picker/image_picker_android/test/test_api.g.dart +++ b/packages/image_picker/image_picker_android/test/test_api.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 (v17.0.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.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, unnecessary_import, no_leading_underscores_for_local_identifiers // ignore_for_file: avoid_relative_lib_imports @@ -13,30 +13,42 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:image_picker_android/src/messages.g.dart'; -class _TestHostImagePickerApiCodec extends StandardMessageCodec { - const _TestHostImagePickerApiCodec(); +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is CacheRetrievalError) { - buffer.putUint8(128); - writeValue(buffer, value.encode()); - } else if (value is CacheRetrievalResult) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is SourceCamera) { buffer.putUint8(129); - writeValue(buffer, value.encode()); - } else if (value is GeneralOptions) { + writeValue(buffer, value.index); + } else if (value is SourceType) { buffer.putUint8(130); + writeValue(buffer, value.index); + } else if (value is CacheRetrievalType) { + buffer.putUint8(131); + writeValue(buffer, value.index); + } else if (value is GeneralOptions) { + buffer.putUint8(132); writeValue(buffer, value.encode()); } else if (value is ImageSelectionOptions) { - buffer.putUint8(131); + buffer.putUint8(133); writeValue(buffer, value.encode()); } else if (value is MediaSelectionOptions) { - buffer.putUint8(132); + buffer.putUint8(134); + writeValue(buffer, value.encode()); + } else if (value is VideoSelectionOptions) { + buffer.putUint8(135); writeValue(buffer, value.encode()); } else if (value is SourceSpecification) { - buffer.putUint8(133); + buffer.putUint8(136); writeValue(buffer, value.encode()); - } else if (value is VideoSelectionOptions) { - buffer.putUint8(134); + } else if (value is CacheRetrievalError) { + buffer.putUint8(137); + writeValue(buffer, value.encode()); + } else if (value is CacheRetrievalResult) { + buffer.putUint8(138); writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); @@ -46,20 +58,29 @@ class _TestHostImagePickerApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: - return CacheRetrievalError.decode(readValue(buffer)!); case 129: - return CacheRetrievalResult.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : SourceCamera.values[value]; case 130: - return GeneralOptions.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : SourceType.values[value]; case 131: - return ImageSelectionOptions.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : CacheRetrievalType.values[value]; case 132: - return MediaSelectionOptions.decode(readValue(buffer)!); + return GeneralOptions.decode(readValue(buffer)!); case 133: - return SourceSpecification.decode(readValue(buffer)!); + return ImageSelectionOptions.decode(readValue(buffer)!); case 134: + return MediaSelectionOptions.decode(readValue(buffer)!); + case 135: return VideoSelectionOptions.decode(readValue(buffer)!); + case 136: + return SourceSpecification.decode(readValue(buffer)!); + case 137: + return CacheRetrievalError.decode(readValue(buffer)!); + case 138: + return CacheRetrievalResult.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -69,47 +90,43 @@ class _TestHostImagePickerApiCodec extends StandardMessageCodec { abstract class TestHostImagePickerApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec pigeonChannelCodec = - _TestHostImagePickerApiCodec(); + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); /// Selects images and returns their paths. - /// - /// Elements must not be null, by convention. See - /// https://github.com/flutter/flutter/issues/97848 - Future> pickImages(SourceSpecification source, + Future> pickImages(SourceSpecification source, ImageSelectionOptions options, GeneralOptions generalOptions); /// Selects video and returns their paths. - /// - /// Elements must not be null, by convention. See - /// https://github.com/flutter/flutter/issues/97848 - Future> pickVideos(SourceSpecification source, + Future> pickVideos(SourceSpecification source, VideoSelectionOptions options, GeneralOptions generalOptions); /// Selects images and videos and returns their paths. - /// - /// Elements must not be null, by convention. See - /// https://github.com/flutter/flutter/issues/97848 - Future> pickMedia(MediaSelectionOptions mediaSelectionOptions, + Future> pickMedia(MediaSelectionOptions mediaSelectionOptions, GeneralOptions generalOptions); /// Returns results from a previous app session, if any. CacheRetrievalResult? retrieveLostResults(); - static void setup(TestHostImagePickerApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + TestHostImagePickerApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.image_picker_android.ImagePickerApi.pickImages', + 'dev.flutter.pigeon.image_picker_android.ImagePickerApi.pickImages$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.image_picker_android.ImagePickerApi.pickImages was null.'); @@ -127,7 +144,7 @@ abstract class TestHostImagePickerApi { assert(arg_generalOptions != null, 'Argument for dev.flutter.pigeon.image_picker_android.ImagePickerApi.pickImages was null, expected non-null GeneralOptions.'); try { - final List output = await api.pickImages( + final List output = await api.pickImages( arg_source!, arg_options!, arg_generalOptions!); return [output]; } on PlatformException catch (e) { @@ -140,17 +157,18 @@ abstract class TestHostImagePickerApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.image_picker_android.ImagePickerApi.pickVideos', + 'dev.flutter.pigeon.image_picker_android.ImagePickerApi.pickVideos$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.image_picker_android.ImagePickerApi.pickVideos was null.'); @@ -168,7 +186,7 @@ abstract class TestHostImagePickerApi { assert(arg_generalOptions != null, 'Argument for dev.flutter.pigeon.image_picker_android.ImagePickerApi.pickVideos was null, expected non-null GeneralOptions.'); try { - final List output = await api.pickVideos( + final List output = await api.pickVideos( arg_source!, arg_options!, arg_generalOptions!); return [output]; } on PlatformException catch (e) { @@ -181,17 +199,18 @@ abstract class TestHostImagePickerApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.image_picker_android.ImagePickerApi.pickMedia', + 'dev.flutter.pigeon.image_picker_android.ImagePickerApi.pickMedia$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.image_picker_android.ImagePickerApi.pickMedia was null.'); @@ -205,7 +224,7 @@ abstract class TestHostImagePickerApi { assert(arg_generalOptions != null, 'Argument for dev.flutter.pigeon.image_picker_android.ImagePickerApi.pickMedia was null, expected non-null GeneralOptions.'); try { - final List output = await api.pickMedia( + final List output = await api.pickMedia( arg_mediaSelectionOptions!, arg_generalOptions!); return [output]; } on PlatformException catch (e) { @@ -218,17 +237,18 @@ abstract class TestHostImagePickerApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.image_picker_android.ImagePickerApi.retrieveLostResults', + 'dev.flutter.pigeon.image_picker_android.ImagePickerApi.retrieveLostResults$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { try { final CacheRetrievalResult? output = api.retrieveLostResults(); diff --git a/packages/image_picker/image_picker_for_web/CHANGELOG.md b/packages/image_picker/image_picker_for_web/CHANGELOG.md index d548ccd9b824..8770e322a3dc 100644 --- a/packages/image_picker/image_picker_for_web/CHANGELOG.md +++ b/packages/image_picker/image_picker_for_web/CHANGELOG.md @@ -1,3 +1,12 @@ +## 3.0.6 + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. +* Extends the `mime` package version constraint from `^1.0.4` to `>=1.0.4 <3.0.0`. + +## 3.0.5 + +* Adds support for `web: ^1.0.0`. + ## 3.0.4 * Improves README example and updates it to use code excerpts. diff --git a/packages/image_picker/image_picker_for_web/README.md b/packages/image_picker/image_picker_for_web/README.md index 9e581d550dd9..0e82d9887f28 100644 --- a/packages/image_picker/image_picker_for_web/README.md +++ b/packages/image_picker/image_picker_for_web/README.md @@ -57,7 +57,7 @@ The argument `maxDuration` is not supported on the web. ### Import the package -This package is [endorsed](https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin), +This package is [endorsed](https://flutter.dev/to/endorsed-federated-plugin), which means you can simply use `image_picker` normally. This package will be automatically included in your app when you do, so you do not need to add it to your `pubspec.yaml`. diff --git a/packages/image_picker/image_picker_for_web/example/README.md b/packages/image_picker/image_picker_for_web/example/README.md index 4a01887de7fb..932e9f227cbe 100644 --- a/packages/image_picker/image_picker_for_web/example/README.md +++ b/packages/image_picker/image_picker_for_web/example/README.md @@ -15,5 +15,5 @@ This package uses `package:integration_test` to run its tests in a web browser. See [Plugin Tests > Web Tests](https://github.com/flutter/flutter/blob/master/docs/ecosystem/testing/Plugin-Tests.md#web-tests) in the Flutter documentation for instructions to set up and run the tests in this package. -Check [flutter.dev > Integration testing](https://flutter.dev/docs/testing/integration-tests) +Check [flutter.dev > Integration testing](https://docs.flutter.dev/testing/integration-tests) for more info. diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart index dc01ef6d1972..33f397a8c791 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart @@ -11,7 +11,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:image_picker_for_web/src/image_resizer.dart'; import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; import 'package:integration_test/integration_test.dart'; -import 'package:web/helpers.dart'; import 'package:web/web.dart' as web; //This is a sample 10x10 png image @@ -136,5 +135,5 @@ web.Blob _base64ToBlob(String data) { n--; } - return Blob([u8arr.toJS].toJS); + return web.Blob([u8arr.toJS].toJS); } diff --git a/packages/image_picker/image_picker_for_web/example/pubspec.yaml b/packages/image_picker/image_picker_for_web/example/pubspec.yaml index f4f85645c58d..25619c21184a 100644 --- a/packages/image_picker/image_picker_for_web/example/pubspec.yaml +++ b/packages/image_picker/image_picker_for_web/example/pubspec.yaml @@ -2,8 +2,8 @@ name: image_picker_for_web_integration_tests publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: @@ -11,7 +11,7 @@ dependencies: image_picker_for_web: path: ../ image_picker_platform_interface: ^2.8.0 - web: ^0.5.1 + web: ^1.0.0 dev_dependencies: flutter_test: diff --git a/packages/image_picker/image_picker_for_web/example/web/index.html b/packages/image_picker/image_picker_for_web/example/web/index.html index 7fb138cc90fa..956b11f49f7a 100644 --- a/packages/image_picker/image_picker_for_web/example/web/index.html +++ b/packages/image_picker/image_picker_for_web/example/web/index.html @@ -8,6 +8,6 @@ example - + diff --git a/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart b/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart index 7b32a451b67d..8cba8cfe91de 100644 --- a/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart +++ b/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart @@ -8,7 +8,6 @@ import 'dart:math'; import 'dart:ui'; import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; -import 'package:web/helpers.dart'; import 'package:web/web.dart' as web; import 'image_resizer_utils.dart'; @@ -48,7 +47,6 @@ class ImageResizer { Completer(); final web.HTMLImageElement imageElement = web.HTMLImageElement(); imageElement - // ignore: unsafe_html ..src = blobUrl ..onLoad.listen((web.Event event) { imageLoadCompleter.complete(imageElement); diff --git a/packages/image_picker/image_picker_for_web/pubspec.yaml b/packages/image_picker/image_picker_for_web/pubspec.yaml index 0fd82a6eeff9..89ccc2337762 100644 --- a/packages/image_picker/image_picker_for_web/pubspec.yaml +++ b/packages/image_picker/image_picker_for_web/pubspec.yaml @@ -2,11 +2,11 @@ name: image_picker_for_web description: Web platform implementation of image_picker repository: https://github.com/flutter/packages/tree/main/packages/image_picker/image_picker_for_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+image_picker%22 -version: 3.0.4 +version: 3.0.6 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: @@ -22,8 +22,8 @@ dependencies: flutter_web_plugins: sdk: flutter image_picker_platform_interface: ^2.9.0 - mime: ^1.0.4 - web: ^0.5.1 + mime: ">=1.0.4 <3.0.0" + web: ">=0.5.1 <2.0.0" dev_dependencies: flutter_test: diff --git a/packages/image_picker/image_picker_ios/CHANGELOG.md b/packages/image_picker/image_picker_ios/CHANGELOG.md index 4bbdbe6e865a..f31aa5c36662 100644 --- a/packages/image_picker/image_picker_ios/CHANGELOG.md +++ b/packages/image_picker/image_picker_ios/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.8.12+1 + +* Updates Pigeon for non-nullable collection type support. +* Updates UI test photo element query for iOS 18. + ## 0.8.12 * Re-adds Swift Package Manager compatibility. diff --git a/packages/image_picker/image_picker_ios/README.md b/packages/image_picker/image_picker_ios/README.md index 7375ecec55d8..02f126bbcf36 100755 --- a/packages/image_picker/image_picker_ios/README.md +++ b/packages/image_picker/image_picker_ios/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/image_picker -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/image_picker/image_picker_ios/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m b/packages/image_picker/image_picker_ios/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m index ddad2f03defb..45149f65f192 100644 --- a/packages/image_picker/image_picker_ios/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m +++ b/packages/image_picker/image_picker_ios/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m @@ -201,7 +201,8 @@ - (void)launchPickerAndPickWithMaxWidth:(NSNumber *)maxWidth // Find an image and tap on it. (IOS 14 UI, images are showing directly) XCUIElement *aImage; if (@available(iOS 14, *)) { - aImage = [self.app.scrollViews.firstMatch.images elementBoundByIndex:1]; + NSPredicate *imagePredicate = [NSPredicate predicateWithFormat:@"label BEGINSWITH 'Photo, '"]; + aImage = [self.app.images matchingPredicate:imagePredicate].firstMatch; } else { XCUIElement *allPhotosCell = self.app.cells[@"All Photos"].firstMatch; if (![allPhotosCell waitForExistenceWithTimeout:kElementWaitingTime]) { diff --git a/packages/image_picker/image_picker_ios/example/ios/RunnerUITests/ImagePickerFromLimitedGalleryUITests.m b/packages/image_picker/image_picker_ios/example/ios/RunnerUITests/ImagePickerFromLimitedGalleryUITests.m index bae11d5c01f9..d65b16d70fb2 100644 --- a/packages/image_picker/image_picker_ios/example/ios/RunnerUITests/ImagePickerFromLimitedGalleryUITests.m +++ b/packages/image_picker/image_picker_ios/example/ios/RunnerUITests/ImagePickerFromLimitedGalleryUITests.m @@ -107,7 +107,9 @@ - (void)testSelectingFromGallery API_AVAILABLE(ios(14)) { [self handlePermissionInterruption]; // Find an image and tap on it. - XCUIElement *aImage = [self.app.scrollViews.firstMatch.images elementBoundByIndex:1]; + NSPredicate *imagePredicate = [NSPredicate predicateWithFormat:@"label BEGINSWITH 'Photo, '"]; + XCUIElementQuery *imageQuery = [self.app.images matchingPredicate:imagePredicate]; + XCUIElement *aImage = imageQuery.firstMatch; os_log_error(OS_LOG_DEFAULT, "description before picking image %@", self.app.debugDescription); if (![aImage waitForExistenceWithTimeout:kLimitedElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription); @@ -126,7 +128,7 @@ - (void)testSelectingFromGallery API_AVAILABLE(ios(14)) { [doneButton tap]; // Find an image and tap on it to have access to selected photos. - aImage = [self.app.scrollViews.firstMatch.images elementBoundByIndex:1]; + aImage = imageQuery.firstMatch; os_log_error(OS_LOG_DEFAULT, "description before picking image %@", self.app.debugDescription); if (![aImage waitForExistenceWithTimeout:kLimitedElementWaitingTime]) { diff --git a/packages/image_picker/image_picker_ios/example/pubspec.yaml b/packages/image_picker/image_picker_ios/example/pubspec.yaml index 57c9e2d83fc4..dbfe54d4420f 100755 --- a/packages/image_picker/image_picker_ios/example/pubspec.yaml +++ b/packages/image_picker/image_picker_ios/example/pubspec.yaml @@ -17,7 +17,7 @@ dependencies: # the parent directory to use the current plugin's version. path: ../ image_picker_platform_interface: ^2.10.0 - mime: ^1.0.4 + mime: ^2.0.0 video_player: ^2.1.4 dev_dependencies: diff --git a/packages/image_picker/image_picker_ios/ios/image_picker_ios/Sources/image_picker_ios/include/image_picker_ios/messages.g.h b/packages/image_picker/image_picker_ios/ios/image_picker_ios/Sources/image_picker_ios/include/image_picker_ios/messages.g.h index de9a8200b82f..ccf843795064 100644 --- a/packages/image_picker/image_picker_ios/ios/image_picker_ios/Sources/image_picker_ios/include/image_picker_ios/messages.g.h +++ b/packages/image_picker/image_picker_ios/ios/image_picker_ios/Sources/image_picker_ios/include/image_picker_ios/messages.g.h @@ -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 (v17.0.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.1), do not edit directly. // See also: https://pub.dev/packages/pigeon #import @@ -68,8 +68,8 @@ typedef NS_ENUM(NSUInteger, FLTSourceType) { @property(nonatomic, assign) FLTSourceCamera camera; @end -/// The codec used by FLTImagePickerApi. -NSObject *FLTImagePickerApiGetCodec(void); +/// The codec used by all APIs. +NSObject *FLTGetMessagesCodec(void); @protocol FLTImagePickerApi - (void)pickImageWithSource:(FLTSourceSpecification *)source @@ -95,4 +95,8 @@ NSObject *FLTImagePickerApiGetCodec(void); extern void SetUpFLTImagePickerApi(id binaryMessenger, NSObject *_Nullable api); +extern void SetUpFLTImagePickerApiWithSuffix(id binaryMessenger, + NSObject *_Nullable api, + NSString *messageChannelSuffix); + NS_ASSUME_NONNULL_END diff --git a/packages/image_picker/image_picker_ios/ios/image_picker_ios/Sources/image_picker_ios/messages.g.m b/packages/image_picker/image_picker_ios/ios/image_picker_ios/Sources/image_picker_ios/messages.g.m index 0588aa932665..f2d8395cafff 100644 --- a/packages/image_picker/image_picker_ios/ios/image_picker_ios/Sources/image_picker_ios/messages.g.m +++ b/packages/image_picker/image_picker_ios/ios/image_picker_ios/Sources/image_picker_ios/messages.g.m @@ -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 (v17.0.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.1), do not edit directly. // See also: https://pub.dev/packages/pigeon #import "./include/image_picker_ios/messages.g.h" @@ -16,7 +16,7 @@ #error File requires ARC to be enabled. #endif -static NSArray *wrapResult(id result, FlutterError *error) { +static NSArray *wrapResult(id result, FlutterError *error) { if (error) { return @[ error.code ?: [NSNull null], error.message ?: [NSNull null], error.details ?: [NSNull null] @@ -25,7 +25,7 @@ return @[ result ?: [NSNull null] ]; } -static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) { +static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) { id result = array[key]; return (result == [NSNull null]) ? nil : result; } @@ -51,21 +51,21 @@ - (instancetype)initWithValue:(FLTSourceType)value { @end @interface FLTMaxSize () -+ (FLTMaxSize *)fromList:(NSArray *)list; -+ (nullable FLTMaxSize *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; ++ (FLTMaxSize *)fromList:(NSArray *)list; ++ (nullable FLTMaxSize *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; @end @interface FLTMediaSelectionOptions () -+ (FLTMediaSelectionOptions *)fromList:(NSArray *)list; -+ (nullable FLTMediaSelectionOptions *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; ++ (FLTMediaSelectionOptions *)fromList:(NSArray *)list; ++ (nullable FLTMediaSelectionOptions *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; @end @interface FLTSourceSpecification () -+ (FLTSourceSpecification *)fromList:(NSArray *)list; -+ (nullable FLTSourceSpecification *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; ++ (FLTSourceSpecification *)fromList:(NSArray *)list; ++ (nullable FLTSourceSpecification *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; @end @implementation FLTMaxSize @@ -75,16 +75,16 @@ + (instancetype)makeWithWidth:(nullable NSNumber *)width height:(nullable NSNumb pigeonResult.height = height; return pigeonResult; } -+ (FLTMaxSize *)fromList:(NSArray *)list { ++ (FLTMaxSize *)fromList:(NSArray *)list { FLTMaxSize *pigeonResult = [[FLTMaxSize alloc] init]; pigeonResult.width = GetNullableObjectAtIndex(list, 0); pigeonResult.height = GetNullableObjectAtIndex(list, 1); return pigeonResult; } -+ (nullable FLTMaxSize *)nullableFromList:(NSArray *)list { ++ (nullable FLTMaxSize *)nullableFromList:(NSArray *)list { return (list) ? [FLTMaxSize fromList:list] : nil; } -- (NSArray *)toList { +- (NSArray *)toList { return @[ self.width ?: [NSNull null], self.height ?: [NSNull null], @@ -106,21 +106,21 @@ + (instancetype)makeWithMaxSize:(FLTMaxSize *)maxSize pigeonResult.limit = limit; return pigeonResult; } -+ (FLTMediaSelectionOptions *)fromList:(NSArray *)list { ++ (FLTMediaSelectionOptions *)fromList:(NSArray *)list { FLTMediaSelectionOptions *pigeonResult = [[FLTMediaSelectionOptions alloc] init]; - pigeonResult.maxSize = [FLTMaxSize nullableFromList:(GetNullableObjectAtIndex(list, 0))]; + pigeonResult.maxSize = GetNullableObjectAtIndex(list, 0); pigeonResult.imageQuality = GetNullableObjectAtIndex(list, 1); pigeonResult.requestFullMetadata = [GetNullableObjectAtIndex(list, 2) boolValue]; pigeonResult.allowMultiple = [GetNullableObjectAtIndex(list, 3) boolValue]; pigeonResult.limit = GetNullableObjectAtIndex(list, 4); return pigeonResult; } -+ (nullable FLTMediaSelectionOptions *)nullableFromList:(NSArray *)list { ++ (nullable FLTMediaSelectionOptions *)nullableFromList:(NSArray *)list { return (list) ? [FLTMediaSelectionOptions fromList:list] : nil; } -- (NSArray *)toList { +- (NSArray *)toList { return @[ - (self.maxSize ? [self.maxSize toList] : [NSNull null]), + self.maxSize ?: [NSNull null], self.imageQuality ?: [NSNull null], @(self.requestFullMetadata), @(self.allowMultiple), @@ -136,33 +136,47 @@ + (instancetype)makeWithType:(FLTSourceType)type camera:(FLTSourceCamera)camera pigeonResult.camera = camera; return pigeonResult; } -+ (FLTSourceSpecification *)fromList:(NSArray *)list { ++ (FLTSourceSpecification *)fromList:(NSArray *)list { FLTSourceSpecification *pigeonResult = [[FLTSourceSpecification alloc] init]; - pigeonResult.type = [GetNullableObjectAtIndex(list, 0) integerValue]; - pigeonResult.camera = [GetNullableObjectAtIndex(list, 1) integerValue]; + FLTSourceTypeBox *boxedFLTSourceType = GetNullableObjectAtIndex(list, 0); + pigeonResult.type = boxedFLTSourceType.value; + FLTSourceCameraBox *boxedFLTSourceCamera = GetNullableObjectAtIndex(list, 1); + pigeonResult.camera = boxedFLTSourceCamera.value; return pigeonResult; } -+ (nullable FLTSourceSpecification *)nullableFromList:(NSArray *)list { ++ (nullable FLTSourceSpecification *)nullableFromList:(NSArray *)list { return (list) ? [FLTSourceSpecification fromList:list] : nil; } -- (NSArray *)toList { +- (NSArray *)toList { return @[ - @(self.type), - @(self.camera), + [[FLTSourceTypeBox alloc] initWithValue:self.type], + [[FLTSourceCameraBox alloc] initWithValue:self.camera], ]; } @end -@interface FLTImagePickerApiCodecReader : FlutterStandardReader +@interface FLTMessagesPigeonCodecReader : FlutterStandardReader @end -@implementation FLTImagePickerApiCodecReader +@implementation FLTMessagesPigeonCodecReader - (nullable id)readValueOfType:(UInt8)type { switch (type) { - case 128: + case 129: { + NSNumber *enumAsNumber = [self readValue]; + return enumAsNumber == nil + ? nil + : [[FLTSourceCameraBox alloc] initWithValue:[enumAsNumber integerValue]]; + } + case 130: { + NSNumber *enumAsNumber = [self readValue]; + return enumAsNumber == nil + ? nil + : [[FLTSourceTypeBox alloc] initWithValue:[enumAsNumber integerValue]]; + } + case 131: return [FLTMaxSize fromList:[self readValue]]; - case 129: + case 132: return [FLTMediaSelectionOptions fromList:[self readValue]]; - case 130: + case 133: return [FLTSourceSpecification fromList:[self readValue]]; default: return [super readValueOfType:type]; @@ -170,18 +184,26 @@ - (nullable id)readValueOfType:(UInt8)type { } @end -@interface FLTImagePickerApiCodecWriter : FlutterStandardWriter +@interface FLTMessagesPigeonCodecWriter : FlutterStandardWriter @end -@implementation FLTImagePickerApiCodecWriter +@implementation FLTMessagesPigeonCodecWriter - (void)writeValue:(id)value { - if ([value isKindOfClass:[FLTMaxSize class]]) { - [self writeByte:128]; + if ([value isKindOfClass:[FLTSourceCameraBox class]]) { + FLTSourceCameraBox *box = (FLTSourceCameraBox *)value; + [self writeByte:129]; + [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; + } else if ([value isKindOfClass:[FLTSourceTypeBox class]]) { + FLTSourceTypeBox *box = (FLTSourceTypeBox *)value; + [self writeByte:130]; + [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; + } else if ([value isKindOfClass:[FLTMaxSize class]]) { + [self writeByte:131]; [self writeValue:[value toList]]; } else if ([value isKindOfClass:[FLTMediaSelectionOptions class]]) { - [self writeByte:129]; + [self writeByte:132]; [self writeValue:[value toList]]; } else if ([value isKindOfClass:[FLTSourceSpecification class]]) { - [self writeByte:130]; + [self writeByte:133]; [self writeValue:[value toList]]; } else { [super writeValue:value]; @@ -189,35 +211,47 @@ - (void)writeValue:(id)value { } @end -@interface FLTImagePickerApiCodecReaderWriter : FlutterStandardReaderWriter +@interface FLTMessagesPigeonCodecReaderWriter : FlutterStandardReaderWriter @end -@implementation FLTImagePickerApiCodecReaderWriter +@implementation FLTMessagesPigeonCodecReaderWriter - (FlutterStandardWriter *)writerWithData:(NSMutableData *)data { - return [[FLTImagePickerApiCodecWriter alloc] initWithData:data]; + return [[FLTMessagesPigeonCodecWriter alloc] initWithData:data]; } - (FlutterStandardReader *)readerWithData:(NSData *)data { - return [[FLTImagePickerApiCodecReader alloc] initWithData:data]; + return [[FLTMessagesPigeonCodecReader alloc] initWithData:data]; } @end -NSObject *FLTImagePickerApiGetCodec(void) { +NSObject *FLTGetMessagesCodec(void) { static FlutterStandardMessageCodec *sSharedObject = nil; static dispatch_once_t sPred = 0; dispatch_once(&sPred, ^{ - FLTImagePickerApiCodecReaderWriter *readerWriter = - [[FLTImagePickerApiCodecReaderWriter alloc] init]; + FLTMessagesPigeonCodecReaderWriter *readerWriter = + [[FLTMessagesPigeonCodecReaderWriter alloc] init]; sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter]; }); return sSharedObject; } - void SetUpFLTImagePickerApi(id binaryMessenger, NSObject *api) { + SetUpFLTImagePickerApiWithSuffix(binaryMessenger, api, @""); +} + +void SetUpFLTImagePickerApiWithSuffix(id binaryMessenger, + NSObject *api, + NSString *messageChannelSuffix) { + messageChannelSuffix = messageChannelSuffix.length > 0 + ? [NSString stringWithFormat:@".%@", messageChannelSuffix] + : @""; { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickImage" + initWithName: + [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickImage", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FLTImagePickerApiGetCodec()]; + codec:FLTGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector (pickImageWithSource:maxSize:quality:fullMetadata:completion:)], @@ -225,7 +259,7 @@ void SetUpFLTImagePickerApi(id binaryMessenger, @"@selector(pickImageWithSource:maxSize:quality:fullMetadata:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; FLTSourceSpecification *arg_source = GetNullableObjectAtIndex(args, 0); FLTMaxSize *arg_maxSize = GetNullableObjectAtIndex(args, 1); NSNumber *arg_imageQuality = GetNullableObjectAtIndex(args, 2); @@ -244,9 +278,12 @@ void SetUpFLTImagePickerApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickMultiImage" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.image_picker_ios." + @"ImagePickerApi.pickMultiImage", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FLTImagePickerApiGetCodec()]; + codec:FLTGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector (pickMultiImageWithMaxSize:quality:fullMetadata:limit:completion:)], @@ -254,7 +291,7 @@ void SetUpFLTImagePickerApi(id binaryMessenger, @"@selector(pickMultiImageWithMaxSize:quality:fullMetadata:limit:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; FLTMaxSize *arg_maxSize = GetNullableObjectAtIndex(args, 0); NSNumber *arg_imageQuality = GetNullableObjectAtIndex(args, 1); BOOL arg_requestFullMetadata = [GetNullableObjectAtIndex(args, 2) boolValue]; @@ -274,16 +311,20 @@ void SetUpFLTImagePickerApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickVideo" + initWithName: + [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickVideo", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FLTImagePickerApiGetCodec()]; + codec:FLTGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(pickVideoWithSource:maxDuration:completion:)], @"FLTImagePickerApi api (%@) doesn't respond to " @"@selector(pickVideoWithSource:maxDuration:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; FLTSourceSpecification *arg_source = GetNullableObjectAtIndex(args, 0); NSNumber *arg_maxDurationSeconds = GetNullableObjectAtIndex(args, 1); [api pickVideoWithSource:arg_source @@ -299,16 +340,20 @@ void SetUpFLTImagePickerApi(id binaryMessenger, /// Selects images and videos and returns their paths. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickMedia" + initWithName: + [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickMedia", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FLTImagePickerApiGetCodec()]; + codec:FLTGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(pickMediaWithMediaSelectionOptions:completion:)], @"FLTImagePickerApi api (%@) doesn't respond to " @"@selector(pickMediaWithMediaSelectionOptions:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; FLTMediaSelectionOptions *arg_mediaSelectionOptions = GetNullableObjectAtIndex(args, 0); [api pickMediaWithMediaSelectionOptions:arg_mediaSelectionOptions completion:^(NSArray *_Nullable output, diff --git a/packages/image_picker/image_picker_ios/lib/image_picker_ios.dart b/packages/image_picker/image_picker_ios/lib/image_picker_ios.dart index 96166130797d..ea188cb4ad63 100644 --- a/packages/image_picker/image_picker_ios/lib/image_picker_ios.dart +++ b/packages/image_picker/image_picker_ios/lib/image_picker_ios.dart @@ -88,7 +88,7 @@ class ImagePickerIOS extends ImagePickerPlatform { double? maxHeight, int? imageQuality, }) async { - final List paths = await _pickMultiImageAsPath( + final List paths = await _pickMultiImageAsPath( options: MultiImagePickerOptions( imageOptions: ImageOptions( maxWidth: maxWidth, @@ -103,7 +103,7 @@ class ImagePickerIOS extends ImagePickerPlatform { return null; } - return paths.map((dynamic path) => PickedFile(path as String)).toList(); + return paths.map((String path) => PickedFile(path)).toList(); } @override @@ -138,15 +138,12 @@ class ImagePickerIOS extends ImagePickerPlatform { throw ArgumentError.value(limit, 'limit', 'cannot be lower than 2'); } - // TODO(stuartmorgan): Remove the cast once Pigeon supports non-nullable - // generics, https://github.com/flutter/flutter/issues/97848 - return (await _hostApi.pickMultiImage( + return _hostApi.pickMultiImage( MaxSize(width: maxWidth, height: maxHeight), imageQuality, options.imageOptions.requestFullMetadata, limit, - )) - .cast(); + ); } Future _pickImageAsPath({ diff --git a/packages/image_picker/image_picker_ios/lib/src/messages.g.dart b/packages/image_picker/image_picker_ios/lib/src/messages.g.dart index b3e785a09dff..63a245a1a673 100644 --- a/packages/image_picker/image_picker_ios/lib/src/messages.g.dart +++ b/packages/image_picker/image_picker_ios/lib/src/messages.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 (v17.0.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.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 @@ -86,7 +86,7 @@ class MediaSelectionOptions { Object encode() { return [ - maxSize.encode(), + maxSize, imageQuality, requestFullMetadata, allowMultiple, @@ -97,7 +97,7 @@ class MediaSelectionOptions { static MediaSelectionOptions decode(Object result) { result as List; return MediaSelectionOptions( - maxSize: MaxSize.decode(result[0]! as List), + maxSize: result[0]! as MaxSize, imageQuality: result[1] as int?, requestFullMetadata: result[2]! as bool, allowMultiple: result[3]! as bool, @@ -118,32 +118,41 @@ class SourceSpecification { Object encode() { return [ - type.index, - camera.index, + type, + camera, ]; } static SourceSpecification decode(Object result) { result as List; return SourceSpecification( - type: SourceType.values[result[0]! as int], - camera: SourceCamera.values[result[1]! as int], + type: result[0]! as SourceType, + camera: result[1]! as SourceCamera, ); } } -class _ImagePickerApiCodec extends StandardMessageCodec { - const _ImagePickerApiCodec(); +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is MaxSize) { - buffer.putUint8(128); + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is SourceCamera) { + buffer.putUint8(129); + writeValue(buffer, value.index); + } else if (value is SourceType) { + buffer.putUint8(130); + writeValue(buffer, value.index); + } else if (value is MaxSize) { + buffer.putUint8(131); writeValue(buffer, value.encode()); } else if (value is MediaSelectionOptions) { - buffer.putUint8(129); + buffer.putUint8(132); writeValue(buffer, value.encode()); } else if (value is SourceSpecification) { - buffer.putUint8(130); + buffer.putUint8(133); writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); @@ -153,11 +162,17 @@ class _ImagePickerApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: - return MaxSize.decode(readValue(buffer)!); case 129: - return MediaSelectionOptions.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : SourceCamera.values[value]; case 130: + final int? value = readValue(buffer) as int?; + return value == null ? null : SourceType.values[value]; + case 131: + return MaxSize.decode(readValue(buffer)!); + case 132: + return MediaSelectionOptions.decode(readValue(buffer)!); + case 133: return SourceSpecification.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -169,123 +184,127 @@ class ImagePickerApi { /// Constructor for [ImagePickerApi]. 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. - ImagePickerApi({BinaryMessenger? binaryMessenger}) - : __pigeon_binaryMessenger = binaryMessenger; - final BinaryMessenger? __pigeon_binaryMessenger; + ImagePickerApi( + {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 = - _ImagePickerApiCodec(); + final String pigeonVar_messageChannelSuffix; Future pickImage(SourceSpecification source, MaxSize maxSize, int? imageQuality, bool requestFullMetadata) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickImage'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickImage$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([source, maxSize, imageQuality, requestFullMetadata]) 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 (__pigeon_replyList[0] as String?); + return (pigeonVar_replyList[0] as String?); } } - Future> pickMultiImage(MaxSize maxSize, int? imageQuality, + Future> pickMultiImage(MaxSize maxSize, int? imageQuality, bool requestFullMetadata, int? limit) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickMultiImage'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickMultiImage$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([maxSize, imageQuality, requestFullMetadata, limit]) 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(); } } Future pickVideo( SourceSpecification source, int? maxDurationSeconds) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickVideo'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickVideo$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([source, maxDurationSeconds]) 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 (__pigeon_replyList[0] as String?); + return (pigeonVar_replyList[0] as String?); } } /// Selects images and videos and returns their paths. - Future> pickMedia( + Future> pickMedia( MediaSelectionOptions mediaSelectionOptions) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickMedia'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickMedia$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([mediaSelectionOptions]) 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/image_picker/image_picker_ios/pigeons/messages.dart b/packages/image_picker/image_picker_ios/pigeons/messages.dart index 4a31ae0b6c32..c8dd34fa5697 100644 --- a/packages/image_picker/image_picker_ios/pigeons/messages.dart +++ b/packages/image_picker/image_picker_ios/pigeons/messages.dart @@ -58,7 +58,7 @@ abstract class ImagePickerApi { int? imageQuality, bool requestFullMetadata); @async @ObjCSelector('pickMultiImageWithMaxSize:quality:fullMetadata:limit:') - List pickMultiImage( + List pickMultiImage( MaxSize maxSize, int? imageQuality, bool requestFullMetadata, int? limit); @async @ObjCSelector('pickVideoWithSource:maxDuration:') @@ -67,5 +67,5 @@ abstract class ImagePickerApi { /// Selects images and videos and returns their paths. @async @ObjCSelector('pickMediaWithMediaSelectionOptions:') - List pickMedia(MediaSelectionOptions mediaSelectionOptions); + List pickMedia(MediaSelectionOptions mediaSelectionOptions); } diff --git a/packages/image_picker/image_picker_ios/pubspec.yaml b/packages/image_picker/image_picker_ios/pubspec.yaml index bbc99bc79f31..a1f752f33bce 100755 --- a/packages/image_picker/image_picker_ios/pubspec.yaml +++ b/packages/image_picker/image_picker_ios/pubspec.yaml @@ -2,7 +2,7 @@ name: image_picker_ios description: iOS implementation of the image_picker plugin. repository: https://github.com/flutter/packages/tree/main/packages/image_picker/image_picker_ios issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+image_picker%22 -version: 0.8.12 +version: 0.8.12+1 environment: sdk: ^3.3.0 @@ -24,11 +24,11 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - mockito: 5.4.4 - pigeon: ^17.0.0 + mockito: ^5.4.4 + pigeon: ^22.4.1 topics: - camera - image-picker - files - - file-selection \ No newline at end of file + - file-selection diff --git a/packages/image_picker/image_picker_ios/test/image_picker_ios_test.dart b/packages/image_picker/image_picker_ios/test/image_picker_ios_test.dart index c2e5f74763f2..c84b2554301d 100644 --- a/packages/image_picker/image_picker_ios/test/image_picker_ios_test.dart +++ b/packages/image_picker/image_picker_ios/test/image_picker_ios_test.dart @@ -57,7 +57,7 @@ class _ApiLogger implements TestHostImagePickerApi { } @override - Future> pickMultiImage( + Future> pickMultiImage( MaxSize maxSize, int? imageQuality, bool requestFullMetadata, @@ -70,11 +70,11 @@ class _ApiLogger implements TestHostImagePickerApi { 'requestFullMetadata': requestFullMetadata, 'limit': limit, })); - return returnValue as List; + return returnValue as List; } @override - Future> pickMedia( + Future> pickMedia( MediaSelectionOptions mediaSelectionOptions) async { calls.add(_LoggedMethodCall('pickMedia', arguments: { 'maxWidth': mediaSelectionOptions.maxSize.width, @@ -84,7 +84,7 @@ class _ApiLogger implements TestHostImagePickerApi { 'allowMultiple': mediaSelectionOptions.allowMultiple, 'limit': mediaSelectionOptions.limit, })); - return returnValue as List; + return returnValue as List; } @override @@ -107,7 +107,7 @@ void main() { setUp(() { log = _ApiLogger(); - TestHostImagePickerApi.setup(log); + TestHostImagePickerApi.setUp(log); }); test('registration', () async { diff --git a/packages/image_picker/image_picker_ios/test/test_api.g.dart b/packages/image_picker/image_picker_ios/test/test_api.g.dart index 4208c68e32f2..46dc4e4e85d8 100644 --- a/packages/image_picker/image_picker_ios/test/test_api.g.dart +++ b/packages/image_picker/image_picker_ios/test/test_api.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 (v17.0.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.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, unnecessary_import, no_leading_underscores_for_local_identifiers // ignore_for_file: avoid_relative_lib_imports @@ -13,18 +13,27 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:image_picker_ios/src/messages.g.dart'; -class _TestHostImagePickerApiCodec extends StandardMessageCodec { - const _TestHostImagePickerApiCodec(); +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is MaxSize) { - buffer.putUint8(128); + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is SourceCamera) { + buffer.putUint8(129); + writeValue(buffer, value.index); + } else if (value is SourceType) { + buffer.putUint8(130); + writeValue(buffer, value.index); + } else if (value is MaxSize) { + buffer.putUint8(131); writeValue(buffer, value.encode()); } else if (value is MediaSelectionOptions) { - buffer.putUint8(129); + buffer.putUint8(132); writeValue(buffer, value.encode()); } else if (value is SourceSpecification) { - buffer.putUint8(130); + buffer.putUint8(133); writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); @@ -34,11 +43,17 @@ class _TestHostImagePickerApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: - return MaxSize.decode(readValue(buffer)!); case 129: - return MediaSelectionOptions.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : SourceCamera.values[value]; case 130: + final int? value = readValue(buffer) as int?; + return value == null ? null : SourceType.values[value]; + case 131: + return MaxSize.decode(readValue(buffer)!); + case 132: + return MediaSelectionOptions.decode(readValue(buffer)!); + case 133: return SourceSpecification.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -49,35 +64,40 @@ class _TestHostImagePickerApiCodec extends StandardMessageCodec { abstract class TestHostImagePickerApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec pigeonChannelCodec = - _TestHostImagePickerApiCodec(); + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); Future pickImage(SourceSpecification source, MaxSize maxSize, int? imageQuality, bool requestFullMetadata); - Future> pickMultiImage( + Future> pickMultiImage( MaxSize maxSize, int? imageQuality, bool requestFullMetadata, int? limit); Future pickVideo( SourceSpecification source, int? maxDurationSeconds); /// Selects images and videos and returns their paths. - Future> pickMedia(MediaSelectionOptions mediaSelectionOptions); + Future> pickMedia(MediaSelectionOptions mediaSelectionOptions); - static void setup(TestHostImagePickerApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + TestHostImagePickerApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel __pigeon_channel = - BasicMessageChannel( - 'dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickImage', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickImage$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickImage was null.'); @@ -107,17 +127,18 @@ abstract class TestHostImagePickerApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickMultiImage', + 'dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickMultiImage$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickMultiImage was null.'); @@ -131,7 +152,7 @@ abstract class TestHostImagePickerApi { 'Argument for dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickMultiImage was null, expected non-null bool.'); final int? arg_limit = (args[3] as int?); try { - final List output = await api.pickMultiImage(arg_maxSize!, + final List output = await api.pickMultiImage(arg_maxSize!, arg_imageQuality, arg_requestFullMetadata!, arg_limit); return [output]; } on PlatformException catch (e) { @@ -144,17 +165,18 @@ abstract class TestHostImagePickerApi { } } { - final BasicMessageChannel __pigeon_channel = - BasicMessageChannel( - 'dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickVideo', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickVideo$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickVideo was null.'); @@ -178,17 +200,18 @@ abstract class TestHostImagePickerApi { } } { - final BasicMessageChannel __pigeon_channel = - BasicMessageChannel( - 'dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickMedia', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickMedia$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickMedia was null.'); @@ -198,7 +221,7 @@ abstract class TestHostImagePickerApi { assert(arg_mediaSelectionOptions != null, 'Argument for dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickMedia was null, expected non-null MediaSelectionOptions.'); try { - final List output = + final List output = await api.pickMedia(arg_mediaSelectionOptions!); return [output]; } on PlatformException catch (e) { diff --git a/packages/image_picker/image_picker_linux/CHANGELOG.md b/packages/image_picker/image_picker_linux/CHANGELOG.md index 0299d9f52578..50d3dd738917 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.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 0.2.1+1 diff --git a/packages/image_picker/image_picker_linux/README.md b/packages/image_picker/image_picker_linux/README.md index 1f1833e81e62..55b58356c707 100644 --- a/packages/image_picker/image_picker_linux/README.md +++ b/packages/image_picker/image_picker_linux/README.md @@ -24,4 +24,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/image_picker -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/image_picker/image_picker_linux/example/pubspec.yaml b/packages/image_picker/image_picker_linux/example/pubspec.yaml index f211797e1c3e..5db5fb085f8c 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: @@ -18,7 +18,7 @@ dependencies: # the parent directory to use the current plugin's version. path: .. image_picker_platform_interface: ^2.8.0 - mime: ^1.0.4 + mime: ^2.0.0 video_player: ^2.1.4 dev_dependencies: diff --git a/packages/image_picker/image_picker_linux/pubspec.yaml b/packages/image_picker/image_picker_linux/pubspec.yaml index c0d530e5b9e5..8e44fac8d48a 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -26,7 +26,7 @@ dev_dependencies: build_runner: ^2.1.5 flutter_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 topics: - image-picker diff --git a/packages/image_picker/image_picker_macos/CHANGELOG.md b/packages/image_picker/image_picker_macos/CHANGELOG.md index 16afc6978afd..6012fff8dbcd 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.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 0.2.1+1 diff --git a/packages/image_picker/image_picker_macos/README.md b/packages/image_picker/image_picker_macos/README.md index ec76d85e26be..9aa87453532e 100644 --- a/packages/image_picker/image_picker_macos/README.md +++ b/packages/image_picker/image_picker_macos/README.md @@ -33,6 +33,6 @@ need to add a read-only file acces [entitlement][4]: ``` [1]: https://pub.dev/packages/image_picker -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin [3]: https://pub.dev/packages/file_selector -[4]: https://docs.flutter.dev/platform-integration/macos/building#entitlements-and-the-app-sandbox +[4]: https://flutter.dev/to/macos-entitlements diff --git a/packages/image_picker/image_picker_macos/example/macos/Podfile b/packages/image_picker/image_picker_macos/example/macos/Podfile index 049abe295427..ae77cc1d4269 100644 --- a/packages/image_picker/image_picker_macos/example/macos/Podfile +++ b/packages/image_picker/image_picker_macos/example/macos/Podfile @@ -28,7 +28,6 @@ flutter_macos_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) end diff --git a/packages/image_picker/image_picker_macos/example/pubspec.yaml b/packages/image_picker/image_picker_macos/example/pubspec.yaml index e6f1b3ba1eb1..ab0d82bbc305 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: @@ -18,7 +18,7 @@ dependencies: # the parent directory to use the current plugin's version. path: .. image_picker_platform_interface: ^2.8.0 - mime: ^1.0.4 + mime: ^2.0.0 video_player: ^2.1.4 dev_dependencies: diff --git a/packages/image_picker/image_picker_macos/pubspec.yaml b/packages/image_picker/image_picker_macos/pubspec.yaml index ce1d4ae5b99e..3b11740e8d86 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -26,7 +26,7 @@ dev_dependencies: build_runner: ^2.1.5 flutter_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 topics: - image-picker diff --git a/packages/image_picker/image_picker_windows/CHANGELOG.md b/packages/image_picker/image_picker_windows/CHANGELOG.md index eb9eed2363e2..8195bb8a66af 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.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 0.2.1+1 diff --git a/packages/image_picker/image_picker_windows/README.md b/packages/image_picker/image_picker_windows/README.md index 1aa30b17fc0b..d071b2a6f43f 100644 --- a/packages/image_picker/image_picker_windows/README.md +++ b/packages/image_picker/image_picker_windows/README.md @@ -24,4 +24,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/image_picker -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/image_picker/image_picker_windows/example/pubspec.yaml b/packages/image_picker/image_picker_windows/example/pubspec.yaml index 0d50b6751b06..744a9e61ba0f 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: @@ -18,7 +18,7 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: .. - mime: ^1.0.4 + mime: ^2.0.0 video_player: ^2.1.4 dev_dependencies: diff --git a/packages/image_picker/image_picker_windows/pubspec.yaml b/packages/image_picker/image_picker_windows/pubspec.yaml index ca65e3dcfb64..51d9a94ee6e4 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -26,7 +26,7 @@ dev_dependencies: build_runner: ^2.1.5 flutter_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 topics: - image-picker diff --git a/packages/in_app_purchase/in_app_purchase/CHANGELOG.md b/packages/in_app_purchase/in_app_purchase/CHANGELOG.md index fc0f7d286cb5..d4a2e5ab131d 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.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 3.2.0 diff --git a/packages/in_app_purchase/in_app_purchase/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/in_app_purchase/in_app_purchase/example/android/app/gradle/wrapper/gradle-wrapper.properties index 609ab8e6c8b5..d951fac2bf31 100644 --- a/packages/in_app_purchase/in_app_purchase/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ b/packages/in_app_purchase/in_app_purchase/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/packages/in_app_purchase/in_app_purchase/example/android/build.gradle b/packages/in_app_purchase/in_app_purchase/example/android/build.gradle index cec92de922cf..0bed8906c094 100644 --- a/packages/in_app_purchase/in_app_purchase/example/android/build.gradle +++ b/packages/in_app_purchase/in_app_purchase/example/android/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath 'com.android.tools.build:gradle:8.5.2' } } diff --git a/packages/in_app_purchase/in_app_purchase/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/in_app_purchase/in_app_purchase/example/android/gradle/wrapper/gradle-wrapper.properties index aeaff6f869f3..7aeeb11c6ee5 100644 --- a/packages/in_app_purchase/in_app_purchase/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/in_app_purchase/in_app_purchase/example/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/in_app_purchase/in_app_purchase/example/macos/Podfile b/packages/in_app_purchase/in_app_purchase/example/macos/Podfile index 9ec46f8cd53c..66f6172bbb39 100644 --- a/packages/in_app_purchase/in_app_purchase/example/macos/Podfile +++ b/packages/in_app_purchase/in_app_purchase/example/macos/Podfile @@ -28,7 +28,6 @@ flutter_macos_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) end 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 d689dce3c083..c9c79cf63bc4 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.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 3f31fcd2e414..c5ff3bf3b588 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.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: diff --git a/packages/in_app_purchase/in_app_purchase_android/CHANGELOG.md b/packages/in_app_purchase/in_app_purchase_android/CHANGELOG.md index ea9332cbe962..e3084fe05632 100644 --- a/packages/in_app_purchase/in_app_purchase_android/CHANGELOG.md +++ b/packages/in_app_purchase/in_app_purchase_android/CHANGELOG.md @@ -1,3 +1,44 @@ +## 0.3.6+11 + +* Bumps androidx.annotation:annotation from 1.8.2 to 1.9.0. + +## 0.3.6+10 + +* Updates Pigeon for non-nullable collection type support. + +## 0.3.6+9 + +* Updates Java compatibility version to 11. + +## 0.3.6+8 + +* Removes dependency on org.jetbrains.kotlin:kotlin-bom. +* Updates minimum supported SDK version to Flutter 3.24/Dart 3.5. + +## 0.3.6+7 + +* Sets `android.buildFeatures.buildConfig` to true for compatibility with AGP 8.0+. + +## 0.3.6+6 + +* Bumps androidx.annotation:annotation from 1.8.1 to 1.8.2. + +## 0.3.6+5 + +* Bumps com.android.billingclient:billing from 6.1.0 to 6.2.0. + +## 0.3.6+4 + +* Bumps androidx.annotation:annotation from 1.8.0 to 1.8.1. + +## 0.3.6+3 + +* Updates lint checks to ignore NewerVersionAvailable. + +## 0.3.6+2 + +* Updates Android Gradle Plugin to 8.5.1. + ## 0.3.6+1 * Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. diff --git a/packages/in_app_purchase/in_app_purchase_android/README.md b/packages/in_app_purchase/in_app_purchase_android/README.md index f5cdbf9e0e95..92257cd2ba6e 100644 --- a/packages/in_app_purchase/in_app_purchase_android/README.md +++ b/packages/in_app_purchase/in_app_purchase_android/README.md @@ -37,5 +37,5 @@ If you would like to contribute to the plugin, check out our [1]: https://pub.dev/packages/in_app_purchase -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin [3]: https://pub.dev/packages/in_app_purchase_android/install diff --git a/packages/in_app_purchase/in_app_purchase_android/android/build.gradle b/packages/in_app_purchase/in_app_purchase_android/android/build.gradle index bd28bd93ed0e..7a790d8d8406 100644 --- a/packages/in_app_purchase/in_app_purchase_android/android/build.gradle +++ b/packages/in_app_purchase/in_app_purchase_android/android/build.gradle @@ -8,7 +8,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.3.1' + classpath 'com.android.tools.build:gradle:8.5.1' } } @@ -22,10 +22,11 @@ rootProject.allprojects { apply plugin: 'com.android.library' android { - // Conditional for compatibility with AGP <4.2. - if (project.android.hasProperty("namespace")) { - namespace 'io.flutter.plugins.inapppurchase' + buildFeatures { + buildConfig true } + + namespace 'io.flutter.plugins.inapppurchase' compileSdk 34 @@ -36,11 +37,11 @@ android { lintOptions { checkAllWarnings true warningsAsErrors true - disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency' + disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency', 'NewerVersionAvailable' } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } @@ -58,16 +59,13 @@ android { } dependencies { - implementation 'androidx.annotation:annotation:1.8.0' - // org.jetbrains.kotlin:kotlin-bom artifact purpose is to align kotlin stdlib and related code versions. - // See: https://youtrack.jetbrains.com/issue/KT-55297/kotlin-stdlib-should-declare-constraints-on-kotlin-stdlib-jdk8-and-kotlin-stdlib-jdk7 - implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.22")) - implementation 'com.android.billingclient:billing:6.1.0' + implementation 'androidx.annotation:annotation:1.9.0' + implementation 'com.android.billingclient:billing:6.2.0' testImplementation 'junit:junit:4.13.2' testImplementation 'org.json:json:20240303' testImplementation 'org.mockito:mockito-core:5.4.0' testImplementation 'androidx.test:core:1.5.0' testImplementation 'org.robolectric:robolectric:4.10.3' androidTestImplementation 'androidx.test:runner:1.5.2' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' } diff --git a/packages/in_app_purchase/in_app_purchase_android/android/src/main/java/io/flutter/plugins/inapppurchase/Messages.java b/packages/in_app_purchase/in_app_purchase_android/android/src/main/java/io/flutter/plugins/inapppurchase/Messages.java index 0602260e72f4..cef3e316c3d6 100644 --- a/packages/in_app_purchase/in_app_purchase_android/android/src/main/java/io/flutter/plugins/inapppurchase/Messages.java +++ b/packages/in_app_purchase/in_app_purchase_android/android/src/main/java/io/flutter/plugins/inapppurchase/Messages.java @@ -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 (v17.3.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.2), do not edit directly. // See also: https://pub.dev/packages/pigeon package io.flutter.plugins.inapppurchase; @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Objects; /** Generated class from Pigeon. */ @SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression", "serial"}) @@ -46,7 +47,7 @@ public FlutterError(@NonNull String code, @Nullable String message, @Nullable Ob @NonNull protected static ArrayList wrapError(@NonNull Throwable exception) { - ArrayList errorList = new ArrayList(3); + ArrayList errorList = new ArrayList<>(3); if (exception instanceof FlutterError) { FlutterError error = (FlutterError) exception; errorList.add(error.code); @@ -78,7 +79,7 @@ public enum PlatformProductType { final int index; - private PlatformProductType(final int index) { + PlatformProductType(final int index) { this.index = index; } } @@ -98,7 +99,7 @@ public enum PlatformBillingChoiceMode { final int index; - private PlatformBillingChoiceMode(final int index) { + PlatformBillingChoiceMode(final int index) { this.index = index; } } @@ -111,7 +112,7 @@ public enum PlatformPurchaseState { final int index; - private PlatformPurchaseState(final int index) { + PlatformPurchaseState(final int index) { this.index = index; } } @@ -124,7 +125,7 @@ public enum PlatformRecurrenceMode { final int index; - private PlatformRecurrenceMode(final int index) { + PlatformRecurrenceMode(final int index) { this.index = index; } } @@ -164,6 +165,23 @@ public void setProductType(@NonNull PlatformProductType setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ PlatformQueryProduct() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformQueryProduct that = (PlatformQueryProduct) o; + return productId.equals(that.productId) && productType.equals(that.productType); + } + + @Override + public int hashCode() { + return Objects.hash(productId, productType); + } + public static final class Builder { private @Nullable String productId; @@ -192,18 +210,18 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(2); + ArrayList toListResult = new ArrayList<>(2); toListResult.add(productId); - toListResult.add(productType == null ? null : productType.index); + toListResult.add(productType); return toListResult; } - static @NonNull PlatformQueryProduct fromList(@NonNull ArrayList list) { + static @NonNull PlatformQueryProduct fromList(@NonNull ArrayList pigeonVar_list) { PlatformQueryProduct pigeonResult = new PlatformQueryProduct(); - Object productId = list.get(0); + Object productId = pigeonVar_list.get(0); pigeonResult.setProductId((String) productId); - Object productType = list.get(1); - pigeonResult.setProductType(PlatformProductType.values()[(int) productType]); + Object productType = pigeonVar_list.get(1); + pigeonResult.setProductType((PlatformProductType) productType); return pigeonResult; } } @@ -234,6 +252,24 @@ public void setObfuscatedProfileId(@Nullable String setterArg) { this.obfuscatedProfileId = setterArg; } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformAccountIdentifiers that = (PlatformAccountIdentifiers) o; + return Objects.equals(obfuscatedAccountId, that.obfuscatedAccountId) + && Objects.equals(obfuscatedProfileId, that.obfuscatedProfileId); + } + + @Override + public int hashCode() { + return Objects.hash(obfuscatedAccountId, obfuscatedProfileId); + } + public static final class Builder { private @Nullable String obfuscatedAccountId; @@ -262,17 +298,17 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(2); + ArrayList toListResult = new ArrayList<>(2); toListResult.add(obfuscatedAccountId); toListResult.add(obfuscatedProfileId); return toListResult; } - static @NonNull PlatformAccountIdentifiers fromList(@NonNull ArrayList list) { + static @NonNull PlatformAccountIdentifiers fromList(@NonNull ArrayList pigeonVar_list) { PlatformAccountIdentifiers pigeonResult = new PlatformAccountIdentifiers(); - Object obfuscatedAccountId = list.get(0); + Object obfuscatedAccountId = pigeonVar_list.get(0); pigeonResult.setObfuscatedAccountId((String) obfuscatedAccountId); - Object obfuscatedProfileId = list.get(1); + Object obfuscatedProfileId = pigeonVar_list.get(1); pigeonResult.setObfuscatedProfileId((String) obfuscatedProfileId); return pigeonResult; } @@ -313,6 +349,23 @@ public void setDebugMessage(@NonNull String setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ PlatformBillingResult() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformBillingResult that = (PlatformBillingResult) o; + return responseCode.equals(that.responseCode) && debugMessage.equals(that.debugMessage); + } + + @Override + public int hashCode() { + return Objects.hash(responseCode, debugMessage); + } + public static final class Builder { private @Nullable Long responseCode; @@ -341,20 +394,17 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(2); + ArrayList toListResult = new ArrayList<>(2); toListResult.add(responseCode); toListResult.add(debugMessage); return toListResult; } - static @NonNull PlatformBillingResult fromList(@NonNull ArrayList list) { + static @NonNull PlatformBillingResult fromList(@NonNull ArrayList pigeonVar_list) { PlatformBillingResult pigeonResult = new PlatformBillingResult(); - Object responseCode = list.get(0); - pigeonResult.setResponseCode( - (responseCode == null) - ? null - : ((responseCode instanceof Integer) ? (Integer) responseCode : (Long) responseCode)); - Object debugMessage = list.get(1); + Object responseCode = pigeonVar_list.get(0); + pigeonResult.setResponseCode((Long) responseCode); + Object debugMessage = pigeonVar_list.get(1); pigeonResult.setDebugMessage((String) debugMessage); return pigeonResult; } @@ -408,6 +458,25 @@ public void setPriceCurrencyCode(@NonNull String setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ PlatformOneTimePurchaseOfferDetails() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformOneTimePurchaseOfferDetails that = (PlatformOneTimePurchaseOfferDetails) o; + return priceAmountMicros.equals(that.priceAmountMicros) + && formattedPrice.equals(that.formattedPrice) + && priceCurrencyCode.equals(that.priceCurrencyCode); + } + + @Override + public int hashCode() { + return Objects.hash(priceAmountMicros, formattedPrice, priceCurrencyCode); + } + public static final class Builder { private @Nullable Long priceAmountMicros; @@ -446,25 +515,21 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(3); + ArrayList toListResult = new ArrayList<>(3); toListResult.add(priceAmountMicros); toListResult.add(formattedPrice); toListResult.add(priceCurrencyCode); return toListResult; } - static @NonNull PlatformOneTimePurchaseOfferDetails fromList(@NonNull ArrayList list) { + static @NonNull PlatformOneTimePurchaseOfferDetails fromList( + @NonNull ArrayList pigeonVar_list) { PlatformOneTimePurchaseOfferDetails pigeonResult = new PlatformOneTimePurchaseOfferDetails(); - Object priceAmountMicros = list.get(0); - pigeonResult.setPriceAmountMicros( - (priceAmountMicros == null) - ? null - : ((priceAmountMicros instanceof Integer) - ? (Integer) priceAmountMicros - : (Long) priceAmountMicros)); - Object formattedPrice = list.get(1); + Object priceAmountMicros = pigeonVar_list.get(0); + pigeonResult.setPriceAmountMicros((Long) priceAmountMicros); + Object formattedPrice = pigeonVar_list.get(1); pigeonResult.setFormattedPrice((String) formattedPrice); - Object priceCurrencyCode = list.get(2); + Object priceCurrencyCode = pigeonVar_list.get(2); pigeonResult.setPriceCurrencyCode((String) priceCurrencyCode); return pigeonResult; } @@ -566,6 +631,36 @@ public void setSubscriptionOfferDetails( /** Constructor is non-public to enforce null safety; use Builder. */ PlatformProductDetails() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformProductDetails that = (PlatformProductDetails) o; + return description.equals(that.description) + && name.equals(that.name) + && productId.equals(that.productId) + && productType.equals(that.productType) + && title.equals(that.title) + && Objects.equals(oneTimePurchaseOfferDetails, that.oneTimePurchaseOfferDetails) + && Objects.equals(subscriptionOfferDetails, that.subscriptionOfferDetails); + } + + @Override + public int hashCode() { + return Objects.hash( + description, + name, + productId, + productType, + title, + oneTimePurchaseOfferDetails, + subscriptionOfferDetails); + } + public static final class Builder { private @Nullable String description; @@ -641,37 +736,33 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(7); + ArrayList toListResult = new ArrayList<>(7); toListResult.add(description); toListResult.add(name); toListResult.add(productId); - toListResult.add(productType == null ? null : productType.index); + toListResult.add(productType); toListResult.add(title); - toListResult.add( - (oneTimePurchaseOfferDetails == null) ? null : oneTimePurchaseOfferDetails.toList()); + toListResult.add(oneTimePurchaseOfferDetails); toListResult.add(subscriptionOfferDetails); return toListResult; } - static @NonNull PlatformProductDetails fromList(@NonNull ArrayList list) { + static @NonNull PlatformProductDetails fromList(@NonNull ArrayList pigeonVar_list) { PlatformProductDetails pigeonResult = new PlatformProductDetails(); - Object description = list.get(0); + Object description = pigeonVar_list.get(0); pigeonResult.setDescription((String) description); - Object name = list.get(1); + Object name = pigeonVar_list.get(1); pigeonResult.setName((String) name); - Object productId = list.get(2); + Object productId = pigeonVar_list.get(2); pigeonResult.setProductId((String) productId); - Object productType = list.get(3); - pigeonResult.setProductType(PlatformProductType.values()[(int) productType]); - Object title = list.get(4); + Object productType = pigeonVar_list.get(3); + pigeonResult.setProductType((PlatformProductType) productType); + Object title = pigeonVar_list.get(4); pigeonResult.setTitle((String) title); - Object oneTimePurchaseOfferDetails = list.get(5); + Object oneTimePurchaseOfferDetails = pigeonVar_list.get(5); pigeonResult.setOneTimePurchaseOfferDetails( - (oneTimePurchaseOfferDetails == null) - ? null - : PlatformOneTimePurchaseOfferDetails.fromList( - (ArrayList) oneTimePurchaseOfferDetails)); - Object subscriptionOfferDetails = list.get(6); + (PlatformOneTimePurchaseOfferDetails) oneTimePurchaseOfferDetails); + Object subscriptionOfferDetails = pigeonVar_list.get(6); pigeonResult.setSubscriptionOfferDetails( (List) subscriptionOfferDetails); return pigeonResult; @@ -714,6 +805,23 @@ public void setProductDetails(@NonNull List setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ PlatformProductDetailsResponse() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformProductDetailsResponse that = (PlatformProductDetailsResponse) o; + return billingResult.equals(that.billingResult) && productDetails.equals(that.productDetails); + } + + @Override + public int hashCode() { + return Objects.hash(billingResult, productDetails); + } + public static final class Builder { private @Nullable PlatformBillingResult billingResult; @@ -742,20 +850,18 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(2); - toListResult.add((billingResult == null) ? null : billingResult.toList()); + ArrayList toListResult = new ArrayList<>(2); + toListResult.add(billingResult); toListResult.add(productDetails); return toListResult; } - static @NonNull PlatformProductDetailsResponse fromList(@NonNull ArrayList list) { + static @NonNull PlatformProductDetailsResponse fromList( + @NonNull ArrayList pigeonVar_list) { PlatformProductDetailsResponse pigeonResult = new PlatformProductDetailsResponse(); - Object billingResult = list.get(0); - pigeonResult.setBillingResult( - (billingResult == null) - ? null - : PlatformBillingResult.fromList((ArrayList) billingResult)); - Object productDetails = list.get(1); + Object billingResult = pigeonVar_list.get(0); + pigeonResult.setBillingResult((PlatformBillingResult) billingResult); + Object productDetails = pigeonVar_list.get(1); pigeonResult.setProductDetails((List) productDetails); return pigeonResult; } @@ -797,6 +903,25 @@ public void setExternalTransactionToken(@NonNull String setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ PlatformAlternativeBillingOnlyReportingDetailsResponse() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformAlternativeBillingOnlyReportingDetailsResponse that = + (PlatformAlternativeBillingOnlyReportingDetailsResponse) o; + return billingResult.equals(that.billingResult) + && externalTransactionToken.equals(that.externalTransactionToken); + } + + @Override + public int hashCode() { + return Objects.hash(billingResult, externalTransactionToken); + } + public static final class Builder { private @Nullable PlatformBillingResult billingResult; @@ -826,22 +951,19 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(2); - toListResult.add((billingResult == null) ? null : billingResult.toList()); + ArrayList toListResult = new ArrayList<>(2); + toListResult.add(billingResult); toListResult.add(externalTransactionToken); return toListResult; } static @NonNull PlatformAlternativeBillingOnlyReportingDetailsResponse fromList( - @NonNull ArrayList list) { + @NonNull ArrayList pigeonVar_list) { PlatformAlternativeBillingOnlyReportingDetailsResponse pigeonResult = new PlatformAlternativeBillingOnlyReportingDetailsResponse(); - Object billingResult = list.get(0); - pigeonResult.setBillingResult( - (billingResult == null) - ? null - : PlatformBillingResult.fromList((ArrayList) billingResult)); - Object externalTransactionToken = list.get(1); + Object billingResult = pigeonVar_list.get(0); + pigeonResult.setBillingResult((PlatformBillingResult) billingResult); + Object externalTransactionToken = pigeonVar_list.get(1); pigeonResult.setExternalTransactionToken((String) externalTransactionToken); return pigeonResult; } @@ -883,6 +1005,23 @@ public void setCountryCode(@NonNull String setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ PlatformBillingConfigResponse() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformBillingConfigResponse that = (PlatformBillingConfigResponse) o; + return billingResult.equals(that.billingResult) && countryCode.equals(that.countryCode); + } + + @Override + public int hashCode() { + return Objects.hash(billingResult, countryCode); + } + public static final class Builder { private @Nullable PlatformBillingResult billingResult; @@ -911,20 +1050,18 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(2); - toListResult.add((billingResult == null) ? null : billingResult.toList()); + ArrayList toListResult = new ArrayList<>(2); + toListResult.add(billingResult); toListResult.add(countryCode); return toListResult; } - static @NonNull PlatformBillingConfigResponse fromList(@NonNull ArrayList list) { + static @NonNull PlatformBillingConfigResponse fromList( + @NonNull ArrayList pigeonVar_list) { PlatformBillingConfigResponse pigeonResult = new PlatformBillingConfigResponse(); - Object billingResult = list.get(0); - pigeonResult.setBillingResult( - (billingResult == null) - ? null - : PlatformBillingResult.fromList((ArrayList) billingResult)); - Object countryCode = list.get(1); + Object billingResult = pigeonVar_list.get(0); + pigeonResult.setBillingResult((PlatformBillingResult) billingResult); + Object countryCode = pigeonVar_list.get(1); pigeonResult.setCountryCode((String) countryCode); return pigeonResult; } @@ -1028,6 +1165,38 @@ public void setPurchaseToken(@Nullable String setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ PlatformBillingFlowParams() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformBillingFlowParams that = (PlatformBillingFlowParams) o; + return product.equals(that.product) + && prorationMode.equals(that.prorationMode) + && replacementMode.equals(that.replacementMode) + && Objects.equals(offerToken, that.offerToken) + && Objects.equals(accountId, that.accountId) + && Objects.equals(obfuscatedProfileId, that.obfuscatedProfileId) + && Objects.equals(oldProduct, that.oldProduct) + && Objects.equals(purchaseToken, that.purchaseToken); + } + + @Override + public int hashCode() { + return Objects.hash( + product, + prorationMode, + replacementMode, + offerToken, + accountId, + obfuscatedProfileId, + oldProduct, + purchaseToken); + } + public static final class Builder { private @Nullable String product; @@ -1110,7 +1279,7 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(8); + ArrayList toListResult = new ArrayList<>(8); toListResult.add(product); toListResult.add(prorationMode); toListResult.add(replacementMode); @@ -1122,33 +1291,23 @@ ArrayList toList() { return toListResult; } - static @NonNull PlatformBillingFlowParams fromList(@NonNull ArrayList list) { + static @NonNull PlatformBillingFlowParams fromList(@NonNull ArrayList pigeonVar_list) { PlatformBillingFlowParams pigeonResult = new PlatformBillingFlowParams(); - Object product = list.get(0); + Object product = pigeonVar_list.get(0); pigeonResult.setProduct((String) product); - Object prorationMode = list.get(1); - pigeonResult.setProrationMode( - (prorationMode == null) - ? null - : ((prorationMode instanceof Integer) - ? (Integer) prorationMode - : (Long) prorationMode)); - Object replacementMode = list.get(2); - pigeonResult.setReplacementMode( - (replacementMode == null) - ? null - : ((replacementMode instanceof Integer) - ? (Integer) replacementMode - : (Long) replacementMode)); - Object offerToken = list.get(3); + Object prorationMode = pigeonVar_list.get(1); + pigeonResult.setProrationMode((Long) prorationMode); + Object replacementMode = pigeonVar_list.get(2); + pigeonResult.setReplacementMode((Long) replacementMode); + Object offerToken = pigeonVar_list.get(3); pigeonResult.setOfferToken((String) offerToken); - Object accountId = list.get(4); + Object accountId = pigeonVar_list.get(4); pigeonResult.setAccountId((String) accountId); - Object obfuscatedProfileId = list.get(5); + Object obfuscatedProfileId = pigeonVar_list.get(5); pigeonResult.setObfuscatedProfileId((String) obfuscatedProfileId); - Object oldProduct = list.get(6); + Object oldProduct = pigeonVar_list.get(6); pigeonResult.setOldProduct((String) oldProduct); - Object purchaseToken = list.get(7); + Object purchaseToken = pigeonVar_list.get(7); pigeonResult.setPurchaseToken((String) purchaseToken); return pigeonResult; } @@ -1241,6 +1400,34 @@ public void setPriceCurrencyCode(@NonNull String setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ PlatformPricingPhase() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformPricingPhase that = (PlatformPricingPhase) o; + return billingCycleCount.equals(that.billingCycleCount) + && recurrenceMode.equals(that.recurrenceMode) + && priceAmountMicros.equals(that.priceAmountMicros) + && billingPeriod.equals(that.billingPeriod) + && formattedPrice.equals(that.formattedPrice) + && priceCurrencyCode.equals(that.priceCurrencyCode); + } + + @Override + public int hashCode() { + return Objects.hash( + billingCycleCount, + recurrenceMode, + priceAmountMicros, + billingPeriod, + formattedPrice, + priceCurrencyCode); + } + public static final class Builder { private @Nullable Long billingCycleCount; @@ -1305,9 +1492,9 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(6); + ArrayList toListResult = new ArrayList<>(6); toListResult.add(billingCycleCount); - toListResult.add(recurrenceMode == null ? null : recurrenceMode.index); + toListResult.add(recurrenceMode); toListResult.add(priceAmountMicros); toListResult.add(billingPeriod); toListResult.add(formattedPrice); @@ -1315,29 +1502,19 @@ ArrayList toList() { return toListResult; } - static @NonNull PlatformPricingPhase fromList(@NonNull ArrayList list) { + static @NonNull PlatformPricingPhase fromList(@NonNull ArrayList pigeonVar_list) { PlatformPricingPhase pigeonResult = new PlatformPricingPhase(); - Object billingCycleCount = list.get(0); - pigeonResult.setBillingCycleCount( - (billingCycleCount == null) - ? null - : ((billingCycleCount instanceof Integer) - ? (Integer) billingCycleCount - : (Long) billingCycleCount)); - Object recurrenceMode = list.get(1); - pigeonResult.setRecurrenceMode(PlatformRecurrenceMode.values()[(int) recurrenceMode]); - Object priceAmountMicros = list.get(2); - pigeonResult.setPriceAmountMicros( - (priceAmountMicros == null) - ? null - : ((priceAmountMicros instanceof Integer) - ? (Integer) priceAmountMicros - : (Long) priceAmountMicros)); - Object billingPeriod = list.get(3); + Object billingCycleCount = pigeonVar_list.get(0); + pigeonResult.setBillingCycleCount((Long) billingCycleCount); + Object recurrenceMode = pigeonVar_list.get(1); + pigeonResult.setRecurrenceMode((PlatformRecurrenceMode) recurrenceMode); + Object priceAmountMicros = pigeonVar_list.get(2); + pigeonResult.setPriceAmountMicros((Long) priceAmountMicros); + Object billingPeriod = pigeonVar_list.get(3); pigeonResult.setBillingPeriod((String) billingPeriod); - Object formattedPrice = list.get(4); + Object formattedPrice = pigeonVar_list.get(4); pigeonResult.setFormattedPrice((String) formattedPrice); - Object priceCurrencyCode = list.get(5); + Object priceCurrencyCode = pigeonVar_list.get(5); pigeonResult.setPriceCurrencyCode((String) priceCurrencyCode); return pigeonResult; } @@ -1517,6 +1694,48 @@ public void setAccountIdentifiers(@Nullable PlatformAccountIdentifiers setterArg /** Constructor is non-public to enforce null safety; use Builder. */ PlatformPurchase() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformPurchase that = (PlatformPurchase) o; + return Objects.equals(orderId, that.orderId) + && packageName.equals(that.packageName) + && purchaseTime.equals(that.purchaseTime) + && purchaseToken.equals(that.purchaseToken) + && signature.equals(that.signature) + && products.equals(that.products) + && isAutoRenewing.equals(that.isAutoRenewing) + && originalJson.equals(that.originalJson) + && developerPayload.equals(that.developerPayload) + && isAcknowledged.equals(that.isAcknowledged) + && quantity.equals(that.quantity) + && purchaseState.equals(that.purchaseState) + && Objects.equals(accountIdentifiers, that.accountIdentifiers); + } + + @Override + public int hashCode() { + return Objects.hash( + orderId, + packageName, + purchaseTime, + purchaseToken, + signature, + products, + isAutoRenewing, + originalJson, + developerPayload, + isAcknowledged, + quantity, + purchaseState, + accountIdentifiers); + } + public static final class Builder { private @Nullable String orderId; @@ -1645,7 +1864,7 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(13); + ArrayList toListResult = new ArrayList<>(13); toListResult.add(orderId); toListResult.add(packageName); toListResult.add(purchaseTime); @@ -1657,48 +1876,39 @@ ArrayList toList() { toListResult.add(developerPayload); toListResult.add(isAcknowledged); toListResult.add(quantity); - toListResult.add(purchaseState == null ? null : purchaseState.index); - toListResult.add((accountIdentifiers == null) ? null : accountIdentifiers.toList()); + toListResult.add(purchaseState); + toListResult.add(accountIdentifiers); return toListResult; } - static @NonNull PlatformPurchase fromList(@NonNull ArrayList list) { + static @NonNull PlatformPurchase fromList(@NonNull ArrayList pigeonVar_list) { PlatformPurchase pigeonResult = new PlatformPurchase(); - Object orderId = list.get(0); + Object orderId = pigeonVar_list.get(0); pigeonResult.setOrderId((String) orderId); - Object packageName = list.get(1); + Object packageName = pigeonVar_list.get(1); pigeonResult.setPackageName((String) packageName); - Object purchaseTime = list.get(2); - pigeonResult.setPurchaseTime( - (purchaseTime == null) - ? null - : ((purchaseTime instanceof Integer) ? (Integer) purchaseTime : (Long) purchaseTime)); - Object purchaseToken = list.get(3); + Object purchaseTime = pigeonVar_list.get(2); + pigeonResult.setPurchaseTime((Long) purchaseTime); + Object purchaseToken = pigeonVar_list.get(3); pigeonResult.setPurchaseToken((String) purchaseToken); - Object signature = list.get(4); + Object signature = pigeonVar_list.get(4); pigeonResult.setSignature((String) signature); - Object products = list.get(5); + Object products = pigeonVar_list.get(5); pigeonResult.setProducts((List) products); - Object isAutoRenewing = list.get(6); + Object isAutoRenewing = pigeonVar_list.get(6); pigeonResult.setIsAutoRenewing((Boolean) isAutoRenewing); - Object originalJson = list.get(7); + Object originalJson = pigeonVar_list.get(7); pigeonResult.setOriginalJson((String) originalJson); - Object developerPayload = list.get(8); + Object developerPayload = pigeonVar_list.get(8); pigeonResult.setDeveloperPayload((String) developerPayload); - Object isAcknowledged = list.get(9); + Object isAcknowledged = pigeonVar_list.get(9); pigeonResult.setIsAcknowledged((Boolean) isAcknowledged); - Object quantity = list.get(10); - pigeonResult.setQuantity( - (quantity == null) - ? null - : ((quantity instanceof Integer) ? (Integer) quantity : (Long) quantity)); - Object purchaseState = list.get(11); - pigeonResult.setPurchaseState(PlatformPurchaseState.values()[(int) purchaseState]); - Object accountIdentifiers = list.get(12); - pigeonResult.setAccountIdentifiers( - (accountIdentifiers == null) - ? null - : PlatformAccountIdentifiers.fromList((ArrayList) accountIdentifiers)); + Object quantity = pigeonVar_list.get(10); + pigeonResult.setQuantity((Long) quantity); + Object purchaseState = pigeonVar_list.get(11); + pigeonResult.setPurchaseState((PlatformPurchaseState) purchaseState); + Object accountIdentifiers = pigeonVar_list.get(12); + pigeonResult.setAccountIdentifiers((PlatformAccountIdentifiers) accountIdentifiers); return pigeonResult; } } @@ -1802,6 +2012,36 @@ public void setProducts(@NonNull List setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ PlatformPurchaseHistoryRecord() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformPurchaseHistoryRecord that = (PlatformPurchaseHistoryRecord) o; + return quantity.equals(that.quantity) + && purchaseTime.equals(that.purchaseTime) + && Objects.equals(developerPayload, that.developerPayload) + && originalJson.equals(that.originalJson) + && purchaseToken.equals(that.purchaseToken) + && signature.equals(that.signature) + && products.equals(that.products); + } + + @Override + public int hashCode() { + return Objects.hash( + quantity, + purchaseTime, + developerPayload, + originalJson, + purchaseToken, + signature, + products); + } + public static final class Builder { private @Nullable Long quantity; @@ -1875,7 +2115,7 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(7); + ArrayList toListResult = new ArrayList<>(7); toListResult.add(quantity); toListResult.add(purchaseTime); toListResult.add(developerPayload); @@ -1886,27 +2126,22 @@ ArrayList toList() { return toListResult; } - static @NonNull PlatformPurchaseHistoryRecord fromList(@NonNull ArrayList list) { + static @NonNull PlatformPurchaseHistoryRecord fromList( + @NonNull ArrayList pigeonVar_list) { PlatformPurchaseHistoryRecord pigeonResult = new PlatformPurchaseHistoryRecord(); - Object quantity = list.get(0); - pigeonResult.setQuantity( - (quantity == null) - ? null - : ((quantity instanceof Integer) ? (Integer) quantity : (Long) quantity)); - Object purchaseTime = list.get(1); - pigeonResult.setPurchaseTime( - (purchaseTime == null) - ? null - : ((purchaseTime instanceof Integer) ? (Integer) purchaseTime : (Long) purchaseTime)); - Object developerPayload = list.get(2); + Object quantity = pigeonVar_list.get(0); + pigeonResult.setQuantity((Long) quantity); + Object purchaseTime = pigeonVar_list.get(1); + pigeonResult.setPurchaseTime((Long) purchaseTime); + Object developerPayload = pigeonVar_list.get(2); pigeonResult.setDeveloperPayload((String) developerPayload); - Object originalJson = list.get(3); + Object originalJson = pigeonVar_list.get(3); pigeonResult.setOriginalJson((String) originalJson); - Object purchaseToken = list.get(4); + Object purchaseToken = pigeonVar_list.get(4); pigeonResult.setPurchaseToken((String) purchaseToken); - Object signature = list.get(5); + Object signature = pigeonVar_list.get(5); pigeonResult.setSignature((String) signature); - Object products = list.get(6); + Object products = pigeonVar_list.get(6); pigeonResult.setProducts((List) products); return pigeonResult; } @@ -1948,6 +2183,23 @@ public void setPurchases(@NonNull List setterArg) /** Constructor is non-public to enforce null safety; use Builder. */ PlatformPurchaseHistoryResponse() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformPurchaseHistoryResponse that = (PlatformPurchaseHistoryResponse) o; + return billingResult.equals(that.billingResult) && purchases.equals(that.purchases); + } + + @Override + public int hashCode() { + return Objects.hash(billingResult, purchases); + } + public static final class Builder { private @Nullable PlatformBillingResult billingResult; @@ -1976,20 +2228,18 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(2); - toListResult.add((billingResult == null) ? null : billingResult.toList()); + ArrayList toListResult = new ArrayList<>(2); + toListResult.add(billingResult); toListResult.add(purchases); return toListResult; } - static @NonNull PlatformPurchaseHistoryResponse fromList(@NonNull ArrayList list) { + static @NonNull PlatformPurchaseHistoryResponse fromList( + @NonNull ArrayList pigeonVar_list) { PlatformPurchaseHistoryResponse pigeonResult = new PlatformPurchaseHistoryResponse(); - Object billingResult = list.get(0); - pigeonResult.setBillingResult( - (billingResult == null) - ? null - : PlatformBillingResult.fromList((ArrayList) billingResult)); - Object purchases = list.get(1); + Object billingResult = pigeonVar_list.get(0); + pigeonResult.setBillingResult((PlatformBillingResult) billingResult); + Object purchases = pigeonVar_list.get(1); pigeonResult.setPurchases((List) purchases); return pigeonResult; } @@ -2031,6 +2281,23 @@ public void setPurchases(@NonNull List setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ PlatformPurchasesResponse() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformPurchasesResponse that = (PlatformPurchasesResponse) o; + return billingResult.equals(that.billingResult) && purchases.equals(that.purchases); + } + + @Override + public int hashCode() { + return Objects.hash(billingResult, purchases); + } + public static final class Builder { private @Nullable PlatformBillingResult billingResult; @@ -2059,20 +2326,17 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(2); - toListResult.add((billingResult == null) ? null : billingResult.toList()); + ArrayList toListResult = new ArrayList<>(2); + toListResult.add(billingResult); toListResult.add(purchases); return toListResult; } - static @NonNull PlatformPurchasesResponse fromList(@NonNull ArrayList list) { + static @NonNull PlatformPurchasesResponse fromList(@NonNull ArrayList pigeonVar_list) { PlatformPurchasesResponse pigeonResult = new PlatformPurchasesResponse(); - Object billingResult = list.get(0); - pigeonResult.setBillingResult( - (billingResult == null) - ? null - : PlatformBillingResult.fromList((ArrayList) billingResult)); - Object purchases = list.get(1); + Object billingResult = pigeonVar_list.get(0); + pigeonResult.setBillingResult((PlatformBillingResult) billingResult); + Object purchases = pigeonVar_list.get(1); pigeonResult.setPurchases((List) purchases); return pigeonResult; } @@ -2149,6 +2413,27 @@ public void setPricingPhases(@NonNull List setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ PlatformSubscriptionOfferDetails() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformSubscriptionOfferDetails that = (PlatformSubscriptionOfferDetails) o; + return basePlanId.equals(that.basePlanId) + && Objects.equals(offerId, that.offerId) + && offerToken.equals(that.offerToken) + && offerTags.equals(that.offerTags) + && pricingPhases.equals(that.pricingPhases); + } + + @Override + public int hashCode() { + return Objects.hash(basePlanId, offerId, offerToken, offerTags, pricingPhases); + } + public static final class Builder { private @Nullable String basePlanId; @@ -2204,7 +2489,7 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(5); + ArrayList toListResult = new ArrayList<>(5); toListResult.add(basePlanId); toListResult.add(offerId); toListResult.add(offerToken); @@ -2213,17 +2498,18 @@ ArrayList toList() { return toListResult; } - static @NonNull PlatformSubscriptionOfferDetails fromList(@NonNull ArrayList list) { + static @NonNull PlatformSubscriptionOfferDetails fromList( + @NonNull ArrayList pigeonVar_list) { PlatformSubscriptionOfferDetails pigeonResult = new PlatformSubscriptionOfferDetails(); - Object basePlanId = list.get(0); + Object basePlanId = pigeonVar_list.get(0); pigeonResult.setBasePlanId((String) basePlanId); - Object offerId = list.get(1); + Object offerId = pigeonVar_list.get(1); pigeonResult.setOfferId((String) offerId); - Object offerToken = list.get(2); + Object offerToken = pigeonVar_list.get(2); pigeonResult.setOfferToken((String) offerToken); - Object offerTags = list.get(3); + Object offerTags = pigeonVar_list.get(3); pigeonResult.setOfferTags((List) offerTags); - Object pricingPhases = list.get(4); + Object pricingPhases = pigeonVar_list.get(4); pigeonResult.setPricingPhases((List) pricingPhases); return pigeonResult; } @@ -2274,6 +2560,25 @@ public void setProducts(@NonNull List setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ PlatformUserChoiceDetails() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformUserChoiceDetails that = (PlatformUserChoiceDetails) o; + return Objects.equals(originalExternalTransactionId, that.originalExternalTransactionId) + && externalTransactionToken.equals(that.externalTransactionToken) + && products.equals(that.products); + } + + @Override + public int hashCode() { + return Objects.hash(originalExternalTransactionId, externalTransactionToken, products); + } + public static final class Builder { private @Nullable String originalExternalTransactionId; @@ -2311,20 +2616,20 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(3); + ArrayList toListResult = new ArrayList<>(3); toListResult.add(originalExternalTransactionId); toListResult.add(externalTransactionToken); toListResult.add(products); return toListResult; } - static @NonNull PlatformUserChoiceDetails fromList(@NonNull ArrayList list) { + static @NonNull PlatformUserChoiceDetails fromList(@NonNull ArrayList pigeonVar_list) { PlatformUserChoiceDetails pigeonResult = new PlatformUserChoiceDetails(); - Object originalExternalTransactionId = list.get(0); + Object originalExternalTransactionId = pigeonVar_list.get(0); pigeonResult.setOriginalExternalTransactionId((String) originalExternalTransactionId); - Object externalTransactionToken = list.get(1); + Object externalTransactionToken = pigeonVar_list.get(1); pigeonResult.setExternalTransactionToken((String) externalTransactionToken); - Object products = list.get(2); + Object products = pigeonVar_list.get(2); pigeonResult.setProducts((List) products); return pigeonResult; } @@ -2375,6 +2680,25 @@ public void setType(@NonNull PlatformProductType setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ PlatformUserChoiceProduct() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformUserChoiceProduct that = (PlatformUserChoiceProduct) o; + return id.equals(that.id) + && Objects.equals(offerToken, that.offerToken) + && type.equals(that.type); + } + + @Override + public int hashCode() { + return Objects.hash(id, offerToken, type); + } + public static final class Builder { private @Nullable String id; @@ -2412,90 +2736,93 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(3); + ArrayList toListResult = new ArrayList<>(3); toListResult.add(id); toListResult.add(offerToken); - toListResult.add(type == null ? null : type.index); + toListResult.add(type); return toListResult; } - static @NonNull PlatformUserChoiceProduct fromList(@NonNull ArrayList list) { + static @NonNull PlatformUserChoiceProduct fromList(@NonNull ArrayList pigeonVar_list) { PlatformUserChoiceProduct pigeonResult = new PlatformUserChoiceProduct(); - Object id = list.get(0); + Object id = pigeonVar_list.get(0); pigeonResult.setId((String) id); - Object offerToken = list.get(1); + Object offerToken = pigeonVar_list.get(1); pigeonResult.setOfferToken((String) offerToken); - Object type = list.get(2); - pigeonResult.setType(PlatformProductType.values()[(int) type]); + Object type = pigeonVar_list.get(2); + pigeonResult.setType((PlatformProductType) type); return pigeonResult; } } - /** Asynchronous error handling return type for non-nullable API method returns. */ - public interface Result { - /** Success case callback method for handling returns. */ - void success(@NonNull T result); - - /** Failure case callback method for handling errors. */ - void error(@NonNull Throwable error); - } - /** Asynchronous error handling return type for nullable API method returns. */ - public interface NullableResult { - /** Success case callback method for handling returns. */ - void success(@Nullable T result); - - /** Failure case callback method for handling errors. */ - void error(@NonNull Throwable error); - } - /** Asynchronous error handling return type for void API method returns. */ - public interface VoidResult { - /** Success case callback method for handling returns. */ - void success(); - - /** Failure case callback method for handling errors. */ - void error(@NonNull Throwable error); - } - - private static class InAppPurchaseApiCodec extends StandardMessageCodec { - public static final InAppPurchaseApiCodec INSTANCE = new InAppPurchaseApiCodec(); + private static class PigeonCodec extends StandardMessageCodec { + public static final PigeonCodec INSTANCE = new PigeonCodec(); - private InAppPurchaseApiCodec() {} + private PigeonCodec() {} @Override protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { switch (type) { - case (byte) 128: - return PlatformAccountIdentifiers.fromList((ArrayList) readValue(buffer)); case (byte) 129: - return PlatformAlternativeBillingOnlyReportingDetailsResponse.fromList( - (ArrayList) readValue(buffer)); + { + Object value = readValue(buffer); + return value == null ? null : PlatformProductType.values()[((Long) value).intValue()]; + } case (byte) 130: - return PlatformBillingConfigResponse.fromList((ArrayList) readValue(buffer)); + { + Object value = readValue(buffer); + return value == null + ? null + : PlatformBillingChoiceMode.values()[((Long) value).intValue()]; + } case (byte) 131: - return PlatformBillingFlowParams.fromList((ArrayList) readValue(buffer)); + { + Object value = readValue(buffer); + return value == null ? null : PlatformPurchaseState.values()[((Long) value).intValue()]; + } case (byte) 132: - return PlatformBillingResult.fromList((ArrayList) readValue(buffer)); + { + Object value = readValue(buffer); + return value == null + ? null + : PlatformRecurrenceMode.values()[((Long) value).intValue()]; + } case (byte) 133: - return PlatformOneTimePurchaseOfferDetails.fromList( - (ArrayList) readValue(buffer)); + return PlatformQueryProduct.fromList((ArrayList) readValue(buffer)); case (byte) 134: - return PlatformPricingPhase.fromList((ArrayList) readValue(buffer)); + return PlatformAccountIdentifiers.fromList((ArrayList) readValue(buffer)); case (byte) 135: - return PlatformProductDetails.fromList((ArrayList) readValue(buffer)); + return PlatformBillingResult.fromList((ArrayList) readValue(buffer)); case (byte) 136: - return PlatformProductDetailsResponse.fromList((ArrayList) readValue(buffer)); + return PlatformOneTimePurchaseOfferDetails.fromList( + (ArrayList) readValue(buffer)); case (byte) 137: - return PlatformPurchase.fromList((ArrayList) readValue(buffer)); + return PlatformProductDetails.fromList((ArrayList) readValue(buffer)); case (byte) 138: - return PlatformPurchaseHistoryRecord.fromList((ArrayList) readValue(buffer)); + return PlatformProductDetailsResponse.fromList((ArrayList) readValue(buffer)); case (byte) 139: - return PlatformPurchaseHistoryResponse.fromList((ArrayList) readValue(buffer)); + return PlatformAlternativeBillingOnlyReportingDetailsResponse.fromList( + (ArrayList) readValue(buffer)); case (byte) 140: - return PlatformPurchasesResponse.fromList((ArrayList) readValue(buffer)); + return PlatformBillingConfigResponse.fromList((ArrayList) readValue(buffer)); case (byte) 141: - return PlatformQueryProduct.fromList((ArrayList) readValue(buffer)); + return PlatformBillingFlowParams.fromList((ArrayList) readValue(buffer)); case (byte) 142: + return PlatformPricingPhase.fromList((ArrayList) readValue(buffer)); + case (byte) 143: + return PlatformPurchase.fromList((ArrayList) readValue(buffer)); + case (byte) 144: + return PlatformPurchaseHistoryRecord.fromList((ArrayList) readValue(buffer)); + case (byte) 145: + return PlatformPurchaseHistoryResponse.fromList((ArrayList) readValue(buffer)); + case (byte) 146: + return PlatformPurchasesResponse.fromList((ArrayList) readValue(buffer)); + case (byte) 147: return PlatformSubscriptionOfferDetails.fromList((ArrayList) readValue(buffer)); + case (byte) 148: + return PlatformUserChoiceDetails.fromList((ArrayList) readValue(buffer)); + case (byte) 149: + return PlatformUserChoiceProduct.fromList((ArrayList) readValue(buffer)); default: return super.readValueOfType(type, buffer); } @@ -2503,58 +2830,100 @@ protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { @Override protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { - if (value instanceof PlatformAccountIdentifiers) { - stream.write(128); - writeValue(stream, ((PlatformAccountIdentifiers) value).toList()); - } else if (value instanceof PlatformAlternativeBillingOnlyReportingDetailsResponse) { + if (value instanceof PlatformProductType) { stream.write(129); - writeValue( - stream, ((PlatformAlternativeBillingOnlyReportingDetailsResponse) value).toList()); - } else if (value instanceof PlatformBillingConfigResponse) { + writeValue(stream, value == null ? null : ((PlatformProductType) value).index); + } else if (value instanceof PlatformBillingChoiceMode) { stream.write(130); - writeValue(stream, ((PlatformBillingConfigResponse) value).toList()); - } else if (value instanceof PlatformBillingFlowParams) { + writeValue(stream, value == null ? null : ((PlatformBillingChoiceMode) value).index); + } else if (value instanceof PlatformPurchaseState) { stream.write(131); - writeValue(stream, ((PlatformBillingFlowParams) value).toList()); - } else if (value instanceof PlatformBillingResult) { + writeValue(stream, value == null ? null : ((PlatformPurchaseState) value).index); + } else if (value instanceof PlatformRecurrenceMode) { stream.write(132); + writeValue(stream, value == null ? null : ((PlatformRecurrenceMode) value).index); + } else if (value instanceof PlatformQueryProduct) { + stream.write(133); + writeValue(stream, ((PlatformQueryProduct) value).toList()); + } else if (value instanceof PlatformAccountIdentifiers) { + stream.write(134); + writeValue(stream, ((PlatformAccountIdentifiers) value).toList()); + } else if (value instanceof PlatformBillingResult) { + stream.write(135); writeValue(stream, ((PlatformBillingResult) value).toList()); } else if (value instanceof PlatformOneTimePurchaseOfferDetails) { - stream.write(133); + stream.write(136); writeValue(stream, ((PlatformOneTimePurchaseOfferDetails) value).toList()); - } else if (value instanceof PlatformPricingPhase) { - stream.write(134); - writeValue(stream, ((PlatformPricingPhase) value).toList()); } else if (value instanceof PlatformProductDetails) { - stream.write(135); + stream.write(137); writeValue(stream, ((PlatformProductDetails) value).toList()); } else if (value instanceof PlatformProductDetailsResponse) { - stream.write(136); + stream.write(138); writeValue(stream, ((PlatformProductDetailsResponse) value).toList()); + } else if (value instanceof PlatformAlternativeBillingOnlyReportingDetailsResponse) { + stream.write(139); + writeValue( + stream, ((PlatformAlternativeBillingOnlyReportingDetailsResponse) value).toList()); + } else if (value instanceof PlatformBillingConfigResponse) { + stream.write(140); + writeValue(stream, ((PlatformBillingConfigResponse) value).toList()); + } else if (value instanceof PlatformBillingFlowParams) { + stream.write(141); + writeValue(stream, ((PlatformBillingFlowParams) value).toList()); + } else if (value instanceof PlatformPricingPhase) { + stream.write(142); + writeValue(stream, ((PlatformPricingPhase) value).toList()); } else if (value instanceof PlatformPurchase) { - stream.write(137); + stream.write(143); writeValue(stream, ((PlatformPurchase) value).toList()); } else if (value instanceof PlatformPurchaseHistoryRecord) { - stream.write(138); + stream.write(144); writeValue(stream, ((PlatformPurchaseHistoryRecord) value).toList()); } else if (value instanceof PlatformPurchaseHistoryResponse) { - stream.write(139); + stream.write(145); writeValue(stream, ((PlatformPurchaseHistoryResponse) value).toList()); } else if (value instanceof PlatformPurchasesResponse) { - stream.write(140); + stream.write(146); writeValue(stream, ((PlatformPurchasesResponse) value).toList()); - } else if (value instanceof PlatformQueryProduct) { - stream.write(141); - writeValue(stream, ((PlatformQueryProduct) value).toList()); } else if (value instanceof PlatformSubscriptionOfferDetails) { - stream.write(142); + stream.write(147); writeValue(stream, ((PlatformSubscriptionOfferDetails) value).toList()); + } else if (value instanceof PlatformUserChoiceDetails) { + stream.write(148); + writeValue(stream, ((PlatformUserChoiceDetails) value).toList()); + } else if (value instanceof PlatformUserChoiceProduct) { + stream.write(149); + writeValue(stream, ((PlatformUserChoiceProduct) value).toList()); } else { super.writeValue(stream, value); } } } + /** Asynchronous error handling return type for non-nullable API method returns. */ + public interface Result { + /** Success case callback method for handling returns. */ + void success(@NonNull T result); + + /** Failure case callback method for handling errors. */ + void error(@NonNull Throwable error); + } + /** Asynchronous error handling return type for nullable API method returns. */ + public interface NullableResult { + /** Success case callback method for handling returns. */ + void success(@Nullable T result); + + /** Failure case callback method for handling errors. */ + void error(@NonNull Throwable error); + } + /** Asynchronous error handling return type for void API method returns. */ + public interface VoidResult { + /** Success case callback method for handling returns. */ + void success(); + + /** Failure case callback method for handling errors. */ + void error(@NonNull Throwable error); + } /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ public interface InAppPurchaseApi { /** Wraps BillingClient#isReady. */ @@ -2617,28 +2986,36 @@ void createAlternativeBillingOnlyReportingDetailsAsync( /** The codec used by InAppPurchaseApi. */ static @NonNull MessageCodec getCodec() { - return InAppPurchaseApiCodec.INSTANCE; + return PigeonCodec.INSTANCE; } /** * Sets up an instance of `InAppPurchaseApi` to handle messages through the `binaryMessenger`. */ static void setUp(@NonNull BinaryMessenger binaryMessenger, @Nullable InAppPurchaseApi api) { + setUp(binaryMessenger, "", api); + } + + static void setUp( + @NonNull BinaryMessenger binaryMessenger, + @NonNull String messageChannelSuffix, + @Nullable InAppPurchaseApi api) { + messageChannelSuffix = messageChannelSuffix.isEmpty() ? "" : "." + messageChannelSuffix; { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.isReady", + "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.isReady" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { Boolean output = api.isReady(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2650,16 +3027,16 @@ static void setUp(@NonNull BinaryMessenger binaryMessenger, @Nullable InAppPurch BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.startConnection", + "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.startConnection" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Number callbackHandleArg = (Number) args.get(0); - PlatformBillingChoiceMode billingModeArg = - PlatformBillingChoiceMode.values()[(int) args.get(1)]; + Long callbackHandleArg = (Long) args.get(0); + PlatformBillingChoiceMode billingModeArg = (PlatformBillingChoiceMode) args.get(1); Result resultCallback = new Result() { public void success(PlatformBillingResult result) { @@ -2673,10 +3050,7 @@ public void error(Throwable error) { } }; - api.startConnection( - (callbackHandleArg == null) ? null : callbackHandleArg.longValue(), - billingModeArg, - resultCallback); + api.startConnection(callbackHandleArg, billingModeArg, resultCallback); }); } else { channel.setMessageHandler(null); @@ -2686,18 +3060,18 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.endConnection", + "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.endConnection" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { api.endConnection(); wrapped.add(0, null); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2709,12 +3083,13 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.getBillingConfigAsync", + "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.getBillingConfigAsync" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); Result resultCallback = new Result() { public void success(PlatformBillingConfigResponse result) { @@ -2738,20 +3113,20 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.launchBillingFlow", + "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.launchBillingFlow" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; PlatformBillingFlowParams paramsArg = (PlatformBillingFlowParams) args.get(0); try { PlatformBillingResult output = api.launchBillingFlow(paramsArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2763,12 +3138,13 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.acknowledgePurchase", + "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.acknowledgePurchase" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; String purchaseTokenArg = (String) args.get(0); Result resultCallback = @@ -2794,12 +3170,13 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.consumeAsync", + "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.consumeAsync" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; String purchaseTokenArg = (String) args.get(0); Result resultCallback = @@ -2825,15 +3202,15 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.queryPurchasesAsync", + "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.queryPurchasesAsync" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - PlatformProductType productTypeArg = - PlatformProductType.values()[(int) args.get(0)]; + PlatformProductType productTypeArg = (PlatformProductType) args.get(0); Result resultCallback = new Result() { public void success(PlatformPurchasesResponse result) { @@ -2857,15 +3234,15 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.queryPurchaseHistoryAsync", + "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.queryPurchaseHistoryAsync" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - PlatformProductType productTypeArg = - PlatformProductType.values()[(int) args.get(0)]; + PlatformProductType productTypeArg = (PlatformProductType) args.get(0); Result resultCallback = new Result() { public void success(PlatformPurchaseHistoryResponse result) { @@ -2889,12 +3266,13 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.queryProductDetailsAsync", + "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.queryProductDetailsAsync" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; List productsArg = (List) args.get(0); Result resultCallback = @@ -2920,20 +3298,20 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.isFeatureSupported", + "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.isFeatureSupported" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; String featureArg = (String) args.get(0); try { Boolean output = api.isFeatureSupported(featureArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2945,12 +3323,13 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.isAlternativeBillingOnlyAvailableAsync", + "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.isAlternativeBillingOnlyAvailableAsync" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); Result resultCallback = new Result() { public void success(PlatformBillingResult result) { @@ -2974,12 +3353,13 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.showAlternativeBillingOnlyInformationDialog", + "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.showAlternativeBillingOnlyInformationDialog" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); Result resultCallback = new Result() { public void success(PlatformBillingResult result) { @@ -3003,12 +3383,13 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.createAlternativeBillingOnlyReportingDetailsAsync", + "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.createAlternativeBillingOnlyReportingDetailsAsync" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); Result resultCallback = new Result() { public void success( @@ -3031,90 +3412,42 @@ public void error(Throwable error) { } } } - - private static class InAppPurchaseCallbackApiCodec extends StandardMessageCodec { - public static final InAppPurchaseCallbackApiCodec INSTANCE = - new InAppPurchaseCallbackApiCodec(); - - private InAppPurchaseCallbackApiCodec() {} - - @Override - protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { - switch (type) { - case (byte) 128: - return PlatformAccountIdentifiers.fromList((ArrayList) readValue(buffer)); - case (byte) 129: - return PlatformBillingResult.fromList((ArrayList) readValue(buffer)); - case (byte) 130: - return PlatformPurchase.fromList((ArrayList) readValue(buffer)); - case (byte) 131: - return PlatformPurchasesResponse.fromList((ArrayList) readValue(buffer)); - case (byte) 132: - return PlatformUserChoiceDetails.fromList((ArrayList) readValue(buffer)); - case (byte) 133: - return PlatformUserChoiceProduct.fromList((ArrayList) readValue(buffer)); - default: - return super.readValueOfType(type, buffer); - } - } - - @Override - protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { - if (value instanceof PlatformAccountIdentifiers) { - stream.write(128); - writeValue(stream, ((PlatformAccountIdentifiers) value).toList()); - } else if (value instanceof PlatformBillingResult) { - stream.write(129); - writeValue(stream, ((PlatformBillingResult) value).toList()); - } else if (value instanceof PlatformPurchase) { - stream.write(130); - writeValue(stream, ((PlatformPurchase) value).toList()); - } else if (value instanceof PlatformPurchasesResponse) { - stream.write(131); - writeValue(stream, ((PlatformPurchasesResponse) value).toList()); - } else if (value instanceof PlatformUserChoiceDetails) { - stream.write(132); - writeValue(stream, ((PlatformUserChoiceDetails) value).toList()); - } else if (value instanceof PlatformUserChoiceProduct) { - stream.write(133); - writeValue(stream, ((PlatformUserChoiceProduct) value).toList()); - } else { - super.writeValue(stream, value); - } - } - } - /** Generated class from Pigeon that represents Flutter messages that can be called from Java. */ public static class InAppPurchaseCallbackApi { private final @NonNull BinaryMessenger binaryMessenger; + private final String messageChannelSuffix; public InAppPurchaseCallbackApi(@NonNull BinaryMessenger argBinaryMessenger) { + this(argBinaryMessenger, ""); + } + + public InAppPurchaseCallbackApi( + @NonNull BinaryMessenger argBinaryMessenger, @NonNull String messageChannelSuffix) { this.binaryMessenger = argBinaryMessenger; + this.messageChannelSuffix = messageChannelSuffix.isEmpty() ? "" : "." + messageChannelSuffix; } - /** Public interface for sending reply. */ - /** The codec used by InAppPurchaseCallbackApi. */ + /** Public interface for sending reply. The codec used by InAppPurchaseCallbackApi. */ static @NonNull MessageCodec getCodec() { - return InAppPurchaseCallbackApiCodec.INSTANCE; + return PigeonCodec.INSTANCE; } /** Called for BillingClientStateListener#onBillingServiceDisconnected(). */ public void onBillingServiceDisconnected( @NonNull Long callbackHandleArg, @NonNull VoidResult result) { final String channelName = - "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseCallbackApi.onBillingServiceDisconnected"; + "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseCallbackApi.onBillingServiceDisconnected" + + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(callbackHandleArg)), + new ArrayList<>(Collections.singletonList(callbackHandleArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else { result.success(); } @@ -3127,20 +3460,19 @@ public void onBillingServiceDisconnected( public void onPurchasesUpdated( @NonNull PlatformPurchasesResponse updateArg, @NonNull VoidResult result) { final String channelName = - "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseCallbackApi.onPurchasesUpdated"; + "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseCallbackApi.onPurchasesUpdated" + + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(updateArg)), + new ArrayList<>(Collections.singletonList(updateArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else { result.success(); } @@ -3153,20 +3485,19 @@ public void onPurchasesUpdated( public void userSelectedalternativeBilling( @NonNull PlatformUserChoiceDetails detailsArg, @NonNull VoidResult result) { final String channelName = - "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseCallbackApi.userSelectedalternativeBilling"; + "dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseCallbackApi.userSelectedalternativeBilling" + + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(detailsArg)), + new ArrayList<>(Collections.singletonList(detailsArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else { result.success(); } diff --git a/packages/in_app_purchase/in_app_purchase_android/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/in_app_purchase/in_app_purchase_android/example/android/app/gradle/wrapper/gradle-wrapper.properties index 609ab8e6c8b5..d951fac2bf31 100644 --- a/packages/in_app_purchase/in_app_purchase_android/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ b/packages/in_app_purchase/in_app_purchase_android/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/packages/in_app_purchase/in_app_purchase_android/example/android/build.gradle b/packages/in_app_purchase/in_app_purchase_android/example/android/build.gradle index bde7e79aa948..bb2a63600c80 100644 --- a/packages/in_app_purchase/in_app_purchase_android/example/android/build.gradle +++ b/packages/in_app_purchase/in_app_purchase_android/example/android/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath 'com.android.tools.build:gradle:8.5.1' } } diff --git a/packages/in_app_purchase/in_app_purchase_android/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/in_app_purchase/in_app_purchase_android/example/android/gradle/wrapper/gradle-wrapper.properties index aeaff6f869f3..7aeeb11c6ee5 100644 --- a/packages/in_app_purchase/in_app_purchase_android/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/in_app_purchase/in_app_purchase_android/example/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/in_app_purchase/in_app_purchase_android/example/pubspec.yaml b/packages/in_app_purchase/in_app_purchase_android/example/pubspec.yaml index a22c81be11fc..31258d0f3ce5 100644 --- a/packages/in_app_purchase/in_app_purchase_android/example/pubspec.yaml +++ b/packages/in_app_purchase/in_app_purchase_android/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the in_app_purchase_android plugin. publish_to: none environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" dependencies: flutter: diff --git a/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/alternative_billing_only_reporting_details_wrapper.g.dart b/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/alternative_billing_only_reporting_details_wrapper.g.dart index 46b82645de0f..04578fb4a45b 100644 --- a/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/alternative_billing_only_reporting_details_wrapper.g.dart +++ b/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/alternative_billing_only_reporting_details_wrapper.g.dart @@ -10,7 +10,7 @@ AlternativeBillingOnlyReportingDetailsWrapper _$AlternativeBillingOnlyReportingDetailsWrapperFromJson(Map json) => AlternativeBillingOnlyReportingDetailsWrapper( responseCode: const BillingResponseConverter() - .fromJson(json['responseCode'] as int?), + .fromJson((json['responseCode'] as num?)?.toInt()), debugMessage: json['debugMessage'] as String? ?? '', externalTransactionToken: json['externalTransactionToken'] as String? ?? '', diff --git a/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/billing_client_wrapper.dart b/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/billing_client_wrapper.dart index 3f7bd499bbf1..1f46c3f1de20 100644 --- a/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/billing_client_wrapper.dart +++ b/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/billing_client_wrapper.dart @@ -64,7 +64,7 @@ class BillingClient { }) : _hostApi = api ?? InAppPurchaseApi(), hostCallbackHandler = HostBillingClientCallbackHandler( onPurchasesUpdated, alternativeBillingListener) { - InAppPurchaseCallbackApi.setup(hostCallbackHandler); + InAppPurchaseCallbackApi.setUp(hostCallbackHandler); } /// Interface for calling host-side code. diff --git a/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/billing_config_wrapper.g.dart b/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/billing_config_wrapper.g.dart index 21f98577d91e..fc8328aec176 100644 --- a/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/billing_config_wrapper.g.dart +++ b/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/billing_config_wrapper.g.dart @@ -9,7 +9,7 @@ part of 'billing_config_wrapper.dart'; BillingConfigWrapper _$BillingConfigWrapperFromJson(Map json) => BillingConfigWrapper( responseCode: const BillingResponseConverter() - .fromJson(json['responseCode'] as int?), + .fromJson((json['responseCode'] as num?)?.toInt()), debugMessage: json['debugMessage'] as String? ?? '', countryCode: json['countryCode'] as String? ?? '', ); diff --git a/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/billing_response_wrapper.g.dart b/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/billing_response_wrapper.g.dart index bff62ae85744..a3b28403983e 100644 --- a/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/billing_response_wrapper.g.dart +++ b/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/billing_response_wrapper.g.dart @@ -9,6 +9,6 @@ part of 'billing_response_wrapper.dart'; BillingResultWrapper _$BillingResultWrapperFromJson(Map json) => BillingResultWrapper( responseCode: const BillingResponseConverter() - .fromJson(json['responseCode'] as int?), + .fromJson((json['responseCode'] as num?)?.toInt()), debugMessage: json['debugMessage'] as String?, ); diff --git a/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/one_time_purchase_offer_details_wrapper.g.dart b/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/one_time_purchase_offer_details_wrapper.g.dart index 19e57e80157b..f26a38162fcd 100644 --- a/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/one_time_purchase_offer_details_wrapper.g.dart +++ b/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/one_time_purchase_offer_details_wrapper.g.dart @@ -10,6 +10,6 @@ OneTimePurchaseOfferDetailsWrapper _$OneTimePurchaseOfferDetailsWrapperFromJson( Map json) => OneTimePurchaseOfferDetailsWrapper( formattedPrice: json['formattedPrice'] as String? ?? '', - priceAmountMicros: json['priceAmountMicros'] as int? ?? 0, + priceAmountMicros: (json['priceAmountMicros'] as num?)?.toInt() ?? 0, priceCurrencyCode: json['priceCurrencyCode'] as String? ?? '', ); diff --git a/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/purchase_wrapper.g.dart b/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/purchase_wrapper.g.dart index 0270d610eb68..b97afce0f628 100644 --- a/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/purchase_wrapper.g.dart +++ b/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/purchase_wrapper.g.dart @@ -9,7 +9,7 @@ part of 'purchase_wrapper.dart'; PurchaseWrapper _$PurchaseWrapperFromJson(Map json) => PurchaseWrapper( orderId: json['orderId'] as String? ?? '', packageName: json['packageName'] as String? ?? '', - purchaseTime: json['purchaseTime'] as int? ?? 0, + purchaseTime: (json['purchaseTime'] as num?)?.toInt() ?? 0, purchaseToken: json['purchaseToken'] as String? ?? '', signature: json['signature'] as String? ?? '', products: (json['products'] as List?) @@ -21,14 +21,14 @@ PurchaseWrapper _$PurchaseWrapperFromJson(Map json) => PurchaseWrapper( developerPayload: json['developerPayload'] as String?, isAcknowledged: json['isAcknowledged'] as bool? ?? false, purchaseState: const PurchaseStateConverter() - .fromJson(json['purchaseState'] as int?), + .fromJson((json['purchaseState'] as num?)?.toInt()), obfuscatedAccountId: json['obfuscatedAccountId'] as String?, obfuscatedProfileId: json['obfuscatedProfileId'] as String?, ); PurchaseHistoryRecordWrapper _$PurchaseHistoryRecordWrapperFromJson(Map json) => PurchaseHistoryRecordWrapper( - purchaseTime: json['purchaseTime'] as int? ?? 0, + purchaseTime: (json['purchaseTime'] as num?)?.toInt() ?? 0, purchaseToken: json['purchaseToken'] as String? ?? '', signature: json['signature'] as String? ?? '', products: (json['products'] as List?) @@ -42,7 +42,7 @@ PurchaseHistoryRecordWrapper _$PurchaseHistoryRecordWrapperFromJson(Map json) => PurchasesResultWrapper _$PurchasesResultWrapperFromJson(Map json) => PurchasesResultWrapper( responseCode: const BillingResponseConverter() - .fromJson(json['responseCode'] as int?), + .fromJson((json['responseCode'] as num?)?.toInt()), billingResult: BillingResultWrapper.fromJson((json['billingResult'] as Map?)?.map( (k, e) => MapEntry(k as String, e), diff --git a/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/subscription_offer_details_wrapper.g.dart b/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/subscription_offer_details_wrapper.g.dart index eca645340fe5..46973ed7d427 100644 --- a/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/subscription_offer_details_wrapper.g.dart +++ b/packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/subscription_offer_details_wrapper.g.dart @@ -25,13 +25,13 @@ SubscriptionOfferDetailsWrapper _$SubscriptionOfferDetailsWrapperFromJson( PricingPhaseWrapper _$PricingPhaseWrapperFromJson(Map json) => PricingPhaseWrapper( - billingCycleCount: json['billingCycleCount'] as int? ?? 0, + billingCycleCount: (json['billingCycleCount'] as num?)?.toInt() ?? 0, billingPeriod: json['billingPeriod'] as String? ?? '', formattedPrice: json['formattedPrice'] as String? ?? '', - priceAmountMicros: json['priceAmountMicros'] as int? ?? 0, + priceAmountMicros: (json['priceAmountMicros'] as num?)?.toInt() ?? 0, priceCurrencyCode: json['priceCurrencyCode'] as String? ?? '', recurrenceMode: json['recurrenceMode'] == null ? RecurrenceMode.nonRecurring : const RecurrenceModeConverter() - .fromJson(json['recurrenceMode'] as int?), + .fromJson((json['recurrenceMode'] as num?)?.toInt()), ); diff --git a/packages/in_app_purchase/in_app_purchase_android/lib/src/messages.g.dart b/packages/in_app_purchase/in_app_purchase_android/lib/src/messages.g.dart index e6444b8d9b64..1e6cca2ccbd3 100644 --- a/packages/in_app_purchase/in_app_purchase_android/lib/src/messages.g.dart +++ b/packages/in_app_purchase/in_app_purchase_android/lib/src/messages.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 (v17.3.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.2), 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 @@ -77,7 +77,7 @@ class PlatformQueryProduct { Object encode() { return [ productId, - productType.index, + productType, ]; } @@ -85,7 +85,7 @@ class PlatformQueryProduct { result as List; return PlatformQueryProduct( productId: result[0]! as String, - productType: PlatformProductType.values[result[1]! as int], + productType: result[1]! as PlatformProductType, ); } } @@ -200,16 +200,16 @@ class PlatformProductDetails { PlatformOneTimePurchaseOfferDetails? oneTimePurchaseOfferDetails; - List? subscriptionOfferDetails; + List? subscriptionOfferDetails; Object encode() { return [ description, name, productId, - productType.index, + productType, title, - oneTimePurchaseOfferDetails?.encode(), + oneTimePurchaseOfferDetails, subscriptionOfferDetails, ]; } @@ -220,14 +220,12 @@ class PlatformProductDetails { description: result[0]! as String, name: result[1]! as String, productId: result[2]! as String, - productType: PlatformProductType.values[result[3]! as int], + productType: result[3]! as PlatformProductType, title: result[4]! as String, - oneTimePurchaseOfferDetails: result[5] != null - ? PlatformOneTimePurchaseOfferDetails.decode( - result[5]! as List) - : null, + oneTimePurchaseOfferDetails: + result[5] as PlatformOneTimePurchaseOfferDetails?, subscriptionOfferDetails: (result[6] as List?) - ?.cast(), + ?.cast(), ); } } @@ -242,11 +240,11 @@ class PlatformProductDetailsResponse { PlatformBillingResult billingResult; - List productDetails; + List productDetails; Object encode() { return [ - billingResult.encode(), + billingResult, productDetails, ]; } @@ -254,9 +252,9 @@ class PlatformProductDetailsResponse { static PlatformProductDetailsResponse decode(Object result) { result as List; return PlatformProductDetailsResponse( - billingResult: PlatformBillingResult.decode(result[0]! as List), + billingResult: result[0]! as PlatformBillingResult, productDetails: - (result[1] as List?)!.cast(), + (result[1] as List?)!.cast(), ); } } @@ -276,7 +274,7 @@ class PlatformAlternativeBillingOnlyReportingDetailsResponse { Object encode() { return [ - billingResult.encode(), + billingResult, externalTransactionToken, ]; } @@ -285,7 +283,7 @@ class PlatformAlternativeBillingOnlyReportingDetailsResponse { Object result) { result as List; return PlatformAlternativeBillingOnlyReportingDetailsResponse( - billingResult: PlatformBillingResult.decode(result[0]! as List), + billingResult: result[0]! as PlatformBillingResult, externalTransactionToken: result[1]! as String, ); } @@ -305,7 +303,7 @@ class PlatformBillingConfigResponse { Object encode() { return [ - billingResult.encode(), + billingResult, countryCode, ]; } @@ -313,7 +311,7 @@ class PlatformBillingConfigResponse { static PlatformBillingConfigResponse decode(Object result) { result as List; return PlatformBillingConfigResponse( - billingResult: PlatformBillingResult.decode(result[0]! as List), + billingResult: result[0]! as PlatformBillingResult, countryCode: result[1]! as String, ); } @@ -402,7 +400,7 @@ class PlatformPricingPhase { Object encode() { return [ billingCycleCount, - recurrenceMode.index, + recurrenceMode, priceAmountMicros, billingPeriod, formattedPrice, @@ -414,7 +412,7 @@ class PlatformPricingPhase { result as List; return PlatformPricingPhase( billingCycleCount: result[0]! as int, - recurrenceMode: PlatformRecurrenceMode.values[result[1]! as int], + recurrenceMode: result[1]! as PlatformRecurrenceMode, priceAmountMicros: result[2]! as int, billingPeriod: result[3]! as String, formattedPrice: result[4]! as String, @@ -453,7 +451,7 @@ class PlatformPurchase { String signature; - List products; + List products; bool isAutoRenewing; @@ -482,8 +480,8 @@ class PlatformPurchase { developerPayload, isAcknowledged, quantity, - purchaseState.index, - accountIdentifiers?.encode(), + purchaseState, + accountIdentifiers, ]; } @@ -495,16 +493,14 @@ class PlatformPurchase { purchaseTime: result[2]! as int, purchaseToken: result[3]! as String, signature: result[4]! as String, - products: (result[5] as List?)!.cast(), + products: (result[5] as List?)!.cast(), isAutoRenewing: result[6]! as bool, originalJson: result[7]! as String, developerPayload: result[8]! as String, isAcknowledged: result[9]! as bool, quantity: result[10]! as int, - purchaseState: PlatformPurchaseState.values[result[11]! as int], - accountIdentifiers: result[12] != null - ? PlatformAccountIdentifiers.decode(result[12]! as List) - : null, + purchaseState: result[11]! as PlatformPurchaseState, + accountIdentifiers: result[12] as PlatformAccountIdentifiers?, ); } } @@ -535,7 +531,7 @@ class PlatformPurchaseHistoryRecord { String signature; - List products; + List products; Object encode() { return [ @@ -558,7 +554,7 @@ class PlatformPurchaseHistoryRecord { originalJson: result[3]! as String, purchaseToken: result[4]! as String, signature: result[5]! as String, - products: (result[6] as List?)!.cast(), + products: (result[6] as List?)!.cast(), ); } } @@ -573,11 +569,11 @@ class PlatformPurchaseHistoryResponse { PlatformBillingResult billingResult; - List purchases; + List purchases; Object encode() { return [ - billingResult.encode(), + billingResult, purchases, ]; } @@ -585,9 +581,9 @@ class PlatformPurchaseHistoryResponse { static PlatformPurchaseHistoryResponse decode(Object result) { result as List; return PlatformPurchaseHistoryResponse( - billingResult: PlatformBillingResult.decode(result[0]! as List), + billingResult: result[0]! as PlatformBillingResult, purchases: - (result[1] as List?)!.cast(), + (result[1] as List?)!.cast(), ); } } @@ -602,11 +598,11 @@ class PlatformPurchasesResponse { PlatformBillingResult billingResult; - List purchases; + List purchases; Object encode() { return [ - billingResult.encode(), + billingResult, purchases, ]; } @@ -614,8 +610,8 @@ class PlatformPurchasesResponse { static PlatformPurchasesResponse decode(Object result) { result as List; return PlatformPurchasesResponse( - billingResult: PlatformBillingResult.decode(result[0]! as List), - purchases: (result[1] as List?)!.cast(), + billingResult: result[0]! as PlatformBillingResult, + purchases: (result[1] as List?)!.cast(), ); } } @@ -636,9 +632,9 @@ class PlatformSubscriptionOfferDetails { String offerToken; - List offerTags; + List offerTags; - List pricingPhases; + List pricingPhases; Object encode() { return [ @@ -656,9 +652,9 @@ class PlatformSubscriptionOfferDetails { basePlanId: result[0]! as String, offerId: result[1] as String?, offerToken: result[2]! as String, - offerTags: (result[3] as List?)!.cast(), + offerTags: (result[3] as List?)!.cast(), pricingPhases: - (result[4] as List?)!.cast(), + (result[4] as List?)!.cast(), ); } } @@ -675,7 +671,7 @@ class PlatformUserChoiceDetails { String externalTransactionToken; - List products; + List products; Object encode() { return [ @@ -691,7 +687,7 @@ class PlatformUserChoiceDetails { originalExternalTransactionId: result[0] as String?, externalTransactionToken: result[1]! as String, products: - (result[2] as List?)!.cast(), + (result[2] as List?)!.cast(), ); } } @@ -714,7 +710,7 @@ class PlatformUserChoiceProduct { return [ id, offerToken, - type.index, + type, ]; } @@ -723,61 +719,82 @@ class PlatformUserChoiceProduct { return PlatformUserChoiceProduct( id: result[0]! as String, offerToken: result[1] as String?, - type: PlatformProductType.values[result[2]! as int], + type: result[2]! as PlatformProductType, ); } } -class _InAppPurchaseApiCodec extends StandardMessageCodec { - const _InAppPurchaseApiCodec(); +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is PlatformAccountIdentifiers) { - buffer.putUint8(128); - writeValue(buffer, value.encode()); - } else if (value - is PlatformAlternativeBillingOnlyReportingDetailsResponse) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is PlatformProductType) { buffer.putUint8(129); - writeValue(buffer, value.encode()); - } else if (value is PlatformBillingConfigResponse) { + writeValue(buffer, value.index); + } else if (value is PlatformBillingChoiceMode) { buffer.putUint8(130); - writeValue(buffer, value.encode()); - } else if (value is PlatformBillingFlowParams) { + writeValue(buffer, value.index); + } else if (value is PlatformPurchaseState) { buffer.putUint8(131); - writeValue(buffer, value.encode()); - } else if (value is PlatformBillingResult) { + writeValue(buffer, value.index); + } else if (value is PlatformRecurrenceMode) { buffer.putUint8(132); - writeValue(buffer, value.encode()); - } else if (value is PlatformOneTimePurchaseOfferDetails) { + writeValue(buffer, value.index); + } else if (value is PlatformQueryProduct) { buffer.putUint8(133); writeValue(buffer, value.encode()); - } else if (value is PlatformPricingPhase) { + } else if (value is PlatformAccountIdentifiers) { buffer.putUint8(134); writeValue(buffer, value.encode()); - } else if (value is PlatformProductDetails) { + } else if (value is PlatformBillingResult) { buffer.putUint8(135); writeValue(buffer, value.encode()); - } else if (value is PlatformProductDetailsResponse) { + } else if (value is PlatformOneTimePurchaseOfferDetails) { buffer.putUint8(136); writeValue(buffer, value.encode()); - } else if (value is PlatformPurchase) { + } else if (value is PlatformProductDetails) { buffer.putUint8(137); writeValue(buffer, value.encode()); - } else if (value is PlatformPurchaseHistoryRecord) { + } else if (value is PlatformProductDetailsResponse) { buffer.putUint8(138); writeValue(buffer, value.encode()); - } else if (value is PlatformPurchaseHistoryResponse) { + } else if (value + is PlatformAlternativeBillingOnlyReportingDetailsResponse) { buffer.putUint8(139); writeValue(buffer, value.encode()); - } else if (value is PlatformPurchasesResponse) { + } else if (value is PlatformBillingConfigResponse) { buffer.putUint8(140); writeValue(buffer, value.encode()); - } else if (value is PlatformQueryProduct) { + } else if (value is PlatformBillingFlowParams) { buffer.putUint8(141); writeValue(buffer, value.encode()); - } else if (value is PlatformSubscriptionOfferDetails) { + } else if (value is PlatformPricingPhase) { buffer.putUint8(142); writeValue(buffer, value.encode()); + } else if (value is PlatformPurchase) { + buffer.putUint8(143); + writeValue(buffer, value.encode()); + } else if (value is PlatformPurchaseHistoryRecord) { + buffer.putUint8(144); + writeValue(buffer, value.encode()); + } else if (value is PlatformPurchaseHistoryResponse) { + buffer.putUint8(145); + writeValue(buffer, value.encode()); + } else if (value is PlatformPurchasesResponse) { + buffer.putUint8(146); + writeValue(buffer, value.encode()); + } else if (value is PlatformSubscriptionOfferDetails) { + buffer.putUint8(147); + writeValue(buffer, value.encode()); + } else if (value is PlatformUserChoiceDetails) { + buffer.putUint8(148); + writeValue(buffer, value.encode()); + } else if (value is PlatformUserChoiceProduct) { + buffer.putUint8(149); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -786,37 +803,53 @@ class _InAppPurchaseApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: - return PlatformAccountIdentifiers.decode(readValue(buffer)!); case 129: - return PlatformAlternativeBillingOnlyReportingDetailsResponse.decode( - readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformProductType.values[value]; case 130: - return PlatformBillingConfigResponse.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformBillingChoiceMode.values[value]; case 131: - return PlatformBillingFlowParams.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformPurchaseState.values[value]; case 132: - return PlatformBillingResult.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformRecurrenceMode.values[value]; case 133: - return PlatformOneTimePurchaseOfferDetails.decode(readValue(buffer)!); + return PlatformQueryProduct.decode(readValue(buffer)!); case 134: - return PlatformPricingPhase.decode(readValue(buffer)!); + return PlatformAccountIdentifiers.decode(readValue(buffer)!); case 135: - return PlatformProductDetails.decode(readValue(buffer)!); + return PlatformBillingResult.decode(readValue(buffer)!); case 136: - return PlatformProductDetailsResponse.decode(readValue(buffer)!); + return PlatformOneTimePurchaseOfferDetails.decode(readValue(buffer)!); case 137: - return PlatformPurchase.decode(readValue(buffer)!); + return PlatformProductDetails.decode(readValue(buffer)!); case 138: - return PlatformPurchaseHistoryRecord.decode(readValue(buffer)!); + return PlatformProductDetailsResponse.decode(readValue(buffer)!); case 139: - return PlatformPurchaseHistoryResponse.decode(readValue(buffer)!); + return PlatformAlternativeBillingOnlyReportingDetailsResponse.decode( + readValue(buffer)!); case 140: - return PlatformPurchasesResponse.decode(readValue(buffer)!); + return PlatformBillingConfigResponse.decode(readValue(buffer)!); case 141: - return PlatformQueryProduct.decode(readValue(buffer)!); + return PlatformBillingFlowParams.decode(readValue(buffer)!); case 142: + return PlatformPricingPhase.decode(readValue(buffer)!); + case 143: + return PlatformPurchase.decode(readValue(buffer)!); + case 144: + return PlatformPurchaseHistoryRecord.decode(readValue(buffer)!); + case 145: + return PlatformPurchaseHistoryResponse.decode(readValue(buffer)!); + case 146: + return PlatformPurchasesResponse.decode(readValue(buffer)!); + case 147: return PlatformSubscriptionOfferDetails.decode(readValue(buffer)!); + case 148: + return PlatformUserChoiceDetails.decode(readValue(buffer)!); + case 149: + return PlatformUserChoiceProduct.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -827,93 +860,97 @@ class InAppPurchaseApi { /// Constructor for [InAppPurchaseApi]. 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. - InAppPurchaseApi({BinaryMessenger? binaryMessenger}) - : __pigeon_binaryMessenger = binaryMessenger; - final BinaryMessenger? __pigeon_binaryMessenger; + InAppPurchaseApi( + {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 = - _InAppPurchaseApiCodec(); + final String pigeonVar_messageChannelSuffix; /// Wraps BillingClient#isReady. Future isReady() async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.isReady'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.isReady$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } /// Wraps BillingClient#startConnection(BillingClientStateListener). Future startConnection( int callbackHandle, PlatformBillingChoiceMode billingMode) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.startConnection'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.startConnection$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([callbackHandle, billingMode.index]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([callbackHandle, billingMode]) 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 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 PlatformBillingResult?)!; + return (pigeonVar_replyList[0] as PlatformBillingResult?)!; } } /// Wraps BillingClient#endConnection(BillingClientStateListener). Future endConnection() async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.endConnection'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.endConnection$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; @@ -922,394 +959,345 @@ class InAppPurchaseApi { /// Wraps BillingClient#getBillingConfigAsync(GetBillingConfigParams, BillingConfigResponseListener). Future getBillingConfigAsync() async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.getBillingConfigAsync'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.getBillingConfigAsync$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 PlatformBillingConfigResponse?)!; + return (pigeonVar_replyList[0] as PlatformBillingConfigResponse?)!; } } /// Wraps BillingClient#launchBillingFlow(Activity, BillingFlowParams). Future launchBillingFlow( PlatformBillingFlowParams params) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.launchBillingFlow'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.launchBillingFlow$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([params]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([params]) 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 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 PlatformBillingResult?)!; + return (pigeonVar_replyList[0] as PlatformBillingResult?)!; } } /// Wraps BillingClient#acknowledgePurchase(AcknowledgePurchaseParams, AcknowledgePurchaseResponseListener). Future acknowledgePurchase( String purchaseToken) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.acknowledgePurchase'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.acknowledgePurchase$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([purchaseToken]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([purchaseToken]) 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 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 PlatformBillingResult?)!; + return (pigeonVar_replyList[0] as PlatformBillingResult?)!; } } /// Wraps BillingClient#consumeAsync(ConsumeParams, ConsumeResponseListener). Future consumeAsync(String purchaseToken) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.consumeAsync'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.consumeAsync$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([purchaseToken]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([purchaseToken]) 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 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 PlatformBillingResult?)!; + return (pigeonVar_replyList[0] as PlatformBillingResult?)!; } } /// Wraps BillingClient#queryPurchasesAsync(QueryPurchaseParams, PurchaseResponseListener). Future queryPurchasesAsync( PlatformProductType productType) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.queryPurchasesAsync'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.queryPurchasesAsync$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([productType.index]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([productType]) 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 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 PlatformPurchasesResponse?)!; + return (pigeonVar_replyList[0] as PlatformPurchasesResponse?)!; } } /// Wraps BillingClient#queryPurchaseHistoryAsync(QueryPurchaseHistoryParams, PurchaseHistoryResponseListener). Future queryPurchaseHistoryAsync( PlatformProductType productType) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.queryPurchaseHistoryAsync'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.queryPurchaseHistoryAsync$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([productType.index]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([productType]) 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 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 PlatformPurchaseHistoryResponse?)!; + return (pigeonVar_replyList[0] as PlatformPurchaseHistoryResponse?)!; } } /// Wraps BillingClient#queryProductDetailsAsync(QueryProductDetailsParams, ProductDetailsResponseListener). Future queryProductDetailsAsync( - List products) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.queryProductDetailsAsync'; - final BasicMessageChannel __pigeon_channel = + List products) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.queryProductDetailsAsync$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([products]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([products]) 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 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 PlatformProductDetailsResponse?)!; + return (pigeonVar_replyList[0] as PlatformProductDetailsResponse?)!; } } /// Wraps BillingClient#isFeatureSupported(String). Future isFeatureSupported(String feature) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.isFeatureSupported'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.isFeatureSupported$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([feature]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([feature]) 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 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 bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } /// Wraps BillingClient#isAlternativeBillingOnlyAvailableAsync(). Future isAlternativeBillingOnlyAvailableAsync() async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.isAlternativeBillingOnlyAvailableAsync'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.isAlternativeBillingOnlyAvailableAsync$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 PlatformBillingResult?)!; + return (pigeonVar_replyList[0] as PlatformBillingResult?)!; } } /// Wraps BillingClient#showAlternativeBillingOnlyInformationDialog(). Future showAlternativeBillingOnlyInformationDialog() async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.showAlternativeBillingOnlyInformationDialog'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.showAlternativeBillingOnlyInformationDialog$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 PlatformBillingResult?)!; + return (pigeonVar_replyList[0] as PlatformBillingResult?)!; } } /// Wraps BillingClient#createAlternativeBillingOnlyReportingDetailsAsync(AlternativeBillingOnlyReportingDetailsListener). Future createAlternativeBillingOnlyReportingDetailsAsync() async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.createAlternativeBillingOnlyReportingDetailsAsync'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseApi.createAlternativeBillingOnlyReportingDetailsAsync$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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] + return (pigeonVar_replyList[0] as PlatformAlternativeBillingOnlyReportingDetailsResponse?)!; } } } -class _InAppPurchaseCallbackApiCodec extends StandardMessageCodec { - const _InAppPurchaseCallbackApiCodec(); - @override - void writeValue(WriteBuffer buffer, Object? value) { - if (value is PlatformAccountIdentifiers) { - buffer.putUint8(128); - writeValue(buffer, value.encode()); - } else if (value is PlatformBillingResult) { - buffer.putUint8(129); - writeValue(buffer, value.encode()); - } else if (value is PlatformPurchase) { - buffer.putUint8(130); - writeValue(buffer, value.encode()); - } else if (value is PlatformPurchasesResponse) { - buffer.putUint8(131); - writeValue(buffer, value.encode()); - } else if (value is PlatformUserChoiceDetails) { - buffer.putUint8(132); - writeValue(buffer, value.encode()); - } else if (value is PlatformUserChoiceProduct) { - buffer.putUint8(133); - writeValue(buffer, value.encode()); - } else { - super.writeValue(buffer, value); - } - } - - @override - Object? readValueOfType(int type, ReadBuffer buffer) { - switch (type) { - case 128: - return PlatformAccountIdentifiers.decode(readValue(buffer)!); - case 129: - return PlatformBillingResult.decode(readValue(buffer)!); - case 130: - return PlatformPurchase.decode(readValue(buffer)!); - case 131: - return PlatformPurchasesResponse.decode(readValue(buffer)!); - case 132: - return PlatformUserChoiceDetails.decode(readValue(buffer)!); - case 133: - return PlatformUserChoiceProduct.decode(readValue(buffer)!); - default: - return super.readValueOfType(type, buffer); - } - } -} - abstract class InAppPurchaseCallbackApi { - static const MessageCodec pigeonChannelCodec = - _InAppPurchaseCallbackApiCodec(); + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); /// Called for BillingClientStateListener#onBillingServiceDisconnected(). void onBillingServiceDisconnected(int callbackHandle); @@ -1320,18 +1308,24 @@ abstract class InAppPurchaseCallbackApi { /// Called for UserChoiceBillingListener#userSelectedAlternativeBilling(UserChoiceDetails). void userSelectedalternativeBilling(PlatformUserChoiceDetails details); - static void setup(InAppPurchaseCallbackApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + InAppPurchaseCallbackApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseCallbackApi.onBillingServiceDisconnected', + 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseCallbackApi.onBillingServiceDisconnected$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseCallbackApi.onBillingServiceDisconnected was null.'); final List args = (message as List?)!; @@ -1351,15 +1345,16 @@ abstract class InAppPurchaseCallbackApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseCallbackApi.onPurchasesUpdated', + 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseCallbackApi.onPurchasesUpdated$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseCallbackApi.onPurchasesUpdated was null.'); final List args = (message as List?)!; @@ -1380,15 +1375,16 @@ abstract class InAppPurchaseCallbackApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseCallbackApi.userSelectedalternativeBilling', + 'dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseCallbackApi.userSelectedalternativeBilling$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.in_app_purchase_android.InAppPurchaseCallbackApi.userSelectedalternativeBilling was null.'); final List args = (message as List?)!; diff --git a/packages/in_app_purchase/in_app_purchase_android/lib/src/pigeon_converters.dart b/packages/in_app_purchase/in_app_purchase_android/lib/src/pigeon_converters.dart index 7fe8a3c92f21..bc93f614704f 100644 --- a/packages/in_app_purchase/in_app_purchase_android/lib/src/pigeon_converters.dart +++ b/packages/in_app_purchase/in_app_purchase_android/lib/src/pigeon_converters.dart @@ -32,8 +32,6 @@ ProductDetailsResponseWrapper productDetailsResponseWrapperFromPlatform( return ProductDetailsResponseWrapper( billingResult: resultWrapperFromPlatform(response.billingResult), productDetailsList: response.productDetails - // See TODOs in messages.dart for why casting away nullability is safe. - .map((PlatformProductDetails? p) => p!) .map(productDetailsWrapperFromPlatform) .toList()); } @@ -50,9 +48,7 @@ ProductDetailsWrapper productDetailsWrapperFromPlatform( oneTimePurchaseOfferDetails: oneTimePurchaseOfferDetailsWrapperFromPlatform( product.oneTimePurchaseOfferDetails), subscriptionOfferDetails: product.subscriptionOfferDetails - // See comment in messages.dart for why casting away nullability is safe. - ?.map((PlatformSubscriptionOfferDetails? o) => o!) - .map(subscriptionOfferDetailsWrapperFromPlatform) + ?.map(subscriptionOfferDetailsWrapperFromPlatform) .toList(), ); } @@ -77,8 +73,6 @@ PurchasesHistoryResult purchaseHistoryResultFromPlatform( return PurchasesHistoryResult( billingResult: resultWrapperFromPlatform(response.billingResult), purchaseHistoryRecordList: response.purchases - // See comment in messages.dart for why casting away nullability is safe. - .map((PlatformPurchaseHistoryRecord? r) => r!) .map(purchaseHistoryRecordWrapperFromPlatform) .toList(), ); @@ -91,8 +85,7 @@ PurchaseHistoryRecordWrapper purchaseHistoryRecordWrapperFromPlatform( purchaseTime: record.purchaseTime, purchaseToken: record.purchaseToken, signature: record.signature, - // See comment in messages.dart for why casting away nullability is safe. - products: record.products.map((String? s) => s!).toList(), + products: record.products, originalJson: record.originalJson, developerPayload: record.developerPayload, ); @@ -104,11 +97,7 @@ PurchasesResultWrapper purchasesResultWrapperFromPlatform( {bool forceOkResponseCode = false}) { return PurchasesResultWrapper( billingResult: resultWrapperFromPlatform(response.billingResult), - purchasesList: response.purchases - // See TODOs in messages.dart for why casting away nullability is safe. - .map((PlatformPurchase? p) => p!) - .map(purchaseWrapperFromPlatform) - .toList(), + purchasesList: response.purchases.map(purchaseWrapperFromPlatform).toList(), responseCode: forceOkResponseCode ? BillingResponse.ok : const BillingResponseConverter() @@ -185,8 +174,7 @@ PurchaseWrapper purchaseWrapperFromPlatform(PlatformPurchase purchase) { purchaseTime: purchase.purchaseTime, purchaseToken: purchase.purchaseToken, signature: purchase.signature, - // See comment in messages.dart for why casting away nullability is safe. - products: purchase.products.map((String? s) => s!).toList(), + products: purchase.products, isAutoRenewing: purchase.isAutoRenewing, originalJson: purchase.originalJson, isAcknowledged: purchase.isAcknowledged, @@ -223,14 +211,10 @@ SubscriptionOfferDetailsWrapper subscriptionOfferDetailsWrapperFromPlatform( return SubscriptionOfferDetailsWrapper( basePlanId: offer.basePlanId, offerId: offer.offerId, - // See comment in messages.dart for why casting away nullability is safe. - offerTags: offer.offerTags.map((String? s) => s!).toList(), + offerTags: offer.offerTags, offerIdToken: offer.offerToken, - pricingPhases: offer.pricingPhases - // See comment in messages.dart for why casting away nullability is safe. - .map((PlatformPricingPhase? p) => p!) - .map(pricingPhaseWrapperFromPlatform) - .toList(), + pricingPhases: + offer.pricingPhases.map(pricingPhaseWrapperFromPlatform).toList(), ); } @@ -240,11 +224,8 @@ UserChoiceDetailsWrapper userChoiceDetailsFromPlatform( return UserChoiceDetailsWrapper( originalExternalTransactionId: details.originalExternalTransactionId ?? '', externalTransactionToken: details.externalTransactionToken, - products: details.products - // See comment in messages.dart for why casting away nullability is safe. - .map((PlatformUserChoiceProduct? p) => p!) - .map(userChoiceDetailsProductFromPlatform) - .toList(), + products: + details.products.map(userChoiceDetailsProductFromPlatform).toList(), ); } diff --git a/packages/in_app_purchase/in_app_purchase_android/pigeons/messages.dart b/packages/in_app_purchase/in_app_purchase_android/pigeons/messages.dart index d0bbc51e973e..3c15cc4750a9 100644 --- a/packages/in_app_purchase/in_app_purchase_android/pigeons/messages.dart +++ b/packages/in_app_purchase/in_app_purchase_android/pigeons/messages.dart @@ -70,11 +70,7 @@ class PlatformProductDetails { final PlatformProductType productType; final String title; final PlatformOneTimePurchaseOfferDetails? oneTimePurchaseOfferDetails; - // TODO(stuartmorgan): Make the generic type non-nullable once supported. - // https://github.com/flutter/flutter/issues/97848 - // The consuming code treats it (the entries, not the list itself) as - // non-nullable. - final List? subscriptionOfferDetails; + final List? subscriptionOfferDetails; } /// Pigeon version of ProductDetailsResponseWrapper, which contains the @@ -86,10 +82,7 @@ class PlatformProductDetailsResponse { }); final PlatformBillingResult billingResult; - // TODO(stuartmorgan): Make the generic type non-nullable once supported. - // https://github.com/flutter/flutter/issues/97848 - // The consuming code treats it as non-nullable. - final List productDetails; + final List productDetails; } /// Pigeon version of AlternativeBillingOnlyReportingDetailsWrapper, which @@ -183,10 +176,7 @@ class PlatformPurchase { final int purchaseTime; final String purchaseToken; final String signature; - // TODO(stuartmorgan): Make the type non-nullable once supported. - // https://github.com/flutter/flutter/issues/97848 - // The consuming code treats it as non-nullable. - final List products; + final List products; final bool isAutoRenewing; final String originalJson; final String developerPayload; @@ -216,10 +206,7 @@ class PlatformPurchaseHistoryRecord { final String originalJson; final String purchaseToken; final String signature; - // TODO(stuartmorgan): Make the type non-nullable once supported. - // https://github.com/flutter/flutter/issues/97848 - // The consuming code treats it as non-nullable. - final List products; + final List products; } /// Pigeon version of PurchasesHistoryResult, which contains the components of @@ -231,10 +218,7 @@ class PlatformPurchaseHistoryResponse { }); final PlatformBillingResult billingResult; - // TODO(stuartmorgan): Make the type non-nullable once supported. - // https://github.com/flutter/flutter/issues/97848 - // The consuming code treats it as non-nullable. - final List purchases; + final List purchases; } /// Pigeon version of PurchasesResultWrapper, which contains the components of @@ -246,10 +230,7 @@ class PlatformPurchasesResponse { }); final PlatformBillingResult billingResult; - // TODO(stuartmorgan): Make the generic type non-nullable once supported. - // https://github.com/flutter/flutter/issues/97848 - // The consuming code treats it as non-nullable. - final List purchases; + final List purchases; } /// Pigeon version of Java ProductDetails.SubscriptionOfferDetails. @@ -265,18 +246,12 @@ class PlatformSubscriptionOfferDetails { final String basePlanId; final String? offerId; final String offerToken; - // TODO(stuartmorgan): Make the generic type non-nullable once supported. - // https://github.com/flutter/flutter/issues/97848 - // The consuming code treats it as non-nullable. - final List offerTags; + final List offerTags; // On the native side this is actually a class called PricingPhases, // which contains nothing but a List. Since this is an // internal API, we can always add that indirection later if we need it, // so for now this bypasses that unnecessary wrapper. - // TODO(stuartmorgan): Make the generic type non-nullable once supported. - // https://github.com/flutter/flutter/issues/97848 - // The consuming code treats it as non-nullable. - final List pricingPhases; + final List pricingPhases; } /// Pigeon version of UserChoiceDetailsWrapper and Java UserChoiceDetails. @@ -289,10 +264,7 @@ class PlatformUserChoiceDetails { final String? originalExternalTransactionId; final String externalTransactionToken; - // TODO(stuartmorgan): Make the generic type non-nullable once supported. - // https://github.com/flutter/flutter/issues/97848 - // The consuming code treats it as non-nullable. - final List products; + final List products; } /// Pigeon version of UserChoiseDetails.Product. diff --git a/packages/in_app_purchase/in_app_purchase_android/pubspec.yaml b/packages/in_app_purchase/in_app_purchase_android/pubspec.yaml index 29961fcfe4cb..dfd6878462d8 100644 --- a/packages/in_app_purchase/in_app_purchase_android/pubspec.yaml +++ b/packages/in_app_purchase/in_app_purchase_android/pubspec.yaml @@ -2,11 +2,11 @@ name: in_app_purchase_android description: An implementation for the Android platform of the Flutter `in_app_purchase` plugin. This uses the Android BillingClient APIs. repository: https://github.com/flutter/packages/tree/main/packages/in_app_purchase/in_app_purchase_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+in_app_purchase%22 -version: 0.3.6+1 +version: 0.3.6+11 environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" flutter: plugin: @@ -28,8 +28,8 @@ dev_dependencies: flutter_test: sdk: flutter json_serializable: ^6.3.1 - mockito: 5.4.4 - pigeon: ^17.1.1 + mockito: ^5.4.4 + pigeon: ^22.4.2 test: ^1.16.0 topics: diff --git a/packages/in_app_purchase/in_app_purchase_android/test/billing_client_wrappers/billing_client_wrapper_test.mocks.dart b/packages/in_app_purchase/in_app_purchase_android/test/billing_client_wrappers/billing_client_wrapper_test.mocks.dart index 1fd6c3382453..5a93a96f9754 100644 --- a/packages/in_app_purchase/in_app_purchase_android/test/billing_client_wrappers/billing_client_wrapper_test.mocks.dart +++ b/packages/in_app_purchase/in_app_purchase_android/test/billing_client_wrappers/billing_client_wrapper_test.mocks.dart @@ -3,10 +3,11 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i3; +import 'dart:async' as _i4; import 'package:in_app_purchase_android/src/messages.g.dart' as _i2; import 'package:mockito/mockito.dart' as _i1; +import 'package:mockito/src/dummies.dart' as _i3; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -93,17 +94,30 @@ class _FakePlatformAlternativeBillingOnlyReportingDetailsResponse_5 /// See the documentation for Mockito's code generation for more information. class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { @override - _i3.Future isReady() => (super.noSuchMethod( + String get pigeonVar_messageChannelSuffix => (super.noSuchMethod( + Invocation.getter(#pigeonVar_messageChannelSuffix), + returnValue: _i3.dummyValue( + this, + Invocation.getter(#pigeonVar_messageChannelSuffix), + ), + returnValueForMissingStub: _i3.dummyValue( + this, + Invocation.getter(#pigeonVar_messageChannelSuffix), + ), + ) as String); + + @override + _i4.Future isReady() => (super.noSuchMethod( Invocation.method( #isReady, [], ), - returnValue: _i3.Future.value(false), - returnValueForMissingStub: _i3.Future.value(false), - ) as _i3.Future); + returnValue: _i4.Future.value(false), + returnValueForMissingStub: _i4.Future.value(false), + ) as _i4.Future); @override - _i3.Future<_i2.PlatformBillingResult> startConnection( + _i4.Future<_i2.PlatformBillingResult> startConnection( int? callbackHandle, _i2.PlatformBillingChoiceMode? billingMode, ) => @@ -115,7 +129,7 @@ class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { billingMode, ], ), - returnValue: _i3.Future<_i2.PlatformBillingResult>.value( + returnValue: _i4.Future<_i2.PlatformBillingResult>.value( _FakePlatformBillingResult_0( this, Invocation.method( @@ -126,7 +140,7 @@ class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { ], ), )), - returnValueForMissingStub: _i3.Future<_i2.PlatformBillingResult>.value( + returnValueForMissingStub: _i4.Future<_i2.PlatformBillingResult>.value( _FakePlatformBillingResult_0( this, Invocation.method( @@ -137,26 +151,26 @@ class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { ], ), )), - ) as _i3.Future<_i2.PlatformBillingResult>); + ) as _i4.Future<_i2.PlatformBillingResult>); @override - _i3.Future endConnection() => (super.noSuchMethod( + _i4.Future endConnection() => (super.noSuchMethod( Invocation.method( #endConnection, [], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future<_i2.PlatformBillingConfigResponse> getBillingConfigAsync() => + _i4.Future<_i2.PlatformBillingConfigResponse> getBillingConfigAsync() => (super.noSuchMethod( Invocation.method( #getBillingConfigAsync, [], ), - returnValue: _i3.Future<_i2.PlatformBillingConfigResponse>.value( + returnValue: _i4.Future<_i2.PlatformBillingConfigResponse>.value( _FakePlatformBillingConfigResponse_1( this, Invocation.method( @@ -165,7 +179,7 @@ class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { ), )), returnValueForMissingStub: - _i3.Future<_i2.PlatformBillingConfigResponse>.value( + _i4.Future<_i2.PlatformBillingConfigResponse>.value( _FakePlatformBillingConfigResponse_1( this, Invocation.method( @@ -173,17 +187,17 @@ class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { [], ), )), - ) as _i3.Future<_i2.PlatformBillingConfigResponse>); + ) as _i4.Future<_i2.PlatformBillingConfigResponse>); @override - _i3.Future<_i2.PlatformBillingResult> launchBillingFlow( + _i4.Future<_i2.PlatformBillingResult> launchBillingFlow( _i2.PlatformBillingFlowParams? params) => (super.noSuchMethod( Invocation.method( #launchBillingFlow, [params], ), - returnValue: _i3.Future<_i2.PlatformBillingResult>.value( + returnValue: _i4.Future<_i2.PlatformBillingResult>.value( _FakePlatformBillingResult_0( this, Invocation.method( @@ -191,7 +205,7 @@ class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { [params], ), )), - returnValueForMissingStub: _i3.Future<_i2.PlatformBillingResult>.value( + returnValueForMissingStub: _i4.Future<_i2.PlatformBillingResult>.value( _FakePlatformBillingResult_0( this, Invocation.method( @@ -199,17 +213,17 @@ class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { [params], ), )), - ) as _i3.Future<_i2.PlatformBillingResult>); + ) as _i4.Future<_i2.PlatformBillingResult>); @override - _i3.Future<_i2.PlatformBillingResult> acknowledgePurchase( + _i4.Future<_i2.PlatformBillingResult> acknowledgePurchase( String? purchaseToken) => (super.noSuchMethod( Invocation.method( #acknowledgePurchase, [purchaseToken], ), - returnValue: _i3.Future<_i2.PlatformBillingResult>.value( + returnValue: _i4.Future<_i2.PlatformBillingResult>.value( _FakePlatformBillingResult_0( this, Invocation.method( @@ -217,7 +231,7 @@ class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { [purchaseToken], ), )), - returnValueForMissingStub: _i3.Future<_i2.PlatformBillingResult>.value( + returnValueForMissingStub: _i4.Future<_i2.PlatformBillingResult>.value( _FakePlatformBillingResult_0( this, Invocation.method( @@ -225,16 +239,16 @@ class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { [purchaseToken], ), )), - ) as _i3.Future<_i2.PlatformBillingResult>); + ) as _i4.Future<_i2.PlatformBillingResult>); @override - _i3.Future<_i2.PlatformBillingResult> consumeAsync(String? purchaseToken) => + _i4.Future<_i2.PlatformBillingResult> consumeAsync(String? purchaseToken) => (super.noSuchMethod( Invocation.method( #consumeAsync, [purchaseToken], ), - returnValue: _i3.Future<_i2.PlatformBillingResult>.value( + returnValue: _i4.Future<_i2.PlatformBillingResult>.value( _FakePlatformBillingResult_0( this, Invocation.method( @@ -242,7 +256,7 @@ class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { [purchaseToken], ), )), - returnValueForMissingStub: _i3.Future<_i2.PlatformBillingResult>.value( + returnValueForMissingStub: _i4.Future<_i2.PlatformBillingResult>.value( _FakePlatformBillingResult_0( this, Invocation.method( @@ -250,17 +264,17 @@ class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { [purchaseToken], ), )), - ) as _i3.Future<_i2.PlatformBillingResult>); + ) as _i4.Future<_i2.PlatformBillingResult>); @override - _i3.Future<_i2.PlatformPurchasesResponse> queryPurchasesAsync( + _i4.Future<_i2.PlatformPurchasesResponse> queryPurchasesAsync( _i2.PlatformProductType? productType) => (super.noSuchMethod( Invocation.method( #queryPurchasesAsync, [productType], ), - returnValue: _i3.Future<_i2.PlatformPurchasesResponse>.value( + returnValue: _i4.Future<_i2.PlatformPurchasesResponse>.value( _FakePlatformPurchasesResponse_2( this, Invocation.method( @@ -269,7 +283,7 @@ class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { ), )), returnValueForMissingStub: - _i3.Future<_i2.PlatformPurchasesResponse>.value( + _i4.Future<_i2.PlatformPurchasesResponse>.value( _FakePlatformPurchasesResponse_2( this, Invocation.method( @@ -277,17 +291,17 @@ class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { [productType], ), )), - ) as _i3.Future<_i2.PlatformPurchasesResponse>); + ) as _i4.Future<_i2.PlatformPurchasesResponse>); @override - _i3.Future<_i2.PlatformPurchaseHistoryResponse> queryPurchaseHistoryAsync( + _i4.Future<_i2.PlatformPurchaseHistoryResponse> queryPurchaseHistoryAsync( _i2.PlatformProductType? productType) => (super.noSuchMethod( Invocation.method( #queryPurchaseHistoryAsync, [productType], ), - returnValue: _i3.Future<_i2.PlatformPurchaseHistoryResponse>.value( + returnValue: _i4.Future<_i2.PlatformPurchaseHistoryResponse>.value( _FakePlatformPurchaseHistoryResponse_3( this, Invocation.method( @@ -296,7 +310,7 @@ class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { ), )), returnValueForMissingStub: - _i3.Future<_i2.PlatformPurchaseHistoryResponse>.value( + _i4.Future<_i2.PlatformPurchaseHistoryResponse>.value( _FakePlatformPurchaseHistoryResponse_3( this, Invocation.method( @@ -304,17 +318,17 @@ class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { [productType], ), )), - ) as _i3.Future<_i2.PlatformPurchaseHistoryResponse>); + ) as _i4.Future<_i2.PlatformPurchaseHistoryResponse>); @override - _i3.Future<_i2.PlatformProductDetailsResponse> queryProductDetailsAsync( - List<_i2.PlatformQueryProduct?>? products) => + _i4.Future<_i2.PlatformProductDetailsResponse> queryProductDetailsAsync( + List<_i2.PlatformQueryProduct>? products) => (super.noSuchMethod( Invocation.method( #queryProductDetailsAsync, [products], ), - returnValue: _i3.Future<_i2.PlatformProductDetailsResponse>.value( + returnValue: _i4.Future<_i2.PlatformProductDetailsResponse>.value( _FakePlatformProductDetailsResponse_4( this, Invocation.method( @@ -323,7 +337,7 @@ class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { ), )), returnValueForMissingStub: - _i3.Future<_i2.PlatformProductDetailsResponse>.value( + _i4.Future<_i2.PlatformProductDetailsResponse>.value( _FakePlatformProductDetailsResponse_4( this, Invocation.method( @@ -331,26 +345,26 @@ class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { [products], ), )), - ) as _i3.Future<_i2.PlatformProductDetailsResponse>); + ) as _i4.Future<_i2.PlatformProductDetailsResponse>); @override - _i3.Future isFeatureSupported(String? feature) => (super.noSuchMethod( + _i4.Future isFeatureSupported(String? feature) => (super.noSuchMethod( Invocation.method( #isFeatureSupported, [feature], ), - returnValue: _i3.Future.value(false), - returnValueForMissingStub: _i3.Future.value(false), - ) as _i3.Future); + returnValue: _i4.Future.value(false), + returnValueForMissingStub: _i4.Future.value(false), + ) as _i4.Future); @override - _i3.Future<_i2.PlatformBillingResult> + _i4.Future<_i2.PlatformBillingResult> isAlternativeBillingOnlyAvailableAsync() => (super.noSuchMethod( Invocation.method( #isAlternativeBillingOnlyAvailableAsync, [], ), - returnValue: _i3.Future<_i2.PlatformBillingResult>.value( + returnValue: _i4.Future<_i2.PlatformBillingResult>.value( _FakePlatformBillingResult_0( this, Invocation.method( @@ -359,7 +373,7 @@ class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { ), )), returnValueForMissingStub: - _i3.Future<_i2.PlatformBillingResult>.value( + _i4.Future<_i2.PlatformBillingResult>.value( _FakePlatformBillingResult_0( this, Invocation.method( @@ -367,16 +381,16 @@ class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { [], ), )), - ) as _i3.Future<_i2.PlatformBillingResult>); + ) as _i4.Future<_i2.PlatformBillingResult>); @override - _i3.Future<_i2.PlatformBillingResult> + _i4.Future<_i2.PlatformBillingResult> showAlternativeBillingOnlyInformationDialog() => (super.noSuchMethod( Invocation.method( #showAlternativeBillingOnlyInformationDialog, [], ), - returnValue: _i3.Future<_i2.PlatformBillingResult>.value( + returnValue: _i4.Future<_i2.PlatformBillingResult>.value( _FakePlatformBillingResult_0( this, Invocation.method( @@ -385,7 +399,7 @@ class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { ), )), returnValueForMissingStub: - _i3.Future<_i2.PlatformBillingResult>.value( + _i4.Future<_i2.PlatformBillingResult>.value( _FakePlatformBillingResult_0( this, Invocation.method( @@ -393,17 +407,17 @@ class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { [], ), )), - ) as _i3.Future<_i2.PlatformBillingResult>); + ) as _i4.Future<_i2.PlatformBillingResult>); @override - _i3.Future<_i2.PlatformAlternativeBillingOnlyReportingDetailsResponse> + _i4.Future<_i2.PlatformAlternativeBillingOnlyReportingDetailsResponse> createAlternativeBillingOnlyReportingDetailsAsync() => (super.noSuchMethod( Invocation.method( #createAlternativeBillingOnlyReportingDetailsAsync, [], ), - returnValue: _i3.Future< + returnValue: _i4.Future< _i2 .PlatformAlternativeBillingOnlyReportingDetailsResponse>.value( _FakePlatformAlternativeBillingOnlyReportingDetailsResponse_5( @@ -413,7 +427,7 @@ class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { [], ), )), - returnValueForMissingStub: _i3.Future< + returnValueForMissingStub: _i4.Future< _i2 .PlatformAlternativeBillingOnlyReportingDetailsResponse>.value( _FakePlatformAlternativeBillingOnlyReportingDetailsResponse_5( @@ -423,6 +437,6 @@ class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { [], ), )), - ) as _i3.Future< + ) as _i4.Future< _i2.PlatformAlternativeBillingOnlyReportingDetailsResponse>); } 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 05c0849f416b..d8fef6189343 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.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 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 41aa86446133..9de0b0133408 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: @@ -18,7 +18,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 topics: - in-app-purchase 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 18072ee2a3ee..aeb236752ec8 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,36 @@ +## 0.3.18+4 + +* Adds StoreKit 2 support for restoring purchases. + +## 0.3.18+3 + +* Updates Pigeon for non-nullable collection type support. + +## 0.3.18+2 + +* Adds support for StoreKit2's `purchase` and `transactions` + +## 0.3.18+1 + +* Adds support for StoreKit2's `canMakePayments` and `products` + +## 0.3.18 + +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Changes the `localizedDescription` field of `SKProductMessage` to allow for null values + +## 0.3.17+3 + +* Converts TranslatorTests to swift. + +## 0.3.17+2 + +* Converts FIAPPaymentQueueDeleteTests to swift. + +## 0.3.17+1 + +* Converts main plugin tests to swift. + ## 0.3.17 * Removes OCMock from tests. @@ -28,7 +61,7 @@ ## 0.3.12 -* Converts `refreshReceipt()`, `startObservingPaymentQueue()`, `stopObservingPaymentQueue()`, +* Converts `refreshReceipt()`, `startObservingPaymentQueue()`, `stopObservingPaymentQueue()`, `registerPaymentQueueDelegate()`, `removePaymentQueueDelegate()`, `showPriceConsentIfNeeded()` to pigeon. ## 0.3.11 @@ -55,7 +88,7 @@ ## 0.3.7 -* Adds `Future storefront()` in SKPaymentQueueWrapper class. +* Adds `Future storefront()` in SKPaymentQueueWrapper class. ## 0.3.6+7 diff --git a/packages/in_app_purchase/in_app_purchase_storekit/README.md b/packages/in_app_purchase/in_app_purchase_storekit/README.md index 779d81fc3cf6..3c7b5fac08d5 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/README.md +++ b/packages/in_app_purchase/in_app_purchase_storekit/README.md @@ -27,5 +27,5 @@ If you would like to contribute to the plugin, check out our [1]: ../in_app_purchase -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin [3]: https://pub.dev/packages/in_app_purchase_storekit/install diff --git a/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/FIAObjectTranslator.h b/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/FIAObjectTranslator.h index ffb0f1fe9588..bca07a586535 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/FIAObjectTranslator.h +++ b/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/FIAObjectTranslator.h @@ -57,33 +57,33 @@ NS_ASSUME_NONNULL_BEGIN withError:(NSString *_Nullable *_Nullable)error API_AVAILABLE(ios(12.2)); -+ (nullable SKPaymentTransactionMessage *)convertTransactionToPigeon: ++ (nullable FIASKPaymentTransactionMessage *)convertTransactionToPigeon: (nullable SKPaymentTransaction *)transaction; -+ (nullable SKStorefrontMessage *)convertStorefrontToPigeon:(nullable SKStorefront *)storefront ++ (nullable FIASKStorefrontMessage *)convertStorefrontToPigeon:(nullable SKStorefront *)storefront API_AVAILABLE(ios(13.0)); -+ (nullable SKPaymentDiscountMessage *)convertPaymentDiscountToPigeon: ++ (nullable FIASKPaymentDiscountMessage *)convertPaymentDiscountToPigeon: (nullable SKPaymentDiscount *)discount API_AVAILABLE(ios(12.2)); -+ (nullable SKPaymentMessage *)convertPaymentToPigeon:(nullable SKPayment *)payment ++ (nullable FIASKPaymentMessage *)convertPaymentToPigeon:(nullable SKPayment *)payment API_AVAILABLE(ios(12.2)); -+ (nullable SKErrorMessage *)convertSKErrorToPigeon:(nullable NSError *)error; ++ (nullable FIASKErrorMessage *)convertSKErrorToPigeon:(nullable NSError *)error; -+ (nullable SKProductsResponseMessage *)convertProductsResponseToPigeon: ++ (nullable FIASKProductsResponseMessage *)convertProductsResponseToPigeon: (nullable SKProductsResponse *)payment; -+ (nullable SKProductMessage *)convertProductToPigeon:(nullable SKProduct *)product ++ (nullable FIASKProductMessage *)convertProductToPigeon:(nullable SKProduct *)product API_AVAILABLE(ios(12.2)); -+ (nullable SKProductDiscountMessage *)convertProductDiscountToPigeon: ++ (nullable FIASKProductDiscountMessage *)convertProductDiscountToPigeon: (nullable SKProductDiscount *)productDiscount API_AVAILABLE(ios(12.2)); -+ (nullable SKPriceLocaleMessage *)convertNSLocaleToPigeon:(nullable NSLocale *)locale ++ (nullable FIASKPriceLocaleMessage *)convertNSLocaleToPigeon:(nullable NSLocale *)locale API_AVAILABLE(ios(12.2)); -+ (nullable SKProductSubscriptionPeriodMessage *)convertSKProductSubscriptionPeriodToPigeon: ++ (nullable FIASKProductSubscriptionPeriodMessage *)convertSKProductSubscriptionPeriodToPigeon: (nullable SKProductSubscriptionPeriod *)period API_AVAILABLE(ios(12.2)); @end diff --git a/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/FIAObjectTranslator.m b/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/FIAObjectTranslator.m index b9509eb4bee9..04f9817250b5 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/FIAObjectTranslator.m +++ b/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/FIAObjectTranslator.m @@ -118,11 +118,9 @@ + (NSDictionary *)getMapFromNSLocale:(NSLocale *)locale { return nil; } NSMutableDictionary *map = [[NSMutableDictionary alloc] init]; - [map setObject:[locale objectForKey:NSLocaleCurrencySymbol] ?: [NSNull null] - forKey:@"currencySymbol"]; - [map setObject:[locale objectForKey:NSLocaleCurrencyCode] ?: [NSNull null] - forKey:@"currencyCode"]; - [map setObject:[locale objectForKey:NSLocaleCountryCode] ?: [NSNull null] forKey:@"countryCode"]; + [map setObject:locale.currencySymbol ?: [NSNull null] forKey:@"currencySymbol"]; + [map setObject:locale.currencyCode ?: [NSNull null] forKey:@"currencyCode"]; + [map setObject:locale.countryCode ?: [NSNull null] forKey:@"countryCode"]; return map; } @@ -293,12 +291,12 @@ + (SKPaymentDiscount *)getSKPaymentDiscountFromMap:(NSDictionary *)map return discount; } -+ (nullable SKPaymentTransactionMessage *)convertTransactionToPigeon: ++ (nullable FIASKPaymentTransactionMessage *)convertTransactionToPigeon: (nullable SKPaymentTransaction *)transaction API_AVAILABLE(ios(12.2)) { if (!transaction) { return nil; } - SKPaymentTransactionMessage *msg = [SKPaymentTransactionMessage + return [FIASKPaymentTransactionMessage makeWithPayment:[self convertPaymentToPigeon:transaction.payment] transactionState:[self convertTransactionStateToPigeon:transaction.transactionState] originalTransaction:transaction.originalTransaction @@ -308,10 +306,9 @@ + (nullable SKPaymentTransactionMessage *)convertTransactionToPigeon: timeIntervalSince1970]] transactionIdentifier:transaction.transactionIdentifier error:[self convertSKErrorToPigeon:transaction.error]]; - return msg; } -+ (nullable SKErrorMessage *)convertSKErrorToPigeon:(nullable NSError *)error { ++ (nullable FIASKErrorMessage *)convertSKErrorToPigeon:(nullable NSError *)error { if (!error) { return nil; } @@ -322,34 +319,31 @@ + (nullable SKErrorMessage *)convertSKErrorToPigeon:(nullable NSError *)error { userInfo[key] = [FIAObjectTranslator encodeNSErrorUserInfo:value]; } - SKErrorMessage *msg = [SKErrorMessage makeWithCode:error.code - domain:error.domain - userInfo:userInfo]; - return msg; + return [FIASKErrorMessage makeWithCode:error.code domain:error.domain userInfo:userInfo]; } -+ (SKPaymentTransactionStateMessage)convertTransactionStateToPigeon: ++ (FIASKPaymentTransactionStateMessage)convertTransactionStateToPigeon: (SKPaymentTransactionState)state { switch (state) { case SKPaymentTransactionStatePurchasing: - return SKPaymentTransactionStateMessagePurchasing; + return FIASKPaymentTransactionStateMessagePurchasing; case SKPaymentTransactionStatePurchased: - return SKPaymentTransactionStateMessagePurchased; + return FIASKPaymentTransactionStateMessagePurchased; case SKPaymentTransactionStateFailed: - return SKPaymentTransactionStateMessageFailed; + return FIASKPaymentTransactionStateMessageFailed; case SKPaymentTransactionStateRestored: - return SKPaymentTransactionStateMessageRestored; + return FIASKPaymentTransactionStateMessageRestored; case SKPaymentTransactionStateDeferred: - return SKPaymentTransactionStateMessageDeferred; + return FIASKPaymentTransactionStateMessageDeferred; } } -+ (nullable SKPaymentMessage *)convertPaymentToPigeon:(nullable SKPayment *)payment ++ (nullable FIASKPaymentMessage *)convertPaymentToPigeon:(nullable SKPayment *)payment API_AVAILABLE(ios(12.2)) { if (!payment) { return nil; } - SKPaymentMessage *msg = [SKPaymentMessage + return [FIASKPaymentMessage makeWithProductIdentifier:payment.productIdentifier applicationUsername:payment.applicationUsername requestData:[[NSString alloc] initWithData:payment.requestData @@ -357,92 +351,85 @@ + (nullable SKPaymentMessage *)convertPaymentToPigeon:(nullable SKPayment *)paym quantity:payment.quantity simulatesAskToBuyInSandbox:payment.simulatesAskToBuyInSandbox paymentDiscount:[self convertPaymentDiscountToPigeon:payment.paymentDiscount]]; - return msg; } -+ (nullable SKPaymentDiscountMessage *)convertPaymentDiscountToPigeon: ++ (nullable FIASKPaymentDiscountMessage *)convertPaymentDiscountToPigeon: (nullable SKPaymentDiscount *)discount API_AVAILABLE(ios(12.2)) { if (!discount) { return nil; } - SKPaymentDiscountMessage *msg = - [SKPaymentDiscountMessage makeWithIdentifier:discount.identifier - keyIdentifier:discount.keyIdentifier - nonce:[discount.nonce UUIDString] - signature:discount.signature - timestamp:[discount.timestamp intValue]]; - - return msg; + return [FIASKPaymentDiscountMessage makeWithIdentifier:discount.identifier + keyIdentifier:discount.keyIdentifier + nonce:[discount.nonce UUIDString] + signature:discount.signature + timestamp:[discount.timestamp intValue]]; } -+ (nullable SKStorefrontMessage *)convertStorefrontToPigeon:(nullable SKStorefront *)storefront ++ (nullable FIASKStorefrontMessage *)convertStorefrontToPigeon:(nullable SKStorefront *)storefront API_AVAILABLE(ios(13.0)) { if (!storefront) { return nil; } - SKStorefrontMessage *msg = [SKStorefrontMessage makeWithCountryCode:storefront.countryCode - identifier:storefront.identifier]; - return msg; + return [FIASKStorefrontMessage makeWithCountryCode:storefront.countryCode + identifier:storefront.identifier]; } -+ (nullable SKProductSubscriptionPeriodMessage *)convertSKProductSubscriptionPeriodToPigeon: ++ (nullable FIASKProductSubscriptionPeriodMessage *)convertSKProductSubscriptionPeriodToPigeon: (nullable SKProductSubscriptionPeriod *)period API_AVAILABLE(ios(12.2)) { if (!period) { return nil; } - SKSubscriptionPeriodUnitMessage unit; + FIASKSubscriptionPeriodUnitMessage unit; switch (period.unit) { case SKProductPeriodUnitDay: - unit = SKSubscriptionPeriodUnitMessageDay; + unit = FIASKSubscriptionPeriodUnitMessageDay; break; case SKProductPeriodUnitWeek: - unit = SKSubscriptionPeriodUnitMessageWeek; + unit = FIASKSubscriptionPeriodUnitMessageWeek; break; case SKProductPeriodUnitMonth: - unit = SKSubscriptionPeriodUnitMessageMonth; + unit = FIASKSubscriptionPeriodUnitMessageMonth; break; case SKProductPeriodUnitYear: - unit = SKSubscriptionPeriodUnitMessageYear; + unit = FIASKSubscriptionPeriodUnitMessageYear; break; } - SKProductSubscriptionPeriodMessage *msg = - [SKProductSubscriptionPeriodMessage makeWithNumberOfUnits:period.numberOfUnits unit:unit]; - - return msg; + return [FIASKProductSubscriptionPeriodMessage makeWithNumberOfUnits:period.numberOfUnits + unit:unit]; } -+ (nullable SKProductDiscountMessage *)convertProductDiscountToPigeon: ++ (nullable FIASKProductDiscountMessage *)convertProductDiscountToPigeon: (nullable SKProductDiscount *)productDiscount API_AVAILABLE(ios(12.2)) { if (!productDiscount) { return nil; } - SKProductDiscountPaymentModeMessage paymentMode; + FIASKProductDiscountPaymentModeMessage paymentMode; switch (productDiscount.paymentMode) { case SKProductDiscountPaymentModeFreeTrial: - paymentMode = SKProductDiscountPaymentModeMessageFreeTrial; + paymentMode = FIASKProductDiscountPaymentModeMessageFreeTrial; break; case SKProductDiscountPaymentModePayAsYouGo: - paymentMode = SKProductDiscountPaymentModeMessagePayAsYouGo; + paymentMode = FIASKProductDiscountPaymentModeMessagePayAsYouGo; break; case SKProductDiscountPaymentModePayUpFront: - paymentMode = SKProductDiscountPaymentModeMessagePayUpFront; + paymentMode = FIASKProductDiscountPaymentModeMessagePayUpFront; break; } - SKProductDiscountTypeMessage type; + FIASKProductDiscountTypeMessage type; switch (productDiscount.type) { case SKProductDiscountTypeIntroductory: - type = SKProductDiscountTypeMessageIntroductory; + type = FIASKProductDiscountTypeMessageIntroductory; break; case SKProductDiscountTypeSubscription: - type = SKProductDiscountTypeMessageSubscription; + type = FIASKProductDiscountTypeMessageSubscription; break; } - SKProductDiscountMessage *msg = [SKProductDiscountMessage + return [FIASKProductDiscountMessage makeWithPrice:productDiscount.price.description priceLocale:[self convertNSLocaleToPigeon:productDiscount.priceLocale] numberOfPeriods:productDiscount.numberOfPeriods @@ -451,37 +438,33 @@ + (nullable SKProductDiscountMessage *)convertProductDiscountToPigeon: .subscriptionPeriod] identifier:productDiscount.identifier type:type]; - - return msg; } -+ (nullable SKPriceLocaleMessage *)convertNSLocaleToPigeon:(nullable NSLocale *)locale ++ (nullable FIASKPriceLocaleMessage *)convertNSLocaleToPigeon:(nullable NSLocale *)locale API_AVAILABLE(ios(12.2)) { if (!locale) { return nil; } - SKPriceLocaleMessage *msg = [SKPriceLocaleMessage makeWithCurrencySymbol:locale.currencySymbol - currencyCode:locale.currencyCode - countryCode:locale.countryCode]; - - return msg; + return [FIASKPriceLocaleMessage makeWithCurrencySymbol:locale.currencySymbol + currencyCode:locale.currencyCode + countryCode:locale.countryCode]; } -+ (nullable SKProductMessage *)convertProductToPigeon:(nullable SKProduct *)product ++ (nullable FIASKProductMessage *)convertProductToPigeon:(nullable SKProduct *)product API_AVAILABLE(ios(12.2)) { if (!product) { return nil; } NSArray *skProductDiscounts = product.discounts; - NSMutableArray *pigeonProductDiscounts = + NSMutableArray *pigeonProductDiscounts = [NSMutableArray arrayWithCapacity:skProductDiscounts.count]; for (SKProductDiscount *productDiscount in skProductDiscounts) { [pigeonProductDiscounts addObject:[self convertProductDiscountToPigeon:productDiscount]]; }; - SKProductMessage *msg = [SKProductMessage + return [FIASKProductMessage makeWithProductIdentifier:product.productIdentifier localizedTitle:product.localizedTitle localizedDescription:product.localizedDescription @@ -492,27 +475,24 @@ + (nullable SKProductMessage *)convertProductToPigeon:(nullable SKProduct *)prod [self convertSKProductSubscriptionPeriodToPigeon:product.subscriptionPeriod] introductoryPrice:[self convertProductDiscountToPigeon:product.introductoryPrice] discounts:pigeonProductDiscounts]; - - return msg; } -+ (nullable SKProductsResponseMessage *)convertProductsResponseToPigeon: ++ (nullable FIASKProductsResponseMessage *)convertProductsResponseToPigeon: (nullable SKProductsResponse *)productsResponse API_AVAILABLE(ios(12.2)) { if (!productsResponse) { return nil; } NSArray *skProducts = productsResponse.products; - NSMutableArray *pigeonProducts = + NSMutableArray *pigeonProducts = [NSMutableArray arrayWithCapacity:skProducts.count]; for (SKProduct *product in skProducts) { [pigeonProducts addObject:[self convertProductToPigeon:product]]; }; - SKProductsResponseMessage *msg = - [SKProductsResponseMessage makeWithProducts:pigeonProducts - invalidProductIdentifiers:productsResponse.invalidProductIdentifiers]; - return msg; + return [FIASKProductsResponseMessage + makeWithProducts:pigeonProducts + invalidProductIdentifiers:productsResponse.invalidProductIdentifiers ?: @[]]; } @end diff --git a/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/FIAPPaymentQueueDelegate.h b/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/FIAPPaymentQueueDelegate.h index 12ef96bee5c2..522c081923d8 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/FIAPPaymentQueueDelegate.h +++ b/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/FIAPPaymentQueueDelegate.h @@ -13,8 +13,8 @@ NS_ASSUME_NONNULL_BEGIN -API_AVAILABLE(ios(13)) -API_UNAVAILABLE(tvos, macos, watchos) +API_AVAILABLE(ios(13), macos(10.15)) +API_UNAVAILABLE(tvos, watchos) @interface FIAPPaymentQueueDelegate : NSObject - (id)initWithMethodChannel:(id)methodChannel; @end diff --git a/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift b/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift index 4ebd88281842..23b8972c96c1 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift +++ b/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift @@ -11,7 +11,7 @@ import StoreKit import FlutterMacOS #endif -public class InAppPurchasePlugin: NSObject, FlutterPlugin, InAppPurchaseAPI { +public class InAppPurchasePlugin: NSObject, FlutterPlugin, FIAInAppPurchaseAPI { private let receiptManager: FIAPReceiptManager private var productsCache: NSMutableDictionary = [:] private var paymentQueueDelegateCallbackChannel: FlutterMethodChannel? @@ -22,15 +22,25 @@ public class InAppPurchasePlugin: NSObject, FlutterPlugin, InAppPurchaseAPI { // TODO(louisehsu): Change it back to a set when removing obj-c dependancies from this file via type erasure private var requestHandlers = NSHashTable() private var handlerFactory: ((SKRequest) -> FLTRequestHandlerProtocol) - // TODO(louisehsu): Once tests are migrated to swift, we can use @testable import, and make theses vars private again and remove all instances of @objc - @objc + private var transactionObserverCallbackChannel: FLTMethodChannelProtocol? public var registrar: FlutterPluginRegistrar? // This property is optional, as it requires self to exist to be initialized. - @objc public var paymentQueueHandler: FLTPaymentQueueHandlerProtocol? - // This property is optional, as it needs to be set during plugin registration, and can't be directly initialized. - @objc - public var transactionObserverCallbackChannel: FLTMethodChannelProtocol? + + // This should be an Task, but Task is on available >= iOS 13 + private var _updateListenerTask: Any? + + @available(iOS 13.0, *) + var updateListenerTask: Task<(), Never> { + return self._updateListenerTask as! Task<(), Never> + } + + @available(iOS 13.0, *) + func setListenerTaskAsTask(task: Task<(), Never>) { + self._updateListenerTask = task + } + + var transactionCallbackAPI: InAppPurchase2CallbackAPI? = nil public static func register(with registrar: FlutterPluginRegistrar) { #if os(iOS) @@ -45,19 +55,23 @@ public class InAppPurchasePlugin: NSObject, FlutterPlugin, InAppPurchaseAPI { let instance = InAppPurchasePlugin(registrar: registrar) registrar.addMethodCallDelegate(instance, channel: channel) registrar.addApplicationDelegate(instance) - SetUpInAppPurchaseAPI(messenger, instance) + SetUpFIAInAppPurchaseAPI(messenger, instance) + if #available(iOS 15.0, macOS 12.0, *) { + InAppPurchase2APISetup.setUp(binaryMessenger: messenger, api: instance) + } } - @objc // This init is used for tests public init( receiptManager: FIAPReceiptManager, handlerFactory: @escaping (SKRequest) -> FLTRequestHandlerProtocol = { DefaultRequestHandler(requestHandler: FIAPRequestHandler(request: $0)) - } + }, + transactionCallbackChannel: FLTMethodChannelProtocol? = nil ) { self.receiptManager = receiptManager self.handlerFactory = handlerFactory + self.transactionObserverCallbackChannel = transactionCallbackChannel super.init() } @@ -93,11 +107,8 @@ public class InAppPurchasePlugin: NSObject, FlutterPlugin, InAppPurchaseAPI { #if os(macOS) let messenger = registrar.messenger #endif - transactionObserverCallbackChannel = DefaultMethodChannel( - channel: FlutterMethodChannel( - name: "plugins.flutter.io/in_app_purchase", - binaryMessenger: messenger) - ) + setupTransactionObserverChannelIfNeeded(withMessenger: messenger) + self.transactionCallbackAPI = InAppPurchase2CallbackAPI(binaryMessenger: messenger) } // MARK: - Pigeon Functions @@ -109,7 +120,7 @@ public class InAppPurchasePlugin: NSObject, FlutterPlugin, InAppPurchaseAPI { } public func transactionsWithError(_ error: AutoreleasingUnsafeMutablePointer) - -> [SKPaymentTransactionMessage]? + -> [FIASKPaymentTransactionMessage]? { return getPaymentQueueHandler() .getUnfinishedTransactions() @@ -119,7 +130,7 @@ public class InAppPurchasePlugin: NSObject, FlutterPlugin, InAppPurchaseAPI { } public func storefrontWithError(_ error: AutoreleasingUnsafeMutablePointer) - -> SKStorefrontMessage? + -> FIASKStorefrontMessage? { if #available(iOS 13.0, *), let storefront = getPaymentQueueHandler().storefront { return FIAObjectTranslator.convertStorefront(toPigeon: storefront) @@ -129,7 +140,7 @@ public class InAppPurchasePlugin: NSObject, FlutterPlugin, InAppPurchaseAPI { public func startProductRequestProductIdentifiers( _ productIdentifiers: [String], - completion: @escaping (SKProductsResponseMessage?, FlutterError?) -> Void + completion: @escaping (FIASKProductsResponseMessage?, FlutterError?) -> Void ) { let request = getProductRequest(withIdentifiers: Set(productIdentifiers)) let handler = handlerFactory(request) @@ -359,7 +370,6 @@ public class InAppPurchasePlugin: NSObject, FlutterPlugin, InAppPurchaseAPI { #endif } - @objc public func handleTransactionsUpdated(_ transactions: [SKPaymentTransaction]) { let translatedTransactions = transactions.map { FIAObjectTranslator.getMapFrom($0) @@ -368,7 +378,6 @@ public class InAppPurchasePlugin: NSObject, FlutterPlugin, InAppPurchaseAPI { "updatedTransactions", arguments: translatedTransactions) } - @objc public func handleTransactionsRemoved(_ transactions: [SKPaymentTransaction]) { let translatedTransactions = transactions.map { FIAObjectTranslator.getMapFrom($0) @@ -377,19 +386,16 @@ public class InAppPurchasePlugin: NSObject, FlutterPlugin, InAppPurchaseAPI { "removedTransactions", arguments: translatedTransactions) } - @objc public func handleTransactionRestoreFailed(_ error: NSError) { transactionObserverCallbackChannel?.invokeMethod( "restoreCompletedTransactionsFailed", arguments: FIAObjectTranslator.getMapFrom(error)) } - @objc public func restoreCompletedTransactionsFinished() { transactionObserverCallbackChannel?.invokeMethod( "paymentQueueRestoreCompletedTransactionsFinished", arguments: nil) } - @objc public func shouldAddStorePayment(payment: SKPayment, product: SKProduct) -> Bool { productsCache[product.productIdentifier] = product transactionObserverCallbackChannel?.invokeMethod( @@ -432,4 +438,18 @@ public class InAppPurchasePlugin: NSObject, FlutterPlugin, InAppPurchaseAPI { } return paymentQueueHandler } + + private func setupTransactionObserverChannelIfNeeded( + withMessenger messenger: FlutterBinaryMessenger + ) { + // If the channel is already set (e.g., injected in tests), don't overwrite it. + guard self.transactionObserverCallbackChannel == nil else { return } + + self.transactionObserverCallbackChannel = DefaultMethodChannel( + channel: FlutterMethodChannel( + name: "plugins.flutter.io/in_app_purchase", + binaryMessenger: messenger + ) + ) + } } diff --git a/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/StoreKit2/InAppPurchasePlugin+StoreKit2.swift b/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/StoreKit2/InAppPurchasePlugin+StoreKit2.swift new file mode 100644 index 000000000000..47daff575302 --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/StoreKit2/InAppPurchasePlugin+StoreKit2.swift @@ -0,0 +1,211 @@ +// 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. + +@available(iOS 15.0, macOS 12.0, *) +extension InAppPurchasePlugin: InAppPurchase2API { + + // MARK: - Pigeon Functions + + /// Wrapper method around StoreKit2's canMakePayments() method + /// https://developer.apple.com/documentation/storekit/appstore/3822277-canmakepayments + func canMakePayments() throws -> Bool { + return AppStore.canMakePayments + } + + /// Wrapper method around StoreKit2's products() method + /// https://developer.apple.com/documentation/storekit/product/3851116-products + func products( + identifiers: [String], completion: @escaping (Result<[SK2ProductMessage], Error>) -> Void + ) { + Task { + do { + let products = try await Product.products(for: identifiers) + let productMessages = products.map { + $0.convertToPigeon + } + completion(.success(productMessages)) + } catch { + completion( + .failure( + PigeonError( + code: "storekit2_products_error", + message: error.localizedDescription, + details: error.localizedDescription))) + } + } + } + + /// Gets the appropriate product, then calls purchase on it. + /// https://developer.apple.com/documentation/storekit/product/3791971-purchase + func purchase( + id: String, options: SK2ProductPurchaseOptionsMessage?, + completion: @escaping (Result) -> Void + ) { + Task { @MainActor in + do { + guard let product = try await Product.products(for: [id]).first else { + let error = PigeonError( + code: "storekit2_failed_to_fetch_product", + message: "Storekit has failed to fetch this product.", + details: "Product ID : \(id)") + return completion(.failure(error)) + } + + let result = try await product.purchase(options: []) + + switch result { + case .success(let verification): + switch verification { + case .verified(let transaction): + self.sendTransactionUpdate(transaction: transaction) + completion(.success(result.convertToPigeon())) + case .unverified(_, let error): + completion(.failure(error)) + } + case .pending: + completion( + .failure( + PigeonError( + code: "storekit2_purchase_pending", + message: + "This transaction is still pending and but may complete in the future. If it completes, it will be delivered via `purchaseStream`", + details: "Product ID : \(id)"))) + case .userCancelled: + completion( + .failure( + PigeonError( + code: "storekit2_purchase_cancelled", + message: "This transaction has been cancelled by the user.", + details: "Product ID : \(id)"))) + @unknown default: + fatalError("An unknown StoreKit PurchaseResult has been encountered.") + } + } catch { + completion(.failure(error)) + } + } + } + + /// Wrapper method around StoreKit2's transactions() method + /// https://developer.apple.com/documentation/storekit/product/3851116-products + func transactions( + completion: @escaping (Result<[SK2TransactionMessage], Error>) -> Void + ) { + Task { + @MainActor in + do { + let transactionsMsgs = await rawTransactions().map { + $0.convertToPigeon(receipt: nil) + } + completion(.success(transactionsMsgs)) + } + } + } + + func restorePurchases(completion: @escaping (Result) -> Void) { + Task { [weak self] in + guard let self = self else { return } + do { + var unverifiedPurchases: [UInt64: (receipt: String, error: Error?)] = [:] + for await completedPurchase in Transaction.currentEntitlements { + switch completedPurchase { + case .verified(let purchase): + self.sendTransactionUpdate( + transaction: purchase, receipt: "\(completedPurchase.jwsRepresentation)") + case .unverified(let failedPurchase, let error): + unverifiedPurchases[failedPurchase.id] = ( + receipt: completedPurchase.jwsRepresentation, error: error + ) + } + } + if !unverifiedPurchases.isEmpty { + completion( + .failure( + PigeonError( + code: "storekit2_restore_failed", + message: + "This purchase could not be restored.", + details: unverifiedPurchases))) + } + completion(.success(Void())) + } + } + } + + /// Wrapper method around StoreKit2's finish() method https://developer.apple.com/documentation/storekit/transaction/3749694-finish + func finish(id: Int64, completion: @escaping (Result) -> Void) { + Task { + let transaction = try await fetchTransaction(by: UInt64(id)) + if let transaction = transaction { + await transaction.finish() + } + } + } + + /// This Task listens to Transation.updates as shown here + /// https://developer.apple.com/documentation/storekit/transaction/3851206-updates + /// This function should be called as soon as the app starts to avoid missing any Transactions done outside of the app. + func startListeningToTransactions() throws { + self.setListenerTaskAsTask( + task: Task { [weak self] in + for await verificationResult in Transaction.updates { + switch verificationResult { + case .verified(let transaction): + self?.sendTransactionUpdate(transaction: transaction) + case .unverified: + break + } + } + }) + } + + /// Stop subscribing to Transaction.updates + func stopListeningToTransactions() throws { + updateListenerTask.cancel() + } + + /// Sends an transaction back to Dart. Access these transactions with `purchaseStream` + private func sendTransactionUpdate(transaction: Transaction, receipt: String? = nil) { + let transactionMessage = transaction.convertToPigeon(receipt: receipt) + self.transactionCallbackAPI?.onTransactionsUpdated(newTransactions: [transactionMessage]) { + result in + switch result { + case .success: break + case .failure(let error): + print("Failed to send transaction updates: \(error)") + } + } + } + + // MARK: - Convenience Functions + + /// Helper function that fetches and unwraps all verified transactions + private func rawTransactions() async -> [Transaction] { + var transactions: [Transaction] = [] + for await verificationResult in Transaction.all { + switch verificationResult { + case .verified(let transaction): + transactions.append(transaction) + case .unverified: + break + } + } + return transactions + } + + /// Helper function to fetch specific transaction + private func fetchTransaction(by id: UInt64) async throws -> Transaction? { + for await result in Transaction.all { + switch result { + case .verified(let transaction): + if transaction.id == id { + return transaction + } + case .unverified: + continue + } + } + return nil + } +} diff --git a/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/StoreKit2/StoreKit2Translators.swift b/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/StoreKit2/StoreKit2Translators.swift new file mode 100644 index 000000000000..f2b2511afa98 --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/StoreKit2/StoreKit2Translators.swift @@ -0,0 +1,205 @@ +// 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 Foundation +import StoreKit + +@available(iOS 15.0, macOS 12.0, *) +extension Product { + var convertToPigeon: SK2ProductMessage { + + return SK2ProductMessage( + id: id, + displayName: displayName, + description: description, + price: NSDecimalNumber(decimal: price).doubleValue, + displayPrice: displayPrice, + type: type.convertToPigeon, + subscription: subscription?.convertToPigeon, + priceLocale: priceFormatStyle.locale.convertToPigeon + ) + } +} + +extension SK2ProductMessage: Equatable { + static func == (lhs: SK2ProductMessage, rhs: SK2ProductMessage) -> Bool { + return lhs.id == rhs.id && lhs.displayName == rhs.displayName + && lhs.description == rhs.description && lhs.price == rhs.price + && lhs.displayPrice == rhs.displayPrice && lhs.type == rhs.type + && lhs.subscription == rhs.subscription && lhs.priceLocale == rhs.priceLocale + } +} + +@available(iOS 15.0, macOS 12.0, *) +extension Product.ProductType { + var convertToPigeon: SK2ProductTypeMessage { + switch self { + case Product.ProductType.autoRenewable: + return SK2ProductTypeMessage.autoRenewable + case Product.ProductType.consumable: + return SK2ProductTypeMessage.consumable + case Product.ProductType.nonConsumable: + return SK2ProductTypeMessage.nonConsumable + case Product.ProductType.nonRenewable: + return SK2ProductTypeMessage.nonRenewable + default: + fatalError("An unknown ProductType was passed in") + } + } +} + +@available(iOS 15.0, macOS 12.0, *) +extension Product.SubscriptionInfo { + var convertToPigeon: SK2SubscriptionInfoMessage { + return SK2SubscriptionInfoMessage( + promotionalOffers: promotionalOffers.map({ $0.convertToPigeon }), + subscriptionGroupID: subscriptionGroupID, + subscriptionPeriod: subscriptionPeriod.convertToPigeon) + } +} + +extension SK2SubscriptionInfoMessage: Equatable { + static func == (lhs: SK2SubscriptionInfoMessage, rhs: SK2SubscriptionInfoMessage) -> Bool { + return lhs.promotionalOffers == rhs.promotionalOffers + && lhs.subscriptionGroupID == rhs.subscriptionGroupID + && lhs.subscriptionPeriod == rhs.subscriptionPeriod + } +} + +@available(iOS 15.0, macOS 12.0, *) +extension Product.SubscriptionOffer { + var convertToPigeon: SK2SubscriptionOfferMessage { + return SK2SubscriptionOfferMessage( + /// ID is always `nil` for introductory offers and never `nil` for other offer types. + id: id, + price: NSDecimalNumber(decimal: price).doubleValue, + type: type.convertToPigeon, + period: period.convertToPigeon, + periodCount: Int64(periodCount), + paymentMode: paymentMode.convertToPigeon + ) + } +} + +extension SK2SubscriptionOfferMessage: Equatable { + static func == (lhs: SK2SubscriptionOfferMessage, rhs: SK2SubscriptionOfferMessage) -> Bool { + return lhs.id == rhs.id && lhs.price == rhs.price && lhs.type == rhs.type + && lhs.period == rhs.period && lhs.periodCount == rhs.periodCount + && lhs.paymentMode == rhs.paymentMode + } +} + +@available(iOS 15.0, macOS 12.0, *) +extension Product.SubscriptionOffer.OfferType { + var convertToPigeon: SK2SubscriptionOfferTypeMessage { + switch self { + case .introductory: + return SK2SubscriptionOfferTypeMessage.introductory + case .promotional: + return SK2SubscriptionOfferTypeMessage.promotional + default: + fatalError("An unknown OfferType was passed in") + } + } +} + +@available(iOS 15.0, macOS 12.0, *) +extension Product.SubscriptionPeriod { + var convertToPigeon: SK2SubscriptionPeriodMessage { + return SK2SubscriptionPeriodMessage( + value: Int64(value), + unit: unit.convertToPigeon) + } +} + +extension SK2SubscriptionPeriodMessage: Equatable { + static func == (lhs: SK2SubscriptionPeriodMessage, rhs: SK2SubscriptionPeriodMessage) -> Bool { + return lhs.value == rhs.value && lhs.unit == rhs.unit + } +} + +@available(iOS 15.0, macOS 12.0, *) +extension Product.SubscriptionPeriod.Unit { + var convertToPigeon: SK2SubscriptionPeriodUnitMessage { + switch self { + case .day: + return SK2SubscriptionPeriodUnitMessage.day + case .week: + return SK2SubscriptionPeriodUnitMessage.week + case .month: + return SK2SubscriptionPeriodUnitMessage.month + case .year: + return SK2SubscriptionPeriodUnitMessage.year + @unknown default: + fatalError("unknown SubscriptionPeriodUnit encountered") + } + } +} + +@available(iOS 15.0, macOS 12.0, *) +extension Product.SubscriptionOffer.PaymentMode { + var convertToPigeon: SK2SubscriptionOfferPaymentModeMessage { + switch self { + case .freeTrial: + return SK2SubscriptionOfferPaymentModeMessage.freeTrial + case .payUpFront: + return SK2SubscriptionOfferPaymentModeMessage.payUpFront + case .payAsYouGo: + return SK2SubscriptionOfferPaymentModeMessage.payAsYouGo + default: + fatalError("Encountered an unknown PaymentMode") + } + } +} + +extension Locale { + var convertToPigeon: SK2PriceLocaleMessage { + return SK2PriceLocaleMessage( + currencyCode: currencyCode ?? "", + currencySymbol: currencySymbol ?? "" + ) + } +} + +extension SK2PriceLocaleMessage: Equatable { + static func == (lhs: SK2PriceLocaleMessage, rhs: SK2PriceLocaleMessage) -> Bool { + return lhs.currencyCode == rhs.currencyCode && lhs.currencySymbol == rhs.currencySymbol + } +} + +@available(iOS 15.0, macOS 12.0, *) +extension Product.PurchaseResult { + func convertToPigeon() -> SK2ProductPurchaseResultMessage { + switch self { + case .success(_): + return SK2ProductPurchaseResultMessage.success + case .userCancelled: + return SK2ProductPurchaseResultMessage.userCancelled + case .pending: + return SK2ProductPurchaseResultMessage.pending + @unknown default: + fatalError() + } + } +} + +@available(iOS 15.0, macOS 12.0, *) +extension Transaction { + func convertToPigeon(receipt: String?) -> SK2TransactionMessage { + + let dateFromatter: DateFormatter = DateFormatter() + dateFromatter.dateFormat = "yyyy-MM-dd HH:mm:ss" + + return SK2TransactionMessage( + id: Int64(id), + originalId: Int64(originalID), + productId: productID, + purchaseDate: dateFromatter.string(from: purchaseDate), + purchasedQuantity: Int64(purchasedQuantity), + appAccountToken: appAccountToken?.uuidString, + restoring: receipt != nil, + receiptData: receipt + ) + } +} diff --git a/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/StoreKit2/sk2_pigeon.g.swift b/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/StoreKit2/sk2_pigeon.g.swift new file mode 100644 index 000000000000..f79f51b260de --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/StoreKit2/sk2_pigeon.g.swift @@ -0,0 +1,712 @@ +// 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 (v22.6.0), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +import Foundation + +#if os(iOS) + import Flutter +#elseif os(macOS) + import FlutterMacOS +#else + #error("Unsupported platform.") +#endif + +/// Error class for passing custom error details to Dart side. +final class PigeonError: Error { + let code: String + let message: String? + let details: Any? + + init(code: String, message: String?, details: Any?) { + self.code = code + self.message = message + self.details = details + } + + var localizedDescription: String { + return + "PigeonError(code: \(code), message: \(message ?? ""), details: \(details ?? "")" + } +} + +private func wrapResult(_ result: Any?) -> [Any?] { + return [result] +} + +private func wrapError(_ error: Any) -> [Any?] { + if let pigeonError = error as? PigeonError { + return [ + pigeonError.code, + pigeonError.message, + pigeonError.details, + ] + } + if let flutterError = error as? FlutterError { + return [ + flutterError.code, + flutterError.message, + flutterError.details, + ] + } + return [ + "\(error)", + "\(type(of: error))", + "Stacktrace: \(Thread.callStackSymbols)", + ] +} + +private func createConnectionError(withChannelName channelName: String) -> PigeonError { + return PigeonError( + code: "channel-error", message: "Unable to establish connection on channel: '\(channelName)'.", + details: "") +} + +private func isNullish(_ value: Any?) -> Bool { + return value is NSNull || value == nil +} + +private func nilOrValue(_ value: Any?) -> T? { + if value is NSNull { return nil } + return value as! T? +} + +enum SK2ProductTypeMessage: Int { + /// A consumable in-app purchase. + case consumable = 0 + /// A non-consumable in-app purchase. + case nonConsumable = 1 + /// A non-renewing subscription. + case nonRenewable = 2 + /// An auto-renewable subscription. + case autoRenewable = 3 +} + +enum SK2SubscriptionOfferTypeMessage: Int { + case introductory = 0 + case promotional = 1 +} + +enum SK2SubscriptionOfferPaymentModeMessage: Int { + case payAsYouGo = 0 + case payUpFront = 1 + case freeTrial = 2 +} + +enum SK2SubscriptionPeriodUnitMessage: Int { + case day = 0 + case week = 1 + case month = 2 + case year = 3 +} + +enum SK2ProductPurchaseResultMessage: Int { + case success = 0 + case userCancelled = 1 + case pending = 2 +} + +/// Generated class from Pigeon that represents data sent in messages. +struct SK2SubscriptionOfferMessage { + var id: String? = nil + var price: Double + var type: SK2SubscriptionOfferTypeMessage + var period: SK2SubscriptionPeriodMessage + var periodCount: Int64 + var paymentMode: SK2SubscriptionOfferPaymentModeMessage + + // swift-format-ignore: AlwaysUseLowerCamelCase + static func fromList(_ pigeonVar_list: [Any?]) -> SK2SubscriptionOfferMessage? { + let id: String? = nilOrValue(pigeonVar_list[0]) + let price = pigeonVar_list[1] as! Double + let type = pigeonVar_list[2] as! SK2SubscriptionOfferTypeMessage + let period = pigeonVar_list[3] as! SK2SubscriptionPeriodMessage + let periodCount = pigeonVar_list[4] as! Int64 + let paymentMode = pigeonVar_list[5] as! SK2SubscriptionOfferPaymentModeMessage + + return SK2SubscriptionOfferMessage( + id: id, + price: price, + type: type, + period: period, + periodCount: periodCount, + paymentMode: paymentMode + ) + } + func toList() -> [Any?] { + return [ + id, + price, + type, + period, + periodCount, + paymentMode, + ] + } +} + +/// Generated class from Pigeon that represents data sent in messages. +struct SK2SubscriptionPeriodMessage { + /// The number of units that the period represents. + var value: Int64 + /// The unit of time that this period represents. + var unit: SK2SubscriptionPeriodUnitMessage + + // swift-format-ignore: AlwaysUseLowerCamelCase + static func fromList(_ pigeonVar_list: [Any?]) -> SK2SubscriptionPeriodMessage? { + let value = pigeonVar_list[0] as! Int64 + let unit = pigeonVar_list[1] as! SK2SubscriptionPeriodUnitMessage + + return SK2SubscriptionPeriodMessage( + value: value, + unit: unit + ) + } + func toList() -> [Any?] { + return [ + value, + unit, + ] + } +} + +/// Generated class from Pigeon that represents data sent in messages. +struct SK2SubscriptionInfoMessage { + /// An array of all the promotional offers configured for this subscription. + var promotionalOffers: [SK2SubscriptionOfferMessage] + /// The group identifier for this subscription. + var subscriptionGroupID: String + /// The duration that this subscription lasts before auto-renewing. + var subscriptionPeriod: SK2SubscriptionPeriodMessage + + // swift-format-ignore: AlwaysUseLowerCamelCase + static func fromList(_ pigeonVar_list: [Any?]) -> SK2SubscriptionInfoMessage? { + let promotionalOffers = pigeonVar_list[0] as! [SK2SubscriptionOfferMessage] + let subscriptionGroupID = pigeonVar_list[1] as! String + let subscriptionPeriod = pigeonVar_list[2] as! SK2SubscriptionPeriodMessage + + return SK2SubscriptionInfoMessage( + promotionalOffers: promotionalOffers, + subscriptionGroupID: subscriptionGroupID, + subscriptionPeriod: subscriptionPeriod + ) + } + func toList() -> [Any?] { + return [ + promotionalOffers, + subscriptionGroupID, + subscriptionPeriod, + ] + } +} + +/// A Pigeon message class representing a Product +/// https://developer.apple.com/documentation/storekit/product +/// +/// Generated class from Pigeon that represents data sent in messages. +struct SK2ProductMessage { + /// The unique product identifier. + var id: String + /// The localized display name of the product, if it exists. + var displayName: String + /// The localized description of the product. + var description: String + /// The localized string representation of the product price, suitable for display. + var price: Double + /// The localized price of the product as a string. + var displayPrice: String + /// The types of in-app purchases. + var type: SK2ProductTypeMessage + /// The subscription information for an auto-renewable subscription. + var subscription: SK2SubscriptionInfoMessage? = nil + /// The currency and locale information for this product + var priceLocale: SK2PriceLocaleMessage + + // swift-format-ignore: AlwaysUseLowerCamelCase + static func fromList(_ pigeonVar_list: [Any?]) -> SK2ProductMessage? { + let id = pigeonVar_list[0] as! String + let displayName = pigeonVar_list[1] as! String + let description = pigeonVar_list[2] as! String + let price = pigeonVar_list[3] as! Double + let displayPrice = pigeonVar_list[4] as! String + let type = pigeonVar_list[5] as! SK2ProductTypeMessage + let subscription: SK2SubscriptionInfoMessage? = nilOrValue(pigeonVar_list[6]) + let priceLocale = pigeonVar_list[7] as! SK2PriceLocaleMessage + + return SK2ProductMessage( + id: id, + displayName: displayName, + description: description, + price: price, + displayPrice: displayPrice, + type: type, + subscription: subscription, + priceLocale: priceLocale + ) + } + func toList() -> [Any?] { + return [ + id, + displayName, + description, + price, + displayPrice, + type, + subscription, + priceLocale, + ] + } +} + +/// Generated class from Pigeon that represents data sent in messages. +struct SK2PriceLocaleMessage { + var currencyCode: String + var currencySymbol: String + + // swift-format-ignore: AlwaysUseLowerCamelCase + static func fromList(_ pigeonVar_list: [Any?]) -> SK2PriceLocaleMessage? { + let currencyCode = pigeonVar_list[0] as! String + let currencySymbol = pigeonVar_list[1] as! String + + return SK2PriceLocaleMessage( + currencyCode: currencyCode, + currencySymbol: currencySymbol + ) + } + func toList() -> [Any?] { + return [ + currencyCode, + currencySymbol, + ] + } +} + +/// Generated class from Pigeon that represents data sent in messages. +struct SK2ProductPurchaseOptionsMessage { + var appAccountToken: String? = nil + var quantity: Int64? = nil + + // swift-format-ignore: AlwaysUseLowerCamelCase + static func fromList(_ pigeonVar_list: [Any?]) -> SK2ProductPurchaseOptionsMessage? { + let appAccountToken: String? = nilOrValue(pigeonVar_list[0]) + let quantity: Int64? = nilOrValue(pigeonVar_list[1]) + + return SK2ProductPurchaseOptionsMessage( + appAccountToken: appAccountToken, + quantity: quantity + ) + } + func toList() -> [Any?] { + return [ + appAccountToken, + quantity, + ] + } +} + +/// Generated class from Pigeon that represents data sent in messages. +struct SK2TransactionMessage { + var id: Int64 + var originalId: Int64 + var productId: String + var purchaseDate: String + var purchasedQuantity: Int64 + var appAccountToken: String? = nil + var restoring: Bool + var receiptData: String? = nil + var error: SK2ErrorMessage? = nil + + // swift-format-ignore: AlwaysUseLowerCamelCase + static func fromList(_ pigeonVar_list: [Any?]) -> SK2TransactionMessage? { + let id = pigeonVar_list[0] as! Int64 + let originalId = pigeonVar_list[1] as! Int64 + let productId = pigeonVar_list[2] as! String + let purchaseDate = pigeonVar_list[3] as! String + let purchasedQuantity = pigeonVar_list[4] as! Int64 + let appAccountToken: String? = nilOrValue(pigeonVar_list[5]) + let restoring = pigeonVar_list[6] as! Bool + let receiptData: String? = nilOrValue(pigeonVar_list[7]) + let error: SK2ErrorMessage? = nilOrValue(pigeonVar_list[8]) + + return SK2TransactionMessage( + id: id, + originalId: originalId, + productId: productId, + purchaseDate: purchaseDate, + purchasedQuantity: purchasedQuantity, + appAccountToken: appAccountToken, + restoring: restoring, + receiptData: receiptData, + error: error + ) + } + func toList() -> [Any?] { + return [ + id, + originalId, + productId, + purchaseDate, + purchasedQuantity, + appAccountToken, + restoring, + receiptData, + error, + ] + } +} + +/// Generated class from Pigeon that represents data sent in messages. +struct SK2ErrorMessage { + var code: Int64 + var domain: String + var userInfo: [String: Any]? = nil + + // swift-format-ignore: AlwaysUseLowerCamelCase + static func fromList(_ pigeonVar_list: [Any?]) -> SK2ErrorMessage? { + let code = pigeonVar_list[0] as! Int64 + let domain = pigeonVar_list[1] as! String + let userInfo: [String: Any]? = nilOrValue(pigeonVar_list[2]) + + return SK2ErrorMessage( + code: code, + domain: domain, + userInfo: userInfo + ) + } + func toList() -> [Any?] { + return [ + code, + domain, + userInfo, + ] + } +} + +private class sk2_pigeonPigeonCodecReader: FlutterStandardReader { + override func readValue(ofType type: UInt8) -> Any? { + switch type { + case 129: + let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?) + if let enumResultAsInt = enumResultAsInt { + return SK2ProductTypeMessage(rawValue: enumResultAsInt) + } + return nil + case 130: + let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?) + if let enumResultAsInt = enumResultAsInt { + return SK2SubscriptionOfferTypeMessage(rawValue: enumResultAsInt) + } + return nil + case 131: + let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?) + if let enumResultAsInt = enumResultAsInt { + return SK2SubscriptionOfferPaymentModeMessage(rawValue: enumResultAsInt) + } + return nil + case 132: + let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?) + if let enumResultAsInt = enumResultAsInt { + return SK2SubscriptionPeriodUnitMessage(rawValue: enumResultAsInt) + } + return nil + case 133: + let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?) + if let enumResultAsInt = enumResultAsInt { + return SK2ProductPurchaseResultMessage(rawValue: enumResultAsInt) + } + return nil + case 134: + return SK2SubscriptionOfferMessage.fromList(self.readValue() as! [Any?]) + case 135: + return SK2SubscriptionPeriodMessage.fromList(self.readValue() as! [Any?]) + case 136: + return SK2SubscriptionInfoMessage.fromList(self.readValue() as! [Any?]) + case 137: + return SK2ProductMessage.fromList(self.readValue() as! [Any?]) + case 138: + return SK2PriceLocaleMessage.fromList(self.readValue() as! [Any?]) + case 139: + return SK2ProductPurchaseOptionsMessage.fromList(self.readValue() as! [Any?]) + case 140: + return SK2TransactionMessage.fromList(self.readValue() as! [Any?]) + case 141: + return SK2ErrorMessage.fromList(self.readValue() as! [Any?]) + default: + return super.readValue(ofType: type) + } + } +} + +private class sk2_pigeonPigeonCodecWriter: FlutterStandardWriter { + override func writeValue(_ value: Any) { + if let value = value as? SK2ProductTypeMessage { + super.writeByte(129) + super.writeValue(value.rawValue) + } else if let value = value as? SK2SubscriptionOfferTypeMessage { + super.writeByte(130) + super.writeValue(value.rawValue) + } else if let value = value as? SK2SubscriptionOfferPaymentModeMessage { + super.writeByte(131) + super.writeValue(value.rawValue) + } else if let value = value as? SK2SubscriptionPeriodUnitMessage { + super.writeByte(132) + super.writeValue(value.rawValue) + } else if let value = value as? SK2ProductPurchaseResultMessage { + super.writeByte(133) + super.writeValue(value.rawValue) + } else if let value = value as? SK2SubscriptionOfferMessage { + super.writeByte(134) + super.writeValue(value.toList()) + } else if let value = value as? SK2SubscriptionPeriodMessage { + super.writeByte(135) + super.writeValue(value.toList()) + } else if let value = value as? SK2SubscriptionInfoMessage { + super.writeByte(136) + super.writeValue(value.toList()) + } else if let value = value as? SK2ProductMessage { + super.writeByte(137) + super.writeValue(value.toList()) + } else if let value = value as? SK2PriceLocaleMessage { + super.writeByte(138) + super.writeValue(value.toList()) + } else if let value = value as? SK2ProductPurchaseOptionsMessage { + super.writeByte(139) + super.writeValue(value.toList()) + } else if let value = value as? SK2TransactionMessage { + super.writeByte(140) + super.writeValue(value.toList()) + } else if let value = value as? SK2ErrorMessage { + super.writeByte(141) + super.writeValue(value.toList()) + } else { + super.writeValue(value) + } + } +} + +private class sk2_pigeonPigeonCodecReaderWriter: FlutterStandardReaderWriter { + override func reader(with data: Data) -> FlutterStandardReader { + return sk2_pigeonPigeonCodecReader(data: data) + } + + override func writer(with data: NSMutableData) -> FlutterStandardWriter { + return sk2_pigeonPigeonCodecWriter(data: data) + } +} + +class sk2_pigeonPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable { + static let shared = sk2_pigeonPigeonCodec(readerWriter: sk2_pigeonPigeonCodecReaderWriter()) +} + +/// Generated protocol from Pigeon that represents a handler of messages from Flutter. +protocol InAppPurchase2API { + func canMakePayments() throws -> Bool + func products( + identifiers: [String], completion: @escaping (Result<[SK2ProductMessage], Error>) -> Void) + func purchase( + id: String, options: SK2ProductPurchaseOptionsMessage?, + completion: @escaping (Result) -> Void) + func transactions(completion: @escaping (Result<[SK2TransactionMessage], Error>) -> Void) + func finish(id: Int64, completion: @escaping (Result) -> Void) + func startListeningToTransactions() throws + func stopListeningToTransactions() throws + func restorePurchases(completion: @escaping (Result) -> Void) +} + +/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. +class InAppPurchase2APISetup { + static var codec: FlutterStandardMessageCodec { sk2_pigeonPigeonCodec.shared } + /// Sets up an instance of `InAppPurchase2API` to handle messages through the `binaryMessenger`. + static func setUp( + binaryMessenger: FlutterBinaryMessenger, api: InAppPurchase2API?, + messageChannelSuffix: String = "" + ) { + let channelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : "" + let canMakePaymentsChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.canMakePayments\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + canMakePaymentsChannel.setMessageHandler { _, reply in + do { + let result = try api.canMakePayments() + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + canMakePaymentsChannel.setMessageHandler(nil) + } + let productsChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.products\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + productsChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let identifiersArg = args[0] as! [String] + api.products(identifiers: identifiersArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + productsChannel.setMessageHandler(nil) + } + let purchaseChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.purchase\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + purchaseChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let idArg = args[0] as! String + let optionsArg: SK2ProductPurchaseOptionsMessage? = nilOrValue(args[1]) + api.purchase(id: idArg, options: optionsArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + purchaseChannel.setMessageHandler(nil) + } + let transactionsChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.transactions\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + transactionsChannel.setMessageHandler { _, reply in + api.transactions { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + transactionsChannel.setMessageHandler(nil) + } + let finishChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.finish\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + finishChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let idArg = args[0] as! Int64 + api.finish(id: idArg) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + finishChannel.setMessageHandler(nil) + } + let startListeningToTransactionsChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.startListeningToTransactions\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + startListeningToTransactionsChannel.setMessageHandler { _, reply in + do { + try api.startListeningToTransactions() + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + startListeningToTransactionsChannel.setMessageHandler(nil) + } + let stopListeningToTransactionsChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.stopListeningToTransactions\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + stopListeningToTransactionsChannel.setMessageHandler { _, reply in + do { + try api.stopListeningToTransactions() + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + stopListeningToTransactionsChannel.setMessageHandler(nil) + } + let restorePurchasesChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.restorePurchases\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + restorePurchasesChannel.setMessageHandler { _, reply in + api.restorePurchases { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + restorePurchasesChannel.setMessageHandler(nil) + } + } +} +/// Generated protocol from Pigeon that represents Flutter messages that can be called from Swift. +protocol InAppPurchase2CallbackAPIProtocol { + func onTransactionsUpdated( + newTransactions newTransactionsArg: [SK2TransactionMessage], + completion: @escaping (Result) -> Void) +} +class InAppPurchase2CallbackAPI: InAppPurchase2CallbackAPIProtocol { + private let binaryMessenger: FlutterBinaryMessenger + private let messageChannelSuffix: String + init(binaryMessenger: FlutterBinaryMessenger, messageChannelSuffix: String = "") { + self.binaryMessenger = binaryMessenger + self.messageChannelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : "" + } + var codec: sk2_pigeonPigeonCodec { + return sk2_pigeonPigeonCodec.shared + } + func onTransactionsUpdated( + newTransactions newTransactionsArg: [SK2TransactionMessage], + completion: @escaping (Result) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2CallbackAPI.onTransactionsUpdated\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([newTransactionsArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} diff --git a/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/messages.g.h b/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/messages.g.h index 79bdffc76afe..a6059f269d73 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/messages.g.h +++ b/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/messages.g.h @@ -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.4), do not edit directly. +// Autogenerated from Pigeon (v22.4.2), do not edit directly. // See also: https://pub.dev/packages/pigeon #import @@ -13,117 +13,117 @@ NS_ASSUME_NONNULL_BEGIN -typedef NS_ENUM(NSUInteger, SKPaymentTransactionStateMessage) { +typedef NS_ENUM(NSUInteger, FIASKPaymentTransactionStateMessage) { /// Indicates the transaction is being processed in App Store. /// /// You should update your UI to indicate that you are waiting for the /// transaction to update to another state. Never complete a transaction that /// is still in a purchasing state. - SKPaymentTransactionStateMessagePurchasing = 0, + FIASKPaymentTransactionStateMessagePurchasing = 0, /// The user's payment has been succesfully processed. /// /// You should provide the user the content that they purchased. - SKPaymentTransactionStateMessagePurchased = 1, + FIASKPaymentTransactionStateMessagePurchased = 1, /// The transaction failed. /// /// Check the [PaymentTransactionWrapper.error] property from /// [PaymentTransactionWrapper] for details. - SKPaymentTransactionStateMessageFailed = 2, + FIASKPaymentTransactionStateMessageFailed = 2, /// This transaction is restoring content previously purchased by the user. /// /// The previous transaction information can be obtained in /// [PaymentTransactionWrapper.originalTransaction] from /// [PaymentTransactionWrapper]. - SKPaymentTransactionStateMessageRestored = 3, + FIASKPaymentTransactionStateMessageRestored = 3, /// The transaction is in the queue but pending external action. Wait for /// another callback to get the final state. /// /// You should update your UI to indicate that you are waiting for the /// transaction to update to another state. - SKPaymentTransactionStateMessageDeferred = 4, + FIASKPaymentTransactionStateMessageDeferred = 4, /// Indicates the transaction is in an unspecified state. - SKPaymentTransactionStateMessageUnspecified = 5, + FIASKPaymentTransactionStateMessageUnspecified = 5, }; -/// Wrapper for SKPaymentTransactionStateMessage to allow for nullability. -@interface SKPaymentTransactionStateMessageBox : NSObject -@property(nonatomic, assign) SKPaymentTransactionStateMessage value; -- (instancetype)initWithValue:(SKPaymentTransactionStateMessage)value; +/// Wrapper for FIASKPaymentTransactionStateMessage to allow for nullability. +@interface FIASKPaymentTransactionStateMessageBox : NSObject +@property(nonatomic, assign) FIASKPaymentTransactionStateMessage value; +- (instancetype)initWithValue:(FIASKPaymentTransactionStateMessage)value; @end -typedef NS_ENUM(NSUInteger, SKProductDiscountTypeMessage) { +typedef NS_ENUM(NSUInteger, FIASKProductDiscountTypeMessage) { /// A constant indicating the discount type is an introductory offer. - SKProductDiscountTypeMessageIntroductory = 0, + FIASKProductDiscountTypeMessageIntroductory = 0, /// A constant indicating the discount type is a promotional offer. - SKProductDiscountTypeMessageSubscription = 1, + FIASKProductDiscountTypeMessageSubscription = 1, }; -/// Wrapper for SKProductDiscountTypeMessage to allow for nullability. -@interface SKProductDiscountTypeMessageBox : NSObject -@property(nonatomic, assign) SKProductDiscountTypeMessage value; -- (instancetype)initWithValue:(SKProductDiscountTypeMessage)value; +/// Wrapper for FIASKProductDiscountTypeMessage to allow for nullability. +@interface FIASKProductDiscountTypeMessageBox : NSObject +@property(nonatomic, assign) FIASKProductDiscountTypeMessage value; +- (instancetype)initWithValue:(FIASKProductDiscountTypeMessage)value; @end -typedef NS_ENUM(NSUInteger, SKProductDiscountPaymentModeMessage) { +typedef NS_ENUM(NSUInteger, FIASKProductDiscountPaymentModeMessage) { /// Allows user to pay the discounted price at each payment period. - SKProductDiscountPaymentModeMessagePayAsYouGo = 0, + FIASKProductDiscountPaymentModeMessagePayAsYouGo = 0, /// Allows user to pay the discounted price upfront and receive the product for the rest of time /// that was paid for. - SKProductDiscountPaymentModeMessagePayUpFront = 1, + FIASKProductDiscountPaymentModeMessagePayUpFront = 1, /// User pays nothing during the discounted period. - SKProductDiscountPaymentModeMessageFreeTrial = 2, + FIASKProductDiscountPaymentModeMessageFreeTrial = 2, /// Unspecified mode. - SKProductDiscountPaymentModeMessageUnspecified = 3, + FIASKProductDiscountPaymentModeMessageUnspecified = 3, }; -/// Wrapper for SKProductDiscountPaymentModeMessage to allow for nullability. -@interface SKProductDiscountPaymentModeMessageBox : NSObject -@property(nonatomic, assign) SKProductDiscountPaymentModeMessage value; -- (instancetype)initWithValue:(SKProductDiscountPaymentModeMessage)value; +/// Wrapper for FIASKProductDiscountPaymentModeMessage to allow for nullability. +@interface FIASKProductDiscountPaymentModeMessageBox : NSObject +@property(nonatomic, assign) FIASKProductDiscountPaymentModeMessage value; +- (instancetype)initWithValue:(FIASKProductDiscountPaymentModeMessage)value; @end -typedef NS_ENUM(NSUInteger, SKSubscriptionPeriodUnitMessage) { - SKSubscriptionPeriodUnitMessageDay = 0, - SKSubscriptionPeriodUnitMessageWeek = 1, - SKSubscriptionPeriodUnitMessageMonth = 2, - SKSubscriptionPeriodUnitMessageYear = 3, +typedef NS_ENUM(NSUInteger, FIASKSubscriptionPeriodUnitMessage) { + FIASKSubscriptionPeriodUnitMessageDay = 0, + FIASKSubscriptionPeriodUnitMessageWeek = 1, + FIASKSubscriptionPeriodUnitMessageMonth = 2, + FIASKSubscriptionPeriodUnitMessageYear = 3, }; -/// Wrapper for SKSubscriptionPeriodUnitMessage to allow for nullability. -@interface SKSubscriptionPeriodUnitMessageBox : NSObject -@property(nonatomic, assign) SKSubscriptionPeriodUnitMessage value; -- (instancetype)initWithValue:(SKSubscriptionPeriodUnitMessage)value; +/// Wrapper for FIASKSubscriptionPeriodUnitMessage to allow for nullability. +@interface FIASKSubscriptionPeriodUnitMessageBox : NSObject +@property(nonatomic, assign) FIASKSubscriptionPeriodUnitMessage value; +- (instancetype)initWithValue:(FIASKSubscriptionPeriodUnitMessage)value; @end -@class SKPaymentTransactionMessage; -@class SKPaymentMessage; -@class SKErrorMessage; -@class SKPaymentDiscountMessage; -@class SKStorefrontMessage; -@class SKProductsResponseMessage; -@class SKProductMessage; -@class SKPriceLocaleMessage; -@class SKProductDiscountMessage; -@class SKProductSubscriptionPeriodMessage; +@class FIASKPaymentTransactionMessage; +@class FIASKPaymentMessage; +@class FIASKErrorMessage; +@class FIASKPaymentDiscountMessage; +@class FIASKStorefrontMessage; +@class FIASKProductsResponseMessage; +@class FIASKProductMessage; +@class FIASKPriceLocaleMessage; +@class FIASKProductDiscountMessage; +@class FIASKProductSubscriptionPeriodMessage; -@interface SKPaymentTransactionMessage : NSObject +@interface FIASKPaymentTransactionMessage : NSObject /// `init` unavailable to enforce nonnull fields, see the `make` class method. - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)makeWithPayment:(SKPaymentMessage *)payment - transactionState:(SKPaymentTransactionStateMessage)transactionState - originalTransaction:(nullable SKPaymentTransactionMessage *)originalTransaction ++ (instancetype)makeWithPayment:(FIASKPaymentMessage *)payment + transactionState:(FIASKPaymentTransactionStateMessage)transactionState + originalTransaction:(nullable FIASKPaymentTransactionMessage *)originalTransaction transactionTimeStamp:(nullable NSNumber *)transactionTimeStamp transactionIdentifier:(nullable NSString *)transactionIdentifier - error:(nullable SKErrorMessage *)error; -@property(nonatomic, strong) SKPaymentMessage *payment; -@property(nonatomic, assign) SKPaymentTransactionStateMessage transactionState; -@property(nonatomic, strong, nullable) SKPaymentTransactionMessage *originalTransaction; + error:(nullable FIASKErrorMessage *)error; +@property(nonatomic, strong) FIASKPaymentMessage *payment; +@property(nonatomic, assign) FIASKPaymentTransactionStateMessage transactionState; +@property(nonatomic, strong, nullable) FIASKPaymentTransactionMessage *originalTransaction; @property(nonatomic, strong, nullable) NSNumber *transactionTimeStamp; @property(nonatomic, copy, nullable) NSString *transactionIdentifier; -@property(nonatomic, strong, nullable) SKErrorMessage *error; +@property(nonatomic, strong, nullable) FIASKErrorMessage *error; @end -@interface SKPaymentMessage : NSObject +@interface FIASKPaymentMessage : NSObject /// `init` unavailable to enforce nonnull fields, see the `make` class method. - (instancetype)init NS_UNAVAILABLE; + (instancetype)makeWithProductIdentifier:(NSString *)productIdentifier @@ -131,16 +131,16 @@ typedef NS_ENUM(NSUInteger, SKSubscriptionPeriodUnitMessage) { requestData:(nullable NSString *)requestData quantity:(NSInteger)quantity simulatesAskToBuyInSandbox:(BOOL)simulatesAskToBuyInSandbox - paymentDiscount:(nullable SKPaymentDiscountMessage *)paymentDiscount; + paymentDiscount:(nullable FIASKPaymentDiscountMessage *)paymentDiscount; @property(nonatomic, copy) NSString *productIdentifier; @property(nonatomic, copy, nullable) NSString *applicationUsername; @property(nonatomic, copy, nullable) NSString *requestData; @property(nonatomic, assign) NSInteger quantity; @property(nonatomic, assign) BOOL simulatesAskToBuyInSandbox; -@property(nonatomic, strong, nullable) SKPaymentDiscountMessage *paymentDiscount; +@property(nonatomic, strong, nullable) FIASKPaymentDiscountMessage *paymentDiscount; @end -@interface SKErrorMessage : NSObject +@interface FIASKErrorMessage : NSObject /// `init` unavailable to enforce nonnull fields, see the `make` class method. - (instancetype)init NS_UNAVAILABLE; + (instancetype)makeWithCode:(NSInteger)code @@ -151,7 +151,7 @@ typedef NS_ENUM(NSUInteger, SKSubscriptionPeriodUnitMessage) { @property(nonatomic, copy, nullable) NSDictionary *userInfo; @end -@interface SKPaymentDiscountMessage : NSObject +@interface FIASKPaymentDiscountMessage : NSObject /// `init` unavailable to enforce nonnull fields, see the `make` class method. - (instancetype)init NS_UNAVAILABLE; + (instancetype)makeWithIdentifier:(NSString *)identifier @@ -166,7 +166,7 @@ typedef NS_ENUM(NSUInteger, SKSubscriptionPeriodUnitMessage) { @property(nonatomic, assign) NSInteger timestamp; @end -@interface SKStorefrontMessage : NSObject +@interface FIASKStorefrontMessage : NSObject /// `init` unavailable to enforce nonnull fields, see the `make` class method. - (instancetype)init NS_UNAVAILABLE; + (instancetype)makeWithCountryCode:(NSString *)countryCode identifier:(NSString *)identifier; @@ -174,38 +174,38 @@ typedef NS_ENUM(NSUInteger, SKSubscriptionPeriodUnitMessage) { @property(nonatomic, copy) NSString *identifier; @end -@interface SKProductsResponseMessage : NSObject -+ (instancetype)makeWithProducts:(nullable NSArray *)products +@interface FIASKProductsResponseMessage : NSObject ++ (instancetype)makeWithProducts:(nullable NSArray *)products invalidProductIdentifiers:(nullable NSArray *)invalidProductIdentifiers; -@property(nonatomic, copy, nullable) NSArray *products; +@property(nonatomic, copy, nullable) NSArray *products; @property(nonatomic, copy, nullable) NSArray *invalidProductIdentifiers; @end -@interface SKProductMessage : NSObject +@interface FIASKProductMessage : NSObject /// `init` unavailable to enforce nonnull fields, see the `make` class method. - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)makeWithProductIdentifier:(NSString *)productIdentifier - localizedTitle:(NSString *)localizedTitle - localizedDescription:(NSString *)localizedDescription - priceLocale:(SKPriceLocaleMessage *)priceLocale - subscriptionGroupIdentifier:(nullable NSString *)subscriptionGroupIdentifier - price:(NSString *)price - subscriptionPeriod: - (nullable SKProductSubscriptionPeriodMessage *)subscriptionPeriod - introductoryPrice:(nullable SKProductDiscountMessage *)introductoryPrice - discounts:(nullable NSArray *)discounts; ++ (instancetype) + makeWithProductIdentifier:(NSString *)productIdentifier + localizedTitle:(NSString *)localizedTitle + localizedDescription:(nullable NSString *)localizedDescription + priceLocale:(FIASKPriceLocaleMessage *)priceLocale + subscriptionGroupIdentifier:(nullable NSString *)subscriptionGroupIdentifier + price:(NSString *)price + subscriptionPeriod:(nullable FIASKProductSubscriptionPeriodMessage *)subscriptionPeriod + introductoryPrice:(nullable FIASKProductDiscountMessage *)introductoryPrice + discounts:(nullable NSArray *)discounts; @property(nonatomic, copy) NSString *productIdentifier; @property(nonatomic, copy) NSString *localizedTitle; -@property(nonatomic, copy) NSString *localizedDescription; -@property(nonatomic, strong) SKPriceLocaleMessage *priceLocale; +@property(nonatomic, copy, nullable) NSString *localizedDescription; +@property(nonatomic, strong) FIASKPriceLocaleMessage *priceLocale; @property(nonatomic, copy, nullable) NSString *subscriptionGroupIdentifier; @property(nonatomic, copy) NSString *price; -@property(nonatomic, strong, nullable) SKProductSubscriptionPeriodMessage *subscriptionPeriod; -@property(nonatomic, strong, nullable) SKProductDiscountMessage *introductoryPrice; -@property(nonatomic, copy, nullable) NSArray *discounts; +@property(nonatomic, strong, nullable) FIASKProductSubscriptionPeriodMessage *subscriptionPeriod; +@property(nonatomic, strong, nullable) FIASKProductDiscountMessage *introductoryPrice; +@property(nonatomic, copy, nullable) NSArray *discounts; @end -@interface SKPriceLocaleMessage : NSObject +@interface FIASKPriceLocaleMessage : NSObject /// `init` unavailable to enforce nonnull fields, see the `make` class method. - (instancetype)init NS_UNAVAILABLE; + (instancetype)makeWithCurrencySymbol:(NSString *)currencySymbol @@ -219,51 +219,51 @@ typedef NS_ENUM(NSUInteger, SKSubscriptionPeriodUnitMessage) { @property(nonatomic, copy) NSString *countryCode; @end -@interface SKProductDiscountMessage : NSObject +@interface FIASKProductDiscountMessage : NSObject /// `init` unavailable to enforce nonnull fields, see the `make` class method. - (instancetype)init NS_UNAVAILABLE; + (instancetype)makeWithPrice:(NSString *)price - priceLocale:(SKPriceLocaleMessage *)priceLocale + priceLocale:(FIASKPriceLocaleMessage *)priceLocale numberOfPeriods:(NSInteger)numberOfPeriods - paymentMode:(SKProductDiscountPaymentModeMessage)paymentMode - subscriptionPeriod:(SKProductSubscriptionPeriodMessage *)subscriptionPeriod + paymentMode:(FIASKProductDiscountPaymentModeMessage)paymentMode + subscriptionPeriod:(FIASKProductSubscriptionPeriodMessage *)subscriptionPeriod identifier:(nullable NSString *)identifier - type:(SKProductDiscountTypeMessage)type; + type:(FIASKProductDiscountTypeMessage)type; @property(nonatomic, copy) NSString *price; -@property(nonatomic, strong) SKPriceLocaleMessage *priceLocale; +@property(nonatomic, strong) FIASKPriceLocaleMessage *priceLocale; @property(nonatomic, assign) NSInteger numberOfPeriods; -@property(nonatomic, assign) SKProductDiscountPaymentModeMessage paymentMode; -@property(nonatomic, strong) SKProductSubscriptionPeriodMessage *subscriptionPeriod; +@property(nonatomic, assign) FIASKProductDiscountPaymentModeMessage paymentMode; +@property(nonatomic, strong) FIASKProductSubscriptionPeriodMessage *subscriptionPeriod; @property(nonatomic, copy, nullable) NSString *identifier; -@property(nonatomic, assign) SKProductDiscountTypeMessage type; +@property(nonatomic, assign) FIASKProductDiscountTypeMessage type; @end -@interface SKProductSubscriptionPeriodMessage : NSObject +@interface FIASKProductSubscriptionPeriodMessage : NSObject /// `init` unavailable to enforce nonnull fields, see the `make` class method. - (instancetype)init NS_UNAVAILABLE; + (instancetype)makeWithNumberOfUnits:(NSInteger)numberOfUnits - unit:(SKSubscriptionPeriodUnitMessage)unit; + unit:(FIASKSubscriptionPeriodUnitMessage)unit; @property(nonatomic, assign) NSInteger numberOfUnits; -@property(nonatomic, assign) SKSubscriptionPeriodUnitMessage unit; +@property(nonatomic, assign) FIASKSubscriptionPeriodUnitMessage unit; @end -/// The codec used by InAppPurchaseAPI. -NSObject *InAppPurchaseAPIGetCodec(void); +/// The codec used by all APIs. +NSObject *FIAGetMessagesCodec(void); -@protocol InAppPurchaseAPI +@protocol FIAInAppPurchaseAPI /// Returns if the current device is able to make payments /// /// @return `nil` only when `error != nil`. - (nullable NSNumber *)canMakePaymentsWithError:(FlutterError *_Nullable *_Nonnull)error; /// @return `nil` only when `error != nil`. -- (nullable NSArray *)transactionsWithError: +- (nullable NSArray *)transactionsWithError: (FlutterError *_Nullable *_Nonnull)error; /// @return `nil` only when `error != nil`. -- (nullable SKStorefrontMessage *)storefrontWithError:(FlutterError *_Nullable *_Nonnull)error; +- (nullable FIASKStorefrontMessage *)storefrontWithError:(FlutterError *_Nullable *_Nonnull)error; - (void)addPaymentPaymentMap:(NSDictionary *)paymentMap error:(FlutterError *_Nullable *_Nonnull)error; - (void)startProductRequestProductIdentifiers:(NSArray *)productIdentifiers - completion:(void (^)(SKProductsResponseMessage *_Nullable, + completion:(void (^)(FIASKProductsResponseMessage *_Nullable, FlutterError *_Nullable))completion; - (void)finishTransactionFinishMap:(NSDictionary *)finishMap error:(FlutterError *_Nullable *_Nonnull)error; @@ -280,7 +280,11 @@ NSObject *InAppPurchaseAPIGetCodec(void); - (void)showPriceConsentIfNeededWithError:(FlutterError *_Nullable *_Nonnull)error; @end -extern void SetUpInAppPurchaseAPI(id binaryMessenger, - NSObject *_Nullable api); +extern void SetUpFIAInAppPurchaseAPI(id binaryMessenger, + NSObject *_Nullable api); + +extern void SetUpFIAInAppPurchaseAPIWithSuffix(id binaryMessenger, + NSObject *_Nullable api, + NSString *messageChannelSuffix); NS_ASSUME_NONNULL_END diff --git a/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/messages.g.m b/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/messages.g.m index f013f720511c..62988eb04fee 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/messages.g.m +++ b/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/messages.g.m @@ -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.4), do not edit directly. +// Autogenerated from Pigeon (v22.4.2), do not edit directly. // See also: https://pub.dev/packages/pigeon #import "messages.g.h" @@ -16,7 +16,7 @@ #error File requires ARC to be enabled. #endif -static NSArray *wrapResult(id result, FlutterError *error) { +static NSArray *wrapResult(id result, FlutterError *error) { if (error) { return @[ error.code ?: [NSNull null], error.message ?: [NSNull null], error.details ?: [NSNull null] @@ -25,13 +25,13 @@ return @[ result ?: [NSNull null] ]; } -static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) { +static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) { id result = array[key]; return (result == [NSNull null]) ? nil : result; } -@implementation SKPaymentTransactionStateMessageBox -- (instancetype)initWithValue:(SKPaymentTransactionStateMessage)value { +@implementation FIASKPaymentTransactionStateMessageBox +- (instancetype)initWithValue:(FIASKPaymentTransactionStateMessage)value { self = [super init]; if (self) { _value = value; @@ -40,8 +40,8 @@ - (instancetype)initWithValue:(SKPaymentTransactionStateMessage)value { } @end -@implementation SKProductDiscountTypeMessageBox -- (instancetype)initWithValue:(SKProductDiscountTypeMessage)value { +@implementation FIASKProductDiscountTypeMessageBox +- (instancetype)initWithValue:(FIASKProductDiscountTypeMessage)value { self = [super init]; if (self) { _value = value; @@ -50,8 +50,8 @@ - (instancetype)initWithValue:(SKProductDiscountTypeMessage)value { } @end -@implementation SKProductDiscountPaymentModeMessageBox -- (instancetype)initWithValue:(SKProductDiscountPaymentModeMessage)value { +@implementation FIASKProductDiscountPaymentModeMessageBox +- (instancetype)initWithValue:(FIASKProductDiscountPaymentModeMessage)value { self = [super init]; if (self) { _value = value; @@ -60,8 +60,8 @@ - (instancetype)initWithValue:(SKProductDiscountPaymentModeMessage)value { } @end -@implementation SKSubscriptionPeriodUnitMessageBox -- (instancetype)initWithValue:(SKSubscriptionPeriodUnitMessage)value { +@implementation FIASKSubscriptionPeriodUnitMessageBox +- (instancetype)initWithValue:(FIASKSubscriptionPeriodUnitMessage)value { self = [super init]; if (self) { _value = value; @@ -70,74 +70,74 @@ - (instancetype)initWithValue:(SKSubscriptionPeriodUnitMessage)value { } @end -@interface SKPaymentTransactionMessage () -+ (SKPaymentTransactionMessage *)fromList:(NSArray *)list; -+ (nullable SKPaymentTransactionMessage *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; +@interface FIASKPaymentTransactionMessage () ++ (FIASKPaymentTransactionMessage *)fromList:(NSArray *)list; ++ (nullable FIASKPaymentTransactionMessage *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; @end -@interface SKPaymentMessage () -+ (SKPaymentMessage *)fromList:(NSArray *)list; -+ (nullable SKPaymentMessage *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; +@interface FIASKPaymentMessage () ++ (FIASKPaymentMessage *)fromList:(NSArray *)list; ++ (nullable FIASKPaymentMessage *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; @end -@interface SKErrorMessage () -+ (SKErrorMessage *)fromList:(NSArray *)list; -+ (nullable SKErrorMessage *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; +@interface FIASKErrorMessage () ++ (FIASKErrorMessage *)fromList:(NSArray *)list; ++ (nullable FIASKErrorMessage *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; @end -@interface SKPaymentDiscountMessage () -+ (SKPaymentDiscountMessage *)fromList:(NSArray *)list; -+ (nullable SKPaymentDiscountMessage *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; +@interface FIASKPaymentDiscountMessage () ++ (FIASKPaymentDiscountMessage *)fromList:(NSArray *)list; ++ (nullable FIASKPaymentDiscountMessage *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; @end -@interface SKStorefrontMessage () -+ (SKStorefrontMessage *)fromList:(NSArray *)list; -+ (nullable SKStorefrontMessage *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; +@interface FIASKStorefrontMessage () ++ (FIASKStorefrontMessage *)fromList:(NSArray *)list; ++ (nullable FIASKStorefrontMessage *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; @end -@interface SKProductsResponseMessage () -+ (SKProductsResponseMessage *)fromList:(NSArray *)list; -+ (nullable SKProductsResponseMessage *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; +@interface FIASKProductsResponseMessage () ++ (FIASKProductsResponseMessage *)fromList:(NSArray *)list; ++ (nullable FIASKProductsResponseMessage *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; @end -@interface SKProductMessage () -+ (SKProductMessage *)fromList:(NSArray *)list; -+ (nullable SKProductMessage *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; +@interface FIASKProductMessage () ++ (FIASKProductMessage *)fromList:(NSArray *)list; ++ (nullable FIASKProductMessage *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; @end -@interface SKPriceLocaleMessage () -+ (SKPriceLocaleMessage *)fromList:(NSArray *)list; -+ (nullable SKPriceLocaleMessage *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; +@interface FIASKPriceLocaleMessage () ++ (FIASKPriceLocaleMessage *)fromList:(NSArray *)list; ++ (nullable FIASKPriceLocaleMessage *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; @end -@interface SKProductDiscountMessage () -+ (SKProductDiscountMessage *)fromList:(NSArray *)list; -+ (nullable SKProductDiscountMessage *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; +@interface FIASKProductDiscountMessage () ++ (FIASKProductDiscountMessage *)fromList:(NSArray *)list; ++ (nullable FIASKProductDiscountMessage *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; @end -@interface SKProductSubscriptionPeriodMessage () -+ (SKProductSubscriptionPeriodMessage *)fromList:(NSArray *)list; -+ (nullable SKProductSubscriptionPeriodMessage *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; +@interface FIASKProductSubscriptionPeriodMessage () ++ (FIASKProductSubscriptionPeriodMessage *)fromList:(NSArray *)list; ++ (nullable FIASKProductSubscriptionPeriodMessage *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; @end -@implementation SKPaymentTransactionMessage -+ (instancetype)makeWithPayment:(SKPaymentMessage *)payment - transactionState:(SKPaymentTransactionStateMessage)transactionState - originalTransaction:(nullable SKPaymentTransactionMessage *)originalTransaction +@implementation FIASKPaymentTransactionMessage ++ (instancetype)makeWithPayment:(FIASKPaymentMessage *)payment + transactionState:(FIASKPaymentTransactionStateMessage)transactionState + originalTransaction:(nullable FIASKPaymentTransactionMessage *)originalTransaction transactionTimeStamp:(nullable NSNumber *)transactionTimeStamp transactionIdentifier:(nullable NSString *)transactionIdentifier - error:(nullable SKErrorMessage *)error { - SKPaymentTransactionMessage *pigeonResult = [[SKPaymentTransactionMessage alloc] init]; + error:(nullable FIASKErrorMessage *)error { + FIASKPaymentTransactionMessage *pigeonResult = [[FIASKPaymentTransactionMessage alloc] init]; pigeonResult.payment = payment; pigeonResult.transactionState = transactionState; pigeonResult.originalTransaction = originalTransaction; @@ -146,40 +146,41 @@ + (instancetype)makeWithPayment:(SKPaymentMessage *)payment pigeonResult.error = error; return pigeonResult; } -+ (SKPaymentTransactionMessage *)fromList:(NSArray *)list { - SKPaymentTransactionMessage *pigeonResult = [[SKPaymentTransactionMessage alloc] init]; - pigeonResult.payment = [SKPaymentMessage nullableFromList:(GetNullableObjectAtIndex(list, 0))]; - pigeonResult.transactionState = [GetNullableObjectAtIndex(list, 1) integerValue]; - pigeonResult.originalTransaction = - [SKPaymentTransactionMessage nullableFromList:(GetNullableObjectAtIndex(list, 2))]; ++ (FIASKPaymentTransactionMessage *)fromList:(NSArray *)list { + FIASKPaymentTransactionMessage *pigeonResult = [[FIASKPaymentTransactionMessage alloc] init]; + pigeonResult.payment = GetNullableObjectAtIndex(list, 0); + FIASKPaymentTransactionStateMessageBox *boxedFIASKPaymentTransactionStateMessage = + GetNullableObjectAtIndex(list, 1); + pigeonResult.transactionState = boxedFIASKPaymentTransactionStateMessage.value; + pigeonResult.originalTransaction = GetNullableObjectAtIndex(list, 2); pigeonResult.transactionTimeStamp = GetNullableObjectAtIndex(list, 3); pigeonResult.transactionIdentifier = GetNullableObjectAtIndex(list, 4); - pigeonResult.error = [SKErrorMessage nullableFromList:(GetNullableObjectAtIndex(list, 5))]; + pigeonResult.error = GetNullableObjectAtIndex(list, 5); return pigeonResult; } -+ (nullable SKPaymentTransactionMessage *)nullableFromList:(NSArray *)list { - return (list) ? [SKPaymentTransactionMessage fromList:list] : nil; ++ (nullable FIASKPaymentTransactionMessage *)nullableFromList:(NSArray *)list { + return (list) ? [FIASKPaymentTransactionMessage fromList:list] : nil; } -- (NSArray *)toList { +- (NSArray *)toList { return @[ - (self.payment ? [self.payment toList] : [NSNull null]), - @(self.transactionState), - (self.originalTransaction ? [self.originalTransaction toList] : [NSNull null]), + self.payment ?: [NSNull null], + [[FIASKPaymentTransactionStateMessageBox alloc] initWithValue:self.transactionState], + self.originalTransaction ?: [NSNull null], self.transactionTimeStamp ?: [NSNull null], self.transactionIdentifier ?: [NSNull null], - (self.error ? [self.error toList] : [NSNull null]), + self.error ?: [NSNull null], ]; } @end -@implementation SKPaymentMessage +@implementation FIASKPaymentMessage + (instancetype)makeWithProductIdentifier:(NSString *)productIdentifier applicationUsername:(nullable NSString *)applicationUsername requestData:(nullable NSString *)requestData quantity:(NSInteger)quantity simulatesAskToBuyInSandbox:(BOOL)simulatesAskToBuyInSandbox - paymentDiscount:(nullable SKPaymentDiscountMessage *)paymentDiscount { - SKPaymentMessage *pigeonResult = [[SKPaymentMessage alloc] init]; + paymentDiscount:(nullable FIASKPaymentDiscountMessage *)paymentDiscount { + FIASKPaymentMessage *pigeonResult = [[FIASKPaymentMessage alloc] init]; pigeonResult.productIdentifier = productIdentifier; pigeonResult.applicationUsername = applicationUsername; pigeonResult.requestData = requestData; @@ -188,53 +189,52 @@ + (instancetype)makeWithProductIdentifier:(NSString *)productIdentifier pigeonResult.paymentDiscount = paymentDiscount; return pigeonResult; } -+ (SKPaymentMessage *)fromList:(NSArray *)list { - SKPaymentMessage *pigeonResult = [[SKPaymentMessage alloc] init]; ++ (FIASKPaymentMessage *)fromList:(NSArray *)list { + FIASKPaymentMessage *pigeonResult = [[FIASKPaymentMessage alloc] init]; pigeonResult.productIdentifier = GetNullableObjectAtIndex(list, 0); pigeonResult.applicationUsername = GetNullableObjectAtIndex(list, 1); pigeonResult.requestData = GetNullableObjectAtIndex(list, 2); pigeonResult.quantity = [GetNullableObjectAtIndex(list, 3) integerValue]; pigeonResult.simulatesAskToBuyInSandbox = [GetNullableObjectAtIndex(list, 4) boolValue]; - pigeonResult.paymentDiscount = - [SKPaymentDiscountMessage nullableFromList:(GetNullableObjectAtIndex(list, 5))]; + pigeonResult.paymentDiscount = GetNullableObjectAtIndex(list, 5); return pigeonResult; } -+ (nullable SKPaymentMessage *)nullableFromList:(NSArray *)list { - return (list) ? [SKPaymentMessage fromList:list] : nil; ++ (nullable FIASKPaymentMessage *)nullableFromList:(NSArray *)list { + return (list) ? [FIASKPaymentMessage fromList:list] : nil; } -- (NSArray *)toList { +- (NSArray *)toList { return @[ self.productIdentifier ?: [NSNull null], self.applicationUsername ?: [NSNull null], self.requestData ?: [NSNull null], @(self.quantity), @(self.simulatesAskToBuyInSandbox), - (self.paymentDiscount ? [self.paymentDiscount toList] : [NSNull null]), + self.paymentDiscount ?: [NSNull null], ]; } @end -@implementation SKErrorMessage +@implementation FIASKErrorMessage + (instancetype)makeWithCode:(NSInteger)code domain:(NSString *)domain userInfo:(nullable NSDictionary *)userInfo { - SKErrorMessage *pigeonResult = [[SKErrorMessage alloc] init]; + FIASKErrorMessage *pigeonResult = [[FIASKErrorMessage alloc] init]; pigeonResult.code = code; pigeonResult.domain = domain; pigeonResult.userInfo = userInfo; return pigeonResult; } -+ (SKErrorMessage *)fromList:(NSArray *)list { - SKErrorMessage *pigeonResult = [[SKErrorMessage alloc] init]; ++ (FIASKErrorMessage *)fromList:(NSArray *)list { + FIASKErrorMessage *pigeonResult = [[FIASKErrorMessage alloc] init]; pigeonResult.code = [GetNullableObjectAtIndex(list, 0) integerValue]; pigeonResult.domain = GetNullableObjectAtIndex(list, 1); pigeonResult.userInfo = GetNullableObjectAtIndex(list, 2); return pigeonResult; } -+ (nullable SKErrorMessage *)nullableFromList:(NSArray *)list { - return (list) ? [SKErrorMessage fromList:list] : nil; ++ (nullable FIASKErrorMessage *)nullableFromList:(NSArray *)list { + return (list) ? [FIASKErrorMessage fromList:list] : nil; } -- (NSArray *)toList { +- (NSArray *)toList { return @[ @(self.code), self.domain ?: [NSNull null], @@ -243,13 +243,13 @@ - (NSArray *)toList { } @end -@implementation SKPaymentDiscountMessage +@implementation FIASKPaymentDiscountMessage + (instancetype)makeWithIdentifier:(NSString *)identifier keyIdentifier:(NSString *)keyIdentifier nonce:(NSString *)nonce signature:(NSString *)signature timestamp:(NSInteger)timestamp { - SKPaymentDiscountMessage *pigeonResult = [[SKPaymentDiscountMessage alloc] init]; + FIASKPaymentDiscountMessage *pigeonResult = [[FIASKPaymentDiscountMessage alloc] init]; pigeonResult.identifier = identifier; pigeonResult.keyIdentifier = keyIdentifier; pigeonResult.nonce = nonce; @@ -257,8 +257,8 @@ + (instancetype)makeWithIdentifier:(NSString *)identifier pigeonResult.timestamp = timestamp; return pigeonResult; } -+ (SKPaymentDiscountMessage *)fromList:(NSArray *)list { - SKPaymentDiscountMessage *pigeonResult = [[SKPaymentDiscountMessage alloc] init]; ++ (FIASKPaymentDiscountMessage *)fromList:(NSArray *)list { + FIASKPaymentDiscountMessage *pigeonResult = [[FIASKPaymentDiscountMessage alloc] init]; pigeonResult.identifier = GetNullableObjectAtIndex(list, 0); pigeonResult.keyIdentifier = GetNullableObjectAtIndex(list, 1); pigeonResult.nonce = GetNullableObjectAtIndex(list, 2); @@ -266,10 +266,10 @@ + (SKPaymentDiscountMessage *)fromList:(NSArray *)list { pigeonResult.timestamp = [GetNullableObjectAtIndex(list, 4) integerValue]; return pigeonResult; } -+ (nullable SKPaymentDiscountMessage *)nullableFromList:(NSArray *)list { - return (list) ? [SKPaymentDiscountMessage fromList:list] : nil; ++ (nullable FIASKPaymentDiscountMessage *)nullableFromList:(NSArray *)list { + return (list) ? [FIASKPaymentDiscountMessage fromList:list] : nil; } -- (NSArray *)toList { +- (NSArray *)toList { return @[ self.identifier ?: [NSNull null], self.keyIdentifier ?: [NSNull null], @@ -280,23 +280,23 @@ - (NSArray *)toList { } @end -@implementation SKStorefrontMessage +@implementation FIASKStorefrontMessage + (instancetype)makeWithCountryCode:(NSString *)countryCode identifier:(NSString *)identifier { - SKStorefrontMessage *pigeonResult = [[SKStorefrontMessage alloc] init]; + FIASKStorefrontMessage *pigeonResult = [[FIASKStorefrontMessage alloc] init]; pigeonResult.countryCode = countryCode; pigeonResult.identifier = identifier; return pigeonResult; } -+ (SKStorefrontMessage *)fromList:(NSArray *)list { - SKStorefrontMessage *pigeonResult = [[SKStorefrontMessage alloc] init]; ++ (FIASKStorefrontMessage *)fromList:(NSArray *)list { + FIASKStorefrontMessage *pigeonResult = [[FIASKStorefrontMessage alloc] init]; pigeonResult.countryCode = GetNullableObjectAtIndex(list, 0); pigeonResult.identifier = GetNullableObjectAtIndex(list, 1); return pigeonResult; } -+ (nullable SKStorefrontMessage *)nullableFromList:(NSArray *)list { - return (list) ? [SKStorefrontMessage fromList:list] : nil; ++ (nullable FIASKStorefrontMessage *)nullableFromList:(NSArray *)list { + return (list) ? [FIASKStorefrontMessage fromList:list] : nil; } -- (NSArray *)toList { +- (NSArray *)toList { return @[ self.countryCode ?: [NSNull null], self.identifier ?: [NSNull null], @@ -304,24 +304,24 @@ - (NSArray *)toList { } @end -@implementation SKProductsResponseMessage -+ (instancetype)makeWithProducts:(nullable NSArray *)products +@implementation FIASKProductsResponseMessage ++ (instancetype)makeWithProducts:(nullable NSArray *)products invalidProductIdentifiers:(nullable NSArray *)invalidProductIdentifiers { - SKProductsResponseMessage *pigeonResult = [[SKProductsResponseMessage alloc] init]; + FIASKProductsResponseMessage *pigeonResult = [[FIASKProductsResponseMessage alloc] init]; pigeonResult.products = products; pigeonResult.invalidProductIdentifiers = invalidProductIdentifiers; return pigeonResult; } -+ (SKProductsResponseMessage *)fromList:(NSArray *)list { - SKProductsResponseMessage *pigeonResult = [[SKProductsResponseMessage alloc] init]; ++ (FIASKProductsResponseMessage *)fromList:(NSArray *)list { + FIASKProductsResponseMessage *pigeonResult = [[FIASKProductsResponseMessage alloc] init]; pigeonResult.products = GetNullableObjectAtIndex(list, 0); pigeonResult.invalidProductIdentifiers = GetNullableObjectAtIndex(list, 1); return pigeonResult; } -+ (nullable SKProductsResponseMessage *)nullableFromList:(NSArray *)list { - return (list) ? [SKProductsResponseMessage fromList:list] : nil; ++ (nullable FIASKProductsResponseMessage *)nullableFromList:(NSArray *)list { + return (list) ? [FIASKProductsResponseMessage fromList:list] : nil; } -- (NSArray *)toList { +- (NSArray *)toList { return @[ self.products ?: [NSNull null], self.invalidProductIdentifiers ?: [NSNull null], @@ -329,18 +329,18 @@ - (NSArray *)toList { } @end -@implementation SKProductMessage +@implementation FIASKProductMessage + (instancetype) makeWithProductIdentifier:(NSString *)productIdentifier localizedTitle:(NSString *)localizedTitle - localizedDescription:(NSString *)localizedDescription - priceLocale:(SKPriceLocaleMessage *)priceLocale + localizedDescription:(nullable NSString *)localizedDescription + priceLocale:(FIASKPriceLocaleMessage *)priceLocale subscriptionGroupIdentifier:(nullable NSString *)subscriptionGroupIdentifier price:(NSString *)price - subscriptionPeriod:(nullable SKProductSubscriptionPeriodMessage *)subscriptionPeriod - introductoryPrice:(nullable SKProductDiscountMessage *)introductoryPrice - discounts:(nullable NSArray *)discounts { - SKProductMessage *pigeonResult = [[SKProductMessage alloc] init]; + subscriptionPeriod:(nullable FIASKProductSubscriptionPeriodMessage *)subscriptionPeriod + introductoryPrice:(nullable FIASKProductDiscountMessage *)introductoryPrice + discounts:(nullable NSArray *)discounts { + FIASKProductMessage *pigeonResult = [[FIASKProductMessage alloc] init]; pigeonResult.productIdentifier = productIdentifier; pigeonResult.localizedTitle = localizedTitle; pigeonResult.localizedDescription = localizedDescription; @@ -352,61 +352,58 @@ @implementation SKProductMessage pigeonResult.discounts = discounts; return pigeonResult; } -+ (SKProductMessage *)fromList:(NSArray *)list { - SKProductMessage *pigeonResult = [[SKProductMessage alloc] init]; ++ (FIASKProductMessage *)fromList:(NSArray *)list { + FIASKProductMessage *pigeonResult = [[FIASKProductMessage alloc] init]; pigeonResult.productIdentifier = GetNullableObjectAtIndex(list, 0); pigeonResult.localizedTitle = GetNullableObjectAtIndex(list, 1); pigeonResult.localizedDescription = GetNullableObjectAtIndex(list, 2); - pigeonResult.priceLocale = - [SKPriceLocaleMessage nullableFromList:(GetNullableObjectAtIndex(list, 3))]; + pigeonResult.priceLocale = GetNullableObjectAtIndex(list, 3); pigeonResult.subscriptionGroupIdentifier = GetNullableObjectAtIndex(list, 4); pigeonResult.price = GetNullableObjectAtIndex(list, 5); - pigeonResult.subscriptionPeriod = - [SKProductSubscriptionPeriodMessage nullableFromList:(GetNullableObjectAtIndex(list, 6))]; - pigeonResult.introductoryPrice = - [SKProductDiscountMessage nullableFromList:(GetNullableObjectAtIndex(list, 7))]; + pigeonResult.subscriptionPeriod = GetNullableObjectAtIndex(list, 6); + pigeonResult.introductoryPrice = GetNullableObjectAtIndex(list, 7); pigeonResult.discounts = GetNullableObjectAtIndex(list, 8); return pigeonResult; } -+ (nullable SKProductMessage *)nullableFromList:(NSArray *)list { - return (list) ? [SKProductMessage fromList:list] : nil; ++ (nullable FIASKProductMessage *)nullableFromList:(NSArray *)list { + return (list) ? [FIASKProductMessage fromList:list] : nil; } -- (NSArray *)toList { +- (NSArray *)toList { return @[ self.productIdentifier ?: [NSNull null], self.localizedTitle ?: [NSNull null], self.localizedDescription ?: [NSNull null], - (self.priceLocale ? [self.priceLocale toList] : [NSNull null]), + self.priceLocale ?: [NSNull null], self.subscriptionGroupIdentifier ?: [NSNull null], self.price ?: [NSNull null], - (self.subscriptionPeriod ? [self.subscriptionPeriod toList] : [NSNull null]), - (self.introductoryPrice ? [self.introductoryPrice toList] : [NSNull null]), + self.subscriptionPeriod ?: [NSNull null], + self.introductoryPrice ?: [NSNull null], self.discounts ?: [NSNull null], ]; } @end -@implementation SKPriceLocaleMessage +@implementation FIASKPriceLocaleMessage + (instancetype)makeWithCurrencySymbol:(NSString *)currencySymbol currencyCode:(NSString *)currencyCode countryCode:(NSString *)countryCode { - SKPriceLocaleMessage *pigeonResult = [[SKPriceLocaleMessage alloc] init]; + FIASKPriceLocaleMessage *pigeonResult = [[FIASKPriceLocaleMessage alloc] init]; pigeonResult.currencySymbol = currencySymbol; pigeonResult.currencyCode = currencyCode; pigeonResult.countryCode = countryCode; return pigeonResult; } -+ (SKPriceLocaleMessage *)fromList:(NSArray *)list { - SKPriceLocaleMessage *pigeonResult = [[SKPriceLocaleMessage alloc] init]; ++ (FIASKPriceLocaleMessage *)fromList:(NSArray *)list { + FIASKPriceLocaleMessage *pigeonResult = [[FIASKPriceLocaleMessage alloc] init]; pigeonResult.currencySymbol = GetNullableObjectAtIndex(list, 0); pigeonResult.currencyCode = GetNullableObjectAtIndex(list, 1); pigeonResult.countryCode = GetNullableObjectAtIndex(list, 2); return pigeonResult; } -+ (nullable SKPriceLocaleMessage *)nullableFromList:(NSArray *)list { - return (list) ? [SKPriceLocaleMessage fromList:list] : nil; ++ (nullable FIASKPriceLocaleMessage *)nullableFromList:(NSArray *)list { + return (list) ? [FIASKPriceLocaleMessage fromList:list] : nil; } -- (NSArray *)toList { +- (NSArray *)toList { return @[ self.currencySymbol ?: [NSNull null], self.currencyCode ?: [NSNull null], @@ -415,15 +412,15 @@ - (NSArray *)toList { } @end -@implementation SKProductDiscountMessage +@implementation FIASKProductDiscountMessage + (instancetype)makeWithPrice:(NSString *)price - priceLocale:(SKPriceLocaleMessage *)priceLocale + priceLocale:(FIASKPriceLocaleMessage *)priceLocale numberOfPeriods:(NSInteger)numberOfPeriods - paymentMode:(SKProductDiscountPaymentModeMessage)paymentMode - subscriptionPeriod:(SKProductSubscriptionPeriodMessage *)subscriptionPeriod + paymentMode:(FIASKProductDiscountPaymentModeMessage)paymentMode + subscriptionPeriod:(FIASKProductSubscriptionPeriodMessage *)subscriptionPeriod identifier:(nullable NSString *)identifier - type:(SKProductDiscountTypeMessage)type { - SKProductDiscountMessage *pigeonResult = [[SKProductDiscountMessage alloc] init]; + type:(FIASKProductDiscountTypeMessage)type { + FIASKProductDiscountMessage *pigeonResult = [[FIASKProductDiscountMessage alloc] init]; pigeonResult.price = price; pigeonResult.priceLocale = priceLocale; pigeonResult.numberOfPeriods = numberOfPeriods; @@ -433,168 +430,223 @@ + (instancetype)makeWithPrice:(NSString *)price pigeonResult.type = type; return pigeonResult; } -+ (SKProductDiscountMessage *)fromList:(NSArray *)list { - SKProductDiscountMessage *pigeonResult = [[SKProductDiscountMessage alloc] init]; ++ (FIASKProductDiscountMessage *)fromList:(NSArray *)list { + FIASKProductDiscountMessage *pigeonResult = [[FIASKProductDiscountMessage alloc] init]; pigeonResult.price = GetNullableObjectAtIndex(list, 0); - pigeonResult.priceLocale = - [SKPriceLocaleMessage nullableFromList:(GetNullableObjectAtIndex(list, 1))]; + pigeonResult.priceLocale = GetNullableObjectAtIndex(list, 1); pigeonResult.numberOfPeriods = [GetNullableObjectAtIndex(list, 2) integerValue]; - pigeonResult.paymentMode = [GetNullableObjectAtIndex(list, 3) integerValue]; - pigeonResult.subscriptionPeriod = - [SKProductSubscriptionPeriodMessage nullableFromList:(GetNullableObjectAtIndex(list, 4))]; + FIASKProductDiscountPaymentModeMessageBox *boxedFIASKProductDiscountPaymentModeMessage = + GetNullableObjectAtIndex(list, 3); + pigeonResult.paymentMode = boxedFIASKProductDiscountPaymentModeMessage.value; + pigeonResult.subscriptionPeriod = GetNullableObjectAtIndex(list, 4); pigeonResult.identifier = GetNullableObjectAtIndex(list, 5); - pigeonResult.type = [GetNullableObjectAtIndex(list, 6) integerValue]; + FIASKProductDiscountTypeMessageBox *boxedFIASKProductDiscountTypeMessage = + GetNullableObjectAtIndex(list, 6); + pigeonResult.type = boxedFIASKProductDiscountTypeMessage.value; return pigeonResult; } -+ (nullable SKProductDiscountMessage *)nullableFromList:(NSArray *)list { - return (list) ? [SKProductDiscountMessage fromList:list] : nil; ++ (nullable FIASKProductDiscountMessage *)nullableFromList:(NSArray *)list { + return (list) ? [FIASKProductDiscountMessage fromList:list] : nil; } -- (NSArray *)toList { +- (NSArray *)toList { return @[ self.price ?: [NSNull null], - (self.priceLocale ? [self.priceLocale toList] : [NSNull null]), + self.priceLocale ?: [NSNull null], @(self.numberOfPeriods), - @(self.paymentMode), - (self.subscriptionPeriod ? [self.subscriptionPeriod toList] : [NSNull null]), + [[FIASKProductDiscountPaymentModeMessageBox alloc] initWithValue:self.paymentMode], + self.subscriptionPeriod ?: [NSNull null], self.identifier ?: [NSNull null], - @(self.type), + [[FIASKProductDiscountTypeMessageBox alloc] initWithValue:self.type], ]; } @end -@implementation SKProductSubscriptionPeriodMessage +@implementation FIASKProductSubscriptionPeriodMessage + (instancetype)makeWithNumberOfUnits:(NSInteger)numberOfUnits - unit:(SKSubscriptionPeriodUnitMessage)unit { - SKProductSubscriptionPeriodMessage *pigeonResult = - [[SKProductSubscriptionPeriodMessage alloc] init]; + unit:(FIASKSubscriptionPeriodUnitMessage)unit { + FIASKProductSubscriptionPeriodMessage *pigeonResult = + [[FIASKProductSubscriptionPeriodMessage alloc] init]; pigeonResult.numberOfUnits = numberOfUnits; pigeonResult.unit = unit; return pigeonResult; } -+ (SKProductSubscriptionPeriodMessage *)fromList:(NSArray *)list { - SKProductSubscriptionPeriodMessage *pigeonResult = - [[SKProductSubscriptionPeriodMessage alloc] init]; ++ (FIASKProductSubscriptionPeriodMessage *)fromList:(NSArray *)list { + FIASKProductSubscriptionPeriodMessage *pigeonResult = + [[FIASKProductSubscriptionPeriodMessage alloc] init]; pigeonResult.numberOfUnits = [GetNullableObjectAtIndex(list, 0) integerValue]; - pigeonResult.unit = [GetNullableObjectAtIndex(list, 1) integerValue]; + FIASKSubscriptionPeriodUnitMessageBox *boxedFIASKSubscriptionPeriodUnitMessage = + GetNullableObjectAtIndex(list, 1); + pigeonResult.unit = boxedFIASKSubscriptionPeriodUnitMessage.value; return pigeonResult; } -+ (nullable SKProductSubscriptionPeriodMessage *)nullableFromList:(NSArray *)list { - return (list) ? [SKProductSubscriptionPeriodMessage fromList:list] : nil; ++ (nullable FIASKProductSubscriptionPeriodMessage *)nullableFromList:(NSArray *)list { + return (list) ? [FIASKProductSubscriptionPeriodMessage fromList:list] : nil; } -- (NSArray *)toList { +- (NSArray *)toList { return @[ @(self.numberOfUnits), - @(self.unit), + [[FIASKSubscriptionPeriodUnitMessageBox alloc] initWithValue:self.unit], ]; } @end -@interface InAppPurchaseAPICodecReader : FlutterStandardReader +@interface FIAMessagesPigeonCodecReader : FlutterStandardReader @end -@implementation InAppPurchaseAPICodecReader +@implementation FIAMessagesPigeonCodecReader - (nullable id)readValueOfType:(UInt8)type { switch (type) { - case 128: - return [SKErrorMessage fromList:[self readValue]]; - case 129: - return [SKPaymentDiscountMessage fromList:[self readValue]]; - case 130: - return [SKPaymentMessage fromList:[self readValue]]; - case 131: - return [SKPaymentTransactionMessage fromList:[self readValue]]; - case 132: - return [SKPriceLocaleMessage fromList:[self readValue]]; + case 129: { + NSNumber *enumAsNumber = [self readValue]; + return enumAsNumber == nil ? nil + : [[FIASKPaymentTransactionStateMessageBox alloc] + initWithValue:[enumAsNumber integerValue]]; + } + case 130: { + NSNumber *enumAsNumber = [self readValue]; + return enumAsNumber == nil ? nil + : [[FIASKProductDiscountTypeMessageBox alloc] + initWithValue:[enumAsNumber integerValue]]; + } + case 131: { + NSNumber *enumAsNumber = [self readValue]; + return enumAsNumber == nil ? nil + : [[FIASKProductDiscountPaymentModeMessageBox alloc] + initWithValue:[enumAsNumber integerValue]]; + } + case 132: { + NSNumber *enumAsNumber = [self readValue]; + return enumAsNumber == nil ? nil + : [[FIASKSubscriptionPeriodUnitMessageBox alloc] + initWithValue:[enumAsNumber integerValue]]; + } case 133: - return [SKProductDiscountMessage fromList:[self readValue]]; + return [FIASKPaymentTransactionMessage fromList:[self readValue]]; case 134: - return [SKProductMessage fromList:[self readValue]]; + return [FIASKPaymentMessage fromList:[self readValue]]; case 135: - return [SKProductSubscriptionPeriodMessage fromList:[self readValue]]; + return [FIASKErrorMessage fromList:[self readValue]]; case 136: - return [SKProductsResponseMessage fromList:[self readValue]]; + return [FIASKPaymentDiscountMessage fromList:[self readValue]]; case 137: - return [SKStorefrontMessage fromList:[self readValue]]; + return [FIASKStorefrontMessage fromList:[self readValue]]; + case 138: + return [FIASKProductsResponseMessage fromList:[self readValue]]; + case 139: + return [FIASKProductMessage fromList:[self readValue]]; + case 140: + return [FIASKPriceLocaleMessage fromList:[self readValue]]; + case 141: + return [FIASKProductDiscountMessage fromList:[self readValue]]; + case 142: + return [FIASKProductSubscriptionPeriodMessage fromList:[self readValue]]; default: return [super readValueOfType:type]; } } @end -@interface InAppPurchaseAPICodecWriter : FlutterStandardWriter +@interface FIAMessagesPigeonCodecWriter : FlutterStandardWriter @end -@implementation InAppPurchaseAPICodecWriter +@implementation FIAMessagesPigeonCodecWriter - (void)writeValue:(id)value { - if ([value isKindOfClass:[SKErrorMessage class]]) { - [self writeByte:128]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[SKPaymentDiscountMessage class]]) { + if ([value isKindOfClass:[FIASKPaymentTransactionStateMessageBox class]]) { + FIASKPaymentTransactionStateMessageBox *box = (FIASKPaymentTransactionStateMessageBox *)value; [self writeByte:129]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[SKPaymentMessage class]]) { + [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; + } else if ([value isKindOfClass:[FIASKProductDiscountTypeMessageBox class]]) { + FIASKProductDiscountTypeMessageBox *box = (FIASKProductDiscountTypeMessageBox *)value; [self writeByte:130]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[SKPaymentTransactionMessage class]]) { + [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; + } else if ([value isKindOfClass:[FIASKProductDiscountPaymentModeMessageBox class]]) { + FIASKProductDiscountPaymentModeMessageBox *box = + (FIASKProductDiscountPaymentModeMessageBox *)value; [self writeByte:131]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[SKPriceLocaleMessage class]]) { + [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; + } else if ([value isKindOfClass:[FIASKSubscriptionPeriodUnitMessageBox class]]) { + FIASKSubscriptionPeriodUnitMessageBox *box = (FIASKSubscriptionPeriodUnitMessageBox *)value; [self writeByte:132]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[SKProductDiscountMessage class]]) { + [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; + } else if ([value isKindOfClass:[FIASKPaymentTransactionMessage class]]) { [self writeByte:133]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[SKProductMessage class]]) { + } else if ([value isKindOfClass:[FIASKPaymentMessage class]]) { [self writeByte:134]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[SKProductSubscriptionPeriodMessage class]]) { + } else if ([value isKindOfClass:[FIASKErrorMessage class]]) { [self writeByte:135]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[SKProductsResponseMessage class]]) { + } else if ([value isKindOfClass:[FIASKPaymentDiscountMessage class]]) { [self writeByte:136]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[SKStorefrontMessage class]]) { + } else if ([value isKindOfClass:[FIASKStorefrontMessage class]]) { [self writeByte:137]; [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FIASKProductsResponseMessage class]]) { + [self writeByte:138]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FIASKProductMessage class]]) { + [self writeByte:139]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FIASKPriceLocaleMessage class]]) { + [self writeByte:140]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FIASKProductDiscountMessage class]]) { + [self writeByte:141]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FIASKProductSubscriptionPeriodMessage class]]) { + [self writeByte:142]; + [self writeValue:[value toList]]; } else { [super writeValue:value]; } } @end -@interface InAppPurchaseAPICodecReaderWriter : FlutterStandardReaderWriter +@interface FIAMessagesPigeonCodecReaderWriter : FlutterStandardReaderWriter @end -@implementation InAppPurchaseAPICodecReaderWriter +@implementation FIAMessagesPigeonCodecReaderWriter - (FlutterStandardWriter *)writerWithData:(NSMutableData *)data { - return [[InAppPurchaseAPICodecWriter alloc] initWithData:data]; + return [[FIAMessagesPigeonCodecWriter alloc] initWithData:data]; } - (FlutterStandardReader *)readerWithData:(NSData *)data { - return [[InAppPurchaseAPICodecReader alloc] initWithData:data]; + return [[FIAMessagesPigeonCodecReader alloc] initWithData:data]; } @end -NSObject *InAppPurchaseAPIGetCodec(void) { +NSObject *FIAGetMessagesCodec(void) { static FlutterStandardMessageCodec *sSharedObject = nil; static dispatch_once_t sPred = 0; dispatch_once(&sPred, ^{ - InAppPurchaseAPICodecReaderWriter *readerWriter = - [[InAppPurchaseAPICodecReaderWriter alloc] init]; + FIAMessagesPigeonCodecReaderWriter *readerWriter = + [[FIAMessagesPigeonCodecReaderWriter alloc] init]; sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter]; }); return sSharedObject; } +void SetUpFIAInAppPurchaseAPI(id binaryMessenger, + NSObject *api) { + SetUpFIAInAppPurchaseAPIWithSuffix(binaryMessenger, api, @""); +} -void SetUpInAppPurchaseAPI(id binaryMessenger, - NSObject *api) { +void SetUpFIAInAppPurchaseAPIWithSuffix(id binaryMessenger, + NSObject *api, + NSString *messageChannelSuffix) { + messageChannelSuffix = messageChannelSuffix.length > 0 + ? [NSString stringWithFormat:@".%@", messageChannelSuffix] + : @""; /// Returns if the current device is able to make payments { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.canMakePayments" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.in_app_purchase_storekit." + @"InAppPurchaseAPI.canMakePayments", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:InAppPurchaseAPIGetCodec()]; + codec:FIAGetMessagesCodec()]; if (api) { NSCAssert( [api respondsToSelector:@selector(canMakePaymentsWithError:)], - @"InAppPurchaseAPI api (%@) doesn't respond to @selector(canMakePaymentsWithError:)", + @"FIAInAppPurchaseAPI api (%@) doesn't respond to @selector(canMakePaymentsWithError:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { FlutterError *error; @@ -607,16 +659,20 @@ void SetUpInAppPurchaseAPI(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.transactions" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.in_app_purchase_storekit." + @"InAppPurchaseAPI.transactions", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:InAppPurchaseAPIGetCodec()]; + codec:FIAGetMessagesCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(transactionsWithError:)], - @"InAppPurchaseAPI api (%@) doesn't respond to @selector(transactionsWithError:)", - api); + NSCAssert( + [api respondsToSelector:@selector(transactionsWithError:)], + @"FIAInAppPurchaseAPI api (%@) doesn't respond to @selector(transactionsWithError:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { FlutterError *error; - NSArray *output = [api transactionsWithError:&error]; + NSArray *output = [api transactionsWithError:&error]; callback(wrapResult(output, error)); }]; } else { @@ -625,16 +681,19 @@ void SetUpInAppPurchaseAPI(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.storefront" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.in_app_purchase_storekit." + @"InAppPurchaseAPI.storefront", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:InAppPurchaseAPIGetCodec()]; + codec:FIAGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(storefrontWithError:)], - @"InAppPurchaseAPI api (%@) doesn't respond to @selector(storefrontWithError:)", + @"FIAInAppPurchaseAPI api (%@) doesn't respond to @selector(storefrontWithError:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { FlutterError *error; - SKStorefrontMessage *output = [api storefrontWithError:&error]; + FIASKStorefrontMessage *output = [api storefrontWithError:&error]; callback(wrapResult(output, error)); }]; } else { @@ -643,16 +702,19 @@ void SetUpInAppPurchaseAPI(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.addPayment" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.in_app_purchase_storekit." + @"InAppPurchaseAPI.addPayment", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:InAppPurchaseAPIGetCodec()]; + codec:FIAGetMessagesCodec()]; if (api) { NSCAssert( [api respondsToSelector:@selector(addPaymentPaymentMap:error:)], - @"InAppPurchaseAPI api (%@) doesn't respond to @selector(addPaymentPaymentMap:error:)", + @"FIAInAppPurchaseAPI api (%@) doesn't respond to @selector(addPaymentPaymentMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; NSDictionary *arg_paymentMap = GetNullableObjectAtIndex(args, 0); FlutterError *error; [api addPaymentPaymentMap:arg_paymentMap error:&error]; @@ -664,21 +726,23 @@ void SetUpInAppPurchaseAPI(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.startProductRequest" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.in_app_purchase_storekit." + @"InAppPurchaseAPI.startProductRequest", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:InAppPurchaseAPIGetCodec()]; + codec:FIAGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(startProductRequestProductIdentifiers: completion:)], - @"InAppPurchaseAPI api (%@) doesn't respond to " + @"FIAInAppPurchaseAPI api (%@) doesn't respond to " @"@selector(startProductRequestProductIdentifiers:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; NSArray *arg_productIdentifiers = GetNullableObjectAtIndex(args, 0); [api startProductRequestProductIdentifiers:arg_productIdentifiers - completion:^(SKProductsResponseMessage *_Nullable output, + completion:^(FIASKProductsResponseMessage *_Nullable output, FlutterError *_Nullable error) { callback(wrapResult(output, error)); }]; @@ -689,17 +753,19 @@ void SetUpInAppPurchaseAPI(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.finishTransaction" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.in_app_purchase_storekit." + @"InAppPurchaseAPI.finishTransaction", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:InAppPurchaseAPIGetCodec()]; + codec:FIAGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(finishTransactionFinishMap:error:)], - @"InAppPurchaseAPI api (%@) doesn't respond to " + @"FIAInAppPurchaseAPI api (%@) doesn't respond to " @"@selector(finishTransactionFinishMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; NSDictionary *arg_finishMap = GetNullableObjectAtIndex(args, 0); FlutterError *error; [api finishTransactionFinishMap:arg_finishMap error:&error]; @@ -711,17 +777,19 @@ void SetUpInAppPurchaseAPI(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.restoreTransactions" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.in_app_purchase_storekit." + @"InAppPurchaseAPI.restoreTransactions", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:InAppPurchaseAPIGetCodec()]; + codec:FIAGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(restoreTransactionsApplicationUserName:error:)], - @"InAppPurchaseAPI api (%@) doesn't respond to " + @"FIAInAppPurchaseAPI api (%@) doesn't respond to " @"@selector(restoreTransactionsApplicationUserName:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; NSString *arg_applicationUserName = GetNullableObjectAtIndex(args, 0); FlutterError *error; [api restoreTransactionsApplicationUserName:arg_applicationUserName error:&error]; @@ -733,13 +801,15 @@ void SetUpInAppPurchaseAPI(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI." - @"presentCodeRedemptionSheet" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.in_app_purchase_storekit." + @"InAppPurchaseAPI.presentCodeRedemptionSheet", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:InAppPurchaseAPIGetCodec()]; + codec:FIAGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(presentCodeRedemptionSheetWithError:)], - @"InAppPurchaseAPI api (%@) doesn't respond to " + @"FIAInAppPurchaseAPI api (%@) doesn't respond to " @"@selector(presentCodeRedemptionSheetWithError:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { @@ -753,15 +823,17 @@ void SetUpInAppPurchaseAPI(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.retrieveReceiptData" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.in_app_purchase_storekit." + @"InAppPurchaseAPI.retrieveReceiptData", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:InAppPurchaseAPIGetCodec()]; + codec:FIAGetMessagesCodec()]; if (api) { - NSCAssert( - [api respondsToSelector:@selector(retrieveReceiptDataWithError:)], - @"InAppPurchaseAPI api (%@) doesn't respond to @selector(retrieveReceiptDataWithError:)", - api); + NSCAssert([api respondsToSelector:@selector(retrieveReceiptDataWithError:)], + @"FIAInAppPurchaseAPI api (%@) doesn't respond to " + @"@selector(retrieveReceiptDataWithError:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { FlutterError *error; NSString *output = [api retrieveReceiptDataWithError:&error]; @@ -773,17 +845,19 @@ void SetUpInAppPurchaseAPI(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.refreshReceipt" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.in_app_purchase_storekit." + @"InAppPurchaseAPI.refreshReceipt", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:InAppPurchaseAPIGetCodec()]; + codec:FIAGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(refreshReceiptReceiptProperties:completion:)], - @"InAppPurchaseAPI api (%@) doesn't respond to " + @"FIAInAppPurchaseAPI api (%@) doesn't respond to " @"@selector(refreshReceiptReceiptProperties:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; NSDictionary *arg_receiptProperties = GetNullableObjectAtIndex(args, 0); [api refreshReceiptReceiptProperties:arg_receiptProperties completion:^(FlutterError *_Nullable error) { @@ -796,13 +870,15 @@ void SetUpInAppPurchaseAPI(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI." - @"startObservingPaymentQueue" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.in_app_purchase_storekit." + @"InAppPurchaseAPI.startObservingPaymentQueue", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:InAppPurchaseAPIGetCodec()]; + codec:FIAGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(startObservingPaymentQueueWithError:)], - @"InAppPurchaseAPI api (%@) doesn't respond to " + @"FIAInAppPurchaseAPI api (%@) doesn't respond to " @"@selector(startObservingPaymentQueueWithError:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { @@ -816,13 +892,15 @@ void SetUpInAppPurchaseAPI(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI." - @"stopObservingPaymentQueue" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.in_app_purchase_storekit." + @"InAppPurchaseAPI.stopObservingPaymentQueue", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:InAppPurchaseAPIGetCodec()]; + codec:FIAGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(stopObservingPaymentQueueWithError:)], - @"InAppPurchaseAPI api (%@) doesn't respond to " + @"FIAInAppPurchaseAPI api (%@) doesn't respond to " @"@selector(stopObservingPaymentQueueWithError:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { @@ -836,13 +914,15 @@ void SetUpInAppPurchaseAPI(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI." - @"registerPaymentQueueDelegate" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.in_app_purchase_storekit." + @"InAppPurchaseAPI.registerPaymentQueueDelegate", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:InAppPurchaseAPIGetCodec()]; + codec:FIAGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(registerPaymentQueueDelegateWithError:)], - @"InAppPurchaseAPI api (%@) doesn't respond to " + @"FIAInAppPurchaseAPI api (%@) doesn't respond to " @"@selector(registerPaymentQueueDelegateWithError:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { @@ -856,13 +936,15 @@ void SetUpInAppPurchaseAPI(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI." - @"removePaymentQueueDelegate" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.in_app_purchase_storekit." + @"InAppPurchaseAPI.removePaymentQueueDelegate", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:InAppPurchaseAPIGetCodec()]; + codec:FIAGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(removePaymentQueueDelegateWithError:)], - @"InAppPurchaseAPI api (%@) doesn't respond to " + @"FIAInAppPurchaseAPI api (%@) doesn't respond to " @"@selector(removePaymentQueueDelegateWithError:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { @@ -876,13 +958,15 @@ void SetUpInAppPurchaseAPI(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI." - @"showPriceConsentIfNeeded" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.in_app_purchase_storekit." + @"InAppPurchaseAPI.showPriceConsentIfNeeded", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:InAppPurchaseAPIGetCodec()]; + codec:FIAGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(showPriceConsentIfNeededWithError:)], - @"InAppPurchaseAPI api (%@) doesn't respond to " + @"FIAInAppPurchaseAPI api (%@) doesn't respond to " @"@selector(showPriceConsentIfNeededWithError:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/ios/Runner.xcodeproj/project.pbxproj b/packages/in_app_purchase/in_app_purchase_storekit/example/ios/Runner.xcodeproj/project.pbxproj index 7d99ab6109b1..9d01ee6865fe 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/in_app_purchase/in_app_purchase_storekit/example/ios/Runner.xcodeproj/project.pbxproj @@ -18,13 +18,16 @@ C4667AA10A6BC70CE9A5007C /* libPods-RunnerTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AB9CD9DD098BDAB3D5053EE5 /* libPods-RunnerTests.a */; }; E680BD031412EB2D02C9190B /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 21CE6E615CF661FC0E18FB0A /* libPods-Runner.a */; }; F22BF91C2BC9B40B00713878 /* SwiftStubs.swift in Sources */ = {isa = PBXBuildFile; fileRef = F22BF91B2BC9B40B00713878 /* SwiftStubs.swift */; }; + F22FD7A22CB080AE0006F28F /* StoreKit2TranslatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F22FD7A12CB080AE0006F28F /* StoreKit2TranslatorTests.swift */; }; + F24C45E22C409D42000C6C72 /* InAppPurchasePluginTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F24C45E12C409D41000C6C72 /* InAppPurchasePluginTests.swift */; }; + F276940B2C47268700277144 /* ProductRequestHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F276940A2C47268700277144 /* ProductRequestHandlerTests.swift */; }; + F27694112C49BF6F00277144 /* FIAPPaymentQueueDeleteTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F27694102C49BF6F00277144 /* FIAPPaymentQueueDeleteTests.swift */; }; + F27694172C49DBCA00277144 /* FIATransactionCacheTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F27694162C49DBCA00277144 /* FIATransactionCacheTests.swift */; }; + F2858EE82C76A4230063A092 /* Configuration.storekit in Resources */ = {isa = PBXBuildFile; fileRef = F6E5D5F926131C4800C68BED /* Configuration.storekit */; }; F295AD3A2C1256DD0067C78A /* Stubs.m in Sources */ = {isa = PBXBuildFile; fileRef = F295AD392C1256DD0067C78A /* Stubs.m */; }; - F295AD412C1256F50067C78A /* FIAPPaymentQueueDeleteTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F295AD3B2C1256F50067C78A /* FIAPPaymentQueueDeleteTests.m */; }; - F295AD422C1256F50067C78A /* InAppPurchasePluginTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F295AD3C2C1256F50067C78A /* InAppPurchasePluginTests.m */; }; - F295AD432C1256F50067C78A /* ProductRequestHandlerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F295AD3D2C1256F50067C78A /* ProductRequestHandlerTests.m */; }; - F295AD442C1256F50067C78A /* FIATransactionCacheTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F295AD3E2C1256F50067C78A /* FIATransactionCacheTests.m */; }; - F295AD452C1256F50067C78A /* PaymentQueueTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F295AD3F2C1256F50067C78A /* PaymentQueueTests.m */; }; - F295AD462C1256F50067C78A /* TranslatorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F295AD402C1256F50067C78A /* TranslatorTests.m */; }; + F2D127492CB4A76D005FA2E5 /* InAppPurchaseStoreKit2PluginTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2D127482CB4A76D005FA2E5 /* InAppPurchaseStoreKit2PluginTests.swift */; }; + F2D5271A2C50627500C137C7 /* PaymentQueueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2D527192C50627500C137C7 /* PaymentQueueTests.swift */; }; + F2D5272A2C583C4A00C137C7 /* TranslatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2D527292C583C4A00C137C7 /* TranslatorTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -75,14 +78,16 @@ CC9E5595B2B9B9B90632DA75 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; F22BF91A2BC9B40B00713878 /* RunnerTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RunnerTests-Bridging-Header.h"; sourceTree = ""; }; F22BF91B2BC9B40B00713878 /* SwiftStubs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftStubs.swift; sourceTree = ""; }; + F22FD7A12CB080AE0006F28F /* StoreKit2TranslatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = StoreKit2TranslatorTests.swift; path = ../shared/RunnerTests/StoreKit2TranslatorTests.swift; sourceTree = SOURCE_ROOT; }; + F24C45E12C409D41000C6C72 /* InAppPurchasePluginTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = InAppPurchasePluginTests.swift; path = ../../shared/RunnerTests/InAppPurchasePluginTests.swift; sourceTree = ""; }; + F276940A2C47268700277144 /* ProductRequestHandlerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ProductRequestHandlerTests.swift; path = ../../shared/RunnerTests/ProductRequestHandlerTests.swift; sourceTree = ""; }; + F27694102C49BF6F00277144 /* FIAPPaymentQueueDeleteTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FIAPPaymentQueueDeleteTests.swift; path = ../../shared/RunnerTests/FIAPPaymentQueueDeleteTests.swift; sourceTree = ""; }; + F27694162C49DBCA00277144 /* FIATransactionCacheTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FIATransactionCacheTests.swift; path = ../../shared/RunnerTests/FIATransactionCacheTests.swift; sourceTree = ""; }; F295AD362C1251300067C78A /* Stubs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Stubs.h; path = ../../shared/RunnerTests/Stubs.h; sourceTree = ""; }; F295AD392C1256DD0067C78A /* Stubs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Stubs.m; path = ../../shared/RunnerTests/Stubs.m; sourceTree = ""; }; - F295AD3B2C1256F50067C78A /* FIAPPaymentQueueDeleteTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FIAPPaymentQueueDeleteTests.m; path = ../../shared/RunnerTests/FIAPPaymentQueueDeleteTests.m; sourceTree = ""; }; - F295AD3C2C1256F50067C78A /* InAppPurchasePluginTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = InAppPurchasePluginTests.m; path = ../../shared/RunnerTests/InAppPurchasePluginTests.m; sourceTree = ""; }; - F295AD3D2C1256F50067C78A /* ProductRequestHandlerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ProductRequestHandlerTests.m; path = ../../shared/RunnerTests/ProductRequestHandlerTests.m; sourceTree = ""; }; - F295AD3E2C1256F50067C78A /* FIATransactionCacheTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FIATransactionCacheTests.m; path = ../../shared/RunnerTests/FIATransactionCacheTests.m; sourceTree = ""; }; - F295AD3F2C1256F50067C78A /* PaymentQueueTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PaymentQueueTests.m; path = ../../shared/RunnerTests/PaymentQueueTests.m; sourceTree = ""; }; - F295AD402C1256F50067C78A /* TranslatorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TranslatorTests.m; path = ../../shared/RunnerTests/TranslatorTests.m; sourceTree = ""; }; + F2D127482CB4A76D005FA2E5 /* InAppPurchaseStoreKit2PluginTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = InAppPurchaseStoreKit2PluginTests.swift; path = ../shared/RunnerTests/InAppPurchaseStoreKit2PluginTests.swift; sourceTree = SOURCE_ROOT; }; + F2D527192C50627500C137C7 /* PaymentQueueTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = PaymentQueueTests.swift; path = ../../shared/RunnerTests/PaymentQueueTests.swift; sourceTree = ""; }; + F2D527292C583C4A00C137C7 /* TranslatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TranslatorTests.swift; path = ../../shared/RunnerTests/TranslatorTests.swift; sourceTree = ""; }; F6E5D5F926131C4800C68BED /* Configuration.storekit */ = {isa = PBXFileReference; lastKnownFileType = text; path = Configuration.storekit; sourceTree = ""; }; /* End PBXFileReference section */ @@ -186,12 +191,14 @@ A59001A521E69658004A3E5E /* RunnerTests */ = { isa = PBXGroup; children = ( - F295AD3B2C1256F50067C78A /* FIAPPaymentQueueDeleteTests.m */, - F295AD3E2C1256F50067C78A /* FIATransactionCacheTests.m */, - F295AD3C2C1256F50067C78A /* InAppPurchasePluginTests.m */, - F295AD3F2C1256F50067C78A /* PaymentQueueTests.m */, - F295AD3D2C1256F50067C78A /* ProductRequestHandlerTests.m */, - F295AD402C1256F50067C78A /* TranslatorTests.m */, + F2D127482CB4A76D005FA2E5 /* InAppPurchaseStoreKit2PluginTests.swift */, + F22FD7A12CB080AE0006F28F /* StoreKit2TranslatorTests.swift */, + F2D527292C583C4A00C137C7 /* TranslatorTests.swift */, + F2D527192C50627500C137C7 /* PaymentQueueTests.swift */, + F27694162C49DBCA00277144 /* FIATransactionCacheTests.swift */, + F27694102C49BF6F00277144 /* FIAPPaymentQueueDeleteTests.swift */, + F24C45E12C409D41000C6C72 /* InAppPurchasePluginTests.swift */, + F276940A2C47268700277144 /* ProductRequestHandlerTests.swift */, F295AD392C1256DD0067C78A /* Stubs.m */, F295AD362C1251300067C78A /* Stubs.h */, F22BF91B2BC9B40B00713878 /* SwiftStubs.swift */, @@ -304,6 +311,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + F2858EE82C76A4230063A092 /* Configuration.storekit in Resources */, 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, @@ -392,7 +400,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n"; }; 9AF65E7BDC9361CB3944EE9C /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; @@ -433,14 +441,16 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - F295AD432C1256F50067C78A /* ProductRequestHandlerTests.m in Sources */, + F2D5271A2C50627500C137C7 /* PaymentQueueTests.swift in Sources */, + F24C45E22C409D42000C6C72 /* InAppPurchasePluginTests.swift in Sources */, F22BF91C2BC9B40B00713878 /* SwiftStubs.swift in Sources */, - F295AD412C1256F50067C78A /* FIAPPaymentQueueDeleteTests.m in Sources */, - F295AD452C1256F50067C78A /* PaymentQueueTests.m in Sources */, - F295AD442C1256F50067C78A /* FIATransactionCacheTests.m in Sources */, - F295AD462C1256F50067C78A /* TranslatorTests.m in Sources */, - F295AD422C1256F50067C78A /* InAppPurchasePluginTests.m in Sources */, + F22FD7A22CB080AE0006F28F /* StoreKit2TranslatorTests.swift in Sources */, + F276940B2C47268700277144 /* ProductRequestHandlerTests.swift in Sources */, F295AD3A2C1256DD0067C78A /* Stubs.m in Sources */, + F2D5272A2C583C4A00C137C7 /* TranslatorTests.swift in Sources */, + F27694172C49DBCA00277144 /* FIATransactionCacheTests.swift in Sources */, + F2D127492CB4A76D005FA2E5 /* InAppPurchaseStoreKit2PluginTests.swift in Sources */, + F27694112C49BF6F00277144 /* FIAPPaymentQueueDeleteTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/in_app_purchase/in_app_purchase_storekit/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 477131feb699..9c3ad5d54dda 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/in_app_purchase/in_app_purchase_storekit/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -39,6 +39,7 @@ skipped = "NO"> /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; 3399D490228B24CF009A79C7 /* ShellScript */ = { @@ -402,7 +415,7 @@ shellPath = /bin/sh; shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; }; - 75DE29BFD3B3C1D676C22160 /* [CP] Check Pods Manifest.lock */ = { + 4AB6971641BFC5F28870AACB /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -417,33 +430,28 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - F83C62E1BF4D0A86747FA7CF /* [CP] Check Pods Manifest.lock */ = { + 52AE403FA1A5A62558A171B7 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -463,14 +471,14 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - F79BDC1A2905FC1F00E3999D /* ProductRequestHandlerTests.m in Sources */, - F79BDC1E2905FC3900E3999D /* TranslatorTests.m in Sources */, - F79BDC182905FC1800E3999D /* PaymentQueueTests.m in Sources */, + F2D5271E2C50645600C137C7 /* PaymentQueueTests.swift in Sources */, + F24C45E42C409D87000C6C72 /* InAppPurchasePluginTests.swift in Sources */, F79BDC1C2905FC3200E3999D /* Stubs.m in Sources */, - F79BDC102905FBE300E3999D /* FIAPPaymentQueueDeleteTests.m in Sources */, - F79BDC142905FBFE00E3999D /* InAppPurchasePluginTests.m in Sources */, - F79BDC122905FBF700E3999D /* FIATransactionCacheTests.m in Sources */, + F27694092C4724B200277144 /* ProductRequestHandlerTests.swift in Sources */, F2C3A7412BD9D33D000D35F2 /* Stubs.swift in Sources */, + F2D527262C583C1C00C137C7 /* TranslatorTests.swift in Sources */, + F27694192C49DBE800277144 /* FIATransactionCacheTests.swift in Sources */, + F27694132C49BF7B00277144 /* FIAPPaymentQueueDeleteTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -734,7 +742,7 @@ }; F700DD0828E652A10004836B /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 89C4EE02AA38CF7BF853991B /* Pods-RunnerTests.debug.xcconfig */; + baseConfigurationReference = B537BC9F2D936311267ABC65 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; @@ -767,7 +775,7 @@ }; F700DD0928E652A10004836B /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 79C769808042591E28A245B8 /* Pods-RunnerTests.release.xcconfig */; + baseConfigurationReference = 0332995B6EC622E1F0605C08 /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; @@ -798,7 +806,7 @@ }; F700DD0A28E652A10004836B /* Profile */ = { isa = XCBuildConfiguration; - baseConfigurationReference = BEE5894B3A0A82FD8D495BDD /* Pods-RunnerTests.profile.xcconfig */; + baseConfigurationReference = 46EFB01DD1BBB34F886C33A0 /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/Runner.xcworkspace/contents.xcworkspacedata index 7f167c1063d5..21a3cc14c74e 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/Runner.xcworkspace/contents.xcworkspacedata +++ b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -1,9 +1,6 @@ - - diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/Runner/AppDelegate.swift b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/Runner/AppDelegate.swift index 5cec4c48f620..689c0ecd5254 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/Runner/AppDelegate.swift +++ b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/Runner/AppDelegate.swift @@ -5,7 +5,7 @@ import Cocoa import FlutterMacOS -@NSApplicationMain +@main class AppDelegate: FlutterAppDelegate { override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { return true diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/FIAPPaymentQueueDeleteTests.m b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/FIAPPaymentQueueDeleteTests.m deleted file mode 120000 index 7c8e7691c6d4..000000000000 --- a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/FIAPPaymentQueueDeleteTests.m +++ /dev/null @@ -1 +0,0 @@ -../../shared/RunnerTests/FIAPPaymentQueueDeleteTests.m \ No newline at end of file diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/FIAPPaymentQueueDeleteTests.swift b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/FIAPPaymentQueueDeleteTests.swift new file mode 120000 index 000000000000..1514b2683967 --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/FIAPPaymentQueueDeleteTests.swift @@ -0,0 +1 @@ +../../shared/RunnerTests/FIAPPaymentQueueDeleteTests.swift \ No newline at end of file diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/FIATransactionCacheTests.m b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/FIATransactionCacheTests.m deleted file mode 120000 index 5c7c87fd1aea..000000000000 --- a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/FIATransactionCacheTests.m +++ /dev/null @@ -1 +0,0 @@ -../../shared/RunnerTests/FIATransactionCacheTests.m \ No newline at end of file diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/FIATransactionCacheTests.swift b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/FIATransactionCacheTests.swift new file mode 120000 index 000000000000..58817e3feff0 --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/FIATransactionCacheTests.swift @@ -0,0 +1 @@ +../../shared/RunnerTests/FIATransactionCacheTests.swift \ No newline at end of file diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/InAppPurchasePluginTests.m b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/InAppPurchasePluginTests.m deleted file mode 120000 index 495146dde20b..000000000000 --- a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/InAppPurchasePluginTests.m +++ /dev/null @@ -1 +0,0 @@ -../../shared/RunnerTests/InAppPurchasePluginTests.m \ No newline at end of file diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/InAppPurchasePluginTests.swift b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/InAppPurchasePluginTests.swift new file mode 120000 index 000000000000..adb0ea0dc27c --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/InAppPurchasePluginTests.swift @@ -0,0 +1 @@ +../../shared/RunnerTests/InAppPurchasePluginTests.swift \ No newline at end of file diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/PaymentQueueTests.m b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/PaymentQueueTests.m deleted file mode 120000 index f207cda68945..000000000000 --- a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/PaymentQueueTests.m +++ /dev/null @@ -1 +0,0 @@ -../../shared/RunnerTests/PaymentQueueTests.m \ No newline at end of file diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/PaymentQueueTests.swift b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/PaymentQueueTests.swift new file mode 120000 index 000000000000..781896937403 --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/PaymentQueueTests.swift @@ -0,0 +1 @@ +../../shared/RunnerTests/PaymentQueueTests.swift \ No newline at end of file diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/ProductRequestHandlerTests.m b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/ProductRequestHandlerTests.m deleted file mode 120000 index f186e1122526..000000000000 --- a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/ProductRequestHandlerTests.m +++ /dev/null @@ -1 +0,0 @@ -../../shared/RunnerTests/ProductRequestHandlerTests.m \ No newline at end of file diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/ProductRequestHandlerTests.swift b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/ProductRequestHandlerTests.swift new file mode 120000 index 000000000000..80c0dc82d57b --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/ProductRequestHandlerTests.swift @@ -0,0 +1 @@ +../../shared/RunnerTests/ProductRequestHandlerTests.swift \ No newline at end of file diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/TranslatorTests.m b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/TranslatorTests.m deleted file mode 120000 index ac58ed96972e..000000000000 --- a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/TranslatorTests.m +++ /dev/null @@ -1 +0,0 @@ -../../shared/RunnerTests/TranslatorTests.m \ No newline at end of file diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/TranslatorTests.swift b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/TranslatorTests.swift new file mode 120000 index 000000000000..743854417c0b --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/RunnerTests/TranslatorTests.swift @@ -0,0 +1 @@ +../../shared/RunnerTests/TranslatorTests.swift \ No newline at end of file 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 2062efd0fb70..a59dafe8df95 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.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/FIAPPaymentQueueDeleteTests.m b/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/FIAPPaymentQueueDeleteTests.m deleted file mode 100644 index 1056c343b173..000000000000 --- a/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/FIAPPaymentQueueDeleteTests.m +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import -#import "FIAObjectTranslator.h" -#import "FIAPaymentQueueHandler.h" -#import "Stubs.h" - -@import in_app_purchase_storekit; - -API_AVAILABLE(ios(13.0)) -API_UNAVAILABLE(tvos, macos, watchos) -@interface FIAPPaymentQueueDelegateTests : XCTestCase - -@property(nonatomic, strong) SKPaymentTransaction *transaction; -@property(nonatomic, strong) SKStorefront *storefront; - -@end - -@implementation FIAPPaymentQueueDelegateTests - -- (void)setUp { - NSDictionary *transactionMap = @{ - @"transactionIdentifier" : [NSNull null], - @"transactionState" : @(SKPaymentTransactionStatePurchasing), - @"payment" : [NSNull null], - @"error" : [FIAObjectTranslator getMapFromNSError:[NSError errorWithDomain:@"test_stub" - code:123 - userInfo:@{}]], - @"transactionTimeStamp" : @([NSDate date].timeIntervalSince1970), - @"originalTransaction" : [NSNull null], - }; - self.transaction = [[SKPaymentTransactionStub alloc] initWithMap:transactionMap]; - - NSDictionary *storefrontMap = @{ - @"countryCode" : @"USA", - @"identifier" : @"unique_identifier", - }; - self.storefront = [[SKStorefrontStub alloc] initWithMap:storefrontMap]; -} - -- (void)tearDown { -} - -- (void)testShouldContinueTransaction { - if (@available(iOS 13.0, *)) { - MethodChannelStub *channelStub = [[MethodChannelStub alloc] init]; - channelStub.invokeMethodChannelWithResultsStub = - ^(NSString *_Nonnull method, id _Nonnull arguments, FlutterResult _Nullable result) { - XCTAssertEqualObjects(method, @"shouldContinueTransaction"); - XCTAssertEqualObjects(arguments, - [FIAObjectTranslator getMapFromSKStorefront:self.storefront - andSKPaymentTransaction:self.transaction]); - result(@NO); - }; - - FIAPPaymentQueueDelegate *delegate = - [[FIAPPaymentQueueDelegate alloc] initWithMethodChannel:channelStub]; - - BOOL shouldContinue = [delegate paymentQueue:[[SKPaymentQueueStub alloc] init] - shouldContinueTransaction:self.transaction - inStorefront:self.storefront]; - - XCTAssertFalse(shouldContinue); - } -} - -- (void)testShouldContinueTransaction_should_default_to_yes { - if (@available(iOS 13.0, *)) { - MethodChannelStub *channelStub = [[MethodChannelStub alloc] init]; - FIAPPaymentQueueDelegate *delegate = - [[FIAPPaymentQueueDelegate alloc] initWithMethodChannel:channelStub]; - - channelStub.invokeMethodChannelWithResultsStub = - ^(NSString *_Nonnull method, id _Nonnull arguments, FlutterResult _Nullable result) { - XCTAssertEqualObjects(method, @"shouldContinueTransaction"); - XCTAssertEqualObjects(arguments, - [FIAObjectTranslator getMapFromSKStorefront:self.storefront - andSKPaymentTransaction:self.transaction]); - }; - - BOOL shouldContinue = [delegate paymentQueue:[[SKPaymentQueueStub alloc] init] - shouldContinueTransaction:self.transaction - inStorefront:self.storefront]; - - XCTAssertTrue(shouldContinue); - } -} - -#if TARGET_OS_IOS -- (void)testShouldShowPriceConsentIfNeeded { - if (@available(iOS 13.4, *)) { - MethodChannelStub *channelStub = [[MethodChannelStub alloc] init]; - FIAPPaymentQueueDelegate *delegate = - [[FIAPPaymentQueueDelegate alloc] initWithMethodChannel:channelStub]; - - channelStub.invokeMethodChannelWithResultsStub = - ^(NSString *_Nonnull method, id _Nonnull arguments, FlutterResult _Nullable result) { - XCTAssertEqualObjects(method, @"shouldShowPriceConsent"); - XCTAssertNil(arguments); - result(@NO); - }; - - BOOL shouldShow = - [delegate paymentQueueShouldShowPriceConsent:[[SKPaymentQueueStub alloc] init]]; - - XCTAssertFalse(shouldShow); - } -} -#endif - -#if TARGET_OS_IOS -- (void)testShouldShowPriceConsentIfNeeded_should_default_to_yes { - if (@available(iOS 13.4, *)) { - MethodChannelStub *channelStub = [[MethodChannelStub alloc] init]; - FIAPPaymentQueueDelegate *delegate = - [[FIAPPaymentQueueDelegate alloc] initWithMethodChannel:channelStub]; - - channelStub.invokeMethodChannelWithResultsStub = - ^(NSString *_Nonnull method, id _Nonnull arguments, FlutterResult _Nullable result) { - XCTAssertEqualObjects(method, @"shouldShowPriceConsent"); - XCTAssertNil(arguments); - }; - - BOOL shouldShow = - [delegate paymentQueueShouldShowPriceConsent:[[SKPaymentQueueStub alloc] init]]; - - XCTAssertTrue(shouldShow); - } -} -#endif - -@end diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/FIAPPaymentQueueDeleteTests.swift b/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/FIAPPaymentQueueDeleteTests.swift new file mode 100644 index 000000000000..af3fdbc4446e --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/FIAPPaymentQueueDeleteTests.swift @@ -0,0 +1,127 @@ +// 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 Foundation +import StoreKit +import XCTest + +@testable import in_app_purchase_storekit + +@available(iOS 13.0, *) +final class FIAPPaymentQueueDelegateTests: XCTestCase { + var transaction: SKPaymentTransaction! + var storefront: SKStorefront! + + override func setUp() { + super.setUp() + let transactionMap: [String: Any] = [ + "transactionIdentifier": NSNull(), + "transactionState": SKPaymentTransactionState.purchasing.rawValue, + "payment": NSNull(), + "error": FIAObjectTranslator.getMapFrom( + NSError(domain: "test_stub", code: 123, userInfo: [:])), + "transactionTimeStamp": Date().timeIntervalSince1970, + "originalTransaction": NSNull(), + ] + self.transaction = SKPaymentTransactionStub(map: transactionMap) + + let storefrontMap: [String: Any] = [ + "countryCode": "USA", + "identifier": "unique_identifier", + ] + self.storefront = SKStorefrontStub(map: storefrontMap) + } + + override func tearDown() { + super.tearDown() + } + + func testShouldContinueTransaction() { + let channelStub = MethodChannelStub() + channelStub.invokeMethodChannelWithResultsStub = { method, arguments, result in + XCTAssertEqual(method, "shouldContinueTransaction") + XCTAssertEqual( + arguments as! NSDictionary, + FIAObjectTranslator.getMapFrom( + self.storefront, + andSKPaymentTransaction: self.transaction) as NSDictionary) + + guard let result = result else { + XCTFail("Result should not be nil") + return + } + result(false) + } + + let delegate = FIAPPaymentQueueDelegate(methodChannel: channelStub) + + let shouldContinue = delegate.paymentQueue( + SKPaymentQueueStub(), + shouldContinue: self.transaction, + in: self.storefront) + + XCTAssertFalse(shouldContinue) + } + + func testShouldContinueTransactionShouldDefaultToYes() { + let channelStub = MethodChannelStub() + let delegate = FIAPPaymentQueueDelegate(methodChannel: channelStub) + + channelStub.invokeMethodChannelWithResultsStub = { method, arguments, result in + XCTAssertEqual(method, "shouldContinueTransaction") + XCTAssertEqual( + arguments as! NSDictionary, + FIAObjectTranslator.getMapFrom( + self.storefront, + andSKPaymentTransaction: self.transaction) as NSDictionary) + } + + let shouldContinue = delegate.paymentQueue( + SKPaymentQueueStub(), + shouldContinue: self.transaction, + in: self.storefront) + + XCTAssertTrue(shouldContinue) + } + + #if TARGET_OS_IOS + func testShouldShowPriceConsentIfNeeded() throws { + if #available(iOS 13.4, *) { + let channelStub = MethodChannelStub() + let delegate = FIAPPaymentQueueDelegate(methodChannel: channelStub) + + channelStub.invokeMethodChannelWithResultsStub = { method, arguments, result in + XCTAssertEqual(method, "shouldShowPriceConsent") + XCTAssertNil(arguments) + + guard let result = result else { + XCTFail("Result should not be nil") + return + } + result(false) + } + + let shouldShow = delegate.paymentQueueShouldShowPriceConsent(SKPaymentQueueStub()) + + XCTAssertFalse(shouldShow) + } + } + + func testShouldShowPriceConsentIfNeededShouldDefaultToYes() { + if #available(iOS 13.4, *) { + let channelStub = MethodChannelStub() + let delegate = FIAPPaymentQueueDelegate(methodChannel: channelStub) + + channelStub.invokeMethodChannelWithResultsStub = { method, arguments, result in + XCTAssertEqual(method, "shouldShowPriceConsent") + XCTAssertNil(arguments) + } + + let shouldShow = delegate.paymentQueueShouldShowPriceConsent(SKPaymentQueueStub()) + + XCTAssertTrue(shouldShow) + } + } + #endif +} diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/FIATransactionCacheTests.m b/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/FIATransactionCacheTests.m deleted file mode 100644 index 1ba0aea76e39..000000000000 --- a/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/FIATransactionCacheTests.m +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import - -@import in_app_purchase_storekit; - -@interface FIATransactionCacheTests : XCTestCase - -@end - -@implementation FIATransactionCacheTests - -- (void)testAddObjectsForNewKey { - NSArray *dummyArray = @[ @1, @2, @3 ]; - FIATransactionCache *cache = [[FIATransactionCache alloc] init]; - [cache addObjects:dummyArray forKey:TransactionCacheKeyUpdatedTransactions]; - - XCTAssertEqual(dummyArray, [cache getObjectsForKey:TransactionCacheKeyUpdatedTransactions]); -} - -- (void)testAddObjectsForExistingKey { - NSArray *dummyArray = @[ @1, @2, @3 ]; - FIATransactionCache *cache = [[FIATransactionCache alloc] init]; - [cache addObjects:dummyArray forKey:TransactionCacheKeyUpdatedTransactions]; - - XCTAssertEqual(dummyArray, [cache getObjectsForKey:TransactionCacheKeyUpdatedTransactions]); - - [cache addObjects:@[ @4, @5, @6 ] forKey:TransactionCacheKeyUpdatedTransactions]; - - NSArray *expected = @[ @1, @2, @3, @4, @5, @6 ]; - XCTAssertEqualObjects(expected, [cache getObjectsForKey:TransactionCacheKeyUpdatedTransactions]); -} - -- (void)testGetObjectsForNonExistingKey { - FIATransactionCache *cache = [[FIATransactionCache alloc] init]; - XCTAssertNil([cache getObjectsForKey:TransactionCacheKeyUpdatedTransactions]); -} - -- (void)testClear { - NSArray *fakeUpdatedTransactions = @[ @1, @2, @3 ]; - NSArray *fakeRemovedTransactions = @[ @"Remove 1", @"Remove 2", @"Remove 3" ]; - NSArray *fakeUpdatedDownloads = @[ @"Download 1", @"Download 2" ]; - FIATransactionCache *cache = [[FIATransactionCache alloc] init]; - [cache addObjects:fakeUpdatedTransactions forKey:TransactionCacheKeyUpdatedTransactions]; - [cache addObjects:fakeRemovedTransactions forKey:TransactionCacheKeyRemovedTransactions]; - [cache addObjects:fakeUpdatedDownloads forKey:TransactionCacheKeyUpdatedDownloads]; - - XCTAssertEqual(fakeUpdatedTransactions, - [cache getObjectsForKey:TransactionCacheKeyUpdatedTransactions]); - XCTAssertEqual(fakeRemovedTransactions, - [cache getObjectsForKey:TransactionCacheKeyRemovedTransactions]); - XCTAssertEqual(fakeUpdatedDownloads, - [cache getObjectsForKey:TransactionCacheKeyUpdatedDownloads]); - - [cache clear]; - - XCTAssertNil([cache getObjectsForKey:TransactionCacheKeyUpdatedTransactions]); - XCTAssertNil([cache getObjectsForKey:TransactionCacheKeyRemovedTransactions]); - XCTAssertNil([cache getObjectsForKey:TransactionCacheKeyUpdatedDownloads]); -} -@end diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/FIATransactionCacheTests.swift b/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/FIATransactionCacheTests.swift new file mode 100644 index 000000000000..dae6464ae4df --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/FIATransactionCacheTests.swift @@ -0,0 +1,70 @@ +// 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 XCTest + +@testable import in_app_purchase_storekit + +final class FIATransactionCacheTests: XCTestCase { + + func testAddObjectsForNewKey() throws { + let dummyArray = [1, 2, 3] + let cache = FIATransactionCache() + cache.add(dummyArray, for: TransactionCacheKey.updatedTransactions) + + let updatedTransactions = try XCTUnwrap( + cache.getObjectsFor(TransactionCacheKey.updatedTransactions) as? [Int]) + XCTAssertEqual(dummyArray, updatedTransactions) + } + + func testAddObjectsForExistingKey() throws { + let dummyArray = [1, 2, 3] + let cache = FIATransactionCache() + cache.add(dummyArray, for: TransactionCacheKey.updatedTransactions) + + let firstUpdatedTransactions = try XCTUnwrap( + cache.getObjectsFor(TransactionCacheKey.updatedTransactions) as? [Int]) + XCTAssertEqual(dummyArray, firstUpdatedTransactions) + + cache.add([4, 5, 6], for: TransactionCacheKey.updatedTransactions) + + let expected = [1, 2, 3, 4, 5, 6] + let secondUpdatedTransactions = try XCTUnwrap( + cache.getObjectsFor(TransactionCacheKey.updatedTransactions) as? [Int]) + XCTAssertEqual(expected, secondUpdatedTransactions) + } + + func testGetObjectsForNonExistingKey() { + let cache = FIATransactionCache() + XCTAssertTrue(cache.getObjectsFor(TransactionCacheKey.updatedTransactions).isEmpty) + } + + func testClear() throws { + let fakeUpdatedTransactions = [1, 2, 3] + let fakeRemovedTransactions = ["Remove 1", "Remove 2", "Remove 3"] + let fakeUpdatedDownloads = ["Download 1", "Download 2"] + let cache = FIATransactionCache() + + cache.add(fakeUpdatedTransactions, for: TransactionCacheKey.updatedTransactions) + cache.add(fakeRemovedTransactions, for: TransactionCacheKey.removedTransactions) + cache.add(fakeUpdatedDownloads, for: TransactionCacheKey.updatedDownloads) + + let updatedTransactions = try XCTUnwrap( + cache.getObjectsFor(TransactionCacheKey.updatedTransactions) as? [Int]) + let removedTransactions = try XCTUnwrap( + cache.getObjectsFor(TransactionCacheKey.removedTransactions) as? [String]) + let updatedDownloads = try XCTUnwrap( + cache.getObjectsFor(TransactionCacheKey.updatedDownloads) as? [String]) + + XCTAssertEqual(fakeUpdatedTransactions, updatedTransactions) + XCTAssertEqual(fakeRemovedTransactions, removedTransactions) + XCTAssertEqual(fakeUpdatedDownloads, updatedDownloads) + + cache.clear() + + XCTAssertTrue(cache.getObjectsFor(TransactionCacheKey.updatedTransactions).isEmpty) + XCTAssertTrue(cache.getObjectsFor(TransactionCacheKey.removedTransactions).isEmpty) + XCTAssertTrue(cache.getObjectsFor(TransactionCacheKey.updatedDownloads).isEmpty) + } +} diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/InAppPurchasePluginTests.m b/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/InAppPurchasePluginTests.m deleted file mode 100644 index 1820ff8f65a4..000000000000 --- a/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/InAppPurchasePluginTests.m +++ /dev/null @@ -1,990 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import -#import "FIAPaymentQueueHandler.h" -#import "RunnerTests-Swift.h" -#import "Stubs.h" - -@import in_app_purchase_storekit; - -@interface InAppPurchasePluginTest : XCTestCase - -@property(nonatomic, strong) FIAPReceiptManagerStub *receiptManagerStub; -@property(nonatomic, strong) InAppPurchasePlugin *plugin; - -@end - -@implementation InAppPurchasePluginTest - -- (void)setUp { - self.receiptManagerStub = [FIAPReceiptManagerStub new]; - self.plugin = [[InAppPurchasePluginStub alloc] - initWithReceiptManager:self.receiptManagerStub - handlerFactory:^DefaultRequestHandler *(SKRequest *request) { - return [[DefaultRequestHandler alloc] - initWithRequestHandler:[[FIAPRequestHandler alloc] initWithRequest:request]]; - }]; -} - -- (void)tearDown { -} - -- (void)testCanMakePayments { - FlutterError *error; - NSNumber *result = [self.plugin canMakePaymentsWithError:&error]; - XCTAssertTrue([result boolValue]); - XCTAssertNil(error); -} - -- (void)testPaymentQueueStorefront { - if (@available(iOS 13, macOS 10.15, *)) { - NSDictionary *storefrontMap = @{ - @"countryCode" : @"USA", - @"identifier" : @"unique_identifier", - }; - PaymentQueueStub *queueStub = [[PaymentQueueStub alloc] init]; - TransactionCacheStub *cache = [[TransactionCacheStub alloc] init]; - - queueStub.storefront = [[SKStorefrontStub alloc] initWithMap:storefrontMap]; - - self.plugin.paymentQueueHandler = [[FIAPaymentQueueHandler alloc] initWithQueue:queueStub - transactionsUpdated:nil - transactionRemoved:nil - restoreTransactionFailed:nil - restoreCompletedTransactionsFinished:nil - shouldAddStorePayment:nil - updatedDownloads:nil - transactionCache:cache]; - - FlutterError *error; - SKStorefrontMessage *result = [self.plugin storefrontWithError:&error]; - - XCTAssertEqualObjects(result.countryCode, storefrontMap[@"countryCode"]); - XCTAssertEqualObjects(result.identifier, storefrontMap[@"identifier"]); - XCTAssertNil(error); - } else { - NSLog(@"Skip testPaymentQueueStorefront for iOS lower than 13.0 or macOS lower than 10.15."); - } -} - -- (void)testPaymentQueueStorefrontReturnsNil { - if (@available(iOS 13, macOS 10.15, *)) { - PaymentQueueStub *queueStub = [[PaymentQueueStub alloc] init]; - TransactionCacheStub *cache = [[TransactionCacheStub alloc] init]; - - self.plugin.paymentQueueHandler = [[FIAPaymentQueueHandler alloc] initWithQueue:queueStub - transactionsUpdated:nil - transactionRemoved:nil - restoreTransactionFailed:nil - restoreCompletedTransactionsFinished:nil - shouldAddStorePayment:nil - updatedDownloads:nil - transactionCache:cache]; - - FlutterError *error; - SKStorefrontMessage *resultMap = [self.plugin storefrontWithError:&error]; - - XCTAssertNil(resultMap); - XCTAssertNil(error); - } else { - NSLog(@"Skip testPaymentQueueStorefront for iOS lower than 13.0 or macOS lower than 10.15."); - } -} - -- (void)testGetProductResponse { - NSArray *argument = @[ @"123" ]; - XCTestExpectation *expectation = - [self expectationWithDescription:@"completion handler successfully called"]; - [self.plugin - startProductRequestProductIdentifiers:argument - completion:^(SKProductsResponseMessage *_Nullable response, - FlutterError *_Nullable startProductRequestError) { - XCTAssert( - [response isKindOfClass:[SKProductsResponseMessage class]]); - XCTAssertEqual(response.products.count, 1); - XCTAssertEqual(response.invalidProductIdentifiers.count, 0); - XCTAssertEqual(response.products[0].productIdentifier, @"123"); - [expectation fulfill]; - }]; - [self waitForExpectations:@[ expectation ] timeout:5]; -} - -- (void)testFinishTransactionSucceeds { - NSDictionary *args = @{ - @"transactionIdentifier" : @"567", - @"productIdentifier" : @"unique_identifier", - }; - - NSDictionary *transactionMap = @{ - @"transactionIdentifier" : @"567", - @"transactionState" : @(SKPaymentTransactionStatePurchasing), - @"payment" : [NSNull null], - @"error" : [FIAObjectTranslator getMapFromNSError:[NSError errorWithDomain:@"test_stub" - code:123 - userInfo:@{}]], - @"transactionTimeStamp" : @([NSDate date].timeIntervalSince1970), - }; - - SKPaymentTransactionStub *paymentTransactionStub = - [[SKPaymentTransactionStub alloc] initWithMap:transactionMap]; - NSArray *array = @[ paymentTransactionStub ]; - - PaymentQueueStub *queue = [[PaymentQueueStub alloc] init]; - queue.transactions = array; - - TransactionCacheStub *cache = [[TransactionCacheStub alloc] init]; - - self.plugin.paymentQueueHandler = [[FIAPaymentQueueHandler alloc] initWithQueue:queue - transactionsUpdated:nil - transactionRemoved:nil - restoreTransactionFailed:nil - restoreCompletedTransactionsFinished:nil - shouldAddStorePayment:nil - updatedDownloads:nil - transactionCache:cache]; - - FlutterError *error; - [self.plugin finishTransactionFinishMap:args error:&error]; - - XCTAssertNil(error); -} - -- (void)testFinishTransactionSucceedsWithNilTransaction { - NSDictionary *args = @{ - @"transactionIdentifier" : [NSNull null], - @"productIdentifier" : @"unique_identifier", - }; - - NSDictionary *paymentMap = @{ - @"productIdentifier" : @"123", - @"requestData" : @"abcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefgh", - @"quantity" : @(2), - @"applicationUsername" : @"app user name", - @"simulatesAskToBuyInSandbox" : @(NO) - }; - - NSDictionary *transactionMap = @{ - @"transactionState" : @(SKPaymentTransactionStatePurchasing), - @"payment" : paymentMap, - @"error" : [FIAObjectTranslator getMapFromNSError:[NSError errorWithDomain:@"test_stub" - code:123 - userInfo:@{}]], - @"transactionTimeStamp" : @([NSDate date].timeIntervalSince1970), - }; - - SKPaymentTransactionStub *paymentTransactionStub = - [[SKPaymentTransactionStub alloc] initWithMap:transactionMap]; - - PaymentQueueStub *queueStub = [[PaymentQueueStub alloc] init]; - queueStub.transactions = @[ paymentTransactionStub ]; - - TransactionCacheStub *cache = [[TransactionCacheStub alloc] init]; - - self.plugin.paymentQueueHandler = [[FIAPaymentQueueHandler alloc] initWithQueue:queueStub - transactionsUpdated:nil - transactionRemoved:nil - restoreTransactionFailed:nil - restoreCompletedTransactionsFinished:nil - shouldAddStorePayment:nil - updatedDownloads:nil - transactionCache:cache]; - ; - - FlutterError *error; - [self.plugin finishTransactionFinishMap:args error:&error]; - - XCTAssertNil(error); -} - -- (void)testGetProductResponseWithRequestError { - NSArray *argument = @[ @"123" ]; - XCTestExpectation *expectation = - [self expectationWithDescription:@"completion handler successfully called"]; - - RequestHandlerStub *handlerStub = [[RequestHandlerStub alloc] init]; - InAppPurchasePlugin *plugin = [[InAppPurchasePlugin alloc] - initWithReceiptManager:_receiptManagerStub - handlerFactory:^RequestHandlerStub *(SKRequest *request) { - return handlerStub; - }]; - - NSError *error = [NSError errorWithDomain:@"errorDomain" - code:0 - userInfo:@{NSLocalizedDescriptionKey : @"description"}]; - - handlerStub.startProductRequestWithCompletionHandlerStub = - ^(ProductRequestCompletion _Nonnull completion) { - completion(nil, error); - }; - - [plugin - startProductRequestProductIdentifiers:argument - completion:^(SKProductsResponseMessage *_Nullable response, - FlutterError *_Nullable startProductRequestError) { - [expectation fulfill]; - XCTAssertNotNil(error); - XCTAssertNotNil(startProductRequestError); - XCTAssertEqualObjects( - startProductRequestError.code, - @"storekit_getproductrequest_platform_error"); - }]; - [self waitForExpectations:@[ expectation ] timeout:5]; -} - -- (void)testGetProductResponseWithNoResponse { - NSArray *argument = @[ @"123" ]; - XCTestExpectation *expectation = - [self expectationWithDescription:@"completion handler successfully called"]; - - RequestHandlerStub *handlerStub = [[RequestHandlerStub alloc] init]; - InAppPurchasePlugin *plugin = [[InAppPurchasePlugin alloc] - initWithReceiptManager:_receiptManagerStub - handlerFactory:^RequestHandlerStub *(SKRequest *request) { - return handlerStub; - }]; - - handlerStub.startProductRequestWithCompletionHandlerStub = - ^(ProductRequestCompletion _Nonnull completion) { - completion(nil, nil); - }; - - [plugin - startProductRequestProductIdentifiers:argument - completion:^(SKProductsResponseMessage *_Nullable response, - FlutterError *_Nullable startProductRequestError) { - [expectation fulfill]; - XCTAssertNotNil(startProductRequestError); - XCTAssertEqualObjects(startProductRequestError.code, - @"storekit_platform_no_response"); - }]; - [self waitForExpectations:@[ expectation ] timeout:5]; -} - -- (void)testAddPaymentShouldReturnFlutterErrorWhenPaymentFails { - NSDictionary *argument = @{ - @"productIdentifier" : @"123", - @"quantity" : @(1), - @"simulatesAskToBuyInSandbox" : @YES, - }; - - PaymentQueueHandlerStub *handlerStub = [[PaymentQueueHandlerStub alloc] init]; - self.plugin.paymentQueueHandler = handlerStub; - - FlutterError *error; - - __block NSInteger addPaymentInvokeCount = 0; - handlerStub.addPaymentStub = ^(SKPayment *payment) { - addPaymentInvokeCount += 1; - return NO; - }; - - [self.plugin addPaymentPaymentMap:argument error:&error]; - - XCTAssertEqual(addPaymentInvokeCount, 1); - XCTAssertEqualObjects(@"storekit_duplicate_product_object", error.code); - XCTAssertEqualObjects(@"There is a pending transaction for the same product identifier. " - @"Please either wait for it to be finished or finish it manually " - @"using `completePurchase` to avoid edge cases.", - error.message); - XCTAssertEqualObjects(argument, error.details); -} - -- (void)testAddPaymentShouldReturnFlutterErrorWhenInvalidProduct { - NSDictionary *argument = @{ - // stubbed function will return nil for an empty productIdentifier - @"productIdentifier" : @"", - @"quantity" : @(1), - @"simulatesAskToBuyInSandbox" : @YES, - }; - - FlutterError *error; - - [self.plugin addPaymentPaymentMap:argument error:&error]; - - XCTAssertEqualObjects(@"storekit_invalid_payment_object", error.code); - XCTAssertEqualObjects( - @"You have requested a payment for an invalid product. Either the " - @"`productIdentifier` of the payment is not valid or the product has not been " - @"fetched before adding the payment to the payment queue.", - error.message); - XCTAssertEqualObjects(argument, error.details); -} - -- (void)testAddPaymentSuccessWithoutPaymentDiscount { - NSDictionary *argument = @{ - @"productIdentifier" : @"123", - @"quantity" : @(1), - @"simulatesAskToBuyInSandbox" : @YES, - }; - - PaymentQueueHandlerStub *handlerStub = [[PaymentQueueHandlerStub alloc] init]; - self.plugin.paymentQueueHandler = handlerStub; - - __block NSInteger addPaymentInvokeCount = 0; - handlerStub.addPaymentStub = ^(SKPayment *payment) { - XCTAssert(payment != nil); - XCTAssertEqual(payment.productIdentifier, @"123"); - XCTAssert(payment.quantity == 1); - addPaymentInvokeCount++; - return YES; - }; - - FlutterError *error; - - [self.plugin addPaymentPaymentMap:argument error:&error]; - - XCTAssertNil(error); - XCTAssertEqual(addPaymentInvokeCount, 1); -} - -- (void)testAddPaymentSuccessWithPaymentDiscount { - NSDictionary *argument = @{ - @"productIdentifier" : @"123", - @"quantity" : @(1), - @"simulatesAskToBuyInSandbox" : @YES, - @"paymentDiscount" : @{ - @"identifier" : @"test_identifier", - @"keyIdentifier" : @"test_key_identifier", - @"nonce" : @"4a11a9cc-3bc3-11ec-8d3d-0242ac130003", - @"signature" : @"test_signature", - @"timestamp" : @(1635847102), - } - }; - - PaymentQueueHandlerStub *handlerStub = [[PaymentQueueHandlerStub alloc] init]; - self.plugin.paymentQueueHandler = handlerStub; - - __block NSInteger addPaymentInvokeCount = 0; - handlerStub.addPaymentStub = ^(SKPayment *payment) { - if (@available(iOS 12.2, *)) { - SKPaymentDiscount *discount = payment.paymentDiscount; - XCTAssertEqual(discount.identifier, @"test_identifier"); - XCTAssertEqual(discount.keyIdentifier, @"test_key_identifier"); - XCTAssertEqualObjects( - discount.nonce, - [[NSUUID alloc] initWithUUIDString:@"4a11a9cc-3bc3-11ec-8d3d-0242ac130003"]); - XCTAssertEqual(discount.signature, @"test_signature"); - addPaymentInvokeCount++; - return YES; - } - addPaymentInvokeCount++; - return YES; - }; - - FlutterError *error; - - [self.plugin addPaymentPaymentMap:argument error:&error]; - XCTAssertEqual(addPaymentInvokeCount, 1); - XCTAssertNil(error); -} - -- (void)testAddPaymentFailureWithInvalidPaymentDiscount { - // Support for payment discount is only available on iOS 12.2 and higher. - if (@available(iOS 12.2, *)) { - NSDictionary *invalidDiscount = @{ - @"productIdentifier" : @"123", - @"quantity" : @(1), - @"simulatesAskToBuyInSandbox" : @YES, - @"paymentDiscount" : @{ - /// This payment discount is missing the field `identifier`, and is thus malformed - @"keyIdentifier" : @"test_key_identifier", - @"nonce" : @"4a11a9cc-3bc3-11ec-8d3d-0242ac130003", - @"signature" : @"test_signature", - @"timestamp" : @(1635847102), - } - }; - - PaymentQueueHandlerStub *handlerStub = [[PaymentQueueHandlerStub alloc] init]; - - __block NSInteger addPaymentCount = 0; - handlerStub.addPaymentStub = ^BOOL(SKPayment *_Nonnull payment) { - addPaymentCount++; - return YES; - }; - - self.plugin.paymentQueueHandler = handlerStub; - FlutterError *error; - - [self.plugin addPaymentPaymentMap:invalidDiscount error:&error]; - - XCTAssertEqualObjects(@"storekit_invalid_payment_discount_object", error.code); - XCTAssertEqualObjects(@"You have requested a payment and specified a " - @"payment discount with invalid properties. When specifying a payment " - @"discount the 'identifier' field is mandatory.", - error.message); - XCTAssertEqualObjects(invalidDiscount, error.details); - XCTAssertEqual(0, addPaymentCount); - } -} - -- (void)testAddPaymentWithNullSandboxArgument { - NSDictionary *argument = @{ - @"productIdentifier" : @"123", - @"quantity" : @(1), - @"simulatesAskToBuyInSandbox" : [NSNull null], - }; - - PaymentQueueHandlerStub *handlerStub = [[PaymentQueueHandlerStub alloc] init]; - self.plugin.paymentQueueHandler = handlerStub; - FlutterError *error; - - __block NSInteger addPaymentInvokeCount = 0; - handlerStub.addPaymentStub = ^(SKPayment *payment) { - XCTAssertEqual(payment.simulatesAskToBuyInSandbox, false); - addPaymentInvokeCount++; - return YES; - }; - - [self.plugin addPaymentPaymentMap:argument error:&error]; - XCTAssertEqual(addPaymentInvokeCount, 1); -} - -- (void)testRestoreTransactions { - XCTestExpectation *expectation = - [self expectationWithDescription:@"result successfully restore transactions"]; - - TransactionCacheStub *cacheStub = [[TransactionCacheStub alloc] init]; - PaymentQueueStub *queueStub = [[PaymentQueueStub alloc] init]; - - __block BOOL callbackInvoked = NO; - self.plugin.paymentQueueHandler = [[FIAPaymentQueueHandler alloc] initWithQueue:queueStub - transactionsUpdated:^(NSArray *_Nonnull transactions) { - } - transactionRemoved:nil - restoreTransactionFailed:nil - restoreCompletedTransactionsFinished:^() { - callbackInvoked = YES; - [expectation fulfill]; - } - shouldAddStorePayment:nil - updatedDownloads:nil - transactionCache:cacheStub]; - [queueStub addTransactionObserver:self.plugin.paymentQueueHandler]; - - FlutterError *error; - [self.plugin restoreTransactionsApplicationUserName:nil error:&error]; - - [self waitForExpectations:@[ expectation ] timeout:5]; - XCTAssertTrue(callbackInvoked); -} - -- (void)testRetrieveReceiptDataSuccess { - FlutterError *error; - NSString *result = [self.plugin retrieveReceiptDataWithError:&error]; - XCTAssertNotNil(result); - XCTAssert([result isKindOfClass:[NSString class]]); -} - -- (void)testRetrieveReceiptDataNil { - self.receiptManagerStub.returnNilURL = YES; - - FlutterError *error; - NSString *result = [self.plugin retrieveReceiptDataWithError:&error]; - XCTAssertNil(result); -} - -- (void)testRetrieveReceiptDataError { - self.receiptManagerStub.returnError = YES; - - FlutterError *error; - NSString *result = [self.plugin retrieveReceiptDataWithError:&error]; - - XCTAssertNil(result); - XCTAssertNotNil(error); - XCTAssert([error.code isKindOfClass:[NSString class]]); - NSDictionary *details = error.details; - XCTAssertNotNil(details[@"error"]); - NSNumber *errorCode = (NSNumber *)details[@"error"][@"code"]; - XCTAssertEqual(errorCode, [NSNumber numberWithInteger:99]); -} - -- (void)testRefreshReceiptRequest { - XCTestExpectation *expectation = - [self expectationWithDescription:@"completion handler successfully called"]; - - RequestHandlerStub *handlerStub = [[RequestHandlerStub alloc] init]; - InAppPurchasePlugin *plugin = [[InAppPurchasePlugin alloc] - initWithReceiptManager:_receiptManagerStub - handlerFactory:^RequestHandlerStub *(SKRequest *request) { - return handlerStub; - }]; - - NSError *recieptError = [NSError errorWithDomain:@"errorDomain" - code:0 - userInfo:@{NSLocalizedDescriptionKey : @"description"}]; - - handlerStub.startProductRequestWithCompletionHandlerStub = - ^(ProductRequestCompletion _Nonnull completion) { - completion(nil, recieptError); - }; - - [plugin refreshReceiptReceiptProperties:nil - completion:^(FlutterError *_Nullable error) { - [expectation fulfill]; - }]; - [self waitForExpectations:@[ expectation ] timeout:5]; -} - -- (void)testRefreshReceiptRequestWithParams { - NSDictionary *properties = @{ - @"isExpired" : @NO, - @"isRevoked" : @NO, - @"isVolumePurchase" : @NO, - }; - - XCTestExpectation *expectation = - [self expectationWithDescription:@"completion handler successfully called"]; - - RequestHandlerStub *handlerStub = [[RequestHandlerStub alloc] init]; - InAppPurchasePlugin *plugin = [[InAppPurchasePlugin alloc] - initWithReceiptManager:_receiptManagerStub - handlerFactory:^RequestHandlerStub *(SKRequest *request) { - return handlerStub; - }]; - - NSError *recieptError = [NSError errorWithDomain:@"errorDomain" - code:0 - userInfo:@{NSLocalizedDescriptionKey : @"description"}]; - - handlerStub.startProductRequestWithCompletionHandlerStub = - ^(ProductRequestCompletion _Nonnull completion) { - completion(nil, recieptError); - }; - - [plugin refreshReceiptReceiptProperties:properties - completion:^(FlutterError *_Nullable error) { - [expectation fulfill]; - }]; - - [self waitForExpectations:@[ expectation ] timeout:5]; -} - -- (void)testRefreshReceiptRequestWithError { - NSDictionary *properties = @{ - @"isExpired" : @NO, - @"isRevoked" : @NO, - @"isVolumePurchase" : @NO, - }; - XCTestExpectation *expectation = - [self expectationWithDescription:@"completion handler successfully called"]; - - RequestHandlerStub *handlerStub = [[RequestHandlerStub alloc] init]; - InAppPurchasePlugin *plugin = [[InAppPurchasePlugin alloc] - initWithReceiptManager:_receiptManagerStub - handlerFactory:^RequestHandlerStub *(SKRequest *request) { - return handlerStub; - }]; - - NSError *recieptError = [NSError errorWithDomain:@"errorDomain" - code:0 - userInfo:@{NSLocalizedDescriptionKey : @"description"}]; - - handlerStub.startProductRequestWithCompletionHandlerStub = - ^(ProductRequestCompletion _Nonnull completion) { - completion(nil, recieptError); - }; - - [plugin refreshReceiptReceiptProperties:properties - completion:^(FlutterError *_Nullable error) { - XCTAssertNotNil(error); - XCTAssertEqualObjects( - error.code, @"storekit_refreshreceiptrequest_platform_error"); - [expectation fulfill]; - }]; - [self waitForExpectations:@[ expectation ] timeout:5]; -} - -/// presentCodeRedemptionSheetWithError:error is only available on iOS -#if TARGET_OS_IOS -- (void)testPresentCodeRedemptionSheet { - PaymentQueueHandlerStub *handlerStub = [[PaymentQueueHandlerStub alloc] init]; - self.plugin.paymentQueueHandler = handlerStub; - - __block NSInteger presentCodeRedemptionSheetCount = 0; - handlerStub.presentCodeRedemptionSheetStub = ^{ - presentCodeRedemptionSheetCount++; - }; - - FlutterError *error; - [self.plugin presentCodeRedemptionSheetWithError:&error]; - - XCTAssertEqual(1, presentCodeRedemptionSheetCount); -} -#endif - -- (void)testGetPendingTransactions { - PaymentQueueStub *queueStub = [[PaymentQueueStub alloc] init]; - TransactionCacheStub *cacheStub = [[TransactionCacheStub alloc] init]; - NSDictionary *transactionMap = @{ - @"transactionIdentifier" : [NSNull null], - @"transactionState" : @(SKPaymentTransactionStatePurchasing), - @"payment" : [NSNull null], - @"error" : [FIAObjectTranslator getMapFromNSError:[NSError errorWithDomain:@"test_stub" - code:123 - userInfo:@{}]], - @"transactionTimeStamp" : @([NSDate date].timeIntervalSince1970), - @"originalTransaction" : [NSNull null], - }; - queueStub.transactions = @[ [[SKPaymentTransactionStub alloc] initWithMap:transactionMap] ]; - self.plugin.paymentQueueHandler = [[FIAPaymentQueueHandler alloc] initWithQueue:queueStub - transactionsUpdated:nil - transactionRemoved:nil - restoreTransactionFailed:nil - restoreCompletedTransactionsFinished:nil - shouldAddStorePayment:nil - updatedDownloads:nil - transactionCache:cacheStub]; - FlutterError *error; - SKPaymentTransactionStub *original = - [[SKPaymentTransactionStub alloc] initWithMap:transactionMap]; - - SKPaymentTransactionMessage *originalPigeon = - [FIAObjectTranslator convertTransactionToPigeon:original]; - SKPaymentTransactionMessage *result = [self.plugin transactionsWithError:&error][0]; - - XCTAssertEqualObjects([self paymentTransactionToList:result], - [self paymentTransactionToList:originalPigeon]); -} - -- (void)testStartObservingPaymentQueue { - PaymentQueueHandlerStub *handlerStub = [[PaymentQueueHandlerStub alloc] init]; - self.plugin.paymentQueueHandler = handlerStub; - - __block NSInteger startObservingCount = 0; - handlerStub.startObservingPaymentQueueStub = ^{ - startObservingCount++; - }; - - FlutterError *error; - [self.plugin startObservingPaymentQueueWithError:&error]; - - XCTAssertEqual(1, startObservingCount); -} - -- (void)testStopObservingPaymentQueue { - PaymentQueueHandlerStub *handlerStub = [[PaymentQueueHandlerStub alloc] init]; - self.plugin.paymentQueueHandler = handlerStub; - - __block NSInteger stopObservingCount = 0; - handlerStub.stopObservingPaymentQueueStub = ^{ - stopObservingCount++; - }; - - FlutterError *error; - [self.plugin stopObservingPaymentQueueWithError:&error]; - - XCTAssertEqual(1, stopObservingCount); -} - -#if TARGET_OS_IOS -- (void)testRegisterPaymentQueueDelegate { - TransactionCacheStub *cacheStub = [[TransactionCacheStub alloc] init]; - PaymentQueueStub *queueStub = [[PaymentQueueStub alloc] init]; - if (@available(iOS 13, *)) { - self.plugin.paymentQueueHandler = [[FIAPaymentQueueHandler alloc] initWithQueue:queueStub - transactionsUpdated:nil - transactionRemoved:nil - restoreTransactionFailed:nil - restoreCompletedTransactionsFinished:nil - shouldAddStorePayment:nil - updatedDownloads:nil - transactionCache:cacheStub]; - - self.plugin.registrar = [[FlutterPluginRegistrarStub alloc] init]; - - // Verify the delegate is nil before we register one. - XCTAssertNil(self.plugin.paymentQueueHandler.delegate); - - FlutterError *error; - [self.plugin registerPaymentQueueDelegateWithError:&error]; - - // Verify the delegate is not nil after we registered one. - XCTAssertNotNil(self.plugin.paymentQueueHandler.delegate); - } -} - -- (void)testRemovePaymentQueueDelegate { - if (@available(iOS 13, *)) { - TransactionCacheStub *cacheStub = [[TransactionCacheStub alloc] init]; - PaymentQueueStub *queueStub = [[PaymentQueueStub alloc] init]; - self.plugin.paymentQueueHandler = [[FIAPaymentQueueHandler alloc] initWithQueue:queueStub - transactionsUpdated:nil - transactionRemoved:nil - restoreTransactionFailed:nil - restoreCompletedTransactionsFinished:nil - shouldAddStorePayment:nil - updatedDownloads:nil - transactionCache:cacheStub]; - - self.plugin.registrar = [[FlutterPluginRegistrarStub alloc] init]; - - // Verify the delegate is nil before we register one. - XCTAssertNil(self.plugin.paymentQueueHandler.delegate); - - FlutterError *error; - [self.plugin registerPaymentQueueDelegateWithError:&error]; - - // Verify the delegate is not nil before removing it. - XCTAssertNotNil(self.plugin.paymentQueueHandler.delegate); - - [self.plugin removePaymentQueueDelegateWithError:&error]; - - // Verify the delegate is nill after removing it. - XCTAssertNil(self.plugin.paymentQueueHandler.delegate); - } -} -#endif - -- (void)testHandleTransactionsUpdated { - NSDictionary *transactionMap = @{ - @"transactionIdentifier" : @"567", - @"transactionState" : @(SKPaymentTransactionStatePurchasing), - @"payment" : [NSNull null], - @"error" : [FIAObjectTranslator getMapFromNSError:[NSError errorWithDomain:@"test_stub" - code:123 - userInfo:@{}]], - @"transactionTimeStamp" : @([NSDate date].timeIntervalSince1970), - }; - - InAppPurchasePlugin *plugin = [[InAppPurchasePluginStub alloc] - initWithReceiptManager:self.receiptManagerStub - handlerFactory:^DefaultRequestHandler *(SKRequest *request) { - return [[DefaultRequestHandler alloc] - initWithRequestHandler:[[FIAPRequestHandler alloc] initWithRequest:request]]; - }]; - MethodChannelStub *channelStub = [[MethodChannelStub alloc] init]; - __block NSInteger invokeMethodCount = 0; - - channelStub.invokeMethodChannelStub = ^(NSString *_Nonnull method, id _Nonnull arguments) { - XCTAssertEqualObjects(@"updatedTransactions", method); - XCTAssertNotNil(arguments); - invokeMethodCount++; - }; - - // (TODO: louisehsu) Change this to inject the channel, like requestHandler - plugin.transactionObserverCallbackChannel = channelStub; - - SKPaymentTransactionStub *paymentTransactionStub = - [[SKPaymentTransactionStub alloc] initWithMap:transactionMap]; - NSArray *array = [NSArray arrayWithObjects:paymentTransactionStub, nil]; - NSMutableArray *maps = [NSMutableArray new]; - [maps addObject:[FIAObjectTranslator getMapFromSKPaymentTransaction:paymentTransactionStub]]; - - [plugin handleTransactionsUpdated:array]; - XCTAssertEqual(invokeMethodCount, 1); -} - -- (void)testHandleTransactionsRemoved { - NSDictionary *transactionMap = @{ - @"transactionIdentifier" : @"567", - @"transactionState" : @(SKPaymentTransactionStatePurchasing), - @"payment" : [NSNull null], - @"error" : [FIAObjectTranslator getMapFromNSError:[NSError errorWithDomain:@"test_stub" - code:123 - userInfo:@{}]], - @"transactionTimeStamp" : @([NSDate date].timeIntervalSince1970), - }; - - InAppPurchasePlugin *plugin = [[InAppPurchasePluginStub alloc] - initWithReceiptManager:self.receiptManagerStub - handlerFactory:^DefaultRequestHandler *(SKRequest *request) { - return [[DefaultRequestHandler alloc] - initWithRequestHandler:[[FIAPRequestHandler alloc] initWithRequest:request]]; - }]; - SKPaymentTransactionStub *paymentTransactionStub = - [[SKPaymentTransactionStub alloc] initWithMap:transactionMap]; - NSArray *array = [NSArray arrayWithObjects:paymentTransactionStub, nil]; - NSMutableArray *maps = [NSMutableArray new]; - [maps addObject:[FIAObjectTranslator getMapFromSKPaymentTransaction:paymentTransactionStub]]; - - MethodChannelStub *channelStub = [[MethodChannelStub alloc] init]; - __block NSInteger invokeMethodCount = 0; - - channelStub.invokeMethodChannelStub = ^(NSString *_Nonnull method, id _Nonnull arguments) { - XCTAssertEqualObjects(@"removedTransactions", method); - XCTAssertEqualObjects(maps, arguments); - invokeMethodCount++; - }; - - // (TODO: louisehsu) Change this to inject the channel, like requestHandler - plugin.transactionObserverCallbackChannel = channelStub; - - [plugin handleTransactionsRemoved:array]; - XCTAssertEqual(invokeMethodCount, 1); -} - -- (void)testHandleTransactionRestoreFailed { - InAppPurchasePlugin *plugin = [[InAppPurchasePluginStub alloc] - initWithReceiptManager:self.receiptManagerStub - handlerFactory:^DefaultRequestHandler *(SKRequest *request) { - return [[DefaultRequestHandler alloc] - initWithRequestHandler:[[FIAPRequestHandler alloc] initWithRequest:request]]; - }]; - MethodChannelStub *channelStub = [[MethodChannelStub alloc] init]; - __block NSInteger invokeMethodCount = 0; - NSError *error = [NSError errorWithDomain:@"error" code:0 userInfo:nil]; - - channelStub.invokeMethodChannelStub = ^(NSString *_Nonnull method, id _Nonnull arguments) { - XCTAssertEqualObjects(@"restoreCompletedTransactionsFailed", method); - XCTAssertEqualObjects([FIAObjectTranslator getMapFromNSError:error], arguments); - invokeMethodCount++; - }; - - // (TODO: louisehsu) Change this to inject the channel, like requestHandler - plugin.transactionObserverCallbackChannel = channelStub; - - [plugin handleTransactionRestoreFailed:error]; - XCTAssertEqual(invokeMethodCount, 1); -} - -- (void)testRestoreCompletedTransactionsFinished { - InAppPurchasePlugin *plugin = [[InAppPurchasePluginStub alloc] - initWithReceiptManager:self.receiptManagerStub - handlerFactory:^DefaultRequestHandler *(SKRequest *request) { - return [[DefaultRequestHandler alloc] - initWithRequestHandler:[[FIAPRequestHandler alloc] initWithRequest:request]]; - }]; - MethodChannelStub *channelStub = [[MethodChannelStub alloc] init]; - __block NSInteger invokeMethodCount = 0; - channelStub.invokeMethodChannelStub = ^(NSString *_Nonnull method, id _Nonnull arguments) { - XCTAssertEqualObjects(@"paymentQueueRestoreCompletedTransactionsFinished", method); - XCTAssertNil(arguments); - invokeMethodCount++; - }; - - // (TODO: louisehsu) Change this to inject the channel, like requestHandler - plugin.transactionObserverCallbackChannel = channelStub; - - [plugin restoreCompletedTransactionsFinished]; - XCTAssertEqual(invokeMethodCount, 1); -} - -- (void)testShouldAddStorePayment { - NSDictionary *paymentMap = @{ - @"productIdentifier" : @"123", - @"requestData" : @"abcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefgh", - @"quantity" : @(2), - @"applicationUsername" : @"app user name", - @"simulatesAskToBuyInSandbox" : @(NO) - }; - - NSDictionary *productMap = @{ - @"price" : @"1", - @"priceLocale" : [FIAObjectTranslator getMapFromNSLocale:NSLocale.systemLocale], - @"productIdentifier" : @"123", - @"localizedTitle" : @"title", - @"localizedDescription" : @"des", - }; - - SKMutablePayment *payment = [FIAObjectTranslator getSKMutablePaymentFromMap:paymentMap]; - SKProductStub *productStub = [[SKProductStub alloc] initWithMap:productMap]; - - InAppPurchasePlugin *plugin = [[InAppPurchasePluginStub alloc] - initWithReceiptManager:self.receiptManagerStub - handlerFactory:^DefaultRequestHandler *(SKRequest *request) { - return [[DefaultRequestHandler alloc] - initWithRequestHandler:[[FIAPRequestHandler alloc] initWithRequest:request]]; - }]; - - NSDictionary *args = @{ - @"payment" : [FIAObjectTranslator getMapFromSKPayment:payment], - @"product" : [FIAObjectTranslator getMapFromSKProduct:productStub] - }; - - MethodChannelStub *channelStub = [[MethodChannelStub alloc] init]; - - __block NSInteger invokeMethodCount = 0; - channelStub.invokeMethodChannelStub = ^(NSString *_Nonnull method, id _Nonnull arguments) { - XCTAssertEqualObjects(@"shouldAddStorePayment", method); - XCTAssertEqualObjects(args, arguments); - invokeMethodCount++; - }; - - // (TODO: louisehsu) Change this to inject the channel, like requestHandler - plugin.transactionObserverCallbackChannel = channelStub; - - BOOL result = [plugin shouldAddStorePaymentWithPayment:payment product:productStub]; - XCTAssertEqual(result, NO); - XCTAssertEqual(invokeMethodCount, 1); -} - -#if TARGET_OS_IOS -- (void)testShowPriceConsentIfNeeded { - TransactionCacheStub *cacheStub = [[TransactionCacheStub alloc] init]; - PaymentQueueStub *queueStub = [[PaymentQueueStub alloc] init]; - self.plugin.paymentQueueHandler = [[FIAPaymentQueueHandler alloc] initWithQueue:queueStub - transactionsUpdated:nil - transactionRemoved:nil - restoreTransactionFailed:nil - restoreCompletedTransactionsFinished:nil - shouldAddStorePayment:nil - updatedDownloads:nil - transactionCache:cacheStub]; - - FlutterError *error; - __block NSInteger showPriceConsentIfNeededCount = 0; - - queueStub.showPriceConsentIfNeededStub = ^(void) { - showPriceConsentIfNeededCount++; - }; - - [self.plugin showPriceConsentIfNeededWithError:&error]; - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wpartial-availability" - if (@available(iOS 13.4, *)) { - XCTAssertEqual(showPriceConsentIfNeededCount, 1); - } else { - XCTAssertEqual(showPriceConsentIfNeededCount, 0); - } -#pragma clang diagnostic pop -} -#endif - -// The following methods are deserializer copied from Pigeon's output. - -- (NSArray *)paymentTransactionToList:(SKPaymentTransactionMessage *)paymentTransaction { - return @[ - (paymentTransaction.payment ? [self paymentToList:paymentTransaction.payment] : [NSNull null]), - @(paymentTransaction.transactionState), - (paymentTransaction.originalTransaction - ? [self paymentTransactionToList:paymentTransaction.originalTransaction] - : [NSNull null]), - paymentTransaction.transactionTimeStamp ?: [NSNull null], - paymentTransaction.transactionIdentifier ?: [NSNull null], - (paymentTransaction.error ? [self errorToList:paymentTransaction.error] : [NSNull null]), - ]; -} - -- (NSArray *)paymentToList:(SKPaymentMessage *)payment { - return @[ - payment.productIdentifier ?: [NSNull null], - payment.applicationUsername ?: [NSNull null], - payment.requestData ?: [NSNull null], - @(payment.quantity), - @(payment.simulatesAskToBuyInSandbox), - (payment.paymentDiscount ? [self paymentDiscountToList:payment.paymentDiscount] - : [NSNull null]), - ]; -} - -- (NSArray *)paymentDiscountToList:(SKPaymentDiscountMessage *)discount { - return @[ - discount.identifier ?: [NSNull null], - discount.keyIdentifier ?: [NSNull null], - discount.nonce ?: [NSNull null], - discount.signature ?: [NSNull null], - @(discount.timestamp), - ]; -} - -- (NSArray *)errorToList:(SKErrorMessage *)error { - return @[ - @(error.code), - error.domain ?: [NSNull null], - error.userInfo ?: [NSNull null], - ]; -} -@end diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/InAppPurchasePluginTests.swift b/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/InAppPurchasePluginTests.swift new file mode 100644 index 000000000000..a074f133161b --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/InAppPurchasePluginTests.swift @@ -0,0 +1,856 @@ +// 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 Foundation +import StoreKitTest +import XCTest + +@testable import in_app_purchase_storekit + +final class InAppPurchasePluginTests: XCTestCase { + var receiptManagerStub: FIAPReceiptManagerStub! + var plugin: InAppPurchasePlugin! + + override func setUp() { + super.setUp() + receiptManagerStub = FIAPReceiptManagerStub() + plugin = InAppPurchasePluginStub(receiptManager: receiptManagerStub) { request in + DefaultRequestHandler(requestHandler: FIAPRequestHandler(request: request)) + } + } + + override func tearDown() { + receiptManagerStub = nil + plugin = nil + super.tearDown() + } + + func testCanMakePayments() throws { + var error: FlutterError? + let result = plugin.canMakePaymentsWithError(&error) + let unwrappedResult = try XCTUnwrap(result) + XCTAssertTrue(unwrappedResult.boolValue) + XCTAssertNil(error) + } + + func testPaymentQueueStorefrontReturnsNil() throws { + if #available(iOS 13, macOS 10.15, *) { + let storefrontMap = [ + "countryCode": "USA", + "identifier": "unique_identifier", + ] + let queueStub = PaymentQueueStub() + let cache = TransactionCacheStub() + + queueStub.storefront = SKStorefrontStub(map: storefrontMap) + + plugin.paymentQueueHandler = FIAPaymentQueueHandler( + queue: queueStub, + transactionsUpdated: nil, + transactionRemoved: nil, + restoreTransactionFailed: nil, + restoreCompletedTransactionsFinished: nil, + shouldAddStorePayment: nil, + updatedDownloads: nil, + transactionCache: cache) + + var error: FlutterError? + let result = plugin.storefrontWithError(&error) + + let unwrappedResult = try XCTUnwrap(result) + XCTAssertEqual(unwrappedResult.countryCode, storefrontMap["countryCode"]) + XCTAssertEqual(unwrappedResult.identifier, storefrontMap["identifier"]) + XCTAssertNil(error) + } else { + print("Skip testPaymentQueueStorefront for iOS lower than 13.0 or macOS lower than 10.15.") + } + } + func testGetProductResponse() { + let argument = ["123"] + let expectation = self.expectation(description: "completion handler successfully called") + + plugin.startProductRequestProductIdentifiers(argument) { response, startProductRequestError in + guard let response = response else { + XCTFail("Response should not be nil") + return + } + + guard let unwrappedProducts = response.products else { + XCTFail("Products should not be nil") + return + } + + XCTAssertEqual(unwrappedProducts.count, 1) + XCTAssertEqual(response.invalidProductIdentifiers, []) + XCTAssertEqual(unwrappedProducts[0].productIdentifier, "123") + expectation.fulfill() + } + + waitForExpectations(timeout: 5, handler: nil) + } + + func testFinishTransactionSucceedsWithNilTransaction() { + let args: [String: Any] = [ + "transactionIdentifier": NSNull(), + "productIdentifier": "unique_identifier", + ] + + let paymentMap: [String: Any] = [ + "productIdentifier": "123", + "requestData": "abcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefgh", + "quantity": 2, + "applicationUsername": "app user name", + "simulatesAskToBuyInSandbox": false, + ] + + let transactionMap: [String: Any] = [ + "transactionState": SKPaymentTransactionState.purchasing.rawValue, + "payment": paymentMap, + "error": FIAObjectTranslator.getMapFrom( + NSError(domain: "test_stub", code: 123, userInfo: [:])), + "transactionTimeStamp": NSDate().timeIntervalSince1970, + ] + + let paymentTransactionStub = SKPaymentTransactionStub(map: transactionMap) + + let queueStub = PaymentQueueStub() + queueStub.transactions = [paymentTransactionStub] + + let cache = TransactionCacheStub() + + plugin.paymentQueueHandler = FIAPaymentQueueHandler( + queue: queueStub, + transactionsUpdated: nil, + transactionRemoved: nil, + restoreTransactionFailed: nil, + restoreCompletedTransactionsFinished: nil, + shouldAddStorePayment: nil, + updatedDownloads: nil, + transactionCache: cache) + + var error: FlutterError? + plugin.finishTransactionFinishMap(args, error: &error) + + XCTAssertNil(error) + } + + func testGetProductResponseWithRequestError() { + let argument = ["123"] + let expectation = self.expectation(description: "completion handler successfully called") + + let handlerStub = RequestHandlerStub() + let plugin = InAppPurchasePlugin(receiptManager: receiptManagerStub) { request in + return handlerStub + } + + let error = NSError( + domain: "errorDomain", code: 0, userInfo: [NSLocalizedDescriptionKey: "description"]) + + handlerStub.startProductRequestWithCompletionHandlerStub = { completion in + completion(nil, error) + } + + plugin.startProductRequestProductIdentifiers(argument) { response, startProductRequestError in + expectation.fulfill() + XCTAssertNotNil(error) + XCTAssertNotNil(startProductRequestError) + XCTAssertEqual(startProductRequestError?.code, "storekit_getproductrequest_platform_error") + } + + waitForExpectations(timeout: 5, handler: nil) + } + + func testGetProductResponseWithNoResponse() { + let argument = ["123"] + let expectation = self.expectation(description: "completion handler successfully called") + + let handlerStub = RequestHandlerStub() + let plugin = InAppPurchasePlugin(receiptManager: receiptManagerStub) { request in + return handlerStub + } + + let error = NSError( + domain: "errorDomain", code: 0, userInfo: [NSLocalizedDescriptionKey: "description"]) + + handlerStub.startProductRequestWithCompletionHandlerStub = { completion in + completion(nil, nil) + } + + plugin.startProductRequestProductIdentifiers(argument) { response, startProductRequestError in + expectation.fulfill() + XCTAssertNotNil(error) + XCTAssertNotNil(startProductRequestError) + XCTAssertEqual(startProductRequestError?.code, "storekit_platform_no_response") + } + + waitForExpectations(timeout: 5, handler: nil) + } + + func testAddPaymentShouldReturnFlutterErrorWhenPaymentFails() { + let argument: [String: Any] = [ + "productIdentifier": "123", + "quantity": 1, + "simulatesAskToBuyInSandbox": true, + ] + + let handlerStub = PaymentQueueHandlerStub() + plugin.paymentQueueHandler = handlerStub + + var error: FlutterError? + + var addPaymentInvokeCount = 0 + handlerStub.addPaymentStub = { payment in + addPaymentInvokeCount += 1 + return false + } + + plugin.addPaymentPaymentMap(argument, error: &error) + + XCTAssertEqual(addPaymentInvokeCount, 1) + + guard let error = error else { + XCTFail("Error should not be nil") + return + } + + XCTAssertEqual(error.code, "storekit_duplicate_product_object") + XCTAssertEqual( + error.message, + "There is a pending transaction for the same product identifier. Please either wait for it to be finished or finish it manually using `completePurchase` to avoid edge cases." + ) + XCTAssertEqual(error.details as! NSDictionary, argument as NSDictionary) + } + + func testAddPaymentShouldReturnFlutterErrorWhenInvalidProduct() { + let argument: [String: Any] = [ + // stubbed function will return nil for an empty productIdentifier + "productIdentifier": "", + "quantity": 1, + "simulatesAskToBuyInSandbox": true, + ] + + var error: FlutterError? + plugin.addPaymentPaymentMap(argument, error: &error) + + guard let error = error else { + XCTFail("Error should not be nil") + return + } + + XCTAssertEqual(error.code, "storekit_invalid_payment_object") + XCTAssertEqual( + error.message, + "You have requested a payment for an invalid product. Either the `productIdentifier` of the payment is not valid or the product has not been fetched before adding the payment to the payment queue." + ) + XCTAssertEqual(error.details as! NSDictionary, argument as NSDictionary) + } + + func testAddPaymentSuccessWithoutPaymentDiscount() { + let argument: [String: Any] = [ + "productIdentifier": "123", + "quantity": 1, + "simulatesAskToBuyInSandbox": true, + ] + + let handlerStub = PaymentQueueHandlerStub() + plugin.paymentQueueHandler = handlerStub + + var error: FlutterError? + + var addPaymentInvokeCount = 0 + handlerStub.addPaymentStub = { payment in + XCTAssertNotNil(payment) + XCTAssertEqual(payment.productIdentifier, "123") + XCTAssertEqual(payment.quantity, 1) + addPaymentInvokeCount += 1 + return false + } + + plugin.addPaymentPaymentMap(argument, error: &error) + + XCTAssertEqual(addPaymentInvokeCount, 1) + + guard let error = error else { + XCTFail("Error should not be nil") + return + } + + XCTAssertEqual(error.code, "storekit_duplicate_product_object") + XCTAssertEqual( + error.message, + "There is a pending transaction for the same product identifier. Please either wait for it to be finished or finish it manually using `completePurchase` to avoid edge cases." + ) + XCTAssertEqual(error.details as! NSDictionary, argument as NSDictionary) + } + + func testAddPaymentSuccessWithPaymentDiscount() { + let argument: [String: Any] = [ + "productIdentifier": "123", + "quantity": 1, + "simulatesAskToBuyInSandbox": true, + "paymentDiscount": [ + "identifier": "test_identifier", + "keyIdentifier": "test_key_identifier", + "nonce": "4a11a9cc-3bc3-11ec-8d3d-0242ac130003", + "signature": "test_signature", + "timestamp": 1_635_847_102, + ], + ] + + let handlerStub = PaymentQueueHandlerStub() + plugin.paymentQueueHandler = handlerStub + + var addPaymentInvokeCount = 0 + handlerStub.addPaymentStub = { payment in + if #available(iOS 12.2, *) { + guard let discount = payment.paymentDiscount else { + XCTFail("Discount should not be nil") + return false + } + XCTAssertEqual(discount.identifier, "test_identifier") + XCTAssertEqual(discount.keyIdentifier, "test_key_identifier") + XCTAssertEqual(discount.nonce, UUID(uuidString: "4a11a9cc-3bc3-11ec-8d3d-0242ac130003")) + XCTAssertEqual(discount.signature, "test_signature") + XCTAssertEqual(discount.timestamp, 1_635_847_102) + addPaymentInvokeCount += 1 + return true + } else { + addPaymentInvokeCount += 1 + return true + } + } + + var error: FlutterError? + + plugin.addPaymentPaymentMap(argument, error: &error) + XCTAssertEqual(addPaymentInvokeCount, 1) + XCTAssertNil(error) + } + + func testAddPaymentFailureWithInvalidPaymentDiscount() { + if #available(iOS 12.2, *) { + let invalidDiscount: [String: Any] = [ + "productIdentifier": "123", + "quantity": 1, + "simulatesAskToBuyInSandbox": true, + "paymentDiscount": [ + // This payment discount is missing the field `identifier`, and is thus malformed + "keyIdentifier": "test_key_identifier", + "nonce": "4a11a9cc-3bc3-11ec-8d3d-0242ac130003", + "signature": "test_signature", + "timestamp": 1_635_847_102, + ], + ] + + let handlerStub = PaymentQueueHandlerStub() + + var addPaymentCount = 0 + handlerStub.addPaymentStub = { payment in + addPaymentCount += 1 + return true + } + + plugin.paymentQueueHandler = handlerStub + var error: FlutterError? + + plugin.addPaymentPaymentMap(invalidDiscount, error: &error) + + guard let error = error else { + XCTFail("Error should not be nil") + return + } + + XCTAssertEqual(error.code, "storekit_invalid_payment_discount_object") + XCTAssertEqual( + error.message, + "You have requested a payment and specified a payment discount with invalid properties. When specifying a payment discount the 'identifier' field is mandatory." + ) + XCTAssertEqual(error.details as! NSDictionary, invalidDiscount as NSDictionary) + XCTAssertEqual(addPaymentCount, 0) + } + } + + func testAddPaymentWithNullSandboxArgument() { + let argument: [String: Any] = [ + "productIdentifier": "123", + "quantity": 1, + "simulatesAskToBuyInSandbox": NSNull(), + ] + + let handlerStub = PaymentQueueHandlerStub() + plugin.paymentQueueHandler = handlerStub + var error: FlutterError? + + var addPaymentInvokeCount = 0 + handlerStub.addPaymentStub = { payment in + XCTAssertEqual(payment.simulatesAskToBuyInSandbox, false) + addPaymentInvokeCount += 1 + return true + } + + plugin.addPaymentPaymentMap(argument, error: &error) + XCTAssertEqual(addPaymentInvokeCount, 1) + } + + func testRestoreTransactions() { + let expectation = self.expectation(description: "result successfully restore transactions") + + let cacheStub = TransactionCacheStub() + let queueStub = PaymentQueueStub() + + var callbackInvoked = false + plugin.paymentQueueHandler = FIAPaymentQueueHandler( + queue: queueStub, + transactionsUpdated: { transactions in }, + transactionRemoved: nil, + restoreTransactionFailed: nil, + restoreCompletedTransactionsFinished: { + callbackInvoked = true + expectation.fulfill() + }, + shouldAddStorePayment: nil, + updatedDownloads: nil, + transactionCache: cacheStub) + queueStub.add(plugin.paymentQueueHandler!) + + var error: FlutterError? + plugin.restoreTransactionsApplicationUserName(nil, error: &error) + + waitForExpectations(timeout: 5, handler: nil) + XCTAssertTrue(callbackInvoked) + } + + func testRetrieveReceiptDataSuccess() { + var error: FlutterError? + let result = plugin.retrieveReceiptDataWithError(&error) + XCTAssertNotNil(result) + } + + func testRetrieveReceiptDataNil() { + receiptManagerStub.returnNilURL = true + + var error: FlutterError? + let result = plugin.retrieveReceiptDataWithError(&error) + XCTAssertNil(result) + } + + func testRetrieveReceiptDataError() { + receiptManagerStub.returnError = true + var error: FlutterError? + let result = plugin.retrieveReceiptDataWithError(&error) + + XCTAssertNil(result) + XCTAssertNotNil(error) + + guard let error = error else { + XCTFail("Error should not be nil") + return + } + + guard let details = error.details as? [String: Any], + let errorDetails = details["error"] as? [String: Any], + let errorCode = errorDetails["code"] as? NSNumber + else { + XCTFail("Error details are not in the correct format") + return + } + + XCTAssertEqual(errorCode, 99) + } + + func testRefreshReceiptRequest() { + let expectation = self.expectation(description: "completion handler successfully called") + + let handlerStub = RequestHandlerStub() + let plugin = InAppPurchasePlugin(receiptManager: receiptManagerStub) { request in + return handlerStub + } + + let receiptError = NSError( + domain: "errorDomain", code: 0, userInfo: [NSLocalizedDescriptionKey: "description"]) + + handlerStub.startProductRequestWithCompletionHandlerStub = { completion in + completion(nil, receiptError) + } + + plugin.refreshReceiptReceiptProperties(nil) { error in + expectation.fulfill() + } + + waitForExpectations(timeout: 5, handler: nil) + } + + func testRefreshReceiptRequestWithParams() { + let properties = [ + "isExpired": false, + "isRevoked": false, + "isVolumePurchase": false, + ] + let expectation = self.expectation(description: "completion handler successfully called") + + let handlerStub = RequestHandlerStub() + let plugin = InAppPurchasePlugin(receiptManager: receiptManagerStub) { request in + return handlerStub + } + + let receiptError = NSError( + domain: "errorDomain", code: 0, userInfo: [NSLocalizedDescriptionKey: "description"]) + + handlerStub.startProductRequestWithCompletionHandlerStub = { completion in + completion(nil, receiptError) + } + + plugin.refreshReceiptReceiptProperties(properties) { error in + expectation.fulfill() + } + + waitForExpectations(timeout: 5, handler: nil) + } + + func testRefreshReceiptRequestWithError() { + let properties: [String: Any] = [ + "isExpired": false, + "isRevoked": false, + "isVolumePurchase": false, + ] + + let expectation = self.expectation(description: "completion handler successfully called") + + let handlerStub = RequestHandlerStub() + let plugin = InAppPurchasePlugin(receiptManager: receiptManagerStub) { request in + return handlerStub + } + + let receiptError = NSError( + domain: "errorDomain", code: 0, userInfo: [NSLocalizedDescriptionKey: "description"]) + + handlerStub.startProductRequestWithCompletionHandlerStub = { completion in + completion(nil, receiptError) + } + + plugin.refreshReceiptReceiptProperties(properties) { error in + XCTAssertNotNil(error) + XCTAssertEqual(error?.code, "storekit_refreshreceiptrequest_platform_error") + expectation.fulfill() + } + + waitForExpectations(timeout: 5, handler: nil) + } + + #if os(iOS) + func testPresentCodeRedemptionSheet() { + let handlerStub = PaymentQueueHandlerStub() + plugin.paymentQueueHandler = handlerStub + + var presentCodeRedemptionSheetCount = 0 + handlerStub.presentCodeRedemptionSheetStub = { + presentCodeRedemptionSheetCount += 1 + } + + var error: FlutterError? + plugin.presentCodeRedemptionSheetWithError(&error) + + XCTAssertEqual(presentCodeRedemptionSheetCount, 1) + } + #endif + + func testGetPendingTransactions() { + let queueStub = PaymentQueueStub() + let cacheStub = TransactionCacheStub() + let transactionMap: [String: Any] = [ + "transactionIdentifier": "567", + "transactionState": SKPaymentTransactionState.purchasing.rawValue, + "payment": NSNull(), + "error": FIAObjectTranslator.getMapFrom( + NSError(domain: "test_stub", code: 123, userInfo: [:])), + "transactionTimeStamp": NSDate().timeIntervalSince1970, + "originalTransaction": NSNull(), + ] + queueStub.transactions = [SKPaymentTransactionStub(map: transactionMap)] + plugin.paymentQueueHandler = FIAPaymentQueueHandler( + queue: queueStub, + transactionsUpdated: nil, + transactionRemoved: nil, + restoreTransactionFailed: nil, + restoreCompletedTransactionsFinished: nil, + shouldAddStorePayment: nil, + updatedDownloads: nil, + transactionCache: cacheStub) + + var error: FlutterError? + let original = SKPaymentTransactionStub(map: transactionMap) + let originalPigeon = FIAObjectTranslator.convertTransaction(toPigeon: original) + + guard let result = plugin.transactionsWithError(&error)?.first else { + XCTFail("Expected a transaction but got nil") + return + } + XCTAssertEqual(result.payment, originalPigeon?.payment) + XCTAssertEqual(result.transactionIdentifier, originalPigeon?.transactionIdentifier) + XCTAssertEqual(result.transactionState, originalPigeon?.transactionState) + XCTAssertEqual(result.transactionTimeStamp, originalPigeon?.transactionTimeStamp) + XCTAssertEqual(result.originalTransaction, originalPigeon?.originalTransaction) + XCTAssertEqual(result.error?.domain, originalPigeon?.error?.domain) + XCTAssertEqual(result.error?.code, originalPigeon?.error?.code) + } + + func testStartObservingPaymentQueue() { + let handlerStub = PaymentQueueHandlerStub() + plugin.paymentQueueHandler = handlerStub + + var startObservingCount = 0 + handlerStub.startObservingPaymentQueueStub = { + startObservingCount += 1 + } + + var error: FlutterError? + plugin.startObservingPaymentQueueWithError(&error) + + XCTAssertEqual(startObservingCount, 1) + } + + func testStopObservingPaymentQueue() { + let handlerStub = PaymentQueueHandlerStub() + plugin.paymentQueueHandler = handlerStub + + var stopObservingCount = 0 + handlerStub.stopObservingPaymentQueueStub = { + stopObservingCount += 1 + } + + var error: FlutterError? + plugin.stopObservingPaymentQueueWithError(&error) + + XCTAssertEqual(stopObservingCount, 1) + } + + #if os(iOS) + func testRegisterPaymentQueueDelegate() { + let cacheStub = TransactionCacheStub() + let queueStub = PaymentQueueStub() + + if #available(iOS 13, *) { + plugin.paymentQueueHandler = FIAPaymentQueueHandler( + queue: queueStub, + transactionsUpdated: nil, + transactionRemoved: nil, + restoreTransactionFailed: nil, + restoreCompletedTransactionsFinished: nil, + shouldAddStorePayment: nil, + updatedDownloads: nil, + transactionCache: cacheStub) + + plugin.registrar = FlutterPluginRegistrarStub() + + // Verify the delegate is nil before we register one. + XCTAssertNil(plugin.paymentQueueHandler?.delegate) + + var error: FlutterError? + plugin.registerPaymentQueueDelegateWithError(&error) + + // Verify the delegate is not nil after we registered one. + XCTAssertNotNil(plugin.paymentQueueHandler?.delegate) + } + } + + func testRemovePaymentQueueDelegate() { + if #available(iOS 13, *) { + let cacheStub = TransactionCacheStub() + let queueStub = PaymentQueueStub() + + plugin.paymentQueueHandler = FIAPaymentQueueHandler( + queue: queueStub, + transactionsUpdated: nil, + transactionRemoved: nil, + restoreTransactionFailed: nil, + restoreCompletedTransactionsFinished: nil, + shouldAddStorePayment: nil, + updatedDownloads: nil, + transactionCache: cacheStub) + + plugin.registrar = FlutterPluginRegistrarStub() + + // Verify the delegate is nil before we register one. + XCTAssertNil(plugin.paymentQueueHandler?.delegate) + + var error: FlutterError? + plugin.registerPaymentQueueDelegateWithError(&error) + + // Verify the delegate is not nil before removing it. + XCTAssertNotNil(plugin.paymentQueueHandler?.delegate) + + plugin.removePaymentQueueDelegateWithError(&error) + + // Verify the delegate is nil after removing it. + XCTAssertNil(plugin.paymentQueueHandler?.delegate) + } + } + #endif + + func testHandleTransactionsUpdated() { + let transactionMap: [String: Any] = [ + "transactionIdentifier": "567", + "transactionState": SKPaymentTransactionState.purchasing.rawValue, + "payment": NSNull(), + "error": FIAObjectTranslator.getMapFrom( + NSError(domain: "test_stub", code: 123, userInfo: [:])), + "transactionTimeStamp": NSDate().timeIntervalSince1970, + ] + + let channelStub = MethodChannelStub() + var invokeMethodCount = 0 + + channelStub.invokeMethodChannelStub = { method, arguments in + XCTAssertEqual(method, "updatedTransactions") + XCTAssertNotNil(arguments) + invokeMethodCount += 1 + } + + let plugin = InAppPurchasePlugin( + receiptManager: receiptManagerStub, transactionCallbackChannel: channelStub) + + let paymentTransactionStub = SKPaymentTransactionStub(map: transactionMap) + let array = [paymentTransactionStub] + + plugin.handleTransactionsUpdated(array) + XCTAssertEqual(invokeMethodCount, 1) + } + + func testHandleTransactionsRemoved() { + let transactionMap: [String: Any] = [ + "transactionIdentifier": "567", + "transactionState": SKPaymentTransactionState.purchasing.rawValue, + "payment": NSNull(), + "error": FIAObjectTranslator.getMapFrom( + NSError(domain: "test_stub", code: 123, userInfo: [:])), + "transactionTimeStamp": NSDate().timeIntervalSince1970, + ] + + let paymentTransactionStub = SKPaymentTransactionStub(map: transactionMap) + let array = [paymentTransactionStub] + let maps = [FIAObjectTranslator.getMapFrom(paymentTransactionStub)] + + let channelStub = MethodChannelStub() + var invokeMethodCount = 0 + + channelStub.invokeMethodChannelStub = { method, arguments in + XCTAssertEqual(method, "removedTransactions") + XCTAssertEqual(arguments as! NSObject, maps as NSObject) + invokeMethodCount += 1 + } + + let plugin = InAppPurchasePlugin( + receiptManager: receiptManagerStub, transactionCallbackChannel: channelStub) + + plugin.handleTransactionsRemoved(array) + XCTAssertEqual(invokeMethodCount, 1) + } + + func testHandleTransactionRestoreFailed() { + let channelStub = MethodChannelStub() + var invokeMethodCount = 0 + let error = NSError(domain: "error", code: 0, userInfo: nil) + + channelStub.invokeMethodChannelStub = { method, arguments in + XCTAssertEqual(method, "restoreCompletedTransactionsFailed") + XCTAssertEqual(arguments as! NSObject, FIAObjectTranslator.getMapFrom(error) as NSObject) + invokeMethodCount += 1 + } + + let plugin = InAppPurchasePlugin( + receiptManager: receiptManagerStub, transactionCallbackChannel: channelStub) + + plugin.handleTransactionRestoreFailed(error) + XCTAssertEqual(invokeMethodCount, 1) + } + + func testRestoreCompletedTransactionsFinished() { + let channelStub = MethodChannelStub() + var invokeMethodCount = 0 + + channelStub.invokeMethodChannelStub = { method, arguments in + XCTAssertEqual(method, "paymentQueueRestoreCompletedTransactionsFinished") + XCTAssertNil(arguments) + invokeMethodCount += 1 + } + + let plugin = InAppPurchasePlugin( + receiptManager: receiptManagerStub, transactionCallbackChannel: channelStub) + + plugin.restoreCompletedTransactionsFinished() + XCTAssertEqual(invokeMethodCount, 1) + } + + func testShouldAddStorePayment() { + let paymentMap: [String: Any] = [ + "productIdentifier": "123", + "requestData": "abcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefgh", + "quantity": 2, + "applicationUsername": "app user name", + "simulatesAskToBuyInSandbox": false, + ] + + let productMap: [String: Any] = [ + "price": "1", + "priceLocale": FIAObjectTranslator.getMapFrom(Locale.current), + "productIdentifier": "123", + "localizedTitle": "title", + "localizedDescription": "des", + ] + + let payment = FIAObjectTranslator.getSKMutablePayment(fromMap: paymentMap) + let productStub = SKProductStub(map: productMap) + + let args: [String: Any] = [ + "payment": FIAObjectTranslator.getMapFrom(payment), + "product": FIAObjectTranslator.getMapFrom(productStub), + ] + + let channelStub = MethodChannelStub() + + var invokeMethodCount = 0 + channelStub.invokeMethodChannelStub = { method, arguments in + XCTAssertEqual(method, "shouldAddStorePayment") + XCTAssertEqual(arguments as! NSObject, args as NSObject) + invokeMethodCount += 1 + } + + let plugin = InAppPurchasePlugin( + receiptManager: receiptManagerStub, transactionCallbackChannel: channelStub) + + let result = plugin.shouldAddStorePayment(payment: payment, product: productStub) + XCTAssertEqual(result, false) + XCTAssertEqual(invokeMethodCount, 1) + } + #if os(iOS) + func testShowPriceConsentIfNeeded() { + let cacheStub = TransactionCacheStub() + let queueStub = PaymentQueueStub() + plugin.paymentQueueHandler = FIAPaymentQueueHandler( + queue: queueStub, + transactionsUpdated: nil, + transactionRemoved: nil, + restoreTransactionFailed: nil, + restoreCompletedTransactionsFinished: nil, + shouldAddStorePayment: nil, + updatedDownloads: nil, + transactionCache: cacheStub) + + var error: FlutterError? + var showPriceConsentIfNeededCount = 0 + + queueStub.showPriceConsentIfNeededStub = { + showPriceConsentIfNeededCount += 1 + } + + plugin.showPriceConsentIfNeededWithError(&error) + + if #available(iOS 13.4, *) { + XCTAssertEqual(showPriceConsentIfNeededCount, 1) + } else { + XCTAssertEqual(showPriceConsentIfNeededCount, 0) + } + } + #endif +} diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/InAppPurchaseStoreKit2PluginTests.swift b/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/InAppPurchaseStoreKit2PluginTests.swift new file mode 100644 index 000000000000..34caa9271331 --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/InAppPurchaseStoreKit2PluginTests.swift @@ -0,0 +1,253 @@ +// 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 StoreKitTest +import XCTest + +@testable import in_app_purchase_storekit + +@available(iOS 15.0, macOS 12.0, *) + +final class InAppPurchase2PluginTests: XCTestCase { + private var session: SKTestSession! + private var plugin: InAppPurchasePlugin! + + override func setUp() async throws { + try await super.setUp() + + session = try! SKTestSession(configurationFileNamed: "Configuration") + session.resetToDefaultState() + session.clearTransactions() + session.disableDialogs = true + + plugin = InAppPurchasePluginStub(receiptManager: FIAPReceiptManagerStub()) { request in + DefaultRequestHandler(requestHandler: FIAPRequestHandler(request: request)) + } + try plugin.startListeningToTransactions() + } + + override func tearDown() async throws { + self.session.clearTransactions() + session.disableDialogs = false + } + + func testCanMakePayments() throws { + let result = try plugin.canMakePayments() + XCTAssertTrue(result) + } + + func testGetProducts() async throws { + let expectation = self.expectation(description: "products successfully fetched") + + var fetchedProductMsg: SK2ProductMessage? + plugin.products(identifiers: ["subscription_silver"]) { result in + switch result { + case .success(let productMessages): + fetchedProductMsg = productMessages.first + expectation.fulfill() + case .failure(let error): + print("Failed to fetch products: \(error.localizedDescription)") + } + } + await fulfillment(of: [expectation], timeout: 5) + + let testProduct = try await Product.products(for: ["subscription_silver"]).first + + let testProductMsg = testProduct?.convertToPigeon + + XCTAssertNotNil(fetchedProductMsg) + XCTAssertEqual(testProductMsg, fetchedProductMsg) + } + + func testGetDiscountedProducts() async throws { + let expectation = self.expectation(description: "products successfully fetched") + + var fetchedProductMsg: SK2ProductMessage? + plugin.products(identifiers: ["subscription_silver"]) { result in + switch result { + case .success(let productMessages): + fetchedProductMsg = productMessages.first + expectation.fulfill() + case .failure(let error): print("Failed to fetch products: \(error.localizedDescription)") + } + } + await fulfillment(of: [expectation], timeout: 5) + + let testProduct = try await Product.products(for: ["subscription_silver"]).first + + let testProductMsg = testProduct?.convertToPigeon + + XCTAssertNotNil(fetchedProductMsg) + XCTAssertEqual(testProductMsg, fetchedProductMsg) + } + + func testGetInvalidProducts() async throws { + let expectation = self.expectation(description: "products successfully fetched") + + var fetchedProductMsg: [SK2ProductMessage]? + plugin.products(identifiers: ["invalid_product"]) { result in + switch result { + case .success(let productMessages): + fetchedProductMsg = productMessages + expectation.fulfill() + case .failure(_): + XCTFail("Products should be successfully fetched") + } + } + await fulfillment(of: [expectation], timeout: 5) + + XCTAssert(fetchedProductMsg?.count == 0) + } + + //TODO(louisehsu): Add testing for lower versions. + @available(iOS 17.0, macOS 14.0, *) + func testGetProductsWithStoreKitError() async throws { + try await session.setSimulatedError( + .generic(.networkError(URLError(.badURL))), forAPI: .loadProducts) + + let expectation = self.expectation(description: "products request should fail") + + plugin.products(identifiers: ["subscription_silver"]) { result in + switch result { + case .success(_): + XCTFail("This `products` call should not succeed") + case .failure(let error): + expectation.fulfill() + XCTAssert( + error.localizedDescription + == "The operation couldn’t be completed. (in_app_purchase_storekit.PigeonError error 1.)" + ) + } + } + await fulfillment(of: [expectation], timeout: 5) + } + + func testSuccessfulPurchase() async throws { + let expectation = self.expectation(description: "Purchase request should succeed") + plugin.purchase(id: "consumable", options: nil) { result in + switch result { + case .success(let purchaseResult): + expectation.fulfill() + case .failure(let error): + XCTFail("Purchase should NOT fail. Failed with \(error)") + } + } + await fulfillment(of: [expectation], timeout: 5) + } + + @available(iOS 17.0, macOS 14.0, *) + func testFailedNetworkErrorPurchase() async throws { + try await session.setSimulatedError( + .generic(.networkError(URLError(.badURL))), forAPI: .loadProducts) + let expectation = self.expectation(description: "products request should fail") + plugin.purchase(id: "consumable", options: nil) { result in + switch result { + case .success(_): + XCTFail("Purchase should NOT suceed.") + case .failure(let error): + XCTAssertEqual( + error.localizedDescription, + "The operation couldn’t be completed. (NSURLErrorDomain error -1009.)") + expectation.fulfill() + } + } + await fulfillment(of: [expectation], timeout: 5) + } + + @available(iOS 17.0, macOS 14.0, *) + func testFailedProductUnavilablePurchase() async throws { + try await session.setSimulatedError( + .purchase(.productUnavailable), forAPI: .purchase) + let expectation = self.expectation(description: "Purchase request should succeed") + plugin.purchase(id: "consumable", options: nil) { result in + switch result { + case .success(_): + XCTFail("Purchase should NOT suceed.") + case .failure(let error): + XCTAssertEqual(error.localizedDescription, "Item Unavailable") + expectation.fulfill() + } + } + await fulfillment(of: [expectation], timeout: 5) + } + + func testInvalidProductPurchase() async throws { + let expectation = self.expectation(description: "products request should fail") + plugin.purchase(id: "invalid_product", options: nil) { result in + switch result { + case .success(_): + XCTFail("Purchase should NOT suceed.") + case .failure(let error): + let pigeonError = error as! PigeonError + + XCTAssertEqual(pigeonError.code, "storekit2_failed_to_fetch_product") + expectation.fulfill() + } + } + await fulfillment(of: [expectation], timeout: 5) + } + + func testPurchaseUpgradeConsumableSuccess() async throws { + let expectation = self.expectation(description: "Purchase request should succeed") + plugin.purchase(id: "subscription_discounted", options: nil) { result in + switch result { + case .success(let purchaseResult): + expectation.fulfill() + case .failure(let error): + XCTFail("Purchase should NOT fail. Failed with \(error)") + } + } + await fulfillment(of: [expectation], timeout: 5) + } + + func testDiscountedSubscriptionSuccess() async throws { + let expectation = self.expectation(description: "Purchase request should succeed") + plugin.purchase(id: "subscription_discounted", options: nil) { result in + switch result { + case .success(let purchaseResult): + expectation.fulfill() + case .failure(let error): + XCTFail("Purchase should NOT fail. Failed with \(error)") + } + } + await fulfillment(of: [expectation], timeout: 5) + } + + func testDiscountedProductSuccess() async throws { + let expectation = self.expectation(description: "Purchase request should succeed") + plugin.purchase(id: "consumable_discounted", options: nil) { result in + switch result { + case .success(let purchaseResult): + expectation.fulfill() + case .failure(let error): + XCTFail("Purchase should NOT fail. Failed with \(error)") + } + } + await fulfillment(of: [expectation], timeout: 5) + } + + func testRestoreProductSuccess() async throws { + let purchaseExpectation = self.expectation(description: "Purchase request should succeed") + let restoreExpectation = self.expectation(description: "Restore request should succeed") + + plugin.purchase(id: "subscription_silver", options: nil) { result in + switch result { + case .success(_): + purchaseExpectation.fulfill() + case .failure(let error): + XCTFail("Purchase should NOT fail. Failed with \(error)") + } + } + plugin.restorePurchases { result in + switch result { + case .success(): + restoreExpectation.fulfill() + case .failure(let error): + XCTFail("Restore purchases should NOT fail. Failed with \(error)") + } + } + + await fulfillment(of: [restoreExpectation, purchaseExpectation], timeout: 5) + } +} diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/PaymentQueueTests.m b/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/PaymentQueueTests.m deleted file mode 100644 index 0c6d51a3b75d..000000000000 --- a/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/PaymentQueueTests.m +++ /dev/null @@ -1,515 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import -#import "Stubs.h" - -@import in_app_purchase_storekit; - -@interface PaymentQueueTest : XCTestCase - -@property(nonatomic, strong) NSDictionary *periodMap; -@property(nonatomic, strong) NSDictionary *discountMap; -@property(nonatomic, strong) NSDictionary *productMap; -@property(nonatomic, strong) NSDictionary *productResponseMap; - -@end - -@implementation PaymentQueueTest - -- (void)setUp { - self.periodMap = @{@"numberOfUnits" : @(0), @"unit" : @(0)}; - self.discountMap = @{ - @"price" : @1.0, - @"currencyCode" : @"USD", - @"numberOfPeriods" : @1, - @"subscriptionPeriod" : self.periodMap, - @"paymentMode" : @1 - }; - self.productMap = @{ - @"price" : @1.0, - @"currencyCode" : @"USD", - @"productIdentifier" : @"123", - @"localizedTitle" : @"title", - @"localizedDescription" : @"des", - @"subscriptionPeriod" : self.periodMap, - @"introductoryPrice" : self.discountMap, - @"subscriptionGroupIdentifier" : @"com.group" - }; - self.productResponseMap = - @{@"products" : @[ self.productMap ], @"invalidProductIdentifiers" : [NSNull null]}; -} - -- (void)testTransactionPurchased { - XCTestExpectation *expectation = - [self expectationWithDescription:@"expect to get purchased transcation."]; - PaymentQueueStub *queue = [[PaymentQueueStub alloc] init]; - queue.testState = SKPaymentTransactionStatePurchased; - __block SKPaymentTransactionStub *tran; - FIAPaymentQueueHandler *handler = [[FIAPaymentQueueHandler alloc] initWithQueue:queue - transactionsUpdated:^(NSArray *_Nonnull transactions) { - SKPaymentTransaction *transaction = transactions[0]; - tran = (SKPaymentTransactionStub *)transaction; - [expectation fulfill]; - } - transactionRemoved:nil - restoreTransactionFailed:nil - restoreCompletedTransactionsFinished:nil - shouldAddStorePayment:^BOOL(SKPayment *_Nonnull payment, SKProduct *_Nonnull product) { - return YES; - } - updatedDownloads:nil - transactionCache:[[TransactionCacheStub alloc] init]]; - SKPayment *payment = - [SKPayment paymentWithProduct:[[SKProductStub alloc] initWithMap:self.productResponseMap]]; - [handler startObservingPaymentQueue]; - [handler addPayment:payment]; - [self waitForExpectations:@[ expectation ] timeout:5]; - XCTAssertEqual(tran.transactionState, SKPaymentTransactionStatePurchased); - XCTAssertEqualObjects(tran.transactionIdentifier, @"fakeID"); -} - -- (void)testTransactionFailed { - XCTestExpectation *expectation = - [self expectationWithDescription:@"expect to get failed transcation."]; - PaymentQueueStub *queue = [[PaymentQueueStub alloc] init]; - queue.testState = SKPaymentTransactionStateFailed; - __block SKPaymentTransactionStub *tran; - FIAPaymentQueueHandler *handler = [[FIAPaymentQueueHandler alloc] initWithQueue:queue - transactionsUpdated:^(NSArray *_Nonnull transactions) { - SKPaymentTransaction *transaction = transactions[0]; - tran = (SKPaymentTransactionStub *)transaction; - [expectation fulfill]; - } - transactionRemoved:nil - restoreTransactionFailed:nil - restoreCompletedTransactionsFinished:nil - shouldAddStorePayment:^BOOL(SKPayment *_Nonnull payment, SKProduct *_Nonnull product) { - return YES; - } - updatedDownloads:nil - transactionCache:[[TransactionCacheStub alloc] init]]; - - SKPayment *payment = - [SKPayment paymentWithProduct:[[SKProductStub alloc] initWithMap:self.productResponseMap]]; - [handler startObservingPaymentQueue]; - [handler addPayment:payment]; - [self waitForExpectations:@[ expectation ] timeout:5]; - XCTAssertEqual(tran.transactionState, SKPaymentTransactionStateFailed); - XCTAssertEqual(tran.transactionIdentifier, nil); -} - -- (void)testTransactionRestored { - XCTestExpectation *expectation = - [self expectationWithDescription:@"expect to get restored transcation."]; - PaymentQueueStub *queue = [[PaymentQueueStub alloc] init]; - queue.testState = SKPaymentTransactionStateRestored; - __block SKPaymentTransactionStub *tran; - FIAPaymentQueueHandler *handler = [[FIAPaymentQueueHandler alloc] initWithQueue:queue - transactionsUpdated:^(NSArray *_Nonnull transactions) { - SKPaymentTransaction *transaction = transactions[0]; - tran = (SKPaymentTransactionStub *)transaction; - [expectation fulfill]; - } - transactionRemoved:nil - restoreTransactionFailed:nil - restoreCompletedTransactionsFinished:nil - shouldAddStorePayment:^BOOL(SKPayment *_Nonnull payment, SKProduct *_Nonnull product) { - return YES; - } - updatedDownloads:nil - transactionCache:[[TransactionCacheStub alloc] init]]; - - SKPayment *payment = - [SKPayment paymentWithProduct:[[SKProductStub alloc] initWithMap:self.productResponseMap]]; - [handler startObservingPaymentQueue]; - [handler addPayment:payment]; - [self waitForExpectations:@[ expectation ] timeout:5]; - XCTAssertEqual(tran.transactionState, SKPaymentTransactionStateRestored); - XCTAssertEqualObjects(tran.transactionIdentifier, @"fakeID"); -} - -- (void)testTransactionPurchasing { - XCTestExpectation *expectation = - [self expectationWithDescription:@"expect to get purchasing transcation."]; - PaymentQueueStub *queue = [[PaymentQueueStub alloc] init]; - queue.testState = SKPaymentTransactionStatePurchasing; - __block SKPaymentTransactionStub *tran; - FIAPaymentQueueHandler *handler = [[FIAPaymentQueueHandler alloc] initWithQueue:queue - transactionsUpdated:^(NSArray *_Nonnull transactions) { - SKPaymentTransaction *transaction = transactions[0]; - tran = (SKPaymentTransactionStub *)transaction; - [expectation fulfill]; - } - transactionRemoved:nil - restoreTransactionFailed:nil - restoreCompletedTransactionsFinished:nil - shouldAddStorePayment:^BOOL(SKPayment *_Nonnull payment, SKProduct *_Nonnull product) { - return YES; - } - updatedDownloads:nil - transactionCache:[[TransactionCacheStub alloc] init]]; - - SKPayment *payment = - [SKPayment paymentWithProduct:[[SKProductStub alloc] initWithMap:self.productResponseMap]]; - [handler startObservingPaymentQueue]; - [handler addPayment:payment]; - [self waitForExpectations:@[ expectation ] timeout:5]; - XCTAssertEqual(tran.transactionState, SKPaymentTransactionStatePurchasing); - XCTAssertEqual(tran.transactionIdentifier, nil); -} - -- (void)testTransactionDeferred { - XCTestExpectation *expectation = - [self expectationWithDescription:@"expect to get deffered transcation."]; - PaymentQueueStub *queue = [[PaymentQueueStub alloc] init]; - queue.testState = SKPaymentTransactionStateDeferred; - __block SKPaymentTransactionStub *tran; - FIAPaymentQueueHandler *handler = [[FIAPaymentQueueHandler alloc] initWithQueue:queue - transactionsUpdated:^(NSArray *_Nonnull transactions) { - SKPaymentTransaction *transaction = transactions[0]; - tran = (SKPaymentTransactionStub *)transaction; - [expectation fulfill]; - } - transactionRemoved:nil - restoreTransactionFailed:nil - restoreCompletedTransactionsFinished:nil - shouldAddStorePayment:^BOOL(SKPayment *_Nonnull payment, SKProduct *_Nonnull product) { - return YES; - } - updatedDownloads:nil - transactionCache:[[TransactionCacheStub alloc] init]]; - SKPayment *payment = - [SKPayment paymentWithProduct:[[SKProductStub alloc] initWithMap:self.productResponseMap]]; - [handler startObservingPaymentQueue]; - [handler addPayment:payment]; - [self waitForExpectations:@[ expectation ] timeout:5]; - XCTAssertEqual(tran.transactionState, SKPaymentTransactionStateDeferred); - XCTAssertEqual(tran.transactionIdentifier, nil); -} - -- (void)testFinishTransaction { - XCTestExpectation *expectation = - [self expectationWithDescription:@"handler.transactions should be empty."]; - PaymentQueueStub *queue = [[PaymentQueueStub alloc] init]; - queue.testState = SKPaymentTransactionStateDeferred; - __block FIAPaymentQueueHandler *handler = [[FIAPaymentQueueHandler alloc] initWithQueue:queue - transactionsUpdated:^(NSArray *_Nonnull transactions) { - XCTAssertEqual(transactions.count, 1); - SKPaymentTransaction *transaction = transactions[0]; - [handler finishTransaction:transaction]; - } - transactionRemoved:^(NSArray *_Nonnull transactions) { - XCTAssertEqual(transactions.count, 1); - [expectation fulfill]; - } - restoreTransactionFailed:nil - restoreCompletedTransactionsFinished:nil - shouldAddStorePayment:^BOOL(SKPayment *_Nonnull payment, SKProduct *_Nonnull product) { - return YES; - } - updatedDownloads:nil - transactionCache:[[TransactionCacheStub alloc] init]]; - SKPayment *payment = - [SKPayment paymentWithProduct:[[SKProductStub alloc] initWithMap:self.productResponseMap]]; - [handler startObservingPaymentQueue]; - [handler addPayment:payment]; - [self waitForExpectations:@[ expectation ] timeout:5]; -} - -- (void)testStartObservingPaymentQueueShouldNotProcessTransactionsWhenCacheIsEmpty { - TransactionCacheStub *cacheStub = [[TransactionCacheStub alloc] init]; - FIAPaymentQueueHandler *handler = - [[FIAPaymentQueueHandler alloc] initWithQueue:[[PaymentQueueStub alloc] init] - transactionsUpdated:^(NSArray *_Nonnull transactions) { - XCTFail("transactionsUpdated callback should not be called when cache is empty."); - } - transactionRemoved:^(NSArray *_Nonnull transactions) { - XCTFail("transactionRemoved callback should not be called when cache is empty."); - } - restoreTransactionFailed:nil - restoreCompletedTransactionsFinished:nil - shouldAddStorePayment:^BOOL(SKPayment *_Nonnull payment, SKProduct *_Nonnull product) { - return YES; - } - updatedDownloads:^(NSArray *_Nonnull downloads) { - XCTFail("updatedDownloads callback should not be called when cache is empty."); - } - transactionCache:cacheStub]; - - __block NSInteger TransactionCacheKeyUpdatedTransactionsInvokedCount = 0; - __block NSInteger TransactionCacheKeyUpdatedDownloadsInvokedCount = 0; - __block NSInteger TransactionCacheKeyRemovedTransactionsInvokedCount = 0; - - cacheStub.getObjectsForKeyStub = ^NSArray *_Nonnull(TransactionCacheKey key) { - switch (key) { - case TransactionCacheKeyUpdatedTransactions: - TransactionCacheKeyUpdatedTransactionsInvokedCount++; - break; - case TransactionCacheKeyUpdatedDownloads: - TransactionCacheKeyUpdatedDownloadsInvokedCount++; - break; - case TransactionCacheKeyRemovedTransactions: - TransactionCacheKeyRemovedTransactionsInvokedCount++; - break; - default: - XCTFail("Invalid transaction state was invoked."); - } - return nil; - }; - - [handler startObservingPaymentQueue]; - - XCTAssertEqual(1, TransactionCacheKeyUpdatedTransactionsInvokedCount); - XCTAssertEqual(1, TransactionCacheKeyUpdatedDownloadsInvokedCount); - XCTAssertEqual(1, TransactionCacheKeyRemovedTransactionsInvokedCount); -} - -- (void) - testStartObservingPaymentQueueShouldNotProcessTransactionsWhenCacheContainsEmptyTransactionArrays { - TransactionCacheStub *cacheStub = [[TransactionCacheStub alloc] init]; - FIAPaymentQueueHandler *handler = - [[FIAPaymentQueueHandler alloc] initWithQueue:[[PaymentQueueStub alloc] init] - transactionsUpdated:^(NSArray *_Nonnull transactions) { - XCTFail("transactionsUpdated callback should not be called when cache is empty."); - } - transactionRemoved:^(NSArray *_Nonnull transactions) { - XCTFail("transactionRemoved callback should not be called when cache is empty."); - } - restoreTransactionFailed:nil - restoreCompletedTransactionsFinished:nil - shouldAddStorePayment:^BOOL(SKPayment *_Nonnull payment, SKProduct *_Nonnull product) { - return YES; - } - updatedDownloads:^(NSArray *_Nonnull downloads) { - XCTFail("updatedDownloads callback should not be called when cache is empty."); - } - transactionCache:cacheStub]; - - __block NSInteger TransactionCacheKeyUpdatedTransactionsInvokedCount = 0; - __block NSInteger TransactionCacheKeyUpdatedDownloadsInvokedCount = 0; - __block NSInteger TransactionCacheKeyRemovedTransactionsInvokedCount = 0; - - cacheStub.getObjectsForKeyStub = ^NSArray *_Nonnull(TransactionCacheKey key) { - switch (key) { - case TransactionCacheKeyUpdatedTransactions: - TransactionCacheKeyUpdatedTransactionsInvokedCount++; - return @[]; - break; - case TransactionCacheKeyUpdatedDownloads: - TransactionCacheKeyUpdatedDownloadsInvokedCount++; - return @[]; - break; - case TransactionCacheKeyRemovedTransactions: - TransactionCacheKeyRemovedTransactionsInvokedCount++; - return @[]; - break; - default: - XCTFail("Invalid transaction state was invoked."); - } - }; - - [handler startObservingPaymentQueue]; - - XCTAssertEqual(1, TransactionCacheKeyUpdatedTransactionsInvokedCount); - XCTAssertEqual(1, TransactionCacheKeyUpdatedDownloadsInvokedCount); - XCTAssertEqual(1, TransactionCacheKeyRemovedTransactionsInvokedCount); -} - -- (void)testStartObservingPaymentQueueShouldProcessTransactionsForItemsInCache { - XCTestExpectation *updateTransactionsExpectation = - [self expectationWithDescription: - @"transactionsUpdated callback should be called with one transaction."]; - XCTestExpectation *removeTransactionsExpectation = - [self expectationWithDescription: - @"transactionsRemoved callback should be called with one transaction."]; - XCTestExpectation *updateDownloadsExpectation = - [self expectationWithDescription: - @"downloadsUpdated callback should be called with one transaction."]; - SKPaymentTransaction *transactionStub = [[SKPaymentTransactionStub alloc] init]; - SKDownload *downloadStub = [[SKDownload alloc] init]; - TransactionCacheStub *cacheStub = [[TransactionCacheStub alloc] init]; - FIAPaymentQueueHandler *handler = - [[FIAPaymentQueueHandler alloc] initWithQueue:[[PaymentQueueStub alloc] init] - transactionsUpdated:^(NSArray *_Nonnull transactions) { - XCTAssertEqualObjects(transactions, @[ transactionStub ]); - [updateTransactionsExpectation fulfill]; - } - transactionRemoved:^(NSArray *_Nonnull transactions) { - XCTAssertEqualObjects(transactions, @[ transactionStub ]); - [removeTransactionsExpectation fulfill]; - } - restoreTransactionFailed:nil - restoreCompletedTransactionsFinished:nil - shouldAddStorePayment:^BOOL(SKPayment *_Nonnull payment, SKProduct *_Nonnull product) { - return YES; - } - updatedDownloads:^(NSArray *_Nonnull downloads) { - XCTAssertEqualObjects(downloads, @[ downloadStub ]); - [updateDownloadsExpectation fulfill]; - } - transactionCache:cacheStub]; - - __block NSInteger TransactionCacheKeyUpdatedTransactionsInvokedCount = 0; - __block NSInteger TransactionCacheKeyUpdatedDownloadsInvokedCount = 0; - __block NSInteger TransactionCacheKeyRemovedTransactionsInvokedCount = 0; - - cacheStub.getObjectsForKeyStub = ^NSArray *_Nonnull(TransactionCacheKey key) { - switch (key) { - case TransactionCacheKeyUpdatedTransactions: - TransactionCacheKeyUpdatedTransactionsInvokedCount++; - return @[ transactionStub ]; - break; - case TransactionCacheKeyUpdatedDownloads: - TransactionCacheKeyUpdatedDownloadsInvokedCount++; - return @[ downloadStub ]; - break; - case TransactionCacheKeyRemovedTransactions: - TransactionCacheKeyRemovedTransactionsInvokedCount++; - return @[ transactionStub ]; - break; - default: - XCTFail("Invalid transaction state was invoked."); - } - }; - - __block NSInteger clearInvokedCount = 0; - cacheStub.clearStub = ^{ - clearInvokedCount++; - }; - - [handler startObservingPaymentQueue]; - - [self waitForExpectations:@[ - updateTransactionsExpectation, removeTransactionsExpectation, updateDownloadsExpectation - ] - timeout:5]; - - XCTAssertEqual(1, TransactionCacheKeyUpdatedTransactionsInvokedCount); - XCTAssertEqual(1, TransactionCacheKeyUpdatedDownloadsInvokedCount); - XCTAssertEqual(1, TransactionCacheKeyRemovedTransactionsInvokedCount); - XCTAssertEqual(1, clearInvokedCount); -} - -- (void)testTransactionsShouldBeCachedWhenNotObserving { - PaymentQueueStub *queue = [[PaymentQueueStub alloc] init]; - TransactionCacheStub *cacheStub = [[TransactionCacheStub alloc] init]; - FIAPaymentQueueHandler *handler = [[FIAPaymentQueueHandler alloc] initWithQueue:queue - transactionsUpdated:^(NSArray *_Nonnull transactions) { - XCTFail("transactionsUpdated callback should not be called when cache is empty."); - } - transactionRemoved:^(NSArray *_Nonnull transactions) { - XCTFail("transactionRemoved callback should not be called when cache is empty."); - } - restoreTransactionFailed:nil - restoreCompletedTransactionsFinished:nil - shouldAddStorePayment:^BOOL(SKPayment *_Nonnull payment, SKProduct *_Nonnull product) { - return YES; - } - updatedDownloads:^(NSArray *_Nonnull downloads) { - XCTFail("updatedDownloads callback should not be called when cache is empty."); - } - transactionCache:cacheStub]; - - SKPayment *payment = - [SKPayment paymentWithProduct:[[SKProductStub alloc] initWithMap:self.productResponseMap]]; - - __block NSInteger TransactionCacheKeyUpdatedTransactionsInvokedCount = 0; - __block NSInteger TransactionCacheKeyUpdatedDownloadsInvokedCount = 0; - __block NSInteger TransactionCacheKeyRemovedTransactionsInvokedCount = 0; - - cacheStub.addObjectsStub = ^(NSArray *_Nonnull objects, TransactionCacheKey key) { - switch (key) { - case TransactionCacheKeyUpdatedTransactions: - TransactionCacheKeyUpdatedTransactionsInvokedCount++; - break; - case TransactionCacheKeyUpdatedDownloads: - TransactionCacheKeyUpdatedDownloadsInvokedCount++; - break; - case TransactionCacheKeyRemovedTransactions: - TransactionCacheKeyRemovedTransactionsInvokedCount++; - break; - default: - XCTFail("Invalid transaction state was invoked."); - } - }; - - [handler addPayment:payment]; - - XCTAssertEqual(1, TransactionCacheKeyUpdatedTransactionsInvokedCount); - XCTAssertEqual(0, TransactionCacheKeyUpdatedDownloadsInvokedCount); - XCTAssertEqual(0, TransactionCacheKeyRemovedTransactionsInvokedCount); -} - -- (void)testTransactionsShouldNotBeCachedWhenObserving { - XCTestExpectation *updateTransactionsExpectation = - [self expectationWithDescription: - @"transactionsUpdated callback should be called with one transaction."]; - XCTestExpectation *removeTransactionsExpectation = - [self expectationWithDescription: - @"transactionsRemoved callback should be called with one transaction."]; - XCTestExpectation *updateDownloadsExpectation = - [self expectationWithDescription: - @"downloadsUpdated callback should be called with one transaction."]; - SKPaymentTransaction *transactionStub = [[SKPaymentTransactionStub alloc] init]; - SKDownload *downloadStub = [[SKDownload alloc] init]; - PaymentQueueStub *queue = [[PaymentQueueStub alloc] init]; - queue.testState = SKPaymentTransactionStatePurchased; - TransactionCacheStub *cacheStub = [[TransactionCacheStub alloc] init]; - FIAPaymentQueueHandler *handler = [[FIAPaymentQueueHandler alloc] initWithQueue:queue - transactionsUpdated:^(NSArray *_Nonnull transactions) { - XCTAssertEqualObjects(transactions, @[ transactionStub ]); - [updateTransactionsExpectation fulfill]; - } - transactionRemoved:^(NSArray *_Nonnull transactions) { - XCTAssertEqualObjects(transactions, @[ transactionStub ]); - [removeTransactionsExpectation fulfill]; - } - restoreTransactionFailed:nil - restoreCompletedTransactionsFinished:nil - shouldAddStorePayment:^BOOL(SKPayment *_Nonnull payment, SKProduct *_Nonnull product) { - return YES; - } - updatedDownloads:^(NSArray *_Nonnull downloads) { - XCTAssertEqualObjects(downloads, @[ downloadStub ]); - [updateDownloadsExpectation fulfill]; - } - transactionCache:cacheStub]; - - SKPaymentQueueStub *paymentQueueStub = [[SKPaymentQueueStub alloc] init]; - - [handler startObservingPaymentQueue]; - [handler paymentQueue:paymentQueueStub updatedTransactions:@[ transactionStub ]]; - [handler paymentQueue:paymentQueueStub removedTransactions:@[ transactionStub ]]; - [handler paymentQueue:paymentQueueStub updatedDownloads:@[ downloadStub ]]; - - [self waitForExpectations:@[ - updateTransactionsExpectation, removeTransactionsExpectation, updateDownloadsExpectation - ] - timeout:5]; - - __block NSInteger TransactionCacheKeyUpdatedTransactionsInvokedCount = 0; - __block NSInteger TransactionCacheKeyUpdatedDownloadsInvokedCount = 0; - __block NSInteger TransactionCacheKeyRemovedTransactionsInvokedCount = 0; - - cacheStub.addObjectsStub = ^(NSArray *_Nonnull objects, TransactionCacheKey key) { - switch (key) { - case TransactionCacheKeyUpdatedTransactions: - TransactionCacheKeyUpdatedTransactionsInvokedCount++; - break; - case TransactionCacheKeyUpdatedDownloads: - TransactionCacheKeyUpdatedDownloadsInvokedCount++; - break; - case TransactionCacheKeyRemovedTransactions: - TransactionCacheKeyRemovedTransactionsInvokedCount++; - break; - default: - XCTFail("Invalid transaction state was invoked."); - } - }; - XCTAssertEqual(0, TransactionCacheKeyUpdatedTransactionsInvokedCount); - XCTAssertEqual(0, TransactionCacheKeyUpdatedDownloadsInvokedCount); - XCTAssertEqual(0, TransactionCacheKeyRemovedTransactionsInvokedCount); -} -@end diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/PaymentQueueTests.swift b/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/PaymentQueueTests.swift new file mode 100644 index 000000000000..9f3a7e9d9cd5 --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/PaymentQueueTests.swift @@ -0,0 +1,496 @@ +// 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 StoreKit +import XCTest + +@testable import in_app_purchase_storekit + +final class PaymentQueueTest: XCTestCase { + private var periodMap: [String: Any] { + return ["numberOfUnits": 0, "unit": 0] + } + private var discountMap: [String: Any] { + return [ + "price": 1.0, + "currencyCode": "USD", + "numberOfPeriods": 1, + "subscriptionPeriod": periodMap, + "paymentMode": 1, + ] + } + private var productMap: [String: Any] { + return [ + "price": 1.0, + "currencyCode": "USD", + "productIdentifier": "123", + "localizedTitle": "title", + "localizedDescription": "des", + "subscriptionPeriod": periodMap, + "introductoryPrice": discountMap, + "subscriptionGroupIdentifier": "com.group", + ] + } + private var productResponseMap: [String: Any] { + return ["products": [productMap], "invalidProductIdentifiers": []] + } + + func testTransactionPurchased() throws { + let expectation = self.expectation(description: "expect to get purchased transaction.") + let queue = PaymentQueueStub() + queue.testState = .purchased + var transactionStub: SKPaymentTransactionStub? + let handler = FIAPaymentQueueHandler( + queue: queue, + transactionsUpdated: { transactions in + let transaction = transactions[0] + transactionStub = transaction as? SKPaymentTransactionStub + expectation.fulfill() + }, + transactionRemoved: nil, + restoreTransactionFailed: nil, + restoreCompletedTransactionsFinished: nil, + shouldAddStorePayment: { _, _ in + return true + }, + updatedDownloads: nil, + transactionCache: TransactionCacheStub()) + let payment = SKPayment(product: SKProductStub(map: productResponseMap)) + + handler.startObservingPaymentQueue() + handler.add(payment) + waitForExpectations(timeout: 5) + + let unwrappedTransaction = try XCTUnwrap(transactionStub) + XCTAssertEqual(unwrappedTransaction.transactionState, .purchased) + XCTAssertEqual(unwrappedTransaction.transactionIdentifier, "fakeID") + } + + func testTransactionFailed() throws { + let expectation = self.expectation(description: "expect to get failed transaction.") + let queue = PaymentQueueStub() + queue.testState = .failed + var transactionStub: SKPaymentTransactionStub? + let handler = FIAPaymentQueueHandler( + queue: queue, + transactionsUpdated: { transactions in + let transaction = transactions[0] + transactionStub = transaction as? SKPaymentTransactionStub + expectation.fulfill() + }, + transactionRemoved: nil, + restoreTransactionFailed: nil, + restoreCompletedTransactionsFinished: nil, + shouldAddStorePayment: { _, _ in + return true + }, + updatedDownloads: nil, + transactionCache: TransactionCacheStub()) + let payment = SKPayment(product: SKProductStub(map: productResponseMap)) + + handler.startObservingPaymentQueue() + handler.add(payment) + waitForExpectations(timeout: 5) + + let unwrappedTransaction = try XCTUnwrap(transactionStub) + XCTAssertEqual(unwrappedTransaction.transactionState, .failed) + XCTAssertEqual(unwrappedTransaction.transactionIdentifier, nil) + } + + func testTransactionRestored() throws { + let expectation = self.expectation(description: "expect to get restored transaction.") + let queue = PaymentQueueStub() + queue.testState = .restored + var transactionStub: SKPaymentTransactionStub? + let handler = FIAPaymentQueueHandler( + queue: queue, + transactionsUpdated: { transactions in + let transaction = transactions[0] + transactionStub = transaction as? SKPaymentTransactionStub + expectation.fulfill() + }, + transactionRemoved: nil, + restoreTransactionFailed: nil, + restoreCompletedTransactionsFinished: nil, + shouldAddStorePayment: { _, _ in + return true + }, + updatedDownloads: nil, + transactionCache: TransactionCacheStub()) + let payment = SKPayment(product: SKProductStub(map: productResponseMap)) + + handler.startObservingPaymentQueue() + handler.add(payment) + waitForExpectations(timeout: 5) + + let unwrappedTransaction = try XCTUnwrap(transactionStub) + XCTAssertEqual(unwrappedTransaction.transactionState, .restored) + XCTAssertEqual(unwrappedTransaction.transactionIdentifier, "fakeID") + } + + func testTransactionPurchasing() throws { + let expectation = self.expectation(description: "expect to get purchasing transaction.") + let queue = PaymentQueueStub() + queue.testState = .purchasing + var transactionStub: SKPaymentTransactionStub? + let handler = FIAPaymentQueueHandler( + queue: queue, + transactionsUpdated: { transactions in + let transaction = transactions[0] + transactionStub = transaction as? SKPaymentTransactionStub + expectation.fulfill() + }, + transactionRemoved: nil, + restoreTransactionFailed: nil, + restoreCompletedTransactionsFinished: nil, + shouldAddStorePayment: { _, _ in + return true + }, + updatedDownloads: nil, + transactionCache: TransactionCacheStub()) + let payment = SKPayment(product: SKProductStub(map: productResponseMap)) + + handler.startObservingPaymentQueue() + handler.add(payment) + waitForExpectations(timeout: 5) + + let unwrappedTransaction = try XCTUnwrap(transactionStub) + XCTAssertEqual(unwrappedTransaction.transactionState, .purchasing) + XCTAssertEqual(unwrappedTransaction.transactionIdentifier, nil) + } + + func testTransactionDeferred() throws { + let expectation = self.expectation(description: "expect to get deferred transaction.") + let queue = PaymentQueueStub() + queue.testState = .deferred + var transactionStub: SKPaymentTransactionStub? + let handler = FIAPaymentQueueHandler( + queue: queue, + transactionsUpdated: { transactions in + let transaction = transactions[0] + transactionStub = transaction as? SKPaymentTransactionStub + expectation.fulfill() + }, + transactionRemoved: nil, + restoreTransactionFailed: nil, + restoreCompletedTransactionsFinished: nil, + shouldAddStorePayment: { _, _ in + return true + }, + updatedDownloads: nil, + transactionCache: TransactionCacheStub()) + let payment = SKPayment(product: SKProductStub(map: productResponseMap)) + + handler.startObservingPaymentQueue() + handler.add(payment) + waitForExpectations(timeout: 5) + + let unwrappedTransaction = try XCTUnwrap(transactionStub) + XCTAssertEqual(unwrappedTransaction.transactionState, .deferred) + XCTAssertEqual(unwrappedTransaction.transactionIdentifier, nil) + } + + func testFinishTransaction() { + let expectation = self.expectation(description: "handler.transactions should be empty.") + let queue = PaymentQueueStub() + queue.testState = .deferred + var handler: FIAPaymentQueueHandler! + handler = FIAPaymentQueueHandler( + queue: queue, + transactionsUpdated: { transactions in + XCTAssertEqual(transactions.count, 1) + let transaction = transactions[0] + handler.finish(transaction) + }, + transactionRemoved: { transactions in + XCTAssertEqual(transactions.count, 1) + expectation.fulfill() + }, + restoreTransactionFailed: nil, + restoreCompletedTransactionsFinished: nil, + shouldAddStorePayment: { _, _ in + return true + }, + updatedDownloads: nil, + transactionCache: TransactionCacheStub()) + let payment = SKPayment(product: SKProductStub(map: productResponseMap)) + + handler.startObservingPaymentQueue() + handler.add(payment) + + waitForExpectations(timeout: 5) + } + + func testStartObservingPaymentQueueShouldNotProcessTransactionsWhenCacheIsEmpty() { + let cacheStub = TransactionCacheStub() + let handler = FIAPaymentQueueHandler( + queue: PaymentQueueStub(), + transactionsUpdated: { _ in + XCTFail("transactionsUpdated callback should not be called when cache is empty.") + }, + transactionRemoved: { _ in + XCTFail("transactionRemoved callback should not be called when cache is empty.") + }, + restoreTransactionFailed: nil, + restoreCompletedTransactionsFinished: nil, + shouldAddStorePayment: { _, _ in + return true + }, + updatedDownloads: { _ in + XCTFail("updatedDownloads callback should not be called when cache is empty.") + }, + transactionCache: cacheStub) + + var transactionCacheKeyUpdatedTransactionsInvokedCount = 0 + var transactionCacheKeyUpdatedDownloadsInvokedCount = 0 + var transactionCacheKeyRemovedTransactionsInvokedCount = 0 + + cacheStub.getObjectsForKeyStub = { key in + switch key { + case .updatedTransactions: + transactionCacheKeyUpdatedTransactionsInvokedCount += 1 + case .updatedDownloads: + transactionCacheKeyUpdatedDownloadsInvokedCount += 1 + case .removedTransactions: + transactionCacheKeyRemovedTransactionsInvokedCount += 1 + default: + XCTFail("Invalid transaction state was invoked.") + } + return [] + } + + handler.startObservingPaymentQueue() + + XCTAssertEqual(transactionCacheKeyUpdatedTransactionsInvokedCount, 1) + XCTAssertEqual(transactionCacheKeyUpdatedDownloadsInvokedCount, 1) + XCTAssertEqual(transactionCacheKeyRemovedTransactionsInvokedCount, 1) + } + + func + testStartObservingPaymentQueueShouldNotProcessTransactionsWhenCacheContainsEmptyTransactionArrays() + { + let cacheStub = TransactionCacheStub() + let handler = FIAPaymentQueueHandler( + queue: PaymentQueueStub(), + transactionsUpdated: { _ in + XCTFail("transactionsUpdated callback should not be called when cache is empty.") + }, + transactionRemoved: { _ in + XCTFail("transactionRemoved callback should not be called when cache is empty.") + }, + restoreTransactionFailed: nil, + restoreCompletedTransactionsFinished: nil, + shouldAddStorePayment: { _, _ in + return true + }, + updatedDownloads: { _ in + XCTFail("updatedDownloads callback should not be called when cache is empty.") + }, + transactionCache: cacheStub) + + var transactionCacheKeyUpdatedTransactionsInvokedCount = 0 + var transactionCacheKeyUpdatedDownloadsInvokedCount = 0 + var transactionCacheKeyRemovedTransactionsInvokedCount = 0 + + cacheStub.getObjectsForKeyStub = { key in + switch key { + case .updatedTransactions: + transactionCacheKeyUpdatedTransactionsInvokedCount += 1 + return [] + case .updatedDownloads: + transactionCacheKeyUpdatedDownloadsInvokedCount += 1 + return [] + case .removedTransactions: + transactionCacheKeyRemovedTransactionsInvokedCount += 1 + return [] + default: + XCTFail("Invalid transaction state was invoked.") + } + return [] + } + + handler.startObservingPaymentQueue() + + XCTAssertEqual(transactionCacheKeyUpdatedTransactionsInvokedCount, 1) + XCTAssertEqual(transactionCacheKeyUpdatedDownloadsInvokedCount, 1) + XCTAssertEqual(transactionCacheKeyRemovedTransactionsInvokedCount, 1) + } + + func testStartObservingPaymentQueueShouldProcessTransactionsForItemsInCache() { + let updateTransactionsExpectation = expectation( + description: "transactionsUpdated callback should be called with one transaction.") + let removeTransactionsExpectation = expectation( + description: "transactionsRemoved callback should be called with one transaction.") + let updateDownloadsExpectation = expectation( + description: "downloadsUpdated callback should be called with one transaction.") + let transactionStub = SKPaymentTransactionStub() + let downloadStub = SKDownload() + let cacheStub = TransactionCacheStub() + let handler = FIAPaymentQueueHandler( + queue: PaymentQueueStub(), + transactionsUpdated: { transactions in + XCTAssertEqual(transactions as? [SKPaymentTransactionStub], [transactionStub]) + updateTransactionsExpectation.fulfill() + }, + transactionRemoved: { transactions in + XCTAssertEqual(transactions as? [SKPaymentTransactionStub], [transactionStub]) + removeTransactionsExpectation.fulfill() + }, + restoreTransactionFailed: nil, + restoreCompletedTransactionsFinished: nil, + shouldAddStorePayment: { _, _ in + return true + }, + updatedDownloads: { downloads in + XCTAssertEqual(downloads as NSArray, [downloadStub] as NSArray) + updateDownloadsExpectation.fulfill() + }, + transactionCache: cacheStub) + + var transactionCacheKeyUpdatedTransactionsInvokedCount = 0 + var transactionCacheKeyUpdatedDownloadsInvokedCount = 0 + var transactionCacheKeyRemovedTransactionsInvokedCount = 0 + + cacheStub.getObjectsForKeyStub = { key in + switch key { + case .updatedTransactions: + transactionCacheKeyUpdatedTransactionsInvokedCount += 1 + return [transactionStub] + case .updatedDownloads: + transactionCacheKeyUpdatedDownloadsInvokedCount += 1 + return [downloadStub] + case .removedTransactions: + transactionCacheKeyRemovedTransactionsInvokedCount += 1 + return [transactionStub] + default: + XCTFail("Invalid transaction state was invoked.") + } + return [] + } + + var clearInvokedCount = 0 + cacheStub.clearStub = { + clearInvokedCount += 1 + } + + handler.startObservingPaymentQueue() + + waitForExpectations(timeout: 5) + XCTAssertEqual(transactionCacheKeyUpdatedTransactionsInvokedCount, 1) + XCTAssertEqual(transactionCacheKeyUpdatedDownloadsInvokedCount, 1) + XCTAssertEqual(transactionCacheKeyRemovedTransactionsInvokedCount, 1) + XCTAssertEqual(clearInvokedCount, 1) + } + + func testTransactionsShouldBeCachedWhenNotObserving() { + let queue = PaymentQueueStub() + let cacheStub = TransactionCacheStub() + let handler = FIAPaymentQueueHandler( + queue: queue, + transactionsUpdated: { _ in + XCTFail("transactionsUpdated callback should not be called when cache is empty.") + }, + transactionRemoved: { _ in + XCTFail("transactionRemoved callback should not be called when cache is empty.") + }, + restoreTransactionFailed: nil, + restoreCompletedTransactionsFinished: nil, + shouldAddStorePayment: { _, _ in + return true + }, + updatedDownloads: { _ in + XCTFail("updatedDownloads callback should not be called when cache is empty.") + }, + transactionCache: cacheStub) + + let payment = SKPayment(product: SKProductStub(map: productResponseMap)) + + var transactionCacheKeyUpdatedTransactionsInvokedCount = 0 + var transactionCacheKeyUpdatedDownloadsInvokedCount = 0 + var transactionCacheKeyRemovedTransactionsInvokedCount = 0 + + cacheStub.addObjectsStub = { objects, key in + switch key { + case .updatedTransactions: + transactionCacheKeyUpdatedTransactionsInvokedCount += 1 + case .updatedDownloads: + transactionCacheKeyUpdatedDownloadsInvokedCount += 1 + case .removedTransactions: + transactionCacheKeyRemovedTransactionsInvokedCount += 1 + default: + XCTFail("Invalid transaction state was invoked.") + } + } + + handler.add(payment) + + XCTAssertEqual(transactionCacheKeyUpdatedTransactionsInvokedCount, 1) + XCTAssertEqual(transactionCacheKeyUpdatedDownloadsInvokedCount, 0) + XCTAssertEqual(transactionCacheKeyRemovedTransactionsInvokedCount, 0) + } + + func testTransactionsShouldNotBeCachedWhenObserving() { + let updateTransactionsExpectation = expectation( + description: "transactionsUpdated callback should be called with one transaction.") + let removeTransactionsExpectation = expectation( + description: "transactionsRemoved callback should be called with one transaction.") + let updateDownloadsExpectation = expectation( + description: "downloadsUpdated callback should be called with one transaction.") + let transactionStub = SKPaymentTransactionStub() + let downloadStub = SKDownload() + let queue = PaymentQueueStub() + queue.testState = .purchased + let cacheStub = TransactionCacheStub() + let handler = FIAPaymentQueueHandler( + queue: queue, + transactionsUpdated: { transactions in + XCTAssertEqual(transactions as? [SKPaymentTransactionStub], [transactionStub]) + updateTransactionsExpectation.fulfill() + }, + transactionRemoved: { transactions in + XCTAssertEqual(transactions as? [SKPaymentTransactionStub], [transactionStub]) + removeTransactionsExpectation.fulfill() + }, + restoreTransactionFailed: nil, + restoreCompletedTransactionsFinished: nil, + shouldAddStorePayment: { _, _ in + return true + }, + updatedDownloads: { downloads in + XCTAssertEqual(downloads as NSArray, [downloadStub] as NSArray) + updateDownloadsExpectation.fulfill() + }, + transactionCache: cacheStub) + + let paymentQueueStub = SKPaymentQueueStub() + + handler.startObservingPaymentQueue() + handler.paymentQueue(paymentQueueStub, updatedTransactions: [transactionStub]) + handler.paymentQueue(paymentQueueStub, removedTransactions: [transactionStub]) + handler.paymentQueue(paymentQueueStub, updatedDownloads: [downloadStub]) + + waitForExpectations(timeout: 5) + + var transactionCacheKeyUpdatedTransactionsInvokedCount = 0 + var transactionCacheKeyUpdatedDownloadsInvokedCount = 0 + var transactionCacheKeyRemovedTransactionsInvokedCount = 0 + + cacheStub.addObjectsStub = { objects, key in + switch key { + case .updatedTransactions: + transactionCacheKeyUpdatedTransactionsInvokedCount += 1 + case .updatedDownloads: + transactionCacheKeyUpdatedDownloadsInvokedCount += 1 + case .removedTransactions: + transactionCacheKeyRemovedTransactionsInvokedCount += 1 + default: + XCTFail("Invalid transaction state was invoked.") + } + } + + XCTAssertEqual(transactionCacheKeyUpdatedTransactionsInvokedCount, 0) + XCTAssertEqual(transactionCacheKeyUpdatedDownloadsInvokedCount, 0) + XCTAssertEqual(transactionCacheKeyRemovedTransactionsInvokedCount, 0) + } +} diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/ProductRequestHandlerTests.m b/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/ProductRequestHandlerTests.m deleted file mode 100644 index ac36aae5acb5..000000000000 --- a/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/ProductRequestHandlerTests.m +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import -#import "Stubs.h" - -@import in_app_purchase_storekit; - -#pragma tests start here - -@interface RequestHandlerTest : XCTestCase - -@end - -@implementation RequestHandlerTest - -- (void)testRequestHandlerWithProductRequestSuccess { - SKProductRequestStub *request = - [[SKProductRequestStub alloc] initWithProductIdentifiers:[NSSet setWithArray:@[ @"123" ]]]; - FIAPRequestHandler *handler = [[FIAPRequestHandler alloc] initWithRequest:request]; - XCTestExpectation *expectation = - [self expectationWithDescription:@"expect to get response with 1 product"]; - __block SKProductsResponse *response; - [handler - startProductRequestWithCompletionHandler:^(SKProductsResponse *_Nullable r, NSError *error) { - response = r; - [expectation fulfill]; - }]; - [self waitForExpectations:@[ expectation ] timeout:5]; - XCTAssertNotNil(response); - XCTAssertEqual(response.products.count, 1); - SKProduct *product = response.products.firstObject; - XCTAssertTrue([product.productIdentifier isEqualToString:@"123"]); -} - -- (void)testRequestHandlerWithProductRequestFailure { - SKProductRequestStub *request = [[SKProductRequestStub alloc] - initWithFailureError:[NSError errorWithDomain:@"test" code:123 userInfo:@{}]]; - FIAPRequestHandler *handler = [[FIAPRequestHandler alloc] initWithRequest:request]; - XCTestExpectation *expectation = - [self expectationWithDescription:@"expect to get response with 1 product"]; - __block NSError *error; - __block SKProductsResponse *response; - [handler startProductRequestWithCompletionHandler:^(SKProductsResponse *_Nullable r, NSError *e) { - error = e; - response = r; - [expectation fulfill]; - }]; - [self waitForExpectations:@[ expectation ] timeout:5]; - XCTAssertNotNil(error); - XCTAssertEqual(error.domain, @"test"); - XCTAssertNil(response); -} - -- (void)testRequestHandlerWithRefreshReceiptSuccess { - SKReceiptRefreshRequestStub *request = - [[SKReceiptRefreshRequestStub alloc] initWithReceiptProperties:nil]; - FIAPRequestHandler *handler = [[FIAPRequestHandler alloc] initWithRequest:request]; - XCTestExpectation *expectation = [self expectationWithDescription:@"expect no error"]; - __block NSError *e; - [handler - startProductRequestWithCompletionHandler:^(SKProductsResponse *_Nullable r, NSError *error) { - e = error; - [expectation fulfill]; - }]; - [self waitForExpectations:@[ expectation ] timeout:5]; - XCTAssertNil(e); -} - -- (void)testRequestHandlerWithRefreshReceiptFailure { - SKReceiptRefreshRequestStub *request = [[SKReceiptRefreshRequestStub alloc] - initWithFailureError:[NSError errorWithDomain:@"test" code:123 userInfo:@{}]]; - FIAPRequestHandler *handler = [[FIAPRequestHandler alloc] initWithRequest:request]; - XCTestExpectation *expectation = [self expectationWithDescription:@"expect error"]; - __block NSError *error; - __block SKProductsResponse *response; - [handler startProductRequestWithCompletionHandler:^(SKProductsResponse *_Nullable r, NSError *e) { - error = e; - response = r; - [expectation fulfill]; - }]; - [self waitForExpectations:@[ expectation ] timeout:5]; - XCTAssertNotNil(error); - XCTAssertEqual(error.domain, @"test"); - XCTAssertNil(response); -} - -@end diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/ProductRequestHandlerTests.swift b/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/ProductRequestHandlerTests.swift new file mode 100644 index 000000000000..189ab5a85272 --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/ProductRequestHandlerTests.swift @@ -0,0 +1,91 @@ +// 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 StoreKit +import XCTest + +@testable import in_app_purchase_storekit + +final class RequestHandlerTest: XCTestCase { + + func testRequestHandlerWithProductRequestSuccess() { + let productIdentifiers = Set(["123"]) + let request = SKProductRequestStub(productIdentifiers: productIdentifiers) + let handler = FIAPRequestHandler(request: request) + + let expectation = expectation(description: "Expect response with 1 product") + var response: SKProductsResponse? + + handler.startProductRequest { requestResponse, _ in + response = requestResponse + expectation.fulfill() + } + + wait(for: [expectation], timeout: 5) + + XCTAssertNotNil(response) + XCTAssertEqual(response?.products.count, 1) + XCTAssertEqual(response?.products.first?.productIdentifier, "123") + } + + func testRequestHandlerWithProductRequestFailure() { + let request = SKProductRequestStub( + failureError: NSError(domain: "test", code: 123, userInfo: [:])) + let handler = FIAPRequestHandler(request: request) + + let expectation = expectation(description: "Expect response with error") + var error: Error? + var response: SKProductsResponse? + + handler.startProductRequest { r, e in + response = r + error = e + expectation.fulfill() + } + + wait(for: [expectation], timeout: 5) + + XCTAssertNotNil(error) + XCTAssertEqual((error as NSError?)?.domain, "test") + XCTAssertNil(response) + } + + func testRequestHandlerWithRefreshReceiptSuccess() { + let request = SKReceiptRefreshRequestStub(receiptProperties: nil) + let handler = FIAPRequestHandler(request: request) + + let expectation = expectation(description: "Expect no error") + var error: Error? + + handler.startProductRequest { _, e in + error = e + expectation.fulfill() + } + + wait(for: [expectation], timeout: 5) + XCTAssertNil(error) + } + + func testRequestHandlerWithRefreshReceiptFailure() { + let request = SKReceiptRefreshRequestStub( + failureError: NSError(domain: "test", code: 123, userInfo: [:])) + let handler = FIAPRequestHandler(request: request) + + let expectation = expectation(description: "Expect error") + var error: Error? + var response: SKProductsResponse? + + handler.startProductRequest { r, e in + response = r + error = e + expectation.fulfill() + } + + wait(for: [expectation], timeout: 5) + + XCTAssertNotNil(error) + XCTAssertEqual((error as NSError?)?.domain, "test") + XCTAssertNil(response) + } +} diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/StoreKit2TranslatorTests.swift b/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/StoreKit2TranslatorTests.swift new file mode 100644 index 000000000000..6fbd1f8444f0 --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/StoreKit2TranslatorTests.swift @@ -0,0 +1,82 @@ +// 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 Foundation +import StoreKitTest +import XCTest + +@testable import in_app_purchase_storekit + +@available(iOS 15.0, macOS 12.0, *) +final class StoreKit2TranslatorTests: XCTestCase { + private var session: SKTestSession! + private var plugin: InAppPurchasePlugin! + private var product: Product! + + // This is transcribed from the Configuration.storekit file. + var productMessage: SK2ProductMessage = + SK2ProductMessage( + id: "subscription_silver", + displayName: "Subscription Silver", + description: "A lower level subscription.", + price: 4.99, + displayPrice: "$4.99", + type: SK2ProductTypeMessage.autoRenewable, + subscription: SK2SubscriptionInfoMessage( + promotionalOffers: [], + subscriptionGroupID: "D0FEE8D8", + subscriptionPeriod: SK2SubscriptionPeriodMessage( + value: 1, + unit: SK2SubscriptionPeriodUnitMessage.week)), + priceLocale: SK2PriceLocaleMessage(currencyCode: "USD", currencySymbol: "$")) + + override func setUp() async throws { + try await super.setUp() + + self.session = try! SKTestSession(configurationFileNamed: "Configuration") + self.session.clearTransactions() + let receiptManagerStub = FIAPReceiptManagerStub() + plugin = InAppPurchasePluginStub(receiptManager: receiptManagerStub) { request in + DefaultRequestHandler(requestHandler: FIAPRequestHandler(request: request)) + } + product = try await Product.products(for: ["subscription_silver"]).first! + + } + + func testPigeonConversionForProduct() async throws { + XCTAssertNotNil(product) + let pigeonMessage = product.convertToPigeon + XCTAssertEqual(pigeonMessage, productMessage) + } + + func testPigeonConversionForSubscriptionInfo() async throws { + guard let subscription = product.subscription else { + XCTFail("SubscriptionInfo should not be nil") + return + } + let pigeonMessage = subscription.convertToPigeon + XCTAssertEqual(pigeonMessage, productMessage.subscription) + } + + func testPigeonConversionForProductType() async throws { + let type = product.type + let pigeonMessage = type.convertToPigeon + XCTAssertEqual(pigeonMessage, productMessage.type) + } + + func testPigeonConversionForSubscriptionPeriod() async throws { + guard let period = product.subscription?.subscriptionPeriod else { + XCTFail("SubscriptionPeriod should not be nil") + return + } + let pigeonMessage = period.convertToPigeon + XCTAssertEqual(pigeonMessage, productMessage.subscription?.subscriptionPeriod) + } + + func testPigeonConversionForPriceLocale() async throws { + let locale = product.priceFormatStyle.locale + let pigeonMessage = locale.convertToPigeon + XCTAssertEqual(pigeonMessage, productMessage.priceLocale) + } +} diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/Stubs.h b/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/Stubs.h index 8e7769c5b5a1..bfdec37d394c 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/Stubs.h +++ b/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/Stubs.h @@ -117,10 +117,10 @@ API_AVAILABLE(ios(13.0), macos(10.15)) @interface MethodChannelStub : NSObject // Stubs -@property(nonatomic, copy, nullable) void (^invokeMethodChannelStub)(NSString *method, id arguments) - ; +@property(nonatomic, copy, nullable) void (^invokeMethodChannelStub) + (NSString *method, id _Nullable arguments); @property(nonatomic, copy, nullable) void (^invokeMethodChannelWithResultsStub) - (NSString *method, id arguments, FlutterResult _Nullable); + (NSString *method, id _Nullable arguments, FlutterResult _Nullable); @end diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/TranslatorTests.m b/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/TranslatorTests.m deleted file mode 100644 index 7ffe4c6ac7ff..000000000000 --- a/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/TranslatorTests.m +++ /dev/null @@ -1,518 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import -#import "Stubs.h" - -@import in_app_purchase_storekit; - -@interface TranslatorTest : XCTestCase - -@property(strong, nonatomic) NSDictionary *periodMap; -@property(strong, nonatomic) NSMutableDictionary *discountMap; -@property(strong, nonatomic) NSMutableDictionary *discountMissingIdentifierMap; -@property(strong, nonatomic) NSMutableDictionary *productMap; -@property(strong, nonatomic) NSDictionary *productResponseMap; -@property(strong, nonatomic) NSDictionary *paymentMap; -@property(copy, nonatomic) NSDictionary *paymentDiscountMap; -@property(strong, nonatomic) NSDictionary *transactionMap; -@property(strong, nonatomic) NSDictionary *errorMap; -@property(strong, nonatomic) NSDictionary *localeMap; -@property(strong, nonatomic) NSDictionary *storefrontMap; -@property(strong, nonatomic) NSDictionary *storefrontAndPaymentTransactionMap; -@end - -@implementation TranslatorTest -- (void)setUp { - self.periodMap = @{@"numberOfUnits" : @(0), @"unit" : @(0)}; - - self.discountMap = [[NSMutableDictionary alloc] initWithDictionary:@{ - @"price" : @"1", - @"priceLocale" : [FIAObjectTranslator getMapFromNSLocale:NSLocale.systemLocale], - @"numberOfPeriods" : @1, - @"subscriptionPeriod" : self.periodMap, - @"paymentMode" : @1, - }]; - if (@available(iOS 12.2, *)) { - self.discountMap[@"identifier"] = @"test offer id"; - self.discountMap[@"type"] = @(SKProductDiscountTypeIntroductory); - } - self.discountMissingIdentifierMap = [[NSMutableDictionary alloc] initWithDictionary:@{ - @"price" : @"1", - @"priceLocale" : [FIAObjectTranslator getMapFromNSLocale:NSLocale.systemLocale], - @"numberOfPeriods" : @1, - @"subscriptionPeriod" : self.periodMap, - @"paymentMode" : @1, - @"identifier" : [NSNull null], - @"type" : @0, - }]; - - self.productMap = [[NSMutableDictionary alloc] initWithDictionary:@{ - @"price" : @"1", - @"priceLocale" : [FIAObjectTranslator getMapFromNSLocale:NSLocale.systemLocale], - @"productIdentifier" : @"123", - @"localizedTitle" : @"title", - @"localizedDescription" : @"des", - }]; - self.productMap[@"subscriptionPeriod"] = self.periodMap; - self.productMap[@"introductoryPrice"] = self.discountMap; - if (@available(iOS 12.2, *)) { - self.productMap[@"discounts"] = @[ self.discountMap ]; - } - self.productMap[@"subscriptionGroupIdentifier"] = @"com.group"; - - self.productResponseMap = - @{@"products" : @[ self.productMap ], @"invalidProductIdentifiers" : @[]}; - self.paymentMap = @{ - @"productIdentifier" : @"123", - @"requestData" : @"abcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefgh", - @"quantity" : @(2), - @"applicationUsername" : @"app user name", - @"simulatesAskToBuyInSandbox" : @(NO) - }; - self.paymentDiscountMap = @{ - @"identifier" : @"payment_discount_identifier", - @"keyIdentifier" : @"payment_discount_key_identifier", - @"nonce" : @"d18981e0-9003-4365-98a2-4b90e3b62c52", - @"signature" : @"this is a encrypted signature", - @"timestamp" : @([NSDate date].timeIntervalSince1970), - }; - NSDictionary *originalTransactionMap = @{ - @"transactionIdentifier" : @"567", - @"transactionState" : @(SKPaymentTransactionStatePurchasing), - @"payment" : [NSNull null], - @"error" : [FIAObjectTranslator getMapFromNSError:[NSError errorWithDomain:@"test_stub" - code:123 - userInfo:@{}]], - @"transactionTimeStamp" : @([NSDate date].timeIntervalSince1970), - @"originalTransaction" : [NSNull null], - }; - self.transactionMap = @{ - @"transactionIdentifier" : @"567", - @"transactionState" : @(SKPaymentTransactionStatePurchasing), - @"payment" : [NSNull null], - @"error" : [FIAObjectTranslator getMapFromNSError:[NSError errorWithDomain:@"test_stub" - code:123 - userInfo:@{}]], - @"transactionTimeStamp" : @([NSDate date].timeIntervalSince1970), - @"originalTransaction" : originalTransactionMap, - }; - self.errorMap = @{ - @"code" : @(123), - @"domain" : @"test_domain", - @"userInfo" : @{ - @"key" : @"value", - } - }; - self.storefrontMap = @{ - @"countryCode" : @"USA", - @"identifier" : @"unique_identifier", - }; - - self.storefrontAndPaymentTransactionMap = @{ - @"storefront" : self.storefrontMap, - @"transaction" : self.transactionMap, - }; -} - -- (void)testSKProductSubscriptionPeriodStubToMap { - SKProductSubscriptionPeriodStub *period = - [[SKProductSubscriptionPeriodStub alloc] initWithMap:self.periodMap]; - NSDictionary *map = [FIAObjectTranslator getMapFromSKProductSubscriptionPeriod:period]; - XCTAssertEqualObjects(map, self.periodMap); -} - -- (void)testSKProductDiscountStubToMap { - SKProductDiscountStub *discount = [[SKProductDiscountStub alloc] initWithMap:self.discountMap]; - NSDictionary *map = [FIAObjectTranslator getMapFromSKProductDiscount:discount]; - XCTAssertEqualObjects(map, self.discountMap); -} - -- (void)testProductToMap { - SKProductStub *product = [[SKProductStub alloc] initWithMap:self.productMap]; - NSDictionary *map = [FIAObjectTranslator getMapFromSKProduct:product]; - XCTAssertEqualObjects(map, self.productMap); -} - -- (void)testProductResponseToMap { - SKProductsResponseStub *response = - [[SKProductsResponseStub alloc] initWithMap:self.productResponseMap]; - NSDictionary *map = [FIAObjectTranslator getMapFromSKProductsResponse:response]; - XCTAssertEqualObjects(map, self.productResponseMap); -} - -- (void)testPaymentToMap { - SKMutablePayment *payment = [FIAObjectTranslator getSKMutablePaymentFromMap:self.paymentMap]; - NSDictionary *map = [FIAObjectTranslator getMapFromSKPayment:payment]; - XCTAssertEqualObjects(map, self.paymentMap); -} - -- (void)testPaymentTransactionToMap { - // payment is not KVC, cannot test payment field. - SKPaymentTransactionStub *paymentTransaction = - [[SKPaymentTransactionStub alloc] initWithMap:self.transactionMap]; - NSDictionary *map = [FIAObjectTranslator getMapFromSKPaymentTransaction:paymentTransaction]; - XCTAssertEqualObjects(map, self.transactionMap); -} - -- (void)testError { - NSErrorStub *error = [[NSErrorStub alloc] initWithMap:self.errorMap]; - NSDictionary *map = [FIAObjectTranslator getMapFromNSError:error]; - XCTAssertEqualObjects(map, self.errorMap); -} - -- (void)testErrorWithNSNumberAsUserInfo { - NSError *error = [NSError errorWithDomain:SKErrorDomain code:3 userInfo:@{@"key" : @42}]; - NSDictionary *expectedMap = - @{@"domain" : SKErrorDomain, @"code" : @3, @"userInfo" : @{@"key" : @42}}; - NSDictionary *map = [FIAObjectTranslator getMapFromNSError:error]; - XCTAssertEqualObjects(expectedMap, map); -} - -- (void)testErrorWithMultipleUnderlyingErrors { - NSError *underlyingErrorOne = [NSError errorWithDomain:SKErrorDomain code:2 userInfo:nil]; - NSError *underlyingErrorTwo = [NSError errorWithDomain:SKErrorDomain code:1 userInfo:nil]; - NSError *mainError = [NSError - errorWithDomain:SKErrorDomain - code:3 - userInfo:@{@"underlyingErrors" : @[ underlyingErrorOne, underlyingErrorTwo ]}]; - NSDictionary *expectedMap = @{ - @"domain" : SKErrorDomain, - @"code" : @3, - @"userInfo" : @{ - @"underlyingErrors" : @[ - @{@"domain" : SKErrorDomain, @"code" : @2, @"userInfo" : @{}}, - @{@"domain" : SKErrorDomain, @"code" : @1, @"userInfo" : @{}} - ] - } - }; - NSDictionary *map = [FIAObjectTranslator getMapFromNSError:mainError]; - XCTAssertEqualObjects(expectedMap, map); -} - -- (void)testErrorWithNestedUnderlyingError { - NSError *underlyingError = [NSError errorWithDomain:SKErrorDomain code:2 userInfo:nil]; - NSError *mainError = - [NSError errorWithDomain:SKErrorDomain - code:3 - userInfo:@{@"nesting" : @{@"underlyingError" : underlyingError}}]; - NSDictionary *expectedMap = @{ - @"domain" : SKErrorDomain, - @"code" : @3, - @"userInfo" : @{ - @"nesting" : @{ - @"underlyingError" : @{@"domain" : SKErrorDomain, @"code" : @2, @"userInfo" : @{}}, - - } - } - }; - NSDictionary *map = [FIAObjectTranslator getMapFromNSError:mainError]; - XCTAssertEqualObjects(expectedMap, map); -} - -- (void)testErrorWithUnsupportedUserInfo { - NSError *error = [NSError errorWithDomain:SKErrorDomain - code:3 - userInfo:@{@"user_info" : [[NSObject alloc] init]}]; - NSDictionary *expectedMap = @{ - @"domain" : SKErrorDomain, - @"code" : @3, - @"userInfo" : @{ - @"user_info" : [NSString - stringWithFormat: - @"Unable to encode native userInfo object of type %@ to map. Please submit an " - @"issue at https://github.com/flutter/flutter/issues/new with the title " - @"\"[in_app_purchase_storekit] Unable to encode userInfo of type %@\" and add " - @"reproduction steps and the error details in the description field.", - [NSObject class], [NSObject class]] - } - }; - NSDictionary *map = [FIAObjectTranslator getMapFromNSError:error]; - XCTAssertEqualObjects(expectedMap, map); -} - -- (void)testLocaleToMap { - NSLocale *system = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]; - NSDictionary *map = [FIAObjectTranslator getMapFromNSLocale:system]; - XCTAssertEqualObjects(map[@"currencySymbol"], system.currencySymbol); - XCTAssertEqualObjects(map[@"countryCode"], system.countryCode); -} - -- (void)testSKStorefrontToMap { - if (@available(iOS 13.0, *)) { - SKStorefront *storefront = [[SKStorefrontStub alloc] initWithMap:self.storefrontMap]; - NSDictionary *map = [FIAObjectTranslator getMapFromSKStorefront:storefront]; - XCTAssertEqualObjects(map, self.storefrontMap); - } -} - -- (void)testSKStorefrontAndSKPaymentTransactionToMap { - if (@available(iOS 13.0, *)) { - SKStorefront *storefront = [[SKStorefrontStub alloc] initWithMap:self.storefrontMap]; - SKPaymentTransaction *transaction = - [[SKPaymentTransactionStub alloc] initWithMap:self.transactionMap]; - NSDictionary *map = [FIAObjectTranslator getMapFromSKStorefront:storefront - andSKPaymentTransaction:transaction]; - XCTAssertEqualObjects(map, self.storefrontAndPaymentTransactionMap); - } -} - -- (void)testSKPaymentDiscountFromMap { - if (@available(iOS 12.2, *)) { - NSString *error = nil; - SKPaymentDiscount *paymentDiscount = - [FIAObjectTranslator getSKPaymentDiscountFromMap:self.paymentDiscountMap withError:&error]; - - XCTAssertEqual(paymentDiscount.identifier, self.paymentDiscountMap[@"identifier"]); - XCTAssertEqual(paymentDiscount.keyIdentifier, self.paymentDiscountMap[@"keyIdentifier"]); - XCTAssertEqualObjects(paymentDiscount.nonce, - [[NSUUID alloc] initWithUUIDString:self.paymentDiscountMap[@"nonce"]]); - XCTAssertEqual(paymentDiscount.signature, self.paymentDiscountMap[@"signature"]); - XCTAssertEqual(paymentDiscount.timestamp, self.paymentDiscountMap[@"timestamp"]); - } -} - -- (void)testSKPaymentDiscountFromMapMissingIdentifier { - if (@available(iOS 12.2, *)) { - NSArray *invalidValues = @[ [NSNull null], @(1), @"" ]; - - for (id value in invalidValues) { - NSDictionary *discountMap = @{ - @"identifier" : value, - @"keyIdentifier" : @"payment_discount_key_identifier", - @"nonce" : @"d18981e0-9003-4365-98a2-4b90e3b62c52", - @"signature" : @"this is a encrypted signature", - @"timestamp" : @([NSDate date].timeIntervalSince1970), - }; - - NSString *error = nil; - [FIAObjectTranslator getSKPaymentDiscountFromMap:discountMap withError:&error]; - - XCTAssertNotNil(error); - XCTAssertEqualObjects( - error, @"When specifying a payment discount the 'identifier' field is mandatory."); - } - } -} - -- (void)testGetMapFromSKProductDiscountMissingIdentifier { - if (@available(iOS 12.2, *)) { - SKProductDiscountStub *discount = - [[SKProductDiscountStub alloc] initWithMap:self.discountMissingIdentifierMap]; - NSDictionary *map = [FIAObjectTranslator getMapFromSKProductDiscount:discount]; - XCTAssertEqualObjects(map, self.discountMissingIdentifierMap); - } -} - -- (void)testSKPaymentDiscountFromMapMissingKeyIdentifier { - if (@available(iOS 12.2, *)) { - NSArray *invalidValues = @[ [NSNull null], @(1), @"" ]; - - for (id value in invalidValues) { - NSDictionary *discountMap = @{ - @"identifier" : @"payment_discount_identifier", - @"keyIdentifier" : value, - @"nonce" : @"d18981e0-9003-4365-98a2-4b90e3b62c52", - @"signature" : @"this is a encrypted signature", - @"timestamp" : @([NSDate date].timeIntervalSince1970), - }; - - NSString *error = nil; - [FIAObjectTranslator getSKPaymentDiscountFromMap:discountMap withError:&error]; - - XCTAssertNotNil(error); - XCTAssertEqualObjects( - error, @"When specifying a payment discount the 'keyIdentifier' field is mandatory."); - } - } -} - -- (void)testSKPaymentDiscountFromMapMissingNonce { - if (@available(iOS 12.2, *)) { - NSArray *invalidValues = @[ [NSNull null], @(1), @"" ]; - - for (id value in invalidValues) { - NSDictionary *discountMap = @{ - @"identifier" : @"payment_discount_identifier", - @"keyIdentifier" : @"payment_discount_key_identifier", - @"nonce" : value, - @"signature" : @"this is a encrypted signature", - @"timestamp" : @([NSDate date].timeIntervalSince1970), - }; - - NSString *error = nil; - [FIAObjectTranslator getSKPaymentDiscountFromMap:discountMap withError:&error]; - - XCTAssertNotNil(error); - XCTAssertEqualObjects(error, - @"When specifying a payment discount the 'nonce' field is mandatory."); - } - } -} - -- (void)testSKPaymentDiscountFromMapMissingSignature { - if (@available(iOS 12.2, *)) { - NSArray *invalidValues = @[ [NSNull null], @(1), @"" ]; - - for (id value in invalidValues) { - NSDictionary *discountMap = @{ - @"identifier" : @"payment_discount_identifier", - @"keyIdentifier" : @"payment_discount_key_identifier", - @"nonce" : @"d18981e0-9003-4365-98a2-4b90e3b62c52", - @"signature" : value, - @"timestamp" : @([NSDate date].timeIntervalSince1970), - }; - - NSString *error = nil; - [FIAObjectTranslator getSKPaymentDiscountFromMap:discountMap withError:&error]; - - XCTAssertNotNil(error); - XCTAssertEqualObjects( - error, @"When specifying a payment discount the 'signature' field is mandatory."); - } - } -} - -- (void)testSKPaymentDiscountFromMapMissingTimestamp { - if (@available(iOS 12.2, *)) { - NSArray *invalidValues = @[ [NSNull null], @"", @(-1) ]; - - for (id value in invalidValues) { - NSDictionary *discountMap = @{ - @"identifier" : @"payment_discount_identifier", - @"keyIdentifier" : @"payment_discount_key_identifier", - @"nonce" : @"d18981e0-9003-4365-98a2-4b90e3b62c52", - @"signature" : @"this is a encrypted signature", - @"timestamp" : value, - }; - - NSString *error = nil; - [FIAObjectTranslator getSKPaymentDiscountFromMap:discountMap withError:&error]; - - XCTAssertNotNil(error); - XCTAssertEqualObjects( - error, @"When specifying a payment discount the 'timestamp' field is mandatory."); - } - } -} - -- (void)testSKPaymentDiscountFromMapOverflowingTimestamp { - if (@available(iOS 12.2, *)) { - NSDictionary *discountMap = @{ - @"identifier" : @"payment_discount_identifier", - @"keyIdentifier" : @"payment_discount_key_identifier", - @"nonce" : @"d18981e0-9003-4365-98a2-4b90e3b62c52", - @"signature" : @"this is a encrypted signature", - @"timestamp" : @1665044583595, // timestamp 2022 Oct - }; - NSString *error = nil; - SKPaymentDiscount *paymentDiscount = - [FIAObjectTranslator getSKPaymentDiscountFromMap:discountMap withError:&error]; - XCTAssertNil(error); - XCTAssertNotNil(paymentDiscount); - XCTAssertEqual(paymentDiscount.identifier, discountMap[@"identifier"]); - XCTAssertEqual(paymentDiscount.keyIdentifier, discountMap[@"keyIdentifier"]); - XCTAssertEqualObjects(paymentDiscount.nonce, - [[NSUUID alloc] initWithUUIDString:discountMap[@"nonce"]]); - XCTAssertEqual(paymentDiscount.signature, discountMap[@"signature"]); - XCTAssertEqual(paymentDiscount.timestamp, discountMap[@"timestamp"]); - } -} - -- (void)testSKPaymentDiscountConvertToPigeon { - if (@available(iOS 12.2, *)) { - NSString *error = nil; - SKPaymentDiscount *paymentDiscount = - [FIAObjectTranslator getSKPaymentDiscountFromMap:self.paymentDiscountMap withError:&error]; - SKPaymentDiscountMessage *paymentDiscountPigeon = - [FIAObjectTranslator convertPaymentDiscountToPigeon:paymentDiscount]; - - XCTAssertNotNil(paymentDiscountPigeon); - XCTAssertEqual(paymentDiscount.identifier, paymentDiscountPigeon.identifier); - XCTAssertEqual(paymentDiscount.keyIdentifier, paymentDiscount.keyIdentifier); - XCTAssertEqualObjects(paymentDiscount.nonce, - [[NSUUID alloc] initWithUUIDString:paymentDiscountPigeon.nonce]); - XCTAssertEqual(paymentDiscount.signature, paymentDiscountPigeon.signature); - XCTAssertEqual([paymentDiscount.timestamp intValue], paymentDiscountPigeon.timestamp); - } -} - -- (void)testSKErrorConvertToPigeon { - NSError *error = [NSError errorWithDomain:SKErrorDomain code:3 userInfo:@{@"key" : @42}]; - SKErrorMessage *msg = [SKErrorMessage makeWithCode:3 - domain:SKErrorDomain - userInfo:@{@"key" : @42}]; - - SKErrorMessage *skerror = [FIAObjectTranslator convertSKErrorToPigeon:error]; - XCTAssertEqual(skerror.domain, msg.domain); - XCTAssertEqual(skerror.code, msg.code); - XCTAssertEqualObjects(skerror.userInfo, msg.userInfo); -} - -- (void)testSKPaymentConvertToPigeon { - if (@available(iOS 12.2, *)) { - SKMutablePayment *payment = [FIAObjectTranslator getSKMutablePaymentFromMap:self.paymentMap]; - SKPaymentMessage *msg = [FIAObjectTranslator convertPaymentToPigeon:payment]; - - XCTAssertEqual(payment.productIdentifier, msg.productIdentifier); - XCTAssertEqualObjects(payment.requestData, - [msg.requestData dataUsingEncoding:NSUTF8StringEncoding]); - XCTAssertEqual(payment.quantity, msg.quantity); - XCTAssertEqual(payment.applicationUsername, msg.applicationUsername); - XCTAssertEqual(payment.simulatesAskToBuyInSandbox, msg.simulatesAskToBuyInSandbox); - } -} - -- (void)testSKPaymentTransactionConvertToPigeon { - SKPaymentTransactionStub *paymentTransaction = - [[SKPaymentTransactionStub alloc] initWithMap:self.transactionMap]; - - SKPaymentTransactionMessage *msg = - [FIAObjectTranslator convertTransactionToPigeon:paymentTransaction]; - - XCTAssertEqual(msg.payment, NULL); - XCTAssertEqual(msg.transactionState, SKPaymentTransactionStateMessagePurchasing); - XCTAssertEqual(paymentTransaction.transactionDate, - [NSDate dateWithTimeIntervalSince1970:[msg.transactionTimeStamp doubleValue]]); - XCTAssertEqual(paymentTransaction.transactionIdentifier, msg.transactionIdentifier); -} - -- (void)testSKProductResponseCovertToPigeon { - SKProductsResponseStub *response = - [[SKProductsResponseStub alloc] initWithMap:self.productResponseMap]; - SKProductsResponseMessage *responseMsg = - [FIAObjectTranslator convertProductsResponseToPigeon:response]; - - XCTAssertEqual(responseMsg.products.count, 1); - XCTAssertEqual(responseMsg.invalidProductIdentifiers.count, 0); - - SKProductMessage *productMsg = responseMsg.products[0]; - - // These values are being set in productResponseMap in setUp() - XCTAssertEqualObjects(productMsg.price, @"1"); - XCTAssertEqualObjects(productMsg.productIdentifier, @"123"); - XCTAssertEqualObjects(productMsg.localizedTitle, @"title"); - XCTAssertEqualObjects(productMsg.localizedDescription, @"des"); - XCTAssertEqualObjects(productMsg.subscriptionGroupIdentifier, @"com.group"); - - SKPriceLocaleMessage *localeMsg = productMsg.priceLocale; - SKProductSubscriptionPeriodMessage *subPeriod = productMsg.subscriptionPeriod; - SKProductDiscountMessage *introDiscount = productMsg.introductoryPrice; - NSArray *discounts = productMsg.discounts; - - XCTAssertEqualObjects(localeMsg.countryCode, nil); - XCTAssertEqualObjects(localeMsg.currencyCode, nil); - XCTAssertEqualObjects(localeMsg.currencySymbol, @"\u00a4"); - - XCTAssertEqual(subPeriod.unit, SKSubscriptionPeriodUnitMessageDay); - XCTAssertEqual(subPeriod.numberOfUnits, 0); - - XCTAssertEqualObjects(introDiscount.price, @"1"); - XCTAssertEqual(introDiscount.numberOfPeriods, 1); - XCTAssertEqual(introDiscount.paymentMode, SKProductDiscountPaymentModeMessagePayUpFront); - - XCTAssertEqual(discounts.count, 1); -} - -@end diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/TranslatorTests.swift b/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/TranslatorTests.swift new file mode 100644 index 000000000000..f7e384804033 --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/example/shared/RunnerTests/TranslatorTests.swift @@ -0,0 +1,551 @@ +// 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 Foundation +import StoreKit +import XCTest + +@testable import in_app_purchase_storekit + +final class ObjectTranslatorTest: XCTestCase { + private var periodMap: [String: Any] { + ["numberOfUnits": 0, "unit": 0] + } + private var discountMap: [String: Any] { + var map: [String: Any] = [ + "price": "1", + "priceLocale": FIAObjectTranslator.getMapFrom(NSLocale.system), + "numberOfPeriods": 1, + "subscriptionPeriod": periodMap, + "paymentMode": 1, + ] + if #available(iOS 12.2, *) { + map["identifier"] = "test offer id" + // Type is being instantiated like this because of Swift naming weirdness + let type: SKProductDiscount.`Type` = .introductory + map["type"] = type.rawValue + } + return map + } + private var discountMissingIdentifierMap: [String: Any] { + [ + "price": "1", + "priceLocale": FIAObjectTranslator.getMapFrom(NSLocale.system), + "numberOfPeriods": 1, + "subscriptionPeriod": periodMap, + "paymentMode": 1, + "identifier": NSNull(), + "type": 0, + ] + } + private var productMap: [String: Any] { + var map: [String: Any] = [ + "price": "1", + "priceLocale": FIAObjectTranslator.getMapFrom(NSLocale.system), + "productIdentifier": "123", + "localizedTitle": "title", + "localizedDescription": "des", + "subscriptionPeriod": periodMap, + "introductoryPrice": discountMap, + "subscriptionGroupIdentifier": "com.group", + ] + if #available(iOS 12.2, *) { + map["discounts"] = [discountMap] + } + return map + } + private var productResponseMap: [String: Any] { + ["products": [productMap], "invalidProductIdentifiers": []] + } + private var paymentMap: [String: Any] { + [ + "productIdentifier": "123", + "requestData": "abcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefgh", + "quantity": 2, + "applicationUsername": "app user name", + "simulatesAskToBuyInSandbox": false, + ] + } + private var paymentDiscountMap: [String: Any] { + [ + "identifier": "payment_discount_identifier", + "keyIdentifier": "payment_discount_key_identifier", + "nonce": "d18981e0-9003-4365-98a2-4b90e3b62c52", + "signature": "this is an encrypted signature", + "timestamp": Int(Date().timeIntervalSince1970), + ] + } + private var transactionMap: [String: Any] { + [ + "transactionIdentifier": "567", + "transactionState": SKPaymentTransactionState.purchasing.rawValue, + "payment": NSNull(), + "error": FIAObjectTranslator.getMapFrom( + NSError(domain: "test_stub", code: 123, userInfo: [:])), + "transactionTimeStamp": Int(Date().timeIntervalSince1970), + "originalTransaction": originalTransactionMap, + ] + } + private var originalTransactionMap: [String: Any] { + [ + "transactionIdentifier": "567", + "transactionState": SKPaymentTransactionState.purchasing.rawValue, + "payment": NSNull(), + "error": FIAObjectTranslator.getMapFrom( + NSError(domain: "test_stub", code: 123, userInfo: [:])), + "transactionTimeStamp": Int(Date().timeIntervalSince1970), + "originalTransaction": NSNull(), + ] + } + private var errorMap: [String: Any] { + [ + "code": 123, + "domain": "test_domain", + "userInfo": ["key": "value"], + ] + } + private var storefrontMap: [String: Any] { + [ + "countryCode": "USA", + "identifier": "unique_identifier", + ] + } + private var storefrontAndPaymentTransactionMap: [String: Any] { + [ + "storefront": storefrontMap, + "transaction": transactionMap, + ] + } + + func testSKProductSubscriptionPeriodStubToMap() { + let period = SKProductSubscriptionPeriodStub(map: periodMap) + let map = FIAObjectTranslator.getMapFrom(period) + + XCTAssertEqual(map as NSDictionary, periodMap as NSDictionary) + } + + func testSKProductDiscountStubToMap() { + let discount = SKProductDiscountStub(map: discountMap) + let map = FIAObjectTranslator.getMapFrom(discount) + + XCTAssertEqual(map as NSDictionary, discountMap as NSDictionary) + } + + func testProductToMap() { + let product = SKProductStub(map: productMap) + let map = FIAObjectTranslator.getMapFrom(product) + + XCTAssertEqual(map as NSDictionary, productMap as NSDictionary) + } + + func testProductResponseToMap() { + let response = SKProductsResponseStub(map: productResponseMap) + let map = FIAObjectTranslator.getMapFrom(response) + + XCTAssertEqual(map as NSDictionary, productResponseMap as NSDictionary) + } + + func testPaymentToMap() { + let payment = FIAObjectTranslator.getSKMutablePayment(fromMap: paymentMap) + let map = FIAObjectTranslator.getMapFrom(payment) + + XCTAssertEqual(map as NSDictionary, paymentMap as NSDictionary) + } + + func testPaymentTransactionToMap() { + let paymentTransaction = SKPaymentTransactionStub(map: transactionMap) + let map = FIAObjectTranslator.getMapFrom(paymentTransaction) + + XCTAssertEqual(map as NSDictionary, transactionMap as NSDictionary) + } + + func testError() { + let error = NSErrorStub(map: errorMap) + let map = FIAObjectTranslator.getMapFrom(error) + + XCTAssertEqual(map as NSDictionary, errorMap as NSDictionary) + } + + func testErrorWithNSNumberAsUserInfo() { + let error = NSError(domain: SKErrorDomain, code: 3, userInfo: ["key": 42]) + let expectedMap: [String: Any] = [ + "domain": SKErrorDomain, + "code": 3, + "userInfo": ["key": 42], + ] + let map = FIAObjectTranslator.getMapFrom(error) + + XCTAssertEqual(map as NSDictionary, expectedMap as NSDictionary) + } + + func testErrorWithMultipleUnderlyingErrors() { + let underlyingErrorOne = NSError(domain: SKErrorDomain, code: 2, userInfo: nil) + let underlyingErrorTwo = NSError(domain: SKErrorDomain, code: 1, userInfo: nil) + let mainError = NSError( + domain: SKErrorDomain, + code: 3, + userInfo: ["underlyingErrors": [underlyingErrorOne, underlyingErrorTwo]] + ) + let expectedMap: [String: Any] = [ + "domain": SKErrorDomain, + "code": 3, + "userInfo": [ + "underlyingErrors": [ + ["domain": SKErrorDomain, "code": 2, "userInfo": [:]], + ["domain": SKErrorDomain, "code": 1, "userInfo": [:]], + ] + ], + ] + let map = FIAObjectTranslator.getMapFrom(mainError) + + XCTAssertEqual(map as NSDictionary, expectedMap as NSDictionary) + } + + func testErrorWithNestedUnderlyingError() { + let underlyingError = NSError(domain: SKErrorDomain, code: 2, userInfo: nil) + let mainError = NSError( + domain: SKErrorDomain, + code: 3, + userInfo: ["nesting": ["underlyingError": underlyingError]] + ) + let expectedMap: [String: Any] = [ + "domain": SKErrorDomain, + "code": 3, + "userInfo": [ + "nesting": [ + "underlyingError": ["domain": SKErrorDomain, "code": 2, "userInfo": [:]] + ] + ], + ] + let map = FIAObjectTranslator.getMapFrom(mainError) + + XCTAssertEqual(map as NSDictionary, expectedMap as NSDictionary) + } + + func testErrorWithUnsupportedUserInfo() { + let error = NSError( + domain: SKErrorDomain, + code: 3, + userInfo: ["user_info": NSObject()] + ) + let expectedMap: [String: Any] = [ + "domain": SKErrorDomain, + "code": 3, + "userInfo": [ + "user_info": String( + format: """ + Unable to encode native userInfo object of type %@ to map. \ + Please submit an issue at https://github.com/flutter/flutter/issues/new \ + with the title "[in_app_purchase_storekit] Unable to encode userInfo of type %@\" \ + and add reproduction steps and the error details in the description field. + """, + NSStringFromClass(NSObject.self), NSStringFromClass(NSObject.self) + ) + ], + ] + let map = FIAObjectTranslator.getMapFrom(error) + + XCTAssertEqual(map as NSDictionary, expectedMap as NSDictionary) + } + + func testLocaleToMap() { + let system = Locale(identifier: "en_US") + let map = FIAObjectTranslator.getMapFrom(system) + + XCTAssertEqual(map["currencySymbol"] as? String, system.currencySymbol) + XCTAssertEqual(map["countryCode"] as? String, system.regionCode) + } + + func testSKStorefrontToMap() { + if #available(iOS 13.0, *) { + let storefront = SKStorefrontStub(map: storefrontMap) + let map = FIAObjectTranslator.getMapFrom(storefront) + + XCTAssertEqual(map as NSDictionary, storefrontMap as NSDictionary) + } + } + + func testSKStorefrontAndSKPaymentTransactionToMap() { + if #available(iOS 13.0, *) { + let storefront = SKStorefrontStub(map: storefrontMap) + let transaction = SKPaymentTransactionStub(map: transactionMap) + let map = FIAObjectTranslator.getMapFrom(storefront, andSKPaymentTransaction: transaction) + + XCTAssertEqual(map as NSDictionary, storefrontAndPaymentTransactionMap as NSDictionary) + } + } + + func testSKPaymentDiscountFromMap() throws { + if #available(iOS 12.2, *) { + var error: NSString? + let paymentDiscount = FIAObjectTranslator.getSKPaymentDiscount( + fromMap: paymentDiscountMap, withError: &error) + + XCTAssertNil(error) + + let unwrappedDiscount = try XCTUnwrap(paymentDiscount) + let unwrappedNonce = try XCTUnwrap(paymentDiscountMap["nonce"] as? String) + + XCTAssertEqual(unwrappedDiscount.identifier, paymentDiscountMap["identifier"] as? String) + XCTAssertEqual( + unwrappedDiscount.keyIdentifier, paymentDiscountMap["keyIdentifier"] as? String) + XCTAssertEqual( + unwrappedDiscount.nonce, UUID(uuidString: unwrappedNonce)) + XCTAssertEqual(unwrappedDiscount.signature, paymentDiscountMap["signature"] as? String) + XCTAssertEqual(unwrappedDiscount.timestamp as? Int, paymentDiscountMap["timestamp"] as? Int) + } + } + + func testSKPaymentDiscountFromMapMissingIdentifier() { + if #available(iOS 12.2, *) { + let invalidValues: [Any?] = [NSNull(), 1, ""] + for value in invalidValues { + let discountMap: [String: Any?] = [ + "identifier": value, + "keyIdentifier": "payment_discount_key_identifier", + "nonce": "d18981e0-9003-4365-98a2-4b90e3b62c52", + "signature": "this is an encrypted signature", + "timestamp": Int(Date().timeIntervalSince1970), + ] + var error: NSString? + let _ = FIAObjectTranslator.getSKPaymentDiscount( + fromMap: discountMap as [String: Any], withError: &error) + + XCTAssertNotNil(error) + XCTAssertEqual( + error, "When specifying a payment discount the 'identifier' field is mandatory.") + } + } + } + + func testGetMapFromSKProductDiscountMissingIdentifier() { + if #available(iOS 12.2, *) { + let discount = SKProductDiscountStub(map: discountMissingIdentifierMap) + let map = FIAObjectTranslator.getMapFrom(discount) + + XCTAssertEqual(map as NSDictionary, discountMissingIdentifierMap as NSDictionary) + } + } + + func testSKPaymentDiscountFromMapMissingKeyIdentifier() { + if #available(iOS 12.2, *) { + let invalidValues: [Any?] = [NSNull(), 1, ""] + for value in invalidValues { + let discountMap: [String: Any?] = [ + "identifier": "payment_discount_identifier", + "keyIdentifier": value, + "nonce": "d18981e0-9003-4365-98a2-4b90e3b62c52", + "signature": "this is an encrypted signature", + "timestamp": Int(Date().timeIntervalSince1970), + ] + var error: NSString? + let _ = FIAObjectTranslator.getSKPaymentDiscount( + fromMap: discountMap as [String: Any], withError: &error) + + XCTAssertNotNil(error) + XCTAssertEqual( + error, "When specifying a payment discount the 'keyIdentifier' field is mandatory.") + } + } + } + + func testSKPaymentDiscountFromMapMissingNonce() { + if #available(iOS 12.2, *) { + let invalidValues: [Any?] = [NSNull(), 1, ""] + for value in invalidValues { + let discountMap: [String: Any?] = [ + "identifier": "payment_discount_identifier", + "keyIdentifier": "payment_discount_key_identifier", + "nonce": value, + "signature": "this is an encrypted signature", + "timestamp": Int(Date().timeIntervalSince1970), + ] + var error: NSString? + let _ = FIAObjectTranslator.getSKPaymentDiscount( + fromMap: discountMap as [String: Any], withError: &error) + + XCTAssertNotNil(error) + XCTAssertEqual(error, "When specifying a payment discount the 'nonce' field is mandatory.") + } + } + } + + func testSKPaymentDiscountFromMapMissingSignature() { + if #available(iOS 12.2, *) { + let invalidValues: [Any?] = [NSNull(), 1, ""] + for value in invalidValues { + let discountMap: [String: Any?] = [ + "identifier": "payment_discount_identifier", + "keyIdentifier": "payment_discount_key_identifier", + "nonce": "d18981e0-9003-4365-98a2-4b90e3b62c52", + "signature": value, + "timestamp": Int(Date().timeIntervalSince1970), + ] + var error: NSString? + let _ = FIAObjectTranslator.getSKPaymentDiscount( + fromMap: discountMap as [String: Any], withError: &error) + + XCTAssertNotNil(error) + XCTAssertEqual( + error, "When specifying a payment discount the 'signature' field is mandatory.") + } + } + } + + func testSKPaymentDiscountFromMapMissingTimestamp() { + if #available(iOS 12.2, *) { + let invalidValues: [Any?] = [NSNull(), "", -1] + for value in invalidValues { + let discountMap: [String: Any?] = [ + "identifier": "payment_discount_identifier", + "keyIdentifier": "payment_discount_key_identifier", + "nonce": "d18981e0-9003-4365-98a2-4b90e3b62c52", + "signature": "this is an encrypted signature", + "timestamp": value, + ] + var error: NSString? + let _ = FIAObjectTranslator.getSKPaymentDiscount( + fromMap: discountMap as [String: Any], withError: &error) + + XCTAssertNotNil(error) + XCTAssertEqual( + error, "When specifying a payment discount the 'timestamp' field is mandatory.") + } + } + } + + func testSKPaymentDiscountFromMapOverflowingTimestamp() throws { + if #available(iOS 12.2, *) { + let discountMap: [String: Any] = [ + "identifier": "payment_discount_identifier", + "keyIdentifier": "payment_discount_key_identifier", + "nonce": "d18981e0-9003-4365-98a2-4b90e3b62c52", + "signature": "this is an encrypted signature", + "timestamp": 1_665_044_583_595, // timestamp 2022 Oct + ] + var error: NSString? + let paymentDiscount = FIAObjectTranslator.getSKPaymentDiscount( + fromMap: discountMap, withError: &error) + XCTAssertNil(error) + + let unwrappedPaymentDiscount = try XCTUnwrap(paymentDiscount) + let identifier = try XCTUnwrap(discountMap["identifier"] as? String) + XCTAssertEqual(unwrappedPaymentDiscount.identifier, identifier) + + let keyIdentifier = try XCTUnwrap(discountMap["keyIdentifier"] as? String) + XCTAssertEqual(unwrappedPaymentDiscount.keyIdentifier, keyIdentifier) + + let nonceString = try XCTUnwrap(discountMap["nonce"] as? String) + let nonce = try XCTUnwrap(UUID(uuidString: nonceString)) + XCTAssertEqual(unwrappedPaymentDiscount.nonce, nonce) + + let signature = try XCTUnwrap(discountMap["signature"] as? String) + XCTAssertEqual(unwrappedPaymentDiscount.signature, signature) + + let timestamp = try XCTUnwrap(discountMap["timestamp"] as? Int) + XCTAssertEqual(unwrappedPaymentDiscount.timestamp as? Int, timestamp) + } + } + + func testSKPaymentDiscountConvertToPigeon() throws { + if #available(iOS 12.2, *) { + var error: NSString? + let paymentDiscount = try XCTUnwrap( + FIAObjectTranslator.getSKPaymentDiscount( + fromMap: paymentDiscountMap, withError: &error)) + let paymentDiscountPigeon = try XCTUnwrap( + FIAObjectTranslator.convertPaymentDiscount( + toPigeon: paymentDiscount)) + + XCTAssertNotNil(paymentDiscountPigeon) + XCTAssertEqual(paymentDiscount.identifier, paymentDiscountPigeon.identifier) + XCTAssertEqual(paymentDiscount.keyIdentifier, paymentDiscount.keyIdentifier) + XCTAssertEqual(paymentDiscount.nonce, UUID(uuidString: paymentDiscountPigeon.nonce)) + XCTAssertEqual(paymentDiscount.signature, paymentDiscountPigeon.signature) + + let paymentDiscountTimestamp = paymentDiscount.timestamp as? Int + let paymentDiscountPigeonTimestamp = paymentDiscountPigeon.timestamp + + XCTAssertEqual(paymentDiscountTimestamp, paymentDiscountPigeonTimestamp) + } + } + + func testSKErrorConvertToPigeon() throws { + let error = NSError(domain: SKErrorDomain, code: 3, userInfo: ["key": 42]) + let msg = FIASKErrorMessage.make( + withCode: 3, domain: SKErrorDomain, userInfo: ["key": 42] as [String: Any]) + let skerror = try XCTUnwrap(FIAObjectTranslator.convertSKError(toPigeon: error)) + + XCTAssertEqual(skerror.domain, msg.domain) + XCTAssertEqual(skerror.code, msg.code) + + let skerrorUserInfo = skerror.userInfo + let msgUserInfo = try XCTUnwrap(msg.userInfo) + + XCTAssertEqual(skerrorUserInfo as NSDictionary?, msgUserInfo as NSDictionary) + } + + func testSKPaymentConvertToPigeon() throws { + if #available(iOS 12.2, *) { + let payment = FIAObjectTranslator.getSKMutablePayment(fromMap: paymentMap) + let msg = try XCTUnwrap(FIAObjectTranslator.convertPayment(toPigeon: payment)) + let msgRequestData = try XCTUnwrap(msg.requestData) + + XCTAssertEqual(payment.productIdentifier, msg.productIdentifier) + XCTAssertEqual(payment.requestData, msgRequestData.data(using: .utf8)) + XCTAssertEqual(payment.quantity, msg.quantity) + XCTAssertEqual(payment.applicationUsername, msg.applicationUsername) + XCTAssertEqual(payment.simulatesAskToBuyInSandbox, msg.simulatesAskToBuyInSandbox) + } + } + + func testSKPaymentTransactionConvertToPigeon() throws { + let paymentTransaction = SKPaymentTransactionStub(map: transactionMap) + let msg = FIAObjectTranslator.convertTransaction(toPigeon: paymentTransaction) + + let unwrappedMsg = try XCTUnwrap(msg) + let unwrappedTimeStamp = try XCTUnwrap(unwrappedMsg.transactionTimeStamp) + + XCTAssertEqual(unwrappedMsg.transactionState, FIASKPaymentTransactionStateMessage.purchasing) + XCTAssertEqual( + paymentTransaction.transactionDate, + Date(timeIntervalSince1970: TimeInterval(truncating: unwrappedTimeStamp))) + XCTAssertEqual(paymentTransaction.transactionIdentifier, unwrappedMsg.transactionIdentifier) + } + + func testSKProductResponseCovertToPigeon() throws { + let response = SKProductsResponseStub(map: productResponseMap) + let responseMsg = FIAObjectTranslator.convertProductsResponse(toPigeon: response) + let unwrappedMsg = try XCTUnwrap(responseMsg) + + let products = try XCTUnwrap(unwrappedMsg.products) + XCTAssertEqual(products.count, 1) + + let invalidProductIdentifiers = try XCTUnwrap(unwrappedMsg.invalidProductIdentifiers) + XCTAssertTrue(invalidProductIdentifiers.isEmpty) + + let productMsg = try XCTUnwrap(unwrappedMsg.products?.first) + XCTAssertEqual(productMsg.productIdentifier, "123") + XCTAssertEqual(productMsg.localizedTitle, "title") + XCTAssertEqual(productMsg.localizedDescription, "des") + XCTAssertEqual(productMsg.subscriptionGroupIdentifier, "com.group") + + let localeMsg = try XCTUnwrap(productMsg.priceLocale) + XCTAssertEqual(localeMsg.countryCode, "") + XCTAssertEqual(localeMsg.currencyCode, "") + XCTAssertEqual(localeMsg.currencySymbol, "\u{00a4}") + + let subPeriod = try XCTUnwrap(productMsg.subscriptionPeriod) + XCTAssertEqual(subPeriod.unit, FIASKSubscriptionPeriodUnitMessage.day) + XCTAssertEqual(subPeriod.numberOfUnits, 0) + + let introDiscount = try XCTUnwrap(productMsg.introductoryPrice) + XCTAssertEqual(introDiscount.price, "1") + XCTAssertEqual(introDiscount.numberOfPeriods, 1) + XCTAssertEqual(introDiscount.paymentMode, FIASKProductDiscountPaymentModeMessage.payUpFront) + + let discounts = try XCTUnwrap(productMsg.discounts) + XCTAssertEqual(discounts.count, 1) + } +} diff --git a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/in_app_purchase_storekit_platform.dart b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/in_app_purchase_storekit_platform.dart index 713a8c909e69..e74b46ddfc2f 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/in_app_purchase_storekit_platform.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/in_app_purchase_storekit_platform.dart @@ -9,6 +9,7 @@ import 'package:flutter/services.dart'; import 'package:in_app_purchase_platform_interface/in_app_purchase_platform_interface.dart'; import '../in_app_purchase_storekit.dart'; +import '../store_kit_2_wrappers.dart'; import '../store_kit_wrappers.dart'; /// [IAPError.code] code for failed purchases. @@ -29,16 +30,29 @@ class InAppPurchaseStoreKitPlatform extends InAppPurchasePlatform { @visibleForTesting InAppPurchaseStoreKitPlatform(); + /// Experimental flag for StoreKit2. + static bool _useStoreKit2 = false; + + /// StoreKit1 static late SKPaymentQueueWrapper _skPaymentQueueWrapper; - static late _TransactionObserver _observer; + static late _TransactionObserver _sk1transactionObserver; + + /// StoreKit2 + static late SK2TransactionObserverWrapper _sk2transactionObserver; @override - Stream> get purchaseStream => - _observer.purchaseUpdatedController.stream; + Stream> get purchaseStream => _useStoreKit2 + ? _sk2transactionObserver.transactionsCreatedController.stream + : _sk1transactionObserver.purchaseUpdatedController.stream; /// Callback handler for transaction status changes. @visibleForTesting - static SKTransactionObserverWrapper get observer => _observer; + static SKTransactionObserverWrapper get observer => _sk1transactionObserver; + + /// Callback handler for transaction status changes for StoreKit2 transactions + @visibleForTesting + static SK2TransactionObserverWrapper get sk2TransactionObserver => + _sk2transactionObserver; /// Registers this class as the default instance of [InAppPurchasePlatform]. static void registerPlatform() { @@ -53,22 +67,49 @@ class InAppPurchaseStoreKitPlatform extends InAppPurchasePlatform { _skPaymentQueueWrapper = SKPaymentQueueWrapper(); - // Create a purchaseUpdatedController and notify the native side when to - // start of stop sending updates. - final StreamController> updateController = - StreamController>.broadcast( - onListen: () => _skPaymentQueueWrapper.startObservingTransactionQueue(), - onCancel: () => _skPaymentQueueWrapper.stopObservingTransactionQueue(), - ); - _observer = _TransactionObserver(updateController); - _skPaymentQueueWrapper.setTransactionObserver(observer); + if (_useStoreKit2) { + final StreamController> updateController2 = + StreamController>.broadcast( + onListen: () => SK2Transaction.startListeningToTransactions(), + onCancel: () => SK2Transaction.stopListeningToTransactions(), + ); + _sk2transactionObserver = SK2TransactionObserverWrapper( + transactionsCreatedController: updateController2); + InAppPurchase2CallbackAPI.setUp(_sk2transactionObserver); + } else { + // Create a purchaseUpdatedController and notify the native side when to + // start of stop sending updates. + final StreamController> updateController = + StreamController>.broadcast( + onListen: () => _skPaymentQueueWrapper.startObservingTransactionQueue(), + onCancel: () => _skPaymentQueueWrapper.stopObservingTransactionQueue(), + ); + _sk1transactionObserver = _TransactionObserver(updateController); + _skPaymentQueueWrapper.setTransactionObserver(observer); + } } @override - Future isAvailable() => SKPaymentQueueWrapper.canMakePayments(); + Future isAvailable() { + if (_useStoreKit2) { + return AppStore().canMakePayments(); + } + return SKPaymentQueueWrapper.canMakePayments(); + } @override Future buyNonConsumable({required PurchaseParam purchaseParam}) async { + if (_useStoreKit2) { + final SK2ProductPurchaseOptions options = SK2ProductPurchaseOptions( + quantity: purchaseParam is AppStorePurchaseParam + ? purchaseParam.quantity + : 1, + appAccountToken: purchaseParam.applicationUserName); + await SK2Product.purchase(purchaseParam.productDetails.id, + options: options); + + return true; + } await _skPaymentQueueWrapper.addPayment(SKPaymentWrapper( productIdentifier: purchaseParam.productDetails.id, quantity: @@ -93,10 +134,14 @@ class InAppPurchaseStoreKitPlatform extends InAppPurchasePlatform { @override Future completePurchase(PurchaseDetails purchase) { assert( - purchase is AppStorePurchaseDetails, + purchase is AppStorePurchaseDetails || purchase is SK2PurchaseDetails, 'On iOS, the `purchase` should always be of type `AppStorePurchaseDetails`.', ); + if (_useStoreKit2) { + return SK2Transaction.finish(int.parse(purchase.purchaseID!)); + } + return _skPaymentQueueWrapper.finishTransaction( (purchase as AppStorePurchaseDetails).skPaymentTransaction, ); @@ -104,11 +149,15 @@ class InAppPurchaseStoreKitPlatform extends InAppPurchasePlatform { @override Future restorePurchases({String? applicationUserName}) async { - return _observer + if (_useStoreKit2) { + return SK2Transaction.restorePurchases(); + } + return _sk1transactionObserver .restoreTransactions( queue: _skPaymentQueueWrapper, applicationUserName: applicationUserName) - .whenComplete(() => _observer.cleanUpRestoredTransactions()); + .whenComplete( + () => _sk1transactionObserver.cleanUpRestoredTransactions()); } /// Query the product detail list. @@ -119,6 +168,38 @@ class InAppPurchaseStoreKitPlatform extends InAppPurchasePlatform { @override Future queryProductDetails( Set identifiers) async { + if (_useStoreKit2) { + List products = []; + Set invalidProductIdentifiers; + PlatformException? exception; + try { + products = await SK2Product.products(identifiers.toList()); + // Storekit 2 no longer automatically returns a list of invalid identifiers, + // so get the difference between given identifiers and returned products + invalidProductIdentifiers = identifiers.difference( + products.map((SK2Product product) => product.id).toSet()); + } on PlatformException catch (e) { + exception = e; + invalidProductIdentifiers = identifiers; + } + List productDetails; + productDetails = products + .map((SK2Product productWrapper) => + AppStoreProduct2Details.fromSK2Product(productWrapper)) + .toList(); + final ProductDetailsResponse response = ProductDetailsResponse( + productDetails: productDetails, + notFoundIDs: invalidProductIdentifiers.toList(), + error: exception == null + ? null + : IAPError( + source: kIAPSource, + code: exception.code, + message: exception.message ?? '', + details: exception.details), + ); + return response; + } final SKRequestMaker requestMaker = SKRequestMaker(); SkProductResponseWrapper response; PlatformException? exception; @@ -166,6 +247,11 @@ class InAppPurchaseStoreKitPlatform extends InAppPurchasePlatform { /// Use countryCode instead. @Deprecated('Use countryCode') Future getCountryCode() => countryCode(); + + /// Turns on StoreKit2. You cannot disable this after it is enabled. + void enableStoreKit2() { + _useStoreKit2 = true; + } } enum _TransactionRestoreState { diff --git a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/messages.g.dart b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/messages.g.dart index e136e05b5d1e..8679df86f749 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/messages.g.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/messages.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.4.2), 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 @@ -119,29 +119,24 @@ class SKPaymentTransactionMessage { Object encode() { return [ - payment.encode(), - transactionState.index, - originalTransaction?.encode(), + payment, + transactionState, + originalTransaction, transactionTimeStamp, transactionIdentifier, - error?.encode(), + error, ]; } static SKPaymentTransactionMessage decode(Object result) { result as List; return SKPaymentTransactionMessage( - payment: SKPaymentMessage.decode(result[0]! as List), - transactionState: - SKPaymentTransactionStateMessage.values[result[1]! as int], - originalTransaction: result[2] != null - ? SKPaymentTransactionMessage.decode(result[2]! as List) - : null, + payment: result[0]! as SKPaymentMessage, + transactionState: result[1]! as SKPaymentTransactionStateMessage, + originalTransaction: result[2] as SKPaymentTransactionMessage?, transactionTimeStamp: result[3] as double?, transactionIdentifier: result[4] as String?, - error: result[5] != null - ? SKErrorMessage.decode(result[5]! as List) - : null, + error: result[5] as SKErrorMessage?, ); } } @@ -175,7 +170,7 @@ class SKPaymentMessage { requestData, quantity, simulatesAskToBuyInSandbox, - paymentDiscount?.encode(), + paymentDiscount, ]; } @@ -187,9 +182,7 @@ class SKPaymentMessage { requestData: result[2] as String?, quantity: result[3]! as int, simulatesAskToBuyInSandbox: result[4]! as bool, - paymentDiscount: result[5] != null - ? SKPaymentDiscountMessage.decode(result[5]! as List) - : null, + paymentDiscount: result[5] as SKPaymentDiscountMessage?, ); } } @@ -205,7 +198,7 @@ class SKErrorMessage { String domain; - Map? userInfo; + Map? userInfo; Object encode() { return [ @@ -220,7 +213,7 @@ class SKErrorMessage { return SKErrorMessage( code: result[0]! as int, domain: result[1]! as String, - userInfo: (result[2] as Map?)?.cast(), + userInfo: (result[2] as Map?)?.cast(), ); } } @@ -298,9 +291,9 @@ class SKProductsResponseMessage { this.invalidProductIdentifiers, }); - List? products; + List? products; - List? invalidProductIdentifiers; + List? invalidProductIdentifiers; Object encode() { return [ @@ -312,8 +305,8 @@ class SKProductsResponseMessage { static SKProductsResponseMessage decode(Object result) { result as List; return SKProductsResponseMessage( - products: (result[0] as List?)?.cast(), - invalidProductIdentifiers: (result[1] as List?)?.cast(), + products: (result[0] as List?)?.cast(), + invalidProductIdentifiers: (result[1] as List?)?.cast(), ); } } @@ -322,7 +315,7 @@ class SKProductMessage { SKProductMessage({ required this.productIdentifier, required this.localizedTitle, - required this.localizedDescription, + this.localizedDescription, required this.priceLocale, this.subscriptionGroupIdentifier, required this.price, @@ -335,7 +328,7 @@ class SKProductMessage { String localizedTitle; - String localizedDescription; + String? localizedDescription; SKPriceLocaleMessage priceLocale; @@ -347,18 +340,18 @@ class SKProductMessage { SKProductDiscountMessage? introductoryPrice; - List? discounts; + List? discounts; Object encode() { return [ productIdentifier, localizedTitle, localizedDescription, - priceLocale.encode(), + priceLocale, subscriptionGroupIdentifier, price, - subscriptionPeriod?.encode(), - introductoryPrice?.encode(), + subscriptionPeriod, + introductoryPrice, discounts, ]; } @@ -368,19 +361,14 @@ class SKProductMessage { return SKProductMessage( productIdentifier: result[0]! as String, localizedTitle: result[1]! as String, - localizedDescription: result[2]! as String, - priceLocale: SKPriceLocaleMessage.decode(result[3]! as List), + localizedDescription: result[2] as String?, + priceLocale: result[3]! as SKPriceLocaleMessage, subscriptionGroupIdentifier: result[4] as String?, price: result[5]! as String, - subscriptionPeriod: result[6] != null - ? SKProductSubscriptionPeriodMessage.decode( - result[6]! as List) - : null, - introductoryPrice: result[7] != null - ? SKProductDiscountMessage.decode(result[7]! as List) - : null, + subscriptionPeriod: result[6] as SKProductSubscriptionPeriodMessage?, + introductoryPrice: result[7] as SKProductDiscountMessage?, discounts: - (result[8] as List?)?.cast(), + (result[8] as List?)?.cast(), ); } } @@ -447,12 +435,12 @@ class SKProductDiscountMessage { Object encode() { return [ price, - priceLocale.encode(), + priceLocale, numberOfPeriods, - paymentMode.index, - subscriptionPeriod.encode(), + paymentMode, + subscriptionPeriod, identifier, - type.index, + type, ]; } @@ -460,14 +448,12 @@ class SKProductDiscountMessage { result as List; return SKProductDiscountMessage( price: result[0]! as String, - priceLocale: SKPriceLocaleMessage.decode(result[1]! as List), + priceLocale: result[1]! as SKPriceLocaleMessage, numberOfPeriods: result[2]! as int, - paymentMode: - SKProductDiscountPaymentModeMessage.values[result[3]! as int], - subscriptionPeriod: SKProductSubscriptionPeriodMessage.decode( - result[4]! as List), + paymentMode: result[3]! as SKProductDiscountPaymentModeMessage, + subscriptionPeriod: result[4]! as SKProductSubscriptionPeriodMessage, identifier: result[5] as String?, - type: SKProductDiscountTypeMessage.values[result[6]! as int], + type: result[6]! as SKProductDiscountTypeMessage, ); } } @@ -485,7 +471,7 @@ class SKProductSubscriptionPeriodMessage { Object encode() { return [ numberOfUnits, - unit.index, + unit, ]; } @@ -493,45 +479,60 @@ class SKProductSubscriptionPeriodMessage { result as List; return SKProductSubscriptionPeriodMessage( numberOfUnits: result[0]! as int, - unit: SKSubscriptionPeriodUnitMessage.values[result[1]! as int], + unit: result[1]! as SKSubscriptionPeriodUnitMessage, ); } } -class _InAppPurchaseAPICodec extends StandardMessageCodec { - const _InAppPurchaseAPICodec(); +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is SKErrorMessage) { - buffer.putUint8(128); - writeValue(buffer, value.encode()); - } else if (value is SKPaymentDiscountMessage) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is SKPaymentTransactionStateMessage) { buffer.putUint8(129); - writeValue(buffer, value.encode()); - } else if (value is SKPaymentMessage) { + writeValue(buffer, value.index); + } else if (value is SKProductDiscountTypeMessage) { buffer.putUint8(130); - writeValue(buffer, value.encode()); - } else if (value is SKPaymentTransactionMessage) { + writeValue(buffer, value.index); + } else if (value is SKProductDiscountPaymentModeMessage) { buffer.putUint8(131); - writeValue(buffer, value.encode()); - } else if (value is SKPriceLocaleMessage) { + writeValue(buffer, value.index); + } else if (value is SKSubscriptionPeriodUnitMessage) { buffer.putUint8(132); - writeValue(buffer, value.encode()); - } else if (value is SKProductDiscountMessage) { + writeValue(buffer, value.index); + } else if (value is SKPaymentTransactionMessage) { buffer.putUint8(133); writeValue(buffer, value.encode()); - } else if (value is SKProductMessage) { + } else if (value is SKPaymentMessage) { buffer.putUint8(134); writeValue(buffer, value.encode()); - } else if (value is SKProductSubscriptionPeriodMessage) { + } else if (value is SKErrorMessage) { buffer.putUint8(135); writeValue(buffer, value.encode()); - } else if (value is SKProductsResponseMessage) { + } else if (value is SKPaymentDiscountMessage) { buffer.putUint8(136); writeValue(buffer, value.encode()); } else if (value is SKStorefrontMessage) { buffer.putUint8(137); writeValue(buffer, value.encode()); + } else if (value is SKProductsResponseMessage) { + buffer.putUint8(138); + writeValue(buffer, value.encode()); + } else if (value is SKProductMessage) { + buffer.putUint8(139); + writeValue(buffer, value.encode()); + } else if (value is SKPriceLocaleMessage) { + buffer.putUint8(140); + writeValue(buffer, value.encode()); + } else if (value is SKProductDiscountMessage) { + buffer.putUint8(141); + writeValue(buffer, value.encode()); + } else if (value is SKProductSubscriptionPeriodMessage) { + buffer.putUint8(142); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -540,26 +541,46 @@ class _InAppPurchaseAPICodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: - return SKErrorMessage.decode(readValue(buffer)!); case 129: - return SKPaymentDiscountMessage.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null + ? null + : SKPaymentTransactionStateMessage.values[value]; case 130: - return SKPaymentMessage.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null + ? null + : SKProductDiscountTypeMessage.values[value]; case 131: - return SKPaymentTransactionMessage.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null + ? null + : SKProductDiscountPaymentModeMessage.values[value]; case 132: - return SKPriceLocaleMessage.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null + ? null + : SKSubscriptionPeriodUnitMessage.values[value]; case 133: - return SKProductDiscountMessage.decode(readValue(buffer)!); + return SKPaymentTransactionMessage.decode(readValue(buffer)!); case 134: - return SKProductMessage.decode(readValue(buffer)!); + return SKPaymentMessage.decode(readValue(buffer)!); case 135: - return SKProductSubscriptionPeriodMessage.decode(readValue(buffer)!); + return SKErrorMessage.decode(readValue(buffer)!); case 136: - return SKProductsResponseMessage.decode(readValue(buffer)!); + return SKPaymentDiscountMessage.decode(readValue(buffer)!); case 137: return SKStorefrontMessage.decode(readValue(buffer)!); + case 138: + return SKProductsResponseMessage.decode(readValue(buffer)!); + case 139: + return SKProductMessage.decode(readValue(buffer)!); + case 140: + return SKPriceLocaleMessage.decode(readValue(buffer)!); + case 141: + return SKProductDiscountMessage.decode(readValue(buffer)!); + case 142: + return SKProductSubscriptionPeriodMessage.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -570,120 +591,124 @@ class InAppPurchaseAPI { /// Constructor for [InAppPurchaseAPI]. 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. - InAppPurchaseAPI({BinaryMessenger? binaryMessenger}) - : __pigeon_binaryMessenger = binaryMessenger; - final BinaryMessenger? __pigeon_binaryMessenger; + InAppPurchaseAPI( + {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 = - _InAppPurchaseAPICodec(); + final String pigeonVar_messageChannelSuffix; /// Returns if the current device is able to make payments Future canMakePayments() async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.canMakePayments'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.canMakePayments$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } - Future> transactions() async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.transactions'; - final BasicMessageChannel __pigeon_channel = + Future> transactions() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.transactions$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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(); } } Future storefront() async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.storefront'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.storefront$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 SKStorefrontMessage?)!; + return (pigeonVar_replyList[0] as SKStorefrontMessage?)!; } } - Future addPayment(Map paymentMap) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.addPayment'; - final BasicMessageChannel __pigeon_channel = + Future addPayment(Map paymentMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.addPayment$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([paymentMap]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([paymentMap]) 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; @@ -691,53 +716,53 @@ class InAppPurchaseAPI { } Future startProductRequest( - List productIdentifiers) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.startProductRequest'; - final BasicMessageChannel __pigeon_channel = + List productIdentifiers) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.startProductRequest$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([productIdentifiers]) 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 SKProductsResponseMessage?)!; + return (pigeonVar_replyList[0] as SKProductsResponseMessage?)!; } } - Future finishTransaction(Map finishMap) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.finishTransaction'; - final BasicMessageChannel __pigeon_channel = + Future finishTransaction(Map finishMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.finishTransaction$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([finishMap]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([finishMap]) 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; @@ -745,23 +770,23 @@ class InAppPurchaseAPI { } Future restoreTransactions(String? applicationUserName) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.restoreTransactions'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.restoreTransactions$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([applicationUserName]) 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; @@ -769,23 +794,23 @@ class InAppPurchaseAPI { } Future presentCodeRedemptionSheet() async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.presentCodeRedemptionSheet'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.presentCodeRedemptionSheet$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; @@ -793,48 +818,47 @@ class InAppPurchaseAPI { } Future retrieveReceiptData() async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.retrieveReceiptData'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.retrieveReceiptData$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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?); } } - Future refreshReceipt( - {Map? receiptProperties}) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.refreshReceipt'; - final BasicMessageChannel __pigeon_channel = + Future refreshReceipt({Map? receiptProperties}) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.refreshReceipt$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([receiptProperties]) 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; @@ -842,23 +866,23 @@ class InAppPurchaseAPI { } Future startObservingPaymentQueue() async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.startObservingPaymentQueue'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.startObservingPaymentQueue$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; @@ -866,23 +890,23 @@ class InAppPurchaseAPI { } Future stopObservingPaymentQueue() async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.stopObservingPaymentQueue'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.stopObservingPaymentQueue$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; @@ -890,23 +914,23 @@ class InAppPurchaseAPI { } Future registerPaymentQueueDelegate() async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.registerPaymentQueueDelegate'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.registerPaymentQueueDelegate$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; @@ -914,23 +938,23 @@ class InAppPurchaseAPI { } Future removePaymentQueueDelegate() async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.removePaymentQueueDelegate'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.removePaymentQueueDelegate$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; @@ -938,23 +962,23 @@ class InAppPurchaseAPI { } Future showPriceConsentIfNeeded() async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.showPriceConsentIfNeeded'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.showPriceConsentIfNeeded$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; diff --git a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/sk2_pigeon.g.dart b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/sk2_pigeon.g.dart new file mode 100644 index 000000000000..ac154ddce079 --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/sk2_pigeon.g.dart @@ -0,0 +1,762 @@ +// 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 (v22.6.0), 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 + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; + +import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/services.dart'; + +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); +} + +List wrapResponse( + {Object? result, PlatformException? error, bool empty = false}) { + if (empty) { + return []; + } + if (error == null) { + return [result]; + } + return [error.code, error.message, error.details]; +} + +enum SK2ProductTypeMessage { + /// A consumable in-app purchase. + consumable, + + /// A non-consumable in-app purchase. + nonConsumable, + + /// A non-renewing subscription. + nonRenewable, + + /// An auto-renewable subscription. + autoRenewable, +} + +enum SK2SubscriptionOfferTypeMessage { + introductory, + promotional, +} + +enum SK2SubscriptionOfferPaymentModeMessage { + payAsYouGo, + payUpFront, + freeTrial, +} + +enum SK2SubscriptionPeriodUnitMessage { + day, + week, + month, + year, +} + +enum SK2ProductPurchaseResultMessage { + success, + userCancelled, + pending, +} + +class SK2SubscriptionOfferMessage { + SK2SubscriptionOfferMessage({ + this.id, + required this.price, + required this.type, + required this.period, + required this.periodCount, + required this.paymentMode, + }); + + String? id; + + double price; + + SK2SubscriptionOfferTypeMessage type; + + SK2SubscriptionPeriodMessage period; + + int periodCount; + + SK2SubscriptionOfferPaymentModeMessage paymentMode; + + Object encode() { + return [ + id, + price, + type, + period, + periodCount, + paymentMode, + ]; + } + + static SK2SubscriptionOfferMessage decode(Object result) { + result as List; + return SK2SubscriptionOfferMessage( + id: result[0] as String?, + price: result[1]! as double, + type: result[2]! as SK2SubscriptionOfferTypeMessage, + period: result[3]! as SK2SubscriptionPeriodMessage, + periodCount: result[4]! as int, + paymentMode: result[5]! as SK2SubscriptionOfferPaymentModeMessage, + ); + } +} + +class SK2SubscriptionPeriodMessage { + SK2SubscriptionPeriodMessage({ + required this.value, + required this.unit, + }); + + /// The number of units that the period represents. + int value; + + /// The unit of time that this period represents. + SK2SubscriptionPeriodUnitMessage unit; + + Object encode() { + return [ + value, + unit, + ]; + } + + static SK2SubscriptionPeriodMessage decode(Object result) { + result as List; + return SK2SubscriptionPeriodMessage( + value: result[0]! as int, + unit: result[1]! as SK2SubscriptionPeriodUnitMessage, + ); + } +} + +class SK2SubscriptionInfoMessage { + SK2SubscriptionInfoMessage({ + required this.promotionalOffers, + required this.subscriptionGroupID, + required this.subscriptionPeriod, + }); + + /// An array of all the promotional offers configured for this subscription. + List promotionalOffers; + + /// The group identifier for this subscription. + String subscriptionGroupID; + + /// The duration that this subscription lasts before auto-renewing. + SK2SubscriptionPeriodMessage subscriptionPeriod; + + Object encode() { + return [ + promotionalOffers, + subscriptionGroupID, + subscriptionPeriod, + ]; + } + + static SK2SubscriptionInfoMessage decode(Object result) { + result as List; + return SK2SubscriptionInfoMessage( + promotionalOffers: + (result[0] as List?)!.cast(), + subscriptionGroupID: result[1]! as String, + subscriptionPeriod: result[2]! as SK2SubscriptionPeriodMessage, + ); + } +} + +/// A Pigeon message class representing a Product +/// https://developer.apple.com/documentation/storekit/product +class SK2ProductMessage { + SK2ProductMessage({ + required this.id, + required this.displayName, + required this.description, + required this.price, + required this.displayPrice, + required this.type, + this.subscription, + required this.priceLocale, + }); + + /// The unique product identifier. + String id; + + /// The localized display name of the product, if it exists. + String displayName; + + /// The localized description of the product. + String description; + + /// The localized string representation of the product price, suitable for display. + double price; + + /// The localized price of the product as a string. + String displayPrice; + + /// The types of in-app purchases. + SK2ProductTypeMessage type; + + /// The subscription information for an auto-renewable subscription. + SK2SubscriptionInfoMessage? subscription; + + /// The currency and locale information for this product + SK2PriceLocaleMessage priceLocale; + + Object encode() { + return [ + id, + displayName, + description, + price, + displayPrice, + type, + subscription, + priceLocale, + ]; + } + + static SK2ProductMessage decode(Object result) { + result as List; + return SK2ProductMessage( + id: result[0]! as String, + displayName: result[1]! as String, + description: result[2]! as String, + price: result[3]! as double, + displayPrice: result[4]! as String, + type: result[5]! as SK2ProductTypeMessage, + subscription: result[6] as SK2SubscriptionInfoMessage?, + priceLocale: result[7]! as SK2PriceLocaleMessage, + ); + } +} + +class SK2PriceLocaleMessage { + SK2PriceLocaleMessage({ + required this.currencyCode, + required this.currencySymbol, + }); + + String currencyCode; + + String currencySymbol; + + Object encode() { + return [ + currencyCode, + currencySymbol, + ]; + } + + static SK2PriceLocaleMessage decode(Object result) { + result as List; + return SK2PriceLocaleMessage( + currencyCode: result[0]! as String, + currencySymbol: result[1]! as String, + ); + } +} + +class SK2ProductPurchaseOptionsMessage { + SK2ProductPurchaseOptionsMessage({ + this.appAccountToken, + this.quantity = 1, + }); + + String? appAccountToken; + + int? quantity; + + Object encode() { + return [ + appAccountToken, + quantity, + ]; + } + + static SK2ProductPurchaseOptionsMessage decode(Object result) { + result as List; + return SK2ProductPurchaseOptionsMessage( + appAccountToken: result[0] as String?, + quantity: result[1] as int?, + ); + } +} + +class SK2TransactionMessage { + SK2TransactionMessage({ + required this.id, + required this.originalId, + required this.productId, + required this.purchaseDate, + this.purchasedQuantity = 1, + this.appAccountToken, + this.restoring = false, + this.receiptData, + this.error, + }); + + int id; + + int originalId; + + String productId; + + String purchaseDate; + + int purchasedQuantity; + + String? appAccountToken; + + bool restoring; + + String? receiptData; + + SK2ErrorMessage? error; + + Object encode() { + return [ + id, + originalId, + productId, + purchaseDate, + purchasedQuantity, + appAccountToken, + restoring, + receiptData, + error, + ]; + } + + static SK2TransactionMessage decode(Object result) { + result as List; + return SK2TransactionMessage( + id: result[0]! as int, + originalId: result[1]! as int, + productId: result[2]! as String, + purchaseDate: result[3]! as String, + purchasedQuantity: result[4]! as int, + appAccountToken: result[5] as String?, + restoring: result[6]! as bool, + receiptData: result[7] as String?, + error: result[8] as SK2ErrorMessage?, + ); + } +} + +class SK2ErrorMessage { + SK2ErrorMessage({ + required this.code, + required this.domain, + this.userInfo, + }); + + int code; + + String domain; + + Map? userInfo; + + Object encode() { + return [ + code, + domain, + userInfo, + ]; + } + + static SK2ErrorMessage decode(Object result) { + result as List; + return SK2ErrorMessage( + code: result[0]! as int, + domain: result[1]! as String, + userInfo: (result[2] as Map?)?.cast(), + ); + } +} + +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is SK2ProductTypeMessage) { + buffer.putUint8(129); + writeValue(buffer, value.index); + } else if (value is SK2SubscriptionOfferTypeMessage) { + buffer.putUint8(130); + writeValue(buffer, value.index); + } else if (value is SK2SubscriptionOfferPaymentModeMessage) { + buffer.putUint8(131); + writeValue(buffer, value.index); + } else if (value is SK2SubscriptionPeriodUnitMessage) { + buffer.putUint8(132); + writeValue(buffer, value.index); + } else if (value is SK2ProductPurchaseResultMessage) { + buffer.putUint8(133); + writeValue(buffer, value.index); + } else if (value is SK2SubscriptionOfferMessage) { + buffer.putUint8(134); + writeValue(buffer, value.encode()); + } else if (value is SK2SubscriptionPeriodMessage) { + buffer.putUint8(135); + writeValue(buffer, value.encode()); + } else if (value is SK2SubscriptionInfoMessage) { + buffer.putUint8(136); + writeValue(buffer, value.encode()); + } else if (value is SK2ProductMessage) { + buffer.putUint8(137); + writeValue(buffer, value.encode()); + } else if (value is SK2PriceLocaleMessage) { + buffer.putUint8(138); + writeValue(buffer, value.encode()); + } else if (value is SK2ProductPurchaseOptionsMessage) { + buffer.putUint8(139); + writeValue(buffer, value.encode()); + } else if (value is SK2TransactionMessage) { + buffer.putUint8(140); + writeValue(buffer, value.encode()); + } else if (value is SK2ErrorMessage) { + buffer.putUint8(141); + writeValue(buffer, value.encode()); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 129: + final int? value = readValue(buffer) as int?; + return value == null ? null : SK2ProductTypeMessage.values[value]; + case 130: + final int? value = readValue(buffer) as int?; + return value == null + ? null + : SK2SubscriptionOfferTypeMessage.values[value]; + case 131: + final int? value = readValue(buffer) as int?; + return value == null + ? null + : SK2SubscriptionOfferPaymentModeMessage.values[value]; + case 132: + final int? value = readValue(buffer) as int?; + return value == null + ? null + : SK2SubscriptionPeriodUnitMessage.values[value]; + case 133: + final int? value = readValue(buffer) as int?; + return value == null + ? null + : SK2ProductPurchaseResultMessage.values[value]; + case 134: + return SK2SubscriptionOfferMessage.decode(readValue(buffer)!); + case 135: + return SK2SubscriptionPeriodMessage.decode(readValue(buffer)!); + case 136: + return SK2SubscriptionInfoMessage.decode(readValue(buffer)!); + case 137: + return SK2ProductMessage.decode(readValue(buffer)!); + case 138: + return SK2PriceLocaleMessage.decode(readValue(buffer)!); + case 139: + return SK2ProductPurchaseOptionsMessage.decode(readValue(buffer)!); + case 140: + return SK2TransactionMessage.decode(readValue(buffer)!); + case 141: + return SK2ErrorMessage.decode(readValue(buffer)!); + default: + return super.readValueOfType(type, buffer); + } + } +} + +class InAppPurchase2API { + /// Constructor for [InAppPurchase2API]. 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. + InAppPurchase2API( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String pigeonVar_messageChannelSuffix; + + Future canMakePayments() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.canMakePayments$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as bool?)!; + } + } + + Future> products(List identifiers) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.products$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([identifiers]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as List?)! + .cast(); + } + } + + Future purchase(String id, + {SK2ProductPurchaseOptionsMessage? options}) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.purchase$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([id, options]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as SK2ProductPurchaseResultMessage?)!; + } + } + + Future> transactions() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.transactions$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as List?)! + .cast(); + } + } + + Future finish(int id) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.finish$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([id]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + Future startListeningToTransactions() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.startListeningToTransactions$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + Future stopListeningToTransactions() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.stopListeningToTransactions$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + Future restorePurchases() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.restorePurchases$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } +} + +abstract class InAppPurchase2CallbackAPI { + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + void onTransactionsUpdated(List newTransactions); + + static void setUp( + InAppPurchase2CallbackAPI? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2CallbackAPI.onTransactionsUpdated$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2CallbackAPI.onTransactionsUpdated was null.'); + final List args = (message as List?)!; + final List? arg_newTransactions = + (args[0] as List?)?.cast(); + assert(arg_newTransactions != null, + 'Argument for dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2CallbackAPI.onTransactionsUpdated was null, expected non-null List.'); + try { + api.onTransactionsUpdated(arg_newTransactions!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } +} diff --git a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/store_kit_2_wrappers/sk2_appstore_wrapper.dart b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/store_kit_2_wrappers/sk2_appstore_wrapper.dart new file mode 100644 index 000000000000..a57ad5611266 --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/store_kit_2_wrappers/sk2_appstore_wrapper.dart @@ -0,0 +1,18 @@ +// 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 '../../store_kit_2_wrappers.dart'; + +InAppPurchase2API _hostApi = InAppPurchase2API(); + +/// Wrapper for StoreKit2's AppStore +/// (https://developer.apple.com/documentation/storekit/appstore) +final class AppStore { + /// Dart wrapper for StoreKit2's canMakePayments() + /// Returns a bool that indicates whether the person can make purchases. + /// (https://developer.apple.com/documentation/storekit/appstore/3822277-canmakepayments) + Future canMakePayments() { + return _hostApi.canMakePayments(); + } +} diff --git a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/store_kit_2_wrappers/sk2_product_wrapper.dart b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/store_kit_2_wrappers/sk2_product_wrapper.dart new file mode 100644 index 000000000000..ad5de9c5c77a --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/store_kit_2_wrappers/sk2_product_wrapper.dart @@ -0,0 +1,407 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/services.dart'; +import '../../store_kit_2_wrappers.dart'; + +InAppPurchase2API _hostApi = InAppPurchase2API(); + +/// A wrapper around StoreKit2's ProductType +/// https://developer.apple.com/documentation/storekit/product/producttype +/// The types of in-app purchases. +enum SK2ProductType { + /// A consumable in-app purchase. + consumable, + + /// A non-consumable in-app purchase. + nonConsumable, + + /// A non-renewing subscription. + nonRenewable, + + /// An auto-renewable subscription. + autoRenewable; +} + +extension on SK2ProductTypeMessage { + /// Convert the equivalent pigeon class of [SK2ProductTypeMessage] into an instance of [SK2ProductType] + SK2ProductType convertFromPigeon() { + switch (this) { + case SK2ProductTypeMessage.autoRenewable: + return SK2ProductType.autoRenewable; + case SK2ProductTypeMessage.consumable: + return SK2ProductType.consumable; + case SK2ProductTypeMessage.nonConsumable: + return SK2ProductType.nonConsumable; + case SK2ProductTypeMessage.nonRenewable: + return SK2ProductType.nonRenewable; + } + } +} + +extension on SK2ProductType { + SK2ProductTypeMessage convertToPigeon() { + switch (this) { + case SK2ProductType.autoRenewable: + return SK2ProductTypeMessage.autoRenewable; + case SK2ProductType.consumable: + return SK2ProductTypeMessage.consumable; + case SK2ProductType.nonConsumable: + return SK2ProductTypeMessage.nonConsumable; + case SK2ProductType.nonRenewable: + return SK2ProductTypeMessage.nonRenewable; + } + } +} + +/// A wrapper around StoreKit2's SubscriptionOfferType +/// https://developer.apple.com/documentation/appstoreserverapi/offertype/ +/// The subscription offer types. +enum SK2SubscriptionOfferType { + /// An introductory offer. + introductory, + + /// A A promotional offer. + promotional +} + +extension on SK2SubscriptionOfferTypeMessage { + SK2SubscriptionOfferType convertFromPigeon() { + switch (this) { + case SK2SubscriptionOfferTypeMessage.introductory: + return SK2SubscriptionOfferType.introductory; + case SK2SubscriptionOfferTypeMessage.promotional: + return SK2SubscriptionOfferType.promotional; + } + } +} + +/// A wrapper around StoreKit2's SubscriptionOffer +/// https://developer.apple.com/documentation/storekit/product/subscriptionoffer +/// Information about a subscription offer on a product. +class SK2SubscriptionOffer { + /// Creates a new [SK2SubscriptionOffer] + SK2SubscriptionOffer({ + this.id, + required this.price, + required this.type, + required this.period, + required this.periodCount, + required this.paymentMode, + }); + + /// The subscription offer identifier. + final String? id; + + /// The decimal representation of the discounted price of the subscription offer. + final double price; + + /// The type of subscription offer, either introductory or promotional. + final SK2SubscriptionOfferType type; + + /// The subscription period for the subscription offer. + final SK2SubscriptionPeriod period; + + /// The number of periods that the subscription offer renews for. + final int periodCount; + + /// The payment modes for subscription offers that apply to a transaction. + final SK2SubscriptionOfferPaymentMode paymentMode; +} + +extension on SK2SubscriptionOfferMessage { + SK2SubscriptionOffer convertFromPigeon() { + return SK2SubscriptionOffer( + id: id, + price: price, + type: type.convertFromPigeon(), + period: period.convertFromPigeon(), + periodCount: periodCount, + paymentMode: paymentMode.convertFromPigeon()); + } +} + +/// A wrapper around StoreKit2's SubscriptionInfo +/// https://developer.apple.com/documentation/storekit/product/subscriptioninfo +/// Information about an auto-renewable subscription, +/// such as its status, period, subscription group, and subscription offer details. +class SK2SubscriptionInfo { + /// Creates a new instance of [SK2SubscriptionInfo] + const SK2SubscriptionInfo({ + required this.subscriptionGroupID, + required this.promotionalOffers, + required this.subscriptionPeriod, + }); + + /// An array of all the promotional offers configured for this subscription. + final List promotionalOffers; + + /// The group identifier for this subscription. + final String subscriptionGroupID; + + /// The duration that this subscription lasts before auto-renewing. + final SK2SubscriptionPeriod subscriptionPeriod; +} + +extension on SK2SubscriptionInfoMessage { + SK2SubscriptionInfo convertFromPigeon() { + return SK2SubscriptionInfo( + subscriptionGroupID: subscriptionGroupID, + promotionalOffers: promotionalOffers + .map((SK2SubscriptionOfferMessage offer) => + offer.convertFromPigeon()) + .toList(), + subscriptionPeriod: subscriptionPeriod.convertFromPigeon()); + } +} + +/// A wrapper around StoreKit2's SubscriptionPeriod +/// https://developer.apple.com/documentation/storekit/product/subscriptionperiod +/// Values that represent the duration of time between subscription renewals. +class SK2SubscriptionPeriod { + /// Creates a new instance of [SK2SubscriptionPeriod] + const SK2SubscriptionPeriod({required this.value, required this.unit}); + + /// The number of units that the period represents. + final int value; + + /// The unit of time that this period represents. + final SK2SubscriptionPeriodUnit unit; +} + +extension on SK2SubscriptionPeriodMessage { + SK2SubscriptionPeriod convertFromPigeon() { + return SK2SubscriptionPeriod(value: value, unit: unit.convertFromPigeon()); + } +} + +/// A wrapper around StoreKit2's SubscriptionPeriodUnit +/// https://developer.apple.com/documentation/storekit/product/subscriptionperiod/3749576-unit +/// The increment of time for the subscription period. +enum SK2SubscriptionPeriodUnit { + /// A subscription period unit of a day. + day, + + /// A subscription period unit of a week. + week, + + /// A subscription period unit of a month. + month, + + /// A subscription period unit of a year. + year +} + +extension on SK2SubscriptionPeriodUnitMessage { + SK2SubscriptionPeriodUnit convertFromPigeon() { + switch (this) { + case SK2SubscriptionPeriodUnitMessage.day: + return SK2SubscriptionPeriodUnit.day; + case SK2SubscriptionPeriodUnitMessage.week: + return SK2SubscriptionPeriodUnit.week; + case SK2SubscriptionPeriodUnitMessage.month: + return SK2SubscriptionPeriodUnit.month; + case SK2SubscriptionPeriodUnitMessage.year: + return SK2SubscriptionPeriodUnit.year; + } + } +} + +/// A wrapper around StoreKit2's [PaymentMode](https://developer.apple.com/documentation/storekit/product/subscriptionoffer/paymentmode) +/// The payment modes for subscription offers that apply to a transaction. +enum SK2SubscriptionOfferPaymentMode { + /// A payment mode of a product discount that applies over a single billing period or multiple billing periods. + payAsYouGo, + + /// A payment mode of a product discount that applies the discount up front. + payUpFront, + + /// A payment mode of a product discount that indicates a free trial offer. + freeTrial; +} + +extension on SK2SubscriptionOfferPaymentModeMessage { + SK2SubscriptionOfferPaymentMode convertFromPigeon() { + switch (this) { + case SK2SubscriptionOfferPaymentModeMessage.payAsYouGo: + return SK2SubscriptionOfferPaymentMode.payAsYouGo; + case SK2SubscriptionOfferPaymentModeMessage.payUpFront: + return SK2SubscriptionOfferPaymentMode.payUpFront; + case SK2SubscriptionOfferPaymentModeMessage.freeTrial: + return SK2SubscriptionOfferPaymentMode.freeTrial; + } + } +} + +/// A wrapper around StoreKit2's [Locale](https://developer.apple.com/documentation/foundation/locale) +/// The payment modes for subscription offers that apply to a transaction. +class SK2PriceLocale { + /// Creates a new instance of [SK2PriceLocale] + SK2PriceLocale({required this.currencyCode, required this.currencySymbol}); + + /// The currency code this format style uses. + final String currencyCode; + + /// The currency symbol this format style uses. + final String currencySymbol; + + /// Convert this instance of [SK2PriceLocale] to [SK2PriceLocaleMessage] + SK2PriceLocaleMessage convertToPigeon() { + return SK2PriceLocaleMessage( + currencyCode: currencyCode, currencySymbol: currencySymbol); + } +} + +extension on SK2PriceLocaleMessage { + SK2PriceLocale convertFromPigeon() { + return SK2PriceLocale( + currencyCode: currencyCode, currencySymbol: currencySymbol); + } +} + +/// Wrapper around [PurchaseResult] +/// https://developer.apple.com/documentation/storekit/product/purchaseresult +enum SK2ProductPurchaseResult { + /// The purchase succeeded and results in a transaction. + success, + + /// The user canceled the purchase. + userCancelled, + + /// The purchase is pending, and requires action from the customer. + pending +} + +/// Wrapper around [PurchaseOption] +/// https://developer.apple.com/documentation/storekit/product/purchaseoption +class SK2ProductPurchaseOptions { + /// Creates a new instance of [SK2ProductPurchaseOptions] + SK2ProductPurchaseOptions({this.appAccountToken, this.quantity}); + + /// Sets a UUID to associate the purchase with an account in your system. + final String? appAccountToken; + + /// Indicates the quantity of items the customer is purchasing. + final int? quantity; + + /// Convert to pigeon representation [SK2ProductPurchaseOptionsMessage] + SK2ProductPurchaseOptionsMessage convertToPigeon() { + return SK2ProductPurchaseOptionsMessage( + appAccountToken: appAccountToken, quantity: quantity); + } +} + +extension on SK2ProductPurchaseResultMessage { + SK2ProductPurchaseResult convertFromPigeon() { + switch (this) { + case SK2ProductPurchaseResultMessage.success: + return SK2ProductPurchaseResult.success; + case SK2ProductPurchaseResultMessage.userCancelled: + return SK2ProductPurchaseResult.userCancelled; + case SK2ProductPurchaseResultMessage.pending: + return SK2ProductPurchaseResult.pending; + } + } +} + +/// A wrapper around StoreKit2's [Product](https://developer.apple.com/documentation/storekit/product). +/// The Product type represents the in-app purchases that you configure in +/// App Store Connect and make available for purchase within your app. +class SK2Product { + /// Creates a new [SKStorefrontWrapper] with the provided information. + SK2Product({ + required this.id, + required this.displayName, + required this.displayPrice, + required this.description, + required this.price, + required this.type, + required this.priceLocale, + this.subscription, + }); + + /// The unique product identifier. + final String id; + + /// The localized display name of the product, if it exists. + final String displayName; + + /// The localized description of the product. + final String description; + + /// The localized string representation of the product price, suitable for display. + final double price; + + /// The localized price of the product as a string. + final String displayPrice; + + /// The types of in-app purchases. + final SK2ProductType type; + + /// The subscription information for an auto-renewable subscription. + final SK2SubscriptionInfo? subscription; + + /// The locale and currency information for this product. + final SK2PriceLocale priceLocale; + + /// https://developer.apple.com/documentation/storekit/product/3851116-products + /// Given a list of identifiers, return a list of products + /// If any of the identifiers are invalid or can't be found, they are excluded + /// from the returned list. + static Future> products(List identifiers) async { + final List productsMsg = + await _hostApi.products(identifiers); + if (productsMsg.isEmpty && identifiers.isNotEmpty) { + throw PlatformException( + code: 'storekit_no_response', + message: 'StoreKit: Failed to get response from platform.', + ); + } + + return productsMsg + .whereType() + .map((SK2ProductMessage product) => product.convertFromPigeon()) + .toList(); + } + + /// Wrapper for StoreKit's [Product.purchase] + /// https://developer.apple.com/documentation/storekit/product/3791971-purchase + /// Initiates a purchase for the product with the App Store and displays the confirmation sheet. + static Future purchase(String id, + {SK2ProductPurchaseOptions? options}) async { + SK2ProductPurchaseResultMessage result; + if (options != null) { + result = await _hostApi.purchase(id, options: options.convertToPigeon()); + } else { + result = await _hostApi.purchase(id); + } + return result.convertFromPigeon(); + } + + /// Converts this instance of [SK2Product] to it's pigeon representation [SK2ProductMessage] + SK2ProductMessage convertToPigeon() { + return SK2ProductMessage( + id: id, + displayName: displayName, + description: description, + price: price, + displayPrice: displayPrice, + type: type.convertToPigeon(), + priceLocale: priceLocale.convertToPigeon()); + } +} + +extension on SK2ProductMessage { + SK2Product convertFromPigeon() { + return SK2Product( + id: id, + displayName: displayName, + displayPrice: displayPrice, + price: price, + description: description, + type: type.convertFromPigeon(), + subscription: subscription?.convertFromPigeon(), + priceLocale: priceLocale.convertFromPigeon()); + } +} diff --git a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/store_kit_2_wrappers/sk2_transaction_wrapper.dart b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/store_kit_2_wrappers/sk2_transaction_wrapper.dart new file mode 100644 index 000000000000..4e727dce333b --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/store_kit_2_wrappers/sk2_transaction_wrapper.dart @@ -0,0 +1,140 @@ +// 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:in_app_purchase_platform_interface/in_app_purchase_platform_interface.dart'; + +import '../../in_app_purchase_storekit.dart'; +import '../../store_kit_wrappers.dart'; +import '../sk2_pigeon.g.dart'; + +InAppPurchase2API _hostApi = InAppPurchase2API(); + +/// Dart wrapper around StoreKit2's [Transaction](https://developer.apple.com/documentation/storekit/transaction) +/// Note that in StoreKit2, a Transaction encompasses the data contained by +/// SKPayment and SKTransaction in StoreKit1 +class SK2Transaction { + /// Creates a new instance of [SK2Transaction] + SK2Transaction( + {required this.id, + required this.originalId, + required this.productId, + required this.purchaseDate, + this.quantity = 1, + required this.appAccountToken, + this.subscriptionGroupID, + this.price, + this.error}); + + /// The unique identifier for the transaction. + final String id; + + /// The original transaction identifier of a purchase. + /// The original transaction identifier, originalID, is identical to id except + /// when the user restores a purchase or renews a transaction. + final String originalId; + + /// The product identifier of the in-app purchase. + final String productId; + + /// The date that the App Store charged the user’s account for a purchased or + /// restored product, or for a subscription purchase or renewal after a lapse. + final String purchaseDate; + + /// The number of consumable products purchased. + final int quantity; + + /// A UUID that associates the transaction with a user on your own service. + final String? appAccountToken; + + /// The identifier of the subscription group that the subscription belongs to. + final String? subscriptionGroupID; + + /// The price of the in-app purchase that the system records in the transaction. + final double? price; + + /// Any error returned from StoreKit + final SKError? error; + + /// Wrapper around [Transaction.finish] + /// https://developer.apple.com/documentation/storekit/transaction/3749694-finish + /// Indicates to the App Store that the app delivered the purchased content + /// or enabled the service to finish the transaction. + static Future finish(int id) async { + await _hostApi.finish(id); + } + + /// A wrapper around [Transaction.all] + /// https://developer.apple.com/documentation/storekit/transaction/3851203-all + /// A sequence that emits all the customer’s transactions for your app. + static Future> transactions() async { + final List msgs = await _hostApi.transactions(); + final List transactions = + msgs.map((SK2TransactionMessage e) => e.convertFromPigeon()).toList(); + return transactions; + } + + /// Start listening to transactions. + /// Call this as soon as you can your app to avoid missing transactions. + static void startListeningToTransactions() { + _hostApi.startListeningToTransactions(); + } + + /// Stop listening to transactions. + static void stopListeningToTransactions() { + _hostApi.stopListeningToTransactions(); + } + + /// Restore previously completed purchases. + static Future restorePurchases() async { + await _hostApi.restorePurchases(); + } +} + +extension on SK2TransactionMessage { + SK2Transaction convertFromPigeon() { + return SK2Transaction( + id: id.toString(), + originalId: originalId.toString(), + productId: productId, + purchaseDate: purchaseDate, + appAccountToken: appAccountToken); + } + + PurchaseDetails convertToDetails() { + return SK2PurchaseDetails( + productID: productId, + // in SK2, as per Apple + // https://developer.apple.com/documentation/foundation/nsbundle/1407276-appstorereceipturl + // receipt isn’t necessary with SK2 as a Transaction can only be returned + // from validated purchases. + verificationData: PurchaseVerificationData( + localVerificationData: '', serverVerificationData: '', source: ''), + transactionDate: purchaseDate, + // Note that with SK2, any transactions that *can* be returned will + // require to be finished, and are already purchased. + // So set this as purchased for all transactions initially. + // Any failed transaction will simply not be returned. + status: restoring ? PurchaseStatus.restored : PurchaseStatus.purchased, + purchaseID: id.toString(), + ); + } +} + +/// An observer that listens to all transactions created +class SK2TransactionObserverWrapper implements InAppPurchase2CallbackAPI { + /// Creates a new instance of [SK2TransactionObserverWrapper] + SK2TransactionObserverWrapper({required this.transactionsCreatedController}); + + /// The transactions stream to listen to + final StreamController> transactionsCreatedController; + + @override + void onTransactionsUpdated(List newTransactions) { + transactionsCreatedController.add(newTransactions + .map((SK2TransactionMessage e) => e.convertToDetails()) + .toList()); + } +} diff --git a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart index 8f1af1c64049..138ecc8b7472 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart @@ -416,8 +416,8 @@ class SKPaymentWrapper { } /// Creates a Map object describes the payment object. - Map toMap() { - return { + Map toMap() { + return { 'productIdentifier': productIdentifier, 'applicationUsername': applicationUsername, 'requestData': requestData, diff --git a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/store_kit_wrappers/sk_product_wrapper.dart b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/store_kit_wrappers/sk_product_wrapper.dart index dfd8c3083fac..95698271c3ff 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/store_kit_wrappers/sk_product_wrapper.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/store_kit_wrappers/sk_product_wrapper.dart @@ -72,11 +72,9 @@ class SkProductResponseWrapper { SKProductsResponseMessage msg) { return SkProductResponseWrapper( products: msg.products! - .map((SKProductMessage? e) => SKProductWrapper.convertFromPigeon(e!)) + .map((SKProductMessage e) => SKProductWrapper.convertFromPigeon(e)) .toList(), - invalidProductIdentifiers: msg.invalidProductIdentifiers != null - ? msg.invalidProductIdentifiers!.cast() - : [], + invalidProductIdentifiers: msg.invalidProductIdentifiers ?? [], ); } @@ -86,10 +84,9 @@ class SkProductResponseWrapper { SkProductResponseWrapper wrapper) { return SKProductsResponseMessage( products: wrapper.products - .map((SKProductWrapper? e) => SKProductWrapper.convertToPigeon(e!)) + .map((SKProductWrapper e) => SKProductWrapper.convertToPigeon(e)) .toList(), - invalidProductIdentifiers: - wrapper.invalidProductIdentifiers.cast()); + invalidProductIdentifiers: wrapper.invalidProductIdentifiers); } } @@ -550,7 +547,7 @@ class SKProductWrapper { return SKProductWrapper( productIdentifier: msg.productIdentifier, localizedTitle: msg.localizedTitle, - localizedDescription: msg.localizedDescription, + localizedDescription: msg.localizedDescription ?? '', priceLocale: SKPriceLocaleWrapper.convertFromPigeon(msg.priceLocale), price: msg.price, subscriptionGroupIdentifier: msg.subscriptionGroupIdentifier, @@ -563,8 +560,8 @@ class SKProductWrapper { : null, discounts: msg.discounts != null ? msg.discounts! - .map((SKProductDiscountMessage? e) => - SKProductDiscountWrapper.convertFromPigeon(e!)) + .map((SKProductDiscountMessage e) => + SKProductDiscountWrapper.convertFromPigeon(e)) .toList() : []); } @@ -587,8 +584,8 @@ class SKProductWrapper { wrapper.introductoryPrice!) : null, discounts: wrapper.discounts - .map((SKProductDiscountWrapper? e) => - SKProductDiscountWrapper.convertToPigeon(e!)) + .map((SKProductDiscountWrapper e) => + SKProductDiscountWrapper.convertToPigeon(e)) .toList()); } } diff --git a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/store_kit_wrappers/sk_request_maker.dart b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/store_kit_wrappers/sk_request_maker.dart index 5a16f261cdd7..9075db9157ab 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/store_kit_wrappers/sk_request_maker.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/store_kit_wrappers/sk_request_maker.dart @@ -52,7 +52,7 @@ class SKRequestMaker { /// * isRevoked: whether the receipt has been revoked. /// * isVolumePurchase: whether the receipt is a Volume Purchase Plan receipt. Future startRefreshReceiptRequest( - {Map? receiptProperties}) { + {Map? receiptProperties}) { return _hostApi.refreshReceipt(receiptProperties: receiptProperties); } } diff --git a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/types/app_store_product_details.dart b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/types/app_store_product_details.dart index 47bcf616fa40..f0ab7257b375 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/types/app_store_product_details.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/types/app_store_product_details.dart @@ -5,6 +5,7 @@ import 'package:in_app_purchase_platform_interface/in_app_purchase_platform_interface.dart'; import '../../store_kit_wrappers.dart'; +import '../store_kit_2_wrappers/sk2_product_wrapper.dart'; /// The class represents the information of a product as registered in the Apple /// AppStore. @@ -42,3 +43,38 @@ class AppStoreProductDetails extends ProductDetails { /// this [AppStoreProductDetails] object. final SKProductWrapper skProduct; } + +/// The class represents the information of a StoreKit2 product as registered in the Apple +/// AppStore. +class AppStoreProduct2Details extends ProductDetails { + /// Creates a new AppStore specific product details object with the provided + /// details. + AppStoreProduct2Details({ + required super.id, + required super.title, + required super.description, + required super.price, + required super.rawPrice, + required super.currencyCode, + required this.sk2Product, + required super.currencySymbol, + }); + + /// Generate a [AppStoreProductDetails] object based on an iOS [SKProductWrapper] object. + factory AppStoreProduct2Details.fromSK2Product(SK2Product product) { + return AppStoreProduct2Details( + id: product.id, + title: product.displayName, + description: product.description, + price: product.priceLocale.currencySymbol + product.price.toString(), + rawPrice: product.price, + currencyCode: product.priceLocale.currencyCode, + currencySymbol: product.priceLocale.currencySymbol, + sk2Product: product, + ); + } + + /// Points back to the [SKProductWrapper] object that was used to generate + /// this [AppStoreProductDetails] object. + final SK2Product sk2Product; +} diff --git a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/types/app_store_purchase_details.dart b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/types/app_store_purchase_details.dart index 21a1e11116b7..335ff6ad2641 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/types/app_store_purchase_details.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/types/app_store_purchase_details.dart @@ -77,3 +77,18 @@ class AppStorePurchaseDetails extends PurchaseDetails { @override bool get pendingCompletePurchase => _pendingCompletePurchase; } + +/// The class represents the information of a purchase made with the Apple +/// AppStore, when using Storekit2 +class SK2PurchaseDetails extends PurchaseDetails { + /// Creates new instance of [SK2PurchaseDetails] + SK2PurchaseDetails( + {required super.productID, + required super.purchaseID, + required super.verificationData, + required super.transactionDate, + required super.status}); + + @override + bool get pendingCompletePurchase => status == PurchaseStatus.purchased; +} diff --git a/packages/in_app_purchase/in_app_purchase_storekit/lib/store_kit_2_wrappers.dart b/packages/in_app_purchase/in_app_purchase_storekit/lib/store_kit_2_wrappers.dart new file mode 100644 index 000000000000..05482180b1a1 --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/lib/store_kit_2_wrappers.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. + +export 'src/sk2_pigeon.g.dart'; +export 'src/store_kit_2_wrappers/sk2_appstore_wrapper.dart'; +export 'src/store_kit_2_wrappers/sk2_product_wrapper.dart'; +export 'src/store_kit_2_wrappers/sk2_transaction_wrapper.dart'; diff --git a/packages/in_app_purchase/in_app_purchase_storekit/pigeons/messages.dart b/packages/in_app_purchase/in_app_purchase_storekit/pigeons/messages.dart index 6351c889cc38..cd7b6b70a57a 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/pigeons/messages.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/pigeons/messages.dart @@ -9,6 +9,9 @@ import 'package:pigeon/pigeon.dart'; dartTestOut: 'test/test_api.g.dart', objcHeaderOut: 'darwin/Classes/messages.g.h', objcSourceOut: 'darwin/Classes/messages.g.m', + objcOptions: ObjcOptions( + prefix: 'FIA', + ), copyrightHeader: 'pigeons/copyright.txt', )) class SKPaymentTransactionMessage { @@ -91,7 +94,7 @@ class SKErrorMessage { final int code; final String domain; - final Map? userInfo; + final Map? userInfo; } class SKPaymentDiscountMessage { @@ -123,17 +126,17 @@ class SKStorefrontMessage { class SKProductsResponseMessage { const SKProductsResponseMessage( {required this.products, required this.invalidProductIdentifiers}); - final List? products; - final List? invalidProductIdentifiers; + final List? products; + final List? invalidProductIdentifiers; } class SKProductMessage { const SKProductMessage( {required this.productIdentifier, required this.localizedTitle, - required this.localizedDescription, required this.priceLocale, required this.price, + this.localizedDescription, this.subscriptionGroupIdentifier, this.subscriptionPeriod, this.introductoryPrice, @@ -141,13 +144,16 @@ class SKProductMessage { final String productIdentifier; final String localizedTitle; - final String localizedDescription; + // This field should be nullable to handle occasional nulls in the StoreKit + // object despite the the StoreKit header showing that it is nonnullable + // https://github.com/flutter/flutter/issues/154047 + final String? localizedDescription; final SKPriceLocaleMessage priceLocale; final String? subscriptionGroupIdentifier; final String price; final SKProductSubscriptionPeriodMessage? subscriptionPeriod; final SKProductDiscountMessage? introductoryPrice; - final List? discounts; + final List? discounts; } class SKPriceLocaleMessage { diff --git a/packages/in_app_purchase/in_app_purchase_storekit/pigeons/sk2_pigeon.dart b/packages/in_app_purchase/in_app_purchase_storekit/pigeons/sk2_pigeon.dart new file mode 100644 index 000000000000..e3aa52232684 --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/pigeons/sk2_pigeon.dart @@ -0,0 +1,202 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:pigeon/pigeon.dart'; + +@ConfigurePigeon(PigeonOptions( + dartOut: 'lib/src/sk2_pigeon.g.dart', + dartTestOut: 'test/sk2_test_api.g.dart', + swiftOut: 'darwin/Classes/StoreKit2/sk2_pigeon.g.swift', + copyrightHeader: 'pigeons/copyright.txt', +)) +enum SK2ProductTypeMessage { + /// A consumable in-app purchase. + consumable, + + /// A non-consumable in-app purchase. + nonConsumable, + + /// A non-renewing subscription. + nonRenewable, + + /// An auto-renewable subscription. + autoRenewable +} + +enum SK2SubscriptionOfferTypeMessage { introductory, promotional } + +enum SK2SubscriptionOfferPaymentModeMessage { + payAsYouGo, + payUpFront, + freeTrial, +} + +class SK2SubscriptionOfferMessage { + const SK2SubscriptionOfferMessage({ + this.id, + required this.price, + required this.type, + required this.period, + required this.periodCount, + required this.paymentMode, + }); + final String? id; + final double price; + final SK2SubscriptionOfferTypeMessage type; + final SK2SubscriptionPeriodMessage period; + final int periodCount; + final SK2SubscriptionOfferPaymentModeMessage paymentMode; +} + +enum SK2SubscriptionPeriodUnitMessage { day, week, month, year } + +class SK2SubscriptionPeriodMessage { + const SK2SubscriptionPeriodMessage({required this.value, required this.unit}); + + /// The number of units that the period represents. + final int value; + + /// The unit of time that this period represents. + final SK2SubscriptionPeriodUnitMessage unit; +} + +class SK2SubscriptionInfoMessage { + const SK2SubscriptionInfoMessage({ + required this.subscriptionGroupID, + required this.promotionalOffers, + required this.subscriptionPeriod, + }); + + /// An array of all the promotional offers configured for this subscription. + final List promotionalOffers; + + /// The group identifier for this subscription. + final String subscriptionGroupID; + + /// The duration that this subscription lasts before auto-renewing. + final SK2SubscriptionPeriodMessage subscriptionPeriod; +} + +/// A Pigeon message class representing a Product +/// https://developer.apple.com/documentation/storekit/product +class SK2ProductMessage { + const SK2ProductMessage( + {required this.id, + required this.displayName, + required this.displayPrice, + required this.description, + required this.price, + required this.type, + this.subscription, + required this.priceLocale}); + + /// The unique product identifier. + final String id; + + /// The localized display name of the product, if it exists. + final String displayName; + + /// The localized description of the product. + final String description; + + /// The localized string representation of the product price, suitable for display. + final double price; + + /// The localized price of the product as a string. + final String displayPrice; + + /// The types of in-app purchases. + final SK2ProductTypeMessage type; + + /// The subscription information for an auto-renewable subscription. + final SK2SubscriptionInfoMessage? subscription; + + /// The currency and locale information for this product + final SK2PriceLocaleMessage priceLocale; +} + +class SK2PriceLocaleMessage { + SK2PriceLocaleMessage({ + required this.currencyCode, + required this.currencySymbol, + }); + + final String currencyCode; + final String currencySymbol; +} + +class SK2ProductPurchaseOptionsMessage { + SK2ProductPurchaseOptionsMessage({ + this.appAccountToken, + this.quantity = 1, + }); + final String? appAccountToken; + final int? quantity; +} + +class SK2TransactionMessage { + SK2TransactionMessage( + {required this.id, + required this.originalId, + required this.productId, + required this.purchaseDate, + this.purchasedQuantity = 1, + this.appAccountToken, + this.error, + this.receiptData, + this.restoring = false}); + final int id; + final int originalId; + final String productId; + final String purchaseDate; + final int purchasedQuantity; + final String? appAccountToken; + final bool restoring; + final String? receiptData; + final SK2ErrorMessage? error; +} + +class SK2ErrorMessage { + const SK2ErrorMessage( + {required this.code, required this.domain, required this.userInfo}); + + final int code; + final String domain; + final Map? userInfo; +} + +enum SK2ProductPurchaseResultMessage { success, userCancelled, pending } + +@HostApi(dartHostTestHandler: 'TestInAppPurchase2Api') +abstract class InAppPurchase2API { + // https://developer.apple.com/documentation/storekit/appstore/3822277-canmakepayments + bool canMakePayments(); + + // https://developer.apple.com/documentation/storekit/product/3851116-products + @async + List products(List identifiers); + + // https://developer.apple.com/documentation/storekit/product/3791971-purchase + @async + SK2ProductPurchaseResultMessage purchase(String id, + {SK2ProductPurchaseOptionsMessage? options}); + + @async + List transactions(); + + @async + void finish(int id); + + void startListeningToTransactions(); + + void stopListeningToTransactions(); + + @async + void restorePurchases(); +} + +@FlutterApi() +abstract class InAppPurchase2CallbackAPI { + void onTransactionsUpdated(List newTransactions); +} 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 bcb280781d08..317bc8d0e107 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/pubspec.yaml +++ b/packages/in_app_purchase/in_app_purchase_storekit/pubspec.yaml @@ -2,11 +2,11 @@ name: in_app_purchase_storekit description: An implementation for the iOS and macOS platforms of the Flutter `in_app_purchase` plugin. This uses the StoreKit Framework. repository: https://github.com/flutter/packages/tree/main/packages/in_app_purchase/in_app_purchase_storekit issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+in_app_purchase%22 -version: 0.3.17 +version: 0.3.18+4 environment: - sdk: ^3.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -31,7 +31,7 @@ dev_dependencies: flutter_test: sdk: flutter json_serializable: ^6.0.0 - pigeon: ^16.0.4 + pigeon: ^22.4.2 test: ^1.16.0 topics: diff --git a/packages/in_app_purchase/in_app_purchase_storekit/test/fakes/fake_storekit_platform.dart b/packages/in_app_purchase/in_app_purchase_storekit/test/fakes/fake_storekit_platform.dart index 082d62939d90..55c490bb62b4 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/test/fakes/fake_storekit_platform.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/test/fakes/fake_storekit_platform.dart @@ -6,8 +6,12 @@ import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:in_app_purchase_storekit/in_app_purchase_storekit.dart'; import 'package:in_app_purchase_storekit/src/messages.g.dart'; +import 'package:in_app_purchase_storekit/src/sk2_pigeon.g.dart'; +import 'package:in_app_purchase_storekit/src/store_kit_2_wrappers/sk2_product_wrapper.dart'; +import 'package:in_app_purchase_storekit/src/store_kit_2_wrappers/sk2_transaction_wrapper.dart'; import 'package:in_app_purchase_storekit/store_kit_wrappers.dart'; +import '../sk2_test_api.g.dart'; import '../store_kit_wrappers/sk_test_stub_objects.dart'; import '../test_api.g.dart'; @@ -33,7 +37,7 @@ class FakeStoreKitPlatform implements TestInAppPurchaseApi { void reset() { transactionList = []; receiptData = 'dummy base64data'; - validProductIDs = {'123', '456'}; + validProductIDs = {'123', '456', '789'}; validProducts = {}; for (final String validID in validProductIDs) { final Map productWrapperMap = @@ -42,6 +46,9 @@ class FakeStoreKitPlatform implements TestInAppPurchaseApi { if (validID == '456') { productWrapperMap['priceLocale'] = buildLocaleMap(noSymbolLocale); } + if (validID == '789') { + productWrapperMap['localizedDescription'] = null; + } validProducts[validID] = SKProductWrapper.fromJson(productWrapperMap); } @@ -180,7 +187,7 @@ class FakeStoreKitPlatform implements TestInAppPurchaseApi { } @override - List transactions() { + List transactions() { throw UnimplementedError(); } @@ -274,3 +281,121 @@ class FakeStoreKitPlatform implements TestInAppPurchaseApi { queueIsActive = false; } } + +class FakeStoreKit2Platform implements TestInAppPurchase2Api { + late Set validProductIDs; + late Map validProducts; + late List transactionList = []; + late bool testTransactionFail; + late int testTransactionCancel; + late List finishedTransactions; + + PlatformException? queryProductException; + bool isListenerRegistered = false; + + void reset() { + validProductIDs = {'123', '456'}; + validProducts = {}; + for (final String validID in validProductIDs) { + final SK2Product product = SK2Product( + id: validID, + displayName: 'test_product', + displayPrice: '0.99', + description: 'description', + price: 0.99, + type: SK2ProductType.consumable, + priceLocale: + SK2PriceLocale(currencyCode: 'USD', currencySymbol: r'$')); + validProducts[validID] = product; + } + } + + SK2TransactionMessage createRestoredTransaction( + String productId, String transactionId, + {int quantity = 1}) { + return SK2TransactionMessage( + id: 123, + originalId: 321, + productId: '', + purchaseDate: '', + appAccountToken: '', + restoring: true); + } + + @override + bool canMakePayments() { + return true; + } + + @override + Future> products(List identifiers) { + if (queryProductException != null) { + throw queryProductException!; + } + final List productIDS = identifiers; + final List products = []; + for (final String? productID in productIDS) { + if (validProductIDs.contains(productID)) { + products.add(validProducts[productID]!); + } + } + final List result = []; + for (final SK2Product p in products) { + result.add(p.convertToPigeon()); + } + + return Future>.value(result); + } + + @override + Future purchase(String id, + {SK2ProductPurchaseOptionsMessage? options}) { + final SK2TransactionMessage transaction = createPendingTransaction(id); + + InAppPurchaseStoreKitPlatform.sk2TransactionObserver + .onTransactionsUpdated([transaction]); + return Future.value( + SK2ProductPurchaseResultMessage.success); + } + + @override + Future finish(int id) { + return Future.value(); + } + + @override + Future> transactions() { + return Future>.value([ + SK2TransactionMessage( + id: 123, + originalId: 123, + productId: 'product_id', + purchaseDate: '12-12') + ]); + } + + @override + void startListeningToTransactions() { + isListenerRegistered = true; + } + + @override + void stopListeningToTransactions() { + isListenerRegistered = false; + } + + @override + Future restorePurchases() async { + InAppPurchaseStoreKitPlatform.sk2TransactionObserver + .onTransactionsUpdated(transactionList); + } +} + +SK2TransactionMessage createPendingTransaction(String id, {int quantity = 1}) { + return SK2TransactionMessage( + id: 1, + originalId: 2, + productId: id, + purchaseDate: 'purchaseDate', + appAccountToken: 'appAccountToken'); +} diff --git a/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_2_platform_test.dart b/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_2_platform_test.dart new file mode 100644 index 000000000000..6fb2ba030704 --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_2_platform_test.dart @@ -0,0 +1,191 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:in_app_purchase_platform_interface/in_app_purchase_platform_interface.dart'; +import 'package:in_app_purchase_storekit/in_app_purchase_storekit.dart'; +import 'package:in_app_purchase_storekit/store_kit_2_wrappers.dart'; + +import 'fakes/fake_storekit_platform.dart'; +import 'sk2_test_api.g.dart'; + +void main() { + final SK2Product dummyProductWrapper = SK2Product( + id: '2', + displayName: 'name', + displayPrice: '0.99', + description: 'desc', + price: 0.99, + type: SK2ProductType.consumable, + priceLocale: SK2PriceLocale(currencyCode: 'USD', currencySymbol: r'$')); + + TestWidgetsFlutterBinding.ensureInitialized(); + + final FakeStoreKit2Platform fakeStoreKit2Platform = FakeStoreKit2Platform(); + late InAppPurchaseStoreKitPlatform iapStoreKitPlatform; + + setUpAll(() { + TestInAppPurchase2Api.setUp(fakeStoreKit2Platform); + }); + + setUp(() { + InAppPurchaseStoreKitPlatform.registerPlatform(); + iapStoreKitPlatform = + InAppPurchasePlatform.instance as InAppPurchaseStoreKitPlatform; + iapStoreKitPlatform.enableStoreKit2(); + fakeStoreKit2Platform.reset(); + }); + + tearDown(() => fakeStoreKit2Platform.reset()); + + group('isAvailable', () { + test('true', () async { + expect(await iapStoreKitPlatform.isAvailable(), isTrue); + }); + }); + + group('query product list', () { + test('should get product list and correct invalid identifiers', () async { + final InAppPurchaseStoreKitPlatform connection = + InAppPurchaseStoreKitPlatform(); + final ProductDetailsResponse response = + await connection.queryProductDetails({'123', '456', '789'}); + final List products = response.productDetails; + expect(products.first.id, '123'); + expect(products[1].id, '456'); + expect(response.notFoundIDs, ['789']); + expect(response.error, isNull); + expect(response.productDetails.first.currencySymbol, r'$'); + expect(response.productDetails[1].currencySymbol, r'$'); + }); + test( + 'if query products throws error, should get error object in the response', + () async { + fakeStoreKit2Platform.queryProductException = PlatformException( + code: 'error_code', + message: 'error_message', + details: {'info': 'error_info'}); + final InAppPurchaseStoreKitPlatform connection = + InAppPurchaseStoreKitPlatform(); + final ProductDetailsResponse response = + await connection.queryProductDetails({'123', '456', '789'}); + expect(response.productDetails, []); + expect(response.notFoundIDs, ['123', '456', '789']); + expect(response.error, isNotNull); + expect(response.error!.source, kIAPSource); + expect(response.error!.code, 'error_code'); + expect(response.error!.message, 'error_message'); + expect(response.error!.details, {'info': 'error_info'}); + }); + }); + + group('make payment', () { + test( + 'buying non consumable, should get purchase objects in the purchase update callback', + () async { + final List details = []; + final Completer> completer = + Completer>(); + final Stream> stream = + iapStoreKitPlatform.purchaseStream; + + late StreamSubscription> subscription; + subscription = stream.listen((List purchaseDetailsList) { + details.addAll(purchaseDetailsList); + if (purchaseDetailsList.first.status == PurchaseStatus.purchased) { + completer.complete(details); + subscription.cancel(); + } + }); + final AppStorePurchaseParam purchaseParam = AppStorePurchaseParam( + productDetails: + AppStoreProduct2Details.fromSK2Product(dummyProductWrapper), + applicationUserName: 'appName'); + await iapStoreKitPlatform.buyNonConsumable(purchaseParam: purchaseParam); + + final List result = await completer.future; + expect(result.length, 1); + expect(result.first.productID, dummyProductWrapper.id); + }); + + test( + 'buying consumable, should get purchase objects in the purchase update callback', + () async { + final List details = []; + final Completer> completer = + Completer>(); + final Stream> stream = + iapStoreKitPlatform.purchaseStream; + + late StreamSubscription> subscription; + subscription = stream.listen((List purchaseDetailsList) { + details.addAll(purchaseDetailsList); + if (purchaseDetailsList.first.status == PurchaseStatus.purchased) { + completer.complete(details); + subscription.cancel(); + } + }); + final AppStorePurchaseParam purchaseParam = AppStorePurchaseParam( + productDetails: + AppStoreProduct2Details.fromSK2Product(dummyProductWrapper), + applicationUserName: 'appName'); + await iapStoreKitPlatform.buyConsumable(purchaseParam: purchaseParam); + + final List result = await completer.future; + expect(result.length, 1); + expect(result.first.productID, dummyProductWrapper.id); + }); + + test('buying consumable, should throw when autoConsume is false', () async { + final AppStorePurchaseParam purchaseParam = AppStorePurchaseParam( + productDetails: + AppStoreProduct2Details.fromSK2Product(dummyProductWrapper), + applicationUserName: 'appName'); + expect( + () => iapStoreKitPlatform.buyConsumable( + purchaseParam: purchaseParam, autoConsume: false), + throwsA(isInstanceOf())); + }); + }); + + group('restore purchases', () { + test('should emit restored transactions on purchase stream', () async { + fakeStoreKit2Platform.transactionList + .add(fakeStoreKit2Platform.createRestoredTransaction('foo', 'RT1')); + fakeStoreKit2Platform.transactionList + .add(fakeStoreKit2Platform.createRestoredTransaction('foo', 'RT2')); + final Completer> completer = + Completer>(); + final Stream> stream = + iapStoreKitPlatform.purchaseStream; + + late StreamSubscription> subscription; + subscription = stream.listen((List purchaseDetailsList) { + if (purchaseDetailsList.first.status == PurchaseStatus.restored) { + subscription.cancel(); + completer.complete(purchaseDetailsList); + } + }); + + await iapStoreKitPlatform.restorePurchases(); + final List details = await completer.future; + + expect(details.length, 2); + for (int i = 0; i < fakeStoreKit2Platform.transactionList.length; i++) { + final SK2TransactionMessage expected = + fakeStoreKit2Platform.transactionList[i]; + final PurchaseDetails actual = details[i]; + + expect(actual.purchaseID, expected.id.toString()); + expect(actual.verificationData, isNotNull); + expect(actual.status, PurchaseStatus.restored); + // In storekit 2, restored purchases don't have to finished. + expect(actual.pendingCompletePurchase, false); + } + }); + }); +} diff --git a/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_platform_addtion_test.dart b/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_platform_addtion_test.dart index 40068db75a71..dfa3c11ca6bf 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_platform_addtion_test.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_platform_addtion_test.dart @@ -15,7 +15,7 @@ void main() { final FakeStoreKitPlatform fakeStoreKitPlatform = FakeStoreKitPlatform(); setUpAll(() { - TestInAppPurchaseApi.setup(fakeStoreKitPlatform); + TestInAppPurchaseApi.setUp(fakeStoreKitPlatform); }); group('present code redemption sheet', () { diff --git a/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_platform_test.dart b/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_platform_test.dart index 56dc89fb190c..a255b4fa3bd2 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_platform_test.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_platform_test.dart @@ -22,7 +22,7 @@ void main() { late InAppPurchaseStoreKitPlatform iapStoreKitPlatform; setUpAll(() { - TestInAppPurchaseApi.setup(fakeStoreKitPlatform); + TestInAppPurchaseApi.setUp(fakeStoreKitPlatform); }); setUp(() { @@ -44,12 +44,14 @@ void main() { test('should get product list and correct invalid identifiers', () async { final InAppPurchaseStoreKitPlatform connection = InAppPurchaseStoreKitPlatform(); - final ProductDetailsResponse response = - await connection.queryProductDetails({'123', '456', '789'}); + final ProductDetailsResponse response = await connection + .queryProductDetails({'123', '456', '789', '999'}); final List products = response.productDetails; expect(products.first.id, '123'); expect(products[1].id, '456'); - expect(response.notFoundIDs, ['789']); + expect(products[2].id, '789'); + expect(products[2].description, ''); + expect(response.notFoundIDs, ['999']); expect(response.error, isNull); expect(response.productDetails.first.currencySymbol, r'$'); expect(response.productDetails[1].currencySymbol, 'EUR'); diff --git a/packages/in_app_purchase/in_app_purchase_storekit/test/sk2_test_api.g.dart b/packages/in_app_purchase/in_app_purchase_storekit/test/sk2_test_api.g.dart new file mode 100644 index 000000000000..5c595d45c09e --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase_storekit/test/sk2_test_api.g.dart @@ -0,0 +1,376 @@ +// 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 (v22.6.0), 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, unnecessary_import, no_leading_underscores_for_local_identifiers +// ignore_for_file: avoid_relative_lib_imports +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; +import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:in_app_purchase_storekit/src/sk2_pigeon.g.dart'; + +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is SK2ProductTypeMessage) { + buffer.putUint8(129); + writeValue(buffer, value.index); + } else if (value is SK2SubscriptionOfferTypeMessage) { + buffer.putUint8(130); + writeValue(buffer, value.index); + } else if (value is SK2SubscriptionOfferPaymentModeMessage) { + buffer.putUint8(131); + writeValue(buffer, value.index); + } else if (value is SK2SubscriptionPeriodUnitMessage) { + buffer.putUint8(132); + writeValue(buffer, value.index); + } else if (value is SK2ProductPurchaseResultMessage) { + buffer.putUint8(133); + writeValue(buffer, value.index); + } else if (value is SK2SubscriptionOfferMessage) { + buffer.putUint8(134); + writeValue(buffer, value.encode()); + } else if (value is SK2SubscriptionPeriodMessage) { + buffer.putUint8(135); + writeValue(buffer, value.encode()); + } else if (value is SK2SubscriptionInfoMessage) { + buffer.putUint8(136); + writeValue(buffer, value.encode()); + } else if (value is SK2ProductMessage) { + buffer.putUint8(137); + writeValue(buffer, value.encode()); + } else if (value is SK2PriceLocaleMessage) { + buffer.putUint8(138); + writeValue(buffer, value.encode()); + } else if (value is SK2ProductPurchaseOptionsMessage) { + buffer.putUint8(139); + writeValue(buffer, value.encode()); + } else if (value is SK2TransactionMessage) { + buffer.putUint8(140); + writeValue(buffer, value.encode()); + } else if (value is SK2ErrorMessage) { + buffer.putUint8(141); + writeValue(buffer, value.encode()); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 129: + final int? value = readValue(buffer) as int?; + return value == null ? null : SK2ProductTypeMessage.values[value]; + case 130: + final int? value = readValue(buffer) as int?; + return value == null + ? null + : SK2SubscriptionOfferTypeMessage.values[value]; + case 131: + final int? value = readValue(buffer) as int?; + return value == null + ? null + : SK2SubscriptionOfferPaymentModeMessage.values[value]; + case 132: + final int? value = readValue(buffer) as int?; + return value == null + ? null + : SK2SubscriptionPeriodUnitMessage.values[value]; + case 133: + final int? value = readValue(buffer) as int?; + return value == null + ? null + : SK2ProductPurchaseResultMessage.values[value]; + case 134: + return SK2SubscriptionOfferMessage.decode(readValue(buffer)!); + case 135: + return SK2SubscriptionPeriodMessage.decode(readValue(buffer)!); + case 136: + return SK2SubscriptionInfoMessage.decode(readValue(buffer)!); + case 137: + return SK2ProductMessage.decode(readValue(buffer)!); + case 138: + return SK2PriceLocaleMessage.decode(readValue(buffer)!); + case 139: + return SK2ProductPurchaseOptionsMessage.decode(readValue(buffer)!); + case 140: + return SK2TransactionMessage.decode(readValue(buffer)!); + case 141: + return SK2ErrorMessage.decode(readValue(buffer)!); + default: + return super.readValueOfType(type, buffer); + } + } +} + +abstract class TestInAppPurchase2Api { + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + bool canMakePayments(); + + Future> products(List identifiers); + + Future purchase(String id, + {SK2ProductPurchaseOptionsMessage? options}); + + Future> transactions(); + + Future finish(int id); + + void startListeningToTransactions(); + + void stopListeningToTransactions(); + + Future restorePurchases(); + + static void setUp( + TestInAppPurchase2Api? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.canMakePayments$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + try { + final bool output = api.canMakePayments(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.products$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.products was null.'); + final List args = (message as List?)!; + final List? arg_identifiers = + (args[0] as List?)?.cast(); + assert(arg_identifiers != null, + 'Argument for dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.products was null, expected non-null List.'); + try { + final List output = + await api.products(arg_identifiers!); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.purchase$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.purchase was null.'); + final List args = (message as List?)!; + final String? arg_id = (args[0] as String?); + assert(arg_id != null, + 'Argument for dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.purchase was null, expected non-null String.'); + final SK2ProductPurchaseOptionsMessage? arg_options = + (args[1] as SK2ProductPurchaseOptionsMessage?); + try { + final SK2ProductPurchaseResultMessage output = + await api.purchase(arg_id!, options: arg_options); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.transactions$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + try { + final List output = await api.transactions(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.finish$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.finish was null.'); + final List args = (message as List?)!; + final int? arg_id = (args[0] as int?); + assert(arg_id != null, + 'Argument for dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.finish was null, expected non-null int.'); + try { + await api.finish(arg_id!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.startListeningToTransactions$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + try { + api.startListeningToTransactions(); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.stopListeningToTransactions$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + try { + api.stopListeningToTransactions(); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.restorePurchases$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + try { + await api.restorePurchases(); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } +} diff --git a/packages/in_app_purchase/in_app_purchase_storekit/test/store_kit_wrappers/sk_methodchannel_apis_test.dart b/packages/in_app_purchase/in_app_purchase_storekit/test/store_kit_wrappers/sk_methodchannel_apis_test.dart index f7fe5283d949..b774552f84ba 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/test/store_kit_wrappers/sk_methodchannel_apis_test.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/test/store_kit_wrappers/sk_methodchannel_apis_test.dart @@ -15,7 +15,7 @@ void main() { final FakeStoreKitPlatform fakeStoreKitPlatform = FakeStoreKitPlatform(); setUpAll(() { - TestInAppPurchaseApi.setup(fakeStoreKitPlatform); + TestInAppPurchaseApi.setUp(fakeStoreKitPlatform); }); setUp(() {}); @@ -235,7 +235,7 @@ class FakeStoreKitPlatform implements TestInAppPurchaseApi { } @override - List transactions() => + List transactions() => [dummyTransactionMessage]; @override diff --git a/packages/in_app_purchase/in_app_purchase_storekit/test/store_kit_wrappers/sk_payment_queue_delegate_api_test.dart b/packages/in_app_purchase/in_app_purchase_storekit/test/store_kit_wrappers/sk_payment_queue_delegate_api_test.dart index 03c9fda381cb..f9efd427bfc5 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/test/store_kit_wrappers/sk_payment_queue_delegate_api_test.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/test/store_kit_wrappers/sk_payment_queue_delegate_api_test.dart @@ -15,7 +15,7 @@ void main() { final FakeStoreKitPlatform fakeStoreKitPlatform = FakeStoreKitPlatform(); setUpAll(() { - TestInAppPurchaseApi.setup(fakeStoreKitPlatform); + TestInAppPurchaseApi.setUp(fakeStoreKitPlatform); }); test( diff --git a/packages/in_app_purchase/in_app_purchase_storekit/test/test_api.g.dart b/packages/in_app_purchase/in_app_purchase_storekit/test/test_api.g.dart index 6b0c9a77ab46..2092930d208d 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/test/test_api.g.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/test/test_api.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.4.2), 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, unnecessary_import, no_leading_underscores_for_local_identifiers // ignore_for_file: avoid_relative_lib_imports @@ -13,40 +13,55 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:in_app_purchase_storekit/src/messages.g.dart'; -class _TestInAppPurchaseApiCodec extends StandardMessageCodec { - const _TestInAppPurchaseApiCodec(); +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is SKErrorMessage) { - buffer.putUint8(128); - writeValue(buffer, value.encode()); - } else if (value is SKPaymentDiscountMessage) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is SKPaymentTransactionStateMessage) { buffer.putUint8(129); - writeValue(buffer, value.encode()); - } else if (value is SKPaymentMessage) { + writeValue(buffer, value.index); + } else if (value is SKProductDiscountTypeMessage) { buffer.putUint8(130); - writeValue(buffer, value.encode()); - } else if (value is SKPaymentTransactionMessage) { + writeValue(buffer, value.index); + } else if (value is SKProductDiscountPaymentModeMessage) { buffer.putUint8(131); - writeValue(buffer, value.encode()); - } else if (value is SKPriceLocaleMessage) { + writeValue(buffer, value.index); + } else if (value is SKSubscriptionPeriodUnitMessage) { buffer.putUint8(132); - writeValue(buffer, value.encode()); - } else if (value is SKProductDiscountMessage) { + writeValue(buffer, value.index); + } else if (value is SKPaymentTransactionMessage) { buffer.putUint8(133); writeValue(buffer, value.encode()); - } else if (value is SKProductMessage) { + } else if (value is SKPaymentMessage) { buffer.putUint8(134); writeValue(buffer, value.encode()); - } else if (value is SKProductSubscriptionPeriodMessage) { + } else if (value is SKErrorMessage) { buffer.putUint8(135); writeValue(buffer, value.encode()); - } else if (value is SKProductsResponseMessage) { + } else if (value is SKPaymentDiscountMessage) { buffer.putUint8(136); writeValue(buffer, value.encode()); } else if (value is SKStorefrontMessage) { buffer.putUint8(137); writeValue(buffer, value.encode()); + } else if (value is SKProductsResponseMessage) { + buffer.putUint8(138); + writeValue(buffer, value.encode()); + } else if (value is SKProductMessage) { + buffer.putUint8(139); + writeValue(buffer, value.encode()); + } else if (value is SKPriceLocaleMessage) { + buffer.putUint8(140); + writeValue(buffer, value.encode()); + } else if (value is SKProductDiscountMessage) { + buffer.putUint8(141); + writeValue(buffer, value.encode()); + } else if (value is SKProductSubscriptionPeriodMessage) { + buffer.putUint8(142); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -55,26 +70,46 @@ class _TestInAppPurchaseApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: - return SKErrorMessage.decode(readValue(buffer)!); case 129: - return SKPaymentDiscountMessage.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null + ? null + : SKPaymentTransactionStateMessage.values[value]; case 130: - return SKPaymentMessage.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null + ? null + : SKProductDiscountTypeMessage.values[value]; case 131: - return SKPaymentTransactionMessage.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null + ? null + : SKProductDiscountPaymentModeMessage.values[value]; case 132: - return SKPriceLocaleMessage.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null + ? null + : SKSubscriptionPeriodUnitMessage.values[value]; case 133: - return SKProductDiscountMessage.decode(readValue(buffer)!); + return SKPaymentTransactionMessage.decode(readValue(buffer)!); case 134: - return SKProductMessage.decode(readValue(buffer)!); + return SKPaymentMessage.decode(readValue(buffer)!); case 135: - return SKProductSubscriptionPeriodMessage.decode(readValue(buffer)!); + return SKErrorMessage.decode(readValue(buffer)!); case 136: - return SKProductsResponseMessage.decode(readValue(buffer)!); + return SKPaymentDiscountMessage.decode(readValue(buffer)!); case 137: return SKStorefrontMessage.decode(readValue(buffer)!); + case 138: + return SKProductsResponseMessage.decode(readValue(buffer)!); + case 139: + return SKProductMessage.decode(readValue(buffer)!); + case 140: + return SKPriceLocaleMessage.decode(readValue(buffer)!); + case 141: + return SKProductDiscountMessage.decode(readValue(buffer)!); + case 142: + return SKProductSubscriptionPeriodMessage.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -84,22 +119,21 @@ class _TestInAppPurchaseApiCodec extends StandardMessageCodec { abstract class TestInAppPurchaseApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec pigeonChannelCodec = - _TestInAppPurchaseApiCodec(); + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); /// Returns if the current device is able to make payments bool canMakePayments(); - List transactions(); + List transactions(); SKStorefrontMessage storefront(); - void addPayment(Map paymentMap); + void addPayment(Map paymentMap); Future startProductRequest( - List productIdentifiers); + List productIdentifiers); - void finishTransaction(Map finishMap); + void finishTransaction(Map finishMap); void restoreTransactions(String? applicationUserName); @@ -107,7 +141,7 @@ abstract class TestInAppPurchaseApi { String? retrieveReceiptData(); - Future refreshReceipt({Map? receiptProperties}); + Future refreshReceipt({Map? receiptProperties}); void startObservingPaymentQueue(); @@ -119,20 +153,26 @@ abstract class TestInAppPurchaseApi { void showPriceConsentIfNeeded(); - static void setup(TestInAppPurchaseApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + TestInAppPurchaseApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.canMakePayments', + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.canMakePayments$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { try { final bool output = api.canMakePayments(); @@ -147,21 +187,21 @@ abstract class TestInAppPurchaseApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.transactions', + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.transactions$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { try { - final List output = - api.transactions(); + final List output = api.transactions(); return [output]; } on PlatformException catch (e) { return wrapResponse(error: e); @@ -173,17 +213,18 @@ abstract class TestInAppPurchaseApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.storefront', + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.storefront$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { try { final SKStorefrontMessage output = api.storefront(); @@ -198,25 +239,26 @@ abstract class TestInAppPurchaseApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.addPayment', + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.addPayment$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.addPayment was null.'); final List args = (message as List?)!; - final Map? arg_paymentMap = - (args[0] as Map?)?.cast(); + final Map? arg_paymentMap = + (args[0] as Map?)?.cast(); assert(arg_paymentMap != null, - 'Argument for dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.addPayment was null, expected non-null Map.'); + 'Argument for dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.addPayment was null, expected non-null Map.'); try { api.addPayment(arg_paymentMap!); return wrapResponse(empty: true); @@ -230,25 +272,26 @@ abstract class TestInAppPurchaseApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.startProductRequest', + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.startProductRequest$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.startProductRequest was null.'); final List args = (message as List?)!; - final List? arg_productIdentifiers = - (args[0] as List?)?.cast(); + final List? arg_productIdentifiers = + (args[0] as List?)?.cast(); assert(arg_productIdentifiers != null, - 'Argument for dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.startProductRequest was null, expected non-null List.'); + 'Argument for dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.startProductRequest was null, expected non-null List.'); try { final SKProductsResponseMessage output = await api.startProductRequest(arg_productIdentifiers!); @@ -263,25 +306,26 @@ abstract class TestInAppPurchaseApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.finishTransaction', + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.finishTransaction$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.finishTransaction was null.'); final List args = (message as List?)!; - final Map? arg_finishMap = - (args[0] as Map?)?.cast(); + final Map? arg_finishMap = + (args[0] as Map?)?.cast(); assert(arg_finishMap != null, - 'Argument for dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.finishTransaction was null, expected non-null Map.'); + 'Argument for dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.finishTransaction was null, expected non-null Map.'); try { api.finishTransaction(arg_finishMap!); return wrapResponse(empty: true); @@ -295,17 +339,18 @@ abstract class TestInAppPurchaseApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.restoreTransactions', + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.restoreTransactions$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.restoreTransactions was null.'); @@ -324,17 +369,18 @@ abstract class TestInAppPurchaseApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.presentCodeRedemptionSheet', + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.presentCodeRedemptionSheet$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { try { api.presentCodeRedemptionSheet(); @@ -349,17 +395,18 @@ abstract class TestInAppPurchaseApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.retrieveReceiptData', + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.retrieveReceiptData$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { try { final String? output = api.retrieveReceiptData(); @@ -374,23 +421,24 @@ abstract class TestInAppPurchaseApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.refreshReceipt', + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.refreshReceipt$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.refreshReceipt was null.'); final List args = (message as List?)!; - final Map? arg_receiptProperties = - (args[0] as Map?)?.cast(); + final Map? arg_receiptProperties = + (args[0] as Map?)?.cast(); try { await api.refreshReceipt(receiptProperties: arg_receiptProperties); return wrapResponse(empty: true); @@ -404,17 +452,18 @@ abstract class TestInAppPurchaseApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.startObservingPaymentQueue', + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.startObservingPaymentQueue$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { try { api.startObservingPaymentQueue(); @@ -429,17 +478,18 @@ abstract class TestInAppPurchaseApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.stopObservingPaymentQueue', + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.stopObservingPaymentQueue$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { try { api.stopObservingPaymentQueue(); @@ -454,17 +504,18 @@ abstract class TestInAppPurchaseApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.registerPaymentQueueDelegate', + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.registerPaymentQueueDelegate$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { try { api.registerPaymentQueueDelegate(); @@ -479,17 +530,18 @@ abstract class TestInAppPurchaseApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.removePaymentQueueDelegate', + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.removePaymentQueueDelegate$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { try { api.removePaymentQueueDelegate(); @@ -504,17 +556,18 @@ abstract class TestInAppPurchaseApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.showPriceConsentIfNeeded', + 'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.showPriceConsentIfNeeded$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { try { api.showPriceConsentIfNeeded(); diff --git a/packages/integration_test/README.md b/packages/integration_test/README.md index 83c4adb500f0..1f9442a6beec 100644 --- a/packages/integration_test/README.md +++ b/packages/integration_test/README.md @@ -15,4 +15,4 @@ dev_dependencies: ``` For the latest documentation, see [Integration -testing](https://flutter.dev/docs/testing/integration-tests). +testing](https://docs.flutter.dev/testing/integration-tests). diff --git a/packages/interactive_media_ads/CHANGELOG.md b/packages/interactive_media_ads/CHANGELOG.md index ece165f4961e..cf488dd18cce 100644 --- a/packages/interactive_media_ads/CHANGELOG.md +++ b/packages/interactive_media_ads/CHANGELOG.md @@ -1,3 +1,146 @@ +## 0.2.2+15 + +* Adds remaining methods for internal wrapper of the Android native `BaseManager`. + +## 0.2.2+14 + +* Adds internal wrapper for iOS native `IMACompanionAdSlot` and `IMACompanionDelegate`. + +## 0.2.2+13 + +* Adds internal wrapper for Android native `Ad`. + +## 0.2.2+12 + +* Adds internal wrapper for iOS native `IMACompanionAd`. + +## 0.2.2+11 + +* Adds internal wrapper for Android native `UniversalAdId`. + +## 0.2.2+10 + +* Fixes bug where Android would show the last frame of the previous Ad before playing the current + one. + +## 0.2.2+9 + +* Adds internal wrapper for Android native `CompanionAd`. + +## 0.2.2+8 + +* Adds remaining methods for internal wrapper of the iOS native `IMAAdsRenderingSettings`. + +## 0.2.2+7 + +* Updates Java compatibility version to 11. +* Updates minimum supported SDK version to Flutter 3.24/Dart 3.5. + +## 0.2.2+6 + +* Bumps Android dependency `com.google.ads.interactivemedia.v3:interactivemedia` from `3.50.0` to + `3.35.1`. + +## 0.2.2+5 + +* Changes the example app to initialize the `AdsLoader` in `onContainerAdded`. + +## 0.2.2+4 + +* Adds internal wrapper for Android native `AdProgressInfo`. + +## 0.2.2+3 + +* Adds internal wrapper for iOS native `IMAFriendlyObstruction`. + +## 0.2.2+2 + +* Adds internal wrapper for Android native `AdsRenderingSettings`. + +## 0.2.2+1 + +* Bumps Android dependency `com.google.ads.interactivemedia.v3:interactivemedia` from `3.34.0` to + `3.35.0`. + +## 0.2.2 + +* Adds support for mid-roll ads. See `AdsRequest.contentProgressProvider`. + +## 0.2.1 + +* Adds internal wrapper for Android native `ContentProgressProvider`. + +## 0.2.0 + +* Adds support for pausing and resuming Ad playback. See `AdsManager.pause` and `AdsManager.resume`. +* Adds support to skip an Ad. See `AdsManager.skip` and `AdsManager.discardAdBreak`. +* **Breaking Change** To keep platform consistency, Android no longer continues playing an Ad + whenever it returns from an Ad click. Call `AdsManager.resume` to resume Ad playback. + +## 0.1.2+6 + +* Fixes bug where the ad would play when the app returned to foreground during content playback. + +## 0.1.2+5 + +* Adds internal wrapper for remaining methods of the Android native `AdsManager`. + +## 0.1.2+4 + +* Bumps androidx.annotation:annotation from 1.8.1 to 1.8.2. + +## 0.1.2+3 + +* Adds a contribution guide. See `CONTRIBUTING.md`. + +## 0.1.2+2 + +* Removes dependency on org.jetbrains.kotlin:kotlin-bom. +* Updates minimum supported SDK version to Flutter 3.24/Dart 3.5. + +## 0.1.2+1 + +* Updates README to clarify supported features and link to issues tracker. + +## 0.1.2 + +* Adds support for all `AdEventType`s and ad data. See `AdEvent.adData`. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + +## 0.1.1+1 + +* Fixes a typo in the formatting of the CHANGELOG. + +## 0.1.1 + +* Adds iOS implementation. +* Adds support for setting the layout direction of the `AdDisplayContainer`. + +## 0.1.0+2 + +* Bumps androidx.annotation:annotation from 1.7.1 to 1.8.1. + +## 0.1.0+1 + +* Updates lint checks to ignore NewerVersionAvailable. + +## 0.1.0 + +* Bumps `com.google.ads.interactivemedia.v3:interactivemedia` from 3.33.0 to 3.34.0. +* **Breaking Change** Updates Android `minSdk` from 19 to 21. + +## 0.0.2+1 + +* Updates `README` with a usage section and fix app-facing interface documentation. + +## 0.0.2 + +* Adds Android implementation. + +## 0.0.1+3 + +* Fixes the pub badge source. + ## 0.0.1+2 * Bumps Android's androidx.annotation:annotation dependency from 1.5.0 to 1.8.0. diff --git a/packages/interactive_media_ads/CONTRIBUTING.md b/packages/interactive_media_ads/CONTRIBUTING.md new file mode 100644 index 000000000000..0578595c34f0 --- /dev/null +++ b/packages/interactive_media_ads/CONTRIBUTING.md @@ -0,0 +1,216 @@ +# Contributing to `interactive_media_ads` + +Please start by taking a look at the general guide to contributing to the `flutter/packages` repo: +https://github.com/flutter/packages/blob/main/CONTRIBUTING.md + +## Package Structure + +The structure of this plugin is similar to a [federated plugin](https://docs.flutter.dev/packages-and-plugins/developing-packages#federated-plugins), +except the code for each package (platform interface, platform implementations, and app-facing +interface) are maintained in this single plugin. The sections below will provide an overview of how +this plugin implements each portion. + +If you are familiar with [changing federated plugin](https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#changing-federated-plugins) +in the `flutter/packages` repo, the process is similar except that all changes are made in this +plugin. Therefore, it is not necessary to run the script that makes dependencies path based. + +### Quick Overview + +This plugin uses the native [IMA SDKs] for Android and iOS. The API for the SDK of both platforms +are relatively similar, so this plugin attempts to maintain an interface that is similar to the +native SDKs. + +The app-facing interface uses delegation to interact with the underlying platform implementations. +Therefore, the platform interface is similar to the app-facing interface with the differences being +explained in the sections below. Many app-facing interface classes will contain a `platform` field +that is used to forward handling to the platform implementation: + +```dart +// App-facing class used by apps +class AdsLoader { + AdsLoader.fromPlatform(this.platform); + + final PlatformAdsLoader platform; + + Future requestAds(AdsRequest request) { + return platform.requestAds(request); + } +} + +// Platform interface class implemented by each platform +abstract base class PlatformAdsLoader { + Future requestAds(AdsRequest request); +} +``` + +The `platform` variable should also be used to provide access to platform specific methods or +platform specific creation parameters: + +```dart +final AdsLoader loader = AdsLoader(); +(loader.platform as AndroidAdsLoader).callAndroidSpecificMethod(); +``` + +The other classes/enums included in the app-facing interface are typically exported from the +platform interface. A data class being a good example of a class that is exported. + +### Platform Interface + +Code location: `lib/src/platform_interface/`. + +This declares an interface that each platform must implement to be supported by the app-facing +interface. + +The design of the platform interface should prioritize: +* Minimizing the chances of needing a breaking change when adding a new feature. +* Allowing platform implementations to easily add platform specific features. +* Being straight-forward to write unit tests. + +Each platform creates a subclass of the central [InteractiveMediaAdsPlatform](lib/src/platform_interface/interactive_media_ads_platform.dart) +class. A platform implementation is set by setting `InteractiveMediaAdsPlatform.instance` to an +instance of a platform implementation of `InteractiveMediaAdsPlatform`. + +### Platform Interface Class Types + +Below are some of the types of classes in the interface. + +#### Delegate Platform Class + +These are classes where the app-facing interface needs to delegate handling to the platform +implementation. These classes are typically prefixed with `Platform`. + +If the corresponding app-facing class can be instantiated by the app (e.g. [AdsLoader]), +the `InteractiveMediaAdsPlatform.instance` field should be used in a factory to instantiate the +correct platform implementation. See [PlatformAdsLoader] as an example. This class should should +also take a creation params class as the only constructor parameter. + +If the corresponding app-facing class can't be instantiated by the app (e.g. `AdsManager`), the +class should only have a single protected constructor. See [PlatformAdsManager]. + +If the corresponding app-facing class needs to be a `Widget` (e.g. [AdDisplayContainer]), this +should follow the same pattern as being instantiable by the app except it should contain a single +method: `Widget build(BuildContext)`. See [PlatformAdDisplayContainer]. + +**Note** + +Every method should contain no more than one parameter. This allows the platform interface and +platform implementations to add new features without requiring a breaking change. + +#### Data Classes + +These classes contain only fields and no methods. Each data class should be made `@immutable`. + +### Platform Implementations + +Code location: +* Android: `lib/src/android/` +* iOS: `lib/src/ios/` + +The platform implementations create a subclass of `InteractiveMediaAdsPlatform` and implement the +platform classes that are returned by this. + +#### SDK Wrappers + +The platform implementations use Dart wrappers of their native SDKs. The SDKs are wrapped using +using the `pigeon` package. However, the code that handles generating the wrappers for iOS is still +in the process of review, so this plugin must use a git dependency in the pubspec. + +The wrappers for the SDK of each platform can be updated and modified by changing the pigeon files: + +* Android: `pigeons/interactive_media_ads_android.dart` +* iOS: `pigeons/interactive_media_ads_ios.dart` + +The generated files are located: +* Android: + * `lib/src/android/interactive_media_ads.g.dart` + * `android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/InteractiveMediaAdsLibrary.g.kt` +* iOS + * `lib/src/ios/interactive_media_ads.g.dart` + * `ios/interactive_media_ads/Sources/interactive_media_ads/InteractiveMediaAdsLibrary.g.swift` + +To update a wrapper for a platform, follow the steps: + +##### 1. Ensure the project has been built at least once + +* Android: Run `flutter build apk --debug` in `example/`. +* iOS: Run `flutter build ios --simulator` in `example/` + +##### 2. Make changes to the respective pigeon file that matches the native SDK + +* Android: + - [Android SDK] + - Pigeon file to update: `pigeons/interactive_media_ads_android.dart` +* iOS: + - [iOS SDK] + - Pigeon file to update: `pigeons/interactive_media_ads_ios.dart` + +##### 3. Run the code generator from the terminal + +* Android: `dart run pigeon --input pigeons/interactive_media_ads_android.dart` +* iOS: `dart run pigeon --input pigeons/interactive_media_ads_ios.dart` + +##### 4. Update the generated APIs in native code + +Running the `flutter build` step from step 1 again should provide build errors and indicate what +needs to be done. Alternatively, it can be easier to update native code with the platform's specific +IDE: + +* Android: Open `example/android/` in a separate Android Studio project. +* iOS: Open `example/ios/` in Xcode. + +##### 5. Write API tests + +Assuming a non-static method or constructor was added to the native wrapper, a native test will need +to be added. + +* Android native tests location: `android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/` +* iOS native tests location `example/ios/RunnerTests/` + +#### Dart Unit Testing + +Tests for the platform implementations use [mockito] to generate mock objects of the native Dart +wrappers. To generate the mock objects in `test/`, run +`dart run build_runner build --delete-conflicting-outputs`. + +### App-facing Interface + +Code location: `lib/src/` + +The app-facing interface shares the same structure as the platform interface and uses delegation +to forward handling to the platform implementation. Note a few differences from the platform +interface: + +* Constructors and methods can contain more than one parameter. +* Platform classes can be instantiated with a platform implementation or creation params of + the corresponding platform interface class. See `AdsLoader.fromPlatform` and + `AdsLoader.fromPlatformCreationParams`. + +## Recommended Process for Adding a New Feature + +### 1. Create a new feature request issue in the `flutter/flutter` repo. + +See https://github.com/flutter/flutter/issues/new?assignees=&labels=&projects=&template=3_feature_request.yml + +### 2. In that issue add the specific native classes/methods that this feature requires for each platform: + +* [Android SDK] +* [iOS SDK] + +Add a note if this feature only exist for a single platform. + +### 3. Add a design where the feature can be added to the platform interface and app-facing interface. + +If this is only supported on a single platform, add where it can be added in the platform +implementation. + +### 4. Work can be started on the feature request or you can wait for feedback from a Flutter contributor. + +[IMA SDKs]: https://developers.google.com/interactive-media-ads +[AdsLoader]: lib/src/ads_loader.dart +[AdDisplayContainer]: lib/src/ad_display_container.dart +[PlatformAdsLoader]: lib/src/platform_interface/platform_ads_loader.dart +[PlatformAdsManager]: lib/src/platform_interface/platform_ads_manager.dart +[PlatformAdDisplayContainer]: lib/src/platform_interface/platform_ad_display_container.dart +[Android SDK]: https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/package-summary +[iOS SDK]: https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes +[mockito]: https://pub.dev/packages/mockito diff --git a/packages/interactive_media_ads/README.md b/packages/interactive_media_ads/README.md index d1d17151f02b..d3e1817f09ba 100644 --- a/packages/interactive_media_ads/README.md +++ b/packages/interactive_media_ads/README.md @@ -2,14 +2,320 @@ Flutter plugin for the [Interactive Media Ads SDKs][1]. -[![pub package](https://img.shields.io/pub/v/webview_flutter.svg)](https://pub.dev/packages/interactive_media_ads) +[![pub package](https://img.shields.io/pub/v/interactive_media_ads.svg)](https://pub.dev/packages/interactive_media_ads) -A Flutter plugin for using the Interactive Media Ads SDKs on Android and iOS. +IMA SDKs make it easy to integrate multimedia ads into your websites and apps. IMA SDKs can request +ads from any [VAST-compliant][2] ad server and manage ad playback in your apps. With IMA client-side +SDKs, you maintain control of content video playback, while the SDK handles ad playback. Ads play in +a separate video player positioned on top of the app's content video player. | | Android | iOS | |-------------|---------|-------| -| **Support** | SDK 19+ | 12.0+ | +| **Support** | SDK 21+ | 12.0+ | -**This package is still in development.** +**NOTE:** +* Companion ads, Background Audio ads and Google Dynamic Ad Insertion methods are currently not + supported. + +## IMA client-side overview + +Implementing IMA client-side involves five main SDK components, which are demonstrated in this +guide: + +* [AdDisplayContainer][3]: A container object where ads are rendered. +* [AdsLoader][4]: Requests ads and handles events from ads request responses. You should only +instantiate one ads loader, which can be reused throughout the life of the application. +* [AdsRequest][5]: An object that defines an ads request. Ads requests specify the URL for the VAST +ad tag, as well as additional parameters, such as ad dimensions. +* [AdsManager][6]: Contains the response to the ads request, controls ad playback, +and listens for ad events fired by the SDK. +* [AdsManagerDelegate][8]: Handles ad events and errors that occur during ad or stream +initialization and playback. + +## Usage + +This guide demonstrates how to integrate the IMA SDK into a new `Widget` using the [video_player][7] +plugin to display content. + +### 1. Add Android Required Permissions + +If building on Android, add the user permissions required by the IMA SDK for requesting ads in +`android/app/src/main/AndroidManifest.xml`. + + +```xml + + + + +``` + +### 2. Add Imports + +Add the import statements for the `interactive_media_ads` and [video_player][7]. Both plugins should +already be added to your `pubspec.yaml`. + + +```dart +import 'package:interactive_media_ads/interactive_media_ads.dart'; +import 'package:video_player/video_player.dart'; +``` + +### 3. Create a New Widget + +Create a new [StatefulWidget](https://api.flutter.dev/flutter/widgets/StatefulWidget-class.html) +that handles displaying Ads and playing content. + + +```dart +/// Example widget displaying an Ad before a video. +class AdExampleWidget extends StatefulWidget { + /// Constructs an [AdExampleWidget]. + const AdExampleWidget({super.key}); + + @override + State createState() => _AdExampleWidgetState(); +} + +class _AdExampleWidgetState extends State + with WidgetsBindingObserver { + // IMA sample tag for a pre-, mid-, and post-roll, single inline video ad. See more IMA sample + // tags at https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/tags + static const String _adTagUrl = + 'https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/vmap_ad_samples&sz=640x480&cust_params=sample_ar%3Dpremidpost&ciu_szs=300x250&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&env=vp&impl=s&cmsid=496&vid=short_onecue&correlator='; + + // The AdsLoader instance exposes the request ads method. + late final AdsLoader _adsLoader; + + // AdsManager exposes methods to control ad playback and listen to ad events. + AdsManager? _adsManager; + + // ··· + // Whether the widget should be displaying the content video. The content + // player is hidden while Ads are playing. + bool _shouldShowContentVideo = false; + + // Controls the content video player. + late final VideoPlayerController _contentVideoController; + + // Periodically updates the SDK of the current playback progress of the + // content video. + Timer? _contentProgressTimer; + + // Provides the SDK with the current playback progress of the content video. + // This is required to support mid-roll ads. + final ContentProgressProvider _contentProgressProvider = + ContentProgressProvider(); + // ··· + @override + Widget build(BuildContext context) { + // ··· + } +} +``` + +### 4. Add the Video Players + +Instantiate the [AdDisplayContainer][3] for playing Ads and the +[VideoPlayerController](https://pub.dev/documentation/video_player/latest/video_player/VideoPlayerController-class.html) +for playing content. + + +```dart +late final AdDisplayContainer _adDisplayContainer = AdDisplayContainer( + onContainerAdded: (AdDisplayContainer container) { + _adsLoader = AdsLoader( + container: container, + onAdsLoaded: (OnAdsLoadedData data) { + final AdsManager manager = data.manager; + _adsManager = data.manager; + + manager.setAdsManagerDelegate(AdsManagerDelegate( + onAdEvent: (AdEvent event) { + debugPrint('OnAdEvent: ${event.type} => ${event.adData}'); + switch (event.type) { + case AdEventType.loaded: + manager.start(); + case AdEventType.contentPauseRequested: + _pauseContent(); + case AdEventType.contentResumeRequested: + _resumeContent(); + case AdEventType.allAdsCompleted: + manager.destroy(); + _adsManager = null; + case AdEventType.clicked: + case AdEventType.complete: + case _: + } + }, + onAdErrorEvent: (AdErrorEvent event) { + debugPrint('AdErrorEvent: ${event.error.message}'); + _resumeContent(); + }, + )); + + manager.init(); + }, + onAdsLoadError: (AdsLoadErrorData data) { + debugPrint('OnAdsLoadError: ${data.error.message}'); + _resumeContent(); + }, + ); + + // Ads can't be requested until the `AdDisplayContainer` has been added to + // the native View hierarchy. + _requestAds(container); + }, +); + +@override +void initState() { + super.initState(); + // ··· + _contentVideoController = VideoPlayerController.networkUrl( + Uri.parse( + 'https://storage.googleapis.com/gvabox/media/samples/stock.mp4', + ), + ) + ..addListener(() { + if (_contentVideoController.value.isCompleted) { + _adsLoader.contentComplete(); + } + setState(() {}); + }) + ..initialize().then((_) { + // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed. + setState(() {}); + }); +} +``` + +### 5. Implement the `build` Method + +Return a `Widget` that contains the ad player and the content player. + + +```dart +@override +Widget build(BuildContext context) { + return Scaffold( + body: Center( + child: SizedBox( + width: 300, + child: !_contentVideoController.value.isInitialized + ? Container() + : AspectRatio( + aspectRatio: _contentVideoController.value.aspectRatio, + child: Stack( + children: [ + // The display container must be on screen before any Ads can be + // loaded and can't be removed between ads. This handles clicks for + // ads. + _adDisplayContainer, + if (_shouldShowContentVideo) + VideoPlayer(_contentVideoController) + ], + ), + ), + ), + ), + floatingActionButton: + _contentVideoController.value.isInitialized && _shouldShowContentVideo + ? FloatingActionButton( + onPressed: () { + setState(() { + _contentVideoController.value.isPlaying + ? _contentVideoController.pause() + : _contentVideoController.play(); + }); + }, + child: Icon( + _contentVideoController.value.isPlaying + ? Icons.pause + : Icons.play_arrow, + ), + ) + : null, + ); +} +``` + +### 6. Request Ads + +Handle requesting ads and add event listeners to handle when content should be displayed or hidden. + + +```dart +Future _requestAds(AdDisplayContainer container) { + return _adsLoader.requestAds(AdsRequest( + adTagUrl: _adTagUrl, + contentProgressProvider: _contentProgressProvider, + )); +} + +Future _resumeContent() async { + setState(() { + _shouldShowContentVideo = true; + }); + + if (_adsManager != null) { + _contentProgressTimer = Timer.periodic( + const Duration(milliseconds: 200), + (Timer timer) async { + if (_contentVideoController.value.isInitialized) { + final Duration? progress = await _contentVideoController.position; + if (progress != null) { + await _contentProgressProvider.setProgress( + progress: progress, + duration: _contentVideoController.value.duration, + ); + } + } + }, + ); + } + + await _contentVideoController.play(); +} + +Future _pauseContent() { + setState(() { + _shouldShowContentVideo = false; + }); + _contentProgressTimer?.cancel(); + _contentProgressTimer = null; + return _contentVideoController.pause(); +} +``` + +### 7. Dispose Resources + +Dispose the content player and destroy the [AdsManager][6]. + + +```dart +@override +void dispose() { + super.dispose(); + _contentProgressTimer?.cancel(); + _contentVideoController.dispose(); + _adsManager?.destroy(); + // ··· +} +``` + +That's it! You're now requesting and displaying ads with the IMA SDK. To learn about additional SDK +features, see the [API reference](https://pub.dev/documentation/interactive_media_ads/latest/). + +## Contributing + +For information on contributing to this plugin, see [`CONTRIBUTING.md`](CONTRIBUTING.md). [1]: https://developers.google.com/interactive-media-ads +[2]: https://www.iab.com/guidelines/vast/ +[3]: https://pub.dev/documentation/interactive_media_ads/latest/interactive_media_ads/AdDisplayContainer-class.html +[4]: https://pub.dev/documentation/interactive_media_ads/latest/interactive_media_ads/AdsLoader-class.html +[5]: https://pub.dev/documentation/interactive_media_ads/latest/interactive_media_ads/AdsRequest-class.html +[6]: https://pub.dev/documentation/interactive_media_ads/latest/interactive_media_ads/AdsManager-class.html +[7]: https://pub.dev/packages/video_player +[8]: https://pub.dev/documentation/interactive_media_ads/latest/interactive_media_ads/AdsManagerDelegate-class.html diff --git a/packages/interactive_media_ads/android/build.gradle b/packages/interactive_media_ads/android/build.gradle index eab18ff2d763..9c57c1ff7cec 100644 --- a/packages/interactive_media_ads/android/build.gradle +++ b/packages/interactive_media_ads/android/build.gradle @@ -25,19 +25,17 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' android { - if (project.android.hasProperty("namespace")) { - namespace 'dev.flutter.packages.interactive_media_ads' - } + namespace 'dev.flutter.packages.interactive_media_ads' compileSdk 34 compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '11' } sourceSets { @@ -46,13 +44,15 @@ android { } defaultConfig { - minSdk 19 + minSdk 21 } dependencies { - implementation 'androidx.annotation:annotation:1.8.0' + implementation 'androidx.annotation:annotation:1.8.2' + implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.35.1' testImplementation 'junit:junit:4.13.2' testImplementation 'org.jetbrains.kotlin:kotlin-test' + testImplementation "org.mockito.kotlin:mockito-kotlin:4.1.0" testImplementation 'org.mockito:mockito-inline:5.1.0' testImplementation 'androidx.test:core:1.3.0' } @@ -60,7 +60,7 @@ android { lintOptions { checkAllWarnings true warningsAsErrors true - disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency' + disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency', 'NewerVersionAvailable' } testOptions { diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdDisplayContainerProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdDisplayContainerProxyApi.kt new file mode 100644 index 000000000000..225abe612669 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdDisplayContainerProxyApi.kt @@ -0,0 +1,14 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +/** + * ProxyApi implementation for [com.google.ads.interactivemedia.v3.api.AdDisplayContainer]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class AdDisplayContainerProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiAdDisplayContainer(pigeonRegistrar) diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdErrorEventProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdErrorEventProxyApi.kt new file mode 100644 index 000000000000..63e52492cd8c --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdErrorEventProxyApi.kt @@ -0,0 +1,21 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdError +import com.google.ads.interactivemedia.v3.api.AdErrorEvent + +/** + * ProxyApi implementation for [AdErrorEvent]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class AdErrorEventProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiAdErrorEvent(pigeonRegistrar) { + override fun error(pigeon_instance: AdErrorEvent): AdError { + return pigeon_instance.error + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdErrorListenerProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdErrorListenerProxyApi.kt new file mode 100644 index 000000000000..0fc8ee253333 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdErrorListenerProxyApi.kt @@ -0,0 +1,27 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdErrorEvent + +/** + * ProxyApi implementation for [AdErrorEvent.AdErrorListener]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class AdErrorListenerProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiAdErrorListener(pigeonRegistrar) { + internal class AdErrorListenerImpl(val api: AdErrorListenerProxyApi) : + AdErrorEvent.AdErrorListener { + override fun onAdError(event: AdErrorEvent) { + api.pigeonRegistrar.runOnMainThread { api.onAdError(this, event) {} } + } + } + + override fun pigeon_defaultConstructor(): AdErrorEvent.AdErrorListener { + return AdErrorListenerImpl(this) + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdErrorProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdErrorProxyApi.kt new file mode 100644 index 000000000000..5e06fe2c3b70 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdErrorProxyApi.kt @@ -0,0 +1,61 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdError + +/** + * ProxyApi implementation for [AdError]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class AdErrorProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiAdError(pigeonRegistrar) { + override fun errorCode(pigeon_instance: AdError): AdErrorCode { + return when (pigeon_instance.errorCode) { + AdError.AdErrorCode.ADS_PLAYER_NOT_PROVIDED -> AdErrorCode.ADS_PLAYER_WAS_NOT_PROVIDED + AdError.AdErrorCode.INTERNAL_ERROR -> AdErrorCode.INTERNAL_ERROR + AdError.AdErrorCode.VAST_MALFORMED_RESPONSE -> AdErrorCode.VAST_MALFORMED_RESPONSE + AdError.AdErrorCode.UNKNOWN_AD_RESPONSE -> AdErrorCode.UNKNOWN_AD_RESPONSE + AdError.AdErrorCode.VAST_TRAFFICKING_ERROR -> AdErrorCode.VAST_TRAFFICKING_ERROR + AdError.AdErrorCode.VAST_LOAD_TIMEOUT -> AdErrorCode.VAST_LOAD_TIMEOUT + AdError.AdErrorCode.VAST_TOO_MANY_REDIRECTS -> AdErrorCode.VAST_TOO_MANY_REDIRECTS + AdError.AdErrorCode.VAST_NO_ADS_AFTER_WRAPPER -> AdErrorCode.VAST_NO_ADS_AFTER_WRAPPER + AdError.AdErrorCode.VIDEO_PLAY_ERROR -> AdErrorCode.VIDEO_PLAY_ERROR + AdError.AdErrorCode.VAST_MEDIA_LOAD_TIMEOUT -> AdErrorCode.VAST_MEDIA_LOAD_TIMEOUT + AdError.AdErrorCode.VAST_LINEAR_ASSET_MISMATCH -> AdErrorCode.VAST_LINEAR_ASSET_MISMATCH + AdError.AdErrorCode.OVERLAY_AD_PLAYING_FAILED -> AdErrorCode.OVERLAY_AD_PLAYING_FAILED + AdError.AdErrorCode.OVERLAY_AD_LOADING_FAILED -> AdErrorCode.OVERLAY_AD_LOADING_FAILED + AdError.AdErrorCode.VAST_NONLINEAR_ASSET_MISMATCH -> AdErrorCode.VAST_NONLINEAR_ASSET_MISMATCH + AdError.AdErrorCode.COMPANION_AD_LOADING_FAILED -> AdErrorCode.COMPANION_AD_LOADING_FAILED + AdError.AdErrorCode.UNKNOWN_ERROR -> AdErrorCode.UNKNOWN_ERROR + AdError.AdErrorCode.VAST_EMPTY_RESPONSE -> AdErrorCode.VAST_EMPTY_RESPONSE + AdError.AdErrorCode.FAILED_TO_REQUEST_ADS -> AdErrorCode.FAILED_TO_REQUEST_ADS + AdError.AdErrorCode.VAST_ASSET_NOT_FOUND -> AdErrorCode.VAST_ASSET_NOT_FOUND + AdError.AdErrorCode.ADS_REQUEST_NETWORK_ERROR -> AdErrorCode.ADS_REQUEST_NETWORK_ERROR + AdError.AdErrorCode.INVALID_ARGUMENTS -> AdErrorCode.INVALID_ARGUMENTS + AdError.AdErrorCode.PLAYLIST_NO_CONTENT_TRACKING -> AdErrorCode.PLAYLIST_NO_CONTENT_TRACKING + AdError.AdErrorCode.UNEXPECTED_ADS_LOADED_EVENT -> AdErrorCode.UNEXPECTED_ADS_LOADED_EVENT + else -> AdErrorCode.UNKNOWN + } + } + + override fun errorCodeNumber(pigeon_instance: AdError): Long { + return pigeon_instance.errorCodeNumber.toLong() + } + + override fun errorType(pigeon_instance: AdError): AdErrorType { + return when (pigeon_instance.errorType) { + AdError.AdErrorType.LOAD -> AdErrorType.LOAD + AdError.AdErrorType.PLAY -> AdErrorType.PLAY + else -> AdErrorType.UNKNOWN + } + } + + override fun message(pigeon_instance: AdError): String { + return pigeon_instance.message + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdEventListenerProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdEventListenerProxyApi.kt new file mode 100644 index 000000000000..9037799d1a89 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdEventListenerProxyApi.kt @@ -0,0 +1,26 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdEvent + +/** + * ProxyApi implementation for [AdEvent.AdEventListener]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class AdEventListenerProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiAdEventListener(pigeonRegistrar) { + internal class AdEventListenerImpl(val api: AdEventListenerProxyApi) : AdEvent.AdEventListener { + override fun onAdEvent(event: AdEvent) { + api.pigeonRegistrar.runOnMainThread { api.onAdEvent(this, event) {} } + } + } + + override fun pigeon_defaultConstructor(): AdEvent.AdEventListener { + return AdEventListenerImpl(this) + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdEventProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdEventProxyApi.kt new file mode 100644 index 000000000000..8cbf527a3751 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdEventProxyApi.kt @@ -0,0 +1,53 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdEvent + +/** + * ProxyApi implementation for [AdEvent]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class AdEventProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiAdEvent(pigeonRegistrar) { + override fun type(pigeon_instance: AdEvent): AdEventType { + return when (pigeon_instance.type) { + AdEvent.AdEventType.ALL_ADS_COMPLETED -> AdEventType.ALL_ADS_COMPLETED + AdEvent.AdEventType.AD_BREAK_FETCH_ERROR -> AdEventType.AD_BREAK_FETCH_ERROR + AdEvent.AdEventType.CLICKED -> AdEventType.CLICKED + AdEvent.AdEventType.COMPLETED -> AdEventType.COMPLETED + AdEvent.AdEventType.CUEPOINTS_CHANGED -> AdEventType.CUEPOINTS_CHANGED + AdEvent.AdEventType.CONTENT_PAUSE_REQUESTED -> AdEventType.CONTENT_PAUSE_REQUESTED + AdEvent.AdEventType.CONTENT_RESUME_REQUESTED -> AdEventType.CONTENT_RESUME_REQUESTED + AdEvent.AdEventType.FIRST_QUARTILE -> AdEventType.FIRST_QUARTILE + AdEvent.AdEventType.LOG -> AdEventType.LOG + AdEvent.AdEventType.AD_BREAK_READY -> AdEventType.AD_BREAK_READY + AdEvent.AdEventType.MIDPOINT -> AdEventType.MIDPOINT + AdEvent.AdEventType.PAUSED -> AdEventType.PAUSED + AdEvent.AdEventType.RESUMED -> AdEventType.RESUMED + AdEvent.AdEventType.SKIPPABLE_STATE_CHANGED -> AdEventType.SKIPPABLE_STATE_CHANGED + AdEvent.AdEventType.SKIPPED -> AdEventType.SKIPPED + AdEvent.AdEventType.STARTED -> AdEventType.STARTED + AdEvent.AdEventType.TAPPED -> AdEventType.TAPPED + AdEvent.AdEventType.ICON_TAPPED -> AdEventType.ICON_TAPPED + AdEvent.AdEventType.ICON_FALLBACK_IMAGE_CLOSED -> AdEventType.ICON_FALLBACK_IMAGE_CLOSED + AdEvent.AdEventType.THIRD_QUARTILE -> AdEventType.THIRD_QUARTILE + AdEvent.AdEventType.LOADED -> AdEventType.LOADED + AdEvent.AdEventType.AD_PROGRESS -> AdEventType.AD_PROGRESS + AdEvent.AdEventType.AD_BUFFERING -> AdEventType.AD_BUFFERING + AdEvent.AdEventType.AD_BREAK_STARTED -> AdEventType.AD_BREAK_STARTED + AdEvent.AdEventType.AD_BREAK_ENDED -> AdEventType.AD_BREAK_ENDED + AdEvent.AdEventType.AD_PERIOD_STARTED -> AdEventType.AD_PERIOD_STARTED + AdEvent.AdEventType.AD_PERIOD_ENDED -> AdEventType.AD_PERIOD_ENDED + else -> AdEventType.UNKNOWN + } + } + + override fun adData(pigeon_instance: AdEvent): Map? { + return pigeon_instance.adData + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdMediaInfoProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdMediaInfoProxyApi.kt new file mode 100644 index 000000000000..cb1e03500b12 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdMediaInfoProxyApi.kt @@ -0,0 +1,20 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.player.AdMediaInfo + +/** + * ProxyApi implementation for [AdMediaInfo]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class AdMediaInfoProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiAdMediaInfo(pigeonRegistrar) { + override fun url(pigeon_instance: AdMediaInfo): String { + return pigeon_instance.url + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdPodInfoProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdPodInfoProxyApi.kt new file mode 100644 index 000000000000..367d5f5416a2 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdPodInfoProxyApi.kt @@ -0,0 +1,40 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdPodInfo + +/** + * ProxyApi implementation for [AdPodInfo]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class AdPodInfoProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiAdPodInfo(pigeonRegistrar) { + override fun adPosition(pigeon_instance: AdPodInfo): Long { + return pigeon_instance.adPosition.toLong() + } + + override fun maxDuration(pigeon_instance: AdPodInfo): Double { + return pigeon_instance.maxDuration + } + + override fun podIndex(pigeon_instance: AdPodInfo): Long { + return pigeon_instance.podIndex.toLong() + } + + override fun timeOffset(pigeon_instance: AdPodInfo): Double { + return pigeon_instance.timeOffset + } + + override fun totalAds(pigeon_instance: AdPodInfo): Long { + return pigeon_instance.totalAds.toLong() + } + + override fun isBumper(pigeon_instance: AdPodInfo): Boolean { + return pigeon_instance.isBumper + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdProgressInfoProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdProgressInfoProxyApi.kt new file mode 100644 index 000000000000..51fbf0c54e40 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdProgressInfoProxyApi.kt @@ -0,0 +1,41 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdProgressInfo + +/** + * ProxyApi implementation for [AdProgressInfo]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class AdProgressInfoProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiAdProgressInfo(pigeonRegistrar) { + + override fun adBreakDuration(pigeon_instance: AdProgressInfo): Double { + return pigeon_instance.adBreakDuration + } + + override fun adPeriodDuration(pigeon_instance: AdProgressInfo): Double { + return pigeon_instance.adPeriodDuration + } + + override fun adPosition(pigeon_instance: AdProgressInfo): Long { + return pigeon_instance.adPosition.toLong() + } + + override fun currentTime(pigeon_instance: AdProgressInfo): Double { + return pigeon_instance.currentTime + } + + override fun duration(pigeon_instance: AdProgressInfo): Double { + return pigeon_instance.duration + } + + override fun totalAds(pigeon_instance: AdProgressInfo): Long { + return pigeon_instance.totalAds.toLong() + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdProxyApi.kt new file mode 100644 index 000000000000..11c77bce8750 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdProxyApi.kt @@ -0,0 +1,132 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.Ad +import com.google.ads.interactivemedia.v3.api.AdPodInfo +import com.google.ads.interactivemedia.v3.api.CompanionAd +import com.google.ads.interactivemedia.v3.api.UniversalAdId + +/** + * ProxyApi implementation for [Ad]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class AdProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : PigeonApiAd(pigeonRegistrar) { + override fun adId(pigeon_instance: Ad): String { + return pigeon_instance.adId + } + + override fun adPodInfo(pigeon_instance: Ad): AdPodInfo { + return pigeon_instance.adPodInfo + } + + override fun adSystem(pigeon_instance: Ad): String { + return pigeon_instance.adSystem + } + + override fun adWrapperCreativeIds(pigeon_instance: Ad): List { + return pigeon_instance.adWrapperCreativeIds.asList() + } + + override fun adWrapperIds(pigeon_instance: Ad): List { + return pigeon_instance.adWrapperIds.asList() + } + + override fun adWrapperSystems(pigeon_instance: Ad): List { + return pigeon_instance.adWrapperSystems.asList() + } + + override fun advertiserName(pigeon_instance: Ad): String { + return pigeon_instance.advertiserName + } + + override fun companionAds(pigeon_instance: Ad): List { + return pigeon_instance.companionAds + } + + override fun contentType(pigeon_instance: Ad): String? { + return pigeon_instance.contentType + } + + override fun creativeAdId(pigeon_instance: Ad): String { + return pigeon_instance.creativeAdId + } + + override fun creativeId(pigeon_instance: Ad): String { + return pigeon_instance.creativeId + } + + override fun dealId(pigeon_instance: Ad): String { + return pigeon_instance.dealId + } + + override fun description(pigeon_instance: Ad): String? { + return pigeon_instance.description + } + + override fun duration(pigeon_instance: Ad): Double { + return pigeon_instance.duration + } + + override fun height(pigeon_instance: Ad): Long { + return pigeon_instance.height.toLong() + } + + override fun skipTimeOffset(pigeon_instance: Ad): Double { + return pigeon_instance.skipTimeOffset + } + + override fun surveyUrl(pigeon_instance: Ad): String? { + return pigeon_instance.surveyUrl + } + + override fun title(pigeon_instance: Ad): String? { + return pigeon_instance.title + } + + override fun traffickingParameters(pigeon_instance: Ad): String { + return pigeon_instance.traffickingParameters + } + + override fun uiElements(pigeon_instance: Ad): List { + return pigeon_instance.uiElements.map { + when (it) { + com.google.ads.interactivemedia.v3.api.UiElement.AD_ATTRIBUTION -> UiElement.AD_ATTRIBUTION + com.google.ads.interactivemedia.v3.api.UiElement.COUNTDOWN -> UiElement.COUNTDOWN + else -> UiElement.UNKNOWN + } + } + } + + override fun universalAdIds(pigeon_instance: Ad): List { + return pigeon_instance.universalAdIds.toList() + } + + override fun vastMediaBitrate(pigeon_instance: Ad): Long { + return pigeon_instance.vastMediaBitrate.toLong() + } + + override fun vastMediaHeight(pigeon_instance: Ad): Long { + return pigeon_instance.vastMediaHeight.toLong() + } + + override fun vastMediaWidth(pigeon_instance: Ad): Long { + return pigeon_instance.vastMediaWidth.toLong() + } + + override fun width(pigeon_instance: Ad): Long { + return pigeon_instance.width.toLong() + } + + override fun isLinear(pigeon_instance: Ad): Boolean { + return pigeon_instance.isLinear + } + + override fun isSkippable(pigeon_instance: Ad): Boolean { + return pigeon_instance.isSkippable + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsLoadedListenerProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsLoadedListenerProxyApi.kt new file mode 100644 index 000000000000..2054e84dac34 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsLoadedListenerProxyApi.kt @@ -0,0 +1,28 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdsLoader +import com.google.ads.interactivemedia.v3.api.AdsManagerLoadedEvent + +/** + * ProxyApi implementation for [AdsLoader.AdsLoadedListener]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class AdsLoadedListenerProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiAdsLoadedListener(pigeonRegistrar) { + internal class AdsLoadedListenerImpl(val api: AdsLoadedListenerProxyApi) : + AdsLoader.AdsLoadedListener { + override fun onAdsManagerLoaded(event: AdsManagerLoadedEvent) { + api.pigeonRegistrar.runOnMainThread { api.onAdsManagerLoaded(this, event) {} } + } + } + + override fun pigeon_defaultConstructor(): AdsLoader.AdsLoadedListener { + return AdsLoadedListenerImpl(this) + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsLoaderProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsLoaderProxyApi.kt new file mode 100644 index 000000000000..5b5d1d7721e8 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsLoaderProxyApi.kt @@ -0,0 +1,36 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdErrorEvent +import com.google.ads.interactivemedia.v3.api.AdsLoader +import com.google.ads.interactivemedia.v3.api.AdsRequest + +/** + * ProxyApi implementation for [AdsLoader]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class AdsLoaderProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiAdsLoader(pigeonRegistrar) { + override fun addAdErrorListener( + pigeon_instance: AdsLoader, + listener: AdErrorEvent.AdErrorListener + ) { + pigeon_instance.addAdErrorListener(listener) + } + + override fun addAdsLoadedListener( + pigeon_instance: AdsLoader, + listener: AdsLoader.AdsLoadedListener + ) { + pigeon_instance.addAdsLoadedListener(listener) + } + + override fun requestAds(pigeon_instance: AdsLoader, request: AdsRequest) { + pigeon_instance.requestAds(request) + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsManagerLoadedEventProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsManagerLoadedEventProxyApi.kt new file mode 100644 index 000000000000..1374ecde4a12 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsManagerLoadedEventProxyApi.kt @@ -0,0 +1,21 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdsManager +import com.google.ads.interactivemedia.v3.api.AdsManagerLoadedEvent + +/** + * ProxyApi implementation for [AdsManagerLoadedEvent]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class AdsManagerLoadedEventProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiAdsManagerLoadedEvent(pigeonRegistrar) { + override fun manager(pigeon_instance: AdsManagerLoadedEvent): AdsManager { + return pigeon_instance.adsManager + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsManagerProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsManagerProxyApi.kt new file mode 100644 index 000000000000..11d7250c88c1 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsManagerProxyApi.kt @@ -0,0 +1,40 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdsManager + +/** + * ProxyApi implementation for [AdsManager]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class AdsManagerProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiAdsManager(pigeonRegistrar) { + override fun discardAdBreak(pigeon_instance: AdsManager) { + pigeon_instance.discardAdBreak() + } + + override fun pause(pigeon_instance: AdsManager) { + pigeon_instance.pause() + } + + override fun start(pigeon_instance: AdsManager) { + pigeon_instance.start() + } + + override fun getAdCuePoints(pigeon_instance: AdsManager): List { + return pigeon_instance.adCuePoints.map { it.toDouble() } + } + + override fun resume(pigeon_instance: AdsManager) { + pigeon_instance.resume() + } + + override fun skip(pigeon_instance: AdsManager) { + pigeon_instance.skip() + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsRenderingSettingsProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsRenderingSettingsProxyApi.kt new file mode 100644 index 000000000000..d924ad43f783 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsRenderingSettingsProxyApi.kt @@ -0,0 +1,91 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdsRenderingSettings +import com.google.ads.interactivemedia.v3.api.UiElement + +/** + * ProxyApi implementation for [AdsRenderingSettings]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class AdsRenderingSettingsProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiAdsRenderingSettings(pigeonRegistrar) { + override fun getBitrateKbps(pigeon_instance: AdsRenderingSettings): Long { + return pigeon_instance.bitrateKbps.toLong() + } + + override fun getEnableCustomTabs(pigeon_instance: AdsRenderingSettings): Boolean { + return pigeon_instance.enableCustomTabs + } + + override fun getEnablePreloading(pigeon_instance: AdsRenderingSettings): Boolean { + return pigeon_instance.enablePreloading + } + + override fun getFocusSkipButtonWhenAvailable(pigeon_instance: AdsRenderingSettings): Boolean { + return pigeon_instance.focusSkipButtonWhenAvailable + } + + override fun getMimeTypes(pigeon_instance: AdsRenderingSettings): List { + return pigeon_instance.mimeTypes + } + + override fun setBitrateKbps(pigeon_instance: AdsRenderingSettings, bitrate: Long) { + pigeon_instance.bitrateKbps = bitrate.toInt() + } + + override fun setEnableCustomTabs( + pigeon_instance: AdsRenderingSettings, + enableCustomTabs: Boolean + ) { + pigeon_instance.enableCustomTabs = enableCustomTabs + } + + override fun setEnablePreloading( + pigeon_instance: AdsRenderingSettings, + enablePreloading: Boolean + ) { + pigeon_instance.enablePreloading = enablePreloading + } + + override fun setFocusSkipButtonWhenAvailable( + pigeon_instance: AdsRenderingSettings, + enableFocusSkipButton: Boolean + ) { + pigeon_instance.focusSkipButtonWhenAvailable = enableFocusSkipButton + } + + override fun setLoadVideoTimeout(pigeon_instance: AdsRenderingSettings, loadVideoTimeout: Long) { + pigeon_instance.setLoadVideoTimeout(loadVideoTimeout.toInt()) + } + + override fun setMimeTypes(pigeon_instance: AdsRenderingSettings, mimeTypes: List) { + pigeon_instance.mimeTypes = mimeTypes + } + + override fun setPlayAdsAfterTime(pigeon_instance: AdsRenderingSettings, time: Double) { + pigeon_instance.setPlayAdsAfterTime(time) + } + + override fun setUiElements( + pigeon_instance: AdsRenderingSettings, + uiElements: List + ) { + val nativeUiElements = + uiElements.map { + when (it) { + dev.flutter.packages.interactive_media_ads.UiElement.AD_ATTRIBUTION -> + UiElement.AD_ATTRIBUTION + dev.flutter.packages.interactive_media_ads.UiElement.COUNTDOWN -> UiElement.COUNTDOWN + dev.flutter.packages.interactive_media_ads.UiElement.UNKNOWN -> + throw UnsupportedOperationException("$it is not supported.") + } + } + pigeon_instance.setUiElements(nativeUiElements.toSet()) + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsRequestProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsRequestProxyApi.kt new file mode 100644 index 000000000000..5d14b8a72db3 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsRequestProxyApi.kt @@ -0,0 +1,41 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdsRequest +import com.google.ads.interactivemedia.v3.api.player.ContentProgressProvider + +/** + * ProxyApi implementation for [AdsRequest]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class AdsRequestProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiAdsRequest(pigeonRegistrar) { + companion object { + /** + * The current version of the `interactive_media_ads` plugin. + * + * This must match the version in pubspec.yaml. + */ + const val pluginVersion = "0.2.2+15" + } + + override fun setAdTagUrl(pigeon_instance: AdsRequest, adTagUrl: String) { + // Ensure adTag can append a custom parameter. + require(adTagUrl.contains("?")) + require(!adTagUrl.contains("#")) + + pigeon_instance.adTagUrl = "$adTagUrl&request_agent=Flutter-IMA-$pluginVersion" + } + + override fun setContentProgressProvider( + pigeon_instance: AdsRequest, + provider: ContentProgressProvider + ) { + pigeon_instance.contentProgressProvider = provider + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/BaseDisplayContainerProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/BaseDisplayContainerProxyApi.kt new file mode 100644 index 000000000000..6499138ad9cf --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/BaseDisplayContainerProxyApi.kt @@ -0,0 +1,14 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +/** + * ProxyApi implementation for [com.google.ads.interactivemedia.v3.api.BaseDisplayContainer]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class BaseDisplayContainerProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiBaseDisplayContainer(pigeonRegistrar) diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/BaseManagerProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/BaseManagerProxyApi.kt new file mode 100644 index 000000000000..a227cf916c02 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/BaseManagerProxyApi.kt @@ -0,0 +1,73 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.Ad +import com.google.ads.interactivemedia.v3.api.AdErrorEvent +import com.google.ads.interactivemedia.v3.api.AdEvent +import com.google.ads.interactivemedia.v3.api.AdProgressInfo +import com.google.ads.interactivemedia.v3.api.AdsRenderingSettings +import com.google.ads.interactivemedia.v3.api.BaseManager + +/** + * ProxyApi implementation for [BaseManager]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class BaseManagerProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiBaseManager(pigeonRegistrar) { + override fun addAdErrorListener( + pigeon_instance: BaseManager, + errorListener: AdErrorEvent.AdErrorListener + ) { + pigeon_instance.addAdErrorListener(errorListener) + } + + override fun addAdEventListener( + pigeon_instance: BaseManager, + adEventListener: AdEvent.AdEventListener + ) { + pigeon_instance.addAdEventListener(adEventListener) + } + + override fun destroy(pigeon_instance: BaseManager) { + pigeon_instance.destroy() + } + + override fun init(pigeon_instance: BaseManager, settings: AdsRenderingSettings?) { + if (settings == null) { + pigeon_instance.init() + } else { + pigeon_instance.init(settings) + } + } + + override fun focus(pigeon_instance: BaseManager) { + pigeon_instance.focus() + } + + override fun getAdProgressInfo(pigeon_instance: BaseManager): AdProgressInfo? { + return pigeon_instance.adProgressInfo + } + + override fun getCurrentAd(pigeon_instance: BaseManager): Ad? { + return pigeon_instance.currentAd + } + + override fun removeAdErrorListener( + pigeon_instance: BaseManager, + errorListener: AdErrorEvent.AdErrorListener + ) { + pigeon_instance.removeAdErrorListener(errorListener) + } + + override fun removeAdEventListener( + pigeon_instance: BaseManager, + adEventListener: AdEvent.AdEventListener + ) { + pigeon_instance.removeAdEventListener(adEventListener) + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/CompanionAdProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/CompanionAdProxyApi.kt new file mode 100644 index 000000000000..06b805c840f5 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/CompanionAdProxyApi.kt @@ -0,0 +1,32 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.CompanionAd + +/** + * ProxyApi implementation for [CompanionAd]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class CompanionAdProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiCompanionAd(pigeonRegistrar) { + override fun apiFramework(pigeon_instance: CompanionAd): String? { + return pigeon_instance.apiFramework + } + + override fun height(pigeon_instance: CompanionAd): Long { + return pigeon_instance.height.toLong() + } + + override fun resourceValue(pigeon_instance: CompanionAd): String { + return pigeon_instance.resourceValue + } + + override fun width(pigeon_instance: CompanionAd): Long { + return pigeon_instance.width.toLong() + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ContentProgressProviderProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ContentProgressProviderProxyApi.kt new file mode 100644 index 000000000000..de942c05aa3c --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ContentProgressProviderProxyApi.kt @@ -0,0 +1,37 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.player.ContentProgressProvider +import com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate + +/** + * ProxyApi implementation for [ContentProgressProvider]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class ContentProgressProviderProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiContentProgressProvider(pigeonRegistrar) { + internal class ContentProgressProviderImpl(val api: ContentProgressProviderProxyApi) : + ContentProgressProvider { + var currentProgress = VideoProgressUpdate.VIDEO_TIME_NOT_READY + + override fun getContentProgress(): VideoProgressUpdate { + return currentProgress + } + } + + override fun pigeon_defaultConstructor(): ContentProgressProvider { + return ContentProgressProviderImpl(this) + } + + override fun setContentProgress( + pigeon_instance: ContentProgressProvider, + update: VideoProgressUpdate + ) { + (pigeon_instance as ContentProgressProviderImpl).currentProgress = update + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/FrameLayoutProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/FrameLayoutProxyApi.kt new file mode 100644 index 000000000000..c2d6ee342787 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/FrameLayoutProxyApi.kt @@ -0,0 +1,20 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import android.widget.FrameLayout + +/** + * ProxyApi implementation for [FrameLayout]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class FrameLayoutProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiFrameLayout(pigeonRegistrar) { + override fun pigeon_defaultConstructor(): FrameLayout { + return FrameLayout(pigeonRegistrar.context) + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ImaSdkFactoryProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ImaSdkFactoryProxyApi.kt new file mode 100644 index 000000000000..eaed1baabe25 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ImaSdkFactoryProxyApi.kt @@ -0,0 +1,49 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import android.view.ViewGroup +import com.google.ads.interactivemedia.v3.api.AdDisplayContainer +import com.google.ads.interactivemedia.v3.api.AdsLoader +import com.google.ads.interactivemedia.v3.api.AdsRequest +import com.google.ads.interactivemedia.v3.api.ImaSdkFactory +import com.google.ads.interactivemedia.v3.api.ImaSdkSettings +import com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer + +/** + * ProxyApi implementation for [ImaSdkFactory]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class ImaSdkFactoryProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiImaSdkFactory(pigeonRegistrar) { + override fun instance(): ImaSdkFactory { + return ImaSdkFactory.getInstance() + } + + override fun createAdDisplayContainer( + container: ViewGroup, + player: VideoAdPlayer + ): AdDisplayContainer { + return ImaSdkFactory.createAdDisplayContainer(container, player) + } + + override fun createImaSdkSettings(pigeon_instance: ImaSdkFactory): ImaSdkSettings { + return pigeon_instance.createImaSdkSettings() + } + + override fun createAdsLoader( + pigeon_instance: ImaSdkFactory, + settings: ImaSdkSettings, + container: AdDisplayContainer + ): AdsLoader { + return pigeon_instance.createAdsLoader(pigeonRegistrar.context, settings, container) + } + + override fun createAdsRequest(pigeon_instance: ImaSdkFactory): AdsRequest { + return pigeon_instance.createAdsRequest() + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ImaSdkSettingsProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ImaSdkSettingsProxyApi.kt new file mode 100644 index 000000000000..c95fd1d71e02 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ImaSdkSettingsProxyApi.kt @@ -0,0 +1,14 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +/** + * ProxyApi implementation for [com.google.ads.interactivemedia.v3.api.ImaSdkSettings]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class ImaSdkSettingsProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiImaSdkSettings(pigeonRegistrar) diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/InteractiveMediaAdsLibrary.g.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/InteractiveMediaAdsLibrary.g.kt new file mode 100644 index 000000000000..b42ee9d2fd5b --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/InteractiveMediaAdsLibrary.g.kt @@ -0,0 +1,5268 @@ +// 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 (v22.5.0), do not edit directly. +// See also: https://pub.dev/packages/pigeon +@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass", "SyntheticAccessor") + +package dev.flutter.packages.interactive_media_ads + +import android.util.Log +import io.flutter.plugin.common.BasicMessageChannel +import io.flutter.plugin.common.BinaryMessenger +import io.flutter.plugin.common.MessageCodec +import io.flutter.plugin.common.StandardMessageCodec +import java.io.ByteArrayOutputStream +import java.nio.ByteBuffer + +private fun wrapResult(result: Any?): List { + return listOf(result) +} + +private fun wrapError(exception: Throwable): List { + return if (exception is FlutterError) { + listOf(exception.code, exception.message, exception.details) + } else { + listOf( + exception.javaClass.simpleName, + exception.toString(), + "Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception)) + } +} + +private fun createConnectionError(channelName: String): FlutterError { + return FlutterError( + "channel-error", "Unable to establish connection on channel: '$channelName'.", "") +} + +/** + * Error class for passing custom error details to Flutter via a thrown PlatformException. + * + * @property code The error code. + * @property message The error message. + * @property details The error details. Must be a datatype supported by the api codec. + */ +class FlutterError( + val code: String, + override val message: String? = null, + val details: Any? = null +) : Throwable() +/** + * Maintains instances used to communicate with the corresponding objects in Dart. + * + * Objects stored in this container are represented by an object in Dart that is also stored in an + * InstanceManager with the same identifier. + * + * When an instance is added with an identifier, either can be used to retrieve the other. + * + * Added instances are added as a weak reference and a strong reference. When the strong reference + * is removed with [remove] and the weak reference is deallocated, the + * `finalizationListener.onFinalize` is called with the instance's identifier. However, if the + * strong reference is removed and then the identifier is retrieved with the intention to pass the + * identifier to Dart (e.g. calling [getIdentifierForStrongReference]), the strong reference to the + * instance is recreated. The strong reference will then need to be removed manually again. + */ +@Suppress("UNCHECKED_CAST", "MemberVisibilityCanBePrivate") +class InteractiveMediaAdsLibraryPigeonInstanceManager( + private val finalizationListener: PigeonFinalizationListener +) { + /** Interface for listening when a weak reference of an instance is removed from the manager. */ + interface PigeonFinalizationListener { + fun onFinalize(identifier: Long) + } + + private val identifiers = java.util.WeakHashMap() + private val weakInstances = HashMap>() + private val strongInstances = HashMap() + private val referenceQueue = java.lang.ref.ReferenceQueue() + private val weakReferencesToIdentifiers = HashMap, Long>() + private val handler = android.os.Handler(android.os.Looper.getMainLooper()) + private var nextIdentifier: Long = minHostCreatedIdentifier + private var hasFinalizationListenerStopped = false + + /** + * Modifies the time interval used to define how often this instance removes garbage collected + * weak references to native Android objects that this instance was managing. + */ + var clearFinalizedWeakReferencesInterval: Long = 3000 + set(value) { + handler.removeCallbacks { this.releaseAllFinalizedInstances() } + field = value + releaseAllFinalizedInstances() + } + + init { + handler.postDelayed({ releaseAllFinalizedInstances() }, clearFinalizedWeakReferencesInterval) + } + + companion object { + // Identifiers are locked to a specific range to avoid collisions with objects + // created simultaneously from Dart. + // Host uses identifiers >= 2^16 and Dart is expected to use values n where, + // 0 <= n < 2^16. + private const val minHostCreatedIdentifier: Long = 65536 + private const val tag = "PigeonInstanceManager" + + /** + * Instantiate a new manager with a listener for garbage collected weak references. + * + * When the manager is no longer needed, [stopFinalizationListener] must be called. + */ + fun create( + finalizationListener: PigeonFinalizationListener + ): InteractiveMediaAdsLibraryPigeonInstanceManager { + return InteractiveMediaAdsLibraryPigeonInstanceManager(finalizationListener) + } + } + + /** + * Removes `identifier` and return its associated strongly referenced instance, if present, from + * the manager. + */ + fun remove(identifier: Long): T? { + logWarningIfFinalizationListenerHasStopped() + return strongInstances.remove(identifier) as T? + } + + /** + * Retrieves the identifier paired with an instance, if present, otherwise `null`. + * + * If the manager contains a strong reference to `instance`, it will return the identifier + * associated with `instance`. If the manager contains only a weak reference to `instance`, a new + * strong reference to `instance` will be added and will need to be removed again with [remove]. + * + * If this method returns a nonnull identifier, this method also expects the Dart + * `InteractiveMediaAdsLibraryPigeonInstanceManager` to have, or recreate, a weak reference to the + * Dart instance the identifier is associated with. + */ + fun getIdentifierForStrongReference(instance: Any?): Long? { + logWarningIfFinalizationListenerHasStopped() + val identifier = identifiers[instance] + if (identifier != null) { + strongInstances[identifier] = instance!! + } + return identifier + } + + /** + * Adds a new instance that was instantiated from Dart. + * + * The same instance can be added multiple times, but each identifier must be unique. This allows + * two objects that are equivalent (e.g. the `equals` method returns true and their hashcodes are + * equal) to both be added. + * + * [identifier] must be >= 0 and unique. + */ + fun addDartCreatedInstance(instance: Any, identifier: Long) { + logWarningIfFinalizationListenerHasStopped() + addInstance(instance, identifier) + } + + /** + * Adds a new unique instance that was instantiated from the host platform. + * + * [identifier] must be >= 0 and unique. + */ + fun addHostCreatedInstance(instance: Any): Long { + logWarningIfFinalizationListenerHasStopped() + require(!containsInstance(instance)) { + "Instance of ${instance.javaClass} has already been added." + } + val identifier = nextIdentifier++ + addInstance(instance, identifier) + return identifier + } + + /** Retrieves the instance associated with identifier, if present, otherwise `null`. */ + fun getInstance(identifier: Long): T? { + logWarningIfFinalizationListenerHasStopped() + val instance = weakInstances[identifier] as java.lang.ref.WeakReference? + return instance?.get() + } + + /** Returns whether this manager contains the given `instance`. */ + fun containsInstance(instance: Any?): Boolean { + logWarningIfFinalizationListenerHasStopped() + return identifiers.containsKey(instance) + } + + /** + * Stops the periodic run of the [PigeonFinalizationListener] for instances that have been garbage + * collected. + * + * The InstanceManager can continue to be used, but the [PigeonFinalizationListener] will no + * longer be called and methods will log a warning. + */ + fun stopFinalizationListener() { + handler.removeCallbacks { this.releaseAllFinalizedInstances() } + hasFinalizationListenerStopped = true + } + + /** + * Removes all of the instances from this manager. + * + * The manager will be empty after this call returns. + */ + fun clear() { + identifiers.clear() + weakInstances.clear() + strongInstances.clear() + weakReferencesToIdentifiers.clear() + } + + /** + * Whether the [PigeonFinalizationListener] is still being called for instances that are garbage + * collected. + * + * See [stopFinalizationListener]. + */ + fun hasFinalizationListenerStopped(): Boolean { + return hasFinalizationListenerStopped + } + + private fun releaseAllFinalizedInstances() { + if (hasFinalizationListenerStopped()) { + return + } + var reference: java.lang.ref.WeakReference? + while ((referenceQueue.poll() as java.lang.ref.WeakReference?).also { reference = it } != + null) { + val identifier = weakReferencesToIdentifiers.remove(reference) + if (identifier != null) { + weakInstances.remove(identifier) + strongInstances.remove(identifier) + finalizationListener.onFinalize(identifier) + } + } + handler.postDelayed({ releaseAllFinalizedInstances() }, clearFinalizedWeakReferencesInterval) + } + + private fun addInstance(instance: Any, identifier: Long) { + require(identifier >= 0) { "Identifier must be >= 0: $identifier" } + require(!weakInstances.containsKey(identifier)) { + "Identifier has already been added: $identifier" + } + val weakReference = java.lang.ref.WeakReference(instance, referenceQueue) + identifiers[instance] = identifier + weakInstances[identifier] = weakReference + weakReferencesToIdentifiers[weakReference] = identifier + strongInstances[identifier] = instance + } + + private fun logWarningIfFinalizationListenerHasStopped() { + if (hasFinalizationListenerStopped()) { + Log.w( + tag, + "The manager was used after calls to the PigeonFinalizationListener has been stopped.") + } + } +} + +/** Generated API for managing the Dart and native `InstanceManager`s. */ +private class InteractiveMediaAdsLibraryPigeonInstanceManagerApi( + val binaryMessenger: BinaryMessenger +) { + companion object { + /** The codec used by InteractiveMediaAdsLibraryPigeonInstanceManagerApi. */ + val codec: MessageCodec by lazy { InteractiveMediaAdsLibraryPigeonCodec() } + + /** + * Sets up an instance of `InteractiveMediaAdsLibraryPigeonInstanceManagerApi` to handle + * messages from the `binaryMessenger`. + */ + fun setUpMessageHandlers( + binaryMessenger: BinaryMessenger, + instanceManager: InteractiveMediaAdsLibraryPigeonInstanceManager? + ) { + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.PigeonInternalInstanceManager.removeStrongReference", + codec) + if (instanceManager != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val identifierArg = args[0] as Long + val wrapped: List = + try { + instanceManager.remove(identifierArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.PigeonInternalInstanceManager.clear", + codec) + if (instanceManager != null) { + channel.setMessageHandler { _, reply -> + val wrapped: List = + try { + instanceManager.clear() + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } + } + + fun removeStrongReference(identifierArg: Long, callback: (Result) -> Unit) { + val channelName = + "dev.flutter.pigeon.interactive_media_ads.PigeonInternalInstanceManager.removeStrongReference" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(identifierArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * Provides implementations for each ProxyApi implementation and provides access to resources needed + * by any implementation. + */ +abstract class InteractiveMediaAdsLibraryPigeonProxyApiRegistrar( + val binaryMessenger: BinaryMessenger +) { + /** Whether APIs should ignore calling to Dart. */ + public var ignoreCallsToDart = false + val instanceManager: InteractiveMediaAdsLibraryPigeonInstanceManager + private var _codec: MessageCodec? = null + val codec: MessageCodec + get() { + if (_codec == null) { + _codec = InteractiveMediaAdsLibraryPigeonProxyApiBaseCodec(this) + } + return _codec!! + } + + init { + val api = InteractiveMediaAdsLibraryPigeonInstanceManagerApi(binaryMessenger) + instanceManager = + InteractiveMediaAdsLibraryPigeonInstanceManager.create( + object : InteractiveMediaAdsLibraryPigeonInstanceManager.PigeonFinalizationListener { + override fun onFinalize(identifier: Long) { + api.removeStrongReference(identifier) { + if (it.isFailure) { + Log.e( + "PigeonProxyApiRegistrar", + "Failed to remove Dart strong reference with identifier: $identifier") + } + } + } + }) + } + /** + * An implementation of [PigeonApiBaseDisplayContainer] used to add a new Dart instance of + * `BaseDisplayContainer` to the Dart `InstanceManager`. + */ + open fun getPigeonApiBaseDisplayContainer(): PigeonApiBaseDisplayContainer { + return PigeonApiBaseDisplayContainer(this) + } + + /** + * An implementation of [PigeonApiAdDisplayContainer] used to add a new Dart instance of + * `AdDisplayContainer` to the Dart `InstanceManager`. + */ + open fun getPigeonApiAdDisplayContainer(): PigeonApiAdDisplayContainer { + return PigeonApiAdDisplayContainer(this) + } + + /** + * An implementation of [PigeonApiAdsLoader] used to add a new Dart instance of `AdsLoader` to the + * Dart `InstanceManager`. + */ + abstract fun getPigeonApiAdsLoader(): PigeonApiAdsLoader + + /** + * An implementation of [PigeonApiAdsManagerLoadedEvent] used to add a new Dart instance of + * `AdsManagerLoadedEvent` to the Dart `InstanceManager`. + */ + abstract fun getPigeonApiAdsManagerLoadedEvent(): PigeonApiAdsManagerLoadedEvent + + /** + * An implementation of [PigeonApiAdErrorEvent] used to add a new Dart instance of `AdErrorEvent` + * to the Dart `InstanceManager`. + */ + abstract fun getPigeonApiAdErrorEvent(): PigeonApiAdErrorEvent + + /** + * An implementation of [PigeonApiAdError] used to add a new Dart instance of `AdError` to the + * Dart `InstanceManager`. + */ + abstract fun getPigeonApiAdError(): PigeonApiAdError + + /** + * An implementation of [PigeonApiAdsRequest] used to add a new Dart instance of `AdsRequest` to + * the Dart `InstanceManager`. + */ + abstract fun getPigeonApiAdsRequest(): PigeonApiAdsRequest + + /** + * An implementation of [PigeonApiContentProgressProvider] used to add a new Dart instance of + * `ContentProgressProvider` to the Dart `InstanceManager`. + */ + abstract fun getPigeonApiContentProgressProvider(): PigeonApiContentProgressProvider + + /** + * An implementation of [PigeonApiAdsManager] used to add a new Dart instance of `AdsManager` to + * the Dart `InstanceManager`. + */ + abstract fun getPigeonApiAdsManager(): PigeonApiAdsManager + + /** + * An implementation of [PigeonApiBaseManager] used to add a new Dart instance of `BaseManager` to + * the Dart `InstanceManager`. + */ + abstract fun getPigeonApiBaseManager(): PigeonApiBaseManager + + /** + * An implementation of [PigeonApiAdEvent] used to add a new Dart instance of `AdEvent` to the + * Dart `InstanceManager`. + */ + abstract fun getPigeonApiAdEvent(): PigeonApiAdEvent + + /** + * An implementation of [PigeonApiImaSdkFactory] used to add a new Dart instance of + * `ImaSdkFactory` to the Dart `InstanceManager`. + */ + abstract fun getPigeonApiImaSdkFactory(): PigeonApiImaSdkFactory + + /** + * An implementation of [PigeonApiImaSdkSettings] used to add a new Dart instance of + * `ImaSdkSettings` to the Dart `InstanceManager`. + */ + open fun getPigeonApiImaSdkSettings(): PigeonApiImaSdkSettings { + return PigeonApiImaSdkSettings(this) + } + + /** + * An implementation of [PigeonApiVideoProgressUpdate] used to add a new Dart instance of + * `VideoProgressUpdate` to the Dart `InstanceManager`. + */ + abstract fun getPigeonApiVideoProgressUpdate(): PigeonApiVideoProgressUpdate + + /** + * An implementation of [PigeonApiAdMediaInfo] used to add a new Dart instance of `AdMediaInfo` to + * the Dart `InstanceManager`. + */ + abstract fun getPigeonApiAdMediaInfo(): PigeonApiAdMediaInfo + + /** + * An implementation of [PigeonApiAdPodInfo] used to add a new Dart instance of `AdPodInfo` to the + * Dart `InstanceManager`. + */ + abstract fun getPigeonApiAdPodInfo(): PigeonApiAdPodInfo + + /** + * An implementation of [PigeonApiFrameLayout] used to add a new Dart instance of `FrameLayout` to + * the Dart `InstanceManager`. + */ + abstract fun getPigeonApiFrameLayout(): PigeonApiFrameLayout + + /** + * An implementation of [PigeonApiViewGroup] used to add a new Dart instance of `ViewGroup` to the + * Dart `InstanceManager`. + */ + abstract fun getPigeonApiViewGroup(): PigeonApiViewGroup + + /** + * An implementation of [PigeonApiVideoView] used to add a new Dart instance of `VideoView` to the + * Dart `InstanceManager`. + */ + abstract fun getPigeonApiVideoView(): PigeonApiVideoView + + /** + * An implementation of [PigeonApiView] used to add a new Dart instance of `View` to the Dart + * `InstanceManager`. + */ + open fun getPigeonApiView(): PigeonApiView { + return PigeonApiView(this) + } + + /** + * An implementation of [PigeonApiMediaPlayer] used to add a new Dart instance of `MediaPlayer` to + * the Dart `InstanceManager`. + */ + abstract fun getPigeonApiMediaPlayer(): PigeonApiMediaPlayer + + /** + * An implementation of [PigeonApiVideoAdPlayerCallback] used to add a new Dart instance of + * `VideoAdPlayerCallback` to the Dart `InstanceManager`. + */ + abstract fun getPigeonApiVideoAdPlayerCallback(): PigeonApiVideoAdPlayerCallback + + /** + * An implementation of [PigeonApiVideoAdPlayer] used to add a new Dart instance of + * `VideoAdPlayer` to the Dart `InstanceManager`. + */ + abstract fun getPigeonApiVideoAdPlayer(): PigeonApiVideoAdPlayer + + /** + * An implementation of [PigeonApiAdsLoadedListener] used to add a new Dart instance of + * `AdsLoadedListener` to the Dart `InstanceManager`. + */ + abstract fun getPigeonApiAdsLoadedListener(): PigeonApiAdsLoadedListener + + /** + * An implementation of [PigeonApiAdErrorListener] used to add a new Dart instance of + * `AdErrorListener` to the Dart `InstanceManager`. + */ + abstract fun getPigeonApiAdErrorListener(): PigeonApiAdErrorListener + + /** + * An implementation of [PigeonApiAdEventListener] used to add a new Dart instance of + * `AdEventListener` to the Dart `InstanceManager`. + */ + abstract fun getPigeonApiAdEventListener(): PigeonApiAdEventListener + + /** + * An implementation of [PigeonApiAdsRenderingSettings] used to add a new Dart instance of + * `AdsRenderingSettings` to the Dart `InstanceManager`. + */ + abstract fun getPigeonApiAdsRenderingSettings(): PigeonApiAdsRenderingSettings + + /** + * An implementation of [PigeonApiAdProgressInfo] used to add a new Dart instance of + * `AdProgressInfo` to the Dart `InstanceManager`. + */ + abstract fun getPigeonApiAdProgressInfo(): PigeonApiAdProgressInfo + + /** + * An implementation of [PigeonApiCompanionAd] used to add a new Dart instance of `CompanionAd` to + * the Dart `InstanceManager`. + */ + abstract fun getPigeonApiCompanionAd(): PigeonApiCompanionAd + + /** + * An implementation of [PigeonApiUniversalAdId] used to add a new Dart instance of + * `UniversalAdId` to the Dart `InstanceManager`. + */ + abstract fun getPigeonApiUniversalAdId(): PigeonApiUniversalAdId + + /** + * An implementation of [PigeonApiAd] used to add a new Dart instance of `Ad` to the Dart + * `InstanceManager`. + */ + abstract fun getPigeonApiAd(): PigeonApiAd + + fun setUp() { + InteractiveMediaAdsLibraryPigeonInstanceManagerApi.setUpMessageHandlers( + binaryMessenger, instanceManager) + PigeonApiAdsLoader.setUpMessageHandlers(binaryMessenger, getPigeonApiAdsLoader()) + PigeonApiAdsRequest.setUpMessageHandlers(binaryMessenger, getPigeonApiAdsRequest()) + PigeonApiContentProgressProvider.setUpMessageHandlers( + binaryMessenger, getPigeonApiContentProgressProvider()) + PigeonApiAdsManager.setUpMessageHandlers(binaryMessenger, getPigeonApiAdsManager()) + PigeonApiBaseManager.setUpMessageHandlers(binaryMessenger, getPigeonApiBaseManager()) + PigeonApiImaSdkFactory.setUpMessageHandlers(binaryMessenger, getPigeonApiImaSdkFactory()) + PigeonApiVideoProgressUpdate.setUpMessageHandlers( + binaryMessenger, getPigeonApiVideoProgressUpdate()) + PigeonApiFrameLayout.setUpMessageHandlers(binaryMessenger, getPigeonApiFrameLayout()) + PigeonApiViewGroup.setUpMessageHandlers(binaryMessenger, getPigeonApiViewGroup()) + PigeonApiVideoView.setUpMessageHandlers(binaryMessenger, getPigeonApiVideoView()) + PigeonApiMediaPlayer.setUpMessageHandlers(binaryMessenger, getPigeonApiMediaPlayer()) + PigeonApiVideoAdPlayerCallback.setUpMessageHandlers( + binaryMessenger, getPigeonApiVideoAdPlayerCallback()) + PigeonApiVideoAdPlayer.setUpMessageHandlers(binaryMessenger, getPigeonApiVideoAdPlayer()) + PigeonApiAdsLoadedListener.setUpMessageHandlers( + binaryMessenger, getPigeonApiAdsLoadedListener()) + PigeonApiAdErrorListener.setUpMessageHandlers(binaryMessenger, getPigeonApiAdErrorListener()) + PigeonApiAdEventListener.setUpMessageHandlers(binaryMessenger, getPigeonApiAdEventListener()) + PigeonApiAdsRenderingSettings.setUpMessageHandlers( + binaryMessenger, getPigeonApiAdsRenderingSettings()) + } + + fun tearDown() { + InteractiveMediaAdsLibraryPigeonInstanceManagerApi.setUpMessageHandlers(binaryMessenger, null) + PigeonApiAdsLoader.setUpMessageHandlers(binaryMessenger, null) + PigeonApiAdsRequest.setUpMessageHandlers(binaryMessenger, null) + PigeonApiContentProgressProvider.setUpMessageHandlers(binaryMessenger, null) + PigeonApiAdsManager.setUpMessageHandlers(binaryMessenger, null) + PigeonApiBaseManager.setUpMessageHandlers(binaryMessenger, null) + PigeonApiImaSdkFactory.setUpMessageHandlers(binaryMessenger, null) + PigeonApiVideoProgressUpdate.setUpMessageHandlers(binaryMessenger, null) + PigeonApiFrameLayout.setUpMessageHandlers(binaryMessenger, null) + PigeonApiViewGroup.setUpMessageHandlers(binaryMessenger, null) + PigeonApiVideoView.setUpMessageHandlers(binaryMessenger, null) + PigeonApiMediaPlayer.setUpMessageHandlers(binaryMessenger, null) + PigeonApiVideoAdPlayerCallback.setUpMessageHandlers(binaryMessenger, null) + PigeonApiVideoAdPlayer.setUpMessageHandlers(binaryMessenger, null) + PigeonApiAdsLoadedListener.setUpMessageHandlers(binaryMessenger, null) + PigeonApiAdErrorListener.setUpMessageHandlers(binaryMessenger, null) + PigeonApiAdEventListener.setUpMessageHandlers(binaryMessenger, null) + PigeonApiAdsRenderingSettings.setUpMessageHandlers(binaryMessenger, null) + } +} + +private class InteractiveMediaAdsLibraryPigeonProxyApiBaseCodec( + val registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) : InteractiveMediaAdsLibraryPigeonCodec() { + override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? { + return when (type) { + 128.toByte() -> { + return registrar.instanceManager.getInstance(readValue(buffer) as Long) + } + else -> super.readValueOfType(type, buffer) + } + } + + override fun writeValue(stream: ByteArrayOutputStream, value: Any?) { + if (value is Boolean || + value is ByteArray || + value is Double || + value is DoubleArray || + value is FloatArray || + value is Int || + value is IntArray || + value is List<*> || + value is Long || + value is LongArray || + value is Map<*, *> || + value is String || + value is AdErrorCode || + value is AdErrorType || + value is AdEventType || + value is UiElement || + value == null) { + super.writeValue(stream, value) + return + } + + if (value is com.google.ads.interactivemedia.v3.api.AdDisplayContainer) { + registrar.getPigeonApiAdDisplayContainer().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.BaseDisplayContainer) { + registrar.getPigeonApiBaseDisplayContainer().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.AdsLoader) { + registrar.getPigeonApiAdsLoader().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.AdsManagerLoadedEvent) { + registrar.getPigeonApiAdsManagerLoadedEvent().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.AdErrorEvent) { + registrar.getPigeonApiAdErrorEvent().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.AdError) { + registrar.getPigeonApiAdError().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.AdsRequest) { + registrar.getPigeonApiAdsRequest().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.player.ContentProgressProvider) { + registrar.getPigeonApiContentProgressProvider().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.AdsManager) { + registrar.getPigeonApiAdsManager().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.BaseManager) { + registrar.getPigeonApiBaseManager().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.AdEvent) { + registrar.getPigeonApiAdEvent().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.ImaSdkFactory) { + registrar.getPigeonApiImaSdkFactory().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.ImaSdkSettings) { + registrar.getPigeonApiImaSdkSettings().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate) { + registrar.getPigeonApiVideoProgressUpdate().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.player.AdMediaInfo) { + registrar.getPigeonApiAdMediaInfo().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.AdPodInfo) { + registrar.getPigeonApiAdPodInfo().pigeon_newInstance(value) {} + } else if (value is android.widget.FrameLayout) { + registrar.getPigeonApiFrameLayout().pigeon_newInstance(value) {} + } else if (value is android.view.ViewGroup) { + registrar.getPigeonApiViewGroup().pigeon_newInstance(value) {} + } else if (value is android.widget.VideoView) { + registrar.getPigeonApiVideoView().pigeon_newInstance(value) {} + } else if (value is android.view.View) { + registrar.getPigeonApiView().pigeon_newInstance(value) {} + } else if (value is android.media.MediaPlayer) { + registrar.getPigeonApiMediaPlayer().pigeon_newInstance(value) {} + } else if (value + is com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback) { + registrar.getPigeonApiVideoAdPlayerCallback().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer) { + registrar.getPigeonApiVideoAdPlayer().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.AdsLoader.AdsLoadedListener) { + registrar.getPigeonApiAdsLoadedListener().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.AdErrorEvent.AdErrorListener) { + registrar.getPigeonApiAdErrorListener().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.AdEvent.AdEventListener) { + registrar.getPigeonApiAdEventListener().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.AdsRenderingSettings) { + registrar.getPigeonApiAdsRenderingSettings().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.AdProgressInfo) { + registrar.getPigeonApiAdProgressInfo().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.CompanionAd) { + registrar.getPigeonApiCompanionAd().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.UniversalAdId) { + registrar.getPigeonApiUniversalAdId().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.Ad) { + registrar.getPigeonApiAd().pigeon_newInstance(value) {} + } + + when { + registrar.instanceManager.containsInstance(value) -> { + stream.write(128) + writeValue(stream, registrar.instanceManager.getIdentifierForStrongReference(value)) + } + else -> + throw IllegalArgumentException( + "Unsupported value: '$value' of type '${value.javaClass.name}'") + } + } +} + +/** + * The types of error that can be encountered. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdError.AdErrorCode.html. + */ +enum class AdErrorCode(val raw: Int) { + /** Ads player was not provided. */ + ADS_PLAYER_WAS_NOT_PROVIDED(0), + /** There was a problem requesting ads from the server. */ + ADS_REQUEST_NETWORK_ERROR(1), + /** A companion ad failed to load or render. */ + COMPANION_AD_LOADING_FAILED(2), + /** There was a problem requesting ads from the server. */ + FAILED_TO_REQUEST_ADS(3), + /** An error internal to the SDK occurred. */ + INTERNAL_ERROR(4), + /** Invalid arguments were provided to SDK methods. */ + INVALID_ARGUMENTS(5), + /** An overlay ad failed to load. */ + OVERLAY_AD_LOADING_FAILED(6), + /** An overlay ad failed to render. */ + OVERLAY_AD_PLAYING_FAILED(7), + /** Ads list was returned but ContentProgressProvider was not configured. */ + PLAYLIST_NO_CONTENT_TRACKING(8), + /** Ads loader sent ads loaded event when it was not expected. */ + UNEXPECTED_ADS_LOADED_EVENT(9), + /** The ad response was not understood and cannot be parsed. */ + UNKNOWN_AD_RESPONSE(10), + /** An unexpected error occurred and the cause is not known. */ + UNKNOWN_ERROR(11), + /** No assets were found in the VAST ad response. */ + VAST_ASSET_NOT_FOUND(12), + /** A VAST response containing a single `` tag with no child tags. */ + VAST_EMPTY_RESPONSE(13), + /** + * Assets were found in the VAST ad response for a linear ad, but none of them matched the video + * player's capabilities. + */ + VAST_LINEAR_ASSET_MISMATCH(14), + /** + * At least one VAST wrapper ad loaded successfully and a subsequent wrapper or inline ad load has + * timed out. + */ + VAST_LOAD_TIMEOUT(15), + /** The ad response was not recognized as a valid VAST ad. */ + VAST_MALFORMED_RESPONSE(16), + /** Failed to load media assets from a VAST response. */ + VAST_MEDIA_LOAD_TIMEOUT(17), + /** + * Assets were found in the VAST ad response for a nonlinear ad, but none of them matched the + * video player's capabilities. + */ + VAST_NONLINEAR_ASSET_MISMATCH(18), + /** No Ads VAST response after one or more wrappers. */ + VAST_NO_ADS_AFTER_WRAPPER(19), + /** The maximum number of VAST wrapper redirects has been reached. */ + VAST_TOO_MANY_REDIRECTS(20), + /** + * Trafficking error. + * + * Video player received an ad type that it was not expecting and/or cannot display. + */ + VAST_TRAFFICKING_ERROR(21), + /** There was an error playing the video ad. */ + VIDEO_PLAY_ERROR(22), + /** The error code is not recognized by this wrapper. */ + UNKNOWN(23); + + companion object { + fun ofRaw(raw: Int): AdErrorCode? { + return values().firstOrNull { it.raw == raw } + } + } +} + +/** + * Specifies when the error was encountered, during either ad loading or playback. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdError.AdErrorType.html. + */ +enum class AdErrorType(val raw: Int) { + /** Indicates that the error was encountered when the ad was being loaded. */ + LOAD(0), + /** Indicates that the error was encountered after the ad loaded, during ad play. */ + PLAY(1), + /** The error is not recognized by this wrapper. */ + UNKNOWN(2); + + companion object { + fun ofRaw(raw: Int): AdErrorType? { + return values().firstOrNull { it.raw == raw } + } + } +} + +/** + * Types of events that can occur during ad playback. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdEvent.AdEventType.html. + */ +enum class AdEventType(val raw: Int) { + /** Fired when an ad break in a stream ends. */ + AD_BREAK_ENDED(0), + /** Fired when an ad break will not play back any ads. */ + AD_BREAK_FETCH_ERROR(1), + /** Fired when an ad break is ready from VMAP or ad rule ads. */ + AD_BREAK_READY(2), + /** Fired when an ad break in a stream starts. */ + AD_BREAK_STARTED(3), + /** Fired when playback stalls while the ad buffers. */ + AD_BUFFERING(4), + /** Fired when an ad period in a stream ends. */ + AD_PERIOD_ENDED(5), + /** Fired when an ad period in a stream starts. */ + AD_PERIOD_STARTED(6), + /** Fired to inform of ad progress and can be used by publisher to display a countdown timer. */ + AD_PROGRESS(7), + /** + * Fired when the ads manager is done playing all the valid ads in the ads response, or when the + * response doesn't return any valid ads. + */ + ALL_ADS_COMPLETED(8), + /** Fired when an ad is clicked. */ + CLICKED(9), + /** Fired when an ad completes playing. */ + COMPLETED(10), + /** Fired when content should be paused. */ + CONTENT_PAUSE_REQUESTED(11), + /** Fired when content should be resumed. */ + CONTENT_RESUME_REQUESTED(12), + /** Fired when VOD stream cuepoints have changed. */ + CUEPOINTS_CHANGED(13), + /** Fired when the ad playhead crosses first quartile. */ + FIRST_QUARTILE(14), + /** The user has closed the icon fallback image dialog. */ + ICON_FALLBACK_IMAGE_CLOSED(15), + /** The user has tapped an ad icon. */ + ICON_TAPPED(16), + /** Fired when the VAST response has been received. */ + LOADED(17), + /** Fired to enable the SDK to communicate a message to be logged, which is stored in adData. */ + LOG(18), + /** Fired when the ad playhead crosses midpoint. */ + MIDPOINT(19), + /** Fired when an ad is paused. */ + PAUSED(20), + /** Fired when an ad is resumed. */ + RESUMED(21), + /** Fired when an ad changes its skippable state. */ + SKIPPABLE_STATE_CHANGED(22), + /** Fired when an ad was skipped. */ + SKIPPED(23), + /** Fired when an ad starts playing. */ + STARTED(24), + /** Fired when a non-clickthrough portion of a video ad is clicked. */ + TAPPED(25), + /** Fired when the ad playhead crosses third quartile. */ + THIRD_QUARTILE(26), + /** The event type is not recognized by this wrapper. */ + UNKNOWN(27); + + companion object { + fun ofRaw(raw: Int): AdEventType? { + return values().firstOrNull { it.raw == raw } + } + } +} + +/** + * Describes an element of the ad UI, to be requested or rendered by the SDK. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/UiElement.html. + */ +enum class UiElement(val raw: Int) { + /** The ad attribution UI element, for example, "Ad". */ + AD_ATTRIBUTION(0), + /** Ad attribution is required for a countdown timer to be displayed. */ + COUNTDOWN(1), + /** The element is not recognized by this wrapper. */ + UNKNOWN(2); + + companion object { + fun ofRaw(raw: Int): UiElement? { + return values().firstOrNull { it.raw == raw } + } + } +} + +private open class InteractiveMediaAdsLibraryPigeonCodec : StandardMessageCodec() { + override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? { + return when (type) { + 129.toByte() -> { + return (readValue(buffer) as Long?)?.let { AdErrorCode.ofRaw(it.toInt()) } + } + 130.toByte() -> { + return (readValue(buffer) as Long?)?.let { AdErrorType.ofRaw(it.toInt()) } + } + 131.toByte() -> { + return (readValue(buffer) as Long?)?.let { AdEventType.ofRaw(it.toInt()) } + } + 132.toByte() -> { + return (readValue(buffer) as Long?)?.let { UiElement.ofRaw(it.toInt()) } + } + else -> super.readValueOfType(type, buffer) + } + } + + override fun writeValue(stream: ByteArrayOutputStream, value: Any?) { + when (value) { + is AdErrorCode -> { + stream.write(129) + writeValue(stream, value.raw) + } + is AdErrorType -> { + stream.write(130) + writeValue(stream, value.raw) + } + is AdEventType -> { + stream.write(131) + writeValue(stream, value.raw) + } + is UiElement -> { + stream.write(132) + writeValue(stream, value.raw) + } + else -> super.writeValue(stream, value) + } + } +} + +/** + * A base class for more specialized container interfaces. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/BaseDisplayContainer.html. + */ +@Suppress("UNCHECKED_CAST") +open class PigeonApiBaseDisplayContainer( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of BaseDisplayContainer and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.BaseDisplayContainer, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.interactive_media_ads.BaseDisplayContainer.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_identifierArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * A container in which to display the ads. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdDisplayContainer. + */ +@Suppress("UNCHECKED_CAST") +open class PigeonApiAdDisplayContainer( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of AdDisplayContainer and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.AdDisplayContainer, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.interactive_media_ads.AdDisplayContainer.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_identifierArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + @Suppress("FunctionName") + /** An implementation of [PigeonApiBaseDisplayContainer] used to access callback methods */ + fun pigeon_getPigeonApiBaseDisplayContainer(): PigeonApiBaseDisplayContainer { + return pigeonRegistrar.getPigeonApiBaseDisplayContainer() + } +} +/** + * An object which allows publishers to request ads from ad servers or a dynamic ad insertion + * stream. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdsLoader. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiAdsLoader( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + /** Registers a listener for errors that occur during the ads request. */ + abstract fun addAdErrorListener( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsLoader, + listener: com.google.ads.interactivemedia.v3.api.AdErrorEvent.AdErrorListener + ) + + /** Registers a listener for the ads manager loaded event. */ + abstract fun addAdsLoadedListener( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsLoader, + listener: com.google.ads.interactivemedia.v3.api.AdsLoader.AdsLoadedListener + ) + + /** Requests ads from a server. */ + abstract fun requestAds( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsLoader, + request: com.google.ads.interactivemedia.v3.api.AdsRequest + ) + + companion object { + @Suppress("LocalVariableName") + fun setUpMessageHandlers(binaryMessenger: BinaryMessenger, api: PigeonApiAdsLoader?) { + val codec = api?.pigeonRegistrar?.codec ?: InteractiveMediaAdsLibraryPigeonCodec() + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.AdsLoader.addAdErrorListener", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.AdsLoader + val listenerArg = + args[1] as com.google.ads.interactivemedia.v3.api.AdErrorEvent.AdErrorListener + val wrapped: List = + try { + api.addAdErrorListener(pigeon_instanceArg, listenerArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.AdsLoader.addAdsLoadedListener", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.AdsLoader + val listenerArg = + args[1] as com.google.ads.interactivemedia.v3.api.AdsLoader.AdsLoadedListener + val wrapped: List = + try { + api.addAdsLoadedListener(pigeon_instanceArg, listenerArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.AdsLoader.requestAds", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.AdsLoader + val requestArg = args[1] as com.google.ads.interactivemedia.v3.api.AdsRequest + val wrapped: List = + try { + api.requestAds(pigeon_instanceArg, requestArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } + } + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of AdsLoader and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.AdsLoader, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.AdsLoader.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_identifierArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * An event raised when ads are successfully loaded from the ad server through an AdsLoader. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdsManagerLoadedEvent.html. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiAdsManagerLoadedEvent( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + /** + * The ads manager that will control playback of the loaded ads, or null when using dynamic ad + * insertion. + */ + abstract fun manager( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsManagerLoadedEvent + ): com.google.ads.interactivemedia.v3.api.AdsManager + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of AdsManagerLoadedEvent and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.AdsManagerLoadedEvent, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val managerArg = manager(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.interactive_media_ads.AdsManagerLoadedEvent.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_identifierArg, managerArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * An event raised when there is an error loading or playing ads. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdErrorEvent.html. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiAdErrorEvent( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + /** The AdError that caused this event. */ + abstract fun error( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdErrorEvent + ): com.google.ads.interactivemedia.v3.api.AdError + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of AdErrorEvent and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.AdErrorEvent, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val errorArg = error(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.AdErrorEvent.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_identifierArg, errorArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * An error that occurred in the SDK. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdError.html. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiAdError( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + /** The error's code. */ + abstract fun errorCode( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdError + ): AdErrorCode + + /** The error code's number. */ + abstract fun errorCodeNumber( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdError + ): Long + + /** The error's type. */ + abstract fun errorType( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdError + ): AdErrorType + + /** A human-readable summary of the error. */ + abstract fun message(pigeon_instance: com.google.ads.interactivemedia.v3.api.AdError): String + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of AdError and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.AdError, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val errorCodeArg = errorCode(pigeon_instanceArg) + val errorCodeNumberArg = errorCodeNumber(pigeon_instanceArg) + val errorTypeArg = errorType(pigeon_instanceArg) + val messageArg = message(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.AdError.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send( + listOf(pigeon_identifierArg, errorCodeArg, errorCodeNumberArg, errorTypeArg, messageArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * An object containing the data used to request ads from the server. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdsRequest. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiAdsRequest( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + /** Sets the URL from which ads will be requested. */ + abstract fun setAdTagUrl( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsRequest, + adTagUrl: String + ) + + /** + * Attaches a ContentProgressProvider instance to allow scheduling ad breaks based on content + * progress (cue points). + */ + abstract fun setContentProgressProvider( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsRequest, + provider: com.google.ads.interactivemedia.v3.api.player.ContentProgressProvider + ) + + companion object { + @Suppress("LocalVariableName") + fun setUpMessageHandlers(binaryMessenger: BinaryMessenger, api: PigeonApiAdsRequest?) { + val codec = api?.pigeonRegistrar?.codec ?: InteractiveMediaAdsLibraryPigeonCodec() + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.AdsRequest.setAdTagUrl", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.AdsRequest + val adTagUrlArg = args[1] as String + val wrapped: List = + try { + api.setAdTagUrl(pigeon_instanceArg, adTagUrlArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.AdsRequest.setContentProgressProvider", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.AdsRequest + val providerArg = + args[1] as com.google.ads.interactivemedia.v3.api.player.ContentProgressProvider + val wrapped: List = + try { + api.setContentProgressProvider(pigeon_instanceArg, providerArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } + } + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of AdsRequest and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.AdsRequest, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.AdsRequest.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_identifierArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * Defines an interface to allow SDK to track progress of the content video. + * + * See + * https://developers.google.com/ad-manager/dynamic-ad-insertion/sdk/android/api/reference/com/google/ads/interactivemedia/v3/api/player/ContentProgressProvider.html. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiContentProgressProvider( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + abstract fun pigeon_defaultConstructor(): + com.google.ads.interactivemedia.v3.api.player.ContentProgressProvider + + /** + * Sets an update on the progress of the video. + * + * This is a custom method added to the native class because the native method + * `getContentProgress` requires a synchronous return value. + */ + abstract fun setContentProgress( + pigeon_instance: com.google.ads.interactivemedia.v3.api.player.ContentProgressProvider, + update: com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate + ) + + companion object { + @Suppress("LocalVariableName") + fun setUpMessageHandlers( + binaryMessenger: BinaryMessenger, + api: PigeonApiContentProgressProvider? + ) { + val codec = api?.pigeonRegistrar?.codec ?: InteractiveMediaAdsLibraryPigeonCodec() + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.ContentProgressProvider.pigeon_defaultConstructor", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_identifierArg = args[0] as Long + val wrapped: List = + try { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + api.pigeon_defaultConstructor(), pigeon_identifierArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.ContentProgressProvider.setContentProgress", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] as com.google.ads.interactivemedia.v3.api.player.ContentProgressProvider + val updateArg = + args[1] as com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate + val wrapped: List = + try { + api.setContentProgress(pigeon_instanceArg, updateArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } + } + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of ContentProgressProvider and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.player.ContentProgressProvider, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.interactive_media_ads.ContentProgressProvider.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_identifierArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * An object which handles playing ads after they've been received from the server. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdsManager. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiAdsManager( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + /** Discards current ad break and resumes content. */ + abstract fun discardAdBreak(pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsManager) + + /** Pauses the current ad. */ + abstract fun pause(pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsManager) + + /** Starts playing the ads. */ + abstract fun start(pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsManager) + + /** + * List of content time offsets in seconds at which ad breaks are scheduled. + * + * The list will be empty if no ad breaks are scheduled. + */ + abstract fun getAdCuePoints( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsManager + ): List + + /** Resumes the current ad. */ + abstract fun resume(pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsManager) + + /** + * Skips the current ad. + * + * `AdsManager.skip()` only skips ads if IMA does not render the 'Skip ad' button. + */ + abstract fun skip(pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsManager) + + companion object { + @Suppress("LocalVariableName") + fun setUpMessageHandlers(binaryMessenger: BinaryMessenger, api: PigeonApiAdsManager?) { + val codec = api?.pigeonRegistrar?.codec ?: InteractiveMediaAdsLibraryPigeonCodec() + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.AdsManager.discardAdBreak", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.AdsManager + val wrapped: List = + try { + api.discardAdBreak(pigeon_instanceArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, "dev.flutter.pigeon.interactive_media_ads.AdsManager.pause", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.AdsManager + val wrapped: List = + try { + api.pause(pigeon_instanceArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, "dev.flutter.pigeon.interactive_media_ads.AdsManager.start", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.AdsManager + val wrapped: List = + try { + api.start(pigeon_instanceArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.AdsManager.getAdCuePoints", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.AdsManager + val wrapped: List = + try { + listOf(api.getAdCuePoints(pigeon_instanceArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.AdsManager.resume", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.AdsManager + val wrapped: List = + try { + api.resume(pigeon_instanceArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, "dev.flutter.pigeon.interactive_media_ads.AdsManager.skip", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.AdsManager + val wrapped: List = + try { + api.skip(pigeon_instanceArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } + } + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of AdsManager and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.AdsManager, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.AdsManager.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_identifierArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + @Suppress("FunctionName") + /** An implementation of [PigeonApiBaseManager] used to access callback methods */ + fun pigeon_getPigeonApiBaseManager(): PigeonApiBaseManager { + return pigeonRegistrar.getPigeonApiBaseManager() + } +} +/** + * Base interface for managing ads.. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/BaseManager.html. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiBaseManager( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + /** + * Registers a listener for errors that occur during the ad or stream initialization and playback. + */ + abstract fun addAdErrorListener( + pigeon_instance: com.google.ads.interactivemedia.v3.api.BaseManager, + errorListener: com.google.ads.interactivemedia.v3.api.AdErrorEvent.AdErrorListener + ) + + /** + * Registers a listener for ad events that occur during ad or stream initialization and playback. + */ + abstract fun addAdEventListener( + pigeon_instance: com.google.ads.interactivemedia.v3.api.BaseManager, + adEventListener: com.google.ads.interactivemedia.v3.api.AdEvent.AdEventListener + ) + + /** Stops the ad and all tracking, then releases all assets that were loaded to play the ad. */ + abstract fun destroy(pigeon_instance: com.google.ads.interactivemedia.v3.api.BaseManager) + + /** Initializes the ad experience on the manager. */ + abstract fun init( + pigeon_instance: com.google.ads.interactivemedia.v3.api.BaseManager, + settings: com.google.ads.interactivemedia.v3.api.AdsRenderingSettings? + ) + + /** Generic focus endpoint that puts focus on the skip button if present. */ + abstract fun focus(pigeon_instance: com.google.ads.interactivemedia.v3.api.BaseManager) + + /** Returns the latest AdProgressInfo for the current playing ad. */ + abstract fun getAdProgressInfo( + pigeon_instance: com.google.ads.interactivemedia.v3.api.BaseManager + ): com.google.ads.interactivemedia.v3.api.AdProgressInfo? + + /** Get currently playing ad. */ + abstract fun getCurrentAd( + pigeon_instance: com.google.ads.interactivemedia.v3.api.BaseManager + ): com.google.ads.interactivemedia.v3.api.Ad? + + /** Removes a listener for error events. */ + abstract fun removeAdErrorListener( + pigeon_instance: com.google.ads.interactivemedia.v3.api.BaseManager, + errorListener: com.google.ads.interactivemedia.v3.api.AdErrorEvent.AdErrorListener + ) + + /** Removes a listener for ad events. */ + abstract fun removeAdEventListener( + pigeon_instance: com.google.ads.interactivemedia.v3.api.BaseManager, + adEventListener: com.google.ads.interactivemedia.v3.api.AdEvent.AdEventListener + ) + + companion object { + @Suppress("LocalVariableName") + fun setUpMessageHandlers(binaryMessenger: BinaryMessenger, api: PigeonApiBaseManager?) { + val codec = api?.pigeonRegistrar?.codec ?: InteractiveMediaAdsLibraryPigeonCodec() + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.BaseManager.addAdErrorListener", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.BaseManager + val errorListenerArg = + args[1] as com.google.ads.interactivemedia.v3.api.AdErrorEvent.AdErrorListener + val wrapped: List = + try { + api.addAdErrorListener(pigeon_instanceArg, errorListenerArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.BaseManager.addAdEventListener", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.BaseManager + val adEventListenerArg = + args[1] as com.google.ads.interactivemedia.v3.api.AdEvent.AdEventListener + val wrapped: List = + try { + api.addAdEventListener(pigeon_instanceArg, adEventListenerArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.BaseManager.destroy", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.BaseManager + val wrapped: List = + try { + api.destroy(pigeon_instanceArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, "dev.flutter.pigeon.interactive_media_ads.BaseManager.init", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.BaseManager + val settingsArg = + args[1] as com.google.ads.interactivemedia.v3.api.AdsRenderingSettings? + val wrapped: List = + try { + api.init(pigeon_instanceArg, settingsArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.BaseManager.focus", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.BaseManager + val wrapped: List = + try { + api.focus(pigeon_instanceArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.BaseManager.getAdProgressInfo", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.BaseManager + val wrapped: List = + try { + listOf(api.getAdProgressInfo(pigeon_instanceArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.BaseManager.getCurrentAd", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.BaseManager + val wrapped: List = + try { + listOf(api.getCurrentAd(pigeon_instanceArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.BaseManager.removeAdErrorListener", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.BaseManager + val errorListenerArg = + args[1] as com.google.ads.interactivemedia.v3.api.AdErrorEvent.AdErrorListener + val wrapped: List = + try { + api.removeAdErrorListener(pigeon_instanceArg, errorListenerArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.BaseManager.removeAdEventListener", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.BaseManager + val adEventListenerArg = + args[1] as com.google.ads.interactivemedia.v3.api.AdEvent.AdEventListener + val wrapped: List = + try { + api.removeAdEventListener(pigeon_instanceArg, adEventListenerArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } + } + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of BaseManager and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.BaseManager, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.BaseManager.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_identifierArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * Event to notify publisher that an event occurred with an Ad. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdEvent.html. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiAdEvent( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + /** The type of event that occurred. */ + abstract fun type(pigeon_instance: com.google.ads.interactivemedia.v3.api.AdEvent): AdEventType + + /** A map containing any extra ad data for the event, if needed. */ + abstract fun adData( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdEvent + ): Map? + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of AdEvent and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.AdEvent, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val typeArg = type(pigeon_instanceArg) + val adDataArg = adData(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.AdEvent.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_identifierArg, typeArg, adDataArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * Factory class for creating SDK objects. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/ImaSdkFactory. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiImaSdkFactory( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + abstract fun instance(): com.google.ads.interactivemedia.v3.api.ImaSdkFactory + + abstract fun createAdDisplayContainer( + container: android.view.ViewGroup, + player: com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer + ): com.google.ads.interactivemedia.v3.api.AdDisplayContainer + + /** Creates an `ImaSdkSettings` object for configuring the IMA SDK. */ + abstract fun createImaSdkSettings( + pigeon_instance: com.google.ads.interactivemedia.v3.api.ImaSdkFactory + ): com.google.ads.interactivemedia.v3.api.ImaSdkSettings + + /** Creates an `AdsLoader` for requesting ads using the specified settings object. */ + abstract fun createAdsLoader( + pigeon_instance: com.google.ads.interactivemedia.v3.api.ImaSdkFactory, + settings: com.google.ads.interactivemedia.v3.api.ImaSdkSettings, + container: com.google.ads.interactivemedia.v3.api.AdDisplayContainer + ): com.google.ads.interactivemedia.v3.api.AdsLoader + + /** Creates an AdsRequest object to contain the data used to request ads. */ + abstract fun createAdsRequest( + pigeon_instance: com.google.ads.interactivemedia.v3.api.ImaSdkFactory + ): com.google.ads.interactivemedia.v3.api.AdsRequest + + companion object { + @Suppress("LocalVariableName") + fun setUpMessageHandlers(binaryMessenger: BinaryMessenger, api: PigeonApiImaSdkFactory?) { + val codec = api?.pigeonRegistrar?.codec ?: InteractiveMediaAdsLibraryPigeonCodec() + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.ImaSdkFactory.instance", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_identifierArg = args[0] as Long + val wrapped: List = + try { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + api.instance(), pigeon_identifierArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.ImaSdkFactory.createAdDisplayContainer", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val containerArg = args[0] as android.view.ViewGroup + val playerArg = args[1] as com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer + val wrapped: List = + try { + listOf(api.createAdDisplayContainer(containerArg, playerArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.ImaSdkFactory.createImaSdkSettings", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.ImaSdkFactory + val wrapped: List = + try { + listOf(api.createImaSdkSettings(pigeon_instanceArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.ImaSdkFactory.createAdsLoader", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.ImaSdkFactory + val settingsArg = args[1] as com.google.ads.interactivemedia.v3.api.ImaSdkSettings + val containerArg = args[2] as com.google.ads.interactivemedia.v3.api.AdDisplayContainer + val wrapped: List = + try { + listOf(api.createAdsLoader(pigeon_instanceArg, settingsArg, containerArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.ImaSdkFactory.createAdsRequest", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.ImaSdkFactory + val wrapped: List = + try { + listOf(api.createAdsRequest(pigeon_instanceArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } + } + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of ImaSdkFactory and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.ImaSdkFactory, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.ImaSdkFactory.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_identifierArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * Defines general SDK settings that are used when creating an `AdsLoader`. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/ImaSdkSettings.html. + */ +@Suppress("UNCHECKED_CAST") +open class PigeonApiImaSdkSettings( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of ImaSdkSettings and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.ImaSdkSettings, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.ImaSdkSettings.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_identifierArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * Defines an update to the video's progress. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/player/VideoProgressUpdate.html. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiVideoProgressUpdate( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + abstract fun pigeon_defaultConstructor( + currentTimeMs: Long, + durationMs: Long + ): com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate + + /** Value to use for cases when progress is not yet defined, such as video initialization. */ + abstract fun videoTimeNotReady(): + com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate + + companion object { + @Suppress("LocalVariableName") + fun setUpMessageHandlers(binaryMessenger: BinaryMessenger, api: PigeonApiVideoProgressUpdate?) { + val codec = api?.pigeonRegistrar?.codec ?: InteractiveMediaAdsLibraryPigeonCodec() + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.VideoProgressUpdate.pigeon_defaultConstructor", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_identifierArg = args[0] as Long + val currentTimeMsArg = args[1] as Long + val durationMsArg = args[2] as Long + val wrapped: List = + try { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + api.pigeon_defaultConstructor(currentTimeMsArg, durationMsArg), + pigeon_identifierArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.VideoProgressUpdate.videoTimeNotReady", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_identifierArg = args[0] as Long + val wrapped: List = + try { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + api.videoTimeNotReady(), pigeon_identifierArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } + } + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of VideoProgressUpdate and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.interactive_media_ads.VideoProgressUpdate.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_identifierArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * The minimal information required to play an ad. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/player/AdMediaInfo.html. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiAdMediaInfo( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + abstract fun url( + pigeon_instance: com.google.ads.interactivemedia.v3.api.player.AdMediaInfo + ): String + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of AdMediaInfo and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.player.AdMediaInfo, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val urlArg = url(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.AdMediaInfo.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_identifierArg, urlArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * An ad may be part of a pod of ads. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdPodInfo.html. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiAdPodInfo( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + /** + * The position of the ad within the pod. + * + * The value returned is one-based, for example, 1 of 2, 2 of 2, etc. If the ad is not part of a + * pod, this will return 1. + */ + abstract fun adPosition(pigeon_instance: com.google.ads.interactivemedia.v3.api.AdPodInfo): Long + + /** + * The maximum duration of the pod in seconds. + * + * For unknown duration, -1 is returned. + */ + abstract fun maxDuration( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdPodInfo + ): Double + + /** Client side and DAI VOD: Returns the index of the ad pod. */ + abstract fun podIndex(pigeon_instance: com.google.ads.interactivemedia.v3.api.AdPodInfo): Long + + /** + * The content time offset at which the current ad pod was scheduled. + * + * For preroll pod, 0 is returned. For midrolls, the scheduled time is returned in seconds. For + * postroll, -1 is returned. Defaults to 0 if this ad is not part of a pod, or the pod is not part + * of an ad playlist. + */ + abstract fun timeOffset(pigeon_instance: com.google.ads.interactivemedia.v3.api.AdPodInfo): Double + + /** The total number of ads contained within this pod, including bumpers. */ + abstract fun totalAds(pigeon_instance: com.google.ads.interactivemedia.v3.api.AdPodInfo): Long + + /** Returns true if the ad is a bumper ad. */ + abstract fun isBumper(pigeon_instance: com.google.ads.interactivemedia.v3.api.AdPodInfo): Boolean + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of AdPodInfo and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.AdPodInfo, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val adPositionArg = adPosition(pigeon_instanceArg) + val maxDurationArg = maxDuration(pigeon_instanceArg) + val podIndexArg = podIndex(pigeon_instanceArg) + val timeOffsetArg = timeOffset(pigeon_instanceArg) + val totalAdsArg = totalAds(pigeon_instanceArg) + val isBumperArg = isBumper(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.AdPodInfo.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send( + listOf( + pigeon_identifierArg, + adPositionArg, + maxDurationArg, + podIndexArg, + timeOffsetArg, + totalAdsArg, + isBumperArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * FrameLayout is designed to block out an area on the screen to display a single item. + * + * See https://developer.android.com/reference/android/widget/FrameLayout. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiFrameLayout( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + abstract fun pigeon_defaultConstructor(): android.widget.FrameLayout + + companion object { + @Suppress("LocalVariableName") + fun setUpMessageHandlers(binaryMessenger: BinaryMessenger, api: PigeonApiFrameLayout?) { + val codec = api?.pigeonRegistrar?.codec ?: InteractiveMediaAdsLibraryPigeonCodec() + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.FrameLayout.pigeon_defaultConstructor", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_identifierArg = args[0] as Long + val wrapped: List = + try { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + api.pigeon_defaultConstructor(), pigeon_identifierArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } + } + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of FrameLayout and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: android.widget.FrameLayout, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.FrameLayout.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_identifierArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + @Suppress("FunctionName") + /** An implementation of [PigeonApiViewGroup] used to access callback methods */ + fun pigeon_getPigeonApiViewGroup(): PigeonApiViewGroup { + return pigeonRegistrar.getPigeonApiViewGroup() + } +} +/** + * A special view that can contain other views (called children.) + * + * See https://developer.android.com/reference/android/view/ViewGroup. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiViewGroup( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + /** Adds a child view. */ + abstract fun addView(pigeon_instance: android.view.ViewGroup, view: android.view.View) + + /** + * Called by a ViewGroup subclass to remove child views from itself, when it must first know its + * size on screen before it can calculate how many child views it will render. + */ + abstract fun removeView(pigeon_instance: android.view.ViewGroup, view: android.view.View) + + companion object { + @Suppress("LocalVariableName") + fun setUpMessageHandlers(binaryMessenger: BinaryMessenger, api: PigeonApiViewGroup?) { + val codec = api?.pigeonRegistrar?.codec ?: InteractiveMediaAdsLibraryPigeonCodec() + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.ViewGroup.addView", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as android.view.ViewGroup + val viewArg = args[1] as android.view.View + val wrapped: List = + try { + api.addView(pigeon_instanceArg, viewArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.ViewGroup.removeView", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as android.view.ViewGroup + val viewArg = args[1] as android.view.View + val wrapped: List = + try { + api.removeView(pigeon_instanceArg, viewArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } + } + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of ViewGroup and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: android.view.ViewGroup, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.ViewGroup.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_identifierArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + @Suppress("FunctionName") + /** An implementation of [PigeonApiView] used to access callback methods */ + fun pigeon_getPigeonApiView(): PigeonApiView { + return pigeonRegistrar.getPigeonApiView() + } +} +/** + * Displays a video file. + * + * See https://developer.android.com/reference/android/widget/VideoView. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiVideoView( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + abstract fun pigeon_defaultConstructor(): android.widget.VideoView + + /** Sets the URI of the video. */ + abstract fun setVideoUri(pigeon_instance: android.widget.VideoView, uri: String?) + + /** + * The current position of the playing video. + * + * In milliseconds. + */ + abstract fun getCurrentPosition(pigeon_instance: android.widget.VideoView): Long + + companion object { + @Suppress("LocalVariableName") + fun setUpMessageHandlers(binaryMessenger: BinaryMessenger, api: PigeonApiVideoView?) { + val codec = api?.pigeonRegistrar?.codec ?: InteractiveMediaAdsLibraryPigeonCodec() + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.VideoView.pigeon_defaultConstructor", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_identifierArg = args[0] as Long + val wrapped: List = + try { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + api.pigeon_defaultConstructor(), pigeon_identifierArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.VideoView.setVideoUri", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as android.widget.VideoView + val uriArg = args[1] as String? + val wrapped: List = + try { + api.setVideoUri(pigeon_instanceArg, uriArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.VideoView.getCurrentPosition", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as android.widget.VideoView + val wrapped: List = + try { + listOf(api.getCurrentPosition(pigeon_instanceArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } + } + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of VideoView and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: android.widget.VideoView, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + throw IllegalStateException( + "Attempting to create a new Dart instance of VideoView, but the class has a nonnull callback method.") + } + + /** Callback to be invoked when the media source is ready for playback. */ + fun onPrepared( + pigeon_instanceArg: android.widget.VideoView, + playerArg: android.media.MediaPlayer, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.VideoView.onPrepared" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, playerArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Callback to be invoked when playback of a media source has completed. */ + fun onCompletion( + pigeon_instanceArg: android.widget.VideoView, + playerArg: android.media.MediaPlayer, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.VideoView.onCompletion" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, playerArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Callback to be invoked when there has been an error during an asynchronous operation. */ + fun onError( + pigeon_instanceArg: android.widget.VideoView, + playerArg: android.media.MediaPlayer, + whatArg: Long, + extraArg: Long, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.VideoView.onError" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, playerArg, whatArg, extraArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + @Suppress("FunctionName") + /** An implementation of [PigeonApiView] used to access callback methods */ + fun pigeon_getPigeonApiView(): PigeonApiView { + return pigeonRegistrar.getPigeonApiView() + } +} +/** + * This class represents the basic building block for user interface components. + * + * See https://developer.android.com/reference/android/view/View. + */ +@Suppress("UNCHECKED_CAST") +open class PigeonApiView( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of View and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance(pigeon_instanceArg: android.view.View, callback: (Result) -> Unit) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.View.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_identifierArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * MediaPlayer class can be used to control playback of audio/video files and streams. + * + * See https://developer.android.com/reference/android/media/MediaPlayer. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiMediaPlayer( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + /** Gets the duration of the file. */ + abstract fun getDuration(pigeon_instance: android.media.MediaPlayer): Long + + /** Seeks to specified time position. */ + abstract fun seekTo(pigeon_instance: android.media.MediaPlayer, mSec: Long) + + /** Starts or resumes playback. */ + abstract fun start(pigeon_instance: android.media.MediaPlayer) + + /** Pauses playback. */ + abstract fun pause(pigeon_instance: android.media.MediaPlayer) + + /** Stops playback after playback has been started or paused. */ + abstract fun stop(pigeon_instance: android.media.MediaPlayer) + + companion object { + @Suppress("LocalVariableName") + fun setUpMessageHandlers(binaryMessenger: BinaryMessenger, api: PigeonApiMediaPlayer?) { + val codec = api?.pigeonRegistrar?.codec ?: InteractiveMediaAdsLibraryPigeonCodec() + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.MediaPlayer.getDuration", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as android.media.MediaPlayer + val wrapped: List = + try { + listOf(api.getDuration(pigeon_instanceArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.MediaPlayer.seekTo", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as android.media.MediaPlayer + val mSecArg = args[1] as Long + val wrapped: List = + try { + api.seekTo(pigeon_instanceArg, mSecArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.MediaPlayer.start", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as android.media.MediaPlayer + val wrapped: List = + try { + api.start(pigeon_instanceArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.MediaPlayer.pause", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as android.media.MediaPlayer + val wrapped: List = + try { + api.pause(pigeon_instanceArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, "dev.flutter.pigeon.interactive_media_ads.MediaPlayer.stop", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as android.media.MediaPlayer + val wrapped: List = + try { + api.stop(pigeon_instanceArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } + } + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of MediaPlayer and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: android.media.MediaPlayer, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.MediaPlayer.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_identifierArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * Callbacks that the player must fire. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/player/VideoAdPlayer.VideoAdPlayerCallback.html + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiVideoAdPlayerCallback( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + /** Fire this callback periodically as ad playback occurs. */ + abstract fun onAdProgress( + pigeon_instance: + com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback, + adMediaInfo: com.google.ads.interactivemedia.v3.api.player.AdMediaInfo, + videoProgressUpdate: com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate + ) + + /** Fire this callback when video playback stalls waiting for data. */ + abstract fun onBuffering( + pigeon_instance: + com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback, + adMediaInfo: com.google.ads.interactivemedia.v3.api.player.AdMediaInfo + ) + + /** Fire this callback when all content has finished playing. */ + abstract fun onContentComplete( + pigeon_instance: + com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback + ) + + /** Fire this callback when the video finishes playing. */ + abstract fun onEnded( + pigeon_instance: + com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback, + adMediaInfo: com.google.ads.interactivemedia.v3.api.player.AdMediaInfo + ) + + /** Fire this callback when the video has encountered an error. */ + abstract fun onError( + pigeon_instance: + com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback, + adMediaInfo: com.google.ads.interactivemedia.v3.api.player.AdMediaInfo + ) + + /** Fire this callback when the video is ready to begin playback. */ + abstract fun onLoaded( + pigeon_instance: + com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback, + adMediaInfo: com.google.ads.interactivemedia.v3.api.player.AdMediaInfo + ) + + /** Fire this callback when the video is paused. */ + abstract fun onPause( + pigeon_instance: + com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback, + adMediaInfo: com.google.ads.interactivemedia.v3.api.player.AdMediaInfo + ) + + /** Fire this callback when the player begins playing a video. */ + abstract fun onPlay( + pigeon_instance: + com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback, + adMediaInfo: com.google.ads.interactivemedia.v3.api.player.AdMediaInfo + ) + + /** Fire this callback when the video is unpaused. */ + abstract fun onResume( + pigeon_instance: + com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback, + adMediaInfo: com.google.ads.interactivemedia.v3.api.player.AdMediaInfo + ) + + /** Fire this callback when the playback volume changes. */ + abstract fun onVolumeChanged( + pigeon_instance: + com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback, + adMediaInfo: com.google.ads.interactivemedia.v3.api.player.AdMediaInfo, + percentage: Long + ) + + companion object { + @Suppress("LocalVariableName") + fun setUpMessageHandlers( + binaryMessenger: BinaryMessenger, + api: PigeonApiVideoAdPlayerCallback? + ) { + val codec = api?.pigeonRegistrar?.codec ?: InteractiveMediaAdsLibraryPigeonCodec() + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.VideoAdPlayerCallback.onAdProgress", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] + as + com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback + val adMediaInfoArg = + args[1] as com.google.ads.interactivemedia.v3.api.player.AdMediaInfo + val videoProgressUpdateArg = + args[2] as com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate + val wrapped: List = + try { + api.onAdProgress(pigeon_instanceArg, adMediaInfoArg, videoProgressUpdateArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.VideoAdPlayerCallback.onBuffering", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] + as + com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback + val adMediaInfoArg = + args[1] as com.google.ads.interactivemedia.v3.api.player.AdMediaInfo + val wrapped: List = + try { + api.onBuffering(pigeon_instanceArg, adMediaInfoArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.VideoAdPlayerCallback.onContentComplete", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] + as + com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback + val wrapped: List = + try { + api.onContentComplete(pigeon_instanceArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.VideoAdPlayerCallback.onEnded", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] + as + com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback + val adMediaInfoArg = + args[1] as com.google.ads.interactivemedia.v3.api.player.AdMediaInfo + val wrapped: List = + try { + api.onEnded(pigeon_instanceArg, adMediaInfoArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.VideoAdPlayerCallback.onError", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] + as + com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback + val adMediaInfoArg = + args[1] as com.google.ads.interactivemedia.v3.api.player.AdMediaInfo + val wrapped: List = + try { + api.onError(pigeon_instanceArg, adMediaInfoArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.VideoAdPlayerCallback.onLoaded", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] + as + com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback + val adMediaInfoArg = + args[1] as com.google.ads.interactivemedia.v3.api.player.AdMediaInfo + val wrapped: List = + try { + api.onLoaded(pigeon_instanceArg, adMediaInfoArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.VideoAdPlayerCallback.onPause", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] + as + com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback + val adMediaInfoArg = + args[1] as com.google.ads.interactivemedia.v3.api.player.AdMediaInfo + val wrapped: List = + try { + api.onPause(pigeon_instanceArg, adMediaInfoArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.VideoAdPlayerCallback.onPlay", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] + as + com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback + val adMediaInfoArg = + args[1] as com.google.ads.interactivemedia.v3.api.player.AdMediaInfo + val wrapped: List = + try { + api.onPlay(pigeon_instanceArg, adMediaInfoArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.VideoAdPlayerCallback.onResume", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] + as + com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback + val adMediaInfoArg = + args[1] as com.google.ads.interactivemedia.v3.api.player.AdMediaInfo + val wrapped: List = + try { + api.onResume(pigeon_instanceArg, adMediaInfoArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.VideoAdPlayerCallback.onVolumeChanged", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] + as + com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback + val adMediaInfoArg = + args[1] as com.google.ads.interactivemedia.v3.api.player.AdMediaInfo + val percentageArg = args[2] as Long + val wrapped: List = + try { + api.onVolumeChanged(pigeon_instanceArg, adMediaInfoArg, percentageArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } + } + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of VideoAdPlayerCallback and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: + com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.interactive_media_ads.VideoAdPlayerCallback.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_identifierArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * Defines the set of methods that a video player must implement to be used by the IMA SDK, as well + * as a set of callbacks that it must fire. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/player/VideoAdPlayer.html. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiVideoAdPlayer( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + abstract fun pigeon_defaultConstructor(): + com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer + + /** The volume of the player as a percentage from 0 to 100. */ + abstract fun setVolume( + pigeon_instance: com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer, + value: Long + ) + + /** The `VideoProgressUpdate` describing playback progress of the current video. */ + abstract fun setAdProgress( + pigeon_instance: com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer, + progress: com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate + ) + + companion object { + @Suppress("LocalVariableName") + fun setUpMessageHandlers(binaryMessenger: BinaryMessenger, api: PigeonApiVideoAdPlayer?) { + val codec = api?.pigeonRegistrar?.codec ?: InteractiveMediaAdsLibraryPigeonCodec() + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.pigeon_defaultConstructor", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_identifierArg = args[0] as Long + val wrapped: List = + try { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + api.pigeon_defaultConstructor(), pigeon_identifierArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.setVolume", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] as com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer + val valueArg = args[1] as Long + val wrapped: List = + try { + api.setVolume(pigeon_instanceArg, valueArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.setAdProgress", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] as com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer + val progressArg = + args[1] as com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate + val wrapped: List = + try { + api.setAdProgress(pigeon_instanceArg, progressArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } + } + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of VideoAdPlayer and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + throw IllegalStateException( + "Attempting to create a new Dart instance of VideoAdPlayer, but the class has a nonnull callback method.") + } + + /** Adds a callback. */ + fun addCallback( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer, + callbackArg: + com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.addCallback" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, callbackArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Loads a video ad hosted at AdMediaInfo. */ + fun loadAd( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer, + adMediaInfoArg: com.google.ads.interactivemedia.v3.api.player.AdMediaInfo, + adPodInfoArg: com.google.ads.interactivemedia.v3.api.AdPodInfo, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.loadAd" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, adMediaInfoArg, adPodInfoArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Pauses playing the current ad. */ + fun pauseAd( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer, + adMediaInfoArg: com.google.ads.interactivemedia.v3.api.player.AdMediaInfo, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.pauseAd" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, adMediaInfoArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** + * Starts or resumes playing the video ad referenced by the AdMediaInfo, provided loadAd has + * already been called for it. + */ + fun playAd( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer, + adMediaInfoArg: com.google.ads.interactivemedia.v3.api.player.AdMediaInfo, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.playAd" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, adMediaInfoArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Cleans up and releases all resources used by the `VideoAdPlayer`. */ + fun release( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.release" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Removes a callback. */ + fun removeCallback( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer, + callbackArg: + com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.removeCallback" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, callbackArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Stops playing the current ad. */ + fun stopAd( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer, + adMediaInfoArg: com.google.ads.interactivemedia.v3.api.player.AdMediaInfo, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.stopAd" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, adMediaInfoArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * Listener interface for notification of ad load or stream load completion. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdsLoader.AdsLoadedListener.html. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiAdsLoadedListener( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + abstract fun pigeon_defaultConstructor(): + com.google.ads.interactivemedia.v3.api.AdsLoader.AdsLoadedListener + + companion object { + @Suppress("LocalVariableName") + fun setUpMessageHandlers(binaryMessenger: BinaryMessenger, api: PigeonApiAdsLoadedListener?) { + val codec = api?.pigeonRegistrar?.codec ?: InteractiveMediaAdsLibraryPigeonCodec() + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.AdsLoadedListener.pigeon_defaultConstructor", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_identifierArg = args[0] as Long + val wrapped: List = + try { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + api.pigeon_defaultConstructor(), pigeon_identifierArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } + } + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of AdsLoadedListener and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.AdsLoader.AdsLoadedListener, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + throw IllegalStateException( + "Attempting to create a new Dart instance of AdsLoadedListener, but the class has a nonnull callback method.") + } + + /** Called once the AdsManager or StreamManager has been loaded. */ + fun onAdsManagerLoaded( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.AdsLoader.AdsLoadedListener, + eventArg: com.google.ads.interactivemedia.v3.api.AdsManagerLoadedEvent, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.interactive_media_ads.AdsLoadedListener.onAdsManagerLoaded" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, eventArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * Interface for classes that will listen to AdErrorEvents. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdErrorEvent.AdErrorListener.html. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiAdErrorListener( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + abstract fun pigeon_defaultConstructor(): + com.google.ads.interactivemedia.v3.api.AdErrorEvent.AdErrorListener + + companion object { + @Suppress("LocalVariableName") + fun setUpMessageHandlers(binaryMessenger: BinaryMessenger, api: PigeonApiAdErrorListener?) { + val codec = api?.pigeonRegistrar?.codec ?: InteractiveMediaAdsLibraryPigeonCodec() + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.AdErrorListener.pigeon_defaultConstructor", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_identifierArg = args[0] as Long + val wrapped: List = + try { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + api.pigeon_defaultConstructor(), pigeon_identifierArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } + } + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of AdErrorListener and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.AdErrorEvent.AdErrorListener, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + throw IllegalStateException( + "Attempting to create a new Dart instance of AdErrorListener, but the class has a nonnull callback method.") + } + + /** Called when an error occurs. */ + fun onAdError( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.AdErrorEvent.AdErrorListener, + eventArg: com.google.ads.interactivemedia.v3.api.AdErrorEvent, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.AdErrorListener.onAdError" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, eventArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * Listener interface for ad events. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdEvent.AdEventListener.html. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiAdEventListener( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + abstract fun pigeon_defaultConstructor(): + com.google.ads.interactivemedia.v3.api.AdEvent.AdEventListener + + companion object { + @Suppress("LocalVariableName") + fun setUpMessageHandlers(binaryMessenger: BinaryMessenger, api: PigeonApiAdEventListener?) { + val codec = api?.pigeonRegistrar?.codec ?: InteractiveMediaAdsLibraryPigeonCodec() + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.AdEventListener.pigeon_defaultConstructor", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_identifierArg = args[0] as Long + val wrapped: List = + try { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + api.pigeon_defaultConstructor(), pigeon_identifierArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } + } + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of AdEventListener and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.AdEvent.AdEventListener, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + throw IllegalStateException( + "Attempting to create a new Dart instance of AdEventListener, but the class has a nonnull callback method.") + } + + /** Respond to an occurrence of an AdEvent. */ + fun onAdEvent( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.AdEvent.AdEventListener, + eventArg: com.google.ads.interactivemedia.v3.api.AdEvent, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.AdEventListener.onAdEvent" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, eventArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * Defines parameters that control the rendering of ads. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdsRenderingSettings.html. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiAdsRenderingSettings( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + /** Maximum recommended bitrate. */ + abstract fun getBitrateKbps( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsRenderingSettings + ): Long + + /** Returns whether the click-through URL will be opened using Custom Tabs feature. */ + abstract fun getEnableCustomTabs( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsRenderingSettings + ): Boolean + + /** + * Whether the SDK will instruct the player to load the creative in response to + * `BaseManager.init()`. + */ + abstract fun getEnablePreloading( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsRenderingSettings + ): Boolean + + /** + * Whether to focus on the skip button when the skippable ad can be skipped on Android TV. + * + * This is a no-op on non-Android TV devices. + */ + abstract fun getFocusSkipButtonWhenAvailable( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsRenderingSettings + ): Boolean + + /** The SDK will prioritize the media with MIME type on the list. */ + abstract fun getMimeTypes( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsRenderingSettings + ): List + + /** + * Maximum recommended bitrate. + * + * The value is in kbit/s. Default value, -1, means the bitrate will be selected by the SDK. + */ + abstract fun setBitrateKbps( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsRenderingSettings, + bitrate: Long + ) + + /** + * Notifies the SDK whether to launch the click-through URL using Custom Tabs feature. + * + * Default is false. + */ + abstract fun setEnableCustomTabs( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsRenderingSettings, + enableCustomTabs: Boolean + ) + + /** + * If set, the SDK will instruct the player to load the creative in response to + * `BaseManager.init()`. + * + * This allows the player to preload the ad at any point before calling `AdsManager.start()`. + */ + abstract fun setEnablePreloading( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsRenderingSettings, + enablePreloading: Boolean + ) + + /** + * Set whether to focus on the skip button when the skippable ad can be skipped on Android TV. + * + * This is a no-op on non-Android TV devices. + * + * Default is true. + */ + abstract fun setFocusSkipButtonWhenAvailable( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsRenderingSettings, + enableFocusSkipButton: Boolean + ) + + /** + * Specifies a non-default amount of time to wait for media to load before timing out, in + * milliseconds. + * + * This only applies to the IMA client-side SDK. + * + * Default time is 8000 ms. + */ + abstract fun setLoadVideoTimeout( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsRenderingSettings, + loadVideoTimeout: Long + ) + + /** If specified, the SDK will prioritize the media with MIME type on the list. */ + abstract fun setMimeTypes( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsRenderingSettings, + mimeTypes: List + ) + + /** + * For VMAP and ad rules playlists, only play ad breaks scheduled after this time (in seconds). + */ + abstract fun setPlayAdsAfterTime( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsRenderingSettings, + time: Double + ) + + /** Sets the ad UI elements to be rendered by the IMA SDK. */ + abstract fun setUiElements( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsRenderingSettings, + uiElements: List + ) + + companion object { + @Suppress("LocalVariableName") + fun setUpMessageHandlers( + binaryMessenger: BinaryMessenger, + api: PigeonApiAdsRenderingSettings? + ) { + val codec = api?.pigeonRegistrar?.codec ?: InteractiveMediaAdsLibraryPigeonCodec() + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.getBitrateKbps", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] as com.google.ads.interactivemedia.v3.api.AdsRenderingSettings + val wrapped: List = + try { + listOf(api.getBitrateKbps(pigeon_instanceArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.getEnableCustomTabs", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] as com.google.ads.interactivemedia.v3.api.AdsRenderingSettings + val wrapped: List = + try { + listOf(api.getEnableCustomTabs(pigeon_instanceArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.getEnablePreloading", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] as com.google.ads.interactivemedia.v3.api.AdsRenderingSettings + val wrapped: List = + try { + listOf(api.getEnablePreloading(pigeon_instanceArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.getFocusSkipButtonWhenAvailable", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] as com.google.ads.interactivemedia.v3.api.AdsRenderingSettings + val wrapped: List = + try { + listOf(api.getFocusSkipButtonWhenAvailable(pigeon_instanceArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.getMimeTypes", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] as com.google.ads.interactivemedia.v3.api.AdsRenderingSettings + val wrapped: List = + try { + listOf(api.getMimeTypes(pigeon_instanceArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.setBitrateKbps", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] as com.google.ads.interactivemedia.v3.api.AdsRenderingSettings + val bitrateArg = args[1] as Long + val wrapped: List = + try { + api.setBitrateKbps(pigeon_instanceArg, bitrateArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.setEnableCustomTabs", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] as com.google.ads.interactivemedia.v3.api.AdsRenderingSettings + val enableCustomTabsArg = args[1] as Boolean + val wrapped: List = + try { + api.setEnableCustomTabs(pigeon_instanceArg, enableCustomTabsArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.setEnablePreloading", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] as com.google.ads.interactivemedia.v3.api.AdsRenderingSettings + val enablePreloadingArg = args[1] as Boolean + val wrapped: List = + try { + api.setEnablePreloading(pigeon_instanceArg, enablePreloadingArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.setFocusSkipButtonWhenAvailable", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] as com.google.ads.interactivemedia.v3.api.AdsRenderingSettings + val enableFocusSkipButtonArg = args[1] as Boolean + val wrapped: List = + try { + api.setFocusSkipButtonWhenAvailable(pigeon_instanceArg, enableFocusSkipButtonArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.setLoadVideoTimeout", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] as com.google.ads.interactivemedia.v3.api.AdsRenderingSettings + val loadVideoTimeoutArg = args[1] as Long + val wrapped: List = + try { + api.setLoadVideoTimeout(pigeon_instanceArg, loadVideoTimeoutArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.setMimeTypes", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] as com.google.ads.interactivemedia.v3.api.AdsRenderingSettings + val mimeTypesArg = args[1] as List + val wrapped: List = + try { + api.setMimeTypes(pigeon_instanceArg, mimeTypesArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.setPlayAdsAfterTime", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] as com.google.ads.interactivemedia.v3.api.AdsRenderingSettings + val timeArg = args[1] as Double + val wrapped: List = + try { + api.setPlayAdsAfterTime(pigeon_instanceArg, timeArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.setUiElements", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = + args[0] as com.google.ads.interactivemedia.v3.api.AdsRenderingSettings + val uiElementsArg = args[1] as List + val wrapped: List = + try { + api.setUiElements(pigeon_instanceArg, uiElementsArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } + } + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of AdsRenderingSettings and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.AdsRenderingSettings, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_identifierArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * Represents the progress within this ad break. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdProgressInfo.html. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiAdProgressInfo( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + /** Total ad break duration (in seconds). */ + abstract fun adBreakDuration( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdProgressInfo + ): Double + + /** Total ad period duration (in seconds). */ + abstract fun adPeriodDuration( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdProgressInfo + ): Double + + /** The position of current ad within the ad break, starting with 1. */ + abstract fun adPosition( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdProgressInfo + ): Long + + /** Current time within the ad (in seconds). */ + abstract fun currentTime( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdProgressInfo + ): Double + + /** Duration of current ad (in seconds). */ + abstract fun duration( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdProgressInfo + ): Double + + /** The total number of ads in this ad break. */ + abstract fun totalAds( + pigeon_instance: com.google.ads.interactivemedia.v3.api.AdProgressInfo + ): Long + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of AdProgressInfo and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.AdProgressInfo, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val adBreakDurationArg = adBreakDuration(pigeon_instanceArg) + val adPeriodDurationArg = adPeriodDuration(pigeon_instanceArg) + val adPositionArg = adPosition(pigeon_instanceArg) + val currentTimeArg = currentTime(pigeon_instanceArg) + val durationArg = duration(pigeon_instanceArg) + val totalAdsArg = totalAds(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.AdProgressInfo.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send( + listOf( + pigeon_identifierArg, + adBreakDurationArg, + adPeriodDurationArg, + adPositionArg, + currentTimeArg, + durationArg, + totalAdsArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * An object that holds data corresponding to the companion Ad. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/CompanionAd.html. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiCompanionAd( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + /** The API needed to execute this ad, or null if unavailable. */ + abstract fun apiFramework( + pigeon_instance: com.google.ads.interactivemedia.v3.api.CompanionAd + ): String? + + /** + * The height of the companion in pixels. + * + * 0 if unavailable. + */ + abstract fun height(pigeon_instance: com.google.ads.interactivemedia.v3.api.CompanionAd): Long + + /** The URL for the static resource of this companion. */ + abstract fun resourceValue( + pigeon_instance: com.google.ads.interactivemedia.v3.api.CompanionAd + ): String + + /** + * The width of the companion in pixels. + * + * 0 if unavailable. + */ + abstract fun width(pigeon_instance: com.google.ads.interactivemedia.v3.api.CompanionAd): Long + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of CompanionAd and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.CompanionAd, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val apiFrameworkArg = apiFramework(pigeon_instanceArg) + val heightArg = height(pigeon_instanceArg) + val resourceValueArg = resourceValue(pigeon_instanceArg) + val widthArg = width(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.CompanionAd.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send( + listOf(pigeon_identifierArg, apiFrameworkArg, heightArg, resourceValueArg, widthArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * This object exposes information about the universal ad ID. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/UniversalAdId.html. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiUniversalAdId( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + /** + * Returns the ad ID registry associated with the ad ID value. + * + * Returns "unknown" if the registry is not known. + */ + abstract fun adIdRegistry( + pigeon_instance: com.google.ads.interactivemedia.v3.api.UniversalAdId + ): String + + /** + * Returns the universal ad ID value. + * + * Returns "unknown" if the value is not known. + */ + abstract fun adIdValue( + pigeon_instance: com.google.ads.interactivemedia.v3.api.UniversalAdId + ): String + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of UniversalAdId and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.UniversalAdId, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val adIdRegistryArg = adIdRegistry(pigeon_instanceArg) + val adIdValueArg = adIdValue(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.UniversalAdId.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_identifierArg, adIdRegistryArg, adIdValueArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * An object that holds data corresponding to the main Ad. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/Ad.html. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiAd( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + /** The ad ID as specified in the VAST response. */ + abstract fun adId(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): String + + /** The pod metadata object. */ + abstract fun adPodInfo( + pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad + ): com.google.ads.interactivemedia.v3.api.AdPodInfo + + /** The ad system as specified in the VAST response. */ + abstract fun adSystem(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): String + + /** The IDs of the ads' creatives, starting with the first wrapper ad. */ + abstract fun adWrapperCreativeIds( + pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad + ): List + + /** The wrapper ad IDs as specified in the VAST response. */ + abstract fun adWrapperIds( + pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad + ): List + + /** The wrapper ad systems as specified in the VAST response. */ + abstract fun adWrapperSystems( + pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad + ): List + + /** The advertiser name as defined by the serving party. */ + abstract fun advertiserName(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): String + + /** + * The companions for the current ad while using DAI. + * + * Returns an empty list in any other scenario. + */ + abstract fun companionAds( + pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad + ): List + + /** + * The content type of the currently selected creative, or null if no creative is selected or the + * content type is unavailable. + */ + abstract fun contentType(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): String? + + /** The ISCI (Industry Standard Commercial Identifier) code for an ad. */ + abstract fun creativeAdId(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): String + + /** The ID of the selected creative for the ad, */ + abstract fun creativeId(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): String + + /** The first deal ID present in the wrapper chain for the current ad, starting from the top. */ + abstract fun dealId(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): String + + /** The description of this ad from the VAST response. */ + abstract fun description(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): String? + + /** The duration of the ad in seconds, -1 if not available. */ + abstract fun duration(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): Double + + /** The height of the selected creative if non-linear, else returns 0. */ + abstract fun height(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): Long + + /** The number of seconds of playback before the ad becomes skippable. */ + abstract fun skipTimeOffset(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): Double + + /** The URL associated with the survey for the given ad. */ + abstract fun surveyUrl(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): String? + + /** The title of this ad from the VAST response. */ + abstract fun title(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): String? + + /** The custom parameters associated with the ad at the time of ad trafficking. */ + abstract fun traffickingParameters( + pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad + ): String + + /** Te set of ad UI elements rendered by the IMA SDK for this ad. */ + abstract fun uiElements( + pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad + ): List + + /** The list of all universal ad IDs for this ad. */ + abstract fun universalAdIds( + pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad + ): List + + /** The VAST bitrate in Kbps of the selected creative. */ + abstract fun vastMediaBitrate(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): Long + + /** The VAST media height in pixels of the selected creative. */ + abstract fun vastMediaHeight(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): Long + + /** The VAST media width in pixels of the selected creative. */ + abstract fun vastMediaWidth(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): Long + + /** The width of the selected creative if non-linear, else returns 0. */ + abstract fun width(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): Long + + /** Indicates whether the ad’s current mode of operation is linear or non-linear. */ + abstract fun isLinear(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): Boolean + + /** Indicates whether the ad can be skipped by the user. */ + abstract fun isSkippable(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): Boolean + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of Ad and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.Ad, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val adIdArg = adId(pigeon_instanceArg) + val adPodInfoArg = adPodInfo(pigeon_instanceArg) + val adSystemArg = adSystem(pigeon_instanceArg) + val adWrapperCreativeIdsArg = adWrapperCreativeIds(pigeon_instanceArg) + val adWrapperIdsArg = adWrapperIds(pigeon_instanceArg) + val adWrapperSystemsArg = adWrapperSystems(pigeon_instanceArg) + val advertiserNameArg = advertiserName(pigeon_instanceArg) + val companionAdsArg = companionAds(pigeon_instanceArg) + val contentTypeArg = contentType(pigeon_instanceArg) + val creativeAdIdArg = creativeAdId(pigeon_instanceArg) + val creativeIdArg = creativeId(pigeon_instanceArg) + val dealIdArg = dealId(pigeon_instanceArg) + val descriptionArg = description(pigeon_instanceArg) + val durationArg = duration(pigeon_instanceArg) + val heightArg = height(pigeon_instanceArg) + val skipTimeOffsetArg = skipTimeOffset(pigeon_instanceArg) + val surveyUrlArg = surveyUrl(pigeon_instanceArg) + val titleArg = title(pigeon_instanceArg) + val traffickingParametersArg = traffickingParameters(pigeon_instanceArg) + val uiElementsArg = uiElements(pigeon_instanceArg) + val universalAdIdsArg = universalAdIds(pigeon_instanceArg) + val vastMediaBitrateArg = vastMediaBitrate(pigeon_instanceArg) + val vastMediaHeightArg = vastMediaHeight(pigeon_instanceArg) + val vastMediaWidthArg = vastMediaWidth(pigeon_instanceArg) + val widthArg = width(pigeon_instanceArg) + val isLinearArg = isLinear(pigeon_instanceArg) + val isSkippableArg = isSkippable(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send( + listOf( + pigeon_identifierArg, + adIdArg, + adPodInfoArg, + adSystemArg, + adWrapperCreativeIdsArg, + adWrapperIdsArg, + adWrapperSystemsArg, + advertiserNameArg, + companionAdsArg, + contentTypeArg, + creativeAdIdArg, + creativeIdArg, + dealIdArg, + descriptionArg, + durationArg, + heightArg, + skipTimeOffsetArg, + surveyUrlArg, + titleArg, + traffickingParametersArg, + uiElementsArg, + universalAdIdsArg, + vastMediaBitrateArg, + vastMediaHeightArg, + vastMediaWidthArg, + widthArg, + isLinearArg, + isSkippableArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/InteractiveMediaAdsPlugin.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/InteractiveMediaAdsPlugin.kt index 50595236588a..ce7d1fba5741 100644 --- a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/InteractiveMediaAdsPlugin.kt +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/InteractiveMediaAdsPlugin.kt @@ -4,34 +4,75 @@ package dev.flutter.packages.interactive_media_ads +import android.content.Context +import android.view.View import io.flutter.embedding.engine.plugins.FlutterPlugin -import io.flutter.plugin.common.MethodCall -import io.flutter.plugin.common.MethodChannel -import io.flutter.plugin.common.MethodChannel.MethodCallHandler -import io.flutter.plugin.common.MethodChannel.Result +import io.flutter.embedding.engine.plugins.activity.ActivityAware +import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding +import io.flutter.plugin.common.StandardMessageCodec +import io.flutter.plugin.platform.PlatformView +import io.flutter.plugin.platform.PlatformViewFactory /** InteractiveMediaAdsPlugin */ -class InteractiveMediaAdsPlugin : FlutterPlugin, MethodCallHandler { - /// The MethodChannel that will the communication between Flutter and native Android - /// - /// This local reference serves to register the plugin with the Flutter Engine and unregister it - /// when the Flutter Engine is detached from the Activity - private lateinit var channel: MethodChannel +class InteractiveMediaAdsPlugin : FlutterPlugin, ActivityAware { + private lateinit var pluginBinding: FlutterPlugin.FlutterPluginBinding + private lateinit var registrar: ProxyApiRegistrar override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { - channel = MethodChannel(flutterPluginBinding.binaryMessenger, "interactive_media_ads") - channel.setMethodCallHandler(this) - } + pluginBinding = flutterPluginBinding - override fun onMethodCall(call: MethodCall, result: Result) { - if (call.method == "getPlatformVersion") { - result.success("Android ${android.os.Build.VERSION.RELEASE}") - } else { - result.notImplemented() - } + registrar = + ProxyApiRegistrar(pluginBinding.binaryMessenger, context = pluginBinding.applicationContext) + registrar.setUp() + + flutterPluginBinding.platformViewRegistry.registerViewFactory( + "interactive_media_ads.packages.flutter.dev/view", + FlutterViewFactory(registrar.instanceManager)) } override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { - channel.setMethodCallHandler(null) + registrar.ignoreCallsToDart = true + registrar.tearDown() + registrar.instanceManager.clear() + } + + override fun onAttachedToActivity(binding: ActivityPluginBinding) { + registrar.context = binding.activity + } + + override fun onDetachedFromActivityForConfigChanges() { + registrar.context = pluginBinding.applicationContext + } + + override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) { + registrar.context = binding.activity + } + + override fun onDetachedFromActivity() { + registrar.context = pluginBinding.applicationContext + } +} + +internal class FlutterViewFactory( + private val instanceManager: InteractiveMediaAdsLibraryPigeonInstanceManager +) : PlatformViewFactory(StandardMessageCodec.INSTANCE) { + + override fun create(context: Context, viewId: Int, args: Any?): PlatformView { + val identifier = + args as Int? + ?: throw IllegalStateException("An identifier is required to retrieve a View instance.") + val instance: Any? = instanceManager.getInstance(identifier.toLong()) + if (instance is PlatformView) { + return instance + } else if (instance is View) { + return object : PlatformView { + override fun getView(): View { + return instance + } + + override fun dispose() {} + } + } + throw IllegalStateException("Unable to find a PlatformView or View instance: $args, $instance") } } diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/MediaPlayerProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/MediaPlayerProxyApi.kt new file mode 100644 index 000000000000..61915a2bc03a --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/MediaPlayerProxyApi.kt @@ -0,0 +1,36 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import android.media.MediaPlayer + +/** + * ProxyApi implementation for [MediaPlayer]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class MediaPlayerProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiMediaPlayer(pigeonRegistrar) { + override fun getDuration(pigeon_instance: MediaPlayer): Long { + return pigeon_instance.duration.toLong() + } + + override fun seekTo(pigeon_instance: MediaPlayer, mSec: Long) { + pigeon_instance.seekTo(mSec.toInt()) + } + + override fun start(pigeon_instance: MediaPlayer) { + pigeon_instance.start() + } + + override fun pause(pigeon_instance: MediaPlayer) { + pigeon_instance.pause() + } + + override fun stop(pigeon_instance: MediaPlayer) { + pigeon_instance.stop() + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ProxyApiRegistrar.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ProxyApiRegistrar.kt new file mode 100644 index 000000000000..d1cfda322bea --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ProxyApiRegistrar.kt @@ -0,0 +1,148 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import android.content.Context +import android.os.Handler +import android.os.Looper +import io.flutter.plugin.common.BinaryMessenger + +/** + * Implementation of [InteractiveMediaAdsLibraryPigeonProxyApiRegistrar] that provides each ProxyApi + * implementation and any additional resources needed by an implementation. + */ +open class ProxyApiRegistrar(binaryMessenger: BinaryMessenger, var context: Context) : + InteractiveMediaAdsLibraryPigeonProxyApiRegistrar(binaryMessenger) { + + // Added to be overriden for tests. The test implementation calls `callback` immediately, instead + // of waiting for the main thread to run it. + internal open fun runOnMainThread(callback: Runnable) { + Handler(Looper.getMainLooper()).post { callback.run() } + } + + override fun getPigeonApiBaseDisplayContainer(): PigeonApiBaseDisplayContainer { + return BaseDisplayContainerProxyApi(this) + } + + override fun getPigeonApiAdDisplayContainer(): PigeonApiAdDisplayContainer { + return AdDisplayContainerProxyApi(this) + } + + override fun getPigeonApiAdsLoader(): PigeonApiAdsLoader { + return AdsLoaderProxyApi(this) + } + + override fun getPigeonApiAdsManagerLoadedEvent(): PigeonApiAdsManagerLoadedEvent { + return AdsManagerLoadedEventProxyApi(this) + } + + override fun getPigeonApiAdsLoadedListener(): PigeonApiAdsLoadedListener { + return AdsLoadedListenerProxyApi(this) + } + + override fun getPigeonApiAdErrorListener(): PigeonApiAdErrorListener { + return AdErrorListenerProxyApi(this) + } + + override fun getPigeonApiAdErrorEvent(): PigeonApiAdErrorEvent { + return AdErrorEventProxyApi(this) + } + + override fun getPigeonApiAdError(): PigeonApiAdError { + return AdErrorProxyApi(this) + } + + override fun getPigeonApiAdsRequest(): PigeonApiAdsRequest { + return AdsRequestProxyApi(this) + } + + override fun getPigeonApiContentProgressProvider(): PigeonApiContentProgressProvider { + return ContentProgressProviderProxyApi(this) + } + + override fun getPigeonApiAdsManager(): PigeonApiAdsManager { + return AdsManagerProxyApi(this) + } + + override fun getPigeonApiBaseManager(): PigeonApiBaseManager { + return BaseManagerProxyApi(this) + } + + override fun getPigeonApiAdEventListener(): PigeonApiAdEventListener { + return AdEventListenerProxyApi(this) + } + + override fun getPigeonApiAdEvent(): PigeonApiAdEvent { + return AdEventProxyApi(this) + } + + override fun getPigeonApiImaSdkFactory(): PigeonApiImaSdkFactory { + return ImaSdkFactoryProxyApi(this) + } + + override fun getPigeonApiImaSdkSettings(): PigeonApiImaSdkSettings { + return ImaSdkSettingsProxyApi(this) + } + + override fun getPigeonApiVideoAdPlayer(): PigeonApiVideoAdPlayer { + return VideoAdPlayerProxyApi(this) + } + + override fun getPigeonApiVideoProgressUpdate(): PigeonApiVideoProgressUpdate { + return VideoProgressUpdateProxyApi(this) + } + + override fun getPigeonApiVideoAdPlayerCallback(): PigeonApiVideoAdPlayerCallback { + return VideoAdPlayerCallbackProxyApi(this) + } + + override fun getPigeonApiAdMediaInfo(): PigeonApiAdMediaInfo { + return AdMediaInfoProxyApi(this) + } + + override fun getPigeonApiAdPodInfo(): PigeonApiAdPodInfo { + return AdPodInfoProxyApi(this) + } + + override fun getPigeonApiFrameLayout(): PigeonApiFrameLayout { + return FrameLayoutProxyApi(this) + } + + override fun getPigeonApiViewGroup(): PigeonApiViewGroup { + return ViewGroupProxyApi(this) + } + + override fun getPigeonApiVideoView(): PigeonApiVideoView { + return VideoViewProxyApi(this) + } + + override fun getPigeonApiView(): PigeonApiView { + return ViewProxyApi(this) + } + + override fun getPigeonApiMediaPlayer(): PigeonApiMediaPlayer { + return MediaPlayerProxyApi(this) + } + + override fun getPigeonApiAdsRenderingSettings(): PigeonApiAdsRenderingSettings { + return AdsRenderingSettingsProxyApi(this) + } + + override fun getPigeonApiAdProgressInfo(): PigeonApiAdProgressInfo { + return AdProgressInfoProxyApi(this) + } + + override fun getPigeonApiCompanionAd(): PigeonApiCompanionAd { + return CompanionAdProxyApi(this) + } + + override fun getPigeonApiUniversalAdId(): PigeonApiUniversalAdId { + return UniversalAdIdProxyApi(this) + } + + override fun getPigeonApiAd(): PigeonApiAd { + return AdProxyApi(this) + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/UniversalAdIdProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/UniversalAdIdProxyApi.kt new file mode 100644 index 000000000000..237ee69e93d9 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/UniversalAdIdProxyApi.kt @@ -0,0 +1,24 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.UniversalAdId + +/** + * ProxyApi implementation for [UniversalAdId]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class UniversalAdIdProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiUniversalAdId(pigeonRegistrar) { + override fun adIdRegistry(pigeon_instance: UniversalAdId): String { + return pigeon_instance.adIdRegistry + } + + override fun adIdValue(pigeon_instance: UniversalAdId): String { + return pigeon_instance.adIdValue + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/VideoAdPlayerCallbackProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/VideoAdPlayerCallbackProxyApi.kt new file mode 100644 index 000000000000..dc10cbd77533 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/VideoAdPlayerCallbackProxyApi.kt @@ -0,0 +1,87 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.player.AdMediaInfo +import com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer +import com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate + +/** + * ProxyApi implementation for [VideoAdPlayer.VideoAdPlayerCallback]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class VideoAdPlayerCallbackProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiVideoAdPlayerCallback(pigeonRegistrar) { + override fun onAdProgress( + pigeon_instance: VideoAdPlayer.VideoAdPlayerCallback, + adMediaInfo: AdMediaInfo, + videoProgressUpdate: VideoProgressUpdate + ) { + pigeon_instance.onAdProgress(adMediaInfo, videoProgressUpdate) + } + + override fun onBuffering( + pigeon_instance: VideoAdPlayer.VideoAdPlayerCallback, + adMediaInfo: AdMediaInfo + ) { + pigeon_instance.onBuffering(adMediaInfo) + } + + override fun onContentComplete(pigeon_instance: VideoAdPlayer.VideoAdPlayerCallback) { + pigeon_instance.onContentComplete() + } + + override fun onEnded( + pigeon_instance: VideoAdPlayer.VideoAdPlayerCallback, + adMediaInfo: AdMediaInfo + ) { + pigeon_instance.onEnded(adMediaInfo) + } + + override fun onError( + pigeon_instance: VideoAdPlayer.VideoAdPlayerCallback, + adMediaInfo: AdMediaInfo + ) { + pigeon_instance.onError(adMediaInfo) + } + + override fun onLoaded( + pigeon_instance: VideoAdPlayer.VideoAdPlayerCallback, + adMediaInfo: AdMediaInfo + ) { + pigeon_instance.onLoaded(adMediaInfo) + } + + override fun onPause( + pigeon_instance: VideoAdPlayer.VideoAdPlayerCallback, + adMediaInfo: AdMediaInfo + ) { + pigeon_instance.onPause(adMediaInfo) + } + + override fun onPlay( + pigeon_instance: VideoAdPlayer.VideoAdPlayerCallback, + adMediaInfo: AdMediaInfo + ) { + pigeon_instance.onPlay(adMediaInfo) + } + + override fun onResume( + pigeon_instance: VideoAdPlayer.VideoAdPlayerCallback, + adMediaInfo: AdMediaInfo + ) { + pigeon_instance.onResume(adMediaInfo) + } + + override fun onVolumeChanged( + pigeon_instance: VideoAdPlayer.VideoAdPlayerCallback, + adMediaInfo: AdMediaInfo, + percentage: Long + ) { + pigeon_instance.onVolumeChanged(adMediaInfo, percentage.toInt()) + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/VideoAdPlayerProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/VideoAdPlayerProxyApi.kt new file mode 100644 index 000000000000..5c79153bac74 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/VideoAdPlayerProxyApi.kt @@ -0,0 +1,80 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdPodInfo +import com.google.ads.interactivemedia.v3.api.player.AdMediaInfo +import com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer +import com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate + +/** + * ProxyApi implementation for [VideoAdPlayer]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class VideoAdPlayerProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiVideoAdPlayer(pigeonRegistrar) { + override fun pigeon_defaultConstructor(): VideoAdPlayer { + return VideoAdPlayerImpl(this) + } + + internal class VideoAdPlayerImpl(val api: VideoAdPlayerProxyApi) : VideoAdPlayer { + var savedVolume: Int = 0 + + var savedAdProgress: VideoProgressUpdate = VideoProgressUpdate.VIDEO_TIME_NOT_READY + + override fun getAdProgress(): VideoProgressUpdate { + return savedAdProgress + } + + override fun getVolume(): Int { + return savedVolume + } + + override fun addCallback(callback: VideoAdPlayer.VideoAdPlayerCallback) { + api.pigeonRegistrar.runOnMainThread { api.addCallback(this, callbackArg = callback) {} } + } + + override fun loadAd(adMediaInfo: AdMediaInfo, adPodInfo: AdPodInfo) { + api.pigeonRegistrar.runOnMainThread { api.loadAd(this, adMediaInfo, adPodInfo) {} } + } + + override fun pauseAd(adMediaInfo: AdMediaInfo) { + api.pigeonRegistrar.runOnMainThread { api.pauseAd(this, adMediaInfo) {} } + } + + override fun playAd(adMediaInfo: AdMediaInfo) { + api.pigeonRegistrar.runOnMainThread { api.playAd(this, adMediaInfo) {} } + } + + override fun release() { + api.pigeonRegistrar.runOnMainThread { api.release(this) {} } + } + + override fun removeCallback(callback: VideoAdPlayer.VideoAdPlayerCallback) { + api.pigeonRegistrar.runOnMainThread { api.removeCallback(this, callbackArg = callback) {} } + } + + override fun stopAd(adMediaInfo: AdMediaInfo) { + api.pigeonRegistrar.runOnMainThread { api.stopAd(this, adMediaInfo) {} } + } + } + + /** + * Sets the internal `volume` variable that is returned in the [VideoAdPlayer.getVolume] callback. + */ + override fun setVolume(pigeon_instance: VideoAdPlayer, value: Long) { + (pigeon_instance as VideoAdPlayerImpl).savedVolume = value.toInt() + } + + /** + * Sets the internal `adProgress` variable that is returned in the [VideoAdPlayer.getAdProgress] + * callback. + */ + override fun setAdProgress(pigeon_instance: VideoAdPlayer, progress: VideoProgressUpdate) { + (pigeon_instance as VideoAdPlayerImpl).savedAdProgress = progress + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/VideoProgressUpdateProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/VideoProgressUpdateProxyApi.kt new file mode 100644 index 000000000000..307bf6ec3f3b --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/VideoProgressUpdateProxyApi.kt @@ -0,0 +1,27 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate + +/** + * ProxyApi implementation for [VideoProgressUpdate]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class VideoProgressUpdateProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiVideoProgressUpdate(pigeonRegistrar) { + override fun pigeon_defaultConstructor( + currentTimeMs: Long, + durationMs: Long + ): VideoProgressUpdate { + return VideoProgressUpdate(currentTimeMs, durationMs) + } + + override fun videoTimeNotReady(): VideoProgressUpdate { + return VideoProgressUpdate.VIDEO_TIME_NOT_READY + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/VideoViewProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/VideoViewProxyApi.kt new file mode 100644 index 000000000000..a9634cb44f4f --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/VideoViewProxyApi.kt @@ -0,0 +1,38 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import android.media.MediaPlayer +import android.net.Uri +import android.widget.VideoView + +/** + * ProxyApi implementation for [VideoView]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class VideoViewProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiVideoView(pigeonRegistrar) { + + override fun pigeon_defaultConstructor(): VideoView { + val instance = VideoView(pigeonRegistrar.context) + instance.setOnPreparedListener { player: MediaPlayer -> onPrepared(instance, player) {} } + instance.setOnErrorListener { player: MediaPlayer, what: Int, extra: Int -> + onError(instance, player, what.toLong(), extra.toLong()) {} + true + } + instance.setOnCompletionListener { player: MediaPlayer -> onCompletion(instance, player) {} } + return instance + } + + override fun setVideoUri(pigeon_instance: VideoView, uri: String?) { + pigeon_instance.setVideoURI(if (uri != null) Uri.parse(uri) else null) + } + + override fun getCurrentPosition(pigeon_instance: VideoView): Long { + return pigeon_instance.currentPosition.toLong() + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ViewGroupProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ViewGroupProxyApi.kt new file mode 100644 index 000000000000..8c891ad5e009 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ViewGroupProxyApi.kt @@ -0,0 +1,25 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import android.view.View +import android.view.ViewGroup + +/** + * ProxyApi implementation for [ViewGroup]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class ViewGroupProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiViewGroup(pigeonRegistrar) { + override fun addView(pigeon_instance: ViewGroup, view: View) { + pigeon_instance.addView(view) + } + + override fun removeView(pigeon_instance: ViewGroup, view: View) { + pigeon_instance.removeView(view) + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ViewProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ViewProxyApi.kt new file mode 100644 index 000000000000..59934e882254 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ViewProxyApi.kt @@ -0,0 +1,14 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +/** + * ProxyApi implementation for [android.view.View]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class ViewProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiView(pigeonRegistrar) diff --git a/packages/interactive_media_ads/android/src/test/kotlin/android/net/Uri.kt b/packages/interactive_media_ads/android/src/test/kotlin/android/net/Uri.kt new file mode 100644 index 000000000000..107eef275d93 --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/android/net/Uri.kt @@ -0,0 +1,22 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package android.net + +/** + * Redeclaration of Uri that works for tests. + * + * Without this redeclaration, `Uri.parse` always returns null. + */ +class Uri { + companion object { + @JvmStatic var lastValue: String? = null + + @JvmStatic + fun parse(value: String): Uri { + lastValue = value + return Uri() + } + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdErrorEventProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdErrorEventProxyApiTest.kt new file mode 100644 index 000000000000..e51f4f66894e --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdErrorEventProxyApiTest.kt @@ -0,0 +1,25 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdError +import com.google.ads.interactivemedia.v3.api.AdErrorEvent +import kotlin.test.Test +import kotlin.test.assertEquals +import org.mockito.Mockito.mock +import org.mockito.kotlin.whenever + +internal class AdErrorEventProxyApiTest { + @Test + fun error() { + val api = TestProxyApiRegistrar().getPigeonApiAdErrorEvent() + + val instance = mock() + val mockError = mock() + whenever(instance.error).thenReturn(mockError) + + assertEquals(mockError, api.error(instance)) + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdErrorListenerProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdErrorListenerProxyApiTest.kt new file mode 100644 index 000000000000..10890f84d613 --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdErrorListenerProxyApiTest.kt @@ -0,0 +1,35 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdErrorEvent +import kotlin.test.Test +import kotlin.test.assertTrue +import org.mockito.Mockito.mock +import org.mockito.Mockito.verify +import org.mockito.kotlin.any +import org.mockito.kotlin.eq +import org.mockito.kotlin.whenever + +internal class AdErrorListenerProxyApiTest { + @Test + fun pigeon_defaultConstructor() { + val api = TestProxyApiRegistrar().getPigeonApiAdErrorListener() + + assertTrue(api.pigeon_defaultConstructor() is AdErrorListenerProxyApi.AdErrorListenerImpl) + } + + @Test + fun onAdError() { + val mockApi = mock() + whenever(mockApi.pigeonRegistrar).thenReturn(TestProxyApiRegistrar()) + + val instance = AdErrorListenerProxyApi.AdErrorListenerImpl(mockApi) + val mockEvent = mock() + instance.onAdError(mockEvent) + + verify(mockApi).onAdError(eq(instance), eq(mockEvent), any()) + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdErrorProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdErrorProxyApiTest.kt new file mode 100644 index 000000000000..62e8efe927f9 --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdErrorProxyApiTest.kt @@ -0,0 +1,53 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdError +import kotlin.test.Test +import kotlin.test.assertEquals +import org.mockito.Mockito +import org.mockito.kotlin.whenever + +class AdErrorProxyApiTest { + @Test + fun errorCode() { + val api = TestProxyApiRegistrar().getPigeonApiAdError() + + val instance = Mockito.mock() + whenever(instance.errorCode).thenReturn(AdError.AdErrorCode.VIDEO_PLAY_ERROR) + + assertEquals(AdErrorCode.VIDEO_PLAY_ERROR, api.errorCode(instance)) + } + + @Test + fun errorCodeNumber() { + val api = TestProxyApiRegistrar().getPigeonApiAdError() + + val instance = Mockito.mock() + whenever(instance.errorCodeNumber).thenReturn(0) + + assertEquals(0, api.errorCodeNumber(instance)) + } + + @Test + fun errorType() { + val api = TestProxyApiRegistrar().getPigeonApiAdError() + + val instance = Mockito.mock() + whenever(instance.errorType).thenReturn(AdError.AdErrorType.LOAD) + + assertEquals(AdErrorType.LOAD, api.errorType(instance)) + } + + @Test + fun message() { + val api = TestProxyApiRegistrar().getPigeonApiAdError() + + val instance = Mockito.mock() + whenever(instance.message).thenReturn("message") + + assertEquals("message", api.message(instance)) + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdEventListenerProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdEventListenerProxyApiTest.kt new file mode 100644 index 000000000000..02904a9005b0 --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdEventListenerProxyApiTest.kt @@ -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. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdEvent +import kotlin.test.Test +import kotlin.test.assertTrue +import org.mockito.Mockito +import org.mockito.kotlin.any +import org.mockito.kotlin.eq +import org.mockito.kotlin.whenever + +class AdEventListenerProxyApiTest { + @Test + fun pigeon_defaultConstructor() { + val api = TestProxyApiRegistrar().getPigeonApiAdEventListener() + + assertTrue(api.pigeon_defaultConstructor() is AdEventListenerProxyApi.AdEventListenerImpl) + } + + @Test + fun onAdEvent() { + val mockApi = Mockito.mock() + whenever(mockApi.pigeonRegistrar).thenReturn(TestProxyApiRegistrar()) + + val instance = AdEventListenerProxyApi.AdEventListenerImpl(mockApi) + val mockEvent = Mockito.mock() + instance.onAdEvent(mockEvent) + + Mockito.verify(mockApi).onAdEvent(eq(instance), eq(mockEvent), any()) + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdEventProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdEventProxyApiTest.kt new file mode 100644 index 000000000000..974ad7b5f3ef --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdEventProxyApiTest.kt @@ -0,0 +1,33 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdEvent +import kotlin.test.Test +import kotlin.test.assertEquals +import org.mockito.Mockito +import org.mockito.kotlin.whenever + +class AdEventProxyApiTest { + @Test + fun type() { + val api = TestProxyApiRegistrar().getPigeonApiAdEvent() + + val instance = Mockito.mock() + whenever(instance.type).thenReturn(AdEvent.AdEventType.PAUSED) + + assertEquals(AdEventType.PAUSED, api.type(instance)) + } + + @Test + fun adData() { + val api = TestProxyApiRegistrar().getPigeonApiAdEvent() + + val instance = Mockito.mock() + whenever(instance.adData).thenReturn(mapOf("a" to "b", "c" to "d")) + + assertEquals(mapOf("a" to "b", "c" to "d"), api.adData(instance)) + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdMediaInfoProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdMediaInfoProxyApiTest.kt new file mode 100644 index 000000000000..37602d5ab9ee --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdMediaInfoProxyApiTest.kt @@ -0,0 +1,23 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.player.AdMediaInfo +import kotlin.test.Test +import kotlin.test.assertEquals +import org.mockito.Mockito +import org.mockito.kotlin.whenever + +class AdMediaInfoProxyApiTest { + @Test + fun url() { + val api = TestProxyApiRegistrar().getPigeonApiAdMediaInfo() + + val instance = Mockito.mock() + whenever(instance.url).thenReturn("url") + + assertEquals("url", api.url(instance)) + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdPodInfoProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdPodInfoProxyApiTest.kt new file mode 100644 index 000000000000..b1610f25108d --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdPodInfoProxyApiTest.kt @@ -0,0 +1,73 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdPodInfo +import kotlin.test.Test +import kotlin.test.assertEquals +import org.mockito.Mockito +import org.mockito.kotlin.whenever + +class AdPodInfoProxyApiTest { + @Test + fun adPosition() { + val api = TestProxyApiRegistrar().getPigeonApiAdPodInfo() + + val instance = Mockito.mock() + whenever(instance.adPosition).thenReturn(0) + + assertEquals(0, api.adPosition(instance)) + } + + @Test + fun maxDuration() { + val api = TestProxyApiRegistrar().getPigeonApiAdPodInfo() + + val instance = Mockito.mock() + whenever(instance.maxDuration).thenReturn(0.0) + + assertEquals(0.0, api.maxDuration(instance)) + } + + @Test + fun podIndex() { + val api = TestProxyApiRegistrar().getPigeonApiAdPodInfo() + + val instance = Mockito.mock() + whenever(instance.podIndex).thenReturn(0) + + assertEquals(0, api.podIndex(instance)) + } + + @Test + fun timeOffset() { + val api = TestProxyApiRegistrar().getPigeonApiAdPodInfo() + + val instance = Mockito.mock() + whenever(instance.timeOffset).thenReturn(0.0) + + assertEquals(0.0, api.timeOffset(instance)) + } + + @Test + fun totalAds() { + val api = TestProxyApiRegistrar().getPigeonApiAdPodInfo() + + val instance = Mockito.mock() + whenever(instance.totalAds).thenReturn(0) + + assertEquals(0, api.totalAds(instance)) + } + + @Test + fun isBumper() { + val api = TestProxyApiRegistrar().getPigeonApiAdPodInfo() + + val instance = Mockito.mock() + whenever(instance.isBumper).thenReturn(true) + + assertEquals(true, api.isBumper(instance)) + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdProgressInfoProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdProgressInfoProxyApiTest.kt new file mode 100644 index 000000000000..8745bbf89f75 --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdProgressInfoProxyApiTest.kt @@ -0,0 +1,79 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdProgressInfo +import kotlin.test.Test +import kotlin.test.assertEquals +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever + +class AdProgressInfoProxyApiTest { + @Test + fun adBreakDuration() { + val api = TestProxyApiRegistrar().getPigeonApiAdProgressInfo() + + val instance = mock() + val value = 1.0 + whenever(instance.adBreakDuration).thenReturn(value) + + assertEquals(value, api.adBreakDuration(instance)) + } + + @Test + fun adPeriodDuration() { + val api = TestProxyApiRegistrar().getPigeonApiAdProgressInfo() + + val instance = mock() + val value = 1.0 + whenever(instance.adPeriodDuration).thenReturn(value) + + assertEquals(value, api.adPeriodDuration(instance)) + } + + @Test + fun adPosition() { + val api = TestProxyApiRegistrar().getPigeonApiAdProgressInfo() + + val instance = mock() + val value = 0 + whenever(instance.adPosition).thenReturn(value) + + assertEquals(value.toLong(), api.adPosition(instance)) + } + + @Test + fun currentTime() { + val api = TestProxyApiRegistrar().getPigeonApiAdProgressInfo() + + val instance = mock() + val value = 1.0 + whenever(instance.currentTime).thenReturn(value) + + assertEquals(value, api.currentTime(instance)) + } + + @Test + fun duration() { + val api = TestProxyApiRegistrar().getPigeonApiAdProgressInfo() + + val instance = mock() + val value = 1.0 + whenever(instance.duration).thenReturn(value) + + assertEquals(value, api.duration(instance)) + } + + @Test + fun totalAds() { + val api = TestProxyApiRegistrar().getPigeonApiAdProgressInfo() + + val instance = mock() + val value = 0 + whenever(instance.totalAds).thenReturn(value) + + assertEquals(value.toLong(), api.totalAds(instance)) + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdProxyApiTest.kt new file mode 100644 index 000000000000..65e498f18c91 --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdProxyApiTest.kt @@ -0,0 +1,316 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.Ad +import com.google.ads.interactivemedia.v3.api.AdPodInfo +import com.google.ads.interactivemedia.v3.api.CompanionAd +import com.google.ads.interactivemedia.v3.api.UiElement +import com.google.ads.interactivemedia.v3.api.UniversalAdId +import kotlin.test.Test +import kotlin.test.assertEquals +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever + +class AdProxyApiTest { + @Test + fun adId() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = "myString" + whenever(instance.adId).thenReturn(value) + + assertEquals(value, api.adId(instance)) + } + + @Test + fun adPodInfo() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = mock() + whenever(instance.adPodInfo).thenReturn(value) + + assertEquals(value, api.adPodInfo(instance)) + } + + @Test + fun adSystem() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = "myString" + whenever(instance.adSystem).thenReturn(value) + + assertEquals(value, api.adSystem(instance)) + } + + @Test + fun adWrapperCreativeIds() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = listOf("myString") + whenever(instance.adWrapperCreativeIds).thenReturn(arrayOf("myString")) + + assertEquals(value, api.adWrapperCreativeIds(instance)) + } + + @Test + fun adWrapperIds() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = listOf("myString") + whenever(instance.adWrapperIds).thenReturn(arrayOf("myString")) + + assertEquals(value, api.adWrapperIds(instance)) + } + + @Test + fun adWrapperSystems() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = listOf("myString") + whenever(instance.adWrapperSystems).thenReturn(arrayOf("myString")) + + assertEquals(value, api.adWrapperSystems(instance)) + } + + @Test + fun advertiserName() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = "myString" + whenever(instance.advertiserName).thenReturn(value) + + assertEquals(value, api.advertiserName(instance)) + } + + @Test + fun companionAds() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = listOf(mock()) + whenever(instance.companionAds).thenReturn(value) + + assertEquals(value, api.companionAds(instance)) + } + + @Test + fun contentType() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = "myString" + whenever(instance.contentType).thenReturn(value) + + assertEquals(value, api.contentType(instance)) + } + + @Test + fun creativeAdId() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = "myString" + whenever(instance.creativeAdId).thenReturn(value) + + assertEquals(value, api.creativeAdId(instance)) + } + + @Test + fun creativeId() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = "myString" + whenever(instance.creativeId).thenReturn(value) + + assertEquals(value, api.creativeId(instance)) + } + + @Test + fun dealId() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = "myString" + whenever(instance.dealId).thenReturn(value) + + assertEquals(value, api.dealId(instance)) + } + + @Test + fun description() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = "myString" + whenever(instance.description).thenReturn(value) + + assertEquals(value, api.description(instance)) + } + + @Test + fun duration() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = 1.0 + whenever(instance.duration).thenReturn(value) + + assertEquals(value, api.duration(instance)) + } + + @Test + fun height() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = 0 + whenever(instance.height).thenReturn(value) + + assertEquals(value.toLong(), api.height(instance)) + } + + @Test + fun skipTimeOffset() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = 1.0 + whenever(instance.skipTimeOffset).thenReturn(value) + + assertEquals(value, api.skipTimeOffset(instance)) + } + + @Test + fun surveyUrl() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = "myString" + whenever(instance.surveyUrl).thenReturn(value) + + assertEquals(value, api.surveyUrl(instance)) + } + + @Test + fun title() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = "myString" + whenever(instance.title).thenReturn(value) + + assertEquals(value, api.title(instance)) + } + + @Test + fun traffickingParameters() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = "myString" + whenever(instance.traffickingParameters).thenReturn(value) + + assertEquals(value, api.traffickingParameters(instance)) + } + + @Test + fun uiElements() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = listOf(UiElement.AD_ATTRIBUTION) + whenever(instance.uiElements).thenReturn(value.toSet()) + + assertEquals( + listOf(dev.flutter.packages.interactive_media_ads.UiElement.AD_ATTRIBUTION), + api.uiElements(instance)) + } + + @Test + fun universalAdIds() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = listOf(mock()) + whenever(instance.universalAdIds).thenReturn(value.toTypedArray()) + + assertEquals(value, api.universalAdIds(instance)) + } + + @Test + fun vastMediaBitrate() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = 0 + whenever(instance.vastMediaBitrate).thenReturn(value) + + assertEquals(value.toLong(), api.vastMediaBitrate(instance)) + } + + @Test + fun vastMediaHeight() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = 0 + whenever(instance.vastMediaHeight).thenReturn(value) + + assertEquals(value.toLong(), api.vastMediaHeight(instance)) + } + + @Test + fun vastMediaWidth() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = 0 + whenever(instance.vastMediaWidth).thenReturn(value) + + assertEquals(value.toLong(), api.vastMediaWidth(instance)) + } + + @Test + fun width() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = 0 + whenever(instance.width).thenReturn(value) + + assertEquals(value.toLong(), api.width(instance)) + } + + @Test + fun isLinear() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = true + whenever(instance.isLinear).thenReturn(value) + + assertEquals(value, api.isLinear(instance)) + } + + @Test + fun isSkippable() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = true + whenever(instance.isSkippable).thenReturn(value) + + assertEquals(value, api.isSkippable(instance)) + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdsLoadedListenerProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdsLoadedListenerProxyApiTest.kt new file mode 100644 index 000000000000..5d89ba05da31 --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdsLoadedListenerProxyApiTest.kt @@ -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. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdsManagerLoadedEvent +import kotlin.test.Test +import kotlin.test.assertTrue +import org.mockito.Mockito +import org.mockito.kotlin.any +import org.mockito.kotlin.eq +import org.mockito.kotlin.whenever + +class AdsLoadedListenerProxyApiTest { + @Test + fun pigeon_defaultConstructor() { + val api = TestProxyApiRegistrar().getPigeonApiAdsLoadedListener() + + assertTrue(api.pigeon_defaultConstructor() is AdsLoadedListenerProxyApi.AdsLoadedListenerImpl) + } + + @Test + fun onAdsManagerLoaded() { + val mockApi = Mockito.mock() + whenever(mockApi.pigeonRegistrar).thenReturn(TestProxyApiRegistrar()) + + val instance = AdsLoadedListenerProxyApi.AdsLoadedListenerImpl(mockApi) + val mockEvent = Mockito.mock() + instance.onAdsManagerLoaded(mockEvent) + + Mockito.verify(mockApi).onAdsManagerLoaded(eq(instance), eq(mockEvent), any()) + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdsLoaderProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdsLoaderProxyApiTest.kt new file mode 100644 index 000000000000..f70fb27f00be --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdsLoaderProxyApiTest.kt @@ -0,0 +1,47 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdErrorEvent +import com.google.ads.interactivemedia.v3.api.AdsLoader +import com.google.ads.interactivemedia.v3.api.AdsRequest +import kotlin.test.Test +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify + +class AdsLoaderProxyApiTest { + @Test + fun addAdErrorListener() { + val api = TestProxyApiRegistrar().getPigeonApiAdsLoader() + + val instance = mock() + val mockListener = mock() + api.addAdErrorListener(instance, mockListener) + + verify(instance).addAdErrorListener(mockListener) + } + + @Test + fun addAdsLoadedListener() { + val api = TestProxyApiRegistrar().getPigeonApiAdsLoader() + + val instance = mock() + val mockListener = mock() + api.addAdsLoadedListener(instance, mockListener) + + verify(instance).addAdsLoadedListener(mockListener) + } + + @Test + fun requestAds() { + val api = TestProxyApiRegistrar().getPigeonApiAdsLoader() + + val instance = mock() + val mockRequest = mock() + api.requestAds(instance, mockRequest) + + verify(instance).requestAds(mockRequest) + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdsManagerLoadedEventProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdsManagerLoadedEventProxyApiTest.kt new file mode 100644 index 000000000000..ff3f3f51dce0 --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdsManagerLoadedEventProxyApiTest.kt @@ -0,0 +1,25 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdsManager +import com.google.ads.interactivemedia.v3.api.AdsManagerLoadedEvent +import kotlin.test.Test +import kotlin.test.assertEquals +import org.mockito.Mockito +import org.mockito.kotlin.whenever + +class AdsManagerLoadedEventProxyApiTest { + @Test + fun manager() { + val api = TestProxyApiRegistrar().getPigeonApiAdsManagerLoadedEvent() + + val instance = Mockito.mock() + val mockManager = Mockito.mock() + whenever(instance.adsManager).thenReturn(mockManager) + + assertEquals(mockManager, api.manager(instance)) + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdsManagerProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdsManagerProxyApiTest.kt new file mode 100644 index 000000000000..e394e4761b80 --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdsManagerProxyApiTest.kt @@ -0,0 +1,75 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdsManager +import kotlin.test.Test +import kotlin.test.assertEquals +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever + +class AdsManagerProxyApiTest { + @Test + fun discardAdBreak() { + val api = TestProxyApiRegistrar().getPigeonApiAdsManager() + + val instance = mock() + api.discardAdBreak(instance) + + verify(instance).discardAdBreak() + } + + @Test + fun pause() { + val api = TestProxyApiRegistrar().getPigeonApiAdsManager() + + val instance = mock() + api.pause(instance) + + verify(instance).pause() + } + + @Test + fun start() { + val api = TestProxyApiRegistrar().getPigeonApiAdsManager() + + val instance = mock() + api.start(instance) + + verify(instance).start() + } + + @Test + fun getAdCuePoints() { + val api = TestProxyApiRegistrar().getPigeonApiAdsManager() + + val instance = mock() + val value = listOf(1.0) + whenever(instance.adCuePoints).thenReturn(listOf(1.0f)) + + assertEquals(value, api.getAdCuePoints(instance)) + } + + @Test + fun resume() { + val api = TestProxyApiRegistrar().getPigeonApiAdsManager() + + val instance = mock() + api.resume(instance) + + verify(instance).resume() + } + + @Test + fun skip() { + val api = TestProxyApiRegistrar().getPigeonApiAdsManager() + + val instance = mock() + api.skip(instance) + + verify(instance).skip() + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdsRenderingSettingsProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdsRenderingSettingsProxyApiTest.kt new file mode 100644 index 000000000000..f7585858a8e4 --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdsRenderingSettingsProxyApiTest.kt @@ -0,0 +1,158 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdsRenderingSettings +import com.google.ads.interactivemedia.v3.api.UiElement +import kotlin.test.Test +import kotlin.test.assertEquals +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever + +class AdsRenderingSettingsProxyApiTest { + @Test + fun getBitrateKbps() { + val api = TestProxyApiRegistrar().getPigeonApiAdsRenderingSettings() + + val instance = mock() + val value = 0 + whenever(instance.bitrateKbps).thenReturn(value) + + assertEquals(value.toLong(), api.getBitrateKbps(instance)) + } + + @Test + fun getEnableCustomTabs() { + val api = TestProxyApiRegistrar().getPigeonApiAdsRenderingSettings() + + val instance = mock() + val value = true + whenever(instance.enableCustomTabs).thenReturn(value) + + assertEquals(value, api.getEnableCustomTabs(instance)) + } + + @Test + fun getEnablePreloading() { + val api = TestProxyApiRegistrar().getPigeonApiAdsRenderingSettings() + + val instance = mock() + val value = true + whenever(instance.enablePreloading).thenReturn(value) + + assertEquals(value, api.getEnablePreloading(instance)) + } + + @Test + fun getFocusSkipButtonWhenAvailable() { + val api = TestProxyApiRegistrar().getPigeonApiAdsRenderingSettings() + + val instance = mock() + val value = true + whenever(instance.focusSkipButtonWhenAvailable).thenReturn(value) + + assertEquals(value, api.getFocusSkipButtonWhenAvailable(instance)) + } + + @Test + fun getMimeTypes() { + val api = TestProxyApiRegistrar().getPigeonApiAdsRenderingSettings() + + val instance = mock() + val value = listOf("myString") + whenever(instance.mimeTypes).thenReturn(value) + + assertEquals(value, api.getMimeTypes(instance)) + } + + @Test + fun setBitrateKbps() { + val api = TestProxyApiRegistrar().getPigeonApiAdsRenderingSettings() + + val instance = mock() + val bitrate = 0L + api.setBitrateKbps(instance, bitrate) + + verify(instance).bitrateKbps = bitrate.toInt() + } + + @Test + fun setEnableCustomTabs() { + val api = TestProxyApiRegistrar().getPigeonApiAdsRenderingSettings() + + val instance = mock() + val enableCustomTabs = true + api.setEnableCustomTabs(instance, enableCustomTabs) + + verify(instance).enableCustomTabs = enableCustomTabs + } + + @Test + fun setEnablePreloading() { + val api = TestProxyApiRegistrar().getPigeonApiAdsRenderingSettings() + + val instance = mock() + val enablePreloading = true + api.setEnablePreloading(instance, enablePreloading) + + verify(instance).enablePreloading = enablePreloading + } + + @Test + fun setFocusSkipButtonWhenAvailable() { + val api = TestProxyApiRegistrar().getPigeonApiAdsRenderingSettings() + + val instance = mock() + val enableFocusSkipButton = true + api.setFocusSkipButtonWhenAvailable(instance, enableFocusSkipButton) + + verify(instance).focusSkipButtonWhenAvailable = enableFocusSkipButton + } + + @Test + fun setLoadVideoTimeout() { + val api = TestProxyApiRegistrar().getPigeonApiAdsRenderingSettings() + + val instance = mock() + val loadVideoTimeout = 0L + api.setLoadVideoTimeout(instance, loadVideoTimeout) + + verify(instance).setLoadVideoTimeout(loadVideoTimeout.toInt()) + } + + @Test + fun setMimeTypes() { + val api = TestProxyApiRegistrar().getPigeonApiAdsRenderingSettings() + + val instance = mock() + val mimeTypes = listOf("myString") + api.setMimeTypes(instance, mimeTypes) + + verify(instance).mimeTypes = mimeTypes + } + + @Test + fun setPlayAdsAfterTime() { + val api = TestProxyApiRegistrar().getPigeonApiAdsRenderingSettings() + + val instance = mock() + val time = 1.0 + api.setPlayAdsAfterTime(instance, time) + + verify(instance).setPlayAdsAfterTime(time) + } + + @Test + fun setUiElements() { + val api = TestProxyApiRegistrar().getPigeonApiAdsRenderingSettings() + + val instance = mock() + val uiElements = listOf(dev.flutter.packages.interactive_media_ads.UiElement.AD_ATTRIBUTION) + api.setUiElements(instance, uiElements) + + verify(instance).setUiElements(setOf(UiElement.AD_ATTRIBUTION)) + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdsRequestProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdsRequestProxyApiTest.kt new file mode 100644 index 000000000000..42f0cc88b84e --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdsRequestProxyApiTest.kt @@ -0,0 +1,35 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdsRequest +import com.google.ads.interactivemedia.v3.api.player.ContentProgressProvider +import kotlin.test.Test +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify + +class AdsRequestProxyApiTest { + @Test + fun setAdTagUrl() { + val api = TestProxyApiRegistrar().getPigeonApiAdsRequest() + + val instance = mock() + api.setAdTagUrl(instance, "adTag?") + + verify(instance).adTagUrl = + "adTag?&request_agent=Flutter-IMA-${AdsRequestProxyApi.pluginVersion}" + } + + @Test + fun setContentProgressProvider() { + val api = TestProxyApiRegistrar().getPigeonApiAdsRequest() + + val instance = mock() + val mockProvider = mock() + api.setContentProgressProvider(instance, mockProvider) + + verify(instance).contentProgressProvider = mockProvider + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/BaseManagerProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/BaseManagerProxyApiTest.kt new file mode 100644 index 000000000000..728bc38ba05e --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/BaseManagerProxyApiTest.kt @@ -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. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.Ad +import com.google.ads.interactivemedia.v3.api.AdErrorEvent +import com.google.ads.interactivemedia.v3.api.AdEvent +import com.google.ads.interactivemedia.v3.api.AdProgressInfo +import com.google.ads.interactivemedia.v3.api.AdsRenderingSettings +import com.google.ads.interactivemedia.v3.api.BaseManager +import junit.framework.TestCase.assertEquals +import kotlin.test.Test +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever + +class BaseManagerProxyApiTest { + @Test + fun addAdErrorListener() { + val api = TestProxyApiRegistrar().getPigeonApiBaseManager() + + val instance = mock() + val mockListener = mock() + api.addAdErrorListener(instance, mockListener) + + verify(instance).addAdErrorListener(mockListener) + } + + @Test + fun addAdEventListener() { + val api = TestProxyApiRegistrar().getPigeonApiBaseManager() + + val instance = mock() + val mockListener = mock() + api.addAdEventListener(instance, mockListener) + + verify(instance).addAdEventListener(mockListener) + } + + @Test + fun destroy() { + val api = TestProxyApiRegistrar().getPigeonApiBaseManager() + + val instance = mock() + api.destroy(instance) + + verify(instance).destroy() + } + + @Test + fun init() { + val api = TestProxyApiRegistrar().getPigeonApiBaseManager() + + val instance = mock() + val settings = mock() + api.init(instance, settings) + + verify(instance).init(settings) + } + + @Test + fun focus() { + val api = TestProxyApiRegistrar().getPigeonApiBaseManager() + + val instance = mock() + api.focus(instance) + + verify(instance).focus() + } + + @Test + fun getAdProgressInfo() { + val api = TestProxyApiRegistrar().getPigeonApiBaseManager() + + val instance = mock() + val value = mock() + whenever(instance.adProgressInfo).thenReturn(value) + + assertEquals(value, api.getAdProgressInfo(instance)) + } + + @Test + fun getCurrentAd() { + val api = TestProxyApiRegistrar().getPigeonApiBaseManager() + + val instance = mock() + val value = mock() + whenever(instance.currentAd).thenReturn(value) + + assertEquals(value, api.getCurrentAd(instance)) + } + + @Test + fun removeAdErrorListener() { + val api = TestProxyApiRegistrar().getPigeonApiBaseManager() + + val instance = mock() + val errorListener = mock() + api.removeAdErrorListener(instance, errorListener) + + verify(instance).removeAdErrorListener(errorListener) + } + + @Test + fun removeAdEventListener() { + val api = TestProxyApiRegistrar().getPigeonApiBaseManager() + + val instance = mock() + val adEventListener = mock() + api.removeAdEventListener(instance, adEventListener) + + verify(instance).removeAdEventListener(adEventListener) + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/CompanionAdProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/CompanionAdProxyApiTest.kt new file mode 100644 index 000000000000..dbc6aaf1e7c2 --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/CompanionAdProxyApiTest.kt @@ -0,0 +1,57 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.CompanionAd +import kotlin.test.Test +import kotlin.test.assertEquals +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever + +class CompanionAdProxyApiTest { + @Test + fun apiFramework() { + val api = TestProxyApiRegistrar().getPigeonApiCompanionAd() + + val instance = mock() + val value = "myString" + whenever(instance.apiFramework).thenReturn(value) + + assertEquals(value, api.apiFramework(instance)) + } + + @Test + fun height() { + val api = TestProxyApiRegistrar().getPigeonApiCompanionAd() + + val instance = mock() + val value = 0 + whenever(instance.height).thenReturn(value) + + assertEquals(value.toLong(), api.height(instance)) + } + + @Test + fun resourceValue() { + val api = TestProxyApiRegistrar().getPigeonApiCompanionAd() + + val instance = mock() + val value = "myString" + whenever(instance.resourceValue).thenReturn(value) + + assertEquals(value, api.resourceValue(instance)) + } + + @Test + fun width() { + val api = TestProxyApiRegistrar().getPigeonApiCompanionAd() + + val instance = mock() + val value = 0 + whenever(instance.width).thenReturn(value) + + assertEquals(value.toLong(), api.width(instance)) + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/ContentProgressProviderProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/ContentProgressProviderProxyApiTest.kt new file mode 100644 index 000000000000..55c8accb055e --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/ContentProgressProviderProxyApiTest.kt @@ -0,0 +1,36 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue +import org.mockito.kotlin.mock + +class ContentProgressProviderProxyApiTest { + @Test + fun pigeon_defaultConstructor() { + val api = TestProxyApiRegistrar().getPigeonApiContentProgressProvider() + + assertTrue( + api.pigeon_defaultConstructor() + is ContentProgressProviderProxyApi.ContentProgressProviderImpl) + } + + @Test + fun setContentProgress() { + val api = TestProxyApiRegistrar().getPigeonApiContentProgressProvider() + + val instance = + ContentProgressProviderProxyApi.ContentProgressProviderImpl( + api as ContentProgressProviderProxyApi) + val mockProgressUpdate = mock() + api.setContentProgress(instance, mockProgressUpdate) + + assertEquals(mockProgressUpdate, instance.currentProgress) + assertEquals(mockProgressUpdate, instance.contentProgress) + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/ImaSdkFactoryProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/ImaSdkFactoryProxyApiTest.kt new file mode 100644 index 000000000000..600e5e41a09e --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/ImaSdkFactoryProxyApiTest.kt @@ -0,0 +1,54 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdDisplayContainer +import com.google.ads.interactivemedia.v3.api.AdsLoader +import com.google.ads.interactivemedia.v3.api.AdsRequest +import com.google.ads.interactivemedia.v3.api.ImaSdkFactory +import com.google.ads.interactivemedia.v3.api.ImaSdkSettings +import kotlin.test.Test +import kotlin.test.assertEquals +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever + +class ImaSdkFactoryProxyApiTest { + @Test + fun createImaSdkSettings() { + val api = TestProxyApiRegistrar().getPigeonApiImaSdkFactory() + + val instance = mock() + val mockSettings = mock() + whenever(instance.createImaSdkSettings()).thenReturn(mockSettings) + + assertEquals(mockSettings, api.createImaSdkSettings(instance)) + } + + @Test + fun createAdsLoader() { + val registrar = TestProxyApiRegistrar() + val api = registrar.getPigeonApiImaSdkFactory() + + val instance = mock() + val mockAdsLoader = mock() + val mockSettings = mock() + val mockContainer = mock() + whenever(instance.createAdsLoader(registrar.context, mockSettings, mockContainer)) + .thenReturn(mockAdsLoader) + + assertEquals(mockAdsLoader, api.createAdsLoader(instance, mockSettings, mockContainer)) + } + + @Test + fun createAdsRequest() { + val api = TestProxyApiRegistrar().getPigeonApiImaSdkFactory() + + val instance = mock() + val mockRequest = mock() + whenever(instance.createAdsRequest()).thenReturn(mockRequest) + + assertEquals(mockRequest, api.createAdsRequest(instance)) + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/InteractiveMediaAdsPluginTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/InteractiveMediaAdsPluginTest.kt deleted file mode 100644 index 3adc0d0a56b4..000000000000 --- a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/InteractiveMediaAdsPluginTest.kt +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package dev.flutter.packages.interactive_media_ads - -import io.flutter.plugin.common.MethodCall -import io.flutter.plugin.common.MethodChannel -import kotlin.test.Test -import org.mockito.Mockito - -/* - * This demonstrates a simple unit test of the Kotlin portion of this plugin's implementation. - * - * Once you have built the plugin's example app, you can run these tests from the command - * line by running `./gradlew testDebugUnitTest` in the `example/android/` directory, or - * you can run them directly from IDEs that support JUnit such as Android Studio. - */ - -internal class InteractiveMediaAdsPluginTest { - @Test - fun onMethodCall_getPlatformVersion_returnsExpectedValue() { - val plugin = InteractiveMediaAdsPlugin() - - val call = MethodCall("getPlatformVersion", null) - val mockResult: MethodChannel.Result = Mockito.mock(MethodChannel.Result::class.java) - plugin.onMethodCall(call, mockResult) - - Mockito.verify(mockResult).success("Android " + android.os.Build.VERSION.RELEASE) - } -} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/MediaPlayerProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/MediaPlayerProxyApiTest.kt new file mode 100644 index 000000000000..cee45eb3d905 --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/MediaPlayerProxyApiTest.kt @@ -0,0 +1,64 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import android.media.MediaPlayer +import kotlin.test.Test +import kotlin.test.assertEquals +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever + +class MediaPlayerProxyApiTest { + @Test + fun getDuration() { + val api = TestProxyApiRegistrar().getPigeonApiMediaPlayer() + + val instance = mock() + whenever(instance.duration).thenReturn(0) + + assertEquals(0, api.getDuration(instance)) + } + + @Test + fun seekTo() { + val api = TestProxyApiRegistrar().getPigeonApiMediaPlayer() + + val instance = mock() + api.seekTo(instance, 0) + + verify(instance).seekTo(0) + } + + @Test + fun start() { + val api = TestProxyApiRegistrar().getPigeonApiMediaPlayer() + + val instance = mock() + api.start(instance) + + verify(instance).start() + } + + @Test + fun pause() { + val api = TestProxyApiRegistrar().getPigeonApiMediaPlayer() + + val instance = mock() + api.pause(instance) + + verify(instance).pause() + } + + @Test + fun stop() { + val api = TestProxyApiRegistrar().getPigeonApiMediaPlayer() + + val instance = mock() + api.stop(instance) + + verify(instance).stop() + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/TestProxyApiRegistrar.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/TestProxyApiRegistrar.kt new file mode 100644 index 000000000000..0aba7066a28a --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/TestProxyApiRegistrar.kt @@ -0,0 +1,17 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import org.mockito.kotlin.mock + +/** + * Test implementation of `ProxyApiRegistrar` that provides mocks and instantly runs callbacks + * instead of posting them. + */ +class TestProxyApiRegistrar : ProxyApiRegistrar(mock(), mock()) { + override fun runOnMainThread(callback: Runnable) { + callback.run() + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/UniversalAdIdProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/UniversalAdIdProxyApiTest.kt new file mode 100644 index 000000000000..5161cc687f4b --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/UniversalAdIdProxyApiTest.kt @@ -0,0 +1,35 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.UniversalAdId +import kotlin.test.Test +import kotlin.test.assertEquals +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever + +class UniversalAdIdProxyApiTest { + @Test + fun adIdRegistry() { + val api = TestProxyApiRegistrar().getPigeonApiUniversalAdId() + + val instance = mock() + val value = "myString" + whenever(instance.adIdRegistry).thenReturn(value) + + assertEquals(value, api.adIdRegistry(instance)) + } + + @Test + fun adIdValue() { + val api = TestProxyApiRegistrar().getPigeonApiUniversalAdId() + + val instance = mock() + val value = "myString" + whenever(instance.adIdValue).thenReturn(value) + + assertEquals(value, api.adIdValue(instance)) + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/VideoAdPlayerCallbackProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/VideoAdPlayerCallbackProxyApiTest.kt new file mode 100644 index 000000000000..125fd16f951e --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/VideoAdPlayerCallbackProxyApiTest.kt @@ -0,0 +1,124 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.player.AdMediaInfo +import com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback +import com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate +import kotlin.test.Test +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify + +class VideoAdPlayerCallbackProxyApiTest { + @Test + fun onAdProgress() { + val api = TestProxyApiRegistrar().getPigeonApiVideoAdPlayerCallback() + + val instance = mock() + val mockInfo = mock() + val mockUpdate = mock() + api.onAdProgress(instance, mockInfo, mockUpdate) + + verify(instance).onAdProgress(mockInfo, mockUpdate) + } + + @Test + fun onBuffering() { + val api = TestProxyApiRegistrar().getPigeonApiVideoAdPlayerCallback() + + val instance = mock() + val mockInfo = mock() + api.onBuffering(instance, mockInfo) + + verify(instance).onBuffering(mockInfo) + } + + @Test + fun onContentComplete() { + val api = TestProxyApiRegistrar().getPigeonApiVideoAdPlayerCallback() + + val instance = mock() + api.onContentComplete(instance) + + verify(instance).onContentComplete() + } + + @Test + fun onEnded() { + val api = TestProxyApiRegistrar().getPigeonApiVideoAdPlayerCallback() + + val instance = mock() + val mockInfo = mock() + api.onEnded(instance, mockInfo) + + verify(instance).onEnded(mockInfo) + } + + @Test + fun onError() { + val api = TestProxyApiRegistrar().getPigeonApiVideoAdPlayerCallback() + + val instance = mock() + val mockInfo = mock() + api.onError(instance, mockInfo) + + verify(instance).onError(mockInfo) + } + + @Test + fun onLoaded() { + val api = TestProxyApiRegistrar().getPigeonApiVideoAdPlayerCallback() + + val instance = mock() + val mockInfo = mock() + api.onLoaded(instance, mockInfo) + + verify(instance).onLoaded(mockInfo) + } + + @Test + fun onPause() { + val api = TestProxyApiRegistrar().getPigeonApiVideoAdPlayerCallback() + + val instance = mock() + val mockInfo = mock() + api.onPause(instance, mockInfo) + + verify(instance).onPause(mockInfo) + } + + @Test + fun onPlay() { + val api = TestProxyApiRegistrar().getPigeonApiVideoAdPlayerCallback() + + val instance = mock() + val mockInfo = mock() + api.onPlay(instance, mockInfo) + + verify(instance).onPlay(mockInfo) + } + + @Test + fun onResume() { + val api = TestProxyApiRegistrar().getPigeonApiVideoAdPlayerCallback() + + val instance = mock() + val mockInfo = mock() + api.onResume(instance, mockInfo) + + verify(instance).onResume(mockInfo) + } + + @Test + fun onVolumeChanged() { + val api = TestProxyApiRegistrar().getPigeonApiVideoAdPlayerCallback() + + val instance = mock() + val mockInfo = mock() + api.onVolumeChanged(instance, mockInfo, 0) + + verify(instance).onVolumeChanged(mockInfo, 0) + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/VideoAdPlayerProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/VideoAdPlayerProxyApiTest.kt new file mode 100644 index 000000000000..01eb2b1f6dd9 --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/VideoAdPlayerProxyApiTest.kt @@ -0,0 +1,132 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.AdPodInfo +import com.google.ads.interactivemedia.v3.api.player.AdMediaInfo +import com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer +import com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue +import org.mockito.Mockito +import org.mockito.kotlin.any +import org.mockito.kotlin.eq +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever + +class VideoAdPlayerProxyApiTest { + @Test + fun pigeon_defaultConstructor() { + val api = ProxyApiRegistrar(Mockito.mock(), Mockito.mock()).getPigeonApiVideoAdPlayer() + + assertTrue(api.pigeon_defaultConstructor() is VideoAdPlayerProxyApi.VideoAdPlayerImpl) + } + + @Test + fun setVolume() { + val api = TestProxyApiRegistrar().getPigeonApiVideoAdPlayer() + + val instance = VideoAdPlayerProxyApi.VideoAdPlayerImpl(api as VideoAdPlayerProxyApi) + api.setVolume(instance, 0) + + assertEquals(0, instance.volume) + } + + @Test + fun setAdProgress() { + val api = TestProxyApiRegistrar().getPigeonApiVideoAdPlayer() + + val instance = VideoAdPlayerProxyApi.VideoAdPlayerImpl(api as VideoAdPlayerProxyApi) + val mockProgressUpdate = mock() + api.setAdProgress(instance, mockProgressUpdate) + + assertEquals(mockProgressUpdate, instance.adProgress) + } + + @Test + fun addCallback() { + val mockApi = Mockito.mock() + whenever(mockApi.pigeonRegistrar).thenReturn(TestProxyApiRegistrar()) + + val instance = VideoAdPlayerProxyApi.VideoAdPlayerImpl(mockApi) + val mockCallback = Mockito.mock() + instance.addCallback(mockCallback) + + Mockito.verify(mockApi).addCallback(eq(instance), eq(mockCallback), any()) + } + + @Test + fun loadAd() { + val mockApi = Mockito.mock() + whenever(mockApi.pigeonRegistrar).thenReturn(TestProxyApiRegistrar()) + + val instance = VideoAdPlayerProxyApi.VideoAdPlayerImpl(mockApi) + val mockMediaInfo = mock() + val mockPodInfo = mock() + instance.loadAd(mockMediaInfo, mockPodInfo) + + Mockito.verify(mockApi).loadAd(eq(instance), eq(mockMediaInfo), eq(mockPodInfo), any()) + } + + @Test + fun pauseAd() { + val mockApi = Mockito.mock() + whenever(mockApi.pigeonRegistrar).thenReturn(TestProxyApiRegistrar()) + + val instance = VideoAdPlayerProxyApi.VideoAdPlayerImpl(mockApi) + val mockMediaInfo = mock() + instance.pauseAd(mockMediaInfo) + + Mockito.verify(mockApi).pauseAd(eq(instance), eq(mockMediaInfo), any()) + } + + @Test + fun playAd() { + val mockApi = Mockito.mock() + whenever(mockApi.pigeonRegistrar).thenReturn(TestProxyApiRegistrar()) + + val instance = VideoAdPlayerProxyApi.VideoAdPlayerImpl(mockApi) + val mockMediaInfo = mock() + instance.playAd(mockMediaInfo) + + Mockito.verify(mockApi).playAd(eq(instance), eq(mockMediaInfo), any()) + } + + @Test + fun release() { + val mockApi = Mockito.mock() + whenever(mockApi.pigeonRegistrar).thenReturn(TestProxyApiRegistrar()) + + val instance = VideoAdPlayerProxyApi.VideoAdPlayerImpl(mockApi) + instance.release() + + Mockito.verify(mockApi).release(eq(instance), any()) + } + + @Test + fun removeCallback() { + val mockApi = Mockito.mock() + whenever(mockApi.pigeonRegistrar).thenReturn(TestProxyApiRegistrar()) + + val instance = VideoAdPlayerProxyApi.VideoAdPlayerImpl(mockApi) + val mockCallback = Mockito.mock() + instance.removeCallback(mockCallback) + + Mockito.verify(mockApi).removeCallback(eq(instance), eq(mockCallback), any()) + } + + @Test + fun stopAd() { + val mockApi = Mockito.mock() + whenever(mockApi.pigeonRegistrar).thenReturn(TestProxyApiRegistrar()) + + val instance = VideoAdPlayerProxyApi.VideoAdPlayerImpl(mockApi) + val mockMediaInfo = mock() + instance.stopAd(mockMediaInfo) + + Mockito.verify(mockApi).stopAd(eq(instance), eq(mockMediaInfo), any()) + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/VideoViewProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/VideoViewProxyApiTest.kt new file mode 100644 index 000000000000..f43af0aa4287 --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/VideoViewProxyApiTest.kt @@ -0,0 +1,38 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import android.net.Uri +import android.widget.VideoView +import kotlin.test.Test +import kotlin.test.assertEquals +import org.mockito.kotlin.isNotNull +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever + +class VideoViewProxyApiTest { + @Test + fun setVideoURI() { + val api = TestProxyApiRegistrar().getPigeonApiVideoView() + + val instance = mock() + api.setVideoUri(instance, "adTag") + + verify(instance).setVideoURI(isNotNull()) + assertEquals("adTag", Uri.lastValue) + } + + @Test + fun getCurrentPosition() { + val api = TestProxyApiRegistrar().getPigeonApiVideoView() + + val instance = mock() + whenever(instance.currentPosition).thenReturn(0) + api.getCurrentPosition(instance) + + assertEquals(0, api.getCurrentPosition(instance)) + } +} diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/ViewGroupProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/ViewGroupProxyApiTest.kt new file mode 100644 index 000000000000..19b5c38c2155 --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/ViewGroupProxyApiTest.kt @@ -0,0 +1,35 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package dev.flutter.packages.interactive_media_ads + +import android.view.View +import android.view.ViewGroup +import kotlin.test.Test +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify + +class ViewGroupProxyApiTest { + @Test + fun addView() { + val api = TestProxyApiRegistrar().getPigeonApiViewGroup() + + val instance = mock() + val mockView = mock() + api.addView(instance, mockView) + + verify(instance).addView(mockView) + } + + @Test + fun removeView() { + val api = TestProxyApiRegistrar().getPigeonApiViewGroup() + + val instance = mock() + val mockView = mock() + api.removeView(instance, mockView) + + verify(instance).removeView(mockView) + } +} diff --git a/packages/interactive_media_ads/example/android/app/build.gradle b/packages/interactive_media_ads/example/android/app/build.gradle index f3018aafa7a5..5d5473c54690 100644 --- a/packages/interactive_media_ads/example/android/app/build.gradle +++ b/packages/interactive_media_ads/example/android/app/build.gradle @@ -28,12 +28,12 @@ android { ndkVersion flutter.ndkVersion compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '11' } sourceSets { @@ -44,7 +44,6 @@ android { applicationId "dev.flutter.packages.interactive_media_ads_example" minSdk flutter.minSdkVersion targetSdk flutter.targetSdkVersion - multiDexEnabled true versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/packages/interactive_media_ads/example/android/app/src/main/AndroidManifest.xml b/packages/interactive_media_ads/example/android/app/src/main/AndroidManifest.xml index 8733f2b862ab..48c5bc7ca184 100644 --- a/packages/interactive_media_ads/example/android/app/src/main/AndroidManifest.xml +++ b/packages/interactive_media_ads/example/android/app/src/main/AndroidManifest.xml @@ -1,4 +1,9 @@ + + + + + /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -238,6 +358,28 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; + 8BF613E92E45E672229E9718 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -253,6 +395,23 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; + F9AB3D76E1CFC93475F15A54 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -260,7 +419,24 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, + 8F599BBF2C3335B40090A0DF /* ViewControllerTests.swift in Sources */, + 8F8382A32CBDB4A4007F28E0 /* CompanionAdProxyApiTests.swift in Sources */, + 8FC919922CA5D86F00188068 /* FriendlyObstructionTests.swift in Sources */, + 8F977DD92C2C8C6A00A90D4B /* AdLoadingErrorDataTests.swift in Sources */, + 8F599BB32C2DD87D0090A0DF /* AdsLoaderTests.swift in Sources */, + 8F977DD72C2C89A600A90D4B /* AdEventTests.swift in Sources */, + 8F977DD32C2BA15100A90D4B /* TestProxyApiRegistrar.swift in Sources */, + 8F599BBB2C332C010090A0DF /* AdsRequestTests.swift in Sources */, + 8F599BB72C3327F10090A0DF /* AdsManagerDelegateTests.swift in Sources */, + 8F599BBD2C332CFE0090A0DF /* ContentPlayheadTests.swift in Sources */, + 8FFF0C182CC1A7F300A7CB98 /* CompanionAdSlotProxyApiTests.swift in Sources */, + 8FFF0C1A2CC1A97B00A7CB98 /* CompanionDelegateProxyApiTests.swift in Sources */, + 8F977DCF2C2B99C600A90D4B /* AdDisplayContainerTests.swift in Sources */, + 8F599BB52C2DD8EC0090A0DF /* AdsLoaderDelegateTests.swift in Sources */, + 8F599BB92C332A320090A0DF /* AdsRenderingSettingsTests.swift in Sources */, + 8F977DD52C2C777600A90D4B /* AdErrorTests.swift in Sources */, + 8F599BB12C2DD1FD0090A0DF /* AdsManagerTests.swift in Sources */, + 8F977DDB2C2C8D2E00A90D4B /* AdsLoadedDataTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -379,6 +555,7 @@ }; 331C8088294A63A400263BE5 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 89C6230E68C80A6F4B207726 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -396,6 +573,7 @@ }; 331C8089294A63A400263BE5 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 5B63D978173E0F79E02D7128 /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -411,6 +589,7 @@ }; 331C808A294A63A400263BE5 /* Profile */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 41604FD1E0DA824F933934B2 /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; diff --git a/packages/interactive_media_ads/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/interactive_media_ads/example/ios/Runner.xcworkspace/contents.xcworkspacedata index 1d526a16ed0f..21a3cc14c74e 100644 --- a/packages/interactive_media_ads/example/ios/Runner.xcworkspace/contents.xcworkspacedata +++ b/packages/interactive_media_ads/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,7 @@ + + diff --git a/packages/interactive_media_ads/example/ios/Runner/AppDelegate.swift b/packages/interactive_media_ads/example/ios/Runner/AppDelegate.swift index d83c0ff0beea..4580c8e76da4 100644 --- a/packages/interactive_media_ads/example/ios/Runner/AppDelegate.swift +++ b/packages/interactive_media_ads/example/ios/Runner/AppDelegate.swift @@ -5,7 +5,7 @@ import Flutter import UIKit -@UIApplicationMain +@main @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, diff --git a/packages/interactive_media_ads/example/ios/RunnerTests/AdDisplayContainerTests.swift b/packages/interactive_media_ads/example/ios/RunnerTests/AdDisplayContainerTests.swift new file mode 100644 index 000000000000..be3bad268049 --- /dev/null +++ b/packages/interactive_media_ads/example/ios/RunnerTests/AdDisplayContainerTests.swift @@ -0,0 +1,20 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import Flutter +import XCTest + +@testable import interactive_media_ads + +final class AdDisplayContainerTests: XCTestCase { + func testPigeonDefaultConstructor() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdDisplayContainer(registrar) + + let instance = try? api.pigeonDelegate.pigeonDefaultConstructor( + pigeonApi: api, adContainer: UIView(), adContainerViewController: UIViewController()) + + XCTAssertNotNil(instance) + } +} diff --git a/packages/interactive_media_ads/example/ios/RunnerTests/AdErrorTests.swift b/packages/interactive_media_ads/example/ios/RunnerTests/AdErrorTests.swift new file mode 100644 index 000000000000..c770b6738ac0 --- /dev/null +++ b/packages/interactive_media_ads/example/ios/RunnerTests/AdErrorTests.swift @@ -0,0 +1,65 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import Flutter +import GoogleInteractiveMediaAds +import XCTest + +@testable import interactive_media_ads + +final class AdErrorTests: XCTestCase { + func testType() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdError(registrar) + + let instance = TestAdError.customInit() + + let value = try? api.pigeonDelegate.type(pigeonApi: api, pigeonInstance: instance) + + XCTAssertEqual(value, .loadingFailed) + } + + func testCode() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdError(registrar) + + let instance = TestAdError.customInit() + + let value = try? api.pigeonDelegate.code(pigeonApi: api, pigeonInstance: instance) + + XCTAssertEqual(value, .apiError) + } + + func testMessage() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdError(registrar) + + let instance = TestAdError.customInit() + + let value = try? api.pigeonDelegate.message(pigeonApi: api, pigeonInstance: instance) + + XCTAssertEqual(value, "message") + } +} + +class TestAdError: IMAAdError { + // Workaround to subclass an Objective-C class that has an `init` constructor with NS_UNAVAILABLE + static func customInit() -> IMAAdError { + let instance = + TestAdError.perform(NSSelectorFromString("new")).takeRetainedValue() as! TestAdError + return instance + } + + override var type: IMAErrorType { + return .adLoadingFailed + } + + override var code: IMAErrorCode { + return .API_ERROR + } + + override var message: String? { + return "message" + } +} diff --git a/packages/interactive_media_ads/example/ios/RunnerTests/AdEventTests.swift b/packages/interactive_media_ads/example/ios/RunnerTests/AdEventTests.swift new file mode 100644 index 000000000000..9906e3157342 --- /dev/null +++ b/packages/interactive_media_ads/example/ios/RunnerTests/AdEventTests.swift @@ -0,0 +1,65 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import Flutter +import GoogleInteractiveMediaAds +import XCTest + +@testable import interactive_media_ads + +final class AdEventTests: XCTestCase { + func testType() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdEvent(registrar) + + let instance = TestAdEvent.customInit() + + let value = try? api.pigeonDelegate.type(pigeonApi: api, pigeonInstance: instance) + + XCTAssertEqual(value, .adBreakEnded) + } + + func testMessage() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdEvent(registrar) + + let instance = TestAdEvent.customInit() + + let value = try? api.pigeonDelegate.typeString(pigeonApi: api, pigeonInstance: instance) + + XCTAssertEqual(value, "message") + } + + func testAdData() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdEvent(registrar) + + let instance = TestAdEvent.customInit() + + let value = try? api.pigeonDelegate.adData(pigeonApi: api, pigeonInstance: instance) + + XCTAssertEqual(value as! [String: String], ["my": "string"]) + } +} + +class TestAdEvent: IMAAdEvent { + // Workaround to subclass an Objective-C class that has an `init` constructor with NS_UNAVAILABLE + static func customInit() -> TestAdEvent { + let instance = + TestAdEvent.perform(NSSelectorFromString("new")).takeRetainedValue() as! TestAdEvent + return instance + } + + override var type: IMAAdEventType { + return .AD_BREAK_ENDED + } + + override var typeString: String { + return "message" + } + + override var adData: [String: Any]? { + return ["my": "string"] + } +} diff --git a/packages/interactive_media_ads/example/ios/RunnerTests/AdLoadingErrorDataTests.swift b/packages/interactive_media_ads/example/ios/RunnerTests/AdLoadingErrorDataTests.swift new file mode 100644 index 000000000000..1797c16dae2b --- /dev/null +++ b/packages/interactive_media_ads/example/ios/RunnerTests/AdLoadingErrorDataTests.swift @@ -0,0 +1,36 @@ +// 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 Flutter +import GoogleInteractiveMediaAds +import XCTest + +@testable import interactive_media_ads + +final class AdLoadingErrorTests: XCTestCase { + func testAdError() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdLoadingErrorData(registrar) + + let instance = TestAdLoadingErrorData.customInit() + + let value = try? api.pigeonDelegate.adError(pigeonApi: api, pigeonInstance: instance) + + XCTAssertTrue(value is TestAdError) + } +} + +class TestAdLoadingErrorData: IMAAdLoadingErrorData { + // Workaround to subclass an Objective-C class that has an `init` constructor with NS_UNAVAILABLE + static func customInit() -> TestAdLoadingErrorData { + let instance = + TestAdLoadingErrorData.perform(NSSelectorFromString("new")).takeRetainedValue() + as! TestAdLoadingErrorData + return instance + } + + override var adError: IMAAdError { + return TestAdError.customInit() + } +} diff --git a/packages/interactive_media_ads/example/ios/RunnerTests/AdsLoadedDataTests.swift b/packages/interactive_media_ads/example/ios/RunnerTests/AdsLoadedDataTests.swift new file mode 100644 index 000000000000..d5afe99c2307 --- /dev/null +++ b/packages/interactive_media_ads/example/ios/RunnerTests/AdsLoadedDataTests.swift @@ -0,0 +1,36 @@ +// 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 Flutter +import GoogleInteractiveMediaAds +import XCTest + +@testable import interactive_media_ads + +final class AdsLoadedDataTests: XCTestCase { + func testAdsManager() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdsLoadedData(registrar) + + let instance = TestAdsLoadedData.customInit() + + let value = try? api.pigeonDelegate.adsManager(pigeonApi: api, pigeonInstance: instance) + + XCTAssertTrue(value is TestAdsManager) + } +} + +class TestAdsLoadedData: IMAAdsLoadedData { + // Workaround to subclass an Objective-C class that has an `init` constructor with NS_UNAVAILABLE + static func customInit() -> TestAdsLoadedData { + let instance = + TestAdsLoadedData.perform(NSSelectorFromString("new")).takeRetainedValue() + as! TestAdsLoadedData + return instance + } + + override var adsManager: IMAAdsManager? { + return TestAdsManager.customInit() + } +} diff --git a/packages/interactive_media_ads/example/ios/RunnerTests/AdsLoaderDelegateTests.swift b/packages/interactive_media_ads/example/ios/RunnerTests/AdsLoaderDelegateTests.swift new file mode 100644 index 000000000000..6e50f0c5e771 --- /dev/null +++ b/packages/interactive_media_ads/example/ios/RunnerTests/AdsLoaderDelegateTests.swift @@ -0,0 +1,63 @@ +// 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 Flutter +import GoogleInteractiveMediaAds +import XCTest + +@testable import interactive_media_ads + +final class AdsLoaderDelegateTests: XCTestCase { + func testPigeonDefaultConstructor() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdsLoaderDelegate(registrar) + + let instance = try? api.pigeonDelegate.pigeonDefaultConstructor(pigeonApi: api) + + XCTAssertTrue(instance is AdsLoaderDelegateImpl) + } + + func testAdLoaderLoadedWith() { + let api = TestAdsLoaderDelegateApi() + let instance = AdsLoaderDelegateImpl(api: api) + + let adsLoader = IMAAdsLoader(settings: nil) + let data = TestAdsLoadedData() + instance.adsLoader(adsLoader, adsLoadedWith: data) + + XCTAssertEqual(api.adLoaderLoadedWithArgs, [adsLoader, data]) + } + + func testAdsLoaderFailedWithErrorData() { + let api = TestAdsLoaderDelegateApi() + let instance = AdsLoaderDelegateImpl(api: api) + + let adsLoader = IMAAdsLoader(settings: nil) + let error = TestAdLoadingErrorData.customInit() + instance.adsLoader(adsLoader, failedWith: error) + + XCTAssertEqual(api.adsLoaderFailedWithErrorDataArgs, [adsLoader, error]) + } +} + +class TestAdsLoaderDelegateApi: PigeonApiProtocolIMAAdsLoaderDelegate { + var adLoaderLoadedWithArgs: [AnyHashable?]? = nil + var adsLoaderFailedWithErrorDataArgs: [AnyHashable?]? = nil + + func adLoaderLoadedWith( + pigeonInstance pigeonInstanceArg: IMAAdsLoaderDelegate, loader loaderArg: IMAAdsLoader, + adsLoadedData adsLoadedDataArg: IMAAdsLoadedData, + completion: @escaping (Result) -> Void + ) { + adLoaderLoadedWithArgs = [loaderArg, adsLoadedDataArg] + } + + func adsLoaderFailedWithErrorData( + pigeonInstance pigeonInstanceArg: IMAAdsLoaderDelegate, loader loaderArg: IMAAdsLoader, + adErrorData adErrorDataArg: IMAAdLoadingErrorData, + completion: @escaping (Result) -> Void + ) { + adsLoaderFailedWithErrorDataArgs = [loaderArg, adErrorDataArg] + } +} diff --git a/packages/interactive_media_ads/example/ios/RunnerTests/AdsLoaderTests.swift b/packages/interactive_media_ads/example/ios/RunnerTests/AdsLoaderTests.swift new file mode 100644 index 000000000000..1d7263efdbb0 --- /dev/null +++ b/packages/interactive_media_ads/example/ios/RunnerTests/AdsLoaderTests.swift @@ -0,0 +1,82 @@ +// 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 Flutter +import GoogleInteractiveMediaAds +import XCTest + +@testable import interactive_media_ads + +final class AdsLoaderTests: XCTestCase { + func testPigeonDefaultConstructor() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdsLoader(registrar) + + let settings = IMASettings() + settings.ppid = "ppid" + let instance = try? api.pigeonDelegate.pigeonDefaultConstructor( + pigeonApi: api, settings: settings) + + XCTAssertNotNil(instance) + XCTAssertEqual(instance?.settings.ppid, settings.ppid) + } + + func testContentComplete() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdsLoader(registrar) + + let instance = TestAdsLoader(settings: nil) + + try? api.pigeonDelegate.contentComplete(pigeonApi: api, pigeonInstance: instance) + + XCTAssertTrue(instance.contentCompleteCalled) + } + + func testRequestAds() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdsLoader(registrar) + + let instance = TestAdsLoader(settings: nil) + + let request = IMAAdsRequest( + adTagUrl: "", + adDisplayContainer: IMAAdDisplayContainer(adContainer: UIView(), viewController: nil), + contentPlayhead: ContentPlayheadImpl(), userContext: nil) + try? api.pigeonDelegate.requestAds( + pigeonApi: api, pigeonInstance: instance, request: request) + + XCTAssertIdentical(instance.adsRequested, request) + } + + func testSetDelegate() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdsLoader(registrar) + + let instance = TestAdsLoader(settings: nil) + + let delegate = AdsLoaderDelegateImpl( + api: registrar.apiDelegate.pigeonApiIMAAdsLoaderDelegate(registrar)) + try? api.pigeonDelegate.setDelegate( + pigeonApi: api, pigeonInstance: instance, delegate: delegate) + + XCTAssertIdentical(instance.delegate, delegate) + } +} + +class TestAdsLoader: IMAAdsLoader { + var contentCompleteCalled = false + var adsRequested: IMAAdsRequest? = nil + + override init(settings: IMASettings?) { + super.init(settings: settings) + } + + override func contentComplete() { + contentCompleteCalled = true + } + + override func requestAds(with request: IMAAdsRequest) { + adsRequested = request + } +} diff --git a/packages/interactive_media_ads/example/ios/RunnerTests/AdsManagerDelegateTests.swift b/packages/interactive_media_ads/example/ios/RunnerTests/AdsManagerDelegateTests.swift new file mode 100644 index 000000000000..303502971dad --- /dev/null +++ b/packages/interactive_media_ads/example/ios/RunnerTests/AdsManagerDelegateTests.swift @@ -0,0 +1,101 @@ +// 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 Flutter +import GoogleInteractiveMediaAds +import XCTest + +@testable import interactive_media_ads + +final class AdsManagerDelegateTests: XCTestCase { + func testPigeonDefaultConstructor() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdsManagerDelegate(registrar) + + let instance = try? api.pigeonDelegate.pigeonDefaultConstructor(pigeonApi: api) + + XCTAssertTrue(instance is AdsManagerDelegateImpl) + } + + func testDidReceiveAdEvent() { + let api = TestAdsManagerDelegateApi() + let instance = AdsManagerDelegateImpl(api: api) + + let manager = TestAdsManager.customInit() + let event = TestAdEvent.customInit() + instance.adsManager(manager, didReceive: event) + + XCTAssertEqual(api.didReceiveAdEventArgs, [manager, event]) + } + + func testDidReceiveAdError() { + let api = TestAdsManagerDelegateApi() + let instance = AdsManagerDelegateImpl(api: api) + + let manager = TestAdsManager.customInit() + let error = TestAdError.customInit() + instance.adsManager(manager, didReceive: error) + + XCTAssertEqual(api.didReceiveAdErrorArgs, [manager, error]) + } + + func testDidRequestContentPause() { + let api = TestAdsManagerDelegateApi() + let instance = AdsManagerDelegateImpl(api: api) + + let manager = TestAdsManager.customInit() + instance.adsManagerDidRequestContentPause(manager) + + XCTAssertEqual(api.didRequestContentPauseArgs, [manager]) + } + + func testDidRequestContentResume() { + let api = TestAdsManagerDelegateApi() + let instance = AdsManagerDelegateImpl(api: api) + + let manager = TestAdsManager.customInit() + instance.adsManagerDidRequestContentResume(manager) + + XCTAssertEqual(api.didRequestContentResumeArgs, [manager]) + } +} + +class TestAdsManagerDelegateApi: PigeonApiProtocolIMAAdsManagerDelegate { + var didReceiveAdEventArgs: [AnyHashable?]? = nil + var didReceiveAdErrorArgs: [AnyHashable?]? = nil + var didRequestContentPauseArgs: [AnyHashable?]? = nil + var didRequestContentResumeArgs: [AnyHashable?]? = nil + + func didReceiveAdEvent( + pigeonInstance pigeonInstanceArg: IMAAdsManagerDelegate, + adsManager adsManagerArg: IMAAdsManager, event eventArg: IMAAdEvent, + completion: @escaping (Result) -> Void + ) { + didReceiveAdEventArgs = [adsManagerArg, eventArg] + } + + func didReceiveAdError( + pigeonInstance pigeonInstanceArg: IMAAdsManagerDelegate, + adsManager adsManagerArg: IMAAdsManager, error errorArg: IMAAdError, + completion: @escaping (Result) -> Void + ) { + didReceiveAdErrorArgs = [adsManagerArg, errorArg] + } + + func didRequestContentPause( + pigeonInstance pigeonInstanceArg: IMAAdsManagerDelegate, + adsManager adsManagerArg: IMAAdsManager, + completion: @escaping (Result) -> Void + ) { + didRequestContentPauseArgs = [adsManagerArg] + } + + func didRequestContentResume( + pigeonInstance pigeonInstanceArg: IMAAdsManagerDelegate, + adsManager adsManagerArg: IMAAdsManager, + completion: @escaping (Result) -> Void + ) { + didRequestContentResumeArgs = [adsManagerArg] + } +} diff --git a/packages/interactive_media_ads/example/ios/RunnerTests/AdsManagerTests.swift b/packages/interactive_media_ads/example/ios/RunnerTests/AdsManagerTests.swift new file mode 100644 index 000000000000..48c232dc751e --- /dev/null +++ b/packages/interactive_media_ads/example/ios/RunnerTests/AdsManagerTests.swift @@ -0,0 +1,149 @@ +// 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 Flutter +import GoogleInteractiveMediaAds +import XCTest + +@testable import interactive_media_ads + +final class AdsManagerTests: XCTestCase { + func testSetDelegate() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdsManager(registrar) + + let instance = TestAdsManager.customInit() + + let delegate = AdsManagerDelegateImpl( + api: registrar.apiDelegate.pigeonApiIMAAdsManagerDelegate(registrar)) + try? api.pigeonDelegate.setDelegate( + pigeonApi: api, pigeonInstance: instance, delegate: delegate) + + XCTAssertIdentical(instance.delegate, delegate) + } + + func testInitialize() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdsManager(registrar) + + let instance = TestAdsManager.customInit() + + let renderingSettings = IMAAdsRenderingSettings() + try? api.pigeonDelegate.initialize( + pigeonApi: api, pigeonInstance: instance, adsRenderingSettings: renderingSettings) + + XCTAssertEqual(instance.renderingSettings, renderingSettings) + } + + func testStart() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdsManager(registrar) + + let instance = TestAdsManager.customInit() + + try? api.pigeonDelegate.start(pigeonApi: api, pigeonInstance: instance) + + XCTAssertTrue(instance.startCalled) + } + + func testPause() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdsManager(registrar) + + let instance = TestAdsManager.customInit() + + try? api.pigeonDelegate.pause(pigeonApi: api, pigeonInstance: instance) + + XCTAssertTrue(instance.pauseCalled) + } + + func testSkip() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdsManager(registrar) + + let instance = TestAdsManager.customInit() + + try? api.pigeonDelegate.skip(pigeonApi: api, pigeonInstance: instance) + + XCTAssertTrue(instance.skipCalled) + } + + func testDiscardAdBreak() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdsManager(registrar) + + let instance = TestAdsManager.customInit() + + try? api.pigeonDelegate.discardAdBreak(pigeonApi: api, pigeonInstance: instance) + + XCTAssertTrue(instance.discardAdBreakCalled) + } + + func testResume() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdsManager(registrar) + + let instance = TestAdsManager.customInit() + + try? api.pigeonDelegate.resume(pigeonApi: api, pigeonInstance: instance) + + XCTAssertTrue(instance.resumeCalled) + } + + func testDestroy() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdsManager(registrar) + + let instance = TestAdsManager.customInit() + + try? api.pigeonDelegate.destroy(pigeonApi: api, pigeonInstance: instance) + + XCTAssertTrue(instance.destroyCalled) + } +} + +class TestAdsManager: IMAAdsManager { + var renderingSettings: IMAAdsRenderingSettings? = nil + var startCalled = false + var pauseCalled = false + var skipCalled = false + var discardAdBreakCalled = false + var resumeCalled = false + var destroyCalled = false + + // Workaround to subclass an Objective-C class that has an `init` constructor with NS_UNAVAILABLE + static func customInit() -> TestAdsManager { + let instance = + TestAdsManager.perform(NSSelectorFromString("new")).takeRetainedValue() as! TestAdsManager + return instance + } + + override func initialize(with adsRenderingSettings: IMAAdsRenderingSettings?) { + renderingSettings = adsRenderingSettings + } + + override func start() { + startCalled = true + } + + override func pause() { + pauseCalled = true + } + + override func skip() { + skipCalled = true + } + + override func discardAdBreak() { + discardAdBreakCalled = true + } + + override func resume() { + resumeCalled = true + } + + override func destroy() { + destroyCalled = true + } +} diff --git a/packages/interactive_media_ads/example/ios/RunnerTests/AdsRenderingSettingsTests.swift b/packages/interactive_media_ads/example/ios/RunnerTests/AdsRenderingSettingsTests.swift new file mode 100644 index 000000000000..2c49b859eb01 --- /dev/null +++ b/packages/interactive_media_ads/example/ios/RunnerTests/AdsRenderingSettingsTests.swift @@ -0,0 +1,104 @@ +// 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 Flutter +import GoogleInteractiveMediaAds +import XCTest + +@testable import interactive_media_ads + +final class AdsRenderingSettingsTests: XCTestCase { + func testPigeonDefaultConstructor() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdsRenderingSettings(registrar) + + let instance = try? api.pigeonDelegate.pigeonDefaultConstructor( + pigeonApi: api) + + XCTAssertTrue(instance != nil) + } + + func testSetMimeTypes() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdsRenderingSettings(registrar) + + let instance = IMAAdsRenderingSettings() + let types = ["myString"] + try? api.pigeonDelegate.setMimeTypes(pigeonApi: api, pigeonInstance: instance, types: types) + + XCTAssertEqual(instance.mimeTypes, types) + } + + func testSetBitrate() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdsRenderingSettings(registrar) + + let instance = IMAAdsRenderingSettings() + let bitrate = 0 + try? api.pigeonDelegate.setBitrate( + pigeonApi: api, pigeonInstance: instance, bitrate: Int64(bitrate)) + + XCTAssertEqual(instance.bitrate, bitrate) + } + + func testSetLoadVideoTimeout() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdsRenderingSettings(registrar) + + let instance = IMAAdsRenderingSettings() + let seconds = 1.0 + try? api.pigeonDelegate.setLoadVideoTimeout( + pigeonApi: api, pigeonInstance: instance, seconds: seconds) + + XCTAssertEqual(instance.loadVideoTimeout, seconds) + } + + func testSetPlayAdsAfterTime() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdsRenderingSettings(registrar) + + let instance = IMAAdsRenderingSettings() + let seconds = 1.0 + try? api.pigeonDelegate.setPlayAdsAfterTime( + pigeonApi: api, pigeonInstance: instance, seconds: seconds) + + XCTAssertEqual(instance.playAdsAfterTime, seconds) + } + + func testSetUIElements() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdsRenderingSettings(registrar) + + let instance = IMAAdsRenderingSettings() + let types = [UIElementType.adAttribution] + try? api.pigeonDelegate.setUIElements(pigeonApi: api, pigeonInstance: instance, types: types) + + XCTAssertEqual( + instance.uiElements, [IMAUiElementType.elements_AD_ATTRIBUTION.rawValue as NSNumber]) + } + + func testSetEnablePreloading() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdsRenderingSettings(registrar) + + let instance = IMAAdsRenderingSettings() + let enable = true + try? api.pigeonDelegate.setEnablePreloading( + pigeonApi: api, pigeonInstance: instance, enable: enable) + + XCTAssertTrue(instance.enablePreloading) + } + + func testSetLinkOpenerPresentingController() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdsRenderingSettings(registrar) + + let instance = IMAAdsRenderingSettings() + let controller = UIViewController() + try? api.pigeonDelegate.setLinkOpenerPresentingController( + pigeonApi: api, pigeonInstance: instance, controller: controller) + + XCTAssertEqual(instance.linkOpenerPresentingController, controller) + } +} diff --git a/packages/interactive_media_ads/example/ios/RunnerTests/AdsRequestTests.swift b/packages/interactive_media_ads/example/ios/RunnerTests/AdsRequestTests.swift new file mode 100644 index 000000000000..21b52654ad9d --- /dev/null +++ b/packages/interactive_media_ads/example/ios/RunnerTests/AdsRequestTests.swift @@ -0,0 +1,28 @@ +// 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 Flutter +import GoogleInteractiveMediaAds +import XCTest + +@testable import interactive_media_ads + +final class AdsRequestTests: XCTestCase { + func testPigeonDefaultConstructor() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdsRequest(registrar) + + let container = IMAAdDisplayContainer(adContainer: UIView(), viewController: nil) + let contentPlayhead = ContentPlayheadImpl() + let instance = try? api.pigeonDelegate.pigeonDefaultConstructor( + pigeonApi: api, adTagUrl: "adTag?", adDisplayContainer: container, + contentPlayhead: contentPlayhead) + + XCTAssertNotNil(instance) + XCTAssertEqual( + instance?.adTagUrl, + "adTag?&request_agent=Flutter-IMA-\(AdsRequestProxyAPIDelegate.pluginVersion)") + XCTAssertIdentical(instance?.adDisplayContainer, container) + } +} diff --git a/packages/interactive_media_ads/example/ios/RunnerTests/CompanionAdProxyApiTests.swift b/packages/interactive_media_ads/example/ios/RunnerTests/CompanionAdProxyApiTests.swift new file mode 100644 index 000000000000..59391c3d5ec6 --- /dev/null +++ b/packages/interactive_media_ads/example/ios/RunnerTests/CompanionAdProxyApiTests.swift @@ -0,0 +1,77 @@ +// 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 Flutter +import GoogleInteractiveMediaAds +import XCTest + +@testable import interactive_media_ads + +class CompanionAdProxyApiTests: XCTestCase { + func testResourceValue() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMACompanionAd(registrar) + + let instance = TestCompanionAd.customInit() + let value = try? api.pigeonDelegate.resourceValue(pigeonApi: api, pigeonInstance: instance) + + XCTAssertEqual(value, instance.resourceValue) + } + + func testApiFramework() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMACompanionAd(registrar) + + let instance = TestCompanionAd.customInit() + let value = try? api.pigeonDelegate.apiFramework(pigeonApi: api, pigeonInstance: instance) + + XCTAssertEqual(value, instance.apiFramework) + } + + func testWidth() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMACompanionAd(registrar) + + let instance = TestCompanionAd.customInit() + let value = try? api.pigeonDelegate.width(pigeonApi: api, pigeonInstance: instance) + + XCTAssertEqual(value, Int64(instance.width)) + } + + func testHeight() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMACompanionAd(registrar) + + let instance = TestCompanionAd.customInit() + let value = try? api.pigeonDelegate.height(pigeonApi: api, pigeonInstance: instance) + + XCTAssertEqual(value, Int64(instance.height)) + } + +} + +class TestCompanionAd: IMACompanionAd { + // Workaround to subclass an Objective-C class that has an `init` constructor with NS_UNAVAILABLE + static func customInit() -> TestCompanionAd { + let instance = + TestCompanionAd.perform(NSSelectorFromString("new")).takeRetainedValue() as! TestCompanionAd + return instance + } + + override var resourceValue: String? { + return "resourceValue" + } + + override var apiFramework: String? { + return "apiFramework" + } + + override var width: Int { + return 0 + } + + override var height: Int { + return 1 + } +} diff --git a/packages/interactive_media_ads/example/ios/RunnerTests/CompanionAdSlotProxyApiTests.swift b/packages/interactive_media_ads/example/ios/RunnerTests/CompanionAdSlotProxyApiTests.swift new file mode 100644 index 000000000000..987389e58226 --- /dev/null +++ b/packages/interactive_media_ads/example/ios/RunnerTests/CompanionAdSlotProxyApiTests.swift @@ -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. + +import Flutter +import GoogleInteractiveMediaAds +import UIKit +import XCTest + +@testable import interactive_media_ads + +class CompanionAdSlotProxyApiTests: XCTestCase { + func testPigeonDefaultConstructor() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMACompanionAdSlot(registrar) + + let view = UIView() + let instance = try! api.pigeonDelegate.pigeonDefaultConstructor(pigeonApi: api, view: view) + XCTAssertEqual(instance.view, view) + } + + func testSize() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMACompanionAdSlot(registrar) + + let view = UIView() + let width = 0 + let height = 1 + let instance = try! api.pigeonDelegate.size( + pigeonApi: api, view: view, width: Int64(width), height: Int64(height)) + XCTAssertEqual(instance.view, view) + XCTAssertEqual(instance.width, width) + XCTAssertEqual(instance.height, height) + } + + func testView() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMACompanionAdSlot(registrar) + + let instance = IMACompanionAdSlot(view: UIView()) + let value = try? api.pigeonDelegate.view(pigeonApi: api, pigeonInstance: instance) + + XCTAssertEqual(value, instance.view) + } + + func testSetDelegate() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMACompanionAdSlot(registrar) + + let instance = IMACompanionAdSlot(view: UIView()) + let delegate = CompanionDelegateImpl( + api: registrar.apiDelegate.pigeonApiIMACompanionDelegate(registrar)) + try? api.pigeonDelegate.setDelegate( + pigeonApi: api, pigeonInstance: instance, delegate: delegate) + + XCTAssertIdentical(instance.delegate, delegate) + } +} diff --git a/packages/interactive_media_ads/example/ios/RunnerTests/CompanionDelegateProxyApiTests.swift b/packages/interactive_media_ads/example/ios/RunnerTests/CompanionDelegateProxyApiTests.swift new file mode 100644 index 000000000000..e66f5e2a5f06 --- /dev/null +++ b/packages/interactive_media_ads/example/ios/RunnerTests/CompanionDelegateProxyApiTests.swift @@ -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 Flutter +import GoogleInteractiveMediaAds +import UIKit +import XCTest + +@testable import interactive_media_ads + +class CompanionDelegateProxyApiTests: XCTestCase { + func testPigeonDefaultConstructor() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMACompanionDelegate(registrar) + + let instance = try? api.pigeonDelegate.pigeonDefaultConstructor(pigeonApi: api) + XCTAssertNotNil(instance) + } + + func testCompanionAdSlotFilled() { + let api = TestCompanionDelegateApi() + let instance = CompanionDelegateImpl(api: api) + let slot = IMACompanionAdSlot(view: UIView()) + let filled = true + instance.companionSlot(slot, filled: filled) + + XCTAssertEqual(api.companionAdSlotFilledArgs, [slot, filled]) + } + + func testCompanionSlotWasClicked() { + let api = TestCompanionDelegateApi() + let instance = CompanionDelegateImpl(api: api) + let slot = IMACompanionAdSlot(view: UIView()) + instance.companionSlotWasClicked(slot) + + XCTAssertEqual(api.companionSlotWasClickedArgs, [slot]) + } +} + +class TestCompanionDelegateApi: PigeonApiProtocolIMACompanionDelegate { + var companionAdSlotFilledArgs: [AnyHashable?]? = nil + var companionSlotWasClickedArgs: [AnyHashable?]? = nil + + func companionAdSlotFilled( + pigeonInstance pigeonInstanceArg: IMACompanionDelegate, slot slotArg: IMACompanionAdSlot, + filled filledArg: Bool, + completion: @escaping (Result) -> Void + ) { + companionAdSlotFilledArgs = [slotArg, filledArg] + } + + func companionSlotWasClicked( + pigeonInstance pigeonInstanceArg: IMACompanionDelegate, slot slotArg: IMACompanionAdSlot, + completion: @escaping (Result) -> Void + ) { + companionSlotWasClickedArgs = [slotArg] + } +} diff --git a/packages/interactive_media_ads/example/ios/RunnerTests/ContentPlayheadTests.swift b/packages/interactive_media_ads/example/ios/RunnerTests/ContentPlayheadTests.swift new file mode 100644 index 000000000000..3d4b60fa35b8 --- /dev/null +++ b/packages/interactive_media_ads/example/ios/RunnerTests/ContentPlayheadTests.swift @@ -0,0 +1,32 @@ +// 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 Flutter +import GoogleInteractiveMediaAds +import XCTest + +@testable import interactive_media_ads + +final class ContentPlayheadTests: XCTestCase { + func testPigeonDefaultConstructor() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAContentPlayhead(registrar) + + let instance = try? api.pigeonDelegate.pigeonDefaultConstructor( + pigeonApi: api) + + XCTAssertNotNil(instance) + } + + func testSetCurrentTime() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAContentPlayhead(registrar) + + let instance = ContentPlayheadImpl() + try? api.pigeonDelegate.setCurrentTime( + pigeonApi: api, pigeonInstance: instance, timeInterval: 12) + + XCTAssertEqual(instance.currentTime, 12) + } +} diff --git a/packages/interactive_media_ads/example/ios/RunnerTests/FriendlyObstructionTests.swift b/packages/interactive_media_ads/example/ios/RunnerTests/FriendlyObstructionTests.swift new file mode 100644 index 000000000000..7fab9c42f83e --- /dev/null +++ b/packages/interactive_media_ads/example/ios/RunnerTests/FriendlyObstructionTests.swift @@ -0,0 +1,66 @@ +// 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 Flutter +import GoogleInteractiveMediaAds +import UIKit +import XCTest + +@testable import interactive_media_ads + +class FriendlyObstructionProxyApiTests: XCTestCase { + func testPigeonDefaultConstructor() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAFriendlyObstruction(registrar) + + let instance = try? api.pigeonDelegate.pigeonDefaultConstructor( + pigeonApi: api, view: UIView(), purpose: .mediaControls, detailedReason: "myString") + XCTAssertNotNil(instance) + } + + func testPigeonDefaultConstructorWithUnknownPurpose() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAFriendlyObstruction(registrar) + + XCTAssertThrowsError( + try api.pigeonDelegate.pigeonDefaultConstructor( + pigeonApi: api, view: UIView(), purpose: .unknown, detailedReason: "myString") + ) { error in + XCTAssertTrue(error is PigeonError) + } + } + + func testView() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAFriendlyObstruction(registrar) + + let instance = IMAFriendlyObstruction( + view: UIView(), purpose: IMAFriendlyObstructionPurpose.closeAd, detailedReason: "reason") + let value = try? api.pigeonDelegate.view(pigeonApi: api, pigeonInstance: instance) + + XCTAssertEqual(value, instance.view) + } + + func testPurpose() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAFriendlyObstruction(registrar) + + let instance = IMAFriendlyObstruction( + view: UIView(), purpose: IMAFriendlyObstructionPurpose.closeAd, detailedReason: "reason") + let value = try? api.pigeonDelegate.purpose(pigeonApi: api, pigeonInstance: instance) + + XCTAssertEqual(value, FriendlyObstructionPurpose.closeAd) + } + + func testDetailedReason() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAFriendlyObstruction(registrar) + + let instance = IMAFriendlyObstruction( + view: UIView(), purpose: IMAFriendlyObstructionPurpose.closeAd, detailedReason: "reason") + let value = try? api.pigeonDelegate.detailedReason(pigeonApi: api, pigeonInstance: instance) + + XCTAssertEqual(value, instance.detailedReason) + } +} diff --git a/packages/interactive_media_ads/example/ios/RunnerTests/RunnerTests.swift b/packages/interactive_media_ads/example/ios/RunnerTests/RunnerTests.swift deleted file mode 100644 index cea3cbd3a1fb..000000000000 --- a/packages/interactive_media_ads/example/ios/RunnerTests/RunnerTests.swift +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import Flutter -import UIKit -import XCTest - -@testable import interactive_media_ads - -// This demonstrates a simple unit test of the Swift portion of this plugin's implementation. -// -// See https://developer.apple.com/documentation/xctest for more information about using XCTest. - -class RunnerTests: XCTestCase { - - func testGetPlatformVersion() { - let plugin = InteractiveMediaAdsPlugin() - - let call = FlutterMethodCall(methodName: "getPlatformVersion", arguments: []) - - let resultExpectation = expectation(description: "result block must be called.") - plugin.handle(call) { result in - XCTAssertEqual(result as! String, "iOS " + UIDevice.current.systemVersion) - resultExpectation.fulfill() - } - waitForExpectations(timeout: 1) - } - -} diff --git a/packages/interactive_media_ads/example/ios/RunnerTests/TestProxyApiRegistrar.swift b/packages/interactive_media_ads/example/ios/RunnerTests/TestProxyApiRegistrar.swift new file mode 100644 index 000000000000..cb723d71de71 --- /dev/null +++ b/packages/interactive_media_ads/example/ios/RunnerTests/TestProxyApiRegistrar.swift @@ -0,0 +1,37 @@ +// 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 Flutter +import XCTest + +@testable import interactive_media_ads + +class TestProxyApiRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar { + private class TestBinaryMessenger: NSObject, FlutterBinaryMessenger { + func send(onChannel channel: String, message: Data?) { + + } + + func send( + onChannel channel: String, message: Data?, binaryReply callback: FlutterBinaryReply? = nil + ) { + + } + + func setMessageHandlerOnChannel( + _ channel: String, binaryMessageHandler handler: FlutterBinaryMessageHandler? = nil + ) -> FlutterBinaryMessengerConnection { + return 0 + } + + func cleanUpConnection(_ connection: FlutterBinaryMessengerConnection) { + + } + } + + init() { + let testBinaryMessenger = TestBinaryMessenger() + super.init(binaryMessenger: testBinaryMessenger, apiDelegate: ProxyApiDelegate()) + } +} diff --git a/packages/interactive_media_ads/example/ios/RunnerTests/ViewControllerTests.swift b/packages/interactive_media_ads/example/ios/RunnerTests/ViewControllerTests.swift new file mode 100644 index 000000000000..73ccd24c40be --- /dev/null +++ b/packages/interactive_media_ads/example/ios/RunnerTests/ViewControllerTests.swift @@ -0,0 +1,50 @@ +// 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 Flutter +import XCTest + +@testable import interactive_media_ads + +final class ViewControllerTests: XCTestCase { + func testPigeonDefaultConstructor() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiUIViewController(registrar) + + let instance = try? api.pigeonDelegate.pigeonDefaultConstructor( + pigeonApi: api) + + XCTAssertNotNil(instance) + } + + func testView() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiUIViewController(registrar) + + let instance = UIViewController() + let view = try? api.pigeonDelegate.view(pigeonApi: api, pigeonInstance: instance) + + XCTAssertNotNil(view) + } + + func testViewDidAppear() { + let api = TestUIViewControllerApi() + let instance = ViewControllerImpl(api: api) + + instance.viewDidAppear(true) + + XCTAssertEqual(api.viewDidAppearArgs, [instance, true]) + } +} + +class TestUIViewControllerApi: PigeonApiProtocolUIViewController { + var viewDidAppearArgs: [AnyHashable?]? = nil + + func viewDidAppear( + pigeonInstance pigeonInstanceArg: UIViewController, animated animatedArg: Bool, + completion: @escaping (Result) -> Void + ) { + viewDidAppearArgs = [pigeonInstanceArg, animatedArg] + } +} diff --git a/packages/interactive_media_ads/example/lib/main.dart b/packages/interactive_media_ads/example/lib/main.dart index fd385e0a60c3..01cdb603dc01 100644 --- a/packages/interactive_media_ads/example/lib/main.dart +++ b/packages/interactive_media_ads/example/lib/main.dart @@ -2,9 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:flutter/foundation.dart'; +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:flutter_driver/driver_extension.dart'; +// #docregion imports +import 'package:interactive_media_ads/interactive_media_ads.dart'; +import 'package:video_player/video_player.dart'; +// #enddocregion imports /// Entry point for integration tests that require espresso. @pragma('vm:entry-point') @@ -14,31 +19,252 @@ void integrationTestMain() { } void main() { - runApp(const MyApp()); + runApp(const MaterialApp(home: AdExampleWidget())); } -/// Home widget of the example app. -class MyApp extends StatefulWidget { - /// Constructs [MyApp]. - const MyApp({super.key}); +// #docregion example_widget +/// Example widget displaying an Ad before a video. +class AdExampleWidget extends StatefulWidget { + /// Constructs an [AdExampleWidget]. + const AdExampleWidget({super.key}); @override - State createState() => _MyAppState(); + State createState() => _AdExampleWidgetState(); } -class _MyAppState extends State { +class _AdExampleWidgetState extends State + with WidgetsBindingObserver { + // IMA sample tag for a pre-, mid-, and post-roll, single inline video ad. See more IMA sample + // tags at https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/tags + static const String _adTagUrl = + 'https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/vmap_ad_samples&sz=640x480&cust_params=sample_ar%3Dpremidpost&ciu_szs=300x250&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&env=vp&impl=s&cmsid=496&vid=short_onecue&correlator='; + + // The AdsLoader instance exposes the request ads method. + late final AdsLoader _adsLoader; + + // AdsManager exposes methods to control ad playback and listen to ad events. + AdsManager? _adsManager; + + // #enddocregion example_widget + // Last state received in `didChangeAppLifecycleState`. + AppLifecycleState _lastLifecycleState = AppLifecycleState.resumed; + + // #docregion example_widget + // Whether the widget should be displaying the content video. The content + // player is hidden while Ads are playing. + bool _shouldShowContentVideo = false; + + // Controls the content video player. + late final VideoPlayerController _contentVideoController; + + // Periodically updates the SDK of the current playback progress of the + // content video. + Timer? _contentProgressTimer; + + // Provides the SDK with the current playback progress of the content video. + // This is required to support mid-roll ads. + final ContentProgressProvider _contentProgressProvider = + ContentProgressProvider(); + // #enddocregion example_widget + + // #docregion ad_and_content_players + late final AdDisplayContainer _adDisplayContainer = AdDisplayContainer( + onContainerAdded: (AdDisplayContainer container) { + _adsLoader = AdsLoader( + container: container, + onAdsLoaded: (OnAdsLoadedData data) { + final AdsManager manager = data.manager; + _adsManager = data.manager; + + manager.setAdsManagerDelegate(AdsManagerDelegate( + onAdEvent: (AdEvent event) { + debugPrint('OnAdEvent: ${event.type} => ${event.adData}'); + switch (event.type) { + case AdEventType.loaded: + manager.start(); + case AdEventType.contentPauseRequested: + _pauseContent(); + case AdEventType.contentResumeRequested: + _resumeContent(); + case AdEventType.allAdsCompleted: + manager.destroy(); + _adsManager = null; + case AdEventType.clicked: + case AdEventType.complete: + case _: + } + }, + onAdErrorEvent: (AdErrorEvent event) { + debugPrint('AdErrorEvent: ${event.error.message}'); + _resumeContent(); + }, + )); + + manager.init(); + }, + onAdsLoadError: (AdsLoadErrorData data) { + debugPrint('OnAdsLoadError: ${data.error.message}'); + _resumeContent(); + }, + ); + + // Ads can't be requested until the `AdDisplayContainer` has been added to + // the native View hierarchy. + _requestAds(container); + }, + ); + + @override + void initState() { + super.initState(); + // #enddocregion ad_and_content_players + // Adds this instance as an observer for `AppLifecycleState` changes. + WidgetsBinding.instance.addObserver(this); + + // #docregion ad_and_content_players + _contentVideoController = VideoPlayerController.networkUrl( + Uri.parse( + 'https://storage.googleapis.com/gvabox/media/samples/stock.mp4', + ), + ) + ..addListener(() { + if (_contentVideoController.value.isCompleted) { + _adsLoader.contentComplete(); + } + setState(() {}); + }) + ..initialize().then((_) { + // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed. + setState(() {}); + }); + } + // #enddocregion ad_and_content_players + + @override + void didChangeAppLifecycleState(AppLifecycleState state) { + switch (state) { + case AppLifecycleState.resumed: + if (!_shouldShowContentVideo) { + _adsManager?.resume(); + } + case AppLifecycleState.inactive: + // Pausing the Ad video player on Android can only be done in this state + // because it corresponds to `Activity.onPause`. This state is also + // triggered before resume, so this will only pause the Ad if the app is + // in the process of being sent to the background. + if (!_shouldShowContentVideo && + _lastLifecycleState == AppLifecycleState.resumed) { + _adsManager?.pause(); + } + case AppLifecycleState.hidden: + case AppLifecycleState.paused: + case AppLifecycleState.detached: + } + _lastLifecycleState = state; + } + + // #docregion request_ads + Future _requestAds(AdDisplayContainer container) { + return _adsLoader.requestAds(AdsRequest( + adTagUrl: _adTagUrl, + contentProgressProvider: _contentProgressProvider, + )); + } + + Future _resumeContent() async { + setState(() { + _shouldShowContentVideo = true; + }); + + if (_adsManager != null) { + _contentProgressTimer = Timer.periodic( + const Duration(milliseconds: 200), + (Timer timer) async { + if (_contentVideoController.value.isInitialized) { + final Duration? progress = await _contentVideoController.position; + if (progress != null) { + await _contentProgressProvider.setProgress( + progress: progress, + duration: _contentVideoController.value.duration, + ); + } + } + }, + ); + } + + await _contentVideoController.play(); + } + + Future _pauseContent() { + setState(() { + _shouldShowContentVideo = false; + }); + _contentProgressTimer?.cancel(); + _contentProgressTimer = null; + return _contentVideoController.pause(); + } + // #enddocregion request_ads + + // #docregion dispose + @override + void dispose() { + super.dispose(); + _contentProgressTimer?.cancel(); + _contentVideoController.dispose(); + _adsManager?.destroy(); + // #enddocregion dispose + WidgetsBinding.instance.removeObserver(this); + // #docregion dispose + } + // #enddocregion dispose + + // #docregion example_widget + // #docregion widget_build @override Widget build(BuildContext context) { - debugPrint('THEAPP'); - return MaterialApp( - home: Scaffold( - appBar: AppBar( - title: const Text('Plugin example app'), - ), - body: Center( - child: Text('Running on: $defaultTargetPlatform'), + // #enddocregion example_widget + return Scaffold( + body: Center( + child: SizedBox( + width: 300, + child: !_contentVideoController.value.isInitialized + ? Container() + : AspectRatio( + aspectRatio: _contentVideoController.value.aspectRatio, + child: Stack( + children: [ + // The display container must be on screen before any Ads can be + // loaded and can't be removed between ads. This handles clicks for + // ads. + _adDisplayContainer, + if (_shouldShowContentVideo) + VideoPlayer(_contentVideoController) + ], + ), + ), ), ), + floatingActionButton: + _contentVideoController.value.isInitialized && _shouldShowContentVideo + ? FloatingActionButton( + onPressed: () { + setState(() { + _contentVideoController.value.isPlaying + ? _contentVideoController.pause() + : _contentVideoController.play(); + }); + }, + child: Icon( + _contentVideoController.value.isPlaying + ? Icons.pause + : Icons.play_arrow, + ), + ) + : null, ); + // #docregion example_widget } + // #enddocregion widget_build } +// #enddocregion example_widget diff --git a/packages/interactive_media_ads/example/pubspec.yaml b/packages/interactive_media_ads/example/pubspec.yaml index fde3e7a8b2ec..bf8ce6d5a487 100644 --- a/packages/interactive_media_ads/example/pubspec.yaml +++ b/packages/interactive_media_ads/example/pubspec.yaml @@ -3,8 +3,8 @@ description: "Demonstrates how to use the interactive_media_ads plugin." publish_to: 'none' # Remove this line if you wish to publish to pub.dev environment: - sdk: ^3.2.3 - flutter: ">=3.16.6" + sdk: ^3.5.0 + flutter: ">=3.24.0" dependencies: flutter: @@ -13,9 +13,10 @@ dependencies: sdk: flutter interactive_media_ads: path: ../ + video_player: ^2.8.6 dev_dependencies: - espresso: ^0.2.0 + espresso: ^0.4.0 flutter_test: sdk: flutter integration_test: diff --git a/packages/interactive_media_ads/ios/interactive_media_ads.podspec b/packages/interactive_media_ads/ios/interactive_media_ads.podspec index bb42cc28763b..093c7d3d9324 100644 --- a/packages/interactive_media_ads/ios/interactive_media_ads.podspec +++ b/packages/interactive_media_ads/ios/interactive_media_ads.podspec @@ -16,6 +16,7 @@ Downloaded by pub (not CocoaPods). s.source = { :http => 'https://github.com/flutter/packages/tree/main/packages/interactive_media_ads/interactive_media_ads' } s.source_files = 'interactive_media_ads/Sources/interactive_media_ads/**/*.swift' s.dependency 'Flutter' + s.dependency 'GoogleAds-IMA-iOS-SDK', '~> 3.23' s.platform = :ios, '12.0' # Flutter.framework does not contain a i386 slice. diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Package.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Package.swift index 1864dffbb787..1ef9d7838d00 100644 --- a/packages/interactive_media_ads/ios/interactive_media_ads/Package.swift +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Package.swift @@ -15,11 +15,19 @@ let package = Package( products: [ .library(name: "interactive-media-ads", targets: ["interactive_media_ads"]) ], - dependencies: [], + dependencies: [ + .package( + url: "https://github.com/googleads/swift-package-manager-google-interactive-media-ads-ios", + .upToNextMajor(from: "3.23.0")) + ], targets: [ .target( name: "interactive_media_ads", - dependencies: [], + dependencies: [ + .product( + name: "GoogleInteractiveMediaAds", + package: "swift-package-manager-google-interactive-media-ads-ios") + ], resources: [ .process("Resources") ] diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdDisplayContainerProxyAPIDelegate.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdDisplayContainerProxyAPIDelegate.swift new file mode 100644 index 000000000000..a7ab7f0f504c --- /dev/null +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdDisplayContainerProxyAPIDelegate.swift @@ -0,0 +1,20 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import Foundation +import GoogleInteractiveMediaAds + +/// ProxyApi delegate implementation for `IMAAdDisplayContainer`. +/// +/// This class may handle instantiating native object instances that are attached to a Dart +/// instance or handle method calls on the associated native class or an instance of that class. +class AdDisplayContainerProxyAPIDelegate: PigeonApiDelegateIMAAdDisplayContainer { + func pigeonDefaultConstructor( + pigeonApi: PigeonApiIMAAdDisplayContainer, adContainer: UIView, + adContainerViewController: UIViewController? + ) throws -> IMAAdDisplayContainer { + return IMAAdDisplayContainer( + adContainer: adContainer, viewController: adContainerViewController) + } +} diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdErrorProxyAPIDelegate.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdErrorProxyAPIDelegate.swift new file mode 100644 index 000000000000..3005bbd81a26 --- /dev/null +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdErrorProxyAPIDelegate.swift @@ -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 Foundation +import GoogleInteractiveMediaAds + +/// ProxyApi delegate implementation for `IMAAdError`. +/// +/// This class may handle instantiating native object instances that are attached to a Dart +/// instance or handle method calls on the associated native class or an instance of that class. +class AdErrorProxyAPIDelegate: PigeonApiDelegateIMAAdError { + func type(pigeonApi: PigeonApiIMAAdError, pigeonInstance: IMAAdError) throws -> AdErrorType { + switch pigeonInstance.type { + case .adLoadingFailed: + return .loadingFailed + case .adPlayingFailed: + return .adPlayingFailed + case .adUnknownErrorType: + return .unknown + @unknown default: + return .unknown + } + } + + func code(pigeonApi: PigeonApiIMAAdError, pigeonInstance: IMAAdError) throws -> AdErrorCode { + switch pigeonInstance.code { + case .VAST_MALFORMED_RESPONSE: + return .vastMalformedResponse + case .VAST_TRAFFICKING_ERROR: + return .vastTraffickingError + case .VAST_LOAD_TIMEOUT: + return .vastLoadTimeout + case .VAST_TOO_MANY_REDIRECTS: + return .vastTooManyRedirects + case .VAST_INVALID_URL: + return .vastInvalidUrl + case .VIDEO_PLAY_ERROR: + return .videoPlayError + case .VAST_MEDIA_LOAD_TIMEOUT: + return .vastMediaLoadTimeout + case .VAST_LINEAR_ASSET_MISMATCH: + return .vastLinearAssetMismatch + case .COMPANION_AD_LOADING_FAILED: + return .companionAdLoadingFailed + case .UNKNOWN_ERROR: + return .unknownError + case .PLAYLIST_MALFORMED_RESPONSE: + return .playlistMalformedResponse + case .FAILED_TO_REQUEST_ADS: + return .failedToRequestAds + case .REQUIRED_LISTENERS_NOT_ADDED: + return .requiredListenersNotAdded + case .VAST_ASSET_NOT_FOUND: + return .vastAssetNotFound + case .ADSLOT_NOT_VISIBLE: + return .adslotNotVisible + case .VAST_EMPTY_RESPONSE: + return .vastEmptyResponse + case .FAILED_LOADING_AD: + return .failedLoadingAd + case .STREAM_INITIALIZATION_FAILED: + return .streamInitializationFailed + case .INVALID_ARGUMENTS: + return .invalidArguments + case .API_ERROR: + return .apiError + case .OS_RUNTIME_TOO_OLD: + return .osRuntimeTooOld + case .VIDEO_ELEMENT_USED: + return .videoElementUsed + case .VIDEO_ELEMENT_REQUIRED: + return .videoElementRequired + case .CONTENT_PLAYHEAD_MISSING: + return .contentPlayheadMissing + @unknown default: + return .unknownError + } + } + + func message(pigeonApi: PigeonApiIMAAdError, pigeonInstance: IMAAdError) throws -> String? { + return pigeonInstance.message + } +} diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdEventProxyAPIDelegate.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdEventProxyAPIDelegate.swift new file mode 100644 index 000000000000..f4d018700d06 --- /dev/null +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdEventProxyAPIDelegate.swift @@ -0,0 +1,75 @@ +// 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 Foundation +import GoogleInteractiveMediaAds + +/// ProxyApi delegate implementation for `IMAAdEvent`. +/// +/// This class may handle instantiating native object instances that are attached to a Dart +/// instance or handle method calls on the associated native class or an instance of that class. +class AdEventProxyAPIDelegate: PigeonApiDelegateIMAAdEvent { + func adData(pigeonApi: PigeonApiIMAAdEvent, pigeonInstance: IMAAdEvent) throws -> [String: Any]? { + return pigeonInstance.adData + } + + func type(pigeonApi: PigeonApiIMAAdEvent, pigeonInstance: IMAAdEvent) throws -> AdEventType { + switch pigeonInstance.type { + case .AD_BREAK_READY: + return .adBreakReady + case .AD_BREAK_FETCH_ERROR: + return .adBreakFetchError + case .AD_BREAK_ENDED: + return .adBreakEnded + case .AD_BREAK_STARTED: + return .adBreakStarted + case .AD_PERIOD_ENDED: + return .adPeriodEnded + case .AD_PERIOD_STARTED: + return .adPeriodStarted + case .ALL_ADS_COMPLETED: + return .allAdsCompleted + case .CLICKED: + return .clicked + case .COMPLETE: + return .completed + case .CUEPOINTS_CHANGED: + return .cuepointsChanged + case .ICON_FALLBACK_IMAGE_CLOSED: + return .iconFallbackImageClosed + case .ICON_TAPPED: + return .iconTapped + case .FIRST_QUARTILE: + return .firstQuartile + case .LOADED: + return .loaded + case .LOG: + return .log + case .MIDPOINT: + return .midpoint + case .PAUSE: + return .pause + case .RESUME: + return .resume + case .SKIPPED: + return .skipped + case .STARTED: + return .started + case .STREAM_LOADED: + return .streamLoaded + case .STREAM_STARTED: + return .streamStarted + case .TAPPED: + return .tapped + case .THIRD_QUARTILE: + return .thirdQuartile + @unknown default: + return .unknown + } + } + + func typeString(pigeonApi: PigeonApiIMAAdEvent, pigeonInstance: IMAAdEvent) throws -> String { + return pigeonInstance.typeString + } +} diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdLoadingErrorDataProxyAPIDelegate.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdLoadingErrorDataProxyAPIDelegate.swift new file mode 100644 index 000000000000..3179213941f5 --- /dev/null +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdLoadingErrorDataProxyAPIDelegate.swift @@ -0,0 +1,18 @@ +// 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 Foundation +import GoogleInteractiveMediaAds + +/// ProxyApi delegate implementation for `IMAAdLoadingErrorData`. +/// +/// This class may handle instantiating native object instances that are attached to a Dart +/// instance or handle method calls on the associated native class or an instance of that class. +class AdLoadingErrorDataProxyAPIDelegate: PigeonApiDelegateIMAAdLoadingErrorData { + func adError(pigeonApi: PigeonApiIMAAdLoadingErrorData, pigeonInstance: IMAAdLoadingErrorData) + throws -> IMAAdError + { + return pigeonInstance.adError + } +} diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsLoadedDataProxyAPIDelegate.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsLoadedDataProxyAPIDelegate.swift new file mode 100644 index 000000000000..f387cbbd50dd --- /dev/null +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsLoadedDataProxyAPIDelegate.swift @@ -0,0 +1,18 @@ +// 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 Foundation +import GoogleInteractiveMediaAds + +/// ProxyApi delegate implementation for `IMAAdsLoadedData`. +/// +/// This class may handle instantiating native object instances that are attached to a Dart +/// instance or handle method calls on the associated native class or an instance of that class. +class AdsLoadedDataProxyAPIDelegate: PigeonApiDelegateIMAAdsLoadedData { + func adsManager(pigeonApi: PigeonApiIMAAdsLoadedData, pigeonInstance: IMAAdsLoadedData) throws + -> IMAAdsManager? + { + return pigeonInstance.adsManager + } +} diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsLoaderDelegateProxyAPIDelegate.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsLoaderDelegateProxyAPIDelegate.swift new file mode 100644 index 000000000000..53eda9bc51c2 --- /dev/null +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsLoaderDelegateProxyAPIDelegate.swift @@ -0,0 +1,38 @@ +// 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 Foundation +import GoogleInteractiveMediaAds + +/// Implementation of `IMAAdsManagerDelegate` that calls to Dart in callback methods. +class AdsLoaderDelegateImpl: IMAAdsLoaderDelegate { + let api: PigeonApiProtocolIMAAdsLoaderDelegate + + init(api: PigeonApiProtocolIMAAdsLoaderDelegate) { + self.api = api + } + + func adsLoader(_ loader: IMAAdsLoader, adsLoadedWith adsLoadedData: IMAAdsLoadedData) { + api.adLoaderLoadedWith(pigeonInstance: self, loader: loader, adsLoadedData: adsLoadedData) { + _ in + } + } + + func adsLoader(_ loader: IMAAdsLoader, failedWith adErrorData: IMAAdLoadingErrorData) { + api.adsLoaderFailedWithErrorData(pigeonInstance: self, loader: loader, adErrorData: adErrorData) + { _ in } + } +} + +/// ProxyApi delegate implementation for `IMAAdsLoaderDelegate`. +/// +/// This class may handle instantiating native object instances that are attached to a Dart +/// instance or handle method calls on the associated native class or an instance of that class. +class AdsLoaderDelegateProxyAPIDelegate: PigeonApiDelegateIMAAdsLoaderDelegate { + func pigeonDefaultConstructor(pigeonApi: PigeonApiIMAAdsLoaderDelegate) throws + -> IMAAdsLoaderDelegate + { + return AdsLoaderDelegateImpl(api: pigeonApi) + } +} diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsLoaderProxyAPIDelegate.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsLoaderProxyAPIDelegate.swift new file mode 100644 index 000000000000..d1cf5fe56cb5 --- /dev/null +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsLoaderProxyAPIDelegate.swift @@ -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. + +import Foundation +import GoogleInteractiveMediaAds + +/// ProxyApi delegate implementation for `IMAAdsLoader`. +/// +/// This class may handle instantiating native object instances that are attached to a Dart +/// instance or handle method calls on the associated native class or an instance of that class. +class AdsLoaderProxyAPIDelegate: PigeonApiDelegateIMAAdsLoader { + func pigeonDefaultConstructor(pigeonApi: PigeonApiIMAAdsLoader, settings: IMASettings?) throws + -> IMAAdsLoader + { + return IMAAdsLoader(settings: settings) + } + + func contentComplete(pigeonApi: PigeonApiIMAAdsLoader, pigeonInstance: IMAAdsLoader) throws { + pigeonInstance.contentComplete() + } + + func requestAds( + pigeonApi: PigeonApiIMAAdsLoader, pigeonInstance: IMAAdsLoader, request: IMAAdsRequest + ) throws { + pigeonInstance.requestAds(with: request) + } + + func setDelegate( + pigeonApi: PigeonApiIMAAdsLoader, pigeonInstance: IMAAdsLoader, delegate: IMAAdsLoaderDelegate? + ) throws { + pigeonInstance.delegate = delegate + } +} diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsManagerDelegateProxyAPIDelegate.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsManagerDelegateProxyAPIDelegate.swift new file mode 100644 index 000000000000..8b48f77a30ba --- /dev/null +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsManagerDelegateProxyAPIDelegate.swift @@ -0,0 +1,43 @@ +// 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 Foundation +import GoogleInteractiveMediaAds + +/// Implementation of `IMAAdsManagerDelegate` that calls to Dart in callback methods. +class AdsManagerDelegateImpl: NSObject, IMAAdsManagerDelegate { + let api: PigeonApiProtocolIMAAdsManagerDelegate + + init(api: PigeonApiProtocolIMAAdsManagerDelegate) { + self.api = api + } + + func adsManager(_ adsManager: IMAAdsManager, didReceive event: IMAAdEvent) { + api.didReceiveAdEvent(pigeonInstance: self, adsManager: adsManager, event: event) { _ in } + } + + func adsManager(_ adsManager: IMAAdsManager, didReceive error: IMAAdError) { + api.didReceiveAdError(pigeonInstance: self, adsManager: adsManager, error: error) { _ in } + } + + func adsManagerDidRequestContentPause(_ adsManager: IMAAdsManager) { + api.didRequestContentPause(pigeonInstance: self, adsManager: adsManager) { _ in } + } + + func adsManagerDidRequestContentResume(_ adsManager: IMAAdsManager) { + api.didRequestContentResume(pigeonInstance: self, adsManager: adsManager) { _ in } + } +} + +/// ProxyApi delegate implementation for `IMAAdsManagerDelegate`. +/// +/// This class may handle instantiating native object instances that are attached to a Dart +/// instance or handle method calls on the associated native class or an instance of that class. +class AdsManagerDelegateProxyAPIDelegate: PigeonApiDelegateIMAAdsManagerDelegate { + func pigeonDefaultConstructor(pigeonApi: PigeonApiIMAAdsManagerDelegate) throws + -> IMAAdsManagerDelegate + { + return AdsManagerDelegateImpl(api: pigeonApi) + } +} diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsManagerProxyAPIDelegate.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsManagerProxyAPIDelegate.swift new file mode 100644 index 000000000000..3916362e4cb7 --- /dev/null +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsManagerProxyAPIDelegate.swift @@ -0,0 +1,50 @@ +// 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 Foundation +import GoogleInteractiveMediaAds + +/// ProxyApi delegate implementation for `IMAAdsManager`. +/// +/// This class may handle instantiating native object instances that are attached to a Dart +/// instance or handle method calls on the associated native class or an instance of that class. +class AdsManagerProxyAPIDelegate: PigeonApiDelegateIMAAdsManager { + func setDelegate( + pigeonApi: PigeonApiIMAAdsManager, pigeonInstance: IMAAdsManager, + delegate: IMAAdsManagerDelegate? + ) throws { + pigeonInstance.delegate = delegate as? AdsManagerDelegateImpl + } + + func initialize( + pigeonApi: PigeonApiIMAAdsManager, pigeonInstance: IMAAdsManager, + adsRenderingSettings: IMAAdsRenderingSettings? + ) throws { + pigeonInstance.initialize(with: adsRenderingSettings) + } + + func start(pigeonApi: PigeonApiIMAAdsManager, pigeonInstance: IMAAdsManager) throws { + pigeonInstance.start() + } + + func pause(pigeonApi: PigeonApiIMAAdsManager, pigeonInstance: IMAAdsManager) throws { + pigeonInstance.pause() + } + + func skip(pigeonApi: PigeonApiIMAAdsManager, pigeonInstance: IMAAdsManager) throws { + pigeonInstance.skip() + } + + func discardAdBreak(pigeonApi: PigeonApiIMAAdsManager, pigeonInstance: IMAAdsManager) throws { + pigeonInstance.discardAdBreak() + } + + func resume(pigeonApi: PigeonApiIMAAdsManager, pigeonInstance: IMAAdsManager) throws { + pigeonInstance.resume() + } + + func destroy(pigeonApi: PigeonApiIMAAdsManager, pigeonInstance: IMAAdsManager) throws { + pigeonInstance.destroy() + } +} diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsRenderingSettingsProxyAPIDelegate.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsRenderingSettingsProxyAPIDelegate.swift new file mode 100644 index 000000000000..bf63b7ecdb8b --- /dev/null +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsRenderingSettingsProxyAPIDelegate.swift @@ -0,0 +1,79 @@ +// 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 Foundation +import GoogleInteractiveMediaAds + +/// ProxyApi delegate implementation for `IMAAdsRenderingSettings`. +/// +/// This class may handle instantiating native object instances that are attached to a Dart +/// instance or handle method calls on the associated native class or an instance of that class. +class AdsRenderingSettingsProxyAPIDelegate: PigeonApiDelegateIMAAdsRenderingSettings { + func pigeonDefaultConstructor(pigeonApi: PigeonApiIMAAdsRenderingSettings) throws + -> IMAAdsRenderingSettings + { + return IMAAdsRenderingSettings() + } + + func setMimeTypes( + pigeonApi: PigeonApiIMAAdsRenderingSettings, pigeonInstance: IMAAdsRenderingSettings, + types: [String]? + ) throws { + pigeonInstance.mimeTypes = types + } + + func setBitrate( + pigeonApi: PigeonApiIMAAdsRenderingSettings, pigeonInstance: IMAAdsRenderingSettings, + bitrate: Int64 + ) throws { + pigeonInstance.bitrate = Int(bitrate) + } + + func setLoadVideoTimeout( + pigeonApi: PigeonApiIMAAdsRenderingSettings, pigeonInstance: IMAAdsRenderingSettings, + seconds: Double + ) throws { + pigeonInstance.loadVideoTimeout = seconds + } + + func setPlayAdsAfterTime( + pigeonApi: PigeonApiIMAAdsRenderingSettings, pigeonInstance: IMAAdsRenderingSettings, + seconds: Double + ) throws { + pigeonInstance.playAdsAfterTime = seconds + } + + func setUIElements( + pigeonApi: PigeonApiIMAAdsRenderingSettings, pigeonInstance: IMAAdsRenderingSettings, + types: [UIElementType]? + ) throws { + let nativeUiElementTypes: [NSNumber]? = try types?.map { type in + switch type { + case .adAttribution: + return IMAUiElementType.elements_AD_ATTRIBUTION.rawValue as NSNumber + case .countdown: + return IMAUiElementType.elements_COUNTDOWN.rawValue as NSNumber + case .unknown: + throw (pigeonApi.pigeonRegistrar.apiDelegate as! ProxyApiDelegate).createUnknownEnumError( + withEnum: type) + } + } + + pigeonInstance.uiElements = nativeUiElementTypes + } + + func setEnablePreloading( + pigeonApi: PigeonApiIMAAdsRenderingSettings, pigeonInstance: IMAAdsRenderingSettings, + enable: Bool + ) throws { + pigeonInstance.enablePreloading = enable + } + + func setLinkOpenerPresentingController( + pigeonApi: PigeonApiIMAAdsRenderingSettings, pigeonInstance: IMAAdsRenderingSettings, + controller: UIViewController + ) throws { + pigeonInstance.linkOpenerPresentingController = controller + } +} diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsRequestProxyAPIDelegate.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsRequestProxyAPIDelegate.swift new file mode 100644 index 000000000000..de4a711123da --- /dev/null +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsRequestProxyAPIDelegate.swift @@ -0,0 +1,32 @@ +// 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 Foundation +import GoogleInteractiveMediaAds + +/// ProxyApi delegate implementation for `IMAAdsRequest`. +/// +/// This class may handle instantiating native object instances that are attached to a Dart +/// instance or handle method calls on the associated native class or an instance of that class. +class AdsRequestProxyAPIDelegate: PigeonApiDelegateIMAAdsRequest { + /// The current version of the `interactive_media_ads` plugin. + /// + /// This must match the version in pubspec.yaml. + static let pluginVersion = "0.2.2+15" + + func pigeonDefaultConstructor( + pigeonApi: PigeonApiIMAAdsRequest, adTagUrl: String, adDisplayContainer: IMAAdDisplayContainer, + contentPlayhead: IMAContentPlayhead? + ) throws -> IMAAdsRequest { + // Ensure adTag can append a custom parameter. + assert(adTagUrl.contains("?")) + assert(!adTagUrl.contains("#")) + + let adTagWithRequestAgent = + "\(adTagUrl)&request_agent=Flutter-IMA-\(AdsRequestProxyAPIDelegate.pluginVersion)" + return IMAAdsRequest( + adTagUrl: adTagWithRequestAgent, adDisplayContainer: adDisplayContainer, + contentPlayhead: contentPlayhead as? ContentPlayheadImpl, userContext: nil) + } +} diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/CompanionAdProxyAPIDelegate.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/CompanionAdProxyAPIDelegate.swift new file mode 100644 index 000000000000..b58ad8b9055e --- /dev/null +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/CompanionAdProxyAPIDelegate.swift @@ -0,0 +1,32 @@ +// 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 Foundation +import GoogleInteractiveMediaAds + +/// ProxyApi implementation for [IMACompanionAd]. +/// +/// This class may handle instantiating native object instances that are attached to a Dart instance +/// or handle method calls on the associated native class or an instance of that class. +class CompanionAdProxyAPIDelegate: PigeonApiDelegateIMACompanionAd { + func resourceValue(pigeonApi: PigeonApiIMACompanionAd, pigeonInstance: IMACompanionAd) throws + -> String? + { + return pigeonInstance.resourceValue + } + + func apiFramework(pigeonApi: PigeonApiIMACompanionAd, pigeonInstance: IMACompanionAd) throws + -> String? + { + return pigeonInstance.apiFramework + } + + func width(pigeonApi: PigeonApiIMACompanionAd, pigeonInstance: IMACompanionAd) throws -> Int64 { + return Int64(pigeonInstance.width) + } + + func height(pigeonApi: PigeonApiIMACompanionAd, pigeonInstance: IMACompanionAd) throws -> Int64 { + return Int64(pigeonInstance.height) + } +} diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/CompanionAdSlotProxyAPIDelegate.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/CompanionAdSlotProxyAPIDelegate.swift new file mode 100644 index 000000000000..263063221a5e --- /dev/null +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/CompanionAdSlotProxyAPIDelegate.swift @@ -0,0 +1,38 @@ +// 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 Foundation +import GoogleInteractiveMediaAds +import UIKit + +/// ProxyApi implementation for [IMACompanionAdSlot]. +/// +/// This class may handle instantiating native object instances that are attached to a Dart instance +/// or handle method calls on the associated native class or an instance of that class. +class CompanionAdSlotProxyAPIDelegate: PigeonApiDelegateIMACompanionAdSlot { + func pigeonDefaultConstructor(pigeonApi: PigeonApiIMACompanionAdSlot, view: UIView) throws + -> IMACompanionAdSlot + { + return IMACompanionAdSlot(view: view) + } + + func size(pigeonApi: PigeonApiIMACompanionAdSlot, view: UIView, width: Int64, height: Int64) + throws -> IMACompanionAdSlot + { + return IMACompanionAdSlot(view: view, width: Int(width), height: Int(height)) + } + + func view(pigeonApi: PigeonApiIMACompanionAdSlot, pigeonInstance: IMACompanionAdSlot) throws + -> UIView + { + return pigeonInstance.view + } + + func setDelegate( + pigeonApi: PigeonApiIMACompanionAdSlot, pigeonInstance: IMACompanionAdSlot, + delegate: IMACompanionDelegate? + ) throws { + pigeonInstance.delegate = delegate + } +} diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/CompanionDelegateProxyAPIDelegate.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/CompanionDelegateProxyAPIDelegate.swift new file mode 100644 index 000000000000..b7e1a5f6d08b --- /dev/null +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/CompanionDelegateProxyAPIDelegate.swift @@ -0,0 +1,35 @@ +// 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 Foundation +import GoogleInteractiveMediaAds + +/// Implementation of `IMACompanionDelegate` that calls to Dart in callback methods. +class CompanionDelegateImpl: NSObject, IMACompanionDelegate { + let api: PigeonApiProtocolIMACompanionDelegate + + init(api: PigeonApiProtocolIMACompanionDelegate) { + self.api = api + } + + func companionSlot(_ slot: IMACompanionAdSlot, filled: Bool) { + api.companionAdSlotFilled(pigeonInstance: self, slot: slot, filled: filled) { _ in } + } + + func companionSlotWasClicked(_ slot: IMACompanionAdSlot) { + api.companionSlotWasClicked(pigeonInstance: self, slot: slot) { _ in } + } +} + +/// ProxyApi implementation for [IMACompanionDelegate]. +/// +/// This class may handle instantiating native object instances that are attached to a Dart instance +/// or handle method calls on the associated native class or an instance of that class. +class CompanionDelegateProxyAPIDelegate: PigeonApiDelegateIMACompanionDelegate { + func pigeonDefaultConstructor(pigeonApi: PigeonApiIMACompanionDelegate) throws + -> IMACompanionDelegate + { + return CompanionDelegateImpl(api: pigeonApi) + } +} diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/ContentPlayheadProxyAPIDelegate.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/ContentPlayheadProxyAPIDelegate.swift new file mode 100644 index 000000000000..2c7848216f3d --- /dev/null +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/ContentPlayheadProxyAPIDelegate.swift @@ -0,0 +1,29 @@ +// 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 Foundation +import GoogleInteractiveMediaAds + +/// Implementation of `IMAContentPlayhead` with a settable time interval. +class ContentPlayheadImpl: NSObject, IMAContentPlayhead { + var currentTime: TimeInterval = 0.0 +} + +/// ProxyApi delegate implementation for `IMAContentPlayhead`. +/// +/// This class may handle instantiating native object instances that are attached to a Dart +/// instance or handle method calls on the associated native class or an instance of that class. +class ContentPlayheadProxyAPIDelegate: PigeonApiDelegateIMAContentPlayhead { + func pigeonDefaultConstructor(pigeonApi: PigeonApiIMAContentPlayhead) throws -> IMAContentPlayhead + { + return ContentPlayheadImpl() + } + + // This is not an actual method on IMAContentPlayhead, but added so it can handle the sync callback. + func setCurrentTime( + pigeonApi: PigeonApiIMAContentPlayhead, pigeonInstance: IMAContentPlayhead, timeInterval: Double + ) throws { + (pigeonInstance as! ContentPlayheadImpl).currentTime = timeInterval + } +} diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/FlutterViewFactory.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/FlutterViewFactory.swift new file mode 100644 index 000000000000..857ac8a14f50 --- /dev/null +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/FlutterViewFactory.swift @@ -0,0 +1,45 @@ +// 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 Flutter +import Foundation + +/// Implementation of `FlutterPlatformViewFactory` that converts any `UIView` in a +/// `PigeonInstanceManager` to a `FlutterPlatformView`. +class FlutterViewFactory: NSObject, FlutterPlatformViewFactory { + unowned let instanceManager: InteractiveMediaAdsLibraryPigeonInstanceManager + + class PlatformViewImpl: NSObject, FlutterPlatformView { + let uiView: UIView + + init(uiView: UIView) { + self.uiView = uiView + } + + func view() -> UIView { + return uiView + } + } + + init(instanceManager: InteractiveMediaAdsLibraryPigeonInstanceManager) { + self.instanceManager = instanceManager + } + + func create(withFrame frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?) + -> FlutterPlatformView + { + let identifier: Int64 = args is Int64 ? args as! Int64 : Int64(args as! Int32) + let instance: AnyObject? = instanceManager.instance(forIdentifier: identifier) + + if let instance = instance as? FlutterPlatformView { + return instance + } else { + return PlatformViewImpl(uiView: instance as! UIView) + } + } + + func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol { + return FlutterStandardMessageCodec.sharedInstance() + } +} diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/FriendlyObstructionAPIDelegate.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/FriendlyObstructionAPIDelegate.swift new file mode 100644 index 000000000000..e03843bc2992 --- /dev/null +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/FriendlyObstructionAPIDelegate.swift @@ -0,0 +1,64 @@ +// 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 Foundation +import GoogleInteractiveMediaAds +import UIKit + +/// ProxyApi implementation for [IMAFriendlyObstruction]. +/// +/// This class may handle instantiating native object instances that are attached to a Dart instance +/// or handle method calls on the associated native class or an instance of that class. +class FriendlyObstructionProxyAPIDelegate: PigeonApiDelegateIMAFriendlyObstruction { + func pigeonDefaultConstructor( + pigeonApi: PigeonApiIMAFriendlyObstruction, view: UIView, purpose: FriendlyObstructionPurpose, + detailedReason: String? + ) throws -> IMAFriendlyObstruction { + var nativePurpose: IMAFriendlyObstructionPurpose + switch purpose { + case .mediaControls: + nativePurpose = IMAFriendlyObstructionPurpose.mediaControls + case .closeAd: + nativePurpose = IMAFriendlyObstructionPurpose.closeAd + case .notVisible: + nativePurpose = IMAFriendlyObstructionPurpose.notVisible + case .other: + nativePurpose = IMAFriendlyObstructionPurpose.other + case .unknown: + throw (pigeonApi.pigeonRegistrar.apiDelegate as! ProxyApiDelegate).createUnknownEnumError( + withEnum: purpose) + } + return IMAFriendlyObstruction( + view: view, purpose: nativePurpose, detailedReason: detailedReason) + } + + func view(pigeonApi: PigeonApiIMAFriendlyObstruction, pigeonInstance: IMAFriendlyObstruction) + throws -> UIView + { + return pigeonInstance.view + } + + func purpose(pigeonApi: PigeonApiIMAFriendlyObstruction, pigeonInstance: IMAFriendlyObstruction) + throws -> FriendlyObstructionPurpose + { + switch pigeonInstance.purpose { + case .mediaControls: + return .mediaControls + case .closeAd: + return .closeAd + case .notVisible: + return .notVisible + case .other: + return .other + @unknown default: + return .unknown + } + } + + func detailedReason( + pigeonApi: PigeonApiIMAFriendlyObstruction, pigeonInstance: IMAFriendlyObstruction + ) throws -> String? { + return pigeonInstance.detailedReason + } +} diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/InteractiveMediaAdsLibrary.g.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/InteractiveMediaAdsLibrary.g.swift new file mode 100644 index 000000000000..501b6ac923ff --- /dev/null +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/InteractiveMediaAdsLibrary.g.swift @@ -0,0 +1,3711 @@ +// 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 (v22.5.0), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +import Foundation +import GoogleInteractiveMediaAds +import UIKit + +#if os(iOS) + import Flutter +#elseif os(macOS) + import FlutterMacOS +#else + #error("Unsupported platform.") +#endif + +/// Error class for passing custom error details to Dart side. +final class PigeonError: Error { + let code: String + let message: String? + let details: Any? + + init(code: String, message: String?, details: Any?) { + self.code = code + self.message = message + self.details = details + } + + var localizedDescription: String { + return + "PigeonError(code: \(code), message: \(message ?? ""), details: \(details ?? "")" + } +} + +private func wrapResult(_ result: Any?) -> [Any?] { + return [result] +} + +private func wrapError(_ error: Any) -> [Any?] { + if let pigeonError = error as? PigeonError { + return [ + pigeonError.code, + pigeonError.message, + pigeonError.details, + ] + } + if let flutterError = error as? FlutterError { + return [ + flutterError.code, + flutterError.message, + flutterError.details, + ] + } + return [ + "\(error)", + "\(type(of: error))", + "Stacktrace: \(Thread.callStackSymbols)", + ] +} + +private func createConnectionError(withChannelName channelName: String) -> PigeonError { + return PigeonError( + code: "channel-error", message: "Unable to establish connection on channel: '\(channelName)'.", + details: "") +} + +private func isNullish(_ value: Any?) -> Bool { + return value is NSNull || value == nil +} + +private func nilOrValue(_ value: Any?) -> T? { + if value is NSNull { return nil } + return value as! T? +} +/// Handles the callback when an object is deallocated. +protocol InteractiveMediaAdsLibraryPigeonInternalFinalizerDelegate: AnyObject { + /// Invoked when the strong reference of an object is deallocated in an `InstanceManager`. + func onDeinit(identifier: Int64) +} + +// Attaches to an object to receive a callback when the object is deallocated. +internal final class InteractiveMediaAdsLibraryPigeonInternalFinalizer { + private static let associatedObjectKey = malloc(1)! + + private let identifier: Int64 + // Reference to the delegate is weak because the callback should be ignored if the + // `InstanceManager` is deallocated. + private weak var delegate: InteractiveMediaAdsLibraryPigeonInternalFinalizerDelegate? + + private init( + identifier: Int64, delegate: InteractiveMediaAdsLibraryPigeonInternalFinalizerDelegate + ) { + self.identifier = identifier + self.delegate = delegate + } + + internal static func attach( + to instance: AnyObject, identifier: Int64, + delegate: InteractiveMediaAdsLibraryPigeonInternalFinalizerDelegate + ) { + let finalizer = InteractiveMediaAdsLibraryPigeonInternalFinalizer( + identifier: identifier, delegate: delegate) + objc_setAssociatedObject(instance, associatedObjectKey, finalizer, .OBJC_ASSOCIATION_RETAIN) + } + + static func detach(from instance: AnyObject) { + objc_setAssociatedObject(instance, associatedObjectKey, nil, .OBJC_ASSOCIATION_ASSIGN) + } + + deinit { + delegate?.onDeinit(identifier: identifier) + } +} + +/// Maintains instances used to communicate with the corresponding objects in Dart. +/// +/// Objects stored in this container are represented by an object in Dart that is also stored in +/// an InstanceManager with the same identifier. +/// +/// When an instance is added with an identifier, either can be used to retrieve the other. +/// +/// Added instances are added as a weak reference and a strong reference. When the strong +/// reference is removed and the weak reference is deallocated,`InteractiveMediaAdsLibraryPigeonInternalFinalizerDelegate.onDeinit` +/// is called with the instance's identifier. However, if the strong reference is removed and then the identifier is +/// retrieved with the intention to pass the identifier to Dart (e.g. by calling `identifierWithStrongReference`), +/// the strong reference to the instance is re-added. The strong reference will then need to be removed manually +/// again. +/// +/// Accessing and inserting to an InstanceManager is thread safe. +final class InteractiveMediaAdsLibraryPigeonInstanceManager { + // Identifiers are locked to a specific range to avoid collisions with objects + // created simultaneously from Dart. + // Host uses identifiers >= 2^16 and Dart is expected to use values n where, + // 0 <= n < 2^16. + private static let minHostCreatedIdentifier: Int64 = 65536 + + private let lockQueue = DispatchQueue(label: "InteractiveMediaAdsLibraryPigeonInstanceManager") + private let identifiers: NSMapTable = NSMapTable( + keyOptions: [.weakMemory, .objectPointerPersonality], valueOptions: .strongMemory) + private let weakInstances: NSMapTable = NSMapTable( + keyOptions: .strongMemory, valueOptions: [.weakMemory, .objectPointerPersonality]) + private let strongInstances: NSMapTable = NSMapTable( + keyOptions: .strongMemory, valueOptions: [.strongMemory, .objectPointerPersonality]) + private let finalizerDelegate: InteractiveMediaAdsLibraryPigeonInternalFinalizerDelegate + private var nextIdentifier: Int64 = minHostCreatedIdentifier + + public init(finalizerDelegate: InteractiveMediaAdsLibraryPigeonInternalFinalizerDelegate) { + self.finalizerDelegate = finalizerDelegate + } + + /// Adds a new instance that was instantiated from Dart. + /// + /// The same instance can be added multiple times, but each identifier must be unique. This allows + /// two objects that are equivalent (e.g. conforms to `Equatable`) to both be added. + /// + /// - Parameters: + /// - instance: the instance to be stored + /// - identifier: the identifier to be paired with instance. This value must be >= 0 and unique + func addDartCreatedInstance(_ instance: AnyObject, withIdentifier identifier: Int64) { + lockQueue.async { + self.addInstance(instance, withIdentifier: identifier) + } + } + + /// Adds a new instance that was instantiated from the host platform. + /// + /// - Parameters: + /// - instance: the instance to be stored. This must be unique to all other added instances. + /// - Returns: the unique identifier (>= 0) stored with instance + func addHostCreatedInstance(_ instance: AnyObject) -> Int64 { + assert(!containsInstance(instance), "Instance of \(instance) has already been added.") + var identifier: Int64 = -1 + lockQueue.sync { + identifier = nextIdentifier + nextIdentifier += 1 + self.addInstance(instance, withIdentifier: identifier) + } + return identifier + } + + /// Removes `instanceIdentifier` and its associated strongly referenced instance, if present, from the manager. + /// + /// - Parameters: + /// - instanceIdentifier: the identifier paired to an instance. + /// - Returns: removed instance if the manager contains the given identifier, otherwise `nil` if + /// the manager doesn't contain the value + func removeInstance(withIdentifier instanceIdentifier: Int64) throws -> T? { + var instance: AnyObject? = nil + lockQueue.sync { + instance = strongInstances.object(forKey: NSNumber(value: instanceIdentifier)) + strongInstances.removeObject(forKey: NSNumber(value: instanceIdentifier)) + } + return instance as? T + } + + /// Retrieves the instance associated with identifier. + /// + /// - Parameters: + /// - instanceIdentifier: the identifier associated with an instance + /// - Returns: the instance associated with `instanceIdentifier` if the manager contains the value, otherwise + /// `nil` if the manager doesn't contain the value + func instance(forIdentifier instanceIdentifier: Int64) -> T? { + var instance: AnyObject? = nil + lockQueue.sync { + instance = weakInstances.object(forKey: NSNumber(value: instanceIdentifier)) + } + return instance as? T + } + + private func addInstance(_ instance: AnyObject, withIdentifier identifier: Int64) { + assert(identifier >= 0) + assert( + weakInstances.object(forKey: identifier as NSNumber) == nil, + "Identifier has already been added: \(identifier)") + identifiers.setObject(NSNumber(value: identifier), forKey: instance) + weakInstances.setObject(instance, forKey: NSNumber(value: identifier)) + strongInstances.setObject(instance, forKey: NSNumber(value: identifier)) + InteractiveMediaAdsLibraryPigeonInternalFinalizer.attach( + to: instance, identifier: identifier, delegate: finalizerDelegate) + } + + /// Retrieves the identifier paired with an instance. + /// + /// If the manager contains a strong reference to `instance`, it will return the identifier + /// associated with `instance`. If the manager contains only a weak reference to `instance`, a new + /// strong reference to `instance` will be added and will need to be removed again with `removeInstance`. + /// + /// If this method returns a nonnull identifier, this method also expects the Dart + /// `InteractiveMediaAdsLibraryPigeonInstanceManager` to have, or recreate, a weak reference to the Dart instance the + /// identifier is associated with. + /// + /// - Parameters: + /// - instance: an instance that may be stored in the manager + /// - Returns: the identifier associated with `instance` if the manager contains the value, otherwise + /// `nil` if the manager doesn't contain the value + func identifierWithStrongReference(forInstance instance: AnyObject) -> Int64? { + var identifier: Int64? = nil + lockQueue.sync { + if let existingIdentifier = identifiers.object(forKey: instance)?.int64Value { + strongInstances.setObject(instance, forKey: NSNumber(value: existingIdentifier)) + identifier = existingIdentifier + } + } + return identifier + } + + /// Whether this manager contains the given `instance`. + /// + /// - Parameters: + /// - instance: the instance whose presence in this manager is to be tested + /// - Returns: whether this manager contains the given `instance` + func containsInstance(_ instance: AnyObject) -> Bool { + var containsInstance = false + lockQueue.sync { + containsInstance = identifiers.object(forKey: instance) != nil + } + return containsInstance + } + + /// Removes all of the instances from this manager. + /// + /// The manager will be empty after this call returns. + func removeAllObjects() throws { + lockQueue.sync { + identifiers.removeAllObjects() + weakInstances.removeAllObjects() + strongInstances.removeAllObjects() + nextIdentifier = InteractiveMediaAdsLibraryPigeonInstanceManager.minHostCreatedIdentifier + } + } + + /// The number of instances stored as a strong reference. + /// + /// For debugging and testing purposes. + internal var strongInstanceCount: Int { + var count: Int = 0 + lockQueue.sync { + count = strongInstances.count + } + return count + } + + /// The number of instances stored as a weak reference. + /// + /// For debugging and testing purposes. NSMapTables that store keys or objects as weak + /// reference will be reclaimed non-deterministically. + internal var weakInstanceCount: Int { + var count: Int = 0 + lockQueue.sync { + count = weakInstances.count + } + return count + } +} + +private class InteractiveMediaAdsLibraryPigeonInstanceManagerApi { + /// The codec used for serializing messages. + var codec: FlutterStandardMessageCodec { InteractiveMediaAdsLibraryPigeonCodec.shared } + + /// Handles sending and receiving messages with Dart. + unowned let binaryMessenger: FlutterBinaryMessenger + + init(binaryMessenger: FlutterBinaryMessenger) { + self.binaryMessenger = binaryMessenger + } + + /// Sets up an instance of `InteractiveMediaAdsLibraryPigeonInstanceManagerApi` to handle messages through the `binaryMessenger`. + static func setUpMessageHandlers( + binaryMessenger: FlutterBinaryMessenger, + instanceManager: InteractiveMediaAdsLibraryPigeonInstanceManager? + ) { + let codec = InteractiveMediaAdsLibraryPigeonCodec.shared + let removeStrongReferenceChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.interactive_media_ads.PigeonInternalInstanceManager.removeStrongReference", + binaryMessenger: binaryMessenger, codec: codec) + if let instanceManager = instanceManager { + removeStrongReferenceChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let identifierArg = args[0] as! Int64 + do { + let _: AnyObject? = try instanceManager.removeInstance(withIdentifier: identifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + removeStrongReferenceChannel.setMessageHandler(nil) + } + let clearChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.PigeonInternalInstanceManager.clear", + binaryMessenger: binaryMessenger, codec: codec) + if let instanceManager = instanceManager { + clearChannel.setMessageHandler { _, reply in + do { + try instanceManager.removeAllObjects() + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + clearChannel.setMessageHandler(nil) + } + } + + /// Sends a message to the Dart `InstanceManager` to remove the strong reference of the instance associated with `identifier`. + func removeStrongReference( + identifier identifierArg: Int64, completion: @escaping (Result) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.PigeonInternalInstanceManager.removeStrongReference" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([identifierArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} +protocol InteractiveMediaAdsLibraryPigeonProxyApiDelegate { + /// An implementation of [PigeonApiIMAAdDisplayContainer] used to add a new Dart instance of + /// `IMAAdDisplayContainer` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiIMAAdDisplayContainer( + _ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + ) -> PigeonApiIMAAdDisplayContainer + /// An implementation of [PigeonApiUIView] used to add a new Dart instance of + /// `UIView` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiUIView(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiUIView + /// An implementation of [PigeonApiUIViewController] used to add a new Dart instance of + /// `UIViewController` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiUIViewController(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiUIViewController + /// An implementation of [PigeonApiIMAContentPlayhead] used to add a new Dart instance of + /// `IMAContentPlayhead` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiIMAContentPlayhead(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMAContentPlayhead + /// An implementation of [PigeonApiIMAAdsLoader] used to add a new Dart instance of + /// `IMAAdsLoader` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiIMAAdsLoader(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMAAdsLoader + /// An implementation of [PigeonApiIMASettings] used to add a new Dart instance of + /// `IMASettings` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiIMASettings(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMASettings + /// An implementation of [PigeonApiIMAAdsRequest] used to add a new Dart instance of + /// `IMAAdsRequest` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiIMAAdsRequest(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMAAdsRequest + /// An implementation of [PigeonApiIMAAdsLoaderDelegate] used to add a new Dart instance of + /// `IMAAdsLoaderDelegate` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiIMAAdsLoaderDelegate(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMAAdsLoaderDelegate + /// An implementation of [PigeonApiIMAAdsLoadedData] used to add a new Dart instance of + /// `IMAAdsLoadedData` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiIMAAdsLoadedData(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMAAdsLoadedData + /// An implementation of [PigeonApiIMAAdLoadingErrorData] used to add a new Dart instance of + /// `IMAAdLoadingErrorData` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiIMAAdLoadingErrorData( + _ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + ) -> PigeonApiIMAAdLoadingErrorData + /// An implementation of [PigeonApiIMAAdError] used to add a new Dart instance of + /// `IMAAdError` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiIMAAdError(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMAAdError + /// An implementation of [PigeonApiIMAAdsManager] used to add a new Dart instance of + /// `IMAAdsManager` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiIMAAdsManager(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMAAdsManager + /// An implementation of [PigeonApiIMAAdsManagerDelegate] used to add a new Dart instance of + /// `IMAAdsManagerDelegate` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiIMAAdsManagerDelegate( + _ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + ) -> PigeonApiIMAAdsManagerDelegate + /// An implementation of [PigeonApiIMAAdEvent] used to add a new Dart instance of + /// `IMAAdEvent` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiIMAAdEvent(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMAAdEvent + /// An implementation of [PigeonApiIMAAdsRenderingSettings] used to add a new Dart instance of + /// `IMAAdsRenderingSettings` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiIMAAdsRenderingSettings( + _ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + ) -> PigeonApiIMAAdsRenderingSettings + /// An implementation of [PigeonApiNSObject] used to add a new Dart instance of + /// `NSObject` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiNSObject(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiNSObject + /// An implementation of [PigeonApiIMAFriendlyObstruction] used to add a new Dart instance of + /// `IMAFriendlyObstruction` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiIMAFriendlyObstruction( + _ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + ) -> PigeonApiIMAFriendlyObstruction + /// An implementation of [PigeonApiIMACompanionAd] used to add a new Dart instance of + /// `IMACompanionAd` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiIMACompanionAd(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMACompanionAd + /// An implementation of [PigeonApiIMACompanionAdSlot] used to add a new Dart instance of + /// `IMACompanionAdSlot` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiIMACompanionAdSlot(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMACompanionAdSlot + /// An implementation of [PigeonApiIMACompanionDelegate] used to add a new Dart instance of + /// `IMACompanionDelegate` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiIMACompanionDelegate(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMACompanionDelegate +} + +extension InteractiveMediaAdsLibraryPigeonProxyApiDelegate { + func pigeonApiUIView(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiUIView + { + return PigeonApiUIView(pigeonRegistrar: registrar, delegate: PigeonApiDelegateUIView()) + } + func pigeonApiIMASettings(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMASettings + { + return PigeonApiIMASettings( + pigeonRegistrar: registrar, delegate: PigeonApiDelegateIMASettings()) + } + func pigeonApiNSObject(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiNSObject + { + return PigeonApiNSObject(pigeonRegistrar: registrar, delegate: PigeonApiDelegateNSObject()) + } +} + +open class InteractiveMediaAdsLibraryPigeonProxyApiRegistrar { + let binaryMessenger: FlutterBinaryMessenger + let apiDelegate: InteractiveMediaAdsLibraryPigeonProxyApiDelegate + let instanceManager: InteractiveMediaAdsLibraryPigeonInstanceManager + /// Whether APIs should ignore calling to Dart. + public var ignoreCallsToDart = false + private var _codec: FlutterStandardMessageCodec? + var codec: FlutterStandardMessageCodec { + if _codec == nil { + _codec = FlutterStandardMessageCodec( + readerWriter: InteractiveMediaAdsLibraryPigeonInternalProxyApiCodecReaderWriter( + pigeonRegistrar: self)) + } + return _codec! + } + + private class InstanceManagerApiFinalizerDelegate: + InteractiveMediaAdsLibraryPigeonInternalFinalizerDelegate + { + let api: InteractiveMediaAdsLibraryPigeonInstanceManagerApi + + init(_ api: InteractiveMediaAdsLibraryPigeonInstanceManagerApi) { + self.api = api + } + + public func onDeinit(identifier: Int64) { + api.removeStrongReference(identifier: identifier) { + _ in + } + } + } + + init( + binaryMessenger: FlutterBinaryMessenger, + apiDelegate: InteractiveMediaAdsLibraryPigeonProxyApiDelegate + ) { + self.binaryMessenger = binaryMessenger + self.apiDelegate = apiDelegate + self.instanceManager = InteractiveMediaAdsLibraryPigeonInstanceManager( + finalizerDelegate: InstanceManagerApiFinalizerDelegate( + InteractiveMediaAdsLibraryPigeonInstanceManagerApi(binaryMessenger: binaryMessenger))) + } + + func setUp() { + InteractiveMediaAdsLibraryPigeonInstanceManagerApi.setUpMessageHandlers( + binaryMessenger: binaryMessenger, instanceManager: instanceManager) + PigeonApiIMAAdDisplayContainer.setUpMessageHandlers( + binaryMessenger: binaryMessenger, api: apiDelegate.pigeonApiIMAAdDisplayContainer(self)) + PigeonApiUIViewController.setUpMessageHandlers( + binaryMessenger: binaryMessenger, api: apiDelegate.pigeonApiUIViewController(self)) + PigeonApiIMAContentPlayhead.setUpMessageHandlers( + binaryMessenger: binaryMessenger, api: apiDelegate.pigeonApiIMAContentPlayhead(self)) + PigeonApiIMAAdsLoader.setUpMessageHandlers( + binaryMessenger: binaryMessenger, api: apiDelegate.pigeonApiIMAAdsLoader(self)) + PigeonApiIMAAdsRequest.setUpMessageHandlers( + binaryMessenger: binaryMessenger, api: apiDelegate.pigeonApiIMAAdsRequest(self)) + PigeonApiIMAAdsLoaderDelegate.setUpMessageHandlers( + binaryMessenger: binaryMessenger, api: apiDelegate.pigeonApiIMAAdsLoaderDelegate(self)) + PigeonApiIMAAdsManager.setUpMessageHandlers( + binaryMessenger: binaryMessenger, api: apiDelegate.pigeonApiIMAAdsManager(self)) + PigeonApiIMAAdsManagerDelegate.setUpMessageHandlers( + binaryMessenger: binaryMessenger, api: apiDelegate.pigeonApiIMAAdsManagerDelegate(self)) + PigeonApiIMAAdsRenderingSettings.setUpMessageHandlers( + binaryMessenger: binaryMessenger, api: apiDelegate.pigeonApiIMAAdsRenderingSettings(self)) + PigeonApiIMAFriendlyObstruction.setUpMessageHandlers( + binaryMessenger: binaryMessenger, api: apiDelegate.pigeonApiIMAFriendlyObstruction(self)) + PigeonApiIMACompanionAdSlot.setUpMessageHandlers( + binaryMessenger: binaryMessenger, api: apiDelegate.pigeonApiIMACompanionAdSlot(self)) + PigeonApiIMACompanionDelegate.setUpMessageHandlers( + binaryMessenger: binaryMessenger, api: apiDelegate.pigeonApiIMACompanionDelegate(self)) + } + func tearDown() { + InteractiveMediaAdsLibraryPigeonInstanceManagerApi.setUpMessageHandlers( + binaryMessenger: binaryMessenger, instanceManager: nil) + PigeonApiIMAAdDisplayContainer.setUpMessageHandlers(binaryMessenger: binaryMessenger, api: nil) + PigeonApiUIViewController.setUpMessageHandlers(binaryMessenger: binaryMessenger, api: nil) + PigeonApiIMAContentPlayhead.setUpMessageHandlers(binaryMessenger: binaryMessenger, api: nil) + PigeonApiIMAAdsLoader.setUpMessageHandlers(binaryMessenger: binaryMessenger, api: nil) + PigeonApiIMAAdsRequest.setUpMessageHandlers(binaryMessenger: binaryMessenger, api: nil) + PigeonApiIMAAdsLoaderDelegate.setUpMessageHandlers(binaryMessenger: binaryMessenger, api: nil) + PigeonApiIMAAdsManager.setUpMessageHandlers(binaryMessenger: binaryMessenger, api: nil) + PigeonApiIMAAdsManagerDelegate.setUpMessageHandlers(binaryMessenger: binaryMessenger, api: nil) + PigeonApiIMAAdsRenderingSettings.setUpMessageHandlers( + binaryMessenger: binaryMessenger, api: nil) + PigeonApiIMAFriendlyObstruction.setUpMessageHandlers(binaryMessenger: binaryMessenger, api: nil) + PigeonApiIMACompanionAdSlot.setUpMessageHandlers(binaryMessenger: binaryMessenger, api: nil) + PigeonApiIMACompanionDelegate.setUpMessageHandlers(binaryMessenger: binaryMessenger, api: nil) + } +} +private class InteractiveMediaAdsLibraryPigeonInternalProxyApiCodecReaderWriter: + FlutterStandardReaderWriter +{ + unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + + private class InteractiveMediaAdsLibraryPigeonInternalProxyApiCodecReader: + InteractiveMediaAdsLibraryPigeonCodecReader + { + unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + + init(data: Data, pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) { + self.pigeonRegistrar = pigeonRegistrar + super.init(data: data) + } + + override func readValue(ofType type: UInt8) -> Any? { + switch type { + case 128: + let identifier = self.readValue() + let instance: AnyObject? = pigeonRegistrar.instanceManager.instance( + forIdentifier: identifier is Int64 ? identifier as! Int64 : Int64(identifier as! Int32)) + return instance + default: + return super.readValue(ofType: type) + } + } + } + + private class InteractiveMediaAdsLibraryPigeonInternalProxyApiCodecWriter: + InteractiveMediaAdsLibraryPigeonCodecWriter + { + unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + + init(data: NSMutableData, pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) { + self.pigeonRegistrar = pigeonRegistrar + super.init(data: data) + } + + override func writeValue(_ value: Any) { + if value is [Any] || value is Bool || value is Data || value is [AnyHashable: Any] + || value is Double || value is FlutterStandardTypedData || value is Int64 || value is String + || value is AdErrorType || value is AdErrorCode || value is AdEventType + || value is KeyValueObservingOptions || value is KeyValueChange + || value is KeyValueChangeKey || value is FriendlyObstructionPurpose + || value is UIElementType + { + super.writeValue(value) + return + } + + if let instance = value as? IMAAdDisplayContainer { + pigeonRegistrar.apiDelegate.pigeonApiIMAAdDisplayContainer(pigeonRegistrar) + .pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as? UIView { + pigeonRegistrar.apiDelegate.pigeonApiUIView(pigeonRegistrar).pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as? UIViewController { + pigeonRegistrar.apiDelegate.pigeonApiUIViewController(pigeonRegistrar).pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as? IMAContentPlayhead { + pigeonRegistrar.apiDelegate.pigeonApiIMAContentPlayhead(pigeonRegistrar).pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as? IMAAdsLoader { + pigeonRegistrar.apiDelegate.pigeonApiIMAAdsLoader(pigeonRegistrar).pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as? IMASettings { + pigeonRegistrar.apiDelegate.pigeonApiIMASettings(pigeonRegistrar).pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as? IMAAdsRequest { + pigeonRegistrar.apiDelegate.pigeonApiIMAAdsRequest(pigeonRegistrar).pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as? IMAAdsLoaderDelegate { + pigeonRegistrar.apiDelegate.pigeonApiIMAAdsLoaderDelegate(pigeonRegistrar) + .pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as? IMAAdsLoadedData { + pigeonRegistrar.apiDelegate.pigeonApiIMAAdsLoadedData(pigeonRegistrar).pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as? IMAAdLoadingErrorData { + pigeonRegistrar.apiDelegate.pigeonApiIMAAdLoadingErrorData(pigeonRegistrar) + .pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as? IMAAdError { + pigeonRegistrar.apiDelegate.pigeonApiIMAAdError(pigeonRegistrar).pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as? IMAAdsManager { + pigeonRegistrar.apiDelegate.pigeonApiIMAAdsManager(pigeonRegistrar).pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as? IMAAdsManagerDelegate { + pigeonRegistrar.apiDelegate.pigeonApiIMAAdsManagerDelegate(pigeonRegistrar) + .pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as? IMAAdEvent { + pigeonRegistrar.apiDelegate.pigeonApiIMAAdEvent(pigeonRegistrar).pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as? IMAAdsRenderingSettings { + pigeonRegistrar.apiDelegate.pigeonApiIMAAdsRenderingSettings(pigeonRegistrar) + .pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as? IMAFriendlyObstruction { + pigeonRegistrar.apiDelegate.pigeonApiIMAFriendlyObstruction(pigeonRegistrar) + .pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as? IMACompanionAd { + pigeonRegistrar.apiDelegate.pigeonApiIMACompanionAd(pigeonRegistrar).pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as? IMACompanionAdSlot { + pigeonRegistrar.apiDelegate.pigeonApiIMACompanionAdSlot(pigeonRegistrar).pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as? IMACompanionDelegate { + pigeonRegistrar.apiDelegate.pigeonApiIMACompanionDelegate(pigeonRegistrar) + .pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as? NSObject { + pigeonRegistrar.apiDelegate.pigeonApiNSObject(pigeonRegistrar).pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as AnyObject?, + pigeonRegistrar.instanceManager.containsInstance(instance) + { + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference(forInstance: instance)!) + } else { + print("Unsupported value: \(value) of \(type(of: value))") + assert( + false, "Unsupported value for InteractiveMediaAdsLibraryPigeonInternalProxyApiCodecWriter" + ) + } + + } + } + + init(pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) { + self.pigeonRegistrar = pigeonRegistrar + } + + override func reader(with data: Data) -> FlutterStandardReader { + return InteractiveMediaAdsLibraryPigeonInternalProxyApiCodecReader( + data: data, pigeonRegistrar: pigeonRegistrar) + } + + override func writer(with data: NSMutableData) -> FlutterStandardWriter { + return InteractiveMediaAdsLibraryPigeonInternalProxyApiCodecWriter( + data: data, pigeonRegistrar: pigeonRegistrar) + } +} + +/// Possible error types while loading or playing ads. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Enums/IMAErrorType.html. +enum AdErrorType: Int { + /// An error occurred while loading the ads. + case loadingFailed = 0 + /// An error occurred while playing the ads. + case adPlayingFailed = 1 + /// An unexpected error occurred while loading or playing the ads. + /// + /// This may mean that the SDK wasn’t loaded properly or the wrapper doesn't + /// recognize this value. + case unknown = 2 +} + +/// Possible error codes raised while loading or playing ads. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Enums/IMAErrorCode.html. +enum AdErrorCode: Int { + /// The ad slot is not visible on the page. + case adslotNotVisible = 0 + /// Generic invalid usage of the API. + case apiError = 1 + /// A companion ad failed to load or render. + case companionAdLoadingFailed = 2 + /// Content playhead was not passed in, but list of ads has been returned from + /// the server. + case contentPlayheadMissing = 3 + /// There was an error loading the ad. + case failedLoadingAd = 4 + /// There was a problem requesting ads from the server. + case failedToRequestAds = 5 + /// Invalid arguments were provided to SDK methods. + case invalidArguments = 6 + /// The version of the runtime is too old. + case osRuntimeTooOld = 7 + /// Ads list response was malformed. + case playlistMalformedResponse = 8 + /// Listener for at least one of the required vast events was not added. + case requiredListenersNotAdded = 9 + /// There was an error initializing the stream. + case streamInitializationFailed = 10 + /// An unexpected error occurred and the cause is not known. + case unknownError = 11 + /// No assets were found in the VAST ad response. + case vastAssetNotFound = 12 + /// A VAST response containing a single `` tag with no child tags. + case vastEmptyResponse = 13 + /// At least one VAST wrapper loaded and a subsequent wrapper or inline ad + /// load has resulted in a 404 response code. + case vastInvalidUrl = 14 + /// Assets were found in the VAST ad response for a linear ad, but none of + /// them matched the video player's capabilities. + case vastLinearAssetMismatch = 15 + /// The VAST URI provided, or a VAST URI provided in a subsequent Wrapper + /// element, was either unavailable or reached a timeout, as defined by the + /// video player. + case vastLoadTimeout = 16 + /// The ad response was not recognized as a valid VAST ad. + case vastMalformedResponse = 17 + /// Failed to load media assets from a VAST response. + case vastMediaLoadTimeout = 18 + /// The maximum number of VAST wrapper redirects has been reached. + case vastTooManyRedirects = 19 + /// Trafficking error. + /// + /// Video player received an ad type that it was not expecting and/or cannot + /// display. + case vastTraffickingError = 20 + /// Another VideoAdsManager is still using the video. + case videoElementUsed = 21 + /// A video element was not specified where it was required. + case videoElementRequired = 22 + /// There was an error playing the video ad. + case videoPlayError = 23 +} + +/// Different event types sent by the IMAAdsManager to its delegate. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Enums/IMAAdEventType.html. +enum AdEventType: Int { + /// Fired the first time each ad break ends. + case adBreakEnded = 0 + /// Fired when an ad break will not play back any ads. + case adBreakFetchError = 1 + /// Fired when an ad break is ready. + case adBreakReady = 2 + /// Fired first time each ad break begins playback. + case adBreakStarted = 3 + /// Fired every time the stream switches from advertising or slate to content. + case adPeriodEnded = 4 + /// Fired every time the stream switches from content to advertising or slate. + case adPeriodStarted = 5 + /// All valid ads managed by the ads manager have completed or the ad response + /// did not return any valid ads. + case allAdsCompleted = 6 + /// Fired when an ad is clicked. + case clicked = 7 + /// Single ad has finished. + case completed = 8 + /// Cuepoints changed for VOD stream (only used for dynamic ad insertion). + case cuepointsChanged = 9 + /// First quartile of a linear ad was reached. + case firstQuartile = 10 + /// The user has closed the icon fallback image dialog. + case iconFallbackImageClosed = 11 + /// The user has tapped an ad icon. + case iconTapped = 12 + /// An ad was loaded. + case loaded = 13 + /// A log event for the ads being played. + case log = 14 + /// Midpoint of a linear ad was reached. + case midpoint = 15 + /// Ad paused. + case pause = 16 + /// Ad resumed. + case resume = 17 + /// Fired when an ad was skipped. + case skipped = 18 + /// Fired when an ad starts playing. + case started = 19 + /// Stream request has loaded (only used for dynamic ad insertion). + case streamLoaded = 20 + /// Stream has started playing (only used for dynamic ad insertion). + case streamStarted = 21 + /// Ad tapped. + case tapped = 22 + /// Third quartile of a linear ad was reached.. + case thirdQuartile = 23 + /// The event type is not recognized by this wrapper. + case unknown = 24 +} + +/// The values that can be returned in a change dictionary. +/// +/// See https://developer.apple.com/documentation/foundation/nskeyvalueobservingoptions?language=objc. +enum KeyValueObservingOptions: Int { + /// Indicates that the change dictionary should provide the new attribute + /// value, if applicable. + case newValue = 0 + /// Indicates that the change dictionary should contain the old attribute + /// value, if applicable. + case oldValue = 1 + /// If specified, a notification should be sent to the observer immediately, + /// before the observer registration method even returns. + case initialValue = 2 + /// Whether separate notifications should be sent to the observer before and + /// after each change, instead of a single notification after the change. + case priorNotification = 3 +} + +/// The kinds of changes that can be observed.. +/// +/// See https://developer.apple.com/documentation/foundation/nskeyvaluechange?language=objc. +enum KeyValueChange: Int { + /// Indicates that the value of the observed key path was set to a new value. + case setting = 0 + /// Indicates that an object has been inserted into the to-many relationship + /// that is being observed. + case insertion = 1 + /// Indicates that an object has been removed from the to-many relationship + /// that is being observed. + case removal = 2 + /// Indicates that an object has been replaced in the to-many relationship + /// that is being observed. + case replacement = 3 +} + +/// The keys that can appear in the change dictionary.. +/// +/// See https://developer.apple.com/documentation/foundation/nskeyvaluechangekey?language=objc. +enum KeyValueChangeKey: Int { + /// If the value of the kindKey entry is NSKeyValueChange.insertion, + /// NSKeyValueChange.removal, or NSKeyValueChange.replacement, the value of + /// this key is an NSIndexSet object that contains the indexes of the + /// inserted, removed, or replaced objects. + case indexes = 0 + /// An NSNumber object that contains a value corresponding to one of the + /// NSKeyValueChange enums, indicating what sort of change has occurred. + case kind = 1 + /// If the value of the kindKey entry is NSKeyValueChange.setting, and new was + /// specified when the observer was registered, the value of this key is the + /// new value for the attribute. + case newValue = 2 + /// If the prior option was specified when the observer was registered this + /// notification is sent prior to a change. + case notificationIsPrior = 3 + /// If the value of the kindKey entry is NSKeyValueChange.setting, and old was + /// specified when the observer was registered, the value of this key is the + /// value before the attribute was changed. + case oldValue = 4 + /// The key is not recognized by this wrapper. + case unknown = 5 +} + +/// A list of purposes for which an obstruction would be registered as friendly. +/// +/// See https://developers.google.com/ad-manager/dynamic-ad-insertion/sdk/ios/reference/Enums/IMAFriendlyObstructionPurpose.html. +enum FriendlyObstructionPurpose: Int { + case mediaControls = 0 + case closeAd = 1 + case notVisible = 2 + case other = 3 + /// The purpose type is not recognized by this wrapper. + case unknown = 4 +} + +/// Different UI elements that can be customized. +/// +/// See https://developers.google.com/ad-manager/dynamic-ad-insertion/sdk/ios/reference/Enums/IMAUiElementType.html. +enum UIElementType: Int { + /// Ad attribution UI element. + case adAttribution = 0 + /// Ad countdown element. + case countdown = 1 + /// The element is not recognized by this wrapper. + case unknown = 2 +} + +private class InteractiveMediaAdsLibraryPigeonCodecReader: FlutterStandardReader { + override func readValue(ofType type: UInt8) -> Any? { + switch type { + case 129: + let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?) + if let enumResultAsInt = enumResultAsInt { + return AdErrorType(rawValue: enumResultAsInt) + } + return nil + case 130: + let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?) + if let enumResultAsInt = enumResultAsInt { + return AdErrorCode(rawValue: enumResultAsInt) + } + return nil + case 131: + let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?) + if let enumResultAsInt = enumResultAsInt { + return AdEventType(rawValue: enumResultAsInt) + } + return nil + case 132: + let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?) + if let enumResultAsInt = enumResultAsInt { + return KeyValueObservingOptions(rawValue: enumResultAsInt) + } + return nil + case 133: + let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?) + if let enumResultAsInt = enumResultAsInt { + return KeyValueChange(rawValue: enumResultAsInt) + } + return nil + case 134: + let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?) + if let enumResultAsInt = enumResultAsInt { + return KeyValueChangeKey(rawValue: enumResultAsInt) + } + return nil + case 135: + let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?) + if let enumResultAsInt = enumResultAsInt { + return FriendlyObstructionPurpose(rawValue: enumResultAsInt) + } + return nil + case 136: + let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?) + if let enumResultAsInt = enumResultAsInt { + return UIElementType(rawValue: enumResultAsInt) + } + return nil + default: + return super.readValue(ofType: type) + } + } +} + +private class InteractiveMediaAdsLibraryPigeonCodecWriter: FlutterStandardWriter { + override func writeValue(_ value: Any) { + if let value = value as? AdErrorType { + super.writeByte(129) + super.writeValue(value.rawValue) + } else if let value = value as? AdErrorCode { + super.writeByte(130) + super.writeValue(value.rawValue) + } else if let value = value as? AdEventType { + super.writeByte(131) + super.writeValue(value.rawValue) + } else if let value = value as? KeyValueObservingOptions { + super.writeByte(132) + super.writeValue(value.rawValue) + } else if let value = value as? KeyValueChange { + super.writeByte(133) + super.writeValue(value.rawValue) + } else if let value = value as? KeyValueChangeKey { + super.writeByte(134) + super.writeValue(value.rawValue) + } else if let value = value as? FriendlyObstructionPurpose { + super.writeByte(135) + super.writeValue(value.rawValue) + } else if let value = value as? UIElementType { + super.writeByte(136) + super.writeValue(value.rawValue) + } else { + super.writeValue(value) + } + } +} + +private class InteractiveMediaAdsLibraryPigeonCodecReaderWriter: FlutterStandardReaderWriter { + override func reader(with data: Data) -> FlutterStandardReader { + return InteractiveMediaAdsLibraryPigeonCodecReader(data: data) + } + + override func writer(with data: NSMutableData) -> FlutterStandardWriter { + return InteractiveMediaAdsLibraryPigeonCodecWriter(data: data) + } +} + +class InteractiveMediaAdsLibraryPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable { + static let shared = InteractiveMediaAdsLibraryPigeonCodec( + readerWriter: InteractiveMediaAdsLibraryPigeonCodecReaderWriter()) +} + +protocol PigeonApiDelegateIMAAdDisplayContainer { + func pigeonDefaultConstructor( + pigeonApi: PigeonApiIMAAdDisplayContainer, adContainer: UIView, + adContainerViewController: UIViewController? + ) throws -> IMAAdDisplayContainer +} + +protocol PigeonApiProtocolIMAAdDisplayContainer { +} + +final class PigeonApiIMAAdDisplayContainer: PigeonApiProtocolIMAAdDisplayContainer { + unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateIMAAdDisplayContainer + ///An implementation of [NSObject] used to access callback methods + var pigeonApiNSObject: PigeonApiNSObject { + return pigeonRegistrar.apiDelegate.pigeonApiNSObject(pigeonRegistrar) + } + + init( + pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateIMAAdDisplayContainer + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + static func setUpMessageHandlers( + binaryMessenger: FlutterBinaryMessenger, api: PigeonApiIMAAdDisplayContainer? + ) { + let codec: FlutterStandardMessageCodec = + api != nil + ? FlutterStandardMessageCodec( + readerWriter: InteractiveMediaAdsLibraryPigeonInternalProxyApiCodecReaderWriter( + pigeonRegistrar: api!.pigeonRegistrar)) + : FlutterStandardMessageCodec.sharedInstance() + let pigeonDefaultConstructorChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.interactive_media_ads.IMAAdDisplayContainer.pigeon_defaultConstructor", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + pigeonDefaultConstructorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonIdentifierArg = args[0] as! Int64 + let adContainerArg = args[1] as! UIView + let adContainerViewControllerArg: UIViewController? = nilOrValue(args[2]) + do { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + try api.pigeonDelegate.pigeonDefaultConstructor( + pigeonApi: api, adContainer: adContainerArg, + adContainerViewController: adContainerViewControllerArg), + withIdentifier: pigeonIdentifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + pigeonDefaultConstructorChannel.setMessageHandler(nil) + } + } + + ///Creates a Dart instance of IMAAdDisplayContainer and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: IMAAdDisplayContainer, completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.IMAAdDisplayContainer.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonIdentifierArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} +open class PigeonApiDelegateUIView { +} + +protocol PigeonApiProtocolUIView { +} + +final class PigeonApiUIView: PigeonApiProtocolUIView { + unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateUIView + ///An implementation of [NSObject] used to access callback methods + var pigeonApiNSObject: PigeonApiNSObject { + return pigeonRegistrar.apiDelegate.pigeonApiNSObject(pigeonRegistrar) + } + + init( + pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateUIView + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + ///Creates a Dart instance of UIView and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: UIView, completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = "dev.flutter.pigeon.interactive_media_ads.UIView.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonIdentifierArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} +protocol PigeonApiDelegateUIViewController { + func pigeonDefaultConstructor(pigeonApi: PigeonApiUIViewController) throws -> UIViewController + /// Retrieves the view that the controller manages. + /// + /// For convenience this is a `final` attached field despite this being + /// settable. Since this is not a part of the IMA SDK this is slightly changed + /// for convenience. Note that this wrapper should not add the ability to set + /// this property as it should not be needed anyways. + func view(pigeonApi: PigeonApiUIViewController, pigeonInstance: UIViewController) throws -> UIView +} + +protocol PigeonApiProtocolUIViewController { + /// Notifies the view controller that its view was added to a view hierarchy. + func viewDidAppear( + pigeonInstance pigeonInstanceArg: UIViewController, animated animatedArg: Bool, + completion: @escaping (Result) -> Void) +} + +final class PigeonApiUIViewController: PigeonApiProtocolUIViewController { + unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateUIViewController + ///An implementation of [NSObject] used to access callback methods + var pigeonApiNSObject: PigeonApiNSObject { + return pigeonRegistrar.apiDelegate.pigeonApiNSObject(pigeonRegistrar) + } + + init( + pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateUIViewController + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + static func setUpMessageHandlers( + binaryMessenger: FlutterBinaryMessenger, api: PigeonApiUIViewController? + ) { + let codec: FlutterStandardMessageCodec = + api != nil + ? FlutterStandardMessageCodec( + readerWriter: InteractiveMediaAdsLibraryPigeonInternalProxyApiCodecReaderWriter( + pigeonRegistrar: api!.pigeonRegistrar)) + : FlutterStandardMessageCodec.sharedInstance() + let pigeonDefaultConstructorChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.UIViewController.pigeon_defaultConstructor", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + pigeonDefaultConstructorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonIdentifierArg = args[0] as! Int64 + do { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + try api.pigeonDelegate.pigeonDefaultConstructor(pigeonApi: api), + withIdentifier: pigeonIdentifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + pigeonDefaultConstructorChannel.setMessageHandler(nil) + } + let viewChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.UIViewController.view", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + viewChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! UIViewController + let pigeonIdentifierArg = args[1] as! Int64 + do { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + try api.pigeonDelegate.view(pigeonApi: api, pigeonInstance: pigeonInstanceArg), + withIdentifier: pigeonIdentifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + viewChannel.setMessageHandler(nil) + } + } + + ///Creates a Dart instance of UIViewController and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: UIViewController, completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.UIViewController.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonIdentifierArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + /// Notifies the view controller that its view was added to a view hierarchy. + func viewDidAppear( + pigeonInstance pigeonInstanceArg: UIViewController, animated animatedArg: Bool, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.UIViewController.viewDidAppear" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, animatedArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + +} +protocol PigeonApiDelegateIMAContentPlayhead { + func pigeonDefaultConstructor(pigeonApi: PigeonApiIMAContentPlayhead) throws -> IMAContentPlayhead + /// Reflects the current playback time in seconds for the content. + func setCurrentTime( + pigeonApi: PigeonApiIMAContentPlayhead, pigeonInstance: IMAContentPlayhead, timeInterval: Double + ) throws +} + +protocol PigeonApiProtocolIMAContentPlayhead { +} + +final class PigeonApiIMAContentPlayhead: PigeonApiProtocolIMAContentPlayhead { + unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateIMAContentPlayhead + ///An implementation of [NSObject] used to access callback methods + var pigeonApiNSObject: PigeonApiNSObject { + return pigeonRegistrar.apiDelegate.pigeonApiNSObject(pigeonRegistrar) + } + + init( + pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateIMAContentPlayhead + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + static func setUpMessageHandlers( + binaryMessenger: FlutterBinaryMessenger, api: PigeonApiIMAContentPlayhead? + ) { + let codec: FlutterStandardMessageCodec = + api != nil + ? FlutterStandardMessageCodec( + readerWriter: InteractiveMediaAdsLibraryPigeonInternalProxyApiCodecReaderWriter( + pigeonRegistrar: api!.pigeonRegistrar)) + : FlutterStandardMessageCodec.sharedInstance() + let pigeonDefaultConstructorChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.IMAContentPlayhead.pigeon_defaultConstructor", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + pigeonDefaultConstructorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonIdentifierArg = args[0] as! Int64 + do { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + try api.pigeonDelegate.pigeonDefaultConstructor(pigeonApi: api), + withIdentifier: pigeonIdentifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + pigeonDefaultConstructorChannel.setMessageHandler(nil) + } + let setCurrentTimeChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.IMAContentPlayhead.setCurrentTime", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + setCurrentTimeChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! IMAContentPlayhead + let timeIntervalArg = args[1] as! Double + do { + try api.pigeonDelegate.setCurrentTime( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, timeInterval: timeIntervalArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + setCurrentTimeChannel.setMessageHandler(nil) + } + } + + ///Creates a Dart instance of IMAContentPlayhead and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: IMAContentPlayhead, completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.IMAContentPlayhead.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonIdentifierArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} +protocol PigeonApiDelegateIMAAdsLoader { + func pigeonDefaultConstructor(pigeonApi: PigeonApiIMAAdsLoader, settings: IMASettings?) throws + -> IMAAdsLoader + /// Signal to the SDK that the content has completed. + func contentComplete(pigeonApi: PigeonApiIMAAdsLoader, pigeonInstance: IMAAdsLoader) throws + /// Request ads from the ad server. + func requestAds( + pigeonApi: PigeonApiIMAAdsLoader, pigeonInstance: IMAAdsLoader, request: IMAAdsRequest) throws + /// Delegate that receives `IMAAdsLoaderDelegate` callbacks. + /// + /// Note that this sets to a `weak` property in Swift. + func setDelegate( + pigeonApi: PigeonApiIMAAdsLoader, pigeonInstance: IMAAdsLoader, delegate: IMAAdsLoaderDelegate?) + throws +} + +protocol PigeonApiProtocolIMAAdsLoader { +} + +final class PigeonApiIMAAdsLoader: PigeonApiProtocolIMAAdsLoader { + unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateIMAAdsLoader + ///An implementation of [NSObject] used to access callback methods + var pigeonApiNSObject: PigeonApiNSObject { + return pigeonRegistrar.apiDelegate.pigeonApiNSObject(pigeonRegistrar) + } + + init( + pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateIMAAdsLoader + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + static func setUpMessageHandlers( + binaryMessenger: FlutterBinaryMessenger, api: PigeonApiIMAAdsLoader? + ) { + let codec: FlutterStandardMessageCodec = + api != nil + ? FlutterStandardMessageCodec( + readerWriter: InteractiveMediaAdsLibraryPigeonInternalProxyApiCodecReaderWriter( + pigeonRegistrar: api!.pigeonRegistrar)) + : FlutterStandardMessageCodec.sharedInstance() + let pigeonDefaultConstructorChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.IMAAdsLoader.pigeon_defaultConstructor", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + pigeonDefaultConstructorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonIdentifierArg = args[0] as! Int64 + let settingsArg: IMASettings? = nilOrValue(args[1]) + do { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + try api.pigeonDelegate.pigeonDefaultConstructor(pigeonApi: api, settings: settingsArg), + withIdentifier: pigeonIdentifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + pigeonDefaultConstructorChannel.setMessageHandler(nil) + } + let contentCompleteChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.IMAAdsLoader.contentComplete", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + contentCompleteChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! IMAAdsLoader + do { + try api.pigeonDelegate.contentComplete(pigeonApi: api, pigeonInstance: pigeonInstanceArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + contentCompleteChannel.setMessageHandler(nil) + } + let requestAdsChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.IMAAdsLoader.requestAds", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + requestAdsChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! IMAAdsLoader + let requestArg = args[1] as! IMAAdsRequest + do { + try api.pigeonDelegate.requestAds( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, request: requestArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + requestAdsChannel.setMessageHandler(nil) + } + let setDelegateChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.IMAAdsLoader.setDelegate", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + setDelegateChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! IMAAdsLoader + let delegateArg: IMAAdsLoaderDelegate? = nilOrValue(args[1]) + do { + try api.pigeonDelegate.setDelegate( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, delegate: delegateArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + setDelegateChannel.setMessageHandler(nil) + } + } + + ///Creates a Dart instance of IMAAdsLoader and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: IMAAdsLoader, completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.IMAAdsLoader.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonIdentifierArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} +open class PigeonApiDelegateIMASettings { +} + +protocol PigeonApiProtocolIMASettings { +} + +final class PigeonApiIMASettings: PigeonApiProtocolIMASettings { + unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateIMASettings + ///An implementation of [NSObject] used to access callback methods + var pigeonApiNSObject: PigeonApiNSObject { + return pigeonRegistrar.apiDelegate.pigeonApiNSObject(pigeonRegistrar) + } + + init( + pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateIMASettings + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + ///Creates a Dart instance of IMASettings and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: IMASettings, completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.IMASettings.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonIdentifierArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} +protocol PigeonApiDelegateIMAAdsRequest { + /// Initializes an ads request instance with the given ad tag URL and ad + /// display container. + func pigeonDefaultConstructor( + pigeonApi: PigeonApiIMAAdsRequest, adTagUrl: String, adDisplayContainer: IMAAdDisplayContainer, + contentPlayhead: IMAContentPlayhead? + ) throws -> IMAAdsRequest +} + +protocol PigeonApiProtocolIMAAdsRequest { +} + +final class PigeonApiIMAAdsRequest: PigeonApiProtocolIMAAdsRequest { + unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateIMAAdsRequest + ///An implementation of [NSObject] used to access callback methods + var pigeonApiNSObject: PigeonApiNSObject { + return pigeonRegistrar.apiDelegate.pigeonApiNSObject(pigeonRegistrar) + } + + init( + pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateIMAAdsRequest + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + static func setUpMessageHandlers( + binaryMessenger: FlutterBinaryMessenger, api: PigeonApiIMAAdsRequest? + ) { + let codec: FlutterStandardMessageCodec = + api != nil + ? FlutterStandardMessageCodec( + readerWriter: InteractiveMediaAdsLibraryPigeonInternalProxyApiCodecReaderWriter( + pigeonRegistrar: api!.pigeonRegistrar)) + : FlutterStandardMessageCodec.sharedInstance() + let pigeonDefaultConstructorChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.IMAAdsRequest.pigeon_defaultConstructor", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + pigeonDefaultConstructorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonIdentifierArg = args[0] as! Int64 + let adTagUrlArg = args[1] as! String + let adDisplayContainerArg = args[2] as! IMAAdDisplayContainer + let contentPlayheadArg: IMAContentPlayhead? = nilOrValue(args[3]) + do { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + try api.pigeonDelegate.pigeonDefaultConstructor( + pigeonApi: api, adTagUrl: adTagUrlArg, adDisplayContainer: adDisplayContainerArg, + contentPlayhead: contentPlayheadArg), + withIdentifier: pigeonIdentifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + pigeonDefaultConstructorChannel.setMessageHandler(nil) + } + } + + ///Creates a Dart instance of IMAAdsRequest and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: IMAAdsRequest, completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.IMAAdsRequest.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonIdentifierArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} +protocol PigeonApiDelegateIMAAdsLoaderDelegate { + func pigeonDefaultConstructor(pigeonApi: PigeonApiIMAAdsLoaderDelegate) throws + -> IMAAdsLoaderDelegate +} + +protocol PigeonApiProtocolIMAAdsLoaderDelegate { + /// Called when ads are successfully loaded from the ad servers by the loader. + func adLoaderLoadedWith( + pigeonInstance pigeonInstanceArg: IMAAdsLoaderDelegate, loader loaderArg: IMAAdsLoader, + adsLoadedData adsLoadedDataArg: IMAAdsLoadedData, + completion: @escaping (Result) -> Void) + /// Error reported by the ads loader when loading or requesting an ad fails. + func adsLoaderFailedWithErrorData( + pigeonInstance pigeonInstanceArg: IMAAdsLoaderDelegate, loader loaderArg: IMAAdsLoader, + adErrorData adErrorDataArg: IMAAdLoadingErrorData, + completion: @escaping (Result) -> Void) +} + +final class PigeonApiIMAAdsLoaderDelegate: PigeonApiProtocolIMAAdsLoaderDelegate { + unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateIMAAdsLoaderDelegate + ///An implementation of [NSObject] used to access callback methods + var pigeonApiNSObject: PigeonApiNSObject { + return pigeonRegistrar.apiDelegate.pigeonApiNSObject(pigeonRegistrar) + } + + init( + pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateIMAAdsLoaderDelegate + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + static func setUpMessageHandlers( + binaryMessenger: FlutterBinaryMessenger, api: PigeonApiIMAAdsLoaderDelegate? + ) { + let codec: FlutterStandardMessageCodec = + api != nil + ? FlutterStandardMessageCodec( + readerWriter: InteractiveMediaAdsLibraryPigeonInternalProxyApiCodecReaderWriter( + pigeonRegistrar: api!.pigeonRegistrar)) + : FlutterStandardMessageCodec.sharedInstance() + let pigeonDefaultConstructorChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.interactive_media_ads.IMAAdsLoaderDelegate.pigeon_defaultConstructor", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + pigeonDefaultConstructorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonIdentifierArg = args[0] as! Int64 + do { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + try api.pigeonDelegate.pigeonDefaultConstructor(pigeonApi: api), + withIdentifier: pigeonIdentifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + pigeonDefaultConstructorChannel.setMessageHandler(nil) + } + } + + ///Creates a Dart instance of IMAAdsLoaderDelegate and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: IMAAdsLoaderDelegate, completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + print( + "Error: Attempting to create a new Dart instance of IMAAdsLoaderDelegate, but the class has a nonnull callback method." + ) + } + /// Called when ads are successfully loaded from the ad servers by the loader. + func adLoaderLoadedWith( + pigeonInstance pigeonInstanceArg: IMAAdsLoaderDelegate, loader loaderArg: IMAAdsLoader, + adsLoadedData adsLoadedDataArg: IMAAdsLoadedData, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.IMAAdsLoaderDelegate.adLoaderLoadedWith" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, loaderArg, adsLoadedDataArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + + /// Error reported by the ads loader when loading or requesting an ad fails. + func adsLoaderFailedWithErrorData( + pigeonInstance pigeonInstanceArg: IMAAdsLoaderDelegate, loader loaderArg: IMAAdsLoader, + adErrorData adErrorDataArg: IMAAdLoadingErrorData, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.IMAAdsLoaderDelegate.adsLoaderFailedWithErrorData" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, loaderArg, adErrorDataArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + +} +protocol PigeonApiDelegateIMAAdsLoadedData { + /// The ads manager instance created by the ads loader. + /// + /// Will be null when using dynamic ad insertion. + func adsManager(pigeonApi: PigeonApiIMAAdsLoadedData, pigeonInstance: IMAAdsLoadedData) throws + -> IMAAdsManager? +} + +protocol PigeonApiProtocolIMAAdsLoadedData { +} + +final class PigeonApiIMAAdsLoadedData: PigeonApiProtocolIMAAdsLoadedData { + unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateIMAAdsLoadedData + ///An implementation of [NSObject] used to access callback methods + var pigeonApiNSObject: PigeonApiNSObject { + return pigeonRegistrar.apiDelegate.pigeonApiNSObject(pigeonRegistrar) + } + + init( + pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateIMAAdsLoadedData + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + ///Creates a Dart instance of IMAAdsLoadedData and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: IMAAdsLoadedData, completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let adsManagerArg = try! pigeonDelegate.adsManager( + pigeonApi: self, pigeonInstance: pigeonInstance) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.IMAAdsLoadedData.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonIdentifierArg, adsManagerArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} +protocol PigeonApiDelegateIMAAdLoadingErrorData { + /// The ad error that occurred while loading the ad. + func adError(pigeonApi: PigeonApiIMAAdLoadingErrorData, pigeonInstance: IMAAdLoadingErrorData) + throws -> IMAAdError +} + +protocol PigeonApiProtocolIMAAdLoadingErrorData { +} + +final class PigeonApiIMAAdLoadingErrorData: PigeonApiProtocolIMAAdLoadingErrorData { + unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateIMAAdLoadingErrorData + ///An implementation of [NSObject] used to access callback methods + var pigeonApiNSObject: PigeonApiNSObject { + return pigeonRegistrar.apiDelegate.pigeonApiNSObject(pigeonRegistrar) + } + + init( + pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateIMAAdLoadingErrorData + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + ///Creates a Dart instance of IMAAdLoadingErrorData and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: IMAAdLoadingErrorData, completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let adErrorArg = try! pigeonDelegate.adError(pigeonApi: self, pigeonInstance: pigeonInstance) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.IMAAdLoadingErrorData.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonIdentifierArg, adErrorArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} +protocol PigeonApiDelegateIMAAdError { + /// The type of error that occurred during ad loading or ad playing. + func type(pigeonApi: PigeonApiIMAAdError, pigeonInstance: IMAAdError) throws -> AdErrorType + /// The error code for obtaining more specific information about the error. + func code(pigeonApi: PigeonApiIMAAdError, pigeonInstance: IMAAdError) throws -> AdErrorCode + /// A brief description about the error. + func message(pigeonApi: PigeonApiIMAAdError, pigeonInstance: IMAAdError) throws -> String? +} + +protocol PigeonApiProtocolIMAAdError { +} + +final class PigeonApiIMAAdError: PigeonApiProtocolIMAAdError { + unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateIMAAdError + ///An implementation of [NSObject] used to access callback methods + var pigeonApiNSObject: PigeonApiNSObject { + return pigeonRegistrar.apiDelegate.pigeonApiNSObject(pigeonRegistrar) + } + + init( + pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateIMAAdError + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + ///Creates a Dart instance of IMAAdError and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: IMAAdError, completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let typeArg = try! pigeonDelegate.type(pigeonApi: self, pigeonInstance: pigeonInstance) + let codeArg = try! pigeonDelegate.code(pigeonApi: self, pigeonInstance: pigeonInstance) + let messageArg = try! pigeonDelegate.message(pigeonApi: self, pigeonInstance: pigeonInstance) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.IMAAdError.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonIdentifierArg, typeArg, codeArg, messageArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} +protocol PigeonApiDelegateIMAAdsManager { + /// The `IMAAdsManagerDelegate` to notify with events during ad playback. + func setDelegate( + pigeonApi: PigeonApiIMAAdsManager, pigeonInstance: IMAAdsManager, + delegate: IMAAdsManagerDelegate?) throws + /// Initializes and loads the ad. + func initialize( + pigeonApi: PigeonApiIMAAdsManager, pigeonInstance: IMAAdsManager, + adsRenderingSettings: IMAAdsRenderingSettings?) throws + /// Starts advertisement playback. + func start(pigeonApi: PigeonApiIMAAdsManager, pigeonInstance: IMAAdsManager) throws + /// Pauses advertisement. + func pause(pigeonApi: PigeonApiIMAAdsManager, pigeonInstance: IMAAdsManager) throws + /// Resumes the current ad. + func resume(pigeonApi: PigeonApiIMAAdsManager, pigeonInstance: IMAAdsManager) throws + /// Skips the advertisement if the ad is skippable and the skip offset has + /// been reached. + func skip(pigeonApi: PigeonApiIMAAdsManager, pigeonInstance: IMAAdsManager) throws + /// If an ad break is currently playing, discard it and resume content. + func discardAdBreak(pigeonApi: PigeonApiIMAAdsManager, pigeonInstance: IMAAdsManager) throws + /// Causes the ads manager to stop the ad and clean its internal state. + func destroy(pigeonApi: PigeonApiIMAAdsManager, pigeonInstance: IMAAdsManager) throws +} + +protocol PigeonApiProtocolIMAAdsManager { +} + +final class PigeonApiIMAAdsManager: PigeonApiProtocolIMAAdsManager { + unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateIMAAdsManager + ///An implementation of [NSObject] used to access callback methods + var pigeonApiNSObject: PigeonApiNSObject { + return pigeonRegistrar.apiDelegate.pigeonApiNSObject(pigeonRegistrar) + } + + init( + pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateIMAAdsManager + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + static func setUpMessageHandlers( + binaryMessenger: FlutterBinaryMessenger, api: PigeonApiIMAAdsManager? + ) { + let codec: FlutterStandardMessageCodec = + api != nil + ? FlutterStandardMessageCodec( + readerWriter: InteractiveMediaAdsLibraryPigeonInternalProxyApiCodecReaderWriter( + pigeonRegistrar: api!.pigeonRegistrar)) + : FlutterStandardMessageCodec.sharedInstance() + let setDelegateChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.setDelegate", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + setDelegateChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! IMAAdsManager + let delegateArg: IMAAdsManagerDelegate? = nilOrValue(args[1]) + do { + try api.pigeonDelegate.setDelegate( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, delegate: delegateArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + setDelegateChannel.setMessageHandler(nil) + } + let initializeChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.initialize", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + initializeChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! IMAAdsManager + let adsRenderingSettingsArg: IMAAdsRenderingSettings? = nilOrValue(args[1]) + do { + try api.pigeonDelegate.initialize( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, + adsRenderingSettings: adsRenderingSettingsArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + initializeChannel.setMessageHandler(nil) + } + let startChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.start", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + startChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! IMAAdsManager + do { + try api.pigeonDelegate.start(pigeonApi: api, pigeonInstance: pigeonInstanceArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + startChannel.setMessageHandler(nil) + } + let pauseChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.pause", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + pauseChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! IMAAdsManager + do { + try api.pigeonDelegate.pause(pigeonApi: api, pigeonInstance: pigeonInstanceArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + pauseChannel.setMessageHandler(nil) + } + let resumeChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.resume", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + resumeChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! IMAAdsManager + do { + try api.pigeonDelegate.resume(pigeonApi: api, pigeonInstance: pigeonInstanceArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + resumeChannel.setMessageHandler(nil) + } + let skipChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.skip", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + skipChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! IMAAdsManager + do { + try api.pigeonDelegate.skip(pigeonApi: api, pigeonInstance: pigeonInstanceArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + skipChannel.setMessageHandler(nil) + } + let discardAdBreakChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.discardAdBreak", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + discardAdBreakChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! IMAAdsManager + do { + try api.pigeonDelegate.discardAdBreak(pigeonApi: api, pigeonInstance: pigeonInstanceArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + discardAdBreakChannel.setMessageHandler(nil) + } + let destroyChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.destroy", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + destroyChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! IMAAdsManager + do { + try api.pigeonDelegate.destroy(pigeonApi: api, pigeonInstance: pigeonInstanceArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + destroyChannel.setMessageHandler(nil) + } + } + + ///Creates a Dart instance of IMAAdsManager and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: IMAAdsManager, completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonIdentifierArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} +protocol PigeonApiDelegateIMAAdsManagerDelegate { + func pigeonDefaultConstructor(pigeonApi: PigeonApiIMAAdsManagerDelegate) throws + -> IMAAdsManagerDelegate +} + +protocol PigeonApiProtocolIMAAdsManagerDelegate { + /// Called when there is an IMAAdEvent. + func didReceiveAdEvent( + pigeonInstance pigeonInstanceArg: IMAAdsManagerDelegate, + adsManager adsManagerArg: IMAAdsManager, event eventArg: IMAAdEvent, + completion: @escaping (Result) -> Void) + /// Called when there was an error playing the ad. + func didReceiveAdError( + pigeonInstance pigeonInstanceArg: IMAAdsManagerDelegate, + adsManager adsManagerArg: IMAAdsManager, error errorArg: IMAAdError, + completion: @escaping (Result) -> Void) + /// Called when an ad is ready to play. + func didRequestContentPause( + pigeonInstance pigeonInstanceArg: IMAAdsManagerDelegate, + adsManager adsManagerArg: IMAAdsManager, + completion: @escaping (Result) -> Void) + /// Called when an ad has finished or an error occurred during the playback. + func didRequestContentResume( + pigeonInstance pigeonInstanceArg: IMAAdsManagerDelegate, + adsManager adsManagerArg: IMAAdsManager, + completion: @escaping (Result) -> Void) +} + +final class PigeonApiIMAAdsManagerDelegate: PigeonApiProtocolIMAAdsManagerDelegate { + unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateIMAAdsManagerDelegate + ///An implementation of [NSObject] used to access callback methods + var pigeonApiNSObject: PigeonApiNSObject { + return pigeonRegistrar.apiDelegate.pigeonApiNSObject(pigeonRegistrar) + } + + init( + pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateIMAAdsManagerDelegate + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + static func setUpMessageHandlers( + binaryMessenger: FlutterBinaryMessenger, api: PigeonApiIMAAdsManagerDelegate? + ) { + let codec: FlutterStandardMessageCodec = + api != nil + ? FlutterStandardMessageCodec( + readerWriter: InteractiveMediaAdsLibraryPigeonInternalProxyApiCodecReaderWriter( + pigeonRegistrar: api!.pigeonRegistrar)) + : FlutterStandardMessageCodec.sharedInstance() + let pigeonDefaultConstructorChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.interactive_media_ads.IMAAdsManagerDelegate.pigeon_defaultConstructor", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + pigeonDefaultConstructorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonIdentifierArg = args[0] as! Int64 + do { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + try api.pigeonDelegate.pigeonDefaultConstructor(pigeonApi: api), + withIdentifier: pigeonIdentifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + pigeonDefaultConstructorChannel.setMessageHandler(nil) + } + } + + ///Creates a Dart instance of IMAAdsManagerDelegate and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: IMAAdsManagerDelegate, completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + print( + "Error: Attempting to create a new Dart instance of IMAAdsManagerDelegate, but the class has a nonnull callback method." + ) + } + /// Called when there is an IMAAdEvent. + func didReceiveAdEvent( + pigeonInstance pigeonInstanceArg: IMAAdsManagerDelegate, + adsManager adsManagerArg: IMAAdsManager, event eventArg: IMAAdEvent, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.IMAAdsManagerDelegate.didReceiveAdEvent" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, adsManagerArg, eventArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + + /// Called when there was an error playing the ad. + func didReceiveAdError( + pigeonInstance pigeonInstanceArg: IMAAdsManagerDelegate, + adsManager adsManagerArg: IMAAdsManager, error errorArg: IMAAdError, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.IMAAdsManagerDelegate.didReceiveAdError" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, adsManagerArg, errorArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + + /// Called when an ad is ready to play. + func didRequestContentPause( + pigeonInstance pigeonInstanceArg: IMAAdsManagerDelegate, + adsManager adsManagerArg: IMAAdsManager, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.IMAAdsManagerDelegate.didRequestContentPause" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, adsManagerArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + + /// Called when an ad has finished or an error occurred during the playback. + func didRequestContentResume( + pigeonInstance pigeonInstanceArg: IMAAdsManagerDelegate, + adsManager adsManagerArg: IMAAdsManager, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.IMAAdsManagerDelegate.didRequestContentResume" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, adsManagerArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + +} +protocol PigeonApiDelegateIMAAdEvent { + /// Type of the event. + func type(pigeonApi: PigeonApiIMAAdEvent, pigeonInstance: IMAAdEvent) throws -> AdEventType + /// Stringified type of the event. + func typeString(pigeonApi: PigeonApiIMAAdEvent, pigeonInstance: IMAAdEvent) throws -> String + /// Extra data about the ad. + func adData(pigeonApi: PigeonApiIMAAdEvent, pigeonInstance: IMAAdEvent) throws -> [String: Any]? +} + +protocol PigeonApiProtocolIMAAdEvent { +} + +final class PigeonApiIMAAdEvent: PigeonApiProtocolIMAAdEvent { + unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateIMAAdEvent + ///An implementation of [NSObject] used to access callback methods + var pigeonApiNSObject: PigeonApiNSObject { + return pigeonRegistrar.apiDelegate.pigeonApiNSObject(pigeonRegistrar) + } + + init( + pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateIMAAdEvent + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + ///Creates a Dart instance of IMAAdEvent and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: IMAAdEvent, completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let typeArg = try! pigeonDelegate.type(pigeonApi: self, pigeonInstance: pigeonInstance) + let typeStringArg = try! pigeonDelegate.typeString( + pigeonApi: self, pigeonInstance: pigeonInstance) + let adDataArg = try! pigeonDelegate.adData(pigeonApi: self, pigeonInstance: pigeonInstance) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.IMAAdEvent.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonIdentifierArg, typeArg, typeStringArg, adDataArg] as [Any?]) { + response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} +protocol PigeonApiDelegateIMAAdsRenderingSettings { + func pigeonDefaultConstructor(pigeonApi: PigeonApiIMAAdsRenderingSettings) throws + -> IMAAdsRenderingSettings + /// If specified, the SDK will play the media with MIME type on the list. + func setMimeTypes( + pigeonApi: PigeonApiIMAAdsRenderingSettings, pigeonInstance: IMAAdsRenderingSettings, + types: [String]?) throws + /// Maximum recommended bitrate. + /// + /// The value is in kbit/s. + func setBitrate( + pigeonApi: PigeonApiIMAAdsRenderingSettings, pigeonInstance: IMAAdsRenderingSettings, + bitrate: Int64) throws + /// Timeout (in seconds) when loading a video ad media file. + /// + /// Use -1 for the default of 8 seconds. + func setLoadVideoTimeout( + pigeonApi: PigeonApiIMAAdsRenderingSettings, pigeonInstance: IMAAdsRenderingSettings, + seconds: Double) throws + /// For VMAP and ad rules playlists, only play ad breaks scheduled after this + /// time (in seconds). + func setPlayAdsAfterTime( + pigeonApi: PigeonApiIMAAdsRenderingSettings, pigeonInstance: IMAAdsRenderingSettings, + seconds: Double) throws + /// Specifies the list of UI elements that should be visible. + func setUIElements( + pigeonApi: PigeonApiIMAAdsRenderingSettings, pigeonInstance: IMAAdsRenderingSettings, + types: [UIElementType]?) throws + /// Whether or not the SDK will preload ad media. + /// + /// Default is YES. + func setEnablePreloading( + pigeonApi: PigeonApiIMAAdsRenderingSettings, pigeonInstance: IMAAdsRenderingSettings, + enable: Bool) throws + /// Specifies the optional UIViewController that will be used to open links + /// in-app. + func setLinkOpenerPresentingController( + pigeonApi: PigeonApiIMAAdsRenderingSettings, pigeonInstance: IMAAdsRenderingSettings, + controller: UIViewController) throws +} + +protocol PigeonApiProtocolIMAAdsRenderingSettings { +} + +final class PigeonApiIMAAdsRenderingSettings: PigeonApiProtocolIMAAdsRenderingSettings { + unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateIMAAdsRenderingSettings + ///An implementation of [NSObject] used to access callback methods + var pigeonApiNSObject: PigeonApiNSObject { + return pigeonRegistrar.apiDelegate.pigeonApiNSObject(pigeonRegistrar) + } + + init( + pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateIMAAdsRenderingSettings + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + static func setUpMessageHandlers( + binaryMessenger: FlutterBinaryMessenger, api: PigeonApiIMAAdsRenderingSettings? + ) { + let codec: FlutterStandardMessageCodec = + api != nil + ? FlutterStandardMessageCodec( + readerWriter: InteractiveMediaAdsLibraryPigeonInternalProxyApiCodecReaderWriter( + pigeonRegistrar: api!.pigeonRegistrar)) + : FlutterStandardMessageCodec.sharedInstance() + let pigeonDefaultConstructorChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.interactive_media_ads.IMAAdsRenderingSettings.pigeon_defaultConstructor", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + pigeonDefaultConstructorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonIdentifierArg = args[0] as! Int64 + do { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + try api.pigeonDelegate.pigeonDefaultConstructor(pigeonApi: api), + withIdentifier: pigeonIdentifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + pigeonDefaultConstructorChannel.setMessageHandler(nil) + } + let setMimeTypesChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.IMAAdsRenderingSettings.setMimeTypes", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + setMimeTypesChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! IMAAdsRenderingSettings + let typesArg: [String]? = nilOrValue(args[1]) + do { + try api.pigeonDelegate.setMimeTypes( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, types: typesArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + setMimeTypesChannel.setMessageHandler(nil) + } + let setBitrateChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.IMAAdsRenderingSettings.setBitrate", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + setBitrateChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! IMAAdsRenderingSettings + let bitrateArg = args[1] as! Int64 + do { + try api.pigeonDelegate.setBitrate( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, bitrate: bitrateArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + setBitrateChannel.setMessageHandler(nil) + } + let setLoadVideoTimeoutChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.IMAAdsRenderingSettings.setLoadVideoTimeout", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + setLoadVideoTimeoutChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! IMAAdsRenderingSettings + let secondsArg = args[1] as! Double + do { + try api.pigeonDelegate.setLoadVideoTimeout( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, seconds: secondsArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + setLoadVideoTimeoutChannel.setMessageHandler(nil) + } + let setPlayAdsAfterTimeChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.IMAAdsRenderingSettings.setPlayAdsAfterTime", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + setPlayAdsAfterTimeChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! IMAAdsRenderingSettings + let secondsArg = args[1] as! Double + do { + try api.pigeonDelegate.setPlayAdsAfterTime( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, seconds: secondsArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + setPlayAdsAfterTimeChannel.setMessageHandler(nil) + } + let setUIElementsChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.IMAAdsRenderingSettings.setUIElements", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + setUIElementsChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! IMAAdsRenderingSettings + let typesArg: [UIElementType]? = nilOrValue(args[1]) + do { + try api.pigeonDelegate.setUIElements( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, types: typesArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + setUIElementsChannel.setMessageHandler(nil) + } + let setEnablePreloadingChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.IMAAdsRenderingSettings.setEnablePreloading", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + setEnablePreloadingChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! IMAAdsRenderingSettings + let enableArg = args[1] as! Bool + do { + try api.pigeonDelegate.setEnablePreloading( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, enable: enableArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + setEnablePreloadingChannel.setMessageHandler(nil) + } + let setLinkOpenerPresentingControllerChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.interactive_media_ads.IMAAdsRenderingSettings.setLinkOpenerPresentingController", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + setLinkOpenerPresentingControllerChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! IMAAdsRenderingSettings + let controllerArg = args[1] as! UIViewController + do { + try api.pigeonDelegate.setLinkOpenerPresentingController( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, controller: controllerArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + setLinkOpenerPresentingControllerChannel.setMessageHandler(nil) + } + } + + ///Creates a Dart instance of IMAAdsRenderingSettings and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: IMAAdsRenderingSettings, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.IMAAdsRenderingSettings.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonIdentifierArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} +open class PigeonApiDelegateNSObject { +} + +protocol PigeonApiProtocolNSObject { +} + +final class PigeonApiNSObject: PigeonApiProtocolNSObject { + unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateNSObject + init( + pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateNSObject + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + ///Creates a Dart instance of NSObject and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: NSObject, completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = "dev.flutter.pigeon.interactive_media_ads.NSObject.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonIdentifierArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} +protocol PigeonApiDelegateIMAFriendlyObstruction { + /// Initializes a friendly obstruction. + func pigeonDefaultConstructor( + pigeonApi: PigeonApiIMAFriendlyObstruction, view: UIView, purpose: FriendlyObstructionPurpose, + detailedReason: String? + ) throws -> IMAFriendlyObstruction + /// The view causing the obstruction. + func view(pigeonApi: PigeonApiIMAFriendlyObstruction, pigeonInstance: IMAFriendlyObstruction) + throws -> UIView + /// The purpose for registering the obstruction as friendly. + func purpose(pigeonApi: PigeonApiIMAFriendlyObstruction, pigeonInstance: IMAFriendlyObstruction) + throws -> FriendlyObstructionPurpose + /// Optional, detailed reasoning for registering this obstruction as friendly. + /// + /// If the detailedReason is not null, it must follow the IAB standard by + /// being 50 characters or less and only containing characters A-z, 0-9, or + /// spaces. + func detailedReason( + pigeonApi: PigeonApiIMAFriendlyObstruction, pigeonInstance: IMAFriendlyObstruction + ) throws -> String? +} + +protocol PigeonApiProtocolIMAFriendlyObstruction { +} + +final class PigeonApiIMAFriendlyObstruction: PigeonApiProtocolIMAFriendlyObstruction { + unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateIMAFriendlyObstruction + ///An implementation of [NSObject] used to access callback methods + var pigeonApiNSObject: PigeonApiNSObject { + return pigeonRegistrar.apiDelegate.pigeonApiNSObject(pigeonRegistrar) + } + + init( + pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateIMAFriendlyObstruction + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + static func setUpMessageHandlers( + binaryMessenger: FlutterBinaryMessenger, api: PigeonApiIMAFriendlyObstruction? + ) { + let codec: FlutterStandardMessageCodec = + api != nil + ? FlutterStandardMessageCodec( + readerWriter: InteractiveMediaAdsLibraryPigeonInternalProxyApiCodecReaderWriter( + pigeonRegistrar: api!.pigeonRegistrar)) + : FlutterStandardMessageCodec.sharedInstance() + let pigeonDefaultConstructorChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.interactive_media_ads.IMAFriendlyObstruction.pigeon_defaultConstructor", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + pigeonDefaultConstructorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonIdentifierArg = args[0] as! Int64 + let viewArg = args[1] as! UIView + let purposeArg = args[2] as! FriendlyObstructionPurpose + let detailedReasonArg: String? = nilOrValue(args[3]) + do { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + try api.pigeonDelegate.pigeonDefaultConstructor( + pigeonApi: api, view: viewArg, purpose: purposeArg, detailedReason: detailedReasonArg), + withIdentifier: pigeonIdentifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + pigeonDefaultConstructorChannel.setMessageHandler(nil) + } + } + + ///Creates a Dart instance of IMAFriendlyObstruction and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: IMAFriendlyObstruction, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let viewArg = try! pigeonDelegate.view(pigeonApi: self, pigeonInstance: pigeonInstance) + let purposeArg = try! pigeonDelegate.purpose(pigeonApi: self, pigeonInstance: pigeonInstance) + let detailedReasonArg = try! pigeonDelegate.detailedReason( + pigeonApi: self, pigeonInstance: pigeonInstance) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.IMAFriendlyObstruction.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonIdentifierArg, viewArg, purposeArg, detailedReasonArg] as [Any?]) { + response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} +protocol PigeonApiDelegateIMACompanionAd { + /// The value for the resource of this companion. + func resourceValue(pigeonApi: PigeonApiIMACompanionAd, pigeonInstance: IMACompanionAd) throws + -> String? + /// The API needed to execute this ad, or nil if unavailable. + func apiFramework(pigeonApi: PigeonApiIMACompanionAd, pigeonInstance: IMACompanionAd) throws + -> String? + /// The width of the companion in pixels. + /// + /// 0 if unavailable. + func width(pigeonApi: PigeonApiIMACompanionAd, pigeonInstance: IMACompanionAd) throws -> Int64 + /// The height of the companion in pixels. + /// + /// 0 if unavailable. + func height(pigeonApi: PigeonApiIMACompanionAd, pigeonInstance: IMACompanionAd) throws -> Int64 +} + +protocol PigeonApiProtocolIMACompanionAd { +} + +final class PigeonApiIMACompanionAd: PigeonApiProtocolIMACompanionAd { + unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateIMACompanionAd + ///An implementation of [NSObject] used to access callback methods + var pigeonApiNSObject: PigeonApiNSObject { + return pigeonRegistrar.apiDelegate.pigeonApiNSObject(pigeonRegistrar) + } + + init( + pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateIMACompanionAd + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + ///Creates a Dart instance of IMACompanionAd and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: IMACompanionAd, completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let resourceValueArg = try! pigeonDelegate.resourceValue( + pigeonApi: self, pigeonInstance: pigeonInstance) + let apiFrameworkArg = try! pigeonDelegate.apiFramework( + pigeonApi: self, pigeonInstance: pigeonInstance) + let widthArg = try! pigeonDelegate.width(pigeonApi: self, pigeonInstance: pigeonInstance) + let heightArg = try! pigeonDelegate.height(pigeonApi: self, pigeonInstance: pigeonInstance) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.IMACompanionAd.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage( + [pigeonIdentifierArg, resourceValueArg, apiFrameworkArg, widthArg, heightArg] as [Any?] + ) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} +protocol PigeonApiDelegateIMACompanionAdSlot { + /// Initializes an instance of a IMACompanionAdSlot with fluid size. + func pigeonDefaultConstructor(pigeonApi: PigeonApiIMACompanionAdSlot, view: UIView) throws + -> IMACompanionAdSlot + /// Initializes an instance of a IMACompanionAdSlot with design ad width and + /// height. + /// + /// `width` and `height` are in pixels. + func size(pigeonApi: PigeonApiIMACompanionAdSlot, view: UIView, width: Int64, height: Int64) + throws -> IMACompanionAdSlot + /// The view the companion will be rendered in. + /// + /// Display this view in your application before video ad starts. + func view(pigeonApi: PigeonApiIMACompanionAdSlot, pigeonInstance: IMACompanionAdSlot) throws + -> UIView + /// The IMACompanionDelegate for receiving events from the companion ad slot. + /// + /// This instance only creates a weak reference to the delegate, so the Dart + /// instance should create an explicit reference to receive callbacks. + func setDelegate( + pigeonApi: PigeonApiIMACompanionAdSlot, pigeonInstance: IMACompanionAdSlot, + delegate: IMACompanionDelegate?) throws +} + +protocol PigeonApiProtocolIMACompanionAdSlot { +} + +final class PigeonApiIMACompanionAdSlot: PigeonApiProtocolIMACompanionAdSlot { + unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateIMACompanionAdSlot + init( + pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateIMACompanionAdSlot + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + static func setUpMessageHandlers( + binaryMessenger: FlutterBinaryMessenger, api: PigeonApiIMACompanionAdSlot? + ) { + let codec: FlutterStandardMessageCodec = + api != nil + ? FlutterStandardMessageCodec( + readerWriter: InteractiveMediaAdsLibraryPigeonInternalProxyApiCodecReaderWriter( + pigeonRegistrar: api!.pigeonRegistrar)) + : FlutterStandardMessageCodec.sharedInstance() + let pigeonDefaultConstructorChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.IMACompanionAdSlot.pigeon_defaultConstructor", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + pigeonDefaultConstructorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonIdentifierArg = args[0] as! Int64 + let viewArg = args[1] as! UIView + do { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + try api.pigeonDelegate.pigeonDefaultConstructor(pigeonApi: api, view: viewArg), + withIdentifier: pigeonIdentifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + pigeonDefaultConstructorChannel.setMessageHandler(nil) + } + let sizeChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.IMACompanionAdSlot.pigeon_defaultConstructor", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + sizeChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonIdentifierArg = args[0] as! Int64 + let viewArg = args[1] as! UIView + let widthArg = args[2] as! Int64 + let heightArg = args[3] as! Int64 + do { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + try api.pigeonDelegate.size( + pigeonApi: api, view: viewArg, width: widthArg, height: heightArg), + withIdentifier: pigeonIdentifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + sizeChannel.setMessageHandler(nil) + } + let setDelegateChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.interactive_media_ads.IMACompanionAdSlot.setDelegate", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + setDelegateChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! IMACompanionAdSlot + let delegateArg: IMACompanionDelegate? = nilOrValue(args[1]) + do { + try api.pigeonDelegate.setDelegate( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, delegate: delegateArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + setDelegateChannel.setMessageHandler(nil) + } + } + + ///Creates a Dart instance of IMACompanionAdSlot and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: IMACompanionAdSlot, completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let viewArg = try! pigeonDelegate.view(pigeonApi: self, pigeonInstance: pigeonInstance) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.IMACompanionAdSlot.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonIdentifierArg, viewArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} +protocol PigeonApiDelegateIMACompanionDelegate { + func pigeonDefaultConstructor(pigeonApi: PigeonApiIMACompanionDelegate) throws + -> IMACompanionDelegate +} + +protocol PigeonApiProtocolIMACompanionDelegate { + /// Called when the slot is either filled or not filled. + func companionAdSlotFilled( + pigeonInstance pigeonInstanceArg: IMACompanionDelegate, slot slotArg: IMACompanionAdSlot, + filled filledArg: Bool, completion: @escaping (Result) -> Void) + /// Called when the slot is clicked on by the user and will successfully + /// navigate away. + func companionSlotWasClicked( + pigeonInstance pigeonInstanceArg: IMACompanionDelegate, slot slotArg: IMACompanionAdSlot, + completion: @escaping (Result) -> Void) +} + +final class PigeonApiIMACompanionDelegate: PigeonApiProtocolIMACompanionDelegate { + unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateIMACompanionDelegate + ///An implementation of [NSObject] used to access callback methods + var pigeonApiNSObject: PigeonApiNSObject { + return pigeonRegistrar.apiDelegate.pigeonApiNSObject(pigeonRegistrar) + } + + init( + pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateIMACompanionDelegate + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + static func setUpMessageHandlers( + binaryMessenger: FlutterBinaryMessenger, api: PigeonApiIMACompanionDelegate? + ) { + let codec: FlutterStandardMessageCodec = + api != nil + ? FlutterStandardMessageCodec( + readerWriter: InteractiveMediaAdsLibraryPigeonInternalProxyApiCodecReaderWriter( + pigeonRegistrar: api!.pigeonRegistrar)) + : FlutterStandardMessageCodec.sharedInstance() + let pigeonDefaultConstructorChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.interactive_media_ads.IMACompanionDelegate.pigeon_defaultConstructor", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + pigeonDefaultConstructorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonIdentifierArg = args[0] as! Int64 + do { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + try api.pigeonDelegate.pigeonDefaultConstructor(pigeonApi: api), + withIdentifier: pigeonIdentifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + pigeonDefaultConstructorChannel.setMessageHandler(nil) + } + } + + ///Creates a Dart instance of IMACompanionDelegate and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: IMACompanionDelegate, completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.IMACompanionDelegate.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonIdentifierArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + /// Called when the slot is either filled or not filled. + func companionAdSlotFilled( + pigeonInstance pigeonInstanceArg: IMACompanionDelegate, slot slotArg: IMACompanionAdSlot, + filled filledArg: Bool, completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.IMACompanionDelegate.companionAdSlotFilled" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, slotArg, filledArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + + /// Called when the slot is clicked on by the user and will successfully + /// navigate away. + func companionSlotWasClicked( + pigeonInstance pigeonInstanceArg: IMACompanionDelegate, slot slotArg: IMACompanionAdSlot, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.IMACompanionDelegate.companionSlotWasClicked" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, slotArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + +} diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/InteractiveMediaAdsPlugin.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/InteractiveMediaAdsPlugin.swift index 5b94fd6a24aa..e0bc5caec0af 100644 --- a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/InteractiveMediaAdsPlugin.swift +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/InteractiveMediaAdsPlugin.swift @@ -6,19 +6,24 @@ import Flutter import UIKit public class InteractiveMediaAdsPlugin: NSObject, FlutterPlugin { + var proxyApiRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar? + + init(binaryMessenger: FlutterBinaryMessenger) { + proxyApiRegistrar = InteractiveMediaAdsLibraryPigeonProxyApiRegistrar( + binaryMessenger: binaryMessenger, apiDelegate: ProxyApiDelegate()) + proxyApiRegistrar?.setUp() + } + public static func register(with registrar: FlutterPluginRegistrar) { - let channel = FlutterMethodChannel( - name: "interactive_media_ads", binaryMessenger: registrar.messenger()) - let instance = InteractiveMediaAdsPlugin() - registrar.addMethodCallDelegate(instance, channel: channel) + let plugin = InteractiveMediaAdsPlugin(binaryMessenger: registrar.messenger()) + let viewFactory = FlutterViewFactory(instanceManager: plugin.proxyApiRegistrar!.instanceManager) + registrar.register(viewFactory, withId: "interactive_media_ads.packages.flutter.dev/view") + registrar.publish(plugin) } - public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { - switch call.method { - case "getPlatformVersion": - result("iOS " + UIDevice.current.systemVersion) - default: - result(FlutterMethodNotImplemented) - } + public func detachFromEngine(for registrar: FlutterPluginRegistrar) { + proxyApiRegistrar!.ignoreCallsToDart = true + proxyApiRegistrar!.tearDown() + proxyApiRegistrar = nil } } diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/ProxyApiDelegate.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/ProxyApiDelegate.swift new file mode 100644 index 000000000000..0475adf37efa --- /dev/null +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/ProxyApiDelegate.swift @@ -0,0 +1,148 @@ +// 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 Foundation +import GoogleInteractiveMediaAds + +/// Implementation of `PigeonProxyApiDelegate` that provides each ProxyApi delegate implementation +/// and any additional resources needed by an implementation. +open class ProxyApiDelegate: InteractiveMediaAdsLibraryPigeonProxyApiDelegate { + func createUnknownEnumError(withEnum enumValue: Any) -> PigeonError { + return PigeonError( + code: "UnknownEnumError", message: "\(enumValue) doesn't represent a native value.", + details: nil) + } + + func pigeonApiUIView(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiUIView + { + return PigeonApiUIView(pigeonRegistrar: registrar, delegate: ViewProxyAPIDelegate()) + } + + func pigeonApiIMAAdDisplayContainer( + _ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + ) + -> PigeonApiIMAAdDisplayContainer + { + return PigeonApiIMAAdDisplayContainer( + pigeonRegistrar: registrar, delegate: AdDisplayContainerProxyAPIDelegate()) + } + + func pigeonApiUIViewController(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiUIViewController + { + return PigeonApiUIViewController( + pigeonRegistrar: registrar, delegate: ViewControllerProxyAPIDelegate()) + } + + func pigeonApiIMAContentPlayhead(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMAContentPlayhead + { + return PigeonApiIMAContentPlayhead( + pigeonRegistrar: registrar, delegate: ContentPlayheadProxyAPIDelegate()) + } + + func pigeonApiIMAAdsLoader(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMAAdsLoader + { + return PigeonApiIMAAdsLoader(pigeonRegistrar: registrar, delegate: AdsLoaderProxyAPIDelegate()) + } + + func pigeonApiIMAAdsRequest(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMAAdsRequest + { + return PigeonApiIMAAdsRequest( + pigeonRegistrar: registrar, delegate: AdsRequestProxyAPIDelegate()) + } + + func pigeonApiIMAAdsLoaderDelegate(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMAAdsLoaderDelegate + { + return PigeonApiIMAAdsLoaderDelegate( + pigeonRegistrar: registrar, delegate: AdsLoaderDelegateProxyAPIDelegate()) + } + + func pigeonApiIMAAdsLoadedData(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMAAdsLoadedData + { + return PigeonApiIMAAdsLoadedData( + pigeonRegistrar: registrar, delegate: AdsLoadedDataProxyAPIDelegate()) + } + + func pigeonApiIMAAdLoadingErrorData( + _ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + ) + -> PigeonApiIMAAdLoadingErrorData + { + return PigeonApiIMAAdLoadingErrorData( + pigeonRegistrar: registrar, delegate: AdLoadingErrorDataProxyAPIDelegate()) + } + + func pigeonApiIMAAdError(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMAAdError + { + return PigeonApiIMAAdError(pigeonRegistrar: registrar, delegate: AdErrorProxyAPIDelegate()) + } + + func pigeonApiIMAAdsManager(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMAAdsManager + { + return PigeonApiIMAAdsManager( + pigeonRegistrar: registrar, delegate: AdsManagerProxyAPIDelegate()) + } + + func pigeonApiIMAAdsManagerDelegate( + _ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + ) + -> PigeonApiIMAAdsManagerDelegate + { + return PigeonApiIMAAdsManagerDelegate( + pigeonRegistrar: registrar, delegate: AdsManagerDelegateProxyAPIDelegate()) + } + + func pigeonApiIMAAdEvent(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMAAdEvent + { + return PigeonApiIMAAdEvent(pigeonRegistrar: registrar, delegate: AdEventProxyAPIDelegate()) + } + + func pigeonApiIMAAdsRenderingSettings( + _ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + ) + -> PigeonApiIMAAdsRenderingSettings + { + return PigeonApiIMAAdsRenderingSettings( + pigeonRegistrar: registrar, delegate: AdsRenderingSettingsProxyAPIDelegate()) + } + + func pigeonApiIMAFriendlyObstruction( + _ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + ) + -> PigeonApiIMAFriendlyObstruction + { + return PigeonApiIMAFriendlyObstruction( + pigeonRegistrar: registrar, delegate: FriendlyObstructionProxyAPIDelegate()) + } + + func pigeonApiIMACompanionAd(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMACompanionAd + { + return PigeonApiIMACompanionAd( + pigeonRegistrar: registrar, delegate: CompanionAdProxyAPIDelegate()) + } + + func pigeonApiIMACompanionAdSlot(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMACompanionAdSlot + { + return PigeonApiIMACompanionAdSlot( + pigeonRegistrar: registrar, delegate: CompanionAdSlotProxyAPIDelegate()) + } + + func pigeonApiIMACompanionDelegate(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMACompanionDelegate + { + return PigeonApiIMACompanionDelegate( + pigeonRegistrar: registrar, delegate: CompanionDelegateProxyAPIDelegate()) + } +} diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/ViewControllerProxyAPIDelegate.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/ViewControllerProxyAPIDelegate.swift new file mode 100644 index 000000000000..623ad1dd1e0a --- /dev/null +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/ViewControllerProxyAPIDelegate.swift @@ -0,0 +1,38 @@ +// 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 Foundation +import UIKit + +class ViewControllerImpl: UIViewController { + let api: PigeonApiProtocolUIViewController + + init(api: PigeonApiProtocolUIViewController) { + self.api = api + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func viewDidAppear(_ animated: Bool) { + api.viewDidAppear(pigeonInstance: self, animated: animated) { _ in } + } +} + +/// ProxyApi delegate implementation for `UIViewController`. +/// +/// This class may handle instantiating native object instances that are attached to a Dart +/// instance or handle method calls on the associated native class or an instance of that class. +class ViewControllerProxyAPIDelegate: PigeonApiDelegateUIViewController { + func pigeonDefaultConstructor(pigeonApi: PigeonApiUIViewController) throws -> UIViewController { + return ViewControllerImpl(api: pigeonApi) + } + + func view(pigeonApi: PigeonApiUIViewController, pigeonInstance: UIViewController) throws -> UIView + { + return pigeonInstance.view + } +} diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/ViewProxyAPIDelegate.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/ViewProxyAPIDelegate.swift new file mode 100644 index 000000000000..1352a6fa2696 --- /dev/null +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/ViewProxyAPIDelegate.swift @@ -0,0 +1,16 @@ +// 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 Foundation +import UIKit + +/// ProxyApi delegate implementation for `UIView`. +/// +/// This class may handle instantiating native object instances that are attached to a Dart +/// instance or handle method calls on the associated native class or an instance of that class. +class ViewProxyAPIDelegate: PigeonApiDelegateUIView { + func getWindow(pigeonApi: PigeonApiUIView, pigeonInstance: UIView) throws -> UIWindow? { + return pigeonInstance.window + } +} diff --git a/packages/interactive_media_ads/lib/interactive_media_ads.dart b/packages/interactive_media_ads/lib/interactive_media_ads.dart index 185d304cf5bc..06c180248410 100644 --- a/packages/interactive_media_ads/lib/interactive_media_ads.dart +++ b/packages/interactive_media_ads/lib/interactive_media_ads.dart @@ -5,6 +5,17 @@ export 'src/ad_display_container.dart'; export 'src/ads_loader.dart'; export 'src/ads_manager_delegate.dart'; -export 'src/platform_interface/ad_error.dart'; -export 'src/platform_interface/ad_event.dart'; -export 'src/platform_interface/ads_request.dart'; +export 'src/ads_request.dart'; +export 'src/android/android_interactive_media_ads.dart' + show AndroidInteractiveMediaAds; +export 'src/content_progress_provider.dart'; +export 'src/ios/ios_interactive_media_ads.dart' show IOSInteractiveMediaAds; +export 'src/platform_interface/platform_interface.dart' + show + AdError, + AdErrorCode, + AdErrorEvent, + AdErrorType, + AdEvent, + AdEventType, + AdsLoadErrorData; diff --git a/packages/interactive_media_ads/lib/src/ad_display_container.dart b/packages/interactive_media_ads/lib/src/ad_display_container.dart index 99da19682b8e..9c4aeed93872 100644 --- a/packages/interactive_media_ads/lib/src/ad_display_container.dart +++ b/packages/interactive_media_ads/lib/src/ad_display_container.dart @@ -7,7 +7,7 @@ import 'package:flutter/cupertino.dart'; import 'platform_interface/platform_ad_display_container.dart'; import 'platform_interface/platform_interface.dart'; -/// Handles playing ads after they've been received from the server. +/// A [Widget] for displaying loaded ads. /// /// ## Platform-Specific Features /// This class contains an underlying implementation provided by the current @@ -37,6 +37,7 @@ class AdDisplayContainer extends StatelessWidget { AdDisplayContainer({ Key? key, required void Function(AdDisplayContainer container) onContainerAdded, + TextDirection layoutDirection = TextDirection.ltr, }) : this.fromPlatformCreationParams( key: key, params: PlatformAdDisplayContainerCreationParams( @@ -45,6 +46,7 @@ class AdDisplayContainer extends StatelessWidget { platform: container, )); }, + layoutDirection: layoutDirection, ), ); @@ -95,6 +97,9 @@ class AdDisplayContainer extends StatelessWidget { void Function(PlatformAdDisplayContainer container) get onContainerAdded => platform.params.onContainerAdded; + /// The layout direction to use for the embedded AdDisplayContainer. + TextDirection get layoutDirection => platform.params.layoutDirection; + @override Widget build(BuildContext context) { return platform.build(context); diff --git a/packages/interactive_media_ads/lib/src/ads_loader.dart b/packages/interactive_media_ads/lib/src/ads_loader.dart index 9370cc9fec35..9863d4c01293 100644 --- a/packages/interactive_media_ads/lib/src/ads_loader.dart +++ b/packages/interactive_media_ads/lib/src/ads_loader.dart @@ -6,9 +6,11 @@ import 'package:flutter/foundation.dart'; import 'ad_display_container.dart'; import 'ads_manager_delegate.dart'; +import 'ads_request.dart'; import 'platform_interface/platform_interface.dart'; -/// Handles playing ads after they've been received from the server. +/// Allows publishers to request ads from ad servers or a dynamic ad insertion +/// stream. /// /// ## Platform-Specific Features /// This class contains an underlying implementation provided by the current @@ -92,8 +94,11 @@ class AdsLoader { } /// Requests ads from a server. + /// + /// Ads cannot be requested until the `AdDisplayContainer` has been added to + /// the native View hierarchy. See [AdDisplayContainer.onContainerAdded]. Future requestAds(AdsRequest request) { - return platform.requestAds(request); + return platform.requestAds(request.platform); } } @@ -154,6 +159,30 @@ class AdsManager { return platform.setAdsManagerDelegate(delegate.platform); } + /// Pauses the current ad. + Future pause() { + return platform.pause(); + } + + /// Resumes the current ad. + Future resume() { + return platform.resume(); + } + + /// Skips the current ad. + /// + /// This only skips ads if IMA does not render the 'Skip ad' button. + Future skip() { + return platform.skip(); + } + + /// Discards current ad break and resumes content. + /// + /// If there is no current ad then the next ad break is discarded. + Future discardAdBreak() { + return platform.discardAdBreak(); + } + /// Stops the ad and all tracking, then releases all assets that were loaded /// to play the ad. Future destroy() { diff --git a/packages/interactive_media_ads/lib/src/ads_manager_delegate.dart b/packages/interactive_media_ads/lib/src/ads_manager_delegate.dart index 4a3813c719af..c04cf5c9c52a 100644 --- a/packages/interactive_media_ads/lib/src/ads_manager_delegate.dart +++ b/packages/interactive_media_ads/lib/src/ads_manager_delegate.dart @@ -4,7 +4,8 @@ import 'platform_interface/platform_interface.dart'; -/// Handles playing ads after they've been received from the server. +/// Delegate for ad events or errors that occur during ad or stream +/// initialization and playback. /// /// ## Platform-Specific Features /// This class contains an underlying implementation provided by the current diff --git a/packages/interactive_media_ads/lib/src/ads_request.dart b/packages/interactive_media_ads/lib/src/ads_request.dart new file mode 100644 index 000000000000..ecc8e2f2ccc5 --- /dev/null +++ b/packages/interactive_media_ads/lib/src/ads_request.dart @@ -0,0 +1,37 @@ +// 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 'content_progress_provider.dart'; +import 'platform_interface/platform_interface.dart'; + +/// An object containing the data used to request ads from the server. +class AdsRequest { + /// Creates an [AdsRequest]. + AdsRequest({ + required String adTagUrl, + ContentProgressProvider? contentProgressProvider, + }) : this.fromPlatform( + PlatformAdsRequest( + adTagUrl: adTagUrl, + contentProgressProvider: contentProgressProvider?.platform, + ), + ); + + /// Constructs an [AdsRequest] from a specific platform implementation. + AdsRequest.fromPlatform(this.platform); + + /// Implementation of [PlatformAdsRequest] for the current platform. + final PlatformAdsRequest platform; + + /// The URL from which ads will be requested. + String get adTagUrl => platform.adTagUrl; + + /// A [ContentProgressProvider] instance to allow scheduling of ad breaks + /// based on content progress (cue points). + ContentProgressProvider? get contentProgressProvider => platform + .contentProgressProvider != + null + ? ContentProgressProvider.fromPlatform(platform.contentProgressProvider!) + : null; +} diff --git a/packages/interactive_media_ads/lib/src/android/android_ad_display_container.dart b/packages/interactive_media_ads/lib/src/android/android_ad_display_container.dart new file mode 100644 index 000000000000..1c3a63dd9650 --- /dev/null +++ b/packages/interactive_media_ads/lib/src/android/android_ad_display_container.dart @@ -0,0 +1,303 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import 'package:flutter/widgets.dart'; +import 'package:meta/meta.dart'; + +import '../platform_interface/platform_interface.dart'; +import 'android_view_widget.dart'; +import 'interactive_media_ads.g.dart' as ima; +import 'interactive_media_ads_proxy.dart'; +import 'platform_views_service_proxy.dart'; + +/// Android implementation of [PlatformAdDisplayContainerCreationParams]. +final class AndroidAdDisplayContainerCreationParams + extends PlatformAdDisplayContainerCreationParams { + /// Constructs a [AndroidAdDisplayContainerCreationParams]. + const AndroidAdDisplayContainerCreationParams({ + super.key, + required super.onContainerAdded, + @visibleForTesting InteractiveMediaAdsProxy? imaProxy, + @visibleForTesting PlatformViewsServiceProxy? platformViewsProxy, + }) : _imaProxy = imaProxy ?? const InteractiveMediaAdsProxy(), + _platformViewsProxy = + platformViewsProxy ?? const PlatformViewsServiceProxy(), + super(); + + /// Creates a [AndroidAdDisplayContainerCreationParams] from an instance of + /// [PlatformAdDisplayContainerCreationParams]. + factory AndroidAdDisplayContainerCreationParams.fromPlatformAdDisplayContainerCreationParams( + PlatformAdDisplayContainerCreationParams params, { + @visibleForTesting InteractiveMediaAdsProxy? imaProxy, + @visibleForTesting PlatformViewsServiceProxy? platformViewsProxy, + }) { + return AndroidAdDisplayContainerCreationParams( + key: params.key, + onContainerAdded: params.onContainerAdded, + imaProxy: imaProxy, + platformViewsProxy: platformViewsProxy, + ); + } + + final InteractiveMediaAdsProxy _imaProxy; + final PlatformViewsServiceProxy _platformViewsProxy; +} + +/// Android implementation of [PlatformAdDisplayContainer]. +/// +/// This acts as the video player for an ad. To be a player for an ad from the +/// IMA SDK: +/// 1. The [ima.VideoView] must be in the View hierarchy until all ads have +/// finished. +/// 2. Must respond to callbacks from the [ima.VideoAdPlayer]. +/// 3. Must trigger methods for [ima.VideoAdPlayerCallback]s that provide ad +/// playback information to the IMA SDK. [ima.VideoAdPlayerCallback]s are +/// provided by [ima.VideoAdPlayer.addCallback]. +/// 4. Must create an [ima.AdDisplayContainer] with the `ViewGroup` that +/// contains the `VideoView`. +base class AndroidAdDisplayContainer extends PlatformAdDisplayContainer { + /// Constructs an [AndroidAdDisplayContainer]. + AndroidAdDisplayContainer(super.params) : super.implementation() { + final WeakReference weakThis = + WeakReference(this); + _videoView = _setUpVideoView(weakThis); + _frameLayout.addView(_videoView); + _videoAdPlayer = _setUpVideoAdPlayer(weakThis); + } + + // The duration between each update to the IMA SDK of the progress of the + // currently playing ad. This value matches the one used in the Android + // example. + // See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side#6.-create-the-videoadplayeradapter-class + static const int _progressPollingMs = 250; + + // The `ViewGroup` used to create the native `ima.AdDisplayContainer`. The + // `View` that handles playing an ad is added as a child to this `ViewGroup`. + late final ima.FrameLayout _frameLayout = + _androidParams._imaProxy.newFrameLayout(); + + // Handles loading and displaying an ad. + late ima.VideoView _videoView; + + // After an ad is loaded in the `VideoView`, this is used to control + // playback. + ima.MediaPlayer? _mediaPlayer; + + /// Methods that must be triggered to update the IMA SDK of the state of + /// playback of an ad. + @internal + final Set videoAdPlayerCallbacks = + {}; + + // Handles ad playback callbacks from the IMA SDK. For a player to be used for + // ad playback, the callbacks in this class must be implemented. This also + // provides `VideoAdPlayerCallback`s that contain methods that must be + // triggered by the player. + late final ima.VideoAdPlayer _videoAdPlayer; + + /// The native Android AdDisplayContainer. + /// + /// This holds the player for video ads. + /// + /// Created with the `ViewGroup` that contains the `View` that handles playing + /// an ad. + @internal + ima.AdDisplayContainer? adDisplayContainer; + + // Currently loaded ad. + ima.AdMediaInfo? _loadedAdMediaInfo; + + // The saved ad position, used to resume ad playback following an ad + // click-through. + int _savedAdPosition = 0; + + // Timer used to periodically update the IMA SDK of the progress of the + // currently playing ad. + Timer? _adProgressTimer; + + int? _adDuration; + + // Whether MediaPlayer.start() should be called whenever the VideoView + // `onPrepared` callback is triggered. `onPrepared` is triggered whenever the + // app is resumed after being inactive. + bool _startPlayerWhenVideoIsPrepared = true; + + late final AndroidAdDisplayContainerCreationParams _androidParams = + params is AndroidAdDisplayContainerCreationParams + ? params as AndroidAdDisplayContainerCreationParams + : AndroidAdDisplayContainerCreationParams + .fromPlatformAdDisplayContainerCreationParams(params); + + @override + Widget build(BuildContext context) { + return AndroidViewWidget( + key: params.key, + view: _frameLayout, + platformViewsServiceProxy: _androidParams._platformViewsProxy, + layoutDirection: params.layoutDirection, + onPlatformViewCreated: () async { + adDisplayContainer = await _androidParams._imaProxy + .createAdDisplayContainerImaSdkFactory( + _frameLayout, + _videoAdPlayer, + ); + params.onContainerAdded(this); + }, + ); + } + + // Clears the current `MediaPlayer` and resets any saved position of an ad. + // This should be used when current ad that is loaded in the `VideoView` is + // complete, failed to load/play, or has been stopped. + void _clearMediaPlayer() { + _mediaPlayer = null; + _savedAdPosition = 0; + } + + // Starts periodically updating the IMA SDK the progress of the currently + // playing ad. + // + // Setting a timer to periodically update the IMA SDK is also done in the + // official Android example: https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side#8.-set-up-ad-tracking. + void _startAdProgressTracking() { + // Stop any previous ad tracking. + _stopAdProgressTracking(); + _adProgressTimer = Timer.periodic( + const Duration(milliseconds: _progressPollingMs), + (Timer timer) async { + final ima.VideoProgressUpdate currentProgress = + _androidParams._imaProxy.newVideoProgressUpdate( + currentTimeMs: await _videoView.getCurrentPosition(), + durationMs: _adDuration!, + ); + await Future.wait( + >[ + _videoAdPlayer.setAdProgress(currentProgress), + ...videoAdPlayerCallbacks.map( + (ima.VideoAdPlayerCallback callback) async { + await callback.onAdProgress( + _loadedAdMediaInfo!, + currentProgress, + ); + }, + ), + ], + ); + }, + ); + } + + // Stops updating the IMA SDK the progress of the currently playing ad. + void _stopAdProgressTracking() { + _adProgressTimer?.cancel(); + _adProgressTimer = null; + } + + // This value is created in a static method because the callback methods for + // any wrapped classes must not reference the encapsulating object. This is to + // prevent a circular reference that prevents garbage collection. + static ima.VideoView _setUpVideoView( + WeakReference weakThis, + ) { + return weakThis.target!._androidParams._imaProxy.newVideoView( + onCompletion: (_, __) { + final AndroidAdDisplayContainer? container = weakThis.target; + if (container != null) { + container._clearMediaPlayer(); + container._stopAdProgressTracking(); + for (final ima.VideoAdPlayerCallback callback + in container.videoAdPlayerCallbacks) { + callback.onEnded(container._loadedAdMediaInfo!); + } + } + }, + onPrepared: (_, ima.MediaPlayer player) async { + final AndroidAdDisplayContainer? container = weakThis.target; + if (container != null) { + container._adDuration = await player.getDuration(); + container._mediaPlayer = player; + if (container._savedAdPosition > 0) { + await player.seekTo(container._savedAdPosition); + } + + if (container._startPlayerWhenVideoIsPrepared) { + await player.start(); + container._startAdProgressTracking(); + } + } + }, + onError: (_, __, ___, ____) { + final AndroidAdDisplayContainer? container = weakThis.target; + if (container != null) { + container._clearMediaPlayer(); + for (final ima.VideoAdPlayerCallback callback + in container.videoAdPlayerCallbacks) { + callback.onError(container._loadedAdMediaInfo!); + } + container._loadedAdMediaInfo = null; + container._adDuration = null; + } + }, + ); + } + + // This value is created in a static method because the callback methods for + // any wrapped classes must not reference the encapsulating object. This is to + // prevent a circular reference that prevents garbage collection. + static ima.VideoAdPlayer _setUpVideoAdPlayer( + WeakReference weakThis, + ) { + return weakThis.target!._androidParams._imaProxy.newVideoAdPlayer( + addCallback: (_, ima.VideoAdPlayerCallback callback) { + weakThis.target?.videoAdPlayerCallbacks.add(callback); + }, + removeCallback: (_, ima.VideoAdPlayerCallback callback) { + weakThis.target?.videoAdPlayerCallbacks.remove(callback); + }, + loadAd: (_, ima.AdMediaInfo adMediaInfo, __) { + weakThis.target?._loadedAdMediaInfo = adMediaInfo; + }, + pauseAd: (_, __) async { + final AndroidAdDisplayContainer? container = weakThis.target; + if (container != null) { + // Setting this to false ensures the ad doesn't start playing if an + // app is returned to the foreground. + container._startPlayerWhenVideoIsPrepared = false; + await container._mediaPlayer!.pause(); + container._savedAdPosition = + await container._videoView.getCurrentPosition(); + container._stopAdProgressTracking(); + } + }, + playAd: (_, ima.AdMediaInfo adMediaInfo) { + final AndroidAdDisplayContainer? container = weakThis.target; + if (container != null) { + container._startPlayerWhenVideoIsPrepared = true; + container._videoView.setVideoUri(adMediaInfo.url); + } + }, + release: (_) {}, + stopAd: (_, __) { + final AndroidAdDisplayContainer? container = weakThis.target; + if (container != null) { + // Clear and reset all state. + container._stopAdProgressTracking(); + + container._frameLayout.removeView(container._videoView); + container._videoView = _setUpVideoView( + WeakReference(container), + ); + container._frameLayout.addView(container._videoView); + + container._clearMediaPlayer(); + container._loadedAdMediaInfo = null; + container._adDuration = null; + container._startPlayerWhenVideoIsPrepared = true; + } + }, + ); + } +} diff --git a/packages/interactive_media_ads/lib/src/android/android_ads_loader.dart b/packages/interactive_media_ads/lib/src/android/android_ads_loader.dart new file mode 100644 index 000000000000..2ccbd4b62e04 --- /dev/null +++ b/packages/interactive_media_ads/lib/src/android/android_ads_loader.dart @@ -0,0 +1,149 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import 'package:flutter/widgets.dart'; + +import '../platform_interface/platform_interface.dart'; +import 'android_ad_display_container.dart'; +import 'android_ads_manager.dart'; +import 'android_content_progress_provider.dart'; +import 'enum_converter_utils.dart'; +import 'interactive_media_ads.g.dart' as ima; +import 'interactive_media_ads_proxy.dart'; + +/// Android implementation of [PlatformAdsLoaderCreationParams]. +final class AndroidAdsLoaderCreationParams + extends PlatformAdsLoaderCreationParams { + /// Constructs a [AndroidAdsLoaderCreationParams]. + const AndroidAdsLoaderCreationParams({ + required super.container, + required super.onAdsLoaded, + required super.onAdsLoadError, + @visibleForTesting InteractiveMediaAdsProxy? proxy, + }) : _proxy = proxy ?? const InteractiveMediaAdsProxy(), + super(); + + /// Creates a [AndroidAdsLoaderCreationParams] from an instance of + /// [PlatformAdsLoaderCreationParams]. + factory AndroidAdsLoaderCreationParams.fromPlatformAdsLoaderCreationParams( + PlatformAdsLoaderCreationParams params, { + @visibleForTesting InteractiveMediaAdsProxy? proxy, + }) { + return AndroidAdsLoaderCreationParams( + container: params.container, + onAdsLoaded: params.onAdsLoaded, + onAdsLoadError: params.onAdsLoadError, + proxy: proxy, + ); + } + + final InteractiveMediaAdsProxy _proxy; +} + +/// Android implementation of [PlatformAdsLoader]. +base class AndroidAdsLoader extends PlatformAdsLoader { + /// Constructs an [AndroidAdsLoader]. + AndroidAdsLoader(super.params) + : assert(params.container is AndroidAdDisplayContainer), + assert( + (params.container as AndroidAdDisplayContainer).adDisplayContainer != + null, + 'Ensure the AdDisplayContainer has been added to the Widget tree before creating an AdsLoader.', + ), + super.implementation() { + _adsLoaderFuture = _createAdsLoader(); + } + + late final ima.ImaSdkFactory _sdkFactory = + _androidParams._proxy.instanceImaSdkFactory(); + late Future _adsLoaderFuture; + + late final AndroidAdsLoaderCreationParams _androidParams = + params is AndroidAdsLoaderCreationParams + ? params as AndroidAdsLoaderCreationParams + : AndroidAdsLoaderCreationParams.fromPlatformAdsLoaderCreationParams( + params, + ); + + @override + Future contentComplete() async { + final Set callbacks = + (params.container as AndroidAdDisplayContainer).videoAdPlayerCallbacks; + await Future.wait( + callbacks.map( + (ima.VideoAdPlayerCallback callback) => callback.onContentComplete(), + ), + ); + } + + @override + Future requestAds(PlatformAdsRequest request) async { + final ima.AdsLoader adsLoader = await _adsLoaderFuture; + + final ima.AdsRequest androidRequest = await _sdkFactory.createAdsRequest(); + + await Future.wait(>[ + androidRequest.setAdTagUrl(request.adTagUrl), + if (request.contentProgressProvider != null) + androidRequest.setContentProgressProvider( + (request.contentProgressProvider! as AndroidContentProgressProvider) + .progressProvider, + ), + adsLoader.requestAds(androidRequest), + ]); + } + + Future _createAdsLoader() async { + final ima.ImaSdkSettings settings = + await _sdkFactory.createImaSdkSettings(); + + final ima.AdsLoader adsLoader = await _sdkFactory.createAdsLoader( + settings, + (params.container as AndroidAdDisplayContainer).adDisplayContainer!, + ); + + _addListeners(WeakReference(this), adsLoader); + + return adsLoader; + } + + // This value is created in a static method because the callback methods for + // any wrapped classes must not reference the encapsulating object. This is to + // prevent a circular reference that prevents garbage collection. + static void _addListeners( + WeakReference weakThis, + ima.AdsLoader adsLoader, + ) { + final InteractiveMediaAdsProxy proxy = + weakThis.target!._androidParams._proxy; + adsLoader + ..addAdsLoadedListener(proxy.newAdsLoadedListener( + onAdsManagerLoaded: (_, ima.AdsManagerLoadedEvent event) { + weakThis.target?.params.onAdsLoaded( + PlatformOnAdsLoadedData( + manager: AndroidAdsManager( + event.manager, + proxy: weakThis.target?._androidParams._proxy, + ), + ), + ); + }, + )) + ..addAdErrorListener(proxy.newAdErrorListener( + onAdError: (_, ima.AdErrorEvent event) { + weakThis.target?.params.onAdsLoadError( + AdsLoadErrorData( + error: AdError( + type: toInterfaceErrorType(event.error.errorType), + code: toInterfaceErrorCode(event.error.errorCode), + message: event.error.message, + ), + ), + ); + }, + )); + } +} diff --git a/packages/interactive_media_ads/lib/src/android/android_ads_manager.dart b/packages/interactive_media_ads/lib/src/android/android_ads_manager.dart new file mode 100644 index 000000000000..fbba105e4e27 --- /dev/null +++ b/packages/interactive_media_ads/lib/src/android/android_ads_manager.dart @@ -0,0 +1,107 @@ +// 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:meta/meta.dart'; + +import '../platform_interface/platform_interface.dart'; +import 'enum_converter_utils.dart'; +import 'interactive_media_ads.g.dart' as ima; +import 'interactive_media_ads_proxy.dart'; + +/// Android implementation of [PlatformAdsManager]. +class AndroidAdsManager extends PlatformAdsManager { + /// Constructs an [AndroidAdsManager]. + @internal + AndroidAdsManager( + ima.AdsManager manager, { + InteractiveMediaAdsProxy? proxy, + }) : _manager = manager, + _proxy = proxy ?? const InteractiveMediaAdsProxy(); + + final ima.AdsManager _manager; + final InteractiveMediaAdsProxy _proxy; + + PlatformAdsManagerDelegate? _managerDelegate; + + @override + Future destroy() { + return _manager.destroy(); + } + + @override + Future init(AdsManagerInitParams params) { + return _manager.init(null); + } + + @override + Future setAdsManagerDelegate( + PlatformAdsManagerDelegate delegate, + ) async { + _managerDelegate = delegate; + _addListeners(WeakReference(this)); + } + + @override + Future start(AdsManagerStartParams params) { + return _manager.start(); + } + + @override + Future discardAdBreak() { + return _manager.discardAdBreak(); + } + + @override + Future pause() { + return _manager.pause(); + } + + @override + Future resume() { + return _manager.resume(); + } + + @override + Future skip() { + return _manager.skip(); + } + + // This value is created in a static method because the callback methods for + // any wrapped classes must not reference the encapsulating object. This is to + // prevent a circular reference that prevents garbage collection. + static void _addListeners(WeakReference weakThis) { + final InteractiveMediaAdsProxy proxy = weakThis.target!._proxy; + weakThis.target?._manager.addAdEventListener( + proxy.newAdEventListener( + onAdEvent: (_, ima.AdEvent event) { + weakThis.target?._managerDelegate?.params.onAdEvent?.call( + AdEvent( + type: toInterfaceEventType(event.type), + adData: + event.adData?.cast() ?? {}, + ), + ); + }, + ), + ); + weakThis.target?._manager.addAdErrorListener( + proxy.newAdErrorListener( + onAdError: (_, ima.AdErrorEvent event) { + weakThis.target?._managerDelegate?.params.onAdErrorEvent?.call( + AdErrorEvent( + error: AdError( + type: toInterfaceErrorType(event.error.errorType), + code: toInterfaceErrorCode(event.error.errorCode), + message: event.error.message, + ), + ), + ); + weakThis.target?._manager.discardAdBreak(); + }, + ), + ); + } +} diff --git a/packages/interactive_media_ads/lib/src/android/android_ads_manager_delegate.dart b/packages/interactive_media_ads/lib/src/android/android_ads_manager_delegate.dart new file mode 100644 index 000000000000..24ab7eca9267 --- /dev/null +++ b/packages/interactive_media_ads/lib/src/android/android_ads_manager_delegate.dart @@ -0,0 +1,11 @@ +// 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 '../platform_interface/platform_interface.dart'; + +/// Android implementation of [PlatformAdsManagerDelegate]. +final class AndroidAdsManagerDelegate extends PlatformAdsManagerDelegate { + /// Constructs an [AndroidAdsManagerDelegate]. + AndroidAdsManagerDelegate(super.params) : super.implementation(); +} diff --git a/packages/interactive_media_ads/lib/src/android/android_content_progress_provider.dart b/packages/interactive_media_ads/lib/src/android/android_content_progress_provider.dart new file mode 100644 index 000000000000..e3f4d57c2955 --- /dev/null +++ b/packages/interactive_media_ads/lib/src/android/android_content_progress_provider.dart @@ -0,0 +1,70 @@ +// 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:meta/meta.dart'; + +import '../platform_interface/platform_content_progress_provider.dart'; +import 'interactive_media_ads.g.dart' as ima; +import 'interactive_media_ads_proxy.dart'; + +/// Android implementation of [PlatformContentProgressProviderCreationParams]. +final class AndroidContentProgressProviderCreationParams + extends PlatformContentProgressProviderCreationParams { + /// Constructs a [AndroidContentProgressProviderCreationParams]. + const AndroidContentProgressProviderCreationParams({ + @visibleForTesting InteractiveMediaAdsProxy? proxy, + }) : _proxy = proxy ?? const InteractiveMediaAdsProxy(), + super(); + + /// Creates a [AndroidContentProgressProviderCreationParams] from an instance of + /// [PlatformContentProgressProviderCreationParams]. + factory AndroidContentProgressProviderCreationParams.fromPlatformContentProgressProviderCreationParams( + // Placeholder to prevent requiring a breaking change if params are added to + // PlatformContentProgressProviderCreationParams. + // ignore: avoid_unused_constructor_parameters + PlatformContentProgressProviderCreationParams params, { + @visibleForTesting InteractiveMediaAdsProxy? proxy, + }) { + return AndroidContentProgressProviderCreationParams(proxy: proxy); + } + + final InteractiveMediaAdsProxy _proxy; +} + +/// Android implementation of [PlatformContentProgressProvider]. +base class AndroidContentProgressProvider + extends PlatformContentProgressProvider { + /// Constructs an [AndroidContentProgressProvider]. + AndroidContentProgressProvider(super.params) : super.implementation(); + + /// The native Android ContentProgressProvider. + /// + /// This allows the SDK to track progress of the content video. + @internal + late final ima.ContentProgressProvider progressProvider = + _androidParams._proxy.newContentProgressProvider(); + + late final AndroidContentProgressProviderCreationParams _androidParams = + params is AndroidContentProgressProviderCreationParams + ? params as AndroidContentProgressProviderCreationParams + : AndroidContentProgressProviderCreationParams + .fromPlatformContentProgressProviderCreationParams( + params, + ); + + @override + Future setProgress({ + required Duration progress, + required Duration duration, + }) async { + return progressProvider.setContentProgress( + _androidParams._proxy.newVideoProgressUpdate( + currentTimeMs: progress.inMilliseconds, + durationMs: duration.inMilliseconds, + ), + ); + } +} diff --git a/packages/interactive_media_ads/lib/src/android/android_interactive_media_ads.dart b/packages/interactive_media_ads/lib/src/android/android_interactive_media_ads.dart new file mode 100644 index 000000000000..0f05362a6919 --- /dev/null +++ b/packages/interactive_media_ads/lib/src/android/android_interactive_media_ads.dart @@ -0,0 +1,49 @@ +// 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 '../platform_interface/interactive_media_ads_platform.dart'; +import '../platform_interface/platform_ad_display_container.dart'; +import '../platform_interface/platform_ads_loader.dart'; +import '../platform_interface/platform_ads_manager_delegate.dart'; +import '../platform_interface/platform_content_progress_provider.dart'; +import 'android_ad_display_container.dart'; +import 'android_ads_loader.dart'; +import 'android_ads_manager_delegate.dart'; +import 'android_content_progress_provider.dart'; + +/// Android implementation of [InteractiveMediaAdsPlatform]. +final class AndroidInteractiveMediaAds extends InteractiveMediaAdsPlatform { + /// Registers this class as the default instance of [InteractiveMediaAdsPlatform]. + static void registerWith() { + InteractiveMediaAdsPlatform.instance = AndroidInteractiveMediaAds(); + } + + @override + PlatformAdDisplayContainer createPlatformAdDisplayContainer( + PlatformAdDisplayContainerCreationParams params, + ) { + return AndroidAdDisplayContainer(params); + } + + @override + PlatformAdsLoader createPlatformAdsLoader( + PlatformAdsLoaderCreationParams params, + ) { + return AndroidAdsLoader(params); + } + + @override + PlatformAdsManagerDelegate createPlatformAdsManagerDelegate( + PlatformAdsManagerDelegateCreationParams params, + ) { + return AndroidAdsManagerDelegate(params); + } + + @override + PlatformContentProgressProvider createPlatformContentProgressProvider( + PlatformContentProgressProviderCreationParams params, + ) { + return AndroidContentProgressProvider(params); + } +} diff --git a/packages/interactive_media_ads/lib/src/android/android_view_widget.dart b/packages/interactive_media_ads/lib/src/android/android_view_widget.dart new file mode 100644 index 000000000000..3d6f9b8e6fc0 --- /dev/null +++ b/packages/interactive_media_ads/lib/src/android/android_view_widget.dart @@ -0,0 +1,106 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/foundation.dart'; +import 'package:flutter/gestures.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; + +import 'interactive_media_ads.g.dart' as ima; +import 'platform_views_service_proxy.dart'; + +/// Represents a Flutter implementation of the Android [View](https://developer.android.com/reference/android/view/View) +/// that is created by the Android platform. +class AndroidViewWidget extends StatelessWidget { + /// Creates a [AndroidViewWidget]. + /// + /// The [AndroidViewWidget] should only be instantiated internally. + /// This constructor is visible for testing purposes only and should + /// never be called externally. + AndroidViewWidget({ + super.key, + required this.view, + this.layoutDirection = TextDirection.ltr, + this.onPlatformViewCreated, + this.displayWithHybridComposition = false, + ima.PigeonInstanceManager? instanceManager, + this.platformViewsServiceProxy = const PlatformViewsServiceProxy(), + }) : instanceManager = instanceManager ?? ima.PigeonInstanceManager.instance; + + /// The unique identifier for the view type to be embedded. + static const String _viewType = + 'interactive_media_ads.packages.flutter.dev/view'; + + /// The reference to the Android native view that should be shown. + final ima.View view; + + /// Maintains instances used to communicate with the native objects they + /// represent. + /// + /// This field is exposed for testing purposes only and should not be used + /// outside of tests. + final ima.PigeonInstanceManager instanceManager; + + /// Proxy that provides access to the platform views service. + /// + /// This service allows creating and controlling platform-specific views. + final PlatformViewsServiceProxy platformViewsServiceProxy; + + /// Whether to use Hybrid Composition to display the Android View. + final bool displayWithHybridComposition; + + /// Layout direction used by the Android View. + final TextDirection layoutDirection; + + /// Callback that will get invoke after the platform view has been created. + final VoidCallback? onPlatformViewCreated; + + @override + Widget build(BuildContext context) { + return PlatformViewLink( + viewType: _viewType, + surfaceFactory: ( + BuildContext context, + PlatformViewController controller, + ) { + return AndroidViewSurface( + controller: controller as AndroidViewController, + hitTestBehavior: PlatformViewHitTestBehavior.opaque, + gestureRecognizers: const >{}, + ); + }, + onCreatePlatformView: (PlatformViewCreationParams params) { + return _initAndroidView(params) + ..addOnPlatformViewCreatedListener((int id) { + params.onPlatformViewCreated(id); + onPlatformViewCreated?.call(); + }) + ..create(); + }, + ); + } + + AndroidViewController _initAndroidView(PlatformViewCreationParams params) { + final int? identifier = instanceManager.getIdentifier(view); + + if (displayWithHybridComposition) { + return platformViewsServiceProxy.initExpensiveAndroidView( + id: params.id, + viewType: _viewType, + layoutDirection: layoutDirection, + creationParams: identifier, + creationParamsCodec: const StandardMessageCodec(), + ); + } else { + return platformViewsServiceProxy.initSurfaceAndroidView( + id: params.id, + viewType: _viewType, + layoutDirection: layoutDirection, + creationParams: identifier, + creationParamsCodec: const StandardMessageCodec(), + ); + } + } +} diff --git a/packages/interactive_media_ads/lib/src/android/enum_converter_utils.dart b/packages/interactive_media_ads/lib/src/android/enum_converter_utils.dart new file mode 100644 index 000000000000..46fbe72ec204 --- /dev/null +++ b/packages/interactive_media_ads/lib/src/android/enum_converter_utils.dart @@ -0,0 +1,91 @@ +// 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 '../platform_interface/platform_interface.dart'; +import 'interactive_media_ads.g.dart' as ima; + +/// Converts [ima.AdErrorType] to [AdErrorType]. +AdErrorType toInterfaceErrorType(ima.AdErrorType type) { + return switch (type) { + ima.AdErrorType.load => AdErrorType.loading, + ima.AdErrorType.play => AdErrorType.playing, + ima.AdErrorType.unknown => AdErrorType.unknown, + }; +} + +/// Attempts to convert an [ima.AdEventType] to [AdEventType]. +/// +/// Returns null is the type is not supported by the platform interface. +AdEventType toInterfaceEventType(ima.AdEventType type) { + return switch (type) { + ima.AdEventType.allAdsCompleted => AdEventType.allAdsCompleted, + ima.AdEventType.completed => AdEventType.complete, + ima.AdEventType.contentPauseRequested => AdEventType.contentPauseRequested, + ima.AdEventType.contentResumeRequested => + AdEventType.contentResumeRequested, + ima.AdEventType.loaded => AdEventType.loaded, + ima.AdEventType.clicked => AdEventType.clicked, + ima.AdEventType.adBreakEnded => AdEventType.adBreakEnded, + ima.AdEventType.adBreakFetchError => AdEventType.adBreakFetchError, + ima.AdEventType.adBreakReady => AdEventType.adBreakReady, + ima.AdEventType.adBreakStarted => AdEventType.adBreakStarted, + ima.AdEventType.adBuffering => AdEventType.adBuffering, + ima.AdEventType.adPeriodEnded => AdEventType.adPeriodEnded, + ima.AdEventType.adPeriodStarted => AdEventType.adPeriodStarted, + ima.AdEventType.adProgress => AdEventType.adProgress, + ima.AdEventType.cuepointsChanged => AdEventType.cuepointsChanged, + ima.AdEventType.firstQuartile => AdEventType.firstQuartile, + ima.AdEventType.iconFallbackImageClosed => + AdEventType.iconFallbackImageClosed, + ima.AdEventType.iconTapped => AdEventType.iconTapped, + ima.AdEventType.log => AdEventType.log, + ima.AdEventType.midpoint => AdEventType.midpoint, + ima.AdEventType.paused => AdEventType.paused, + ima.AdEventType.resumed => AdEventType.resumed, + ima.AdEventType.skippableStateChanged => AdEventType.skippableStateChanged, + ima.AdEventType.skipped => AdEventType.skipped, + ima.AdEventType.started => AdEventType.started, + ima.AdEventType.tapped => AdEventType.tapped, + ima.AdEventType.thirdQuartile => AdEventType.thirdQuartile, + ima.AdEventType.unknown => AdEventType.unknown, + }; +} + +/// Converts [ima.AdErrorCode] to [AdErrorCode]. +AdErrorCode toInterfaceErrorCode(ima.AdErrorCode code) { + return switch (code) { + ima.AdErrorCode.adsPlayerWasNotProvided => AdErrorCode.adsPlayerNotProvided, + ima.AdErrorCode.adsRequestNetworkError => + AdErrorCode.adsRequestNetworkError, + ima.AdErrorCode.companionAdLoadingFailed => + AdErrorCode.companionAdLoadingFailed, + ima.AdErrorCode.failedToRequestAds => AdErrorCode.failedToRequestAds, + ima.AdErrorCode.internalError => AdErrorCode.internalError, + ima.AdErrorCode.invalidArguments => AdErrorCode.invalidArguments, + ima.AdErrorCode.overlayAdLoadingFailed => + AdErrorCode.overlayAdLoadingFailed, + ima.AdErrorCode.overlayAdPlayingFailed => + AdErrorCode.overlayAdPlayingFailed, + ima.AdErrorCode.playlistNoContentTracking => + AdErrorCode.playlistNoContentTracking, + ima.AdErrorCode.unexpectedAdsLoadedEvent => + AdErrorCode.unexpectedAdsLoadedEvent, + ima.AdErrorCode.unknownAdResponse => AdErrorCode.unknownAdResponse, + ima.AdErrorCode.unknownError => AdErrorCode.unknownError, + ima.AdErrorCode.vastAssetNotFound => AdErrorCode.vastAssetNotFound, + ima.AdErrorCode.vastEmptyResponse => AdErrorCode.vastEmptyResponse, + ima.AdErrorCode.vastLinearAssetMismatch => + AdErrorCode.vastLinearAssetMismatch, + ima.AdErrorCode.vastLoadTimeout => AdErrorCode.vastLoadTimeout, + ima.AdErrorCode.vastMalformedResponse => AdErrorCode.vastMalformedResponse, + ima.AdErrorCode.vastMediaLoadTimeout => AdErrorCode.vastMediaLoadTimeout, + ima.AdErrorCode.vastNonlinearAssetMismatch => + AdErrorCode.vastNonlinearAssetMismatch, + ima.AdErrorCode.vastNoAdsAfterWrapper => AdErrorCode.vastNoAdsAfterWrapper, + ima.AdErrorCode.vastTooManyRedirects => AdErrorCode.vastTooManyRedirects, + ima.AdErrorCode.vastTraffickingError => AdErrorCode.vastTraffickingError, + ima.AdErrorCode.videoPlayError => AdErrorCode.videoPlayError, + ima.AdErrorCode.unknown => AdErrorCode.unknownError, + }; +} diff --git a/packages/interactive_media_ads/lib/src/android/interactive_media_ads.g.dart b/packages/interactive_media_ads/lib/src/android/interactive_media_ads.g.dart new file mode 100644 index 000000000000..330cf444e2f6 --- /dev/null +++ b/packages/interactive_media_ads/lib/src/android/interactive_media_ads.g.dart @@ -0,0 +1,6395 @@ +// 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 (v22.5.0), 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 + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; + +import 'package:flutter/foundation.dart' + show ReadBuffer, WriteBuffer, immutable, protected; +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart' show WidgetsFlutterBinding; + +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); +} + +List wrapResponse( + {Object? result, PlatformException? error, bool empty = false}) { + if (empty) { + return []; + } + if (error == null) { + return [result]; + } + return [error.code, error.message, error.details]; +} + +/// An immutable object that serves as the base class for all ProxyApis and +/// can provide functional copies of itself. +/// +/// All implementers are expected to be [immutable] as defined by the annotation +/// and override [pigeon_copy] returning an instance of itself. +@immutable +abstract class PigeonInternalProxyApiBaseClass { + /// Construct a [PigeonInternalProxyApiBaseClass]. + PigeonInternalProxyApiBaseClass({ + this.pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + }) : pigeon_instanceManager = + pigeon_instanceManager ?? PigeonInstanceManager.instance; + + /// Sends and receives binary data across the Flutter platform barrier. + /// + /// If it is null, the default BinaryMessenger will be used, which routes to + /// the host platform. + @protected + final BinaryMessenger? pigeon_binaryMessenger; + + /// Maintains instances stored to communicate with native language objects. + @protected + final PigeonInstanceManager pigeon_instanceManager; + + /// Instantiates and returns a functionally identical object to oneself. + /// + /// Outside of tests, this method should only ever be called by + /// [PigeonInstanceManager]. + /// + /// Subclasses should always override their parent's implementation of this + /// method. + @protected + PigeonInternalProxyApiBaseClass pigeon_copy(); +} + +/// Maintains instances used to communicate with the native objects they +/// represent. +/// +/// Added instances are stored as weak references and their copies are stored +/// as strong references to maintain access to their variables and callback +/// methods. Both are stored with the same identifier. +/// +/// When a weak referenced instance becomes inaccessible, +/// [onWeakReferenceRemoved] is called with its associated identifier. +/// +/// If an instance is retrieved and has the possibility to be used, +/// (e.g. calling [getInstanceWithWeakReference]) a copy of the strong reference +/// is added as a weak reference with the same identifier. This prevents a +/// scenario where the weak referenced instance was released and then later +/// returned by the host platform. +class PigeonInstanceManager { + /// Constructs a [PigeonInstanceManager]. + PigeonInstanceManager({required void Function(int) onWeakReferenceRemoved}) { + this.onWeakReferenceRemoved = (int identifier) { + _weakInstances.remove(identifier); + onWeakReferenceRemoved(identifier); + }; + _finalizer = Finalizer(this.onWeakReferenceRemoved); + } + + // Identifiers are locked to a specific range to avoid collisions with objects + // created simultaneously by the host platform. + // Host uses identifiers >= 2^16 and Dart is expected to use values n where, + // 0 <= n < 2^16. + static const int _maxDartCreatedIdentifier = 65536; + + /// The default [PigeonInstanceManager] used by ProxyApis. + /// + /// On creation, this manager makes a call to clear the native + /// InstanceManager. This is to prevent identifier conflicts after a host + /// restart. + static final PigeonInstanceManager instance = _initInstance(); + + // Expando is used because it doesn't prevent its keys from becoming + // inaccessible. This allows the manager to efficiently retrieve an identifier + // of an instance without holding a strong reference to that instance. + // + // It also doesn't use `==` to search for identifiers, which would lead to an + // infinite loop when comparing an object to its copy. (i.e. which was caused + // by calling instanceManager.getIdentifier() inside of `==` while this was a + // HashMap). + final Expando _identifiers = Expando(); + final Map> + _weakInstances = >{}; + final Map _strongInstances = + {}; + late final Finalizer _finalizer; + int _nextIdentifier = 0; + + /// Called when a weak referenced instance is removed by [removeWeakReference] + /// or becomes inaccessible. + late final void Function(int) onWeakReferenceRemoved; + + static PigeonInstanceManager _initInstance() { + WidgetsFlutterBinding.ensureInitialized(); + final _PigeonInternalInstanceManagerApi api = + _PigeonInternalInstanceManagerApi(); + // Clears the native `PigeonInstanceManager` on the initial use of the Dart one. + api.clear(); + final PigeonInstanceManager instanceManager = PigeonInstanceManager( + onWeakReferenceRemoved: (int identifier) { + api.removeStrongReference(identifier); + }, + ); + _PigeonInternalInstanceManagerApi.setUpMessageHandlers( + instanceManager: instanceManager); + BaseDisplayContainer.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + AdDisplayContainer.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + AdsLoader.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + AdsManagerLoadedEvent.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + AdErrorEvent.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + AdError.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + AdsRequest.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + ContentProgressProvider.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + AdsManager.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + BaseManager.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + AdEvent.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + ImaSdkFactory.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + ImaSdkSettings.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + VideoProgressUpdate.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + AdMediaInfo.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + AdPodInfo.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + FrameLayout.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + ViewGroup.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + VideoView.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + View.pigeon_setUpMessageHandlers(pigeon_instanceManager: instanceManager); + MediaPlayer.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + VideoAdPlayerCallback.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + VideoAdPlayer.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + AdsLoadedListener.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + AdErrorListener.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + AdEventListener.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + AdsRenderingSettings.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + AdProgressInfo.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + CompanionAd.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + UniversalAdId.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + Ad.pigeon_setUpMessageHandlers(pigeon_instanceManager: instanceManager); + return instanceManager; + } + + /// Adds a new instance that was instantiated by Dart. + /// + /// In other words, Dart wants to add a new instance that will represent + /// an object that will be instantiated on the host platform. + /// + /// Throws assertion error if the instance has already been added. + /// + /// Returns the randomly generated id of the [instance] added. + int addDartCreatedInstance(PigeonInternalProxyApiBaseClass instance) { + final int identifier = _nextUniqueIdentifier(); + _addInstanceWithIdentifier(instance, identifier); + return identifier; + } + + /// Removes the instance, if present, and call [onWeakReferenceRemoved] with + /// its identifier. + /// + /// Returns the identifier associated with the removed instance. Otherwise, + /// `null` if the instance was not found in this manager. + /// + /// This does not remove the strong referenced instance associated with + /// [instance]. This can be done with [remove]. + int? removeWeakReference(PigeonInternalProxyApiBaseClass instance) { + final int? identifier = getIdentifier(instance); + if (identifier == null) { + return null; + } + + _identifiers[instance] = null; + _finalizer.detach(instance); + onWeakReferenceRemoved(identifier); + + return identifier; + } + + /// Removes [identifier] and its associated strongly referenced instance, if + /// present, from the manager. + /// + /// Returns the strong referenced instance associated with [identifier] before + /// it was removed. Returns `null` if [identifier] was not associated with + /// any strong reference. + /// + /// This does not remove the weak referenced instance associated with + /// [identifier]. This can be done with [removeWeakReference]. + T? remove(int identifier) { + return _strongInstances.remove(identifier) as T?; + } + + /// Retrieves the instance associated with identifier. + /// + /// The value returned is chosen from the following order: + /// + /// 1. A weakly referenced instance associated with identifier. + /// 2. If the only instance associated with identifier is a strongly + /// referenced instance, a copy of the instance is added as a weak reference + /// with the same identifier. Returning the newly created copy. + /// 3. If no instance is associated with identifier, returns null. + /// + /// This method also expects the host `InstanceManager` to have a strong + /// reference to the instance the identifier is associated with. + T? getInstanceWithWeakReference( + int identifier) { + final PigeonInternalProxyApiBaseClass? weakInstance = + _weakInstances[identifier]?.target; + + if (weakInstance == null) { + final PigeonInternalProxyApiBaseClass? strongInstance = + _strongInstances[identifier]; + if (strongInstance != null) { + final PigeonInternalProxyApiBaseClass copy = + strongInstance.pigeon_copy(); + _identifiers[copy] = identifier; + _weakInstances[identifier] = + WeakReference(copy); + _finalizer.attach(copy, identifier, detach: copy); + return copy as T; + } + return strongInstance as T?; + } + + return weakInstance as T; + } + + /// Retrieves the identifier associated with instance. + int? getIdentifier(PigeonInternalProxyApiBaseClass instance) { + return _identifiers[instance]; + } + + /// Adds a new instance that was instantiated by the host platform. + /// + /// In other words, the host platform wants to add a new instance that + /// represents an object on the host platform. Stored with [identifier]. + /// + /// Throws assertion error if the instance or its identifier has already been + /// added. + /// + /// Returns unique identifier of the [instance] added. + void addHostCreatedInstance( + PigeonInternalProxyApiBaseClass instance, int identifier) { + _addInstanceWithIdentifier(instance, identifier); + } + + void _addInstanceWithIdentifier( + PigeonInternalProxyApiBaseClass instance, int identifier) { + assert(!containsIdentifier(identifier)); + assert(getIdentifier(instance) == null); + assert(identifier >= 0); + + _identifiers[instance] = identifier; + _weakInstances[identifier] = + WeakReference(instance); + _finalizer.attach(instance, identifier, detach: instance); + + final PigeonInternalProxyApiBaseClass copy = instance.pigeon_copy(); + _identifiers[copy] = identifier; + _strongInstances[identifier] = copy; + } + + /// Whether this manager contains the given [identifier]. + bool containsIdentifier(int identifier) { + return _weakInstances.containsKey(identifier) || + _strongInstances.containsKey(identifier); + } + + int _nextUniqueIdentifier() { + late int identifier; + do { + identifier = _nextIdentifier; + _nextIdentifier = (_nextIdentifier + 1) % _maxDartCreatedIdentifier; + } while (containsIdentifier(identifier)); + return identifier; + } +} + +/// Generated API for managing the Dart and native `PigeonInstanceManager`s. +class _PigeonInternalInstanceManagerApi { + /// Constructor for [_PigeonInternalInstanceManagerApi]. + _PigeonInternalInstanceManagerApi({BinaryMessenger? binaryMessenger}) + : pigeonVar_binaryMessenger = binaryMessenger; + + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + static void setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? binaryMessenger, + PigeonInstanceManager? instanceManager, + }) { + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.PigeonInternalInstanceManager.removeStrongReference', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.PigeonInternalInstanceManager.removeStrongReference was null.'); + final List args = (message as List?)!; + final int? arg_identifier = (args[0] as int?); + assert(arg_identifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.PigeonInternalInstanceManager.removeStrongReference was null, expected non-null int.'); + try { + (instanceManager ?? PigeonInstanceManager.instance) + .remove(arg_identifier!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + Future removeStrongReference(int identifier) async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.PigeonInternalInstanceManager.removeStrongReference'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([identifier]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Clear the native `PigeonInstanceManager`. + /// + /// This is typically called after a hot restart. + Future clear() async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.PigeonInternalInstanceManager.clear'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } +} + +class _PigeonInternalProxyApiBaseCodec extends _PigeonCodec { + const _PigeonInternalProxyApiBaseCodec(this.instanceManager); + final PigeonInstanceManager instanceManager; + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is PigeonInternalProxyApiBaseClass) { + buffer.putUint8(128); + writeValue(buffer, instanceManager.getIdentifier(value)); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 128: + return instanceManager + .getInstanceWithWeakReference(readValue(buffer)! as int); + default: + return super.readValueOfType(type, buffer); + } + } +} + +/// The types of error that can be encountered. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdError.AdErrorCode.html. +enum AdErrorCode { + /// Ads player was not provided. + adsPlayerWasNotProvided, + + /// There was a problem requesting ads from the server. + adsRequestNetworkError, + + /// A companion ad failed to load or render. + companionAdLoadingFailed, + + /// There was a problem requesting ads from the server. + failedToRequestAds, + + /// An error internal to the SDK occurred. + internalError, + + /// Invalid arguments were provided to SDK methods. + invalidArguments, + + /// An overlay ad failed to load. + overlayAdLoadingFailed, + + /// An overlay ad failed to render. + overlayAdPlayingFailed, + + /// Ads list was returned but ContentProgressProvider was not configured. + playlistNoContentTracking, + + /// Ads loader sent ads loaded event when it was not expected. + unexpectedAdsLoadedEvent, + + /// The ad response was not understood and cannot be parsed. + unknownAdResponse, + + /// An unexpected error occurred and the cause is not known. + unknownError, + + /// No assets were found in the VAST ad response. + vastAssetNotFound, + + /// A VAST response containing a single `` tag with no child tags. + vastEmptyResponse, + + /// Assets were found in the VAST ad response for a linear ad, but none of + /// them matched the video player's capabilities. + vastLinearAssetMismatch, + + /// At least one VAST wrapper ad loaded successfully and a subsequent wrapper + /// or inline ad load has timed out. + vastLoadTimeout, + + /// The ad response was not recognized as a valid VAST ad. + vastMalformedResponse, + + /// Failed to load media assets from a VAST response. + vastMediaLoadTimeout, + + /// Assets were found in the VAST ad response for a nonlinear ad, but none of + /// them matched the video player's capabilities. + vastNonlinearAssetMismatch, + + /// No Ads VAST response after one or more wrappers. + vastNoAdsAfterWrapper, + + /// The maximum number of VAST wrapper redirects has been reached. + vastTooManyRedirects, + + /// Trafficking error. + /// + /// Video player received an ad type that it was not expecting and/or cannot + /// display. + vastTraffickingError, + + /// There was an error playing the video ad. + videoPlayError, + + /// The error code is not recognized by this wrapper. + unknown, +} + +/// Specifies when the error was encountered, during either ad loading or playback. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdError.AdErrorType.html. +enum AdErrorType { + /// Indicates that the error was encountered when the ad was being loaded. + load, + + /// Indicates that the error was encountered after the ad loaded, during ad play. + play, + + /// The error is not recognized by this wrapper. + unknown, +} + +/// Types of events that can occur during ad playback. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdEvent.AdEventType.html. +enum AdEventType { + /// Fired when an ad break in a stream ends. + adBreakEnded, + + /// Fired when an ad break will not play back any ads. + adBreakFetchError, + + /// Fired when an ad break is ready from VMAP or ad rule ads. + adBreakReady, + + /// Fired when an ad break in a stream starts. + adBreakStarted, + + /// Fired when playback stalls while the ad buffers. + adBuffering, + + /// Fired when an ad period in a stream ends. + adPeriodEnded, + + /// Fired when an ad period in a stream starts. + adPeriodStarted, + + /// Fired to inform of ad progress and can be used by publisher to display a + /// countdown timer. + adProgress, + + /// Fired when the ads manager is done playing all the valid ads in the ads + /// response, or when the response doesn't return any valid ads. + allAdsCompleted, + + /// Fired when an ad is clicked. + clicked, + + /// Fired when an ad completes playing. + completed, + + /// Fired when content should be paused. + contentPauseRequested, + + /// Fired when content should be resumed. + contentResumeRequested, + + /// Fired when VOD stream cuepoints have changed. + cuepointsChanged, + + /// Fired when the ad playhead crosses first quartile. + firstQuartile, + + /// The user has closed the icon fallback image dialog. + iconFallbackImageClosed, + + /// The user has tapped an ad icon. + iconTapped, + + /// Fired when the VAST response has been received. + loaded, + + /// Fired to enable the SDK to communicate a message to be logged, which is + /// stored in adData. + log, + + /// Fired when the ad playhead crosses midpoint. + midpoint, + + /// Fired when an ad is paused. + paused, + + /// Fired when an ad is resumed. + resumed, + + /// Fired when an ad changes its skippable state. + skippableStateChanged, + + /// Fired when an ad was skipped. + skipped, + + /// Fired when an ad starts playing. + started, + + /// Fired when a non-clickthrough portion of a video ad is clicked. + tapped, + + /// Fired when the ad playhead crosses third quartile. + thirdQuartile, + + /// The event type is not recognized by this wrapper. + unknown, +} + +/// Describes an element of the ad UI, to be requested or rendered by the SDK. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/UiElement.html. +enum UiElement { + /// The ad attribution UI element, for example, "Ad". + adAttribution, + + /// Ad attribution is required for a countdown timer to be displayed. + countdown, + + /// The element is not recognized by this wrapper. + unknown, +} + +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is AdErrorCode) { + buffer.putUint8(129); + writeValue(buffer, value.index); + } else if (value is AdErrorType) { + buffer.putUint8(130); + writeValue(buffer, value.index); + } else if (value is AdEventType) { + buffer.putUint8(131); + writeValue(buffer, value.index); + } else if (value is UiElement) { + buffer.putUint8(132); + writeValue(buffer, value.index); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 129: + final int? value = readValue(buffer) as int?; + return value == null ? null : AdErrorCode.values[value]; + case 130: + final int? value = readValue(buffer) as int?; + return value == null ? null : AdErrorType.values[value]; + case 131: + final int? value = readValue(buffer) as int?; + return value == null ? null : AdEventType.values[value]; + case 132: + final int? value = readValue(buffer) as int?; + return value == null ? null : UiElement.values[value]; + default: + return super.readValueOfType(type, buffer); + } + } +} + +/// A base class for more specialized container interfaces. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/BaseDisplayContainer.html. +class BaseDisplayContainer extends PigeonInternalProxyApiBaseClass { + /// Constructs [BaseDisplayContainer] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + BaseDisplayContainer.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + BaseDisplayContainer Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.BaseDisplayContainer.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.BaseDisplayContainer.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.BaseDisplayContainer.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + BaseDisplayContainer.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + BaseDisplayContainer pigeon_copy() { + return BaseDisplayContainer.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// A container in which to display the ads. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdDisplayContainer. +class AdDisplayContainer extends PigeonInternalProxyApiBaseClass + implements BaseDisplayContainer { + /// Constructs [AdDisplayContainer] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + AdDisplayContainer.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + AdDisplayContainer Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.AdDisplayContainer.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdDisplayContainer.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdDisplayContainer.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + AdDisplayContainer.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + AdDisplayContainer pigeon_copy() { + return AdDisplayContainer.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// An object which allows publishers to request ads from ad servers or a +/// dynamic ad insertion stream. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdsLoader. +class AdsLoader extends PigeonInternalProxyApiBaseClass { + /// Constructs [AdsLoader] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + AdsLoader.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }); + + late final _PigeonInternalProxyApiBaseCodec _pigeonVar_codecAdsLoader = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + AdsLoader Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.AdsLoader.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdsLoader.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdsLoader.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + AdsLoader.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + /// Registers a listener for errors that occur during the ads request. + Future addAdErrorListener(AdErrorListener listener) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsLoader; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsLoader.addAdErrorListener'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, listener]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Registers a listener for the ads manager loaded event. + Future addAdsLoadedListener(AdsLoadedListener listener) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsLoader; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsLoader.addAdsLoadedListener'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, listener]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Requests ads from a server. + Future requestAds(AdsRequest request) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsLoader; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsLoader.requestAds'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, request]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + @override + AdsLoader pigeon_copy() { + return AdsLoader.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// An event raised when ads are successfully loaded from the ad server through an AdsLoader. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdsManagerLoadedEvent.html. +class AdsManagerLoadedEvent extends PigeonInternalProxyApiBaseClass { + /// Constructs [AdsManagerLoadedEvent] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + AdsManagerLoadedEvent.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.manager, + }); + + /// The ads manager that will control playback of the loaded ads, or null when + /// using dynamic ad insertion. + final AdsManager manager; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + AdsManagerLoadedEvent Function(AdsManager manager)? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.AdsManagerLoadedEvent.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdsManagerLoadedEvent.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdsManagerLoadedEvent.pigeon_newInstance was null, expected non-null int.'); + final AdsManager? arg_manager = (args[1] as AdsManager?); + assert(arg_manager != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdsManagerLoadedEvent.pigeon_newInstance was null, expected non-null AdsManager.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call(arg_manager!) ?? + AdsManagerLoadedEvent.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + manager: arg_manager!, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + AdsManagerLoadedEvent pigeon_copy() { + return AdsManagerLoadedEvent.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + manager: manager, + ); + } +} + +/// An event raised when there is an error loading or playing ads. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdErrorEvent.html. +class AdErrorEvent extends PigeonInternalProxyApiBaseClass { + /// Constructs [AdErrorEvent] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + AdErrorEvent.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.error, + }); + + /// The AdError that caused this event. + final AdError error; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + AdErrorEvent Function(AdError error)? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.AdErrorEvent.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdErrorEvent.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdErrorEvent.pigeon_newInstance was null, expected non-null int.'); + final AdError? arg_error = (args[1] as AdError?); + assert(arg_error != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdErrorEvent.pigeon_newInstance was null, expected non-null AdError.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call(arg_error!) ?? + AdErrorEvent.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + error: arg_error!, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + AdErrorEvent pigeon_copy() { + return AdErrorEvent.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + error: error, + ); + } +} + +/// An error that occurred in the SDK. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdError.html. +class AdError extends PigeonInternalProxyApiBaseClass { + /// Constructs [AdError] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + AdError.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.errorCode, + required this.errorCodeNumber, + required this.errorType, + required this.message, + }); + + /// The error's code. + final AdErrorCode errorCode; + + /// The error code's number. + final int errorCodeNumber; + + /// The error's type. + final AdErrorType errorType; + + /// A human-readable summary of the error. + final String message; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + AdError Function( + AdErrorCode errorCode, + int errorCodeNumber, + AdErrorType errorType, + String message, + )? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.AdError.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdError.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdError.pigeon_newInstance was null, expected non-null int.'); + final AdErrorCode? arg_errorCode = (args[1] as AdErrorCode?); + assert(arg_errorCode != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdError.pigeon_newInstance was null, expected non-null AdErrorCode.'); + final int? arg_errorCodeNumber = (args[2] as int?); + assert(arg_errorCodeNumber != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdError.pigeon_newInstance was null, expected non-null int.'); + final AdErrorType? arg_errorType = (args[3] as AdErrorType?); + assert(arg_errorType != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdError.pigeon_newInstance was null, expected non-null AdErrorType.'); + final String? arg_message = (args[4] as String?); + assert(arg_message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdError.pigeon_newInstance was null, expected non-null String.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call(arg_errorCode!, arg_errorCodeNumber!, + arg_errorType!, arg_message!) ?? + AdError.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + errorCode: arg_errorCode!, + errorCodeNumber: arg_errorCodeNumber!, + errorType: arg_errorType!, + message: arg_message!, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + AdError pigeon_copy() { + return AdError.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + errorCode: errorCode, + errorCodeNumber: errorCodeNumber, + errorType: errorType, + message: message, + ); + } +} + +/// An object containing the data used to request ads from the server. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdsRequest. +class AdsRequest extends PigeonInternalProxyApiBaseClass { + /// Constructs [AdsRequest] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + AdsRequest.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }); + + late final _PigeonInternalProxyApiBaseCodec _pigeonVar_codecAdsRequest = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + AdsRequest Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.AdsRequest.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdsRequest.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdsRequest.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + AdsRequest.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + /// Sets the URL from which ads will be requested. + Future setAdTagUrl(String adTagUrl) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsRequest; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsRequest.setAdTagUrl'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, adTagUrl]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Attaches a ContentProgressProvider instance to allow scheduling ad breaks + /// based on content progress (cue points). + Future setContentProgressProvider( + ContentProgressProvider provider) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsRequest; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsRequest.setContentProgressProvider'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, provider]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + @override + AdsRequest pigeon_copy() { + return AdsRequest.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// Defines an interface to allow SDK to track progress of the content video. +/// +/// See https://developers.google.com/ad-manager/dynamic-ad-insertion/sdk/android/api/reference/com/google/ads/interactivemedia/v3/api/player/ContentProgressProvider.html. +class ContentProgressProvider extends PigeonInternalProxyApiBaseClass { + ContentProgressProvider({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }) { + final int pigeonVar_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(this); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecContentProgressProvider; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + () async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.ContentProgressProvider.pigeon_defaultConstructor'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([pigeonVar_instanceIdentifier]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + }(); + } + + /// Constructs [ContentProgressProvider] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + ContentProgressProvider.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }); + + late final _PigeonInternalProxyApiBaseCodec + _pigeonVar_codecContentProgressProvider = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + ContentProgressProvider Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.ContentProgressProvider.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.ContentProgressProvider.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.ContentProgressProvider.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + ContentProgressProvider.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + /// Sets an update on the progress of the video. + /// + /// This is a custom method added to the native class because the native + /// method `getContentProgress` requires a synchronous return value. + Future setContentProgress(VideoProgressUpdate update) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecContentProgressProvider; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.ContentProgressProvider.setContentProgress'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, update]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + @override + ContentProgressProvider pigeon_copy() { + return ContentProgressProvider.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// An object which handles playing ads after they've been received from the +/// server. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdsManager. +class AdsManager extends BaseManager { + /// Constructs [AdsManager] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + AdsManager.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }) : super.pigeon_detached(); + + late final _PigeonInternalProxyApiBaseCodec _pigeonVar_codecAdsManager = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + AdsManager Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.AdsManager.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdsManager.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdsManager.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + AdsManager.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + /// Discards current ad break and resumes content. + Future discardAdBreak() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsManager; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsManager.discardAdBreak'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Pauses the current ad. + Future pause() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsManager; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsManager.pause'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Starts playing the ads. + Future start() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsManager; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsManager.start'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// List of content time offsets in seconds at which ad breaks are scheduled. + /// + /// The list will be empty if no ad breaks are scheduled. + Future> getAdCuePoints() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsManager; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsManager.getAdCuePoints'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as List?)!.cast(); + } + } + + /// Resumes the current ad. + Future resume() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsManager; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsManager.resume'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Skips the current ad. + /// + /// `AdsManager.skip()` only skips ads if IMA does not render the 'Skip ad' + /// button. + Future skip() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsManager; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsManager.skip'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + @override + AdsManager pigeon_copy() { + return AdsManager.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// Base interface for managing ads.. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/BaseManager.html. +class BaseManager extends PigeonInternalProxyApiBaseClass { + /// Constructs [BaseManager] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + BaseManager.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }); + + late final _PigeonInternalProxyApiBaseCodec _pigeonVar_codecBaseManager = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + BaseManager Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.BaseManager.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.BaseManager.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.BaseManager.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + BaseManager.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + /// Registers a listener for errors that occur during the ad or stream + /// initialization and playback. + Future addAdErrorListener(AdErrorListener errorListener) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecBaseManager; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.BaseManager.addAdErrorListener'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, errorListener]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Registers a listener for ad events that occur during ad or stream + /// initialization and playback. + Future addAdEventListener(AdEventListener adEventListener) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecBaseManager; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.BaseManager.addAdEventListener'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, adEventListener]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Stops the ad and all tracking, then releases all assets that were loaded + /// to play the ad. + Future destroy() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecBaseManager; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.BaseManager.destroy'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Initializes the ad experience on the manager. + Future init(AdsRenderingSettings? settings) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecBaseManager; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.BaseManager.init'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, settings]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Generic focus endpoint that puts focus on the skip button if present. + Future focus() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecBaseManager; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.BaseManager.focus'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Returns the latest AdProgressInfo for the current playing ad. + Future getAdProgressInfo() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecBaseManager; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.BaseManager.getAdProgressInfo'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as AdProgressInfo?); + } + } + + /// Get currently playing ad. + Future getCurrentAd() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecBaseManager; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.BaseManager.getCurrentAd'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as Ad?); + } + } + + /// Removes a listener for error events. + Future removeAdErrorListener(AdErrorListener errorListener) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecBaseManager; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.BaseManager.removeAdErrorListener'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, errorListener]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Removes a listener for ad events. + Future removeAdEventListener(AdEventListener adEventListener) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecBaseManager; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.BaseManager.removeAdEventListener'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, adEventListener]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + @override + BaseManager pigeon_copy() { + return BaseManager.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// Event to notify publisher that an event occurred with an Ad. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdEvent.html. +class AdEvent extends PigeonInternalProxyApiBaseClass { + /// Constructs [AdEvent] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + AdEvent.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.type, + this.adData, + }); + + /// The type of event that occurred. + final AdEventType type; + + /// A map containing any extra ad data for the event, if needed. + final Map? adData; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + AdEvent Function( + AdEventType type, + Map? adData, + )? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.AdEvent.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdEvent.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdEvent.pigeon_newInstance was null, expected non-null int.'); + final AdEventType? arg_type = (args[1] as AdEventType?); + assert(arg_type != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdEvent.pigeon_newInstance was null, expected non-null AdEventType.'); + final Map? arg_adData = + (args[2] as Map?)?.cast(); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call(arg_type!, arg_adData) ?? + AdEvent.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + type: arg_type!, + adData: arg_adData, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + AdEvent pigeon_copy() { + return AdEvent.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + type: type, + adData: adData, + ); + } +} + +/// Factory class for creating SDK objects. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/ImaSdkFactory. +class ImaSdkFactory extends PigeonInternalProxyApiBaseClass { + /// Constructs [ImaSdkFactory] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + ImaSdkFactory.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }); + + late final _PigeonInternalProxyApiBaseCodec _pigeonVar_codecImaSdkFactory = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + static final ImaSdkFactory instance = pigeonVar_instance(); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + ImaSdkFactory Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.ImaSdkFactory.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.ImaSdkFactory.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.ImaSdkFactory.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + ImaSdkFactory.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + static ImaSdkFactory pigeonVar_instance() { + final ImaSdkFactory pigeonVar_instance = ImaSdkFactory.pigeon_detached(); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec(PigeonInstanceManager.instance); + final BinaryMessenger pigeonVar_binaryMessenger = + ServicesBinding.instance.defaultBinaryMessenger; + final int pigeonVar_instanceIdentifier = PigeonInstanceManager.instance + .addDartCreatedInstance(pigeonVar_instance); + () async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.ImaSdkFactory.instance'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([pigeonVar_instanceIdentifier]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + }(); + return pigeonVar_instance; + } + + static Future createAdDisplayContainer( + ViewGroup container, + VideoAdPlayer player, { + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + }) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.ImaSdkFactory.createAdDisplayContainer'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([container, player]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as AdDisplayContainer?)!; + } + } + + /// Creates an `ImaSdkSettings` object for configuring the IMA SDK. + Future createImaSdkSettings() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecImaSdkFactory; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.ImaSdkFactory.createImaSdkSettings'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as ImaSdkSettings?)!; + } + } + + /// Creates an `AdsLoader` for requesting ads using the specified settings + /// object. + Future createAdsLoader( + ImaSdkSettings settings, + AdDisplayContainer container, + ) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecImaSdkFactory; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.ImaSdkFactory.createAdsLoader'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, settings, container]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as AdsLoader?)!; + } + } + + /// Creates an AdsRequest object to contain the data used to request ads. + Future createAdsRequest() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecImaSdkFactory; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.ImaSdkFactory.createAdsRequest'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as AdsRequest?)!; + } + } + + @override + ImaSdkFactory pigeon_copy() { + return ImaSdkFactory.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// Defines general SDK settings that are used when creating an `AdsLoader`. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/ImaSdkSettings.html. +class ImaSdkSettings extends PigeonInternalProxyApiBaseClass { + /// Constructs [ImaSdkSettings] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + ImaSdkSettings.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + ImaSdkSettings Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.ImaSdkSettings.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.ImaSdkSettings.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.ImaSdkSettings.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + ImaSdkSettings.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + ImaSdkSettings pigeon_copy() { + return ImaSdkSettings.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// Defines an update to the video's progress. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/player/VideoProgressUpdate.html. +class VideoProgressUpdate extends PigeonInternalProxyApiBaseClass { + VideoProgressUpdate({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required int currentTimeMs, + required int durationMs, + }) { + final int pigeonVar_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(this); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecVideoProgressUpdate; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + () async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.VideoProgressUpdate.pigeon_defaultConstructor'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([ + pigeonVar_instanceIdentifier, + currentTimeMs, + durationMs + ]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + }(); + } + + /// Constructs [VideoProgressUpdate] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + VideoProgressUpdate.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }); + + late final _PigeonInternalProxyApiBaseCodec + _pigeonVar_codecVideoProgressUpdate = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + /// Value to use for cases when progress is not yet defined, such as video + /// initialization. + static final VideoProgressUpdate videoTimeNotReady = + pigeonVar_videoTimeNotReady(); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + VideoProgressUpdate Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.VideoProgressUpdate.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoProgressUpdate.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoProgressUpdate.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + VideoProgressUpdate.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + static VideoProgressUpdate pigeonVar_videoTimeNotReady() { + final VideoProgressUpdate pigeonVar_instance = + VideoProgressUpdate.pigeon_detached(); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec(PigeonInstanceManager.instance); + final BinaryMessenger pigeonVar_binaryMessenger = + ServicesBinding.instance.defaultBinaryMessenger; + final int pigeonVar_instanceIdentifier = PigeonInstanceManager.instance + .addDartCreatedInstance(pigeonVar_instance); + () async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.VideoProgressUpdate.videoTimeNotReady'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([pigeonVar_instanceIdentifier]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + }(); + return pigeonVar_instance; + } + + @override + VideoProgressUpdate pigeon_copy() { + return VideoProgressUpdate.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// The minimal information required to play an ad. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/player/AdMediaInfo.html. +class AdMediaInfo extends PigeonInternalProxyApiBaseClass { + /// Constructs [AdMediaInfo] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + AdMediaInfo.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.url, + }); + + final String url; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + AdMediaInfo Function(String url)? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.AdMediaInfo.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdMediaInfo.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdMediaInfo.pigeon_newInstance was null, expected non-null int.'); + final String? arg_url = (args[1] as String?); + assert(arg_url != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdMediaInfo.pigeon_newInstance was null, expected non-null String.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call(arg_url!) ?? + AdMediaInfo.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + url: arg_url!, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + AdMediaInfo pigeon_copy() { + return AdMediaInfo.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + url: url, + ); + } +} + +/// An ad may be part of a pod of ads. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdPodInfo.html. +class AdPodInfo extends PigeonInternalProxyApiBaseClass { + /// Constructs [AdPodInfo] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + AdPodInfo.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.adPosition, + required this.maxDuration, + required this.podIndex, + required this.timeOffset, + required this.totalAds, + required this.isBumper, + }); + + /// The position of the ad within the pod. + /// + /// The value returned is one-based, for example, 1 of 2, 2 of 2, etc. If the + /// ad is not part of a pod, this will return 1. + final int adPosition; + + /// The maximum duration of the pod in seconds. + /// + /// For unknown duration, -1 is returned. + final double maxDuration; + + /// Client side and DAI VOD: Returns the index of the ad pod. + final int podIndex; + + /// The content time offset at which the current ad pod was scheduled. + /// + /// For preroll pod, 0 is returned. For midrolls, the scheduled time is + /// returned in seconds. For postroll, -1 is returned. Defaults to 0 if this + /// ad is not part of a pod, or the pod is not part of an ad playlist. + final double timeOffset; + + /// The total number of ads contained within this pod, including bumpers. + final int totalAds; + + /// Returns true if the ad is a bumper ad. + final bool isBumper; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + AdPodInfo Function( + int adPosition, + double maxDuration, + int podIndex, + double timeOffset, + int totalAds, + bool isBumper, + )? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.AdPodInfo.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdPodInfo.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdPodInfo.pigeon_newInstance was null, expected non-null int.'); + final int? arg_adPosition = (args[1] as int?); + assert(arg_adPosition != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdPodInfo.pigeon_newInstance was null, expected non-null int.'); + final double? arg_maxDuration = (args[2] as double?); + assert(arg_maxDuration != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdPodInfo.pigeon_newInstance was null, expected non-null double.'); + final int? arg_podIndex = (args[3] as int?); + assert(arg_podIndex != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdPodInfo.pigeon_newInstance was null, expected non-null int.'); + final double? arg_timeOffset = (args[4] as double?); + assert(arg_timeOffset != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdPodInfo.pigeon_newInstance was null, expected non-null double.'); + final int? arg_totalAds = (args[5] as int?); + assert(arg_totalAds != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdPodInfo.pigeon_newInstance was null, expected non-null int.'); + final bool? arg_isBumper = (args[6] as bool?); + assert(arg_isBumper != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdPodInfo.pigeon_newInstance was null, expected non-null bool.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call( + arg_adPosition!, + arg_maxDuration!, + arg_podIndex!, + arg_timeOffset!, + arg_totalAds!, + arg_isBumper!) ?? + AdPodInfo.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + adPosition: arg_adPosition!, + maxDuration: arg_maxDuration!, + podIndex: arg_podIndex!, + timeOffset: arg_timeOffset!, + totalAds: arg_totalAds!, + isBumper: arg_isBumper!, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + AdPodInfo pigeon_copy() { + return AdPodInfo.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + adPosition: adPosition, + maxDuration: maxDuration, + podIndex: podIndex, + timeOffset: timeOffset, + totalAds: totalAds, + isBumper: isBumper, + ); + } +} + +/// FrameLayout is designed to block out an area on the screen to display a +/// single item. +/// +/// See https://developer.android.com/reference/android/widget/FrameLayout. +class FrameLayout extends ViewGroup { + FrameLayout({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }) : super.pigeon_detached() { + final int pigeonVar_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(this); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecFrameLayout; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + () async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.FrameLayout.pigeon_defaultConstructor'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([pigeonVar_instanceIdentifier]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + }(); + } + + /// Constructs [FrameLayout] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + FrameLayout.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }) : super.pigeon_detached(); + + late final _PigeonInternalProxyApiBaseCodec _pigeonVar_codecFrameLayout = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + FrameLayout Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.FrameLayout.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.FrameLayout.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.FrameLayout.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + FrameLayout.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + FrameLayout pigeon_copy() { + return FrameLayout.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// A special view that can contain other views (called children.) +/// +/// See https://developer.android.com/reference/android/view/ViewGroup. +class ViewGroup extends View { + /// Constructs [ViewGroup] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + ViewGroup.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }) : super.pigeon_detached(); + + late final _PigeonInternalProxyApiBaseCodec _pigeonVar_codecViewGroup = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + ViewGroup Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.ViewGroup.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.ViewGroup.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.ViewGroup.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + ViewGroup.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + /// Adds a child view. + Future addView(View view) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecViewGroup; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.ViewGroup.addView'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, view]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Called by a ViewGroup subclass to remove child views from itself, when it + /// must first know its size on screen before it can calculate how many child + /// views it will render. + Future removeView(View view) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecViewGroup; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.ViewGroup.removeView'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, view]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + @override + ViewGroup pigeon_copy() { + return ViewGroup.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// Displays a video file. +/// +/// See https://developer.android.com/reference/android/widget/VideoView. +class VideoView extends View { + VideoView({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + this.onPrepared, + this.onCompletion, + required this.onError, + }) : super.pigeon_detached() { + final int pigeonVar_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(this); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecVideoView; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + () async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.VideoView.pigeon_defaultConstructor'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([pigeonVar_instanceIdentifier]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + }(); + } + + /// Constructs [VideoView] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + VideoView.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + this.onPrepared, + this.onCompletion, + required this.onError, + }) : super.pigeon_detached(); + + late final _PigeonInternalProxyApiBaseCodec _pigeonVar_codecVideoView = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + /// Callback to be invoked when the media source is ready for playback. + /// + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// with a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final VideoView instance = VideoView( + /// onPrepared: (VideoView pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, [PigeonInstanceManager.removeWeakReference] can be used to + /// release the associated Native object manually. + final void Function( + VideoView pigeon_instance, + MediaPlayer player, + )? onPrepared; + + /// Callback to be invoked when playback of a media source has completed. + /// + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// with a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final VideoView instance = VideoView( + /// onCompletion: (VideoView pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, [PigeonInstanceManager.removeWeakReference] can be used to + /// release the associated Native object manually. + final void Function( + VideoView pigeon_instance, + MediaPlayer player, + )? onCompletion; + + /// Callback to be invoked when there has been an error during an asynchronous + /// operation. + /// + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// with a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final VideoView instance = VideoView( + /// onError: (VideoView pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, [PigeonInstanceManager.removeWeakReference] can be used to + /// release the associated Native object manually. + final void Function( + VideoView pigeon_instance, + MediaPlayer player, + int what, + int extra, + ) onError; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + void Function( + VideoView pigeon_instance, + MediaPlayer player, + )? onPrepared, + void Function( + VideoView pigeon_instance, + MediaPlayer player, + )? onCompletion, + void Function( + VideoView pigeon_instance, + MediaPlayer player, + int what, + int extra, + )? onError, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + 'dev.flutter.pigeon.interactive_media_ads.VideoView.onPrepared', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoView.onPrepared was null.'); + final List args = (message as List?)!; + final VideoView? arg_pigeon_instance = (args[0] as VideoView?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoView.onPrepared was null, expected non-null VideoView.'); + final MediaPlayer? arg_player = (args[1] as MediaPlayer?); + assert(arg_player != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoView.onPrepared was null, expected non-null MediaPlayer.'); + try { + (onPrepared ?? arg_pigeon_instance!.onPrepared) + ?.call(arg_pigeon_instance!, arg_player!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + 'dev.flutter.pigeon.interactive_media_ads.VideoView.onCompletion', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoView.onCompletion was null.'); + final List args = (message as List?)!; + final VideoView? arg_pigeon_instance = (args[0] as VideoView?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoView.onCompletion was null, expected non-null VideoView.'); + final MediaPlayer? arg_player = (args[1] as MediaPlayer?); + assert(arg_player != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoView.onCompletion was null, expected non-null MediaPlayer.'); + try { + (onCompletion ?? arg_pigeon_instance!.onCompletion) + ?.call(arg_pigeon_instance!, arg_player!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + 'dev.flutter.pigeon.interactive_media_ads.VideoView.onError', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoView.onError was null.'); + final List args = (message as List?)!; + final VideoView? arg_pigeon_instance = (args[0] as VideoView?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoView.onError was null, expected non-null VideoView.'); + final MediaPlayer? arg_player = (args[1] as MediaPlayer?); + assert(arg_player != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoView.onError was null, expected non-null MediaPlayer.'); + final int? arg_what = (args[2] as int?); + assert(arg_what != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoView.onError was null, expected non-null int.'); + final int? arg_extra = (args[3] as int?); + assert(arg_extra != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoView.onError was null, expected non-null int.'); + try { + (onError ?? arg_pigeon_instance!.onError) + .call(arg_pigeon_instance!, arg_player!, arg_what!, arg_extra!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + /// Sets the URI of the video. + Future setVideoUri(String? uri) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecVideoView; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.VideoView.setVideoUri'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, uri]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// The current position of the playing video. + /// + /// In milliseconds. + Future getCurrentPosition() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecVideoView; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.VideoView.getCurrentPosition'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as int?)!; + } + } + + @override + VideoView pigeon_copy() { + return VideoView.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + onPrepared: onPrepared, + onCompletion: onCompletion, + onError: onError, + ); + } +} + +/// This class represents the basic building block for user interface components. +/// +/// See https://developer.android.com/reference/android/view/View. +class View extends PigeonInternalProxyApiBaseClass { + /// Constructs [View] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + View.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + View Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.View.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.View.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.View.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + View.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + View pigeon_copy() { + return View.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// MediaPlayer class can be used to control playback of audio/video files and +/// streams. +/// +/// See https://developer.android.com/reference/android/media/MediaPlayer. +class MediaPlayer extends PigeonInternalProxyApiBaseClass { + /// Constructs [MediaPlayer] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + MediaPlayer.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }); + + late final _PigeonInternalProxyApiBaseCodec _pigeonVar_codecMediaPlayer = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + MediaPlayer Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.MediaPlayer.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.MediaPlayer.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.MediaPlayer.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + MediaPlayer.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + /// Gets the duration of the file. + Future getDuration() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecMediaPlayer; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.MediaPlayer.getDuration'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as int?)!; + } + } + + /// Seeks to specified time position. + Future seekTo(int mSec) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecMediaPlayer; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.MediaPlayer.seekTo'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, mSec]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Starts or resumes playback. + Future start() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecMediaPlayer; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.MediaPlayer.start'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Pauses playback. + Future pause() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecMediaPlayer; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.MediaPlayer.pause'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Stops playback after playback has been started or paused. + Future stop() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecMediaPlayer; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.MediaPlayer.stop'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + @override + MediaPlayer pigeon_copy() { + return MediaPlayer.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// Callbacks that the player must fire. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/player/VideoAdPlayer.VideoAdPlayerCallback.html +class VideoAdPlayerCallback extends PigeonInternalProxyApiBaseClass { + /// Constructs [VideoAdPlayerCallback] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + VideoAdPlayerCallback.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }); + + late final _PigeonInternalProxyApiBaseCodec + _pigeonVar_codecVideoAdPlayerCallback = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + VideoAdPlayerCallback Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.VideoAdPlayerCallback.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoAdPlayerCallback.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoAdPlayerCallback.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + VideoAdPlayerCallback.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + /// Fire this callback periodically as ad playback occurs. + Future onAdProgress( + AdMediaInfo adMediaInfo, + VideoProgressUpdate videoProgressUpdate, + ) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecVideoAdPlayerCallback; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.VideoAdPlayerCallback.onAdProgress'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, adMediaInfo, videoProgressUpdate]) + as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Fire this callback when video playback stalls waiting for data. + Future onBuffering(AdMediaInfo adMediaInfo) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecVideoAdPlayerCallback; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.VideoAdPlayerCallback.onBuffering'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, adMediaInfo]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Fire this callback when all content has finished playing. + Future onContentComplete() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecVideoAdPlayerCallback; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.VideoAdPlayerCallback.onContentComplete'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Fire this callback when the video finishes playing. + Future onEnded(AdMediaInfo adMediaInfo) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecVideoAdPlayerCallback; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.VideoAdPlayerCallback.onEnded'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, adMediaInfo]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Fire this callback when the video has encountered an error. + Future onError(AdMediaInfo adMediaInfo) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecVideoAdPlayerCallback; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.VideoAdPlayerCallback.onError'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, adMediaInfo]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Fire this callback when the video is ready to begin playback. + Future onLoaded(AdMediaInfo adMediaInfo) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecVideoAdPlayerCallback; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.VideoAdPlayerCallback.onLoaded'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, adMediaInfo]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Fire this callback when the video is paused. + Future onPause(AdMediaInfo adMediaInfo) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecVideoAdPlayerCallback; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.VideoAdPlayerCallback.onPause'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, adMediaInfo]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Fire this callback when the player begins playing a video. + Future onPlay(AdMediaInfo adMediaInfo) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecVideoAdPlayerCallback; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.VideoAdPlayerCallback.onPlay'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, adMediaInfo]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Fire this callback when the video is unpaused. + Future onResume(AdMediaInfo adMediaInfo) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecVideoAdPlayerCallback; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.VideoAdPlayerCallback.onResume'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, adMediaInfo]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Fire this callback when the playback volume changes. + Future onVolumeChanged( + AdMediaInfo adMediaInfo, + int percentage, + ) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecVideoAdPlayerCallback; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.VideoAdPlayerCallback.onVolumeChanged'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, adMediaInfo, percentage]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + @override + VideoAdPlayerCallback pigeon_copy() { + return VideoAdPlayerCallback.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// Defines the set of methods that a video player must implement to be used by +/// the IMA SDK, as well as a set of callbacks that it must fire. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/player/VideoAdPlayer.html. +class VideoAdPlayer extends PigeonInternalProxyApiBaseClass { + VideoAdPlayer({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.addCallback, + required this.loadAd, + required this.pauseAd, + required this.playAd, + required this.release, + required this.removeCallback, + required this.stopAd, + }) { + final int pigeonVar_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(this); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecVideoAdPlayer; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + () async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.pigeon_defaultConstructor'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([pigeonVar_instanceIdentifier]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + }(); + } + + /// Constructs [VideoAdPlayer] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + VideoAdPlayer.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.addCallback, + required this.loadAd, + required this.pauseAd, + required this.playAd, + required this.release, + required this.removeCallback, + required this.stopAd, + }); + + late final _PigeonInternalProxyApiBaseCodec _pigeonVar_codecVideoAdPlayer = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + /// Adds a callback. + /// + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// with a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final VideoAdPlayer instance = VideoAdPlayer( + /// addCallback: (VideoAdPlayer pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, [PigeonInstanceManager.removeWeakReference] can be used to + /// release the associated Native object manually. + final void Function( + VideoAdPlayer pigeon_instance, + VideoAdPlayerCallback callback, + ) addCallback; + + /// Loads a video ad hosted at AdMediaInfo. + /// + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// with a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final VideoAdPlayer instance = VideoAdPlayer( + /// loadAd: (VideoAdPlayer pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, [PigeonInstanceManager.removeWeakReference] can be used to + /// release the associated Native object manually. + final void Function( + VideoAdPlayer pigeon_instance, + AdMediaInfo adMediaInfo, + AdPodInfo adPodInfo, + ) loadAd; + + /// Pauses playing the current ad. + /// + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// with a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final VideoAdPlayer instance = VideoAdPlayer( + /// pauseAd: (VideoAdPlayer pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, [PigeonInstanceManager.removeWeakReference] can be used to + /// release the associated Native object manually. + final void Function( + VideoAdPlayer pigeon_instance, + AdMediaInfo adMediaInfo, + ) pauseAd; + + /// Starts or resumes playing the video ad referenced by the AdMediaInfo, + /// provided loadAd has already been called for it. + /// + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// with a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final VideoAdPlayer instance = VideoAdPlayer( + /// playAd: (VideoAdPlayer pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, [PigeonInstanceManager.removeWeakReference] can be used to + /// release the associated Native object manually. + final void Function( + VideoAdPlayer pigeon_instance, + AdMediaInfo adMediaInfo, + ) playAd; + + /// Cleans up and releases all resources used by the `VideoAdPlayer`. + /// + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// with a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final VideoAdPlayer instance = VideoAdPlayer( + /// release: (VideoAdPlayer pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, [PigeonInstanceManager.removeWeakReference] can be used to + /// release the associated Native object manually. + final void Function(VideoAdPlayer pigeon_instance) release; + + /// Removes a callback. + /// + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// with a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final VideoAdPlayer instance = VideoAdPlayer( + /// removeCallback: (VideoAdPlayer pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, [PigeonInstanceManager.removeWeakReference] can be used to + /// release the associated Native object manually. + final void Function( + VideoAdPlayer pigeon_instance, + VideoAdPlayerCallback callback, + ) removeCallback; + + /// Stops playing the current ad. + /// + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// with a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final VideoAdPlayer instance = VideoAdPlayer( + /// stopAd: (VideoAdPlayer pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, [PigeonInstanceManager.removeWeakReference] can be used to + /// release the associated Native object manually. + final void Function( + VideoAdPlayer pigeon_instance, + AdMediaInfo adMediaInfo, + ) stopAd; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + void Function( + VideoAdPlayer pigeon_instance, + VideoAdPlayerCallback callback, + )? addCallback, + void Function( + VideoAdPlayer pigeon_instance, + AdMediaInfo adMediaInfo, + AdPodInfo adPodInfo, + )? loadAd, + void Function( + VideoAdPlayer pigeon_instance, + AdMediaInfo adMediaInfo, + )? pauseAd, + void Function( + VideoAdPlayer pigeon_instance, + AdMediaInfo adMediaInfo, + )? playAd, + void Function(VideoAdPlayer pigeon_instance)? release, + void Function( + VideoAdPlayer pigeon_instance, + VideoAdPlayerCallback callback, + )? removeCallback, + void Function( + VideoAdPlayer pigeon_instance, + AdMediaInfo adMediaInfo, + )? stopAd, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.addCallback', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.addCallback was null.'); + final List args = (message as List?)!; + final VideoAdPlayer? arg_pigeon_instance = + (args[0] as VideoAdPlayer?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.addCallback was null, expected non-null VideoAdPlayer.'); + final VideoAdPlayerCallback? arg_callback = + (args[1] as VideoAdPlayerCallback?); + assert(arg_callback != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.addCallback was null, expected non-null VideoAdPlayerCallback.'); + try { + (addCallback ?? arg_pigeon_instance!.addCallback) + .call(arg_pigeon_instance!, arg_callback!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + 'dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.loadAd', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.loadAd was null.'); + final List args = (message as List?)!; + final VideoAdPlayer? arg_pigeon_instance = + (args[0] as VideoAdPlayer?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.loadAd was null, expected non-null VideoAdPlayer.'); + final AdMediaInfo? arg_adMediaInfo = (args[1] as AdMediaInfo?); + assert(arg_adMediaInfo != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.loadAd was null, expected non-null AdMediaInfo.'); + final AdPodInfo? arg_adPodInfo = (args[2] as AdPodInfo?); + assert(arg_adPodInfo != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.loadAd was null, expected non-null AdPodInfo.'); + try { + (loadAd ?? arg_pigeon_instance!.loadAd) + .call(arg_pigeon_instance!, arg_adMediaInfo!, arg_adPodInfo!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + 'dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.pauseAd', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.pauseAd was null.'); + final List args = (message as List?)!; + final VideoAdPlayer? arg_pigeon_instance = + (args[0] as VideoAdPlayer?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.pauseAd was null, expected non-null VideoAdPlayer.'); + final AdMediaInfo? arg_adMediaInfo = (args[1] as AdMediaInfo?); + assert(arg_adMediaInfo != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.pauseAd was null, expected non-null AdMediaInfo.'); + try { + (pauseAd ?? arg_pigeon_instance!.pauseAd) + .call(arg_pigeon_instance!, arg_adMediaInfo!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + 'dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.playAd', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.playAd was null.'); + final List args = (message as List?)!; + final VideoAdPlayer? arg_pigeon_instance = + (args[0] as VideoAdPlayer?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.playAd was null, expected non-null VideoAdPlayer.'); + final AdMediaInfo? arg_adMediaInfo = (args[1] as AdMediaInfo?); + assert(arg_adMediaInfo != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.playAd was null, expected non-null AdMediaInfo.'); + try { + (playAd ?? arg_pigeon_instance!.playAd) + .call(arg_pigeon_instance!, arg_adMediaInfo!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + 'dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.release', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.release was null.'); + final List args = (message as List?)!; + final VideoAdPlayer? arg_pigeon_instance = + (args[0] as VideoAdPlayer?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.release was null, expected non-null VideoAdPlayer.'); + try { + (release ?? arg_pigeon_instance!.release) + .call(arg_pigeon_instance!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.removeCallback', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.removeCallback was null.'); + final List args = (message as List?)!; + final VideoAdPlayer? arg_pigeon_instance = + (args[0] as VideoAdPlayer?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.removeCallback was null, expected non-null VideoAdPlayer.'); + final VideoAdPlayerCallback? arg_callback = + (args[1] as VideoAdPlayerCallback?); + assert(arg_callback != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.removeCallback was null, expected non-null VideoAdPlayerCallback.'); + try { + (removeCallback ?? arg_pigeon_instance!.removeCallback) + .call(arg_pigeon_instance!, arg_callback!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + 'dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.stopAd', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.stopAd was null.'); + final List args = (message as List?)!; + final VideoAdPlayer? arg_pigeon_instance = + (args[0] as VideoAdPlayer?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.stopAd was null, expected non-null VideoAdPlayer.'); + final AdMediaInfo? arg_adMediaInfo = (args[1] as AdMediaInfo?); + assert(arg_adMediaInfo != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.stopAd was null, expected non-null AdMediaInfo.'); + try { + (stopAd ?? arg_pigeon_instance!.stopAd) + .call(arg_pigeon_instance!, arg_adMediaInfo!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + /// The volume of the player as a percentage from 0 to 100. + Future setVolume(int value) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecVideoAdPlayer; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.setVolume'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, value]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// The `VideoProgressUpdate` describing playback progress of the current + /// video. + Future setAdProgress(VideoProgressUpdate progress) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecVideoAdPlayer; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.VideoAdPlayer.setAdProgress'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, progress]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + @override + VideoAdPlayer pigeon_copy() { + return VideoAdPlayer.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + addCallback: addCallback, + loadAd: loadAd, + pauseAd: pauseAd, + playAd: playAd, + release: release, + removeCallback: removeCallback, + stopAd: stopAd, + ); + } +} + +/// Listener interface for notification of ad load or stream load completion. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdsLoader.AdsLoadedListener.html. +class AdsLoadedListener extends PigeonInternalProxyApiBaseClass { + AdsLoadedListener({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.onAdsManagerLoaded, + }) { + final int pigeonVar_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(this); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsLoadedListener; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + () async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsLoadedListener.pigeon_defaultConstructor'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([pigeonVar_instanceIdentifier]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + }(); + } + + /// Constructs [AdsLoadedListener] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + AdsLoadedListener.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.onAdsManagerLoaded, + }); + + late final _PigeonInternalProxyApiBaseCodec + _pigeonVar_codecAdsLoadedListener = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + /// Called once the AdsManager or StreamManager has been loaded. + /// + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// with a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final AdsLoadedListener instance = AdsLoadedListener( + /// onAdsManagerLoaded: (AdsLoadedListener pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, [PigeonInstanceManager.removeWeakReference] can be used to + /// release the associated Native object manually. + final void Function( + AdsLoadedListener pigeon_instance, + AdsManagerLoadedEvent event, + ) onAdsManagerLoaded; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + void Function( + AdsLoadedListener pigeon_instance, + AdsManagerLoadedEvent event, + )? onAdsManagerLoaded, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.AdsLoadedListener.onAdsManagerLoaded', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdsLoadedListener.onAdsManagerLoaded was null.'); + final List args = (message as List?)!; + final AdsLoadedListener? arg_pigeon_instance = + (args[0] as AdsLoadedListener?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdsLoadedListener.onAdsManagerLoaded was null, expected non-null AdsLoadedListener.'); + final AdsManagerLoadedEvent? arg_event = + (args[1] as AdsManagerLoadedEvent?); + assert(arg_event != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdsLoadedListener.onAdsManagerLoaded was null, expected non-null AdsManagerLoadedEvent.'); + try { + (onAdsManagerLoaded ?? arg_pigeon_instance!.onAdsManagerLoaded) + .call(arg_pigeon_instance!, arg_event!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + AdsLoadedListener pigeon_copy() { + return AdsLoadedListener.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + onAdsManagerLoaded: onAdsManagerLoaded, + ); + } +} + +/// Interface for classes that will listen to AdErrorEvents. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdErrorEvent.AdErrorListener.html. +class AdErrorListener extends PigeonInternalProxyApiBaseClass { + AdErrorListener({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.onAdError, + }) { + final int pigeonVar_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(this); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdErrorListener; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + () async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdErrorListener.pigeon_defaultConstructor'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([pigeonVar_instanceIdentifier]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + }(); + } + + /// Constructs [AdErrorListener] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + AdErrorListener.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.onAdError, + }); + + late final _PigeonInternalProxyApiBaseCodec _pigeonVar_codecAdErrorListener = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + /// Called when an error occurs. + /// + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// with a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final AdErrorListener instance = AdErrorListener( + /// onAdError: (AdErrorListener pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, [PigeonInstanceManager.removeWeakReference] can be used to + /// release the associated Native object manually. + final void Function( + AdErrorListener pigeon_instance, + AdErrorEvent event, + ) onAdError; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + void Function( + AdErrorListener pigeon_instance, + AdErrorEvent event, + )? onAdError, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.AdErrorListener.onAdError', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdErrorListener.onAdError was null.'); + final List args = (message as List?)!; + final AdErrorListener? arg_pigeon_instance = + (args[0] as AdErrorListener?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdErrorListener.onAdError was null, expected non-null AdErrorListener.'); + final AdErrorEvent? arg_event = (args[1] as AdErrorEvent?); + assert(arg_event != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdErrorListener.onAdError was null, expected non-null AdErrorEvent.'); + try { + (onAdError ?? arg_pigeon_instance!.onAdError) + .call(arg_pigeon_instance!, arg_event!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + AdErrorListener pigeon_copy() { + return AdErrorListener.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + onAdError: onAdError, + ); + } +} + +/// Listener interface for ad events. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdEvent.AdEventListener.html. +class AdEventListener extends PigeonInternalProxyApiBaseClass { + AdEventListener({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.onAdEvent, + }) { + final int pigeonVar_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(this); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdEventListener; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + () async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdEventListener.pigeon_defaultConstructor'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([pigeonVar_instanceIdentifier]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + }(); + } + + /// Constructs [AdEventListener] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + AdEventListener.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.onAdEvent, + }); + + late final _PigeonInternalProxyApiBaseCodec _pigeonVar_codecAdEventListener = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + /// Respond to an occurrence of an AdEvent. + /// + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// with a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final AdEventListener instance = AdEventListener( + /// onAdEvent: (AdEventListener pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, [PigeonInstanceManager.removeWeakReference] can be used to + /// release the associated Native object manually. + final void Function( + AdEventListener pigeon_instance, + AdEvent event, + ) onAdEvent; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + void Function( + AdEventListener pigeon_instance, + AdEvent event, + )? onAdEvent, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.AdEventListener.onAdEvent', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdEventListener.onAdEvent was null.'); + final List args = (message as List?)!; + final AdEventListener? arg_pigeon_instance = + (args[0] as AdEventListener?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdEventListener.onAdEvent was null, expected non-null AdEventListener.'); + final AdEvent? arg_event = (args[1] as AdEvent?); + assert(arg_event != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdEventListener.onAdEvent was null, expected non-null AdEvent.'); + try { + (onAdEvent ?? arg_pigeon_instance!.onAdEvent) + .call(arg_pigeon_instance!, arg_event!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + AdEventListener pigeon_copy() { + return AdEventListener.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + onAdEvent: onAdEvent, + ); + } +} + +/// Defines parameters that control the rendering of ads. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdsRenderingSettings.html. +class AdsRenderingSettings extends PigeonInternalProxyApiBaseClass { + /// Constructs [AdsRenderingSettings] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + AdsRenderingSettings.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }); + + late final _PigeonInternalProxyApiBaseCodec + _pigeonVar_codecAdsRenderingSettings = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + AdsRenderingSettings Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + AdsRenderingSettings.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + /// Maximum recommended bitrate. + Future getBitrateKbps() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsRenderingSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.getBitrateKbps'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as int?)!; + } + } + + /// Returns whether the click-through URL will be opened using Custom Tabs + /// feature. + Future getEnableCustomTabs() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsRenderingSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.getEnableCustomTabs'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as bool?)!; + } + } + + /// Whether the SDK will instruct the player to load the creative in response + /// to `BaseManager.init()`. + Future getEnablePreloading() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsRenderingSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.getEnablePreloading'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as bool?)!; + } + } + + /// Whether to focus on the skip button when the skippable ad can be skipped + /// on Android TV. + /// + /// This is a no-op on non-Android TV devices. + Future getFocusSkipButtonWhenAvailable() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsRenderingSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.getFocusSkipButtonWhenAvailable'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as bool?)!; + } + } + + /// The SDK will prioritize the media with MIME type on the list. + Future> getMimeTypes() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsRenderingSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.getMimeTypes'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as List?)!.cast(); + } + } + + /// Maximum recommended bitrate. + /// + /// The value is in kbit/s. Default value, -1, means the bitrate will be + /// selected by the SDK. + Future setBitrateKbps(int bitrate) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsRenderingSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.setBitrateKbps'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, bitrate]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Notifies the SDK whether to launch the click-through URL using Custom Tabs + /// feature. + /// + /// Default is false. + Future setEnableCustomTabs(bool enableCustomTabs) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsRenderingSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.setEnableCustomTabs'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, enableCustomTabs]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// If set, the SDK will instruct the player to load the creative in response + /// to `BaseManager.init()`. + /// + /// This allows the player to preload the ad at any point before calling + /// `AdsManager.start()`. + Future setEnablePreloading(bool enablePreloading) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsRenderingSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.setEnablePreloading'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, enablePreloading]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Set whether to focus on the skip button when the skippable ad can be + /// skipped on Android TV. + /// + /// This is a no-op on non-Android TV devices. + /// + /// Default is true. + Future setFocusSkipButtonWhenAvailable( + bool enableFocusSkipButton) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsRenderingSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.setFocusSkipButtonWhenAvailable'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, enableFocusSkipButton]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Specifies a non-default amount of time to wait for media to load before + /// timing out, in milliseconds. + /// + /// This only applies to the IMA client-side SDK. + /// + /// Default time is 8000 ms. + Future setLoadVideoTimeout(int loadVideoTimeout) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsRenderingSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.setLoadVideoTimeout'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, loadVideoTimeout]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// If specified, the SDK will prioritize the media with MIME type on the + /// list. + Future setMimeTypes(List mimeTypes) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsRenderingSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.setMimeTypes'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, mimeTypes]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// For VMAP and ad rules playlists, only play ad breaks scheduled after this + /// time (in seconds). + Future setPlayAdsAfterTime(double time) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsRenderingSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.setPlayAdsAfterTime'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, time]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Sets the ad UI elements to be rendered by the IMA SDK. + Future setUiElements(List uiElements) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecAdsRenderingSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.AdsRenderingSettings.setUiElements'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, uiElements]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + @override + AdsRenderingSettings pigeon_copy() { + return AdsRenderingSettings.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// Represents the progress within this ad break. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdProgressInfo.html. +class AdProgressInfo extends PigeonInternalProxyApiBaseClass { + /// Constructs [AdProgressInfo] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + AdProgressInfo.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.adBreakDuration, + required this.adPeriodDuration, + required this.adPosition, + required this.currentTime, + required this.duration, + required this.totalAds, + }); + + /// Total ad break duration (in seconds). + final double adBreakDuration; + + /// Total ad period duration (in seconds). + final double adPeriodDuration; + + /// The position of current ad within the ad break, starting with 1. + final int adPosition; + + /// Current time within the ad (in seconds). + final double currentTime; + + /// Duration of current ad (in seconds). + final double duration; + + /// The total number of ads in this ad break. + final int totalAds; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + AdProgressInfo Function( + double adBreakDuration, + double adPeriodDuration, + int adPosition, + double currentTime, + double duration, + int totalAds, + )? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.AdProgressInfo.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdProgressInfo.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdProgressInfo.pigeon_newInstance was null, expected non-null int.'); + final double? arg_adBreakDuration = (args[1] as double?); + assert(arg_adBreakDuration != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdProgressInfo.pigeon_newInstance was null, expected non-null double.'); + final double? arg_adPeriodDuration = (args[2] as double?); + assert(arg_adPeriodDuration != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdProgressInfo.pigeon_newInstance was null, expected non-null double.'); + final int? arg_adPosition = (args[3] as int?); + assert(arg_adPosition != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdProgressInfo.pigeon_newInstance was null, expected non-null int.'); + final double? arg_currentTime = (args[4] as double?); + assert(arg_currentTime != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdProgressInfo.pigeon_newInstance was null, expected non-null double.'); + final double? arg_duration = (args[5] as double?); + assert(arg_duration != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdProgressInfo.pigeon_newInstance was null, expected non-null double.'); + final int? arg_totalAds = (args[6] as int?); + assert(arg_totalAds != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.AdProgressInfo.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call( + arg_adBreakDuration!, + arg_adPeriodDuration!, + arg_adPosition!, + arg_currentTime!, + arg_duration!, + arg_totalAds!) ?? + AdProgressInfo.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + adBreakDuration: arg_adBreakDuration!, + adPeriodDuration: arg_adPeriodDuration!, + adPosition: arg_adPosition!, + currentTime: arg_currentTime!, + duration: arg_duration!, + totalAds: arg_totalAds!, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + AdProgressInfo pigeon_copy() { + return AdProgressInfo.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + adBreakDuration: adBreakDuration, + adPeriodDuration: adPeriodDuration, + adPosition: adPosition, + currentTime: currentTime, + duration: duration, + totalAds: totalAds, + ); + } +} + +/// An object that holds data corresponding to the companion Ad. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/CompanionAd.html. +class CompanionAd extends PigeonInternalProxyApiBaseClass { + /// Constructs [CompanionAd] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + CompanionAd.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + this.apiFramework, + required this.height, + required this.resourceValue, + required this.width, + }); + + /// The API needed to execute this ad, or null if unavailable. + final String? apiFramework; + + /// The height of the companion in pixels. + /// + /// 0 if unavailable. + final int height; + + /// The URL for the static resource of this companion. + final String resourceValue; + + /// The width of the companion in pixels. + /// + /// 0 if unavailable. + final int width; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + CompanionAd Function( + String? apiFramework, + int height, + String resourceValue, + int width, + )? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.CompanionAd.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.CompanionAd.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.CompanionAd.pigeon_newInstance was null, expected non-null int.'); + final String? arg_apiFramework = (args[1] as String?); + final int? arg_height = (args[2] as int?); + assert(arg_height != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.CompanionAd.pigeon_newInstance was null, expected non-null int.'); + final String? arg_resourceValue = (args[3] as String?); + assert(arg_resourceValue != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.CompanionAd.pigeon_newInstance was null, expected non-null String.'); + final int? arg_width = (args[4] as int?); + assert(arg_width != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.CompanionAd.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call(arg_apiFramework, arg_height!, + arg_resourceValue!, arg_width!) ?? + CompanionAd.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + apiFramework: arg_apiFramework, + height: arg_height!, + resourceValue: arg_resourceValue!, + width: arg_width!, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + CompanionAd pigeon_copy() { + return CompanionAd.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + apiFramework: apiFramework, + height: height, + resourceValue: resourceValue, + width: width, + ); + } +} + +/// This object exposes information about the universal ad ID. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/UniversalAdId.html. +class UniversalAdId extends PigeonInternalProxyApiBaseClass { + /// Constructs [UniversalAdId] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + UniversalAdId.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.adIdRegistry, + required this.adIdValue, + }); + + /// Returns the ad ID registry associated with the ad ID value. + /// + /// Returns "unknown" if the registry is not known. + final String adIdRegistry; + + /// Returns the universal ad ID value. + /// + /// Returns "unknown" if the value is not known. + final String adIdValue; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + UniversalAdId Function( + String adIdRegistry, + String adIdValue, + )? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.UniversalAdId.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.UniversalAdId.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.UniversalAdId.pigeon_newInstance was null, expected non-null int.'); + final String? arg_adIdRegistry = (args[1] as String?); + assert(arg_adIdRegistry != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.UniversalAdId.pigeon_newInstance was null, expected non-null String.'); + final String? arg_adIdValue = (args[2] as String?); + assert(arg_adIdValue != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.UniversalAdId.pigeon_newInstance was null, expected non-null String.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call(arg_adIdRegistry!, arg_adIdValue!) ?? + UniversalAdId.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + adIdRegistry: arg_adIdRegistry!, + adIdValue: arg_adIdValue!, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + UniversalAdId pigeon_copy() { + return UniversalAdId.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + adIdRegistry: adIdRegistry, + adIdValue: adIdValue, + ); + } +} + +/// An object that holds data corresponding to the main Ad. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/Ad.html. +class Ad extends PigeonInternalProxyApiBaseClass { + /// Constructs [Ad] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + Ad.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.adId, + required this.adPodInfo, + required this.adSystem, + required this.adWrapperCreativeIds, + required this.adWrapperIds, + required this.adWrapperSystems, + required this.advertiserName, + required this.companionAds, + this.contentType, + required this.creativeAdId, + required this.creativeId, + required this.dealId, + this.description, + required this.duration, + required this.height, + required this.skipTimeOffset, + this.surveyUrl, + this.title, + required this.traffickingParameters, + required this.uiElements, + required this.universalAdIds, + required this.vastMediaBitrate, + required this.vastMediaHeight, + required this.vastMediaWidth, + required this.width, + required this.isLinear, + required this.isSkippable, + }); + + /// The ad ID as specified in the VAST response. + final String adId; + + /// The pod metadata object. + final AdPodInfo adPodInfo; + + /// The ad system as specified in the VAST response. + final String adSystem; + + /// The IDs of the ads' creatives, starting with the first wrapper ad. + final List adWrapperCreativeIds; + + /// The wrapper ad IDs as specified in the VAST response. + final List adWrapperIds; + + /// The wrapper ad systems as specified in the VAST response. + final List adWrapperSystems; + + /// The advertiser name as defined by the serving party. + final String advertiserName; + + /// The companions for the current ad while using DAI. + /// + /// Returns an empty list in any other scenario. + final List companionAds; + + /// The content type of the currently selected creative, or null if no + /// creative is selected or the content type is unavailable. + final String? contentType; + + /// The ISCI (Industry Standard Commercial Identifier) code for an ad. + final String creativeAdId; + + /// The ID of the selected creative for the ad, + final String creativeId; + + /// The first deal ID present in the wrapper chain for the current ad, + /// starting from the top. + final String dealId; + + /// The description of this ad from the VAST response. + final String? description; + + /// The duration of the ad in seconds, -1 if not available. + final double duration; + + /// The height of the selected creative if non-linear, else returns 0. + final int height; + + /// The number of seconds of playback before the ad becomes skippable. + final double skipTimeOffset; + + /// The URL associated with the survey for the given ad. + final String? surveyUrl; + + /// The title of this ad from the VAST response. + final String? title; + + /// The custom parameters associated with the ad at the time of ad + /// trafficking. + final String traffickingParameters; + + /// Te set of ad UI elements rendered by the IMA SDK for this ad. + final List uiElements; + + /// The list of all universal ad IDs for this ad. + final List universalAdIds; + + /// The VAST bitrate in Kbps of the selected creative. + final int vastMediaBitrate; + + /// The VAST media height in pixels of the selected creative. + final int vastMediaHeight; + + /// The VAST media width in pixels of the selected creative. + final int vastMediaWidth; + + /// The width of the selected creative if non-linear, else returns 0. + final int width; + + /// Indicates whether the ad’s current mode of operation is linear or + /// non-linear. + final bool isLinear; + + /// Indicates whether the ad can be skipped by the user. + final bool isSkippable; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + Ad Function( + String adId, + AdPodInfo adPodInfo, + String adSystem, + List adWrapperCreativeIds, + List adWrapperIds, + List adWrapperSystems, + String advertiserName, + List companionAds, + String? contentType, + String creativeAdId, + String creativeId, + String dealId, + String? description, + double duration, + int height, + double skipTimeOffset, + String? surveyUrl, + String? title, + String traffickingParameters, + List uiElements, + List universalAdIds, + int vastMediaBitrate, + int vastMediaHeight, + int vastMediaWidth, + int width, + bool isLinear, + bool isSkippable, + )? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + 'dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null int.'); + final String? arg_adId = (args[1] as String?); + assert(arg_adId != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null String.'); + final AdPodInfo? arg_adPodInfo = (args[2] as AdPodInfo?); + assert(arg_adPodInfo != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null AdPodInfo.'); + final String? arg_adSystem = (args[3] as String?); + assert(arg_adSystem != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null String.'); + final List? arg_adWrapperCreativeIds = + (args[4] as List?)?.cast(); + assert(arg_adWrapperCreativeIds != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null List.'); + final List? arg_adWrapperIds = + (args[5] as List?)?.cast(); + assert(arg_adWrapperIds != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null List.'); + final List? arg_adWrapperSystems = + (args[6] as List?)?.cast(); + assert(arg_adWrapperSystems != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null List.'); + final String? arg_advertiserName = (args[7] as String?); + assert(arg_advertiserName != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null String.'); + final List? arg_companionAds = + (args[8] as List?)?.cast(); + assert(arg_companionAds != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null List.'); + final String? arg_contentType = (args[9] as String?); + final String? arg_creativeAdId = (args[10] as String?); + assert(arg_creativeAdId != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null String.'); + final String? arg_creativeId = (args[11] as String?); + assert(arg_creativeId != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null String.'); + final String? arg_dealId = (args[12] as String?); + assert(arg_dealId != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null String.'); + final String? arg_description = (args[13] as String?); + final double? arg_duration = (args[14] as double?); + assert(arg_duration != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null double.'); + final int? arg_height = (args[15] as int?); + assert(arg_height != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null int.'); + final double? arg_skipTimeOffset = (args[16] as double?); + assert(arg_skipTimeOffset != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null double.'); + final String? arg_surveyUrl = (args[17] as String?); + final String? arg_title = (args[18] as String?); + final String? arg_traffickingParameters = (args[19] as String?); + assert(arg_traffickingParameters != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null String.'); + final List? arg_uiElements = + (args[20] as List?)?.cast(); + assert(arg_uiElements != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null List.'); + final List? arg_universalAdIds = + (args[21] as List?)?.cast(); + assert(arg_universalAdIds != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null List.'); + final int? arg_vastMediaBitrate = (args[22] as int?); + assert(arg_vastMediaBitrate != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null int.'); + final int? arg_vastMediaHeight = (args[23] as int?); + assert(arg_vastMediaHeight != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null int.'); + final int? arg_vastMediaWidth = (args[24] as int?); + assert(arg_vastMediaWidth != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null int.'); + final int? arg_width = (args[25] as int?); + assert(arg_width != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null int.'); + final bool? arg_isLinear = (args[26] as bool?); + assert(arg_isLinear != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null bool.'); + final bool? arg_isSkippable = (args[27] as bool?); + assert(arg_isSkippable != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null bool.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call( + arg_adId!, + arg_adPodInfo!, + arg_adSystem!, + arg_adWrapperCreativeIds!, + arg_adWrapperIds!, + arg_adWrapperSystems!, + arg_advertiserName!, + arg_companionAds!, + arg_contentType, + arg_creativeAdId!, + arg_creativeId!, + arg_dealId!, + arg_description, + arg_duration!, + arg_height!, + arg_skipTimeOffset!, + arg_surveyUrl, + arg_title, + arg_traffickingParameters!, + arg_uiElements!, + arg_universalAdIds!, + arg_vastMediaBitrate!, + arg_vastMediaHeight!, + arg_vastMediaWidth!, + arg_width!, + arg_isLinear!, + arg_isSkippable!) ?? + Ad.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + adId: arg_adId!, + adPodInfo: arg_adPodInfo!, + adSystem: arg_adSystem!, + adWrapperCreativeIds: arg_adWrapperCreativeIds!, + adWrapperIds: arg_adWrapperIds!, + adWrapperSystems: arg_adWrapperSystems!, + advertiserName: arg_advertiserName!, + companionAds: arg_companionAds!, + contentType: arg_contentType, + creativeAdId: arg_creativeAdId!, + creativeId: arg_creativeId!, + dealId: arg_dealId!, + description: arg_description, + duration: arg_duration!, + height: arg_height!, + skipTimeOffset: arg_skipTimeOffset!, + surveyUrl: arg_surveyUrl, + title: arg_title, + traffickingParameters: arg_traffickingParameters!, + uiElements: arg_uiElements!, + universalAdIds: arg_universalAdIds!, + vastMediaBitrate: arg_vastMediaBitrate!, + vastMediaHeight: arg_vastMediaHeight!, + vastMediaWidth: arg_vastMediaWidth!, + width: arg_width!, + isLinear: arg_isLinear!, + isSkippable: arg_isSkippable!, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + Ad pigeon_copy() { + return Ad.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + adId: adId, + adPodInfo: adPodInfo, + adSystem: adSystem, + adWrapperCreativeIds: adWrapperCreativeIds, + adWrapperIds: adWrapperIds, + adWrapperSystems: adWrapperSystems, + advertiserName: advertiserName, + companionAds: companionAds, + contentType: contentType, + creativeAdId: creativeAdId, + creativeId: creativeId, + dealId: dealId, + description: description, + duration: duration, + height: height, + skipTimeOffset: skipTimeOffset, + surveyUrl: surveyUrl, + title: title, + traffickingParameters: traffickingParameters, + uiElements: uiElements, + universalAdIds: universalAdIds, + vastMediaBitrate: vastMediaBitrate, + vastMediaHeight: vastMediaHeight, + vastMediaWidth: vastMediaWidth, + width: width, + isLinear: isLinear, + isSkippable: isSkippable, + ); + } +} diff --git a/packages/interactive_media_ads/lib/src/android/interactive_media_ads_proxy.dart b/packages/interactive_media_ads/lib/src/android/interactive_media_ads_proxy.dart new file mode 100644 index 000000000000..7aa120654e84 --- /dev/null +++ b/packages/interactive_media_ads/lib/src/android/interactive_media_ads_proxy.dart @@ -0,0 +1,94 @@ +// 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 'interactive_media_ads.g.dart'; + +/// Handles constructing objects and calling static methods for the Android +/// Interactive Media Ads native library. +/// +/// This class provides dependency injection for the implementations of the +/// platform interface classes. Improving the ease of unit testing and/or +/// overriding the underlying Android classes. +/// +/// By default each function calls the default constructor of the class it +/// intends to return. +class InteractiveMediaAdsProxy { + /// Constructs an [InteractiveMediaAdsProxy]. + const InteractiveMediaAdsProxy({ + this.newContentProgressProvider = ContentProgressProvider.new, + this.newVideoProgressUpdate = VideoProgressUpdate.new, + this.newFrameLayout = FrameLayout.new, + this.newVideoView = VideoView.new, + this.newVideoAdPlayer = VideoAdPlayer.new, + this.newAdsLoadedListener = AdsLoadedListener.new, + this.newAdErrorListener = AdErrorListener.new, + this.newAdEventListener = AdEventListener.new, + this.createAdDisplayContainerImaSdkFactory = + ImaSdkFactory.createAdDisplayContainer, + this.instanceImaSdkFactory = _instanceImaSdkFactory, + this.videoTimeNotReadyVideoProgressUpdate = + _videoTimeNotReadyVideoProgressUpdate, + }); + + /// Constructs [ContentProgressProvider]. + final ContentProgressProvider Function() newContentProgressProvider; + + /// Constructs [VideoProgressUpdate]. + final VideoProgressUpdate Function({ + required int currentTimeMs, + required int durationMs, + }) newVideoProgressUpdate; + + /// Constructs [FrameLayout]. + final FrameLayout Function() newFrameLayout; + + /// Constructs [VideoView]. + final VideoView Function({ + required void Function(VideoView, MediaPlayer, int, int) onError, + void Function(VideoView, MediaPlayer)? onPrepared, + void Function(VideoView, MediaPlayer)? onCompletion, + }) newVideoView; + + /// Constructs [VideoAdPlayer]. + final VideoAdPlayer Function({ + required void Function(VideoAdPlayer, VideoAdPlayerCallback) addCallback, + required void Function(VideoAdPlayer, AdMediaInfo, AdPodInfo) loadAd, + required void Function(VideoAdPlayer, AdMediaInfo) pauseAd, + required void Function(VideoAdPlayer, AdMediaInfo) playAd, + required void Function(VideoAdPlayer) release, + required void Function(VideoAdPlayer, VideoAdPlayerCallback) removeCallback, + required void Function(VideoAdPlayer, AdMediaInfo) stopAd, + }) newVideoAdPlayer; + + /// Constructs [AdsLoadedListener]. + final AdsLoadedListener Function({ + required void Function(AdsLoadedListener, AdsManagerLoadedEvent) + onAdsManagerLoaded, + }) newAdsLoadedListener; + + /// Constructs [AdErrorListener]. + final AdErrorListener Function({ + required void Function(AdErrorListener, AdErrorEvent) onAdError, + }) newAdErrorListener; + + /// Constructs [AdEventListener]. + final AdEventListener Function({ + required void Function(AdEventListener, AdEvent) onAdEvent, + }) newAdEventListener; + + /// Calls to [ImaSdkFactory.createAdDisplayContainer]. + final Future Function(ViewGroup, VideoAdPlayer) + createAdDisplayContainerImaSdkFactory; + + /// Calls to [ImaSdkFactory.instance]. + final ImaSdkFactory Function() instanceImaSdkFactory; + + /// Calls to [VideoProgressUpdate.videoTimeNotReady]. + final VideoProgressUpdate Function() videoTimeNotReadyVideoProgressUpdate; + + static ImaSdkFactory _instanceImaSdkFactory() => ImaSdkFactory.instance; + + static VideoProgressUpdate _videoTimeNotReadyVideoProgressUpdate() => + VideoProgressUpdate.videoTimeNotReady; +} diff --git a/packages/interactive_media_ads/lib/src/android/platform_views_service_proxy.dart b/packages/interactive_media_ads/lib/src/android/platform_views_service_proxy.dart new file mode 100644 index 000000000000..6e0501cb8093 --- /dev/null +++ b/packages/interactive_media_ads/lib/src/android/platform_views_service_proxy.dart @@ -0,0 +1,53 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; + +/// Proxy that provides access to the platform views service. +/// +/// This service allows creating and controlling platform-specific views. +@immutable +class PlatformViewsServiceProxy { + /// Constructs a [PlatformViewsServiceProxy]. + const PlatformViewsServiceProxy(); + + /// Proxy method for [PlatformViewsService.initExpensiveAndroidView]. + ExpensiveAndroidViewController initExpensiveAndroidView({ + required int id, + required String viewType, + required TextDirection layoutDirection, + dynamic creationParams, + MessageCodec? creationParamsCodec, + VoidCallback? onFocus, + }) { + return PlatformViewsService.initExpensiveAndroidView( + id: id, + viewType: viewType, + layoutDirection: layoutDirection, + creationParams: creationParams, + creationParamsCodec: creationParamsCodec, + onFocus: onFocus, + ); + } + + /// Proxy method for [PlatformViewsService.initSurfaceAndroidView]. + SurfaceAndroidViewController initSurfaceAndroidView({ + required int id, + required String viewType, + required TextDirection layoutDirection, + dynamic creationParams, + MessageCodec? creationParamsCodec, + VoidCallback? onFocus, + }) { + return PlatformViewsService.initSurfaceAndroidView( + id: id, + viewType: viewType, + layoutDirection: layoutDirection, + creationParams: creationParams, + creationParamsCodec: creationParamsCodec, + onFocus: onFocus, + ); + } +} diff --git a/packages/interactive_media_ads/lib/src/content_progress_provider.dart b/packages/interactive_media_ads/lib/src/content_progress_provider.dart new file mode 100644 index 000000000000..0b0f0e6df8b5 --- /dev/null +++ b/packages/interactive_media_ads/lib/src/content_progress_provider.dart @@ -0,0 +1,92 @@ +// 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 'platform_interface/platform_interface.dart'; + +/// Allow the SDK to track progress of the content video. +/// +/// Provides updates required to enable triggering ads at configured cue points. +/// +/// ## Platform-Specific Features +/// This class contains an underlying implementation provided by the current +/// platform. Once a platform implementation is imported, the examples below +/// can be followed to use features provided by a platform's implementation. +/// +/// {@macro interactive_media_ads.ContentProgressProvider.fromPlatformCreationParams} +/// +/// Below is an example of accessing the platform-specific implementation for +/// iOS and Android: +/// +/// ```dart +/// final ContentProgressProvider provider = ContentProgressProvider(); +/// +/// if (InteractiveMediaAdsPlatform.instance is IOSInteractiveMediaAdsPlatform) { +/// final IOSContentProgressProvider iosProvider = +/// provider.platform as IOSContentProgressProvider; +/// } else if (InteractiveMediaAdsPlatform.instance is AndroidInteractiveMediaAdsPlatform) { +/// final AndroidContentProgressProvider androidProvider = +/// provider.platform as AndroidContentProgressProvider; +/// } +/// ``` +class ContentProgressProvider { + /// Constructs an [ContentProgressProvider]. + /// + /// See [ContentProgressProvider.fromPlatformCreationParams] for setting + /// parameters for a specific platform. + ContentProgressProvider() + : this.fromPlatformCreationParams( + const PlatformContentProgressProviderCreationParams(), + ); + + /// Constructs an [ContentProgressProvider] from creation params for a + /// specific platform. + /// + /// {@template interactive_media_ads.ContentProgressProvider.fromPlatformCreationParams} + /// Below is an example of setting platform-specific creation parameters for + /// iOS and Android: + /// + /// ```dart + /// PlatformContentProgressProviderCreationParams params = + /// const PlatformContentProgressProviderCreationParams(); + /// + /// if (InteractiveMediaAdsPlatform.instance is IOSInteractiveMediaAdsPlatform) { + /// params = IOSContentProgressProviderCreationParams + /// .fromPlatformContentProgressProviderCreationParams( + /// params, + /// ); + /// } else if (InteractiveMediaAdsPlatform.instance is AndroidInteractiveMediaAdsPlatform) { + /// params = AndroidContentProgressProviderCreationParams + /// .fromPlatformContentProgressProviderCreationParams( + /// params, + /// ); + /// } + /// + /// final ContentProgressProvider provider = ContentProgressProvider.fromPlatformCreationParams( + /// params, + /// ); + /// ``` + /// {@endtemplate} + ContentProgressProvider.fromPlatformCreationParams( + PlatformContentProgressProviderCreationParams params, + ) : this.fromPlatform(PlatformContentProgressProvider(params)); + + /// Constructs a [ContentProgressProvider] from a specific platform + /// implementation. + ContentProgressProvider.fromPlatform(this.platform); + + /// Implementation of [PlatformContentProgressProvider] for the current + /// platform. + final PlatformContentProgressProvider platform; + + /// Sends an update on the progress of the content video. + /// + /// When using a `Timer` to periodically send updates through this method, an + /// interval of 200ms is recommended. + Future setProgress({ + required Duration progress, + required Duration duration, + }) { + return platform.setProgress(progress: progress, duration: duration); + } +} diff --git a/packages/interactive_media_ads/lib/src/ios/enum_converter_utils.dart b/packages/interactive_media_ads/lib/src/ios/enum_converter_utils.dart new file mode 100644 index 000000000000..46c7a4e9a6bf --- /dev/null +++ b/packages/interactive_media_ads/lib/src/ios/enum_converter_utils.dart @@ -0,0 +1,85 @@ +// 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 '../platform_interface/platform_interface.dart'; +import 'interactive_media_ads.g.dart' as ima; + +/// Converts [ima.AdErrorType] to [AdErrorType]. +AdErrorType toInterfaceErrorType(ima.AdErrorType type) { + return switch (type) { + ima.AdErrorType.loadingFailed => AdErrorType.loading, + ima.AdErrorType.adPlayingFailed => AdErrorType.playing, + ima.AdErrorType.unknown => AdErrorType.unknown, + }; +} + +/// Attempts to convert an [ima.AdEventType] to [AdEventType]. +/// +/// Returns null is the type is not supported by the platform interface. +AdEventType toInterfaceEventType(ima.AdEventType type) { + return switch (type) { + ima.AdEventType.allAdsCompleted => AdEventType.allAdsCompleted, + ima.AdEventType.completed => AdEventType.complete, + ima.AdEventType.loaded => AdEventType.loaded, + ima.AdEventType.clicked => AdEventType.clicked, + ima.AdEventType.adBreakEnded => AdEventType.adBreakEnded, + ima.AdEventType.adBreakFetchError => AdEventType.adBreakFetchError, + ima.AdEventType.adBreakReady => AdEventType.adBreakReady, + ima.AdEventType.adBreakStarted => AdEventType.adBreakStarted, + ima.AdEventType.adPeriodEnded => AdEventType.adPeriodEnded, + ima.AdEventType.adPeriodStarted => AdEventType.adPeriodStarted, + ima.AdEventType.cuepointsChanged => AdEventType.cuepointsChanged, + ima.AdEventType.firstQuartile => AdEventType.firstQuartile, + ima.AdEventType.iconFallbackImageClosed => + AdEventType.iconFallbackImageClosed, + ima.AdEventType.iconTapped => AdEventType.iconTapped, + ima.AdEventType.log => AdEventType.log, + ima.AdEventType.midpoint => AdEventType.midpoint, + ima.AdEventType.pause => AdEventType.paused, + ima.AdEventType.resume => AdEventType.resumed, + ima.AdEventType.skipped => AdEventType.skipped, + ima.AdEventType.started => AdEventType.started, + ima.AdEventType.streamLoaded => AdEventType.streamLoaded, + ima.AdEventType.streamStarted => AdEventType.streamStarted, + ima.AdEventType.tapped => AdEventType.tapped, + ima.AdEventType.thirdQuartile => AdEventType.thirdQuartile, + ima.AdEventType.unknown => AdEventType.unknown, + }; +} + +/// Converts [ima.AdErrorCode] to [AdErrorCode]. +AdErrorCode toInterfaceErrorCode(ima.AdErrorCode code) { + return switch (code) { + ima.AdErrorCode.companionAdLoadingFailed => + AdErrorCode.companionAdLoadingFailed, + ima.AdErrorCode.failedToRequestAds => AdErrorCode.failedToRequestAds, + ima.AdErrorCode.invalidArguments => AdErrorCode.invalidArguments, + ima.AdErrorCode.unknownError => AdErrorCode.unknownError, + ima.AdErrorCode.vastAssetNotFound => AdErrorCode.vastAssetNotFound, + ima.AdErrorCode.vastEmptyResponse => AdErrorCode.vastEmptyResponse, + ima.AdErrorCode.vastLinearAssetMismatch => + AdErrorCode.vastLinearAssetMismatch, + ima.AdErrorCode.vastLoadTimeout => AdErrorCode.vastLoadTimeout, + ima.AdErrorCode.vastMalformedResponse => AdErrorCode.vastMalformedResponse, + ima.AdErrorCode.vastMediaLoadTimeout => AdErrorCode.vastMediaLoadTimeout, + ima.AdErrorCode.vastTooManyRedirects => AdErrorCode.vastTooManyRedirects, + ima.AdErrorCode.vastTraffickingError => AdErrorCode.vastTraffickingError, + ima.AdErrorCode.videoPlayError => AdErrorCode.videoPlayError, + ima.AdErrorCode.adslotNotVisible => AdErrorCode.adslotNotVisible, + ima.AdErrorCode.apiError => AdErrorCode.apiError, + ima.AdErrorCode.contentPlayheadMissing => + AdErrorCode.contentPlayheadMissing, + ima.AdErrorCode.failedLoadingAd => AdErrorCode.failedLoadingAd, + ima.AdErrorCode.osRuntimeTooOld => AdErrorCode.osRuntimeTooOld, + ima.AdErrorCode.playlistMalformedResponse => + AdErrorCode.playlistMalformedResponse, + ima.AdErrorCode.requiredListenersNotAdded => + AdErrorCode.requiredListenersNotAdded, + ima.AdErrorCode.streamInitializationFailed => + AdErrorCode.streamInitializationFailed, + ima.AdErrorCode.vastInvalidUrl => AdErrorCode.vastInvalidUrl, + ima.AdErrorCode.videoElementUsed => AdErrorCode.videoElementUsed, + ima.AdErrorCode.videoElementRequired => AdErrorCode.videoElementRequired, + }; +} diff --git a/packages/interactive_media_ads/lib/src/ios/interactive_media_ads.g.dart b/packages/interactive_media_ads/lib/src/ios/interactive_media_ads.g.dart new file mode 100644 index 000000000000..a26cfa675acb --- /dev/null +++ b/packages/interactive_media_ads/lib/src/ios/interactive_media_ads.g.dart @@ -0,0 +1,4061 @@ +// 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 (v22.5.0), 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 + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; + +import 'package:flutter/foundation.dart' + show ReadBuffer, WriteBuffer, immutable, protected; +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart' show WidgetsFlutterBinding; + +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); +} + +List wrapResponse( + {Object? result, PlatformException? error, bool empty = false}) { + if (empty) { + return []; + } + if (error == null) { + return [result]; + } + return [error.code, error.message, error.details]; +} + +/// An immutable object that serves as the base class for all ProxyApis and +/// can provide functional copies of itself. +/// +/// All implementers are expected to be [immutable] as defined by the annotation +/// and override [pigeon_copy] returning an instance of itself. +@immutable +abstract class PigeonInternalProxyApiBaseClass { + /// Construct a [PigeonInternalProxyApiBaseClass]. + PigeonInternalProxyApiBaseClass({ + this.pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + }) : pigeon_instanceManager = + pigeon_instanceManager ?? PigeonInstanceManager.instance; + + /// Sends and receives binary data across the Flutter platform barrier. + /// + /// If it is null, the default BinaryMessenger will be used, which routes to + /// the host platform. + @protected + final BinaryMessenger? pigeon_binaryMessenger; + + /// Maintains instances stored to communicate with native language objects. + @protected + final PigeonInstanceManager pigeon_instanceManager; + + /// Instantiates and returns a functionally identical object to oneself. + /// + /// Outside of tests, this method should only ever be called by + /// [PigeonInstanceManager]. + /// + /// Subclasses should always override their parent's implementation of this + /// method. + @protected + PigeonInternalProxyApiBaseClass pigeon_copy(); +} + +/// Maintains instances used to communicate with the native objects they +/// represent. +/// +/// Added instances are stored as weak references and their copies are stored +/// as strong references to maintain access to their variables and callback +/// methods. Both are stored with the same identifier. +/// +/// When a weak referenced instance becomes inaccessible, +/// [onWeakReferenceRemoved] is called with its associated identifier. +/// +/// If an instance is retrieved and has the possibility to be used, +/// (e.g. calling [getInstanceWithWeakReference]) a copy of the strong reference +/// is added as a weak reference with the same identifier. This prevents a +/// scenario where the weak referenced instance was released and then later +/// returned by the host platform. +class PigeonInstanceManager { + /// Constructs a [PigeonInstanceManager]. + PigeonInstanceManager({required void Function(int) onWeakReferenceRemoved}) { + this.onWeakReferenceRemoved = (int identifier) { + _weakInstances.remove(identifier); + onWeakReferenceRemoved(identifier); + }; + _finalizer = Finalizer(this.onWeakReferenceRemoved); + } + + // Identifiers are locked to a specific range to avoid collisions with objects + // created simultaneously by the host platform. + // Host uses identifiers >= 2^16 and Dart is expected to use values n where, + // 0 <= n < 2^16. + static const int _maxDartCreatedIdentifier = 65536; + + /// The default [PigeonInstanceManager] used by ProxyApis. + /// + /// On creation, this manager makes a call to clear the native + /// InstanceManager. This is to prevent identifier conflicts after a host + /// restart. + static final PigeonInstanceManager instance = _initInstance(); + + // Expando is used because it doesn't prevent its keys from becoming + // inaccessible. This allows the manager to efficiently retrieve an identifier + // of an instance without holding a strong reference to that instance. + // + // It also doesn't use `==` to search for identifiers, which would lead to an + // infinite loop when comparing an object to its copy. (i.e. which was caused + // by calling instanceManager.getIdentifier() inside of `==` while this was a + // HashMap). + final Expando _identifiers = Expando(); + final Map> + _weakInstances = >{}; + final Map _strongInstances = + {}; + late final Finalizer _finalizer; + int _nextIdentifier = 0; + + /// Called when a weak referenced instance is removed by [removeWeakReference] + /// or becomes inaccessible. + late final void Function(int) onWeakReferenceRemoved; + + static PigeonInstanceManager _initInstance() { + WidgetsFlutterBinding.ensureInitialized(); + final _PigeonInternalInstanceManagerApi api = + _PigeonInternalInstanceManagerApi(); + // Clears the native `PigeonInstanceManager` on the initial use of the Dart one. + api.clear(); + final PigeonInstanceManager instanceManager = PigeonInstanceManager( + onWeakReferenceRemoved: (int identifier) { + api.removeStrongReference(identifier); + }, + ); + _PigeonInternalInstanceManagerApi.setUpMessageHandlers( + instanceManager: instanceManager); + IMAAdDisplayContainer.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + UIView.pigeon_setUpMessageHandlers(pigeon_instanceManager: instanceManager); + UIViewController.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + IMAContentPlayhead.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + IMAAdsLoader.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + IMASettings.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + IMAAdsRequest.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + IMAAdsLoaderDelegate.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + IMAAdsLoadedData.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + IMAAdLoadingErrorData.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + IMAAdError.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + IMAAdsManager.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + IMAAdsManagerDelegate.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + IMAAdEvent.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + IMAAdsRenderingSettings.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + NSObject.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + IMAFriendlyObstruction.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + IMACompanionAd.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + IMACompanionAdSlot.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + IMACompanionDelegate.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + return instanceManager; + } + + /// Adds a new instance that was instantiated by Dart. + /// + /// In other words, Dart wants to add a new instance that will represent + /// an object that will be instantiated on the host platform. + /// + /// Throws assertion error if the instance has already been added. + /// + /// Returns the randomly generated id of the [instance] added. + int addDartCreatedInstance(PigeonInternalProxyApiBaseClass instance) { + final int identifier = _nextUniqueIdentifier(); + _addInstanceWithIdentifier(instance, identifier); + return identifier; + } + + /// Removes the instance, if present, and call [onWeakReferenceRemoved] with + /// its identifier. + /// + /// Returns the identifier associated with the removed instance. Otherwise, + /// `null` if the instance was not found in this manager. + /// + /// This does not remove the strong referenced instance associated with + /// [instance]. This can be done with [remove]. + int? removeWeakReference(PigeonInternalProxyApiBaseClass instance) { + final int? identifier = getIdentifier(instance); + if (identifier == null) { + return null; + } + + _identifiers[instance] = null; + _finalizer.detach(instance); + onWeakReferenceRemoved(identifier); + + return identifier; + } + + /// Removes [identifier] and its associated strongly referenced instance, if + /// present, from the manager. + /// + /// Returns the strong referenced instance associated with [identifier] before + /// it was removed. Returns `null` if [identifier] was not associated with + /// any strong reference. + /// + /// This does not remove the weak referenced instance associated with + /// [identifier]. This can be done with [removeWeakReference]. + T? remove(int identifier) { + return _strongInstances.remove(identifier) as T?; + } + + /// Retrieves the instance associated with identifier. + /// + /// The value returned is chosen from the following order: + /// + /// 1. A weakly referenced instance associated with identifier. + /// 2. If the only instance associated with identifier is a strongly + /// referenced instance, a copy of the instance is added as a weak reference + /// with the same identifier. Returning the newly created copy. + /// 3. If no instance is associated with identifier, returns null. + /// + /// This method also expects the host `InstanceManager` to have a strong + /// reference to the instance the identifier is associated with. + T? getInstanceWithWeakReference( + int identifier) { + final PigeonInternalProxyApiBaseClass? weakInstance = + _weakInstances[identifier]?.target; + + if (weakInstance == null) { + final PigeonInternalProxyApiBaseClass? strongInstance = + _strongInstances[identifier]; + if (strongInstance != null) { + final PigeonInternalProxyApiBaseClass copy = + strongInstance.pigeon_copy(); + _identifiers[copy] = identifier; + _weakInstances[identifier] = + WeakReference(copy); + _finalizer.attach(copy, identifier, detach: copy); + return copy as T; + } + return strongInstance as T?; + } + + return weakInstance as T; + } + + /// Retrieves the identifier associated with instance. + int? getIdentifier(PigeonInternalProxyApiBaseClass instance) { + return _identifiers[instance]; + } + + /// Adds a new instance that was instantiated by the host platform. + /// + /// In other words, the host platform wants to add a new instance that + /// represents an object on the host platform. Stored with [identifier]. + /// + /// Throws assertion error if the instance or its identifier has already been + /// added. + /// + /// Returns unique identifier of the [instance] added. + void addHostCreatedInstance( + PigeonInternalProxyApiBaseClass instance, int identifier) { + _addInstanceWithIdentifier(instance, identifier); + } + + void _addInstanceWithIdentifier( + PigeonInternalProxyApiBaseClass instance, int identifier) { + assert(!containsIdentifier(identifier)); + assert(getIdentifier(instance) == null); + assert(identifier >= 0); + + _identifiers[instance] = identifier; + _weakInstances[identifier] = + WeakReference(instance); + _finalizer.attach(instance, identifier, detach: instance); + + final PigeonInternalProxyApiBaseClass copy = instance.pigeon_copy(); + _identifiers[copy] = identifier; + _strongInstances[identifier] = copy; + } + + /// Whether this manager contains the given [identifier]. + bool containsIdentifier(int identifier) { + return _weakInstances.containsKey(identifier) || + _strongInstances.containsKey(identifier); + } + + int _nextUniqueIdentifier() { + late int identifier; + do { + identifier = _nextIdentifier; + _nextIdentifier = (_nextIdentifier + 1) % _maxDartCreatedIdentifier; + } while (containsIdentifier(identifier)); + return identifier; + } +} + +/// Generated API for managing the Dart and native `PigeonInstanceManager`s. +class _PigeonInternalInstanceManagerApi { + /// Constructor for [_PigeonInternalInstanceManagerApi]. + _PigeonInternalInstanceManagerApi({BinaryMessenger? binaryMessenger}) + : pigeonVar_binaryMessenger = binaryMessenger; + + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + static void setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? binaryMessenger, + PigeonInstanceManager? instanceManager, + }) { + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.PigeonInternalInstanceManager.removeStrongReference', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.PigeonInternalInstanceManager.removeStrongReference was null.'); + final List args = (message as List?)!; + final int? arg_identifier = (args[0] as int?); + assert(arg_identifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.PigeonInternalInstanceManager.removeStrongReference was null, expected non-null int.'); + try { + (instanceManager ?? PigeonInstanceManager.instance) + .remove(arg_identifier!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + Future removeStrongReference(int identifier) async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.PigeonInternalInstanceManager.removeStrongReference'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([identifier]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Clear the native `PigeonInstanceManager`. + /// + /// This is typically called after a hot restart. + Future clear() async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.PigeonInternalInstanceManager.clear'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } +} + +class _PigeonInternalProxyApiBaseCodec extends _PigeonCodec { + const _PigeonInternalProxyApiBaseCodec(this.instanceManager); + final PigeonInstanceManager instanceManager; + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is PigeonInternalProxyApiBaseClass) { + buffer.putUint8(128); + writeValue(buffer, instanceManager.getIdentifier(value)); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 128: + return instanceManager + .getInstanceWithWeakReference(readValue(buffer)! as int); + default: + return super.readValueOfType(type, buffer); + } + } +} + +/// Possible error types while loading or playing ads. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Enums/IMAErrorType.html. +enum AdErrorType { + /// An error occurred while loading the ads. + loadingFailed, + + /// An error occurred while playing the ads. + adPlayingFailed, + + /// An unexpected error occurred while loading or playing the ads. + /// + /// This may mean that the SDK wasn’t loaded properly or the wrapper doesn't + /// recognize this value. + unknown, +} + +/// Possible error codes raised while loading or playing ads. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Enums/IMAErrorCode.html. +enum AdErrorCode { + /// The ad slot is not visible on the page. + adslotNotVisible, + + /// Generic invalid usage of the API. + apiError, + + /// A companion ad failed to load or render. + companionAdLoadingFailed, + + /// Content playhead was not passed in, but list of ads has been returned from + /// the server. + contentPlayheadMissing, + + /// There was an error loading the ad. + failedLoadingAd, + + /// There was a problem requesting ads from the server. + failedToRequestAds, + + /// Invalid arguments were provided to SDK methods. + invalidArguments, + + /// The version of the runtime is too old. + osRuntimeTooOld, + + /// Ads list response was malformed. + playlistMalformedResponse, + + /// Listener for at least one of the required vast events was not added. + requiredListenersNotAdded, + + /// There was an error initializing the stream. + streamInitializationFailed, + + /// An unexpected error occurred and the cause is not known. + unknownError, + + /// No assets were found in the VAST ad response. + vastAssetNotFound, + + /// A VAST response containing a single `` tag with no child tags. + vastEmptyResponse, + + /// At least one VAST wrapper loaded and a subsequent wrapper or inline ad + /// load has resulted in a 404 response code. + vastInvalidUrl, + + /// Assets were found in the VAST ad response for a linear ad, but none of + /// them matched the video player's capabilities. + vastLinearAssetMismatch, + + /// The VAST URI provided, or a VAST URI provided in a subsequent Wrapper + /// element, was either unavailable or reached a timeout, as defined by the + /// video player. + vastLoadTimeout, + + /// The ad response was not recognized as a valid VAST ad. + vastMalformedResponse, + + /// Failed to load media assets from a VAST response. + vastMediaLoadTimeout, + + /// The maximum number of VAST wrapper redirects has been reached. + vastTooManyRedirects, + + /// Trafficking error. + /// + /// Video player received an ad type that it was not expecting and/or cannot + /// display. + vastTraffickingError, + + /// Another VideoAdsManager is still using the video. + videoElementUsed, + + /// A video element was not specified where it was required. + videoElementRequired, + + /// There was an error playing the video ad. + videoPlayError, +} + +/// Different event types sent by the IMAAdsManager to its delegate. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Enums/IMAAdEventType.html. +enum AdEventType { + /// Fired the first time each ad break ends. + adBreakEnded, + + /// Fired when an ad break will not play back any ads. + adBreakFetchError, + + /// Fired when an ad break is ready. + adBreakReady, + + /// Fired first time each ad break begins playback. + adBreakStarted, + + /// Fired every time the stream switches from advertising or slate to content. + adPeriodEnded, + + /// Fired every time the stream switches from content to advertising or slate. + adPeriodStarted, + + /// All valid ads managed by the ads manager have completed or the ad response + /// did not return any valid ads. + allAdsCompleted, + + /// Fired when an ad is clicked. + clicked, + + /// Single ad has finished. + completed, + + /// Cuepoints changed for VOD stream (only used for dynamic ad insertion). + cuepointsChanged, + + /// First quartile of a linear ad was reached. + firstQuartile, + + /// The user has closed the icon fallback image dialog. + iconFallbackImageClosed, + + /// The user has tapped an ad icon. + iconTapped, + + /// An ad was loaded. + loaded, + + /// A log event for the ads being played. + log, + + /// Midpoint of a linear ad was reached. + midpoint, + + /// Ad paused. + pause, + + /// Ad resumed. + resume, + + /// Fired when an ad was skipped. + skipped, + + /// Fired when an ad starts playing. + started, + + /// Stream request has loaded (only used for dynamic ad insertion). + streamLoaded, + + /// Stream has started playing (only used for dynamic ad insertion). + streamStarted, + + /// Ad tapped. + tapped, + + /// Third quartile of a linear ad was reached.. + thirdQuartile, + + /// The event type is not recognized by this wrapper. + unknown, +} + +/// The values that can be returned in a change dictionary. +/// +/// See https://developer.apple.com/documentation/foundation/nskeyvalueobservingoptions?language=objc. +enum KeyValueObservingOptions { + /// Indicates that the change dictionary should provide the new attribute + /// value, if applicable. + newValue, + + /// Indicates that the change dictionary should contain the old attribute + /// value, if applicable. + oldValue, + + /// If specified, a notification should be sent to the observer immediately, + /// before the observer registration method even returns. + initialValue, + + /// Whether separate notifications should be sent to the observer before and + /// after each change, instead of a single notification after the change. + priorNotification, +} + +/// The kinds of changes that can be observed.. +/// +/// See https://developer.apple.com/documentation/foundation/nskeyvaluechange?language=objc. +enum KeyValueChange { + /// Indicates that the value of the observed key path was set to a new value. + setting, + + /// Indicates that an object has been inserted into the to-many relationship + /// that is being observed. + insertion, + + /// Indicates that an object has been removed from the to-many relationship + /// that is being observed. + removal, + + /// Indicates that an object has been replaced in the to-many relationship + /// that is being observed. + replacement, +} + +/// The keys that can appear in the change dictionary.. +/// +/// See https://developer.apple.com/documentation/foundation/nskeyvaluechangekey?language=objc. +enum KeyValueChangeKey { + /// If the value of the kindKey entry is NSKeyValueChange.insertion, + /// NSKeyValueChange.removal, or NSKeyValueChange.replacement, the value of + /// this key is an NSIndexSet object that contains the indexes of the + /// inserted, removed, or replaced objects. + indexes, + + /// An NSNumber object that contains a value corresponding to one of the + /// NSKeyValueChange enums, indicating what sort of change has occurred. + kind, + + /// If the value of the kindKey entry is NSKeyValueChange.setting, and new was + /// specified when the observer was registered, the value of this key is the + /// new value for the attribute. + newValue, + + /// If the prior option was specified when the observer was registered this + /// notification is sent prior to a change. + notificationIsPrior, + + /// If the value of the kindKey entry is NSKeyValueChange.setting, and old was + /// specified when the observer was registered, the value of this key is the + /// value before the attribute was changed. + oldValue, + + /// The key is not recognized by this wrapper. + unknown, +} + +/// A list of purposes for which an obstruction would be registered as friendly. +/// +/// See https://developers.google.com/ad-manager/dynamic-ad-insertion/sdk/ios/reference/Enums/IMAFriendlyObstructionPurpose.html. +enum FriendlyObstructionPurpose { + mediaControls, + closeAd, + notVisible, + other, + + /// The purpose type is not recognized by this wrapper. + unknown, +} + +/// Different UI elements that can be customized. +/// +/// See https://developers.google.com/ad-manager/dynamic-ad-insertion/sdk/ios/reference/Enums/IMAUiElementType.html. +enum UIElementType { + /// Ad attribution UI element. + adAttribution, + + /// Ad countdown element. + countdown, + + /// The element is not recognized by this wrapper. + unknown, +} + +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is AdErrorType) { + buffer.putUint8(129); + writeValue(buffer, value.index); + } else if (value is AdErrorCode) { + buffer.putUint8(130); + writeValue(buffer, value.index); + } else if (value is AdEventType) { + buffer.putUint8(131); + writeValue(buffer, value.index); + } else if (value is KeyValueObservingOptions) { + buffer.putUint8(132); + writeValue(buffer, value.index); + } else if (value is KeyValueChange) { + buffer.putUint8(133); + writeValue(buffer, value.index); + } else if (value is KeyValueChangeKey) { + buffer.putUint8(134); + writeValue(buffer, value.index); + } else if (value is FriendlyObstructionPurpose) { + buffer.putUint8(135); + writeValue(buffer, value.index); + } else if (value is UIElementType) { + buffer.putUint8(136); + writeValue(buffer, value.index); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 129: + final int? value = readValue(buffer) as int?; + return value == null ? null : AdErrorType.values[value]; + case 130: + final int? value = readValue(buffer) as int?; + return value == null ? null : AdErrorCode.values[value]; + case 131: + final int? value = readValue(buffer) as int?; + return value == null ? null : AdEventType.values[value]; + case 132: + final int? value = readValue(buffer) as int?; + return value == null ? null : KeyValueObservingOptions.values[value]; + case 133: + final int? value = readValue(buffer) as int?; + return value == null ? null : KeyValueChange.values[value]; + case 134: + final int? value = readValue(buffer) as int?; + return value == null ? null : KeyValueChangeKey.values[value]; + case 135: + final int? value = readValue(buffer) as int?; + return value == null ? null : FriendlyObstructionPurpose.values[value]; + case 136: + final int? value = readValue(buffer) as int?; + return value == null ? null : UIElementType.values[value]; + default: + return super.readValueOfType(type, buffer); + } + } +} + +/// The `IMAAdDisplayContainer` is responsible for managing the ad container +/// view and companion ad slots used for ad playback. +/// +/// See https://developers.google.com/ad-manager/dynamic-ad-insertion/sdk/ios/reference/Classes/IMAAdDisplayContainer. +class IMAAdDisplayContainer extends NSObject { + IMAAdDisplayContainer({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required UIView adContainer, + UIViewController? adContainerViewController, + }) : super.pigeon_detached() { + final int pigeonVar_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(this); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAAdDisplayContainer; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + () async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAAdDisplayContainer.pigeon_defaultConstructor'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([ + pigeonVar_instanceIdentifier, + adContainer, + adContainerViewController + ]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + }(); + } + + /// Constructs [IMAAdDisplayContainer] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + IMAAdDisplayContainer.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }) : super.pigeon_detached(); + + late final _PigeonInternalProxyApiBaseCodec + _pigeonVar_codecIMAAdDisplayContainer = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + IMAAdDisplayContainer Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.IMAAdDisplayContainer.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdDisplayContainer.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdDisplayContainer.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + IMAAdDisplayContainer.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + IMAAdDisplayContainer pigeon_copy() { + return IMAAdDisplayContainer.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// An object that manages the content for a rectangular area on the screen. +/// +/// See https://developer.apple.com/documentation/uikit/uiview. +class UIView extends NSObject { + /// Constructs [UIView] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + UIView.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }) : super.pigeon_detached(); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + UIView Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.UIView.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.UIView.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.UIView.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + UIView.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + UIView pigeon_copy() { + return UIView.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// An object that manages a view hierarchy for your UIKit app. +/// +/// See https://developer.apple.com/documentation/uikit/uiviewcontroller. +class UIViewController extends NSObject { + UIViewController({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + this.viewDidAppear, + }) : super.pigeon_detached() { + final int pigeonVar_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(this); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecUIViewController; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + () async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.UIViewController.pigeon_defaultConstructor'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([pigeonVar_instanceIdentifier]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + }(); + } + + /// Constructs [UIViewController] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + UIViewController.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + this.viewDidAppear, + }) : super.pigeon_detached(); + + late final _PigeonInternalProxyApiBaseCodec _pigeonVar_codecUIViewController = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + /// Notifies the view controller that its view was added to a view hierarchy. + /// + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// with a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final UIViewController instance = UIViewController( + /// viewDidAppear: (UIViewController pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, [PigeonInstanceManager.removeWeakReference] can be used to + /// release the associated Native object manually. + final void Function( + UIViewController pigeon_instance, + bool animated, + )? viewDidAppear; + + /// Retrieves the view that the controller manages. + /// + /// For convenience this is a `final` attached field despite this being + /// settable. Since this is not a part of the IMA SDK this is slightly changed + /// for convenience. Note that this wrapper should not add the ability to set + /// this property as it should not be needed anyways. + late final UIView view = pigeonVar_view(); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + UIViewController Function()? pigeon_newInstance, + void Function( + UIViewController pigeon_instance, + bool animated, + )? viewDidAppear, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.UIViewController.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.UIViewController.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.UIViewController.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + UIViewController.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.UIViewController.viewDidAppear', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.UIViewController.viewDidAppear was null.'); + final List args = (message as List?)!; + final UIViewController? arg_pigeon_instance = + (args[0] as UIViewController?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.UIViewController.viewDidAppear was null, expected non-null UIViewController.'); + final bool? arg_animated = (args[1] as bool?); + assert(arg_animated != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.UIViewController.viewDidAppear was null, expected non-null bool.'); + try { + (viewDidAppear ?? arg_pigeon_instance!.viewDidAppear) + ?.call(arg_pigeon_instance!, arg_animated!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + UIView pigeonVar_view() { + final UIView pigeonVar_instance = UIView.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecUIViewController; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + final int pigeonVar_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(pigeonVar_instance); + () async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.UIViewController.view'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, pigeonVar_instanceIdentifier]) + as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + }(); + return pigeonVar_instance; + } + + @override + UIViewController pigeon_copy() { + return UIViewController.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + viewDidAppear: viewDidAppear, + ); + } +} + +/// Defines an interface for a class that tracks video content progress and +/// exposes a key value observable property |currentTime|. +/// +/// See https://developers.google.com/ad-manager/dynamic-ad-insertion/sdk/ios/reference/Protocols/IMAContentPlayhead. +class IMAContentPlayhead extends NSObject { + IMAContentPlayhead({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }) : super.pigeon_detached() { + final int pigeonVar_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(this); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAContentPlayhead; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + () async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAContentPlayhead.pigeon_defaultConstructor'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([pigeonVar_instanceIdentifier]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + }(); + } + + /// Constructs [IMAContentPlayhead] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + IMAContentPlayhead.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }) : super.pigeon_detached(); + + late final _PigeonInternalProxyApiBaseCodec + _pigeonVar_codecIMAContentPlayhead = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + IMAContentPlayhead Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.IMAContentPlayhead.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAContentPlayhead.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAContentPlayhead.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + IMAContentPlayhead.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + /// Reflects the current playback time in seconds for the content. + Future setCurrentTime(double timeInterval) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAContentPlayhead; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAContentPlayhead.setCurrentTime'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, timeInterval]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + @override + IMAContentPlayhead pigeon_copy() { + return IMAContentPlayhead.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// Allows the requesting of ads from the ad server. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes/IMAAdsLoader. +class IMAAdsLoader extends NSObject { + IMAAdsLoader({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + IMASettings? settings, + }) : super.pigeon_detached() { + final int pigeonVar_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(this); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAAdsLoader; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + () async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsLoader.pigeon_defaultConstructor'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([pigeonVar_instanceIdentifier, settings]) + as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + }(); + } + + /// Constructs [IMAAdsLoader] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + IMAAdsLoader.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }) : super.pigeon_detached(); + + late final _PigeonInternalProxyApiBaseCodec _pigeonVar_codecIMAAdsLoader = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + IMAAdsLoader Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsLoader.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsLoader.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsLoader.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + IMAAdsLoader.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + /// Signal to the SDK that the content has completed. + Future contentComplete() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAAdsLoader; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsLoader.contentComplete'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Request ads from the ad server. + Future requestAds(IMAAdsRequest request) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAAdsLoader; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsLoader.requestAds'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, request]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Delegate that receives `IMAAdsLoaderDelegate` callbacks. + /// + /// Note that this sets to a `weak` property in Swift. + Future setDelegate(IMAAdsLoaderDelegate? delegate) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAAdsLoader; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsLoader.setDelegate'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, delegate]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + @override + IMAAdsLoader pigeon_copy() { + return IMAAdsLoader.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// The IMASettings class stores SDK wide settings. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes/IMASettings.html. +class IMASettings extends NSObject { + /// Constructs [IMASettings] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + IMASettings.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }) : super.pigeon_detached(); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + IMASettings Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.IMASettings.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMASettings.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMASettings.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + IMASettings.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + IMASettings pigeon_copy() { + return IMASettings.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// Data class describing the ad request. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes/IMAAdsRequest. +class IMAAdsRequest extends NSObject { + /// Initializes an ads request instance with the given ad tag URL and ad + /// display container. + IMAAdsRequest({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required String adTagUrl, + required IMAAdDisplayContainer adDisplayContainer, + IMAContentPlayhead? contentPlayhead, + }) : super.pigeon_detached() { + final int pigeonVar_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(this); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAAdsRequest; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + () async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsRequest.pigeon_defaultConstructor'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([ + pigeonVar_instanceIdentifier, + adTagUrl, + adDisplayContainer, + contentPlayhead + ]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + }(); + } + + /// Constructs [IMAAdsRequest] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + IMAAdsRequest.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }) : super.pigeon_detached(); + + late final _PigeonInternalProxyApiBaseCodec _pigeonVar_codecIMAAdsRequest = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + IMAAdsRequest Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsRequest.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsRequest.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsRequest.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + IMAAdsRequest.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + IMAAdsRequest pigeon_copy() { + return IMAAdsRequest.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// Delegate object that receives state change callbacks from `IMAAdsLoader`. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Protocols/IMAAdsLoaderDelegate.html. +class IMAAdsLoaderDelegate extends NSObject { + IMAAdsLoaderDelegate({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.adLoaderLoadedWith, + required this.adsLoaderFailedWithErrorData, + }) : super.pigeon_detached() { + final int pigeonVar_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(this); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAAdsLoaderDelegate; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + () async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsLoaderDelegate.pigeon_defaultConstructor'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([pigeonVar_instanceIdentifier]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + }(); + } + + /// Constructs [IMAAdsLoaderDelegate] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + IMAAdsLoaderDelegate.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.adLoaderLoadedWith, + required this.adsLoaderFailedWithErrorData, + }) : super.pigeon_detached(); + + late final _PigeonInternalProxyApiBaseCodec + _pigeonVar_codecIMAAdsLoaderDelegate = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + /// Called when ads are successfully loaded from the ad servers by the loader. + /// + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// with a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final IMAAdsLoaderDelegate instance = IMAAdsLoaderDelegate( + /// adLoaderLoadedWith: (IMAAdsLoaderDelegate pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, [PigeonInstanceManager.removeWeakReference] can be used to + /// release the associated Native object manually. + final void Function( + IMAAdsLoaderDelegate pigeon_instance, + IMAAdsLoader loader, + IMAAdsLoadedData adsLoadedData, + ) adLoaderLoadedWith; + + /// Error reported by the ads loader when loading or requesting an ad fails. + /// + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// with a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final IMAAdsLoaderDelegate instance = IMAAdsLoaderDelegate( + /// adsLoaderFailedWithErrorData: (IMAAdsLoaderDelegate pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, [PigeonInstanceManager.removeWeakReference] can be used to + /// release the associated Native object manually. + final void Function( + IMAAdsLoaderDelegate pigeon_instance, + IMAAdsLoader loader, + IMAAdLoadingErrorData adErrorData, + ) adsLoaderFailedWithErrorData; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + void Function( + IMAAdsLoaderDelegate pigeon_instance, + IMAAdsLoader loader, + IMAAdsLoadedData adsLoadedData, + )? adLoaderLoadedWith, + void Function( + IMAAdsLoaderDelegate pigeon_instance, + IMAAdsLoader loader, + IMAAdLoadingErrorData adErrorData, + )? adsLoaderFailedWithErrorData, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsLoaderDelegate.adLoaderLoadedWith', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsLoaderDelegate.adLoaderLoadedWith was null.'); + final List args = (message as List?)!; + final IMAAdsLoaderDelegate? arg_pigeon_instance = + (args[0] as IMAAdsLoaderDelegate?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsLoaderDelegate.adLoaderLoadedWith was null, expected non-null IMAAdsLoaderDelegate.'); + final IMAAdsLoader? arg_loader = (args[1] as IMAAdsLoader?); + assert(arg_loader != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsLoaderDelegate.adLoaderLoadedWith was null, expected non-null IMAAdsLoader.'); + final IMAAdsLoadedData? arg_adsLoadedData = + (args[2] as IMAAdsLoadedData?); + assert(arg_adsLoadedData != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsLoaderDelegate.adLoaderLoadedWith was null, expected non-null IMAAdsLoadedData.'); + try { + (adLoaderLoadedWith ?? arg_pigeon_instance!.adLoaderLoadedWith) + .call(arg_pigeon_instance!, arg_loader!, arg_adsLoadedData!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsLoaderDelegate.adsLoaderFailedWithErrorData', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsLoaderDelegate.adsLoaderFailedWithErrorData was null.'); + final List args = (message as List?)!; + final IMAAdsLoaderDelegate? arg_pigeon_instance = + (args[0] as IMAAdsLoaderDelegate?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsLoaderDelegate.adsLoaderFailedWithErrorData was null, expected non-null IMAAdsLoaderDelegate.'); + final IMAAdsLoader? arg_loader = (args[1] as IMAAdsLoader?); + assert(arg_loader != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsLoaderDelegate.adsLoaderFailedWithErrorData was null, expected non-null IMAAdsLoader.'); + final IMAAdLoadingErrorData? arg_adErrorData = + (args[2] as IMAAdLoadingErrorData?); + assert(arg_adErrorData != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsLoaderDelegate.adsLoaderFailedWithErrorData was null, expected non-null IMAAdLoadingErrorData.'); + try { + (adsLoaderFailedWithErrorData ?? + arg_pigeon_instance!.adsLoaderFailedWithErrorData) + .call(arg_pigeon_instance!, arg_loader!, arg_adErrorData!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + IMAAdsLoaderDelegate pigeon_copy() { + return IMAAdsLoaderDelegate.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + adLoaderLoadedWith: adLoaderLoadedWith, + adsLoaderFailedWithErrorData: adsLoaderFailedWithErrorData, + ); + } +} + +/// Ad data that is returned when the ads loader loads the ad. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes/IMAAdsLoadedData.html. +class IMAAdsLoadedData extends NSObject { + /// Constructs [IMAAdsLoadedData] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + IMAAdsLoadedData.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + this.adsManager, + }) : super.pigeon_detached(); + + /// The ads manager instance created by the ads loader. + /// + /// Will be null when using dynamic ad insertion. + final IMAAdsManager? adsManager; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + IMAAdsLoadedData Function(IMAAdsManager? adsManager)? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsLoadedData.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsLoadedData.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsLoadedData.pigeon_newInstance was null, expected non-null int.'); + final IMAAdsManager? arg_adsManager = (args[1] as IMAAdsManager?); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call(arg_adsManager) ?? + IMAAdsLoadedData.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + adsManager: arg_adsManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + IMAAdsLoadedData pigeon_copy() { + return IMAAdsLoadedData.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + adsManager: adsManager, + ); + } +} + +/// Ad error data that is returned when the ads loader fails to load the ad. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes/IMAAdLoadingErrorData.html. +class IMAAdLoadingErrorData extends NSObject { + /// Constructs [IMAAdLoadingErrorData] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + IMAAdLoadingErrorData.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.adError, + }) : super.pigeon_detached(); + + /// The ad error that occurred while loading the ad. + final IMAAdError adError; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + IMAAdLoadingErrorData Function(IMAAdError adError)? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.IMAAdLoadingErrorData.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdLoadingErrorData.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdLoadingErrorData.pigeon_newInstance was null, expected non-null int.'); + final IMAAdError? arg_adError = (args[1] as IMAAdError?); + assert(arg_adError != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdLoadingErrorData.pigeon_newInstance was null, expected non-null IMAAdError.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call(arg_adError!) ?? + IMAAdLoadingErrorData.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + adError: arg_adError!, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + IMAAdLoadingErrorData pigeon_copy() { + return IMAAdLoadingErrorData.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + adError: adError, + ); + } +} + +/// Surfaces an error that occurred during ad loading or playing. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes/IMAAdError.html. +class IMAAdError extends NSObject { + /// Constructs [IMAAdError] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + IMAAdError.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.type, + required this.code, + this.message, + }) : super.pigeon_detached(); + + /// The type of error that occurred during ad loading or ad playing. + final AdErrorType type; + + /// The error code for obtaining more specific information about the error. + final AdErrorCode code; + + /// A brief description about the error. + final String? message; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + IMAAdError Function( + AdErrorType type, + AdErrorCode code, + String? message, + )? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.IMAAdError.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdError.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdError.pigeon_newInstance was null, expected non-null int.'); + final AdErrorType? arg_type = (args[1] as AdErrorType?); + assert(arg_type != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdError.pigeon_newInstance was null, expected non-null AdErrorType.'); + final AdErrorCode? arg_code = (args[2] as AdErrorCode?); + assert(arg_code != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdError.pigeon_newInstance was null, expected non-null AdErrorCode.'); + final String? arg_message = (args[3] as String?); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call(arg_type!, arg_code!, arg_message) ?? + IMAAdError.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + type: arg_type!, + code: arg_code!, + message: arg_message, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + IMAAdError pigeon_copy() { + return IMAAdError.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + type: type, + code: code, + message: message, + ); + } +} + +/// Responsible for playing ads. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes/IMAAdsManager.html. +class IMAAdsManager extends NSObject { + /// Constructs [IMAAdsManager] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + IMAAdsManager.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }) : super.pigeon_detached(); + + late final _PigeonInternalProxyApiBaseCodec _pigeonVar_codecIMAAdsManager = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + IMAAdsManager Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + IMAAdsManager.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + /// The `IMAAdsManagerDelegate` to notify with events during ad playback. + Future setDelegate(IMAAdsManagerDelegate? delegate) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAAdsManager; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.setDelegate'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, delegate]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Initializes and loads the ad. + Future initialize(IMAAdsRenderingSettings? adsRenderingSettings) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAAdsManager; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.initialize'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, adsRenderingSettings]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Starts advertisement playback. + Future start() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAAdsManager; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.start'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Pauses advertisement. + Future pause() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAAdsManager; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.pause'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Resumes the current ad. + Future resume() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAAdsManager; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.resume'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Skips the advertisement if the ad is skippable and the skip offset has + /// been reached. + Future skip() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAAdsManager; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.skip'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// If an ad break is currently playing, discard it and resume content. + Future discardAdBreak() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAAdsManager; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.discardAdBreak'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Causes the ads manager to stop the ad and clean its internal state. + Future destroy() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAAdsManager; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.destroy'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + @override + IMAAdsManager pigeon_copy() { + return IMAAdsManager.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// A callback protocol for IMAAdsManager. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Protocols/IMAAdsManagerDelegate.html. +class IMAAdsManagerDelegate extends NSObject { + IMAAdsManagerDelegate({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.didReceiveAdEvent, + required this.didReceiveAdError, + required this.didRequestContentPause, + required this.didRequestContentResume, + }) : super.pigeon_detached() { + final int pigeonVar_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(this); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAAdsManagerDelegate; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + () async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsManagerDelegate.pigeon_defaultConstructor'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([pigeonVar_instanceIdentifier]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + }(); + } + + /// Constructs [IMAAdsManagerDelegate] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + IMAAdsManagerDelegate.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.didReceiveAdEvent, + required this.didReceiveAdError, + required this.didRequestContentPause, + required this.didRequestContentResume, + }) : super.pigeon_detached(); + + late final _PigeonInternalProxyApiBaseCodec + _pigeonVar_codecIMAAdsManagerDelegate = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + /// Called when there is an IMAAdEvent. + /// + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// with a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final IMAAdsManagerDelegate instance = IMAAdsManagerDelegate( + /// didReceiveAdEvent: (IMAAdsManagerDelegate pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, [PigeonInstanceManager.removeWeakReference] can be used to + /// release the associated Native object manually. + final void Function( + IMAAdsManagerDelegate pigeon_instance, + IMAAdsManager adsManager, + IMAAdEvent event, + ) didReceiveAdEvent; + + /// Called when there was an error playing the ad. + /// + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// with a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final IMAAdsManagerDelegate instance = IMAAdsManagerDelegate( + /// didReceiveAdError: (IMAAdsManagerDelegate pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, [PigeonInstanceManager.removeWeakReference] can be used to + /// release the associated Native object manually. + final void Function( + IMAAdsManagerDelegate pigeon_instance, + IMAAdsManager adsManager, + IMAAdError error, + ) didReceiveAdError; + + /// Called when an ad is ready to play. + /// + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// with a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final IMAAdsManagerDelegate instance = IMAAdsManagerDelegate( + /// didRequestContentPause: (IMAAdsManagerDelegate pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, [PigeonInstanceManager.removeWeakReference] can be used to + /// release the associated Native object manually. + final void Function( + IMAAdsManagerDelegate pigeon_instance, + IMAAdsManager adsManager, + ) didRequestContentPause; + + /// Called when an ad has finished or an error occurred during the playback. + /// + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// with a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final IMAAdsManagerDelegate instance = IMAAdsManagerDelegate( + /// didRequestContentResume: (IMAAdsManagerDelegate pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, [PigeonInstanceManager.removeWeakReference] can be used to + /// release the associated Native object manually. + final void Function( + IMAAdsManagerDelegate pigeon_instance, + IMAAdsManager adsManager, + ) didRequestContentResume; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + void Function( + IMAAdsManagerDelegate pigeon_instance, + IMAAdsManager adsManager, + IMAAdEvent event, + )? didReceiveAdEvent, + void Function( + IMAAdsManagerDelegate pigeon_instance, + IMAAdsManager adsManager, + IMAAdError error, + )? didReceiveAdError, + void Function( + IMAAdsManagerDelegate pigeon_instance, + IMAAdsManager adsManager, + )? didRequestContentPause, + void Function( + IMAAdsManagerDelegate pigeon_instance, + IMAAdsManager adsManager, + )? didRequestContentResume, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsManagerDelegate.didReceiveAdEvent', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsManagerDelegate.didReceiveAdEvent was null.'); + final List args = (message as List?)!; + final IMAAdsManagerDelegate? arg_pigeon_instance = + (args[0] as IMAAdsManagerDelegate?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsManagerDelegate.didReceiveAdEvent was null, expected non-null IMAAdsManagerDelegate.'); + final IMAAdsManager? arg_adsManager = (args[1] as IMAAdsManager?); + assert(arg_adsManager != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsManagerDelegate.didReceiveAdEvent was null, expected non-null IMAAdsManager.'); + final IMAAdEvent? arg_event = (args[2] as IMAAdEvent?); + assert(arg_event != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsManagerDelegate.didReceiveAdEvent was null, expected non-null IMAAdEvent.'); + try { + (didReceiveAdEvent ?? arg_pigeon_instance!.didReceiveAdEvent) + .call(arg_pigeon_instance!, arg_adsManager!, arg_event!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsManagerDelegate.didReceiveAdError', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsManagerDelegate.didReceiveAdError was null.'); + final List args = (message as List?)!; + final IMAAdsManagerDelegate? arg_pigeon_instance = + (args[0] as IMAAdsManagerDelegate?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsManagerDelegate.didReceiveAdError was null, expected non-null IMAAdsManagerDelegate.'); + final IMAAdsManager? arg_adsManager = (args[1] as IMAAdsManager?); + assert(arg_adsManager != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsManagerDelegate.didReceiveAdError was null, expected non-null IMAAdsManager.'); + final IMAAdError? arg_error = (args[2] as IMAAdError?); + assert(arg_error != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsManagerDelegate.didReceiveAdError was null, expected non-null IMAAdError.'); + try { + (didReceiveAdError ?? arg_pigeon_instance!.didReceiveAdError) + .call(arg_pigeon_instance!, arg_adsManager!, arg_error!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsManagerDelegate.didRequestContentPause', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsManagerDelegate.didRequestContentPause was null.'); + final List args = (message as List?)!; + final IMAAdsManagerDelegate? arg_pigeon_instance = + (args[0] as IMAAdsManagerDelegate?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsManagerDelegate.didRequestContentPause was null, expected non-null IMAAdsManagerDelegate.'); + final IMAAdsManager? arg_adsManager = (args[1] as IMAAdsManager?); + assert(arg_adsManager != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsManagerDelegate.didRequestContentPause was null, expected non-null IMAAdsManager.'); + try { + (didRequestContentPause ?? + arg_pigeon_instance!.didRequestContentPause) + .call(arg_pigeon_instance!, arg_adsManager!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsManagerDelegate.didRequestContentResume', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsManagerDelegate.didRequestContentResume was null.'); + final List args = (message as List?)!; + final IMAAdsManagerDelegate? arg_pigeon_instance = + (args[0] as IMAAdsManagerDelegate?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsManagerDelegate.didRequestContentResume was null, expected non-null IMAAdsManagerDelegate.'); + final IMAAdsManager? arg_adsManager = (args[1] as IMAAdsManager?); + assert(arg_adsManager != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsManagerDelegate.didRequestContentResume was null, expected non-null IMAAdsManager.'); + try { + (didRequestContentResume ?? + arg_pigeon_instance!.didRequestContentResume) + .call(arg_pigeon_instance!, arg_adsManager!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + IMAAdsManagerDelegate pigeon_copy() { + return IMAAdsManagerDelegate.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + didReceiveAdEvent: didReceiveAdEvent, + didReceiveAdError: didReceiveAdError, + didRequestContentPause: didRequestContentPause, + didRequestContentResume: didRequestContentResume, + ); + } +} + +/// Simple data class used to transport ad playback information. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes/IMAAdEvent.html. +class IMAAdEvent extends NSObject { + /// Constructs [IMAAdEvent] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + IMAAdEvent.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.type, + required this.typeString, + this.adData, + }) : super.pigeon_detached(); + + /// Type of the event. + final AdEventType type; + + /// Stringified type of the event. + final String typeString; + + /// Extra data about the ad. + final Map? adData; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + IMAAdEvent Function( + AdEventType type, + String typeString, + Map? adData, + )? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.IMAAdEvent.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdEvent.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdEvent.pigeon_newInstance was null, expected non-null int.'); + final AdEventType? arg_type = (args[1] as AdEventType?); + assert(arg_type != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdEvent.pigeon_newInstance was null, expected non-null AdEventType.'); + final String? arg_typeString = (args[2] as String?); + assert(arg_typeString != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdEvent.pigeon_newInstance was null, expected non-null String.'); + final Map? arg_adData = + (args[3] as Map?)?.cast(); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call( + arg_type!, arg_typeString!, arg_adData) ?? + IMAAdEvent.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + type: arg_type!, + typeString: arg_typeString!, + adData: arg_adData, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + IMAAdEvent pigeon_copy() { + return IMAAdEvent.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + type: type, + typeString: typeString, + adData: adData, + ); + } +} + +/// Set of properties that influence how ads are rendered. +/// +/// See https://developers.google.com/ad-manager/dynamic-ad-insertion/sdk/ios/reference/Classes/IMAAdsRenderingSettings. +class IMAAdsRenderingSettings extends NSObject { + IMAAdsRenderingSettings({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }) : super.pigeon_detached() { + final int pigeonVar_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(this); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAAdsRenderingSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + () async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsRenderingSettings.pigeon_defaultConstructor'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([pigeonVar_instanceIdentifier]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + }(); + } + + /// Constructs [IMAAdsRenderingSettings] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + IMAAdsRenderingSettings.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }) : super.pigeon_detached(); + + late final _PigeonInternalProxyApiBaseCodec + _pigeonVar_codecIMAAdsRenderingSettings = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + IMAAdsRenderingSettings Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsRenderingSettings.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsRenderingSettings.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsRenderingSettings.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + IMAAdsRenderingSettings.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + /// If specified, the SDK will play the media with MIME type on the list. + Future setMimeTypes(List? types) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAAdsRenderingSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsRenderingSettings.setMimeTypes'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, types]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Maximum recommended bitrate. + /// + /// The value is in kbit/s. + Future setBitrate(int bitrate) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAAdsRenderingSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsRenderingSettings.setBitrate'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, bitrate]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Timeout (in seconds) when loading a video ad media file. + /// + /// Use -1 for the default of 8 seconds. + Future setLoadVideoTimeout(double seconds) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAAdsRenderingSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsRenderingSettings.setLoadVideoTimeout'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, seconds]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// For VMAP and ad rules playlists, only play ad breaks scheduled after this + /// time (in seconds). + Future setPlayAdsAfterTime(double seconds) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAAdsRenderingSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsRenderingSettings.setPlayAdsAfterTime'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, seconds]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Specifies the list of UI elements that should be visible. + Future setUIElements(List? types) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAAdsRenderingSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsRenderingSettings.setUIElements'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, types]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Whether or not the SDK will preload ad media. + /// + /// Default is YES. + Future setEnablePreloading(bool enable) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAAdsRenderingSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsRenderingSettings.setEnablePreloading'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, enable]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Specifies the optional UIViewController that will be used to open links + /// in-app. + Future setLinkOpenerPresentingController( + UIViewController controller) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAAdsRenderingSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAAdsRenderingSettings.setLinkOpenerPresentingController'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, controller]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + @override + IMAAdsRenderingSettings pigeon_copy() { + return IMAAdsRenderingSettings.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// The root class of most Objective-C class hierarchies, from which subclasses +/// inherit a basic interface to the runtime system and the ability to behave as +/// Objective-C objects. +/// +/// See https://developer.apple.com/documentation/objectivec/nsobject. +class NSObject extends PigeonInternalProxyApiBaseClass { + /// Constructs [NSObject] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + NSObject.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + NSObject Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.NSObject.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.NSObject.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.NSObject.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + NSObject.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + NSObject pigeon_copy() { + return NSObject.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// An obstruction that is marked as “friendly” for viewability measurement +/// purposes. +/// +/// See https://developers.google.com/ad-manager/dynamic-ad-insertion/sdk/ios/reference/Classes/IMAFriendlyObstruction.html. +class IMAFriendlyObstruction extends NSObject { + /// Initializes a friendly obstruction. + IMAFriendlyObstruction({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.view, + required this.purpose, + this.detailedReason, + }) : super.pigeon_detached() { + final int pigeonVar_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(this); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMAFriendlyObstruction; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + () async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMAFriendlyObstruction.pigeon_defaultConstructor'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([ + pigeonVar_instanceIdentifier, + view, + purpose, + detailedReason + ]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + }(); + } + + /// Constructs [IMAFriendlyObstruction] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + IMAFriendlyObstruction.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.view, + required this.purpose, + this.detailedReason, + }) : super.pigeon_detached(); + + late final _PigeonInternalProxyApiBaseCodec + _pigeonVar_codecIMAFriendlyObstruction = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + /// The view causing the obstruction. + final UIView view; + + /// The purpose for registering the obstruction as friendly. + final FriendlyObstructionPurpose purpose; + + /// Optional, detailed reasoning for registering this obstruction as friendly. + /// + /// If the detailedReason is not null, it must follow the IAB standard by + /// being 50 characters or less and only containing characters A-z, 0-9, or + /// spaces. + final String? detailedReason; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + IMAFriendlyObstruction Function( + UIView view, + FriendlyObstructionPurpose purpose, + String? detailedReason, + )? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.IMAFriendlyObstruction.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAFriendlyObstruction.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAFriendlyObstruction.pigeon_newInstance was null, expected non-null int.'); + final UIView? arg_view = (args[1] as UIView?); + assert(arg_view != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAFriendlyObstruction.pigeon_newInstance was null, expected non-null UIView.'); + final FriendlyObstructionPurpose? arg_purpose = + (args[2] as FriendlyObstructionPurpose?); + assert(arg_purpose != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAFriendlyObstruction.pigeon_newInstance was null, expected non-null FriendlyObstructionPurpose.'); + final String? arg_detailedReason = (args[3] as String?); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call( + arg_view!, arg_purpose!, arg_detailedReason) ?? + IMAFriendlyObstruction.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + view: arg_view!, + purpose: arg_purpose!, + detailedReason: arg_detailedReason, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + IMAFriendlyObstruction pigeon_copy() { + return IMAFriendlyObstruction.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + view: view, + purpose: purpose, + detailedReason: detailedReason, + ); + } +} + +/// An object that holds data corresponding to the companion ad. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes/IMACompanionAd. +class IMACompanionAd extends NSObject { + /// Constructs [IMACompanionAd] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + IMACompanionAd.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + this.resourceValue, + this.apiFramework, + required this.width, + required this.height, + }) : super.pigeon_detached(); + + /// The value for the resource of this companion. + final String? resourceValue; + + /// The API needed to execute this ad, or nil if unavailable. + final String? apiFramework; + + /// The width of the companion in pixels. + /// + /// 0 if unavailable. + final int width; + + /// The height of the companion in pixels. + /// + /// 0 if unavailable. + final int height; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + IMACompanionAd Function( + String? resourceValue, + String? apiFramework, + int width, + int height, + )? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.IMACompanionAd.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMACompanionAd.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMACompanionAd.pigeon_newInstance was null, expected non-null int.'); + final String? arg_resourceValue = (args[1] as String?); + final String? arg_apiFramework = (args[2] as String?); + final int? arg_width = (args[3] as int?); + assert(arg_width != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMACompanionAd.pigeon_newInstance was null, expected non-null int.'); + final int? arg_height = (args[4] as int?); + assert(arg_height != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMACompanionAd.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call(arg_resourceValue, arg_apiFramework, + arg_width!, arg_height!) ?? + IMACompanionAd.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + resourceValue: arg_resourceValue, + apiFramework: arg_apiFramework, + width: arg_width!, + height: arg_height!, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + IMACompanionAd pigeon_copy() { + return IMACompanionAd.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + resourceValue: resourceValue, + apiFramework: apiFramework, + width: width, + height: height, + ); + } +} + +/// Ad slot for companion ads. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes/IMACompanionAdSlot. +class IMACompanionAdSlot extends PigeonInternalProxyApiBaseClass { + /// Initializes an instance of a IMACompanionAdSlot with fluid size. + IMACompanionAdSlot({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.view, + }) { + final int pigeonVar_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(this); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMACompanionAdSlot; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + () async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMACompanionAdSlot.pigeon_defaultConstructor'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([pigeonVar_instanceIdentifier, view]) + as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + }(); + } + + /// Initializes an instance of a IMACompanionAdSlot with design ad width and + /// height. + /// + /// `width` and `height` are in pixels. + IMACompanionAdSlot.size({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.view, + required int width, + required int height, + }) { + final int pigeonVar_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(this); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMACompanionAdSlot; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + () async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMACompanionAdSlot.size'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel.send( + [pigeonVar_instanceIdentifier, view, width, height]) + as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + }(); + } + + /// Constructs [IMACompanionAdSlot] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + IMACompanionAdSlot.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.view, + }); + + late final _PigeonInternalProxyApiBaseCodec + _pigeonVar_codecIMACompanionAdSlot = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + /// The view the companion will be rendered in. + /// + /// Display this view in your application before video ad starts. + final UIView view; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + IMACompanionAdSlot Function(UIView view)? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.IMACompanionAdSlot.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMACompanionAdSlot.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMACompanionAdSlot.pigeon_newInstance was null, expected non-null int.'); + final UIView? arg_view = (args[1] as UIView?); + assert(arg_view != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMACompanionAdSlot.pigeon_newInstance was null, expected non-null UIView.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call(arg_view!) ?? + IMACompanionAdSlot.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + view: arg_view!, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + /// The IMACompanionDelegate for receiving events from the companion ad slot. + /// + /// This instance only creates a weak reference to the delegate, so the Dart + /// instance should create an explicit reference to receive callbacks. + Future setDelegate(IMACompanionDelegate? delegate) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMACompanionAdSlot; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMACompanionAdSlot.setDelegate'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, delegate]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + @override + IMACompanionAdSlot pigeon_copy() { + return IMACompanionAdSlot.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + view: view, + ); + } +} + +/// Delegate to receive events from the companion ad slot. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Protocols/IMACompanionDelegate.html. +class IMACompanionDelegate extends NSObject { + IMACompanionDelegate({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + this.companionAdSlotFilled, + this.companionSlotWasClicked, + }) : super.pigeon_detached() { + final int pigeonVar_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(this); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecIMACompanionDelegate; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + () async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.IMACompanionDelegate.pigeon_defaultConstructor'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([pigeonVar_instanceIdentifier]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + }(); + } + + /// Constructs [IMACompanionDelegate] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + IMACompanionDelegate.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + this.companionAdSlotFilled, + this.companionSlotWasClicked, + }) : super.pigeon_detached(); + + late final _PigeonInternalProxyApiBaseCodec + _pigeonVar_codecIMACompanionDelegate = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + /// Called when the slot is either filled or not filled. + /// + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// with a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final IMACompanionDelegate instance = IMACompanionDelegate( + /// companionAdSlotFilled: (IMACompanionDelegate pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, [PigeonInstanceManager.removeWeakReference] can be used to + /// release the associated Native object manually. + final void Function( + IMACompanionDelegate pigeon_instance, + IMACompanionAdSlot slot, + bool filled, + )? companionAdSlotFilled; + + /// Called when the slot is clicked on by the user and will successfully + /// navigate away. + /// + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// with a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final IMACompanionDelegate instance = IMACompanionDelegate( + /// companionSlotWasClicked: (IMACompanionDelegate pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, [PigeonInstanceManager.removeWeakReference] can be used to + /// release the associated Native object manually. + final void Function( + IMACompanionDelegate pigeon_instance, + IMACompanionAdSlot slot, + )? companionSlotWasClicked; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + IMACompanionDelegate Function()? pigeon_newInstance, + void Function( + IMACompanionDelegate pigeon_instance, + IMACompanionAdSlot slot, + bool filled, + )? companionAdSlotFilled, + void Function( + IMACompanionDelegate pigeon_instance, + IMACompanionAdSlot slot, + )? companionSlotWasClicked, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.IMACompanionDelegate.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMACompanionDelegate.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMACompanionDelegate.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + IMACompanionDelegate.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.IMACompanionDelegate.companionAdSlotFilled', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMACompanionDelegate.companionAdSlotFilled was null.'); + final List args = (message as List?)!; + final IMACompanionDelegate? arg_pigeon_instance = + (args[0] as IMACompanionDelegate?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMACompanionDelegate.companionAdSlotFilled was null, expected non-null IMACompanionDelegate.'); + final IMACompanionAdSlot? arg_slot = (args[1] as IMACompanionAdSlot?); + assert(arg_slot != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMACompanionDelegate.companionAdSlotFilled was null, expected non-null IMACompanionAdSlot.'); + final bool? arg_filled = (args[2] as bool?); + assert(arg_filled != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMACompanionDelegate.companionAdSlotFilled was null, expected non-null bool.'); + try { + (companionAdSlotFilled ?? + arg_pigeon_instance!.companionAdSlotFilled) + ?.call(arg_pigeon_instance!, arg_slot!, arg_filled!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.IMACompanionDelegate.companionSlotWasClicked', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMACompanionDelegate.companionSlotWasClicked was null.'); + final List args = (message as List?)!; + final IMACompanionDelegate? arg_pigeon_instance = + (args[0] as IMACompanionDelegate?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMACompanionDelegate.companionSlotWasClicked was null, expected non-null IMACompanionDelegate.'); + final IMACompanionAdSlot? arg_slot = (args[1] as IMACompanionAdSlot?); + assert(arg_slot != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMACompanionDelegate.companionSlotWasClicked was null, expected non-null IMACompanionAdSlot.'); + try { + (companionSlotWasClicked ?? + arg_pigeon_instance!.companionSlotWasClicked) + ?.call(arg_pigeon_instance!, arg_slot!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + IMACompanionDelegate pigeon_copy() { + return IMACompanionDelegate.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + companionAdSlotFilled: companionAdSlotFilled, + companionSlotWasClicked: companionSlotWasClicked, + ); + } +} diff --git a/packages/interactive_media_ads/lib/src/ios/interactive_media_ads_proxy.dart b/packages/interactive_media_ads/lib/src/ios/interactive_media_ads_proxy.dart new file mode 100644 index 000000000000..53b472f4fb62 --- /dev/null +++ b/packages/interactive_media_ads/lib/src/ios/interactive_media_ads_proxy.dart @@ -0,0 +1,100 @@ +// 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 'interactive_media_ads.g.dart'; + +/// Handles constructing objects and calling static methods for the iOS +/// Interactive Media Ads native library. +/// +/// This class provides dependency injection for the implementations of the +/// platform interface classes. Improving the ease of unit testing and/or +/// overriding the underlying iOS classes. +class InteractiveMediaAdsProxy { + /// Constructs an [InteractiveMediaAdsProxy]. + const InteractiveMediaAdsProxy({ + this.newIMAAdDisplayContainer = IMAAdDisplayContainer.new, + this.newUIViewController = UIViewController.new, + this.newIMAContentPlayhead = IMAContentPlayhead.new, + this.newIMAAdsLoader = IMAAdsLoader.new, + this.newIMAAdsRequest = IMAAdsRequest.new, + this.newIMAAdsLoaderDelegate = IMAAdsLoaderDelegate.new, + this.newIMAAdsManagerDelegate = IMAAdsManagerDelegate.new, + this.newIMAAdsRenderingSettings = IMAAdsRenderingSettings.new, + this.newIMAFriendlyObstruction = IMAFriendlyObstruction.new, + this.newIMACompanionAdSlot = IMACompanionAdSlot.new, + this.sizeIMACompanionAdSlot = IMACompanionAdSlot.size, + this.newIMACompanionDelegate = IMACompanionDelegate.new, + }); + + /// Constructs [IMAAdDisplayContainer]. + final IMAAdDisplayContainer Function({ + required UIView adContainer, + UIViewController? adContainerViewController, + }) newIMAAdDisplayContainer; + + /// Constructs [UIViewController]. + final UIViewController Function({ + void Function(UIViewController, bool)? viewDidAppear, + }) newUIViewController; + + /// Constructs [IMAContentPlayhead]. + final IMAContentPlayhead Function() newIMAContentPlayhead; + + /// Constructs [IMAAdsLoader]. + final IMAAdsLoader Function({IMASettings? settings}) newIMAAdsLoader; + + /// Constructs [IMAAdsRequest]. + final IMAAdsRequest Function({ + required String adTagUrl, + required IMAAdDisplayContainer adDisplayContainer, + IMAContentPlayhead? contentPlayhead, + }) newIMAAdsRequest; + + /// Constructs [IMAAdsLoaderDelegate]. + final IMAAdsLoaderDelegate Function({ + required void Function(IMAAdsLoaderDelegate, IMAAdsLoader, IMAAdsLoadedData) + adLoaderLoadedWith, + required void Function( + IMAAdsLoaderDelegate, + IMAAdsLoader, + IMAAdLoadingErrorData, + ) adsLoaderFailedWithErrorData, + }) newIMAAdsLoaderDelegate; + + /// Constructs [IMAAdsManagerDelegate]. + final IMAAdsManagerDelegate Function({ + required void Function(IMAAdsManagerDelegate, IMAAdsManager, IMAAdEvent) + didReceiveAdEvent, + required void Function(IMAAdsManagerDelegate, IMAAdsManager, IMAAdError) + didReceiveAdError, + required void Function(IMAAdsManagerDelegate, IMAAdsManager) + didRequestContentPause, + required void Function(IMAAdsManagerDelegate, IMAAdsManager) + didRequestContentResume, + }) newIMAAdsManagerDelegate; + + /// Constructs [IMAAdsRenderingSettings]. + final IMAAdsRenderingSettings Function() newIMAAdsRenderingSettings; + + /// Constructs [IMAFriendlyObstruction]. + final IMAFriendlyObstruction Function({ + required UIView view, + required FriendlyObstructionPurpose purpose, + String? detailedReason, + }) newIMAFriendlyObstruction; + + /// Constructs [IMACompanionAdSlot]. + final IMACompanionAdSlot Function({required UIView view}) + newIMACompanionAdSlot; + + /// Constructs [IMACompanionAdSlot]. + final IMACompanionAdSlot Function({ + required int width, + required int height, + required UIView view, + }) sizeIMACompanionAdSlot; + + /// Constructs [IMACompanionDelegate]. + final IMACompanionDelegate Function() newIMACompanionDelegate; +} diff --git a/packages/interactive_media_ads/lib/src/ios/ios_ad_display_container.dart b/packages/interactive_media_ads/lib/src/ios/ios_ad_display_container.dart new file mode 100644 index 000000000000..4bdd8fa46133 --- /dev/null +++ b/packages/interactive_media_ads/lib/src/ios/ios_ad_display_container.dart @@ -0,0 +1,104 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/services.dart'; +import 'package:meta/meta.dart'; + +import '../platform_interface/platform_interface.dart'; +import 'interactive_media_ads.g.dart'; +import 'interactive_media_ads_proxy.dart'; + +/// Implementation of [PlatformAdDisplayContainerCreationParams] for iOS. +final class IOSAdDisplayContainerCreationParams + extends PlatformAdDisplayContainerCreationParams { + /// Constructs a [IOSAdDisplayContainerCreationParams]. + const IOSAdDisplayContainerCreationParams({ + super.key, + required super.onContainerAdded, + @visibleForTesting InteractiveMediaAdsProxy? imaProxy, + }) : _imaProxy = imaProxy ?? const InteractiveMediaAdsProxy(), + super(); + + /// Creates a [IOSAdDisplayContainerCreationParams] from an instance of + /// [PlatformAdDisplayContainerCreationParams]. + factory IOSAdDisplayContainerCreationParams.fromPlatformAdDisplayContainerCreationParams( + PlatformAdDisplayContainerCreationParams params, { + @visibleForTesting InteractiveMediaAdsProxy? imaProxy, + }) { + return IOSAdDisplayContainerCreationParams( + key: params.key, + onContainerAdded: params.onContainerAdded, + imaProxy: imaProxy, + ); + } + + final InteractiveMediaAdsProxy _imaProxy; +} + +/// Implementation of [PlatformAdDisplayContainer] for iOS. +base class IOSAdDisplayContainer extends PlatformAdDisplayContainer { + /// Constructs an [IOSAdDisplayContainer]. + IOSAdDisplayContainer(super.params) : super.implementation(); + + // The `UIViewController` used to create the native `IMAAdDisplayContainer`. + late final UIViewController _controller = _createViewController( + WeakReference(this), + ); + + final Completer _viewDidAppearCompleter = Completer(); + + /// The native iOS IMAAdDisplayContainer. + /// + /// Created with the `UIView` that handles playing an ad. + @internal + late final IMAAdDisplayContainer? adDisplayContainer; + + late final IOSAdDisplayContainerCreationParams _iosParams = + params is IOSAdDisplayContainerCreationParams + ? params as IOSAdDisplayContainerCreationParams + : IOSAdDisplayContainerCreationParams + .fromPlatformAdDisplayContainerCreationParams(params); + + @override + Widget build(BuildContext context) { + return UiKitView( + key: _iosParams.key, + viewType: 'interactive_media_ads.packages.flutter.dev/view', + onPlatformViewCreated: (_) async { + adDisplayContainer = _iosParams._imaProxy.newIMAAdDisplayContainer( + adContainer: _controller.view, + adContainerViewController: _controller, + ); + await _viewDidAppearCompleter.future; + params.onContainerAdded(this); + }, + layoutDirection: params.layoutDirection, + creationParams: + // ignore: invalid_use_of_protected_member + _controller.view.pigeon_instanceManager + .getIdentifier(_controller.view), + creationParamsCodec: const StandardMessageCodec(), + ); + } + + // This value is created in a static method because the callback methods for + // any wrapped classes must not reference the encapsulating object. This is to + // prevent a circular reference that prevents garbage collection. + static UIViewController _createViewController( + WeakReference interfaceContainer, + ) { + return interfaceContainer.target!._iosParams._imaProxy.newUIViewController( + viewDidAppear: (_, bool animated) { + final IOSAdDisplayContainer? container = interfaceContainer.target; + if (container != null && + !container._viewDidAppearCompleter.isCompleted) { + container._viewDidAppearCompleter.complete(); + } + }, + ); + } +} diff --git a/packages/interactive_media_ads/lib/src/ios/ios_ads_loader.dart b/packages/interactive_media_ads/lib/src/ios/ios_ads_loader.dart new file mode 100644 index 000000000000..606cfb6c835e --- /dev/null +++ b/packages/interactive_media_ads/lib/src/ios/ios_ads_loader.dart @@ -0,0 +1,115 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import 'package:flutter/widgets.dart'; + +import '../platform_interface/platform_interface.dart'; +import 'enum_converter_utils.dart'; +import 'interactive_media_ads.g.dart'; +import 'interactive_media_ads_proxy.dart'; +import 'ios_ad_display_container.dart'; +import 'ios_ads_manager.dart'; +import 'ios_content_progress_provider.dart'; + +/// Implementation of [PlatformAdsLoaderCreationParams] for iOS. +final class IOSAdsLoaderCreationParams extends PlatformAdsLoaderCreationParams { + /// Constructs a [IOSAdsLoaderCreationParams]. + const IOSAdsLoaderCreationParams({ + required super.container, + required super.onAdsLoaded, + required super.onAdsLoadError, + @visibleForTesting InteractiveMediaAdsProxy? proxy, + }) : _proxy = proxy ?? const InteractiveMediaAdsProxy(), + super(); + + /// Creates a [IOSAdsLoaderCreationParams] from an instance of + /// [PlatformAdsLoaderCreationParams]. + factory IOSAdsLoaderCreationParams.fromPlatformAdsLoaderCreationParams( + PlatformAdsLoaderCreationParams params, { + @visibleForTesting InteractiveMediaAdsProxy? proxy, + }) { + return IOSAdsLoaderCreationParams( + container: params.container, + onAdsLoaded: params.onAdsLoaded, + onAdsLoadError: params.onAdsLoadError, + proxy: proxy, + ); + } + + final InteractiveMediaAdsProxy _proxy; +} + +/// Implementation of [PlatformAdsLoader] for iOS. +base class IOSAdsLoader extends PlatformAdsLoader { + /// Constructs an [IOSAdsLoader]. + IOSAdsLoader(super.params) + : assert(params.container is IOSAdDisplayContainer), + assert( + (params.container as IOSAdDisplayContainer).adDisplayContainer != + null, + 'Ensure the AdDisplayContainer has been added to the Widget tree before creating an AdsLoader.', + ), + super.implementation() { + _adsLoader = _iosParams._proxy.newIMAAdsLoader(); + _adsLoader.setDelegate(_delegate); + } + + late final IMAAdsLoader _adsLoader; + late final IMAAdsLoaderDelegate _delegate = _createAdsLoaderDelegate( + WeakReference(this), + ); + + late final IOSAdsLoaderCreationParams _iosParams = params + is IOSAdsLoaderCreationParams + ? params as IOSAdsLoaderCreationParams + : IOSAdsLoaderCreationParams.fromPlatformAdsLoaderCreationParams(params); + + @override + Future contentComplete() { + return _adsLoader.contentComplete(); + } + + @override + Future requestAds(PlatformAdsRequest request) async { + return _adsLoader.requestAds(_iosParams._proxy.newIMAAdsRequest( + adTagUrl: request.adTagUrl, + adDisplayContainer: + (_iosParams.container as IOSAdDisplayContainer).adDisplayContainer!, + contentPlayhead: request.contentProgressProvider != null + ? (request.contentProgressProvider! as IOSContentProgressProvider) + .contentPlayhead + : null, + )); + } + + // This value is created in a static method because the callback methods for + // any wrapped classes must not reference the encapsulating object. This is to + // prevent a circular reference that prevents garbage collection. + static IMAAdsLoaderDelegate _createAdsLoaderDelegate( + WeakReference interfaceLoader, + ) { + return interfaceLoader.target!._iosParams._proxy.newIMAAdsLoaderDelegate( + adLoaderLoadedWith: (_, __, IMAAdsLoadedData adsLoadedData) { + interfaceLoader.target?._iosParams.onAdsLoaded( + PlatformOnAdsLoadedData( + manager: IOSAdsManager(adsLoadedData.adsManager!), + ), + ); + }, + adsLoaderFailedWithErrorData: (_, __, IMAAdLoadingErrorData adErrorData) { + interfaceLoader.target?._iosParams.onAdsLoadError( + AdsLoadErrorData( + error: AdError( + type: toInterfaceErrorType(adErrorData.adError.type), + code: toInterfaceErrorCode(adErrorData.adError.code), + message: adErrorData.adError.message, + ), + ), + ); + }, + ); + } +} diff --git a/packages/interactive_media_ads/lib/src/ios/ios_ads_manager.dart b/packages/interactive_media_ads/lib/src/ios/ios_ads_manager.dart new file mode 100644 index 000000000000..0c51bf926f14 --- /dev/null +++ b/packages/interactive_media_ads/lib/src/ios/ios_ads_manager.dart @@ -0,0 +1,71 @@ +// 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:meta/meta.dart'; + +import '../platform_interface/platform_interface.dart'; +import 'interactive_media_ads.g.dart'; +import 'ios_ads_manager_delegate.dart'; + +/// Implementation of [PlatformAdsManager] for iOS. +class IOSAdsManager extends PlatformAdsManager { + /// Constructs an [IOSAdsManager]. + @internal + IOSAdsManager(IMAAdsManager manager) : _manager = manager; + + final IMAAdsManager _manager; + + // This must maintain a reference to the delegate because the native + // `IMAAdsManagerDelegate.delegate` property is only a weak reference. + // Therefore, this would be garbage collected without this explicit reference. + // ignore: unused_field + late IOSAdsManagerDelegate _delegate; + + @override + Future destroy() { + return _manager.destroy(); + } + + @override + Future init(AdsManagerInitParams params) { + return _manager.initialize(null); + } + + @override + Future setAdsManagerDelegate(PlatformAdsManagerDelegate delegate) { + final IOSAdsManagerDelegate platformDelegate = + delegate is IOSAdsManagerDelegate + ? delegate + : IOSAdsManagerDelegate(delegate.params); + _delegate = platformDelegate; + return _manager.setDelegate(platformDelegate.delegate); + } + + @override + Future start(AdsManagerStartParams params) { + return _manager.start(); + } + + @override + Future discardAdBreak() { + return _manager.discardAdBreak(); + } + + @override + Future pause() { + return _manager.pause(); + } + + @override + Future resume() { + return _manager.resume(); + } + + @override + Future skip() { + return _manager.skip(); + } +} diff --git a/packages/interactive_media_ads/lib/src/ios/ios_ads_manager_delegate.dart b/packages/interactive_media_ads/lib/src/ios/ios_ads_manager_delegate.dart new file mode 100644 index 000000000000..d055805064a3 --- /dev/null +++ b/packages/interactive_media_ads/lib/src/ios/ios_ads_manager_delegate.dart @@ -0,0 +1,102 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:meta/meta.dart'; + +import '../platform_interface/platform_interface.dart'; +import 'enum_converter_utils.dart'; +import 'interactive_media_ads.g.dart' as ima; +import 'interactive_media_ads_proxy.dart'; + +/// Implementation of [PlatformAdsManagerDelegateCreationParams] for iOS. +final class IOSAdsManagerDelegateCreationParams + extends PlatformAdsManagerDelegateCreationParams { + /// Constructs an [IOSAdsManagerDelegateCreationParams]. + const IOSAdsManagerDelegateCreationParams({ + super.onAdEvent, + super.onAdErrorEvent, + @visibleForTesting InteractiveMediaAdsProxy? proxy, + }) : _proxy = proxy ?? const InteractiveMediaAdsProxy(), + super(); + + /// Creates an [IOSAdsManagerDelegateCreationParams] from an instance of + /// [PlatformAdsManagerDelegateCreationParams]. + factory IOSAdsManagerDelegateCreationParams.fromPlatformAdsManagerDelegateCreationParams( + PlatformAdsManagerDelegateCreationParams params, { + @visibleForTesting InteractiveMediaAdsProxy? proxy, + }) { + return IOSAdsManagerDelegateCreationParams( + onAdEvent: params.onAdEvent, + onAdErrorEvent: params.onAdErrorEvent, + proxy: proxy, + ); + } + + final InteractiveMediaAdsProxy _proxy; +} + +/// Implementation of [PlatformAdsManagerDelegate] for iOS. +final class IOSAdsManagerDelegate extends PlatformAdsManagerDelegate { + /// Constructs an [IOSAdsManagerDelegate]. + IOSAdsManagerDelegate(super.params) : super.implementation(); + + /// The native iOS `IMAAdsManagerDelegate`. + /// + /// This handles ad events and errors that occur during ad or stream + /// initialization and playback. + @internal + late final ima.IMAAdsManagerDelegate delegate = _createAdsManagerDelegate( + WeakReference(this), + ); + + late final IOSAdsManagerDelegateCreationParams _iosParams = + params is IOSAdsManagerDelegateCreationParams + ? params as IOSAdsManagerDelegateCreationParams + : IOSAdsManagerDelegateCreationParams + .fromPlatformAdsManagerDelegateCreationParams(params); + + // This value is created in a static method because the callback methods for + // any wrapped classes must not reference the encapsulating object. This is to + // prevent a circular reference that prevents garbage collection. + static ima.IMAAdsManagerDelegate _createAdsManagerDelegate( + WeakReference interfaceDelegate, + ) { + return interfaceDelegate.target!._iosParams._proxy.newIMAAdsManagerDelegate( + didReceiveAdEvent: (_, __, ima.IMAAdEvent event) { + interfaceDelegate.target?.params.onAdEvent?.call( + AdEvent( + type: toInterfaceEventType(event.type), + adData: event.adData?.map( + (String? key, Object? value) { + return MapEntry(key!, value.toString()); + }, + ) ?? + {}, + ), + ); + }, + didReceiveAdError: (_, __, ima.IMAAdError event) { + interfaceDelegate.target?.params.onAdErrorEvent?.call( + AdErrorEvent( + error: AdError( + type: toInterfaceErrorType(event.type), + code: toInterfaceErrorCode(event.code), + message: event.message, + ), + ), + ); + }, + didRequestContentPause: (_, __) { + interfaceDelegate.target?.params.onAdEvent?.call( + const AdEvent(type: AdEventType.contentPauseRequested), + ); + }, + didRequestContentResume: (_, __) { + interfaceDelegate.target?.params.onAdEvent?.call( + const AdEvent(type: AdEventType.contentResumeRequested), + ); + }, + ); + } +} diff --git a/packages/interactive_media_ads/lib/src/ios/ios_content_progress_provider.dart b/packages/interactive_media_ads/lib/src/ios/ios_content_progress_provider.dart new file mode 100644 index 000000000000..9b75466ae548 --- /dev/null +++ b/packages/interactive_media_ads/lib/src/ios/ios_content_progress_provider.dart @@ -0,0 +1,64 @@ +// 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:meta/meta.dart'; + +import '../platform_interface/platform_content_progress_provider.dart'; +import 'interactive_media_ads.g.dart' as ima; +import 'interactive_media_ads_proxy.dart'; + +/// Implementation of [PlatformContentProgressProviderCreationParams] for iOS. +final class IOSContentProgressProviderCreationParams + extends PlatformContentProgressProviderCreationParams { + /// Constructs an [IOSContentProgressProviderCreationParams]. + const IOSContentProgressProviderCreationParams({ + @visibleForTesting InteractiveMediaAdsProxy? proxy, + }) : _proxy = proxy ?? const InteractiveMediaAdsProxy(), + super(); + + /// Creates a [IOSContentProgressProviderCreationParams] from an instance of + /// [PlatformContentProgressProviderCreationParams]. + factory IOSContentProgressProviderCreationParams.fromPlatformContentProgressProviderCreationParams( + // Placeholder to prevent requiring a breaking change if params are added to + // PlatformContentProgressProviderCreationParams. + // ignore: avoid_unused_constructor_parameters + PlatformContentProgressProviderCreationParams params, { + @visibleForTesting InteractiveMediaAdsProxy? proxy, + }) { + return IOSContentProgressProviderCreationParams(proxy: proxy); + } + + final InteractiveMediaAdsProxy _proxy; +} + +/// Implementation of [PlatformContentProgressProvider] for iOS. +base class IOSContentProgressProvider extends PlatformContentProgressProvider { + /// Constructs an [IOSContentProgressProvider]. + IOSContentProgressProvider(super.params) : super.implementation(); + + /// The native iOS IMAContentPlayhead. + /// + /// This allows the SDK to track progress of the content video. + @internal + late final ima.IMAContentPlayhead contentPlayhead = + _iosParams._proxy.newIMAContentPlayhead(); + + late final IOSContentProgressProviderCreationParams _iosParams = + params is IOSContentProgressProviderCreationParams + ? params as IOSContentProgressProviderCreationParams + : IOSContentProgressProviderCreationParams + .fromPlatformContentProgressProviderCreationParams( + params, + ); + + @override + Future setProgress({ + required Duration progress, + required Duration duration, + }) async { + return contentPlayhead.setCurrentTime(progress.inSeconds.toDouble()); + } +} diff --git a/packages/interactive_media_ads/lib/src/ios/ios_interactive_media_ads.dart b/packages/interactive_media_ads/lib/src/ios/ios_interactive_media_ads.dart new file mode 100644 index 000000000000..ee55ecce0c98 --- /dev/null +++ b/packages/interactive_media_ads/lib/src/ios/ios_interactive_media_ads.dart @@ -0,0 +1,47 @@ +// 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 '../platform_interface/interactive_media_ads_platform.dart'; +import '../platform_interface/platform_ad_display_container.dart'; +import '../platform_interface/platform_ads_loader.dart'; +import '../platform_interface/platform_ads_manager_delegate.dart'; +import '../platform_interface/platform_content_progress_provider.dart'; +import 'ios_ad_display_container.dart'; +import 'ios_ads_loader.dart'; +import 'ios_ads_manager_delegate.dart'; +import 'ios_content_progress_provider.dart'; + +/// Implementation of [InteractiveMediaAdsPlatform] for iOS. +final class IOSInteractiveMediaAds extends InteractiveMediaAdsPlatform { + /// Registers this class as the default instance of [InteractiveMediaAdsPlatform]. + static void registerWith() { + InteractiveMediaAdsPlatform.instance = IOSInteractiveMediaAds(); + } + + @override + IOSAdDisplayContainer createPlatformAdDisplayContainer( + PlatformAdDisplayContainerCreationParams params, + ) { + return IOSAdDisplayContainer(params); + } + + @override + IOSAdsLoader createPlatformAdsLoader(PlatformAdsLoaderCreationParams params) { + return IOSAdsLoader(params); + } + + @override + IOSAdsManagerDelegate createPlatformAdsManagerDelegate( + PlatformAdsManagerDelegateCreationParams params, + ) { + return IOSAdsManagerDelegate(params); + } + + @override + IOSContentProgressProvider createPlatformContentProgressProvider( + PlatformContentProgressProviderCreationParams params, + ) { + return IOSContentProgressProvider(params); + } +} diff --git a/packages/interactive_media_ads/lib/src/platform_interface/ad_event.dart b/packages/interactive_media_ads/lib/src/platform_interface/ad_event.dart index 9824d9915fb3..5246f8226bd2 100644 --- a/packages/interactive_media_ads/lib/src/platform_interface/ad_event.dart +++ b/packages/interactive_media_ads/lib/src/platform_interface/ad_event.dart @@ -8,6 +8,31 @@ import 'ad_error.dart'; /// Types of events that can occur during ad playback. enum AdEventType { + /// Fired when an ad break in a stream ends. + adBreakEnded, + + /// Fired when an ad break will not play back any ads. + adBreakFetchError, + + /// Fired when an ad break is ready from VMAP or ad rule ads. + adBreakReady, + + /// Fired when an ad break in a stream starts. + adBreakStarted, + + /// Fired when playback stalls while the ad buffers. + adBuffering, + + /// Fired when an ad period in a stream ends. + adPeriodEnded, + + /// Fired when an ad period in a stream starts. + adPeriodStarted, + + /// Fired to inform of ad progress and can be used by publisher to display a + /// countdown timer. + adProgress, + /// Fired when the ads manager is done playing all the valid ads in the ads /// response, or when the response doesn't return any valid ads. allAdsCompleted, @@ -28,18 +53,72 @@ enum AdEventType { /// This usually happens when an ad finishes or collapses. contentResumeRequested, + /// Fired when VOD stream cuepoints have changed. + cuepointsChanged, + + /// Fired when the ad playhead crosses first quartile. + firstQuartile, + + /// The user has closed the icon fallback image dialog. + iconFallbackImageClosed, + + /// The user has tapped an ad icon. + iconTapped, + /// Fired when the VAST response has been received. loaded, + + /// Fired to enable the SDK to communicate a message to be logged, which is + /// stored in adData. + log, + + /// Fired when the ad playhead crosses midpoint. + midpoint, + + /// Fired when an ad is paused. + paused, + + /// Fired when an ad is resumed. + resumed, + + /// Fired when an ad changes its skippable state. + skippableStateChanged, + + /// Fired when an ad was skipped. + skipped, + + /// Fired when an ad starts playing. + started, + + /// Stream request has loaded (only used for dynamic ad insertion). + streamLoaded, + + /// Stream has started playing (only used for dynamic ad insertion). + streamStarted, + + /// Fired when a non-clickthrough portion of a video ad is clicked. + tapped, + + /// Fired when the ad playhead crosses third quartile. + thirdQuartile, + + /// An unexpected event occurred and the type is not known. + /// + /// Refer to the inner error for more information. + unknown, } /// Simple data class used to transport ad playback information. @immutable class AdEvent { /// Creates an [AdEvent]. - const AdEvent({required this.type}); + const AdEvent({required this.type, this.adData = const {}}); /// The type of event that occurred. final AdEventType type; + + /// A map containing any extra ad data for the event, if needed. + final Map adData; } /// An event raised when there is an error loading or playing ads. diff --git a/packages/interactive_media_ads/lib/src/platform_interface/ads_request.dart b/packages/interactive_media_ads/lib/src/platform_interface/ads_request.dart deleted file mode 100644 index 72e4dfc69b63..000000000000 --- a/packages/interactive_media_ads/lib/src/platform_interface/ads_request.dart +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/// An object containing the data used to request ads from the server. -class AdsRequest { - /// Creates an [AdsRequest]. - AdsRequest({required this.adTagUrl}); - - /// The URL from which ads will be requested. - final String adTagUrl; -} diff --git a/packages/interactive_media_ads/lib/src/platform_interface/interactive_media_ads_platform.dart b/packages/interactive_media_ads/lib/src/platform_interface/interactive_media_ads_platform.dart index f1dac2db7d1d..fdb8593bdcb4 100644 --- a/packages/interactive_media_ads/lib/src/platform_interface/interactive_media_ads_platform.dart +++ b/packages/interactive_media_ads/lib/src/platform_interface/interactive_media_ads_platform.dart @@ -5,6 +5,7 @@ import 'platform_ad_display_container.dart'; import 'platform_ads_loader.dart'; import 'platform_ads_manager_delegate.dart'; +import 'platform_content_progress_provider.dart'; /// Interface for a platform implementation of the Interactive Media Ads SDKs. abstract base class InteractiveMediaAdsPlatform { @@ -29,4 +30,9 @@ abstract base class InteractiveMediaAdsPlatform { PlatformAdDisplayContainer createPlatformAdDisplayContainer( PlatformAdDisplayContainerCreationParams params, ); + + /// Creates a new [PlatformContentProgressProvider]. + PlatformContentProgressProvider createPlatformContentProgressProvider( + PlatformContentProgressProviderCreationParams params, + ); } diff --git a/packages/interactive_media_ads/lib/src/platform_interface/platform_ad_display_container.dart b/packages/interactive_media_ads/lib/src/platform_interface/platform_ad_display_container.dart index 075706f39307..2f961f9a7cc7 100644 --- a/packages/interactive_media_ads/lib/src/platform_interface/platform_ad_display_container.dart +++ b/packages/interactive_media_ads/lib/src/platform_interface/platform_ad_display_container.dart @@ -45,6 +45,7 @@ base class PlatformAdDisplayContainerCreationParams { const PlatformAdDisplayContainerCreationParams({ this.key, required this.onContainerAdded, + this.layoutDirection = TextDirection.ltr, }); /// Controls how one widget replaces another widget in the tree. @@ -56,6 +57,9 @@ base class PlatformAdDisplayContainerCreationParams { /// Invoked when the View that contains the ad has been added to the platform /// view hierarchy. final void Function(PlatformAdDisplayContainer container) onContainerAdded; + + /// The layout direction to use for the embedded AdDisplayContainer. + final TextDirection layoutDirection; } /// The interface for a platform implementation for a container in which to diff --git a/packages/interactive_media_ads/lib/src/platform_interface/platform_ads_loader.dart b/packages/interactive_media_ads/lib/src/platform_interface/platform_ads_loader.dart index 7dc6a57a1d22..51ed2a64e686 100644 --- a/packages/interactive_media_ads/lib/src/platform_interface/platform_ads_loader.dart +++ b/packages/interactive_media_ads/lib/src/platform_interface/platform_ads_loader.dart @@ -5,10 +5,10 @@ import 'package:flutter/foundation.dart'; import 'ad_error.dart'; -import 'ads_request.dart'; import 'interactive_media_ads_platform.dart'; import 'platform_ad_display_container.dart'; import 'platform_ads_manager.dart'; +import 'platform_ads_request.dart'; /// Object specifying creation parameters for creating a [PlatformAdsLoader]. /// @@ -94,7 +94,7 @@ abstract base class PlatformAdsLoader { Future contentComplete(); /// Requests ads from a server. - Future requestAds(AdsRequest request); + Future requestAds(PlatformAdsRequest request); } /// Data when ads are successfully loaded from the ad server through an diff --git a/packages/interactive_media_ads/lib/src/platform_interface/platform_ads_manager.dart b/packages/interactive_media_ads/lib/src/platform_interface/platform_ads_manager.dart index d80a17a6a730..0f3d7a7ea46f 100644 --- a/packages/interactive_media_ads/lib/src/platform_interface/platform_ads_manager.dart +++ b/packages/interactive_media_ads/lib/src/platform_interface/platform_ads_manager.dart @@ -13,7 +13,7 @@ base class AdsManagerInitParams {} /// ads. base class AdsManagerStartParams {} -/// Interface for a platform implementation of a `AdsManager`. +/// Interface for a platform implementation of an `AdsManager`. abstract class PlatformAdsManager { /// Creates a [PlatformAdsManager]. @protected @@ -28,6 +28,22 @@ abstract class PlatformAdsManager { /// /// The [AdsManagerDelegate] to notify with events during ad playback. Future setAdsManagerDelegate(PlatformAdsManagerDelegate delegate); + /// Pauses the current ad. + Future pause(); + + /// Resumes the current ad. + Future resume(); + + /// Skips the current ad. + /// + /// This only skips ads if IMA does not render the 'Skip ad' button. + Future skip(); + + /// Discards current ad break and resumes content. + /// + /// If there is no current ad then the next ad break is discarded. + Future discardAdBreak(); + /// Stops the ad and all tracking, then releases all assets that were loaded /// to play the ad. Future destroy(); diff --git a/packages/interactive_media_ads/lib/src/platform_interface/platform_ads_request.dart b/packages/interactive_media_ads/lib/src/platform_interface/platform_ads_request.dart new file mode 100644 index 000000000000..b9ef51b0ec8c --- /dev/null +++ b/packages/interactive_media_ads/lib/src/platform_interface/platform_ads_request.dart @@ -0,0 +1,21 @@ +// 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 'platform_content_progress_provider.dart'; + +/// An object containing the data used to request ads from the server. +class PlatformAdsRequest { + /// Creates an [PlatformAdsRequest]. + PlatformAdsRequest({ + required this.adTagUrl, + this.contentProgressProvider, + }); + + /// The URL from which ads will be requested. + final String adTagUrl; + + /// A [PlatformContentProgressProvider] instance to allow scheduling of ad + /// breaks based on content progress (cue points). + final PlatformContentProgressProvider? contentProgressProvider; +} diff --git a/packages/interactive_media_ads/lib/src/platform_interface/platform_content_progress_provider.dart b/packages/interactive_media_ads/lib/src/platform_interface/platform_content_progress_provider.dart new file mode 100644 index 000000000000..fb5c54a563ea --- /dev/null +++ b/packages/interactive_media_ads/lib/src/platform_interface/platform_content_progress_provider.dart @@ -0,0 +1,86 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/foundation.dart'; + +import 'interactive_media_ads_platform.dart'; + +/// Object specifying creation parameters for creating a +/// [PlatformContentProgressProvider]. +/// +/// Platform specific implementations can add additional fields by extending +/// this class. +/// +/// This example demonstrates how to extend the +/// [PlatformContentProgressProviderCreationParams] to provide additional +/// platform specific parameters. +/// +/// When extending [PlatformContentProgressProviderCreationParams] additional +/// parameters should always accept `null` or have a default value to prevent +/// breaking changes. +/// +/// ```dart +/// class AndroidPlatformContentProgressProviderCreationParams +/// extends PlatformContentProgressProviderCreationParams { +/// AndroidPlatformContentProgressProviderCreationParams._( +/// PlatformContentProgressProviderCreationParams params, { +/// this.uri, +/// }) : super(); +/// +/// factory AndroidPlatformContentProgressProviderCreationParams.fromPlatformContentProgressProviderCreationParams( +/// PlatformContentProgressProviderCreationParams params, { +/// Uri? uri, +/// }) { +/// return AndroidPlatformContentProgressProviderCreationParams._(params, uri: uri); +/// } +/// +/// final Uri? uri; +/// } +/// ``` +@immutable +base class PlatformContentProgressProviderCreationParams { + /// Used by the platform implementation to create a new + /// [PlatformContentProgressProvider]. + const PlatformContentProgressProviderCreationParams(); +} + +/// Interface to allow the SDK to track progress of the content video. +/// +/// Provides updates required to enable triggering ads at configured cue points. +abstract class PlatformContentProgressProvider { + /// Creates a new [PlatformAdsManagerDelegate] + factory PlatformContentProgressProvider( + PlatformContentProgressProviderCreationParams params, + ) { + assert( + InteractiveMediaAdsPlatform.instance != null, + 'A platform implementation for `interactive_media_ads` has not been set. ' + 'Please ensure that an implementation of `InteractiveMediaAdsPlatform` ' + 'has been set to `InteractiveMediaAdsPlatform.instance` before use. For ' + 'unit testing, `InteractiveMediaAdsPlatform.instance` can be set with ' + 'your own test implementation.', + ); + final PlatformContentProgressProvider implementation = + InteractiveMediaAdsPlatform.instance! + .createPlatformContentProgressProvider(params); + return implementation; + } + + /// Used by the platform implementation to create a new + /// [PlatformContentProgressProvider]. + /// + /// Should only be used by platform implementations because they can't extend + /// a class that only contains a factory constructor. + @protected + PlatformContentProgressProvider.implementation(this.params); + + /// The parameters used to initialize the [PlatformContentProgressProvider]. + final PlatformContentProgressProviderCreationParams params; + + /// Sends an update on the progress of the content video. + Future setProgress({ + required Duration progress, + required Duration duration, + }); +} diff --git a/packages/interactive_media_ads/lib/src/platform_interface/platform_interface.dart b/packages/interactive_media_ads/lib/src/platform_interface/platform_interface.dart index ad8896480443..fad06fe592f5 100644 --- a/packages/interactive_media_ads/lib/src/platform_interface/platform_interface.dart +++ b/packages/interactive_media_ads/lib/src/platform_interface/platform_interface.dart @@ -4,9 +4,10 @@ export 'ad_error.dart'; export 'ad_event.dart'; -export 'ads_request.dart'; export 'interactive_media_ads_platform.dart'; export 'platform_ad_display_container.dart'; export 'platform_ads_loader.dart'; export 'platform_ads_manager.dart'; export 'platform_ads_manager_delegate.dart'; +export 'platform_ads_request.dart'; +export 'platform_content_progress_provider.dart'; diff --git a/packages/interactive_media_ads/pigeons/copyright.txt b/packages/interactive_media_ads/pigeons/copyright.txt new file mode 100644 index 000000000000..fb682b1ab965 --- /dev/null +++ b/packages/interactive_media_ads/pigeons/copyright.txt @@ -0,0 +1,3 @@ +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. \ No newline at end of file diff --git a/packages/interactive_media_ads/pigeons/interactive_media_ads_android.dart b/packages/interactive_media_ads/pigeons/interactive_media_ads_android.dart new file mode 100644 index 000000000000..24318a2c6fc1 --- /dev/null +++ b/packages/interactive_media_ads/pigeons/interactive_media_ads_android.dart @@ -0,0 +1,1028 @@ +// 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: avoid_unused_constructor_parameters + +import 'package:pigeon/pigeon.dart'; + +@ConfigurePigeon( + PigeonOptions( + copyrightHeader: 'pigeons/copyright.txt', + dartOut: 'lib/src/android/interactive_media_ads.g.dart', + kotlinOut: + 'android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/InteractiveMediaAdsLibrary.g.kt', + kotlinOptions: KotlinOptions( + package: 'dev.flutter.packages.interactive_media_ads', + ), + ), +) + +/// The types of error that can be encountered. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdError.AdErrorCode.html. +enum AdErrorCode { + /// Ads player was not provided. + adsPlayerWasNotProvided, + + /// There was a problem requesting ads from the server. + adsRequestNetworkError, + + /// A companion ad failed to load or render. + companionAdLoadingFailed, + + /// There was a problem requesting ads from the server. + failedToRequestAds, + + /// An error internal to the SDK occurred. + internalError, + + /// Invalid arguments were provided to SDK methods. + invalidArguments, + + /// An overlay ad failed to load. + overlayAdLoadingFailed, + + /// An overlay ad failed to render. + overlayAdPlayingFailed, + + /// Ads list was returned but ContentProgressProvider was not configured. + playlistNoContentTracking, + + /// Ads loader sent ads loaded event when it was not expected. + unexpectedAdsLoadedEvent, + + /// The ad response was not understood and cannot be parsed. + unknownAdResponse, + + /// An unexpected error occurred and the cause is not known. + unknownError, + + /// No assets were found in the VAST ad response. + vastAssetNotFound, + + /// A VAST response containing a single `` tag with no child tags. + vastEmptyResponse, + + /// Assets were found in the VAST ad response for a linear ad, but none of + /// them matched the video player's capabilities. + vastLinearAssetMismatch, + + /// At least one VAST wrapper ad loaded successfully and a subsequent wrapper + /// or inline ad load has timed out. + vastLoadTimeout, + + /// The ad response was not recognized as a valid VAST ad. + vastMalformedResponse, + + /// Failed to load media assets from a VAST response. + vastMediaLoadTimeout, + + /// Assets were found in the VAST ad response for a nonlinear ad, but none of + /// them matched the video player's capabilities. + vastNonlinearAssetMismatch, + + /// No Ads VAST response after one or more wrappers. + vastNoAdsAfterWrapper, + + /// The maximum number of VAST wrapper redirects has been reached. + vastTooManyRedirects, + + /// Trafficking error. + /// + /// Video player received an ad type that it was not expecting and/or cannot + /// display. + vastTraffickingError, + + /// There was an error playing the video ad. + videoPlayError, + + /// The error code is not recognized by this wrapper. + unknown, +} + +/// Specifies when the error was encountered, during either ad loading or playback. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdError.AdErrorType.html. +enum AdErrorType { + /// Indicates that the error was encountered when the ad was being loaded. + load, + + /// Indicates that the error was encountered after the ad loaded, during ad play. + play, + + /// The error is not recognized by this wrapper. + unknown, +} + +/// Types of events that can occur during ad playback. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdEvent.AdEventType.html. +enum AdEventType { + /// Fired when an ad break in a stream ends. + adBreakEnded, + + /// Fired when an ad break will not play back any ads. + adBreakFetchError, + + /// Fired when an ad break is ready from VMAP or ad rule ads. + adBreakReady, + + /// Fired when an ad break in a stream starts. + adBreakStarted, + + /// Fired when playback stalls while the ad buffers. + adBuffering, + + /// Fired when an ad period in a stream ends. + adPeriodEnded, + + /// Fired when an ad period in a stream starts. + adPeriodStarted, + + /// Fired to inform of ad progress and can be used by publisher to display a + /// countdown timer. + adProgress, + + /// Fired when the ads manager is done playing all the valid ads in the ads + /// response, or when the response doesn't return any valid ads. + allAdsCompleted, + + /// Fired when an ad is clicked. + clicked, + + /// Fired when an ad completes playing. + completed, + + /// Fired when content should be paused. + contentPauseRequested, + + /// Fired when content should be resumed. + contentResumeRequested, + + /// Fired when VOD stream cuepoints have changed. + cuepointsChanged, + + /// Fired when the ad playhead crosses first quartile. + firstQuartile, + + /// The user has closed the icon fallback image dialog. + iconFallbackImageClosed, + + /// The user has tapped an ad icon. + iconTapped, + + /// Fired when the VAST response has been received. + loaded, + + /// Fired to enable the SDK to communicate a message to be logged, which is + /// stored in adData. + log, + + /// Fired when the ad playhead crosses midpoint. + midpoint, + + /// Fired when an ad is paused. + paused, + + /// Fired when an ad is resumed. + resumed, + + /// Fired when an ad changes its skippable state. + skippableStateChanged, + + /// Fired when an ad was skipped. + skipped, + + /// Fired when an ad starts playing. + started, + + /// Fired when a non-clickthrough portion of a video ad is clicked. + tapped, + + /// Fired when the ad playhead crosses third quartile. + thirdQuartile, + + /// The event type is not recognized by this wrapper. + unknown, +} + +/// Describes an element of the ad UI, to be requested or rendered by the SDK. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/UiElement.html. +enum UiElement { + /// The ad attribution UI element, for example, "Ad". + adAttribution, + + /// Ad attribution is required for a countdown timer to be displayed. + countdown, + + /// The element is not recognized by this wrapper. + unknown, +} + +/// A base class for more specialized container interfaces. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/BaseDisplayContainer.html. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: + 'com.google.ads.interactivemedia.v3.api.BaseDisplayContainer', + ), +) +abstract class BaseDisplayContainer {} + +/// A container in which to display the ads. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdDisplayContainer. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: 'com.google.ads.interactivemedia.v3.api.AdDisplayContainer', + ), +) +abstract class AdDisplayContainer implements BaseDisplayContainer {} + +/// An object which allows publishers to request ads from ad servers or a +/// dynamic ad insertion stream. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdsLoader. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: 'com.google.ads.interactivemedia.v3.api.AdsLoader', + ), +) +abstract class AdsLoader { + /// Registers a listener for errors that occur during the ads request. + void addAdErrorListener(AdErrorListener listener); + + /// Registers a listener for the ads manager loaded event. + void addAdsLoadedListener(AdsLoadedListener listener); + + /// Requests ads from a server. + void requestAds(AdsRequest request); +} + +/// An event raised when ads are successfully loaded from the ad server through an AdsLoader. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdsManagerLoadedEvent.html. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: + 'com.google.ads.interactivemedia.v3.api.AdsManagerLoadedEvent', + ), +) +abstract class AdsManagerLoadedEvent { + /// The ads manager that will control playback of the loaded ads, or null when + /// using dynamic ad insertion. + late final AdsManager manager; +} + +/// An event raised when there is an error loading or playing ads. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdErrorEvent.html. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: 'com.google.ads.interactivemedia.v3.api.AdErrorEvent', + ), +) +abstract class AdErrorEvent { + /// The AdError that caused this event. + late final AdError error; +} + +/// An error that occurred in the SDK. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdError.html. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: 'com.google.ads.interactivemedia.v3.api.AdError', + ), +) +abstract class AdError { + /// The error's code. + late final AdErrorCode errorCode; + + /// The error code's number. + late final int errorCodeNumber; + + /// The error's type. + late final AdErrorType errorType; + + /// A human-readable summary of the error. + late final String message; +} + +/// An object containing the data used to request ads from the server. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdsRequest. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: 'com.google.ads.interactivemedia.v3.api.AdsRequest', + ), +) +abstract class AdsRequest { + /// Sets the URL from which ads will be requested. + void setAdTagUrl(String adTagUrl); + + /// Attaches a ContentProgressProvider instance to allow scheduling ad breaks + /// based on content progress (cue points). + void setContentProgressProvider(ContentProgressProvider provider); +} + +/// Defines an interface to allow SDK to track progress of the content video. +/// +/// See https://developers.google.com/ad-manager/dynamic-ad-insertion/sdk/android/api/reference/com/google/ads/interactivemedia/v3/api/player/ContentProgressProvider.html. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: + 'com.google.ads.interactivemedia.v3.api.player.ContentProgressProvider', + ), +) +abstract class ContentProgressProvider { + ContentProgressProvider(); + + /// Sets an update on the progress of the video. + /// + /// This is a custom method added to the native class because the native + /// method `getContentProgress` requires a synchronous return value. + void setContentProgress(VideoProgressUpdate update); +} + +/// An object which handles playing ads after they've been received from the +/// server. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdsManager. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: 'com.google.ads.interactivemedia.v3.api.AdsManager', + ), +) +abstract class AdsManager extends BaseManager { + /// Discards current ad break and resumes content. + void discardAdBreak(); + + /// Pauses the current ad. + void pause(); + + /// Starts playing the ads. + void start(); + + /// List of content time offsets in seconds at which ad breaks are scheduled. + /// + /// The list will be empty if no ad breaks are scheduled. + List getAdCuePoints(); + + /// Resumes the current ad. + void resume(); + + /// Skips the current ad. + /// + /// `AdsManager.skip()` only skips ads if IMA does not render the 'Skip ad' + /// button. + void skip(); +} + +/// Base interface for managing ads.. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/BaseManager.html. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: 'com.google.ads.interactivemedia.v3.api.BaseManager', + ), +) +abstract class BaseManager { + /// Registers a listener for errors that occur during the ad or stream + /// initialization and playback. + void addAdErrorListener(AdErrorListener errorListener); + + /// Registers a listener for ad events that occur during ad or stream + /// initialization and playback. + void addAdEventListener(AdEventListener adEventListener); + + /// Stops the ad and all tracking, then releases all assets that were loaded + /// to play the ad. + void destroy(); + + /// Initializes the ad experience on the manager. + void init(AdsRenderingSettings? settings); + + /// Generic focus endpoint that puts focus on the skip button if present. + void focus(); + + /// Returns the latest AdProgressInfo for the current playing ad. + AdProgressInfo? getAdProgressInfo(); + + /// Get currently playing ad. + Ad? getCurrentAd(); + + /// Removes a listener for error events. + void removeAdErrorListener(AdErrorListener errorListener); + + /// Removes a listener for ad events. + void removeAdEventListener(AdEventListener adEventListener); +} + +/// Event to notify publisher that an event occurred with an Ad. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdEvent.html. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: 'com.google.ads.interactivemedia.v3.api.AdEvent', + ), +) +abstract class AdEvent { + /// The type of event that occurred. + late final AdEventType type; + + /// A map containing any extra ad data for the event, if needed. + late final Map? adData; +} + +/// Factory class for creating SDK objects. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/ImaSdkFactory. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: 'com.google.ads.interactivemedia.v3.api.ImaSdkFactory', + ), +) +abstract class ImaSdkFactory { + @static + @attached + late final ImaSdkFactory instance; + + @static + AdDisplayContainer createAdDisplayContainer( + ViewGroup container, + VideoAdPlayer player, + ); + + /// Creates an `ImaSdkSettings` object for configuring the IMA SDK. + ImaSdkSettings createImaSdkSettings(); + + /// Creates an `AdsLoader` for requesting ads using the specified settings + /// object. + AdsLoader createAdsLoader( + ImaSdkSettings settings, + AdDisplayContainer container, + ); + + /// Creates an AdsRequest object to contain the data used to request ads. + AdsRequest createAdsRequest(); +} + +/// Defines general SDK settings that are used when creating an `AdsLoader`. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/ImaSdkSettings.html. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: 'com.google.ads.interactivemedia.v3.api.ImaSdkSettings', + ), +) +abstract class ImaSdkSettings {} + +/// Defines an update to the video's progress. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/player/VideoProgressUpdate.html. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: + 'com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate', + ), +) +abstract class VideoProgressUpdate { + VideoProgressUpdate(int currentTimeMs, int durationMs); + + /// Value to use for cases when progress is not yet defined, such as video + /// initialization. + @static + @attached + late final VideoProgressUpdate videoTimeNotReady; +} + +/// The minimal information required to play an ad. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/player/AdMediaInfo.html. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: 'com.google.ads.interactivemedia.v3.api.player.AdMediaInfo', + ), +) +abstract class AdMediaInfo { + late final String url; +} + +/// An ad may be part of a pod of ads. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdPodInfo.html. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: 'com.google.ads.interactivemedia.v3.api.AdPodInfo', + ), +) +abstract class AdPodInfo { + /// The position of the ad within the pod. + /// + /// The value returned is one-based, for example, 1 of 2, 2 of 2, etc. If the + /// ad is not part of a pod, this will return 1. + late final int adPosition; + + /// The maximum duration of the pod in seconds. + /// + /// For unknown duration, -1 is returned. + late final double maxDuration; + + /// Client side and DAI VOD: Returns the index of the ad pod. + late final int podIndex; + + /// The content time offset at which the current ad pod was scheduled. + /// + /// For preroll pod, 0 is returned. For midrolls, the scheduled time is + /// returned in seconds. For postroll, -1 is returned. Defaults to 0 if this + /// ad is not part of a pod, or the pod is not part of an ad playlist. + late final double timeOffset; + + /// The total number of ads contained within this pod, including bumpers. + late final int totalAds; + + /// Returns true if the ad is a bumper ad. + late final bool isBumper; +} + +/// FrameLayout is designed to block out an area on the screen to display a +/// single item. +/// +/// See https://developer.android.com/reference/android/widget/FrameLayout. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: 'android.widget.FrameLayout', + ), +) +abstract class FrameLayout extends ViewGroup { + FrameLayout(); +} + +/// A special view that can contain other views (called children.) +/// +/// See https://developer.android.com/reference/android/view/ViewGroup. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: 'android.view.ViewGroup', + ), +) +abstract class ViewGroup extends View { + /// Adds a child view. + void addView(View view); + + /// Called by a ViewGroup subclass to remove child views from itself, when it + /// must first know its size on screen before it can calculate how many child + /// views it will render. + void removeView(View view); +} + +/// Displays a video file. +/// +/// See https://developer.android.com/reference/android/widget/VideoView. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: 'android.widget.VideoView', + ), +) +abstract class VideoView extends View { + VideoView(); + + /// Callback to be invoked when the media source is ready for playback. + late final void Function(MediaPlayer player)? onPrepared; + + /// Callback to be invoked when playback of a media source has completed. + late final void Function(MediaPlayer player)? onCompletion; + + /// Callback to be invoked when there has been an error during an asynchronous + /// operation. + late final void Function(MediaPlayer player, int what, int extra) onError; + + /// Sets the URI of the video. + void setVideoUri(String? uri); + + /// The current position of the playing video. + /// + /// In milliseconds. + int getCurrentPosition(); +} + +/// This class represents the basic building block for user interface components. +/// +/// See https://developer.android.com/reference/android/view/View. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions(fullClassName: 'android.view.View'), +) +abstract class View {} + +/// MediaPlayer class can be used to control playback of audio/video files and +/// streams. +/// +/// See https://developer.android.com/reference/android/media/MediaPlayer. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: 'android.media.MediaPlayer', + ), +) +abstract class MediaPlayer { + /// Gets the duration of the file. + int getDuration(); + + /// Seeks to specified time position. + void seekTo(int mSec); + + /// Starts or resumes playback. + void start(); + + /// Pauses playback. + void pause(); + + /// Stops playback after playback has been started or paused. + void stop(); +} + +/// Callbacks that the player must fire. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/player/VideoAdPlayer.VideoAdPlayerCallback.html +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: + 'com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer.VideoAdPlayerCallback', + ), +) +abstract class VideoAdPlayerCallback { + /// Fire this callback periodically as ad playback occurs. + void onAdProgress( + AdMediaInfo adMediaInfo, + VideoProgressUpdate videoProgressUpdate, + ); + + /// Fire this callback when video playback stalls waiting for data. + void onBuffering(AdMediaInfo adMediaInfo); + + /// Fire this callback when all content has finished playing. + void onContentComplete(); + + /// Fire this callback when the video finishes playing. + void onEnded(AdMediaInfo adMediaInfo); + + /// Fire this callback when the video has encountered an error. + void onError(AdMediaInfo adMediaInfo); + + /// Fire this callback when the video is ready to begin playback. + void onLoaded(AdMediaInfo adMediaInfo); + + /// Fire this callback when the video is paused. + void onPause(AdMediaInfo adMediaInfo); + + /// Fire this callback when the player begins playing a video. + void onPlay(AdMediaInfo adMediaInfo); + + /// Fire this callback when the video is unpaused. + void onResume(AdMediaInfo adMediaInfo); + + /// Fire this callback when the playback volume changes. + void onVolumeChanged(AdMediaInfo adMediaInfo, int percentage); +} + +/// Defines the set of methods that a video player must implement to be used by +/// the IMA SDK, as well as a set of callbacks that it must fire. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/player/VideoAdPlayer.html. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: + 'com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer', + ), +) +abstract class VideoAdPlayer { + VideoAdPlayer(); + + /// Adds a callback. + late final void Function(VideoAdPlayerCallback callback) addCallback; + + /// Loads a video ad hosted at AdMediaInfo. + late final void Function(AdMediaInfo adMediaInfo, AdPodInfo adPodInfo) loadAd; + + /// Pauses playing the current ad. + late final void Function(AdMediaInfo adMediaInfo) pauseAd; + + /// Starts or resumes playing the video ad referenced by the AdMediaInfo, + /// provided loadAd has already been called for it. + late final void Function(AdMediaInfo adMediaInfo) playAd; + + /// Cleans up and releases all resources used by the `VideoAdPlayer`. + late final void Function() release; + + /// Removes a callback. + late final void Function(VideoAdPlayerCallback callback) removeCallback; + + /// Stops playing the current ad. + late final void Function(AdMediaInfo adMediaInfo) stopAd; + + /// The volume of the player as a percentage from 0 to 100. + void setVolume(int value); + + /// The `VideoProgressUpdate` describing playback progress of the current + /// video. + void setAdProgress(VideoProgressUpdate progress); +} + +/// Listener interface for notification of ad load or stream load completion. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdsLoader.AdsLoadedListener.html. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: + 'com.google.ads.interactivemedia.v3.api.AdsLoader.AdsLoadedListener', + ), +) +abstract class AdsLoadedListener { + AdsLoadedListener(); + + /// Called once the AdsManager or StreamManager has been loaded. + late final void Function(AdsManagerLoadedEvent event) onAdsManagerLoaded; +} + +/// Interface for classes that will listen to AdErrorEvents. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdErrorEvent.AdErrorListener.html. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: + 'com.google.ads.interactivemedia.v3.api.AdErrorEvent.AdErrorListener', + ), +) +abstract class AdErrorListener { + AdErrorListener(); + + /// Called when an error occurs. + late final void Function(AdErrorEvent event) onAdError; +} + +/// Listener interface for ad events. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdEvent.AdEventListener.html. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: + 'com.google.ads.interactivemedia.v3.api.AdEvent.AdEventListener', + ), +) +abstract class AdEventListener { + AdEventListener(); + + /// Respond to an occurrence of an AdEvent. + late final void Function(AdEvent event) onAdEvent; +} + +/// Defines parameters that control the rendering of ads. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdsRenderingSettings.html. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: + 'com.google.ads.interactivemedia.v3.api.AdsRenderingSettings', + ), +) +abstract class AdsRenderingSettings { + /// Maximum recommended bitrate. + int getBitrateKbps(); + + /// Returns whether the click-through URL will be opened using Custom Tabs + /// feature. + bool getEnableCustomTabs(); + + /// Whether the SDK will instruct the player to load the creative in response + /// to `BaseManager.init()`. + bool getEnablePreloading(); + + /// Whether to focus on the skip button when the skippable ad can be skipped + /// on Android TV. + /// + /// This is a no-op on non-Android TV devices. + bool getFocusSkipButtonWhenAvailable(); + + /// The SDK will prioritize the media with MIME type on the list. + List getMimeTypes(); + + /// Maximum recommended bitrate. + /// + /// The value is in kbit/s. Default value, -1, means the bitrate will be + /// selected by the SDK. + void setBitrateKbps(int bitrate); + + /// Notifies the SDK whether to launch the click-through URL using Custom Tabs + /// feature. + /// + /// Default is false. + void setEnableCustomTabs(bool enableCustomTabs); + + /// If set, the SDK will instruct the player to load the creative in response + /// to `BaseManager.init()`. + /// + /// This allows the player to preload the ad at any point before calling + /// `AdsManager.start()`. + void setEnablePreloading(bool enablePreloading); + + /// Set whether to focus on the skip button when the skippable ad can be + /// skipped on Android TV. + /// + /// This is a no-op on non-Android TV devices. + /// + /// Default is true. + void setFocusSkipButtonWhenAvailable(bool enableFocusSkipButton); + + /// Specifies a non-default amount of time to wait for media to load before + /// timing out, in milliseconds. + /// + /// This only applies to the IMA client-side SDK. + /// + /// Default time is 8000 ms. + void setLoadVideoTimeout(int loadVideoTimeout); + + /// If specified, the SDK will prioritize the media with MIME type on the + /// list. + void setMimeTypes(List mimeTypes); + + /// For VMAP and ad rules playlists, only play ad breaks scheduled after this + /// time (in seconds). + void setPlayAdsAfterTime(double time); + + /// Sets the ad UI elements to be rendered by the IMA SDK. + void setUiElements(List uiElements); +} + +/// Represents the progress within this ad break. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdProgressInfo.html. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: 'com.google.ads.interactivemedia.v3.api.AdProgressInfo', + ), +) +abstract class AdProgressInfo { + /// Total ad break duration (in seconds). + late final double adBreakDuration; + + /// Total ad period duration (in seconds). + late final double adPeriodDuration; + + /// The position of current ad within the ad break, starting with 1. + late final int adPosition; + + /// Current time within the ad (in seconds). + late final double currentTime; + + /// Duration of current ad (in seconds). + late final double duration; + + /// The total number of ads in this ad break. + late final int totalAds; +} + +/// An object that holds data corresponding to the companion Ad. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/CompanionAd.html. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: 'com.google.ads.interactivemedia.v3.api.CompanionAd', + ), +) +abstract class CompanionAd { + /// The API needed to execute this ad, or null if unavailable. + late final String? apiFramework; + + /// The height of the companion in pixels. + /// + /// 0 if unavailable. + late final int height; + + /// The URL for the static resource of this companion. + late final String resourceValue; + + /// The width of the companion in pixels. + /// + /// 0 if unavailable. + late final int width; +} + +/// This object exposes information about the universal ad ID. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/UniversalAdId.html. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: 'com.google.ads.interactivemedia.v3.api.UniversalAdId', + ), +) +abstract class UniversalAdId { + /// Returns the ad ID registry associated with the ad ID value. + /// + /// Returns "unknown" if the registry is not known. + late final String adIdRegistry; + + /// Returns the universal ad ID value. + /// + /// Returns "unknown" if the value is not known. + late final String adIdValue; +} + +/// An object that holds data corresponding to the main Ad. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/Ad.html. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: 'com.google.ads.interactivemedia.v3.api.Ad', + ), +) +abstract class Ad { + /// The ad ID as specified in the VAST response. + late final String adId; + + /// The pod metadata object. + late final AdPodInfo adPodInfo; + + /// The ad system as specified in the VAST response. + late final String adSystem; + + /// The IDs of the ads' creatives, starting with the first wrapper ad. + late final List adWrapperCreativeIds; + + /// The wrapper ad IDs as specified in the VAST response. + late final List adWrapperIds; + + /// The wrapper ad systems as specified in the VAST response. + late final List adWrapperSystems; + + /// The advertiser name as defined by the serving party. + late final String advertiserName; + + /// The companions for the current ad while using DAI. + /// + /// Returns an empty list in any other scenario. + late final List companionAds; + + /// The content type of the currently selected creative, or null if no + /// creative is selected or the content type is unavailable. + late final String? contentType; + + /// The ISCI (Industry Standard Commercial Identifier) code for an ad. + late final String creativeAdId; + + /// The ID of the selected creative for the ad, + late final String creativeId; + + /// The first deal ID present in the wrapper chain for the current ad, + /// starting from the top. + late final String dealId; + + /// The description of this ad from the VAST response. + late final String? description; + + /// The duration of the ad in seconds, -1 if not available. + late final double duration; + + /// The height of the selected creative if non-linear, else returns 0. + late final int height; + + /// The number of seconds of playback before the ad becomes skippable. + late final double skipTimeOffset; + + /// The URL associated with the survey for the given ad. + late final String? surveyUrl; + + /// The title of this ad from the VAST response. + late final String? title; + + /// The custom parameters associated with the ad at the time of ad + /// trafficking. + late final String traffickingParameters; + + /// Te set of ad UI elements rendered by the IMA SDK for this ad. + late final List uiElements; + + /// The list of all universal ad IDs for this ad. + late final List universalAdIds; + + /// The VAST bitrate in Kbps of the selected creative. + late final int vastMediaBitrate; + + /// The VAST media height in pixels of the selected creative. + late final int vastMediaHeight; + + /// The VAST media width in pixels of the selected creative. + late final int vastMediaWidth; + + /// The width of the selected creative if non-linear, else returns 0. + late final int width; + + /// Indicates whether the ad’s current mode of operation is linear or + /// non-linear. + late final bool isLinear; + + /// Indicates whether the ad can be skipped by the user. + late final bool isSkippable; +} diff --git a/packages/interactive_media_ads/pigeons/interactive_media_ads_ios.dart b/packages/interactive_media_ads/pigeons/interactive_media_ads_ios.dart new file mode 100644 index 000000000000..da64692f8456 --- /dev/null +++ b/packages/interactive_media_ads/pigeons/interactive_media_ads_ios.dart @@ -0,0 +1,654 @@ +// 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: avoid_unused_constructor_parameters + +import 'package:pigeon/pigeon.dart'; + +@ConfigurePigeon( + PigeonOptions( + copyrightHeader: 'pigeons/copyright.txt', + dartOut: 'lib/src/ios/interactive_media_ads.g.dart', + swiftOut: + 'ios/interactive_media_ads/Sources/interactive_media_ads/InteractiveMediaAdsLibrary.g.swift', + ), +) + +/// Possible error types while loading or playing ads. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Enums/IMAErrorType.html. +enum AdErrorType { + /// An error occurred while loading the ads. + loadingFailed, + + /// An error occurred while playing the ads. + adPlayingFailed, + + /// An unexpected error occurred while loading or playing the ads. + /// + /// This may mean that the SDK wasn’t loaded properly or the wrapper doesn't + /// recognize this value. + unknown, +} + +/// Possible error codes raised while loading or playing ads. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Enums/IMAErrorCode.html. +enum AdErrorCode { + /// The ad slot is not visible on the page. + adslotNotVisible, + + /// Generic invalid usage of the API. + apiError, + + /// A companion ad failed to load or render. + companionAdLoadingFailed, + + /// Content playhead was not passed in, but list of ads has been returned from + /// the server. + contentPlayheadMissing, + + /// There was an error loading the ad. + failedLoadingAd, + + /// There was a problem requesting ads from the server. + failedToRequestAds, + + /// Invalid arguments were provided to SDK methods. + invalidArguments, + + /// The version of the runtime is too old. + osRuntimeTooOld, + + /// Ads list response was malformed. + playlistMalformedResponse, + + /// Listener for at least one of the required vast events was not added. + requiredListenersNotAdded, + + /// There was an error initializing the stream. + streamInitializationFailed, + + /// An unexpected error occurred and the cause is not known. + unknownError, + + /// No assets were found in the VAST ad response. + vastAssetNotFound, + + /// A VAST response containing a single `` tag with no child tags. + vastEmptyResponse, + + /// At least one VAST wrapper loaded and a subsequent wrapper or inline ad + /// load has resulted in a 404 response code. + vastInvalidUrl, + + /// Assets were found in the VAST ad response for a linear ad, but none of + /// them matched the video player's capabilities. + vastLinearAssetMismatch, + + /// The VAST URI provided, or a VAST URI provided in a subsequent Wrapper + /// element, was either unavailable or reached a timeout, as defined by the + /// video player. + vastLoadTimeout, + + /// The ad response was not recognized as a valid VAST ad. + vastMalformedResponse, + + /// Failed to load media assets from a VAST response. + vastMediaLoadTimeout, + + /// The maximum number of VAST wrapper redirects has been reached. + vastTooManyRedirects, + + /// Trafficking error. + /// + /// Video player received an ad type that it was not expecting and/or cannot + /// display. + vastTraffickingError, + + /// Another VideoAdsManager is still using the video. + videoElementUsed, + + /// A video element was not specified where it was required. + videoElementRequired, + + /// There was an error playing the video ad. + videoPlayError, +} + +/// Different event types sent by the IMAAdsManager to its delegate. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Enums/IMAAdEventType.html. +enum AdEventType { + /// Fired the first time each ad break ends. + adBreakEnded, + + /// Fired when an ad break will not play back any ads. + adBreakFetchError, + + /// Fired when an ad break is ready. + adBreakReady, + + /// Fired first time each ad break begins playback. + adBreakStarted, + + /// Fired every time the stream switches from advertising or slate to content. + adPeriodEnded, + + /// Fired every time the stream switches from content to advertising or slate. + adPeriodStarted, + + /// All valid ads managed by the ads manager have completed or the ad response + /// did not return any valid ads. + allAdsCompleted, + + /// Fired when an ad is clicked. + clicked, + + /// Single ad has finished. + completed, + + /// Cuepoints changed for VOD stream (only used for dynamic ad insertion). + cuepointsChanged, + + /// First quartile of a linear ad was reached. + firstQuartile, + + /// The user has closed the icon fallback image dialog. + iconFallbackImageClosed, + + /// The user has tapped an ad icon. + iconTapped, + + /// An ad was loaded. + loaded, + + /// A log event for the ads being played. + log, + + /// Midpoint of a linear ad was reached. + midpoint, + + /// Ad paused. + pause, + + /// Ad resumed. + resume, + + /// Fired when an ad was skipped. + skipped, + + /// Fired when an ad starts playing. + started, + + /// Stream request has loaded (only used for dynamic ad insertion). + streamLoaded, + + /// Stream has started playing (only used for dynamic ad insertion). + streamStarted, + + /// Ad tapped. + tapped, + + /// Third quartile of a linear ad was reached.. + thirdQuartile, + + /// The event type is not recognized by this wrapper. + unknown, +} + +/// The values that can be returned in a change dictionary. +/// +/// See https://developer.apple.com/documentation/foundation/nskeyvalueobservingoptions?language=objc. +enum KeyValueObservingOptions { + /// Indicates that the change dictionary should provide the new attribute + /// value, if applicable. + newValue, + + /// Indicates that the change dictionary should contain the old attribute + /// value, if applicable. + oldValue, + + /// If specified, a notification should be sent to the observer immediately, + /// before the observer registration method even returns. + initialValue, + + /// Whether separate notifications should be sent to the observer before and + /// after each change, instead of a single notification after the change. + priorNotification, +} + +/// The kinds of changes that can be observed.. +/// +/// See https://developer.apple.com/documentation/foundation/nskeyvaluechange?language=objc. +enum KeyValueChange { + /// Indicates that the value of the observed key path was set to a new value. + setting, + + /// Indicates that an object has been inserted into the to-many relationship + /// that is being observed. + insertion, + + /// Indicates that an object has been removed from the to-many relationship + /// that is being observed. + removal, + + /// Indicates that an object has been replaced in the to-many relationship + /// that is being observed. + replacement, +} + +/// The keys that can appear in the change dictionary.. +/// +/// See https://developer.apple.com/documentation/foundation/nskeyvaluechangekey?language=objc. +enum KeyValueChangeKey { + /// If the value of the kindKey entry is NSKeyValueChange.insertion, + /// NSKeyValueChange.removal, or NSKeyValueChange.replacement, the value of + /// this key is an NSIndexSet object that contains the indexes of the + /// inserted, removed, or replaced objects. + indexes, + + /// An NSNumber object that contains a value corresponding to one of the + /// NSKeyValueChange enums, indicating what sort of change has occurred. + kind, + + /// If the value of the kindKey entry is NSKeyValueChange.setting, and new was + /// specified when the observer was registered, the value of this key is the + /// new value for the attribute. + newValue, + + /// If the prior option was specified when the observer was registered this + /// notification is sent prior to a change. + notificationIsPrior, + + /// If the value of the kindKey entry is NSKeyValueChange.setting, and old was + /// specified when the observer was registered, the value of this key is the + /// value before the attribute was changed. + oldValue, + + /// The key is not recognized by this wrapper. + unknown, +} + +/// A list of purposes for which an obstruction would be registered as friendly. +/// +/// See https://developers.google.com/ad-manager/dynamic-ad-insertion/sdk/ios/reference/Enums/IMAFriendlyObstructionPurpose.html. +enum FriendlyObstructionPurpose { + mediaControls, + + closeAd, + + notVisible, + + other, + + /// The purpose type is not recognized by this wrapper. + unknown, +} + +/// Different UI elements that can be customized. +/// +/// See https://developers.google.com/ad-manager/dynamic-ad-insertion/sdk/ios/reference/Enums/IMAUiElementType.html. +enum UIElementType { + /// Ad attribution UI element. + adAttribution, + + /// Ad countdown element. + countdown, + + /// The element is not recognized by this wrapper. + unknown, +} + +/// The `IMAAdDisplayContainer` is responsible for managing the ad container +/// view and companion ad slots used for ad playback. +/// +/// See https://developers.google.com/ad-manager/dynamic-ad-insertion/sdk/ios/reference/Classes/IMAAdDisplayContainer. +@ProxyApi( + swiftOptions: SwiftProxyApiOptions(import: 'GoogleInteractiveMediaAds'), +) +abstract class IMAAdDisplayContainer extends NSObject { + IMAAdDisplayContainer( + UIView adContainer, + UIViewController? adContainerViewController, + ); +} + +/// An object that manages the content for a rectangular area on the screen. +/// +/// See https://developer.apple.com/documentation/uikit/uiview. +@ProxyApi(swiftOptions: SwiftProxyApiOptions(import: 'UIKit')) +abstract class UIView extends NSObject {} + +/// An object that manages a view hierarchy for your UIKit app. +/// +/// See https://developer.apple.com/documentation/uikit/uiviewcontroller. +@ProxyApi() +abstract class UIViewController extends NSObject { + UIViewController(); + + /// Notifies the view controller that its view was added to a view hierarchy. + late void Function(bool animated)? viewDidAppear; + + /// Retrieves the view that the controller manages. + /// + /// For convenience this is a `final` attached field despite this being + /// settable. Since this is not a part of the IMA SDK this is slightly changed + /// for convenience. Note that this wrapper should not add the ability to set + /// this property as it should not be needed anyways. + @attached + late final UIView view; +} + +/// Defines an interface for a class that tracks video content progress and +/// exposes a key value observable property |currentTime|. +/// +/// See https://developers.google.com/ad-manager/dynamic-ad-insertion/sdk/ios/reference/Protocols/IMAContentPlayhead. +@ProxyApi() +abstract class IMAContentPlayhead extends NSObject { + IMAContentPlayhead(); + + /// Reflects the current playback time in seconds for the content. + void setCurrentTime(double timeInterval); +} + +/// Allows the requesting of ads from the ad server. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes/IMAAdsLoader. +@ProxyApi() +abstract class IMAAdsLoader extends NSObject { + IMAAdsLoader(IMASettings? settings); + + /// Signal to the SDK that the content has completed. + void contentComplete(); + + /// Request ads from the ad server. + void requestAds(IMAAdsRequest request); + + /// Delegate that receives `IMAAdsLoaderDelegate` callbacks. + /// + /// Note that this sets to a `weak` property in Swift. + void setDelegate(IMAAdsLoaderDelegate? delegate); +} + +/// The IMASettings class stores SDK wide settings. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes/IMASettings.html. +@ProxyApi() +abstract class IMASettings extends NSObject {} + +/// Data class describing the ad request. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes/IMAAdsRequest. +@ProxyApi() +abstract class IMAAdsRequest extends NSObject { + /// Initializes an ads request instance with the given ad tag URL and ad + /// display container. + IMAAdsRequest( + String adTagUrl, + IMAAdDisplayContainer adDisplayContainer, + IMAContentPlayhead? contentPlayhead, + ); +} + +/// Delegate object that receives state change callbacks from `IMAAdsLoader`. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Protocols/IMAAdsLoaderDelegate.html. +@ProxyApi() +abstract class IMAAdsLoaderDelegate extends NSObject { + IMAAdsLoaderDelegate(); + + /// Called when ads are successfully loaded from the ad servers by the loader. + late final void Function( + IMAAdsLoader loader, + IMAAdsLoadedData adsLoadedData, + ) adLoaderLoadedWith; + + /// Error reported by the ads loader when loading or requesting an ad fails. + late final void Function( + IMAAdsLoader loader, + IMAAdLoadingErrorData adErrorData, + ) adsLoaderFailedWithErrorData; +} + +/// Ad data that is returned when the ads loader loads the ad. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes/IMAAdsLoadedData.html. +@ProxyApi() +abstract class IMAAdsLoadedData extends NSObject { + /// The ads manager instance created by the ads loader. + /// + /// Will be null when using dynamic ad insertion. + IMAAdsManager? adsManager; +} + +/// Ad error data that is returned when the ads loader fails to load the ad. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes/IMAAdLoadingErrorData.html. +@ProxyApi() +abstract class IMAAdLoadingErrorData extends NSObject { + /// The ad error that occurred while loading the ad. + late final IMAAdError adError; +} + +/// Surfaces an error that occurred during ad loading or playing. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes/IMAAdError.html. +@ProxyApi() +abstract class IMAAdError extends NSObject { + /// The type of error that occurred during ad loading or ad playing. + late final AdErrorType type; + + /// The error code for obtaining more specific information about the error. + late final AdErrorCode code; + + /// A brief description about the error. + late final String? message; +} + +/// Responsible for playing ads. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes/IMAAdsManager.html. +@ProxyApi() +abstract class IMAAdsManager extends NSObject { + /// The `IMAAdsManagerDelegate` to notify with events during ad playback. + void setDelegate(IMAAdsManagerDelegate? delegate); + + /// Initializes and loads the ad. + void initialize(IMAAdsRenderingSettings? adsRenderingSettings); + + /// Starts advertisement playback. + void start(); + + /// Pauses advertisement. + void pause(); + + /// Resumes the current ad. + void resume(); + + /// Skips the advertisement if the ad is skippable and the skip offset has + /// been reached. + void skip(); + + /// If an ad break is currently playing, discard it and resume content. + void discardAdBreak(); + + /// Causes the ads manager to stop the ad and clean its internal state. + void destroy(); +} + +/// A callback protocol for IMAAdsManager. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Protocols/IMAAdsManagerDelegate.html. +@ProxyApi() +abstract class IMAAdsManagerDelegate extends NSObject { + IMAAdsManagerDelegate(); + + /// Called when there is an IMAAdEvent. + late final void Function( + IMAAdsManager adsManager, + IMAAdEvent event, + ) didReceiveAdEvent; + + /// Called when there was an error playing the ad. + late final void Function( + IMAAdsManager adsManager, + IMAAdError error, + ) didReceiveAdError; + + /// Called when an ad is ready to play. + late final void Function(IMAAdsManager adsManager) didRequestContentPause; + + /// Called when an ad has finished or an error occurred during the playback. + late final void Function(IMAAdsManager adsManager) didRequestContentResume; +} + +/// Simple data class used to transport ad playback information. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes/IMAAdEvent.html. +@ProxyApi() +abstract class IMAAdEvent extends NSObject { + /// Type of the event. + late final AdEventType type; + + /// Stringified type of the event. + late final String typeString; + + /// Extra data about the ad. + late final Map? adData; +} + +/// Set of properties that influence how ads are rendered. +/// +/// See https://developers.google.com/ad-manager/dynamic-ad-insertion/sdk/ios/reference/Classes/IMAAdsRenderingSettings. +@ProxyApi() +abstract class IMAAdsRenderingSettings extends NSObject { + IMAAdsRenderingSettings(); + + /// If specified, the SDK will play the media with MIME type on the list. + void setMimeTypes(List? types); + + /// Maximum recommended bitrate. + /// + /// The value is in kbit/s. + void setBitrate(int bitrate); + + /// Timeout (in seconds) when loading a video ad media file. + /// + /// Use -1 for the default of 8 seconds. + void setLoadVideoTimeout(double seconds); + + /// For VMAP and ad rules playlists, only play ad breaks scheduled after this + /// time (in seconds). + void setPlayAdsAfterTime(double seconds); + + /// Specifies the list of UI elements that should be visible. + void setUIElements(List? types); + + /// Whether or not the SDK will preload ad media. + /// + /// Default is YES. + void setEnablePreloading(bool enable); + + /// Specifies the optional UIViewController that will be used to open links + /// in-app. + void setLinkOpenerPresentingController(UIViewController controller); +} + +/// The root class of most Objective-C class hierarchies, from which subclasses +/// inherit a basic interface to the runtime system and the ability to behave as +/// Objective-C objects. +/// +/// See https://developer.apple.com/documentation/objectivec/nsobject. +@ProxyApi() +abstract class NSObject {} + +/// An obstruction that is marked as “friendly” for viewability measurement +/// purposes. +/// +/// See https://developers.google.com/ad-manager/dynamic-ad-insertion/sdk/ios/reference/Classes/IMAFriendlyObstruction.html. +@ProxyApi() +abstract class IMAFriendlyObstruction extends NSObject { + /// Initializes a friendly obstruction. + IMAFriendlyObstruction(); + + /// The view causing the obstruction. + late final UIView view; + + /// The purpose for registering the obstruction as friendly. + late final FriendlyObstructionPurpose purpose; + + /// Optional, detailed reasoning for registering this obstruction as friendly. + /// + /// If the detailedReason is not null, it must follow the IAB standard by + /// being 50 characters or less and only containing characters A-z, 0-9, or + /// spaces. + late final String? detailedReason; +} + +/// An object that holds data corresponding to the companion ad. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes/IMACompanionAd. +@ProxyApi() +abstract class IMACompanionAd extends NSObject { + /// The value for the resource of this companion. + late final String? resourceValue; + + /// The API needed to execute this ad, or nil if unavailable. + late final String? apiFramework; + + /// The width of the companion in pixels. + /// + /// 0 if unavailable. + late final int width; + + /// The height of the companion in pixels. + /// + /// 0 if unavailable. + late final int height; +} + +/// Ad slot for companion ads. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes/IMACompanionAdSlot. +@ProxyApi() +abstract class IMACompanionAdSlot { + /// Initializes an instance of a IMACompanionAdSlot with fluid size. + IMACompanionAdSlot(); + + /// Initializes an instance of a IMACompanionAdSlot with design ad width and + /// height. + /// + /// `width` and `height` are in pixels. + IMACompanionAdSlot.size(int width, int height); + + /// The view the companion will be rendered in. + /// + /// Display this view in your application before video ad starts. + late final UIView view; + + /// The IMACompanionDelegate for receiving events from the companion ad slot. + /// + /// This instance only creates a weak reference to the delegate, so the Dart + /// instance should create an explicit reference to receive callbacks. + void setDelegate(IMACompanionDelegate? delegate); +} + +/// Delegate to receive events from the companion ad slot. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Protocols/IMACompanionDelegate.html. +@ProxyApi() +abstract class IMACompanionDelegate extends NSObject { + IMACompanionDelegate(); + + /// Called when the slot is either filled or not filled. + late void Function( + IMACompanionAdSlot slot, + bool filled, + )? companionAdSlotFilled; + + /// Called when the slot is clicked on by the user and will successfully + /// navigate away. + late void Function(IMACompanionAdSlot slot)? companionSlotWasClicked; +} diff --git a/packages/interactive_media_ads/pubspec.yaml b/packages/interactive_media_ads/pubspec.yaml index bd4d715f7b50..88e8c6fc8489 100644 --- a/packages/interactive_media_ads/pubspec.yaml +++ b/packages/interactive_media_ads/pubspec.yaml @@ -2,11 +2,13 @@ name: interactive_media_ads description: A Flutter plugin for using the Interactive Media Ads SDKs on Android and iOS. repository: https://github.com/flutter/packages/tree/main/packages/interactive_media_ads issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+interactive_media_ads%22 -version: 0.0.1+2 +version: 0.2.2+15 # This must match the version in + # `android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsRequestProxyApi.kt` and + # `ios/interactive_media_ads/Sources/interactive_media_ads/AdsRequestProxyAPIDelegate.swift` environment: - sdk: ^3.2.3 - flutter: ">=3.16.6" + sdk: ^3.5.0 + flutter: ">=3.24.0" flutter: plugin: @@ -14,18 +16,22 @@ flutter: android: package: dev.flutter.packages.interactive_media_ads pluginClass: InteractiveMediaAdsPlugin + dartPluginClass: AndroidInteractiveMediaAds ios: pluginClass: InteractiveMediaAdsPlugin + dartPluginClass: IOSInteractiveMediaAds dependencies: flutter: sdk: flutter + meta: ^1.10.0 dev_dependencies: build_runner: ^2.1.4 flutter_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 + pigeon: ^22.5.0 topics: - ads diff --git a/packages/interactive_media_ads/test/ad_display_container_test.dart b/packages/interactive_media_ads/test/ad_display_container_test.dart index a82a16e8c4c2..c237424a806c 100644 --- a/packages/interactive_media_ads/test/ad_display_container_test.dart +++ b/packages/interactive_media_ads/test/ad_display_container_test.dart @@ -45,6 +45,8 @@ void main() { PlatformAdsManagerDelegateCreationParams params, ) { throw UnimplementedError(); + }, onCreatePlatformContentProgressProvider: (_) { + throw UnimplementedError(); }); final AdDisplayContainer adDisplayContainer = AdDisplayContainer( diff --git a/packages/interactive_media_ads/test/ads_loader_test.dart b/packages/interactive_media_ads/test/ads_loader_test.dart index 424c86ccc1d5..c571830fc4f3 100644 --- a/packages/interactive_media_ads/test/ads_loader_test.dart +++ b/packages/interactive_media_ads/test/ads_loader_test.dart @@ -18,7 +18,7 @@ void main() { onAdsLoadError: (AdsLoadErrorData data) {}, ), onContentComplete: expectAsync0(() async {}), - onRequestAds: (AdsRequest request) async {}, + onRequestAds: (PlatformAdsRequest request) async {}, ); final AdsLoader loader = AdsLoader.fromPlatform(adsLoader); @@ -26,18 +26,27 @@ void main() { }); test('requestAds', () async { + final PlatformAdsRequest platformRequest = PlatformAdsRequest( + adTagUrl: 'adTagUrl', + contentProgressProvider: TestContentProgressProvider( + const PlatformContentProgressProviderCreationParams(), + ), + ); + final TestPlatformAdsLoader adsLoader = TestPlatformAdsLoader( PlatformAdsLoaderCreationParams( container: createTestAdDisplayContainer(), onAdsLoaded: (PlatformOnAdsLoadedData data) {}, onAdsLoadError: (AdsLoadErrorData data) {}, ), - onRequestAds: expectAsync1((AdsRequest request) async {}), + onRequestAds: expectAsync1((PlatformAdsRequest request) async { + expect(request, platformRequest); + }), onContentComplete: () async {}, ); final AdsLoader loader = AdsLoader.fromPlatform(adsLoader); - await loader.requestAds(AdsRequest(adTagUrl: '')); + await loader.requestAds(AdsRequest.fromPlatform(platformRequest)); }); } diff --git a/packages/interactive_media_ads/test/ads_manager_delegate_test.dart b/packages/interactive_media_ads/test/ads_manager_delegate_test.dart index ba6801dc41f3..a0d519864c43 100644 --- a/packages/interactive_media_ads/test/ads_manager_delegate_test.dart +++ b/packages/interactive_media_ads/test/ads_manager_delegate_test.dart @@ -22,6 +22,8 @@ void main() { (PlatformAdDisplayContainerCreationParams params) { throw UnimplementedError(); }, + onCreatePlatformContentProgressProvider: (_) => + throw UnimplementedError(), ); void onAdEvent(AdEvent event) {} diff --git a/packages/interactive_media_ads/test/ads_manager_test.dart b/packages/interactive_media_ads/test/ads_manager_test.dart index cb5f42ccb3f6..f27f37aa82c1 100644 --- a/packages/interactive_media_ads/test/ads_manager_test.dart +++ b/packages/interactive_media_ads/test/ads_manager_test.dart @@ -41,6 +41,42 @@ void main() { )); }); + test('discardAdBreak', () async { + final TestAdsManager platformManager = TestAdsManager( + onDiscardAdBreak: expectAsync0(() async {}), + ); + + final AdsManager manager = createAdsManager(platformManager); + await manager.discardAdBreak(); + }); + + test('pause', () async { + final TestAdsManager platformManager = TestAdsManager( + onPause: expectAsync0(() async {}), + ); + + final AdsManager manager = createAdsManager(platformManager); + await manager.pause(); + }); + + test('resume', () async { + final TestAdsManager platformManager = TestAdsManager( + onResume: expectAsync0(() async {}), + ); + + final AdsManager manager = createAdsManager(platformManager); + await manager.resume(); + }); + + test('skip', () async { + final TestAdsManager platformManager = TestAdsManager( + onSkip: expectAsync0(() async {}), + ); + + final AdsManager manager = createAdsManager(platformManager); + await manager.skip(); + }); + test('destroy', () async { final TestAdsManager platformManager = TestAdsManager( onDestroy: expectAsync0(() async {}), @@ -56,7 +92,7 @@ AdsManager createAdsManager(PlatformAdsManager platformManager) { onCreatePlatformAdsLoader: (PlatformAdsLoaderCreationParams params) { return TestPlatformAdsLoader(params, onContentComplete: () async {}, - onRequestAds: (AdsRequest request) async {}); + onRequestAds: (PlatformAdsRequest request) async {}); }, onCreatePlatformAdsManagerDelegate: (PlatformAdsManagerDelegateCreationParams params) { @@ -66,6 +102,7 @@ AdsManager createAdsManager(PlatformAdsManager platformManager) { (PlatformAdDisplayContainerCreationParams params) { throw UnimplementedError(); }, + onCreatePlatformContentProgressProvider: (_) => throw UnimplementedError(), ); late final AdsManager manager; diff --git a/packages/interactive_media_ads/test/android/ad_display_container_test.dart b/packages/interactive_media_ads/test/android/ad_display_container_test.dart new file mode 100644 index 000000000000..5578c338986a --- /dev/null +++ b/packages/interactive_media_ads/test/android/ad_display_container_test.dart @@ -0,0 +1,685 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:interactive_media_ads/src/android/android_ad_display_container.dart'; +import 'package:interactive_media_ads/src/android/interactive_media_ads.g.dart' + as ima; +import 'package:interactive_media_ads/src/android/interactive_media_ads_proxy.dart'; +import 'package:interactive_media_ads/src/android/platform_views_service_proxy.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; + +import 'ad_display_container_test.mocks.dart'; + +@GenerateNiceMocks(>[ + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), +]) +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group('AndroidAdDisplayContainer', () { + testWidgets('build with key', (WidgetTester tester) async { + final AndroidAdDisplayContainer container = AndroidAdDisplayContainer( + AndroidAdDisplayContainerCreationParams( + key: const Key('testKey'), + onContainerAdded: (_) {}, + ), + ); + + await tester.pumpWidget(Builder( + builder: (BuildContext context) => container.build(context), + )); + + expect(find.byType(PlatformViewLink), findsOneWidget); + expect(find.byKey(const Key('testKey')), findsOneWidget); + }); + + testWidgets('onContainerAdded is called', (WidgetTester tester) async { + final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( + newFrameLayout: () => MockFrameLayout(), + newVideoView: ({ + required dynamic onError, + dynamic onPrepared, + dynamic onCompletion, + }) => + MockVideoView(), + createAdDisplayContainerImaSdkFactory: ( + _, + __, + ) async { + return MockAdDisplayContainer(); + }, + newVideoAdPlayer: ({ + required dynamic addCallback, + required dynamic loadAd, + required dynamic pauseAd, + required dynamic playAd, + required dynamic release, + required dynamic removeCallback, + required dynamic stopAd, + }) => + MockVideoAdPlayer(), + ); + + final MockPlatformViewsServiceProxy mockPlatformViewsProxy = + MockPlatformViewsServiceProxy(); + final MockSurfaceAndroidViewController mockAndroidViewController = + MockSurfaceAndroidViewController(); + + late final int platformViewId; + when( + mockPlatformViewsProxy.initSurfaceAndroidView( + id: anyNamed('id'), + viewType: anyNamed('viewType'), + layoutDirection: anyNamed('layoutDirection'), + creationParams: anyNamed('creationParams'), + creationParamsCodec: anyNamed('creationParamsCodec'), + onFocus: anyNamed('onFocus'), + ), + ).thenAnswer((Invocation invocation) { + platformViewId = invocation.namedArguments[const Symbol('id')] as int; + return mockAndroidViewController; + }); + + final AndroidAdDisplayContainer container = AndroidAdDisplayContainer( + AndroidAdDisplayContainerCreationParams( + onContainerAdded: expectAsync1((_) {}), + platformViewsProxy: mockPlatformViewsProxy, + imaProxy: imaProxy, + ), + ); + + await tester.pumpWidget(Builder( + builder: (BuildContext context) => container.build(context), + )); + + final void Function(int) onPlatformCreatedCallback = verify( + mockAndroidViewController + .addOnPlatformViewCreatedListener(captureAny)) + .captured[0] as void Function(int); + + onPlatformCreatedCallback(platformViewId); + + await tester.pumpAndSettle(); + }); + + test('completing the ad notifies IMA SDK the ad has ended', () { + late final void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ima.AdPodInfo, + ) loadAdCallback; + + late final void Function( + ima.VideoAdPlayer, + ima.VideoAdPlayerCallback, + ) addCallbackCallback; + + late final void Function( + ima.VideoView, + ima.MediaPlayer, + ) onCompletionCallback; + + final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( + newFrameLayout: () => MockFrameLayout(), + newVideoView: ({ + required dynamic onError, + dynamic onPrepared, + void Function( + ima.VideoView, + ima.MediaPlayer, + )? onCompletion, + }) { + onCompletionCallback = onCompletion!; + return MockVideoView(); + }, + createAdDisplayContainerImaSdkFactory: ( + _, + __, + ) async { + return MockAdDisplayContainer(); + }, + newVideoAdPlayer: ({ + required void Function( + ima.VideoAdPlayer, + ima.VideoAdPlayerCallback, + ) addCallback, + required void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ima.AdPodInfo, + ) loadAd, + required dynamic pauseAd, + required dynamic playAd, + required dynamic release, + required dynamic removeCallback, + required dynamic stopAd, + }) { + loadAdCallback = loadAd; + addCallbackCallback = addCallback; + return MockVideoAdPlayer(); + }, + ); + + AndroidAdDisplayContainer( + AndroidAdDisplayContainerCreationParams( + onContainerAdded: (_) {}, + imaProxy: imaProxy, + ), + ); + + final ima.AdMediaInfo mockAdMediaInfo = MockAdMediaInfo(); + loadAdCallback(MockVideoAdPlayer(), mockAdMediaInfo, MockAdPodInfo()); + + final MockVideoAdPlayerCallback mockPlayerCallback = + MockVideoAdPlayerCallback(); + addCallbackCallback(MockVideoAdPlayer(), mockPlayerCallback); + + onCompletionCallback(MockVideoView(), MockMediaPlayer()); + + verify(mockPlayerCallback.onEnded(mockAdMediaInfo)); + }); + + test('error loading the ad notifies IMA SDK of error', () { + late final void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ima.AdPodInfo, + ) loadAdCallback; + + late final void Function( + ima.VideoAdPlayer, + ima.VideoAdPlayerCallback, + ) addCallbackCallback; + + late final void Function( + ima.VideoView, + ima.MediaPlayer, + int, + int, + ) onErrorCallback; + + final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( + newFrameLayout: () => MockFrameLayout(), + newVideoView: ({ + required void Function( + ima.VideoView, + ima.MediaPlayer, + int, + int, + ) onError, + dynamic onPrepared, + dynamic onCompletion, + }) { + onErrorCallback = onError; + return MockVideoView(); + }, + createAdDisplayContainerImaSdkFactory: ( + _, + __, + ) async { + return MockAdDisplayContainer(); + }, + newVideoAdPlayer: ({ + required void Function( + ima.VideoAdPlayer, + ima.VideoAdPlayerCallback, + ) addCallback, + required void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ima.AdPodInfo, + ) loadAd, + required dynamic pauseAd, + required dynamic playAd, + required dynamic release, + required dynamic removeCallback, + required dynamic stopAd, + }) { + loadAdCallback = loadAd; + addCallbackCallback = addCallback; + return MockVideoAdPlayer(); + }, + ); + + AndroidAdDisplayContainer( + AndroidAdDisplayContainerCreationParams( + onContainerAdded: (_) {}, + imaProxy: imaProxy, + ), + ); + + final ima.AdMediaInfo mockAdMediaInfo = MockAdMediaInfo(); + loadAdCallback(MockVideoAdPlayer(), mockAdMediaInfo, MockAdPodInfo()); + + final MockVideoAdPlayerCallback mockPlayerCallback = + MockVideoAdPlayerCallback(); + addCallbackCallback(MockVideoAdPlayer(), mockPlayerCallback); + + onErrorCallback(MockVideoView(), MockMediaPlayer(), 0, 0); + + verify(mockPlayerCallback.onError(mockAdMediaInfo)); + }); + + test('play ad once when it is prepared', () async { + late final void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ima.AdPodInfo, + ) loadAdCallback; + + late final void Function( + ima.VideoAdPlayer, + ima.VideoAdPlayerCallback, + ) addCallbackCallback; + + late final Future Function( + ima.VideoView, + ima.MediaPlayer, + ) onPreparedCallback; + + const int adDuration = 100; + const int adProgress = 10; + + final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( + newFrameLayout: () => MockFrameLayout(), + newVideoView: ({ + dynamic onError, + dynamic onPrepared, + dynamic onCompletion, + }) { + // VideoView.onPrepared returns void, but the implementation uses an + // async callback method. + onPreparedCallback = onPrepared! as Future Function( + ima.VideoView, + ima.MediaPlayer, + ); + final MockVideoView mockVideoView = MockVideoView(); + when(mockVideoView.getCurrentPosition()).thenAnswer( + (_) async => adProgress, + ); + return mockVideoView; + }, + createAdDisplayContainerImaSdkFactory: (_, __) async { + return MockAdDisplayContainer(); + }, + newVideoAdPlayer: ({ + required void Function( + ima.VideoAdPlayer, + ima.VideoAdPlayerCallback, + ) addCallback, + required void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ima.AdPodInfo, + ) loadAd, + required dynamic pauseAd, + required dynamic playAd, + required dynamic release, + required dynamic removeCallback, + required dynamic stopAd, + }) { + loadAdCallback = loadAd; + addCallbackCallback = addCallback; + return MockVideoAdPlayer(); + }, + newVideoProgressUpdate: ({ + required int currentTimeMs, + required int durationMs, + }) { + expect(currentTimeMs, adProgress); + expect(durationMs, adDuration); + return MockVideoProgressUpdate(); + }, + ); + + AndroidAdDisplayContainer( + AndroidAdDisplayContainerCreationParams( + onContainerAdded: (_) {}, + imaProxy: imaProxy, + ), + ); + + final ima.AdMediaInfo mockAdMediaInfo = MockAdMediaInfo(); + loadAdCallback(MockVideoAdPlayer(), mockAdMediaInfo, MockAdPodInfo()); + + final MockVideoAdPlayerCallback mockPlayerCallback = + MockVideoAdPlayerCallback(); + addCallbackCallback(MockVideoAdPlayer(), mockPlayerCallback); + + final MockMediaPlayer mockMediaPlayer = MockMediaPlayer(); + when(mockMediaPlayer.getDuration()).thenAnswer((_) async => adDuration); + + await onPreparedCallback(MockVideoView(), mockMediaPlayer); + + verify(mockMediaPlayer.start()); + + // Ad progress is updated with a reoccurring timer, so this waits for + // at least one update. + await Future.delayed(const Duration(milliseconds: 300)); + verify(mockPlayerCallback.onAdProgress(mockAdMediaInfo, any)); + }); + + test('pause ad', () async { + late final void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ima.AdPodInfo, + ) loadAdCallback; + + late final Future Function( + ima.VideoView, + ima.MediaPlayer, + ) onPreparedCallback; + + late final Future Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ) pauseAdCallback; + + final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( + newFrameLayout: () => MockFrameLayout(), + newVideoView: ({ + dynamic onError, + void Function( + ima.VideoView, + ima.MediaPlayer, + )? onPrepared, + dynamic onCompletion, + }) { + // VideoView.onPrepared returns void, but the implementation uses an + // async callback method. + onPreparedCallback = onPrepared! as Future Function( + ima.VideoView, + ima.MediaPlayer, + ); + final MockVideoView mockVideoView = MockVideoView(); + when(mockVideoView.getCurrentPosition()).thenAnswer((_) async => 10); + return mockVideoView; + }, + createAdDisplayContainerImaSdkFactory: (_, __) async { + return MockAdDisplayContainer(); + }, + newVideoAdPlayer: ({ + required dynamic addCallback, + required void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ima.AdPodInfo, + ) loadAd, + required dynamic pauseAd, + required dynamic playAd, + required dynamic release, + required dynamic removeCallback, + required dynamic stopAd, + }) { + loadAdCallback = loadAd; + // VideoAdPlayer.pauseAd returns void, but the implementation uses an + // async callback method. + pauseAdCallback = pauseAd as Future Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ); + return MockVideoAdPlayer(); + }, + newVideoProgressUpdate: ({ + required int currentTimeMs, + required int durationMs, + }) { + return MockVideoProgressUpdate(); + }, + ); + + AndroidAdDisplayContainer( + AndroidAdDisplayContainerCreationParams( + onContainerAdded: (_) {}, + imaProxy: imaProxy, + ), + ); + + final ima.AdMediaInfo mockAdMediaInfo = MockAdMediaInfo(); + loadAdCallback(MockVideoAdPlayer(), mockAdMediaInfo, MockAdPodInfo()); + + final MockMediaPlayer mockMediaPlayer = MockMediaPlayer(); + when(mockMediaPlayer.getDuration()).thenAnswer((_) async => 100); + + await onPreparedCallback(MockVideoView(), mockMediaPlayer); + + await pauseAdCallback(MockVideoAdPlayer(), mockAdMediaInfo); + + verify(mockMediaPlayer.pause()); + }); + + test('ad does not play automatically after calling pause', () async { + late final void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ima.AdPodInfo, + ) loadAdCallback; + + late final Future Function( + ima.VideoView, + ima.MediaPlayer, + ) onPreparedCallback; + + late final Future Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ) pauseAdCallback; + + late final void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ) playAdCallback; + + final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( + newFrameLayout: () => MockFrameLayout(), + newVideoView: ({ + dynamic onError, + void Function( + ima.VideoView, + ima.MediaPlayer, + )? onPrepared, + dynamic onCompletion, + }) { + // VideoView.onPrepared returns void, but the implementation uses an + // async callback method. + onPreparedCallback = onPrepared! as Future Function( + ima.VideoView, + ima.MediaPlayer, + ); + final MockVideoView mockVideoView = MockVideoView(); + when(mockVideoView.getCurrentPosition()).thenAnswer((_) async => 10); + return mockVideoView; + }, + createAdDisplayContainerImaSdkFactory: (_, __) async { + return MockAdDisplayContainer(); + }, + newVideoAdPlayer: ({ + required dynamic addCallback, + required void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ima.AdPodInfo, + ) loadAd, + required dynamic pauseAd, + required void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ) playAd, + required dynamic release, + required dynamic removeCallback, + required dynamic stopAd, + }) { + loadAdCallback = loadAd; + // VideoAdPlayer.pauseAd returns void, but the implementation uses an + // async callback method. + pauseAdCallback = pauseAd as Future Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ); + playAdCallback = playAd; + return MockVideoAdPlayer(); + }, + newVideoProgressUpdate: ({ + required int currentTimeMs, + required int durationMs, + }) { + return MockVideoProgressUpdate(); + }, + ); + + AndroidAdDisplayContainer( + AndroidAdDisplayContainerCreationParams( + onContainerAdded: (_) {}, + imaProxy: imaProxy, + ), + ); + + final ima.AdMediaInfo mockAdMediaInfo = MockAdMediaInfo(); + when(mockAdMediaInfo.url).thenReturn('url'); + loadAdCallback(MockVideoAdPlayer(), mockAdMediaInfo, MockAdPodInfo()); + + final MockMediaPlayer mockMediaPlayer = MockMediaPlayer(); + when(mockMediaPlayer.getDuration()).thenAnswer((_) async => 100); + + await onPreparedCallback(MockVideoView(), mockMediaPlayer); + + // Pausing the ad prevents Ad from starting again automatically when it is + // prepared. + await pauseAdCallback(MockVideoAdPlayer(), mockAdMediaInfo); + reset(mockMediaPlayer); + await onPreparedCallback(MockVideoView(), mockMediaPlayer); + verifyNever(mockMediaPlayer.start()); + + // The playAd callback allows the Ad to start automatically once it is + // prepared. + playAdCallback(MockVideoAdPlayer(), mockAdMediaInfo); + await onPreparedCallback(MockVideoView(), mockMediaPlayer); + verify(mockMediaPlayer.start()); + }); + + test('play ad', () async { + late final void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ) playAdCallback; + + final MockVideoView mockVideoView = MockVideoView(); + final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( + newFrameLayout: () => MockFrameLayout(), + newVideoView: ({ + dynamic onError, + dynamic onPrepared, + dynamic onCompletion, + }) { + return mockVideoView; + }, + createAdDisplayContainerImaSdkFactory: (_, __) async { + return MockAdDisplayContainer(); + }, + newVideoAdPlayer: ({ + required dynamic addCallback, + required dynamic loadAd, + required dynamic pauseAd, + required void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ) playAd, + required dynamic release, + required dynamic removeCallback, + required dynamic stopAd, + }) { + playAdCallback = playAd; + return MockVideoAdPlayer(); + }, + ); + + AndroidAdDisplayContainer( + AndroidAdDisplayContainerCreationParams( + onContainerAdded: (_) {}, + imaProxy: imaProxy, + ), + ); + + const String videoUrl = 'url'; + final ima.AdMediaInfo mockAdMediaInfo = MockAdMediaInfo(); + when(mockAdMediaInfo.url).thenReturn(videoUrl); + playAdCallback(MockVideoAdPlayer(), mockAdMediaInfo); + + verify(mockVideoView.setVideoUri(videoUrl)); + }); + + test('stop ad creates and sets a new VideoView', () async { + late final void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ) stopAdCallback; + + final MockFrameLayout mockFrameLayout = MockFrameLayout(); + late final MockVideoView mockVideoView = MockVideoView(); + late final MockVideoView mockVideoView2 = MockVideoView(); + int newViewVideoCallCount = 0; + final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( + newFrameLayout: () => mockFrameLayout, + newVideoView: ({ + dynamic onError, + dynamic onPrepared, + dynamic onCompletion, + }) { + switch (newViewVideoCallCount) { + case 0: + newViewVideoCallCount++; + return mockVideoView; + case 1: + newViewVideoCallCount++; + return mockVideoView2; + default: + fail('newVideoView was called too many times'); + } + }, + createAdDisplayContainerImaSdkFactory: (_, __) async { + return MockAdDisplayContainer(); + }, + newVideoAdPlayer: ({ + required dynamic addCallback, + required dynamic loadAd, + required dynamic pauseAd, + required dynamic playAd, + required dynamic release, + required dynamic removeCallback, + required void Function(ima.VideoAdPlayer, ima.AdMediaInfo) stopAd, + }) { + stopAdCallback = stopAd; + return MockVideoAdPlayer(); + }, + ); + + AndroidAdDisplayContainer( + AndroidAdDisplayContainerCreationParams( + onContainerAdded: (_) {}, + imaProxy: imaProxy, + ), + ); + + stopAdCallback(MockVideoAdPlayer(), MockAdMediaInfo()); + + verify(mockFrameLayout.removeView(mockVideoView)); + verify(mockFrameLayout.addView(mockVideoView2)); + }); + }); +} diff --git a/packages/interactive_media_ads/test/android/ad_display_container_test.mocks.dart b/packages/interactive_media_ads/test/android/ad_display_container_test.mocks.dart new file mode 100644 index 000000000000..adedc00cd18b --- /dev/null +++ b/packages/interactive_media_ads/test/android/ad_display_container_test.mocks.dart @@ -0,0 +1,1276 @@ +// Mocks generated by Mockito 5.4.4 from annotations +// in interactive_media_ads/test/android/ad_display_container_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i6; +import 'dart:ui' as _i3; + +import 'package:flutter/services.dart' as _i4; +import 'package:interactive_media_ads/src/android/interactive_media_ads.g.dart' + as _i2; +import 'package:interactive_media_ads/src/android/platform_views_service_proxy.dart' + as _i7; +import 'package:mockito/mockito.dart' as _i1; +import 'package:mockito/src/dummies.dart' as _i5; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakePigeonInstanceManager_0 extends _i1.SmartFake + implements _i2.PigeonInstanceManager { + _FakePigeonInstanceManager_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeAdDisplayContainer_1 extends _i1.SmartFake + implements _i2.AdDisplayContainer { + _FakeAdDisplayContainer_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeAdMediaInfo_2 extends _i1.SmartFake implements _i2.AdMediaInfo { + _FakeAdMediaInfo_2( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeAdPodInfo_3 extends _i1.SmartFake implements _i2.AdPodInfo { + _FakeAdPodInfo_3( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeFrameLayout_4 extends _i1.SmartFake implements _i2.FrameLayout { + _FakeFrameLayout_4( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeMediaPlayer_5 extends _i1.SmartFake implements _i2.MediaPlayer { + _FakeMediaPlayer_5( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeVideoAdPlayer_6 extends _i1.SmartFake implements _i2.VideoAdPlayer { + _FakeVideoAdPlayer_6( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeVideoAdPlayerCallback_7 extends _i1.SmartFake + implements _i2.VideoAdPlayerCallback { + _FakeVideoAdPlayerCallback_7( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeVideoProgressUpdate_8 extends _i1.SmartFake + implements _i2.VideoProgressUpdate { + _FakeVideoProgressUpdate_8( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeVideoView_9 extends _i1.SmartFake implements _i2.VideoView { + _FakeVideoView_9( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeOffset_10 extends _i1.SmartFake implements _i3.Offset { + _FakeOffset_10( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeSize_11 extends _i1.SmartFake implements _i3.Size { + _FakeSize_11( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeExpensiveAndroidViewController_12 extends _i1.SmartFake + implements _i4.ExpensiveAndroidViewController { + _FakeExpensiveAndroidViewController_12( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeSurfaceAndroidViewController_13 extends _i1.SmartFake + implements _i4.SurfaceAndroidViewController { + _FakeSurfaceAndroidViewController_13( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [AdDisplayContainer]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAdDisplayContainer extends _i1.Mock + implements _i2.AdDisplayContainer { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.AdDisplayContainer pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeAdDisplayContainer_1( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeAdDisplayContainer_1( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.AdDisplayContainer); +} + +/// A class which mocks [AdMediaInfo]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAdMediaInfo extends _i1.Mock implements _i2.AdMediaInfo { + @override + String get url => (super.noSuchMethod( + Invocation.getter(#url), + returnValue: _i5.dummyValue( + this, + Invocation.getter(#url), + ), + returnValueForMissingStub: _i5.dummyValue( + this, + Invocation.getter(#url), + ), + ) as String); + + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.AdMediaInfo pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeAdMediaInfo_2( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeAdMediaInfo_2( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.AdMediaInfo); +} + +/// A class which mocks [AdPodInfo]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAdPodInfo extends _i1.Mock implements _i2.AdPodInfo { + @override + int get adPosition => (super.noSuchMethod( + Invocation.getter(#adPosition), + returnValue: 0, + returnValueForMissingStub: 0, + ) as int); + + @override + double get maxDuration => (super.noSuchMethod( + Invocation.getter(#maxDuration), + returnValue: 0.0, + returnValueForMissingStub: 0.0, + ) as double); + + @override + int get podIndex => (super.noSuchMethod( + Invocation.getter(#podIndex), + returnValue: 0, + returnValueForMissingStub: 0, + ) as int); + + @override + double get timeOffset => (super.noSuchMethod( + Invocation.getter(#timeOffset), + returnValue: 0.0, + returnValueForMissingStub: 0.0, + ) as double); + + @override + int get totalAds => (super.noSuchMethod( + Invocation.getter(#totalAds), + returnValue: 0, + returnValueForMissingStub: 0, + ) as int); + + @override + bool get isBumper => (super.noSuchMethod( + Invocation.getter(#isBumper), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.AdPodInfo pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeAdPodInfo_3( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeAdPodInfo_3( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.AdPodInfo); +} + +/// A class which mocks [FrameLayout]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockFrameLayout extends _i1.Mock implements _i2.FrameLayout { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.FrameLayout pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeFrameLayout_4( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeFrameLayout_4( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.FrameLayout); + + @override + _i6.Future addView(_i2.View? view) => (super.noSuchMethod( + Invocation.method( + #addView, + [view], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future removeView(_i2.View? view) => (super.noSuchMethod( + Invocation.method( + #removeView, + [view], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); +} + +/// A class which mocks [MediaPlayer]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockMediaPlayer extends _i1.Mock implements _i2.MediaPlayer { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i6.Future getDuration() => (super.noSuchMethod( + Invocation.method( + #getDuration, + [], + ), + returnValue: _i6.Future.value(0), + returnValueForMissingStub: _i6.Future.value(0), + ) as _i6.Future); + + @override + _i6.Future seekTo(int? mSec) => (super.noSuchMethod( + Invocation.method( + #seekTo, + [mSec], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future start() => (super.noSuchMethod( + Invocation.method( + #start, + [], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future pause() => (super.noSuchMethod( + Invocation.method( + #pause, + [], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future stop() => (super.noSuchMethod( + Invocation.method( + #stop, + [], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i2.MediaPlayer pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeMediaPlayer_5( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeMediaPlayer_5( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.MediaPlayer); +} + +/// A class which mocks [VideoAdPlayer]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockVideoAdPlayer extends _i1.Mock implements _i2.VideoAdPlayer { + @override + void Function( + _i2.VideoAdPlayer, + _i2.VideoAdPlayerCallback, + ) get addCallback => (super.noSuchMethod( + Invocation.getter(#addCallback), + returnValue: ( + _i2.VideoAdPlayer pigeon_instance, + _i2.VideoAdPlayerCallback callback, + ) {}, + returnValueForMissingStub: ( + _i2.VideoAdPlayer pigeon_instance, + _i2.VideoAdPlayerCallback callback, + ) {}, + ) as void Function( + _i2.VideoAdPlayer, + _i2.VideoAdPlayerCallback, + )); + + @override + void Function( + _i2.VideoAdPlayer, + _i2.AdMediaInfo, + _i2.AdPodInfo, + ) get loadAd => (super.noSuchMethod( + Invocation.getter(#loadAd), + returnValue: ( + _i2.VideoAdPlayer pigeon_instance, + _i2.AdMediaInfo adMediaInfo, + _i2.AdPodInfo adPodInfo, + ) {}, + returnValueForMissingStub: ( + _i2.VideoAdPlayer pigeon_instance, + _i2.AdMediaInfo adMediaInfo, + _i2.AdPodInfo adPodInfo, + ) {}, + ) as void Function( + _i2.VideoAdPlayer, + _i2.AdMediaInfo, + _i2.AdPodInfo, + )); + + @override + void Function( + _i2.VideoAdPlayer, + _i2.AdMediaInfo, + ) get pauseAd => (super.noSuchMethod( + Invocation.getter(#pauseAd), + returnValue: ( + _i2.VideoAdPlayer pigeon_instance, + _i2.AdMediaInfo adMediaInfo, + ) {}, + returnValueForMissingStub: ( + _i2.VideoAdPlayer pigeon_instance, + _i2.AdMediaInfo adMediaInfo, + ) {}, + ) as void Function( + _i2.VideoAdPlayer, + _i2.AdMediaInfo, + )); + + @override + void Function( + _i2.VideoAdPlayer, + _i2.AdMediaInfo, + ) get playAd => (super.noSuchMethod( + Invocation.getter(#playAd), + returnValue: ( + _i2.VideoAdPlayer pigeon_instance, + _i2.AdMediaInfo adMediaInfo, + ) {}, + returnValueForMissingStub: ( + _i2.VideoAdPlayer pigeon_instance, + _i2.AdMediaInfo adMediaInfo, + ) {}, + ) as void Function( + _i2.VideoAdPlayer, + _i2.AdMediaInfo, + )); + + @override + void Function(_i2.VideoAdPlayer) get release => (super.noSuchMethod( + Invocation.getter(#release), + returnValue: (_i2.VideoAdPlayer pigeon_instance) {}, + returnValueForMissingStub: (_i2.VideoAdPlayer pigeon_instance) {}, + ) as void Function(_i2.VideoAdPlayer)); + + @override + void Function( + _i2.VideoAdPlayer, + _i2.VideoAdPlayerCallback, + ) get removeCallback => (super.noSuchMethod( + Invocation.getter(#removeCallback), + returnValue: ( + _i2.VideoAdPlayer pigeon_instance, + _i2.VideoAdPlayerCallback callback, + ) {}, + returnValueForMissingStub: ( + _i2.VideoAdPlayer pigeon_instance, + _i2.VideoAdPlayerCallback callback, + ) {}, + ) as void Function( + _i2.VideoAdPlayer, + _i2.VideoAdPlayerCallback, + )); + + @override + void Function( + _i2.VideoAdPlayer, + _i2.AdMediaInfo, + ) get stopAd => (super.noSuchMethod( + Invocation.getter(#stopAd), + returnValue: ( + _i2.VideoAdPlayer pigeon_instance, + _i2.AdMediaInfo adMediaInfo, + ) {}, + returnValueForMissingStub: ( + _i2.VideoAdPlayer pigeon_instance, + _i2.AdMediaInfo adMediaInfo, + ) {}, + ) as void Function( + _i2.VideoAdPlayer, + _i2.AdMediaInfo, + )); + + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i6.Future setVolume(int? value) => (super.noSuchMethod( + Invocation.method( + #setVolume, + [value], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future setAdProgress(_i2.VideoProgressUpdate? progress) => + (super.noSuchMethod( + Invocation.method( + #setAdProgress, + [progress], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i2.VideoAdPlayer pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeVideoAdPlayer_6( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeVideoAdPlayer_6( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.VideoAdPlayer); +} + +/// A class which mocks [VideoAdPlayerCallback]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockVideoAdPlayerCallback extends _i1.Mock + implements _i2.VideoAdPlayerCallback { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i6.Future onAdProgress( + _i2.AdMediaInfo? adMediaInfo, + _i2.VideoProgressUpdate? videoProgressUpdate, + ) => + (super.noSuchMethod( + Invocation.method( + #onAdProgress, + [ + adMediaInfo, + videoProgressUpdate, + ], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future onBuffering(_i2.AdMediaInfo? adMediaInfo) => + (super.noSuchMethod( + Invocation.method( + #onBuffering, + [adMediaInfo], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future onContentComplete() => (super.noSuchMethod( + Invocation.method( + #onContentComplete, + [], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future onEnded(_i2.AdMediaInfo? adMediaInfo) => (super.noSuchMethod( + Invocation.method( + #onEnded, + [adMediaInfo], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future onError(_i2.AdMediaInfo? adMediaInfo) => (super.noSuchMethod( + Invocation.method( + #onError, + [adMediaInfo], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future onLoaded(_i2.AdMediaInfo? adMediaInfo) => + (super.noSuchMethod( + Invocation.method( + #onLoaded, + [adMediaInfo], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future onPause(_i2.AdMediaInfo? adMediaInfo) => (super.noSuchMethod( + Invocation.method( + #onPause, + [adMediaInfo], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future onPlay(_i2.AdMediaInfo? adMediaInfo) => (super.noSuchMethod( + Invocation.method( + #onPlay, + [adMediaInfo], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future onResume(_i2.AdMediaInfo? adMediaInfo) => + (super.noSuchMethod( + Invocation.method( + #onResume, + [adMediaInfo], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future onVolumeChanged( + _i2.AdMediaInfo? adMediaInfo, + int? percentage, + ) => + (super.noSuchMethod( + Invocation.method( + #onVolumeChanged, + [ + adMediaInfo, + percentage, + ], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i2.VideoAdPlayerCallback pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeVideoAdPlayerCallback_7( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeVideoAdPlayerCallback_7( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.VideoAdPlayerCallback); +} + +/// A class which mocks [VideoProgressUpdate]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockVideoProgressUpdate extends _i1.Mock + implements _i2.VideoProgressUpdate { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.VideoProgressUpdate pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeVideoProgressUpdate_8( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeVideoProgressUpdate_8( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.VideoProgressUpdate); +} + +/// A class which mocks [VideoView]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockVideoView extends _i1.Mock implements _i2.VideoView { + @override + void Function( + _i2.VideoView, + _i2.MediaPlayer, + int, + int, + ) get onError => (super.noSuchMethod( + Invocation.getter(#onError), + returnValue: ( + _i2.VideoView pigeon_instance, + _i2.MediaPlayer player, + int what, + int extra, + ) {}, + returnValueForMissingStub: ( + _i2.VideoView pigeon_instance, + _i2.MediaPlayer player, + int what, + int extra, + ) {}, + ) as void Function( + _i2.VideoView, + _i2.MediaPlayer, + int, + int, + )); + + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i6.Future setVideoUri(String? uri) => (super.noSuchMethod( + Invocation.method( + #setVideoUri, + [uri], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future getCurrentPosition() => (super.noSuchMethod( + Invocation.method( + #getCurrentPosition, + [], + ), + returnValue: _i6.Future.value(0), + returnValueForMissingStub: _i6.Future.value(0), + ) as _i6.Future); + + @override + _i2.VideoView pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeVideoView_9( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeVideoView_9( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.VideoView); +} + +/// A class which mocks [SurfaceAndroidViewController]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockSurfaceAndroidViewController extends _i1.Mock + implements _i4.SurfaceAndroidViewController { + @override + bool get requiresViewComposition => (super.noSuchMethod( + Invocation.getter(#requiresViewComposition), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + int get viewId => (super.noSuchMethod( + Invocation.getter(#viewId), + returnValue: 0, + returnValueForMissingStub: 0, + ) as int); + + @override + bool get awaitingCreation => (super.noSuchMethod( + Invocation.getter(#awaitingCreation), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + _i4.PointTransformer get pointTransformer => (super.noSuchMethod( + Invocation.getter(#pointTransformer), + returnValue: (_i3.Offset position) => _FakeOffset_10( + this, + Invocation.getter(#pointTransformer), + ), + returnValueForMissingStub: (_i3.Offset position) => _FakeOffset_10( + this, + Invocation.getter(#pointTransformer), + ), + ) as _i4.PointTransformer); + + @override + set pointTransformer(_i4.PointTransformer? transformer) => super.noSuchMethod( + Invocation.setter( + #pointTransformer, + transformer, + ), + returnValueForMissingStub: null, + ); + + @override + bool get isCreated => (super.noSuchMethod( + Invocation.getter(#isCreated), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + List<_i4.PlatformViewCreatedCallback> get createdCallbacks => + (super.noSuchMethod( + Invocation.getter(#createdCallbacks), + returnValue: <_i4.PlatformViewCreatedCallback>[], + returnValueForMissingStub: <_i4.PlatformViewCreatedCallback>[], + ) as List<_i4.PlatformViewCreatedCallback>); + + @override + _i6.Future setOffset(_i3.Offset? off) => (super.noSuchMethod( + Invocation.method( + #setOffset, + [off], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future create({ + _i3.Size? size, + _i3.Offset? position, + }) => + (super.noSuchMethod( + Invocation.method( + #create, + [], + { + #size: size, + #position: position, + }, + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future<_i3.Size> setSize(_i3.Size? size) => (super.noSuchMethod( + Invocation.method( + #setSize, + [size], + ), + returnValue: _i6.Future<_i3.Size>.value(_FakeSize_11( + this, + Invocation.method( + #setSize, + [size], + ), + )), + returnValueForMissingStub: _i6.Future<_i3.Size>.value(_FakeSize_11( + this, + Invocation.method( + #setSize, + [size], + ), + )), + ) as _i6.Future<_i3.Size>); + + @override + _i6.Future sendMotionEvent(_i4.AndroidMotionEvent? event) => + (super.noSuchMethod( + Invocation.method( + #sendMotionEvent, + [event], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + void addOnPlatformViewCreatedListener( + _i4.PlatformViewCreatedCallback? listener) => + super.noSuchMethod( + Invocation.method( + #addOnPlatformViewCreatedListener, + [listener], + ), + returnValueForMissingStub: null, + ); + + @override + void removeOnPlatformViewCreatedListener( + _i4.PlatformViewCreatedCallback? listener) => + super.noSuchMethod( + Invocation.method( + #removeOnPlatformViewCreatedListener, + [listener], + ), + returnValueForMissingStub: null, + ); + + @override + _i6.Future setLayoutDirection(_i3.TextDirection? layoutDirection) => + (super.noSuchMethod( + Invocation.method( + #setLayoutDirection, + [layoutDirection], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future dispatchPointerEvent(_i4.PointerEvent? event) => + (super.noSuchMethod( + Invocation.method( + #dispatchPointerEvent, + [event], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future clearFocus() => (super.noSuchMethod( + Invocation.method( + #clearFocus, + [], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future dispose() => (super.noSuchMethod( + Invocation.method( + #dispose, + [], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); +} + +/// A class which mocks [PlatformViewsServiceProxy]. +/// +/// See the documentation for Mockito's code generation for more information. +// ignore: must_be_immutable +class MockPlatformViewsServiceProxy extends _i1.Mock + implements _i7.PlatformViewsServiceProxy { + @override + _i4.ExpensiveAndroidViewController initExpensiveAndroidView({ + required int? id, + required String? viewType, + required _i3.TextDirection? layoutDirection, + dynamic creationParams, + _i4.MessageCodec? creationParamsCodec, + _i3.VoidCallback? onFocus, + }) => + (super.noSuchMethod( + Invocation.method( + #initExpensiveAndroidView, + [], + { + #id: id, + #viewType: viewType, + #layoutDirection: layoutDirection, + #creationParams: creationParams, + #creationParamsCodec: creationParamsCodec, + #onFocus: onFocus, + }, + ), + returnValue: _FakeExpensiveAndroidViewController_12( + this, + Invocation.method( + #initExpensiveAndroidView, + [], + { + #id: id, + #viewType: viewType, + #layoutDirection: layoutDirection, + #creationParams: creationParams, + #creationParamsCodec: creationParamsCodec, + #onFocus: onFocus, + }, + ), + ), + returnValueForMissingStub: _FakeExpensiveAndroidViewController_12( + this, + Invocation.method( + #initExpensiveAndroidView, + [], + { + #id: id, + #viewType: viewType, + #layoutDirection: layoutDirection, + #creationParams: creationParams, + #creationParamsCodec: creationParamsCodec, + #onFocus: onFocus, + }, + ), + ), + ) as _i4.ExpensiveAndroidViewController); + + @override + _i4.SurfaceAndroidViewController initSurfaceAndroidView({ + required int? id, + required String? viewType, + required _i3.TextDirection? layoutDirection, + dynamic creationParams, + _i4.MessageCodec? creationParamsCodec, + _i3.VoidCallback? onFocus, + }) => + (super.noSuchMethod( + Invocation.method( + #initSurfaceAndroidView, + [], + { + #id: id, + #viewType: viewType, + #layoutDirection: layoutDirection, + #creationParams: creationParams, + #creationParamsCodec: creationParamsCodec, + #onFocus: onFocus, + }, + ), + returnValue: _FakeSurfaceAndroidViewController_13( + this, + Invocation.method( + #initSurfaceAndroidView, + [], + { + #id: id, + #viewType: viewType, + #layoutDirection: layoutDirection, + #creationParams: creationParams, + #creationParamsCodec: creationParamsCodec, + #onFocus: onFocus, + }, + ), + ), + returnValueForMissingStub: _FakeSurfaceAndroidViewController_13( + this, + Invocation.method( + #initSurfaceAndroidView, + [], + { + #id: id, + #viewType: viewType, + #layoutDirection: layoutDirection, + #creationParams: creationParams, + #creationParamsCodec: creationParamsCodec, + #onFocus: onFocus, + }, + ), + ), + ) as _i4.SurfaceAndroidViewController); +} diff --git a/packages/interactive_media_ads/test/android/ads_loader_test.dart b/packages/interactive_media_ads/test/android/ads_loader_test.dart new file mode 100644 index 000000000000..ae25fdde99f9 --- /dev/null +++ b/packages/interactive_media_ads/test/android/ads_loader_test.dart @@ -0,0 +1,337 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:interactive_media_ads/src/android/android_ad_display_container.dart'; +import 'package:interactive_media_ads/src/android/android_ads_loader.dart'; +import 'package:interactive_media_ads/src/android/android_content_progress_provider.dart'; +import 'package:interactive_media_ads/src/android/interactive_media_ads.g.dart' + as ima; +import 'package:interactive_media_ads/src/android/interactive_media_ads_proxy.dart'; +import 'package:interactive_media_ads/src/android/platform_views_service_proxy.dart'; +import 'package:interactive_media_ads/src/platform_interface/platform_interface.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; + +import 'ads_loader_test.mocks.dart'; + +@GenerateNiceMocks(>[ + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), +]) +void main() { + group('AndroidAdsLoader', () { + testWidgets('instantiate AndroidAdsLoader', (WidgetTester tester) async { + final AndroidAdDisplayContainer container = + await _pumpAdDisplayContainer(tester); + + AndroidAdsLoader( + AndroidAdsLoaderCreationParams( + container: container, + onAdsLoaded: (PlatformOnAdsLoadedData data) {}, + onAdsLoadError: (AdsLoadErrorData data) {}, + ), + ); + }); + + testWidgets('contentComplete', (WidgetTester tester) async { + final MockVideoAdPlayerCallback mockAdPlayerCallback = + MockVideoAdPlayerCallback(); + final AndroidAdDisplayContainer container = await _pumpAdDisplayContainer( + tester, + mockAdPlayerCallback: mockAdPlayerCallback, + ); + + final AndroidAdsLoader loader = AndroidAdsLoader( + AndroidAdsLoaderCreationParams( + container: container, + onAdsLoaded: (PlatformOnAdsLoadedData data) {}, + onAdsLoadError: (AdsLoadErrorData data) {}, + ), + ); + + await loader.contentComplete(); + verify(mockAdPlayerCallback.onContentComplete()); + }); + + testWidgets('requestAds', (WidgetTester tester) async { + final AndroidAdDisplayContainer container = + await _pumpAdDisplayContainer(tester); + + final MockImaSdkFactory mockSdkFactory = MockImaSdkFactory(); + when(mockSdkFactory.createImaSdkSettings()).thenAnswer((_) async { + return MockImaSdkSettings(); + }); + + final MockAdsLoader mockAdsLoader = MockAdsLoader(); + when(mockSdkFactory.createAdsLoader(any, any)).thenAnswer((_) async { + return mockAdsLoader; + }); + + final MockAdsRequest mockAdsRequest = MockAdsRequest(); + when(mockSdkFactory.createAdsRequest()).thenAnswer((_) async { + return mockAdsRequest; + }); + + final InteractiveMediaAdsProxy proxy = InteractiveMediaAdsProxy( + instanceImaSdkFactory: () => mockSdkFactory, + newContentProgressProvider: () => + ima.ContentProgressProvider.pigeon_detached(), + ); + + final AndroidAdsLoader adsLoader = AndroidAdsLoader( + AndroidAdsLoaderCreationParams( + container: container, + onAdsLoaded: (PlatformOnAdsLoadedData data) {}, + onAdsLoadError: (AdsLoadErrorData data) {}, + proxy: proxy, + ), + ); + + final AndroidContentProgressProvider progressProvider = + AndroidContentProgressProvider( + AndroidContentProgressProviderCreationParams(proxy: proxy), + ); + await adsLoader.requestAds( + PlatformAdsRequest( + adTagUrl: 'url', + contentProgressProvider: progressProvider, + ), + ); + + verifyInOrder(>[ + mockAdsRequest.setAdTagUrl('url'), + mockAdsRequest.setContentProgressProvider( + progressProvider.progressProvider, + ), + mockAdsLoader.requestAds(mockAdsRequest), + ]); + }); + + testWidgets('onAdsLoaded', (WidgetTester tester) async { + final AndroidAdDisplayContainer container = + await _pumpAdDisplayContainer(tester); + + final MockImaSdkFactory mockSdkFactory = MockImaSdkFactory(); + when(mockSdkFactory.createImaSdkSettings()).thenAnswer((_) async { + return MockImaSdkSettings(); + }); + + final MockAdsLoader mockAdsLoader = MockAdsLoader(); + final Completer addEventListenerCompleter = Completer(); + when(mockAdsLoader.addAdsLoadedListener(any)).thenAnswer((_) async { + addEventListenerCompleter.complete(); + }); + + when(mockSdkFactory.createAdsLoader(any, any)).thenAnswer((_) async { + return mockAdsLoader; + }); + + late final void Function( + ima.AdsLoadedListener, + ima.AdsManagerLoadedEvent, + ) onAdsManagerLoadedCallback; + + final InteractiveMediaAdsProxy proxy = InteractiveMediaAdsProxy( + instanceImaSdkFactory: () => mockSdkFactory, + newAdsLoadedListener: ({ + required void Function( + ima.AdsLoadedListener, + ima.AdsManagerLoadedEvent, + ) onAdsManagerLoaded, + }) { + onAdsManagerLoadedCallback = onAdsManagerLoaded; + return MockAdsLoadedListener(); + }, + newAdErrorListener: ({required dynamic onAdError}) { + return MockAdErrorListener(); + }, + ); + + AndroidAdsLoader( + AndroidAdsLoaderCreationParams( + container: container, + onAdsLoaded: expectAsync1((_) {}), + onAdsLoadError: (_) {}, + proxy: proxy, + ), + ); + + final MockAdsManagerLoadedEvent mockLoadedEvent = + MockAdsManagerLoadedEvent(); + when(mockLoadedEvent.manager).thenReturn(MockAdsManager()); + + await addEventListenerCompleter.future; + + onAdsManagerLoadedCallback(MockAdsLoadedListener(), mockLoadedEvent); + }); + + testWidgets('onAdError', (WidgetTester tester) async { + final AndroidAdDisplayContainer container = + await _pumpAdDisplayContainer(tester); + + final MockImaSdkFactory mockSdkFactory = MockImaSdkFactory(); + when(mockSdkFactory.createImaSdkSettings()).thenAnswer((_) async { + return MockImaSdkSettings(); + }); + + final MockAdsLoader mockAdsLoader = MockAdsLoader(); + final Completer addErrorListenerCompleter = Completer(); + when(mockAdsLoader.addAdErrorListener(any)).thenAnswer((_) async { + addErrorListenerCompleter.complete(); + }); + + when(mockSdkFactory.createAdsLoader(any, any)).thenAnswer((_) async { + return mockAdsLoader; + }); + + late final void Function( + ima.AdErrorListener, + ima.AdErrorEvent, + ) onAdErrorCallback; + + final InteractiveMediaAdsProxy proxy = InteractiveMediaAdsProxy( + instanceImaSdkFactory: () => mockSdkFactory, + newAdsLoadedListener: ({required dynamic onAdsManagerLoaded}) { + return MockAdsLoadedListener(); + }, + newAdErrorListener: ({ + required void Function( + ima.AdErrorListener, + ima.AdErrorEvent, + ) onAdError, + }) { + onAdErrorCallback = onAdError; + return MockAdErrorListener(); + }, + ); + + AndroidAdsLoader( + AndroidAdsLoaderCreationParams( + container: container, + onAdsLoaded: (_) {}, + onAdsLoadError: expectAsync1((_) {}), + proxy: proxy, + ), + ); + + final MockAdErrorEvent mockErrorEvent = MockAdErrorEvent(); + final MockAdError mockError = MockAdError(); + when(mockError.errorType).thenReturn(ima.AdErrorType.load); + when(mockError.errorCode) + .thenReturn(ima.AdErrorCode.adsRequestNetworkError); + when(mockError.message).thenReturn('error message'); + when(mockErrorEvent.error).thenReturn(mockError); + + await addErrorListenerCompleter.future; + + onAdErrorCallback(MockAdErrorListener(), mockErrorEvent); + }); + }); +} + +Future _pumpAdDisplayContainer( + WidgetTester tester, { + MockVideoAdPlayerCallback? mockAdPlayerCallback, +}) async { + final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( + newFrameLayout: () => MockFrameLayout(), + newVideoView: ({ + required dynamic onError, + dynamic onPrepared, + dynamic onCompletion, + }) => + MockVideoView(), + createAdDisplayContainerImaSdkFactory: ( + _, + __, + ) async { + return MockAdDisplayContainer(); + }, + newVideoAdPlayer: ({ + required void Function( + ima.VideoAdPlayer, + ima.VideoAdPlayerCallback, + ) addCallback, + required dynamic loadAd, + required dynamic pauseAd, + required dynamic playAd, + required dynamic release, + required dynamic removeCallback, + required dynamic stopAd, + }) { + if (mockAdPlayerCallback != null) { + addCallback(MockVideoAdPlayer(), mockAdPlayerCallback); + } + return MockVideoAdPlayer(); + }, + ); + + final MockPlatformViewsServiceProxy mockPlatformViewsProxy = + MockPlatformViewsServiceProxy(); + final MockSurfaceAndroidViewController mockAndroidViewController = + MockSurfaceAndroidViewController(); + + late final int platformViewId; + when( + mockPlatformViewsProxy.initSurfaceAndroidView( + id: anyNamed('id'), + viewType: anyNamed('viewType'), + layoutDirection: anyNamed('layoutDirection'), + creationParams: anyNamed('creationParams'), + creationParamsCodec: anyNamed('creationParamsCodec'), + onFocus: anyNamed('onFocus'), + ), + ).thenAnswer((Invocation invocation) { + platformViewId = invocation.namedArguments[const Symbol('id')] as int; + return mockAndroidViewController; + }); + + final Completer adDisplayContainerCompleter = + Completer(); + + final AndroidAdDisplayContainer container = AndroidAdDisplayContainer( + AndroidAdDisplayContainerCreationParams( + onContainerAdded: (PlatformAdDisplayContainer container) { + adDisplayContainerCompleter.complete( + container as AndroidAdDisplayContainer, + ); + }, + platformViewsProxy: mockPlatformViewsProxy, + imaProxy: imaProxy, + ), + ); + + await tester.pumpWidget(Builder( + builder: (BuildContext context) => container.build(context), + )); + + final void Function(int) onPlatformCreatedCallback = verify( + mockAndroidViewController + .addOnPlatformViewCreatedListener(captureAny)) + .captured[0] as void Function(int); + + onPlatformCreatedCallback(platformViewId); + + return adDisplayContainerCompleter.future; +} diff --git a/packages/interactive_media_ads/test/android/ads_loader_test.mocks.dart b/packages/interactive_media_ads/test/android/ads_loader_test.mocks.dart new file mode 100644 index 000000000000..fc6fe08a4000 --- /dev/null +++ b/packages/interactive_media_ads/test/android/ads_loader_test.mocks.dart @@ -0,0 +1,1865 @@ +// Mocks generated by Mockito 5.4.4 from annotations +// in interactive_media_ads/test/android/ads_loader_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i6; +import 'dart:ui' as _i3; + +import 'package:flutter/services.dart' as _i4; +import 'package:interactive_media_ads/src/android/interactive_media_ads.g.dart' + as _i2; +import 'package:interactive_media_ads/src/android/platform_views_service_proxy.dart' + as _i7; +import 'package:mockito/mockito.dart' as _i1; +import 'package:mockito/src/dummies.dart' as _i5; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakePigeonInstanceManager_0 extends _i1.SmartFake + implements _i2.PigeonInstanceManager { + _FakePigeonInstanceManager_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeAdDisplayContainer_1 extends _i1.SmartFake + implements _i2.AdDisplayContainer { + _FakeAdDisplayContainer_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeAdError_2 extends _i1.SmartFake implements _i2.AdError { + _FakeAdError_2( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeAdErrorEvent_3 extends _i1.SmartFake implements _i2.AdErrorEvent { + _FakeAdErrorEvent_3( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeAdErrorListener_4 extends _i1.SmartFake + implements _i2.AdErrorListener { + _FakeAdErrorListener_4( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeAdsLoadedListener_5 extends _i1.SmartFake + implements _i2.AdsLoadedListener { + _FakeAdsLoadedListener_5( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeAdsManager_6 extends _i1.SmartFake implements _i2.AdsManager { + _FakeAdsManager_6( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeAdsManagerLoadedEvent_7 extends _i1.SmartFake + implements _i2.AdsManagerLoadedEvent { + _FakeAdsManagerLoadedEvent_7( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeAdsLoader_8 extends _i1.SmartFake implements _i2.AdsLoader { + _FakeAdsLoader_8( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeAdsRequest_9 extends _i1.SmartFake implements _i2.AdsRequest { + _FakeAdsRequest_9( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeFrameLayout_10 extends _i1.SmartFake implements _i2.FrameLayout { + _FakeFrameLayout_10( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeImaSdkSettings_11 extends _i1.SmartFake + implements _i2.ImaSdkSettings { + _FakeImaSdkSettings_11( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeImaSdkFactory_12 extends _i1.SmartFake implements _i2.ImaSdkFactory { + _FakeImaSdkFactory_12( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeVideoAdPlayer_13 extends _i1.SmartFake implements _i2.VideoAdPlayer { + _FakeVideoAdPlayer_13( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeVideoAdPlayerCallback_14 extends _i1.SmartFake + implements _i2.VideoAdPlayerCallback { + _FakeVideoAdPlayerCallback_14( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeVideoView_15 extends _i1.SmartFake implements _i2.VideoView { + _FakeVideoView_15( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeOffset_16 extends _i1.SmartFake implements _i3.Offset { + _FakeOffset_16( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeSize_17 extends _i1.SmartFake implements _i3.Size { + _FakeSize_17( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeExpensiveAndroidViewController_18 extends _i1.SmartFake + implements _i4.ExpensiveAndroidViewController { + _FakeExpensiveAndroidViewController_18( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeSurfaceAndroidViewController_19 extends _i1.SmartFake + implements _i4.SurfaceAndroidViewController { + _FakeSurfaceAndroidViewController_19( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [AdDisplayContainer]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAdDisplayContainer extends _i1.Mock + implements _i2.AdDisplayContainer { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.AdDisplayContainer pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeAdDisplayContainer_1( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeAdDisplayContainer_1( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.AdDisplayContainer); +} + +/// A class which mocks [AdError]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAdError extends _i1.Mock implements _i2.AdError { + @override + _i2.AdErrorCode get errorCode => (super.noSuchMethod( + Invocation.getter(#errorCode), + returnValue: _i2.AdErrorCode.adsPlayerWasNotProvided, + returnValueForMissingStub: _i2.AdErrorCode.adsPlayerWasNotProvided, + ) as _i2.AdErrorCode); + + @override + int get errorCodeNumber => (super.noSuchMethod( + Invocation.getter(#errorCodeNumber), + returnValue: 0, + returnValueForMissingStub: 0, + ) as int); + + @override + _i2.AdErrorType get errorType => (super.noSuchMethod( + Invocation.getter(#errorType), + returnValue: _i2.AdErrorType.load, + returnValueForMissingStub: _i2.AdErrorType.load, + ) as _i2.AdErrorType); + + @override + String get message => (super.noSuchMethod( + Invocation.getter(#message), + returnValue: _i5.dummyValue( + this, + Invocation.getter(#message), + ), + returnValueForMissingStub: _i5.dummyValue( + this, + Invocation.getter(#message), + ), + ) as String); + + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.AdError pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeAdError_2( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeAdError_2( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.AdError); +} + +/// A class which mocks [AdErrorEvent]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAdErrorEvent extends _i1.Mock implements _i2.AdErrorEvent { + @override + _i2.AdError get error => (super.noSuchMethod( + Invocation.getter(#error), + returnValue: _FakeAdError_2( + this, + Invocation.getter(#error), + ), + returnValueForMissingStub: _FakeAdError_2( + this, + Invocation.getter(#error), + ), + ) as _i2.AdError); + + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.AdErrorEvent pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeAdErrorEvent_3( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeAdErrorEvent_3( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.AdErrorEvent); +} + +/// A class which mocks [AdErrorListener]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAdErrorListener extends _i1.Mock implements _i2.AdErrorListener { + @override + void Function( + _i2.AdErrorListener, + _i2.AdErrorEvent, + ) get onAdError => (super.noSuchMethod( + Invocation.getter(#onAdError), + returnValue: ( + _i2.AdErrorListener pigeon_instance, + _i2.AdErrorEvent event, + ) {}, + returnValueForMissingStub: ( + _i2.AdErrorListener pigeon_instance, + _i2.AdErrorEvent event, + ) {}, + ) as void Function( + _i2.AdErrorListener, + _i2.AdErrorEvent, + )); + + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.AdErrorListener pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeAdErrorListener_4( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeAdErrorListener_4( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.AdErrorListener); +} + +/// A class which mocks [AdsLoadedListener]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAdsLoadedListener extends _i1.Mock implements _i2.AdsLoadedListener { + @override + void Function( + _i2.AdsLoadedListener, + _i2.AdsManagerLoadedEvent, + ) get onAdsManagerLoaded => (super.noSuchMethod( + Invocation.getter(#onAdsManagerLoaded), + returnValue: ( + _i2.AdsLoadedListener pigeon_instance, + _i2.AdsManagerLoadedEvent event, + ) {}, + returnValueForMissingStub: ( + _i2.AdsLoadedListener pigeon_instance, + _i2.AdsManagerLoadedEvent event, + ) {}, + ) as void Function( + _i2.AdsLoadedListener, + _i2.AdsManagerLoadedEvent, + )); + + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.AdsLoadedListener pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeAdsLoadedListener_5( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeAdsLoadedListener_5( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.AdsLoadedListener); +} + +/// A class which mocks [AdsManager]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAdsManager extends _i1.Mock implements _i2.AdsManager { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i6.Future discardAdBreak() => (super.noSuchMethod( + Invocation.method( + #discardAdBreak, + [], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future pause() => (super.noSuchMethod( + Invocation.method( + #pause, + [], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future start() => (super.noSuchMethod( + Invocation.method( + #start, + [], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future> getAdCuePoints() => (super.noSuchMethod( + Invocation.method( + #getAdCuePoints, + [], + ), + returnValue: _i6.Future>.value([]), + returnValueForMissingStub: _i6.Future>.value([]), + ) as _i6.Future>); + + @override + _i6.Future resume() => (super.noSuchMethod( + Invocation.method( + #resume, + [], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future skip() => (super.noSuchMethod( + Invocation.method( + #skip, + [], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i2.AdsManager pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeAdsManager_6( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeAdsManager_6( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.AdsManager); + + @override + _i6.Future addAdErrorListener(_i2.AdErrorListener? errorListener) => + (super.noSuchMethod( + Invocation.method( + #addAdErrorListener, + [errorListener], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future addAdEventListener(_i2.AdEventListener? adEventListener) => + (super.noSuchMethod( + Invocation.method( + #addAdEventListener, + [adEventListener], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future destroy() => (super.noSuchMethod( + Invocation.method( + #destroy, + [], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future init(_i2.AdsRenderingSettings? settings) => + (super.noSuchMethod( + Invocation.method( + #init, + [settings], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future focus() => (super.noSuchMethod( + Invocation.method( + #focus, + [], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future<_i2.AdProgressInfo?> getAdProgressInfo() => (super.noSuchMethod( + Invocation.method( + #getAdProgressInfo, + [], + ), + returnValue: _i6.Future<_i2.AdProgressInfo?>.value(), + returnValueForMissingStub: _i6.Future<_i2.AdProgressInfo?>.value(), + ) as _i6.Future<_i2.AdProgressInfo?>); + + @override + _i6.Future<_i2.Ad?> getCurrentAd() => (super.noSuchMethod( + Invocation.method( + #getCurrentAd, + [], + ), + returnValue: _i6.Future<_i2.Ad?>.value(), + returnValueForMissingStub: _i6.Future<_i2.Ad?>.value(), + ) as _i6.Future<_i2.Ad?>); + + @override + _i6.Future removeAdErrorListener(_i2.AdErrorListener? errorListener) => + (super.noSuchMethod( + Invocation.method( + #removeAdErrorListener, + [errorListener], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future removeAdEventListener( + _i2.AdEventListener? adEventListener) => + (super.noSuchMethod( + Invocation.method( + #removeAdEventListener, + [adEventListener], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); +} + +/// A class which mocks [AdsManagerLoadedEvent]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAdsManagerLoadedEvent extends _i1.Mock + implements _i2.AdsManagerLoadedEvent { + @override + _i2.AdsManager get manager => (super.noSuchMethod( + Invocation.getter(#manager), + returnValue: _FakeAdsManager_6( + this, + Invocation.getter(#manager), + ), + returnValueForMissingStub: _FakeAdsManager_6( + this, + Invocation.getter(#manager), + ), + ) as _i2.AdsManager); + + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.AdsManagerLoadedEvent pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeAdsManagerLoadedEvent_7( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeAdsManagerLoadedEvent_7( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.AdsManagerLoadedEvent); +} + +/// A class which mocks [AdsLoader]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAdsLoader extends _i1.Mock implements _i2.AdsLoader { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i6.Future addAdErrorListener(_i2.AdErrorListener? listener) => + (super.noSuchMethod( + Invocation.method( + #addAdErrorListener, + [listener], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future addAdsLoadedListener(_i2.AdsLoadedListener? listener) => + (super.noSuchMethod( + Invocation.method( + #addAdsLoadedListener, + [listener], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future requestAds(_i2.AdsRequest? request) => (super.noSuchMethod( + Invocation.method( + #requestAds, + [request], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i2.AdsLoader pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeAdsLoader_8( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeAdsLoader_8( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.AdsLoader); +} + +/// A class which mocks [AdsRequest]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAdsRequest extends _i1.Mock implements _i2.AdsRequest { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i6.Future setAdTagUrl(String? adTagUrl) => (super.noSuchMethod( + Invocation.method( + #setAdTagUrl, + [adTagUrl], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future setContentProgressProvider( + _i2.ContentProgressProvider? provider) => + (super.noSuchMethod( + Invocation.method( + #setContentProgressProvider, + [provider], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i2.AdsRequest pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeAdsRequest_9( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeAdsRequest_9( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.AdsRequest); +} + +/// A class which mocks [FrameLayout]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockFrameLayout extends _i1.Mock implements _i2.FrameLayout { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.FrameLayout pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeFrameLayout_10( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeFrameLayout_10( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.FrameLayout); + + @override + _i6.Future addView(_i2.View? view) => (super.noSuchMethod( + Invocation.method( + #addView, + [view], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future removeView(_i2.View? view) => (super.noSuchMethod( + Invocation.method( + #removeView, + [view], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); +} + +/// A class which mocks [ImaSdkFactory]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockImaSdkFactory extends _i1.Mock implements _i2.ImaSdkFactory { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i6.Future<_i2.ImaSdkSettings> createImaSdkSettings() => (super.noSuchMethod( + Invocation.method( + #createImaSdkSettings, + [], + ), + returnValue: + _i6.Future<_i2.ImaSdkSettings>.value(_FakeImaSdkSettings_11( + this, + Invocation.method( + #createImaSdkSettings, + [], + ), + )), + returnValueForMissingStub: + _i6.Future<_i2.ImaSdkSettings>.value(_FakeImaSdkSettings_11( + this, + Invocation.method( + #createImaSdkSettings, + [], + ), + )), + ) as _i6.Future<_i2.ImaSdkSettings>); + + @override + _i6.Future<_i2.AdsLoader> createAdsLoader( + _i2.ImaSdkSettings? settings, + _i2.AdDisplayContainer? container, + ) => + (super.noSuchMethod( + Invocation.method( + #createAdsLoader, + [ + settings, + container, + ], + ), + returnValue: _i6.Future<_i2.AdsLoader>.value(_FakeAdsLoader_8( + this, + Invocation.method( + #createAdsLoader, + [ + settings, + container, + ], + ), + )), + returnValueForMissingStub: + _i6.Future<_i2.AdsLoader>.value(_FakeAdsLoader_8( + this, + Invocation.method( + #createAdsLoader, + [ + settings, + container, + ], + ), + )), + ) as _i6.Future<_i2.AdsLoader>); + + @override + _i6.Future<_i2.AdsRequest> createAdsRequest() => (super.noSuchMethod( + Invocation.method( + #createAdsRequest, + [], + ), + returnValue: _i6.Future<_i2.AdsRequest>.value(_FakeAdsRequest_9( + this, + Invocation.method( + #createAdsRequest, + [], + ), + )), + returnValueForMissingStub: + _i6.Future<_i2.AdsRequest>.value(_FakeAdsRequest_9( + this, + Invocation.method( + #createAdsRequest, + [], + ), + )), + ) as _i6.Future<_i2.AdsRequest>); + + @override + _i2.ImaSdkFactory pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeImaSdkFactory_12( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeImaSdkFactory_12( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.ImaSdkFactory); +} + +/// A class which mocks [ImaSdkSettings]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockImaSdkSettings extends _i1.Mock implements _i2.ImaSdkSettings { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.ImaSdkSettings pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeImaSdkSettings_11( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeImaSdkSettings_11( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.ImaSdkSettings); +} + +/// A class which mocks [VideoAdPlayer]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockVideoAdPlayer extends _i1.Mock implements _i2.VideoAdPlayer { + @override + void Function( + _i2.VideoAdPlayer, + _i2.VideoAdPlayerCallback, + ) get addCallback => (super.noSuchMethod( + Invocation.getter(#addCallback), + returnValue: ( + _i2.VideoAdPlayer pigeon_instance, + _i2.VideoAdPlayerCallback callback, + ) {}, + returnValueForMissingStub: ( + _i2.VideoAdPlayer pigeon_instance, + _i2.VideoAdPlayerCallback callback, + ) {}, + ) as void Function( + _i2.VideoAdPlayer, + _i2.VideoAdPlayerCallback, + )); + + @override + void Function( + _i2.VideoAdPlayer, + _i2.AdMediaInfo, + _i2.AdPodInfo, + ) get loadAd => (super.noSuchMethod( + Invocation.getter(#loadAd), + returnValue: ( + _i2.VideoAdPlayer pigeon_instance, + _i2.AdMediaInfo adMediaInfo, + _i2.AdPodInfo adPodInfo, + ) {}, + returnValueForMissingStub: ( + _i2.VideoAdPlayer pigeon_instance, + _i2.AdMediaInfo adMediaInfo, + _i2.AdPodInfo adPodInfo, + ) {}, + ) as void Function( + _i2.VideoAdPlayer, + _i2.AdMediaInfo, + _i2.AdPodInfo, + )); + + @override + void Function( + _i2.VideoAdPlayer, + _i2.AdMediaInfo, + ) get pauseAd => (super.noSuchMethod( + Invocation.getter(#pauseAd), + returnValue: ( + _i2.VideoAdPlayer pigeon_instance, + _i2.AdMediaInfo adMediaInfo, + ) {}, + returnValueForMissingStub: ( + _i2.VideoAdPlayer pigeon_instance, + _i2.AdMediaInfo adMediaInfo, + ) {}, + ) as void Function( + _i2.VideoAdPlayer, + _i2.AdMediaInfo, + )); + + @override + void Function( + _i2.VideoAdPlayer, + _i2.AdMediaInfo, + ) get playAd => (super.noSuchMethod( + Invocation.getter(#playAd), + returnValue: ( + _i2.VideoAdPlayer pigeon_instance, + _i2.AdMediaInfo adMediaInfo, + ) {}, + returnValueForMissingStub: ( + _i2.VideoAdPlayer pigeon_instance, + _i2.AdMediaInfo adMediaInfo, + ) {}, + ) as void Function( + _i2.VideoAdPlayer, + _i2.AdMediaInfo, + )); + + @override + void Function(_i2.VideoAdPlayer) get release => (super.noSuchMethod( + Invocation.getter(#release), + returnValue: (_i2.VideoAdPlayer pigeon_instance) {}, + returnValueForMissingStub: (_i2.VideoAdPlayer pigeon_instance) {}, + ) as void Function(_i2.VideoAdPlayer)); + + @override + void Function( + _i2.VideoAdPlayer, + _i2.VideoAdPlayerCallback, + ) get removeCallback => (super.noSuchMethod( + Invocation.getter(#removeCallback), + returnValue: ( + _i2.VideoAdPlayer pigeon_instance, + _i2.VideoAdPlayerCallback callback, + ) {}, + returnValueForMissingStub: ( + _i2.VideoAdPlayer pigeon_instance, + _i2.VideoAdPlayerCallback callback, + ) {}, + ) as void Function( + _i2.VideoAdPlayer, + _i2.VideoAdPlayerCallback, + )); + + @override + void Function( + _i2.VideoAdPlayer, + _i2.AdMediaInfo, + ) get stopAd => (super.noSuchMethod( + Invocation.getter(#stopAd), + returnValue: ( + _i2.VideoAdPlayer pigeon_instance, + _i2.AdMediaInfo adMediaInfo, + ) {}, + returnValueForMissingStub: ( + _i2.VideoAdPlayer pigeon_instance, + _i2.AdMediaInfo adMediaInfo, + ) {}, + ) as void Function( + _i2.VideoAdPlayer, + _i2.AdMediaInfo, + )); + + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i6.Future setVolume(int? value) => (super.noSuchMethod( + Invocation.method( + #setVolume, + [value], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future setAdProgress(_i2.VideoProgressUpdate? progress) => + (super.noSuchMethod( + Invocation.method( + #setAdProgress, + [progress], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i2.VideoAdPlayer pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeVideoAdPlayer_13( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeVideoAdPlayer_13( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.VideoAdPlayer); +} + +/// A class which mocks [VideoAdPlayerCallback]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockVideoAdPlayerCallback extends _i1.Mock + implements _i2.VideoAdPlayerCallback { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i6.Future onAdProgress( + _i2.AdMediaInfo? adMediaInfo, + _i2.VideoProgressUpdate? videoProgressUpdate, + ) => + (super.noSuchMethod( + Invocation.method( + #onAdProgress, + [ + adMediaInfo, + videoProgressUpdate, + ], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future onBuffering(_i2.AdMediaInfo? adMediaInfo) => + (super.noSuchMethod( + Invocation.method( + #onBuffering, + [adMediaInfo], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future onContentComplete() => (super.noSuchMethod( + Invocation.method( + #onContentComplete, + [], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future onEnded(_i2.AdMediaInfo? adMediaInfo) => (super.noSuchMethod( + Invocation.method( + #onEnded, + [adMediaInfo], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future onError(_i2.AdMediaInfo? adMediaInfo) => (super.noSuchMethod( + Invocation.method( + #onError, + [adMediaInfo], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future onLoaded(_i2.AdMediaInfo? adMediaInfo) => + (super.noSuchMethod( + Invocation.method( + #onLoaded, + [adMediaInfo], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future onPause(_i2.AdMediaInfo? adMediaInfo) => (super.noSuchMethod( + Invocation.method( + #onPause, + [adMediaInfo], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future onPlay(_i2.AdMediaInfo? adMediaInfo) => (super.noSuchMethod( + Invocation.method( + #onPlay, + [adMediaInfo], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future onResume(_i2.AdMediaInfo? adMediaInfo) => + (super.noSuchMethod( + Invocation.method( + #onResume, + [adMediaInfo], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future onVolumeChanged( + _i2.AdMediaInfo? adMediaInfo, + int? percentage, + ) => + (super.noSuchMethod( + Invocation.method( + #onVolumeChanged, + [ + adMediaInfo, + percentage, + ], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i2.VideoAdPlayerCallback pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeVideoAdPlayerCallback_14( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeVideoAdPlayerCallback_14( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.VideoAdPlayerCallback); +} + +/// A class which mocks [VideoView]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockVideoView extends _i1.Mock implements _i2.VideoView { + @override + void Function( + _i2.VideoView, + _i2.MediaPlayer, + int, + int, + ) get onError => (super.noSuchMethod( + Invocation.getter(#onError), + returnValue: ( + _i2.VideoView pigeon_instance, + _i2.MediaPlayer player, + int what, + int extra, + ) {}, + returnValueForMissingStub: ( + _i2.VideoView pigeon_instance, + _i2.MediaPlayer player, + int what, + int extra, + ) {}, + ) as void Function( + _i2.VideoView, + _i2.MediaPlayer, + int, + int, + )); + + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i6.Future setVideoUri(String? uri) => (super.noSuchMethod( + Invocation.method( + #setVideoUri, + [uri], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future getCurrentPosition() => (super.noSuchMethod( + Invocation.method( + #getCurrentPosition, + [], + ), + returnValue: _i6.Future.value(0), + returnValueForMissingStub: _i6.Future.value(0), + ) as _i6.Future); + + @override + _i2.VideoView pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeVideoView_15( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeVideoView_15( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.VideoView); +} + +/// A class which mocks [SurfaceAndroidViewController]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockSurfaceAndroidViewController extends _i1.Mock + implements _i4.SurfaceAndroidViewController { + @override + bool get requiresViewComposition => (super.noSuchMethod( + Invocation.getter(#requiresViewComposition), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + int get viewId => (super.noSuchMethod( + Invocation.getter(#viewId), + returnValue: 0, + returnValueForMissingStub: 0, + ) as int); + + @override + bool get awaitingCreation => (super.noSuchMethod( + Invocation.getter(#awaitingCreation), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + _i4.PointTransformer get pointTransformer => (super.noSuchMethod( + Invocation.getter(#pointTransformer), + returnValue: (_i3.Offset position) => _FakeOffset_16( + this, + Invocation.getter(#pointTransformer), + ), + returnValueForMissingStub: (_i3.Offset position) => _FakeOffset_16( + this, + Invocation.getter(#pointTransformer), + ), + ) as _i4.PointTransformer); + + @override + set pointTransformer(_i4.PointTransformer? transformer) => super.noSuchMethod( + Invocation.setter( + #pointTransformer, + transformer, + ), + returnValueForMissingStub: null, + ); + + @override + bool get isCreated => (super.noSuchMethod( + Invocation.getter(#isCreated), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + List<_i4.PlatformViewCreatedCallback> get createdCallbacks => + (super.noSuchMethod( + Invocation.getter(#createdCallbacks), + returnValue: <_i4.PlatformViewCreatedCallback>[], + returnValueForMissingStub: <_i4.PlatformViewCreatedCallback>[], + ) as List<_i4.PlatformViewCreatedCallback>); + + @override + _i6.Future setOffset(_i3.Offset? off) => (super.noSuchMethod( + Invocation.method( + #setOffset, + [off], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future create({ + _i3.Size? size, + _i3.Offset? position, + }) => + (super.noSuchMethod( + Invocation.method( + #create, + [], + { + #size: size, + #position: position, + }, + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future<_i3.Size> setSize(_i3.Size? size) => (super.noSuchMethod( + Invocation.method( + #setSize, + [size], + ), + returnValue: _i6.Future<_i3.Size>.value(_FakeSize_17( + this, + Invocation.method( + #setSize, + [size], + ), + )), + returnValueForMissingStub: _i6.Future<_i3.Size>.value(_FakeSize_17( + this, + Invocation.method( + #setSize, + [size], + ), + )), + ) as _i6.Future<_i3.Size>); + + @override + _i6.Future sendMotionEvent(_i4.AndroidMotionEvent? event) => + (super.noSuchMethod( + Invocation.method( + #sendMotionEvent, + [event], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + void addOnPlatformViewCreatedListener( + _i4.PlatformViewCreatedCallback? listener) => + super.noSuchMethod( + Invocation.method( + #addOnPlatformViewCreatedListener, + [listener], + ), + returnValueForMissingStub: null, + ); + + @override + void removeOnPlatformViewCreatedListener( + _i4.PlatformViewCreatedCallback? listener) => + super.noSuchMethod( + Invocation.method( + #removeOnPlatformViewCreatedListener, + [listener], + ), + returnValueForMissingStub: null, + ); + + @override + _i6.Future setLayoutDirection(_i3.TextDirection? layoutDirection) => + (super.noSuchMethod( + Invocation.method( + #setLayoutDirection, + [layoutDirection], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future dispatchPointerEvent(_i4.PointerEvent? event) => + (super.noSuchMethod( + Invocation.method( + #dispatchPointerEvent, + [event], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future clearFocus() => (super.noSuchMethod( + Invocation.method( + #clearFocus, + [], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future dispose() => (super.noSuchMethod( + Invocation.method( + #dispose, + [], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); +} + +/// A class which mocks [PlatformViewsServiceProxy]. +/// +/// See the documentation for Mockito's code generation for more information. +// ignore: must_be_immutable +class MockPlatformViewsServiceProxy extends _i1.Mock + implements _i7.PlatformViewsServiceProxy { + @override + _i4.ExpensiveAndroidViewController initExpensiveAndroidView({ + required int? id, + required String? viewType, + required _i3.TextDirection? layoutDirection, + dynamic creationParams, + _i4.MessageCodec? creationParamsCodec, + _i3.VoidCallback? onFocus, + }) => + (super.noSuchMethod( + Invocation.method( + #initExpensiveAndroidView, + [], + { + #id: id, + #viewType: viewType, + #layoutDirection: layoutDirection, + #creationParams: creationParams, + #creationParamsCodec: creationParamsCodec, + #onFocus: onFocus, + }, + ), + returnValue: _FakeExpensiveAndroidViewController_18( + this, + Invocation.method( + #initExpensiveAndroidView, + [], + { + #id: id, + #viewType: viewType, + #layoutDirection: layoutDirection, + #creationParams: creationParams, + #creationParamsCodec: creationParamsCodec, + #onFocus: onFocus, + }, + ), + ), + returnValueForMissingStub: _FakeExpensiveAndroidViewController_18( + this, + Invocation.method( + #initExpensiveAndroidView, + [], + { + #id: id, + #viewType: viewType, + #layoutDirection: layoutDirection, + #creationParams: creationParams, + #creationParamsCodec: creationParamsCodec, + #onFocus: onFocus, + }, + ), + ), + ) as _i4.ExpensiveAndroidViewController); + + @override + _i4.SurfaceAndroidViewController initSurfaceAndroidView({ + required int? id, + required String? viewType, + required _i3.TextDirection? layoutDirection, + dynamic creationParams, + _i4.MessageCodec? creationParamsCodec, + _i3.VoidCallback? onFocus, + }) => + (super.noSuchMethod( + Invocation.method( + #initSurfaceAndroidView, + [], + { + #id: id, + #viewType: viewType, + #layoutDirection: layoutDirection, + #creationParams: creationParams, + #creationParamsCodec: creationParamsCodec, + #onFocus: onFocus, + }, + ), + returnValue: _FakeSurfaceAndroidViewController_19( + this, + Invocation.method( + #initSurfaceAndroidView, + [], + { + #id: id, + #viewType: viewType, + #layoutDirection: layoutDirection, + #creationParams: creationParams, + #creationParamsCodec: creationParamsCodec, + #onFocus: onFocus, + }, + ), + ), + returnValueForMissingStub: _FakeSurfaceAndroidViewController_19( + this, + Invocation.method( + #initSurfaceAndroidView, + [], + { + #id: id, + #viewType: viewType, + #layoutDirection: layoutDirection, + #creationParams: creationParams, + #creationParamsCodec: creationParamsCodec, + #onFocus: onFocus, + }, + ), + ), + ) as _i4.SurfaceAndroidViewController); +} diff --git a/packages/interactive_media_ads/test/android/ads_manager_test.dart b/packages/interactive_media_ads/test/android/ads_manager_test.dart new file mode 100644 index 000000000000..0b94d6a7d753 --- /dev/null +++ b/packages/interactive_media_ads/test/android/ads_manager_test.dart @@ -0,0 +1,172 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:interactive_media_ads/src/android/android_ads_manager.dart'; +import 'package:interactive_media_ads/src/android/android_ads_manager_delegate.dart'; +import 'package:interactive_media_ads/src/android/interactive_media_ads.g.dart' + as ima; +import 'package:interactive_media_ads/src/android/interactive_media_ads_proxy.dart'; +import 'package:interactive_media_ads/src/platform_interface/platform_interface.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; + +import 'ads_manager_test.mocks.dart'; + +@GenerateNiceMocks(>[ + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), +]) +void main() { + group('AndroidAdsManager', () { + test('destroy', () { + final MockAdsManager mockAdsManager = MockAdsManager(); + final AndroidAdsManager adsManager = AndroidAdsManager(mockAdsManager); + adsManager.destroy(); + + verify(mockAdsManager.destroy()); + }); + + test('init', () { + final MockAdsManager mockAdsManager = MockAdsManager(); + final AndroidAdsManager adsManager = AndroidAdsManager(mockAdsManager); + adsManager.init(AdsManagerInitParams()); + + verify(mockAdsManager.init(null)); + }); + + test('start', () { + final MockAdsManager mockAdsManager = MockAdsManager(); + final AndroidAdsManager adsManager = AndroidAdsManager(mockAdsManager); + adsManager.start(AdsManagerStartParams()); + + verify(mockAdsManager.start()); + }); + + test('discardAdBreak', () { + final MockAdsManager mockAdsManager = MockAdsManager(); + final AndroidAdsManager adsManager = AndroidAdsManager(mockAdsManager); + adsManager.discardAdBreak(); + + verify(mockAdsManager.discardAdBreak()); + }); + + test('pause', () { + final MockAdsManager mockAdsManager = MockAdsManager(); + final AndroidAdsManager adsManager = AndroidAdsManager(mockAdsManager); + adsManager.pause(); + + verify(mockAdsManager.pause()); + }); + + test('skip', () { + final MockAdsManager mockAdsManager = MockAdsManager(); + final AndroidAdsManager adsManager = AndroidAdsManager(mockAdsManager); + adsManager.skip(); + + verify(mockAdsManager.skip()); + }); + + test('resume', () { + final MockAdsManager mockAdsManager = MockAdsManager(); + final AndroidAdsManager adsManager = AndroidAdsManager(mockAdsManager); + adsManager.resume(); + + verify(mockAdsManager.resume()); + }); + + test('onAdEvent', () async { + final MockAdsManager mockAdsManager = MockAdsManager(); + + late final void Function( + ima.AdEventListener, + ima.AdEvent, + ) onAdEventCallback; + + final InteractiveMediaAdsProxy proxy = InteractiveMediaAdsProxy( + newAdEventListener: ({ + required void Function( + ima.AdEventListener, + ima.AdEvent, + ) onAdEvent, + }) { + onAdEventCallback = onAdEvent; + return MockAdEventListener(); + }, + newAdErrorListener: ({required dynamic onAdError}) { + return MockAdErrorListener(); + }, + ); + + final AndroidAdsManager adsManager = AndroidAdsManager( + mockAdsManager, + proxy: proxy, + ); + await adsManager.setAdsManagerDelegate( + AndroidAdsManagerDelegate( + PlatformAdsManagerDelegateCreationParams( + onAdEvent: expectAsync1((AdEvent event) { + expect(event.type, AdEventType.allAdsCompleted); + expect(event.adData, {'hello': 'world'}); + }), + ), + ), + ); + + final MockAdEvent mockAdEvent = MockAdEvent(); + when(mockAdEvent.type).thenReturn(ima.AdEventType.allAdsCompleted); + when(mockAdEvent.adData).thenReturn({'hello': 'world'}); + onAdEventCallback(MockAdEventListener(), mockAdEvent); + }); + + test('onAdErrorEvent', () async { + final MockAdsManager mockAdsManager = MockAdsManager(); + + late final void Function( + ima.AdErrorListener, + ima.AdErrorEvent, + ) onAdErrorCallback; + + final InteractiveMediaAdsProxy proxy = InteractiveMediaAdsProxy( + newAdEventListener: ({required dynamic onAdEvent}) { + return MockAdEventListener(); + }, + newAdErrorListener: ({ + required void Function( + ima.AdErrorListener, + ima.AdErrorEvent, + ) onAdError, + }) { + onAdErrorCallback = onAdError; + return MockAdErrorListener(); + }, + ); + + final AndroidAdsManager adsManager = AndroidAdsManager( + mockAdsManager, + proxy: proxy, + ); + await adsManager.setAdsManagerDelegate( + AndroidAdsManagerDelegate( + PlatformAdsManagerDelegateCreationParams( + onAdErrorEvent: expectAsync1((_) {}), + ), + ), + ); + + final MockAdErrorEvent mockErrorEvent = MockAdErrorEvent(); + final MockAdError mockError = MockAdError(); + when(mockError.errorType).thenReturn(ima.AdErrorType.load); + when(mockError.errorCode) + .thenReturn(ima.AdErrorCode.adsRequestNetworkError); + when(mockError.message).thenReturn('error message'); + when(mockErrorEvent.error).thenReturn(mockError); + onAdErrorCallback(MockAdErrorListener(), mockErrorEvent); + }); + }); +} diff --git a/packages/interactive_media_ads/test/android/ads_manager_test.mocks.dart b/packages/interactive_media_ads/test/android/ads_manager_test.mocks.dart new file mode 100644 index 000000000000..6006ba48f18a --- /dev/null +++ b/packages/interactive_media_ads/test/android/ads_manager_test.mocks.dart @@ -0,0 +1,585 @@ +// Mocks generated by Mockito 5.4.4 from annotations +// in interactive_media_ads/test/android/ads_manager_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i4; + +import 'package:interactive_media_ads/src/android/interactive_media_ads.g.dart' + as _i2; +import 'package:mockito/mockito.dart' as _i1; +import 'package:mockito/src/dummies.dart' as _i3; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakePigeonInstanceManager_0 extends _i1.SmartFake + implements _i2.PigeonInstanceManager { + _FakePigeonInstanceManager_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeAdError_1 extends _i1.SmartFake implements _i2.AdError { + _FakeAdError_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeAdErrorEvent_2 extends _i1.SmartFake implements _i2.AdErrorEvent { + _FakeAdErrorEvent_2( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeAdErrorListener_3 extends _i1.SmartFake + implements _i2.AdErrorListener { + _FakeAdErrorListener_3( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeAdEvent_4 extends _i1.SmartFake implements _i2.AdEvent { + _FakeAdEvent_4( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeAdEventListener_5 extends _i1.SmartFake + implements _i2.AdEventListener { + _FakeAdEventListener_5( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeAdsManager_6 extends _i1.SmartFake implements _i2.AdsManager { + _FakeAdsManager_6( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [AdError]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAdError extends _i1.Mock implements _i2.AdError { + @override + _i2.AdErrorCode get errorCode => (super.noSuchMethod( + Invocation.getter(#errorCode), + returnValue: _i2.AdErrorCode.adsPlayerWasNotProvided, + returnValueForMissingStub: _i2.AdErrorCode.adsPlayerWasNotProvided, + ) as _i2.AdErrorCode); + + @override + int get errorCodeNumber => (super.noSuchMethod( + Invocation.getter(#errorCodeNumber), + returnValue: 0, + returnValueForMissingStub: 0, + ) as int); + + @override + _i2.AdErrorType get errorType => (super.noSuchMethod( + Invocation.getter(#errorType), + returnValue: _i2.AdErrorType.load, + returnValueForMissingStub: _i2.AdErrorType.load, + ) as _i2.AdErrorType); + + @override + String get message => (super.noSuchMethod( + Invocation.getter(#message), + returnValue: _i3.dummyValue( + this, + Invocation.getter(#message), + ), + returnValueForMissingStub: _i3.dummyValue( + this, + Invocation.getter(#message), + ), + ) as String); + + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.AdError pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeAdError_1( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeAdError_1( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.AdError); +} + +/// A class which mocks [AdErrorEvent]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAdErrorEvent extends _i1.Mock implements _i2.AdErrorEvent { + @override + _i2.AdError get error => (super.noSuchMethod( + Invocation.getter(#error), + returnValue: _FakeAdError_1( + this, + Invocation.getter(#error), + ), + returnValueForMissingStub: _FakeAdError_1( + this, + Invocation.getter(#error), + ), + ) as _i2.AdError); + + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.AdErrorEvent pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeAdErrorEvent_2( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeAdErrorEvent_2( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.AdErrorEvent); +} + +/// A class which mocks [AdErrorListener]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAdErrorListener extends _i1.Mock implements _i2.AdErrorListener { + @override + void Function( + _i2.AdErrorListener, + _i2.AdErrorEvent, + ) get onAdError => (super.noSuchMethod( + Invocation.getter(#onAdError), + returnValue: ( + _i2.AdErrorListener pigeon_instance, + _i2.AdErrorEvent event, + ) {}, + returnValueForMissingStub: ( + _i2.AdErrorListener pigeon_instance, + _i2.AdErrorEvent event, + ) {}, + ) as void Function( + _i2.AdErrorListener, + _i2.AdErrorEvent, + )); + + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.AdErrorListener pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeAdErrorListener_3( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeAdErrorListener_3( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.AdErrorListener); +} + +/// A class which mocks [AdEvent]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAdEvent extends _i1.Mock implements _i2.AdEvent { + @override + _i2.AdEventType get type => (super.noSuchMethod( + Invocation.getter(#type), + returnValue: _i2.AdEventType.adBreakEnded, + returnValueForMissingStub: _i2.AdEventType.adBreakEnded, + ) as _i2.AdEventType); + + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.AdEvent pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeAdEvent_4( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeAdEvent_4( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.AdEvent); +} + +/// A class which mocks [AdEventListener]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAdEventListener extends _i1.Mock implements _i2.AdEventListener { + @override + void Function( + _i2.AdEventListener, + _i2.AdEvent, + ) get onAdEvent => (super.noSuchMethod( + Invocation.getter(#onAdEvent), + returnValue: ( + _i2.AdEventListener pigeon_instance, + _i2.AdEvent event, + ) {}, + returnValueForMissingStub: ( + _i2.AdEventListener pigeon_instance, + _i2.AdEvent event, + ) {}, + ) as void Function( + _i2.AdEventListener, + _i2.AdEvent, + )); + + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.AdEventListener pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeAdEventListener_5( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeAdEventListener_5( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.AdEventListener); +} + +/// A class which mocks [AdsManager]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAdsManager extends _i1.Mock implements _i2.AdsManager { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i4.Future discardAdBreak() => (super.noSuchMethod( + Invocation.method( + #discardAdBreak, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future pause() => (super.noSuchMethod( + Invocation.method( + #pause, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future start() => (super.noSuchMethod( + Invocation.method( + #start, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future> getAdCuePoints() => (super.noSuchMethod( + Invocation.method( + #getAdCuePoints, + [], + ), + returnValue: _i4.Future>.value([]), + returnValueForMissingStub: _i4.Future>.value([]), + ) as _i4.Future>); + + @override + _i4.Future resume() => (super.noSuchMethod( + Invocation.method( + #resume, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future skip() => (super.noSuchMethod( + Invocation.method( + #skip, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i2.AdsManager pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeAdsManager_6( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeAdsManager_6( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.AdsManager); + + @override + _i4.Future addAdErrorListener(_i2.AdErrorListener? errorListener) => + (super.noSuchMethod( + Invocation.method( + #addAdErrorListener, + [errorListener], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future addAdEventListener(_i2.AdEventListener? adEventListener) => + (super.noSuchMethod( + Invocation.method( + #addAdEventListener, + [adEventListener], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future destroy() => (super.noSuchMethod( + Invocation.method( + #destroy, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future init(_i2.AdsRenderingSettings? settings) => + (super.noSuchMethod( + Invocation.method( + #init, + [settings], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future focus() => (super.noSuchMethod( + Invocation.method( + #focus, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future<_i2.AdProgressInfo?> getAdProgressInfo() => (super.noSuchMethod( + Invocation.method( + #getAdProgressInfo, + [], + ), + returnValue: _i4.Future<_i2.AdProgressInfo?>.value(), + returnValueForMissingStub: _i4.Future<_i2.AdProgressInfo?>.value(), + ) as _i4.Future<_i2.AdProgressInfo?>); + + @override + _i4.Future<_i2.Ad?> getCurrentAd() => (super.noSuchMethod( + Invocation.method( + #getCurrentAd, + [], + ), + returnValue: _i4.Future<_i2.Ad?>.value(), + returnValueForMissingStub: _i4.Future<_i2.Ad?>.value(), + ) as _i4.Future<_i2.Ad?>); + + @override + _i4.Future removeAdErrorListener(_i2.AdErrorListener? errorListener) => + (super.noSuchMethod( + Invocation.method( + #removeAdErrorListener, + [errorListener], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future removeAdEventListener( + _i2.AdEventListener? adEventListener) => + (super.noSuchMethod( + Invocation.method( + #removeAdEventListener, + [adEventListener], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); +} diff --git a/packages/interactive_media_ads/test/android/content_progress_provider_test.dart b/packages/interactive_media_ads/test/android/content_progress_provider_test.dart new file mode 100644 index 000000000000..bf7885bb77c6 --- /dev/null +++ b/packages/interactive_media_ads/test/android/content_progress_provider_test.dart @@ -0,0 +1,49 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:interactive_media_ads/src/android/android_content_progress_provider.dart'; +import 'package:interactive_media_ads/src/android/interactive_media_ads.g.dart' + as ima; +import 'package:interactive_media_ads/src/android/interactive_media_ads_proxy.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; + +import 'content_progress_provider_test.mocks.dart'; + +@GenerateNiceMocks(>[ + MockSpec(), +]) +void main() { + group('AndroidContentProgressProvider', () { + test('setProgress', () async { + final MockContentProgressProvider mockContentProgressProvider = + MockContentProgressProvider(); + + final AndroidContentProgressProvider provider = + AndroidContentProgressProvider( + AndroidContentProgressProviderCreationParams( + proxy: InteractiveMediaAdsProxy( + newContentProgressProvider: () => mockContentProgressProvider, + newVideoProgressUpdate: ({ + required int currentTimeMs, + required int durationMs, + }) { + expect(currentTimeMs, 1000); + expect(durationMs, 10000); + return ima.VideoProgressUpdate.pigeon_detached(); + }, + ), + ), + ); + + await provider.setProgress( + progress: const Duration(seconds: 1), + duration: const Duration(seconds: 10), + ); + + verify(mockContentProgressProvider.setContentProgress(any)); + }); + }); +} diff --git a/packages/interactive_media_ads/test/android/content_progress_provider_test.mocks.dart b/packages/interactive_media_ads/test/android/content_progress_provider_test.mocks.dart new file mode 100644 index 000000000000..6d65d6475030 --- /dev/null +++ b/packages/interactive_media_ads/test/android/content_progress_provider_test.mocks.dart @@ -0,0 +1,97 @@ +// Mocks generated by Mockito 5.4.4 from annotations +// in interactive_media_ads/test/android/content_progress_provider_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i3; + +import 'package:interactive_media_ads/src/android/interactive_media_ads.g.dart' + as _i2; +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakePigeonInstanceManager_0 extends _i1.SmartFake + implements _i2.PigeonInstanceManager { + _FakePigeonInstanceManager_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeContentProgressProvider_1 extends _i1.SmartFake + implements _i2.ContentProgressProvider { + _FakeContentProgressProvider_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [ContentProgressProvider]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockContentProgressProvider extends _i1.Mock + implements _i2.ContentProgressProvider { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i3.Future setContentProgress(_i2.VideoProgressUpdate? update) => + (super.noSuchMethod( + Invocation.method( + #setContentProgress, + [update], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i2.ContentProgressProvider pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeContentProgressProvider_1( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeContentProgressProvider_1( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.ContentProgressProvider); +} diff --git a/packages/interactive_media_ads/test/content_progress_provider_test.dart b/packages/interactive_media_ads/test/content_progress_provider_test.dart new file mode 100644 index 000000000000..180d9ce0d015 --- /dev/null +++ b/packages/interactive_media_ads/test/content_progress_provider_test.dart @@ -0,0 +1,41 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:interactive_media_ads/src/content_progress_provider.dart'; +import 'package:interactive_media_ads/src/platform_interface/platform_content_progress_provider.dart'; + +import 'test_stubs.dart'; + +void main() { + test('setProgress', () async { + late final Duration callbackProgress; + late final Duration callbackDuration; + + final TestContentProgressProvider platformProvider = + TestContentProgressProvider( + const PlatformContentProgressProviderCreationParams(), + onSetProgress: ({ + required Duration progress, + required Duration duration, + }) async { + callbackProgress = progress; + callbackDuration = duration; + }, + ); + + final ContentProgressProvider provider = + ContentProgressProvider.fromPlatform( + platformProvider, + ); + + await provider.setProgress( + progress: const Duration(seconds: 1), + duration: const Duration(seconds: 10), + ); + + expect(callbackProgress, const Duration(seconds: 1)); + expect(callbackDuration, const Duration(seconds: 10)); + }); +} diff --git a/packages/interactive_media_ads/test/ios/ad_display_container_test.dart b/packages/interactive_media_ads/test/ios/ad_display_container_test.dart new file mode 100644 index 000000000000..b3eb09356394 --- /dev/null +++ b/packages/interactive_media_ads/test/ios/ad_display_container_test.dart @@ -0,0 +1,94 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import 'package:flutter/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:interactive_media_ads/src/ios/interactive_media_ads.g.dart'; +import 'package:interactive_media_ads/src/ios/interactive_media_ads_proxy.dart'; +import 'package:interactive_media_ads/src/ios/ios_ad_display_container.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; + +import 'ad_display_container_test.mocks.dart'; + +@GenerateNiceMocks(>[ + MockSpec(), + MockSpec(), + MockSpec(), +]) +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group('IOSAdDisplayContainer', () { + testWidgets('build with key', (WidgetTester tester) async { + final IOSAdDisplayContainer container = IOSAdDisplayContainer( + IOSAdDisplayContainerCreationParams( + key: const Key('testKey'), + onContainerAdded: (_) {}, + ), + ); + + await tester.pumpWidget(Builder( + builder: (BuildContext context) => container.build(context), + )); + + expect(find.byType(UiKitView), findsOneWidget); + expect(find.byKey(const Key('testKey')), findsOneWidget); + }); + + testWidgets('onContainerAdded is called', (WidgetTester tester) async { + late final void Function(UIViewController, bool) viewDidAppearCallback; + final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( + newUIViewController: ({ + void Function(UIViewController, bool)? viewDidAppear, + }) { + viewDidAppearCallback = viewDidAppear!; + + final PigeonInstanceManager instanceManager = PigeonInstanceManager( + onWeakReferenceRemoved: (_) {}, + ); + final UIView view = + UIView.pigeon_detached(pigeon_instanceManager: instanceManager); + instanceManager.addDartCreatedInstance(view); + + final MockUIViewController mockController = MockUIViewController(); + when(mockController.view).thenReturn(view); + return mockController; + }, + newIMAAdDisplayContainer: ({ + required UIView adContainer, + UIViewController? adContainerViewController, + }) => + MockIMAAdDisplayContainer(), + ); + + final Completer onContainerAddedCompleter = Completer(); + + final IOSAdDisplayContainer container = IOSAdDisplayContainer( + IOSAdDisplayContainerCreationParams( + onContainerAdded: (_) => onContainerAddedCompleter.complete(), + imaProxy: imaProxy, + ), + ); + + await tester.pumpWidget(Builder( + builder: (BuildContext context) => container.build(context), + )); + + final UiKitView view = + find.byType(UiKitView).evaluate().single.widget as UiKitView; + view.onPlatformViewCreated!.call(0); + + // Ensure onContainerAdded is not called until viewDidAppear is called. + expect(onContainerAddedCompleter.isCompleted, isFalse); + + viewDidAppearCallback(MockUIViewController(), true); + await tester.pumpAndSettle(); + + expect(onContainerAddedCompleter.isCompleted, isTrue); + }); + }); +} diff --git a/packages/interactive_media_ads/test/ios/ad_display_container_test.mocks.dart b/packages/interactive_media_ads/test/ios/ad_display_container_test.mocks.dart new file mode 100644 index 000000000000..cb8c37e05dc3 --- /dev/null +++ b/packages/interactive_media_ads/test/ios/ad_display_container_test.mocks.dart @@ -0,0 +1,220 @@ +// Mocks generated by Mockito 5.4.4 from annotations +// in interactive_media_ads/test/ios/ad_display_container_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'package:interactive_media_ads/src/ios/interactive_media_ads.g.dart' + as _i2; +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakePigeonInstanceManager_0 extends _i1.SmartFake + implements _i2.PigeonInstanceManager { + _FakePigeonInstanceManager_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeIMAAdDisplayContainer_1 extends _i1.SmartFake + implements _i2.IMAAdDisplayContainer { + _FakeIMAAdDisplayContainer_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeUIView_2 extends _i1.SmartFake implements _i2.UIView { + _FakeUIView_2( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeUIViewController_3 extends _i1.SmartFake + implements _i2.UIViewController { + _FakeUIViewController_3( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [IMAAdDisplayContainer]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockIMAAdDisplayContainer extends _i1.Mock + implements _i2.IMAAdDisplayContainer { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.IMAAdDisplayContainer pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeIMAAdDisplayContainer_1( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeIMAAdDisplayContainer_1( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.IMAAdDisplayContainer); +} + +/// A class which mocks [UIView]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockUIView extends _i1.Mock implements _i2.UIView { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.UIView pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeUIView_2( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeUIView_2( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.UIView); +} + +/// A class which mocks [UIViewController]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockUIViewController extends _i1.Mock implements _i2.UIViewController { + @override + _i2.UIView get view => (super.noSuchMethod( + Invocation.getter(#view), + returnValue: _FakeUIView_2( + this, + Invocation.getter(#view), + ), + returnValueForMissingStub: _FakeUIView_2( + this, + Invocation.getter(#view), + ), + ) as _i2.UIView); + + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.UIView pigeonVar_view() => (super.noSuchMethod( + Invocation.method( + #pigeonVar_view, + [], + ), + returnValue: _FakeUIView_2( + this, + Invocation.method( + #pigeonVar_view, + [], + ), + ), + returnValueForMissingStub: _FakeUIView_2( + this, + Invocation.method( + #pigeonVar_view, + [], + ), + ), + ) as _i2.UIView); + + @override + _i2.UIViewController pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeUIViewController_3( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeUIViewController_3( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.UIViewController); +} diff --git a/packages/interactive_media_ads/test/ios/ads_loader_test.dart b/packages/interactive_media_ads/test/ios/ads_loader_test.dart new file mode 100644 index 000000000000..633e96e9803f --- /dev/null +++ b/packages/interactive_media_ads/test/ios/ads_loader_test.dart @@ -0,0 +1,260 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:interactive_media_ads/src/ios/interactive_media_ads.g.dart' + as ima; +import 'package:interactive_media_ads/src/ios/interactive_media_ads_proxy.dart'; +import 'package:interactive_media_ads/src/ios/ios_ad_display_container.dart'; +import 'package:interactive_media_ads/src/ios/ios_ads_loader.dart'; +import 'package:interactive_media_ads/src/ios/ios_content_progress_provider.dart'; +import 'package:interactive_media_ads/src/platform_interface/platform_interface.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; + +import 'ads_loader_test.mocks.dart'; + +@GenerateNiceMocks(>[ + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), +]) +void main() { + group('IOSAdsLoader', () { + testWidgets('instantiate IOSAdsLoader', (WidgetTester tester) async { + final IOSAdDisplayContainer container = + await _pumpAdDisplayContainer(tester); + + IOSAdsLoader( + IOSAdsLoaderCreationParams( + container: container, + onAdsLoaded: (PlatformOnAdsLoadedData data) {}, + onAdsLoadError: (AdsLoadErrorData data) {}, + ), + ); + }); + + testWidgets('contentComplete', (WidgetTester tester) async { + final IOSAdDisplayContainer container = await _pumpAdDisplayContainer( + tester, + ); + + final MockIMAAdsLoader mockLoader = MockIMAAdsLoader(); + final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( + newIMAAdsLoader: ({ima.IMASettings? settings}) => mockLoader, + ); + + final IOSAdsLoader loader = IOSAdsLoader( + IOSAdsLoaderCreationParams( + container: container, + onAdsLoaded: (PlatformOnAdsLoadedData data) {}, + onAdsLoadError: (AdsLoadErrorData data) {}, + proxy: imaProxy, + ), + ); + + await loader.contentComplete(); + verify(mockLoader.contentComplete()); + }); + + testWidgets('requestAds', (WidgetTester tester) async { + final IOSAdDisplayContainer container = await _pumpAdDisplayContainer( + tester, + ); + + const String adTag = 'myAdTag'; + + final MockIMAAdsLoader mockLoader = MockIMAAdsLoader(); + final ima.IMAContentPlayhead contentPlayheadInstance = + ima.IMAContentPlayhead(); + final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( + newIMAAdsLoader: ({ima.IMASettings? settings}) => mockLoader, + newIMAAdsRequest: ({ + required String adTagUrl, + required ima.IMAAdDisplayContainer adDisplayContainer, + ima.IMAContentPlayhead? contentPlayhead, + }) { + expect(adTagUrl, adTag); + expect(adDisplayContainer, container.adDisplayContainer); + expect(contentPlayhead, contentPlayheadInstance); + return MockIMAAdsRequest(); + }, + newIMAContentPlayhead: () => contentPlayheadInstance, + ); + + final IOSAdsLoader loader = IOSAdsLoader( + IOSAdsLoaderCreationParams( + container: container, + onAdsLoaded: (PlatformOnAdsLoadedData data) {}, + onAdsLoadError: (AdsLoadErrorData data) {}, + proxy: imaProxy, + ), + ); + + final IOSContentProgressProvider provider = IOSContentProgressProvider( + IOSContentProgressProviderCreationParams(proxy: imaProxy), + ); + + await loader.requestAds(PlatformAdsRequest( + adTagUrl: adTag, + contentProgressProvider: provider, + )); + + verify(mockLoader.requestAds(any)); + }); + + testWidgets('onAdsLoaded', (WidgetTester tester) async { + final IOSAdDisplayContainer container = + await _pumpAdDisplayContainer(tester); + + late final void Function( + ima.IMAAdsLoaderDelegate, + ima.IMAAdsLoader, + ima.IMAAdsLoadedData, + ) adLoaderLoadedWithCallback; + + final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( + newIMAAdsLoader: ({ima.IMASettings? settings}) => MockIMAAdsLoader(), + newIMAAdsLoaderDelegate: ({ + required void Function( + ima.IMAAdsLoaderDelegate, + ima.IMAAdsLoader, + ima.IMAAdsLoadedData, + ) adLoaderLoadedWith, + required dynamic adsLoaderFailedWithErrorData, + }) { + adLoaderLoadedWithCallback = adLoaderLoadedWith; + return MockIMAAdsLoaderDelegate(); + }, + ); + + IOSAdsLoader( + IOSAdsLoaderCreationParams( + container: container, + onAdsLoaded: expectAsync1((_) {}), + onAdsLoadError: (AdsLoadErrorData data) {}, + proxy: imaProxy, + ), + ); + + adLoaderLoadedWithCallback( + MockIMAAdsLoaderDelegate(), + MockIMAAdsLoader(), + ima.IMAAdsLoadedData.pigeon_detached( + adsManager: MockIMAAdsManager(), + pigeon_instanceManager: ima.PigeonInstanceManager( + onWeakReferenceRemoved: (_) {}, + ), + ), + ); + }); + + testWidgets('onAdsLoadError', (WidgetTester tester) async { + final IOSAdDisplayContainer container = + await _pumpAdDisplayContainer(tester); + + late final void Function( + ima.IMAAdsLoaderDelegate, + ima.IMAAdsLoader, + ima.IMAAdLoadingErrorData, + ) adsLoaderFailedWithErrorDataCallback; + + final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( + newIMAAdsLoader: ({ima.IMASettings? settings}) => MockIMAAdsLoader(), + newIMAAdsLoaderDelegate: ({ + required dynamic adLoaderLoadedWith, + required void Function( + ima.IMAAdsLoaderDelegate, + ima.IMAAdsLoader, + ima.IMAAdLoadingErrorData, + ) adsLoaderFailedWithErrorData, + }) { + adsLoaderFailedWithErrorDataCallback = adsLoaderFailedWithErrorData; + return MockIMAAdsLoaderDelegate(); + }, + ); + + IOSAdsLoader( + IOSAdsLoaderCreationParams( + container: container, + onAdsLoaded: (PlatformOnAdsLoadedData data) {}, + onAdsLoadError: expectAsync1((AdsLoadErrorData data) { + expect(data.error.type, AdErrorType.loading); + expect(data.error.code, AdErrorCode.apiError); + }), + proxy: imaProxy, + ), + ); + + final ima.PigeonInstanceManager instanceManager = + ima.PigeonInstanceManager( + onWeakReferenceRemoved: (_) {}, + ); + + adsLoaderFailedWithErrorDataCallback( + MockIMAAdsLoaderDelegate(), + MockIMAAdsLoader(), + ima.IMAAdLoadingErrorData.pigeon_detached( + adError: ima.IMAAdError.pigeon_detached( + type: ima.AdErrorType.loadingFailed, + code: ima.AdErrorCode.apiError, + pigeon_instanceManager: instanceManager, + ), + pigeon_instanceManager: instanceManager, + ), + ); + }); + }); +} + +Future _pumpAdDisplayContainer( + WidgetTester tester) async { + final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( + newUIViewController: ({ + void Function(ima.UIViewController, bool)? viewDidAppear, + }) { + final ima.PigeonInstanceManager instanceManager = + ima.PigeonInstanceManager( + onWeakReferenceRemoved: (_) {}, + ); + final ima.UIView view = + ima.UIView.pigeon_detached(pigeon_instanceManager: instanceManager); + instanceManager.addDartCreatedInstance(view); + + final MockUIViewController mockController = MockUIViewController(); + viewDidAppear!.call(mockController, true); + when(mockController.view).thenReturn(view); + return mockController; + }, + newIMAAdDisplayContainer: ({ + required ima.UIView adContainer, + ima.UIViewController? adContainerViewController, + }) => + MockIMAAdDisplayContainer(), + ); + + final IOSAdDisplayContainer container = IOSAdDisplayContainer( + IOSAdDisplayContainerCreationParams( + onContainerAdded: expectAsync1((_) {}), + imaProxy: imaProxy, + ), + ); + + await tester.pumpWidget(Builder( + builder: (BuildContext context) => container.build(context), + )); + + final UiKitView view = + find.byType(UiKitView).evaluate().single.widget as UiKitView; + view.onPlatformViewCreated!.call(0); + + await tester.pumpAndSettle(const Duration(seconds: 1)); + + return container; +} diff --git a/packages/interactive_media_ads/test/ios/ads_loader_test.mocks.dart b/packages/interactive_media_ads/test/ios/ads_loader_test.mocks.dart new file mode 100644 index 000000000000..a19db9487f11 --- /dev/null +++ b/packages/interactive_media_ads/test/ios/ads_loader_test.mocks.dart @@ -0,0 +1,585 @@ +// Mocks generated by Mockito 5.4.4 from annotations +// in interactive_media_ads/test/ios/ads_loader_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i3; + +import 'package:interactive_media_ads/src/ios/interactive_media_ads.g.dart' + as _i2; +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakePigeonInstanceManager_0 extends _i1.SmartFake + implements _i2.PigeonInstanceManager { + _FakePigeonInstanceManager_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeIMAAdDisplayContainer_1 extends _i1.SmartFake + implements _i2.IMAAdDisplayContainer { + _FakeIMAAdDisplayContainer_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeIMAAdsLoader_2 extends _i1.SmartFake implements _i2.IMAAdsLoader { + _FakeIMAAdsLoader_2( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeIMAAdsLoaderDelegate_3 extends _i1.SmartFake + implements _i2.IMAAdsLoaderDelegate { + _FakeIMAAdsLoaderDelegate_3( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeIMAAdsManager_4 extends _i1.SmartFake implements _i2.IMAAdsManager { + _FakeIMAAdsManager_4( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeIMAAdsRequest_5 extends _i1.SmartFake implements _i2.IMAAdsRequest { + _FakeIMAAdsRequest_5( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeUIView_6 extends _i1.SmartFake implements _i2.UIView { + _FakeUIView_6( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeUIViewController_7 extends _i1.SmartFake + implements _i2.UIViewController { + _FakeUIViewController_7( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [IMAAdDisplayContainer]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockIMAAdDisplayContainer extends _i1.Mock + implements _i2.IMAAdDisplayContainer { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.IMAAdDisplayContainer pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeIMAAdDisplayContainer_1( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeIMAAdDisplayContainer_1( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.IMAAdDisplayContainer); +} + +/// A class which mocks [IMAAdsLoader]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockIMAAdsLoader extends _i1.Mock implements _i2.IMAAdsLoader { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i3.Future contentComplete() => (super.noSuchMethod( + Invocation.method( + #contentComplete, + [], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future requestAds(_i2.IMAAdsRequest? request) => + (super.noSuchMethod( + Invocation.method( + #requestAds, + [request], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future setDelegate(_i2.IMAAdsLoaderDelegate? delegate) => + (super.noSuchMethod( + Invocation.method( + #setDelegate, + [delegate], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i2.IMAAdsLoader pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeIMAAdsLoader_2( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeIMAAdsLoader_2( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.IMAAdsLoader); +} + +/// A class which mocks [IMAAdsLoaderDelegate]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockIMAAdsLoaderDelegate extends _i1.Mock + implements _i2.IMAAdsLoaderDelegate { + @override + void Function( + _i2.IMAAdsLoaderDelegate, + _i2.IMAAdsLoader, + _i2.IMAAdsLoadedData, + ) get adLoaderLoadedWith => (super.noSuchMethod( + Invocation.getter(#adLoaderLoadedWith), + returnValue: ( + _i2.IMAAdsLoaderDelegate pigeon_instance, + _i2.IMAAdsLoader loader, + _i2.IMAAdsLoadedData adsLoadedData, + ) {}, + returnValueForMissingStub: ( + _i2.IMAAdsLoaderDelegate pigeon_instance, + _i2.IMAAdsLoader loader, + _i2.IMAAdsLoadedData adsLoadedData, + ) {}, + ) as void Function( + _i2.IMAAdsLoaderDelegate, + _i2.IMAAdsLoader, + _i2.IMAAdsLoadedData, + )); + + @override + void Function( + _i2.IMAAdsLoaderDelegate, + _i2.IMAAdsLoader, + _i2.IMAAdLoadingErrorData, + ) get adsLoaderFailedWithErrorData => (super.noSuchMethod( + Invocation.getter(#adsLoaderFailedWithErrorData), + returnValue: ( + _i2.IMAAdsLoaderDelegate pigeon_instance, + _i2.IMAAdsLoader loader, + _i2.IMAAdLoadingErrorData adErrorData, + ) {}, + returnValueForMissingStub: ( + _i2.IMAAdsLoaderDelegate pigeon_instance, + _i2.IMAAdsLoader loader, + _i2.IMAAdLoadingErrorData adErrorData, + ) {}, + ) as void Function( + _i2.IMAAdsLoaderDelegate, + _i2.IMAAdsLoader, + _i2.IMAAdLoadingErrorData, + )); + + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.IMAAdsLoaderDelegate pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeIMAAdsLoaderDelegate_3( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeIMAAdsLoaderDelegate_3( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.IMAAdsLoaderDelegate); +} + +/// A class which mocks [IMAAdsManager]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockIMAAdsManager extends _i1.Mock implements _i2.IMAAdsManager { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i3.Future setDelegate(_i2.IMAAdsManagerDelegate? delegate) => + (super.noSuchMethod( + Invocation.method( + #setDelegate, + [delegate], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future initialize( + _i2.IMAAdsRenderingSettings? adsRenderingSettings) => + (super.noSuchMethod( + Invocation.method( + #initialize, + [adsRenderingSettings], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future start() => (super.noSuchMethod( + Invocation.method( + #start, + [], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future pause() => (super.noSuchMethod( + Invocation.method( + #pause, + [], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future resume() => (super.noSuchMethod( + Invocation.method( + #resume, + [], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future skip() => (super.noSuchMethod( + Invocation.method( + #skip, + [], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future discardAdBreak() => (super.noSuchMethod( + Invocation.method( + #discardAdBreak, + [], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future destroy() => (super.noSuchMethod( + Invocation.method( + #destroy, + [], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i2.IMAAdsManager pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeIMAAdsManager_4( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeIMAAdsManager_4( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.IMAAdsManager); +} + +/// A class which mocks [IMAAdsRequest]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockIMAAdsRequest extends _i1.Mock implements _i2.IMAAdsRequest { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.IMAAdsRequest pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeIMAAdsRequest_5( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeIMAAdsRequest_5( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.IMAAdsRequest); +} + +/// A class which mocks [UIView]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockUIView extends _i1.Mock implements _i2.UIView { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.UIView pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeUIView_6( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeUIView_6( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.UIView); +} + +/// A class which mocks [UIViewController]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockUIViewController extends _i1.Mock implements _i2.UIViewController { + @override + _i2.UIView get view => (super.noSuchMethod( + Invocation.getter(#view), + returnValue: _FakeUIView_6( + this, + Invocation.getter(#view), + ), + returnValueForMissingStub: _FakeUIView_6( + this, + Invocation.getter(#view), + ), + ) as _i2.UIView); + + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i2.UIView pigeonVar_view() => (super.noSuchMethod( + Invocation.method( + #pigeonVar_view, + [], + ), + returnValue: _FakeUIView_6( + this, + Invocation.method( + #pigeonVar_view, + [], + ), + ), + returnValueForMissingStub: _FakeUIView_6( + this, + Invocation.method( + #pigeonVar_view, + [], + ), + ), + ) as _i2.UIView); + + @override + _i2.UIViewController pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeUIViewController_7( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeUIViewController_7( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.UIViewController); +} diff --git a/packages/interactive_media_ads/test/ios/ads_manager_delegate_tests.dart b/packages/interactive_media_ads/test/ios/ads_manager_delegate_tests.dart new file mode 100644 index 000000000000..62174b25d87a --- /dev/null +++ b/packages/interactive_media_ads/test/ios/ads_manager_delegate_tests.dart @@ -0,0 +1,267 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:interactive_media_ads/src/ios/interactive_media_ads.g.dart' + as ima; +import 'package:interactive_media_ads/src/ios/interactive_media_ads_proxy.dart'; +import 'package:interactive_media_ads/src/ios/ios_ads_manager_delegate.dart'; +import 'package:interactive_media_ads/src/platform_interface/platform_interface.dart'; + +void main() { + group('IOSAdsManagerDelegate', () { + test('didReceiveAdEvent calls onAdEvent', () { + final ima.PigeonInstanceManager instanceManager = + ima.PigeonInstanceManager(onWeakReferenceRemoved: (_) {}); + + late final void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ima.IMAAdEvent, + ) didReceiveAdEventCallback; + + late final ima.IMAAdsManagerDelegate delegate; + final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( + newIMAAdsManagerDelegate: ({ + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ima.IMAAdEvent, + ) didReceiveAdEvent, + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ima.IMAAdError, + ) didReceiveAdError, + required void Function(ima.IMAAdsManagerDelegate, ima.IMAAdsManager) + didRequestContentPause, + required void Function(ima.IMAAdsManagerDelegate, ima.IMAAdsManager) + didRequestContentResume, + }) { + didReceiveAdEventCallback = didReceiveAdEvent; + delegate = ima.IMAAdsManagerDelegate.pigeon_detached( + didReceiveAdEvent: didReceiveAdEvent, + didReceiveAdError: didReceiveAdError, + didRequestContentPause: didRequestContentPause, + didRequestContentResume: didRequestContentResume, + pigeon_instanceManager: instanceManager, + ); + return delegate; + }, + ); + + final IOSAdsManagerDelegate adsManagerDelegate = IOSAdsManagerDelegate( + IOSAdsManagerDelegateCreationParams( + onAdEvent: expectAsync1((AdEvent event) { + expect(event.type, AdEventType.allAdsCompleted); + expect(event.adData, {'hello': 'world'}); + }), + proxy: imaProxy, + ), + ); + + // Calls the field because the value is instantiated lazily. + // ignore: unnecessary_statements + adsManagerDelegate.delegate; + + didReceiveAdEventCallback( + delegate, + ima.IMAAdsManager.pigeon_detached( + pigeon_instanceManager: instanceManager, + ), + ima.IMAAdEvent.pigeon_detached( + type: ima.AdEventType.allAdsCompleted, + typeString: 'typeString', + adData: const {'hello': 'world'}, + pigeon_instanceManager: instanceManager, + ), + ); + }); + + test('didRequestContentPause calls onAdEvent', () { + final ima.PigeonInstanceManager instanceManager = + ima.PigeonInstanceManager(onWeakReferenceRemoved: (_) {}); + + late final void Function(ima.IMAAdsManagerDelegate, ima.IMAAdsManager) + didRequestContentPauseCallback; + + late final ima.IMAAdsManagerDelegate delegate; + final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( + newIMAAdsManagerDelegate: ({ + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ima.IMAAdEvent, + ) didReceiveAdEvent, + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ima.IMAAdError, + ) didReceiveAdError, + required void Function(ima.IMAAdsManagerDelegate, ima.IMAAdsManager) + didRequestContentPause, + required void Function(ima.IMAAdsManagerDelegate, ima.IMAAdsManager) + didRequestContentResume, + }) { + didRequestContentPauseCallback = didRequestContentPause; + delegate = ima.IMAAdsManagerDelegate.pigeon_detached( + didReceiveAdEvent: didReceiveAdEvent, + didReceiveAdError: didReceiveAdError, + didRequestContentPause: didRequestContentPause, + didRequestContentResume: didRequestContentResume, + pigeon_instanceManager: instanceManager, + ); + return delegate; + }, + ); + + final IOSAdsManagerDelegate adsManagerDelegate = IOSAdsManagerDelegate( + IOSAdsManagerDelegateCreationParams( + onAdEvent: expectAsync1((AdEvent event) { + expect(event.type, AdEventType.contentPauseRequested); + }), + proxy: imaProxy, + ), + ); + + // Calls the field because the value is instantiated lazily. + // ignore: unnecessary_statements + adsManagerDelegate.delegate; + + didRequestContentPauseCallback( + delegate, + ima.IMAAdsManager.pigeon_detached( + pigeon_instanceManager: instanceManager, + ), + ); + }); + + test('didRequestContentResume calls onAdEvent', () { + final ima.PigeonInstanceManager instanceManager = + ima.PigeonInstanceManager(onWeakReferenceRemoved: (_) {}); + + late final void Function(ima.IMAAdsManagerDelegate, ima.IMAAdsManager) + didRequestContentResumeCallback; + + late final ima.IMAAdsManagerDelegate delegate; + final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( + newIMAAdsManagerDelegate: ({ + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ima.IMAAdEvent, + ) didReceiveAdEvent, + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ima.IMAAdError, + ) didReceiveAdError, + required void Function(ima.IMAAdsManagerDelegate, ima.IMAAdsManager) + didRequestContentPause, + required void Function(ima.IMAAdsManagerDelegate, ima.IMAAdsManager) + didRequestContentResume, + }) { + didRequestContentResumeCallback = didRequestContentResume; + delegate = ima.IMAAdsManagerDelegate.pigeon_detached( + didReceiveAdEvent: didReceiveAdEvent, + didReceiveAdError: didReceiveAdError, + didRequestContentPause: didRequestContentPause, + didRequestContentResume: didRequestContentResume, + pigeon_instanceManager: instanceManager, + ); + return delegate; + }, + ); + + final IOSAdsManagerDelegate adsManagerDelegate = IOSAdsManagerDelegate( + IOSAdsManagerDelegateCreationParams( + onAdEvent: expectAsync1((AdEvent event) { + expect(event.type, AdEventType.contentResumeRequested); + }), + proxy: imaProxy, + ), + ); + + // Calls the field because the value is instantiated lazily. + // ignore: unnecessary_statements + adsManagerDelegate.delegate; + + didRequestContentResumeCallback( + delegate, + ima.IMAAdsManager.pigeon_detached( + pigeon_instanceManager: instanceManager, + ), + ); + }); + + test('didReceiveAdError calls onAdErrorEvent', () { + final ima.PigeonInstanceManager instanceManager = + ima.PigeonInstanceManager(onWeakReferenceRemoved: (_) {}); + + late final void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ima.IMAAdError, + ) didReceiveAdErrorCallback; + + late final ima.IMAAdsManagerDelegate delegate; + final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( + newIMAAdsManagerDelegate: ({ + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ima.IMAAdEvent, + ) didReceiveAdEvent, + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ima.IMAAdError, + ) didReceiveAdError, + required void Function(ima.IMAAdsManagerDelegate, ima.IMAAdsManager) + didRequestContentPause, + required void Function(ima.IMAAdsManagerDelegate, ima.IMAAdsManager) + didRequestContentResume, + }) { + didReceiveAdErrorCallback = didReceiveAdError; + delegate = ima.IMAAdsManagerDelegate.pigeon_detached( + didReceiveAdEvent: didReceiveAdEvent, + didReceiveAdError: didReceiveAdError, + didRequestContentPause: didRequestContentPause, + didRequestContentResume: didRequestContentResume, + pigeon_instanceManager: instanceManager, + ); + return delegate; + }, + ); + + final IOSAdsManagerDelegate adsManagerDelegate = IOSAdsManagerDelegate( + IOSAdsManagerDelegateCreationParams( + onAdErrorEvent: expectAsync1((AdErrorEvent event) { + expect(event.error.type, AdErrorType.loading); + expect(event.error.code, AdErrorCode.apiError); + expect(event.error.message, 'error message'); + }), + proxy: imaProxy, + ), + ); + + // Calls the field because the value is instantiated lazily. + // ignore: unnecessary_statements + adsManagerDelegate.delegate; + + didReceiveAdErrorCallback( + delegate, + ima.IMAAdsManager.pigeon_detached( + pigeon_instanceManager: instanceManager, + ), + ima.IMAAdError.pigeon_detached( + type: ima.AdErrorType.loadingFailed, + code: ima.AdErrorCode.apiError, + message: 'error message', + pigeon_instanceManager: instanceManager, + ), + ); + }); + }); +} diff --git a/packages/interactive_media_ads/test/ios/ads_manager_test.dart b/packages/interactive_media_ads/test/ios/ads_manager_test.dart new file mode 100644 index 000000000000..06d1e1dab51e --- /dev/null +++ b/packages/interactive_media_ads/test/ios/ads_manager_test.dart @@ -0,0 +1,118 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:interactive_media_ads/src/ios/interactive_media_ads.g.dart' + as ima; +import 'package:interactive_media_ads/src/ios/interactive_media_ads_proxy.dart'; +import 'package:interactive_media_ads/src/ios/ios_ads_manager.dart'; +import 'package:interactive_media_ads/src/ios/ios_ads_manager_delegate.dart'; +import 'package:interactive_media_ads/src/platform_interface/platform_interface.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; + +import 'ads_manager_test.mocks.dart'; + +@GenerateNiceMocks(>[MockSpec()]) +void main() { + group('IOSAdsManager', () { + test('destroy', () { + final MockIMAAdsManager mockAdsManager = MockIMAAdsManager(); + final IOSAdsManager adsManager = IOSAdsManager(mockAdsManager); + adsManager.destroy(); + + verify(mockAdsManager.destroy()); + }); + + test('init', () { + final MockIMAAdsManager mockAdsManager = MockIMAAdsManager(); + final IOSAdsManager adsManager = IOSAdsManager(mockAdsManager); + adsManager.init(AdsManagerInitParams()); + + verify(mockAdsManager.initialize(null)); + }); + + test('start', () { + final MockIMAAdsManager mockAdsManager = MockIMAAdsManager(); + final IOSAdsManager adsManager = IOSAdsManager(mockAdsManager); + adsManager.start(AdsManagerStartParams()); + + verify(mockAdsManager.start()); + }); + + test('discardAdBreak', () { + final MockIMAAdsManager mockAdsManager = MockIMAAdsManager(); + final IOSAdsManager adsManager = IOSAdsManager(mockAdsManager); + adsManager.discardAdBreak(); + + verify(mockAdsManager.discardAdBreak()); + }); + + test('pause', () { + final MockIMAAdsManager mockAdsManager = MockIMAAdsManager(); + final IOSAdsManager adsManager = IOSAdsManager(mockAdsManager); + adsManager.pause(); + + verify(mockAdsManager.pause()); + }); + + test('skip', () { + final MockIMAAdsManager mockAdsManager = MockIMAAdsManager(); + final IOSAdsManager adsManager = IOSAdsManager(mockAdsManager); + adsManager.skip(); + + verify(mockAdsManager.skip()); + }); + + test('resume', () { + final MockIMAAdsManager mockAdsManager = MockIMAAdsManager(); + final IOSAdsManager adsManager = IOSAdsManager(mockAdsManager); + adsManager.resume(); + + verify(mockAdsManager.resume()); + }); + + test('setAdsManagerDelegate', () { + final MockIMAAdsManager mockAdsManager = MockIMAAdsManager(); + final IOSAdsManager adsManager = IOSAdsManager(mockAdsManager); + + late final ima.IMAAdsManagerDelegate delegate; + final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( + newIMAAdsManagerDelegate: ({ + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ima.IMAAdEvent, + ) didReceiveAdEvent, + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ima.IMAAdError, + ) didReceiveAdError, + required void Function(ima.IMAAdsManagerDelegate, ima.IMAAdsManager) + didRequestContentPause, + required void Function(ima.IMAAdsManagerDelegate, ima.IMAAdsManager) + didRequestContentResume, + }) { + delegate = ima.IMAAdsManagerDelegate.pigeon_detached( + didReceiveAdEvent: didReceiveAdEvent, + didReceiveAdError: didReceiveAdError, + didRequestContentPause: didRequestContentPause, + didRequestContentResume: didRequestContentResume, + pigeon_instanceManager: ima.PigeonInstanceManager( + onWeakReferenceRemoved: (_) {}, + ), + ); + return delegate; + }, + ); + + adsManager.setAdsManagerDelegate(IOSAdsManagerDelegate( + IOSAdsManagerDelegateCreationParams(proxy: imaProxy), + )); + + verify(mockAdsManager.setDelegate(delegate)); + }); + }); +} diff --git a/packages/interactive_media_ads/test/ios/ads_manager_test.mocks.dart b/packages/interactive_media_ads/test/ios/ads_manager_test.mocks.dart new file mode 100644 index 000000000000..9e891eb299f2 --- /dev/null +++ b/packages/interactive_media_ads/test/ios/ads_manager_test.mocks.dart @@ -0,0 +1,167 @@ +// Mocks generated by Mockito 5.4.4 from annotations +// in interactive_media_ads/test/ios/ads_manager_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i3; + +import 'package:interactive_media_ads/src/ios/interactive_media_ads.g.dart' + as _i2; +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakePigeonInstanceManager_0 extends _i1.SmartFake + implements _i2.PigeonInstanceManager { + _FakePigeonInstanceManager_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeIMAAdsManager_1 extends _i1.SmartFake implements _i2.IMAAdsManager { + _FakeIMAAdsManager_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [IMAAdsManager]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockIMAAdsManager extends _i1.Mock implements _i2.IMAAdsManager { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i3.Future setDelegate(_i2.IMAAdsManagerDelegate? delegate) => + (super.noSuchMethod( + Invocation.method( + #setDelegate, + [delegate], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future initialize( + _i2.IMAAdsRenderingSettings? adsRenderingSettings) => + (super.noSuchMethod( + Invocation.method( + #initialize, + [adsRenderingSettings], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future start() => (super.noSuchMethod( + Invocation.method( + #start, + [], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future pause() => (super.noSuchMethod( + Invocation.method( + #pause, + [], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future resume() => (super.noSuchMethod( + Invocation.method( + #resume, + [], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future skip() => (super.noSuchMethod( + Invocation.method( + #skip, + [], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future discardAdBreak() => (super.noSuchMethod( + Invocation.method( + #discardAdBreak, + [], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future destroy() => (super.noSuchMethod( + Invocation.method( + #destroy, + [], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i2.IMAAdsManager pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeIMAAdsManager_1( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeIMAAdsManager_1( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.IMAAdsManager); +} diff --git a/packages/interactive_media_ads/test/ios/content_progress_provider_test.dart b/packages/interactive_media_ads/test/ios/content_progress_provider_test.dart new file mode 100644 index 000000000000..80975174d3aa --- /dev/null +++ b/packages/interactive_media_ads/test/ios/content_progress_provider_test.dart @@ -0,0 +1,39 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:interactive_media_ads/src/ios/interactive_media_ads.g.dart'; +import 'package:interactive_media_ads/src/ios/interactive_media_ads_proxy.dart'; +import 'package:interactive_media_ads/src/ios/ios_content_progress_provider.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; + +import 'content_progress_provider_test.mocks.dart'; + +@GenerateNiceMocks(>[ + MockSpec(), +]) +void main() { + group('IOSContentProgressProvider', () { + test('setProgress', () async { + final MockIMAContentPlayhead mockContentPlayhead = + MockIMAContentPlayhead(); + + final IOSContentProgressProvider provider = IOSContentProgressProvider( + IOSContentProgressProviderCreationParams( + proxy: InteractiveMediaAdsProxy( + newIMAContentPlayhead: () => mockContentPlayhead, + ), + ), + ); + + await provider.setProgress( + progress: const Duration(seconds: 1), + duration: const Duration(seconds: 10), + ); + + verify(mockContentPlayhead.setCurrentTime(1.0)); + }); + }); +} diff --git a/packages/interactive_media_ads/test/ios/content_progress_provider_test.mocks.dart b/packages/interactive_media_ads/test/ios/content_progress_provider_test.mocks.dart new file mode 100644 index 000000000000..a82fb3fbade8 --- /dev/null +++ b/packages/interactive_media_ads/test/ios/content_progress_provider_test.mocks.dart @@ -0,0 +1,96 @@ +// Mocks generated by Mockito 5.4.4 from annotations +// in interactive_media_ads/test/ios/content_progress_provider_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i3; + +import 'package:interactive_media_ads/src/ios/interactive_media_ads.g.dart' + as _i2; +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakePigeonInstanceManager_0 extends _i1.SmartFake + implements _i2.PigeonInstanceManager { + _FakePigeonInstanceManager_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeIMAContentPlayhead_1 extends _i1.SmartFake + implements _i2.IMAContentPlayhead { + _FakeIMAContentPlayhead_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [IMAContentPlayhead]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockIMAContentPlayhead extends _i1.Mock + implements _i2.IMAContentPlayhead { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i3.Future setCurrentTime(double? timeInterval) => (super.noSuchMethod( + Invocation.method( + #setCurrentTime, + [timeInterval], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i2.IMAContentPlayhead pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeIMAContentPlayhead_1( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeIMAContentPlayhead_1( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.IMAContentPlayhead); +} diff --git a/packages/interactive_media_ads/test/test_stubs.dart b/packages/interactive_media_ads/test/test_stubs.dart index fd59fb3073f1..328f58f46995 100644 --- a/packages/interactive_media_ads/test/test_stubs.dart +++ b/packages/interactive_media_ads/test/test_stubs.dart @@ -11,6 +11,7 @@ final class TestInteractiveMediaAdsPlatform required this.onCreatePlatformAdsLoader, required this.onCreatePlatformAdsManagerDelegate, required this.onCreatePlatformAdDisplayContainer, + required this.onCreatePlatformContentProgressProvider, }); PlatformAdsLoader Function(PlatformAdsLoaderCreationParams params) @@ -24,6 +25,10 @@ final class TestInteractiveMediaAdsPlatform PlatformAdDisplayContainerCreationParams params, ) onCreatePlatformAdDisplayContainer; + PlatformContentProgressProvider Function( + PlatformContentProgressProviderCreationParams params, + ) onCreatePlatformContentProgressProvider; + @override PlatformAdsLoader createPlatformAdsLoader( PlatformAdsLoaderCreationParams params, @@ -44,6 +49,13 @@ final class TestInteractiveMediaAdsPlatform ) { return onCreatePlatformAdDisplayContainer(params); } + + @override + PlatformContentProgressProvider createPlatformContentProgressProvider( + PlatformContentProgressProviderCreationParams params, + ) { + return onCreatePlatformContentProgressProvider(params); + } } final class TestPlatformAdDisplayContainer extends PlatformAdDisplayContainer { @@ -69,7 +81,7 @@ final class TestPlatformAdsLoader extends PlatformAdsLoader { Future Function() onContentComplete; - Future Function(AdsRequest request) onRequestAds; + Future Function(PlatformAdsRequest request) onRequestAds; @override Future contentComplete() async { @@ -77,7 +89,7 @@ final class TestPlatformAdsLoader extends PlatformAdsLoader { } @override - Future requestAds(AdsRequest request) async { + Future requestAds(PlatformAdsRequest request) async { return onRequestAds(request); } } @@ -92,6 +104,10 @@ class TestAdsManager extends PlatformAdsManager { this.onSetAdsManagerDelegate, this.onStart, this.onDestroy, + this.onDiscardAdBreak, + this.onPause, + this.onResume, + this.onSkip, }); Future Function(AdsManagerInitParams params)? onInit; @@ -101,6 +117,14 @@ class TestAdsManager extends PlatformAdsManager { Future Function(AdsManagerStartParams params)? onStart; + Future Function()? onDiscardAdBreak; + + Future Function()? onPause; + + Future Function()? onResume; + + Future Function()? onSkip; + Future Function()? onDestroy; @override @@ -124,4 +148,44 @@ class TestAdsManager extends PlatformAdsManager { Future destroy() async { return onDestroy?.call(); } + + @override + Future discardAdBreak() async { + return onDiscardAdBreak?.call(); + } + + @override + Future pause() async { + return onPause?.call(); + } + + @override + Future resume() async { + return onResume?.call(); + } + + @override + Future skip() async { + return onSkip?.call(); + } +} + +class TestContentProgressProvider extends PlatformContentProgressProvider { + TestContentProgressProvider( + super.params, { + this.onSetProgress, + }) : super.implementation(); + + Future Function({ + required Duration progress, + required Duration duration, + })? onSetProgress; + + @override + Future setProgress({ + required Duration progress, + required Duration duration, + }) async { + return onSetProgress?.call(progress: progress, duration: duration); + } } diff --git a/packages/interactive_media_ads/test/version_test.dart b/packages/interactive_media_ads/test/version_test.dart new file mode 100644 index 000000000000..a04edc460620 --- /dev/null +++ b/packages/interactive_media_ads/test/version_test.dart @@ -0,0 +1,47 @@ +// 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:io'; + +import 'package:flutter_test/flutter_test.dart'; + +void main() { + test('AdsRequestProxyApi.pluginVersion matches pubspec version', () { + final String pubspecVersion = _getPubspecVersion(); + + final String adsRequestProxyApiPath = + '${Directory.current.path}/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsRequestProxyApi.kt'; + final String apiFileAsString = + File(adsRequestProxyApiPath).readAsStringSync(); + + expect( + apiFileAsString, + contains('const val pluginVersion = "$pubspecVersion"'), + ); + }); + + test('AdsRequestProxyAPIDelegate.pluginVersion matches pubspec version', () { + final String pubspecVersion = _getPubspecVersion(); + + final String adsRequestProxyApiDelegatePath = + '${Directory.current.path}/ios/interactive_media_ads/Sources/interactive_media_ads/AdsRequestProxyAPIDelegate.swift'; + final String apiFileAsString = + File(adsRequestProxyApiDelegatePath).readAsStringSync(); + + expect( + apiFileAsString, + contains('static let pluginVersion = "$pubspecVersion"'), + ); + }); +} + +String _getPubspecVersion() { + final String pubspecPath = '${Directory.current.path}/pubspec.yaml'; + final String pubspec = File(pubspecPath).readAsStringSync(); + + final RegExp regex = RegExp(r'version:\s*(.*?) #'); + final RegExpMatch? match = regex.firstMatch(pubspec); + + return match!.group(1)!.trim(); +} diff --git a/packages/ios_platform_images/CHANGELOG.md b/packages/ios_platform_images/CHANGELOG.md index e85c36769902..61e3b597f50b 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.19/Dart 3.3. + ## 0.2.4 * Updates minimum iOS version to 12.0 and minimum Flutter version to 3.16.6. diff --git a/packages/ios_platform_images/example/ios/Podfile b/packages/ios_platform_images/example/ios/Podfile index d97f17e223fb..e549ee22f3b0 100644 --- a/packages/ios_platform_images/example/ios/Podfile +++ b/packages/ios_platform_images/example/ios/Podfile @@ -29,7 +29,6 @@ flutter_ios_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) target 'RunnerTests' do diff --git a/packages/ios_platform_images/example/ios/RunnerTests/UIImage+ios_platform_imagesTests.m b/packages/ios_platform_images/example/ios/RunnerTests/UIImage+ios_platform_imagesTests.m index d107ac4bd34f..4e176e84a5ca 100644 --- a/packages/ios_platform_images/example/ios/RunnerTests/UIImage+ios_platform_imagesTests.m +++ b/packages/ios_platform_images/example/ios/RunnerTests/UIImage+ios_platform_imagesTests.m @@ -21,7 +21,7 @@ - (void)testMultiResolutionImageUsesBest { const double height2x = 250; // The height of assets/2.0x/multisize.png. // Loading assets should get the best available asset for the screen scale when resolution-aware // assets are available (and the example app has 1x and 2x for this asset). See - // https://docs.flutter.dev/ui/assets/assets-and-images#resolution-aware + // https://flutter.dev/to/resolution-aware-images if (UIScreen.mainScreen.scale > 1.0) { XCTAssertEqualWithAccuracy(image.size.height, height2x, 0.00001); } else { diff --git a/packages/ios_platform_images/example/pubspec.yaml b/packages/ios_platform_images/example/pubspec.yaml index 9ed52b1b8100..65fa44b71154 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.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: cupertino_icons: ^1.0.2 diff --git a/packages/ios_platform_images/ios/ios_platform_images/Sources/ios_platform_images/UIImageIosPlatformImages.swift b/packages/ios_platform_images/ios/ios_platform_images/Sources/ios_platform_images/UIImageIosPlatformImages.swift index 2e9cdefe6731..af7f34972228 100644 --- a/packages/ios_platform_images/ios/ios_platform_images/Sources/ios_platform_images/UIImageIosPlatformImages.swift +++ b/packages/ios_platform_images/ios/ios_platform_images/Sources/ios_platform_images/UIImageIosPlatformImages.swift @@ -19,7 +19,7 @@ import UIKit /// `[UIImage flutterImageWithName:@"assets/foo.png"]` will load /// "assets/2.0x/foo.png". /// - /// See also https://flutter.dev/docs/development/ui/assets-and-images + /// See also https://docs.flutter.dev/ui/assets/assets-and-images /// /// Note: We don't yet support images from package dependencies (ex. /// `AssetImage('icons/heart.png', package: 'my_icons')`). diff --git a/packages/ios_platform_images/pubspec.yaml b/packages/ios_platform_images/pubspec.yaml index e17ed82f26c2..3d2fb1cb064f 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 environment: - sdk: ^3.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: diff --git a/packages/local_auth/local_auth/CHANGELOG.md b/packages/local_auth/local_auth/CHANGELOG.md index b7b2c263da5f..a830dbc1cd6f 100644 --- a/packages/local_auth/local_auth/CHANGELOG.md +++ b/packages/local_auth/local_auth/CHANGELOG.md @@ -1,3 +1,11 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + +## 2.3.0 + +* Adds endorsed macOS support. + ## 2.2.0 * Switches endorsed iOS implementation to `local_auth_darwin`. diff --git a/packages/local_auth/local_auth/README.md b/packages/local_auth/local_auth/README.md index 78c0b2038a19..1fff94350f5a 100644 --- a/packages/local_auth/local_auth/README.md +++ b/packages/local_auth/local_auth/README.md @@ -8,9 +8,9 @@ the user. On supported devices, this includes authentication with biometrics such as fingerprint or facial recognition. -| | Android | iOS | Windows | -|-------------|-----------|-------|-------------| -| **Support** | SDK 16+\* | 12.0+ | Windows 10+ | +| | Android | iOS | macOS | Windows | +|-------------|-----------|-------|--------|-------------| +| **Support** | SDK 16+\* | 12.0+ | 10.14+ | Windows 10+ | ## Usage diff --git a/packages/local_auth/local_auth/example/android/app/build.gradle b/packages/local_auth/local_auth/example/android/app/build.gradle index f075d5813cf9..c564af855289 100644 --- a/packages/local_auth/local_auth/example/android/app/build.gradle +++ b/packages/local_auth/local_auth/example/android/app/build.gradle @@ -36,7 +36,6 @@ android { versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - multiDexEnabled true } buildTypes { diff --git a/packages/local_auth/local_auth/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/local_auth/local_auth/example/android/app/gradle/wrapper/gradle-wrapper.properties index 609ab8e6c8b5..d951fac2bf31 100644 --- a/packages/local_auth/local_auth/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ b/packages/local_auth/local_auth/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/packages/local_auth/local_auth/example/android/build.gradle b/packages/local_auth/local_auth/example/android/build.gradle index cec92de922cf..0bed8906c094 100644 --- a/packages/local_auth/local_auth/example/android/build.gradle +++ b/packages/local_auth/local_auth/example/android/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath 'com.android.tools.build:gradle:8.5.2' } } diff --git a/packages/local_auth/local_auth/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/local_auth/local_auth/example/android/gradle/wrapper/gradle-wrapper.properties index a4f684d08a81..155a12c6d657 100644 --- a/packages/local_auth/local_auth/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/local_auth/local_auth/example/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/local_auth/local_auth/example/macos/.gitignore b/packages/local_auth/local_auth/example/macos/.gitignore new file mode 100644 index 000000000000..746adbb6b9e1 --- /dev/null +++ b/packages/local_auth/local_auth/example/macos/.gitignore @@ -0,0 +1,7 @@ +# Flutter-related +**/Flutter/ephemeral/ +**/Pods/ + +# Xcode-related +**/dgph +**/xcuserdata/ diff --git a/packages/local_auth/local_auth/example/macos/Flutter/Flutter-Debug.xcconfig b/packages/local_auth/local_auth/example/macos/Flutter/Flutter-Debug.xcconfig new file mode 100644 index 000000000000..4b81f9b2d200 --- /dev/null +++ b/packages/local_auth/local_auth/example/macos/Flutter/Flutter-Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/packages/local_auth/local_auth/example/macos/Flutter/Flutter-Release.xcconfig b/packages/local_auth/local_auth/example/macos/Flutter/Flutter-Release.xcconfig new file mode 100644 index 000000000000..5caa9d1579e4 --- /dev/null +++ b/packages/local_auth/local_auth/example/macos/Flutter/Flutter-Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/packages/local_auth/local_auth/example/macos/Podfile b/packages/local_auth/local_auth/example/macos/Podfile new file mode 100644 index 000000000000..ae77cc1d4269 --- /dev/null +++ b/packages/local_auth/local_auth/example/macos/Podfile @@ -0,0 +1,39 @@ +platform :osx, '10.14' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_macos_podfile_setup + +target 'Runner' do + use_frameworks! + + flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_macos_build_settings(target) + end +end diff --git a/packages/local_auth/local_auth/example/macos/Runner.xcodeproj/project.pbxproj b/packages/local_auth/local_auth/example/macos/Runner.xcodeproj/project.pbxproj new file mode 100644 index 000000000000..f0ddcb528e43 --- /dev/null +++ b/packages/local_auth/local_auth/example/macos/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,650 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXAggregateTarget section */ + 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; + buildPhases = ( + 33CC111E2044C6BF0003C045 /* ShellScript */, + ); + dependencies = ( + ); + name = "Flutter Assemble"; + productName = FLX; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 1BC2DC09A8E94B377F42CF98 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AE72E01DCF4158EA81E6F9AC /* Pods_Runner.framework */; }; + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC111A2044C6BA0003C045; + remoteInfo = FLX; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 33CC110E2044A8840003C045 /* Bundle Framework */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Bundle Framework"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 09A2351319B85EBB2712065D /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; + 206B53A30EED4EAA41637C9C /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; + 33CC10ED2044A3C60003C045 /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; + 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; + 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; + 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; + 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 48ED168D9C105B30C2229B4F /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 84B2F8C324D0BC6169CF7C4A /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; + 8FAE613E79CDA0335C27BB71 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 941800DCC46CF3A6E134F013 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + AE72E01DCF4158EA81E6F9AC /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C0EE013DE4EFF82F20A45B81 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 33CC10EA2044A3C60003C045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1BC2DC09A8E94B377F42CF98 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 33BA886A226E78AF003329D5 /* Configs */ = { + isa = PBXGroup; + children = ( + 33E5194F232828860026EE4D /* AppInfo.xcconfig */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, + ); + path = Configs; + sourceTree = ""; + }; + 33CC10E42044A3C60003C045 = { + isa = PBXGroup; + children = ( + 33FAB671232836740065AC1E /* Runner */, + 33CEB47122A05771004F2AC0 /* Flutter */, + 33CC10EE2044A3C60003C045 /* Products */, + D73912EC22F37F3D000D13A0 /* Frameworks */, + F749529E0EAC4E62673B56C1 /* Pods */, + ); + sourceTree = ""; + }; + 33CC10EE2044A3C60003C045 /* Products */ = { + isa = PBXGroup; + children = ( + 33CC10ED2044A3C60003C045 /* example.app */, + ); + name = Products; + sourceTree = ""; + }; + 33CC11242044D66E0003C045 /* Resources */ = { + isa = PBXGroup; + children = ( + 33CC10F22044A3C60003C045 /* Assets.xcassets */, + 33CC10F42044A3C60003C045 /* MainMenu.xib */, + 33CC10F72044A3C60003C045 /* Info.plist */, + ); + name = Resources; + path = ..; + sourceTree = ""; + }; + 33CEB47122A05771004F2AC0 /* Flutter */ = { + isa = PBXGroup; + children = ( + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, + ); + path = Flutter; + sourceTree = ""; + }; + 33FAB671232836740065AC1E /* Runner */ = { + isa = PBXGroup; + children = ( + 33CC10F02044A3C60003C045 /* AppDelegate.swift */, + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, + 33E51913231747F40026EE4D /* DebugProfile.entitlements */, + 33E51914231749380026EE4D /* Release.entitlements */, + 33CC11242044D66E0003C045 /* Resources */, + 33BA886A226E78AF003329D5 /* Configs */, + ); + path = Runner; + sourceTree = ""; + }; + D73912EC22F37F3D000D13A0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + AE72E01DCF4158EA81E6F9AC /* Pods_Runner.framework */, + 941800DCC46CF3A6E134F013 /* Pods_RunnerTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + F749529E0EAC4E62673B56C1 /* Pods */ = { + isa = PBXGroup; + children = ( + C0EE013DE4EFF82F20A45B81 /* Pods-Runner.debug.xcconfig */, + 8FAE613E79CDA0335C27BB71 /* Pods-Runner.release.xcconfig */, + 48ED168D9C105B30C2229B4F /* Pods-Runner.profile.xcconfig */, + 206B53A30EED4EAA41637C9C /* Pods-RunnerTests.debug.xcconfig */, + 84B2F8C324D0BC6169CF7C4A /* Pods-RunnerTests.release.xcconfig */, + 09A2351319B85EBB2712065D /* Pods-RunnerTests.profile.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 33CC10EC2044A3C60003C045 /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 43C24571E48B9A5309B915D5 /* [CP] Check Pods Manifest.lock */, + 33CC10E92044A3C60003C045 /* Sources */, + 33CC10EA2044A3C60003C045 /* Frameworks */, + 33CC10EB2044A3C60003C045 /* Resources */, + 33CC110E2044A8840003C045 /* Bundle Framework */, + 3399D490228B24CF009A79C7 /* ShellScript */, + BC39F33EA96004E670EDC9C7 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 33CC11202044C79F0003C045 /* PBXTargetDependency */, + ); + name = Runner; + productName = Runner; + productReference = 33CC10ED2044A3C60003C045 /* example.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 33CC10E52044A3C60003C045 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 33CC10EC2044A3C60003C045 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1100; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 1; + }; + }; + }; + 33CC111A2044C6BA0003C045 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Manual; + }; + }; + }; + buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 33CC10E42044A3C60003C045; + productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 33CC10EC2044A3C60003C045 /* Runner */, + 33CC111A2044C6BA0003C045 /* Flutter Assemble */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 33CC10EB2044A3C60003C045 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3399D490228B24CF009A79C7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; + }; + 33CC111E2044C6BF0003C045 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + Flutter/ephemeral/FlutterInputs.xcfilelist, + ); + inputPaths = ( + Flutter/ephemeral/tripwire, + ); + outputFileListPaths = ( + Flutter/ephemeral/FlutterOutputs.xcfilelist, + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; + }; + 43C24571E48B9A5309B915D5 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + BC39F33EA96004E670EDC9C7 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 33CC10E92044A3C60003C045 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; + targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 33CC10F52044A3C60003C045 /* Base */, + ); + name = MainMenu.xib; + path = Runner; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 338D0CE9231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.14; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Profile; + }; + 338D0CEA231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Profile; + }; + 338D0CEB231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Profile; + }; + 33CC10F92044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.14; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 33CC10FA2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.14; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 33CC10FC2044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 33CC10FD2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 33CC111C2044C6BA0003C045 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 33CC111D2044C6BA0003C045 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10F92044A3C60003C045 /* Debug */, + 33CC10FA2044A3C60003C045 /* Release */, + 338D0CE9231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10FC2044A3C60003C045 /* Debug */, + 33CC10FD2044A3C60003C045 /* Release */, + 338D0CEA231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC111C2044C6BA0003C045 /* Debug */, + 33CC111D2044C6BA0003C045 /* Release */, + 338D0CEB231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 33CC10E52044A3C60003C045 /* Project object */; +} diff --git a/packages/local_auth/local_auth/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/local_auth/local_auth/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000000..18d981003d68 --- /dev/null +++ b/packages/local_auth/local_auth/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/local_auth/local_auth/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/local_auth/local_auth/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 000000000000..15368eccb25a --- /dev/null +++ b/packages/local_auth/local_auth/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/local_auth/local_auth/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/packages/local_auth/local_auth/example/macos/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000000..21a3cc14c74e --- /dev/null +++ b/packages/local_auth/local_auth/example/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/packages/local_auth/local_auth/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/local_auth/local_auth/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000000..18d981003d68 --- /dev/null +++ b/packages/local_auth/local_auth/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/local_auth/local_auth/example/macos/Runner/AppDelegate.swift b/packages/local_auth/local_auth/example/macos/Runner/AppDelegate.swift new file mode 100644 index 000000000000..5cec4c48f620 --- /dev/null +++ b/packages/local_auth/local_auth/example/macos/Runner/AppDelegate.swift @@ -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 Cocoa +import FlutterMacOS + +@NSApplicationMain +class AppDelegate: FlutterAppDelegate { + override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } +} diff --git a/packages/local_auth/local_auth/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/local_auth/local_auth/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000000..a2ec33f19f11 --- /dev/null +++ b/packages/local_auth/local_auth/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_16.png", + "scale" : "1x" + }, + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "2x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "1x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_64.png", + "scale" : "2x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_128.png", + "scale" : "1x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "2x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_1024.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/packages/local_auth/local_auth/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/packages/local_auth/local_auth/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png new file mode 100644 index 000000000000..82b6f9d9a33e Binary files /dev/null and b/packages/local_auth/local_auth/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ diff --git a/packages/local_auth/local_auth/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/packages/local_auth/local_auth/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png new file mode 100644 index 000000000000..13b35eba55c6 Binary files /dev/null and b/packages/local_auth/local_auth/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/packages/local_auth/local_auth/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/packages/local_auth/local_auth/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png new file mode 100644 index 000000000000..0a3f5fa40fb3 Binary files /dev/null and b/packages/local_auth/local_auth/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ diff --git a/packages/local_auth/local_auth/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/packages/local_auth/local_auth/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png new file mode 100644 index 000000000000..bdb57226d5f2 Binary files /dev/null and b/packages/local_auth/local_auth/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/packages/local_auth/local_auth/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/packages/local_auth/local_auth/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png new file mode 100644 index 000000000000..f083318e09ca Binary files /dev/null and b/packages/local_auth/local_auth/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ diff --git a/packages/local_auth/local_auth/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/packages/local_auth/local_auth/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png new file mode 100644 index 000000000000..326c0e72c9d8 Binary files /dev/null and b/packages/local_auth/local_auth/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/packages/local_auth/local_auth/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/packages/local_auth/local_auth/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png new file mode 100644 index 000000000000..2f1632cfddf3 Binary files /dev/null and b/packages/local_auth/local_auth/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/packages/local_auth/local_auth/example/macos/Runner/Base.lproj/MainMenu.xib b/packages/local_auth/local_auth/example/macos/Runner/Base.lproj/MainMenu.xib new file mode 100644 index 000000000000..80e867a4e06b --- /dev/null +++ b/packages/local_auth/local_auth/example/macos/Runner/Base.lproj/MainMenu.xib @@ -0,0 +1,343 @@ + + + + + + + + + + + + + + + + + + + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/local_auth/local_auth/example/macos/Runner/Configs/AppInfo.xcconfig b/packages/local_auth/local_auth/example/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 000000000000..bdb88cb7b7e3 --- /dev/null +++ b/packages/local_auth/local_auth/example/macos/Runner/Configs/AppInfo.xcconfig @@ -0,0 +1,14 @@ +// Application-level settings for the Runner target. +// +// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the +// future. If not, the values below would default to using the project name when this becomes a +// 'flutter create' template. + +// The application's name. By default this is also the title of the Flutter window. +PRODUCT_NAME = example + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.example + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2024 dev.flutter.plugins. All rights reserved. diff --git a/packages/local_auth/local_auth/example/macos/Runner/Configs/Debug.xcconfig b/packages/local_auth/local_auth/example/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 000000000000..36b0fd9464f4 --- /dev/null +++ b/packages/local_auth/local_auth/example/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/packages/local_auth/local_auth/example/macos/Runner/Configs/Release.xcconfig b/packages/local_auth/local_auth/example/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 000000000000..dff4f49561c8 --- /dev/null +++ b/packages/local_auth/local_auth/example/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/packages/local_auth/local_auth/example/macos/Runner/Configs/Warnings.xcconfig b/packages/local_auth/local_auth/example/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 000000000000..42bcbf4780b1 --- /dev/null +++ b/packages/local_auth/local_auth/example/macos/Runner/Configs/Warnings.xcconfig @@ -0,0 +1,13 @@ +WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings +GCC_WARN_UNDECLARED_SELECTOR = YES +CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES +CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_PRAGMA_PACK = YES +CLANG_WARN_STRICT_PROTOTYPES = YES +CLANG_WARN_COMMA = YES +GCC_WARN_STRICT_SELECTOR_MATCH = YES +CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES +GCC_WARN_SHADOW = YES +CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/packages/local_auth/local_auth/example/macos/Runner/DebugProfile.entitlements b/packages/local_auth/local_auth/example/macos/Runner/DebugProfile.entitlements new file mode 100644 index 000000000000..dddb8a30c851 --- /dev/null +++ b/packages/local_auth/local_auth/example/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,12 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.cs.allow-jit + + com.apple.security.network.server + + + diff --git a/packages/local_auth/local_auth/example/macos/Runner/Info.plist b/packages/local_auth/local_auth/example/macos/Runner/Info.plist new file mode 100644 index 000000000000..4789daa6a443 --- /dev/null +++ b/packages/local_auth/local_auth/example/macos/Runner/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + $(PRODUCT_COPYRIGHT) + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/packages/local_auth/local_auth/example/macos/Runner/MainFlutterWindow.swift b/packages/local_auth/local_auth/example/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 000000000000..f21908966e95 --- /dev/null +++ b/packages/local_auth/local_auth/example/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,19 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + + super.awakeFromNib() + } +} diff --git a/packages/local_auth/local_auth/example/macos/Runner/Release.entitlements b/packages/local_auth/local_auth/example/macos/Runner/Release.entitlements new file mode 100644 index 000000000000..852fa1a4728a --- /dev/null +++ b/packages/local_auth/local_auth/example/macos/Runner/Release.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.app-sandbox + + + diff --git a/packages/local_auth/local_auth/example/pubspec.yaml b/packages/local_auth/local_auth/example/pubspec.yaml index 73265f90cd33..8bcf50db130d 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.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/local_auth/local_auth/pubspec.yaml b/packages/local_auth/local_auth/pubspec.yaml index f36bc4049def..0ebc00c4d3d4 100644 --- a/packages/local_auth/local_auth/pubspec.yaml +++ b/packages/local_auth/local_auth/pubspec.yaml @@ -3,11 +3,11 @@ description: Flutter plugin for Android and iOS devices to allow local authentication via fingerprint, touch ID, face ID, passcode, pin, or pattern. repository: https://github.com/flutter/packages/tree/main/packages/local_auth/local_auth issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+local_auth%22 -version: 2.2.0 +version: 2.3.0 environment: - sdk: ^3.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -16,6 +16,8 @@ flutter: default_package: local_auth_android ios: default_package: local_auth_darwin + macos: + default_package: local_auth_darwin windows: default_package: local_auth_windows @@ -23,7 +25,7 @@ dependencies: flutter: sdk: flutter local_auth_android: ^1.0.0 - local_auth_darwin: ^1.2.1 + local_auth_darwin: ^1.4.0 local_auth_platform_interface: ^1.0.1 local_auth_windows: ^1.0.0 @@ -32,7 +34,7 @@ dev_dependencies: sdk: flutter integration_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 plugin_platform_interface: ^2.1.7 topics: diff --git a/packages/local_auth/local_auth_android/CHANGELOG.md b/packages/local_auth/local_auth_android/CHANGELOG.md index 5f74d5c8e6b4..b5bc8bc9545a 100644 --- a/packages/local_auth/local_auth_android/CHANGELOG.md +++ b/packages/local_auth/local_auth_android/CHANGELOG.md @@ -1,3 +1,28 @@ +## 1.0.46 + +* Updates Java compatibility version to 11. + +## 1.0.45 + +* Updates to the latest version of Pigeon. + +## 1.0.44 + +* Removes dependency on org.jetbrains.kotlin:kotlin-bom. +* Updates minimum supported SDK version to Flutter 3.24/Dart 3.5. + +## 1.0.43 + +* Updates lint checks to ignore NewerVersionAvailable. + +## 1.0.42 + +* Updates AGP version to 8.5.0. + +## 1.0.41 + +* Updates espresso to 3.6.1. + ## 1.0.40 * Updates androidx.core version to 1.13.1. diff --git a/packages/local_auth/local_auth_android/README.md b/packages/local_auth/local_auth_android/README.md index 047e82ef64b3..d9e3b8bba796 100644 --- a/packages/local_auth/local_auth_android/README.md +++ b/packages/local_auth/local_auth_android/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/local_auth -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/local_auth/local_auth_android/android/build.gradle b/packages/local_auth/local_auth_android/android/build.gradle index b2326e4b212a..38acc695fae9 100644 --- a/packages/local_auth/local_auth_android/android/build.gradle +++ b/packages/local_auth/local_auth_android/android/build.gradle @@ -8,7 +8,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.3.1' + classpath 'com.android.tools.build:gradle:8.5.0' } } @@ -22,10 +22,7 @@ rootProject.allprojects { apply plugin: 'com.android.library' android { - // Conditional for compatibility with AGP <4.2. - if (project.android.hasProperty("namespace")) { - namespace 'io.flutter.plugins.localauth' - } + namespace 'io.flutter.plugins.localauth' compileSdk 34 defaultConfig { @@ -34,14 +31,14 @@ android { } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } lintOptions { checkAllWarnings true warningsAsErrors true - disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency' + disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency', 'NewerVersionAvailable' } @@ -67,8 +64,5 @@ dependencies { testImplementation 'org.robolectric:robolectric:4.10.3' androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test:rules:1.2.0' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' - // TODO(camsim99): org.jetbrains.kotlin:kotlin-bom artifact purpose is to align kotlin stdlib and related code versions. - // This should be removed when https://github.com/flutter/flutter/issues/125062 is fixed. - implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.10")) + androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' } diff --git a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java index 5d1fe195449a..09af7c6656c0 100644 --- a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java +++ b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java @@ -24,7 +24,6 @@ import io.flutter.plugin.common.PluginRegistry; import io.flutter.plugins.localauth.AuthenticationHelper.AuthCompletionHandler; import io.flutter.plugins.localauth.Messages.AuthClassification; -import io.flutter.plugins.localauth.Messages.AuthClassificationWrapper; import io.flutter.plugins.localauth.Messages.AuthOptions; import io.flutter.plugins.localauth.Messages.AuthResult; import io.flutter.plugins.localauth.Messages.AuthStrings; @@ -82,23 +81,19 @@ public LocalAuthPlugin() {} return hasBiometricHardware(); } - public @NonNull List getEnrolledBiometrics() { - ArrayList biometrics = new ArrayList<>(); + public @NonNull List getEnrolledBiometrics() { + ArrayList biometrics = new ArrayList<>(); if (biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK) == BiometricManager.BIOMETRIC_SUCCESS) { - biometrics.add(wrappedBiometric(AuthClassification.WEAK)); + biometrics.add(AuthClassification.WEAK); } if (biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG) == BiometricManager.BIOMETRIC_SUCCESS) { - biometrics.add(wrappedBiometric(AuthClassification.STRONG)); + biometrics.add(AuthClassification.STRONG); } return biometrics; } - private @NonNull AuthClassificationWrapper wrappedBiometric(AuthClassification value) { - return new AuthClassificationWrapper.Builder().setValue(value).build(); - } - public @NonNull Boolean stopAuthentication() { try { if (authHelper != null && authInProgress.get()) { @@ -208,12 +203,12 @@ public boolean canAuthenticateWithDeviceCredential() { @Override public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { - LocalAuthApi.setup(binding.getBinaryMessenger(), this); + LocalAuthApi.setUp(binding.getBinaryMessenger(), this); } @Override public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { - LocalAuthApi.setup(binding.getBinaryMessenger(), null); + LocalAuthApi.setUp(binding.getBinaryMessenger(), null); } private void setServicesFromActivity(Activity activity) { diff --git a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/Messages.java b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/Messages.java index e878c481c273..e04a999a109b 100644 --- a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/Messages.java +++ b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/Messages.java @@ -1,11 +1,14 @@ // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v11.0.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.0), do not edit directly. // See also: https://pub.dev/packages/pigeon package io.flutter.plugins.localauth; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.CLASS; + import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -14,9 +17,12 @@ import io.flutter.plugin.common.MessageCodec; import io.flutter.plugin.common.StandardMessageCodec; import java.io.ByteArrayOutputStream; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; +import java.util.Objects; /** Generated class from Pigeon. */ @SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression", "serial"}) @@ -40,7 +46,7 @@ public FlutterError(@NonNull String code, @Nullable String message, @Nullable Ob @NonNull protected static ArrayList wrapError(@NonNull Throwable exception) { - ArrayList errorList = new ArrayList(3); + ArrayList errorList = new ArrayList<>(3); if (exception instanceof FlutterError) { FlutterError error = (FlutterError) exception; errorList.add(error.code); @@ -55,6 +61,10 @@ protected static ArrayList wrapError(@NonNull Throwable exception) { return errorList; } + @Target(METHOD) + @Retention(CLASS) + @interface CanIgnoreReturnValue {} + /** Possible outcomes of an authentication attempt. */ public enum AuthResult { /** The user authenticated successfully. */ @@ -78,7 +88,7 @@ public enum AuthResult { final int index; - private AuthResult(final int index) { + AuthResult(final int index) { this.index = index; } } @@ -90,7 +100,7 @@ public enum AuthClassification { final int index; - private AuthClassification(final int index) { + AuthClassification(final int index) { this.index = index; } } @@ -238,10 +248,47 @@ public void setSignInTitle(@NonNull String setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ AuthStrings() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AuthStrings that = (AuthStrings) o; + return reason.equals(that.reason) + && biometricHint.equals(that.biometricHint) + && biometricNotRecognized.equals(that.biometricNotRecognized) + && biometricRequiredTitle.equals(that.biometricRequiredTitle) + && cancelButton.equals(that.cancelButton) + && deviceCredentialsRequiredTitle.equals(that.deviceCredentialsRequiredTitle) + && deviceCredentialsSetupDescription.equals(that.deviceCredentialsSetupDescription) + && goToSettingsButton.equals(that.goToSettingsButton) + && goToSettingsDescription.equals(that.goToSettingsDescription) + && signInTitle.equals(that.signInTitle); + } + + @Override + public int hashCode() { + return Objects.hash( + reason, + biometricHint, + biometricNotRecognized, + biometricRequiredTitle, + cancelButton, + deviceCredentialsRequiredTitle, + deviceCredentialsSetupDescription, + goToSettingsButton, + goToSettingsDescription, + signInTitle); + } + public static final class Builder { private @Nullable String reason; + @CanIgnoreReturnValue public @NonNull Builder setReason(@NonNull String setterArg) { this.reason = setterArg; return this; @@ -249,6 +296,7 @@ public static final class Builder { private @Nullable String biometricHint; + @CanIgnoreReturnValue public @NonNull Builder setBiometricHint(@NonNull String setterArg) { this.biometricHint = setterArg; return this; @@ -256,6 +304,7 @@ public static final class Builder { private @Nullable String biometricNotRecognized; + @CanIgnoreReturnValue public @NonNull Builder setBiometricNotRecognized(@NonNull String setterArg) { this.biometricNotRecognized = setterArg; return this; @@ -263,6 +312,7 @@ public static final class Builder { private @Nullable String biometricRequiredTitle; + @CanIgnoreReturnValue public @NonNull Builder setBiometricRequiredTitle(@NonNull String setterArg) { this.biometricRequiredTitle = setterArg; return this; @@ -270,6 +320,7 @@ public static final class Builder { private @Nullable String cancelButton; + @CanIgnoreReturnValue public @NonNull Builder setCancelButton(@NonNull String setterArg) { this.cancelButton = setterArg; return this; @@ -277,6 +328,7 @@ public static final class Builder { private @Nullable String deviceCredentialsRequiredTitle; + @CanIgnoreReturnValue public @NonNull Builder setDeviceCredentialsRequiredTitle(@NonNull String setterArg) { this.deviceCredentialsRequiredTitle = setterArg; return this; @@ -284,6 +336,7 @@ public static final class Builder { private @Nullable String deviceCredentialsSetupDescription; + @CanIgnoreReturnValue public @NonNull Builder setDeviceCredentialsSetupDescription(@NonNull String setterArg) { this.deviceCredentialsSetupDescription = setterArg; return this; @@ -291,6 +344,7 @@ public static final class Builder { private @Nullable String goToSettingsButton; + @CanIgnoreReturnValue public @NonNull Builder setGoToSettingsButton(@NonNull String setterArg) { this.goToSettingsButton = setterArg; return this; @@ -298,6 +352,7 @@ public static final class Builder { private @Nullable String goToSettingsDescription; + @CanIgnoreReturnValue public @NonNull Builder setGoToSettingsDescription(@NonNull String setterArg) { this.goToSettingsDescription = setterArg; return this; @@ -305,6 +360,7 @@ public static final class Builder { private @Nullable String signInTitle; + @CanIgnoreReturnValue public @NonNull Builder setSignInTitle(@NonNull String setterArg) { this.signInTitle = setterArg; return this; @@ -328,7 +384,7 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(10); + ArrayList toListResult = new ArrayList<>(10); toListResult.add(reason); toListResult.add(biometricHint); toListResult.add(biometricNotRecognized); @@ -342,27 +398,27 @@ ArrayList toList() { return toListResult; } - static @NonNull AuthStrings fromList(@NonNull ArrayList list) { + static @NonNull AuthStrings fromList(@NonNull ArrayList pigeonVar_list) { AuthStrings pigeonResult = new AuthStrings(); - Object reason = list.get(0); + Object reason = pigeonVar_list.get(0); pigeonResult.setReason((String) reason); - Object biometricHint = list.get(1); + Object biometricHint = pigeonVar_list.get(1); pigeonResult.setBiometricHint((String) biometricHint); - Object biometricNotRecognized = list.get(2); + Object biometricNotRecognized = pigeonVar_list.get(2); pigeonResult.setBiometricNotRecognized((String) biometricNotRecognized); - Object biometricRequiredTitle = list.get(3); + Object biometricRequiredTitle = pigeonVar_list.get(3); pigeonResult.setBiometricRequiredTitle((String) biometricRequiredTitle); - Object cancelButton = list.get(4); + Object cancelButton = pigeonVar_list.get(4); pigeonResult.setCancelButton((String) cancelButton); - Object deviceCredentialsRequiredTitle = list.get(5); + Object deviceCredentialsRequiredTitle = pigeonVar_list.get(5); pigeonResult.setDeviceCredentialsRequiredTitle((String) deviceCredentialsRequiredTitle); - Object deviceCredentialsSetupDescription = list.get(6); + Object deviceCredentialsSetupDescription = pigeonVar_list.get(6); pigeonResult.setDeviceCredentialsSetupDescription((String) deviceCredentialsSetupDescription); - Object goToSettingsButton = list.get(7); + Object goToSettingsButton = pigeonVar_list.get(7); pigeonResult.setGoToSettingsButton((String) goToSettingsButton); - Object goToSettingsDescription = list.get(8); + Object goToSettingsDescription = pigeonVar_list.get(8); pigeonResult.setGoToSettingsDescription((String) goToSettingsDescription); - Object signInTitle = list.get(9); + Object signInTitle = pigeonVar_list.get(9); pigeonResult.setSignInTitle((String) signInTitle); return pigeonResult; } @@ -425,10 +481,31 @@ public void setUseErrorDialgs(@NonNull Boolean setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ AuthOptions() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AuthOptions that = (AuthOptions) o; + return biometricOnly.equals(that.biometricOnly) + && sensitiveTransaction.equals(that.sensitiveTransaction) + && sticky.equals(that.sticky) + && useErrorDialgs.equals(that.useErrorDialgs); + } + + @Override + public int hashCode() { + return Objects.hash(biometricOnly, sensitiveTransaction, sticky, useErrorDialgs); + } + public static final class Builder { private @Nullable Boolean biometricOnly; + @CanIgnoreReturnValue public @NonNull Builder setBiometricOnly(@NonNull Boolean setterArg) { this.biometricOnly = setterArg; return this; @@ -436,6 +513,7 @@ public static final class Builder { private @Nullable Boolean sensitiveTransaction; + @CanIgnoreReturnValue public @NonNull Builder setSensitiveTransaction(@NonNull Boolean setterArg) { this.sensitiveTransaction = setterArg; return this; @@ -443,6 +521,7 @@ public static final class Builder { private @Nullable Boolean sticky; + @CanIgnoreReturnValue public @NonNull Builder setSticky(@NonNull Boolean setterArg) { this.sticky = setterArg; return this; @@ -450,6 +529,7 @@ public static final class Builder { private @Nullable Boolean useErrorDialgs; + @CanIgnoreReturnValue public @NonNull Builder setUseErrorDialgs(@NonNull Boolean setterArg) { this.useErrorDialgs = setterArg; return this; @@ -467,7 +547,7 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(4); + ArrayList toListResult = new ArrayList<>(4); toListResult.add(biometricOnly); toListResult.add(sensitiveTransaction); toListResult.add(sticky); @@ -475,90 +555,42 @@ ArrayList toList() { return toListResult; } - static @NonNull AuthOptions fromList(@NonNull ArrayList list) { + static @NonNull AuthOptions fromList(@NonNull ArrayList pigeonVar_list) { AuthOptions pigeonResult = new AuthOptions(); - Object biometricOnly = list.get(0); + Object biometricOnly = pigeonVar_list.get(0); pigeonResult.setBiometricOnly((Boolean) biometricOnly); - Object sensitiveTransaction = list.get(1); + Object sensitiveTransaction = pigeonVar_list.get(1); pigeonResult.setSensitiveTransaction((Boolean) sensitiveTransaction); - Object sticky = list.get(2); + Object sticky = pigeonVar_list.get(2); pigeonResult.setSticky((Boolean) sticky); - Object useErrorDialgs = list.get(3); + Object useErrorDialgs = pigeonVar_list.get(3); pigeonResult.setUseErrorDialgs((Boolean) useErrorDialgs); return pigeonResult; } } - /** Generated class from Pigeon that represents data sent in messages. */ - public static final class AuthClassificationWrapper { - private @NonNull AuthClassification value; - - public @NonNull AuthClassification getValue() { - return value; - } - - public void setValue(@NonNull AuthClassification setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"value\" is null."); - } - this.value = setterArg; - } - - /** Constructor is non-public to enforce null safety; use Builder. */ - AuthClassificationWrapper() {} - - public static final class Builder { - - private @Nullable AuthClassification value; - - public @NonNull Builder setValue(@NonNull AuthClassification setterArg) { - this.value = setterArg; - return this; - } - - public @NonNull AuthClassificationWrapper build() { - AuthClassificationWrapper pigeonReturn = new AuthClassificationWrapper(); - pigeonReturn.setValue(value); - return pigeonReturn; - } - } - - @NonNull - ArrayList toList() { - ArrayList toListResult = new ArrayList(1); - toListResult.add(value == null ? null : value.index); - return toListResult; - } - - static @NonNull AuthClassificationWrapper fromList(@NonNull ArrayList list) { - AuthClassificationWrapper pigeonResult = new AuthClassificationWrapper(); - Object value = list.get(0); - pigeonResult.setValue(AuthClassification.values()[(int) value]); - return pigeonResult; - } - } - - public interface Result { - @SuppressWarnings("UnknownNullness") - void success(T result); - - void error(@NonNull Throwable error); - } + private static class PigeonCodec extends StandardMessageCodec { + public static final PigeonCodec INSTANCE = new PigeonCodec(); - private static class LocalAuthApiCodec extends StandardMessageCodec { - public static final LocalAuthApiCodec INSTANCE = new LocalAuthApiCodec(); - - private LocalAuthApiCodec() {} + private PigeonCodec() {} @Override protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { switch (type) { - case (byte) 128: - return AuthClassificationWrapper.fromList((ArrayList) readValue(buffer)); case (byte) 129: - return AuthOptions.fromList((ArrayList) readValue(buffer)); + { + Object value = readValue(buffer); + return value == null ? null : AuthResult.values()[((Long) value).intValue()]; + } case (byte) 130: + { + Object value = readValue(buffer); + return value == null ? null : AuthClassification.values()[((Long) value).intValue()]; + } + case (byte) 131: return AuthStrings.fromList((ArrayList) readValue(buffer)); + case (byte) 132: + return AuthOptions.fromList((ArrayList) readValue(buffer)); default: return super.readValueOfType(type, buffer); } @@ -566,21 +598,48 @@ protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { @Override protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { - if (value instanceof AuthClassificationWrapper) { - stream.write(128); - writeValue(stream, ((AuthClassificationWrapper) value).toList()); - } else if (value instanceof AuthOptions) { + if (value instanceof AuthResult) { stream.write(129); - writeValue(stream, ((AuthOptions) value).toList()); - } else if (value instanceof AuthStrings) { + writeValue(stream, value == null ? null : ((AuthResult) value).index); + } else if (value instanceof AuthClassification) { stream.write(130); + writeValue(stream, value == null ? null : ((AuthClassification) value).index); + } else if (value instanceof AuthStrings) { + stream.write(131); writeValue(stream, ((AuthStrings) value).toList()); + } else if (value instanceof AuthOptions) { + stream.write(132); + writeValue(stream, ((AuthOptions) value).toList()); } else { super.writeValue(stream, value); } } } + /** Asynchronous error handling return type for non-nullable API method returns. */ + public interface Result { + /** Success case callback method for handling returns. */ + void success(@NonNull T result); + + /** Failure case callback method for handling errors. */ + void error(@NonNull Throwable error); + } + /** Asynchronous error handling return type for nullable API method returns. */ + public interface NullableResult { + /** Success case callback method for handling returns. */ + void success(@Nullable T result); + + /** Failure case callback method for handling errors. */ + void error(@NonNull Throwable error); + } + /** Asynchronous error handling return type for void API method returns. */ + public interface VoidResult { + /** Success case callback method for handling returns. */ + void success(); + + /** Failure case callback method for handling errors. */ + void error(@NonNull Throwable error); + } /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ public interface LocalAuthApi { /** Returns true if this device supports authentication. */ @@ -603,7 +662,7 @@ public interface LocalAuthApi { * Returns the biometric types that are enrolled, and can thus be used without additional setup. */ @NonNull - List getEnrolledBiometrics(); + List getEnrolledBiometrics(); /** * Attempts to authenticate the user with the provided [options], and using [strings] for any * UI. @@ -615,26 +674,34 @@ void authenticate( /** The codec used by LocalAuthApi. */ static @NonNull MessageCodec getCodec() { - return LocalAuthApiCodec.INSTANCE; + return PigeonCodec.INSTANCE; } /** Sets up an instance of `LocalAuthApi` to handle messages through the `binaryMessenger`. */ - static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable LocalAuthApi api) { + static void setUp(@NonNull BinaryMessenger binaryMessenger, @Nullable LocalAuthApi api) { + setUp(binaryMessenger, "", api); + } + + static void setUp( + @NonNull BinaryMessenger binaryMessenger, + @NonNull String messageChannelSuffix, + @Nullable LocalAuthApi api) { + messageChannelSuffix = messageChannelSuffix.isEmpty() ? "" : "." + messageChannelSuffix; { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.local_auth_android.LocalAuthApi.isDeviceSupported", + "dev.flutter.pigeon.local_auth_android.LocalAuthApi.isDeviceSupported" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { Boolean output = api.isDeviceSupported(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -646,18 +713,18 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable LocalAuthA BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.local_auth_android.LocalAuthApi.deviceCanSupportBiometrics", + "dev.flutter.pigeon.local_auth_android.LocalAuthApi.deviceCanSupportBiometrics" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { Boolean output = api.deviceCanSupportBiometrics(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -669,18 +736,18 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable LocalAuthA BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.local_auth_android.LocalAuthApi.stopAuthentication", + "dev.flutter.pigeon.local_auth_android.LocalAuthApi.stopAuthentication" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { Boolean output = api.stopAuthentication(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -692,18 +759,18 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable LocalAuthA BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.local_auth_android.LocalAuthApi.getEnrolledBiometrics", + "dev.flutter.pigeon.local_auth_android.LocalAuthApi.getEnrolledBiometrics" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { - List output = api.getEnrolledBiometrics(); + List output = api.getEnrolledBiometrics(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -715,19 +782,20 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable LocalAuthA BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.local_auth_android.LocalAuthApi.authenticate", + "dev.flutter.pigeon.local_auth_android.LocalAuthApi.authenticate" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; AuthOptions optionsArg = (AuthOptions) args.get(0); AuthStrings stringsArg = (AuthStrings) args.get(1); Result resultCallback = new Result() { public void success(AuthResult result) { - wrapped.add(0, result.index); + wrapped.add(0, result); reply.reply(wrapped); } diff --git a/packages/local_auth/local_auth_android/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java b/packages/local_auth/local_auth_android/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java index 5e7c14d68b20..1fbc20a78037 100644 --- a/packages/local_auth/local_auth_android/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java +++ b/packages/local_auth/local_auth_android/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java @@ -30,7 +30,6 @@ import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugins.localauth.AuthenticationHelper.AuthCompletionHandler; import io.flutter.plugins.localauth.Messages.AuthClassification; -import io.flutter.plugins.localauth.Messages.AuthClassificationWrapper; import io.flutter.plugins.localauth.Messages.AuthOptions; import io.flutter.plugins.localauth.Messages.AuthResult; import io.flutter.plugins.localauth.Messages.AuthStrings; @@ -291,7 +290,7 @@ public void getEnrolledBiometrics_shouldReturnEmptyList_withoutHardwarePresent() .thenReturn(BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE); plugin.setBiometricManager(mockBiometricManager); - final List enrolled = plugin.getEnrolledBiometrics(); + final List enrolled = plugin.getEnrolledBiometrics(); assertTrue(enrolled.isEmpty()); } @@ -304,7 +303,7 @@ public void getEnrolledBiometrics_shouldReturnEmptyList_withNoMethodsEnrolled() .thenReturn(BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED); plugin.setBiometricManager(mockBiometricManager); - final List enrolled = plugin.getEnrolledBiometrics(); + final List enrolled = plugin.getEnrolledBiometrics(); assertTrue(enrolled.isEmpty()); } @@ -319,9 +318,9 @@ public void getEnrolledBiometrics_shouldOnlyAddEnrolledBiometrics() { .thenReturn(BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED); plugin.setBiometricManager(mockBiometricManager); - final List enrolled = plugin.getEnrolledBiometrics(); + final List enrolled = plugin.getEnrolledBiometrics(); assertEquals(1, enrolled.size()); - assertEquals(AuthClassification.WEAK, enrolled.get(0).getValue()); + assertEquals(AuthClassification.WEAK, enrolled.get(0)); } @Test @@ -335,10 +334,10 @@ public void getEnrolledBiometrics_shouldAddStrongBiometrics() { .thenReturn(BiometricManager.BIOMETRIC_SUCCESS); plugin.setBiometricManager(mockBiometricManager); - final List enrolled = plugin.getEnrolledBiometrics(); + final List enrolled = plugin.getEnrolledBiometrics(); assertEquals(2, enrolled.size()); - assertEquals(AuthClassification.WEAK, enrolled.get(0).getValue()); - assertEquals(AuthClassification.STRONG, enrolled.get(1).getValue()); + assertEquals(AuthClassification.WEAK, enrolled.get(0)); + assertEquals(AuthClassification.STRONG, enrolled.get(1)); } @Test diff --git a/packages/local_auth/local_auth_android/example/android/app/build.gradle b/packages/local_auth/local_auth_android/example/android/app/build.gradle index f075d5813cf9..7db5363be38d 100644 --- a/packages/local_auth/local_auth_android/example/android/app/build.gradle +++ b/packages/local_auth/local_auth_android/example/android/app/build.gradle @@ -32,11 +32,10 @@ android { defaultConfig { applicationId "io.flutter.plugins.localauthexample" minSdkVersion flutter.minSdkVersion - targetSdkVersion 28 + targetSdkVersion 34 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - multiDexEnabled true } buildTypes { diff --git a/packages/local_auth/local_auth_android/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/local_auth/local_auth_android/example/android/app/gradle/wrapper/gradle-wrapper.properties index 609ab8e6c8b5..d951fac2bf31 100644 --- a/packages/local_auth/local_auth_android/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ b/packages/local_auth/local_auth_android/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/packages/local_auth/local_auth_android/example/android/app/src/main/AndroidManifest.xml b/packages/local_auth/local_auth_android/example/android/app/src/main/AndroidManifest.xml index 4acc4eb87ed6..02d732716e62 100644 --- a/packages/local_auth/local_auth_android/example/android/app/src/main/AndroidManifest.xml +++ b/packages/local_auth/local_auth_android/example/android/app/src/main/AndroidManifest.xml @@ -6,7 +6,8 @@ =3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" dependencies: flutter: diff --git a/packages/local_auth/local_auth_android/lib/local_auth_android.dart b/packages/local_auth/local_auth_android/lib/local_auth_android.dart index cf117cb00667..3b1fd96059e0 100644 --- a/packages/local_auth/local_auth_android/lib/local_auth_android.dart +++ b/packages/local_auth/local_auth_android/lib/local_auth_android.dart @@ -95,12 +95,9 @@ class LocalAuthAndroid extends LocalAuthPlatform { @override Future> getEnrolledBiometrics() async { - final List result = - await _api.getEnrolledBiometrics(); - return result - .cast() - .map((AuthClassificationWrapper entry) { - switch (entry.value) { + final List result = await _api.getEnrolledBiometrics(); + return result.map((AuthClassification value) { + switch (value) { case AuthClassification.weak: return BiometricType.weak; case AuthClassification.strong: diff --git a/packages/local_auth/local_auth_android/lib/src/messages.g.dart b/packages/local_auth/local_auth_android/lib/src/messages.g.dart index 77f5215596b7..590562c03709 100644 --- a/packages/local_auth/local_auth_android/lib/src/messages.g.dart +++ b/packages/local_auth/local_auth_android/lib/src/messages.g.dart @@ -1,9 +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 (v11.0.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.0), 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 +// 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 import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; @@ -11,6 +11,13 @@ import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; import 'package:flutter/services.dart'; +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); +} + /// Possible outcomes of an authentication attempt. enum AuthResult { /// The user authenticated successfully. @@ -153,39 +160,24 @@ class AuthOptions { } } -class AuthClassificationWrapper { - AuthClassificationWrapper({ - required this.value, - }); - - AuthClassification value; - - Object encode() { - return [ - value.index, - ]; - } - - static AuthClassificationWrapper decode(Object result) { - result as List; - return AuthClassificationWrapper( - value: AuthClassification.values[result[0]! as int], - ); - } -} - -class _LocalAuthApiCodec extends StandardMessageCodec { - const _LocalAuthApiCodec(); +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is AuthClassificationWrapper) { - buffer.putUint8(128); - writeValue(buffer, value.encode()); - } else if (value is AuthOptions) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is AuthResult) { buffer.putUint8(129); - writeValue(buffer, value.encode()); - } else if (value is AuthStrings) { + writeValue(buffer, value.index); + } else if (value is AuthClassification) { buffer.putUint8(130); + writeValue(buffer, value.index); + } else if (value is AuthStrings) { + buffer.putUint8(131); + writeValue(buffer, value.encode()); + } else if (value is AuthOptions) { + buffer.putUint8(132); writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); @@ -195,12 +187,16 @@ class _LocalAuthApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: - return AuthClassificationWrapper.decode(readValue(buffer)!); case 129: - return AuthOptions.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : AuthResult.values[value]; case 130: + final int? value = readValue(buffer) as int?; + return value == null ? null : AuthClassification.values[value]; + case 131: return AuthStrings.decode(readValue(buffer)!); + case 132: + return AuthOptions.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -211,66 +207,75 @@ class LocalAuthApi { /// Constructor for [LocalAuthApi]. 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. - LocalAuthApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; + LocalAuthApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - static const MessageCodec codec = _LocalAuthApiCodec(); + final String pigeonVar_messageChannelSuffix; /// Returns true if this device supports authentication. Future isDeviceSupported() async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.local_auth_android.LocalAuthApi.isDeviceSupported', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send(null) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.local_auth_android.LocalAuthApi.isDeviceSupported$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 (replyList[0] as bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } /// Returns true if this device can support biometric authentication, whether /// any biometrics are enrolled or not. Future deviceCanSupportBiometrics() async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.local_auth_android.LocalAuthApi.deviceCanSupportBiometrics', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send(null) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.local_auth_android.LocalAuthApi.deviceCanSupportBiometrics$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 (replyList[0] as bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } @@ -279,90 +284,95 @@ class LocalAuthApi { /// Returns true only if authentication was in progress, and was successfully /// cancelled. Future stopAuthentication() async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.local_auth_android.LocalAuthApi.stopAuthentication', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send(null) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.local_auth_android.LocalAuthApi.stopAuthentication$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 (replyList[0] as bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } /// Returns the biometric types that are enrolled, and can thus be used /// without additional setup. - Future> getEnrolledBiometrics() async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.local_auth_android.LocalAuthApi.getEnrolledBiometrics', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send(null) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future> getEnrolledBiometrics() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.local_auth_android.LocalAuthApi.getEnrolledBiometrics$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 (replyList[0] as List?)! - .cast(); + return (pigeonVar_replyList[0] as List?)! + .cast(); } } /// Attempts to authenticate the user with the provided [options], and using /// [strings] for any UI. Future authenticate( - AuthOptions arg_options, AuthStrings arg_strings) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.local_auth_android.LocalAuthApi.authenticate', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_options, arg_strings]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + AuthOptions options, AuthStrings strings) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.local_auth_android.LocalAuthApi.authenticate$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([options, strings]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 AuthResult.values[replyList[0]! as int]; + return (pigeonVar_replyList[0] as AuthResult?)!; } } } diff --git a/packages/local_auth/local_auth_android/pigeons/messages.dart b/packages/local_auth/local_auth_android/pigeons/messages.dart index 622c1657cd6a..b08936637e27 100644 --- a/packages/local_auth/local_auth_android/pigeons/messages.dart +++ b/packages/local_auth/local_auth_android/pigeons/messages.dart @@ -87,13 +87,6 @@ class AuthOptions { /// Pigeon equivalent of the subset of BiometricType used by Android. enum AuthClassification { weak, strong } -// TODO(stuartmorgan): Remove this when -// https://github.com/flutter/flutter/issues/87307 is implemented. -class AuthClassificationWrapper { - AuthClassificationWrapper({required this.value}); - final AuthClassification value; -} - @HostApi() abstract class LocalAuthApi { /// Returns true if this device supports authentication. @@ -111,7 +104,7 @@ abstract class LocalAuthApi { /// Returns the biometric types that are enrolled, and can thus be used /// without additional setup. - List getEnrolledBiometrics(); + List getEnrolledBiometrics(); /// Attempts to authenticate the user with the provided [options], and using /// [strings] for any UI. diff --git a/packages/local_auth/local_auth_android/pubspec.yaml b/packages/local_auth/local_auth_android/pubspec.yaml index 4352b3b82990..b75c2440797e 100644 --- a/packages/local_auth/local_auth_android/pubspec.yaml +++ b/packages/local_auth/local_auth_android/pubspec.yaml @@ -2,11 +2,11 @@ name: local_auth_android description: Android implementation of the local_auth plugin. repository: https://github.com/flutter/packages/tree/main/packages/local_auth/local_auth_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+local_auth%22 -version: 1.0.40 +version: 1.0.46 environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" flutter: plugin: @@ -28,8 +28,8 @@ dev_dependencies: build_runner: ^2.3.3 flutter_test: sdk: flutter - mockito: 5.4.4 - pigeon: ^11.0.0 + mockito: ^5.4.4 + pigeon: ^22.4.0 topics: - authentication diff --git a/packages/local_auth/local_auth_android/test/local_auth_test.dart b/packages/local_auth/local_auth_android/test/local_auth_test.dart index d37898105a4b..4c3785c96721 100644 --- a/packages/local_auth/local_auth_android/test/local_auth_test.dart +++ b/packages/local_auth/local_auth_android/test/local_auth_test.dart @@ -66,9 +66,9 @@ void main() { group('getEnrolledBiometrics', () { test('translates values', () async { when(api.getEnrolledBiometrics()) - .thenAnswer((_) async => [ - AuthClassificationWrapper(value: AuthClassification.weak), - AuthClassificationWrapper(value: AuthClassification.strong), + .thenAnswer((_) async => [ + AuthClassification.weak, + AuthClassification.strong, ]); final List result = await plugin.getEnrolledBiometrics(); @@ -81,7 +81,7 @@ void main() { test('handles empty', () async { when(api.getEnrolledBiometrics()) - .thenAnswer((_) async => []); + .thenAnswer((_) async => []); final List result = await plugin.getEnrolledBiometrics(); diff --git a/packages/local_auth/local_auth_android/test/local_auth_test.mocks.dart b/packages/local_auth/local_auth_android/test/local_auth_test.mocks.dart index 9f38167c3fd6..e09d0bda114e 100644 --- a/packages/local_auth/local_auth_android/test/local_auth_test.mocks.dart +++ b/packages/local_auth/local_auth_android/test/local_auth_test.mocks.dart @@ -3,10 +3,11 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i3; +import 'dart:async' as _i4; import 'package:local_auth_android/src/messages.g.dart' as _i2; import 'package:mockito/mockito.dart' as _i1; +import 'package:mockito/src/dummies.dart' as _i3; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -30,56 +31,65 @@ class MockLocalAuthApi extends _i1.Mock implements _i2.LocalAuthApi { } @override - _i3.Future isDeviceSupported() => (super.noSuchMethod( + String get pigeonVar_messageChannelSuffix => (super.noSuchMethod( + Invocation.getter(#pigeonVar_messageChannelSuffix), + returnValue: _i3.dummyValue( + this, + Invocation.getter(#pigeonVar_messageChannelSuffix), + ), + ) as String); + + @override + _i4.Future isDeviceSupported() => (super.noSuchMethod( Invocation.method( #isDeviceSupported, [], ), - returnValue: _i3.Future.value(false), - ) as _i3.Future); + returnValue: _i4.Future.value(false), + ) as _i4.Future); @override - _i3.Future deviceCanSupportBiometrics() => (super.noSuchMethod( + _i4.Future deviceCanSupportBiometrics() => (super.noSuchMethod( Invocation.method( #deviceCanSupportBiometrics, [], ), - returnValue: _i3.Future.value(false), - ) as _i3.Future); + returnValue: _i4.Future.value(false), + ) as _i4.Future); @override - _i3.Future stopAuthentication() => (super.noSuchMethod( + _i4.Future stopAuthentication() => (super.noSuchMethod( Invocation.method( #stopAuthentication, [], ), - returnValue: _i3.Future.value(false), - ) as _i3.Future); + returnValue: _i4.Future.value(false), + ) as _i4.Future); @override - _i3.Future> getEnrolledBiometrics() => + _i4.Future> getEnrolledBiometrics() => (super.noSuchMethod( Invocation.method( #getEnrolledBiometrics, [], ), - returnValue: _i3.Future>.value( - <_i2.AuthClassificationWrapper?>[]), - ) as _i3.Future>); + returnValue: _i4.Future>.value( + <_i2.AuthClassification>[]), + ) as _i4.Future>); @override - _i3.Future<_i2.AuthResult> authenticate( - _i2.AuthOptions? arg_options, - _i2.AuthStrings? arg_strings, + _i4.Future<_i2.AuthResult> authenticate( + _i2.AuthOptions? options, + _i2.AuthStrings? strings, ) => (super.noSuchMethod( Invocation.method( #authenticate, [ - arg_options, - arg_strings, + options, + strings, ], ), - returnValue: _i3.Future<_i2.AuthResult>.value(_i2.AuthResult.success), - ) as _i3.Future<_i2.AuthResult>); + returnValue: _i4.Future<_i2.AuthResult>.value(_i2.AuthResult.success), + ) as _i4.Future<_i2.AuthResult>); } diff --git a/packages/local_auth/local_auth_darwin/CHANGELOG.md b/packages/local_auth/local_auth_darwin/CHANGELOG.md index 28d789ca0f68..1002a874e2f3 100644 --- a/packages/local_auth/local_auth_darwin/CHANGELOG.md +++ b/packages/local_auth/local_auth_darwin/CHANGELOG.md @@ -1,3 +1,12 @@ +## 1.4.1 + +* Updates to the current version of Pigeon. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + +## 1.4.0 + +* Adds macOS support. + ## 1.3.1 * Adjusts implementation for improved testability, and removes use of OCMock. diff --git a/packages/local_auth/local_auth_darwin/README.md b/packages/local_auth/local_auth_darwin/README.md index 46cea6593921..39650ce1110f 100644 --- a/packages/local_auth/local_auth_darwin/README.md +++ b/packages/local_auth/local_auth_darwin/README.md @@ -1,6 +1,6 @@ # local_auth_darwin -The iOS implementation of [`local_auth`][1]. +The iOS and macOS implementation of [`local_auth`][1]. ## Usage @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/local_auth -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/local_auth/local_auth_darwin/darwin/Tests/FLALocalAuthPluginTests.swift b/packages/local_auth/local_auth_darwin/darwin/Tests/FLALocalAuthPluginTests.swift index 865be355fd16..73da7123b38f 100644 --- a/packages/local_auth/local_auth_darwin/darwin/Tests/FLALocalAuthPluginTests.swift +++ b/packages/local_auth/local_auth_darwin/darwin/Tests/FLALocalAuthPluginTests.swift @@ -2,16 +2,22 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import Flutter import XCTest @testable import local_auth_darwin +#if os(iOS) + import Flutter +#else + import FlutterMacOS +#endif + // Set a long timeout to avoid flake due to slow CI. private let timeout: TimeInterval = 30.0 /// A context factory that returns preset contexts. final class StubAuthContextFactory: NSObject, FLADAuthContextFactory { + var contexts: [FLADAuthContext] init(contexts: [FLADAuthContext]) { self.contexts = contexts @@ -23,6 +29,74 @@ final class StubAuthContextFactory: NSObject, FLADAuthContextFactory { } } +final class StubViewProvider: NSObject, FLAViewProvider { + #if os(macOS) + var view: NSView + var window: NSWindow + override init() { + self.window = NSWindow() + self.view = NSView() + self.window.contentView = self.view + } + #endif +} + +#if os(macOS) + final class TestAlert: NSObject, FLANSAlert { + var messageText: String = "" + var buttons: [String] = [] + var presentingWindow: NSWindow? + + func addButton(withTitle title: String) -> NSButton { + buttons.append(title) + return NSButton() // The return value is not used by the plugin. + } + + func beginSheetModal(for sheetWindow: NSWindow) async -> NSApplication.ModalResponse { + presentingWindow = sheetWindow + return NSApplication.ModalResponse.OK + } + } +#else + final class TestAlertController: NSObject, FLAUIAlertController { + var actions: [UIAlertAction] = [] + var presented = false + var presentingViewController: UIViewController? + + func add(_ action: UIAlertAction) { + actions.append(action) + } + + func present( + on presentingViewController: UIViewController, animated flag: Bool, + completion: (() -> Void)? = nil + ) { + presented = true + self.presentingViewController = presentingViewController + } + } +#endif + +final class StubAlertFactory: NSObject, FLADAlertFactory { + #if os(macOS) + var alert: TestAlert = TestAlert() + #else + var alertController: TestAlertController = TestAlertController() + #endif + + #if os(macOS) + func createAlert() -> FLANSAlert { + return self.alert + } + #else + func createAlertController( + withTitle title: String?, message: String?, preferredStyle: UIAlertController.Style + ) -> FLAUIAlertController { + return self.alertController + } + #endif +} + final class StubAuthContext: NSObject, FLADAuthContext { /// Whether calls to this stub are expected to be for biometric authentication. /// @@ -75,8 +149,12 @@ class FLALocalAuthPluginTests: XCTestCase { func testSuccessfullAuthWithBiometrics() throws { let stubAuthContext = StubAuthContext() + let alertFactory = StubAlertFactory() + let viewProvider = StubViewProvider() let plugin = FLALocalAuthPlugin( - contextFactory: StubAuthContextFactory(contexts: [stubAuthContext])) + contextFactory: StubAuthContextFactory(contexts: [stubAuthContext]), + alertFactory: alertFactory, viewProvider: viewProvider + ) let strings = createAuthStrings() stubAuthContext.expectBiometrics = true @@ -99,8 +177,12 @@ class FLALocalAuthPluginTests: XCTestCase { func testSuccessfullAuthWithoutBiometrics() { let stubAuthContext = StubAuthContext() + let alertFactory = StubAlertFactory() + let viewProvider = StubViewProvider() + let plugin = FLALocalAuthPlugin( - contextFactory: StubAuthContextFactory(contexts: [stubAuthContext])) + contextFactory: StubAuthContextFactory(contexts: [stubAuthContext]), + alertFactory: alertFactory, viewProvider: viewProvider) let strings = createAuthStrings() stubAuthContext.evaluateResponse = true @@ -123,8 +205,11 @@ class FLALocalAuthPluginTests: XCTestCase { func testFailedAuthWithBiometrics() { let stubAuthContext = StubAuthContext() + let alertFactory = StubAlertFactory() + let viewProvider = StubViewProvider() let plugin = FLALocalAuthPlugin( - contextFactory: StubAuthContextFactory(contexts: [stubAuthContext])) + contextFactory: StubAuthContextFactory(contexts: [stubAuthContext]), + alertFactory: alertFactory, viewProvider: viewProvider) let strings = createAuthStrings() stubAuthContext.expectBiometrics = true @@ -153,8 +238,11 @@ class FLALocalAuthPluginTests: XCTestCase { func testFailedWithUnknownErrorCode() { let stubAuthContext = StubAuthContext() + let alertFactory = StubAlertFactory() + let viewProvider = StubViewProvider() let plugin = FLALocalAuthPlugin( - contextFactory: StubAuthContextFactory(contexts: [stubAuthContext])) + contextFactory: StubAuthContextFactory(contexts: [stubAuthContext]), + alertFactory: alertFactory, viewProvider: viewProvider) let strings = createAuthStrings() stubAuthContext.evaluateError = NSError(domain: "error", code: 99) @@ -177,8 +265,11 @@ class FLALocalAuthPluginTests: XCTestCase { func testSystemCancelledWithoutStickyAuth() { let stubAuthContext = StubAuthContext() + let alertFactory = StubAlertFactory() + let viewProvider = StubViewProvider() let plugin = FLALocalAuthPlugin( - contextFactory: StubAuthContextFactory(contexts: [stubAuthContext])) + contextFactory: StubAuthContextFactory(contexts: [stubAuthContext]), + alertFactory: alertFactory, viewProvider: viewProvider) let strings = createAuthStrings() stubAuthContext.evaluateError = NSError(domain: "error", code: LAError.systemCancel.rawValue) @@ -201,8 +292,11 @@ class FLALocalAuthPluginTests: XCTestCase { func testFailedAuthWithoutBiometrics() { let stubAuthContext = StubAuthContext() + let alertFactory = StubAlertFactory() + let viewProvider = StubViewProvider() let plugin = FLALocalAuthPlugin( - contextFactory: StubAuthContextFactory(contexts: [stubAuthContext])) + contextFactory: StubAuthContextFactory(contexts: [stubAuthContext]), + alertFactory: alertFactory, viewProvider: viewProvider) let strings = createAuthStrings() stubAuthContext.evaluateError = NSError( @@ -228,10 +322,50 @@ class FLALocalAuthPluginTests: XCTestCase { self.waitForExpectations(timeout: timeout) } + func testFailedAuthShowsAlert() { + let stubAuthContext = StubAuthContext() + let alertFactory = StubAlertFactory() + let viewProvider = StubViewProvider() + let plugin = FLALocalAuthPlugin( + contextFactory: StubAuthContextFactory(contexts: [stubAuthContext]), + alertFactory: alertFactory, viewProvider: viewProvider) + + let strings = createAuthStrings() + stubAuthContext.canEvaluateError = NSError( + domain: "error", code: LAError.biometryNotEnrolled.rawValue) + + #if os(macOS) + let expectation = expectation(description: "Result is called") + #endif + plugin.authenticate( + with: FLADAuthOptions.make( + withBiometricOnly: false, + sticky: false, + useErrorDialogs: true), + strings: strings + ) { resultDetails, error in + // TODO(stuartmorgan): Add a wrapper around UIAction to allow accessing the handler, so + // that the test can trigger the callback on iOS as well, and then unfork this. + #if os(macOS) + expectation.fulfill() + #endif + } + #if os(macOS) + self.waitForExpectations(timeout: timeout) + XCTAssertEqual(alertFactory.alert.presentingWindow, viewProvider.view.window) + #else + XCTAssertTrue(alertFactory.alertController.presented) + XCTAssertEqual(alertFactory.alertController.actions.count, 2) + #endif + } + func testLocalizedFallbackTitle() { let stubAuthContext = StubAuthContext() + let alertFactory = StubAlertFactory() + let viewProvider = StubViewProvider() let plugin = FLALocalAuthPlugin( - contextFactory: StubAuthContextFactory(contexts: [stubAuthContext])) + contextFactory: StubAuthContextFactory(contexts: [stubAuthContext]), + alertFactory: alertFactory, viewProvider: viewProvider) let strings = createAuthStrings() strings.localizedFallbackTitle = "a title" @@ -255,8 +389,11 @@ class FLALocalAuthPluginTests: XCTestCase { func testSkippedLocalizedFallbackTitle() { let stubAuthContext = StubAuthContext() + let alertFactory = StubAlertFactory() + let viewProvider = StubViewProvider() let plugin = FLALocalAuthPlugin( - contextFactory: StubAuthContextFactory(contexts: [stubAuthContext])) + contextFactory: StubAuthContextFactory(contexts: [stubAuthContext]), + alertFactory: alertFactory, viewProvider: viewProvider) let strings = createAuthStrings() strings.localizedFallbackTitle = nil @@ -278,8 +415,11 @@ class FLALocalAuthPluginTests: XCTestCase { func testDeviceSupportsBiometrics_withEnrolledHardware() { let stubAuthContext = StubAuthContext() + let alertFactory = StubAlertFactory() + let viewProvider = StubViewProvider() let plugin = FLALocalAuthPlugin( - contextFactory: StubAuthContextFactory(contexts: [stubAuthContext])) + contextFactory: StubAuthContextFactory(contexts: [stubAuthContext]), + alertFactory: alertFactory, viewProvider: viewProvider) stubAuthContext.expectBiometrics = true @@ -291,8 +431,11 @@ class FLALocalAuthPluginTests: XCTestCase { func testDeviceSupportsBiometrics_withNonEnrolledHardware() { let stubAuthContext = StubAuthContext() + let alertFactory = StubAlertFactory() + let viewProvider = StubViewProvider() let plugin = FLALocalAuthPlugin( - contextFactory: StubAuthContextFactory(contexts: [stubAuthContext])) + contextFactory: StubAuthContextFactory(contexts: [stubAuthContext]), + alertFactory: alertFactory, viewProvider: viewProvider) stubAuthContext.expectBiometrics = true stubAuthContext.canEvaluateError = NSError( @@ -306,8 +449,11 @@ class FLALocalAuthPluginTests: XCTestCase { func testDeviceSupportsBiometrics_withNoBiometricHardware() { let stubAuthContext = StubAuthContext() + let alertFactory = StubAlertFactory() + let viewProvider = StubViewProvider() let plugin = FLALocalAuthPlugin( - contextFactory: StubAuthContextFactory(contexts: [stubAuthContext])) + contextFactory: StubAuthContextFactory(contexts: [stubAuthContext]), + alertFactory: alertFactory, viewProvider: viewProvider) stubAuthContext.expectBiometrics = true stubAuthContext.canEvaluateError = NSError(domain: "error", code: 0) @@ -320,11 +466,17 @@ class FLALocalAuthPluginTests: XCTestCase { func testGetEnrolledBiometricsWithFaceID() { let stubAuthContext = StubAuthContext() + let alertFactory = StubAlertFactory() + let viewProvider = StubViewProvider() let plugin = FLALocalAuthPlugin( - contextFactory: StubAuthContextFactory(contexts: [stubAuthContext])) + contextFactory: StubAuthContextFactory(contexts: [stubAuthContext]), + alertFactory: alertFactory, viewProvider: viewProvider) stubAuthContext.expectBiometrics = true - stubAuthContext.biometryType = .faceID + if #available(iOS 11, macOS 10.15, *) { + stubAuthContext.biometryType = .faceID + + } var error: FlutterError? let result = plugin.getEnrolledBiometricsWithError(&error) @@ -335,8 +487,11 @@ class FLALocalAuthPluginTests: XCTestCase { func testGetEnrolledBiometricsWithTouchID() { let stubAuthContext = StubAuthContext() + let alertFactory = StubAlertFactory() + let viewProvider = StubViewProvider() let plugin = FLALocalAuthPlugin( - contextFactory: StubAuthContextFactory(contexts: [stubAuthContext])) + contextFactory: StubAuthContextFactory(contexts: [stubAuthContext]), + alertFactory: alertFactory, viewProvider: viewProvider) stubAuthContext.expectBiometrics = true stubAuthContext.biometryType = .touchID @@ -350,8 +505,11 @@ class FLALocalAuthPluginTests: XCTestCase { func testGetEnrolledBiometricsWithoutEnrolledHardware() { let stubAuthContext = StubAuthContext() + let alertFactory = StubAlertFactory() + let viewProvider = StubViewProvider() let plugin = FLALocalAuthPlugin( - contextFactory: StubAuthContextFactory(contexts: [stubAuthContext])) + contextFactory: StubAuthContextFactory(contexts: [stubAuthContext]), + alertFactory: alertFactory, viewProvider: viewProvider) stubAuthContext.expectBiometrics = true stubAuthContext.canEvaluateError = NSError( @@ -365,8 +523,11 @@ class FLALocalAuthPluginTests: XCTestCase { func testIsDeviceSupportedHandlesSupported() { let stubAuthContext = StubAuthContext() + let alertFactory = StubAlertFactory() + let viewProvider = StubViewProvider() let plugin = FLALocalAuthPlugin( - contextFactory: StubAuthContextFactory(contexts: [stubAuthContext])) + contextFactory: StubAuthContextFactory(contexts: [stubAuthContext]), + alertFactory: alertFactory, viewProvider: viewProvider) var error: FlutterError? let result = plugin.isDeviceSupportedWithError(&error) @@ -378,8 +539,11 @@ class FLALocalAuthPluginTests: XCTestCase { let stubAuthContext = StubAuthContext() // An arbitrary error to cause canEvaluatePolicy to return false. stubAuthContext.canEvaluateError = NSError(domain: "error", code: 1) + let alertFactory = StubAlertFactory() + let viewProvider = StubViewProvider() let plugin = FLALocalAuthPlugin( - contextFactory: StubAuthContextFactory(contexts: [stubAuthContext])) + contextFactory: StubAuthContextFactory(contexts: [stubAuthContext]), + alertFactory: alertFactory, viewProvider: viewProvider) var error: FlutterError? let result = plugin.isDeviceSupportedWithError(&error) diff --git a/packages/local_auth/local_auth_darwin/darwin/local_auth_darwin.podspec b/packages/local_auth/local_auth_darwin/darwin/local_auth_darwin.podspec index e3947dd28175..9e2b96213be6 100644 --- a/packages/local_auth/local_auth_darwin/darwin/local_auth_darwin.podspec +++ b/packages/local_auth/local_auth_darwin/darwin/local_auth_darwin.podspec @@ -16,8 +16,11 @@ Downloaded by pub (not CocoaPods). s.documentation_url = 'https://pub.dev/packages/local_auth_darwin' s.source_files = 'local_auth_darwin/Sources/local_auth_darwin/**/*.{h,m}' s.public_header_files = 'local_auth_darwin/Sources/local_auth_darwin/include/**/*.h' - s.dependency 'Flutter' - s.platform = :ios, '12.0' + s.ios.dependency 'Flutter' + s.osx.dependency 'FlutterMacOS' + s.ios.deployment_target = '12.0' + s.osx.deployment_target = '10.14' + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } s.resource_bundles = {'local_auth_darwin_privacy' => ['local_auth_darwin/Sources/local_auth_darwin/Resources/PrivacyInfo.xcprivacy']} end diff --git a/packages/local_auth/local_auth_darwin/darwin/local_auth_darwin/Sources/local_auth_darwin/FLALocalAuthPlugin.m b/packages/local_auth/local_auth_darwin/darwin/local_auth_darwin/Sources/local_auth_darwin/FLALocalAuthPlugin.m index c8bc35980858..bc50a59a41f3 100644 --- a/packages/local_auth/local_auth_darwin/darwin/local_auth_darwin/Sources/local_auth_darwin/FLALocalAuthPlugin.m +++ b/packages/local_auth/local_auth_darwin/darwin/local_auth_darwin/Sources/local_auth_darwin/FLALocalAuthPlugin.m @@ -68,6 +68,140 @@ @implementation FLADefaultAuthContextFactory #pragma mark - +#if TARGET_OS_OSX +/// A default alert that wraps NSAlert. +// TODO(stuartmorgan): When converting to Swift, eliminate this class and use an extension to make +// NSAlert declare conformance to FLANSAlert. +@interface FLADefaultNSAlert : NSObject +/// Returns a wrapper for the given NSAlert. +- (instancetype)initWithAlert:(NSAlert *)alert NS_DESIGNATED_INITIALIZER; +- (instancetype)init NS_UNAVAILABLE; + +/// The wrapped alert. +@property(nonatomic) NSAlert *alert; +@end + +@implementation FLADefaultNSAlert +- (instancetype)initWithAlert:(NSAlert *)alert { + self = [super init]; + if (self) { + _alert = alert; + } + return self; +} + +- (NSString *)messageText { + return self.alert.messageText; +} + +- (void)setMessageText:(NSString *)messageText { + self.alert.messageText = messageText; +} + +- (NSButton *)addButtonWithTitle:(NSString *)title { + return [self.alert addButtonWithTitle:title]; +} + +- (void)beginSheetModalForWindow:(NSWindow *)sheetWindow + completionHandler:(void (^_Nullable)(NSModalResponse returnCode))handler { + [self.alert beginSheetModalForWindow:sheetWindow completionHandler:handler]; +} +@end +#elif TARGET_OS_IOS +/// A default alert controller that wraps UIAlertController. +// TODO(stuartmorgan): When converting to Swift, eliminate this class and use an extension to make +// UIAlertController declare conformance to FLAUIAlertController. +@interface FLADefaultUIAlertController : NSObject +/// Returns a wrapper for the given UIAlertController. +- (instancetype)initWithAlertController:(UIAlertController *)controller NS_DESIGNATED_INITIALIZER; +- (instancetype)init NS_UNAVAILABLE; + +/// The wrapped alert controller. +@property(nonatomic) UIAlertController *controller; +@end + +@implementation FLADefaultUIAlertController +- (instancetype)initWithAlertController:(UIAlertController *)controller { + self = [super init]; + if (self) { + _controller = controller; + } + return self; +} + +- (void)addAction:(UIAlertAction *)action { + [self.controller addAction:action]; +} + +- (void)presentOnViewController:(UIViewController *)presentingViewController + animated:(BOOL)flag + completion:(void (^__nullable)(void))completion { + [presentingViewController presentViewController:self.controller + animated:flag + completion:completion]; +} +@end +#endif + +/// A default alert factory that wraps standard UIAlertController and NSAlert allocation for iOS and +/// macOS respectfully. +@interface FLADefaultAlertFactory : NSObject +@end + +@implementation FLADefaultAlertFactory + +#if TARGET_OS_OSX +- (NSObject *)createAlert { + // TODO(stuartmorgan): When converting to Swift, just return NSAlert here. + return [[FLADefaultNSAlert alloc] initWithAlert:[[NSAlert alloc] init]]; +} +#elif TARGET_OS_IOS +- (NSObject *)createAlertControllerWithTitle:(nullable NSString *)title + message:(nullable NSString *)message + preferredStyle: + (UIAlertControllerStyle)preferredStyle { + // TODO(stuartmorgan): When converting to Swift, just return UIAlertController here. + return [[FLADefaultUIAlertController alloc] + initWithAlertController:[UIAlertController alertControllerWithTitle:title + message:message + preferredStyle:preferredStyle]]; +} +#endif +@end + +#pragma mark - + +/// A default view provider that wraps the FlutterPluginRegistrar. +// TODO(stuartmorgan): When converting to Swift, eliminate this class and use an extension to make +// FlutterPluginRegistrar declare conformance to FLAViewProvider. +@interface FLADefaultViewProvider : NSObject +/// Returns a wrapper for the given registrar. +- (instancetype)initWithRegistrar:(NSObject *)registrar + NS_DESIGNATED_INITIALIZER; +- (instancetype)init NS_UNAVAILABLE; + +/// The wrapped registrar. +@property(nonatomic) NSObject *registrar; +@end + +@implementation FLADefaultViewProvider +- (instancetype)initWithRegistrar:(NSObject *)registrar { + self = [super init]; + if (self) { + _registrar = registrar; + } + return self; +} + +#if TARGET_OS_OSX +- (NSView *)view { + return self.registrar.view; +} +#endif +@end + +#pragma mark - + /// A data container for sticky auth state. @interface FLAStickyAuthState : NSObject @property(nonatomic, strong, nonnull) FLADAuthOptions *options; @@ -94,27 +228,45 @@ - (instancetype)initWithOptions:(nonnull FLADAuthOptions *)options #pragma mark - +/// A flutter plugin for local authentication. @interface FLALocalAuthPlugin () + +/// Manages the last call state for sticky auth. @property(nonatomic, strong, nullable) FLAStickyAuthState *lastCallState; + +/// The factory to create LAContexts. @property(nonatomic, strong) NSObject *authContextFactory; + +/// The factory to create alerts. +@property(nonatomic, strong) NSObject *alertFactory; + +/// The Flutter view provider. +@property(nonatomic, strong) NSObject *viewProvider; @end @implementation FLALocalAuthPlugin + (void)registerWithRegistrar:(NSObject *)registrar { - FLALocalAuthPlugin *instance = [[FLALocalAuthPlugin alloc] init]; + NSObject *alertFactory = [[FLADefaultAlertFactory alloc] init]; + NSObject *authContextFactory = + [[FLADefaultAuthContextFactory alloc] init]; + FLALocalAuthPlugin *instance = [[FLALocalAuthPlugin alloc] + initWithContextFactory:authContextFactory + alertFactory:alertFactory + viewProvider:[[FLADefaultViewProvider alloc] initWithRegistrar:registrar]]; [registrar addApplicationDelegate:instance]; SetUpFLADLocalAuthApi([registrar messenger], instance); } -- (instancetype)init { - return [self initWithContextFactory:[[FLADefaultAuthContextFactory alloc] init]]; -} - -- (instancetype)initWithContextFactory:(NSObject *)factory { +/// Returns an instance that uses the given factory to create LAContexts. +- (instancetype)initWithContextFactory:(NSObject *)authFactory + alertFactory:(NSObject *)alertFactory + viewProvider:(NSObject *)viewProvider { self = [super init]; if (self) { - _authContextFactory = factory; + _viewProvider = viewProvider; + _authContextFactory = authFactory; + _alertFactory = alertFactory; } return self; } @@ -170,19 +322,23 @@ - (nullable NSNumber *)deviceCanSupportBiometricsWithError: return @NO; } -- (nullable NSArray *)getEnrolledBiometricsWithError: +- (nullable NSArray *)getEnrolledBiometricsWithError: (FlutterError *_Nullable __autoreleasing *_Nonnull)error { id context = [self.authContextFactory createAuthContext]; NSError *authError = nil; - NSMutableArray *biometrics = [[NSMutableArray alloc] init]; + NSMutableArray *biometrics = [[NSMutableArray alloc] init]; if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) { if (authError == nil) { - if (context.biometryType == LABiometryTypeFaceID) { - [biometrics addObject:[FLADAuthBiometricWrapper makeWithValue:FLADAuthBiometricFace]]; - } else if (context.biometryType == LABiometryTypeTouchID) { + if (@available(macOS 10.15, iOS 11.0, *)) { + if (context.biometryType == LABiometryTypeFaceID) { + [biometrics addObject:[[FLADAuthBiometricBox alloc] initWithValue:FLADAuthBiometricFace]]; + return biometrics; + } + } + if (context.biometryType == LABiometryTypeTouchID) { [biometrics - addObject:[FLADAuthBiometricWrapper makeWithValue:FLADAuthBiometricFingerprint]]; + addObject:[[FLADAuthBiometricBox alloc] initWithValue:FLADAuthBiometricFingerprint]]; } } } @@ -201,10 +357,21 @@ - (void)showAlertWithMessage:(NSString *)message dismissButtonTitle:(NSString *)dismissButtonTitle openSettingsButtonTitle:(NSString *)openSettingsButtonTitle completion:(FLADAuthCompletion)completion { - UIAlertController *alert = - [UIAlertController alertControllerWithTitle:@"" - message:message - preferredStyle:UIAlertControllerStyleAlert]; +#if TARGET_OS_OSX + id alert = [_alertFactory createAlert]; + alert.messageText = message; + [alert addButtonWithTitle:dismissButtonTitle]; + NSWindow *window = self.viewProvider.view.window; + [alert beginSheetModalForWindow:window + completionHandler:^(NSModalResponse returnCode) { + [self handleSucceeded:NO withCompletion:completion]; + }]; + return; +#elif TARGET_OS_IOS + id alert = + [_alertFactory createAlertControllerWithTitle:@"" + message:message + preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:dismissButtonTitle style:UIAlertActionStyleDefault @@ -227,9 +394,11 @@ - (void)showAlertWithMessage:(NSString *)message }]; [alert addAction:additionalAction]; } - [[UIApplication sharedApplication].delegate.window.rootViewController presentViewController:alert - animated:YES - completion:nil]; + [alert + presentOnViewController:[UIApplication sharedApplication].delegate.window.rootViewController + animated:YES + completion:nil]; +#endif } - (void)handleAuthReplyWithSuccess:(BOOL)success @@ -305,6 +474,8 @@ - (void)handleError:(NSError *)authError #pragma mark - AppDelegate +// This method is called when the app is resumed from the background only on iOS +#if TARGET_OS_IOS - (void)applicationDidBecomeActive:(UIApplication *)application { if (self.lastCallState != nil) { [self authenticateWithOptions:_lastCallState.options @@ -312,5 +483,6 @@ - (void)applicationDidBecomeActive:(UIApplication *)application { completion:_lastCallState.resultHandler]; } } +#endif @end diff --git a/packages/local_auth/local_auth_darwin/darwin/local_auth_darwin/Sources/local_auth_darwin/include/local_auth_darwin/FLALocalAuthPlugin.h b/packages/local_auth/local_auth_darwin/darwin/local_auth_darwin/Sources/local_auth_darwin/include/local_auth_darwin/FLALocalAuthPlugin.h index 7168f350fe04..e54e24be490f 100644 --- a/packages/local_auth/local_auth_darwin/darwin/local_auth_darwin/Sources/local_auth_darwin/include/local_auth_darwin/FLALocalAuthPlugin.h +++ b/packages/local_auth/local_auth_darwin/darwin/local_auth_darwin/Sources/local_auth_darwin/include/local_auth_darwin/FLALocalAuthPlugin.h @@ -1,10 +1,18 @@ // 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 +#if TARGET_OS_OSX +#import +#elif TARGET_OS_IOS #import +#endif #import "messages.g.h" @interface FLALocalAuthPlugin : NSObject + +- (instancetype)init NS_UNAVAILABLE; + @end diff --git a/packages/local_auth/local_auth_darwin/darwin/local_auth_darwin/Sources/local_auth_darwin/include/local_auth_darwin/FLALocalAuthPlugin_Test.h b/packages/local_auth/local_auth_darwin/darwin/local_auth_darwin/Sources/local_auth_darwin/include/local_auth_darwin/FLALocalAuthPlugin_Test.h index cfba07b8fb4f..685e61d4c8cc 100644 --- a/packages/local_auth/local_auth_darwin/darwin/local_auth_darwin/Sources/local_auth_darwin/include/local_auth_darwin/FLALocalAuthPlugin_Test.h +++ b/packages/local_auth/local_auth_darwin/darwin/local_auth_darwin/Sources/local_auth_darwin/include/local_auth_darwin/FLALocalAuthPlugin_Test.h @@ -1,8 +1,14 @@ // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#import +#if TARGET_OS_OSX +#import +#elif TARGET_OS_IOS #import +#endif + #import NS_ASSUME_NONNULL_BEGIN @@ -22,13 +28,72 @@ NS_ASSUME_NONNULL_BEGIN /// Protocol for a source of FLADAuthContext instances. Used to allow context injection in unit /// tests. @protocol FLADAuthContextFactory +- (NSObject *)createAuthContext; +@end + +#pragma mark - + +#if TARGET_OS_OSX +/// Protocol for interacting with NSAlert instances, abstracted to allow using mock/fake instances +/// in unit tests. +@protocol FLANSAlert @required -- (id)createAuthContext; +@property(copy) NSString *messageText; +- (NSButton *)addButtonWithTitle:(NSString *)title; +- (void)beginSheetModalForWindow:(NSWindow *)sheetWindow + completionHandler:(void (^_Nullable)(NSModalResponse returnCode))handler; @end +#endif // TARGET_OS_OSX + +#if TARGET_OS_IOS +/// Protocol for interacting with UIAlertController instances, abstracted to allow using mock/fake +/// instances in unit tests. +@protocol FLAUIAlertController +@required +- (void)addAction:(UIAlertAction *)action; +// Reversed wrapper of presentViewController:... since the protocol can't be passed to the real +// method. +- (void)presentOnViewController:(UIViewController *)presentingViewController + animated:(BOOL)flag + completion:(void (^__nullable)(void))completion NS_SWIFT_DISABLE_ASYNC; +@end +#endif // TARGET_OS_IOS + +/// Protocol for a source of alert factory that wraps standard UIAlertController and NSAlert +/// allocation for iOS and macOS respectfully. Used to allow context injection in unit tests. +@protocol FLADAlertFactory + +#if TARGET_OS_OSX +- (NSObject *)createAlert; +#elif TARGET_OS_IOS +- (NSObject *)createAlertControllerWithTitle:(nullable NSString *)title + message:(nullable NSString *)message + preferredStyle: + (UIAlertControllerStyle)preferredStyle; +#endif + +@end + +/// Protocol for a provider of the view containing the Flutter content, abstracted to allow using +/// mock/fake instances in unit tests. +@protocol FLAViewProvider +@required +#if TARGET_OS_OSX +@property(readonly, nonatomic) NSView *view; +#elif TARGET_OS_IOS +// TODO(stuartmorgan): Add a view accessor once https://github.com/flutter/flutter/issues/104117 +// is resolved, and use that in 'showAlertWithMessage:...'. +#endif + +@end + +#pragma mark - @interface FLALocalAuthPlugin () /// Returns an instance that uses the given factory to create LAContexts. -- (instancetype)initWithContextFactory:(NSObject *)factory +- (instancetype _Nonnull)initWithContextFactory:(NSObject *)authFactory + alertFactory:(NSObject *)alertFactory + viewProvider:(NSObject *)viewProvider NS_DESIGNATED_INITIALIZER; @end diff --git a/packages/local_auth/local_auth_darwin/darwin/local_auth_darwin/Sources/local_auth_darwin/include/local_auth_darwin/messages.g.h b/packages/local_auth/local_auth_darwin/darwin/local_auth_darwin/Sources/local_auth_darwin/include/local_auth_darwin/messages.g.h index e15d520472a8..3e64f6e9e0ac 100644 --- a/packages/local_auth/local_auth_darwin/darwin/local_auth_darwin/Sources/local_auth_darwin/include/local_auth_darwin/messages.g.h +++ b/packages/local_auth/local_auth_darwin/darwin/local_auth_darwin/Sources/local_auth_darwin/include/local_auth_darwin/messages.g.h @@ -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 (v13.1.2), do not edit directly. +// Autogenerated from Pigeon (v22.4.0), do not edit directly. // See also: https://pub.dev/packages/pigeon #import @@ -48,7 +48,6 @@ typedef NS_ENUM(NSUInteger, FLADAuthBiometric) { @class FLADAuthStrings; @class FLADAuthOptions; @class FLADAuthResultDetails; -@class FLADAuthBiometricWrapper; /// Pigeon version of IOSAuthMessages, plus the authorization reason. /// @@ -58,14 +57,14 @@ typedef NS_ENUM(NSUInteger, FLADAuthBiometric) { - (instancetype)init NS_UNAVAILABLE; + (instancetype)makeWithReason:(NSString *)reason lockOut:(NSString *)lockOut - goToSettingsButton:(NSString *)goToSettingsButton - goToSettingsDescription:(NSString *)goToSettingsDescription + goToSettingsButton:(nullable NSString *)goToSettingsButton + goToSettingsDescription:(nullable NSString *)goToSettingsDescription cancelButton:(NSString *)cancelButton localizedFallbackTitle:(nullable NSString *)localizedFallbackTitle; @property(nonatomic, copy) NSString *reason; @property(nonatomic, copy) NSString *lockOut; -@property(nonatomic, copy) NSString *goToSettingsButton; -@property(nonatomic, copy) NSString *goToSettingsDescription; +@property(nonatomic, copy, nullable) NSString *goToSettingsButton; +@property(nonatomic, copy, nullable) NSString *goToSettingsDescription; @property(nonatomic, copy) NSString *cancelButton; @property(nonatomic, copy, nullable) NSString *localizedFallbackTitle; @end @@ -95,15 +94,8 @@ typedef NS_ENUM(NSUInteger, FLADAuthBiometric) { @property(nonatomic, copy, nullable) NSString *errorDetails; @end -@interface FLADAuthBiometricWrapper : NSObject -/// `init` unavailable to enforce nonnull fields, see the `make` class method. -- (instancetype)init NS_UNAVAILABLE; -+ (instancetype)makeWithValue:(FLADAuthBiometric)value; -@property(nonatomic, assign) FLADAuthBiometric value; -@end - -/// The codec used by FLADLocalAuthApi. -NSObject *FLADLocalAuthApiGetCodec(void); +/// The codec used by all APIs. +NSObject *FLADGetMessagesCodec(void); @protocol FLADLocalAuthApi /// Returns true if this device supports authentication. @@ -119,7 +111,7 @@ NSObject *FLADLocalAuthApiGetCodec(void); /// without additional setup. /// /// @return `nil` only when `error != nil`. -- (nullable NSArray *)getEnrolledBiometricsWithError: +- (nullable NSArray *)getEnrolledBiometricsWithError: (FlutterError *_Nullable *_Nonnull)error; /// Attempts to authenticate the user with the provided [options], and using /// [strings] for any UI. @@ -132,4 +124,8 @@ NSObject *FLADLocalAuthApiGetCodec(void); extern void SetUpFLADLocalAuthApi(id binaryMessenger, NSObject *_Nullable api); +extern void SetUpFLADLocalAuthApiWithSuffix(id binaryMessenger, + NSObject *_Nullable api, + NSString *messageChannelSuffix); + NS_ASSUME_NONNULL_END diff --git a/packages/local_auth/local_auth_darwin/darwin/local_auth_darwin/Sources/local_auth_darwin/messages.g.m b/packages/local_auth/local_auth_darwin/darwin/local_auth_darwin/Sources/local_auth_darwin/messages.g.m index 6ab8ee5edf95..b43fcf138b71 100644 --- a/packages/local_auth/local_auth_darwin/darwin/local_auth_darwin/Sources/local_auth_darwin/messages.g.m +++ b/packages/local_auth/local_auth_darwin/darwin/local_auth_darwin/Sources/local_auth_darwin/messages.g.m @@ -1,11 +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 (v13.1.2), do not edit directly. +// Autogenerated from Pigeon (v22.4.0), do not edit directly. // See also: https://pub.dev/packages/pigeon -// The line below is manually edited. See: -// https://github.com/flutter/flutter/issues/147587 #import "./include/local_auth_darwin/messages.g.h" #if TARGET_OS_OSX @@ -18,7 +16,7 @@ #error File requires ARC to be enabled. #endif -static NSArray *wrapResult(id result, FlutterError *error) { +static NSArray *wrapResult(id result, FlutterError *error) { if (error) { return @[ error.code ?: [NSNull null], error.message ?: [NSNull null], error.details ?: [NSNull null] @@ -27,7 +25,7 @@ return @[ result ?: [NSNull null] ]; } -static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) { +static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) { id result = array[key]; return (result == [NSNull null]) ? nil : result; } @@ -55,34 +53,28 @@ - (instancetype)initWithValue:(FLADAuthBiometric)value { @end @interface FLADAuthStrings () -+ (FLADAuthStrings *)fromList:(NSArray *)list; -+ (nullable FLADAuthStrings *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; ++ (FLADAuthStrings *)fromList:(NSArray *)list; ++ (nullable FLADAuthStrings *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; @end @interface FLADAuthOptions () -+ (FLADAuthOptions *)fromList:(NSArray *)list; -+ (nullable FLADAuthOptions *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; ++ (FLADAuthOptions *)fromList:(NSArray *)list; ++ (nullable FLADAuthOptions *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; @end @interface FLADAuthResultDetails () -+ (FLADAuthResultDetails *)fromList:(NSArray *)list; -+ (nullable FLADAuthResultDetails *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; -@end - -@interface FLADAuthBiometricWrapper () -+ (FLADAuthBiometricWrapper *)fromList:(NSArray *)list; -+ (nullable FLADAuthBiometricWrapper *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; ++ (FLADAuthResultDetails *)fromList:(NSArray *)list; ++ (nullable FLADAuthResultDetails *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; @end @implementation FLADAuthStrings + (instancetype)makeWithReason:(NSString *)reason lockOut:(NSString *)lockOut - goToSettingsButton:(NSString *)goToSettingsButton - goToSettingsDescription:(NSString *)goToSettingsDescription + goToSettingsButton:(nullable NSString *)goToSettingsButton + goToSettingsDescription:(nullable NSString *)goToSettingsDescription cancelButton:(NSString *)cancelButton localizedFallbackTitle:(nullable NSString *)localizedFallbackTitle { FLADAuthStrings *pigeonResult = [[FLADAuthStrings alloc] init]; @@ -94,7 +86,7 @@ + (instancetype)makeWithReason:(NSString *)reason pigeonResult.localizedFallbackTitle = localizedFallbackTitle; return pigeonResult; } -+ (FLADAuthStrings *)fromList:(NSArray *)list { ++ (FLADAuthStrings *)fromList:(NSArray *)list { FLADAuthStrings *pigeonResult = [[FLADAuthStrings alloc] init]; pigeonResult.reason = GetNullableObjectAtIndex(list, 0); pigeonResult.lockOut = GetNullableObjectAtIndex(list, 1); @@ -104,10 +96,10 @@ + (FLADAuthStrings *)fromList:(NSArray *)list { pigeonResult.localizedFallbackTitle = GetNullableObjectAtIndex(list, 5); return pigeonResult; } -+ (nullable FLADAuthStrings *)nullableFromList:(NSArray *)list { ++ (nullable FLADAuthStrings *)nullableFromList:(NSArray *)list { return (list) ? [FLADAuthStrings fromList:list] : nil; } -- (NSArray *)toList { +- (NSArray *)toList { return @[ self.reason ?: [NSNull null], self.lockOut ?: [NSNull null], @@ -129,17 +121,17 @@ + (instancetype)makeWithBiometricOnly:(BOOL)biometricOnly pigeonResult.useErrorDialogs = useErrorDialogs; return pigeonResult; } -+ (FLADAuthOptions *)fromList:(NSArray *)list { ++ (FLADAuthOptions *)fromList:(NSArray *)list { FLADAuthOptions *pigeonResult = [[FLADAuthOptions alloc] init]; pigeonResult.biometricOnly = [GetNullableObjectAtIndex(list, 0) boolValue]; pigeonResult.sticky = [GetNullableObjectAtIndex(list, 1) boolValue]; pigeonResult.useErrorDialogs = [GetNullableObjectAtIndex(list, 2) boolValue]; return pigeonResult; } -+ (nullable FLADAuthOptions *)nullableFromList:(NSArray *)list { ++ (nullable FLADAuthOptions *)nullableFromList:(NSArray *)list { return (list) ? [FLADAuthOptions fromList:list] : nil; } -- (NSArray *)toList { +- (NSArray *)toList { return @[ @(self.biometricOnly), @(self.sticky), @@ -158,117 +150,123 @@ + (instancetype)makeWithResult:(FLADAuthResult)result pigeonResult.errorDetails = errorDetails; return pigeonResult; } -+ (FLADAuthResultDetails *)fromList:(NSArray *)list { ++ (FLADAuthResultDetails *)fromList:(NSArray *)list { FLADAuthResultDetails *pigeonResult = [[FLADAuthResultDetails alloc] init]; - pigeonResult.result = [GetNullableObjectAtIndex(list, 0) integerValue]; + FLADAuthResultBox *boxedFLADAuthResult = GetNullableObjectAtIndex(list, 0); + pigeonResult.result = boxedFLADAuthResult.value; pigeonResult.errorMessage = GetNullableObjectAtIndex(list, 1); pigeonResult.errorDetails = GetNullableObjectAtIndex(list, 2); return pigeonResult; } -+ (nullable FLADAuthResultDetails *)nullableFromList:(NSArray *)list { ++ (nullable FLADAuthResultDetails *)nullableFromList:(NSArray *)list { return (list) ? [FLADAuthResultDetails fromList:list] : nil; } -- (NSArray *)toList { +- (NSArray *)toList { return @[ - @(self.result), + [[FLADAuthResultBox alloc] initWithValue:self.result], self.errorMessage ?: [NSNull null], self.errorDetails ?: [NSNull null], ]; } @end -@implementation FLADAuthBiometricWrapper -+ (instancetype)makeWithValue:(FLADAuthBiometric)value { - FLADAuthBiometricWrapper *pigeonResult = [[FLADAuthBiometricWrapper alloc] init]; - pigeonResult.value = value; - return pigeonResult; -} -+ (FLADAuthBiometricWrapper *)fromList:(NSArray *)list { - FLADAuthBiometricWrapper *pigeonResult = [[FLADAuthBiometricWrapper alloc] init]; - pigeonResult.value = [GetNullableObjectAtIndex(list, 0) integerValue]; - return pigeonResult; -} -+ (nullable FLADAuthBiometricWrapper *)nullableFromList:(NSArray *)list { - return (list) ? [FLADAuthBiometricWrapper fromList:list] : nil; -} -- (NSArray *)toList { - return @[ - @(self.value), - ]; -} -@end - -@interface FLADLocalAuthApiCodecReader : FlutterStandardReader +@interface FLADMessagesPigeonCodecReader : FlutterStandardReader @end -@implementation FLADLocalAuthApiCodecReader +@implementation FLADMessagesPigeonCodecReader - (nullable id)readValueOfType:(UInt8)type { switch (type) { - case 128: - return [FLADAuthBiometricWrapper fromList:[self readValue]]; - case 129: - return [FLADAuthOptions fromList:[self readValue]]; - case 130: - return [FLADAuthResultDetails fromList:[self readValue]]; + case 129: { + NSNumber *enumAsNumber = [self readValue]; + return enumAsNumber == nil + ? nil + : [[FLADAuthResultBox alloc] initWithValue:[enumAsNumber integerValue]]; + } + case 130: { + NSNumber *enumAsNumber = [self readValue]; + return enumAsNumber == nil + ? nil + : [[FLADAuthBiometricBox alloc] initWithValue:[enumAsNumber integerValue]]; + } case 131: return [FLADAuthStrings fromList:[self readValue]]; + case 132: + return [FLADAuthOptions fromList:[self readValue]]; + case 133: + return [FLADAuthResultDetails fromList:[self readValue]]; default: return [super readValueOfType:type]; } } @end -@interface FLADLocalAuthApiCodecWriter : FlutterStandardWriter +@interface FLADMessagesPigeonCodecWriter : FlutterStandardWriter @end -@implementation FLADLocalAuthApiCodecWriter +@implementation FLADMessagesPigeonCodecWriter - (void)writeValue:(id)value { - if ([value isKindOfClass:[FLADAuthBiometricWrapper class]]) { - [self writeByte:128]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FLADAuthOptions class]]) { + if ([value isKindOfClass:[FLADAuthResultBox class]]) { + FLADAuthResultBox *box = (FLADAuthResultBox *)value; [self writeByte:129]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FLADAuthResultDetails class]]) { + [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; + } else if ([value isKindOfClass:[FLADAuthBiometricBox class]]) { + FLADAuthBiometricBox *box = (FLADAuthBiometricBox *)value; [self writeByte:130]; - [self writeValue:[value toList]]; + [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; } else if ([value isKindOfClass:[FLADAuthStrings class]]) { [self writeByte:131]; [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FLADAuthOptions class]]) { + [self writeByte:132]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FLADAuthResultDetails class]]) { + [self writeByte:133]; + [self writeValue:[value toList]]; } else { [super writeValue:value]; } } @end -@interface FLADLocalAuthApiCodecReaderWriter : FlutterStandardReaderWriter +@interface FLADMessagesPigeonCodecReaderWriter : FlutterStandardReaderWriter @end -@implementation FLADLocalAuthApiCodecReaderWriter +@implementation FLADMessagesPigeonCodecReaderWriter - (FlutterStandardWriter *)writerWithData:(NSMutableData *)data { - return [[FLADLocalAuthApiCodecWriter alloc] initWithData:data]; + return [[FLADMessagesPigeonCodecWriter alloc] initWithData:data]; } - (FlutterStandardReader *)readerWithData:(NSData *)data { - return [[FLADLocalAuthApiCodecReader alloc] initWithData:data]; + return [[FLADMessagesPigeonCodecReader alloc] initWithData:data]; } @end -NSObject *FLADLocalAuthApiGetCodec(void) { +NSObject *FLADGetMessagesCodec(void) { static FlutterStandardMessageCodec *sSharedObject = nil; static dispatch_once_t sPred = 0; dispatch_once(&sPred, ^{ - FLADLocalAuthApiCodecReaderWriter *readerWriter = - [[FLADLocalAuthApiCodecReaderWriter alloc] init]; + FLADMessagesPigeonCodecReaderWriter *readerWriter = + [[FLADMessagesPigeonCodecReaderWriter alloc] init]; sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter]; }); return sSharedObject; } - void SetUpFLADLocalAuthApi(id binaryMessenger, NSObject *api) { + SetUpFLADLocalAuthApiWithSuffix(binaryMessenger, api, @""); +} + +void SetUpFLADLocalAuthApiWithSuffix(id binaryMessenger, + NSObject *api, + NSString *messageChannelSuffix) { + messageChannelSuffix = messageChannelSuffix.length > 0 + ? [NSString stringWithFormat:@".%@", messageChannelSuffix] + : @""; /// Returns true if this device supports authentication. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.local_auth_darwin.LocalAuthApi.isDeviceSupported" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.local_auth_darwin." + @"LocalAuthApi.isDeviceSupported", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FLADLocalAuthApiGetCodec()]; + codec:FLADGetMessagesCodec()]; if (api) { NSCAssert( [api respondsToSelector:@selector(isDeviceSupportedWithError:)], @@ -287,10 +285,12 @@ void SetUpFLADLocalAuthApi(id binaryMessenger, /// any biometrics are enrolled or not. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.local_auth_darwin.LocalAuthApi.deviceCanSupportBiometrics" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.local_auth_darwin." + @"LocalAuthApi.deviceCanSupportBiometrics", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FLADLocalAuthApiGetCodec()]; + codec:FLADGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(deviceCanSupportBiometricsWithError:)], @"FLADLocalAuthApi api (%@) doesn't respond to " @@ -309,9 +309,12 @@ void SetUpFLADLocalAuthApi(id binaryMessenger, /// without additional setup. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.local_auth_darwin.LocalAuthApi.getEnrolledBiometrics" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.local_auth_darwin." + @"LocalAuthApi.getEnrolledBiometrics", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FLADLocalAuthApiGetCodec()]; + codec:FLADGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(getEnrolledBiometricsWithError:)], @"FLADLocalAuthApi api (%@) doesn't respond to " @@ -319,7 +322,7 @@ void SetUpFLADLocalAuthApi(id binaryMessenger, api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { FlutterError *error; - NSArray *output = [api getEnrolledBiometricsWithError:&error]; + NSArray *output = [api getEnrolledBiometricsWithError:&error]; callback(wrapResult(output, error)); }]; } else { @@ -330,16 +333,20 @@ void SetUpFLADLocalAuthApi(id binaryMessenger, /// [strings] for any UI. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.local_auth_darwin.LocalAuthApi.authenticate" + initWithName:[NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.local_auth_darwin.LocalAuthApi.authenticate", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FLADLocalAuthApiGetCodec()]; + codec:FLADGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(authenticateWithOptions:strings:completion:)], @"FLADLocalAuthApi api (%@) doesn't respond to " @"@selector(authenticateWithOptions:strings:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; FLADAuthOptions *arg_options = GetNullableObjectAtIndex(args, 0); FLADAuthStrings *arg_strings = GetNullableObjectAtIndex(args, 1); [api authenticateWithOptions:arg_options diff --git a/packages/local_auth/local_auth_darwin/example/.gitignore b/packages/local_auth/local_auth_darwin/example/.gitignore new file mode 100644 index 000000000000..29a3a5017f04 --- /dev/null +++ b/packages/local_auth/local_auth_darwin/example/.gitignore @@ -0,0 +1,43 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/packages/local_auth/local_auth_darwin/example/.metadata b/packages/local_auth/local_auth_darwin/example/.metadata new file mode 100644 index 000000000000..87b4b9ab251c --- /dev/null +++ b/packages/local_auth/local_auth_darwin/example/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "68bfaea224880b488c617afe30ab12091ea8fa4e" + channel: "stable" + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 68bfaea224880b488c617afe30ab12091ea8fa4e + base_revision: 68bfaea224880b488c617afe30ab12091ea8fa4e + - platform: macos + create_revision: 68bfaea224880b488c617afe30ab12091ea8fa4e + base_revision: 68bfaea224880b488c617afe30ab12091ea8fa4e + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/packages/local_auth/local_auth_darwin/example/macos/.gitignore b/packages/local_auth/local_auth_darwin/example/macos/.gitignore new file mode 100644 index 000000000000..746adbb6b9e1 --- /dev/null +++ b/packages/local_auth/local_auth_darwin/example/macos/.gitignore @@ -0,0 +1,7 @@ +# Flutter-related +**/Flutter/ephemeral/ +**/Pods/ + +# Xcode-related +**/dgph +**/xcuserdata/ diff --git a/packages/local_auth/local_auth_darwin/example/macos/Flutter/Flutter-Debug.xcconfig b/packages/local_auth/local_auth_darwin/example/macos/Flutter/Flutter-Debug.xcconfig new file mode 100644 index 000000000000..4b81f9b2d200 --- /dev/null +++ b/packages/local_auth/local_auth_darwin/example/macos/Flutter/Flutter-Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/packages/local_auth/local_auth_darwin/example/macos/Flutter/Flutter-Release.xcconfig b/packages/local_auth/local_auth_darwin/example/macos/Flutter/Flutter-Release.xcconfig new file mode 100644 index 000000000000..5caa9d1579e4 --- /dev/null +++ b/packages/local_auth/local_auth_darwin/example/macos/Flutter/Flutter-Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/packages/local_auth/local_auth_darwin/example/macos/Podfile b/packages/local_auth/local_auth_darwin/example/macos/Podfile new file mode 100644 index 000000000000..29c8eb3294cb --- /dev/null +++ b/packages/local_auth/local_auth_darwin/example/macos/Podfile @@ -0,0 +1,42 @@ +platform :osx, '10.14' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_macos_podfile_setup + +target 'Runner' do + use_frameworks! + + flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) + target 'RunnerTests' do + inherit! :search_paths + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_macos_build_settings(target) + end +end diff --git a/packages/local_auth/local_auth_darwin/example/macos/Runner.xcodeproj/project.pbxproj b/packages/local_auth/local_auth_darwin/example/macos/Runner.xcodeproj/project.pbxproj new file mode 100644 index 000000000000..8392afcc7297 --- /dev/null +++ b/packages/local_auth/local_auth_darwin/example/macos/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,820 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXAggregateTarget section */ + 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; + buildPhases = ( + 33CC111E2044C6BF0003C045 /* ShellScript */, + ); + dependencies = ( + ); + name = "Flutter Assemble"; + productName = FLX; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 274905EC52005E05DF633ACA /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 91FACED086369F6DB644E8B1 /* Pods_Runner.framework */; }; + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + 3A858B24A41D64C4BF302405 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB20D00B3AAB343668A80A59 /* Pods_RunnerTests.framework */; }; + E62C10892C07DA2A000E3CCC /* FLALocalAuthPluginTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E62C10882C07DA2A000E3CCC /* FLALocalAuthPluginTests.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC10EC2044A3C60003C045; + remoteInfo = Runner; + }; + 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC111A2044C6BA0003C045; + remoteInfo = FLX; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 33CC110E2044A8840003C045 /* Bundle Framework */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Bundle Framework"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 09A6D0964FC42F6CEB3383B0 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; + 33CC10ED2044A3C60003C045 /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; + 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; + 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; + 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; + 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 6DC2CC18007F1B81C5CD38EB /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; + 6E148E4EE27FBB2587C8CCE0 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 7C88C93F66E851DCCA28120C /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; + 8CA026E1D618025C0D52DD90 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 91FACED086369F6DB644E8B1 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + CB20D00B3AAB343668A80A59 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + DC8BF0B04B7666C6A6EA0D26 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + E62C10882C07DA2A000E3CCC /* FLALocalAuthPluginTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FLALocalAuthPluginTests.swift; path = ../../../darwin/Tests/FLALocalAuthPluginTests.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 331C80D2294CF70F00263BE5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3A858B24A41D64C4BF302405 /* Pods_RunnerTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10EA2044A3C60003C045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 274905EC52005E05DF633ACA /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 331C80D6294CF71000263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + E62C10882C07DA2A000E3CCC /* FLALocalAuthPluginTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; + 33BA886A226E78AF003329D5 /* Configs */ = { + isa = PBXGroup; + children = ( + 33E5194F232828860026EE4D /* AppInfo.xcconfig */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, + ); + path = Configs; + sourceTree = ""; + }; + 33CC10E42044A3C60003C045 = { + isa = PBXGroup; + children = ( + 33FAB671232836740065AC1E /* Runner */, + 33CEB47122A05771004F2AC0 /* Flutter */, + 331C80D6294CF71000263BE5 /* RunnerTests */, + 33CC10EE2044A3C60003C045 /* Products */, + D73912EC22F37F3D000D13A0 /* Frameworks */, + 42D886FD4D6805989133E5D0 /* Pods */, + ); + sourceTree = ""; + }; + 33CC10EE2044A3C60003C045 /* Products */ = { + isa = PBXGroup; + children = ( + 33CC10ED2044A3C60003C045 /* example.app */, + 331C80D5294CF71000263BE5 /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 33CC11242044D66E0003C045 /* Resources */ = { + isa = PBXGroup; + children = ( + 33CC10F22044A3C60003C045 /* Assets.xcassets */, + 33CC10F42044A3C60003C045 /* MainMenu.xib */, + 33CC10F72044A3C60003C045 /* Info.plist */, + ); + name = Resources; + path = ..; + sourceTree = ""; + }; + 33CEB47122A05771004F2AC0 /* Flutter */ = { + isa = PBXGroup; + children = ( + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, + ); + path = Flutter; + sourceTree = ""; + }; + 33FAB671232836740065AC1E /* Runner */ = { + isa = PBXGroup; + children = ( + 33CC10F02044A3C60003C045 /* AppDelegate.swift */, + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, + 33E51913231747F40026EE4D /* DebugProfile.entitlements */, + 33E51914231749380026EE4D /* Release.entitlements */, + 33CC11242044D66E0003C045 /* Resources */, + 33BA886A226E78AF003329D5 /* Configs */, + ); + path = Runner; + sourceTree = ""; + }; + 42D886FD4D6805989133E5D0 /* Pods */ = { + isa = PBXGroup; + children = ( + 09A6D0964FC42F6CEB3383B0 /* Pods-Runner.debug.xcconfig */, + 8CA026E1D618025C0D52DD90 /* Pods-Runner.release.xcconfig */, + DC8BF0B04B7666C6A6EA0D26 /* Pods-Runner.profile.xcconfig */, + 7C88C93F66E851DCCA28120C /* Pods-RunnerTests.debug.xcconfig */, + 6E148E4EE27FBB2587C8CCE0 /* Pods-RunnerTests.release.xcconfig */, + 6DC2CC18007F1B81C5CD38EB /* Pods-RunnerTests.profile.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + D73912EC22F37F3D000D13A0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 91FACED086369F6DB644E8B1 /* Pods_Runner.framework */, + CB20D00B3AAB343668A80A59 /* Pods_RunnerTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 331C80D4294CF70F00263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + 079FC72150E3D6C338EFB4FA /* [CP] Check Pods Manifest.lock */, + 331C80D1294CF70F00263BE5 /* Sources */, + 331C80D2294CF70F00263BE5 /* Frameworks */, + 331C80D3294CF70F00263BE5 /* Resources */, + 4A22C8F8819194F5DFFCC074 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 331C80DA294CF71000263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C80D5294CF71000263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 33CC10EC2044A3C60003C045 /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 15765A7727B689B854708867 /* [CP] Check Pods Manifest.lock */, + 33CC10E92044A3C60003C045 /* Sources */, + 33CC10EA2044A3C60003C045 /* Frameworks */, + 33CC10EB2044A3C60003C045 /* Resources */, + 33CC110E2044A8840003C045 /* Bundle Framework */, + 3399D490228B24CF009A79C7 /* ShellScript */, + 42F7693C713BF5CD10521737 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 33CC11202044C79F0003C045 /* PBXTargetDependency */, + ); + name = Runner; + productName = Runner; + productReference = 33CC10ED2044A3C60003C045 /* example.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 33CC10E52044A3C60003C045 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 331C80D4294CF70F00263BE5 = { + CreatedOnToolsVersion = 14.0; + LastSwiftMigration = 1540; + TestTargetID = 33CC10EC2044A3C60003C045; + }; + 33CC10EC2044A3C60003C045 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1100; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 1; + }; + }; + }; + 33CC111A2044C6BA0003C045 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Manual; + }; + }; + }; + buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 33CC10E42044A3C60003C045; + productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 33CC10EC2044A3C60003C045 /* Runner */, + 331C80D4294CF70F00263BE5 /* RunnerTests */, + 33CC111A2044C6BA0003C045 /* Flutter Assemble */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 331C80D3294CF70F00263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10EB2044A3C60003C045 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 079FC72150E3D6C338EFB4FA /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 15765A7727B689B854708867 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 3399D490228B24CF009A79C7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; + }; + 33CC111E2044C6BF0003C045 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + Flutter/ephemeral/FlutterInputs.xcfilelist, + ); + inputPaths = ( + Flutter/ephemeral/tripwire, + ); + outputFileListPaths = ( + Flutter/ephemeral/FlutterOutputs.xcfilelist, + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; + }; + 42F7693C713BF5CD10521737 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 4A22C8F8819194F5DFFCC074 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-RunnerTests/Pods-RunnerTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-RunnerTests/Pods-RunnerTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RunnerTests/Pods-RunnerTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 331C80D1294CF70F00263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E62C10892C07DA2A000E3CCC /* FLALocalAuthPluginTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10E92044A3C60003C045 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 331C80DA294CF71000263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC10EC2044A3C60003C045 /* Runner */; + targetProxy = 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */; + }; + 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; + targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 33CC10F52044A3C60003C045 /* Base */, + ); + name = MainMenu.xib; + path = Runner; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 331C80DB294CF71000263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7C88C93F66E851DCCA28120C /* Pods-RunnerTests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.example.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/example.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/example"; + }; + name = Debug; + }; + 331C80DC294CF71000263BE5 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 6E148E4EE27FBB2587C8CCE0 /* Pods-RunnerTests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.example.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/example.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/example"; + }; + name = Release; + }; + 331C80DD294CF71000263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 6DC2CC18007F1B81C5CD38EB /* Pods-RunnerTests.profile.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.example.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/example.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/example"; + }; + name = Profile; + }; + 338D0CE9231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.14; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Profile; + }; + 338D0CEA231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Profile; + }; + 338D0CEB231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Profile; + }; + 33CC10F92044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.14; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 33CC10FA2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.14; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 33CC10FC2044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 33CC10FD2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 33CC111C2044C6BA0003C045 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 33CC111D2044C6BA0003C045 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C80DB294CF71000263BE5 /* Debug */, + 331C80DC294CF71000263BE5 /* Release */, + 331C80DD294CF71000263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10F92044A3C60003C045 /* Debug */, + 33CC10FA2044A3C60003C045 /* Release */, + 338D0CE9231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10FC2044A3C60003C045 /* Debug */, + 33CC10FD2044A3C60003C045 /* Release */, + 338D0CEA231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC111C2044C6BA0003C045 /* Debug */, + 33CC111D2044C6BA0003C045 /* Release */, + 338D0CEB231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 33CC10E52044A3C60003C045 /* Project object */; +} diff --git a/packages/local_auth/local_auth_darwin/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/local_auth/local_auth_darwin/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000000..18d981003d68 --- /dev/null +++ b/packages/local_auth/local_auth_darwin/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/local_auth/local_auth_darwin/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/local_auth/local_auth_darwin/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 000000000000..15368eccb25a --- /dev/null +++ b/packages/local_auth/local_auth_darwin/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/local_auth/local_auth_darwin/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/packages/local_auth/local_auth_darwin/example/macos/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000000..21a3cc14c74e --- /dev/null +++ b/packages/local_auth/local_auth_darwin/example/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/packages/local_auth/local_auth_darwin/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/local_auth/local_auth_darwin/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000000..18d981003d68 --- /dev/null +++ b/packages/local_auth/local_auth_darwin/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/local_auth/local_auth_darwin/example/macos/Runner/AppDelegate.swift b/packages/local_auth/local_auth_darwin/example/macos/Runner/AppDelegate.swift new file mode 100644 index 000000000000..5cec4c48f620 --- /dev/null +++ b/packages/local_auth/local_auth_darwin/example/macos/Runner/AppDelegate.swift @@ -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 Cocoa +import FlutterMacOS + +@NSApplicationMain +class AppDelegate: FlutterAppDelegate { + override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } +} diff --git a/packages/local_auth/local_auth_darwin/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/local_auth/local_auth_darwin/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000000..a2ec33f19f11 --- /dev/null +++ b/packages/local_auth/local_auth_darwin/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_16.png", + "scale" : "1x" + }, + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "2x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "1x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_64.png", + "scale" : "2x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_128.png", + "scale" : "1x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "2x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_1024.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/packages/local_auth/local_auth_darwin/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/packages/local_auth/local_auth_darwin/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png new file mode 100644 index 000000000000..82b6f9d9a33e Binary files /dev/null and b/packages/local_auth/local_auth_darwin/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ diff --git a/packages/local_auth/local_auth_darwin/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/packages/local_auth/local_auth_darwin/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png new file mode 100644 index 000000000000..13b35eba55c6 Binary files /dev/null and b/packages/local_auth/local_auth_darwin/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/packages/local_auth/local_auth_darwin/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/packages/local_auth/local_auth_darwin/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png new file mode 100644 index 000000000000..0a3f5fa40fb3 Binary files /dev/null and b/packages/local_auth/local_auth_darwin/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ diff --git a/packages/local_auth/local_auth_darwin/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/packages/local_auth/local_auth_darwin/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png new file mode 100644 index 000000000000..bdb57226d5f2 Binary files /dev/null and b/packages/local_auth/local_auth_darwin/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/packages/local_auth/local_auth_darwin/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/packages/local_auth/local_auth_darwin/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png new file mode 100644 index 000000000000..f083318e09ca Binary files /dev/null and b/packages/local_auth/local_auth_darwin/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ diff --git a/packages/local_auth/local_auth_darwin/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/packages/local_auth/local_auth_darwin/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png new file mode 100644 index 000000000000..326c0e72c9d8 Binary files /dev/null and b/packages/local_auth/local_auth_darwin/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/packages/local_auth/local_auth_darwin/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/packages/local_auth/local_auth_darwin/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png new file mode 100644 index 000000000000..2f1632cfddf3 Binary files /dev/null and b/packages/local_auth/local_auth_darwin/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/packages/local_auth/local_auth_darwin/example/macos/Runner/Base.lproj/MainMenu.xib b/packages/local_auth/local_auth_darwin/example/macos/Runner/Base.lproj/MainMenu.xib new file mode 100644 index 000000000000..80e867a4e06b --- /dev/null +++ b/packages/local_auth/local_auth_darwin/example/macos/Runner/Base.lproj/MainMenu.xib @@ -0,0 +1,343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/local_auth/local_auth_darwin/example/macos/Runner/Configs/AppInfo.xcconfig b/packages/local_auth/local_auth_darwin/example/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 000000000000..bdb88cb7b7e3 --- /dev/null +++ b/packages/local_auth/local_auth_darwin/example/macos/Runner/Configs/AppInfo.xcconfig @@ -0,0 +1,14 @@ +// Application-level settings for the Runner target. +// +// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the +// future. If not, the values below would default to using the project name when this becomes a +// 'flutter create' template. + +// The application's name. By default this is also the title of the Flutter window. +PRODUCT_NAME = example + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.example + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2024 dev.flutter.plugins. All rights reserved. diff --git a/packages/local_auth/local_auth_darwin/example/macos/Runner/Configs/Debug.xcconfig b/packages/local_auth/local_auth_darwin/example/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 000000000000..36b0fd9464f4 --- /dev/null +++ b/packages/local_auth/local_auth_darwin/example/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/packages/local_auth/local_auth_darwin/example/macos/Runner/Configs/Release.xcconfig b/packages/local_auth/local_auth_darwin/example/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 000000000000..dff4f49561c8 --- /dev/null +++ b/packages/local_auth/local_auth_darwin/example/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/packages/local_auth/local_auth_darwin/example/macos/Runner/Configs/Warnings.xcconfig b/packages/local_auth/local_auth_darwin/example/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 000000000000..42bcbf4780b1 --- /dev/null +++ b/packages/local_auth/local_auth_darwin/example/macos/Runner/Configs/Warnings.xcconfig @@ -0,0 +1,13 @@ +WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings +GCC_WARN_UNDECLARED_SELECTOR = YES +CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES +CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_PRAGMA_PACK = YES +CLANG_WARN_STRICT_PROTOTYPES = YES +CLANG_WARN_COMMA = YES +GCC_WARN_STRICT_SELECTOR_MATCH = YES +CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES +GCC_WARN_SHADOW = YES +CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/packages/local_auth/local_auth_darwin/example/macos/Runner/DebugProfile.entitlements b/packages/local_auth/local_auth_darwin/example/macos/Runner/DebugProfile.entitlements new file mode 100644 index 000000000000..dddb8a30c851 --- /dev/null +++ b/packages/local_auth/local_auth_darwin/example/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,12 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.cs.allow-jit + + com.apple.security.network.server + + + diff --git a/packages/local_auth/local_auth_darwin/example/macos/Runner/Info.plist b/packages/local_auth/local_auth_darwin/example/macos/Runner/Info.plist new file mode 100644 index 000000000000..eeb242927f38 --- /dev/null +++ b/packages/local_auth/local_auth_darwin/example/macos/Runner/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSFaceIDUsageDescription + Test for local auth + NSHumanReadableCopyright + $(PRODUCT_COPYRIGHT) + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/packages/local_auth/local_auth_darwin/example/macos/Runner/MainFlutterWindow.swift b/packages/local_auth/local_auth_darwin/example/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 000000000000..f21908966e95 --- /dev/null +++ b/packages/local_auth/local_auth_darwin/example/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,19 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + + super.awakeFromNib() + } +} diff --git a/packages/local_auth/local_auth_darwin/example/macos/Runner/Release.entitlements b/packages/local_auth/local_auth_darwin/example/macos/Runner/Release.entitlements new file mode 100644 index 000000000000..852fa1a4728a --- /dev/null +++ b/packages/local_auth/local_auth_darwin/example/macos/Runner/Release.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.app-sandbox + + + diff --git a/packages/local_auth/local_auth_darwin/example/pubspec.yaml b/packages/local_auth/local_auth_darwin/example/pubspec.yaml index ba1a8b042d2c..ab0ca6e62cce 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.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/local_auth/local_auth_darwin/lib/local_auth_darwin.dart b/packages/local_auth/local_auth_darwin/lib/local_auth_darwin.dart index 240aa6e6018e..935d274efa6c 100644 --- a/packages/local_auth/local_auth_darwin/lib/local_auth_darwin.dart +++ b/packages/local_auth/local_auth_darwin/lib/local_auth_darwin.dart @@ -2,24 +2,30 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:io'; + import 'package:flutter/foundation.dart' show visibleForTesting; import 'package:flutter/services.dart'; import 'package:local_auth_platform_interface/local_auth_platform_interface.dart'; import 'src/messages.g.dart'; import 'types/auth_messages_ios.dart'; +import 'types/auth_messages_macos.dart'; export 'package:local_auth_darwin/types/auth_messages_ios.dart'; export 'package:local_auth_platform_interface/types/auth_messages.dart'; export 'package:local_auth_platform_interface/types/auth_options.dart'; export 'package:local_auth_platform_interface/types/biometric_type.dart'; -/// The implementation of [LocalAuthPlatform] for iOS. +/// The implementation of [LocalAuthPlatform] for iOS and macOS. class LocalAuthDarwin extends LocalAuthPlatform { /// Creates a new plugin implementation instance. LocalAuthDarwin({ @visibleForTesting LocalAuthApi? api, - }) : _api = api ?? LocalAuthApi(); + @visibleForTesting bool? overrideUseMacOSAuthMessages, + }) : _api = api ?? LocalAuthApi(), + _useMacOSAuthMessages = + overrideUseMacOSAuthMessages ?? Platform.isMacOS; /// Registers this class as the default instance of [LocalAuthPlatform]. static void registerWith() { @@ -27,6 +33,7 @@ class LocalAuthDarwin extends LocalAuthPlatform { } final LocalAuthApi _api; + final bool _useMacOSAuthMessages; @override Future authenticate({ @@ -40,7 +47,9 @@ class LocalAuthDarwin extends LocalAuthPlatform { biometricOnly: options.biometricOnly, sticky: options.stickyAuth, useErrorDialogs: options.useErrorDialogs), - _pigeonStringsFromAuthMessages(localizedReason, authMessages)); + _useMacOSAuthMessages + ? _pigeonStringsFromMacOSAuthMessages(localizedReason, authMessages) + : _pigeonStringsFromiOSAuthMessages(localizedReason, authMessages)); // TODO(stuartmorgan): Replace this with structured errors, coordinated // across all platform implementations, per // https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#platform-exception-handling @@ -76,12 +85,9 @@ class LocalAuthDarwin extends LocalAuthPlatform { @override Future> getEnrolledBiometrics() async { - final List result = - await _api.getEnrolledBiometrics(); - return result - .cast() - .map((AuthBiometricWrapper entry) { - switch (entry.value) { + final List result = await _api.getEnrolledBiometrics(); + return result.map((AuthBiometric value) { + switch (value) { case AuthBiometric.face: return BiometricType.face; case AuthBiometric.fingerprint: @@ -93,11 +99,11 @@ class LocalAuthDarwin extends LocalAuthPlatform { @override Future isDeviceSupported() async => _api.isDeviceSupported(); - /// Always returns false as this method is not supported on iOS. + /// Always returns false as this method is not supported on iOS or macOS. @override Future stopAuthentication() async => false; - AuthStrings _pigeonStringsFromAuthMessages( + AuthStrings _pigeonStringsFromiOSAuthMessages( String localizedReason, Iterable messagesList) { IOSAuthMessages? messages; for (final AuthMessages entry in messagesList) { @@ -118,4 +124,23 @@ class LocalAuthDarwin extends LocalAuthPlatform { localizedFallbackTitle: messages?.localizedFallbackTitle, ); } + + AuthStrings _pigeonStringsFromMacOSAuthMessages( + String localizedReason, Iterable messagesList) { + MacOSAuthMessages? messages; + for (final AuthMessages entry in messagesList) { + if (entry is MacOSAuthMessages) { + messages = entry; + break; + } + } + return AuthStrings( + reason: localizedReason, + lockOut: messages?.lockOut ?? macOSLockOut, + goToSettingsDescription: + messages?.goToSettingsDescription ?? macOSGoToSettingsDescription, + cancelButton: messages?.cancelButton ?? macOSCancelButton, + localizedFallbackTitle: messages?.localizedFallbackTitle, + ); + } } diff --git a/packages/local_auth/local_auth_darwin/lib/src/messages.g.dart b/packages/local_auth/local_auth_darwin/lib/src/messages.g.dart index a3d722da5ec9..51b921c1540b 100644 --- a/packages/local_auth/local_auth_darwin/lib/src/messages.g.dart +++ b/packages/local_auth/local_auth_darwin/lib/src/messages.g.dart @@ -1,9 +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 (v13.1.2), do not edit directly. +// Autogenerated from Pigeon (v22.4.0), 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 +// 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 import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; @@ -49,8 +49,8 @@ class AuthStrings { AuthStrings({ required this.reason, required this.lockOut, - required this.goToSettingsButton, - required this.goToSettingsDescription, + this.goToSettingsButton, + this.goToSettingsDescription, required this.cancelButton, this.localizedFallbackTitle, }); @@ -59,9 +59,9 @@ class AuthStrings { String lockOut; - String goToSettingsButton; + String? goToSettingsButton; - String goToSettingsDescription; + String? goToSettingsDescription; String cancelButton; @@ -83,8 +83,8 @@ class AuthStrings { return AuthStrings( reason: result[0]! as String, lockOut: result[1]! as String, - goToSettingsButton: result[2]! as String, - goToSettingsDescription: result[3]! as String, + goToSettingsButton: result[2] as String?, + goToSettingsDescription: result[3] as String?, cancelButton: result[4]! as String, localizedFallbackTitle: result[5] as String?, ); @@ -140,7 +140,7 @@ class AuthResultDetails { Object encode() { return [ - result.index, + result, errorMessage, errorDetails, ]; @@ -149,50 +149,35 @@ class AuthResultDetails { static AuthResultDetails decode(Object result) { result as List; return AuthResultDetails( - result: AuthResult.values[result[0]! as int], + result: result[0]! as AuthResult, errorMessage: result[1] as String?, errorDetails: result[2] as String?, ); } } -class AuthBiometricWrapper { - AuthBiometricWrapper({ - required this.value, - }); - - AuthBiometric value; - - Object encode() { - return [ - value.index, - ]; - } - - static AuthBiometricWrapper decode(Object result) { - result as List; - return AuthBiometricWrapper( - value: AuthBiometric.values[result[0]! as int], - ); - } -} - -class _LocalAuthApiCodec extends StandardMessageCodec { - const _LocalAuthApiCodec(); +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is AuthBiometricWrapper) { - buffer.putUint8(128); - writeValue(buffer, value.encode()); - } else if (value is AuthOptions) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is AuthResult) { buffer.putUint8(129); - writeValue(buffer, value.encode()); - } else if (value is AuthResultDetails) { + writeValue(buffer, value.index); + } else if (value is AuthBiometric) { buffer.putUint8(130); - writeValue(buffer, value.encode()); + writeValue(buffer, value.index); } else if (value is AuthStrings) { buffer.putUint8(131); writeValue(buffer, value.encode()); + } else if (value is AuthOptions) { + buffer.putUint8(132); + writeValue(buffer, value.encode()); + } else if (value is AuthResultDetails) { + buffer.putUint8(133); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -201,14 +186,18 @@ class _LocalAuthApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: - return AuthBiometricWrapper.decode(readValue(buffer)!); case 129: - return AuthOptions.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : AuthResult.values[value]; case 130: - return AuthResultDetails.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : AuthBiometric.values[value]; case 131: return AuthStrings.decode(readValue(buffer)!); + case 132: + return AuthOptions.decode(readValue(buffer)!); + case 133: + return AuthResultDetails.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -219,126 +208,138 @@ class LocalAuthApi { /// Constructor for [LocalAuthApi]. 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. - LocalAuthApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; + LocalAuthApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - static const MessageCodec codec = _LocalAuthApiCodec(); + final String pigeonVar_messageChannelSuffix; /// Returns true if this device supports authentication. Future isDeviceSupported() async { - const String channelName = - 'dev.flutter.pigeon.local_auth_darwin.LocalAuthApi.isDeviceSupported'; - final BasicMessageChannel channel = BasicMessageChannel( - channelName, - codec, - binaryMessenger: _binaryMessenger, + final String pigeonVar_channelName = + 'dev.flutter.pigeon.local_auth_darwin.LocalAuthApi.isDeviceSupported$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? replyList = await channel.send(null) as List?; - if (replyList == null) { - throw _createConnectionError(channelName); - } else if (replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 (replyList[0] as bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } /// Returns true if this device can support biometric authentication, whether /// any biometrics are enrolled or not. Future deviceCanSupportBiometrics() async { - const String channelName = - 'dev.flutter.pigeon.local_auth_darwin.LocalAuthApi.deviceCanSupportBiometrics'; - final BasicMessageChannel channel = BasicMessageChannel( - channelName, - codec, - binaryMessenger: _binaryMessenger, + final String pigeonVar_channelName = + 'dev.flutter.pigeon.local_auth_darwin.LocalAuthApi.deviceCanSupportBiometrics$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? replyList = await channel.send(null) as List?; - if (replyList == null) { - throw _createConnectionError(channelName); - } else if (replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 (replyList[0] as bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } /// Returns the biometric types that are enrolled, and can thus be used /// without additional setup. - Future> getEnrolledBiometrics() async { - const String channelName = - 'dev.flutter.pigeon.local_auth_darwin.LocalAuthApi.getEnrolledBiometrics'; - final BasicMessageChannel channel = BasicMessageChannel( - channelName, - codec, - binaryMessenger: _binaryMessenger, + Future> getEnrolledBiometrics() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.local_auth_darwin.LocalAuthApi.getEnrolledBiometrics$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? replyList = await channel.send(null) as List?; - if (replyList == null) { - throw _createConnectionError(channelName); - } else if (replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 (replyList[0] as List?)!.cast(); + return (pigeonVar_replyList[0] as List?)!.cast(); } } /// Attempts to authenticate the user with the provided [options], and using /// [strings] for any UI. Future authenticate( - AuthOptions arg_options, AuthStrings arg_strings) async { - const String channelName = - 'dev.flutter.pigeon.local_auth_darwin.LocalAuthApi.authenticate'; - final BasicMessageChannel channel = BasicMessageChannel( - channelName, - codec, - binaryMessenger: _binaryMessenger, + AuthOptions options, AuthStrings strings) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.local_auth_darwin.LocalAuthApi.authenticate$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? replyList = await channel - .send([arg_options, arg_strings]) as List?; - if (replyList == null) { - throw _createConnectionError(channelName); - } else if (replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([options, strings]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 (replyList[0] as AuthResultDetails?)!; + return (pigeonVar_replyList[0] as AuthResultDetails?)!; } } } diff --git a/packages/local_auth/local_auth_darwin/lib/types/auth_messages_macos.dart b/packages/local_auth/local_auth_darwin/lib/types/auth_messages_macos.dart new file mode 100644 index 000000000000..16ce91a15bb8 --- /dev/null +++ b/packages/local_auth/local_auth_darwin/lib/types/auth_messages_macos.dart @@ -0,0 +1,87 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/foundation.dart'; +import 'package:intl/intl.dart'; +import 'package:local_auth_platform_interface/types/auth_messages.dart'; + +/// Class wrapping all authentication messages needed on macOS. +/// Provides default values for all messages. +@immutable +class MacOSAuthMessages extends AuthMessages { + /// Constructs a new instance. + const MacOSAuthMessages({ + this.lockOut, + this.goToSettingsDescription, + this.cancelButton, + this.localizedFallbackTitle, + }); + + /// Message advising the user to re-enable biometrics on their device. + final String? lockOut; + + /// Message advising the user to go to the settings and configure Biometrics + /// for their device. + final String? goToSettingsDescription; + + /// Message shown on a button that the user can click to leave the current + /// dialog. + /// Maximum 30 characters. + final String? cancelButton; + + /// The localized title for the fallback button in the dialog presented to + /// the user during authentication. + final String? localizedFallbackTitle; + + @override + Map get args { + return { + 'lockOut': lockOut ?? macOSLockOut, + 'okButton': cancelButton ?? macOSCancelButton, + if (localizedFallbackTitle != null) + 'localizedFallbackTitle': localizedFallbackTitle!, + }; + } + + @override + bool operator ==(Object other) => + identical(this, other) || + other is MacOSAuthMessages && + runtimeType == other.runtimeType && + lockOut == other.lockOut && + cancelButton == other.cancelButton && + localizedFallbackTitle == other.localizedFallbackTitle; + + @override + int get hashCode => Object.hash( + super.hashCode, + lockOut, + cancelButton, + localizedFallbackTitle, + ); +} + +// Default Strings for MacOSAuthMessages plugin. Currently supports English. +// Intl.message must be string literals. + +/// Message advising the user to re-enable biometrics on their device. +/// It shows in a dialog on macOS. +String get macOSLockOut => Intl.message( + 'Biometric authentication is disabled. Please restart your computer and try again.', + desc: 'Message advising the user to re-enable biometrics on their device.'); + +/// Message advising the user to go to the settings and configure Biometrics +/// for their device. +String get macOSGoToSettingsDescription => Intl.message( + 'Biometric authentication is not set up on your device. Please enable ' + 'Touch ID on your computer in the Settings app.', + desc: + 'Message advising the user to go to the settings and configure Biometrics ' + 'for their device.'); + +/// Message shown on a button that the user can click to leave the current +/// dialog. +String get macOSCancelButton => Intl.message('OK', + desc: 'Message showed on a button that the user can click to leave the ' + 'current dialog. Maximum 30 characters.'); diff --git a/packages/local_auth/local_auth_darwin/pigeons/messages.dart b/packages/local_auth/local_auth_darwin/pigeons/messages.dart index 121e89886516..17aad093a06a 100644 --- a/packages/local_auth/local_auth_darwin/pigeons/messages.dart +++ b/packages/local_auth/local_auth_darwin/pigeons/messages.dart @@ -25,16 +25,16 @@ class AuthStrings { const AuthStrings({ required this.reason, required this.lockOut, - required this.goToSettingsButton, - required this.goToSettingsDescription, + this.goToSettingsButton, + this.goToSettingsDescription, required this.cancelButton, required this.localizedFallbackTitle, }); final String reason; final String lockOut; - final String goToSettingsButton; - final String goToSettingsDescription; + final String? goToSettingsButton; + final String? goToSettingsDescription; final String cancelButton; final String? localizedFallbackTitle; } @@ -88,13 +88,6 @@ class AuthResultDetails { /// Pigeon equivalent of the subset of BiometricType used by iOS. enum AuthBiometric { face, fingerprint } -// TODO(stuartmorgan): Enums need be wrapped in a data class because thay can't -// be used as collection arguments. See https://github.com/flutter/flutter/issues/133728 -class AuthBiometricWrapper { - AuthBiometricWrapper({required this.value}); - final AuthBiometric value; -} - @HostApi() abstract class LocalAuthApi { /// Returns true if this device supports authentication. @@ -106,7 +99,7 @@ abstract class LocalAuthApi { /// Returns the biometric types that are enrolled, and can thus be used /// without additional setup. - List getEnrolledBiometrics(); + List getEnrolledBiometrics(); /// Attempts to authenticate the user with the provided [options], and using /// [strings] for any UI. diff --git a/packages/local_auth/local_auth_darwin/pubspec.yaml b/packages/local_auth/local_auth_darwin/pubspec.yaml index 05a6be6cd59a..1ed3b6563041 100644 --- a/packages/local_auth/local_auth_darwin/pubspec.yaml +++ b/packages/local_auth/local_auth_darwin/pubspec.yaml @@ -2,11 +2,11 @@ name: local_auth_darwin description: iOS implementation of the local_auth plugin. repository: https://github.com/flutter/packages/tree/main/packages/local_auth/local_auth_darwin issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+local_auth%22 -version: 1.3.1 +version: 1.4.1 environment: - sdk: ^3.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -16,6 +16,10 @@ flutter: pluginClass: FLALocalAuthPlugin dartPluginClass: LocalAuthDarwin sharedDarwinSource: true + macos: + pluginClass: FLALocalAuthPlugin + dartPluginClass: LocalAuthDarwin + sharedDarwinSource: true dependencies: flutter: @@ -27,8 +31,8 @@ dev_dependencies: build_runner: ^2.3.3 flutter_test: sdk: flutter - mockito: 5.4.4 - pigeon: ^13.0.0 + mockito: ^5.4.4 + pigeon: ^22.4.0 topics: - authentication diff --git a/packages/local_auth/local_auth_darwin/test/local_auth_darwin_test.dart b/packages/local_auth/local_auth_darwin/test/local_auth_darwin_test.dart index 6075b50571f8..756205f1b681 100644 --- a/packages/local_auth/local_auth_darwin/test/local_auth_darwin_test.dart +++ b/packages/local_auth/local_auth_darwin/test/local_auth_darwin_test.dart @@ -6,6 +6,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:local_auth_darwin/local_auth_darwin.dart'; import 'package:local_auth_darwin/src/messages.g.dart'; +import 'package:local_auth_darwin/types/auth_messages_macos.dart'; import 'package:local_auth_platform_interface/local_auth_platform_interface.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; @@ -59,11 +60,10 @@ void main() { group('getEnrolledBiometrics', () { test('translates values', () async { - when(api.getEnrolledBiometrics()) - .thenAnswer((_) async => [ - AuthBiometricWrapper(value: AuthBiometric.face), - AuthBiometricWrapper(value: AuthBiometric.fingerprint), - ]); + when(api.getEnrolledBiometrics()).thenAnswer((_) async => [ + AuthBiometric.face, + AuthBiometric.fingerprint, + ]); final List result = await plugin.getEnrolledBiometrics(); @@ -75,7 +75,7 @@ void main() { test('handles empty', () async { when(api.getEnrolledBiometrics()) - .thenAnswer((_) async => []); + .thenAnswer((_) async => []); final List result = await plugin.getEnrolledBiometrics(); @@ -86,6 +86,8 @@ void main() { group('authenticate', () { group('strings', () { test('passes default values when nothing is provided', () async { + plugin = LocalAuthDarwin(api: api, overrideUseMacOSAuthMessages: false); + when(api.authenticate(any, any)).thenAnswer( (_) async => AuthResultDetails(result: AuthResult.success)); @@ -108,6 +110,8 @@ void main() { test('passes default values when only other platform values are provided', () async { + plugin = LocalAuthDarwin(api: api, overrideUseMacOSAuthMessages: false); + when(api.authenticate(any, any)).thenAnswer( (_) async => AuthResultDetails(result: AuthResult.success)); @@ -129,7 +133,78 @@ void main() { expect(strings.localizedFallbackTitle, null); }); - test('passes all non-default values correctly', () async { + test( + 'passes default values when only MacOSAuthMessages platform values are provided', + () async { + plugin = LocalAuthDarwin(api: api, overrideUseMacOSAuthMessages: true); + + when(api.authenticate(any, any)).thenAnswer( + (_) async => AuthResultDetails(result: AuthResult.success)); + + const String reason = 'test reason'; + await plugin.authenticate( + localizedReason: reason, + authMessages: [const MacOSAuthMessages()]); + + final VerificationResult result = + verify(api.authenticate(any, captureAny)); + final AuthStrings strings = result.captured[0] as AuthStrings; + expect(strings.reason, reason); + // These should all be the default values from + // auth_messages_ios.dart + expect(strings.lockOut, macOSLockOut); + expect(strings.goToSettingsDescription, macOSGoToSettingsDescription); + expect(strings.cancelButton, macOSCancelButton); + expect(strings.localizedFallbackTitle, null); + }); + + test( + 'passes all non-default values correctly with IOSAuthMessages', + () async { + plugin = + LocalAuthDarwin(api: api, overrideUseMacOSAuthMessages: false); + + when(api.authenticate(any, any)).thenAnswer( + (_) async => AuthResultDetails(result: AuthResult.success)); + + // These are arbitrary values; all that matters is that: + // - they are different from the defaults, and + // - they are different from each other. + const String reason = 'A'; + const String lockOut = 'B'; + const String goToSettingsButton = 'C'; + const String gotToSettingsDescription = 'D'; + const String cancel = 'E'; + const String localizedFallbackTitle = 'F'; + + await plugin.authenticate( + localizedReason: reason, + authMessages: [ + const IOSAuthMessages( + lockOut: lockOut, + goToSettingsButton: goToSettingsButton, + goToSettingsDescription: gotToSettingsDescription, + cancelButton: cancel, + localizedFallbackTitle: localizedFallbackTitle, + ), + AnotherPlatformAuthMessages(), + ]); + + final VerificationResult result = + verify(api.authenticate(any, captureAny)); + final AuthStrings strings = result.captured[0] as AuthStrings; + expect(strings.reason, reason); + expect(strings.lockOut, lockOut); + expect(strings.goToSettingsButton, goToSettingsButton); + expect(strings.goToSettingsDescription, gotToSettingsDescription); + expect(strings.cancelButton, cancel); + expect(strings.localizedFallbackTitle, localizedFallbackTitle); + }, + ); + + test('passes all non-default values correctly with MacOSAuthMessages', + () async { + plugin = LocalAuthDarwin(api: api, overrideUseMacOSAuthMessages: true); when(api.authenticate(any, any)).thenAnswer( (_) async => AuthResultDetails(result: AuthResult.success)); @@ -138,16 +213,12 @@ void main() { // - they are different from each other. const String reason = 'A'; const String lockOut = 'B'; - const String goToSettingsButton = 'C'; - const String gotToSettingsDescription = 'D'; const String cancel = 'E'; const String localizedFallbackTitle = 'F'; await plugin .authenticate(localizedReason: reason, authMessages: [ - const IOSAuthMessages( + const MacOSAuthMessages( lockOut: lockOut, - goToSettingsButton: goToSettingsButton, - goToSettingsDescription: gotToSettingsDescription, cancelButton: cancel, localizedFallbackTitle: localizedFallbackTitle, ), @@ -159,13 +230,13 @@ void main() { final AuthStrings strings = result.captured[0] as AuthStrings; expect(strings.reason, reason); expect(strings.lockOut, lockOut); - expect(strings.goToSettingsButton, goToSettingsButton); - expect(strings.goToSettingsDescription, gotToSettingsDescription); expect(strings.cancelButton, cancel); expect(strings.localizedFallbackTitle, localizedFallbackTitle); }); test('passes provided messages with default fallbacks', () async { + plugin = LocalAuthDarwin(api: api, overrideUseMacOSAuthMessages: false); + when(api.authenticate(any, any)).thenAnswer( (_) async => AuthResultDetails(result: AuthResult.success)); @@ -202,6 +273,8 @@ void main() { group('options', () { test('passes default values', () async { + plugin = LocalAuthDarwin(api: api, overrideUseMacOSAuthMessages: false); + when(api.authenticate(any, any)).thenAnswer( (_) async => AuthResultDetails(result: AuthResult.success)); diff --git a/packages/local_auth/local_auth_darwin/test/local_auth_darwin_test.mocks.dart b/packages/local_auth/local_auth_darwin/test/local_auth_darwin_test.mocks.dart index 30ea55ae2ca2..befeb1bbbfc5 100644 --- a/packages/local_auth/local_auth_darwin/test/local_auth_darwin_test.mocks.dart +++ b/packages/local_auth/local_auth_darwin/test/local_auth_darwin_test.mocks.dart @@ -3,10 +3,11 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i3; +import 'dart:async' as _i4; import 'package:local_auth_darwin/src/messages.g.dart' as _i2; import 'package:mockito/mockito.dart' as _i1; +import 'package:mockito/src/dummies.dart' as _i3; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -41,57 +42,66 @@ class MockLocalAuthApi extends _i1.Mock implements _i2.LocalAuthApi { } @override - _i3.Future isDeviceSupported() => (super.noSuchMethod( + String get pigeonVar_messageChannelSuffix => (super.noSuchMethod( + Invocation.getter(#pigeonVar_messageChannelSuffix), + returnValue: _i3.dummyValue( + this, + Invocation.getter(#pigeonVar_messageChannelSuffix), + ), + ) as String); + + @override + _i4.Future isDeviceSupported() => (super.noSuchMethod( Invocation.method( #isDeviceSupported, [], ), - returnValue: _i3.Future.value(false), - ) as _i3.Future); + returnValue: _i4.Future.value(false), + ) as _i4.Future); @override - _i3.Future deviceCanSupportBiometrics() => (super.noSuchMethod( + _i4.Future deviceCanSupportBiometrics() => (super.noSuchMethod( Invocation.method( #deviceCanSupportBiometrics, [], ), - returnValue: _i3.Future.value(false), - ) as _i3.Future); + returnValue: _i4.Future.value(false), + ) as _i4.Future); @override - _i3.Future> getEnrolledBiometrics() => + _i4.Future> getEnrolledBiometrics() => (super.noSuchMethod( Invocation.method( #getEnrolledBiometrics, [], ), - returnValue: _i3.Future>.value( - <_i2.AuthBiometricWrapper?>[]), - ) as _i3.Future>); + returnValue: + _i4.Future>.value(<_i2.AuthBiometric>[]), + ) as _i4.Future>); @override - _i3.Future<_i2.AuthResultDetails> authenticate( - _i2.AuthOptions? arg_options, - _i2.AuthStrings? arg_strings, + _i4.Future<_i2.AuthResultDetails> authenticate( + _i2.AuthOptions? options, + _i2.AuthStrings? strings, ) => (super.noSuchMethod( Invocation.method( #authenticate, [ - arg_options, - arg_strings, + options, + strings, ], ), returnValue: - _i3.Future<_i2.AuthResultDetails>.value(_FakeAuthResultDetails_0( + _i4.Future<_i2.AuthResultDetails>.value(_FakeAuthResultDetails_0( this, Invocation.method( #authenticate, [ - arg_options, - arg_strings, + options, + strings, ], ), )), - ) as _i3.Future<_i2.AuthResultDetails>); + ) as _i4.Future<_i2.AuthResultDetails>); } diff --git a/packages/local_auth/local_auth_platform_interface/CHANGELOG.md b/packages/local_auth/local_auth_platform_interface/CHANGELOG.md index 7317947e8d84..30dd66f1c3d1 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.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 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 5e34a426352e..471978598642 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: @@ -18,7 +18,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 topics: - authentication diff --git a/packages/local_auth/local_auth_windows/CHANGELOG.md b/packages/local_auth/local_auth_windows/CHANGELOG.md index 46d66bac3615..d8654c0a2e79 100644 --- a/packages/local_auth/local_auth_windows/CHANGELOG.md +++ b/packages/local_auth/local_auth_windows/CHANGELOG.md @@ -1,5 +1,10 @@ ## NEXT +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + +## 1.0.11 + +* Updates to pigeon 21. * Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. ## 1.0.10 diff --git a/packages/local_auth/local_auth_windows/README.md b/packages/local_auth/local_auth_windows/README.md index 64c5446f77c1..dd6c4aca603c 100644 --- a/packages/local_auth/local_auth_windows/README.md +++ b/packages/local_auth/local_auth_windows/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/local_auth -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/local_auth/local_auth_windows/example/pubspec.yaml b/packages/local_auth/local_auth_windows/example/pubspec.yaml index 4bdb1ebcaa29..e953214f9853 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/local_auth/local_auth_windows/lib/src/messages.g.dart b/packages/local_auth/local_auth_windows/lib/src/messages.g.dart index f303a0803c32..e1c45ef20c5d 100644 --- a/packages/local_auth/local_auth_windows/lib/src/messages.g.dart +++ b/packages/local_auth/local_auth_windows/lib/src/messages.g.dart @@ -1,9 +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 (v10.1.2), do not edit directly. +// Autogenerated from Pigeon (v21.0.0), 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 +// 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 import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; @@ -11,40 +11,59 @@ import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; import 'package:flutter/services.dart'; +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); +} + +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); +} + class LocalAuthApi { /// Constructor for [LocalAuthApi]. 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. - LocalAuthApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; + LocalAuthApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : __pigeon_binaryMessenger = binaryMessenger, + __pigeon_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? __pigeon_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - static const MessageCodec codec = StandardMessageCodec(); + final String __pigeon_messageChannelSuffix; /// Returns true if this device supports authentication. Future isDeviceSupported() async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.LocalAuthApi.isDeviceSupported', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send(null) as List?; - if (replyList == null) { + final String __pigeon_channelName = + 'dev.flutter.pigeon.local_auth_windows.LocalAuthApi.isDeviceSupported$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send(null) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else if (replyList[0] == null) { + } else if (__pigeon_replyList[0] == null) { throw PlatformException( code: 'null-error', message: 'Host platform returned null value for non-null return value.', ); } else { - return (replyList[0] as bool?)!; + return (__pigeon_replyList[0] as bool?)!; } } @@ -53,30 +72,32 @@ class LocalAuthApi { /// /// Returns true if authorization succeeds, false if it is attempted but is /// not successful, and an error if authorization could not be attempted. - Future authenticate(String arg_localizedReason) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.LocalAuthApi.authenticate', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_localizedReason]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future authenticate(String localizedReason) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.local_auth_windows.LocalAuthApi.authenticate$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([localizedReason]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); - } else if (replyList[0] == null) { + } else if (__pigeon_replyList[0] == null) { throw PlatformException( code: 'null-error', message: 'Host platform returned null value for non-null return value.', ); } else { - return (replyList[0] as bool?)!; + return (__pigeon_replyList[0] as bool?)!; } } } diff --git a/packages/local_auth/local_auth_windows/pubspec.yaml b/packages/local_auth/local_auth_windows/pubspec.yaml index 52a4240fa8a1..1919a989f0c4 100644 --- a/packages/local_auth/local_auth_windows/pubspec.yaml +++ b/packages/local_auth/local_auth_windows/pubspec.yaml @@ -2,11 +2,11 @@ name: local_auth_windows description: Windows implementation of the local_auth plugin. repository: https://github.com/flutter/packages/tree/main/packages/local_auth/local_auth_windows issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+local_auth%22 -version: 1.0.10 +version: 1.0.11 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -24,7 +24,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - pigeon: ^10.1.2 + pigeon: ^21.0.0 topics: - authentication diff --git a/packages/local_auth/local_auth_windows/windows/local_auth_plugin.cpp b/packages/local_auth/local_auth_windows/windows/local_auth_plugin.cpp index 80fab37ee50d..cb8d4cf0b5fb 100644 --- a/packages/local_auth/local_auth_windows/windows/local_auth_plugin.cpp +++ b/packages/local_auth/local_auth_windows/windows/local_auth_plugin.cpp @@ -45,7 +45,7 @@ namespace local_auth_windows { class UserConsentVerifierImpl : public UserConsentVerifier { public: explicit UserConsentVerifierImpl(std::function window_provider) - : get_root_window_(std::move(window_provider)){}; + : get_root_window_(std::move(window_provider)) {} virtual ~UserConsentVerifierImpl() = default; // Calls the native Windows API to get the user's consent diff --git a/packages/local_auth/local_auth_windows/windows/messages.g.cpp b/packages/local_auth/local_auth_windows/windows/messages.g.cpp index 6b771904dd52..ce0f578edfc3 100644 --- a/packages/local_auth/local_auth_windows/windows/messages.g.cpp +++ b/packages/local_auth/local_auth_windows/windows/messages.g.cpp @@ -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 (v10.1.2), do not edit directly. +// Autogenerated from Pigeon (v21.0.0), do not edit directly. // See also: https://pub.dev/packages/pigeon #undef _HAS_EXCEPTIONS @@ -24,22 +24,53 @@ using flutter::EncodableList; using flutter::EncodableMap; using flutter::EncodableValue; +FlutterError CreateConnectionError(const std::string channel_name) { + return FlutterError( + "channel-error", + "Unable to establish connection on channel: '" + channel_name + "'.", + EncodableValue("")); +} + +PigeonCodecSerializer::PigeonCodecSerializer() {} + +EncodableValue PigeonCodecSerializer::ReadValueOfType( + uint8_t type, flutter::ByteStreamReader* stream) const { + return flutter::StandardCodecSerializer::ReadValueOfType(type, stream); +} + +void PigeonCodecSerializer::WriteValue( + const EncodableValue& value, flutter::ByteStreamWriter* stream) const { + flutter::StandardCodecSerializer::WriteValue(value, stream); +} + /// The codec used by LocalAuthApi. const flutter::StandardMessageCodec& LocalAuthApi::GetCodec() { return flutter::StandardMessageCodec::GetInstance( - &flutter::StandardCodecSerializer::GetInstance()); + &PigeonCodecSerializer::GetInstance()); } // Sets up an instance of `LocalAuthApi` to handle messages through the // `binary_messenger`. void LocalAuthApi::SetUp(flutter::BinaryMessenger* binary_messenger, LocalAuthApi* api) { + LocalAuthApi::SetUp(binary_messenger, api, ""); +} + +void LocalAuthApi::SetUp(flutter::BinaryMessenger* binary_messenger, + LocalAuthApi* api, + const std::string& message_channel_suffix) { + const std::string prepended_suffix = + message_channel_suffix.length() > 0 + ? std::string(".") + message_channel_suffix + : ""; { - auto channel = std::make_unique>( - binary_messenger, "dev.flutter.pigeon.LocalAuthApi.isDeviceSupported", + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.local_auth_windows.LocalAuthApi.isDeviceSupported" + + prepended_suffix, &GetCodec()); if (api != nullptr) { - channel->SetMessageHandler( + channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { @@ -58,15 +89,17 @@ void LocalAuthApi::SetUp(flutter::BinaryMessenger* binary_messenger, } }); } else { - channel->SetMessageHandler(nullptr); + channel.SetMessageHandler(nullptr); } } { - auto channel = std::make_unique>( - binary_messenger, "dev.flutter.pigeon.LocalAuthApi.authenticate", + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.local_auth_windows.LocalAuthApi.authenticate" + + prepended_suffix, &GetCodec()); if (api != nullptr) { - channel->SetMessageHandler( + channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { @@ -94,7 +127,7 @@ void LocalAuthApi::SetUp(flutter::BinaryMessenger* binary_messenger, } }); } else { - channel->SetMessageHandler(nullptr); + channel.SetMessageHandler(nullptr); } } } diff --git a/packages/local_auth/local_auth_windows/windows/messages.g.h b/packages/local_auth/local_auth_windows/windows/messages.g.h index 60a809514ee4..60d35feec399 100644 --- a/packages/local_auth/local_auth_windows/windows/messages.g.h +++ b/packages/local_auth/local_auth_windows/windows/messages.g.h @@ -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 (v10.1.2), do not edit directly. +// Autogenerated from Pigeon (v21.0.0), do not edit directly. // See also: https://pub.dev/packages/pigeon #ifndef PIGEON_MESSAGES_G_H_ @@ -58,6 +58,22 @@ class ErrorOr { std::variant v_; }; +class PigeonCodecSerializer : public flutter::StandardCodecSerializer { + public: + PigeonCodecSerializer(); + inline static PigeonCodecSerializer& GetInstance() { + static PigeonCodecSerializer sInstance; + return sInstance; + } + + void WriteValue(const flutter::EncodableValue& value, + flutter::ByteStreamWriter* stream) const override; + + protected: + flutter::EncodableValue ReadValueOfType( + uint8_t type, flutter::ByteStreamReader* stream) const override; +}; + // Generated interface from Pigeon that represents a handler of messages from // Flutter. class LocalAuthApi { @@ -83,6 +99,9 @@ class LocalAuthApi { // `binary_messenger`. static void SetUp(flutter::BinaryMessenger* binary_messenger, LocalAuthApi* api); + static void SetUp(flutter::BinaryMessenger* binary_messenger, + LocalAuthApi* api, + const std::string& message_channel_suffix); static flutter::EncodableValue WrapError(std::string_view error_message); static flutter::EncodableValue WrapError(const FlutterError& error); diff --git a/packages/local_auth/local_auth_windows/windows/test/mocks.h b/packages/local_auth/local_auth_windows/windows/test/mocks.h index a31eb98aa7ef..824e0e78e5bf 100644 --- a/packages/local_auth/local_auth_windows/windows/test/mocks.h +++ b/packages/local_auth/local_auth_windows/windows/test/mocks.h @@ -19,7 +19,7 @@ using ::testing::_; class MockUserConsentVerifier : public UserConsentVerifier { public: - explicit MockUserConsentVerifier(){}; + explicit MockUserConsentVerifier() {} virtual ~MockUserConsentVerifier() = default; MOCK_METHOD(winrt::Windows::Foundation::IAsyncOperation< diff --git a/packages/metrics_center/CHANGELOG.md b/packages/metrics_center/CHANGELOG.md index fd91d632989b..904f9775a932 100644 --- a/packages/metrics_center/CHANGELOG.md +++ b/packages/metrics_center/CHANGELOG.md @@ -1,6 +1,7 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Update dependency `http: ^1.0.0` ## 1.0.13 diff --git a/packages/metrics_center/pubspec.yaml b/packages/metrics_center/pubspec.yaml index 21f60340f44b..a1ef1bebcf93 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.2.0 + sdk: ^3.3.0 dependencies: _discoveryapis_commons: ^1.0.0 @@ -14,12 +14,12 @@ dependencies: gcloud: ^0.8.2 googleapis: ^12.0.0 googleapis_auth: ^1.1.0 - http: ">=0.13.0 <2.0.0" + http: ^1.0.0 dev_dependencies: build_runner: ^2.1.1 fake_async: ^1.2.0 - mockito: 5.4.4 + mockito: ^5.4.4 test: ^1.17.11 topics: diff --git a/packages/multicast_dns/CHANGELOG.md b/packages/multicast_dns/CHANGELOG.md index 9cb48301ba2f..b6956e0acbc4 100644 --- a/packages/multicast_dns/CHANGELOG.md +++ b/packages/multicast_dns/CHANGELOG.md @@ -1,5 +1,10 @@ ## NEXT +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + +## 0.3.2+7 + +* Optimized Socket Binding: Always bind to 0.0.0.0 for simplicity and efficiency. * Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. ## 0.3.2+6 diff --git a/packages/multicast_dns/README.md b/packages/multicast_dns/README.md index 10cd33e4bb63..f30ce16936e8 100644 --- a/packages/multicast_dns/README.md +++ b/packages/multicast_dns/README.md @@ -1,5 +1,7 @@ # Multicast DNS package +Based on [RFC 6762 Multicast DNS](https://datatracker.ietf.org/doc/html/rfc6762). + [![pub package](https://img.shields.io/pub/v/multicast_dns.svg)]( https://pub.dartlang.org/packages/multicast_dns) @@ -7,8 +9,5 @@ A Dart package to do service discovery over multicast DNS (mDNS), Bonjour, and A ## Usage -To use this package, add `multicast_dns` as a -[dependency in your pubspec.yaml file](https://pub.dev/packages/multicast_dns/install). - [The example](https://pub.dev/packages/multicast_dns/example) demonstrates how to use the `MDnsClient` Dart class in your code. diff --git a/packages/multicast_dns/lib/multicast_dns.dart b/packages/multicast_dns/lib/multicast_dns.dart index 336ac427930e..d6e2e6b06c0b 100644 --- a/packages/multicast_dns/lib/multicast_dns.dart +++ b/packages/multicast_dns/lib/multicast_dns.dart @@ -48,8 +48,8 @@ class MDnsClient { bool _starting = false; bool _started = false; - final List _sockets = []; - final List _toBeClosed = []; + RawDatagramSocket? _incomingIPv4; + final List _ipv6InterfaceSockets = []; final LookupResolver _resolver = LookupResolver(); final ResourceRecordCache _cache = ResourceRecordCache(); final RawDatagramSocketFactory _rawDatagramSocketFactory; @@ -117,9 +117,9 @@ class MDnsClient { // Can't send to IPv6 any address. if (incoming.address != InternetAddress.anyIPv6) { - _sockets.add(incoming); + _incomingIPv4 = incoming; } else { - _toBeClosed.add(incoming); + _ipv6InterfaceSockets.add(incoming); } _mDnsAddress ??= incoming.address.type == InternetAddressType.IPv4 @@ -130,30 +130,25 @@ class MDnsClient { (await interfacesFactory(listenAddress.type)).toList(); for (final NetworkInterface interface in interfaces) { - // Create a socket for sending on each adapter. final InternetAddress targetAddress = interface.addresses[0]; - final RawDatagramSocket socket = await _rawDatagramSocketFactory( - targetAddress, - selectedMDnsPort, - reuseAddress: true, - reusePort: true, - ttl: 255, - ); - _sockets.add(socket); + // Ensure that we're using this address/interface for multicast. - if (targetAddress.type == InternetAddressType.IPv4) { - socket.setRawOption(RawSocketOption( - RawSocketOption.levelIPv4, - RawSocketOption.IPv4MulticastInterface, - targetAddress.rawAddress, - )); - } else { + if (targetAddress.type == InternetAddressType.IPv6) { + final RawDatagramSocket socket = await _rawDatagramSocketFactory( + targetAddress, + selectedMDnsPort, + reuseAddress: true, + reusePort: true, + ttl: 255, + ); + _ipv6InterfaceSockets.add(socket); socket.setRawOption(RawSocketOption.fromInt( RawSocketOption.levelIPv6, RawSocketOption.IPv6MulticastInterface, interface.index, )); } + // Join multicast on this interface. incoming.joinMulticast(_mDnsAddress!, interface); } @@ -171,15 +166,13 @@ class MDnsClient { throw StateError('Cannot stop mDNS client while it is starting.'); } - for (final RawDatagramSocket socket in _sockets) { - socket.close(); - } - _sockets.clear(); + _incomingIPv4?.close(); + _incomingIPv4 = null; - for (final RawDatagramSocket socket in _toBeClosed) { + for (final RawDatagramSocket socket in _ipv6InterfaceSockets) { socket.close(); } - _toBeClosed.clear(); + _ipv6InterfaceSockets.clear(); _resolver.clearPendingRequests(); @@ -219,11 +212,17 @@ class MDnsClient { final Stream results = _resolver.addPendingRequest( query.resourceRecordType, query.fullyQualifiedName, timeout); - // Send the request on all interfaces. final List packet = query.encode(); - for (final RawDatagramSocket socket in _sockets) { - socket.send(packet, _mDnsAddress!, selectedMDnsPort); + + if (_mDnsAddress?.type == InternetAddressType.IPv4) { + // Send and listen on same "ANY" interface + _incomingIPv4?.send(packet, _mDnsAddress!, selectedMDnsPort); + } else { + for (final RawDatagramSocket socket in _ipv6InterfaceSockets) { + socket.send(packet, _mDnsAddress!, selectedMDnsPort); + } } + return results; } diff --git a/packages/multicast_dns/pubspec.yaml b/packages/multicast_dns/pubspec.yaml index 1d6d4341e1ed..8683b680c98a 100644 --- a/packages/multicast_dns/pubspec.yaml +++ b/packages/multicast_dns/pubspec.yaml @@ -2,10 +2,10 @@ name: multicast_dns description: Dart package for performing mDNS queries (e.g. Bonjour, Avahi). repository: https://github.com/flutter/packages/tree/main/packages/multicast_dns issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+multicast_dns%22 -version: 0.3.2+6 +version: 0.3.2+7 environment: - sdk: ^3.2.0 + sdk: ^3.3.0 dependencies: meta: ^1.3.0 diff --git a/packages/multicast_dns/test/client_test.dart b/packages/multicast_dns/test/client_test.dart index 134d7518d86a..f3047e5deeed 100644 --- a/packages/multicast_dns/test/client_test.dart +++ b/packages/multicast_dns/test/client_test.dart @@ -86,6 +86,78 @@ void main() { await client.start(); await client.lookup(ResourceRecordQuery.serverPointer('_')).toList(); }); + + group('Bind a single socket to ANY IPv4 and more than one when IPv6', () { + final List> testCases = >[ + { + 'name': 'IPv4', + 'datagramSocketType': InternetAddress.anyIPv4, + 'interfacePrefix': '192.168.2.' + }, + { + 'name': 'IPv6', + 'datagramSocketType': InternetAddress.anyIPv6, + 'interfacePrefix': '2001:0db8:85a3:0000:0000:8a2e:7335:030' + } + ]; + + for (final Map testCase in testCases) { + test('Bind a single socket to ANY ${testCase["name"]}', () async { + final FakeRawDatagramSocket datagramSocket = FakeRawDatagramSocket(); + + datagramSocket.address = + testCase['datagramSocketType']! as InternetAddress; + + final List selectedInterfacesForSendingPackets = []; + final MDnsClient client = MDnsClient(rawDatagramSocketFactory: + (dynamic host, int port, + {bool reuseAddress = true, + bool reusePort = true, + int ttl = 1}) async { + selectedInterfacesForSendingPackets.add(host); + return datagramSocket; + }); + + const int numberOfFakeInterfaces = 10; + Future> fakeNetworkInterfacesFactory( + InternetAddressType type) async { + final List fakeInterfaces = []; + + // Generate "fake" interfaces + for (int i = 0; i < numberOfFakeInterfaces; i++) { + fakeInterfaces.add(FakeNetworkInterface( + 'inetfake$i', + [ + InternetAddress("${testCase['interfacePrefix']! as String}$i") + ], + 0, + )); + } + + // ignore: always_specify_types + return Future.value(fakeInterfaces); + } + + final InternetAddress listenAddress = + testCase['datagramSocketType']! as InternetAddress; + + await client.start( + listenAddress: listenAddress, + mDnsPort: 1234, + interfacesFactory: fakeNetworkInterfacesFactory); + client.stop(); + + if (testCase['datagramSocketType'] == InternetAddress.anyIPv4) { + expect(selectedInterfacesForSendingPackets.length, 1); + } else { + // + 1 because of unspecified address (::) + expect(selectedInterfacesForSendingPackets.length, + numberOfFakeInterfaces + 1); + } + expect(selectedInterfacesForSendingPackets[0], listenAddress.address); + }); + } + }); } class FakeRawDatagramSocket extends Fake implements RawDatagramSocket { @@ -113,4 +185,30 @@ class FakeRawDatagramSocket extends Fake implements RawDatagramSocket { int send(List buffer, InternetAddress address, int port) { return buffer.length; } + + @override + void joinMulticast(InternetAddress group, [NetworkInterface? interface]) { + // nothing to do here + } + @override + void setRawOption(RawSocketOption option) { + // nothing to do here + } +} + +class FakeNetworkInterface implements NetworkInterface { + FakeNetworkInterface(this._name, this._addresses, this._index); + + final String _name; + final List _addresses; + final int _index; + + @override + List get addresses => _addresses; + + @override + String get name => _name; + + @override + int get index => _index; } diff --git a/packages/palette_generator/CHANGELOG.md b/packages/palette_generator/CHANGELOG.md index 88f3a48c3064..73b2ee0f5a47 100644 --- a/packages/palette_generator/CHANGELOG.md +++ b/packages/palette_generator/CHANGELOG.md @@ -1,5 +1,11 @@ -## NEXT +## 0.3.3+5 +* Updates README to link to the published example. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + +## 0.3.3+4 + +* Makes the example app compatible with the `web`. * Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. ## 0.3.3+3 diff --git a/packages/palette_generator/README.md b/packages/palette_generator/README.md index 3d378811745d..4cf11c0486f6 100644 --- a/packages/palette_generator/README.md +++ b/packages/palette_generator/README.md @@ -5,18 +5,7 @@ A Flutter package to extract prominent colors from an Image, typically used to find colors for a user interface. -## Usage - -To use this package, add `palette_generator` as a -[dependency in your pubspec.yaml file](https://flutter.io/platform-plugins/). - ## Example -Import the library via - -```dart -import 'package:palette_generator/palette_generator.dart'; -``` - -Then use the `PaletteGenerator` Dart class in your code. To see how this is done, -check out the [image_colors example app](example/). +To see how to use the `PaletteGenerator` class in your code, see +[the example app](https://pub.dev/packages/palette_generator/example). diff --git a/packages/palette_generator/dart_test.yaml b/packages/palette_generator/dart_test.yaml new file mode 100644 index 000000000000..b414d6939258 --- /dev/null +++ b/packages/palette_generator/dart_test.yaml @@ -0,0 +1,2 @@ +# TODO(dit): Reenable web tests and remove this file, https://github.com/flutter/flutter/issues/151498 +test_on: vm diff --git a/packages/palette_generator/example/android/app/build.gradle b/packages/palette_generator/example/android/app/build.gradle index c03f3db0324a..f38935a3e743 100644 --- a/packages/palette_generator/example/android/app/build.gradle +++ b/packages/palette_generator/example/android/app/build.gradle @@ -1,3 +1,8 @@ +plugins { + id "com.android.application" + id "dev.flutter.flutter-gradle-plugin" +} + def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { @@ -6,19 +11,11 @@ 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 flutterVersionName = localProperties.getProperty('flutter.versionName') if (flutterVersionName == null) { throw new GradleException("versionName not found. Define flutter.versionName in the local.properties file.") } -apply plugin: 'com.android.application' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - android { compileSdk flutter.compileSdkVersion @@ -26,7 +23,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "io.flutter.packages.palettegenerator.imagecolors" - minSdkVersion 19 + minSdkVersion flutter.minSdkVersion targetSdkVersion 33 versionCode 1 versionName flutterVersionName diff --git a/packages/palette_generator/example/android/build.gradle b/packages/palette_generator/example/android/build.gradle index cec92de922cf..b9db5700753a 100644 --- a/packages/palette_generator/example/android/build.gradle +++ b/packages/palette_generator/example/android/build.gradle @@ -1,14 +1,3 @@ -buildscript { - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' - } -} - 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/palette_generator/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/palette_generator/example/android/gradle/wrapper/gradle-wrapper.properties index a8080642df08..c5b3f7f9bfe1 100644 --- a/packages/palette_generator/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/palette_generator/example/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/palette_generator/example/android/settings.gradle b/packages/palette_generator/example/android/settings.gradle index 32735a3cfd4b..96619e83b201 100644 --- a/packages/palette_generator/example/android/settings.gradle +++ b/packages/palette_generator/example/android/settings.gradle @@ -1,28 +1,26 @@ -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 flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") -def plugins = new Properties() -def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') -if (pluginsFile.exists()) { - pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } -} - -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 "com.google.cloud.artifactregistry.gradle-plugin" version "2.2.1" } -apply plugin: "com.google.cloud.artifactregistry.gradle-plugin" + +include ":app" diff --git a/packages/palette_generator/example/lib/main.dart b/packages/palette_generator/example/lib/main.dart index 67cf07dae8d2..98e17ce85451 100644 --- a/packages/palette_generator/example/lib/main.dart +++ b/packages/palette_generator/example/lib/main.dart @@ -275,17 +275,20 @@ class PaletteSwatch extends StatelessWidget { fallbackHeight: 20.0, color: Color(0xff404040), ) - : Container( - decoration: BoxDecoration( - color: color, - border: Border.all( - color: _kPlaceholderColor, - style: colorDistance < 0.2 - ? BorderStyle.solid - : BorderStyle.none, - )), - width: 34.0, - height: 20.0, + : Tooltip( + message: color!.toRGB(), + child: Container( + decoration: BoxDecoration( + color: color, + border: Border.all( + color: _kPlaceholderColor, + style: colorDistance < 0.2 + ? BorderStyle.solid + : BorderStyle.none, + )), + width: 34.0, + height: 20.0, + ), ), ); @@ -304,3 +307,18 @@ class PaletteSwatch extends StatelessWidget { return swatch; } } + +/// Converts a [Color] into a #RRGGBB string. +extension on Color { + String toRGB() { + // In the example all alphas are 255, so no need to show it. + return '#${red.toHex()}${green.toHex()}${blue.toHex()}'; + } +} + +/// Converts an [int] to a uppercase hexadecimal string of at least [minDigits] length. +extension on int { + String toHex([int minDigits = 2]) { + return toRadixString(16).toUpperCase().padLeft(minDigits, '0'); + } +} diff --git a/packages/palette_generator/example/pubspec.yaml b/packages/palette_generator/example/pubspec.yaml index c9963cbbcbda..b0d61af8345c 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/palette_generator/example/web/favicon.png b/packages/palette_generator/example/web/favicon.png new file mode 100644 index 000000000000..8aaa46ac1ae2 Binary files /dev/null and b/packages/palette_generator/example/web/favicon.png differ diff --git a/packages/palette_generator/example/web/icons/Icon-192.png b/packages/palette_generator/example/web/icons/Icon-192.png new file mode 100644 index 000000000000..b749bfef0747 Binary files /dev/null and b/packages/palette_generator/example/web/icons/Icon-192.png differ diff --git a/packages/palette_generator/example/web/icons/Icon-512.png b/packages/palette_generator/example/web/icons/Icon-512.png new file mode 100644 index 000000000000..88cfd48dff11 Binary files /dev/null and b/packages/palette_generator/example/web/icons/Icon-512.png differ diff --git a/packages/palette_generator/example/web/icons/Icon-maskable-192.png b/packages/palette_generator/example/web/icons/Icon-maskable-192.png new file mode 100644 index 000000000000..eb9b4d76e525 Binary files /dev/null and b/packages/palette_generator/example/web/icons/Icon-maskable-192.png differ diff --git a/packages/palette_generator/example/web/icons/Icon-maskable-512.png b/packages/palette_generator/example/web/icons/Icon-maskable-512.png new file mode 100644 index 000000000000..d69c56691fbd Binary files /dev/null and b/packages/palette_generator/example/web/icons/Icon-maskable-512.png differ diff --git a/packages/palette_generator/example/web/index.html b/packages/palette_generator/example/web/index.html new file mode 100644 index 000000000000..c0ac6432762e --- /dev/null +++ b/packages/palette_generator/example/web/index.html @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + Image Colors + + + + + + diff --git a/packages/palette_generator/example/web/manifest.json b/packages/palette_generator/example/web/manifest.json new file mode 100644 index 000000000000..5bcc67d14c06 --- /dev/null +++ b/packages/palette_generator/example/web/manifest.json @@ -0,0 +1,35 @@ +{ + "name": "Flutter Palette Generator example app", + "short_name": "Palette Generator Example", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A demonstration of the Palette Generator Flutter package.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + }, + { + "src": "icons/Icon-maskable-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "icons/Icon-maskable-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +} diff --git a/packages/palette_generator/pubspec.yaml b/packages/palette_generator/pubspec.yaml index 07e682c41594..ed67a31c72c9 100644 --- a/packages/palette_generator/pubspec.yaml +++ b/packages/palette_generator/pubspec.yaml @@ -2,11 +2,11 @@ name: palette_generator description: Flutter package for generating palette colors from a source image. repository: https://github.com/flutter/packages/tree/main/packages/palette_generator issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+palette_generator%22 -version: 0.3.3+3 +version: 0.3.3+5 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.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 63d58809c218..6a8b2aeacd09 100644 --- a/packages/path_provider/path_provider/CHANGELOG.md +++ b/packages/path_provider/path_provider/CHANGELOG.md @@ -1,5 +1,13 @@ -## NEXT +## 2.1.5 +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum required `path_provider_android` to [2.2.5](https://pub.dev/packages/path_provider_android/changelog#225) as the v1 Android embedder is no longer available. + +## 2.1.4 + +* Updates minimum required `path_provider_android` to 2.2.0 to ensure support for `getDownloadsDirectory()` on Android. +* Updates supported platforms and paths matrix to indicate that downloads + are supported on Android. * Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. ## 2.1.3 diff --git a/packages/path_provider/path_provider/README.md b/packages/path_provider/path_provider/README.md index 3c0e5b2fa867..3ff47ab52eaa 100644 --- a/packages/path_provider/path_provider/README.md +++ b/packages/path_provider/path_provider/README.md @@ -11,10 +11,6 @@ Not all methods are supported on all platforms. |-------------|---------|-------|-------|--------|-------------| | **Support** | SDK 16+ | 12.0+ | Any | 10.14+ | Windows 10+ | -## Usage - -To use this plugin, add `path_provider` as a [dependency in your pubspec.yaml file](https://flutter.dev/docs/development/platform-integration/platform-channels). - ## Example ```dart @@ -39,7 +35,7 @@ Directories support by platform: | External Storage | ✔️ | ❌ | ❌ | ❌️ | ❌️ | | External Cache Directories | ✔️ | ❌ | ❌ | ❌️ | ❌️ | | External Storage Directories | ✔️ | ❌ | ❌ | ❌️ | ❌️ | -| Downloads | ❌ | ✔️ | ✔️ | ✔️ | ✔️ | +| Downloads | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ## Testing diff --git a/packages/path_provider/path_provider/example/android/app/build.gradle b/packages/path_provider/path_provider/example/android/app/build.gradle index 3e67e5d7f4ca..cd37f70f199b 100644 --- a/packages/path_provider/path_provider/example/android/app/build.gradle +++ b/packages/path_provider/path_provider/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.pathproviderexample' compileSdk flutter.compileSdkVersion @@ -32,7 +30,7 @@ android { defaultConfig { applicationId "io.flutter.plugins.pathproviderexample" minSdkVersion flutter.minSdkVersion - targetSdkVersion 28 + targetSdkVersion 35 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/packages/path_provider/path_provider/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/path_provider/path_provider/example/android/app/gradle/wrapper/gradle-wrapper.properties index 609ab8e6c8b5..28f5fcf95755 100644 --- a/packages/path_provider/path_provider/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ b/packages/path_provider/path_provider/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/packages/path_provider/path_provider/example/android/app/src/main/AndroidManifest.xml b/packages/path_provider/path_provider/example/android/app/src/main/AndroidManifest.xml index df8cee7bc3be..d72897496391 100644 --- a/packages/path_provider/path_provider/example/android/app/src/main/AndroidManifest.xml +++ b/packages/path_provider/path_provider/example/android/app/src/main/AndroidManifest.xml @@ -6,6 +6,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.6.0" apply false + id "org.jetbrains.kotlin.android" version "1.7.10" 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/path_provider/path_provider/example/macos/Podfile b/packages/path_provider/path_provider/example/macos/Podfile index 049abe295427..ae77cc1d4269 100644 --- a/packages/path_provider/path_provider/example/macos/Podfile +++ b/packages/path_provider/path_provider/example/macos/Podfile @@ -28,7 +28,6 @@ flutter_macos_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) end diff --git a/packages/path_provider/path_provider/example/pubspec.yaml b/packages/path_provider/path_provider/example/pubspec.yaml index 60ba6783f7f2..154e969ce49e 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/path_provider/path_provider/pubspec.yaml b/packages/path_provider/path_provider/pubspec.yaml index c6a07a768edf..c972341e43bb 100644 --- a/packages/path_provider/path_provider/pubspec.yaml +++ b/packages/path_provider/path_provider/pubspec.yaml @@ -2,11 +2,11 @@ name: path_provider description: Flutter plugin for getting commonly used locations on host platform file systems, such as the temp and app data directories. repository: https://github.com/flutter/packages/tree/main/packages/path_provider/path_provider issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+path_provider%22 -version: 2.1.3 +version: 2.1.5 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: @@ -25,7 +25,7 @@ flutter: dependencies: flutter: sdk: flutter - path_provider_android: ^2.1.0 + path_provider_android: ^2.2.5 path_provider_foundation: ^2.3.2 path_provider_linux: ^2.2.0 path_provider_platform_interface: ^2.1.0 diff --git a/packages/path_provider/path_provider_android/CHANGELOG.md b/packages/path_provider/path_provider_android/CHANGELOG.md index 30d7c22190aa..352bad5b6cb7 100644 --- a/packages/path_provider/path_provider_android/CHANGELOG.md +++ b/packages/path_provider/path_provider_android/CHANGELOG.md @@ -1,3 +1,32 @@ +## 2.2.13 + +* Updates annotations lib to 1.9.0. + +## 2.2.12 + +* Updates Pigeon for non-nullable collection type support. + +## 2.2.11 + +* Updates Java compatibility version to 11. +* Updates minimum supported SDK version to Flutter 3.24/Dart 3.5. + +## 2.2.10 + +* Updates annotations lib to 1.8.2. + +## 2.2.9 + +* Updates annotations lib to 1.8.1. + +## 2.2.8 + +* Updates lint checks to ignore NewerVersionAvailable. + +## 2.2.7 + +* Updates AGP version to 8.5.0. + ## 2.2.6 * Updates annotations lib to 1.8.0. diff --git a/packages/path_provider/path_provider_android/README.md b/packages/path_provider/path_provider_android/README.md index 3bfc4255f08b..a92c41e2b932 100644 --- a/packages/path_provider/path_provider_android/README.md +++ b/packages/path_provider/path_provider_android/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/path_provider -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/path_provider/path_provider_android/android/build.gradle b/packages/path_provider/path_provider_android/android/build.gradle index 84d85748e239..69a189f90d45 100644 --- a/packages/path_provider/path_provider_android/android/build.gradle +++ b/packages/path_provider/path_provider_android/android/build.gradle @@ -8,7 +8,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.3.1' + classpath 'com.android.tools.build:gradle:8.5.0' } } @@ -22,10 +22,7 @@ rootProject.allprojects { apply plugin: 'com.android.library' android { - // Conditional for compatibility with AGP <4.2. - if (project.android.hasProperty("namespace")) { - namespace 'io.flutter.plugins.pathprovider' - } + namespace 'io.flutter.plugins.pathprovider' compileSdk 34 defaultConfig { @@ -35,11 +32,11 @@ android { lintOptions { checkAllWarnings true warningsAsErrors true - disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency' + disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency', 'NewerVersionAvailable' } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } @@ -57,6 +54,6 @@ android { } dependencies { - implementation 'androidx.annotation:annotation:1.8.0' + implementation 'androidx.annotation:annotation:1.9.0' testImplementation 'junit:junit:4.13.2' } diff --git a/packages/path_provider/path_provider_android/android/src/main/java/io/flutter/plugins/pathprovider/Messages.java b/packages/path_provider/path_provider_android/android/src/main/java/io/flutter/plugins/pathprovider/Messages.java index 1bfa729157db..9bf8785650d2 100644 --- a/packages/path_provider/path_provider_android/android/src/main/java/io/flutter/plugins/pathprovider/Messages.java +++ b/packages/path_provider/path_provider_android/android/src/main/java/io/flutter/plugins/pathprovider/Messages.java @@ -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 (v9.2.5), do not edit directly. +// Autogenerated from Pigeon (v22.4.2), do not edit directly. // See also: https://pub.dev/packages/pigeon package io.flutter.plugins.pathprovider; @@ -13,6 +13,8 @@ import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.MessageCodec; import io.flutter.plugin.common.StandardMessageCodec; +import java.io.ByteArrayOutputStream; +import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; @@ -38,7 +40,7 @@ public FlutterError(@NonNull String code, @Nullable String message, @Nullable Ob @NonNull protected static ArrayList wrapError(@NonNull Throwable exception) { - ArrayList errorList = new ArrayList(3); + ArrayList errorList = new ArrayList<>(3); if (exception instanceof FlutterError) { FlutterError error = (FlutterError) exception; errorList.add(error.code); @@ -68,10 +70,40 @@ public enum StorageDirectory { final int index; - private StorageDirectory(final int index) { + StorageDirectory(final int index) { this.index = index; } } + + private static class PigeonCodec extends StandardMessageCodec { + public static final PigeonCodec INSTANCE = new PigeonCodec(); + + private PigeonCodec() {} + + @Override + protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { + switch (type) { + case (byte) 129: + { + Object value = readValue(buffer); + return value == null ? null : StorageDirectory.values()[((Long) value).intValue()]; + } + default: + return super.readValueOfType(type, buffer); + } + } + + @Override + protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { + if (value instanceof StorageDirectory) { + stream.write(129); + writeValue(stream, value == null ? null : ((StorageDirectory) value).index); + } else { + super.writeValue(stream, value); + } + } + } + /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ public interface PathProviderApi { @@ -98,30 +130,38 @@ public interface PathProviderApi { /** The codec used by PathProviderApi. */ static @NonNull MessageCodec getCodec() { - return new StandardMessageCodec(); + return PigeonCodec.INSTANCE; } /** * Sets up an instance of `PathProviderApi` to handle messages through the `binaryMessenger`. */ - static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable PathProviderApi api) { + static void setUp(@NonNull BinaryMessenger binaryMessenger, @Nullable PathProviderApi api) { + setUp(binaryMessenger, "", api); + } + + static void setUp( + @NonNull BinaryMessenger binaryMessenger, + @NonNull String messageChannelSuffix, + @Nullable PathProviderApi api) { + messageChannelSuffix = messageChannelSuffix.isEmpty() ? "" : "." + messageChannelSuffix; { BinaryMessenger.TaskQueue taskQueue = binaryMessenger.makeBackgroundTaskQueue(); BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.PathProviderApi.getTemporaryPath", + "dev.flutter.pigeon.path_provider_android.PathProviderApi.getTemporaryPath" + + messageChannelSuffix, getCodec(), taskQueue); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { String output = api.getTemporaryPath(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -134,19 +174,19 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable PathProvid BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.PathProviderApi.getApplicationSupportPath", + "dev.flutter.pigeon.path_provider_android.PathProviderApi.getApplicationSupportPath" + + messageChannelSuffix, getCodec(), taskQueue); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { String output = api.getApplicationSupportPath(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -159,19 +199,19 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable PathProvid BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.PathProviderApi.getApplicationDocumentsPath", + "dev.flutter.pigeon.path_provider_android.PathProviderApi.getApplicationDocumentsPath" + + messageChannelSuffix, getCodec(), taskQueue); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { String output = api.getApplicationDocumentsPath(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -184,19 +224,19 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable PathProvid BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.PathProviderApi.getApplicationCachePath", + "dev.flutter.pigeon.path_provider_android.PathProviderApi.getApplicationCachePath" + + messageChannelSuffix, getCodec(), taskQueue); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { String output = api.getApplicationCachePath(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -209,19 +249,19 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable PathProvid BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.PathProviderApi.getExternalStoragePath", + "dev.flutter.pigeon.path_provider_android.PathProviderApi.getExternalStoragePath" + + messageChannelSuffix, getCodec(), taskQueue); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { String output = api.getExternalStoragePath(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -234,19 +274,19 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable PathProvid BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.PathProviderApi.getExternalCachePaths", + "dev.flutter.pigeon.path_provider_android.PathProviderApi.getExternalCachePaths" + + messageChannelSuffix, getCodec(), taskQueue); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { List output = api.getExternalCachePaths(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -259,22 +299,21 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable PathProvid BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.PathProviderApi.getExternalStoragePaths", + "dev.flutter.pigeon.path_provider_android.PathProviderApi.getExternalStoragePaths" + + messageChannelSuffix, getCodec(), taskQueue); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - StorageDirectory directoryArg = - args.get(0) == null ? null : StorageDirectory.values()[(int) args.get(0)]; + StorageDirectory directoryArg = (StorageDirectory) args.get(0); try { List output = api.getExternalStoragePaths(directoryArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); diff --git a/packages/path_provider/path_provider_android/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java b/packages/path_provider/path_provider_android/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java index ce23e545d618..1140875fd2bc 100644 --- a/packages/path_provider/path_provider_android/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java +++ b/packages/path_provider/path_provider_android/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java @@ -22,9 +22,9 @@ public class PathProviderPlugin implements FlutterPlugin, PathProviderApi { public PathProviderPlugin() {} - private void setup(BinaryMessenger messenger, Context context) { + private void setUp(BinaryMessenger messenger, Context context) { try { - PathProviderApi.setup(messenger, this); + PathProviderApi.setUp(messenger, this); } catch (Exception ex) { Log.e(TAG, "Received exception while setting up PathProviderPlugin", ex); } @@ -34,12 +34,12 @@ private void setup(BinaryMessenger messenger, Context context) { @Override public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { - setup(binding.getBinaryMessenger(), binding.getApplicationContext()); + setUp(binding.getBinaryMessenger(), binding.getApplicationContext()); } @Override public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { - PathProviderApi.setup(binding.getBinaryMessenger(), null); + PathProviderApi.setUp(binding.getBinaryMessenger(), null); } @Override diff --git a/packages/path_provider/path_provider_android/example/android/app/build.gradle b/packages/path_provider/path_provider_android/example/android/app/build.gradle index 3e67e5d7f4ca..c7d65dde33ea 100644 --- a/packages/path_provider/path_provider_android/example/android/app/build.gradle +++ b/packages/path_provider/path_provider_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.pathproviderexample' compileSdk flutter.compileSdkVersion @@ -32,7 +30,7 @@ android { defaultConfig { applicationId "io.flutter.plugins.pathproviderexample" minSdkVersion flutter.minSdkVersion - targetSdkVersion 28 + targetSdkVersion 34 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/packages/path_provider/path_provider_android/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/path_provider/path_provider_android/example/android/app/gradle/wrapper/gradle-wrapper.properties index 609ab8e6c8b5..d951fac2bf31 100644 --- a/packages/path_provider/path_provider_android/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ b/packages/path_provider/path_provider_android/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/packages/path_provider/path_provider_android/example/android/app/src/main/AndroidManifest.xml b/packages/path_provider/path_provider_android/example/android/app/src/main/AndroidManifest.xml index df8cee7bc3be..b298b976f220 100644 --- a/packages/path_provider/path_provider_android/example/android/app/src/main/AndroidManifest.xml +++ b/packages/path_provider/path_provider_android/example/android/app/src/main/AndroidManifest.xml @@ -5,7 +5,8 @@ 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.7.10" 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/path_provider/path_provider_android/example/pubspec.yaml b/packages/path_provider/path_provider_android/example/pubspec.yaml index 54601fb67d72..417f34b0efd9 100644 --- a/packages/path_provider/path_provider_android/example/pubspec.yaml +++ b/packages/path_provider/path_provider_android/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the path_provider plugin. publish_to: none environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" dependencies: flutter: diff --git a/packages/path_provider/path_provider_android/lib/messages.g.dart b/packages/path_provider/path_provider_android/lib/messages.g.dart index 20d4368d5d44..20c0e9c23997 100644 --- a/packages/path_provider/path_provider_android/lib/messages.g.dart +++ b/packages/path_provider/path_provider_android/lib/messages.g.dart @@ -1,9 +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 (v9.2.5), do not edit directly. +// Autogenerated from Pigeon (v22.4.2), 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 +// 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 import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; @@ -11,6 +11,24 @@ import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; import 'package:flutter/services.dart'; +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); +} + +List wrapResponse( + {Object? result, PlatformException? error, bool empty = false}) { + if (empty) { + return []; + } + if (error == null) { + return [result]; + } + return [error.code, error.message, error.details]; +} + enum StorageDirectory { root, music, @@ -25,172 +43,224 @@ enum StorageDirectory { documents, } +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is StorageDirectory) { + buffer.putUint8(129); + writeValue(buffer, value.index); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 129: + final int? value = readValue(buffer) as int?; + return value == null ? null : StorageDirectory.values[value]; + default: + return super.readValueOfType(type, buffer); + } + } +} + class PathProviderApi { /// Constructor for [PathProviderApi]. 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. - PathProviderApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; + PathProviderApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - static const MessageCodec codec = StandardMessageCodec(); + final String pigeonVar_messageChannelSuffix; Future getTemporaryPath() async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PathProviderApi.getTemporaryPath', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send(null) as List?; - if (replyList == null) { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.path_provider_android.PathProviderApi.getTemporaryPath$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { - return (replyList[0] as String?); + return (pigeonVar_replyList[0] as String?); } } Future getApplicationSupportPath() async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PathProviderApi.getApplicationSupportPath', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send(null) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.path_provider_android.PathProviderApi.getApplicationSupportPath$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { - return (replyList[0] as String?); + return (pigeonVar_replyList[0] as String?); } } Future getApplicationDocumentsPath() async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PathProviderApi.getApplicationDocumentsPath', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send(null) as List?; - if (replyList == null) { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.path_provider_android.PathProviderApi.getApplicationDocumentsPath$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { - return (replyList[0] as String?); + return (pigeonVar_replyList[0] as String?); } } Future getApplicationCachePath() async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PathProviderApi.getApplicationCachePath', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send(null) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.path_provider_android.PathProviderApi.getApplicationCachePath$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { - return (replyList[0] as String?); + return (pigeonVar_replyList[0] as String?); } } Future getExternalStoragePath() async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PathProviderApi.getExternalStoragePath', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send(null) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.path_provider_android.PathProviderApi.getExternalStoragePath$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { - return (replyList[0] as String?); + return (pigeonVar_replyList[0] as String?); } } - Future> getExternalCachePaths() async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PathProviderApi.getExternalCachePaths', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send(null) as List?; - if (replyList == null) { + Future> getExternalCachePaths() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.path_provider_android.PathProviderApi.getExternalCachePaths$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else if (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 (replyList[0] as List?)!.cast(); + return (pigeonVar_replyList[0] as List?)!.cast(); } } - Future> getExternalStoragePaths( - StorageDirectory arg_directory) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PathProviderApi.getExternalStoragePaths', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_directory.index]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future> getExternalStoragePaths( + StorageDirectory directory) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.path_provider_android.PathProviderApi.getExternalStoragePaths$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([directory]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 (replyList[0] as List?)!.cast(); + return (pigeonVar_replyList[0] as List?)!.cast(); } } } diff --git a/packages/path_provider/path_provider_android/lib/path_provider_android.dart b/packages/path_provider/path_provider_android/lib/path_provider_android.dart index 20effb2f3c29..2698e10ab638 100644 --- a/packages/path_provider/path_provider_android/lib/path_provider_android.dart +++ b/packages/path_provider/path_provider_android/lib/path_provider_android.dart @@ -74,7 +74,7 @@ class PathProviderAndroid extends PathProviderPlatform { @override Future?> getExternalCachePaths() async { - return (await _api.getExternalCachePaths()).cast(); + return _api.getExternalCachePaths(); } @override @@ -94,7 +94,6 @@ class PathProviderAndroid extends PathProviderPlatform { Future> _getExternalStoragePaths({ StorageDirectory? type, }) async { - return (await _api.getExternalStoragePaths(_convertStorageDirectory(type))) - .cast(); + return _api.getExternalStoragePaths(_convertStorageDirectory(type)); } } diff --git a/packages/path_provider/path_provider_android/pigeons/messages.dart b/packages/path_provider/path_provider_android/pigeons/messages.dart index 6e4eb8f1956e..c8db7ec55e12 100644 --- a/packages/path_provider/path_provider_android/pigeons/messages.dart +++ b/packages/path_provider/path_provider_android/pigeons/messages.dart @@ -40,7 +40,7 @@ abstract class PathProviderApi { @TaskQueue(type: TaskQueueType.serialBackgroundThread) String? getExternalStoragePath(); @TaskQueue(type: TaskQueueType.serialBackgroundThread) - List getExternalCachePaths(); + List getExternalCachePaths(); @TaskQueue(type: TaskQueueType.serialBackgroundThread) - List getExternalStoragePaths(StorageDirectory directory); + List getExternalStoragePaths(StorageDirectory directory); } diff --git a/packages/path_provider/path_provider_android/pubspec.yaml b/packages/path_provider/path_provider_android/pubspec.yaml index a0e2bd05f05b..d46959f9cd75 100644 --- a/packages/path_provider/path_provider_android/pubspec.yaml +++ b/packages/path_provider/path_provider_android/pubspec.yaml @@ -2,11 +2,11 @@ name: path_provider_android description: Android implementation of the path_provider plugin. repository: https://github.com/flutter/packages/tree/main/packages/path_provider/path_provider_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+path_provider%22 -version: 2.2.6 +version: 2.2.13 environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" flutter: plugin: @@ -27,7 +27,7 @@ dev_dependencies: sdk: flutter integration_test: sdk: flutter - pigeon: ^9.2.4 + pigeon: ^22.4.2 test: ^1.16.0 topics: diff --git a/packages/path_provider/path_provider_android/test/messages_test.g.dart b/packages/path_provider/path_provider_android/test/messages_test.g.dart index e18fc9699969..48b8e023862f 100644 --- a/packages/path_provider/path_provider_android/test/messages_test.g.dart +++ b/packages/path_provider/path_provider_android/test/messages_test.g.dart @@ -1,9 +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 (v9.2.5), do not edit directly. +// Autogenerated from Pigeon (v22.4.2), 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, unnecessary_import +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import, no_leading_underscores_for_local_identifiers // ignore_for_file: avoid_relative_lib_imports import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; @@ -13,10 +13,37 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:path_provider_android/messages.g.dart'; +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is StorageDirectory) { + buffer.putUint8(129); + writeValue(buffer, value.index); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 129: + final int? value = readValue(buffer) as int?; + return value == null ? null : StorageDirectory.values[value]; + default: + return super.readValueOfType(type, buffer); + } + } +} + abstract class TestPathProviderApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec codec = StandardMessageCodec(); + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); String? getTemporaryPath(); @@ -28,136 +55,204 @@ abstract class TestPathProviderApi { String? getExternalStoragePath(); - List getExternalCachePaths(); + List getExternalCachePaths(); - List getExternalStoragePaths(StorageDirectory directory); + List getExternalStoragePaths(StorageDirectory directory); - static void setup(TestPathProviderApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + TestPathProviderApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PathProviderApi.getTemporaryPath', codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.path_provider_android.PathProviderApi.getTemporaryPath$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { - // ignore message - final String? output = api.getTemporaryPath(); - return [output]; + try { + final String? output = api.getTemporaryPath(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PathProviderApi.getApplicationSupportPath', codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.path_provider_android.PathProviderApi.getApplicationSupportPath$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { - // ignore message - final String? output = api.getApplicationSupportPath(); - return [output]; + try { + final String? output = api.getApplicationSupportPath(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PathProviderApi.getApplicationDocumentsPath', - codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.path_provider_android.PathProviderApi.getApplicationDocumentsPath$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { - // ignore message - final String? output = api.getApplicationDocumentsPath(); - return [output]; + try { + final String? output = api.getApplicationDocumentsPath(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PathProviderApi.getApplicationCachePath', codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.path_provider_android.PathProviderApi.getApplicationCachePath$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { - // ignore message - final String? output = api.getApplicationCachePath(); - return [output]; + try { + final String? output = api.getApplicationCachePath(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PathProviderApi.getExternalStoragePath', codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.path_provider_android.PathProviderApi.getExternalStoragePath$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { - // ignore message - final String? output = api.getExternalStoragePath(); - return [output]; + try { + final String? output = api.getExternalStoragePath(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PathProviderApi.getExternalCachePaths', codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.path_provider_android.PathProviderApi.getExternalCachePaths$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { - // ignore message - final List output = api.getExternalCachePaths(); - return [output]; + try { + final List output = api.getExternalCachePaths(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PathProviderApi.getExternalStoragePaths', codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.path_provider_android.PathProviderApi.getExternalStoragePaths$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.PathProviderApi.getExternalStoragePaths was null.'); + 'Argument for dev.flutter.pigeon.path_provider_android.PathProviderApi.getExternalStoragePaths was null.'); final List args = (message as List?)!; final StorageDirectory? arg_directory = - args[0] == null ? null : StorageDirectory.values[args[0] as int]; + (args[0] as StorageDirectory?); assert(arg_directory != null, - 'Argument for dev.flutter.pigeon.PathProviderApi.getExternalStoragePaths was null, expected non-null StorageDirectory.'); - final List output = - api.getExternalStoragePaths(arg_directory!); - return [output]; + 'Argument for dev.flutter.pigeon.path_provider_android.PathProviderApi.getExternalStoragePaths was null, expected non-null StorageDirectory.'); + try { + final List output = + api.getExternalStoragePaths(arg_directory!); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } diff --git a/packages/path_provider/path_provider_android/test/path_provider_android_test.dart b/packages/path_provider/path_provider_android/test/path_provider_android_test.dart index 10c4cd0f2d63..440c5275a717 100644 --- a/packages/path_provider/path_provider_android/test/path_provider_android_test.dart +++ b/packages/path_provider/path_provider_android/test/path_provider_android_test.dart @@ -30,14 +30,14 @@ class _Api implements TestPathProviderApi { String? getApplicationCachePath() => kApplicationCachePath; @override - List getExternalCachePaths() => [kExternalCachePaths]; + List getExternalCachePaths() => [kExternalCachePaths]; @override String? getExternalStoragePath() => kExternalStoragePaths; @override - List getExternalStoragePaths(messages.StorageDirectory directory) { - return [if (returnsExternalStoragePaths) kExternalStoragePaths]; + List getExternalStoragePaths(messages.StorageDirectory directory) { + return [if (returnsExternalStoragePaths) kExternalStoragePaths]; } @override @@ -52,7 +52,7 @@ void main() { setUp(() async { pathProvider = PathProviderAndroid(); - TestPathProviderApi.setup(_Api()); + TestPathProviderApi.setUp(_Api()); }); test('getTemporaryPath', () async { @@ -90,7 +90,7 @@ void main() { expect(result.first, kExternalCachePaths); }); - for (final StorageDirectory? type in [ + for (final StorageDirectory? type in [ ...StorageDirectory.values ]) { test('getExternalStoragePaths (type: $type) android succeeds', () async { @@ -110,7 +110,7 @@ void main() { 'getDownloadsPath returns null, when getExternalStoragePaths returns ' 'an empty list', () async { final PathProviderAndroid pathProvider = PathProviderAndroid(); - TestPathProviderApi.setup(_Api(returnsExternalStoragePaths: false)); + TestPathProviderApi.setUp(_Api(returnsExternalStoragePaths: false)); final String? path = await pathProvider.getDownloadsPath(); expect(path, null); }); diff --git a/packages/path_provider/path_provider_foundation/CHANGELOG.md b/packages/path_provider/path_provider_foundation/CHANGELOG.md index 760b40f7d065..8846f5503ae5 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.19/Dart 3.3. + ## 2.4.0 * Adds Swift Package Manager compatibility. diff --git a/packages/path_provider/path_provider_foundation/README.md b/packages/path_provider/path_provider_foundation/README.md index 5a01ace4b1e3..4aff670a1e6d 100644 --- a/packages/path_provider/path_provider_foundation/README.md +++ b/packages/path_provider/path_provider_foundation/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/path_provider -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/path_provider/path_provider_foundation/example/ios/Podfile b/packages/path_provider/path_provider_foundation/example/ios/Podfile index 4edba1e1fa01..61fe86ef4128 100644 --- a/packages/path_provider/path_provider_foundation/example/ios/Podfile +++ b/packages/path_provider/path_provider_foundation/example/ios/Podfile @@ -29,7 +29,6 @@ flutter_ios_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) diff --git a/packages/path_provider/path_provider_foundation/example/macos/Podfile b/packages/path_provider/path_provider_foundation/example/macos/Podfile index 47c1b18fedae..dd603efb9895 100644 --- a/packages/path_provider/path_provider_foundation/example/macos/Podfile +++ b/packages/path_provider/path_provider_foundation/example/macos/Podfile @@ -28,7 +28,6 @@ flutter_macos_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) diff --git a/packages/path_provider/path_provider_foundation/example/pubspec.yaml b/packages/path_provider/path_provider_foundation/example/pubspec.yaml index dfb78293a158..860c9124c923 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.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/path_provider/path_provider_foundation/pubspec.yaml b/packages/path_provider/path_provider_foundation/pubspec.yaml index 6410e24fb324..cfeac45f6cd4 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.0 environment: - sdk: ^3.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -30,7 +30,7 @@ dev_dependencies: build_runner: ^2.3.2 flutter_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 path: ^1.8.0 pigeon: ^10.1.3 diff --git a/packages/path_provider/path_provider_linux/CHANGELOG.md b/packages/path_provider/path_provider_linux/CHANGELOG.md index ce7dd926f6e8..68d613ba43a4 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.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 2.2.1 diff --git a/packages/path_provider/path_provider_linux/README.md b/packages/path_provider/path_provider_linux/README.md index 12c5c51443ff..745bbcf7a476 100644 --- a/packages/path_provider/path_provider_linux/README.md +++ b/packages/path_provider/path_provider_linux/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/path_provider -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/path_provider/path_provider_linux/example/pubspec.yaml b/packages/path_provider/path_provider_linux/example/pubspec.yaml index 3444e5a16262..3eb9843ede65 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/path_provider/path_provider_linux/pubspec.yaml b/packages/path_provider/path_provider_linux/pubspec.yaml index b056c30d64d2..02e6d6f2bbd7 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.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 0679b8421cf7..9c60b4e0db93 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.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 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 70fb194289bd..2ea8166ed613 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/path_provider/path_provider_windows/CHANGELOG.md b/packages/path_provider/path_provider_windows/CHANGELOG.md index 933fe1f1d81c..d3c880d9afa7 100644 --- a/packages/path_provider/path_provider_windows/CHANGELOG.md +++ b/packages/path_provider/path_provider_windows/CHANGELOG.md @@ -1,5 +1,10 @@ ## NEXT +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + +## 2.3.0 + +* Replaces `win32` dependency with direct FFI usage. * Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. ## 2.2.1 diff --git a/packages/path_provider/path_provider_windows/README.md b/packages/path_provider/path_provider_windows/README.md index 2bdeac409936..0aeb40395d8b 100644 --- a/packages/path_provider/path_provider_windows/README.md +++ b/packages/path_provider/path_provider_windows/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/path_provider -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/path_provider/path_provider_windows/example/pubspec.yaml b/packages/path_provider/path_provider_windows/example/pubspec.yaml index 632615bf50da..b5a73980e783 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/path_provider/path_provider_windows/lib/src/folders.dart b/packages/path_provider/path_provider_windows/lib/src/folders.dart index 55def29df2d7..022aba45d602 100644 --- a/packages/path_provider/path_provider_windows/lib/src/folders.dart +++ b/packages/path_provider/path_provider_windows/lib/src/folders.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:win32/win32.dart'; - // ignore_for_file: non_constant_identifier_names // ignore: avoid_classes_with_only_static_members @@ -11,122 +9,127 @@ import 'package:win32/win32.dart'; /// known folders. A property of this class may be passed to the `getPath` /// method in the [PathProvidersWindows] class to retrieve a known folder from /// Windows. +// These constants come from +// https://learn.microsoft.com/windows/win32/shell/knownfolderid class WindowsKnownFolder { /// The file system directory that is used to store administrative tools for /// an individual user. The MMC will save customized consoles to this /// directory, and it will roam with the user. - static String get AdminTools => FOLDERID_AdminTools; + static String get AdminTools => '{724EF170-A42D-4FEF-9F26-B60E846FBA4F}'; /// The file system directory that acts as a staging area for files waiting to /// be written to a CD. A typical path is C:\Documents and /// Settings\username\Local Settings\Application Data\Microsoft\CD Burning. - static String get CDBurning => FOLDERID_CDBurning; + static String get CDBurning => '{9E52AB10-F80D-49DF-ACB8-4330F5687855}'; /// The file system directory that contains administrative tools for all users /// of the computer. - static String get CommonAdminTools => FOLDERID_CommonAdminTools; + static String get CommonAdminTools => + '{D0384E7D-BAC3-4797-8F14-CBA229B392B5}'; /// The file system directory that contains the directories for the common /// program groups that appear on the Start menu for all users. A typical path /// is C:\Documents and Settings\All Users\Start Menu\Programs. - static String get CommonPrograms => FOLDERID_CommonPrograms; + static String get CommonPrograms => '{0139D44E-6AFE-49F2-8690-3DAFCAE6FFB8}'; /// The file system directory that contains the programs and folders that /// appear on the Start menu for all users. A typical path is C:\Documents and /// Settings\All Users\Start Menu. - static String get CommonStartMenu => FOLDERID_CommonStartMenu; + static String get CommonStartMenu => '{A4115719-D62E-491D-AA7C-E74B8BE3B067}'; /// The file system directory that contains the programs that appear in the /// Startup folder for all users. A typical path is C:\Documents and /// Settings\All Users\Start Menu\Programs\Startup. - static String get CommonStartup => FOLDERID_CommonStartup; + static String get CommonStartup => '{82A5EA35-D9CD-47C5-9629-E15D2F714E6E}'; /// The file system directory that contains the templates that are available /// to all users. A typical path is C:\Documents and Settings\All /// Users\Templates. - static String get CommonTemplates => FOLDERID_CommonTemplates; + static String get CommonTemplates => '{B94237E7-57AC-4347-9151-B08C6C32D1F7}'; /// The virtual folder that represents My Computer, containing everything on /// the local computer: storage devices, printers, and Control Panel. The /// folder can also contain mapped network drives. - static String get ComputerFolder => FOLDERID_ComputerFolder; + static String get ComputerFolder => '{0AC0837C-BBF8-452A-850D-79D08E667CA7}'; /// The virtual folder that represents Network Connections, that contains /// network and dial-up connections. - static String get ConnectionsFolder => FOLDERID_ConnectionsFolder; + static String get ConnectionsFolder => + '{6F0CD92B-2E97-45D1-88FF-B0D186B8DEDD}'; /// The virtual folder that contains icons for the Control Panel applications. - static String get ControlPanelFolder => FOLDERID_ControlPanelFolder; + static String get ControlPanelFolder => + '{82A74AEB-AEB4-465C-A014-D097EE346D63}'; /// The file system directory that serves as a common repository for Internet /// cookies. A typical path is C:\Documents and Settings\username\Cookies. - static String get Cookies => FOLDERID_Cookies; + static String get Cookies => '{2B0F765D-C0E9-4171-908E-08A611B84FF6}'; /// The virtual folder that represents the Windows desktop, the root of the /// namespace. - static String get Desktop => FOLDERID_Desktop; + static String get Desktop => '{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}'; /// The virtual folder that represents the My Documents desktop item. - static String get Documents => FOLDERID_Documents; + static String get Documents => '{FDD39AD0-238F-46AF-ADB4-6C85480369C7}'; /// The file system directory that serves as a repository for Internet /// downloads. - static String get Downloads => FOLDERID_Downloads; + static String get Downloads => '{374DE290-123F-4565-9164-39C4925E467B}'; /// The file system directory that serves as a common repository for the /// user's favorite items. A typical path is C:\Documents and /// Settings\username\Favorites. - static String get Favorites => FOLDERID_Favorites; + static String get Favorites => '{1777F761-68AD-4D8A-87BD-30B759FA33DD}'; /// A virtual folder that contains fonts. A typical path is C:\Windows\Fonts. - static String get Fonts => FOLDERID_Fonts; + static String get Fonts => '{FD228CB7-AE11-4AE3-864C-16F3910AB8FE}'; /// The file system directory that serves as a common repository for Internet /// history items. - static String get History => FOLDERID_History; + static String get History => '{D9DC8A3B-B784-432E-A781-5A1130A75963}'; /// The file system directory that serves as a common repository for temporary /// Internet files. A typical path is C:\Documents and Settings\username\Local /// Settings\Temporary Internet Files. - static String get InternetCache => FOLDERID_InternetCache; + static String get InternetCache => '{352481E8-33BE-4251-BA85-6007CAEDCF9D}'; /// A virtual folder for Internet Explorer. - static String get InternetFolder => FOLDERID_InternetFolder; + static String get InternetFolder => '{4D9F7874-4E0C-4904-967B-40B0D20C3E4B}'; /// The file system directory that serves as a data repository for local /// (nonroaming) applications. A typical path is C:\Documents and /// Settings\username\Local Settings\Application Data. - static String get LocalAppData => FOLDERID_LocalAppData; + static String get LocalAppData => '{F1B32785-6FBA-4FCF-9D55-7B8E7F157091}'; /// The file system directory that serves as a common repository for music /// files. A typical path is C:\Documents and Settings\User\My Documents\My /// Music. - static String get Music => FOLDERID_Music; + static String get Music => '{4BD8D571-6D19-48D3-BE97-422220080E43}'; /// A file system directory that contains the link objects that may exist in /// the My Network Places virtual folder. A typical path is C:\Documents and /// Settings\username\NetHood. - static String get NetHood => FOLDERID_NetHood; + static String get NetHood => '{C5ABBF53-E17F-4121-8900-86626FC2C973}'; /// The folder that represents other computers in your workgroup. - static String get NetworkFolder => FOLDERID_NetworkFolder; + static String get NetworkFolder => '{D20BEEC4-5CA8-4905-AE3B-BF251EA09B53}'; /// The file system directory that serves as a common repository for image /// files. A typical path is C:\Documents and Settings\username\My /// Documents\My Pictures. - static String get Pictures => FOLDERID_Pictures; + static String get Pictures => '{33E28130-4E1E-4676-835A-98395C3BC3BB}'; /// The file system directory that contains the link objects that can exist in /// the Printers virtual folder. A typical path is C:\Documents and /// Settings\username\PrintHood. - static String get PrintHood => FOLDERID_PrintHood; + static String get PrintHood => '{9274BD8D-CFD1-41C3-B35E-B13F55A758F4}'; /// The virtual folder that contains installed printers. - static String get PrintersFolder => FOLDERID_PrintersFolder; + static String get PrintersFolder => '{76FC4E2D-D6AD-4519-A663-37BD56068185}'; /// The user's profile folder. A typical path is C:\Users\username. /// Applications should not create files or folders at this level. - static String get Profile => FOLDERID_Profile; + static String get Profile => '{5E6C858F-0E22-4760-9AFE-EA3317B67173}'; /// The file system directory that contains application data for all users. A /// typical path is C:\Documents and Settings\All Users\Application Data. This @@ -134,110 +137,114 @@ class WindowsKnownFolder { /// example, an application can store a spell-check dictionary, a database of /// clip art, or a log file in the CSIDL_COMMON_APPDATA folder. This /// information will not roam and is available to anyone using the computer. - static String get ProgramData => FOLDERID_ProgramData; + static String get ProgramData => '{62AB5D82-FDC1-4DC3-A9DD-070D1D495D97}'; /// The Program Files folder. A typical path is C:\Program Files. - static String get ProgramFiles => FOLDERID_ProgramFiles; + static String get ProgramFiles => '{905e63b6-c1bf-494e-b29c-65b732d3d21a}'; /// The common Program Files folder. A typical path is C:\Program /// Files\Common. - static String get ProgramFilesCommon => FOLDERID_ProgramFilesCommon; + static String get ProgramFilesCommon => + '{F7F1ED05-9F6D-47A2-AAAE-29D317C6F066}'; /// On 64-bit systems, a link to the common Program Files folder. A typical path is /// C:\Program Files\Common Files. - static String get ProgramFilesCommonX64 => FOLDERID_ProgramFilesCommonX64; + static String get ProgramFilesCommonX64 => + '{6365D5A7-0F0D-45e5-87F6-0DA56B6A4F7D}'; /// On 64-bit systems, a link to the 32-bit common Program Files folder. A /// typical path is C:\Program Files (x86)\Common Files. On 32-bit systems, a /// link to the Common Program Files folder. - static String get ProgramFilesCommonX86 => FOLDERID_ProgramFilesCommonX86; + static String get ProgramFilesCommonX86 => + '{DE974D24-D9C6-4D3E-BF91-F4455120B917}'; /// On 64-bit systems, a link to the Program Files folder. A typical path is /// C:\Program Files. - static String get ProgramFilesX64 => FOLDERID_ProgramFilesX64; + static String get ProgramFilesX64 => '{6D809377-6AF0-444b-8957-A3773F02200E}'; /// On 64-bit systems, a link to the 32-bit Program Files folder. A typical /// path is C:\Program Files (x86). On 32-bit systems, a link to the Common /// Program Files folder. - static String get ProgramFilesX86 => FOLDERID_ProgramFilesX86; + static String get ProgramFilesX86 => '{7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E}'; /// The file system directory that contains the user's program groups (which /// are themselves file system directories). - static String get Programs => FOLDERID_Programs; + static String get Programs => '{A77F5D77-2E2B-44C3-A6A2-ABA601054A51}'; /// The file system directory that contains files and folders that appear on /// the desktop for all users. A typical path is C:\Documents and Settings\All /// Users\Desktop. - static String get PublicDesktop => FOLDERID_PublicDesktop; + static String get PublicDesktop => '{C4AA340D-F20F-4863-AFEF-F87EF2E6BA25}'; /// The file system directory that contains documents that are common to all /// users. A typical path is C:\Documents and Settings\All Users\Documents. - static String get PublicDocuments => FOLDERID_PublicDocuments; + static String get PublicDocuments => '{ED4824AF-DCE4-45A8-81E2-FC7965083634}'; /// The file system directory that serves as a repository for music files /// common to all users. A typical path is C:\Documents and Settings\All /// Users\Documents\My Music. - static String get PublicMusic => FOLDERID_PublicMusic; + static String get PublicMusic => '{3214FAB5-9757-4298-BB61-92A9DEAA44FF}'; /// The file system directory that serves as a repository for image files /// common to all users. A typical path is C:\Documents and Settings\All /// Users\Documents\My Pictures. - static String get PublicPictures => FOLDERID_PublicPictures; + static String get PublicPictures => '{B6EBFB86-6907-413C-9AF7-4FC2ABF07CC5}'; /// The file system directory that serves as a repository for video files /// common to all users. A typical path is C:\Documents and Settings\All /// Users\Documents\My Videos. - static String get PublicVideos => FOLDERID_PublicVideos; + static String get PublicVideos => '{2400183A-6185-49FB-A2D8-4A392A602BA3}'; /// The file system directory that contains shortcuts to the user's most /// recently used documents. A typical path is C:\Documents and /// Settings\username\My Recent Documents. - static String get Recent => FOLDERID_Recent; + static String get Recent => '{AE50C081-EBD2-438A-8655-8A092E34987A}'; /// The virtual folder that contains the objects in the user's Recycle Bin. - static String get RecycleBinFolder => FOLDERID_RecycleBinFolder; + static String get RecycleBinFolder => + '{B7534046-3ECB-4C18-BE4E-64CD4CB7D6AC}'; /// The file system directory that contains resource data. A typical path is /// C:\Windows\Resources. - static String get ResourceDir => FOLDERID_ResourceDir; + static String get ResourceDir => '{8AD10C31-2ADB-4296-A8F7-E4701232C972}'; /// The file system directory that serves as a common repository for /// application-specific data. A typical path is C:\Documents and /// Settings\username\Application Data. - static String get RoamingAppData => FOLDERID_RoamingAppData; + static String get RoamingAppData => '{3EB685DB-65F9-4CF6-A03A-E3EF65729F3D}'; /// The file system directory that contains Send To menu items. A typical path /// is C:\Documents and Settings\username\SendTo. - static String get SendTo => FOLDERID_SendTo; + static String get SendTo => '{8983036C-27C0-404B-8F08-102D10DCFD74}'; /// The file system directory that contains Start menu items. A typical path /// is C:\Documents and Settings\username\Start Menu. - static String get StartMenu => FOLDERID_StartMenu; + static String get StartMenu => '{625B53C3-AB48-4EC1-BA1F-A1EF4146FC19}'; /// The file system directory that corresponds to the user's Startup program /// group. The system starts these programs whenever the associated user logs /// on. A typical path is C:\Documents and Settings\username\Start /// Menu\Programs\Startup. - static String get Startup => FOLDERID_Startup; + static String get Startup => '{B97D20BB-F46A-4C97-BA10-5E3608430854}'; /// The Windows System folder. A typical path is C:\Windows\System32. - static String get System => FOLDERID_System; + static String get System => '{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}'; /// The 32-bit Windows System folder. On 32-bit systems, this is typically /// C:\Windows\system32. On 64-bit systems, this is typically /// C:\Windows\syswow64. - static String get SystemX86 => FOLDERID_SystemX86; + static String get SystemX86 => '{D65231B0-B2F1-4857-A4CE-A8E7C6EA7D27}'; /// The file system directory that serves as a common repository for document /// templates. A typical path is C:\Documents and Settings\username\Templates. - static String get Templates => FOLDERID_Templates; + static String get Templates => '{A63293E8-664E-48DB-A079-DF759E0509F7}'; /// The file system directory that serves as a common repository for video /// files. A typical path is C:\Documents and Settings\username\My /// Documents\My Videos. - static String get Videos => FOLDERID_Videos; + static String get Videos => '{18989B1D-99B5-455B-841C-AB7C74E4DDFC}'; /// The Windows directory or SYSROOT. This corresponds to the %windir% or /// %SYSTEMROOT% environment variables. A typical path is C:\Windows. - static String get Windows => FOLDERID_Windows; + static String get Windows => '{F38BF404-1D43-42F2-9305-67DE0B28FC23}'; } diff --git a/packages/path_provider/path_provider_windows/lib/src/guid.dart b/packages/path_provider/path_provider_windows/lib/src/guid.dart new file mode 100644 index 000000000000..84daffe6bed7 --- /dev/null +++ b/packages/path_provider/path_provider_windows/lib/src/guid.dart @@ -0,0 +1,51 @@ +// 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:ffi'; +import 'dart:typed_data'; + +/// Representation of the Win32 GUID struct. +// For the layout of this struct, see +// https://learn.microsoft.com/windows/win32/api/guiddef/ns-guiddef-guid +@Packed(4) +base class GUID extends Struct { + /// Native Data1 field. + @Uint32() + external int data1; + + /// Native Data2 field. + @Uint16() + external int data2; + + /// Native Data3 field. + @Uint16() + external int data3; + + /// Native Data4 field. + // This should be an eight-element byte array, but there's no such annotation. + @Uint64() + external int data4; + + /// Parses a GUID string, with optional enclosing "{}"s and optional "-"s, + /// into data. + void parse(String guid) { + final String hexOnly = guid.replaceAll(RegExp(r'[{}-]'), ''); + if (hexOnly.length != 32) { + throw ArgumentError.value(guid, 'guid', 'Invalid GUID string'); + } + final ByteData bytes = ByteData(16); + for (int i = 0; i < 16; ++i) { + bytes.setUint8( + i, int.parse(hexOnly.substring(i * 2, i * 2 + 2), radix: 16)); + } + data1 = bytes.getInt32(0); + data2 = bytes.getInt16(4); + data3 = bytes.getInt16(6); + // [bytes] is big endian, but the host is little endian, so a default + // big-endian read would reverse the bytes. Since data4 is supposed to be + // a byte array, the order should be preserved, so do a little-endian read. + // https://en.wikipedia.org/wiki/Universally_unique_identifier#Encoding + data4 = bytes.getInt64(8, Endian.little); + } +} diff --git a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart index 2faa599a5341..50f010ba56f2 100644 --- a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart +++ b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart @@ -7,11 +7,13 @@ import 'dart:io'; import 'package:ffi/ffi.dart'; import 'package:flutter/foundation.dart' show visibleForTesting; +import 'package:flutter/services.dart'; import 'package:path/path.dart' as path; import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; -import 'package:win32/win32.dart'; import 'folders.dart'; +import 'guid.dart'; +import 'win32_wrappers.dart'; /// Constant for en-US language used in VersionInfo keys. @visibleForTesting @@ -35,7 +37,7 @@ class VersionInfoQuerier { /// language and encoding, or null if there is no such entry, /// or if versionInfo is null. /// - /// See https://docs.microsoft.com/en-us/windows/win32/menurc/versioninfo-resource + /// See https://docs.microsoft.com/windows/win32/menurc/versioninfo-resource /// for list of possible language and encoding values. String? getStringValue( Pointer? versionInfo, @@ -49,7 +51,7 @@ class VersionInfoQuerier { return null; } final Pointer keyPath = - TEXT('\\StringFileInfo\\$language$encoding\\$key'); + '\\StringFileInfo\\$language$encoding\\$key'.toNativeUtf16(); final Pointer length = calloc(); final Pointer> valueAddress = calloc>(); try { @@ -89,7 +91,7 @@ class PathProviderWindows extends PathProviderPlatform { if (length == 0) { final int error = GetLastError(); - throw WindowsException(error); + throw _createWin32Exception(error); } else { path = buffer.toDartString(); @@ -134,7 +136,7 @@ class PathProviderWindows extends PathProviderPlatform { /// [WindowsKnownFolder]. Future getPath(String folderID) { final Pointer> pathPtrPtr = calloc>(); - final Pointer knownFolderID = calloc()..ref.setGUID(folderID); + final Pointer knownFolderID = calloc()..ref.parse(folderID); try { final int hr = SHGetKnownFolderPath( @@ -146,7 +148,7 @@ class PathProviderWindows extends PathProviderPlatform { if (FAILED(hr)) { if (hr == E_INVALIDARG || hr == E_FAIL) { - throw WindowsException(hr); + throw _createWin32Exception(hr); } return Future.value(); } @@ -179,7 +181,8 @@ class PathProviderWindows extends PathProviderPlatform { String? companyName; String? productName; - final Pointer moduleNameBuffer = wsalloc(MAX_PATH + 1); + final Pointer moduleNameBuffer = + calloc(MAX_PATH + 1).cast(); final Pointer unused = calloc(); Pointer? infoBuffer; try { @@ -188,7 +191,7 @@ class PathProviderWindows extends PathProviderPlatform { GetModuleFileName(0, moduleNameBuffer, MAX_PATH); if (moduleNameLength == 0) { final int error = GetLastError(); - throw WindowsException(error); + throw _createWin32Exception(error); } // From that, load the VERSIONINFO resource @@ -223,7 +226,7 @@ class PathProviderWindows extends PathProviderPlatform { } /// Makes [rawString] safe as a directory component. See - /// https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions + /// https://docs.microsoft.com/windows/win32/fileio/naming-a-file#naming-conventions /// /// If after sanitizing the string is empty, returns null. String? _sanitizedDirectoryName(String? rawString) { @@ -263,3 +266,15 @@ class PathProviderWindows extends PathProviderPlatform { return directory.path; } } + +Exception _createWin32Exception(int errorCode) { + return PlatformException( + code: 'Win32 Error', + // TODO(stuartmorgan): Consider getting the system error message via + // FormatMessage if it turns out to be necessary for debugging issues. + // Plugin-client-level usability isn't a major consideration since per + // https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#platform-exception-handling + // any case that comes up in practice should be handled and returned + // via a plugin-specific exception, not this fallback. + message: 'Error code 0x${errorCode.toRadixString(16)}'); +} diff --git a/packages/path_provider/path_provider_windows/lib/src/win32_wrappers.dart b/packages/path_provider/path_provider_windows/lib/src/win32_wrappers.dart new file mode 100644 index 000000000000..a39488eb0a08 --- /dev/null +++ b/packages/path_provider/path_provider_windows/lib/src/win32_wrappers.dart @@ -0,0 +1,112 @@ +// 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. + +// The types and functions here correspond directly to corresponding Windows +// types and functions, so the Windows docs are the definitive source of +// documentation. +// ignore_for_file: public_member_api_docs + +import 'dart:ffi'; + +import 'package:ffi/ffi.dart'; + +import 'guid.dart'; + +typedef BOOL = Int32; +typedef BYTE = Uint8; +typedef DWORD = Uint32; +typedef UINT = Uint32; +typedef HANDLE = IntPtr; +typedef HMODULE = HANDLE; +typedef HRESULT = Int32; +typedef LPCVOID = Pointer; +typedef LPCWSTR = Pointer; +typedef LPDWORD = Pointer; +typedef LPWSTR = Pointer; +typedef LPVOID = Pointer; +typedef PUINT = Pointer; +typedef PWSTR = Pointer>; +typedef WCHAR = Uint16; + +const int NULL = 0; + +// https://learn.microsoft.com/windows/win32/fileio/maximum-file-path-limitation?tabs=registry +const int MAX_PATH = 260; + +// https://learn.microsoft.com/windows/win32/seccrypto/common-hresult-values +// ignore: non_constant_identifier_names +final int E_FAIL = 0x80004005.toSigned(32); +// ignore: non_constant_identifier_names +final int E_INVALIDARG = 0x80070057.toSigned(32); + +// https://learn.microsoft.com/windows/win32/api/winerror/nf-winerror-failed#remarks +// ignore: non_constant_identifier_names +bool FAILED(int hr) => hr < 0; + +// https://learn.microsoft.com/windows/win32/api/shlobj_core/ne-shlobj_core-known_folder_flag +const int KF_FLAG_DEFAULT = 0x00000000; + +final DynamicLibrary _dllKernel32 = DynamicLibrary.open('kernel32.dll'); +final DynamicLibrary _dllVersion = DynamicLibrary.open('version.dll'); +final DynamicLibrary _dllShell32 = DynamicLibrary.open('shell32.dll'); + +// https://learn.microsoft.com/windows/win32/api/shlobj_core/nf-shlobj_core-shgetknownfolderpath +typedef _FFITypeSHGetKnownFolderPath = HRESULT Function( + Pointer, DWORD, HANDLE, PWSTR); +typedef FFITypeSHGetKnownFolderPathDart = int Function( + Pointer, int, int, Pointer>); +// ignore: non_constant_identifier_names +final FFITypeSHGetKnownFolderPathDart SHGetKnownFolderPath = + _dllShell32.lookupFunction<_FFITypeSHGetKnownFolderPath, + FFITypeSHGetKnownFolderPathDart>('SHGetKnownFolderPath'); + +// https://learn.microsoft.com/windows/win32/api/winver/nf-winver-getfileversioninfow +typedef _FFITypeGetFileVersionInfoW = BOOL Function( + LPCWSTR, DWORD, DWORD, LPVOID); +typedef FFITypeGetFileVersionInfoW = int Function( + Pointer, int, int, Pointer); +// ignore: non_constant_identifier_names +final FFITypeGetFileVersionInfoW GetFileVersionInfo = _dllVersion + .lookupFunction<_FFITypeGetFileVersionInfoW, FFITypeGetFileVersionInfoW>( + 'GetFileVersionInfoW'); + +// https://learn.microsoft.com/windows/win32/api/winver/nf-winver-getfileversioninfosizew +typedef _FFITypeGetFileVersionInfoSizeW = DWORD Function(LPCWSTR, LPDWORD); +typedef FFITypeGetFileVersionInfoSizeW = int Function( + Pointer, Pointer); +// ignore: non_constant_identifier_names +final FFITypeGetFileVersionInfoSizeW GetFileVersionInfoSize = + _dllVersion.lookupFunction<_FFITypeGetFileVersionInfoSizeW, + FFITypeGetFileVersionInfoSizeW>('GetFileVersionInfoSizeW'); + +// https://learn.microsoft.com/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror +typedef _FFITypeGetLastError = DWORD Function(); +typedef FFITypeGetLastError = int Function(); +// ignore: non_constant_identifier_names +final FFITypeGetLastError GetLastError = _dllKernel32 + .lookupFunction<_FFITypeGetLastError, FFITypeGetLastError>('GetLastError'); + +// https://learn.microsoft.com/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulefilenamew +typedef _FFITypeGetModuleFileNameW = DWORD Function(HMODULE, LPWSTR, DWORD); +typedef FFITypeGetModuleFileNameW = int Function(int, Pointer, int); +// ignore: non_constant_identifier_names +final FFITypeGetModuleFileNameW GetModuleFileName = _dllKernel32.lookupFunction< + _FFITypeGetModuleFileNameW, + FFITypeGetModuleFileNameW>('GetModuleFileNameW'); + +// https://learn.microsoft.com/windows/win32/api/winver/nf-winver-verqueryvaluew +typedef _FFITypeVerQueryValueW = BOOL Function(LPCVOID, LPCWSTR, LPVOID, PUINT); +typedef FFITypeVerQueryValueW = int Function( + Pointer, Pointer, Pointer, Pointer); +// ignore: non_constant_identifier_names +final FFITypeVerQueryValueW VerQueryValue = + _dllVersion.lookupFunction<_FFITypeVerQueryValueW, FFITypeVerQueryValueW>( + 'VerQueryValueW'); + +// https://learn.microsoft.com/windows/win32/api/fileapi/nf-fileapi-gettemppathw +typedef _FFITypeGetTempPathW = DWORD Function(DWORD, LPWSTR); +typedef FFITypeGetTempPathW = int Function(int, Pointer); +// ignore: non_constant_identifier_names +final FFITypeGetTempPathW GetTempPath = _dllKernel32 + .lookupFunction<_FFITypeGetTempPathW, FFITypeGetTempPathW>('GetTempPathW'); diff --git a/packages/path_provider/path_provider_windows/pubspec.yaml b/packages/path_provider/path_provider_windows/pubspec.yaml index c3211cf3c474..8a9d00c42aeb 100644 --- a/packages/path_provider/path_provider_windows/pubspec.yaml +++ b/packages/path_provider/path_provider_windows/pubspec.yaml @@ -2,11 +2,11 @@ name: path_provider_windows description: Windows implementation of the path_provider plugin repository: https://github.com/flutter/packages/tree/main/packages/path_provider/path_provider_windows issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+path_provider%22 -version: 2.2.1 +version: 2.3.0 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -21,7 +21,6 @@ dependencies: sdk: flutter path: ^1.8.0 path_provider_platform_interface: ^2.1.0 - win32: ">=2.1.0 <6.0.0" dev_dependencies: flutter_test: diff --git a/packages/path_provider/path_provider_windows/test/guid_test.dart b/packages/path_provider/path_provider_windows/test/guid_test.dart new file mode 100644 index 000000000000..561ad3b87d62 --- /dev/null +++ b/packages/path_provider/path_provider_windows/test/guid_test.dart @@ -0,0 +1,63 @@ +// 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:ffi'; +import 'dart:typed_data'; + +import 'package:ffi/ffi.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:path_provider_windows/src/guid.dart'; + +void main() { + test('has correct byte representation', () async { + final Pointer guid = calloc() + ..ref.parse('{00112233-4455-6677-8899-aabbccddeeff}'); + final ByteData data = ByteData(16) + ..setInt32(0, guid.ref.data1, Endian.little) + ..setInt16(4, guid.ref.data2, Endian.little) + ..setInt16(6, guid.ref.data3, Endian.little) + ..setInt64(8, guid.ref.data4, Endian.little); + expect(data.getUint8(0), 0x33); + expect(data.getUint8(1), 0x22); + expect(data.getUint8(2), 0x11); + expect(data.getUint8(3), 0x00); + expect(data.getUint8(4), 0x55); + expect(data.getUint8(5), 0x44); + expect(data.getUint8(6), 0x77); + expect(data.getUint8(7), 0x66); + expect(data.getUint8(8), 0x88); + expect(data.getUint8(9), 0x99); + expect(data.getUint8(10), 0xAA); + expect(data.getUint8(11), 0xBB); + expect(data.getUint8(12), 0xCC); + expect(data.getUint8(13), 0xDD); + expect(data.getUint8(14), 0xEE); + expect(data.getUint8(15), 0xFF); + + calloc.free(guid); + }); + + test('handles alternate forms', () async { + final Pointer guid1 = calloc() + ..ref.parse('{00112233-4455-6677-8899-aabbccddeeff}'); + final Pointer guid2 = calloc() + ..ref.parse('00112233445566778899AABBCCDDEEFF'); + + expect(guid1.ref.data1, guid2.ref.data1); + expect(guid1.ref.data2, guid2.ref.data2); + expect(guid1.ref.data3, guid2.ref.data3); + expect(guid1.ref.data4, guid2.ref.data4); + + calloc.free(guid1); + calloc.free(guid2); + }); + + test('throws for bad data', () async { + final Pointer guid = calloc(); + + expect(() => guid.ref.parse('{00112233-4455-6677-88'), throwsArgumentError); + + calloc.free(guid); + }); +} diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index 6e039a923623..85842f046117 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,5 +1,63 @@ -## NEXT +## 22.6.0 +* [swift] Adds `includeErrorClass` to `SwiftOptions`. + +## 22.5.0 + +* [swift] Adds implementation for `@ProxyApi`. + +## 22.4.2 + +* Updates `README.md` to replace the deprecated `flutter pub run pigeon` command with `dart run pigeon`. + +## 22.4.1 + +* [dart] Fixes bug where special handling of ints is ignored if no custom types are used. + +## 22.4.0 + +* Adds support for non-nullable types in collections. + +## 22.3.0 + +* Adds support for enums and classes in collections. + +## 22.2.0 + +* [kotlin] Adds implementation for `@ProxyApi`. + +## 22.1.0 + +* Allows generation of classes that aren't referenced in an API. + +## 22.0.0 + +* [dart] Changes codec to send int64 instead of int32. +* **Breaking Change** [swift] Changes generic `map` to nullable keys of `AnyHashable` to conform to other platforms. +* Adds tests to validate collections of ints. + +## 21.2.0 + +* Removes restriction on number of custom types. +* [java] Fixes bug with multiple enums. +* [java] Removes `Object` from generics. +* [objc] Fixes bug with multiple enums per data class. +* Updates `varPrefix` and `classMemberNamePrefix`. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + +## 21.1.0 + +* Adds GObject (Linux) support. + +## 21.0.0 + +* **Breaking Change** [cpp] Fixes style of enum names. References to enum values + will need to be updated to `EnumType.kValue` style, instead of the previous + `EnumType.value`. + +## 20.0.2 + +* [java] Adds `equals` and `hashCode` support for data classes. * [swift] Fully-qualifies types in Equatable extension test. ## 20.0.1 @@ -17,7 +75,7 @@ ## 19.0.2 -* [kotlin] Adds the `@JvmOverloads` to the `HostApi` setUp method. This prevents the calling Java code from having to provide an empty `String` as Kotlin provides it by default +* [kotlin] Adds the `@JvmOverloads` to the `HostApi` setUp method. This prevents the calling Java code from having to provide an empty `String` as Kotlin provides it by default ## 19.0.1 @@ -164,8 +222,6 @@ `YES`. Any data class or Flutter API interactions involving `bool`s should be carefully audited by hand when updating. - - ## 12.0.1 * [swift] Adds protocol for Flutter APIs. diff --git a/packages/pigeon/CONTRIBUTING.md b/packages/pigeon/CONTRIBUTING.md index 0caf41ec42da..4bf96c208086 100644 --- a/packages/pigeon/CONTRIBUTING.md +++ b/packages/pigeon/CONTRIBUTING.md @@ -21,8 +21,10 @@ generators with that AST. * [ast.dart](./lib/ast.dart) - The data structure for representing the Abstract Syntax Tree. * [dart_generator.dart](./lib/dart_generator.dart) - The Dart code generator. * [java_generator.dart](./lib/java_generator.dart) - The Java code generator. +* [kotlin_generator.dart](./lib/kotlin_generator.dart) - The Kotlin code generator. * [objc_generator.dart](./lib/objc_generator.dart) - The Objective-C code generator (header and source files). +* [swift_generator.dart](./lib/swift_generator.dart) - The Swift code generator. * [cpp_generator.dart](./lib/cpp_generator.dart) - The C++ code generator. * [generator_tools.dart](./lib/generator_tools.dart) - Shared code between generators. * [pigeon_cl.dart](./lib/pigeon_cl.dart) - The top-level function executed by @@ -49,13 +51,18 @@ Pigeon has 3 types of tests, you'll find them all in code, then execute the generated code. It can be thought of as unit-tests run against the generated code. Examples: [platform_tests](./platform_tests) +For local testing, always use `test.dart` rather than `run_tests.dart`, as +`run_tests.dart` is specifically a CI entrypoint. When iterating on a specific +generator, you will likely want to use the `-t` flag to specific only the +relevant tests. Pass `-l` to get a list of available tests for the `-t` flag. + ## Generated Source Code Example This is what the temporary generated code that the _PigeonIsolate_ executes looks like (see [State Diagram](#state-diagram)): ```dart -import 'path/to/supplied/pigeon/file.dart' +import 'path/to/supplied/pigeon/file.dart'; import 'dart:io'; import 'dart:isolate'; import 'package:pigeon/pigeon_lib.dart'; diff --git a/packages/pigeon/README.md b/packages/pigeon/README.md index 2eb938092a13..cc375f5e2faa 100644 --- a/packages/pigeon/README.md +++ b/packages/pigeon/README.md @@ -17,11 +17,12 @@ Currently pigeon supports generating: * Kotlin and Java code for Android * Swift and Objective-C code for iOS and macOS * C++ code for Windows +* GObject code for Linux ### Supported Datatypes Pigeon uses the `StandardMessageCodec` so it supports -[any datatype platform channels support](https://flutter.dev/docs/development/platform-integration/platform-channels#codec). +[any datatype platform channels support](https://flutter.dev/to/platform-channels-codec). Custom classes, nested datatypes, and enums are also supported. @@ -85,7 +86,7 @@ to the api to allow for multiple instances to be created and operate in parallel 1) Make a ".dart" file outside of your "lib" directory for defining the communication interface. 1) Run pigeon on your ".dart" file to generate the required Dart and - host-language code: `flutter pub get` then `flutter pub run pigeon` + host-language code: `flutter pub get` then `dart run pigeon` with suitable arguments. [Example](./example/README.md#Invocation). 1) Add the generated Dart code to `./lib` for compilation. 1) Implement the host-language code and add it to your build (see below). @@ -136,6 +137,13 @@ to the api to allow for multiple instances to be created and operate in parallel 1) Implement the generated protocol for handling the calls on macOS, set it up as the handler for the messages. +### Flutter calling into Linux steps + +1) Add the generated GObject code to your `./linux` directory for compilation, and + to your `linux/CMakeLists.txt` file. +1) Implement the generated protocol for handling the calls on Linux, set it up + as the vtable for the API object. + ### Calling into Flutter from the host platform Pigeon also supports calling in the opposite direction. The steps are similar diff --git a/packages/pigeon/example/README.md b/packages/pigeon/example/README.md index 46e8c643b1dc..bd5e4bd116af 100644 --- a/packages/pigeon/example/README.md +++ b/packages/pigeon/example/README.md @@ -19,6 +19,9 @@ needed for your project. cppOptions: CppOptions(namespace: 'pigeon_example'), cppHeaderOut: 'windows/runner/messages.g.h', cppSourceOut: 'windows/runner/messages.g.cpp', + gobjectHeaderOut: 'linux/messages.g.h', + gobjectSourceOut: 'linux/messages.g.cc', + gobjectOptions: GObjectOptions(), kotlinOut: 'android/app/src/main/kotlin/dev/flutter/pigeon_example_app/Messages.g.kt', kotlinOptions: KotlinOptions(), @@ -37,7 +40,7 @@ needed for your project. Then make a simple call to run pigeon on the Dart file containing your definitions. ```sh -flutter pub run pigeon --input path/to/input.dart +dart run pigeon --input path/to/input.dart ``` ## HostApi Example @@ -59,7 +62,7 @@ class MessageData { String? name; String? description; Code code; - Map data; + Map data; } @HostApi() @@ -100,7 +103,7 @@ Future add(int a, int b) async { Future sendMessage(String messageText) { final MessageData message = MessageData( code: Code.one, - data: {'header': 'this is a header'}, + data: {'header': 'this is a header'}, description: 'uri text', ); try { @@ -182,7 +185,7 @@ class PigeonApiImplementation : public ExampleHostApi { } void SendMessage(const MessageData& message, std::function reply)> result) { - if (message.code == Code.one) { + if (message.code == Code.kOne) { result(FlutterError("code", "message", "details")); return; } @@ -191,6 +194,49 @@ class PigeonApiImplementation : public ExampleHostApi { }; ``` +### GObject + +```c++ +static PigeonExamplePackageExampleHostApiGetHostLanguageResponse* +handle_get_host_language(gpointer user_data) { + return pigeon_example_package_example_host_api_get_host_language_response_new( + "C++"); +} + +static PigeonExamplePackageExampleHostApiAddResponse* handle_add( + int64_t a, int64_t b, gpointer user_data) { + if (a < 0 || b < 0) { + g_autoptr(FlValue) details = fl_value_new_string("details"); + return pigeon_example_package_example_host_api_add_response_new_error( + "code", "message", details); + } + + return pigeon_example_package_example_host_api_add_response_new(a + b); +} + +static void handle_send_message( + PigeonExamplePackageMessageData* message, + PigeonExamplePackageExampleHostApiResponseHandle* response_handle, + gpointer user_data) { + PigeonExamplePackageCode code = + pigeon_example_package_message_data_get_code(message); + if (code == PIGEON_EXAMPLE_PACKAGE_CODE_ONE) { + g_autoptr(FlValue) details = fl_value_new_string("details"); + pigeon_example_package_example_host_api_respond_error_send_message( + response_handle, "code", "message", details); + return; + } + + pigeon_example_package_example_host_api_respond_send_message(response_handle, + TRUE); +} + +static PigeonExamplePackageExampleHostApiVTable example_host_api_vtable = { + .get_host_language = handle_get_host_language, + .add = handle_add, + .send_message = handle_send_message}; +``` + ## FlutterApi Example This example gives an overview of how to use Pigeon to call into the Flutter @@ -274,6 +320,37 @@ void TestPlugin::CallFlutterMethod( } ``` +### GObject + + +```c++ +static void flutter_method_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(GError) error = nullptr; + g_autoptr( + PigeonExamplePackageMessageFlutterApiFlutterMethodResponse) response = + pigeon_example_package_message_flutter_api_flutter_method_finish( + PIGEON_EXAMPLE_PACKAGE_MESSAGE_FLUTTER_API(object), result, &error); + if (response == nullptr) { + g_warning("Failed to call Flutter method: %s", error->message); + return; + } + + g_printerr( + "Got result from Flutter method: %s\n", + pigeon_example_package_message_flutter_api_flutter_method_response_get_return_value( + response)); +} +``` + + +```c++ +self->flutter_api = + pigeon_example_package_message_flutter_api_new(messenger, nullptr); +pigeon_example_package_message_flutter_api_flutter_method( + self->flutter_api, "hello", nullptr, flutter_method_cb, self); +``` + ## Swift / Kotlin Plugin Example A downloadable example of using Pigeon to create a Flutter Plugin with Swift and diff --git a/packages/pigeon/example/app/android/.gitignore b/packages/pigeon/example/app/android/.gitignore index 6f568019d3c6..55afd919c659 100644 --- a/packages/pigeon/example/app/android/.gitignore +++ b/packages/pigeon/example/app/android/.gitignore @@ -7,7 +7,7 @@ gradle-wrapper.jar GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. -# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +# See https://flutter.dev/to/reference-keystore key.properties **/*.keystore **/*.jks diff --git a/packages/pigeon/example/app/android/app/build.gradle b/packages/pigeon/example/app/android/app/build.gradle index 0877433025ad..f898ecae685a 100644 --- a/packages/pigeon/example/app/android/app/build.gradle +++ b/packages/pigeon/example/app/android/app/build.gradle @@ -31,12 +31,12 @@ android { ndkVersion flutter.ndkVersion compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '11' } sourceSets { diff --git a/packages/pigeon/example/app/android/app/src/main/java/io/flutter/plugins/Messages.java b/packages/pigeon/example/app/android/app/src/main/java/io/flutter/plugins/Messages.java index 4993909460e1..8d9256c3795e 100644 --- a/packages/pigeon/example/app/android/app/src/main/java/io/flutter/plugins/Messages.java +++ b/packages/pigeon/example/app/android/app/src/main/java/io/flutter/plugins/Messages.java @@ -22,6 +22,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Objects; /** Generated class from Pigeon. */ @SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression", "serial"}) @@ -45,7 +46,7 @@ public FlutterError(@NonNull String code, @Nullable String message, @Nullable Ob @NonNull protected static ArrayList wrapError(@NonNull Throwable exception) { - ArrayList errorList = new ArrayList(3); + ArrayList errorList = new ArrayList<>(3); if (exception instanceof FlutterError) { FlutterError error = (FlutterError) exception; errorList.add(error.code); @@ -76,7 +77,7 @@ public enum Code { final int index; - private Code(final int index) { + Code(final int index) { this.index = index; } } @@ -132,6 +133,26 @@ public void setData(@NonNull Map setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ MessageData() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + MessageData that = (MessageData) o; + return Objects.equals(name, that.name) + && Objects.equals(description, that.description) + && code.equals(that.code) + && data.equals(that.data); + } + + @Override + public int hashCode() { + return Objects.hash(name, description, code, data); + } + public static final class Builder { private @Nullable String name; @@ -178,7 +199,7 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(4); + ArrayList toListResult = new ArrayList<>(4); toListResult.add(name); toListResult.add(description); toListResult.add(code); @@ -186,15 +207,15 @@ ArrayList toList() { return toListResult; } - static @NonNull MessageData fromList(@NonNull ArrayList __pigeon_list) { + static @NonNull MessageData fromList(@NonNull ArrayList pigeonVar_list) { MessageData pigeonResult = new MessageData(); - Object name = __pigeon_list.get(0); + Object name = pigeonVar_list.get(0); pigeonResult.setName((String) name); - Object description = __pigeon_list.get(1); + Object description = pigeonVar_list.get(1); pigeonResult.setDescription((String) description); - Object code = __pigeon_list.get(2); + Object code = pigeonVar_list.get(2); pigeonResult.setCode((Code) code); - Object data = __pigeon_list.get(3); + Object data = pigeonVar_list.get(3); pigeonResult.setData((Map) data); return pigeonResult; } @@ -209,10 +230,12 @@ private PigeonCodec() {} protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { switch (type) { case (byte) 129: - return MessageData.fromList((ArrayList) readValue(buffer)); + { + Object value = readValue(buffer); + return value == null ? null : Code.values()[((Long) value).intValue()]; + } case (byte) 130: - Object value = readValue(buffer); - return value == null ? null : Code.values()[(int) value]; + return MessageData.fromList((ArrayList) readValue(buffer)); default: return super.readValueOfType(type, buffer); } @@ -220,12 +243,12 @@ protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { @Override protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { - if (value instanceof MessageData) { + if (value instanceof Code) { stream.write(129); - writeValue(stream, ((MessageData) value).toList()); - } else if (value instanceof Code) { - stream.write(130); writeValue(stream, value == null ? null : ((Code) value).index); + } else if (value instanceof MessageData) { + stream.write(130); + writeValue(stream, ((MessageData) value).toList()); } else { super.writeValue(stream, value); } @@ -291,13 +314,12 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { String output = api.getHostLanguage(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -315,19 +337,15 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Number aArg = (Number) args.get(0); - Number bArg = (Number) args.get(1); + Long aArg = (Long) args.get(0); + Long bArg = (Long) args.get(1); try { - Long output = - api.add( - (aArg == null) ? null : aArg.longValue(), - (bArg == null) ? null : bArg.longValue()); + Long output = api.add(aArg, bArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -345,7 +363,7 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; MessageData messageArg = (MessageData) args.get(0); Result resultCallback = @@ -384,8 +402,7 @@ public MessageFlutterApi( this.messageChannelSuffix = messageChannelSuffix.isEmpty() ? "" : "." + messageChannelSuffix; } - /** Public interface for sending reply. */ - /** The codec used by MessageFlutterApi. */ + /** Public interface for sending reply. The codec used by MessageFlutterApi. */ static @NonNull MessageCodec getCodec() { return PigeonCodec.INSTANCE; } @@ -397,16 +414,14 @@ public void flutterMethod(@Nullable String aStringArg, @NonNull Result r BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(aStringArg)), + new ArrayList<>(Collections.singletonList(aStringArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else if (listReply.get(0) == null) { result.error( new FlutterError( diff --git a/packages/pigeon/example/app/android/app/src/main/kotlin/dev/flutter/pigeon_example_app/Messages.g.kt b/packages/pigeon/example/app/android/app/src/main/kotlin/dev/flutter/pigeon_example_app/Messages.g.kt index 6542e190e78e..c6b32713ebf4 100644 --- a/packages/pigeon/example/app/android/app/src/main/kotlin/dev/flutter/pigeon_example_app/Messages.g.kt +++ b/packages/pigeon/example/app/android/app/src/main/kotlin/dev/flutter/pigeon_example_app/Messages.g.kt @@ -62,15 +62,14 @@ data class MessageData( val name: String? = null, val description: String? = null, val code: Code, - val data: Map + val data: Map ) { companion object { - @Suppress("LocalVariableName") - fun fromList(__pigeon_list: List): MessageData { - val name = __pigeon_list[0] as String? - val description = __pigeon_list[1] as String? - val code = __pigeon_list[2] as Code - val data = __pigeon_list[3] as Map + fun fromList(pigeonVar_list: List): MessageData { + val name = pigeonVar_list[0] as String? + val description = pigeonVar_list[1] as String? + val code = pigeonVar_list[2] as Code + val data = pigeonVar_list[3] as Map return MessageData(name, description, code, data) } } @@ -85,14 +84,14 @@ data class MessageData( } } -private object MessagesPigeonCodec : StandardMessageCodec() { +private open class MessagesPigeonCodec : StandardMessageCodec() { override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? { return when (type) { 129.toByte() -> { - return (readValue(buffer) as? List)?.let { MessageData.fromList(it) } + return (readValue(buffer) as Long?)?.let { Code.ofRaw(it.toInt()) } } 130.toByte() -> { - return (readValue(buffer) as Int?)?.let { Code.ofRaw(it) } + return (readValue(buffer) as? List)?.let { MessageData.fromList(it) } } else -> super.readValueOfType(type, buffer) } @@ -100,13 +99,13 @@ private object MessagesPigeonCodec : StandardMessageCodec() { override fun writeValue(stream: ByteArrayOutputStream, value: Any?) { when (value) { - is MessageData -> { + is Code -> { stream.write(129) - writeValue(stream, value.toList()) + writeValue(stream, value.raw) } - is Code -> { + is MessageData -> { stream.write(130) - writeValue(stream, value.raw) + writeValue(stream, value.toList()) } else -> super.writeValue(stream, value) } @@ -123,7 +122,7 @@ interface ExampleHostApi { companion object { /** The codec used by ExampleHostApi. */ - val codec: MessageCodec by lazy { MessagesPigeonCodec } + val codec: MessageCodec by lazy { MessagesPigeonCodec() } /** Sets up an instance of `ExampleHostApi` to handle messages through the `binaryMessenger`. */ @JvmOverloads fun setUp( @@ -162,8 +161,8 @@ interface ExampleHostApi { if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aArg = args[0].let { num -> if (num is Int) num.toLong() else num as Long } - val bArg = args[1].let { num -> if (num is Int) num.toLong() else num as Long } + val aArg = args[0] as Long + val bArg = args[1] as Long val wrapped: List = try { listOf(api.add(aArg, bArg)) @@ -210,7 +209,7 @@ class MessageFlutterApi( ) { companion object { /** The codec used by MessageFlutterApi. */ - val codec: MessageCodec by lazy { MessagesPigeonCodec } + val codec: MessageCodec by lazy { MessagesPigeonCodec() } } fun flutterMethod(aStringArg: String?, callback: (Result) -> Unit) { diff --git a/packages/pigeon/example/app/android/build.gradle b/packages/pigeon/example/app/android/build.gradle index fdf447f8a7e6..4a9ad584b421 100644 --- a/packages/pigeon/example/app/android/build.gradle +++ b/packages/pigeon/example/app/android/build.gradle @@ -1,12 +1,12 @@ buildscript { - ext.kotlin_version = '1.7.10' + ext.kotlin_version = '1.9.0' repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.3.0' + classpath 'com.android.tools.build:gradle:8.5.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/packages/pigeon/example/app/android/gradle/wrapper/gradle-wrapper.properties b/packages/pigeon/example/app/android/gradle/wrapper/gradle-wrapper.properties index e1ca574ef017..3c85cfe057a1 100644 --- a/packages/pigeon/example/app/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/pigeon/example/app/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/pigeon/example/app/ios/Podfile b/packages/pigeon/example/app/ios/Podfile index 88359b225fa1..5fbdfa333224 100644 --- a/packages/pigeon/example/app/ios/Podfile +++ b/packages/pigeon/example/app/ios/Podfile @@ -29,7 +29,6 @@ flutter_ios_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) end diff --git a/packages/pigeon/example/app/ios/Runner/Messages.g.swift b/packages/pigeon/example/app/ios/Runner/Messages.g.swift index 3d5362cc4f1b..b42c8a41a1d5 100644 --- a/packages/pigeon/example/app/ios/Runner/Messages.g.swift +++ b/packages/pigeon/example/app/ios/Runner/Messages.g.swift @@ -83,14 +83,14 @@ struct MessageData { var name: String? = nil var description: String? = nil var code: Code - var data: [String?: String?] + var data: [String: String] // swift-format-ignore: AlwaysUseLowerCamelCase - static func fromList(_ __pigeon_list: [Any?]) -> MessageData? { - let name: String? = nilOrValue(__pigeon_list[0]) - let description: String? = nilOrValue(__pigeon_list[1]) - let code = __pigeon_list[2] as! Code - let data = __pigeon_list[3] as! [String?: String?] + static func fromList(_ pigeonVar_list: [Any?]) -> MessageData? { + let name: String? = nilOrValue(pigeonVar_list[0]) + let description: String? = nilOrValue(pigeonVar_list[1]) + let code = pigeonVar_list[2] as! Code + let data = pigeonVar_list[3] as! [String: String] return MessageData( name: name, @@ -108,18 +108,18 @@ struct MessageData { ] } } + private class MessagesPigeonCodecReader: FlutterStandardReader { override func readValue(ofType type: UInt8) -> Any? { switch type { case 129: - return MessageData.fromList(self.readValue() as! [Any?]) - case 130: - var enumResult: Code? = nil - let enumResultAsInt: Int? = nilOrValue(self.readValue() as? Int) + let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?) if let enumResultAsInt = enumResultAsInt { - enumResult = Code(rawValue: enumResultAsInt) + return Code(rawValue: enumResultAsInt) } - return enumResult + return nil + case 130: + return MessageData.fromList(self.readValue() as! [Any?]) default: return super.readValue(ofType: type) } @@ -128,12 +128,12 @@ private class MessagesPigeonCodecReader: FlutterStandardReader { private class MessagesPigeonCodecWriter: FlutterStandardWriter { override func writeValue(_ value: Any) { - if let value = value as? MessageData { + if let value = value as? Code { super.writeByte(129) - super.writeValue(value.toList()) - } else if let value = value as? Code { - super.writeByte(130) super.writeValue(value.rawValue) + } else if let value = value as? MessageData { + super.writeByte(130) + super.writeValue(value.toList()) } else { super.writeValue(value) } @@ -191,8 +191,8 @@ class ExampleHostApiSetup { if let api = api { addChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) - let bArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32) + let aArg = args[0] as! Int64 + let bArg = args[1] as! Int64 do { let result = try api.add(aArg, to: bArg) reply(wrapResult(result)) diff --git a/packages/pigeon/example/app/lib/main.dart b/packages/pigeon/example/app/lib/main.dart index 7f318d63d50d..cc158abe0c1f 100644 --- a/packages/pigeon/example/app/lib/main.dart +++ b/packages/pigeon/example/app/lib/main.dart @@ -19,6 +19,7 @@ class _ExampleFlutterApi implements MessageFlutterApi { // #enddocregion main-dart-flutter void main() { + WidgetsFlutterBinding.ensureInitialized(); // #docregion main-dart-flutter MessageFlutterApi.setUp(_ExampleFlutterApi()); // #enddocregion main-dart-flutter @@ -72,7 +73,7 @@ class _MyHomePageState extends State { Future sendMessage(String messageText) { final MessageData message = MessageData( code: Code.one, - data: {'header': 'this is a header'}, + data: {'header': 'this is a header'}, description: 'uri text', ); try { diff --git a/packages/pigeon/example/app/lib/src/messages.g.dart b/packages/pigeon/example/app/lib/src/messages.g.dart index d8d4fde551c5..330809525762 100644 --- a/packages/pigeon/example/app/lib/src/messages.g.dart +++ b/packages/pigeon/example/app/lib/src/messages.g.dart @@ -48,7 +48,7 @@ class MessageData { Code code; - Map data; + Map data; Object encode() { return [ @@ -65,7 +65,7 @@ class MessageData { name: result[0] as String?, description: result[1] as String?, code: result[2]! as Code, - data: (result[3] as Map?)!.cast(), + data: (result[3] as Map?)!.cast(), ); } } @@ -74,12 +74,15 @@ class _PigeonCodec extends StandardMessageCodec { const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is MessageData) { - buffer.putUint8(129); - writeValue(buffer, value.encode()); + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); } else if (value is Code) { - buffer.putUint8(130); + buffer.putUint8(129); writeValue(buffer, value.index); + } else if (value is MessageData) { + buffer.putUint8(130); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -89,10 +92,10 @@ class _PigeonCodec extends StandardMessageCodec { Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { case 129: - return MessageData.decode(readValue(buffer)!); - case 130: final int? value = readValue(buffer) as int?; return value == null ? null : Code.values[value]; + case 130: + return MessageData.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -105,99 +108,99 @@ class ExampleHostApi { /// BinaryMessenger will be used which routes to the host platform. ExampleHostApi( {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : __pigeon_binaryMessenger = binaryMessenger, - __pigeon_messageChannelSuffix = + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; - final BinaryMessenger? __pigeon_binaryMessenger; + final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - final String __pigeon_messageChannelSuffix; + final String pigeonVar_messageChannelSuffix; Future getHostLanguage() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_example_package.ExampleHostApi.getHostLanguage$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_example_package.ExampleHostApi.getHostLanguage$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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 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 String?)!; + return (pigeonVar_replyList[0] as String?)!; } } Future add(int a, int b) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_example_package.ExampleHostApi.add$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_example_package.ExampleHostApi.add$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([a, b]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([a, b]) 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 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 int?)!; + return (pigeonVar_replyList[0] as int?)!; } } Future sendMessage(MessageData message) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_example_package.ExampleHostApi.sendMessage$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_example_package.ExampleHostApi.sendMessage$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([message]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([message]) 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 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 bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } } @@ -215,15 +218,16 @@ abstract class MessageFlutterApi { messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_example_package.MessageFlutterApi.flutterMethod$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_example_package.MessageFlutterApi.flutterMethod was null.'); final List args = (message as List?)!; diff --git a/packages/pigeon/example/app/linux/.gitignore b/packages/pigeon/example/app/linux/.gitignore new file mode 100644 index 000000000000..d3896c98444f --- /dev/null +++ b/packages/pigeon/example/app/linux/.gitignore @@ -0,0 +1 @@ +flutter/ephemeral diff --git a/packages/pigeon/example/app/linux/CMakeLists.txt b/packages/pigeon/example/app/linux/CMakeLists.txt new file mode 100644 index 000000000000..340076b55677 --- /dev/null +++ b/packages/pigeon/example/app/linux/CMakeLists.txt @@ -0,0 +1,140 @@ +# Project-level configuration. +cmake_minimum_required(VERSION 3.10) +project(runner LANGUAGES CXX) + +# The name of the executable created for the application. Change this to change +# the on-disk name of your application. +set(BINARY_NAME "pigeon_example_app") +# The unique GTK application identifier for this application. See: +# https://wiki.gnome.org/HowDoI/ChooseApplicationID +set(APPLICATION_ID "dev.flutter.pigeon_example_app") + +# Explicitly opt in to modern CMake behaviors to avoid warnings with recent +# versions of CMake. +cmake_policy(SET CMP0063 NEW) + +# Load bundled libraries from the lib/ directory relative to the binary. +set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") + +# Root filesystem for cross-building. +if(FLUTTER_TARGET_PLATFORM_SYSROOT) + set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) + set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +endif() + +# Define build configuration options. +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") +endif() + +# Compilation settings that should be applied to most targets. +# +# Be cautious about adding new options here, as plugins use this function by +# default. In most cases, you should add new options to specific targets instead +# of modifying this function. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_14) + target_compile_options(${TARGET} PRIVATE -Wall -Werror) + target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") + target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") +endfunction() + +# Flutter library and tool build rules. +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) + +add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") + +# Define the application target. To change its name, change BINARY_NAME above, +# not the value here, or `flutter run` will no longer work. +# +# Any new source files that you add to the application should be added here. +add_executable(${BINARY_NAME} + "main.cc" + "my_application.cc" + "messages.g.cc" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" +) + +# Apply the standard set of build settings. This can be removed for applications +# that need different build settings. +apply_standard_settings(${BINARY_NAME}) + +# Add dependency libraries. Add any application-specific dependencies here. +target_link_libraries(${BINARY_NAME} PRIVATE flutter) +target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) + +# Run the Flutter tool portions of the build. This must not be removed. +add_dependencies(${BINARY_NAME} flutter_assemble) + +# Only the install-generated bundle's copy of the executable will launch +# correctly, since the resources must in the right relative locations. To avoid +# people trying to run the unbundled copy, put it in a subdirectory instead of +# the default top-level location. +set_target_properties(${BINARY_NAME} + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" +) + + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# By default, "installing" just makes a relocatable bundle in the build +# directory. +set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +# Start with a clean build bundle directory every time. +install(CODE " + file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") + " COMPONENT Runtime) + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) + install(FILES "${bundled_library}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endforeach(bundled_library) + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") + install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() diff --git a/packages/pigeon/example/app/linux/flutter/CMakeLists.txt b/packages/pigeon/example/app/linux/flutter/CMakeLists.txt new file mode 100644 index 000000000000..d5bd01648a96 --- /dev/null +++ b/packages/pigeon/example/app/linux/flutter/CMakeLists.txt @@ -0,0 +1,88 @@ +# This file controls Flutter-level build steps. It should not be edited. +cmake_minimum_required(VERSION 3.10) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. + +# Serves the same purpose as list(TRANSFORM ... PREPEND ...), +# which isn't available in 3.10. +function(list_prepend LIST_NAME PREFIX) + set(NEW_LIST "") + foreach(element ${${LIST_NAME}}) + list(APPEND NEW_LIST "${PREFIX}${element}") + endforeach(element) + set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) +endfunction() + +# === Flutter Library === +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) +pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) +pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) + +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "fl_basic_message_channel.h" + "fl_binary_codec.h" + "fl_binary_messenger.h" + "fl_dart_project.h" + "fl_engine.h" + "fl_json_message_codec.h" + "fl_json_method_codec.h" + "fl_message_codec.h" + "fl_method_call.h" + "fl_method_channel.h" + "fl_method_codec.h" + "fl_method_response.h" + "fl_plugin_registrar.h" + "fl_plugin_registry.h" + "fl_standard_message_codec.h" + "fl_standard_method_codec.h" + "fl_string_codec.h" + "fl_value.h" + "fl_view.h" + "flutter_linux.h" +) +list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") +target_link_libraries(flutter INTERFACE + PkgConfig::GTK + PkgConfig::GLIB + PkgConfig::GIO +) +add_dependencies(flutter flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CMAKE_CURRENT_BINARY_DIR}/_phony_ + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" + ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} +) diff --git a/packages/pigeon/example/app/linux/flutter/generated_plugins.cmake b/packages/pigeon/example/app/linux/flutter/generated_plugins.cmake new file mode 100644 index 000000000000..2e1de87a7eb6 --- /dev/null +++ b/packages/pigeon/example/app/linux/flutter/generated_plugins.cmake @@ -0,0 +1,23 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/packages/pigeon/example/app/linux/main.cc b/packages/pigeon/example/app/linux/main.cc new file mode 100644 index 000000000000..1507d02825e7 --- /dev/null +++ b/packages/pigeon/example/app/linux/main.cc @@ -0,0 +1,10 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "my_application.h" + +int main(int argc, char** argv) { + g_autoptr(MyApplication) app = my_application_new(); + return g_application_run(G_APPLICATION(app), argc, argv); +} diff --git a/packages/pigeon/example/app/linux/messages.g.cc b/packages/pigeon/example/app/linux/messages.g.cc new file mode 100644 index 000000000000..a9ee2105989f --- /dev/null +++ b/packages/pigeon/example/app/linux/messages.g.cc @@ -0,0 +1,898 @@ +// 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, do not edit directly. +// See also: https://pub.dev/packages/pigeon + +#include "messages.g.h" + +struct _PigeonExamplePackageMessageData { + GObject parent_instance; + + gchar* name; + gchar* description; + PigeonExamplePackageCode code; + FlValue* data; +}; + +G_DEFINE_TYPE(PigeonExamplePackageMessageData, + pigeon_example_package_message_data, G_TYPE_OBJECT) + +static void pigeon_example_package_message_data_dispose(GObject* object) { + PigeonExamplePackageMessageData* self = + PIGEON_EXAMPLE_PACKAGE_MESSAGE_DATA(object); + g_clear_pointer(&self->name, g_free); + g_clear_pointer(&self->description, g_free); + g_clear_pointer(&self->data, fl_value_unref); + G_OBJECT_CLASS(pigeon_example_package_message_data_parent_class) + ->dispose(object); +} + +static void pigeon_example_package_message_data_init( + PigeonExamplePackageMessageData* self) {} + +static void pigeon_example_package_message_data_class_init( + PigeonExamplePackageMessageDataClass* klass) { + G_OBJECT_CLASS(klass)->dispose = pigeon_example_package_message_data_dispose; +} + +PigeonExamplePackageMessageData* pigeon_example_package_message_data_new( + const gchar* name, const gchar* description, PigeonExamplePackageCode code, + FlValue* data) { + PigeonExamplePackageMessageData* self = PIGEON_EXAMPLE_PACKAGE_MESSAGE_DATA( + g_object_new(pigeon_example_package_message_data_get_type(), nullptr)); + if (name != nullptr) { + self->name = g_strdup(name); + } else { + self->name = nullptr; + } + if (description != nullptr) { + self->description = g_strdup(description); + } else { + self->description = nullptr; + } + self->code = code; + self->data = fl_value_ref(data); + return self; +} + +const gchar* pigeon_example_package_message_data_get_name( + PigeonExamplePackageMessageData* self) { + g_return_val_if_fail(PIGEON_EXAMPLE_PACKAGE_IS_MESSAGE_DATA(self), nullptr); + return self->name; +} + +const gchar* pigeon_example_package_message_data_get_description( + PigeonExamplePackageMessageData* self) { + g_return_val_if_fail(PIGEON_EXAMPLE_PACKAGE_IS_MESSAGE_DATA(self), nullptr); + return self->description; +} + +PigeonExamplePackageCode pigeon_example_package_message_data_get_code( + PigeonExamplePackageMessageData* self) { + g_return_val_if_fail(PIGEON_EXAMPLE_PACKAGE_IS_MESSAGE_DATA(self), + static_cast(0)); + return self->code; +} + +FlValue* pigeon_example_package_message_data_get_data( + PigeonExamplePackageMessageData* self) { + g_return_val_if_fail(PIGEON_EXAMPLE_PACKAGE_IS_MESSAGE_DATA(self), nullptr); + return self->data; +} + +static FlValue* pigeon_example_package_message_data_to_list( + PigeonExamplePackageMessageData* self) { + FlValue* values = fl_value_new_list(); + fl_value_append_take(values, self->name != nullptr + ? fl_value_new_string(self->name) + : fl_value_new_null()); + fl_value_append_take(values, self->description != nullptr + ? fl_value_new_string(self->description) + : fl_value_new_null()); + fl_value_append_take(values, + fl_value_new_custom(129, fl_value_new_int(self->code), + (GDestroyNotify)fl_value_unref)); + fl_value_append_take(values, fl_value_ref(self->data)); + return values; +} + +static PigeonExamplePackageMessageData* +pigeon_example_package_message_data_new_from_list(FlValue* values) { + FlValue* value0 = fl_value_get_list_value(values, 0); + const gchar* name = nullptr; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + name = fl_value_get_string(value0); + } + FlValue* value1 = fl_value_get_list_value(values, 1); + const gchar* description = nullptr; + if (fl_value_get_type(value1) != FL_VALUE_TYPE_NULL) { + description = fl_value_get_string(value1); + } + FlValue* value2 = fl_value_get_list_value(values, 2); + PigeonExamplePackageCode code = static_cast( + fl_value_get_int(reinterpret_cast( + const_cast(fl_value_get_custom_value(value2))))); + FlValue* value3 = fl_value_get_list_value(values, 3); + FlValue* data = value3; + return pigeon_example_package_message_data_new(name, description, code, data); +} + +G_DECLARE_FINAL_TYPE(PigeonExamplePackageMessageCodec, + pigeon_example_package_message_codec, + PIGEON_EXAMPLE_PACKAGE, MESSAGE_CODEC, + FlStandardMessageCodec) + +struct _PigeonExamplePackageMessageCodec { + FlStandardMessageCodec parent_instance; +}; + +G_DEFINE_TYPE(PigeonExamplePackageMessageCodec, + pigeon_example_package_message_codec, + fl_standard_message_codec_get_type()) + +static gboolean +pigeon_example_package_message_codec_write_pigeon_example_package_code( + FlStandardMessageCodec* codec, GByteArray* buffer, FlValue* value, + GError** error) { + uint8_t type = 129; + g_byte_array_append(buffer, &type, sizeof(uint8_t)); + return fl_standard_message_codec_write_value(codec, buffer, value, error); +} + +static gboolean +pigeon_example_package_message_codec_write_pigeon_example_package_message_data( + FlStandardMessageCodec* codec, GByteArray* buffer, + PigeonExamplePackageMessageData* value, GError** error) { + uint8_t type = 130; + g_byte_array_append(buffer, &type, sizeof(uint8_t)); + g_autoptr(FlValue) values = + pigeon_example_package_message_data_to_list(value); + return fl_standard_message_codec_write_value(codec, buffer, values, error); +} + +static gboolean pigeon_example_package_message_codec_write_value( + FlStandardMessageCodec* codec, GByteArray* buffer, FlValue* value, + GError** error) { + if (fl_value_get_type(value) == FL_VALUE_TYPE_CUSTOM) { + switch (fl_value_get_custom_type(value)) { + case 129: + return pigeon_example_package_message_codec_write_pigeon_example_package_code( + codec, buffer, + reinterpret_cast( + const_cast(fl_value_get_custom_value(value))), + error); + case 130: + return pigeon_example_package_message_codec_write_pigeon_example_package_message_data( + codec, buffer, + PIGEON_EXAMPLE_PACKAGE_MESSAGE_DATA( + fl_value_get_custom_value_object(value)), + error); + } + } + + return FL_STANDARD_MESSAGE_CODEC_CLASS( + pigeon_example_package_message_codec_parent_class) + ->write_value(codec, buffer, value, error); +} + +static FlValue* +pigeon_example_package_message_codec_read_pigeon_example_package_code( + FlStandardMessageCodec* codec, GBytes* buffer, size_t* offset, + GError** error) { + return fl_value_new_custom( + 129, fl_standard_message_codec_read_value(codec, buffer, offset, error), + (GDestroyNotify)fl_value_unref); +} + +static FlValue* +pigeon_example_package_message_codec_read_pigeon_example_package_message_data( + FlStandardMessageCodec* codec, GBytes* buffer, size_t* offset, + GError** error) { + g_autoptr(FlValue) values = + fl_standard_message_codec_read_value(codec, buffer, offset, error); + if (values == nullptr) { + return nullptr; + } + + g_autoptr(PigeonExamplePackageMessageData) value = + pigeon_example_package_message_data_new_from_list(values); + if (value == nullptr) { + g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED, + "Invalid data received for MessageData"); + return nullptr; + } + + return fl_value_new_custom_object(130, G_OBJECT(value)); +} + +static FlValue* pigeon_example_package_message_codec_read_value_of_type( + FlStandardMessageCodec* codec, GBytes* buffer, size_t* offset, int type, + GError** error) { + switch (type) { + case 129: + return pigeon_example_package_message_codec_read_pigeon_example_package_code( + codec, buffer, offset, error); + case 130: + return pigeon_example_package_message_codec_read_pigeon_example_package_message_data( + codec, buffer, offset, error); + default: + return FL_STANDARD_MESSAGE_CODEC_CLASS( + pigeon_example_package_message_codec_parent_class) + ->read_value_of_type(codec, buffer, offset, type, error); + } +} + +static void pigeon_example_package_message_codec_init( + PigeonExamplePackageMessageCodec* self) {} + +static void pigeon_example_package_message_codec_class_init( + PigeonExamplePackageMessageCodecClass* klass) { + FL_STANDARD_MESSAGE_CODEC_CLASS(klass)->write_value = + pigeon_example_package_message_codec_write_value; + FL_STANDARD_MESSAGE_CODEC_CLASS(klass)->read_value_of_type = + pigeon_example_package_message_codec_read_value_of_type; +} + +static PigeonExamplePackageMessageCodec* +pigeon_example_package_message_codec_new() { + PigeonExamplePackageMessageCodec* self = PIGEON_EXAMPLE_PACKAGE_MESSAGE_CODEC( + g_object_new(pigeon_example_package_message_codec_get_type(), nullptr)); + return self; +} + +struct _PigeonExamplePackageExampleHostApiResponseHandle { + GObject parent_instance; + + FlBasicMessageChannel* channel; + FlBasicMessageChannelResponseHandle* response_handle; +}; + +G_DEFINE_TYPE(PigeonExamplePackageExampleHostApiResponseHandle, + pigeon_example_package_example_host_api_response_handle, + G_TYPE_OBJECT) + +static void pigeon_example_package_example_host_api_response_handle_dispose( + GObject* object) { + PigeonExamplePackageExampleHostApiResponseHandle* self = + PIGEON_EXAMPLE_PACKAGE_EXAMPLE_HOST_API_RESPONSE_HANDLE(object); + g_clear_object(&self->channel); + g_clear_object(&self->response_handle); + G_OBJECT_CLASS( + pigeon_example_package_example_host_api_response_handle_parent_class) + ->dispose(object); +} + +static void pigeon_example_package_example_host_api_response_handle_init( + PigeonExamplePackageExampleHostApiResponseHandle* self) {} + +static void pigeon_example_package_example_host_api_response_handle_class_init( + PigeonExamplePackageExampleHostApiResponseHandleClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + pigeon_example_package_example_host_api_response_handle_dispose; +} + +static PigeonExamplePackageExampleHostApiResponseHandle* +pigeon_example_package_example_host_api_response_handle_new( + FlBasicMessageChannel* channel, + FlBasicMessageChannelResponseHandle* response_handle) { + PigeonExamplePackageExampleHostApiResponseHandle* self = + PIGEON_EXAMPLE_PACKAGE_EXAMPLE_HOST_API_RESPONSE_HANDLE(g_object_new( + pigeon_example_package_example_host_api_response_handle_get_type(), + nullptr)); + self->channel = FL_BASIC_MESSAGE_CHANNEL(g_object_ref(channel)); + self->response_handle = + FL_BASIC_MESSAGE_CHANNEL_RESPONSE_HANDLE(g_object_ref(response_handle)); + return self; +} + +struct _PigeonExamplePackageExampleHostApiGetHostLanguageResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + PigeonExamplePackageExampleHostApiGetHostLanguageResponse, + pigeon_example_package_example_host_api_get_host_language_response, + G_TYPE_OBJECT) + +static void +pigeon_example_package_example_host_api_get_host_language_response_dispose( + GObject* object) { + PigeonExamplePackageExampleHostApiGetHostLanguageResponse* self = + PIGEON_EXAMPLE_PACKAGE_EXAMPLE_HOST_API_GET_HOST_LANGUAGE_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + pigeon_example_package_example_host_api_get_host_language_response_parent_class) + ->dispose(object); +} + +static void +pigeon_example_package_example_host_api_get_host_language_response_init( + PigeonExamplePackageExampleHostApiGetHostLanguageResponse* self) {} + +static void +pigeon_example_package_example_host_api_get_host_language_response_class_init( + PigeonExamplePackageExampleHostApiGetHostLanguageResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + pigeon_example_package_example_host_api_get_host_language_response_dispose; +} + +PigeonExamplePackageExampleHostApiGetHostLanguageResponse* +pigeon_example_package_example_host_api_get_host_language_response_new( + const gchar* return_value) { + PigeonExamplePackageExampleHostApiGetHostLanguageResponse* self = + PIGEON_EXAMPLE_PACKAGE_EXAMPLE_HOST_API_GET_HOST_LANGUAGE_RESPONSE(g_object_new( + pigeon_example_package_example_host_api_get_host_language_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(return_value)); + return self; +} + +PigeonExamplePackageExampleHostApiGetHostLanguageResponse* +pigeon_example_package_example_host_api_get_host_language_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + PigeonExamplePackageExampleHostApiGetHostLanguageResponse* self = + PIGEON_EXAMPLE_PACKAGE_EXAMPLE_HOST_API_GET_HOST_LANGUAGE_RESPONSE(g_object_new( + pigeon_example_package_example_host_api_get_host_language_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _PigeonExamplePackageExampleHostApiAddResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE(PigeonExamplePackageExampleHostApiAddResponse, + pigeon_example_package_example_host_api_add_response, + G_TYPE_OBJECT) + +static void pigeon_example_package_example_host_api_add_response_dispose( + GObject* object) { + PigeonExamplePackageExampleHostApiAddResponse* self = + PIGEON_EXAMPLE_PACKAGE_EXAMPLE_HOST_API_ADD_RESPONSE(object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + pigeon_example_package_example_host_api_add_response_parent_class) + ->dispose(object); +} + +static void pigeon_example_package_example_host_api_add_response_init( + PigeonExamplePackageExampleHostApiAddResponse* self) {} + +static void pigeon_example_package_example_host_api_add_response_class_init( + PigeonExamplePackageExampleHostApiAddResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + pigeon_example_package_example_host_api_add_response_dispose; +} + +PigeonExamplePackageExampleHostApiAddResponse* +pigeon_example_package_example_host_api_add_response_new(int64_t return_value) { + PigeonExamplePackageExampleHostApiAddResponse* self = + PIGEON_EXAMPLE_PACKAGE_EXAMPLE_HOST_API_ADD_RESPONSE(g_object_new( + pigeon_example_package_example_host_api_add_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_int(return_value)); + return self; +} + +PigeonExamplePackageExampleHostApiAddResponse* +pigeon_example_package_example_host_api_add_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + PigeonExamplePackageExampleHostApiAddResponse* self = + PIGEON_EXAMPLE_PACKAGE_EXAMPLE_HOST_API_ADD_RESPONSE(g_object_new( + pigeon_example_package_example_host_api_add_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + PigeonExamplePackageExampleHostApiSendMessageResponse, + pigeon_example_package_example_host_api_send_message_response, + PIGEON_EXAMPLE_PACKAGE, EXAMPLE_HOST_API_SEND_MESSAGE_RESPONSE, GObject) + +struct _PigeonExamplePackageExampleHostApiSendMessageResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE(PigeonExamplePackageExampleHostApiSendMessageResponse, + pigeon_example_package_example_host_api_send_message_response, + G_TYPE_OBJECT) + +static void +pigeon_example_package_example_host_api_send_message_response_dispose( + GObject* object) { + PigeonExamplePackageExampleHostApiSendMessageResponse* self = + PIGEON_EXAMPLE_PACKAGE_EXAMPLE_HOST_API_SEND_MESSAGE_RESPONSE(object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + pigeon_example_package_example_host_api_send_message_response_parent_class) + ->dispose(object); +} + +static void pigeon_example_package_example_host_api_send_message_response_init( + PigeonExamplePackageExampleHostApiSendMessageResponse* self) {} + +static void +pigeon_example_package_example_host_api_send_message_response_class_init( + PigeonExamplePackageExampleHostApiSendMessageResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + pigeon_example_package_example_host_api_send_message_response_dispose; +} + +static PigeonExamplePackageExampleHostApiSendMessageResponse* +pigeon_example_package_example_host_api_send_message_response_new( + gboolean return_value) { + PigeonExamplePackageExampleHostApiSendMessageResponse* self = + PIGEON_EXAMPLE_PACKAGE_EXAMPLE_HOST_API_SEND_MESSAGE_RESPONSE(g_object_new( + pigeon_example_package_example_host_api_send_message_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_bool(return_value)); + return self; +} + +static PigeonExamplePackageExampleHostApiSendMessageResponse* +pigeon_example_package_example_host_api_send_message_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + PigeonExamplePackageExampleHostApiSendMessageResponse* self = + PIGEON_EXAMPLE_PACKAGE_EXAMPLE_HOST_API_SEND_MESSAGE_RESPONSE(g_object_new( + pigeon_example_package_example_host_api_send_message_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE(PigeonExamplePackageExampleHostApi, + pigeon_example_package_example_host_api, + PIGEON_EXAMPLE_PACKAGE, EXAMPLE_HOST_API, GObject) + +struct _PigeonExamplePackageExampleHostApi { + GObject parent_instance; + + const PigeonExamplePackageExampleHostApiVTable* vtable; + gpointer user_data; + GDestroyNotify user_data_free_func; +}; + +G_DEFINE_TYPE(PigeonExamplePackageExampleHostApi, + pigeon_example_package_example_host_api, G_TYPE_OBJECT) + +static void pigeon_example_package_example_host_api_dispose(GObject* object) { + PigeonExamplePackageExampleHostApi* self = + PIGEON_EXAMPLE_PACKAGE_EXAMPLE_HOST_API(object); + if (self->user_data != nullptr) { + self->user_data_free_func(self->user_data); + } + self->user_data = nullptr; + G_OBJECT_CLASS(pigeon_example_package_example_host_api_parent_class) + ->dispose(object); +} + +static void pigeon_example_package_example_host_api_init( + PigeonExamplePackageExampleHostApi* self) {} + +static void pigeon_example_package_example_host_api_class_init( + PigeonExamplePackageExampleHostApiClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + pigeon_example_package_example_host_api_dispose; +} + +static PigeonExamplePackageExampleHostApi* +pigeon_example_package_example_host_api_new( + const PigeonExamplePackageExampleHostApiVTable* vtable, gpointer user_data, + GDestroyNotify user_data_free_func) { + PigeonExamplePackageExampleHostApi* self = + PIGEON_EXAMPLE_PACKAGE_EXAMPLE_HOST_API(g_object_new( + pigeon_example_package_example_host_api_get_type(), nullptr)); + self->vtable = vtable; + self->user_data = user_data; + self->user_data_free_func = user_data_free_func; + return self; +} + +static void pigeon_example_package_example_host_api_get_host_language_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + PigeonExamplePackageExampleHostApi* self = + PIGEON_EXAMPLE_PACKAGE_EXAMPLE_HOST_API(user_data); + + if (self->vtable == nullptr || self->vtable->get_host_language == nullptr) { + return; + } + + g_autoptr(PigeonExamplePackageExampleHostApiGetHostLanguageResponse) + response = self->vtable->get_host_language(self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "ExampleHostApi", + "getHostLanguage"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "ExampleHostApi", + "getHostLanguage", error->message); + } +} + +static void pigeon_example_package_example_host_api_add_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + PigeonExamplePackageExampleHostApi* self = + PIGEON_EXAMPLE_PACKAGE_EXAMPLE_HOST_API(user_data); + + if (self->vtable == nullptr || self->vtable->add == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + int64_t a = fl_value_get_int(value0); + FlValue* value1 = fl_value_get_list_value(message_, 1); + int64_t b = fl_value_get_int(value1); + g_autoptr(PigeonExamplePackageExampleHostApiAddResponse) response = + self->vtable->add(a, b, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "ExampleHostApi", "add"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "ExampleHostApi", "add", + error->message); + } +} + +static void pigeon_example_package_example_host_api_send_message_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + PigeonExamplePackageExampleHostApi* self = + PIGEON_EXAMPLE_PACKAGE_EXAMPLE_HOST_API(user_data); + + if (self->vtable == nullptr || self->vtable->send_message == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + PigeonExamplePackageMessageData* message = + PIGEON_EXAMPLE_PACKAGE_MESSAGE_DATA( + fl_value_get_custom_value_object(value0)); + g_autoptr(PigeonExamplePackageExampleHostApiResponseHandle) handle = + pigeon_example_package_example_host_api_response_handle_new( + channel, response_handle); + self->vtable->send_message(message, handle, self->user_data); +} + +void pigeon_example_package_example_host_api_set_method_handlers( + FlBinaryMessenger* messenger, const gchar* suffix, + const PigeonExamplePackageExampleHostApiVTable* vtable, gpointer user_data, + GDestroyNotify user_data_free_func) { + g_autofree gchar* dot_suffix = + suffix != nullptr ? g_strdup_printf(".%s", suffix) : g_strdup(""); + g_autoptr(PigeonExamplePackageExampleHostApi) api_data = + pigeon_example_package_example_host_api_new(vtable, user_data, + user_data_free_func); + + g_autoptr(PigeonExamplePackageMessageCodec) codec = + pigeon_example_package_message_codec_new(); + g_autofree gchar* get_host_language_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_example_package.ExampleHostApi." + "getHostLanguage%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) get_host_language_channel = + fl_basic_message_channel_new(messenger, get_host_language_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + get_host_language_channel, + pigeon_example_package_example_host_api_get_host_language_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* add_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_example_package.ExampleHostApi.add%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) add_channel = fl_basic_message_channel_new( + messenger, add_channel_name, FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + add_channel, pigeon_example_package_example_host_api_add_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* send_message_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_example_package.ExampleHostApi.sendMessage%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) send_message_channel = + fl_basic_message_channel_new(messenger, send_message_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + send_message_channel, + pigeon_example_package_example_host_api_send_message_cb, + g_object_ref(api_data), g_object_unref); +} + +void pigeon_example_package_example_host_api_clear_method_handlers( + FlBinaryMessenger* messenger, const gchar* suffix) { + g_autofree gchar* dot_suffix = + suffix != nullptr ? g_strdup_printf(".%s", suffix) : g_strdup(""); + + g_autoptr(PigeonExamplePackageMessageCodec) codec = + pigeon_example_package_message_codec_new(); + g_autofree gchar* get_host_language_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_example_package.ExampleHostApi." + "getHostLanguage%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) get_host_language_channel = + fl_basic_message_channel_new(messenger, get_host_language_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(get_host_language_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* add_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_example_package.ExampleHostApi.add%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) add_channel = fl_basic_message_channel_new( + messenger, add_channel_name, FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(add_channel, nullptr, nullptr, + nullptr); + g_autofree gchar* send_message_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_example_package.ExampleHostApi.sendMessage%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) send_message_channel = + fl_basic_message_channel_new(messenger, send_message_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(send_message_channel, nullptr, + nullptr, nullptr); +} + +void pigeon_example_package_example_host_api_respond_send_message( + PigeonExamplePackageExampleHostApiResponseHandle* response_handle, + gboolean return_value) { + g_autoptr(PigeonExamplePackageExampleHostApiSendMessageResponse) response = + pigeon_example_package_example_host_api_send_message_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "ExampleHostApi", + "sendMessage", error->message); + } +} + +void pigeon_example_package_example_host_api_respond_error_send_message( + PigeonExamplePackageExampleHostApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr(PigeonExamplePackageExampleHostApiSendMessageResponse) response = + pigeon_example_package_example_host_api_send_message_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "ExampleHostApi", + "sendMessage", error->message); + } +} + +struct _PigeonExamplePackageMessageFlutterApi { + GObject parent_instance; + + FlBinaryMessenger* messenger; + gchar* suffix; +}; + +G_DEFINE_TYPE(PigeonExamplePackageMessageFlutterApi, + pigeon_example_package_message_flutter_api, G_TYPE_OBJECT) + +static void pigeon_example_package_message_flutter_api_dispose( + GObject* object) { + PigeonExamplePackageMessageFlutterApi* self = + PIGEON_EXAMPLE_PACKAGE_MESSAGE_FLUTTER_API(object); + g_clear_object(&self->messenger); + g_clear_pointer(&self->suffix, g_free); + G_OBJECT_CLASS(pigeon_example_package_message_flutter_api_parent_class) + ->dispose(object); +} + +static void pigeon_example_package_message_flutter_api_init( + PigeonExamplePackageMessageFlutterApi* self) {} + +static void pigeon_example_package_message_flutter_api_class_init( + PigeonExamplePackageMessageFlutterApiClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + pigeon_example_package_message_flutter_api_dispose; +} + +PigeonExamplePackageMessageFlutterApi* +pigeon_example_package_message_flutter_api_new(FlBinaryMessenger* messenger, + const gchar* suffix) { + PigeonExamplePackageMessageFlutterApi* self = + PIGEON_EXAMPLE_PACKAGE_MESSAGE_FLUTTER_API(g_object_new( + pigeon_example_package_message_flutter_api_get_type(), nullptr)); + self->messenger = FL_BINARY_MESSENGER(g_object_ref(messenger)); + self->suffix = + suffix != nullptr ? g_strdup_printf(".%s", suffix) : g_strdup(""); + return self; +} + +struct _PigeonExamplePackageMessageFlutterApiFlutterMethodResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + PigeonExamplePackageMessageFlutterApiFlutterMethodResponse, + pigeon_example_package_message_flutter_api_flutter_method_response, + G_TYPE_OBJECT) + +static void +pigeon_example_package_message_flutter_api_flutter_method_response_dispose( + GObject* object) { + PigeonExamplePackageMessageFlutterApiFlutterMethodResponse* self = + PIGEON_EXAMPLE_PACKAGE_MESSAGE_FLUTTER_API_FLUTTER_METHOD_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + pigeon_example_package_message_flutter_api_flutter_method_response_parent_class) + ->dispose(object); +} + +static void +pigeon_example_package_message_flutter_api_flutter_method_response_init( + PigeonExamplePackageMessageFlutterApiFlutterMethodResponse* self) {} + +static void +pigeon_example_package_message_flutter_api_flutter_method_response_class_init( + PigeonExamplePackageMessageFlutterApiFlutterMethodResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + pigeon_example_package_message_flutter_api_flutter_method_response_dispose; +} + +static PigeonExamplePackageMessageFlutterApiFlutterMethodResponse* +pigeon_example_package_message_flutter_api_flutter_method_response_new( + FlValue* response) { + PigeonExamplePackageMessageFlutterApiFlutterMethodResponse* self = + PIGEON_EXAMPLE_PACKAGE_MESSAGE_FLUTTER_API_FLUTTER_METHOD_RESPONSE(g_object_new( + pigeon_example_package_message_flutter_api_flutter_method_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +pigeon_example_package_message_flutter_api_flutter_method_response_is_error( + PigeonExamplePackageMessageFlutterApiFlutterMethodResponse* self) { + g_return_val_if_fail( + PIGEON_EXAMPLE_PACKAGE_IS_MESSAGE_FLUTTER_API_FLUTTER_METHOD_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +pigeon_example_package_message_flutter_api_flutter_method_response_get_error_code( + PigeonExamplePackageMessageFlutterApiFlutterMethodResponse* self) { + g_return_val_if_fail( + PIGEON_EXAMPLE_PACKAGE_IS_MESSAGE_FLUTTER_API_FLUTTER_METHOD_RESPONSE( + self), + nullptr); + g_assert( + pigeon_example_package_message_flutter_api_flutter_method_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +pigeon_example_package_message_flutter_api_flutter_method_response_get_error_message( + PigeonExamplePackageMessageFlutterApiFlutterMethodResponse* self) { + g_return_val_if_fail( + PIGEON_EXAMPLE_PACKAGE_IS_MESSAGE_FLUTTER_API_FLUTTER_METHOD_RESPONSE( + self), + nullptr); + g_assert( + pigeon_example_package_message_flutter_api_flutter_method_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +pigeon_example_package_message_flutter_api_flutter_method_response_get_error_details( + PigeonExamplePackageMessageFlutterApiFlutterMethodResponse* self) { + g_return_val_if_fail( + PIGEON_EXAMPLE_PACKAGE_IS_MESSAGE_FLUTTER_API_FLUTTER_METHOD_RESPONSE( + self), + nullptr); + g_assert( + pigeon_example_package_message_flutter_api_flutter_method_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +const gchar* +pigeon_example_package_message_flutter_api_flutter_method_response_get_return_value( + PigeonExamplePackageMessageFlutterApiFlutterMethodResponse* self) { + g_return_val_if_fail( + PIGEON_EXAMPLE_PACKAGE_IS_MESSAGE_FLUTTER_API_FLUTTER_METHOD_RESPONSE( + self), + nullptr); + g_assert( + !pigeon_example_package_message_flutter_api_flutter_method_response_is_error( + self)); + return fl_value_get_string(self->return_value); +} + +static void pigeon_example_package_message_flutter_api_flutter_method_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void pigeon_example_package_message_flutter_api_flutter_method( + PigeonExamplePackageMessageFlutterApi* self, const gchar* a_string, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, a_string != nullptr ? fl_value_new_string(a_string) + : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_example_package.MessageFlutterApi." + "flutterMethod%s", + self->suffix); + g_autoptr(PigeonExamplePackageMessageCodec) codec = + pigeon_example_package_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + pigeon_example_package_message_flutter_api_flutter_method_cb, task); +} + +PigeonExamplePackageMessageFlutterApiFlutterMethodResponse* +pigeon_example_package_message_flutter_api_flutter_method_finish( + PigeonExamplePackageMessageFlutterApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return pigeon_example_package_message_flutter_api_flutter_method_response_new( + response); +} diff --git a/packages/pigeon/example/app/linux/messages.g.h b/packages/pigeon/example/app/linux/messages.g.h new file mode 100644 index 000000000000..0f784ab1a1fc --- /dev/null +++ b/packages/pigeon/example/app/linux/messages.g.h @@ -0,0 +1,349 @@ +// 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, do not edit directly. +// See also: https://pub.dev/packages/pigeon + +#ifndef PIGEON_MESSAGES_G_H_ +#define PIGEON_MESSAGES_G_H_ + +#include + +G_BEGIN_DECLS + +/** + * PigeonExamplePackageCode: + * PIGEON_EXAMPLE_PACKAGE_CODE_ONE: + * PIGEON_EXAMPLE_PACKAGE_CODE_TWO: + * + */ +typedef enum { + PIGEON_EXAMPLE_PACKAGE_CODE_ONE = 0, + PIGEON_EXAMPLE_PACKAGE_CODE_TWO = 1 +} PigeonExamplePackageCode; + +/** + * PigeonExamplePackageMessageData: + * + */ + +G_DECLARE_FINAL_TYPE(PigeonExamplePackageMessageData, + pigeon_example_package_message_data, + PIGEON_EXAMPLE_PACKAGE, MESSAGE_DATA, GObject) + +/** + * pigeon_example_package_message_data_new: + * name: field in this object. + * description: field in this object. + * code: field in this object. + * data: field in this object. + * + * Creates a new #MessageData object. + * + * Returns: a new #PigeonExamplePackageMessageData + */ +PigeonExamplePackageMessageData* pigeon_example_package_message_data_new( + const gchar* name, const gchar* description, PigeonExamplePackageCode code, + FlValue* data); + +/** + * pigeon_example_package_message_data_get_name + * @object: a #PigeonExamplePackageMessageData. + * + * Gets the value of the name field of @object. + * + * Returns: the field value. + */ +const gchar* pigeon_example_package_message_data_get_name( + PigeonExamplePackageMessageData* object); + +/** + * pigeon_example_package_message_data_get_description + * @object: a #PigeonExamplePackageMessageData. + * + * Gets the value of the description field of @object. + * + * Returns: the field value. + */ +const gchar* pigeon_example_package_message_data_get_description( + PigeonExamplePackageMessageData* object); + +/** + * pigeon_example_package_message_data_get_code + * @object: a #PigeonExamplePackageMessageData. + * + * Gets the value of the code field of @object. + * + * Returns: the field value. + */ +PigeonExamplePackageCode pigeon_example_package_message_data_get_code( + PigeonExamplePackageMessageData* object); + +/** + * pigeon_example_package_message_data_get_data + * @object: a #PigeonExamplePackageMessageData. + * + * Gets the value of the data field of @object. + * + * Returns: the field value. + */ +FlValue* pigeon_example_package_message_data_get_data( + PigeonExamplePackageMessageData* object); + +G_DECLARE_FINAL_TYPE(PigeonExamplePackageExampleHostApiResponseHandle, + pigeon_example_package_example_host_api_response_handle, + PIGEON_EXAMPLE_PACKAGE, EXAMPLE_HOST_API_RESPONSE_HANDLE, + GObject) + +G_DECLARE_FINAL_TYPE( + PigeonExamplePackageExampleHostApiGetHostLanguageResponse, + pigeon_example_package_example_host_api_get_host_language_response, + PIGEON_EXAMPLE_PACKAGE, EXAMPLE_HOST_API_GET_HOST_LANGUAGE_RESPONSE, + GObject) + +/** + * pigeon_example_package_example_host_api_get_host_language_response_new: + * + * Creates a new response to ExampleHostApi.getHostLanguage. + * + * Returns: a new #PigeonExamplePackageExampleHostApiGetHostLanguageResponse + */ +PigeonExamplePackageExampleHostApiGetHostLanguageResponse* +pigeon_example_package_example_host_api_get_host_language_response_new( + const gchar* return_value); + +/** + * pigeon_example_package_example_host_api_get_host_language_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to ExampleHostApi.getHostLanguage. + * + * Returns: a new #PigeonExamplePackageExampleHostApiGetHostLanguageResponse + */ +PigeonExamplePackageExampleHostApiGetHostLanguageResponse* +pigeon_example_package_example_host_api_get_host_language_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE(PigeonExamplePackageExampleHostApiAddResponse, + pigeon_example_package_example_host_api_add_response, + PIGEON_EXAMPLE_PACKAGE, EXAMPLE_HOST_API_ADD_RESPONSE, + GObject) + +/** + * pigeon_example_package_example_host_api_add_response_new: + * + * Creates a new response to ExampleHostApi.add. + * + * Returns: a new #PigeonExamplePackageExampleHostApiAddResponse + */ +PigeonExamplePackageExampleHostApiAddResponse* +pigeon_example_package_example_host_api_add_response_new(int64_t return_value); + +/** + * pigeon_example_package_example_host_api_add_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to ExampleHostApi.add. + * + * Returns: a new #PigeonExamplePackageExampleHostApiAddResponse + */ +PigeonExamplePackageExampleHostApiAddResponse* +pigeon_example_package_example_host_api_add_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +/** + * PigeonExamplePackageExampleHostApiVTable: + * + * Table of functions exposed by ExampleHostApi to be implemented by the API + * provider. + */ +typedef struct { + PigeonExamplePackageExampleHostApiGetHostLanguageResponse* ( + *get_host_language)(gpointer user_data); + PigeonExamplePackageExampleHostApiAddResponse* (*add)(int64_t a, int64_t b, + gpointer user_data); + void (*send_message)( + PigeonExamplePackageMessageData* message, + PigeonExamplePackageExampleHostApiResponseHandle* response_handle, + gpointer user_data); +} PigeonExamplePackageExampleHostApiVTable; + +/** + * pigeon_example_package_example_host_api_set_method_handlers: + * + * @messenger: an #FlBinaryMessenger. + * @suffix: (allow-none): a suffix to add to the API or %NULL for none. + * @vtable: implementations of the methods in this API. + * @user_data: (closure): user data to pass to the functions in @vtable. + * @user_data_free_func: (allow-none): a function which gets called to free + * @user_data, or %NULL. + * + * Connects the method handlers in the ExampleHostApi API. + */ +void pigeon_example_package_example_host_api_set_method_handlers( + FlBinaryMessenger* messenger, const gchar* suffix, + const PigeonExamplePackageExampleHostApiVTable* vtable, gpointer user_data, + GDestroyNotify user_data_free_func); + +/** + * pigeon_example_package_example_host_api_clear_method_handlers: + * + * @messenger: an #FlBinaryMessenger. + * @suffix: (allow-none): a suffix to add to the API or %NULL for none. + * + * Clears the method handlers in the ExampleHostApi API. + */ +void pigeon_example_package_example_host_api_clear_method_handlers( + FlBinaryMessenger* messenger, const gchar* suffix); + +/** + * pigeon_example_package_example_host_api_respond_send_message: + * @response_handle: a #PigeonExamplePackageExampleHostApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to ExampleHostApi.sendMessage. + */ +void pigeon_example_package_example_host_api_respond_send_message( + PigeonExamplePackageExampleHostApiResponseHandle* response_handle, + gboolean return_value); + +/** + * pigeon_example_package_example_host_api_respond_error_send_message: + * @response_handle: a #PigeonExamplePackageExampleHostApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to ExampleHostApi.sendMessage. + */ +void pigeon_example_package_example_host_api_respond_error_send_message( + PigeonExamplePackageExampleHostApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + PigeonExamplePackageMessageFlutterApiFlutterMethodResponse, + pigeon_example_package_message_flutter_api_flutter_method_response, + PIGEON_EXAMPLE_PACKAGE, MESSAGE_FLUTTER_API_FLUTTER_METHOD_RESPONSE, + GObject) + +/** + * pigeon_example_package_message_flutter_api_flutter_method_response_is_error: + * @response: a #PigeonExamplePackageMessageFlutterApiFlutterMethodResponse. + * + * Checks if a response to MessageFlutterApi.flutterMethod is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +pigeon_example_package_message_flutter_api_flutter_method_response_is_error( + PigeonExamplePackageMessageFlutterApiFlutterMethodResponse* response); + +/** + * pigeon_example_package_message_flutter_api_flutter_method_response_get_error_code: + * @response: a #PigeonExamplePackageMessageFlutterApiFlutterMethodResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +pigeon_example_package_message_flutter_api_flutter_method_response_get_error_code( + PigeonExamplePackageMessageFlutterApiFlutterMethodResponse* response); + +/** + * pigeon_example_package_message_flutter_api_flutter_method_response_get_error_message: + * @response: a #PigeonExamplePackageMessageFlutterApiFlutterMethodResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +pigeon_example_package_message_flutter_api_flutter_method_response_get_error_message( + PigeonExamplePackageMessageFlutterApiFlutterMethodResponse* response); + +/** + * pigeon_example_package_message_flutter_api_flutter_method_response_get_error_details: + * @response: a #PigeonExamplePackageMessageFlutterApiFlutterMethodResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +pigeon_example_package_message_flutter_api_flutter_method_response_get_error_details( + PigeonExamplePackageMessageFlutterApiFlutterMethodResponse* response); + +/** + * pigeon_example_package_message_flutter_api_flutter_method_response_get_return_value: + * @response: a #PigeonExamplePackageMessageFlutterApiFlutterMethodResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +const gchar* +pigeon_example_package_message_flutter_api_flutter_method_response_get_return_value( + PigeonExamplePackageMessageFlutterApiFlutterMethodResponse* response); + +/** + * PigeonExamplePackageMessageFlutterApi: + * + */ + +G_DECLARE_FINAL_TYPE(PigeonExamplePackageMessageFlutterApi, + pigeon_example_package_message_flutter_api, + PIGEON_EXAMPLE_PACKAGE, MESSAGE_FLUTTER_API, GObject) + +/** + * pigeon_example_package_message_flutter_api_new: + * @messenger: an #FlBinaryMessenger. + * @suffix: (allow-none): a suffix to add to the API or %NULL for none. + * + * Creates a new object to access the MessageFlutterApi API. + * + * Returns: a new #PigeonExamplePackageMessageFlutterApi + */ +PigeonExamplePackageMessageFlutterApi* +pigeon_example_package_message_flutter_api_new(FlBinaryMessenger* messenger, + const gchar* suffix); + +/** + * pigeon_example_package_message_flutter_api_flutter_method: + * @api: a #PigeonExamplePackageMessageFlutterApi. + * @a_string: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + */ +void pigeon_example_package_message_flutter_api_flutter_method( + PigeonExamplePackageMessageFlutterApi* api, const gchar* a_string, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * pigeon_example_package_message_flutter_api_flutter_method_finish: + * @api: a #PigeonExamplePackageMessageFlutterApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a pigeon_example_package_message_flutter_api_flutter_method() call. + * + * Returns: a #PigeonExamplePackageMessageFlutterApiFlutterMethodResponse or + * %NULL on error. + */ +PigeonExamplePackageMessageFlutterApiFlutterMethodResponse* +pigeon_example_package_message_flutter_api_flutter_method_finish( + PigeonExamplePackageMessageFlutterApi* api, GAsyncResult* result, + GError** error); + +G_END_DECLS + +#endif // PIGEON_MESSAGES_G_H_ diff --git a/packages/pigeon/example/app/linux/my_application.cc b/packages/pigeon/example/app/linux/my_application.cc new file mode 100644 index 000000000000..812b96a8ceec --- /dev/null +++ b/packages/pigeon/example/app/linux/my_application.cc @@ -0,0 +1,187 @@ +// 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. + +#include "my_application.h" + +#include +#ifdef GDK_WINDOWING_X11 +#include +#endif + +#include "flutter/generated_plugin_registrant.h" +#include "messages.g.h" + +struct _MyApplication { + GtkApplication parent_instance; + char** dart_entrypoint_arguments; + + PigeonExamplePackageMessageFlutterApi* flutter_api; +}; + +G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) + +// #docregion vtable +static PigeonExamplePackageExampleHostApiGetHostLanguageResponse* +handle_get_host_language(gpointer user_data) { + return pigeon_example_package_example_host_api_get_host_language_response_new( + "C++"); +} + +static PigeonExamplePackageExampleHostApiAddResponse* handle_add( + int64_t a, int64_t b, gpointer user_data) { + if (a < 0 || b < 0) { + g_autoptr(FlValue) details = fl_value_new_string("details"); + return pigeon_example_package_example_host_api_add_response_new_error( + "code", "message", details); + } + + return pigeon_example_package_example_host_api_add_response_new(a + b); +} + +static void handle_send_message( + PigeonExamplePackageMessageData* message, + PigeonExamplePackageExampleHostApiResponseHandle* response_handle, + gpointer user_data) { + PigeonExamplePackageCode code = + pigeon_example_package_message_data_get_code(message); + if (code == PIGEON_EXAMPLE_PACKAGE_CODE_ONE) { + g_autoptr(FlValue) details = fl_value_new_string("details"); + pigeon_example_package_example_host_api_respond_error_send_message( + response_handle, "code", "message", details); + return; + } + + pigeon_example_package_example_host_api_respond_send_message(response_handle, + TRUE); +} + +static PigeonExamplePackageExampleHostApiVTable example_host_api_vtable = { + .get_host_language = handle_get_host_language, + .add = handle_add, + .send_message = handle_send_message}; +// #enddocregion vtable + +// #docregion flutter-method-callback +static void flutter_method_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(GError) error = nullptr; + g_autoptr( + PigeonExamplePackageMessageFlutterApiFlutterMethodResponse) response = + pigeon_example_package_message_flutter_api_flutter_method_finish( + PIGEON_EXAMPLE_PACKAGE_MESSAGE_FLUTTER_API(object), result, &error); + if (response == nullptr) { + g_warning("Failed to call Flutter method: %s", error->message); + return; + } + + g_printerr( + "Got result from Flutter method: %s\n", + pigeon_example_package_message_flutter_api_flutter_method_response_get_return_value( + response)); +} +// #enddocregion flutter-method-callback + +// Implements GApplication::activate. +static void my_application_activate(GApplication* application) { + MyApplication* self = MY_APPLICATION(application); + GtkWindow* window = + GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); + + // Use a header bar when running in GNOME as this is the common style used + // by applications and is the setup most users will be using (e.g. Ubuntu + // desktop). + // If running on X and not using GNOME then just use a traditional title bar + // in case the window manager does more exotic layout, e.g. tiling. + // If running on Wayland assume the header bar will work (may need changing + // if future cases occur). + gboolean use_header_bar = TRUE; +#ifdef GDK_WINDOWING_X11 + GdkScreen* screen = gtk_window_get_screen(window); + if (GDK_IS_X11_SCREEN(screen)) { + const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); + if (g_strcmp0(wm_name, "GNOME Shell") != 0) { + use_header_bar = FALSE; + } + } +#endif + if (use_header_bar) { + GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); + gtk_widget_show(GTK_WIDGET(header_bar)); + gtk_header_bar_set_title(header_bar, "pigeon_example_app"); + gtk_header_bar_set_show_close_button(header_bar, TRUE); + gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); + } else { + gtk_window_set_title(window, "pigeon_example_app"); + } + + gtk_window_set_default_size(window, 1280, 720); + gtk_widget_show(GTK_WIDGET(window)); + + g_autoptr(FlDartProject) project = fl_dart_project_new(); + fl_dart_project_set_dart_entrypoint_arguments( + project, self->dart_entrypoint_arguments); + + FlView* view = fl_view_new(project); + gtk_widget_show(GTK_WIDGET(view)); + gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); + + FlBinaryMessenger* messenger = + fl_engine_get_binary_messenger(fl_view_get_engine(view)); + pigeon_example_package_example_host_api_set_method_handlers( + messenger, nullptr, &example_host_api_vtable, self, nullptr); + + fl_register_plugins(FL_PLUGIN_REGISTRY(view)); + + gtk_widget_grab_focus(GTK_WIDGET(view)); + + // #docregion flutter-method + self->flutter_api = + pigeon_example_package_message_flutter_api_new(messenger, nullptr); + pigeon_example_package_message_flutter_api_flutter_method( + self->flutter_api, "hello", nullptr, flutter_method_cb, self); + // #enddocregion flutter-method +} + +// Implements GApplication::local_command_line. +static gboolean my_application_local_command_line(GApplication* application, + gchar*** arguments, + int* exit_status) { + MyApplication* self = MY_APPLICATION(application); + // Strip out the first argument as it is the binary name. + self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); + + g_autoptr(GError) error = nullptr; + if (!g_application_register(application, nullptr, &error)) { + g_warning("Failed to register: %s", error->message); + *exit_status = 1; + return TRUE; + } + + g_application_activate(application); + *exit_status = 0; + + return TRUE; +} + +// Implements GObject::dispose. +static void my_application_dispose(GObject* object) { + MyApplication* self = MY_APPLICATION(object); + g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); + G_OBJECT_CLASS(my_application_parent_class)->dispose(object); +} + +static void my_application_class_init(MyApplicationClass* klass) { + G_APPLICATION_CLASS(klass)->activate = my_application_activate; + G_APPLICATION_CLASS(klass)->local_command_line = + my_application_local_command_line; + G_OBJECT_CLASS(klass)->dispose = my_application_dispose; +} + +static void my_application_init(MyApplication* self) {} + +MyApplication* my_application_new() { + return MY_APPLICATION(g_object_new(my_application_get_type(), + "application-id", APPLICATION_ID, "flags", + G_APPLICATION_NON_UNIQUE, nullptr)); +} diff --git a/packages/pigeon/example/app/linux/my_application.h b/packages/pigeon/example/app/linux/my_application.h new file mode 100644 index 000000000000..6e9f0c3ff665 --- /dev/null +++ b/packages/pigeon/example/app/linux/my_application.h @@ -0,0 +1,22 @@ +// 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. + +#ifndef FLUTTER_MY_APPLICATION_H_ +#define FLUTTER_MY_APPLICATION_H_ + +#include + +G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, + GtkApplication) + +/** + * my_application_new: + * + * Creates a new Flutter-based application. + * + * Returns: a new #MyApplication. + */ +MyApplication* my_application_new(); + +#endif // FLUTTER_MY_APPLICATION_H_ diff --git a/packages/pigeon/example/app/macos/Podfile b/packages/pigeon/example/app/macos/Podfile index 049abe295427..ae77cc1d4269 100644 --- a/packages/pigeon/example/app/macos/Podfile +++ b/packages/pigeon/example/app/macos/Podfile @@ -28,7 +28,6 @@ flutter_macos_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) end diff --git a/packages/pigeon/example/app/macos/Runner/messages.g.m b/packages/pigeon/example/app/macos/Runner/messages.g.m index 1471345b8801..cdf19a2849ba 100644 --- a/packages/pigeon/example/app/macos/Runner/messages.g.m +++ b/packages/pigeon/example/app/macos/Runner/messages.g.m @@ -71,8 +71,8 @@ + (PGNMessageData *)fromList:(NSArray *)list { PGNMessageData *pigeonResult = [[PGNMessageData alloc] init]; pigeonResult.name = GetNullableObjectAtIndex(list, 0); pigeonResult.description = GetNullableObjectAtIndex(list, 1); - PGNCodeBox *enumBox = GetNullableObjectAtIndex(list, 2); - pigeonResult.code = enumBox.value; + PGNCodeBox *boxedPGNCode = GetNullableObjectAtIndex(list, 2); + pigeonResult.code = boxedPGNCode.value; pigeonResult.data = GetNullableObjectAtIndex(list, 3); return pigeonResult; } @@ -94,13 +94,13 @@ @interface PGNMessagesPigeonCodecReader : FlutterStandardReader @implementation PGNMessagesPigeonCodecReader - (nullable id)readValueOfType:(UInt8)type { switch (type) { - case 129: - return [PGNMessageData fromList:[self readValue]]; - case 130: { + case 129: { NSNumber *enumAsNumber = [self readValue]; return enumAsNumber == nil ? nil : [[PGNCodeBox alloc] initWithValue:[enumAsNumber integerValue]]; } + case 130: + return [PGNMessageData fromList:[self readValue]]; default: return [super readValueOfType:type]; } @@ -111,13 +111,13 @@ @interface PGNMessagesPigeonCodecWriter : FlutterStandardWriter @end @implementation PGNMessagesPigeonCodecWriter - (void)writeValue:(id)value { - if ([value isKindOfClass:[PGNMessageData class]]) { - [self writeByte:129]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[PGNCodeBox class]]) { + if ([value isKindOfClass:[PGNCodeBox class]]) { PGNCodeBox *box = (PGNCodeBox *)value; - [self writeByte:130]; + [self writeByte:129]; [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; + } else if ([value isKindOfClass:[PGNMessageData class]]) { + [self writeByte:130]; + [self writeValue:[value toList]]; } else { [super writeValue:value]; } diff --git a/packages/pigeon/example/app/pigeons/messages.dart b/packages/pigeon/example/app/pigeons/messages.dart index da66c0e8553d..2112fed96371 100644 --- a/packages/pigeon/example/app/pigeons/messages.dart +++ b/packages/pigeon/example/app/pigeons/messages.dart @@ -11,6 +11,9 @@ import 'package:pigeon/pigeon.dart'; cppOptions: CppOptions(namespace: 'pigeon_example'), cppHeaderOut: 'windows/runner/messages.g.h', cppSourceOut: 'windows/runner/messages.g.cpp', + gobjectHeaderOut: 'linux/messages.g.h', + gobjectSourceOut: 'linux/messages.g.cc', + gobjectOptions: GObjectOptions(), kotlinOut: 'android/app/src/main/kotlin/dev/flutter/pigeon_example_app/Messages.g.kt', kotlinOptions: KotlinOptions(), @@ -37,7 +40,7 @@ class MessageData { String? name; String? description; Code code; - Map data; + Map data; } @HostApi() diff --git a/packages/pigeon/example/app/pubspec.yaml b/packages/pigeon/example/app/pubspec.yaml index e0cb64f60a74..ab11f4fa8293 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.2.0 + sdk: ^3.3.0 dependencies: flutter: diff --git a/packages/pigeon/example/app/windows/runner/flutter_window.cpp b/packages/pigeon/example/app/windows/runner/flutter_window.cpp index d4f0fec67470..b7f7ab03595b 100644 --- a/packages/pigeon/example/app/windows/runner/flutter_window.cpp +++ b/packages/pigeon/example/app/windows/runner/flutter_window.cpp @@ -29,7 +29,7 @@ class PigeonApiImplementation : public ExampleHostApi { } void SendMessage(const MessageData& message, std::function reply)> result) { - if (message.code == Code.one) { + if (message.code == Code.kOne) { result(FlutterError("code", "message", "details")); return; } diff --git a/packages/pigeon/example/app/windows/runner/messages.g.cpp b/packages/pigeon/example/app/windows/runner/messages.g.cpp index 7a43ec397a3a..f1643f87edc5 100644 --- a/packages/pigeon/example/app/windows/runner/messages.g.cpp +++ b/packages/pigeon/example/app/windows/runner/messages.g.cpp @@ -102,15 +102,12 @@ MessageData MessageData::FromEncodableList(const EncodableList& list) { return decoded; } -PigeonCodecSerializer::PigeonCodecSerializer() {} +PigeonInternalCodecSerializer::PigeonInternalCodecSerializer() {} -EncodableValue PigeonCodecSerializer::ReadValueOfType( +EncodableValue PigeonInternalCodecSerializer::ReadValueOfType( uint8_t type, flutter::ByteStreamReader* stream) const { switch (type) { - case 129: - return CustomEncodableValue(MessageData::FromEncodableList( - std::get(ReadValue(stream)))); - case 130: { + case 129: { const auto& encodable_enum_arg = ReadValue(stream); const int64_t enum_arg_value = encodable_enum_arg.IsNull() ? 0 : encodable_enum_arg.LongValue(); @@ -118,27 +115,31 @@ EncodableValue PigeonCodecSerializer::ReadValueOfType( ? EncodableValue() : CustomEncodableValue(static_cast(enum_arg_value)); } + case 130: { + return CustomEncodableValue(MessageData::FromEncodableList( + std::get(ReadValue(stream)))); + } default: return flutter::StandardCodecSerializer::ReadValueOfType(type, stream); } } -void PigeonCodecSerializer::WriteValue( +void PigeonInternalCodecSerializer::WriteValue( const EncodableValue& value, flutter::ByteStreamWriter* stream) const { if (const CustomEncodableValue* custom_value = std::get_if(&value)) { - if (custom_value->type() == typeid(MessageData)) { + if (custom_value->type() == typeid(Code)) { stream->WriteByte(129); WriteValue( - EncodableValue( - std::any_cast(*custom_value).ToEncodableList()), + EncodableValue(static_cast(std::any_cast(*custom_value))), stream); return; } - if (custom_value->type() == typeid(Code)) { + if (custom_value->type() == typeid(MessageData)) { stream->WriteByte(130); WriteValue( - EncodableValue(static_cast(std::any_cast(*custom_value))), + EncodableValue( + std::any_cast(*custom_value).ToEncodableList()), stream); return; } @@ -149,7 +150,7 @@ void PigeonCodecSerializer::WriteValue( /// The codec used by ExampleHostApi. const flutter::StandardMessageCodec& ExampleHostApi::GetCodec() { return flutter::StandardMessageCodec::GetInstance( - &PigeonCodecSerializer::GetInstance()); + &PigeonInternalCodecSerializer::GetInstance()); } // Sets up an instance of `ExampleHostApi` to handle messages through the @@ -298,7 +299,7 @@ MessageFlutterApi::MessageFlutterApi(flutter::BinaryMessenger* binary_messenger, const flutter::StandardMessageCodec& MessageFlutterApi::GetCodec() { return flutter::StandardMessageCodec::GetInstance( - &PigeonCodecSerializer::GetInstance()); + &PigeonInternalCodecSerializer::GetInstance()); } void MessageFlutterApi::FlutterMethod( diff --git a/packages/pigeon/example/app/windows/runner/messages.g.h b/packages/pigeon/example/app/windows/runner/messages.g.h index 84368cbb1dfc..7e0e261eb0cd 100644 --- a/packages/pigeon/example/app/windows/runner/messages.g.h +++ b/packages/pigeon/example/app/windows/runner/messages.g.h @@ -59,7 +59,7 @@ class ErrorOr { std::variant v_; }; -enum class Code { one = 0, two = 1 }; +enum class Code { kOne = 0, kTwo = 1 }; // Generated class from Pigeon that represents data sent in messages. class MessageData { @@ -90,18 +90,18 @@ class MessageData { flutter::EncodableList ToEncodableList() const; friend class ExampleHostApi; friend class MessageFlutterApi; - friend class PigeonCodecSerializer; + friend class PigeonInternalCodecSerializer; std::optional name_; std::optional description_; Code code_; flutter::EncodableMap data_; }; -class PigeonCodecSerializer : public flutter::StandardCodecSerializer { +class PigeonInternalCodecSerializer : public flutter::StandardCodecSerializer { public: - PigeonCodecSerializer(); - inline static PigeonCodecSerializer& GetInstance() { - static PigeonCodecSerializer sInstance; + PigeonInternalCodecSerializer(); + inline static PigeonInternalCodecSerializer& GetInstance() { + static PigeonInternalCodecSerializer sInstance; return sInstance; } diff --git a/packages/pigeon/example/pubspec.yaml b/packages/pigeon/example/pubspec.yaml index 63663a48ec28..4356a3636b1c 100644 --- a/packages/pigeon/example/pubspec.yaml +++ b/packages/pigeon/example/pubspec.yaml @@ -3,7 +3,7 @@ description: example app to show basic usage of pigeon. publish_to: none environment: - sdk: ^3.2.0 + sdk: ^3.3.0 dependencies: diff --git a/packages/pigeon/lib/ast.dart b/packages/pigeon/lib/ast.dart index b3469b03295f..1c93d4630e30 100644 --- a/packages/pigeon/lib/ast.dart +++ b/packages/pigeon/lib/ast.dart @@ -4,7 +4,11 @@ import 'package:collection/collection.dart' show ListEquality; import 'package:meta/meta.dart'; + +import 'generator_tools.dart'; +import 'kotlin_generator.dart' show KotlinProxyApiOptions; import 'pigeon_lib.dart'; +import 'swift_generator.dart' show SwiftProxyApiOptions; typedef _ListEquals = bool Function(List, List); @@ -139,6 +143,8 @@ class AstProxyApi extends Api { required this.fields, this.superClass, this.interfaces = const {}, + this.swiftOptions, + this.kotlinOptions, }); /// List of constructors inside the API. @@ -153,6 +159,14 @@ class AstProxyApi extends Api { /// Name of the classes this class considers to be implemented. Set interfaces; + /// Options that control how Swift code will be generated for a specific + /// ProxyApi. + final SwiftProxyApiOptions? swiftOptions; + + /// Options that control how Kotlin code will be generated for a specific + /// ProxyApi. + final KotlinProxyApiOptions? kotlinOptions; + /// Methods implemented in the host platform language. Iterable get hostMethods => methods.where( (Method method) => method.location == ApiLocation.host, @@ -252,7 +266,7 @@ class AstProxyApi extends Api { } } - /// Whether the api has a method that callbacks to Dart to add a new instance + /// Whether the API has a method that callbacks to Dart to add a new instance /// to the InstanceManager. /// /// This is possible as long as no callback methods are required to @@ -264,6 +278,21 @@ class AstProxyApi extends Api { .every((Method method) => !method.isRequired); } + /// Whether the API has any message calls from Dart to host. + bool hasAnyHostMessageCalls() => + constructors.isNotEmpty || + attachedFields.isNotEmpty || + hostMethods.isNotEmpty; + + /// Whether the API has any message calls from host to Dart. + bool hasAnyFlutterMessageCalls() => + hasCallbackConstructor() || flutterMethods.isNotEmpty; + + /// Whether the host proxy API class will have methods that need to be + /// implemented. + bool hasMethodsRequiringImplementation() => + hasAnyHostMessageCalls() || unattachedFields.isNotEmpty; + // Recursively search for all the interfaces apis from a list of names of // interfaces. // @@ -651,6 +680,7 @@ class Class extends Node { Class({ required this.name, required this.fields, + this.isReferenced = true, this.isSwiftClass = false, this.documentationComments = const [], }); @@ -661,6 +691,9 @@ class Class extends Node { /// All the fields contained in the class. List fields; + /// Whether the class is referenced in any API. + bool isReferenced; + /// Determines whether the defined class should be represented as a struct or /// a class in Swift generation. /// @@ -755,6 +788,11 @@ class Root extends Node { /// All of the enums contained in the AST. List enums; + /// Returns true if the number of custom types would exceed the available enumerations + /// on the standard codec. + bool get requiresOverflowClass => + classes.length + enums.length >= totalCustomCodecKeysAllowed; + @override String toString() { return '(Root classes:$classes apis:$apis enums:$enums)'; diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 47dd2b3276bd..96579cc23f9a 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -21,7 +21,25 @@ const DocumentCommentSpecification _docCommentSpec = const String _standardCodecSerializer = 'flutter::StandardCodecSerializer'; /// The name of the codec serializer. -const String _codecSerializerName = 'PigeonCodecSerializer'; +const String _codecSerializerName = '${classNamePrefix}CodecSerializer'; + +const String _overflowClassName = '${classNamePrefix}CodecOverflow'; + +final NamedType _overflowType = NamedType( + name: 'type', + type: const TypeDeclaration(baseName: 'int', isNullable: false)); +final NamedType _overflowObject = NamedType( + name: 'wrapped', + type: const TypeDeclaration(baseName: 'Object', isNullable: false)); +final List _overflowFields = [ + _overflowType, + _overflowObject, +]; +final Class _overflowClass = + Class(name: _overflowClassName, fields: _overflowFields); +final EnumeratedType _enumeratedOverflow = EnumeratedType( + _overflowClassName, maximumCodecFieldKey, CustomTypes.customClass, + associatedClass: _overflowClass); /// Options that control how C++ code will be generated. class CppOptions { @@ -181,8 +199,9 @@ class CppHeaderGenerator extends StructuredGenerator { enumerate(anEnum.members, (int index, final EnumMember member) { addDocumentationComments( indent, member.documentationComments, _docCommentSpec); + final String valueName = 'k${_pascalCaseFromCamelCase(member.name)}'; indent.writeln( - '${member.name} = $index${index == anEnum.members.length - 1 ? '' : ','}'); + '$valueName = $index${index == anEnum.members.length - 1 ? '' : ','}'); }); }); } @@ -215,6 +234,32 @@ class CppHeaderGenerator extends StructuredGenerator { } } + @override + void writeDataClasses( + CppOptions generatorOptions, + Root root, + Indent indent, { + required String dartPackageName, + }) { + indent.newln(); + super.writeDataClasses( + generatorOptions, + root, + indent, + dartPackageName: dartPackageName, + ); + if (root.requiresOverflowClass) { + writeDataClass( + generatorOptions, + root, + indent, + _overflowClass, + dartPackageName: dartPackageName, + isOverflowClass: true, + ); + } + } + @override void writeDataClass( CppOptions generatorOptions, @@ -222,6 +267,7 @@ class CppHeaderGenerator extends StructuredGenerator { Indent indent, Class classDefinition, { required String dartPackageName, + bool isOverflowClass = false, }) { // When generating for a Pigeon unit test, add a test fixture friend class to // allow unit testing private methods, since testing serialization via public @@ -318,11 +364,20 @@ class CppHeaderGenerator extends StructuredGenerator { _writeAccessBlock(indent, _ClassAccess.private, () { _writeFunctionDeclaration(indent, 'FromEncodableList', - returnType: classDefinition.name, + returnType: isOverflowClass + ? 'flutter::EncodableValue' + : classDefinition.name, parameters: ['const flutter::EncodableList& list'], isStatic: true); _writeFunctionDeclaration(indent, 'ToEncodableList', returnType: 'flutter::EncodableList', isConst: true); + if (isOverflowClass) { + _writeFunctionDeclaration(indent, 'Unwrap', + returnType: 'flutter::EncodableValue'); + } + if (!isOverflowClass && root.requiresOverflowClass) { + indent.writeln('friend class $_overflowClassName;'); + } for (final Class friend in root.classes) { if (friend != classDefinition && friend.fields.any((NamedType element) => @@ -359,6 +414,7 @@ class CppHeaderGenerator extends StructuredGenerator { Indent indent, { required String dartPackageName, }) { + indent.newln(); indent.write( 'class $_codecSerializerName : public $_standardCodecSerializer '); indent.addScoped('{', '};', () { @@ -811,9 +867,7 @@ class CppSourceGenerator extends StructuredGenerator { // Returns the expression to convert the given EncodableValue to a field // value. String getValueExpression(NamedType field, String encodable) { - if (field.type.baseName == 'int') { - return '$encodable.LongValue()'; - } else if (field.type.baseName == 'Object') { + if (field.type.baseName == 'Object') { return encodable; } else { final HostDatatype hostDatatype = @@ -874,6 +928,72 @@ class CppSourceGenerator extends StructuredGenerator { }); } + void _writeCodecOverflowUtilities( + CppOptions generatorOptions, + Root root, + Indent indent, + List types, { + required String dartPackageName, + }) { + _writeClassConstructor(root, indent, _overflowClass, _overflowFields); + // Getters and setters. + for (final NamedType field in _overflowFields) { + _writeCppSourceClassField( + generatorOptions, root, indent, _overflowClass, field); + } + // Serialization. + writeClassEncode( + generatorOptions, + root, + indent, + _overflowClass, + dartPackageName: dartPackageName, + ); + + indent.format(''' +EncodableValue $_overflowClassName::FromEncodableList( + const EncodableList& list) { + return $_overflowClassName(list[0].LongValue(), + list[1].IsNull() ? EncodableValue() : list[1]) + .Unwrap(); +}'''); + + indent.writeScoped('EncodableValue $_overflowClassName::Unwrap() {', '}', + () { + indent.writeScoped('if (wrapped_.IsNull()) {', '}', () { + indent.writeln('return EncodableValue();'); + }); + indent.writeScoped('switch(type_) {', '}', () { + for (int i = totalCustomCodecKeysAllowed; i < types.length; i++) { + indent.write('case ${types[i].enumeration - maximumCodecFieldKey}: '); + _writeCodecDecode(indent, types[i], 'wrapped_'); + } + }); + indent.writeln('return EncodableValue();'); + }); + } + + void _writeCodecDecode( + Indent indent, EnumeratedType customType, String value) { + indent.addScoped('{', '}', () { + if (customType.type == CustomTypes.customClass) { + if (customType.name == _overflowClassName) { + indent.writeln( + 'return ${customType.name}::FromEncodableList(std::get($value));'); + } else { + indent.writeln( + 'return CustomEncodableValue(${customType.name}::FromEncodableList(std::get($value)));'); + } + } else if (customType.type == CustomTypes.customEnum) { + indent.writeln('const auto& encodable_enum_arg = $value;'); + indent.writeln( + 'const int64_t enum_arg_value = encodable_enum_arg.IsNull() ? 0 : encodable_enum_arg.LongValue();'); + indent.writeln( + 'return encodable_enum_arg.IsNull() ? EncodableValue() : CustomEncodableValue(static_cast<${customType.name}>(enum_arg_value));'); + } + }); + } + @override void writeGeneralCodec( CppOptions generatorOptions, @@ -881,8 +1001,14 @@ class CppSourceGenerator extends StructuredGenerator { Indent indent, { required String dartPackageName, }) { - final Iterable customTypes = getEnumeratedTypes(root); + final List enumeratedTypes = + getEnumeratedTypes(root).toList(); indent.newln(); + if (root.requiresOverflowClass) { + _writeCodecOverflowUtilities( + generatorOptions, root, indent, enumeratedTypes, + dartPackageName: dartPackageName); + } _writeFunctionDefinition(indent, _codecSerializerName, scope: _codecSerializerName); _writeFunctionDefinition(indent, 'ReadValueOfType', @@ -893,33 +1019,27 @@ class CppSourceGenerator extends StructuredGenerator { 'flutter::ByteStreamReader* stream', ], isConst: true, body: () { - if (customTypes.isNotEmpty) { + if (enumeratedTypes.isNotEmpty) { indent.writeln('switch (type) {'); indent.inc(); - for (final EnumeratedType customType in customTypes) { - indent.writeln('case ${customType.enumeration}:'); - indent.nest(1, () { - if (customType.type == CustomTypes.customClass) { - indent.writeln( - 'return CustomEncodableValue(${customType.name}::FromEncodableList(std::get(ReadValue(stream))));'); - } else if (customType.type == CustomTypes.customEnum) { - indent.writeScoped('{', '}', () { - indent.writeln( - 'const auto& encodable_enum_arg = ReadValue(stream);'); - indent.writeln( - 'const int64_t enum_arg_value = encodable_enum_arg.IsNull() ? 0 : encodable_enum_arg.LongValue();'); - indent.writeln( - 'return encodable_enum_arg.IsNull() ? EncodableValue() : CustomEncodableValue(static_cast<${customType.name}>(enum_arg_value));'); - }); - } - }); + for (final EnumeratedType customType in enumeratedTypes) { + if (customType.enumeration < maximumCodecFieldKey) { + indent.write('case ${customType.enumeration}: '); + indent.nest(1, () { + _writeCodecDecode(indent, customType, 'ReadValue(stream)'); + }); + } + } + if (root.requiresOverflowClass) { + indent.write('case $maximumCodecFieldKey:'); + _writeCodecDecode(indent, _enumeratedOverflow, 'ReadValue(stream)'); } indent.writeln('default:'); indent.inc(); } indent.writeln( 'return $_standardCodecSerializer::ReadValueOfType(type, stream);'); - if (customTypes.isNotEmpty) { + if (enumeratedTypes.isNotEmpty) { indent.dec(); indent.writeln('}'); indent.dec(); @@ -933,22 +1053,33 @@ class CppSourceGenerator extends StructuredGenerator { 'flutter::ByteStreamWriter* stream', ], isConst: true, body: () { - if (customTypes.isNotEmpty) { + if (enumeratedTypes.isNotEmpty) { indent.write( 'if (const CustomEncodableValue* custom_value = std::get_if(&value)) '); indent.addScoped('{', '}', () { - for (final EnumeratedType customType in customTypes) { + for (final EnumeratedType customType in enumeratedTypes) { + final String encodeString = customType.type == + CustomTypes.customClass + ? 'std::any_cast<${customType.name}>(*custom_value).ToEncodableList()' + : 'static_cast(std::any_cast<${customType.name}>(*custom_value))'; + final String valueString = + customType.enumeration < maximumCodecFieldKey + ? encodeString + : 'wrap.ToEncodableList()'; + final int enumeration = + customType.enumeration < maximumCodecFieldKey + ? customType.enumeration + : maximumCodecFieldKey; indent.write( 'if (custom_value->type() == typeid(${customType.name})) '); indent.addScoped('{', '}', () { - indent.writeln('stream->WriteByte(${customType.enumeration});'); - if (customType.type == CustomTypes.customClass) { - indent.writeln( - 'WriteValue(EncodableValue(std::any_cast<${customType.name}>(*custom_value).ToEncodableList()), stream);'); - } else if (customType.type == CustomTypes.customEnum) { + indent.writeln('stream->WriteByte($enumeration);'); + if (enumeration == maximumCodecFieldKey) { indent.writeln( - 'WriteValue(EncodableValue(static_cast(std::any_cast<${customType.name}>(*custom_value))), stream);'); + 'const auto wrap = $_overflowClassName(${customType.enumeration - maximumCodecFieldKey}, $encodeString);'); } + indent + .writeln('WriteValue(EncodableValue($valueString), stream);'); indent.writeln('return;'); }); } @@ -1503,17 +1634,7 @@ ${prefix}reply(EncodableValue(std::move(wrapped)));'''; if (hostType.isNullable) { // Nullable arguments are always pointers, with nullptr corresponding to // null. - if (hostType.datatype == 'int64_t') { - // The EncodableValue will either be an int32_t or an int64_t depending - // on the value, but the generated API requires an int64_t so that it can - // handle any case. Create a local variable for the 64-bit value... - final String valueVarName = '${argName}_value'; - indent.writeln( - 'const int64_t $valueVarName = $encodableArgName.IsNull() ? 0 : $encodableArgName.LongValue();'); - // ... then declare the arg as a reference to that local. - indent.writeln( - 'const auto* $argName = $encodableArgName.IsNull() ? nullptr : &$valueVarName;'); - } else if (hostType.datatype == 'EncodableValue') { + if (hostType.datatype == 'EncodableValue') { // Generic objects just pass the EncodableValue through directly. indent.writeln('const auto* $argName = &$encodableArgName;'); } else if (hostType.isBuiltin) { diff --git a/packages/pigeon/lib/dart/templates.dart b/packages/pigeon/lib/dart/templates.dart index 48c5859dc3d5..c78c4f566d22 100644 --- a/packages/pigeon/lib/dart/templates.dart +++ b/packages/pigeon/lib/dart/templates.dart @@ -4,6 +4,20 @@ import '../generator_tools.dart'; +/// Name for the generated InstanceManager for ProxyApis. +/// +/// This lowers the chances of variable name collisions with user defined +/// parameters. +const String dartInstanceManagerClassName = + '${proxyApiClassNamePrefix}InstanceManager'; + +/// Name for the generated InstanceManager API for ProxyApis. +/// +/// This lowers the chances of variable name collisions with user defined +/// parameters. +const String dartInstanceManagerApiClassName = + '_${classNamePrefix}InstanceManagerApi'; + /// Creates the `InstanceManager` with the passed string values. String instanceManagerTemplate({ required Iterable allProxyApiNames, @@ -30,9 +44,9 @@ String instanceManagerTemplate({ /// is added as a weak reference with the same identifier. This prevents a /// scenario where the weak referenced instance was released and then later /// returned by the host platform. -class $instanceManagerClassName { - /// Constructs a [$instanceManagerClassName]. - $instanceManagerClassName({required void Function(int) onWeakReferenceRemoved}) { +class $dartInstanceManagerClassName { + /// Constructs a [$dartInstanceManagerClassName]. + $dartInstanceManagerClassName({required void Function(int) onWeakReferenceRemoved}) { this.onWeakReferenceRemoved = (int identifier) { _weakInstances.remove(identifier); onWeakReferenceRemoved(identifier); @@ -46,12 +60,12 @@ class $instanceManagerClassName { // 0 <= n < 2^16. static const int _maxDartCreatedIdentifier = 65536; - /// The default [$instanceManagerClassName] used by ProxyApis. + /// The default [$dartInstanceManagerClassName] used by ProxyApis. /// /// On creation, this manager makes a call to clear the native /// InstanceManager. This is to prevent identifier conflicts after a host /// restart. - static final $instanceManagerClassName instance = _initInstance(); + static final $dartInstanceManagerClassName instance = _initInstance(); // Expando is used because it doesn't prevent its keys from becoming // inaccessible. This allows the manager to efficiently retrieve an identifier @@ -72,17 +86,17 @@ class $instanceManagerClassName { /// or becomes inaccessible. late final void Function(int) onWeakReferenceRemoved; - static $instanceManagerClassName _initInstance() { + static $dartInstanceManagerClassName _initInstance() { WidgetsFlutterBinding.ensureInitialized(); - final _${instanceManagerClassName}Api api = _${instanceManagerClassName}Api(); - // Clears the native `$instanceManagerClassName` on the initial use of the Dart one. + final $dartInstanceManagerApiClassName api = $dartInstanceManagerApiClassName(); + // Clears the native `$dartInstanceManagerClassName` on the initial use of the Dart one. api.clear(); - final $instanceManagerClassName instanceManager = $instanceManagerClassName( + final $dartInstanceManagerClassName instanceManager = $dartInstanceManagerClassName( onWeakReferenceRemoved: (int identifier) { api.removeStrongReference(identifier); }, ); - _${instanceManagerClassName}Api.setUpMessageHandlers(instanceManager: instanceManager); + $dartInstanceManagerApiClassName.setUpMessageHandlers(instanceManager: instanceManager); ${apiHandlerSetUps.join('\n\t\t')} return instanceManager; } @@ -229,9 +243,9 @@ abstract class $proxyApiBaseClassName { /// Construct a [$proxyApiBaseClassName]. $proxyApiBaseClassName({ this.$_proxyApiBaseClassMessengerVarName, - $instanceManagerClassName? $_proxyApiBaseClassInstanceManagerVarName, + $dartInstanceManagerClassName? $_proxyApiBaseClassInstanceManagerVarName, }) : $_proxyApiBaseClassInstanceManagerVarName = - $_proxyApiBaseClassInstanceManagerVarName ?? $instanceManagerClassName.instance; + $_proxyApiBaseClassInstanceManagerVarName ?? $dartInstanceManagerClassName.instance; /// Sends and receives binary data across the Flutter platform barrier. /// @@ -242,12 +256,12 @@ abstract class $proxyApiBaseClassName { /// Maintains instances stored to communicate with native language objects. @protected - final $instanceManagerClassName $_proxyApiBaseClassInstanceManagerVarName; + final $dartInstanceManagerClassName $_proxyApiBaseClassInstanceManagerVarName; /// Instantiates and returns a functionally identical object to oneself. /// /// Outside of tests, this method should only ever be called by - /// [$instanceManagerClassName]. + /// [$dartInstanceManagerClassName]. /// /// Subclasses should always override their parent's implementation of this /// method. @@ -264,11 +278,11 @@ abstract class $proxyApiBaseClassName { const String proxyApiBaseCodec = ''' class $_proxyApiCodecName extends _PigeonCodec { const $_proxyApiCodecName(this.instanceManager); - final $instanceManagerClassName instanceManager; + final $dartInstanceManagerClassName instanceManager; @override void writeValue(WriteBuffer buffer, Object? value) { if (value is $proxyApiBaseClassName) { - buffer.putUint8(128); + buffer.putUint8($proxyApiCodecInstanceManagerKey); writeValue(buffer, instanceManager.getIdentifier(value)); } else { super.writeValue(buffer, value); @@ -277,7 +291,7 @@ class $_proxyApiCodecName extends _PigeonCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: + case $proxyApiCodecInstanceManagerKey: return instanceManager .getInstanceWithWeakReference(readValue(buffer)! as int); default: diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index b5c0e42d365b..e8c7550cd708 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -32,6 +32,8 @@ const DocumentCommentSpecification _docCommentSpec = /// The custom codec used for all pigeon APIs. const String _pigeonCodec = '_PigeonCodec'; +const String _overflowClassName = '_PigeonCodecOverflow'; + /// Options that control how Dart code will be generated. class DartOptions { /// Constructor for DartOptions. @@ -283,59 +285,96 @@ class DartGenerator extends StructuredGenerator { Indent indent, { required String dartPackageName, }) { + void writeEncodeLogic(EnumeratedType customType) { + indent.writeScoped('else if (value is ${customType.name}) {', '}', () { + if (customType.enumeration < maximumCodecFieldKey) { + indent.writeln('buffer.putUint8(${customType.enumeration});'); + if (customType.type == CustomTypes.customClass) { + indent.writeln('writeValue(buffer, value.encode());'); + } else if (customType.type == CustomTypes.customEnum) { + indent.writeln('writeValue(buffer, value.index);'); + } + } else { + final String encodeString = customType.type == CustomTypes.customClass + ? '.encode()' + : '.index'; + indent.writeln( + 'final $_overflowClassName wrap = $_overflowClassName(type: ${customType.enumeration - maximumCodecFieldKey}, wrapped: value$encodeString);'); + indent.writeln('buffer.putUint8($maximumCodecFieldKey);'); + indent.writeln('writeValue(buffer, wrap.encode());'); + } + }, addTrailingNewline: false); + } + + void writeDecodeLogic(EnumeratedType customType) { + indent.writeln('case ${customType.enumeration}: '); + indent.nest(1, () { + if (customType.type == CustomTypes.customClass) { + if (customType.enumeration == maximumCodecFieldKey) { + indent.writeln( + 'final ${customType.name} wrapper = ${customType.name}.decode(readValue(buffer)!);'); + indent.writeln('return wrapper.unwrap();'); + } else { + indent.writeln( + 'return ${customType.name}.decode(readValue(buffer)!);'); + } + } else if (customType.type == CustomTypes.customEnum) { + indent.writeln('final int? value = readValue(buffer) as int?;'); + indent.writeln( + 'return value == null ? null : ${customType.name}.values[value];'); + } + }); + } + + final EnumeratedType overflowClass = EnumeratedType( + _overflowClassName, maximumCodecFieldKey, CustomTypes.customClass); + indent.newln(); - final Iterable enumeratedTypes = getEnumeratedTypes(root); + final List enumeratedTypes = + getEnumeratedTypes(root).toList(); + if (root.requiresOverflowClass) { + _writeCodecOverflowUtilities(indent, enumeratedTypes); + } indent.newln(); indent.write('class $_pigeonCodec extends StandardMessageCodec'); indent.addScoped(' {', '}', () { indent.writeln('const $_pigeonCodec();'); - if (enumeratedTypes.isNotEmpty) { - indent.writeln('@override'); - indent.write('void writeValue(WriteBuffer buffer, Object? value) '); - indent.addScoped('{', '}', () { - enumerate(enumeratedTypes, - (int index, final EnumeratedType customType) { - indent.writeScoped('if (value is ${customType.name}) {', '} else ', - () { - indent.writeln('buffer.putUint8(${customType.enumeration});'); - if (customType.type == CustomTypes.customClass) { - indent.writeln('writeValue(buffer, value.encode());'); - } else if (customType.type == CustomTypes.customEnum) { - indent.writeln('writeValue(buffer, value.index);'); - } - }, addTrailingNewline: false); - }); - indent.addScoped('{', '}', () { - indent.writeln('super.writeValue(buffer, value);'); - }); + indent.writeln('@override'); + indent.write('void writeValue(WriteBuffer buffer, Object? value) '); + indent.addScoped('{', '}', () { + indent.writeScoped('if (value is int) {', '}', () { + indent.writeln('buffer.putUint8(4);'); + indent.writeln('buffer.putInt64(value);'); + }, addTrailingNewline: false); + + enumerate(enumeratedTypes, + (int index, final EnumeratedType customType) { + writeEncodeLogic(customType); }); - indent.newln(); - indent.writeln('@override'); - indent.write('Object? readValueOfType(int type, ReadBuffer buffer) '); + indent.addScoped(' else {', '}', () { + indent.writeln('super.writeValue(buffer, value);'); + }); + }); + indent.newln(); + indent.writeln('@override'); + indent.write('Object? readValueOfType(int type, ReadBuffer buffer) '); + indent.addScoped('{', '}', () { + indent.write('switch (type) '); indent.addScoped('{', '}', () { - indent.write('switch (type) '); - indent.addScoped('{', '}', () { - for (final EnumeratedType customType in enumeratedTypes) { - indent.writeln('case ${customType.enumeration}: '); - indent.nest(1, () { - if (customType.type == CustomTypes.customClass) { - indent.writeln( - 'return ${customType.name}.decode(readValue(buffer)!);'); - } else if (customType.type == CustomTypes.customEnum) { - indent - .writeln('final int? value = readValue(buffer) as int?;'); - indent.writeln( - 'return value == null ? null : ${customType.name}.values[value];'); - } - }); + for (final EnumeratedType customType in enumeratedTypes) { + if (customType.enumeration < maximumCodecFieldKey) { + writeDecodeLogic(customType); } - indent.writeln('default:'); - indent.nest(1, () { - indent.writeln('return super.readValueOfType(type, buffer);'); - }); + } + if (root.requiresOverflowClass) { + writeDecodeLogic(overflowClass); + } + indent.writeln('default:'); + indent.nest(1, () { + indent.writeln('return super.readValueOfType(type, buffer);'); }); }); - } + }); }); } @@ -498,8 +537,6 @@ final BinaryMessenger? ${varNamePrefix}binaryMessenger; Indent indent, { required String dartPackageName, }) { - const String apiName = '${instanceManagerClassName}Api'; - final cb.Parameter binaryMessengerParameter = cb.Parameter( (cb.ParameterBuilder builder) => builder ..name = 'binaryMessenger' @@ -514,23 +551,18 @@ final BinaryMessenger? ${varNamePrefix}binaryMessenger; ..modifier = cb.FieldModifier.final$, ); - final String removeStrongReferenceName = makeChannelNameWithStrings( - apiName: apiName, - methodName: 'removeStrongReference', - dartPackageName: dartPackageName, - ); - final cb.Class instanceManagerApi = cb.Class( (cb.ClassBuilder builder) => builder - ..name = '_$apiName' + ..name = dartInstanceManagerApiClassName ..docs.add( - '/// Generated API for managing the Dart and native `$instanceManagerClassName`s.', + '/// Generated API for managing the Dart and native `$dartInstanceManagerClassName`s.', ) ..constructors.add( cb.Constructor( (cb.ConstructorBuilder builder) { builder - ..docs.add('/// Constructor for [_$apiName].') + ..docs.add( + '/// Constructor for [$dartInstanceManagerApiClassName].') ..optionalParameters.add(binaryMessengerParameter) ..initializers.add( cb.Code( @@ -550,7 +582,7 @@ final BinaryMessenger? ${varNamePrefix}binaryMessenger; ..type = cb.refer('MessageCodec') ..static = true ..modifier = cb.FieldModifier.constant - ..assignment = const cb.Code('StandardMessageCodec()'); + ..assignment = const cb.Code('$_pigeonCodec()'); }, ) ], @@ -575,7 +607,7 @@ final BinaryMessenger? ${varNamePrefix}binaryMessenger; (cb.ParameterBuilder builder) => builder ..name = 'instanceManager' ..named = true - ..type = cb.refer('$instanceManagerClassName?'), + ..type = cb.refer('$dartInstanceManagerClassName?'), ), ]) ..body = cb.Block.of( @@ -595,7 +627,9 @@ final BinaryMessenger? ${varNamePrefix}binaryMessenger; ) ], returnType: const TypeDeclaration.voidDeclaration(), - channelName: removeStrongReferenceName, + channelName: makeRemoveStrongReferenceChannelName( + dartPackageName, + ), isMockHandler: false, isAsynchronous: false, nullHandlerExpression: @@ -605,7 +639,7 @@ final BinaryMessenger? ${varNamePrefix}binaryMessenger; Iterable parameters, Iterable safeArgumentNames, ) { - return '(instanceManager ?? $instanceManagerClassName.instance).remove(${safeArgumentNames.single})'; + return '(instanceManager ?? $dartInstanceManagerClassName.instance).remove(${safeArgumentNames.single})'; }, ); builder.statements.add( @@ -638,7 +672,8 @@ final BinaryMessenger? ${varNamePrefix}binaryMessenger; _writeHostMethodMessageCall( Indent(messageCallSink), addSuffixVariable: false, - channelName: removeStrongReferenceName, + channelName: makeRemoveStrongReferenceChannelName( + dartPackageName), parameters: [ Parameter( name: 'identifier', @@ -664,7 +699,7 @@ final BinaryMessenger? ${varNamePrefix}binaryMessenger; ..returns = cb.refer('Future') ..modifier = cb.MethodModifier.async ..docs.addAll([ - '/// Clear the native `$instanceManagerClassName`.', + '/// Clear the native `$dartInstanceManagerClassName`.', '///', '/// This is typically called after a hot restart.', ]) @@ -674,11 +709,7 @@ final BinaryMessenger? ${varNamePrefix}binaryMessenger; _writeHostMethodMessageCall( Indent(messageCallSink), addSuffixVariable: false, - channelName: makeChannelNameWithStrings( - apiName: apiName, - methodName: 'clear', - dartPackageName: dartPackageName, - ), + channelName: makeClearChannelName(dartPackageName), parameters: [], returnType: const TypeDeclaration.voidDeclaration(), ); @@ -720,7 +751,7 @@ final BinaryMessenger? ${varNamePrefix}binaryMessenger; // Each API has a private codec instance used by every host method, // constructor, or non-static field. - final String codecInstanceName = '${varNamePrefix}codec${api.name}'; + final String codecInstanceName = '_${varNamePrefix}codec${api.name}'; // AST class used by code_builder to generate the code. final cb.Class proxyApi = cb.Class( @@ -955,6 +986,52 @@ PlatformException _createConnectionError(String channelName) { }'''); } + void _writeCodecOverflowUtilities(Indent indent, List types) { + indent.newln(); + indent.writeln('// ignore: camel_case_types'); + indent.writeScoped('class $_overflowClassName {', '}', () { + indent.format(''' +$_overflowClassName({required this.type, required this.wrapped}); + +int type; +Object? wrapped; + +Object encode() { + return [type, wrapped]; +} + +static $_overflowClassName decode(Object result) { + result as List; + return $_overflowClassName( + type: result[0]! as int, + wrapped: result[1], + ); +} +'''); + indent.writeScoped('Object? unwrap() {', '}', () { + indent.format(''' +if (wrapped == null) { + return null; +} +'''); + indent.writeScoped('switch (type) {', '}', () { + for (int i = totalCustomCodecKeysAllowed; i < types.length; i++) { + indent.writeScoped('case ${i - totalCustomCodecKeysAllowed}:', '', + () { + if (types[i].type == CustomTypes.customClass) { + indent.writeln('return ${types[i].name}.decode(wrapped!);'); + } else if (types[i].type == CustomTypes.customEnum) { + indent.writeln( + 'return ${types[i].name}.values[wrapped! as int];'); + } + }); + } + }); + indent.writeln('return null;'); + }); + }); + } + void _writeHostMethod( Indent indent, { required String name, @@ -1341,7 +1418,7 @@ if (${varNamePrefix}replyList == null) { '/// Constructs [$apiName] without creating the associated native object.', '///', '/// This should only be used by subclasses created by this library or to', - '/// create copies for an [$instanceManagerClassName].', + '/// create copies for an [$dartInstanceManagerClassName].', ]) ..annotations.add(cb.refer('protected')) ..optionalParameters.addAll([ @@ -1448,7 +1525,7 @@ if (${varNamePrefix}replyList == null) { ');', '```', '', - 'Alternatively, [$instanceManagerClassName.removeWeakReference] can be used to', + 'Alternatively, [$dartInstanceManagerClassName.removeWeakReference] can be used to', 'release the associated Native object manually.', ], ], @@ -1594,7 +1671,7 @@ if (${varNamePrefix}replyList == null) { (cb.ParameterBuilder builder) => builder ..name = _instanceManagerVarName ..named = true - ..type = cb.refer('$instanceManagerClassName?'), + ..type = cb.refer('$dartInstanceManagerClassName?'), ), if (hasCallbackConstructor) cb.Parameter( @@ -1645,7 +1722,7 @@ if (${varNamePrefix}replyList == null) { ..body = cb.Block.of([ if (hasAnyMessageHandlers) ...[ cb.Code( - 'final $codecName $_pigeonChannelCodec = $codecName($_instanceManagerVarName ?? $instanceManagerClassName.instance);', + 'final $codecName $_pigeonChannelCodec = $codecName($_instanceManagerVarName ?? $dartInstanceManagerClassName.instance);', ), const cb.Code( 'final BinaryMessenger? binaryMessenger = ${classMemberNamePrefix}binaryMessenger;', @@ -1693,7 +1770,7 @@ if (${varNamePrefix}replyList == null) { return '${parameter.name}: $safeArgName,\n'; }, ).skip(1).join(); - return '($_instanceManagerVarName ?? $instanceManagerClassName.instance)\n' + return '($_instanceManagerVarName ?? $dartInstanceManagerClassName.instance)\n' ' .addHostCreatedInstance(\n' ' $methodName?.call(${safeArgumentNames.skip(1).join(',')}) ??\n' ' $apiName.${classMemberNamePrefix}detached(' @@ -1812,8 +1889,8 @@ if (${varNamePrefix}replyList == null) { if (!field.isStatic) ...[ cb.Code( 'final $type $instanceName = $type.${classMemberNamePrefix}detached(\n' - ' pigeon_binaryMessenger: pigeon_binaryMessenger,\n' - ' pigeon_instanceManager: pigeon_instanceManager,\n' + ' ${classMemberNamePrefix}binaryMessenger: ${classMemberNamePrefix}binaryMessenger,\n' + ' ${classMemberNamePrefix}instanceManager: ${classMemberNamePrefix}instanceManager,\n' ');', ), cb.Code('final $codecName $_pigeonChannelCodec =\n' @@ -1829,13 +1906,13 @@ if (${varNamePrefix}replyList == null) { 'final $type $instanceName = $type.${classMemberNamePrefix}detached();', ), cb.Code( - 'final $codecName $_pigeonChannelCodec = $codecName($instanceManagerClassName.instance);', + 'final $codecName $_pigeonChannelCodec = $codecName($dartInstanceManagerClassName.instance);', ), const cb.Code( 'final BinaryMessenger ${varNamePrefix}binaryMessenger = ServicesBinding.instance.defaultBinaryMessenger;', ), const cb.Code( - 'final int $identifierInstanceName = $instanceManagerClassName.instance.addDartCreatedInstance($instanceName);', + 'final int $identifierInstanceName = $dartInstanceManagerClassName.instance.addDartCreatedInstance($instanceName);', ), ], const cb.Code('() async {'), @@ -1896,7 +1973,7 @@ if (${varNamePrefix}replyList == null) { cb.Parameter( (cb.ParameterBuilder builder) => builder ..name = _instanceManagerVarName - ..type = cb.refer('$instanceManagerClassName?'), + ..type = cb.refer('$dartInstanceManagerClassName?'), ), ], ]) @@ -1930,7 +2007,7 @@ if (${varNamePrefix}replyList == null) { ' $codecInstanceName;') else cb.Code( - 'final $codecName $_pigeonChannelCodec = $codecName($_instanceManagerVarName ?? $instanceManagerClassName.instance);', + 'final $codecName $_pigeonChannelCodec = $codecName($_instanceManagerVarName ?? $dartInstanceManagerClassName.instance);', ), const cb.Code( 'final BinaryMessenger? ${varNamePrefix}binaryMessenger = ${classMemberNamePrefix}binaryMessenger;', @@ -2080,8 +2157,8 @@ String _getMethodParameterSignature(Iterable parameters) { String _flattenTypeArguments(List args) { return args .map((TypeDeclaration arg) => arg.typeArguments.isEmpty - ? '${arg.baseName}?' - : '${arg.baseName}<${_flattenTypeArguments(arg.typeArguments)}>?') + ? '${arg.baseName}${arg.isNullable ? '?' : ''}' + : '${arg.baseName}<${_flattenTypeArguments(arg.typeArguments)}>${arg.isNullable ? '?' : ''}') .join(', '); } @@ -2091,11 +2168,11 @@ String _addGenericTypes(TypeDeclaration type) { final List typeArguments = type.typeArguments; switch (type.baseName) { case 'List': - return (typeArguments.isEmpty) + return typeArguments.isEmpty ? 'List' : 'List<${_flattenTypeArguments(typeArguments)}>'; case 'Map': - return (typeArguments.isEmpty) + return typeArguments.isEmpty ? 'Map' : 'Map<${_flattenTypeArguments(typeArguments)}>'; default: diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart index 7c43243b0f53..cbec3e8da6fc 100644 --- a/packages/pigeon/lib/generator_tools.dart +++ b/packages/pigeon/lib/generator_tools.dart @@ -4,6 +4,7 @@ import 'dart:convert'; import 'dart:io'; +import 'dart:math'; import 'dart:mirrors'; import 'package:yaml/yaml.dart' as yaml; @@ -13,13 +14,7 @@ import 'ast.dart'; /// The current version of pigeon. /// /// This must match the version in pubspec.yaml. -const String pigeonVersion = '20.0.1'; - -/// Prefix for all local variables in methods. -/// -/// This lowers the chances of variable name collisions with -/// user defined parameters. -const String varNamePrefix = '__pigeon_'; +const String pigeonVersion = '22.6.0'; /// Read all the content from [stdin] to a String. String readStdin() { @@ -76,11 +71,29 @@ class Indent { } /// Replaces the newlines and tabs of input and adds it to the stream. - void format(String input, - {bool leadingSpace = true, bool trailingNewline = true}) { + /// + /// [trimIndentation] flag finds the line with the fewest leading empty + /// spaces and trims the beginning of all lines by this number. + void format( + String input, { + bool leadingSpace = true, + bool trailingNewline = true, + bool trimIndentation = true, + }) { final List lines = input.split('\n'); + + final int indentationToRemove = !trimIndentation + ? 0 + : lines + .where((String line) => line.trim().isNotEmpty) + .map((String line) => line.length - line.trimLeft().length) + .reduce(min); + for (int i = 0; i < lines.length; ++i) { - final String line = lines[i]; + final String line = lines[i].length >= indentationToRemove + ? lines[i].substring(indentationToRemove) + : lines[i]; + if (i == 0 && !leadingSpace) { add(line.replaceAll('\t', tab)); } else if (line.isNotEmpty) { @@ -102,8 +115,6 @@ class Indent { bool addTrailingNewline = true, int nestCount = 1, }) { - assert(begin != '' || end != '', - 'Use nest for indentation without any decoration'); if (begin != null) { _sink.write(begin + newline); } @@ -123,8 +134,6 @@ class Indent { Function func, { bool addTrailingNewline = true, }) { - assert(begin != '' || end != '', - 'Use nest for indentation without any decoration'); addScoped(str() + (begin ?? ''), end, func, addTrailingNewline: addTrailingNewline); } @@ -301,17 +310,23 @@ String getGeneratedCodeWarning() { /// String to be printed after `getGeneratedCodeWarning()'s warning`. const String seeAlsoWarning = 'See also: https://pub.dev/packages/pigeon'; -/// Prefix for utility classes generated for ProxyApis. +/// Prefix for generated internal classes. /// /// This lowers the chances of variable name collisions with user defined /// parameters. -const String classNamePrefix = 'Pigeon'; +const String classNamePrefix = 'PigeonInternal'; -/// Name for the generated InstanceManager for ProxyApis. +/// Prefix for classes generated to use with ProxyApis. /// /// This lowers the chances of variable name collisions with user defined /// parameters. -const String instanceManagerClassName = '${classNamePrefix}InstanceManager'; +const String proxyApiClassNamePrefix = 'Pigeon'; + +/// Prefix for APIs generated for ProxyApi. +/// +/// Since ProxyApis are intended to wrap a class and will often share the name +/// of said class, host APIs should prefix the API with this protected name. +const String hostProxyApiPrefix = '${proxyApiClassNamePrefix}Api'; /// Prefix for class member names not defined by the user. /// @@ -319,6 +334,22 @@ const String instanceManagerClassName = '${classNamePrefix}InstanceManager'; /// parameters. const String classMemberNamePrefix = 'pigeon_'; +/// Prefix for variable names not defined by the user. +/// +/// This lowers the chances of variable name collisions with user defined +/// parameters. +const String varNamePrefix = 'pigeonVar_'; + +/// Prefixes that are not allowed for any names of any types or methods. +const List disallowedPrefixes = [ + classNamePrefix, + classMemberNamePrefix, + hostProxyApiPrefix, + proxyApiClassNamePrefix, + varNamePrefix, + 'pigeonChannelCodec' +]; + /// Collection of keys used in dictionaries across generators. class Keys { /// The key in the result hash for the 'result' value. @@ -418,9 +449,26 @@ const List validTypes = [ 'Object', ]; -/// Custom codecs' custom types are enumerated from 255 down to this number to +/// The dedicated key for accessing an InstanceManager in ProxyApi base codecs. +/// +/// Generated codecs override the `StandardMessageCodec` which reserves the byte +/// keys of 0-127, so this value is chosen because it is the lowest available +/// key. +/// +/// See https://api.flutter.dev/flutter/services/StandardMessageCodec/writeValue.html +/// for more information on keys in MessageCodecs. +const int proxyApiCodecInstanceManagerKey = 128; + +/// Custom codecs' custom types are enumerations begin at this number to /// avoid collisions with the StandardMessageCodec. -const int _minimumCodecFieldKey = 129; +const int minimumCodecFieldKey = proxyApiCodecInstanceManagerKey + 1; + +/// The maximum codec enumeration allowed. +const int maximumCodecFieldKey = 255; + +/// The total number of keys allowed in the custom codec. +const int totalCustomCodecKeysAllowed = + maximumCodecFieldKey - minimumCodecFieldKey; Iterable _getTypeArguments(TypeDeclaration type) sync* { for (final TypeDeclaration typeArg in type.typeArguments) { @@ -504,6 +552,48 @@ Map> getReferencedTypes( return references.map; } +/// Find the [TypeDeclaration] that has the highest API requirement and its +/// version, [T]. +/// +/// [T] depends on the language. For example, Android uses an int while iOS uses +/// semantic versioning. +({TypeDeclaration type, T version})? + findHighestApiRequirement( + Iterable types, { + required T? Function(TypeDeclaration) onGetApiRequirement, + required Comparator onCompare, +}) { + Iterable addAllRecursive(TypeDeclaration type) sync* { + yield type; + if (type.typeArguments.isNotEmpty) { + for (final TypeDeclaration typeArg in type.typeArguments) { + yield* addAllRecursive(typeArg); + } + } + } + + final Iterable allReferencedTypes = types + .expand(addAllRecursive) + .where((TypeDeclaration type) => onGetApiRequirement(type) != null); + + if (allReferencedTypes.isEmpty) { + return null; + } + + final TypeDeclaration typeWithHighestRequirement = allReferencedTypes.reduce( + (TypeDeclaration one, TypeDeclaration two) { + return onCompare(onGetApiRequirement(one)!, onGetApiRequirement(two)!) > 0 + ? one + : two; + }, + ); + + return ( + type: typeWithHighestRequirement, + version: onGetApiRequirement(typeWithHighestRequirement)!, + ); +} + /// All custom definable data types. enum CustomTypes { /// A custom Class. @@ -516,31 +606,33 @@ enum CustomTypes { /// Return the enumerated types that must exist in the codec /// where the enumeration should be the key used in the buffer. Iterable getEnumeratedTypes(Root root) sync* { - const int maxCustomClassesPerApi = 255 - _minimumCodecFieldKey; - if (root.classes.length + root.enums.length > maxCustomClassesPerApi) { - throw Exception( - "Pigeon doesn't currently support more than $maxCustomClassesPerApi referenced custom classes per file."); - } int index = 0; - for (final Class customClass in root.classes) { - yield EnumeratedType( - customClass.name, - index + _minimumCodecFieldKey, - CustomTypes.customClass, - associatedClass: customClass, - ); - index += 1; - } for (final Enum customEnum in root.enums) { yield EnumeratedType( customEnum.name, - index + _minimumCodecFieldKey, + index + minimumCodecFieldKey, CustomTypes.customEnum, associatedEnum: customEnum, ); index += 1; } + + for (final Class customClass in root.classes) { + yield EnumeratedType( + customClass.name, + index + minimumCodecFieldKey, + CustomTypes.customClass, + associatedClass: customClass, + ); + index += 1; + } +} + +/// Checks if [root] contains enough custom types to require overflow codec tools. +bool customTypeOverflowCheck(Root root) { + return root.classes.length + root.enums.length > + maximumCodecFieldKey - minimumCodecFieldKey; } /// Describes how to format a document comment. @@ -708,3 +800,34 @@ String toUpperCamelCase(String text) { : word.substring(0, 1).toUpperCase() + word.substring(1); }).join(); } + +/// Converts string to SCREAMING_SNAKE_CASE. +String toScreamingSnakeCase(String string) { + return string + .replaceAllMapped( + RegExp(r'(?<=[a-z])[A-Z]'), (Match m) => '_${m.group(0)}') + .toUpperCase(); +} + +/// The channel name for the `removeStrongReference` method of the +/// `InstanceManager` API. +/// +/// This ensures the channel name is the same for all languages. +String makeRemoveStrongReferenceChannelName(String dartPackageName) { + return makeChannelNameWithStrings( + apiName: '${classNamePrefix}InstanceManager', + methodName: 'removeStrongReference', + dartPackageName: dartPackageName, + ); +} + +/// The channel name for the `clear` method of the `InstanceManager` API. +/// +/// This ensures the channel name is the same for all languages. +String makeClearChannelName(String dartPackageName) { + return makeChannelNameWithStrings( + apiName: '${classNamePrefix}InstanceManager', + methodName: 'clear', + dartPackageName: dartPackageName, + ); +} diff --git a/packages/pigeon/lib/gobject_generator.dart b/packages/pigeon/lib/gobject_generator.dart new file mode 100644 index 000000000000..bee03804f53b --- /dev/null +++ b/packages/pigeon/lib/gobject_generator.dart @@ -0,0 +1,2109 @@ +// 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 'ast.dart'; +import 'generator.dart'; +import 'generator_tools.dart'; + +/// Documentation comment spec. +const DocumentCommentSpecification _docCommentSpec = + DocumentCommentSpecification('/**', + closeCommentToken: ' */', blockContinuationToken: ' *'); + +/// Name for codec class. +const String _codecBaseName = 'MessageCodec'; + +/// Options that control how GObject code will be generated. +class GObjectOptions { + /// Creates a [GObjectOptions] object + const GObjectOptions({ + this.headerIncludePath, + this.module, + this.copyrightHeader, + this.headerOutPath, + }); + + /// The path to the header that will get placed in the source filed (example: + /// "foo.h"). + final String? headerIncludePath; + + /// The module where the generated class will live. + final String? module; + + /// A copyright header that will get prepended to generated code. + final Iterable? copyrightHeader; + + /// The path to the output header file location. + final String? headerOutPath; + + /// Creates a [GObjectOptions] from a Map representation where: + /// `x = GObjectOptions.fromMap(x.toMap())`. + static GObjectOptions fromMap(Map map) { + final Iterable? copyrightHeader = + map['copyrightHeader'] as Iterable?; + return GObjectOptions( + headerIncludePath: map['header'] as String?, + module: map['module'] as String?, + copyrightHeader: copyrightHeader?.cast(), + headerOutPath: map['gobjectHeaderOut'] as String?, + ); + } + + /// Converts a [GObjectOptions] to a Map representation where: + /// `x = GObjectOptions.fromMap(x.toMap())`. + Map toMap() { + final Map result = { + if (headerIncludePath != null) 'header': headerIncludePath!, + if (module != null) 'module': module!, + if (copyrightHeader != null) 'copyrightHeader': copyrightHeader!, + }; + return result; + } + + /// Overrides any non-null parameters from [options] into this to make a new + /// [GObjectOptions]. + GObjectOptions merge(GObjectOptions options) { + return GObjectOptions.fromMap(mergeMaps(toMap(), options.toMap())); + } +} + +/// Class that manages all GObject code generation. +class GObjectGenerator extends Generator> { + /// Constructor. + const GObjectGenerator(); + + /// Generates GObject file of type specified in [generatorOptions] + @override + void generate( + OutputFileOptions generatorOptions, + Root root, + StringSink sink, { + required String dartPackageName, + }) { + assert(generatorOptions.fileType == FileType.header || + generatorOptions.fileType == FileType.source); + if (generatorOptions.fileType == FileType.header) { + const GObjectHeaderGenerator().generate( + generatorOptions.languageOptions, + root, + sink, + dartPackageName: dartPackageName, + ); + } else if (generatorOptions.fileType == FileType.source) { + const GObjectSourceGenerator().generate( + generatorOptions.languageOptions, + root, + sink, + dartPackageName: dartPackageName, + ); + } + } +} + +/// Writes GObject header (.h) file to sink. +class GObjectHeaderGenerator extends StructuredGenerator { + /// Constructor. + const GObjectHeaderGenerator(); + + @override + void writeFilePrologue( + GObjectOptions generatorOptions, + Root root, + Indent indent, { + required String dartPackageName, + }) { + if (generatorOptions.copyrightHeader != null) { + addLines(indent, generatorOptions.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('// ${getGeneratedCodeWarning()}'); + indent.writeln('// $seeAlsoWarning'); + } + + @override + void writeFileImports( + GObjectOptions generatorOptions, + Root root, + Indent indent, { + required String dartPackageName, + }) { + indent.newln(); + final String guardName = _getGuardName(generatorOptions.headerIncludePath); + indent.writeln('#ifndef $guardName'); + indent.writeln('#define $guardName'); + + indent.newln(); + indent.writeln('#include '); + } + + @override + void writeOpenNamespace( + GObjectOptions generatorOptions, + Root root, + Indent indent, { + required String dartPackageName, + }) { + indent.newln(); + indent.writeln('G_BEGIN_DECLS'); + } + + @override + void writeEnum( + GObjectOptions generatorOptions, + Root root, + Indent indent, + Enum anEnum, { + required String dartPackageName, + }) { + final String module = _getModule(generatorOptions, dartPackageName); + final String enumName = _getClassName(module, anEnum.name); + + indent.newln(); + final List enumValueCommentLines = []; + for (int i = 0; i < anEnum.members.length; i++) { + final EnumMember member = anEnum.members[i]; + final String itemName = + _getEnumValue(dartPackageName, anEnum.name, member.name); + enumValueCommentLines.add('$itemName:'); + enumValueCommentLines.addAll(member.documentationComments); + } + addDocumentationComments( + indent, + [ + '$enumName:', + ...enumValueCommentLines, + '', + ...anEnum.documentationComments + ], + _docCommentSpec); + indent.writeScoped('typedef enum {', '} $enumName;', () { + for (int i = 0; i < anEnum.members.length; i++) { + final EnumMember member = anEnum.members[i]; + final String itemName = + _getEnumValue(dartPackageName, anEnum.name, member.name); + indent.writeln( + '$itemName = $i${i == anEnum.members.length - 1 ? '' : ','}'); + } + }); + } + + @override + void writeDataClass( + GObjectOptions generatorOptions, + Root root, + Indent indent, + Class classDefinition, { + required String dartPackageName, + }) { + final String module = _getModule(generatorOptions, dartPackageName); + final String className = _getClassName(module, classDefinition.name); + final String methodPrefix = _getMethodPrefix(module, classDefinition.name); + + indent.newln(); + addDocumentationComments( + indent, + [ + '$className:', + '', + ...classDefinition.documentationComments, + ], + _docCommentSpec); + + indent.newln(); + _writeDeclareFinalType(indent, module, classDefinition.name); + + indent.newln(); + final List constructorArgs = []; + for (final NamedType field in classDefinition.fields) { + final String fieldName = _getFieldName(field.name); + final String type = _getType(module, field.type); + constructorArgs.add('$type $fieldName'); + if (_isNumericListType(field.type)) { + constructorArgs.add('size_t ${fieldName}_length'); + } + } + final List constructorFieldCommentLines = []; + for (final NamedType field in classDefinition.fields) { + final String fieldName = _getFieldName(field.name); + constructorFieldCommentLines.add('$fieldName: field in this object.'); + if (_isNumericListType(field.type)) { + constructorFieldCommentLines + .add('${fieldName}_length: length of @$fieldName.'); + } + } + addDocumentationComments( + indent, + [ + '${methodPrefix}_new:', + ...constructorFieldCommentLines, + '', + 'Creates a new #${classDefinition.name} object.', + '', + 'Returns: a new #$className', + ], + _docCommentSpec); + + indent.writeln( + "$className* ${methodPrefix}_new(${constructorArgs.join(', ')});"); + + for (final NamedType field in classDefinition.fields) { + final String fieldName = _getFieldName(field.name); + final String returnType = _getType(module, field.type); + + indent.newln(); + addDocumentationComments( + indent, + [ + '${methodPrefix}_get_$fieldName', + '@object: a #$className.', + if (_isNumericListType(field.type)) + '@length: location to write the length of this value.', + '', + if (field.documentationComments.isNotEmpty) + ...field.documentationComments + else + 'Gets the value of the ${field.name} field of @object.', + '', + 'Returns: the field value.', + ], + _docCommentSpec); + final List getterArgs = [ + '$className* object', + if (_isNumericListType(field.type)) 'size_t* length' + ]; + indent.writeln( + '$returnType ${methodPrefix}_get_$fieldName(${getterArgs.join(', ')});'); + } + } + + @override + void writeGeneralCodec( + GObjectOptions generatorOptions, + Root root, + Indent indent, { + required String dartPackageName, + }) {} + + @override + void writeFlutterApi( + GObjectOptions generatorOptions, + Root root, + Indent indent, + Api api, { + required String dartPackageName, + }) { + final String module = _getModule(generatorOptions, dartPackageName); + final String className = _getClassName(module, api.name); + + for (final Method method in api.methods) { + _writeFlutterApiRespondClass(indent, module, api, method); + } + + final String methodPrefix = _getMethodPrefix(module, api.name); + indent.newln(); + addDocumentationComments( + indent, + [ + '$className:', + '', + ...api.documentationComments, + ], + _docCommentSpec); + + indent.newln(); + _writeDeclareFinalType(indent, module, api.name); + + indent.newln(); + addDocumentationComments( + indent, + [ + '${methodPrefix}_new:', + '@messenger: an #FlBinaryMessenger.', + '@suffix: (allow-none): a suffix to add to the API or %NULL for none.', + '', + 'Creates a new object to access the ${api.name} API.', + '', + 'Returns: a new #$className', + ], + _docCommentSpec); + indent.writeln( + '$className* ${methodPrefix}_new(FlBinaryMessenger* messenger, const gchar* suffix);'); + + for (final Method method in api.methods) { + final String methodName = _getMethodName(method.name); + final String responseName = _getResponseName(api.name, method.name); + final String responseClassName = _getClassName(module, responseName); + + final List asyncArgs = ['$className* api']; + for (final Parameter param in method.parameters) { + final String paramName = _snakeCaseFromCamelCase(param.name); + asyncArgs.add('${_getType(module, param.type)} $paramName'); + if (_isNumericListType(param.type)) { + asyncArgs.add('size_t ${paramName}_length'); + } + } + asyncArgs.addAll([ + 'GCancellable* cancellable', + 'GAsyncReadyCallback callback', + 'gpointer user_data' + ]); + indent.newln(); + final List methodParameterCommentLines = []; + for (final Parameter param in method.parameters) { + final String paramName = _snakeCaseFromCamelCase(param.name); + methodParameterCommentLines.add( + '@$paramName: ${param.type.isNullable ? '(allow-none): ' : ''}parameter for this method.'); + if (_isNumericListType(param.type)) { + methodParameterCommentLines + .add('@${paramName}_length: length of $paramName.'); + } + } + addDocumentationComments( + indent, + [ + '${methodPrefix}_$methodName:', + '@api: a #$className.', + ...methodParameterCommentLines, + '@cancellable: (allow-none): a #GCancellable or %NULL.', + '@callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when the call is complete or %NULL to ignore the response.', + '@user_data: (closure): user data to pass to @callback.', + '', + ...method.documentationComments + ], + _docCommentSpec); + indent.writeln( + "void ${methodPrefix}_$methodName(${asyncArgs.join(', ')});"); + + final List finishArgs = [ + '$className* api', + 'GAsyncResult* result', + 'GError** error' + ]; + indent.newln(); + addDocumentationComments( + indent, + [ + '${methodPrefix}_${methodName}_finish:', + '@api: a #$className.', + '@result: a #GAsyncResult.', + '@error: (allow-none): #GError location to store the error occurring, or %NULL to ignore.', + '', + 'Completes a ${methodPrefix}_$methodName() call.', + '', + 'Returns: a #$responseClassName or %NULL on error.', + ], + _docCommentSpec); + indent.writeln( + "$responseClassName* ${methodPrefix}_${methodName}_finish(${finishArgs.join(', ')});"); + } + } + + // Write the API response classes. + void _writeFlutterApiRespondClass( + Indent indent, String module, Api api, Method method) { + final String responseName = _getResponseName(api.name, method.name); + final String responseClassName = _getClassName(module, responseName); + final String responseMethodPrefix = _getMethodPrefix(module, responseName); + final String primitiveType = + _getType(module, method.returnType, primitive: true); + + indent.newln(); + _writeDeclareFinalType(indent, module, responseName); + + indent.newln(); + addDocumentationComments( + indent, + [ + '${responseMethodPrefix}_is_error:', + '@response: a #$responseClassName.', + '', + 'Checks if a response to ${api.name}.${method.name} is an error.', + '', + 'Returns: a %TRUE if this response is an error.', + ], + _docCommentSpec); + indent.writeln( + 'gboolean ${responseMethodPrefix}_is_error($responseClassName* response);'); + + indent.newln(); + addDocumentationComments( + indent, + [ + '${responseMethodPrefix}_get_error_code:', + '@response: a #$responseClassName.', + '', + 'Get the error code for this response.', + '', + 'Returns: an error code or %NULL if not an error.', + ], + _docCommentSpec); + indent.writeln( + 'const gchar* ${responseMethodPrefix}_get_error_code($responseClassName* response);'); + + indent.newln(); + addDocumentationComments( + indent, + [ + '${responseMethodPrefix}_get_error_message:', + '@response: a #$responseClassName.', + '', + 'Get the error message for this response.', + '', + 'Returns: an error message.', + ], + _docCommentSpec); + indent.writeln( + 'const gchar* ${responseMethodPrefix}_get_error_message($responseClassName* response);'); + + indent.newln(); + addDocumentationComments( + indent, + [ + '${responseMethodPrefix}_get_error_details:', + '@response: a #$responseClassName.', + '', + 'Get the error details for this response.', + '', + 'Returns: (allow-none): an error details or %NULL.', + ], + _docCommentSpec); + indent.writeln( + 'FlValue* ${responseMethodPrefix}_get_error_details($responseClassName* response);'); + + if (!method.returnType.isVoid) { + indent.newln(); + addDocumentationComments( + indent, + [ + '${responseMethodPrefix}_get_return_value:', + '@response: a #$responseClassName.', + if (_isNumericListType(method.returnType)) + '@return_value_length: (allow-none): location to write length of the return value or %NULL to ignore.', + '', + 'Get the return value for this response.', + '', + if (method.returnType.isNullable) + 'Returns: (allow-none): a return value or %NULL.' + else + 'Returns: a return value.', + ], + _docCommentSpec); + final String returnType = _isNullablePrimitiveType(method.returnType) + ? '$primitiveType*' + : primitiveType; + indent.writeln( + '$returnType ${responseMethodPrefix}_get_return_value($responseClassName* response${_isNumericListType(method.returnType) ? ', size_t* return_value_length' : ''});'); + } + } + + @override + void writeHostApi( + GObjectOptions generatorOptions, + Root root, + Indent indent, + Api api, { + required String dartPackageName, + }) { + final String module = _getModule(generatorOptions, dartPackageName); + final String methodPrefix = _getMethodPrefix(module, api.name); + final String vtableName = _getVTableName(module, api.name); + + final bool hasAsyncMethod = + api.methods.any((Method method) => method.isAsynchronous); + if (hasAsyncMethod) { + indent.newln(); + _writeDeclareFinalType(indent, module, '${api.name}ResponseHandle'); + } + + for (final Method method + in api.methods.where((Method method) => !method.isAsynchronous)) { + _writeHostApiRespondClass(indent, module, api, method); + } + + indent.newln(); + _writeApiVTable(indent, module, api); + + indent.newln(); + addDocumentationComments( + indent, + [ + '${methodPrefix}_set_method_handlers:', + '', + '@messenger: an #FlBinaryMessenger.', + '@suffix: (allow-none): a suffix to add to the API or %NULL for none.', + '@vtable: implementations of the methods in this API.', + '@user_data: (closure): user data to pass to the functions in @vtable.', + '@user_data_free_func: (allow-none): a function which gets called to free @user_data, or %NULL.', + '', + 'Connects the method handlers in the ${api.name} API.', + ], + _docCommentSpec); + indent.writeln( + 'void ${methodPrefix}_set_method_handlers(FlBinaryMessenger* messenger, const gchar* suffix, const $vtableName* vtable, gpointer user_data, GDestroyNotify user_data_free_func);'); + + indent.newln(); + addDocumentationComments( + indent, + [ + '${methodPrefix}_clear_method_handlers:', + '', + '@messenger: an #FlBinaryMessenger.', + '@suffix: (allow-none): a suffix to add to the API or %NULL for none.', + '', + 'Clears the method handlers in the ${api.name} API.', + ], + _docCommentSpec); + indent.writeln( + 'void ${methodPrefix}_clear_method_handlers(FlBinaryMessenger* messenger, const gchar* suffix);'); + + for (final Method method + in api.methods.where((Method method) => method.isAsynchronous)) { + _writeHostApiRespondFunctionPrototype(indent, module, api, method); + } + } + + // Write the API response classes. + void _writeHostApiRespondClass( + Indent indent, String module, Api api, Method method) { + final String responseName = _getResponseName(api.name, method.name); + final String responseClassName = _getClassName(module, responseName); + final String responseMethodPrefix = _getMethodPrefix(module, responseName); + + indent.newln(); + _writeDeclareFinalType(indent, module, responseName); + + final String returnType = _getType(module, method.returnType); + indent.newln(); + final List constructorArgs = [ + if (returnType != 'void') '$returnType return_value', + if (_isNumericListType(method.returnType)) 'size_t return_value_length' + ]; + addDocumentationComments( + indent, + [ + '${responseMethodPrefix}_new:', + '', + 'Creates a new response to ${api.name}.${method.name}.', + '', + 'Returns: a new #$responseClassName', + ], + _docCommentSpec); + indent.writeln( + '$responseClassName* ${responseMethodPrefix}_new(${constructorArgs.join(', ')});'); + + indent.newln(); + addDocumentationComments( + indent, + [ + '${responseMethodPrefix}_new_error:', + '@code: error code.', + '@message: error message.', + '@details: (allow-none): error details or %NULL.', + '', + 'Creates a new error response to ${api.name}.${method.name}.', + '', + 'Returns: a new #$responseClassName', + ], + _docCommentSpec); + indent.writeln( + '$responseClassName* ${responseMethodPrefix}_new_error(const gchar* code, const gchar* message, FlValue* details);'); + } + + // Write the vtable for an API. + void _writeApiVTable(Indent indent, String module, Api api) { + final String className = _getClassName(module, api.name); + final String vtableName = _getVTableName(module, api.name); + + addDocumentationComments( + indent, + [ + '$vtableName:', + '', + 'Table of functions exposed by ${api.name} to be implemented by the API provider.', + ], + _docCommentSpec); + indent.writeScoped('typedef struct {', '} $vtableName;', () { + for (final Method method in api.methods) { + final String methodName = _getMethodName(method.name); + final String responseName = _getResponseName(api.name, method.name); + final String responseClassName = _getClassName(module, responseName); + + final List methodArgs = []; + for (final Parameter param in method.parameters) { + final String name = _snakeCaseFromCamelCase(param.name); + methodArgs.add('${_getType(module, param.type)} $name'); + if (_isNumericListType(param.type)) { + methodArgs.add('size_t ${name}_length'); + } + } + methodArgs.addAll([ + if (method.isAsynchronous) + '${className}ResponseHandle* response_handle', + 'gpointer user_data', + ]); + final String returnType = + method.isAsynchronous ? 'void' : '$responseClassName*'; + indent.writeln("$returnType (*$methodName)(${methodArgs.join(', ')});"); + } + }); + } + + // Write the function prototype for an API method response. + void _writeHostApiRespondFunctionPrototype( + Indent indent, String module, Api api, Method method) { + final String className = _getClassName(module, api.name); + final String methodPrefix = _getMethodPrefix(module, api.name); + final String methodName = _getMethodName(method.name); + final String returnType = _getType(module, method.returnType); + + indent.newln(); + final List respondArgs = [ + '${className}ResponseHandle* response_handle', + if (returnType != 'void') '$returnType return_value', + if (_isNumericListType(method.returnType)) 'size_t return_value_length' + ]; + addDocumentationComments( + indent, + [ + '${methodPrefix}_respond_$methodName:', + '@response_handle: a #${className}ResponseHandle.', + if (returnType != 'void') + '@return_value: location to write the value returned by this method.', + if (_isNumericListType(method.returnType)) + '@return_value_length: (allow-none): location to write length of @return_value or %NULL to ignore.', + '', + 'Responds to ${api.name}.${method.name}. ', + ], + _docCommentSpec); + indent.writeln( + "void ${methodPrefix}_respond_$methodName(${respondArgs.join(', ')});"); + + indent.newln(); + final List respondErrorArgs = [ + '${className}ResponseHandle* response_handle', + 'const gchar* code', + 'const gchar* message', + 'FlValue* details' + ]; + addDocumentationComments( + indent, + [ + '${methodPrefix}_respond_error_$methodName:', + '@response_handle: a #${className}ResponseHandle.', + '@code: error code.', + '@message: error message.', + '@details: (allow-none): error details or %NULL.', + '', + 'Responds with an error to ${api.name}.${method.name}. ', + ], + _docCommentSpec); + indent.writeln( + "void ${methodPrefix}_respond_error_$methodName(${respondErrorArgs.join(', ')});"); + } + + @override + void writeCloseNamespace( + GObjectOptions generatorOptions, + Root root, + Indent indent, { + required String dartPackageName, + }) { + indent.newln(); + indent.writeln('G_END_DECLS'); + + indent.newln(); + final String guardName = _getGuardName(generatorOptions.headerIncludePath); + indent.writeln('#endif // $guardName'); + } +} + +/// Writes GObject source (.cc) file to sink. +class GObjectSourceGenerator extends StructuredGenerator { + /// Constructor. + const GObjectSourceGenerator(); + + @override + void writeFilePrologue( + GObjectOptions generatorOptions, + Root root, + Indent indent, { + required String dartPackageName, + }) { + if (generatorOptions.copyrightHeader != null) { + addLines(indent, generatorOptions.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('// ${getGeneratedCodeWarning()}'); + indent.writeln('// $seeAlsoWarning'); + } + + @override + void writeFileImports( + GObjectOptions generatorOptions, + Root root, + Indent indent, { + required String dartPackageName, + }) { + indent.newln(); + indent.writeln('#include "${generatorOptions.headerIncludePath}"'); + } + + @override + void writeDataClass( + GObjectOptions generatorOptions, + Root root, + Indent indent, + Class classDefinition, { + required String dartPackageName, + }) { + final String module = _getModule(generatorOptions, dartPackageName); + final String snakeModule = _snakeCaseFromCamelCase(module); + final String className = _getClassName(module, classDefinition.name); + final String snakeClassName = _snakeCaseFromCamelCase(classDefinition.name); + + final String methodPrefix = _getMethodPrefix(module, classDefinition.name); + final String testMacro = '${snakeModule}_IS_$snakeClassName'.toUpperCase(); + + indent.newln(); + _writeObjectStruct(indent, module, classDefinition.name, () { + for (final NamedType field in classDefinition.fields) { + final String fieldName = _getFieldName(field.name); + final String fieldType = _getType(module, field.type, isOutput: true); + indent.writeln('$fieldType $fieldName;'); + if (_isNumericListType(field.type)) { + indent.writeln('size_t ${fieldName}_length;'); + } + } + }); + + indent.newln(); + _writeDefineType(indent, module, classDefinition.name); + + indent.newln(); + _writeDispose(indent, module, classDefinition.name, () { + bool haveSelf = false; + for (final NamedType field in classDefinition.fields) { + final String fieldName = _getFieldName(field.name); + final String? clear = _getClearFunction(field.type, 'self->$fieldName'); + if (clear != null) { + if (!haveSelf) { + _writeCastSelf(indent, module, classDefinition.name, 'object'); + haveSelf = true; + } + indent.writeln('$clear;'); + } + } + }); + + indent.newln(); + _writeInit(indent, module, classDefinition.name, () {}); + + indent.newln(); + _writeClassInit(indent, module, classDefinition.name, () {}); + + final List constructorArgs = []; + for (final NamedType field in classDefinition.fields) { + final String fieldName = _getFieldName(field.name); + constructorArgs.add('${_getType(module, field.type)} $fieldName'); + if (_isNumericListType(field.type)) { + constructorArgs.add('size_t ${fieldName}_length'); + } + } + indent.newln(); + indent.writeScoped( + "$className* ${methodPrefix}_new(${constructorArgs.join(', ')}) {", '}', + () { + _writeObjectNew(indent, module, classDefinition.name); + for (final NamedType field in classDefinition.fields) { + final String fieldName = _getFieldName(field.name); + final String value = _referenceValue(module, field.type, fieldName, + lengthVariableName: '${fieldName}_length'); + + if (_isNullablePrimitiveType(field.type)) { + final String primitiveType = + _getType(module, field.type, primitive: true); + indent.writeScoped('if ($value != nullptr) {', '}', () { + indent.writeln( + 'self->$fieldName = static_cast<$primitiveType*>(malloc(sizeof($primitiveType)));'); + indent.writeln('*self->$fieldName = *$value;'); + }); + indent.writeScoped('else {', '}', () { + indent.writeln('self->$fieldName = nullptr;'); + }); + } else if (field.type.isNullable) { + indent.writeScoped('if ($fieldName != nullptr) {', '}', () { + indent.writeln('self->$fieldName = $value;'); + if (_isNumericListType(field.type)) { + indent + .writeln('self->${fieldName}_length = ${fieldName}_length;'); + } + }); + indent.writeScoped('else {', '}', () { + indent.writeln('self->$fieldName = nullptr;'); + if (_isNumericListType(field.type)) { + indent.writeln('self->${fieldName}_length = 0;'); + } + }); + } else { + indent.writeln('self->$fieldName = $value;'); + if (_isNumericListType(field.type)) { + indent.writeln('self->${fieldName}_length = ${fieldName}_length;'); + } + } + } + indent.writeln('return self;'); + }); + + for (final NamedType field in classDefinition.fields) { + final String fieldName = _getFieldName(field.name); + final String returnType = _getType(module, field.type); + + indent.newln(); + final List getterArgs = [ + '$className* self', + if (_isNumericListType(field.type)) 'size_t* length' + ]; + indent.writeScoped( + '$returnType ${methodPrefix}_get_$fieldName(${getterArgs.join(', ')}) {', + '}', () { + indent.writeln( + 'g_return_val_if_fail($testMacro(self), ${_getDefaultValue(module, field.type)});'); + if (_isNumericListType(field.type)) { + indent.writeln('*length = self->${fieldName}_length;'); + } + indent.writeln('return self->$fieldName;'); + }); + } + + indent.newln(); + indent.writeScoped( + 'static FlValue* ${methodPrefix}_to_list($className* self) {', '}', () { + indent.writeln('FlValue* values = fl_value_new_list();'); + for (final NamedType field in classDefinition.fields) { + final String fieldName = _getFieldName(field.name); + indent.writeln( + 'fl_value_append_take(values, ${_makeFlValue(root, module, field.type, 'self->$fieldName', lengthVariableName: 'self->${fieldName}_length')});'); + } + indent.writeln('return values;'); + }); + + indent.newln(); + indent.writeScoped( + 'static $className* ${methodPrefix}_new_from_list(FlValue* values) {', + '}', () { + final List args = []; + for (int i = 0; i < classDefinition.fields.length; i++) { + final NamedType field = classDefinition.fields[i]; + final String fieldName = _getFieldName(field.name); + final String fieldType = _getType(module, field.type); + final String fieldValue = _fromFlValue(module, field.type, 'value$i'); + indent + .writeln('FlValue* value$i = fl_value_get_list_value(values, $i);'); + args.add(fieldName); + if (_isNullablePrimitiveType(field.type)) { + indent.writeln('$fieldType $fieldName = nullptr;'); + indent.writeln( + '${_getType(module, field.type, isOutput: true, primitive: true)} ${fieldName}_value;'); + indent.writeScoped( + 'if (fl_value_get_type(value$i) != FL_VALUE_TYPE_NULL) {', '}', + () { + indent.writeln('${fieldName}_value = $fieldValue;'); + indent.writeln('$fieldName = &${fieldName}_value;'); + }); + } else if (field.type.isNullable) { + indent.writeln('$fieldType $fieldName = nullptr;'); + if (_isNumericListType(field.type)) { + indent.writeln('size_t ${fieldName}_length = 0;'); + args.add('${fieldName}_length'); + } + indent.writeScoped( + 'if (fl_value_get_type(value$i) != FL_VALUE_TYPE_NULL) {', '}', + () { + indent.writeln('$fieldName = $fieldValue;'); + if (_isNumericListType(field.type)) { + indent.writeln( + '${fieldName}_length = fl_value_get_length(value$i);'); + } + }); + } else { + indent.writeln('$fieldType $fieldName = $fieldValue;'); + if (_isNumericListType(field.type)) { + indent.writeln( + 'size_t ${fieldName}_length = fl_value_get_length(value$i);'); + args.add('${fieldName}_length'); + } + } + } + indent.writeln('return ${methodPrefix}_new(${args.join(', ')});'); + }); + } + + @override + void writeGeneralCodec( + GObjectOptions generatorOptions, + Root root, + Indent indent, { + required String dartPackageName, + }) { + final String module = _getModule(generatorOptions, dartPackageName); + final String codecClassName = _getClassName(module, _codecBaseName); + final String codecMethodPrefix = _getMethodPrefix(module, _codecBaseName); + + final Iterable customTypes = getEnumeratedTypes(root); + + indent.newln(); + _writeDeclareFinalType(indent, module, _codecBaseName, + parentClassName: 'FlStandardMessageCodec'); + + indent.newln(); + _writeObjectStruct(indent, module, _codecBaseName, () {}, + parentClassName: 'FlStandardMessageCodec'); + + indent.newln(); + _writeDefineType(indent, module, _codecBaseName, + parentType: 'fl_standard_message_codec_get_type()'); + + for (final EnumeratedType customType in customTypes) { + final String customTypeName = _getClassName(module, customType.name); + final String snakeCustomTypeName = + _snakeCaseFromCamelCase(customTypeName); + indent.newln(); + final String valueType = customType.type == CustomTypes.customClass + ? '$customTypeName*' + : 'FlValue*'; + indent.writeScoped( + 'static gboolean ${codecMethodPrefix}_write_$snakeCustomTypeName(FlStandardMessageCodec* codec, GByteArray* buffer, $valueType value, GError** error) {', + '}', () { + indent.writeln('uint8_t type = ${customType.enumeration};'); + indent.writeln('g_byte_array_append(buffer, &type, sizeof(uint8_t));'); + if (customType.type == CustomTypes.customClass) { + indent.writeln( + 'g_autoptr(FlValue) values = ${snakeCustomTypeName}_to_list(value);'); + indent.writeln( + 'return fl_standard_message_codec_write_value(codec, buffer, values, error);'); + } else if (customType.type == CustomTypes.customEnum) { + indent.writeln( + 'return fl_standard_message_codec_write_value(codec, buffer, value, error);'); + } + }); + } + + indent.newln(); + indent.writeScoped( + 'static gboolean ${codecMethodPrefix}_write_value(FlStandardMessageCodec* codec, GByteArray* buffer, FlValue* value, GError** error) {', + '}', () { + indent.writeScoped( + 'if (fl_value_get_type(value) == FL_VALUE_TYPE_CUSTOM) {', '}', () { + indent.writeScoped('switch (fl_value_get_custom_type(value)) {', '}', + () { + for (final EnumeratedType customType in customTypes) { + indent.writeln('case ${customType.enumeration}:'); + indent.nest(1, () { + final String customTypeName = + _getClassName(module, customType.name); + final String snakeCustomTypeName = + _snakeCaseFromCamelCase(customTypeName); + final String castMacro = + _getClassCastMacro(module, customType.name); + if (customType.type == CustomTypes.customClass) { + indent.writeln( + 'return ${codecMethodPrefix}_write_$snakeCustomTypeName(codec, buffer, $castMacro(fl_value_get_custom_value_object(value)), error);'); + } else if (customType.type == CustomTypes.customEnum) { + indent.writeln( + 'return ${codecMethodPrefix}_write_$snakeCustomTypeName(codec, buffer, reinterpret_cast(const_cast(fl_value_get_custom_value(value))), error);'); + } + }); + } + }); + }); + + indent.newln(); + indent.writeln( + 'return FL_STANDARD_MESSAGE_CODEC_CLASS(${codecMethodPrefix}_parent_class)->write_value(codec, buffer, value, error);'); + }); + + for (final EnumeratedType customType in customTypes) { + final String customTypeName = _getClassName(module, customType.name); + final String snakeCustomTypeName = + _snakeCaseFromCamelCase(customTypeName); + indent.newln(); + indent.writeScoped( + 'static FlValue* ${codecMethodPrefix}_read_$snakeCustomTypeName(FlStandardMessageCodec* codec, GBytes* buffer, size_t* offset, GError** error) {', + '}', () { + if (customType.type == CustomTypes.customClass) { + indent.writeln( + 'g_autoptr(FlValue) values = fl_standard_message_codec_read_value(codec, buffer, offset, error);'); + indent.writeScoped('if (values == nullptr) {', '}', () { + indent.writeln('return nullptr;'); + }); + indent.newln(); + indent.writeln( + 'g_autoptr($customTypeName) value = ${snakeCustomTypeName}_new_from_list(values);'); + indent.writeScoped('if (value == nullptr) {', '}', () { + indent.writeln( + 'g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED, "Invalid data received for MessageData");'); + indent.writeln('return nullptr;'); + }); + indent.newln(); + indent.writeln( + 'return fl_value_new_custom_object(${customType.enumeration}, G_OBJECT(value));'); + } else if (customType.type == CustomTypes.customEnum) { + indent.writeln( + 'return fl_value_new_custom(${customType.enumeration}, fl_standard_message_codec_read_value(codec, buffer, offset, error), (GDestroyNotify)fl_value_unref);'); + } + }); + } + + indent.newln(); + indent.writeScoped( + 'static FlValue* ${codecMethodPrefix}_read_value_of_type(FlStandardMessageCodec* codec, GBytes* buffer, size_t* offset, int type, GError** error) {', + '}', () { + indent.writeScoped('switch (type) {', '}', () { + for (final EnumeratedType customType in customTypes) { + final String customTypeName = _getClassName(module, customType.name); + final String snakeCustomTypeName = + _snakeCaseFromCamelCase(customTypeName); + indent.writeln('case ${customType.enumeration}:'); + indent.nest(1, () { + indent.writeln( + 'return ${codecMethodPrefix}_read_$snakeCustomTypeName(codec, buffer, offset, error);'); + }); + } + + indent.writeln('default:'); + indent.nest(1, () { + indent.writeln( + 'return FL_STANDARD_MESSAGE_CODEC_CLASS(${codecMethodPrefix}_parent_class)->read_value_of_type(codec, buffer, offset, type, error);'); + }); + }); + }); + + indent.newln(); + _writeInit(indent, module, _codecBaseName, () {}); + + indent.newln(); + _writeClassInit(indent, module, _codecBaseName, () { + indent.writeln( + 'FL_STANDARD_MESSAGE_CODEC_CLASS(klass)->write_value = ${codecMethodPrefix}_write_value;'); + indent.writeln( + 'FL_STANDARD_MESSAGE_CODEC_CLASS(klass)->read_value_of_type = ${codecMethodPrefix}_read_value_of_type;'); + }, hasDispose: false); + + indent.newln(); + indent.writeScoped( + 'static $codecClassName* ${codecMethodPrefix}_new() {', '}', () { + _writeObjectNew(indent, module, _codecBaseName); + indent.writeln('return self;'); + }); + } + + @override + void writeFlutterApi( + GObjectOptions generatorOptions, + Root root, + Indent indent, + Api api, { + required String dartPackageName, + }) { + final String module = _getModule(generatorOptions, dartPackageName); + final String className = _getClassName(module, api.name); + final String methodPrefix = _getMethodPrefix(module, api.name); + final String codecClassName = _getClassName(module, _codecBaseName); + final String codecMethodPrefix = _getMethodPrefix(module, _codecBaseName); + + indent.newln(); + _writeObjectStruct(indent, module, api.name, () { + indent.writeln('FlBinaryMessenger* messenger;'); + indent.writeln('gchar *suffix;'); + }); + + indent.newln(); + _writeDefineType(indent, module, api.name); + + indent.newln(); + _writeDispose(indent, module, api.name, () { + _writeCastSelf(indent, module, api.name, 'object'); + indent.writeln('g_clear_object(&self->messenger);'); + indent.writeln('g_clear_pointer(&self->suffix, g_free);'); + }); + + indent.newln(); + _writeInit(indent, module, api.name, () {}); + + indent.newln(); + _writeClassInit(indent, module, api.name, () {}); + + indent.newln(); + indent.writeScoped( + '$className* ${methodPrefix}_new(FlBinaryMessenger* messenger, const gchar* suffix) {', + '}', () { + _writeObjectNew(indent, module, api.name); + indent.writeln( + 'self->messenger = FL_BINARY_MESSENGER(g_object_ref(messenger));'); + indent.writeln( + 'self->suffix = suffix != nullptr ? g_strdup_printf(".%s", suffix) : g_strdup("");'); + indent.writeln('return self;'); + }); + + for (final Method method in api.methods) { + final String methodName = _getMethodName(method.name); + final String responseName = _getResponseName(api.name, method.name); + final String responseClassName = _getClassName(module, responseName); + final String responseMethodPrefix = + _getMethodPrefix(module, responseName); + final String testResponseMacro = + '${_snakeCaseFromCamelCase(module)}_IS_${_snakeCaseFromCamelCase(responseName)}' + .toUpperCase(); + + indent.newln(); + _writeObjectStruct(indent, module, responseName, () { + indent.writeln('FlValue* error;'); + if (!method.returnType.isVoid) { + indent.writeln('FlValue* return_value;'); + if (_isNullablePrimitiveType(method.returnType)) { + final String primitiveType = + _getType(module, method.returnType, primitive: true); + indent.writeln('$primitiveType return_value_;'); + } + } + }); + + indent.newln(); + _writeDefineType(indent, module, responseName); + + indent.newln(); + _writeDispose(indent, module, responseName, () { + _writeCastSelf(indent, module, responseName, 'object'); + indent.writeln('g_clear_pointer(&self->error, fl_value_unref);'); + if (!method.returnType.isVoid) { + indent + .writeln('g_clear_pointer(&self->return_value, fl_value_unref);'); + } + }); + + indent.newln(); + _writeInit(indent, module, responseName, () {}); + + indent.newln(); + _writeClassInit(indent, module, responseName, () {}); + + indent.newln(); + indent.writeScoped( + 'static $responseClassName* ${responseMethodPrefix}_new(FlValue* response) {', + '}', () { + _writeObjectNew(indent, module, responseName); + indent.writeScoped('if (fl_value_get_length(response) > 1) {', '}', () { + indent.writeln('self->error = fl_value_ref(response);'); + }); + if (!method.returnType.isVoid) { + indent.writeScoped('else {', '}', () { + indent.writeln( + 'FlValue* value = fl_value_get_list_value(response, 0);'); + indent.writeln('self->return_value = fl_value_ref(value);'); + }); + } + indent.writeln('return self;'); + }); + + indent.newln(); + indent.writeScoped( + 'gboolean ${responseMethodPrefix}_is_error($responseClassName* self) {', + '}', () { + indent + .writeln('g_return_val_if_fail($testResponseMacro(self), FALSE);'); + indent.writeln('return self->error != nullptr;'); + }); + + indent.newln(); + indent.writeScoped( + 'const gchar* ${responseMethodPrefix}_get_error_code($responseClassName* self) {', + '}', () { + indent.writeln( + 'g_return_val_if_fail($testResponseMacro(self), nullptr);'); + indent.writeln('g_assert(${responseMethodPrefix}_is_error(self));'); + indent.writeln( + 'return fl_value_get_string(fl_value_get_list_value(self->error, 0));'); + }); + + indent.newln(); + indent.writeScoped( + 'const gchar* ${responseMethodPrefix}_get_error_message($responseClassName* self) {', + '}', () { + indent.writeln( + 'g_return_val_if_fail($testResponseMacro(self), nullptr);'); + indent.writeln('g_assert(${responseMethodPrefix}_is_error(self));'); + indent.writeln( + 'return fl_value_get_string(fl_value_get_list_value(self->error, 1));'); + }); + + indent.newln(); + indent.writeScoped( + 'FlValue* ${responseMethodPrefix}_get_error_details($responseClassName* self) {', + '}', () { + indent.writeln( + 'g_return_val_if_fail($testResponseMacro(self), nullptr);'); + indent.writeln('g_assert(${responseMethodPrefix}_is_error(self));'); + indent.writeln('return fl_value_get_list_value(self->error, 2);'); + }); + + if (!method.returnType.isVoid) { + final String primitiveType = + _getType(module, method.returnType, primitive: true); + + indent.newln(); + final String returnType = _isNullablePrimitiveType(method.returnType) + ? '$primitiveType*' + : primitiveType; + indent.writeScoped( + '$returnType ${responseMethodPrefix}_get_return_value($responseClassName* self${_isNumericListType(method.returnType) ? ', size_t* return_value_length' : ''}) {', + '}', () { + indent.writeln( + 'g_return_val_if_fail($testResponseMacro(self), ${_getDefaultValue(module, method.returnType)});'); + indent.writeln('g_assert(!${responseMethodPrefix}_is_error(self));'); + if (method.returnType.isNullable) { + indent.writeScoped( + 'if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) {', + '}', () { + indent.writeln('return nullptr;'); + }); + } + if (_isNumericListType(method.returnType)) { + indent.writeScoped('if (return_value_length != nullptr) {', '}', + () { + indent.writeln( + '*return_value_length = fl_value_get_length(self->return_value);'); + }); + } + if (_isNullablePrimitiveType(method.returnType)) { + indent.writeln( + 'self->return_value_ = ${_fromFlValue(module, method.returnType, 'self->return_value')};'); + indent.writeln('return &self->return_value_;'); + } else { + indent.writeln( + 'return ${_fromFlValue(module, method.returnType, 'self->return_value')};'); + } + }); + } + + indent.newln(); + indent.writeScoped( + 'static void ${methodPrefix}_${methodName}_cb(GObject* object, GAsyncResult* result, gpointer user_data) {', + '}', () { + indent.writeln('GTask* task = G_TASK(user_data);'); + indent.writeln('g_task_return_pointer(task, result, g_object_unref);'); + }); + + final List asyncArgs = ['$className* self']; + for (final Parameter param in method.parameters) { + final String name = _snakeCaseFromCamelCase(param.name); + asyncArgs.add('${_getType(module, param.type)} $name'); + if (_isNumericListType(param.type)) { + asyncArgs.add('size_t ${name}_length'); + } + } + asyncArgs.addAll([ + 'GCancellable* cancellable', + 'GAsyncReadyCallback callback', + 'gpointer user_data', + ]); + indent.newln(); + indent.writeScoped( + "void ${methodPrefix}_$methodName(${asyncArgs.join(', ')}) {", '}', + () { + indent.writeln('g_autoptr(FlValue) args = fl_value_new_list();'); + for (final Parameter param in method.parameters) { + final String name = _snakeCaseFromCamelCase(param.name); + final String value = _makeFlValue(root, module, param.type, name, + lengthVariableName: '${name}_length'); + indent.writeln('fl_value_append_take(args, $value);'); + } + final String channelName = + makeChannelName(api, method, dartPackageName); + indent.writeln( + 'g_autofree gchar* channel_name = g_strdup_printf("$channelName%s", self->suffix);'); + indent.writeln( + 'g_autoptr($codecClassName) codec = ${codecMethodPrefix}_new();'); + indent.writeln( + 'FlBasicMessageChannel* channel = fl_basic_message_channel_new(self->messenger, channel_name, FL_MESSAGE_CODEC(codec));'); + indent.writeln( + 'GTask* task = g_task_new(self, cancellable, callback, user_data);'); + indent.writeln('g_task_set_task_data(task, channel, g_object_unref);'); + indent.writeln( + 'fl_basic_message_channel_send(channel, args, cancellable, ${methodPrefix}_${methodName}_cb, task);'); + }); + + final List finishArgs = [ + '$className* self', + 'GAsyncResult* result', + 'GError** error', + ]; + indent.newln(); + indent.writeScoped( + "$responseClassName* ${methodPrefix}_${methodName}_finish(${finishArgs.join(', ')}) {", + '}', () { + indent.writeln('g_autoptr(GTask) task = G_TASK(result);'); + indent.writeln( + 'GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr));'); + indent.writeln( + 'FlBasicMessageChannel* channel = FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task));'); + indent.writeln( + 'g_autoptr(FlValue) response = fl_basic_message_channel_send_finish(channel, r, error);'); + indent.writeScoped('if (response == nullptr) { ', '}', () { + indent.writeln('return nullptr;'); + }); + indent.writeln('return ${responseMethodPrefix}_new(response);'); + }); + } + } + + @override + void writeHostApi( + GObjectOptions generatorOptions, + Root root, + Indent indent, + Api api, { + required String dartPackageName, + }) { + final String module = _getModule(generatorOptions, dartPackageName); + final String className = _getClassName(module, api.name); + + final String methodPrefix = _getMethodPrefix(module, api.name); + final String vtableName = _getVTableName(module, api.name); + + final String codecClassName = _getClassName(module, _codecBaseName); + final String codecMethodPrefix = _getMethodPrefix(module, _codecBaseName); + + final bool hasAsyncMethod = + api.methods.any((Method method) => method.isAsynchronous); + if (hasAsyncMethod) { + indent.newln(); + _writeObjectStruct(indent, module, '${api.name}ResponseHandle', () { + indent.writeln('FlBasicMessageChannel* channel;'); + indent.writeln('FlBasicMessageChannelResponseHandle* response_handle;'); + }); + + indent.newln(); + _writeDefineType(indent, module, '${api.name}ResponseHandle'); + + indent.newln(); + _writeDispose(indent, module, '${api.name}ResponseHandle', () { + _writeCastSelf(indent, module, '${api.name}ResponseHandle', 'object'); + indent.writeln('g_clear_object(&self->channel);'); + indent.writeln('g_clear_object(&self->response_handle);'); + }); + + indent.newln(); + _writeInit(indent, module, '${api.name}ResponseHandle', () {}); + + indent.newln(); + _writeClassInit(indent, module, '${api.name}ResponseHandle', () {}); + + indent.newln(); + indent.writeScoped( + 'static ${className}ResponseHandle* ${methodPrefix}_response_handle_new(FlBasicMessageChannel* channel, FlBasicMessageChannelResponseHandle* response_handle) {', + '}', () { + _writeObjectNew(indent, module, '${api.name}ResponseHandle'); + indent.writeln( + 'self->channel = FL_BASIC_MESSAGE_CHANNEL(g_object_ref(channel));'); + indent.writeln( + 'self->response_handle = FL_BASIC_MESSAGE_CHANNEL_RESPONSE_HANDLE(g_object_ref(response_handle));'); + indent.writeln('return self;'); + }); + } + + for (final Method method in api.methods) { + final String responseName = _getResponseName(api.name, method.name); + final String responseClassName = _getClassName(module, responseName); + final String responseMethodPrefix = + _getMethodPrefix(module, responseName); + + if (method.isAsynchronous) { + indent.newln(); + _writeDeclareFinalType(indent, module, responseName); + } + + indent.newln(); + _writeObjectStruct(indent, module, responseName, () { + indent.writeln('FlValue* value;'); + }); + + indent.newln(); + _writeDefineType(indent, module, responseName); + + indent.newln(); + _writeDispose(indent, module, responseName, () { + _writeCastSelf(indent, module, responseName, 'object'); + indent.writeln('g_clear_pointer(&self->value, fl_value_unref);'); + }); + + indent.newln(); + _writeInit(indent, module, responseName, () {}); + + indent.newln(); + _writeClassInit(indent, module, responseName, () {}); + + final String returnType = _getType(module, method.returnType); + indent.newln(); + final List constructorArgs = [ + if (returnType != 'void') '$returnType return_value', + if (_isNumericListType(method.returnType)) 'size_t return_value_length' + ]; + indent.writeScoped( + "${method.isAsynchronous ? 'static ' : ''}$responseClassName* ${responseMethodPrefix}_new(${constructorArgs.join(', ')}) {", + '}', () { + _writeObjectNew(indent, module, responseName); + indent.writeln('self->value = fl_value_new_list();'); + indent.writeln( + "fl_value_append_take(self->value, ${_makeFlValue(root, module, method.returnType, 'return_value', lengthVariableName: 'return_value_length')});"); + indent.writeln('return self;'); + }); + + indent.newln(); + indent.writeScoped( + '${method.isAsynchronous ? 'static ' : ''}$responseClassName* ${responseMethodPrefix}_new_error(const gchar* code, const gchar* message, FlValue* details) {', + '}', () { + _writeObjectNew(indent, module, responseName); + indent.writeln('self->value = fl_value_new_list();'); + indent.writeln( + 'fl_value_append_take(self->value, fl_value_new_string(code));'); + indent.writeln( + 'fl_value_append_take(self->value, fl_value_new_string(message != nullptr ? message : ""));'); + indent.writeln( + 'fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) : fl_value_new_null());'); + indent.writeln('return self;'); + }); + } + + indent.newln(); + _writeDeclareFinalType(indent, module, api.name); + + indent.newln(); + _writeObjectStruct(indent, module, api.name, () { + indent.writeln('const ${className}VTable* vtable;'); + indent.writeln('gpointer user_data;'); + indent.writeln('GDestroyNotify user_data_free_func;'); + }); + + indent.newln(); + _writeDefineType(indent, module, api.name); + + indent.newln(); + _writeDispose(indent, module, api.name, () { + _writeCastSelf(indent, module, api.name, 'object'); + indent.writeScoped('if (self->user_data != nullptr) {', '}', () { + indent.writeln('self->user_data_free_func(self->user_data);'); + }); + indent.writeln('self->user_data = nullptr;'); + }); + + indent.newln(); + _writeInit(indent, module, api.name, () {}); + + indent.newln(); + _writeClassInit(indent, module, api.name, () {}); + + indent.newln(); + indent.writeScoped( + 'static $className* ${methodPrefix}_new(const $vtableName* vtable, gpointer user_data, GDestroyNotify user_data_free_func) {', + '}', () { + _writeObjectNew(indent, module, api.name); + indent.writeln('self->vtable = vtable;'); + indent.writeln('self->user_data = user_data;'); + indent.writeln('self->user_data_free_func = user_data_free_func;'); + indent.writeln('return self;'); + }); + + for (final Method method in api.methods) { + final String methodName = _getMethodName(method.name); + final String responseName = _getResponseName(api.name, method.name); + final String responseClassName = _getClassName(module, responseName); + + indent.newln(); + indent.writeScoped( + 'static void ${methodPrefix}_${methodName}_cb(FlBasicMessageChannel* channel, FlValue* message_, FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) {', + '}', () { + _writeCastSelf(indent, module, api.name, 'user_data'); + + indent.newln(); + indent.writeScoped( + 'if (self->vtable == nullptr || self->vtable->$methodName == nullptr) {', + '}', () { + indent.writeln('return;'); + }); + + indent.newln(); + final List methodArgs = []; + for (int i = 0; i < method.parameters.length; i++) { + final Parameter param = method.parameters[i]; + final String paramName = _snakeCaseFromCamelCase(param.name); + final String paramType = _getType(module, param.type); + indent.writeln( + 'FlValue* value$i = fl_value_get_list_value(message_, $i);'); + if (_isNullablePrimitiveType(param.type)) { + final String primitiveType = + _getType(module, param.type, primitive: true); + indent.writeln('$paramType $paramName = nullptr;'); + indent.writeln('$primitiveType ${paramName}_value;'); + indent.writeScoped( + 'if (fl_value_get_type(value$i) != FL_VALUE_TYPE_NULL) {', '}', + () { + final String paramValue = + _fromFlValue(module, method.parameters[i].type, 'value$i'); + indent.writeln('${paramName}_value = $paramValue;'); + indent.writeln('$paramName = &${paramName}_value;'); + }); + } else { + final String paramValue = + _fromFlValue(module, method.parameters[i].type, 'value$i'); + indent.writeln('$paramType $paramName = $paramValue;'); + } + methodArgs.add(paramName); + if (_isNumericListType(method.parameters[i].type)) { + indent.writeln( + 'size_t ${paramName}_length = fl_value_get_length(value$i);'); + methodArgs.add('${paramName}_length'); + } + } + if (method.isAsynchronous) { + final List vfuncArgs = []; + vfuncArgs.addAll(methodArgs); + vfuncArgs.addAll(['handle', 'self->user_data']); + indent.writeln( + 'g_autoptr(${className}ResponseHandle) handle = ${methodPrefix}_response_handle_new(channel, response_handle);'); + indent.writeln("self->vtable->$methodName(${vfuncArgs.join(', ')});"); + } else { + final List vfuncArgs = []; + vfuncArgs.addAll(methodArgs); + vfuncArgs.add('self->user_data'); + indent.writeln( + "g_autoptr($responseClassName) response = self->vtable->$methodName(${vfuncArgs.join(', ')});"); + indent.writeScoped('if (response == nullptr) {', '}', () { + indent.writeln( + 'g_warning("No response returned to %s.%s", "${api.name}", "${method.name}");'); + indent.writeln('return;'); + }); + + indent.newln(); + indent.writeln('g_autoptr(GError) error = NULL;'); + indent.writeScoped( + 'if (!fl_basic_message_channel_respond(channel, response_handle, response->value, &error)) {', + '}', () { + indent.writeln( + 'g_warning("Failed to send response to %s.%s: %s", "${api.name}", "${method.name}", error->message);'); + }); + } + }); + } + + indent.newln(); + indent.writeScoped( + 'void ${methodPrefix}_set_method_handlers(FlBinaryMessenger* messenger, const gchar* suffix, const $vtableName* vtable, gpointer user_data, GDestroyNotify user_data_free_func) {', + '}', () { + indent.writeln( + 'g_autofree gchar* dot_suffix = suffix != nullptr ? g_strdup_printf(".%s", suffix) : g_strdup("");'); + indent.writeln( + 'g_autoptr($className) api_data = ${methodPrefix}_new(vtable, user_data, user_data_free_func);'); + + indent.newln(); + indent.writeln( + 'g_autoptr($codecClassName) codec = ${codecMethodPrefix}_new();'); + for (final Method method in api.methods) { + final String methodName = _getMethodName(method.name); + final String channelName = + makeChannelName(api, method, dartPackageName); + indent.writeln( + 'g_autofree gchar* ${methodName}_channel_name = g_strdup_printf("$channelName%s", dot_suffix);'); + indent.writeln( + 'g_autoptr(FlBasicMessageChannel) ${methodName}_channel = fl_basic_message_channel_new(messenger, ${methodName}_channel_name, FL_MESSAGE_CODEC(codec));'); + indent.writeln( + 'fl_basic_message_channel_set_message_handler(${methodName}_channel, ${methodPrefix}_${methodName}_cb, g_object_ref(api_data), g_object_unref);'); + } + }); + + indent.newln(); + indent.writeScoped( + 'void ${methodPrefix}_clear_method_handlers(FlBinaryMessenger* messenger, const gchar* suffix) {', + '}', () { + indent.writeln( + 'g_autofree gchar* dot_suffix = suffix != nullptr ? g_strdup_printf(".%s", suffix) : g_strdup("");'); + + indent.newln(); + indent.writeln( + 'g_autoptr($codecClassName) codec = ${codecMethodPrefix}_new();'); + for (final Method method in api.methods) { + final String methodName = _getMethodName(method.name); + final String channelName = + makeChannelName(api, method, dartPackageName); + indent.writeln( + 'g_autofree gchar* ${methodName}_channel_name = g_strdup_printf("$channelName%s", dot_suffix);'); + indent.writeln( + 'g_autoptr(FlBasicMessageChannel) ${methodName}_channel = fl_basic_message_channel_new(messenger, ${methodName}_channel_name, FL_MESSAGE_CODEC(codec));'); + indent.writeln( + 'fl_basic_message_channel_set_message_handler(${methodName}_channel, nullptr, nullptr, nullptr);'); + } + }); + + for (final Method method + in api.methods.where((Method method) => method.isAsynchronous)) { + final String returnType = _getType(module, method.returnType); + final String methodName = _getMethodName(method.name); + final String responseName = _getResponseName(api.name, method.name); + final String responseClassName = _getClassName(module, responseName); + final String responseMethodPrefix = + _getMethodPrefix(module, responseName); + + indent.newln(); + final List respondArgs = [ + '${className}ResponseHandle* response_handle', + if (returnType != 'void') '$returnType return_value', + if (_isNumericListType(method.returnType)) 'size_t return_value_length' + ]; + indent.writeScoped( + "void ${methodPrefix}_respond_$methodName(${respondArgs.join(', ')}) {", + '}', () { + final List returnArgs = [ + if (returnType != 'void') 'return_value', + if (_isNumericListType(method.returnType)) 'return_value_length' + ]; + indent.writeln( + 'g_autoptr($responseClassName) response = ${responseMethodPrefix}_new(${returnArgs.join(', ')});'); + indent.writeln('g_autoptr(GError) error = nullptr;'); + indent.writeScoped( + 'if (!fl_basic_message_channel_respond(response_handle->channel, response_handle->response_handle, response->value, &error)) {', + '}', () { + indent.writeln( + 'g_warning("Failed to send response to %s.%s: %s", "${api.name}", "${method.name}", error->message);'); + }); + }); + + indent.newln(); + final List respondErrorArgs = [ + '${className}ResponseHandle* response_handle', + 'const gchar* code', + 'const gchar* message', + 'FlValue* details' + ]; + indent.writeScoped( + "void ${methodPrefix}_respond_error_$methodName(${respondErrorArgs.join(', ')}) {", + '}', () { + indent.writeln( + 'g_autoptr($responseClassName) response = ${responseMethodPrefix}_new_error(code, message, details);'); + indent.writeln('g_autoptr(GError) error = nullptr;'); + indent.writeScoped( + 'if (!fl_basic_message_channel_respond(response_handle->channel, response_handle->response_handle, response->value, &error)) {', + '}', () { + indent.writeln( + 'g_warning("Failed to send response to %s.%s: %s", "${api.name}", "${method.name}", error->message);'); + }); + }); + } + } +} + +// Returns the module name to use. +String _getModule(GObjectOptions generatorOptions, String dartPackageName) { + return generatorOptions.module ?? _camelCaseFromSnakeCase(dartPackageName); +} + +// Returns the header guard defintion for [headerFileName]. +String _getGuardName(String? headerFileName) { + const String prefix = 'PIGEON_'; + if (headerFileName != null) { + return '$prefix${headerFileName.replaceAll('.', '_').toUpperCase()}_'; + } else { + return '${prefix}H_'; + } +} + +// Writes the GObject macro to generate a new type. +void _writeDeclareFinalType(Indent indent, String module, String name, + {String parentClassName = 'GObject'}) { + final String upperModule = _snakeCaseFromCamelCase(module).toUpperCase(); + final String className = _getClassName(module, name); + final String snakeClassName = _snakeCaseFromCamelCase(name); + final String upperSnakeClassName = snakeClassName.toUpperCase(); + final String methodPrefix = _getMethodPrefix(module, name); + + indent.writeln( + 'G_DECLARE_FINAL_TYPE($className, $methodPrefix, $upperModule, $upperSnakeClassName, $parentClassName)'); +} + +// Writes the GObject macro to define a new type. +void _writeDefineType(Indent indent, String module, String name, + {String parentType = 'G_TYPE_OBJECT'}) { + final String className = _getClassName(module, name); + final String methodPrefix = _getMethodPrefix(module, name); + + indent.writeln('G_DEFINE_TYPE($className, $methodPrefix, $parentType)'); +} + +// Writes the struct for a GObject. +void _writeObjectStruct( + Indent indent, String module, String name, void Function() func, + {String parentClassName = 'GObject'}) { + final String className = _getClassName(module, name); + + indent.writeScoped('struct _$className {', '};', () { + indent.writeln('$parentClassName parent_instance;'); + indent.newln(); + + func(); + }); +} + +// Writes the dispose method for a GObject. +void _writeDispose( + Indent indent, String module, String name, void Function() func) { + final String methodPrefix = _getMethodPrefix(module, name); + + indent.writeScoped( + 'static void ${methodPrefix}_dispose(GObject* object) {', '}', () { + func(); + indent.writeln( + 'G_OBJECT_CLASS(${methodPrefix}_parent_class)->dispose(object);'); + }); +} + +// Writes the init function for a GObject. +void _writeInit( + Indent indent, String module, String name, void Function() func) { + final String className = _getClassName(module, name); + final String methodPrefix = _getMethodPrefix(module, name); + + indent.writeScoped( + 'static void ${methodPrefix}_init($className* self) {', '}', () { + func(); + }); +} + +// Writes the class init function for a GObject. +void _writeClassInit( + Indent indent, String module, String name, void Function() func, + {bool hasDispose = true}) { + final String className = _getClassName(module, name); + final String methodPrefix = _getMethodPrefix(module, name); + + indent.writeScoped( + 'static void ${methodPrefix}_class_init(${className}Class* klass) {', '}', + () { + if (hasDispose) { + indent + .writeln('G_OBJECT_CLASS(klass)->dispose = ${methodPrefix}_dispose;'); + } + func(); + }); +} + +// Writes the constructor for a GObject. +void _writeObjectNew(Indent indent, String module, String name) { + final String className = _getClassName(module, name); + final String methodPrefix = _getMethodPrefix(module, name); + final String castMacro = _getClassCastMacro(module, name); + + indent.writeln( + '$className* self = $castMacro(g_object_new(${methodPrefix}_get_type(), nullptr));'); +} + +// Writes the cast used at the top of GObject methods. +void _writeCastSelf( + Indent indent, String module, String name, String variableName) { + final String className = _getClassName(module, name); + final String castMacro = _getClassCastMacro(module, name); + indent.writeln('$className* self = $castMacro($variableName);'); +} + +// Converts a string from CamelCase to snake_case. +String _snakeCaseFromCamelCase(String camelCase) { + return camelCase.replaceAllMapped(RegExp(r'[A-Z]'), + (Match m) => '${m.start == 0 ? '' : '_'}${m[0]!.toLowerCase()}'); +} + +// Converts a string from snake_case to CamelCase +String _camelCaseFromSnakeCase(String snakeCase) { + return snakeCase + .split('_') + .map((String v) => v[0].toUpperCase() + v.substring(1)) + .join(); +} + +// Returns the GObject class name for [name]. +String _getClassName(String module, String name) { + return '$module$name'; +} + +// Returns the name to use for a class field with [name]. +String _getFieldName(String name) { + final List reservedNames = ['type']; + if (reservedNames.contains(name)) { + name += '_'; + } + return _snakeCaseFromCamelCase(name); +} + +// Returns the name to user for a class method with [name] +String _getMethodName(String name) { + final List reservedNames = ['new', 'get_type']; + if (reservedNames.contains(name)) { + name += '_'; + } + return _snakeCaseFromCamelCase(name); +} + +/// Return the name of the VTable structure to use for API requests. +String _getVTableName(String module, String name) { + final String className = _getClassName(module, name); + return '${className}VTable'; +} + +// Returns the GObject macro to cast a GObject to a class of [name]. +String _getClassCastMacro(String module, String name) { + final String className = _getClassName(module, name); + final String snakeClassName = _snakeCaseFromCamelCase(className); + return snakeClassName.toUpperCase(); +} + +// Returns the prefix used for methods in class [name]. +String _getMethodPrefix(String module, String name) { + final String className = _getClassName(module, name); + return _snakeCaseFromCamelCase(className); +} + +// Returns an enumeration value in C++ form. +String _getEnumValue(String module, String enumName, String memberName) { + final String snakeEnumName = _snakeCaseFromCamelCase(enumName); + final String snakeMemberName = _snakeCaseFromCamelCase(memberName); + return '${module}_${snakeEnumName}_$snakeMemberName'.toUpperCase(); +} + +// Returns code for storing a value of [type]. +String _getType(String module, TypeDeclaration type, + {bool isOutput = false, bool primitive = false}) { + if (type.isClass) { + return '${_getClassName(module, type.baseName)}*'; + } else if (type.isEnum) { + final String name = _getClassName(module, type.baseName); + return type.isNullable && !primitive ? '$name*' : name; + } else if (_isFlValueWrappedType(type)) { + return 'FlValue*'; + } else if (type.baseName == 'void') { + return 'void'; + } else if (type.baseName == 'bool') { + return type.isNullable && !primitive ? 'gboolean*' : 'gboolean'; + } else if (type.baseName == 'int') { + return type.isNullable && !primitive ? 'int64_t*' : 'int64_t'; + } else if (type.baseName == 'double') { + return type.isNullable && !primitive ? 'double*' : 'double'; + } else if (type.baseName == 'String') { + return isOutput ? 'gchar*' : 'const gchar*'; + } else if (type.baseName == 'Uint8List') { + return isOutput ? 'uint8_t*' : 'const uint8_t*'; + } else if (type.baseName == 'Int32List') { + return isOutput ? 'int32_t*' : 'const int32_t*'; + } else if (type.baseName == 'Int64List') { + return isOutput ? 'int64_t*' : 'const int64_t*'; + } else if (type.baseName == 'Float32List') { + return isOutput ? 'float*' : 'const float*'; + } else if (type.baseName == 'Float64List') { + return isOutput ? 'double*' : 'const double*'; + } else { + throw Exception('Unknown type ${type.baseName}'); + } +} + +// Returns true if [type] is a *List typed numeric list type. +bool _isNumericListType(TypeDeclaration type) { + return type.baseName == 'Uint8List' || + type.baseName == 'Int32List' || + type.baseName == 'Int64List' || + type.baseName == 'Float32List' || + type.baseName == 'Float64List'; +} + +// Returns true if [type] is a nullable type with a primitive native data type. +bool _isNullablePrimitiveType(TypeDeclaration type) { + if (!type.isNullable) { + return false; + } + + return type.isEnum || + type.baseName == 'bool' || + type.baseName == 'int' || + type.baseName == 'double'; +} + +// Whether [type] is a type that needs to stay an FlValue* since it can't be +// expressed as a more concrete type. +bool _isFlValueWrappedType(TypeDeclaration type) { + return type.baseName == 'List' || + type.baseName == 'Map' || + type.baseName == 'Object'; +} + +// Returns code to clear a value stored in [variableName], or null if no function required. +String? _getClearFunction(TypeDeclaration type, String variableName) { + if (type.isClass) { + return 'g_clear_object(&$variableName)'; + } else if (_isFlValueWrappedType(type)) { + return 'g_clear_pointer(&$variableName, fl_value_unref)'; + } else if (type.baseName == 'String') { + return 'g_clear_pointer(&$variableName, g_free)'; + } else if (_isNullablePrimitiveType(type)) { + return 'g_clear_pointer(&$variableName, g_free)'; + } else { + return null; + } +} + +// Returns code for the default value for [type]. +String _getDefaultValue(String module, TypeDeclaration type, + {bool primitive = false}) { + if (type.isClass || (type.isNullable && !primitive)) { + return 'nullptr'; + } else if (type.isEnum) { + final String enumName = _getClassName(module, type.baseName); + return 'static_cast<$enumName>(0)'; + } else if (_isFlValueWrappedType(type)) { + return 'nullptr'; + } else if (type.baseName == 'void') { + return ''; + } else if (type.baseName == 'bool') { + return 'FALSE'; + } else if (type.baseName == 'int') { + return '0'; + } else if (type.baseName == 'double') { + return '0.0'; + } else if (type.baseName == 'String') { + return 'nullptr'; + } else if (_isNumericListType(type)) { + return 'nullptr'; + } else { + throw Exception('Unknown type ${type.baseName}'); + } +} + +// Returns code to copy the native data type stored in [variableName]. +// +// [lengthVariableName] must be provided for the typed numeric *List types. +String _referenceValue(String module, TypeDeclaration type, String variableName, + {String? lengthVariableName}) { + if (type.isClass) { + final String castMacro = _getClassCastMacro(module, type.baseName); + return '$castMacro(g_object_ref($variableName))'; + } else if (_isFlValueWrappedType(type)) { + return 'fl_value_ref($variableName)'; + } else if (type.baseName == 'String') { + return 'g_strdup($variableName)'; + } else if (type.baseName == 'Uint8List') { + return 'static_cast(memcpy(malloc($lengthVariableName), $variableName, $lengthVariableName))'; + } else if (type.baseName == 'Int32List') { + return 'static_cast(memcpy(malloc(sizeof(int32_t) * $lengthVariableName), $variableName, sizeof(int32_t) * $lengthVariableName))'; + } else if (type.baseName == 'Int64List') { + return 'static_cast(memcpy(malloc(sizeof(int64_t) * $lengthVariableName), $variableName, sizeof(int64_t) * $lengthVariableName))'; + } else if (type.baseName == 'Float32List') { + return 'static_cast(memcpy(malloc(sizeof(float) * $lengthVariableName), $variableName, sizeof(float) * $lengthVariableName))'; + } else if (type.baseName == 'Float64List') { + return 'static_cast(memcpy(malloc(sizeof(double) * $lengthVariableName), $variableName, sizeof(double) * $lengthVariableName))'; + } else { + return variableName; + } +} + +int _getTypeEnumeration(Root root, TypeDeclaration type) { + return getEnumeratedTypes(root) + .firstWhere((EnumeratedType t) => + (type.isClass && t.associatedClass == type.associatedClass) || + (type.isEnum && t.associatedEnum == type.associatedEnum)) + .enumeration; +} + +// Returns code to convert the native data type stored in [variableName] to a FlValue. +// +// [lengthVariableName] must be provided for the typed numeric *List types. +String _makeFlValue( + Root root, String module, TypeDeclaration type, String variableName, + {String? lengthVariableName}) { + final String value; + if (type.isClass) { + final int enumeration = _getTypeEnumeration(root, type); + value = 'fl_value_new_custom_object($enumeration, G_OBJECT($variableName))'; + } else if (type.isEnum) { + final int enumeration = _getTypeEnumeration(root, type); + value = + 'fl_value_new_custom($enumeration, fl_value_new_int(${type.isNullable ? '*$variableName' : variableName}), (GDestroyNotify)fl_value_unref)'; + } else if (_isFlValueWrappedType(type)) { + value = 'fl_value_ref($variableName)'; + } else if (type.baseName == 'void') { + value = 'fl_value_new_null()'; + } else if (type.baseName == 'bool') { + value = type.isNullable + ? 'fl_value_new_bool(*$variableName)' + : 'fl_value_new_bool($variableName)'; + } else if (type.baseName == 'int') { + value = type.isNullable + ? 'fl_value_new_int(*$variableName)' + : 'fl_value_new_int($variableName)'; + } else if (type.baseName == 'double') { + value = type.isNullable + ? 'fl_value_new_float(*$variableName)' + : 'fl_value_new_float($variableName)'; + } else if (type.baseName == 'String') { + value = 'fl_value_new_string($variableName)'; + } else if (type.baseName == 'Uint8List') { + value = 'fl_value_new_uint8_list($variableName, $lengthVariableName)'; + } else if (type.baseName == 'Int32List') { + value = 'fl_value_new_int32_list($variableName, $lengthVariableName)'; + } else if (type.baseName == 'Int64List') { + value = 'fl_value_new_int64_list($variableName, $lengthVariableName)'; + } else if (type.baseName == 'Float32List') { + value = 'fl_value_new_float32_list($variableName, $lengthVariableName)'; + } else if (type.baseName == 'Float64List') { + value = 'fl_value_new_float_list($variableName, $lengthVariableName)'; + } else { + throw Exception('Unknown type ${type.baseName}'); + } + + if (type.isNullable) { + return '$variableName != nullptr ? $value : fl_value_new_null()'; + } else { + return value; + } +} + +// Returns code to convert the FlValue stored in [variableName] to a native data type. +String _fromFlValue(String module, TypeDeclaration type, String variableName) { + if (type.isClass) { + final String castMacro = _getClassCastMacro(module, type.baseName); + return '$castMacro(fl_value_get_custom_value_object($variableName))'; + } else if (type.isEnum) { + final String enumName = _getClassName(module, type.baseName); + return 'static_cast<$enumName>(fl_value_get_int(reinterpret_cast(const_cast(fl_value_get_custom_value($variableName)))))'; + } else if (_isFlValueWrappedType(type)) { + return variableName; + } else if (type.baseName == 'bool') { + return 'fl_value_get_bool($variableName)'; + } else if (type.baseName == 'int') { + return 'fl_value_get_int($variableName)'; + } else if (type.baseName == 'double') { + return 'fl_value_get_float($variableName)'; + } else if (type.baseName == 'String') { + return 'fl_value_get_string($variableName)'; + } else if (type.baseName == 'Uint8List') { + return 'fl_value_get_uint8_list($variableName)'; + } else if (type.baseName == 'Int32List') { + return 'fl_value_get_int32_list($variableName)'; + } else if (type.baseName == 'Int64List') { + return 'fl_value_get_int64_list($variableName)'; + } else if (type.baseName == 'Float32List') { + return 'fl_value_get_float32_list($variableName)'; + } else if (type.baseName == 'Float64List') { + return 'fl_value_get_float_list($variableName)'; + } else { + throw Exception('Unknown type ${type.baseName}'); + } +} + +// Returns the name of a GObject class used to send responses to [methodName]. +String _getResponseName(String name, String methodName) { + final String upperMethodName = + methodName[0].toUpperCase() + methodName.substring(1); + return '$name${upperMethodName}Response'; +} diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index 55622995b714..27a1a5915e78 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -28,6 +28,8 @@ const DocumentCommentSpecification _docCommentSpec = /// The standard codec for Flutter, used for any non custom codecs and extended for custom codecs. const String _codecName = 'PigeonCodec'; +const String _overflowClassName = '${classNamePrefix}CodecOverflow'; + /// Options that control how Java code will be generated. class JavaOptions { /// Creates a [JavaOptions] object @@ -141,6 +143,7 @@ class JavaGenerator extends StructuredGenerator { indent.writeln('import java.util.HashMap;'); indent.writeln('import java.util.List;'); indent.writeln('import java.util.Map;'); + indent.writeln('import java.util.Objects;'); indent.newln(); } @@ -194,7 +197,7 @@ class JavaGenerator extends StructuredGenerator { // SyntheticAccessor warnings in the serialization code. indent.writeln('final int index;'); indent.newln(); - indent.write('private ${anEnum.name}(final int index) '); + indent.write('${anEnum.name}(final int index) '); indent.addScoped('{', '}', () { indent.writeln('this.index = index;'); }); @@ -217,14 +220,7 @@ class JavaGenerator extends StructuredGenerator { indent, classDefinition.documentationComments, _docCommentSpec, generatorComments: generatedMessages); - indent.write('public static final class ${classDefinition.name} '); - indent.addScoped('{', '}', () { - for (final NamedType field - in getFieldsInSerializationOrder(classDefinition)) { - _writeClassField(generatorOptions, root, indent, field); - indent.newln(); - } - + _writeDataClassSignature(generatorOptions, indent, classDefinition, () { if (getFieldsInSerializationOrder(classDefinition) .map((NamedType e) => !e.type.isNullable) .any((bool e) => e)) { @@ -233,6 +229,7 @@ class JavaGenerator extends StructuredGenerator { indent.writeln('${classDefinition.name}() {}'); indent.newln(); } + _writeEquality(indent, classDefinition); _writeClassBuilder(generatorOptions, root, indent, classDefinition); writeClassEncode( @@ -253,24 +250,25 @@ class JavaGenerator extends StructuredGenerator { } void _writeClassField( - JavaOptions generatorOptions, Root root, Indent indent, NamedType field) { + JavaOptions generatorOptions, Indent indent, NamedType field) { final HostDatatype hostDatatype = getFieldHostDatatype( field, (TypeDeclaration x) => _javaTypeForBuiltinDartType(x)); - final String nullability = field.type.isNullable ? '@Nullable' : '@NonNull'; + final String nullability = + field.type.isNullable ? '@Nullable ' : '@NonNull '; addDocumentationComments( indent, field.documentationComments, _docCommentSpec); - indent.writeln( - 'private $nullability ${hostDatatype.datatype} ${field.name};'); + indent + .writeln('private $nullability${hostDatatype.datatype} ${field.name};'); indent.newln(); indent.write( - 'public $nullability ${hostDatatype.datatype} ${_makeGetter(field)}() '); + 'public $nullability${hostDatatype.datatype} ${_makeGetter(field)}() '); indent.addScoped('{', '}', () { indent.writeln('return ${field.name};'); }); indent.newln(); indent.writeScoped( - 'public void ${_makeSetter(field)}($nullability ${hostDatatype.datatype} setterArg) {', + 'public void ${_makeSetter(field)}($nullability${hostDatatype.datatype} setterArg) {', '}', () { if (!field.type.isNullable) { indent.writeScoped('if (setterArg == null) {', '}', () { @@ -282,6 +280,85 @@ class JavaGenerator extends StructuredGenerator { }); } + void _writeDataClassSignature( + JavaOptions generatorOptions, + Indent indent, + Class classDefinition, + void Function() dataClassBody, { + bool private = false, + }) { + indent.write( + '${private ? 'private' : 'public'} static final class ${classDefinition.name} '); + indent.addScoped('{', '}', () { + for (final NamedType field + in getFieldsInSerializationOrder(classDefinition)) { + _writeClassField( + generatorOptions, + indent, + field, + ); + indent.newln(); + } + dataClassBody(); + }); + } + + void _writeEquality(Indent indent, Class classDefinition) { + // Implement equals(...). + indent.writeln('@Override'); + indent.writeScoped('public boolean equals(Object o) {', '}', () { + indent.writeln('if (this == o) { return true; }'); + indent.writeln( + 'if (o == null || getClass() != o.getClass()) { return false; }'); + indent.writeln( + '${classDefinition.name} that = (${classDefinition.name}) o;'); + final Iterable checks = classDefinition.fields.map( + (NamedType field) { + // Objects.equals only does pointer equality for array types. + if (_javaTypeIsArray(field.type)) { + return 'Arrays.equals(${field.name}, that.${field.name})'; + } + return field.type.isNullable + ? 'Objects.equals(${field.name}, that.${field.name})' + : '${field.name}.equals(that.${field.name})'; + }, + ); + indent.writeln('return ${checks.join(' && ')};'); + }); + indent.newln(); + + // Implement hashCode(). + indent.writeln('@Override'); + indent.writeScoped('public int hashCode() {', '}', () { + // As with equalty checks, arrays need special handling. + final Iterable arrayFieldNames = classDefinition.fields + .where((NamedType field) => _javaTypeIsArray(field.type)) + .map((NamedType field) => field.name); + final Iterable nonArrayFieldNames = classDefinition.fields + .where((NamedType field) => !_javaTypeIsArray(field.type)) + .map((NamedType field) => field.name); + final String nonArrayHashValue = nonArrayFieldNames.isNotEmpty + ? 'Objects.hash(${nonArrayFieldNames.join(', ')})' + : '0'; + + if (arrayFieldNames.isEmpty) { + // Return directly if there are no array variables, to avoid redundant + // variable lint warnings. + indent.writeln('return $nonArrayHashValue;'); + } else { + const String resultVar = '${varNamePrefix}result'; + indent.writeln('int $resultVar = $nonArrayHashValue;'); + // Manually mix in the Arrays.hashCode values. + for (final String name in arrayFieldNames) { + indent.writeln( + '$resultVar = 31 * $resultVar + Arrays.hashCode($name);'); + } + indent.writeln('return $resultVar;'); + } + }); + indent.newln(); + } + void _writeClassBuilder( JavaOptions generatorOptions, Root root, @@ -336,7 +413,7 @@ class JavaGenerator extends StructuredGenerator { indent.write('ArrayList toList() '); indent.addScoped('{', '}', () { indent.writeln( - 'ArrayList toListResult = new ArrayList(${classDefinition.fields.length});'); + 'ArrayList toListResult = new ArrayList<>(${classDefinition.fields.length});'); for (final NamedType field in getFieldsInSerializationOrder(classDefinition)) { indent.writeln('toListResult.add(${field.name});'); @@ -380,7 +457,66 @@ class JavaGenerator extends StructuredGenerator { Indent indent, { required String dartPackageName, }) { - final Iterable enumeratedTypes = getEnumeratedTypes(root); + final List enumeratedTypes = + getEnumeratedTypes(root).toList(); + + void writeEncodeLogic(EnumeratedType customType) { + final String encodeString = + customType.type == CustomTypes.customClass ? 'toList()' : 'index'; + final String nullCheck = customType.type == CustomTypes.customEnum + ? 'value == null ? null : ' + : ''; + final String valueString = customType.enumeration < maximumCodecFieldKey + ? '$nullCheck((${customType.name}) value).$encodeString' + : 'wrap.toList()'; + final int enumeration = customType.enumeration < maximumCodecFieldKey + ? customType.enumeration + : maximumCodecFieldKey; + + indent.add('if (value instanceof ${customType.name}) '); + indent.addScoped('{', '} else ', () { + if (customType.enumeration >= maximumCodecFieldKey) { + indent + .writeln('$_overflowClassName wrap = new $_overflowClassName();'); + indent.writeln( + 'wrap.setType(${customType.enumeration - maximumCodecFieldKey}L);'); + indent.writeln( + 'wrap.setWrapped($nullCheck((${customType.name}) value).$encodeString);'); + } + indent.writeln('stream.write($enumeration);'); + indent.writeln('writeValue(stream, $valueString);'); + }, addTrailingNewline: false); + } + + void writeDecodeLogic(EnumeratedType customType) { + indent.write('case (byte) ${customType.enumeration}:'); + if (customType.type == CustomTypes.customClass) { + indent.newln(); + indent.nest(1, () { + indent.writeln( + 'return ${customType.name}.fromList((ArrayList) readValue(buffer));'); + }); + } else if (customType.type == CustomTypes.customEnum) { + indent.addScoped(' {', '}', () { + indent.writeln('Object value = readValue(buffer);'); + indent + .writeln('return ${_intToEnum('value', customType.name, true)};'); + }); + } + } + + final EnumeratedType overflowClass = EnumeratedType( + _overflowClassName, maximumCodecFieldKey, CustomTypes.customClass); + + if (root.requiresOverflowClass) { + _writeCodecOverflowUtilities( + generatorOptions, + root, + indent, + enumeratedTypes, + dartPackageName: dartPackageName, + ); + } indent.newln(); indent.write( 'private static class $_codecName extends StandardMessageCodec '); @@ -391,23 +527,17 @@ class JavaGenerator extends StructuredGenerator { indent.writeln('private $_codecName() {}'); indent.newln(); indent.writeln('@Override'); - indent.write( - 'protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) '); - indent.addScoped('{', '}', () { - indent.write('switch (type) '); - indent.addScoped('{', '}', () { + indent.writeScoped( + 'protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) {', + '}', () { + indent.writeScoped('switch (type) {', '}', () { for (final EnumeratedType customType in enumeratedTypes) { - indent.writeln('case (byte) ${customType.enumeration}:'); - indent.nest(1, () { - if (customType.type == CustomTypes.customClass) { - indent.writeln( - 'return ${customType.name}.fromList((ArrayList) readValue(buffer));'); - } else if (customType.type == CustomTypes.customEnum) { - indent.writeln('Object value = readValue(buffer);'); - indent.writeln( - 'return ${_intToEnum('value', customType.name, true)};'); - } - }); + if (customType.enumeration < maximumCodecFieldKey) { + writeDecodeLogic(customType); + } + } + if (root.requiresOverflowClass) { + writeDecodeLogic(overflowClass); } indent.writeln('default:'); indent.nest(1, () { @@ -420,24 +550,8 @@ class JavaGenerator extends StructuredGenerator { indent.write( 'protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) '); indent.addScoped('{', '}', () { - bool firstClass = true; - for (final EnumeratedType customType in enumeratedTypes) { - if (firstClass) { - indent.write(''); - firstClass = false; - } - indent.add('if (value instanceof ${customType.name}) '); - indent.addScoped('{', '} else ', () { - indent.writeln('stream.write(${customType.enumeration});'); - if (customType.type == CustomTypes.customClass) { - indent.writeln( - 'writeValue(stream, ((${customType.name}) value).toList());'); - } else { - indent.writeln( - 'writeValue(stream, value == null ? null : ((${customType.name}) value).index);'); - } - }, addTrailingNewline: false); - } + indent.write(''); + enumeratedTypes.forEach(writeEncodeLogic); indent.addScoped('{', '}', () { indent.writeln('super.writeValue(stream, value);'); }); @@ -446,6 +560,75 @@ class JavaGenerator extends StructuredGenerator { indent.newln(); } + void _writeCodecOverflowUtilities( + JavaOptions generatorOptions, + Root root, + Indent indent, + List types, { + required String dartPackageName, + }) { + final NamedType overflowInteration = NamedType( + name: 'type', + type: const TypeDeclaration(baseName: 'int', isNullable: false)); + final NamedType overflowObject = NamedType( + name: 'wrapped', + type: const TypeDeclaration(baseName: 'Object', isNullable: true)); + final List overflowFields = [ + overflowInteration, + overflowObject, + ]; + final Class overflowClass = + Class(name: _overflowClassName, fields: overflowFields); + + _writeDataClassSignature( + generatorOptions, + indent, + overflowClass, + () { + writeClassEncode( + generatorOptions, + root, + indent, + overflowClass, + dartPackageName: dartPackageName, + ); + + indent.format(''' +static @Nullable Object fromList(@NonNull ArrayList ${varNamePrefix}list) { + $_overflowClassName wrapper = new $_overflowClassName(); + wrapper.setType((Long) ${varNamePrefix}list.get(0)); + wrapper.setWrapped(${varNamePrefix}list.get(1)); + return wrapper.unwrap(); +} +'''); + + indent.writeScoped('@Nullable Object unwrap() {', '}', () { + indent.format(''' +if (wrapped == null) { + return null; +} + '''); + indent.writeScoped('switch (type.intValue()) {', '}', () { + for (int i = totalCustomCodecKeysAllowed; i < types.length; i++) { + indent.writeln('case ${i - totalCustomCodecKeysAllowed}:'); + indent.nest(1, () { + if (types[i].type == CustomTypes.customClass) { + indent.writeln( + 'return ${types[i].name}.fromList((ArrayList) wrapped);'); + } else if (types[i].type == CustomTypes.customEnum) { + indent.writeln( + 'return ${_intToEnum('wrapped', types[i].name, false)};'); + } + }); + } + }); + indent.writeln('return null;'); + }); + }, + private: true, + ); + } + /// Writes the code for a flutter [Api], [api]. /// Example: /// public static final class Foo { @@ -492,8 +675,11 @@ class JavaGenerator extends StructuredGenerator { 'this.messageChannelSuffix = messageChannelSuffix.isEmpty() ? "" : "." + messageChannelSuffix;'); }); indent.newln(); - indent.writeln('/** Public interface for sending reply. */ '); - indent.writeln('/** The codec used by ${api.name}. */'); + addDocumentationComments(indent, [], _docCommentSpec, + generatorComments: [ + 'Public interface for sending reply.', + 'The codec used by ${api.name}.' + ]); indent.write('static @NonNull MessageCodec getCodec() '); indent.addScoped('{', '}', () { indent.writeln('return $_codecName.INSTANCE;'); @@ -520,10 +706,10 @@ class JavaGenerator extends StructuredGenerator { indexMap(func.parameters, getSafeArgumentExpression); if (func.parameters.length == 1) { sendArgument = - 'new ArrayList(Collections.singletonList(${enumSafeArgNames.first}))'; + 'new ArrayList<>(Collections.singletonList(${enumSafeArgNames.first}))'; } else { sendArgument = - 'new ArrayList(Arrays.asList(${enumSafeArgNames.join(', ')}))'; + 'new ArrayList<>(Arrays.asList(${enumSafeArgNames.join(', ')}))'; } final String argsSignature = map2(argTypes, argNames, (String x, String y) => '$x $y') @@ -553,7 +739,7 @@ class JavaGenerator extends StructuredGenerator { 'List listReply = (List) channelReply;'); indent.writeScoped('if (listReply.size() > 1) {', '} ', () { indent.writeln( - 'result.error(new FlutterError((String) listReply.get(0), (String) listReply.get(1), (String) listReply.get(2)));'); + 'result.error(new FlutterError((String) listReply.get(0), (String) listReply.get(1), listReply.get(2)));'); }, addTrailingNewline: false); if (!func.returnType.isNullable && !func.returnType.isVoid) { indent.addScoped('else if (listReply.get(0) == null) {', '} ', @@ -569,13 +755,8 @@ class JavaGenerator extends StructuredGenerator { const String output = 'output'; final String outputExpression; indent.writeln('@SuppressWarnings("ConstantConditions")'); - if (func.returnType.baseName == 'int') { - outputExpression = - 'listReply.get(0) == null ? null : ((Number) listReply.get(0)).longValue();'; - } else { - outputExpression = - '${_cast('listReply.get(0)', javaType: returnType)};'; - } + outputExpression = + '${_cast('listReply.get(0)', javaType: returnType)};'; indent.writeln('$returnType $output = $outputExpression'); indent.writeln('result.success($output);'); } @@ -748,23 +929,15 @@ class JavaGenerator extends StructuredGenerator { final String returnType = method.returnType.isVoid ? 'Void' : _javaTypeForDartType(method.returnType); - indent.writeln( - 'ArrayList wrapped = new ArrayList();'); + indent.writeln('ArrayList wrapped = new ArrayList<>();'); final List methodArgument = []; if (method.parameters.isNotEmpty) { indent.writeln( 'ArrayList args = (ArrayList) message;'); enumerate(method.parameters, (int index, NamedType arg) { - // The StandardMessageCodec can give us [Integer, Long] for - // a Dart 'int'. To keep things simple we just use 64bit - // longs in Pigeon with Java. - final bool isInt = arg.type.baseName == 'int'; - final String argType = - isInt ? 'Number' : _javaTypeForDartType(arg.type); + final String argType = _javaTypeForDartType(arg.type); final String argName = _getSafeArgumentName(index, arg); - final String argExpression = isInt - ? '($argName == null) ? null : $argName.longValue()' - : argName; + final String argExpression = argName; String accessor = 'args.get($index)'; if (argType != 'Object') { accessor = _cast(accessor, javaType: argType); @@ -815,12 +988,10 @@ $resultType $resultName = }); indent.add(' catch (Throwable exception) '); indent.addScoped('{', '}', () { - indent.writeln( - 'ArrayList wrappedError = wrapError(exception);'); if (method.isAsynchronous) { - indent.writeln('reply.reply(wrappedError);'); + indent.writeln('reply.reply(wrapError(exception));'); } else { - indent.writeln('wrapped = wrappedError;'); + indent.writeln('wrapped = wrapError(exception);'); } }); indent.writeln('reply.reply(wrapped);'); @@ -902,7 +1073,7 @@ $resultType $resultName = indent.format(''' @NonNull protected static ArrayList wrapError(@NonNull Throwable exception) { -\tArrayList errorList = new ArrayList(3); +\tArrayList errorList = new ArrayList<>(3); \tif (exception instanceof FlutterError) { \t\tFlutterError error = (FlutterError) exception; \t\terrorList.add(error.code); @@ -982,9 +1153,10 @@ protected static ArrayList wrapError(@NonNull Throwable exception) { /// Converts an expression that evaluates to an nullable int to an expression /// that evaluates to a nullable enum. -String _intToEnum(String expression, String enumName, bool nullable) => nullable - ? '$expression == null ? null : $enumName.values()[(int) $expression]' - : '$enumName.values()[(int) $expression]'; +String _intToEnum(String expression, String enumName, bool nullable) { + final String toEnum = '$enumName.values()[((Long) $expression).intValue()]'; + return nullable ? '$expression == null ? null : $toEnum' : toEnum; +} String _getArgumentName(int count, NamedType argument) => argument.name.isEmpty ? 'arg$count' : argument.name; @@ -1022,6 +1194,10 @@ String _javaTypeForBuiltinGenericDartType( } } +bool _javaTypeIsArray(TypeDeclaration type) { + return _javaTypeForBuiltinDartType(type)?.endsWith('[]') ?? false; +} + String? _javaTypeForBuiltinDartType(TypeDeclaration type) { const Map javaTypeForDartTypeMap = { 'bool': 'Boolean', @@ -1071,11 +1247,7 @@ String _cast(String variable, {required String javaType}) { String _castObject(NamedType field, String varName) { final HostDatatype hostDatatype = getFieldHostDatatype( field, (TypeDeclaration x) => _javaTypeForBuiltinDartType(x)); - if (field.type.baseName == 'int') { - return '($varName == null) ? null : (($varName instanceof Integer) ? (Integer) $varName : (${hostDatatype.datatype}) $varName)'; - } else { - return _cast(varName, javaType: hostDatatype.datatype); - } + return _cast(varName, javaType: hostDatatype.datatype); } /// Returns string of Result class type for method based on [TypeDeclaration]. diff --git a/packages/pigeon/lib/kotlin/templates.dart b/packages/pigeon/lib/kotlin/templates.dart new file mode 100644 index 000000000000..5f85078588be --- /dev/null +++ b/packages/pigeon/lib/kotlin/templates.dart @@ -0,0 +1,240 @@ +// 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 '../generator_tools.dart'; +import '../kotlin_generator.dart'; + +/// Name of the Kotlin `InstanceManager`. +String kotlinInstanceManagerClassName(KotlinOptions options) => + '${options.fileSpecificClassNameComponent ?? ''}${proxyApiClassNamePrefix}InstanceManager'; + +/// The name of the registrar containing all the ProxyApi implementations. +String proxyApiRegistrarName(KotlinOptions options) => + '${options.fileSpecificClassNameComponent ?? ''}${proxyApiClassNamePrefix}ProxyApiRegistrar'; + +/// The name of the codec that handles ProxyApis. +String proxyApiCodecName(KotlinOptions options) => + '${options.fileSpecificClassNameComponent ?? ''}${proxyApiClassNamePrefix}ProxyApiBaseCodec'; + +/// The Kotlin `InstanceManager`. +String instanceManagerTemplate(KotlinOptions options) { + return ''' +/** + * Maintains instances used to communicate with the corresponding objects in Dart. + * + * Objects stored in this container are represented by an object in Dart that is also stored in + * an InstanceManager with the same identifier. + * + * When an instance is added with an identifier, either can be used to retrieve the other. + * + * Added instances are added as a weak reference and a strong reference. When the strong + * reference is removed with [remove] and the weak reference is deallocated, the + * `finalizationListener.onFinalize` is called with the instance's identifier. However, if the strong + * reference is removed and then the identifier is retrieved with the intention to pass the identifier + * to Dart (e.g. calling [getIdentifierForStrongReference]), the strong reference to the instance + * is recreated. The strong reference will then need to be removed manually again. + */ +@Suppress("UNCHECKED_CAST", "MemberVisibilityCanBePrivate") +class ${kotlinInstanceManagerClassName(options)}(private val finalizationListener: $_finalizationListenerClassName) { + /** Interface for listening when a weak reference of an instance is removed from the manager. */ + interface $_finalizationListenerClassName { + fun onFinalize(identifier: Long) + } + + private val identifiers = java.util.WeakHashMap() + private val weakInstances = HashMap>() + private val strongInstances = HashMap() + private val referenceQueue = java.lang.ref.ReferenceQueue() + private val weakReferencesToIdentifiers = HashMap, Long>() + private val handler = android.os.Handler(android.os.Looper.getMainLooper()) + private var nextIdentifier: Long = minHostCreatedIdentifier + private var hasFinalizationListenerStopped = false + + /** + * Modifies the time interval used to define how often this instance removes garbage collected + * weak references to native Android objects that this instance was managing. + */ + var clearFinalizedWeakReferencesInterval: Long = 3000 + set(value) { + handler.removeCallbacks { this.releaseAllFinalizedInstances() } + field = value + releaseAllFinalizedInstances() + } + + init { + handler.postDelayed( + { releaseAllFinalizedInstances() }, + clearFinalizedWeakReferencesInterval + ) + } + + companion object { + // Identifiers are locked to a specific range to avoid collisions with objects + // created simultaneously from Dart. + // Host uses identifiers >= 2^16 and Dart is expected to use values n where, + // 0 <= n < 2^16. + private const val minHostCreatedIdentifier: Long = 65536 + private const val tag = "${proxyApiClassNamePrefix}InstanceManager" + + /** + * Instantiate a new manager with a listener for garbage collected weak + * references. + * + * When the manager is no longer needed, [stopFinalizationListener] must be called. + */ + fun create(finalizationListener: $_finalizationListenerClassName): ${kotlinInstanceManagerClassName(options)} { + return ${kotlinInstanceManagerClassName(options)}(finalizationListener) + } + } + + /** + * Removes `identifier` and return its associated strongly referenced instance, if present, + * from the manager. + */ + fun remove(identifier: Long): T? { + logWarningIfFinalizationListenerHasStopped() + return strongInstances.remove(identifier) as T? + } + + /** + * Retrieves the identifier paired with an instance, if present, otherwise `null`. + * + * + * If the manager contains a strong reference to `instance`, it will return the identifier + * associated with `instance`. If the manager contains only a weak reference to `instance`, a new + * strong reference to `instance` will be added and will need to be removed again with [remove]. + * + * + * If this method returns a nonnull identifier, this method also expects the Dart + * `${kotlinInstanceManagerClassName(options)}` to have, or recreate, a weak reference to the Dart instance the + * identifier is associated with. + */ + fun getIdentifierForStrongReference(instance: Any?): Long? { + logWarningIfFinalizationListenerHasStopped() + val identifier = identifiers[instance] + if (identifier != null) { + strongInstances[identifier] = instance!! + } + return identifier + } + + /** + * Adds a new instance that was instantiated from Dart. + * + * The same instance can be added multiple times, but each identifier must be unique. This + * allows two objects that are equivalent (e.g. the `equals` method returns true and their + * hashcodes are equal) to both be added. + * + * [identifier] must be >= 0 and unique. + */ + fun addDartCreatedInstance(instance: Any, identifier: Long) { + logWarningIfFinalizationListenerHasStopped() + addInstance(instance, identifier) + } + + /** + * Adds a new unique instance that was instantiated from the host platform. + * + * [identifier] must be >= 0 and unique. + */ + fun addHostCreatedInstance(instance: Any): Long { + logWarningIfFinalizationListenerHasStopped() + require(!containsInstance(instance)) { "Instance of \${instance.javaClass} has already been added." } + val identifier = nextIdentifier++ + addInstance(instance, identifier) + return identifier + } + + /** Retrieves the instance associated with identifier, if present, otherwise `null`. */ + fun getInstance(identifier: Long): T? { + logWarningIfFinalizationListenerHasStopped() + val instance = weakInstances[identifier] as java.lang.ref.WeakReference? + return instance?.get() + } + + /** Returns whether this manager contains the given `instance`. */ + fun containsInstance(instance: Any?): Boolean { + logWarningIfFinalizationListenerHasStopped() + return identifiers.containsKey(instance) + } + + /** + * Stops the periodic run of the [$_finalizationListenerClassName] for instances that have been garbage + * collected. + * + * The InstanceManager can continue to be used, but the [$_finalizationListenerClassName] will no + * longer be called and methods will log a warning. + */ + fun stopFinalizationListener() { + handler.removeCallbacks { this.releaseAllFinalizedInstances() } + hasFinalizationListenerStopped = true + } + + /** + * Removes all of the instances from this manager. + * + * The manager will be empty after this call returns. + */ + fun clear() { + identifiers.clear() + weakInstances.clear() + strongInstances.clear() + weakReferencesToIdentifiers.clear() + } + + /** + * Whether the [$_finalizationListenerClassName] is still being called for instances that are garbage + * collected. + * + * See [stopFinalizationListener]. + */ + fun hasFinalizationListenerStopped(): Boolean { + return hasFinalizationListenerStopped + } + + private fun releaseAllFinalizedInstances() { + if (hasFinalizationListenerStopped()) { + return + } + var reference: java.lang.ref.WeakReference? + while ((referenceQueue.poll() as java.lang.ref.WeakReference?).also { reference = it } != null) { + val identifier = weakReferencesToIdentifiers.remove(reference) + if (identifier != null) { + weakInstances.remove(identifier) + strongInstances.remove(identifier) + finalizationListener.onFinalize(identifier) + } + } + handler.postDelayed( + { releaseAllFinalizedInstances() }, + clearFinalizedWeakReferencesInterval + ) + } + + private fun addInstance(instance: Any, identifier: Long) { + require(identifier >= 0) { "Identifier must be >= 0: \$identifier" } + require(!weakInstances.containsKey(identifier)) { + "Identifier has already been added: \$identifier" + } + val weakReference = java.lang.ref.WeakReference(instance, referenceQueue) + identifiers[instance] = identifier + weakInstances[identifier] = weakReference + weakReferencesToIdentifiers[weakReference] = identifier + strongInstances[identifier] = instance + } + + private fun logWarningIfFinalizationListenerHasStopped() { + if (hasFinalizationListenerStopped()) { + Log.w( + tag, + "The manager was used after calls to the $_finalizationListenerClassName has been stopped." + ) + } + } +} +'''; +} + +const String _finalizationListenerClassName = + '${proxyApiClassNamePrefix}FinalizationListener'; diff --git a/packages/pigeon/lib/kotlin_generator.dart b/packages/pigeon/lib/kotlin_generator.dart index 1d827aff1648..3b5ff62aa822 100644 --- a/packages/pigeon/lib/kotlin_generator.dart +++ b/packages/pigeon/lib/kotlin_generator.dart @@ -2,10 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:graphs/graphs.dart'; + import 'ast.dart'; import 'functional.dart'; import 'generator.dart'; import 'generator_tools.dart'; +import 'kotlin/templates.dart'; import 'pigeon_lib.dart' show TaskQueueType; /// Documentation open symbol. @@ -27,6 +30,8 @@ const DocumentCommentSpecification _docCommentSpec = String _codecName = 'PigeonCodec'; +const String _overflowClassName = '${classNamePrefix}CodecOverflow'; + /// Options that control how Kotlin code will be generated. class KotlinOptions { /// Creates a [KotlinOptions] object @@ -90,6 +95,23 @@ class KotlinOptions { } } +/// Options that control how Kotlin code will be generated for a specific +/// ProxyApi. +class KotlinProxyApiOptions { + /// Construct a [KotlinProxyApiOptions]. + const KotlinProxyApiOptions({this.fullClassName, this.minAndroidApi}); + + /// The name of the full runtime Kotlin class name (including the package). + final String? fullClassName; + + /// The minimum Android api version. + /// + /// This adds the [RequiresApi](https://developer.android.com/reference/androidx/annotation/RequiresApi) + /// annotations on top of any constructor, field, or method that references + /// this element. + final int? minAndroidApi; +} + /// Class that manages all Kotlin code generation. class KotlinGenerator extends StructuredGenerator { /// Instantiates a Kotlin Generator. @@ -147,10 +169,7 @@ class KotlinGenerator extends StructuredGenerator { enumerate(anEnum.members, (int index, final EnumMember member) { addDocumentationComments( indent, member.documentationComments, _docCommentSpec); - final String nameScreamingSnakeCase = member.name - .replaceAllMapped( - RegExp(r'(?<=[a-z])[A-Z]'), (Match m) => '_${m.group(0)}') - .toUpperCase(); + final String nameScreamingSnakeCase = toScreamingSnakeCase(member.name); indent.write('$nameScreamingSnakeCase($index)'); if (index != anEnum.members.length - 1) { indent.addln(','); @@ -185,20 +204,8 @@ class KotlinGenerator extends StructuredGenerator { addDocumentationComments( indent, classDefinition.documentationComments, _docCommentSpec, generatorComments: generatedMessages); - indent.write('data class ${classDefinition.name} '); - indent.addScoped('(', '', () { - for (final NamedType element - in getFieldsInSerializationOrder(classDefinition)) { - _writeClassField(indent, element); - if (getFieldsInSerializationOrder(classDefinition).last != element) { - indent.addln(','); - } else { - indent.newln(); - } - } - }); - - indent.addScoped(') {', '}', () { + _writeDataClassSignature(indent, classDefinition); + indent.addScoped(' {', '}', () { writeClassDecode( generatorOptions, root, @@ -216,6 +223,26 @@ class KotlinGenerator extends StructuredGenerator { }); } + void _writeDataClassSignature( + Indent indent, + Class classDefinition, { + bool private = false, + }) { + indent.write( + '${private ? 'private ' : ''}data class ${classDefinition.name} '); + indent.addScoped('(', ')', () { + for (final NamedType element + in getFieldsInSerializationOrder(classDefinition)) { + _writeClassField(indent, element); + if (getFieldsInSerializationOrder(classDefinition).last != element) { + indent.addln(','); + } else { + indent.newln(); + } + } + }); + } + @override void writeClassEncode( KotlinOptions generatorOptions, @@ -249,7 +276,6 @@ class KotlinGenerator extends StructuredGenerator { indent.write('companion object '); indent.addScoped('{', '}', () { - indent.writeln('@Suppress("LocalVariableName")'); indent .write('fun fromList(${varNamePrefix}list: List): $className '); @@ -307,9 +333,62 @@ class KotlinGenerator extends StructuredGenerator { Indent indent, { required String dartPackageName, }) { - final Iterable enumeratedTypes = getEnumeratedTypes(root); + final List enumeratedTypes = + getEnumeratedTypes(root).toList(); + + void writeEncodeLogic(EnumeratedType customType) { + final String encodeString = + customType.type == CustomTypes.customClass ? 'toList()' : 'raw'; + final String valueString = customType.enumeration < maximumCodecFieldKey + ? 'value.$encodeString' + : 'wrap.toList()'; + final int enumeration = customType.enumeration < maximumCodecFieldKey + ? customType.enumeration + : maximumCodecFieldKey; + indent.writeScoped('is ${customType.name} -> {', '}', () { + if (customType.enumeration >= maximumCodecFieldKey) { + indent.writeln( + 'val wrap = ${generatorOptions.fileSpecificClassNameComponent}$_overflowClassName(type = ${customType.enumeration - maximumCodecFieldKey}, wrapped = value.$encodeString)'); + } + indent.writeln('stream.write($enumeration)'); + indent.writeln('writeValue(stream, $valueString)'); + }); + } + + void writeDecodeLogic(EnumeratedType customType) { + indent.write('${customType.enumeration}.toByte() -> '); + indent.addScoped('{', '}', () { + if (customType.type == CustomTypes.customClass) { + indent.write('return (readValue(buffer) as? List)?.let '); + indent.addScoped('{', '}', () { + indent.writeln('${customType.name}.fromList(it)'); + }); + } else if (customType.type == CustomTypes.customEnum) { + indent.write('return (readValue(buffer) as Long?)?.let '); + indent.addScoped('{', '}', () { + indent.writeln('${customType.name}.ofRaw(it.toInt())'); + }); + } + }); + } + + final EnumeratedType overflowClass = EnumeratedType( + '${generatorOptions.fileSpecificClassNameComponent}$_overflowClassName', + maximumCodecFieldKey, + CustomTypes.customClass); + + if (root.requiresOverflowClass) { + _writeCodecOverflowUtilities( + generatorOptions, + root, + indent, + enumeratedTypes, + dartPackageName: dartPackageName, + ); + } + indent.write( - 'private object ${generatorOptions.fileSpecificClassNameComponent}$_codecName : StandardMessageCodec() '); + 'private open class ${generatorOptions.fileSpecificClassNameComponent}$_codecName : StandardMessageCodec() '); indent.addScoped('{', '}', () { indent.write( 'override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? '); @@ -319,21 +398,12 @@ class KotlinGenerator extends StructuredGenerator { indent.add('when (type) '); indent.addScoped('{', '}', () { for (final EnumeratedType customType in enumeratedTypes) { - indent.write('${customType.enumeration}.toByte() -> '); - indent.addScoped('{', '}', () { - if (customType.type == CustomTypes.customClass) { - indent - .write('return (readValue(buffer) as? List)?.let '); - indent.addScoped('{', '}', () { - indent.writeln('${customType.name}.fromList(it)'); - }); - } else if (customType.type == CustomTypes.customEnum) { - indent.write('return (readValue(buffer) as Int?)?.let '); - indent.addScoped('{', '}', () { - indent.writeln('${customType.name}.ofRaw(it)'); - }); - } - }); + if (customType.enumeration < maximumCodecFieldKey) { + writeDecodeLogic(customType); + } + } + if (root.requiresOverflowClass) { + writeDecodeLogic(overflowClass); } indent.writeln('else -> super.readValueOfType(type, buffer)'); }); @@ -348,17 +418,7 @@ class KotlinGenerator extends StructuredGenerator { if (root.classes.isNotEmpty || root.enums.isNotEmpty) { indent.write('when (value) '); indent.addScoped('{', '}', () { - for (final EnumeratedType customType in enumeratedTypes) { - indent.write('is ${customType.name} -> '); - indent.addScoped('{', '}', () { - indent.writeln('stream.write(${customType.enumeration})'); - if (customType.type == CustomTypes.customClass) { - indent.writeln('writeValue(stream, value.toList())'); - } else if (customType.type == CustomTypes.customEnum) { - indent.writeln('writeValue(stream, value.raw)'); - } - }); - } + enumeratedTypes.forEach(writeEncodeLogic); indent.writeln('else -> super.writeValue(stream, value)'); }); } else { @@ -369,6 +429,74 @@ class KotlinGenerator extends StructuredGenerator { indent.newln(); } + void _writeCodecOverflowUtilities( + KotlinOptions generatorOptions, + Root root, + Indent indent, + List types, { + required String dartPackageName, + }) { + final NamedType overflowInt = NamedType( + name: 'type', + type: const TypeDeclaration(baseName: 'int', isNullable: false)); + final NamedType overflowObject = NamedType( + name: 'wrapped', + type: const TypeDeclaration(baseName: 'Object', isNullable: true)); + final List overflowFields = [ + overflowInt, + overflowObject, + ]; + final Class overflowClass = Class( + name: + '${generatorOptions.fileSpecificClassNameComponent}$_overflowClassName', + fields: overflowFields); + + _writeDataClassSignature(indent, overflowClass, private: true); + indent.addScoped(' {', '}', () { + writeClassEncode( + generatorOptions, + root, + indent, + overflowClass, + dartPackageName: dartPackageName, + ); + + indent.format(''' +companion object { + fun fromList(${varNamePrefix}list: List): Any? { + val wrapper = ${generatorOptions.fileSpecificClassNameComponent}$_overflowClassName( + type = ${varNamePrefix}list[0] as Long, + wrapped = ${varNamePrefix}list[1], + ); + return wrapper.unwrap() + } +} +'''); + + indent.writeScoped('fun unwrap(): Any? {', '}', () { + indent.format(''' +if (wrapped == null) { + return null +} + '''); + indent.writeScoped('when (type.toInt()) {', '}', () { + for (int i = totalCustomCodecKeysAllowed; i < types.length; i++) { + indent.writeScoped('${i - totalCustomCodecKeysAllowed} ->', '', () { + if (types[i].type == CustomTypes.customClass) { + indent.writeln( + 'return ${types[i].name}.fromList(wrapped as List)'); + } else if (types[i].type == CustomTypes.customEnum) { + indent.writeln( + 'return ${types[i].name}.ofRaw((wrapped as Long).toInt())'); + } + }); + } + }); + indent.writeln('return null'); + }); + }); + } + /// Writes the code for a flutter [Api], [api]. /// Example: /// class Foo(private val binaryMessenger: BinaryMessenger) { @@ -398,7 +526,7 @@ class KotlinGenerator extends StructuredGenerator { indent.write('val codec: MessageCodec by lazy '); indent.addScoped('{', '}', () { indent.writeln( - '${generatorOptions.fileSpecificClassNameComponent}$_codecName'); + '${generatorOptions.fileSpecificClassNameComponent}$_codecName()'); }); }); @@ -412,6 +540,24 @@ class KotlinGenerator extends StructuredGenerator { channelName: makeChannelName(api, method, dartPackageName), documentationComments: method.documentationComments, dartPackageName: dartPackageName, + onWriteBody: ( + Indent indent, { + required List parameters, + required TypeDeclaration returnType, + required String channelName, + required String errorClassName, + }) { + indent.writeln( + r'val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""', + ); + _writeFlutterMethodMessageCall( + indent, + parameters: parameters, + returnType: returnType, + channelName: '$channelName\$separatedMessageChannelSuffix', + errorClassName: errorClassName, + ); + }, ); } }); @@ -462,7 +608,7 @@ class KotlinGenerator extends StructuredGenerator { indent.write('val codec: MessageCodec by lazy '); indent.addScoped('{', '}', () { indent.writeln( - '${generatorOptions.fileSpecificClassNameComponent}$_codecName'); + '${generatorOptions.fileSpecificClassNameComponent}$_codecName()'); }); indent.writeln( '/** Sets up an instance of `$apiName` to handle messages through the `binaryMessenger`. */'); @@ -475,9 +621,9 @@ class KotlinGenerator extends StructuredGenerator { for (final Method method in api.methods) { _writeHostMethodMessageHandler( indent, - api: api, name: method.name, - channelName: makeChannelName(api, method, dartPackageName), + channelName: + '${makeChannelName(api, method, dartPackageName)}\$separatedMessageChannelSuffix', taskQueueType: method.taskQueueType, parameters: method.parameters, returnType: method.returnType, @@ -489,6 +635,355 @@ class KotlinGenerator extends StructuredGenerator { }); } + @override + void writeInstanceManager( + KotlinOptions generatorOptions, + Root root, + Indent indent, { + required String dartPackageName, + }) { + indent.format(instanceManagerTemplate(generatorOptions)); + indent.newln(); + } + + @override + void writeInstanceManagerApi( + KotlinOptions generatorOptions, + Root root, + Indent indent, { + required String dartPackageName, + }) { + final String instanceManagerApiName = + '${kotlinInstanceManagerClassName(generatorOptions)}Api'; + + addDocumentationComments( + indent, + [ + ' Generated API for managing the Dart and native `InstanceManager`s.', + ], + _docCommentSpec, + ); + indent.writeScoped( + 'private class $instanceManagerApiName(val binaryMessenger: BinaryMessenger) {', + '}', + () { + indent.writeScoped('companion object {', '}', () { + addDocumentationComments( + indent, + [' The codec used by $instanceManagerApiName.'], + _docCommentSpec, + ); + indent.writeScoped( + 'val codec: MessageCodec by lazy {', + '}', + () { + indent.writeln( + '${generatorOptions.fileSpecificClassNameComponent}$_codecName()', + ); + }, + ); + indent.newln(); + + addDocumentationComments( + indent, + [ + ' Sets up an instance of `$instanceManagerApiName` to handle messages from the', + ' `binaryMessenger`.', + ], + _docCommentSpec, + ); + indent.writeScoped( + 'fun setUpMessageHandlers(binaryMessenger: BinaryMessenger, instanceManager: ${kotlinInstanceManagerClassName(generatorOptions)}?) {', + '}', + () { + const String setHandlerCondition = 'instanceManager != null'; + _writeHostMethodMessageHandler( + indent, + name: 'removeStrongReference', + channelName: + makeRemoveStrongReferenceChannelName(dartPackageName), + taskQueueType: TaskQueueType.serial, + parameters: [ + Parameter( + name: 'identifier', + type: const TypeDeclaration( + baseName: 'int', + isNullable: false, + ), + ), + ], + returnType: const TypeDeclaration.voidDeclaration(), + setHandlerCondition: setHandlerCondition, + onCreateCall: ( + List safeArgNames, { + required String apiVarName, + }) { + return 'instanceManager.remove(${safeArgNames.single})'; + }, + ); + _writeHostMethodMessageHandler( + indent, + name: 'clear', + channelName: makeClearChannelName(dartPackageName), + taskQueueType: TaskQueueType.serial, + parameters: [], + returnType: const TypeDeclaration.voidDeclaration(), + setHandlerCondition: setHandlerCondition, + onCreateCall: ( + List safeArgNames, { + required String apiVarName, + }) { + return 'instanceManager.clear()'; + }, + ); + }, + ); + }); + indent.newln(); + + _writeFlutterMethod( + indent, + generatorOptions: generatorOptions, + name: 'removeStrongReference', + parameters: [ + Parameter( + name: 'identifier', + type: const TypeDeclaration(baseName: 'int', isNullable: false), + ) + ], + returnType: const TypeDeclaration.voidDeclaration(), + channelName: makeRemoveStrongReferenceChannelName(dartPackageName), + dartPackageName: dartPackageName, + ); + }, + ); + } + + @override + void writeProxyApiBaseCodec( + KotlinOptions generatorOptions, + Root root, + Indent indent, + ) { + final Iterable allProxyApis = + root.apis.whereType(); + + _writeProxyApiRegistrar( + indent, + generatorOptions: generatorOptions, + allProxyApis: allProxyApis, + ); + + // Sort APIs where edges are an API's super class and interfaces. + // + // This sorts the APIs to have child classes be listed before their parent + // classes. This prevents the scenario where a method might return the super + // class of the actual class, so the incorrect Dart class gets created + // because the 'value is ' was checked first in the codec. For + // example: + // + // class Shape {} + // class Circle extends Shape {} + // + // class SomeClass { + // Shape giveMeAShape() => Circle(); + // } + final List sortedApis = topologicalSort( + allProxyApis, + (AstProxyApi api) { + return [ + if (api.superClass?.associatedProxyApi != null) + api.superClass!.associatedProxyApi!, + ...api.interfaces.map( + (TypeDeclaration interface) => interface.associatedProxyApi!, + ), + ]; + }, + ); + + indent.writeScoped( + 'private class ${proxyApiCodecName(generatorOptions)}(val registrar: ${proxyApiRegistrarName(generatorOptions)}) : ' + '${generatorOptions.fileSpecificClassNameComponent}$_codecName() {', + '}', + () { + indent.format( + ''' + override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? { + return when (type) { + $proxyApiCodecInstanceManagerKey.toByte() -> { + return registrar.instanceManager.getInstance(readValue(buffer) as Long) + } + else -> super.readValueOfType(type, buffer) + } + }''', + ); + indent.newln(); + + indent.writeScoped( + 'override fun writeValue(stream: ByteArrayOutputStream, value: Any?) {', + '}', + () { + final List nonProxyApiTypes = [ + 'Boolean', + 'ByteArray', + 'Double', + 'DoubleArray', + 'FloatArray', + 'Int', + 'IntArray', + 'List<*>', + 'Long', + 'LongArray', + 'Map<*, *>', + 'String', + ...root.enums.map((Enum anEnum) => anEnum.name), + ]; + final String isSupportedExpression = nonProxyApiTypes + .map((String kotlinType) => 'value is $kotlinType') + .followedBy(['value == null']).join(' || '); + // Non ProxyApi types are checked first to handle the scenario + // where a client wraps the `Object` class which all the + // classes above extend. + indent.writeScoped('if ($isSupportedExpression) {', '}', () { + indent.writeln('super.writeValue(stream, value)'); + indent.writeln('return'); + }); + indent.newln(); + + enumerate( + sortedApis, + (int index, AstProxyApi api) { + final String className = + api.kotlinOptions?.fullClassName ?? api.name; + + final int? minApi = api.kotlinOptions?.minAndroidApi; + final String versionCheck = minApi != null + ? 'android.os.Build.VERSION.SDK_INT >= $minApi && ' + : ''; + + indent.format( + ''' + ${index > 0 ? ' else ' : ''}if (${versionCheck}value is $className) { + registrar.get$hostProxyApiPrefix${api.name}().${classMemberNamePrefix}newInstance(value) { } + }''', + ); + }, + ); + indent.newln(); + + indent.format( + ''' + when { + registrar.instanceManager.containsInstance(value) -> { + stream.write($proxyApiCodecInstanceManagerKey) + writeValue(stream, registrar.instanceManager.getIdentifierForStrongReference(value)) + } + else -> throw IllegalArgumentException("Unsupported value: '\$value' of type '\${value.javaClass.name}'") + }''', + ); + }, + ); + }, + ); + } + + @override + void writeProxyApi( + KotlinOptions generatorOptions, + Root root, + Indent indent, + AstProxyApi api, { + required String dartPackageName, + }) { + final String kotlinApiName = '$hostProxyApiPrefix${api.name}'; + + addDocumentationComments( + indent, + api.documentationComments, + _docCommentSpec, + ); + indent.writeln('@Suppress("UNCHECKED_CAST")'); + // The API only needs to be abstract if there are methods to override. + final String classModifier = + api.hasMethodsRequiringImplementation() ? 'abstract' : 'open'; + indent.writeScoped( + '$classModifier class $kotlinApiName(open val pigeonRegistrar: ${proxyApiRegistrarName(generatorOptions)}) {', + '}', + () { + final String fullKotlinClassName = + api.kotlinOptions?.fullClassName ?? api.name; + + final TypeDeclaration apiAsTypeDeclaration = TypeDeclaration( + baseName: api.name, + isNullable: false, + associatedProxyApi: api, + ); + + _writeProxyApiConstructorAbstractMethods( + indent, + api, + apiAsTypeDeclaration: apiAsTypeDeclaration, + ); + + _writeProxyApiAttachedFieldAbstractMethods( + indent, + api, + apiAsTypeDeclaration: apiAsTypeDeclaration, + ); + + if (api.hasCallbackConstructor()) { + _writeProxyApiUnattachedFieldAbstractMethods( + indent, + api, + apiAsTypeDeclaration: apiAsTypeDeclaration, + ); + } + + _writeProxyApiHostMethodAbstractMethods( + indent, + api, + apiAsTypeDeclaration: apiAsTypeDeclaration, + ); + + if (api.constructors.isNotEmpty || + api.attachedFields.isNotEmpty || + api.hostMethods.isNotEmpty) { + indent.writeScoped('companion object {', '}', () { + _writeProxyApiMessageHandlerMethod( + indent, + api, + apiAsTypeDeclaration: apiAsTypeDeclaration, + kotlinApiName: kotlinApiName, + dartPackageName: dartPackageName, + fullKotlinClassName: fullKotlinClassName, + generatorOptions: generatorOptions, + ); + }); + indent.newln(); + } + + _writeProxyApiNewInstanceMethod( + indent, + api, + generatorOptions: generatorOptions, + apiAsTypeDeclaration: apiAsTypeDeclaration, + newInstanceMethodName: '${classMemberNamePrefix}newInstance', + dartPackageName: dartPackageName, + ); + + _writeProxyApiFlutterMethods( + indent, + api, + generatorOptions: generatorOptions, + apiAsTypeDeclaration: apiAsTypeDeclaration, + dartPackageName: dartPackageName, + ); + + _writeProxyApiInheritedApiMethods(indent, api); + }, + ); + } + void _writeWrapResult(Indent indent) { indent.newln(); indent.write('private fun wrapResult(result: Any?): List '); @@ -565,12 +1060,13 @@ class KotlinGenerator extends StructuredGenerator { final bool hasFlutterApi = root.apis .whereType() .any((Api api) => api.methods.isNotEmpty); + final bool hasProxyApi = root.apis.any((Api api) => api is AstProxyApi); - if (hasHostApi) { + if (hasHostApi || hasProxyApi) { _writeWrapResult(indent); _writeWrapError(generatorOptions, indent); } - if (hasFlutterApi) { + if (hasFlutterApi || hasProxyApi) { _writeCreateConnectionError(generatorOptions, indent); } if (generatorOptions.includeErrorClass) { @@ -586,6 +1082,7 @@ class KotlinGenerator extends StructuredGenerator { List documentationComments = const [], int? minApiRequirement, bool isAsynchronous = false, + bool isOpen = false, bool isAbstract = false, String Function(int index, NamedType type) getArgumentName = _getArgumentName, @@ -618,28 +1115,33 @@ class KotlinGenerator extends StructuredGenerator { ); } + final String openKeyword = isOpen ? 'open ' : ''; final String abstractKeyword = isAbstract ? 'abstract ' : ''; if (isAsynchronous) { argSignature.add('callback: (Result<$resultType>) -> Unit'); - indent.writeln('${abstractKeyword}fun $name(${argSignature.join(', ')})'); + indent.writeln( + '$openKeyword${abstractKeyword}fun $name(${argSignature.join(', ')})', + ); } else if (returnType.isVoid) { - indent.writeln('${abstractKeyword}fun $name(${argSignature.join(', ')})'); + indent.writeln( + '$openKeyword${abstractKeyword}fun $name(${argSignature.join(', ')})', + ); } else { indent.writeln( - '${abstractKeyword}fun $name(${argSignature.join(', ')}): $returnTypeString', + '$openKeyword${abstractKeyword}fun $name(${argSignature.join(', ')}): $returnTypeString', ); } } void _writeHostMethodMessageHandler( Indent indent, { - required Api api, required String name, required String channelName, required TaskQueueType taskQueueType, required List parameters, required TypeDeclaration returnType, + String setHandlerCondition = 'api != null', bool isAsynchronous = false, String Function(List safeArgNames, {required String apiVarName})? onCreateCall, @@ -652,8 +1154,10 @@ class KotlinGenerator extends StructuredGenerator { indent.writeln( 'val $taskQueue = binaryMessenger.makeBackgroundTaskQueue()'); } + indent.write( - 'val channel = BasicMessageChannel(binaryMessenger, "$channelName\$separatedMessageChannelSuffix", codec'); + 'val channel = BasicMessageChannel(binaryMessenger, "$channelName", codec', + ); if (taskQueue != null) { indent.addln(', $taskQueue)'); @@ -661,7 +1165,7 @@ class KotlinGenerator extends StructuredGenerator { indent.addln(')'); } - indent.write('if (api != null) '); + indent.write('if ($setHandlerCondition) '); indent.addScoped('{', '}', () { final String messageVarName = parameters.isNotEmpty ? 'message' : '_'; @@ -734,6 +1238,13 @@ class KotlinGenerator extends StructuredGenerator { required String dartPackageName, List documentationComments = const [], int? minApiRequirement, + void Function( + Indent indent, { + required List parameters, + required TypeDeclaration returnType, + required String channelName, + required String errorClassName, + }) onWriteBody = _writeFlutterMethodMessageCall, }) { _writeMethodDeclaration( indent, @@ -748,7 +1259,7 @@ class KotlinGenerator extends StructuredGenerator { final String errorClassName = _getErrorClassName(generatorOptions); indent.addScoped('{', '}', () { - _writeFlutterMethodMessageCall( + onWriteBody( indent, parameters: parameters, returnType: returnType, @@ -778,10 +1289,7 @@ class KotlinGenerator extends StructuredGenerator { } const String channel = 'channel'; - indent.writeln( - r'val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""'); - indent.writeln( - 'val channelName = "$channelName\$separatedMessageChannelSuffix"'); + indent.writeln('val channelName = "$channelName"'); indent.writeln( 'val $channel = BasicMessageChannel(binaryMessenger, channelName, codec)'); indent.writeScoped('$channel.send($sendArgument) {', '}', () { @@ -813,6 +1321,664 @@ class KotlinGenerator extends StructuredGenerator { }); }); } + + void _writeProxyApiRegistrar( + Indent indent, { + required KotlinOptions generatorOptions, + required Iterable allProxyApis, + }) { + final String registrarName = proxyApiRegistrarName(generatorOptions); + final String instanceManagerName = kotlinInstanceManagerClassName( + generatorOptions, + ); + final String instanceManagerApiName = '${instanceManagerName}Api'; + + addDocumentationComments( + indent, + [ + ' Provides implementations for each ProxyApi implementation and provides access to resources', + ' needed by any implementation.', + ], + _docCommentSpec, + ); + indent.writeScoped( + 'abstract class $registrarName(val binaryMessenger: BinaryMessenger) {', + '}', + () { + addDocumentationComments( + indent, + [' Whether APIs should ignore calling to Dart.'], + _docCommentSpec, + ); + indent.writeln('public var ignoreCallsToDart = false'); + indent.format( + ''' + val instanceManager: $instanceManagerName + private var _codec: MessageCodec? = null + val codec: MessageCodec + get() { + if (_codec == null) { + _codec = ${proxyApiCodecName(generatorOptions)}(this) + } + return _codec!! + } + + init { + val api = $instanceManagerApiName(binaryMessenger) + instanceManager = $instanceManagerName.create( + object : $instanceManagerName.PigeonFinalizationListener { + override fun onFinalize(identifier: Long) { + api.removeStrongReference(identifier) { + if (it.isFailure) { + Log.e( + "${proxyApiClassNamePrefix}ProxyApiRegistrar", + "Failed to remove Dart strong reference with identifier: \$identifier" + ) + } + } + } + } + ) + }''', + ); + for (final AstProxyApi api in allProxyApis) { + _writeMethodDeclaration( + indent, + name: 'get$hostProxyApiPrefix${api.name}', + isAbstract: + api.hasAnyHostMessageCalls() || api.unattachedFields.isNotEmpty, + isOpen: + !api.hasAnyHostMessageCalls() && api.unattachedFields.isEmpty, + documentationComments: [ + ' An implementation of [$hostProxyApiPrefix${api.name}] used to add a new Dart instance of', + ' `${api.name}` to the Dart `InstanceManager`.' + ], + returnType: TypeDeclaration( + baseName: '$hostProxyApiPrefix${api.name}', + isNullable: false, + ), + parameters: [], + ); + + // Use the default API implementation if this API does not have any + // methods to implement. + if (!api.hasMethodsRequiringImplementation()) { + indent.writeScoped('{', '}', () { + indent.writeln('return $hostProxyApiPrefix${api.name}(this)'); + }); + } + indent.newln(); + } + + indent.writeScoped('fun setUp() {', '}', () { + indent.writeln( + '$instanceManagerApiName.setUpMessageHandlers(binaryMessenger, instanceManager)', + ); + for (final AstProxyApi api in allProxyApis) { + final bool hasHostMessageCalls = api.constructors.isNotEmpty || + api.attachedFields.isNotEmpty || + api.hostMethods.isNotEmpty; + if (hasHostMessageCalls) { + indent.writeln( + '$hostProxyApiPrefix${api.name}.setUpMessageHandlers(binaryMessenger, get$hostProxyApiPrefix${api.name}())', + ); + } + } + }); + + indent.writeScoped('fun tearDown() {', '}', () { + indent.writeln( + '$instanceManagerApiName.setUpMessageHandlers(binaryMessenger, null)', + ); + for (final AstProxyApi api in allProxyApis) { + if (api.hasAnyHostMessageCalls()) { + indent.writeln( + '$hostProxyApiPrefix${api.name}.setUpMessageHandlers(binaryMessenger, null)', + ); + } + } + }); + }, + ); + } + + // Writes the abstract method that instantiates a new instance of the Kotlin + // class. + void _writeProxyApiConstructorAbstractMethods( + Indent indent, + AstProxyApi api, { + required TypeDeclaration apiAsTypeDeclaration, + }) { + for (final Constructor constructor in api.constructors) { + _writeMethodDeclaration( + indent, + name: constructor.name.isNotEmpty + ? constructor.name + : '${classMemberNamePrefix}defaultConstructor', + returnType: apiAsTypeDeclaration, + documentationComments: constructor.documentationComments, + minApiRequirement: _findAndroidHighestApiRequirement([ + apiAsTypeDeclaration, + ...constructor.parameters.map( + (Parameter parameter) => parameter.type, + ), + ])?.version, + isAbstract: true, + parameters: [ + ...api.unattachedFields.map((ApiField field) { + return Parameter(name: field.name, type: field.type); + }), + ...constructor.parameters + ], + ); + indent.newln(); + } + } + + // Writes the abstract method that handles instantiating an attached field. + void _writeProxyApiAttachedFieldAbstractMethods( + Indent indent, + AstProxyApi api, { + required TypeDeclaration apiAsTypeDeclaration, + }) { + for (final ApiField field in api.attachedFields) { + _writeMethodDeclaration( + indent, + name: field.name, + documentationComments: field.documentationComments, + returnType: field.type, + isAbstract: true, + minApiRequirement: _findAndroidHighestApiRequirement([ + apiAsTypeDeclaration, + field.type, + ])?.version, + parameters: [ + if (!field.isStatic) + Parameter( + name: '${classMemberNamePrefix}instance', + type: apiAsTypeDeclaration, + ), + ], + ); + indent.newln(); + } + } + + // Writes the abstract method that handles accessing an unattached field. + void _writeProxyApiUnattachedFieldAbstractMethods( + Indent indent, + AstProxyApi api, { + required TypeDeclaration apiAsTypeDeclaration, + }) { + for (final ApiField field in api.unattachedFields) { + _writeMethodDeclaration( + indent, + name: field.name, + documentationComments: field.documentationComments, + returnType: field.type, + isAbstract: true, + minApiRequirement: _findAndroidHighestApiRequirement([ + apiAsTypeDeclaration, + field.type, + ])?.version, + parameters: [ + Parameter( + name: '${classMemberNamePrefix}instance', + type: apiAsTypeDeclaration, + ), + ], + ); + indent.newln(); + } + } + + // Writes the abstract method that handles making a call from for a host + // method. + void _writeProxyApiHostMethodAbstractMethods( + Indent indent, + AstProxyApi api, { + required TypeDeclaration apiAsTypeDeclaration, + }) { + for (final Method method in api.hostMethods) { + _writeMethodDeclaration( + indent, + name: method.name, + returnType: method.returnType, + documentationComments: method.documentationComments, + isAsynchronous: method.isAsynchronous, + isAbstract: true, + minApiRequirement: _findAndroidHighestApiRequirement( + [ + if (!method.isStatic) apiAsTypeDeclaration, + method.returnType, + ...method.parameters.map((Parameter p) => p.type), + ], + )?.version, + parameters: [ + if (!method.isStatic) + Parameter( + name: '${classMemberNamePrefix}instance', + type: apiAsTypeDeclaration, + ), + ...method.parameters, + ], + ); + indent.newln(); + } + } + + // Writes the `..setUpMessageHandler` method to ensure incoming messages are + // handled by the correct abstract host methods. + void _writeProxyApiMessageHandlerMethod( + Indent indent, + AstProxyApi api, { + required TypeDeclaration apiAsTypeDeclaration, + required String kotlinApiName, + required String dartPackageName, + required String fullKotlinClassName, + required KotlinOptions generatorOptions, + }) { + indent.writeln('@Suppress("LocalVariableName")'); + indent.writeScoped( + 'fun setUpMessageHandlers(binaryMessenger: BinaryMessenger, api: $kotlinApiName?) {', + '}', + () { + indent.writeln( + 'val codec = api?.pigeonRegistrar?.codec ?: ${generatorOptions.fileSpecificClassNameComponent}$_codecName()', + ); + void writeWithApiCheckIfNecessary( + List types, { + required String channelName, + required void Function() onWrite, + }) { + final ({TypeDeclaration type, int version})? typeWithRequirement = + _findAndroidHighestApiRequirement(types); + if (typeWithRequirement != null) { + final int apiRequirement = typeWithRequirement.version; + indent.writeScoped( + 'if (android.os.Build.VERSION.SDK_INT >= $apiRequirement) {', + '}', + onWrite, + addTrailingNewline: false, + ); + indent.writeScoped(' else {', '}', () { + final String className = typeWithRequirement + .type.associatedProxyApi!.kotlinOptions?.fullClassName ?? + typeWithRequirement.type.baseName; + indent.format( + ''' + val channel = BasicMessageChannel( + binaryMessenger, + "$channelName", + codec + ) + if (api != null) { + channel.setMessageHandler { _, reply -> + reply.reply(wrapError(UnsupportedOperationException( + "Call references class `$className`, which requires api version $apiRequirement." + ))) + } + } else { + channel.setMessageHandler(null) + }''', + ); + }); + } else { + onWrite(); + } + } + + for (final Constructor constructor in api.constructors) { + final String name = constructor.name.isNotEmpty + ? constructor.name + : '${classMemberNamePrefix}defaultConstructor'; + final String channelName = makeChannelNameWithStrings( + apiName: api.name, + methodName: name, + dartPackageName: dartPackageName, + ); + writeWithApiCheckIfNecessary( + [ + apiAsTypeDeclaration, + ...api.unattachedFields.map((ApiField f) => f.type), + ...constructor.parameters.map((Parameter p) => p.type), + ], + channelName: channelName, + onWrite: () { + _writeHostMethodMessageHandler( + indent, + name: name, + channelName: channelName, + taskQueueType: TaskQueueType.serial, + returnType: const TypeDeclaration.voidDeclaration(), + onCreateCall: ( + List methodParameters, { + required String apiVarName, + }) { + return '$apiVarName.pigeonRegistrar.instanceManager.addDartCreatedInstance(' + '$apiVarName.$name(${methodParameters.skip(1).join(',')}), ${methodParameters.first})'; + }, + parameters: [ + Parameter( + name: '${classMemberNamePrefix}identifier', + type: const TypeDeclaration( + baseName: 'int', + isNullable: false, + ), + ), + ...api.unattachedFields.map((ApiField field) { + return Parameter( + name: field.name, + type: field.type, + ); + }), + ...constructor.parameters, + ], + ); + }, + ); + } + + for (final ApiField field in api.attachedFields) { + final String channelName = makeChannelNameWithStrings( + apiName: api.name, + methodName: field.name, + dartPackageName: dartPackageName, + ); + writeWithApiCheckIfNecessary( + [apiAsTypeDeclaration, field.type], + channelName: channelName, + onWrite: () { + _writeHostMethodMessageHandler( + indent, + name: field.name, + channelName: channelName, + taskQueueType: TaskQueueType.serial, + returnType: const TypeDeclaration.voidDeclaration(), + onCreateCall: ( + List methodParameters, { + required String apiVarName, + }) { + final String param = + methodParameters.length > 1 ? methodParameters.first : ''; + return '$apiVarName.pigeonRegistrar.instanceManager.addDartCreatedInstance(' + '$apiVarName.${field.name}($param), ${methodParameters.last})'; + }, + parameters: [ + if (!field.isStatic) + Parameter( + name: '${classMemberNamePrefix}instance', + type: apiAsTypeDeclaration, + ), + Parameter( + name: '${classMemberNamePrefix}identifier', + type: const TypeDeclaration( + baseName: 'int', + isNullable: false, + ), + ), + ], + ); + }, + ); + } + + for (final Method method in api.hostMethods) { + final String channelName = + makeChannelName(api, method, dartPackageName); + writeWithApiCheckIfNecessary( + [ + if (!method.isStatic) apiAsTypeDeclaration, + method.returnType, + ...method.parameters.map((Parameter p) => p.type), + ], + channelName: channelName, + onWrite: () { + _writeHostMethodMessageHandler( + indent, + name: method.name, + channelName: makeChannelName(api, method, dartPackageName), + taskQueueType: method.taskQueueType, + returnType: method.returnType, + isAsynchronous: method.isAsynchronous, + parameters: [ + if (!method.isStatic) + Parameter( + name: '${classMemberNamePrefix}instance', + type: TypeDeclaration( + baseName: fullKotlinClassName, + isNullable: false, + associatedProxyApi: api, + ), + ), + ...method.parameters, + ], + ); + }, + ); + } + }, + ); + } + + // Writes the method that calls to Dart to instantiate a new Dart instance. + void _writeProxyApiNewInstanceMethod( + Indent indent, + AstProxyApi api, { + required KotlinOptions generatorOptions, + required TypeDeclaration apiAsTypeDeclaration, + required String newInstanceMethodName, + required String dartPackageName, + }) { + indent.writeln('@Suppress("LocalVariableName", "FunctionName")'); + _writeFlutterMethod( + indent, + generatorOptions: generatorOptions, + name: newInstanceMethodName, + returnType: const TypeDeclaration.voidDeclaration(), + documentationComments: [ + ' Creates a Dart instance of ${api.name} and attaches it to [${classMemberNamePrefix}instanceArg].', + ], + channelName: makeChannelNameWithStrings( + apiName: api.name, + methodName: newInstanceMethodName, + dartPackageName: dartPackageName, + ), + minApiRequirement: _findAndroidHighestApiRequirement([ + apiAsTypeDeclaration, + ...api.unattachedFields.map((ApiField field) => field.type), + ])?.version, + dartPackageName: dartPackageName, + parameters: [ + Parameter( + name: '${classMemberNamePrefix}instance', + type: TypeDeclaration( + baseName: api.name, + isNullable: false, + associatedProxyApi: api, + ), + ), + ], + onWriteBody: ( + Indent indent, { + required List parameters, + required TypeDeclaration returnType, + required String channelName, + required String errorClassName, + }) { + indent.writeScoped( + 'if (pigeonRegistrar.ignoreCallsToDart) {', + '}', + () { + indent.format( + ''' + callback( + Result.failure( + $errorClassName("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return''', + ); + }, + ); + indent.writeScoped( + 'if (pigeonRegistrar.instanceManager.containsInstance(${classMemberNamePrefix}instanceArg)) {', + '}', + () { + indent.writeln('Result.success(Unit)'); + indent.writeln('return'); + }, + ); + if (api.hasCallbackConstructor()) { + indent.writeln( + 'val ${classMemberNamePrefix}identifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance(${classMemberNamePrefix}instanceArg)', + ); + enumerate(api.unattachedFields, (int index, ApiField field) { + final String argName = _getSafeArgumentName(index, field); + indent.writeln( + 'val $argName = ${field.name}(${classMemberNamePrefix}instanceArg)', + ); + }); + + indent + .writeln('val binaryMessenger = pigeonRegistrar.binaryMessenger'); + indent.writeln('val codec = pigeonRegistrar.codec'); + _writeFlutterMethodMessageCall( + indent, + returnType: returnType, + channelName: channelName, + errorClassName: errorClassName, + parameters: [ + Parameter( + name: '${classMemberNamePrefix}identifier', + type: const TypeDeclaration( + baseName: 'int', + isNullable: false, + ), + ), + ...api.unattachedFields.map( + (ApiField field) { + return Parameter(name: field.name, type: field.type); + }, + ), + ], + ); + } else { + indent.writeln( + 'throw IllegalStateException("Attempting to create a new Dart instance of ${api.name}, but the class has a nonnull callback method.")', + ); + } + }, + ); + indent.newln(); + } + + // Writes the Flutter methods that call back to Dart. + void _writeProxyApiFlutterMethods( + Indent indent, + AstProxyApi api, { + required KotlinOptions generatorOptions, + required TypeDeclaration apiAsTypeDeclaration, + required String dartPackageName, + }) { + for (final Method method in api.flutterMethods) { + _writeFlutterMethod( + indent, + generatorOptions: generatorOptions, + name: method.name, + returnType: method.returnType, + channelName: makeChannelName(api, method, dartPackageName), + dartPackageName: dartPackageName, + documentationComments: method.documentationComments, + minApiRequirement: _findAndroidHighestApiRequirement([ + apiAsTypeDeclaration, + method.returnType, + ...method.parameters.map((Parameter parameter) => parameter.type), + ])?.version, + parameters: [ + Parameter( + name: '${classMemberNamePrefix}instance', + type: TypeDeclaration( + baseName: api.name, + isNullable: false, + associatedProxyApi: api, + ), + ), + ...method.parameters, + ], + onWriteBody: ( + Indent indent, { + required List parameters, + required TypeDeclaration returnType, + required String channelName, + required String errorClassName, + }) { + indent.writeScoped( + 'if (pigeonRegistrar.ignoreCallsToDart) {', + '}', + () { + indent.format( + ''' + callback( + Result.failure( + $errorClassName("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return''', + ); + }, + ); + indent + .writeln('val binaryMessenger = pigeonRegistrar.binaryMessenger'); + indent.writeln('val codec = pigeonRegistrar.codec'); + _writeFlutterMethodMessageCall( + indent, + returnType: returnType, + channelName: channelName, + errorClassName: errorClassName, + parameters: parameters, + ); + }, + ); + indent.newln(); + } + } + + // Writes the getters for accessing the implementation of other ProxyApis. + // + // These are used for inherited Flutter methods. + void _writeProxyApiInheritedApiMethods(Indent indent, AstProxyApi api) { + final Set inheritedApiNames = { + if (api.superClass != null) api.superClass!.baseName, + ...api.interfaces.map((TypeDeclaration type) => type.baseName), + }; + for (final String name in inheritedApiNames) { + indent.writeln('@Suppress("FunctionName")'); + final String apiName = '$hostProxyApiPrefix$name'; + _writeMethodDeclaration( + indent, + name: '${classMemberNamePrefix}get$apiName', + documentationComments: [ + ' An implementation of [$apiName] used to access callback methods', + ], + returnType: TypeDeclaration(baseName: apiName, isNullable: false), + parameters: [], + ); + + indent.writeScoped('{', '}', () { + indent.writeln('return pigeonRegistrar.get$apiName()'); + }); + indent.newln(); + } + } +} + +({TypeDeclaration type, int version})? _findAndroidHighestApiRequirement( + Iterable types, +) { + return findHighestApiRequirement( + types, + onGetApiRequirement: (TypeDeclaration type) { + return type.associatedProxyApi?.kotlinOptions?.minAndroidApi; + }, + onCompare: (int first, int second) => first.compareTo(second), + ); } String _getErrorClassName(KotlinOptions generatorOptions) => @@ -886,8 +2052,19 @@ String? _kotlinTypeForBuiltinDartType(TypeDeclaration type) { } } +String? _kotlinTypeForProxyApiType(TypeDeclaration type) { + if (type.isProxyApi) { + return type.associatedProxyApi!.kotlinOptions?.fullClassName ?? + type.associatedProxyApi!.name; + } + + return null; +} + String _kotlinTypeForDartType(TypeDeclaration type) { - return _kotlinTypeForBuiltinDartType(type) ?? type.baseName; + return _kotlinTypeForBuiltinDartType(type) ?? + _kotlinTypeForProxyApiType(type) ?? + type.baseName; } String _nullSafeKotlinTypeForDartType(TypeDeclaration type) { @@ -902,13 +2079,5 @@ String _cast(Indent indent, String variable, {required TypeDeclaration type}) { if (type.isNullable && typeString == 'Any') { return variable; } - if (typeString == 'Int' || typeString == 'Long') { - return '$variable${_castInt(type.isNullable)}'; - } return '$variable as ${_nullSafeKotlinTypeForDartType(type)}'; } - -String _castInt(bool isNullable) { - final String nullability = isNullable ? '?' : ''; - return '.let { num -> if (num is Int) num.toLong() else num as Long$nullability }'; -} diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index e378fbac1c2f..d0e0e99ee293 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -15,6 +15,24 @@ const String _docCommentPrefix = '///'; const DocumentCommentSpecification _docCommentSpec = DocumentCommentSpecification(_docCommentPrefix); +const String _overflowClassName = '${classNamePrefix}CodecOverflow'; + +final NamedType _overflowInt = NamedType( + name: 'type', + type: const TypeDeclaration(baseName: 'int', isNullable: false)); +final NamedType _overflowObject = NamedType( + name: 'wrapped', + type: const TypeDeclaration(baseName: 'Object', isNullable: true)); +final List _overflowFields = [ + _overflowInt, + _overflowObject, +]; +final Class _overflowClass = + Class(name: _overflowClassName, fields: _overflowFields); +final EnumeratedType _enumeratedOverflow = EnumeratedType( + _overflowClassName, maximumCodecFieldKey, CustomTypes.customClass, + associatedClass: _overflowClass); + /// Options that control how Objective-C code will be generated. class ObjcOptions { /// Parametric constructor for ObjcOptions. @@ -207,56 +225,12 @@ class ObjcHeaderGenerator extends StructuredGenerator { Class classDefinition, { required String dartPackageName, }) { - final String? prefix = generatorOptions.prefix; - - addDocumentationComments( - indent, classDefinition.documentationComments, _docCommentSpec); - - indent.writeln( - '@interface ${_className(prefix, classDefinition.name)} : NSObject'); - if (getFieldsInSerializationOrder(classDefinition).isNotEmpty) { - if (getFieldsInSerializationOrder(classDefinition) - .map((NamedType e) => !e.type.isNullable) - .any((bool e) => e)) { - indent.writeln( - '$_docCommentPrefix `init` unavailable to enforce nonnull fields, see the `make` class method.'); - indent.writeln('- (instancetype)init NS_UNAVAILABLE;'); - } - _writeObjcSourceClassInitializerDeclaration( - indent, - generatorOptions, - root, - classDefinition, - prefix, - ); - indent.addln(';'); - } - for (final NamedType field - in getFieldsInSerializationOrder(classDefinition)) { - final HostDatatype hostDatatype = getFieldHostDatatype( - field, - (TypeDeclaration x) => _objcTypeStringForPrimitiveDartType(prefix, x, - beforeString: true), - customResolver: field.type.isEnum - ? (String x) => _enumName(x, prefix: prefix) - : (String x) => '${_className(prefix, x)} *'); - late final String propertyType; - addDocumentationComments( - indent, field.documentationComments, _docCommentSpec); - propertyType = _propertyTypeForDartType(field.type, - isNullable: field.type.isNullable, isEnum: field.type.isEnum); - final String nullability = field.type.isNullable ? ', nullable' : ''; - final String fieldType = field.type.isEnum && field.type.isNullable - ? _enumName(field.type.baseName, - suffix: ' *', - prefix: generatorOptions.prefix, - box: field.type.isNullable) - : hostDatatype.datatype; - indent.writeln( - '@property(nonatomic, $propertyType$nullability) $fieldType ${field.name};'); - } - indent.writeln('@end'); - indent.newln(); + _writeDataClassDeclaration( + generatorOptions, + root, + indent, + classDefinition, + ); } @override @@ -323,7 +297,7 @@ class ObjcHeaderGenerator extends StructuredGenerator { final _ObjcType returnType = _objcTypeForDartType( generatorOptions.prefix, func.returnType, // Nullability is required since the return must be nil if NSError is set. - forceNullability: true, + forceBox: true, ); final String callbackType = _callbackForType(func.returnType, returnType, generatorOptions); @@ -362,7 +336,7 @@ class ObjcHeaderGenerator extends StructuredGenerator { func.returnType, // Nullability is required since the return must be nil if NSError is // set. - forceNullability: true, + forceBox: true, ); String? lastArgName; @@ -505,7 +479,10 @@ class ObjcSourceGenerator extends StructuredGenerator { }) { for (final Class classDefinition in root.classes) { _writeObjcSourceDataClassExtension( - generatorOptions, indent, classDefinition); + generatorOptions, + indent, + classDefinition, + ); } indent.newln(); super.writeDataClasses( @@ -524,16 +501,12 @@ class ObjcSourceGenerator extends StructuredGenerator { Class classDefinition, { required String dartPackageName, }) { - final Set customClassNames = - root.classes.map((Class x) => x.name).toSet(); - final Set customEnumNames = - root.enums.map((Enum x) => x.name).toSet(); final String className = _className(generatorOptions.prefix, classDefinition.name); indent.writeln('@implementation $className'); - _writeObjcSourceClassInitializer(generatorOptions, root, indent, - classDefinition, customClassNames, customEnumNames, className); + _writeObjcSourceClassInitializer( + generatorOptions, root, indent, classDefinition, className); writeClassDecode( generatorOptions, root, @@ -592,13 +565,16 @@ class ObjcSourceGenerator extends StructuredGenerator { _nsnumberExtractionMethod(field.type); final String ivarValueExpression; if (field.type.isEnum && !field.type.isNullable) { + final String varName = + 'boxed${_enumName(field.type.baseName, prefix: generatorOptions.prefix)}'; _writeEnumBoxToEnum( indent, field, + varName, valueGetter, prefix: generatorOptions.prefix, ); - ivarValueExpression = 'enumBox.value'; + ivarValueExpression = '$varName.value'; } else if (primitiveExtractionMethod != null) { ivarValueExpression = '[$valueGetter $primitiveExtractionMethod]'; } else { @@ -616,6 +592,100 @@ class ObjcSourceGenerator extends StructuredGenerator { }); } + void _writeCodecOverflowUtilities( + ObjcOptions generatorOptions, + Root root, + Indent indent, + List types, { + required String dartPackageName, + }) { + _writeObjcSourceDataClassExtension( + generatorOptions, + indent, + _overflowClass, + returnType: 'id', + isOverflowClass: true, + ); + indent.newln(); + indent.writeln( + '@implementation ${_className(generatorOptions.prefix, _overflowClassName)}'); + + _writeObjcSourceClassInitializer( + generatorOptions, + root, + indent, + _overflowClass, + _className(generatorOptions.prefix, _overflowClassName)); + writeClassEncode( + generatorOptions, + root, + indent, + _overflowClass, + dartPackageName: dartPackageName, + ); + + indent.format(''' ++ (id)fromList:(NSArray *)list { + ${_className(generatorOptions.prefix, _overflowClassName)} *wrapper = [[${_className(generatorOptions.prefix, _overflowClassName)} alloc] init]; + wrapper.type = [GetNullableObjectAtIndex(list, 0) integerValue]; + wrapper.wrapped = GetNullableObjectAtIndex(list, 1); + return [wrapper unwrap]; +} +'''); + + indent.writeScoped('- (id) unwrap {', '}', () { + indent.format(''' +if (self.wrapped == nil) { + return nil; +} + '''); + indent.writeScoped('switch (self.type) {', '}', () { + for (int i = totalCustomCodecKeysAllowed; i < types.length; i++) { + indent.write('case ${i - totalCustomCodecKeysAllowed}:'); + _writeCodecDecode( + indent, + types[i], + generatorOptions.prefix ?? '', + isOverflowClass: true, + ); + } + indent.writeScoped('default: ', '', () { + indent.writeln('return nil;'); + }, addTrailingNewline: false); + }); + }); + indent.writeln('@end'); + } + + void _writeCodecDecode( + Indent indent, EnumeratedType customType, String? prefix, + {bool isOverflowClass = false}) { + String readValue = '[self readValue]'; + if (isOverflowClass) { + readValue = 'self.wrapped'; + } + if (customType.type == CustomTypes.customClass) { + indent.addScoped('', null, () { + indent.writeln( + 'return [${_className(prefix, customType.name)} fromList:$readValue];'); + }, addTrailingNewline: false); + } else if (customType.type == CustomTypes.customEnum) { + indent.addScoped( + !isOverflowClass ? '{' : '', !isOverflowClass ? '}' : null, () { + String enumAsNumber = 'enumAsNumber'; + if (!isOverflowClass) { + indent.writeln('NSNumber *$enumAsNumber = $readValue;'); + indent.write('return $enumAsNumber == nil ? nil : '); + } else { + enumAsNumber = 'self.wrapped'; + indent.write('return '); + } + indent.addln( + '[[${_enumName(customType.name, prefix: prefix, box: true)} alloc] initWithValue:[$enumAsNumber integerValue]];'); + }, addTrailingNewline: !isOverflowClass); + } + } + @override void writeGeneralCodec( ObjcOptions generatorOptions, @@ -624,34 +694,41 @@ class ObjcSourceGenerator extends StructuredGenerator { required String dartPackageName, }) { const String codecName = 'PigeonCodec'; - final Iterable codecClasses = getEnumeratedTypes(root); + final List enumeratedTypes = + getEnumeratedTypes(root).toList(); final String readerWriterName = '${generatorOptions.prefix}${toUpperCamelCase(generatorOptions.fileSpecificClassNameComponent ?? '')}${codecName}ReaderWriter'; final String readerName = '${generatorOptions.prefix}${toUpperCamelCase(generatorOptions.fileSpecificClassNameComponent ?? '')}${codecName}Reader'; final String writerName = '${generatorOptions.prefix}${toUpperCamelCase(generatorOptions.fileSpecificClassNameComponent ?? '')}${codecName}Writer'; + + if (root.requiresOverflowClass) { + _writeCodecOverflowUtilities( + generatorOptions, root, indent, enumeratedTypes, + dartPackageName: dartPackageName); + } + indent.writeln('@interface $readerName : FlutterStandardReader'); indent.writeln('@end'); indent.writeln('@implementation $readerName'); indent.write('- (nullable id)readValueOfType:(UInt8)type '); indent.addScoped('{', '}', () { - indent.write('switch (type) '); - indent.addScoped('{', '}', () { - for (final EnumeratedType customType in codecClasses) { - indent.writeln('case ${customType.enumeration}: '); - indent.nest(1, () { - if (customType.type == CustomTypes.customClass) { - indent.writeln( - 'return [${_className(generatorOptions.prefix, customType.name)} fromList:[self readValue]];'); - } else if (customType.type == CustomTypes.customEnum) { - indent.writeScoped('{', '}', () { - indent.writeln('NSNumber *enumAsNumber = [self readValue];'); - indent.writeln( - 'return enumAsNumber == nil ? nil : [[${_enumName(customType.name, prefix: generatorOptions.prefix, box: true)} alloc] initWithValue:[enumAsNumber integerValue]];'); - }); - } - }); + indent.writeScoped('switch (type) {', '}', () { + for (final EnumeratedType customType in enumeratedTypes) { + if (customType.enumeration < maximumCodecFieldKey) { + indent.write('case ${customType.enumeration}: '); + _writeCodecDecode( + indent, customType, generatorOptions.prefix ?? ''); + } + } + if (root.requiresOverflowClass) { + indent.write('case $maximumCodecFieldKey: '); + _writeCodecDecode( + indent, + _enumeratedOverflow, + generatorOptions.prefix, + ); } indent.writeln('default:'); indent.nest(1, () { @@ -666,30 +743,33 @@ class ObjcSourceGenerator extends StructuredGenerator { indent.writeln('@implementation $writerName'); indent.write('- (void)writeValue:(id)value '); indent.addScoped('{', '}', () { - bool firstClass = true; - for (final EnumeratedType customClass in codecClasses) { - if (firstClass) { - indent.write(''); - firstClass = false; - } - if (customClass.type == CustomTypes.customClass) { - indent.add( - 'if ([value isKindOfClass:[${_className(generatorOptions.prefix, customClass.name)} class]]) '); - indent.addScoped('{', '} else ', () { - indent.writeln('[self writeByte:${customClass.enumeration}];'); - indent.writeln('[self writeValue:[value toList]];'); - }, addTrailingNewline: false); - } else if (customClass.type == CustomTypes.customEnum) { - final String boxName = _enumName(customClass.name, - prefix: generatorOptions.prefix, box: true); - indent.add('if ([value isKindOfClass:[$boxName class]]) '); - indent.addScoped('{', '} else ', () { - indent.writeln('$boxName * box = ($boxName *)value;'); - indent.writeln('[self writeByte:${customClass.enumeration}];'); + indent.write(''); + for (final EnumeratedType customType in enumeratedTypes) { + final String encodeString = customType.type == CustomTypes.customClass + ? '[value toList]' + : '(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])'; + final String valueString = customType.enumeration < maximumCodecFieldKey + ? encodeString + : '[wrap toList]'; + final String className = customType.type == CustomTypes.customClass + ? _className(generatorOptions.prefix, customType.name) + : _enumName(customType.name, + prefix: generatorOptions.prefix, box: true); + indent.addScoped( + 'if ([value isKindOfClass:[$className class]]) {', '} else ', () { + if (customType.type == CustomTypes.customEnum) { + indent.writeln('$className *box = ($className *)value;'); + } + final int enumeration = customType.enumeration < maximumCodecFieldKey + ? customType.enumeration + : maximumCodecFieldKey; + if (customType.enumeration >= maximumCodecFieldKey) { indent.writeln( - '[self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])];'); - }, addTrailingNewline: false); - } + '${_className(generatorOptions.prefix, _overflowClassName)} *wrap = [${_className(generatorOptions.prefix, _overflowClassName)} makeWithType:${customType.enumeration - maximumCodecFieldKey} wrapped:$encodeString];'); + } + indent.writeln('[self writeByte:$enumeration];'); + indent.writeln('[self writeValue:$valueString];'); + }, addTrailingNewline: false); } indent.addScoped('{', '}', () { indent.writeln('[super writeValue:value];'); @@ -840,6 +920,15 @@ class ObjcSourceGenerator extends StructuredGenerator { if (hasHostApi || hasFlutterApi) { _writeGetNullableObjectAtIndex(indent); } + + if (root.requiresOverflowClass) { + _writeDataClassDeclaration( + generatorOptions, + root, + indent, + _overflowClass, + ); + } } void _writeWrapError(Indent indent) { @@ -886,13 +975,16 @@ static FlutterError *createConnectionError(NSString *channelName) { final String ivarValueExpression; String beforeString = objcArgType.beforeString; if (arg.type.isEnum && !arg.type.isNullable) { + final String varName = + 'boxed${_enumName(arg.type.baseName, prefix: generatorOptions.prefix)}'; _writeEnumBoxToEnum( indent, arg, + varName, valueGetter, prefix: generatorOptions.prefix, ); - ivarValueExpression = 'enumBox.value'; + ivarValueExpression = '$varName.value'; } else if (primitiveExtractionMethod != null) { ivarValueExpression = '[$valueGetter $primitiveExtractionMethod]'; } else { @@ -980,7 +1072,7 @@ static FlutterError *createConnectionError(NSString *channelName) { final _ObjcType returnType = _objcTypeForDartType( generatorOptions.prefix, func.returnType, // Nullability is required since the return must be nil if NSError is set. - forceNullability: true, + forceBox: true, ); final Iterable selectorComponents = _getSelectorComponents(func, lastSelectorComponent); @@ -1036,14 +1128,23 @@ static FlutterError *createConnectionError(NSString *channelName) { } void _writeObjcSourceDataClassExtension( - ObjcOptions languageOptions, Indent indent, Class classDefinition) { + ObjcOptions languageOptions, + Indent indent, + Class classDefinition, { + String? returnType, + bool isOverflowClass = false, + }) { final String className = _className(languageOptions.prefix, classDefinition.name); + returnType = returnType ?? className; indent.newln(); indent.writeln('@interface $className ()'); - indent.writeln('+ ($className *)fromList:(NSArray *)list;'); indent.writeln( - '+ (nullable $className *)nullableFromList:(NSArray *)list;'); + '+ ($returnType${isOverflowClass ? '' : ' *'})fromList:(NSArray *)list;'); + if (!isOverflowClass) { + indent.writeln( + '+ (nullable $returnType *)nullableFromList:(NSArray *)list;'); + } indent.writeln('- (NSArray *)toList;'); indent.writeln('@end'); } @@ -1053,8 +1154,6 @@ static FlutterError *createConnectionError(NSString *channelName) { Root root, Indent indent, Class classDefinition, - Set customClassNames, - Set customEnumNames, String className, ) { _writeObjcSourceClassInitializerDeclaration( @@ -1088,7 +1187,7 @@ void _writeMethod( languageOptions.prefix, func.returnType, // Nullability is required since the return must be nil if NSError is set. - forceNullability: true, + forceBox: true, ); final String callbackType = _callbackForType(func.returnType, returnType, languageOptions); @@ -1341,28 +1440,27 @@ String? _nsnumberExtractionMethod( /// Example: ('FOO', ['Foo', 'Bar']) -> 'FOOFoo *, FOOBar *'). String _flattenTypeArguments(String? classPrefix, List args) { final String result = args.map((TypeDeclaration e) { - // print(e); if (e.isEnum) { return _enumName(e.baseName, prefix: classPrefix, box: true, suffix: ' *'); } - return _objcTypeForDartType(classPrefix, e).toString(); + return _objcTypeForDartType(classPrefix, e, forceBox: true).toString(); }).join(', '); return result; } _ObjcType? _objcTypeForPrimitiveDartType(TypeDeclaration type, - {bool forceNullability = false}) { - return forceNullability || type.isNullable + {bool forceBox = false}) { + return forceBox || type.isNullable ? _objcTypeForNullableDartTypeMap[type.baseName] : _objcTypeForNonNullableDartTypeMap[type.baseName]; } String? _objcTypeStringForPrimitiveDartType( String? classPrefix, TypeDeclaration type, - {required bool beforeString, bool forceNullability = false}) { + {required bool beforeString, bool forceBox = false}) { final _ObjcType? objcType; - if (forceNullability || type.isNullable) { + if (forceBox || type.isNullable) { objcType = _objcTypeForNullableDartTypeMap.containsKey(type.baseName) ? _objcTypeForDartType(classPrefix, type) : null; @@ -1377,14 +1475,14 @@ String? _objcTypeStringForPrimitiveDartType( /// Returns the Objective-C type for a Dart [field], prepending the /// [classPrefix] for generated classes. _ObjcType _objcTypeForDartType(String? classPrefix, TypeDeclaration field, - {bool forceNullability = false}) { + {bool forceBox = false}) { final _ObjcType? primitiveType = - _objcTypeForPrimitiveDartType(field, forceNullability: forceNullability); + _objcTypeForPrimitiveDartType(field, forceBox: forceBox); return primitiveType == null ? _ObjcType( baseName: _className(classPrefix, field.baseName), // Non-nullable enums are non-pointer types. - isPointer: !field.isEnum || (field.isNullable || forceNullability)) + isPointer: !field.isEnum || (field.isNullable || forceBox)) : field.typeArguments.isEmpty ? primitiveType : _ObjcType( @@ -1417,7 +1515,7 @@ String _propertyTypeForDartType(TypeDeclaration type, } String _capitalize(String str) => - (str.isEmpty) ? '' : str[0].toUpperCase() + str.substring(1); + str.isEmpty ? '' : str[0].toUpperCase() + str.substring(1); /// Returns the components of the objc selector that will be generated from /// [func], ie the strings between the semicolons. [lastSelectorComponent] is @@ -1572,11 +1670,12 @@ List validateObjc(ObjcOptions options, Root root) { void _writeEnumBoxToEnum( Indent indent, NamedType field, + String varName, String valueGetter, { String? prefix = '', }) { indent.writeln( - '${_enumName(field.type.baseName, prefix: prefix, box: true, suffix: ' *')}enumBox = $valueGetter;'); + '${_enumName(field.type.baseName, prefix: prefix, box: true, suffix: ' *')}$varName = $valueGetter;'); } String _getEnumToEnumBox( @@ -1586,3 +1685,61 @@ String _getEnumToEnumBox( }) { return '[[${_enumName(field.type.baseName, prefix: prefix, box: true)} alloc] initWithValue:$valueSetter]'; } + +void _writeDataClassDeclaration( + ObjcOptions generatorOptions, + Root root, + Indent indent, + Class classDefinition, +) { + final String? prefix = generatorOptions.prefix; + + addDocumentationComments( + indent, classDefinition.documentationComments, _docCommentSpec); + + indent.writeln( + '@interface ${_className(prefix, classDefinition.name)} : NSObject'); + if (getFieldsInSerializationOrder(classDefinition).isNotEmpty) { + if (getFieldsInSerializationOrder(classDefinition) + .map((NamedType e) => !e.type.isNullable) + .any((bool e) => e)) { + indent.writeln( + '$_docCommentPrefix `init` unavailable to enforce nonnull fields, see the `make` class method.'); + indent.writeln('- (instancetype)init NS_UNAVAILABLE;'); + } + _writeObjcSourceClassInitializerDeclaration( + indent, + generatorOptions, + root, + classDefinition, + prefix, + ); + indent.addln(';'); + } + for (final NamedType field + in getFieldsInSerializationOrder(classDefinition)) { + final HostDatatype hostDatatype = getFieldHostDatatype( + field, + (TypeDeclaration x) => + _objcTypeStringForPrimitiveDartType(prefix, x, beforeString: true), + customResolver: field.type.isEnum + ? (String x) => _enumName(x, prefix: prefix) + : (String x) => '${_className(prefix, x)} *'); + late final String propertyType; + addDocumentationComments( + indent, field.documentationComments, _docCommentSpec); + propertyType = _propertyTypeForDartType(field.type, + isNullable: field.type.isNullable, isEnum: field.type.isEnum); + final String nullability = field.type.isNullable ? ', nullable' : ''; + final String fieldType = field.type.isEnum && field.type.isNullable + ? _enumName(field.type.baseName, + suffix: ' *', + prefix: generatorOptions.prefix, + box: field.type.isNullable) + : hostDatatype.datatype; + indent.writeln( + '@property(nonatomic, $propertyType$nullability) $fieldType ${field.name};'); + } + indent.writeln('@end'); + indent.newln(); +} diff --git a/packages/pigeon/lib/pigeon.dart b/packages/pigeon/lib/pigeon.dart index 7f2fb7505fa8..bfa23ad58017 100644 --- a/packages/pigeon/lib/pigeon.dart +++ b/packages/pigeon/lib/pigeon.dart @@ -6,8 +6,9 @@ export 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; export 'cpp_generator.dart' show CppOptions; export 'dart_generator.dart' show DartOptions; +export 'gobject_generator.dart' show GObjectOptions; export 'java_generator.dart' show JavaOptions; -export 'kotlin_generator.dart' show KotlinOptions; +export 'kotlin_generator.dart' show KotlinOptions, KotlinProxyApiOptions; export 'objc_generator.dart' show ObjcOptions; export 'pigeon_lib.dart'; -export 'swift_generator.dart' show SwiftOptions; +export 'swift_generator.dart' show SwiftOptions, SwiftProxyApiOptions; diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index 2592dd24c55c..075049d98298 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -23,6 +23,7 @@ import 'package:analyzer/error/error.dart' show AnalysisError; import 'package:args/args.dart'; import 'package:collection/collection.dart' as collection; import 'package:path/path.dart' as path; +import 'package:pub_semver/pub_semver.dart'; import 'ast.dart'; import 'ast_generator.dart'; @@ -30,6 +31,7 @@ import 'cpp_generator.dart'; import 'dart_generator.dart'; import 'generator_tools.dart'; import 'generator_tools.dart' as generator_tools; +import 'gobject_generator.dart'; import 'java_generator.dart'; import 'kotlin_generator.dart'; import 'objc_generator.dart'; @@ -65,7 +67,7 @@ const Object async = _Asynchronous(); /// /// ```dart /// class MyProxyApi { -/// final MyOtherProxyApi myField = __pigeon_myField(). +/// final MyOtherProxyApi myField = pigeon_myField(). /// } /// ``` /// @@ -138,7 +140,7 @@ class FlutterApi { /// methods. class ProxyApi { /// Parametric constructor for [ProxyApi]. - const ProxyApi({this.superClass}); + const ProxyApi({this.superClass, this.kotlinOptions, this.swiftOptions}); /// The proxy api that is a super class to this one. /// @@ -148,6 +150,14 @@ class ProxyApi { /// Note that using this instead of `extends` can cause unexpected conflicts /// with inherited method names. final Type? superClass; + + /// Options that control how Swift code will be generated for a specific + /// ProxyApi. + final SwiftProxyApiOptions? swiftOptions; + + /// Options that control how Kotlin code will be generated for a specific + /// ProxyApi. + final KotlinProxyApiOptions? kotlinOptions; } /// Metadata to annotation methods to control the selector used for objc output. @@ -253,6 +263,9 @@ class PigeonOptions { this.cppHeaderOut, this.cppSourceOut, this.cppOptions, + this.gobjectHeaderOut, + this.gobjectSourceOut, + this.gobjectOptions, this.dartOptions, this.copyrightHeader, this.oneLanguage, @@ -307,6 +320,15 @@ class PigeonOptions { /// Options that control how C++ will be generated. final CppOptions? cppOptions; + /// Path to the ".h" GObject file that will be generated. + final String? gobjectHeaderOut; + + /// Path to the ".cc" GObject file that will be generated. + final String? gobjectSourceOut; + + /// Options that control how GObject source will be generated. + final GObjectOptions? gobjectOptions; + /// Options that control how Dart will be generated. final DartOptions? dartOptions; @@ -357,6 +379,12 @@ class PigeonOptions { cppOptions: map.containsKey('cppOptions') ? CppOptions.fromMap(map['cppOptions']! as Map) : null, + gobjectHeaderOut: map['gobjectHeaderOut'] as String?, + gobjectSourceOut: map['gobjectSourceOut'] as String?, + gobjectOptions: map.containsKey('gobjectOptions') + ? GObjectOptions.fromMap( + map['gobjectOptions']! as Map) + : null, dartOptions: map.containsKey('dartOptions') ? DartOptions.fromMap(map['dartOptions']! as Map) : null, @@ -388,6 +416,9 @@ class PigeonOptions { if (cppHeaderOut != null) 'cppHeaderOut': cppHeaderOut!, if (cppSourceOut != null) 'cppSourceOut': cppSourceOut!, if (cppOptions != null) 'cppOptions': cppOptions!.toMap(), + if (gobjectHeaderOut != null) 'gobjectHeaderOut': gobjectHeaderOut!, + if (gobjectSourceOut != null) 'gobjectSourceOut': gobjectSourceOut!, + if (gobjectOptions != null) 'gobjectOptions': gobjectOptions!.toMap(), if (dartOptions != null) 'dartOptions': dartOptions!.toMap(), if (copyrightHeader != null) 'copyrightHeader': copyrightHeader!, if (astOut != null) 'astOut': astOut!, @@ -714,6 +745,7 @@ class SwiftGeneratorAdapter implements GeneratorAdapter { path.posix.join(options.basePath ?? '', options.copyrightHeader)) : null, errorClassName: swiftOptions.errorClassName, + includeErrorClass: swiftOptions.includeErrorClass, )); const SwiftGenerator generator = SwiftGenerator(); generator.generate( @@ -776,6 +808,64 @@ class CppGeneratorAdapter implements GeneratorAdapter { List validate(PigeonOptions options, Root root) => []; } +/// A [GeneratorAdapter] that generates GObject source code. +class GObjectGeneratorAdapter implements GeneratorAdapter { + /// Constructor for [GObjectGeneratorAdapter]. + GObjectGeneratorAdapter( + {this.fileTypeList = const [FileType.header, FileType.source]}); + + @override + List fileTypeList; + + @override + void generate( + StringSink sink, PigeonOptions options, Root root, FileType fileType) { + final GObjectOptions gobjectOptions = + options.gobjectOptions ?? const GObjectOptions(); + final GObjectOptions gobjectOptionsWithHeader = + gobjectOptions.merge(GObjectOptions( + copyrightHeader: options.copyrightHeader != null + ? _lineReader( + path.posix.join(options.basePath ?? '', options.copyrightHeader)) + : null, + )); + final OutputFileOptions outputFileOptions = + OutputFileOptions( + fileType: fileType, languageOptions: gobjectOptionsWithHeader); + const GObjectGenerator generator = GObjectGenerator(); + generator.generate( + outputFileOptions, + root, + sink, + dartPackageName: options.getPackageName(), + ); + } + + @override + IOSink? shouldGenerate(PigeonOptions options, FileType fileType) { + if (fileType == FileType.source) { + return _openSink(options.gobjectSourceOut, + basePath: options.basePath ?? ''); + } else { + return _openSink(options.gobjectHeaderOut, + basePath: options.basePath ?? ''); + } + } + + @override + List validate(PigeonOptions options, Root root) { + final List errors = []; + // TODO(tarrinneal): Remove once overflow class is added to gobject generator. + // https://github.com/flutter/flutter/issues/152916 + if (root.classes.length + root.enums.length > totalCustomCodecKeysAllowed) { + errors.add(Error( + message: + 'GObject generator does not yet support more than $totalCustomCodecKeysAllowed custom types.')); + } + return errors; + } +} + /// A [GeneratorAdapter] that generates Kotlin source code. class KotlinGeneratorAdapter implements GeneratorAdapter { /// Constructor for [KotlinGeneratorAdapter]. @@ -839,24 +929,53 @@ List _validateAst(Root root, String source) { final List customClasses = root.classes.map((Class x) => x.name).toList(); final Iterable customEnums = root.enums.map((Enum x) => x.name); + for (final Enum enumDefinition in root.enums) { + final String? matchingPrefix = _findMatchingPrefixOrNull( + enumDefinition.name, + prefixes: disallowedPrefixes, + ); + if (matchingPrefix != null) { + result.add(Error( + message: + 'Enum name must not begin with "$matchingPrefix" in enum "${enumDefinition.name}"', + )); + } + for (final EnumMember enumMember in enumDefinition.members) { + final String? matchingPrefix = _findMatchingPrefixOrNull( + enumMember.name, + prefixes: disallowedPrefixes, + ); + if (matchingPrefix != null) { + result.add(Error( + message: + 'Enum member name must not begin with "$matchingPrefix" in enum member "${enumMember.name}" of enum "${enumDefinition.name}"', + )); + } + } + } for (final Class classDefinition in root.classes) { + final String? matchingPrefix = _findMatchingPrefixOrNull( + classDefinition.name, + prefixes: disallowedPrefixes, + ); + if (matchingPrefix != null) { + result.add(Error( + message: + 'Class name must not begin with "$matchingPrefix" in class "${classDefinition.name}"', + )); + } for (final NamedType field in getFieldsInSerializationOrder(classDefinition)) { - for (final TypeDeclaration typeArgument in field.type.typeArguments) { - if (!typeArgument.isNullable) { - result.add(Error( - message: - 'Generic type parameters must be nullable in field "${field.name}" in class "${classDefinition.name}".', - lineNumber: _calculateLineNumberNullable(source, field.offset), - )); - } - if (customEnums.contains(typeArgument.baseName)) { - result.add(Error( - message: - 'Enum types aren\'t supported in type arguments in "${field.name}" in class "${classDefinition.name}".', - lineNumber: _calculateLineNumberNullable(source, field.offset), - )); - } + final String? matchingPrefix = _findMatchingPrefixOrNull( + field.name, + prefixes: disallowedPrefixes, + ); + if (matchingPrefix != null) { + result.add(Error( + message: + 'Class field name must not begin with "$matchingPrefix" in field "${field.name}" of class "${classDefinition.name}"', + lineNumber: _calculateLineNumberNullable(source, field.offset), + )); } if (!(validTypes.contains(field.type.baseName) || customClasses.contains(field.type.baseName) || @@ -871,6 +990,16 @@ List _validateAst(Root root, String source) { } for (final Api api in root.apis) { + final String? matchingPrefix = _findMatchingPrefixOrNull( + api.name, + prefixes: disallowedPrefixes, + ); + if (matchingPrefix != null) { + result.add(Error( + message: + 'API name must not begin with "$matchingPrefix" in API "${api.name}"', + )); + } if (api is AstProxyApi) { result.addAll(_validateProxyApi( api, @@ -880,6 +1009,17 @@ List _validateAst(Root root, String source) { )); } for (final Method method in api.methods) { + final String? matchingPrefix = _findMatchingPrefixOrNull( + method.name, + prefixes: disallowedPrefixes, + ); + if (matchingPrefix != null) { + result.add(Error( + message: + 'Method name must not begin with "$matchingPrefix" in method "${method.name}" in API: "${api.name}"', + lineNumber: _calculateLineNumberNullable(source, method.offset), + )); + } for (final Parameter param in method.parameters) { if (param.type.baseName.isEmpty) { result.add(Error( @@ -889,13 +1029,13 @@ List _validateAst(Root root, String source) { )); } else { final String? matchingPrefix = _findMatchingPrefixOrNull( - method.name, - prefixes: ['__pigeon_', 'pigeonChannelCodec'], + param.name, + prefixes: disallowedPrefixes, ); if (matchingPrefix != null) { result.add(Error( message: - 'Parameter name must not begin with "$matchingPrefix" in method "${method.name} in API: "${api.name}"', + 'Parameter name must not begin with "$matchingPrefix" in method "${method.name}" in API: "${api.name}"', lineNumber: _calculateLineNumberNullable(source, param.offset), )); } @@ -1093,12 +1233,7 @@ List _validateProxyApi( } else { final String? matchingPrefix = _findMatchingPrefixOrNull( parameter.name, - prefixes: [ - '__pigeon_', - 'pigeonChannelCodec', - classNamePrefix, - classMemberNamePrefix, - ], + prefixes: disallowedPrefixes, ); if (matchingPrefix != null) { result.add(Error( @@ -1133,7 +1268,7 @@ List _validateProxyApi( parameter.name, prefixes: [ classNamePrefix, - classMemberNamePrefix, + varNamePrefix, ], ); if (matchingPrefix != null) { @@ -1186,23 +1321,6 @@ List _validateProxyApi( )); } } - - final String? matchingPrefix = _findMatchingPrefixOrNull( - field.name, - prefixes: [ - '__pigeon_', - 'pigeonChannelCodec', - classNamePrefix, - classMemberNamePrefix, - ], - ); - if (matchingPrefix != null) { - result.add(Error( - message: - 'Field name must not begin with "$matchingPrefix" in API: "${api.name}"', - lineNumber: _calculateLineNumberNullable(source, field.offset), - )); - } } return result; @@ -1269,13 +1387,16 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { getReferencedTypes(_apis, _classes); final Set referencedTypeNames = referencedTypes.keys.map((TypeDeclaration e) => e.baseName).toSet(); - final List referencedClasses = List.from(_classes); - referencedClasses - .removeWhere((Class x) => !referencedTypeNames.contains(x.name)); + final List nonReferencedClasses = List.from(_classes); + nonReferencedClasses + .removeWhere((Class x) => referencedTypeNames.contains(x.name)); + for (final Class x in nonReferencedClasses) { + x.isReferenced = false; + } final List referencedEnums = List.from(_enums); final Root completeRoot = - Root(apis: _apis, classes: referencedClasses, enums: referencedEnums); + Root(apis: _apis, classes: _classes, enums: referencedEnums); final List validateErrors = _validateAst(completeRoot, source); final List totalErrors = List.from(_errors); @@ -1283,9 +1404,7 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { for (final MapEntry> element in referencedTypes.entries) { - if (!referencedClasses - .map((Class e) => e.name) - .contains(element.key.baseName) && + if (!_classes.map((Class e) => e.name).contains(element.key.baseName) && !referencedEnums .map((Enum e) => e.name) .contains(element.key.baseName) && @@ -1306,7 +1425,7 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { lineNumber: lineNumber)); } } - for (final Class classDefinition in referencedClasses) { + for (final Class classDefinition in _classes) { classDefinition.fields = _attachAssociatedDefinitions( classDefinition.fields, ); @@ -1561,6 +1680,50 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { } } + SwiftProxyApiOptions? swiftOptions; + final Map? swiftOptionsMap = + annotationMap['swiftOptions'] as Map?; + if (swiftOptionsMap != null) { + swiftOptions = SwiftProxyApiOptions( + name: swiftOptionsMap['name'] as String?, + import: swiftOptionsMap['import'] as String?, + minIosApi: swiftOptionsMap['minIosApi'] as String?, + minMacosApi: swiftOptionsMap['minMacosApi'] as String?, + supportsIos: swiftOptionsMap['supportsIos'] as bool? ?? true, + supportsMacos: swiftOptionsMap['supportsMacos'] as bool? ?? true, + ); + } + + void tryParseApiRequirement(String? version) { + if (version == null) { + return; + } + try { + Version.parse(version); + } on FormatException catch (error) { + _errors.add( + Error( + message: + 'Could not parse version: ${error.message}. Please use semantic versioning format: "1.2.3".', + lineNumber: _calculateLineNumber(source, node.offset), + ), + ); + } + } + + tryParseApiRequirement(swiftOptions?.minIosApi); + tryParseApiRequirement(swiftOptions?.minMacosApi); + + KotlinProxyApiOptions? kotlinOptions; + final Map? kotlinOptionsMap = + annotationMap['kotlinOptions'] as Map?; + if (kotlinOptionsMap != null) { + kotlinOptions = KotlinProxyApiOptions( + fullClassName: kotlinOptionsMap['fullClassName'] as String?, + minAndroidApi: kotlinOptionsMap['minAndroidApi'] as int?, + ); + } + _currentApi = AstProxyApi( name: node.name.lexeme, methods: [], @@ -1568,6 +1731,8 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { fields: [], superClass: superClass, interfaces: interfaces, + swiftOptions: swiftOptions, + kotlinOptions: kotlinOptions, documentationComments: _documentationCommentsParser(node.documentationComment?.tokens), ); @@ -2100,6 +2265,18 @@ ${_argParser.usage}'''; ) ..addOption('cpp_namespace', help: 'The namespace that generated C++ code will be in.') + ..addOption( + 'gobject_header_out', + help: 'Path to generated GObject header file (.h).', + aliases: const ['experimental_gobject_header_out'], + ) + ..addOption( + 'gobject_source_out', + help: 'Path to generated GObject classes file (.cc).', + aliases: const ['experimental_gobject_source_out'], + ) + ..addOption('gobject_module', + help: 'The module that generated GObject code will be in.') ..addOption('objc_header_out', help: 'Path to generated Objective-C header file (.h).') ..addOption('objc_prefix', @@ -2154,6 +2331,11 @@ ${_argParser.usage}'''; cppOptions: CppOptions( namespace: results['cpp_namespace'] as String?, ), + gobjectHeaderOut: results['gobject_header_out'] as String?, + gobjectSourceOut: results['gobject_source_out'] as String?, + gobjectOptions: GObjectOptions( + module: results['gobject_module'] as String?, + ), copyrightHeader: results['copyright_header'] as String?, oneLanguage: results['one_language'] as bool?, astOut: results['ast_out'] as String?, @@ -2197,8 +2379,12 @@ ${_argParser.usage}'''; /// used when running the code generator. The optional parameter [adapters] allows you to /// customize the generators that pigeon will use. The optional parameter /// [sdkPath] allows you to specify the Dart SDK path. - static Future runWithOptions(PigeonOptions options, - {List? adapters, String? sdkPath}) async { + static Future runWithOptions( + PigeonOptions options, { + List? adapters, + String? sdkPath, + bool injectOverflowTypes = false, + }) async { final Pigeon pigeon = Pigeon.setup(); if (options.debugGenerators ?? false) { generator_tools.debugGenerators = true; @@ -2210,6 +2396,7 @@ ${_argParser.usage}'''; SwiftGeneratorAdapter(), KotlinGeneratorAdapter(), CppGeneratorAdapter(), + GObjectGeneratorAdapter(), DartTestGeneratorAdapter(), ObjcGeneratorAdapter(), AstGeneratorAdapter(), @@ -2224,6 +2411,19 @@ ${_argParser.usage}'''; final ParseResults parseResults = pigeon.parseFile(options.input!, sdkPath: sdkPath); + if (injectOverflowTypes) { + final List addedEnums = List.generate( + totalCustomCodecKeysAllowed - 1, + (final int tag) { + return Enum( + name: 'FillerEnum$tag', + members: [EnumMember(name: 'FillerMember$tag')]); + }, + ); + addedEnums.addAll(parseResults.root.enums); + parseResults.root.enums = addedEnums; + } + final List errors = []; errors.addAll(parseResults.errors); @@ -2235,6 +2435,9 @@ ${_argParser.usage}'''; } for (final GeneratorAdapter adapter in safeGeneratorAdapters) { + if (injectOverflowTypes && adapter is GObjectGeneratorAdapter) { + continue; + } final IOSink? sink = adapter.shouldGenerate(options, FileType.source); if (sink != null) { final List adapterErrors = @@ -2280,6 +2483,14 @@ ${_argParser.usage}'''; path.basename(options.cppHeaderOut!))))); } + if (options.gobjectHeaderOut != null) { + options = options.merge(PigeonOptions( + gobjectOptions: (options.gobjectOptions ?? const GObjectOptions()) + .merge(GObjectOptions( + headerIncludePath: + path.basename(options.gobjectHeaderOut!))))); + } + for (final GeneratorAdapter adapter in safeGeneratorAdapters) { for (final FileType fileType in adapter.fileTypeList) { final IOSink? sink = adapter.shouldGenerate(options, fileType); diff --git a/packages/pigeon/lib/swift/templates.dart b/packages/pigeon/lib/swift/templates.dart new file mode 100644 index 000000000000..d67e8acf18fa --- /dev/null +++ b/packages/pigeon/lib/swift/templates.dart @@ -0,0 +1,256 @@ +// 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 '../generator_tools.dart'; +import '../pigeon.dart'; + +/// Name of delegate that handles the callback when an object is deallocated +/// in an `InstanceManager`. +String instanceManagerFinalizerDelegateName(SwiftOptions options) => + '${_instanceManagerFinalizerName(options)}Delegate'; + +/// The name of the registrar containing all the ProxyApi implementations. +String proxyApiRegistrarName(SwiftOptions options) => + '${options.fileSpecificClassNameComponent ?? ''}${proxyApiClassNamePrefix}ProxyApiRegistrar'; + +/// The name of the `ReaderWriter` that handles ProxyApis. +String proxyApiReaderWriterName(SwiftOptions options) => + '${options.fileSpecificClassNameComponent ?? ''}${classNamePrefix}ProxyApiCodecReaderWriter'; + +/// Name of the Swift `InstanceManager`. +String swiftInstanceManagerClassName(SwiftOptions options) => + '${options.fileSpecificClassNameComponent ?? ''}${proxyApiClassNamePrefix}InstanceManager'; + +/// Template for delegate with callback when an object is deallocated. +String instanceManagerFinalizerDelegateTemplate(SwiftOptions options) => ''' +/// Handles the callback when an object is deallocated. +protocol ${instanceManagerFinalizerDelegateName(options)}: AnyObject { + /// Invoked when the strong reference of an object is deallocated in an `InstanceManager`. + func onDeinit(identifier: Int64) +} + +'''; + +/// Template for an object that tracks when an object is deallocated. +String instanceManagerFinalizerTemplate(SwiftOptions options) => ''' +// Attaches to an object to receive a callback when the object is deallocated. +internal final class ${_instanceManagerFinalizerName(options)} { + private static let associatedObjectKey = malloc(1)! + + private let identifier: Int64 + // Reference to the delegate is weak because the callback should be ignored if the + // `InstanceManager` is deallocated. + private weak var delegate: ${instanceManagerFinalizerDelegateName(options)}? + + private init(identifier: Int64, delegate: ${instanceManagerFinalizerDelegateName(options)}) { + self.identifier = identifier + self.delegate = delegate + } + + internal static func attach( + to instance: AnyObject, identifier: Int64, delegate: ${instanceManagerFinalizerDelegateName(options)} + ) { + let finalizer = ${_instanceManagerFinalizerName(options)}(identifier: identifier, delegate: delegate) + objc_setAssociatedObject(instance, associatedObjectKey, finalizer, .OBJC_ASSOCIATION_RETAIN) + } + + static func detach(from instance: AnyObject) { + objc_setAssociatedObject(instance, associatedObjectKey, nil, .OBJC_ASSOCIATION_ASSIGN) + } + + deinit { + delegate?.onDeinit(identifier: identifier) + } +} + +'''; + +/// The Swift `InstanceManager`. +String instanceManagerTemplate(SwiftOptions options) { + return ''' +/// Maintains instances used to communicate with the corresponding objects in Dart. +/// +/// Objects stored in this container are represented by an object in Dart that is also stored in +/// an InstanceManager with the same identifier. +/// +/// When an instance is added with an identifier, either can be used to retrieve the other. +/// +/// Added instances are added as a weak reference and a strong reference. When the strong +/// reference is removed and the weak reference is deallocated,`${instanceManagerFinalizerDelegateName(options)}.onDeinit` +/// is called with the instance's identifier. However, if the strong reference is removed and then the identifier is +/// retrieved with the intention to pass the identifier to Dart (e.g. by calling `identifierWithStrongReference`), +/// the strong reference to the instance is re-added. The strong reference will then need to be removed manually +/// again. +/// +/// Accessing and inserting to an InstanceManager is thread safe. +final class ${swiftInstanceManagerClassName(options)} { + // Identifiers are locked to a specific range to avoid collisions with objects + // created simultaneously from Dart. + // Host uses identifiers >= 2^16 and Dart is expected to use values n where, + // 0 <= n < 2^16. + private static let minHostCreatedIdentifier: Int64 = 65536 + + private let lockQueue = DispatchQueue(label: "${swiftInstanceManagerClassName(options)}") + private let identifiers: NSMapTable = NSMapTable( + keyOptions: [.weakMemory, .objectPointerPersonality], valueOptions: .strongMemory) + private let weakInstances: NSMapTable = NSMapTable( + keyOptions: .strongMemory, valueOptions: [.weakMemory, .objectPointerPersonality]) + private let strongInstances: NSMapTable = NSMapTable( + keyOptions: .strongMemory, valueOptions: [.strongMemory, .objectPointerPersonality]) + private let finalizerDelegate: ${instanceManagerFinalizerDelegateName(options)} + private var nextIdentifier: Int64 = minHostCreatedIdentifier + + public init(finalizerDelegate: ${instanceManagerFinalizerDelegateName(options)}) { + self.finalizerDelegate = finalizerDelegate + } + + /// Adds a new instance that was instantiated from Dart. + /// + /// The same instance can be added multiple times, but each identifier must be unique. This allows + /// two objects that are equivalent (e.g. conforms to `Equatable`) to both be added. + /// + /// - Parameters: + /// - instance: the instance to be stored + /// - identifier: the identifier to be paired with instance. This value must be >= 0 and unique + func addDartCreatedInstance(_ instance: AnyObject, withIdentifier identifier: Int64) { + lockQueue.async { + self.addInstance(instance, withIdentifier: identifier) + } + } + + /// Adds a new instance that was instantiated from the host platform. + /// + /// - Parameters: + /// - instance: the instance to be stored. This must be unique to all other added instances. + /// - Returns: the unique identifier (>= 0) stored with instance + func addHostCreatedInstance(_ instance: AnyObject) -> Int64 { + assert(!containsInstance(instance), "Instance of \\(instance) has already been added.") + var identifier: Int64 = -1 + lockQueue.sync { + identifier = nextIdentifier + nextIdentifier += 1 + self.addInstance(instance, withIdentifier: identifier) + } + return identifier + } + + /// Removes `instanceIdentifier` and its associated strongly referenced instance, if present, from the manager. + /// + /// - Parameters: + /// - instanceIdentifier: the identifier paired to an instance. + /// - Returns: removed instance if the manager contains the given identifier, otherwise `nil` if + /// the manager doesn't contain the value + func removeInstance(withIdentifier instanceIdentifier: Int64) throws -> T? { + var instance: AnyObject? = nil + lockQueue.sync { + instance = strongInstances.object(forKey: NSNumber(value: instanceIdentifier)) + strongInstances.removeObject(forKey: NSNumber(value: instanceIdentifier)) + } + return instance as? T + } + + /// Retrieves the instance associated with identifier. + /// + /// - Parameters: + /// - instanceIdentifier: the identifier associated with an instance + /// - Returns: the instance associated with `instanceIdentifier` if the manager contains the value, otherwise + /// `nil` if the manager doesn't contain the value + func instance(forIdentifier instanceIdentifier: Int64) -> T? { + var instance: AnyObject? = nil + lockQueue.sync { + instance = weakInstances.object(forKey: NSNumber(value: instanceIdentifier)) + } + return instance as? T + } + + private func addInstance(_ instance: AnyObject, withIdentifier identifier: Int64) { + assert(identifier >= 0) + assert( + weakInstances.object(forKey: identifier as NSNumber) == nil, + "Identifier has already been added: \\(identifier)") + identifiers.setObject(NSNumber(value: identifier), forKey: instance) + weakInstances.setObject(instance, forKey: NSNumber(value: identifier)) + strongInstances.setObject(instance, forKey: NSNumber(value: identifier)) + ${_instanceManagerFinalizerName(options)}.attach(to: instance, identifier: identifier, delegate: finalizerDelegate) + } + + /// Retrieves the identifier paired with an instance. + /// + /// If the manager contains a strong reference to `instance`, it will return the identifier + /// associated with `instance`. If the manager contains only a weak reference to `instance`, a new + /// strong reference to `instance` will be added and will need to be removed again with `removeInstance`. + /// + /// If this method returns a nonnull identifier, this method also expects the Dart + /// `${swiftInstanceManagerClassName(options)}` to have, or recreate, a weak reference to the Dart instance the + /// identifier is associated with. + /// + /// - Parameters: + /// - instance: an instance that may be stored in the manager + /// - Returns: the identifier associated with `instance` if the manager contains the value, otherwise + /// `nil` if the manager doesn't contain the value + func identifierWithStrongReference(forInstance instance: AnyObject) -> Int64? { + var identifier: Int64? = nil + lockQueue.sync { + if let existingIdentifier = identifiers.object(forKey: instance)?.int64Value { + strongInstances.setObject(instance, forKey: NSNumber(value: existingIdentifier)) + identifier = existingIdentifier + } + } + return identifier + } + + /// Whether this manager contains the given `instance`. + /// + /// - Parameters: + /// - instance: the instance whose presence in this manager is to be tested + /// - Returns: whether this manager contains the given `instance` + func containsInstance(_ instance: AnyObject) -> Bool { + var containsInstance = false + lockQueue.sync { + containsInstance = identifiers.object(forKey: instance) != nil + } + return containsInstance + } + + /// Removes all of the instances from this manager. + /// + /// The manager will be empty after this call returns. + func removeAllObjects() throws { + lockQueue.sync { + identifiers.removeAllObjects() + weakInstances.removeAllObjects() + strongInstances.removeAllObjects() + nextIdentifier = ${swiftInstanceManagerClassName(options)}.minHostCreatedIdentifier + } + } + + /// The number of instances stored as a strong reference. + /// + /// For debugging and testing purposes. + internal var strongInstanceCount: Int { + var count: Int = 0 + lockQueue.sync { + count = strongInstances.count + } + return count + } + + /// The number of instances stored as a weak reference. + /// + /// For debugging and testing purposes. NSMapTables that store keys or objects as weak + /// reference will be reclaimed non-deterministically. + internal var weakInstanceCount: Int { + var count: Int = 0 + lockQueue.sync { + count = weakInstances.count + } + return count + } +} + +'''; +} + +String _instanceManagerFinalizerName(SwiftOptions options) => + '${options.fileSpecificClassNameComponent ?? ''}${classNamePrefix}Finalizer'; diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index 99ad77f39e7c..289c50dbd887 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -2,10 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:collection/collection.dart' as collection; +import 'package:graphs/graphs.dart'; +import 'package:pub_semver/pub_semver.dart'; + import 'ast.dart'; import 'functional.dart'; import 'generator.dart'; import 'generator_tools.dart'; +import 'swift/templates.dart'; /// Documentation comment open symbol. const String _docCommentPrefix = '///'; @@ -14,6 +19,8 @@ const String _docCommentPrefix = '///'; const DocumentCommentSpecification _docCommentSpec = DocumentCommentSpecification(_docCommentPrefix); +const String _overflowClassName = '${classNamePrefix}CodecOverflow'; + /// Options that control how Swift code will be generated. class SwiftOptions { /// Creates a [SwiftOptions] object @@ -21,6 +28,7 @@ class SwiftOptions { this.copyrightHeader, this.fileSpecificClassNameComponent, this.errorClassName, + this.includeErrorClass = true, }); /// A copyright header that will get prepended to generated code. @@ -32,6 +40,12 @@ class SwiftOptions { /// The name of the error class used for passing custom error parameters. final String? errorClassName; + /// Whether to include the error class in generation. + /// + /// This should only ever be set to false if you have another generated + /// Swift file in the same directory. + final bool includeErrorClass; + /// Creates a [SwiftOptions] from a Map representation where: /// `x = SwiftOptions.fromList(x.toMap())`. static SwiftOptions fromList(Map map) { @@ -40,6 +54,7 @@ class SwiftOptions { fileSpecificClassNameComponent: map['fileSpecificClassNameComponent'] as String?, errorClassName: map['errorClassName'] as String?, + includeErrorClass: map['includeErrorClass'] as bool? ?? true, ); } @@ -51,6 +66,7 @@ class SwiftOptions { if (fileSpecificClassNameComponent != null) 'fileSpecificClassNameComponent': fileSpecificClassNameComponent!, if (errorClassName != null) 'errorClassName': errorClassName!, + 'includeErrorClass': includeErrorClass, }; return result; } @@ -62,6 +78,54 @@ class SwiftOptions { } } +/// Options that control how Swift code will be generated for a specific +/// ProxyApi. +class SwiftProxyApiOptions { + /// Constructs a [SwiftProxyApiOptions]. + const SwiftProxyApiOptions({ + this.name, + this.import, + this.minIosApi, + this.minMacosApi, + this.supportsIos = true, + this.supportsMacos = true, + }); + + /// The name of the Swift class. + /// + /// By default, generated code will use the same name as the class in the Dart + /// pigeon file. + final String? name; + + /// The name of the module that needs to be imported to access the class. + final String? import; + + /// The API version requirement for iOS. + /// + /// This adds `@available` annotations on top of any constructor, field, or + /// method that references this element. + final String? minIosApi; + + /// The API version requirement for macOS. + /// + /// This adds `@available` annotations on top of any constructor, field, or + /// method that references this element. + final String? minMacosApi; + + /// Whether this ProxyApi class compiles on iOS. + /// + /// This adds `#` annotations on top of any constructor, field, or + /// method that references this element. + /// + /// Defaults to true. + final bool supportsIos; + + /// Whether this ProxyApi class compiles on macOS. + /// + /// Defaults to true. + final bool supportsMacos; +} + /// Class that manages all Swift code generation. class SwiftGenerator extends StructuredGenerator { /// Instantiates a Swift Generator. @@ -90,7 +154,17 @@ class SwiftGenerator extends StructuredGenerator { required String dartPackageName, }) { indent.writeln('import Foundation'); + + final Iterable proxyApiImports = root.apis + .whereType() + .map((AstProxyApi proxyApi) => proxyApi.swiftOptions?.import) + .whereNotNull() + .toSet(); + for (final String import in proxyApiImports) { + indent.writeln('import $import'); + } indent.newln(); + indent.format(''' #if os(iOS) import Flutter @@ -135,33 +209,54 @@ class SwiftGenerator extends StructuredGenerator { final String readerName = '${codecName}Reader'; final String writerName = '${codecName}Writer'; - final Iterable allTypes = getEnumeratedTypes(root); + final List enumeratedTypes = + getEnumeratedTypes(root).toList(); + + void writeDecodeLogic(EnumeratedType customType) { + indent.writeln('case ${customType.enumeration}:'); + indent.nest(1, () { + if (customType.type == CustomTypes.customEnum) { + indent.writeln( + 'let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?)'); + indent.writeScoped('if let enumResultAsInt = enumResultAsInt {', '}', + () { + indent.writeln( + 'return ${customType.name}(rawValue: enumResultAsInt)'); + }); + indent.writeln('return nil'); + } else { + indent.writeln( + 'return ${customType.name}.fromList(self.readValue() as! [Any?])'); + } + }); + } + + final EnumeratedType overflowClass = EnumeratedType( + _overflowClassName, maximumCodecFieldKey, CustomTypes.customClass); + + if (root.requiresOverflowClass) { + indent.newln(); + _writeCodecOverflowUtilities( + generatorOptions, root, indent, enumeratedTypes, + dartPackageName: dartPackageName); + } + + indent.newln(); // Generate Reader indent.write('private class $readerName: FlutterStandardReader '); indent.addScoped('{', '}', () { - if (allTypes.isNotEmpty) { + if (enumeratedTypes.isNotEmpty) { indent.write('override func readValue(ofType type: UInt8) -> Any? '); indent.addScoped('{', '}', () { indent.write('switch type '); indent.addScoped('{', '}', nestCount: 0, () { - for (final EnumeratedType customType in allTypes) { - indent.writeln('case ${customType.enumeration}:'); - indent.nest(1, () { - if (customType.type == CustomTypes.customEnum) { - indent.writeln('var enumResult: ${customType.name}? = nil'); - indent.writeln( - 'let enumResultAsInt: Int? = nilOrValue(self.readValue() as? Int)'); - indent.writeScoped( - 'if let enumResultAsInt = enumResultAsInt {', '}', () { - indent.writeln( - 'enumResult = ${customType.name}(rawValue: enumResultAsInt)'); - }); - indent.writeln('return enumResult'); - } else { - indent.writeln( - 'return ${customType.name}.fromList(self.readValue() as! [Any?])'); - } - }); + for (final EnumeratedType customType in enumeratedTypes) { + if (customType.enumeration < maximumCodecFieldKey) { + writeDecodeLogic(customType); + } + } + if (root.requiresOverflowClass) { + writeDecodeLogic(overflowClass); } indent.writeln('default:'); indent.nest(1, () { @@ -176,19 +271,31 @@ class SwiftGenerator extends StructuredGenerator { indent.newln(); indent.write('private class $writerName: FlutterStandardWriter '); indent.addScoped('{', '}', () { - if (allTypes.isNotEmpty) { + if (enumeratedTypes.isNotEmpty) { indent.write('override func writeValue(_ value: Any) '); indent.addScoped('{', '}', () { indent.write(''); - for (final EnumeratedType customType in allTypes) { + for (final EnumeratedType customType in enumeratedTypes) { indent.add('if let value = value as? ${customType.name} '); indent.addScoped('{', '} else ', () { - indent.writeln('super.writeByte(${customType.enumeration})'); - if (customType.type == CustomTypes.customEnum) { - indent.writeln('super.writeValue(value.rawValue)'); - } else if (customType.type == CustomTypes.customClass) { - indent.writeln('super.writeValue(value.toList())'); + final String encodeString = + customType.type == CustomTypes.customClass + ? 'toList()' + : 'rawValue'; + final String valueString = + customType.enumeration < maximumCodecFieldKey + ? 'value.$encodeString' + : 'wrap.toList()'; + final int enumeration = + customType.enumeration < maximumCodecFieldKey + ? customType.enumeration + : maximumCodecFieldKey; + if (customType.enumeration >= maximumCodecFieldKey) { + indent.writeln( + 'let wrap = $_overflowClassName(type: ${customType.enumeration - maximumCodecFieldKey}, wrapped: value.$encodeString)'); } + indent.writeln('super.writeByte($enumeration)'); + indent.writeln('super.writeValue($valueString)'); }, addTrailingNewline: false); } indent.addScoped('{', '}', () { @@ -227,28 +334,19 @@ class SwiftGenerator extends StructuredGenerator { indent.newln(); } - @override - void writeDataClass( - SwiftOptions generatorOptions, - Root root, + void _writeDataClassSignature( Indent indent, Class classDefinition, { - required String dartPackageName, + bool private = false, }) { - const List generatedComments = [ - ' Generated class from Pigeon that represents data sent in messages.' - ]; - indent.newln(); - addDocumentationComments( - indent, classDefinition.documentationComments, _docCommentSpec, - generatorComments: generatedComments); - + final String privateString = private ? 'private ' : ''; if (classDefinition.isSwiftClass) { - indent.write('class ${classDefinition.name} '); + indent.write('${privateString}class ${classDefinition.name} '); } else { - indent.write('struct ${classDefinition.name} '); + indent.write('${privateString}struct ${classDefinition.name} '); } - indent.addScoped('{', '}', () { + + indent.addScoped('{', '', () { final Iterable fields = getFieldsInSerializationOrder(classDefinition); @@ -263,7 +361,98 @@ class SwiftGenerator extends StructuredGenerator { _writeClassField(indent, field, addNil: !classDefinition.isSwiftClass); indent.newln(); } + }); + } + + void _writeCodecOverflowUtilities( + SwiftOptions generatorOptions, + Root root, + Indent indent, + List types, { + required String dartPackageName, + }) { + final NamedType overflowInt = NamedType( + name: 'type', + type: const TypeDeclaration(baseName: 'Int', isNullable: false)); + final NamedType overflowObject = NamedType( + name: 'wrapped', + type: const TypeDeclaration(baseName: 'Object', isNullable: true)); + final List overflowFields = [ + overflowInt, + overflowObject, + ]; + final Class overflowClass = + Class(name: _overflowClassName, fields: overflowFields); + indent.newln(); + _writeDataClassSignature(indent, overflowClass, private: true); + indent.addScoped('', '}', () { + writeClassEncode( + generatorOptions, + root, + indent, + overflowClass, + dartPackageName: dartPackageName, + ); + + indent.format(''' +// swift-format-ignore: AlwaysUseLowerCamelCase +static func fromList(_ ${varNamePrefix}list: [Any?]) -> Any? { + let type = ${varNamePrefix}list[0] as! Int + let wrapped: Any? = ${varNamePrefix}list[1] + + let wrapper = $_overflowClassName( + type: type, + wrapped: wrapped + ) + + return wrapper.unwrap() +} +'''); + + indent.writeScoped('func unwrap() -> Any? {', '}', () { + indent.format(''' +if (wrapped == nil) { + return nil; +} + '''); + indent.writeScoped('switch type {', '}', () { + for (int i = totalCustomCodecKeysAllowed; i < types.length; i++) { + indent.writeScoped('case ${i - totalCustomCodecKeysAllowed}:', '', + () { + if (types[i].type == CustomTypes.customClass) { + indent.writeln( + 'return ${types[i].name}.fromList(wrapped as! [Any?]);'); + } else if (types[i].type == CustomTypes.customEnum) { + indent.writeln( + 'return ${types[i].name}(rawValue: wrapped as! Int);'); + } + }, addTrailingNewline: false); + } + indent.writeScoped('default: ', '', () { + indent.writeln('return nil'); + }, addTrailingNewline: false); + }); + }); + }); + } + @override + void writeDataClass( + SwiftOptions generatorOptions, + Root root, + Indent indent, + Class classDefinition, { + required String dartPackageName, + }) { + const List generatedComments = [ + ' Generated class from Pigeon that represents data sent in messages.' + ]; + indent.newln(); + addDocumentationComments( + indent, classDefinition.documentationComments, _docCommentSpec, + generatorComments: generatedComments); + _writeDataClassSignature(indent, classDefinition); + indent.writeScoped('', '}', () { indent.newln(); writeClassDecode( generatorOptions, @@ -302,7 +491,7 @@ class SwiftGenerator extends StructuredGenerator { } void _writeClassField(Indent indent, NamedType field, {bool addNil = true}) { - indent.add('${field.name}: ${_nullsafeSwiftTypeForDartType(field.type)}'); + indent.add('${field.name}: ${_nullSafeSwiftTypeForDartType(field.type)}'); final String defaultNil = field.type.isNullable && addNil ? ' = nil' : ''; indent.add(defaultNil); } @@ -370,7 +559,17 @@ class SwiftGenerator extends StructuredGenerator { getFieldsInSerializationOrder(classDefinition).last == field ? '' : ','; - indent.writeln('${field.name}: ${field.name}$comma'); + // Force-casting nullable enums in maps doesn't work the same as other types. + // It needs soft-casting followed by force unwrapping. + final String forceUnwrapMapWithNullableEnums = + (field.type.baseName == 'Map' && + !field.type.isNullable && + field.type.typeArguments + .any((TypeDeclaration type) => type.isEnum)) + ? '!' + : ''; + indent.writeln( + '${field.name}: ${field.name}$forceUnwrapMapWithNullableEnums$comma'); } }); }); @@ -453,7 +652,8 @@ class SwiftGenerator extends StructuredGenerator { indent, generatorOptions: generatorOptions, name: func.name, - channelName: makeChannelName(api, func, dartPackageName), + channelName: + '${makeChannelName(api, func, dartPackageName)}\\(messageChannelSuffix)', parameters: func.parameters, returnType: func.returnType, swiftFunction: func.swiftFunction, @@ -517,7 +717,8 @@ class SwiftGenerator extends StructuredGenerator { _writeHostMethodMessageHandler( indent, name: method.name, - channelName: makeChannelName(api, method, dartPackageName), + channelName: + '${makeChannelName(api, method, dartPackageName)}\\(channelSuffix)', parameters: method.parameters, returnType: method.returnType, isAsynchronous: method.isAsynchronous, @@ -529,18 +730,483 @@ class SwiftGenerator extends StructuredGenerator { }); } + @override + void writeInstanceManager( + SwiftOptions generatorOptions, + Root root, + Indent indent, { + required String dartPackageName, + }) { + indent.format(instanceManagerFinalizerDelegateTemplate(generatorOptions)); + indent.format(instanceManagerFinalizerTemplate(generatorOptions)); + indent.format(instanceManagerTemplate(generatorOptions)); + } + + @override + void writeInstanceManagerApi( + SwiftOptions generatorOptions, + Root root, + Indent indent, { + required String dartPackageName, + }) { + final String instanceManagerApiName = + '${swiftInstanceManagerClassName(generatorOptions)}Api'; + + final String removeStrongReferenceName = + makeRemoveStrongReferenceChannelName( + dartPackageName, + ); + + indent.writeScoped('private class $instanceManagerApiName {', '}', () { + addDocumentationComments( + indent, + [' The codec used for serializing messages.'], + _docCommentSpec, + ); + indent.writeln( + 'var codec: FlutterStandardMessageCodec { ${_getCodecName(generatorOptions)}.shared }', + ); + indent.newln(); + + addDocumentationComments( + indent, + [' Handles sending and receiving messages with Dart.'], + _docCommentSpec, + ); + indent.writeln('unowned let binaryMessenger: FlutterBinaryMessenger'); + indent.newln(); + + indent.writeScoped( + 'init(binaryMessenger: FlutterBinaryMessenger) {', + '}', + () { + indent.writeln('self.binaryMessenger = binaryMessenger'); + }, + ); + indent.newln(); + + addDocumentationComments( + indent, + [ + ' Sets up an instance of `$instanceManagerApiName` to handle messages through the `binaryMessenger`.', + ], + _docCommentSpec, + ); + indent.writeScoped( + 'static func setUpMessageHandlers(binaryMessenger: FlutterBinaryMessenger, instanceManager: ${swiftInstanceManagerClassName(generatorOptions)}?) {', + '}', + () { + indent.writeln( + 'let codec = ${_getCodecName(generatorOptions)}.shared', + ); + const String setHandlerCondition = + 'let instanceManager = instanceManager'; + _writeHostMethodMessageHandler( + indent, + name: 'removeStrongReference', + channelName: removeStrongReferenceName, + parameters: [ + Parameter( + name: 'identifier', + type: const TypeDeclaration( + baseName: 'int', + isNullable: false, + ), + ), + ], + returnType: const TypeDeclaration.voidDeclaration(), + swiftFunction: 'method(withIdentifier:)', + setHandlerCondition: setHandlerCondition, + isAsynchronous: false, + onCreateCall: ( + List safeArgNames, { + required String apiVarName, + }) { + return 'let _: AnyObject? = try instanceManager.removeInstance(${safeArgNames.single})'; + }, + ); + _writeHostMethodMessageHandler( + indent, + name: 'clear', + channelName: makeClearChannelName(dartPackageName), + parameters: [], + returnType: const TypeDeclaration.voidDeclaration(), + setHandlerCondition: setHandlerCondition, + swiftFunction: null, + isAsynchronous: false, + onCreateCall: ( + List safeArgNames, { + required String apiVarName, + }) { + return 'try instanceManager.removeAllObjects()'; + }, + ); + }, + ); + indent.newln(); + + addDocumentationComments( + indent, + [ + ' Sends a message to the Dart `InstanceManager` to remove the strong reference of the instance associated with `identifier`.', + ], + _docCommentSpec, + ); + _writeFlutterMethod( + indent, + generatorOptions: generatorOptions, + name: 'removeStrongReference', + parameters: [ + Parameter( + name: 'identifier', + type: const TypeDeclaration(baseName: 'int', isNullable: false), + ) + ], + returnType: const TypeDeclaration.voidDeclaration(), + channelName: removeStrongReferenceName, + swiftFunction: null, + ); + }); + } + + @override + void writeProxyApiBaseCodec( + SwiftOptions generatorOptions, + Root root, + Indent indent, + ) { + final Iterable allProxyApis = + root.apis.whereType(); + + _writeProxyApiRegistrar( + indent, + generatorOptions: generatorOptions, + allProxyApis: allProxyApis, + ); + + final String filePrefix = + generatorOptions.fileSpecificClassNameComponent ?? ''; + + final String registrarName = proxyApiRegistrarName(generatorOptions); + + indent.writeScoped( + 'private class ${proxyApiReaderWriterName(generatorOptions)}: FlutterStandardReaderWriter {', + '}', + () { + indent.writeln( + 'unowned let pigeonRegistrar: $registrarName', + ); + indent.newln(); + + indent.writeScoped( + 'private class $filePrefix${classNamePrefix}ProxyApiCodecReader: ${_getCodecName(generatorOptions)}Reader {', + '}', + () { + indent.writeln('unowned let pigeonRegistrar: $registrarName'); + indent.newln(); + + indent.writeScoped( + 'init(data: Data, pigeonRegistrar: $registrarName) {', + '}', + () { + indent.writeln('self.pigeonRegistrar = pigeonRegistrar'); + indent.writeln('super.init(data: data)'); + }, + ); + indent.newln(); + + indent.writeScoped( + 'override func readValue(ofType type: UInt8) -> Any? {', + '}', + () { + indent.format( + ''' + switch type { + case $proxyApiCodecInstanceManagerKey: + let identifier = self.readValue() + let instance: AnyObject? = pigeonRegistrar.instanceManager.instance( + forIdentifier: identifier is Int64 ? identifier as! Int64 : Int64(identifier as! Int32)) + return instance + default: + return super.readValue(ofType: type) + }''', + ); + }, + ); + }, + ); + indent.newln(); + + indent.writeScoped( + 'private class $filePrefix${classNamePrefix}ProxyApiCodecWriter: ${_getCodecName(generatorOptions)}Writer {', + '}', + () { + indent.writeln( + 'unowned let pigeonRegistrar: $registrarName', + ); + indent.newln(); + + indent.writeScoped( + 'init(data: NSMutableData, pigeonRegistrar: $registrarName) {', + '}', + () { + indent.writeln('self.pigeonRegistrar = pigeonRegistrar'); + indent.writeln('super.init(data: data)'); + }, + ); + indent.newln(); + + indent.writeScoped( + 'override func writeValue(_ value: Any) {', + '}', + () { + final List nonProxyApiTypes = [ + '[Any]', + 'Bool', + 'Data', + '[AnyHashable: Any]', + 'Double', + 'FlutterStandardTypedData', + 'Int64', + 'String', + ...root.enums.map((Enum anEnum) => anEnum.name), + ]; + final String isBuiltinExpression = nonProxyApiTypes + .map((String swiftType) => 'value is $swiftType') + .join(' || '); + // Non ProxyApi types are checked first to prevent the scenario + // where a client wraps the `NSObject` class which all the + // classes above extend. + indent.writeScoped('if $isBuiltinExpression {', '}', () { + indent.writeln('super.writeValue(value)'); + indent.writeln('return'); + }); + indent.newln(); + + // Sort APIs where edges are an API's super class and interfaces. + // + // This sorts the APIs to have child classes be listed before their parent + // classes. This prevents the scenario where a method might return the super + // class of the actual class, so the incorrect Dart class gets created + // because the 'value is ' was checked first in the codec. For + // example: + // + // class Shape {} + // class Circle extends Shape {} + // + // class SomeClass { + // Shape giveMeAShape() => Circle(); + // } + final List sortedApis = topologicalSort( + allProxyApis, + (AstProxyApi api) { + return [ + if (api.superClass?.associatedProxyApi != null) + api.superClass!.associatedProxyApi!, + ...api.interfaces.map( + (TypeDeclaration interface) => + interface.associatedProxyApi!, + ), + ]; + }, + ); + + enumerate( + sortedApis, + (int index, AstProxyApi api) { + final TypeDeclaration apiAsTypeDecl = TypeDeclaration( + baseName: api.name, + isNullable: false, + associatedProxyApi: api, + ); + final String? availability = _tryGetAvailabilityAnnotation( + [apiAsTypeDecl], + ); + final String? unsupportedPlatforms = + _tryGetUnsupportedPlatformsCondition( + [apiAsTypeDecl], + ); + final String className = api.swiftOptions?.name ?? api.name; + indent.format( + ''' + ${unsupportedPlatforms != null ? '#if $unsupportedPlatforms' : ''} + if ${availability != null ? '#$availability, ' : ''}let instance = value as? $className { + pigeonRegistrar.apiDelegate.pigeonApi${api.name}(pigeonRegistrar).pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte($proxyApiCodecInstanceManagerKey) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference(forInstance: instance as AnyObject)!) + return + } + ${unsupportedPlatforms != null ? '#endif' : ''}''', + ); + }, + ); + indent.newln(); + + indent.format( + ''' + if let instance = value as AnyObject?, pigeonRegistrar.instanceManager.containsInstance(instance) + { + super.writeByte($proxyApiCodecInstanceManagerKey) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference(forInstance: instance)!) + } else { + print("Unsupported value: \\(value) of \\(type(of: value))") + assert(false, "Unsupported value for $filePrefix${classNamePrefix}ProxyApiCodecWriter") + } + ''', + ); + }, + ); + }, + ); + indent.newln(); + + indent.format( + ''' + init(pigeonRegistrar: $registrarName) { + self.pigeonRegistrar = pigeonRegistrar + }''', + ); + indent.newln(); + + indent.format( + ''' + override func reader(with data: Data) -> FlutterStandardReader { + return $filePrefix${classNamePrefix}ProxyApiCodecReader(data: data, pigeonRegistrar: pigeonRegistrar) + }''', + ); + indent.newln(); + + indent.format( + ''' + override func writer(with data: NSMutableData) -> FlutterStandardWriter { + return $filePrefix${classNamePrefix}ProxyApiCodecWriter(data: data, pigeonRegistrar: pigeonRegistrar) + }''', + ); + }, + ); + } + + @override + void writeProxyApi( + SwiftOptions generatorOptions, + Root root, + Indent indent, + AstProxyApi api, { + required String dartPackageName, + }) { + final TypeDeclaration apiAsTypeDeclaration = TypeDeclaration( + baseName: api.name, + isNullable: false, + associatedProxyApi: api, + ); + + final String swiftApiDelegateName = + '${hostProxyApiPrefix}Delegate${api.name}'; + final String type = + api.hasMethodsRequiringImplementation() ? 'protocol' : 'open class'; + indent.writeScoped('$type $swiftApiDelegateName {', '}', () { + _writeProxyApiConstructorDelegateMethods( + indent, + api, + apiAsTypeDeclaration: apiAsTypeDeclaration, + ); + _writeProxyApiAttachedFieldDelegateMethods( + indent, + api, + apiAsTypeDeclaration: apiAsTypeDeclaration, + ); + if (api.hasCallbackConstructor()) { + _writeProxyApiUnattachedFieldDelegateMethods( + indent, + api, + apiAsTypeDeclaration: apiAsTypeDeclaration, + ); + } + _writeProxyApiHostMethodDelegateMethods( + indent, + api, + apiAsTypeDeclaration: apiAsTypeDeclaration, + ); + }); + indent.newln(); + + final String swiftApiProtocolName = + '${hostProxyApiPrefix}Protocol${api.name}'; + indent.writeScoped('protocol $swiftApiProtocolName {', '}', () { + _writeProxyApiFlutterMethods( + indent, + api, + generatorOptions: generatorOptions, + apiAsTypeDeclaration: apiAsTypeDeclaration, + dartPackageName: dartPackageName, + writeBody: false, + ); + }); + indent.newln(); + + final String swiftApiName = '$hostProxyApiPrefix${api.name}'; + indent.writeScoped( + 'final class $swiftApiName: $swiftApiProtocolName {', '}', () { + indent.writeln( + 'unowned let pigeonRegistrar: ${proxyApiRegistrarName(generatorOptions)}', + ); + indent.writeln('let pigeonDelegate: $swiftApiDelegateName'); + + _writeProxyApiInheritedApiMethods(indent, api); + + indent.writeScoped( + 'init(pigeonRegistrar: ${proxyApiRegistrarName(generatorOptions)}, delegate: $swiftApiDelegateName) {', + '}', + () { + indent.writeln('self.pigeonRegistrar = pigeonRegistrar'); + indent.writeln('self.pigeonDelegate = delegate'); + }, + ); + + if (api.hasAnyHostMessageCalls()) { + _writeProxyApiMessageHandlerMethod( + indent, + api, + generatorOptions: generatorOptions, + apiAsTypeDeclaration: apiAsTypeDeclaration, + swiftApiName: swiftApiName, + dartPackageName: dartPackageName, + ); + indent.newln(); + } + + _writeProxyApiNewInstanceMethod( + indent, + api, + generatorOptions: generatorOptions, + apiAsTypeDeclaration: apiAsTypeDeclaration, + newInstanceMethodName: '${classMemberNamePrefix}newInstance', + dartPackageName: dartPackageName, + ); + + _writeProxyApiFlutterMethods( + indent, + api, + generatorOptions: generatorOptions, + apiAsTypeDeclaration: apiAsTypeDeclaration, + dartPackageName: dartPackageName, + ); + }); + } + String _castForceUnwrap(String value, TypeDeclaration type) { assert(!type.isVoid); if (type.baseName == 'Object') { return value + (type.isNullable ? '' : '!'); - } else if (type.baseName == 'int') { - if (type.isNullable) { - // Nullable ints need to check for NSNull, and Int32 before casting can be done safely. - // This nested ternary is a necessary evil to avoid less efficient conversions. - return 'isNullish($value) ? nil : ($value is Int64? ? $value as! Int64? : Int64($value as! Int32))'; - } else { - return '$value is Int64 ? $value as! Int64 : Int64($value as! Int32)'; - } + // Force-casting nullable enums in maps doesn't work the same as other types. + // It needs soft-casting followed by force unwrapping. + } else if (type.baseName == 'Map' && + type.typeArguments.any((TypeDeclaration type) => type.isEnum)) { + return '$value as? ${_swiftTypeForDartType(type)}'; } else if (type.isNullable) { return 'nilOrValue($value)'; } else { @@ -644,14 +1310,17 @@ private func nilOrValue(_ value: Any?) -> T? { final bool hasFlutterApi = root.apis .whereType() .any((Api api) => api.methods.isNotEmpty); + final bool hasProxyApi = root.apis.any((Api api) => api is AstProxyApi); - _writePigeonError(generatorOptions, indent); + if (generatorOptions.includeErrorClass) { + _writePigeonError(generatorOptions, indent); + } - if (hasHostApi) { + if (hasHostApi || hasProxyApi) { _writeWrapResult(indent); _writeWrapError(generatorOptions, indent); } - if (hasFlutterApi) { + if (hasFlutterApi || hasProxyApi) { _writeCreateConnectionError(generatorOptions, indent); } @@ -678,60 +1347,81 @@ private func nilOrValue(_ value: Any?) -> T? { getParameterName: _getSafeArgumentName, ); + indent.writeScoped('$methodSignature {', '}', () { + _writeFlutterMethodMessageCall( + indent, + generatorOptions: generatorOptions, + parameters: parameters, + returnType: returnType, + channelName: channelName, + ); + }); + } + + void _writeFlutterMethodMessageCall( + Indent indent, { + required SwiftOptions generatorOptions, + required List parameters, + required TypeDeclaration returnType, + required String channelName, + }) { /// Returns an argument name that can be used in a context where it is possible to collide. String getEnumSafeArgumentExpression(int count, NamedType argument) { return '${_getArgumentName(count, argument)}Arg'; } - indent.writeScoped('$methodSignature {', '}', () { - final Iterable enumSafeArgNames = parameters.asMap().entries.map( - (MapEntry e) => - getEnumSafeArgumentExpression(e.key, e.value)); - final String sendArgument = parameters.isEmpty - ? 'nil' - : '[${enumSafeArgNames.join(', ')}] as [Any?]'; - const String channel = 'channel'; - indent.writeln( - 'let channelName: String = "$channelName\\(messageChannelSuffix)"'); - indent.writeln( - 'let $channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec)'); - indent.write('$channel.sendMessage($sendArgument) '); + final Iterable enumSafeArgNames = parameters.asMap().entries.map( + (MapEntry e) => + getEnumSafeArgumentExpression(e.key, e.value)); + final String sendArgument = parameters.isEmpty + ? 'nil' + : '[${enumSafeArgNames.join(', ')}] as [Any?]'; + const String channel = 'channel'; + indent.writeln('let channelName: String = "$channelName"'); + indent.writeln( + 'let $channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec)'); + indent.write('$channel.sendMessage($sendArgument) '); - indent.addScoped('{ response in', '}', () { - indent.writeScoped( - 'guard let listResponse = response as? [Any?] else {', '}', () { - indent.writeln( - 'completion(.failure(createConnectionError(withChannelName: channelName)))'); - indent.writeln('return'); - }); - indent.writeScoped('if listResponse.count > 1 {', '} ', () { - indent.writeln('let code: String = listResponse[0] as! String'); - indent.writeln('let message: String? = nilOrValue(listResponse[1])'); - indent.writeln('let details: String? = nilOrValue(listResponse[2])'); + indent.addScoped('{ response in', '}', () { + indent.writeScoped( + 'guard let listResponse = response as? [Any?] else {', '}', () { + indent.writeln( + 'completion(.failure(createConnectionError(withChannelName: channelName)))'); + indent.writeln('return'); + }); + indent.writeScoped('if listResponse.count > 1 {', '} ', () { + indent.writeln('let code: String = listResponse[0] as! String'); + indent.writeln('let message: String? = nilOrValue(listResponse[1])'); + indent.writeln('let details: String? = nilOrValue(listResponse[2])'); + indent.writeln( + 'completion(.failure(${_getErrorClassName(generatorOptions)}(code: code, message: message, details: details)))'); + }, addTrailingNewline: false); + if (!returnType.isNullable && !returnType.isVoid) { + indent.addScoped('else if listResponse[0] == nil {', '} ', () { indent.writeln( - 'completion(.failure(${_getErrorClassName(generatorOptions)}(code: code, message: message, details: details)))'); + 'completion(.failure(${_getErrorClassName(generatorOptions)}(code: "null-error", message: "Flutter api returned null value for non-null return value.", details: "")))'); }, addTrailingNewline: false); - if (!returnType.isNullable && !returnType.isVoid) { - indent.addScoped('else if listResponse[0] == nil {', '} ', () { - indent.writeln( - 'completion(.failure(${_getErrorClassName(generatorOptions)}(code: "null-error", message: "Flutter api returned null value for non-null return value.", details: "")))'); - }, addTrailingNewline: false); + } + indent.addScoped('else {', '}', () { + if (returnType.isVoid) { + indent.writeln('completion(.success(Void()))'); + } else { + final String fieldType = _swiftTypeForDartType(returnType); + _writeGenericCasting( + indent: indent, + value: 'listResponse[0]', + variableName: 'result', + fieldType: fieldType, + type: returnType, + ); + // There is a swift bug with unwrapping maps of nullable Enums; + final String enumMapForceUnwrap = returnType.baseName == 'Map' && + returnType.typeArguments + .any((TypeDeclaration type) => type.isEnum) + ? '!' + : ''; + indent.writeln('completion(.success(result$enumMapForceUnwrap))'); } - indent.addScoped('else {', '}', () { - if (returnType.isVoid) { - indent.writeln('completion(.success(Void()))'); - } else { - final String fieldType = _swiftTypeForDartType(returnType); - _writeGenericCasting( - indent: indent, - value: 'listResponse[0]', - variableName: 'result', - fieldType: fieldType, - type: returnType, - ); - indent.writeln('completion(.success(result))'); - } - }); }); }); } @@ -744,7 +1434,10 @@ private func nilOrValue(_ value: Any?) -> T? { required TypeDeclaration returnType, required bool isAsynchronous, required String? swiftFunction, + String setHandlerCondition = 'let api = api', List documentationComments = const [], + String Function(List safeArgNames, {required String apiVarName})? + onCreateCall, }) { final _SwiftFunctionComponents components = _SwiftFunctionComponents( name: name, @@ -756,8 +1449,8 @@ private func nilOrValue(_ value: Any?) -> T? { final String varChannelName = '${name}Channel'; addDocumentationComments(indent, documentationComments, _docCommentSpec); indent.writeln( - 'let $varChannelName = FlutterBasicMessageChannel(name: "$channelName\\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)'); - indent.write('if let api = api '); + 'let $varChannelName = FlutterBasicMessageChannel(name: "$channelName", binaryMessenger: binaryMessenger, codec: codec)'); + indent.write('if $setHandlerCondition '); indent.addScoped('{', '}', () { indent.write('$varChannelName.setMessageHandler '); final String messageVarName = parameters.isNotEmpty ? 'message' : '_'; @@ -770,6 +1463,12 @@ private func nilOrValue(_ value: Any?) -> T? { final String argName = _getSafeArgumentName(index, arg.namedType); final String argIndex = 'args[$index]'; final String fieldType = _swiftTypeForDartType(arg.type); + // There is a swift bug with unwrapping maps of nullable Enums; + final String enumMapForceUnwrap = arg.type.baseName == 'Map' && + arg.type.typeArguments + .any((TypeDeclaration type) => type.isEnum) + ? '!' + : ''; _writeGenericCasting( indent: indent, @@ -779,20 +1478,25 @@ private func nilOrValue(_ value: Any?) -> T? { type: arg.type); if (arg.label == '_') { - methodArgument.add(argName); + methodArgument.add('$argName$enumMapForceUnwrap'); } else { - methodArgument.add('${arg.label ?? arg.name}: $argName'); + methodArgument + .add('${arg.label ?? arg.name}: $argName$enumMapForceUnwrap'); } }); } final String tryStatement = isAsynchronous ? '' : 'try '; - // Empty parens are not required when calling a method whose only - // argument is a trailing closure. - final String argumentString = methodArgument.isEmpty && isAsynchronous - ? '' - : '(${methodArgument.join(', ')})'; - final String call = - '${tryStatement}api.${components.name}$argumentString'; + late final String call; + if (onCreateCall == null) { + // Empty parens are not required when calling a method whose only + // argument is a trailing closure. + final String argumentString = methodArgument.isEmpty && isAsynchronous + ? '' + : '(${methodArgument.join(', ')})'; + call = '${tryStatement}api.${components.name}$argumentString'; + } else { + call = onCreateCall(methodArgument, apiVarName: 'api'); + } if (isAsynchronous) { final String resultName = returnType.isVoid ? 'nil' : 'res'; final String successVariableInit = @@ -834,6 +1538,837 @@ private func nilOrValue(_ value: Any?) -> T? { }); } + void _writeProxyApiRegistrar( + Indent indent, { + required SwiftOptions generatorOptions, + required Iterable allProxyApis, + }) { + final String delegateName = + '${generatorOptions.fileSpecificClassNameComponent ?? ''}${proxyApiClassNamePrefix}ProxyApiDelegate'; + indent.writeScoped('protocol $delegateName {', '}', () { + for (final AstProxyApi api in allProxyApis) { + final String hostApiName = '$hostProxyApiPrefix${api.name}'; + addDocumentationComments( + indent, + [ + ' An implementation of [$hostApiName] used to add a new Dart instance of', + ' `${api.name}` to the Dart `InstanceManager` and make calls to Dart.' + ], + _docCommentSpec, + ); + indent.writeln( + 'func pigeonApi${api.name}(_ registrar: ${proxyApiRegistrarName(generatorOptions)}) -> $hostApiName', + ); + } + }); + indent.newln(); + + // Some APIs don't have any methods to implement, + // so this creates an extension of the PigeonProxyApiDelegate that adds + // default implementations for these APIs. + final Iterable apisThatCanHaveADefaultImpl = allProxyApis + .where((AstProxyApi api) => !api.hasMethodsRequiringImplementation()); + if (apisThatCanHaveADefaultImpl.isNotEmpty) { + indent.writeScoped('extension $delegateName {', '}', () { + for (final AstProxyApi api in apisThatCanHaveADefaultImpl) { + final String hostApiName = '$hostProxyApiPrefix${api.name}'; + final String swiftApiDelegateName = + '${hostProxyApiPrefix}Delegate${api.name}'; + indent.format( + ''' + func pigeonApi${api.name}(_ registrar: ${proxyApiRegistrarName(generatorOptions)}) -> $hostApiName { + return $hostApiName(pigeonRegistrar: registrar, delegate: $swiftApiDelegateName()) + }''', + ); + } + }); + indent.newln(); + } + + final String instanceManagerApiName = + '${swiftInstanceManagerClassName(generatorOptions)}Api'; + + indent.writeScoped( + 'open class ${proxyApiRegistrarName(generatorOptions)} {', '}', () { + indent.writeln('let binaryMessenger: FlutterBinaryMessenger'); + indent.writeln('let apiDelegate: $delegateName'); + indent.writeln( + 'let instanceManager: ${swiftInstanceManagerClassName(generatorOptions)}'); + + addDocumentationComments( + indent, + [' Whether APIs should ignore calling to Dart.'], + _docCommentSpec, + ); + indent.writeln('public var ignoreCallsToDart = false'); + + indent.writeln('private var _codec: FlutterStandardMessageCodec?'); + indent.format( + ''' + var codec: FlutterStandardMessageCodec { + if _codec == nil { + _codec = FlutterStandardMessageCodec( + readerWriter: ${proxyApiReaderWriterName(generatorOptions)}(pigeonRegistrar: self)) + } + return _codec! + }''', + ); + indent.newln(); + + indent.format( + ''' + private class InstanceManagerApiFinalizerDelegate: ${instanceManagerFinalizerDelegateName(generatorOptions)} { + let api: $instanceManagerApiName + + init(_ api: $instanceManagerApiName) { + self.api = api + } + + public func onDeinit(identifier: Int64) { + api.removeStrongReference(identifier: identifier) { + _ in + } + } + }''', + ); + indent.newln(); + + indent.format( + ''' + init(binaryMessenger: FlutterBinaryMessenger, apiDelegate: $delegateName) { + self.binaryMessenger = binaryMessenger + self.apiDelegate = apiDelegate + self.instanceManager = ${swiftInstanceManagerClassName(generatorOptions)}( + finalizerDelegate: InstanceManagerApiFinalizerDelegate( + $instanceManagerApiName(binaryMessenger: binaryMessenger))) + }''', + ); + indent.newln(); + + indent.writeScoped('func setUp() {', '}', () { + indent.writeln( + '$instanceManagerApiName.setUpMessageHandlers(binaryMessenger: binaryMessenger, instanceManager: instanceManager)', + ); + for (final AstProxyApi api in allProxyApis) { + if (api.hasAnyHostMessageCalls()) { + indent.writeln( + '$hostProxyApiPrefix${api.name}.setUpMessageHandlers(binaryMessenger: binaryMessenger, api: apiDelegate.pigeonApi${api.name}(self))', + ); + } + } + }); + + indent.writeScoped('func tearDown() {', '}', () { + indent.writeln( + '$instanceManagerApiName.setUpMessageHandlers(binaryMessenger: binaryMessenger, instanceManager: nil)', + ); + for (final AstProxyApi api in allProxyApis) { + if (api.hasAnyHostMessageCalls()) { + indent.writeln( + '$hostProxyApiPrefix${api.name}.setUpMessageHandlers(binaryMessenger: binaryMessenger, api: nil)', + ); + } + } + }); + }); + } + + // Writes the delegate method that instantiates a new instance of the Kotlin + // class. + void _writeProxyApiConstructorDelegateMethods( + Indent indent, + AstProxyApi api, { + required TypeDeclaration apiAsTypeDeclaration, + }) { + for (final Constructor constructor in api.constructors) { + final List allReferencedTypes = [ + apiAsTypeDeclaration, + ...api.unattachedFields.map((ApiField field) => field.type), + ...constructor.parameters.map((Parameter parameter) => parameter.type), + ]; + + final String? unsupportedPlatforms = + _tryGetUnsupportedPlatformsCondition(allReferencedTypes); + if (unsupportedPlatforms != null) { + indent.writeln('#if $unsupportedPlatforms'); + } + + addDocumentationComments( + indent, + constructor.documentationComments, + _docCommentSpec, + ); + + final String? availableAnnotation = + _tryGetAvailabilityAnnotation(allReferencedTypes); + if (availableAnnotation != null) { + indent.writeln('@$availableAnnotation'); + } + + final String methodSignature = _getMethodSignature( + name: constructor.name.isNotEmpty + ? constructor.name + : 'pigeonDefaultConstructor', + parameters: [ + Parameter( + name: 'pigeonApi', + type: TypeDeclaration( + baseName: '$hostProxyApiPrefix${api.name}', + isNullable: false, + ), + ), + ...api.unattachedFields.map((ApiField field) { + return Parameter(name: field.name, type: field.type); + }), + ...constructor.parameters + ], + returnType: apiAsTypeDeclaration, + errorTypeName: '', + ); + indent.writeln(methodSignature); + + if (unsupportedPlatforms != null) { + indent.writeln('#endif'); + } + } + } + + // Writes the delegate method that handles instantiating an attached field. + void _writeProxyApiAttachedFieldDelegateMethods( + Indent indent, + AstProxyApi api, { + required TypeDeclaration apiAsTypeDeclaration, + }) { + for (final ApiField field in api.attachedFields) { + final List allReferencedTypes = [ + apiAsTypeDeclaration, + field.type, + ]; + + final String? unsupportedPlatforms = + _tryGetUnsupportedPlatformsCondition(allReferencedTypes); + if (unsupportedPlatforms != null) { + indent.writeln('#if $unsupportedPlatforms'); + } + + addDocumentationComments( + indent, + field.documentationComments, + _docCommentSpec, + ); + + final String? availableAnnotation = + _tryGetAvailabilityAnnotation(allReferencedTypes); + if (availableAnnotation != null) { + indent.writeln('@$availableAnnotation'); + } + + final String methodSignature = _getMethodSignature( + name: field.name, + parameters: [ + Parameter( + name: 'pigeonApi', + type: TypeDeclaration( + baseName: '$hostProxyApiPrefix${api.name}', + isNullable: false, + ), + ), + if (!field.isStatic) + Parameter( + name: 'pigeonInstance', + type: apiAsTypeDeclaration, + ), + ], + returnType: field.type, + errorTypeName: '', + ); + indent.writeln(methodSignature); + + if (unsupportedPlatforms != null) { + indent.writeln('#endif'); + } + } + } + + // Writes the delegate method that handles accessing an unattached field. + void _writeProxyApiUnattachedFieldDelegateMethods( + Indent indent, + AstProxyApi api, { + required TypeDeclaration apiAsTypeDeclaration, + }) { + for (final ApiField field in api.unattachedFields) { + final List allReferencedTypes = [ + apiAsTypeDeclaration, + field.type, + ]; + + final String? unsupportedPlatforms = + _tryGetUnsupportedPlatformsCondition(allReferencedTypes); + if (unsupportedPlatforms != null) { + indent.writeln('#if $unsupportedPlatforms'); + } + + addDocumentationComments( + indent, + field.documentationComments, + _docCommentSpec, + ); + + final String? availableAnnotation = + _tryGetAvailabilityAnnotation(allReferencedTypes); + if (availableAnnotation != null) { + indent.writeln('@$availableAnnotation'); + } + + final String methodSignature = _getMethodSignature( + name: field.name, + parameters: [ + Parameter( + name: 'pigeonApi', + type: TypeDeclaration( + baseName: '$hostProxyApiPrefix${api.name}', + isNullable: false, + ), + ), + Parameter( + name: 'pigeonInstance', + type: apiAsTypeDeclaration, + ), + ], + returnType: field.type, + errorTypeName: '', + ); + indent.writeln(methodSignature); + + if (unsupportedPlatforms != null) { + indent.writeln('#endif'); + } + } + } + + // Writes the delegate method that handles making a call from for a host + // method. + void _writeProxyApiHostMethodDelegateMethods( + Indent indent, + AstProxyApi api, { + required TypeDeclaration apiAsTypeDeclaration, + }) { + for (final Method method in api.hostMethods) { + final List allReferencedTypes = [ + if (!method.isStatic) apiAsTypeDeclaration, + method.returnType, + ...method.parameters.map((Parameter p) => p.type), + ]; + + final String? unsupportedPlatforms = + _tryGetUnsupportedPlatformsCondition(allReferencedTypes); + if (unsupportedPlatforms != null) { + indent.writeln('#if $unsupportedPlatforms'); + } + + addDocumentationComments( + indent, + method.documentationComments, + _docCommentSpec, + ); + + final String? availableAnnotation = + _tryGetAvailabilityAnnotation(allReferencedTypes); + if (availableAnnotation != null) { + indent.writeln('@$availableAnnotation'); + } + + final String methodSignature = _getMethodSignature( + name: method.name, + parameters: [ + Parameter( + name: 'pigeonApi', + type: TypeDeclaration( + baseName: '$hostProxyApiPrefix${api.name}', + isNullable: false, + ), + ), + if (!method.isStatic) + Parameter( + name: 'pigeonInstance', + type: apiAsTypeDeclaration, + ), + ...method.parameters, + ], + returnType: method.returnType, + isAsynchronous: method.isAsynchronous, + errorTypeName: 'Error', + ); + indent.writeln(methodSignature); + + if (unsupportedPlatforms != null) { + indent.writeln('#endif'); + } + } + } + + // Writes the getters for accessing the implementation of other ProxyApis. + // + // These are used for inherited Flutter methods. + void _writeProxyApiInheritedApiMethods(Indent indent, AstProxyApi api) { + final Set inheritedApiNames = { + if (api.superClass != null) api.superClass!.baseName, + ...api.interfaces.map((TypeDeclaration type) => type.baseName), + }; + for (final String name in inheritedApiNames) { + addDocumentationComments( + indent, + [ + 'An implementation of [$name] used to access callback methods', + ], + _docCommentSpec, + ); + indent.writeScoped( + 'var pigeonApi$name: $hostProxyApiPrefix$name {', + '}', + () { + indent.writeln( + 'return pigeonRegistrar.apiDelegate.pigeonApi$name(pigeonRegistrar)', + ); + }, + ); + indent.newln(); + } + } + + // Writes the `..setUpMessageHandler` method to ensure incoming messages are + // handled by the correct delegate host methods. + void _writeProxyApiMessageHandlerMethod( + Indent indent, + AstProxyApi api, { + required SwiftOptions generatorOptions, + required TypeDeclaration apiAsTypeDeclaration, + required String swiftApiName, + required String dartPackageName, + }) { + indent.writeScoped( + 'static func setUpMessageHandlers(binaryMessenger: FlutterBinaryMessenger, api: $swiftApiName?) {', + '}', + () { + indent.format( + ''' + let codec: FlutterStandardMessageCodec = + api != nil + ? FlutterStandardMessageCodec( + readerWriter: ${proxyApiReaderWriterName(generatorOptions)}(pigeonRegistrar: api!.pigeonRegistrar)) + : FlutterStandardMessageCodec.sharedInstance()''', + ); + void writeWithApiCheckIfNecessary( + List types, { + required String methodName, + required String channelName, + required void Function() onWrite, + }) { + final String? unsupportedPlatforms = + _tryGetUnsupportedPlatformsCondition(types); + if (unsupportedPlatforms != null) { + indent.writeln('#if $unsupportedPlatforms'); + } + + final String? availableAnnotation = + _tryGetAvailabilityAnnotation(types); + if (availableAnnotation != null) { + indent.writeScoped( + 'if #$availableAnnotation {', + '}', + onWrite, + addTrailingNewline: false, + ); + indent.writeScoped(' else {', '}', () { + final String varChannelName = '${methodName}Channel'; + indent.format( + ''' + let $varChannelName = FlutterBasicMessageChannel( + name: "$channelName", + binaryMessenger: binaryMessenger, codec: codec) + if api != nil { + $varChannelName.setMessageHandler { message, reply in + reply(wrapError(FlutterError(code: "PigeonUnsupportedOperationError", + message: "Call to $methodName requires @$availableAnnotation.", + details: nil + ))) + } + } else { + $varChannelName.setMessageHandler(nil) + }''', + ); + }); + } else { + onWrite(); + } + + if (unsupportedPlatforms != null) { + indent.writeln('#endif'); + } + } + + for (final Constructor constructor in api.constructors) { + final String name = constructor.name.isNotEmpty + ? constructor.name + : 'pigeonDefaultConstructor'; + final String channelName = makeChannelNameWithStrings( + apiName: api.name, + methodName: '${classMemberNamePrefix}defaultConstructor', + dartPackageName: dartPackageName, + ); + writeWithApiCheckIfNecessary( + [ + apiAsTypeDeclaration, + ...api.unattachedFields.map((ApiField f) => f.type), + ...constructor.parameters.map((Parameter p) => p.type), + ], + methodName: name, + channelName: channelName, + onWrite: () { + _writeHostMethodMessageHandler( + indent, + name: name, + channelName: channelName, + returnType: const TypeDeclaration.voidDeclaration(), + swiftFunction: null, + isAsynchronous: false, + onCreateCall: ( + List methodParameters, { + required String apiVarName, + }) { + final List parameters = [ + 'pigeonApi: $apiVarName', + // Skip the identifier used by the InstanceManager. + ...methodParameters.skip(1), + ]; + return '$apiVarName.pigeonRegistrar.instanceManager.addDartCreatedInstance(\n' + 'try $apiVarName.pigeonDelegate.$name(${parameters.join(', ')}),\n' + 'withIdentifier: pigeonIdentifierArg)'; + }, + parameters: [ + Parameter( + name: 'pigeonIdentifier', + type: const TypeDeclaration( + baseName: 'int', + isNullable: false, + ), + ), + ...api.unattachedFields.map((ApiField field) { + return Parameter( + name: field.name, + type: field.type, + ); + }), + ...constructor.parameters, + ], + ); + }, + ); + } + + for (final ApiField field in api.attachedFields) { + final String channelName = makeChannelNameWithStrings( + apiName: api.name, + methodName: field.name, + dartPackageName: dartPackageName, + ); + writeWithApiCheckIfNecessary( + [apiAsTypeDeclaration, field.type], + methodName: field.name, + channelName: channelName, + onWrite: () { + _writeHostMethodMessageHandler( + indent, + name: field.name, + channelName: channelName, + swiftFunction: null, + isAsynchronous: false, + returnType: const TypeDeclaration.voidDeclaration(), + onCreateCall: ( + List methodParameters, { + required String apiVarName, + }) { + final String instanceArg = field.isStatic + ? '' + : ', pigeonInstance: pigeonInstanceArg'; + return '$apiVarName.pigeonRegistrar.instanceManager.addDartCreatedInstance(' + 'try $apiVarName.pigeonDelegate.${field.name}(pigeonApi: api$instanceArg), ' + 'withIdentifier: pigeonIdentifierArg)'; + }, + parameters: [ + if (!field.isStatic) + Parameter( + name: 'pigeonInstance', + type: apiAsTypeDeclaration, + ), + Parameter( + name: 'pigeonIdentifier', + type: const TypeDeclaration( + baseName: 'int', + isNullable: false, + ), + ), + ], + ); + }, + ); + } + + for (final Method method in api.hostMethods) { + final String channelName = + makeChannelName(api, method, dartPackageName); + writeWithApiCheckIfNecessary( + [ + apiAsTypeDeclaration, + method.returnType, + ...method.parameters.map((Parameter parameter) => parameter.type), + ], + methodName: method.name, + channelName: channelName, + onWrite: () { + _writeHostMethodMessageHandler( + indent, + name: method.name, + channelName: makeChannelName(api, method, dartPackageName), + returnType: method.returnType, + isAsynchronous: method.isAsynchronous, + swiftFunction: null, + onCreateCall: ( + List methodParameters, { + required String apiVarName, + }) { + final String tryStatement = + method.isAsynchronous ? '' : 'try '; + final List parameters = [ + 'pigeonApi: $apiVarName', + // Skip the identifier used by the InstanceManager. + ...methodParameters, + ]; + + return '$tryStatement$apiVarName.pigeonDelegate.${method.name}(${parameters.join(', ')})'; + }, + parameters: [ + if (!method.isStatic) + Parameter( + name: 'pigeonInstance', + type: apiAsTypeDeclaration, + ), + ...method.parameters, + ], + ); + }, + ); + } + }, + ); + } + + // Writes the method that calls to Dart to instantiate a new Dart instance. + void _writeProxyApiNewInstanceMethod( + Indent indent, + AstProxyApi api, { + required SwiftOptions generatorOptions, + required TypeDeclaration apiAsTypeDeclaration, + required String newInstanceMethodName, + required String dartPackageName, + }) { + final List allReferencedTypes = [ + apiAsTypeDeclaration, + ...api.unattachedFields.map((ApiField field) => field.type), + ]; + + final String? unsupportedPlatforms = + _tryGetUnsupportedPlatformsCondition(allReferencedTypes); + if (unsupportedPlatforms != null) { + indent.writeln('#if $unsupportedPlatforms'); + } + + addDocumentationComments( + indent, + [ + 'Creates a Dart instance of ${api.name} and attaches it to [pigeonInstance].' + ], + _docCommentSpec, + ); + + final String? availableAnnotation = _tryGetAvailabilityAnnotation( + allReferencedTypes, + ); + if (availableAnnotation != null) { + indent.writeln('@$availableAnnotation'); + } + + final String methodSignature = _getMethodSignature( + name: 'pigeonNewInstance', + parameters: [ + Parameter(name: 'pigeonInstance', type: apiAsTypeDeclaration), + ], + returnType: const TypeDeclaration.voidDeclaration(), + isAsynchronous: true, + errorTypeName: _getErrorClassName(generatorOptions), + ); + indent.writeScoped('$methodSignature {', '}', () { + indent.writeScoped( + 'if pigeonRegistrar.ignoreCallsToDart {', + '}', + () { + indent.format( + ''' + completion( + .failure( + ${_getErrorClassName(generatorOptions)}( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return''', + ); + }, + ); + + indent.writeScoped( + 'if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) {', + '}', + () { + indent.writeln('completion(.success(Void()))'); + indent.writeln('return'); + }, + ); + if (api.hasCallbackConstructor()) { + indent.writeln( + 'let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeonInstance as AnyObject)', + ); + enumerate(api.unattachedFields, (int index, ApiField field) { + final String argName = _getSafeArgumentName(index, field); + indent.writeln( + 'let $argName = try! pigeonDelegate.${field.name}(pigeonApi: self, pigeonInstance: pigeonInstance)', + ); + }); + indent.writeln( + 'let binaryMessenger = pigeonRegistrar.binaryMessenger', + ); + indent.writeln('let codec = pigeonRegistrar.codec'); + _writeFlutterMethodMessageCall( + indent, + generatorOptions: generatorOptions, + parameters: [ + Parameter( + name: 'pigeonIdentifier', + type: const TypeDeclaration( + baseName: 'int', + isNullable: false, + ), + ), + ...api.unattachedFields.map( + (ApiField field) { + return Parameter(name: field.name, type: field.type); + }, + ), + ], + returnType: const TypeDeclaration.voidDeclaration(), + channelName: makeChannelNameWithStrings( + apiName: api.name, + methodName: newInstanceMethodName, + dartPackageName: dartPackageName, + ), + ); + } else { + indent.writeln( + 'print("Error: Attempting to create a new Dart instance of ${api.name}, but the class has a nonnull callback method.")', + ); + } + }); + + if (unsupportedPlatforms != null) { + indent.writeln('#endif'); + } + } + + // Writes the Flutter methods that call back to Dart. + void _writeProxyApiFlutterMethods( + Indent indent, + AstProxyApi api, { + required SwiftOptions generatorOptions, + required TypeDeclaration apiAsTypeDeclaration, + required String dartPackageName, + bool writeBody = true, + }) { + for (final Method method in api.flutterMethods) { + final List allReferencedTypes = [ + apiAsTypeDeclaration, + ...method.parameters.map((Parameter parameter) => parameter.type), + method.returnType, + ]; + + final String? unsupportedPlatforms = + _tryGetUnsupportedPlatformsCondition(allReferencedTypes); + if (unsupportedPlatforms != null) { + indent.writeln('#if $unsupportedPlatforms'); + } + + addDocumentationComments( + indent, + method.documentationComments, + _docCommentSpec, + ); + + final String? availableAnnotation = + _tryGetAvailabilityAnnotation(allReferencedTypes); + if (availableAnnotation != null) { + indent.writeln('@$availableAnnotation'); + } + + final String methodSignature = _getMethodSignature( + name: method.name, + parameters: [ + Parameter(name: 'pigeonInstance', type: apiAsTypeDeclaration), + ...method.parameters, + ], + returnType: method.returnType, + isAsynchronous: true, + errorTypeName: _getErrorClassName(generatorOptions), + getParameterName: _getSafeArgumentName, + ); + + indent.write(methodSignature); + if (writeBody) { + indent.writeScoped(' {', '}', () { + indent.writeScoped( + 'if pigeonRegistrar.ignoreCallsToDart {', + '}', + () { + indent.format( + ''' + completion( + .failure( + ${_getErrorClassName(generatorOptions)}( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return''', + ); + }, + ); + indent + .writeln('let binaryMessenger = pigeonRegistrar.binaryMessenger'); + indent.writeln('let codec = pigeonRegistrar.codec'); + + _writeFlutterMethodMessageCall( + indent, + generatorOptions: generatorOptions, + parameters: [ + Parameter(name: 'pigeonInstance', type: apiAsTypeDeclaration), + ...method.parameters, + ], + returnType: method.returnType, + channelName: makeChannelName(api, method, dartPackageName), + ); + }); + } + if (unsupportedPlatforms != null) { + indent.writeln('#endif'); + } + indent.newln(); + } + } + void _writePigeonError(SwiftOptions generatorOptions, Indent indent) { indent.newln(); indent.writeln( @@ -862,6 +2397,99 @@ private func nilOrValue(_ value: Any?) -> T? { } } +typedef _VersionRequirement = ({TypeDeclaration type, Version version}); +({_VersionRequirement? ios, _VersionRequirement? macos}) + _findHighestVersionRequirement( + Iterable types, +) { + final _VersionRequirement? iosApiRequirement = + findHighestApiRequirement( + types, + onGetApiRequirement: (TypeDeclaration type) { + final String? apiRequirement = + type.associatedProxyApi?.swiftOptions?.minIosApi; + if (apiRequirement != null) { + return Version.parse(apiRequirement); + } + + return null; + }, + onCompare: (Version one, Version two) => one.compareTo(two), + ); + + final _VersionRequirement? macosApiRequirement = + findHighestApiRequirement( + types, + onGetApiRequirement: (TypeDeclaration type) { + final String? apiRequirement = + type.associatedProxyApi?.swiftOptions?.minMacosApi; + if (apiRequirement != null) { + return Version.parse(apiRequirement); + } + + return null; + }, + onCompare: (Version one, Version two) => one.compareTo(two), + ); + + return (ios: iosApiRequirement, macos: macosApiRequirement); +} + +/// Finds the highest api requirement for each supported platform and creates +/// the `available(platform version , platform version ..., *)` annotation. +/// +/// Returns `null` if there is not api requirement in [types]. +String? _tryGetAvailabilityAnnotation(Iterable types) { + final ({ + _VersionRequirement? ios, + _VersionRequirement? macos + }) versionRequirement = _findHighestVersionRequirement(types); + + final List apis = [ + if (versionRequirement.ios != null) + 'iOS ${versionRequirement.ios!.version}', + if (versionRequirement.macos != null) + 'macOS ${versionRequirement.macos!.version}', + ]; + + return apis.isNotEmpty ? 'available(${apis.join(', ')}, *)' : null; +} + +/// Creates the string used to indicate a platform is unsupported. +/// +/// Recursively iterates through all types to find any that are not supported +/// by a platform. +/// +/// Returns `null` if every type supports all platforms. +String? _tryGetUnsupportedPlatformsCondition(Iterable types) { + Iterable addAllRecursive(TypeDeclaration type) sync* { + yield type; + if (type.typeArguments.isNotEmpty) { + for (final TypeDeclaration typeArg in type.typeArguments) { + yield* addAllRecursive(typeArg); + } + } + } + + final Iterable allReferencedTypes = + types.expand(addAllRecursive); + + final List unsupportedPlatforms = [ + if (!allReferencedTypes.every((TypeDeclaration type) { + return type.associatedProxyApi?.swiftOptions?.supportsIos ?? true; + })) + '!os(iOS)', + if (!allReferencedTypes.every((TypeDeclaration type) { + return type.associatedProxyApi?.swiftOptions?.supportsMacos ?? true; + })) + '!os(macOS)', + ]; + + return unsupportedPlatforms.isNotEmpty + ? unsupportedPlatforms.join(' || ') + : null; +} + /// Calculates the name of the codec that will be generated for [api]. String _getCodecName(SwiftOptions options) { return '${options.fileSpecificClassNameComponent}PigeonCodec'; @@ -894,27 +2522,29 @@ String _flattenTypeArguments(List args) { } String _swiftTypeForBuiltinGenericDartType(TypeDeclaration type) { - if (type.typeArguments.isEmpty || - (type.typeArguments.first.baseName == 'Object')) { + if (type.typeArguments.isEmpty) { if (type.baseName == 'List') { return '[Any?]'; } else if (type.baseName == 'Map') { - return '[AnyHashable: Any?]'; + return '[AnyHashable?: Any?]'; } else { return 'Any'; } } else { if (type.baseName == 'List') { - return '[${_nullsafeSwiftTypeForDartType(type.typeArguments.first)}]'; + return '[${_nullSafeSwiftTypeForDartType(type.typeArguments.first)}]'; } else if (type.baseName == 'Map') { - return '[${_nullsafeSwiftTypeForDartType(type.typeArguments.first)}: ${_nullsafeSwiftTypeForDartType(type.typeArguments.last)}]'; + return '[${_nullSafeSwiftTypeForDartType(type.typeArguments.first, mapKey: true)}: ${_nullSafeSwiftTypeForDartType(type.typeArguments.last)}]'; } else { return '${type.baseName}<${_flattenTypeArguments(type.typeArguments)}>'; } } } -String? _swiftTypeForBuiltinDartType(TypeDeclaration type) { +String? _swiftTypeForBuiltinDartType( + TypeDeclaration type, { + bool mapKey = false, +}) { const Map swiftTypeForDartTypeMap = { 'void': 'Void', 'bool': 'Bool', @@ -928,7 +2558,9 @@ String? _swiftTypeForBuiltinDartType(TypeDeclaration type) { 'Float64List': 'FlutterStandardTypedData', 'Object': 'Any', }; - if (swiftTypeForDartTypeMap.containsKey(type.baseName)) { + if (mapKey && type.baseName == 'Object') { + return 'AnyHashable'; + } else if (swiftTypeForDartTypeMap.containsKey(type.baseName)) { return swiftTypeForDartTypeMap[type.baseName]; } else if (type.baseName == 'List' || type.baseName == 'Map') { return _swiftTypeForBuiltinGenericDartType(type); @@ -937,13 +2569,27 @@ String? _swiftTypeForBuiltinDartType(TypeDeclaration type) { } } -String _swiftTypeForDartType(TypeDeclaration type) { - return _swiftTypeForBuiltinDartType(type) ?? type.baseName; +String? _swiftTypeForProxyApiType(TypeDeclaration type) { + if (type.isProxyApi) { + return type.associatedProxyApi!.swiftOptions?.name ?? + type.associatedProxyApi!.name; + } + + return null; +} + +String _swiftTypeForDartType(TypeDeclaration type, {bool mapKey = false}) { + return _swiftTypeForBuiltinDartType(type, mapKey: mapKey) ?? + _swiftTypeForProxyApiType(type) ?? + type.baseName; } -String _nullsafeSwiftTypeForDartType(TypeDeclaration type) { +String _nullSafeSwiftTypeForDartType( + TypeDeclaration type, { + bool mapKey = false, +}) { final String nullSafe = type.isNullable ? '?' : ''; - return '${_swiftTypeForDartType(type)}$nullSafe'; + return '${_swiftTypeForDartType(type, mapKey: mapKey)}$nullSafe'; } String _getMethodSignature({ @@ -963,10 +2609,10 @@ String _getMethodSignature({ swiftFunction: swiftFunction, ); final String returnTypeString = - returnType.isVoid ? 'Void' : _nullsafeSwiftTypeForDartType(returnType); + returnType.isVoid ? 'Void' : _nullSafeSwiftTypeForDartType(returnType); final Iterable types = - parameters.map((NamedType e) => _nullsafeSwiftTypeForDartType(e.type)); + parameters.map((NamedType e) => _nullSafeSwiftTypeForDartType(e.type)); final Iterable labels = indexMap(components.arguments, (int index, _SwiftFunctionArgument argument) { return argument.label ?? _getArgumentName(index, argument.namedType); diff --git a/packages/pigeon/pigeons/core_tests.dart b/packages/pigeon/pigeons/core_tests.dart index b4dc3fdfb027..a644ce5b3e00 100644 --- a/packages/pigeon/pigeons/core_tests.dart +++ b/packages/pigeon/pigeons/core_tests.dart @@ -12,6 +12,19 @@ enum AnEnum { fourHundredTwentyTwo, } +// Enums require special logic, having multiple ensures that the logic can be +// replicated without collision. +enum AnotherEnum { + justInCase, +} + +// This exists to show that unused data classes still generate. +class UnusedClass { + UnusedClass({this.aField}); + + Object? aField; +} + /// A class containing all supported types. class AllTypes { AllTypes({ @@ -24,20 +37,31 @@ class AllTypes { required this.a8ByteArray, required this.aFloatArray, this.anEnum = AnEnum.one, + this.anotherEnum = AnotherEnum.justInCase, this.aString = '', this.anObject = 0, // Lists // This name is in a different format than the others to ensure that name - // collision with the work 'list' doesn't occur in the generated files. + // collision with the word 'list' doesn't occur in the generated files. required this.list, required this.stringList, required this.intList, required this.doubleList, required this.boolList, + required this.enumList, + required this.objectList, + required this.listList, + required this.mapList, // Maps required this.map, + required this.stringMap, + required this.intMap, + required this.enumMap, + required this.objectMap, + required this.listMap, + required this.mapMap, }); bool aBool; @@ -49,20 +73,31 @@ class AllTypes { Int64List a8ByteArray; Float64List aFloatArray; AnEnum anEnum; + AnotherEnum anotherEnum; String aString; Object anObject; // Lists // ignore: strict_raw_type, always_specify_types List list; - List stringList; - List intList; - List doubleList; - List boolList; + List stringList; + List intList; + List doubleList; + List boolList; + List enumList; + List objectList; + List> listList; + List> mapList; // Maps // ignore: strict_raw_type, always_specify_types Map map; + Map stringMap; + Map intMap; + Map enumMap; + Map objectMap; + Map> listMap; + Map> mapMap; } /// A class containing all supported nullable types. @@ -77,24 +112,35 @@ class AllNullableTypes { this.aNullable4ByteArray, this.aNullable8ByteArray, this.aNullableFloatArray, - this.nullableNestedList, - this.nullableMapWithAnnotations, - this.nullableMapWithObject, this.aNullableEnum, + this.anotherNullableEnum, this.aNullableString, this.aNullableObject, this.allNullableTypes, // Lists + // This name is in a different format than the others to ensure that name + // collision with the word 'list' doesn't occur in the generated files. this.list, this.stringList, this.intList, this.doubleList, this.boolList, - this.nestedClassList, + this.enumList, + this.objectList, + this.listList, + this.mapList, + this.recursiveClassList, - //Maps + // Maps this.map, + this.stringMap, + this.intMap, + this.enumMap, + this.objectMap, + this.listMap, + this.mapMap, + this.recursiveClassMap, ); bool? aNullableBool; @@ -105,10 +151,8 @@ class AllNullableTypes { Int32List? aNullable4ByteArray; Int64List? aNullable8ByteArray; Float64List? aNullableFloatArray; - List?>? nullableNestedList; - Map? nullableMapWithAnnotations; - Map? nullableMapWithObject; AnEnum? aNullableEnum; + AnotherEnum? anotherNullableEnum; String? aNullableString; Object? aNullableObject; AllNullableTypes? allNullableTypes; @@ -120,11 +164,22 @@ class AllNullableTypes { List? intList; List? doubleList; List? boolList; - List? nestedClassList; + List? enumList; + List? objectList; + List?>? listList; + List?>? mapList; + List? recursiveClassList; // Maps // ignore: strict_raw_type, always_specify_types Map? map; + Map? stringMap; + Map? intMap; + Map? enumMap; + Map? objectMap; + Map?>? listMap; + Map?>? mapMap; + Map? recursiveClassMap; } /// The primary purpose for this class is to ensure coverage of Swift structs @@ -140,22 +195,32 @@ class AllNullableTypesWithoutRecursion { this.aNullable4ByteArray, this.aNullable8ByteArray, this.aNullableFloatArray, - this.nullableNestedList, - this.nullableMapWithAnnotations, - this.nullableMapWithObject, this.aNullableEnum, + this.anotherNullableEnum, this.aNullableString, this.aNullableObject, // Lists + // This name is in a different format than the others to ensure that name + // collision with the word 'list' doesn't occur in the generated files. this.list, this.stringList, this.intList, this.doubleList, this.boolList, + this.enumList, + this.objectList, + this.listList, + this.mapList, - //Maps + // Maps this.map, + this.stringMap, + this.intMap, + this.enumMap, + this.objectMap, + this.listMap, + this.mapMap, ); bool? aNullableBool; @@ -166,10 +231,8 @@ class AllNullableTypesWithoutRecursion { Int32List? aNullable4ByteArray; Int64List? aNullable8ByteArray; Float64List? aNullableFloatArray; - List?>? nullableNestedList; - Map? nullableMapWithAnnotations; - Map? nullableMapWithObject; AnEnum? aNullableEnum; + AnotherEnum? anotherNullableEnum; String? aNullableString; Object? aNullableObject; @@ -180,10 +243,20 @@ class AllNullableTypesWithoutRecursion { List? intList; List? doubleList; List? boolList; + List? enumList; + List? objectList; + List?>? listList; + List?>? mapList; // Maps // ignore: strict_raw_type, always_specify_types Map? map; + Map? stringMap; + Map? intMap; + Map? enumMap; + Map? objectMap; + Map?>? listMap; + Map?>? mapMap; } /// A class for testing nested class handling. @@ -192,11 +265,22 @@ class AllNullableTypesWithoutRecursion { /// `AllNullableTypes` is non-nullable here as it is easier to instantiate /// than `AllTypes` when testing doesn't require both (ie. testing null classes). class AllClassesWrapper { - AllClassesWrapper(this.allNullableTypes, - this.allNullableTypesWithoutRecursion, this.allTypes); + AllClassesWrapper( + this.allNullableTypes, + this.allNullableTypesWithoutRecursion, + this.allTypes, + this.classList, + this.classMap, + this.nullableClassList, + this.nullableClassMap, + ); AllNullableTypes allNullableTypes; AllNullableTypesWithoutRecursion? allNullableTypesWithoutRecursion; AllTypes? allTypes; + List classList; + List? nullableClassList; + Map classMap; + Map? nullableClassMap; } /// The core interface that each host language plugin must implement in @@ -258,12 +342,74 @@ abstract class HostIntegrationCoreApi { @SwiftFunction('echo(_:)') List echoList(List list); + /// Returns the passed list, to test serialization and deserialization. + @ObjCSelector('echoEnumList:') + @SwiftFunction('echo(enumList:)') + List echoEnumList(List enumList); + + /// Returns the passed list, to test serialization and deserialization. + @ObjCSelector('echoClassList:') + @SwiftFunction('echo(classList:)') + List echoClassList(List classList); + + /// Returns the passed list, to test serialization and deserialization. + @ObjCSelector('echoNonNullEnumList:') + @SwiftFunction('echoNonNull(enumList:)') + List echoNonNullEnumList(List enumList); + + /// Returns the passed list, to test serialization and deserialization. + @ObjCSelector('echoNonNullClassList:') + @SwiftFunction('echoNonNull(classList:)') + List echoNonNullClassList(List classList); + /// Returns the passed map, to test serialization and deserialization. @ObjCSelector('echoMap:') @SwiftFunction('echo(_:)') - Map echoMap(Map aMap); + Map echoMap(Map map); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoStringMap:') + @SwiftFunction('echo(stringMap:)') + Map echoStringMap(Map stringMap); - /// Returns the passed map to test nested class serialization and deserialization. + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoIntMap:') + @SwiftFunction('echo(intMap:)') + Map echoIntMap(Map intMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoEnumMap:') + @SwiftFunction('echo(enumMap:)') + Map echoEnumMap(Map enumMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoClassMap:') + @SwiftFunction('echo(classMap:)') + Map echoClassMap( + Map classMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoNonNullStringMap:') + @SwiftFunction('echoNonNull(stringMap:)') + Map echoNonNullStringMap(Map stringMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoNonNullIntMap:') + @SwiftFunction('echoNonNull(intMap:)') + Map echoNonNullIntMap(Map intMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoNonNullEnumMap:') + @SwiftFunction('echoNonNull(enumMap:)') + Map echoNonNullEnumMap(Map enumMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoNonNullClassMap:') + @SwiftFunction('echoNonNull(classMap:)') + Map echoNonNullClassMap( + Map classMap); + + /// Returns the passed class to test nested class serialization and deserialization. @ObjCSelector('echoClassWrapper:') @SwiftFunction('echo(_:)') AllClassesWrapper echoClassWrapper(AllClassesWrapper wrapper); @@ -273,6 +419,11 @@ abstract class HostIntegrationCoreApi { @SwiftFunction('echo(_:)') AnEnum echoEnum(AnEnum anEnum); + /// Returns the passed enum to test serialization and deserialization. + @ObjCSelector('echoAnotherEnum:') + @SwiftFunction('echo(_:)') + AnotherEnum echoAnotherEnum(AnotherEnum anotherEnum); + /// Returns the default string. @ObjCSelector('echoNamedDefaultString:') @SwiftFunction('echoNamedDefault(_:)') @@ -361,15 +512,85 @@ abstract class HostIntegrationCoreApi { @SwiftFunction('echoNullable(_:)') List? echoNullableList(List? aNullableList); + /// Returns the passed list, to test serialization and deserialization. + @ObjCSelector('echoNullableEnumList:') + @SwiftFunction('echoNullable(enumList:)') + List? echoNullableEnumList(List? enumList); + + /// Returns the passed list, to test serialization and deserialization. + @ObjCSelector('echoNullableClassList:') + @SwiftFunction('echoNullable(classList:)') + List? echoNullableClassList( + List? classList); + + /// Returns the passed list, to test serialization and deserialization. + @ObjCSelector('echoNullableNonNullEnumList:') + @SwiftFunction('echoNullableNonNull(enumList:)') + List? echoNullableNonNullEnumList(List? enumList); + + /// Returns the passed list, to test serialization and deserialization. + @ObjCSelector('echoNullableNonNullClassList:') + @SwiftFunction('echoNullableNonNull(classList:)') + List? echoNullableNonNullClassList( + List? classList); + /// Returns the passed map, to test serialization and deserialization. @ObjCSelector('echoNullableMap:') @SwiftFunction('echoNullable(_:)') - Map? echoNullableMap(Map? aNullableMap); + Map? echoNullableMap(Map? map); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoNullableStringMap:') + @SwiftFunction('echoNullable(stringMap:)') + Map? echoNullableStringMap( + Map? stringMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoNullableIntMap:') + @SwiftFunction('echoNullable(intMap:)') + Map? echoNullableIntMap(Map? intMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoNullableEnumMap:') + @SwiftFunction('echoNullable(enumMap:)') + Map? echoNullableEnumMap(Map? enumMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoNullableClassMap:') + @SwiftFunction('echoNullable(classMap:)') + Map? echoNullableClassMap( + Map? classMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoNullableNonNullStringMap:') + @SwiftFunction('echoNullableNonNull(stringMap:)') + Map? echoNullableNonNullStringMap( + Map? stringMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoNullableNonNullIntMap:') + @SwiftFunction('echoNullableNonNull(intMap:)') + Map? echoNullableNonNullIntMap(Map? intMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoNullableNonNullEnumMap:') + @SwiftFunction('echoNullableNonNull(enumMap:)') + Map? echoNullableNonNullEnumMap(Map? enumMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoNullableNonNullClassMap:') + @SwiftFunction('echoNullableNonNull(classMap:)') + Map? echoNullableNonNullClassMap( + Map? classMap); @ObjCSelector('echoNullableEnum:') @SwiftFunction('echoNullable(_:)') AnEnum? echoNullableEnum(AnEnum? anEnum); + @ObjCSelector('echoAnotherNullableEnum:') + @SwiftFunction('echoNullable(_:)') + AnotherEnum? echoAnotherNullableEnum(AnotherEnum? anotherEnum); + /// Returns passed in int. @ObjCSelector('echoOptionalNullableInt:') @SwiftFunction('echoOptional(_:)') @@ -429,11 +650,48 @@ abstract class HostIntegrationCoreApi { @SwiftFunction('echoAsync(_:)') List echoAsyncList(List list); + /// Returns the passed list, to test asynchronous serialization and deserialization. + @async + @ObjCSelector('echoAsyncEnumList:') + @SwiftFunction('echoAsync(enumList:)') + List echoAsyncEnumList(List enumList); + + /// Returns the passed list, to test asynchronous serialization and deserialization. + @async + @ObjCSelector('echoAsyncClassList:') + @SwiftFunction('echoAsync(classList:)') + List echoAsyncClassList(List classList); + /// Returns the passed map, to test asynchronous serialization and deserialization. @async @ObjCSelector('echoAsyncMap:') @SwiftFunction('echoAsync(_:)') - Map echoAsyncMap(Map aMap); + Map echoAsyncMap(Map map); + + /// Returns the passed map, to test asynchronous serialization and deserialization. + @async + @ObjCSelector('echoAsyncStringMap:') + @SwiftFunction('echoAsync(stringMap:)') + Map echoAsyncStringMap(Map stringMap); + + /// Returns the passed map, to test asynchronous serialization and deserialization. + @async + @ObjCSelector('echoAsyncIntMap:') + @SwiftFunction('echoAsync(intMap:)') + Map echoAsyncIntMap(Map intMap); + + /// Returns the passed map, to test asynchronous serialization and deserialization. + @async + @ObjCSelector('echoAsyncEnumMap:') + @SwiftFunction('echoAsync(enumMap:)') + Map echoAsyncEnumMap(Map enumMap); + + /// Returns the passed map, to test asynchronous serialization and deserialization. + @async + @ObjCSelector('echoAsyncClassMap:') + @SwiftFunction('echoAsync(classMap:)') + Map echoAsyncClassMap( + Map classMap); /// Returns the passed enum, to test asynchronous serialization and deserialization. @async @@ -441,6 +699,12 @@ abstract class HostIntegrationCoreApi { @SwiftFunction('echoAsync(_:)') AnEnum echoAsyncEnum(AnEnum anEnum); + /// Returns the passed enum, to test asynchronous serialization and deserialization. + @async + @ObjCSelector('echoAnotherAsyncEnum:') + @SwiftFunction('echoAsync(_:)') + AnotherEnum echoAnotherAsyncEnum(AnotherEnum anotherEnum); + /// Responds with an error from an async function returning a value. @async Object? throwAsyncError(); @@ -516,11 +780,51 @@ abstract class HostIntegrationCoreApi { @SwiftFunction('echoAsyncNullable(_:)') List? echoAsyncNullableList(List? list); + /// Returns the passed list, to test asynchronous serialization and deserialization. + @async + @ObjCSelector('echoAsyncNullableEnumList:') + @SwiftFunction('echoAsyncNullable(enumList:)') + List? echoAsyncNullableEnumList(List? enumList); + + /// Returns the passed list, to test asynchronous serialization and deserialization. + @async + @ObjCSelector('echoAsyncNullableClassList:') + @SwiftFunction('echoAsyncNullable(classList:)') + List? echoAsyncNullableClassList( + List? classList); + /// Returns the passed map, to test asynchronous serialization and deserialization. @async @ObjCSelector('echoAsyncNullableMap:') @SwiftFunction('echoAsyncNullable(_:)') - Map? echoAsyncNullableMap(Map? aMap); + Map? echoAsyncNullableMap(Map? map); + + /// Returns the passed map, to test asynchronous serialization and deserialization. + @async + @ObjCSelector('echoAsyncNullableStringMap:') + @SwiftFunction('echoAsyncNullable(stringMap:)') + Map? echoAsyncNullableStringMap( + Map? stringMap); + + /// Returns the passed map, to test asynchronous serialization and deserialization. + @async + @ObjCSelector('echoAsyncNullableIntMap:') + @SwiftFunction('echoAsyncNullable(intMap:)') + Map? echoAsyncNullableIntMap(Map? intMap); + + /// Returns the passed map, to test asynchronous serialization and deserialization. + @async + @ObjCSelector('echoAsyncNullableEnumMap:') + @SwiftFunction('echoAsyncNullable(enumMap:)') + Map? echoAsyncNullableEnumMap( + Map? enumMap); + + /// Returns the passed map, to test asynchronous serialization and deserialization. + @async + @ObjCSelector('echoAsyncNullableClassMap:') + @SwiftFunction('echoAsyncNullable(classMap:)') + Map? echoAsyncNullableClassMap( + Map? classMap); /// Returns the passed enum, to test asynchronous serialization and deserialization. @async @@ -528,6 +832,12 @@ abstract class HostIntegrationCoreApi { @SwiftFunction('echoAsyncNullable(_:)') AnEnum? echoAsyncNullableEnum(AnEnum? anEnum); + /// Returns the passed enum, to test asynchronous serialization and deserialization. + @async + @ObjCSelector('echoAnotherAsyncNullableEnum:') + @SwiftFunction('echoAsyncNullable(_:)') + AnotherEnum? echoAnotherAsyncNullableEnum(AnotherEnum? anotherEnum); + // ========== Flutter API test wrappers ========== @async @@ -602,16 +912,88 @@ abstract class HostIntegrationCoreApi { @SwiftFunction('callFlutterEcho(_:)') List callFlutterEchoList(List list); + @async + @ObjCSelector('callFlutterEchoEnumList:') + @SwiftFunction('callFlutterEcho(enumList:)') + List callFlutterEchoEnumList(List enumList); + + @async + @ObjCSelector('callFlutterEchoClassList:') + @SwiftFunction('callFlutterEcho(classList:)') + List callFlutterEchoClassList( + List classList); + + @async + @ObjCSelector('callFlutterEchoNonNullEnumList:') + @SwiftFunction('callFlutterEchoNonNull(enumList:)') + List callFlutterEchoNonNullEnumList(List enumList); + + @async + @ObjCSelector('callFlutterEchoNonNullClassList:') + @SwiftFunction('callFlutterEchoNonNull(classList:)') + List callFlutterEchoNonNullClassList( + List classList); + @async @ObjCSelector('callFlutterEchoMap:') @SwiftFunction('callFlutterEcho(_:)') - Map callFlutterEchoMap(Map aMap); + Map callFlutterEchoMap(Map map); + + @async + @ObjCSelector('callFlutterEchoStringMap:') + @SwiftFunction('callFlutterEcho(stringMap:)') + Map callFlutterEchoStringMap( + Map stringMap); + + @async + @ObjCSelector('callFlutterEchoIntMap:') + @SwiftFunction('callFlutterEcho(intMap:)') + Map callFlutterEchoIntMap(Map intMap); + + @async + @ObjCSelector('callFlutterEchoEnumMap:') + @SwiftFunction('callFlutterEcho(enumMap:)') + Map callFlutterEchoEnumMap(Map enumMap); + + @async + @ObjCSelector('callFlutterEchoClassMap:') + @SwiftFunction('callFlutterEcho(classMap:)') + Map callFlutterEchoClassMap( + Map classMap); + + @async + @ObjCSelector('callFlutterEchoNonNullStringMap:') + @SwiftFunction('callFlutterEchoNonNull(stringMap:)') + Map callFlutterEchoNonNullStringMap( + Map stringMap); + + @async + @ObjCSelector('callFlutterEchoNonNullIntMap:') + @SwiftFunction('callFlutterEchoNonNull(intMap:)') + Map callFlutterEchoNonNullIntMap(Map intMap); + + @async + @ObjCSelector('callFlutterEchoNonNullEnumMap:') + @SwiftFunction('callFlutterEchoNonNull(enumMap:)') + Map callFlutterEchoNonNullEnumMap( + Map enumMap); + + @async + @ObjCSelector('callFlutterEchoNonNullClassMap:') + @SwiftFunction('callFlutterEchoNonNull(classMap:)') + Map callFlutterEchoNonNullClassMap( + Map classMap); @async @ObjCSelector('callFlutterEchoEnum:') @SwiftFunction('callFlutterEcho(_:)') AnEnum callFlutterEchoEnum(AnEnum anEnum); + @async + @ObjCSelector('callFlutterEchoAnotherEnum:') + @SwiftFunction('callFlutterEcho(_:)') + AnotherEnum callFlutterEchoAnotherEnum(AnotherEnum anotherEnum); + @async @ObjCSelector('callFlutterEchoNullableBool:') @SwiftFunction('callFlutterEchoNullable(_:)') @@ -642,17 +1024,89 @@ abstract class HostIntegrationCoreApi { @SwiftFunction('callFlutterEchoNullable(_:)') List? callFlutterEchoNullableList(List? list); + @async + @ObjCSelector('callFlutterEchoNullableEnumList:') + @SwiftFunction('callFlutterEchoNullable(enumList:)') + List? callFlutterEchoNullableEnumList(List? enumList); + + @async + @ObjCSelector('callFlutterEchoNullableClassList:') + @SwiftFunction('callFlutterEchoNullable(classList:)') + List? callFlutterEchoNullableClassList( + List? classList); + + @async + @ObjCSelector('callFlutterEchoNullableNonNullEnumList:') + @SwiftFunction('callFlutterEchoNullableNonNull(enumList:)') + List? callFlutterEchoNullableNonNullEnumList(List? enumList); + + @async + @ObjCSelector('callFlutterEchoNullableNonNullClassList:') + @SwiftFunction('callFlutterEchoNullableNonNull(classList:)') + List? callFlutterEchoNullableNonNullClassList( + List? classList); + @async @ObjCSelector('callFlutterEchoNullableMap:') @SwiftFunction('callFlutterEchoNullable(_:)') - Map? callFlutterEchoNullableMap( - Map? aMap); + Map? callFlutterEchoNullableMap(Map? map); + + @async + @ObjCSelector('callFlutterEchoNullableStringMap:') + @SwiftFunction('callFlutterEchoNullable(stringMap:)') + Map? callFlutterEchoNullableStringMap( + Map? stringMap); + + @async + @ObjCSelector('callFlutterEchoNullableIntMap:') + @SwiftFunction('callFlutterEchoNullable(intMap:)') + Map? callFlutterEchoNullableIntMap(Map? intMap); + + @async + @ObjCSelector('callFlutterEchoNullableEnumMap:') + @SwiftFunction('callFlutterEchoNullable(enumMap:)') + Map? callFlutterEchoNullableEnumMap( + Map? enumMap); + + @async + @ObjCSelector('callFlutterEchoNullableClassMap:') + @SwiftFunction('callFlutterEchoNullable(classMap:)') + Map? callFlutterEchoNullableClassMap( + Map? classMap); + + @async + @ObjCSelector('callFlutterEchoNullableNonNullStringMap:') + @SwiftFunction('callFlutterEchoNullableNonNull(stringMap:)') + Map? callFlutterEchoNullableNonNullStringMap( + Map? stringMap); + + @async + @ObjCSelector('callFlutterEchoNullableNonNullIntMap:') + @SwiftFunction('callFlutterEchoNullableNonNull(intMap:)') + Map? callFlutterEchoNullableNonNullIntMap(Map? intMap); + + @async + @ObjCSelector('callFlutterEchoNullableNonNullEnumMap:') + @SwiftFunction('callFlutterEchoNullableNonNull(enumMap:)') + Map? callFlutterEchoNullableNonNullEnumMap( + Map? enumMap); + + @async + @ObjCSelector('callFlutterEchoNullableNonNullClassMap:') + @SwiftFunction('callFlutterEchoNullableNonNull(classMap:)') + Map? callFlutterEchoNullableNonNullClassMap( + Map? classMap); @async @ObjCSelector('callFlutterEchoNullableEnum:') - @SwiftFunction('callFlutterNullableEcho(_:)') + @SwiftFunction('callFlutterEchoNullable(_:)') AnEnum? callFlutterEchoNullableEnum(AnEnum? anEnum); + @async + @ObjCSelector('callFlutterEchoAnotherNullableEnum:') + @SwiftFunction('callFlutterEchoNullable(_:)') + AnotherEnum? callFlutterEchoAnotherNullableEnum(AnotherEnum? anotherEnum); + @async @ObjCSelector('callFlutterSmallApiEchoString:') @SwiftFunction('callFlutterSmallApiEcho(_:)') @@ -738,16 +1192,83 @@ abstract class FlutterIntegrationCoreApi { @SwiftFunction('echo(_:)') List echoList(List list); + /// Returns the passed list, to test serialization and deserialization. + @ObjCSelector('echoEnumList:') + @SwiftFunction('echo(enumList:)') + List echoEnumList(List enumList); + + /// Returns the passed list, to test serialization and deserialization. + @ObjCSelector('echoClassList:') + @SwiftFunction('echo(classList:)') + List echoClassList(List classList); + + /// Returns the passed list, to test serialization and deserialization. + @ObjCSelector('echoNonNullEnumList:') + @SwiftFunction('echoNonNull(enumList:)') + List echoNonNullEnumList(List enumList); + + /// Returns the passed list, to test serialization and deserialization. + @ObjCSelector('echoNonNullClassList:') + @SwiftFunction('echoNonNull(classList:)') + List echoNonNullClassList(List classList); + /// Returns the passed map, to test serialization and deserialization. @ObjCSelector('echoMap:') @SwiftFunction('echo(_:)') - Map echoMap(Map aMap); + Map echoMap(Map map); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoStringMap:') + @SwiftFunction('echo(stringMap:)') + Map echoStringMap(Map stringMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoIntMap:') + @SwiftFunction('echo(intMap:)') + Map echoIntMap(Map intMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoEnumMap:') + @SwiftFunction('echo(enumMap:)') + Map echoEnumMap(Map enumMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoClassMap:') + @SwiftFunction('echo(classMap:)') + Map echoClassMap( + Map classMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoNonNullStringMap:') + @SwiftFunction('echoNonNull(stringMap:)') + Map echoNonNullStringMap(Map stringMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoNonNullIntMap:') + @SwiftFunction('echoNonNull(intMap:)') + Map echoNonNullIntMap(Map intMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoNonNullEnumMap:') + @SwiftFunction('echoNonNull(enumMap:)') + Map echoNonNullEnumMap(Map enumMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoNonNullClassMap:') + @SwiftFunction('echoNonNull(classMap:)') + Map echoNonNullClassMap( + Map classMap); /// Returns the passed enum to test serialization and deserialization. @ObjCSelector('echoEnum:') @SwiftFunction('echo(_:)') AnEnum echoEnum(AnEnum anEnum); + /// Returns the passed enum to test serialization and deserialization. + @ObjCSelector('echoAnotherEnum:') + @SwiftFunction('echo(_:)') + AnotherEnum echoAnotherEnum(AnotherEnum anotherEnum); + // ========== Nullable argument/return type tests ========== /// Returns the passed boolean, to test serialization and deserialization. @@ -780,16 +1301,87 @@ abstract class FlutterIntegrationCoreApi { @SwiftFunction('echoNullable(_:)') List? echoNullableList(List? list); + /// Returns the passed list, to test serialization and deserialization. + @ObjCSelector('echoNullableEnumList:') + @SwiftFunction('echoNullable(enumList:)') + List? echoNullableEnumList(List? enumList); + + /// Returns the passed list, to test serialization and deserialization. + @ObjCSelector('echoNullableClassList:') + @SwiftFunction('echoNullable(classList:)') + List? echoNullableClassList( + List? classList); + + /// Returns the passed list, to test serialization and deserialization. + @ObjCSelector('echoNullableNonNullEnumList:') + @SwiftFunction('echoNullableNonNull(enumList:)') + List? echoNullableNonNullEnumList(List? enumList); + + /// Returns the passed list, to test serialization and deserialization. + @ObjCSelector('echoNullableNonNullClassList:') + @SwiftFunction('echoNullableNonNull(classList:)') + List? echoNullableNonNullClassList( + List? classList); + /// Returns the passed map, to test serialization and deserialization. @ObjCSelector('echoNullableMap:') @SwiftFunction('echoNullable(_:)') - Map? echoNullableMap(Map? aMap); + Map? echoNullableMap(Map? map); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoNullableStringMap:') + @SwiftFunction('echoNullable(stringMap:)') + Map? echoNullableStringMap( + Map? stringMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoNullableIntMap:') + @SwiftFunction('echoNullable(intMap:)') + Map? echoNullableIntMap(Map? intMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoNullableEnumMap:') + @SwiftFunction('echoNullable(enumMap:)') + Map? echoNullableEnumMap(Map? enumMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoNullableClassMap:') + @SwiftFunction('echoNullable(classMap:)') + Map? echoNullableClassMap( + Map? classMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoNullableNonNullStringMap:') + @SwiftFunction('echoNullableNonNull(stringMap:)') + Map? echoNullableNonNullStringMap( + Map? stringMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoNullableNonNullIntMap:') + @SwiftFunction('echoNullableNonNull(intMap:)') + Map? echoNullableNonNullIntMap(Map? intMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoNullableNonNullEnumMap:') + @SwiftFunction('echoNullableNonNull(enumMap:)') + Map? echoNullableNonNullEnumMap(Map? enumMap); + + /// Returns the passed map, to test serialization and deserialization. + @ObjCSelector('echoNullableNonNullClassMap:') + @SwiftFunction('echoNullableNonNull(classMap:)') + Map? echoNullableNonNullClassMap( + Map? classMap); /// Returns the passed enum to test serialization and deserialization. @ObjCSelector('echoNullableEnum:') @SwiftFunction('echoNullable(_:)') AnEnum? echoNullableEnum(AnEnum? anEnum); + /// Returns the passed enum to test serialization and deserialization. + @ObjCSelector('echoAnotherNullableEnum:') + @SwiftFunction('echoNullable(_:)') + AnotherEnum? echoAnotherNullableEnum(AnotherEnum? anotherEnum); + // ========== Async tests ========== // These are minimal since async FlutterApi only changes Dart generation. // Currently they aren't integration tested, but having them here ensures diff --git a/packages/pigeon/pigeons/proxy_api_tests.dart b/packages/pigeon/pigeons/proxy_api_tests.dart index 699e5dfaed86..0e7bfed75ff6 100644 --- a/packages/pigeon/pigeons/proxy_api_tests.dart +++ b/packages/pigeon/pigeons/proxy_api_tests.dart @@ -455,7 +455,12 @@ abstract class ProxyApiTestClass extends ProxyApiSuperClass } /// ProxyApi to serve as a super class to the core ProxyApi class. -@ProxyApi() +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: 'com.example.test_plugin.ProxyApiSuperClass', + ), + swiftOptions: SwiftProxyApiOptions(name: 'ProxyApiSuperClass'), +) abstract class ProxyApiSuperClass { ProxyApiSuperClass(); @@ -467,3 +472,16 @@ abstract class ProxyApiSuperClass { abstract class ProxyApiInterface { late void Function()? anInterfaceMethod; } + +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions(minAndroidApi: 25), + swiftOptions: SwiftProxyApiOptions( + minIosApi: '15.0.0', + minMacosApi: '10.0.0', + ), +) +abstract class ClassWithApiRequirement { + ClassWithApiRequirement(); + + void aMethod(); +} diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/build.gradle b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/build.gradle index 4add59bacb2a..099568e3c98e 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/build.gradle +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/build.gradle @@ -22,15 +22,12 @@ rootProject.allprojects { apply plugin: 'com.android.library' android { - // Conditional for compatibility with AGP <4.2. - if (project.android.hasProperty("namespace")) { - namespace 'com.example.alternate_language_test_plugin' - } + namespace 'com.example.alternate_language_test_plugin' compileSdk 34 compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } defaultConfig { @@ -52,7 +49,7 @@ android { lintOptions { checkAllWarnings true warningsAsErrors true - disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency' + disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency', 'NewerVersionAvailable' } dependencies { diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/AlternateLanguageTestPlugin.java b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/AlternateLanguageTestPlugin.java index ef8c57873382..8580645a27d7 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/AlternateLanguageTestPlugin.java +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/AlternateLanguageTestPlugin.java @@ -11,6 +11,7 @@ import com.example.alternate_language_test_plugin.CoreTests.AllNullableTypesWithoutRecursion; import com.example.alternate_language_test_plugin.CoreTests.AllTypes; import com.example.alternate_language_test_plugin.CoreTests.AnEnum; +import com.example.alternate_language_test_plugin.CoreTests.AnotherEnum; import com.example.alternate_language_test_plugin.CoreTests.FlutterIntegrationCoreApi; import com.example.alternate_language_test_plugin.CoreTests.FlutterSmallApi; import com.example.alternate_language_test_plugin.CoreTests.HostIntegrationCoreApi; @@ -18,6 +19,8 @@ import com.example.alternate_language_test_plugin.CoreTests.Result; import com.example.alternate_language_test_plugin.CoreTests.VoidResult; import io.flutter.embedding.engine.plugins.FlutterPlugin; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -114,8 +117,76 @@ public void throwErrorFromVoid() { } @Override - public @NonNull Map echoMap(@NonNull Map aMap) { - return aMap; + public @NonNull List echoEnumList(@NonNull List enumList) { + return enumList; + } + + @Override + public @NonNull List echoClassList(@NonNull List classList) { + return classList; + } + + @NonNull + @Override + public List echoNonNullEnumList(@NonNull List enumList) { + return enumList; + } + + @NonNull + @Override + public List echoNonNullClassList(@NonNull List classList) { + return classList; + } + + @Override + public @NonNull Map echoMap(@NonNull Map map) { + return map; + } + + @Override + public @NonNull Map echoStringMap(@NonNull Map stringMap) { + return stringMap; + } + + @Override + public @NonNull Map echoIntMap(@NonNull Map intMap) { + return intMap; + } + + @Override + public @NonNull Map echoEnumMap(@NonNull Map enumMap) { + return enumMap; + } + + @Override + public @NonNull Map echoClassMap( + @NonNull Map classMap) { + return classMap; + } + + @NonNull + @Override + public Map echoNonNullStringMap(@NonNull Map stringMap) { + return stringMap; + } + + @NonNull + @Override + public Map echoNonNullIntMap(@NonNull Map intMap) { + return intMap; + } + + @NonNull + @Override + public Map echoNonNullEnumMap(@NonNull Map enumMap) { + return enumMap; + } + + @NonNull + @Override + public Map echoNonNullClassMap( + @NonNull Map classMap) { + return classMap; } @Override @@ -128,6 +199,11 @@ public void throwErrorFromVoid() { return anEnum; } + @Override + public @NonNull AnotherEnum echoAnotherEnum(@NonNull AnotherEnum anotherEnum) { + return anotherEnum; + } + @Override public @NonNull String echoNamedDefaultString(@NonNull String aString) { return aString; @@ -152,7 +228,11 @@ public void throwErrorFromVoid() { public @NonNull AllClassesWrapper createNestedNullableString(@Nullable String nullableString) { AllNullableTypes innerObject = new AllNullableTypes.Builder().setANullableString(nullableString).build(); - return new AllClassesWrapper.Builder().setAllNullableTypes(innerObject).build(); + return new AllClassesWrapper.Builder() + .setAllNullableTypes(innerObject) + .setClassList(new ArrayList()) + .setClassMap(new HashMap()) + .build(); } @Override @@ -215,8 +295,79 @@ public void throwErrorFromVoid() { } @Override - public @Nullable Map echoNullableMap(@Nullable Map aNullableMap) { - return aNullableMap; + public @Nullable List echoNullableEnumList(@Nullable List enumList) { + return enumList; + } + + @Override + public @Nullable List echoNullableClassList( + @Nullable List classList) { + return classList; + } + + @Nullable + @Override + public List echoNullableNonNullEnumList(@Nullable List enumList) { + return enumList; + } + + @Nullable + @Override + public List echoNullableNonNullClassList( + @Nullable List classList) { + return classList; + } + + @Override + public @Nullable Map echoNullableMap(@Nullable Map map) { + return map; + } + + @Override + public @Nullable Map echoNullableStringMap( + @Nullable Map stringMap) { + return stringMap; + } + + @Override + public @Nullable Map echoNullableIntMap(@Nullable Map intMap) { + return intMap; + } + + @Override + public @Nullable Map echoNullableEnumMap(@Nullable Map enumMap) { + return enumMap; + } + + @Override + public @Nullable Map echoNullableClassMap( + @Nullable Map classMap) { + return classMap; + } + + @Nullable + @Override + public Map echoNullableNonNullStringMap(@Nullable Map stringMap) { + return stringMap; + } + + @Nullable + @Override + public Map echoNullableNonNullIntMap(@Nullable Map intMap) { + return intMap; + } + + @Nullable + @Override + public Map echoNullableNonNullEnumMap(@Nullable Map enumMap) { + return enumMap; + } + + @Nullable + @Override + public Map echoNullableNonNullClassMap( + @Nullable Map classMap) { + return classMap; } @Override @@ -224,6 +375,11 @@ public void throwErrorFromVoid() { return anEnum; } + @Override + public @Nullable AnotherEnum echoAnotherNullableEnum(@Nullable AnotherEnum anotherEnum) { + return anotherEnum; + } + @Override public @Nullable Long echoOptionalNullableInt(@Nullable Long aNullableInt) { return aNullableInt; @@ -307,10 +463,47 @@ public void echoAsyncList(@NonNull List list, @NonNull Result enumList, @NonNull Result> result) { + result.success(enumList); + } + + @Override + public void echoAsyncClassList( + @NonNull List classList, @NonNull Result> result) { + result.success(classList); + } + @Override public void echoAsyncMap( - @NonNull Map aMap, @NonNull Result> result) { - result.success(aMap); + @NonNull Map map, @NonNull Result> result) { + result.success(map); + } + + @Override + public void echoAsyncStringMap( + @NonNull Map stringMap, @NonNull Result> result) { + result.success(stringMap); + } + + @Override + public void echoAsyncIntMap( + @NonNull Map intMap, @NonNull Result> result) { + result.success(intMap); + } + + @Override + public void echoAsyncEnumMap( + @NonNull Map enumMap, @NonNull Result> result) { + result.success(enumMap); + } + + @Override + public void echoAsyncClassMap( + @NonNull Map classMap, + @NonNull Result> result) { + result.success(classMap); } @Override @@ -318,6 +511,12 @@ public void echoAsyncEnum(@NonNull AnEnum anEnum, @NonNull Result result result.success(anEnum); } + @Override + public void echoAnotherAsyncEnum( + @NonNull AnotherEnum anotherEnum, @NonNull Result result) { + result.success(anotherEnum); + } + @Override public void echoAsyncNullableInt(@Nullable Long anInt, @NonNull NullableResult result) { result.success(anInt); @@ -359,10 +558,49 @@ public void echoAsyncNullableList( result.success(list); } + @Override + public void echoAsyncNullableEnumList( + @Nullable List enumList, @NonNull NullableResult> result) { + result.success(enumList); + } + + @Override + public void echoAsyncNullableClassList( + @Nullable List classList, + @NonNull NullableResult> result) { + result.success(classList); + } + @Override public void echoAsyncNullableMap( - @Nullable Map aMap, @NonNull NullableResult> result) { - result.success(aMap); + @Nullable Map map, @NonNull NullableResult> result) { + result.success(map); + } + + @Override + public void echoAsyncNullableStringMap( + @Nullable Map stringMap, + @NonNull NullableResult> result) { + result.success(stringMap); + } + + @Override + public void echoAsyncNullableIntMap( + @Nullable Map intMap, @NonNull NullableResult> result) { + result.success(intMap); + } + + @Override + public void echoAsyncNullableEnumMap( + @Nullable Map enumMap, @NonNull NullableResult> result) { + result.success(enumMap); + } + + @Override + public void echoAsyncNullableClassMap( + @Nullable Map classMap, + @NonNull NullableResult> result) { + result.success(classMap); } @Override @@ -371,6 +609,12 @@ public void echoAsyncNullableEnum( result.success(anEnum); } + @Override + public void echoAnotherAsyncNullableEnum( + @Nullable AnotherEnum anotherEnum, @NonNull NullableResult result) { + result.success(anotherEnum); + } + @Override public void callFlutterNoop(@NonNull VoidResult result) { assert flutterApi != null; @@ -469,11 +713,98 @@ public void callFlutterEchoList( flutterApi.echoList(list, result); } + @Override + public void callFlutterEchoEnumList( + @NonNull List enumList, @NonNull Result> result) { + assert flutterApi != null; + flutterApi.echoEnumList(enumList, result); + } + + @Override + public void callFlutterEchoClassList( + @NonNull List classNullableTypes, + @NonNull Result> result) { + assert flutterApi != null; + flutterApi.echoClassList(classNullableTypes, result); + } + + @Override + public void callFlutterEchoNonNullEnumList( + @NonNull List enumList, @NonNull Result> result) { + assert flutterApi != null; + flutterApi.echoNonNullEnumList(enumList, result); + } + + @Override + public void callFlutterEchoNonNullClassList( + @NonNull List classList, @NonNull Result> result) { + assert flutterApi != null; + flutterApi.echoNonNullClassList(classList, result); + } + @Override public void callFlutterEchoMap( - @NonNull Map aMap, @NonNull Result> result) { + @NonNull Map map, @NonNull Result> result) { assert flutterApi != null; - flutterApi.echoMap(aMap, result); + flutterApi.echoMap(map, result); + } + + @Override + public void callFlutterEchoStringMap( + @NonNull Map stringMap, @NonNull Result> result) { + assert flutterApi != null; + flutterApi.echoStringMap(stringMap, result); + } + + @Override + public void callFlutterEchoIntMap( + @NonNull Map intMap, @NonNull Result> result) { + assert flutterApi != null; + flutterApi.echoIntMap(intMap, result); + } + + @Override + public void callFlutterEchoEnumMap( + @NonNull Map enumMap, @NonNull Result> result) { + assert flutterApi != null; + flutterApi.echoEnumMap(enumMap, result); + } + + @Override + public void callFlutterEchoClassMap( + @NonNull Map classMap, + @NonNull Result> result) { + assert flutterApi != null; + flutterApi.echoClassMap(classMap, result); + } + + @Override + public void callFlutterEchoNonNullStringMap( + @NonNull Map stringMap, @NonNull Result> result) { + assert flutterApi != null; + flutterApi.echoNonNullStringMap(stringMap, result); + } + + @Override + public void callFlutterEchoNonNullIntMap( + @NonNull Map intMap, @NonNull Result> result) { + assert flutterApi != null; + flutterApi.echoNonNullIntMap(intMap, result); + } + + @Override + public void callFlutterEchoNonNullEnumMap( + @NonNull Map enumMap, @NonNull Result> result) { + assert flutterApi != null; + flutterApi.echoNonNullEnumMap(enumMap, result); + } + + @Override + public void callFlutterEchoNonNullClassMap( + @NonNull Map classMap, + @NonNull Result> result) { + assert flutterApi != null; + flutterApi.echoNonNullClassMap(classMap, result); } @Override @@ -482,6 +813,13 @@ public void callFlutterEchoEnum(@NonNull AnEnum anEnum, @NonNull Result flutterApi.echoEnum(anEnum, result); } + @Override + public void callFlutterEchoAnotherEnum( + @NonNull AnotherEnum anotherEnum, @NonNull Result result) { + assert flutterApi != null; + flutterApi.echoAnotherEnum(anotherEnum, result); + } + @Override public void callFlutterEchoNullableBool( @Nullable Boolean aBool, @NonNull NullableResult result) { @@ -524,11 +862,102 @@ public void callFlutterEchoNullableList( flutterApi.echoNullableList(list, result); } + @Override + public void callFlutterEchoNullableEnumList( + @Nullable List enumList, @NonNull NullableResult> result) { + assert flutterApi != null; + flutterApi.echoNullableEnumList(enumList, result); + } + + @Override + public void callFlutterEchoNullableClassList( + @Nullable List classList, + @NonNull NullableResult> result) { + assert flutterApi != null; + flutterApi.echoNullableClassList(classList, result); + } + + @Override + public void callFlutterEchoNullableNonNullEnumList( + @Nullable List enumList, @NonNull NullableResult> result) { + assert flutterApi != null; + flutterApi.echoNullableNonNullEnumList(enumList, result); + } + + @Override + public void callFlutterEchoNullableNonNullClassList( + @Nullable List classList, + @NonNull NullableResult> result) { + assert flutterApi != null; + flutterApi.echoNullableNonNullClassList(classList, result); + } + @Override public void callFlutterEchoNullableMap( - @Nullable Map aMap, @NonNull NullableResult> result) { + @Nullable Map map, @NonNull NullableResult> result) { + assert flutterApi != null; + flutterApi.echoNullableMap(map, result); + } + + @Override + public void callFlutterEchoNullableStringMap( + @Nullable Map stringMap, + @NonNull NullableResult> result) { assert flutterApi != null; - flutterApi.echoNullableMap(aMap, result); + flutterApi.echoNullableStringMap(stringMap, result); + } + + @Override + public void callFlutterEchoNullableIntMap( + @Nullable Map intMap, @NonNull NullableResult> result) { + assert flutterApi != null; + flutterApi.echoNullableIntMap(intMap, result); + } + + @Override + public void callFlutterEchoNullableEnumMap( + @Nullable Map enumMap, @NonNull NullableResult> result) { + assert flutterApi != null; + flutterApi.echoNullableEnumMap(enumMap, result); + } + + @Override + public void callFlutterEchoNullableClassMap( + @Nullable Map classMap, + @NonNull NullableResult> result) { + assert flutterApi != null; + flutterApi.echoNullableClassMap(classMap, result); + } + + @Override + public void callFlutterEchoNullableNonNullStringMap( + @Nullable Map stringMap, + @NonNull NullableResult> result) { + + assert flutterApi != null; + flutterApi.echoNullableNonNullStringMap(stringMap, result); + } + + @Override + public void callFlutterEchoNullableNonNullIntMap( + @Nullable Map intMap, @NonNull NullableResult> result) { + assert flutterApi != null; + flutterApi.echoNullableNonNullIntMap(intMap, result); + } + + @Override + public void callFlutterEchoNullableNonNullEnumMap( + @Nullable Map enumMap, @NonNull NullableResult> result) { + assert flutterApi != null; + flutterApi.echoNullableNonNullEnumMap(enumMap, result); + } + + @Override + public void callFlutterEchoNullableNonNullClassMap( + @Nullable Map classMap, + @NonNull NullableResult> result) { + assert flutterApi != null; + flutterApi.echoNullableNonNullClassMap(classMap, result); } @Override @@ -538,6 +967,13 @@ public void callFlutterEchoNullableEnum( flutterApi.echoNullableEnum(anEnum, result); } + @Override + public void callFlutterEchoAnotherNullableEnum( + @Nullable AnotherEnum anotherEnum, @NonNull NullableResult result) { + assert flutterApi != null; + flutterApi.echoAnotherNullableEnum(anotherEnum, result); + } + @Override public void callFlutterSmallApiEchoString( @NonNull String aString, @NonNull Result result) { @@ -576,6 +1012,10 @@ public void error(Throwable error) { }; flutterSmallApiOne.echoString(aString, resultCallbackOne); } + + public @NonNull CoreTests.UnusedClass testIfUnusedClassIsGenerated() { + return new CoreTests.UnusedClass(); + } } class TestPluginWithSuffix implements CoreTests.HostSmallApi { diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java index d0b5b600836f..4707969aab13 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java @@ -26,6 +26,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Objects; /** Generated class from Pigeon. */ @SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression", "serial"}) @@ -49,7 +50,7 @@ public FlutterError(@NonNull String code, @Nullable String message, @Nullable Ob @NonNull protected static ArrayList wrapError(@NonNull Throwable exception) { - ArrayList errorList = new ArrayList(3); + ArrayList errorList = new ArrayList<>(3); if (exception instanceof FlutterError) { FlutterError error = (FlutterError) exception; errorList.add(error.code); @@ -83,11 +84,82 @@ public enum AnEnum { final int index; - private AnEnum(final int index) { + AnEnum(final int index) { this.index = index; } } + public enum AnotherEnum { + JUST_IN_CASE(0); + + final int index; + + AnotherEnum(final int index) { + this.index = index; + } + } + + /** Generated class from Pigeon that represents data sent in messages. */ + public static final class UnusedClass { + private @Nullable Object aField; + + public @Nullable Object getAField() { + return aField; + } + + public void setAField(@Nullable Object setterArg) { + this.aField = setterArg; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UnusedClass that = (UnusedClass) o; + return Objects.equals(aField, that.aField); + } + + @Override + public int hashCode() { + return Objects.hash(aField); + } + + public static final class Builder { + + private @Nullable Object aField; + + @CanIgnoreReturnValue + public @NonNull Builder setAField(@Nullable Object setterArg) { + this.aField = setterArg; + return this; + } + + public @NonNull UnusedClass build() { + UnusedClass pigeonReturn = new UnusedClass(); + pigeonReturn.setAField(aField); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList<>(1); + toListResult.add(aField); + return toListResult; + } + + static @NonNull UnusedClass fromList(@NonNull ArrayList pigeonVar_list) { + UnusedClass pigeonResult = new UnusedClass(); + Object aField = pigeonVar_list.get(0); + pigeonResult.setAField(aField); + return pigeonResult; + } + } + /** * A class containing all supported types. * @@ -211,6 +283,19 @@ public void setAnEnum(@NonNull AnEnum setterArg) { this.anEnum = setterArg; } + private @NonNull AnotherEnum anotherEnum; + + public @NonNull AnotherEnum getAnotherEnum() { + return anotherEnum; + } + + public void setAnotherEnum(@NonNull AnotherEnum setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"anotherEnum\" is null."); + } + this.anotherEnum = setterArg; + } + private @NonNull String aString; public @NonNull String getAString() { @@ -302,6 +387,58 @@ public void setBoolList(@NonNull List setterArg) { this.boolList = setterArg; } + private @NonNull List enumList; + + public @NonNull List getEnumList() { + return enumList; + } + + public void setEnumList(@NonNull List setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"enumList\" is null."); + } + this.enumList = setterArg; + } + + private @NonNull List objectList; + + public @NonNull List getObjectList() { + return objectList; + } + + public void setObjectList(@NonNull List setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"objectList\" is null."); + } + this.objectList = setterArg; + } + + private @NonNull List> listList; + + public @NonNull List> getListList() { + return listList; + } + + public void setListList(@NonNull List> setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"listList\" is null."); + } + this.listList = setterArg; + } + + private @NonNull List> mapList; + + public @NonNull List> getMapList() { + return mapList; + } + + public void setMapList(@NonNull List> setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"mapList\" is null."); + } + this.mapList = setterArg; + } + private @NonNull Map map; public @NonNull Map getMap() { @@ -315,9 +452,161 @@ public void setMap(@NonNull Map setterArg) { this.map = setterArg; } + private @NonNull Map stringMap; + + public @NonNull Map getStringMap() { + return stringMap; + } + + public void setStringMap(@NonNull Map setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"stringMap\" is null."); + } + this.stringMap = setterArg; + } + + private @NonNull Map intMap; + + public @NonNull Map getIntMap() { + return intMap; + } + + public void setIntMap(@NonNull Map setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"intMap\" is null."); + } + this.intMap = setterArg; + } + + private @NonNull Map enumMap; + + public @NonNull Map getEnumMap() { + return enumMap; + } + + public void setEnumMap(@NonNull Map setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"enumMap\" is null."); + } + this.enumMap = setterArg; + } + + private @NonNull Map objectMap; + + public @NonNull Map getObjectMap() { + return objectMap; + } + + public void setObjectMap(@NonNull Map setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"objectMap\" is null."); + } + this.objectMap = setterArg; + } + + private @NonNull Map> listMap; + + public @NonNull Map> getListMap() { + return listMap; + } + + public void setListMap(@NonNull Map> setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"listMap\" is null."); + } + this.listMap = setterArg; + } + + private @NonNull Map> mapMap; + + public @NonNull Map> getMapMap() { + return mapMap; + } + + public void setMapMap(@NonNull Map> setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"mapMap\" is null."); + } + this.mapMap = setterArg; + } + /** Constructor is non-public to enforce null safety; use Builder. */ AllTypes() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AllTypes that = (AllTypes) o; + return aBool.equals(that.aBool) + && anInt.equals(that.anInt) + && anInt64.equals(that.anInt64) + && aDouble.equals(that.aDouble) + && Arrays.equals(aByteArray, that.aByteArray) + && Arrays.equals(a4ByteArray, that.a4ByteArray) + && Arrays.equals(a8ByteArray, that.a8ByteArray) + && Arrays.equals(aFloatArray, that.aFloatArray) + && anEnum.equals(that.anEnum) + && anotherEnum.equals(that.anotherEnum) + && aString.equals(that.aString) + && anObject.equals(that.anObject) + && list.equals(that.list) + && stringList.equals(that.stringList) + && intList.equals(that.intList) + && doubleList.equals(that.doubleList) + && boolList.equals(that.boolList) + && enumList.equals(that.enumList) + && objectList.equals(that.objectList) + && listList.equals(that.listList) + && mapList.equals(that.mapList) + && map.equals(that.map) + && stringMap.equals(that.stringMap) + && intMap.equals(that.intMap) + && enumMap.equals(that.enumMap) + && objectMap.equals(that.objectMap) + && listMap.equals(that.listMap) + && mapMap.equals(that.mapMap); + } + + @Override + public int hashCode() { + int pigeonVar_result = + Objects.hash( + aBool, + anInt, + anInt64, + aDouble, + anEnum, + anotherEnum, + aString, + anObject, + list, + stringList, + intList, + doubleList, + boolList, + enumList, + objectList, + listList, + mapList, + map, + stringMap, + intMap, + enumMap, + objectMap, + listMap, + mapMap); + pigeonVar_result = 31 * pigeonVar_result + Arrays.hashCode(aByteArray); + pigeonVar_result = 31 * pigeonVar_result + Arrays.hashCode(a4ByteArray); + pigeonVar_result = 31 * pigeonVar_result + Arrays.hashCode(a8ByteArray); + pigeonVar_result = 31 * pigeonVar_result + Arrays.hashCode(aFloatArray); + return pigeonVar_result; + } + public static final class Builder { private @Nullable Boolean aBool; @@ -392,6 +681,14 @@ public static final class Builder { return this; } + private @Nullable AnotherEnum anotherEnum; + + @CanIgnoreReturnValue + public @NonNull Builder setAnotherEnum(@NonNull AnotherEnum setterArg) { + this.anotherEnum = setterArg; + return this; + } + private @Nullable String aString; @CanIgnoreReturnValue @@ -448,6 +745,38 @@ public static final class Builder { return this; } + private @Nullable List enumList; + + @CanIgnoreReturnValue + public @NonNull Builder setEnumList(@NonNull List setterArg) { + this.enumList = setterArg; + return this; + } + + private @Nullable List objectList; + + @CanIgnoreReturnValue + public @NonNull Builder setObjectList(@NonNull List setterArg) { + this.objectList = setterArg; + return this; + } + + private @Nullable List> listList; + + @CanIgnoreReturnValue + public @NonNull Builder setListList(@NonNull List> setterArg) { + this.listList = setterArg; + return this; + } + + private @Nullable List> mapList; + + @CanIgnoreReturnValue + public @NonNull Builder setMapList(@NonNull List> setterArg) { + this.mapList = setterArg; + return this; + } + private @Nullable Map map; @CanIgnoreReturnValue @@ -456,6 +785,54 @@ public static final class Builder { return this; } + private @Nullable Map stringMap; + + @CanIgnoreReturnValue + public @NonNull Builder setStringMap(@NonNull Map setterArg) { + this.stringMap = setterArg; + return this; + } + + private @Nullable Map intMap; + + @CanIgnoreReturnValue + public @NonNull Builder setIntMap(@NonNull Map setterArg) { + this.intMap = setterArg; + return this; + } + + private @Nullable Map enumMap; + + @CanIgnoreReturnValue + public @NonNull Builder setEnumMap(@NonNull Map setterArg) { + this.enumMap = setterArg; + return this; + } + + private @Nullable Map objectMap; + + @CanIgnoreReturnValue + public @NonNull Builder setObjectMap(@NonNull Map setterArg) { + this.objectMap = setterArg; + return this; + } + + private @Nullable Map> listMap; + + @CanIgnoreReturnValue + public @NonNull Builder setListMap(@NonNull Map> setterArg) { + this.listMap = setterArg; + return this; + } + + private @Nullable Map> mapMap; + + @CanIgnoreReturnValue + public @NonNull Builder setMapMap(@NonNull Map> setterArg) { + this.mapMap = setterArg; + return this; + } + public @NonNull AllTypes build() { AllTypes pigeonReturn = new AllTypes(); pigeonReturn.setABool(aBool); @@ -467,6 +844,7 @@ public static final class Builder { pigeonReturn.setA8ByteArray(a8ByteArray); pigeonReturn.setAFloatArray(aFloatArray); pigeonReturn.setAnEnum(anEnum); + pigeonReturn.setAnotherEnum(anotherEnum); pigeonReturn.setAString(aString); pigeonReturn.setAnObject(anObject); pigeonReturn.setList(list); @@ -474,14 +852,24 @@ public static final class Builder { pigeonReturn.setIntList(intList); pigeonReturn.setDoubleList(doubleList); pigeonReturn.setBoolList(boolList); + pigeonReturn.setEnumList(enumList); + pigeonReturn.setObjectList(objectList); + pigeonReturn.setListList(listList); + pigeonReturn.setMapList(mapList); pigeonReturn.setMap(map); + pigeonReturn.setStringMap(stringMap); + pigeonReturn.setIntMap(intMap); + pigeonReturn.setEnumMap(enumMap); + pigeonReturn.setObjectMap(objectMap); + pigeonReturn.setListMap(listMap); + pigeonReturn.setMapMap(mapMap); return pigeonReturn; } } @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(17); + ArrayList toListResult = new ArrayList<>(28); toListResult.add(aBool); toListResult.add(anInt); toListResult.add(anInt64); @@ -491,6 +879,7 @@ ArrayList toList() { toListResult.add(a8ByteArray); toListResult.add(aFloatArray); toListResult.add(anEnum); + toListResult.add(anotherEnum); toListResult.add(aString); toListResult.add(anObject); toListResult.add(list); @@ -498,50 +887,78 @@ ArrayList toList() { toListResult.add(intList); toListResult.add(doubleList); toListResult.add(boolList); + toListResult.add(enumList); + toListResult.add(objectList); + toListResult.add(listList); + toListResult.add(mapList); toListResult.add(map); + toListResult.add(stringMap); + toListResult.add(intMap); + toListResult.add(enumMap); + toListResult.add(objectMap); + toListResult.add(listMap); + toListResult.add(mapMap); return toListResult; } - static @NonNull AllTypes fromList(@NonNull ArrayList __pigeon_list) { + static @NonNull AllTypes fromList(@NonNull ArrayList pigeonVar_list) { AllTypes pigeonResult = new AllTypes(); - Object aBool = __pigeon_list.get(0); + Object aBool = pigeonVar_list.get(0); pigeonResult.setABool((Boolean) aBool); - Object anInt = __pigeon_list.get(1); - pigeonResult.setAnInt( - (anInt == null) ? null : ((anInt instanceof Integer) ? (Integer) anInt : (Long) anInt)); - Object anInt64 = __pigeon_list.get(2); - pigeonResult.setAnInt64( - (anInt64 == null) - ? null - : ((anInt64 instanceof Integer) ? (Integer) anInt64 : (Long) anInt64)); - Object aDouble = __pigeon_list.get(3); + Object anInt = pigeonVar_list.get(1); + pigeonResult.setAnInt((Long) anInt); + Object anInt64 = pigeonVar_list.get(2); + pigeonResult.setAnInt64((Long) anInt64); + Object aDouble = pigeonVar_list.get(3); pigeonResult.setADouble((Double) aDouble); - Object aByteArray = __pigeon_list.get(4); + Object aByteArray = pigeonVar_list.get(4); pigeonResult.setAByteArray((byte[]) aByteArray); - Object a4ByteArray = __pigeon_list.get(5); + Object a4ByteArray = pigeonVar_list.get(5); pigeonResult.setA4ByteArray((int[]) a4ByteArray); - Object a8ByteArray = __pigeon_list.get(6); + Object a8ByteArray = pigeonVar_list.get(6); pigeonResult.setA8ByteArray((long[]) a8ByteArray); - Object aFloatArray = __pigeon_list.get(7); + Object aFloatArray = pigeonVar_list.get(7); pigeonResult.setAFloatArray((double[]) aFloatArray); - Object anEnum = __pigeon_list.get(8); + Object anEnum = pigeonVar_list.get(8); pigeonResult.setAnEnum((AnEnum) anEnum); - Object aString = __pigeon_list.get(9); + Object anotherEnum = pigeonVar_list.get(9); + pigeonResult.setAnotherEnum((AnotherEnum) anotherEnum); + Object aString = pigeonVar_list.get(10); pigeonResult.setAString((String) aString); - Object anObject = __pigeon_list.get(10); + Object anObject = pigeonVar_list.get(11); pigeonResult.setAnObject(anObject); - Object list = __pigeon_list.get(11); + Object list = pigeonVar_list.get(12); pigeonResult.setList((List) list); - Object stringList = __pigeon_list.get(12); + Object stringList = pigeonVar_list.get(13); pigeonResult.setStringList((List) stringList); - Object intList = __pigeon_list.get(13); + Object intList = pigeonVar_list.get(14); pigeonResult.setIntList((List) intList); - Object doubleList = __pigeon_list.get(14); + Object doubleList = pigeonVar_list.get(15); pigeonResult.setDoubleList((List) doubleList); - Object boolList = __pigeon_list.get(15); + Object boolList = pigeonVar_list.get(16); pigeonResult.setBoolList((List) boolList); - Object map = __pigeon_list.get(16); + Object enumList = pigeonVar_list.get(17); + pigeonResult.setEnumList((List) enumList); + Object objectList = pigeonVar_list.get(18); + pigeonResult.setObjectList((List) objectList); + Object listList = pigeonVar_list.get(19); + pigeonResult.setListList((List>) listList); + Object mapList = pigeonVar_list.get(20); + pigeonResult.setMapList((List>) mapList); + Object map = pigeonVar_list.get(21); pigeonResult.setMap((Map) map); + Object stringMap = pigeonVar_list.get(22); + pigeonResult.setStringMap((Map) stringMap); + Object intMap = pigeonVar_list.get(23); + pigeonResult.setIntMap((Map) intMap); + Object enumMap = pigeonVar_list.get(24); + pigeonResult.setEnumMap((Map) enumMap); + Object objectMap = pigeonVar_list.get(25); + pigeonResult.setObjectMap((Map) objectMap); + Object listMap = pigeonVar_list.get(26); + pigeonResult.setListMap((Map>) listMap); + Object mapMap = pigeonVar_list.get(27); + pigeonResult.setMapMap((Map>) mapMap); return pigeonResult; } } @@ -632,36 +1049,6 @@ public void setANullableFloatArray(@Nullable double[] setterArg) { this.aNullableFloatArray = setterArg; } - private @Nullable List> nullableNestedList; - - public @Nullable List> getNullableNestedList() { - return nullableNestedList; - } - - public void setNullableNestedList(@Nullable List> setterArg) { - this.nullableNestedList = setterArg; - } - - private @Nullable Map nullableMapWithAnnotations; - - public @Nullable Map getNullableMapWithAnnotations() { - return nullableMapWithAnnotations; - } - - public void setNullableMapWithAnnotations(@Nullable Map setterArg) { - this.nullableMapWithAnnotations = setterArg; - } - - private @Nullable Map nullableMapWithObject; - - public @Nullable Map getNullableMapWithObject() { - return nullableMapWithObject; - } - - public void setNullableMapWithObject(@Nullable Map setterArg) { - this.nullableMapWithObject = setterArg; - } - private @Nullable AnEnum aNullableEnum; public @Nullable AnEnum getANullableEnum() { @@ -672,6 +1059,16 @@ public void setANullableEnum(@Nullable AnEnum setterArg) { this.aNullableEnum = setterArg; } + private @Nullable AnotherEnum anotherNullableEnum; + + public @Nullable AnotherEnum getAnotherNullableEnum() { + return anotherNullableEnum; + } + + public void setAnotherNullableEnum(@Nullable AnotherEnum setterArg) { + this.anotherNullableEnum = setterArg; + } + private @Nullable String aNullableString; public @Nullable String getANullableString() { @@ -752,14 +1149,54 @@ public void setBoolList(@Nullable List setterArg) { this.boolList = setterArg; } - private @Nullable List nestedClassList; + private @Nullable List enumList; + + public @Nullable List getEnumList() { + return enumList; + } + + public void setEnumList(@Nullable List setterArg) { + this.enumList = setterArg; + } + + private @Nullable List objectList; + + public @Nullable List getObjectList() { + return objectList; + } + + public void setObjectList(@Nullable List setterArg) { + this.objectList = setterArg; + } + + private @Nullable List> listList; - public @Nullable List getNestedClassList() { - return nestedClassList; + public @Nullable List> getListList() { + return listList; } - public void setNestedClassList(@Nullable List setterArg) { - this.nestedClassList = setterArg; + public void setListList(@Nullable List> setterArg) { + this.listList = setterArg; + } + + private @Nullable List> mapList; + + public @Nullable List> getMapList() { + return mapList; + } + + public void setMapList(@Nullable List> setterArg) { + this.mapList = setterArg; + } + + private @Nullable List recursiveClassList; + + public @Nullable List getRecursiveClassList() { + return recursiveClassList; + } + + public void setRecursiveClassList(@Nullable List setterArg) { + this.recursiveClassList = setterArg; } private @Nullable Map map; @@ -772,94 +1209,219 @@ public void setMap(@Nullable Map setterArg) { this.map = setterArg; } - public static final class Builder { + private @Nullable Map stringMap; - private @Nullable Boolean aNullableBool; + public @Nullable Map getStringMap() { + return stringMap; + } - @CanIgnoreReturnValue - public @NonNull Builder setANullableBool(@Nullable Boolean setterArg) { - this.aNullableBool = setterArg; - return this; - } + public void setStringMap(@Nullable Map setterArg) { + this.stringMap = setterArg; + } - private @Nullable Long aNullableInt; + private @Nullable Map intMap; - @CanIgnoreReturnValue - public @NonNull Builder setANullableInt(@Nullable Long setterArg) { - this.aNullableInt = setterArg; - return this; - } + public @Nullable Map getIntMap() { + return intMap; + } - private @Nullable Long aNullableInt64; + public void setIntMap(@Nullable Map setterArg) { + this.intMap = setterArg; + } - @CanIgnoreReturnValue - public @NonNull Builder setANullableInt64(@Nullable Long setterArg) { - this.aNullableInt64 = setterArg; - return this; - } + private @Nullable Map enumMap; - private @Nullable Double aNullableDouble; + public @Nullable Map getEnumMap() { + return enumMap; + } - @CanIgnoreReturnValue - public @NonNull Builder setANullableDouble(@Nullable Double setterArg) { - this.aNullableDouble = setterArg; - return this; - } + public void setEnumMap(@Nullable Map setterArg) { + this.enumMap = setterArg; + } - private @Nullable byte[] aNullableByteArray; + private @Nullable Map objectMap; - @CanIgnoreReturnValue - public @NonNull Builder setANullableByteArray(@Nullable byte[] setterArg) { - this.aNullableByteArray = setterArg; - return this; - } + public @Nullable Map getObjectMap() { + return objectMap; + } - private @Nullable int[] aNullable4ByteArray; + public void setObjectMap(@Nullable Map setterArg) { + this.objectMap = setterArg; + } + + private @Nullable Map> listMap; + + public @Nullable Map> getListMap() { + return listMap; + } + + public void setListMap(@Nullable Map> setterArg) { + this.listMap = setterArg; + } + + private @Nullable Map> mapMap; + + public @Nullable Map> getMapMap() { + return mapMap; + } + + public void setMapMap(@Nullable Map> setterArg) { + this.mapMap = setterArg; + } + + private @Nullable Map recursiveClassMap; + + public @Nullable Map getRecursiveClassMap() { + return recursiveClassMap; + } + + public void setRecursiveClassMap(@Nullable Map setterArg) { + this.recursiveClassMap = setterArg; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AllNullableTypes that = (AllNullableTypes) o; + return Objects.equals(aNullableBool, that.aNullableBool) + && Objects.equals(aNullableInt, that.aNullableInt) + && Objects.equals(aNullableInt64, that.aNullableInt64) + && Objects.equals(aNullableDouble, that.aNullableDouble) + && Arrays.equals(aNullableByteArray, that.aNullableByteArray) + && Arrays.equals(aNullable4ByteArray, that.aNullable4ByteArray) + && Arrays.equals(aNullable8ByteArray, that.aNullable8ByteArray) + && Arrays.equals(aNullableFloatArray, that.aNullableFloatArray) + && Objects.equals(aNullableEnum, that.aNullableEnum) + && Objects.equals(anotherNullableEnum, that.anotherNullableEnum) + && Objects.equals(aNullableString, that.aNullableString) + && Objects.equals(aNullableObject, that.aNullableObject) + && Objects.equals(allNullableTypes, that.allNullableTypes) + && Objects.equals(list, that.list) + && Objects.equals(stringList, that.stringList) + && Objects.equals(intList, that.intList) + && Objects.equals(doubleList, that.doubleList) + && Objects.equals(boolList, that.boolList) + && Objects.equals(enumList, that.enumList) + && Objects.equals(objectList, that.objectList) + && Objects.equals(listList, that.listList) + && Objects.equals(mapList, that.mapList) + && Objects.equals(recursiveClassList, that.recursiveClassList) + && Objects.equals(map, that.map) + && Objects.equals(stringMap, that.stringMap) + && Objects.equals(intMap, that.intMap) + && Objects.equals(enumMap, that.enumMap) + && Objects.equals(objectMap, that.objectMap) + && Objects.equals(listMap, that.listMap) + && Objects.equals(mapMap, that.mapMap) + && Objects.equals(recursiveClassMap, that.recursiveClassMap); + } + + @Override + public int hashCode() { + int pigeonVar_result = + Objects.hash( + aNullableBool, + aNullableInt, + aNullableInt64, + aNullableDouble, + aNullableEnum, + anotherNullableEnum, + aNullableString, + aNullableObject, + allNullableTypes, + list, + stringList, + intList, + doubleList, + boolList, + enumList, + objectList, + listList, + mapList, + recursiveClassList, + map, + stringMap, + intMap, + enumMap, + objectMap, + listMap, + mapMap, + recursiveClassMap); + pigeonVar_result = 31 * pigeonVar_result + Arrays.hashCode(aNullableByteArray); + pigeonVar_result = 31 * pigeonVar_result + Arrays.hashCode(aNullable4ByteArray); + pigeonVar_result = 31 * pigeonVar_result + Arrays.hashCode(aNullable8ByteArray); + pigeonVar_result = 31 * pigeonVar_result + Arrays.hashCode(aNullableFloatArray); + return pigeonVar_result; + } + + public static final class Builder { + + private @Nullable Boolean aNullableBool; @CanIgnoreReturnValue - public @NonNull Builder setANullable4ByteArray(@Nullable int[] setterArg) { - this.aNullable4ByteArray = setterArg; + public @NonNull Builder setANullableBool(@Nullable Boolean setterArg) { + this.aNullableBool = setterArg; return this; } - private @Nullable long[] aNullable8ByteArray; + private @Nullable Long aNullableInt; @CanIgnoreReturnValue - public @NonNull Builder setANullable8ByteArray(@Nullable long[] setterArg) { - this.aNullable8ByteArray = setterArg; + public @NonNull Builder setANullableInt(@Nullable Long setterArg) { + this.aNullableInt = setterArg; return this; } - private @Nullable double[] aNullableFloatArray; + private @Nullable Long aNullableInt64; @CanIgnoreReturnValue - public @NonNull Builder setANullableFloatArray(@Nullable double[] setterArg) { - this.aNullableFloatArray = setterArg; + public @NonNull Builder setANullableInt64(@Nullable Long setterArg) { + this.aNullableInt64 = setterArg; + return this; + } + + private @Nullable Double aNullableDouble; + + @CanIgnoreReturnValue + public @NonNull Builder setANullableDouble(@Nullable Double setterArg) { + this.aNullableDouble = setterArg; + return this; + } + + private @Nullable byte[] aNullableByteArray; + + @CanIgnoreReturnValue + public @NonNull Builder setANullableByteArray(@Nullable byte[] setterArg) { + this.aNullableByteArray = setterArg; return this; } - private @Nullable List> nullableNestedList; + private @Nullable int[] aNullable4ByteArray; @CanIgnoreReturnValue - public @NonNull Builder setNullableNestedList(@Nullable List> setterArg) { - this.nullableNestedList = setterArg; + public @NonNull Builder setANullable4ByteArray(@Nullable int[] setterArg) { + this.aNullable4ByteArray = setterArg; return this; } - private @Nullable Map nullableMapWithAnnotations; + private @Nullable long[] aNullable8ByteArray; @CanIgnoreReturnValue - public @NonNull Builder setNullableMapWithAnnotations( - @Nullable Map setterArg) { - this.nullableMapWithAnnotations = setterArg; + public @NonNull Builder setANullable8ByteArray(@Nullable long[] setterArg) { + this.aNullable8ByteArray = setterArg; return this; } - private @Nullable Map nullableMapWithObject; + private @Nullable double[] aNullableFloatArray; @CanIgnoreReturnValue - public @NonNull Builder setNullableMapWithObject(@Nullable Map setterArg) { - this.nullableMapWithObject = setterArg; + public @NonNull Builder setANullableFloatArray(@Nullable double[] setterArg) { + this.aNullableFloatArray = setterArg; return this; } @@ -871,6 +1433,14 @@ public static final class Builder { return this; } + private @Nullable AnotherEnum anotherNullableEnum; + + @CanIgnoreReturnValue + public @NonNull Builder setAnotherNullableEnum(@Nullable AnotherEnum setterArg) { + this.anotherNullableEnum = setterArg; + return this; + } + private @Nullable String aNullableString; @CanIgnoreReturnValue @@ -935,11 +1505,43 @@ public static final class Builder { return this; } - private @Nullable List nestedClassList; + private @Nullable List enumList; + + @CanIgnoreReturnValue + public @NonNull Builder setEnumList(@Nullable List setterArg) { + this.enumList = setterArg; + return this; + } + + private @Nullable List objectList; + + @CanIgnoreReturnValue + public @NonNull Builder setObjectList(@Nullable List setterArg) { + this.objectList = setterArg; + return this; + } + + private @Nullable List> listList; + + @CanIgnoreReturnValue + public @NonNull Builder setListList(@Nullable List> setterArg) { + this.listList = setterArg; + return this; + } + + private @Nullable List> mapList; @CanIgnoreReturnValue - public @NonNull Builder setNestedClassList(@Nullable List setterArg) { - this.nestedClassList = setterArg; + public @NonNull Builder setMapList(@Nullable List> setterArg) { + this.mapList = setterArg; + return this; + } + + private @Nullable List recursiveClassList; + + @CanIgnoreReturnValue + public @NonNull Builder setRecursiveClassList(@Nullable List setterArg) { + this.recursiveClassList = setterArg; return this; } @@ -951,6 +1553,63 @@ public static final class Builder { return this; } + private @Nullable Map stringMap; + + @CanIgnoreReturnValue + public @NonNull Builder setStringMap(@Nullable Map setterArg) { + this.stringMap = setterArg; + return this; + } + + private @Nullable Map intMap; + + @CanIgnoreReturnValue + public @NonNull Builder setIntMap(@Nullable Map setterArg) { + this.intMap = setterArg; + return this; + } + + private @Nullable Map enumMap; + + @CanIgnoreReturnValue + public @NonNull Builder setEnumMap(@Nullable Map setterArg) { + this.enumMap = setterArg; + return this; + } + + private @Nullable Map objectMap; + + @CanIgnoreReturnValue + public @NonNull Builder setObjectMap(@Nullable Map setterArg) { + this.objectMap = setterArg; + return this; + } + + private @Nullable Map> listMap; + + @CanIgnoreReturnValue + public @NonNull Builder setListMap(@Nullable Map> setterArg) { + this.listMap = setterArg; + return this; + } + + private @Nullable Map> mapMap; + + @CanIgnoreReturnValue + public @NonNull Builder setMapMap(@Nullable Map> setterArg) { + this.mapMap = setterArg; + return this; + } + + private @Nullable Map recursiveClassMap; + + @CanIgnoreReturnValue + public @NonNull Builder setRecursiveClassMap( + @Nullable Map setterArg) { + this.recursiveClassMap = setterArg; + return this; + } + public @NonNull AllNullableTypes build() { AllNullableTypes pigeonReturn = new AllNullableTypes(); pigeonReturn.setANullableBool(aNullableBool); @@ -961,10 +1620,8 @@ public static final class Builder { pigeonReturn.setANullable4ByteArray(aNullable4ByteArray); pigeonReturn.setANullable8ByteArray(aNullable8ByteArray); pigeonReturn.setANullableFloatArray(aNullableFloatArray); - pigeonReturn.setNullableNestedList(nullableNestedList); - pigeonReturn.setNullableMapWithAnnotations(nullableMapWithAnnotations); - pigeonReturn.setNullableMapWithObject(nullableMapWithObject); pigeonReturn.setANullableEnum(aNullableEnum); + pigeonReturn.setAnotherNullableEnum(anotherNullableEnum); pigeonReturn.setANullableString(aNullableString); pigeonReturn.setANullableObject(aNullableObject); pigeonReturn.setAllNullableTypes(allNullableTypes); @@ -973,15 +1630,26 @@ public static final class Builder { pigeonReturn.setIntList(intList); pigeonReturn.setDoubleList(doubleList); pigeonReturn.setBoolList(boolList); - pigeonReturn.setNestedClassList(nestedClassList); + pigeonReturn.setEnumList(enumList); + pigeonReturn.setObjectList(objectList); + pigeonReturn.setListList(listList); + pigeonReturn.setMapList(mapList); + pigeonReturn.setRecursiveClassList(recursiveClassList); pigeonReturn.setMap(map); + pigeonReturn.setStringMap(stringMap); + pigeonReturn.setIntMap(intMap); + pigeonReturn.setEnumMap(enumMap); + pigeonReturn.setObjectMap(objectMap); + pigeonReturn.setListMap(listMap); + pigeonReturn.setMapMap(mapMap); + pigeonReturn.setRecursiveClassMap(recursiveClassMap); return pigeonReturn; } } @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(22); + ArrayList toListResult = new ArrayList<>(31); toListResult.add(aNullableBool); toListResult.add(aNullableInt); toListResult.add(aNullableInt64); @@ -990,10 +1658,8 @@ ArrayList toList() { toListResult.add(aNullable4ByteArray); toListResult.add(aNullable8ByteArray); toListResult.add(aNullableFloatArray); - toListResult.add(nullableNestedList); - toListResult.add(nullableMapWithAnnotations); - toListResult.add(nullableMapWithObject); toListResult.add(aNullableEnum); + toListResult.add(anotherNullableEnum); toListResult.add(aNullableString); toListResult.add(aNullableObject); toListResult.add(allNullableTypes); @@ -1002,65 +1668,86 @@ ArrayList toList() { toListResult.add(intList); toListResult.add(doubleList); toListResult.add(boolList); - toListResult.add(nestedClassList); + toListResult.add(enumList); + toListResult.add(objectList); + toListResult.add(listList); + toListResult.add(mapList); + toListResult.add(recursiveClassList); toListResult.add(map); + toListResult.add(stringMap); + toListResult.add(intMap); + toListResult.add(enumMap); + toListResult.add(objectMap); + toListResult.add(listMap); + toListResult.add(mapMap); + toListResult.add(recursiveClassMap); return toListResult; } - static @NonNull AllNullableTypes fromList(@NonNull ArrayList __pigeon_list) { + static @NonNull AllNullableTypes fromList(@NonNull ArrayList pigeonVar_list) { AllNullableTypes pigeonResult = new AllNullableTypes(); - Object aNullableBool = __pigeon_list.get(0); + Object aNullableBool = pigeonVar_list.get(0); pigeonResult.setANullableBool((Boolean) aNullableBool); - Object aNullableInt = __pigeon_list.get(1); - pigeonResult.setANullableInt( - (aNullableInt == null) - ? null - : ((aNullableInt instanceof Integer) ? (Integer) aNullableInt : (Long) aNullableInt)); - Object aNullableInt64 = __pigeon_list.get(2); - pigeonResult.setANullableInt64( - (aNullableInt64 == null) - ? null - : ((aNullableInt64 instanceof Integer) - ? (Integer) aNullableInt64 - : (Long) aNullableInt64)); - Object aNullableDouble = __pigeon_list.get(3); + Object aNullableInt = pigeonVar_list.get(1); + pigeonResult.setANullableInt((Long) aNullableInt); + Object aNullableInt64 = pigeonVar_list.get(2); + pigeonResult.setANullableInt64((Long) aNullableInt64); + Object aNullableDouble = pigeonVar_list.get(3); pigeonResult.setANullableDouble((Double) aNullableDouble); - Object aNullableByteArray = __pigeon_list.get(4); + Object aNullableByteArray = pigeonVar_list.get(4); pigeonResult.setANullableByteArray((byte[]) aNullableByteArray); - Object aNullable4ByteArray = __pigeon_list.get(5); + Object aNullable4ByteArray = pigeonVar_list.get(5); pigeonResult.setANullable4ByteArray((int[]) aNullable4ByteArray); - Object aNullable8ByteArray = __pigeon_list.get(6); + Object aNullable8ByteArray = pigeonVar_list.get(6); pigeonResult.setANullable8ByteArray((long[]) aNullable8ByteArray); - Object aNullableFloatArray = __pigeon_list.get(7); + Object aNullableFloatArray = pigeonVar_list.get(7); pigeonResult.setANullableFloatArray((double[]) aNullableFloatArray); - Object nullableNestedList = __pigeon_list.get(8); - pigeonResult.setNullableNestedList((List>) nullableNestedList); - Object nullableMapWithAnnotations = __pigeon_list.get(9); - pigeonResult.setNullableMapWithAnnotations((Map) nullableMapWithAnnotations); - Object nullableMapWithObject = __pigeon_list.get(10); - pigeonResult.setNullableMapWithObject((Map) nullableMapWithObject); - Object aNullableEnum = __pigeon_list.get(11); + Object aNullableEnum = pigeonVar_list.get(8); pigeonResult.setANullableEnum((AnEnum) aNullableEnum); - Object aNullableString = __pigeon_list.get(12); + Object anotherNullableEnum = pigeonVar_list.get(9); + pigeonResult.setAnotherNullableEnum((AnotherEnum) anotherNullableEnum); + Object aNullableString = pigeonVar_list.get(10); pigeonResult.setANullableString((String) aNullableString); - Object aNullableObject = __pigeon_list.get(13); + Object aNullableObject = pigeonVar_list.get(11); pigeonResult.setANullableObject(aNullableObject); - Object allNullableTypes = __pigeon_list.get(14); + Object allNullableTypes = pigeonVar_list.get(12); pigeonResult.setAllNullableTypes((AllNullableTypes) allNullableTypes); - Object list = __pigeon_list.get(15); + Object list = pigeonVar_list.get(13); pigeonResult.setList((List) list); - Object stringList = __pigeon_list.get(16); + Object stringList = pigeonVar_list.get(14); pigeonResult.setStringList((List) stringList); - Object intList = __pigeon_list.get(17); + Object intList = pigeonVar_list.get(15); pigeonResult.setIntList((List) intList); - Object doubleList = __pigeon_list.get(18); + Object doubleList = pigeonVar_list.get(16); pigeonResult.setDoubleList((List) doubleList); - Object boolList = __pigeon_list.get(19); + Object boolList = pigeonVar_list.get(17); pigeonResult.setBoolList((List) boolList); - Object nestedClassList = __pigeon_list.get(20); - pigeonResult.setNestedClassList((List) nestedClassList); - Object map = __pigeon_list.get(21); + Object enumList = pigeonVar_list.get(18); + pigeonResult.setEnumList((List) enumList); + Object objectList = pigeonVar_list.get(19); + pigeonResult.setObjectList((List) objectList); + Object listList = pigeonVar_list.get(20); + pigeonResult.setListList((List>) listList); + Object mapList = pigeonVar_list.get(21); + pigeonResult.setMapList((List>) mapList); + Object recursiveClassList = pigeonVar_list.get(22); + pigeonResult.setRecursiveClassList((List) recursiveClassList); + Object map = pigeonVar_list.get(23); pigeonResult.setMap((Map) map); + Object stringMap = pigeonVar_list.get(24); + pigeonResult.setStringMap((Map) stringMap); + Object intMap = pigeonVar_list.get(25); + pigeonResult.setIntMap((Map) intMap); + Object enumMap = pigeonVar_list.get(26); + pigeonResult.setEnumMap((Map) enumMap); + Object objectMap = pigeonVar_list.get(27); + pigeonResult.setObjectMap((Map) objectMap); + Object listMap = pigeonVar_list.get(28); + pigeonResult.setListMap((Map>) listMap); + Object mapMap = pigeonVar_list.get(29); + pigeonResult.setMapMap((Map>) mapMap); + Object recursiveClassMap = pigeonVar_list.get(30); + pigeonResult.setRecursiveClassMap((Map) recursiveClassMap); return pigeonResult; } } @@ -1152,36 +1839,6 @@ public void setANullableFloatArray(@Nullable double[] setterArg) { this.aNullableFloatArray = setterArg; } - private @Nullable List> nullableNestedList; - - public @Nullable List> getNullableNestedList() { - return nullableNestedList; - } - - public void setNullableNestedList(@Nullable List> setterArg) { - this.nullableNestedList = setterArg; - } - - private @Nullable Map nullableMapWithAnnotations; - - public @Nullable Map getNullableMapWithAnnotations() { - return nullableMapWithAnnotations; - } - - public void setNullableMapWithAnnotations(@Nullable Map setterArg) { - this.nullableMapWithAnnotations = setterArg; - } - - private @Nullable Map nullableMapWithObject; - - public @Nullable Map getNullableMapWithObject() { - return nullableMapWithObject; - } - - public void setNullableMapWithObject(@Nullable Map setterArg) { - this.nullableMapWithObject = setterArg; - } - private @Nullable AnEnum aNullableEnum; public @Nullable AnEnum getANullableEnum() { @@ -1192,6 +1849,16 @@ public void setANullableEnum(@Nullable AnEnum setterArg) { this.aNullableEnum = setterArg; } + private @Nullable AnotherEnum anotherNullableEnum; + + public @Nullable AnotherEnum getAnotherNullableEnum() { + return anotherNullableEnum; + } + + public void setAnotherNullableEnum(@Nullable AnotherEnum setterArg) { + this.anotherNullableEnum = setterArg; + } + private @Nullable String aNullableString; public @Nullable String getANullableString() { @@ -1262,6 +1929,46 @@ public void setBoolList(@Nullable List setterArg) { this.boolList = setterArg; } + private @Nullable List enumList; + + public @Nullable List getEnumList() { + return enumList; + } + + public void setEnumList(@Nullable List setterArg) { + this.enumList = setterArg; + } + + private @Nullable List objectList; + + public @Nullable List getObjectList() { + return objectList; + } + + public void setObjectList(@Nullable List setterArg) { + this.objectList = setterArg; + } + + private @Nullable List> listList; + + public @Nullable List> getListList() { + return listList; + } + + public void setListList(@Nullable List> setterArg) { + this.listList = setterArg; + } + + private @Nullable List> mapList; + + public @Nullable List> getMapList() { + return mapList; + } + + public void setMapList(@Nullable List> setterArg) { + this.mapList = setterArg; + } + private @Nullable Map map; public @Nullable Map getMap() { @@ -1272,6 +1979,140 @@ public void setMap(@Nullable Map setterArg) { this.map = setterArg; } + private @Nullable Map stringMap; + + public @Nullable Map getStringMap() { + return stringMap; + } + + public void setStringMap(@Nullable Map setterArg) { + this.stringMap = setterArg; + } + + private @Nullable Map intMap; + + public @Nullable Map getIntMap() { + return intMap; + } + + public void setIntMap(@Nullable Map setterArg) { + this.intMap = setterArg; + } + + private @Nullable Map enumMap; + + public @Nullable Map getEnumMap() { + return enumMap; + } + + public void setEnumMap(@Nullable Map setterArg) { + this.enumMap = setterArg; + } + + private @Nullable Map objectMap; + + public @Nullable Map getObjectMap() { + return objectMap; + } + + public void setObjectMap(@Nullable Map setterArg) { + this.objectMap = setterArg; + } + + private @Nullable Map> listMap; + + public @Nullable Map> getListMap() { + return listMap; + } + + public void setListMap(@Nullable Map> setterArg) { + this.listMap = setterArg; + } + + private @Nullable Map> mapMap; + + public @Nullable Map> getMapMap() { + return mapMap; + } + + public void setMapMap(@Nullable Map> setterArg) { + this.mapMap = setterArg; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AllNullableTypesWithoutRecursion that = (AllNullableTypesWithoutRecursion) o; + return Objects.equals(aNullableBool, that.aNullableBool) + && Objects.equals(aNullableInt, that.aNullableInt) + && Objects.equals(aNullableInt64, that.aNullableInt64) + && Objects.equals(aNullableDouble, that.aNullableDouble) + && Arrays.equals(aNullableByteArray, that.aNullableByteArray) + && Arrays.equals(aNullable4ByteArray, that.aNullable4ByteArray) + && Arrays.equals(aNullable8ByteArray, that.aNullable8ByteArray) + && Arrays.equals(aNullableFloatArray, that.aNullableFloatArray) + && Objects.equals(aNullableEnum, that.aNullableEnum) + && Objects.equals(anotherNullableEnum, that.anotherNullableEnum) + && Objects.equals(aNullableString, that.aNullableString) + && Objects.equals(aNullableObject, that.aNullableObject) + && Objects.equals(list, that.list) + && Objects.equals(stringList, that.stringList) + && Objects.equals(intList, that.intList) + && Objects.equals(doubleList, that.doubleList) + && Objects.equals(boolList, that.boolList) + && Objects.equals(enumList, that.enumList) + && Objects.equals(objectList, that.objectList) + && Objects.equals(listList, that.listList) + && Objects.equals(mapList, that.mapList) + && Objects.equals(map, that.map) + && Objects.equals(stringMap, that.stringMap) + && Objects.equals(intMap, that.intMap) + && Objects.equals(enumMap, that.enumMap) + && Objects.equals(objectMap, that.objectMap) + && Objects.equals(listMap, that.listMap) + && Objects.equals(mapMap, that.mapMap); + } + + @Override + public int hashCode() { + int pigeonVar_result = + Objects.hash( + aNullableBool, + aNullableInt, + aNullableInt64, + aNullableDouble, + aNullableEnum, + anotherNullableEnum, + aNullableString, + aNullableObject, + list, + stringList, + intList, + doubleList, + boolList, + enumList, + objectList, + listList, + mapList, + map, + stringMap, + intMap, + enumMap, + objectMap, + listMap, + mapMap); + pigeonVar_result = 31 * pigeonVar_result + Arrays.hashCode(aNullableByteArray); + pigeonVar_result = 31 * pigeonVar_result + Arrays.hashCode(aNullable4ByteArray); + pigeonVar_result = 31 * pigeonVar_result + Arrays.hashCode(aNullable8ByteArray); + pigeonVar_result = 31 * pigeonVar_result + Arrays.hashCode(aNullableFloatArray); + return pigeonVar_result; + } + public static final class Builder { private @Nullable Boolean aNullableBool; @@ -1338,36 +2179,19 @@ public static final class Builder { return this; } - private @Nullable List> nullableNestedList; - - @CanIgnoreReturnValue - public @NonNull Builder setNullableNestedList(@Nullable List> setterArg) { - this.nullableNestedList = setterArg; - return this; - } - - private @Nullable Map nullableMapWithAnnotations; - - @CanIgnoreReturnValue - public @NonNull Builder setNullableMapWithAnnotations( - @Nullable Map setterArg) { - this.nullableMapWithAnnotations = setterArg; - return this; - } - - private @Nullable Map nullableMapWithObject; + private @Nullable AnEnum aNullableEnum; @CanIgnoreReturnValue - public @NonNull Builder setNullableMapWithObject(@Nullable Map setterArg) { - this.nullableMapWithObject = setterArg; + public @NonNull Builder setANullableEnum(@Nullable AnEnum setterArg) { + this.aNullableEnum = setterArg; return this; } - private @Nullable AnEnum aNullableEnum; + private @Nullable AnotherEnum anotherNullableEnum; @CanIgnoreReturnValue - public @NonNull Builder setANullableEnum(@Nullable AnEnum setterArg) { - this.aNullableEnum = setterArg; + public @NonNull Builder setAnotherNullableEnum(@Nullable AnotherEnum setterArg) { + this.anotherNullableEnum = setterArg; return this; } @@ -1427,6 +2251,38 @@ public static final class Builder { return this; } + private @Nullable List enumList; + + @CanIgnoreReturnValue + public @NonNull Builder setEnumList(@Nullable List setterArg) { + this.enumList = setterArg; + return this; + } + + private @Nullable List objectList; + + @CanIgnoreReturnValue + public @NonNull Builder setObjectList(@Nullable List setterArg) { + this.objectList = setterArg; + return this; + } + + private @Nullable List> listList; + + @CanIgnoreReturnValue + public @NonNull Builder setListList(@Nullable List> setterArg) { + this.listList = setterArg; + return this; + } + + private @Nullable List> mapList; + + @CanIgnoreReturnValue + public @NonNull Builder setMapList(@Nullable List> setterArg) { + this.mapList = setterArg; + return this; + } + private @Nullable Map map; @CanIgnoreReturnValue @@ -1435,35 +2291,91 @@ public static final class Builder { return this; } - public @NonNull AllNullableTypesWithoutRecursion build() { - AllNullableTypesWithoutRecursion pigeonReturn = new AllNullableTypesWithoutRecursion(); - pigeonReturn.setANullableBool(aNullableBool); - pigeonReturn.setANullableInt(aNullableInt); - pigeonReturn.setANullableInt64(aNullableInt64); - pigeonReturn.setANullableDouble(aNullableDouble); - pigeonReturn.setANullableByteArray(aNullableByteArray); - pigeonReturn.setANullable4ByteArray(aNullable4ByteArray); - pigeonReturn.setANullable8ByteArray(aNullable8ByteArray); - pigeonReturn.setANullableFloatArray(aNullableFloatArray); - pigeonReturn.setNullableNestedList(nullableNestedList); - pigeonReturn.setNullableMapWithAnnotations(nullableMapWithAnnotations); - pigeonReturn.setNullableMapWithObject(nullableMapWithObject); - pigeonReturn.setANullableEnum(aNullableEnum); - pigeonReturn.setANullableString(aNullableString); - pigeonReturn.setANullableObject(aNullableObject); - pigeonReturn.setList(list); - pigeonReturn.setStringList(stringList); - pigeonReturn.setIntList(intList); + private @Nullable Map stringMap; + + @CanIgnoreReturnValue + public @NonNull Builder setStringMap(@Nullable Map setterArg) { + this.stringMap = setterArg; + return this; + } + + private @Nullable Map intMap; + + @CanIgnoreReturnValue + public @NonNull Builder setIntMap(@Nullable Map setterArg) { + this.intMap = setterArg; + return this; + } + + private @Nullable Map enumMap; + + @CanIgnoreReturnValue + public @NonNull Builder setEnumMap(@Nullable Map setterArg) { + this.enumMap = setterArg; + return this; + } + + private @Nullable Map objectMap; + + @CanIgnoreReturnValue + public @NonNull Builder setObjectMap(@Nullable Map setterArg) { + this.objectMap = setterArg; + return this; + } + + private @Nullable Map> listMap; + + @CanIgnoreReturnValue + public @NonNull Builder setListMap(@Nullable Map> setterArg) { + this.listMap = setterArg; + return this; + } + + private @Nullable Map> mapMap; + + @CanIgnoreReturnValue + public @NonNull Builder setMapMap(@Nullable Map> setterArg) { + this.mapMap = setterArg; + return this; + } + + public @NonNull AllNullableTypesWithoutRecursion build() { + AllNullableTypesWithoutRecursion pigeonReturn = new AllNullableTypesWithoutRecursion(); + pigeonReturn.setANullableBool(aNullableBool); + pigeonReturn.setANullableInt(aNullableInt); + pigeonReturn.setANullableInt64(aNullableInt64); + pigeonReturn.setANullableDouble(aNullableDouble); + pigeonReturn.setANullableByteArray(aNullableByteArray); + pigeonReturn.setANullable4ByteArray(aNullable4ByteArray); + pigeonReturn.setANullable8ByteArray(aNullable8ByteArray); + pigeonReturn.setANullableFloatArray(aNullableFloatArray); + pigeonReturn.setANullableEnum(aNullableEnum); + pigeonReturn.setAnotherNullableEnum(anotherNullableEnum); + pigeonReturn.setANullableString(aNullableString); + pigeonReturn.setANullableObject(aNullableObject); + pigeonReturn.setList(list); + pigeonReturn.setStringList(stringList); + pigeonReturn.setIntList(intList); pigeonReturn.setDoubleList(doubleList); pigeonReturn.setBoolList(boolList); + pigeonReturn.setEnumList(enumList); + pigeonReturn.setObjectList(objectList); + pigeonReturn.setListList(listList); + pigeonReturn.setMapList(mapList); pigeonReturn.setMap(map); + pigeonReturn.setStringMap(stringMap); + pigeonReturn.setIntMap(intMap); + pigeonReturn.setEnumMap(enumMap); + pigeonReturn.setObjectMap(objectMap); + pigeonReturn.setListMap(listMap); + pigeonReturn.setMapMap(mapMap); return pigeonReturn; } } @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(20); + ArrayList toListResult = new ArrayList<>(28); toListResult.add(aNullableBool); toListResult.add(aNullableInt); toListResult.add(aNullableInt64); @@ -1472,10 +2384,8 @@ ArrayList toList() { toListResult.add(aNullable4ByteArray); toListResult.add(aNullable8ByteArray); toListResult.add(aNullableFloatArray); - toListResult.add(nullableNestedList); - toListResult.add(nullableMapWithAnnotations); - toListResult.add(nullableMapWithObject); toListResult.add(aNullableEnum); + toListResult.add(anotherNullableEnum); toListResult.add(aNullableString); toListResult.add(aNullableObject); toListResult.add(list); @@ -1483,61 +2393,79 @@ ArrayList toList() { toListResult.add(intList); toListResult.add(doubleList); toListResult.add(boolList); + toListResult.add(enumList); + toListResult.add(objectList); + toListResult.add(listList); + toListResult.add(mapList); toListResult.add(map); + toListResult.add(stringMap); + toListResult.add(intMap); + toListResult.add(enumMap); + toListResult.add(objectMap); + toListResult.add(listMap); + toListResult.add(mapMap); return toListResult; } static @NonNull AllNullableTypesWithoutRecursion fromList( - @NonNull ArrayList __pigeon_list) { + @NonNull ArrayList pigeonVar_list) { AllNullableTypesWithoutRecursion pigeonResult = new AllNullableTypesWithoutRecursion(); - Object aNullableBool = __pigeon_list.get(0); + Object aNullableBool = pigeonVar_list.get(0); pigeonResult.setANullableBool((Boolean) aNullableBool); - Object aNullableInt = __pigeon_list.get(1); - pigeonResult.setANullableInt( - (aNullableInt == null) - ? null - : ((aNullableInt instanceof Integer) ? (Integer) aNullableInt : (Long) aNullableInt)); - Object aNullableInt64 = __pigeon_list.get(2); - pigeonResult.setANullableInt64( - (aNullableInt64 == null) - ? null - : ((aNullableInt64 instanceof Integer) - ? (Integer) aNullableInt64 - : (Long) aNullableInt64)); - Object aNullableDouble = __pigeon_list.get(3); + Object aNullableInt = pigeonVar_list.get(1); + pigeonResult.setANullableInt((Long) aNullableInt); + Object aNullableInt64 = pigeonVar_list.get(2); + pigeonResult.setANullableInt64((Long) aNullableInt64); + Object aNullableDouble = pigeonVar_list.get(3); pigeonResult.setANullableDouble((Double) aNullableDouble); - Object aNullableByteArray = __pigeon_list.get(4); + Object aNullableByteArray = pigeonVar_list.get(4); pigeonResult.setANullableByteArray((byte[]) aNullableByteArray); - Object aNullable4ByteArray = __pigeon_list.get(5); + Object aNullable4ByteArray = pigeonVar_list.get(5); pigeonResult.setANullable4ByteArray((int[]) aNullable4ByteArray); - Object aNullable8ByteArray = __pigeon_list.get(6); + Object aNullable8ByteArray = pigeonVar_list.get(6); pigeonResult.setANullable8ByteArray((long[]) aNullable8ByteArray); - Object aNullableFloatArray = __pigeon_list.get(7); + Object aNullableFloatArray = pigeonVar_list.get(7); pigeonResult.setANullableFloatArray((double[]) aNullableFloatArray); - Object nullableNestedList = __pigeon_list.get(8); - pigeonResult.setNullableNestedList((List>) nullableNestedList); - Object nullableMapWithAnnotations = __pigeon_list.get(9); - pigeonResult.setNullableMapWithAnnotations((Map) nullableMapWithAnnotations); - Object nullableMapWithObject = __pigeon_list.get(10); - pigeonResult.setNullableMapWithObject((Map) nullableMapWithObject); - Object aNullableEnum = __pigeon_list.get(11); + Object aNullableEnum = pigeonVar_list.get(8); pigeonResult.setANullableEnum((AnEnum) aNullableEnum); - Object aNullableString = __pigeon_list.get(12); + Object anotherNullableEnum = pigeonVar_list.get(9); + pigeonResult.setAnotherNullableEnum((AnotherEnum) anotherNullableEnum); + Object aNullableString = pigeonVar_list.get(10); pigeonResult.setANullableString((String) aNullableString); - Object aNullableObject = __pigeon_list.get(13); + Object aNullableObject = pigeonVar_list.get(11); pigeonResult.setANullableObject(aNullableObject); - Object list = __pigeon_list.get(14); + Object list = pigeonVar_list.get(12); pigeonResult.setList((List) list); - Object stringList = __pigeon_list.get(15); + Object stringList = pigeonVar_list.get(13); pigeonResult.setStringList((List) stringList); - Object intList = __pigeon_list.get(16); + Object intList = pigeonVar_list.get(14); pigeonResult.setIntList((List) intList); - Object doubleList = __pigeon_list.get(17); + Object doubleList = pigeonVar_list.get(15); pigeonResult.setDoubleList((List) doubleList); - Object boolList = __pigeon_list.get(18); + Object boolList = pigeonVar_list.get(16); pigeonResult.setBoolList((List) boolList); - Object map = __pigeon_list.get(19); + Object enumList = pigeonVar_list.get(17); + pigeonResult.setEnumList((List) enumList); + Object objectList = pigeonVar_list.get(18); + pigeonResult.setObjectList((List) objectList); + Object listList = pigeonVar_list.get(19); + pigeonResult.setListList((List>) listList); + Object mapList = pigeonVar_list.get(20); + pigeonResult.setMapList((List>) mapList); + Object map = pigeonVar_list.get(21); pigeonResult.setMap((Map) map); + Object stringMap = pigeonVar_list.get(22); + pigeonResult.setStringMap((Map) stringMap); + Object intMap = pigeonVar_list.get(23); + pigeonResult.setIntMap((Map) intMap); + Object enumMap = pigeonVar_list.get(24); + pigeonResult.setEnumMap((Map) enumMap); + Object objectMap = pigeonVar_list.get(25); + pigeonResult.setObjectMap((Map) objectMap); + Object listMap = pigeonVar_list.get(26); + pigeonResult.setListMap((Map>) listMap); + Object mapMap = pigeonVar_list.get(27); + pigeonResult.setMapMap((Map>) mapMap); return pigeonResult; } } @@ -1586,9 +2514,86 @@ public void setAllTypes(@Nullable AllTypes setterArg) { this.allTypes = setterArg; } + private @NonNull List classList; + + public @NonNull List getClassList() { + return classList; + } + + public void setClassList(@NonNull List setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"classList\" is null."); + } + this.classList = setterArg; + } + + private @Nullable List nullableClassList; + + public @Nullable List getNullableClassList() { + return nullableClassList; + } + + public void setNullableClassList(@Nullable List setterArg) { + this.nullableClassList = setterArg; + } + + private @NonNull Map classMap; + + public @NonNull Map getClassMap() { + return classMap; + } + + public void setClassMap(@NonNull Map setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"classMap\" is null."); + } + this.classMap = setterArg; + } + + private @Nullable Map nullableClassMap; + + public @Nullable Map getNullableClassMap() { + return nullableClassMap; + } + + public void setNullableClassMap( + @Nullable Map setterArg) { + this.nullableClassMap = setterArg; + } + /** Constructor is non-public to enforce null safety; use Builder. */ AllClassesWrapper() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AllClassesWrapper that = (AllClassesWrapper) o; + return allNullableTypes.equals(that.allNullableTypes) + && Objects.equals(allNullableTypesWithoutRecursion, that.allNullableTypesWithoutRecursion) + && Objects.equals(allTypes, that.allTypes) + && classList.equals(that.classList) + && Objects.equals(nullableClassList, that.nullableClassList) + && classMap.equals(that.classMap) + && Objects.equals(nullableClassMap, that.nullableClassMap); + } + + @Override + public int hashCode() { + return Objects.hash( + allNullableTypes, + allNullableTypesWithoutRecursion, + allTypes, + classList, + nullableClassList, + classMap, + nullableClassMap); + } + public static final class Builder { private @Nullable AllNullableTypes allNullableTypes; @@ -1616,33 +2621,84 @@ public static final class Builder { return this; } + private @Nullable List classList; + + @CanIgnoreReturnValue + public @NonNull Builder setClassList(@NonNull List setterArg) { + this.classList = setterArg; + return this; + } + + private @Nullable List nullableClassList; + + @CanIgnoreReturnValue + public @NonNull Builder setNullableClassList( + @Nullable List setterArg) { + this.nullableClassList = setterArg; + return this; + } + + private @Nullable Map classMap; + + @CanIgnoreReturnValue + public @NonNull Builder setClassMap(@NonNull Map setterArg) { + this.classMap = setterArg; + return this; + } + + private @Nullable Map nullableClassMap; + + @CanIgnoreReturnValue + public @NonNull Builder setNullableClassMap( + @Nullable Map setterArg) { + this.nullableClassMap = setterArg; + return this; + } + public @NonNull AllClassesWrapper build() { AllClassesWrapper pigeonReturn = new AllClassesWrapper(); pigeonReturn.setAllNullableTypes(allNullableTypes); pigeonReturn.setAllNullableTypesWithoutRecursion(allNullableTypesWithoutRecursion); pigeonReturn.setAllTypes(allTypes); + pigeonReturn.setClassList(classList); + pigeonReturn.setNullableClassList(nullableClassList); + pigeonReturn.setClassMap(classMap); + pigeonReturn.setNullableClassMap(nullableClassMap); return pigeonReturn; } } @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(3); + ArrayList toListResult = new ArrayList<>(7); toListResult.add(allNullableTypes); toListResult.add(allNullableTypesWithoutRecursion); toListResult.add(allTypes); + toListResult.add(classList); + toListResult.add(nullableClassList); + toListResult.add(classMap); + toListResult.add(nullableClassMap); return toListResult; } - static @NonNull AllClassesWrapper fromList(@NonNull ArrayList __pigeon_list) { + static @NonNull AllClassesWrapper fromList(@NonNull ArrayList pigeonVar_list) { AllClassesWrapper pigeonResult = new AllClassesWrapper(); - Object allNullableTypes = __pigeon_list.get(0); + Object allNullableTypes = pigeonVar_list.get(0); pigeonResult.setAllNullableTypes((AllNullableTypes) allNullableTypes); - Object allNullableTypesWithoutRecursion = __pigeon_list.get(1); + Object allNullableTypesWithoutRecursion = pigeonVar_list.get(1); pigeonResult.setAllNullableTypesWithoutRecursion( (AllNullableTypesWithoutRecursion) allNullableTypesWithoutRecursion); - Object allTypes = __pigeon_list.get(2); + Object allTypes = pigeonVar_list.get(2); pigeonResult.setAllTypes((AllTypes) allTypes); + Object classList = pigeonVar_list.get(3); + pigeonResult.setClassList((List) classList); + Object nullableClassList = pigeonVar_list.get(4); + pigeonResult.setNullableClassList((List) nullableClassList); + Object classMap = pigeonVar_list.get(5); + pigeonResult.setClassMap((Map) classMap); + Object nullableClassMap = pigeonVar_list.get(6); + pigeonResult.setNullableClassMap( + (Map) nullableClassMap); return pigeonResult; } } @@ -1663,6 +2719,23 @@ public void setTestList(@Nullable List setterArg) { this.testList = setterArg; } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + TestMessage that = (TestMessage) o; + return Objects.equals(testList, that.testList); + } + + @Override + public int hashCode() { + return Objects.hash(testList); + } + public static final class Builder { private @Nullable List testList; @@ -1682,14 +2755,14 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(1); + ArrayList toListResult = new ArrayList<>(1); toListResult.add(testList); return toListResult; } - static @NonNull TestMessage fromList(@NonNull ArrayList __pigeon_list) { + static @NonNull TestMessage fromList(@NonNull ArrayList pigeonVar_list) { TestMessage pigeonResult = new TestMessage(); - Object testList = __pigeon_list.get(0); + Object testList = pigeonVar_list.get(0); pigeonResult.setTestList((List) testList); return pigeonResult; } @@ -1704,18 +2777,27 @@ private PigeonCodec() {} protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { switch (type) { case (byte) 129: - return AllTypes.fromList((ArrayList) readValue(buffer)); + { + Object value = readValue(buffer); + return value == null ? null : AnEnum.values()[((Long) value).intValue()]; + } case (byte) 130: - return AllNullableTypes.fromList((ArrayList) readValue(buffer)); + { + Object value = readValue(buffer); + return value == null ? null : AnotherEnum.values()[((Long) value).intValue()]; + } case (byte) 131: - return AllNullableTypesWithoutRecursion.fromList((ArrayList) readValue(buffer)); + return UnusedClass.fromList((ArrayList) readValue(buffer)); case (byte) 132: - return AllClassesWrapper.fromList((ArrayList) readValue(buffer)); + return AllTypes.fromList((ArrayList) readValue(buffer)); case (byte) 133: - return TestMessage.fromList((ArrayList) readValue(buffer)); + return AllNullableTypes.fromList((ArrayList) readValue(buffer)); case (byte) 134: - Object value = readValue(buffer); - return value == null ? null : AnEnum.values()[(int) value]; + return AllNullableTypesWithoutRecursion.fromList((ArrayList) readValue(buffer)); + case (byte) 135: + return AllClassesWrapper.fromList((ArrayList) readValue(buffer)); + case (byte) 136: + return TestMessage.fromList((ArrayList) readValue(buffer)); default: return super.readValueOfType(type, buffer); } @@ -1723,24 +2805,30 @@ protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { @Override protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { - if (value instanceof AllTypes) { + if (value instanceof AnEnum) { stream.write(129); + writeValue(stream, value == null ? null : ((AnEnum) value).index); + } else if (value instanceof AnotherEnum) { + stream.write(130); + writeValue(stream, value == null ? null : ((AnotherEnum) value).index); + } else if (value instanceof UnusedClass) { + stream.write(131); + writeValue(stream, ((UnusedClass) value).toList()); + } else if (value instanceof AllTypes) { + stream.write(132); writeValue(stream, ((AllTypes) value).toList()); } else if (value instanceof AllNullableTypes) { - stream.write(130); + stream.write(133); writeValue(stream, ((AllNullableTypes) value).toList()); } else if (value instanceof AllNullableTypesWithoutRecursion) { - stream.write(131); + stream.write(134); writeValue(stream, ((AllNullableTypesWithoutRecursion) value).toList()); } else if (value instanceof AllClassesWrapper) { - stream.write(132); + stream.write(135); writeValue(stream, ((AllClassesWrapper) value).toList()); } else if (value instanceof TestMessage) { - stream.write(133); + stream.write(136); writeValue(stream, ((TestMessage) value).toList()); - } else if (value instanceof AnEnum) { - stream.write(134); - writeValue(stream, value == null ? null : ((AnEnum) value).index); } else { super.writeValue(stream, value); } @@ -1814,15 +2902,54 @@ public interface HostIntegrationCoreApi { /** Returns the passed list, to test serialization and deserialization. */ @NonNull List echoList(@NonNull List list); + /** Returns the passed list, to test serialization and deserialization. */ + @NonNull + List echoEnumList(@NonNull List enumList); + /** Returns the passed list, to test serialization and deserialization. */ + @NonNull + List echoClassList(@NonNull List classList); + /** Returns the passed list, to test serialization and deserialization. */ + @NonNull + List echoNonNullEnumList(@NonNull List enumList); + /** Returns the passed list, to test serialization and deserialization. */ + @NonNull + List echoNonNullClassList(@NonNull List classList); + /** Returns the passed map, to test serialization and deserialization. */ + @NonNull + Map echoMap(@NonNull Map map); + /** Returns the passed map, to test serialization and deserialization. */ + @NonNull + Map echoStringMap(@NonNull Map stringMap); + /** Returns the passed map, to test serialization and deserialization. */ + @NonNull + Map echoIntMap(@NonNull Map intMap); + /** Returns the passed map, to test serialization and deserialization. */ + @NonNull + Map echoEnumMap(@NonNull Map enumMap); /** Returns the passed map, to test serialization and deserialization. */ @NonNull - Map echoMap(@NonNull Map aMap); - /** Returns the passed map to test nested class serialization and deserialization. */ + Map echoClassMap(@NonNull Map classMap); + /** Returns the passed map, to test serialization and deserialization. */ + @NonNull + Map echoNonNullStringMap(@NonNull Map stringMap); + /** Returns the passed map, to test serialization and deserialization. */ + @NonNull + Map echoNonNullIntMap(@NonNull Map intMap); + /** Returns the passed map, to test serialization and deserialization. */ + @NonNull + Map echoNonNullEnumMap(@NonNull Map enumMap); + /** Returns the passed map, to test serialization and deserialization. */ + @NonNull + Map echoNonNullClassMap(@NonNull Map classMap); + /** Returns the passed class to test nested class serialization and deserialization. */ @NonNull AllClassesWrapper echoClassWrapper(@NonNull AllClassesWrapper wrapper); /** Returns the passed enum to test serialization and deserialization. */ @NonNull AnEnum echoEnum(@NonNull AnEnum anEnum); + /** Returns the passed enum to test serialization and deserialization. */ + @NonNull + AnotherEnum echoAnotherEnum(@NonNull AnotherEnum anotherEnum); /** Returns the default string. */ @NonNull String echoNamedDefaultString(@NonNull String aString); @@ -1882,12 +3009,53 @@ AllNullableTypesWithoutRecursion sendMultipleNullableTypesWithoutRecursion( /** Returns the passed list, to test serialization and deserialization. */ @Nullable List echoNullableList(@Nullable List aNullableList); + /** Returns the passed list, to test serialization and deserialization. */ + @Nullable + List echoNullableEnumList(@Nullable List enumList); + /** Returns the passed list, to test serialization and deserialization. */ + @Nullable + List echoNullableClassList(@Nullable List classList); + /** Returns the passed list, to test serialization and deserialization. */ + @Nullable + List echoNullableNonNullEnumList(@Nullable List enumList); + /** Returns the passed list, to test serialization and deserialization. */ + @Nullable + List echoNullableNonNullClassList(@Nullable List classList); + /** Returns the passed map, to test serialization and deserialization. */ + @Nullable + Map echoNullableMap(@Nullable Map map); + /** Returns the passed map, to test serialization and deserialization. */ + @Nullable + Map echoNullableStringMap(@Nullable Map stringMap); + /** Returns the passed map, to test serialization and deserialization. */ + @Nullable + Map echoNullableIntMap(@Nullable Map intMap); + /** Returns the passed map, to test serialization and deserialization. */ + @Nullable + Map echoNullableEnumMap(@Nullable Map enumMap); + /** Returns the passed map, to test serialization and deserialization. */ + @Nullable + Map echoNullableClassMap( + @Nullable Map classMap); + /** Returns the passed map, to test serialization and deserialization. */ + @Nullable + Map echoNullableNonNullStringMap(@Nullable Map stringMap); + /** Returns the passed map, to test serialization and deserialization. */ + @Nullable + Map echoNullableNonNullIntMap(@Nullable Map intMap); /** Returns the passed map, to test serialization and deserialization. */ @Nullable - Map echoNullableMap(@Nullable Map aNullableMap); + Map echoNullableNonNullEnumMap(@Nullable Map enumMap); + /** Returns the passed map, to test serialization and deserialization. */ + @Nullable + Map echoNullableNonNullClassMap( + @Nullable Map classMap); @Nullable AnEnum echoNullableEnum(@Nullable AnEnum anEnum); + + @Nullable + AnotherEnum echoAnotherNullableEnum(@Nullable AnotherEnum anotherEnum); /** Returns passed in int. */ @Nullable Long echoOptionalNullableInt(@Nullable Long aNullableInt); @@ -1913,11 +3081,31 @@ AllNullableTypesWithoutRecursion sendMultipleNullableTypesWithoutRecursion( void echoAsyncObject(@NonNull Object anObject, @NonNull Result result); /** Returns the passed list, to test asynchronous serialization and deserialization. */ void echoAsyncList(@NonNull List list, @NonNull Result> result); + /** Returns the passed list, to test asynchronous serialization and deserialization. */ + void echoAsyncEnumList(@NonNull List enumList, @NonNull Result> result); + /** Returns the passed list, to test asynchronous serialization and deserialization. */ + void echoAsyncClassList( + @NonNull List classList, @NonNull Result> result); /** Returns the passed map, to test asynchronous serialization and deserialization. */ void echoAsyncMap( - @NonNull Map aMap, @NonNull Result> result); + @NonNull Map map, @NonNull Result> result); + /** Returns the passed map, to test asynchronous serialization and deserialization. */ + void echoAsyncStringMap( + @NonNull Map stringMap, @NonNull Result> result); + /** Returns the passed map, to test asynchronous serialization and deserialization. */ + void echoAsyncIntMap(@NonNull Map intMap, @NonNull Result> result); + /** Returns the passed map, to test asynchronous serialization and deserialization. */ + void echoAsyncEnumMap( + @NonNull Map enumMap, @NonNull Result> result); + /** Returns the passed map, to test asynchronous serialization and deserialization. */ + void echoAsyncClassMap( + @NonNull Map classMap, + @NonNull Result> result); /** Returns the passed enum, to test asynchronous serialization and deserialization. */ void echoAsyncEnum(@NonNull AnEnum anEnum, @NonNull Result result); + /** Returns the passed enum, to test asynchronous serialization and deserialization. */ + void echoAnotherAsyncEnum( + @NonNull AnotherEnum anotherEnum, @NonNull Result result); /** Responds with an error from an async function returning a value. */ void throwAsyncError(@NonNull NullableResult result); /** Responds with an error from an async void function. */ @@ -1949,11 +3137,35 @@ void echoAsyncNullableUint8List( /** Returns the passed list, to test asynchronous serialization and deserialization. */ void echoAsyncNullableList( @Nullable List list, @NonNull NullableResult> result); + /** Returns the passed list, to test asynchronous serialization and deserialization. */ + void echoAsyncNullableEnumList( + @Nullable List enumList, @NonNull NullableResult> result); + /** Returns the passed list, to test asynchronous serialization and deserialization. */ + void echoAsyncNullableClassList( + @Nullable List classList, + @NonNull NullableResult> result); /** Returns the passed map, to test asynchronous serialization and deserialization. */ void echoAsyncNullableMap( - @Nullable Map aMap, @NonNull NullableResult> result); + @Nullable Map map, @NonNull NullableResult> result); + /** Returns the passed map, to test asynchronous serialization and deserialization. */ + void echoAsyncNullableStringMap( + @Nullable Map stringMap, + @NonNull NullableResult> result); + /** Returns the passed map, to test asynchronous serialization and deserialization. */ + void echoAsyncNullableIntMap( + @Nullable Map intMap, @NonNull NullableResult> result); + /** Returns the passed map, to test asynchronous serialization and deserialization. */ + void echoAsyncNullableEnumMap( + @Nullable Map enumMap, @NonNull NullableResult> result); + /** Returns the passed map, to test asynchronous serialization and deserialization. */ + void echoAsyncNullableClassMap( + @Nullable Map classMap, + @NonNull NullableResult> result); /** Returns the passed enum, to test asynchronous serialization and deserialization. */ void echoAsyncNullableEnum(@Nullable AnEnum anEnum, @NonNull NullableResult result); + /** Returns the passed enum, to test asynchronous serialization and deserialization. */ + void echoAnotherAsyncNullableEnum( + @Nullable AnotherEnum anotherEnum, @NonNull NullableResult result); void callFlutterNoop(@NonNull VoidResult result); @@ -1994,11 +3206,52 @@ void callFlutterSendMultipleNullableTypesWithoutRecursion( void callFlutterEchoList(@NonNull List list, @NonNull Result> result); + void callFlutterEchoEnumList( + @NonNull List enumList, @NonNull Result> result); + + void callFlutterEchoClassList( + @NonNull List classList, @NonNull Result> result); + + void callFlutterEchoNonNullEnumList( + @NonNull List enumList, @NonNull Result> result); + + void callFlutterEchoNonNullClassList( + @NonNull List classList, @NonNull Result> result); + void callFlutterEchoMap( - @NonNull Map aMap, @NonNull Result> result); + @NonNull Map map, @NonNull Result> result); + + void callFlutterEchoStringMap( + @NonNull Map stringMap, @NonNull Result> result); + + void callFlutterEchoIntMap( + @NonNull Map intMap, @NonNull Result> result); + + void callFlutterEchoEnumMap( + @NonNull Map enumMap, @NonNull Result> result); + + void callFlutterEchoClassMap( + @NonNull Map classMap, + @NonNull Result> result); + + void callFlutterEchoNonNullStringMap( + @NonNull Map stringMap, @NonNull Result> result); + + void callFlutterEchoNonNullIntMap( + @NonNull Map intMap, @NonNull Result> result); + + void callFlutterEchoNonNullEnumMap( + @NonNull Map enumMap, @NonNull Result> result); + + void callFlutterEchoNonNullClassMap( + @NonNull Map classMap, + @NonNull Result> result); void callFlutterEchoEnum(@NonNull AnEnum anEnum, @NonNull Result result); + void callFlutterEchoAnotherEnum( + @NonNull AnotherEnum anotherEnum, @NonNull Result result); + void callFlutterEchoNullableBool( @Nullable Boolean aBool, @NonNull NullableResult result); @@ -2016,12 +3269,57 @@ void callFlutterEchoNullableUint8List( void callFlutterEchoNullableList( @Nullable List list, @NonNull NullableResult> result); + void callFlutterEchoNullableEnumList( + @Nullable List enumList, @NonNull NullableResult> result); + + void callFlutterEchoNullableClassList( + @Nullable List classList, + @NonNull NullableResult> result); + + void callFlutterEchoNullableNonNullEnumList( + @Nullable List enumList, @NonNull NullableResult> result); + + void callFlutterEchoNullableNonNullClassList( + @Nullable List classList, + @NonNull NullableResult> result); + void callFlutterEchoNullableMap( - @Nullable Map aMap, @NonNull NullableResult> result); + @Nullable Map map, @NonNull NullableResult> result); + + void callFlutterEchoNullableStringMap( + @Nullable Map stringMap, + @NonNull NullableResult> result); + + void callFlutterEchoNullableIntMap( + @Nullable Map intMap, @NonNull NullableResult> result); + + void callFlutterEchoNullableEnumMap( + @Nullable Map enumMap, @NonNull NullableResult> result); + + void callFlutterEchoNullableClassMap( + @Nullable Map classMap, + @NonNull NullableResult> result); + + void callFlutterEchoNullableNonNullStringMap( + @Nullable Map stringMap, + @NonNull NullableResult> result); + + void callFlutterEchoNullableNonNullIntMap( + @Nullable Map intMap, @NonNull NullableResult> result); + + void callFlutterEchoNullableNonNullEnumMap( + @Nullable Map enumMap, @NonNull NullableResult> result); + + void callFlutterEchoNullableNonNullClassMap( + @Nullable Map classMap, + @NonNull NullableResult> result); void callFlutterEchoNullableEnum( @Nullable AnEnum anEnum, @NonNull NullableResult result); + void callFlutterEchoAnotherNullableEnum( + @Nullable AnotherEnum anotherEnum, @NonNull NullableResult result); + void callFlutterSmallApiEchoString(@NonNull String aString, @NonNull Result result); /** The codec used by HostIntegrationCoreApi. */ @@ -2052,13 +3350,12 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { api.noop(); wrapped.add(0, null); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2076,15 +3373,14 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; AllTypes everythingArg = (AllTypes) args.get(0); try { AllTypes output = api.echoAllTypes(everythingArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2102,13 +3398,12 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { Object output = api.throwError(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2126,13 +3421,12 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { api.throwErrorFromVoid(); wrapped.add(0, null); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2150,13 +3444,12 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { Object output = api.throwFlutterError(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2174,15 +3467,14 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Number anIntArg = (Number) args.get(0); + Long anIntArg = (Long) args.get(0); try { - Long output = api.echoInt((anIntArg == null) ? null : anIntArg.longValue()); + Long output = api.echoInt(anIntArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2200,15 +3492,14 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; Double aDoubleArg = (Double) args.get(0); try { Double output = api.echoDouble(aDoubleArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2226,15 +3517,14 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; Boolean aBoolArg = (Boolean) args.get(0); try { Boolean output = api.echoBool(aBoolArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2252,15 +3542,14 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; String aStringArg = (String) args.get(0); try { String output = api.echoString(aStringArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2278,15 +3567,14 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; byte[] aUint8ListArg = (byte[]) args.get(0); try { byte[] output = api.echoUint8List(aUint8ListArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2304,15 +3592,14 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; Object anObjectArg = args.get(0); try { Object output = api.echoObject(anObjectArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2330,15 +3617,14 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; List listArg = (List) args.get(0); try { List output = api.echoList(listArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2350,21 +3636,20 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoMap" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoEnumList" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Map aMapArg = (Map) args.get(0); + List enumListArg = (List) args.get(0); try { - Map output = api.echoMap(aMapArg); + List output = api.echoEnumList(enumListArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2376,21 +3661,20 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoClassWrapper" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoClassList" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - AllClassesWrapper wrapperArg = (AllClassesWrapper) args.get(0); + List classListArg = (List) args.get(0); try { - AllClassesWrapper output = api.echoClassWrapper(wrapperArg); + List output = api.echoClassList(classListArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2402,21 +3686,20 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoEnum" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullEnumList" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - AnEnum anEnumArg = (AnEnum) args.get(0); + List enumListArg = (List) args.get(0); try { - AnEnum output = api.echoEnum(anEnumArg); + List output = api.echoNonNullEnumList(enumListArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2428,21 +3711,20 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNamedDefaultString" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullClassList" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - String aStringArg = (String) args.get(0); + List classListArg = (List) args.get(0); try { - String output = api.echoNamedDefaultString(aStringArg); + List output = api.echoNonNullClassList(classListArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2454,21 +3736,20 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoOptionalDefaultDouble" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoMap" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Double aDoubleArg = (Double) args.get(0); + Map mapArg = (Map) args.get(0); try { - Double output = api.echoOptionalDefaultDouble(aDoubleArg); + Map output = api.echoMap(mapArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2480,22 +3761,20 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoRequiredInt" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoStringMap" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Number anIntArg = (Number) args.get(0); + Map stringMapArg = (Map) args.get(0); try { - Long output = - api.echoRequiredInt((anIntArg == null) ? null : anIntArg.longValue()); + Map output = api.echoStringMap(stringMapArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2507,21 +3786,20 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypes" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoIntMap" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - AllNullableTypes everythingArg = (AllNullableTypes) args.get(0); + Map intMapArg = (Map) args.get(0); try { - AllNullableTypes output = api.echoAllNullableTypes(everythingArg); + Map output = api.echoIntMap(intMapArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2533,23 +3811,20 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypesWithoutRecursion" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoEnumMap" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - AllNullableTypesWithoutRecursion everythingArg = - (AllNullableTypesWithoutRecursion) args.get(0); + Map enumMapArg = (Map) args.get(0); try { - AllNullableTypesWithoutRecursion output = - api.echoAllNullableTypesWithoutRecursion(everythingArg); + Map output = api.echoEnumMap(enumMapArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2561,21 +3836,20 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.extractNestedNullableString" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoClassMap" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - AllClassesWrapper wrapperArg = (AllClassesWrapper) args.get(0); + Map classMapArg = (Map) args.get(0); try { - String output = api.extractNestedNullableString(wrapperArg); + Map output = api.echoClassMap(classMapArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2587,21 +3861,20 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.createNestedNullableString" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullStringMap" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - String nullableStringArg = (String) args.get(0); + Map stringMapArg = (Map) args.get(0); try { - AllClassesWrapper output = api.createNestedNullableString(nullableStringArg); + Map output = api.echoNonNullStringMap(stringMapArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2613,27 +3886,20 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypes" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullIntMap" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Boolean aNullableBoolArg = (Boolean) args.get(0); - Number aNullableIntArg = (Number) args.get(1); - String aNullableStringArg = (String) args.get(2); + Map intMapArg = (Map) args.get(0); try { - AllNullableTypes output = - api.sendMultipleNullableTypes( - aNullableBoolArg, - (aNullableIntArg == null) ? null : aNullableIntArg.longValue(), - aNullableStringArg); + Map output = api.echoNonNullIntMap(intMapArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2645,27 +3911,20 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullEnumMap" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Boolean aNullableBoolArg = (Boolean) args.get(0); - Number aNullableIntArg = (Number) args.get(1); - String aNullableStringArg = (String) args.get(2); + Map enumMapArg = (Map) args.get(0); try { - AllNullableTypesWithoutRecursion output = - api.sendMultipleNullableTypesWithoutRecursion( - aNullableBoolArg, - (aNullableIntArg == null) ? null : aNullableIntArg.longValue(), - aNullableStringArg); + Map output = api.echoNonNullEnumMap(enumMapArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2677,23 +3936,20 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableInt" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullClassMap" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Number aNullableIntArg = (Number) args.get(0); + Map classMapArg = (Map) args.get(0); try { - Long output = - api.echoNullableInt( - (aNullableIntArg == null) ? null : aNullableIntArg.longValue()); + Map output = api.echoNonNullClassMap(classMapArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2705,21 +3961,20 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableDouble" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoClassWrapper" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Double aNullableDoubleArg = (Double) args.get(0); + AllClassesWrapper wrapperArg = (AllClassesWrapper) args.get(0); try { - Double output = api.echoNullableDouble(aNullableDoubleArg); + AllClassesWrapper output = api.echoClassWrapper(wrapperArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2731,21 +3986,20 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableBool" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoEnum" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Boolean aNullableBoolArg = (Boolean) args.get(0); + AnEnum anEnumArg = (AnEnum) args.get(0); try { - Boolean output = api.echoNullableBool(aNullableBoolArg); + AnEnum output = api.echoEnum(anEnumArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2757,21 +4011,20 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableString" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAnotherEnum" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - String aNullableStringArg = (String) args.get(0); + AnotherEnum anotherEnumArg = (AnotherEnum) args.get(0); try { - String output = api.echoNullableString(aNullableStringArg); + AnotherEnum output = api.echoAnotherEnum(anotherEnumArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2783,21 +4036,20 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableUint8List" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNamedDefaultString" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - byte[] aNullableUint8ListArg = (byte[]) args.get(0); + String aStringArg = (String) args.get(0); try { - byte[] output = api.echoNullableUint8List(aNullableUint8ListArg); + String output = api.echoNamedDefaultString(aStringArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2809,21 +4061,20 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableObject" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoOptionalDefaultDouble" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Object aNullableObjectArg = args.get(0); + Double aDoubleArg = (Double) args.get(0); try { - Object output = api.echoNullableObject(aNullableObjectArg); + Double output = api.echoOptionalDefaultDouble(aDoubleArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2835,21 +4086,20 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableList" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoRequiredInt" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - List aNullableListArg = (List) args.get(0); + Long anIntArg = (Long) args.get(0); try { - List output = api.echoNullableList(aNullableListArg); + Long output = api.echoRequiredInt(anIntArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2861,21 +4111,20 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableMap" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypes" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Map aNullableMapArg = (Map) args.get(0); + AllNullableTypes everythingArg = (AllNullableTypes) args.get(0); try { - Map output = api.echoNullableMap(aNullableMapArg); + AllNullableTypes output = api.echoAllNullableTypes(everythingArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2887,21 +4136,22 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableEnum" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypesWithoutRecursion" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - AnEnum anEnumArg = (AnEnum) args.get(0); + AllNullableTypesWithoutRecursion everythingArg = + (AllNullableTypesWithoutRecursion) args.get(0); try { - AnEnum output = api.echoNullableEnum(anEnumArg); + AllNullableTypesWithoutRecursion output = + api.echoAllNullableTypesWithoutRecursion(everythingArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2913,23 +4163,20 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoOptionalNullableInt" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.extractNestedNullableString" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Number aNullableIntArg = (Number) args.get(0); + AllClassesWrapper wrapperArg = (AllClassesWrapper) args.get(0); try { - Long output = - api.echoOptionalNullableInt( - (aNullableIntArg == null) ? null : aNullableIntArg.longValue()); + String output = api.extractNestedNullableString(wrapperArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2941,21 +4188,20 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNamedNullableString" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.createNestedNullableString" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - String aNullableStringArg = (String) args.get(0); + String nullableStringArg = (String) args.get(0); try { - String output = api.echoNamedNullableString(aNullableStringArg); + AllClassesWrapper output = api.createNestedNullableString(nullableStringArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -2967,27 +4213,26 @@ static void setUp( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.noopAsync" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypes" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); - VoidResult resultCallback = - new VoidResult() { - public void success() { - wrapped.add(0, null); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.noopAsync(resultCallback); + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Boolean aNullableBoolArg = (Boolean) args.get(0); + Long aNullableIntArg = (Long) args.get(1); + String aNullableStringArg = (String) args.get(2); + try { + AllNullableTypes output = + api.sendMultipleNullableTypes( + aNullableBoolArg, aNullableIntArg, aNullableStringArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -2997,29 +4242,26 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncInt" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Number anIntArg = (Number) args.get(0); - Result resultCallback = - new Result() { - public void success(Long result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.echoAsyncInt((anIntArg == null) ? null : anIntArg.longValue(), resultCallback); + Boolean aNullableBoolArg = (Boolean) args.get(0); + Long aNullableIntArg = (Long) args.get(1); + String aNullableStringArg = (String) args.get(2); + try { + AllNullableTypesWithoutRecursion output = + api.sendMultipleNullableTypesWithoutRecursion( + aNullableBoolArg, aNullableIntArg, aNullableStringArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -3029,29 +4271,22 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncDouble" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableInt" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Double aDoubleArg = (Double) args.get(0); - Result resultCallback = - new Result() { - public void success(Double result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.echoAsyncDouble(aDoubleArg, resultCallback); + Long aNullableIntArg = (Long) args.get(0); + try { + Long output = api.echoNullableInt(aNullableIntArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -3061,29 +4296,22 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncBool" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableDouble" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Boolean aBoolArg = (Boolean) args.get(0); - Result resultCallback = - new Result() { - public void success(Boolean result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.echoAsyncBool(aBoolArg, resultCallback); + Double aNullableDoubleArg = (Double) args.get(0); + try { + Double output = api.echoNullableDouble(aNullableDoubleArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -3093,29 +4321,22 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncString" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableBool" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - String aStringArg = (String) args.get(0); - Result resultCallback = - new Result() { - public void success(String result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.echoAsyncString(aStringArg, resultCallback); + Boolean aNullableBoolArg = (Boolean) args.get(0); + try { + Boolean output = api.echoNullableBool(aNullableBoolArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -3125,29 +4346,22 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncUint8List" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableString" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - byte[] aUint8ListArg = (byte[]) args.get(0); - Result resultCallback = - new Result() { - public void success(byte[] result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.echoAsyncUint8List(aUint8ListArg, resultCallback); + String aNullableStringArg = (String) args.get(0); + try { + String output = api.echoNullableString(aNullableStringArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -3157,29 +4371,22 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncObject" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableUint8List" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Object anObjectArg = args.get(0); - Result resultCallback = - new Result() { - public void success(Object result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.echoAsyncObject(anObjectArg, resultCallback); + byte[] aNullableUint8ListArg = (byte[]) args.get(0); + try { + byte[] output = api.echoNullableUint8List(aNullableUint8ListArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -3189,29 +4396,22 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncList" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableObject" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - List listArg = (List) args.get(0); - Result> resultCallback = - new Result>() { - public void success(List result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.echoAsyncList(listArg, resultCallback); + Object aNullableObjectArg = args.get(0); + try { + Object output = api.echoNullableObject(aNullableObjectArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -3221,29 +4421,22 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncMap" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableList" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Map aMapArg = (Map) args.get(0); - Result> resultCallback = - new Result>() { - public void success(Map result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.echoAsyncMap(aMapArg, resultCallback); + List aNullableListArg = (List) args.get(0); + try { + List output = api.echoNullableList(aNullableListArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -3253,29 +4446,22 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncEnum" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableEnumList" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - AnEnum anEnumArg = (AnEnum) args.get(0); - Result resultCallback = - new Result() { - public void success(AnEnum result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.echoAsyncEnum(anEnumArg, resultCallback); + List enumListArg = (List) args.get(0); + try { + List output = api.echoNullableEnumList(enumListArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -3285,27 +4471,22 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncError" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableClassList" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); - NullableResult resultCallback = - new NullableResult() { - public void success(Object result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.throwAsyncError(resultCallback); + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List classListArg = (List) args.get(0); + try { + List output = api.echoNullableClassList(classListArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -3315,27 +4496,22 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncErrorFromVoid" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullEnumList" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); - VoidResult resultCallback = - new VoidResult() { - public void success() { - wrapped.add(0, null); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.throwAsyncErrorFromVoid(resultCallback); + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List enumListArg = (List) args.get(0); + try { + List output = api.echoNullableNonNullEnumList(enumListArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -3345,27 +4521,22 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncFlutterError" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullClassList" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); - NullableResult resultCallback = - new NullableResult() { - public void success(Object result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.throwAsyncFlutterError(resultCallback); + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List classListArg = (List) args.get(0); + try { + List output = api.echoNullableNonNullClassList(classListArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -3375,29 +4546,22 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncAllTypes" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableMap" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - AllTypes everythingArg = (AllTypes) args.get(0); - Result resultCallback = - new Result() { - public void success(AllTypes result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.echoAsyncAllTypes(everythingArg, resultCallback); + Map mapArg = (Map) args.get(0); + try { + Map output = api.echoNullableMap(mapArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -3407,29 +4571,22 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypes" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableStringMap" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - AllNullableTypes everythingArg = (AllNullableTypes) args.get(0); - NullableResult resultCallback = - new NullableResult() { - public void success(AllNullableTypes result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.echoAsyncNullableAllNullableTypes(everythingArg, resultCallback); + Map stringMapArg = (Map) args.get(0); + try { + Map output = api.echoNullableStringMap(stringMapArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -3439,31 +4596,22 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypesWithoutRecursion" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableIntMap" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - AllNullableTypesWithoutRecursion everythingArg = - (AllNullableTypesWithoutRecursion) args.get(0); - NullableResult resultCallback = - new NullableResult() { - public void success(AllNullableTypesWithoutRecursion result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.echoAsyncNullableAllNullableTypesWithoutRecursion( - everythingArg, resultCallback); + Map intMapArg = (Map) args.get(0); + try { + Map output = api.echoNullableIntMap(intMapArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -3473,30 +4621,22 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableInt" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableEnumMap" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Number anIntArg = (Number) args.get(0); - NullableResult resultCallback = - new NullableResult() { - public void success(Long result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.echoAsyncNullableInt( - (anIntArg == null) ? null : anIntArg.longValue(), resultCallback); + Map enumMapArg = (Map) args.get(0); + try { + Map output = api.echoNullableEnumMap(enumMapArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -3506,29 +4646,22 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableDouble" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableClassMap" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Double aDoubleArg = (Double) args.get(0); - NullableResult resultCallback = - new NullableResult() { - public void success(Double result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.echoAsyncNullableDouble(aDoubleArg, resultCallback); + Map classMapArg = (Map) args.get(0); + try { + Map output = api.echoNullableClassMap(classMapArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -3538,29 +4671,22 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableBool" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullStringMap" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Boolean aBoolArg = (Boolean) args.get(0); - NullableResult resultCallback = - new NullableResult() { - public void success(Boolean result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.echoAsyncNullableBool(aBoolArg, resultCallback); + Map stringMapArg = (Map) args.get(0); + try { + Map output = api.echoNullableNonNullStringMap(stringMapArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -3570,29 +4696,22 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableString" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullIntMap" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - String aStringArg = (String) args.get(0); - NullableResult resultCallback = - new NullableResult() { - public void success(String result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.echoAsyncNullableString(aStringArg, resultCallback); + Map intMapArg = (Map) args.get(0); + try { + Map output = api.echoNullableNonNullIntMap(intMapArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -3602,29 +4721,22 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableUint8List" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullEnumMap" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - byte[] aUint8ListArg = (byte[]) args.get(0); - NullableResult resultCallback = - new NullableResult() { - public void success(byte[] result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.echoAsyncNullableUint8List(aUint8ListArg, resultCallback); + Map enumMapArg = (Map) args.get(0); + try { + Map output = api.echoNullableNonNullEnumMap(enumMapArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -3634,29 +4746,22 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableObject" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullClassMap" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Object anObjectArg = args.get(0); - NullableResult resultCallback = - new NullableResult() { - public void success(Object result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.echoAsyncNullableObject(anObjectArg, resultCallback); + Map classMapArg = (Map) args.get(0); + try { + Map output = api.echoNullableNonNullClassMap(classMapArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -3666,29 +4771,22 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableList" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableEnum" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - List listArg = (List) args.get(0); - NullableResult> resultCallback = - new NullableResult>() { - public void success(List result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.echoAsyncNullableList(listArg, resultCallback); + AnEnum anEnumArg = (AnEnum) args.get(0); + try { + AnEnum output = api.echoNullableEnum(anEnumArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -3698,29 +4796,22 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableMap" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAnotherNullableEnum" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Map aMapArg = (Map) args.get(0); - NullableResult> resultCallback = - new NullableResult>() { - public void success(Map result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.echoAsyncNullableMap(aMapArg, resultCallback); + AnotherEnum anotherEnumArg = (AnotherEnum) args.get(0); + try { + AnotherEnum output = api.echoAnotherNullableEnum(anotherEnumArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -3730,29 +4821,22 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableEnum" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoOptionalNullableInt" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - AnEnum anEnumArg = (AnEnum) args.get(0); - NullableResult resultCallback = - new NullableResult() { - public void success(AnEnum result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.echoAsyncNullableEnum(anEnumArg, resultCallback); + Long aNullableIntArg = (Long) args.get(0); + try { + Long output = api.echoOptionalNullableInt(aNullableIntArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); }); } else { channel.setMessageHandler(null); @@ -3762,13 +4846,38 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterNoop" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNamedNullableString" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + String aNullableStringArg = (String) args.get(0); + try { + String output = api.echoNamedNullableString(aNullableStringArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.noopAsync" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); VoidResult resultCallback = new VoidResult() { public void success() { @@ -3782,7 +4891,7 @@ public void error(Throwable error) { } }; - api.callFlutterNoop(resultCallback); + api.noopAsync(resultCallback); }); } else { channel.setMessageHandler(null); @@ -3792,16 +4901,18 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterThrowError" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncInt" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); - NullableResult resultCallback = - new NullableResult() { - public void success(Object result) { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Long anIntArg = (Long) args.get(0); + Result resultCallback = + new Result() { + public void success(Long result) { wrapped.add(0, result); reply.reply(wrapped); } @@ -3812,7 +4923,7 @@ public void error(Throwable error) { } }; - api.callFlutterThrowError(resultCallback); + api.echoAsyncInt(anIntArg, resultCallback); }); } else { channel.setMessageHandler(null); @@ -3822,17 +4933,19 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterThrowErrorFromVoid" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncDouble" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); - VoidResult resultCallback = - new VoidResult() { - public void success() { - wrapped.add(0, null); + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Double aDoubleArg = (Double) args.get(0); + Result resultCallback = + new Result() { + public void success(Double result) { + wrapped.add(0, result); reply.reply(wrapped); } @@ -3842,7 +4955,7 @@ public void error(Throwable error) { } }; - api.callFlutterThrowErrorFromVoid(resultCallback); + api.echoAsyncDouble(aDoubleArg, resultCallback); }); } else { channel.setMessageHandler(null); @@ -3852,18 +4965,18 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllTypes" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncBool" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - AllTypes everythingArg = (AllTypes) args.get(0); - Result resultCallback = - new Result() { - public void success(AllTypes result) { + Boolean aBoolArg = (Boolean) args.get(0); + Result resultCallback = + new Result() { + public void success(Boolean result) { wrapped.add(0, result); reply.reply(wrapped); } @@ -3874,7 +4987,7 @@ public void error(Throwable error) { } }; - api.callFlutterEchoAllTypes(everythingArg, resultCallback); + api.echoAsyncBool(aBoolArg, resultCallback); }); } else { channel.setMessageHandler(null); @@ -3884,18 +4997,18 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypes" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncString" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - AllNullableTypes everythingArg = (AllNullableTypes) args.get(0); - NullableResult resultCallback = - new NullableResult() { - public void success(AllNullableTypes result) { + String aStringArg = (String) args.get(0); + Result resultCallback = + new Result() { + public void success(String result) { wrapped.add(0, result); reply.reply(wrapped); } @@ -3906,7 +5019,7 @@ public void error(Throwable error) { } }; - api.callFlutterEchoAllNullableTypes(everythingArg, resultCallback); + api.echoAsyncString(aStringArg, resultCallback); }); } else { channel.setMessageHandler(null); @@ -3916,20 +5029,18 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypes" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncUint8List" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Boolean aNullableBoolArg = (Boolean) args.get(0); - Number aNullableIntArg = (Number) args.get(1); - String aNullableStringArg = (String) args.get(2); - Result resultCallback = - new Result() { - public void success(AllNullableTypes result) { + byte[] aUint8ListArg = (byte[]) args.get(0); + Result resultCallback = + new Result() { + public void success(byte[] result) { wrapped.add(0, result); reply.reply(wrapped); } @@ -3940,11 +5051,7 @@ public void error(Throwable error) { } }; - api.callFlutterSendMultipleNullableTypes( - aNullableBoolArg, - (aNullableIntArg == null) ? null : aNullableIntArg.longValue(), - aNullableStringArg, - resultCallback); + api.echoAsyncUint8List(aUint8ListArg, resultCallback); }); } else { channel.setMessageHandler(null); @@ -3954,19 +5061,18 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypesWithoutRecursion" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncObject" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - AllNullableTypesWithoutRecursion everythingArg = - (AllNullableTypesWithoutRecursion) args.get(0); - NullableResult resultCallback = - new NullableResult() { - public void success(AllNullableTypesWithoutRecursion result) { + Object anObjectArg = args.get(0); + Result resultCallback = + new Result() { + public void success(Object result) { wrapped.add(0, result); reply.reply(wrapped); } @@ -3977,7 +5083,7 @@ public void error(Throwable error) { } }; - api.callFlutterEchoAllNullableTypesWithoutRecursion(everythingArg, resultCallback); + api.echoAsyncObject(anObjectArg, resultCallback); }); } else { channel.setMessageHandler(null); @@ -3987,20 +5093,18 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypesWithoutRecursion" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncList" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Boolean aNullableBoolArg = (Boolean) args.get(0); - Number aNullableIntArg = (Number) args.get(1); - String aNullableStringArg = (String) args.get(2); - Result resultCallback = - new Result() { - public void success(AllNullableTypesWithoutRecursion result) { + List listArg = (List) args.get(0); + Result> resultCallback = + new Result>() { + public void success(List result) { wrapped.add(0, result); reply.reply(wrapped); } @@ -4011,11 +5115,7 @@ public void error(Throwable error) { } }; - api.callFlutterSendMultipleNullableTypesWithoutRecursion( - aNullableBoolArg, - (aNullableIntArg == null) ? null : aNullableIntArg.longValue(), - aNullableStringArg, - resultCallback); + api.echoAsyncList(listArg, resultCallback); }); } else { channel.setMessageHandler(null); @@ -4025,18 +5125,18 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoBool" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncEnumList" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Boolean aBoolArg = (Boolean) args.get(0); - Result resultCallback = - new Result() { - public void success(Boolean result) { + List enumListArg = (List) args.get(0); + Result> resultCallback = + new Result>() { + public void success(List result) { wrapped.add(0, result); reply.reply(wrapped); } @@ -4047,7 +5147,7 @@ public void error(Throwable error) { } }; - api.callFlutterEchoBool(aBoolArg, resultCallback); + api.echoAsyncEnumList(enumListArg, resultCallback); }); } else { channel.setMessageHandler(null); @@ -4057,18 +5157,18 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoInt" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncClassList" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Number anIntArg = (Number) args.get(0); - Result resultCallback = - new Result() { - public void success(Long result) { + List classListArg = (List) args.get(0); + Result> resultCallback = + new Result>() { + public void success(List result) { wrapped.add(0, result); reply.reply(wrapped); } @@ -4079,8 +5179,7 @@ public void error(Throwable error) { } }; - api.callFlutterEchoInt( - (anIntArg == null) ? null : anIntArg.longValue(), resultCallback); + api.echoAsyncClassList(classListArg, resultCallback); }); } else { channel.setMessageHandler(null); @@ -4090,18 +5189,18 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoDouble" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncMap" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Double aDoubleArg = (Double) args.get(0); - Result resultCallback = - new Result() { - public void success(Double result) { + Map mapArg = (Map) args.get(0); + Result> resultCallback = + new Result>() { + public void success(Map result) { wrapped.add(0, result); reply.reply(wrapped); } @@ -4112,7 +5211,7 @@ public void error(Throwable error) { } }; - api.callFlutterEchoDouble(aDoubleArg, resultCallback); + api.echoAsyncMap(mapArg, resultCallback); }); } else { channel.setMessageHandler(null); @@ -4122,18 +5221,18 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoString" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncStringMap" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - String aStringArg = (String) args.get(0); - Result resultCallback = - new Result() { - public void success(String result) { + Map stringMapArg = (Map) args.get(0); + Result> resultCallback = + new Result>() { + public void success(Map result) { wrapped.add(0, result); reply.reply(wrapped); } @@ -4144,7 +5243,7 @@ public void error(Throwable error) { } }; - api.callFlutterEchoString(aStringArg, resultCallback); + api.echoAsyncStringMap(stringMapArg, resultCallback); }); } else { channel.setMessageHandler(null); @@ -4154,18 +5253,18 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoUint8List" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncIntMap" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - byte[] listArg = (byte[]) args.get(0); - Result resultCallback = - new Result() { - public void success(byte[] result) { + Map intMapArg = (Map) args.get(0); + Result> resultCallback = + new Result>() { + public void success(Map result) { wrapped.add(0, result); reply.reply(wrapped); } @@ -4176,7 +5275,7 @@ public void error(Throwable error) { } }; - api.callFlutterEchoUint8List(listArg, resultCallback); + api.echoAsyncIntMap(intMapArg, resultCallback); }); } else { channel.setMessageHandler(null); @@ -4186,18 +5285,18 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoList" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncEnumMap" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - List listArg = (List) args.get(0); - Result> resultCallback = - new Result>() { - public void success(List result) { + Map enumMapArg = (Map) args.get(0); + Result> resultCallback = + new Result>() { + public void success(Map result) { wrapped.add(0, result); reply.reply(wrapped); } @@ -4208,7 +5307,7 @@ public void error(Throwable error) { } }; - api.callFlutterEchoList(listArg, resultCallback); + api.echoAsyncEnumMap(enumMapArg, resultCallback); }); } else { channel.setMessageHandler(null); @@ -4218,18 +5317,18 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoMap" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncClassMap" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Map aMapArg = (Map) args.get(0); - Result> resultCallback = - new Result>() { - public void success(Map result) { + Map classMapArg = (Map) args.get(0); + Result> resultCallback = + new Result>() { + public void success(Map result) { wrapped.add(0, result); reply.reply(wrapped); } @@ -4240,7 +5339,7 @@ public void error(Throwable error) { } }; - api.callFlutterEchoMap(aMapArg, resultCallback); + api.echoAsyncClassMap(classMapArg, resultCallback); }); } else { channel.setMessageHandler(null); @@ -4250,13 +5349,13 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoEnum" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncEnum" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; AnEnum anEnumArg = (AnEnum) args.get(0); Result resultCallback = @@ -4272,7 +5371,7 @@ public void error(Throwable error) { } }; - api.callFlutterEchoEnum(anEnumArg, resultCallback); + api.echoAsyncEnum(anEnumArg, resultCallback); }); } else { channel.setMessageHandler(null); @@ -4282,18 +5381,18 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableBool" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAnotherAsyncEnum" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Boolean aBoolArg = (Boolean) args.get(0); - NullableResult resultCallback = - new NullableResult() { - public void success(Boolean result) { + AnotherEnum anotherEnumArg = (AnotherEnum) args.get(0); + Result resultCallback = + new Result() { + public void success(AnotherEnum result) { wrapped.add(0, result); reply.reply(wrapped); } @@ -4304,7 +5403,7 @@ public void error(Throwable error) { } }; - api.callFlutterEchoNullableBool(aBoolArg, resultCallback); + api.echoAnotherAsyncEnum(anotherEnumArg, resultCallback); }); } else { channel.setMessageHandler(null); @@ -4314,16 +5413,204 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableInt" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncError" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); - ArrayList args = (ArrayList) message; - Number anIntArg = (Number) args.get(0); - NullableResult resultCallback = + ArrayList wrapped = new ArrayList<>(); + NullableResult resultCallback = + new NullableResult() { + public void success(Object result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.throwAsyncError(resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncErrorFromVoid" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + VoidResult resultCallback = + new VoidResult() { + public void success() { + wrapped.add(0, null); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.throwAsyncErrorFromVoid(resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncFlutterError" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + NullableResult resultCallback = + new NullableResult() { + public void success(Object result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.throwAsyncFlutterError(resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncAllTypes" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + AllTypes everythingArg = (AllTypes) args.get(0); + Result resultCallback = + new Result() { + public void success(AllTypes result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.echoAsyncAllTypes(everythingArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypes" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + AllNullableTypes everythingArg = (AllNullableTypes) args.get(0); + NullableResult resultCallback = + new NullableResult() { + public void success(AllNullableTypes result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.echoAsyncNullableAllNullableTypes(everythingArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypesWithoutRecursion" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + AllNullableTypesWithoutRecursion everythingArg = + (AllNullableTypesWithoutRecursion) args.get(0); + NullableResult resultCallback = + new NullableResult() { + public void success(AllNullableTypesWithoutRecursion result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.echoAsyncNullableAllNullableTypesWithoutRecursion( + everythingArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableInt" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Long anIntArg = (Long) args.get(0); + NullableResult resultCallback = new NullableResult() { public void success(Long result) { wrapped.add(0, result); @@ -4336,8 +5623,7 @@ public void error(Throwable error) { } }; - api.callFlutterEchoNullableInt( - (anIntArg == null) ? null : anIntArg.longValue(), resultCallback); + api.echoAsyncNullableInt(anIntArg, resultCallback); }); } else { channel.setMessageHandler(null); @@ -4347,13 +5633,13 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableDouble" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableDouble" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; Double aDoubleArg = (Double) args.get(0); NullableResult resultCallback = @@ -4369,7 +5655,7 @@ public void error(Throwable error) { } }; - api.callFlutterEchoNullableDouble(aDoubleArg, resultCallback); + api.echoAsyncNullableDouble(aDoubleArg, resultCallback); }); } else { channel.setMessageHandler(null); @@ -4379,18 +5665,18 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableString" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableBool" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - String aStringArg = (String) args.get(0); - NullableResult resultCallback = - new NullableResult() { - public void success(String result) { + Boolean aBoolArg = (Boolean) args.get(0); + NullableResult resultCallback = + new NullableResult() { + public void success(Boolean result) { wrapped.add(0, result); reply.reply(wrapped); } @@ -4401,7 +5687,7 @@ public void error(Throwable error) { } }; - api.callFlutterEchoNullableString(aStringArg, resultCallback); + api.echoAsyncNullableBool(aBoolArg, resultCallback); }); } else { channel.setMessageHandler(null); @@ -4411,18 +5697,18 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableUint8List" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableString" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - byte[] listArg = (byte[]) args.get(0); - NullableResult resultCallback = - new NullableResult() { - public void success(byte[] result) { + String aStringArg = (String) args.get(0); + NullableResult resultCallback = + new NullableResult() { + public void success(String result) { wrapped.add(0, result); reply.reply(wrapped); } @@ -4433,7 +5719,7 @@ public void error(Throwable error) { } }; - api.callFlutterEchoNullableUint8List(listArg, resultCallback); + api.echoAsyncNullableString(aStringArg, resultCallback); }); } else { channel.setMessageHandler(null); @@ -4443,18 +5729,18 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableList" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableUint8List" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - List listArg = (List) args.get(0); - NullableResult> resultCallback = - new NullableResult>() { - public void success(List result) { + byte[] aUint8ListArg = (byte[]) args.get(0); + NullableResult resultCallback = + new NullableResult() { + public void success(byte[] result) { wrapped.add(0, result); reply.reply(wrapped); } @@ -4465,7 +5751,7 @@ public void error(Throwable error) { } }; - api.callFlutterEchoNullableList(listArg, resultCallback); + api.echoAsyncNullableUint8List(aUint8ListArg, resultCallback); }); } else { channel.setMessageHandler(null); @@ -4475,18 +5761,18 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableMap" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableObject" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - Map aMapArg = (Map) args.get(0); - NullableResult> resultCallback = - new NullableResult>() { - public void success(Map result) { + Object anObjectArg = args.get(0); + NullableResult resultCallback = + new NullableResult() { + public void success(Object result) { wrapped.add(0, result); reply.reply(wrapped); } @@ -4497,7 +5783,7 @@ public void error(Throwable error) { } }; - api.callFlutterEchoNullableMap(aMapArg, resultCallback); + api.echoAsyncNullableObject(anObjectArg, resultCallback); }); } else { channel.setMessageHandler(null); @@ -4507,18 +5793,18 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableEnum" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableList" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - AnEnum anEnumArg = (AnEnum) args.get(0); - NullableResult resultCallback = - new NullableResult() { - public void success(AnEnum result) { + List listArg = (List) args.get(0); + NullableResult> resultCallback = + new NullableResult>() { + public void success(List result) { wrapped.add(0, result); reply.reply(wrapped); } @@ -4529,7 +5815,7 @@ public void error(Throwable error) { } }; - api.callFlutterEchoNullableEnum(anEnumArg, resultCallback); + api.echoAsyncNullableList(listArg, resultCallback); }); } else { channel.setMessageHandler(null); @@ -4539,18 +5825,18 @@ public void error(Throwable error) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSmallApiEchoString" + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableEnumList" + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - String aStringArg = (String) args.get(0); - Result resultCallback = - new Result() { - public void success(String result) { + List enumListArg = (List) args.get(0); + NullableResult> resultCallback = + new NullableResult>() { + public void success(List result) { wrapped.add(0, result); reply.reply(wrapped); } @@ -4561,88 +5847,2791 @@ public void error(Throwable error) { } }; - api.callFlutterSmallApiEchoString(aStringArg, resultCallback); + api.echoAsyncNullableEnumList(enumListArg, resultCallback); }); } else { channel.setMessageHandler(null); } } - } - } - /** - * The core interface that the Dart platform_test code implements for host integration tests to - * call into. - * - *

Generated class from Pigeon that represents Flutter messages that can be called from Java. - */ - public static class FlutterIntegrationCoreApi { - private final @NonNull BinaryMessenger binaryMessenger; - private final String messageChannelSuffix; + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableClassList" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List classListArg = (List) args.get(0); + NullableResult> resultCallback = + new NullableResult>() { + public void success(List result) { + wrapped.add(0, result); + reply.reply(wrapped); + } - public FlutterIntegrationCoreApi(@NonNull BinaryMessenger argBinaryMessenger) { - this(argBinaryMessenger, ""); + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.echoAsyncNullableClassList(classListArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableMap" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Map mapArg = (Map) args.get(0); + NullableResult> resultCallback = + new NullableResult>() { + public void success(Map result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.echoAsyncNullableMap(mapArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableStringMap" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Map stringMapArg = (Map) args.get(0); + NullableResult> resultCallback = + new NullableResult>() { + public void success(Map result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.echoAsyncNullableStringMap(stringMapArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableIntMap" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Map intMapArg = (Map) args.get(0); + NullableResult> resultCallback = + new NullableResult>() { + public void success(Map result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.echoAsyncNullableIntMap(intMapArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableEnumMap" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Map enumMapArg = (Map) args.get(0); + NullableResult> resultCallback = + new NullableResult>() { + public void success(Map result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.echoAsyncNullableEnumMap(enumMapArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableClassMap" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Map classMapArg = (Map) args.get(0); + NullableResult> resultCallback = + new NullableResult>() { + public void success(Map result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.echoAsyncNullableClassMap(classMapArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableEnum" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + AnEnum anEnumArg = (AnEnum) args.get(0); + NullableResult resultCallback = + new NullableResult() { + public void success(AnEnum result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.echoAsyncNullableEnum(anEnumArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAnotherAsyncNullableEnum" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + AnotherEnum anotherEnumArg = (AnotherEnum) args.get(0); + NullableResult resultCallback = + new NullableResult() { + public void success(AnotherEnum result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.echoAnotherAsyncNullableEnum(anotherEnumArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterNoop" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + VoidResult resultCallback = + new VoidResult() { + public void success() { + wrapped.add(0, null); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterNoop(resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterThrowError" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + NullableResult resultCallback = + new NullableResult() { + public void success(Object result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterThrowError(resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterThrowErrorFromVoid" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + VoidResult resultCallback = + new VoidResult() { + public void success() { + wrapped.add(0, null); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterThrowErrorFromVoid(resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllTypes" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + AllTypes everythingArg = (AllTypes) args.get(0); + Result resultCallback = + new Result() { + public void success(AllTypes result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoAllTypes(everythingArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypes" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + AllNullableTypes everythingArg = (AllNullableTypes) args.get(0); + NullableResult resultCallback = + new NullableResult() { + public void success(AllNullableTypes result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoAllNullableTypes(everythingArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypes" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Boolean aNullableBoolArg = (Boolean) args.get(0); + Long aNullableIntArg = (Long) args.get(1); + String aNullableStringArg = (String) args.get(2); + Result resultCallback = + new Result() { + public void success(AllNullableTypes result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterSendMultipleNullableTypes( + aNullableBoolArg, aNullableIntArg, aNullableStringArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypesWithoutRecursion" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + AllNullableTypesWithoutRecursion everythingArg = + (AllNullableTypesWithoutRecursion) args.get(0); + NullableResult resultCallback = + new NullableResult() { + public void success(AllNullableTypesWithoutRecursion result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoAllNullableTypesWithoutRecursion(everythingArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypesWithoutRecursion" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Boolean aNullableBoolArg = (Boolean) args.get(0); + Long aNullableIntArg = (Long) args.get(1); + String aNullableStringArg = (String) args.get(2); + Result resultCallback = + new Result() { + public void success(AllNullableTypesWithoutRecursion result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterSendMultipleNullableTypesWithoutRecursion( + aNullableBoolArg, aNullableIntArg, aNullableStringArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoBool" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Boolean aBoolArg = (Boolean) args.get(0); + Result resultCallback = + new Result() { + public void success(Boolean result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoBool(aBoolArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoInt" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Long anIntArg = (Long) args.get(0); + Result resultCallback = + new Result() { + public void success(Long result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoInt(anIntArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoDouble" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Double aDoubleArg = (Double) args.get(0); + Result resultCallback = + new Result() { + public void success(Double result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoDouble(aDoubleArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoString" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + String aStringArg = (String) args.get(0); + Result resultCallback = + new Result() { + public void success(String result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoString(aStringArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoUint8List" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + byte[] listArg = (byte[]) args.get(0); + Result resultCallback = + new Result() { + public void success(byte[] result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoUint8List(listArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoList" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List listArg = (List) args.get(0); + Result> resultCallback = + new Result>() { + public void success(List result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoList(listArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoEnumList" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List enumListArg = (List) args.get(0); + Result> resultCallback = + new Result>() { + public void success(List result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoEnumList(enumListArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoClassList" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List classListArg = (List) args.get(0); + Result> resultCallback = + new Result>() { + public void success(List result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoClassList(classListArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullEnumList" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List enumListArg = (List) args.get(0); + Result> resultCallback = + new Result>() { + public void success(List result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNonNullEnumList(enumListArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullClassList" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List classListArg = (List) args.get(0); + Result> resultCallback = + new Result>() { + public void success(List result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNonNullClassList(classListArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoMap" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Map mapArg = (Map) args.get(0); + Result> resultCallback = + new Result>() { + public void success(Map result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoMap(mapArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoStringMap" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Map stringMapArg = (Map) args.get(0); + Result> resultCallback = + new Result>() { + public void success(Map result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoStringMap(stringMapArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoIntMap" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Map intMapArg = (Map) args.get(0); + Result> resultCallback = + new Result>() { + public void success(Map result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoIntMap(intMapArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoEnumMap" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Map enumMapArg = (Map) args.get(0); + Result> resultCallback = + new Result>() { + public void success(Map result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoEnumMap(enumMapArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoClassMap" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Map classMapArg = (Map) args.get(0); + Result> resultCallback = + new Result>() { + public void success(Map result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoClassMap(classMapArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullStringMap" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Map stringMapArg = (Map) args.get(0); + Result> resultCallback = + new Result>() { + public void success(Map result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNonNullStringMap(stringMapArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullIntMap" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Map intMapArg = (Map) args.get(0); + Result> resultCallback = + new Result>() { + public void success(Map result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNonNullIntMap(intMapArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullEnumMap" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Map enumMapArg = (Map) args.get(0); + Result> resultCallback = + new Result>() { + public void success(Map result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNonNullEnumMap(enumMapArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullClassMap" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Map classMapArg = (Map) args.get(0); + Result> resultCallback = + new Result>() { + public void success(Map result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNonNullClassMap(classMapArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoEnum" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + AnEnum anEnumArg = (AnEnum) args.get(0); + Result resultCallback = + new Result() { + public void success(AnEnum result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoEnum(anEnumArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAnotherEnum" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + AnotherEnum anotherEnumArg = (AnotherEnum) args.get(0); + Result resultCallback = + new Result() { + public void success(AnotherEnum result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoAnotherEnum(anotherEnumArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableBool" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Boolean aBoolArg = (Boolean) args.get(0); + NullableResult resultCallback = + new NullableResult() { + public void success(Boolean result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNullableBool(aBoolArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableInt" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Long anIntArg = (Long) args.get(0); + NullableResult resultCallback = + new NullableResult() { + public void success(Long result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNullableInt(anIntArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableDouble" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Double aDoubleArg = (Double) args.get(0); + NullableResult resultCallback = + new NullableResult() { + public void success(Double result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNullableDouble(aDoubleArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableString" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + String aStringArg = (String) args.get(0); + NullableResult resultCallback = + new NullableResult() { + public void success(String result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNullableString(aStringArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableUint8List" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + byte[] listArg = (byte[]) args.get(0); + NullableResult resultCallback = + new NullableResult() { + public void success(byte[] result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNullableUint8List(listArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableList" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List listArg = (List) args.get(0); + NullableResult> resultCallback = + new NullableResult>() { + public void success(List result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNullableList(listArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableEnumList" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List enumListArg = (List) args.get(0); + NullableResult> resultCallback = + new NullableResult>() { + public void success(List result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNullableEnumList(enumListArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableClassList" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List classListArg = (List) args.get(0); + NullableResult> resultCallback = + new NullableResult>() { + public void success(List result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNullableClassList(classListArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullEnumList" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List enumListArg = (List) args.get(0); + NullableResult> resultCallback = + new NullableResult>() { + public void success(List result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNullableNonNullEnumList(enumListArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullClassList" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List classListArg = (List) args.get(0); + NullableResult> resultCallback = + new NullableResult>() { + public void success(List result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNullableNonNullClassList(classListArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableMap" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Map mapArg = (Map) args.get(0); + NullableResult> resultCallback = + new NullableResult>() { + public void success(Map result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNullableMap(mapArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableStringMap" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Map stringMapArg = (Map) args.get(0); + NullableResult> resultCallback = + new NullableResult>() { + public void success(Map result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNullableStringMap(stringMapArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableIntMap" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Map intMapArg = (Map) args.get(0); + NullableResult> resultCallback = + new NullableResult>() { + public void success(Map result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNullableIntMap(intMapArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableEnumMap" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Map enumMapArg = (Map) args.get(0); + NullableResult> resultCallback = + new NullableResult>() { + public void success(Map result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNullableEnumMap(enumMapArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableClassMap" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Map classMapArg = (Map) args.get(0); + NullableResult> resultCallback = + new NullableResult>() { + public void success(Map result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNullableClassMap(classMapArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullStringMap" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Map stringMapArg = (Map) args.get(0); + NullableResult> resultCallback = + new NullableResult>() { + public void success(Map result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNullableNonNullStringMap(stringMapArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullIntMap" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Map intMapArg = (Map) args.get(0); + NullableResult> resultCallback = + new NullableResult>() { + public void success(Map result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNullableNonNullIntMap(intMapArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullEnumMap" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Map enumMapArg = (Map) args.get(0); + NullableResult> resultCallback = + new NullableResult>() { + public void success(Map result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNullableNonNullEnumMap(enumMapArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullClassMap" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Map classMapArg = (Map) args.get(0); + NullableResult> resultCallback = + new NullableResult>() { + public void success(Map result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNullableNonNullClassMap(classMapArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableEnum" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + AnEnum anEnumArg = (AnEnum) args.get(0); + NullableResult resultCallback = + new NullableResult() { + public void success(AnEnum result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoNullableEnum(anEnumArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAnotherNullableEnum" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + AnotherEnum anotherEnumArg = (AnotherEnum) args.get(0); + NullableResult resultCallback = + new NullableResult() { + public void success(AnotherEnum result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoAnotherNullableEnum(anotherEnumArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSmallApiEchoString" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + String aStringArg = (String) args.get(0); + Result resultCallback = + new Result() { + public void success(String result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterSmallApiEchoString(aStringArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + } + } + /** + * The core interface that the Dart platform_test code implements for host integration tests to + * call into. + * + *

Generated class from Pigeon that represents Flutter messages that can be called from Java. + */ + public static class FlutterIntegrationCoreApi { + private final @NonNull BinaryMessenger binaryMessenger; + private final String messageChannelSuffix; + + public FlutterIntegrationCoreApi(@NonNull BinaryMessenger argBinaryMessenger) { + this(argBinaryMessenger, ""); + } + + public FlutterIntegrationCoreApi( + @NonNull BinaryMessenger argBinaryMessenger, @NonNull String messageChannelSuffix) { + this.binaryMessenger = argBinaryMessenger; + this.messageChannelSuffix = messageChannelSuffix.isEmpty() ? "" : "." + messageChannelSuffix; + } + + /** Public interface for sending reply. The codec used by FlutterIntegrationCoreApi. */ + static @NonNull MessageCodec getCodec() { + return PigeonCodec.INSTANCE; + } + /** + * A no-op function taking no arguments and returning no value, to sanity test basic calling. + */ + public void noop(@NonNull VoidResult result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.noop" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + null, + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else { + result.success(); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Responds with an error from an async function returning a value. */ + public void throwError(@NonNull NullableResult result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwError" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + null, + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else { + @SuppressWarnings("ConstantConditions") + Object output = listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Responds with an error from an async void function. */ + public void throwErrorFromVoid(@NonNull VoidResult result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwErrorFromVoid" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + null, + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else { + result.success(); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Returns the passed object, to test serialization and deserialization. */ + public void echoAllTypes(@NonNull AllTypes everythingArg, @NonNull Result result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllTypes" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(everythingArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); + } else { + @SuppressWarnings("ConstantConditions") + AllTypes output = (AllTypes) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Returns the passed object, to test serialization and deserialization. */ + public void echoAllNullableTypes( + @Nullable AllNullableTypes everythingArg, + @NonNull NullableResult result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypes" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(everythingArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else { + @SuppressWarnings("ConstantConditions") + AllNullableTypes output = (AllNullableTypes) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** + * Returns passed in arguments of multiple types. + * + *

Tests multiple-arity FlutterApi handling. + */ + public void sendMultipleNullableTypes( + @Nullable Boolean aNullableBoolArg, + @Nullable Long aNullableIntArg, + @Nullable String aNullableStringArg, + @NonNull Result result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypes" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Arrays.asList(aNullableBoolArg, aNullableIntArg, aNullableStringArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); + } else { + @SuppressWarnings("ConstantConditions") + AllNullableTypes output = (AllNullableTypes) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Returns the passed object, to test serialization and deserialization. */ + public void echoAllNullableTypesWithoutRecursion( + @Nullable AllNullableTypesWithoutRecursion everythingArg, + @NonNull NullableResult result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypesWithoutRecursion" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(everythingArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else { + @SuppressWarnings("ConstantConditions") + AllNullableTypesWithoutRecursion output = + (AllNullableTypesWithoutRecursion) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** + * Returns passed in arguments of multiple types. + * + *

Tests multiple-arity FlutterApi handling. + */ + public void sendMultipleNullableTypesWithoutRecursion( + @Nullable Boolean aNullableBoolArg, + @Nullable Long aNullableIntArg, + @Nullable String aNullableStringArg, + @NonNull Result result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Arrays.asList(aNullableBoolArg, aNullableIntArg, aNullableStringArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); + } else { + @SuppressWarnings("ConstantConditions") + AllNullableTypesWithoutRecursion output = + (AllNullableTypesWithoutRecursion) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Returns the passed boolean, to test serialization and deserialization. */ + public void echoBool(@NonNull Boolean aBoolArg, @NonNull Result result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoBool" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(aBoolArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); + } else { + @SuppressWarnings("ConstantConditions") + Boolean output = (Boolean) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Returns the passed int, to test serialization and deserialization. */ + public void echoInt(@NonNull Long anIntArg, @NonNull Result result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoInt" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(anIntArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); + } else { + @SuppressWarnings("ConstantConditions") + Long output = (Long) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Returns the passed double, to test serialization and deserialization. */ + public void echoDouble(@NonNull Double aDoubleArg, @NonNull Result result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoDouble" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(aDoubleArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); + } else { + @SuppressWarnings("ConstantConditions") + Double output = (Double) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Returns the passed string, to test serialization and deserialization. */ + public void echoString(@NonNull String aStringArg, @NonNull Result result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoString" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(aStringArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); + } else { + @SuppressWarnings("ConstantConditions") + String output = (String) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Returns the passed byte list, to test serialization and deserialization. */ + public void echoUint8List(@NonNull byte[] listArg, @NonNull Result result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoUint8List" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(listArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); + } else { + @SuppressWarnings("ConstantConditions") + byte[] output = (byte[]) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Returns the passed list, to test serialization and deserialization. */ + public void echoList(@NonNull List listArg, @NonNull Result> result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoList" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(listArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); + } else { + @SuppressWarnings("ConstantConditions") + List output = (List) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Returns the passed list, to test serialization and deserialization. */ + public void echoEnumList( + @NonNull List enumListArg, @NonNull Result> result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnumList" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(enumListArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); + } else { + @SuppressWarnings("ConstantConditions") + List output = (List) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Returns the passed list, to test serialization and deserialization. */ + public void echoClassList( + @NonNull List classListArg, + @NonNull Result> result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoClassList" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(classListArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); + } else { + @SuppressWarnings("ConstantConditions") + List output = (List) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Returns the passed list, to test serialization and deserialization. */ + public void echoNonNullEnumList( + @NonNull List enumListArg, @NonNull Result> result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullEnumList" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(enumListArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); + } else { + @SuppressWarnings("ConstantConditions") + List output = (List) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); } - - public FlutterIntegrationCoreApi( - @NonNull BinaryMessenger argBinaryMessenger, @NonNull String messageChannelSuffix) { - this.binaryMessenger = argBinaryMessenger; - this.messageChannelSuffix = messageChannelSuffix.isEmpty() ? "" : "." + messageChannelSuffix; + /** Returns the passed list, to test serialization and deserialization. */ + public void echoNonNullClassList( + @NonNull List classListArg, + @NonNull Result> result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullClassList" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(classListArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); + } else { + @SuppressWarnings("ConstantConditions") + List output = (List) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); } - - /** Public interface for sending reply. */ - /** The codec used by FlutterIntegrationCoreApi. */ - static @NonNull MessageCodec getCodec() { - return PigeonCodec.INSTANCE; + /** Returns the passed map, to test serialization and deserialization. */ + public void echoMap( + @NonNull Map mapArg, @NonNull Result> result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoMap" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(mapArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); + } else { + @SuppressWarnings("ConstantConditions") + Map output = (Map) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); } - /** - * A no-op function taking no arguments and returning no value, to sanity test basic calling. - */ - public void noop(@NonNull VoidResult result) { + /** Returns the passed map, to test serialization and deserialization. */ + public void echoStringMap( + @NonNull Map stringMapArg, @NonNull Result> result) { final String channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.noop" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoStringMap" + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - null, + new ArrayList<>(Collections.singletonList(stringMapArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); + } else { + @SuppressWarnings("ConstantConditions") + Map output = (Map) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Returns the passed map, to test serialization and deserialization. */ + public void echoIntMap( + @NonNull Map intMapArg, @NonNull Result> result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoIntMap" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(intMapArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); + } else { + @SuppressWarnings("ConstantConditions") + Map output = (Map) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Returns the passed map, to test serialization and deserialization. */ + public void echoEnumMap( + @NonNull Map enumMapArg, @NonNull Result> result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnumMap" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(enumMapArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); + } else { + @SuppressWarnings("ConstantConditions") + Map output = (Map) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Returns the passed map, to test serialization and deserialization. */ + public void echoClassMap( + @NonNull Map classMapArg, + @NonNull Result> result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoClassMap" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(classMapArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); + } else { + @SuppressWarnings("ConstantConditions") + Map output = (Map) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Returns the passed map, to test serialization and deserialization. */ + public void echoNonNullStringMap( + @NonNull Map stringMapArg, @NonNull Result> result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullStringMap" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(stringMapArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); + } else { + @SuppressWarnings("ConstantConditions") + Map output = (Map) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Returns the passed map, to test serialization and deserialization. */ + public void echoNonNullIntMap( + @NonNull Map intMapArg, @NonNull Result> result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullIntMap" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(intMapArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); + } else { + @SuppressWarnings("ConstantConditions") + Map output = (Map) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** Returns the passed map, to test serialization and deserialization. */ + public void echoNonNullEnumMap( + @NonNull Map enumMapArg, @NonNull Result> result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullEnumMap" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(enumMapArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); } else { - result.success(); + @SuppressWarnings("ConstantConditions") + Map output = (Map) listReply.get(0); + result.success(output); } } else { result.error(createConnectionError(channelName)); } }); } - /** Responds with an error from an async function returning a value. */ - public void throwError(@NonNull NullableResult result) { + /** Returns the passed map, to test serialization and deserialization. */ + public void echoNonNullClassMap( + @NonNull Map classMapArg, + @NonNull Result> result) { final String channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwError" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullClassMap" + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - null, + new ArrayList<>(Collections.singletonList(classMapArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); } else { @SuppressWarnings("ConstantConditions") - Object output = listReply.get(0); + Map output = (Map) listReply.get(0); result.success(output); } } else { @@ -4650,50 +8639,55 @@ public void throwError(@NonNull NullableResult result) { } }); } - /** Responds with an error from an async void function. */ - public void throwErrorFromVoid(@NonNull VoidResult result) { + /** Returns the passed enum to test serialization and deserialization. */ + public void echoEnum(@NonNull AnEnum anEnumArg, @NonNull Result result) { final String channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwErrorFromVoid" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnum" + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - null, + new ArrayList<>(Collections.singletonList(anEnumArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); } else { - result.success(); + @SuppressWarnings("ConstantConditions") + AnEnum output = (AnEnum) listReply.get(0); + result.success(output); } } else { result.error(createConnectionError(channelName)); } }); } - /** Returns the passed object, to test serialization and deserialization. */ - public void echoAllTypes(@NonNull AllTypes everythingArg, @NonNull Result result) { + /** Returns the passed enum to test serialization and deserialization. */ + public void echoAnotherEnum( + @NonNull AnotherEnum anotherEnumArg, @NonNull Result result) { final String channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllTypes" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAnotherEnum" + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(everythingArg)), + new ArrayList<>(Collections.singletonList(anotherEnumArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else if (listReply.get(0) == null) { result.error( new FlutterError( @@ -4702,7 +8696,7 @@ public void echoAllTypes(@NonNull AllTypes everythingArg, @NonNull Result result) { + /** Returns the passed boolean, to test serialization and deserialization. */ + public void echoNullableBool( + @Nullable Boolean aBoolArg, @NonNull NullableResult result) { final String channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypes" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableBool" + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(everythingArg)), + new ArrayList<>(Collections.singletonList(aBoolArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else { @SuppressWarnings("ConstantConditions") - AllNullableTypes output = (AllNullableTypes) listReply.get(0); + Boolean output = (Boolean) listReply.get(0); result.success(output); } } else { @@ -4740,42 +8731,25 @@ public void echoAllNullableTypes( } }); } - /** - * Returns passed in arguments of multiple types. - * - *

Tests multiple-arity FlutterApi handling. - */ - public void sendMultipleNullableTypes( - @Nullable Boolean aNullableBoolArg, - @Nullable Long aNullableIntArg, - @Nullable String aNullableStringArg, - @NonNull Result result) { + /** Returns the passed int, to test serialization and deserialization. */ + public void echoNullableInt(@Nullable Long anIntArg, @NonNull NullableResult result) { final String channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypes" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableInt" + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList( - Arrays.asList(aNullableBoolArg, aNullableIntArg, aNullableStringArg)), + new ArrayList<>(Collections.singletonList(anIntArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); - } else if (listReply.get(0) == null) { - result.error( - new FlutterError( - "null-error", - "Flutter api returned null value for non-null return value.", - "")); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else { @SuppressWarnings("ConstantConditions") - AllNullableTypes output = (AllNullableTypes) listReply.get(0); + Long output = (Long) listReply.get(0); result.success(output); } } else { @@ -4783,30 +8757,26 @@ public void sendMultipleNullableTypes( } }); } - /** Returns the passed object, to test serialization and deserialization. */ - public void echoAllNullableTypesWithoutRecursion( - @Nullable AllNullableTypesWithoutRecursion everythingArg, - @NonNull NullableResult result) { + /** Returns the passed double, to test serialization and deserialization. */ + public void echoNullableDouble( + @Nullable Double aDoubleArg, @NonNull NullableResult result) { final String channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypesWithoutRecursion" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableDouble" + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(everythingArg)), + new ArrayList<>(Collections.singletonList(aDoubleArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else { @SuppressWarnings("ConstantConditions") - AllNullableTypesWithoutRecursion output = - (AllNullableTypesWithoutRecursion) listReply.get(0); + Double output = (Double) listReply.get(0); result.success(output); } } else { @@ -4814,43 +8784,26 @@ public void echoAllNullableTypesWithoutRecursion( } }); } - /** - * Returns passed in arguments of multiple types. - * - *

Tests multiple-arity FlutterApi handling. - */ - public void sendMultipleNullableTypesWithoutRecursion( - @Nullable Boolean aNullableBoolArg, - @Nullable Long aNullableIntArg, - @Nullable String aNullableStringArg, - @NonNull Result result) { + /** Returns the passed string, to test serialization and deserialization. */ + public void echoNullableString( + @Nullable String aStringArg, @NonNull NullableResult result) { final String channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableString" + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList( - Arrays.asList(aNullableBoolArg, aNullableIntArg, aNullableStringArg)), + new ArrayList<>(Collections.singletonList(aStringArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); - } else if (listReply.get(0) == null) { - result.error( - new FlutterError( - "null-error", - "Flutter api returned null value for non-null return value.", - "")); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else { @SuppressWarnings("ConstantConditions") - AllNullableTypesWithoutRecursion output = - (AllNullableTypesWithoutRecursion) listReply.get(0); + String output = (String) listReply.get(0); result.success(output); } } else { @@ -4858,33 +8811,26 @@ public void sendMultipleNullableTypesWithoutRecursion( } }); } - /** Returns the passed boolean, to test serialization and deserialization. */ - public void echoBool(@NonNull Boolean aBoolArg, @NonNull Result result) { + /** Returns the passed byte list, to test serialization and deserialization. */ + public void echoNullableUint8List( + @Nullable byte[] listArg, @NonNull NullableResult result) { final String channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoBool" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableUint8List" + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(aBoolArg)), + new ArrayList<>(Collections.singletonList(listArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); - } else if (listReply.get(0) == null) { - result.error( - new FlutterError( - "null-error", - "Flutter api returned null value for non-null return value.", - "")); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else { @SuppressWarnings("ConstantConditions") - Boolean output = (Boolean) listReply.get(0); + byte[] output = (byte[]) listReply.get(0); result.success(output); } } else { @@ -4892,34 +8838,26 @@ public void echoBool(@NonNull Boolean aBoolArg, @NonNull Result result) } }); } - /** Returns the passed int, to test serialization and deserialization. */ - public void echoInt(@NonNull Long anIntArg, @NonNull Result result) { + /** Returns the passed list, to test serialization and deserialization. */ + public void echoNullableList( + @Nullable List listArg, @NonNull NullableResult> result) { final String channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoInt" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableList" + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(anIntArg)), + new ArrayList<>(Collections.singletonList(listArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); - } else if (listReply.get(0) == null) { - result.error( - new FlutterError( - "null-error", - "Flutter api returned null value for non-null return value.", - "")); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else { @SuppressWarnings("ConstantConditions") - Long output = - listReply.get(0) == null ? null : ((Number) listReply.get(0)).longValue(); + List output = (List) listReply.get(0); result.success(output); } } else { @@ -4927,33 +8865,26 @@ public void echoInt(@NonNull Long anIntArg, @NonNull Result result) { } }); } - /** Returns the passed double, to test serialization and deserialization. */ - public void echoDouble(@NonNull Double aDoubleArg, @NonNull Result result) { + /** Returns the passed list, to test serialization and deserialization. */ + public void echoNullableEnumList( + @Nullable List enumListArg, @NonNull NullableResult> result) { final String channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoDouble" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableEnumList" + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(aDoubleArg)), + new ArrayList<>(Collections.singletonList(enumListArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); - } else if (listReply.get(0) == null) { - result.error( - new FlutterError( - "null-error", - "Flutter api returned null value for non-null return value.", - "")); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else { @SuppressWarnings("ConstantConditions") - Double output = (Double) listReply.get(0); + List output = (List) listReply.get(0); result.success(output); } } else { @@ -4961,33 +8892,27 @@ public void echoDouble(@NonNull Double aDoubleArg, @NonNull Result resul } }); } - /** Returns the passed string, to test serialization and deserialization. */ - public void echoString(@NonNull String aStringArg, @NonNull Result result) { + /** Returns the passed list, to test serialization and deserialization. */ + public void echoNullableClassList( + @Nullable List classListArg, + @NonNull NullableResult> result) { final String channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoString" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableClassList" + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(aStringArg)), + new ArrayList<>(Collections.singletonList(classListArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); - } else if (listReply.get(0) == null) { - result.error( - new FlutterError( - "null-error", - "Flutter api returned null value for non-null return value.", - "")); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else { @SuppressWarnings("ConstantConditions") - String output = (String) listReply.get(0); + List output = (List) listReply.get(0); result.success(output); } } else { @@ -4995,33 +8920,26 @@ public void echoString(@NonNull String aStringArg, @NonNull Result resul } }); } - /** Returns the passed byte list, to test serialization and deserialization. */ - public void echoUint8List(@NonNull byte[] listArg, @NonNull Result result) { + /** Returns the passed list, to test serialization and deserialization. */ + public void echoNullableNonNullEnumList( + @Nullable List enumListArg, @NonNull NullableResult> result) { final String channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoUint8List" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullEnumList" + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(listArg)), + new ArrayList<>(Collections.singletonList(enumListArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); - } else if (listReply.get(0) == null) { - result.error( - new FlutterError( - "null-error", - "Flutter api returned null value for non-null return value.", - "")); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else { @SuppressWarnings("ConstantConditions") - byte[] output = (byte[]) listReply.get(0); + List output = (List) listReply.get(0); result.success(output); } } else { @@ -5030,32 +8948,26 @@ public void echoUint8List(@NonNull byte[] listArg, @NonNull Result resul }); } /** Returns the passed list, to test serialization and deserialization. */ - public void echoList(@NonNull List listArg, @NonNull Result> result) { + public void echoNullableNonNullClassList( + @Nullable List classListArg, + @NonNull NullableResult> result) { final String channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoList" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullClassList" + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(listArg)), + new ArrayList<>(Collections.singletonList(classListArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); - } else if (listReply.get(0) == null) { - result.error( - new FlutterError( - "null-error", - "Flutter api returned null value for non-null return value.", - "")); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else { @SuppressWarnings("ConstantConditions") - List output = (List) listReply.get(0); + List output = (List) listReply.get(0); result.success(output); } } else { @@ -5064,33 +8976,25 @@ public void echoList(@NonNull List listArg, @NonNull Result }); } /** Returns the passed map, to test serialization and deserialization. */ - public void echoMap( - @NonNull Map aMapArg, @NonNull Result> result) { + public void echoNullableMap( + @Nullable Map mapArg, @NonNull NullableResult> result) { final String channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoMap" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableMap" + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(aMapArg)), + new ArrayList<>(Collections.singletonList(mapArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); - } else if (listReply.get(0) == null) { - result.error( - new FlutterError( - "null-error", - "Flutter api returned null value for non-null return value.", - "")); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else { @SuppressWarnings("ConstantConditions") - Map output = (Map) listReply.get(0); + Map output = (Map) listReply.get(0); result.success(output); } } else { @@ -5098,33 +9002,27 @@ public void echoMap( } }); } - /** Returns the passed enum to test serialization and deserialization. */ - public void echoEnum(@NonNull AnEnum anEnumArg, @NonNull Result result) { + /** Returns the passed map, to test serialization and deserialization. */ + public void echoNullableStringMap( + @Nullable Map stringMapArg, + @NonNull NullableResult> result) { final String channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnum" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableStringMap" + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(anEnumArg)), + new ArrayList<>(Collections.singletonList(stringMapArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); - } else if (listReply.get(0) == null) { - result.error( - new FlutterError( - "null-error", - "Flutter api returned null value for non-null return value.", - "")); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else { @SuppressWarnings("ConstantConditions") - AnEnum output = (AnEnum) listReply.get(0); + Map output = (Map) listReply.get(0); result.success(output); } } else { @@ -5132,28 +9030,26 @@ public void echoEnum(@NonNull AnEnum anEnumArg, @NonNull Result result) } }); } - /** Returns the passed boolean, to test serialization and deserialization. */ - public void echoNullableBool( - @Nullable Boolean aBoolArg, @NonNull NullableResult result) { + /** Returns the passed map, to test serialization and deserialization. */ + public void echoNullableIntMap( + @Nullable Map intMapArg, @NonNull NullableResult> result) { final String channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableBool" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableIntMap" + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(aBoolArg)), + new ArrayList<>(Collections.singletonList(intMapArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else { @SuppressWarnings("ConstantConditions") - Boolean output = (Boolean) listReply.get(0); + Map output = (Map) listReply.get(0); result.success(output); } } else { @@ -5161,28 +9057,27 @@ public void echoNullableBool( } }); } - /** Returns the passed int, to test serialization and deserialization. */ - public void echoNullableInt(@Nullable Long anIntArg, @NonNull NullableResult result) { + /** Returns the passed map, to test serialization and deserialization. */ + public void echoNullableEnumMap( + @Nullable Map enumMapArg, + @NonNull NullableResult> result) { final String channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableInt" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableEnumMap" + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(anIntArg)), + new ArrayList<>(Collections.singletonList(enumMapArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else { @SuppressWarnings("ConstantConditions") - Long output = - listReply.get(0) == null ? null : ((Number) listReply.get(0)).longValue(); + Map output = (Map) listReply.get(0); result.success(output); } } else { @@ -5190,28 +9085,27 @@ public void echoNullableInt(@Nullable Long anIntArg, @NonNull NullableResult result) { + /** Returns the passed map, to test serialization and deserialization. */ + public void echoNullableClassMap( + @Nullable Map classMapArg, + @NonNull NullableResult> result) { final String channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableDouble" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableClassMap" + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(aDoubleArg)), + new ArrayList<>(Collections.singletonList(classMapArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else { @SuppressWarnings("ConstantConditions") - Double output = (Double) listReply.get(0); + Map output = (Map) listReply.get(0); result.success(output); } } else { @@ -5219,28 +9113,27 @@ public void echoNullableDouble( } }); } - /** Returns the passed string, to test serialization and deserialization. */ - public void echoNullableString( - @Nullable String aStringArg, @NonNull NullableResult result) { + /** Returns the passed map, to test serialization and deserialization. */ + public void echoNullableNonNullStringMap( + @Nullable Map stringMapArg, + @NonNull NullableResult> result) { final String channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableString" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullStringMap" + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(aStringArg)), + new ArrayList<>(Collections.singletonList(stringMapArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else { @SuppressWarnings("ConstantConditions") - String output = (String) listReply.get(0); + Map output = (Map) listReply.get(0); result.success(output); } } else { @@ -5248,28 +9141,26 @@ public void echoNullableString( } }); } - /** Returns the passed byte list, to test serialization and deserialization. */ - public void echoNullableUint8List( - @Nullable byte[] listArg, @NonNull NullableResult result) { + /** Returns the passed map, to test serialization and deserialization. */ + public void echoNullableNonNullIntMap( + @Nullable Map intMapArg, @NonNull NullableResult> result) { final String channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableUint8List" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullIntMap" + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(listArg)), + new ArrayList<>(Collections.singletonList(intMapArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else { @SuppressWarnings("ConstantConditions") - byte[] output = (byte[]) listReply.get(0); + Map output = (Map) listReply.get(0); result.success(output); } } else { @@ -5277,28 +9168,27 @@ public void echoNullableUint8List( } }); } - /** Returns the passed list, to test serialization and deserialization. */ - public void echoNullableList( - @Nullable List listArg, @NonNull NullableResult> result) { + /** Returns the passed map, to test serialization and deserialization. */ + public void echoNullableNonNullEnumMap( + @Nullable Map enumMapArg, + @NonNull NullableResult> result) { final String channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableList" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullEnumMap" + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(listArg)), + new ArrayList<>(Collections.singletonList(enumMapArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else { @SuppressWarnings("ConstantConditions") - List output = (List) listReply.get(0); + Map output = (Map) listReply.get(0); result.success(output); } } else { @@ -5307,28 +9197,26 @@ public void echoNullableList( }); } /** Returns the passed map, to test serialization and deserialization. */ - public void echoNullableMap( - @Nullable Map aMapArg, - @NonNull NullableResult> result) { + public void echoNullableNonNullClassMap( + @Nullable Map classMapArg, + @NonNull NullableResult> result) { final String channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableMap" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullClassMap" + messageChannelSuffix; BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(aMapArg)), + new ArrayList<>(Collections.singletonList(classMapArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else { @SuppressWarnings("ConstantConditions") - Map output = (Map) listReply.get(0); + Map output = (Map) listReply.get(0); result.success(output); } } else { @@ -5345,16 +9233,14 @@ public void echoNullableEnum( BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(anEnumArg)), + new ArrayList<>(Collections.singletonList(anEnumArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else { @SuppressWarnings("ConstantConditions") AnEnum output = (AnEnum) listReply.get(0); @@ -5365,6 +9251,33 @@ public void echoNullableEnum( } }); } + /** Returns the passed enum to test serialization and deserialization. */ + public void echoAnotherNullableEnum( + @Nullable AnotherEnum anotherEnumArg, @NonNull NullableResult result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAnotherNullableEnum" + + messageChannelSuffix; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList<>(Collections.singletonList(anotherEnumArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); + } else { + @SuppressWarnings("ConstantConditions") + AnotherEnum output = (AnotherEnum) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } /** * A no-op function taking no arguments and returning no value, to sanity test basic * asynchronous calling. @@ -5383,9 +9296,7 @@ public void noopAsync(@NonNull VoidResult result) { if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else { result.success(); } @@ -5402,16 +9313,14 @@ public void echoAsyncString(@NonNull String aStringArg, @NonNull Result BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(aStringArg)), + new ArrayList<>(Collections.singletonList(aStringArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else if (listReply.get(0) == null) { result.error( new FlutterError( @@ -5462,13 +9371,12 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { api.noop(); wrapped.add(0, null); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -5513,7 +9421,7 @@ static void setUp( if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; String aStringArg = (String) args.get(0); Result resultCallback = @@ -5545,7 +9453,7 @@ public void error(Throwable error) { if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); VoidResult resultCallback = new VoidResult() { public void success() { @@ -5586,8 +9494,7 @@ public FlutterSmallApi( this.messageChannelSuffix = messageChannelSuffix.isEmpty() ? "" : "." + messageChannelSuffix; } - /** Public interface for sending reply. */ - /** The codec used by FlutterSmallApi. */ + /** Public interface for sending reply. The codec used by FlutterSmallApi. */ static @NonNull MessageCodec getCodec() { return PigeonCodec.INSTANCE; } @@ -5599,16 +9506,14 @@ public void echoWrappedList(@NonNull TestMessage msgArg, @NonNull Result channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(msgArg)), + new ArrayList<>(Collections.singletonList(msgArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else if (listReply.get(0) == null) { result.error( new FlutterError( @@ -5633,16 +9538,14 @@ public void echoString(@NonNull String aStringArg, @NonNull Result resul BasicMessageChannel channel = new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); channel.send( - new ArrayList(Collections.singletonList(aStringArg)), + new ArrayList<>(Collections.singletonList(aStringArg)), channelReply -> { if (channelReply instanceof List) { List listReply = (List) channelReply; if (listReply.size() > 1) { result.error( new FlutterError( - (String) listReply.get(0), - (String) listReply.get(1), - (String) listReply.get(2))); + (String) listReply.get(0), (String) listReply.get(1), listReply.get(2))); } else if (listReply.get(0) == null) { result.error( new FlutterError( diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/AllDatatypesTest.java b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/AllDatatypesTest.java index c5f7857915ab..d873a0ffe428 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/AllDatatypesTest.java +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/AllDatatypesTest.java @@ -15,6 +15,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.List; +import java.util.Map; import org.junit.Test; public class AllDatatypesTest { @@ -24,16 +26,17 @@ void compareAllTypes(AllTypes firstTypes, AllTypes secondTypes) { if (firstTypes == null || secondTypes == null) { return; } + // Check all the fields individually to ensure that everything is as expected. assertEquals(firstTypes.getABool(), secondTypes.getABool()); assertEquals(firstTypes.getAnInt(), secondTypes.getAnInt()); assertEquals(firstTypes.getAnInt64(), secondTypes.getAnInt64()); - assertEquals(firstTypes.getADouble(), secondTypes.getADouble()); assertArrayEquals(firstTypes.getAByteArray(), secondTypes.getAByteArray()); assertArrayEquals(firstTypes.getA4ByteArray(), secondTypes.getA4ByteArray()); assertArrayEquals(firstTypes.getA8ByteArray(), secondTypes.getA8ByteArray()); assertTrue(floatArraysEqual(firstTypes.getAFloatArray(), secondTypes.getAFloatArray())); assertEquals(firstTypes.getAnEnum(), secondTypes.getAnEnum()); + assertEquals(firstTypes.getAnotherEnum(), secondTypes.getAnotherEnum()); assertEquals(firstTypes.getAnObject(), secondTypes.getAnObject()); assertArrayEquals(firstTypes.getList().toArray(), secondTypes.getList().toArray()); assertArrayEquals(firstTypes.getStringList().toArray(), secondTypes.getStringList().toArray()); @@ -44,6 +47,10 @@ void compareAllTypes(AllTypes firstTypes, AllTypes secondTypes) { firstTypes.getMap().keySet().toArray(), secondTypes.getMap().keySet().toArray()); assertArrayEquals( firstTypes.getMap().values().toArray(), secondTypes.getMap().values().toArray()); + + // Also check that the implementation of equality works. + assertEquals(firstTypes, secondTypes); + assertEquals(firstTypes.hashCode(), secondTypes.hashCode()); } void compareAllNullableTypes(AllNullableTypes firstTypes, AllNullableTypes secondTypes) { @@ -51,6 +58,7 @@ void compareAllNullableTypes(AllNullableTypes firstTypes, AllNullableTypes secon if (firstTypes == null || secondTypes == null) { return; } + // Check all the fields individually to ensure that everything is as expected. assertEquals(firstTypes.getANullableBool(), secondTypes.getANullableBool()); assertEquals(firstTypes.getANullableInt(), secondTypes.getANullableInt()); assertEquals(firstTypes.getANullableDouble(), secondTypes.getANullableDouble()); @@ -61,19 +69,31 @@ void compareAllNullableTypes(AllNullableTypes firstTypes, AllNullableTypes secon assertTrue( floatArraysEqual( firstTypes.getANullableFloatArray(), secondTypes.getANullableFloatArray())); - assertArrayEquals( - firstTypes.getNullableMapWithObject().values().toArray(), - secondTypes.getNullableMapWithObject().values().toArray()); assertEquals(firstTypes.getANullableObject(), secondTypes.getANullableObject()); assertArrayEquals(firstTypes.getList().toArray(), secondTypes.getList().toArray()); assertArrayEquals(firstTypes.getStringList().toArray(), secondTypes.getStringList().toArray()); assertArrayEquals(firstTypes.getBoolList().toArray(), secondTypes.getBoolList().toArray()); assertArrayEquals(firstTypes.getDoubleList().toArray(), secondTypes.getDoubleList().toArray()); assertArrayEquals(firstTypes.getIntList().toArray(), secondTypes.getIntList().toArray()); + assertArrayEquals(firstTypes.getListList().toArray(), secondTypes.getListList().toArray()); assertArrayEquals( firstTypes.getMap().keySet().toArray(), secondTypes.getMap().keySet().toArray()); assertArrayEquals( firstTypes.getMap().values().toArray(), secondTypes.getMap().values().toArray()); + assertArrayEquals( + firstTypes.getStringMap().keySet().toArray(), + secondTypes.getStringMap().keySet().toArray()); + assertArrayEquals( + firstTypes.getStringMap().values().toArray(), + secondTypes.getStringMap().values().toArray()); + assertArrayEquals( + firstTypes.getIntMap().keySet().toArray(), secondTypes.getIntMap().keySet().toArray()); + assertArrayEquals( + firstTypes.getIntMap().values().toArray(), secondTypes.getIntMap().values().toArray()); + + // Also check that the implementation of equality works. + assertEquals(firstTypes, secondTypes); + assertEquals(firstTypes.hashCode(), secondTypes.hashCode()); } @Test @@ -110,13 +130,15 @@ public void success(AllNullableTypes result) { assertNull(everything.getANullable4ByteArray()); assertNull(everything.getANullable8ByteArray()); assertNull(everything.getANullableFloatArray()); - assertNull(everything.getNullableMapWithObject()); assertNull(everything.getList()); assertNull(everything.getDoubleList()); assertNull(everything.getIntList()); assertNull(everything.getStringList()); assertNull(everything.getBoolList()); + assertNull(everything.getListList()); assertNull(everything.getMap()); + assertNull(everything.getStringMap()); + assertNull(everything.getIntMap()); } public void error(Throwable error) { @@ -126,14 +148,8 @@ public void error(Throwable error) { assertTrue(didCall[0]); } - private static HashMap makeMap(String key, Integer value) { - HashMap result = new HashMap(); - result.put(key, value); - return result; - } - - private static HashMap makeStringMap(String key, Integer value) { - HashMap result = new HashMap(); + private static HashMap makeMap(K key, J value) { + HashMap result = new HashMap(); result.put(key, value); return result; } @@ -152,6 +168,16 @@ private static boolean floatArraysEqual(double[] x, double[] y) { @Test public void hasValues() { + // Not inline due to warnings about an ambiguous varargs call when inline. + final List genericList = Arrays.asList(new Object[] {"hello", 1, true, false, null}); + final List> listList = new ArrayList<>(Arrays.asList()); + final List> mapList = new ArrayList<>(Arrays.asList()); + final Map> listMap = new HashMap>(); + final Map> mapMap = new HashMap>(); + listList.add(genericList); + mapList.add(makeMap("hello", 1234)); + listMap.put(1L, genericList); + mapMap.put(1L, makeMap("hello", 1234)); AllTypes allEverything = new AllTypes.Builder() .setABool(false) @@ -164,13 +190,26 @@ public void hasValues() { .setA8ByteArray(new long[] {1, 2, 3, 4}) .setAFloatArray(new double[] {0.5, 0.25, 1.5, 1.25}) .setAnEnum(CoreTests.AnEnum.ONE) + .setAnotherEnum(CoreTests.AnotherEnum.JUST_IN_CASE) .setAnObject(0) + .setList(genericList) .setBoolList(Arrays.asList(new Boolean[] {true, false})) .setDoubleList(Arrays.asList(new Double[] {0.5, 0.25, 1.5, 1.25})) .setIntList(Arrays.asList(new Long[] {1l, 2l, 3l, 4l})) - .setList(Arrays.asList(new int[] {1, 2, 3, 4})) .setStringList(Arrays.asList(new String[] {"string", "another one"})) + .setObjectList(genericList) + .setEnumList( + Arrays.asList( + new CoreTests.AnEnum[] {CoreTests.AnEnum.ONE, CoreTests.AnEnum.FORTY_TWO})) + .setListList(listList) + .setMapList(mapList) .setMap(makeMap("hello", 1234)) + .setIntMap(makeMap(1L, 0L)) + .setStringMap(makeMap("hello", "you")) + .setObjectMap(makeMap("E", 4321)) + .setEnumMap(makeMap(CoreTests.AnEnum.ONE, CoreTests.AnEnum.FOUR_HUNDRED_TWENTY_TWO)) + .setListMap(listMap) + .setMapMap(mapMap) .build(); AllNullableTypes everything = @@ -183,14 +222,16 @@ public void hasValues() { .setANullable4ByteArray(new int[] {1, 2, 3, 4}) .setANullable8ByteArray(new long[] {1, 2, 3, 4}) .setANullableFloatArray(new double[] {0.5, 0.25, 1.5, 1.25}) - .setNullableMapWithObject(makeStringMap("hello", 1234)) .setANullableObject(0) + .setList(Arrays.asList(genericList)) .setBoolList(Arrays.asList(new Boolean[] {true, false})) .setDoubleList(Arrays.asList(new Double[] {0.5, 0.25, 1.5, 1.25})) .setIntList(Arrays.asList(new Long[] {1l, 2l, 3l, 4l})) - .setList(Arrays.asList(new int[] {1, 2, 3, 4})) .setStringList(Arrays.asList(new String[] {"string", "another one"})) + .setListList(listList) .setMap(makeMap("hello", 1234)) + .setStringMap(makeMap("hello", "you")) + .setIntMap(makeMap(2L, -2L)) .build(); BinaryMessenger binaryMessenger = mock(BinaryMessenger.class); @@ -225,17 +266,4 @@ public void error(Throwable error) { }); assertTrue(didCall[0]); } - - @Test - public void integerToLong() { - AllNullableTypes everything = new AllNullableTypes(); - everything.setANullableInt(123L); - ArrayList list = everything.toList(); - assertNotNull(list); - assertNull(list.get(0)); - assertNotNull(list.get(1)); - list.set(1, 123); - AllNullableTypes readEverything = AllNullableTypes.fromList(list); - assertEquals(readEverything.getANullableInt(), everything.getANullableInt()); - } } diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/PrimitiveTest.java b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/PrimitiveTest.java index fc96adc2cb4b..8624bced5b1f 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/PrimitiveTest.java +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/PrimitiveTest.java @@ -32,14 +32,6 @@ private static BinaryMessenger makeMockBinaryMessenger() { ArrayList args = (ArrayList) PrimitiveFlutterApi.getCodec().decodeMessage(message); Object arg = args.get(0); - if (arg instanceof Long) { - Long longArg = (Long) arg; - if (longArg.intValue() == longArg.longValue()) { - // Value fits in the Integer so gets sent as such - // https://docs.flutter.dev/development/platform-integration/platform-channels?tab=type-mappings-java-tab#codec - arg = Integer.valueOf(longArg.intValue()); - } - } ArrayList wrapped = new ArrayList(); wrapped.add(0, arg); ByteBuffer replyData = PrimitiveFlutterApi.getCodec().encodeMessage(wrapped); @@ -106,7 +98,7 @@ public void primitiveIntHostApi() { handler.capture()); MessageCodec codec = PrimitiveHostApi.getCodec(); @SuppressWarnings("unchecked") - ByteBuffer message = codec.encodeMessage(new ArrayList(Arrays.asList((Integer) 1))); + ByteBuffer message = codec.encodeMessage(new ArrayList(Arrays.asList(1L))); message.rewind(); handler .getValue() diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/android/.gitignore b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/android/.gitignore index 6f568019d3c6..55afd919c659 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/android/.gitignore +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/android/.gitignore @@ -7,7 +7,7 @@ gradle-wrapper.jar GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. -# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +# See https://flutter.dev/to/reference-keystore key.properties **/*.keystore **/*.jks diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/android/app/build.gradle b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/android/app/build.gradle index aecfb56abf70..b6364e4df79d 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/android/app/build.gradle +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/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,18 +22,14 @@ 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 'com.example.alternate_language_test_plugin_example' compileSdk flutter.compileSdkVersion ndkVersion flutter.ndkVersion compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } defaultConfig { diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/android/build.gradle b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/android/build.gradle index 18a1d3ccb472..3f78da216a0e 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/android/build.gradle +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/android/build.gradle @@ -1,16 +1,3 @@ -buildscript { - ext.kotlin_version = '1.7.10' - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' - 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/platform_tests/alternate_language_test_plugin/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/android/gradle/wrapper/gradle-wrapper.properties index e1ca574ef017..3c85cfe057a1 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/android/settings.gradle b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/android/settings.gradle index f246a74091be..d056e4db3665 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/android/settings.gradle +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/android/settings.gradle @@ -1,24 +1,27 @@ -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/platform_tests/alternate_language_test_plugin/example/ios/RunnerTests/AllDatatypesTest.m b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/ios/RunnerTests/AllDatatypesTest.m index a605276d1592..b4ebec5f9c70 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/ios/RunnerTests/AllDatatypesTest.m +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/ios/RunnerTests/AllDatatypesTest.m @@ -38,7 +38,9 @@ - (void)testAllNull { XCTAssertNil(result.intList); XCTAssertNil(result.doubleList); XCTAssertNil(result.stringList); + XCTAssertNil(result.objectList); XCTAssertNil(result.map); + XCTAssertNil(result.objectMap); [expectation fulfill]; }]; [self waitForExpectations:@[ expectation ] timeout:1.0]; @@ -58,13 +60,22 @@ - (void)testAllEquals { typedDataWithInt64:[@"12345678" dataUsingEncoding:NSUTF8StringEncoding]]; everything.aNullableFloatArray = [FlutterStandardTypedData typedDataWithFloat64:[@"12345678" dataUsingEncoding:NSUTF8StringEncoding]]; - everything.nullableMapWithObject = @{@"hello" : @(1234), @"goodbye" : @"world"}; + everything.list = @[ @"string", @1 ]; everything.boolList = @[ @YES, @NO ]; everything.intList = @[ @1, @2 ]; everything.doubleList = @[ @1.1, @2.2 ]; everything.stringList = @[ @"string", @"another one" ]; - everything.list = @[ @"string", @1 ]; + everything.objectList = @[ @"string", @1 ]; + everything.listList = @[ @[ @"string" ], @[ @"another one" ] ]; + everything.mapList = @[ + @{@"hello" : @(1234), @"goodbye" : @"world"}, @{@"hello" : @(1234), @"goodbye" : @"world"} + ]; everything.map = @{@"hello" : @(1234), @"goodbye" : @"world"}; + everything.stringMap = @{@"hello" : @"you", @"goodbye" : @"world"}; + everything.intMap = @{@(1) : @(0), @(2) : @(-2)}; + everything.objectMap = @{@"hello" : @(1234), @"goodbye" : @"world"}; + everything.listMap = @{@(1234) : @[ @"string", @"another one" ]}; + everything.mapMap = @{@(1234) : @{@"goodbye" : @"world"}}; EchoBinaryMessenger *binaryMessenger = [[EchoBinaryMessenger alloc] initWithCodec:FLTGetCoreTestsCodec()]; FLTFlutterIntegrationCoreApi *api = @@ -84,17 +95,27 @@ - (void)testAllEquals { everything.aNullable8ByteArray.data); XCTAssertEqualObjects(result.aNullableFloatArray.data, everything.aNullableFloatArray.data); - XCTAssertEqualObjects(result.nullableMapWithObject, - everything.nullableMapWithObject); XCTAssertEqualObjects(result.list, everything.list); XCTAssertEqualObjects(result.boolList, everything.boolList); XCTAssertEqualObjects(result.intList, everything.intList); XCTAssertEqualObjects(result.doubleList, everything.doubleList); XCTAssertEqualObjects(result.stringList, everything.stringList); + XCTAssertEqualObjects(result.objectList, everything.objectList); + XCTAssertEqualObjects(result.listList, everything.listList); + XCTAssertEqualObjects(result.mapList, everything.mapList); XCTAssertEqualObjects(result.map, everything.map); + XCTAssertEqualObjects(result.stringMap, everything.stringMap); + XCTAssertEqualObjects(result.intMap, everything.intMap); + XCTAssertEqualObjects(result.objectMap, everything.objectMap); + XCTAssertEqualObjects(result.listMap, everything.listMap); + XCTAssertEqualObjects(result.mapMap, everything.mapMap); [expectation fulfill]; }]; [self waitForExpectations:@[ expectation ] timeout:1.0]; } +- (void)unusedClassesExist { + XCTAssert([[FLTUnusedClass alloc] init] != nil); +} + @end diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/macos/Podfile b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/macos/Podfile index c795730db8ed..29c8eb3294cb 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/macos/Podfile +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/macos/Podfile @@ -28,7 +28,6 @@ flutter_macos_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) target 'RunnerTests' do 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 a080fec9236c..d40ce1efd995 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.2.0 + sdk: ^3.3.0 dependencies: alternate_language_test_plugin: diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/AlternateLanguageTestPlugin.m b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/AlternateLanguageTestPlugin.m index 4ea9519033c7..d684acfd55e6 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/AlternateLanguageTestPlugin.m +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/AlternateLanguageTestPlugin.m @@ -95,9 +95,80 @@ - (nullable id)echoObject:(id)anObject error:(FlutterError *_Nullable *_Nonnull) return list; } -- (nullable NSDictionary *)echoMap:(NSDictionary *)aMap +- (nullable NSArray *)echoEnumList:(NSArray *)enumList error:(FlutterError *_Nullable *_Nonnull)error { - return aMap; + return enumList; +} + +- (nullable NSArray *) + echoClassList:(NSArray *)classList + error:(FlutterError *_Nullable *_Nonnull)error { + return classList; +} + +- (nullable NSArray *) + echoNonNullEnumList:(nonnull NSArray *)enumList + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return enumList; +} + +- (nullable NSArray *) + echoNonNullClassList:(nonnull NSArray *)classList + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return classList; +} + +- (nullable NSDictionary *)echoMap:(NSDictionary *)map + error:(FlutterError *_Nullable *_Nonnull)error { + return map; +} + +- (nullable NSDictionary *) + echoStringMap:(NSDictionary *)stringMap + error:(FlutterError *_Nullable *_Nonnull)error { + return stringMap; +} + +- (nullable NSDictionary *) + echoIntMap:(NSDictionary *)intMap + error:(FlutterError *_Nullable *_Nonnull)error { + return intMap; +} + +- (nullable NSDictionary *) + echoEnumMap:(NSDictionary *)enumMap + error:(FlutterError *_Nullable *_Nonnull)error { + return enumMap; +} + +- (nullable NSDictionary *) + echoClassMap:(NSDictionary *)classMap + error:(FlutterError *_Nullable *_Nonnull)error { + return classMap; +} + +- (nullable NSDictionary *) + echoNonNullStringMap:(nonnull NSDictionary *)stringMap + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return stringMap; +} + +- (nullable NSDictionary *) + echoNonNullIntMap:(nonnull NSDictionary *)intMap + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return intMap; +} + +- (nullable NSDictionary *) + echoNonNullEnumMap:(nonnull NSDictionary *)enumMap + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return enumMap; +} + +- (nullable NSDictionary *) + echoNonNullClassMap:(nonnull NSDictionary *)classMap + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return classMap; } - (nullable FLTAllClassesWrapper *)echoClassWrapper:(FLTAllClassesWrapper *)wrapper @@ -110,6 +181,11 @@ - (FLTAnEnumBox *_Nullable)echoEnum:(FLTAnEnum)anEnum return [[FLTAnEnumBox alloc] initWithValue:anEnum]; } +- (FLTAnotherEnumBox *_Nullable)echoAnotherEnum:(FLTAnotherEnum)anotherEnum + error:(FlutterError *_Nullable *_Nonnull)error { + return [[FLTAnotherEnumBox alloc] initWithValue:anotherEnum]; +} + - (nullable NSString *)echoNamedDefaultString:(NSString *)aString error:(FlutterError *_Nullable *_Nonnull)error { return aString; @@ -137,7 +213,11 @@ - (nullable NSString *)extractNestedNullableStringFrom:(FLTAllClassesWrapper *)w innerObject.aNullableString = nullableString; return [FLTAllClassesWrapper makeWithAllNullableTypes:innerObject allNullableTypesWithoutRecursion:nil - allTypes:nil]; + allTypes:nil + classList:@[] + nullableClassList:nil + classMap:@{} + nullableClassMap:nil]; } - (nullable FLTAllNullableTypes *) @@ -203,10 +283,81 @@ - (nullable id)echoNullableObject:(nullable id)aNullableObject return aNullableList; } -- (nullable NSDictionary *) - echoNullableMap:(nullable NSDictionary *)aNullableMap - error:(FlutterError *_Nullable *_Nonnull)error { - return aNullableMap; +- (nullable NSArray *) + echoNullableEnumList:(nullable NSArray *)enumList + error:(FlutterError *_Nullable *_Nonnull)error { + return enumList; +} + +- (nullable NSArray *) + echoNullableClassList:(nullable NSArray *)classList + error:(FlutterError *_Nullable *_Nonnull)error { + return classList; +} + +- (nullable NSArray *) + echoNullableNonNullEnumList:(nullable NSArray *)enumList + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return enumList; +} + +- (nullable NSArray *) + echoNullableNonNullClassList:(nullable NSArray *)classList + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return classList; +} + +- (nullable NSDictionary *)echoNullableMap:(nullable NSDictionary *)map + error:(FlutterError *_Nullable *_Nonnull)error { + return map; +} + +- (nullable NSDictionary *) + echoNullableStringMap:(nullable NSDictionary *)stringMap + error:(FlutterError *_Nullable *_Nonnull)error { + return stringMap; +} + +- (nullable NSDictionary *) + echoNullableIntMap:(nullable NSDictionary *)intMap + error:(FlutterError *_Nullable *_Nonnull)error { + return intMap; +} + +- (nullable NSDictionary *) + echoNullableEnumMap:(nullable NSDictionary *)enumMap + error:(FlutterError *_Nullable *_Nonnull)error { + return enumMap; +} + +- (nullable NSDictionary *) + echoNullableClassMap:(nullable NSDictionary *)classMap + error:(FlutterError *_Nullable *_Nonnull)error { + return classMap; +} + +- (nullable NSDictionary *) + echoNullableNonNullStringMap:(nullable NSDictionary *)stringMap + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return stringMap; +} + +- (nullable NSDictionary *) + echoNullableNonNullIntMap:(nullable NSDictionary *)intMap + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return intMap; +} + +- (nullable NSDictionary *) + echoNullableNonNullEnumMap:(nullable NSDictionary *)enumMap + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return enumMap; +} + +- (nullable NSDictionary *) + echoNullableNonNullClassMap:(nullable NSDictionary *)classMap + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return classMap; } - (FLTAnEnumBox *_Nullable)echoNullableEnum:(nullable FLTAnEnumBox *)AnEnumBoxed @@ -214,6 +365,12 @@ - (FLTAnEnumBox *_Nullable)echoNullableEnum:(nullable FLTAnEnumBox *)AnEnumBoxed return AnEnumBoxed; } +- (FLTAnotherEnumBox *_Nullable)echoAnotherNullableEnum: + (nullable FLTAnotherEnumBox *)AnotherEnumBoxed + error:(FlutterError *_Nullable *_Nonnull)error { + return AnotherEnumBoxed; +} + - (nullable NSNumber *)echoOptionalNullableInt:(nullable NSNumber *)aNullableInt error:(FlutterError *_Nullable *_Nonnull)error { return aNullableInt; @@ -298,10 +455,46 @@ - (void)echoAsyncList:(NSArray *)list completion(list, nil); } -- (void)echoAsyncMap:(NSDictionary *)aMap - completion:(void (^)(NSDictionary *_Nullable, - FlutterError *_Nullable))completion { - completion(aMap, nil); +- (void)echoAsyncEnumList:(NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + completion(enumList, nil); +} + +- (void)echoAsyncClassList:(NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + completion(classList, nil); +} + +- (void)echoAsyncMap:(NSDictionary *)map + completion: + (void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion { + completion(map, nil); +} + +- (void)echoAsyncStringMap:(NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + completion(stringMap, nil); +} + +- (void)echoAsyncIntMap:(NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + completion(intMap, nil); +} + +- (void)echoAsyncEnumMap:(NSDictionary *)enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + completion(enumMap, nil); +} + +- (void)echoAsyncClassMap:(NSDictionary *)classMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + completion(classMap, nil); } - (void)echoAsyncEnum:(FLTAnEnum)anEnum @@ -309,6 +502,12 @@ - (void)echoAsyncEnum:(FLTAnEnum)anEnum completion([[FLTAnEnumBox alloc] initWithValue:anEnum], nil); } +- (void)echoAnotherAsyncEnum:(FLTAnotherEnum)anotherEnum + completion: + (void (^)(FLTAnotherEnumBox *_Nullable, FlutterError *_Nullable))completion { + completion([[FLTAnotherEnumBox alloc] initWithValue:anotherEnum], nil); +} + - (void)echoAsyncNullableInt:(nullable NSNumber *)anInt completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { completion(anInt, nil); @@ -346,10 +545,47 @@ - (void)echoAsyncNullableList:(nullable NSArray *)list completion(list, nil); } -- (void)echoAsyncNullableMap:(nullable NSDictionary *)aMap - completion:(void (^)(NSDictionary *_Nullable, +- (void)echoAsyncNullableEnumList:(nullable NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + completion(enumList, nil); +} + +- (void)echoAsyncNullableClassList:(nullable NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + completion(classList, nil); +} + +- (void)echoAsyncNullableMap:(nullable NSDictionary *)map + completion:(void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion { - completion(aMap, nil); + completion(map, nil); +} + +- (void)echoAsyncNullableStringMap:(nullable NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + completion(stringMap, nil); +} + +- (void)echoAsyncNullableIntMap:(nullable NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + completion(intMap, nil); +} + +- (void)echoAsyncNullableEnumMap:(nullable NSDictionary *)enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + completion(enumMap, nil); +} + +- (void) + echoAsyncNullableClassMap:(nullable NSDictionary *)classMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + completion(classMap, nil); } - (void)echoAsyncNullableEnum:(nullable FLTAnEnumBox *)AnEnumBoxed @@ -358,6 +594,12 @@ - (void)echoAsyncNullableEnum:(nullable FLTAnEnumBox *)AnEnumBoxed completion(AnEnumBoxed, nil); } +- (void)echoAnotherAsyncNullableEnum:(nullable FLTAnotherEnumBox *)AnotherEnumBoxed + completion:(void (^)(FLTAnotherEnumBox *_Nullable, + FlutterError *_Nullable))completion { + completion(AnotherEnumBoxed, nil); +} + - (void)callFlutterNoopWithCompletion:(void (^)(FlutterError *_Nullable))completion { [self.flutterAPI noopWithCompletion:^(FlutterError *error) { completion(error); @@ -468,15 +710,139 @@ - (void)callFlutterEchoList:(NSArray *)list }]; } -- (void)callFlutterEchoMap:(NSDictionary *)aMap - completion:(void (^)(NSDictionary *_Nullable, - FlutterError *_Nullable))completion { - [self.flutterAPI echoMap:aMap - completion:^(NSDictionary *value, FlutterError *error) { +- (void)callFlutterEchoEnumList:(NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoEnumList:enumList + completion:^(NSArray *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoClassList:(NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoClassList:classList + completion:^(NSArray *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNonNullEnumList:(nonnull NSArray *)enumList + completion:(nonnull void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoNonNullEnumList:enumList + completion:^(NSArray *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNonNullClassList:(nonnull NSArray *)classList + completion:(nonnull void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoNonNullClassList:classList + completion:^(NSArray *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoMap:(NSDictionary *)map + completion: + (void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion { + [self.flutterAPI echoMap:map + completion:^(NSDictionary *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoStringMap:(NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoStringMap:stringMap + completion:^(NSDictionary *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoIntMap:(NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoIntMap:intMap + completion:^(NSDictionary *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoEnumMap:(NSDictionary *)enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoEnumMap:enumMap + completion:^(NSDictionary *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoClassMap:(NSDictionary *)classMap + completion: + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoClassMap:classMap + completion:^(NSDictionary *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNonNullStringMap:(nonnull NSDictionary *)stringMap + completion: + (nonnull void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoNonNullStringMap:stringMap + completion:^(NSDictionary *value, FlutterError *error) { completion(value, error); }]; } +- (void)callFlutterEchoNonNullIntMap:(nonnull NSDictionary *)intMap + completion: + (nonnull void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoNonNullIntMap:intMap + completion:^(NSDictionary *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNonNullEnumMap: + (nonnull NSDictionary *)enumMap + completion:(nonnull void (^)( + NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoNonNullEnumMap:enumMap + completion:^(NSDictionary *value, + FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNonNullClassMap: + (nonnull NSDictionary *)classMap + completion: + (nonnull void (^)( + NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoNonNullClassMap:classMap + completion:^(NSDictionary *value, + FlutterError *error) { + completion(value, error); + }]; +} + - (void)callFlutterEchoEnum:(FLTAnEnum)anEnum completion:(void (^)(FLTAnEnumBox *_Nullable, FlutterError *_Nullable))completion { [self.flutterAPI echoEnum:anEnum @@ -485,6 +851,15 @@ - (void)callFlutterEchoEnum:(FLTAnEnum)anEnum }]; } +- (void)callFlutterEchoAnotherEnum:(FLTAnotherEnum)anotherEnum + completion:(void (^)(FLTAnotherEnumBox *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoAnotherEnum:anotherEnum + completion:^(FLTAnotherEnumBox *value, FlutterError *error) { + completion(value, error); + }]; +} + - (void)callFlutterEchoAllNullableTypes:(nullable FLTAllNullableTypes *)everything completion:(void (^)(FLTAllNullableTypes *_Nullable, FlutterError *_Nullable))completion { @@ -562,15 +937,152 @@ - (void)callFlutterEchoNullableList:(nullable NSArray *)list }]; } -- (void)callFlutterEchoNullableMap:(nullable NSDictionary *)aMap - completion:(void (^)(NSDictionary *_Nullable, +- (void)callFlutterEchoNullableEnumList:(nullable NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoNullableEnumList:enumList + completion:^(NSArray *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNullableClassList:(nullable NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoNullableClassList:classList + completion:^(NSArray *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNullableNonNullEnumList:(nullable NSArray *)enumList + completion: + (nonnull void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoNullableNonNullEnumList:enumList + completion:^(NSArray *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNullableNonNullClassList:(nullable NSArray *)classList + completion:(nonnull void (^)( + NSArray *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoNullableNonNullClassList:classList + completion:^(NSArray *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNullableMap:(nullable NSDictionary *)map + completion:(void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion { - [self.flutterAPI echoNullableMap:aMap - completion:^(NSDictionary *value, FlutterError *error) { + [self.flutterAPI echoNullableMap:map + completion:^(NSDictionary *value, FlutterError *error) { completion(value, error); }]; } +- (void)callFlutterEchoNullableStringMap:(nullable NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoNullableStringMap:stringMap + completion:^(NSDictionary *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNullableIntMap:(nullable NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoNullableIntMap:intMap + completion:^(NSDictionary *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNullableEnumMap: + (nullable NSDictionary *)enumMap + completion: + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoNullableEnumMap:enumMap + completion:^(NSDictionary *value, + FlutterError *error) { + completion(value, error); + }]; +} + +- (void) + callFlutterEchoNullableClassMap: + (nullable NSDictionary *)classMap + completion: + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoNullableClassMap:classMap + completion:^(NSDictionary *value, + FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNullableNonNullStringMap: + (nullable NSDictionary *)stringMap + completion:(nonnull void (^)( + NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoNullableNonNullStringMap:stringMap + completion:^(NSDictionary *value, + FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNullableNonNullIntMap:(nullable NSDictionary *)intMap + completion:(nonnull void (^)( + NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoNullableNonNullIntMap:intMap + completion:^(NSDictionary *value, + FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNullableNonNullEnumMap: + (nullable NSDictionary *)enumMap + completion: + (nonnull void (^)( + NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoNullableNonNullEnumMap:enumMap + completion:^(NSDictionary *value, + FlutterError *error) { + completion(value, error); + }]; +} + +- (void) + callFlutterEchoNullableNonNullClassMap: + (nullable NSDictionary *)classMap + completion: + (nonnull void (^)( + NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoNullableNonNullClassMap:classMap + completion:^(NSDictionary *value, + FlutterError *error) { + completion(value, error); + }]; +} + - (void)callFlutterEchoNullableEnum:(nullable FLTAnEnumBox *)AnEnumBoxed completion:(void (^)(FLTAnEnumBox *_Nullable, FlutterError *_Nullable))completion { @@ -580,6 +1092,15 @@ - (void)callFlutterEchoNullableEnum:(nullable FLTAnEnumBox *)AnEnumBoxed }]; } +- (void)callFlutterEchoAnotherNullableEnum:(nullable FLTAnotherEnumBox *)AnotherEnumBoxed + completion:(void (^)(FLTAnotherEnumBox *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoAnotherNullableEnum:AnotherEnumBoxed + completion:^(FLTAnotherEnumBox *value, FlutterError *error) { + completion(value, error); + }]; +} + - (void)callFlutterSmallApiEchoString:(nonnull NSString *)aString completion:(nonnull void (^)(NSString *_Nullable, FlutterError *_Nullable))completion { @@ -606,6 +1127,10 @@ - (void)callFlutterSmallApiEchoString:(nonnull NSString *)aString }]; } +- (FLTUnusedClass *)checkIfUnusedClassGenerated { + return [[FLTUnusedClass alloc] init]; +} + @end @interface AlternateLanguageTestAPIWithSuffix () diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h index 2bf7bbf26bee..bd913ca95a9e 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h @@ -28,12 +28,28 @@ typedef NS_ENUM(NSUInteger, FLTAnEnum) { - (instancetype)initWithValue:(FLTAnEnum)value; @end +typedef NS_ENUM(NSUInteger, FLTAnotherEnum) { + FLTAnotherEnumJustInCase = 0, +}; + +/// Wrapper for FLTAnotherEnum to allow for nullability. +@interface FLTAnotherEnumBox : NSObject +@property(nonatomic, assign) FLTAnotherEnum value; +- (instancetype)initWithValue:(FLTAnotherEnum)value; +@end + +@class FLTUnusedClass; @class FLTAllTypes; @class FLTAllNullableTypes; @class FLTAllNullableTypesWithoutRecursion; @class FLTAllClassesWrapper; @class FLTTestMessage; +@interface FLTUnusedClass : NSObject ++ (instancetype)makeWithAField:(nullable id)aField; +@property(nonatomic, strong, nullable) id aField; +@end + /// A class containing all supported types. @interface FLTAllTypes : NSObject /// `init` unavailable to enforce nonnull fields, see the `make` class method. @@ -47,6 +63,7 @@ typedef NS_ENUM(NSUInteger, FLTAnEnum) { a8ByteArray:(FlutterStandardTypedData *)a8ByteArray aFloatArray:(FlutterStandardTypedData *)aFloatArray anEnum:(FLTAnEnum)anEnum + anotherEnum:(FLTAnotherEnum)anotherEnum aString:(NSString *)aString anObject:(id)anObject list:(NSArray *)list @@ -54,7 +71,17 @@ typedef NS_ENUM(NSUInteger, FLTAnEnum) { intList:(NSArray *)intList doubleList:(NSArray *)doubleList boolList:(NSArray *)boolList - map:(NSDictionary *)map; + enumList:(NSArray *)enumList + objectList:(NSArray *)objectList + listList:(NSArray *> *)listList + mapList:(NSArray *> *)mapList + map:(NSDictionary *)map + stringMap:(NSDictionary *)stringMap + intMap:(NSDictionary *)intMap + enumMap:(NSDictionary *)enumMap + objectMap:(NSDictionary *)objectMap + listMap:(NSDictionary *> *)listMap + mapMap:(NSDictionary *> *)mapMap; @property(nonatomic, assign) BOOL aBool; @property(nonatomic, assign) NSInteger anInt; @property(nonatomic, assign) NSInteger anInt64; @@ -64,6 +91,7 @@ typedef NS_ENUM(NSUInteger, FLTAnEnum) { @property(nonatomic, strong) FlutterStandardTypedData *a8ByteArray; @property(nonatomic, strong) FlutterStandardTypedData *aFloatArray; @property(nonatomic, assign) FLTAnEnum anEnum; +@property(nonatomic, assign) FLTAnotherEnum anotherEnum; @property(nonatomic, copy) NSString *aString; @property(nonatomic, strong) id anObject; @property(nonatomic, copy) NSArray *list; @@ -71,34 +99,54 @@ typedef NS_ENUM(NSUInteger, FLTAnEnum) { @property(nonatomic, copy) NSArray *intList; @property(nonatomic, copy) NSArray *doubleList; @property(nonatomic, copy) NSArray *boolList; +@property(nonatomic, copy) NSArray *enumList; +@property(nonatomic, copy) NSArray *objectList; +@property(nonatomic, copy) NSArray *> *listList; +@property(nonatomic, copy) NSArray *> *mapList; @property(nonatomic, copy) NSDictionary *map; +@property(nonatomic, copy) NSDictionary *stringMap; +@property(nonatomic, copy) NSDictionary *intMap; +@property(nonatomic, copy) NSDictionary *enumMap; +@property(nonatomic, copy) NSDictionary *objectMap; +@property(nonatomic, copy) NSDictionary *> *listMap; +@property(nonatomic, copy) NSDictionary *> *mapMap; @end /// A class containing all supported nullable types. @interface FLTAllNullableTypes : NSObject -+ (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool - aNullableInt:(nullable NSNumber *)aNullableInt - aNullableInt64:(nullable NSNumber *)aNullableInt64 - aNullableDouble:(nullable NSNumber *)aNullableDouble - aNullableByteArray:(nullable FlutterStandardTypedData *)aNullableByteArray - aNullable4ByteArray:(nullable FlutterStandardTypedData *)aNullable4ByteArray - aNullable8ByteArray:(nullable FlutterStandardTypedData *)aNullable8ByteArray - aNullableFloatArray:(nullable FlutterStandardTypedData *)aNullableFloatArray - nullableNestedList:(nullable NSArray *> *)nullableNestedList - nullableMapWithAnnotations: - (nullable NSDictionary *)nullableMapWithAnnotations - nullableMapWithObject:(nullable NSDictionary *)nullableMapWithObject - aNullableEnum:(nullable FLTAnEnumBox *)aNullableEnum - aNullableString:(nullable NSString *)aNullableString - aNullableObject:(nullable id)aNullableObject - allNullableTypes:(nullable FLTAllNullableTypes *)allNullableTypes - list:(nullable NSArray *)list - stringList:(nullable NSArray *)stringList - intList:(nullable NSArray *)intList - doubleList:(nullable NSArray *)doubleList - boolList:(nullable NSArray *)boolList - nestedClassList:(nullable NSArray *)nestedClassList - map:(nullable NSDictionary *)map; ++ (instancetype) + makeWithANullableBool:(nullable NSNumber *)aNullableBool + aNullableInt:(nullable NSNumber *)aNullableInt + aNullableInt64:(nullable NSNumber *)aNullableInt64 + aNullableDouble:(nullable NSNumber *)aNullableDouble + aNullableByteArray:(nullable FlutterStandardTypedData *)aNullableByteArray + aNullable4ByteArray:(nullable FlutterStandardTypedData *)aNullable4ByteArray + aNullable8ByteArray:(nullable FlutterStandardTypedData *)aNullable8ByteArray + aNullableFloatArray:(nullable FlutterStandardTypedData *)aNullableFloatArray + aNullableEnum:(nullable FLTAnEnumBox *)aNullableEnum + anotherNullableEnum:(nullable FLTAnotherEnumBox *)anotherNullableEnum + aNullableString:(nullable NSString *)aNullableString + aNullableObject:(nullable id)aNullableObject + allNullableTypes:(nullable FLTAllNullableTypes *)allNullableTypes + list:(nullable NSArray *)list + stringList:(nullable NSArray *)stringList + intList:(nullable NSArray *)intList + doubleList:(nullable NSArray *)doubleList + boolList:(nullable NSArray *)boolList + enumList:(nullable NSArray *)enumList + objectList:(nullable NSArray *)objectList + listList:(nullable NSArray *> *)listList + mapList:(nullable NSArray *> *)mapList + recursiveClassList:(nullable NSArray *)recursiveClassList + map:(nullable NSDictionary *)map + stringMap:(nullable NSDictionary *)stringMap + intMap:(nullable NSDictionary *)intMap + enumMap:(nullable NSDictionary *)enumMap + objectMap:(nullable NSDictionary *)objectMap + listMap:(nullable NSDictionary *> *)listMap + mapMap:(nullable NSDictionary *> *)mapMap + recursiveClassMap: + (nullable NSDictionary *)recursiveClassMap; @property(nonatomic, strong, nullable) NSNumber *aNullableBool; @property(nonatomic, strong, nullable) NSNumber *aNullableInt; @property(nonatomic, strong, nullable) NSNumber *aNullableInt64; @@ -107,11 +155,8 @@ typedef NS_ENUM(NSUInteger, FLTAnEnum) { @property(nonatomic, strong, nullable) FlutterStandardTypedData *aNullable4ByteArray; @property(nonatomic, strong, nullable) FlutterStandardTypedData *aNullable8ByteArray; @property(nonatomic, strong, nullable) FlutterStandardTypedData *aNullableFloatArray; -@property(nonatomic, copy, nullable) NSArray *> *nullableNestedList; -@property(nonatomic, copy, nullable) - NSDictionary *nullableMapWithAnnotations; -@property(nonatomic, copy, nullable) NSDictionary *nullableMapWithObject; @property(nonatomic, strong, nullable) FLTAnEnumBox *aNullableEnum; +@property(nonatomic, strong, nullable) FLTAnotherEnumBox *anotherNullableEnum; @property(nonatomic, copy, nullable) NSString *aNullableString; @property(nonatomic, strong, nullable) id aNullableObject; @property(nonatomic, strong, nullable) FLTAllNullableTypes *allNullableTypes; @@ -120,35 +165,55 @@ typedef NS_ENUM(NSUInteger, FLTAnEnum) { @property(nonatomic, copy, nullable) NSArray *intList; @property(nonatomic, copy, nullable) NSArray *doubleList; @property(nonatomic, copy, nullable) NSArray *boolList; -@property(nonatomic, copy, nullable) NSArray *nestedClassList; +@property(nonatomic, copy, nullable) NSArray *enumList; +@property(nonatomic, copy, nullable) NSArray *objectList; +@property(nonatomic, copy, nullable) NSArray *> *listList; +@property(nonatomic, copy, nullable) NSArray *> *mapList; +@property(nonatomic, copy, nullable) NSArray *recursiveClassList; @property(nonatomic, copy, nullable) NSDictionary *map; +@property(nonatomic, copy, nullable) NSDictionary *stringMap; +@property(nonatomic, copy, nullable) NSDictionary *intMap; +@property(nonatomic, copy, nullable) NSDictionary *enumMap; +@property(nonatomic, copy, nullable) NSDictionary *objectMap; +@property(nonatomic, copy, nullable) NSDictionary *> *listMap; +@property(nonatomic, copy, nullable) NSDictionary *> *mapMap; +@property(nonatomic, copy, nullable) + NSDictionary *recursiveClassMap; @end /// The primary purpose for this class is to ensure coverage of Swift structs /// with nullable items, as the primary [AllNullableTypes] class is being used to /// test Swift classes. @interface FLTAllNullableTypesWithoutRecursion : NSObject -+ (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool - aNullableInt:(nullable NSNumber *)aNullableInt - aNullableInt64:(nullable NSNumber *)aNullableInt64 - aNullableDouble:(nullable NSNumber *)aNullableDouble - aNullableByteArray:(nullable FlutterStandardTypedData *)aNullableByteArray - aNullable4ByteArray:(nullable FlutterStandardTypedData *)aNullable4ByteArray - aNullable8ByteArray:(nullable FlutterStandardTypedData *)aNullable8ByteArray - aNullableFloatArray:(nullable FlutterStandardTypedData *)aNullableFloatArray - nullableNestedList:(nullable NSArray *> *)nullableNestedList - nullableMapWithAnnotations: - (nullable NSDictionary *)nullableMapWithAnnotations - nullableMapWithObject:(nullable NSDictionary *)nullableMapWithObject - aNullableEnum:(nullable FLTAnEnumBox *)aNullableEnum - aNullableString:(nullable NSString *)aNullableString - aNullableObject:(nullable id)aNullableObject - list:(nullable NSArray *)list - stringList:(nullable NSArray *)stringList - intList:(nullable NSArray *)intList - doubleList:(nullable NSArray *)doubleList - boolList:(nullable NSArray *)boolList - map:(nullable NSDictionary *)map; ++ (instancetype) + makeWithANullableBool:(nullable NSNumber *)aNullableBool + aNullableInt:(nullable NSNumber *)aNullableInt + aNullableInt64:(nullable NSNumber *)aNullableInt64 + aNullableDouble:(nullable NSNumber *)aNullableDouble + aNullableByteArray:(nullable FlutterStandardTypedData *)aNullableByteArray + aNullable4ByteArray:(nullable FlutterStandardTypedData *)aNullable4ByteArray + aNullable8ByteArray:(nullable FlutterStandardTypedData *)aNullable8ByteArray + aNullableFloatArray:(nullable FlutterStandardTypedData *)aNullableFloatArray + aNullableEnum:(nullable FLTAnEnumBox *)aNullableEnum + anotherNullableEnum:(nullable FLTAnotherEnumBox *)anotherNullableEnum + aNullableString:(nullable NSString *)aNullableString + aNullableObject:(nullable id)aNullableObject + list:(nullable NSArray *)list + stringList:(nullable NSArray *)stringList + intList:(nullable NSArray *)intList + doubleList:(nullable NSArray *)doubleList + boolList:(nullable NSArray *)boolList + enumList:(nullable NSArray *)enumList + objectList:(nullable NSArray *)objectList + listList:(nullable NSArray *> *)listList + mapList:(nullable NSArray *> *)mapList + map:(nullable NSDictionary *)map + stringMap:(nullable NSDictionary *)stringMap + intMap:(nullable NSDictionary *)intMap + enumMap:(nullable NSDictionary *)enumMap + objectMap:(nullable NSDictionary *)objectMap + listMap:(nullable NSDictionary *> *)listMap + mapMap:(nullable NSDictionary *> *)mapMap; @property(nonatomic, strong, nullable) NSNumber *aNullableBool; @property(nonatomic, strong, nullable) NSNumber *aNullableInt; @property(nonatomic, strong, nullable) NSNumber *aNullableInt64; @@ -157,11 +222,8 @@ typedef NS_ENUM(NSUInteger, FLTAnEnum) { @property(nonatomic, strong, nullable) FlutterStandardTypedData *aNullable4ByteArray; @property(nonatomic, strong, nullable) FlutterStandardTypedData *aNullable8ByteArray; @property(nonatomic, strong, nullable) FlutterStandardTypedData *aNullableFloatArray; -@property(nonatomic, copy, nullable) NSArray *> *nullableNestedList; -@property(nonatomic, copy, nullable) - NSDictionary *nullableMapWithAnnotations; -@property(nonatomic, copy, nullable) NSDictionary *nullableMapWithObject; @property(nonatomic, strong, nullable) FLTAnEnumBox *aNullableEnum; +@property(nonatomic, strong, nullable) FLTAnotherEnumBox *anotherNullableEnum; @property(nonatomic, copy, nullable) NSString *aNullableString; @property(nonatomic, strong, nullable) id aNullableObject; @property(nonatomic, copy, nullable) NSArray *list; @@ -169,7 +231,17 @@ typedef NS_ENUM(NSUInteger, FLTAnEnum) { @property(nonatomic, copy, nullable) NSArray *intList; @property(nonatomic, copy, nullable) NSArray *doubleList; @property(nonatomic, copy, nullable) NSArray *boolList; +@property(nonatomic, copy, nullable) NSArray *enumList; +@property(nonatomic, copy, nullable) NSArray *objectList; +@property(nonatomic, copy, nullable) NSArray *> *listList; +@property(nonatomic, copy, nullable) NSArray *> *mapList; @property(nonatomic, copy, nullable) NSDictionary *map; +@property(nonatomic, copy, nullable) NSDictionary *stringMap; +@property(nonatomic, copy, nullable) NSDictionary *intMap; +@property(nonatomic, copy, nullable) NSDictionary *enumMap; +@property(nonatomic, copy, nullable) NSDictionary *objectMap; +@property(nonatomic, copy, nullable) NSDictionary *> *listMap; +@property(nonatomic, copy, nullable) NSDictionary *> *mapMap; @end /// A class for testing nested class handling. @@ -180,14 +252,28 @@ typedef NS_ENUM(NSUInteger, FLTAnEnum) { @interface FLTAllClassesWrapper : NSObject /// `init` unavailable to enforce nonnull fields, see the `make` class method. - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)makeWithAllNullableTypes:(FLTAllNullableTypes *)allNullableTypes - allNullableTypesWithoutRecursion: - (nullable FLTAllNullableTypesWithoutRecursion *)allNullableTypesWithoutRecursion - allTypes:(nullable FLTAllTypes *)allTypes; ++ (instancetype) + makeWithAllNullableTypes:(FLTAllNullableTypes *)allNullableTypes + allNullableTypesWithoutRecursion: + (nullable FLTAllNullableTypesWithoutRecursion *)allNullableTypesWithoutRecursion + allTypes:(nullable FLTAllTypes *)allTypes + classList:(NSArray *)classList + nullableClassList: + (nullable NSArray *)nullableClassList + classMap:(NSDictionary *)classMap + nullableClassMap: + (nullable NSDictionary *) + nullableClassMap; @property(nonatomic, strong) FLTAllNullableTypes *allNullableTypes; @property(nonatomic, strong, nullable) FLTAllNullableTypesWithoutRecursion *allNullableTypesWithoutRecursion; @property(nonatomic, strong, nullable) FLTAllTypes *allTypes; +@property(nonatomic, copy) NSArray *classList; +@property(nonatomic, copy, nullable) + NSArray *nullableClassList; +@property(nonatomic, copy) NSDictionary *classMap; +@property(nonatomic, copy, nullable) + NSDictionary *nullableClassMap; @end /// A data class containing a List, used in unit tests. @@ -247,12 +333,82 @@ NSObject *FLTGetCoreTestsCodec(void); /// @return `nil` only when `error != nil`. - (nullable NSArray *)echoList:(NSArray *)list error:(FlutterError *_Nullable *_Nonnull)error; -/// Returns the passed map, to test serialization and deserialization. +/// Returns the passed list, to test serialization and deserialization. /// /// @return `nil` only when `error != nil`. -- (nullable NSDictionary *)echoMap:(NSDictionary *)aMap +- (nullable NSArray *)echoEnumList:(NSArray *)enumList error:(FlutterError *_Nullable *_Nonnull)error; -/// Returns the passed map to test nested class serialization and deserialization. +/// Returns the passed list, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSArray *)echoClassList: + (NSArray *)classList + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed list, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSArray *)echoNonNullEnumList:(NSArray *)enumList + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed list, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSArray *) + echoNonNullClassList:(NSArray *)classList + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSDictionary *)echoMap:(NSDictionary *)map + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSDictionary *) + echoStringMap:(NSDictionary *)stringMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSDictionary *) + echoIntMap:(NSDictionary *)intMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSDictionary *) + echoEnumMap:(NSDictionary *)enumMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSDictionary *) + echoClassMap:(NSDictionary *)classMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSDictionary *) + echoNonNullStringMap:(NSDictionary *)stringMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSDictionary *) + echoNonNullIntMap:(NSDictionary *)intMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSDictionary *) + echoNonNullEnumMap:(NSDictionary *)enumMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSDictionary *) + echoNonNullClassMap:(NSDictionary *)classMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed class to test nested class serialization and deserialization. /// /// @return `nil` only when `error != nil`. - (nullable FLTAllClassesWrapper *)echoClassWrapper:(FLTAllClassesWrapper *)wrapper @@ -262,6 +418,11 @@ NSObject *FLTGetCoreTestsCodec(void); /// @return `nil` only when `error != nil`. - (FLTAnEnumBox *_Nullable)echoEnum:(FLTAnEnum)anEnum error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed enum to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (FLTAnotherEnumBox *_Nullable)echoAnotherEnum:(FLTAnotherEnum)anotherEnum + error:(FlutterError *_Nullable *_Nonnull)error; /// Returns the default string. /// /// @return `nil` only when `error != nil`. @@ -333,12 +494,62 @@ NSObject *FLTGetCoreTestsCodec(void); /// Returns the passed list, to test serialization and deserialization. - (nullable NSArray *)echoNullableList:(nullable NSArray *)aNullableList error:(FlutterError *_Nullable *_Nonnull)error; -/// Returns the passed map, to test serialization and deserialization. -- (nullable NSDictionary *)echoNullableMap: - (nullable NSDictionary *)aNullableMap +/// Returns the passed list, to test serialization and deserialization. +- (nullable NSArray *)echoNullableEnumList: + (nullable NSArray *)enumList error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed list, to test serialization and deserialization. +- (nullable NSArray *) + echoNullableClassList:(nullable NSArray *)classList + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed list, to test serialization and deserialization. +- (nullable NSArray *) + echoNullableNonNullEnumList:(nullable NSArray *)enumList + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed list, to test serialization and deserialization. +- (nullable NSArray *) + echoNullableNonNullClassList:(nullable NSArray *)classList + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +- (nullable NSDictionary *)echoNullableMap:(nullable NSDictionary *)map + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +- (nullable NSDictionary *) + echoNullableStringMap:(nullable NSDictionary *)stringMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +- (nullable NSDictionary *) + echoNullableIntMap:(nullable NSDictionary *)intMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +- (nullable NSDictionary *) + echoNullableEnumMap:(nullable NSDictionary *)enumMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +- (nullable NSDictionary *) + echoNullableClassMap:(nullable NSDictionary *)classMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +- (nullable NSDictionary *) + echoNullableNonNullStringMap:(nullable NSDictionary *)stringMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +- (nullable NSDictionary *) + echoNullableNonNullIntMap:(nullable NSDictionary *)intMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +- (nullable NSDictionary *) + echoNullableNonNullEnumMap:(nullable NSDictionary *)enumMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +- (nullable NSDictionary *) + echoNullableNonNullClassMap:(nullable NSDictionary *)classMap + error:(FlutterError *_Nullable *_Nonnull)error; - (FLTAnEnumBox *_Nullable)echoNullableEnum:(nullable FLTAnEnumBox *)anEnumBoxed error:(FlutterError *_Nullable *_Nonnull)error; +- (FLTAnotherEnumBox *_Nullable)echoAnotherNullableEnum: + (nullable FLTAnotherEnumBox *)anotherEnumBoxed + error:(FlutterError *_Nullable *_Nonnull)error; /// Returns passed in int. - (nullable NSNumber *)echoOptionalNullableInt:(nullable NSNumber *)aNullableInt error:(FlutterError *_Nullable *_Nonnull)error; @@ -370,13 +581,40 @@ NSObject *FLTGetCoreTestsCodec(void); /// Returns the passed list, to test asynchronous serialization and deserialization. - (void)echoAsyncList:(NSArray *)list completion:(void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed list, to test asynchronous serialization and deserialization. +- (void)echoAsyncEnumList:(NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed list, to test asynchronous serialization and deserialization. +- (void)echoAsyncClassList:(NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; /// Returns the passed map, to test asynchronous serialization and deserialization. -- (void)echoAsyncMap:(NSDictionary *)aMap - completion:(void (^)(NSDictionary *_Nullable, - FlutterError *_Nullable))completion; +- (void)echoAsyncMap:(NSDictionary *)map + completion:(void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed map, to test asynchronous serialization and deserialization. +- (void)echoAsyncStringMap:(NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test asynchronous serialization and deserialization. +- (void)echoAsyncIntMap:(NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test asynchronous serialization and deserialization. +- (void)echoAsyncEnumMap:(NSDictionary *)enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test asynchronous serialization and deserialization. +- (void)echoAsyncClassMap:(NSDictionary *)classMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; /// Returns the passed enum, to test asynchronous serialization and deserialization. - (void)echoAsyncEnum:(FLTAnEnum)anEnum completion:(void (^)(FLTAnEnumBox *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed enum, to test asynchronous serialization and deserialization. +- (void)echoAnotherAsyncEnum:(FLTAnotherEnum)anotherEnum + completion: + (void (^)(FLTAnotherEnumBox *_Nullable, FlutterError *_Nullable))completion; /// Responds with an error from an async function returning a value. - (void)throwAsyncErrorWithCompletion:(void (^)(id _Nullable, FlutterError *_Nullable))completion; /// Responds with an error from an async void function. @@ -420,14 +658,43 @@ NSObject *FLTGetCoreTestsCodec(void); /// Returns the passed list, to test asynchronous serialization and deserialization. - (void)echoAsyncNullableList:(nullable NSArray *)list completion:(void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed list, to test asynchronous serialization and deserialization. +- (void)echoAsyncNullableEnumList:(nullable NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed list, to test asynchronous serialization and deserialization. +- (void)echoAsyncNullableClassList:(nullable NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; /// Returns the passed map, to test asynchronous serialization and deserialization. -- (void)echoAsyncNullableMap:(nullable NSDictionary *)aMap - completion:(void (^)(NSDictionary *_Nullable, +- (void)echoAsyncNullableMap:(nullable NSDictionary *)map + completion:(void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed map, to test asynchronous serialization and deserialization. +- (void)echoAsyncNullableStringMap:(nullable NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test asynchronous serialization and deserialization. +- (void)echoAsyncNullableIntMap:(nullable NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test asynchronous serialization and deserialization. +- (void)echoAsyncNullableEnumMap:(nullable NSDictionary *)enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test asynchronous serialization and deserialization. +- (void) + echoAsyncNullableClassMap:(nullable NSDictionary *)classMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; /// Returns the passed enum, to test asynchronous serialization and deserialization. - (void)echoAsyncNullableEnum:(nullable FLTAnEnumBox *)anEnumBoxed completion: (void (^)(FLTAnEnumBox *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed enum, to test asynchronous serialization and deserialization. +- (void)echoAnotherAsyncNullableEnum:(nullable FLTAnotherEnumBox *)anotherEnumBoxed + completion:(void (^)(FLTAnotherEnumBox *_Nullable, + FlutterError *_Nullable))completion; - (void)callFlutterNoopWithCompletion:(void (^)(FlutterError *_Nullable))completion; - (void)callFlutterThrowErrorWithCompletion:(void (^)(id _Nullable, FlutterError *_Nullable))completion; @@ -471,11 +738,54 @@ NSObject *FLTGetCoreTestsCodec(void); FlutterError *_Nullable))completion; - (void)callFlutterEchoList:(NSArray *)list completion:(void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion; -- (void)callFlutterEchoMap:(NSDictionary *)aMap - completion:(void (^)(NSDictionary *_Nullable, - FlutterError *_Nullable))completion; +- (void)callFlutterEchoEnumList:(NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoClassList:(NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNonNullEnumList:(NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNonNullClassList:(NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoMap:(NSDictionary *)map + completion: + (void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion; +- (void)callFlutterEchoStringMap:(NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoIntMap:(NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoEnumMap:(NSDictionary *)enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoClassMap:(NSDictionary *)classMap + completion: + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNonNullStringMap:(NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNonNullIntMap:(NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNonNullEnumMap:(NSDictionary *)enumMap + completion: + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void) + callFlutterEchoNonNullClassMap:(NSDictionary *)classMap + completion: + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; - (void)callFlutterEchoEnum:(FLTAnEnum)anEnum completion:(void (^)(FLTAnEnumBox *_Nullable, FlutterError *_Nullable))completion; +- (void)callFlutterEchoAnotherEnum:(FLTAnotherEnum)anotherEnum + completion:(void (^)(FLTAnotherEnumBox *_Nullable, + FlutterError *_Nullable))completion; - (void)callFlutterEchoNullableBool:(nullable NSNumber *)aBool completion: (void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion; @@ -494,12 +804,65 @@ NSObject *FLTGetCoreTestsCodec(void); - (void)callFlutterEchoNullableList:(nullable NSArray *)list completion: (void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion; -- (void)callFlutterEchoNullableMap:(nullable NSDictionary *)aMap - completion:(void (^)(NSDictionary *_Nullable, +- (void)callFlutterEchoNullableEnumList:(nullable NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNullableClassList:(nullable NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNullableNonNullEnumList:(nullable NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNullableNonNullClassList:(nullable NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNullableMap:(nullable NSDictionary *)map + completion:(void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion; +- (void)callFlutterEchoNullableStringMap:(nullable NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNullableIntMap:(nullable NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNullableEnumMap: + (nullable NSDictionary *)enumMap + completion: + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void) + callFlutterEchoNullableClassMap: + (nullable NSDictionary *)classMap + completion: + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNullableNonNullStringMap: + (nullable NSDictionary *)stringMap + completion: + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNullableNonNullIntMap:(nullable NSDictionary *)intMap + completion: + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNullableNonNullEnumMap: + (nullable NSDictionary *)enumMap + completion: + (void (^)( + NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNullableNonNullClassMap: + (nullable NSDictionary *)classMap + completion: + (void (^)(NSDictionary + *_Nullable, + FlutterError *_Nullable))completion; - (void)callFlutterEchoNullableEnum:(nullable FLTAnEnumBox *)anEnumBoxed completion: (void (^)(FLTAnEnumBox *_Nullable, FlutterError *_Nullable))completion; +- (void)callFlutterEchoAnotherNullableEnum:(nullable FLTAnotherEnumBox *)anotherEnumBoxed + completion:(void (^)(FLTAnotherEnumBox *_Nullable, + FlutterError *_Nullable))completion; - (void)callFlutterSmallApiEchoString:(NSString *)aString completion: (void (^)(NSString *_Nullable, FlutterError *_Nullable))completion; @@ -574,13 +937,63 @@ extern void SetUpFLTHostIntegrationCoreApiWithSuffix( /// Returns the passed list, to test serialization and deserialization. - (void)echoList:(NSArray *)list completion:(void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed list, to test serialization and deserialization. +- (void)echoEnumList:(NSArray *)enumList + completion: + (void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed list, to test serialization and deserialization. +- (void)echoClassList:(NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed list, to test serialization and deserialization. +- (void)echoNonNullEnumList:(NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed list, to test serialization and deserialization. +- (void)echoNonNullClassList:(NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoMap:(NSDictionary *)map + completion:(void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoStringMap:(NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoIntMap:(NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoEnumMap:(NSDictionary *)enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoClassMap:(NSDictionary *)classMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoNonNullStringMap:(NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoNonNullIntMap:(NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoNonNullEnumMap:(NSDictionary *)enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; /// Returns the passed map, to test serialization and deserialization. -- (void)echoMap:(NSDictionary *)aMap - completion: - (void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion; +- (void)echoNonNullClassMap:(NSDictionary *)classMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; /// Returns the passed enum to test serialization and deserialization. - (void)echoEnum:(FLTAnEnum)anEnum completion:(void (^)(FLTAnEnumBox *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed enum to test serialization and deserialization. +- (void)echoAnotherEnum:(FLTAnotherEnum)anotherEnum + completion:(void (^)(FLTAnotherEnumBox *_Nullable, FlutterError *_Nullable))completion; /// Returns the passed boolean, to test serialization and deserialization. - (void)echoNullableBool:(nullable NSNumber *)aBool completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion; @@ -600,13 +1013,68 @@ extern void SetUpFLTHostIntegrationCoreApiWithSuffix( /// Returns the passed list, to test serialization and deserialization. - (void)echoNullableList:(nullable NSArray *)list completion:(void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed list, to test serialization and deserialization. +- (void)echoNullableEnumList:(nullable NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed list, to test serialization and deserialization. +- (void)echoNullableClassList:(nullable NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed list, to test serialization and deserialization. +- (void)echoNullableNonNullEnumList:(nullable NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed list, to test serialization and deserialization. +- (void)echoNullableNonNullClassList:(nullable NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; /// Returns the passed map, to test serialization and deserialization. -- (void)echoNullableMap:(nullable NSDictionary *)aMap - completion:(void (^)(NSDictionary *_Nullable, - FlutterError *_Nullable))completion; +- (void)echoNullableMap:(nullable NSDictionary *)map + completion: + (void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoNullableStringMap:(nullable NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoNullableIntMap:(nullable NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoNullableEnumMap:(nullable NSDictionary *)enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoNullableClassMap:(nullable NSDictionary *)classMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoNullableNonNullStringMap:(nullable NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoNullableNonNullIntMap:(nullable NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoNullableNonNullEnumMap:(nullable NSDictionary *)enumMap + completion: + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoNullableNonNullClassMap: + (nullable NSDictionary *)classMap + completion: + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; /// Returns the passed enum to test serialization and deserialization. - (void)echoNullableEnum:(nullable FLTAnEnumBox *)anEnumBoxed completion:(void (^)(FLTAnEnumBox *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed enum to test serialization and deserialization. +- (void)echoAnotherNullableEnum:(nullable FLTAnotherEnumBox *)anotherEnumBoxed + completion:(void (^)(FLTAnotherEnumBox *_Nullable, + FlutterError *_Nullable))completion; /// A no-op function taking no arguments and returning no value, to sanity /// test basic asynchronous calling. - (void)noopAsyncWithCompletion:(void (^)(FlutterError *_Nullable))completion; diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m index 6dae6ff2abde..2cc3da7877d8 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m @@ -50,6 +50,22 @@ - (instancetype)initWithValue:(FLTAnEnum)value { } @end +@implementation FLTAnotherEnumBox +- (instancetype)initWithValue:(FLTAnotherEnum)value { + self = [super init]; + if (self) { + _value = value; + } + return self; +} +@end + +@interface FLTUnusedClass () ++ (FLTUnusedClass *)fromList:(NSArray *)list; ++ (nullable FLTUnusedClass *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + @interface FLTAllTypes () + (FLTAllTypes *)fromList:(NSArray *)list; + (nullable FLTAllTypes *)nullableFromList:(NSArray *)list; @@ -80,6 +96,27 @@ + (nullable FLTTestMessage *)nullableFromList:(NSArray *)list; - (NSArray *)toList; @end +@implementation FLTUnusedClass ++ (instancetype)makeWithAField:(nullable id)aField { + FLTUnusedClass *pigeonResult = [[FLTUnusedClass alloc] init]; + pigeonResult.aField = aField; + return pigeonResult; +} ++ (FLTUnusedClass *)fromList:(NSArray *)list { + FLTUnusedClass *pigeonResult = [[FLTUnusedClass alloc] init]; + pigeonResult.aField = GetNullableObjectAtIndex(list, 0); + return pigeonResult; +} ++ (nullable FLTUnusedClass *)nullableFromList:(NSArray *)list { + return (list) ? [FLTUnusedClass fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + self.aField ?: [NSNull null], + ]; +} +@end + @implementation FLTAllTypes + (instancetype)makeWithABool:(BOOL)aBool anInt:(NSInteger)anInt @@ -90,6 +127,7 @@ + (instancetype)makeWithABool:(BOOL)aBool a8ByteArray:(FlutterStandardTypedData *)a8ByteArray aFloatArray:(FlutterStandardTypedData *)aFloatArray anEnum:(FLTAnEnum)anEnum + anotherEnum:(FLTAnotherEnum)anotherEnum aString:(NSString *)aString anObject:(id)anObject list:(NSArray *)list @@ -97,7 +135,17 @@ + (instancetype)makeWithABool:(BOOL)aBool intList:(NSArray *)intList doubleList:(NSArray *)doubleList boolList:(NSArray *)boolList - map:(NSDictionary *)map { + enumList:(NSArray *)enumList + objectList:(NSArray *)objectList + listList:(NSArray *> *)listList + mapList:(NSArray *> *)mapList + map:(NSDictionary *)map + stringMap:(NSDictionary *)stringMap + intMap:(NSDictionary *)intMap + enumMap:(NSDictionary *)enumMap + objectMap:(NSDictionary *)objectMap + listMap:(NSDictionary *> *)listMap + mapMap:(NSDictionary *> *)mapMap { FLTAllTypes *pigeonResult = [[FLTAllTypes alloc] init]; pigeonResult.aBool = aBool; pigeonResult.anInt = anInt; @@ -108,6 +156,7 @@ + (instancetype)makeWithABool:(BOOL)aBool pigeonResult.a8ByteArray = a8ByteArray; pigeonResult.aFloatArray = aFloatArray; pigeonResult.anEnum = anEnum; + pigeonResult.anotherEnum = anotherEnum; pigeonResult.aString = aString; pigeonResult.anObject = anObject; pigeonResult.list = list; @@ -115,7 +164,17 @@ + (instancetype)makeWithABool:(BOOL)aBool pigeonResult.intList = intList; pigeonResult.doubleList = doubleList; pigeonResult.boolList = boolList; + pigeonResult.enumList = enumList; + pigeonResult.objectList = objectList; + pigeonResult.listList = listList; + pigeonResult.mapList = mapList; pigeonResult.map = map; + pigeonResult.stringMap = stringMap; + pigeonResult.intMap = intMap; + pigeonResult.enumMap = enumMap; + pigeonResult.objectMap = objectMap; + pigeonResult.listMap = listMap; + pigeonResult.mapMap = mapMap; return pigeonResult; } + (FLTAllTypes *)fromList:(NSArray *)list { @@ -128,16 +187,28 @@ + (FLTAllTypes *)fromList:(NSArray *)list { pigeonResult.a4ByteArray = GetNullableObjectAtIndex(list, 5); pigeonResult.a8ByteArray = GetNullableObjectAtIndex(list, 6); pigeonResult.aFloatArray = GetNullableObjectAtIndex(list, 7); - FLTAnEnumBox *enumBox = GetNullableObjectAtIndex(list, 8); - pigeonResult.anEnum = enumBox.value; - pigeonResult.aString = GetNullableObjectAtIndex(list, 9); - pigeonResult.anObject = GetNullableObjectAtIndex(list, 10); - pigeonResult.list = GetNullableObjectAtIndex(list, 11); - pigeonResult.stringList = GetNullableObjectAtIndex(list, 12); - pigeonResult.intList = GetNullableObjectAtIndex(list, 13); - pigeonResult.doubleList = GetNullableObjectAtIndex(list, 14); - pigeonResult.boolList = GetNullableObjectAtIndex(list, 15); - pigeonResult.map = GetNullableObjectAtIndex(list, 16); + FLTAnEnumBox *boxedFLTAnEnum = GetNullableObjectAtIndex(list, 8); + pigeonResult.anEnum = boxedFLTAnEnum.value; + FLTAnotherEnumBox *boxedFLTAnotherEnum = GetNullableObjectAtIndex(list, 9); + pigeonResult.anotherEnum = boxedFLTAnotherEnum.value; + pigeonResult.aString = GetNullableObjectAtIndex(list, 10); + pigeonResult.anObject = GetNullableObjectAtIndex(list, 11); + pigeonResult.list = GetNullableObjectAtIndex(list, 12); + pigeonResult.stringList = GetNullableObjectAtIndex(list, 13); + pigeonResult.intList = GetNullableObjectAtIndex(list, 14); + pigeonResult.doubleList = GetNullableObjectAtIndex(list, 15); + pigeonResult.boolList = GetNullableObjectAtIndex(list, 16); + pigeonResult.enumList = GetNullableObjectAtIndex(list, 17); + pigeonResult.objectList = GetNullableObjectAtIndex(list, 18); + pigeonResult.listList = GetNullableObjectAtIndex(list, 19); + pigeonResult.mapList = GetNullableObjectAtIndex(list, 20); + pigeonResult.map = GetNullableObjectAtIndex(list, 21); + pigeonResult.stringMap = GetNullableObjectAtIndex(list, 22); + pigeonResult.intMap = GetNullableObjectAtIndex(list, 23); + pigeonResult.enumMap = GetNullableObjectAtIndex(list, 24); + pigeonResult.objectMap = GetNullableObjectAtIndex(list, 25); + pigeonResult.listMap = GetNullableObjectAtIndex(list, 26); + pigeonResult.mapMap = GetNullableObjectAtIndex(list, 27); return pigeonResult; } + (nullable FLTAllTypes *)nullableFromList:(NSArray *)list { @@ -154,6 +225,7 @@ + (nullable FLTAllTypes *)nullableFromList:(NSArray *)list { self.a8ByteArray ?: [NSNull null], self.aFloatArray ?: [NSNull null], [[FLTAnEnumBox alloc] initWithValue:self.anEnum], + [[FLTAnotherEnumBox alloc] initWithValue:self.anotherEnum], self.aString ?: [NSNull null], self.anObject ?: [NSNull null], self.list ?: [NSNull null], @@ -161,35 +233,55 @@ + (nullable FLTAllTypes *)nullableFromList:(NSArray *)list { self.intList ?: [NSNull null], self.doubleList ?: [NSNull null], self.boolList ?: [NSNull null], + self.enumList ?: [NSNull null], + self.objectList ?: [NSNull null], + self.listList ?: [NSNull null], + self.mapList ?: [NSNull null], self.map ?: [NSNull null], + self.stringMap ?: [NSNull null], + self.intMap ?: [NSNull null], + self.enumMap ?: [NSNull null], + self.objectMap ?: [NSNull null], + self.listMap ?: [NSNull null], + self.mapMap ?: [NSNull null], ]; } @end @implementation FLTAllNullableTypes -+ (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool - aNullableInt:(nullable NSNumber *)aNullableInt - aNullableInt64:(nullable NSNumber *)aNullableInt64 - aNullableDouble:(nullable NSNumber *)aNullableDouble - aNullableByteArray:(nullable FlutterStandardTypedData *)aNullableByteArray - aNullable4ByteArray:(nullable FlutterStandardTypedData *)aNullable4ByteArray - aNullable8ByteArray:(nullable FlutterStandardTypedData *)aNullable8ByteArray - aNullableFloatArray:(nullable FlutterStandardTypedData *)aNullableFloatArray - nullableNestedList:(nullable NSArray *> *)nullableNestedList - nullableMapWithAnnotations: - (nullable NSDictionary *)nullableMapWithAnnotations - nullableMapWithObject:(nullable NSDictionary *)nullableMapWithObject - aNullableEnum:(nullable FLTAnEnumBox *)aNullableEnum - aNullableString:(nullable NSString *)aNullableString - aNullableObject:(nullable id)aNullableObject - allNullableTypes:(nullable FLTAllNullableTypes *)allNullableTypes - list:(nullable NSArray *)list - stringList:(nullable NSArray *)stringList - intList:(nullable NSArray *)intList - doubleList:(nullable NSArray *)doubleList - boolList:(nullable NSArray *)boolList - nestedClassList:(nullable NSArray *)nestedClassList - map:(nullable NSDictionary *)map { ++ (instancetype) + makeWithANullableBool:(nullable NSNumber *)aNullableBool + aNullableInt:(nullable NSNumber *)aNullableInt + aNullableInt64:(nullable NSNumber *)aNullableInt64 + aNullableDouble:(nullable NSNumber *)aNullableDouble + aNullableByteArray:(nullable FlutterStandardTypedData *)aNullableByteArray + aNullable4ByteArray:(nullable FlutterStandardTypedData *)aNullable4ByteArray + aNullable8ByteArray:(nullable FlutterStandardTypedData *)aNullable8ByteArray + aNullableFloatArray:(nullable FlutterStandardTypedData *)aNullableFloatArray + aNullableEnum:(nullable FLTAnEnumBox *)aNullableEnum + anotherNullableEnum:(nullable FLTAnotherEnumBox *)anotherNullableEnum + aNullableString:(nullable NSString *)aNullableString + aNullableObject:(nullable id)aNullableObject + allNullableTypes:(nullable FLTAllNullableTypes *)allNullableTypes + list:(nullable NSArray *)list + stringList:(nullable NSArray *)stringList + intList:(nullable NSArray *)intList + doubleList:(nullable NSArray *)doubleList + boolList:(nullable NSArray *)boolList + enumList:(nullable NSArray *)enumList + objectList:(nullable NSArray *)objectList + listList:(nullable NSArray *> *)listList + mapList:(nullable NSArray *> *)mapList + recursiveClassList:(nullable NSArray *)recursiveClassList + map:(nullable NSDictionary *)map + stringMap:(nullable NSDictionary *)stringMap + intMap:(nullable NSDictionary *)intMap + enumMap:(nullable NSDictionary *)enumMap + objectMap:(nullable NSDictionary *)objectMap + listMap:(nullable NSDictionary *> *)listMap + mapMap:(nullable NSDictionary *> *)mapMap + recursiveClassMap: + (nullable NSDictionary *)recursiveClassMap { FLTAllNullableTypes *pigeonResult = [[FLTAllNullableTypes alloc] init]; pigeonResult.aNullableBool = aNullableBool; pigeonResult.aNullableInt = aNullableInt; @@ -199,10 +291,8 @@ + (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool pigeonResult.aNullable4ByteArray = aNullable4ByteArray; pigeonResult.aNullable8ByteArray = aNullable8ByteArray; pigeonResult.aNullableFloatArray = aNullableFloatArray; - pigeonResult.nullableNestedList = nullableNestedList; - pigeonResult.nullableMapWithAnnotations = nullableMapWithAnnotations; - pigeonResult.nullableMapWithObject = nullableMapWithObject; pigeonResult.aNullableEnum = aNullableEnum; + pigeonResult.anotherNullableEnum = anotherNullableEnum; pigeonResult.aNullableString = aNullableString; pigeonResult.aNullableObject = aNullableObject; pigeonResult.allNullableTypes = allNullableTypes; @@ -211,8 +301,19 @@ + (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool pigeonResult.intList = intList; pigeonResult.doubleList = doubleList; pigeonResult.boolList = boolList; - pigeonResult.nestedClassList = nestedClassList; + pigeonResult.enumList = enumList; + pigeonResult.objectList = objectList; + pigeonResult.listList = listList; + pigeonResult.mapList = mapList; + pigeonResult.recursiveClassList = recursiveClassList; pigeonResult.map = map; + pigeonResult.stringMap = stringMap; + pigeonResult.intMap = intMap; + pigeonResult.enumMap = enumMap; + pigeonResult.objectMap = objectMap; + pigeonResult.listMap = listMap; + pigeonResult.mapMap = mapMap; + pigeonResult.recursiveClassMap = recursiveClassMap; return pigeonResult; } + (FLTAllNullableTypes *)fromList:(NSArray *)list { @@ -225,20 +326,29 @@ + (FLTAllNullableTypes *)fromList:(NSArray *)list { pigeonResult.aNullable4ByteArray = GetNullableObjectAtIndex(list, 5); pigeonResult.aNullable8ByteArray = GetNullableObjectAtIndex(list, 6); pigeonResult.aNullableFloatArray = GetNullableObjectAtIndex(list, 7); - pigeonResult.nullableNestedList = GetNullableObjectAtIndex(list, 8); - pigeonResult.nullableMapWithAnnotations = GetNullableObjectAtIndex(list, 9); - pigeonResult.nullableMapWithObject = GetNullableObjectAtIndex(list, 10); - pigeonResult.aNullableEnum = GetNullableObjectAtIndex(list, 11); - pigeonResult.aNullableString = GetNullableObjectAtIndex(list, 12); - pigeonResult.aNullableObject = GetNullableObjectAtIndex(list, 13); - pigeonResult.allNullableTypes = GetNullableObjectAtIndex(list, 14); - pigeonResult.list = GetNullableObjectAtIndex(list, 15); - pigeonResult.stringList = GetNullableObjectAtIndex(list, 16); - pigeonResult.intList = GetNullableObjectAtIndex(list, 17); - pigeonResult.doubleList = GetNullableObjectAtIndex(list, 18); - pigeonResult.boolList = GetNullableObjectAtIndex(list, 19); - pigeonResult.nestedClassList = GetNullableObjectAtIndex(list, 20); - pigeonResult.map = GetNullableObjectAtIndex(list, 21); + pigeonResult.aNullableEnum = GetNullableObjectAtIndex(list, 8); + pigeonResult.anotherNullableEnum = GetNullableObjectAtIndex(list, 9); + pigeonResult.aNullableString = GetNullableObjectAtIndex(list, 10); + pigeonResult.aNullableObject = GetNullableObjectAtIndex(list, 11); + pigeonResult.allNullableTypes = GetNullableObjectAtIndex(list, 12); + pigeonResult.list = GetNullableObjectAtIndex(list, 13); + pigeonResult.stringList = GetNullableObjectAtIndex(list, 14); + pigeonResult.intList = GetNullableObjectAtIndex(list, 15); + pigeonResult.doubleList = GetNullableObjectAtIndex(list, 16); + pigeonResult.boolList = GetNullableObjectAtIndex(list, 17); + pigeonResult.enumList = GetNullableObjectAtIndex(list, 18); + pigeonResult.objectList = GetNullableObjectAtIndex(list, 19); + pigeonResult.listList = GetNullableObjectAtIndex(list, 20); + pigeonResult.mapList = GetNullableObjectAtIndex(list, 21); + pigeonResult.recursiveClassList = GetNullableObjectAtIndex(list, 22); + pigeonResult.map = GetNullableObjectAtIndex(list, 23); + pigeonResult.stringMap = GetNullableObjectAtIndex(list, 24); + pigeonResult.intMap = GetNullableObjectAtIndex(list, 25); + pigeonResult.enumMap = GetNullableObjectAtIndex(list, 26); + pigeonResult.objectMap = GetNullableObjectAtIndex(list, 27); + pigeonResult.listMap = GetNullableObjectAtIndex(list, 28); + pigeonResult.mapMap = GetNullableObjectAtIndex(list, 29); + pigeonResult.recursiveClassMap = GetNullableObjectAtIndex(list, 30); return pigeonResult; } + (nullable FLTAllNullableTypes *)nullableFromList:(NSArray *)list { @@ -254,10 +364,8 @@ + (nullable FLTAllNullableTypes *)nullableFromList:(NSArray *)list { self.aNullable4ByteArray ?: [NSNull null], self.aNullable8ByteArray ?: [NSNull null], self.aNullableFloatArray ?: [NSNull null], - self.nullableNestedList ?: [NSNull null], - self.nullableMapWithAnnotations ?: [NSNull null], - self.nullableMapWithObject ?: [NSNull null], self.aNullableEnum ?: [NSNull null], + self.anotherNullableEnum ?: [NSNull null], self.aNullableString ?: [NSNull null], self.aNullableObject ?: [NSNull null], self.allNullableTypes ?: [NSNull null], @@ -266,34 +374,53 @@ + (nullable FLTAllNullableTypes *)nullableFromList:(NSArray *)list { self.intList ?: [NSNull null], self.doubleList ?: [NSNull null], self.boolList ?: [NSNull null], - self.nestedClassList ?: [NSNull null], + self.enumList ?: [NSNull null], + self.objectList ?: [NSNull null], + self.listList ?: [NSNull null], + self.mapList ?: [NSNull null], + self.recursiveClassList ?: [NSNull null], self.map ?: [NSNull null], + self.stringMap ?: [NSNull null], + self.intMap ?: [NSNull null], + self.enumMap ?: [NSNull null], + self.objectMap ?: [NSNull null], + self.listMap ?: [NSNull null], + self.mapMap ?: [NSNull null], + self.recursiveClassMap ?: [NSNull null], ]; } @end @implementation FLTAllNullableTypesWithoutRecursion -+ (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool - aNullableInt:(nullable NSNumber *)aNullableInt - aNullableInt64:(nullable NSNumber *)aNullableInt64 - aNullableDouble:(nullable NSNumber *)aNullableDouble - aNullableByteArray:(nullable FlutterStandardTypedData *)aNullableByteArray - aNullable4ByteArray:(nullable FlutterStandardTypedData *)aNullable4ByteArray - aNullable8ByteArray:(nullable FlutterStandardTypedData *)aNullable8ByteArray - aNullableFloatArray:(nullable FlutterStandardTypedData *)aNullableFloatArray - nullableNestedList:(nullable NSArray *> *)nullableNestedList - nullableMapWithAnnotations: - (nullable NSDictionary *)nullableMapWithAnnotations - nullableMapWithObject:(nullable NSDictionary *)nullableMapWithObject - aNullableEnum:(nullable FLTAnEnumBox *)aNullableEnum - aNullableString:(nullable NSString *)aNullableString - aNullableObject:(nullable id)aNullableObject - list:(nullable NSArray *)list - stringList:(nullable NSArray *)stringList - intList:(nullable NSArray *)intList - doubleList:(nullable NSArray *)doubleList - boolList:(nullable NSArray *)boolList - map:(nullable NSDictionary *)map { ++ (instancetype) + makeWithANullableBool:(nullable NSNumber *)aNullableBool + aNullableInt:(nullable NSNumber *)aNullableInt + aNullableInt64:(nullable NSNumber *)aNullableInt64 + aNullableDouble:(nullable NSNumber *)aNullableDouble + aNullableByteArray:(nullable FlutterStandardTypedData *)aNullableByteArray + aNullable4ByteArray:(nullable FlutterStandardTypedData *)aNullable4ByteArray + aNullable8ByteArray:(nullable FlutterStandardTypedData *)aNullable8ByteArray + aNullableFloatArray:(nullable FlutterStandardTypedData *)aNullableFloatArray + aNullableEnum:(nullable FLTAnEnumBox *)aNullableEnum + anotherNullableEnum:(nullable FLTAnotherEnumBox *)anotherNullableEnum + aNullableString:(nullable NSString *)aNullableString + aNullableObject:(nullable id)aNullableObject + list:(nullable NSArray *)list + stringList:(nullable NSArray *)stringList + intList:(nullable NSArray *)intList + doubleList:(nullable NSArray *)doubleList + boolList:(nullable NSArray *)boolList + enumList:(nullable NSArray *)enumList + objectList:(nullable NSArray *)objectList + listList:(nullable NSArray *> *)listList + mapList:(nullable NSArray *> *)mapList + map:(nullable NSDictionary *)map + stringMap:(nullable NSDictionary *)stringMap + intMap:(nullable NSDictionary *)intMap + enumMap:(nullable NSDictionary *)enumMap + objectMap:(nullable NSDictionary *)objectMap + listMap:(nullable NSDictionary *> *)listMap + mapMap:(nullable NSDictionary *> *)mapMap { FLTAllNullableTypesWithoutRecursion *pigeonResult = [[FLTAllNullableTypesWithoutRecursion alloc] init]; pigeonResult.aNullableBool = aNullableBool; @@ -304,10 +431,8 @@ + (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool pigeonResult.aNullable4ByteArray = aNullable4ByteArray; pigeonResult.aNullable8ByteArray = aNullable8ByteArray; pigeonResult.aNullableFloatArray = aNullableFloatArray; - pigeonResult.nullableNestedList = nullableNestedList; - pigeonResult.nullableMapWithAnnotations = nullableMapWithAnnotations; - pigeonResult.nullableMapWithObject = nullableMapWithObject; pigeonResult.aNullableEnum = aNullableEnum; + pigeonResult.anotherNullableEnum = anotherNullableEnum; pigeonResult.aNullableString = aNullableString; pigeonResult.aNullableObject = aNullableObject; pigeonResult.list = list; @@ -315,7 +440,17 @@ + (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool pigeonResult.intList = intList; pigeonResult.doubleList = doubleList; pigeonResult.boolList = boolList; + pigeonResult.enumList = enumList; + pigeonResult.objectList = objectList; + pigeonResult.listList = listList; + pigeonResult.mapList = mapList; pigeonResult.map = map; + pigeonResult.stringMap = stringMap; + pigeonResult.intMap = intMap; + pigeonResult.enumMap = enumMap; + pigeonResult.objectMap = objectMap; + pigeonResult.listMap = listMap; + pigeonResult.mapMap = mapMap; return pigeonResult; } + (FLTAllNullableTypesWithoutRecursion *)fromList:(NSArray *)list { @@ -329,18 +464,26 @@ + (FLTAllNullableTypesWithoutRecursion *)fromList:(NSArray *)list { pigeonResult.aNullable4ByteArray = GetNullableObjectAtIndex(list, 5); pigeonResult.aNullable8ByteArray = GetNullableObjectAtIndex(list, 6); pigeonResult.aNullableFloatArray = GetNullableObjectAtIndex(list, 7); - pigeonResult.nullableNestedList = GetNullableObjectAtIndex(list, 8); - pigeonResult.nullableMapWithAnnotations = GetNullableObjectAtIndex(list, 9); - pigeonResult.nullableMapWithObject = GetNullableObjectAtIndex(list, 10); - pigeonResult.aNullableEnum = GetNullableObjectAtIndex(list, 11); - pigeonResult.aNullableString = GetNullableObjectAtIndex(list, 12); - pigeonResult.aNullableObject = GetNullableObjectAtIndex(list, 13); - pigeonResult.list = GetNullableObjectAtIndex(list, 14); - pigeonResult.stringList = GetNullableObjectAtIndex(list, 15); - pigeonResult.intList = GetNullableObjectAtIndex(list, 16); - pigeonResult.doubleList = GetNullableObjectAtIndex(list, 17); - pigeonResult.boolList = GetNullableObjectAtIndex(list, 18); - pigeonResult.map = GetNullableObjectAtIndex(list, 19); + pigeonResult.aNullableEnum = GetNullableObjectAtIndex(list, 8); + pigeonResult.anotherNullableEnum = GetNullableObjectAtIndex(list, 9); + pigeonResult.aNullableString = GetNullableObjectAtIndex(list, 10); + pigeonResult.aNullableObject = GetNullableObjectAtIndex(list, 11); + pigeonResult.list = GetNullableObjectAtIndex(list, 12); + pigeonResult.stringList = GetNullableObjectAtIndex(list, 13); + pigeonResult.intList = GetNullableObjectAtIndex(list, 14); + pigeonResult.doubleList = GetNullableObjectAtIndex(list, 15); + pigeonResult.boolList = GetNullableObjectAtIndex(list, 16); + pigeonResult.enumList = GetNullableObjectAtIndex(list, 17); + pigeonResult.objectList = GetNullableObjectAtIndex(list, 18); + pigeonResult.listList = GetNullableObjectAtIndex(list, 19); + pigeonResult.mapList = GetNullableObjectAtIndex(list, 20); + pigeonResult.map = GetNullableObjectAtIndex(list, 21); + pigeonResult.stringMap = GetNullableObjectAtIndex(list, 22); + pigeonResult.intMap = GetNullableObjectAtIndex(list, 23); + pigeonResult.enumMap = GetNullableObjectAtIndex(list, 24); + pigeonResult.objectMap = GetNullableObjectAtIndex(list, 25); + pigeonResult.listMap = GetNullableObjectAtIndex(list, 26); + pigeonResult.mapMap = GetNullableObjectAtIndex(list, 27); return pigeonResult; } + (nullable FLTAllNullableTypesWithoutRecursion *)nullableFromList:(NSArray *)list { @@ -356,10 +499,8 @@ + (nullable FLTAllNullableTypesWithoutRecursion *)nullableFromList:(NSArray self.aNullable4ByteArray ?: [NSNull null], self.aNullable8ByteArray ?: [NSNull null], self.aNullableFloatArray ?: [NSNull null], - self.nullableNestedList ?: [NSNull null], - self.nullableMapWithAnnotations ?: [NSNull null], - self.nullableMapWithObject ?: [NSNull null], self.aNullableEnum ?: [NSNull null], + self.anotherNullableEnum ?: [NSNull null], self.aNullableString ?: [NSNull null], self.aNullableObject ?: [NSNull null], self.list ?: [NSNull null], @@ -367,20 +508,42 @@ + (nullable FLTAllNullableTypesWithoutRecursion *)nullableFromList:(NSArray self.intList ?: [NSNull null], self.doubleList ?: [NSNull null], self.boolList ?: [NSNull null], + self.enumList ?: [NSNull null], + self.objectList ?: [NSNull null], + self.listList ?: [NSNull null], + self.mapList ?: [NSNull null], self.map ?: [NSNull null], + self.stringMap ?: [NSNull null], + self.intMap ?: [NSNull null], + self.enumMap ?: [NSNull null], + self.objectMap ?: [NSNull null], + self.listMap ?: [NSNull null], + self.mapMap ?: [NSNull null], ]; } @end @implementation FLTAllClassesWrapper -+ (instancetype)makeWithAllNullableTypes:(FLTAllNullableTypes *)allNullableTypes - allNullableTypesWithoutRecursion: - (nullable FLTAllNullableTypesWithoutRecursion *)allNullableTypesWithoutRecursion - allTypes:(nullable FLTAllTypes *)allTypes { ++ (instancetype) + makeWithAllNullableTypes:(FLTAllNullableTypes *)allNullableTypes + allNullableTypesWithoutRecursion: + (nullable FLTAllNullableTypesWithoutRecursion *)allNullableTypesWithoutRecursion + allTypes:(nullable FLTAllTypes *)allTypes + classList:(NSArray *)classList + nullableClassList: + (nullable NSArray *)nullableClassList + classMap:(NSDictionary *)classMap + nullableClassMap: + (nullable NSDictionary *) + nullableClassMap { FLTAllClassesWrapper *pigeonResult = [[FLTAllClassesWrapper alloc] init]; pigeonResult.allNullableTypes = allNullableTypes; pigeonResult.allNullableTypesWithoutRecursion = allNullableTypesWithoutRecursion; pigeonResult.allTypes = allTypes; + pigeonResult.classList = classList; + pigeonResult.nullableClassList = nullableClassList; + pigeonResult.classMap = classMap; + pigeonResult.nullableClassMap = nullableClassMap; return pigeonResult; } + (FLTAllClassesWrapper *)fromList:(NSArray *)list { @@ -388,6 +551,10 @@ + (FLTAllClassesWrapper *)fromList:(NSArray *)list { pigeonResult.allNullableTypes = GetNullableObjectAtIndex(list, 0); pigeonResult.allNullableTypesWithoutRecursion = GetNullableObjectAtIndex(list, 1); pigeonResult.allTypes = GetNullableObjectAtIndex(list, 2); + pigeonResult.classList = GetNullableObjectAtIndex(list, 3); + pigeonResult.nullableClassList = GetNullableObjectAtIndex(list, 4); + pigeonResult.classMap = GetNullableObjectAtIndex(list, 5); + pigeonResult.nullableClassMap = GetNullableObjectAtIndex(list, 6); return pigeonResult; } + (nullable FLTAllClassesWrapper *)nullableFromList:(NSArray *)list { @@ -398,6 +565,10 @@ + (nullable FLTAllClassesWrapper *)nullableFromList:(NSArray *)list { self.allNullableTypes ?: [NSNull null], self.allNullableTypesWithoutRecursion ?: [NSNull null], self.allTypes ?: [NSNull null], + self.classList ?: [NSNull null], + self.nullableClassList ?: [NSNull null], + self.classMap ?: [NSNull null], + self.nullableClassMap ?: [NSNull null], ]; } @end @@ -428,21 +599,29 @@ @interface FLTCoreTestsPigeonCodecReader : FlutterStandardReader @implementation FLTCoreTestsPigeonCodecReader - (nullable id)readValueOfType:(UInt8)type { switch (type) { - case 129: + case 129: { + NSNumber *enumAsNumber = [self readValue]; + return enumAsNumber == nil ? nil + : [[FLTAnEnumBox alloc] initWithValue:[enumAsNumber integerValue]]; + } + case 130: { + NSNumber *enumAsNumber = [self readValue]; + return enumAsNumber == nil + ? nil + : [[FLTAnotherEnumBox alloc] initWithValue:[enumAsNumber integerValue]]; + } + case 131: + return [FLTUnusedClass fromList:[self readValue]]; + case 132: return [FLTAllTypes fromList:[self readValue]]; - case 130: + case 133: return [FLTAllNullableTypes fromList:[self readValue]]; - case 131: + case 134: return [FLTAllNullableTypesWithoutRecursion fromList:[self readValue]]; - case 132: + case 135: return [FLTAllClassesWrapper fromList:[self readValue]]; - case 133: + case 136: return [FLTTestMessage fromList:[self readValue]]; - case 134: { - NSNumber *enumAsNumber = [self readValue]; - return enumAsNumber == nil ? nil - : [[FLTAnEnumBox alloc] initWithValue:[enumAsNumber integerValue]]; - } default: return [super readValueOfType:type]; } @@ -453,25 +632,32 @@ @interface FLTCoreTestsPigeonCodecWriter : FlutterStandardWriter @end @implementation FLTCoreTestsPigeonCodecWriter - (void)writeValue:(id)value { - if ([value isKindOfClass:[FLTAllTypes class]]) { + if ([value isKindOfClass:[FLTAnEnumBox class]]) { + FLTAnEnumBox *box = (FLTAnEnumBox *)value; [self writeByte:129]; + [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; + } else if ([value isKindOfClass:[FLTAnotherEnumBox class]]) { + FLTAnotherEnumBox *box = (FLTAnotherEnumBox *)value; + [self writeByte:130]; + [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; + } else if ([value isKindOfClass:[FLTUnusedClass class]]) { + [self writeByte:131]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FLTAllTypes class]]) { + [self writeByte:132]; [self writeValue:[value toList]]; } else if ([value isKindOfClass:[FLTAllNullableTypes class]]) { - [self writeByte:130]; + [self writeByte:133]; [self writeValue:[value toList]]; } else if ([value isKindOfClass:[FLTAllNullableTypesWithoutRecursion class]]) { - [self writeByte:131]; + [self writeByte:134]; [self writeValue:[value toList]]; } else if ([value isKindOfClass:[FLTAllClassesWrapper class]]) { - [self writeByte:132]; + [self writeByte:135]; [self writeValue:[value toList]]; } else if ([value isKindOfClass:[FLTTestMessage class]]) { - [self writeByte:133]; + [self writeByte:136]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FLTAnEnumBox class]]) { - FLTAnEnumBox *box = (FLTAnEnumBox *)value; - [self writeByte:134]; - [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; } else { [super writeValue:value]; } @@ -799,257 +985,255 @@ void SetUpFLTHostIntegrationCoreApiWithSuffix(id binaryM [channel setMessageHandler:nil]; } } - /// Returns the passed map, to test serialization and deserialization. + /// Returns the passed list, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoMap", + @"HostIntegrationCoreApi.echoEnumList", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoMap:error:)], - @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoMap:error:)", - api); + NSCAssert( + [api respondsToSelector:@selector(echoEnumList:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoEnumList:error:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSDictionary *arg_aMap = GetNullableObjectAtIndex(args, 0); + NSArray *arg_enumList = GetNullableObjectAtIndex(args, 0); FlutterError *error; - NSDictionary *output = [api echoMap:arg_aMap error:&error]; + NSArray *output = [api echoEnumList:arg_enumList error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed map to test nested class serialization and deserialization. + /// Returns the passed list, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoClassWrapper", + @"HostIntegrationCoreApi.echoClassList", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoClassWrapper:error:)], - @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoClassWrapper:error:)", - api); + NSCAssert( + [api respondsToSelector:@selector(echoClassList:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoClassList:error:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FLTAllClassesWrapper *arg_wrapper = GetNullableObjectAtIndex(args, 0); + NSArray *arg_classList = GetNullableObjectAtIndex(args, 0); FlutterError *error; - FLTAllClassesWrapper *output = [api echoClassWrapper:arg_wrapper error:&error]; + NSArray *output = [api echoClassList:arg_classList error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed enum to test serialization and deserialization. + /// Returns the passed list, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoEnum", + @"HostIntegrationCoreApi.echoNonNullEnumList", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoEnum:error:)], - @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoEnum:error:)", + NSCAssert([api respondsToSelector:@selector(echoNonNullEnumList:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNonNullEnumList:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FLTAnEnumBox *enumBox = GetNullableObjectAtIndex(args, 0); - FLTAnEnum arg_anEnum = enumBox.value; + NSArray *arg_enumList = GetNullableObjectAtIndex(args, 0); FlutterError *error; - FLTAnEnumBox *output = [api echoEnum:arg_anEnum error:&error]; + NSArray *output = [api echoNonNullEnumList:arg_enumList error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the default string. + /// Returns the passed list, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoNamedDefaultString", + @"HostIntegrationCoreApi.echoNonNullClassList", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoNamedDefaultString:error:)], + NSCAssert([api respondsToSelector:@selector(echoNonNullClassList:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoNamedDefaultString:error:)", + @"@selector(echoNonNullClassList:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSString *arg_aString = GetNullableObjectAtIndex(args, 0); + NSArray *arg_classList = GetNullableObjectAtIndex(args, 0); FlutterError *error; - NSString *output = [api echoNamedDefaultString:arg_aString error:&error]; + NSArray *output = [api echoNonNullClassList:arg_classList + error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns passed in double. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoOptionalDefaultDouble", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoMap", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoOptionalDefaultDouble:error:)], - @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoOptionalDefaultDouble:error:)", + NSCAssert([api respondsToSelector:@selector(echoMap:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - double arg_aDouble = [GetNullableObjectAtIndex(args, 0) doubleValue]; + NSDictionary *arg_map = GetNullableObjectAtIndex(args, 0); FlutterError *error; - NSNumber *output = [api echoOptionalDefaultDouble:arg_aDouble error:&error]; + NSDictionary *output = [api echoMap:arg_map error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns passed in int. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoRequiredInt", + @"HostIntegrationCoreApi.echoStringMap", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoRequiredInt:error:)], - @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoRequiredInt:error:)", - api); + NSCAssert( + [api respondsToSelector:@selector(echoStringMap:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoStringMap:error:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSInteger arg_anInt = [GetNullableObjectAtIndex(args, 0) integerValue]; + NSDictionary *arg_stringMap = GetNullableObjectAtIndex(args, 0); FlutterError *error; - NSNumber *output = [api echoRequiredInt:arg_anInt error:&error]; + NSDictionary *output = [api echoStringMap:arg_stringMap + error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed object, to test serialization and deserialization. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAllNullableTypes", + @"HostIntegrationCoreApi.echoIntMap", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAllNullableTypes:error:)], - @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAllNullableTypes:error:)", - api); + NSCAssert( + [api respondsToSelector:@selector(echoIntMap:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoIntMap:error:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FLTAllNullableTypes *arg_everything = GetNullableObjectAtIndex(args, 0); + NSDictionary *arg_intMap = GetNullableObjectAtIndex(args, 0); FlutterError *error; - FLTAllNullableTypes *output = [api echoAllNullableTypes:arg_everything error:&error]; + NSDictionary *output = [api echoIntMap:arg_intMap error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed object, to test serialization and deserialization. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - [NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAllNullableTypesWithoutRecursion", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoEnumMap", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAllNullableTypesWithoutRecursion:error:)], - @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAllNullableTypesWithoutRecursion:error:)", - api); + NSCAssert( + [api respondsToSelector:@selector(echoEnumMap:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoEnumMap:error:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FLTAllNullableTypesWithoutRecursion *arg_everything = GetNullableObjectAtIndex(args, 0); + NSDictionary *arg_enumMap = + GetNullableObjectAtIndex(args, 0); FlutterError *error; - FLTAllNullableTypesWithoutRecursion *output = - [api echoAllNullableTypesWithoutRecursion:arg_everything error:&error]; + NSDictionary *output = [api echoEnumMap:arg_enumMap + error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the inner `aString` value from the wrapped object, to test - /// sending of nested objects. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.extractNestedNullableString", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoClassMap", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(extractNestedNullableStringFrom:error:)], - @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(extractNestedNullableStringFrom:error:)", - api); + NSCAssert( + [api respondsToSelector:@selector(echoClassMap:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoClassMap:error:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FLTAllClassesWrapper *arg_wrapper = GetNullableObjectAtIndex(args, 0); + NSDictionary *arg_classMap = + GetNullableObjectAtIndex(args, 0); FlutterError *error; - NSString *output = [api extractNestedNullableStringFrom:arg_wrapper error:&error]; + NSDictionary *output = [api echoClassMap:arg_classMap + error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the inner `aString` value from the wrapped object, to test - /// sending of nested objects. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.createNestedNullableString", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoNonNullStringMap", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(createNestedObjectWithNullableString:error:)], + NSCAssert([api respondsToSelector:@selector(echoNonNullStringMap:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(createNestedObjectWithNullableString:error:)", + @"@selector(echoNonNullStringMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSString *arg_nullableString = GetNullableObjectAtIndex(args, 0); + NSDictionary *arg_stringMap = GetNullableObjectAtIndex(args, 0); FlutterError *error; - FLTAllClassesWrapper *output = [api createNestedObjectWithNullableString:arg_nullableString + NSDictionary *output = [api echoNonNullStringMap:arg_stringMap error:&error]; callback(wrapResult(output, error)); }]; @@ -1057,1273 +1241,1289 @@ void SetUpFLTHostIntegrationCoreApiWithSuffix(id binaryM [channel setMessageHandler:nil]; } } - /// Returns passed in arguments of multiple types. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.sendMultipleNullableTypes", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoNonNullIntMap", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(sendMultipleNullableTypesABool: - anInt:aString:error:)], + NSCAssert([api respondsToSelector:@selector(echoNonNullIntMap:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(sendMultipleNullableTypesABool:anInt:aString:error:)", + @"@selector(echoNonNullIntMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0); - NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 1); - NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 2); + NSDictionary *arg_intMap = GetNullableObjectAtIndex(args, 0); FlutterError *error; - FLTAllNullableTypes *output = [api sendMultipleNullableTypesABool:arg_aNullableBool - anInt:arg_aNullableInt - aString:arg_aNullableString - error:&error]; + NSDictionary *output = [api echoNonNullIntMap:arg_intMap + error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns passed in arguments of multiple types. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat: - @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoNonNullEnumMap", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector - (sendMultipleNullableTypesWithoutRecursionABool:anInt:aString:error:)], + NSCAssert([api respondsToSelector:@selector(echoNonNullEnumMap:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(sendMultipleNullableTypesWithoutRecursionABool:anInt:aString:error:)", + @"@selector(echoNonNullEnumMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0); - NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 1); - NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 2); + NSDictionary *arg_enumMap = + GetNullableObjectAtIndex(args, 0); FlutterError *error; - FLTAllNullableTypesWithoutRecursion *output = - [api sendMultipleNullableTypesWithoutRecursionABool:arg_aNullableBool - anInt:arg_aNullableInt - aString:arg_aNullableString - error:&error]; + NSDictionary *output = [api echoNonNullEnumMap:arg_enumMap + error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns passed in int. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoNullableInt", + @"HostIntegrationCoreApi.echoNonNullClassMap", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoNullableInt:error:)], + NSCAssert([api respondsToSelector:@selector(echoNonNullClassMap:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoNullableInt:error:)", + @"@selector(echoNonNullClassMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 0); + NSDictionary *arg_classMap = + GetNullableObjectAtIndex(args, 0); FlutterError *error; - NSNumber *output = [api echoNullableInt:arg_aNullableInt error:&error]; + NSDictionary *output = + [api echoNonNullClassMap:arg_classMap error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns passed in double. + /// Returns the passed class to test nested class serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoNullableDouble", + @"HostIntegrationCoreApi.echoClassWrapper", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoNullableDouble:error:)], + NSCAssert([api respondsToSelector:@selector(echoClassWrapper:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoNullableDouble:error:)", + @"@selector(echoClassWrapper:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSNumber *arg_aNullableDouble = GetNullableObjectAtIndex(args, 0); + FLTAllClassesWrapper *arg_wrapper = GetNullableObjectAtIndex(args, 0); FlutterError *error; - NSNumber *output = [api echoNullableDouble:arg_aNullableDouble error:&error]; + FLTAllClassesWrapper *output = [api echoClassWrapper:arg_wrapper error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed in boolean. + /// Returns the passed enum to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoNullableBool", + @"HostIntegrationCoreApi.echoEnum", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoNullableBool:error:)], - @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoNullableBool:error:)", + NSCAssert([api respondsToSelector:@selector(echoEnum:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoEnum:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0); + FLTAnEnumBox *boxedFLTAnEnum = GetNullableObjectAtIndex(args, 0); + FLTAnEnum arg_anEnum = boxedFLTAnEnum.value; FlutterError *error; - NSNumber *output = [api echoNullableBool:arg_aNullableBool error:&error]; + FLTAnEnumBox *output = [api echoEnum:arg_anEnum error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed in string. + /// Returns the passed enum to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoNullableString", + @"HostIntegrationCoreApi.echoAnotherEnum", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoNullableString:error:)], + NSCAssert([api respondsToSelector:@selector(echoAnotherEnum:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoNullableString:error:)", + @"@selector(echoAnotherEnum:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 0); + FLTAnotherEnumBox *boxedFLTAnotherEnum = GetNullableObjectAtIndex(args, 0); + FLTAnotherEnum arg_anotherEnum = boxedFLTAnotherEnum.value; FlutterError *error; - NSString *output = [api echoNullableString:arg_aNullableString error:&error]; + FLTAnotherEnumBox *output = [api echoAnotherEnum:arg_anotherEnum error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed in Uint8List. + /// Returns the default string. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoNullableUint8List", + @"HostIntegrationCoreApi.echoNamedDefaultString", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoNullableUint8List:error:)], + NSCAssert([api respondsToSelector:@selector(echoNamedDefaultString:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoNullableUint8List:error:)", + @"@selector(echoNamedDefaultString:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FlutterStandardTypedData *arg_aNullableUint8List = GetNullableObjectAtIndex(args, 0); + NSString *arg_aString = GetNullableObjectAtIndex(args, 0); FlutterError *error; - FlutterStandardTypedData *output = [api echoNullableUint8List:arg_aNullableUint8List - error:&error]; + NSString *output = [api echoNamedDefaultString:arg_aString error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed in generic Object. + /// Returns passed in double. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoNullableObject", - messageChannelSuffix] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoOptionalDefaultDouble", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoNullableObject:error:)], + NSCAssert([api respondsToSelector:@selector(echoOptionalDefaultDouble:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoNullableObject:error:)", + @"@selector(echoOptionalDefaultDouble:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - id arg_aNullableObject = GetNullableObjectAtIndex(args, 0); + double arg_aDouble = [GetNullableObjectAtIndex(args, 0) doubleValue]; FlutterError *error; - id output = [api echoNullableObject:arg_aNullableObject error:&error]; + NSNumber *output = [api echoOptionalDefaultDouble:arg_aDouble error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed list, to test serialization and deserialization. + /// Returns passed in int. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoNullableList", + @"HostIntegrationCoreApi.echoRequiredInt", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoNullableList:error:)], + NSCAssert([api respondsToSelector:@selector(echoRequiredInt:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoNullableList:error:)", + @"@selector(echoRequiredInt:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSArray *arg_aNullableList = GetNullableObjectAtIndex(args, 0); + NSInteger arg_anInt = [GetNullableObjectAtIndex(args, 0) integerValue]; FlutterError *error; - NSArray *output = [api echoNullableList:arg_aNullableList error:&error]; + NSNumber *output = [api echoRequiredInt:arg_anInt error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed map, to test serialization and deserialization. + /// Returns the passed object, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoNullableMap", + @"HostIntegrationCoreApi.echoAllNullableTypes", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoNullableMap:error:)], + NSCAssert([api respondsToSelector:@selector(echoAllNullableTypes:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoNullableMap:error:)", + @"@selector(echoAllNullableTypes:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSDictionary *arg_aNullableMap = GetNullableObjectAtIndex(args, 0); + FLTAllNullableTypes *arg_everything = GetNullableObjectAtIndex(args, 0); FlutterError *error; - NSDictionary *output = [api echoNullableMap:arg_aNullableMap error:&error]; + FLTAllNullableTypes *output = [api echoAllNullableTypes:arg_everything error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed object, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoNullableEnum", - messageChannelSuffix] + initWithName: + [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAllNullableTypesWithoutRecursion", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoNullableEnum:error:)], + NSCAssert([api respondsToSelector:@selector(echoAllNullableTypesWithoutRecursion:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoNullableEnum:error:)", + @"@selector(echoAllNullableTypesWithoutRecursion:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FLTAnEnumBox *arg_anEnum = GetNullableObjectAtIndex(args, 0); + FLTAllNullableTypesWithoutRecursion *arg_everything = GetNullableObjectAtIndex(args, 0); FlutterError *error; - FLTAnEnumBox *output = [api echoNullableEnum:arg_anEnum error:&error]; + FLTAllNullableTypesWithoutRecursion *output = + [api echoAllNullableTypesWithoutRecursion:arg_everything error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns passed in int. + /// Returns the inner `aString` value from the wrapped object, to test + /// sending of nested objects. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoOptionalNullableInt", + @"HostIntegrationCoreApi.extractNestedNullableString", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoOptionalNullableInt:error:)], + NSCAssert([api respondsToSelector:@selector(extractNestedNullableStringFrom:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoOptionalNullableInt:error:)", + @"@selector(extractNestedNullableStringFrom:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 0); + FLTAllClassesWrapper *arg_wrapper = GetNullableObjectAtIndex(args, 0); FlutterError *error; - NSNumber *output = [api echoOptionalNullableInt:arg_aNullableInt error:&error]; + NSString *output = [api extractNestedNullableStringFrom:arg_wrapper error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed in string. + /// Returns the inner `aString` value from the wrapped object, to test + /// sending of nested objects. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoNamedNullableString", + @"HostIntegrationCoreApi.createNestedNullableString", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoNamedNullableString:error:)], + NSCAssert([api respondsToSelector:@selector(createNestedObjectWithNullableString:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoNamedNullableString:error:)", + @"@selector(createNestedObjectWithNullableString:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 0); + NSString *arg_nullableString = GetNullableObjectAtIndex(args, 0); FlutterError *error; - NSString *output = [api echoNamedNullableString:arg_aNullableString error:&error]; + FLTAllClassesWrapper *output = [api createNestedObjectWithNullableString:arg_nullableString + error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// A no-op function taking no arguments and returning no value, to sanity - /// test basic asynchronous calling. + /// Returns passed in arguments of multiple types. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.noopAsync", - messageChannelSuffix] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.sendMultipleNullableTypes", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(noopAsyncWithCompletion:)], + NSCAssert([api respondsToSelector:@selector(sendMultipleNullableTypesABool: + anInt:aString:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(noopAsyncWithCompletion:)", + @"@selector(sendMultipleNullableTypesABool:anInt:aString:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - [api noopAsyncWithCompletion:^(FlutterError *_Nullable error) { - callback(wrapResult(nil, error)); - }]; + NSArray *args = message; + NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0); + NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 1); + NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 2); + FlutterError *error; + FLTAllNullableTypes *output = [api sendMultipleNullableTypesABool:arg_aNullableBool + anInt:arg_aNullableInt + aString:arg_aNullableString + error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns passed in int asynchronously. + /// Returns passed in arguments of multiple types. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncInt", - messageChannelSuffix] + initWithName:[NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncInt:completion:)], + NSCAssert([api respondsToSelector:@selector + (sendMultipleNullableTypesWithoutRecursionABool:anInt:aString:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncInt:completion:)", + @"@selector(sendMultipleNullableTypesWithoutRecursionABool:anInt:aString:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSInteger arg_anInt = [GetNullableObjectAtIndex(args, 0) integerValue]; - [api echoAsyncInt:arg_anInt - completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0); + NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 1); + NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 2); + FlutterError *error; + FLTAllNullableTypesWithoutRecursion *output = + [api sendMultipleNullableTypesWithoutRecursionABool:arg_aNullableBool + anInt:arg_aNullableInt + aString:arg_aNullableString + error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns passed in double asynchronously. + /// Returns passed in int. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncDouble", + @"HostIntegrationCoreApi.echoNullableInt", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncDouble:completion:)], + NSCAssert([api respondsToSelector:@selector(echoNullableInt:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncDouble:completion:)", + @"@selector(echoNullableInt:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - double arg_aDouble = [GetNullableObjectAtIndex(args, 0) doubleValue]; - [api echoAsyncDouble:arg_aDouble - completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSNumber *output = [api echoNullableInt:arg_aNullableInt error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed in boolean asynchronously. + /// Returns passed in double. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncBool", + @"HostIntegrationCoreApi.echoNullableDouble", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncBool:completion:)], + NSCAssert([api respondsToSelector:@selector(echoNullableDouble:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncBool:completion:)", + @"@selector(echoNullableDouble:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - BOOL arg_aBool = [GetNullableObjectAtIndex(args, 0) boolValue]; - [api echoAsyncBool:arg_aBool - completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSNumber *arg_aNullableDouble = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSNumber *output = [api echoNullableDouble:arg_aNullableDouble error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed string asynchronously. + /// Returns the passed in boolean. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncString", + @"HostIntegrationCoreApi.echoNullableBool", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncString:completion:)], + NSCAssert([api respondsToSelector:@selector(echoNullableBool:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncString:completion:)", + @"@selector(echoNullableBool:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSString *arg_aString = GetNullableObjectAtIndex(args, 0); - [api echoAsyncString:arg_aString - completion:^(NSString *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSNumber *output = [api echoNullableBool:arg_aNullableBool error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed in Uint8List asynchronously. + /// Returns the passed in string. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncUint8List", + @"HostIntegrationCoreApi.echoNullableString", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncUint8List:completion:)], + NSCAssert([api respondsToSelector:@selector(echoNullableString:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncUint8List:completion:)", + @"@selector(echoNullableString:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FlutterStandardTypedData *arg_aUint8List = GetNullableObjectAtIndex(args, 0); - [api echoAsyncUint8List:arg_aUint8List - completion:^(FlutterStandardTypedData *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSString *output = [api echoNullableString:arg_aNullableString error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed in generic Object asynchronously. + /// Returns the passed in Uint8List. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncObject", + @"HostIntegrationCoreApi.echoNullableUint8List", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncObject:completion:)], + NSCAssert([api respondsToSelector:@selector(echoNullableUint8List:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncObject:completion:)", + @"@selector(echoNullableUint8List:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - id arg_anObject = GetNullableObjectAtIndex(args, 0); - [api echoAsyncObject:arg_anObject - completion:^(id _Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; - }]; - } else { - [channel setMessageHandler:nil]; - } + FlutterStandardTypedData *arg_aNullableUint8List = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + FlutterStandardTypedData *output = [api echoNullableUint8List:arg_aNullableUint8List + error:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } } - /// Returns the passed list, to test asynchronous serialization and deserialization. + /// Returns the passed in generic Object. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncList", + @"HostIntegrationCoreApi.echoNullableObject", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncList:completion:)], + NSCAssert([api respondsToSelector:@selector(echoNullableObject:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncList:completion:)", + @"@selector(echoNullableObject:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSArray *arg_list = GetNullableObjectAtIndex(args, 0); - [api echoAsyncList:arg_list - completion:^(NSArray *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + id arg_aNullableObject = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + id output = [api echoNullableObject:arg_aNullableObject error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed map, to test asynchronous serialization and deserialization. + /// Returns the passed list, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncMap", + @"HostIntegrationCoreApi.echoNullableList", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncMap:completion:)], + NSCAssert([api respondsToSelector:@selector(echoNullableList:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncMap:completion:)", + @"@selector(echoNullableList:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSDictionary *arg_aMap = GetNullableObjectAtIndex(args, 0); - [api echoAsyncMap:arg_aMap - completion:^(NSDictionary *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSArray *arg_aNullableList = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSArray *output = [api echoNullableList:arg_aNullableList error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed enum, to test asynchronous serialization and deserialization. + /// Returns the passed list, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncEnum", + @"HostIntegrationCoreApi.echoNullableEnumList", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncEnum:completion:)], + NSCAssert([api respondsToSelector:@selector(echoNullableEnumList:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncEnum:completion:)", + @"@selector(echoNullableEnumList:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FLTAnEnumBox *enumBox = GetNullableObjectAtIndex(args, 0); - FLTAnEnum arg_anEnum = enumBox.value; - [api echoAsyncEnum:arg_anEnum - completion:^(FLTAnEnumBox *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSArray *arg_enumList = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSArray *output = [api echoNullableEnumList:arg_enumList error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Responds with an error from an async function returning a value. + /// Returns the passed list, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.throwAsyncError", + @"HostIntegrationCoreApi.echoNullableClassList", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(throwAsyncErrorWithCompletion:)], + NSCAssert([api respondsToSelector:@selector(echoNullableClassList:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(throwAsyncErrorWithCompletion:)", + @"@selector(echoNullableClassList:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - [api throwAsyncErrorWithCompletion:^(id _Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSArray *args = message; + NSArray *arg_classList = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSArray *output = [api echoNullableClassList:arg_classList + error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Responds with an error from an async void function. + /// Returns the passed list, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.throwAsyncErrorFromVoid", + @"HostIntegrationCoreApi.echoNullableNonNullEnumList", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(throwAsyncErrorFromVoidWithCompletion:)], + NSCAssert([api respondsToSelector:@selector(echoNullableNonNullEnumList:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(throwAsyncErrorFromVoidWithCompletion:)", + @"@selector(echoNullableNonNullEnumList:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - [api throwAsyncErrorFromVoidWithCompletion:^(FlutterError *_Nullable error) { - callback(wrapResult(nil, error)); - }]; + NSArray *args = message; + NSArray *arg_enumList = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSArray *output = [api echoNullableNonNullEnumList:arg_enumList + error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Responds with a Flutter error from an async function returning a value. + /// Returns the passed list, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.throwAsyncFlutterError", - messageChannelSuffix] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoNullableNonNullClassList", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(throwAsyncFlutterErrorWithCompletion:)], + NSCAssert([api respondsToSelector:@selector(echoNullableNonNullClassList:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(throwAsyncFlutterErrorWithCompletion:)", + @"@selector(echoNullableNonNullClassList:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - [api throwAsyncFlutterErrorWithCompletion:^(id _Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSArray *args = message; + NSArray *arg_classList = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSArray *output = [api echoNullableNonNullClassList:arg_classList + error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed object, to test async serialization and deserialization. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncAllTypes", + @"HostIntegrationCoreApi.echoNullableMap", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncAllTypes:completion:)], + NSCAssert([api respondsToSelector:@selector(echoNullableMap:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncAllTypes:completion:)", + @"@selector(echoNullableMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FLTAllTypes *arg_everything = GetNullableObjectAtIndex(args, 0); - [api echoAsyncAllTypes:arg_everything - completion:^(FLTAllTypes *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_map = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSDictionary *output = [api echoNullableMap:arg_map error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed object, to test serialization and deserialization. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString stringWithFormat: - @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncNullableAllNullableTypes", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoNullableStringMap", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncNullableAllNullableTypes:completion:)], + NSCAssert([api respondsToSelector:@selector(echoNullableStringMap:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncNullableAllNullableTypes:completion:)", + @"@selector(echoNullableStringMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FLTAllNullableTypes *arg_everything = GetNullableObjectAtIndex(args, 0); - [api echoAsyncNullableAllNullableTypes:arg_everything - completion:^(FLTAllNullableTypes *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_stringMap = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSDictionary *output = [api echoNullableStringMap:arg_stringMap + error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed object, to test serialization and deserialization. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi." - @"echoAsyncNullableAllNullableTypesWithoutRecursion", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoNullableIntMap", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector - (echoAsyncNullableAllNullableTypesWithoutRecursion:completion:)], + NSCAssert([api respondsToSelector:@selector(echoNullableIntMap:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncNullableAllNullableTypesWithoutRecursion:completion:)", + @"@selector(echoNullableIntMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FLTAllNullableTypesWithoutRecursion *arg_everything = GetNullableObjectAtIndex(args, 0); - [api echoAsyncNullableAllNullableTypesWithoutRecursion:arg_everything - completion:^(FLTAllNullableTypesWithoutRecursion - *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_intMap = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSDictionary *output = [api echoNullableIntMap:arg_intMap + error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns passed in int asynchronously. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncNullableInt", + @"HostIntegrationCoreApi.echoNullableEnumMap", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncNullableInt:completion:)], + NSCAssert([api respondsToSelector:@selector(echoNullableEnumMap:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncNullableInt:completion:)", + @"@selector(echoNullableEnumMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSNumber *arg_anInt = GetNullableObjectAtIndex(args, 0); - [api echoAsyncNullableInt:arg_anInt - completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_enumMap = + GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSDictionary *output = [api echoNullableEnumMap:arg_enumMap + error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns passed in double asynchronously. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncNullableDouble", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoNullableClassMap", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncNullableDouble:completion:)], + NSCAssert([api respondsToSelector:@selector(echoNullableClassMap:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncNullableDouble:completion:)", + @"@selector(echoNullableClassMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSNumber *arg_aDouble = GetNullableObjectAtIndex(args, 0); - [api echoAsyncNullableDouble:arg_aDouble - completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_classMap = + GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSDictionary *output = + [api echoNullableClassMap:arg_classMap error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed in boolean asynchronously. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncNullableBool", - messageChannelSuffix] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoNullableNonNullStringMap", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncNullableBool:completion:)], + NSCAssert([api respondsToSelector:@selector(echoNullableNonNullStringMap:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncNullableBool:completion:)", + @"@selector(echoNullableNonNullStringMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSNumber *arg_aBool = GetNullableObjectAtIndex(args, 0); - [api echoAsyncNullableBool:arg_aBool - completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_stringMap = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSDictionary *output = + [api echoNullableNonNullStringMap:arg_stringMap error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed string asynchronously. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncNullableString", + @"HostIntegrationCoreApi.echoNullableNonNullIntMap", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncNullableString:completion:)], + NSCAssert([api respondsToSelector:@selector(echoNullableNonNullIntMap:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncNullableString:completion:)", + @"@selector(echoNullableNonNullIntMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSString *arg_aString = GetNullableObjectAtIndex(args, 0); - [api echoAsyncNullableString:arg_aString - completion:^(NSString *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_intMap = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSDictionary *output = [api echoNullableNonNullIntMap:arg_intMap + error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed in Uint8List asynchronously. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncNullableUint8List", + @"HostIntegrationCoreApi.echoNullableNonNullEnumMap", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncNullableUint8List:completion:)], + NSCAssert([api respondsToSelector:@selector(echoNullableNonNullEnumMap:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncNullableUint8List:completion:)", + @"@selector(echoNullableNonNullEnumMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FlutterStandardTypedData *arg_aUint8List = GetNullableObjectAtIndex(args, 0); - [api echoAsyncNullableUint8List:arg_aUint8List - completion:^(FlutterStandardTypedData *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_enumMap = + GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSDictionary *output = + [api echoNullableNonNullEnumMap:arg_enumMap error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed in generic Object asynchronously. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncNullableObject", + @"HostIntegrationCoreApi.echoNullableNonNullClassMap", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncNullableObject:completion:)], + NSCAssert([api respondsToSelector:@selector(echoNullableNonNullClassMap:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncNullableObject:completion:)", + @"@selector(echoNullableNonNullClassMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - id arg_anObject = GetNullableObjectAtIndex(args, 0); - [api echoAsyncNullableObject:arg_anObject - completion:^(id _Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_classMap = + GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSDictionary *output = + [api echoNullableNonNullClassMap:arg_classMap error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed list, to test asynchronous serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncNullableList", + @"HostIntegrationCoreApi.echoNullableEnum", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncNullableList:completion:)], + NSCAssert([api respondsToSelector:@selector(echoNullableEnum:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncNullableList:completion:)", + @"@selector(echoNullableEnum:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSArray *arg_list = GetNullableObjectAtIndex(args, 0); - [api echoAsyncNullableList:arg_list - completion:^(NSArray *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + FLTAnEnumBox *arg_anEnum = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + FLTAnEnumBox *output = [api echoNullableEnum:arg_anEnum error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed map, to test asynchronous serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncNullableMap", - messageChannelSuffix] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAnotherNullableEnum", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncNullableMap:completion:)], + NSCAssert([api respondsToSelector:@selector(echoAnotherNullableEnum:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncNullableMap:completion:)", + @"@selector(echoAnotherNullableEnum:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSDictionary *arg_aMap = GetNullableObjectAtIndex(args, 0); - [api echoAsyncNullableMap:arg_aMap - completion:^(NSDictionary *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + FLTAnotherEnumBox *arg_anotherEnum = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + FLTAnotherEnumBox *output = [api echoAnotherNullableEnum:arg_anotherEnum error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed enum, to test asynchronous serialization and deserialization. + /// Returns passed in int. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncNullableEnum", - messageChannelSuffix] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoOptionalNullableInt", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncNullableEnum:completion:)], + NSCAssert([api respondsToSelector:@selector(echoOptionalNullableInt:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncNullableEnum:completion:)", + @"@selector(echoOptionalNullableInt:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FLTAnEnumBox *arg_anEnum = GetNullableObjectAtIndex(args, 0); - [api - echoAsyncNullableEnum:arg_anEnum - completion:^(FLTAnEnumBox *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSNumber *output = [api echoOptionalNullableInt:arg_aNullableInt error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed in string. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterNoop", - messageChannelSuffix] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoNamedNullableString", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterNoopWithCompletion:)], + NSCAssert([api respondsToSelector:@selector(echoNamedNullableString:error:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterNoopWithCompletion:)", + @"@selector(echoNamedNullableString:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - [api callFlutterNoopWithCompletion:^(FlutterError *_Nullable error) { - callback(wrapResult(nil, error)); - }]; + NSArray *args = message; + NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSString *output = [api echoNamedNullableString:arg_aNullableString error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic asynchronous calling. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterThrowError", + @"HostIntegrationCoreApi.noopAsync", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterThrowErrorWithCompletion:)], + NSCAssert([api respondsToSelector:@selector(noopAsyncWithCompletion:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterThrowErrorWithCompletion:)", + @"@selector(noopAsyncWithCompletion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - [api callFlutterThrowErrorWithCompletion:^(id _Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); + [api noopAsyncWithCompletion:^(FlutterError *_Nullable error) { + callback(wrapResult(nil, error)); }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns passed in int asynchronously. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - [NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterThrowErrorFromVoid", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncInt", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterThrowErrorFromVoidWithCompletion:)], + NSCAssert([api respondsToSelector:@selector(echoAsyncInt:completion:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterThrowErrorFromVoidWithCompletion:)", + @"@selector(echoAsyncInt:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - [api callFlutterThrowErrorFromVoidWithCompletion:^(FlutterError *_Nullable error) { - callback(wrapResult(nil, error)); - }]; + NSArray *args = message; + NSInteger arg_anInt = [GetNullableObjectAtIndex(args, 0) integerValue]; + [api echoAsyncInt:arg_anInt + completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns passed in double asynchronously. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoAllTypes", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncDouble", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoAllTypes:completion:)], + NSCAssert([api respondsToSelector:@selector(echoAsyncDouble:completion:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoAllTypes:completion:)", + @"@selector(echoAsyncDouble:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FLTAllTypes *arg_everything = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoAllTypes:arg_everything - completion:^(FLTAllTypes *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + double arg_aDouble = [GetNullableObjectAtIndex(args, 0) doubleValue]; + [api echoAsyncDouble:arg_aDouble + completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed in boolean asynchronously. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - [NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoAllNullableTypes", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncBool", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoAllNullableTypes:completion:)], + NSCAssert([api respondsToSelector:@selector(echoAsyncBool:completion:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoAllNullableTypes:completion:)", + @"@selector(echoAsyncBool:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FLTAllNullableTypes *arg_everything = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoAllNullableTypes:arg_everything - completion:^(FLTAllNullableTypes *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + BOOL arg_aBool = [GetNullableObjectAtIndex(args, 0) boolValue]; + [api echoAsyncBool:arg_aBool + completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed string asynchronously. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - [NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterSendMultipleNullableTypes", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncString", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector - (callFlutterSendMultipleNullableTypesABool:anInt:aString:completion:)], + NSCAssert([api respondsToSelector:@selector(echoAsyncString:completion:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterSendMultipleNullableTypesABool:anInt:aString:completion:)", + @"@selector(echoAsyncString:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0); - NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 1); - NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 2); - [api callFlutterSendMultipleNullableTypesABool:arg_aNullableBool - anInt:arg_aNullableInt - aString:arg_aNullableString - completion:^(FLTAllNullableTypes *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSString *arg_aString = GetNullableObjectAtIndex(args, 0); + [api echoAsyncString:arg_aString + completion:^(NSString *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed in Uint8List asynchronously. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi." - @"callFlutterEchoAllNullableTypesWithoutRecursion", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncUint8List", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector - (callFlutterEchoAllNullableTypesWithoutRecursion:completion:)], + NSCAssert([api respondsToSelector:@selector(echoAsyncUint8List:completion:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoAllNullableTypesWithoutRecursion:completion:)", + @"@selector(echoAsyncUint8List:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FLTAllNullableTypesWithoutRecursion *arg_everything = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoAllNullableTypesWithoutRecursion:arg_everything - completion:^(FLTAllNullableTypesWithoutRecursion - *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + FlutterStandardTypedData *arg_aUint8List = GetNullableObjectAtIndex(args, 0); + [api echoAsyncUint8List:arg_aUint8List + completion:^(FlutterStandardTypedData *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed in generic Object asynchronously. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - [NSString stringWithFormat: - @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - @"callFlutterSendMultipleNullableTypesWithoutRecursion", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncObject", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert( - [api respondsToSelector:@selector - (callFlutterSendMultipleNullableTypesWithoutRecursionABool: - anInt:aString:completion:)], - @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterSendMultipleNullableTypesWithoutRecursionABool:anInt:aString:" - @"completion:)", - api); + NSCAssert([api respondsToSelector:@selector(echoAsyncObject:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncObject:completion:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0); - NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 1); - NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 2); - [api callFlutterSendMultipleNullableTypesWithoutRecursionABool:arg_aNullableBool - anInt:arg_aNullableInt - aString:arg_aNullableString - completion:^( - FLTAllNullableTypesWithoutRecursion - *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + id arg_anObject = GetNullableObjectAtIndex(args, 0); + [api echoAsyncObject:arg_anObject + completion:^(id _Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed list, to test asynchronous serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoBool", + @"HostIntegrationCoreApi.echoAsyncList", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoBool:completion:)], + NSCAssert([api respondsToSelector:@selector(echoAsyncList:completion:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoBool:completion:)", + @"@selector(echoAsyncList:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - BOOL arg_aBool = [GetNullableObjectAtIndex(args, 0) boolValue]; - [api callFlutterEchoBool:arg_aBool - completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSArray *arg_list = GetNullableObjectAtIndex(args, 0); + [api echoAsyncList:arg_list + completion:^(NSArray *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed list, to test asynchronous serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoInt", + @"HostIntegrationCoreApi.echoAsyncEnumList", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoInt:completion:)], + NSCAssert([api respondsToSelector:@selector(echoAsyncEnumList:completion:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoInt:completion:)", + @"@selector(echoAsyncEnumList:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSInteger arg_anInt = [GetNullableObjectAtIndex(args, 0) integerValue]; - [api callFlutterEchoInt:arg_anInt - completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { + NSArray *arg_enumList = GetNullableObjectAtIndex(args, 0); + [api echoAsyncEnumList:arg_enumList + completion:^(NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed list, to test asynchronous serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncClassList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncClassList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncClassList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_classList = GetNullableObjectAtIndex(args, 0); + [api echoAsyncClassList:arg_classList + completion:^(NSArray *_Nullable output, + FlutterError *_Nullable error) { callback(wrapResult(output, error)); }]; }]; @@ -2331,341 +2531,479 @@ void SetUpFLTHostIntegrationCoreApiWithSuffix(id binaryM [channel setMessageHandler:nil]; } } + /// Returns the passed map, to test asynchronous serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoDouble", + @"HostIntegrationCoreApi.echoAsyncMap", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoDouble:completion:)], + NSCAssert([api respondsToSelector:@selector(echoAsyncMap:completion:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoDouble:completion:)", + @"@selector(echoAsyncMap:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - double arg_aDouble = [GetNullableObjectAtIndex(args, 0) doubleValue]; - [api callFlutterEchoDouble:arg_aDouble - completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_map = GetNullableObjectAtIndex(args, 0); + [api echoAsyncMap:arg_map + completion:^(NSDictionary *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed map, to test asynchronous serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoString", + @"HostIntegrationCoreApi.echoAsyncStringMap", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoString:completion:)], + NSCAssert([api respondsToSelector:@selector(echoAsyncStringMap:completion:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoString:completion:)", + @"@selector(echoAsyncStringMap:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSString *arg_aString = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoString:arg_aString - completion:^(NSString *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_stringMap = GetNullableObjectAtIndex(args, 0); + [api echoAsyncStringMap:arg_stringMap + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed map, to test asynchronous serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoUint8List", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncIntMap", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoUint8List:completion:)], + NSCAssert([api respondsToSelector:@selector(echoAsyncIntMap:completion:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoUint8List:completion:)", + @"@selector(echoAsyncIntMap:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FlutterStandardTypedData *arg_list = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoUint8List:arg_list - completion:^(FlutterStandardTypedData *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_intMap = GetNullableObjectAtIndex(args, 0); + [api echoAsyncIntMap:arg_intMap + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed map, to test asynchronous serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoList", + @"HostIntegrationCoreApi.echoAsyncEnumMap", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoList:completion:)], + NSCAssert([api respondsToSelector:@selector(echoAsyncEnumMap:completion:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoList:completion:)", + @"@selector(echoAsyncEnumMap:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSArray *arg_list = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoList:arg_list - completion:^(NSArray *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_enumMap = + GetNullableObjectAtIndex(args, 0); + [api echoAsyncEnumMap:arg_enumMap + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed map, to test asynchronous serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoMap", + @"HostIntegrationCoreApi.echoAsyncClassMap", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoMap:completion:)], + NSCAssert([api respondsToSelector:@selector(echoAsyncClassMap:completion:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoMap:completion:)", + @"@selector(echoAsyncClassMap:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSDictionary *arg_aMap = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoMap:arg_aMap - completion:^(NSDictionary *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_classMap = + GetNullableObjectAtIndex(args, 0); + [api echoAsyncClassMap:arg_classMap + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed enum, to test asynchronous serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoEnum", + @"HostIntegrationCoreApi.echoAsyncEnum", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoEnum:completion:)], + NSCAssert([api respondsToSelector:@selector(echoAsyncEnum:completion:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoEnum:completion:)", + @"@selector(echoAsyncEnum:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FLTAnEnumBox *enumBox = GetNullableObjectAtIndex(args, 0); - FLTAnEnum arg_anEnum = enumBox.value; - [api callFlutterEchoEnum:arg_anEnum - completion:^(FLTAnEnumBox *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + FLTAnEnumBox *boxedFLTAnEnum = GetNullableObjectAtIndex(args, 0); + FLTAnEnum arg_anEnum = boxedFLTAnEnum.value; + [api echoAsyncEnum:arg_anEnum + completion:^(FLTAnEnumBox *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed enum, to test asynchronous serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoNullableBool", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAnotherAsyncEnum", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableBool:completion:)], + NSCAssert([api respondsToSelector:@selector(echoAnotherAsyncEnum:completion:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoNullableBool:completion:)", + @"@selector(echoAnotherAsyncEnum:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSNumber *arg_aBool = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoNullableBool:arg_aBool - completion:^(NSNumber *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + FLTAnotherEnumBox *boxedFLTAnotherEnum = GetNullableObjectAtIndex(args, 0); + FLTAnotherEnum arg_anotherEnum = boxedFLTAnotherEnum.value; + [api echoAnotherAsyncEnum:arg_anotherEnum + completion:^(FLTAnotherEnumBox *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Responds with an error from an async function returning a value. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.throwAsyncError", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(throwAsyncErrorWithCompletion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(throwAsyncErrorWithCompletion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + [api throwAsyncErrorWithCompletion:^(id _Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Responds with an error from an async void function. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoNullableInt", + @"HostIntegrationCoreApi.throwAsyncErrorFromVoid", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableInt:completion:)], + NSCAssert([api respondsToSelector:@selector(throwAsyncErrorFromVoidWithCompletion:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoNullableInt:completion:)", + @"@selector(throwAsyncErrorFromVoidWithCompletion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - NSNumber *arg_anInt = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoNullableInt:arg_anInt - completion:^(NSNumber *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + [api throwAsyncErrorFromVoidWithCompletion:^(FlutterError *_Nullable error) { + callback(wrapResult(nil, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Responds with a Flutter error from an async function returning a value. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - [NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoNullableDouble", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.throwAsyncFlutterError", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableDouble:completion:)], + NSCAssert([api respondsToSelector:@selector(throwAsyncFlutterErrorWithCompletion:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoNullableDouble:completion:)", + @"@selector(throwAsyncFlutterErrorWithCompletion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - NSNumber *arg_aDouble = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoNullableDouble:arg_aDouble - completion:^(NSNumber *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + [api throwAsyncFlutterErrorWithCompletion:^(id _Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed object, to test async serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - [NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoNullableString", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncAllTypes", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableString:completion:)], + NSCAssert([api respondsToSelector:@selector(echoAsyncAllTypes:completion:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoNullableString:completion:)", + @"@selector(echoAsyncAllTypes:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSString *arg_aString = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoNullableString:arg_aString - completion:^(NSString *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + FLTAllTypes *arg_everything = GetNullableObjectAtIndex(args, 0); + [api echoAsyncAllTypes:arg_everything + completion:^(FLTAllTypes *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed object, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat: @"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoNullableUint8List", + @"HostIntegrationCoreApi.echoAsyncNullableAllNullableTypes", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableUint8List:completion:)], + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableAllNullableTypes:completion:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoNullableUint8List:completion:)", + @"@selector(echoAsyncNullableAllNullableTypes:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FlutterStandardTypedData *arg_list = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoNullableUint8List:arg_list - completion:^(FlutterStandardTypedData *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + FLTAllNullableTypes *arg_everything = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableAllNullableTypes:arg_everything + completion:^(FLTAllNullableTypes *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed object, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoNullableList", + @"HostIntegrationCoreApi." + @"echoAsyncNullableAllNullableTypesWithoutRecursion", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableList:completion:)], + NSCAssert([api respondsToSelector:@selector + (echoAsyncNullableAllNullableTypesWithoutRecursion:completion:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoNullableList:completion:)", + @"@selector(echoAsyncNullableAllNullableTypesWithoutRecursion:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSArray *arg_list = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoNullableList:arg_list - completion:^(NSArray *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + FLTAllNullableTypesWithoutRecursion *arg_everything = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableAllNullableTypesWithoutRecursion:arg_everything + completion:^(FLTAllNullableTypesWithoutRecursion + *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns passed in int asynchronously. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableInt", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableInt:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableInt:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSNumber *arg_anInt = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableInt:arg_anInt + completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns passed in double asynchronously. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoNullableMap", + @"HostIntegrationCoreApi.echoAsyncNullableDouble", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableMap:completion:)], + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableDouble:completion:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoNullableMap:completion:)", + @"@selector(echoAsyncNullableDouble:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSNumber *arg_aDouble = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableDouble:arg_aDouble + completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed in boolean asynchronously. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableBool", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableBool:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableBool:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSNumber *arg_aBool = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableBool:arg_aBool + completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed string asynchronously. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableString", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableString:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableString:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_aString = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableString:arg_aString + completion:^(NSString *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed in Uint8List asynchronously. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableUint8List", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableUint8List:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableUint8List:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSDictionary *arg_aMap = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoNullableMap:arg_aMap - completion:^(NSDictionary *_Nullable output, + FlutterStandardTypedData *arg_aUint8List = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableUint8List:arg_aUint8List + completion:^(FlutterStandardTypedData *_Nullable output, FlutterError *_Nullable error) { callback(wrapResult(output, error)); }]; @@ -2674,117 +3012,2345 @@ void SetUpFLTHostIntegrationCoreApiWithSuffix(id binaryM [channel setMessageHandler:nil]; } } + /// Returns the passed in generic Object asynchronously. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoNullableEnum", + @"HostIntegrationCoreApi.echoAsyncNullableObject", messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableEnum:completion:)], + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableObject:completion:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoNullableEnum:completion:)", + @"@selector(echoAsyncNullableObject:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FLTAnEnumBox *arg_anEnum = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoNullableEnum:arg_anEnum - completion:^(FLTAnEnumBox *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + id arg_anObject = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableObject:arg_anObject + completion:^(id _Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed list, to test asynchronous serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - [NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterSmallApiEchoString", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableList", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterSmallApiEchoString:completion:)], + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableList:completion:)], @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterSmallApiEchoString:completion:)", + @"@selector(echoAsyncNullableList:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSString *arg_aString = GetNullableObjectAtIndex(args, 0); - [api callFlutterSmallApiEchoString:arg_aString - completion:^(NSString *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSArray *arg_list = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableList:arg_list + completion:^(NSArray *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed list, to test asynchronous serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableEnumList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableEnumList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableEnumList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_enumList = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableEnumList:arg_enumList + completion:^(NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed list, to test asynchronous serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableClassList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableClassList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableClassList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_classList = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableClassList:arg_classList + completion:^(NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed map, to test asynchronous serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_map = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableMap:arg_map + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed map, to test asynchronous serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableStringMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableStringMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableStringMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_stringMap = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableStringMap:arg_stringMap + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed map, to test asynchronous serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableIntMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableIntMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableIntMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_intMap = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableIntMap:arg_intMap + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed map, to test asynchronous serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableEnumMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableEnumMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableEnumMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_enumMap = + GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableEnumMap:arg_enumMap + completion:^( + NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed map, to test asynchronous serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableClassMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableClassMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableClassMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_classMap = + GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableClassMap:arg_classMap + completion:^( + NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed enum, to test asynchronous serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableEnum", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableEnum:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableEnum:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FLTAnEnumBox *arg_anEnum = GetNullableObjectAtIndex(args, 0); + [api + echoAsyncNullableEnum:arg_anEnum + completion:^(FLTAnEnumBox *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed enum, to test asynchronous serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAnotherAsyncNullableEnum", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAnotherAsyncNullableEnum:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAnotherAsyncNullableEnum:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FLTAnotherEnumBox *arg_anotherEnum = GetNullableObjectAtIndex(args, 0); + [api echoAnotherAsyncNullableEnum:arg_anotherEnum + completion:^(FLTAnotherEnumBox *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterNoop", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterNoopWithCompletion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterNoopWithCompletion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + [api callFlutterNoopWithCompletion:^(FlutterError *_Nullable error) { + callback(wrapResult(nil, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterThrowError", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterThrowErrorWithCompletion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterThrowErrorWithCompletion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + [api callFlutterThrowErrorWithCompletion:^(id _Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterThrowErrorFromVoid", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterThrowErrorFromVoidWithCompletion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterThrowErrorFromVoidWithCompletion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + [api callFlutterThrowErrorFromVoidWithCompletion:^(FlutterError *_Nullable error) { + callback(wrapResult(nil, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoAllTypes", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoAllTypes:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoAllTypes:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FLTAllTypes *arg_everything = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoAllTypes:arg_everything + completion:^(FLTAllTypes *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoAllNullableTypes", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoAllNullableTypes:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoAllNullableTypes:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FLTAllNullableTypes *arg_everything = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoAllNullableTypes:arg_everything + completion:^(FLTAllNullableTypes *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterSendMultipleNullableTypes", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector + (callFlutterSendMultipleNullableTypesABool:anInt:aString:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterSendMultipleNullableTypesABool:anInt:aString:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0); + NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 1); + NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 2); + [api callFlutterSendMultipleNullableTypesABool:arg_aNullableBool + anInt:arg_aNullableInt + aString:arg_aNullableString + completion:^(FLTAllNullableTypes *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi." + @"callFlutterEchoAllNullableTypesWithoutRecursion", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector + (callFlutterEchoAllNullableTypesWithoutRecursion:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoAllNullableTypesWithoutRecursion:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FLTAllNullableTypesWithoutRecursion *arg_everything = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoAllNullableTypesWithoutRecursion:arg_everything + completion:^(FLTAllNullableTypesWithoutRecursion + *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + @"callFlutterSendMultipleNullableTypesWithoutRecursion", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert( + [api respondsToSelector:@selector + (callFlutterSendMultipleNullableTypesWithoutRecursionABool: + anInt:aString:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterSendMultipleNullableTypesWithoutRecursionABool:anInt:aString:" + @"completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0); + NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 1); + NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 2); + [api callFlutterSendMultipleNullableTypesWithoutRecursionABool:arg_aNullableBool + anInt:arg_aNullableInt + aString:arg_aNullableString + completion:^( + FLTAllNullableTypesWithoutRecursion + *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoBool", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoBool:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoBool:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + BOOL arg_aBool = [GetNullableObjectAtIndex(args, 0) boolValue]; + [api callFlutterEchoBool:arg_aBool + completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoInt", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoInt:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoInt:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSInteger arg_anInt = [GetNullableObjectAtIndex(args, 0) integerValue]; + [api callFlutterEchoInt:arg_anInt + completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoDouble", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoDouble:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoDouble:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + double arg_aDouble = [GetNullableObjectAtIndex(args, 0) doubleValue]; + [api callFlutterEchoDouble:arg_aDouble + completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoString", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoString:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoString:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_aString = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoString:arg_aString + completion:^(NSString *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoUint8List", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoUint8List:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoUint8List:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FlutterStandardTypedData *arg_list = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoUint8List:arg_list + completion:^(FlutterStandardTypedData *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_list = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoList:arg_list + completion:^(NSArray *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoEnumList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoEnumList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoEnumList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_enumList = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoEnumList:arg_enumList + completion:^(NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoClassList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoClassList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoClassList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_classList = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoClassList:arg_classList + completion:^(NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNonNullEnumList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNonNullEnumList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNonNullEnumList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_enumList = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNonNullEnumList:arg_enumList + completion:^(NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNonNullClassList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNonNullClassList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNonNullClassList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_classList = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNonNullClassList:arg_classList + completion:^(NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_map = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoMap:arg_map + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoStringMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoStringMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoStringMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_stringMap = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoStringMap:arg_stringMap + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoIntMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoIntMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoIntMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_intMap = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoIntMap:arg_intMap + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoEnumMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoEnumMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoEnumMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_enumMap = + GetNullableObjectAtIndex(args, 0); + [api + callFlutterEchoEnumMap:arg_enumMap + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoClassMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoClassMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoClassMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_classMap = + GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoClassMap:arg_classMap + completion:^( + NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNonNullStringMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNonNullStringMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNonNullStringMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_stringMap = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNonNullStringMap:arg_stringMap + completion:^( + NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNonNullIntMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNonNullIntMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNonNullIntMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_intMap = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNonNullIntMap:arg_intMap + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNonNullEnumMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNonNullEnumMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNonNullEnumMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_enumMap = + GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNonNullEnumMap:arg_enumMap + completion:^( + NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNonNullClassMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNonNullClassMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNonNullClassMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_classMap = + GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNonNullClassMap:arg_classMap + completion:^(NSDictionary + *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoEnum", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoEnum:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoEnum:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FLTAnEnumBox *boxedFLTAnEnum = GetNullableObjectAtIndex(args, 0); + FLTAnEnum arg_anEnum = boxedFLTAnEnum.value; + [api callFlutterEchoEnum:arg_anEnum + completion:^(FLTAnEnumBox *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoAnotherEnum", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoAnotherEnum:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoAnotherEnum:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FLTAnotherEnumBox *boxedFLTAnotherEnum = GetNullableObjectAtIndex(args, 0); + FLTAnotherEnum arg_anotherEnum = boxedFLTAnotherEnum.value; + [api callFlutterEchoAnotherEnum:arg_anotherEnum + completion:^(FLTAnotherEnumBox *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableBool", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableBool:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableBool:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSNumber *arg_aBool = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableBool:arg_aBool + completion:^(NSNumber *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableInt", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableInt:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableInt:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSNumber *arg_anInt = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableInt:arg_anInt + completion:^(NSNumber *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableDouble", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableDouble:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableDouble:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSNumber *arg_aDouble = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableDouble:arg_aDouble + completion:^(NSNumber *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableString", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableString:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableString:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_aString = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableString:arg_aString + completion:^(NSString *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableUint8List", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableUint8List:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableUint8List:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FlutterStandardTypedData *arg_list = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableUint8List:arg_list + completion:^(FlutterStandardTypedData *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_list = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableList:arg_list + completion:^(NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableEnumList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableEnumList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableEnumList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_enumList = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableEnumList:arg_enumList + completion:^(NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableClassList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableClassList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableClassList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_classList = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableClassList:arg_classList + completion:^(NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableNonNullEnumList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableNonNullEnumList: + completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableNonNullEnumList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_enumList = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableNonNullEnumList:arg_enumList + completion:^(NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableNonNullClassList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableNonNullClassList: + completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableNonNullClassList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_classList = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableNonNullClassList:arg_classList + completion:^( + NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_map = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableMap:arg_map + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableStringMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableStringMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableStringMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_stringMap = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableStringMap:arg_stringMap + completion:^( + NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableIntMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableIntMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableIntMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_intMap = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableIntMap:arg_intMap + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableEnumMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableEnumMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableEnumMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_enumMap = + GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableEnumMap:arg_enumMap + completion:^( + NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableClassMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableClassMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableClassMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_classMap = + GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableClassMap:arg_classMap + completion:^(NSDictionary + *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableNonNullStringMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableNonNullStringMap: + completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableNonNullStringMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_stringMap = GetNullableObjectAtIndex(args, 0); + [api + callFlutterEchoNullableNonNullStringMap:arg_stringMap + completion:^( + NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableNonNullIntMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableNonNullIntMap: + completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableNonNullIntMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_intMap = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableNonNullIntMap:arg_intMap + completion:^( + NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableNonNullEnumMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableNonNullEnumMap: + completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableNonNullEnumMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_enumMap = + GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableNonNullEnumMap:arg_enumMap + completion:^(NSDictionary + *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableNonNullClassMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableNonNullClassMap: + completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableNonNullClassMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_classMap = + GetNullableObjectAtIndex(args, 0); + [api + callFlutterEchoNullableNonNullClassMap:arg_classMap + completion:^(NSDictionary + *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableEnum", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableEnum:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableEnum:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FLTAnEnumBox *arg_anEnum = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableEnum:arg_anEnum + completion:^(FLTAnEnumBox *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoAnotherNullableEnum", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoAnotherNullableEnum:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoAnotherNullableEnum:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FLTAnotherEnumBox *arg_anotherEnum = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoAnotherNullableEnum:arg_anotherEnum + completion:^(FLTAnotherEnumBox *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterSmallApiEchoString", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterSmallApiEchoString:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterSmallApiEchoString:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_aString = GetNullableObjectAtIndex(args, 0); + [api callFlutterSmallApiEchoString:arg_aString + completion:^(NSString *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } +} +@interface FLTFlutterIntegrationCoreApi () +@property(nonatomic, strong) NSObject *binaryMessenger; +@property(nonatomic, strong) NSString *messageChannelSuffix; +@end + +@implementation FLTFlutterIntegrationCoreApi + +- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger { + return [self initWithBinaryMessenger:binaryMessenger messageChannelSuffix:@""]; +} +- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger + messageChannelSuffix:(nullable NSString *)messageChannelSuffix { + self = [self init]; + if (self) { + _binaryMessenger = binaryMessenger; + _messageChannelSuffix = [messageChannelSuffix length] == 0 + ? @"" + : [NSString stringWithFormat:@".%@", messageChannelSuffix]; + } + return self; +} +- (void)noopWithCompletion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.noop", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:nil + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; +} +- (void)throwErrorWithCompletion:(void (^)(id _Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwError", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:nil + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + id output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)throwErrorFromVoidWithCompletion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.throwErrorFromVoid", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:nil + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; +} +- (void)echoAllTypes:(FLTAllTypes *)arg_everything + completion:(void (^)(FLTAllTypes *_Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllTypes", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_everything ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + FLTAllTypes *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoAllNullableTypes:(nullable FLTAllNullableTypes *)arg_everything + completion:(void (^)(FLTAllNullableTypes *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoAllNullableTypes", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_everything ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + FLTAllNullableTypes *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)sendMultipleNullableTypesABool:(nullable NSNumber *)arg_aNullableBool + anInt:(nullable NSNumber *)arg_aNullableInt + aString:(nullable NSString *)arg_aNullableString + completion:(void (^)(FLTAllNullableTypes *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.sendMultipleNullableTypes", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ + arg_aNullableBool ?: [NSNull null], arg_aNullableInt ?: [NSNull null], + arg_aNullableString ?: [NSNull null] + ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + FLTAllNullableTypes *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoAllNullableTypesWithoutRecursion: + (nullable FLTAllNullableTypesWithoutRecursion *)arg_everything + completion: + (void (^)(FLTAllNullableTypesWithoutRecursion *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoAllNullableTypesWithoutRecursion", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_everything ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + FLTAllNullableTypesWithoutRecursion *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)sendMultipleNullableTypesWithoutRecursionABool:(nullable NSNumber *)arg_aNullableBool + anInt:(nullable NSNumber *)arg_aNullableInt + aString:(nullable NSString *)arg_aNullableString + completion: + (void (^)( + FLTAllNullableTypesWithoutRecursion *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + @"sendMultipleNullableTypesWithoutRecursion", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ + arg_aNullableBool ?: [NSNull null], arg_aNullableInt ?: [NSNull null], + arg_aNullableString ?: [NSNull null] + ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + FLTAllNullableTypesWithoutRecursion *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoBool:(BOOL)arg_aBool + completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoBool", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ @(arg_aBool) ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSNumber *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoInt:(NSInteger)arg_anInt + completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoInt", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ @(arg_anInt) ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSNumber *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoDouble:(double)arg_aDouble + completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoDouble", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ @(arg_aDouble) ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSNumber *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoString:(NSString *)arg_aString + completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoString", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_aString ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSString *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoUint8List:(FlutterStandardTypedData *)arg_list + completion: + (void (^)(FlutterStandardTypedData *_Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoUint8List", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_list ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + FlutterStandardTypedData *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoList:(NSArray *)arg_list + completion:(void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoList", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_list ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSArray *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoEnumList:(NSArray *)arg_enumList + completion: + (void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnumList", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_enumList ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSArray *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoClassList:(NSArray *)arg_classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoClassList", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_classList ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSArray *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoNonNullEnumList:(NSArray *)arg_enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNonNullEnumList", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_enumList ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSArray *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoNonNullClassList:(NSArray *)arg_classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNonNullClassList", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_classList ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSArray *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; } -@interface FLTFlutterIntegrationCoreApi () -@property(nonatomic, strong) NSObject *binaryMessenger; -@property(nonatomic, strong) NSString *messageChannelSuffix; -@end - -@implementation FLTFlutterIntegrationCoreApi - -- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger { - return [self initWithBinaryMessenger:binaryMessenger messageChannelSuffix:@""]; +- (void)echoMap:(NSDictionary *)arg_map + completion:(void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoMap", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_map ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSDictionary *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; } -- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger - messageChannelSuffix:(nullable NSString *)messageChannelSuffix { - self = [self init]; - if (self) { - _binaryMessenger = binaryMessenger; - _messageChannelSuffix = [messageChannelSuffix length] == 0 - ? @"" - : [NSString stringWithFormat:@".%@", messageChannelSuffix]; - } - return self; +- (void)echoStringMap:(NSDictionary *)arg_stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoStringMap", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_stringMap ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; } -- (void)noopWithCompletion:(void (^)(FlutterError *_Nullable))completion { +- (void)echoIntMap:(NSDictionary *)arg_intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { NSString *channelName = [NSString stringWithFormat: - @"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.noop", + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoIntMap", _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FLTGetCoreTestsCodec()]; - [channel sendMessage:nil + [channel sendMessage:@[ arg_intMap ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { - completion([FlutterError errorWithCode:reply[0] - message:reply[1] - details:reply[2]]); + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); } else { - completion(nil); + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); } } else { - completion(createConnectionError(channelName)); + completion(nil, createConnectionError(channelName)); } }]; } -- (void)throwErrorWithCompletion:(void (^)(id _Nullable, FlutterError *_Nullable))completion { +- (void)echoEnumMap:(NSDictionary *)arg_enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { NSString *channelName = [NSString stringWithFormat: @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwError", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnumMap", _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FLTGetCoreTestsCodec()]; - [channel sendMessage:nil + [channel sendMessage:@[ arg_enumMap ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -2792,7 +5358,8 @@ - (void)throwErrorWithCompletion:(void (^)(id _Nullable, FlutterError *_Nullable message:reply[1] details:reply[2]]); } else { - id output = reply[0] == [NSNull null] ? nil : reply[0]; + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -2800,43 +5367,217 @@ - (void)throwErrorWithCompletion:(void (^)(id _Nullable, FlutterError *_Nullable } }]; } -- (void)throwErrorFromVoidWithCompletion:(void (^)(FlutterError *_Nullable))completion { +- (void)echoClassMap:(NSDictionary *)arg_classMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoClassMap", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_classMap ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoNonNullStringMap:(NSDictionary *)arg_stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { NSString *channelName = [NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"FlutterIntegrationCoreApi.throwErrorFromVoid", + @"FlutterIntegrationCoreApi.echoNonNullStringMap", _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FLTGetCoreTestsCodec()]; - [channel sendMessage:nil + [channel sendMessage:@[ arg_stringMap ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { - completion([FlutterError errorWithCode:reply[0] - message:reply[1] - details:reply[2]]); + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); } else { - completion(nil); + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); } } else { - completion(createConnectionError(channelName)); + completion(nil, createConnectionError(channelName)); } }]; } -- (void)echoAllTypes:(FLTAllTypes *)arg_everything - completion:(void (^)(FLTAllTypes *_Nullable, FlutterError *_Nullable))completion { +- (void)echoNonNullIntMap:(NSDictionary *)arg_intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNonNullIntMap", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_intMap ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoNonNullEnumMap:(NSDictionary *)arg_enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNonNullEnumMap", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_enumMap ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoNonNullClassMap:(NSDictionary *)arg_classMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNonNullClassMap", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_classMap ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoEnum:(FLTAnEnum)arg_anEnum + completion:(void (^)(FLTAnEnumBox *_Nullable, FlutterError *_Nullable))completion { NSString *channelName = [NSString stringWithFormat: @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllTypes", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnum", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ [[FLTAnEnumBox alloc] initWithValue:arg_anEnum] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + FLTAnEnumBox *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoAnotherEnum:(FLTAnotherEnum)arg_anotherEnum + completion: + (void (^)(FLTAnotherEnumBox *_Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAnotherEnum", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ [[FLTAnotherEnumBox alloc] initWithValue:arg_anotherEnum] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + FLTAnotherEnumBox *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoNullableBool:(nullable NSNumber *)arg_aBool + completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableBool", _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FLTGetCoreTestsCodec()]; - [channel sendMessage:@[ arg_everything ?: [NSNull null] ] + [channel sendMessage:@[ arg_aBool ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -2844,7 +5585,7 @@ - (void)echoAllTypes:(FLTAllTypes *)arg_everything message:reply[1] details:reply[2]]); } else { - FLTAllTypes *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSNumber *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -2852,19 +5593,18 @@ - (void)echoAllTypes:(FLTAllTypes *)arg_everything } }]; } -- (void)echoAllNullableTypes:(nullable FLTAllNullableTypes *)arg_everything - completion:(void (^)(FLTAllNullableTypes *_Nullable, - FlutterError *_Nullable))completion { - NSString *channelName = - [NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"FlutterIntegrationCoreApi.echoAllNullableTypes", - _messageChannelSuffix]; +- (void)echoNullableInt:(nullable NSNumber *)arg_anInt + completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableInt", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FLTGetCoreTestsCodec()]; - [channel sendMessage:@[ arg_everything ?: [NSNull null] ] + [channel sendMessage:@[ arg_anInt ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -2872,7 +5612,7 @@ - (void)echoAllNullableTypes:(nullable FLTAllNullableTypes *)arg_everything message:reply[1] details:reply[2]]); } else { - FLTAllNullableTypes *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSNumber *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -2880,24 +5620,18 @@ - (void)echoAllNullableTypes:(nullable FLTAllNullableTypes *)arg_everything } }]; } -- (void)sendMultipleNullableTypesABool:(nullable NSNumber *)arg_aNullableBool - anInt:(nullable NSNumber *)arg_aNullableInt - aString:(nullable NSString *)arg_aNullableString - completion:(void (^)(FLTAllNullableTypes *_Nullable, - FlutterError *_Nullable))completion { +- (void)echoNullableDouble:(nullable NSNumber *)arg_aDouble + completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { NSString *channelName = [NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"FlutterIntegrationCoreApi.sendMultipleNullableTypes", + @"FlutterIntegrationCoreApi.echoNullableDouble", _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FLTGetCoreTestsCodec()]; - [channel sendMessage:@[ - arg_aNullableBool ?: [NSNull null], arg_aNullableInt ?: [NSNull null], - arg_aNullableString ?: [NSNull null] - ] + [channel sendMessage:@[ arg_aDouble ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -2905,7 +5639,7 @@ - (void)sendMultipleNullableTypesABool:(nullable NSNumber *)arg_aNullableBool message:reply[1] details:reply[2]]); } else { - FLTAllNullableTypes *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSNumber *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -2913,21 +5647,18 @@ - (void)sendMultipleNullableTypesABool:(nullable NSNumber *)arg_aNullableBool } }]; } -- (void)echoAllNullableTypesWithoutRecursion: - (nullable FLTAllNullableTypesWithoutRecursion *)arg_everything - completion: - (void (^)(FLTAllNullableTypesWithoutRecursion *_Nullable, - FlutterError *_Nullable))completion { +- (void)echoNullableString:(nullable NSString *)arg_aString + completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion { NSString *channelName = [NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"FlutterIntegrationCoreApi.echoAllNullableTypesWithoutRecursion", + @"FlutterIntegrationCoreApi.echoNullableString", _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FLTGetCoreTestsCodec()]; - [channel sendMessage:@[ arg_everything ?: [NSNull null] ] + [channel sendMessage:@[ arg_aString ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -2935,8 +5666,7 @@ - (void)echoAllNullableTypesWithoutRecursion: message:reply[1] details:reply[2]]); } else { - FLTAllNullableTypesWithoutRecursion *output = - reply[0] == [NSNull null] ? nil : reply[0]; + NSString *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -2944,26 +5674,19 @@ - (void)echoAllNullableTypesWithoutRecursion: } }]; } -- (void)sendMultipleNullableTypesWithoutRecursionABool:(nullable NSNumber *)arg_aNullableBool - anInt:(nullable NSNumber *)arg_aNullableInt - aString:(nullable NSString *)arg_aNullableString - completion: - (void (^)( - FLTAllNullableTypesWithoutRecursion *_Nullable, - FlutterError *_Nullable))completion { - NSString *channelName = [NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - @"sendMultipleNullableTypesWithoutRecursion", - _messageChannelSuffix]; +- (void)echoNullableUint8List:(nullable FlutterStandardTypedData *)arg_list + completion:(void (^)(FlutterStandardTypedData *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNullableUint8List", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FLTGetCoreTestsCodec()]; - [channel sendMessage:@[ - arg_aNullableBool ?: [NSNull null], arg_aNullableInt ?: [NSNull null], - arg_aNullableString ?: [NSNull null] - ] + [channel sendMessage:@[ arg_list ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -2971,7 +5694,7 @@ - (void)sendMultipleNullableTypesWithoutRecursionABool:(nullable NSNumber *)arg_ message:reply[1] details:reply[2]]); } else { - FLTAllNullableTypesWithoutRecursion *output = + FlutterStandardTypedData *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } @@ -2980,18 +5703,18 @@ - (void)sendMultipleNullableTypesWithoutRecursionABool:(nullable NSNumber *)arg_ } }]; } -- (void)echoBool:(BOOL)arg_aBool - completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { +- (void)echoNullableList:(nullable NSArray *)arg_list + completion:(void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion { NSString *channelName = [NSString stringWithFormat: @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoBool", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableList", _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FLTGetCoreTestsCodec()]; - [channel sendMessage:@[ @(arg_aBool) ] + [channel sendMessage:@[ arg_list ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -2999,7 +5722,7 @@ - (void)echoBool:(BOOL)arg_aBool message:reply[1] details:reply[2]]); } else { - NSNumber *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSArray *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3007,17 +5730,19 @@ - (void)echoBool:(BOOL)arg_aBool } }]; } -- (void)echoInt:(NSInteger)arg_anInt - completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { - NSString *channelName = [NSString - stringWithFormat: - @"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoInt", - _messageChannelSuffix]; +- (void)echoNullableEnumList:(nullable NSArray *)arg_enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNullableEnumList", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FLTGetCoreTestsCodec()]; - [channel sendMessage:@[ @(arg_anInt) ] + [channel sendMessage:@[ arg_enumList ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3025,7 +5750,7 @@ - (void)echoInt:(NSInteger)arg_anInt message:reply[1] details:reply[2]]); } else { - NSNumber *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSArray *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3033,18 +5758,19 @@ - (void)echoInt:(NSInteger)arg_anInt } }]; } -- (void)echoDouble:(double)arg_aDouble - completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { - NSString *channelName = [NSString - stringWithFormat: - @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoDouble", - _messageChannelSuffix]; +- (void)echoNullableClassList:(nullable NSArray *)arg_classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNullableClassList", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FLTGetCoreTestsCodec()]; - [channel sendMessage:@[ @(arg_aDouble) ] + [channel sendMessage:@[ arg_classList ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3052,7 +5778,8 @@ - (void)echoDouble:(double)arg_aDouble message:reply[1] details:reply[2]]); } else { - NSNumber *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSArray *output = + reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3060,18 +5787,19 @@ - (void)echoDouble:(double)arg_aDouble } }]; } -- (void)echoString:(NSString *)arg_aString - completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion { - NSString *channelName = [NSString - stringWithFormat: - @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoString", - _messageChannelSuffix]; +- (void)echoNullableNonNullEnumList:(nullable NSArray *)arg_enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNullableNonNullEnumList", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FLTGetCoreTestsCodec()]; - [channel sendMessage:@[ arg_aString ?: [NSNull null] ] + [channel sendMessage:@[ arg_enumList ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3079,7 +5807,7 @@ - (void)echoString:(NSString *)arg_aString message:reply[1] details:reply[2]]); } else { - NSString *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSArray *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3087,19 +5815,19 @@ - (void)echoString:(NSString *)arg_aString } }]; } -- (void)echoUint8List:(FlutterStandardTypedData *)arg_list - completion: - (void (^)(FlutterStandardTypedData *_Nullable, FlutterError *_Nullable))completion { - NSString *channelName = [NSString - stringWithFormat: - @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoUint8List", - _messageChannelSuffix]; +- (void)echoNullableNonNullClassList:(nullable NSArray *)arg_classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNullableNonNullClassList", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FLTGetCoreTestsCodec()]; - [channel sendMessage:@[ arg_list ?: [NSNull null] ] + [channel sendMessage:@[ arg_classList ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3107,7 +5835,7 @@ - (void)echoUint8List:(FlutterStandardTypedData *)arg_list message:reply[1] details:reply[2]]); } else { - FlutterStandardTypedData *output = + NSArray *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } @@ -3116,18 +5844,19 @@ - (void)echoUint8List:(FlutterStandardTypedData *)arg_list } }]; } -- (void)echoList:(NSArray *)arg_list - completion:(void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion { +- (void)echoNullableMap:(nullable NSDictionary *)arg_map + completion: + (void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion { NSString *channelName = [NSString stringWithFormat: @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoList", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableMap", _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FLTGetCoreTestsCodec()]; - [channel sendMessage:@[ arg_list ?: [NSNull null] ] + [channel sendMessage:@[ arg_map ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3135,7 +5864,7 @@ - (void)echoList:(NSArray *)arg_list message:reply[1] details:reply[2]]); } else { - NSArray *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSDictionary *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3143,18 +5872,19 @@ - (void)echoList:(NSArray *)arg_list } }]; } -- (void)echoMap:(NSDictionary *)arg_aMap - completion: - (void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion { - NSString *channelName = [NSString - stringWithFormat: - @"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoMap", - _messageChannelSuffix]; +- (void)echoNullableStringMap:(nullable NSDictionary *)arg_stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNullableStringMap", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FLTGetCoreTestsCodec()]; - [channel sendMessage:@[ arg_aMap ?: [NSNull null] ] + [channel sendMessage:@[ arg_stringMap ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3162,7 +5892,7 @@ - (void)echoMap:(NSDictionary *)arg_aMap message:reply[1] details:reply[2]]); } else { - NSDictionary *output = + NSDictionary *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } @@ -3171,18 +5901,19 @@ - (void)echoMap:(NSDictionary *)arg_aMap } }]; } -- (void)echoEnum:(FLTAnEnum)arg_anEnum - completion:(void (^)(FLTAnEnumBox *_Nullable, FlutterError *_Nullable))completion { - NSString *channelName = [NSString - stringWithFormat: - @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnum", - _messageChannelSuffix]; +- (void)echoNullableIntMap:(nullable NSDictionary *)arg_intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNullableIntMap", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FLTGetCoreTestsCodec()]; - [channel sendMessage:@[ [[FLTAnEnumBox alloc] initWithValue:arg_anEnum] ] + [channel sendMessage:@[ arg_intMap ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3190,7 +5921,8 @@ - (void)echoEnum:(FLTAnEnum)arg_anEnum message:reply[1] details:reply[2]]); } else { - FLTAnEnumBox *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3198,18 +5930,19 @@ - (void)echoEnum:(FLTAnEnum)arg_anEnum } }]; } -- (void)echoNullableBool:(nullable NSNumber *)arg_aBool - completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { - NSString *channelName = [NSString - stringWithFormat: - @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableBool", - _messageChannelSuffix]; +- (void)echoNullableEnumMap:(nullable NSDictionary *)arg_enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNullableEnumMap", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FLTGetCoreTestsCodec()]; - [channel sendMessage:@[ arg_aBool ?: [NSNull null] ] + [channel sendMessage:@[ arg_enumMap ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3217,7 +5950,8 @@ - (void)echoNullableBool:(nullable NSNumber *)arg_aBool message:reply[1] details:reply[2]]); } else { - NSNumber *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3225,18 +5959,20 @@ - (void)echoNullableBool:(nullable NSNumber *)arg_aBool } }]; } -- (void)echoNullableInt:(nullable NSNumber *)arg_anInt - completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { - NSString *channelName = [NSString - stringWithFormat: - @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableInt", - _messageChannelSuffix]; +- (void)echoNullableClassMap: + (nullable NSDictionary *)arg_classMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNullableClassMap", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FLTGetCoreTestsCodec()]; - [channel sendMessage:@[ arg_anInt ?: [NSNull null] ] + [channel sendMessage:@[ arg_classMap ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3244,7 +5980,8 @@ - (void)echoNullableInt:(nullable NSNumber *)arg_anInt message:reply[1] details:reply[2]]); } else { - NSNumber *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3252,18 +5989,19 @@ - (void)echoNullableInt:(nullable NSNumber *)arg_anInt } }]; } -- (void)echoNullableDouble:(nullable NSNumber *)arg_aDouble - completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { +- (void)echoNullableNonNullStringMap:(nullable NSDictionary *)arg_stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { NSString *channelName = [NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"FlutterIntegrationCoreApi.echoNullableDouble", + @"FlutterIntegrationCoreApi.echoNullableNonNullStringMap", _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FLTGetCoreTestsCodec()]; - [channel sendMessage:@[ arg_aDouble ?: [NSNull null] ] + [channel sendMessage:@[ arg_stringMap ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3271,7 +6009,8 @@ - (void)echoNullableDouble:(nullable NSNumber *)arg_aDouble message:reply[1] details:reply[2]]); } else { - NSNumber *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3279,18 +6018,19 @@ - (void)echoNullableDouble:(nullable NSNumber *)arg_aDouble } }]; } -- (void)echoNullableString:(nullable NSString *)arg_aString - completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion { +- (void)echoNullableNonNullIntMap:(nullable NSDictionary *)arg_intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { NSString *channelName = [NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"FlutterIntegrationCoreApi.echoNullableString", + @"FlutterIntegrationCoreApi.echoNullableNonNullIntMap", _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FLTGetCoreTestsCodec()]; - [channel sendMessage:@[ arg_aString ?: [NSNull null] ] + [channel sendMessage:@[ arg_intMap ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3298,7 +6038,8 @@ - (void)echoNullableString:(nullable NSString *)arg_aString message:reply[1] details:reply[2]]); } else { - NSString *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3306,19 +6047,20 @@ - (void)echoNullableString:(nullable NSString *)arg_aString } }]; } -- (void)echoNullableUint8List:(nullable FlutterStandardTypedData *)arg_list - completion:(void (^)(FlutterStandardTypedData *_Nullable, - FlutterError *_Nullable))completion { +- (void) + echoNullableNonNullEnumMap:(nullable NSDictionary *)arg_enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { NSString *channelName = [NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"FlutterIntegrationCoreApi.echoNullableUint8List", + @"FlutterIntegrationCoreApi.echoNullableNonNullEnumMap", _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FLTGetCoreTestsCodec()]; - [channel sendMessage:@[ arg_list ?: [NSNull null] ] + [channel sendMessage:@[ arg_enumMap ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3326,7 +6068,7 @@ - (void)echoNullableUint8List:(nullable FlutterStandardTypedData *)arg_list message:reply[1] details:reply[2]]); } else { - FlutterStandardTypedData *output = + NSDictionary *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } @@ -3335,18 +6077,21 @@ - (void)echoNullableUint8List:(nullable FlutterStandardTypedData *)arg_list } }]; } -- (void)echoNullableList:(nullable NSArray *)arg_list - completion:(void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion { - NSString *channelName = [NSString - stringWithFormat: - @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableList", - _messageChannelSuffix]; +- (void)echoNullableNonNullClassMap: + (nullable NSDictionary *)arg_classMap + completion: + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNullableNonNullClassMap", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FLTGetCoreTestsCodec()]; - [channel sendMessage:@[ arg_list ?: [NSNull null] ] + [channel sendMessage:@[ arg_classMap ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3354,7 +6099,8 @@ - (void)echoNullableList:(nullable NSArray *)arg_list message:reply[1] details:reply[2]]); } else { - NSArray *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3362,19 +6108,18 @@ - (void)echoNullableList:(nullable NSArray *)arg_list } }]; } -- (void)echoNullableMap:(nullable NSDictionary *)arg_aMap - completion:(void (^)(NSDictionary *_Nullable, - FlutterError *_Nullable))completion { +- (void)echoNullableEnum:(nullable FLTAnEnumBox *)arg_anEnum + completion:(void (^)(FLTAnEnumBox *_Nullable, FlutterError *_Nullable))completion { NSString *channelName = [NSString stringWithFormat: @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableMap", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableEnum", _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FLTGetCoreTestsCodec()]; - [channel sendMessage:@[ arg_aMap ?: [NSNull null] ] + [channel sendMessage:@[ arg_anEnum == nil ? [NSNull null] : arg_anEnum ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3382,8 +6127,7 @@ - (void)echoNullableMap:(nullable NSDictionary *)arg_aMap message:reply[1] details:reply[2]]); } else { - NSDictionary *output = - reply[0] == [NSNull null] ? nil : reply[0]; + FLTAnEnumBox *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3391,18 +6135,19 @@ - (void)echoNullableMap:(nullable NSDictionary *)arg_aMap } }]; } -- (void)echoNullableEnum:(nullable FLTAnEnumBox *)arg_anEnum - completion:(void (^)(FLTAnEnumBox *_Nullable, FlutterError *_Nullable))completion { - NSString *channelName = [NSString - stringWithFormat: - @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableEnum", - _messageChannelSuffix]; +- (void)echoAnotherNullableEnum:(nullable FLTAnotherEnumBox *)arg_anotherEnum + completion:(void (^)(FLTAnotherEnumBox *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoAnotherNullableEnum", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FLTGetCoreTestsCodec()]; - [channel sendMessage:@[ arg_anEnum == nil ? [NSNull null] : arg_anEnum ] + [channel sendMessage:@[ arg_anotherEnum == nil ? [NSNull null] : arg_anotherEnum ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3410,7 +6155,7 @@ - (void)echoNullableEnum:(nullable FLTAnEnumBox *)arg_anEnum message:reply[1] details:reply[2]]); } else { - FLTAnEnumBox *output = reply[0] == [NSNull null] ? nil : reply[0]; + FLTAnotherEnumBox *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/AlternateLanguageTestPlugin.h b/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/AlternateLanguageTestPlugin.h index 6f0ca22d057c..104ee200c11f 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/AlternateLanguageTestPlugin.h +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/AlternateLanguageTestPlugin.h @@ -6,10 +6,10 @@ #import "CoreTests.gen.h" -@interface AlternateLanguageTestPlugin : NSObject +@interface AlternateLanguageTestPlugin : NSObject @end -@interface AlternateLanguageTestAPIWithSuffix : NSObject +@interface AlternateLanguageTestAPIWithSuffix : NSObject + (void)registerWithRegistrar:(NSObject *)registrar suffix:(NSString *)suffix; @end diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/AlternateLanguageTestPlugin.m b/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/AlternateLanguageTestPlugin.m index 0cdec98b9ed1..d684acfd55e6 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/AlternateLanguageTestPlugin.m +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/AlternateLanguageTestPlugin.m @@ -7,24 +7,26 @@ #import "CoreTests.gen.h" @interface AlternateLanguageTestPlugin () -@property(nonatomic) FlutterIntegrationCoreApi *flutterAPI; -@property(nonatomic) FlutterSmallApi *flutterSmallApiOne; -@property(nonatomic) FlutterSmallApi *flutterSmallApiTwo; +@property(nonatomic) FLTFlutterSmallApi *flutterSmallApiOne; +@property(nonatomic) FLTFlutterSmallApi *flutterSmallApiTwo; +@property(nonatomic) FLTFlutterIntegrationCoreApi *flutterAPI; @end /// This plugin handles the native side of the integration tests in example/integration_test/. @implementation AlternateLanguageTestPlugin + (void)registerWithRegistrar:(NSObject *)registrar { AlternateLanguageTestPlugin *plugin = [[AlternateLanguageTestPlugin alloc] init]; - SetUpHostIntegrationCoreApi(registrar.messenger, plugin); + SetUpFLTHostIntegrationCoreApi([registrar messenger], plugin); [AlternateLanguageTestAPIWithSuffix registerWithRegistrar:registrar suffix:@"suffixOne"]; [AlternateLanguageTestAPIWithSuffix registerWithRegistrar:registrar suffix:@"suffixTwo"]; plugin.flutterAPI = - [[FlutterIntegrationCoreApi alloc] initWithBinaryMessenger:registrar.messenger]; - plugin.flutterSmallApiOne = [[FlutterSmallApi alloc] initWithBinaryMessenger:registrar.messenger - messageChannelSuffix:@"suffixOne"]; - plugin.flutterSmallApiTwo = [[FlutterSmallApi alloc] initWithBinaryMessenger:registrar.messenger - messageChannelSuffix:@"suffixTwo"]; + [[FLTFlutterIntegrationCoreApi alloc] initWithBinaryMessenger:[registrar messenger]]; + plugin.flutterSmallApiOne = + [[FLTFlutterSmallApi alloc] initWithBinaryMessenger:[registrar messenger] + messageChannelSuffix:@"suffixOne"]; + plugin.flutterSmallApiTwo = + [[FLTFlutterSmallApi alloc] initWithBinaryMessenger:[registrar messenger] + messageChannelSuffix:@"suffixTwo"]; } #pragma mark HostIntegrationCoreApi implementation @@ -32,18 +34,18 @@ + (void)registerWithRegistrar:(NSObject *)registrar { - (void)noopWithError:(FlutterError *_Nullable *_Nonnull)error { } -- (nullable AllTypes *)echoAllTypes:(AllTypes *)everything - error:(FlutterError *_Nullable *_Nonnull)error { +- (nullable FLTAllTypes *)echoAllTypes:(FLTAllTypes *)everything + error:(FlutterError *_Nullable *_Nonnull)error { return everything; } -- (nullable AllNullableTypes *)echoAllNullableTypes:(nullable AllNullableTypes *)everything - error:(FlutterError *_Nullable *_Nonnull)error { +- (nullable FLTAllNullableTypes *)echoAllNullableTypes:(nullable FLTAllNullableTypes *)everything + error:(FlutterError *_Nullable *_Nonnull)error { return everything; } -- (nullable AllNullableTypesWithoutRecursion *) - echoAllNullableTypesWithoutRecursion:(nullable AllNullableTypesWithoutRecursion *)everything +- (nullable FLTAllNullableTypesWithoutRecursion *) + echoAllNullableTypesWithoutRecursion:(nullable FLTAllNullableTypesWithoutRecursion *)everything error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { return everything; } @@ -93,18 +95,95 @@ - (nullable id)echoObject:(id)anObject error:(FlutterError *_Nullable *_Nonnull) return list; } -- (nullable NSDictionary *)echoMap:(NSDictionary *)aMap +- (nullable NSArray *)echoEnumList:(NSArray *)enumList error:(FlutterError *_Nullable *_Nonnull)error { - return aMap; + return enumList; } -- (nullable AllClassesWrapper *)echoClassWrapper:(AllClassesWrapper *)wrapper - error:(FlutterError *_Nullable *_Nonnull)error { +- (nullable NSArray *) + echoClassList:(NSArray *)classList + error:(FlutterError *_Nullable *_Nonnull)error { + return classList; +} + +- (nullable NSArray *) + echoNonNullEnumList:(nonnull NSArray *)enumList + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return enumList; +} + +- (nullable NSArray *) + echoNonNullClassList:(nonnull NSArray *)classList + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return classList; +} + +- (nullable NSDictionary *)echoMap:(NSDictionary *)map + error:(FlutterError *_Nullable *_Nonnull)error { + return map; +} + +- (nullable NSDictionary *) + echoStringMap:(NSDictionary *)stringMap + error:(FlutterError *_Nullable *_Nonnull)error { + return stringMap; +} + +- (nullable NSDictionary *) + echoIntMap:(NSDictionary *)intMap + error:(FlutterError *_Nullable *_Nonnull)error { + return intMap; +} + +- (nullable NSDictionary *) + echoEnumMap:(NSDictionary *)enumMap + error:(FlutterError *_Nullable *_Nonnull)error { + return enumMap; +} + +- (nullable NSDictionary *) + echoClassMap:(NSDictionary *)classMap + error:(FlutterError *_Nullable *_Nonnull)error { + return classMap; +} + +- (nullable NSDictionary *) + echoNonNullStringMap:(nonnull NSDictionary *)stringMap + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return stringMap; +} + +- (nullable NSDictionary *) + echoNonNullIntMap:(nonnull NSDictionary *)intMap + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return intMap; +} + +- (nullable NSDictionary *) + echoNonNullEnumMap:(nonnull NSDictionary *)enumMap + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return enumMap; +} + +- (nullable NSDictionary *) + echoNonNullClassMap:(nonnull NSDictionary *)classMap + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return classMap; +} + +- (nullable FLTAllClassesWrapper *)echoClassWrapper:(FLTAllClassesWrapper *)wrapper + error:(FlutterError *_Nullable *_Nonnull)error { return wrapper; } -- (AnEnumBox *_Nullable)echoEnum:(AnEnum)anEnum error:(FlutterError *_Nullable *_Nonnull)error { - return [[AnEnumBox alloc] initWithValue:anEnum]; +- (FLTAnEnumBox *_Nullable)echoEnum:(FLTAnEnum)anEnum + error:(FlutterError *_Nullable *_Nonnull)error { + return [[FLTAnEnumBox alloc] initWithValue:anEnum]; +} + +- (FLTAnotherEnumBox *_Nullable)echoAnotherEnum:(FLTAnotherEnum)anotherEnum + error:(FlutterError *_Nullable *_Nonnull)error { + return [[FLTAnotherEnumBox alloc] initWithValue:anotherEnum]; } - (nullable NSString *)echoNamedDefaultString:(NSString *)aString @@ -122,41 +201,46 @@ - (nullable NSNumber *)echoRequiredInt:(NSInteger)anInt return @(anInt); } -- (nullable NSString *)extractNestedNullableStringFrom:(AllClassesWrapper *)wrapper +- (nullable NSString *)extractNestedNullableStringFrom:(FLTAllClassesWrapper *)wrapper error:(FlutterError *_Nullable *_Nonnull)error { return wrapper.allNullableTypes.aNullableString; } -- (nullable AllClassesWrapper *) +- (nullable FLTAllClassesWrapper *) createNestedObjectWithNullableString:(nullable NSString *)nullableString error:(FlutterError *_Nullable *_Nonnull)error { - AllNullableTypes *innerObject = [[AllNullableTypes alloc] init]; + FLTAllNullableTypes *innerObject = [[FLTAllNullableTypes alloc] init]; innerObject.aNullableString = nullableString; - return [AllClassesWrapper makeWithAllNullableTypes:innerObject - allNullableTypesWithoutRecursion:nil - allTypes:nil]; -} - -- (nullable AllNullableTypes *)sendMultipleNullableTypesABool:(nullable NSNumber *)aNullableBool - anInt:(nullable NSNumber *)aNullableInt - aString:(nullable NSString *)aNullableString - error:(FlutterError *_Nullable *_Nonnull) - error { - AllNullableTypes *someTypes = [[AllNullableTypes alloc] init]; + return [FLTAllClassesWrapper makeWithAllNullableTypes:innerObject + allNullableTypesWithoutRecursion:nil + allTypes:nil + classList:@[] + nullableClassList:nil + classMap:@{} + nullableClassMap:nil]; +} + +- (nullable FLTAllNullableTypes *) + sendMultipleNullableTypesABool:(nullable NSNumber *)aNullableBool + anInt:(nullable NSNumber *)aNullableInt + aString:(nullable NSString *)aNullableString + error:(FlutterError *_Nullable *_Nonnull)error { + FLTAllNullableTypes *someTypes = [[FLTAllNullableTypes alloc] init]; someTypes.aNullableBool = aNullableBool; someTypes.aNullableInt = aNullableInt; someTypes.aNullableString = aNullableString; return someTypes; } -- (nullable AllNullableTypesWithoutRecursion *) +- (nullable FLTAllNullableTypesWithoutRecursion *) sendMultipleNullableTypesWithoutRecursionABool:(nullable NSNumber *)aNullableBool anInt:(nullable NSNumber *)aNullableInt aString:(nullable NSString *)aNullableString error: (FlutterError *_Nullable __autoreleasing *_Nonnull) error { - AllNullableTypesWithoutRecursion *someTypes = [[AllNullableTypesWithoutRecursion alloc] init]; + FLTAllNullableTypesWithoutRecursion *someTypes = + [[FLTAllNullableTypesWithoutRecursion alloc] init]; someTypes.aNullableBool = aNullableBool; someTypes.aNullableInt = aNullableInt; someTypes.aNullableString = aNullableString; @@ -199,17 +283,94 @@ - (nullable id)echoNullableObject:(nullable id)aNullableObject return aNullableList; } -- (nullable NSDictionary *) - echoNullableMap:(nullable NSDictionary *)aNullableMap - error:(FlutterError *_Nullable *_Nonnull)error { - return aNullableMap; +- (nullable NSArray *) + echoNullableEnumList:(nullable NSArray *)enumList + error:(FlutterError *_Nullable *_Nonnull)error { + return enumList; } -- (AnEnumBox *_Nullable)echoNullableEnum:(nullable AnEnumBox *)AnEnumBoxed - error:(FlutterError *_Nullable *_Nonnull)error { +- (nullable NSArray *) + echoNullableClassList:(nullable NSArray *)classList + error:(FlutterError *_Nullable *_Nonnull)error { + return classList; +} + +- (nullable NSArray *) + echoNullableNonNullEnumList:(nullable NSArray *)enumList + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return enumList; +} + +- (nullable NSArray *) + echoNullableNonNullClassList:(nullable NSArray *)classList + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return classList; +} + +- (nullable NSDictionary *)echoNullableMap:(nullable NSDictionary *)map + error:(FlutterError *_Nullable *_Nonnull)error { + return map; +} + +- (nullable NSDictionary *) + echoNullableStringMap:(nullable NSDictionary *)stringMap + error:(FlutterError *_Nullable *_Nonnull)error { + return stringMap; +} + +- (nullable NSDictionary *) + echoNullableIntMap:(nullable NSDictionary *)intMap + error:(FlutterError *_Nullable *_Nonnull)error { + return intMap; +} + +- (nullable NSDictionary *) + echoNullableEnumMap:(nullable NSDictionary *)enumMap + error:(FlutterError *_Nullable *_Nonnull)error { + return enumMap; +} + +- (nullable NSDictionary *) + echoNullableClassMap:(nullable NSDictionary *)classMap + error:(FlutterError *_Nullable *_Nonnull)error { + return classMap; +} + +- (nullable NSDictionary *) + echoNullableNonNullStringMap:(nullable NSDictionary *)stringMap + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return stringMap; +} + +- (nullable NSDictionary *) + echoNullableNonNullIntMap:(nullable NSDictionary *)intMap + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return intMap; +} + +- (nullable NSDictionary *) + echoNullableNonNullEnumMap:(nullable NSDictionary *)enumMap + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return enumMap; +} + +- (nullable NSDictionary *) + echoNullableNonNullClassMap:(nullable NSDictionary *)classMap + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return classMap; +} + +- (FLTAnEnumBox *_Nullable)echoNullableEnum:(nullable FLTAnEnumBox *)AnEnumBoxed + error:(FlutterError *_Nullable *_Nonnull)error { return AnEnumBoxed; } +- (FLTAnotherEnumBox *_Nullable)echoAnotherNullableEnum: + (nullable FLTAnotherEnumBox *)AnotherEnumBoxed + error:(FlutterError *_Nullable *_Nonnull)error { + return AnotherEnumBoxed; +} + - (nullable NSNumber *)echoOptionalNullableInt:(nullable NSNumber *)aNullableInt error:(FlutterError *_Nullable *_Nonnull)error { return aNullableInt; @@ -237,23 +398,24 @@ - (void)throwAsyncFlutterErrorWithCompletion:(void (^)(id _Nullable, completion(nil, [FlutterError errorWithCode:@"code" message:@"message" details:@"details"]); } -- (void)echoAsyncAllTypes:(AllTypes *)everything - completion:(void (^)(AllTypes *_Nullable, FlutterError *_Nullable))completion { +- (void)echoAsyncAllTypes:(FLTAllTypes *)everything + completion:(void (^)(FLTAllTypes *_Nullable, FlutterError *_Nullable))completion { completion(everything, nil); } -- (void)echoAsyncNullableAllNullableTypes:(nullable AllNullableTypes *)everything - completion:(void (^)(AllNullableTypes *_Nullable, +- (void)echoAsyncNullableAllNullableTypes:(nullable FLTAllNullableTypes *)everything + completion:(void (^)(FLTAllNullableTypes *_Nullable, FlutterError *_Nullable))completion { completion(everything, nil); } -- (void)echoAsyncNullableAllNullableTypesWithoutRecursion: - (nullable AllNullableTypesWithoutRecursion *)everything - completion: - (nonnull void (^)( - AllNullableTypesWithoutRecursion *_Nullable, - FlutterError *_Nullable))completion { +- (void) + echoAsyncNullableAllNullableTypesWithoutRecursion: + (nullable FLTAllNullableTypesWithoutRecursion *)everything + completion: + (nonnull void (^)( + FLTAllNullableTypesWithoutRecursion *_Nullable, + FlutterError *_Nullable))completion { completion(everything, nil); } @@ -293,15 +455,57 @@ - (void)echoAsyncList:(NSArray *)list completion(list, nil); } -- (void)echoAsyncMap:(NSDictionary *)aMap - completion:(void (^)(NSDictionary *_Nullable, - FlutterError *_Nullable))completion { - completion(aMap, nil); +- (void)echoAsyncEnumList:(NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + completion(enumList, nil); +} + +- (void)echoAsyncClassList:(NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + completion(classList, nil); } -- (void)echoAsyncEnum:(AnEnum)anEnum - completion:(void (^)(AnEnumBox *_Nullable, FlutterError *_Nullable))completion { - completion([[AnEnumBox alloc] initWithValue:anEnum], nil); +- (void)echoAsyncMap:(NSDictionary *)map + completion: + (void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion { + completion(map, nil); +} + +- (void)echoAsyncStringMap:(NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + completion(stringMap, nil); +} + +- (void)echoAsyncIntMap:(NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + completion(intMap, nil); +} + +- (void)echoAsyncEnumMap:(NSDictionary *)enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + completion(enumMap, nil); +} + +- (void)echoAsyncClassMap:(NSDictionary *)classMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + completion(classMap, nil); +} + +- (void)echoAsyncEnum:(FLTAnEnum)anEnum + completion:(void (^)(FLTAnEnumBox *_Nullable, FlutterError *_Nullable))completion { + completion([[FLTAnEnumBox alloc] initWithValue:anEnum], nil); +} + +- (void)echoAnotherAsyncEnum:(FLTAnotherEnum)anotherEnum + completion: + (void (^)(FLTAnotherEnumBox *_Nullable, FlutterError *_Nullable))completion { + completion([[FLTAnotherEnumBox alloc] initWithValue:anotherEnum], nil); } - (void)echoAsyncNullableInt:(nullable NSNumber *)anInt @@ -341,17 +545,61 @@ - (void)echoAsyncNullableList:(nullable NSArray *)list completion(list, nil); } -- (void)echoAsyncNullableMap:(nullable NSDictionary *)aMap - completion:(void (^)(NSDictionary *_Nullable, +- (void)echoAsyncNullableEnumList:(nullable NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + completion(enumList, nil); +} + +- (void)echoAsyncNullableClassList:(nullable NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + completion(classList, nil); +} + +- (void)echoAsyncNullableMap:(nullable NSDictionary *)map + completion:(void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion { - completion(aMap, nil); + completion(map, nil); +} + +- (void)echoAsyncNullableStringMap:(nullable NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + completion(stringMap, nil); +} + +- (void)echoAsyncNullableIntMap:(nullable NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + completion(intMap, nil); +} + +- (void)echoAsyncNullableEnumMap:(nullable NSDictionary *)enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + completion(enumMap, nil); } -- (void)echoAsyncNullableEnum:(nullable AnEnumBox *)AnEnumBoxed - completion:(void (^)(AnEnumBox *_Nullable, FlutterError *_Nullable))completion { +- (void) + echoAsyncNullableClassMap:(nullable NSDictionary *)classMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + completion(classMap, nil); +} + +- (void)echoAsyncNullableEnum:(nullable FLTAnEnumBox *)AnEnumBoxed + completion: + (void (^)(FLTAnEnumBox *_Nullable, FlutterError *_Nullable))completion { completion(AnEnumBoxed, nil); } +- (void)echoAnotherAsyncNullableEnum:(nullable FLTAnotherEnumBox *)AnotherEnumBoxed + completion:(void (^)(FLTAnotherEnumBox *_Nullable, + FlutterError *_Nullable))completion { + completion(AnotherEnumBoxed, nil); +} + - (void)callFlutterNoopWithCompletion:(void (^)(FlutterError *_Nullable))completion { [self.flutterAPI noopWithCompletion:^(FlutterError *error) { completion(error); @@ -371,10 +619,11 @@ - (void)callFlutterThrowErrorFromVoidWithCompletion:(void (^)(FlutterError *_Nul }]; } -- (void)callFlutterEchoAllTypes:(AllTypes *)everything - completion:(void (^)(AllTypes *_Nullable, FlutterError *_Nullable))completion { +- (void)callFlutterEchoAllTypes:(FLTAllTypes *)everything + completion: + (void (^)(FLTAllTypes *_Nullable, FlutterError *_Nullable))completion { [self.flutterAPI echoAllTypes:everything - completion:^(AllTypes *value, FlutterError *error) { + completion:^(FLTAllTypes *value, FlutterError *error) { completion(value, error); }]; } @@ -382,14 +631,15 @@ - (void)callFlutterEchoAllTypes:(AllTypes *)everything - (void)callFlutterSendMultipleNullableTypesABool:(nullable NSNumber *)aNullableBool anInt:(nullable NSNumber *)aNullableInt aString:(nullable NSString *)aNullableString - completion:(void (^)(AllNullableTypes *_Nullable, + completion:(void (^)(FLTAllNullableTypes *_Nullable, FlutterError *_Nullable))completion { - [self.flutterAPI sendMultipleNullableTypesABool:aNullableBool - anInt:aNullableInt - aString:aNullableString - completion:^(AllNullableTypes *value, FlutterError *error) { - completion(value, error); - }]; + [self.flutterAPI + sendMultipleNullableTypesABool:aNullableBool + anInt:aNullableInt + aString:aNullableString + completion:^(FLTAllNullableTypes *value, FlutterError *error) { + completion(value, error); + }]; } - (void)callFlutterSendMultipleNullableTypesWithoutRecursionABool:(nullable NSNumber *)aNullableBool @@ -398,14 +648,14 @@ - (void)callFlutterSendMultipleNullableTypesWithoutRecursionABool:(nullable NSNu (nullable NSString *)aNullableString completion: (nonnull void (^)( - AllNullableTypesWithoutRecursion + FLTAllNullableTypesWithoutRecursion *_Nullable, FlutterError *_Nullable))completion { [self.flutterAPI sendMultipleNullableTypesWithoutRecursionABool:aNullableBool anInt:aNullableInt aString:aNullableString - completion:^(AllNullableTypesWithoutRecursion *value, + completion:^(FLTAllNullableTypesWithoutRecursion *value, FlutterError *error) { completion(value, error); }]; @@ -460,43 +710,177 @@ - (void)callFlutterEchoList:(NSArray *)list }]; } -- (void)callFlutterEchoMap:(NSDictionary *)aMap - completion:(void (^)(NSDictionary *_Nullable, - FlutterError *_Nullable))completion { - [self.flutterAPI echoMap:aMap - completion:^(NSDictionary *value, FlutterError *error) { +- (void)callFlutterEchoEnumList:(NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoEnumList:enumList + completion:^(NSArray *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoClassList:(NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoClassList:classList + completion:^(NSArray *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNonNullEnumList:(nonnull NSArray *)enumList + completion:(nonnull void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoNonNullEnumList:enumList + completion:^(NSArray *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNonNullClassList:(nonnull NSArray *)classList + completion:(nonnull void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoNonNullClassList:classList + completion:^(NSArray *value, FlutterError *error) { completion(value, error); }]; } -- (void)callFlutterEchoEnum:(AnEnum)anEnum - completion:(void (^)(AnEnumBox *_Nullable, FlutterError *_Nullable))completion { +- (void)callFlutterEchoMap:(NSDictionary *)map + completion: + (void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion { + [self.flutterAPI echoMap:map + completion:^(NSDictionary *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoStringMap:(NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoStringMap:stringMap + completion:^(NSDictionary *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoIntMap:(NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoIntMap:intMap + completion:^(NSDictionary *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoEnumMap:(NSDictionary *)enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoEnumMap:enumMap + completion:^(NSDictionary *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoClassMap:(NSDictionary *)classMap + completion: + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoClassMap:classMap + completion:^(NSDictionary *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNonNullStringMap:(nonnull NSDictionary *)stringMap + completion: + (nonnull void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoNonNullStringMap:stringMap + completion:^(NSDictionary *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNonNullIntMap:(nonnull NSDictionary *)intMap + completion: + (nonnull void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoNonNullIntMap:intMap + completion:^(NSDictionary *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNonNullEnumMap: + (nonnull NSDictionary *)enumMap + completion:(nonnull void (^)( + NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoNonNullEnumMap:enumMap + completion:^(NSDictionary *value, + FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNonNullClassMap: + (nonnull NSDictionary *)classMap + completion: + (nonnull void (^)( + NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoNonNullClassMap:classMap + completion:^(NSDictionary *value, + FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoEnum:(FLTAnEnum)anEnum + completion:(void (^)(FLTAnEnumBox *_Nullable, FlutterError *_Nullable))completion { [self.flutterAPI echoEnum:anEnum - completion:^(AnEnumBox *value, FlutterError *error) { + completion:^(FLTAnEnumBox *value, FlutterError *error) { completion(value, error); }]; } -- (void)callFlutterEchoAllNullableTypes:(nullable AllNullableTypes *)everything - completion:(void (^)(AllNullableTypes *_Nullable, +- (void)callFlutterEchoAnotherEnum:(FLTAnotherEnum)anotherEnum + completion:(void (^)(FLTAnotherEnumBox *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoAnotherEnum:anotherEnum + completion:^(FLTAnotherEnumBox *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoAllNullableTypes:(nullable FLTAllNullableTypes *)everything + completion:(void (^)(FLTAllNullableTypes *_Nullable, FlutterError *_Nullable))completion { [self.flutterAPI echoAllNullableTypes:everything - completion:^(AllNullableTypes *value, FlutterError *error) { + completion:^(FLTAllNullableTypes *value, FlutterError *error) { completion(value, error); }]; } - (void)callFlutterEchoAllNullableTypesWithoutRecursion: - (nullable AllNullableTypesWithoutRecursion *)everything + (nullable FLTAllNullableTypesWithoutRecursion *)everything completion: (nonnull void (^)( - AllNullableTypesWithoutRecursion *_Nullable, + FLTAllNullableTypesWithoutRecursion *_Nullable, FlutterError *_Nullable))completion { - [self.flutterAPI echoAllNullableTypesWithoutRecursion:everything - completion:^(AllNullableTypesWithoutRecursion *value, - FlutterError *error) { - completion(value, error); - }]; + [self.flutterAPI + echoAllNullableTypesWithoutRecursion:everything + completion:^(FLTAllNullableTypesWithoutRecursion *value, + FlutterError *error) { + completion(value, error); + }]; } - (void)callFlutterEchoNullableBool:(nullable NSNumber *)aBool @@ -553,24 +937,170 @@ - (void)callFlutterEchoNullableList:(nullable NSArray *)list }]; } -- (void)callFlutterEchoNullableMap:(nullable NSDictionary *)aMap - completion:(void (^)(NSDictionary *_Nullable, +- (void)callFlutterEchoNullableEnumList:(nullable NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoNullableEnumList:enumList + completion:^(NSArray *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNullableClassList:(nullable NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoNullableClassList:classList + completion:^(NSArray *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNullableNonNullEnumList:(nullable NSArray *)enumList + completion: + (nonnull void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoNullableNonNullEnumList:enumList + completion:^(NSArray *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNullableNonNullClassList:(nullable NSArray *)classList + completion:(nonnull void (^)( + NSArray *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoNullableNonNullClassList:classList + completion:^(NSArray *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNullableMap:(nullable NSDictionary *)map + completion:(void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion { - [self.flutterAPI echoNullableMap:aMap - completion:^(NSDictionary *value, FlutterError *error) { + [self.flutterAPI echoNullableMap:map + completion:^(NSDictionary *value, FlutterError *error) { completion(value, error); }]; } -- (void)callFlutterEchoNullableEnum:(nullable AnEnumBox *)AnEnumBoxed +- (void)callFlutterEchoNullableStringMap:(nullable NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoNullableStringMap:stringMap + completion:^(NSDictionary *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNullableIntMap:(nullable NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoNullableIntMap:intMap + completion:^(NSDictionary *value, FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNullableEnumMap: + (nullable NSDictionary *)enumMap + completion: + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoNullableEnumMap:enumMap + completion:^(NSDictionary *value, + FlutterError *error) { + completion(value, error); + }]; +} + +- (void) + callFlutterEchoNullableClassMap: + (nullable NSDictionary *)classMap completion: - (void (^)(AnEnumBox *_Nullable, FlutterError *_Nullable))completion { + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoNullableClassMap:classMap + completion:^(NSDictionary *value, + FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNullableNonNullStringMap: + (nullable NSDictionary *)stringMap + completion:(nonnull void (^)( + NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoNullableNonNullStringMap:stringMap + completion:^(NSDictionary *value, + FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNullableNonNullIntMap:(nullable NSDictionary *)intMap + completion:(nonnull void (^)( + NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoNullableNonNullIntMap:intMap + completion:^(NSDictionary *value, + FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNullableNonNullEnumMap: + (nullable NSDictionary *)enumMap + completion: + (nonnull void (^)( + NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoNullableNonNullEnumMap:enumMap + completion:^(NSDictionary *value, + FlutterError *error) { + completion(value, error); + }]; +} + +- (void) + callFlutterEchoNullableNonNullClassMap: + (nullable NSDictionary *)classMap + completion: + (nonnull void (^)( + NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoNullableNonNullClassMap:classMap + completion:^(NSDictionary *value, + FlutterError *error) { + completion(value, error); + }]; +} + +- (void)callFlutterEchoNullableEnum:(nullable FLTAnEnumBox *)AnEnumBoxed + completion:(void (^)(FLTAnEnumBox *_Nullable, + FlutterError *_Nullable))completion { [self.flutterAPI echoNullableEnum:AnEnumBoxed - completion:^(AnEnumBox *value, FlutterError *error) { + completion:^(FLTAnEnumBox *value, FlutterError *error) { completion(value, error); }]; } +- (void)callFlutterEchoAnotherNullableEnum:(nullable FLTAnotherEnumBox *)AnotherEnumBoxed + completion:(void (^)(FLTAnotherEnumBox *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoAnotherNullableEnum:AnotherEnumBoxed + completion:^(FLTAnotherEnumBox *value, FlutterError *error) { + completion(value, error); + }]; +} + - (void)callFlutterSmallApiEchoString:(nonnull NSString *)aString completion:(nonnull void (^)(NSString *_Nullable, FlutterError *_Nullable))completion { @@ -597,6 +1127,10 @@ - (void)callFlutterSmallApiEchoString:(nonnull NSString *)aString }]; } +- (FLTUnusedClass *)checkIfUnusedClassGenerated { + return [[FLTUnusedClass alloc] init]; +} + @end @interface AlternateLanguageTestAPIWithSuffix () @@ -606,7 +1140,7 @@ @implementation AlternateLanguageTestAPIWithSuffix + (void)registerWithRegistrar:(NSObject *)registrar suffix:(NSString *)suffix { AlternateLanguageTestAPIWithSuffix *api = [[AlternateLanguageTestAPIWithSuffix alloc] init]; - SetUpHostSmallApiWithSuffix(registrar.messenger, api, suffix); + SetUpFLTHostSmallApiWithSuffix([registrar messenger], api, suffix); } #pragma mark HostSmallAPI implementation diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.h b/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.h index f2b2c0747555..bd913ca95a9e 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.h +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.h @@ -14,28 +14,44 @@ NS_ASSUME_NONNULL_BEGIN -typedef NS_ENUM(NSUInteger, AnEnum) { - AnEnumOne = 0, - AnEnumTwo = 1, - AnEnumThree = 2, - AnEnumFortyTwo = 3, - AnEnumFourHundredTwentyTwo = 4, +typedef NS_ENUM(NSUInteger, FLTAnEnum) { + FLTAnEnumOne = 0, + FLTAnEnumTwo = 1, + FLTAnEnumThree = 2, + FLTAnEnumFortyTwo = 3, + FLTAnEnumFourHundredTwentyTwo = 4, }; -/// Wrapper for AnEnum to allow for nullability. -@interface AnEnumBox : NSObject -@property(nonatomic, assign) AnEnum value; -- (instancetype)initWithValue:(AnEnum)value; +/// Wrapper for FLTAnEnum to allow for nullability. +@interface FLTAnEnumBox : NSObject +@property(nonatomic, assign) FLTAnEnum value; +- (instancetype)initWithValue:(FLTAnEnum)value; @end -@class AllTypes; -@class AllNullableTypes; -@class AllNullableTypesWithoutRecursion; -@class AllClassesWrapper; -@class TestMessage; +typedef NS_ENUM(NSUInteger, FLTAnotherEnum) { + FLTAnotherEnumJustInCase = 0, +}; + +/// Wrapper for FLTAnotherEnum to allow for nullability. +@interface FLTAnotherEnumBox : NSObject +@property(nonatomic, assign) FLTAnotherEnum value; +- (instancetype)initWithValue:(FLTAnotherEnum)value; +@end + +@class FLTUnusedClass; +@class FLTAllTypes; +@class FLTAllNullableTypes; +@class FLTAllNullableTypesWithoutRecursion; +@class FLTAllClassesWrapper; +@class FLTTestMessage; + +@interface FLTUnusedClass : NSObject ++ (instancetype)makeWithAField:(nullable id)aField; +@property(nonatomic, strong, nullable) id aField; +@end /// A class containing all supported types. -@interface AllTypes : NSObject +@interface FLTAllTypes : NSObject /// `init` unavailable to enforce nonnull fields, see the `make` class method. - (instancetype)init NS_UNAVAILABLE; + (instancetype)makeWithABool:(BOOL)aBool @@ -46,7 +62,8 @@ typedef NS_ENUM(NSUInteger, AnEnum) { a4ByteArray:(FlutterStandardTypedData *)a4ByteArray a8ByteArray:(FlutterStandardTypedData *)a8ByteArray aFloatArray:(FlutterStandardTypedData *)aFloatArray - anEnum:(AnEnum)anEnum + anEnum:(FLTAnEnum)anEnum + anotherEnum:(FLTAnotherEnum)anotherEnum aString:(NSString *)aString anObject:(id)anObject list:(NSArray *)list @@ -54,7 +71,17 @@ typedef NS_ENUM(NSUInteger, AnEnum) { intList:(NSArray *)intList doubleList:(NSArray *)doubleList boolList:(NSArray *)boolList - map:(NSDictionary *)map; + enumList:(NSArray *)enumList + objectList:(NSArray *)objectList + listList:(NSArray *> *)listList + mapList:(NSArray *> *)mapList + map:(NSDictionary *)map + stringMap:(NSDictionary *)stringMap + intMap:(NSDictionary *)intMap + enumMap:(NSDictionary *)enumMap + objectMap:(NSDictionary *)objectMap + listMap:(NSDictionary *> *)listMap + mapMap:(NSDictionary *> *)mapMap; @property(nonatomic, assign) BOOL aBool; @property(nonatomic, assign) NSInteger anInt; @property(nonatomic, assign) NSInteger anInt64; @@ -63,7 +90,8 @@ typedef NS_ENUM(NSUInteger, AnEnum) { @property(nonatomic, strong) FlutterStandardTypedData *a4ByteArray; @property(nonatomic, strong) FlutterStandardTypedData *a8ByteArray; @property(nonatomic, strong) FlutterStandardTypedData *aFloatArray; -@property(nonatomic, assign) AnEnum anEnum; +@property(nonatomic, assign) FLTAnEnum anEnum; +@property(nonatomic, assign) FLTAnotherEnum anotherEnum; @property(nonatomic, copy) NSString *aString; @property(nonatomic, strong) id anObject; @property(nonatomic, copy) NSArray *list; @@ -71,34 +99,54 @@ typedef NS_ENUM(NSUInteger, AnEnum) { @property(nonatomic, copy) NSArray *intList; @property(nonatomic, copy) NSArray *doubleList; @property(nonatomic, copy) NSArray *boolList; +@property(nonatomic, copy) NSArray *enumList; +@property(nonatomic, copy) NSArray *objectList; +@property(nonatomic, copy) NSArray *> *listList; +@property(nonatomic, copy) NSArray *> *mapList; @property(nonatomic, copy) NSDictionary *map; +@property(nonatomic, copy) NSDictionary *stringMap; +@property(nonatomic, copy) NSDictionary *intMap; +@property(nonatomic, copy) NSDictionary *enumMap; +@property(nonatomic, copy) NSDictionary *objectMap; +@property(nonatomic, copy) NSDictionary *> *listMap; +@property(nonatomic, copy) NSDictionary *> *mapMap; @end /// A class containing all supported nullable types. -@interface AllNullableTypes : NSObject -+ (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool - aNullableInt:(nullable NSNumber *)aNullableInt - aNullableInt64:(nullable NSNumber *)aNullableInt64 - aNullableDouble:(nullable NSNumber *)aNullableDouble - aNullableByteArray:(nullable FlutterStandardTypedData *)aNullableByteArray - aNullable4ByteArray:(nullable FlutterStandardTypedData *)aNullable4ByteArray - aNullable8ByteArray:(nullable FlutterStandardTypedData *)aNullable8ByteArray - aNullableFloatArray:(nullable FlutterStandardTypedData *)aNullableFloatArray - nullableNestedList:(nullable NSArray *> *)nullableNestedList - nullableMapWithAnnotations: - (nullable NSDictionary *)nullableMapWithAnnotations - nullableMapWithObject:(nullable NSDictionary *)nullableMapWithObject - aNullableEnum:(nullable AnEnumBox *)aNullableEnum - aNullableString:(nullable NSString *)aNullableString - aNullableObject:(nullable id)aNullableObject - allNullableTypes:(nullable AllNullableTypes *)allNullableTypes - list:(nullable NSArray *)list - stringList:(nullable NSArray *)stringList - intList:(nullable NSArray *)intList - doubleList:(nullable NSArray *)doubleList - boolList:(nullable NSArray *)boolList - nestedClassList:(nullable NSArray *)nestedClassList - map:(nullable NSDictionary *)map; +@interface FLTAllNullableTypes : NSObject ++ (instancetype) + makeWithANullableBool:(nullable NSNumber *)aNullableBool + aNullableInt:(nullable NSNumber *)aNullableInt + aNullableInt64:(nullable NSNumber *)aNullableInt64 + aNullableDouble:(nullable NSNumber *)aNullableDouble + aNullableByteArray:(nullable FlutterStandardTypedData *)aNullableByteArray + aNullable4ByteArray:(nullable FlutterStandardTypedData *)aNullable4ByteArray + aNullable8ByteArray:(nullable FlutterStandardTypedData *)aNullable8ByteArray + aNullableFloatArray:(nullable FlutterStandardTypedData *)aNullableFloatArray + aNullableEnum:(nullable FLTAnEnumBox *)aNullableEnum + anotherNullableEnum:(nullable FLTAnotherEnumBox *)anotherNullableEnum + aNullableString:(nullable NSString *)aNullableString + aNullableObject:(nullable id)aNullableObject + allNullableTypes:(nullable FLTAllNullableTypes *)allNullableTypes + list:(nullable NSArray *)list + stringList:(nullable NSArray *)stringList + intList:(nullable NSArray *)intList + doubleList:(nullable NSArray *)doubleList + boolList:(nullable NSArray *)boolList + enumList:(nullable NSArray *)enumList + objectList:(nullable NSArray *)objectList + listList:(nullable NSArray *> *)listList + mapList:(nullable NSArray *> *)mapList + recursiveClassList:(nullable NSArray *)recursiveClassList + map:(nullable NSDictionary *)map + stringMap:(nullable NSDictionary *)stringMap + intMap:(nullable NSDictionary *)intMap + enumMap:(nullable NSDictionary *)enumMap + objectMap:(nullable NSDictionary *)objectMap + listMap:(nullable NSDictionary *> *)listMap + mapMap:(nullable NSDictionary *> *)mapMap + recursiveClassMap: + (nullable NSDictionary *)recursiveClassMap; @property(nonatomic, strong, nullable) NSNumber *aNullableBool; @property(nonatomic, strong, nullable) NSNumber *aNullableInt; @property(nonatomic, strong, nullable) NSNumber *aNullableInt64; @@ -107,48 +155,65 @@ typedef NS_ENUM(NSUInteger, AnEnum) { @property(nonatomic, strong, nullable) FlutterStandardTypedData *aNullable4ByteArray; @property(nonatomic, strong, nullable) FlutterStandardTypedData *aNullable8ByteArray; @property(nonatomic, strong, nullable) FlutterStandardTypedData *aNullableFloatArray; -@property(nonatomic, copy, nullable) NSArray *> *nullableNestedList; -@property(nonatomic, copy, nullable) - NSDictionary *nullableMapWithAnnotations; -@property(nonatomic, copy, nullable) NSDictionary *nullableMapWithObject; -@property(nonatomic, strong, nullable) AnEnumBox *aNullableEnum; +@property(nonatomic, strong, nullable) FLTAnEnumBox *aNullableEnum; +@property(nonatomic, strong, nullable) FLTAnotherEnumBox *anotherNullableEnum; @property(nonatomic, copy, nullable) NSString *aNullableString; @property(nonatomic, strong, nullable) id aNullableObject; -@property(nonatomic, strong, nullable) AllNullableTypes *allNullableTypes; +@property(nonatomic, strong, nullable) FLTAllNullableTypes *allNullableTypes; @property(nonatomic, copy, nullable) NSArray *list; @property(nonatomic, copy, nullable) NSArray *stringList; @property(nonatomic, copy, nullable) NSArray *intList; @property(nonatomic, copy, nullable) NSArray *doubleList; @property(nonatomic, copy, nullable) NSArray *boolList; -@property(nonatomic, copy, nullable) NSArray *nestedClassList; +@property(nonatomic, copy, nullable) NSArray *enumList; +@property(nonatomic, copy, nullable) NSArray *objectList; +@property(nonatomic, copy, nullable) NSArray *> *listList; +@property(nonatomic, copy, nullable) NSArray *> *mapList; +@property(nonatomic, copy, nullable) NSArray *recursiveClassList; @property(nonatomic, copy, nullable) NSDictionary *map; +@property(nonatomic, copy, nullable) NSDictionary *stringMap; +@property(nonatomic, copy, nullable) NSDictionary *intMap; +@property(nonatomic, copy, nullable) NSDictionary *enumMap; +@property(nonatomic, copy, nullable) NSDictionary *objectMap; +@property(nonatomic, copy, nullable) NSDictionary *> *listMap; +@property(nonatomic, copy, nullable) NSDictionary *> *mapMap; +@property(nonatomic, copy, nullable) + NSDictionary *recursiveClassMap; @end /// The primary purpose for this class is to ensure coverage of Swift structs /// with nullable items, as the primary [AllNullableTypes] class is being used to /// test Swift classes. -@interface AllNullableTypesWithoutRecursion : NSObject -+ (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool - aNullableInt:(nullable NSNumber *)aNullableInt - aNullableInt64:(nullable NSNumber *)aNullableInt64 - aNullableDouble:(nullable NSNumber *)aNullableDouble - aNullableByteArray:(nullable FlutterStandardTypedData *)aNullableByteArray - aNullable4ByteArray:(nullable FlutterStandardTypedData *)aNullable4ByteArray - aNullable8ByteArray:(nullable FlutterStandardTypedData *)aNullable8ByteArray - aNullableFloatArray:(nullable FlutterStandardTypedData *)aNullableFloatArray - nullableNestedList:(nullable NSArray *> *)nullableNestedList - nullableMapWithAnnotations: - (nullable NSDictionary *)nullableMapWithAnnotations - nullableMapWithObject:(nullable NSDictionary *)nullableMapWithObject - aNullableEnum:(nullable AnEnumBox *)aNullableEnum - aNullableString:(nullable NSString *)aNullableString - aNullableObject:(nullable id)aNullableObject - list:(nullable NSArray *)list - stringList:(nullable NSArray *)stringList - intList:(nullable NSArray *)intList - doubleList:(nullable NSArray *)doubleList - boolList:(nullable NSArray *)boolList - map:(nullable NSDictionary *)map; +@interface FLTAllNullableTypesWithoutRecursion : NSObject ++ (instancetype) + makeWithANullableBool:(nullable NSNumber *)aNullableBool + aNullableInt:(nullable NSNumber *)aNullableInt + aNullableInt64:(nullable NSNumber *)aNullableInt64 + aNullableDouble:(nullable NSNumber *)aNullableDouble + aNullableByteArray:(nullable FlutterStandardTypedData *)aNullableByteArray + aNullable4ByteArray:(nullable FlutterStandardTypedData *)aNullable4ByteArray + aNullable8ByteArray:(nullable FlutterStandardTypedData *)aNullable8ByteArray + aNullableFloatArray:(nullable FlutterStandardTypedData *)aNullableFloatArray + aNullableEnum:(nullable FLTAnEnumBox *)aNullableEnum + anotherNullableEnum:(nullable FLTAnotherEnumBox *)anotherNullableEnum + aNullableString:(nullable NSString *)aNullableString + aNullableObject:(nullable id)aNullableObject + list:(nullable NSArray *)list + stringList:(nullable NSArray *)stringList + intList:(nullable NSArray *)intList + doubleList:(nullable NSArray *)doubleList + boolList:(nullable NSArray *)boolList + enumList:(nullable NSArray *)enumList + objectList:(nullable NSArray *)objectList + listList:(nullable NSArray *> *)listList + mapList:(nullable NSArray *> *)mapList + map:(nullable NSDictionary *)map + stringMap:(nullable NSDictionary *)stringMap + intMap:(nullable NSDictionary *)intMap + enumMap:(nullable NSDictionary *)enumMap + objectMap:(nullable NSDictionary *)objectMap + listMap:(nullable NSDictionary *> *)listMap + mapMap:(nullable NSDictionary *> *)mapMap; @property(nonatomic, strong, nullable) NSNumber *aNullableBool; @property(nonatomic, strong, nullable) NSNumber *aNullableInt; @property(nonatomic, strong, nullable) NSNumber *aNullableInt64; @@ -157,11 +222,8 @@ typedef NS_ENUM(NSUInteger, AnEnum) { @property(nonatomic, strong, nullable) FlutterStandardTypedData *aNullable4ByteArray; @property(nonatomic, strong, nullable) FlutterStandardTypedData *aNullable8ByteArray; @property(nonatomic, strong, nullable) FlutterStandardTypedData *aNullableFloatArray; -@property(nonatomic, copy, nullable) NSArray *> *nullableNestedList; -@property(nonatomic, copy, nullable) - NSDictionary *nullableMapWithAnnotations; -@property(nonatomic, copy, nullable) NSDictionary *nullableMapWithObject; -@property(nonatomic, strong, nullable) AnEnumBox *aNullableEnum; +@property(nonatomic, strong, nullable) FLTAnEnumBox *aNullableEnum; +@property(nonatomic, strong, nullable) FLTAnotherEnumBox *anotherNullableEnum; @property(nonatomic, copy, nullable) NSString *aNullableString; @property(nonatomic, strong, nullable) id aNullableObject; @property(nonatomic, copy, nullable) NSArray *list; @@ -169,7 +231,17 @@ typedef NS_ENUM(NSUInteger, AnEnum) { @property(nonatomic, copy, nullable) NSArray *intList; @property(nonatomic, copy, nullable) NSArray *doubleList; @property(nonatomic, copy, nullable) NSArray *boolList; +@property(nonatomic, copy, nullable) NSArray *enumList; +@property(nonatomic, copy, nullable) NSArray *objectList; +@property(nonatomic, copy, nullable) NSArray *> *listList; +@property(nonatomic, copy, nullable) NSArray *> *mapList; @property(nonatomic, copy, nullable) NSDictionary *map; +@property(nonatomic, copy, nullable) NSDictionary *stringMap; +@property(nonatomic, copy, nullable) NSDictionary *intMap; +@property(nonatomic, copy, nullable) NSDictionary *enumMap; +@property(nonatomic, copy, nullable) NSDictionary *objectMap; +@property(nonatomic, copy, nullable) NSDictionary *> *listMap; +@property(nonatomic, copy, nullable) NSDictionary *> *mapMap; @end /// A class for testing nested class handling. @@ -177,39 +249,53 @@ typedef NS_ENUM(NSUInteger, AnEnum) { /// This is needed to test nested nullable and non-nullable classes, /// `AllNullableTypes` is non-nullable here as it is easier to instantiate /// than `AllTypes` when testing doesn't require both (ie. testing null classes). -@interface AllClassesWrapper : NSObject +@interface FLTAllClassesWrapper : NSObject /// `init` unavailable to enforce nonnull fields, see the `make` class method. - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)makeWithAllNullableTypes:(AllNullableTypes *)allNullableTypes - allNullableTypesWithoutRecursion: - (nullable AllNullableTypesWithoutRecursion *)allNullableTypesWithoutRecursion - allTypes:(nullable AllTypes *)allTypes; -@property(nonatomic, strong) AllNullableTypes *allNullableTypes; ++ (instancetype) + makeWithAllNullableTypes:(FLTAllNullableTypes *)allNullableTypes + allNullableTypesWithoutRecursion: + (nullable FLTAllNullableTypesWithoutRecursion *)allNullableTypesWithoutRecursion + allTypes:(nullable FLTAllTypes *)allTypes + classList:(NSArray *)classList + nullableClassList: + (nullable NSArray *)nullableClassList + classMap:(NSDictionary *)classMap + nullableClassMap: + (nullable NSDictionary *) + nullableClassMap; +@property(nonatomic, strong) FLTAllNullableTypes *allNullableTypes; @property(nonatomic, strong, nullable) - AllNullableTypesWithoutRecursion *allNullableTypesWithoutRecursion; -@property(nonatomic, strong, nullable) AllTypes *allTypes; + FLTAllNullableTypesWithoutRecursion *allNullableTypesWithoutRecursion; +@property(nonatomic, strong, nullable) FLTAllTypes *allTypes; +@property(nonatomic, copy) NSArray *classList; +@property(nonatomic, copy, nullable) + NSArray *nullableClassList; +@property(nonatomic, copy) NSDictionary *classMap; +@property(nonatomic, copy, nullable) + NSDictionary *nullableClassMap; @end /// A data class containing a List, used in unit tests. -@interface TestMessage : NSObject +@interface FLTTestMessage : NSObject + (instancetype)makeWithTestList:(nullable NSArray *)testList; @property(nonatomic, copy, nullable) NSArray *testList; @end /// The codec used by all APIs. -NSObject *GetCoreTestsCodec(void); +NSObject *FLTGetCoreTestsCodec(void); /// The core interface that each host language plugin must implement in /// platform_test integration tests. -@protocol HostIntegrationCoreApi +@protocol FLTHostIntegrationCoreApi /// A no-op function taking no arguments and returning no value, to sanity /// test basic calling. - (void)noopWithError:(FlutterError *_Nullable *_Nonnull)error; /// Returns the passed object, to test serialization and deserialization. /// /// @return `nil` only when `error != nil`. -- (nullable AllTypes *)echoAllTypes:(AllTypes *)everything - error:(FlutterError *_Nullable *_Nonnull)error; +- (nullable FLTAllTypes *)echoAllTypes:(FLTAllTypes *)everything + error:(FlutterError *_Nullable *_Nonnull)error; /// Returns an error, to test error handling. - (nullable id)throwErrorWithError:(FlutterError *_Nullable *_Nonnull)error; /// Returns an error from a void function, to test error handling. @@ -247,20 +333,96 @@ NSObject *GetCoreTestsCodec(void); /// @return `nil` only when `error != nil`. - (nullable NSArray *)echoList:(NSArray *)list error:(FlutterError *_Nullable *_Nonnull)error; -/// Returns the passed map, to test serialization and deserialization. +/// Returns the passed list, to test serialization and deserialization. /// /// @return `nil` only when `error != nil`. -- (nullable NSDictionary *)echoMap:(NSDictionary *)aMap +- (nullable NSArray *)echoEnumList:(NSArray *)enumList error:(FlutterError *_Nullable *_Nonnull)error; -/// Returns the passed map to test nested class serialization and deserialization. +/// Returns the passed list, to test serialization and deserialization. /// /// @return `nil` only when `error != nil`. -- (nullable AllClassesWrapper *)echoClassWrapper:(AllClassesWrapper *)wrapper - error:(FlutterError *_Nullable *_Nonnull)error; +- (nullable NSArray *)echoClassList: + (NSArray *)classList + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed list, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSArray *)echoNonNullEnumList:(NSArray *)enumList + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed list, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSArray *) + echoNonNullClassList:(NSArray *)classList + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSDictionary *)echoMap:(NSDictionary *)map + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSDictionary *) + echoStringMap:(NSDictionary *)stringMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSDictionary *) + echoIntMap:(NSDictionary *)intMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSDictionary *) + echoEnumMap:(NSDictionary *)enumMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSDictionary *) + echoClassMap:(NSDictionary *)classMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSDictionary *) + echoNonNullStringMap:(NSDictionary *)stringMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSDictionary *) + echoNonNullIntMap:(NSDictionary *)intMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSDictionary *) + echoNonNullEnumMap:(NSDictionary *)enumMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSDictionary *) + echoNonNullClassMap:(NSDictionary *)classMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed class to test nested class serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable FLTAllClassesWrapper *)echoClassWrapper:(FLTAllClassesWrapper *)wrapper + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed enum to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (FLTAnEnumBox *_Nullable)echoEnum:(FLTAnEnum)anEnum + error:(FlutterError *_Nullable *_Nonnull)error; /// Returns the passed enum to test serialization and deserialization. /// /// @return `nil` only when `error != nil`. -- (AnEnumBox *_Nullable)echoEnum:(AnEnum)anEnum error:(FlutterError *_Nullable *_Nonnull)error; +- (FLTAnotherEnumBox *_Nullable)echoAnotherEnum:(FLTAnotherEnum)anotherEnum + error:(FlutterError *_Nullable *_Nonnull)error; /// Returns the default string. /// /// @return `nil` only when `error != nil`. @@ -277,35 +439,35 @@ NSObject *GetCoreTestsCodec(void); - (nullable NSNumber *)echoRequiredInt:(NSInteger)anInt error:(FlutterError *_Nullable *_Nonnull)error; /// Returns the passed object, to test serialization and deserialization. -- (nullable AllNullableTypes *)echoAllNullableTypes:(nullable AllNullableTypes *)everything - error:(FlutterError *_Nullable *_Nonnull)error; +- (nullable FLTAllNullableTypes *)echoAllNullableTypes:(nullable FLTAllNullableTypes *)everything + error:(FlutterError *_Nullable *_Nonnull)error; /// Returns the passed object, to test serialization and deserialization. -- (nullable AllNullableTypesWithoutRecursion *) - echoAllNullableTypesWithoutRecursion:(nullable AllNullableTypesWithoutRecursion *)everything +- (nullable FLTAllNullableTypesWithoutRecursion *) + echoAllNullableTypesWithoutRecursion:(nullable FLTAllNullableTypesWithoutRecursion *)everything error:(FlutterError *_Nullable *_Nonnull)error; /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. -- (nullable NSString *)extractNestedNullableStringFrom:(AllClassesWrapper *)wrapper +- (nullable NSString *)extractNestedNullableStringFrom:(FLTAllClassesWrapper *)wrapper error:(FlutterError *_Nullable *_Nonnull)error; /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. /// /// @return `nil` only when `error != nil`. -- (nullable AllClassesWrapper *) +- (nullable FLTAllClassesWrapper *) createNestedObjectWithNullableString:(nullable NSString *)nullableString error:(FlutterError *_Nullable *_Nonnull)error; /// Returns passed in arguments of multiple types. /// /// @return `nil` only when `error != nil`. -- (nullable AllNullableTypes *)sendMultipleNullableTypesABool:(nullable NSNumber *)aNullableBool - anInt:(nullable NSNumber *)aNullableInt - aString:(nullable NSString *)aNullableString - error:(FlutterError *_Nullable *_Nonnull) - error; +- (nullable FLTAllNullableTypes *) + sendMultipleNullableTypesABool:(nullable NSNumber *)aNullableBool + anInt:(nullable NSNumber *)aNullableInt + aString:(nullable NSString *)aNullableString + error:(FlutterError *_Nullable *_Nonnull)error; /// Returns passed in arguments of multiple types. /// /// @return `nil` only when `error != nil`. -- (nullable AllNullableTypesWithoutRecursion *) +- (nullable FLTAllNullableTypesWithoutRecursion *) sendMultipleNullableTypesWithoutRecursionABool:(nullable NSNumber *)aNullableBool anInt:(nullable NSNumber *)aNullableInt aString:(nullable NSString *)aNullableString @@ -332,12 +494,62 @@ NSObject *GetCoreTestsCodec(void); /// Returns the passed list, to test serialization and deserialization. - (nullable NSArray *)echoNullableList:(nullable NSArray *)aNullableList error:(FlutterError *_Nullable *_Nonnull)error; -/// Returns the passed map, to test serialization and deserialization. -- (nullable NSDictionary *)echoNullableMap: - (nullable NSDictionary *)aNullableMap +/// Returns the passed list, to test serialization and deserialization. +- (nullable NSArray *)echoNullableEnumList: + (nullable NSArray *)enumList error:(FlutterError *_Nullable *_Nonnull)error; -- (AnEnumBox *_Nullable)echoNullableEnum:(nullable AnEnumBox *)anEnumBoxed - error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed list, to test serialization and deserialization. +- (nullable NSArray *) + echoNullableClassList:(nullable NSArray *)classList + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed list, to test serialization and deserialization. +- (nullable NSArray *) + echoNullableNonNullEnumList:(nullable NSArray *)enumList + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed list, to test serialization and deserialization. +- (nullable NSArray *) + echoNullableNonNullClassList:(nullable NSArray *)classList + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +- (nullable NSDictionary *)echoNullableMap:(nullable NSDictionary *)map + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +- (nullable NSDictionary *) + echoNullableStringMap:(nullable NSDictionary *)stringMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +- (nullable NSDictionary *) + echoNullableIntMap:(nullable NSDictionary *)intMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +- (nullable NSDictionary *) + echoNullableEnumMap:(nullable NSDictionary *)enumMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +- (nullable NSDictionary *) + echoNullableClassMap:(nullable NSDictionary *)classMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +- (nullable NSDictionary *) + echoNullableNonNullStringMap:(nullable NSDictionary *)stringMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +- (nullable NSDictionary *) + echoNullableNonNullIntMap:(nullable NSDictionary *)intMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +- (nullable NSDictionary *) + echoNullableNonNullEnumMap:(nullable NSDictionary *)enumMap + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map, to test serialization and deserialization. +- (nullable NSDictionary *) + echoNullableNonNullClassMap:(nullable NSDictionary *)classMap + error:(FlutterError *_Nullable *_Nonnull)error; +- (FLTAnEnumBox *_Nullable)echoNullableEnum:(nullable FLTAnEnumBox *)anEnumBoxed + error:(FlutterError *_Nullable *_Nonnull)error; +- (FLTAnotherEnumBox *_Nullable)echoAnotherNullableEnum: + (nullable FLTAnotherEnumBox *)anotherEnumBoxed + error:(FlutterError *_Nullable *_Nonnull)error; /// Returns passed in int. - (nullable NSNumber *)echoOptionalNullableInt:(nullable NSNumber *)aNullableInt error:(FlutterError *_Nullable *_Nonnull)error; @@ -369,13 +581,40 @@ NSObject *GetCoreTestsCodec(void); /// Returns the passed list, to test asynchronous serialization and deserialization. - (void)echoAsyncList:(NSArray *)list completion:(void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed list, to test asynchronous serialization and deserialization. +- (void)echoAsyncEnumList:(NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed list, to test asynchronous serialization and deserialization. +- (void)echoAsyncClassList:(NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; /// Returns the passed map, to test asynchronous serialization and deserialization. -- (void)echoAsyncMap:(NSDictionary *)aMap - completion:(void (^)(NSDictionary *_Nullable, - FlutterError *_Nullable))completion; +- (void)echoAsyncMap:(NSDictionary *)map + completion:(void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed map, to test asynchronous serialization and deserialization. +- (void)echoAsyncStringMap:(NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test asynchronous serialization and deserialization. +- (void)echoAsyncIntMap:(NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test asynchronous serialization and deserialization. +- (void)echoAsyncEnumMap:(NSDictionary *)enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test asynchronous serialization and deserialization. +- (void)echoAsyncClassMap:(NSDictionary *)classMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; /// Returns the passed enum, to test asynchronous serialization and deserialization. -- (void)echoAsyncEnum:(AnEnum)anEnum - completion:(void (^)(AnEnumBox *_Nullable, FlutterError *_Nullable))completion; +- (void)echoAsyncEnum:(FLTAnEnum)anEnum + completion:(void (^)(FLTAnEnumBox *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed enum, to test asynchronous serialization and deserialization. +- (void)echoAnotherAsyncEnum:(FLTAnotherEnum)anotherEnum + completion: + (void (^)(FLTAnotherEnumBox *_Nullable, FlutterError *_Nullable))completion; /// Responds with an error from an async function returning a value. - (void)throwAsyncErrorWithCompletion:(void (^)(id _Nullable, FlutterError *_Nullable))completion; /// Responds with an error from an async void function. @@ -384,19 +623,19 @@ NSObject *GetCoreTestsCodec(void); - (void)throwAsyncFlutterErrorWithCompletion:(void (^)(id _Nullable, FlutterError *_Nullable))completion; /// Returns the passed object, to test async serialization and deserialization. -- (void)echoAsyncAllTypes:(AllTypes *)everything - completion:(void (^)(AllTypes *_Nullable, FlutterError *_Nullable))completion; +- (void)echoAsyncAllTypes:(FLTAllTypes *)everything + completion:(void (^)(FLTAllTypes *_Nullable, FlutterError *_Nullable))completion; /// Returns the passed object, to test serialization and deserialization. -- (void)echoAsyncNullableAllNullableTypes:(nullable AllNullableTypes *)everything - completion:(void (^)(AllNullableTypes *_Nullable, +- (void)echoAsyncNullableAllNullableTypes:(nullable FLTAllNullableTypes *)everything + completion:(void (^)(FLTAllNullableTypes *_Nullable, FlutterError *_Nullable))completion; /// Returns the passed object, to test serialization and deserialization. - (void)echoAsyncNullableAllNullableTypesWithoutRecursion: - (nullable AllNullableTypesWithoutRecursion *)everything + (nullable FLTAllNullableTypesWithoutRecursion *)everything completion: - (void (^)( - AllNullableTypesWithoutRecursion *_Nullable, - FlutterError *_Nullable))completion; + (void (^)(FLTAllNullableTypesWithoutRecursion + *_Nullable, + FlutterError *_Nullable))completion; /// Returns passed in int asynchronously. - (void)echoAsyncNullableInt:(nullable NSNumber *)anInt completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion; @@ -419,39 +658,70 @@ NSObject *GetCoreTestsCodec(void); /// Returns the passed list, to test asynchronous serialization and deserialization. - (void)echoAsyncNullableList:(nullable NSArray *)list completion:(void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed list, to test asynchronous serialization and deserialization. +- (void)echoAsyncNullableEnumList:(nullable NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed list, to test asynchronous serialization and deserialization. +- (void)echoAsyncNullableClassList:(nullable NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; /// Returns the passed map, to test asynchronous serialization and deserialization. -- (void)echoAsyncNullableMap:(nullable NSDictionary *)aMap - completion:(void (^)(NSDictionary *_Nullable, +- (void)echoAsyncNullableMap:(nullable NSDictionary *)map + completion:(void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed map, to test asynchronous serialization and deserialization. +- (void)echoAsyncNullableStringMap:(nullable NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test asynchronous serialization and deserialization. +- (void)echoAsyncNullableIntMap:(nullable NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test asynchronous serialization and deserialization. +- (void)echoAsyncNullableEnumMap:(nullable NSDictionary *)enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test asynchronous serialization and deserialization. +- (void) + echoAsyncNullableClassMap:(nullable NSDictionary *)classMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; /// Returns the passed enum, to test asynchronous serialization and deserialization. -- (void)echoAsyncNullableEnum:(nullable AnEnumBox *)anEnumBoxed - completion:(void (^)(AnEnumBox *_Nullable, FlutterError *_Nullable))completion; +- (void)echoAsyncNullableEnum:(nullable FLTAnEnumBox *)anEnumBoxed + completion: + (void (^)(FLTAnEnumBox *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed enum, to test asynchronous serialization and deserialization. +- (void)echoAnotherAsyncNullableEnum:(nullable FLTAnotherEnumBox *)anotherEnumBoxed + completion:(void (^)(FLTAnotherEnumBox *_Nullable, + FlutterError *_Nullable))completion; - (void)callFlutterNoopWithCompletion:(void (^)(FlutterError *_Nullable))completion; - (void)callFlutterThrowErrorWithCompletion:(void (^)(id _Nullable, FlutterError *_Nullable))completion; - (void)callFlutterThrowErrorFromVoidWithCompletion:(void (^)(FlutterError *_Nullable))completion; -- (void)callFlutterEchoAllTypes:(AllTypes *)everything - completion:(void (^)(AllTypes *_Nullable, FlutterError *_Nullable))completion; -- (void)callFlutterEchoAllNullableTypes:(nullable AllNullableTypes *)everything - completion:(void (^)(AllNullableTypes *_Nullable, +- (void)callFlutterEchoAllTypes:(FLTAllTypes *)everything + completion: + (void (^)(FLTAllTypes *_Nullable, FlutterError *_Nullable))completion; +- (void)callFlutterEchoAllNullableTypes:(nullable FLTAllNullableTypes *)everything + completion:(void (^)(FLTAllNullableTypes *_Nullable, FlutterError *_Nullable))completion; - (void)callFlutterSendMultipleNullableTypesABool:(nullable NSNumber *)aNullableBool anInt:(nullable NSNumber *)aNullableInt aString:(nullable NSString *)aNullableString - completion:(void (^)(AllNullableTypes *_Nullable, + completion:(void (^)(FLTAllNullableTypes *_Nullable, FlutterError *_Nullable))completion; -- (void) - callFlutterEchoAllNullableTypesWithoutRecursion: - (nullable AllNullableTypesWithoutRecursion *)everything - completion: - (void (^)(AllNullableTypesWithoutRecursion *_Nullable, - FlutterError *_Nullable))completion; +- (void)callFlutterEchoAllNullableTypesWithoutRecursion: + (nullable FLTAllNullableTypesWithoutRecursion *)everything + completion: + (void (^)( + FLTAllNullableTypesWithoutRecursion *_Nullable, + FlutterError *_Nullable))completion; - (void) callFlutterSendMultipleNullableTypesWithoutRecursionABool:(nullable NSNumber *)aNullableBool anInt:(nullable NSNumber *)aNullableInt aString:(nullable NSString *)aNullableString completion: - (void (^)(AllNullableTypesWithoutRecursion + (void (^)(FLTAllNullableTypesWithoutRecursion *_Nullable, FlutterError *_Nullable)) completion; @@ -468,11 +738,54 @@ NSObject *GetCoreTestsCodec(void); FlutterError *_Nullable))completion; - (void)callFlutterEchoList:(NSArray *)list completion:(void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion; -- (void)callFlutterEchoMap:(NSDictionary *)aMap - completion:(void (^)(NSDictionary *_Nullable, - FlutterError *_Nullable))completion; -- (void)callFlutterEchoEnum:(AnEnum)anEnum - completion:(void (^)(AnEnumBox *_Nullable, FlutterError *_Nullable))completion; +- (void)callFlutterEchoEnumList:(NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoClassList:(NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNonNullEnumList:(NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNonNullClassList:(NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoMap:(NSDictionary *)map + completion: + (void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion; +- (void)callFlutterEchoStringMap:(NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoIntMap:(NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoEnumMap:(NSDictionary *)enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoClassMap:(NSDictionary *)classMap + completion: + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNonNullStringMap:(NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNonNullIntMap:(NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNonNullEnumMap:(NSDictionary *)enumMap + completion: + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void) + callFlutterEchoNonNullClassMap:(NSDictionary *)classMap + completion: + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoEnum:(FLTAnEnum)anEnum + completion:(void (^)(FLTAnEnumBox *_Nullable, FlutterError *_Nullable))completion; +- (void)callFlutterEchoAnotherEnum:(FLTAnotherEnum)anotherEnum + completion:(void (^)(FLTAnotherEnumBox *_Nullable, + FlutterError *_Nullable))completion; - (void)callFlutterEchoNullableBool:(nullable NSNumber *)aBool completion: (void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion; @@ -491,27 +804,80 @@ NSObject *GetCoreTestsCodec(void); - (void)callFlutterEchoNullableList:(nullable NSArray *)list completion: (void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion; -- (void)callFlutterEchoNullableMap:(nullable NSDictionary *)aMap - completion:(void (^)(NSDictionary *_Nullable, +- (void)callFlutterEchoNullableEnumList:(nullable NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNullableClassList:(nullable NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNullableNonNullEnumList:(nullable NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNullableNonNullClassList:(nullable NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNullableMap:(nullable NSDictionary *)map + completion:(void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion; -- (void)callFlutterEchoNullableEnum:(nullable AnEnumBox *)anEnumBoxed +- (void)callFlutterEchoNullableStringMap:(nullable NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNullableIntMap:(nullable NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNullableEnumMap: + (nullable NSDictionary *)enumMap + completion: + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void) + callFlutterEchoNullableClassMap: + (nullable NSDictionary *)classMap completion: - (void (^)(AnEnumBox *_Nullable, FlutterError *_Nullable))completion; + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNullableNonNullStringMap: + (nullable NSDictionary *)stringMap + completion: + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNullableNonNullIntMap:(nullable NSDictionary *)intMap + completion: + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNullableNonNullEnumMap: + (nullable NSDictionary *)enumMap + completion: + (void (^)( + NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNullableNonNullClassMap: + (nullable NSDictionary *)classMap + completion: + (void (^)(NSDictionary + *_Nullable, + FlutterError *_Nullable))completion; +- (void)callFlutterEchoNullableEnum:(nullable FLTAnEnumBox *)anEnumBoxed + completion: + (void (^)(FLTAnEnumBox *_Nullable, FlutterError *_Nullable))completion; +- (void)callFlutterEchoAnotherNullableEnum:(nullable FLTAnotherEnumBox *)anotherEnumBoxed + completion:(void (^)(FLTAnotherEnumBox *_Nullable, + FlutterError *_Nullable))completion; - (void)callFlutterSmallApiEchoString:(NSString *)aString completion: (void (^)(NSString *_Nullable, FlutterError *_Nullable))completion; @end -extern void SetUpHostIntegrationCoreApi(id binaryMessenger, - NSObject *_Nullable api); +extern void SetUpFLTHostIntegrationCoreApi(id binaryMessenger, + NSObject *_Nullable api); -extern void SetUpHostIntegrationCoreApiWithSuffix(id binaryMessenger, - NSObject *_Nullable api, - NSString *messageChannelSuffix); +extern void SetUpFLTHostIntegrationCoreApiWithSuffix( + id binaryMessenger, NSObject *_Nullable api, + NSString *messageChannelSuffix); /// The core interface that the Dart platform_test code implements for host /// integration tests to call into. -@interface FlutterIntegrationCoreApi : NSObject +@interface FLTFlutterIntegrationCoreApi : NSObject - (instancetype)initWithBinaryMessenger:(id)binaryMessenger; - (instancetype)initWithBinaryMessenger:(id)binaryMessenger messageChannelSuffix:(nullable NSString *)messageChannelSuffix; @@ -523,34 +889,35 @@ extern void SetUpHostIntegrationCoreApiWithSuffix(id bin /// Responds with an error from an async void function. - (void)throwErrorFromVoidWithCompletion:(void (^)(FlutterError *_Nullable))completion; /// Returns the passed object, to test serialization and deserialization. -- (void)echoAllTypes:(AllTypes *)everything - completion:(void (^)(AllTypes *_Nullable, FlutterError *_Nullable))completion; +- (void)echoAllTypes:(FLTAllTypes *)everything + completion:(void (^)(FLTAllTypes *_Nullable, FlutterError *_Nullable))completion; /// Returns the passed object, to test serialization and deserialization. -- (void)echoAllNullableTypes:(nullable AllNullableTypes *)everything +- (void)echoAllNullableTypes:(nullable FLTAllNullableTypes *)everything completion: - (void (^)(AllNullableTypes *_Nullable, FlutterError *_Nullable))completion; + (void (^)(FLTAllNullableTypes *_Nullable, FlutterError *_Nullable))completion; /// Returns passed in arguments of multiple types. /// /// Tests multiple-arity FlutterApi handling. - (void)sendMultipleNullableTypesABool:(nullable NSNumber *)aNullableBool anInt:(nullable NSNumber *)aNullableInt aString:(nullable NSString *)aNullableString - completion:(void (^)(AllNullableTypes *_Nullable, + completion:(void (^)(FLTAllNullableTypes *_Nullable, FlutterError *_Nullable))completion; /// Returns the passed object, to test serialization and deserialization. -- (void)echoAllNullableTypesWithoutRecursion:(nullable AllNullableTypesWithoutRecursion *)everything - completion:(void (^)(AllNullableTypesWithoutRecursion *_Nullable, - FlutterError *_Nullable))completion; +- (void) + echoAllNullableTypesWithoutRecursion:(nullable FLTAllNullableTypesWithoutRecursion *)everything + completion:(void (^)(FLTAllNullableTypesWithoutRecursion *_Nullable, + FlutterError *_Nullable))completion; /// Returns passed in arguments of multiple types. /// /// Tests multiple-arity FlutterApi handling. -- (void) - sendMultipleNullableTypesWithoutRecursionABool:(nullable NSNumber *)aNullableBool - anInt:(nullable NSNumber *)aNullableInt - aString:(nullable NSString *)aNullableString - completion: - (void (^)(AllNullableTypesWithoutRecursion *_Nullable, - FlutterError *_Nullable))completion; +- (void)sendMultipleNullableTypesWithoutRecursionABool:(nullable NSNumber *)aNullableBool + anInt:(nullable NSNumber *)aNullableInt + aString:(nullable NSString *)aNullableString + completion: + (void (^)( + FLTAllNullableTypesWithoutRecursion *_Nullable, + FlutterError *_Nullable))completion; /// Returns the passed boolean, to test serialization and deserialization. - (void)echoBool:(BOOL)aBool completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion; @@ -570,13 +937,63 @@ extern void SetUpHostIntegrationCoreApiWithSuffix(id bin /// Returns the passed list, to test serialization and deserialization. - (void)echoList:(NSArray *)list completion:(void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed list, to test serialization and deserialization. +- (void)echoEnumList:(NSArray *)enumList + completion: + (void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed list, to test serialization and deserialization. +- (void)echoClassList:(NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed list, to test serialization and deserialization. +- (void)echoNonNullEnumList:(NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed list, to test serialization and deserialization. +- (void)echoNonNullClassList:(NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoMap:(NSDictionary *)map + completion:(void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion; /// Returns the passed map, to test serialization and deserialization. -- (void)echoMap:(NSDictionary *)aMap - completion: - (void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion; +- (void)echoStringMap:(NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoIntMap:(NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoEnumMap:(NSDictionary *)enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoClassMap:(NSDictionary *)classMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoNonNullStringMap:(NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoNonNullIntMap:(NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoNonNullEnumMap:(NSDictionary *)enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoNonNullClassMap:(NSDictionary *)classMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed enum to test serialization and deserialization. +- (void)echoEnum:(FLTAnEnum)anEnum + completion:(void (^)(FLTAnEnumBox *_Nullable, FlutterError *_Nullable))completion; /// Returns the passed enum to test serialization and deserialization. -- (void)echoEnum:(AnEnum)anEnum - completion:(void (^)(AnEnumBox *_Nullable, FlutterError *_Nullable))completion; +- (void)echoAnotherEnum:(FLTAnotherEnum)anotherEnum + completion:(void (^)(FLTAnotherEnumBox *_Nullable, FlutterError *_Nullable))completion; /// Returns the passed boolean, to test serialization and deserialization. - (void)echoNullableBool:(nullable NSNumber *)aBool completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion; @@ -596,13 +1013,68 @@ extern void SetUpHostIntegrationCoreApiWithSuffix(id bin /// Returns the passed list, to test serialization and deserialization. - (void)echoNullableList:(nullable NSArray *)list completion:(void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed list, to test serialization and deserialization. +- (void)echoNullableEnumList:(nullable NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed list, to test serialization and deserialization. +- (void)echoNullableClassList:(nullable NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed list, to test serialization and deserialization. +- (void)echoNullableNonNullEnumList:(nullable NSArray *)enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed list, to test serialization and deserialization. +- (void)echoNullableNonNullClassList:(nullable NSArray *)classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion; /// Returns the passed map, to test serialization and deserialization. -- (void)echoNullableMap:(nullable NSDictionary *)aMap - completion:(void (^)(NSDictionary *_Nullable, - FlutterError *_Nullable))completion; +- (void)echoNullableMap:(nullable NSDictionary *)map + completion: + (void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoNullableStringMap:(nullable NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoNullableIntMap:(nullable NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoNullableEnumMap:(nullable NSDictionary *)enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoNullableClassMap:(nullable NSDictionary *)classMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoNullableNonNullStringMap:(nullable NSDictionary *)stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoNullableNonNullIntMap:(nullable NSDictionary *)intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoNullableNonNullEnumMap:(nullable NSDictionary *)enumMap + completion: + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed map, to test serialization and deserialization. +- (void)echoNullableNonNullClassMap: + (nullable NSDictionary *)classMap + completion: + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion; +/// Returns the passed enum to test serialization and deserialization. +- (void)echoNullableEnum:(nullable FLTAnEnumBox *)anEnumBoxed + completion:(void (^)(FLTAnEnumBox *_Nullable, FlutterError *_Nullable))completion; /// Returns the passed enum to test serialization and deserialization. -- (void)echoNullableEnum:(nullable AnEnumBox *)anEnumBoxed - completion:(void (^)(AnEnumBox *_Nullable, FlutterError *_Nullable))completion; +- (void)echoAnotherNullableEnum:(nullable FLTAnotherEnumBox *)anotherEnumBoxed + completion:(void (^)(FLTAnotherEnumBox *_Nullable, + FlutterError *_Nullable))completion; /// A no-op function taking no arguments and returning no value, to sanity /// test basic asynchronous calling. - (void)noopAsyncWithCompletion:(void (^)(FlutterError *_Nullable))completion; @@ -612,38 +1084,38 @@ extern void SetUpHostIntegrationCoreApiWithSuffix(id bin @end /// An API that can be implemented for minimal, compile-only tests. -@protocol HostTrivialApi +@protocol FLTHostTrivialApi - (void)noopWithError:(FlutterError *_Nullable *_Nonnull)error; @end -extern void SetUpHostTrivialApi(id binaryMessenger, - NSObject *_Nullable api); +extern void SetUpFLTHostTrivialApi(id binaryMessenger, + NSObject *_Nullable api); -extern void SetUpHostTrivialApiWithSuffix(id binaryMessenger, - NSObject *_Nullable api, - NSString *messageChannelSuffix); +extern void SetUpFLTHostTrivialApiWithSuffix(id binaryMessenger, + NSObject *_Nullable api, + NSString *messageChannelSuffix); /// A simple API implemented in some unit tests. -@protocol HostSmallApi +@protocol FLTHostSmallApi - (void)echoString:(NSString *)aString completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion; - (void)voidVoidWithCompletion:(void (^)(FlutterError *_Nullable))completion; @end -extern void SetUpHostSmallApi(id binaryMessenger, - NSObject *_Nullable api); +extern void SetUpFLTHostSmallApi(id binaryMessenger, + NSObject *_Nullable api); -extern void SetUpHostSmallApiWithSuffix(id binaryMessenger, - NSObject *_Nullable api, - NSString *messageChannelSuffix); +extern void SetUpFLTHostSmallApiWithSuffix(id binaryMessenger, + NSObject *_Nullable api, + NSString *messageChannelSuffix); /// A simple API called in some unit tests. -@interface FlutterSmallApi : NSObject +@interface FLTFlutterSmallApi : NSObject - (instancetype)initWithBinaryMessenger:(id)binaryMessenger; - (instancetype)initWithBinaryMessenger:(id)binaryMessenger messageChannelSuffix:(nullable NSString *)messageChannelSuffix; -- (void)echoWrappedList:(TestMessage *)msg - completion:(void (^)(TestMessage *_Nullable, FlutterError *_Nullable))completion; +- (void)echoWrappedList:(FLTTestMessage *)msg + completion:(void (^)(FLTTestMessage *_Nullable, FlutterError *_Nullable))completion; - (void)echoString:(NSString *)aString completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion; @end diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.m b/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.m index be3810ceae8d..2cc3da7877d8 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.m +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.m @@ -40,8 +40,8 @@ static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) { return (result == [NSNull null]) ? nil : result; } -@implementation AnEnumBox -- (instancetype)initWithValue:(AnEnum)value { +@implementation FLTAnEnumBox +- (instancetype)initWithValue:(FLTAnEnum)value { self = [super init]; if (self) { _value = value; @@ -50,37 +50,74 @@ - (instancetype)initWithValue:(AnEnum)value { } @end -@interface AllTypes () -+ (AllTypes *)fromList:(NSArray *)list; -+ (nullable AllTypes *)nullableFromList:(NSArray *)list; +@implementation FLTAnotherEnumBox +- (instancetype)initWithValue:(FLTAnotherEnum)value { + self = [super init]; + if (self) { + _value = value; + } + return self; +} +@end + +@interface FLTUnusedClass () ++ (FLTUnusedClass *)fromList:(NSArray *)list; ++ (nullable FLTUnusedClass *)nullableFromList:(NSArray *)list; - (NSArray *)toList; @end -@interface AllNullableTypes () -+ (AllNullableTypes *)fromList:(NSArray *)list; -+ (nullable AllNullableTypes *)nullableFromList:(NSArray *)list; +@interface FLTAllTypes () ++ (FLTAllTypes *)fromList:(NSArray *)list; ++ (nullable FLTAllTypes *)nullableFromList:(NSArray *)list; - (NSArray *)toList; @end -@interface AllNullableTypesWithoutRecursion () -+ (AllNullableTypesWithoutRecursion *)fromList:(NSArray *)list; -+ (nullable AllNullableTypesWithoutRecursion *)nullableFromList:(NSArray *)list; +@interface FLTAllNullableTypes () ++ (FLTAllNullableTypes *)fromList:(NSArray *)list; ++ (nullable FLTAllNullableTypes *)nullableFromList:(NSArray *)list; - (NSArray *)toList; @end -@interface AllClassesWrapper () -+ (AllClassesWrapper *)fromList:(NSArray *)list; -+ (nullable AllClassesWrapper *)nullableFromList:(NSArray *)list; +@interface FLTAllNullableTypesWithoutRecursion () ++ (FLTAllNullableTypesWithoutRecursion *)fromList:(NSArray *)list; ++ (nullable FLTAllNullableTypesWithoutRecursion *)nullableFromList:(NSArray *)list; - (NSArray *)toList; @end -@interface TestMessage () -+ (TestMessage *)fromList:(NSArray *)list; -+ (nullable TestMessage *)nullableFromList:(NSArray *)list; +@interface FLTAllClassesWrapper () ++ (FLTAllClassesWrapper *)fromList:(NSArray *)list; ++ (nullable FLTAllClassesWrapper *)nullableFromList:(NSArray *)list; - (NSArray *)toList; @end -@implementation AllTypes +@interface FLTTestMessage () ++ (FLTTestMessage *)fromList:(NSArray *)list; ++ (nullable FLTTestMessage *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + +@implementation FLTUnusedClass ++ (instancetype)makeWithAField:(nullable id)aField { + FLTUnusedClass *pigeonResult = [[FLTUnusedClass alloc] init]; + pigeonResult.aField = aField; + return pigeonResult; +} ++ (FLTUnusedClass *)fromList:(NSArray *)list { + FLTUnusedClass *pigeonResult = [[FLTUnusedClass alloc] init]; + pigeonResult.aField = GetNullableObjectAtIndex(list, 0); + return pigeonResult; +} ++ (nullable FLTUnusedClass *)nullableFromList:(NSArray *)list { + return (list) ? [FLTUnusedClass fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + self.aField ?: [NSNull null], + ]; +} +@end + +@implementation FLTAllTypes + (instancetype)makeWithABool:(BOOL)aBool anInt:(NSInteger)anInt anInt64:(NSInteger)anInt64 @@ -89,7 +126,8 @@ + (instancetype)makeWithABool:(BOOL)aBool a4ByteArray:(FlutterStandardTypedData *)a4ByteArray a8ByteArray:(FlutterStandardTypedData *)a8ByteArray aFloatArray:(FlutterStandardTypedData *)aFloatArray - anEnum:(AnEnum)anEnum + anEnum:(FLTAnEnum)anEnum + anotherEnum:(FLTAnotherEnum)anotherEnum aString:(NSString *)aString anObject:(id)anObject list:(NSArray *)list @@ -97,8 +135,18 @@ + (instancetype)makeWithABool:(BOOL)aBool intList:(NSArray *)intList doubleList:(NSArray *)doubleList boolList:(NSArray *)boolList - map:(NSDictionary *)map { - AllTypes *pigeonResult = [[AllTypes alloc] init]; + enumList:(NSArray *)enumList + objectList:(NSArray *)objectList + listList:(NSArray *> *)listList + mapList:(NSArray *> *)mapList + map:(NSDictionary *)map + stringMap:(NSDictionary *)stringMap + intMap:(NSDictionary *)intMap + enumMap:(NSDictionary *)enumMap + objectMap:(NSDictionary *)objectMap + listMap:(NSDictionary *> *)listMap + mapMap:(NSDictionary *> *)mapMap { + FLTAllTypes *pigeonResult = [[FLTAllTypes alloc] init]; pigeonResult.aBool = aBool; pigeonResult.anInt = anInt; pigeonResult.anInt64 = anInt64; @@ -108,6 +156,7 @@ + (instancetype)makeWithABool:(BOOL)aBool pigeonResult.a8ByteArray = a8ByteArray; pigeonResult.aFloatArray = aFloatArray; pigeonResult.anEnum = anEnum; + pigeonResult.anotherEnum = anotherEnum; pigeonResult.aString = aString; pigeonResult.anObject = anObject; pigeonResult.list = list; @@ -115,11 +164,21 @@ + (instancetype)makeWithABool:(BOOL)aBool pigeonResult.intList = intList; pigeonResult.doubleList = doubleList; pigeonResult.boolList = boolList; + pigeonResult.enumList = enumList; + pigeonResult.objectList = objectList; + pigeonResult.listList = listList; + pigeonResult.mapList = mapList; pigeonResult.map = map; + pigeonResult.stringMap = stringMap; + pigeonResult.intMap = intMap; + pigeonResult.enumMap = enumMap; + pigeonResult.objectMap = objectMap; + pigeonResult.listMap = listMap; + pigeonResult.mapMap = mapMap; return pigeonResult; } -+ (AllTypes *)fromList:(NSArray *)list { - AllTypes *pigeonResult = [[AllTypes alloc] init]; ++ (FLTAllTypes *)fromList:(NSArray *)list { + FLTAllTypes *pigeonResult = [[FLTAllTypes alloc] init]; pigeonResult.aBool = [GetNullableObjectAtIndex(list, 0) boolValue]; pigeonResult.anInt = [GetNullableObjectAtIndex(list, 1) integerValue]; pigeonResult.anInt64 = [GetNullableObjectAtIndex(list, 2) integerValue]; @@ -128,20 +187,32 @@ + (AllTypes *)fromList:(NSArray *)list { pigeonResult.a4ByteArray = GetNullableObjectAtIndex(list, 5); pigeonResult.a8ByteArray = GetNullableObjectAtIndex(list, 6); pigeonResult.aFloatArray = GetNullableObjectAtIndex(list, 7); - AnEnumBox *enumBox = GetNullableObjectAtIndex(list, 8); - pigeonResult.anEnum = enumBox.value; - pigeonResult.aString = GetNullableObjectAtIndex(list, 9); - pigeonResult.anObject = GetNullableObjectAtIndex(list, 10); - pigeonResult.list = GetNullableObjectAtIndex(list, 11); - pigeonResult.stringList = GetNullableObjectAtIndex(list, 12); - pigeonResult.intList = GetNullableObjectAtIndex(list, 13); - pigeonResult.doubleList = GetNullableObjectAtIndex(list, 14); - pigeonResult.boolList = GetNullableObjectAtIndex(list, 15); - pigeonResult.map = GetNullableObjectAtIndex(list, 16); + FLTAnEnumBox *boxedFLTAnEnum = GetNullableObjectAtIndex(list, 8); + pigeonResult.anEnum = boxedFLTAnEnum.value; + FLTAnotherEnumBox *boxedFLTAnotherEnum = GetNullableObjectAtIndex(list, 9); + pigeonResult.anotherEnum = boxedFLTAnotherEnum.value; + pigeonResult.aString = GetNullableObjectAtIndex(list, 10); + pigeonResult.anObject = GetNullableObjectAtIndex(list, 11); + pigeonResult.list = GetNullableObjectAtIndex(list, 12); + pigeonResult.stringList = GetNullableObjectAtIndex(list, 13); + pigeonResult.intList = GetNullableObjectAtIndex(list, 14); + pigeonResult.doubleList = GetNullableObjectAtIndex(list, 15); + pigeonResult.boolList = GetNullableObjectAtIndex(list, 16); + pigeonResult.enumList = GetNullableObjectAtIndex(list, 17); + pigeonResult.objectList = GetNullableObjectAtIndex(list, 18); + pigeonResult.listList = GetNullableObjectAtIndex(list, 19); + pigeonResult.mapList = GetNullableObjectAtIndex(list, 20); + pigeonResult.map = GetNullableObjectAtIndex(list, 21); + pigeonResult.stringMap = GetNullableObjectAtIndex(list, 22); + pigeonResult.intMap = GetNullableObjectAtIndex(list, 23); + pigeonResult.enumMap = GetNullableObjectAtIndex(list, 24); + pigeonResult.objectMap = GetNullableObjectAtIndex(list, 25); + pigeonResult.listMap = GetNullableObjectAtIndex(list, 26); + pigeonResult.mapMap = GetNullableObjectAtIndex(list, 27); return pigeonResult; } -+ (nullable AllTypes *)nullableFromList:(NSArray *)list { - return (list) ? [AllTypes fromList:list] : nil; ++ (nullable FLTAllTypes *)nullableFromList:(NSArray *)list { + return (list) ? [FLTAllTypes fromList:list] : nil; } - (NSArray *)toList { return @[ @@ -153,7 +224,8 @@ + (nullable AllTypes *)nullableFromList:(NSArray *)list { self.a4ByteArray ?: [NSNull null], self.a8ByteArray ?: [NSNull null], self.aFloatArray ?: [NSNull null], - [[AnEnumBox alloc] initWithValue:self.anEnum], + [[FLTAnEnumBox alloc] initWithValue:self.anEnum], + [[FLTAnotherEnumBox alloc] initWithValue:self.anotherEnum], self.aString ?: [NSNull null], self.anObject ?: [NSNull null], self.list ?: [NSNull null], @@ -161,36 +233,56 @@ + (nullable AllTypes *)nullableFromList:(NSArray *)list { self.intList ?: [NSNull null], self.doubleList ?: [NSNull null], self.boolList ?: [NSNull null], + self.enumList ?: [NSNull null], + self.objectList ?: [NSNull null], + self.listList ?: [NSNull null], + self.mapList ?: [NSNull null], self.map ?: [NSNull null], + self.stringMap ?: [NSNull null], + self.intMap ?: [NSNull null], + self.enumMap ?: [NSNull null], + self.objectMap ?: [NSNull null], + self.listMap ?: [NSNull null], + self.mapMap ?: [NSNull null], ]; } @end -@implementation AllNullableTypes -+ (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool - aNullableInt:(nullable NSNumber *)aNullableInt - aNullableInt64:(nullable NSNumber *)aNullableInt64 - aNullableDouble:(nullable NSNumber *)aNullableDouble - aNullableByteArray:(nullable FlutterStandardTypedData *)aNullableByteArray - aNullable4ByteArray:(nullable FlutterStandardTypedData *)aNullable4ByteArray - aNullable8ByteArray:(nullable FlutterStandardTypedData *)aNullable8ByteArray - aNullableFloatArray:(nullable FlutterStandardTypedData *)aNullableFloatArray - nullableNestedList:(nullable NSArray *> *)nullableNestedList - nullableMapWithAnnotations: - (nullable NSDictionary *)nullableMapWithAnnotations - nullableMapWithObject:(nullable NSDictionary *)nullableMapWithObject - aNullableEnum:(nullable AnEnumBox *)aNullableEnum - aNullableString:(nullable NSString *)aNullableString - aNullableObject:(nullable id)aNullableObject - allNullableTypes:(nullable AllNullableTypes *)allNullableTypes - list:(nullable NSArray *)list - stringList:(nullable NSArray *)stringList - intList:(nullable NSArray *)intList - doubleList:(nullable NSArray *)doubleList - boolList:(nullable NSArray *)boolList - nestedClassList:(nullable NSArray *)nestedClassList - map:(nullable NSDictionary *)map { - AllNullableTypes *pigeonResult = [[AllNullableTypes alloc] init]; +@implementation FLTAllNullableTypes ++ (instancetype) + makeWithANullableBool:(nullable NSNumber *)aNullableBool + aNullableInt:(nullable NSNumber *)aNullableInt + aNullableInt64:(nullable NSNumber *)aNullableInt64 + aNullableDouble:(nullable NSNumber *)aNullableDouble + aNullableByteArray:(nullable FlutterStandardTypedData *)aNullableByteArray + aNullable4ByteArray:(nullable FlutterStandardTypedData *)aNullable4ByteArray + aNullable8ByteArray:(nullable FlutterStandardTypedData *)aNullable8ByteArray + aNullableFloatArray:(nullable FlutterStandardTypedData *)aNullableFloatArray + aNullableEnum:(nullable FLTAnEnumBox *)aNullableEnum + anotherNullableEnum:(nullable FLTAnotherEnumBox *)anotherNullableEnum + aNullableString:(nullable NSString *)aNullableString + aNullableObject:(nullable id)aNullableObject + allNullableTypes:(nullable FLTAllNullableTypes *)allNullableTypes + list:(nullable NSArray *)list + stringList:(nullable NSArray *)stringList + intList:(nullable NSArray *)intList + doubleList:(nullable NSArray *)doubleList + boolList:(nullable NSArray *)boolList + enumList:(nullable NSArray *)enumList + objectList:(nullable NSArray *)objectList + listList:(nullable NSArray *> *)listList + mapList:(nullable NSArray *> *)mapList + recursiveClassList:(nullable NSArray *)recursiveClassList + map:(nullable NSDictionary *)map + stringMap:(nullable NSDictionary *)stringMap + intMap:(nullable NSDictionary *)intMap + enumMap:(nullable NSDictionary *)enumMap + objectMap:(nullable NSDictionary *)objectMap + listMap:(nullable NSDictionary *> *)listMap + mapMap:(nullable NSDictionary *> *)mapMap + recursiveClassMap: + (nullable NSDictionary *)recursiveClassMap { + FLTAllNullableTypes *pigeonResult = [[FLTAllNullableTypes alloc] init]; pigeonResult.aNullableBool = aNullableBool; pigeonResult.aNullableInt = aNullableInt; pigeonResult.aNullableInt64 = aNullableInt64; @@ -199,10 +291,8 @@ + (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool pigeonResult.aNullable4ByteArray = aNullable4ByteArray; pigeonResult.aNullable8ByteArray = aNullable8ByteArray; pigeonResult.aNullableFloatArray = aNullableFloatArray; - pigeonResult.nullableNestedList = nullableNestedList; - pigeonResult.nullableMapWithAnnotations = nullableMapWithAnnotations; - pigeonResult.nullableMapWithObject = nullableMapWithObject; pigeonResult.aNullableEnum = aNullableEnum; + pigeonResult.anotherNullableEnum = anotherNullableEnum; pigeonResult.aNullableString = aNullableString; pigeonResult.aNullableObject = aNullableObject; pigeonResult.allNullableTypes = allNullableTypes; @@ -211,12 +301,23 @@ + (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool pigeonResult.intList = intList; pigeonResult.doubleList = doubleList; pigeonResult.boolList = boolList; - pigeonResult.nestedClassList = nestedClassList; + pigeonResult.enumList = enumList; + pigeonResult.objectList = objectList; + pigeonResult.listList = listList; + pigeonResult.mapList = mapList; + pigeonResult.recursiveClassList = recursiveClassList; pigeonResult.map = map; + pigeonResult.stringMap = stringMap; + pigeonResult.intMap = intMap; + pigeonResult.enumMap = enumMap; + pigeonResult.objectMap = objectMap; + pigeonResult.listMap = listMap; + pigeonResult.mapMap = mapMap; + pigeonResult.recursiveClassMap = recursiveClassMap; return pigeonResult; } -+ (AllNullableTypes *)fromList:(NSArray *)list { - AllNullableTypes *pigeonResult = [[AllNullableTypes alloc] init]; ++ (FLTAllNullableTypes *)fromList:(NSArray *)list { + FLTAllNullableTypes *pigeonResult = [[FLTAllNullableTypes alloc] init]; pigeonResult.aNullableBool = GetNullableObjectAtIndex(list, 0); pigeonResult.aNullableInt = GetNullableObjectAtIndex(list, 1); pigeonResult.aNullableInt64 = GetNullableObjectAtIndex(list, 2); @@ -225,24 +326,33 @@ + (AllNullableTypes *)fromList:(NSArray *)list { pigeonResult.aNullable4ByteArray = GetNullableObjectAtIndex(list, 5); pigeonResult.aNullable8ByteArray = GetNullableObjectAtIndex(list, 6); pigeonResult.aNullableFloatArray = GetNullableObjectAtIndex(list, 7); - pigeonResult.nullableNestedList = GetNullableObjectAtIndex(list, 8); - pigeonResult.nullableMapWithAnnotations = GetNullableObjectAtIndex(list, 9); - pigeonResult.nullableMapWithObject = GetNullableObjectAtIndex(list, 10); - pigeonResult.aNullableEnum = GetNullableObjectAtIndex(list, 11); - pigeonResult.aNullableString = GetNullableObjectAtIndex(list, 12); - pigeonResult.aNullableObject = GetNullableObjectAtIndex(list, 13); - pigeonResult.allNullableTypes = GetNullableObjectAtIndex(list, 14); - pigeonResult.list = GetNullableObjectAtIndex(list, 15); - pigeonResult.stringList = GetNullableObjectAtIndex(list, 16); - pigeonResult.intList = GetNullableObjectAtIndex(list, 17); - pigeonResult.doubleList = GetNullableObjectAtIndex(list, 18); - pigeonResult.boolList = GetNullableObjectAtIndex(list, 19); - pigeonResult.nestedClassList = GetNullableObjectAtIndex(list, 20); - pigeonResult.map = GetNullableObjectAtIndex(list, 21); + pigeonResult.aNullableEnum = GetNullableObjectAtIndex(list, 8); + pigeonResult.anotherNullableEnum = GetNullableObjectAtIndex(list, 9); + pigeonResult.aNullableString = GetNullableObjectAtIndex(list, 10); + pigeonResult.aNullableObject = GetNullableObjectAtIndex(list, 11); + pigeonResult.allNullableTypes = GetNullableObjectAtIndex(list, 12); + pigeonResult.list = GetNullableObjectAtIndex(list, 13); + pigeonResult.stringList = GetNullableObjectAtIndex(list, 14); + pigeonResult.intList = GetNullableObjectAtIndex(list, 15); + pigeonResult.doubleList = GetNullableObjectAtIndex(list, 16); + pigeonResult.boolList = GetNullableObjectAtIndex(list, 17); + pigeonResult.enumList = GetNullableObjectAtIndex(list, 18); + pigeonResult.objectList = GetNullableObjectAtIndex(list, 19); + pigeonResult.listList = GetNullableObjectAtIndex(list, 20); + pigeonResult.mapList = GetNullableObjectAtIndex(list, 21); + pigeonResult.recursiveClassList = GetNullableObjectAtIndex(list, 22); + pigeonResult.map = GetNullableObjectAtIndex(list, 23); + pigeonResult.stringMap = GetNullableObjectAtIndex(list, 24); + pigeonResult.intMap = GetNullableObjectAtIndex(list, 25); + pigeonResult.enumMap = GetNullableObjectAtIndex(list, 26); + pigeonResult.objectMap = GetNullableObjectAtIndex(list, 27); + pigeonResult.listMap = GetNullableObjectAtIndex(list, 28); + pigeonResult.mapMap = GetNullableObjectAtIndex(list, 29); + pigeonResult.recursiveClassMap = GetNullableObjectAtIndex(list, 30); return pigeonResult; } -+ (nullable AllNullableTypes *)nullableFromList:(NSArray *)list { - return (list) ? [AllNullableTypes fromList:list] : nil; ++ (nullable FLTAllNullableTypes *)nullableFromList:(NSArray *)list { + return (list) ? [FLTAllNullableTypes fromList:list] : nil; } - (NSArray *)toList { return @[ @@ -254,10 +364,8 @@ + (nullable AllNullableTypes *)nullableFromList:(NSArray *)list { self.aNullable4ByteArray ?: [NSNull null], self.aNullable8ByteArray ?: [NSNull null], self.aNullableFloatArray ?: [NSNull null], - self.nullableNestedList ?: [NSNull null], - self.nullableMapWithAnnotations ?: [NSNull null], - self.nullableMapWithObject ?: [NSNull null], self.aNullableEnum ?: [NSNull null], + self.anotherNullableEnum ?: [NSNull null], self.aNullableString ?: [NSNull null], self.aNullableObject ?: [NSNull null], self.allNullableTypes ?: [NSNull null], @@ -266,35 +374,55 @@ + (nullable AllNullableTypes *)nullableFromList:(NSArray *)list { self.intList ?: [NSNull null], self.doubleList ?: [NSNull null], self.boolList ?: [NSNull null], - self.nestedClassList ?: [NSNull null], + self.enumList ?: [NSNull null], + self.objectList ?: [NSNull null], + self.listList ?: [NSNull null], + self.mapList ?: [NSNull null], + self.recursiveClassList ?: [NSNull null], self.map ?: [NSNull null], + self.stringMap ?: [NSNull null], + self.intMap ?: [NSNull null], + self.enumMap ?: [NSNull null], + self.objectMap ?: [NSNull null], + self.listMap ?: [NSNull null], + self.mapMap ?: [NSNull null], + self.recursiveClassMap ?: [NSNull null], ]; } @end -@implementation AllNullableTypesWithoutRecursion -+ (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool - aNullableInt:(nullable NSNumber *)aNullableInt - aNullableInt64:(nullable NSNumber *)aNullableInt64 - aNullableDouble:(nullable NSNumber *)aNullableDouble - aNullableByteArray:(nullable FlutterStandardTypedData *)aNullableByteArray - aNullable4ByteArray:(nullable FlutterStandardTypedData *)aNullable4ByteArray - aNullable8ByteArray:(nullable FlutterStandardTypedData *)aNullable8ByteArray - aNullableFloatArray:(nullable FlutterStandardTypedData *)aNullableFloatArray - nullableNestedList:(nullable NSArray *> *)nullableNestedList - nullableMapWithAnnotations: - (nullable NSDictionary *)nullableMapWithAnnotations - nullableMapWithObject:(nullable NSDictionary *)nullableMapWithObject - aNullableEnum:(nullable AnEnumBox *)aNullableEnum - aNullableString:(nullable NSString *)aNullableString - aNullableObject:(nullable id)aNullableObject - list:(nullable NSArray *)list - stringList:(nullable NSArray *)stringList - intList:(nullable NSArray *)intList - doubleList:(nullable NSArray *)doubleList - boolList:(nullable NSArray *)boolList - map:(nullable NSDictionary *)map { - AllNullableTypesWithoutRecursion *pigeonResult = [[AllNullableTypesWithoutRecursion alloc] init]; +@implementation FLTAllNullableTypesWithoutRecursion ++ (instancetype) + makeWithANullableBool:(nullable NSNumber *)aNullableBool + aNullableInt:(nullable NSNumber *)aNullableInt + aNullableInt64:(nullable NSNumber *)aNullableInt64 + aNullableDouble:(nullable NSNumber *)aNullableDouble + aNullableByteArray:(nullable FlutterStandardTypedData *)aNullableByteArray + aNullable4ByteArray:(nullable FlutterStandardTypedData *)aNullable4ByteArray + aNullable8ByteArray:(nullable FlutterStandardTypedData *)aNullable8ByteArray + aNullableFloatArray:(nullable FlutterStandardTypedData *)aNullableFloatArray + aNullableEnum:(nullable FLTAnEnumBox *)aNullableEnum + anotherNullableEnum:(nullable FLTAnotherEnumBox *)anotherNullableEnum + aNullableString:(nullable NSString *)aNullableString + aNullableObject:(nullable id)aNullableObject + list:(nullable NSArray *)list + stringList:(nullable NSArray *)stringList + intList:(nullable NSArray *)intList + doubleList:(nullable NSArray *)doubleList + boolList:(nullable NSArray *)boolList + enumList:(nullable NSArray *)enumList + objectList:(nullable NSArray *)objectList + listList:(nullable NSArray *> *)listList + mapList:(nullable NSArray *> *)mapList + map:(nullable NSDictionary *)map + stringMap:(nullable NSDictionary *)stringMap + intMap:(nullable NSDictionary *)intMap + enumMap:(nullable NSDictionary *)enumMap + objectMap:(nullable NSDictionary *)objectMap + listMap:(nullable NSDictionary *> *)listMap + mapMap:(nullable NSDictionary *> *)mapMap { + FLTAllNullableTypesWithoutRecursion *pigeonResult = + [[FLTAllNullableTypesWithoutRecursion alloc] init]; pigeonResult.aNullableBool = aNullableBool; pigeonResult.aNullableInt = aNullableInt; pigeonResult.aNullableInt64 = aNullableInt64; @@ -303,10 +431,8 @@ + (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool pigeonResult.aNullable4ByteArray = aNullable4ByteArray; pigeonResult.aNullable8ByteArray = aNullable8ByteArray; pigeonResult.aNullableFloatArray = aNullableFloatArray; - pigeonResult.nullableNestedList = nullableNestedList; - pigeonResult.nullableMapWithAnnotations = nullableMapWithAnnotations; - pigeonResult.nullableMapWithObject = nullableMapWithObject; pigeonResult.aNullableEnum = aNullableEnum; + pigeonResult.anotherNullableEnum = anotherNullableEnum; pigeonResult.aNullableString = aNullableString; pigeonResult.aNullableObject = aNullableObject; pigeonResult.list = list; @@ -314,11 +440,22 @@ + (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool pigeonResult.intList = intList; pigeonResult.doubleList = doubleList; pigeonResult.boolList = boolList; + pigeonResult.enumList = enumList; + pigeonResult.objectList = objectList; + pigeonResult.listList = listList; + pigeonResult.mapList = mapList; pigeonResult.map = map; + pigeonResult.stringMap = stringMap; + pigeonResult.intMap = intMap; + pigeonResult.enumMap = enumMap; + pigeonResult.objectMap = objectMap; + pigeonResult.listMap = listMap; + pigeonResult.mapMap = mapMap; return pigeonResult; } -+ (AllNullableTypesWithoutRecursion *)fromList:(NSArray *)list { - AllNullableTypesWithoutRecursion *pigeonResult = [[AllNullableTypesWithoutRecursion alloc] init]; ++ (FLTAllNullableTypesWithoutRecursion *)fromList:(NSArray *)list { + FLTAllNullableTypesWithoutRecursion *pigeonResult = + [[FLTAllNullableTypesWithoutRecursion alloc] init]; pigeonResult.aNullableBool = GetNullableObjectAtIndex(list, 0); pigeonResult.aNullableInt = GetNullableObjectAtIndex(list, 1); pigeonResult.aNullableInt64 = GetNullableObjectAtIndex(list, 2); @@ -327,22 +464,30 @@ + (AllNullableTypesWithoutRecursion *)fromList:(NSArray *)list { pigeonResult.aNullable4ByteArray = GetNullableObjectAtIndex(list, 5); pigeonResult.aNullable8ByteArray = GetNullableObjectAtIndex(list, 6); pigeonResult.aNullableFloatArray = GetNullableObjectAtIndex(list, 7); - pigeonResult.nullableNestedList = GetNullableObjectAtIndex(list, 8); - pigeonResult.nullableMapWithAnnotations = GetNullableObjectAtIndex(list, 9); - pigeonResult.nullableMapWithObject = GetNullableObjectAtIndex(list, 10); - pigeonResult.aNullableEnum = GetNullableObjectAtIndex(list, 11); - pigeonResult.aNullableString = GetNullableObjectAtIndex(list, 12); - pigeonResult.aNullableObject = GetNullableObjectAtIndex(list, 13); - pigeonResult.list = GetNullableObjectAtIndex(list, 14); - pigeonResult.stringList = GetNullableObjectAtIndex(list, 15); - pigeonResult.intList = GetNullableObjectAtIndex(list, 16); - pigeonResult.doubleList = GetNullableObjectAtIndex(list, 17); - pigeonResult.boolList = GetNullableObjectAtIndex(list, 18); - pigeonResult.map = GetNullableObjectAtIndex(list, 19); + pigeonResult.aNullableEnum = GetNullableObjectAtIndex(list, 8); + pigeonResult.anotherNullableEnum = GetNullableObjectAtIndex(list, 9); + pigeonResult.aNullableString = GetNullableObjectAtIndex(list, 10); + pigeonResult.aNullableObject = GetNullableObjectAtIndex(list, 11); + pigeonResult.list = GetNullableObjectAtIndex(list, 12); + pigeonResult.stringList = GetNullableObjectAtIndex(list, 13); + pigeonResult.intList = GetNullableObjectAtIndex(list, 14); + pigeonResult.doubleList = GetNullableObjectAtIndex(list, 15); + pigeonResult.boolList = GetNullableObjectAtIndex(list, 16); + pigeonResult.enumList = GetNullableObjectAtIndex(list, 17); + pigeonResult.objectList = GetNullableObjectAtIndex(list, 18); + pigeonResult.listList = GetNullableObjectAtIndex(list, 19); + pigeonResult.mapList = GetNullableObjectAtIndex(list, 20); + pigeonResult.map = GetNullableObjectAtIndex(list, 21); + pigeonResult.stringMap = GetNullableObjectAtIndex(list, 22); + pigeonResult.intMap = GetNullableObjectAtIndex(list, 23); + pigeonResult.enumMap = GetNullableObjectAtIndex(list, 24); + pigeonResult.objectMap = GetNullableObjectAtIndex(list, 25); + pigeonResult.listMap = GetNullableObjectAtIndex(list, 26); + pigeonResult.mapMap = GetNullableObjectAtIndex(list, 27); return pigeonResult; } -+ (nullable AllNullableTypesWithoutRecursion *)nullableFromList:(NSArray *)list { - return (list) ? [AllNullableTypesWithoutRecursion fromList:list] : nil; ++ (nullable FLTAllNullableTypesWithoutRecursion *)nullableFromList:(NSArray *)list { + return (list) ? [FLTAllNullableTypesWithoutRecursion fromList:list] : nil; } - (NSArray *)toList { return @[ @@ -354,10 +499,8 @@ + (nullable AllNullableTypesWithoutRecursion *)nullableFromList:(NSArray *)l self.aNullable4ByteArray ?: [NSNull null], self.aNullable8ByteArray ?: [NSNull null], self.aNullableFloatArray ?: [NSNull null], - self.nullableNestedList ?: [NSNull null], - self.nullableMapWithAnnotations ?: [NSNull null], - self.nullableMapWithObject ?: [NSNull null], self.aNullableEnum ?: [NSNull null], + self.anotherNullableEnum ?: [NSNull null], self.aNullableString ?: [NSNull null], self.aNullableObject ?: [NSNull null], self.list ?: [NSNull null], @@ -365,54 +508,84 @@ + (nullable AllNullableTypesWithoutRecursion *)nullableFromList:(NSArray *)l self.intList ?: [NSNull null], self.doubleList ?: [NSNull null], self.boolList ?: [NSNull null], + self.enumList ?: [NSNull null], + self.objectList ?: [NSNull null], + self.listList ?: [NSNull null], + self.mapList ?: [NSNull null], self.map ?: [NSNull null], + self.stringMap ?: [NSNull null], + self.intMap ?: [NSNull null], + self.enumMap ?: [NSNull null], + self.objectMap ?: [NSNull null], + self.listMap ?: [NSNull null], + self.mapMap ?: [NSNull null], ]; } @end -@implementation AllClassesWrapper -+ (instancetype)makeWithAllNullableTypes:(AllNullableTypes *)allNullableTypes - allNullableTypesWithoutRecursion: - (nullable AllNullableTypesWithoutRecursion *)allNullableTypesWithoutRecursion - allTypes:(nullable AllTypes *)allTypes { - AllClassesWrapper *pigeonResult = [[AllClassesWrapper alloc] init]; +@implementation FLTAllClassesWrapper ++ (instancetype) + makeWithAllNullableTypes:(FLTAllNullableTypes *)allNullableTypes + allNullableTypesWithoutRecursion: + (nullable FLTAllNullableTypesWithoutRecursion *)allNullableTypesWithoutRecursion + allTypes:(nullable FLTAllTypes *)allTypes + classList:(NSArray *)classList + nullableClassList: + (nullable NSArray *)nullableClassList + classMap:(NSDictionary *)classMap + nullableClassMap: + (nullable NSDictionary *) + nullableClassMap { + FLTAllClassesWrapper *pigeonResult = [[FLTAllClassesWrapper alloc] init]; pigeonResult.allNullableTypes = allNullableTypes; pigeonResult.allNullableTypesWithoutRecursion = allNullableTypesWithoutRecursion; pigeonResult.allTypes = allTypes; + pigeonResult.classList = classList; + pigeonResult.nullableClassList = nullableClassList; + pigeonResult.classMap = classMap; + pigeonResult.nullableClassMap = nullableClassMap; return pigeonResult; } -+ (AllClassesWrapper *)fromList:(NSArray *)list { - AllClassesWrapper *pigeonResult = [[AllClassesWrapper alloc] init]; ++ (FLTAllClassesWrapper *)fromList:(NSArray *)list { + FLTAllClassesWrapper *pigeonResult = [[FLTAllClassesWrapper alloc] init]; pigeonResult.allNullableTypes = GetNullableObjectAtIndex(list, 0); pigeonResult.allNullableTypesWithoutRecursion = GetNullableObjectAtIndex(list, 1); pigeonResult.allTypes = GetNullableObjectAtIndex(list, 2); + pigeonResult.classList = GetNullableObjectAtIndex(list, 3); + pigeonResult.nullableClassList = GetNullableObjectAtIndex(list, 4); + pigeonResult.classMap = GetNullableObjectAtIndex(list, 5); + pigeonResult.nullableClassMap = GetNullableObjectAtIndex(list, 6); return pigeonResult; } -+ (nullable AllClassesWrapper *)nullableFromList:(NSArray *)list { - return (list) ? [AllClassesWrapper fromList:list] : nil; ++ (nullable FLTAllClassesWrapper *)nullableFromList:(NSArray *)list { + return (list) ? [FLTAllClassesWrapper fromList:list] : nil; } - (NSArray *)toList { return @[ self.allNullableTypes ?: [NSNull null], self.allNullableTypesWithoutRecursion ?: [NSNull null], self.allTypes ?: [NSNull null], + self.classList ?: [NSNull null], + self.nullableClassList ?: [NSNull null], + self.classMap ?: [NSNull null], + self.nullableClassMap ?: [NSNull null], ]; } @end -@implementation TestMessage +@implementation FLTTestMessage + (instancetype)makeWithTestList:(nullable NSArray *)testList { - TestMessage *pigeonResult = [[TestMessage alloc] init]; + FLTTestMessage *pigeonResult = [[FLTTestMessage alloc] init]; pigeonResult.testList = testList; return pigeonResult; } -+ (TestMessage *)fromList:(NSArray *)list { - TestMessage *pigeonResult = [[TestMessage alloc] init]; ++ (FLTTestMessage *)fromList:(NSArray *)list { + FLTTestMessage *pigeonResult = [[FLTTestMessage alloc] init]; pigeonResult.testList = GetNullableObjectAtIndex(list, 0); return pigeonResult; } -+ (nullable TestMessage *)nullableFromList:(NSArray *)list { - return (list) ? [TestMessage fromList:list] : nil; ++ (nullable FLTTestMessage *)nullableFromList:(NSArray *)list { + return (list) ? [FLTTestMessage fromList:list] : nil; } - (NSArray *)toList { return @[ @@ -421,90 +594,105 @@ + (nullable TestMessage *)nullableFromList:(NSArray *)list { } @end -@interface CoreTestsPigeonCodecReader : FlutterStandardReader +@interface FLTCoreTestsPigeonCodecReader : FlutterStandardReader @end -@implementation CoreTestsPigeonCodecReader +@implementation FLTCoreTestsPigeonCodecReader - (nullable id)readValueOfType:(UInt8)type { switch (type) { - case 129: - return [AllTypes fromList:[self readValue]]; - case 130: - return [AllNullableTypes fromList:[self readValue]]; - case 131: - return [AllNullableTypesWithoutRecursion fromList:[self readValue]]; - case 132: - return [AllClassesWrapper fromList:[self readValue]]; - case 133: - return [TestMessage fromList:[self readValue]]; - case 134: { + case 129: { NSNumber *enumAsNumber = [self readValue]; return enumAsNumber == nil ? nil - : [[AnEnumBox alloc] initWithValue:[enumAsNumber integerValue]]; + : [[FLTAnEnumBox alloc] initWithValue:[enumAsNumber integerValue]]; } + case 130: { + NSNumber *enumAsNumber = [self readValue]; + return enumAsNumber == nil + ? nil + : [[FLTAnotherEnumBox alloc] initWithValue:[enumAsNumber integerValue]]; + } + case 131: + return [FLTUnusedClass fromList:[self readValue]]; + case 132: + return [FLTAllTypes fromList:[self readValue]]; + case 133: + return [FLTAllNullableTypes fromList:[self readValue]]; + case 134: + return [FLTAllNullableTypesWithoutRecursion fromList:[self readValue]]; + case 135: + return [FLTAllClassesWrapper fromList:[self readValue]]; + case 136: + return [FLTTestMessage fromList:[self readValue]]; default: return [super readValueOfType:type]; } } @end -@interface CoreTestsPigeonCodecWriter : FlutterStandardWriter +@interface FLTCoreTestsPigeonCodecWriter : FlutterStandardWriter @end -@implementation CoreTestsPigeonCodecWriter +@implementation FLTCoreTestsPigeonCodecWriter - (void)writeValue:(id)value { - if ([value isKindOfClass:[AllTypes class]]) { + if ([value isKindOfClass:[FLTAnEnumBox class]]) { + FLTAnEnumBox *box = (FLTAnEnumBox *)value; [self writeByte:129]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[AllNullableTypes class]]) { + [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; + } else if ([value isKindOfClass:[FLTAnotherEnumBox class]]) { + FLTAnotherEnumBox *box = (FLTAnotherEnumBox *)value; [self writeByte:130]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[AllNullableTypesWithoutRecursion class]]) { + [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; + } else if ([value isKindOfClass:[FLTUnusedClass class]]) { [self writeByte:131]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[AllClassesWrapper class]]) { + } else if ([value isKindOfClass:[FLTAllTypes class]]) { [self writeByte:132]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[TestMessage class]]) { + } else if ([value isKindOfClass:[FLTAllNullableTypes class]]) { [self writeByte:133]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[AnEnumBox class]]) { - AnEnumBox *box = (AnEnumBox *)value; + } else if ([value isKindOfClass:[FLTAllNullableTypesWithoutRecursion class]]) { [self writeByte:134]; - [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FLTAllClassesWrapper class]]) { + [self writeByte:135]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FLTTestMessage class]]) { + [self writeByte:136]; + [self writeValue:[value toList]]; } else { [super writeValue:value]; } } @end -@interface CoreTestsPigeonCodecReaderWriter : FlutterStandardReaderWriter +@interface FLTCoreTestsPigeonCodecReaderWriter : FlutterStandardReaderWriter @end -@implementation CoreTestsPigeonCodecReaderWriter +@implementation FLTCoreTestsPigeonCodecReaderWriter - (FlutterStandardWriter *)writerWithData:(NSMutableData *)data { - return [[CoreTestsPigeonCodecWriter alloc] initWithData:data]; + return [[FLTCoreTestsPigeonCodecWriter alloc] initWithData:data]; } - (FlutterStandardReader *)readerWithData:(NSData *)data { - return [[CoreTestsPigeonCodecReader alloc] initWithData:data]; + return [[FLTCoreTestsPigeonCodecReader alloc] initWithData:data]; } @end -NSObject *GetCoreTestsCodec(void) { +NSObject *FLTGetCoreTestsCodec(void) { static FlutterStandardMessageCodec *sSharedObject = nil; static dispatch_once_t sPred = 0; dispatch_once(&sPred, ^{ - CoreTestsPigeonCodecReaderWriter *readerWriter = - [[CoreTestsPigeonCodecReaderWriter alloc] init]; + FLTCoreTestsPigeonCodecReaderWriter *readerWriter = + [[FLTCoreTestsPigeonCodecReaderWriter alloc] init]; sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter]; }); return sSharedObject; } -void SetUpHostIntegrationCoreApi(id binaryMessenger, - NSObject *api) { - SetUpHostIntegrationCoreApiWithSuffix(binaryMessenger, api, @""); +void SetUpFLTHostIntegrationCoreApi(id binaryMessenger, + NSObject *api) { + SetUpFLTHostIntegrationCoreApiWithSuffix(binaryMessenger, api, @""); } -void SetUpHostIntegrationCoreApiWithSuffix(id binaryMessenger, - NSObject *api, - NSString *messageChannelSuffix) { +void SetUpFLTHostIntegrationCoreApiWithSuffix(id binaryMessenger, + NSObject *api, + NSString *messageChannelSuffix) { messageChannelSuffix = messageChannelSuffix.length > 0 ? [NSString stringWithFormat:@".%@", messageChannelSuffix] : @""; @@ -517,10 +705,10 @@ void SetUpHostIntegrationCoreApiWithSuffix(id binaryMess @"HostIntegrationCoreApi.noop", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(noopWithError:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(noopWithError:)", + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(noopWithError:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { FlutterError *error; @@ -539,17 +727,17 @@ void SetUpHostIntegrationCoreApiWithSuffix(id binaryMess @"HostIntegrationCoreApi.echoAllTypes", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { NSCAssert( [api respondsToSelector:@selector(echoAllTypes:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoAllTypes:error:)", + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoAllTypes:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - AllTypes *arg_everything = GetNullableObjectAtIndex(args, 0); + FLTAllTypes *arg_everything = GetNullableObjectAtIndex(args, 0); FlutterError *error; - AllTypes *output = [api echoAllTypes:arg_everything error:&error]; + FLTAllTypes *output = [api echoAllTypes:arg_everything error:&error]; callback(wrapResult(output, error)); }]; } else { @@ -564,11 +752,11 @@ void SetUpHostIntegrationCoreApiWithSuffix(id binaryMess @"HostIntegrationCoreApi.throwError", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { NSCAssert( [api respondsToSelector:@selector(throwErrorWithError:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(throwErrorWithError:)", + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(throwErrorWithError:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { FlutterError *error; @@ -587,10 +775,10 @@ void SetUpHostIntegrationCoreApiWithSuffix(id binaryMess @"HostIntegrationCoreApi.throwErrorFromVoid", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(throwErrorFromVoidWithError:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " @"@selector(throwErrorFromVoidWithError:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { @@ -610,10 +798,10 @@ void SetUpHostIntegrationCoreApiWithSuffix(id binaryMess @"HostIntegrationCoreApi.throwFlutterError", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(throwFlutterErrorWithError:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " @"@selector(throwFlutterErrorWithError:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { @@ -633,10 +821,10 @@ void SetUpHostIntegrationCoreApiWithSuffix(id binaryMess @"HostIntegrationCoreApi.echoInt", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(echoInt:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoInt:error:)", + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoInt:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; @@ -657,11 +845,12 @@ void SetUpHostIntegrationCoreApiWithSuffix(id binaryMess @"HostIntegrationCoreApi.echoDouble", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoDouble:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoDouble:error:)", - api); + NSCAssert( + [api respondsToSelector:@selector(echoDouble:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoDouble:error:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; double arg_aDouble = [GetNullableObjectAtIndex(args, 0) doubleValue]; @@ -681,10 +870,10 @@ void SetUpHostIntegrationCoreApiWithSuffix(id binaryMess @"HostIntegrationCoreApi.echoBool", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(echoBool:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoBool:error:)", + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoBool:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; @@ -705,11 +894,12 @@ void SetUpHostIntegrationCoreApiWithSuffix(id binaryMess @"HostIntegrationCoreApi.echoString", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoString:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoString:error:)", - api); + NSCAssert( + [api respondsToSelector:@selector(echoString:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoString:error:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; NSString *arg_aString = GetNullableObjectAtIndex(args, 0); @@ -729,11 +919,11 @@ void SetUpHostIntegrationCoreApiWithSuffix(id binaryMess @"HostIntegrationCoreApi.echoUint8List", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { NSCAssert( [api respondsToSelector:@selector(echoUint8List:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoUint8List:error:)", + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoUint8List:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; @@ -754,11 +944,12 @@ void SetUpHostIntegrationCoreApiWithSuffix(id binaryMess @"HostIntegrationCoreApi.echoObject", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoObject:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoObject:error:)", - api); + NSCAssert( + [api respondsToSelector:@selector(echoObject:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoObject:error:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; id arg_anObject = GetNullableObjectAtIndex(args, 0); @@ -778,10 +969,10 @@ void SetUpHostIntegrationCoreApiWithSuffix(id binaryMess @"HostIntegrationCoreApi.echoList", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(echoList:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoList:error:)", + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoList:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; @@ -794,1990 +985,4544 @@ void SetUpHostIntegrationCoreApiWithSuffix(id binaryMess [channel setMessageHandler:nil]; } } - /// Returns the passed map, to test serialization and deserialization. + /// Returns the passed list, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoMap", + @"HostIntegrationCoreApi.echoEnumList", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoMap:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoMap:error:)", - api); + NSCAssert( + [api respondsToSelector:@selector(echoEnumList:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoEnumList:error:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSDictionary *arg_aMap = GetNullableObjectAtIndex(args, 0); + NSArray *arg_enumList = GetNullableObjectAtIndex(args, 0); FlutterError *error; - NSDictionary *output = [api echoMap:arg_aMap error:&error]; + NSArray *output = [api echoEnumList:arg_enumList error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed map to test nested class serialization and deserialization. + /// Returns the passed list, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoClassWrapper", + @"HostIntegrationCoreApi.echoClassList", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { NSCAssert( - [api respondsToSelector:@selector(echoClassWrapper:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoClassWrapper:error:)", + [api respondsToSelector:@selector(echoClassList:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoClassList:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - AllClassesWrapper *arg_wrapper = GetNullableObjectAtIndex(args, 0); + NSArray *arg_classList = GetNullableObjectAtIndex(args, 0); FlutterError *error; - AllClassesWrapper *output = [api echoClassWrapper:arg_wrapper error:&error]; + NSArray *output = [api echoClassList:arg_classList error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed enum to test serialization and deserialization. + /// Returns the passed list, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoEnum", + @"HostIntegrationCoreApi.echoNonNullEnumList", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoEnum:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoEnum:error:)", + NSCAssert([api respondsToSelector:@selector(echoNonNullEnumList:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNonNullEnumList:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - AnEnumBox *enumBox = GetNullableObjectAtIndex(args, 0); - AnEnum arg_anEnum = enumBox.value; + NSArray *arg_enumList = GetNullableObjectAtIndex(args, 0); FlutterError *error; - AnEnumBox *output = [api echoEnum:arg_anEnum error:&error]; + NSArray *output = [api echoNonNullEnumList:arg_enumList error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the default string. + /// Returns the passed list, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoNamedDefaultString", + @"HostIntegrationCoreApi.echoNonNullClassList", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoNamedDefaultString:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoNamedDefaultString:error:)", + NSCAssert([api respondsToSelector:@selector(echoNonNullClassList:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNonNullClassList:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSString *arg_aString = GetNullableObjectAtIndex(args, 0); + NSArray *arg_classList = GetNullableObjectAtIndex(args, 0); FlutterError *error; - NSString *output = [api echoNamedDefaultString:arg_aString error:&error]; + NSArray *output = [api echoNonNullClassList:arg_classList + error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns passed in double. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoOptionalDefaultDouble", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoMap", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoOptionalDefaultDouble:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoOptionalDefaultDouble:error:)", + NSCAssert([api respondsToSelector:@selector(echoMap:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - double arg_aDouble = [GetNullableObjectAtIndex(args, 0) doubleValue]; + NSDictionary *arg_map = GetNullableObjectAtIndex(args, 0); FlutterError *error; - NSNumber *output = [api echoOptionalDefaultDouble:arg_aDouble error:&error]; + NSDictionary *output = [api echoMap:arg_map error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns passed in int. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoRequiredInt", + @"HostIntegrationCoreApi.echoStringMap", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { NSCAssert( - [api respondsToSelector:@selector(echoRequiredInt:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoRequiredInt:error:)", + [api respondsToSelector:@selector(echoStringMap:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoStringMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSInteger arg_anInt = [GetNullableObjectAtIndex(args, 0) integerValue]; + NSDictionary *arg_stringMap = GetNullableObjectAtIndex(args, 0); FlutterError *error; - NSNumber *output = [api echoRequiredInt:arg_anInt error:&error]; + NSDictionary *output = [api echoStringMap:arg_stringMap + error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed object, to test serialization and deserialization. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAllNullableTypes", + @"HostIntegrationCoreApi.echoIntMap", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAllNullableTypes:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAllNullableTypes:error:)", - api); + NSCAssert( + [api respondsToSelector:@selector(echoIntMap:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoIntMap:error:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - AllNullableTypes *arg_everything = GetNullableObjectAtIndex(args, 0); + NSDictionary *arg_intMap = GetNullableObjectAtIndex(args, 0); FlutterError *error; - AllNullableTypes *output = [api echoAllNullableTypes:arg_everything error:&error]; + NSDictionary *output = [api echoIntMap:arg_intMap error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed object, to test serialization and deserialization. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - [NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAllNullableTypesWithoutRecursion", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoEnumMap", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAllNullableTypesWithoutRecursion:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAllNullableTypesWithoutRecursion:error:)", - api); + NSCAssert( + [api respondsToSelector:@selector(echoEnumMap:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoEnumMap:error:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - AllNullableTypesWithoutRecursion *arg_everything = GetNullableObjectAtIndex(args, 0); + NSDictionary *arg_enumMap = + GetNullableObjectAtIndex(args, 0); FlutterError *error; - AllNullableTypesWithoutRecursion *output = - [api echoAllNullableTypesWithoutRecursion:arg_everything error:&error]; + NSDictionary *output = [api echoEnumMap:arg_enumMap + error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the inner `aString` value from the wrapped object, to test - /// sending of nested objects. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.extractNestedNullableString", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoClassMap", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(extractNestedNullableStringFrom:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(extractNestedNullableStringFrom:error:)", - api); + NSCAssert( + [api respondsToSelector:@selector(echoClassMap:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoClassMap:error:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - AllClassesWrapper *arg_wrapper = GetNullableObjectAtIndex(args, 0); + NSDictionary *arg_classMap = + GetNullableObjectAtIndex(args, 0); FlutterError *error; - NSString *output = [api extractNestedNullableStringFrom:arg_wrapper error:&error]; + NSDictionary *output = [api echoClassMap:arg_classMap + error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the inner `aString` value from the wrapped object, to test - /// sending of nested objects. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.createNestedNullableString", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoNonNullStringMap", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(createNestedObjectWithNullableString:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(createNestedObjectWithNullableString:error:)", + NSCAssert([api respondsToSelector:@selector(echoNonNullStringMap:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNonNullStringMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSString *arg_nullableString = GetNullableObjectAtIndex(args, 0); + NSDictionary *arg_stringMap = GetNullableObjectAtIndex(args, 0); FlutterError *error; - AllClassesWrapper *output = [api createNestedObjectWithNullableString:arg_nullableString - error:&error]; + NSDictionary *output = [api echoNonNullStringMap:arg_stringMap + error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns passed in arguments of multiple types. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.sendMultipleNullableTypes", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoNonNullIntMap", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(sendMultipleNullableTypesABool: - anInt:aString:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(sendMultipleNullableTypesABool:anInt:aString:error:)", + NSCAssert([api respondsToSelector:@selector(echoNonNullIntMap:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNonNullIntMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0); - NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 1); - NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 2); + NSDictionary *arg_intMap = GetNullableObjectAtIndex(args, 0); FlutterError *error; - AllNullableTypes *output = [api sendMultipleNullableTypesABool:arg_aNullableBool - anInt:arg_aNullableInt - aString:arg_aNullableString - error:&error]; + NSDictionary *output = [api echoNonNullIntMap:arg_intMap + error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns passed in arguments of multiple types. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat: - @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoNonNullEnumMap", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector - (sendMultipleNullableTypesWithoutRecursionABool:anInt:aString:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(sendMultipleNullableTypesWithoutRecursionABool:anInt:aString:error:)", + NSCAssert([api respondsToSelector:@selector(echoNonNullEnumMap:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNonNullEnumMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0); - NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 1); - NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 2); + NSDictionary *arg_enumMap = + GetNullableObjectAtIndex(args, 0); FlutterError *error; - AllNullableTypesWithoutRecursion *output = - [api sendMultipleNullableTypesWithoutRecursionABool:arg_aNullableBool - anInt:arg_aNullableInt - aString:arg_aNullableString - error:&error]; + NSDictionary *output = [api echoNonNullEnumMap:arg_enumMap + error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns passed in int. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoNullableInt", + @"HostIntegrationCoreApi.echoNonNullClassMap", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert( - [api respondsToSelector:@selector(echoNullableInt:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoNullableInt:error:)", - api); + NSCAssert([api respondsToSelector:@selector(echoNonNullClassMap:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNonNullClassMap:error:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 0); + NSDictionary *arg_classMap = + GetNullableObjectAtIndex(args, 0); FlutterError *error; - NSNumber *output = [api echoNullableInt:arg_aNullableInt error:&error]; + NSDictionary *output = + [api echoNonNullClassMap:arg_classMap error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns passed in double. + /// Returns the passed class to test nested class serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoNullableDouble", + @"HostIntegrationCoreApi.echoClassWrapper", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoNullableDouble:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoNullableDouble:error:)", + NSCAssert([api respondsToSelector:@selector(echoClassWrapper:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoClassWrapper:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSNumber *arg_aNullableDouble = GetNullableObjectAtIndex(args, 0); + FLTAllClassesWrapper *arg_wrapper = GetNullableObjectAtIndex(args, 0); FlutterError *error; - NSNumber *output = [api echoNullableDouble:arg_aNullableDouble error:&error]; + FLTAllClassesWrapper *output = [api echoClassWrapper:arg_wrapper error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed in boolean. + /// Returns the passed enum to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoNullableBool", + @"HostIntegrationCoreApi.echoEnum", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert( - [api respondsToSelector:@selector(echoNullableBool:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoNullableBool:error:)", - api); + NSCAssert([api respondsToSelector:@selector(echoEnum:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoEnum:error:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0); + FLTAnEnumBox *boxedFLTAnEnum = GetNullableObjectAtIndex(args, 0); + FLTAnEnum arg_anEnum = boxedFLTAnEnum.value; FlutterError *error; - NSNumber *output = [api echoNullableBool:arg_aNullableBool error:&error]; + FLTAnEnumBox *output = [api echoEnum:arg_anEnum error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed in string. + /// Returns the passed enum to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoNullableString", + @"HostIntegrationCoreApi.echoAnotherEnum", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoNullableString:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoNullableString:error:)", + NSCAssert([api respondsToSelector:@selector(echoAnotherEnum:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAnotherEnum:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 0); + FLTAnotherEnumBox *boxedFLTAnotherEnum = GetNullableObjectAtIndex(args, 0); + FLTAnotherEnum arg_anotherEnum = boxedFLTAnotherEnum.value; FlutterError *error; - NSString *output = [api echoNullableString:arg_aNullableString error:&error]; + FLTAnotherEnumBox *output = [api echoAnotherEnum:arg_anotherEnum error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed in Uint8List. + /// Returns the default string. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoNullableUint8List", + @"HostIntegrationCoreApi.echoNamedDefaultString", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoNullableUint8List:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoNullableUint8List:error:)", + NSCAssert([api respondsToSelector:@selector(echoNamedDefaultString:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNamedDefaultString:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FlutterStandardTypedData *arg_aNullableUint8List = GetNullableObjectAtIndex(args, 0); + NSString *arg_aString = GetNullableObjectAtIndex(args, 0); FlutterError *error; - FlutterStandardTypedData *output = [api echoNullableUint8List:arg_aNullableUint8List - error:&error]; + NSString *output = [api echoNamedDefaultString:arg_aString error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed in generic Object. + /// Returns passed in double. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoNullableObject", - messageChannelSuffix] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoOptionalDefaultDouble", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoNullableObject:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoNullableObject:error:)", + NSCAssert([api respondsToSelector:@selector(echoOptionalDefaultDouble:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoOptionalDefaultDouble:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - id arg_aNullableObject = GetNullableObjectAtIndex(args, 0); + double arg_aDouble = [GetNullableObjectAtIndex(args, 0) doubleValue]; FlutterError *error; - id output = [api echoNullableObject:arg_aNullableObject error:&error]; + NSNumber *output = [api echoOptionalDefaultDouble:arg_aDouble error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed list, to test serialization and deserialization. + /// Returns passed in int. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoNullableList", + @"HostIntegrationCoreApi.echoRequiredInt", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert( - [api respondsToSelector:@selector(echoNullableList:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoNullableList:error:)", - api); + NSCAssert([api respondsToSelector:@selector(echoRequiredInt:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoRequiredInt:error:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSArray *arg_aNullableList = GetNullableObjectAtIndex(args, 0); + NSInteger arg_anInt = [GetNullableObjectAtIndex(args, 0) integerValue]; FlutterError *error; - NSArray *output = [api echoNullableList:arg_aNullableList error:&error]; + NSNumber *output = [api echoRequiredInt:arg_anInt error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed map, to test serialization and deserialization. + /// Returns the passed object, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoNullableMap", + @"HostIntegrationCoreApi.echoAllNullableTypes", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert( - [api respondsToSelector:@selector(echoNullableMap:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoNullableMap:error:)", - api); + NSCAssert([api respondsToSelector:@selector(echoAllNullableTypes:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAllNullableTypes:error:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSDictionary *arg_aNullableMap = GetNullableObjectAtIndex(args, 0); + FLTAllNullableTypes *arg_everything = GetNullableObjectAtIndex(args, 0); FlutterError *error; - NSDictionary *output = [api echoNullableMap:arg_aNullableMap error:&error]; + FLTAllNullableTypes *output = [api echoAllNullableTypes:arg_everything error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed object, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoNullableEnum", - messageChannelSuffix] + initWithName: + [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAllNullableTypesWithoutRecursion", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert( - [api respondsToSelector:@selector(echoNullableEnum:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoNullableEnum:error:)", - api); + NSCAssert([api respondsToSelector:@selector(echoAllNullableTypesWithoutRecursion:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAllNullableTypesWithoutRecursion:error:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - AnEnumBox *arg_anEnum = GetNullableObjectAtIndex(args, 0); + FLTAllNullableTypesWithoutRecursion *arg_everything = GetNullableObjectAtIndex(args, 0); FlutterError *error; - AnEnumBox *output = [api echoNullableEnum:arg_anEnum error:&error]; + FLTAllNullableTypesWithoutRecursion *output = + [api echoAllNullableTypesWithoutRecursion:arg_everything error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns passed in int. + /// Returns the inner `aString` value from the wrapped object, to test + /// sending of nested objects. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoOptionalNullableInt", + @"HostIntegrationCoreApi.extractNestedNullableString", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoOptionalNullableInt:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoOptionalNullableInt:error:)", + NSCAssert([api respondsToSelector:@selector(extractNestedNullableStringFrom:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(extractNestedNullableStringFrom:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 0); + FLTAllClassesWrapper *arg_wrapper = GetNullableObjectAtIndex(args, 0); FlutterError *error; - NSNumber *output = [api echoOptionalNullableInt:arg_aNullableInt error:&error]; + NSString *output = [api extractNestedNullableStringFrom:arg_wrapper error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed in string. + /// Returns the inner `aString` value from the wrapped object, to test + /// sending of nested objects. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoNamedNullableString", + @"HostIntegrationCoreApi.createNestedNullableString", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoNamedNullableString:error:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoNamedNullableString:error:)", + NSCAssert([api respondsToSelector:@selector(createNestedObjectWithNullableString:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(createNestedObjectWithNullableString:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 0); + NSString *arg_nullableString = GetNullableObjectAtIndex(args, 0); FlutterError *error; - NSString *output = [api echoNamedNullableString:arg_aNullableString error:&error]; + FLTAllClassesWrapper *output = [api createNestedObjectWithNullableString:arg_nullableString + error:&error]; callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// A no-op function taking no arguments and returning no value, to sanity - /// test basic asynchronous calling. + /// Returns passed in arguments of multiple types. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.noopAsync", - messageChannelSuffix] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.sendMultipleNullableTypes", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert( - [api respondsToSelector:@selector(noopAsyncWithCompletion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(noopAsyncWithCompletion:)", - api); + NSCAssert([api respondsToSelector:@selector(sendMultipleNullableTypesABool: + anInt:aString:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(sendMultipleNullableTypesABool:anInt:aString:error:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - [api noopAsyncWithCompletion:^(FlutterError *_Nullable error) { - callback(wrapResult(nil, error)); - }]; + NSArray *args = message; + NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0); + NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 1); + NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 2); + FlutterError *error; + FLTAllNullableTypes *output = [api sendMultipleNullableTypesABool:arg_aNullableBool + anInt:arg_aNullableInt + aString:arg_aNullableString + error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns passed in int asynchronously. + /// Returns passed in arguments of multiple types. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncInt", - messageChannelSuffix] + initWithName:[NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert( - [api respondsToSelector:@selector(echoAsyncInt:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoAsyncInt:completion:)", - api); + NSCAssert([api respondsToSelector:@selector + (sendMultipleNullableTypesWithoutRecursionABool:anInt:aString:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(sendMultipleNullableTypesWithoutRecursionABool:anInt:aString:error:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSInteger arg_anInt = [GetNullableObjectAtIndex(args, 0) integerValue]; - [api echoAsyncInt:arg_anInt - completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0); + NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 1); + NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 2); + FlutterError *error; + FLTAllNullableTypesWithoutRecursion *output = + [api sendMultipleNullableTypesWithoutRecursionABool:arg_aNullableBool + anInt:arg_aNullableInt + aString:arg_aNullableString + error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns passed in double asynchronously. + /// Returns passed in int. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncDouble", + @"HostIntegrationCoreApi.echoNullableInt", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncDouble:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncDouble:completion:)", + NSCAssert([api respondsToSelector:@selector(echoNullableInt:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNullableInt:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - double arg_aDouble = [GetNullableObjectAtIndex(args, 0) doubleValue]; - [api echoAsyncDouble:arg_aDouble - completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSNumber *output = [api echoNullableInt:arg_aNullableInt error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed in boolean asynchronously. + /// Returns passed in double. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncBool", + @"HostIntegrationCoreApi.echoNullableDouble", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncBool:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncBool:completion:)", + NSCAssert([api respondsToSelector:@selector(echoNullableDouble:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNullableDouble:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - BOOL arg_aBool = [GetNullableObjectAtIndex(args, 0) boolValue]; - [api echoAsyncBool:arg_aBool - completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSNumber *arg_aNullableDouble = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSNumber *output = [api echoNullableDouble:arg_aNullableDouble error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed string asynchronously. + /// Returns the passed in boolean. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncString", + @"HostIntegrationCoreApi.echoNullableBool", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncString:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncString:completion:)", + NSCAssert([api respondsToSelector:@selector(echoNullableBool:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNullableBool:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSString *arg_aString = GetNullableObjectAtIndex(args, 0); - [api echoAsyncString:arg_aString - completion:^(NSString *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSNumber *output = [api echoNullableBool:arg_aNullableBool error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed in Uint8List asynchronously. + /// Returns the passed in string. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncUint8List", + @"HostIntegrationCoreApi.echoNullableString", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncUint8List:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncUint8List:completion:)", + NSCAssert([api respondsToSelector:@selector(echoNullableString:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNullableString:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FlutterStandardTypedData *arg_aUint8List = GetNullableObjectAtIndex(args, 0); - [api echoAsyncUint8List:arg_aUint8List - completion:^(FlutterStandardTypedData *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSString *output = [api echoNullableString:arg_aNullableString error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed in generic Object asynchronously. + /// Returns the passed in Uint8List. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncObject", + @"HostIntegrationCoreApi.echoNullableUint8List", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncObject:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncObject:completion:)", + NSCAssert([api respondsToSelector:@selector(echoNullableUint8List:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNullableUint8List:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - id arg_anObject = GetNullableObjectAtIndex(args, 0); - [api echoAsyncObject:arg_anObject - completion:^(id _Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + FlutterStandardTypedData *arg_aNullableUint8List = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + FlutterStandardTypedData *output = [api echoNullableUint8List:arg_aNullableUint8List + error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed list, to test asynchronous serialization and deserialization. + /// Returns the passed in generic Object. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncList", + @"HostIntegrationCoreApi.echoNullableObject", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncList:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncList:completion:)", + NSCAssert([api respondsToSelector:@selector(echoNullableObject:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNullableObject:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSArray *arg_list = GetNullableObjectAtIndex(args, 0); - [api echoAsyncList:arg_list - completion:^(NSArray *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + id arg_aNullableObject = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + id output = [api echoNullableObject:arg_aNullableObject error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed map, to test asynchronous serialization and deserialization. + /// Returns the passed list, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncMap", + @"HostIntegrationCoreApi.echoNullableList", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert( - [api respondsToSelector:@selector(echoAsyncMap:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoAsyncMap:completion:)", - api); + NSCAssert([api respondsToSelector:@selector(echoNullableList:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNullableList:error:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSDictionary *arg_aMap = GetNullableObjectAtIndex(args, 0); - [api echoAsyncMap:arg_aMap - completion:^(NSDictionary *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSArray *arg_aNullableList = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSArray *output = [api echoNullableList:arg_aNullableList error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed enum, to test asynchronous serialization and deserialization. + /// Returns the passed list, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncEnum", + @"HostIntegrationCoreApi.echoNullableEnumList", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncEnum:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncEnum:completion:)", + NSCAssert([api respondsToSelector:@selector(echoNullableEnumList:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNullableEnumList:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - AnEnumBox *enumBox = GetNullableObjectAtIndex(args, 0); - AnEnum arg_anEnum = enumBox.value; - [api echoAsyncEnum:arg_anEnum - completion:^(AnEnumBox *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSArray *arg_enumList = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSArray *output = [api echoNullableEnumList:arg_enumList error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Responds with an error from an async function returning a value. + /// Returns the passed list, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.throwAsyncError", + @"HostIntegrationCoreApi.echoNullableClassList", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(throwAsyncErrorWithCompletion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(throwAsyncErrorWithCompletion:)", + NSCAssert([api respondsToSelector:@selector(echoNullableClassList:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNullableClassList:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - [api throwAsyncErrorWithCompletion:^(id _Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSArray *args = message; + NSArray *arg_classList = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSArray *output = [api echoNullableClassList:arg_classList + error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Responds with an error from an async void function. + /// Returns the passed list, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.throwAsyncErrorFromVoid", + @"HostIntegrationCoreApi.echoNullableNonNullEnumList", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(throwAsyncErrorFromVoidWithCompletion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(throwAsyncErrorFromVoidWithCompletion:)", + NSCAssert([api respondsToSelector:@selector(echoNullableNonNullEnumList:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNullableNonNullEnumList:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - [api throwAsyncErrorFromVoidWithCompletion:^(FlutterError *_Nullable error) { - callback(wrapResult(nil, error)); - }]; + NSArray *args = message; + NSArray *arg_enumList = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSArray *output = [api echoNullableNonNullEnumList:arg_enumList + error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Responds with a Flutter error from an async function returning a value. + /// Returns the passed list, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.throwAsyncFlutterError", - messageChannelSuffix] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoNullableNonNullClassList", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(throwAsyncFlutterErrorWithCompletion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(throwAsyncFlutterErrorWithCompletion:)", + NSCAssert([api respondsToSelector:@selector(echoNullableNonNullClassList:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNullableNonNullClassList:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - [api throwAsyncFlutterErrorWithCompletion:^(id _Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSArray *args = message; + NSArray *arg_classList = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSArray *output = [api echoNullableNonNullClassList:arg_classList + error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed object, to test async serialization and deserialization. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncAllTypes", + @"HostIntegrationCoreApi.echoNullableMap", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncAllTypes:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncAllTypes:completion:)", + NSCAssert([api respondsToSelector:@selector(echoNullableMap:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNullableMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - AllTypes *arg_everything = GetNullableObjectAtIndex(args, 0); - [api echoAsyncAllTypes:arg_everything - completion:^(AllTypes *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_map = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSDictionary *output = [api echoNullableMap:arg_map error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed object, to test serialization and deserialization. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString stringWithFormat: - @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncNullableAllNullableTypes", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoNullableStringMap", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncNullableAllNullableTypes:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncNullableAllNullableTypes:completion:)", + NSCAssert([api respondsToSelector:@selector(echoNullableStringMap:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNullableStringMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - AllNullableTypes *arg_everything = GetNullableObjectAtIndex(args, 0); - [api echoAsyncNullableAllNullableTypes:arg_everything - completion:^(AllNullableTypes *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_stringMap = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSDictionary *output = [api echoNullableStringMap:arg_stringMap + error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed object, to test serialization and deserialization. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi." - @"echoAsyncNullableAllNullableTypesWithoutRecursion", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoNullableIntMap", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector - (echoAsyncNullableAllNullableTypesWithoutRecursion:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncNullableAllNullableTypesWithoutRecursion:completion:)", + NSCAssert([api respondsToSelector:@selector(echoNullableIntMap:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNullableIntMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - AllNullableTypesWithoutRecursion *arg_everything = GetNullableObjectAtIndex(args, 0); - [api echoAsyncNullableAllNullableTypesWithoutRecursion:arg_everything - completion:^(AllNullableTypesWithoutRecursion - *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_intMap = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSDictionary *output = [api echoNullableIntMap:arg_intMap + error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns passed in int asynchronously. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncNullableInt", + @"HostIntegrationCoreApi.echoNullableEnumMap", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncNullableInt:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncNullableInt:completion:)", + NSCAssert([api respondsToSelector:@selector(echoNullableEnumMap:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNullableEnumMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSNumber *arg_anInt = GetNullableObjectAtIndex(args, 0); - [api echoAsyncNullableInt:arg_anInt - completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_enumMap = + GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSDictionary *output = [api echoNullableEnumMap:arg_enumMap + error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns passed in double asynchronously. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncNullableDouble", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoNullableClassMap", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncNullableDouble:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncNullableDouble:completion:)", + NSCAssert([api respondsToSelector:@selector(echoNullableClassMap:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNullableClassMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSNumber *arg_aDouble = GetNullableObjectAtIndex(args, 0); - [api echoAsyncNullableDouble:arg_aDouble - completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_classMap = + GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSDictionary *output = + [api echoNullableClassMap:arg_classMap error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed in boolean asynchronously. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncNullableBool", - messageChannelSuffix] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoNullableNonNullStringMap", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncNullableBool:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncNullableBool:completion:)", + NSCAssert([api respondsToSelector:@selector(echoNullableNonNullStringMap:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNullableNonNullStringMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSNumber *arg_aBool = GetNullableObjectAtIndex(args, 0); - [api echoAsyncNullableBool:arg_aBool - completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_stringMap = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSDictionary *output = + [api echoNullableNonNullStringMap:arg_stringMap error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed string asynchronously. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncNullableString", + @"HostIntegrationCoreApi.echoNullableNonNullIntMap", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncNullableString:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncNullableString:completion:)", + NSCAssert([api respondsToSelector:@selector(echoNullableNonNullIntMap:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNullableNonNullIntMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSString *arg_aString = GetNullableObjectAtIndex(args, 0); - [api echoAsyncNullableString:arg_aString - completion:^(NSString *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_intMap = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSDictionary *output = [api echoNullableNonNullIntMap:arg_intMap + error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed in Uint8List asynchronously. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncNullableUint8List", + @"HostIntegrationCoreApi.echoNullableNonNullEnumMap", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncNullableUint8List:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncNullableUint8List:completion:)", + NSCAssert([api respondsToSelector:@selector(echoNullableNonNullEnumMap:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNullableNonNullEnumMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FlutterStandardTypedData *arg_aUint8List = GetNullableObjectAtIndex(args, 0); - [api echoAsyncNullableUint8List:arg_aUint8List - completion:^(FlutterStandardTypedData *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_enumMap = + GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSDictionary *output = + [api echoNullableNonNullEnumMap:arg_enumMap error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed in generic Object asynchronously. + /// Returns the passed map, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncNullableObject", + @"HostIntegrationCoreApi.echoNullableNonNullClassMap", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncNullableObject:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncNullableObject:completion:)", + NSCAssert([api respondsToSelector:@selector(echoNullableNonNullClassMap:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNullableNonNullClassMap:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - id arg_anObject = GetNullableObjectAtIndex(args, 0); - [api echoAsyncNullableObject:arg_anObject - completion:^(id _Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_classMap = + GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSDictionary *output = + [api echoNullableNonNullClassMap:arg_classMap error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed list, to test asynchronous serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncNullableList", + @"HostIntegrationCoreApi.echoNullableEnum", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncNullableList:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncNullableList:completion:)", + NSCAssert([api respondsToSelector:@selector(echoNullableEnum:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNullableEnum:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSArray *arg_list = GetNullableObjectAtIndex(args, 0); - [api echoAsyncNullableList:arg_list - completion:^(NSArray *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + FLTAnEnumBox *arg_anEnum = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + FLTAnEnumBox *output = [api echoNullableEnum:arg_anEnum error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed map, to test asynchronous serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncNullableMap", - messageChannelSuffix] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAnotherNullableEnum", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncNullableMap:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncNullableMap:completion:)", + NSCAssert([api respondsToSelector:@selector(echoAnotherNullableEnum:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAnotherNullableEnum:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSDictionary *arg_aMap = GetNullableObjectAtIndex(args, 0); - [api echoAsyncNullableMap:arg_aMap - completion:^(NSDictionary *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + FLTAnotherEnumBox *arg_anotherEnum = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + FLTAnotherEnumBox *output = [api echoAnotherNullableEnum:arg_anotherEnum error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } - /// Returns the passed enum, to test asynchronous serialization and deserialization. + /// Returns passed in int. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.echoAsyncNullableEnum", - messageChannelSuffix] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoOptionalNullableInt", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(echoAsyncNullableEnum:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(echoAsyncNullableEnum:completion:)", + NSCAssert([api respondsToSelector:@selector(echoOptionalNullableInt:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoOptionalNullableInt:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - AnEnumBox *arg_anEnum = GetNullableObjectAtIndex(args, 0); - [api echoAsyncNullableEnum:arg_anEnum - completion:^(AnEnumBox *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSNumber *output = [api echoOptionalNullableInt:arg_aNullableInt error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed in string. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterNoop", - messageChannelSuffix] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoNamedNullableString", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterNoopWithCompletion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterNoopWithCompletion:)", + NSCAssert([api respondsToSelector:@selector(echoNamedNullableString:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoNamedNullableString:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - [api callFlutterNoopWithCompletion:^(FlutterError *_Nullable error) { - callback(wrapResult(nil, error)); - }]; + NSArray *args = message; + NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSString *output = [api echoNamedNullableString:arg_aNullableString error:&error]; + callback(wrapResult(output, error)); }]; } else { [channel setMessageHandler:nil]; } } + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic asynchronous calling. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterThrowError", + @"HostIntegrationCoreApi.noopAsync", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterThrowErrorWithCompletion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterThrowErrorWithCompletion:)", + NSCAssert([api respondsToSelector:@selector(noopAsyncWithCompletion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(noopAsyncWithCompletion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - [api callFlutterThrowErrorWithCompletion:^(id _Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); + [api noopAsyncWithCompletion:^(FlutterError *_Nullable error) { + callback(wrapResult(nil, error)); }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns passed in int asynchronously. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - [NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterThrowErrorFromVoid", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncInt", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterThrowErrorFromVoidWithCompletion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterThrowErrorFromVoidWithCompletion:)", + NSCAssert([api respondsToSelector:@selector(echoAsyncInt:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncInt:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - [api callFlutterThrowErrorFromVoidWithCompletion:^(FlutterError *_Nullable error) { - callback(wrapResult(nil, error)); - }]; + NSArray *args = message; + NSInteger arg_anInt = [GetNullableObjectAtIndex(args, 0) integerValue]; + [api echoAsyncInt:arg_anInt + completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns passed in double asynchronously. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoAllTypes", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncDouble", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoAllTypes:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoAllTypes:completion:)", + NSCAssert([api respondsToSelector:@selector(echoAsyncDouble:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncDouble:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - AllTypes *arg_everything = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoAllTypes:arg_everything - completion:^(AllTypes *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + double arg_aDouble = [GetNullableObjectAtIndex(args, 0) doubleValue]; + [api echoAsyncDouble:arg_aDouble + completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed in boolean asynchronously. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - [NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoAllNullableTypes", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncBool", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoAllNullableTypes:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoAllNullableTypes:completion:)", + NSCAssert([api respondsToSelector:@selector(echoAsyncBool:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncBool:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - AllNullableTypes *arg_everything = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoAllNullableTypes:arg_everything - completion:^(AllNullableTypes *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + BOOL arg_aBool = [GetNullableObjectAtIndex(args, 0) boolValue]; + [api echoAsyncBool:arg_aBool + completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed string asynchronously. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - [NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterSendMultipleNullableTypes", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncString", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector - (callFlutterSendMultipleNullableTypesABool:anInt:aString:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterSendMultipleNullableTypesABool:anInt:aString:completion:)", + NSCAssert([api respondsToSelector:@selector(echoAsyncString:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncString:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0); - NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 1); - NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 2); - [api callFlutterSendMultipleNullableTypesABool:arg_aNullableBool - anInt:arg_aNullableInt - aString:arg_aNullableString - completion:^(AllNullableTypes *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSString *arg_aString = GetNullableObjectAtIndex(args, 0); + [api echoAsyncString:arg_aString + completion:^(NSString *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed in Uint8List asynchronously. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi." - @"callFlutterEchoAllNullableTypesWithoutRecursion", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncUint8List", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector - (callFlutterEchoAllNullableTypesWithoutRecursion:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoAllNullableTypesWithoutRecursion:completion:)", + NSCAssert([api respondsToSelector:@selector(echoAsyncUint8List:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncUint8List:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - AllNullableTypesWithoutRecursion *arg_everything = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoAllNullableTypesWithoutRecursion:arg_everything - completion:^(AllNullableTypesWithoutRecursion - *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + FlutterStandardTypedData *arg_aUint8List = GetNullableObjectAtIndex(args, 0); + [api echoAsyncUint8List:arg_aUint8List + completion:^(FlutterStandardTypedData *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed in generic Object asynchronously. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - [NSString stringWithFormat: - @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - @"callFlutterSendMultipleNullableTypesWithoutRecursion", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncObject", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert( - [api respondsToSelector:@selector - (callFlutterSendMultipleNullableTypesWithoutRecursionABool: - anInt:aString:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterSendMultipleNullableTypesWithoutRecursionABool:anInt:aString:" - @"completion:)", - api); + NSCAssert([api respondsToSelector:@selector(echoAsyncObject:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncObject:completion:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0); - NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 1); - NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 2); - [api callFlutterSendMultipleNullableTypesWithoutRecursionABool:arg_aNullableBool - anInt:arg_aNullableInt - aString:arg_aNullableString - completion:^( - AllNullableTypesWithoutRecursion - *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + id arg_anObject = GetNullableObjectAtIndex(args, 0); + [api echoAsyncObject:arg_anObject + completion:^(id _Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed list, to test asynchronous serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoBool", + @"HostIntegrationCoreApi.echoAsyncList", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoBool:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoBool:completion:)", + NSCAssert([api respondsToSelector:@selector(echoAsyncList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncList:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - BOOL arg_aBool = [GetNullableObjectAtIndex(args, 0) boolValue]; - [api callFlutterEchoBool:arg_aBool - completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSArray *arg_list = GetNullableObjectAtIndex(args, 0); + [api echoAsyncList:arg_list + completion:^(NSArray *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed list, to test asynchronous serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoInt", + @"HostIntegrationCoreApi.echoAsyncEnumList", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoInt:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoInt:completion:)", + NSCAssert([api respondsToSelector:@selector(echoAsyncEnumList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncEnumList:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSInteger arg_anInt = [GetNullableObjectAtIndex(args, 0) integerValue]; - [api callFlutterEchoInt:arg_anInt - completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSArray *arg_enumList = GetNullableObjectAtIndex(args, 0); + [api echoAsyncEnumList:arg_enumList + completion:^(NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed list, to test asynchronous serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoDouble", + @"HostIntegrationCoreApi.echoAsyncClassList", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoDouble:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoDouble:completion:)", + NSCAssert([api respondsToSelector:@selector(echoAsyncClassList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncClassList:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - double arg_aDouble = [GetNullableObjectAtIndex(args, 0) doubleValue]; - [api callFlutterEchoDouble:arg_aDouble - completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSArray *arg_classList = GetNullableObjectAtIndex(args, 0); + [api echoAsyncClassList:arg_classList + completion:^(NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed map, to test asynchronous serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoString", + @"HostIntegrationCoreApi.echoAsyncMap", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoString:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoString:completion:)", + NSCAssert([api respondsToSelector:@selector(echoAsyncMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncMap:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSString *arg_aString = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoString:arg_aString - completion:^(NSString *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_map = GetNullableObjectAtIndex(args, 0); + [api echoAsyncMap:arg_map + completion:^(NSDictionary *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed map, to test asynchronous serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoUint8List", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncStringMap", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoUint8List:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoUint8List:completion:)", + NSCAssert([api respondsToSelector:@selector(echoAsyncStringMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncStringMap:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FlutterStandardTypedData *arg_list = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoUint8List:arg_list - completion:^(FlutterStandardTypedData *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_stringMap = GetNullableObjectAtIndex(args, 0); + [api echoAsyncStringMap:arg_stringMap + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed map, to test asynchronous serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoList", + @"HostIntegrationCoreApi.echoAsyncIntMap", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoList:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoList:completion:)", + NSCAssert([api respondsToSelector:@selector(echoAsyncIntMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncIntMap:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSArray *arg_list = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoList:arg_list - completion:^(NSArray *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_intMap = GetNullableObjectAtIndex(args, 0); + [api echoAsyncIntMap:arg_intMap + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed map, to test asynchronous serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoMap", + @"HostIntegrationCoreApi.echoAsyncEnumMap", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoMap:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoMap:completion:)", + NSCAssert([api respondsToSelector:@selector(echoAsyncEnumMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncEnumMap:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSDictionary *arg_aMap = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoMap:arg_aMap - completion:^(NSDictionary *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_enumMap = + GetNullableObjectAtIndex(args, 0); + [api echoAsyncEnumMap:arg_enumMap + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed map, to test asynchronous serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoEnum", + @"HostIntegrationCoreApi.echoAsyncClassMap", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoEnum:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoEnum:completion:)", + NSCAssert([api respondsToSelector:@selector(echoAsyncClassMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncClassMap:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - AnEnumBox *enumBox = GetNullableObjectAtIndex(args, 0); - AnEnum arg_anEnum = enumBox.value; - [api callFlutterEchoEnum:arg_anEnum - completion:^(AnEnumBox *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSDictionary *arg_classMap = + GetNullableObjectAtIndex(args, 0); + [api echoAsyncClassMap:arg_classMap + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed enum, to test asynchronous serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoNullableBool", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncEnum", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableBool:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoNullableBool:completion:)", + NSCAssert([api respondsToSelector:@selector(echoAsyncEnum:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncEnum:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSNumber *arg_aBool = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoNullableBool:arg_aBool - completion:^(NSNumber *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + FLTAnEnumBox *boxedFLTAnEnum = GetNullableObjectAtIndex(args, 0); + FLTAnEnum arg_anEnum = boxedFLTAnEnum.value; + [api echoAsyncEnum:arg_anEnum + completion:^(FLTAnEnumBox *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed enum, to test asynchronous serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAnotherAsyncEnum", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAnotherAsyncEnum:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAnotherAsyncEnum:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FLTAnotherEnumBox *boxedFLTAnotherEnum = GetNullableObjectAtIndex(args, 0); + FLTAnotherEnum arg_anotherEnum = boxedFLTAnotherEnum.value; + [api echoAnotherAsyncEnum:arg_anotherEnum + completion:^(FLTAnotherEnumBox *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Responds with an error from an async function returning a value. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.throwAsyncError", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(throwAsyncErrorWithCompletion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(throwAsyncErrorWithCompletion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + [api throwAsyncErrorWithCompletion:^(id _Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Responds with an error from an async void function. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoNullableInt", + @"HostIntegrationCoreApi.throwAsyncErrorFromVoid", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableInt:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoNullableInt:completion:)", + NSCAssert([api respondsToSelector:@selector(throwAsyncErrorFromVoidWithCompletion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(throwAsyncErrorFromVoidWithCompletion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - NSNumber *arg_anInt = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoNullableInt:arg_anInt - completion:^(NSNumber *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + [api throwAsyncErrorFromVoidWithCompletion:^(FlutterError *_Nullable error) { + callback(wrapResult(nil, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Responds with a Flutter error from an async function returning a value. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - [NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoNullableDouble", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.throwAsyncFlutterError", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableDouble:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoNullableDouble:completion:)", + NSCAssert([api respondsToSelector:@selector(throwAsyncFlutterErrorWithCompletion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(throwAsyncFlutterErrorWithCompletion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - NSNumber *arg_aDouble = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoNullableDouble:arg_aDouble - completion:^(NSNumber *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + [api throwAsyncFlutterErrorWithCompletion:^(id _Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed object, to test async serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - [NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoNullableString", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncAllTypes", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableString:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoNullableString:completion:)", + NSCAssert([api respondsToSelector:@selector(echoAsyncAllTypes:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncAllTypes:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSString *arg_aString = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoNullableString:arg_aString - completion:^(NSString *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + FLTAllTypes *arg_everything = GetNullableObjectAtIndex(args, 0); + [api echoAsyncAllTypes:arg_everything + completion:^(FLTAllTypes *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed object, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat: @"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoNullableUint8List", + @"HostIntegrationCoreApi.echoAsyncNullableAllNullableTypes", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableUint8List:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoNullableUint8List:completion:)", + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableAllNullableTypes:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableAllNullableTypes:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - FlutterStandardTypedData *arg_list = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoNullableUint8List:arg_list - completion:^(FlutterStandardTypedData *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + FLTAllNullableTypes *arg_everything = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableAllNullableTypes:arg_everything + completion:^(FLTAllNullableTypes *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed object, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoNullableList", + @"HostIntegrationCoreApi." + @"echoAsyncNullableAllNullableTypesWithoutRecursion", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableList:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoNullableList:completion:)", + NSCAssert([api respondsToSelector:@selector + (echoAsyncNullableAllNullableTypesWithoutRecursion:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableAllNullableTypesWithoutRecursion:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSArray *arg_list = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoNullableList:arg_list - completion:^(NSArray *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + FLTAllNullableTypesWithoutRecursion *arg_everything = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableAllNullableTypesWithoutRecursion:arg_everything + completion:^(FLTAllNullableTypesWithoutRecursion + *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns passed in int asynchronously. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoNullableMap", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableInt", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableMap:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoNullableMap:completion:)", + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableInt:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableInt:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - NSDictionary *arg_aMap = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoNullableMap:arg_aMap - completion:^(NSDictionary *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSNumber *arg_anInt = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableInt:arg_anInt + completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns passed in double asynchronously. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterEchoNullableEnum", + @"HostIntegrationCoreApi.echoAsyncNullableDouble", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableEnum:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterEchoNullableEnum:completion:)", + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableDouble:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableDouble:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - AnEnumBox *arg_anEnum = GetNullableObjectAtIndex(args, 0); - [api callFlutterEchoNullableEnum:arg_anEnum - completion:^(AnEnumBox *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + NSNumber *arg_aDouble = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableDouble:arg_aDouble + completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } + /// Returns the passed in boolean asynchronously. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - [NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"HostIntegrationCoreApi.callFlutterSmallApiEchoString", - messageChannelSuffix] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableBool", + messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(callFlutterSmallApiEchoString:completion:)], - @"HostIntegrationCoreApi api (%@) doesn't respond to " - @"@selector(callFlutterSmallApiEchoString:completion:)", + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableBool:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableBool:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSNumber *arg_aBool = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableBool:arg_aBool + completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed string asynchronously. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableString", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableString:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableString:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; NSString *arg_aString = GetNullableObjectAtIndex(args, 0); - [api callFlutterSmallApiEchoString:arg_aString - completion:^(NSString *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; + [api echoAsyncNullableString:arg_aString + completion:^(NSString *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; }]; } else { [channel setMessageHandler:nil]; } } -} -@interface FlutterIntegrationCoreApi () -@property(nonatomic, strong) NSObject *binaryMessenger; -@property(nonatomic, strong) NSString *messageChannelSuffix; -@end - -@implementation FlutterIntegrationCoreApi - -- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger { - return [self initWithBinaryMessenger:binaryMessenger messageChannelSuffix:@""]; -} -- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger - messageChannelSuffix:(nullable NSString *)messageChannelSuffix { - self = [self init]; - if (self) { - _binaryMessenger = binaryMessenger; - _messageChannelSuffix = [messageChannelSuffix length] == 0 - ? @"" - : [NSString stringWithFormat:@".%@", messageChannelSuffix]; + /// Returns the passed in Uint8List asynchronously. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableUint8List", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableUint8List:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableUint8List:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FlutterStandardTypedData *arg_aUint8List = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableUint8List:arg_aUint8List + completion:^(FlutterStandardTypedData *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } } - return self; + /// Returns the passed in generic Object asynchronously. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableObject", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableObject:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableObject:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + id arg_anObject = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableObject:arg_anObject + completion:^(id _Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed list, to test asynchronous serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_list = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableList:arg_list + completion:^(NSArray *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed list, to test asynchronous serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableEnumList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableEnumList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableEnumList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_enumList = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableEnumList:arg_enumList + completion:^(NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed list, to test asynchronous serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableClassList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableClassList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableClassList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_classList = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableClassList:arg_classList + completion:^(NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed map, to test asynchronous serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_map = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableMap:arg_map + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed map, to test asynchronous serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableStringMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableStringMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableStringMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_stringMap = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableStringMap:arg_stringMap + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed map, to test asynchronous serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableIntMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableIntMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableIntMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_intMap = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableIntMap:arg_intMap + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed map, to test asynchronous serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableEnumMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableEnumMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableEnumMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_enumMap = + GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableEnumMap:arg_enumMap + completion:^( + NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed map, to test asynchronous serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableClassMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableClassMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableClassMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_classMap = + GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableClassMap:arg_classMap + completion:^( + NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed enum, to test asynchronous serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAsyncNullableEnum", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAsyncNullableEnum:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableEnum:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FLTAnEnumBox *arg_anEnum = GetNullableObjectAtIndex(args, 0); + [api + echoAsyncNullableEnum:arg_anEnum + completion:^(FLTAnEnumBox *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed enum, to test asynchronous serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoAnotherAsyncNullableEnum", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAnotherAsyncNullableEnum:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAnotherAsyncNullableEnum:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FLTAnotherEnumBox *arg_anotherEnum = GetNullableObjectAtIndex(args, 0); + [api echoAnotherAsyncNullableEnum:arg_anotherEnum + completion:^(FLTAnotherEnumBox *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterNoop", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterNoopWithCompletion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterNoopWithCompletion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + [api callFlutterNoopWithCompletion:^(FlutterError *_Nullable error) { + callback(wrapResult(nil, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterThrowError", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterThrowErrorWithCompletion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterThrowErrorWithCompletion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + [api callFlutterThrowErrorWithCompletion:^(id _Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterThrowErrorFromVoid", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterThrowErrorFromVoidWithCompletion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterThrowErrorFromVoidWithCompletion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + [api callFlutterThrowErrorFromVoidWithCompletion:^(FlutterError *_Nullable error) { + callback(wrapResult(nil, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoAllTypes", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoAllTypes:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoAllTypes:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FLTAllTypes *arg_everything = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoAllTypes:arg_everything + completion:^(FLTAllTypes *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoAllNullableTypes", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoAllNullableTypes:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoAllNullableTypes:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FLTAllNullableTypes *arg_everything = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoAllNullableTypes:arg_everything + completion:^(FLTAllNullableTypes *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterSendMultipleNullableTypes", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector + (callFlutterSendMultipleNullableTypesABool:anInt:aString:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterSendMultipleNullableTypesABool:anInt:aString:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0); + NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 1); + NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 2); + [api callFlutterSendMultipleNullableTypesABool:arg_aNullableBool + anInt:arg_aNullableInt + aString:arg_aNullableString + completion:^(FLTAllNullableTypes *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi." + @"callFlutterEchoAllNullableTypesWithoutRecursion", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector + (callFlutterEchoAllNullableTypesWithoutRecursion:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoAllNullableTypesWithoutRecursion:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FLTAllNullableTypesWithoutRecursion *arg_everything = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoAllNullableTypesWithoutRecursion:arg_everything + completion:^(FLTAllNullableTypesWithoutRecursion + *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + @"callFlutterSendMultipleNullableTypesWithoutRecursion", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert( + [api respondsToSelector:@selector + (callFlutterSendMultipleNullableTypesWithoutRecursionABool: + anInt:aString:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterSendMultipleNullableTypesWithoutRecursionABool:anInt:aString:" + @"completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0); + NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 1); + NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 2); + [api callFlutterSendMultipleNullableTypesWithoutRecursionABool:arg_aNullableBool + anInt:arg_aNullableInt + aString:arg_aNullableString + completion:^( + FLTAllNullableTypesWithoutRecursion + *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoBool", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoBool:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoBool:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + BOOL arg_aBool = [GetNullableObjectAtIndex(args, 0) boolValue]; + [api callFlutterEchoBool:arg_aBool + completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoInt", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoInt:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoInt:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSInteger arg_anInt = [GetNullableObjectAtIndex(args, 0) integerValue]; + [api callFlutterEchoInt:arg_anInt + completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoDouble", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoDouble:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoDouble:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + double arg_aDouble = [GetNullableObjectAtIndex(args, 0) doubleValue]; + [api callFlutterEchoDouble:arg_aDouble + completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoString", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoString:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoString:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_aString = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoString:arg_aString + completion:^(NSString *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoUint8List", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoUint8List:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoUint8List:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FlutterStandardTypedData *arg_list = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoUint8List:arg_list + completion:^(FlutterStandardTypedData *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_list = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoList:arg_list + completion:^(NSArray *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoEnumList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoEnumList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoEnumList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_enumList = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoEnumList:arg_enumList + completion:^(NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoClassList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoClassList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoClassList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_classList = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoClassList:arg_classList + completion:^(NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNonNullEnumList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNonNullEnumList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNonNullEnumList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_enumList = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNonNullEnumList:arg_enumList + completion:^(NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNonNullClassList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNonNullClassList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNonNullClassList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_classList = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNonNullClassList:arg_classList + completion:^(NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_map = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoMap:arg_map + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoStringMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoStringMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoStringMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_stringMap = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoStringMap:arg_stringMap + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoIntMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoIntMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoIntMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_intMap = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoIntMap:arg_intMap + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoEnumMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoEnumMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoEnumMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_enumMap = + GetNullableObjectAtIndex(args, 0); + [api + callFlutterEchoEnumMap:arg_enumMap + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoClassMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoClassMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoClassMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_classMap = + GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoClassMap:arg_classMap + completion:^( + NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNonNullStringMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNonNullStringMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNonNullStringMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_stringMap = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNonNullStringMap:arg_stringMap + completion:^( + NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNonNullIntMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNonNullIntMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNonNullIntMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_intMap = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNonNullIntMap:arg_intMap + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNonNullEnumMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNonNullEnumMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNonNullEnumMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_enumMap = + GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNonNullEnumMap:arg_enumMap + completion:^( + NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNonNullClassMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNonNullClassMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNonNullClassMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_classMap = + GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNonNullClassMap:arg_classMap + completion:^(NSDictionary + *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoEnum", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoEnum:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoEnum:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FLTAnEnumBox *boxedFLTAnEnum = GetNullableObjectAtIndex(args, 0); + FLTAnEnum arg_anEnum = boxedFLTAnEnum.value; + [api callFlutterEchoEnum:arg_anEnum + completion:^(FLTAnEnumBox *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoAnotherEnum", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoAnotherEnum:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoAnotherEnum:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FLTAnotherEnumBox *boxedFLTAnotherEnum = GetNullableObjectAtIndex(args, 0); + FLTAnotherEnum arg_anotherEnum = boxedFLTAnotherEnum.value; + [api callFlutterEchoAnotherEnum:arg_anotherEnum + completion:^(FLTAnotherEnumBox *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableBool", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableBool:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableBool:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSNumber *arg_aBool = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableBool:arg_aBool + completion:^(NSNumber *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableInt", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableInt:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableInt:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSNumber *arg_anInt = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableInt:arg_anInt + completion:^(NSNumber *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableDouble", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableDouble:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableDouble:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSNumber *arg_aDouble = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableDouble:arg_aDouble + completion:^(NSNumber *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableString", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableString:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableString:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_aString = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableString:arg_aString + completion:^(NSString *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableUint8List", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableUint8List:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableUint8List:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FlutterStandardTypedData *arg_list = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableUint8List:arg_list + completion:^(FlutterStandardTypedData *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_list = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableList:arg_list + completion:^(NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableEnumList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableEnumList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableEnumList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_enumList = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableEnumList:arg_enumList + completion:^(NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableClassList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableClassList:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableClassList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_classList = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableClassList:arg_classList + completion:^(NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableNonNullEnumList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableNonNullEnumList: + completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableNonNullEnumList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_enumList = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableNonNullEnumList:arg_enumList + completion:^(NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableNonNullClassList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableNonNullClassList: + completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableNonNullClassList:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_classList = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableNonNullClassList:arg_classList + completion:^( + NSArray *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_map = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableMap:arg_map + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableStringMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableStringMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableStringMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_stringMap = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableStringMap:arg_stringMap + completion:^( + NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableIntMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableIntMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableIntMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_intMap = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableIntMap:arg_intMap + completion:^(NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableEnumMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableEnumMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableEnumMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_enumMap = + GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableEnumMap:arg_enumMap + completion:^( + NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableClassMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableClassMap:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableClassMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_classMap = + GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableClassMap:arg_classMap + completion:^(NSDictionary + *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableNonNullStringMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableNonNullStringMap: + completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableNonNullStringMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_stringMap = GetNullableObjectAtIndex(args, 0); + [api + callFlutterEchoNullableNonNullStringMap:arg_stringMap + completion:^( + NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableNonNullIntMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableNonNullIntMap: + completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableNonNullIntMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_intMap = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableNonNullIntMap:arg_intMap + completion:^( + NSDictionary *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableNonNullEnumMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableNonNullEnumMap: + completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableNonNullEnumMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_enumMap = + GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableNonNullEnumMap:arg_enumMap + completion:^(NSDictionary + *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableNonNullClassMap", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableNonNullClassMap: + completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableNonNullClassMap:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSDictionary *arg_classMap = + GetNullableObjectAtIndex(args, 0); + [api + callFlutterEchoNullableNonNullClassMap:arg_classMap + completion:^(NSDictionary + *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoNullableEnum", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableEnum:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoNullableEnum:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FLTAnEnumBox *arg_anEnum = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoNullableEnum:arg_anEnum + completion:^(FLTAnEnumBox *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterEchoAnotherNullableEnum", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterEchoAnotherNullableEnum:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoAnotherNullableEnum:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FLTAnotherEnumBox *arg_anotherEnum = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoAnotherNullableEnum:arg_anotherEnum + completion:^(FLTAnotherEnumBox *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.callFlutterSmallApiEchoString", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(callFlutterSmallApiEchoString:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterSmallApiEchoString:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_aString = GetNullableObjectAtIndex(args, 0); + [api callFlutterSmallApiEchoString:arg_aString + completion:^(NSString *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } +} +@interface FLTFlutterIntegrationCoreApi () +@property(nonatomic, strong) NSObject *binaryMessenger; +@property(nonatomic, strong) NSString *messageChannelSuffix; +@end + +@implementation FLTFlutterIntegrationCoreApi + +- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger { + return [self initWithBinaryMessenger:binaryMessenger messageChannelSuffix:@""]; +} +- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger + messageChannelSuffix:(nullable NSString *)messageChannelSuffix { + self = [self init]; + if (self) { + _binaryMessenger = binaryMessenger; + _messageChannelSuffix = [messageChannelSuffix length] == 0 + ? @"" + : [NSString stringWithFormat:@".%@", messageChannelSuffix]; + } + return self; +} +- (void)noopWithCompletion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.noop", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:nil + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; +} +- (void)throwErrorWithCompletion:(void (^)(id _Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwError", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:nil + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + id output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)throwErrorFromVoidWithCompletion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.throwErrorFromVoid", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:nil + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; +} +- (void)echoAllTypes:(FLTAllTypes *)arg_everything + completion:(void (^)(FLTAllTypes *_Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllTypes", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_everything ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + FLTAllTypes *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoAllNullableTypes:(nullable FLTAllNullableTypes *)arg_everything + completion:(void (^)(FLTAllNullableTypes *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoAllNullableTypes", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_everything ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + FLTAllNullableTypes *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)sendMultipleNullableTypesABool:(nullable NSNumber *)arg_aNullableBool + anInt:(nullable NSNumber *)arg_aNullableInt + aString:(nullable NSString *)arg_aNullableString + completion:(void (^)(FLTAllNullableTypes *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.sendMultipleNullableTypes", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ + arg_aNullableBool ?: [NSNull null], arg_aNullableInt ?: [NSNull null], + arg_aNullableString ?: [NSNull null] + ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + FLTAllNullableTypes *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoAllNullableTypesWithoutRecursion: + (nullable FLTAllNullableTypesWithoutRecursion *)arg_everything + completion: + (void (^)(FLTAllNullableTypesWithoutRecursion *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoAllNullableTypesWithoutRecursion", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_everything ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + FLTAllNullableTypesWithoutRecursion *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)sendMultipleNullableTypesWithoutRecursionABool:(nullable NSNumber *)arg_aNullableBool + anInt:(nullable NSNumber *)arg_aNullableInt + aString:(nullable NSString *)arg_aNullableString + completion: + (void (^)( + FLTAllNullableTypesWithoutRecursion *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + @"sendMultipleNullableTypesWithoutRecursion", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ + arg_aNullableBool ?: [NSNull null], arg_aNullableInt ?: [NSNull null], + arg_aNullableString ?: [NSNull null] + ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + FLTAllNullableTypesWithoutRecursion *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoBool:(BOOL)arg_aBool + completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoBool", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ @(arg_aBool) ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSNumber *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoInt:(NSInteger)arg_anInt + completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoInt", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ @(arg_anInt) ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSNumber *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoDouble:(double)arg_aDouble + completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoDouble", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ @(arg_aDouble) ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSNumber *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoString:(NSString *)arg_aString + completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoString", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_aString ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSString *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoUint8List:(FlutterStandardTypedData *)arg_list + completion: + (void (^)(FlutterStandardTypedData *_Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoUint8List", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_list ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + FlutterStandardTypedData *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoList:(NSArray *)arg_list + completion:(void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoList", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_list ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSArray *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoEnumList:(NSArray *)arg_enumList + completion: + (void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnumList", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_enumList ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSArray *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; } -- (void)noopWithCompletion:(void (^)(FlutterError *_Nullable))completion { +- (void)echoClassList:(NSArray *)arg_classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { NSString *channelName = [NSString stringWithFormat: - @"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.noop", + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoClassList", _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; - [channel sendMessage:nil + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_classList ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { - completion([FlutterError errorWithCode:reply[0] - message:reply[1] - details:reply[2]]); + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); } else { - completion(nil); + NSArray *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); } } else { - completion(createConnectionError(channelName)); + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoNonNullEnumList:(NSArray *)arg_enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNonNullEnumList", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_enumList ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSArray *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoNonNullClassList:(NSArray *)arg_classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNonNullClassList", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_classList ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSArray *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoMap:(NSDictionary *)arg_map + completion:(void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoMap", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_map ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSDictionary *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoStringMap:(NSDictionary *)arg_stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoStringMap", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_stringMap ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoIntMap:(NSDictionary *)arg_intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoIntMap", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_intMap ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoEnumMap:(NSDictionary *)arg_enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnumMap", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_enumMap ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoClassMap:(NSDictionary *)arg_classMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoClassMap", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_classMap ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoNonNullStringMap:(NSDictionary *)arg_stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNonNullStringMap", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_stringMap ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoNonNullIntMap:(NSDictionary *)arg_intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNonNullIntMap", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_intMap ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoNonNullEnumMap:(NSDictionary *)arg_enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNonNullEnumMap", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_enumMap ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)echoNonNullClassMap:(NSDictionary *)arg_classMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNonNullClassMap", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_classMap ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); } }]; } -- (void)throwErrorWithCompletion:(void (^)(id _Nullable, FlutterError *_Nullable))completion { +- (void)echoEnum:(FLTAnEnum)arg_anEnum + completion:(void (^)(FLTAnEnumBox *_Nullable, FlutterError *_Nullable))completion { NSString *channelName = [NSString stringWithFormat: @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwError", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnum", _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; - [channel sendMessage:nil + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ [[FLTAnEnumBox alloc] initWithValue:arg_anEnum] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -2785,7 +5530,7 @@ - (void)throwErrorWithCompletion:(void (^)(id _Nullable, FlutterError *_Nullable message:reply[1] details:reply[2]]); } else { - id output = reply[0] == [NSNull null] ? nil : reply[0]; + FLTAnEnumBox *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -2793,43 +5538,46 @@ - (void)throwErrorWithCompletion:(void (^)(id _Nullable, FlutterError *_Nullable } }]; } -- (void)throwErrorFromVoidWithCompletion:(void (^)(FlutterError *_Nullable))completion { - NSString *channelName = - [NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"FlutterIntegrationCoreApi.throwErrorFromVoid", - _messageChannelSuffix]; +- (void)echoAnotherEnum:(FLTAnotherEnum)arg_anotherEnum + completion: + (void (^)(FLTAnotherEnumBox *_Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAnotherEnum", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; - [channel sendMessage:nil + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ [[FLTAnotherEnumBox alloc] initWithValue:arg_anotherEnum] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { - completion([FlutterError errorWithCode:reply[0] - message:reply[1] - details:reply[2]]); + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); } else { - completion(nil); + FLTAnotherEnumBox *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); } } else { - completion(createConnectionError(channelName)); + completion(nil, createConnectionError(channelName)); } }]; } -- (void)echoAllTypes:(AllTypes *)arg_everything - completion:(void (^)(AllTypes *_Nullable, FlutterError *_Nullable))completion { +- (void)echoNullableBool:(nullable NSNumber *)arg_aBool + completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { NSString *channelName = [NSString stringWithFormat: @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllTypes", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableBool", _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; - [channel sendMessage:@[ arg_everything ?: [NSNull null] ] + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_aBool ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -2837,7 +5585,7 @@ - (void)echoAllTypes:(AllTypes *)arg_everything message:reply[1] details:reply[2]]); } else { - AllTypes *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSNumber *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -2845,19 +5593,18 @@ - (void)echoAllTypes:(AllTypes *)arg_everything } }]; } -- (void)echoAllNullableTypes:(nullable AllNullableTypes *)arg_everything - completion: - (void (^)(AllNullableTypes *_Nullable, FlutterError *_Nullable))completion { - NSString *channelName = - [NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests." - @"FlutterIntegrationCoreApi.echoAllNullableTypes", - _messageChannelSuffix]; +- (void)echoNullableInt:(nullable NSNumber *)arg_anInt + completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableInt", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; - [channel sendMessage:@[ arg_everything ?: [NSNull null] ] + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_anInt ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -2865,7 +5612,7 @@ - (void)echoAllNullableTypes:(nullable AllNullableTypes *)arg_everything message:reply[1] details:reply[2]]); } else { - AllNullableTypes *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSNumber *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -2873,24 +5620,18 @@ - (void)echoAllNullableTypes:(nullable AllNullableTypes *)arg_everything } }]; } -- (void)sendMultipleNullableTypesABool:(nullable NSNumber *)arg_aNullableBool - anInt:(nullable NSNumber *)arg_aNullableInt - aString:(nullable NSString *)arg_aNullableString - completion:(void (^)(AllNullableTypes *_Nullable, - FlutterError *_Nullable))completion { +- (void)echoNullableDouble:(nullable NSNumber *)arg_aDouble + completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { NSString *channelName = [NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"FlutterIntegrationCoreApi.sendMultipleNullableTypes", + @"FlutterIntegrationCoreApi.echoNullableDouble", _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; - [channel sendMessage:@[ - arg_aNullableBool ?: [NSNull null], arg_aNullableInt ?: [NSNull null], - arg_aNullableString ?: [NSNull null] - ] + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_aDouble ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -2898,7 +5639,7 @@ - (void)sendMultipleNullableTypesABool:(nullable NSNumber *)arg_aNullableBool message:reply[1] details:reply[2]]); } else { - AllNullableTypes *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSNumber *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -2906,20 +5647,18 @@ - (void)sendMultipleNullableTypesABool:(nullable NSNumber *)arg_aNullableBool } }]; } -- (void)echoAllNullableTypesWithoutRecursion: - (nullable AllNullableTypesWithoutRecursion *)arg_everything - completion:(void (^)(AllNullableTypesWithoutRecursion *_Nullable, - FlutterError *_Nullable))completion { +- (void)echoNullableString:(nullable NSString *)arg_aString + completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion { NSString *channelName = [NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"FlutterIntegrationCoreApi.echoAllNullableTypesWithoutRecursion", + @"FlutterIntegrationCoreApi.echoNullableString", _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; - [channel sendMessage:@[ arg_everything ?: [NSNull null] ] + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_aString ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -2927,8 +5666,7 @@ - (void)echoAllNullableTypesWithoutRecursion: message:reply[1] details:reply[2]]); } else { - AllNullableTypesWithoutRecursion *output = - reply[0] == [NSNull null] ? nil : reply[0]; + NSString *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -2936,26 +5674,19 @@ - (void)echoAllNullableTypesWithoutRecursion: } }]; } -- (void) - sendMultipleNullableTypesWithoutRecursionABool:(nullable NSNumber *)arg_aNullableBool - anInt:(nullable NSNumber *)arg_aNullableInt - aString:(nullable NSString *)arg_aNullableString - completion: - (void (^)(AllNullableTypesWithoutRecursion *_Nullable, - FlutterError *_Nullable))completion { - NSString *channelName = [NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - @"sendMultipleNullableTypesWithoutRecursion", - _messageChannelSuffix]; +- (void)echoNullableUint8List:(nullable FlutterStandardTypedData *)arg_list + completion:(void (^)(FlutterStandardTypedData *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNullableUint8List", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; - [channel sendMessage:@[ - arg_aNullableBool ?: [NSNull null], arg_aNullableInt ?: [NSNull null], - arg_aNullableString ?: [NSNull null] - ] + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_list ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -2963,7 +5694,7 @@ - (void)echoAllNullableTypesWithoutRecursion: message:reply[1] details:reply[2]]); } else { - AllNullableTypesWithoutRecursion *output = + FlutterStandardTypedData *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } @@ -2972,18 +5703,18 @@ - (void)echoAllNullableTypesWithoutRecursion: } }]; } -- (void)echoBool:(BOOL)arg_aBool - completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { +- (void)echoNullableList:(nullable NSArray *)arg_list + completion:(void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion { NSString *channelName = [NSString stringWithFormat: @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoBool", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableList", _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; - [channel sendMessage:@[ @(arg_aBool) ] + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_list ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -2991,7 +5722,7 @@ - (void)echoBool:(BOOL)arg_aBool message:reply[1] details:reply[2]]); } else { - NSNumber *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSArray *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -2999,17 +5730,19 @@ - (void)echoBool:(BOOL)arg_aBool } }]; } -- (void)echoInt:(NSInteger)arg_anInt - completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { - NSString *channelName = [NSString - stringWithFormat: - @"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoInt", - _messageChannelSuffix]; +- (void)echoNullableEnumList:(nullable NSArray *)arg_enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNullableEnumList", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; - [channel sendMessage:@[ @(arg_anInt) ] + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_enumList ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3017,7 +5750,7 @@ - (void)echoInt:(NSInteger)arg_anInt message:reply[1] details:reply[2]]); } else { - NSNumber *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSArray *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3025,18 +5758,19 @@ - (void)echoInt:(NSInteger)arg_anInt } }]; } -- (void)echoDouble:(double)arg_aDouble - completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { - NSString *channelName = [NSString - stringWithFormat: - @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoDouble", - _messageChannelSuffix]; +- (void)echoNullableClassList:(nullable NSArray *)arg_classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNullableClassList", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; - [channel sendMessage:@[ @(arg_aDouble) ] + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_classList ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3044,7 +5778,8 @@ - (void)echoDouble:(double)arg_aDouble message:reply[1] details:reply[2]]); } else { - NSNumber *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSArray *output = + reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3052,18 +5787,19 @@ - (void)echoDouble:(double)arg_aDouble } }]; } -- (void)echoString:(NSString *)arg_aString - completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion { - NSString *channelName = [NSString - stringWithFormat: - @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoString", - _messageChannelSuffix]; +- (void)echoNullableNonNullEnumList:(nullable NSArray *)arg_enumList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNullableNonNullEnumList", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; - [channel sendMessage:@[ arg_aString ?: [NSNull null] ] + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_enumList ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3071,7 +5807,7 @@ - (void)echoString:(NSString *)arg_aString message:reply[1] details:reply[2]]); } else { - NSString *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSArray *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3079,19 +5815,19 @@ - (void)echoString:(NSString *)arg_aString } }]; } -- (void)echoUint8List:(FlutterStandardTypedData *)arg_list - completion: - (void (^)(FlutterStandardTypedData *_Nullable, FlutterError *_Nullable))completion { - NSString *channelName = [NSString - stringWithFormat: - @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoUint8List", - _messageChannelSuffix]; +- (void)echoNullableNonNullClassList:(nullable NSArray *)arg_classList + completion:(void (^)(NSArray *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNullableNonNullClassList", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; - [channel sendMessage:@[ arg_list ?: [NSNull null] ] + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_classList ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3099,7 +5835,7 @@ - (void)echoUint8List:(FlutterStandardTypedData *)arg_list message:reply[1] details:reply[2]]); } else { - FlutterStandardTypedData *output = + NSArray *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } @@ -3108,18 +5844,19 @@ - (void)echoUint8List:(FlutterStandardTypedData *)arg_list } }]; } -- (void)echoList:(NSArray *)arg_list - completion:(void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion { +- (void)echoNullableMap:(nullable NSDictionary *)arg_map + completion: + (void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion { NSString *channelName = [NSString stringWithFormat: @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoList", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableMap", _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; - [channel sendMessage:@[ arg_list ?: [NSNull null] ] + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_map ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3127,7 +5864,7 @@ - (void)echoList:(NSArray *)arg_list message:reply[1] details:reply[2]]); } else { - NSArray *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSDictionary *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3135,18 +5872,19 @@ - (void)echoList:(NSArray *)arg_list } }]; } -- (void)echoMap:(NSDictionary *)arg_aMap - completion: - (void (^)(NSDictionary *_Nullable, FlutterError *_Nullable))completion { - NSString *channelName = [NSString - stringWithFormat: - @"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoMap", - _messageChannelSuffix]; +- (void)echoNullableStringMap:(nullable NSDictionary *)arg_stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNullableStringMap", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; - [channel sendMessage:@[ arg_aMap ?: [NSNull null] ] + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_stringMap ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3154,7 +5892,7 @@ - (void)echoMap:(NSDictionary *)arg_aMap message:reply[1] details:reply[2]]); } else { - NSDictionary *output = + NSDictionary *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } @@ -3163,18 +5901,19 @@ - (void)echoMap:(NSDictionary *)arg_aMap } }]; } -- (void)echoEnum:(AnEnum)arg_anEnum - completion:(void (^)(AnEnumBox *_Nullable, FlutterError *_Nullable))completion { - NSString *channelName = [NSString - stringWithFormat: - @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnum", - _messageChannelSuffix]; +- (void)echoNullableIntMap:(nullable NSDictionary *)arg_intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNullableIntMap", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; - [channel sendMessage:@[ [[AnEnumBox alloc] initWithValue:arg_anEnum] ] + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_intMap ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3182,7 +5921,8 @@ - (void)echoEnum:(AnEnum)arg_anEnum message:reply[1] details:reply[2]]); } else { - AnEnumBox *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3190,18 +5930,19 @@ - (void)echoEnum:(AnEnum)arg_anEnum } }]; } -- (void)echoNullableBool:(nullable NSNumber *)arg_aBool - completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { - NSString *channelName = [NSString - stringWithFormat: - @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableBool", - _messageChannelSuffix]; +- (void)echoNullableEnumMap:(nullable NSDictionary *)arg_enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNullableEnumMap", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; - [channel sendMessage:@[ arg_aBool ?: [NSNull null] ] + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_enumMap ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3209,7 +5950,8 @@ - (void)echoNullableBool:(nullable NSNumber *)arg_aBool message:reply[1] details:reply[2]]); } else { - NSNumber *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3217,18 +5959,20 @@ - (void)echoNullableBool:(nullable NSNumber *)arg_aBool } }]; } -- (void)echoNullableInt:(nullable NSNumber *)arg_anInt - completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { - NSString *channelName = [NSString - stringWithFormat: - @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableInt", - _messageChannelSuffix]; +- (void)echoNullableClassMap: + (nullable NSDictionary *)arg_classMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNullableClassMap", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; - [channel sendMessage:@[ arg_anInt ?: [NSNull null] ] + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_classMap ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3236,7 +5980,8 @@ - (void)echoNullableInt:(nullable NSNumber *)arg_anInt message:reply[1] details:reply[2]]); } else { - NSNumber *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3244,18 +5989,19 @@ - (void)echoNullableInt:(nullable NSNumber *)arg_anInt } }]; } -- (void)echoNullableDouble:(nullable NSNumber *)arg_aDouble - completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { +- (void)echoNullableNonNullStringMap:(nullable NSDictionary *)arg_stringMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { NSString *channelName = [NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"FlutterIntegrationCoreApi.echoNullableDouble", + @"FlutterIntegrationCoreApi.echoNullableNonNullStringMap", _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; - [channel sendMessage:@[ arg_aDouble ?: [NSNull null] ] + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_stringMap ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3263,7 +6009,8 @@ - (void)echoNullableDouble:(nullable NSNumber *)arg_aDouble message:reply[1] details:reply[2]]); } else { - NSNumber *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3271,18 +6018,19 @@ - (void)echoNullableDouble:(nullable NSNumber *)arg_aDouble } }]; } -- (void)echoNullableString:(nullable NSString *)arg_aString - completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion { +- (void)echoNullableNonNullIntMap:(nullable NSDictionary *)arg_intMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { NSString *channelName = [NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"FlutterIntegrationCoreApi.echoNullableString", + @"FlutterIntegrationCoreApi.echoNullableNonNullIntMap", _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; - [channel sendMessage:@[ arg_aString ?: [NSNull null] ] + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_intMap ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3290,7 +6038,8 @@ - (void)echoNullableString:(nullable NSString *)arg_aString message:reply[1] details:reply[2]]); } else { - NSString *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3298,19 +6047,20 @@ - (void)echoNullableString:(nullable NSString *)arg_aString } }]; } -- (void)echoNullableUint8List:(nullable FlutterStandardTypedData *)arg_list - completion:(void (^)(FlutterStandardTypedData *_Nullable, - FlutterError *_Nullable))completion { +- (void) + echoNullableNonNullEnumMap:(nullable NSDictionary *)arg_enumMap + completion:(void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { NSString *channelName = [NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests." - @"FlutterIntegrationCoreApi.echoNullableUint8List", + @"FlutterIntegrationCoreApi.echoNullableNonNullEnumMap", _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; - [channel sendMessage:@[ arg_list ?: [NSNull null] ] + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_enumMap ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3318,7 +6068,7 @@ - (void)echoNullableUint8List:(nullable FlutterStandardTypedData *)arg_list message:reply[1] details:reply[2]]); } else { - FlutterStandardTypedData *output = + NSDictionary *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } @@ -3327,18 +6077,21 @@ - (void)echoNullableUint8List:(nullable FlutterStandardTypedData *)arg_list } }]; } -- (void)echoNullableList:(nullable NSArray *)arg_list - completion:(void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion { - NSString *channelName = [NSString - stringWithFormat: - @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableList", - _messageChannelSuffix]; +- (void)echoNullableNonNullClassMap: + (nullable NSDictionary *)arg_classMap + completion: + (void (^)(NSDictionary *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoNullableNonNullClassMap", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; - [channel sendMessage:@[ arg_list ?: [NSNull null] ] + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_classMap ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3346,7 +6099,8 @@ - (void)echoNullableList:(nullable NSArray *)arg_list message:reply[1] details:reply[2]]); } else { - NSArray *output = reply[0] == [NSNull null] ? nil : reply[0]; + NSDictionary *output = + reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3354,19 +6108,18 @@ - (void)echoNullableList:(nullable NSArray *)arg_list } }]; } -- (void)echoNullableMap:(nullable NSDictionary *)arg_aMap - completion:(void (^)(NSDictionary *_Nullable, - FlutterError *_Nullable))completion { +- (void)echoNullableEnum:(nullable FLTAnEnumBox *)arg_anEnum + completion:(void (^)(FLTAnEnumBox *_Nullable, FlutterError *_Nullable))completion { NSString *channelName = [NSString stringWithFormat: @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableMap", + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableEnum", _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; - [channel sendMessage:@[ arg_aMap ?: [NSNull null] ] + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_anEnum == nil ? [NSNull null] : arg_anEnum ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3374,8 +6127,7 @@ - (void)echoNullableMap:(nullable NSDictionary *)arg_aMap message:reply[1] details:reply[2]]); } else { - NSDictionary *output = - reply[0] == [NSNull null] ? nil : reply[0]; + FLTAnEnumBox *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3383,18 +6135,19 @@ - (void)echoNullableMap:(nullable NSDictionary *)arg_aMap } }]; } -- (void)echoNullableEnum:(nullable AnEnumBox *)arg_anEnum - completion:(void (^)(AnEnumBox *_Nullable, FlutterError *_Nullable))completion { - NSString *channelName = [NSString - stringWithFormat: - @"%@%@", - @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableEnum", - _messageChannelSuffix]; +- (void)echoAnotherNullableEnum:(nullable FLTAnotherEnumBox *)arg_anotherEnum + completion:(void (^)(FLTAnotherEnumBox *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"FlutterIntegrationCoreApi.echoAnotherNullableEnum", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; - [channel sendMessage:@[ arg_anEnum == nil ? [NSNull null] : arg_anEnum ] + codec:FLTGetCoreTestsCodec()]; + [channel sendMessage:@[ arg_anotherEnum == nil ? [NSNull null] : arg_anotherEnum ] reply:^(NSArray *reply) { if (reply != nil) { if (reply.count > 1) { @@ -3402,7 +6155,7 @@ - (void)echoNullableEnum:(nullable AnEnumBox *)arg_anEnum message:reply[1] details:reply[2]]); } else { - AnEnumBox *output = reply[0] == [NSNull null] ? nil : reply[0]; + FLTAnotherEnumBox *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3419,7 +6172,7 @@ - (void)noopAsyncWithCompletion:(void (^)(FlutterError *_Nullable))completion { FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; [channel sendMessage:nil reply:^(NSArray *reply) { if (reply != nil) { @@ -3445,7 +6198,7 @@ - (void)echoAsyncString:(NSString *)arg_aString FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; [channel sendMessage:@[ arg_aString ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { @@ -3464,13 +6217,14 @@ - (void)echoAsyncString:(NSString *)arg_aString } @end -void SetUpHostTrivialApi(id binaryMessenger, - NSObject *api) { - SetUpHostTrivialApiWithSuffix(binaryMessenger, api, @""); +void SetUpFLTHostTrivialApi(id binaryMessenger, + NSObject *api) { + SetUpFLTHostTrivialApiWithSuffix(binaryMessenger, api, @""); } -void SetUpHostTrivialApiWithSuffix(id binaryMessenger, - NSObject *api, NSString *messageChannelSuffix) { +void SetUpFLTHostTrivialApiWithSuffix(id binaryMessenger, + NSObject *api, + NSString *messageChannelSuffix) { messageChannelSuffix = messageChannelSuffix.length > 0 ? [NSString stringWithFormat:@".%@", messageChannelSuffix] : @""; @@ -3482,10 +6236,10 @@ void SetUpHostTrivialApiWithSuffix(id binaryMessenger, @"dev.flutter.pigeon.pigeon_integration_tests.HostTrivialApi.noop", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(noopWithError:)], - @"HostTrivialApi api (%@) doesn't respond to @selector(noopWithError:)", api); + @"FLTHostTrivialApi api (%@) doesn't respond to @selector(noopWithError:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { FlutterError *error; [api noopWithError:&error]; @@ -3496,12 +6250,14 @@ void SetUpHostTrivialApiWithSuffix(id binaryMessenger, } } } -void SetUpHostSmallApi(id binaryMessenger, NSObject *api) { - SetUpHostSmallApiWithSuffix(binaryMessenger, api, @""); +void SetUpFLTHostSmallApi(id binaryMessenger, + NSObject *api) { + SetUpFLTHostSmallApiWithSuffix(binaryMessenger, api, @""); } -void SetUpHostSmallApiWithSuffix(id binaryMessenger, - NSObject *api, NSString *messageChannelSuffix) { +void SetUpFLTHostSmallApiWithSuffix(id binaryMessenger, + NSObject *api, + NSString *messageChannelSuffix) { messageChannelSuffix = messageChannelSuffix.length > 0 ? [NSString stringWithFormat:@".%@", messageChannelSuffix] : @""; @@ -3513,10 +6269,11 @@ void SetUpHostSmallApiWithSuffix(id binaryMessenger, @"dev.flutter.pigeon.pigeon_integration_tests.HostSmallApi.echo", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(echoString:completion:)], - @"HostSmallApi api (%@) doesn't respond to @selector(echoString:completion:)", api); + @"FLTHostSmallApi api (%@) doesn't respond to @selector(echoString:completion:)", + api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; NSString *arg_aString = GetNullableObjectAtIndex(args, 0); @@ -3536,10 +6293,10 @@ void SetUpHostSmallApiWithSuffix(id binaryMessenger, @"HostSmallApi.voidVoid", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(voidVoidWithCompletion:)], - @"HostSmallApi api (%@) doesn't respond to @selector(voidVoidWithCompletion:)", + @"FLTHostSmallApi api (%@) doesn't respond to @selector(voidVoidWithCompletion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { [api voidVoidWithCompletion:^(FlutterError *_Nullable error) { @@ -3551,12 +6308,12 @@ void SetUpHostSmallApiWithSuffix(id binaryMessenger, } } } -@interface FlutterSmallApi () +@interface FLTFlutterSmallApi () @property(nonatomic, strong) NSObject *binaryMessenger; @property(nonatomic, strong) NSString *messageChannelSuffix; @end -@implementation FlutterSmallApi +@implementation FLTFlutterSmallApi - (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger { return [self initWithBinaryMessenger:binaryMessenger messageChannelSuffix:@""]; @@ -3572,8 +6329,8 @@ - (instancetype)initWithBinaryMessenger:(NSObject *)bina } return self; } -- (void)echoWrappedList:(TestMessage *)arg_msg - completion:(void (^)(TestMessage *_Nullable, FlutterError *_Nullable))completion { +- (void)echoWrappedList:(FLTTestMessage *)arg_msg + completion:(void (^)(FLTTestMessage *_Nullable, FlutterError *_Nullable))completion { NSString *channelName = [NSString stringWithFormat: @"%@%@", @"dev.flutter.pigeon.pigeon_integration_tests.FlutterSmallApi.echoWrappedList", @@ -3581,7 +6338,7 @@ - (void)echoWrappedList:(TestMessage *)arg_msg FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; [channel sendMessage:@[ arg_msg ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { @@ -3590,7 +6347,7 @@ - (void)echoWrappedList:(TestMessage *)arg_msg message:reply[1] details:reply[2]]); } else { - TestMessage *output = reply[0] == [NSNull null] ? nil : reply[0]; + FLTTestMessage *output = reply[0] == [NSNull null] ? nil : reply[0]; completion(output, nil); } } else { @@ -3607,7 +6364,7 @@ - (void)echoString:(NSString *)arg_aString FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:channelName binaryMessenger:self.binaryMessenger - codec:GetCoreTestsCodec()]; + codec:FLTGetCoreTestsCodec()]; [channel sendMessage:@[ arg_aString ?: [NSNull null] ] reply:^(NSArray *reply) { if (reply != nil) { 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 eb8c109ccfca..eefdc514fd1e 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/dart_test.yaml b/packages/pigeon/platform_tests/shared_test_plugin_code/dart_test.yaml new file mode 100644 index 000000000000..91ec220b8e22 --- /dev/null +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/dart_test.yaml @@ -0,0 +1 @@ +test_on: vm diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/generated.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/generated.dart index 31aff33a3f36..b7861ee4d574 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/generated.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/generated.dart @@ -3,3 +3,5 @@ // found in the LICENSE file. export 'src/generated/core_tests.gen.dart'; +export 'src/generated/proxy_api_tests.gen.dart' + show ProxyApiSuperClass, ProxyApiTestClass, ProxyApiTestEnum; diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/integration_tests.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/integration_tests.dart index ba3ac04c1c95..21d76637675c 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/integration_tests.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/integration_tests.dart @@ -2,23 +2,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// ignore_for_file: unused_local_variable + import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'generated.dart'; -import 'src/generated/core_tests.gen.dart'; - -const int _biggerThanBigInt = 3000000000; -const int _regularInt = 42; -const double _doublePi = 3.14159; +import 'test_types.dart'; /// Possible host languages that test can target. enum TargetGenerator { /// The Windows C++ generator. cpp, + /// The Linux GObject generator. + gobject, + /// The Android Java generator. java, @@ -32,339 +33,16 @@ enum TargetGenerator { swift, } +/// Host languages that support generating Proxy APIs. +const Set proxyApiSupportedLanguages = { + TargetGenerator.kotlin, + TargetGenerator.swift, +}; + /// Sets up and runs the integration tests. void runPigeonIntegrationTests(TargetGenerator targetGenerator) { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - void compareAllTypes(AllTypes? allTypesOne, AllTypes? allTypesTwo) { - expect(allTypesOne == null, allTypesTwo == null); - if (allTypesOne == null || allTypesTwo == null) { - return; - } - expect(allTypesOne.aBool, allTypesTwo.aBool); - expect(allTypesOne.anInt, allTypesTwo.anInt); - expect(allTypesOne.anInt64, allTypesTwo.anInt64); - expect(allTypesOne.aDouble, allTypesTwo.aDouble); - expect(allTypesOne.aString, allTypesTwo.aString); - expect(allTypesOne.aByteArray, allTypesTwo.aByteArray); - expect(allTypesOne.a4ByteArray, allTypesTwo.a4ByteArray); - expect(allTypesOne.a8ByteArray, allTypesTwo.a8ByteArray); - expect(allTypesOne.aFloatArray, allTypesTwo.aFloatArray); - expect(allTypesOne.anEnum, allTypesTwo.anEnum); - expect(allTypesOne.anObject, allTypesTwo.anObject); - expect(listEquals(allTypesOne.list, allTypesTwo.list), true); - expect(listEquals(allTypesOne.stringList, allTypesTwo.stringList), true); - expect(listEquals(allTypesOne.boolList, allTypesTwo.boolList), true); - expect(listEquals(allTypesOne.doubleList, allTypesTwo.doubleList), true); - expect(listEquals(allTypesOne.intList, allTypesTwo.intList), true); - expect(mapEquals(allTypesOne.map, allTypesTwo.map), true); - } - - void compareAllNullableTypes(AllNullableTypes? allNullableTypesOne, - AllNullableTypes? allNullableTypesTwo) { - expect(allNullableTypesOne == null, allNullableTypesTwo == null); - if (allNullableTypesOne == null || allNullableTypesTwo == null) { - return; - } - expect( - allNullableTypesOne.aNullableBool, allNullableTypesTwo.aNullableBool); - expect(allNullableTypesOne.aNullableInt, allNullableTypesTwo.aNullableInt); - expect( - allNullableTypesOne.aNullableInt64, allNullableTypesTwo.aNullableInt64); - expect(allNullableTypesOne.aNullableDouble, - allNullableTypesTwo.aNullableDouble); - expect(allNullableTypesOne.aNullableString, - allNullableTypesTwo.aNullableString); - expect(allNullableTypesOne.aNullableByteArray, - allNullableTypesTwo.aNullableByteArray); - expect(allNullableTypesOne.aNullable4ByteArray, - allNullableTypesTwo.aNullable4ByteArray); - expect(allNullableTypesOne.aNullable8ByteArray, - allNullableTypesTwo.aNullable8ByteArray); - expect(allNullableTypesOne.aNullableFloatArray, - allNullableTypesTwo.aNullableFloatArray); - expect(allNullableTypesOne.nullableNestedList?.length, - allNullableTypesTwo.nullableNestedList?.length); - // TODO(stuartmorgan): Enable this once the Dart types are fixed; see - // https://github.com/flutter/flutter/issues/116117 - //for (int i = 0; i < allNullableTypesOne.nullableNestedList!.length; i++) { - // expect(listEquals(allNullableTypesOne.nullableNestedList![i], allNullableTypesTwo.nullableNestedList![i]), - // true); - //} - expect( - mapEquals(allNullableTypesOne.nullableMapWithAnnotations, - allNullableTypesTwo.nullableMapWithAnnotations), - true); - expect( - mapEquals(allNullableTypesOne.nullableMapWithObject, - allNullableTypesTwo.nullableMapWithObject), - true); - expect(allNullableTypesOne.aNullableObject, - allNullableTypesTwo.aNullableObject); - expect( - allNullableTypesOne.aNullableEnum, allNullableTypesTwo.aNullableEnum); - compareAllNullableTypes(allNullableTypesOne.allNullableTypes, - allNullableTypesTwo.allNullableTypes); - expect( - listEquals(allNullableTypesOne.list, allNullableTypesTwo.list), true); - expect( - listEquals( - allNullableTypesOne.stringList, allNullableTypesTwo.stringList), - true); - expect( - listEquals(allNullableTypesOne.boolList, allNullableTypesTwo.boolList), - true); - expect( - listEquals( - allNullableTypesOne.doubleList, allNullableTypesTwo.doubleList), - true); - expect(listEquals(allNullableTypesOne.intList, allNullableTypesTwo.intList), - true); - expect(allNullableTypesOne.nestedClassList?.length, - allNullableTypesTwo.nestedClassList?.length); - for (int i = 0; - i < (allNullableTypesOne.nestedClassList?.length ?? 0); - i++) { - compareAllNullableTypes(allNullableTypesOne.nestedClassList?[i], - allNullableTypesTwo.nestedClassList?[i]); - } - expect(mapEquals(allNullableTypesOne.map, allNullableTypesTwo.map), true); - } - - void compareAllNullableTypesWithoutRecursion( - AllNullableTypesWithoutRecursion? allNullableTypesOne, - AllNullableTypesWithoutRecursion? allNullableTypesTwo) { - expect(allNullableTypesOne == null, allNullableTypesTwo == null); - if (allNullableTypesOne == null || allNullableTypesTwo == null) { - return; - } - expect( - allNullableTypesOne.aNullableBool, allNullableTypesTwo.aNullableBool); - expect(allNullableTypesOne.aNullableInt, allNullableTypesTwo.aNullableInt); - expect( - allNullableTypesOne.aNullableInt64, allNullableTypesTwo.aNullableInt64); - expect(allNullableTypesOne.aNullableDouble, - allNullableTypesTwo.aNullableDouble); - expect(allNullableTypesOne.aNullableString, - allNullableTypesTwo.aNullableString); - expect(allNullableTypesOne.aNullableByteArray, - allNullableTypesTwo.aNullableByteArray); - expect(allNullableTypesOne.aNullable4ByteArray, - allNullableTypesTwo.aNullable4ByteArray); - expect(allNullableTypesOne.aNullable8ByteArray, - allNullableTypesTwo.aNullable8ByteArray); - expect(allNullableTypesOne.aNullableFloatArray, - allNullableTypesTwo.aNullableFloatArray); - expect(allNullableTypesOne.nullableNestedList?.length, - allNullableTypesTwo.nullableNestedList?.length); - // TODO(stuartmorgan): Enable this once the Dart types are fixed; see - // https://github.com/flutter/flutter/issues/116117 - //for (int i = 0; i < allNullableTypesOne.nullableNestedList!.length; i++) { - // expect(listEquals(allNullableTypesOne.nullableNestedList![i], allNullableTypesTwo.nullableNestedList![i]), - // true); - //} - expect( - mapEquals(allNullableTypesOne.nullableMapWithAnnotations, - allNullableTypesTwo.nullableMapWithAnnotations), - true); - expect( - mapEquals(allNullableTypesOne.nullableMapWithObject, - allNullableTypesTwo.nullableMapWithObject), - true); - expect(allNullableTypesOne.aNullableObject, - allNullableTypesTwo.aNullableObject); - expect( - allNullableTypesOne.aNullableEnum, allNullableTypesTwo.aNullableEnum); - expect( - listEquals(allNullableTypesOne.list, allNullableTypesTwo.list), true); - expect( - listEquals( - allNullableTypesOne.stringList, allNullableTypesTwo.stringList), - true); - expect( - listEquals(allNullableTypesOne.boolList, allNullableTypesTwo.boolList), - true); - expect( - listEquals( - allNullableTypesOne.doubleList, allNullableTypesTwo.doubleList), - true); - expect(listEquals(allNullableTypesOne.intList, allNullableTypesTwo.intList), - true); - expect(mapEquals(allNullableTypesOne.map, allNullableTypesTwo.map), true); - } - - void compareAllClassesWrapper( - AllClassesWrapper? wrapperOne, AllClassesWrapper? wrapperTwo) { - expect(wrapperOne == null, wrapperTwo == null); - if (wrapperOne == null || wrapperTwo == null) { - return; - } - - compareAllNullableTypes( - wrapperOne.allNullableTypes, wrapperTwo.allNullableTypes); - compareAllNullableTypesWithoutRecursion( - wrapperOne.allNullableTypesWithoutRecursion, - wrapperTwo.allNullableTypesWithoutRecursion, - ); - compareAllTypes(wrapperOne.allTypes, wrapperTwo.allTypes); - } - - final Map map = { - 'a': 1, - 'b': 2.0, - 'c': 'three', - 'd': false, - 'e': null - }; - - final List list = [ - 'Thing 1', - 2, - true, - 3.14, - null, - ]; - - final List stringList = [ - 'Thing 1', - '2', - 'true', - '3.14', - null, - ]; - - final List intList = [ - 1, - 2, - 3, - 4, - null, - ]; - - final List doubleList = [ - 1, - 2.99999, - 3, - 3.14, - null, - ]; - - final List boolList = [ - true, - false, - true, - false, - null, - ]; - - final AllTypes genericAllTypes = AllTypes( - aBool: true, - anInt: _regularInt, - anInt64: _biggerThanBigInt, - aDouble: _doublePi, - aString: 'Hello host!', - aByteArray: Uint8List.fromList([1, 2, 3]), - a4ByteArray: Int32List.fromList([4, 5, 6]), - a8ByteArray: Int64List.fromList([7, 8, 9]), - aFloatArray: Float64List.fromList([2.71828, _doublePi]), - anEnum: AnEnum.fortyTwo, - anObject: 1, - list: list, - stringList: stringList, - intList: intList, - doubleList: doubleList, - boolList: boolList, - map: map, - ); - - final AllNullableTypes genericAllNullableTypes = AllNullableTypes( - aNullableBool: true, - aNullableInt: _regularInt, - aNullableInt64: _biggerThanBigInt, - aNullableDouble: _doublePi, - aNullableString: 'Hello host!', - aNullableByteArray: Uint8List.fromList([1, 2, 3]), - aNullable4ByteArray: Int32List.fromList([4, 5, 6]), - aNullable8ByteArray: Int64List.fromList([7, 8, 9]), - aNullableFloatArray: Float64List.fromList([2.71828, _doublePi]), - nullableNestedList: >[ - [true, false], - [false, true] - ], - nullableMapWithAnnotations: {}, - nullableMapWithObject: {}, - aNullableEnum: AnEnum.fourHundredTwentyTwo, - aNullableObject: 0, - list: list, - stringList: stringList, - intList: intList, - doubleList: doubleList, - boolList: boolList, - map: map, - ); - - final List allNullableTypesList = [ - genericAllNullableTypes, - AllNullableTypes(), - null, - ]; - - final AllNullableTypes recursiveAllNullableTypes = AllNullableTypes( - aNullableBool: true, - aNullableInt: _regularInt, - aNullableInt64: _biggerThanBigInt, - aNullableDouble: _doublePi, - aNullableString: 'Hello host!', - aNullableByteArray: Uint8List.fromList([1, 2, 3]), - aNullable4ByteArray: Int32List.fromList([4, 5, 6]), - aNullable8ByteArray: Int64List.fromList([7, 8, 9]), - aNullableFloatArray: Float64List.fromList([2.71828, _doublePi]), - nullableNestedList: >[ - [true, false], - [false, true] - ], - nullableMapWithAnnotations: {}, - nullableMapWithObject: {}, - aNullableEnum: AnEnum.fourHundredTwentyTwo, - aNullableObject: 0, - allNullableTypes: genericAllNullableTypes, - list: list, - stringList: stringList, - intList: intList, - doubleList: doubleList, - boolList: boolList, - nestedClassList: allNullableTypesList, - map: map, - ); - - final AllNullableTypesWithoutRecursion - genericAllNullableTypesWithoutRecursion = - AllNullableTypesWithoutRecursion( - aNullableBool: true, - aNullableInt: _regularInt, - aNullableInt64: _biggerThanBigInt, - aNullableDouble: _doublePi, - aNullableString: 'Hello host!', - aNullableByteArray: Uint8List.fromList([1, 2, 3]), - aNullable4ByteArray: Int32List.fromList([4, 5, 6]), - aNullable8ByteArray: Int64List.fromList([7, 8, 9]), - aNullableFloatArray: Float64List.fromList([2.71828, _doublePi]), - nullableNestedList: >[ - [true, false], - [false, true] - ], - nullableMapWithAnnotations: {}, - nullableMapWithObject: {}, - aNullableEnum: AnEnum.fourHundredTwentyTwo, - aNullableObject: 0, - list: list, - stringList: stringList, - intList: intList, - doubleList: doubleList, - boolList: boolList, - map: map, - ); - group('Host sync API tests', () { testWidgets('basic void->void call works', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); @@ -405,26 +83,26 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - final AllNullableTypes nullableListTypes = + final AllNullableTypes listTypes = AllNullableTypes(list: ['String', null]); final AllNullableTypes? echoNullFilledClass = - await api.echoAllNullableTypes(nullableListTypes); + await api.echoAllNullableTypes(listTypes); - compareAllNullableTypes(nullableListTypes, echoNullFilledClass); + compareAllNullableTypes(listTypes, echoNullFilledClass); }); testWidgets('Classes with map of null serialize and deserialize correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - final AllNullableTypes nullableListTypes = AllNullableTypes( + final AllNullableTypes listTypes = AllNullableTypes( map: {'String': 'string', 'null': null}); final AllNullableTypes? echoNullFilledClass = - await api.echoAllNullableTypes(nullableListTypes); + await api.echoAllNullableTypes(listTypes); - compareAllNullableTypes(nullableListTypes, echoNullFilledClass); + compareAllNullableTypes(listTypes, echoNullFilledClass); }); testWidgets( @@ -459,16 +137,15 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - final AllNullableTypesWithoutRecursion nullableListTypes = + final AllNullableTypesWithoutRecursion listTypes = AllNullableTypesWithoutRecursion( list: ['String', null], ); final AllNullableTypesWithoutRecursion? echoNullFilledClass = - await api.echoAllNullableTypesWithoutRecursion(nullableListTypes); + await api.echoAllNullableTypesWithoutRecursion(listTypes); - compareAllNullableTypesWithoutRecursion( - nullableListTypes, echoNullFilledClass); + compareAllNullableTypesWithoutRecursion(listTypes, echoNullFilledClass); }); testWidgets( @@ -476,16 +153,15 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - final AllNullableTypesWithoutRecursion nullableListTypes = + final AllNullableTypesWithoutRecursion listTypes = AllNullableTypesWithoutRecursion( map: {'String': 'string', 'null': null}, ); final AllNullableTypesWithoutRecursion? echoNullFilledClass = - await api.echoAllNullableTypesWithoutRecursion(nullableListTypes); + await api.echoAllNullableTypesWithoutRecursion(listTypes); - compareAllNullableTypesWithoutRecursion( - nullableListTypes, echoNullFilledClass); + compareAllNullableTypesWithoutRecursion(listTypes, echoNullFilledClass); }); testWidgets('errors are returned correctly', (WidgetTester _) async { @@ -520,16 +196,10 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { testWidgets('nested objects can be sent correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - - final AllClassesWrapper sentObject = AllClassesWrapper( - allNullableTypes: recursiveAllNullableTypes, - allNullableTypesWithoutRecursion: - genericAllNullableTypesWithoutRecursion, - allTypes: genericAllTypes); - + final AllClassesWrapper classWrapper = classWrapperMaker(); final String? receivedString = - await api.extractNestedNullableString(sentObject); - expect(receivedString, sentObject.allNullableTypes.aNullableString); + await api.extractNestedNullableString(classWrapper); + expect(receivedString, classWrapper.allNullableTypes.aNullableString); }); testWidgets('nested objects can be received correctly', @@ -545,30 +215,23 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { testWidgets('nested classes can serialize and deserialize correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - - final AllClassesWrapper sentWrapper = AllClassesWrapper( - allNullableTypes: AllNullableTypes(), - allNullableTypesWithoutRecursion: AllNullableTypesWithoutRecursion(), - allTypes: genericAllTypes, - ); + final AllClassesWrapper classWrapper = classWrapperMaker(); final AllClassesWrapper receivedClassWrapper = - await api.echoClassWrapper(sentWrapper); - compareAllClassesWrapper(sentWrapper, receivedClassWrapper); + await api.echoClassWrapper(classWrapper); + compareAllClassesWrapper(classWrapper, receivedClassWrapper); }); testWidgets('nested null classes can serialize and deserialize correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final AllClassesWrapper classWrapper = classWrapperMaker(); - final AllClassesWrapper sentWrapper = AllClassesWrapper( - allNullableTypes: AllNullableTypes(), - allNullableTypesWithoutRecursion: AllNullableTypesWithoutRecursion(), - ); + classWrapper.allTypes = null; final AllClassesWrapper receivedClassWrapper = - await api.echoClassWrapper(sentWrapper); - compareAllClassesWrapper(sentWrapper, receivedClassWrapper); + await api.echoClassWrapper(classWrapper); + compareAllClassesWrapper(classWrapper, receivedClassWrapper); }); testWidgets( @@ -577,7 +240,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); const String aNullableString = 'this is a String'; const bool aNullableBool = false; - const int aNullableInt = _regularInt; + const int aNullableInt = regularInt; final AllNullableTypes echoObject = await api.sendMultipleNullableTypes( aNullableBool, aNullableInt, aNullableString); @@ -604,7 +267,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); const String aNullableString = 'this is a String'; const bool aNullableBool = false; - const int aNullableInt = _regularInt; + const int aNullableInt = regularInt; final AllNullableTypesWithoutRecursion echoObject = await api.sendMultipleNullableTypesWithoutRecursion( @@ -629,7 +292,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { testWidgets('Int serialize and deserialize correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - const int sentInt = _regularInt; + const int sentInt = regularInt; final int receivedInt = await api.echoInt(sentInt); expect(receivedInt, sentInt); }); @@ -638,7 +301,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - const int sentInt = _biggerThanBigInt; + const int sentInt = biggerThanBigInt; final int receivedInt = await api.echoInt(sentInt); expect(receivedInt, sentInt); }); @@ -699,7 +362,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { expect(receivedString, sentString); // Echo a second type as well to ensure the handling is generic. - const Object sentInt = _regularInt; + const Object sentInt = regularInt; final Object receivedInt = await api.echoObject(sentInt); expect(receivedInt, sentInt); }); @@ -708,22 +371,122 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - const List sentObject = [7, 'Hello Dart!']; - final List echoObject = await api.echoList(sentObject); - expect(listEquals(echoObject, sentObject), true); + final List echoObject = await api.echoList(list); + expect(listEquals(echoObject, list), true); + }); + + testWidgets('enum lists serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final List echoObject = await api.echoEnumList(enumList); + expect(listEquals(echoObject, enumList), true); + }); + + testWidgets('class lists serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final List echoObject = + await api.echoClassList(allNullableTypesList); + for (final (int index, AllNullableTypes? value) in echoObject.indexed) { + compareAllNullableTypes(value, allNullableTypesList[index]); + } + }); + + testWidgets('NonNull enum lists serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final List echoObject = + await api.echoNonNullEnumList(nonNullEnumList); + expect(listEquals(echoObject, nonNullEnumList), true); + }); + + testWidgets('NonNull class lists serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final List echoObject = + await api.echoNonNullClassList(nonNullAllNullableTypesList); + for (final (int index, AllNullableTypes value) in echoObject.indexed) { + compareAllNullableTypes(value, nonNullAllNullableTypesList[index]); + } }); testWidgets('maps serialize and deserialize correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map echoObject = await api.echoMap(map); + expect(mapEquals(echoObject, map), true); + }); - const Map sentObject = { - 'a': 1, - 'b': 2.3, - 'c': 'four', - }; - final Map echoObject = await api.echoMap(sentObject); - expect(mapEquals(echoObject, sentObject), true); + testWidgets('string maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map echoObject = + await api.echoStringMap(stringMap); + expect(mapEquals(echoObject, stringMap), true); + }); + + testWidgets('int maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map echoObject = await api.echoIntMap(intMap); + expect(mapEquals(echoObject, intMap), true); + }); + + testWidgets('enum maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map echoObject = await api.echoEnumMap(enumMap); + expect(mapEquals(echoObject, enumMap), true); + }); + + testWidgets('class maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map echoObject = + await api.echoClassMap(allNullableTypesMap); + for (final MapEntry entry + in echoObject.entries) { + compareAllNullableTypes(entry.value, allNullableTypesMap[entry.key]); + } + }); + + testWidgets('NonNull string maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map echoObject = + await api.echoNonNullStringMap(nonNullStringMap); + expect(mapEquals(echoObject, nonNullStringMap), true); + }); + + testWidgets('NonNull int maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map echoObject = + await api.echoNonNullIntMap(nonNullIntMap); + expect(mapEquals(echoObject, nonNullIntMap), true); + }); + + testWidgets('NonNull enum maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map echoObject = + await api.echoNonNullEnumMap(nonNullEnumMap); + expect(mapEquals(echoObject, nonNullEnumMap), true); + }); + + testWidgets('NonNull class maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map echoObject = + await api.echoNonNullClassMap(nonNullAllNullableTypesMap); + for (final MapEntry entry in echoObject.entries) { + compareAllNullableTypes( + entry.value, nonNullAllNullableTypesMap[entry.key]); + } }); testWidgets('enums serialize and deserialize correctly', @@ -735,6 +498,15 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { expect(receivedEnum, sentEnum); }); + testWidgets('enums serialize and deserialize correctly (again)', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + const AnotherEnum sentEnum = AnotherEnum.justInCase; + final AnotherEnum receivedEnum = await api.echoAnotherEnum(sentEnum); + expect(receivedEnum, sentEnum); + }); + testWidgets('multi word enums serialize and deserialize correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); @@ -747,7 +519,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { testWidgets('required named parameter', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); // This number corresponds with the default value of this method. - const int sentInt = _regularInt; + const int sentInt = regularInt; final int receivedInt = await api.echoRequiredInt(anInt: sentInt); expect(receivedInt, sentInt); }); @@ -791,7 +563,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - const int sentInt = _regularInt; + const int sentInt = regularInt; final int? receivedInt = await api.echoNullableInt(sentInt); expect(receivedInt, sentInt); }); @@ -800,7 +572,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - const int sentInt = _biggerThanBigInt; + const int sentInt = biggerThanBigInt; final int? receivedInt = await api.echoNullableInt(sentInt); expect(receivedInt, sentInt); }); @@ -903,7 +675,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { expect(receivedString, sentString); // Echo a second type as well to ensure the handling is generic. - const Object sentInt = _regularInt; + const Object sentInt = regularInt; final Object? receivedInt = await api.echoNullableObject(sentInt); expect(receivedInt, sentInt); }); @@ -920,24 +692,129 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - const List sentObject = [7, 'Hello Dart!', null]; - final List? echoObject = await api.echoNullableList(sentObject); - expect(listEquals(echoObject, sentObject), true); + final List? echoObject = await api.echoNullableList(list); + expect(listEquals(echoObject, list), true); + }); + + testWidgets('nullable enum lists serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final List? echoObject = + await api.echoNullableEnumList(enumList); + expect(listEquals(echoObject, enumList), true); + }); + + testWidgets('nullable lists serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final List? echoObject = + await api.echoNullableClassList(allNullableTypesList); + for (final (int index, AllNullableTypes? value) in echoObject!.indexed) { + compareAllNullableTypes(value, allNullableTypesList[index]); + } + }); + + testWidgets( + 'nullable NonNull enum lists serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final List? echoObject = + await api.echoNullableNonNullEnumList(nonNullEnumList); + expect(listEquals(echoObject, nonNullEnumList), true); + }); + + testWidgets('nullable NonNull lists serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final List? echoObject = + await api.echoNullableClassList(nonNullAllNullableTypesList); + for (final (int index, AllNullableTypes? value) in echoObject!.indexed) { + compareAllNullableTypes(value, nonNullAllNullableTypesList[index]); + } }); testWidgets('nullable maps serialize and deserialize correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map? echoObject = await api.echoNullableMap(map); + expect(mapEquals(echoObject, map), true); + }); - const Map sentObject = { - 'a': 1, - 'b': 2.3, - 'c': 'four', - 'd': null, - }; - final Map? echoObject = - await api.echoNullableMap(sentObject); - expect(mapEquals(echoObject, sentObject), true); + testWidgets('nullable string maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map? echoObject = + await api.echoNullableStringMap(stringMap); + expect(mapEquals(echoObject, stringMap), true); + }); + + testWidgets('nullable int maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map? echoObject = await api.echoNullableIntMap(intMap); + expect(mapEquals(echoObject, intMap), true); + }); + + testWidgets('nullable enum maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map? echoObject = + await api.echoNullableEnumMap(enumMap); + expect(mapEquals(echoObject, enumMap), true); + }); + + testWidgets('nullable class maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map? echoObject = + await api.echoNullableClassMap(allNullableTypesMap); + for (final MapEntry entry + in echoObject!.entries) { + compareAllNullableTypes(entry.value, allNullableTypesMap[entry.key]); + } + }); + + testWidgets( + 'nullable NonNull string maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map? echoObject = + await api.echoNullableNonNullStringMap(nonNullStringMap); + expect(mapEquals(echoObject, nonNullStringMap), true); + }); + + testWidgets('nullable NonNull int maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map? echoObject = + await api.echoNullableNonNullIntMap(nonNullIntMap); + expect(mapEquals(echoObject, nonNullIntMap), true); + }); + + testWidgets( + 'nullable NonNull enum maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map? echoObject = + await api.echoNullableNonNullEnumMap(nonNullEnumMap); + expect(mapEquals(echoObject, nonNullEnumMap), true); + }); + + testWidgets( + 'nullable NonNull class maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map? echoObject = + await api.echoNullableNonNullClassMap(nonNullAllNullableTypesMap); + for (final MapEntry entry + in echoObject!.entries) { + compareAllNullableTypes( + entry.value, nonNullAllNullableTypesMap[entry.key]); + } }); testWidgets('nullable enums serialize and deserialize correctly', @@ -949,6 +826,15 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { expect(echoEnum, sentEnum); }); + testWidgets('nullable enums serialize and deserialize correctly (again)', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + const AnotherEnum sentEnum = AnotherEnum.justInCase; + final AnotherEnum? echoEnum = await api.echoAnotherNullableEnum(sentEnum); + expect(echoEnum, sentEnum); + }); + testWidgets('multi word nullable enums serialize and deserialize correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); @@ -970,7 +856,24 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - final Map? echoObject = await api.echoNullableMap(null); + final Map? echoObject = await api.echoNullableMap(null); + expect(mapEquals(echoObject, null), true); + }); + + testWidgets('null string maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final Map? echoObject = + await api.echoNullableStringMap(null); + expect(mapEquals(echoObject, null), true); + }); + + testWidgets('null int maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final Map? echoObject = await api.echoNullableIntMap(null); expect(mapEquals(echoObject, null), true); }); @@ -983,6 +886,15 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { expect(echoEnum, sentEnum); }); + testWidgets('null enums serialize and deserialize correctly (again)', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + const AnotherEnum? sentEnum = null; + final AnotherEnum? echoEnum = await api.echoAnotherNullableEnum(sentEnum); + expect(echoEnum, sentEnum); + }); + testWidgets('null classes serialize and deserialize correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); @@ -995,7 +907,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { testWidgets('optional nullable parameter', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - const int sentInt = _regularInt; + const int sentInt = regularInt; final int? receivedInt = await api.echoOptionalNullableInt(sentInt); expect(receivedInt, sentInt); }); @@ -1124,7 +1036,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - const int sentInt = _regularInt; + const int sentInt = regularInt; final int receivedInt = await api.echoAsyncInt(sentInt); expect(receivedInt, sentInt); }); @@ -1133,7 +1045,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - const int sentInt = _biggerThanBigInt; + const int sentInt = biggerThanBigInt; final int receivedInt = await api.echoAsyncInt(sentInt); expect(receivedInt, sentInt); }); @@ -1196,7 +1108,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { expect(receivedString, sentString); // Echo a second type as well to ensure the handling is generic. - const Object sentInt = _regularInt; + const Object sentInt = regularInt; final Object receivedInt = await api.echoAsyncObject(sentInt); expect(receivedInt, sentInt); }); @@ -1205,23 +1117,68 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - const List sentObject = [7, 'Hello Dart!']; - final List echoObject = await api.echoAsyncList(sentObject); - expect(listEquals(echoObject, sentObject), true); + final List echoObject = await api.echoAsyncList(list); + expect(listEquals(echoObject, list), true); + }); + + testWidgets('enum lists serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final List echoObject = await api.echoAsyncEnumList(enumList); + expect(listEquals(echoObject, enumList), true); + }); + + testWidgets('class lists serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final List echoObject = + await api.echoAsyncClassList(allNullableTypesList); + for (final (int index, AllNullableTypes? value) in echoObject.indexed) { + compareAllNullableTypes(value, allNullableTypesList[index]); + } }); testWidgets('maps serialize and deserialize correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map echoObject = await api.echoAsyncMap(map); + expect(mapEquals(echoObject, map), true); + }); - const Map sentObject = { - 'a': 1, - 'b': 2.3, - 'c': 'four', - }; - final Map echoObject = - await api.echoAsyncMap(sentObject); - expect(mapEquals(echoObject, sentObject), true); + testWidgets('string maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map echoObject = + await api.echoAsyncStringMap(stringMap); + expect(mapEquals(echoObject, stringMap), true); + }); + + testWidgets('int maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map echoObject = await api.echoAsyncIntMap(intMap); + expect(mapEquals(echoObject, intMap), true); + }); + + testWidgets('enum maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map echoObject = + await api.echoAsyncEnumMap(enumMap); + expect(mapEquals(echoObject, enumMap), true); + }); + + testWidgets('class maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map echoObject = + await api.echoAsyncClassMap(allNullableTypesMap); + for (final MapEntry entry + in echoObject.entries) { + compareAllNullableTypes(entry.value, allNullableTypesMap[entry.key]); + } }); testWidgets('enums serialize and deserialize correctly', @@ -1233,6 +1190,15 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { expect(echoEnum, sentEnum); }); + testWidgets('enums serialize and deserialize correctly (again)', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + const AnotherEnum sentEnum = AnotherEnum.justInCase; + final AnotherEnum echoEnum = await api.echoAnotherAsyncEnum(sentEnum); + expect(echoEnum, sentEnum); + }); + testWidgets('multi word enums serialize and deserialize correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); @@ -1246,7 +1212,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - const int sentInt = _regularInt; + const int sentInt = regularInt; final int? receivedInt = await api.echoAsyncNullableInt(sentInt); expect(receivedInt, sentInt); }); @@ -1255,7 +1221,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - const int sentInt = _biggerThanBigInt; + const int sentInt = biggerThanBigInt; final int? receivedInt = await api.echoAsyncNullableInt(sentInt); expect(receivedInt, sentInt); }); @@ -1321,7 +1287,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { expect(receivedString, sentString); // Echo a second type as well to ensure the handling is generic. - const Object sentInt = _regularInt; + const Object sentInt = regularInt; final Object? receivedInt = await api.echoAsyncNullableObject(sentInt); expect(receivedInt, sentInt); }); @@ -1330,24 +1296,71 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - const List sentObject = [7, 'Hello Dart!']; - final List? echoObject = - await api.echoAsyncNullableList(sentObject); - expect(listEquals(echoObject, sentObject), true); + final List? echoObject = await api.echoAsyncNullableList(list); + expect(listEquals(echoObject, list), true); + }); + + testWidgets('nullable enum lists serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final List? echoObject = + await api.echoAsyncNullableEnumList(enumList); + expect(listEquals(echoObject, enumList), true); + }); + + testWidgets('nullable class lists serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final List? echoObject = + await api.echoAsyncNullableClassList(allNullableTypesList); + for (final (int index, AllNullableTypes? value) in echoObject!.indexed) { + compareAllNullableTypes(value, allNullableTypesList[index]); + } }); testWidgets('nullable maps serialize and deserialize correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map? echoObject = + await api.echoAsyncNullableMap(map); + expect(mapEquals(echoObject, map), true); + }); + + testWidgets('nullable string maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map? echoObject = + await api.echoAsyncNullableStringMap(stringMap); + expect(mapEquals(echoObject, stringMap), true); + }); - const Map sentObject = { - 'a': 1, - 'b': 2.3, - 'c': 'four', - }; - final Map? echoObject = - await api.echoAsyncNullableMap(sentObject); - expect(mapEquals(echoObject, sentObject), true); + testWidgets('nullable int maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map? echoObject = + await api.echoAsyncNullableIntMap(intMap); + expect(mapEquals(echoObject, intMap), true); + }); + + testWidgets('nullable enum maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map? echoObject = + await api.echoAsyncNullableEnumMap(enumMap); + expect(mapEquals(echoObject, enumMap), true); + }); + + testWidgets('nullable class maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map? echoObject = + await api.echoAsyncNullableClassMap(allNullableTypesMap); + for (final MapEntry entry + in echoObject!.entries) { + compareAllNullableTypes(entry.value, allNullableTypesMap[entry.key]); + } }); testWidgets('nullable enums serialize and deserialize correctly', @@ -1359,6 +1372,16 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { expect(echoEnum, sentEnum); }); + testWidgets('nullable enums serialize and deserialize correctly (again)', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + const AnotherEnum sentEnum = AnotherEnum.justInCase; + final AnotherEnum? echoEnum = + await api.echoAnotherAsyncNullableEnum(sentEnum); + expect(echoEnum, sentEnum); + }); + testWidgets('nullable enums serialize and deserialize correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); @@ -1429,19 +1452,47 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - final Map? echoObject = + final Map? echoObject = await api.echoAsyncNullableMap(null); expect(mapEquals(echoObject, null), true); }); - testWidgets('null enums serialize and deserialize correctly', + testWidgets('null string maps serialize and deserialize correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - const AnEnum? sentEnum = null; + final Map? echoObject = + await api.echoAsyncNullableStringMap(null); + expect(mapEquals(echoObject, null), true); + }); + + testWidgets('null int maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final Map? echoObject = + await api.echoAsyncNullableIntMap(null); + expect(mapEquals(echoObject, null), true); + }); + + testWidgets('null enums serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + const AnEnum? sentEnum = null; final AnEnum? echoEnum = await api.echoAsyncNullableEnum(null); expect(echoEnum, sentEnum); }); + + testWidgets('null enums serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + const AnotherEnum? sentEnum = null; + final AnotherEnum? echoEnum = + await api.echoAnotherAsyncNullableEnum(null); + expect(echoEnum, sentEnum); + }); }); group('Host API with suffix', () { @@ -1529,7 +1580,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); const String aNullableString = 'this is a String'; const bool aNullableBool = false; - const int aNullableInt = _regularInt; + const int aNullableInt = regularInt; final AllNullableTypes compositeObject = await api.callFlutterSendMultipleNullableTypes( @@ -1557,7 +1608,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); const String aNullableString = 'this is a String'; const bool aNullableBool = false; - const int aNullableInt = _regularInt; + const int aNullableInt = regularInt; final AllNullableTypesWithoutRecursion compositeObject = await api.callFlutterSendMultipleNullableTypesWithoutRecursion( @@ -1594,7 +1645,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - const int sentObject = _regularInt; + const int sentObject = regularInt; final int echoObject = await api.callFlutterEchoInt(sentObject); expect(echoObject, sentObject); }); @@ -1643,24 +1694,126 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - const List sentObject = [7, 'Hello Dart!']; - final List echoObject = - await api.callFlutterEchoList(sentObject); - expect(listEquals(echoObject, sentObject), true); + final List echoObject = await api.callFlutterEchoList(list); + expect(listEquals(echoObject, list), true); + }); + + testWidgets('enum lists serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final List echoObject = + await api.callFlutterEchoEnumList(enumList); + expect(listEquals(echoObject, enumList), true); + }); + + testWidgets('class lists serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final List echoObject = + await api.callFlutterEchoClassList(allNullableTypesList); + for (final (int index, AllNullableTypes? value) in echoObject.indexed) { + compareAllNullableTypes(value, allNullableTypesList[index]); + } + }); + + testWidgets('NonNull enum lists serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final List echoObject = + await api.callFlutterEchoNonNullEnumList(nonNullEnumList); + expect(listEquals(echoObject, nonNullEnumList), true); + }); + + testWidgets('NonNull class lists serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final List echoObject = await api + .callFlutterEchoNonNullClassList(nonNullAllNullableTypesList); + for (final (int index, AllNullableTypes? value) in echoObject.indexed) { + compareAllNullableTypes(value, nonNullAllNullableTypesList[index]); + } }); testWidgets('maps serialize and deserialize correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map echoObject = + await api.callFlutterEchoMap(map); + expect(mapEquals(echoObject, map), true); + }); - const Map sentObject = { - 'a': 1, - 'b': 2.3, - 'c': 'four', - }; - final Map echoObject = - await api.callFlutterEchoMap(sentObject); - expect(mapEquals(echoObject, sentObject), true); + testWidgets('string maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map echoObject = + await api.callFlutterEchoStringMap(stringMap); + expect(mapEquals(echoObject, stringMap), true); + }); + + testWidgets('int maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map echoObject = + await api.callFlutterEchoIntMap(intMap); + expect(mapEquals(echoObject, intMap), true); + }); + + testWidgets('enum maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map echoObject = + await api.callFlutterEchoEnumMap(enumMap); + expect(mapEquals(echoObject, enumMap), true); + }); + + testWidgets('class maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map echoObject = + await api.callFlutterEchoClassMap(allNullableTypesMap); + for (final MapEntry entry + in echoObject.entries) { + compareAllNullableTypes(entry.value, allNullableTypesMap[entry.key]); + } + }); + + testWidgets('NonNull string maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map echoObject = + await api.callFlutterEchoNonNullStringMap(nonNullStringMap); + expect(mapEquals(echoObject, nonNullStringMap), true); + }); + + testWidgets('NonNull int maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map echoObject = + await api.callFlutterEchoNonNullIntMap(nonNullIntMap); + expect(mapEquals(echoObject, nonNullIntMap), true); + }); + + testWidgets('NonNull enum maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map echoObject = + await api.callFlutterEchoNonNullEnumMap(nonNullEnumMap); + expect(mapEquals(echoObject, nonNullEnumMap), true); + }); + + testWidgets('NonNull class maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map echoObject = + await api.callFlutterEchoNonNullClassMap(nonNullAllNullableTypesMap); + for (final MapEntry entry in echoObject.entries) { + compareAllNullableTypes( + entry.value, nonNullAllNullableTypesMap[entry.key]); + } }); testWidgets('enums serialize and deserialize correctly', @@ -1672,6 +1825,16 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { expect(echoEnum, sentEnum); }); + testWidgets('enums serialize and deserialize correctly (again)', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + const AnotherEnum sentEnum = AnotherEnum.justInCase; + final AnotherEnum echoEnum = + await api.callFlutterEchoAnotherEnum(sentEnum); + expect(echoEnum, sentEnum); + }); + testWidgets('multi word enums serialize and deserialize correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); @@ -1706,7 +1869,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - const int sentObject = _regularInt; + const int sentObject = regularInt; final int? echoObject = await api.callFlutterEchoNullableInt(sentObject); expect(echoObject, sentObject); }); @@ -1715,7 +1878,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - const int sentObject = _biggerThanBigInt; + const int sentObject = biggerThanBigInt; final int? echoObject = await api.callFlutterEchoNullableInt(sentObject); expect(echoObject, sentObject); }); @@ -1798,10 +1961,51 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - const List sentObject = [7, 'Hello Dart!']; final List? echoObject = - await api.callFlutterEchoNullableList(sentObject); - expect(listEquals(echoObject, sentObject), true); + await api.callFlutterEchoNullableList(list); + expect(listEquals(echoObject, list), true); + }); + + testWidgets('nullable enum lists serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final List? echoObject = + await api.callFlutterEchoNullableEnumList(enumList); + expect(listEquals(echoObject, enumList), true); + }); + + testWidgets('nullable class lists serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final List? echoObject = + await api.callFlutterEchoNullableClassList(allNullableTypesList); + for (final (int index, AllNullableTypes? value) in echoObject!.indexed) { + compareAllNullableTypes(value, allNullableTypesList[index]); + } + }); + + testWidgets( + 'nullable NonNull enum lists serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final List? echoObject = + await api.callFlutterEchoNullableNonNullEnumList(nonNullEnumList); + expect(listEquals(echoObject, nonNullEnumList), true); + }); + + testWidgets( + 'nullable NonNull class lists serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final List? echoObject = await api + .callFlutterEchoNullableNonNullClassList(nonNullAllNullableTypesList); + for (final (int index, AllNullableTypes? value) in echoObject!.indexed) { + compareAllNullableTypes(value, nonNullAllNullableTypesList[index]); + } }); testWidgets('null lists serialize and deserialize correctly', @@ -1816,26 +2020,103 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { testWidgets('nullable maps serialize and deserialize correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - - const Map sentObject = { - 'a': 1, - 'b': 2.3, - 'c': 'four', - }; - final Map? echoObject = - await api.callFlutterEchoNullableMap(sentObject); - expect(mapEquals(echoObject, sentObject), true); + final Map? echoObject = + await api.callFlutterEchoNullableMap(map); + expect(mapEquals(echoObject, map), true); }); testWidgets('null maps serialize and deserialize correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - final Map? echoObject = + final Map? echoObject = await api.callFlutterEchoNullableMap(null); expect(mapEquals(echoObject, null), true); }); + testWidgets('nullable string maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map? echoObject = + await api.callFlutterEchoNullableStringMap(stringMap); + expect(mapEquals(echoObject, stringMap), true); + }); + + testWidgets('nullable int maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map? echoObject = + await api.callFlutterEchoNullableIntMap(intMap); + expect(mapEquals(echoObject, intMap), true); + }); + + testWidgets('nullable enum maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map? echoObject = + await api.callFlutterEchoNullableEnumMap(enumMap); + expect(mapEquals(echoObject, enumMap), true); + }); + + testWidgets('nullable class maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map? echoObject = + await api.callFlutterEchoNullableClassMap(allNullableTypesMap); + for (final MapEntry entry + in echoObject!.entries) { + compareAllNullableTypes(entry.value, allNullableTypesMap[entry.key]); + } + }); + + testWidgets( + 'nullable NonNull string maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map? echoObject = + await api.callFlutterEchoNullableNonNullStringMap(nonNullStringMap); + expect(mapEquals(echoObject, nonNullStringMap), true); + }); + + testWidgets('nullable NonNull int maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map? echoObject = + await api.callFlutterEchoNullableNonNullIntMap(nonNullIntMap); + expect(mapEquals(echoObject, nonNullIntMap), true); + }); + + testWidgets( + 'nullable NonNull enum maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map? echoObject = + await api.callFlutterEchoNullableNonNullEnumMap(nonNullEnumMap); + expect(mapEquals(echoObject, nonNullEnumMap), true); + }); + + testWidgets( + 'nullable NonNull class maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final Map? echoObject = await api + .callFlutterEchoNullableNonNullClassMap(nonNullAllNullableTypesMap); + for (final MapEntry entry + in echoObject!.entries) { + compareAllNullableTypes( + entry.value, nonNullAllNullableTypesMap[entry.key]); + } + }); + + testWidgets('null maps serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final Map? echoObject = + await api.callFlutterEchoNullableIntMap(null); + expect(mapEquals(echoObject, null), true); + }); + testWidgets('nullable enums serialize and deserialize correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); @@ -1845,6 +2126,16 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { expect(echoEnum, sentEnum); }); + testWidgets('nullable enums serialize and deserialize correctly (again)', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + const AnotherEnum sentEnum = AnotherEnum.justInCase; + final AnotherEnum? echoEnum = + await api.callFlutterEchoAnotherNullableEnum(sentEnum); + expect(echoEnum, sentEnum); + }); + testWidgets('multi word nullable enums serialize and deserialize correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); @@ -1862,6 +2153,665 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { final AnEnum? echoEnum = await api.callFlutterEchoNullableEnum(sentEnum); expect(echoEnum, sentEnum); }); + + testWidgets('null enums serialize and deserialize correctly (again)', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + const AnotherEnum? sentEnum = null; + final AnotherEnum? echoEnum = + await api.callFlutterEchoAnotherNullableEnum(sentEnum); + expect(echoEnum, sentEnum); + }); + }); + + group('Proxy API Tests', () { + if (!proxyApiSupportedLanguages.contains(targetGenerator)) { + return; + } + + testWidgets('noop', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + await expectLater(api.noop(), completes); + }); + + testWidgets('throwError', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + await expectLater( + () => api.throwError(), + throwsA(isA()), + ); + }); + + testWidgets('throwErrorFromVoid', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + await expectLater( + () => api.throwErrorFromVoid(), + throwsA(isA()), + ); + }); + + testWidgets('throwFlutterError', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + await expectLater( + () => api.throwFlutterError(), + throwsA( + (dynamic e) { + return e is PlatformException && + e.code == 'code' && + e.message == 'message' && + e.details == 'details'; + }, + ), + ); + }); + + testWidgets('echoInt', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + const int value = 0; + expect(await api.echoInt(value), value); + }); + + testWidgets('echoDouble', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + const double value = 0.0; + expect(await api.echoDouble(value), value); + }); + + testWidgets('echoBool', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + const bool value = true; + expect(await api.echoBool(value), value); + }); + + testWidgets('echoString', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + const String value = 'string'; + expect(await api.echoString(value), value); + }); + + testWidgets('echoUint8List', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + final Uint8List value = Uint8List(0); + expect(await api.echoUint8List(value), value); + }); + + testWidgets('echoObject', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + const Object value = 'apples'; + expect(await api.echoObject(value), value); + }); + + testWidgets('echoList', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + const List value = [1, 2]; + expect(await api.echoList(value), value); + }); + + testWidgets('echoProxyApiList', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + final List value = [ + _createGenericProxyApiTestClass(), + _createGenericProxyApiTestClass(), + ]; + expect(await api.echoProxyApiList(value), value); + }); + + testWidgets('echoMap', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + const Map value = {'apple': 'pie'}; + expect(await api.echoMap(value), value); + }); + + testWidgets('echoProxyApiMap', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + final Map value = { + '42': _createGenericProxyApiTestClass(), + }; + expect(await api.echoProxyApiMap(value), value); + }); + + testWidgets('echoEnum', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + const ProxyApiTestEnum value = ProxyApiTestEnum.three; + expect(await api.echoEnum(value), value); + }); + + testWidgets('echoProxyApi', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + final ProxyApiSuperClass value = ProxyApiSuperClass(); + expect(await api.echoProxyApi(value), value); + }); + + testWidgets('echoNullableInt', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + expect(await api.echoNullableInt(null), null); + expect(await api.echoNullableInt(1), 1); + }); + + testWidgets('echoNullableDouble', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + expect(await api.echoNullableDouble(null), null); + expect(await api.echoNullableDouble(1.0), 1.0); + }); + + testWidgets('echoNullableBool', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + expect(await api.echoNullableBool(null), null); + expect(await api.echoNullableBool(false), false); + }); + + testWidgets('echoNullableString', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + expect(await api.echoNullableString(null), null); + expect(await api.echoNullableString('aString'), 'aString'); + }); + + testWidgets('echoNullableUint8List', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + expect(await api.echoNullableUint8List(null), null); + expect(await api.echoNullableUint8List(Uint8List(0)), Uint8List(0)); + }); + + testWidgets('echoNullableObject', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + expect(await api.echoNullableObject(null), null); + expect(await api.echoNullableObject('aString'), 'aString'); + }); + + testWidgets('echoNullableList', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + expect(await api.echoNullableList(null), null); + expect(await api.echoNullableList([1]), [1]); + }); + + testWidgets('echoNullableMap', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + expect(await api.echoNullableMap(null), null); + expect( + await api.echoNullableMap({'value': 1}), + {'value': 1}, + ); + }); + + testWidgets('echoNullableEnum', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + expect(await api.echoNullableEnum(null), null); + expect( + await api.echoNullableEnum(ProxyApiTestEnum.one), + ProxyApiTestEnum.one, + ); + }); + + testWidgets('echoNullableProxyApi', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + expect(await api.echoNullableProxyApi(null), null); + + final ProxyApiSuperClass proxyApi = ProxyApiSuperClass(); + expect( + await api.echoNullableProxyApi(proxyApi), + proxyApi, + ); + }); + + testWidgets('noopAsync', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + await expectLater(api.noopAsync(), completes); + }); + + testWidgets('echoAsyncInt', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + const int value = 0; + expect(await api.echoAsyncInt(value), value); + }); + + testWidgets('echoAsyncDouble', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + const double value = 0.0; + expect(await api.echoAsyncDouble(value), value); + }); + + testWidgets('echoAsyncBool', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + const bool value = false; + expect(await api.echoAsyncBool(value), value); + }); + + testWidgets('echoAsyncString', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + const String value = 'ping'; + expect(await api.echoAsyncString(value), value); + }); + + testWidgets('echoAsyncUint8List', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + final Uint8List value = Uint8List(0); + expect(await api.echoAsyncUint8List(value), value); + }); + + testWidgets('echoAsyncObject', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + const Object value = 0; + expect(await api.echoAsyncObject(value), value); + }); + + testWidgets('echoAsyncList', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + const List value = ['apple', 'pie']; + expect(await api.echoAsyncList(value), value); + }); + + testWidgets('echoAsyncMap', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + final Map value = { + 'something': ProxyApiSuperClass(), + }; + expect(await api.echoAsyncMap(value), value); + }); + + testWidgets('echoAsyncEnum', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + const ProxyApiTestEnum value = ProxyApiTestEnum.two; + expect(await api.echoAsyncEnum(value), value); + }); + + testWidgets('throwAsyncError', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + await expectLater( + () => api.throwAsyncError(), + throwsA(isA()), + ); + }); + + testWidgets('throwAsyncErrorFromVoid', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + await expectLater( + () => api.throwAsyncErrorFromVoid(), + throwsA(isA()), + ); + }); + + testWidgets('throwAsyncFlutterError', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + + await expectLater( + () => api.throwAsyncFlutterError(), + throwsA( + (dynamic e) { + return e is PlatformException && + e.code == 'code' && + e.message == 'message' && + e.details == 'details'; + }, + ), + ); + }); + + testWidgets('echoAsyncNullableInt', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + expect(await api.echoAsyncNullableInt(null), null); + expect(await api.echoAsyncNullableInt(1), 1); + }); + + testWidgets('echoAsyncNullableDouble', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + expect(await api.echoAsyncNullableDouble(null), null); + expect(await api.echoAsyncNullableDouble(2.0), 2.0); + }); + + testWidgets('echoAsyncNullableBool', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + expect(await api.echoAsyncNullableBool(null), null); + expect(await api.echoAsyncNullableBool(true), true); + }); + + testWidgets('echoAsyncNullableString', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + expect(await api.echoAsyncNullableString(null), null); + expect(await api.echoAsyncNullableString('aString'), 'aString'); + }); + + testWidgets('echoAsyncNullableUint8List', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + expect(await api.echoAsyncNullableUint8List(null), null); + expect( + await api.echoAsyncNullableUint8List(Uint8List(0)), + Uint8List(0), + ); + }); + + testWidgets('echoAsyncNullableObject', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + expect(await api.echoAsyncNullableObject(null), null); + expect(await api.echoAsyncNullableObject(1), 1); + }); + + testWidgets('echoAsyncNullableList', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + expect(await api.echoAsyncNullableList(null), null); + expect(await api.echoAsyncNullableList([1]), [1]); + }); + + testWidgets('echoAsyncNullableMap', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + expect(await api.echoAsyncNullableMap(null), null); + expect( + await api.echoAsyncNullableMap({'banana': 1}), + {'banana': 1}, + ); + }); + + testWidgets('echoAsyncNullableEnum', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass(); + expect(await api.echoAsyncNullableEnum(null), null); + expect( + await api.echoAsyncNullableEnum(ProxyApiTestEnum.one), + ProxyApiTestEnum.one, + ); + }); + + testWidgets('staticNoop', (_) async { + await expectLater(ProxyApiTestClass.staticNoop(), completes); + }); + + testWidgets('echoStaticString', (_) async { + const String value = 'static string'; + expect(await ProxyApiTestClass.echoStaticString(value), value); + }); + + testWidgets('staticAsyncNoop', (_) async { + await expectLater(ProxyApiTestClass.staticAsyncNoop(), completes); + }); + + testWidgets('callFlutterNoop', (_) async { + bool called = false; + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterNoop: (ProxyApiTestClass instance) async { + called = true; + }, + ); + + await api.callFlutterNoop(); + expect(called, isTrue); + }); + + testWidgets('callFlutterThrowError', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterThrowError: (_) { + throw FlutterError('this is an error'); + }, + ); + + await expectLater( + api.callFlutterThrowError(), + throwsA( + isA().having( + (PlatformException exception) => exception.message, + 'message', + equals('this is an error'), + ), + ), + ); + }); + + testWidgets('callFlutterThrowErrorFromVoid', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterThrowErrorFromVoid: (_) { + throw FlutterError('this is an error'); + }, + ); + + await expectLater( + api.callFlutterThrowErrorFromVoid(), + throwsA( + isA().having( + (PlatformException exception) => exception.message, + 'message', + equals('this is an error'), + ), + ), + ); + }); + + testWidgets('callFlutterEchoBool', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterEchoBool: (_, bool aBool) => aBool, + ); + + const bool value = true; + expect(await api.callFlutterEchoBool(value), value); + }); + + testWidgets('callFlutterEchoInt', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterEchoInt: (_, int anInt) => anInt, + ); + + const int value = 0; + expect(await api.callFlutterEchoInt(value), value); + }); + + testWidgets('callFlutterEchoDouble', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterEchoDouble: (_, double aDouble) => aDouble, + ); + + const double value = 0.0; + expect(await api.callFlutterEchoDouble(value), value); + }); + + testWidgets('callFlutterEchoString', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterEchoString: (_, String aString) => aString, + ); + + const String value = 'a string'; + expect(await api.callFlutterEchoString(value), value); + }); + + testWidgets('callFlutterEchoUint8List', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterEchoUint8List: (_, Uint8List aUint8List) => aUint8List, + ); + + final Uint8List value = Uint8List(0); + expect(await api.callFlutterEchoUint8List(value), value); + }); + + testWidgets('callFlutterEchoList', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterEchoList: (_, List aList) => aList, + ); + + final List value = [0, 0.0, true, ProxyApiSuperClass()]; + expect(await api.callFlutterEchoList(value), value); + }); + + testWidgets('callFlutterEchoProxyApiList', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterEchoProxyApiList: (_, List aList) => aList, + ); + + final List value = [ + _createGenericProxyApiTestClass(), + ]; + expect(await api.callFlutterEchoProxyApiList(value), value); + }); + + testWidgets('callFlutterEchoMap', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterEchoMap: (_, Map aMap) => aMap, + ); + + final Map value = { + 'a String': 4, + }; + expect(await api.callFlutterEchoMap(value), value); + }); + + testWidgets('callFlutterEchoProxyApiMap', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterEchoProxyApiMap: (_, Map aMap) => + aMap, + ); + + final Map value = + { + 'a String': _createGenericProxyApiTestClass(), + }; + expect(await api.callFlutterEchoProxyApiMap(value), value); + }); + + testWidgets('callFlutterEchoEnum', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterEchoEnum: (_, ProxyApiTestEnum anEnum) => anEnum, + ); + + const ProxyApiTestEnum value = ProxyApiTestEnum.three; + expect(await api.callFlutterEchoEnum(value), value); + }); + + testWidgets('callFlutterEchoProxyApi', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterEchoProxyApi: (_, ProxyApiSuperClass aProxyApi) => aProxyApi, + ); + + final ProxyApiSuperClass value = ProxyApiSuperClass(); + expect(await api.callFlutterEchoProxyApi(value), value); + }); + + testWidgets('callFlutterEchoNullableBool', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterEchoNullableBool: (_, bool? aBool) => aBool, + ); + expect(await api.callFlutterEchoNullableBool(null), null); + expect(await api.callFlutterEchoNullableBool(true), true); + }); + + testWidgets('callFlutterEchoNullableInt', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterEchoNullableInt: (_, int? anInt) => anInt, + ); + expect(await api.callFlutterEchoNullableInt(null), null); + expect(await api.callFlutterEchoNullableInt(1), 1); + }); + + testWidgets('callFlutterEchoNullableDouble', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterEchoNullableDouble: (_, double? aDouble) => aDouble, + ); + expect(await api.callFlutterEchoNullableDouble(null), null); + expect(await api.callFlutterEchoNullableDouble(1.0), 1.0); + }); + + testWidgets('callFlutterEchoNullableString', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterEchoNullableString: (_, String? aString) => aString, + ); + expect(await api.callFlutterEchoNullableString(null), null); + expect(await api.callFlutterEchoNullableString('aString'), 'aString'); + }); + + testWidgets('callFlutterEchoNullableUint8List', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterEchoNullableUint8List: (_, Uint8List? aUint8List) => aUint8List, + ); + expect(await api.callFlutterEchoNullableUint8List(null), null); + expect( + await api.callFlutterEchoNullableUint8List(Uint8List(0)), + Uint8List(0), + ); + }); + + testWidgets('callFlutterEchoNullableList', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterEchoNullableList: (_, List? aList) => aList, + ); + expect(await api.callFlutterEchoNullableList(null), null); + expect(await api.callFlutterEchoNullableList([0]), [0]); + }); + + testWidgets('callFlutterEchoNullableMap', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterEchoNullableMap: (_, Map? aMap) => aMap, + ); + expect(await api.callFlutterEchoNullableMap(null), null); + expect( + await api.callFlutterEchoNullableMap({'str': 0}), + {'str': 0}, + ); + }); + + testWidgets('callFlutterEchoNullableEnum', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterEchoNullableEnum: (_, ProxyApiTestEnum? anEnum) => anEnum, + ); + expect(await api.callFlutterEchoNullableEnum(null), null); + expect( + await api.callFlutterEchoNullableEnum(ProxyApiTestEnum.two), + ProxyApiTestEnum.two, + ); + }); + + testWidgets('callFlutterEchoNullableProxyApi', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterEchoNullableProxyApi: (_, ProxyApiSuperClass? aProxyApi) => + aProxyApi, + ); + + expect(await api.callFlutterEchoNullableProxyApi(null), null); + + final ProxyApiSuperClass proxyApi = ProxyApiSuperClass(); + expect(await api.callFlutterEchoNullableProxyApi(proxyApi), proxyApi); + }); + + testWidgets('callFlutterNoopAsync', (_) async { + bool called = false; + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterNoopAsync: (ProxyApiTestClass instance) async { + called = true; + }, + ); + + await api.callFlutterNoopAsync(); + expect(called, isTrue); + }); + + testWidgets('callFlutterEchoAsyncString', (_) async { + final ProxyApiTestClass api = _createGenericProxyApiTestClass( + flutterEchoAsyncString: (_, String aString) async => aString, + ); + + const String value = 'a string'; + expect(await api.callFlutterEchoAsyncString(value), value); + }); }); group('Flutter API with suffix', () { @@ -1885,6 +2835,11 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { expect(echoObject, sentObject); }); }); + + testWidgets('Unused data class still generate', (_) async { + final UnusedClass unused = UnusedClass(); + expect(unused, unused); + }); } class _FlutterApiTestImplementation implements FlutterIntegrationCoreApi { @@ -1954,11 +2909,64 @@ class _FlutterApiTestImplementation implements FlutterIntegrationCoreApi { List echoList(List list) => list; @override - Map echoMap(Map aMap) => aMap; + List echoEnumList(List enumList) => enumList; + + @override + List echoClassList(List classList) { + return classList; + } + + @override + List echoNonNullEnumList(List enumList) => enumList; + + @override + List echoNonNullClassList( + List classList) { + return classList; + } + + @override + Map echoMap(Map map) => map; + + @override + Map echoStringMap(Map stringMap) => + stringMap; + + @override + Map echoIntMap(Map intMap) => intMap; + + @override + Map echoEnumMap(Map enumMap) => enumMap; + + @override + Map echoClassMap( + Map classMap) { + return classMap; + } + + @override + Map echoNonNullStringMap(Map stringMap) => + stringMap; + + @override + Map echoNonNullIntMap(Map intMap) => intMap; + + @override + Map echoNonNullEnumMap(Map enumMap) => + enumMap; + + @override + Map echoNonNullClassMap( + Map classMap) { + return classMap; + } @override AnEnum echoEnum(AnEnum anEnum) => anEnum; + @override + AnotherEnum echoAnotherEnum(AnotherEnum anotherEnum) => anotherEnum; + @override bool? echoNullableBool(bool? aBool) => aBool; @@ -1972,7 +2980,70 @@ class _FlutterApiTestImplementation implements FlutterIntegrationCoreApi { List? echoNullableList(List? list) => list; @override - Map? echoNullableMap(Map? aMap) => aMap; + List? echoNullableEnumList(List? enumList) => enumList; + + @override + List? echoNullableClassList( + List? classList) { + return classList; + } + + @override + List? echoNullableNonNullEnumList(List? enumList) { + return enumList; + } + + @override + List? echoNullableNonNullClassList( + List? classList) { + return classList; + } + + @override + Map? echoNullableMap(Map? map) => map; + + @override + Map? echoNullableStringMap( + Map? stringMap) { + return stringMap; + } + + @override + Map? echoNullableIntMap(Map? intMap) => intMap; + + @override + Map? echoNullableEnumMap(Map? enumMap) { + return enumMap; + } + + @override + Map? echoNullableClassMap( + Map? classMap) { + return classMap; + } + + @override + Map? echoNullableNonNullStringMap( + Map? stringMap) { + return stringMap; + } + + @override + Map? echoNullableNonNullIntMap(Map? intMap) { + return intMap; + } + + @override + Map? echoNullableNonNullEnumMap( + Map? enumMap) { + return enumMap; + } + + @override + Map? echoNullableNonNullClassMap( + Map? classMap) { + return classMap; + } @override String? echoNullableString(String? aString) => aString; @@ -1983,6 +3054,9 @@ class _FlutterApiTestImplementation implements FlutterIntegrationCoreApi { @override AnEnum? echoNullableEnum(AnEnum? anEnum) => anEnum; + @override + AnotherEnum? echoAnotherNullableEnum(AnotherEnum? anotherEnum) => anotherEnum; + @override Future noopAsync() async {} @@ -2003,3 +3077,142 @@ class _SmallFlutterApi implements FlutterSmallApi { return msg; } } + +ProxyApiTestClass _createGenericProxyApiTestClass({ + void Function(ProxyApiTestClass instance)? flutterNoop, + Object? Function(ProxyApiTestClass instance)? flutterThrowError, + void Function( + ProxyApiTestClass instance, + )? flutterThrowErrorFromVoid, + bool Function( + ProxyApiTestClass instance, + bool aBool, + )? flutterEchoBool, + int Function( + ProxyApiTestClass instance, + int anInt, + )? flutterEchoInt, + double Function( + ProxyApiTestClass instance, + double aDouble, + )? flutterEchoDouble, + String Function( + ProxyApiTestClass instance, + String aString, + )? flutterEchoString, + Uint8List Function( + ProxyApiTestClass instance, + Uint8List aList, + )? flutterEchoUint8List, + List Function( + ProxyApiTestClass instance, + List aList, + )? flutterEchoList, + List Function( + ProxyApiTestClass instance, + List aList, + )? flutterEchoProxyApiList, + Map Function( + ProxyApiTestClass instance, + Map aMap, + )? flutterEchoMap, + Map Function( + ProxyApiTestClass instance, + Map aMap, + )? flutterEchoProxyApiMap, + ProxyApiTestEnum Function( + ProxyApiTestClass instance, + ProxyApiTestEnum anEnum, + )? flutterEchoEnum, + ProxyApiSuperClass Function( + ProxyApiTestClass instance, + ProxyApiSuperClass aProxyApi, + )? flutterEchoProxyApi, + bool? Function( + ProxyApiTestClass instance, + bool? aBool, + )? flutterEchoNullableBool, + int? Function( + ProxyApiTestClass instance, + int? anInt, + )? flutterEchoNullableInt, + double? Function( + ProxyApiTestClass instance, + double? aDouble, + )? flutterEchoNullableDouble, + String? Function( + ProxyApiTestClass instance, + String? aString, + )? flutterEchoNullableString, + Uint8List? Function( + ProxyApiTestClass instance, + Uint8List? aList, + )? flutterEchoNullableUint8List, + List? Function( + ProxyApiTestClass instance, + List? aList, + )? flutterEchoNullableList, + Map? Function( + ProxyApiTestClass instance, + Map? aMap, + )? flutterEchoNullableMap, + ProxyApiTestEnum? Function( + ProxyApiTestClass instance, + ProxyApiTestEnum? anEnum, + )? flutterEchoNullableEnum, + ProxyApiSuperClass? Function( + ProxyApiTestClass instance, + ProxyApiSuperClass? aProxyApi, + )? flutterEchoNullableProxyApi, + Future Function(ProxyApiTestClass instance)? flutterNoopAsync, + Future Function( + ProxyApiTestClass instance, + String aString, + )? flutterEchoAsyncString, +}) { + return ProxyApiTestClass( + aBool: true, + anInt: 0, + aDouble: 0.0, + aString: '', + aUint8List: Uint8List(0), + aList: const [], + aMap: const {}, + anEnum: ProxyApiTestEnum.one, + aProxyApi: ProxyApiSuperClass(), + boolParam: true, + intParam: 0, + doubleParam: 0.0, + stringParam: '', + aUint8ListParam: Uint8List(0), + listParam: const [], + mapParam: const {}, + enumParam: ProxyApiTestEnum.one, + proxyApiParam: ProxyApiSuperClass(), + flutterNoop: flutterNoop, + flutterThrowError: flutterThrowError, + flutterThrowErrorFromVoid: flutterThrowErrorFromVoid, + flutterEchoBool: flutterEchoBool, + flutterEchoInt: flutterEchoInt, + flutterEchoDouble: flutterEchoDouble, + flutterEchoString: flutterEchoString, + flutterEchoUint8List: flutterEchoUint8List, + flutterEchoList: flutterEchoList, + flutterEchoProxyApiList: flutterEchoProxyApiList, + flutterEchoMap: flutterEchoMap, + flutterEchoProxyApiMap: flutterEchoProxyApiMap, + flutterEchoEnum: flutterEchoEnum, + flutterEchoProxyApi: flutterEchoProxyApi, + flutterEchoNullableBool: flutterEchoNullableBool, + flutterEchoNullableInt: flutterEchoNullableInt, + flutterEchoNullableDouble: flutterEchoNullableDouble, + flutterEchoNullableString: flutterEchoNullableString, + flutterEchoNullableUint8List: flutterEchoNullableUint8List, + flutterEchoNullableList: flutterEchoNullableList, + flutterEchoNullableMap: flutterEchoNullableMap, + flutterEchoNullableEnum: flutterEchoNullableEnum, + flutterEchoNullableProxyApi: flutterEchoNullableProxyApi, + flutterNoopAsync: flutterNoopAsync, + flutterEchoAsyncString: flutterEchoAsyncString, + ); +} diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/background_platform_channels.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/background_platform_channels.gen.dart index e9e063126c1a..3bcbaaff4703 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/background_platform_channels.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/background_platform_channels.gen.dart @@ -21,6 +21,23 @@ PlatformException _createConnectionError(String channelName) { class _PigeonCodec extends StandardMessageCodec { const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + default: + return super.readValueOfType(type, buffer); + } + } } class BackgroundApi2Host { @@ -29,41 +46,41 @@ class BackgroundApi2Host { /// BinaryMessenger will be used which routes to the host platform. BackgroundApi2Host( {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : __pigeon_binaryMessenger = binaryMessenger, - __pigeon_messageChannelSuffix = + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; - final BinaryMessenger? __pigeon_binaryMessenger; + final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - final String __pigeon_messageChannelSuffix; + final String pigeonVar_messageChannelSuffix; Future add(int x, int y) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.BackgroundApi2Host.add$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.BackgroundApi2Host.add$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([x, y]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([x, y]) 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 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 int?)!; + return (pigeonVar_replyList[0] as int?)!; } } } diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart index e192a84ceea1..234361ada5ae 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart @@ -38,6 +38,31 @@ enum AnEnum { fourHundredTwentyTwo, } +enum AnotherEnum { + justInCase, +} + +class UnusedClass { + UnusedClass({ + this.aField, + }); + + Object? aField; + + Object encode() { + return [ + aField, + ]; + } + + static UnusedClass decode(Object result) { + result as List; + return UnusedClass( + aField: result[0], + ); + } +} + /// A class containing all supported types. class AllTypes { AllTypes({ @@ -50,6 +75,7 @@ class AllTypes { required this.a8ByteArray, required this.aFloatArray, this.anEnum = AnEnum.one, + this.anotherEnum = AnotherEnum.justInCase, this.aString = '', this.anObject = 0, required this.list, @@ -57,7 +83,17 @@ class AllTypes { required this.intList, required this.doubleList, required this.boolList, + required this.enumList, + required this.objectList, + required this.listList, + required this.mapList, required this.map, + required this.stringMap, + required this.intMap, + required this.enumMap, + required this.objectMap, + required this.listMap, + required this.mapMap, }); bool aBool; @@ -78,22 +114,44 @@ class AllTypes { AnEnum anEnum; + AnotherEnum anotherEnum; + String aString; Object anObject; List list; - List stringList; + List stringList; - List intList; + List intList; - List doubleList; + List doubleList; - List boolList; + List boolList; + + List enumList; + + List objectList; + + List> listList; + + List> mapList; Map map; + Map stringMap; + + Map intMap; + + Map enumMap; + + Map objectMap; + + Map> listMap; + + Map> mapMap; + Object encode() { return [ aBool, @@ -105,6 +163,7 @@ class AllTypes { a8ByteArray, aFloatArray, anEnum, + anotherEnum, aString, anObject, list, @@ -112,7 +171,17 @@ class AllTypes { intList, doubleList, boolList, + enumList, + objectList, + listList, + mapList, map, + stringMap, + intMap, + enumMap, + objectMap, + listMap, + mapMap, ]; } @@ -128,14 +197,27 @@ class AllTypes { a8ByteArray: result[6]! as Int64List, aFloatArray: result[7]! as Float64List, anEnum: result[8]! as AnEnum, - aString: result[9]! as String, - anObject: result[10]!, - list: result[11]! as List, - stringList: (result[12] as List?)!.cast(), - intList: (result[13] as List?)!.cast(), - doubleList: (result[14] as List?)!.cast(), - boolList: (result[15] as List?)!.cast(), - map: result[16]! as Map, + anotherEnum: result[9]! as AnotherEnum, + aString: result[10]! as String, + anObject: result[11]!, + list: result[12]! as List, + stringList: (result[13] as List?)!.cast(), + intList: (result[14] as List?)!.cast(), + doubleList: (result[15] as List?)!.cast(), + boolList: (result[16] as List?)!.cast(), + enumList: (result[17] as List?)!.cast(), + objectList: (result[18] as List?)!.cast(), + listList: (result[19] as List?)!.cast>(), + mapList: (result[20] as List?)!.cast>(), + map: result[21]! as Map, + stringMap: (result[22] as Map?)!.cast(), + intMap: (result[23] as Map?)!.cast(), + enumMap: (result[24] as Map?)!.cast(), + objectMap: (result[25] as Map?)!.cast(), + listMap: + (result[26] as Map?)!.cast>(), + mapMap: (result[27] as Map?)! + .cast>(), ); } } @@ -151,10 +233,8 @@ class AllNullableTypes { this.aNullable4ByteArray, this.aNullable8ByteArray, this.aNullableFloatArray, - this.nullableNestedList, - this.nullableMapWithAnnotations, - this.nullableMapWithObject, this.aNullableEnum, + this.anotherNullableEnum, this.aNullableString, this.aNullableObject, this.allNullableTypes, @@ -163,8 +243,19 @@ class AllNullableTypes { this.intList, this.doubleList, this.boolList, - this.nestedClassList, + this.enumList, + this.objectList, + this.listList, + this.mapList, + this.recursiveClassList, this.map, + this.stringMap, + this.intMap, + this.enumMap, + this.objectMap, + this.listMap, + this.mapMap, + this.recursiveClassMap, }); bool? aNullableBool; @@ -183,14 +274,10 @@ class AllNullableTypes { Float64List? aNullableFloatArray; - List?>? nullableNestedList; - - Map? nullableMapWithAnnotations; - - Map? nullableMapWithObject; - AnEnum? aNullableEnum; + AnotherEnum? anotherNullableEnum; + String? aNullableString; Object? aNullableObject; @@ -207,10 +294,32 @@ class AllNullableTypes { List? boolList; - List? nestedClassList; + List? enumList; + + List? objectList; + + List?>? listList; + + List?>? mapList; + + List? recursiveClassList; Map? map; + Map? stringMap; + + Map? intMap; + + Map? enumMap; + + Map? objectMap; + + Map?>? listMap; + + Map?>? mapMap; + + Map? recursiveClassMap; + Object encode() { return [ aNullableBool, @@ -221,10 +330,8 @@ class AllNullableTypes { aNullable4ByteArray, aNullable8ByteArray, aNullableFloatArray, - nullableNestedList, - nullableMapWithAnnotations, - nullableMapWithObject, aNullableEnum, + anotherNullableEnum, aNullableString, aNullableObject, allNullableTypes, @@ -233,8 +340,19 @@ class AllNullableTypes { intList, doubleList, boolList, - nestedClassList, + enumList, + objectList, + listList, + mapList, + recursiveClassList, map, + stringMap, + intMap, + enumMap, + objectMap, + listMap, + mapMap, + recursiveClassMap, ]; } @@ -249,23 +367,35 @@ class AllNullableTypes { aNullable4ByteArray: result[5] as Int32List?, aNullable8ByteArray: result[6] as Int64List?, aNullableFloatArray: result[7] as Float64List?, - nullableNestedList: (result[8] as List?)?.cast?>(), - nullableMapWithAnnotations: - (result[9] as Map?)?.cast(), - nullableMapWithObject: - (result[10] as Map?)?.cast(), - aNullableEnum: result[11] as AnEnum?, - aNullableString: result[12] as String?, - aNullableObject: result[13], - allNullableTypes: result[14] as AllNullableTypes?, - list: result[15] as List?, - stringList: (result[16] as List?)?.cast(), - intList: (result[17] as List?)?.cast(), - doubleList: (result[18] as List?)?.cast(), - boolList: (result[19] as List?)?.cast(), - nestedClassList: - (result[20] as List?)?.cast(), - map: result[21] as Map?, + aNullableEnum: result[8] as AnEnum?, + anotherNullableEnum: result[9] as AnotherEnum?, + aNullableString: result[10] as String?, + aNullableObject: result[11], + allNullableTypes: result[12] as AllNullableTypes?, + list: result[13] as List?, + stringList: (result[14] as List?)?.cast(), + intList: (result[15] as List?)?.cast(), + doubleList: (result[16] as List?)?.cast(), + boolList: (result[17] as List?)?.cast(), + enumList: (result[18] as List?)?.cast(), + objectList: (result[19] as List?)?.cast(), + listList: (result[20] as List?)?.cast?>(), + mapList: (result[21] as List?)?.cast?>(), + recursiveClassList: + (result[22] as List?)?.cast(), + map: result[23] as Map?, + stringMap: + (result[24] as Map?)?.cast(), + intMap: (result[25] as Map?)?.cast(), + enumMap: (result[26] as Map?)?.cast(), + objectMap: + (result[27] as Map?)?.cast(), + listMap: + (result[28] as Map?)?.cast?>(), + mapMap: (result[29] as Map?) + ?.cast?>(), + recursiveClassMap: (result[30] as Map?) + ?.cast(), ); } } @@ -283,10 +413,8 @@ class AllNullableTypesWithoutRecursion { this.aNullable4ByteArray, this.aNullable8ByteArray, this.aNullableFloatArray, - this.nullableNestedList, - this.nullableMapWithAnnotations, - this.nullableMapWithObject, this.aNullableEnum, + this.anotherNullableEnum, this.aNullableString, this.aNullableObject, this.list, @@ -294,7 +422,17 @@ class AllNullableTypesWithoutRecursion { this.intList, this.doubleList, this.boolList, + this.enumList, + this.objectList, + this.listList, + this.mapList, this.map, + this.stringMap, + this.intMap, + this.enumMap, + this.objectMap, + this.listMap, + this.mapMap, }); bool? aNullableBool; @@ -313,14 +451,10 @@ class AllNullableTypesWithoutRecursion { Float64List? aNullableFloatArray; - List?>? nullableNestedList; - - Map? nullableMapWithAnnotations; - - Map? nullableMapWithObject; - AnEnum? aNullableEnum; + AnotherEnum? anotherNullableEnum; + String? aNullableString; Object? aNullableObject; @@ -335,8 +469,28 @@ class AllNullableTypesWithoutRecursion { List? boolList; + List? enumList; + + List? objectList; + + List?>? listList; + + List?>? mapList; + Map? map; + Map? stringMap; + + Map? intMap; + + Map? enumMap; + + Map? objectMap; + + Map?>? listMap; + + Map?>? mapMap; + Object encode() { return [ aNullableBool, @@ -347,10 +501,8 @@ class AllNullableTypesWithoutRecursion { aNullable4ByteArray, aNullable8ByteArray, aNullableFloatArray, - nullableNestedList, - nullableMapWithAnnotations, - nullableMapWithObject, aNullableEnum, + anotherNullableEnum, aNullableString, aNullableObject, list, @@ -358,7 +510,17 @@ class AllNullableTypesWithoutRecursion { intList, doubleList, boolList, + enumList, + objectList, + listList, + mapList, map, + stringMap, + intMap, + enumMap, + objectMap, + listMap, + mapMap, ]; } @@ -373,20 +535,30 @@ class AllNullableTypesWithoutRecursion { aNullable4ByteArray: result[5] as Int32List?, aNullable8ByteArray: result[6] as Int64List?, aNullableFloatArray: result[7] as Float64List?, - nullableNestedList: (result[8] as List?)?.cast?>(), - nullableMapWithAnnotations: - (result[9] as Map?)?.cast(), - nullableMapWithObject: - (result[10] as Map?)?.cast(), - aNullableEnum: result[11] as AnEnum?, - aNullableString: result[12] as String?, - aNullableObject: result[13], - list: result[14] as List?, - stringList: (result[15] as List?)?.cast(), - intList: (result[16] as List?)?.cast(), - doubleList: (result[17] as List?)?.cast(), - boolList: (result[18] as List?)?.cast(), - map: result[19] as Map?, + aNullableEnum: result[8] as AnEnum?, + anotherNullableEnum: result[9] as AnotherEnum?, + aNullableString: result[10] as String?, + aNullableObject: result[11], + list: result[12] as List?, + stringList: (result[13] as List?)?.cast(), + intList: (result[14] as List?)?.cast(), + doubleList: (result[15] as List?)?.cast(), + boolList: (result[16] as List?)?.cast(), + enumList: (result[17] as List?)?.cast(), + objectList: (result[18] as List?)?.cast(), + listList: (result[19] as List?)?.cast?>(), + mapList: (result[20] as List?)?.cast?>(), + map: result[21] as Map?, + stringMap: + (result[22] as Map?)?.cast(), + intMap: (result[23] as Map?)?.cast(), + enumMap: (result[24] as Map?)?.cast(), + objectMap: + (result[25] as Map?)?.cast(), + listMap: + (result[26] as Map?)?.cast?>(), + mapMap: (result[27] as Map?) + ?.cast?>(), ); } } @@ -401,6 +573,10 @@ class AllClassesWrapper { required this.allNullableTypes, this.allNullableTypesWithoutRecursion, this.allTypes, + required this.classList, + this.nullableClassList, + required this.classMap, + this.nullableClassMap, }); AllNullableTypes allNullableTypes; @@ -409,11 +585,23 @@ class AllClassesWrapper { AllTypes? allTypes; + List classList; + + List? nullableClassList; + + Map classMap; + + Map? nullableClassMap; + Object encode() { return [ allNullableTypes, allNullableTypesWithoutRecursion, allTypes, + classList, + nullableClassList, + classMap, + nullableClassMap, ]; } @@ -424,6 +612,12 @@ class AllClassesWrapper { allNullableTypesWithoutRecursion: result[1] as AllNullableTypesWithoutRecursion?, allTypes: result[2] as AllTypes?, + classList: (result[3] as List?)!.cast(), + nullableClassList: (result[4] as List?) + ?.cast(), + classMap: (result[5] as Map?)!.cast(), + nullableClassMap: (result[6] as Map?) + ?.cast(), ); } } @@ -454,24 +648,33 @@ class _PigeonCodec extends StandardMessageCodec { const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is AllTypes) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is AnEnum) { buffer.putUint8(129); + writeValue(buffer, value.index); + } else if (value is AnotherEnum) { + buffer.putUint8(130); + writeValue(buffer, value.index); + } else if (value is UnusedClass) { + buffer.putUint8(131); + writeValue(buffer, value.encode()); + } else if (value is AllTypes) { + buffer.putUint8(132); writeValue(buffer, value.encode()); } else if (value is AllNullableTypes) { - buffer.putUint8(130); + buffer.putUint8(133); writeValue(buffer, value.encode()); } else if (value is AllNullableTypesWithoutRecursion) { - buffer.putUint8(131); + buffer.putUint8(134); writeValue(buffer, value.encode()); } else if (value is AllClassesWrapper) { - buffer.putUint8(132); + buffer.putUint8(135); writeValue(buffer, value.encode()); } else if (value is TestMessage) { - buffer.putUint8(133); + buffer.putUint8(136); writeValue(buffer, value.encode()); - } else if (value is AnEnum) { - buffer.putUint8(134); - writeValue(buffer, value.index); } else { super.writeValue(buffer, value); } @@ -481,18 +684,23 @@ class _PigeonCodec extends StandardMessageCodec { Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { case 129: - return AllTypes.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : AnEnum.values[value]; case 130: - return AllNullableTypes.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : AnotherEnum.values[value]; case 131: - return AllNullableTypesWithoutRecursion.decode(readValue(buffer)!); + return UnusedClass.decode(readValue(buffer)!); case 132: - return AllClassesWrapper.decode(readValue(buffer)!); + return AllTypes.decode(readValue(buffer)!); case 133: - return TestMessage.decode(readValue(buffer)!); + return AllNullableTypes.decode(readValue(buffer)!); case 134: - final int? value = readValue(buffer) as int?; - return value == null ? null : AnEnum.values[value]; + return AllNullableTypesWithoutRecursion.decode(readValue(buffer)!); + case 135: + return AllClassesWrapper.decode(readValue(buffer)!); + case 136: + return TestMessage.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -507,35 +715,35 @@ class HostIntegrationCoreApi { /// BinaryMessenger will be used which routes to the host platform. HostIntegrationCoreApi( {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : __pigeon_binaryMessenger = binaryMessenger, - __pigeon_messageChannelSuffix = + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; - final BinaryMessenger? __pigeon_binaryMessenger; + final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - final String __pigeon_messageChannelSuffix; + final String pigeonVar_messageChannelSuffix; /// A no-op function taking no arguments and returning no value, to sanity /// test basic calling. Future noop() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.noop$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.noop$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; @@ -544,78 +752,78 @@ class HostIntegrationCoreApi { /// Returns the passed object, to test serialization and deserialization. Future echoAllTypes(AllTypes everything) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllTypes$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllTypes$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([everything]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([everything]) 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 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 AllTypes?)!; + return (pigeonVar_replyList[0] as AllTypes?)!; } } /// Returns an error, to test error handling. Future throwError() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwError$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwError$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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]; + return pigeonVar_replyList[0]; } } /// Returns an error from a void function, to test error handling. Future throwErrorFromVoid() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwErrorFromVoid$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwErrorFromVoid$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; @@ -624,2341 +832,4901 @@ class HostIntegrationCoreApi { /// Returns a Flutter error, to test error handling. Future throwFlutterError() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwFlutterError$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwFlutterError$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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]; + return pigeonVar_replyList[0]; } } /// Returns passed in int. Future echoInt(int anInt) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoInt$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoInt$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([anInt]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([anInt]) 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 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 int?)!; + return (pigeonVar_replyList[0] as int?)!; } } /// Returns passed in double. Future echoDouble(double aDouble) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoDouble$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoDouble$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([aDouble]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aDouble]) 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 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 double?)!; + return (pigeonVar_replyList[0] as double?)!; } } /// Returns the passed in boolean. Future echoBool(bool aBool) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoBool$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoBool$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([aBool]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aBool]) 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 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 bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } /// Returns the passed in string. Future echoString(String aString) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoString$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoString$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([aString]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aString]) 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 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 String?)!; + return (pigeonVar_replyList[0] as String?)!; } } /// Returns the passed in Uint8List. Future echoUint8List(Uint8List aUint8List) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoUint8List$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoUint8List$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([aUint8List]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aUint8List]) 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 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 Uint8List?)!; + return (pigeonVar_replyList[0] as Uint8List?)!; } } /// Returns the passed in generic Object. Future echoObject(Object anObject) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoObject$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoObject$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([anObject]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([anObject]) 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 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]!; + return pigeonVar_replyList[0]!; } } /// Returns the passed list, to test serialization and deserialization. Future> echoList(List list) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoList$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoList$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([list]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([list]) 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 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(); } } - /// Returns the passed map, to test serialization and deserialization. - Future> echoMap(Map aMap) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoMap$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed list, to test serialization and deserialization. + Future> echoEnumList(List enumList) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoEnumList$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([aMap]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([enumList]) 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 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 List?)!.cast(); } } - /// Returns the passed map to test nested class serialization and deserialization. - Future echoClassWrapper(AllClassesWrapper wrapper) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoClassWrapper$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed list, to test serialization and deserialization. + Future> echoClassList( + List classList) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoClassList$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([wrapper]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([classList]) 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 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 AllClassesWrapper?)!; + return (pigeonVar_replyList[0] as List?)! + .cast(); } } - /// Returns the passed enum to test serialization and deserialization. - Future echoEnum(AnEnum anEnum) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoEnum$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed list, to test serialization and deserialization. + Future> echoNonNullEnumList(List enumList) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullEnumList$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([anEnum]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([enumList]) 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 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 AnEnum?)!; + return (pigeonVar_replyList[0] as List?)!.cast(); } } - /// Returns the default string. - Future echoNamedDefaultString({String aString = 'default'}) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNamedDefaultString$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed list, to test serialization and deserialization. + Future> echoNonNullClassList( + List classList) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullClassList$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([aString]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([classList]) 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 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 String?)!; + return (pigeonVar_replyList[0] as List?)! + .cast(); } } - /// Returns passed in double. - Future echoOptionalDefaultDouble([double aDouble = 3.14]) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoOptionalDefaultDouble$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed map, to test serialization and deserialization. + Future> echoMap(Map map) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoMap$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([aDouble]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([map]) 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 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 double?)!; + return (pigeonVar_replyList[0] as Map?)! + .cast(); } } - /// Returns passed in int. - Future echoRequiredInt({required int anInt}) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoRequiredInt$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed map, to test serialization and deserialization. + Future> echoStringMap( + Map stringMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoStringMap$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([anInt]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([stringMap]) 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 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 int?)!; + return (pigeonVar_replyList[0] as Map?)! + .cast(); } } - /// Returns the passed object, to test serialization and deserialization. - Future echoAllNullableTypes( - AllNullableTypes? everything) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypes$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed map, to test serialization and deserialization. + Future> echoIntMap(Map intMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoIntMap$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([everything]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([intMap]) 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 AllNullableTypes?); - } - } - - /// Returns the passed object, to test serialization and deserialization. - Future - echoAllNullableTypesWithoutRecursion( - AllNullableTypesWithoutRecursion? everything) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypesWithoutRecursion$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = - BasicMessageChannel( - __pigeon_channelName, - pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, - ); - final List? __pigeon_replyList = - await __pigeon_channel.send([everything]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + } else if (pigeonVar_replyList[0] == null) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', ); } else { - return (__pigeon_replyList[0] as AllNullableTypesWithoutRecursion?); + return (pigeonVar_replyList[0] as Map?)! + .cast(); } } - /// Returns the inner `aString` value from the wrapped object, to test - /// sending of nested objects. - Future extractNestedNullableString(AllClassesWrapper wrapper) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.extractNestedNullableString$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed map, to test serialization and deserialization. + Future> echoEnumMap( + Map enumMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoEnumMap$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([wrapper]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([enumMap]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', ); } else { - return (__pigeon_replyList[0] as String?); + return (pigeonVar_replyList[0] as Map?)! + .cast(); } } - /// Returns the inner `aString` value from the wrapped object, to test - /// sending of nested objects. - Future createNestedNullableString( - String? nullableString) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.createNestedNullableString$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed map, to test serialization and deserialization. + Future> echoClassMap( + Map classMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoClassMap$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([nullableString]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([classMap]) 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 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 AllClassesWrapper?)!; + return (pigeonVar_replyList[0] as Map?)! + .cast(); } } - /// Returns passed in arguments of multiple types. - Future sendMultipleNullableTypes( - bool? aNullableBool, int? aNullableInt, String? aNullableString) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypes$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed map, to test serialization and deserialization. + Future> echoNonNullStringMap( + Map stringMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullStringMap$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([aNullableBool, aNullableInt, aNullableString]) - as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([stringMap]) 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 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 AllNullableTypes?)!; + return (pigeonVar_replyList[0] as Map?)! + .cast(); } } - /// Returns passed in arguments of multiple types. - Future - sendMultipleNullableTypesWithoutRecursion(bool? aNullableBool, - int? aNullableInt, String? aNullableString) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed map, to test serialization and deserialization. + Future> echoNonNullIntMap(Map intMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullIntMap$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([aNullableBool, aNullableInt, aNullableString]) - as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([intMap]) 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 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 AllNullableTypesWithoutRecursion?)!; + return (pigeonVar_replyList[0] as Map?)! + .cast(); } } - /// Returns passed in int. - Future echoNullableInt(int? aNullableInt) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableInt$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed map, to test serialization and deserialization. + Future> echoNonNullEnumMap( + Map enumMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullEnumMap$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([aNullableInt]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([enumMap]) 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?); - } - } - - /// Returns passed in double. - Future echoNullableDouble(double? aNullableDouble) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableDouble$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = - BasicMessageChannel( - __pigeon_channelName, - pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, - ); - final List? __pigeon_replyList = await __pigeon_channel - .send([aNullableDouble]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + } else if (pigeonVar_replyList[0] == null) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', ); } else { - return (__pigeon_replyList[0] as double?); + return (pigeonVar_replyList[0] as Map?)! + .cast(); } } - /// Returns the passed in boolean. - Future echoNullableBool(bool? aNullableBool) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableBool$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed map, to test serialization and deserialization. + Future> echoNonNullClassMap( + Map classMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullClassMap$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([aNullableBool]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([classMap]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', ); } else { - return (__pigeon_replyList[0] as bool?); + return (pigeonVar_replyList[0] as Map?)! + .cast(); } } - /// Returns the passed in string. - Future echoNullableString(String? aNullableString) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableString$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed class to test nested class serialization and deserialization. + Future echoClassWrapper(AllClassesWrapper wrapper) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoClassWrapper$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([aNullableString]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([wrapper]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', ); } else { - return (__pigeon_replyList[0] as String?); + return (pigeonVar_replyList[0] as AllClassesWrapper?)!; } } - /// Returns the passed in Uint8List. - Future echoNullableUint8List( - Uint8List? aNullableUint8List) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableUint8List$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed enum to test serialization and deserialization. + Future echoEnum(AnEnum anEnum) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoEnum$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([aNullableUint8List]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([anEnum]) 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 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 Uint8List?); + return (pigeonVar_replyList[0] as AnEnum?)!; } } - /// Returns the passed in generic Object. - Future echoNullableObject(Object? aNullableObject) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableObject$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed enum to test serialization and deserialization. + Future echoAnotherEnum(AnotherEnum anotherEnum) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAnotherEnum$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([aNullableObject]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([anotherEnum]) 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 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]; + return (pigeonVar_replyList[0] as AnotherEnum?)!; } } - /// Returns the passed list, to test serialization and deserialization. - Future?> echoNullableList(List? aNullableList) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableList$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the default string. + Future echoNamedDefaultString({String aString = 'default'}) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNamedDefaultString$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([aNullableList]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aString]) 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 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 String?)!; } } - /// Returns the passed map, to test serialization and deserialization. - Future?> echoNullableMap( - Map? aNullableMap) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableMap$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns passed in double. + Future echoOptionalDefaultDouble([double aDouble = 3.14]) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoOptionalDefaultDouble$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([aNullableMap]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aDouble]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + 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 double?)!; } } - Future echoNullableEnum(AnEnum? anEnum) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableEnum$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns passed in int. + Future echoRequiredInt({required int anInt}) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoRequiredInt$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([anEnum]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([anInt]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', ); } else { - return (__pigeon_replyList[0] as AnEnum?); + return (pigeonVar_replyList[0] as int?)!; } } - /// Returns passed in int. - Future echoOptionalNullableInt([int? aNullableInt]) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoOptionalNullableInt$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed object, to test serialization and deserialization. + Future echoAllNullableTypes( + AllNullableTypes? everything) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypes$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([aNullableInt]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([everything]) 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 AllNullableTypes?); } } - /// Returns the passed in string. - Future echoNamedNullableString({String? aNullableString}) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNamedNullableString$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed object, to test serialization and deserialization. + Future + echoAllNullableTypesWithoutRecursion( + AllNullableTypesWithoutRecursion? everything) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypesWithoutRecursion$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([aNullableString]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([everything]) 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 AllNullableTypesWithoutRecursion?); } } - /// A no-op function taking no arguments and returning no value, to sanity - /// test basic asynchronous calling. - Future noopAsync() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.noopAsync$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the inner `aString` value from the wrapped object, to test + /// sending of nested objects. + Future extractNestedNullableString(AllClassesWrapper wrapper) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.extractNestedNullableString$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([wrapper]) 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; + return (pigeonVar_replyList[0] as String?); } } - /// Returns passed in int asynchronously. - Future echoAsyncInt(int anInt) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncInt$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the inner `aString` value from the wrapped object, to test + /// sending of nested objects. + Future createNestedNullableString( + String? nullableString) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.createNestedNullableString$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([anInt]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([nullableString]) 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 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 int?)!; + return (pigeonVar_replyList[0] as AllClassesWrapper?)!; } } - /// Returns passed in double asynchronously. - Future echoAsyncDouble(double aDouble) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncDouble$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns passed in arguments of multiple types. + Future sendMultipleNullableTypes( + bool? aNullableBool, int? aNullableInt, String? aNullableString) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypes$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([aDouble]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([aNullableBool, aNullableInt, aNullableString]) + 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 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 double?)!; + return (pigeonVar_replyList[0] as AllNullableTypes?)!; } } - /// Returns the passed in boolean asynchronously. - Future echoAsyncBool(bool aBool) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncBool$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns passed in arguments of multiple types. + Future + sendMultipleNullableTypesWithoutRecursion(bool? aNullableBool, + int? aNullableInt, String? aNullableString) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion$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([aBool]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([aNullableBool, aNullableInt, aNullableString]) + 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 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 bool?)!; + return (pigeonVar_replyList[0] as AllNullableTypesWithoutRecursion?)!; } } - /// Returns the passed string asynchronously. - Future echoAsyncString(String aString) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncString$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns passed in int. + Future echoNullableInt(int? aNullableInt) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableInt$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([aString]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { - throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], - ); - } else if (__pigeon_replyList[0] == null) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aNullableInt]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', + 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 int?); } } - /// Returns the passed in Uint8List asynchronously. - Future echoAsyncUint8List(Uint8List aUint8List) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncUint8List$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns passed in double. + Future echoNullableDouble(double? aNullableDouble) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableDouble$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([aUint8List]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { - throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], - ); - } else if (__pigeon_replyList[0] == null) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([aNullableDouble]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { - return (__pigeon_replyList[0] as Uint8List?)!; + return (pigeonVar_replyList[0] as double?); } } - /// Returns the passed in generic Object asynchronously. - Future echoAsyncObject(Object anObject) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncObject$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed in boolean. + Future echoNullableBool(bool? aNullableBool) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableBool$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([anObject]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([aNullableBool]) 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], - ); - } else if (__pigeon_replyList[0] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { - return __pigeon_replyList[0]!; + return (pigeonVar_replyList[0] as bool?); } } - /// Returns the passed list, to test asynchronous serialization and deserialization. - Future> echoAsyncList(List list) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncList$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed in string. + Future echoNullableString(String? aNullableString) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableString$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([list]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { - throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], - ); - } else if (__pigeon_replyList[0] == null) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([aNullableString]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', + 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 String?); } } - /// Returns the passed map, to test asynchronous serialization and deserialization. - Future> echoAsyncMap(Map aMap) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncMap$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed in Uint8List. + Future echoNullableUint8List( + Uint8List? aNullableUint8List) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableUint8List$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([aMap]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([aNullableUint8List]) 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 if (__pigeon_replyList[0] == null) { + } else { + return (pigeonVar_replyList[0] as Uint8List?); + } + } + + /// Returns the passed in generic Object. + Future echoNullableObject(Object? aNullableObject) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableObject$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([aNullableObject]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { - return (__pigeon_replyList[0] as Map?)! - .cast(); + return pigeonVar_replyList[0]; } } - /// Returns the passed enum, to test asynchronous serialization and deserialization. - Future echoAsyncEnum(AnEnum anEnum) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncEnum$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed list, to test serialization and deserialization. + Future?> echoNullableList(List? aNullableList) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableList$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([anEnum]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([aNullableList]) 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 if (__pigeon_replyList[0] == null) { + } else { + return (pigeonVar_replyList[0] as List?)?.cast(); + } + } + + /// Returns the passed list, to test serialization and deserialization. + Future?> echoNullableEnumList(List? enumList) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableEnumList$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([enumList]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { - return (__pigeon_replyList[0] as AnEnum?)!; + return (pigeonVar_replyList[0] as List?)?.cast(); } } - /// Responds with an error from an async function returning a value. - Future throwAsyncError() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncError$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed list, to test serialization and deserialization. + Future?> echoNullableClassList( + List? classList) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableClassList$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([classList]) 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]; + return (pigeonVar_replyList[0] as List?) + ?.cast(); } } - /// Responds with an error from an async void function. - Future throwAsyncErrorFromVoid() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncErrorFromVoid$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed list, to test serialization and deserialization. + Future?> echoNullableNonNullEnumList( + List? enumList) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullEnumList$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([enumList]) 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; + return (pigeonVar_replyList[0] as List?)?.cast(); } } - /// Responds with a Flutter error from an async function returning a value. - Future throwAsyncFlutterError() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncFlutterError$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed list, to test serialization and deserialization. + Future?> echoNullableNonNullClassList( + List? classList) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullClassList$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([classList]) 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]; + return (pigeonVar_replyList[0] as List?) + ?.cast(); } } - /// Returns the passed object, to test async serialization and deserialization. - Future echoAsyncAllTypes(AllTypes everything) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncAllTypes$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed map, to test serialization and deserialization. + Future?> echoNullableMap( + Map? map) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableMap$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([everything]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([map]) 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 if (__pigeon_replyList[0] == null) { + } else { + return (pigeonVar_replyList[0] as Map?) + ?.cast(); + } + } + + /// Returns the passed map, to test serialization and deserialization. + Future?> echoNullableStringMap( + Map? stringMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableStringMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([stringMap]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { - return (__pigeon_replyList[0] as AllTypes?)!; + return (pigeonVar_replyList[0] as Map?) + ?.cast(); } } - /// Returns the passed object, to test serialization and deserialization. - Future echoAsyncNullableAllNullableTypes( - AllNullableTypes? everything) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypes$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed map, to test serialization and deserialization. + Future?> echoNullableIntMap(Map? intMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableIntMap$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([everything]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([intMap]) 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 AllNullableTypes?); + return (pigeonVar_replyList[0] as Map?) + ?.cast(); } } - /// Returns the passed object, to test serialization and deserialization. - Future - echoAsyncNullableAllNullableTypesWithoutRecursion( - AllNullableTypesWithoutRecursion? everything) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypesWithoutRecursion$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed map, to test serialization and deserialization. + Future?> echoNullableEnumMap( + Map? enumMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableEnumMap$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([everything]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([enumMap]) 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 AllNullableTypesWithoutRecursion?); + return (pigeonVar_replyList[0] as Map?) + ?.cast(); } } - /// Returns passed in int asynchronously. - Future echoAsyncNullableInt(int? anInt) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableInt$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed map, to test serialization and deserialization. + Future?> echoNullableClassMap( + Map? classMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableClassMap$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([anInt]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([classMap]) 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 Map?) + ?.cast(); } } - /// Returns passed in double asynchronously. - Future echoAsyncNullableDouble(double? aDouble) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableDouble$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed map, to test serialization and deserialization. + Future?> echoNullableNonNullStringMap( + Map? stringMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullStringMap$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([aDouble]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([stringMap]) 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 Map?) + ?.cast(); } } - /// Returns the passed in boolean asynchronously. - Future echoAsyncNullableBool(bool? aBool) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableBool$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed map, to test serialization and deserialization. + Future?> echoNullableNonNullIntMap( + Map? intMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullIntMap$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([aBool]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([intMap]) 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 Map?) + ?.cast(); } } - /// Returns the passed string asynchronously. - Future echoAsyncNullableString(String? aString) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableString$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed map, to test serialization and deserialization. + Future?> echoNullableNonNullEnumMap( + Map? enumMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullEnumMap$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([aString]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([enumMap]) 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 Map?) + ?.cast(); } } - /// Returns the passed in Uint8List asynchronously. - Future echoAsyncNullableUint8List(Uint8List? aUint8List) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableUint8List$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed map, to test serialization and deserialization. + Future?> echoNullableNonNullClassMap( + Map? classMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullClassMap$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([aUint8List]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([classMap]) 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 Uint8List?); + return (pigeonVar_replyList[0] as Map?) + ?.cast(); } } - /// Returns the passed in generic Object asynchronously. - Future echoAsyncNullableObject(Object? anObject) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableObject$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + Future echoNullableEnum(AnEnum? anEnum) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableEnum$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([anObject]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([anEnum]) 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]; + return (pigeonVar_replyList[0] as AnEnum?); } } - /// Returns the passed list, to test asynchronous serialization and deserialization. - Future?> echoAsyncNullableList(List? list) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableList$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + Future echoAnotherNullableEnum(AnotherEnum? anotherEnum) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAnotherNullableEnum$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([list]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([anotherEnum]) 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 AnotherEnum?); } } - /// Returns the passed map, to test asynchronous serialization and deserialization. - Future?> echoAsyncNullableMap( - Map? aMap) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableMap$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns passed in int. + Future echoOptionalNullableInt([int? aNullableInt]) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoOptionalNullableInt$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([aMap]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aNullableInt]) 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 Map?) - ?.cast(); + return (pigeonVar_replyList[0] as int?); } } - /// Returns the passed enum, to test asynchronous serialization and deserialization. - Future echoAsyncNullableEnum(AnEnum? anEnum) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableEnum$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed in string. + Future echoNamedNullableString({String? aNullableString}) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNamedNullableString$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([anEnum]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([aNullableString]) 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 AnEnum?); + return (pigeonVar_replyList[0] as String?); } } - Future callFlutterNoop() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterNoop$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic asynchronous calling. + Future noopAsync() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.noopAsync$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; } } - Future callFlutterThrowError() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterThrowError$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns passed in int asynchronously. + Future echoAsyncInt(int anInt) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncInt$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([anInt]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', ); } else { - return __pigeon_replyList[0]; + return (pigeonVar_replyList[0] as int?)!; } } - Future callFlutterThrowErrorFromVoid() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterThrowErrorFromVoid$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns passed in double asynchronously. + Future echoAsyncDouble(double aDouble) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncDouble$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aDouble]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', ); } else { - return; + return (pigeonVar_replyList[0] as double?)!; } } - Future callFlutterEchoAllTypes(AllTypes everything) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllTypes$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed in boolean asynchronously. + Future echoAsyncBool(bool aBool) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncBool$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([everything]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aBool]) 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 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 AllTypes?)!; + return (pigeonVar_replyList[0] as bool?)!; } } - Future callFlutterEchoAllNullableTypes( - AllNullableTypes? everything) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypes$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed string asynchronously. + Future echoAsyncString(String aString) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncString$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([everything]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aString]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', ); } else { - return (__pigeon_replyList[0] as AllNullableTypes?); + return (pigeonVar_replyList[0] as String?)!; } } - Future callFlutterSendMultipleNullableTypes( - bool? aNullableBool, int? aNullableInt, String? aNullableString) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypes$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed in Uint8List asynchronously. + Future echoAsyncUint8List(Uint8List aUint8List) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncUint8List$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([aNullableBool, aNullableInt, aNullableString]) - as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aUint8List]) 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 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 AllNullableTypes?)!; + return (pigeonVar_replyList[0] as Uint8List?)!; } } - Future - callFlutterEchoAllNullableTypesWithoutRecursion( - AllNullableTypesWithoutRecursion? everything) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypesWithoutRecursion$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed in generic Object asynchronously. + Future echoAsyncObject(Object anObject) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncObject$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([everything]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([anObject]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', ); } else { - return (__pigeon_replyList[0] as AllNullableTypesWithoutRecursion?); + return pigeonVar_replyList[0]!; } } - Future - callFlutterSendMultipleNullableTypesWithoutRecursion(bool? aNullableBool, - int? aNullableInt, String? aNullableString) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypesWithoutRecursion$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed list, to test asynchronous serialization and deserialization. + Future> echoAsyncList(List list) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncList$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([aNullableBool, aNullableInt, aNullableString]) - as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([list]) 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 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 AllNullableTypesWithoutRecursion?)!; + return (pigeonVar_replyList[0] as List?)!.cast(); } } - Future callFlutterEchoBool(bool aBool) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoBool$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed list, to test asynchronous serialization and deserialization. + Future> echoAsyncEnumList(List enumList) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncEnumList$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([aBool]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([enumList]) 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 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 bool?)!; + return (pigeonVar_replyList[0] as List?)!.cast(); } } - Future callFlutterEchoInt(int anInt) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoInt$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed list, to test asynchronous serialization and deserialization. + Future> echoAsyncClassList( + List classList) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncClassList$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([anInt]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([classList]) 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 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 int?)!; + return (pigeonVar_replyList[0] as List?)! + .cast(); } } - Future callFlutterEchoDouble(double aDouble) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoDouble$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed map, to test asynchronous serialization and deserialization. + Future> echoAsyncMap(Map map) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncMap$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([aDouble]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([map]) 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 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 double?)!; + return (pigeonVar_replyList[0] as Map?)! + .cast(); } } - Future callFlutterEchoString(String aString) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoString$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed map, to test asynchronous serialization and deserialization. + Future> echoAsyncStringMap( + Map stringMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncStringMap$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([aString]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([stringMap]) 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 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 String?)!; + return (pigeonVar_replyList[0] as Map?)! + .cast(); } } - Future callFlutterEchoUint8List(Uint8List list) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoUint8List$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed map, to test asynchronous serialization and deserialization. + Future> echoAsyncIntMap(Map intMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncIntMap$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([list]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([intMap]) 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 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 Uint8List?)!; + return (pigeonVar_replyList[0] as Map?)! + .cast(); } } - Future> callFlutterEchoList(List list) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoList$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed map, to test asynchronous serialization and deserialization. + Future> echoAsyncEnumMap( + Map enumMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncEnumMap$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([list]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([enumMap]) 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 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 Map?)! + .cast(); } } - Future> callFlutterEchoMap( - Map aMap) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoMap$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed map, to test asynchronous serialization and deserialization. + Future> echoAsyncClassMap( + Map classMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncClassMap$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([aMap]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([classMap]) 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 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(); } } - Future callFlutterEchoEnum(AnEnum anEnum) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoEnum$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed enum, to test asynchronous serialization and deserialization. + Future echoAsyncEnum(AnEnum anEnum) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncEnum$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([anEnum]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([anEnum]) 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 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 AnEnum?)!; + return (pigeonVar_replyList[0] as AnEnum?)!; } } - Future callFlutterEchoNullableBool(bool? aBool) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableBool$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed enum, to test asynchronous serialization and deserialization. + Future echoAnotherAsyncEnum(AnotherEnum anotherEnum) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAnotherAsyncEnum$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([aBool]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([anotherEnum]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', ); } else { - return (__pigeon_replyList[0] as bool?); + return (pigeonVar_replyList[0] as AnotherEnum?)!; } } - Future callFlutterEchoNullableInt(int? anInt) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableInt$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Responds with an error from an async function returning a value. + Future throwAsyncError() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncError$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([anInt]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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]; } } - Future callFlutterEchoNullableDouble(double? aDouble) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableDouble$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Responds with an error from an async void function. + Future throwAsyncErrorFromVoid() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncErrorFromVoid$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([aDouble]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; } } - Future callFlutterEchoNullableString(String? aString) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableString$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Responds with a Flutter error from an async function returning a value. + Future throwAsyncFlutterError() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncFlutterError$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([aString]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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]; } } - Future callFlutterEchoNullableUint8List(Uint8List? list) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableUint8List$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed object, to test async serialization and deserialization. + Future echoAsyncAllTypes(AllTypes everything) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncAllTypes$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([list]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([everything]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', ); } else { - return (__pigeon_replyList[0] as Uint8List?); + return (pigeonVar_replyList[0] as AllTypes?)!; } } - Future?> callFlutterEchoNullableList( - List? list) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableList$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed object, to test serialization and deserialization. + Future echoAsyncNullableAllNullableTypes( + AllNullableTypes? everything) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypes$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([list]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([everything]) 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 AllNullableTypes?); } } - Future?> callFlutterEchoNullableMap( - Map? aMap) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableMap$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns the passed object, to test serialization and deserialization. + Future + echoAsyncNullableAllNullableTypesWithoutRecursion( + AllNullableTypesWithoutRecursion? everything) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypesWithoutRecursion$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([aMap]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([everything]) 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 Map?) - ?.cast(); + return (pigeonVar_replyList[0] as AllNullableTypesWithoutRecursion?); } } - Future callFlutterEchoNullableEnum(AnEnum? anEnum) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableEnum$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns passed in int asynchronously. + Future echoAsyncNullableInt(int? anInt) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableInt$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([anEnum]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([anInt]) 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 AnEnum?); + return (pigeonVar_replyList[0] as int?); } } - Future callFlutterSmallApiEchoString(String aString) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSmallApiEchoString$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + /// Returns passed in double asynchronously. + Future echoAsyncNullableDouble(double? aDouble) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableDouble$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([aString]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aDouble]) 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 if (__pigeon_replyList[0] == null) { + } else { + return (pigeonVar_replyList[0] as double?); + } + } + + /// Returns the passed in boolean asynchronously. + Future echoAsyncNullableBool(bool? aBool) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableBool$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aBool]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', + 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 bool?); } } -} - -/// The core interface that the Dart platform_test code implements for host -/// integration tests to call into. -abstract class FlutterIntegrationCoreApi { - static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - /// A no-op function taking no arguments and returning no value, to sanity - /// test basic calling. - void noop(); - - /// Responds with an error from an async function returning a value. - Object? throwError(); - - /// Responds with an error from an async void function. - void throwErrorFromVoid(); - - /// Returns the passed object, to test serialization and deserialization. - AllTypes echoAllTypes(AllTypes everything); + /// Returns the passed string asynchronously. + Future echoAsyncNullableString(String? aString) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableString$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aString]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as String?); + } + } - /// Returns the passed object, to test serialization and deserialization. - AllNullableTypes? echoAllNullableTypes(AllNullableTypes? everything); + /// Returns the passed in Uint8List asynchronously. + Future echoAsyncNullableUint8List(Uint8List? aUint8List) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableUint8List$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aUint8List]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as Uint8List?); + } + } - /// Returns passed in arguments of multiple types. - /// - /// Tests multiple-arity FlutterApi handling. - AllNullableTypes sendMultipleNullableTypes( - bool? aNullableBool, int? aNullableInt, String? aNullableString); + /// Returns the passed in generic Object asynchronously. + Future echoAsyncNullableObject(Object? anObject) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableObject$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([anObject]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return pigeonVar_replyList[0]; + } + } - /// Returns the passed object, to test serialization and deserialization. - AllNullableTypesWithoutRecursion? echoAllNullableTypesWithoutRecursion( - AllNullableTypesWithoutRecursion? everything); + /// Returns the passed list, to test asynchronous serialization and deserialization. + Future?> echoAsyncNullableList(List? list) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableList$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([list]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as List?)?.cast(); + } + } - /// Returns passed in arguments of multiple types. - /// - /// Tests multiple-arity FlutterApi handling. - AllNullableTypesWithoutRecursion sendMultipleNullableTypesWithoutRecursion( - bool? aNullableBool, int? aNullableInt, String? aNullableString); + /// Returns the passed list, to test asynchronous serialization and deserialization. + Future?> echoAsyncNullableEnumList( + List? enumList) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableEnumList$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([enumList]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as List?)?.cast(); + } + } - /// Returns the passed boolean, to test serialization and deserialization. - bool echoBool(bool aBool); + /// Returns the passed list, to test asynchronous serialization and deserialization. + Future?> echoAsyncNullableClassList( + List? classList) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableClassList$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([classList]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as List?) + ?.cast(); + } + } - /// Returns the passed int, to test serialization and deserialization. - int echoInt(int anInt); + /// Returns the passed map, to test asynchronous serialization and deserialization. + Future?> echoAsyncNullableMap( + Map? map) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([map]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as Map?) + ?.cast(); + } + } - /// Returns the passed double, to test serialization and deserialization. - double echoDouble(double aDouble); + /// Returns the passed map, to test asynchronous serialization and deserialization. + Future?> echoAsyncNullableStringMap( + Map? stringMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableStringMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([stringMap]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as Map?) + ?.cast(); + } + } - /// Returns the passed string, to test serialization and deserialization. - String echoString(String aString); + /// Returns the passed map, to test asynchronous serialization and deserialization. + Future?> echoAsyncNullableIntMap( + Map? intMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableIntMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([intMap]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as Map?) + ?.cast(); + } + } - /// Returns the passed byte list, to test serialization and deserialization. - Uint8List echoUint8List(Uint8List list); + /// Returns the passed map, to test asynchronous serialization and deserialization. + Future?> echoAsyncNullableEnumMap( + Map? enumMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableEnumMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([enumMap]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as Map?) + ?.cast(); + } + } - /// Returns the passed list, to test serialization and deserialization. - List echoList(List list); + /// Returns the passed map, to test asynchronous serialization and deserialization. + Future?> echoAsyncNullableClassMap( + Map? classMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableClassMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([classMap]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as Map?) + ?.cast(); + } + } - /// Returns the passed map, to test serialization and deserialization. - Map echoMap(Map aMap); + /// Returns the passed enum, to test asynchronous serialization and deserialization. + Future echoAsyncNullableEnum(AnEnum? anEnum) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableEnum$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([anEnum]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as AnEnum?); + } + } - /// Returns the passed enum to test serialization and deserialization. - AnEnum echoEnum(AnEnum anEnum); + /// Returns the passed enum, to test asynchronous serialization and deserialization. + Future echoAnotherAsyncNullableEnum( + AnotherEnum? anotherEnum) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAnotherAsyncNullableEnum$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([anotherEnum]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as AnotherEnum?); + } + } - /// Returns the passed boolean, to test serialization and deserialization. - bool? echoNullableBool(bool? aBool); + Future callFlutterNoop() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterNoop$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } - /// Returns the passed int, to test serialization and deserialization. - int? echoNullableInt(int? anInt); + Future callFlutterThrowError() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterThrowError$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return pigeonVar_replyList[0]; + } + } - /// Returns the passed double, to test serialization and deserialization. - double? echoNullableDouble(double? aDouble); + Future callFlutterThrowErrorFromVoid() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterThrowErrorFromVoid$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } - /// Returns the passed string, to test serialization and deserialization. - String? echoNullableString(String? aString); + Future callFlutterEchoAllTypes(AllTypes everything) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllTypes$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([everything]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as AllTypes?)!; + } + } - /// Returns the passed byte list, to test serialization and deserialization. - Uint8List? echoNullableUint8List(Uint8List? list); + Future callFlutterEchoAllNullableTypes( + AllNullableTypes? everything) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypes$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([everything]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as AllNullableTypes?); + } + } - /// Returns the passed list, to test serialization and deserialization. - List? echoNullableList(List? list); + Future callFlutterSendMultipleNullableTypes( + bool? aNullableBool, int? aNullableInt, String? aNullableString) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypes$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([aNullableBool, aNullableInt, aNullableString]) + as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as AllNullableTypes?)!; + } + } - /// Returns the passed map, to test serialization and deserialization. - Map? echoNullableMap(Map? aMap); + Future + callFlutterEchoAllNullableTypesWithoutRecursion( + AllNullableTypesWithoutRecursion? everything) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypesWithoutRecursion$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([everything]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as AllNullableTypesWithoutRecursion?); + } + } - /// Returns the passed enum to test serialization and deserialization. - AnEnum? echoNullableEnum(AnEnum? anEnum); + Future + callFlutterSendMultipleNullableTypesWithoutRecursion(bool? aNullableBool, + int? aNullableInt, String? aNullableString) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypesWithoutRecursion$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([aNullableBool, aNullableInt, aNullableString]) + as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as AllNullableTypesWithoutRecursion?)!; + } + } - /// A no-op function taking no arguments and returning no value, to sanity - /// test basic asynchronous calling. - Future noopAsync(); + Future callFlutterEchoBool(bool aBool) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoBool$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aBool]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as bool?)!; + } + } - /// Returns the passed in generic Object asynchronously. - Future echoAsyncString(String aString); + Future callFlutterEchoInt(int anInt) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoInt$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([anInt]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as int?)!; + } + } - static void setUp( - FlutterIntegrationCoreApi? api, { - BinaryMessenger? binaryMessenger, - String messageChannelSuffix = '', - }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + Future callFlutterEchoDouble(double aDouble) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoDouble$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aDouble]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as double?)!; + } + } + + Future callFlutterEchoString(String aString) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoString$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aString]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as String?)!; + } + } + + Future callFlutterEchoUint8List(Uint8List list) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoUint8List$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([list]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as Uint8List?)!; + } + } + + Future> callFlutterEchoList(List list) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoList$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([list]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as List?)!.cast(); + } + } + + Future> callFlutterEchoEnumList(List enumList) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoEnumList$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([enumList]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as List?)!.cast(); + } + } + + Future> callFlutterEchoClassList( + List classList) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoClassList$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([classList]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as List?)! + .cast(); + } + } + + Future> callFlutterEchoNonNullEnumList( + List enumList) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullEnumList$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([enumList]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as List?)!.cast(); + } + } + + Future> callFlutterEchoNonNullClassList( + List classList) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullClassList$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([classList]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as List?)! + .cast(); + } + } + + Future> callFlutterEchoMap( + Map map) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([map]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as Map?)! + .cast(); + } + } + + Future> callFlutterEchoStringMap( + Map stringMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoStringMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([stringMap]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as Map?)! + .cast(); + } + } + + Future> callFlutterEchoIntMap(Map intMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoIntMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([intMap]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as Map?)! + .cast(); + } + } + + Future> callFlutterEchoEnumMap( + Map enumMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoEnumMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([enumMap]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as Map?)! + .cast(); + } + } + + Future> callFlutterEchoClassMap( + Map classMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoClassMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([classMap]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as Map?)! + .cast(); + } + } + + Future> callFlutterEchoNonNullStringMap( + Map stringMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullStringMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([stringMap]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as Map?)! + .cast(); + } + } + + Future> callFlutterEchoNonNullIntMap( + Map intMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullIntMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([intMap]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as Map?)! + .cast(); + } + } + + Future> callFlutterEchoNonNullEnumMap( + Map enumMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullEnumMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([enumMap]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as Map?)! + .cast(); + } + } + + Future> callFlutterEchoNonNullClassMap( + Map classMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullClassMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([classMap]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as Map?)! + .cast(); + } + } + + Future callFlutterEchoEnum(AnEnum anEnum) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoEnum$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([anEnum]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as AnEnum?)!; + } + } + + Future callFlutterEchoAnotherEnum( + AnotherEnum anotherEnum) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAnotherEnum$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([anotherEnum]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as AnotherEnum?)!; + } + } + + Future callFlutterEchoNullableBool(bool? aBool) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableBool$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aBool]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as bool?); + } + } + + Future callFlutterEchoNullableInt(int? anInt) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableInt$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([anInt]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as int?); + } + } + + Future callFlutterEchoNullableDouble(double? aDouble) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableDouble$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aDouble]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as double?); + } + } + + Future callFlutterEchoNullableString(String? aString) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableString$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aString]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as String?); + } + } + + Future callFlutterEchoNullableUint8List(Uint8List? list) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableUint8List$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([list]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as Uint8List?); + } + } + + Future?> callFlutterEchoNullableList( + List? list) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableList$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([list]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as List?)?.cast(); + } + } + + Future?> callFlutterEchoNullableEnumList( + List? enumList) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableEnumList$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([enumList]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as List?)?.cast(); + } + } + + Future?> callFlutterEchoNullableClassList( + List? classList) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableClassList$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([classList]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as List?) + ?.cast(); + } + } + + Future?> callFlutterEchoNullableNonNullEnumList( + List? enumList) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullEnumList$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([enumList]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as List?)?.cast(); + } + } + + Future?> callFlutterEchoNullableNonNullClassList( + List? classList) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullClassList$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([classList]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as List?) + ?.cast(); + } + } + + Future?> callFlutterEchoNullableMap( + Map? map) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([map]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as Map?) + ?.cast(); + } + } + + Future?> callFlutterEchoNullableStringMap( + Map? stringMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableStringMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([stringMap]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as Map?) + ?.cast(); + } + } + + Future?> callFlutterEchoNullableIntMap( + Map? intMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableIntMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([intMap]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as Map?) + ?.cast(); + } + } + + Future?> callFlutterEchoNullableEnumMap( + Map? enumMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableEnumMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([enumMap]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as Map?) + ?.cast(); + } + } + + Future?> callFlutterEchoNullableClassMap( + Map? classMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableClassMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([classMap]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as Map?) + ?.cast(); + } + } + + Future?> callFlutterEchoNullableNonNullStringMap( + Map? stringMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullStringMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([stringMap]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as Map?) + ?.cast(); + } + } + + Future?> callFlutterEchoNullableNonNullIntMap( + Map? intMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullIntMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([intMap]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as Map?) + ?.cast(); + } + } + + Future?> callFlutterEchoNullableNonNullEnumMap( + Map? enumMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullEnumMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([enumMap]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as Map?) + ?.cast(); + } + } + + Future?> callFlutterEchoNullableNonNullClassMap( + Map? classMap) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullClassMap$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([classMap]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as Map?) + ?.cast(); + } + } + + Future callFlutterEchoNullableEnum(AnEnum? anEnum) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableEnum$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([anEnum]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as AnEnum?); + } + } + + Future callFlutterEchoAnotherNullableEnum( + AnotherEnum? anotherEnum) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAnotherNullableEnum$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([anotherEnum]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as AnotherEnum?); + } + } + + Future callFlutterSmallApiEchoString(String aString) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSmallApiEchoString$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aString]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as String?)!; + } + } +} + +/// The core interface that the Dart platform_test code implements for host +/// integration tests to call into. +abstract class FlutterIntegrationCoreApi { + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic calling. + void noop(); + + /// Responds with an error from an async function returning a value. + Object? throwError(); + + /// Responds with an error from an async void function. + void throwErrorFromVoid(); + + /// Returns the passed object, to test serialization and deserialization. + AllTypes echoAllTypes(AllTypes everything); + + /// Returns the passed object, to test serialization and deserialization. + AllNullableTypes? echoAllNullableTypes(AllNullableTypes? everything); + + /// Returns passed in arguments of multiple types. + /// + /// Tests multiple-arity FlutterApi handling. + AllNullableTypes sendMultipleNullableTypes( + bool? aNullableBool, int? aNullableInt, String? aNullableString); + + /// Returns the passed object, to test serialization and deserialization. + AllNullableTypesWithoutRecursion? echoAllNullableTypesWithoutRecursion( + AllNullableTypesWithoutRecursion? everything); + + /// Returns passed in arguments of multiple types. + /// + /// Tests multiple-arity FlutterApi handling. + AllNullableTypesWithoutRecursion sendMultipleNullableTypesWithoutRecursion( + bool? aNullableBool, int? aNullableInt, String? aNullableString); + + /// Returns the passed boolean, to test serialization and deserialization. + bool echoBool(bool aBool); + + /// Returns the passed int, to test serialization and deserialization. + int echoInt(int anInt); + + /// Returns the passed double, to test serialization and deserialization. + double echoDouble(double aDouble); + + /// Returns the passed string, to test serialization and deserialization. + String echoString(String aString); + + /// Returns the passed byte list, to test serialization and deserialization. + Uint8List echoUint8List(Uint8List list); + + /// Returns the passed list, to test serialization and deserialization. + List echoList(List list); + + /// Returns the passed list, to test serialization and deserialization. + List echoEnumList(List enumList); + + /// Returns the passed list, to test serialization and deserialization. + List echoClassList(List classList); + + /// Returns the passed list, to test serialization and deserialization. + List echoNonNullEnumList(List enumList); + + /// Returns the passed list, to test serialization and deserialization. + List echoNonNullClassList(List classList); + + /// Returns the passed map, to test serialization and deserialization. + Map echoMap(Map map); + + /// Returns the passed map, to test serialization and deserialization. + Map echoStringMap(Map stringMap); + + /// Returns the passed map, to test serialization and deserialization. + Map echoIntMap(Map intMap); + + /// Returns the passed map, to test serialization and deserialization. + Map echoEnumMap(Map enumMap); + + /// Returns the passed map, to test serialization and deserialization. + Map echoClassMap( + Map classMap); + + /// Returns the passed map, to test serialization and deserialization. + Map echoNonNullStringMap(Map stringMap); + + /// Returns the passed map, to test serialization and deserialization. + Map echoNonNullIntMap(Map intMap); + + /// Returns the passed map, to test serialization and deserialization. + Map echoNonNullEnumMap(Map enumMap); + + /// Returns the passed map, to test serialization and deserialization. + Map echoNonNullClassMap( + Map classMap); + + /// Returns the passed enum to test serialization and deserialization. + AnEnum echoEnum(AnEnum anEnum); + + /// Returns the passed enum to test serialization and deserialization. + AnotherEnum echoAnotherEnum(AnotherEnum anotherEnum); + + /// Returns the passed boolean, to test serialization and deserialization. + bool? echoNullableBool(bool? aBool); + + /// Returns the passed int, to test serialization and deserialization. + int? echoNullableInt(int? anInt); + + /// Returns the passed double, to test serialization and deserialization. + double? echoNullableDouble(double? aDouble); + + /// Returns the passed string, to test serialization and deserialization. + String? echoNullableString(String? aString); + + /// Returns the passed byte list, to test serialization and deserialization. + Uint8List? echoNullableUint8List(Uint8List? list); + + /// Returns the passed list, to test serialization and deserialization. + List? echoNullableList(List? list); + + /// Returns the passed list, to test serialization and deserialization. + List? echoNullableEnumList(List? enumList); + + /// Returns the passed list, to test serialization and deserialization. + List? echoNullableClassList( + List? classList); + + /// Returns the passed list, to test serialization and deserialization. + List? echoNullableNonNullEnumList(List? enumList); + + /// Returns the passed list, to test serialization and deserialization. + List? echoNullableNonNullClassList( + List? classList); + + /// Returns the passed map, to test serialization and deserialization. + Map? echoNullableMap(Map? map); + + /// Returns the passed map, to test serialization and deserialization. + Map? echoNullableStringMap( + Map? stringMap); + + /// Returns the passed map, to test serialization and deserialization. + Map? echoNullableIntMap(Map? intMap); + + /// Returns the passed map, to test serialization and deserialization. + Map? echoNullableEnumMap(Map? enumMap); + + /// Returns the passed map, to test serialization and deserialization. + Map? echoNullableClassMap( + Map? classMap); + + /// Returns the passed map, to test serialization and deserialization. + Map? echoNullableNonNullStringMap( + Map? stringMap); + + /// Returns the passed map, to test serialization and deserialization. + Map? echoNullableNonNullIntMap(Map? intMap); + + /// Returns the passed map, to test serialization and deserialization. + Map? echoNullableNonNullEnumMap(Map? enumMap); + + /// Returns the passed map, to test serialization and deserialization. + Map? echoNullableNonNullClassMap( + Map? classMap); + + /// Returns the passed enum to test serialization and deserialization. + AnEnum? echoNullableEnum(AnEnum? anEnum); + + /// Returns the passed enum to test serialization and deserialization. + AnotherEnum? echoAnotherNullableEnum(AnotherEnum? anotherEnum); + + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic asynchronous calling. + Future noopAsync(); + + /// Returns the passed in generic Object asynchronously. + Future echoAsyncString(String aString); + + static void setUp( + FlutterIntegrationCoreApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.noop$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + try { + api.noop(); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwError$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + try { + final Object? output = api.throwError(); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwErrorFromVoid$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + try { + api.throwErrorFromVoid(); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllTypes$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllTypes was null.'); + final List args = (message as List?)!; + final AllTypes? arg_everything = (args[0] as AllTypes?); + assert(arg_everything != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllTypes was null, expected non-null AllTypes.'); + try { + final AllTypes output = api.echoAllTypes(arg_everything!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypes$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypes was null.'); + final List args = (message as List?)!; + final AllNullableTypes? arg_everything = + (args[0] as AllNullableTypes?); + try { + final AllNullableTypes? output = + api.echoAllNullableTypes(arg_everything); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypes$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypes was null.'); + final List args = (message as List?)!; + final bool? arg_aNullableBool = (args[0] as bool?); + final int? arg_aNullableInt = (args[1] as int?); + final String? arg_aNullableString = (args[2] as String?); + try { + final AllNullableTypes output = api.sendMultipleNullableTypes( + arg_aNullableBool, arg_aNullableInt, arg_aNullableString); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypesWithoutRecursion$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypesWithoutRecursion was null.'); + final List args = (message as List?)!; + final AllNullableTypesWithoutRecursion? arg_everything = + (args[0] as AllNullableTypesWithoutRecursion?); + try { + final AllNullableTypesWithoutRecursion? output = + api.echoAllNullableTypesWithoutRecursion(arg_everything); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion was null.'); + final List args = (message as List?)!; + final bool? arg_aNullableBool = (args[0] as bool?); + final int? arg_aNullableInt = (args[1] as int?); + final String? arg_aNullableString = (args[2] as String?); + try { + final AllNullableTypesWithoutRecursion output = + api.sendMultipleNullableTypesWithoutRecursion( + arg_aNullableBool, arg_aNullableInt, arg_aNullableString); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoBool$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoBool was null.'); + final List args = (message as List?)!; + final bool? arg_aBool = (args[0] as bool?); + assert(arg_aBool != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoBool was null, expected non-null bool.'); + try { + final bool output = api.echoBool(arg_aBool!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoInt$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoInt was null.'); + final List args = (message as List?)!; + final int? arg_anInt = (args[0] as int?); + assert(arg_anInt != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoInt was null, expected non-null int.'); + try { + final int output = api.echoInt(arg_anInt!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoDouble$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoDouble was null.'); + final List args = (message as List?)!; + final double? arg_aDouble = (args[0] as double?); + assert(arg_aDouble != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoDouble was null, expected non-null double.'); + try { + final double output = api.echoDouble(arg_aDouble!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoString$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoString was null.'); + final List args = (message as List?)!; + final String? arg_aString = (args[0] as String?); + assert(arg_aString != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoString was null, expected non-null String.'); + try { + final String output = api.echoString(arg_aString!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoUint8List$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoUint8List was null.'); + final List args = (message as List?)!; + final Uint8List? arg_list = (args[0] as Uint8List?); + assert(arg_list != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoUint8List was null, expected non-null Uint8List.'); + try { + final Uint8List output = api.echoUint8List(arg_list!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoList$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoList was null.'); + final List args = (message as List?)!; + final List? arg_list = + (args[0] as List?)?.cast(); + assert(arg_list != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoList was null, expected non-null List.'); + try { + final List output = api.echoList(arg_list!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnumList$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnumList was null.'); + final List args = (message as List?)!; + final List? arg_enumList = + (args[0] as List?)?.cast(); + assert(arg_enumList != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnumList was null, expected non-null List.'); + try { + final List output = api.echoEnumList(arg_enumList!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoClassList$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoClassList was null.'); + final List args = (message as List?)!; + final List? arg_classList = + (args[0] as List?)?.cast(); + assert(arg_classList != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoClassList was null, expected non-null List.'); + try { + final List output = + api.echoClassList(arg_classList!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullEnumList$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullEnumList was null.'); + final List args = (message as List?)!; + final List? arg_enumList = + (args[0] as List?)?.cast(); + assert(arg_enumList != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullEnumList was null, expected non-null List.'); + try { + final List output = api.echoNonNullEnumList(arg_enumList!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullClassList$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullClassList was null.'); + final List args = (message as List?)!; + final List? arg_classList = + (args[0] as List?)?.cast(); + assert(arg_classList != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullClassList was null, expected non-null List.'); + try { + final List output = + api.echoNonNullClassList(arg_classList!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoMap$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoMap was null.'); + final List args = (message as List?)!; + final Map? arg_map = + (args[0] as Map?)?.cast(); + assert(arg_map != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoMap was null, expected non-null Map.'); + try { + final Map output = api.echoMap(arg_map!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoStringMap$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoStringMap was null.'); + final List args = (message as List?)!; + final Map? arg_stringMap = + (args[0] as Map?)?.cast(); + assert(arg_stringMap != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoStringMap was null, expected non-null Map.'); + try { + final Map output = + api.echoStringMap(arg_stringMap!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.noop$messageChannelSuffix', + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoIntMap$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoIntMap was null.'); + final List args = (message as List?)!; + final Map? arg_intMap = + (args[0] as Map?)?.cast(); + assert(arg_intMap != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoIntMap was null, expected non-null Map.'); try { - api.noop(); - return wrapResponse(empty: true); + final Map output = api.echoIntMap(arg_intMap!); + return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); } catch (e) { @@ -2969,17 +5737,25 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwError$messageChannelSuffix', + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnumMap$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnumMap was null.'); + final List args = (message as List?)!; + final Map? arg_enumMap = + (args[0] as Map?)?.cast(); + assert(arg_enumMap != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnumMap was null, expected non-null Map.'); try { - final Object? output = api.throwError(); + final Map output = api.echoEnumMap(arg_enumMap!); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -2991,18 +5767,28 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwErrorFromVoid$messageChannelSuffix', + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoClassMap$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoClassMap was null.'); + final List args = (message as List?)!; + final Map? arg_classMap = + (args[0] as Map?) + ?.cast(); + assert(arg_classMap != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoClassMap was null, expected non-null Map.'); try { - api.throwErrorFromVoid(); - return wrapResponse(empty: true); + final Map output = + api.echoClassMap(arg_classMap!); + return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); } catch (e) { @@ -3013,23 +5799,26 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllTypes$messageChannelSuffix', + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullStringMap$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllTypes was null.'); + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullStringMap was null.'); final List args = (message as List?)!; - final AllTypes? arg_everything = (args[0] as AllTypes?); - assert(arg_everything != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllTypes was null, expected non-null AllTypes.'); + final Map? arg_stringMap = + (args[0] as Map?)?.cast(); + assert(arg_stringMap != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullStringMap was null, expected non-null Map.'); try { - final AllTypes output = api.echoAllTypes(arg_everything!); + final Map output = + api.echoNonNullStringMap(arg_stringMap!); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3041,23 +5830,25 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypes$messageChannelSuffix', + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullIntMap$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypes was null.'); + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullIntMap was null.'); final List args = (message as List?)!; - final AllNullableTypes? arg_everything = - (args[0] as AllNullableTypes?); + final Map? arg_intMap = + (args[0] as Map?)?.cast(); + assert(arg_intMap != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullIntMap was null, expected non-null Map.'); try { - final AllNullableTypes? output = - api.echoAllNullableTypes(arg_everything); + final Map output = api.echoNonNullIntMap(arg_intMap!); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3069,24 +5860,26 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypes$messageChannelSuffix', + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullEnumMap$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypes was null.'); + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullEnumMap was null.'); final List args = (message as List?)!; - final bool? arg_aNullableBool = (args[0] as bool?); - final int? arg_aNullableInt = (args[1] as int?); - final String? arg_aNullableString = (args[2] as String?); + final Map? arg_enumMap = + (args[0] as Map?)?.cast(); + assert(arg_enumMap != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullEnumMap was null, expected non-null Map.'); try { - final AllNullableTypes output = api.sendMultipleNullableTypes( - arg_aNullableBool, arg_aNullableInt, arg_aNullableString); + final Map output = + api.echoNonNullEnumMap(arg_enumMap!); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3098,23 +5891,27 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypesWithoutRecursion$messageChannelSuffix', + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullClassMap$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypesWithoutRecursion was null.'); + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullClassMap was null.'); final List args = (message as List?)!; - final AllNullableTypesWithoutRecursion? arg_everything = - (args[0] as AllNullableTypesWithoutRecursion?); + final Map? arg_classMap = + (args[0] as Map?) + ?.cast(); + assert(arg_classMap != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullClassMap was null, expected non-null Map.'); try { - final AllNullableTypesWithoutRecursion? output = - api.echoAllNullableTypesWithoutRecursion(arg_everything); + final Map output = + api.echoNonNullClassMap(arg_classMap!); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3126,25 +5923,24 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion$messageChannelSuffix', + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnum$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion was null.'); + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnum was null.'); final List args = (message as List?)!; - final bool? arg_aNullableBool = (args[0] as bool?); - final int? arg_aNullableInt = (args[1] as int?); - final String? arg_aNullableString = (args[2] as String?); + final AnEnum? arg_anEnum = (args[0] as AnEnum?); + assert(arg_anEnum != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnum was null, expected non-null AnEnum.'); try { - final AllNullableTypesWithoutRecursion output = - api.sendMultipleNullableTypesWithoutRecursion( - arg_aNullableBool, arg_aNullableInt, arg_aNullableString); + final AnEnum output = api.echoEnum(arg_anEnum!); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3156,23 +5952,51 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoBool$messageChannelSuffix', + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAnotherEnum$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoBool was null.'); + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAnotherEnum was null.'); + final List args = (message as List?)!; + final AnotherEnum? arg_anotherEnum = (args[0] as AnotherEnum?); + assert(arg_anotherEnum != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAnotherEnum was null, expected non-null AnotherEnum.'); + try { + final AnotherEnum output = api.echoAnotherEnum(arg_anotherEnum!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableBool$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableBool was null.'); final List args = (message as List?)!; final bool? arg_aBool = (args[0] as bool?); - assert(arg_aBool != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoBool was null, expected non-null bool.'); try { - final bool output = api.echoBool(arg_aBool!); + final bool? output = api.echoNullableBool(arg_aBool); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3184,23 +6008,22 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoInt$messageChannelSuffix', + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableInt$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoInt was null.'); + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableInt was null.'); final List args = (message as List?)!; final int? arg_anInt = (args[0] as int?); - assert(arg_anInt != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoInt was null, expected non-null int.'); try { - final int output = api.echoInt(arg_anInt!); + final int? output = api.echoNullableInt(arg_anInt); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3212,23 +6035,22 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoDouble$messageChannelSuffix', + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableDouble$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoDouble was null.'); + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableDouble was null.'); final List args = (message as List?)!; final double? arg_aDouble = (args[0] as double?); - assert(arg_aDouble != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoDouble was null, expected non-null double.'); try { - final double output = api.echoDouble(arg_aDouble!); + final double? output = api.echoNullableDouble(arg_aDouble); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3240,23 +6062,22 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoString$messageChannelSuffix', + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableString$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoString was null.'); + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableString was null.'); final List args = (message as List?)!; final String? arg_aString = (args[0] as String?); - assert(arg_aString != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoString was null, expected non-null String.'); try { - final String output = api.echoString(arg_aString!); + final String? output = api.echoNullableString(arg_aString); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3268,23 +6089,22 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoUint8List$messageChannelSuffix', + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableUint8List$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoUint8List was null.'); + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableUint8List was null.'); final List args = (message as List?)!; final Uint8List? arg_list = (args[0] as Uint8List?); - assert(arg_list != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoUint8List was null, expected non-null Uint8List.'); try { - final Uint8List output = api.echoUint8List(arg_list!); + final Uint8List? output = api.echoNullableUint8List(arg_list); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3296,24 +6116,23 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoList$messageChannelSuffix', + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableList$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoList was null.'); + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableList was null.'); final List args = (message as List?)!; final List? arg_list = (args[0] as List?)?.cast(); - assert(arg_list != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoList was null, expected non-null List.'); try { - final List output = api.echoList(arg_list!); + final List? output = api.echoNullableList(arg_list); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3325,24 +6144,24 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoMap$messageChannelSuffix', + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableEnumList$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoMap was null.'); + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableEnumList was null.'); final List args = (message as List?)!; - final Map? arg_aMap = - (args[0] as Map?)?.cast(); - assert(arg_aMap != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoMap was null, expected non-null Map.'); + final List? arg_enumList = + (args[0] as List?)?.cast(); try { - final Map output = api.echoMap(arg_aMap!); + final List? output = + api.echoNullableEnumList(arg_enumList); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3354,23 +6173,24 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnum$messageChannelSuffix', + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableClassList$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnum was null.'); + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableClassList was null.'); final List args = (message as List?)!; - final AnEnum? arg_anEnum = (args[0] as AnEnum?); - assert(arg_anEnum != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnum was null, expected non-null AnEnum.'); + final List? arg_classList = + (args[0] as List?)?.cast(); try { - final AnEnum output = api.echoEnum(arg_anEnum!); + final List? output = + api.echoNullableClassList(arg_classList); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3382,21 +6202,24 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableBool$messageChannelSuffix', + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullEnumList$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableBool was null.'); + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullEnumList was null.'); final List args = (message as List?)!; - final bool? arg_aBool = (args[0] as bool?); + final List? arg_enumList = + (args[0] as List?)?.cast(); try { - final bool? output = api.echoNullableBool(arg_aBool); + final List? output = + api.echoNullableNonNullEnumList(arg_enumList); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3408,21 +6231,24 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableInt$messageChannelSuffix', + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullClassList$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableInt was null.'); + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullClassList was null.'); final List args = (message as List?)!; - final int? arg_anInt = (args[0] as int?); + final List? arg_classList = + (args[0] as List?)?.cast(); try { - final int? output = api.echoNullableInt(arg_anInt); + final List? output = + api.echoNullableNonNullClassList(arg_classList); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3434,21 +6260,23 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableDouble$messageChannelSuffix', + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableMap$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableDouble was null.'); + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableMap was null.'); final List args = (message as List?)!; - final double? arg_aDouble = (args[0] as double?); + final Map? arg_map = + (args[0] as Map?)?.cast(); try { - final double? output = api.echoNullableDouble(arg_aDouble); + final Map? output = api.echoNullableMap(arg_map); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3460,21 +6288,24 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableString$messageChannelSuffix', + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableStringMap$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableString was null.'); + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableStringMap was null.'); final List args = (message as List?)!; - final String? arg_aString = (args[0] as String?); + final Map? arg_stringMap = + (args[0] as Map?)?.cast(); try { - final String? output = api.echoNullableString(arg_aString); + final Map? output = + api.echoNullableStringMap(arg_stringMap); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3486,21 +6317,23 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableUint8List$messageChannelSuffix', + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableIntMap$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableUint8List was null.'); + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableIntMap was null.'); final List args = (message as List?)!; - final Uint8List? arg_list = (args[0] as Uint8List?); + final Map? arg_intMap = + (args[0] as Map?)?.cast(); try { - final Uint8List? output = api.echoNullableUint8List(arg_list); + final Map? output = api.echoNullableIntMap(arg_intMap); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3512,22 +6345,24 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableList$messageChannelSuffix', + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableEnumMap$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableList was null.'); + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableEnumMap was null.'); final List args = (message as List?)!; - final List? arg_list = - (args[0] as List?)?.cast(); + final Map? arg_enumMap = + (args[0] as Map?)?.cast(); try { - final List? output = api.echoNullableList(arg_list); + final Map? output = + api.echoNullableEnumMap(arg_enumMap); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3539,22 +6374,142 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableMap$messageChannelSuffix', + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableClassMap$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableMap was null.'); + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableClassMap was null.'); + final List args = (message as List?)!; + final Map? arg_classMap = + (args[0] as Map?) + ?.cast(); + try { + final Map? output = + api.echoNullableClassMap(arg_classMap); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullStringMap$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullStringMap was null.'); + final List args = (message as List?)!; + final Map? arg_stringMap = + (args[0] as Map?)?.cast(); + try { + final Map? output = + api.echoNullableNonNullStringMap(arg_stringMap); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullIntMap$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullIntMap was null.'); + final List args = (message as List?)!; + final Map? arg_intMap = + (args[0] as Map?)?.cast(); + try { + final Map? output = + api.echoNullableNonNullIntMap(arg_intMap); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullEnumMap$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullEnumMap was null.'); + final List args = (message as List?)!; + final Map? arg_enumMap = + (args[0] as Map?)?.cast(); + try { + final Map? output = + api.echoNullableNonNullEnumMap(arg_enumMap); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullClassMap$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullClassMap was null.'); final List args = (message as List?)!; - final Map? arg_aMap = - (args[0] as Map?)?.cast(); + final Map? arg_classMap = + (args[0] as Map?) + ?.cast(); try { - final Map? output = api.echoNullableMap(arg_aMap); + final Map? output = + api.echoNullableNonNullClassMap(arg_classMap); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3566,15 +6521,16 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableEnum$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableEnum was null.'); final List args = (message as List?)!; @@ -3592,15 +6548,44 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAnotherNullableEnum$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAnotherNullableEnum was null.'); + final List args = (message as List?)!; + final AnotherEnum? arg_anotherEnum = (args[0] as AnotherEnum?); + try { + final AnotherEnum? output = + api.echoAnotherNullableEnum(arg_anotherEnum); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.noopAsync$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { try { await api.noopAsync(); return wrapResponse(empty: true); @@ -3614,15 +6599,16 @@ abstract class FlutterIntegrationCoreApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAsyncString$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAsyncString was null.'); final List args = (message as List?)!; @@ -3651,33 +6637,33 @@ class HostTrivialApi { /// BinaryMessenger will be used which routes to the host platform. HostTrivialApi( {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : __pigeon_binaryMessenger = binaryMessenger, - __pigeon_messageChannelSuffix = + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; - final BinaryMessenger? __pigeon_binaryMessenger; + final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - final String __pigeon_messageChannelSuffix; + final String pigeonVar_messageChannelSuffix; Future noop() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostTrivialApi.noop$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostTrivialApi.noop$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; @@ -3692,62 +6678,62 @@ class HostSmallApi { /// BinaryMessenger will be used which routes to the host platform. HostSmallApi( {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : __pigeon_binaryMessenger = binaryMessenger, - __pigeon_messageChannelSuffix = + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; - final BinaryMessenger? __pigeon_binaryMessenger; + final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - final String __pigeon_messageChannelSuffix; + final String pigeonVar_messageChannelSuffix; Future echo(String aString) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostSmallApi.echo$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostSmallApi.echo$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([aString]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aString]) 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 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 String?)!; + return (pigeonVar_replyList[0] as String?)!; } } Future voidVoid() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.HostSmallApi.voidVoid$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostSmallApi.voidVoid$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; @@ -3771,15 +6757,16 @@ abstract class FlutterSmallApi { messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.FlutterSmallApi.echoWrappedList$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterSmallApi.echoWrappedList was null.'); final List args = (message as List?)!; @@ -3799,15 +6786,16 @@ abstract class FlutterSmallApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.FlutterSmallApi.echoString$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterSmallApi.echoString was null.'); final List args = (message as List?)!; diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/enum.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/enum.gen.dart index e2ca92672ed7..6dfbc13452ca 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/enum.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/enum.gen.dart @@ -72,12 +72,15 @@ class _PigeonCodec extends StandardMessageCodec { const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is DataWithEnum) { - buffer.putUint8(129); - writeValue(buffer, value.encode()); + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); } else if (value is EnumState) { - buffer.putUint8(130); + buffer.putUint8(129); writeValue(buffer, value.index); + } else if (value is DataWithEnum) { + buffer.putUint8(130); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -87,10 +90,10 @@ class _PigeonCodec extends StandardMessageCodec { Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { case 129: - return DataWithEnum.decode(readValue(buffer)!); - case 130: final int? value = readValue(buffer) as int?; return value == null ? null : EnumState.values[value]; + case 130: + return DataWithEnum.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -104,42 +107,42 @@ class EnumApi2Host { /// BinaryMessenger will be used which routes to the host platform. EnumApi2Host( {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : __pigeon_binaryMessenger = binaryMessenger, - __pigeon_messageChannelSuffix = + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; - final BinaryMessenger? __pigeon_binaryMessenger; + final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - final String __pigeon_messageChannelSuffix; + final String pigeonVar_messageChannelSuffix; /// This comment is to test method documentation comments. Future echo(DataWithEnum data) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.EnumApi2Host.echo$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.EnumApi2Host.echo$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([data]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([data]) 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 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 DataWithEnum?)!; + return (pigeonVar_replyList[0] as DataWithEnum?)!; } } } @@ -159,15 +162,16 @@ abstract class EnumApi2Flutter { messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.EnumApi2Flutter.echo$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.EnumApi2Flutter.echo was null.'); final List args = (message as List?)!; diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/flutter_unittests.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/flutter_unittests.gen.dart index 61e4b97a5fe0..c1a8d542e512 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/flutter_unittests.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/flutter_unittests.gen.dart @@ -112,7 +112,10 @@ class _PigeonCodec extends StandardMessageCodec { const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is FlutterSearchRequest) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is FlutterSearchRequest) { buffer.putUint8(129); writeValue(buffer, value.encode()); } else if (value is FlutterSearchReply) { @@ -151,128 +154,128 @@ class Api { /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. Api({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : __pigeon_binaryMessenger = binaryMessenger, - __pigeon_messageChannelSuffix = + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; - final BinaryMessenger? __pigeon_binaryMessenger; + final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - final String __pigeon_messageChannelSuffix; + final String pigeonVar_messageChannelSuffix; Future search(FlutterSearchRequest request) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.Api.search$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.Api.search$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([request]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([request]) 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 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 FlutterSearchReply?)!; + return (pigeonVar_replyList[0] as FlutterSearchReply?)!; } } Future doSearches(FlutterSearchRequests request) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.Api.doSearches$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.Api.doSearches$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([request]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([request]) 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 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 FlutterSearchReplies?)!; + return (pigeonVar_replyList[0] as FlutterSearchReplies?)!; } } Future echo(FlutterSearchRequests requests) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.Api.echo$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.Api.echo$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([requests]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([requests]) 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 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 FlutterSearchRequests?)!; + return (pigeonVar_replyList[0] as FlutterSearchRequests?)!; } } Future anInt(int value) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.Api.anInt$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.Api.anInt$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([value]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([value]) 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 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 int?)!; + return (pigeonVar_replyList[0] as int?)!; } } } diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/message.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/message.gen.dart index fb7e65c9483f..6a63637da6f6 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/message.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/message.gen.dart @@ -144,18 +144,21 @@ class _PigeonCodec extends StandardMessageCodec { const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is MessageSearchRequest) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is MessageRequestState) { buffer.putUint8(129); - writeValue(buffer, value.encode()); - } else if (value is MessageSearchReply) { + writeValue(buffer, value.index); + } else if (value is MessageSearchRequest) { buffer.putUint8(130); writeValue(buffer, value.encode()); - } else if (value is MessageNested) { + } else if (value is MessageSearchReply) { buffer.putUint8(131); writeValue(buffer, value.encode()); - } else if (value is MessageRequestState) { + } else if (value is MessageNested) { buffer.putUint8(132); - writeValue(buffer, value.index); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -165,14 +168,14 @@ class _PigeonCodec extends StandardMessageCodec { Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { case 129: - return MessageSearchRequest.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : MessageRequestState.values[value]; case 130: - return MessageSearchReply.decode(readValue(buffer)!); + return MessageSearchRequest.decode(readValue(buffer)!); case 131: - return MessageNested.decode(readValue(buffer)!); + return MessageSearchReply.decode(readValue(buffer)!); case 132: - final int? value = readValue(buffer) as int?; - return value == null ? null : MessageRequestState.values[value]; + return MessageNested.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -188,36 +191,36 @@ class MessageApi { /// BinaryMessenger will be used which routes to the host platform. MessageApi( {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : __pigeon_binaryMessenger = binaryMessenger, - __pigeon_messageChannelSuffix = + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; - final BinaryMessenger? __pigeon_binaryMessenger; + final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - final String __pigeon_messageChannelSuffix; + final String pigeonVar_messageChannelSuffix; /// This comment is to test documentation comments. /// /// This comment also tests multiple line comments. Future initialize() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.MessageApi.initialize$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.MessageApi.initialize$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; @@ -226,31 +229,31 @@ class MessageApi { /// This comment is to test method documentation comments. Future search(MessageSearchRequest request) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.MessageApi.search$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.MessageApi.search$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([request]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([request]) 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 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 MessageSearchReply?)!; + return (pigeonVar_replyList[0] as MessageSearchReply?)!; } } } @@ -262,44 +265,44 @@ class MessageNestedApi { /// BinaryMessenger will be used which routes to the host platform. MessageNestedApi( {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : __pigeon_binaryMessenger = binaryMessenger, - __pigeon_messageChannelSuffix = + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; - final BinaryMessenger? __pigeon_binaryMessenger; + final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - final String __pigeon_messageChannelSuffix; + final String pigeonVar_messageChannelSuffix; /// This comment is to test method documentation comments. /// /// This comment also tests multiple line comments. Future search(MessageNested nested) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.MessageNestedApi.search$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.MessageNestedApi.search$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([nested]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([nested]) 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 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 MessageSearchReply?)!; + return (pigeonVar_replyList[0] as MessageSearchReply?)!; } } } @@ -319,15 +322,16 @@ abstract class MessageFlutterSearchApi { messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.MessageFlutterSearchApi.search$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.MessageFlutterSearchApi.search was null.'); final List args = (message as List?)!; diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/multiple_arity.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/multiple_arity.gen.dart index 33b984077af0..05197c29c3ce 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/multiple_arity.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/multiple_arity.gen.dart @@ -32,6 +32,23 @@ List wrapResponse( class _PigeonCodec extends StandardMessageCodec { const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + default: + return super.readValueOfType(type, buffer); + } + } } class MultipleArityHostApi { @@ -40,41 +57,41 @@ class MultipleArityHostApi { /// BinaryMessenger will be used which routes to the host platform. MultipleArityHostApi( {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : __pigeon_binaryMessenger = binaryMessenger, - __pigeon_messageChannelSuffix = + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; - final BinaryMessenger? __pigeon_binaryMessenger; + final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - final String __pigeon_messageChannelSuffix; + final String pigeonVar_messageChannelSuffix; Future subtract(int x, int y) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.MultipleArityHostApi.subtract$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.MultipleArityHostApi.subtract$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([x, y]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([x, y]) 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 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 int?)!; + return (pigeonVar_replyList[0] as int?)!; } } } @@ -92,15 +109,16 @@ abstract class MultipleArityFlutterApi { messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.MultipleArityFlutterApi.subtract$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.MultipleArityFlutterApi.subtract was null.'); final List args = (message as List?)!; diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/non_null_fields.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/non_null_fields.gen.dart index c9c7fe5a638e..c7a84edb7ab0 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/non_null_fields.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/non_null_fields.gen.dart @@ -127,18 +127,21 @@ class _PigeonCodec extends StandardMessageCodec { const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is NonNullFieldSearchRequest) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is ReplyType) { buffer.putUint8(129); - writeValue(buffer, value.encode()); - } else if (value is ExtraData) { + writeValue(buffer, value.index); + } else if (value is NonNullFieldSearchRequest) { buffer.putUint8(130); writeValue(buffer, value.encode()); - } else if (value is NonNullFieldSearchReply) { + } else if (value is ExtraData) { buffer.putUint8(131); writeValue(buffer, value.encode()); - } else if (value is ReplyType) { + } else if (value is NonNullFieldSearchReply) { buffer.putUint8(132); - writeValue(buffer, value.index); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -148,14 +151,14 @@ class _PigeonCodec extends StandardMessageCodec { Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { case 129: - return NonNullFieldSearchRequest.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : ReplyType.values[value]; case 130: - return ExtraData.decode(readValue(buffer)!); + return NonNullFieldSearchRequest.decode(readValue(buffer)!); case 131: - return NonNullFieldSearchReply.decode(readValue(buffer)!); + return ExtraData.decode(readValue(buffer)!); case 132: - final int? value = readValue(buffer) as int?; - return value == null ? null : ReplyType.values[value]; + return NonNullFieldSearchReply.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -168,42 +171,42 @@ class NonNullFieldHostApi { /// BinaryMessenger will be used which routes to the host platform. NonNullFieldHostApi( {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : __pigeon_binaryMessenger = binaryMessenger, - __pigeon_messageChannelSuffix = + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; - final BinaryMessenger? __pigeon_binaryMessenger; + final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - final String __pigeon_messageChannelSuffix; + final String pigeonVar_messageChannelSuffix; Future search( NonNullFieldSearchRequest nested) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.NonNullFieldHostApi.search$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.NonNullFieldHostApi.search$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([nested]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([nested]) 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 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 NonNullFieldSearchReply?)!; + return (pigeonVar_replyList[0] as NonNullFieldSearchReply?)!; } } } @@ -221,15 +224,16 @@ abstract class NonNullFieldFlutterApi { messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.NonNullFieldFlutterApi.search$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.NonNullFieldFlutterApi.search was null.'); final List args = (message as List?)!; diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/null_fields.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/null_fields.gen.dart index 578a7c28c316..9ef352f4a45e 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/null_fields.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/null_fields.gen.dart @@ -106,15 +106,18 @@ class _PigeonCodec extends StandardMessageCodec { const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is NullFieldsSearchRequest) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is NullFieldsSearchReplyType) { buffer.putUint8(129); - writeValue(buffer, value.encode()); - } else if (value is NullFieldsSearchReply) { + writeValue(buffer, value.index); + } else if (value is NullFieldsSearchRequest) { buffer.putUint8(130); writeValue(buffer, value.encode()); - } else if (value is NullFieldsSearchReplyType) { + } else if (value is NullFieldsSearchReply) { buffer.putUint8(131); - writeValue(buffer, value.index); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -124,12 +127,12 @@ class _PigeonCodec extends StandardMessageCodec { Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { case 129: - return NullFieldsSearchRequest.decode(readValue(buffer)!); - case 130: - return NullFieldsSearchReply.decode(readValue(buffer)!); - case 131: final int? value = readValue(buffer) as int?; return value == null ? null : NullFieldsSearchReplyType.values[value]; + case 130: + return NullFieldsSearchRequest.decode(readValue(buffer)!); + case 131: + return NullFieldsSearchReply.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -142,41 +145,41 @@ class NullFieldsHostApi { /// BinaryMessenger will be used which routes to the host platform. NullFieldsHostApi( {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : __pigeon_binaryMessenger = binaryMessenger, - __pigeon_messageChannelSuffix = + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; - final BinaryMessenger? __pigeon_binaryMessenger; + final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - final String __pigeon_messageChannelSuffix; + final String pigeonVar_messageChannelSuffix; Future search(NullFieldsSearchRequest nested) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.NullFieldsHostApi.search$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.NullFieldsHostApi.search$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([nested]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([nested]) 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 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 NullFieldsSearchReply?)!; + return (pigeonVar_replyList[0] as NullFieldsSearchReply?)!; } } } @@ -194,15 +197,16 @@ abstract class NullFieldsFlutterApi { messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.NullFieldsFlutterApi.search$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.NullFieldsFlutterApi.search was null.'); final List args = (message as List?)!; diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/nullable_returns.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/nullable_returns.gen.dart index 72ea0ae7363f..99cb3a3bf928 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/nullable_returns.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/nullable_returns.gen.dart @@ -32,6 +32,23 @@ List wrapResponse( class _PigeonCodec extends StandardMessageCodec { const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + default: + return super.readValueOfType(type, buffer); + } + } } class NullableReturnHostApi { @@ -40,36 +57,36 @@ class NullableReturnHostApi { /// BinaryMessenger will be used which routes to the host platform. NullableReturnHostApi( {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : __pigeon_binaryMessenger = binaryMessenger, - __pigeon_messageChannelSuffix = + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; - final BinaryMessenger? __pigeon_binaryMessenger; + final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - final String __pigeon_messageChannelSuffix; + final String pigeonVar_messageChannelSuffix; Future doit() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.NullableReturnHostApi.doit$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.NullableReturnHostApi.doit$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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?); } } } @@ -87,15 +104,16 @@ abstract class NullableReturnFlutterApi { messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.NullableReturnFlutterApi.doit$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { try { final int? output = api.doit(); return wrapResponse(result: output); @@ -117,41 +135,41 @@ class NullableArgHostApi { /// BinaryMessenger will be used which routes to the host platform. NullableArgHostApi( {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : __pigeon_binaryMessenger = binaryMessenger, - __pigeon_messageChannelSuffix = + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; - final BinaryMessenger? __pigeon_binaryMessenger; + final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - final String __pigeon_messageChannelSuffix; + final String pigeonVar_messageChannelSuffix; Future doit(int? x) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.NullableArgHostApi.doit$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.NullableArgHostApi.doit$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([x]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([x]) 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 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 int?)!; + return (pigeonVar_replyList[0] as int?)!; } } } @@ -169,15 +187,16 @@ abstract class NullableArgFlutterApi { messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.NullableArgFlutterApi.doit$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.NullableArgFlutterApi.doit was null.'); final List args = (message as List?)!; @@ -203,36 +222,36 @@ class NullableCollectionReturnHostApi { /// BinaryMessenger will be used which routes to the host platform. NullableCollectionReturnHostApi( {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : __pigeon_binaryMessenger = binaryMessenger, - __pigeon_messageChannelSuffix = + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; - final BinaryMessenger? __pigeon_binaryMessenger; + final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - final String __pigeon_messageChannelSuffix; + final String pigeonVar_messageChannelSuffix; Future?> doit() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.NullableCollectionReturnHostApi.doit$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.NullableCollectionReturnHostApi.doit$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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(); } } } @@ -250,15 +269,16 @@ abstract class NullableCollectionReturnFlutterApi { messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.NullableCollectionReturnFlutterApi.doit$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { try { final List? output = api.doit(); return wrapResponse(result: output); @@ -280,41 +300,41 @@ class NullableCollectionArgHostApi { /// BinaryMessenger will be used which routes to the host platform. NullableCollectionArgHostApi( {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : __pigeon_binaryMessenger = binaryMessenger, - __pigeon_messageChannelSuffix = + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; - final BinaryMessenger? __pigeon_binaryMessenger; + final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - final String __pigeon_messageChannelSuffix; + final String pigeonVar_messageChannelSuffix; Future> doit(List? x) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.NullableCollectionArgHostApi.doit$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.NullableCollectionArgHostApi.doit$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([x]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([x]) 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 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(); } } } @@ -332,15 +352,16 @@ abstract class NullableCollectionArgFlutterApi { messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.NullableCollectionArgFlutterApi.doit$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.NullableCollectionArgFlutterApi.doit was null.'); final List args = (message as List?)!; diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/primitive.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/primitive.gen.dart index 8ac914eb6fad..e6f864538078 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/primitive.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/primitive.gen.dart @@ -32,6 +32,23 @@ List wrapResponse( class _PigeonCodec extends StandardMessageCodec { const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + default: + return super.readValueOfType(type, buffer); + } + } } class PrimitiveHostApi { @@ -40,273 +57,273 @@ class PrimitiveHostApi { /// BinaryMessenger will be used which routes to the host platform. PrimitiveHostApi( {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : __pigeon_binaryMessenger = binaryMessenger, - __pigeon_messageChannelSuffix = + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; - final BinaryMessenger? __pigeon_binaryMessenger; + final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - final String __pigeon_messageChannelSuffix; + final String pigeonVar_messageChannelSuffix; Future anInt(int value) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.anInt$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.anInt$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([value]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([value]) 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 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 int?)!; + return (pigeonVar_replyList[0] as int?)!; } } Future aBool(bool value) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.aBool$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.aBool$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([value]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([value]) 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 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 bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } Future aString(String value) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.aString$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.aString$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([value]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([value]) 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 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 String?)!; + return (pigeonVar_replyList[0] as String?)!; } } Future aDouble(double value) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.aDouble$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.aDouble$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([value]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([value]) 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 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 double?)!; + return (pigeonVar_replyList[0] as double?)!; } } Future> aMap(Map value) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.aMap$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.aMap$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([value]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([value]) 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 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?)!; + return (pigeonVar_replyList[0] as Map?)!; } } Future> aList(List value) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.aList$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.aList$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([value]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([value]) 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 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?)!; + return (pigeonVar_replyList[0] as List?)!; } } Future anInt32List(Int32List value) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.anInt32List$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.anInt32List$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([value]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([value]) 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 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 Int32List?)!; + return (pigeonVar_replyList[0] as Int32List?)!; } } Future> aBoolList(List value) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.aBoolList$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.aBoolList$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([value]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([value]) 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 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(); } } Future> aStringIntMap(Map value) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.aStringIntMap$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.aStringIntMap$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([value]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([value]) 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 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?)! + return (pigeonVar_replyList[0] as Map?)! .cast(); } } @@ -341,15 +358,16 @@ abstract class PrimitiveFlutterApi { messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveFlutterApi.anInt$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.PrimitiveFlutterApi.anInt was null.'); final List args = (message as List?)!; @@ -369,15 +387,16 @@ abstract class PrimitiveFlutterApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveFlutterApi.aBool$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.PrimitiveFlutterApi.aBool was null.'); final List args = (message as List?)!; @@ -397,15 +416,16 @@ abstract class PrimitiveFlutterApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveFlutterApi.aString$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.PrimitiveFlutterApi.aString was null.'); final List args = (message as List?)!; @@ -425,15 +445,16 @@ abstract class PrimitiveFlutterApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveFlutterApi.aDouble$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.PrimitiveFlutterApi.aDouble was null.'); final List args = (message as List?)!; @@ -453,15 +474,16 @@ abstract class PrimitiveFlutterApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveFlutterApi.aMap$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.PrimitiveFlutterApi.aMap was null.'); final List args = (message as List?)!; @@ -482,15 +504,16 @@ abstract class PrimitiveFlutterApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveFlutterApi.aList$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.PrimitiveFlutterApi.aList was null.'); final List args = (message as List?)!; @@ -510,15 +533,16 @@ abstract class PrimitiveFlutterApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveFlutterApi.anInt32List$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.PrimitiveFlutterApi.anInt32List was null.'); final List args = (message as List?)!; @@ -538,15 +562,16 @@ abstract class PrimitiveFlutterApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveFlutterApi.aBoolList$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.PrimitiveFlutterApi.aBoolList was null.'); final List args = (message as List?)!; @@ -567,15 +592,16 @@ abstract class PrimitiveFlutterApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.PrimitiveFlutterApi.aStringIntMap$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.PrimitiveFlutterApi.aStringIntMap was null.'); final List args = (message as List?)!; diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/proxy_api_tests.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/proxy_api_tests.gen.dart index 97dbbc67559e..54d95c4149b7 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/proxy_api_tests.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/proxy_api_tests.gen.dart @@ -38,9 +38,9 @@ List wrapResponse( /// All implementers are expected to be [immutable] as defined by the annotation /// and override [pigeon_copy] returning an instance of itself. @immutable -abstract class PigeonProxyApiBaseClass { - /// Construct a [PigeonProxyApiBaseClass]. - PigeonProxyApiBaseClass({ +abstract class PigeonInternalProxyApiBaseClass { + /// Construct a [PigeonInternalProxyApiBaseClass]. + PigeonInternalProxyApiBaseClass({ this.pigeon_binaryMessenger, PigeonInstanceManager? pigeon_instanceManager, }) : pigeon_instanceManager = @@ -65,7 +65,7 @@ abstract class PigeonProxyApiBaseClass { /// Subclasses should always override their parent's implementation of this /// method. @protected - PigeonProxyApiBaseClass pigeon_copy(); + PigeonInternalProxyApiBaseClass pigeon_copy(); } /// Maintains instances used to communicate with the native objects they @@ -115,10 +115,10 @@ class PigeonInstanceManager { // by calling instanceManager.getIdentifier() inside of `==` while this was a // HashMap). final Expando _identifiers = Expando(); - final Map> _weakInstances = - >{}; - final Map _strongInstances = - {}; + final Map> + _weakInstances = >{}; + final Map _strongInstances = + {}; late final Finalizer _finalizer; int _nextIdentifier = 0; @@ -128,7 +128,8 @@ class PigeonInstanceManager { static PigeonInstanceManager _initInstance() { WidgetsFlutterBinding.ensureInitialized(); - final _PigeonInstanceManagerApi api = _PigeonInstanceManagerApi(); + final _PigeonInternalInstanceManagerApi api = + _PigeonInternalInstanceManagerApi(); // Clears the native `PigeonInstanceManager` on the initial use of the Dart one. api.clear(); final PigeonInstanceManager instanceManager = PigeonInstanceManager( @@ -136,7 +137,7 @@ class PigeonInstanceManager { api.removeStrongReference(identifier); }, ); - _PigeonInstanceManagerApi.setUpMessageHandlers( + _PigeonInternalInstanceManagerApi.setUpMessageHandlers( instanceManager: instanceManager); ProxyApiTestClass.pigeon_setUpMessageHandlers( pigeon_instanceManager: instanceManager); @@ -144,6 +145,8 @@ class PigeonInstanceManager { pigeon_instanceManager: instanceManager); ProxyApiInterface.pigeon_setUpMessageHandlers( pigeon_instanceManager: instanceManager); + ClassWithApiRequirement.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); return instanceManager; } @@ -155,7 +158,7 @@ class PigeonInstanceManager { /// Throws assertion error if the instance has already been added. /// /// Returns the randomly generated id of the [instance] added. - int addDartCreatedInstance(PigeonProxyApiBaseClass instance) { + int addDartCreatedInstance(PigeonInternalProxyApiBaseClass instance) { final int identifier = _nextUniqueIdentifier(); _addInstanceWithIdentifier(instance, identifier); return identifier; @@ -169,7 +172,7 @@ class PigeonInstanceManager { /// /// This does not remove the strong referenced instance associated with /// [instance]. This can be done with [remove]. - int? removeWeakReference(PigeonProxyApiBaseClass instance) { + int? removeWeakReference(PigeonInternalProxyApiBaseClass instance) { final int? identifier = getIdentifier(instance); if (identifier == null) { return null; @@ -191,7 +194,7 @@ class PigeonInstanceManager { /// /// This does not remove the weak referenced instance associated with /// [identifier]. This can be done with [removeWeakReference]. - T? remove(int identifier) { + T? remove(int identifier) { return _strongInstances.remove(identifier) as T?; } @@ -207,19 +210,20 @@ class PigeonInstanceManager { /// /// This method also expects the host `InstanceManager` to have a strong /// reference to the instance the identifier is associated with. - T? getInstanceWithWeakReference( + T? getInstanceWithWeakReference( int identifier) { - final PigeonProxyApiBaseClass? weakInstance = + final PigeonInternalProxyApiBaseClass? weakInstance = _weakInstances[identifier]?.target; if (weakInstance == null) { - final PigeonProxyApiBaseClass? strongInstance = + final PigeonInternalProxyApiBaseClass? strongInstance = _strongInstances[identifier]; if (strongInstance != null) { - final PigeonProxyApiBaseClass copy = strongInstance.pigeon_copy(); + final PigeonInternalProxyApiBaseClass copy = + strongInstance.pigeon_copy(); _identifiers[copy] = identifier; _weakInstances[identifier] = - WeakReference(copy); + WeakReference(copy); _finalizer.attach(copy, identifier, detach: copy); return copy as T; } @@ -230,7 +234,7 @@ class PigeonInstanceManager { } /// Retrieves the identifier associated with instance. - int? getIdentifier(PigeonProxyApiBaseClass instance) { + int? getIdentifier(PigeonInternalProxyApiBaseClass instance) { return _identifiers[instance]; } @@ -244,22 +248,22 @@ class PigeonInstanceManager { /// /// Returns unique identifier of the [instance] added. void addHostCreatedInstance( - PigeonProxyApiBaseClass instance, int identifier) { + PigeonInternalProxyApiBaseClass instance, int identifier) { _addInstanceWithIdentifier(instance, identifier); } void _addInstanceWithIdentifier( - PigeonProxyApiBaseClass instance, int identifier) { + PigeonInternalProxyApiBaseClass instance, int identifier) { assert(!containsIdentifier(identifier)); assert(getIdentifier(instance) == null); assert(identifier >= 0); _identifiers[instance] = identifier; _weakInstances[identifier] = - WeakReference(instance); + WeakReference(instance); _finalizer.attach(instance, identifier, detach: instance); - final PigeonProxyApiBaseClass copy = instance.pigeon_copy(); + final PigeonInternalProxyApiBaseClass copy = instance.pigeon_copy(); _identifiers[copy] = identifier; _strongInstances[identifier] = copy; } @@ -281,15 +285,14 @@ class PigeonInstanceManager { } /// Generated API for managing the Dart and native `PigeonInstanceManager`s. -class _PigeonInstanceManagerApi { - /// Constructor for [_PigeonInstanceManagerApi]. - _PigeonInstanceManagerApi({BinaryMessenger? binaryMessenger}) - : __pigeon_binaryMessenger = binaryMessenger; +class _PigeonInternalInstanceManagerApi { + /// Constructor for [_PigeonInternalInstanceManagerApi]. + _PigeonInternalInstanceManagerApi({BinaryMessenger? binaryMessenger}) + : pigeonVar_binaryMessenger = binaryMessenger; - final BinaryMessenger? __pigeon_binaryMessenger; + final BinaryMessenger? pigeonVar_binaryMessenger; - static const MessageCodec pigeonChannelCodec = - StandardMessageCodec(); + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); static void setUpMessageHandlers({ bool pigeon_clearHandlers = false, @@ -297,21 +300,22 @@ class _PigeonInstanceManagerApi { PigeonInstanceManager? instanceManager, }) { { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.pigeon_integration_tests.PigeonInstanceManagerApi.removeStrongReference', + 'dev.flutter.pigeon.pigeon_integration_tests.PigeonInternalInstanceManager.removeStrongReference', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.PigeonInstanceManagerApi.removeStrongReference was null.'); + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.PigeonInternalInstanceManager.removeStrongReference was null.'); final List args = (message as List?)!; final int? arg_identifier = (args[0] as int?); assert(arg_identifier != null, - 'Argument for dev.flutter.pigeon.pigeon_integration_tests.PigeonInstanceManagerApi.removeStrongReference was null, expected non-null int.'); + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.PigeonInternalInstanceManager.removeStrongReference was null, expected non-null int.'); try { (instanceManager ?? PigeonInstanceManager.instance) .remove(arg_identifier!); @@ -328,23 +332,23 @@ class _PigeonInstanceManagerApi { } Future removeStrongReference(int identifier) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.PigeonInstanceManagerApi.removeStrongReference'; - final BasicMessageChannel __pigeon_channel = + const String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.PigeonInternalInstanceManager.removeStrongReference'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([identifier]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([identifier]) 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; @@ -355,23 +359,23 @@ class _PigeonInstanceManagerApi { /// /// This is typically called after a hot restart. Future clear() async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.pigeon_integration_tests.PigeonInstanceManagerApi.clear'; - final BasicMessageChannel __pigeon_channel = + const String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.PigeonInternalInstanceManager.clear'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; @@ -379,12 +383,12 @@ class _PigeonInstanceManagerApi { } } -class _PigeonProxyApiBaseCodec extends _PigeonCodec { - const _PigeonProxyApiBaseCodec(this.instanceManager); +class _PigeonInternalProxyApiBaseCodec extends _PigeonCodec { + const _PigeonInternalProxyApiBaseCodec(this.instanceManager); final PigeonInstanceManager instanceManager; @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is PigeonProxyApiBaseClass) { + if (value is PigeonInternalProxyApiBaseClass) { buffer.putUint8(128); writeValue(buffer, instanceManager.getIdentifier(value)); } else { @@ -414,7 +418,10 @@ class _PigeonCodec extends StandardMessageCodec { const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is ProxyApiTestEnum) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is ProxyApiTestEnum) { buffer.putUint8(129); writeValue(buffer, value.index); } else { @@ -504,23 +511,23 @@ class ProxyApiTestClass extends ProxyApiSuperClass ProxyApiTestEnum? nullableEnumParam, ProxyApiSuperClass? nullableProxyApiParam, }) : super.pigeon_detached() { - final int __pigeon_instanceIdentifier = + final int pigeonVar_instanceIdentifier = pigeon_instanceManager.addDartCreatedInstance(this); - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; () async { - const String __pigeon_channelName = + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.pigeon_defaultConstructor'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([ - __pigeon_instanceIdentifier, + final List? pigeonVar_replyList = + await pigeonVar_channel.send([ + pigeonVar_instanceIdentifier, aBool, anInt, aDouble, @@ -558,13 +565,13 @@ class ProxyApiTestClass extends ProxyApiSuperClass nullableEnumParam, nullableProxyApiParam ]) 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; @@ -626,8 +633,9 @@ class ProxyApiTestClass extends ProxyApiSuperClass this.flutterEchoAsyncString, }) : super.pigeon_detached(); - late final _PigeonProxyApiBaseCodec __pigeon_codecProxyApiTestClass = - _PigeonProxyApiBaseCodec(pigeon_instanceManager); + late final _PigeonInternalProxyApiBaseCodec + _pigeonVar_codecProxyApiTestClass = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); final bool aBool; @@ -1262,10 +1270,10 @@ class ProxyApiTestClass extends ProxyApiSuperClass @override final void Function(ProxyApiInterface pigeon_instance)? anInterfaceMethod; - late final ProxyApiSuperClass attachedField = __pigeon_attachedField(); + late final ProxyApiSuperClass attachedField = pigeonVar_attachedField(); static final ProxyApiSuperClass staticAttachedField = - __pigeon_staticAttachedField(); + pigeonVar_staticAttachedField(); static void pigeon_setUpMessageHandlers({ bool pigeon_clearHandlers = false, @@ -1380,20 +1388,21 @@ class ProxyApiTestClass extends ProxyApiSuperClass String aString, )? flutterEchoAsyncString, }) { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - _PigeonProxyApiBaseCodec( + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( pigeon_instanceManager ?? PigeonInstanceManager.instance); final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.pigeon_newInstance', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.pigeon_newInstance was null.'); final List args = (message as List?)!; @@ -1501,15 +1510,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterNoop', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterNoop was null.'); final List args = (message as List?)!; @@ -1532,15 +1542,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterThrowError', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterThrowError was null.'); final List args = (message as List?)!; @@ -1564,15 +1575,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterThrowErrorFromVoid', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterThrowErrorFromVoid was null.'); final List args = (message as List?)!; @@ -1596,15 +1608,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoBool', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoBool was null.'); final List args = (message as List?)!; @@ -1631,15 +1644,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoInt', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoInt was null.'); final List args = (message as List?)!; @@ -1666,15 +1680,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoDouble', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoDouble was null.'); final List args = (message as List?)!; @@ -1701,15 +1716,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoString', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoString was null.'); final List args = (message as List?)!; @@ -1736,15 +1752,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoUint8List', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoUint8List was null.'); final List args = (message as List?)!; @@ -1771,15 +1788,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoList', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoList was null.'); final List args = (message as List?)!; @@ -1807,15 +1825,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoProxyApiList', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoProxyApiList was null.'); final List args = (message as List?)!; @@ -1843,15 +1862,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoMap', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoMap was null.'); final List args = (message as List?)!; @@ -1879,15 +1899,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoProxyApiMap', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoProxyApiMap was null.'); final List args = (message as List?)!; @@ -1917,15 +1938,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoEnum', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoEnum was null.'); final List args = (message as List?)!; @@ -1952,15 +1974,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoProxyApi', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoProxyApi was null.'); final List args = (message as List?)!; @@ -1988,15 +2011,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableBool', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableBool was null.'); final List args = (message as List?)!; @@ -2021,15 +2045,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableInt', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableInt was null.'); final List args = (message as List?)!; @@ -2054,15 +2079,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableDouble', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableDouble was null.'); final List args = (message as List?)!; @@ -2087,15 +2113,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableString', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableString was null.'); final List args = (message as List?)!; @@ -2120,15 +2147,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableUint8List', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableUint8List was null.'); final List args = (message as List?)!; @@ -2153,15 +2181,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableList', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableList was null.'); final List args = (message as List?)!; @@ -2187,15 +2216,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableMap', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableMap was null.'); final List args = (message as List?)!; @@ -2221,15 +2251,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableEnum', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableEnum was null.'); final List args = (message as List?)!; @@ -2254,15 +2285,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableProxyApi', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableProxyApi was null.'); final List args = (message as List?)!; @@ -2288,15 +2320,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterNoopAsync', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterNoopAsync was null.'); final List args = (message as List?)!; @@ -2319,15 +2352,16 @@ class ProxyApiTestClass extends ProxyApiSuperClass } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoAsyncString', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoAsyncString was null.'); final List args = (message as List?)!; @@ -2354,101 +2388,102 @@ class ProxyApiTestClass extends ProxyApiSuperClass } } - ProxyApiSuperClass __pigeon_attachedField() { - final ProxyApiSuperClass __pigeon_instance = + ProxyApiSuperClass pigeonVar_attachedField() { + final ProxyApiSuperClass pigeonVar_instance = ProxyApiSuperClass.pigeon_detached( pigeon_binaryMessenger: pigeon_binaryMessenger, pigeon_instanceManager: pigeon_instanceManager, ); - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - final int __pigeon_instanceIdentifier = - pigeon_instanceManager.addDartCreatedInstance(__pigeon_instance); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + final int pigeonVar_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(pigeonVar_instance); () async { - const String __pigeon_channelName = + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.attachedField'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = await __pigeon_channel - .send([this, __pigeon_instanceIdentifier]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, pigeonVar_instanceIdentifier]) + 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; } }(); - return __pigeon_instance; + return pigeonVar_instance; } - static ProxyApiSuperClass __pigeon_staticAttachedField() { - final ProxyApiSuperClass __pigeon_instance = + static ProxyApiSuperClass pigeonVar_staticAttachedField() { + final ProxyApiSuperClass pigeonVar_instance = ProxyApiSuperClass.pigeon_detached(); - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - _PigeonProxyApiBaseCodec(PigeonInstanceManager.instance); - final BinaryMessenger __pigeon_binaryMessenger = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec(PigeonInstanceManager.instance); + final BinaryMessenger pigeonVar_binaryMessenger = ServicesBinding.instance.defaultBinaryMessenger; - final int __pigeon_instanceIdentifier = PigeonInstanceManager.instance - .addDartCreatedInstance(__pigeon_instance); + final int pigeonVar_instanceIdentifier = PigeonInstanceManager.instance + .addDartCreatedInstance(pigeonVar_instance); () async { - const String __pigeon_channelName = + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.staticAttachedField'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = await __pigeon_channel - .send([__pigeon_instanceIdentifier]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([pigeonVar_instanceIdentifier]) 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; } }(); - return __pigeon_instance; + return pigeonVar_instance; } /// A no-op function taking no arguments and returning no value, to sanity /// test basic calling. Future noop() async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.noop'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) 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; @@ -2457,54 +2492,54 @@ class ProxyApiTestClass extends ProxyApiSuperClass /// Returns an error, to test error handling. Future throwError() async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.throwError'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) 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]; + return pigeonVar_replyList[0]; } } /// Returns an error from a void function, to test error handling. Future throwErrorFromVoid() async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.throwErrorFromVoid'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) 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; @@ -2513,742 +2548,742 @@ class ProxyApiTestClass extends ProxyApiSuperClass /// Returns a Flutter error, to test error handling. Future throwFlutterError() async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.throwFlutterError'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) 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]; + return pigeonVar_replyList[0]; } } /// Returns passed in int. Future echoInt(int anInt) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoInt'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, anInt]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, anInt]) 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 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 int?)!; + return (pigeonVar_replyList[0] as int?)!; } } /// Returns passed in double. Future echoDouble(double aDouble) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoDouble'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aDouble]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, aDouble]) 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 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 double?)!; + return (pigeonVar_replyList[0] as double?)!; } } /// Returns the passed in boolean. Future echoBool(bool aBool) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoBool'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aBool]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, aBool]) 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 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 bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } /// Returns the passed in string. Future echoString(String aString) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoString'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aString]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, aString]) 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 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 String?)!; + return (pigeonVar_replyList[0] as String?)!; } } /// Returns the passed in Uint8List. Future echoUint8List(Uint8List aUint8List) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoUint8List'; - final BasicMessageChannel __pigeon_channel = + 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([this, aUint8List]) 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 Uint8List?)!; + return (pigeonVar_replyList[0] as Uint8List?)!; } } /// Returns the passed in generic Object. Future echoObject(Object anObject) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoObject'; - final BasicMessageChannel __pigeon_channel = + 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([this, anObject]) 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]!; + return pigeonVar_replyList[0]!; } } /// Returns the passed list, to test serialization and deserialization. Future> echoList(List aList) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoList'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aList]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, aList]) 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 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(); } } /// Returns the passed list with ProxyApis, to test serialization and /// deserialization. - Future> echoProxyApiList( - List aList) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + Future> echoProxyApiList( + List aList) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoProxyApiList'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aList]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, aList]) 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 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(); } } /// Returns the passed map, to test serialization and deserialization. Future> echoMap(Map aMap) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoMap'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aMap]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, aMap]) 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 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?)! + return (pigeonVar_replyList[0] as Map?)! .cast(); } } /// Returns the passed map with ProxyApis, to test serialization and /// deserialization. - Future> echoProxyApiMap( - Map aMap) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + Future> echoProxyApiMap( + Map aMap) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoProxyApiMap'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aMap]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, aMap]) 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 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(); } } /// Returns the passed enum to test serialization and deserialization. Future echoEnum(ProxyApiTestEnum anEnum) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoEnum'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, anEnum]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, anEnum]) 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 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 ProxyApiTestEnum?)!; + return (pigeonVar_replyList[0] as ProxyApiTestEnum?)!; } } /// Returns the passed ProxyApi to test serialization and deserialization. Future echoProxyApi(ProxyApiSuperClass aProxyApi) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoProxyApi'; - final BasicMessageChannel __pigeon_channel = + 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([this, aProxyApi]) 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 ProxyApiSuperClass?)!; + return (pigeonVar_replyList[0] as ProxyApiSuperClass?)!; } } /// Returns passed in int. Future echoNullableInt(int? aNullableInt) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableInt'; - final BasicMessageChannel __pigeon_channel = + 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([this, aNullableInt]) 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 (__pigeon_replyList[0] as int?); + return (pigeonVar_replyList[0] as int?); } } /// Returns passed in double. Future echoNullableDouble(double? aNullableDouble) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableDouble'; - final BasicMessageChannel __pigeon_channel = + 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([this, aNullableDouble]) 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 (__pigeon_replyList[0] as double?); + return (pigeonVar_replyList[0] as double?); } } /// Returns the passed in boolean. Future echoNullableBool(bool? aNullableBool) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableBool'; - final BasicMessageChannel __pigeon_channel = + 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([this, aNullableBool]) 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 (__pigeon_replyList[0] as bool?); + return (pigeonVar_replyList[0] as bool?); } } /// Returns the passed in string. Future echoNullableString(String? aNullableString) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableString'; - final BasicMessageChannel __pigeon_channel = + 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([this, aNullableString]) 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 (__pigeon_replyList[0] as String?); + return (pigeonVar_replyList[0] as String?); } } /// Returns the passed in Uint8List. Future echoNullableUint8List( Uint8List? aNullableUint8List) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableUint8List'; - final BasicMessageChannel __pigeon_channel = + 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([this, aNullableUint8List]) 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 (__pigeon_replyList[0] as Uint8List?); + return (pigeonVar_replyList[0] as Uint8List?); } } /// Returns the passed in generic Object. Future echoNullableObject(Object? aNullableObject) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableObject'; - final BasicMessageChannel __pigeon_channel = + 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([this, aNullableObject]) 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 __pigeon_replyList[0]; + return pigeonVar_replyList[0]; } } /// Returns the passed list, to test serialization and deserialization. Future?> echoNullableList(List? aNullableList) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableList'; - final BasicMessageChannel __pigeon_channel = + 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([this, aNullableList]) 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 (__pigeon_replyList[0] as List?)?.cast(); + return (pigeonVar_replyList[0] as List?)?.cast(); } } /// Returns the passed map, to test serialization and deserialization. Future?> echoNullableMap( Map? aNullableMap) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableMap'; - final BasicMessageChannel __pigeon_channel = + 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([this, aNullableMap]) 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 (__pigeon_replyList[0] as Map?) + return (pigeonVar_replyList[0] as Map?) ?.cast(); } } Future echoNullableEnum( ProxyApiTestEnum? aNullableEnum) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableEnum'; - final BasicMessageChannel __pigeon_channel = + 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([this, aNullableEnum]) 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 (__pigeon_replyList[0] as ProxyApiTestEnum?); + return (pigeonVar_replyList[0] as ProxyApiTestEnum?); } } /// Returns the passed ProxyApi to test serialization and deserialization. Future echoNullableProxyApi( ProxyApiSuperClass? aNullableProxyApi) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableProxyApi'; - final BasicMessageChannel __pigeon_channel = + 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([this, aNullableProxyApi]) 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 (__pigeon_replyList[0] as ProxyApiSuperClass?); + return (pigeonVar_replyList[0] as ProxyApiSuperClass?); } } /// A no-op function taking no arguments and returning no value, to sanity /// test basic asynchronous calling. Future noopAsync() async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.noopAsync'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) 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; @@ -3257,352 +3292,352 @@ class ProxyApiTestClass extends ProxyApiSuperClass /// Returns passed in int asynchronously. Future echoAsyncInt(int anInt) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncInt'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, anInt]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, anInt]) 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 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 int?)!; + return (pigeonVar_replyList[0] as int?)!; } } /// Returns passed in double asynchronously. Future echoAsyncDouble(double aDouble) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncDouble'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aDouble]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, aDouble]) 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 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 double?)!; + return (pigeonVar_replyList[0] as double?)!; } } /// Returns the passed in boolean asynchronously. Future echoAsyncBool(bool aBool) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncBool'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aBool]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, aBool]) 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 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 bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } /// Returns the passed string asynchronously. Future echoAsyncString(String aString) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncString'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aString]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, aString]) 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 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 String?)!; + return (pigeonVar_replyList[0] as String?)!; } } /// Returns the passed in Uint8List asynchronously. Future echoAsyncUint8List(Uint8List aUint8List) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncUint8List'; - final BasicMessageChannel __pigeon_channel = + 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([this, aUint8List]) 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 Uint8List?)!; + return (pigeonVar_replyList[0] as Uint8List?)!; } } /// Returns the passed in generic Object asynchronously. Future echoAsyncObject(Object anObject) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncObject'; - final BasicMessageChannel __pigeon_channel = + 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([this, anObject]) 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]!; + return pigeonVar_replyList[0]!; } } /// Returns the passed list, to test asynchronous serialization and deserialization. Future> echoAsyncList(List aList) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncList'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aList]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, aList]) 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 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(); } } /// Returns the passed map, to test asynchronous serialization and deserialization. Future> echoAsyncMap(Map aMap) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncMap'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aMap]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, aMap]) 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 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?)! + return (pigeonVar_replyList[0] as Map?)! .cast(); } } /// Returns the passed enum, to test asynchronous serialization and deserialization. Future echoAsyncEnum(ProxyApiTestEnum anEnum) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncEnum'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, anEnum]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, anEnum]) 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 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 ProxyApiTestEnum?)!; + return (pigeonVar_replyList[0] as ProxyApiTestEnum?)!; } } /// Responds with an error from an async function returning a value. Future throwAsyncError() async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.throwAsyncError'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) 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]; + return pigeonVar_replyList[0]; } } /// Responds with an error from an async void function. Future throwAsyncErrorFromVoid() async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.throwAsyncErrorFromVoid'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) 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; @@ -3611,254 +3646,254 @@ class ProxyApiTestClass extends ProxyApiSuperClass /// Responds with a Flutter error from an async function returning a value. Future throwAsyncFlutterError() async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.throwAsyncFlutterError'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) 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]; + return pigeonVar_replyList[0]; } } /// Returns passed in int asynchronously. Future echoAsyncNullableInt(int? anInt) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableInt'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, anInt]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, anInt]) 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?); } } /// Returns passed in double asynchronously. Future echoAsyncNullableDouble(double? aDouble) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableDouble'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aDouble]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, aDouble]) 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?); } } /// Returns the passed in boolean asynchronously. Future echoAsyncNullableBool(bool? aBool) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableBool'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aBool]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, aBool]) 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?); } } /// Returns the passed string asynchronously. Future echoAsyncNullableString(String? aString) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableString'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aString]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, aString]) 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?); } } /// Returns the passed in Uint8List asynchronously. Future echoAsyncNullableUint8List(Uint8List? aUint8List) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableUint8List'; - final BasicMessageChannel __pigeon_channel = + 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([this, aUint8List]) 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 (__pigeon_replyList[0] as Uint8List?); + return (pigeonVar_replyList[0] as Uint8List?); } } /// Returns the passed in generic Object asynchronously. Future echoAsyncNullableObject(Object? anObject) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableObject'; - final BasicMessageChannel __pigeon_channel = + 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([this, anObject]) 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 __pigeon_replyList[0]; + return pigeonVar_replyList[0]; } } /// Returns the passed list, to test asynchronous serialization and deserialization. Future?> echoAsyncNullableList(List? aList) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableList'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aList]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, aList]) 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(); } } /// Returns the passed map, to test asynchronous serialization and deserialization. Future?> echoAsyncNullableMap( Map? aMap) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableMap'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aMap]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, aMap]) 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 Map?) + return (pigeonVar_replyList[0] as Map?) ?.cast(); } } @@ -3866,29 +3901,29 @@ class ProxyApiTestClass extends ProxyApiSuperClass /// Returns the passed enum, to test asynchronous serialization and deserialization. Future echoAsyncNullableEnum( ProxyApiTestEnum? anEnum) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableEnum'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, anEnum]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, anEnum]) 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 ProxyApiTestEnum?); + return (pigeonVar_replyList[0] as ProxyApiTestEnum?); } } @@ -3896,27 +3931,27 @@ class ProxyApiTestClass extends ProxyApiSuperClass BinaryMessenger? pigeon_binaryMessenger, PigeonInstanceManager? pigeon_instanceManager, }) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - _PigeonProxyApiBaseCodec( + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( pigeon_instanceManager ?? PigeonInstanceManager.instance); - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.staticNoop'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; @@ -3928,35 +3963,35 @@ class ProxyApiTestClass extends ProxyApiSuperClass BinaryMessenger? pigeon_binaryMessenger, PigeonInstanceManager? pigeon_instanceManager, }) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - _PigeonProxyApiBaseCodec( + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( pigeon_instanceManager ?? PigeonInstanceManager.instance); - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoStaticString'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([aString]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([aString]) 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 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 String?)!; + return (pigeonVar_replyList[0] as String?)!; } } @@ -3964,27 +3999,27 @@ class ProxyApiTestClass extends ProxyApiSuperClass BinaryMessenger? pigeon_binaryMessenger, PigeonInstanceManager? pigeon_instanceManager, }) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - _PigeonProxyApiBaseCodec( + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( pigeon_instanceManager ?? PigeonInstanceManager.instance); - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.staticAsyncNoop'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; @@ -3992,26 +4027,26 @@ class ProxyApiTestClass extends ProxyApiSuperClass } Future callFlutterNoop() async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterNoop'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) 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; @@ -4019,53 +4054,53 @@ class ProxyApiTestClass extends ProxyApiSuperClass } Future callFlutterThrowError() async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterThrowError'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) 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]; + return pigeonVar_replyList[0]; } } Future callFlutterThrowErrorFromVoid() async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterThrowErrorFromVoid'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) 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; @@ -4073,634 +4108,634 @@ class ProxyApiTestClass extends ProxyApiSuperClass } Future callFlutterEchoBool(bool aBool) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoBool'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aBool]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, aBool]) 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 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 bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } Future callFlutterEchoInt(int anInt) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoInt'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, anInt]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, anInt]) 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 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 int?)!; + return (pigeonVar_replyList[0] as int?)!; } } Future callFlutterEchoDouble(double aDouble) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoDouble'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aDouble]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, aDouble]) 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 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 double?)!; + return (pigeonVar_replyList[0] as double?)!; } } Future callFlutterEchoString(String aString) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoString'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aString]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, aString]) 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 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 String?)!; + return (pigeonVar_replyList[0] as String?)!; } } Future callFlutterEchoUint8List(Uint8List aUint8List) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoUint8List'; - final BasicMessageChannel __pigeon_channel = + 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([this, aUint8List]) 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 Uint8List?)!; + return (pigeonVar_replyList[0] as Uint8List?)!; } } Future> callFlutterEchoList(List aList) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoList'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aList]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, aList]) 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 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(); } } Future> callFlutterEchoProxyApiList( List aList) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoProxyApiList'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aList]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, aList]) 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 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?)! + return (pigeonVar_replyList[0] as List?)! .cast(); } } Future> callFlutterEchoMap( Map aMap) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoMap'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aMap]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, aMap]) 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 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?)! + return (pigeonVar_replyList[0] as Map?)! .cast(); } } Future> callFlutterEchoProxyApiMap( Map aMap) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoProxyApiMap'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aMap]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, aMap]) 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 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?)! + return (pigeonVar_replyList[0] as Map?)! .cast(); } } Future callFlutterEchoEnum(ProxyApiTestEnum anEnum) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoEnum'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, anEnum]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, anEnum]) 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 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 ProxyApiTestEnum?)!; + return (pigeonVar_replyList[0] as ProxyApiTestEnum?)!; } } Future callFlutterEchoProxyApi( ProxyApiSuperClass aProxyApi) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoProxyApi'; - final BasicMessageChannel __pigeon_channel = + 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([this, aProxyApi]) 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 ProxyApiSuperClass?)!; + return (pigeonVar_replyList[0] as ProxyApiSuperClass?)!; } } Future callFlutterEchoNullableBool(bool? aBool) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableBool'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aBool]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, aBool]) 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?); } } Future callFlutterEchoNullableInt(int? anInt) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableInt'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, anInt]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, anInt]) 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?); } } Future callFlutterEchoNullableDouble(double? aDouble) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableDouble'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aDouble]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, aDouble]) 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?); } } Future callFlutterEchoNullableString(String? aString) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableString'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aString]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, aString]) 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?); } } Future callFlutterEchoNullableUint8List( Uint8List? aUint8List) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableUint8List'; - final BasicMessageChannel __pigeon_channel = + 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([this, aUint8List]) 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 (__pigeon_replyList[0] as Uint8List?); + return (pigeonVar_replyList[0] as Uint8List?); } } Future?> callFlutterEchoNullableList( List? aList) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableList'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aList]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, aList]) 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(); } } Future?> callFlutterEchoNullableMap( Map? aMap) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableMap'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aMap]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, aMap]) 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 Map?) + return (pigeonVar_replyList[0] as Map?) ?.cast(); } } Future callFlutterEchoNullableEnum( ProxyApiTestEnum? anEnum) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableEnum'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, anEnum]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this, anEnum]) 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 ProxyApiTestEnum?); + return (pigeonVar_replyList[0] as ProxyApiTestEnum?); } } Future callFlutterEchoNullableProxyApi( ProxyApiSuperClass? aProxyApi) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableProxyApi'; - final BasicMessageChannel __pigeon_channel = + 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([this, aProxyApi]) 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 (__pigeon_replyList[0] as ProxyApiSuperClass?); + return (pigeonVar_replyList[0] as ProxyApiSuperClass?); } } Future callFlutterNoopAsync() async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterNoopAsync'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) 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; @@ -4708,34 +4743,34 @@ class ProxyApiTestClass extends ProxyApiSuperClass } Future callFlutterEchoAsyncString(String aString) async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiTestClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiTestClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoAsyncString'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this, aString]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, aString]) 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 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 String?)!; + return (pigeonVar_replyList[0] as String?)!; } } @@ -4793,34 +4828,34 @@ class ProxyApiTestClass extends ProxyApiSuperClass } /// ProxyApi to serve as a super class to the core ProxyApi class. -class ProxyApiSuperClass extends PigeonProxyApiBaseClass { +class ProxyApiSuperClass extends PigeonInternalProxyApiBaseClass { ProxyApiSuperClass({ super.pigeon_binaryMessenger, super.pigeon_instanceManager, }) { - final int __pigeon_instanceIdentifier = + final int pigeonVar_instanceIdentifier = pigeon_instanceManager.addDartCreatedInstance(this); - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiSuperClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiSuperClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; () async { - const String __pigeon_channelName = + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiSuperClass.pigeon_defaultConstructor'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = await __pigeon_channel - .send([__pigeon_instanceIdentifier]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([pigeonVar_instanceIdentifier]) 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; @@ -4838,8 +4873,9 @@ class ProxyApiSuperClass extends PigeonProxyApiBaseClass { super.pigeon_instanceManager, }); - late final _PigeonProxyApiBaseCodec __pigeon_codecProxyApiSuperClass = - _PigeonProxyApiBaseCodec(pigeon_instanceManager); + late final _PigeonInternalProxyApiBaseCodec + _pigeonVar_codecProxyApiSuperClass = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); static void pigeon_setUpMessageHandlers({ bool pigeon_clearHandlers = false, @@ -4847,20 +4883,21 @@ class ProxyApiSuperClass extends PigeonProxyApiBaseClass { PigeonInstanceManager? pigeon_instanceManager, ProxyApiSuperClass Function()? pigeon_newInstance, }) { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - _PigeonProxyApiBaseCodec( + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( pigeon_instanceManager ?? PigeonInstanceManager.instance); final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiSuperClass.pigeon_newInstance', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiSuperClass.pigeon_newInstance was null.'); final List args = (message as List?)!; @@ -4890,26 +4927,26 @@ class ProxyApiSuperClass extends PigeonProxyApiBaseClass { } Future aSuperMethod() async { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - __pigeon_codecProxyApiSuperClass; - final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; - const String __pigeon_channelName = + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecProxyApiSuperClass; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiSuperClass.aSuperMethod'; - final BasicMessageChannel __pigeon_channel = + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([this]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) 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; @@ -4926,7 +4963,7 @@ class ProxyApiSuperClass extends PigeonProxyApiBaseClass { } /// ProxyApi to serve as an interface to the core ProxyApi class. -class ProxyApiInterface extends PigeonProxyApiBaseClass { +class ProxyApiInterface extends PigeonInternalProxyApiBaseClass { /// Constructs [ProxyApiInterface] without creating the associated native object. /// /// This should only be used by subclasses created by this library or to @@ -4966,20 +5003,21 @@ class ProxyApiInterface extends PigeonProxyApiBaseClass { ProxyApiInterface Function()? pigeon_newInstance, void Function(ProxyApiInterface pigeon_instance)? anInterfaceMethod, }) { - final _PigeonProxyApiBaseCodec pigeonChannelCodec = - _PigeonProxyApiBaseCodec( + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( pigeon_instanceManager ?? PigeonInstanceManager.instance); final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiInterface.pigeon_newInstance', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiInterface.pigeon_newInstance was null.'); final List args = (message as List?)!; @@ -5008,15 +5046,16 @@ class ProxyApiInterface extends PigeonProxyApiBaseClass { } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiInterface.anInterfaceMethod', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (pigeon_clearHandlers) { - __pigeon_channel.setMessageHandler(null); + pigeonVar_channel.setMessageHandler(null); } else { - __pigeon_channel.setMessageHandler((Object? message) async { + pigeonVar_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiInterface.anInterfaceMethod was null.'); final List args = (message as List?)!; @@ -5048,3 +5087,137 @@ class ProxyApiInterface extends PigeonProxyApiBaseClass { ); } } + +class ClassWithApiRequirement extends PigeonInternalProxyApiBaseClass { + ClassWithApiRequirement({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }) { + final int pigeonVar_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(this); + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecClassWithApiRequirement; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + () async { + const String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ClassWithApiRequirement.pigeon_defaultConstructor'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([pigeonVar_instanceIdentifier]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + }(); + } + + /// Constructs [ClassWithApiRequirement] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + ClassWithApiRequirement.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }); + + late final _PigeonInternalProxyApiBaseCodec + _pigeonVar_codecClassWithApiRequirement = + _PigeonInternalProxyApiBaseCodec(pigeon_instanceManager); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + ClassWithApiRequirement Function()? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ClassWithApiRequirement.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ClassWithApiRequirement.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ClassWithApiRequirement.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + ClassWithApiRequirement.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + Future aMethod() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecClassWithApiRequirement; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ClassWithApiRequirement.aMethod'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + @override + ClassWithApiRequirement pigeon_copy() { + return ClassWithApiRequirement.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/test_types.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/test_types.dart new file mode 100644 index 000000000000..40d35dc67940 --- /dev/null +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/test_types.dart @@ -0,0 +1,692 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// ignore_for_file: public_member_api_docs + +import 'package:flutter/foundation.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'generated.dart'; + +const int biggerThanBigInt = 3000000000; +const int regularInt = 42; +const double doublePi = 3.14159; + +void compareComplexLists(List? listOne, List? listTwo) { + expect(listOne == null, listTwo == null); + if (listOne == null || listTwo == null) { + return; + } + expect(listOne.length, listTwo.length); + for (int i = 0; i < listOne.length; i++) { + if (listOne[i] is List) { + compareComplexLists( + listOne[i] as List, listTwo[i] as List); + } else if (listOne[i] is Map) { + compareComplexMaps(listOne[i] as Map, + listTwo[i] as Map); + } else if (listOne[i] is AllTypes) { + compareAllTypes(listOne[i] as AllTypes, listTwo[i] as AllTypes); + } else if (listOne[i] is AllNullableTypes) { + compareAllNullableTypes( + listOne[i] as AllNullableTypes, listTwo[i] as AllNullableTypes); + } else if (listOne[i] is AllNullableTypesWithoutRecursion) { + compareAllNullableTypesWithoutRecursion( + listOne[i] as AllNullableTypesWithoutRecursion, + listTwo[i] as AllNullableTypesWithoutRecursion); + } else if (listOne[i] is AllClassesWrapper) { + compareAllClassesWrapper( + listOne[i] as AllClassesWrapper, listTwo[i] as AllClassesWrapper); + } else { + expect(listOne[i], listTwo[i]); + } + } +} + +void compareComplexMaps( + Map? mapOne, Map? mapTwo) { + expect(mapOne == null, mapTwo == null); + if (mapOne == null || mapTwo == null) { + return; + } + expect(mapOne.length, mapTwo.length); + for (final dynamic key in mapOne.keys) { + if (mapOne[key] is List) { + compareComplexLists( + mapOne[key] as List, mapTwo[key] as List); + } else if (mapOne[key] is Map) { + compareComplexMaps(mapOne[key] as Map, + mapTwo[key] as Map); + } else if (mapOne[key] is AllTypes) { + compareAllTypes(mapOne[key] as AllTypes, mapTwo[key] as AllTypes); + } else if (mapOne[key] is AllNullableTypes) { + compareAllNullableTypes( + mapOne[key] as AllNullableTypes, mapTwo[key] as AllNullableTypes); + } else if (mapOne[key] is AllNullableTypesWithoutRecursion) { + compareAllNullableTypesWithoutRecursion( + mapOne[key] as AllNullableTypesWithoutRecursion, + mapTwo[key] as AllNullableTypesWithoutRecursion); + } else if (mapOne[key] is AllClassesWrapper) { + compareAllClassesWrapper( + mapOne[key] as AllClassesWrapper, mapTwo[key] as AllClassesWrapper); + } else { + expect(mapOne[key], mapTwo[key]); + } + } +} + +void compareAllNullableTypesWithoutRecursion( + AllNullableTypesWithoutRecursion? allNullableTypesOne, + AllNullableTypesWithoutRecursion? allNullableTypesTwo) { + expect(allNullableTypesOne == null, allNullableTypesTwo == null); + if (allNullableTypesOne == null || allNullableTypesTwo == null) { + return; + } + expect(allNullableTypesOne.aNullableBool, allNullableTypesTwo.aNullableBool); + expect(allNullableTypesOne.aNullableInt, allNullableTypesTwo.aNullableInt); + expect( + allNullableTypesOne.aNullableInt64, allNullableTypesTwo.aNullableInt64); + expect( + allNullableTypesOne.aNullableDouble, allNullableTypesTwo.aNullableDouble); + expect( + allNullableTypesOne.aNullableString, allNullableTypesTwo.aNullableString); + expect(allNullableTypesOne.aNullableByteArray, + allNullableTypesTwo.aNullableByteArray); + expect(allNullableTypesOne.aNullable4ByteArray, + allNullableTypesTwo.aNullable4ByteArray); + expect(allNullableTypesOne.aNullable8ByteArray, + allNullableTypesTwo.aNullable8ByteArray); + expect(allNullableTypesOne.aNullableFloatArray, + allNullableTypesTwo.aNullableFloatArray); + expect( + allNullableTypesOne.aNullableObject, allNullableTypesTwo.aNullableObject); + expect(allNullableTypesOne.aNullableEnum, allNullableTypesTwo.aNullableEnum); + compareComplexLists(allNullableTypesOne.list, allNullableTypesTwo.list); + compareComplexLists( + allNullableTypesOne.stringList, allNullableTypesTwo.stringList); + compareComplexLists( + allNullableTypesOne.boolList, allNullableTypesTwo.boolList); + compareComplexLists( + allNullableTypesOne.doubleList, allNullableTypesTwo.doubleList); + compareComplexLists(allNullableTypesOne.intList, allNullableTypesTwo.intList); + compareComplexLists( + allNullableTypesOne.enumList, allNullableTypesTwo.enumList); + compareComplexLists( + allNullableTypesOne.objectList, allNullableTypesTwo.objectList); + compareComplexLists( + allNullableTypesOne.listList, allNullableTypesTwo.listList); + compareComplexLists(allNullableTypesOne.mapList, allNullableTypesTwo.mapList); + compareComplexMaps(allNullableTypesOne.map, allNullableTypesTwo.map); + compareComplexMaps( + allNullableTypesOne.stringMap, allNullableTypesTwo.stringMap); + compareComplexMaps(allNullableTypesOne.intMap, allNullableTypesTwo.intMap); + compareComplexMaps(allNullableTypesOne.enumMap, allNullableTypesTwo.enumMap); + compareComplexMaps( + allNullableTypesOne.objectMap, allNullableTypesTwo.objectMap); + compareComplexMaps(allNullableTypesOne.listMap, allNullableTypesTwo.listMap); + compareComplexMaps(allNullableTypesOne.mapMap, allNullableTypesTwo.mapMap); +} + +void compareAllTypes(AllTypes? allTypesOne, AllTypes? allTypesTwo) { + expect(allTypesOne == null, allTypesTwo == null); + if (allTypesOne == null || allTypesTwo == null) { + return; + } + expect(allTypesOne.aBool, allTypesTwo.aBool); + expect(allTypesOne.anInt, allTypesTwo.anInt); + expect(allTypesOne.anInt64, allTypesTwo.anInt64); + expect(allTypesOne.aDouble, allTypesTwo.aDouble); + expect(allTypesOne.aString, allTypesTwo.aString); + expect(allTypesOne.aByteArray, allTypesTwo.aByteArray); + expect(allTypesOne.a4ByteArray, allTypesTwo.a4ByteArray); + expect(allTypesOne.a8ByteArray, allTypesTwo.a8ByteArray); + expect(allTypesOne.aFloatArray, allTypesTwo.aFloatArray); + expect(allTypesOne.anEnum, allTypesTwo.anEnum); + expect(allTypesOne.anObject, allTypesTwo.anObject); + compareComplexLists(allTypesOne.list, allTypesTwo.list); + compareComplexLists(allTypesOne.stringList, allTypesTwo.stringList); + compareComplexLists(allTypesOne.boolList, allTypesTwo.boolList); + compareComplexLists(allTypesOne.doubleList, allTypesTwo.doubleList); + compareComplexLists(allTypesOne.intList, allTypesTwo.intList); + compareComplexLists(allTypesOne.enumList, allTypesTwo.enumList); + compareComplexLists(allTypesOne.objectList, allTypesTwo.objectList); + compareComplexLists(allTypesOne.listList, allTypesTwo.listList); + compareComplexLists(allTypesOne.mapList, allTypesTwo.mapList); + compareComplexMaps(allTypesOne.map, allTypesTwo.map); + compareComplexMaps(allTypesOne.stringMap, allTypesTwo.stringMap); + compareComplexMaps(allTypesOne.intMap, allTypesTwo.intMap); + compareComplexMaps(allTypesOne.enumMap, allTypesTwo.enumMap); + compareComplexMaps(allTypesOne.objectMap, allTypesTwo.objectMap); + compareComplexMaps(allTypesOne.listMap, allTypesTwo.listMap); + compareComplexMaps(allTypesOne.mapMap, allTypesTwo.mapMap); +} + +void compareAllNullableTypes(AllNullableTypes? allNullableTypesOne, + AllNullableTypes? allNullableTypesTwo) { + expect(allNullableTypesOne == null, allNullableTypesTwo == null); + if (allNullableTypesOne == null || allNullableTypesTwo == null) { + return; + } + expect(allNullableTypesOne.aNullableBool, allNullableTypesTwo.aNullableBool); + expect(allNullableTypesOne.aNullableInt, allNullableTypesTwo.aNullableInt); + expect( + allNullableTypesOne.aNullableInt64, allNullableTypesTwo.aNullableInt64); + expect( + allNullableTypesOne.aNullableDouble, allNullableTypesTwo.aNullableDouble); + expect( + allNullableTypesOne.aNullableString, allNullableTypesTwo.aNullableString); + expect(allNullableTypesOne.aNullableByteArray, + allNullableTypesTwo.aNullableByteArray); + expect(allNullableTypesOne.aNullable4ByteArray, + allNullableTypesTwo.aNullable4ByteArray); + expect(allNullableTypesOne.aNullable8ByteArray, + allNullableTypesTwo.aNullable8ByteArray); + expect(allNullableTypesOne.aNullableFloatArray, + allNullableTypesTwo.aNullableFloatArray); + expect( + allNullableTypesOne.aNullableObject, allNullableTypesTwo.aNullableObject); + expect(allNullableTypesOne.aNullableEnum, allNullableTypesTwo.aNullableEnum); + compareAllNullableTypes(allNullableTypesOne.allNullableTypes, + allNullableTypesTwo.allNullableTypes); + compareComplexLists(allNullableTypesOne.list, allNullableTypesTwo.list); + compareComplexLists( + allNullableTypesOne.stringList, allNullableTypesTwo.stringList); + compareComplexLists( + allNullableTypesOne.boolList, allNullableTypesTwo.boolList); + compareComplexLists( + allNullableTypesOne.doubleList, allNullableTypesTwo.doubleList); + compareComplexLists(allNullableTypesOne.intList, allNullableTypesTwo.intList); + compareComplexLists( + allNullableTypesOne.enumList, allNullableTypesTwo.enumList); + compareComplexLists( + allNullableTypesOne.objectList, allNullableTypesTwo.objectList); + compareComplexLists( + allNullableTypesOne.listList, allNullableTypesTwo.listList); + compareComplexLists(allNullableTypesOne.recursiveClassList, + allNullableTypesTwo.recursiveClassList); + compareComplexLists(allNullableTypesOne.mapList, allNullableTypesTwo.mapList); + compareComplexMaps(allNullableTypesOne.map, allNullableTypesTwo.map); + compareComplexMaps( + allNullableTypesOne.stringMap, allNullableTypesTwo.stringMap); + compareComplexMaps(allNullableTypesOne.intMap, allNullableTypesTwo.intMap); + compareComplexMaps(allNullableTypesOne.enumMap, allNullableTypesTwo.enumMap); + compareComplexMaps( + allNullableTypesOne.objectMap, allNullableTypesTwo.objectMap); + compareComplexMaps(allNullableTypesOne.listMap, allNullableTypesTwo.listMap); + compareComplexMaps(allNullableTypesOne.mapMap, allNullableTypesTwo.mapMap); + compareComplexMaps(allNullableTypesOne.recursiveClassMap, + allNullableTypesTwo.recursiveClassMap); +} + +void compareAllClassesWrapper( + AllClassesWrapper? wrapperOne, AllClassesWrapper? wrapperTwo) { + expect(wrapperOne == null, wrapperTwo == null); + if (wrapperOne == null || wrapperTwo == null) { + return; + } + + compareAllNullableTypes( + wrapperOne.allNullableTypes, wrapperTwo.allNullableTypes); + compareAllNullableTypesWithoutRecursion( + wrapperOne.allNullableTypesWithoutRecursion, + wrapperTwo.allNullableTypesWithoutRecursion, + ); + compareAllTypes(wrapperOne.allTypes, wrapperTwo.allTypes); + + for (int i = 0; i < (wrapperOne.classList.length); i++) { + compareAllTypes(wrapperOne.classList[i], wrapperTwo.classList[i]); + } + + for (int i = 0; i < (wrapperOne.nullableClassList?.length ?? 0); i++) { + compareAllNullableTypesWithoutRecursion( + wrapperOne.nullableClassList![i], wrapperTwo.nullableClassList![i]); + } + compareComplexMaps(wrapperOne.classMap, wrapperTwo.classMap); + compareComplexMaps(wrapperOne.nullableClassMap, wrapperTwo.nullableClassMap); +} + +final List nonNullList = [ + 'Thing 1', + 2, + true, + 3.14, +]; + +final List nonNullStringList = [ + 'Thing 1', + '2', + 'true', + '3.14', +]; + +final List nonNullIntList = [ + 1, + 2, + 3, + 4, +]; + +final List nonNullDoubleList = [ + 1, + 2.99999, + 3, + 3.14, +]; + +final List nonNullBoolList = [ + true, + false, + true, + false, +]; + +final List nonNullEnumList = [ + AnEnum.one, + AnEnum.two, + AnEnum.three, + AnEnum.fortyTwo, + AnEnum.fourHundredTwentyTwo, +]; + +final List> nonNullListList = >[ + nonNullList, + nonNullStringList, + nonNullIntList, + nonNullDoubleList, + nonNullBoolList, + nonNullEnumList, +]; + +final Map nonNullMap = { + 'a': 1, + 'b': 2.0, + 'c': 'three', + 'd': false, +}; + +final Map nonNullStringMap = { + 'a': '1', + 'b': '2.0', + 'c': 'three', + 'd': 'false', +}; + +final Map nonNullIntMap = { + 0: 0, + 1: 1, + 2: 3, + 4: -1, +}; + +final Map nonNullDoubleMap = { + 0.0: 0, + 1.1: 2.0, + 3: 0.3, + -.4: -0.2, +}; + +final Map nonNullBoolMap = { + 0: true, + 1: false, + 2: true, +}; + +final Map nonNullEnumMap = { + AnEnum.one: AnEnum.one, + AnEnum.two: AnEnum.two, + AnEnum.three: AnEnum.three, + AnEnum.fortyTwo: AnEnum.fortyTwo, +}; + +final Map> nonNullListMap = >{ + 0: nonNullList, + 1: nonNullStringList, + 2: nonNullDoubleList, + 4: nonNullIntList, + 5: nonNullBoolList, + 6: nonNullEnumList, +}; + +final Map> nonNullMapMap = >{ + 0: nonNullMap, + 1: nonNullStringMap, + 2: nonNullDoubleMap, + 4: nonNullIntMap, + 5: nonNullBoolMap, + 6: nonNullEnumMap, +}; + +final List> nonNullMapList = >[ + nonNullMap, + nonNullStringMap, + nonNullDoubleMap, + nonNullIntMap, + nonNullBoolMap, + nonNullEnumMap, +]; + +final List list = [ + 'Thing 1', + 2, + true, + 3.14, + null, +]; + +final List stringList = [ + 'Thing 1', + '2', + 'true', + '3.14', + null, +]; + +final List intList = [ + 1, + 2, + 3, + 4, + null, +]; + +final List doubleList = [ + 1, + 2.99999, + 3, + 3.14, + null, +]; + +final List boolList = [ + true, + false, + true, + false, + null, +]; + +final List enumList = [ + AnEnum.one, + AnEnum.two, + AnEnum.three, + AnEnum.fortyTwo, + AnEnum.fourHundredTwentyTwo, + null +]; + +final List?> listList = ?>[ + list, + stringList, + intList, + doubleList, + boolList, + enumList, + null +]; + +final Map map = { + 'a': 1, + 'b': 2.0, + 'c': 'three', + 'd': false, + 'e': null +}; + +final Map stringMap = { + 'a': '1', + 'b': '2.0', + 'c': 'three', + 'd': 'false', + 'e': 'null', + 'f': null +}; + +final Map intMap = { + 0: 0, + 1: 1, + 2: 3, + 4: -1, + 5: null, +}; + +final Map doubleMap = { + 0.0: 0, + 1.1: 2.0, + 3: 0.3, + -.4: -0.2, + 1111111111111111.11111111111111111111111111111111111111111111: null +}; + +final Map boolMap = { + 0: true, + 1: false, + 2: true, + 3: null, +}; + +final Map enumMap = { + AnEnum.one: AnEnum.one, + AnEnum.two: AnEnum.two, + AnEnum.three: AnEnum.three, + AnEnum.fortyTwo: AnEnum.fortyTwo, + AnEnum.fourHundredTwentyTwo: null, +}; + +final Map?> listMap = ?>{ + 0: list, + 1: stringList, + 2: doubleList, + 4: intList, + 5: boolList, + 6: enumList, + 7: null +}; + +final Map?> mapMap = ?>{ + 0: map, + 1: stringMap, + 2: doubleMap, + 4: intMap, + 5: boolMap, + 6: enumMap, + 7: null +}; + +final List?> mapList = ?>[ + map, + stringMap, + doubleMap, + intMap, + boolMap, + enumMap, + null +]; + +final AllNullableTypesWithoutRecursion genericAllNullableTypesWithoutRecursion = + AllNullableTypesWithoutRecursion( + aNullableBool: true, + aNullableInt: regularInt, + aNullableInt64: biggerThanBigInt, + aNullableDouble: doublePi, + aNullableString: 'Hello host!', + aNullableByteArray: Uint8List.fromList([1, 2, 3]), + aNullable4ByteArray: Int32List.fromList([4, 5, 6]), + aNullable8ByteArray: Int64List.fromList([7, 8, 9]), + aNullableFloatArray: Float64List.fromList([2.71828, doublePi]), + aNullableEnum: AnEnum.fourHundredTwentyTwo, + aNullableObject: 0, + list: list, + stringList: stringList, + intList: intList, + doubleList: doubleList, + boolList: boolList, + enumList: enumList, + objectList: list, + listList: listList, + mapList: mapList, + map: map, + stringMap: stringMap, + intMap: intMap, + enumMap: enumMap, + objectMap: map, + listMap: listMap, + mapMap: mapMap, +); + +final List + allNullableTypesWithoutRecursionClassList = + [ + genericAllNullableTypesWithoutRecursion, + AllNullableTypesWithoutRecursion(), + null, +]; + +final Map + allNullableTypesWithoutRecursionClassMap = + { + 0: genericAllNullableTypesWithoutRecursion, + 1: AllNullableTypesWithoutRecursion(), + 2: null, +}; + +final AllTypes genericAllTypes = AllTypes( + aBool: true, + anInt: regularInt, + anInt64: biggerThanBigInt, + aDouble: doublePi, + aString: 'Hello host!', + aByteArray: Uint8List.fromList([1, 2, 3]), + a4ByteArray: Int32List.fromList([4, 5, 6]), + a8ByteArray: Int64List.fromList([7, 8, 9]), + aFloatArray: Float64List.fromList([2.71828, doublePi]), + anEnum: AnEnum.fortyTwo, + anObject: 1, + list: list, + stringList: nonNullStringList, + intList: nonNullIntList, + doubleList: nonNullDoubleList, + boolList: nonNullBoolList, + enumList: nonNullEnumList, + objectList: nonNullList, + listList: nonNullListList, + mapList: nonNullMapList, + map: nonNullMap, + stringMap: nonNullStringMap, + intMap: nonNullIntMap, + // doubleMap: nonNullDoubleMap, + // boolMap: nonNullBoolMap, + enumMap: nonNullEnumMap, + objectMap: nonNullMap, + listMap: nonNullListMap, + mapMap: nonNullMapMap, +); + +final List allTypesClassList = [ + genericAllTypes, + null, +]; + +final Map allTypesClassMap = { + 0: genericAllTypes, + 1: null, +}; + +final AllNullableTypes genericAllNullableTypes = AllNullableTypes( + aNullableBool: true, + aNullableInt: regularInt, + aNullableInt64: biggerThanBigInt, + aNullableDouble: doublePi, + aNullableString: 'Hello host!', + aNullableByteArray: Uint8List.fromList([1, 2, 3]), + aNullable4ByteArray: Int32List.fromList([4, 5, 6]), + aNullable8ByteArray: Int64List.fromList([7, 8, 9]), + aNullableFloatArray: Float64List.fromList([2.71828, doublePi]), + aNullableEnum: AnEnum.fourHundredTwentyTwo, + aNullableObject: 0, + list: list, + stringList: stringList, + intList: intList, + doubleList: doubleList, + boolList: boolList, + enumList: enumList, + objectList: list, + listList: listList, + mapList: mapList, + map: map, + stringMap: stringMap, + intMap: intMap, + enumMap: enumMap, + objectMap: map, + listMap: listMap, + mapMap: mapMap, +); + +final List nonNullAllNullableTypesList = [ + genericAllNullableTypes, + AllNullableTypes(), +]; + +final Map nonNullAllNullableTypesMap = + { + 0: genericAllNullableTypes, + 1: AllNullableTypes(), +}; + +final List allNullableTypesList = [ + genericAllNullableTypes, + AllNullableTypes(), + null, +]; + +final Map allNullableTypesMap = + { + 0: genericAllNullableTypes, + 1: AllNullableTypes(), + 2: null, +}; + +final AllNullableTypes recursiveAllNullableTypes = AllNullableTypes( + aNullableBool: true, + aNullableInt: regularInt, + aNullableInt64: biggerThanBigInt, + aNullableDouble: doublePi, + aNullableString: 'Hello host!', + aNullableByteArray: Uint8List.fromList([1, 2, 3]), + aNullable4ByteArray: Int32List.fromList([4, 5, 6]), + aNullable8ByteArray: Int64List.fromList([7, 8, 9]), + aNullableFloatArray: Float64List.fromList([2.71828, doublePi]), + aNullableEnum: AnEnum.fourHundredTwentyTwo, + aNullableObject: 0, + allNullableTypes: genericAllNullableTypes, + list: list, + stringList: stringList, + intList: intList, + doubleList: doubleList, + boolList: boolList, + enumList: enumList, + objectList: list, + listList: listList, + mapList: mapList, + recursiveClassList: allNullableTypesList, + map: map, + stringMap: stringMap, + intMap: intMap, + enumMap: enumMap, + objectMap: map, + listMap: listMap, + mapMap: mapMap, + recursiveClassMap: allNullableTypesMap, +); + +AllClassesWrapper classWrapperMaker() { + return AllClassesWrapper( + allNullableTypes: recursiveAllNullableTypes, + allNullableTypesWithoutRecursion: genericAllNullableTypesWithoutRecursion, + allTypes: genericAllTypes, + classList: allTypesClassList, + classMap: allTypesClassMap, + nullableClassList: allNullableTypesWithoutRecursionClassList, + nullableClassMap: allNullableTypesWithoutRecursionClassMap, + ); +} 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 9392c3a13cd6..f0ab70f80712 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: build_runner: ^2.1.10 @@ -18,4 +18,4 @@ dependencies: sdk: flutter integration_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart index aadce1b81d7b..f28cb077dea0 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart @@ -156,7 +156,7 @@ void main() { }); } -class CopyableObject extends PigeonProxyApiBaseClass { +class CopyableObject extends PigeonInternalProxyApiBaseClass { // ignore: non_constant_identifier_names CopyableObject({super.pigeon_instanceManager}); diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/test/test_message.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/test/test_message.gen.dart index 27add3253372..62f677202322 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/test/test_message.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/test/test_message.gen.dart @@ -18,18 +18,21 @@ class _PigeonCodec extends StandardMessageCodec { const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is MessageSearchRequest) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is MessageRequestState) { buffer.putUint8(129); - writeValue(buffer, value.encode()); - } else if (value is MessageSearchReply) { + writeValue(buffer, value.index); + } else if (value is MessageSearchRequest) { buffer.putUint8(130); writeValue(buffer, value.encode()); - } else if (value is MessageNested) { + } else if (value is MessageSearchReply) { buffer.putUint8(131); writeValue(buffer, value.encode()); - } else if (value is MessageRequestState) { + } else if (value is MessageNested) { buffer.putUint8(132); - writeValue(buffer, value.index); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -39,14 +42,14 @@ class _PigeonCodec extends StandardMessageCodec { Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { case 129: - return MessageSearchRequest.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : MessageRequestState.values[value]; case 130: - return MessageSearchReply.decode(readValue(buffer)!); + return MessageSearchRequest.decode(readValue(buffer)!); case 131: - return MessageNested.decode(readValue(buffer)!); + return MessageSearchReply.decode(readValue(buffer)!); case 132: - final int? value = readValue(buffer) as int?; - return value == null ? null : MessageRequestState.values[value]; + return MessageNested.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -77,17 +80,18 @@ abstract class TestHostApi { messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.MessageApi.initialize$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { try { api.initialize(); @@ -102,17 +106,18 @@ abstract class TestHostApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.MessageApi.search$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.MessageApi.search was null.'); @@ -155,17 +160,18 @@ abstract class TestNestedApi { messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.pigeon_integration_tests.MessageNestedApi.search$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.MessageNestedApi.search was null.'); diff --git a/packages/pigeon/platform_tests/test_plugin/android/build.gradle b/packages/pigeon/platform_tests/test_plugin/android/build.gradle index e99686da09c8..2ed864258e26 100644 --- a/packages/pigeon/platform_tests/test_plugin/android/build.gradle +++ b/packages/pigeon/platform_tests/test_plugin/android/build.gradle @@ -2,7 +2,7 @@ group 'com.example.test_plugin' version '1.0-SNAPSHOT' buildscript { - ext.kotlin_version = '2.0.0' + ext.kotlin_version = '2.0.20' repositories { google() mavenCentral() @@ -25,19 +25,16 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' android { - // Conditional for compatibility with AGP <4.2. - if (project.android.hasProperty("namespace")) { - namespace 'com.example.test_plugin' - } + namespace 'com.example.test_plugin' compileSdk 34 compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '11' allWarningsAsErrors = true } @@ -64,11 +61,14 @@ android { lintOptions { checkAllWarnings true warningsAsErrors true - disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency' + disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency', 'NewerVersionAvailable' } dependencies { testImplementation 'junit:junit:4.+' - testImplementation "io.mockk:mockk:1.13.7" + testImplementation "io.mockk:mockk:1.13.12" + // org.jetbrains.kotlin:kotlin-bom artifact purpose is to align kotlin stdlib and related code versions. + // See: https://youtrack.jetbrains.com/issue/KT-55297/kotlin-stdlib-should-declare-constraints-on-kotlin-stdlib-jdk8-and-kotlin-stdlib-jdk7 + implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.10")) } } diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/.gitignore b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/.gitignore index a870aa16cae1..5f3fcaf31604 100644 --- a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/.gitignore +++ b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/.gitignore @@ -3,4 +3,9 @@ # such as a flag to suppress version stamp generation. *.kt !TestPlugin.kt -!CoreTests.gen.kt \ No newline at end of file +!CoreTests.gen.kt +# This contains the declaration of the test classes wrapped by the ProxyApi tests and the +# implemetations of their APIs. +!ProxyApiTestApiImpls.kt +# Including this makes it easier to review code generation changes. +!ProxyApiTests.gen.kt diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt index f90b51196112..c5ba2d8b0ca0 100644 --- a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt +++ b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt @@ -50,6 +50,32 @@ enum class AnEnum(val raw: Int) { } } +enum class AnotherEnum(val raw: Int) { + JUST_IN_CASE(0); + + companion object { + fun ofRaw(raw: Int): AnotherEnum? { + return values().firstOrNull { it.raw == raw } + } + } +} + +/** Generated class from Pigeon that represents data sent in messages. */ +data class UnusedClass(val aField: Any? = null) { + companion object { + fun fromList(pigeonVar_list: List): UnusedClass { + val aField = pigeonVar_list[0] + return UnusedClass(aField) + } + } + + fun toList(): List { + return listOf( + aField, + ) + } +} + /** * A class containing all supported types. * @@ -65,35 +91,56 @@ data class AllTypes( val a8ByteArray: LongArray, val aFloatArray: DoubleArray, val anEnum: AnEnum, + val anotherEnum: AnotherEnum, val aString: String, val anObject: Any, val list: List, - val stringList: List, - val intList: List, - val doubleList: List, - val boolList: List, - val map: Map + val stringList: List, + val intList: List, + val doubleList: List, + val boolList: List, + val enumList: List, + val objectList: List, + val listList: List>, + val mapList: List>, + val map: Map, + val stringMap: Map, + val intMap: Map, + val enumMap: Map, + val objectMap: Map, + val listMap: Map>, + val mapMap: Map> ) { companion object { - @Suppress("LocalVariableName") - fun fromList(__pigeon_list: List): AllTypes { - val aBool = __pigeon_list[0] as Boolean - val anInt = __pigeon_list[1].let { num -> if (num is Int) num.toLong() else num as Long } - val anInt64 = __pigeon_list[2].let { num -> if (num is Int) num.toLong() else num as Long } - val aDouble = __pigeon_list[3] as Double - val aByteArray = __pigeon_list[4] as ByteArray - val a4ByteArray = __pigeon_list[5] as IntArray - val a8ByteArray = __pigeon_list[6] as LongArray - val aFloatArray = __pigeon_list[7] as DoubleArray - val anEnum = __pigeon_list[8] as AnEnum - val aString = __pigeon_list[9] as String - val anObject = __pigeon_list[10] as Any - val list = __pigeon_list[11] as List - val stringList = __pigeon_list[12] as List - val intList = __pigeon_list[13] as List - val doubleList = __pigeon_list[14] as List - val boolList = __pigeon_list[15] as List - val map = __pigeon_list[16] as Map + fun fromList(pigeonVar_list: List): AllTypes { + val aBool = pigeonVar_list[0] as Boolean + val anInt = pigeonVar_list[1] as Long + val anInt64 = pigeonVar_list[2] as Long + val aDouble = pigeonVar_list[3] as Double + val aByteArray = pigeonVar_list[4] as ByteArray + val a4ByteArray = pigeonVar_list[5] as IntArray + val a8ByteArray = pigeonVar_list[6] as LongArray + val aFloatArray = pigeonVar_list[7] as DoubleArray + val anEnum = pigeonVar_list[8] as AnEnum + val anotherEnum = pigeonVar_list[9] as AnotherEnum + val aString = pigeonVar_list[10] as String + val anObject = pigeonVar_list[11] as Any + val list = pigeonVar_list[12] as List + val stringList = pigeonVar_list[13] as List + val intList = pigeonVar_list[14] as List + val doubleList = pigeonVar_list[15] as List + val boolList = pigeonVar_list[16] as List + val enumList = pigeonVar_list[17] as List + val objectList = pigeonVar_list[18] as List + val listList = pigeonVar_list[19] as List> + val mapList = pigeonVar_list[20] as List> + val map = pigeonVar_list[21] as Map + val stringMap = pigeonVar_list[22] as Map + val intMap = pigeonVar_list[23] as Map + val enumMap = pigeonVar_list[24] as Map + val objectMap = pigeonVar_list[25] as Map + val listMap = pigeonVar_list[26] as Map> + val mapMap = pigeonVar_list[27] as Map> return AllTypes( aBool, anInt, @@ -104,6 +151,7 @@ data class AllTypes( a8ByteArray, aFloatArray, anEnum, + anotherEnum, aString, anObject, list, @@ -111,7 +159,17 @@ data class AllTypes( intList, doubleList, boolList, - map) + enumList, + objectList, + listList, + mapList, + map, + stringMap, + intMap, + enumMap, + objectMap, + listMap, + mapMap) } } @@ -126,6 +184,7 @@ data class AllTypes( a8ByteArray, aFloatArray, anEnum, + anotherEnum, aString, anObject, list, @@ -133,7 +192,17 @@ data class AllTypes( intList, doubleList, boolList, + enumList, + objectList, + listList, + mapList, map, + stringMap, + intMap, + enumMap, + objectMap, + listMap, + mapMap, ) } } @@ -152,10 +221,8 @@ data class AllNullableTypes( val aNullable4ByteArray: IntArray? = null, val aNullable8ByteArray: LongArray? = null, val aNullableFloatArray: DoubleArray? = null, - val nullableNestedList: List?>? = null, - val nullableMapWithAnnotations: Map? = null, - val nullableMapWithObject: Map? = null, val aNullableEnum: AnEnum? = null, + val anotherNullableEnum: AnotherEnum? = null, val aNullableString: String? = null, val aNullableObject: Any? = null, val allNullableTypes: AllNullableTypes? = null, @@ -164,36 +231,53 @@ data class AllNullableTypes( val intList: List? = null, val doubleList: List? = null, val boolList: List? = null, - val nestedClassList: List? = null, - val map: Map? = null + val enumList: List? = null, + val objectList: List? = null, + val listList: List?>? = null, + val mapList: List?>? = null, + val recursiveClassList: List? = null, + val map: Map? = null, + val stringMap: Map? = null, + val intMap: Map? = null, + val enumMap: Map? = null, + val objectMap: Map? = null, + val listMap: Map?>? = null, + val mapMap: Map?>? = null, + val recursiveClassMap: Map? = null ) { companion object { - @Suppress("LocalVariableName") - fun fromList(__pigeon_list: List): AllNullableTypes { - val aNullableBool = __pigeon_list[0] as Boolean? - val aNullableInt = - __pigeon_list[1].let { num -> if (num is Int) num.toLong() else num as Long? } - val aNullableInt64 = - __pigeon_list[2].let { num -> if (num is Int) num.toLong() else num as Long? } - val aNullableDouble = __pigeon_list[3] as Double? - val aNullableByteArray = __pigeon_list[4] as ByteArray? - val aNullable4ByteArray = __pigeon_list[5] as IntArray? - val aNullable8ByteArray = __pigeon_list[6] as LongArray? - val aNullableFloatArray = __pigeon_list[7] as DoubleArray? - val nullableNestedList = __pigeon_list[8] as List?>? - val nullableMapWithAnnotations = __pigeon_list[9] as Map? - val nullableMapWithObject = __pigeon_list[10] as Map? - val aNullableEnum = __pigeon_list[11] as AnEnum? - val aNullableString = __pigeon_list[12] as String? - val aNullableObject = __pigeon_list[13] - val allNullableTypes = __pigeon_list[14] as AllNullableTypes? - val list = __pigeon_list[15] as List? - val stringList = __pigeon_list[16] as List? - val intList = __pigeon_list[17] as List? - val doubleList = __pigeon_list[18] as List? - val boolList = __pigeon_list[19] as List? - val nestedClassList = __pigeon_list[20] as List? - val map = __pigeon_list[21] as Map? + fun fromList(pigeonVar_list: List): AllNullableTypes { + val aNullableBool = pigeonVar_list[0] as Boolean? + val aNullableInt = pigeonVar_list[1] as Long? + val aNullableInt64 = pigeonVar_list[2] as Long? + val aNullableDouble = pigeonVar_list[3] as Double? + val aNullableByteArray = pigeonVar_list[4] as ByteArray? + val aNullable4ByteArray = pigeonVar_list[5] as IntArray? + val aNullable8ByteArray = pigeonVar_list[6] as LongArray? + val aNullableFloatArray = pigeonVar_list[7] as DoubleArray? + val aNullableEnum = pigeonVar_list[8] as AnEnum? + val anotherNullableEnum = pigeonVar_list[9] as AnotherEnum? + val aNullableString = pigeonVar_list[10] as String? + val aNullableObject = pigeonVar_list[11] + val allNullableTypes = pigeonVar_list[12] as AllNullableTypes? + val list = pigeonVar_list[13] as List? + val stringList = pigeonVar_list[14] as List? + val intList = pigeonVar_list[15] as List? + val doubleList = pigeonVar_list[16] as List? + val boolList = pigeonVar_list[17] as List? + val enumList = pigeonVar_list[18] as List? + val objectList = pigeonVar_list[19] as List? + val listList = pigeonVar_list[20] as List?>? + val mapList = pigeonVar_list[21] as List?>? + val recursiveClassList = pigeonVar_list[22] as List? + val map = pigeonVar_list[23] as Map? + val stringMap = pigeonVar_list[24] as Map? + val intMap = pigeonVar_list[25] as Map? + val enumMap = pigeonVar_list[26] as Map? + val objectMap = pigeonVar_list[27] as Map? + val listMap = pigeonVar_list[28] as Map?>? + val mapMap = pigeonVar_list[29] as Map?>? + val recursiveClassMap = pigeonVar_list[30] as Map? return AllNullableTypes( aNullableBool, aNullableInt, @@ -203,10 +287,8 @@ data class AllNullableTypes( aNullable4ByteArray, aNullable8ByteArray, aNullableFloatArray, - nullableNestedList, - nullableMapWithAnnotations, - nullableMapWithObject, aNullableEnum, + anotherNullableEnum, aNullableString, aNullableObject, allNullableTypes, @@ -215,8 +297,19 @@ data class AllNullableTypes( intList, doubleList, boolList, - nestedClassList, - map) + enumList, + objectList, + listList, + mapList, + recursiveClassList, + map, + stringMap, + intMap, + enumMap, + objectMap, + listMap, + mapMap, + recursiveClassMap) } } @@ -230,10 +323,8 @@ data class AllNullableTypes( aNullable4ByteArray, aNullable8ByteArray, aNullableFloatArray, - nullableNestedList, - nullableMapWithAnnotations, - nullableMapWithObject, aNullableEnum, + anotherNullableEnum, aNullableString, aNullableObject, allNullableTypes, @@ -242,8 +333,19 @@ data class AllNullableTypes( intList, doubleList, boolList, - nestedClassList, + enumList, + objectList, + listList, + mapList, + recursiveClassList, map, + stringMap, + intMap, + enumMap, + objectMap, + listMap, + mapMap, + recursiveClassMap, ) } } @@ -263,10 +365,8 @@ data class AllNullableTypesWithoutRecursion( val aNullable4ByteArray: IntArray? = null, val aNullable8ByteArray: LongArray? = null, val aNullableFloatArray: DoubleArray? = null, - val nullableNestedList: List?>? = null, - val nullableMapWithAnnotations: Map? = null, - val nullableMapWithObject: Map? = null, val aNullableEnum: AnEnum? = null, + val anotherNullableEnum: AnotherEnum? = null, val aNullableString: String? = null, val aNullableObject: Any? = null, val list: List? = null, @@ -274,33 +374,48 @@ data class AllNullableTypesWithoutRecursion( val intList: List? = null, val doubleList: List? = null, val boolList: List? = null, - val map: Map? = null + val enumList: List? = null, + val objectList: List? = null, + val listList: List?>? = null, + val mapList: List?>? = null, + val map: Map? = null, + val stringMap: Map? = null, + val intMap: Map? = null, + val enumMap: Map? = null, + val objectMap: Map? = null, + val listMap: Map?>? = null, + val mapMap: Map?>? = null ) { companion object { - @Suppress("LocalVariableName") - fun fromList(__pigeon_list: List): AllNullableTypesWithoutRecursion { - val aNullableBool = __pigeon_list[0] as Boolean? - val aNullableInt = - __pigeon_list[1].let { num -> if (num is Int) num.toLong() else num as Long? } - val aNullableInt64 = - __pigeon_list[2].let { num -> if (num is Int) num.toLong() else num as Long? } - val aNullableDouble = __pigeon_list[3] as Double? - val aNullableByteArray = __pigeon_list[4] as ByteArray? - val aNullable4ByteArray = __pigeon_list[5] as IntArray? - val aNullable8ByteArray = __pigeon_list[6] as LongArray? - val aNullableFloatArray = __pigeon_list[7] as DoubleArray? - val nullableNestedList = __pigeon_list[8] as List?>? - val nullableMapWithAnnotations = __pigeon_list[9] as Map? - val nullableMapWithObject = __pigeon_list[10] as Map? - val aNullableEnum = __pigeon_list[11] as AnEnum? - val aNullableString = __pigeon_list[12] as String? - val aNullableObject = __pigeon_list[13] - val list = __pigeon_list[14] as List? - val stringList = __pigeon_list[15] as List? - val intList = __pigeon_list[16] as List? - val doubleList = __pigeon_list[17] as List? - val boolList = __pigeon_list[18] as List? - val map = __pigeon_list[19] as Map? + fun fromList(pigeonVar_list: List): AllNullableTypesWithoutRecursion { + val aNullableBool = pigeonVar_list[0] as Boolean? + val aNullableInt = pigeonVar_list[1] as Long? + val aNullableInt64 = pigeonVar_list[2] as Long? + val aNullableDouble = pigeonVar_list[3] as Double? + val aNullableByteArray = pigeonVar_list[4] as ByteArray? + val aNullable4ByteArray = pigeonVar_list[5] as IntArray? + val aNullable8ByteArray = pigeonVar_list[6] as LongArray? + val aNullableFloatArray = pigeonVar_list[7] as DoubleArray? + val aNullableEnum = pigeonVar_list[8] as AnEnum? + val anotherNullableEnum = pigeonVar_list[9] as AnotherEnum? + val aNullableString = pigeonVar_list[10] as String? + val aNullableObject = pigeonVar_list[11] + val list = pigeonVar_list[12] as List? + val stringList = pigeonVar_list[13] as List? + val intList = pigeonVar_list[14] as List? + val doubleList = pigeonVar_list[15] as List? + val boolList = pigeonVar_list[16] as List? + val enumList = pigeonVar_list[17] as List? + val objectList = pigeonVar_list[18] as List? + val listList = pigeonVar_list[19] as List?>? + val mapList = pigeonVar_list[20] as List?>? + val map = pigeonVar_list[21] as Map? + val stringMap = pigeonVar_list[22] as Map? + val intMap = pigeonVar_list[23] as Map? + val enumMap = pigeonVar_list[24] as Map? + val objectMap = pigeonVar_list[25] as Map? + val listMap = pigeonVar_list[26] as Map?>? + val mapMap = pigeonVar_list[27] as Map?>? return AllNullableTypesWithoutRecursion( aNullableBool, aNullableInt, @@ -310,10 +425,8 @@ data class AllNullableTypesWithoutRecursion( aNullable4ByteArray, aNullable8ByteArray, aNullableFloatArray, - nullableNestedList, - nullableMapWithAnnotations, - nullableMapWithObject, aNullableEnum, + anotherNullableEnum, aNullableString, aNullableObject, list, @@ -321,7 +434,17 @@ data class AllNullableTypesWithoutRecursion( intList, doubleList, boolList, - map) + enumList, + objectList, + listList, + mapList, + map, + stringMap, + intMap, + enumMap, + objectMap, + listMap, + mapMap) } } @@ -335,10 +458,8 @@ data class AllNullableTypesWithoutRecursion( aNullable4ByteArray, aNullable8ByteArray, aNullableFloatArray, - nullableNestedList, - nullableMapWithAnnotations, - nullableMapWithObject, aNullableEnum, + anotherNullableEnum, aNullableString, aNullableObject, list, @@ -346,7 +467,17 @@ data class AllNullableTypesWithoutRecursion( intList, doubleList, boolList, + enumList, + objectList, + listList, + mapList, map, + stringMap, + intMap, + enumMap, + objectMap, + listMap, + mapMap, ) } } @@ -363,15 +494,29 @@ data class AllNullableTypesWithoutRecursion( data class AllClassesWrapper( val allNullableTypes: AllNullableTypes, val allNullableTypesWithoutRecursion: AllNullableTypesWithoutRecursion? = null, - val allTypes: AllTypes? = null + val allTypes: AllTypes? = null, + val classList: List, + val nullableClassList: List? = null, + val classMap: Map, + val nullableClassMap: Map? = null ) { companion object { - @Suppress("LocalVariableName") - fun fromList(__pigeon_list: List): AllClassesWrapper { - val allNullableTypes = __pigeon_list[0] as AllNullableTypes - val allNullableTypesWithoutRecursion = __pigeon_list[1] as AllNullableTypesWithoutRecursion? - val allTypes = __pigeon_list[2] as AllTypes? - return AllClassesWrapper(allNullableTypes, allNullableTypesWithoutRecursion, allTypes) + fun fromList(pigeonVar_list: List): AllClassesWrapper { + val allNullableTypes = pigeonVar_list[0] as AllNullableTypes + val allNullableTypesWithoutRecursion = pigeonVar_list[1] as AllNullableTypesWithoutRecursion? + val allTypes = pigeonVar_list[2] as AllTypes? + val classList = pigeonVar_list[3] as List + val nullableClassList = pigeonVar_list[4] as List? + val classMap = pigeonVar_list[5] as Map + val nullableClassMap = pigeonVar_list[6] as Map? + return AllClassesWrapper( + allNullableTypes, + allNullableTypesWithoutRecursion, + allTypes, + classList, + nullableClassList, + classMap, + nullableClassMap) } } @@ -380,6 +525,10 @@ data class AllClassesWrapper( allNullableTypes, allNullableTypesWithoutRecursion, allTypes, + classList, + nullableClassList, + classMap, + nullableClassMap, ) } } @@ -390,11 +539,9 @@ data class AllClassesWrapper( * Generated class from Pigeon that represents data sent in messages. */ data class TestMessage(val testList: List? = null) { - companion object { - @Suppress("LocalVariableName") - fun fromList(__pigeon_list: List): TestMessage { - val testList = __pigeon_list[0] as List? + fun fromList(pigeonVar_list: List): TestMessage { + val testList = pigeonVar_list[0] as List? return TestMessage(testList) } } @@ -406,58 +553,72 @@ data class TestMessage(val testList: List? = null) { } } -private object CoreTestsPigeonCodec : StandardMessageCodec() { +private open class CoreTestsPigeonCodec : StandardMessageCodec() { override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? { return when (type) { 129.toByte() -> { - return (readValue(buffer) as? List)?.let { AllTypes.fromList(it) } + return (readValue(buffer) as Long?)?.let { AnEnum.ofRaw(it.toInt()) } } 130.toByte() -> { - return (readValue(buffer) as? List)?.let { AllNullableTypes.fromList(it) } + return (readValue(buffer) as Long?)?.let { AnotherEnum.ofRaw(it.toInt()) } } 131.toByte() -> { + return (readValue(buffer) as? List)?.let { UnusedClass.fromList(it) } + } + 132.toByte() -> { + return (readValue(buffer) as? List)?.let { AllTypes.fromList(it) } + } + 133.toByte() -> { + return (readValue(buffer) as? List)?.let { AllNullableTypes.fromList(it) } + } + 134.toByte() -> { return (readValue(buffer) as? List)?.let { AllNullableTypesWithoutRecursion.fromList(it) } } - 132.toByte() -> { + 135.toByte() -> { return (readValue(buffer) as? List)?.let { AllClassesWrapper.fromList(it) } } - 133.toByte() -> { + 136.toByte() -> { return (readValue(buffer) as? List)?.let { TestMessage.fromList(it) } } - 134.toByte() -> { - return (readValue(buffer) as Int?)?.let { AnEnum.ofRaw(it) } - } else -> super.readValueOfType(type, buffer) } } override fun writeValue(stream: ByteArrayOutputStream, value: Any?) { when (value) { - is AllTypes -> { + is AnEnum -> { stream.write(129) - writeValue(stream, value.toList()) + writeValue(stream, value.raw) } - is AllNullableTypes -> { + is AnotherEnum -> { stream.write(130) - writeValue(stream, value.toList()) + writeValue(stream, value.raw) } - is AllNullableTypesWithoutRecursion -> { + is UnusedClass -> { stream.write(131) writeValue(stream, value.toList()) } - is AllClassesWrapper -> { + is AllTypes -> { stream.write(132) writeValue(stream, value.toList()) } - is TestMessage -> { + is AllNullableTypes -> { stream.write(133) writeValue(stream, value.toList()) } - is AnEnum -> { + is AllNullableTypesWithoutRecursion -> { stream.write(134) - writeValue(stream, value.raw) + writeValue(stream, value.toList()) + } + is AllClassesWrapper -> { + stream.write(135) + writeValue(stream, value.toList()) + } + is TestMessage -> { + stream.write(136) + writeValue(stream, value.toList()) } else -> super.writeValue(stream, value) } @@ -495,12 +656,38 @@ interface HostIntegrationCoreApi { fun echoObject(anObject: Any): Any /** Returns the passed list, to test serialization and deserialization. */ fun echoList(list: List): List + /** Returns the passed list, to test serialization and deserialization. */ + fun echoEnumList(enumList: List): List + /** Returns the passed list, to test serialization and deserialization. */ + fun echoClassList(classList: List): List + /** Returns the passed list, to test serialization and deserialization. */ + fun echoNonNullEnumList(enumList: List): List + /** Returns the passed list, to test serialization and deserialization. */ + fun echoNonNullClassList(classList: List): List + /** Returns the passed map, to test serialization and deserialization. */ + fun echoMap(map: Map): Map + /** Returns the passed map, to test serialization and deserialization. */ + fun echoStringMap(stringMap: Map): Map + /** Returns the passed map, to test serialization and deserialization. */ + fun echoIntMap(intMap: Map): Map + /** Returns the passed map, to test serialization and deserialization. */ + fun echoEnumMap(enumMap: Map): Map + /** Returns the passed map, to test serialization and deserialization. */ + fun echoClassMap(classMap: Map): Map /** Returns the passed map, to test serialization and deserialization. */ - fun echoMap(aMap: Map): Map - /** Returns the passed map to test nested class serialization and deserialization. */ + fun echoNonNullStringMap(stringMap: Map): Map + /** Returns the passed map, to test serialization and deserialization. */ + fun echoNonNullIntMap(intMap: Map): Map + /** Returns the passed map, to test serialization and deserialization. */ + fun echoNonNullEnumMap(enumMap: Map): Map + /** Returns the passed map, to test serialization and deserialization. */ + fun echoNonNullClassMap(classMap: Map): Map + /** Returns the passed class to test nested class serialization and deserialization. */ fun echoClassWrapper(wrapper: AllClassesWrapper): AllClassesWrapper /** Returns the passed enum to test serialization and deserialization. */ fun echoEnum(anEnum: AnEnum): AnEnum + /** Returns the passed enum to test serialization and deserialization. */ + fun echoAnotherEnum(anotherEnum: AnotherEnum): AnotherEnum /** Returns the default string. */ fun echoNamedDefaultString(aString: String): String /** Returns passed in double. */ @@ -547,10 +734,38 @@ interface HostIntegrationCoreApi { fun echoNullableObject(aNullableObject: Any?): Any? /** Returns the passed list, to test serialization and deserialization. */ fun echoNullableList(aNullableList: List?): List? + /** Returns the passed list, to test serialization and deserialization. */ + fun echoNullableEnumList(enumList: List?): List? + /** Returns the passed list, to test serialization and deserialization. */ + fun echoNullableClassList(classList: List?): List? + /** Returns the passed list, to test serialization and deserialization. */ + fun echoNullableNonNullEnumList(enumList: List?): List? + /** Returns the passed list, to test serialization and deserialization. */ + fun echoNullableNonNullClassList(classList: List?): List? + /** Returns the passed map, to test serialization and deserialization. */ + fun echoNullableMap(map: Map?): Map? + /** Returns the passed map, to test serialization and deserialization. */ + fun echoNullableStringMap(stringMap: Map?): Map? + /** Returns the passed map, to test serialization and deserialization. */ + fun echoNullableIntMap(intMap: Map?): Map? + /** Returns the passed map, to test serialization and deserialization. */ + fun echoNullableEnumMap(enumMap: Map?): Map? + /** Returns the passed map, to test serialization and deserialization. */ + fun echoNullableClassMap(classMap: Map?): Map? + /** Returns the passed map, to test serialization and deserialization. */ + fun echoNullableNonNullStringMap(stringMap: Map?): Map? + /** Returns the passed map, to test serialization and deserialization. */ + fun echoNullableNonNullIntMap(intMap: Map?): Map? + /** Returns the passed map, to test serialization and deserialization. */ + fun echoNullableNonNullEnumMap(enumMap: Map?): Map? /** Returns the passed map, to test serialization and deserialization. */ - fun echoNullableMap(aNullableMap: Map?): Map? + fun echoNullableNonNullClassMap( + classMap: Map? + ): Map? fun echoNullableEnum(anEnum: AnEnum?): AnEnum? + + fun echoAnotherNullableEnum(anotherEnum: AnotherEnum?): AnotherEnum? /** Returns passed in int. */ fun echoOptionalNullableInt(aNullableInt: Long?): Long? /** Returns the passed in string. */ @@ -574,10 +789,36 @@ interface HostIntegrationCoreApi { fun echoAsyncObject(anObject: Any, callback: (Result) -> Unit) /** Returns the passed list, to test asynchronous serialization and deserialization. */ fun echoAsyncList(list: List, callback: (Result>) -> Unit) + /** Returns the passed list, to test asynchronous serialization and deserialization. */ + fun echoAsyncEnumList(enumList: List, callback: (Result>) -> Unit) + /** Returns the passed list, to test asynchronous serialization and deserialization. */ + fun echoAsyncClassList( + classList: List, + callback: (Result>) -> Unit + ) + /** Returns the passed map, to test asynchronous serialization and deserialization. */ + fun echoAsyncMap(map: Map, callback: (Result>) -> Unit) + /** Returns the passed map, to test asynchronous serialization and deserialization. */ + fun echoAsyncStringMap( + stringMap: Map, + callback: (Result>) -> Unit + ) + /** Returns the passed map, to test asynchronous serialization and deserialization. */ + fun echoAsyncIntMap(intMap: Map, callback: (Result>) -> Unit) /** Returns the passed map, to test asynchronous serialization and deserialization. */ - fun echoAsyncMap(aMap: Map, callback: (Result>) -> Unit) + fun echoAsyncEnumMap( + enumMap: Map, + callback: (Result>) -> Unit + ) + /** Returns the passed map, to test asynchronous serialization and deserialization. */ + fun echoAsyncClassMap( + classMap: Map, + callback: (Result>) -> Unit + ) /** Returns the passed enum, to test asynchronous serialization and deserialization. */ fun echoAsyncEnum(anEnum: AnEnum, callback: (Result) -> Unit) + /** Returns the passed enum, to test asynchronous serialization and deserialization. */ + fun echoAnotherAsyncEnum(anotherEnum: AnotherEnum, callback: (Result) -> Unit) /** Responds with an error from an async function returning a value. */ fun throwAsyncError(callback: (Result) -> Unit) /** Responds with an error from an async void function. */ @@ -610,13 +851,45 @@ interface HostIntegrationCoreApi { fun echoAsyncNullableObject(anObject: Any?, callback: (Result) -> Unit) /** Returns the passed list, to test asynchronous serialization and deserialization. */ fun echoAsyncNullableList(list: List?, callback: (Result?>) -> Unit) + /** Returns the passed list, to test asynchronous serialization and deserialization. */ + fun echoAsyncNullableEnumList( + enumList: List?, + callback: (Result?>) -> Unit + ) + /** Returns the passed list, to test asynchronous serialization and deserialization. */ + fun echoAsyncNullableClassList( + classList: List?, + callback: (Result?>) -> Unit + ) /** Returns the passed map, to test asynchronous serialization and deserialization. */ - fun echoAsyncNullableMap( - aMap: Map?, - callback: (Result?>) -> Unit + fun echoAsyncNullableMap(map: Map?, callback: (Result?>) -> Unit) + /** Returns the passed map, to test asynchronous serialization and deserialization. */ + fun echoAsyncNullableStringMap( + stringMap: Map?, + callback: (Result?>) -> Unit + ) + /** Returns the passed map, to test asynchronous serialization and deserialization. */ + fun echoAsyncNullableIntMap( + intMap: Map?, + callback: (Result?>) -> Unit + ) + /** Returns the passed map, to test asynchronous serialization and deserialization. */ + fun echoAsyncNullableEnumMap( + enumMap: Map?, + callback: (Result?>) -> Unit + ) + /** Returns the passed map, to test asynchronous serialization and deserialization. */ + fun echoAsyncNullableClassMap( + classMap: Map?, + callback: (Result?>) -> Unit ) /** Returns the passed enum, to test asynchronous serialization and deserialization. */ fun echoAsyncNullableEnum(anEnum: AnEnum?, callback: (Result) -> Unit) + /** Returns the passed enum, to test asynchronous serialization and deserialization. */ + fun echoAnotherAsyncNullableEnum( + anotherEnum: AnotherEnum?, + callback: (Result) -> Unit + ) fun callFlutterNoop(callback: (Result) -> Unit) @@ -662,10 +935,69 @@ interface HostIntegrationCoreApi { fun callFlutterEchoList(list: List, callback: (Result>) -> Unit) - fun callFlutterEchoMap(aMap: Map, callback: (Result>) -> Unit) + fun callFlutterEchoEnumList(enumList: List, callback: (Result>) -> Unit) + + fun callFlutterEchoClassList( + classList: List, + callback: (Result>) -> Unit + ) + + fun callFlutterEchoNonNullEnumList( + enumList: List, + callback: (Result>) -> Unit + ) + + fun callFlutterEchoNonNullClassList( + classList: List, + callback: (Result>) -> Unit + ) + + fun callFlutterEchoMap(map: Map, callback: (Result>) -> Unit) + + fun callFlutterEchoStringMap( + stringMap: Map, + callback: (Result>) -> Unit + ) + + fun callFlutterEchoIntMap( + intMap: Map, + callback: (Result>) -> Unit + ) + + fun callFlutterEchoEnumMap( + enumMap: Map, + callback: (Result>) -> Unit + ) + + fun callFlutterEchoClassMap( + classMap: Map, + callback: (Result>) -> Unit + ) + + fun callFlutterEchoNonNullStringMap( + stringMap: Map, + callback: (Result>) -> Unit + ) + + fun callFlutterEchoNonNullIntMap( + intMap: Map, + callback: (Result>) -> Unit + ) + + fun callFlutterEchoNonNullEnumMap( + enumMap: Map, + callback: (Result>) -> Unit + ) + + fun callFlutterEchoNonNullClassMap( + classMap: Map, + callback: (Result>) -> Unit + ) fun callFlutterEchoEnum(anEnum: AnEnum, callback: (Result) -> Unit) + fun callFlutterEchoAnotherEnum(anotherEnum: AnotherEnum, callback: (Result) -> Unit) + fun callFlutterEchoNullableBool(aBool: Boolean?, callback: (Result) -> Unit) fun callFlutterEchoNullableInt(anInt: Long?, callback: (Result) -> Unit) @@ -678,18 +1010,83 @@ interface HostIntegrationCoreApi { fun callFlutterEchoNullableList(list: List?, callback: (Result?>) -> Unit) + fun callFlutterEchoNullableEnumList( + enumList: List?, + callback: (Result?>) -> Unit + ) + + fun callFlutterEchoNullableClassList( + classList: List?, + callback: (Result?>) -> Unit + ) + + fun callFlutterEchoNullableNonNullEnumList( + enumList: List?, + callback: (Result?>) -> Unit + ) + + fun callFlutterEchoNullableNonNullClassList( + classList: List?, + callback: (Result?>) -> Unit + ) + fun callFlutterEchoNullableMap( - aMap: Map?, - callback: (Result?>) -> Unit + map: Map?, + callback: (Result?>) -> Unit + ) + + fun callFlutterEchoNullableStringMap( + stringMap: Map?, + callback: (Result?>) -> Unit + ) + + fun callFlutterEchoNullableIntMap( + intMap: Map?, + callback: (Result?>) -> Unit + ) + + fun callFlutterEchoNullableEnumMap( + enumMap: Map?, + callback: (Result?>) -> Unit + ) + + fun callFlutterEchoNullableClassMap( + classMap: Map?, + callback: (Result?>) -> Unit + ) + + fun callFlutterEchoNullableNonNullStringMap( + stringMap: Map?, + callback: (Result?>) -> Unit + ) + + fun callFlutterEchoNullableNonNullIntMap( + intMap: Map?, + callback: (Result?>) -> Unit + ) + + fun callFlutterEchoNullableNonNullEnumMap( + enumMap: Map?, + callback: (Result?>) -> Unit + ) + + fun callFlutterEchoNullableNonNullClassMap( + classMap: Map?, + callback: (Result?>) -> Unit ) fun callFlutterEchoNullableEnum(anEnum: AnEnum?, callback: (Result) -> Unit) + fun callFlutterEchoAnotherNullableEnum( + anotherEnum: AnotherEnum?, + callback: (Result) -> Unit + ) + fun callFlutterSmallApiEchoString(aString: String, callback: (Result) -> Unit) companion object { /** The codec used by HostIntegrationCoreApi. */ - val codec: MessageCodec by lazy { CoreTestsPigeonCodec } + val codec: MessageCodec by lazy { CoreTestsPigeonCodec() } /** * Sets up an instance of `HostIntegrationCoreApi` to handle messages through the * `binaryMessenger`. @@ -815,7 +1212,7 @@ interface HostIntegrationCoreApi { if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val anIntArg = args[0].let { num -> if (num is Int) num.toLong() else num as Long } + val anIntArg = args[0] as Long val wrapped: List = try { listOf(api.echoInt(anIntArg)) @@ -964,15 +1361,15 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoMap$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoEnumList$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aMapArg = args[0] as Map + val enumListArg = args[0] as List val wrapped: List = try { - listOf(api.echoMap(aMapArg)) + listOf(api.echoEnumList(enumListArg)) } catch (exception: Throwable) { wrapError(exception) } @@ -986,15 +1383,15 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoClassWrapper$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoClassList$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val wrapperArg = args[0] as AllClassesWrapper + val classListArg = args[0] as List val wrapped: List = try { - listOf(api.echoClassWrapper(wrapperArg)) + listOf(api.echoClassList(classListArg)) } catch (exception: Throwable) { wrapError(exception) } @@ -1008,15 +1405,15 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoEnum$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullEnumList$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val anEnumArg = args[0] as AnEnum + val enumListArg = args[0] as List val wrapped: List = try { - listOf(api.echoEnum(anEnumArg)) + listOf(api.echoNonNullEnumList(enumListArg)) } catch (exception: Throwable) { wrapError(exception) } @@ -1030,15 +1427,15 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNamedDefaultString$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullClassList$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aStringArg = args[0] as String + val classListArg = args[0] as List val wrapped: List = try { - listOf(api.echoNamedDefaultString(aStringArg)) + listOf(api.echoNonNullClassList(classListArg)) } catch (exception: Throwable) { wrapError(exception) } @@ -1052,15 +1449,15 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoOptionalDefaultDouble$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoMap$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aDoubleArg = args[0] as Double + val mapArg = args[0] as Map val wrapped: List = try { - listOf(api.echoOptionalDefaultDouble(aDoubleArg)) + listOf(api.echoMap(mapArg)) } catch (exception: Throwable) { wrapError(exception) } @@ -1074,15 +1471,15 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoRequiredInt$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoStringMap$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val anIntArg = args[0].let { num -> if (num is Int) num.toLong() else num as Long } + val stringMapArg = args[0] as Map val wrapped: List = try { - listOf(api.echoRequiredInt(anIntArg)) + listOf(api.echoStringMap(stringMapArg)) } catch (exception: Throwable) { wrapError(exception) } @@ -1096,15 +1493,15 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypes$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoIntMap$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val everythingArg = args[0] as AllNullableTypes? + val intMapArg = args[0] as Map val wrapped: List = try { - listOf(api.echoAllNullableTypes(everythingArg)) + listOf(api.echoIntMap(intMapArg)) } catch (exception: Throwable) { wrapError(exception) } @@ -1118,15 +1515,15 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypesWithoutRecursion$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoEnumMap$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val everythingArg = args[0] as AllNullableTypesWithoutRecursion? + val enumMapArg = args[0] as Map val wrapped: List = try { - listOf(api.echoAllNullableTypesWithoutRecursion(everythingArg)) + listOf(api.echoEnumMap(enumMapArg)) } catch (exception: Throwable) { wrapError(exception) } @@ -1140,15 +1537,15 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.extractNestedNullableString$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoClassMap$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val wrapperArg = args[0] as AllClassesWrapper + val classMapArg = args[0] as Map val wrapped: List = try { - listOf(api.extractNestedNullableString(wrapperArg)) + listOf(api.echoClassMap(classMapArg)) } catch (exception: Throwable) { wrapError(exception) } @@ -1162,15 +1559,15 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.createNestedNullableString$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullStringMap$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val nullableStringArg = args[0] as String? + val stringMapArg = args[0] as Map val wrapped: List = try { - listOf(api.createNestedNullableString(nullableStringArg)) + listOf(api.echoNonNullStringMap(stringMapArg)) } catch (exception: Throwable) { wrapError(exception) } @@ -1184,20 +1581,15 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypes$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullIntMap$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aNullableBoolArg = args[0] as Boolean? - val aNullableIntArg = - args[1].let { num -> if (num is Int) num.toLong() else num as Long? } - val aNullableStringArg = args[2] as String? + val intMapArg = args[0] as Map val wrapped: List = try { - listOf( - api.sendMultipleNullableTypes( - aNullableBoolArg, aNullableIntArg, aNullableStringArg)) + listOf(api.echoNonNullIntMap(intMapArg)) } catch (exception: Throwable) { wrapError(exception) } @@ -1211,20 +1603,15 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullEnumMap$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aNullableBoolArg = args[0] as Boolean? - val aNullableIntArg = - args[1].let { num -> if (num is Int) num.toLong() else num as Long? } - val aNullableStringArg = args[2] as String? + val enumMapArg = args[0] as Map val wrapped: List = try { - listOf( - api.sendMultipleNullableTypesWithoutRecursion( - aNullableBoolArg, aNullableIntArg, aNullableStringArg)) + listOf(api.echoNonNullEnumMap(enumMapArg)) } catch (exception: Throwable) { wrapError(exception) } @@ -1238,16 +1625,15 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableInt$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullClassMap$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aNullableIntArg = - args[0].let { num -> if (num is Int) num.toLong() else num as Long? } + val classMapArg = args[0] as Map val wrapped: List = try { - listOf(api.echoNullableInt(aNullableIntArg)) + listOf(api.echoNonNullClassMap(classMapArg)) } catch (exception: Throwable) { wrapError(exception) } @@ -1261,15 +1647,15 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableDouble$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoClassWrapper$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aNullableDoubleArg = args[0] as Double? + val wrapperArg = args[0] as AllClassesWrapper val wrapped: List = try { - listOf(api.echoNullableDouble(aNullableDoubleArg)) + listOf(api.echoClassWrapper(wrapperArg)) } catch (exception: Throwable) { wrapError(exception) } @@ -1283,15 +1669,15 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableBool$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoEnum$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aNullableBoolArg = args[0] as Boolean? + val anEnumArg = args[0] as AnEnum val wrapped: List = try { - listOf(api.echoNullableBool(aNullableBoolArg)) + listOf(api.echoEnum(anEnumArg)) } catch (exception: Throwable) { wrapError(exception) } @@ -1305,15 +1691,15 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableString$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAnotherEnum$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aNullableStringArg = args[0] as String? + val anotherEnumArg = args[0] as AnotherEnum val wrapped: List = try { - listOf(api.echoNullableString(aNullableStringArg)) + listOf(api.echoAnotherEnum(anotherEnumArg)) } catch (exception: Throwable) { wrapError(exception) } @@ -1327,15 +1713,15 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableUint8List$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNamedDefaultString$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aNullableUint8ListArg = args[0] as ByteArray? + val aStringArg = args[0] as String val wrapped: List = try { - listOf(api.echoNullableUint8List(aNullableUint8ListArg)) + listOf(api.echoNamedDefaultString(aStringArg)) } catch (exception: Throwable) { wrapError(exception) } @@ -1349,15 +1735,15 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableObject$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoOptionalDefaultDouble$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aNullableObjectArg = args[0] + val aDoubleArg = args[0] as Double val wrapped: List = try { - listOf(api.echoNullableObject(aNullableObjectArg)) + listOf(api.echoOptionalDefaultDouble(aDoubleArg)) } catch (exception: Throwable) { wrapError(exception) } @@ -1371,15 +1757,15 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableList$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoRequiredInt$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aNullableListArg = args[0] as List? + val anIntArg = args[0] as Long val wrapped: List = try { - listOf(api.echoNullableList(aNullableListArg)) + listOf(api.echoRequiredInt(anIntArg)) } catch (exception: Throwable) { wrapError(exception) } @@ -1393,15 +1779,15 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableMap$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypes$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aNullableMapArg = args[0] as Map? + val everythingArg = args[0] as AllNullableTypes? val wrapped: List = try { - listOf(api.echoNullableMap(aNullableMapArg)) + listOf(api.echoAllNullableTypes(everythingArg)) } catch (exception: Throwable) { wrapError(exception) } @@ -1415,15 +1801,15 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableEnum$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypesWithoutRecursion$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val anEnumArg = args[0] as AnEnum? + val everythingArg = args[0] as AllNullableTypesWithoutRecursion? val wrapped: List = try { - listOf(api.echoNullableEnum(anEnumArg)) + listOf(api.echoAllNullableTypesWithoutRecursion(everythingArg)) } catch (exception: Throwable) { wrapError(exception) } @@ -1437,16 +1823,15 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoOptionalNullableInt$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.extractNestedNullableString$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aNullableIntArg = - args[0].let { num -> if (num is Int) num.toLong() else num as Long? } + val wrapperArg = args[0] as AllClassesWrapper val wrapped: List = try { - listOf(api.echoOptionalNullableInt(aNullableIntArg)) + listOf(api.extractNestedNullableString(wrapperArg)) } catch (exception: Throwable) { wrapError(exception) } @@ -1460,15 +1845,15 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNamedNullableString$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.createNestedNullableString$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aNullableStringArg = args[0] as String? + val nullableStringArg = args[0] as String? val wrapped: List = try { - listOf(api.echoNamedNullableString(aNullableStringArg)) + listOf(api.createNestedNullableString(nullableStringArg)) } catch (exception: Throwable) { wrapError(exception) } @@ -1482,18 +1867,23 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.noopAsync$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypes$separatedMessageChannelSuffix", codec) if (api != null) { - channel.setMessageHandler { _, reply -> - api.noopAsync { result: Result -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - reply.reply(wrapResult(null)) - } - } + channel.setMessageHandler { message, reply -> + val args = message as List + val aNullableBoolArg = args[0] as Boolean? + val aNullableIntArg = args[1] as Long? + val aNullableStringArg = args[2] as String? + val wrapped: List = + try { + listOf( + api.sendMultipleNullableTypes( + aNullableBoolArg, aNullableIntArg, aNullableStringArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -1503,21 +1893,23 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncInt$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val anIntArg = args[0].let { num -> if (num is Int) num.toLong() else num as Long } - api.echoAsyncInt(anIntArg) { result: Result -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + val aNullableBoolArg = args[0] as Boolean? + val aNullableIntArg = args[1] as Long? + val aNullableStringArg = args[2] as String? + val wrapped: List = + try { + listOf( + api.sendMultipleNullableTypesWithoutRecursion( + aNullableBoolArg, aNullableIntArg, aNullableStringArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -1527,21 +1919,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncDouble$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableInt$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aDoubleArg = args[0] as Double - api.echoAsyncDouble(aDoubleArg) { result: Result -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + val aNullableIntArg = args[0] as Long? + val wrapped: List = + try { + listOf(api.echoNullableInt(aNullableIntArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -1551,21 +1941,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncBool$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableDouble$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aBoolArg = args[0] as Boolean - api.echoAsyncBool(aBoolArg) { result: Result -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + val aNullableDoubleArg = args[0] as Double? + val wrapped: List = + try { + listOf(api.echoNullableDouble(aNullableDoubleArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -1575,21 +1963,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncString$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableBool$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aStringArg = args[0] as String - api.echoAsyncString(aStringArg) { result: Result -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + val aNullableBoolArg = args[0] as Boolean? + val wrapped: List = + try { + listOf(api.echoNullableBool(aNullableBoolArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -1599,21 +1985,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncUint8List$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableString$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aUint8ListArg = args[0] as ByteArray - api.echoAsyncUint8List(aUint8ListArg) { result: Result -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + val aNullableStringArg = args[0] as String? + val wrapped: List = + try { + listOf(api.echoNullableString(aNullableStringArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -1623,21 +2007,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncObject$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableUint8List$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val anObjectArg = args[0] as Any - api.echoAsyncObject(anObjectArg) { result: Result -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + val aNullableUint8ListArg = args[0] as ByteArray? + val wrapped: List = + try { + listOf(api.echoNullableUint8List(aNullableUint8ListArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -1647,21 +2029,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncList$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableObject$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val listArg = args[0] as List - api.echoAsyncList(listArg) { result: Result> -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + val aNullableObjectArg = args[0] + val wrapped: List = + try { + listOf(api.echoNullableObject(aNullableObjectArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -1671,21 +2051,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncMap$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableList$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aMapArg = args[0] as Map - api.echoAsyncMap(aMapArg) { result: Result> -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + val aNullableListArg = args[0] as List? + val wrapped: List = + try { + listOf(api.echoNullableList(aNullableListArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -1695,21 +2073,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncEnum$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableEnumList$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val anEnumArg = args[0] as AnEnum - api.echoAsyncEnum(anEnumArg) { result: Result -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + val enumListArg = args[0] as List? + val wrapped: List = + try { + listOf(api.echoNullableEnumList(enumListArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -1719,19 +2095,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncError$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableClassList$separatedMessageChannelSuffix", codec) if (api != null) { - channel.setMessageHandler { _, reply -> - api.throwAsyncError { result: Result -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + channel.setMessageHandler { message, reply -> + val args = message as List + val classListArg = args[0] as List? + val wrapped: List = + try { + listOf(api.echoNullableClassList(classListArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -1741,18 +2117,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncErrorFromVoid$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullEnumList$separatedMessageChannelSuffix", codec) if (api != null) { - channel.setMessageHandler { _, reply -> - api.throwAsyncErrorFromVoid { result: Result -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - reply.reply(wrapResult(null)) - } - } + channel.setMessageHandler { message, reply -> + val args = message as List + val enumListArg = args[0] as List? + val wrapped: List = + try { + listOf(api.echoNullableNonNullEnumList(enumListArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -1762,19 +2139,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncFlutterError$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullClassList$separatedMessageChannelSuffix", codec) if (api != null) { - channel.setMessageHandler { _, reply -> - api.throwAsyncFlutterError { result: Result -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + channel.setMessageHandler { message, reply -> + val args = message as List + val classListArg = args[0] as List? + val wrapped: List = + try { + listOf(api.echoNullableNonNullClassList(classListArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -1784,21 +2161,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncAllTypes$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableMap$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val everythingArg = args[0] as AllTypes - api.echoAsyncAllTypes(everythingArg) { result: Result -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + val mapArg = args[0] as Map? + val wrapped: List = + try { + listOf(api.echoNullableMap(mapArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -1808,22 +2183,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypes$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableStringMap$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val everythingArg = args[0] as AllNullableTypes? - api.echoAsyncNullableAllNullableTypes(everythingArg) { result: Result - -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + val stringMapArg = args[0] as Map? + val wrapped: List = + try { + listOf(api.echoNullableStringMap(stringMapArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -1833,22 +2205,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypesWithoutRecursion$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableIntMap$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val everythingArg = args[0] as AllNullableTypesWithoutRecursion? - api.echoAsyncNullableAllNullableTypesWithoutRecursion(everythingArg) { - result: Result -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + val intMapArg = args[0] as Map? + val wrapped: List = + try { + listOf(api.echoNullableIntMap(intMapArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -1858,21 +2227,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableInt$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableEnumMap$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val anIntArg = args[0].let { num -> if (num is Int) num.toLong() else num as Long? } - api.echoAsyncNullableInt(anIntArg) { result: Result -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + val enumMapArg = args[0] as Map? + val wrapped: List = + try { + listOf(api.echoNullableEnumMap(enumMapArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -1882,21 +2249,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableDouble$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableClassMap$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aDoubleArg = args[0] as Double? - api.echoAsyncNullableDouble(aDoubleArg) { result: Result -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + val classMapArg = args[0] as Map? + val wrapped: List = + try { + listOf(api.echoNullableClassMap(classMapArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -1906,21 +2271,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableBool$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullStringMap$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aBoolArg = args[0] as Boolean? - api.echoAsyncNullableBool(aBoolArg) { result: Result -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + val stringMapArg = args[0] as Map? + val wrapped: List = + try { + listOf(api.echoNullableNonNullStringMap(stringMapArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -1930,21 +2293,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableString$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullIntMap$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aStringArg = args[0] as String? - api.echoAsyncNullableString(aStringArg) { result: Result -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + val intMapArg = args[0] as Map? + val wrapped: List = + try { + listOf(api.echoNullableNonNullIntMap(intMapArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -1954,21 +2315,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableUint8List$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullEnumMap$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aUint8ListArg = args[0] as ByteArray? - api.echoAsyncNullableUint8List(aUint8ListArg) { result: Result -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + val enumMapArg = args[0] as Map? + val wrapped: List = + try { + listOf(api.echoNullableNonNullEnumMap(enumMapArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -1978,21 +2337,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableObject$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullClassMap$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val anObjectArg = args[0] - api.echoAsyncNullableObject(anObjectArg) { result: Result -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + val classMapArg = args[0] as Map? + val wrapped: List = + try { + listOf(api.echoNullableNonNullClassMap(classMapArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -2002,21 +2359,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableList$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableEnum$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val listArg = args[0] as List? - api.echoAsyncNullableList(listArg) { result: Result?> -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + val anEnumArg = args[0] as AnEnum? + val wrapped: List = + try { + listOf(api.echoNullableEnum(anEnumArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -2026,21 +2381,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableMap$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAnotherNullableEnum$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aMapArg = args[0] as Map? - api.echoAsyncNullableMap(aMapArg) { result: Result?> -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + val anotherEnumArg = args[0] as AnotherEnum? + val wrapped: List = + try { + listOf(api.echoAnotherNullableEnum(anotherEnumArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -2050,21 +2403,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableEnum$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoOptionalNullableInt$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val anEnumArg = args[0] as AnEnum? - api.echoAsyncNullableEnum(anEnumArg) { result: Result -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + val aNullableIntArg = args[0] as Long? + val wrapped: List = + try { + listOf(api.echoOptionalNullableInt(aNullableIntArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -2074,18 +2425,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterNoop$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNamedNullableString$separatedMessageChannelSuffix", codec) if (api != null) { - channel.setMessageHandler { _, reply -> - api.callFlutterNoop { result: Result -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - reply.reply(wrapResult(null)) - } - } + channel.setMessageHandler { message, reply -> + val args = message as List + val aNullableStringArg = args[0] as String? + val wrapped: List = + try { + listOf(api.echoNamedNullableString(aNullableStringArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) } } else { channel.setMessageHandler(null) @@ -2095,17 +2447,16 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterThrowError$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.noopAsync$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { _, reply -> - api.callFlutterThrowError { result: Result -> + api.noopAsync { result: Result -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) + reply.reply(wrapResult(null)) } } } @@ -2117,16 +2468,19 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterThrowErrorFromVoid$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncInt$separatedMessageChannelSuffix", codec) if (api != null) { - channel.setMessageHandler { _, reply -> - api.callFlutterThrowErrorFromVoid { result: Result -> + channel.setMessageHandler { message, reply -> + val args = message as List + val anIntArg = args[0] as Long + api.echoAsyncInt(anIntArg) { result: Result -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) } else { - reply.reply(wrapResult(null)) + val data = result.getOrNull() + reply.reply(wrapResult(data)) } } } @@ -2138,13 +2492,13 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllTypes$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncDouble$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val everythingArg = args[0] as AllTypes - api.callFlutterEchoAllTypes(everythingArg) { result: Result -> + val aDoubleArg = args[0] as Double + api.echoAsyncDouble(aDoubleArg) { result: Result -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) @@ -2162,14 +2516,13 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypes$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncBool$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val everythingArg = args[0] as AllNullableTypes? - api.callFlutterEchoAllNullableTypes(everythingArg) { result: Result - -> + val aBoolArg = args[0] as Boolean + api.echoAsyncBool(aBoolArg) { result: Result -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) @@ -2187,26 +2540,21 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypes$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncString$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aNullableBoolArg = args[0] as Boolean? - val aNullableIntArg = - args[1].let { num -> if (num is Int) num.toLong() else num as Long? } - val aNullableStringArg = args[2] as String? - api.callFlutterSendMultipleNullableTypes( - aNullableBoolArg, aNullableIntArg, aNullableStringArg) { - result: Result -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + val aStringArg = args[0] as String + api.echoAsyncString(aStringArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } } } else { channel.setMessageHandler(null) @@ -2216,14 +2564,13 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypesWithoutRecursion$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncUint8List$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val everythingArg = args[0] as AllNullableTypesWithoutRecursion? - api.callFlutterEchoAllNullableTypesWithoutRecursion(everythingArg) { - result: Result -> + val aUint8ListArg = args[0] as ByteArray + api.echoAsyncUint8List(aUint8ListArg) { result: Result -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) @@ -2241,26 +2588,21 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypesWithoutRecursion$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncObject$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aNullableBoolArg = args[0] as Boolean? - val aNullableIntArg = - args[1].let { num -> if (num is Int) num.toLong() else num as Long? } - val aNullableStringArg = args[2] as String? - api.callFlutterSendMultipleNullableTypesWithoutRecursion( - aNullableBoolArg, aNullableIntArg, aNullableStringArg) { - result: Result -> - val error = result.exceptionOrNull() - if (error != null) { - reply.reply(wrapError(error)) - } else { - val data = result.getOrNull() - reply.reply(wrapResult(data)) - } - } + val anObjectArg = args[0] as Any + api.echoAsyncObject(anObjectArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } } } else { channel.setMessageHandler(null) @@ -2270,13 +2612,13 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoBool$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncList$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aBoolArg = args[0] as Boolean - api.callFlutterEchoBool(aBoolArg) { result: Result -> + val listArg = args[0] as List + api.echoAsyncList(listArg) { result: Result> -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) @@ -2294,13 +2636,13 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoInt$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncEnumList$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val anIntArg = args[0].let { num -> if (num is Int) num.toLong() else num as Long } - api.callFlutterEchoInt(anIntArg) { result: Result -> + val enumListArg = args[0] as List + api.echoAsyncEnumList(enumListArg) { result: Result> -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) @@ -2318,13 +2660,13 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoDouble$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncClassList$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aDoubleArg = args[0] as Double - api.callFlutterEchoDouble(aDoubleArg) { result: Result -> + val classListArg = args[0] as List + api.echoAsyncClassList(classListArg) { result: Result> -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) @@ -2342,13 +2684,13 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoString$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncMap$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aStringArg = args[0] as String - api.callFlutterEchoString(aStringArg) { result: Result -> + val mapArg = args[0] as Map + api.echoAsyncMap(mapArg) { result: Result> -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) @@ -2366,13 +2708,13 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoUint8List$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncStringMap$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val listArg = args[0] as ByteArray - api.callFlutterEchoUint8List(listArg) { result: Result -> + val stringMapArg = args[0] as Map + api.echoAsyncStringMap(stringMapArg) { result: Result> -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) @@ -2390,13 +2732,13 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoList$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncIntMap$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val listArg = args[0] as List - api.callFlutterEchoList(listArg) { result: Result> -> + val intMapArg = args[0] as Map + api.echoAsyncIntMap(intMapArg) { result: Result> -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) @@ -2414,13 +2756,13 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoMap$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncEnumMap$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aMapArg = args[0] as Map - api.callFlutterEchoMap(aMapArg) { result: Result> -> + val enumMapArg = args[0] as Map + api.echoAsyncEnumMap(enumMapArg) { result: Result> -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) @@ -2438,13 +2780,13 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoEnum$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncClassMap$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val anEnumArg = args[0] as AnEnum - api.callFlutterEchoEnum(anEnumArg) { result: Result -> + val classMapArg = args[0] as Map + api.echoAsyncClassMap(classMapArg) { result: Result> -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) @@ -2462,13 +2804,13 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableBool$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncEnum$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aBoolArg = args[0] as Boolean? - api.callFlutterEchoNullableBool(aBoolArg) { result: Result -> + val anEnumArg = args[0] as AnEnum + api.echoAsyncEnum(anEnumArg) { result: Result -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) @@ -2486,13 +2828,13 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableInt$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAnotherAsyncEnum$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val anIntArg = args[0].let { num -> if (num is Int) num.toLong() else num as Long? } - api.callFlutterEchoNullableInt(anIntArg) { result: Result -> + val anotherEnumArg = args[0] as AnotherEnum + api.echoAnotherAsyncEnum(anotherEnumArg) { result: Result -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) @@ -2510,13 +2852,78 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableDouble$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncError$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + api.throwAsyncError { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncErrorFromVoid$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + api.throwAsyncErrorFromVoid { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + reply.reply(wrapResult(null)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncFlutterError$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + api.throwAsyncFlutterError { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncAllTypes$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aDoubleArg = args[0] as Double? - api.callFlutterEchoNullableDouble(aDoubleArg) { result: Result -> + val everythingArg = args[0] as AllTypes + api.echoAsyncAllTypes(everythingArg) { result: Result -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) @@ -2534,13 +2941,14 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableString$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypes$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aStringArg = args[0] as String? - api.callFlutterEchoNullableString(aStringArg) { result: Result -> + val everythingArg = args[0] as AllNullableTypes? + api.echoAsyncNullableAllNullableTypes(everythingArg) { result: Result + -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) @@ -2558,13 +2966,14 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableUint8List$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypesWithoutRecursion$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val listArg = args[0] as ByteArray? - api.callFlutterEchoNullableUint8List(listArg) { result: Result -> + val everythingArg = args[0] as AllNullableTypesWithoutRecursion? + api.echoAsyncNullableAllNullableTypesWithoutRecursion(everythingArg) { + result: Result -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) @@ -2582,13 +2991,13 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableList$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableInt$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val listArg = args[0] as List? - api.callFlutterEchoNullableList(listArg) { result: Result?> -> + val anIntArg = args[0] as Long? + api.echoAsyncNullableInt(anIntArg) { result: Result -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) @@ -2606,13 +3015,13 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableMap$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableDouble$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aMapArg = args[0] as Map? - api.callFlutterEchoNullableMap(aMapArg) { result: Result?> -> + val aDoubleArg = args[0] as Double? + api.echoAsyncNullableDouble(aDoubleArg) { result: Result -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) @@ -2630,13 +3039,13 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableEnum$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableBool$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val anEnumArg = args[0] as AnEnum? - api.callFlutterEchoNullableEnum(anEnumArg) { result: Result -> + val aBoolArg = args[0] as Boolean? + api.echoAsyncNullableBool(aBoolArg) { result: Result -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) @@ -2654,13 +3063,13 @@ interface HostIntegrationCoreApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSmallApiEchoString$separatedMessageChannelSuffix", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableString$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val aStringArg = args[0] as String - api.callFlutterSmallApiEchoString(aStringArg) { result: Result -> + val aStringArg = args[0] as String? + api.echoAsyncNullableString(aStringArg) { result: Result -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) @@ -2674,55 +3083,2025 @@ interface HostIntegrationCoreApi { channel.setMessageHandler(null) } } - } - } -} -/** - * The core interface that the Dart platform_test code implements for host integration tests to call - * into. - * - * Generated class from Pigeon that represents Flutter messages that can be called from Kotlin. - */ -class FlutterIntegrationCoreApi( - private val binaryMessenger: BinaryMessenger, - private val messageChannelSuffix: String = "" -) { - companion object { - /** The codec used by FlutterIntegrationCoreApi. */ - val codec: MessageCodec by lazy { CoreTestsPigeonCodec } - } - /** A no-op function taking no arguments and returning no value, to sanity test basic calling. */ - fun noop(callback: (Result) -> Unit) { - val separatedMessageChannelSuffix = - if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" - val channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.noop$separatedMessageChannelSuffix" - val channel = BasicMessageChannel(binaryMessenger, channelName, codec) - channel.send(null) { - if (it is List<*>) { - if (it.size > 1) { - callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableUint8List$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val aUint8ListArg = args[0] as ByteArray? + api.echoAsyncNullableUint8List(aUint8ListArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } } else { - callback(Result.success(Unit)) + channel.setMessageHandler(null) } - } else { - callback(Result.failure(createConnectionError(channelName))) } - } - } - /** Responds with an error from an async function returning a value. */ - fun throwError(callback: (Result) -> Unit) { - val separatedMessageChannelSuffix = - if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" - val channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwError$separatedMessageChannelSuffix" - val channel = BasicMessageChannel(binaryMessenger, channelName, codec) - channel.send(null) { - if (it is List<*>) { + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableObject$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val anObjectArg = args[0] + api.echoAsyncNullableObject(anObjectArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableList$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val listArg = args[0] as List? + api.echoAsyncNullableList(listArg) { result: Result?> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableEnumList$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val enumListArg = args[0] as List? + api.echoAsyncNullableEnumList(enumListArg) { result: Result?> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableClassList$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val classListArg = args[0] as List? + api.echoAsyncNullableClassList(classListArg) { result: Result?> + -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableMap$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val mapArg = args[0] as Map? + api.echoAsyncNullableMap(mapArg) { result: Result?> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableStringMap$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val stringMapArg = args[0] as Map? + api.echoAsyncNullableStringMap(stringMapArg) { result: Result?> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableIntMap$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val intMapArg = args[0] as Map? + api.echoAsyncNullableIntMap(intMapArg) { result: Result?> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableEnumMap$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val enumMapArg = args[0] as Map? + api.echoAsyncNullableEnumMap(enumMapArg) { result: Result?> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableClassMap$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val classMapArg = args[0] as Map? + api.echoAsyncNullableClassMap(classMapArg) { + result: Result?> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableEnum$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val anEnumArg = args[0] as AnEnum? + api.echoAsyncNullableEnum(anEnumArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAnotherAsyncNullableEnum$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val anotherEnumArg = args[0] as AnotherEnum? + api.echoAnotherAsyncNullableEnum(anotherEnumArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterNoop$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + api.callFlutterNoop { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + reply.reply(wrapResult(null)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterThrowError$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + api.callFlutterThrowError { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterThrowErrorFromVoid$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + api.callFlutterThrowErrorFromVoid { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + reply.reply(wrapResult(null)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllTypes$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val everythingArg = args[0] as AllTypes + api.callFlutterEchoAllTypes(everythingArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypes$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val everythingArg = args[0] as AllNullableTypes? + api.callFlutterEchoAllNullableTypes(everythingArg) { result: Result + -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypes$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val aNullableBoolArg = args[0] as Boolean? + val aNullableIntArg = args[1] as Long? + val aNullableStringArg = args[2] as String? + api.callFlutterSendMultipleNullableTypes( + aNullableBoolArg, aNullableIntArg, aNullableStringArg) { + result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypesWithoutRecursion$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val everythingArg = args[0] as AllNullableTypesWithoutRecursion? + api.callFlutterEchoAllNullableTypesWithoutRecursion(everythingArg) { + result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypesWithoutRecursion$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val aNullableBoolArg = args[0] as Boolean? + val aNullableIntArg = args[1] as Long? + val aNullableStringArg = args[2] as String? + api.callFlutterSendMultipleNullableTypesWithoutRecursion( + aNullableBoolArg, aNullableIntArg, aNullableStringArg) { + result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoBool$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val aBoolArg = args[0] as Boolean + api.callFlutterEchoBool(aBoolArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoInt$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val anIntArg = args[0] as Long + api.callFlutterEchoInt(anIntArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoDouble$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val aDoubleArg = args[0] as Double + api.callFlutterEchoDouble(aDoubleArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoString$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val aStringArg = args[0] as String + api.callFlutterEchoString(aStringArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoUint8List$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val listArg = args[0] as ByteArray + api.callFlutterEchoUint8List(listArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoList$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val listArg = args[0] as List + api.callFlutterEchoList(listArg) { result: Result> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoEnumList$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val enumListArg = args[0] as List + api.callFlutterEchoEnumList(enumListArg) { result: Result> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoClassList$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val classListArg = args[0] as List + api.callFlutterEchoClassList(classListArg) { result: Result> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullEnumList$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val enumListArg = args[0] as List + api.callFlutterEchoNonNullEnumList(enumListArg) { result: Result> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullClassList$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val classListArg = args[0] as List + api.callFlutterEchoNonNullClassList(classListArg) { + result: Result> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoMap$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val mapArg = args[0] as Map + api.callFlutterEchoMap(mapArg) { result: Result> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoStringMap$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val stringMapArg = args[0] as Map + api.callFlutterEchoStringMap(stringMapArg) { result: Result> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoIntMap$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val intMapArg = args[0] as Map + api.callFlutterEchoIntMap(intMapArg) { result: Result> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoEnumMap$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val enumMapArg = args[0] as Map + api.callFlutterEchoEnumMap(enumMapArg) { result: Result> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoClassMap$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val classMapArg = args[0] as Map + api.callFlutterEchoClassMap(classMapArg) { result: Result> + -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullStringMap$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val stringMapArg = args[0] as Map + api.callFlutterEchoNonNullStringMap(stringMapArg) { result: Result> + -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullIntMap$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val intMapArg = args[0] as Map + api.callFlutterEchoNonNullIntMap(intMapArg) { result: Result> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullEnumMap$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val enumMapArg = args[0] as Map + api.callFlutterEchoNonNullEnumMap(enumMapArg) { result: Result> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullClassMap$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val classMapArg = args[0] as Map + api.callFlutterEchoNonNullClassMap(classMapArg) { + result: Result> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoEnum$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val anEnumArg = args[0] as AnEnum + api.callFlutterEchoEnum(anEnumArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAnotherEnum$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val anotherEnumArg = args[0] as AnotherEnum + api.callFlutterEchoAnotherEnum(anotherEnumArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableBool$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val aBoolArg = args[0] as Boolean? + api.callFlutterEchoNullableBool(aBoolArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableInt$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val anIntArg = args[0] as Long? + api.callFlutterEchoNullableInt(anIntArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableDouble$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val aDoubleArg = args[0] as Double? + api.callFlutterEchoNullableDouble(aDoubleArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableString$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val aStringArg = args[0] as String? + api.callFlutterEchoNullableString(aStringArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableUint8List$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val listArg = args[0] as ByteArray? + api.callFlutterEchoNullableUint8List(listArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableList$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val listArg = args[0] as List? + api.callFlutterEchoNullableList(listArg) { result: Result?> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableEnumList$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val enumListArg = args[0] as List? + api.callFlutterEchoNullableEnumList(enumListArg) { result: Result?> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableClassList$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val classListArg = args[0] as List? + api.callFlutterEchoNullableClassList(classListArg) { + result: Result?> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullEnumList$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val enumListArg = args[0] as List? + api.callFlutterEchoNullableNonNullEnumList(enumListArg) { result: Result?> + -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullClassList$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val classListArg = args[0] as List? + api.callFlutterEchoNullableNonNullClassList(classListArg) { + result: Result?> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableMap$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val mapArg = args[0] as Map? + api.callFlutterEchoNullableMap(mapArg) { result: Result?> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableStringMap$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val stringMapArg = args[0] as Map? + api.callFlutterEchoNullableStringMap(stringMapArg) { + result: Result?> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableIntMap$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val intMapArg = args[0] as Map? + api.callFlutterEchoNullableIntMap(intMapArg) { result: Result?> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableEnumMap$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val enumMapArg = args[0] as Map? + api.callFlutterEchoNullableEnumMap(enumMapArg) { result: Result?> + -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableClassMap$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val classMapArg = args[0] as Map? + api.callFlutterEchoNullableClassMap(classMapArg) { + result: Result?> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullStringMap$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val stringMapArg = args[0] as Map? + api.callFlutterEchoNullableNonNullStringMap(stringMapArg) { + result: Result?> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullIntMap$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val intMapArg = args[0] as Map? + api.callFlutterEchoNullableNonNullIntMap(intMapArg) { result: Result?> + -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullEnumMap$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val enumMapArg = args[0] as Map? + api.callFlutterEchoNullableNonNullEnumMap(enumMapArg) { + result: Result?> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullClassMap$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val classMapArg = args[0] as Map? + api.callFlutterEchoNullableNonNullClassMap(classMapArg) { + result: Result?> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableEnum$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val anEnumArg = args[0] as AnEnum? + api.callFlutterEchoNullableEnum(anEnumArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAnotherNullableEnum$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val anotherEnumArg = args[0] as AnotherEnum? + api.callFlutterEchoAnotherNullableEnum(anotherEnumArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSmallApiEchoString$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val aStringArg = args[0] as String + api.callFlutterSmallApiEchoString(aStringArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + } + } +} +/** + * The core interface that the Dart platform_test code implements for host integration tests to call + * into. + * + * Generated class from Pigeon that represents Flutter messages that can be called from Kotlin. + */ +class FlutterIntegrationCoreApi( + private val binaryMessenger: BinaryMessenger, + private val messageChannelSuffix: String = "" +) { + companion object { + /** The codec used by FlutterIntegrationCoreApi. */ + val codec: MessageCodec by lazy { CoreTestsPigeonCodec() } + } + /** A no-op function taking no arguments and returning no value, to sanity test basic calling. */ + fun noop(callback: (Result) -> Unit) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.noop$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(null) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** Responds with an error from an async function returning a value. */ + fun throwError(callback: (Result) -> Unit) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwError$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(null) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + val output = it[0] + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** Responds with an error from an async void function. */ + fun throwErrorFromVoid(callback: (Result) -> Unit) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwErrorFromVoid$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(null) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** Returns the passed object, to test serialization and deserialization. */ + fun echoAllTypes(everythingArg: AllTypes, callback: (Result) -> Unit) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllTypes$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(everythingArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as AllTypes + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** Returns the passed object, to test serialization and deserialization. */ + fun echoAllNullableTypes( + everythingArg: AllNullableTypes?, + callback: (Result) -> Unit + ) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypes$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(everythingArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + val output = it[0] as AllNullableTypes? + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** + * Returns passed in arguments of multiple types. + * + * Tests multiple-arity FlutterApi handling. + */ + fun sendMultipleNullableTypes( + aNullableBoolArg: Boolean?, + aNullableIntArg: Long?, + aNullableStringArg: String?, + callback: (Result) -> Unit + ) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypes$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(aNullableBoolArg, aNullableIntArg, aNullableStringArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as AllNullableTypes + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** Returns the passed object, to test serialization and deserialization. */ + fun echoAllNullableTypesWithoutRecursion( + everythingArg: AllNullableTypesWithoutRecursion?, + callback: (Result) -> Unit + ) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypesWithoutRecursion$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(everythingArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + val output = it[0] as AllNullableTypesWithoutRecursion? + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** + * Returns passed in arguments of multiple types. + * + * Tests multiple-arity FlutterApi handling. + */ + fun sendMultipleNullableTypesWithoutRecursion( + aNullableBoolArg: Boolean?, + aNullableIntArg: Long?, + aNullableStringArg: String?, + callback: (Result) -> Unit + ) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(aNullableBoolArg, aNullableIntArg, aNullableStringArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as AllNullableTypesWithoutRecursion + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** Returns the passed boolean, to test serialization and deserialization. */ + fun echoBool(aBoolArg: Boolean, callback: (Result) -> Unit) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoBool$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(aBoolArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as Boolean + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** Returns the passed int, to test serialization and deserialization. */ + fun echoInt(anIntArg: Long, callback: (Result) -> Unit) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoInt$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(anIntArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as Long + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** Returns the passed double, to test serialization and deserialization. */ + fun echoDouble(aDoubleArg: Double, callback: (Result) -> Unit) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoDouble$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(aDoubleArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as Double + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** Returns the passed string, to test serialization and deserialization. */ + fun echoString(aStringArg: String, callback: (Result) -> Unit) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoString$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(aStringArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as String + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** Returns the passed byte list, to test serialization and deserialization. */ + fun echoUint8List(listArg: ByteArray, callback: (Result) -> Unit) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoUint8List$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(listArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as ByteArray + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** Returns the passed list, to test serialization and deserialization. */ + fun echoList(listArg: List, callback: (Result>) -> Unit) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoList$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(listArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as List + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** Returns the passed list, to test serialization and deserialization. */ + fun echoEnumList(enumListArg: List, callback: (Result>) -> Unit) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnumList$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(enumListArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as List + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** Returns the passed list, to test serialization and deserialization. */ + fun echoClassList( + classListArg: List, + callback: (Result>) -> Unit + ) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoClassList$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(classListArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as List + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** Returns the passed list, to test serialization and deserialization. */ + fun echoNonNullEnumList(enumListArg: List, callback: (Result>) -> Unit) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullEnumList$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(enumListArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as List + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** Returns the passed list, to test serialization and deserialization. */ + fun echoNonNullClassList( + classListArg: List, + callback: (Result>) -> Unit + ) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullClassList$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(classListArg)) { + if (it is List<*>) { if (it.size > 1) { callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) } else { - val output = it[0] + val output = it[0] as List callback(Result.success(output)) } } else { @@ -2730,33 +5109,302 @@ class FlutterIntegrationCoreApi( } } } - /** Responds with an error from an async void function. */ - fun throwErrorFromVoid(callback: (Result) -> Unit) { + /** Returns the passed map, to test serialization and deserialization. */ + fun echoMap(mapArg: Map, callback: (Result>) -> Unit) { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" val channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwErrorFromVoid$separatedMessageChannelSuffix" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoMap$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) - channel.send(null) { + channel.send(listOf(mapArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as Map + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** Returns the passed map, to test serialization and deserialization. */ + fun echoStringMap( + stringMapArg: Map, + callback: (Result>) -> Unit + ) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoStringMap$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(stringMapArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as Map + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** Returns the passed map, to test serialization and deserialization. */ + fun echoIntMap(intMapArg: Map, callback: (Result>) -> Unit) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoIntMap$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(intMapArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as Map + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** Returns the passed map, to test serialization and deserialization. */ + fun echoEnumMap( + enumMapArg: Map, + callback: (Result>) -> Unit + ) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnumMap$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(enumMapArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as Map + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** Returns the passed map, to test serialization and deserialization. */ + fun echoClassMap( + classMapArg: Map, + callback: (Result>) -> Unit + ) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoClassMap$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(classMapArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as Map + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** Returns the passed map, to test serialization and deserialization. */ + fun echoNonNullStringMap( + stringMapArg: Map, + callback: (Result>) -> Unit + ) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullStringMap$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(stringMapArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as Map + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** Returns the passed map, to test serialization and deserialization. */ + fun echoNonNullIntMap(intMapArg: Map, callback: (Result>) -> Unit) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullIntMap$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(intMapArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as Map + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** Returns the passed map, to test serialization and deserialization. */ + fun echoNonNullEnumMap( + enumMapArg: Map, + callback: (Result>) -> Unit + ) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullEnumMap$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(enumMapArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as Map + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** Returns the passed map, to test serialization and deserialization. */ + fun echoNonNullClassMap( + classMapArg: Map, + callback: (Result>) -> Unit + ) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullClassMap$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(classMapArg)) { if (it is List<*>) { if (it.size > 1) { callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as Map + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** Returns the passed enum to test serialization and deserialization. */ + fun echoEnum(anEnumArg: AnEnum, callback: (Result) -> Unit) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnum$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(anEnumArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) } else { - callback(Result.success(Unit)) + val output = it[0] as AnEnum + callback(Result.success(output)) } } else { callback(Result.failure(createConnectionError(channelName))) } } } - /** Returns the passed object, to test serialization and deserialization. */ - fun echoAllTypes(everythingArg: AllTypes, callback: (Result) -> Unit) { + /** Returns the passed enum to test serialization and deserialization. */ + fun echoAnotherEnum(anotherEnumArg: AnotherEnum, callback: (Result) -> Unit) { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" val channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllTypes$separatedMessageChannelSuffix" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAnotherEnum$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) - channel.send(listOf(everythingArg)) { + channel.send(listOf(anotherEnumArg)) { if (it is List<*>) { if (it.size > 1) { callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) @@ -2768,7 +5416,7 @@ class FlutterIntegrationCoreApi( "Flutter api returned null value for non-null return value.", ""))) } else { - val output = it[0] as AllTypes + val output = it[0] as AnotherEnum callback(Result.success(output)) } } else { @@ -2776,22 +5424,19 @@ class FlutterIntegrationCoreApi( } } } - /** Returns the passed object, to test serialization and deserialization. */ - fun echoAllNullableTypes( - everythingArg: AllNullableTypes?, - callback: (Result) -> Unit - ) { + /** Returns the passed boolean, to test serialization and deserialization. */ + fun echoNullableBool(aBoolArg: Boolean?, callback: (Result) -> Unit) { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" val channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypes$separatedMessageChannelSuffix" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableBool$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) - channel.send(listOf(everythingArg)) { + channel.send(listOf(aBoolArg)) { if (it is List<*>) { if (it.size > 1) { callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) } else { - val output = it[0] as AllNullableTypes? + val output = it[0] as Boolean? callback(Result.success(output)) } } else { @@ -2799,35 +5444,19 @@ class FlutterIntegrationCoreApi( } } } - /** - * Returns passed in arguments of multiple types. - * - * Tests multiple-arity FlutterApi handling. - */ - fun sendMultipleNullableTypes( - aNullableBoolArg: Boolean?, - aNullableIntArg: Long?, - aNullableStringArg: String?, - callback: (Result) -> Unit - ) { + /** Returns the passed int, to test serialization and deserialization. */ + fun echoNullableInt(anIntArg: Long?, callback: (Result) -> Unit) { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" val channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypes$separatedMessageChannelSuffix" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableInt$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) - channel.send(listOf(aNullableBoolArg, aNullableIntArg, aNullableStringArg)) { + channel.send(listOf(anIntArg)) { if (it is List<*>) { if (it.size > 1) { callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) - } else if (it[0] == null) { - callback( - Result.failure( - FlutterError( - "null-error", - "Flutter api returned null value for non-null return value.", - ""))) } else { - val output = it[0] as AllNullableTypes + val output = it[0] as Long? callback(Result.success(output)) } } else { @@ -2835,22 +5464,19 @@ class FlutterIntegrationCoreApi( } } } - /** Returns the passed object, to test serialization and deserialization. */ - fun echoAllNullableTypesWithoutRecursion( - everythingArg: AllNullableTypesWithoutRecursion?, - callback: (Result) -> Unit - ) { + /** Returns the passed double, to test serialization and deserialization. */ + fun echoNullableDouble(aDoubleArg: Double?, callback: (Result) -> Unit) { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" val channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypesWithoutRecursion$separatedMessageChannelSuffix" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableDouble$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) - channel.send(listOf(everythingArg)) { + channel.send(listOf(aDoubleArg)) { if (it is List<*>) { if (it.size > 1) { callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) } else { - val output = it[0] as AllNullableTypesWithoutRecursion? + val output = it[0] as Double? callback(Result.success(output)) } } else { @@ -2858,35 +5484,19 @@ class FlutterIntegrationCoreApi( } } } - /** - * Returns passed in arguments of multiple types. - * - * Tests multiple-arity FlutterApi handling. - */ - fun sendMultipleNullableTypesWithoutRecursion( - aNullableBoolArg: Boolean?, - aNullableIntArg: Long?, - aNullableStringArg: String?, - callback: (Result) -> Unit - ) { + /** Returns the passed string, to test serialization and deserialization. */ + fun echoNullableString(aStringArg: String?, callback: (Result) -> Unit) { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" val channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion$separatedMessageChannelSuffix" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableString$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) - channel.send(listOf(aNullableBoolArg, aNullableIntArg, aNullableStringArg)) { + channel.send(listOf(aStringArg)) { if (it is List<*>) { if (it.size > 1) { callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) - } else if (it[0] == null) { - callback( - Result.failure( - FlutterError( - "null-error", - "Flutter api returned null value for non-null return value.", - ""))) } else { - val output = it[0] as AllNullableTypesWithoutRecursion + val output = it[0] as String? callback(Result.success(output)) } } else { @@ -2894,26 +5504,19 @@ class FlutterIntegrationCoreApi( } } } - /** Returns the passed boolean, to test serialization and deserialization. */ - fun echoBool(aBoolArg: Boolean, callback: (Result) -> Unit) { + /** Returns the passed byte list, to test serialization and deserialization. */ + fun echoNullableUint8List(listArg: ByteArray?, callback: (Result) -> Unit) { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" val channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoBool$separatedMessageChannelSuffix" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableUint8List$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) - channel.send(listOf(aBoolArg)) { + channel.send(listOf(listArg)) { if (it is List<*>) { if (it.size > 1) { callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) - } else if (it[0] == null) { - callback( - Result.failure( - FlutterError( - "null-error", - "Flutter api returned null value for non-null return value.", - ""))) } else { - val output = it[0] as Boolean + val output = it[0] as ByteArray? callback(Result.success(output)) } } else { @@ -2921,26 +5524,19 @@ class FlutterIntegrationCoreApi( } } } - /** Returns the passed int, to test serialization and deserialization. */ - fun echoInt(anIntArg: Long, callback: (Result) -> Unit) { + /** Returns the passed list, to test serialization and deserialization. */ + fun echoNullableList(listArg: List?, callback: (Result?>) -> Unit) { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" val channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoInt$separatedMessageChannelSuffix" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableList$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) - channel.send(listOf(anIntArg)) { + channel.send(listOf(listArg)) { if (it is List<*>) { if (it.size > 1) { callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) - } else if (it[0] == null) { - callback( - Result.failure( - FlutterError( - "null-error", - "Flutter api returned null value for non-null return value.", - ""))) } else { - val output = it[0].let { num -> if (num is Int) num.toLong() else num as Long } + val output = it[0] as List? callback(Result.success(output)) } } else { @@ -2948,26 +5544,22 @@ class FlutterIntegrationCoreApi( } } } - /** Returns the passed double, to test serialization and deserialization. */ - fun echoDouble(aDoubleArg: Double, callback: (Result) -> Unit) { + /** Returns the passed list, to test serialization and deserialization. */ + fun echoNullableEnumList( + enumListArg: List?, + callback: (Result?>) -> Unit + ) { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" val channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoDouble$separatedMessageChannelSuffix" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableEnumList$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) - channel.send(listOf(aDoubleArg)) { + channel.send(listOf(enumListArg)) { if (it is List<*>) { if (it.size > 1) { callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) - } else if (it[0] == null) { - callback( - Result.failure( - FlutterError( - "null-error", - "Flutter api returned null value for non-null return value.", - ""))) } else { - val output = it[0] as Double + val output = it[0] as List? callback(Result.success(output)) } } else { @@ -2975,26 +5567,22 @@ class FlutterIntegrationCoreApi( } } } - /** Returns the passed string, to test serialization and deserialization. */ - fun echoString(aStringArg: String, callback: (Result) -> Unit) { + /** Returns the passed list, to test serialization and deserialization. */ + fun echoNullableClassList( + classListArg: List?, + callback: (Result?>) -> Unit + ) { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" val channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoString$separatedMessageChannelSuffix" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableClassList$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) - channel.send(listOf(aStringArg)) { + channel.send(listOf(classListArg)) { if (it is List<*>) { if (it.size > 1) { callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) - } else if (it[0] == null) { - callback( - Result.failure( - FlutterError( - "null-error", - "Flutter api returned null value for non-null return value.", - ""))) } else { - val output = it[0] as String + val output = it[0] as List? callback(Result.success(output)) } } else { @@ -3002,26 +5590,22 @@ class FlutterIntegrationCoreApi( } } } - /** Returns the passed byte list, to test serialization and deserialization. */ - fun echoUint8List(listArg: ByteArray, callback: (Result) -> Unit) { + /** Returns the passed list, to test serialization and deserialization. */ + fun echoNullableNonNullEnumList( + enumListArg: List?, + callback: (Result?>) -> Unit + ) { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" val channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoUint8List$separatedMessageChannelSuffix" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullEnumList$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) - channel.send(listOf(listArg)) { + channel.send(listOf(enumListArg)) { if (it is List<*>) { if (it.size > 1) { callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) - } else if (it[0] == null) { - callback( - Result.failure( - FlutterError( - "null-error", - "Flutter api returned null value for non-null return value.", - ""))) } else { - val output = it[0] as ByteArray + val output = it[0] as List? callback(Result.success(output)) } } else { @@ -3030,25 +5614,21 @@ class FlutterIntegrationCoreApi( } } /** Returns the passed list, to test serialization and deserialization. */ - fun echoList(listArg: List, callback: (Result>) -> Unit) { + fun echoNullableNonNullClassList( + classListArg: List?, + callback: (Result?>) -> Unit + ) { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" val channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoList$separatedMessageChannelSuffix" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullClassList$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) - channel.send(listOf(listArg)) { + channel.send(listOf(classListArg)) { if (it is List<*>) { if (it.size > 1) { callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) - } else if (it[0] == null) { - callback( - Result.failure( - FlutterError( - "null-error", - "Flutter api returned null value for non-null return value.", - ""))) } else { - val output = it[0] as List + val output = it[0] as List? callback(Result.success(output)) } } else { @@ -3057,25 +5637,18 @@ class FlutterIntegrationCoreApi( } } /** Returns the passed map, to test serialization and deserialization. */ - fun echoMap(aMapArg: Map, callback: (Result>) -> Unit) { + fun echoNullableMap(mapArg: Map?, callback: (Result?>) -> Unit) { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" val channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoMap$separatedMessageChannelSuffix" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableMap$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) - channel.send(listOf(aMapArg)) { + channel.send(listOf(mapArg)) { if (it is List<*>) { if (it.size > 1) { callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) - } else if (it[0] == null) { - callback( - Result.failure( - FlutterError( - "null-error", - "Flutter api returned null value for non-null return value.", - ""))) } else { - val output = it[0] as Map + val output = it[0] as Map? callback(Result.success(output)) } } else { @@ -3083,26 +5656,22 @@ class FlutterIntegrationCoreApi( } } } - /** Returns the passed enum to test serialization and deserialization. */ - fun echoEnum(anEnumArg: AnEnum, callback: (Result) -> Unit) { + /** Returns the passed map, to test serialization and deserialization. */ + fun echoNullableStringMap( + stringMapArg: Map?, + callback: (Result?>) -> Unit + ) { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" val channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnum$separatedMessageChannelSuffix" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableStringMap$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) - channel.send(listOf(anEnumArg)) { + channel.send(listOf(stringMapArg)) { if (it is List<*>) { if (it.size > 1) { callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) - } else if (it[0] == null) { - callback( - Result.failure( - FlutterError( - "null-error", - "Flutter api returned null value for non-null return value.", - ""))) } else { - val output = it[0] as AnEnum + val output = it[0] as Map? callback(Result.success(output)) } } else { @@ -3110,19 +5679,22 @@ class FlutterIntegrationCoreApi( } } } - /** Returns the passed boolean, to test serialization and deserialization. */ - fun echoNullableBool(aBoolArg: Boolean?, callback: (Result) -> Unit) { + /** Returns the passed map, to test serialization and deserialization. */ + fun echoNullableIntMap( + intMapArg: Map?, + callback: (Result?>) -> Unit + ) { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" val channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableBool$separatedMessageChannelSuffix" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableIntMap$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) - channel.send(listOf(aBoolArg)) { + channel.send(listOf(intMapArg)) { if (it is List<*>) { if (it.size > 1) { callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) } else { - val output = it[0] as Boolean? + val output = it[0] as Map? callback(Result.success(output)) } } else { @@ -3130,19 +5702,22 @@ class FlutterIntegrationCoreApi( } } } - /** Returns the passed int, to test serialization and deserialization. */ - fun echoNullableInt(anIntArg: Long?, callback: (Result) -> Unit) { + /** Returns the passed map, to test serialization and deserialization. */ + fun echoNullableEnumMap( + enumMapArg: Map?, + callback: (Result?>) -> Unit + ) { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" val channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableInt$separatedMessageChannelSuffix" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableEnumMap$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) - channel.send(listOf(anIntArg)) { + channel.send(listOf(enumMapArg)) { if (it is List<*>) { if (it.size > 1) { callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) } else { - val output = it[0].let { num -> if (num is Int) num.toLong() else num as Long? } + val output = it[0] as Map? callback(Result.success(output)) } } else { @@ -3150,19 +5725,22 @@ class FlutterIntegrationCoreApi( } } } - /** Returns the passed double, to test serialization and deserialization. */ - fun echoNullableDouble(aDoubleArg: Double?, callback: (Result) -> Unit) { + /** Returns the passed map, to test serialization and deserialization. */ + fun echoNullableClassMap( + classMapArg: Map?, + callback: (Result?>) -> Unit + ) { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" val channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableDouble$separatedMessageChannelSuffix" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableClassMap$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) - channel.send(listOf(aDoubleArg)) { + channel.send(listOf(classMapArg)) { if (it is List<*>) { if (it.size > 1) { callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) } else { - val output = it[0] as Double? + val output = it[0] as Map? callback(Result.success(output)) } } else { @@ -3170,19 +5748,22 @@ class FlutterIntegrationCoreApi( } } } - /** Returns the passed string, to test serialization and deserialization. */ - fun echoNullableString(aStringArg: String?, callback: (Result) -> Unit) { + /** Returns the passed map, to test serialization and deserialization. */ + fun echoNullableNonNullStringMap( + stringMapArg: Map?, + callback: (Result?>) -> Unit + ) { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" val channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableString$separatedMessageChannelSuffix" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullStringMap$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) - channel.send(listOf(aStringArg)) { + channel.send(listOf(stringMapArg)) { if (it is List<*>) { if (it.size > 1) { callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) } else { - val output = it[0] as String? + val output = it[0] as Map? callback(Result.success(output)) } } else { @@ -3190,19 +5771,22 @@ class FlutterIntegrationCoreApi( } } } - /** Returns the passed byte list, to test serialization and deserialization. */ - fun echoNullableUint8List(listArg: ByteArray?, callback: (Result) -> Unit) { + /** Returns the passed map, to test serialization and deserialization. */ + fun echoNullableNonNullIntMap( + intMapArg: Map?, + callback: (Result?>) -> Unit + ) { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" val channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableUint8List$separatedMessageChannelSuffix" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullIntMap$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) - channel.send(listOf(listArg)) { + channel.send(listOf(intMapArg)) { if (it is List<*>) { if (it.size > 1) { callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) } else { - val output = it[0] as ByteArray? + val output = it[0] as Map? callback(Result.success(output)) } } else { @@ -3210,19 +5794,22 @@ class FlutterIntegrationCoreApi( } } } - /** Returns the passed list, to test serialization and deserialization. */ - fun echoNullableList(listArg: List?, callback: (Result?>) -> Unit) { + /** Returns the passed map, to test serialization and deserialization. */ + fun echoNullableNonNullEnumMap( + enumMapArg: Map?, + callback: (Result?>) -> Unit + ) { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" val channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableList$separatedMessageChannelSuffix" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullEnumMap$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) - channel.send(listOf(listArg)) { + channel.send(listOf(enumMapArg)) { if (it is List<*>) { if (it.size > 1) { callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) } else { - val output = it[0] as List? + val output = it[0] as Map? callback(Result.success(output)) } } else { @@ -3231,21 +5818,21 @@ class FlutterIntegrationCoreApi( } } /** Returns the passed map, to test serialization and deserialization. */ - fun echoNullableMap( - aMapArg: Map?, - callback: (Result?>) -> Unit + fun echoNullableNonNullClassMap( + classMapArg: Map?, + callback: (Result?>) -> Unit ) { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" val channelName = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableMap$separatedMessageChannelSuffix" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullClassMap$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) - channel.send(listOf(aMapArg)) { + channel.send(listOf(classMapArg)) { if (it is List<*>) { if (it.size > 1) { callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) } else { - val output = it[0] as Map? + val output = it[0] as Map? callback(Result.success(output)) } } else { @@ -3273,6 +5860,29 @@ class FlutterIntegrationCoreApi( } } } + /** Returns the passed enum to test serialization and deserialization. */ + fun echoAnotherNullableEnum( + anotherEnumArg: AnotherEnum?, + callback: (Result) -> Unit + ) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAnotherNullableEnum$separatedMessageChannelSuffix" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(anotherEnumArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + val output = it[0] as AnotherEnum? + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } /** * A no-op function taking no arguments and returning no value, to sanity test basic asynchronous * calling. @@ -3333,7 +5943,7 @@ interface HostTrivialApi { companion object { /** The codec used by HostTrivialApi. */ - val codec: MessageCodec by lazy { CoreTestsPigeonCodec } + val codec: MessageCodec by lazy { CoreTestsPigeonCodec() } /** Sets up an instance of `HostTrivialApi` to handle messages through the `binaryMessenger`. */ @JvmOverloads fun setUp( @@ -3379,7 +5989,7 @@ interface HostSmallApi { companion object { /** The codec used by HostSmallApi. */ - val codec: MessageCodec by lazy { CoreTestsPigeonCodec } + val codec: MessageCodec by lazy { CoreTestsPigeonCodec() } /** Sets up an instance of `HostSmallApi` to handle messages through the `binaryMessenger`. */ @JvmOverloads fun setUp( @@ -3448,7 +6058,7 @@ class FlutterSmallApi( ) { companion object { /** The codec used by FlutterSmallApi. */ - val codec: MessageCodec by lazy { CoreTestsPigeonCodec } + val codec: MessageCodec by lazy { CoreTestsPigeonCodec() } } fun echoWrappedList(msgArg: TestMessage, callback: (Result) -> Unit) { diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/ProxyApiTestApiImpls.kt b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/ProxyApiTestApiImpls.kt new file mode 100644 index 000000000000..bfe6e4257e79 --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/ProxyApiTestApiImpls.kt @@ -0,0 +1,699 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package com.example.test_plugin + +import androidx.annotation.RequiresApi +import io.flutter.plugin.common.BinaryMessenger + +class ProxyApiTestClass : ProxyApiSuperClass(), ProxyApiInterface + +open class ProxyApiSuperClass + +interface ProxyApiInterface + +@RequiresApi(25) class ClassWithApiRequirement + +class ProxyApiRegistrar(binaryMessenger: BinaryMessenger) : + ProxyApiTestsPigeonProxyApiRegistrar(binaryMessenger) { + override fun getPigeonApiProxyApiTestClass(): PigeonApiProxyApiTestClass { + return ProxyApiTestClassApi(this) + } + + override fun getPigeonApiProxyApiSuperClass(): PigeonApiProxyApiSuperClass { + return ProxyApiSuperClassApi(this) + } + + override fun getPigeonApiClassWithApiRequirement(): PigeonApiClassWithApiRequirement { + return ClassWithApiRequirementApi(this) + } +} + +class ProxyApiTestClassApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiProxyApiTestClass(pigeonRegistrar) { + + override fun pigeon_defaultConstructor( + aBool: Boolean, + anInt: Long, + aDouble: Double, + aString: String, + aUint8List: ByteArray, + aList: List, + aMap: Map, + anEnum: ProxyApiTestEnum, + aProxyApi: ProxyApiSuperClass, + aNullableBool: Boolean?, + aNullableInt: Long?, + aNullableDouble: Double?, + aNullableString: String?, + aNullableUint8List: ByteArray?, + aNullableList: List?, + aNullableMap: Map?, + aNullableEnum: ProxyApiTestEnum?, + aNullableProxyApi: ProxyApiSuperClass?, + boolParam: Boolean, + intParam: Long, + doubleParam: Double, + stringParam: String, + aUint8ListParam: ByteArray, + listParam: List, + mapParam: Map, + enumParam: ProxyApiTestEnum, + proxyApiParam: ProxyApiSuperClass, + nullableBoolParam: Boolean?, + nullableIntParam: Long?, + nullableDoubleParam: Double?, + nullableStringParam: String?, + nullableUint8ListParam: ByteArray?, + nullableListParam: List?, + nullableMapParam: Map?, + nullableEnumParam: ProxyApiTestEnum?, + nullableProxyApiParam: ProxyApiSuperClass? + ): ProxyApiTestClass { + return ProxyApiTestClass() + } + + override fun attachedField(pigeon_instance: ProxyApiTestClass): ProxyApiSuperClass { + return ProxyApiSuperClass() + } + + override fun staticAttachedField(): ProxyApiSuperClass { + return ProxyApiSuperClass() + } + + override fun aBool(pigeon_instance: ProxyApiTestClass): Boolean { + return true + } + + override fun anInt(pigeon_instance: ProxyApiTestClass): Long { + return 0 + } + + override fun aDouble(pigeon_instance: ProxyApiTestClass): Double { + return 0.0 + } + + override fun aString(pigeon_instance: ProxyApiTestClass): String { + return "" + } + + override fun aUint8List(pigeon_instance: ProxyApiTestClass): ByteArray { + return byteArrayOf() + } + + override fun aList(pigeon_instance: ProxyApiTestClass): List { + return listOf() + } + + override fun aMap(pigeon_instance: ProxyApiTestClass): Map { + return mapOf() + } + + override fun anEnum(pigeon_instance: ProxyApiTestClass): ProxyApiTestEnum { + return ProxyApiTestEnum.ONE + } + + override fun aProxyApi(pigeon_instance: ProxyApiTestClass): ProxyApiSuperClass { + return ProxyApiSuperClass() + } + + override fun aNullableBool(pigeon_instance: ProxyApiTestClass): Boolean? { + return null + } + + override fun aNullableInt(pigeon_instance: ProxyApiTestClass): Long? { + return null + } + + override fun aNullableDouble(pigeon_instance: ProxyApiTestClass): Double? { + return null + } + + override fun aNullableString(pigeon_instance: ProxyApiTestClass): String? { + return null + } + + override fun aNullableUint8List(pigeon_instance: ProxyApiTestClass): ByteArray? { + return null + } + + override fun aNullableList(pigeon_instance: ProxyApiTestClass): List? { + return null + } + + override fun aNullableMap(pigeon_instance: ProxyApiTestClass): Map? { + return null + } + + override fun aNullableEnum(pigeon_instance: ProxyApiTestClass): ProxyApiTestEnum? { + return null + } + + override fun aNullableProxyApi(pigeon_instance: ProxyApiTestClass): ProxyApiSuperClass? { + return null + } + + override fun noop(pigeon_instance: ProxyApiTestClass) {} + + override fun throwError(pigeon_instance: ProxyApiTestClass): Any? { + throw Exception("message") + } + + override fun throwErrorFromVoid(pigeon_instance: ProxyApiTestClass) { + throw Exception("message") + } + + override fun throwFlutterError(pigeon_instance: ProxyApiTestClass): Any? { + throw ProxyApiTestsError("code", "message", "details") + } + + override fun echoInt(pigeon_instance: ProxyApiTestClass, anInt: Long): Long { + return anInt + } + + override fun echoDouble(pigeon_instance: ProxyApiTestClass, aDouble: Double): Double { + return aDouble + } + + override fun echoBool(pigeon_instance: ProxyApiTestClass, aBool: Boolean): Boolean { + return aBool + } + + override fun echoString(pigeon_instance: ProxyApiTestClass, aString: String): String { + return aString + } + + override fun echoUint8List(pigeon_instance: ProxyApiTestClass, aUint8List: ByteArray): ByteArray { + return aUint8List + } + + override fun echoObject(pigeon_instance: ProxyApiTestClass, anObject: Any): Any { + return anObject + } + + override fun echoList(pigeon_instance: ProxyApiTestClass, aList: List): List { + return aList + } + + override fun echoProxyApiList( + pigeon_instance: ProxyApiTestClass, + aList: List + ): List { + return aList + } + + override fun echoMap( + pigeon_instance: ProxyApiTestClass, + aMap: Map + ): Map { + return aMap + } + + override fun echoProxyApiMap( + pigeon_instance: ProxyApiTestClass, + aMap: Map + ): Map { + return aMap + } + + override fun echoEnum( + pigeon_instance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum + ): ProxyApiTestEnum { + return anEnum + } + + override fun echoProxyApi( + pigeon_instance: ProxyApiTestClass, + aProxyApi: ProxyApiSuperClass + ): ProxyApiSuperClass { + return aProxyApi + } + + override fun echoNullableInt(pigeon_instance: ProxyApiTestClass, aNullableInt: Long?): Long? { + return aNullableInt + } + + override fun echoNullableDouble( + pigeon_instance: ProxyApiTestClass, + aNullableDouble: Double? + ): Double? { + return aNullableDouble + } + + override fun echoNullableBool( + pigeon_instance: ProxyApiTestClass, + aNullableBool: Boolean? + ): Boolean? { + return aNullableBool + } + + override fun echoNullableString( + pigeon_instance: ProxyApiTestClass, + aNullableString: String? + ): String? { + return aNullableString + } + + override fun echoNullableUint8List( + pigeon_instance: ProxyApiTestClass, + aNullableUint8List: ByteArray? + ): ByteArray? { + return aNullableUint8List + } + + override fun echoNullableObject(pigeon_instance: ProxyApiTestClass, aNullableObject: Any?): Any? { + return aNullableObject + } + + override fun echoNullableList( + pigeon_instance: ProxyApiTestClass, + aNullableList: List? + ): List? { + return aNullableList + } + + override fun echoNullableMap( + pigeon_instance: ProxyApiTestClass, + aNullableMap: Map? + ): Map? { + return aNullableMap + } + + override fun echoNullableEnum( + pigeon_instance: ProxyApiTestClass, + aNullableEnum: ProxyApiTestEnum? + ): ProxyApiTestEnum? { + return aNullableEnum + } + + override fun echoNullableProxyApi( + pigeon_instance: ProxyApiTestClass, + aNullableProxyApi: ProxyApiSuperClass? + ): ProxyApiSuperClass? { + return aNullableProxyApi + } + + override fun noopAsync(pigeon_instance: ProxyApiTestClass, callback: (Result) -> Unit) { + callback(Result.success(Unit)) + } + + override fun echoAsyncInt( + pigeon_instance: ProxyApiTestClass, + anInt: Long, + callback: (Result) -> Unit + ) { + callback(Result.success(anInt)) + } + + override fun echoAsyncDouble( + pigeon_instance: ProxyApiTestClass, + aDouble: Double, + callback: (Result) -> Unit + ) { + callback(Result.success(aDouble)) + } + + override fun echoAsyncBool( + pigeon_instance: ProxyApiTestClass, + aBool: Boolean, + callback: (Result) -> Unit + ) { + callback(Result.success(aBool)) + } + + override fun echoAsyncString( + pigeon_instance: ProxyApiTestClass, + aString: String, + callback: (Result) -> Unit + ) { + callback(Result.success(aString)) + } + + override fun echoAsyncUint8List( + pigeon_instance: ProxyApiTestClass, + aUint8List: ByteArray, + callback: (Result) -> Unit + ) { + callback(Result.success(aUint8List)) + } + + override fun echoAsyncObject( + pigeon_instance: ProxyApiTestClass, + anObject: Any, + callback: (Result) -> Unit + ) { + callback(Result.success(anObject)) + } + + override fun echoAsyncList( + pigeon_instance: ProxyApiTestClass, + aList: List, + callback: (Result>) -> Unit + ) { + callback(Result.success(aList)) + } + + override fun echoAsyncMap( + pigeon_instance: ProxyApiTestClass, + aMap: Map, + callback: (Result>) -> Unit + ) { + callback(Result.success(aMap)) + } + + override fun echoAsyncEnum( + pigeon_instance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum, + callback: (Result) -> Unit + ) { + callback(Result.success(anEnum)) + } + + override fun throwAsyncError( + pigeon_instance: ProxyApiTestClass, + callback: (Result) -> Unit + ) { + callback(Result.failure(Exception("message"))) + } + + override fun throwAsyncErrorFromVoid( + pigeon_instance: ProxyApiTestClass, + callback: (Result) -> Unit + ) { + callback(Result.failure(Exception("message"))) + } + + override fun throwAsyncFlutterError( + pigeon_instance: ProxyApiTestClass, + callback: (Result) -> Unit + ) { + callback(Result.failure(ProxyApiTestsError("code", "message", "details"))) + } + + override fun echoAsyncNullableInt( + pigeon_instance: ProxyApiTestClass, + anInt: Long?, + callback: (Result) -> Unit + ) { + callback(Result.success(anInt)) + } + + override fun echoAsyncNullableDouble( + pigeon_instance: ProxyApiTestClass, + aDouble: Double?, + callback: (Result) -> Unit + ) { + callback(Result.success(aDouble)) + } + + override fun echoAsyncNullableBool( + pigeon_instance: ProxyApiTestClass, + aBool: Boolean?, + callback: (Result) -> Unit + ) { + callback(Result.success(aBool)) + } + + override fun echoAsyncNullableString( + pigeon_instance: ProxyApiTestClass, + aString: String?, + callback: (Result) -> Unit + ) { + callback(Result.success(aString)) + } + + override fun echoAsyncNullableUint8List( + pigeon_instance: ProxyApiTestClass, + aUint8List: ByteArray?, + callback: (Result) -> Unit + ) { + callback(Result.success(aUint8List)) + } + + override fun echoAsyncNullableObject( + pigeon_instance: ProxyApiTestClass, + anObject: Any?, + callback: (Result) -> Unit + ) { + callback(Result.success(anObject)) + } + + override fun echoAsyncNullableList( + pigeon_instance: ProxyApiTestClass, + aList: List?, + callback: (Result?>) -> Unit + ) { + callback(Result.success(aList)) + } + + override fun echoAsyncNullableMap( + pigeon_instance: ProxyApiTestClass, + aMap: Map?, + callback: (Result?>) -> Unit + ) { + callback(Result.success(aMap)) + } + + override fun echoAsyncNullableEnum( + pigeon_instance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum?, + callback: (Result) -> Unit + ) { + callback(Result.success(anEnum)) + } + + override fun staticNoop() {} + + override fun echoStaticString(aString: String): String { + return aString + } + + override fun staticAsyncNoop(callback: (Result) -> Unit) { + callback(Result.success(Unit)) + } + + override fun callFlutterNoop( + pigeon_instance: ProxyApiTestClass, + callback: (Result) -> Unit + ) { + flutterNoop(pigeon_instance, callback) + } + + override fun callFlutterThrowError( + pigeon_instance: ProxyApiTestClass, + callback: (Result) -> Unit + ) { + flutterThrowError(pigeon_instance) { result -> + val exception = result.exceptionOrNull() + callback(Result.failure(exception!!)) + } + } + + override fun callFlutterThrowErrorFromVoid( + pigeon_instance: ProxyApiTestClass, + callback: (Result) -> Unit + ) { + flutterThrowErrorFromVoid(pigeon_instance) { result -> + val exception = result.exceptionOrNull() + callback(Result.failure(exception!!)) + } + } + + override fun callFlutterEchoBool( + pigeon_instance: ProxyApiTestClass, + aBool: Boolean, + callback: (Result) -> Unit + ) { + flutterEchoBool(pigeon_instance, aBool, callback) + } + + override fun callFlutterEchoInt( + pigeon_instance: ProxyApiTestClass, + anInt: Long, + callback: (Result) -> Unit + ) { + flutterEchoInt(pigeon_instance, anInt, callback) + } + + override fun callFlutterEchoDouble( + pigeon_instance: ProxyApiTestClass, + aDouble: Double, + callback: (Result) -> Unit + ) { + flutterEchoDouble(pigeon_instance, aDouble, callback) + } + + override fun callFlutterEchoString( + pigeon_instance: ProxyApiTestClass, + aString: String, + callback: (Result) -> Unit + ) { + flutterEchoString(pigeon_instance, aString, callback) + } + + override fun callFlutterEchoUint8List( + pigeon_instance: ProxyApiTestClass, + aUint8List: ByteArray, + callback: (Result) -> Unit + ) { + flutterEchoUint8List(pigeon_instance, aUint8List, callback) + } + + override fun callFlutterEchoList( + pigeon_instance: ProxyApiTestClass, + aList: List, + callback: (Result>) -> Unit + ) { + flutterEchoList(pigeon_instance, aList, callback) + } + + override fun callFlutterEchoProxyApiList( + pigeon_instance: ProxyApiTestClass, + aList: List, + callback: (Result>) -> Unit + ) { + flutterEchoProxyApiList(pigeon_instance, aList, callback) + } + + override fun callFlutterEchoMap( + pigeon_instance: ProxyApiTestClass, + aMap: Map, + callback: (Result>) -> Unit + ) { + flutterEchoMap(pigeon_instance, aMap, callback) + } + + override fun callFlutterEchoProxyApiMap( + pigeon_instance: ProxyApiTestClass, + aMap: Map, + callback: (Result>) -> Unit + ) { + flutterEchoProxyApiMap(pigeon_instance, aMap, callback) + } + + override fun callFlutterEchoEnum( + pigeon_instance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum, + callback: (Result) -> Unit + ) { + flutterEchoEnum(pigeon_instance, anEnum, callback) + } + + override fun callFlutterEchoProxyApi( + pigeon_instance: ProxyApiTestClass, + aProxyApi: ProxyApiSuperClass, + callback: (Result) -> Unit + ) { + flutterEchoProxyApi(pigeon_instance, aProxyApi, callback) + } + + override fun callFlutterEchoNullableBool( + pigeon_instance: ProxyApiTestClass, + aBool: Boolean?, + callback: (Result) -> Unit + ) { + flutterEchoNullableBool(pigeon_instance, aBool, callback) + } + + override fun callFlutterEchoNullableInt( + pigeon_instance: ProxyApiTestClass, + anInt: Long?, + callback: (Result) -> Unit + ) { + flutterEchoNullableInt(pigeon_instance, anInt, callback) + } + + override fun callFlutterEchoNullableDouble( + pigeon_instance: ProxyApiTestClass, + aDouble: Double?, + callback: (Result) -> Unit + ) { + flutterEchoNullableDouble(pigeon_instance, aDouble, callback) + } + + override fun callFlutterEchoNullableString( + pigeon_instance: ProxyApiTestClass, + aString: String?, + callback: (Result) -> Unit + ) { + flutterEchoNullableString(pigeon_instance, aString, callback) + } + + override fun callFlutterEchoNullableUint8List( + pigeon_instance: ProxyApiTestClass, + aUint8List: ByteArray?, + callback: (Result) -> Unit + ) { + flutterEchoNullableUint8List(pigeon_instance, aUint8List, callback) + } + + override fun callFlutterEchoNullableList( + pigeon_instance: ProxyApiTestClass, + aList: List?, + callback: (Result?>) -> Unit + ) { + flutterEchoNullableList(pigeon_instance, aList, callback) + } + + override fun callFlutterEchoNullableMap( + pigeon_instance: ProxyApiTestClass, + aMap: Map?, + callback: (Result?>) -> Unit + ) { + flutterEchoNullableMap(pigeon_instance, aMap, callback) + } + + override fun callFlutterEchoNullableEnum( + pigeon_instance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum?, + callback: (Result) -> Unit + ) { + flutterEchoNullableEnum(pigeon_instance, anEnum, callback) + } + + override fun callFlutterEchoNullableProxyApi( + pigeon_instance: ProxyApiTestClass, + aProxyApi: ProxyApiSuperClass?, + callback: (Result) -> Unit + ) { + flutterEchoNullableProxyApi(pigeon_instance, aProxyApi, callback) + } + + override fun callFlutterNoopAsync( + pigeon_instance: ProxyApiTestClass, + callback: (Result) -> Unit + ) { + flutterNoopAsync(pigeon_instance, callback) + } + + override fun callFlutterEchoAsyncString( + pigeon_instance: ProxyApiTestClass, + aString: String, + callback: (Result) -> Unit + ) { + flutterEchoAsyncString(pigeon_instance, aString, callback) + } +} + +class ProxyApiSuperClassApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiProxyApiSuperClass(pigeonRegistrar) { + override fun pigeon_defaultConstructor(): ProxyApiSuperClass { + return ProxyApiSuperClass() + } + + override fun aSuperMethod(pigeon_instance: ProxyApiSuperClass) {} +} + +class ClassWithApiRequirementApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiClassWithApiRequirement(pigeonRegistrar) { + @RequiresApi(25) + override fun pigeon_defaultConstructor(): ClassWithApiRequirement { + return ClassWithApiRequirement() + } + + override fun aMethod(pigeon_instance: ClassWithApiRequirement) { + // Do nothing + } +} diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/ProxyApiTests.gen.kt b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/ProxyApiTests.gen.kt new file mode 100644 index 000000000000..184a5b00f599 --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/ProxyApiTests.gen.kt @@ -0,0 +1,4291 @@ +// 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, do not edit directly. +// See also: https://pub.dev/packages/pigeon +@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass") + +package com.example.test_plugin + +import android.util.Log +import io.flutter.plugin.common.BasicMessageChannel +import io.flutter.plugin.common.BinaryMessenger +import io.flutter.plugin.common.MessageCodec +import io.flutter.plugin.common.StandardMessageCodec +import java.io.ByteArrayOutputStream +import java.nio.ByteBuffer + +private fun wrapResult(result: Any?): List { + return listOf(result) +} + +private fun wrapError(exception: Throwable): List { + return if (exception is ProxyApiTestsError) { + listOf(exception.code, exception.message, exception.details) + } else { + listOf( + exception.javaClass.simpleName, + exception.toString(), + "Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception)) + } +} + +private fun createConnectionError(channelName: String): ProxyApiTestsError { + return ProxyApiTestsError( + "channel-error", "Unable to establish connection on channel: '$channelName'.", "") +} + +/** + * Error class for passing custom error details to Flutter via a thrown PlatformException. + * + * @property code The error code. + * @property message The error message. + * @property details The error details. Must be a datatype supported by the api codec. + */ +class ProxyApiTestsError( + val code: String, + override val message: String? = null, + val details: Any? = null +) : Throwable() +/** + * Maintains instances used to communicate with the corresponding objects in Dart. + * + * Objects stored in this container are represented by an object in Dart that is also stored in an + * InstanceManager with the same identifier. + * + * When an instance is added with an identifier, either can be used to retrieve the other. + * + * Added instances are added as a weak reference and a strong reference. When the strong reference + * is removed with [remove] and the weak reference is deallocated, the + * `finalizationListener.onFinalize` is called with the instance's identifier. However, if the + * strong reference is removed and then the identifier is retrieved with the intention to pass the + * identifier to Dart (e.g. calling [getIdentifierForStrongReference]), the strong reference to the + * instance is recreated. The strong reference will then need to be removed manually again. + */ +@Suppress("UNCHECKED_CAST", "MemberVisibilityCanBePrivate") +class ProxyApiTestsPigeonInstanceManager( + private val finalizationListener: PigeonFinalizationListener +) { + /** Interface for listening when a weak reference of an instance is removed from the manager. */ + interface PigeonFinalizationListener { + fun onFinalize(identifier: Long) + } + + private val identifiers = java.util.WeakHashMap() + private val weakInstances = HashMap>() + private val strongInstances = HashMap() + private val referenceQueue = java.lang.ref.ReferenceQueue() + private val weakReferencesToIdentifiers = HashMap, Long>() + private val handler = android.os.Handler(android.os.Looper.getMainLooper()) + private var nextIdentifier: Long = minHostCreatedIdentifier + private var hasFinalizationListenerStopped = false + + /** + * Modifies the time interval used to define how often this instance removes garbage collected + * weak references to native Android objects that this instance was managing. + */ + var clearFinalizedWeakReferencesInterval: Long = 3000 + set(value) { + handler.removeCallbacks { this.releaseAllFinalizedInstances() } + field = value + releaseAllFinalizedInstances() + } + + init { + handler.postDelayed({ releaseAllFinalizedInstances() }, clearFinalizedWeakReferencesInterval) + } + + companion object { + // Identifiers are locked to a specific range to avoid collisions with objects + // created simultaneously from Dart. + // Host uses identifiers >= 2^16 and Dart is expected to use values n where, + // 0 <= n < 2^16. + private const val minHostCreatedIdentifier: Long = 65536 + private const val tag = "PigeonInstanceManager" + + /** + * Instantiate a new manager with a listener for garbage collected weak references. + * + * When the manager is no longer needed, [stopFinalizationListener] must be called. + */ + fun create( + finalizationListener: PigeonFinalizationListener + ): ProxyApiTestsPigeonInstanceManager { + return ProxyApiTestsPigeonInstanceManager(finalizationListener) + } + } + + /** + * Removes `identifier` and return its associated strongly referenced instance, if present, from + * the manager. + */ + fun remove(identifier: Long): T? { + logWarningIfFinalizationListenerHasStopped() + return strongInstances.remove(identifier) as T? + } + + /** + * Retrieves the identifier paired with an instance, if present, otherwise `null`. + * + * If the manager contains a strong reference to `instance`, it will return the identifier + * associated with `instance`. If the manager contains only a weak reference to `instance`, a new + * strong reference to `instance` will be added and will need to be removed again with [remove]. + * + * If this method returns a nonnull identifier, this method also expects the Dart + * `ProxyApiTestsPigeonInstanceManager` to have, or recreate, a weak reference to the Dart + * instance the identifier is associated with. + */ + fun getIdentifierForStrongReference(instance: Any?): Long? { + logWarningIfFinalizationListenerHasStopped() + val identifier = identifiers[instance] + if (identifier != null) { + strongInstances[identifier] = instance!! + } + return identifier + } + + /** + * Adds a new instance that was instantiated from Dart. + * + * The same instance can be added multiple times, but each identifier must be unique. This allows + * two objects that are equivalent (e.g. the `equals` method returns true and their hashcodes are + * equal) to both be added. + * + * [identifier] must be >= 0 and unique. + */ + fun addDartCreatedInstance(instance: Any, identifier: Long) { + logWarningIfFinalizationListenerHasStopped() + addInstance(instance, identifier) + } + + /** + * Adds a new unique instance that was instantiated from the host platform. + * + * [identifier] must be >= 0 and unique. + */ + fun addHostCreatedInstance(instance: Any): Long { + logWarningIfFinalizationListenerHasStopped() + require(!containsInstance(instance)) { + "Instance of ${instance.javaClass} has already been added." + } + val identifier = nextIdentifier++ + addInstance(instance, identifier) + return identifier + } + + /** Retrieves the instance associated with identifier, if present, otherwise `null`. */ + fun getInstance(identifier: Long): T? { + logWarningIfFinalizationListenerHasStopped() + val instance = weakInstances[identifier] as java.lang.ref.WeakReference? + return instance?.get() + } + + /** Returns whether this manager contains the given `instance`. */ + fun containsInstance(instance: Any?): Boolean { + logWarningIfFinalizationListenerHasStopped() + return identifiers.containsKey(instance) + } + + /** + * Stops the periodic run of the [PigeonFinalizationListener] for instances that have been garbage + * collected. + * + * The InstanceManager can continue to be used, but the [PigeonFinalizationListener] will no + * longer be called and methods will log a warning. + */ + fun stopFinalizationListener() { + handler.removeCallbacks { this.releaseAllFinalizedInstances() } + hasFinalizationListenerStopped = true + } + + /** + * Removes all of the instances from this manager. + * + * The manager will be empty after this call returns. + */ + fun clear() { + identifiers.clear() + weakInstances.clear() + strongInstances.clear() + weakReferencesToIdentifiers.clear() + } + + /** + * Whether the [PigeonFinalizationListener] is still being called for instances that are garbage + * collected. + * + * See [stopFinalizationListener]. + */ + fun hasFinalizationListenerStopped(): Boolean { + return hasFinalizationListenerStopped + } + + private fun releaseAllFinalizedInstances() { + if (hasFinalizationListenerStopped()) { + return + } + var reference: java.lang.ref.WeakReference? + while ((referenceQueue.poll() as java.lang.ref.WeakReference?).also { reference = it } != + null) { + val identifier = weakReferencesToIdentifiers.remove(reference) + if (identifier != null) { + weakInstances.remove(identifier) + strongInstances.remove(identifier) + finalizationListener.onFinalize(identifier) + } + } + handler.postDelayed({ releaseAllFinalizedInstances() }, clearFinalizedWeakReferencesInterval) + } + + private fun addInstance(instance: Any, identifier: Long) { + require(identifier >= 0) { "Identifier must be >= 0: $identifier" } + require(!weakInstances.containsKey(identifier)) { + "Identifier has already been added: $identifier" + } + val weakReference = java.lang.ref.WeakReference(instance, referenceQueue) + identifiers[instance] = identifier + weakInstances[identifier] = weakReference + weakReferencesToIdentifiers[weakReference] = identifier + strongInstances[identifier] = instance + } + + private fun logWarningIfFinalizationListenerHasStopped() { + if (hasFinalizationListenerStopped()) { + Log.w( + tag, + "The manager was used after calls to the PigeonFinalizationListener has been stopped.") + } + } +} + +/** Generated API for managing the Dart and native `InstanceManager`s. */ +private class ProxyApiTestsPigeonInstanceManagerApi(val binaryMessenger: BinaryMessenger) { + companion object { + /** The codec used by ProxyApiTestsPigeonInstanceManagerApi. */ + val codec: MessageCodec by lazy { ProxyApiTestsPigeonCodec() } + + /** + * Sets up an instance of `ProxyApiTestsPigeonInstanceManagerApi` to handle messages from the + * `binaryMessenger`. + */ + fun setUpMessageHandlers( + binaryMessenger: BinaryMessenger, + instanceManager: ProxyApiTestsPigeonInstanceManager? + ) { + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.PigeonInternalInstanceManager.removeStrongReference", + codec) + if (instanceManager != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val identifierArg = args[0] as Long + val wrapped: List = + try { + instanceManager.remove(identifierArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.PigeonInternalInstanceManager.clear", + codec) + if (instanceManager != null) { + channel.setMessageHandler { _, reply -> + val wrapped: List = + try { + instanceManager.clear() + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } + } + + fun removeStrongReference(identifierArg: Long, callback: (Result) -> Unit) { + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.PigeonInternalInstanceManager.removeStrongReference" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(identifierArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** + * Provides implementations for each ProxyApi implementation and provides access to resources needed + * by any implementation. + */ +abstract class ProxyApiTestsPigeonProxyApiRegistrar(val binaryMessenger: BinaryMessenger) { + /** Whether APIs should ignore calling to Dart. */ + public var ignoreCallsToDart = false + val instanceManager: ProxyApiTestsPigeonInstanceManager + private var _codec: MessageCodec? = null + val codec: MessageCodec + get() { + if (_codec == null) { + _codec = ProxyApiTestsPigeonProxyApiBaseCodec(this) + } + return _codec!! + } + + init { + val api = ProxyApiTestsPigeonInstanceManagerApi(binaryMessenger) + instanceManager = + ProxyApiTestsPigeonInstanceManager.create( + object : ProxyApiTestsPigeonInstanceManager.PigeonFinalizationListener { + override fun onFinalize(identifier: Long) { + api.removeStrongReference(identifier) { + if (it.isFailure) { + Log.e( + "PigeonProxyApiRegistrar", + "Failed to remove Dart strong reference with identifier: $identifier") + } + } + } + }) + } + /** + * An implementation of [PigeonApiProxyApiTestClass] used to add a new Dart instance of + * `ProxyApiTestClass` to the Dart `InstanceManager`. + */ + abstract fun getPigeonApiProxyApiTestClass(): PigeonApiProxyApiTestClass + + /** + * An implementation of [PigeonApiProxyApiSuperClass] used to add a new Dart instance of + * `ProxyApiSuperClass` to the Dart `InstanceManager`. + */ + abstract fun getPigeonApiProxyApiSuperClass(): PigeonApiProxyApiSuperClass + + /** + * An implementation of [PigeonApiProxyApiInterface] used to add a new Dart instance of + * `ProxyApiInterface` to the Dart `InstanceManager`. + */ + open fun getPigeonApiProxyApiInterface(): PigeonApiProxyApiInterface { + return PigeonApiProxyApiInterface(this) + } + + /** + * An implementation of [PigeonApiClassWithApiRequirement] used to add a new Dart instance of + * `ClassWithApiRequirement` to the Dart `InstanceManager`. + */ + abstract fun getPigeonApiClassWithApiRequirement(): PigeonApiClassWithApiRequirement + + fun setUp() { + ProxyApiTestsPigeonInstanceManagerApi.setUpMessageHandlers(binaryMessenger, instanceManager) + PigeonApiProxyApiTestClass.setUpMessageHandlers( + binaryMessenger, getPigeonApiProxyApiTestClass()) + PigeonApiProxyApiSuperClass.setUpMessageHandlers( + binaryMessenger, getPigeonApiProxyApiSuperClass()) + PigeonApiClassWithApiRequirement.setUpMessageHandlers( + binaryMessenger, getPigeonApiClassWithApiRequirement()) + } + + fun tearDown() { + ProxyApiTestsPigeonInstanceManagerApi.setUpMessageHandlers(binaryMessenger, null) + PigeonApiProxyApiTestClass.setUpMessageHandlers(binaryMessenger, null) + PigeonApiProxyApiSuperClass.setUpMessageHandlers(binaryMessenger, null) + PigeonApiClassWithApiRequirement.setUpMessageHandlers(binaryMessenger, null) + } +} + +private class ProxyApiTestsPigeonProxyApiBaseCodec( + val registrar: ProxyApiTestsPigeonProxyApiRegistrar +) : ProxyApiTestsPigeonCodec() { + override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? { + return when (type) { + 128.toByte() -> { + return registrar.instanceManager.getInstance(readValue(buffer) as Long) + } + else -> super.readValueOfType(type, buffer) + } + } + + override fun writeValue(stream: ByteArrayOutputStream, value: Any?) { + if (value is Boolean || + value is ByteArray || + value is Double || + value is DoubleArray || + value is FloatArray || + value is Int || + value is IntArray || + value is List<*> || + value is Long || + value is LongArray || + value is Map<*, *> || + value is String || + value is ProxyApiTestEnum || + value == null) { + super.writeValue(stream, value) + return + } + + if (value is ProxyApiTestClass) { + registrar.getPigeonApiProxyApiTestClass().pigeon_newInstance(value) {} + } else if (value is com.example.test_plugin.ProxyApiSuperClass) { + registrar.getPigeonApiProxyApiSuperClass().pigeon_newInstance(value) {} + } else if (value is ProxyApiInterface) { + registrar.getPigeonApiProxyApiInterface().pigeon_newInstance(value) {} + } else if (android.os.Build.VERSION.SDK_INT >= 25 && value is ClassWithApiRequirement) { + registrar.getPigeonApiClassWithApiRequirement().pigeon_newInstance(value) {} + } + + when { + registrar.instanceManager.containsInstance(value) -> { + stream.write(128) + writeValue(stream, registrar.instanceManager.getIdentifierForStrongReference(value)) + } + else -> + throw IllegalArgumentException( + "Unsupported value: '$value' of type '${value.javaClass.name}'") + } + } +} + +enum class ProxyApiTestEnum(val raw: Int) { + ONE(0), + TWO(1), + THREE(2); + + companion object { + fun ofRaw(raw: Int): ProxyApiTestEnum? { + return values().firstOrNull { it.raw == raw } + } + } +} + +private open class ProxyApiTestsPigeonCodec : StandardMessageCodec() { + override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? { + return when (type) { + 129.toByte() -> { + return (readValue(buffer) as Long?)?.let { ProxyApiTestEnum.ofRaw(it.toInt()) } + } + else -> super.readValueOfType(type, buffer) + } + } + + override fun writeValue(stream: ByteArrayOutputStream, value: Any?) { + when (value) { + is ProxyApiTestEnum -> { + stream.write(129) + writeValue(stream, value.raw) + } + else -> super.writeValue(stream, value) + } + } +} + +/** + * The core ProxyApi test class that each supported host language must implement in platform_tests + * integration tests. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiProxyApiTestClass( + open val pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar +) { + abstract fun pigeon_defaultConstructor( + aBool: Boolean, + anInt: Long, + aDouble: Double, + aString: String, + aUint8List: ByteArray, + aList: List, + aMap: Map, + anEnum: ProxyApiTestEnum, + aProxyApi: com.example.test_plugin.ProxyApiSuperClass, + aNullableBool: Boolean?, + aNullableInt: Long?, + aNullableDouble: Double?, + aNullableString: String?, + aNullableUint8List: ByteArray?, + aNullableList: List?, + aNullableMap: Map?, + aNullableEnum: ProxyApiTestEnum?, + aNullableProxyApi: com.example.test_plugin.ProxyApiSuperClass?, + boolParam: Boolean, + intParam: Long, + doubleParam: Double, + stringParam: String, + aUint8ListParam: ByteArray, + listParam: List, + mapParam: Map, + enumParam: ProxyApiTestEnum, + proxyApiParam: com.example.test_plugin.ProxyApiSuperClass, + nullableBoolParam: Boolean?, + nullableIntParam: Long?, + nullableDoubleParam: Double?, + nullableStringParam: String?, + nullableUint8ListParam: ByteArray?, + nullableListParam: List?, + nullableMapParam: Map?, + nullableEnumParam: ProxyApiTestEnum?, + nullableProxyApiParam: com.example.test_plugin.ProxyApiSuperClass? + ): ProxyApiTestClass + + abstract fun attachedField( + pigeon_instance: ProxyApiTestClass + ): com.example.test_plugin.ProxyApiSuperClass + + abstract fun staticAttachedField(): com.example.test_plugin.ProxyApiSuperClass + + abstract fun aBool(pigeon_instance: ProxyApiTestClass): Boolean + + abstract fun anInt(pigeon_instance: ProxyApiTestClass): Long + + abstract fun aDouble(pigeon_instance: ProxyApiTestClass): Double + + abstract fun aString(pigeon_instance: ProxyApiTestClass): String + + abstract fun aUint8List(pigeon_instance: ProxyApiTestClass): ByteArray + + abstract fun aList(pigeon_instance: ProxyApiTestClass): List + + abstract fun aMap(pigeon_instance: ProxyApiTestClass): Map + + abstract fun anEnum(pigeon_instance: ProxyApiTestClass): ProxyApiTestEnum + + abstract fun aProxyApi( + pigeon_instance: ProxyApiTestClass + ): com.example.test_plugin.ProxyApiSuperClass + + abstract fun aNullableBool(pigeon_instance: ProxyApiTestClass): Boolean? + + abstract fun aNullableInt(pigeon_instance: ProxyApiTestClass): Long? + + abstract fun aNullableDouble(pigeon_instance: ProxyApiTestClass): Double? + + abstract fun aNullableString(pigeon_instance: ProxyApiTestClass): String? + + abstract fun aNullableUint8List(pigeon_instance: ProxyApiTestClass): ByteArray? + + abstract fun aNullableList(pigeon_instance: ProxyApiTestClass): List? + + abstract fun aNullableMap(pigeon_instance: ProxyApiTestClass): Map? + + abstract fun aNullableEnum(pigeon_instance: ProxyApiTestClass): ProxyApiTestEnum? + + abstract fun aNullableProxyApi( + pigeon_instance: ProxyApiTestClass + ): com.example.test_plugin.ProxyApiSuperClass? + + /** A no-op function taking no arguments and returning no value, to sanity test basic calling. */ + abstract fun noop(pigeon_instance: ProxyApiTestClass) + + /** Returns an error, to test error handling. */ + abstract fun throwError(pigeon_instance: ProxyApiTestClass): Any? + + /** Returns an error from a void function, to test error handling. */ + abstract fun throwErrorFromVoid(pigeon_instance: ProxyApiTestClass) + + /** Returns a Flutter error, to test error handling. */ + abstract fun throwFlutterError(pigeon_instance: ProxyApiTestClass): Any? + + /** Returns passed in int. */ + abstract fun echoInt(pigeon_instance: ProxyApiTestClass, anInt: Long): Long + + /** Returns passed in double. */ + abstract fun echoDouble(pigeon_instance: ProxyApiTestClass, aDouble: Double): Double + + /** Returns the passed in boolean. */ + abstract fun echoBool(pigeon_instance: ProxyApiTestClass, aBool: Boolean): Boolean + + /** Returns the passed in string. */ + abstract fun echoString(pigeon_instance: ProxyApiTestClass, aString: String): String + + /** Returns the passed in Uint8List. */ + abstract fun echoUint8List(pigeon_instance: ProxyApiTestClass, aUint8List: ByteArray): ByteArray + + /** Returns the passed in generic Object. */ + abstract fun echoObject(pigeon_instance: ProxyApiTestClass, anObject: Any): Any + + /** Returns the passed list, to test serialization and deserialization. */ + abstract fun echoList(pigeon_instance: ProxyApiTestClass, aList: List): List + + /** Returns the passed list with ProxyApis, to test serialization and deserialization. */ + abstract fun echoProxyApiList( + pigeon_instance: ProxyApiTestClass, + aList: List + ): List + + /** Returns the passed map, to test serialization and deserialization. */ + abstract fun echoMap( + pigeon_instance: ProxyApiTestClass, + aMap: Map + ): Map + + /** Returns the passed map with ProxyApis, to test serialization and deserialization. */ + abstract fun echoProxyApiMap( + pigeon_instance: ProxyApiTestClass, + aMap: Map + ): Map + + /** Returns the passed enum to test serialization and deserialization. */ + abstract fun echoEnum( + pigeon_instance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum + ): ProxyApiTestEnum + + /** Returns the passed ProxyApi to test serialization and deserialization. */ + abstract fun echoProxyApi( + pigeon_instance: ProxyApiTestClass, + aProxyApi: com.example.test_plugin.ProxyApiSuperClass + ): com.example.test_plugin.ProxyApiSuperClass + + /** Returns passed in int. */ + abstract fun echoNullableInt(pigeon_instance: ProxyApiTestClass, aNullableInt: Long?): Long? + + /** Returns passed in double. */ + abstract fun echoNullableDouble( + pigeon_instance: ProxyApiTestClass, + aNullableDouble: Double? + ): Double? + + /** Returns the passed in boolean. */ + abstract fun echoNullableBool( + pigeon_instance: ProxyApiTestClass, + aNullableBool: Boolean? + ): Boolean? + + /** Returns the passed in string. */ + abstract fun echoNullableString( + pigeon_instance: ProxyApiTestClass, + aNullableString: String? + ): String? + + /** Returns the passed in Uint8List. */ + abstract fun echoNullableUint8List( + pigeon_instance: ProxyApiTestClass, + aNullableUint8List: ByteArray? + ): ByteArray? + + /** Returns the passed in generic Object. */ + abstract fun echoNullableObject(pigeon_instance: ProxyApiTestClass, aNullableObject: Any?): Any? + + /** Returns the passed list, to test serialization and deserialization. */ + abstract fun echoNullableList( + pigeon_instance: ProxyApiTestClass, + aNullableList: List? + ): List? + + /** Returns the passed map, to test serialization and deserialization. */ + abstract fun echoNullableMap( + pigeon_instance: ProxyApiTestClass, + aNullableMap: Map? + ): Map? + + abstract fun echoNullableEnum( + pigeon_instance: ProxyApiTestClass, + aNullableEnum: ProxyApiTestEnum? + ): ProxyApiTestEnum? + + /** Returns the passed ProxyApi to test serialization and deserialization. */ + abstract fun echoNullableProxyApi( + pigeon_instance: ProxyApiTestClass, + aNullableProxyApi: com.example.test_plugin.ProxyApiSuperClass? + ): com.example.test_plugin.ProxyApiSuperClass? + + /** + * A no-op function taking no arguments and returning no value, to sanity test basic asynchronous + * calling. + */ + abstract fun noopAsync(pigeon_instance: ProxyApiTestClass, callback: (Result) -> Unit) + + /** Returns passed in int asynchronously. */ + abstract fun echoAsyncInt( + pigeon_instance: ProxyApiTestClass, + anInt: Long, + callback: (Result) -> Unit + ) + + /** Returns passed in double asynchronously. */ + abstract fun echoAsyncDouble( + pigeon_instance: ProxyApiTestClass, + aDouble: Double, + callback: (Result) -> Unit + ) + + /** Returns the passed in boolean asynchronously. */ + abstract fun echoAsyncBool( + pigeon_instance: ProxyApiTestClass, + aBool: Boolean, + callback: (Result) -> Unit + ) + + /** Returns the passed string asynchronously. */ + abstract fun echoAsyncString( + pigeon_instance: ProxyApiTestClass, + aString: String, + callback: (Result) -> Unit + ) + + /** Returns the passed in Uint8List asynchronously. */ + abstract fun echoAsyncUint8List( + pigeon_instance: ProxyApiTestClass, + aUint8List: ByteArray, + callback: (Result) -> Unit + ) + + /** Returns the passed in generic Object asynchronously. */ + abstract fun echoAsyncObject( + pigeon_instance: ProxyApiTestClass, + anObject: Any, + callback: (Result) -> Unit + ) + + /** Returns the passed list, to test asynchronous serialization and deserialization. */ + abstract fun echoAsyncList( + pigeon_instance: ProxyApiTestClass, + aList: List, + callback: (Result>) -> Unit + ) + + /** Returns the passed map, to test asynchronous serialization and deserialization. */ + abstract fun echoAsyncMap( + pigeon_instance: ProxyApiTestClass, + aMap: Map, + callback: (Result>) -> Unit + ) + + /** Returns the passed enum, to test asynchronous serialization and deserialization. */ + abstract fun echoAsyncEnum( + pigeon_instance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum, + callback: (Result) -> Unit + ) + + /** Responds with an error from an async function returning a value. */ + abstract fun throwAsyncError(pigeon_instance: ProxyApiTestClass, callback: (Result) -> Unit) + + /** Responds with an error from an async void function. */ + abstract fun throwAsyncErrorFromVoid( + pigeon_instance: ProxyApiTestClass, + callback: (Result) -> Unit + ) + + /** Responds with a Flutter error from an async function returning a value. */ + abstract fun throwAsyncFlutterError( + pigeon_instance: ProxyApiTestClass, + callback: (Result) -> Unit + ) + + /** Returns passed in int asynchronously. */ + abstract fun echoAsyncNullableInt( + pigeon_instance: ProxyApiTestClass, + anInt: Long?, + callback: (Result) -> Unit + ) + + /** Returns passed in double asynchronously. */ + abstract fun echoAsyncNullableDouble( + pigeon_instance: ProxyApiTestClass, + aDouble: Double?, + callback: (Result) -> Unit + ) + + /** Returns the passed in boolean asynchronously. */ + abstract fun echoAsyncNullableBool( + pigeon_instance: ProxyApiTestClass, + aBool: Boolean?, + callback: (Result) -> Unit + ) + + /** Returns the passed string asynchronously. */ + abstract fun echoAsyncNullableString( + pigeon_instance: ProxyApiTestClass, + aString: String?, + callback: (Result) -> Unit + ) + + /** Returns the passed in Uint8List asynchronously. */ + abstract fun echoAsyncNullableUint8List( + pigeon_instance: ProxyApiTestClass, + aUint8List: ByteArray?, + callback: (Result) -> Unit + ) + + /** Returns the passed in generic Object asynchronously. */ + abstract fun echoAsyncNullableObject( + pigeon_instance: ProxyApiTestClass, + anObject: Any?, + callback: (Result) -> Unit + ) + + /** Returns the passed list, to test asynchronous serialization and deserialization. */ + abstract fun echoAsyncNullableList( + pigeon_instance: ProxyApiTestClass, + aList: List?, + callback: (Result?>) -> Unit + ) + + /** Returns the passed map, to test asynchronous serialization and deserialization. */ + abstract fun echoAsyncNullableMap( + pigeon_instance: ProxyApiTestClass, + aMap: Map?, + callback: (Result?>) -> Unit + ) + + /** Returns the passed enum, to test asynchronous serialization and deserialization. */ + abstract fun echoAsyncNullableEnum( + pigeon_instance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum?, + callback: (Result) -> Unit + ) + + abstract fun staticNoop() + + abstract fun echoStaticString(aString: String): String + + abstract fun staticAsyncNoop(callback: (Result) -> Unit) + + abstract fun callFlutterNoop(pigeon_instance: ProxyApiTestClass, callback: (Result) -> Unit) + + abstract fun callFlutterThrowError( + pigeon_instance: ProxyApiTestClass, + callback: (Result) -> Unit + ) + + abstract fun callFlutterThrowErrorFromVoid( + pigeon_instance: ProxyApiTestClass, + callback: (Result) -> Unit + ) + + abstract fun callFlutterEchoBool( + pigeon_instance: ProxyApiTestClass, + aBool: Boolean, + callback: (Result) -> Unit + ) + + abstract fun callFlutterEchoInt( + pigeon_instance: ProxyApiTestClass, + anInt: Long, + callback: (Result) -> Unit + ) + + abstract fun callFlutterEchoDouble( + pigeon_instance: ProxyApiTestClass, + aDouble: Double, + callback: (Result) -> Unit + ) + + abstract fun callFlutterEchoString( + pigeon_instance: ProxyApiTestClass, + aString: String, + callback: (Result) -> Unit + ) + + abstract fun callFlutterEchoUint8List( + pigeon_instance: ProxyApiTestClass, + aUint8List: ByteArray, + callback: (Result) -> Unit + ) + + abstract fun callFlutterEchoList( + pigeon_instance: ProxyApiTestClass, + aList: List, + callback: (Result>) -> Unit + ) + + abstract fun callFlutterEchoProxyApiList( + pigeon_instance: ProxyApiTestClass, + aList: List, + callback: (Result>) -> Unit + ) + + abstract fun callFlutterEchoMap( + pigeon_instance: ProxyApiTestClass, + aMap: Map, + callback: (Result>) -> Unit + ) + + abstract fun callFlutterEchoProxyApiMap( + pigeon_instance: ProxyApiTestClass, + aMap: Map, + callback: (Result>) -> Unit + ) + + abstract fun callFlutterEchoEnum( + pigeon_instance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum, + callback: (Result) -> Unit + ) + + abstract fun callFlutterEchoProxyApi( + pigeon_instance: ProxyApiTestClass, + aProxyApi: com.example.test_plugin.ProxyApiSuperClass, + callback: (Result) -> Unit + ) + + abstract fun callFlutterEchoNullableBool( + pigeon_instance: ProxyApiTestClass, + aBool: Boolean?, + callback: (Result) -> Unit + ) + + abstract fun callFlutterEchoNullableInt( + pigeon_instance: ProxyApiTestClass, + anInt: Long?, + callback: (Result) -> Unit + ) + + abstract fun callFlutterEchoNullableDouble( + pigeon_instance: ProxyApiTestClass, + aDouble: Double?, + callback: (Result) -> Unit + ) + + abstract fun callFlutterEchoNullableString( + pigeon_instance: ProxyApiTestClass, + aString: String?, + callback: (Result) -> Unit + ) + + abstract fun callFlutterEchoNullableUint8List( + pigeon_instance: ProxyApiTestClass, + aUint8List: ByteArray?, + callback: (Result) -> Unit + ) + + abstract fun callFlutterEchoNullableList( + pigeon_instance: ProxyApiTestClass, + aList: List?, + callback: (Result?>) -> Unit + ) + + abstract fun callFlutterEchoNullableMap( + pigeon_instance: ProxyApiTestClass, + aMap: Map?, + callback: (Result?>) -> Unit + ) + + abstract fun callFlutterEchoNullableEnum( + pigeon_instance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum?, + callback: (Result) -> Unit + ) + + abstract fun callFlutterEchoNullableProxyApi( + pigeon_instance: ProxyApiTestClass, + aProxyApi: com.example.test_plugin.ProxyApiSuperClass?, + callback: (Result) -> Unit + ) + + abstract fun callFlutterNoopAsync( + pigeon_instance: ProxyApiTestClass, + callback: (Result) -> Unit + ) + + abstract fun callFlutterEchoAsyncString( + pigeon_instance: ProxyApiTestClass, + aString: String, + callback: (Result) -> Unit + ) + + companion object { + @Suppress("LocalVariableName") + fun setUpMessageHandlers(binaryMessenger: BinaryMessenger, api: PigeonApiProxyApiTestClass?) { + val codec = api?.pigeonRegistrar?.codec ?: ProxyApiTestsPigeonCodec() + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.pigeon_defaultConstructor", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_identifierArg = args[0] as Long + val aBoolArg = args[1] as Boolean + val anIntArg = args[2] as Long + val aDoubleArg = args[3] as Double + val aStringArg = args[4] as String + val aUint8ListArg = args[5] as ByteArray + val aListArg = args[6] as List + val aMapArg = args[7] as Map + val anEnumArg = args[8] as ProxyApiTestEnum + val aProxyApiArg = args[9] as com.example.test_plugin.ProxyApiSuperClass + val aNullableBoolArg = args[10] as Boolean? + val aNullableIntArg = args[11] as Long? + val aNullableDoubleArg = args[12] as Double? + val aNullableStringArg = args[13] as String? + val aNullableUint8ListArg = args[14] as ByteArray? + val aNullableListArg = args[15] as List? + val aNullableMapArg = args[16] as Map? + val aNullableEnumArg = args[17] as ProxyApiTestEnum? + val aNullableProxyApiArg = args[18] as com.example.test_plugin.ProxyApiSuperClass? + val boolParamArg = args[19] as Boolean + val intParamArg = args[20] as Long + val doubleParamArg = args[21] as Double + val stringParamArg = args[22] as String + val aUint8ListParamArg = args[23] as ByteArray + val listParamArg = args[24] as List + val mapParamArg = args[25] as Map + val enumParamArg = args[26] as ProxyApiTestEnum + val proxyApiParamArg = args[27] as com.example.test_plugin.ProxyApiSuperClass + val nullableBoolParamArg = args[28] as Boolean? + val nullableIntParamArg = args[29] as Long? + val nullableDoubleParamArg = args[30] as Double? + val nullableStringParamArg = args[31] as String? + val nullableUint8ListParamArg = args[32] as ByteArray? + val nullableListParamArg = args[33] as List? + val nullableMapParamArg = args[34] as Map? + val nullableEnumParamArg = args[35] as ProxyApiTestEnum? + val nullableProxyApiParamArg = args[36] as com.example.test_plugin.ProxyApiSuperClass? + val wrapped: List = + try { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + api.pigeon_defaultConstructor( + aBoolArg, + anIntArg, + aDoubleArg, + aStringArg, + aUint8ListArg, + aListArg, + aMapArg, + anEnumArg, + aProxyApiArg, + aNullableBoolArg, + aNullableIntArg, + aNullableDoubleArg, + aNullableStringArg, + aNullableUint8ListArg, + aNullableListArg, + aNullableMapArg, + aNullableEnumArg, + aNullableProxyApiArg, + boolParamArg, + intParamArg, + doubleParamArg, + stringParamArg, + aUint8ListParamArg, + listParamArg, + mapParamArg, + enumParamArg, + proxyApiParamArg, + nullableBoolParamArg, + nullableIntParamArg, + nullableDoubleParamArg, + nullableStringParamArg, + nullableUint8ListParamArg, + nullableListParamArg, + nullableMapParamArg, + nullableEnumParamArg, + nullableProxyApiParamArg), + pigeon_identifierArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.attachedField", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val pigeon_identifierArg = args[1] as Long + val wrapped: List = + try { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + api.attachedField(pigeon_instanceArg), pigeon_identifierArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.staticAttachedField", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_identifierArg = args[0] as Long + val wrapped: List = + try { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + api.staticAttachedField(), pigeon_identifierArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.noop", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val wrapped: List = + try { + api.noop(pigeon_instanceArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.throwError", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val wrapped: List = + try { + listOf(api.throwError(pigeon_instanceArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.throwErrorFromVoid", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val wrapped: List = + try { + api.throwErrorFromVoid(pigeon_instanceArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.throwFlutterError", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val wrapped: List = + try { + listOf(api.throwFlutterError(pigeon_instanceArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoInt", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val anIntArg = args[1] as Long + val wrapped: List = + try { + listOf(api.echoInt(pigeon_instanceArg, anIntArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoDouble", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aDoubleArg = args[1] as Double + val wrapped: List = + try { + listOf(api.echoDouble(pigeon_instanceArg, aDoubleArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoBool", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aBoolArg = args[1] as Boolean + val wrapped: List = + try { + listOf(api.echoBool(pigeon_instanceArg, aBoolArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoString", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aStringArg = args[1] as String + val wrapped: List = + try { + listOf(api.echoString(pigeon_instanceArg, aStringArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoUint8List", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aUint8ListArg = args[1] as ByteArray + val wrapped: List = + try { + listOf(api.echoUint8List(pigeon_instanceArg, aUint8ListArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoObject", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val anObjectArg = args[1] as Any + val wrapped: List = + try { + listOf(api.echoObject(pigeon_instanceArg, anObjectArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoList", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aListArg = args[1] as List + val wrapped: List = + try { + listOf(api.echoList(pigeon_instanceArg, aListArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoProxyApiList", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aListArg = args[1] as List + val wrapped: List = + try { + listOf(api.echoProxyApiList(pigeon_instanceArg, aListArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoMap", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aMapArg = args[1] as Map + val wrapped: List = + try { + listOf(api.echoMap(pigeon_instanceArg, aMapArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoProxyApiMap", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aMapArg = args[1] as Map + val wrapped: List = + try { + listOf(api.echoProxyApiMap(pigeon_instanceArg, aMapArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoEnum", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val anEnumArg = args[1] as ProxyApiTestEnum + val wrapped: List = + try { + listOf(api.echoEnum(pigeon_instanceArg, anEnumArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoProxyApi", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aProxyApiArg = args[1] as com.example.test_plugin.ProxyApiSuperClass + val wrapped: List = + try { + listOf(api.echoProxyApi(pigeon_instanceArg, aProxyApiArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableInt", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aNullableIntArg = args[1] as Long? + val wrapped: List = + try { + listOf(api.echoNullableInt(pigeon_instanceArg, aNullableIntArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableDouble", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aNullableDoubleArg = args[1] as Double? + val wrapped: List = + try { + listOf(api.echoNullableDouble(pigeon_instanceArg, aNullableDoubleArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableBool", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aNullableBoolArg = args[1] as Boolean? + val wrapped: List = + try { + listOf(api.echoNullableBool(pigeon_instanceArg, aNullableBoolArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableString", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aNullableStringArg = args[1] as String? + val wrapped: List = + try { + listOf(api.echoNullableString(pigeon_instanceArg, aNullableStringArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableUint8List", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aNullableUint8ListArg = args[1] as ByteArray? + val wrapped: List = + try { + listOf(api.echoNullableUint8List(pigeon_instanceArg, aNullableUint8ListArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableObject", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aNullableObjectArg = args[1] + val wrapped: List = + try { + listOf(api.echoNullableObject(pigeon_instanceArg, aNullableObjectArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableList", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aNullableListArg = args[1] as List? + val wrapped: List = + try { + listOf(api.echoNullableList(pigeon_instanceArg, aNullableListArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableMap", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aNullableMapArg = args[1] as Map? + val wrapped: List = + try { + listOf(api.echoNullableMap(pigeon_instanceArg, aNullableMapArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableEnum", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aNullableEnumArg = args[1] as ProxyApiTestEnum? + val wrapped: List = + try { + listOf(api.echoNullableEnum(pigeon_instanceArg, aNullableEnumArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableProxyApi", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aNullableProxyApiArg = args[1] as com.example.test_plugin.ProxyApiSuperClass? + val wrapped: List = + try { + listOf(api.echoNullableProxyApi(pigeon_instanceArg, aNullableProxyApiArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.noopAsync", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + api.noopAsync(pigeon_instanceArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + reply.reply(wrapResult(null)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncInt", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val anIntArg = args[1] as Long + api.echoAsyncInt(pigeon_instanceArg, anIntArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncDouble", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aDoubleArg = args[1] as Double + api.echoAsyncDouble(pigeon_instanceArg, aDoubleArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncBool", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aBoolArg = args[1] as Boolean + api.echoAsyncBool(pigeon_instanceArg, aBoolArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncString", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aStringArg = args[1] as String + api.echoAsyncString(pigeon_instanceArg, aStringArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncUint8List", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aUint8ListArg = args[1] as ByteArray + api.echoAsyncUint8List(pigeon_instanceArg, aUint8ListArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncObject", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val anObjectArg = args[1] as Any + api.echoAsyncObject(pigeon_instanceArg, anObjectArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncList", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aListArg = args[1] as List + api.echoAsyncList(pigeon_instanceArg, aListArg) { result: Result> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncMap", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aMapArg = args[1] as Map + api.echoAsyncMap(pigeon_instanceArg, aMapArg) { result: Result> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncEnum", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val anEnumArg = args[1] as ProxyApiTestEnum + api.echoAsyncEnum(pigeon_instanceArg, anEnumArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.throwAsyncError", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + api.throwAsyncError(pigeon_instanceArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.throwAsyncErrorFromVoid", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + api.throwAsyncErrorFromVoid(pigeon_instanceArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + reply.reply(wrapResult(null)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.throwAsyncFlutterError", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + api.throwAsyncFlutterError(pigeon_instanceArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableInt", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val anIntArg = args[1] as Long? + api.echoAsyncNullableInt(pigeon_instanceArg, anIntArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableDouble", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aDoubleArg = args[1] as Double? + api.echoAsyncNullableDouble(pigeon_instanceArg, aDoubleArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableBool", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aBoolArg = args[1] as Boolean? + api.echoAsyncNullableBool(pigeon_instanceArg, aBoolArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableString", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aStringArg = args[1] as String? + api.echoAsyncNullableString(pigeon_instanceArg, aStringArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableUint8List", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aUint8ListArg = args[1] as ByteArray? + api.echoAsyncNullableUint8List(pigeon_instanceArg, aUint8ListArg) { + result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableObject", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val anObjectArg = args[1] + api.echoAsyncNullableObject(pigeon_instanceArg, anObjectArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableList", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aListArg = args[1] as List? + api.echoAsyncNullableList(pigeon_instanceArg, aListArg) { result: Result?> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableMap", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aMapArg = args[1] as Map? + api.echoAsyncNullableMap(pigeon_instanceArg, aMapArg) { + result: Result?> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableEnum", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val anEnumArg = args[1] as ProxyApiTestEnum? + api.echoAsyncNullableEnum(pigeon_instanceArg, anEnumArg) { + result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.staticNoop", + codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + val wrapped: List = + try { + api.staticNoop() + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoStaticString", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val aStringArg = args[0] as String + val wrapped: List = + try { + listOf(api.echoStaticString(aStringArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.staticAsyncNoop", + codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + api.staticAsyncNoop { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + reply.reply(wrapResult(null)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterNoop", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + api.callFlutterNoop(pigeon_instanceArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + reply.reply(wrapResult(null)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterThrowError", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + api.callFlutterThrowError(pigeon_instanceArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterThrowErrorFromVoid", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + api.callFlutterThrowErrorFromVoid(pigeon_instanceArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + reply.reply(wrapResult(null)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoBool", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aBoolArg = args[1] as Boolean + api.callFlutterEchoBool(pigeon_instanceArg, aBoolArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoInt", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val anIntArg = args[1] as Long + api.callFlutterEchoInt(pigeon_instanceArg, anIntArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoDouble", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aDoubleArg = args[1] as Double + api.callFlutterEchoDouble(pigeon_instanceArg, aDoubleArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoString", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aStringArg = args[1] as String + api.callFlutterEchoString(pigeon_instanceArg, aStringArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoUint8List", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aUint8ListArg = args[1] as ByteArray + api.callFlutterEchoUint8List(pigeon_instanceArg, aUint8ListArg) { + result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoList", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aListArg = args[1] as List + api.callFlutterEchoList(pigeon_instanceArg, aListArg) { result: Result> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoProxyApiList", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aListArg = args[1] as List + api.callFlutterEchoProxyApiList(pigeon_instanceArg, aListArg) { + result: Result> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoMap", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aMapArg = args[1] as Map + api.callFlutterEchoMap(pigeon_instanceArg, aMapArg) { result: Result> + -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoProxyApiMap", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aMapArg = args[1] as Map + api.callFlutterEchoProxyApiMap(pigeon_instanceArg, aMapArg) { + result: Result> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoEnum", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val anEnumArg = args[1] as ProxyApiTestEnum + api.callFlutterEchoEnum(pigeon_instanceArg, anEnumArg) { + result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoProxyApi", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aProxyApiArg = args[1] as com.example.test_plugin.ProxyApiSuperClass + api.callFlutterEchoProxyApi(pigeon_instanceArg, aProxyApiArg) { + result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableBool", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aBoolArg = args[1] as Boolean? + api.callFlutterEchoNullableBool(pigeon_instanceArg, aBoolArg) { result: Result + -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableInt", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val anIntArg = args[1] as Long? + api.callFlutterEchoNullableInt(pigeon_instanceArg, anIntArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableDouble", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aDoubleArg = args[1] as Double? + api.callFlutterEchoNullableDouble(pigeon_instanceArg, aDoubleArg) { + result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableString", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aStringArg = args[1] as String? + api.callFlutterEchoNullableString(pigeon_instanceArg, aStringArg) { + result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableUint8List", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aUint8ListArg = args[1] as ByteArray? + api.callFlutterEchoNullableUint8List(pigeon_instanceArg, aUint8ListArg) { + result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableList", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aListArg = args[1] as List? + api.callFlutterEchoNullableList(pigeon_instanceArg, aListArg) { + result: Result?> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableMap", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aMapArg = args[1] as Map? + api.callFlutterEchoNullableMap(pigeon_instanceArg, aMapArg) { + result: Result?> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableEnum", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val anEnumArg = args[1] as ProxyApiTestEnum? + api.callFlutterEchoNullableEnum(pigeon_instanceArg, anEnumArg) { + result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableProxyApi", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aProxyApiArg = args[1] as com.example.test_plugin.ProxyApiSuperClass? + api.callFlutterEchoNullableProxyApi(pigeon_instanceArg, aProxyApiArg) { + result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterNoopAsync", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + api.callFlutterNoopAsync(pigeon_instanceArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + reply.reply(wrapResult(null)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoAsyncString", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ProxyApiTestClass + val aStringArg = args[1] as String + api.callFlutterEchoAsyncString(pigeon_instanceArg, aStringArg) { result: Result + -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + } + } + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of ProxyApiTestClass and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance(pigeon_instanceArg: ProxyApiTestClass, callback: (Result) -> Unit) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val aBoolArg = aBool(pigeon_instanceArg) + val anIntArg = anInt(pigeon_instanceArg) + val aDoubleArg = aDouble(pigeon_instanceArg) + val aStringArg = aString(pigeon_instanceArg) + val aUint8ListArg = aUint8List(pigeon_instanceArg) + val aListArg = aList(pigeon_instanceArg) + val aMapArg = aMap(pigeon_instanceArg) + val anEnumArg = anEnum(pigeon_instanceArg) + val aProxyApiArg = aProxyApi(pigeon_instanceArg) + val aNullableBoolArg = aNullableBool(pigeon_instanceArg) + val aNullableIntArg = aNullableInt(pigeon_instanceArg) + val aNullableDoubleArg = aNullableDouble(pigeon_instanceArg) + val aNullableStringArg = aNullableString(pigeon_instanceArg) + val aNullableUint8ListArg = aNullableUint8List(pigeon_instanceArg) + val aNullableListArg = aNullableList(pigeon_instanceArg) + val aNullableMapArg = aNullableMap(pigeon_instanceArg) + val aNullableEnumArg = aNullableEnum(pigeon_instanceArg) + val aNullableProxyApiArg = aNullableProxyApi(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send( + listOf( + pigeon_identifierArg, + aBoolArg, + anIntArg, + aDoubleArg, + aStringArg, + aUint8ListArg, + aListArg, + aMapArg, + anEnumArg, + aProxyApiArg, + aNullableBoolArg, + aNullableIntArg, + aNullableDoubleArg, + aNullableStringArg, + aNullableUint8ListArg, + aNullableListArg, + aNullableMapArg, + aNullableEnumArg, + aNullableProxyApiArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** A no-op function taking no arguments and returning no value, to sanity test basic calling. */ + fun flutterNoop(pigeon_instanceArg: ProxyApiTestClass, callback: (Result) -> Unit) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterNoop" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Responds with an error from an async function returning a value. */ + fun flutterThrowError(pigeon_instanceArg: ProxyApiTestClass, callback: (Result) -> Unit) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterThrowError" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + val output = it[0] + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Responds with an error from an async void function. */ + fun flutterThrowErrorFromVoid( + pigeon_instanceArg: ProxyApiTestClass, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterThrowErrorFromVoid" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Returns the passed boolean, to test serialization and deserialization. */ + fun flutterEchoBool( + pigeon_instanceArg: ProxyApiTestClass, + aBoolArg: Boolean, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoBool" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, aBoolArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + ProxyApiTestsError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as Boolean + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Returns the passed int, to test serialization and deserialization. */ + fun flutterEchoInt( + pigeon_instanceArg: ProxyApiTestClass, + anIntArg: Long, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoInt" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, anIntArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + ProxyApiTestsError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as Long + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Returns the passed double, to test serialization and deserialization. */ + fun flutterEchoDouble( + pigeon_instanceArg: ProxyApiTestClass, + aDoubleArg: Double, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoDouble" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, aDoubleArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + ProxyApiTestsError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as Double + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Returns the passed string, to test serialization and deserialization. */ + fun flutterEchoString( + pigeon_instanceArg: ProxyApiTestClass, + aStringArg: String, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoString" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, aStringArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + ProxyApiTestsError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as String + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Returns the passed byte list, to test serialization and deserialization. */ + fun flutterEchoUint8List( + pigeon_instanceArg: ProxyApiTestClass, + aListArg: ByteArray, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoUint8List" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, aListArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + ProxyApiTestsError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as ByteArray + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Returns the passed list, to test serialization and deserialization. */ + fun flutterEchoList( + pigeon_instanceArg: ProxyApiTestClass, + aListArg: List, + callback: (Result>) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoList" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, aListArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + ProxyApiTestsError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as List + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Returns the passed list with ProxyApis, to test serialization and deserialization. */ + fun flutterEchoProxyApiList( + pigeon_instanceArg: ProxyApiTestClass, + aListArg: List, + callback: (Result>) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoProxyApiList" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, aListArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + ProxyApiTestsError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as List + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Returns the passed map, to test serialization and deserialization. */ + fun flutterEchoMap( + pigeon_instanceArg: ProxyApiTestClass, + aMapArg: Map, + callback: (Result>) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoMap" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, aMapArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + ProxyApiTestsError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as Map + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Returns the passed map with ProxyApis, to test serialization and deserialization. */ + fun flutterEchoProxyApiMap( + pigeon_instanceArg: ProxyApiTestClass, + aMapArg: Map, + callback: (Result>) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoProxyApiMap" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, aMapArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + ProxyApiTestsError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as Map + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Returns the passed enum to test serialization and deserialization. */ + fun flutterEchoEnum( + pigeon_instanceArg: ProxyApiTestClass, + anEnumArg: ProxyApiTestEnum, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoEnum" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, anEnumArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + ProxyApiTestsError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as ProxyApiTestEnum + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Returns the passed ProxyApi to test serialization and deserialization. */ + fun flutterEchoProxyApi( + pigeon_instanceArg: ProxyApiTestClass, + aProxyApiArg: com.example.test_plugin.ProxyApiSuperClass, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoProxyApi" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, aProxyApiArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + ProxyApiTestsError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as com.example.test_plugin.ProxyApiSuperClass + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Returns the passed boolean, to test serialization and deserialization. */ + fun flutterEchoNullableBool( + pigeon_instanceArg: ProxyApiTestClass, + aBoolArg: Boolean?, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableBool" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, aBoolArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + val output = it[0] as Boolean? + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Returns the passed int, to test serialization and deserialization. */ + fun flutterEchoNullableInt( + pigeon_instanceArg: ProxyApiTestClass, + anIntArg: Long?, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableInt" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, anIntArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + val output = it[0] as Long? + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Returns the passed double, to test serialization and deserialization. */ + fun flutterEchoNullableDouble( + pigeon_instanceArg: ProxyApiTestClass, + aDoubleArg: Double?, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableDouble" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, aDoubleArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + val output = it[0] as Double? + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Returns the passed string, to test serialization and deserialization. */ + fun flutterEchoNullableString( + pigeon_instanceArg: ProxyApiTestClass, + aStringArg: String?, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableString" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, aStringArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + val output = it[0] as String? + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Returns the passed byte list, to test serialization and deserialization. */ + fun flutterEchoNullableUint8List( + pigeon_instanceArg: ProxyApiTestClass, + aListArg: ByteArray?, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableUint8List" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, aListArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + val output = it[0] as ByteArray? + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Returns the passed list, to test serialization and deserialization. */ + fun flutterEchoNullableList( + pigeon_instanceArg: ProxyApiTestClass, + aListArg: List?, + callback: (Result?>) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableList" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, aListArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + val output = it[0] as List? + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Returns the passed map, to test serialization and deserialization. */ + fun flutterEchoNullableMap( + pigeon_instanceArg: ProxyApiTestClass, + aMapArg: Map?, + callback: (Result?>) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableMap" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, aMapArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + val output = it[0] as Map? + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Returns the passed enum to test serialization and deserialization. */ + fun flutterEchoNullableEnum( + pigeon_instanceArg: ProxyApiTestClass, + anEnumArg: ProxyApiTestEnum?, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableEnum" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, anEnumArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + val output = it[0] as ProxyApiTestEnum? + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Returns the passed ProxyApi to test serialization and deserialization. */ + fun flutterEchoNullableProxyApi( + pigeon_instanceArg: ProxyApiTestClass, + aProxyApiArg: com.example.test_plugin.ProxyApiSuperClass?, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableProxyApi" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, aProxyApiArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + val output = it[0] as com.example.test_plugin.ProxyApiSuperClass? + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** + * A no-op function taking no arguments and returning no value, to sanity test basic asynchronous + * calling. + */ + fun flutterNoopAsync(pigeon_instanceArg: ProxyApiTestClass, callback: (Result) -> Unit) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterNoopAsync" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + /** Returns the passed in generic Object asynchronously. */ + fun flutterEchoAsyncString( + pigeon_instanceArg: ProxyApiTestClass, + aStringArg: String, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoAsyncString" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg, aStringArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + ProxyApiTestsError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as String + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + @Suppress("FunctionName") + /** An implementation of [PigeonApiProxyApiSuperClass] used to access callback methods */ + fun pigeon_getPigeonApiProxyApiSuperClass(): PigeonApiProxyApiSuperClass { + return pigeonRegistrar.getPigeonApiProxyApiSuperClass() + } + + @Suppress("FunctionName") + /** An implementation of [PigeonApiProxyApiInterface] used to access callback methods */ + fun pigeon_getPigeonApiProxyApiInterface(): PigeonApiProxyApiInterface { + return pigeonRegistrar.getPigeonApiProxyApiInterface() + } +} +/** ProxyApi to serve as a super class to the core ProxyApi class. */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiProxyApiSuperClass( + open val pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar +) { + abstract fun pigeon_defaultConstructor(): com.example.test_plugin.ProxyApiSuperClass + + abstract fun aSuperMethod(pigeon_instance: com.example.test_plugin.ProxyApiSuperClass) + + companion object { + @Suppress("LocalVariableName") + fun setUpMessageHandlers(binaryMessenger: BinaryMessenger, api: PigeonApiProxyApiSuperClass?) { + val codec = api?.pigeonRegistrar?.codec ?: ProxyApiTestsPigeonCodec() + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiSuperClass.pigeon_defaultConstructor", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_identifierArg = args[0] as Long + val wrapped: List = + try { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + api.pigeon_defaultConstructor(), pigeon_identifierArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiSuperClass.aSuperMethod", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.example.test_plugin.ProxyApiSuperClass + val wrapped: List = + try { + api.aSuperMethod(pigeon_instanceArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } + } + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of ProxyApiSuperClass and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.example.test_plugin.ProxyApiSuperClass, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiSuperClass.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_identifierArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} +/** ProxyApi to serve as an interface to the core ProxyApi class. */ +@Suppress("UNCHECKED_CAST") +open class PigeonApiProxyApiInterface( + open val pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar +) { + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of ProxyApiInterface and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance(pigeon_instanceArg: ProxyApiInterface, callback: (Result) -> Unit) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiInterface.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_identifierArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + + fun anInterfaceMethod(pigeon_instanceArg: ProxyApiInterface, callback: (Result) -> Unit) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiInterface.anInterfaceMethod" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_instanceArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} + +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiClassWithApiRequirement( + open val pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar +) { + @androidx.annotation.RequiresApi(api = 25) + abstract fun pigeon_defaultConstructor(): ClassWithApiRequirement + + @androidx.annotation.RequiresApi(api = 25) + abstract fun aMethod(pigeon_instance: ClassWithApiRequirement) + + companion object { + @Suppress("LocalVariableName") + fun setUpMessageHandlers( + binaryMessenger: BinaryMessenger, + api: PigeonApiClassWithApiRequirement? + ) { + val codec = api?.pigeonRegistrar?.codec ?: ProxyApiTestsPigeonCodec() + if (android.os.Build.VERSION.SDK_INT >= 25) { + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ClassWithApiRequirement.pigeon_defaultConstructor", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_identifierArg = args[0] as Long + val wrapped: List = + try { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + api.pigeon_defaultConstructor(), pigeon_identifierArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } else { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ClassWithApiRequirement.pigeon_defaultConstructor", + codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + reply.reply( + wrapError( + UnsupportedOperationException( + "Call references class `ClassWithApiRequirement`, which requires api version 25."))) + } + } else { + channel.setMessageHandler(null) + } + } + if (android.os.Build.VERSION.SDK_INT >= 25) { + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ClassWithApiRequirement.aMethod", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as ClassWithApiRequirement + val wrapped: List = + try { + api.aMethod(pigeon_instanceArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } else { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.ClassWithApiRequirement.aMethod", + codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + reply.reply( + wrapError( + UnsupportedOperationException( + "Call references class `ClassWithApiRequirement`, which requires api version 25."))) + } + } else { + channel.setMessageHandler(null) + } + } + } + } + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of ClassWithApiRequirement and attaches it to [pigeon_instanceArg]. */ + @androidx.annotation.RequiresApi(api = 25) + fun pigeon_newInstance( + pigeon_instanceArg: ClassWithApiRequirement, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + ProxyApiTestsError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.ClassWithApiRequirement.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(pigeon_identifierArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure( + ProxyApiTestsError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/TestPlugin.kt b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/TestPlugin.kt index 43ed1282d123..9563941624d7 100644 --- a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/TestPlugin.kt +++ b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/TestPlugin.kt @@ -12,6 +12,7 @@ class TestPlugin : FlutterPlugin, HostIntegrationCoreApi { private var flutterApi: FlutterIntegrationCoreApi? = null private var flutterSmallApiOne: FlutterSmallApi? = null private var flutterSmallApiTwo: FlutterSmallApi? = null + private var proxyApiRegistrar: ProxyApiRegistrar? = null override fun onAttachedToEngine(binding: FlutterPluginBinding) { HostIntegrationCoreApi.setUp(binding.binaryMessenger, this) @@ -22,9 +23,14 @@ class TestPlugin : FlutterPlugin, HostIntegrationCoreApi { flutterApi = FlutterIntegrationCoreApi(binding.binaryMessenger) flutterSmallApiOne = FlutterSmallApi(binding.binaryMessenger, "suffixOne") flutterSmallApiTwo = FlutterSmallApi(binding.binaryMessenger, "suffixTwo") + + proxyApiRegistrar = ProxyApiRegistrar(binding.binaryMessenger) + proxyApiRegistrar!!.setUp() } - override fun onDetachedFromEngine(binding: FlutterPluginBinding) {} + override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { + proxyApiRegistrar?.tearDown() + } // HostIntegrationCoreApi @@ -84,8 +90,60 @@ class TestPlugin : FlutterPlugin, HostIntegrationCoreApi { return list } - override fun echoMap(aMap: Map): Map { - return aMap + override fun echoEnumList(enumList: List): List { + return enumList + } + + override fun echoClassList(classList: List): List { + return classList + } + + override fun echoNonNullEnumList(enumList: List): List { + return enumList + } + + override fun echoNonNullClassList(classList: List): List { + return classList + } + + override fun echoMap(map: Map): Map { + return map + } + + override fun echoStringMap(stringMap: Map): Map { + return stringMap + } + + override fun echoIntMap(intMap: Map): Map { + return intMap + } + + override fun echoEnumMap(enumMap: Map): Map { + return enumMap + } + + override fun echoClassMap( + classMap: Map + ): Map { + return classMap + } + + override fun echoNonNullStringMap(stringMap: Map): Map { + return stringMap + } + + override fun echoNonNullIntMap(intMap: Map): Map { + return intMap + } + + override fun echoNonNullEnumMap(enumMap: Map): Map { + return enumMap + } + + override fun echoNonNullClassMap( + classMap: Map + ): Map { + return classMap } override fun echoClassWrapper(wrapper: AllClassesWrapper): AllClassesWrapper { @@ -96,6 +154,10 @@ class TestPlugin : FlutterPlugin, HostIntegrationCoreApi { return anEnum } + override fun echoAnotherEnum(anotherEnum: AnotherEnum): AnotherEnum { + return anotherEnum + } + override fun echoNamedDefaultString(aString: String): String { return aString } @@ -113,7 +175,10 @@ class TestPlugin : FlutterPlugin, HostIntegrationCoreApi { } override fun createNestedNullableString(nullableString: String?): AllClassesWrapper { - return AllClassesWrapper(AllNullableTypes(aNullableString = nullableString)) + return AllClassesWrapper( + AllNullableTypes(aNullableString = nullableString), + classList = arrayOf().toList(), + classMap = HashMap()) } override fun sendMultipleNullableTypes( @@ -166,14 +231,74 @@ class TestPlugin : FlutterPlugin, HostIntegrationCoreApi { return aNullableList } - override fun echoNullableMap(aNullableMap: Map?): Map? { - return aNullableMap + override fun echoNullableEnumList(enumList: List?): List? { + return enumList + } + + override fun echoNullableClassList( + classList: List? + ): List? { + return classList + } + + override fun echoNullableNonNullEnumList(enumList: List?): List? { + return enumList + } + + override fun echoNullableNonNullClassList( + classList: List? + ): List? { + return classList + } + + override fun echoNullableMap(map: Map?): Map? { + return map + } + + override fun echoNullableStringMap(stringMap: Map?): Map? { + return stringMap + } + + override fun echoNullableIntMap(intMap: Map?): Map? { + return intMap + } + + override fun echoNullableEnumMap(enumMap: Map?): Map? { + return enumMap + } + + override fun echoNullableClassMap( + classMap: Map? + ): Map? { + return classMap + } + + override fun echoNullableNonNullStringMap(stringMap: Map?): Map? { + return stringMap + } + + override fun echoNullableNonNullIntMap(intMap: Map?): Map? { + return intMap + } + + override fun echoNullableNonNullEnumMap(enumMap: Map?): Map? { + return enumMap + } + + override fun echoNullableNonNullClassMap( + classMap: Map? + ): Map? { + return classMap } override fun echoNullableEnum(anEnum: AnEnum?): AnEnum? { return anEnum } + override fun echoAnotherNullableEnum(anotherEnum: AnotherEnum?): AnotherEnum? { + return anotherEnum + } + override fun echoOptionalNullableInt(aNullableInt: Long?): Long? { return aNullableInt } @@ -244,17 +369,63 @@ class TestPlugin : FlutterPlugin, HostIntegrationCoreApi { callback(Result.success(list)) } - override fun echoAsyncMap( - aMap: Map, - callback: (Result>) -> Unit + override fun echoAsyncEnumList( + enumList: List, + callback: (Result>) -> Unit + ) { + callback(Result.success(enumList)) + } + + override fun echoAsyncClassList( + classList: List, + callback: (Result>) -> Unit + ) { + callback(Result.success(classList)) + } + + override fun echoAsyncMap(map: Map, callback: (Result>) -> Unit) { + callback(Result.success(map)) + } + + override fun echoAsyncStringMap( + stringMap: Map, + callback: (Result>) -> Unit + ) { + callback(Result.success(stringMap)) + } + + override fun echoAsyncIntMap( + intMap: Map, + callback: (Result>) -> Unit + ) { + callback(Result.success(intMap)) + } + + override fun echoAsyncEnumMap( + enumMap: Map, + callback: (Result>) -> Unit + ) { + callback(Result.success(enumMap)) + } + + override fun echoAsyncClassMap( + classMap: Map, + callback: (Result>) -> Unit ) { - callback(Result.success(aMap)) + callback(Result.success(classMap)) } override fun echoAsyncEnum(anEnum: AnEnum, callback: (Result) -> Unit) { callback(Result.success(anEnum)) } + override fun echoAnotherAsyncEnum( + anotherEnum: AnotherEnum, + callback: (Result) -> Unit + ) { + callback(Result.success(anotherEnum)) + } + override fun echoAsyncNullableInt(anInt: Long?, callback: (Result) -> Unit) { callback(Result.success(anInt)) } @@ -286,17 +457,66 @@ class TestPlugin : FlutterPlugin, HostIntegrationCoreApi { callback(Result.success(list)) } + override fun echoAsyncNullableEnumList( + enumList: List?, + callback: (Result?>) -> Unit + ) { + callback(Result.success(enumList)) + } + + override fun echoAsyncNullableClassList( + classList: List?, + callback: (Result?>) -> Unit + ) { + callback(Result.success(classList)) + } + override fun echoAsyncNullableMap( - aMap: Map?, - callback: (Result?>) -> Unit + map: Map?, + callback: (Result?>) -> Unit + ) { + callback(Result.success(map)) + } + + override fun echoAsyncNullableStringMap( + stringMap: Map?, + callback: (Result?>) -> Unit ) { - callback(Result.success(aMap)) + callback(Result.success(stringMap)) + } + + override fun echoAsyncNullableIntMap( + intMap: Map?, + callback: (Result?>) -> Unit + ) { + callback(Result.success(intMap)) + } + + override fun echoAsyncNullableEnumMap( + enumMap: Map?, + callback: (Result?>) -> Unit + ) { + callback(Result.success(enumMap)) + } + + override fun echoAsyncNullableClassMap( + classMap: Map?, + callback: (Result?>) -> Unit + ) { + callback(Result.success(classMap)) } override fun echoAsyncNullableEnum(anEnum: AnEnum?, callback: (Result) -> Unit) { callback(Result.success(anEnum)) } + override fun echoAnotherAsyncNullableEnum( + anotherEnum: AnotherEnum?, + callback: (Result) -> Unit + ) { + callback(Result.success(anotherEnum)) + } + override fun callFlutterNoop(callback: (Result) -> Unit) { flutterApi!!.noop { callback(Result.success(Unit)) } } @@ -367,18 +587,108 @@ class TestPlugin : FlutterPlugin, HostIntegrationCoreApi { flutterApi!!.echoList(list) { echo -> callback(echo) } } + override fun callFlutterEchoEnumList( + enumList: List, + callback: (Result>) -> Unit + ) { + flutterApi!!.echoEnumList(enumList) { echo -> callback(echo) } + } + + override fun callFlutterEchoClassList( + classList: List, + callback: (Result>) -> Unit + ) { + flutterApi!!.echoClassList(classList) { echo -> callback(echo) } + } + + override fun callFlutterEchoNonNullEnumList( + enumList: List, + callback: (Result>) -> Unit + ) { + flutterApi!!.echoNonNullEnumList(enumList) { echo -> callback(echo) } + } + + override fun callFlutterEchoNonNullClassList( + classList: List, + callback: (Result>) -> Unit + ) { + flutterApi!!.echoNonNullClassList(classList) { echo -> callback(echo) } + } + override fun callFlutterEchoMap( - aMap: Map, - callback: (Result>) -> Unit + map: Map, + callback: (Result>) -> Unit + ) { + flutterApi!!.echoMap(map) { echo -> callback(echo) } + } + + override fun callFlutterEchoStringMap( + stringMap: Map, + callback: (Result>) -> Unit ) { - flutterApi!!.echoMap(aMap) { echo -> callback(echo) } + flutterApi!!.echoStringMap(stringMap) { echo -> callback(echo) } + } + + override fun callFlutterEchoIntMap( + intMap: Map, + callback: (Result>) -> Unit + ) { + flutterApi!!.echoIntMap(intMap) { echo -> callback(echo) } + } + + override fun callFlutterEchoEnumMap( + enumMap: Map, + callback: (Result>) -> Unit + ) { + flutterApi!!.echoEnumMap(enumMap) { echo -> callback(echo) } + } + + override fun callFlutterEchoClassMap( + classMap: Map, + callback: (Result>) -> Unit + ) { + flutterApi!!.echoClassMap(classMap) { echo -> callback(echo) } + } + + override fun callFlutterEchoNonNullStringMap( + stringMap: Map, + callback: (Result>) -> Unit + ) { + flutterApi!!.echoNonNullStringMap(stringMap) { echo -> callback(echo) } + } + + override fun callFlutterEchoNonNullIntMap( + intMap: Map, + callback: (Result>) -> Unit + ) { + flutterApi!!.echoNonNullIntMap(intMap) { echo -> callback(echo) } + } + + override fun callFlutterEchoNonNullEnumMap( + enumMap: Map, + callback: (Result>) -> Unit + ) { + flutterApi!!.echoNonNullEnumMap(enumMap) { echo -> callback(echo) } + } + + override fun callFlutterEchoNonNullClassMap( + classMap: Map, + callback: (Result>) -> Unit + ) { + flutterApi!!.echoNonNullClassMap(classMap) { echo -> callback(echo) } } override fun callFlutterEchoEnum(anEnum: AnEnum, callback: (Result) -> Unit) { - // callback(Result.success(anEnum)) flutterApi!!.echoEnum(anEnum) { echo -> callback(echo) } } + override fun callFlutterEchoAnotherEnum( + anotherEnum: AnotherEnum, + callback: (Result) -> Unit + ) { + flutterApi!!.echoAnotherEnum(anotherEnum) { echo -> callback(echo) } + } + override fun callFlutterEchoAllNullableTypes( everything: AllNullableTypes?, callback: (Result) -> Unit @@ -422,17 +732,108 @@ class TestPlugin : FlutterPlugin, HostIntegrationCoreApi { flutterApi!!.echoNullableList(list) { echo -> callback(echo) } } + override fun callFlutterEchoNullableEnumList( + enumList: List?, + callback: (Result?>) -> Unit + ) { + flutterApi!!.echoNullableEnumList(enumList) { echo -> callback(echo) } + } + + override fun callFlutterEchoNullableClassList( + classList: List?, + callback: (Result?>) -> Unit + ) { + flutterApi!!.echoNullableClassList(classList) { echo -> callback(echo) } + } + + override fun callFlutterEchoNullableNonNullEnumList( + enumList: List?, + callback: (Result?>) -> Unit + ) { + flutterApi!!.echoNullableNonNullEnumList(enumList) { echo -> callback(echo) } + } + + override fun callFlutterEchoNullableNonNullClassList( + classList: List?, + callback: (Result?>) -> Unit + ) { + flutterApi!!.echoNullableNonNullClassList(classList) { echo -> callback(echo) } + } + override fun callFlutterEchoNullableMap( - aMap: Map?, - callback: (Result?>) -> Unit + map: Map?, + callback: (Result?>) -> Unit + ) { + flutterApi!!.echoNullableMap(map) { echo -> callback(echo) } + } + + override fun callFlutterEchoNullableStringMap( + stringMap: Map?, + callback: (Result?>) -> Unit ) { - flutterApi!!.echoNullableMap(aMap) { echo -> callback(echo) } + flutterApi!!.echoNullableStringMap(stringMap) { echo -> callback(echo) } + } + + override fun callFlutterEchoNullableIntMap( + intMap: Map?, + callback: (Result?>) -> Unit + ) { + flutterApi!!.echoNullableIntMap(intMap) { echo -> callback(echo) } + } + + override fun callFlutterEchoNullableEnumMap( + enumMap: Map?, + callback: (Result?>) -> Unit + ) { + flutterApi!!.echoNullableEnumMap(enumMap) { echo -> callback(echo) } + } + + override fun callFlutterEchoNullableClassMap( + classMap: Map?, + callback: (Result?>) -> Unit + ) { + flutterApi!!.echoNullableClassMap(classMap) { echo -> callback(echo) } + } + + override fun callFlutterEchoNullableNonNullStringMap( + stringMap: Map?, + callback: (Result?>) -> Unit + ) { + flutterApi!!.echoNullableNonNullStringMap(stringMap) { echo -> callback(echo) } + } + + override fun callFlutterEchoNullableNonNullIntMap( + intMap: Map?, + callback: (Result?>) -> Unit + ) { + flutterApi!!.echoNullableNonNullIntMap(intMap) { echo -> callback(echo) } + } + + override fun callFlutterEchoNullableNonNullEnumMap( + enumMap: Map?, + callback: (Result?>) -> Unit + ) { + flutterApi!!.echoNullableNonNullEnumMap(enumMap) { echo -> callback(echo) } + } + + override fun callFlutterEchoNullableNonNullClassMap( + classMap: Map?, + callback: (Result?>) -> Unit + ) { + flutterApi!!.echoNullableNonNullClassMap(classMap) { echo -> callback(echo) } } override fun callFlutterEchoNullableEnum(anEnum: AnEnum?, callback: (Result) -> Unit) { flutterApi!!.echoNullableEnum(anEnum) { echo -> callback(echo) } } + override fun callFlutterEchoAnotherNullableEnum( + anotherEnum: AnotherEnum?, + callback: (Result) -> Unit + ) { + flutterApi!!.echoAnotherNullableEnum(anotherEnum) { echo -> callback(echo) } + } + override fun callFlutterSmallApiEchoString(aString: String, callback: (Result) -> Unit) { flutterSmallApiOne!!.echoString(aString) { echoOne -> flutterSmallApiTwo!!.echoString(aString) { echoTwo -> @@ -446,6 +847,10 @@ class TestPlugin : FlutterPlugin, HostIntegrationCoreApi { } } } + + fun testUnusedClassesGenerate(): UnusedClass { + return UnusedClass() + } } class TestPluginWithSuffix : HostSmallApi { diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/AllDatatypesTest.kt b/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/AllDatatypesTest.kt index 56e0111d63f7..aa42535f718c 100644 --- a/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/AllDatatypesTest.kt +++ b/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/AllDatatypesTest.kt @@ -11,7 +11,6 @@ import java.nio.ByteBuffer import java.util.ArrayList import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull -import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.Test @@ -32,6 +31,7 @@ internal class AllDatatypesTest { assertTrue(firstTypes.a8ByteArray.contentEquals(secondTypes.a8ByteArray)) assertTrue(firstTypes.aFloatArray.contentEquals(secondTypes.aFloatArray)) assertEquals(firstTypes.anEnum, secondTypes.anEnum) + assertEquals(firstTypes.anotherEnum, secondTypes.anotherEnum) assertEquals(firstTypes.anObject, secondTypes.anObject) assertEquals(firstTypes.list, secondTypes.list) assertEquals(firstTypes.boolList, secondTypes.boolList) @@ -57,14 +57,21 @@ internal class AllDatatypesTest { assertTrue(firstTypes.aNullable4ByteArray.contentEquals(secondTypes.aNullable4ByteArray)) assertTrue(firstTypes.aNullable8ByteArray.contentEquals(secondTypes.aNullable8ByteArray)) assertTrue(firstTypes.aNullableFloatArray.contentEquals(secondTypes.aNullableFloatArray)) - assertEquals(firstTypes.nullableMapWithObject, secondTypes.nullableMapWithObject) assertEquals(firstTypes.aNullableObject, secondTypes.aNullableObject) + assertEquals(firstTypes.aNullableEnum, secondTypes.aNullableEnum) + assertEquals(firstTypes.anotherNullableEnum, secondTypes.anotherNullableEnum) assertEquals(firstTypes.list, secondTypes.list) assertEquals(firstTypes.boolList, secondTypes.boolList) assertEquals(firstTypes.doubleList, secondTypes.doubleList) assertEquals(firstTypes.intList, secondTypes.intList) assertEquals(firstTypes.stringList, secondTypes.stringList) + assertEquals(firstTypes.listList, secondTypes.listList) + assertEquals(firstTypes.mapList, secondTypes.mapList) assertEquals(firstTypes.map, secondTypes.map) + assertEquals(firstTypes.stringMap, secondTypes.stringMap) + assertEquals(firstTypes.intMap, secondTypes.intMap) + assertEquals(firstTypes.listMap, secondTypes.listMap) + assertEquals(firstTypes.mapMap, secondTypes.mapMap) } @Test @@ -97,6 +104,7 @@ internal class AllDatatypesTest { @Test fun testHasValues() { + val stringList = listOf("string", "another one") val everything = AllNullableTypes( aNullableBool = false, @@ -107,14 +115,21 @@ internal class AllDatatypesTest { aNullable4ByteArray = intArrayOf(1, 2, 3, 4), aNullable8ByteArray = longArrayOf(1, 2, 3, 4), aNullableFloatArray = doubleArrayOf(0.5, 0.25, 1.5, 1.25), - nullableMapWithObject = mapOf("hello" to 1234), aNullableObject = 0, list = listOf(1, 2, 3), - stringList = listOf("string", "another one"), + stringList = stringList, boolList = listOf(true, false), intList = listOf(1, 2), doubleList = listOf(1.1, 2.2), - map = mapOf("hello" to 1234)) + objectList = listOf(1, 2, 3), + listList = listOf(stringList, stringList.toList()), + mapList = listOf(mapOf("hello" to 1234), mapOf("hello" to 1234)), + map = mapOf("hello" to 1234), + stringMap = mapOf("hello" to "you"), + intMap = mapOf(1L to 0L), + objectMap = mapOf("hello" to 1234), + listMap = mapOf(1L to stringList), + mapMap = mapOf(1L to mapOf())) val binaryMessenger = mockk() val api = FlutterIntegrationCoreApi(binaryMessenger) @@ -138,42 +153,4 @@ internal class AllDatatypesTest { assertTrue(didCall) } - - @Test - fun testIntegerToLong() { - val everything = AllNullableTypes(aNullableInt = 123L) - val list = everything.toList() - assertNotNull(list) - assertNull(list.first()) - assertNotNull(list[1]) - assertTrue(list[1] == 123L) - - val list2 = - listOf( - null, - 123, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null) - val everything2 = AllNullableTypes.fromList(list2) - - assertEquals(everything.aNullableInt, everything2.aNullableInt) - } } diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/EnumTest.kt b/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/EnumTest.kt deleted file mode 100644 index acdc6192c016..000000000000 --- a/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/EnumTest.kt +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package com.example.test_plugin - -import io.flutter.plugin.common.BinaryMessenger -import io.mockk.every -import io.mockk.mockk -import io.mockk.slot -import io.mockk.verify -import java.nio.ByteBuffer -import java.util.ArrayList -import org.junit.Assert.assertEquals -import org.junit.Assert.assertNotNull -import org.junit.Assert.assertTrue -import org.junit.Test - -internal class EnumTest { - - @Test - fun testEchoHost() { - val binaryMessenger = mockk() - val api = mockk() - - val channelName = "dev.flutter.pigeon.pigeon_integration_tests.EnumApi2Host.echo" - val input = DataWithEnum(EnumState.SNAKE_CASE) - - val handlerSlot = slot() - - every { binaryMessenger.setMessageHandler(channelName, capture(handlerSlot)) } returns Unit - every { api.echo(any()) } returnsArgument 0 - - EnumApi2Host.setUp(binaryMessenger, api) - - val codec = EnumApi2Host.codec - val message = codec.encodeMessage(listOf(input)) - message?.rewind() - handlerSlot.captured.onMessage(message) { - it?.rewind() - @Suppress("UNCHECKED_CAST") val wrapped = codec.decodeMessage(it) as List? - assertNotNull(wrapped) - wrapped?.let { - assertNotNull(wrapped[0]) - assertEquals(input, wrapped[0]) - } - } - - verify { binaryMessenger.setMessageHandler(channelName, handlerSlot.captured) } - verify { api.echo(input) } - } - - @Test - fun testEchoFlutter() { - val binaryMessenger = mockk() - val api = EnumApi2Flutter(binaryMessenger) - - val input = DataWithEnum(EnumState.SNAKE_CASE) - - every { binaryMessenger.send(any(), any(), any()) } answers - { - val codec = EnumApi2Flutter.codec - val message = arg(1) - val reply = arg(2) - message.position(0) - val args = codec.decodeMessage(message) as ArrayList<*> - val replyData = codec.encodeMessage(args) - replyData?.position(0) - reply.reply(replyData) - } - - var didCall = false - api.echo(input) { - didCall = true - assertEquals(input, it.getOrNull()) - } - - assertTrue(didCall) - } -} diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/InstanceManagerTest.kt b/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/InstanceManagerTest.kt new file mode 100644 index 000000000000..438ccfd1f444 --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/InstanceManagerTest.kt @@ -0,0 +1,129 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package com.example.test_plugin + +import junit.framework.TestCase.assertEquals +import junit.framework.TestCase.assertFalse +import junit.framework.TestCase.assertNotNull +import junit.framework.TestCase.assertNull +import junit.framework.TestCase.assertTrue +import org.junit.Test + +class InstanceManagerTest { + @Test + fun addDartCreatedInstance() { + val instanceManager: ProxyApiTestsPigeonInstanceManager = createInstanceManager() + val testObject = Any() + instanceManager.addDartCreatedInstance(testObject, 0) + + assertEquals(testObject, instanceManager.getInstance(0)) + assertEquals(0L, instanceManager.getIdentifierForStrongReference(testObject)) + assertTrue(instanceManager.containsInstance(testObject)) + + instanceManager.stopFinalizationListener() + } + + @Test + fun addHostCreatedInstance() { + val instanceManager: ProxyApiTestsPigeonInstanceManager = createInstanceManager() + val testObject = Any() + val identifier: Long = instanceManager.addHostCreatedInstance(testObject) + + assertNotNull(instanceManager.getInstance(identifier)) + assertEquals(testObject, instanceManager.getInstance(identifier)) + assertTrue(instanceManager.containsInstance(testObject)) + + instanceManager.stopFinalizationListener() + } + + @Test + fun remove() { + val instanceManager: ProxyApiTestsPigeonInstanceManager = createInstanceManager() + var testObject: Any? = Any() + instanceManager.addDartCreatedInstance(testObject!!, 0) + assertEquals(testObject, instanceManager.remove(0)) + + // To allow for object to be garbage collected. + @Suppress("UNUSED_VALUE") + testObject = null + Runtime.getRuntime().gc() + assertNull(instanceManager.getInstance(0)) + + instanceManager.stopFinalizationListener() + } + + @Test + fun clear() { + val instanceManager: ProxyApiTestsPigeonInstanceManager = createInstanceManager() + val instance = Any() + instanceManager.addDartCreatedInstance(instance, 0) + + assertTrue(instanceManager.containsInstance(instance)) + instanceManager.clear() + assertFalse(instanceManager.containsInstance(instance)) + + instanceManager.stopFinalizationListener() + } + + @Test + fun canAddSameObjectWithAddDartCreatedInstance() { + val instanceManager: ProxyApiTestsPigeonInstanceManager = createInstanceManager() + val instance = Any() + instanceManager.addDartCreatedInstance(instance, 0) + instanceManager.addDartCreatedInstance(instance, 1) + + assertTrue(instanceManager.containsInstance(instance)) + assertEquals(instanceManager.getInstance(0), instance) + assertEquals(instanceManager.getInstance(1), instance) + + instanceManager.stopFinalizationListener() + } + + @Test(expected = IllegalArgumentException::class) + fun cannotAddSameObjectsWithAddHostCreatedInstance() { + val instanceManager: ProxyApiTestsPigeonInstanceManager = createInstanceManager() + val instance = Any() + instanceManager.addHostCreatedInstance(instance) + instanceManager.addHostCreatedInstance(instance) + + instanceManager.stopFinalizationListener() + } + + @Test(expected = IllegalArgumentException::class) + fun cannotUseIdentifierLessThanZero() { + val instanceManager: ProxyApiTestsPigeonInstanceManager = createInstanceManager() + instanceManager.addDartCreatedInstance(Any(), -1) + instanceManager.stopFinalizationListener() + } + + @Test(expected = IllegalArgumentException::class) + fun identifiersMustBeUnique() { + val instanceManager: ProxyApiTestsPigeonInstanceManager = createInstanceManager() + instanceManager.addDartCreatedInstance(Any(), 0) + instanceManager.addDartCreatedInstance(Any(), 0) + + instanceManager.stopFinalizationListener() + } + + @Test + fun managerIsUsableWhileListenerHasStopped() { + val instanceManager: ProxyApiTestsPigeonInstanceManager = createInstanceManager() + instanceManager.stopFinalizationListener() + val instance = Any() + val identifier: Long = 0 + instanceManager.addDartCreatedInstance(instance, identifier) + + assertEquals(instanceManager.getInstance(identifier), instance) + assertEquals(instanceManager.getIdentifierForStrongReference(instance), identifier) + assertTrue(instanceManager.containsInstance(instance)) + } + + private fun createInstanceManager(): ProxyApiTestsPigeonInstanceManager { + return ProxyApiTestsPigeonInstanceManager.create( + object : ProxyApiTestsPigeonInstanceManager.PigeonFinalizationListener { + override fun onFinalize(identifier: Long) {} + }) + } +} diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/PrimitiveTest.kt b/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/PrimitiveTest.kt index 047c5b3c2196..5f496eb0d3d6 100644 --- a/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/PrimitiveTest.kt +++ b/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/PrimitiveTest.kt @@ -21,7 +21,7 @@ class PrimitiveTest { val binaryMessenger = mockk(relaxed = true) val api = mockk(relaxed = true) - val input = 1 + val input = 1L val channelName = "dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.anInt" val handlerSlot = slot() @@ -38,7 +38,7 @@ class PrimitiveTest { it?.rewind() @Suppress("UNCHECKED_CAST") val wrapped = codec.decodeMessage(it) as List? assertNotNull(wrapped) - wrapped?.let { assertEquals(input.toLong(), wrapped[0]) } + wrapped?.let { assertEquals(input, wrapped[0]) } } verify { binaryMessenger.setMessageHandler(channelName, handlerSlot.captured) } diff --git a/packages/pigeon/platform_tests/test_plugin/example/.gitignore b/packages/pigeon/platform_tests/test_plugin/example/.gitignore index 24476c5d1eb5..6c319542b342 100644 --- a/packages/pigeon/platform_tests/test_plugin/example/.gitignore +++ b/packages/pigeon/platform_tests/test_plugin/example/.gitignore @@ -5,9 +5,11 @@ *.swp .DS_Store .atom/ +.build/ .buildlog/ .history .svn/ +.swiftpm/ migrate_working_dir/ # IntelliJ related diff --git a/packages/pigeon/platform_tests/test_plugin/example/android/.gitignore b/packages/pigeon/platform_tests/test_plugin/example/android/.gitignore index 6f568019d3c6..55afd919c659 100644 --- a/packages/pigeon/platform_tests/test_plugin/example/android/.gitignore +++ b/packages/pigeon/platform_tests/test_plugin/example/android/.gitignore @@ -7,7 +7,7 @@ gradle-wrapper.jar GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. -# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +# See https://flutter.dev/to/reference-keystore key.properties **/*.keystore **/*.jks diff --git a/packages/pigeon/platform_tests/test_plugin/example/android/app/build.gradle b/packages/pigeon/platform_tests/test_plugin/example/android/app/build.gradle index 92b34cf1b3e7..3cba4a9ea20e 100644 --- a/packages/pigeon/platform_tests/test_plugin/example/android/app/build.gradle +++ b/packages/pigeon/platform_tests/test_plugin/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,22 +22,18 @@ 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 'com.example.test_plugin_example' compileSdk flutter.compileSdkVersion ndkVersion flutter.ndkVersion compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '11' } sourceSets { @@ -66,7 +63,3 @@ android { flutter { source '../..' } - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" -} diff --git a/packages/pigeon/platform_tests/test_plugin/example/android/build.gradle b/packages/pigeon/platform_tests/test_plugin/example/android/build.gradle index 14cf5d6d58df..aa651bee379b 100644 --- a/packages/pigeon/platform_tests/test_plugin/example/android/build.gradle +++ b/packages/pigeon/platform_tests/test_plugin/example/android/build.gradle @@ -1,16 +1,3 @@ -buildscript { - ext.kotlin_version = '1.7.10' - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' - 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/platform_tests/test_plugin/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/pigeon/platform_tests/test_plugin/example/android/gradle/wrapper/gradle-wrapper.properties index e1ca574ef017..3c85cfe057a1 100644 --- a/packages/pigeon/platform_tests/test_plugin/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/pigeon/platform_tests/test_plugin/example/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/pigeon/platform_tests/test_plugin/example/android/settings.gradle b/packages/pigeon/platform_tests/test_plugin/example/android/settings.gradle index f246a74091be..d056e4db3665 100644 --- a/packages/pigeon/platform_tests/test_plugin/example/android/settings.gradle +++ b/packages/pigeon/platform_tests/test_plugin/example/android/settings.gradle @@ -1,24 +1,27 @@ -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/platform_tests/test_plugin/example/integration_test/test.dart b/packages/pigeon/platform_tests/test_plugin/example/integration_test/test.dart index bfbe0b7085a6..535e39206dd8 100644 --- a/packages/pigeon/platform_tests/test_plugin/example/integration_test/test.dart +++ b/packages/pigeon/platform_tests/test_plugin/example/integration_test/test.dart @@ -15,6 +15,9 @@ TargetGenerator _getTarget() { if (Platform.isIOS || Platform.isMacOS) { return TargetGenerator.swift; } + if (Platform.isLinux) { + return TargetGenerator.gobject; + } if (Platform.isWindows) { return TargetGenerator.cpp; } diff --git a/packages/pigeon/platform_tests/test_plugin/example/ios/Podfile b/packages/pigeon/platform_tests/test_plugin/example/ios/Podfile index b2f29723d1a8..6f5730c5fed8 100644 --- a/packages/pigeon/platform_tests/test_plugin/example/ios/Podfile +++ b/packages/pigeon/platform_tests/test_plugin/example/ios/Podfile @@ -29,7 +29,6 @@ flutter_ios_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) diff --git a/packages/pigeon/platform_tests/test_plugin/example/ios/Runner.xcodeproj/project.pbxproj b/packages/pigeon/platform_tests/test_plugin/example/ios/Runner.xcodeproj/project.pbxproj index c0ccf06b3f23..ea266506b36d 100644 --- a/packages/pigeon/platform_tests/test_plugin/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/pigeon/platform_tests/test_plugin/example/ios/Runner.xcodeproj/project.pbxproj @@ -25,6 +25,7 @@ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 6885ADFFF3D912887C317B7C /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 786308B4AA81D1B6AA2FA10F /* Pods_Runner.framework */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 8F85C49D2BBB14F30053FB60 /* InstanceManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F85C49C2BBB14F30053FB60 /* InstanceManagerTests.swift */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; @@ -79,6 +80,7 @@ 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 786308B4AA81D1B6AA2FA10F /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 8F85C49C2BBB14F30053FB60 /* InstanceManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstanceManagerTests.swift; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -130,6 +132,7 @@ 33A341B7291ECCA100D34E0F /* RunnerTests.swift */, E04641F92A46270400661C9E /* NSNullFieldTests.swift */, 33A341CA291ECDFD00D34E0F /* Utils.swift */, + 8F85C49C2BBB14F30053FB60 /* InstanceManagerTests.swift */, ); path = RunnerTests; sourceTree = ""; @@ -407,6 +410,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 8F85C49D2BBB14F30053FB60 /* InstanceManagerTests.swift in Sources */, 33A341D0291ECDFD00D34E0F /* EchoBinaryMessenger.swift in Sources */, 33A341D3291ECDFD00D34E0F /* PrimitiveTests.swift in Sources */, 33A341D4291ECDFD00D34E0F /* HandlerBinaryMessenger.swift in Sources */, diff --git a/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/AllDatatypesTests.swift b/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/AllDatatypesTests.swift index 76877a809787..d35390a794cf 100644 --- a/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/AllDatatypesTests.swift +++ b/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/AllDatatypesTests.swift @@ -28,15 +28,15 @@ class AllDatatypesTests: XCTestCase { XCTAssertNil(res!.aNullable4ByteArray) XCTAssertNil(res!.aNullable8ByteArray) XCTAssertNil(res!.aNullableFloatArray) - XCTAssertNil(res!.nullableNestedList) - XCTAssertNil(res!.nullableMapWithAnnotations) - XCTAssertNil(res!.nullableMapWithObject) - XCTAssertNil(res!.map) XCTAssertNil(res!.list) XCTAssertNil(res!.boolList) XCTAssertNil(res!.intList) XCTAssertNil(res!.doubleList) XCTAssertNil(res!.stringList) + XCTAssertNil(res!.listList) + XCTAssertNil(res!.map) + XCTAssertNil(res!.stringMap) + XCTAssertNil(res!.intMap) expectation.fulfill() case .failure(_): return @@ -56,16 +56,21 @@ class AllDatatypesTests: XCTestCase { aNullable4ByteArray: FlutterStandardTypedData(int32: "1234".data(using: .utf8)!), aNullable8ByteArray: FlutterStandardTypedData(int64: "12345678".data(using: .utf8)!), aNullableFloatArray: FlutterStandardTypedData(float64: "12345678".data(using: .utf8)!), - nullableNestedList: [[true, false], [true]], - nullableMapWithAnnotations: ["hello": "world"], - nullableMapWithObject: ["hello": 1234, "goodbye": "world"], aNullableString: "123", list: ["string", 2], stringList: ["string", "another one"], intList: [1, 2], doubleList: [1.1, 2.2], boolList: [true, false], - map: ["hello": 1234] + objectList: ["string", 2], + listList: [[true], [false]], + mapList: [["hello": 1234], ["hello": 1234]], + map: ["hello": 1234], + stringMap: ["hello": "you"], + intMap: [1: 0], + objectMap: ["hello": 1234], + listMap: [1234: ["string", 2]], + mapMap: [1234: ["hello": 1234]] ) let binaryMessenger = EchoBinaryMessenger(codec: CoreTestsPigeonCodec.shared) @@ -85,15 +90,36 @@ class AllDatatypesTests: XCTestCase { XCTAssertEqual(res!.aNullable4ByteArray, everything.aNullable4ByteArray) XCTAssertEqual(res!.aNullable8ByteArray, everything.aNullable8ByteArray) XCTAssertEqual(res!.aNullableFloatArray, everything.aNullableFloatArray) - XCTAssertEqual(res!.nullableNestedList, everything.nullableNestedList) - XCTAssertEqual(res!.nullableMapWithAnnotations, everything.nullableMapWithAnnotations) - XCTAssert(equalsDictionary(res!.nullableMapWithObject, everything.nullableMapWithObject)) XCTAssert(equalsList(res!.list, everything.list)) XCTAssert(equalsList(res!.stringList, everything.stringList)) XCTAssert(equalsList(res!.intList, everything.intList)) XCTAssert(equalsList(res!.doubleList, everything.doubleList)) XCTAssert(equalsList(res!.boolList, everything.boolList)) + XCTAssert(equalsList(res!.objectList, everything.objectList)) + if res!.listList != nil { + for (index, list) in res!.listList!.enumerated() { + XCTAssert(equalsList(list, everything.listList![index])) + } + } + if res!.mapList != nil { + for (index, map) in res!.mapList!.enumerated() { + XCTAssert(equalsDictionary(map, everything.mapList![index])) + } + } XCTAssert(equalsDictionary(res!.map, everything.map)) + XCTAssert(equalsDictionary(res!.stringMap, everything.stringMap)) + XCTAssert(equalsDictionary(res!.intMap, everything.intMap)) + XCTAssert(equalsDictionary(res!.objectMap, everything.objectMap)) + if res!.listMap != nil { + for (index, list) in res!.listMap! { + XCTAssert(equalsList(list, everything.listMap![index]!)) + } + } + if res!.mapMap != nil { + for (index, map) in res!.mapMap! { + XCTAssert(equalsDictionary(map, everything.mapMap![index]!)) + } + } expectation.fulfill() return case .failure(_): diff --git a/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/InstanceManagerTests.swift b/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/InstanceManagerTests.swift new file mode 100644 index 000000000000..2031b078dbf8 --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/InstanceManagerTests.swift @@ -0,0 +1,143 @@ +// 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 Flutter +import XCTest + +@testable import test_plugin + +final class InstanceManagerTests: XCTestCase { + func testAddDartCreatedInstance() { + let finalizerDelegate = EmptyFinalizerDelegate() + let instanceManager = ProxyApiTestsPigeonInstanceManager(finalizerDelegate: finalizerDelegate) + let object = NSObject() + + instanceManager.addDartCreatedInstance(object, withIdentifier: 0) + XCTAssertEqual(instanceManager.instance(forIdentifier: 0), object) + XCTAssertEqual(instanceManager.identifierWithStrongReference(forInstance: object), 0) + } + + func testAddHostCreatedInstance() { + let finalizerDelegate = EmptyFinalizerDelegate() + let instanceManager = ProxyApiTestsPigeonInstanceManager(finalizerDelegate: finalizerDelegate) + let object = NSObject() + _ = instanceManager.addHostCreatedInstance(object) + + let identifier = instanceManager.identifierWithStrongReference(forInstance: object) + XCTAssertEqual(instanceManager.instance(forIdentifier: try XCTUnwrap(identifier)), object) + } + + func testRemoveInstance() { + let finalizerDelegate = EmptyFinalizerDelegate() + let instanceManager = ProxyApiTestsPigeonInstanceManager(finalizerDelegate: finalizerDelegate) + let object = NSObject() + + instanceManager.addDartCreatedInstance(object, withIdentifier: 0) + + XCTAssertEqual(try! instanceManager.removeInstance(withIdentifier: 0), object) + XCTAssertEqual(instanceManager.strongInstanceCount, 0) + } + + func testFinalizerCallsDelegateMethod() { + let finalizerDelegate = TestFinalizerDelegate() + + var object: NSObject? = NSObject() + ProxyApiTestsPigeonInternalFinalizer.attach( + to: object!, identifier: 0, delegate: finalizerDelegate) + + object = nil + XCTAssertEqual(finalizerDelegate.lastHandledIdentifier, 0) + } + + func testRemoveAllObjects() { + let finalizerDelegate = EmptyFinalizerDelegate() + let instanceManager = ProxyApiTestsPigeonInstanceManager(finalizerDelegate: finalizerDelegate) + let object = NSObject() + + instanceManager.addDartCreatedInstance(object, withIdentifier: 0) + try? instanceManager.removeAllObjects() + + XCTAssertEqual(instanceManager.strongInstanceCount, 0) + XCTAssertEqual(instanceManager.weakInstanceCount, 0) + } + + func testCanAddSameObjectWithAddDartCreatedInstance() { + let finalizerDelegate = EmptyFinalizerDelegate() + let instanceManager = ProxyApiTestsPigeonInstanceManager(finalizerDelegate: finalizerDelegate) + let object = NSObject() + + instanceManager.addDartCreatedInstance(object, withIdentifier: 0) + instanceManager.addDartCreatedInstance(object, withIdentifier: 1) + + let instance1: NSObject? = instanceManager.instance(forIdentifier: 0) + let instance2: NSObject? = instanceManager.instance(forIdentifier: 1) + + XCTAssertEqual(instance1, instance2) + } + + func testObjectsAreStoredWithPointerHashcode() { + let finalizerDelegate = EmptyFinalizerDelegate() + let instanceManager = ProxyApiTestsPigeonInstanceManager(finalizerDelegate: finalizerDelegate) + + class EquatableClass: Equatable { + static func == (lhs: EquatableClass, rhs: EquatableClass) -> Bool { + return true + } + } + + let instance1 = EquatableClass() + let instance2 = EquatableClass() + + // Ensure instances are considered equal. + XCTAssertTrue(instance1 == instance2) + + _ = instanceManager.addHostCreatedInstance(instance1) + _ = instanceManager.addHostCreatedInstance(instance2) + + XCTAssertNotEqual( + instanceManager.identifierWithStrongReference(forInstance: instance1), + instanceManager.identifierWithStrongReference(forInstance: instance2)) + } + + func testInstanceManagerCanBeDeallocated() { + let binaryMessenger = MockBinaryMessenger( + codec: FlutterStandardMessageCodec.sharedInstance()) + + var registrar: ProxyApiTestsPigeonProxyApiRegistrar? = ProxyApiTestsPigeonProxyApiRegistrar( + binaryMessenger: binaryMessenger, apiDelegate: ProxyApiDelegate()) + + // Add the scenario where the InstanceManager contains an instance that contains a ProxyApi implementation + class TestClass { + let api: PigeonApiProxyApiTestClass + + init(_ api: PigeonApiProxyApiTestClass) { + self.api = api + } + } + _ = registrar!.instanceManager.addHostCreatedInstance( + TestClass(registrar!.apiDelegate.pigeonApiProxyApiTestClass(registrar!))) + + registrar!.setUp() + registrar!.tearDown() + + let finalizerDelegate = TestFinalizerDelegate() + + ProxyApiTestsPigeonInternalFinalizer.attach( + to: registrar!.instanceManager, identifier: 0, delegate: finalizerDelegate) + registrar = nil + XCTAssertEqual(finalizerDelegate.lastHandledIdentifier, 0) + } +} + +class EmptyFinalizerDelegate: ProxyApiTestsPigeonInternalFinalizerDelegate { + func onDeinit(identifier: Int64) {} +} + +class TestFinalizerDelegate: ProxyApiTestsPigeonInternalFinalizerDelegate { + var lastHandledIdentifier: Int64? + + func onDeinit(identifier: Int64) { + lastHandledIdentifier = identifier + } +} diff --git a/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/PrimitiveTests.swift b/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/PrimitiveTests.swift index 2f99f45f1e91..71e98552277d 100644 --- a/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/PrimitiveTests.swift +++ b/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/PrimitiveTests.swift @@ -12,7 +12,7 @@ class MockPrimitiveHostApi: PrimitiveHostApi { func aBool(value: Bool) -> Bool { value } func aString(value: String) -> String { value } func aDouble(value: Double) -> Double { value } - func aMap(value: [AnyHashable: Any?]) -> [AnyHashable: Any?] { value } + func aMap(value: [AnyHashable?: Any?]) -> [AnyHashable?: Any?] { value } func aList(value: [Any?]) -> [Any?] { value } func anInt32List(value: FlutterStandardTypedData) -> FlutterStandardTypedData { value } func aBoolList(value: [Bool?]) -> [Bool?] { value } diff --git a/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/Utils.swift b/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/Utils.swift index c244147bede2..552fc83bf923 100644 --- a/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/Utils.swift +++ b/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/Utils.swift @@ -26,7 +26,7 @@ func equalsList(_ x: [Any?]?, _ y: [Any?]?) -> Bool { return (0.. Bool { +func equalsDictionary(_ x: [AnyHashable?: Any?]?, _ y: [AnyHashable?: Any?]?) -> Bool { if x == nil, y == nil { return true } diff --git a/packages/pigeon/platform_tests/test_plugin/example/linux/.gitignore b/packages/pigeon/platform_tests/test_plugin/example/linux/.gitignore new file mode 100644 index 000000000000..d3896c98444f --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/example/linux/.gitignore @@ -0,0 +1 @@ +flutter/ephemeral diff --git a/packages/pigeon/platform_tests/test_plugin/example/linux/CMakeLists.txt b/packages/pigeon/platform_tests/test_plugin/example/linux/CMakeLists.txt new file mode 100644 index 000000000000..972ceb58f205 --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/example/linux/CMakeLists.txt @@ -0,0 +1,151 @@ +# Project-level configuration. +cmake_minimum_required(VERSION 3.10) +project(runner LANGUAGES CXX) + +# The name of the executable created for the application. Change this to change +# the on-disk name of your application. +set(BINARY_NAME "test_plugin_example") + +# The unique GTK application identifier for this application. See: +# https://wiki.gnome.org/HowDoI/ChooseApplicationID +set(APPLICATION_ID "com.example.test_plugin") + +# Explicitly opt in to modern CMake behaviors to avoid warnings with recent +# versions of CMake. +cmake_policy(SET CMP0063 NEW) + +# Load bundled libraries from the lib/ directory relative to the binary. +set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") + +# Root filesystem for cross-building. +if(FLUTTER_TARGET_PLATFORM_SYSROOT) + set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) + set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +endif() + +# Define build configuration options. +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") +endif() + +# Compilation settings that should be applied to most targets. +# +# Be cautious about adding new options here, as plugins use this function by +# default. In most cases, you should add new options to specific targets instead +# of modifying this function. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_14) + target_compile_options(${TARGET} PRIVATE -Wall -Werror) + target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") + target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") +endfunction() + +# Enable the test target. +set(include_test_plugin_tests TRUE) + +# Flutter library and tool build rules. +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) + +add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") + +# Define the application target. To change its name, change BINARY_NAME above, +# not the value here, or `flutter run` will no longer work. +# +# Any new source files that you add to the application should be added here. +add_executable(${BINARY_NAME} + "main.cc" + "my_application.cc" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" +) + +# Apply the standard set of build settings. This can be removed for applications +# that need different build settings. +apply_standard_settings(${BINARY_NAME}) + +# Add dependency libraries. Add any application-specific dependencies here. +target_link_libraries(${BINARY_NAME} PRIVATE flutter) +target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) + +# Run the Flutter tool portions of the build. This must not be removed. +add_dependencies(${BINARY_NAME} flutter_assemble) + +# Only the install-generated bundle's copy of the executable will launch +# correctly, since the resources must in the right relative locations. To avoid +# people trying to run the unbundled copy, put it in a subdirectory instead of +# the default top-level location. +set_target_properties(${BINARY_NAME} + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" +) + +# Enable the test target. +set(include_test_plugin_tests TRUE) + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + +# === Installation === +# By default, "installing" just makes a relocatable bundle in the build +# directory. +set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") + +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +# Start with a clean build bundle directory every time. +install(CODE " + file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") + " COMPONENT Runtime) + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) + install(FILES "${bundled_library}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endforeach(bundled_library) + +# Copy the native assets provided by the build.dart from all packages. +set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/linux/") +install(DIRECTORY "${NATIVE_ASSETS_DIR}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") + install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() diff --git a/packages/pigeon/platform_tests/test_plugin/example/linux/flutter/CMakeLists.txt b/packages/pigeon/platform_tests/test_plugin/example/linux/flutter/CMakeLists.txt new file mode 100644 index 000000000000..d5bd01648a96 --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/example/linux/flutter/CMakeLists.txt @@ -0,0 +1,88 @@ +# This file controls Flutter-level build steps. It should not be edited. +cmake_minimum_required(VERSION 3.10) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. + +# Serves the same purpose as list(TRANSFORM ... PREPEND ...), +# which isn't available in 3.10. +function(list_prepend LIST_NAME PREFIX) + set(NEW_LIST "") + foreach(element ${${LIST_NAME}}) + list(APPEND NEW_LIST "${PREFIX}${element}") + endforeach(element) + set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) +endfunction() + +# === Flutter Library === +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) +pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) +pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) + +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "fl_basic_message_channel.h" + "fl_binary_codec.h" + "fl_binary_messenger.h" + "fl_dart_project.h" + "fl_engine.h" + "fl_json_message_codec.h" + "fl_json_method_codec.h" + "fl_message_codec.h" + "fl_method_call.h" + "fl_method_channel.h" + "fl_method_codec.h" + "fl_method_response.h" + "fl_plugin_registrar.h" + "fl_plugin_registry.h" + "fl_standard_message_codec.h" + "fl_standard_method_codec.h" + "fl_string_codec.h" + "fl_value.h" + "fl_view.h" + "flutter_linux.h" +) +list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") +target_link_libraries(flutter INTERFACE + PkgConfig::GTK + PkgConfig::GLIB + PkgConfig::GIO +) +add_dependencies(flutter flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CMAKE_CURRENT_BINARY_DIR}/_phony_ + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" + ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} +) diff --git a/packages/pigeon/platform_tests/test_plugin/example/linux/flutter/generated_plugins.cmake b/packages/pigeon/platform_tests/test_plugin/example/linux/flutter/generated_plugins.cmake new file mode 100644 index 000000000000..98e2c9fa93fd --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/example/linux/flutter/generated_plugins.cmake @@ -0,0 +1,24 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST + test_plugin +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/packages/pigeon/platform_tests/test_plugin/example/linux/main.cc b/packages/pigeon/platform_tests/test_plugin/example/linux/main.cc new file mode 100644 index 000000000000..1507d02825e7 --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/example/linux/main.cc @@ -0,0 +1,10 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "my_application.h" + +int main(int argc, char** argv) { + g_autoptr(MyApplication) app = my_application_new(); + return g_application_run(G_APPLICATION(app), argc, argv); +} diff --git a/packages/pigeon/platform_tests/test_plugin/example/linux/my_application.cc b/packages/pigeon/platform_tests/test_plugin/example/linux/my_application.cc new file mode 100644 index 000000000000..2c91863a8049 --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/example/linux/my_application.cc @@ -0,0 +1,131 @@ +// 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. + +#include "my_application.h" + +#include +#ifdef GDK_WINDOWING_X11 +#include +#endif + +#include "flutter/generated_plugin_registrant.h" + +struct _MyApplication { + GtkApplication parent_instance; + char** dart_entrypoint_arguments; +}; + +G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) + +// Implements GApplication::activate. +static void my_application_activate(GApplication* application) { + MyApplication* self = MY_APPLICATION(application); + GtkWindow* window = + GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); + + // Use a header bar when running in GNOME as this is the common style used + // by applications and is the setup most users will be using (e.g. Ubuntu + // desktop). + // If running on X and not using GNOME then just use a traditional title bar + // in case the window manager does more exotic layout, e.g. tiling. + // If running on Wayland assume the header bar will work (may need changing + // if future cases occur). + gboolean use_header_bar = TRUE; +#ifdef GDK_WINDOWING_X11 + GdkScreen* screen = gtk_window_get_screen(window); + if (GDK_IS_X11_SCREEN(screen)) { + const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); + if (g_strcmp0(wm_name, "GNOME Shell") != 0) { + use_header_bar = FALSE; + } + } +#endif + if (use_header_bar) { + GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); + gtk_widget_show(GTK_WIDGET(header_bar)); + gtk_header_bar_set_title(header_bar, "test_plugin_example"); + gtk_header_bar_set_show_close_button(header_bar, TRUE); + gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); + } else { + gtk_window_set_title(window, "test_plugin_example"); + } + + gtk_window_set_default_size(window, 1280, 720); + gtk_widget_show(GTK_WIDGET(window)); + + g_autoptr(FlDartProject) project = fl_dart_project_new(); + fl_dart_project_set_dart_entrypoint_arguments( + project, self->dart_entrypoint_arguments); + + FlView* view = fl_view_new(project); + gtk_widget_show(GTK_WIDGET(view)); + gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); + + fl_register_plugins(FL_PLUGIN_REGISTRY(view)); + + gtk_widget_grab_focus(GTK_WIDGET(view)); +} + +// Implements GApplication::local_command_line. +static gboolean my_application_local_command_line(GApplication* application, + gchar*** arguments, + int* exit_status) { + MyApplication* self = MY_APPLICATION(application); + // Strip out the first argument as it is the binary name. + self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); + + g_autoptr(GError) error = nullptr; + if (!g_application_register(application, nullptr, &error)) { + g_warning("Failed to register: %s", error->message); + *exit_status = 1; + return TRUE; + } + + g_application_activate(application); + *exit_status = 0; + + return TRUE; +} + +// Implements GApplication::startup. +static void my_application_startup(GApplication* application) { + // MyApplication* self = MY_APPLICATION(object); + + // Perform any actions required at application startup. + + G_APPLICATION_CLASS(my_application_parent_class)->startup(application); +} + +// Implements GApplication::shutdown. +static void my_application_shutdown(GApplication* application) { + // MyApplication* self = MY_APPLICATION(object); + + // Perform any actions required at application shutdown. + + G_APPLICATION_CLASS(my_application_parent_class)->shutdown(application); +} + +// Implements GObject::dispose. +static void my_application_dispose(GObject* object) { + MyApplication* self = MY_APPLICATION(object); + g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); + G_OBJECT_CLASS(my_application_parent_class)->dispose(object); +} + +static void my_application_class_init(MyApplicationClass* klass) { + G_APPLICATION_CLASS(klass)->activate = my_application_activate; + G_APPLICATION_CLASS(klass)->local_command_line = + my_application_local_command_line; + G_APPLICATION_CLASS(klass)->startup = my_application_startup; + G_APPLICATION_CLASS(klass)->shutdown = my_application_shutdown; + G_OBJECT_CLASS(klass)->dispose = my_application_dispose; +} + +static void my_application_init(MyApplication* self) {} + +MyApplication* my_application_new() { + return MY_APPLICATION(g_object_new(my_application_get_type(), + "application-id", APPLICATION_ID, "flags", + G_APPLICATION_NON_UNIQUE, nullptr)); +} diff --git a/packages/pigeon/platform_tests/test_plugin/example/linux/my_application.h b/packages/pigeon/platform_tests/test_plugin/example/linux/my_application.h new file mode 100644 index 000000000000..6e9f0c3ff665 --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/example/linux/my_application.h @@ -0,0 +1,22 @@ +// 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. + +#ifndef FLUTTER_MY_APPLICATION_H_ +#define FLUTTER_MY_APPLICATION_H_ + +#include + +G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, + GtkApplication) + +/** + * my_application_new: + * + * Creates a new Flutter-based application. + * + * Returns: a new #MyApplication. + */ +MyApplication* my_application_new(); + +#endif // FLUTTER_MY_APPLICATION_H_ diff --git a/packages/pigeon/platform_tests/test_plugin/example/macos/Podfile b/packages/pigeon/platform_tests/test_plugin/example/macos/Podfile index aca033923efb..71619503cdb0 100644 --- a/packages/pigeon/platform_tests/test_plugin/example/macos/Podfile +++ b/packages/pigeon/platform_tests/test_plugin/example/macos/Podfile @@ -28,7 +28,6 @@ flutter_macos_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) diff --git a/packages/pigeon/platform_tests/test_plugin/example/pubspec.yaml b/packages/pigeon/platform_tests/test_plugin/example/pubspec.yaml index 41f9074af62b..f37ef3a035f0 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.2.0 + sdk: ^3.3.0 dependencies: flutter: diff --git a/packages/pigeon/platform_tests/test_plugin/ios/Classes/.gitignore b/packages/pigeon/platform_tests/test_plugin/ios/Classes/.gitignore index 65eaa145c8ac..18ad850358d9 100644 --- a/packages/pigeon/platform_tests/test_plugin/ios/Classes/.gitignore +++ b/packages/pigeon/platform_tests/test_plugin/ios/Classes/.gitignore @@ -2,4 +2,8 @@ # changes on generated files. This will need a way to avoid unnecessary churn, # such as a flag to suppress version stamp generation. *.gen.swift -!CoreTests.gen.swift \ No newline at end of file +!CoreTests.gen.swift +# Keeping this makes it easier to review changes to ProxyApi generation. +!ProxyApiTests.gen.swift +# Contains the class declartions for testing ProxyApis. +!ProxyApiTestClass.swift diff --git a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift index 2b95f040b483..2b2001d6aa44 100644 --- a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift @@ -82,6 +82,29 @@ enum AnEnum: Int { case fourHundredTwentyTwo = 4 } +enum AnotherEnum: Int { + case justInCase = 0 +} + +/// Generated class from Pigeon that represents data sent in messages. +struct UnusedClass { + var aField: Any? = nil + + // swift-format-ignore: AlwaysUseLowerCamelCase + static func fromList(_ pigeonVar_list: [Any?]) -> UnusedClass? { + let aField: Any? = pigeonVar_list[0] + + return UnusedClass( + aField: aField + ) + } + func toList() -> [Any?] { + return [ + aField + ] + } +} + /// A class containing all supported types. /// /// Generated class from Pigeon that represents data sent in messages. @@ -95,36 +118,56 @@ struct AllTypes { var a8ByteArray: FlutterStandardTypedData var aFloatArray: FlutterStandardTypedData var anEnum: AnEnum + var anotherEnum: AnotherEnum var aString: String var anObject: Any var list: [Any?] - var stringList: [String?] - var intList: [Int64?] - var doubleList: [Double?] - var boolList: [Bool?] - var map: [AnyHashable: Any?] + var stringList: [String] + var intList: [Int64] + var doubleList: [Double] + var boolList: [Bool] + var enumList: [AnEnum] + var objectList: [Any] + var listList: [[Any?]] + var mapList: [[AnyHashable?: Any?]] + var map: [AnyHashable?: Any?] + var stringMap: [String: String] + var intMap: [Int64: Int64] + var enumMap: [AnEnum: AnEnum] + var objectMap: [AnyHashable: Any] + var listMap: [Int64: [Any?]] + var mapMap: [Int64: [AnyHashable?: Any?]] // swift-format-ignore: AlwaysUseLowerCamelCase - static func fromList(_ __pigeon_list: [Any?]) -> AllTypes? { - let aBool = __pigeon_list[0] as! Bool - let anInt = - __pigeon_list[1] is Int64 ? __pigeon_list[1] as! Int64 : Int64(__pigeon_list[1] as! Int32) - let anInt64 = - __pigeon_list[2] is Int64 ? __pigeon_list[2] as! Int64 : Int64(__pigeon_list[2] as! Int32) - let aDouble = __pigeon_list[3] as! Double - let aByteArray = __pigeon_list[4] as! FlutterStandardTypedData - let a4ByteArray = __pigeon_list[5] as! FlutterStandardTypedData - let a8ByteArray = __pigeon_list[6] as! FlutterStandardTypedData - let aFloatArray = __pigeon_list[7] as! FlutterStandardTypedData - let anEnum = __pigeon_list[8] as! AnEnum - let aString = __pigeon_list[9] as! String - let anObject = __pigeon_list[10]! - let list = __pigeon_list[11] as! [Any?] - let stringList = __pigeon_list[12] as! [String?] - let intList = __pigeon_list[13] as! [Int64?] - let doubleList = __pigeon_list[14] as! [Double?] - let boolList = __pigeon_list[15] as! [Bool?] - let map = __pigeon_list[16] as! [AnyHashable: Any?] + static func fromList(_ pigeonVar_list: [Any?]) -> AllTypes? { + let aBool = pigeonVar_list[0] as! Bool + let anInt = pigeonVar_list[1] as! Int64 + let anInt64 = pigeonVar_list[2] as! Int64 + let aDouble = pigeonVar_list[3] as! Double + let aByteArray = pigeonVar_list[4] as! FlutterStandardTypedData + let a4ByteArray = pigeonVar_list[5] as! FlutterStandardTypedData + let a8ByteArray = pigeonVar_list[6] as! FlutterStandardTypedData + let aFloatArray = pigeonVar_list[7] as! FlutterStandardTypedData + let anEnum = pigeonVar_list[8] as! AnEnum + let anotherEnum = pigeonVar_list[9] as! AnotherEnum + let aString = pigeonVar_list[10] as! String + let anObject = pigeonVar_list[11]! + let list = pigeonVar_list[12] as! [Any?] + let stringList = pigeonVar_list[13] as! [String] + let intList = pigeonVar_list[14] as! [Int64] + let doubleList = pigeonVar_list[15] as! [Double] + let boolList = pigeonVar_list[16] as! [Bool] + let enumList = pigeonVar_list[17] as! [AnEnum] + let objectList = pigeonVar_list[18] as! [Any] + let listList = pigeonVar_list[19] as! [[Any?]] + let mapList = pigeonVar_list[20] as! [[AnyHashable?: Any?]] + let map = pigeonVar_list[21] as! [AnyHashable?: Any?] + let stringMap = pigeonVar_list[22] as! [String: String] + let intMap = pigeonVar_list[23] as! [Int64: Int64] + let enumMap = pigeonVar_list[24] as? [AnEnum: AnEnum] + let objectMap = pigeonVar_list[25] as! [AnyHashable: Any] + let listMap = pigeonVar_list[26] as! [Int64: [Any?]] + let mapMap = pigeonVar_list[27] as! [Int64: [AnyHashable?: Any?]] return AllTypes( aBool: aBool, @@ -136,6 +179,7 @@ struct AllTypes { a8ByteArray: a8ByteArray, aFloatArray: aFloatArray, anEnum: anEnum, + anotherEnum: anotherEnum, aString: aString, anObject: anObject, list: list, @@ -143,7 +187,17 @@ struct AllTypes { intList: intList, doubleList: doubleList, boolList: boolList, - map: map + enumList: enumList, + objectList: objectList, + listList: listList, + mapList: mapList, + map: map, + stringMap: stringMap, + intMap: intMap, + enumMap: enumMap!, + objectMap: objectMap, + listMap: listMap, + mapMap: mapMap ) } func toList() -> [Any?] { @@ -157,6 +211,7 @@ struct AllTypes { a8ByteArray, aFloatArray, anEnum, + anotherEnum, aString, anObject, list, @@ -164,7 +219,17 @@ struct AllTypes { intList, doubleList, boolList, + enumList, + objectList, + listList, + mapList, map, + stringMap, + intMap, + enumMap, + objectMap, + listMap, + mapMap, ] } } @@ -182,10 +247,8 @@ class AllNullableTypes { aNullable4ByteArray: FlutterStandardTypedData? = nil, aNullable8ByteArray: FlutterStandardTypedData? = nil, aNullableFloatArray: FlutterStandardTypedData? = nil, - nullableNestedList: [[Bool?]?]? = nil, - nullableMapWithAnnotations: [String?: String?]? = nil, - nullableMapWithObject: [String?: Any?]? = nil, aNullableEnum: AnEnum? = nil, + anotherNullableEnum: AnotherEnum? = nil, aNullableString: String? = nil, aNullableObject: Any? = nil, allNullableTypes: AllNullableTypes? = nil, @@ -194,8 +257,19 @@ class AllNullableTypes { intList: [Int64?]? = nil, doubleList: [Double?]? = nil, boolList: [Bool?]? = nil, - nestedClassList: [AllNullableTypes?]? = nil, - map: [AnyHashable: Any?]? = nil + enumList: [AnEnum?]? = nil, + objectList: [Any?]? = nil, + listList: [[Any?]?]? = nil, + mapList: [[AnyHashable?: Any?]?]? = nil, + recursiveClassList: [AllNullableTypes?]? = nil, + map: [AnyHashable?: Any?]? = nil, + stringMap: [String?: String?]? = nil, + intMap: [Int64?: Int64?]? = nil, + enumMap: [AnEnum?: AnEnum?]? = nil, + objectMap: [AnyHashable?: Any?]? = nil, + listMap: [Int64?: [Any?]?]? = nil, + mapMap: [Int64?: [AnyHashable?: Any?]?]? = nil, + recursiveClassMap: [Int64?: AllNullableTypes?]? = nil ) { self.aNullableBool = aNullableBool self.aNullableInt = aNullableInt @@ -205,10 +279,8 @@ class AllNullableTypes { self.aNullable4ByteArray = aNullable4ByteArray self.aNullable8ByteArray = aNullable8ByteArray self.aNullableFloatArray = aNullableFloatArray - self.nullableNestedList = nullableNestedList - self.nullableMapWithAnnotations = nullableMapWithAnnotations - self.nullableMapWithObject = nullableMapWithObject self.aNullableEnum = aNullableEnum + self.anotherNullableEnum = anotherNullableEnum self.aNullableString = aNullableString self.aNullableObject = aNullableObject self.allNullableTypes = allNullableTypes @@ -217,8 +289,19 @@ class AllNullableTypes { self.intList = intList self.doubleList = doubleList self.boolList = boolList - self.nestedClassList = nestedClassList + self.enumList = enumList + self.objectList = objectList + self.listList = listList + self.mapList = mapList + self.recursiveClassList = recursiveClassList self.map = map + self.stringMap = stringMap + self.intMap = intMap + self.enumMap = enumMap + self.objectMap = objectMap + self.listMap = listMap + self.mapMap = mapMap + self.recursiveClassMap = recursiveClassMap } var aNullableBool: Bool? var aNullableInt: Int64? @@ -228,10 +311,8 @@ class AllNullableTypes { var aNullable4ByteArray: FlutterStandardTypedData? var aNullable8ByteArray: FlutterStandardTypedData? var aNullableFloatArray: FlutterStandardTypedData? - var nullableNestedList: [[Bool?]?]? - var nullableMapWithAnnotations: [String?: String?]? - var nullableMapWithObject: [String?: Any?]? var aNullableEnum: AnEnum? + var anotherNullableEnum: AnotherEnum? var aNullableString: String? var aNullableObject: Any? var allNullableTypes: AllNullableTypes? @@ -240,41 +321,53 @@ class AllNullableTypes { var intList: [Int64?]? var doubleList: [Double?]? var boolList: [Bool?]? - var nestedClassList: [AllNullableTypes?]? - var map: [AnyHashable: Any?]? + var enumList: [AnEnum?]? + var objectList: [Any?]? + var listList: [[Any?]?]? + var mapList: [[AnyHashable?: Any?]?]? + var recursiveClassList: [AllNullableTypes?]? + var map: [AnyHashable?: Any?]? + var stringMap: [String?: String?]? + var intMap: [Int64?: Int64?]? + var enumMap: [AnEnum?: AnEnum?]? + var objectMap: [AnyHashable?: Any?]? + var listMap: [Int64?: [Any?]?]? + var mapMap: [Int64?: [AnyHashable?: Any?]?]? + var recursiveClassMap: [Int64?: AllNullableTypes?]? // swift-format-ignore: AlwaysUseLowerCamelCase - static func fromList(_ __pigeon_list: [Any?]) -> AllNullableTypes? { - let aNullableBool: Bool? = nilOrValue(__pigeon_list[0]) - let aNullableInt: Int64? = - isNullish(__pigeon_list[1]) - ? nil - : (__pigeon_list[1] is Int64? - ? __pigeon_list[1] as! Int64? : Int64(__pigeon_list[1] as! Int32)) - let aNullableInt64: Int64? = - isNullish(__pigeon_list[2]) - ? nil - : (__pigeon_list[2] is Int64? - ? __pigeon_list[2] as! Int64? : Int64(__pigeon_list[2] as! Int32)) - let aNullableDouble: Double? = nilOrValue(__pigeon_list[3]) - let aNullableByteArray: FlutterStandardTypedData? = nilOrValue(__pigeon_list[4]) - let aNullable4ByteArray: FlutterStandardTypedData? = nilOrValue(__pigeon_list[5]) - let aNullable8ByteArray: FlutterStandardTypedData? = nilOrValue(__pigeon_list[6]) - let aNullableFloatArray: FlutterStandardTypedData? = nilOrValue(__pigeon_list[7]) - let nullableNestedList: [[Bool?]?]? = nilOrValue(__pigeon_list[8]) - let nullableMapWithAnnotations: [String?: String?]? = nilOrValue(__pigeon_list[9]) - let nullableMapWithObject: [String?: Any?]? = nilOrValue(__pigeon_list[10]) - let aNullableEnum: AnEnum? = nilOrValue(__pigeon_list[11]) - let aNullableString: String? = nilOrValue(__pigeon_list[12]) - let aNullableObject: Any? = __pigeon_list[13] - let allNullableTypes: AllNullableTypes? = nilOrValue(__pigeon_list[14]) - let list: [Any?]? = nilOrValue(__pigeon_list[15]) - let stringList: [String?]? = nilOrValue(__pigeon_list[16]) - let intList: [Int64?]? = nilOrValue(__pigeon_list[17]) - let doubleList: [Double?]? = nilOrValue(__pigeon_list[18]) - let boolList: [Bool?]? = nilOrValue(__pigeon_list[19]) - let nestedClassList: [AllNullableTypes?]? = nilOrValue(__pigeon_list[20]) - let map: [AnyHashable: Any?]? = nilOrValue(__pigeon_list[21]) + static func fromList(_ pigeonVar_list: [Any?]) -> AllNullableTypes? { + let aNullableBool: Bool? = nilOrValue(pigeonVar_list[0]) + let aNullableInt: Int64? = nilOrValue(pigeonVar_list[1]) + let aNullableInt64: Int64? = nilOrValue(pigeonVar_list[2]) + let aNullableDouble: Double? = nilOrValue(pigeonVar_list[3]) + let aNullableByteArray: FlutterStandardTypedData? = nilOrValue(pigeonVar_list[4]) + let aNullable4ByteArray: FlutterStandardTypedData? = nilOrValue(pigeonVar_list[5]) + let aNullable8ByteArray: FlutterStandardTypedData? = nilOrValue(pigeonVar_list[6]) + let aNullableFloatArray: FlutterStandardTypedData? = nilOrValue(pigeonVar_list[7]) + let aNullableEnum: AnEnum? = nilOrValue(pigeonVar_list[8]) + let anotherNullableEnum: AnotherEnum? = nilOrValue(pigeonVar_list[9]) + let aNullableString: String? = nilOrValue(pigeonVar_list[10]) + let aNullableObject: Any? = pigeonVar_list[11] + let allNullableTypes: AllNullableTypes? = nilOrValue(pigeonVar_list[12]) + let list: [Any?]? = nilOrValue(pigeonVar_list[13]) + let stringList: [String?]? = nilOrValue(pigeonVar_list[14]) + let intList: [Int64?]? = nilOrValue(pigeonVar_list[15]) + let doubleList: [Double?]? = nilOrValue(pigeonVar_list[16]) + let boolList: [Bool?]? = nilOrValue(pigeonVar_list[17]) + let enumList: [AnEnum?]? = nilOrValue(pigeonVar_list[18]) + let objectList: [Any?]? = nilOrValue(pigeonVar_list[19]) + let listList: [[Any?]?]? = nilOrValue(pigeonVar_list[20]) + let mapList: [[AnyHashable?: Any?]?]? = nilOrValue(pigeonVar_list[21]) + let recursiveClassList: [AllNullableTypes?]? = nilOrValue(pigeonVar_list[22]) + let map: [AnyHashable?: Any?]? = nilOrValue(pigeonVar_list[23]) + let stringMap: [String?: String?]? = nilOrValue(pigeonVar_list[24]) + let intMap: [Int64?: Int64?]? = nilOrValue(pigeonVar_list[25]) + let enumMap: [AnEnum?: AnEnum?]? = pigeonVar_list[26] as? [AnEnum?: AnEnum?] + let objectMap: [AnyHashable?: Any?]? = nilOrValue(pigeonVar_list[27]) + let listMap: [Int64?: [Any?]?]? = nilOrValue(pigeonVar_list[28]) + let mapMap: [Int64?: [AnyHashable?: Any?]?]? = nilOrValue(pigeonVar_list[29]) + let recursiveClassMap: [Int64?: AllNullableTypes?]? = nilOrValue(pigeonVar_list[30]) return AllNullableTypes( aNullableBool: aNullableBool, @@ -285,10 +378,8 @@ class AllNullableTypes { aNullable4ByteArray: aNullable4ByteArray, aNullable8ByteArray: aNullable8ByteArray, aNullableFloatArray: aNullableFloatArray, - nullableNestedList: nullableNestedList, - nullableMapWithAnnotations: nullableMapWithAnnotations, - nullableMapWithObject: nullableMapWithObject, aNullableEnum: aNullableEnum, + anotherNullableEnum: anotherNullableEnum, aNullableString: aNullableString, aNullableObject: aNullableObject, allNullableTypes: allNullableTypes, @@ -297,8 +388,19 @@ class AllNullableTypes { intList: intList, doubleList: doubleList, boolList: boolList, - nestedClassList: nestedClassList, - map: map + enumList: enumList, + objectList: objectList, + listList: listList, + mapList: mapList, + recursiveClassList: recursiveClassList, + map: map, + stringMap: stringMap, + intMap: intMap, + enumMap: enumMap, + objectMap: objectMap, + listMap: listMap, + mapMap: mapMap, + recursiveClassMap: recursiveClassMap ) } func toList() -> [Any?] { @@ -311,10 +413,8 @@ class AllNullableTypes { aNullable4ByteArray, aNullable8ByteArray, aNullableFloatArray, - nullableNestedList, - nullableMapWithAnnotations, - nullableMapWithObject, aNullableEnum, + anotherNullableEnum, aNullableString, aNullableObject, allNullableTypes, @@ -323,8 +423,19 @@ class AllNullableTypes { intList, doubleList, boolList, - nestedClassList, + enumList, + objectList, + listList, + mapList, + recursiveClassList, map, + stringMap, + intMap, + enumMap, + objectMap, + listMap, + mapMap, + recursiveClassMap, ] } } @@ -343,10 +454,8 @@ struct AllNullableTypesWithoutRecursion { var aNullable4ByteArray: FlutterStandardTypedData? = nil var aNullable8ByteArray: FlutterStandardTypedData? = nil var aNullableFloatArray: FlutterStandardTypedData? = nil - var nullableNestedList: [[Bool?]?]? = nil - var nullableMapWithAnnotations: [String?: String?]? = nil - var nullableMapWithObject: [String?: Any?]? = nil var aNullableEnum: AnEnum? = nil + var anotherNullableEnum: AnotherEnum? = nil var aNullableString: String? = nil var aNullableObject: Any? = nil var list: [Any?]? = nil @@ -354,38 +463,48 @@ struct AllNullableTypesWithoutRecursion { var intList: [Int64?]? = nil var doubleList: [Double?]? = nil var boolList: [Bool?]? = nil - var map: [AnyHashable: Any?]? = nil + var enumList: [AnEnum?]? = nil + var objectList: [Any?]? = nil + var listList: [[Any?]?]? = nil + var mapList: [[AnyHashable?: Any?]?]? = nil + var map: [AnyHashable?: Any?]? = nil + var stringMap: [String?: String?]? = nil + var intMap: [Int64?: Int64?]? = nil + var enumMap: [AnEnum?: AnEnum?]? = nil + var objectMap: [AnyHashable?: Any?]? = nil + var listMap: [Int64?: [Any?]?]? = nil + var mapMap: [Int64?: [AnyHashable?: Any?]?]? = nil // swift-format-ignore: AlwaysUseLowerCamelCase - static func fromList(_ __pigeon_list: [Any?]) -> AllNullableTypesWithoutRecursion? { - let aNullableBool: Bool? = nilOrValue(__pigeon_list[0]) - let aNullableInt: Int64? = - isNullish(__pigeon_list[1]) - ? nil - : (__pigeon_list[1] is Int64? - ? __pigeon_list[1] as! Int64? : Int64(__pigeon_list[1] as! Int32)) - let aNullableInt64: Int64? = - isNullish(__pigeon_list[2]) - ? nil - : (__pigeon_list[2] is Int64? - ? __pigeon_list[2] as! Int64? : Int64(__pigeon_list[2] as! Int32)) - let aNullableDouble: Double? = nilOrValue(__pigeon_list[3]) - let aNullableByteArray: FlutterStandardTypedData? = nilOrValue(__pigeon_list[4]) - let aNullable4ByteArray: FlutterStandardTypedData? = nilOrValue(__pigeon_list[5]) - let aNullable8ByteArray: FlutterStandardTypedData? = nilOrValue(__pigeon_list[6]) - let aNullableFloatArray: FlutterStandardTypedData? = nilOrValue(__pigeon_list[7]) - let nullableNestedList: [[Bool?]?]? = nilOrValue(__pigeon_list[8]) - let nullableMapWithAnnotations: [String?: String?]? = nilOrValue(__pigeon_list[9]) - let nullableMapWithObject: [String?: Any?]? = nilOrValue(__pigeon_list[10]) - let aNullableEnum: AnEnum? = nilOrValue(__pigeon_list[11]) - let aNullableString: String? = nilOrValue(__pigeon_list[12]) - let aNullableObject: Any? = __pigeon_list[13] - let list: [Any?]? = nilOrValue(__pigeon_list[14]) - let stringList: [String?]? = nilOrValue(__pigeon_list[15]) - let intList: [Int64?]? = nilOrValue(__pigeon_list[16]) - let doubleList: [Double?]? = nilOrValue(__pigeon_list[17]) - let boolList: [Bool?]? = nilOrValue(__pigeon_list[18]) - let map: [AnyHashable: Any?]? = nilOrValue(__pigeon_list[19]) + static func fromList(_ pigeonVar_list: [Any?]) -> AllNullableTypesWithoutRecursion? { + let aNullableBool: Bool? = nilOrValue(pigeonVar_list[0]) + let aNullableInt: Int64? = nilOrValue(pigeonVar_list[1]) + let aNullableInt64: Int64? = nilOrValue(pigeonVar_list[2]) + let aNullableDouble: Double? = nilOrValue(pigeonVar_list[3]) + let aNullableByteArray: FlutterStandardTypedData? = nilOrValue(pigeonVar_list[4]) + let aNullable4ByteArray: FlutterStandardTypedData? = nilOrValue(pigeonVar_list[5]) + let aNullable8ByteArray: FlutterStandardTypedData? = nilOrValue(pigeonVar_list[6]) + let aNullableFloatArray: FlutterStandardTypedData? = nilOrValue(pigeonVar_list[7]) + let aNullableEnum: AnEnum? = nilOrValue(pigeonVar_list[8]) + let anotherNullableEnum: AnotherEnum? = nilOrValue(pigeonVar_list[9]) + let aNullableString: String? = nilOrValue(pigeonVar_list[10]) + let aNullableObject: Any? = pigeonVar_list[11] + let list: [Any?]? = nilOrValue(pigeonVar_list[12]) + let stringList: [String?]? = nilOrValue(pigeonVar_list[13]) + let intList: [Int64?]? = nilOrValue(pigeonVar_list[14]) + let doubleList: [Double?]? = nilOrValue(pigeonVar_list[15]) + let boolList: [Bool?]? = nilOrValue(pigeonVar_list[16]) + let enumList: [AnEnum?]? = nilOrValue(pigeonVar_list[17]) + let objectList: [Any?]? = nilOrValue(pigeonVar_list[18]) + let listList: [[Any?]?]? = nilOrValue(pigeonVar_list[19]) + let mapList: [[AnyHashable?: Any?]?]? = nilOrValue(pigeonVar_list[20]) + let map: [AnyHashable?: Any?]? = nilOrValue(pigeonVar_list[21]) + let stringMap: [String?: String?]? = nilOrValue(pigeonVar_list[22]) + let intMap: [Int64?: Int64?]? = nilOrValue(pigeonVar_list[23]) + let enumMap: [AnEnum?: AnEnum?]? = pigeonVar_list[24] as? [AnEnum?: AnEnum?] + let objectMap: [AnyHashable?: Any?]? = nilOrValue(pigeonVar_list[25]) + let listMap: [Int64?: [Any?]?]? = nilOrValue(pigeonVar_list[26]) + let mapMap: [Int64?: [AnyHashable?: Any?]?]? = nilOrValue(pigeonVar_list[27]) return AllNullableTypesWithoutRecursion( aNullableBool: aNullableBool, @@ -396,10 +515,8 @@ struct AllNullableTypesWithoutRecursion { aNullable4ByteArray: aNullable4ByteArray, aNullable8ByteArray: aNullable8ByteArray, aNullableFloatArray: aNullableFloatArray, - nullableNestedList: nullableNestedList, - nullableMapWithAnnotations: nullableMapWithAnnotations, - nullableMapWithObject: nullableMapWithObject, aNullableEnum: aNullableEnum, + anotherNullableEnum: anotherNullableEnum, aNullableString: aNullableString, aNullableObject: aNullableObject, list: list, @@ -407,7 +524,17 @@ struct AllNullableTypesWithoutRecursion { intList: intList, doubleList: doubleList, boolList: boolList, - map: map + enumList: enumList, + objectList: objectList, + listList: listList, + mapList: mapList, + map: map, + stringMap: stringMap, + intMap: intMap, + enumMap: enumMap, + objectMap: objectMap, + listMap: listMap, + mapMap: mapMap ) } func toList() -> [Any?] { @@ -420,10 +547,8 @@ struct AllNullableTypesWithoutRecursion { aNullable4ByteArray, aNullable8ByteArray, aNullableFloatArray, - nullableNestedList, - nullableMapWithAnnotations, - nullableMapWithObject, aNullableEnum, + anotherNullableEnum, aNullableString, aNullableObject, list, @@ -431,7 +556,17 @@ struct AllNullableTypesWithoutRecursion { intList, doubleList, boolList, + enumList, + objectList, + listList, + mapList, map, + stringMap, + intMap, + enumMap, + objectMap, + listMap, + mapMap, ] } } @@ -447,18 +582,31 @@ struct AllClassesWrapper { var allNullableTypes: AllNullableTypes var allNullableTypesWithoutRecursion: AllNullableTypesWithoutRecursion? = nil var allTypes: AllTypes? = nil + var classList: [AllTypes?] + var nullableClassList: [AllNullableTypesWithoutRecursion?]? = nil + var classMap: [Int64?: AllTypes?] + var nullableClassMap: [Int64?: AllNullableTypesWithoutRecursion?]? = nil // swift-format-ignore: AlwaysUseLowerCamelCase - static func fromList(_ __pigeon_list: [Any?]) -> AllClassesWrapper? { - let allNullableTypes = __pigeon_list[0] as! AllNullableTypes + static func fromList(_ pigeonVar_list: [Any?]) -> AllClassesWrapper? { + let allNullableTypes = pigeonVar_list[0] as! AllNullableTypes let allNullableTypesWithoutRecursion: AllNullableTypesWithoutRecursion? = nilOrValue( - __pigeon_list[1]) - let allTypes: AllTypes? = nilOrValue(__pigeon_list[2]) + pigeonVar_list[1]) + let allTypes: AllTypes? = nilOrValue(pigeonVar_list[2]) + let classList = pigeonVar_list[3] as! [AllTypes?] + let nullableClassList: [AllNullableTypesWithoutRecursion?]? = nilOrValue(pigeonVar_list[4]) + let classMap = pigeonVar_list[5] as! [Int64?: AllTypes?] + let nullableClassMap: [Int64?: AllNullableTypesWithoutRecursion?]? = nilOrValue( + pigeonVar_list[6]) return AllClassesWrapper( allNullableTypes: allNullableTypes, allNullableTypesWithoutRecursion: allNullableTypesWithoutRecursion, - allTypes: allTypes + allTypes: allTypes, + classList: classList, + nullableClassList: nullableClassList, + classMap: classMap, + nullableClassMap: nullableClassMap ) } func toList() -> [Any?] { @@ -466,6 +614,10 @@ struct AllClassesWrapper { allNullableTypes, allNullableTypesWithoutRecursion, allTypes, + classList, + nullableClassList, + classMap, + nullableClassMap, ] } } @@ -477,8 +629,8 @@ struct TestMessage { var testList: [Any?]? = nil // swift-format-ignore: AlwaysUseLowerCamelCase - static func fromList(_ __pigeon_list: [Any?]) -> TestMessage? { - let testList: [Any?]? = nilOrValue(__pigeon_list[0]) + static func fromList(_ pigeonVar_list: [Any?]) -> TestMessage? { + let testList: [Any?]? = nilOrValue(pigeonVar_list[0]) return TestMessage( testList: testList @@ -490,26 +642,34 @@ struct TestMessage { ] } } + private class CoreTestsPigeonCodecReader: FlutterStandardReader { override func readValue(ofType type: UInt8) -> Any? { switch type { case 129: - return AllTypes.fromList(self.readValue() as! [Any?]) + let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?) + if let enumResultAsInt = enumResultAsInt { + return AnEnum(rawValue: enumResultAsInt) + } + return nil case 130: - return AllNullableTypes.fromList(self.readValue() as! [Any?]) + let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?) + if let enumResultAsInt = enumResultAsInt { + return AnotherEnum(rawValue: enumResultAsInt) + } + return nil case 131: - return AllNullableTypesWithoutRecursion.fromList(self.readValue() as! [Any?]) + return UnusedClass.fromList(self.readValue() as! [Any?]) case 132: - return AllClassesWrapper.fromList(self.readValue() as! [Any?]) + return AllTypes.fromList(self.readValue() as! [Any?]) case 133: - return TestMessage.fromList(self.readValue() as! [Any?]) + return AllNullableTypes.fromList(self.readValue() as! [Any?]) case 134: - var enumResult: AnEnum? = nil - let enumResultAsInt: Int? = nilOrValue(self.readValue() as? Int) - if let enumResultAsInt = enumResultAsInt { - enumResult = AnEnum(rawValue: enumResultAsInt) - } - return enumResult + return AllNullableTypesWithoutRecursion.fromList(self.readValue() as! [Any?]) + case 135: + return AllClassesWrapper.fromList(self.readValue() as! [Any?]) + case 136: + return TestMessage.fromList(self.readValue() as! [Any?]) default: return super.readValue(ofType: type) } @@ -518,24 +678,30 @@ private class CoreTestsPigeonCodecReader: FlutterStandardReader { private class CoreTestsPigeonCodecWriter: FlutterStandardWriter { override func writeValue(_ value: Any) { - if let value = value as? AllTypes { + if let value = value as? AnEnum { super.writeByte(129) + super.writeValue(value.rawValue) + } else if let value = value as? AnotherEnum { + super.writeByte(130) + super.writeValue(value.rawValue) + } else if let value = value as? UnusedClass { + super.writeByte(131) + super.writeValue(value.toList()) + } else if let value = value as? AllTypes { + super.writeByte(132) super.writeValue(value.toList()) } else if let value = value as? AllNullableTypes { - super.writeByte(130) + super.writeByte(133) super.writeValue(value.toList()) } else if let value = value as? AllNullableTypesWithoutRecursion { - super.writeByte(131) + super.writeByte(134) super.writeValue(value.toList()) } else if let value = value as? AllClassesWrapper { - super.writeByte(132) + super.writeByte(135) super.writeValue(value.toList()) } else if let value = value as? TestMessage { - super.writeByte(133) + super.writeByte(136) super.writeValue(value.toList()) - } else if let value = value as? AnEnum { - super.writeByte(134) - super.writeValue(value.rawValue) } else { super.writeValue(value) } @@ -586,12 +752,38 @@ protocol HostIntegrationCoreApi { func echo(_ anObject: Any) throws -> Any /// Returns the passed list, to test serialization and deserialization. func echo(_ list: [Any?]) throws -> [Any?] + /// Returns the passed list, to test serialization and deserialization. + func echo(enumList: [AnEnum?]) throws -> [AnEnum?] + /// Returns the passed list, to test serialization and deserialization. + func echo(classList: [AllNullableTypes?]) throws -> [AllNullableTypes?] + /// Returns the passed list, to test serialization and deserialization. + func echoNonNull(enumList: [AnEnum]) throws -> [AnEnum] + /// Returns the passed list, to test serialization and deserialization. + func echoNonNull(classList: [AllNullableTypes]) throws -> [AllNullableTypes] + /// Returns the passed map, to test serialization and deserialization. + func echo(_ map: [AnyHashable?: Any?]) throws -> [AnyHashable?: Any?] + /// Returns the passed map, to test serialization and deserialization. + func echo(stringMap: [String?: String?]) throws -> [String?: String?] + /// Returns the passed map, to test serialization and deserialization. + func echo(intMap: [Int64?: Int64?]) throws -> [Int64?: Int64?] + /// Returns the passed map, to test serialization and deserialization. + func echo(enumMap: [AnEnum?: AnEnum?]) throws -> [AnEnum?: AnEnum?] + /// Returns the passed map, to test serialization and deserialization. + func echo(classMap: [Int64?: AllNullableTypes?]) throws -> [Int64?: AllNullableTypes?] + /// Returns the passed map, to test serialization and deserialization. + func echoNonNull(stringMap: [String: String]) throws -> [String: String] + /// Returns the passed map, to test serialization and deserialization. + func echoNonNull(intMap: [Int64: Int64]) throws -> [Int64: Int64] /// Returns the passed map, to test serialization and deserialization. - func echo(_ aMap: [String?: Any?]) throws -> [String?: Any?] - /// Returns the passed map to test nested class serialization and deserialization. + func echoNonNull(enumMap: [AnEnum: AnEnum]) throws -> [AnEnum: AnEnum] + /// Returns the passed map, to test serialization and deserialization. + func echoNonNull(classMap: [Int64: AllNullableTypes]) throws -> [Int64: AllNullableTypes] + /// Returns the passed class to test nested class serialization and deserialization. func echo(_ wrapper: AllClassesWrapper) throws -> AllClassesWrapper /// Returns the passed enum to test serialization and deserialization. func echo(_ anEnum: AnEnum) throws -> AnEnum + /// Returns the passed enum to test serialization and deserialization. + func echo(_ anotherEnum: AnotherEnum) throws -> AnotherEnum /// Returns the default string. func echoNamedDefault(_ aString: String) throws -> String /// Returns passed in double. @@ -631,9 +823,35 @@ protocol HostIntegrationCoreApi { func echo(_ aNullableObject: Any?) throws -> Any? /// Returns the passed list, to test serialization and deserialization. func echoNullable(_ aNullableList: [Any?]?) throws -> [Any?]? + /// Returns the passed list, to test serialization and deserialization. + func echoNullable(enumList: [AnEnum?]?) throws -> [AnEnum?]? + /// Returns the passed list, to test serialization and deserialization. + func echoNullable(classList: [AllNullableTypes?]?) throws -> [AllNullableTypes?]? + /// Returns the passed list, to test serialization and deserialization. + func echoNullableNonNull(enumList: [AnEnum]?) throws -> [AnEnum]? + /// Returns the passed list, to test serialization and deserialization. + func echoNullableNonNull(classList: [AllNullableTypes]?) throws -> [AllNullableTypes]? + /// Returns the passed map, to test serialization and deserialization. + func echoNullable(_ map: [AnyHashable?: Any?]?) throws -> [AnyHashable?: Any?]? + /// Returns the passed map, to test serialization and deserialization. + func echoNullable(stringMap: [String?: String?]?) throws -> [String?: String?]? /// Returns the passed map, to test serialization and deserialization. - func echoNullable(_ aNullableMap: [String?: Any?]?) throws -> [String?: Any?]? + func echoNullable(intMap: [Int64?: Int64?]?) throws -> [Int64?: Int64?]? + /// Returns the passed map, to test serialization and deserialization. + func echoNullable(enumMap: [AnEnum?: AnEnum?]?) throws -> [AnEnum?: AnEnum?]? + /// Returns the passed map, to test serialization and deserialization. + func echoNullable(classMap: [Int64?: AllNullableTypes?]?) throws -> [Int64?: AllNullableTypes?]? + /// Returns the passed map, to test serialization and deserialization. + func echoNullableNonNull(stringMap: [String: String]?) throws -> [String: String]? + /// Returns the passed map, to test serialization and deserialization. + func echoNullableNonNull(intMap: [Int64: Int64]?) throws -> [Int64: Int64]? + /// Returns the passed map, to test serialization and deserialization. + func echoNullableNonNull(enumMap: [AnEnum: AnEnum]?) throws -> [AnEnum: AnEnum]? + /// Returns the passed map, to test serialization and deserialization. + func echoNullableNonNull(classMap: [Int64: AllNullableTypes]?) throws -> [Int64: + AllNullableTypes]? func echoNullable(_ anEnum: AnEnum?) throws -> AnEnum? + func echoNullable(_ anotherEnum: AnotherEnum?) throws -> AnotherEnum? /// Returns passed in int. func echoOptional(_ aNullableInt: Int64?) throws -> Int64? /// Returns the passed in string. @@ -657,11 +875,35 @@ protocol HostIntegrationCoreApi { func echoAsync(_ anObject: Any, completion: @escaping (Result) -> Void) /// Returns the passed list, to test asynchronous serialization and deserialization. func echoAsync(_ list: [Any?], completion: @escaping (Result<[Any?], Error>) -> Void) + /// Returns the passed list, to test asynchronous serialization and deserialization. + func echoAsync(enumList: [AnEnum?], completion: @escaping (Result<[AnEnum?], Error>) -> Void) + /// Returns the passed list, to test asynchronous serialization and deserialization. + func echoAsync( + classList: [AllNullableTypes?], + completion: @escaping (Result<[AllNullableTypes?], Error>) -> Void) + /// Returns the passed map, to test asynchronous serialization and deserialization. + func echoAsync( + _ map: [AnyHashable?: Any?], completion: @escaping (Result<[AnyHashable?: Any?], Error>) -> Void + ) + /// Returns the passed map, to test asynchronous serialization and deserialization. + func echoAsync( + stringMap: [String?: String?], completion: @escaping (Result<[String?: String?], Error>) -> Void + ) + /// Returns the passed map, to test asynchronous serialization and deserialization. + func echoAsync( + intMap: [Int64?: Int64?], completion: @escaping (Result<[Int64?: Int64?], Error>) -> Void) + /// Returns the passed map, to test asynchronous serialization and deserialization. + func echoAsync( + enumMap: [AnEnum?: AnEnum?], completion: @escaping (Result<[AnEnum?: AnEnum?], Error>) -> Void) /// Returns the passed map, to test asynchronous serialization and deserialization. func echoAsync( - _ aMap: [String?: Any?], completion: @escaping (Result<[String?: Any?], Error>) -> Void) + classMap: [Int64?: AllNullableTypes?], + completion: @escaping (Result<[Int64?: AllNullableTypes?], Error>) -> Void) /// Returns the passed enum, to test asynchronous serialization and deserialization. func echoAsync(_ anEnum: AnEnum, completion: @escaping (Result) -> Void) + /// Returns the passed enum, to test asynchronous serialization and deserialization. + func echoAsync( + _ anotherEnum: AnotherEnum, completion: @escaping (Result) -> Void) /// Responds with an error from an async function returning a value. func throwAsyncError(completion: @escaping (Result) -> Void) /// Responds with an error from an async void function. @@ -694,11 +936,37 @@ protocol HostIntegrationCoreApi { func echoAsyncNullable(_ anObject: Any?, completion: @escaping (Result) -> Void) /// Returns the passed list, to test asynchronous serialization and deserialization. func echoAsyncNullable(_ list: [Any?]?, completion: @escaping (Result<[Any?]?, Error>) -> Void) + /// Returns the passed list, to test asynchronous serialization and deserialization. + func echoAsyncNullable( + enumList: [AnEnum?]?, completion: @escaping (Result<[AnEnum?]?, Error>) -> Void) + /// Returns the passed list, to test asynchronous serialization and deserialization. + func echoAsyncNullable( + classList: [AllNullableTypes?]?, + completion: @escaping (Result<[AllNullableTypes?]?, Error>) -> Void) + /// Returns the passed map, to test asynchronous serialization and deserialization. + func echoAsyncNullable( + _ map: [AnyHashable?: Any?]?, + completion: @escaping (Result<[AnyHashable?: Any?]?, Error>) -> Void) + /// Returns the passed map, to test asynchronous serialization and deserialization. + func echoAsyncNullable( + stringMap: [String?: String?]?, + completion: @escaping (Result<[String?: String?]?, Error>) -> Void) + /// Returns the passed map, to test asynchronous serialization and deserialization. + func echoAsyncNullable( + intMap: [Int64?: Int64?]?, completion: @escaping (Result<[Int64?: Int64?]?, Error>) -> Void) + /// Returns the passed map, to test asynchronous serialization and deserialization. + func echoAsyncNullable( + enumMap: [AnEnum?: AnEnum?]?, completion: @escaping (Result<[AnEnum?: AnEnum?]?, Error>) -> Void + ) /// Returns the passed map, to test asynchronous serialization and deserialization. func echoAsyncNullable( - _ aMap: [String?: Any?]?, completion: @escaping (Result<[String?: Any?]?, Error>) -> Void) + classMap: [Int64?: AllNullableTypes?]?, + completion: @escaping (Result<[Int64?: AllNullableTypes?]?, Error>) -> Void) /// Returns the passed enum, to test asynchronous serialization and deserialization. func echoAsyncNullable(_ anEnum: AnEnum?, completion: @escaping (Result) -> Void) + /// Returns the passed enum, to test asynchronous serialization and deserialization. + func echoAsyncNullable( + _ anotherEnum: AnotherEnum?, completion: @escaping (Result) -> Void) func callFlutterNoop(completion: @escaping (Result) -> Void) func callFlutterThrowError(completion: @escaping (Result) -> Void) func callFlutterThrowErrorFromVoid(completion: @escaping (Result) -> Void) @@ -725,8 +993,40 @@ protocol HostIntegrationCoreApi { completion: @escaping (Result) -> Void) func callFlutterEcho(_ list: [Any?], completion: @escaping (Result<[Any?], Error>) -> Void) func callFlutterEcho( - _ aMap: [String?: Any?], completion: @escaping (Result<[String?: Any?], Error>) -> Void) + enumList: [AnEnum?], completion: @escaping (Result<[AnEnum?], Error>) -> Void) + func callFlutterEcho( + classList: [AllNullableTypes?], + completion: @escaping (Result<[AllNullableTypes?], Error>) -> Void) + func callFlutterEchoNonNull( + enumList: [AnEnum], completion: @escaping (Result<[AnEnum], Error>) -> Void) + func callFlutterEchoNonNull( + classList: [AllNullableTypes], completion: @escaping (Result<[AllNullableTypes], Error>) -> Void + ) + func callFlutterEcho( + _ map: [AnyHashable?: Any?], completion: @escaping (Result<[AnyHashable?: Any?], Error>) -> Void + ) + func callFlutterEcho( + stringMap: [String?: String?], completion: @escaping (Result<[String?: String?], Error>) -> Void + ) + func callFlutterEcho( + intMap: [Int64?: Int64?], completion: @escaping (Result<[Int64?: Int64?], Error>) -> Void) + func callFlutterEcho( + enumMap: [AnEnum?: AnEnum?], completion: @escaping (Result<[AnEnum?: AnEnum?], Error>) -> Void) + func callFlutterEcho( + classMap: [Int64?: AllNullableTypes?], + completion: @escaping (Result<[Int64?: AllNullableTypes?], Error>) -> Void) + func callFlutterEchoNonNull( + stringMap: [String: String], completion: @escaping (Result<[String: String], Error>) -> Void) + func callFlutterEchoNonNull( + intMap: [Int64: Int64], completion: @escaping (Result<[Int64: Int64], Error>) -> Void) + func callFlutterEchoNonNull( + enumMap: [AnEnum: AnEnum], completion: @escaping (Result<[AnEnum: AnEnum], Error>) -> Void) + func callFlutterEchoNonNull( + classMap: [Int64: AllNullableTypes], + completion: @escaping (Result<[Int64: AllNullableTypes], Error>) -> Void) func callFlutterEcho(_ anEnum: AnEnum, completion: @escaping (Result) -> Void) + func callFlutterEcho( + _ anotherEnum: AnotherEnum, completion: @escaping (Result) -> Void) func callFlutterEchoNullable(_ aBool: Bool?, completion: @escaping (Result) -> Void) func callFlutterEchoNullable( _ anInt: Int64?, completion: @escaping (Result) -> Void) @@ -740,9 +1040,42 @@ protocol HostIntegrationCoreApi { func callFlutterEchoNullable( _ list: [Any?]?, completion: @escaping (Result<[Any?]?, Error>) -> Void) func callFlutterEchoNullable( - _ aMap: [String?: Any?]?, completion: @escaping (Result<[String?: Any?]?, Error>) -> Void) - func callFlutterNullableEcho( + enumList: [AnEnum?]?, completion: @escaping (Result<[AnEnum?]?, Error>) -> Void) + func callFlutterEchoNullable( + classList: [AllNullableTypes?]?, + completion: @escaping (Result<[AllNullableTypes?]?, Error>) -> Void) + func callFlutterEchoNullableNonNull( + enumList: [AnEnum]?, completion: @escaping (Result<[AnEnum]?, Error>) -> Void) + func callFlutterEchoNullableNonNull( + classList: [AllNullableTypes]?, + completion: @escaping (Result<[AllNullableTypes]?, Error>) -> Void) + func callFlutterEchoNullable( + _ map: [AnyHashable?: Any?]?, + completion: @escaping (Result<[AnyHashable?: Any?]?, Error>) -> Void) + func callFlutterEchoNullable( + stringMap: [String?: String?]?, + completion: @escaping (Result<[String?: String?]?, Error>) -> Void) + func callFlutterEchoNullable( + intMap: [Int64?: Int64?]?, completion: @escaping (Result<[Int64?: Int64?]?, Error>) -> Void) + func callFlutterEchoNullable( + enumMap: [AnEnum?: AnEnum?]?, completion: @escaping (Result<[AnEnum?: AnEnum?]?, Error>) -> Void + ) + func callFlutterEchoNullable( + classMap: [Int64?: AllNullableTypes?]?, + completion: @escaping (Result<[Int64?: AllNullableTypes?]?, Error>) -> Void) + func callFlutterEchoNullableNonNull( + stringMap: [String: String]?, completion: @escaping (Result<[String: String]?, Error>) -> Void) + func callFlutterEchoNullableNonNull( + intMap: [Int64: Int64]?, completion: @escaping (Result<[Int64: Int64]?, Error>) -> Void) + func callFlutterEchoNullableNonNull( + enumMap: [AnEnum: AnEnum]?, completion: @escaping (Result<[AnEnum: AnEnum]?, Error>) -> Void) + func callFlutterEchoNullableNonNull( + classMap: [Int64: AllNullableTypes]?, + completion: @escaping (Result<[Int64: AllNullableTypes]?, Error>) -> Void) + func callFlutterEchoNullable( _ anEnum: AnEnum?, completion: @escaping (Result) -> Void) + func callFlutterEchoNullable( + _ anotherEnum: AnotherEnum?, completion: @escaping (Result) -> Void) func callFlutterSmallApiEcho( _ aString: String, completion: @escaping (Result) -> Void) } @@ -852,7 +1185,7 @@ class HostIntegrationCoreApiSetup { if let api = api { echoIntChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anIntArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + let anIntArg = args[0] as! Int64 do { let result = try api.echo(anIntArg) reply(wrapResult(result)) @@ -977,985 +1310,952 @@ class HostIntegrationCoreApiSetup { } else { echoListChannel.setMessageHandler(nil) } - /// Returns the passed map, to test serialization and deserialization. - let echoMapChannel = FlutterBasicMessageChannel( + /// Returns the passed list, to test serialization and deserialization. + let echoEnumListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoMap\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoEnumList\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoMapChannel.setMessageHandler { message, reply in + echoEnumListChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aMapArg = args[0] as! [String?: Any?] + let enumListArg = args[0] as! [AnEnum?] do { - let result = try api.echo(aMapArg) + let result = try api.echo(enumList: enumListArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoMapChannel.setMessageHandler(nil) + echoEnumListChannel.setMessageHandler(nil) } - /// Returns the passed map to test nested class serialization and deserialization. - let echoClassWrapperChannel = FlutterBasicMessageChannel( + /// Returns the passed list, to test serialization and deserialization. + let echoClassListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoClassWrapper\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoClassList\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoClassWrapperChannel.setMessageHandler { message, reply in + echoClassListChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let wrapperArg = args[0] as! AllClassesWrapper + let classListArg = args[0] as! [AllNullableTypes?] do { - let result = try api.echo(wrapperArg) + let result = try api.echo(classList: classListArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoClassWrapperChannel.setMessageHandler(nil) + echoClassListChannel.setMessageHandler(nil) } - /// Returns the passed enum to test serialization and deserialization. - let echoEnumChannel = FlutterBasicMessageChannel( + /// Returns the passed list, to test serialization and deserialization. + let echoNonNullEnumListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoEnum\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullEnumList\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoEnumChannel.setMessageHandler { message, reply in + echoNonNullEnumListChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anEnumArg = args[0] as! AnEnum + let enumListArg = args[0] as! [AnEnum] do { - let result = try api.echo(anEnumArg) + let result = try api.echoNonNull(enumList: enumListArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoEnumChannel.setMessageHandler(nil) + echoNonNullEnumListChannel.setMessageHandler(nil) } - /// Returns the default string. - let echoNamedDefaultStringChannel = FlutterBasicMessageChannel( + /// Returns the passed list, to test serialization and deserialization. + let echoNonNullClassListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNamedDefaultString\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullClassList\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoNamedDefaultStringChannel.setMessageHandler { message, reply in + echoNonNullClassListChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aStringArg = args[0] as! String + let classListArg = args[0] as! [AllNullableTypes] do { - let result = try api.echoNamedDefault(aStringArg) + let result = try api.echoNonNull(classList: classListArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoNamedDefaultStringChannel.setMessageHandler(nil) + echoNonNullClassListChannel.setMessageHandler(nil) } - /// Returns passed in double. - let echoOptionalDefaultDoubleChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoOptionalDefaultDouble\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoOptionalDefaultDoubleChannel.setMessageHandler { message, reply in + echoMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aDoubleArg = args[0] as! Double + let mapArg = args[0] as! [AnyHashable?: Any?] do { - let result = try api.echoOptionalDefault(aDoubleArg) + let result = try api.echo(mapArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoOptionalDefaultDoubleChannel.setMessageHandler(nil) + echoMapChannel.setMessageHandler(nil) } - /// Returns passed in int. - let echoRequiredIntChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoStringMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoRequiredInt\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoStringMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoRequiredIntChannel.setMessageHandler { message, reply in + echoStringMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anIntArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + let stringMapArg = args[0] as! [String?: String?] do { - let result = try api.echoRequired(anIntArg) + let result = try api.echo(stringMap: stringMapArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoRequiredIntChannel.setMessageHandler(nil) + echoStringMapChannel.setMessageHandler(nil) } - /// Returns the passed object, to test serialization and deserialization. - let echoAllNullableTypesChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoIntMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypes\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoIntMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAllNullableTypesChannel.setMessageHandler { message, reply in + echoIntMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let everythingArg: AllNullableTypes? = nilOrValue(args[0]) + let intMapArg = args[0] as! [Int64?: Int64?] do { - let result = try api.echo(everythingArg) + let result = try api.echo(intMap: intMapArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoAllNullableTypesChannel.setMessageHandler(nil) + echoIntMapChannel.setMessageHandler(nil) } - /// Returns the passed object, to test serialization and deserialization. - let echoAllNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoEnumMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypesWithoutRecursion\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoEnumMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAllNullableTypesWithoutRecursionChannel.setMessageHandler { message, reply in + echoEnumMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let everythingArg: AllNullableTypesWithoutRecursion? = nilOrValue(args[0]) + let enumMapArg = args[0] as? [AnEnum?: AnEnum?] do { - let result = try api.echo(everythingArg) + let result = try api.echo(enumMap: enumMapArg!) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoAllNullableTypesWithoutRecursionChannel.setMessageHandler(nil) + echoEnumMapChannel.setMessageHandler(nil) } - /// Returns the inner `aString` value from the wrapped object, to test - /// sending of nested objects. - let extractNestedNullableStringChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoClassMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.extractNestedNullableString\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoClassMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - extractNestedNullableStringChannel.setMessageHandler { message, reply in + echoClassMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let wrapperArg = args[0] as! AllClassesWrapper + let classMapArg = args[0] as! [Int64?: AllNullableTypes?] do { - let result = try api.extractNestedNullableString(from: wrapperArg) + let result = try api.echo(classMap: classMapArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - extractNestedNullableStringChannel.setMessageHandler(nil) + echoClassMapChannel.setMessageHandler(nil) } - /// Returns the inner `aString` value from the wrapped object, to test - /// sending of nested objects. - let createNestedNullableStringChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNonNullStringMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.createNestedNullableString\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullStringMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - createNestedNullableStringChannel.setMessageHandler { message, reply in + echoNonNullStringMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let nullableStringArg: String? = nilOrValue(args[0]) + let stringMapArg = args[0] as! [String: String] do { - let result = try api.createNestedObject(with: nullableStringArg) + let result = try api.echoNonNull(stringMap: stringMapArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - createNestedNullableStringChannel.setMessageHandler(nil) + echoNonNullStringMapChannel.setMessageHandler(nil) } - /// Returns passed in arguments of multiple types. - let sendMultipleNullableTypesChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNonNullIntMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypes\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullIntMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - sendMultipleNullableTypesChannel.setMessageHandler { message, reply in + echoNonNullIntMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableBoolArg: Bool? = nilOrValue(args[0]) - let aNullableIntArg: Int64? = - isNullish(args[1]) - ? nil : (args[1] is Int64? ? args[1] as! Int64? : Int64(args[1] as! Int32)) - let aNullableStringArg: String? = nilOrValue(args[2]) + let intMapArg = args[0] as! [Int64: Int64] do { - let result = try api.sendMultipleNullableTypes( - aBool: aNullableBoolArg, anInt: aNullableIntArg, aString: aNullableStringArg) + let result = try api.echoNonNull(intMap: intMapArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - sendMultipleNullableTypesChannel.setMessageHandler(nil) + echoNonNullIntMapChannel.setMessageHandler(nil) } - /// Returns passed in arguments of multiple types. - let sendMultipleNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNonNullEnumMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullEnumMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - sendMultipleNullableTypesWithoutRecursionChannel.setMessageHandler { message, reply in + echoNonNullEnumMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableBoolArg: Bool? = nilOrValue(args[0]) - let aNullableIntArg: Int64? = - isNullish(args[1]) - ? nil : (args[1] is Int64? ? args[1] as! Int64? : Int64(args[1] as! Int32)) - let aNullableStringArg: String? = nilOrValue(args[2]) + let enumMapArg = args[0] as? [AnEnum: AnEnum] do { - let result = try api.sendMultipleNullableTypesWithoutRecursion( - aBool: aNullableBoolArg, anInt: aNullableIntArg, aString: aNullableStringArg) + let result = try api.echoNonNull(enumMap: enumMapArg!) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - sendMultipleNullableTypesWithoutRecursionChannel.setMessageHandler(nil) + echoNonNullEnumMapChannel.setMessageHandler(nil) } - /// Returns passed in int. - let echoNullableIntChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNonNullClassMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableInt\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullClassMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoNullableIntChannel.setMessageHandler { message, reply in + echoNonNullClassMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableIntArg: Int64? = - isNullish(args[0]) - ? nil : (args[0] is Int64? ? args[0] as! Int64? : Int64(args[0] as! Int32)) + let classMapArg = args[0] as! [Int64: AllNullableTypes] do { - let result = try api.echo(aNullableIntArg) + let result = try api.echoNonNull(classMap: classMapArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoNullableIntChannel.setMessageHandler(nil) + echoNonNullClassMapChannel.setMessageHandler(nil) } - /// Returns passed in double. - let echoNullableDoubleChannel = FlutterBasicMessageChannel( + /// Returns the passed class to test nested class serialization and deserialization. + let echoClassWrapperChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableDouble\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoClassWrapper\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoNullableDoubleChannel.setMessageHandler { message, reply in + echoClassWrapperChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableDoubleArg: Double? = nilOrValue(args[0]) + let wrapperArg = args[0] as! AllClassesWrapper do { - let result = try api.echo(aNullableDoubleArg) + let result = try api.echo(wrapperArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoNullableDoubleChannel.setMessageHandler(nil) + echoClassWrapperChannel.setMessageHandler(nil) } - /// Returns the passed in boolean. - let echoNullableBoolChannel = FlutterBasicMessageChannel( + /// Returns the passed enum to test serialization and deserialization. + let echoEnumChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableBool\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoEnum\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoNullableBoolChannel.setMessageHandler { message, reply in + echoEnumChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableBoolArg: Bool? = nilOrValue(args[0]) + let anEnumArg = args[0] as! AnEnum do { - let result = try api.echo(aNullableBoolArg) + let result = try api.echo(anEnumArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoNullableBoolChannel.setMessageHandler(nil) + echoEnumChannel.setMessageHandler(nil) } - /// Returns the passed in string. - let echoNullableStringChannel = FlutterBasicMessageChannel( + /// Returns the passed enum to test serialization and deserialization. + let echoAnotherEnumChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableString\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAnotherEnum\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoNullableStringChannel.setMessageHandler { message, reply in + echoAnotherEnumChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableStringArg: String? = nilOrValue(args[0]) + let anotherEnumArg = args[0] as! AnotherEnum do { - let result = try api.echo(aNullableStringArg) + let result = try api.echo(anotherEnumArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoNullableStringChannel.setMessageHandler(nil) + echoAnotherEnumChannel.setMessageHandler(nil) } - /// Returns the passed in Uint8List. - let echoNullableUint8ListChannel = FlutterBasicMessageChannel( + /// Returns the default string. + let echoNamedDefaultStringChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableUint8List\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNamedDefaultString\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoNullableUint8ListChannel.setMessageHandler { message, reply in + echoNamedDefaultStringChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableUint8ListArg: FlutterStandardTypedData? = nilOrValue(args[0]) + let aStringArg = args[0] as! String do { - let result = try api.echo(aNullableUint8ListArg) + let result = try api.echoNamedDefault(aStringArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoNullableUint8ListChannel.setMessageHandler(nil) + echoNamedDefaultStringChannel.setMessageHandler(nil) } - /// Returns the passed in generic Object. - let echoNullableObjectChannel = FlutterBasicMessageChannel( + /// Returns passed in double. + let echoOptionalDefaultDoubleChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableObject\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoOptionalDefaultDouble\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoNullableObjectChannel.setMessageHandler { message, reply in + echoOptionalDefaultDoubleChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableObjectArg: Any? = args[0] + let aDoubleArg = args[0] as! Double do { - let result = try api.echo(aNullableObjectArg) + let result = try api.echoOptionalDefault(aDoubleArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoNullableObjectChannel.setMessageHandler(nil) + echoOptionalDefaultDoubleChannel.setMessageHandler(nil) } - /// Returns the passed list, to test serialization and deserialization. - let echoNullableListChannel = FlutterBasicMessageChannel( + /// Returns passed in int. + let echoRequiredIntChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableList\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoRequiredInt\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoNullableListChannel.setMessageHandler { message, reply in + echoRequiredIntChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableListArg: [Any?]? = nilOrValue(args[0]) + let anIntArg = args[0] as! Int64 do { - let result = try api.echoNullable(aNullableListArg) + let result = try api.echoRequired(anIntArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoNullableListChannel.setMessageHandler(nil) + echoRequiredIntChannel.setMessageHandler(nil) } - /// Returns the passed map, to test serialization and deserialization. - let echoNullableMapChannel = FlutterBasicMessageChannel( + /// Returns the passed object, to test serialization and deserialization. + let echoAllNullableTypesChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableMap\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypes\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoNullableMapChannel.setMessageHandler { message, reply in + echoAllNullableTypesChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableMapArg: [String?: Any?]? = nilOrValue(args[0]) + let everythingArg: AllNullableTypes? = nilOrValue(args[0]) do { - let result = try api.echoNullable(aNullableMapArg) + let result = try api.echo(everythingArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoNullableMapChannel.setMessageHandler(nil) + echoAllNullableTypesChannel.setMessageHandler(nil) } - let echoNullableEnumChannel = FlutterBasicMessageChannel( + /// Returns the passed object, to test serialization and deserialization. + let echoAllNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableEnum\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypesWithoutRecursion\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoNullableEnumChannel.setMessageHandler { message, reply in + echoAllNullableTypesWithoutRecursionChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anEnumArg: AnEnum? = nilOrValue(args[0]) + let everythingArg: AllNullableTypesWithoutRecursion? = nilOrValue(args[0]) do { - let result = try api.echoNullable(anEnumArg) + let result = try api.echo(everythingArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoNullableEnumChannel.setMessageHandler(nil) + echoAllNullableTypesWithoutRecursionChannel.setMessageHandler(nil) } - /// Returns passed in int. - let echoOptionalNullableIntChannel = FlutterBasicMessageChannel( + /// Returns the inner `aString` value from the wrapped object, to test + /// sending of nested objects. + let extractNestedNullableStringChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoOptionalNullableInt\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.extractNestedNullableString\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoOptionalNullableIntChannel.setMessageHandler { message, reply in + extractNestedNullableStringChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableIntArg: Int64? = - isNullish(args[0]) - ? nil : (args[0] is Int64? ? args[0] as! Int64? : Int64(args[0] as! Int32)) + let wrapperArg = args[0] as! AllClassesWrapper do { - let result = try api.echoOptional(aNullableIntArg) + let result = try api.extractNestedNullableString(from: wrapperArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoOptionalNullableIntChannel.setMessageHandler(nil) + extractNestedNullableStringChannel.setMessageHandler(nil) } - /// Returns the passed in string. - let echoNamedNullableStringChannel = FlutterBasicMessageChannel( + /// Returns the inner `aString` value from the wrapped object, to test + /// sending of nested objects. + let createNestedNullableStringChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNamedNullableString\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.createNestedNullableString\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoNamedNullableStringChannel.setMessageHandler { message, reply in + createNestedNullableStringChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableStringArg: String? = nilOrValue(args[0]) + let nullableStringArg: String? = nilOrValue(args[0]) do { - let result = try api.echoNamed(aNullableStringArg) + let result = try api.createNestedObject(with: nullableStringArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoNamedNullableStringChannel.setMessageHandler(nil) + createNestedNullableStringChannel.setMessageHandler(nil) } - /// A no-op function taking no arguments and returning no value, to sanity - /// test basic asynchronous calling. - let noopAsyncChannel = FlutterBasicMessageChannel( + /// Returns passed in arguments of multiple types. + let sendMultipleNullableTypesChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.noopAsync\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypes\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - noopAsyncChannel.setMessageHandler { _, reply in - api.noopAsync { result in - switch result { - case .success: - reply(wrapResult(nil)) - case .failure(let error): - reply(wrapError(error)) - } + sendMultipleNullableTypesChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aNullableBoolArg: Bool? = nilOrValue(args[0]) + let aNullableIntArg: Int64? = nilOrValue(args[1]) + let aNullableStringArg: String? = nilOrValue(args[2]) + do { + let result = try api.sendMultipleNullableTypes( + aBool: aNullableBoolArg, anInt: aNullableIntArg, aString: aNullableStringArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - noopAsyncChannel.setMessageHandler(nil) + sendMultipleNullableTypesChannel.setMessageHandler(nil) } - /// Returns passed in int asynchronously. - let echoAsyncIntChannel = FlutterBasicMessageChannel( + /// Returns passed in arguments of multiple types. + let sendMultipleNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncInt\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncIntChannel.setMessageHandler { message, reply in + sendMultipleNullableTypesWithoutRecursionChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anIntArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) - api.echoAsync(anIntArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let aNullableBoolArg: Bool? = nilOrValue(args[0]) + let aNullableIntArg: Int64? = nilOrValue(args[1]) + let aNullableStringArg: String? = nilOrValue(args[2]) + do { + let result = try api.sendMultipleNullableTypesWithoutRecursion( + aBool: aNullableBoolArg, anInt: aNullableIntArg, aString: aNullableStringArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncIntChannel.setMessageHandler(nil) + sendMultipleNullableTypesWithoutRecursionChannel.setMessageHandler(nil) } - /// Returns passed in double asynchronously. - let echoAsyncDoubleChannel = FlutterBasicMessageChannel( + /// Returns passed in int. + let echoNullableIntChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncDouble\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableInt\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncDoubleChannel.setMessageHandler { message, reply in + echoNullableIntChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aDoubleArg = args[0] as! Double - api.echoAsync(aDoubleArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let aNullableIntArg: Int64? = nilOrValue(args[0]) + do { + let result = try api.echo(aNullableIntArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncDoubleChannel.setMessageHandler(nil) + echoNullableIntChannel.setMessageHandler(nil) } - /// Returns the passed in boolean asynchronously. - let echoAsyncBoolChannel = FlutterBasicMessageChannel( + /// Returns passed in double. + let echoNullableDoubleChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncBool\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableDouble\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncBoolChannel.setMessageHandler { message, reply in + echoNullableDoubleChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aBoolArg = args[0] as! Bool - api.echoAsync(aBoolArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let aNullableDoubleArg: Double? = nilOrValue(args[0]) + do { + let result = try api.echo(aNullableDoubleArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncBoolChannel.setMessageHandler(nil) + echoNullableDoubleChannel.setMessageHandler(nil) } - /// Returns the passed string asynchronously. - let echoAsyncStringChannel = FlutterBasicMessageChannel( + /// Returns the passed in boolean. + let echoNullableBoolChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncString\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableBool\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncStringChannel.setMessageHandler { message, reply in + echoNullableBoolChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aStringArg = args[0] as! String - api.echoAsync(aStringArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let aNullableBoolArg: Bool? = nilOrValue(args[0]) + do { + let result = try api.echo(aNullableBoolArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncStringChannel.setMessageHandler(nil) + echoNullableBoolChannel.setMessageHandler(nil) } - /// Returns the passed in Uint8List asynchronously. - let echoAsyncUint8ListChannel = FlutterBasicMessageChannel( + /// Returns the passed in string. + let echoNullableStringChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncUint8List\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableString\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncUint8ListChannel.setMessageHandler { message, reply in + echoNullableStringChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aUint8ListArg = args[0] as! FlutterStandardTypedData - api.echoAsync(aUint8ListArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let aNullableStringArg: String? = nilOrValue(args[0]) + do { + let result = try api.echo(aNullableStringArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncUint8ListChannel.setMessageHandler(nil) + echoNullableStringChannel.setMessageHandler(nil) } - /// Returns the passed in generic Object asynchronously. - let echoAsyncObjectChannel = FlutterBasicMessageChannel( + /// Returns the passed in Uint8List. + let echoNullableUint8ListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncObject\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableUint8List\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncObjectChannel.setMessageHandler { message, reply in + echoNullableUint8ListChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anObjectArg = args[0]! - api.echoAsync(anObjectArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let aNullableUint8ListArg: FlutterStandardTypedData? = nilOrValue(args[0]) + do { + let result = try api.echo(aNullableUint8ListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncObjectChannel.setMessageHandler(nil) + echoNullableUint8ListChannel.setMessageHandler(nil) } - /// Returns the passed list, to test asynchronous serialization and deserialization. - let echoAsyncListChannel = FlutterBasicMessageChannel( + /// Returns the passed in generic Object. + let echoNullableObjectChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncList\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableObject\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncListChannel.setMessageHandler { message, reply in + echoNullableObjectChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let listArg = args[0] as! [Any?] - api.echoAsync(listArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let aNullableObjectArg: Any? = args[0] + do { + let result = try api.echo(aNullableObjectArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncListChannel.setMessageHandler(nil) + echoNullableObjectChannel.setMessageHandler(nil) } - /// Returns the passed map, to test asynchronous serialization and deserialization. - let echoAsyncMapChannel = FlutterBasicMessageChannel( + /// Returns the passed list, to test serialization and deserialization. + let echoNullableListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncMap\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableList\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncMapChannel.setMessageHandler { message, reply in + echoNullableListChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aMapArg = args[0] as! [String?: Any?] - api.echoAsync(aMapArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let aNullableListArg: [Any?]? = nilOrValue(args[0]) + do { + let result = try api.echoNullable(aNullableListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncMapChannel.setMessageHandler(nil) + echoNullableListChannel.setMessageHandler(nil) } - /// Returns the passed enum, to test asynchronous serialization and deserialization. - let echoAsyncEnumChannel = FlutterBasicMessageChannel( + /// Returns the passed list, to test serialization and deserialization. + let echoNullableEnumListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncEnum\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableEnumList\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncEnumChannel.setMessageHandler { message, reply in + echoNullableEnumListChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anEnumArg = args[0] as! AnEnum - api.echoAsync(anEnumArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let enumListArg: [AnEnum?]? = nilOrValue(args[0]) + do { + let result = try api.echoNullable(enumList: enumListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncEnumChannel.setMessageHandler(nil) + echoNullableEnumListChannel.setMessageHandler(nil) } - /// Responds with an error from an async function returning a value. - let throwAsyncErrorChannel = FlutterBasicMessageChannel( + /// Returns the passed list, to test serialization and deserialization. + let echoNullableClassListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncError\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableClassList\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - throwAsyncErrorChannel.setMessageHandler { _, reply in - api.throwAsyncError { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + echoNullableClassListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let classListArg: [AllNullableTypes?]? = nilOrValue(args[0]) + do { + let result = try api.echoNullable(classList: classListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - throwAsyncErrorChannel.setMessageHandler(nil) + echoNullableClassListChannel.setMessageHandler(nil) } - /// Responds with an error from an async void function. - let throwAsyncErrorFromVoidChannel = FlutterBasicMessageChannel( + /// Returns the passed list, to test serialization and deserialization. + let echoNullableNonNullEnumListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncErrorFromVoid\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullEnumList\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - throwAsyncErrorFromVoidChannel.setMessageHandler { _, reply in - api.throwAsyncErrorFromVoid { result in - switch result { - case .success: - reply(wrapResult(nil)) - case .failure(let error): - reply(wrapError(error)) - } + echoNullableNonNullEnumListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let enumListArg: [AnEnum]? = nilOrValue(args[0]) + do { + let result = try api.echoNullableNonNull(enumList: enumListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - throwAsyncErrorFromVoidChannel.setMessageHandler(nil) + echoNullableNonNullEnumListChannel.setMessageHandler(nil) } - /// Responds with a Flutter error from an async function returning a value. - let throwAsyncFlutterErrorChannel = FlutterBasicMessageChannel( + /// Returns the passed list, to test serialization and deserialization. + let echoNullableNonNullClassListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncFlutterError\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullClassList\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - throwAsyncFlutterErrorChannel.setMessageHandler { _, reply in - api.throwAsyncFlutterError { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + echoNullableNonNullClassListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let classListArg: [AllNullableTypes]? = nilOrValue(args[0]) + do { + let result = try api.echoNullableNonNull(classList: classListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - throwAsyncFlutterErrorChannel.setMessageHandler(nil) + echoNullableNonNullClassListChannel.setMessageHandler(nil) } - /// Returns the passed object, to test async serialization and deserialization. - let echoAsyncAllTypesChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNullableMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncAllTypes\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncAllTypesChannel.setMessageHandler { message, reply in + echoNullableMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let everythingArg = args[0] as! AllTypes - api.echoAsync(everythingArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let mapArg: [AnyHashable?: Any?]? = nilOrValue(args[0]) + do { + let result = try api.echoNullable(mapArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncAllTypesChannel.setMessageHandler(nil) + echoNullableMapChannel.setMessageHandler(nil) } - /// Returns the passed object, to test serialization and deserialization. - let echoAsyncNullableAllNullableTypesChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNullableStringMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypes\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableStringMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncNullableAllNullableTypesChannel.setMessageHandler { message, reply in + echoNullableStringMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let everythingArg: AllNullableTypes? = nilOrValue(args[0]) - api.echoAsync(everythingArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let stringMapArg: [String?: String?]? = nilOrValue(args[0]) + do { + let result = try api.echoNullable(stringMap: stringMapArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncNullableAllNullableTypesChannel.setMessageHandler(nil) + echoNullableStringMapChannel.setMessageHandler(nil) } - /// Returns the passed object, to test serialization and deserialization. - let echoAsyncNullableAllNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNullableIntMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypesWithoutRecursion\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableIntMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncNullableAllNullableTypesWithoutRecursionChannel.setMessageHandler { message, reply in + echoNullableIntMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let everythingArg: AllNullableTypesWithoutRecursion? = nilOrValue(args[0]) - api.echoAsync(everythingArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let intMapArg: [Int64?: Int64?]? = nilOrValue(args[0]) + do { + let result = try api.echoNullable(intMap: intMapArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncNullableAllNullableTypesWithoutRecursionChannel.setMessageHandler(nil) + echoNullableIntMapChannel.setMessageHandler(nil) } - /// Returns passed in int asynchronously. - let echoAsyncNullableIntChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNullableEnumMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableInt\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableEnumMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncNullableIntChannel.setMessageHandler { message, reply in + echoNullableEnumMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anIntArg: Int64? = - isNullish(args[0]) - ? nil : (args[0] is Int64? ? args[0] as! Int64? : Int64(args[0] as! Int32)) - api.echoAsyncNullable(anIntArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let enumMapArg: [AnEnum?: AnEnum?]? = args[0] as? [AnEnum?: AnEnum?] + do { + let result = try api.echoNullable(enumMap: enumMapArg!) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncNullableIntChannel.setMessageHandler(nil) + echoNullableEnumMapChannel.setMessageHandler(nil) } - /// Returns passed in double asynchronously. - let echoAsyncNullableDoubleChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNullableClassMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableDouble\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableClassMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncNullableDoubleChannel.setMessageHandler { message, reply in + echoNullableClassMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aDoubleArg: Double? = nilOrValue(args[0]) - api.echoAsyncNullable(aDoubleArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let classMapArg: [Int64?: AllNullableTypes?]? = nilOrValue(args[0]) + do { + let result = try api.echoNullable(classMap: classMapArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncNullableDoubleChannel.setMessageHandler(nil) + echoNullableClassMapChannel.setMessageHandler(nil) } - /// Returns the passed in boolean asynchronously. - let echoAsyncNullableBoolChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNullableNonNullStringMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableBool\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullStringMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncNullableBoolChannel.setMessageHandler { message, reply in + echoNullableNonNullStringMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aBoolArg: Bool? = nilOrValue(args[0]) - api.echoAsyncNullable(aBoolArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let stringMapArg: [String: String]? = nilOrValue(args[0]) + do { + let result = try api.echoNullableNonNull(stringMap: stringMapArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncNullableBoolChannel.setMessageHandler(nil) + echoNullableNonNullStringMapChannel.setMessageHandler(nil) } - /// Returns the passed string asynchronously. - let echoAsyncNullableStringChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNullableNonNullIntMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableString\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullIntMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncNullableStringChannel.setMessageHandler { message, reply in + echoNullableNonNullIntMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aStringArg: String? = nilOrValue(args[0]) - api.echoAsyncNullable(aStringArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let intMapArg: [Int64: Int64]? = nilOrValue(args[0]) + do { + let result = try api.echoNullableNonNull(intMap: intMapArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncNullableStringChannel.setMessageHandler(nil) + echoNullableNonNullIntMapChannel.setMessageHandler(nil) } - /// Returns the passed in Uint8List asynchronously. - let echoAsyncNullableUint8ListChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNullableNonNullEnumMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableUint8List\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullEnumMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncNullableUint8ListChannel.setMessageHandler { message, reply in + echoNullableNonNullEnumMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aUint8ListArg: FlutterStandardTypedData? = nilOrValue(args[0]) - api.echoAsyncNullable(aUint8ListArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let enumMapArg: [AnEnum: AnEnum]? = args[0] as? [AnEnum: AnEnum] + do { + let result = try api.echoNullableNonNull(enumMap: enumMapArg!) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncNullableUint8ListChannel.setMessageHandler(nil) + echoNullableNonNullEnumMapChannel.setMessageHandler(nil) } - /// Returns the passed in generic Object asynchronously. - let echoAsyncNullableObjectChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNullableNonNullClassMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableObject\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullClassMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncNullableObjectChannel.setMessageHandler { message, reply in + echoNullableNonNullClassMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anObjectArg: Any? = args[0] - api.echoAsyncNullable(anObjectArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let classMapArg: [Int64: AllNullableTypes]? = nilOrValue(args[0]) + do { + let result = try api.echoNullableNonNull(classMap: classMapArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncNullableObjectChannel.setMessageHandler(nil) + echoNullableNonNullClassMapChannel.setMessageHandler(nil) } - /// Returns the passed list, to test asynchronous serialization and deserialization. - let echoAsyncNullableListChannel = FlutterBasicMessageChannel( + let echoNullableEnumChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableList\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableEnum\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncNullableListChannel.setMessageHandler { message, reply in + echoNullableEnumChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let listArg: [Any?]? = nilOrValue(args[0]) - api.echoAsyncNullable(listArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let anEnumArg: AnEnum? = nilOrValue(args[0]) + do { + let result = try api.echoNullable(anEnumArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncNullableListChannel.setMessageHandler(nil) + echoNullableEnumChannel.setMessageHandler(nil) } - /// Returns the passed map, to test asynchronous serialization and deserialization. - let echoAsyncNullableMapChannel = FlutterBasicMessageChannel( + let echoAnotherNullableEnumChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableMap\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAnotherNullableEnum\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncNullableMapChannel.setMessageHandler { message, reply in + echoAnotherNullableEnumChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aMapArg: [String?: Any?]? = nilOrValue(args[0]) - api.echoAsyncNullable(aMapArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let anotherEnumArg: AnotherEnum? = nilOrValue(args[0]) + do { + let result = try api.echoNullable(anotherEnumArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncNullableMapChannel.setMessageHandler(nil) + echoAnotherNullableEnumChannel.setMessageHandler(nil) } - /// Returns the passed enum, to test asynchronous serialization and deserialization. - let echoAsyncNullableEnumChannel = FlutterBasicMessageChannel( + /// Returns passed in int. + let echoOptionalNullableIntChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableEnum\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoOptionalNullableInt\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncNullableEnumChannel.setMessageHandler { message, reply in + echoOptionalNullableIntChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anEnumArg: AnEnum? = nilOrValue(args[0]) - api.echoAsyncNullable(anEnumArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let aNullableIntArg: Int64? = nilOrValue(args[0]) + do { + let result = try api.echoOptional(aNullableIntArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncNullableEnumChannel.setMessageHandler(nil) + echoOptionalNullableIntChannel.setMessageHandler(nil) } - let callFlutterNoopChannel = FlutterBasicMessageChannel( + /// Returns the passed in string. + let echoNamedNullableStringChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterNoop\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNamedNullableString\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterNoopChannel.setMessageHandler { _, reply in - api.callFlutterNoop { result in + echoNamedNullableStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aNullableStringArg: String? = nilOrValue(args[0]) + do { + let result = try api.echoNamed(aNullableStringArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoNamedNullableStringChannel.setMessageHandler(nil) + } + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic asynchronous calling. + let noopAsyncChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.noopAsync\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + noopAsyncChannel.setMessageHandler { _, reply in + api.noopAsync { result in switch result { case .success: reply(wrapResult(nil)) @@ -1965,15 +2265,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterNoopChannel.setMessageHandler(nil) + noopAsyncChannel.setMessageHandler(nil) } - let callFlutterThrowErrorChannel = FlutterBasicMessageChannel( + /// Returns passed in int asynchronously. + let echoAsyncIntChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterThrowError\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncInt\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterThrowErrorChannel.setMessageHandler { _, reply in - api.callFlutterThrowError { result in + echoAsyncIntChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let anIntArg = args[0] as! Int64 + api.echoAsync(anIntArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -1983,35 +2286,39 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterThrowErrorChannel.setMessageHandler(nil) + echoAsyncIntChannel.setMessageHandler(nil) } - let callFlutterThrowErrorFromVoidChannel = FlutterBasicMessageChannel( + /// Returns passed in double asynchronously. + let echoAsyncDoubleChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterThrowErrorFromVoid\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncDouble\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterThrowErrorFromVoidChannel.setMessageHandler { _, reply in - api.callFlutterThrowErrorFromVoid { result in + echoAsyncDoubleChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aDoubleArg = args[0] as! Double + api.echoAsync(aDoubleArg) { result in switch result { - case .success: - reply(wrapResult(nil)) + case .success(let res): + reply(wrapResult(res)) case .failure(let error): reply(wrapError(error)) } } } } else { - callFlutterThrowErrorFromVoidChannel.setMessageHandler(nil) + echoAsyncDoubleChannel.setMessageHandler(nil) } - let callFlutterEchoAllTypesChannel = FlutterBasicMessageChannel( + /// Returns the passed in boolean asynchronously. + let echoAsyncBoolChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllTypes\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncBool\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoAllTypesChannel.setMessageHandler { message, reply in + echoAsyncBoolChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let everythingArg = args[0] as! AllTypes - api.callFlutterEcho(everythingArg) { result in + let aBoolArg = args[0] as! Bool + api.echoAsync(aBoolArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2021,17 +2328,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoAllTypesChannel.setMessageHandler(nil) + echoAsyncBoolChannel.setMessageHandler(nil) } - let callFlutterEchoAllNullableTypesChannel = FlutterBasicMessageChannel( + /// Returns the passed string asynchronously. + let echoAsyncStringChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypes\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncString\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoAllNullableTypesChannel.setMessageHandler { message, reply in + echoAsyncStringChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let everythingArg: AllNullableTypes? = nilOrValue(args[0]) - api.callFlutterEcho(everythingArg) { result in + let aStringArg = args[0] as! String + api.echoAsync(aStringArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2041,23 +2349,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoAllNullableTypesChannel.setMessageHandler(nil) + echoAsyncStringChannel.setMessageHandler(nil) } - let callFlutterSendMultipleNullableTypesChannel = FlutterBasicMessageChannel( + /// Returns the passed in Uint8List asynchronously. + let echoAsyncUint8ListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypes\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncUint8List\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterSendMultipleNullableTypesChannel.setMessageHandler { message, reply in + echoAsyncUint8ListChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableBoolArg: Bool? = nilOrValue(args[0]) - let aNullableIntArg: Int64? = - isNullish(args[1]) - ? nil : (args[1] is Int64? ? args[1] as! Int64? : Int64(args[1] as! Int32)) - let aNullableStringArg: String? = nilOrValue(args[2]) - api.callFlutterSendMultipleNullableTypes( - aBool: aNullableBoolArg, anInt: aNullableIntArg, aString: aNullableStringArg - ) { result in + let aUint8ListArg = args[0] as! FlutterStandardTypedData + api.echoAsync(aUint8ListArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2067,17 +2370,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterSendMultipleNullableTypesChannel.setMessageHandler(nil) + echoAsyncUint8ListChannel.setMessageHandler(nil) } - let callFlutterEchoAllNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( + /// Returns the passed in generic Object asynchronously. + let echoAsyncObjectChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypesWithoutRecursion\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncObject\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoAllNullableTypesWithoutRecursionChannel.setMessageHandler { message, reply in + echoAsyncObjectChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let everythingArg: AllNullableTypesWithoutRecursion? = nilOrValue(args[0]) - api.callFlutterEcho(everythingArg) { result in + let anObjectArg = args[0]! + api.echoAsync(anObjectArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2087,24 +2391,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoAllNullableTypesWithoutRecursionChannel.setMessageHandler(nil) + echoAsyncObjectChannel.setMessageHandler(nil) } - let callFlutterSendMultipleNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( + /// Returns the passed list, to test asynchronous serialization and deserialization. + let echoAsyncListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypesWithoutRecursion\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncList\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterSendMultipleNullableTypesWithoutRecursionChannel.setMessageHandler { - message, reply in + echoAsyncListChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableBoolArg: Bool? = nilOrValue(args[0]) - let aNullableIntArg: Int64? = - isNullish(args[1]) - ? nil : (args[1] is Int64? ? args[1] as! Int64? : Int64(args[1] as! Int32)) - let aNullableStringArg: String? = nilOrValue(args[2]) - api.callFlutterSendMultipleNullableTypesWithoutRecursion( - aBool: aNullableBoolArg, anInt: aNullableIntArg, aString: aNullableStringArg - ) { result in + let listArg = args[0] as! [Any?] + api.echoAsync(listArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2114,17 +2412,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterSendMultipleNullableTypesWithoutRecursionChannel.setMessageHandler(nil) + echoAsyncListChannel.setMessageHandler(nil) } - let callFlutterEchoBoolChannel = FlutterBasicMessageChannel( + /// Returns the passed list, to test asynchronous serialization and deserialization. + let echoAsyncEnumListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoBool\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncEnumList\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoBoolChannel.setMessageHandler { message, reply in + echoAsyncEnumListChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aBoolArg = args[0] as! Bool - api.callFlutterEcho(aBoolArg) { result in + let enumListArg = args[0] as! [AnEnum?] + api.echoAsync(enumList: enumListArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2134,17 +2433,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoBoolChannel.setMessageHandler(nil) + echoAsyncEnumListChannel.setMessageHandler(nil) } - let callFlutterEchoIntChannel = FlutterBasicMessageChannel( + /// Returns the passed list, to test asynchronous serialization and deserialization. + let echoAsyncClassListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoInt\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncClassList\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoIntChannel.setMessageHandler { message, reply in + echoAsyncClassListChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anIntArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) - api.callFlutterEcho(anIntArg) { result in + let classListArg = args[0] as! [AllNullableTypes?] + api.echoAsync(classList: classListArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2154,17 +2454,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoIntChannel.setMessageHandler(nil) + echoAsyncClassListChannel.setMessageHandler(nil) } - let callFlutterEchoDoubleChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test asynchronous serialization and deserialization. + let echoAsyncMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoDouble\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoDoubleChannel.setMessageHandler { message, reply in + echoAsyncMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aDoubleArg = args[0] as! Double - api.callFlutterEcho(aDoubleArg) { result in + let mapArg = args[0] as! [AnyHashable?: Any?] + api.echoAsync(mapArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2174,17 +2475,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoDoubleChannel.setMessageHandler(nil) + echoAsyncMapChannel.setMessageHandler(nil) } - let callFlutterEchoStringChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test asynchronous serialization and deserialization. + let echoAsyncStringMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoString\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncStringMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoStringChannel.setMessageHandler { message, reply in + echoAsyncStringMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aStringArg = args[0] as! String - api.callFlutterEcho(aStringArg) { result in + let stringMapArg = args[0] as! [String?: String?] + api.echoAsync(stringMap: stringMapArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2194,17 +2496,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoStringChannel.setMessageHandler(nil) + echoAsyncStringMapChannel.setMessageHandler(nil) } - let callFlutterEchoUint8ListChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test asynchronous serialization and deserialization. + let echoAsyncIntMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoUint8List\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncIntMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoUint8ListChannel.setMessageHandler { message, reply in + echoAsyncIntMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let listArg = args[0] as! FlutterStandardTypedData - api.callFlutterEcho(listArg) { result in + let intMapArg = args[0] as! [Int64?: Int64?] + api.echoAsync(intMap: intMapArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2214,17 +2517,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoUint8ListChannel.setMessageHandler(nil) + echoAsyncIntMapChannel.setMessageHandler(nil) } - let callFlutterEchoListChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test asynchronous serialization and deserialization. + let echoAsyncEnumMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoList\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncEnumMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoListChannel.setMessageHandler { message, reply in + echoAsyncEnumMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let listArg = args[0] as! [Any?] - api.callFlutterEcho(listArg) { result in + let enumMapArg = args[0] as? [AnEnum?: AnEnum?] + api.echoAsync(enumMap: enumMapArg!) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2234,17 +2538,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoListChannel.setMessageHandler(nil) + echoAsyncEnumMapChannel.setMessageHandler(nil) } - let callFlutterEchoMapChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test asynchronous serialization and deserialization. + let echoAsyncClassMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoMap\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncClassMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoMapChannel.setMessageHandler { message, reply in + echoAsyncClassMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aMapArg = args[0] as! [String?: Any?] - api.callFlutterEcho(aMapArg) { result in + let classMapArg = args[0] as! [Int64?: AllNullableTypes?] + api.echoAsync(classMap: classMapArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2254,17 +2559,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoMapChannel.setMessageHandler(nil) + echoAsyncClassMapChannel.setMessageHandler(nil) } - let callFlutterEchoEnumChannel = FlutterBasicMessageChannel( + /// Returns the passed enum, to test asynchronous serialization and deserialization. + let echoAsyncEnumChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoEnum\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncEnum\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoEnumChannel.setMessageHandler { message, reply in + echoAsyncEnumChannel.setMessageHandler { message, reply in let args = message as! [Any?] let anEnumArg = args[0] as! AnEnum - api.callFlutterEcho(anEnumArg) { result in + api.echoAsync(anEnumArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2274,17 +2580,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoEnumChannel.setMessageHandler(nil) + echoAsyncEnumChannel.setMessageHandler(nil) } - let callFlutterEchoNullableBoolChannel = FlutterBasicMessageChannel( + /// Returns the passed enum, to test asynchronous serialization and deserialization. + let echoAnotherAsyncEnumChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableBool\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAnotherAsyncEnum\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoNullableBoolChannel.setMessageHandler { message, reply in + echoAnotherAsyncEnumChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aBoolArg: Bool? = nilOrValue(args[0]) - api.callFlutterEchoNullable(aBoolArg) { result in + let anotherEnumArg = args[0] as! AnotherEnum + api.echoAsync(anotherEnumArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2294,19 +2601,75 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoNullableBoolChannel.setMessageHandler(nil) + echoAnotherAsyncEnumChannel.setMessageHandler(nil) } - let callFlutterEchoNullableIntChannel = FlutterBasicMessageChannel( + /// Responds with an error from an async function returning a value. + let throwAsyncErrorChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableInt\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncError\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoNullableIntChannel.setMessageHandler { message, reply in + throwAsyncErrorChannel.setMessageHandler { _, reply in + api.throwAsyncError { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + throwAsyncErrorChannel.setMessageHandler(nil) + } + /// Responds with an error from an async void function. + let throwAsyncErrorFromVoidChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncErrorFromVoid\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + throwAsyncErrorFromVoidChannel.setMessageHandler { _, reply in + api.throwAsyncErrorFromVoid { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + throwAsyncErrorFromVoidChannel.setMessageHandler(nil) + } + /// Responds with a Flutter error from an async function returning a value. + let throwAsyncFlutterErrorChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncFlutterError\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + throwAsyncFlutterErrorChannel.setMessageHandler { _, reply in + api.throwAsyncFlutterError { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + throwAsyncFlutterErrorChannel.setMessageHandler(nil) + } + /// Returns the passed object, to test async serialization and deserialization. + let echoAsyncAllTypesChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncAllTypes\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncAllTypesChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anIntArg: Int64? = - isNullish(args[0]) - ? nil : (args[0] is Int64? ? args[0] as! Int64? : Int64(args[0] as! Int32)) - api.callFlutterEchoNullable(anIntArg) { result in + let everythingArg = args[0] as! AllTypes + api.echoAsync(everythingArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2316,17 +2679,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoNullableIntChannel.setMessageHandler(nil) + echoAsyncAllTypesChannel.setMessageHandler(nil) } - let callFlutterEchoNullableDoubleChannel = FlutterBasicMessageChannel( + /// Returns the passed object, to test serialization and deserialization. + let echoAsyncNullableAllNullableTypesChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableDouble\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypes\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoNullableDoubleChannel.setMessageHandler { message, reply in + echoAsyncNullableAllNullableTypesChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aDoubleArg: Double? = nilOrValue(args[0]) - api.callFlutterEchoNullable(aDoubleArg) { result in + let everythingArg: AllNullableTypes? = nilOrValue(args[0]) + api.echoAsync(everythingArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2336,17 +2700,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoNullableDoubleChannel.setMessageHandler(nil) + echoAsyncNullableAllNullableTypesChannel.setMessageHandler(nil) } - let callFlutterEchoNullableStringChannel = FlutterBasicMessageChannel( + /// Returns the passed object, to test serialization and deserialization. + let echoAsyncNullableAllNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableString\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypesWithoutRecursion\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoNullableStringChannel.setMessageHandler { message, reply in + echoAsyncNullableAllNullableTypesWithoutRecursionChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aStringArg: String? = nilOrValue(args[0]) - api.callFlutterEchoNullable(aStringArg) { result in + let everythingArg: AllNullableTypesWithoutRecursion? = nilOrValue(args[0]) + api.echoAsync(everythingArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2356,17 +2721,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoNullableStringChannel.setMessageHandler(nil) + echoAsyncNullableAllNullableTypesWithoutRecursionChannel.setMessageHandler(nil) } - let callFlutterEchoNullableUint8ListChannel = FlutterBasicMessageChannel( + /// Returns passed in int asynchronously. + let echoAsyncNullableIntChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableUint8List\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableInt\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoNullableUint8ListChannel.setMessageHandler { message, reply in + echoAsyncNullableIntChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let listArg: FlutterStandardTypedData? = nilOrValue(args[0]) - api.callFlutterEchoNullable(listArg) { result in + let anIntArg: Int64? = nilOrValue(args[0]) + api.echoAsyncNullable(anIntArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2376,17 +2742,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoNullableUint8ListChannel.setMessageHandler(nil) + echoAsyncNullableIntChannel.setMessageHandler(nil) } - let callFlutterEchoNullableListChannel = FlutterBasicMessageChannel( + /// Returns passed in double asynchronously. + let echoAsyncNullableDoubleChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableList\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableDouble\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoNullableListChannel.setMessageHandler { message, reply in + echoAsyncNullableDoubleChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let listArg: [Any?]? = nilOrValue(args[0]) - api.callFlutterEchoNullable(listArg) { result in + let aDoubleArg: Double? = nilOrValue(args[0]) + api.echoAsyncNullable(aDoubleArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2396,17 +2763,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoNullableListChannel.setMessageHandler(nil) + echoAsyncNullableDoubleChannel.setMessageHandler(nil) } - let callFlutterEchoNullableMapChannel = FlutterBasicMessageChannel( + /// Returns the passed in boolean asynchronously. + let echoAsyncNullableBoolChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableMap\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableBool\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoNullableMapChannel.setMessageHandler { message, reply in + echoAsyncNullableBoolChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aMapArg: [String?: Any?]? = nilOrValue(args[0]) - api.callFlutterEchoNullable(aMapArg) { result in + let aBoolArg: Bool? = nilOrValue(args[0]) + api.echoAsyncNullable(aBoolArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2416,17 +2784,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoNullableMapChannel.setMessageHandler(nil) + echoAsyncNullableBoolChannel.setMessageHandler(nil) } - let callFlutterEchoNullableEnumChannel = FlutterBasicMessageChannel( + /// Returns the passed string asynchronously. + let echoAsyncNullableStringChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableEnum\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableString\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoNullableEnumChannel.setMessageHandler { message, reply in + echoAsyncNullableStringChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anEnumArg: AnEnum? = nilOrValue(args[0]) - api.callFlutterNullableEcho(anEnumArg) { result in + let aStringArg: String? = nilOrValue(args[0]) + api.echoAsyncNullable(aStringArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2436,17 +2805,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoNullableEnumChannel.setMessageHandler(nil) + echoAsyncNullableStringChannel.setMessageHandler(nil) } - let callFlutterSmallApiEchoStringChannel = FlutterBasicMessageChannel( + /// Returns the passed in Uint8List asynchronously. + let echoAsyncNullableUint8ListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSmallApiEchoString\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableUint8List\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterSmallApiEchoStringChannel.setMessageHandler { message, reply in + echoAsyncNullableUint8ListChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aStringArg = args[0] as! String - api.callFlutterSmallApiEcho(aStringArg) { result in + let aUint8ListArg: FlutterStandardTypedData? = nilOrValue(args[0]) + api.echoAsyncNullable(aUint8ListArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2456,115 +2826,2103 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterSmallApiEchoStringChannel.setMessageHandler(nil) + echoAsyncNullableUint8ListChannel.setMessageHandler(nil) } - } -} -/// The core interface that the Dart platform_test code implements for host -/// integration tests to call into. -/// -/// Generated protocol from Pigeon that represents Flutter messages that can be called from Swift. -protocol FlutterIntegrationCoreApiProtocol { - /// A no-op function taking no arguments and returning no value, to sanity - /// test basic calling. - func noop(completion: @escaping (Result) -> Void) - /// Responds with an error from an async function returning a value. - func throwError(completion: @escaping (Result) -> Void) - /// Responds with an error from an async void function. - func throwErrorFromVoid(completion: @escaping (Result) -> Void) - /// Returns the passed object, to test serialization and deserialization. - func echo( - _ everythingArg: AllTypes, completion: @escaping (Result) -> Void) - /// Returns the passed object, to test serialization and deserialization. - func echoNullable( - _ everythingArg: AllNullableTypes?, - completion: @escaping (Result) -> Void) - /// Returns passed in arguments of multiple types. - /// - /// Tests multiple-arity FlutterApi handling. - func sendMultipleNullableTypes( - aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, - aString aNullableStringArg: String?, - completion: @escaping (Result) -> Void) - /// Returns the passed object, to test serialization and deserialization. - func echoNullable( - _ everythingArg: AllNullableTypesWithoutRecursion?, - completion: @escaping (Result) -> Void) - /// Returns passed in arguments of multiple types. - /// - /// Tests multiple-arity FlutterApi handling. - func sendMultipleNullableTypesWithoutRecursion( - aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, - aString aNullableStringArg: String?, - completion: @escaping (Result) -> Void) - /// Returns the passed boolean, to test serialization and deserialization. - func echo(_ aBoolArg: Bool, completion: @escaping (Result) -> Void) - /// Returns the passed int, to test serialization and deserialization. - func echo(_ anIntArg: Int64, completion: @escaping (Result) -> Void) - /// Returns the passed double, to test serialization and deserialization. - func echo(_ aDoubleArg: Double, completion: @escaping (Result) -> Void) - /// Returns the passed string, to test serialization and deserialization. - func echo(_ aStringArg: String, completion: @escaping (Result) -> Void) - /// Returns the passed byte list, to test serialization and deserialization. - func echo( - _ listArg: FlutterStandardTypedData, - completion: @escaping (Result) -> Void) + /// Returns the passed in generic Object asynchronously. + let echoAsyncNullableObjectChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableObject\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableObjectChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let anObjectArg: Any? = args[0] + api.echoAsyncNullable(anObjectArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableObjectChannel.setMessageHandler(nil) + } + /// Returns the passed list, to test asynchronous serialization and deserialization. + let echoAsyncNullableListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let listArg: [Any?]? = nilOrValue(args[0]) + api.echoAsyncNullable(listArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableListChannel.setMessageHandler(nil) + } + /// Returns the passed list, to test asynchronous serialization and deserialization. + let echoAsyncNullableEnumListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableEnumList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableEnumListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let enumListArg: [AnEnum?]? = nilOrValue(args[0]) + api.echoAsyncNullable(enumList: enumListArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableEnumListChannel.setMessageHandler(nil) + } + /// Returns the passed list, to test asynchronous serialization and deserialization. + let echoAsyncNullableClassListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableClassList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableClassListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let classListArg: [AllNullableTypes?]? = nilOrValue(args[0]) + api.echoAsyncNullable(classList: classListArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableClassListChannel.setMessageHandler(nil) + } + /// Returns the passed map, to test asynchronous serialization and deserialization. + let echoAsyncNullableMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let mapArg: [AnyHashable?: Any?]? = nilOrValue(args[0]) + api.echoAsyncNullable(mapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableMapChannel.setMessageHandler(nil) + } + /// Returns the passed map, to test asynchronous serialization and deserialization. + let echoAsyncNullableStringMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableStringMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableStringMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let stringMapArg: [String?: String?]? = nilOrValue(args[0]) + api.echoAsyncNullable(stringMap: stringMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableStringMapChannel.setMessageHandler(nil) + } + /// Returns the passed map, to test asynchronous serialization and deserialization. + let echoAsyncNullableIntMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableIntMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableIntMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let intMapArg: [Int64?: Int64?]? = nilOrValue(args[0]) + api.echoAsyncNullable(intMap: intMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableIntMapChannel.setMessageHandler(nil) + } + /// Returns the passed map, to test asynchronous serialization and deserialization. + let echoAsyncNullableEnumMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableEnumMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableEnumMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let enumMapArg: [AnEnum?: AnEnum?]? = args[0] as? [AnEnum?: AnEnum?] + api.echoAsyncNullable(enumMap: enumMapArg!) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableEnumMapChannel.setMessageHandler(nil) + } + /// Returns the passed map, to test asynchronous serialization and deserialization. + let echoAsyncNullableClassMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableClassMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableClassMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let classMapArg: [Int64?: AllNullableTypes?]? = nilOrValue(args[0]) + api.echoAsyncNullable(classMap: classMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableClassMapChannel.setMessageHandler(nil) + } + /// Returns the passed enum, to test asynchronous serialization and deserialization. + let echoAsyncNullableEnumChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableEnum\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableEnumChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let anEnumArg: AnEnum? = nilOrValue(args[0]) + api.echoAsyncNullable(anEnumArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableEnumChannel.setMessageHandler(nil) + } + /// Returns the passed enum, to test asynchronous serialization and deserialization. + let echoAnotherAsyncNullableEnumChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAnotherAsyncNullableEnum\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAnotherAsyncNullableEnumChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let anotherEnumArg: AnotherEnum? = nilOrValue(args[0]) + api.echoAsyncNullable(anotherEnumArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAnotherAsyncNullableEnumChannel.setMessageHandler(nil) + } + let callFlutterNoopChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterNoop\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterNoopChannel.setMessageHandler { _, reply in + api.callFlutterNoop { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterNoopChannel.setMessageHandler(nil) + } + let callFlutterThrowErrorChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterThrowError\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterThrowErrorChannel.setMessageHandler { _, reply in + api.callFlutterThrowError { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterThrowErrorChannel.setMessageHandler(nil) + } + let callFlutterThrowErrorFromVoidChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterThrowErrorFromVoid\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterThrowErrorFromVoidChannel.setMessageHandler { _, reply in + api.callFlutterThrowErrorFromVoid { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterThrowErrorFromVoidChannel.setMessageHandler(nil) + } + let callFlutterEchoAllTypesChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllTypes\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoAllTypesChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let everythingArg = args[0] as! AllTypes + api.callFlutterEcho(everythingArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoAllTypesChannel.setMessageHandler(nil) + } + let callFlutterEchoAllNullableTypesChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypes\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoAllNullableTypesChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let everythingArg: AllNullableTypes? = nilOrValue(args[0]) + api.callFlutterEcho(everythingArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoAllNullableTypesChannel.setMessageHandler(nil) + } + let callFlutterSendMultipleNullableTypesChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypes\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterSendMultipleNullableTypesChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aNullableBoolArg: Bool? = nilOrValue(args[0]) + let aNullableIntArg: Int64? = nilOrValue(args[1]) + let aNullableStringArg: String? = nilOrValue(args[2]) + api.callFlutterSendMultipleNullableTypes( + aBool: aNullableBoolArg, anInt: aNullableIntArg, aString: aNullableStringArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterSendMultipleNullableTypesChannel.setMessageHandler(nil) + } + let callFlutterEchoAllNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypesWithoutRecursion\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoAllNullableTypesWithoutRecursionChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let everythingArg: AllNullableTypesWithoutRecursion? = nilOrValue(args[0]) + api.callFlutterEcho(everythingArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoAllNullableTypesWithoutRecursionChannel.setMessageHandler(nil) + } + let callFlutterSendMultipleNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypesWithoutRecursion\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterSendMultipleNullableTypesWithoutRecursionChannel.setMessageHandler { + message, reply in + let args = message as! [Any?] + let aNullableBoolArg: Bool? = nilOrValue(args[0]) + let aNullableIntArg: Int64? = nilOrValue(args[1]) + let aNullableStringArg: String? = nilOrValue(args[2]) + api.callFlutterSendMultipleNullableTypesWithoutRecursion( + aBool: aNullableBoolArg, anInt: aNullableIntArg, aString: aNullableStringArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterSendMultipleNullableTypesWithoutRecursionChannel.setMessageHandler(nil) + } + let callFlutterEchoBoolChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoBool\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoBoolChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aBoolArg = args[0] as! Bool + api.callFlutterEcho(aBoolArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoBoolChannel.setMessageHandler(nil) + } + let callFlutterEchoIntChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoInt\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoIntChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let anIntArg = args[0] as! Int64 + api.callFlutterEcho(anIntArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoIntChannel.setMessageHandler(nil) + } + let callFlutterEchoDoubleChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoDouble\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoDoubleChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aDoubleArg = args[0] as! Double + api.callFlutterEcho(aDoubleArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoDoubleChannel.setMessageHandler(nil) + } + let callFlutterEchoStringChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoString\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aStringArg = args[0] as! String + api.callFlutterEcho(aStringArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoStringChannel.setMessageHandler(nil) + } + let callFlutterEchoUint8ListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoUint8List\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoUint8ListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let listArg = args[0] as! FlutterStandardTypedData + api.callFlutterEcho(listArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoUint8ListChannel.setMessageHandler(nil) + } + let callFlutterEchoListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let listArg = args[0] as! [Any?] + api.callFlutterEcho(listArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoListChannel.setMessageHandler(nil) + } + let callFlutterEchoEnumListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoEnumList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoEnumListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let enumListArg = args[0] as! [AnEnum?] + api.callFlutterEcho(enumList: enumListArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoEnumListChannel.setMessageHandler(nil) + } + let callFlutterEchoClassListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoClassList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoClassListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let classListArg = args[0] as! [AllNullableTypes?] + api.callFlutterEcho(classList: classListArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoClassListChannel.setMessageHandler(nil) + } + let callFlutterEchoNonNullEnumListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullEnumList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNonNullEnumListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let enumListArg = args[0] as! [AnEnum] + api.callFlutterEchoNonNull(enumList: enumListArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNonNullEnumListChannel.setMessageHandler(nil) + } + let callFlutterEchoNonNullClassListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullClassList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNonNullClassListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let classListArg = args[0] as! [AllNullableTypes] + api.callFlutterEchoNonNull(classList: classListArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNonNullClassListChannel.setMessageHandler(nil) + } + let callFlutterEchoMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let mapArg = args[0] as! [AnyHashable?: Any?] + api.callFlutterEcho(mapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoMapChannel.setMessageHandler(nil) + } + let callFlutterEchoStringMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoStringMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoStringMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let stringMapArg = args[0] as! [String?: String?] + api.callFlutterEcho(stringMap: stringMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoStringMapChannel.setMessageHandler(nil) + } + let callFlutterEchoIntMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoIntMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoIntMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let intMapArg = args[0] as! [Int64?: Int64?] + api.callFlutterEcho(intMap: intMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoIntMapChannel.setMessageHandler(nil) + } + let callFlutterEchoEnumMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoEnumMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoEnumMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let enumMapArg = args[0] as? [AnEnum?: AnEnum?] + api.callFlutterEcho(enumMap: enumMapArg!) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoEnumMapChannel.setMessageHandler(nil) + } + let callFlutterEchoClassMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoClassMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoClassMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let classMapArg = args[0] as! [Int64?: AllNullableTypes?] + api.callFlutterEcho(classMap: classMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoClassMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNonNullStringMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullStringMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNonNullStringMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let stringMapArg = args[0] as! [String: String] + api.callFlutterEchoNonNull(stringMap: stringMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNonNullStringMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNonNullIntMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullIntMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNonNullIntMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let intMapArg = args[0] as! [Int64: Int64] + api.callFlutterEchoNonNull(intMap: intMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNonNullIntMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNonNullEnumMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullEnumMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNonNullEnumMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let enumMapArg = args[0] as? [AnEnum: AnEnum] + api.callFlutterEchoNonNull(enumMap: enumMapArg!) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNonNullEnumMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNonNullClassMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullClassMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNonNullClassMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let classMapArg = args[0] as! [Int64: AllNullableTypes] + api.callFlutterEchoNonNull(classMap: classMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNonNullClassMapChannel.setMessageHandler(nil) + } + let callFlutterEchoEnumChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoEnum\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoEnumChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let anEnumArg = args[0] as! AnEnum + api.callFlutterEcho(anEnumArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoEnumChannel.setMessageHandler(nil) + } + let callFlutterEchoAnotherEnumChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAnotherEnum\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoAnotherEnumChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let anotherEnumArg = args[0] as! AnotherEnum + api.callFlutterEcho(anotherEnumArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoAnotherEnumChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableBoolChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableBool\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableBoolChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aBoolArg: Bool? = nilOrValue(args[0]) + api.callFlutterEchoNullable(aBoolArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableBoolChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableIntChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableInt\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableIntChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let anIntArg: Int64? = nilOrValue(args[0]) + api.callFlutterEchoNullable(anIntArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableIntChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableDoubleChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableDouble\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableDoubleChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aDoubleArg: Double? = nilOrValue(args[0]) + api.callFlutterEchoNullable(aDoubleArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableDoubleChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableStringChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableString\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aStringArg: String? = nilOrValue(args[0]) + api.callFlutterEchoNullable(aStringArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableStringChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableUint8ListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableUint8List\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableUint8ListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let listArg: FlutterStandardTypedData? = nilOrValue(args[0]) + api.callFlutterEchoNullable(listArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableUint8ListChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let listArg: [Any?]? = nilOrValue(args[0]) + api.callFlutterEchoNullable(listArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableListChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableEnumListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableEnumList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableEnumListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let enumListArg: [AnEnum?]? = nilOrValue(args[0]) + api.callFlutterEchoNullable(enumList: enumListArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableEnumListChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableClassListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableClassList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableClassListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let classListArg: [AllNullableTypes?]? = nilOrValue(args[0]) + api.callFlutterEchoNullable(classList: classListArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableClassListChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableNonNullEnumListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullEnumList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableNonNullEnumListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let enumListArg: [AnEnum]? = nilOrValue(args[0]) + api.callFlutterEchoNullableNonNull(enumList: enumListArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableNonNullEnumListChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableNonNullClassListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullClassList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableNonNullClassListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let classListArg: [AllNullableTypes]? = nilOrValue(args[0]) + api.callFlutterEchoNullableNonNull(classList: classListArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableNonNullClassListChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let mapArg: [AnyHashable?: Any?]? = nilOrValue(args[0]) + api.callFlutterEchoNullable(mapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableStringMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableStringMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableStringMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let stringMapArg: [String?: String?]? = nilOrValue(args[0]) + api.callFlutterEchoNullable(stringMap: stringMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableStringMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableIntMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableIntMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableIntMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let intMapArg: [Int64?: Int64?]? = nilOrValue(args[0]) + api.callFlutterEchoNullable(intMap: intMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableIntMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableEnumMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableEnumMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableEnumMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let enumMapArg: [AnEnum?: AnEnum?]? = args[0] as? [AnEnum?: AnEnum?] + api.callFlutterEchoNullable(enumMap: enumMapArg!) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableEnumMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableClassMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableClassMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableClassMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let classMapArg: [Int64?: AllNullableTypes?]? = nilOrValue(args[0]) + api.callFlutterEchoNullable(classMap: classMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableClassMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableNonNullStringMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullStringMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableNonNullStringMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let stringMapArg: [String: String]? = nilOrValue(args[0]) + api.callFlutterEchoNullableNonNull(stringMap: stringMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableNonNullStringMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableNonNullIntMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullIntMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableNonNullIntMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let intMapArg: [Int64: Int64]? = nilOrValue(args[0]) + api.callFlutterEchoNullableNonNull(intMap: intMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableNonNullIntMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableNonNullEnumMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullEnumMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableNonNullEnumMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let enumMapArg: [AnEnum: AnEnum]? = args[0] as? [AnEnum: AnEnum] + api.callFlutterEchoNullableNonNull(enumMap: enumMapArg!) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableNonNullEnumMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableNonNullClassMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullClassMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableNonNullClassMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let classMapArg: [Int64: AllNullableTypes]? = nilOrValue(args[0]) + api.callFlutterEchoNullableNonNull(classMap: classMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableNonNullClassMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableEnumChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableEnum\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableEnumChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let anEnumArg: AnEnum? = nilOrValue(args[0]) + api.callFlutterEchoNullable(anEnumArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableEnumChannel.setMessageHandler(nil) + } + let callFlutterEchoAnotherNullableEnumChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAnotherNullableEnum\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoAnotherNullableEnumChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let anotherEnumArg: AnotherEnum? = nilOrValue(args[0]) + api.callFlutterEchoNullable(anotherEnumArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoAnotherNullableEnumChannel.setMessageHandler(nil) + } + let callFlutterSmallApiEchoStringChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSmallApiEchoString\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterSmallApiEchoStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aStringArg = args[0] as! String + api.callFlutterSmallApiEcho(aStringArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterSmallApiEchoStringChannel.setMessageHandler(nil) + } + } +} +/// The core interface that the Dart platform_test code implements for host +/// integration tests to call into. +/// +/// Generated protocol from Pigeon that represents Flutter messages that can be called from Swift. +protocol FlutterIntegrationCoreApiProtocol { + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic calling. + func noop(completion: @escaping (Result) -> Void) + /// Responds with an error from an async function returning a value. + func throwError(completion: @escaping (Result) -> Void) + /// Responds with an error from an async void function. + func throwErrorFromVoid(completion: @escaping (Result) -> Void) + /// Returns the passed object, to test serialization and deserialization. + func echo( + _ everythingArg: AllTypes, completion: @escaping (Result) -> Void) + /// Returns the passed object, to test serialization and deserialization. + func echoNullable( + _ everythingArg: AllNullableTypes?, + completion: @escaping (Result) -> Void) + /// Returns passed in arguments of multiple types. + /// + /// Tests multiple-arity FlutterApi handling. + func sendMultipleNullableTypes( + aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, + aString aNullableStringArg: String?, + completion: @escaping (Result) -> Void) + /// Returns the passed object, to test serialization and deserialization. + func echoNullable( + _ everythingArg: AllNullableTypesWithoutRecursion?, + completion: @escaping (Result) -> Void) + /// Returns passed in arguments of multiple types. + /// + /// Tests multiple-arity FlutterApi handling. + func sendMultipleNullableTypesWithoutRecursion( + aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, + aString aNullableStringArg: String?, + completion: @escaping (Result) -> Void) + /// Returns the passed boolean, to test serialization and deserialization. + func echo(_ aBoolArg: Bool, completion: @escaping (Result) -> Void) + /// Returns the passed int, to test serialization and deserialization. + func echo(_ anIntArg: Int64, completion: @escaping (Result) -> Void) + /// Returns the passed double, to test serialization and deserialization. + func echo(_ aDoubleArg: Double, completion: @escaping (Result) -> Void) + /// Returns the passed string, to test serialization and deserialization. + func echo(_ aStringArg: String, completion: @escaping (Result) -> Void) + /// Returns the passed byte list, to test serialization and deserialization. + func echo( + _ listArg: FlutterStandardTypedData, + completion: @escaping (Result) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func echo(_ listArg: [Any?], completion: @escaping (Result<[Any?], PigeonError>) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func echo( + enumList enumListArg: [AnEnum?], completion: @escaping (Result<[AnEnum?], PigeonError>) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func echo( + classList classListArg: [AllNullableTypes?], + completion: @escaping (Result<[AllNullableTypes?], PigeonError>) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func echoNonNull( + enumList enumListArg: [AnEnum], completion: @escaping (Result<[AnEnum], PigeonError>) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func echoNonNull( + classList classListArg: [AllNullableTypes], + completion: @escaping (Result<[AllNullableTypes], PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echo( + _ mapArg: [AnyHashable?: Any?], + completion: @escaping (Result<[AnyHashable?: Any?], PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echo( + stringMap stringMapArg: [String?: String?], + completion: @escaping (Result<[String?: String?], PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echo( + intMap intMapArg: [Int64?: Int64?], + completion: @escaping (Result<[Int64?: Int64?], PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echo( + enumMap enumMapArg: [AnEnum?: AnEnum?], + completion: @escaping (Result<[AnEnum?: AnEnum?], PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echo( + classMap classMapArg: [Int64?: AllNullableTypes?], + completion: @escaping (Result<[Int64?: AllNullableTypes?], PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNonNull( + stringMap stringMapArg: [String: String], + completion: @escaping (Result<[String: String], PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNonNull( + intMap intMapArg: [Int64: Int64], + completion: @escaping (Result<[Int64: Int64], PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNonNull( + enumMap enumMapArg: [AnEnum: AnEnum], + completion: @escaping (Result<[AnEnum: AnEnum], PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNonNull( + classMap classMapArg: [Int64: AllNullableTypes], + completion: @escaping (Result<[Int64: AllNullableTypes], PigeonError>) -> Void) + /// Returns the passed enum to test serialization and deserialization. + func echo(_ anEnumArg: AnEnum, completion: @escaping (Result) -> Void) + /// Returns the passed enum to test serialization and deserialization. + func echo( + _ anotherEnumArg: AnotherEnum, completion: @escaping (Result) -> Void) + /// Returns the passed boolean, to test serialization and deserialization. + func echoNullable(_ aBoolArg: Bool?, completion: @escaping (Result) -> Void) + /// Returns the passed int, to test serialization and deserialization. + func echoNullable(_ anIntArg: Int64?, completion: @escaping (Result) -> Void) + /// Returns the passed double, to test serialization and deserialization. + func echoNullable( + _ aDoubleArg: Double?, completion: @escaping (Result) -> Void) + /// Returns the passed string, to test serialization and deserialization. + func echoNullable( + _ aStringArg: String?, completion: @escaping (Result) -> Void) + /// Returns the passed byte list, to test serialization and deserialization. + func echoNullable( + _ listArg: FlutterStandardTypedData?, + completion: @escaping (Result) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func echoNullable( + _ listArg: [Any?]?, completion: @escaping (Result<[Any?]?, PigeonError>) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func echoNullable( + enumList enumListArg: [AnEnum?]?, + completion: @escaping (Result<[AnEnum?]?, PigeonError>) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func echoNullable( + classList classListArg: [AllNullableTypes?]?, + completion: @escaping (Result<[AllNullableTypes?]?, PigeonError>) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func echoNullableNonNull( + enumList enumListArg: [AnEnum]?, completion: @escaping (Result<[AnEnum]?, PigeonError>) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func echoNullableNonNull( + classList classListArg: [AllNullableTypes]?, + completion: @escaping (Result<[AllNullableTypes]?, PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNullable( + _ mapArg: [AnyHashable?: Any?]?, + completion: @escaping (Result<[AnyHashable?: Any?]?, PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNullable( + stringMap stringMapArg: [String?: String?]?, + completion: @escaping (Result<[String?: String?]?, PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNullable( + intMap intMapArg: [Int64?: Int64?]?, + completion: @escaping (Result<[Int64?: Int64?]?, PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNullable( + enumMap enumMapArg: [AnEnum?: AnEnum?]?, + completion: @escaping (Result<[AnEnum?: AnEnum?]?, PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNullable( + classMap classMapArg: [Int64?: AllNullableTypes?]?, + completion: @escaping (Result<[Int64?: AllNullableTypes?]?, PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNullableNonNull( + stringMap stringMapArg: [String: String]?, + completion: @escaping (Result<[String: String]?, PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNullableNonNull( + intMap intMapArg: [Int64: Int64]?, + completion: @escaping (Result<[Int64: Int64]?, PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNullableNonNull( + enumMap enumMapArg: [AnEnum: AnEnum]?, + completion: @escaping (Result<[AnEnum: AnEnum]?, PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNullableNonNull( + classMap classMapArg: [Int64: AllNullableTypes]?, + completion: @escaping (Result<[Int64: AllNullableTypes]?, PigeonError>) -> Void) + /// Returns the passed enum to test serialization and deserialization. + func echoNullable( + _ anEnumArg: AnEnum?, completion: @escaping (Result) -> Void) + /// Returns the passed enum to test serialization and deserialization. + func echoNullable( + _ anotherEnumArg: AnotherEnum?, + completion: @escaping (Result) -> Void) + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic asynchronous calling. + func noopAsync(completion: @escaping (Result) -> Void) + /// Returns the passed in generic Object asynchronously. + func echoAsync(_ aStringArg: String, completion: @escaping (Result) -> Void) +} +class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { + private let binaryMessenger: FlutterBinaryMessenger + private let messageChannelSuffix: String + init(binaryMessenger: FlutterBinaryMessenger, messageChannelSuffix: String = "") { + self.binaryMessenger = binaryMessenger + self.messageChannelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : "" + } + var codec: CoreTestsPigeonCodec { + return CoreTestsPigeonCodec.shared + } + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic calling. + func noop(completion: @escaping (Result) -> Void) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.noop\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage(nil) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + /// Responds with an error from an async function returning a value. + func throwError(completion: @escaping (Result) -> Void) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwError\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage(nil) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + let result: Any? = listResponse[0] + completion(.success(result)) + } + } + } + /// Responds with an error from an async void function. + func throwErrorFromVoid(completion: @escaping (Result) -> Void) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwErrorFromVoid\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage(nil) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + /// Returns the passed object, to test serialization and deserialization. + func echo( + _ everythingArg: AllTypes, completion: @escaping (Result) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllTypes\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([everythingArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! AllTypes + completion(.success(result)) + } + } + } + /// Returns the passed object, to test serialization and deserialization. + func echoNullable( + _ everythingArg: AllNullableTypes?, + completion: @escaping (Result) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypes\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([everythingArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + let result: AllNullableTypes? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } + /// Returns passed in arguments of multiple types. + /// + /// Tests multiple-arity FlutterApi handling. + func sendMultipleNullableTypes( + aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, + aString aNullableStringArg: String?, + completion: @escaping (Result) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypes\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([aNullableBoolArg, aNullableIntArg, aNullableStringArg] as [Any?]) { + response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! AllNullableTypes + completion(.success(result)) + } + } + } + /// Returns the passed object, to test serialization and deserialization. + func echoNullable( + _ everythingArg: AllNullableTypesWithoutRecursion?, + completion: @escaping (Result) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypesWithoutRecursion\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([everythingArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + let result: AllNullableTypesWithoutRecursion? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } + /// Returns passed in arguments of multiple types. + /// + /// Tests multiple-arity FlutterApi handling. + func sendMultipleNullableTypesWithoutRecursion( + aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, + aString aNullableStringArg: String?, + completion: @escaping (Result) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([aNullableBoolArg, aNullableIntArg, aNullableStringArg] as [Any?]) { + response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! AllNullableTypesWithoutRecursion + completion(.success(result)) + } + } + } + /// Returns the passed boolean, to test serialization and deserialization. + func echo(_ aBoolArg: Bool, completion: @escaping (Result) -> Void) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoBool\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([aBoolArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! Bool + completion(.success(result)) + } + } + } + /// Returns the passed int, to test serialization and deserialization. + func echo(_ anIntArg: Int64, completion: @escaping (Result) -> Void) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoInt\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([anIntArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! Int64 + completion(.success(result)) + } + } + } + /// Returns the passed double, to test serialization and deserialization. + func echo(_ aDoubleArg: Double, completion: @escaping (Result) -> Void) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoDouble\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([aDoubleArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! Double + completion(.success(result)) + } + } + } + /// Returns the passed string, to test serialization and deserialization. + func echo(_ aStringArg: String, completion: @escaping (Result) -> Void) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoString\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([aStringArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! String + completion(.success(result)) + } + } + } + /// Returns the passed byte list, to test serialization and deserialization. + func echo( + _ listArg: FlutterStandardTypedData, + completion: @escaping (Result) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoUint8List\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([listArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! FlutterStandardTypedData + completion(.success(result)) + } + } + } /// Returns the passed list, to test serialization and deserialization. - func echo(_ listArg: [Any?], completion: @escaping (Result<[Any?], PigeonError>) -> Void) + func echo(_ listArg: [Any?], completion: @escaping (Result<[Any?], PigeonError>) -> Void) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoList\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([listArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [Any?] + completion(.success(result)) + } + } + } + /// Returns the passed list, to test serialization and deserialization. + func echo( + enumList enumListArg: [AnEnum?], completion: @escaping (Result<[AnEnum?], PigeonError>) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnumList\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([enumListArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [AnEnum?] + completion(.success(result)) + } + } + } + /// Returns the passed list, to test serialization and deserialization. + func echo( + classList classListArg: [AllNullableTypes?], + completion: @escaping (Result<[AllNullableTypes?], PigeonError>) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoClassList\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([classListArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [AllNullableTypes?] + completion(.success(result)) + } + } + } + /// Returns the passed list, to test serialization and deserialization. + func echoNonNull( + enumList enumListArg: [AnEnum], completion: @escaping (Result<[AnEnum], PigeonError>) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullEnumList\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([enumListArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [AnEnum] + completion(.success(result)) + } + } + } + /// Returns the passed list, to test serialization and deserialization. + func echoNonNull( + classList classListArg: [AllNullableTypes], + completion: @escaping (Result<[AllNullableTypes], PigeonError>) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullClassList\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([classListArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [AllNullableTypes] + completion(.success(result)) + } + } + } + /// Returns the passed map, to test serialization and deserialization. + func echo( + _ mapArg: [AnyHashable?: Any?], + completion: @escaping (Result<[AnyHashable?: Any?], PigeonError>) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoMap\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([mapArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [AnyHashable?: Any?] + completion(.success(result)) + } + } + } /// Returns the passed map, to test serialization and deserialization. func echo( - _ aMapArg: [String?: Any?], completion: @escaping (Result<[String?: Any?], PigeonError>) -> Void - ) - /// Returns the passed enum to test serialization and deserialization. - func echo(_ anEnumArg: AnEnum, completion: @escaping (Result) -> Void) - /// Returns the passed boolean, to test serialization and deserialization. - func echoNullable(_ aBoolArg: Bool?, completion: @escaping (Result) -> Void) - /// Returns the passed int, to test serialization and deserialization. - func echoNullable(_ anIntArg: Int64?, completion: @escaping (Result) -> Void) - /// Returns the passed double, to test serialization and deserialization. - func echoNullable( - _ aDoubleArg: Double?, completion: @escaping (Result) -> Void) - /// Returns the passed string, to test serialization and deserialization. - func echoNullable( - _ aStringArg: String?, completion: @escaping (Result) -> Void) - /// Returns the passed byte list, to test serialization and deserialization. - func echoNullable( - _ listArg: FlutterStandardTypedData?, - completion: @escaping (Result) -> Void) - /// Returns the passed list, to test serialization and deserialization. - func echoNullable( - _ listArg: [Any?]?, completion: @escaping (Result<[Any?]?, PigeonError>) -> Void) + stringMap stringMapArg: [String?: String?], + completion: @escaping (Result<[String?: String?], PigeonError>) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoStringMap\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([stringMapArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [String?: String?] + completion(.success(result)) + } + } + } /// Returns the passed map, to test serialization and deserialization. - func echoNullable( - _ aMapArg: [String?: Any?]?, - completion: @escaping (Result<[String?: Any?]?, PigeonError>) -> Void) - /// Returns the passed enum to test serialization and deserialization. - func echoNullable( - _ anEnumArg: AnEnum?, completion: @escaping (Result) -> Void) - /// A no-op function taking no arguments and returning no value, to sanity - /// test basic asynchronous calling. - func noopAsync(completion: @escaping (Result) -> Void) - /// Returns the passed in generic Object asynchronously. - func echoAsync(_ aStringArg: String, completion: @escaping (Result) -> Void) -} -class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { - private let binaryMessenger: FlutterBinaryMessenger - private let messageChannelSuffix: String - init(binaryMessenger: FlutterBinaryMessenger, messageChannelSuffix: String = "") { - self.binaryMessenger = binaryMessenger - self.messageChannelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : "" + func echo( + intMap intMapArg: [Int64?: Int64?], + completion: @escaping (Result<[Int64?: Int64?], PigeonError>) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoIntMap\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([intMapArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [Int64?: Int64?] + completion(.success(result)) + } + } } - var codec: CoreTestsPigeonCodec { - return CoreTestsPigeonCodec.shared + /// Returns the passed map, to test serialization and deserialization. + func echo( + enumMap enumMapArg: [AnEnum?: AnEnum?], + completion: @escaping (Result<[AnEnum?: AnEnum?], PigeonError>) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnumMap\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([enumMapArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as? [AnEnum?: AnEnum?] + completion(.success(result!)) + } + } } - /// A no-op function taking no arguments and returning no value, to sanity - /// test basic calling. - func noop(completion: @escaping (Result) -> Void) { + /// Returns the passed map, to test serialization and deserialization. + func echo( + classMap classMapArg: [Int64?: AllNullableTypes?], + completion: @escaping (Result<[Int64?: AllNullableTypes?], PigeonError>) -> Void + ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.noop\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoClassMap\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage(nil) { response in + channel.sendMessage([classMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2574,18 +4932,28 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - completion(.success(Void())) + let result = listResponse[0] as! [Int64?: AllNullableTypes?] + completion(.success(result)) } } } - /// Responds with an error from an async function returning a value. - func throwError(completion: @escaping (Result) -> Void) { + /// Returns the passed map, to test serialization and deserialization. + func echoNonNull( + stringMap stringMapArg: [String: String], + completion: @escaping (Result<[String: String], PigeonError>) -> Void + ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwError\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullStringMap\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage(nil) { response in + channel.sendMessage([stringMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2595,19 +4963,28 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - let result: Any? = listResponse[0] + let result = listResponse[0] as! [String: String] completion(.success(result)) } } } - /// Responds with an error from an async void function. - func throwErrorFromVoid(completion: @escaping (Result) -> Void) { + /// Returns the passed map, to test serialization and deserialization. + func echoNonNull( + intMap intMapArg: [Int64: Int64], + completion: @escaping (Result<[Int64: Int64], PigeonError>) -> Void + ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwErrorFromVoid\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullIntMap\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage(nil) { response in + channel.sendMessage([intMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2617,20 +4994,117 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - completion(.success(Void())) + let result = listResponse[0] as! [Int64: Int64] + completion(.success(result)) } } } - /// Returns the passed object, to test serialization and deserialization. + /// Returns the passed map, to test serialization and deserialization. + func echoNonNull( + enumMap enumMapArg: [AnEnum: AnEnum], + completion: @escaping (Result<[AnEnum: AnEnum], PigeonError>) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullEnumMap\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([enumMapArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as? [AnEnum: AnEnum] + completion(.success(result!)) + } + } + } + /// Returns the passed map, to test serialization and deserialization. + func echoNonNull( + classMap classMapArg: [Int64: AllNullableTypes], + completion: @escaping (Result<[Int64: AllNullableTypes], PigeonError>) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullClassMap\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([classMapArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [Int64: AllNullableTypes] + completion(.success(result)) + } + } + } + /// Returns the passed enum to test serialization and deserialization. + func echo(_ anEnumArg: AnEnum, completion: @escaping (Result) -> Void) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnum\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([anEnumArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! AnEnum + completion(.success(result)) + } + } + } + /// Returns the passed enum to test serialization and deserialization. func echo( - _ everythingArg: AllTypes, completion: @escaping (Result) -> Void + _ anotherEnumArg: AnotherEnum, completion: @escaping (Result) -> Void ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllTypes\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAnotherEnum\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([everythingArg] as [Any?]) { response in + channel.sendMessage([anotherEnumArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2647,21 +5121,18 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { code: "null-error", message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - let result = listResponse[0] as! AllTypes + let result = listResponse[0] as! AnotherEnum completion(.success(result)) } } } - /// Returns the passed object, to test serialization and deserialization. - func echoNullable( - _ everythingArg: AllNullableTypes?, - completion: @escaping (Result) -> Void - ) { + /// Returns the passed boolean, to test serialization and deserialization. + func echoNullable(_ aBoolArg: Bool?, completion: @escaping (Result) -> Void) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypes\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableBool\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([everythingArg] as [Any?]) { response in + channel.sendMessage([aBoolArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2672,25 +5143,19 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) } else { - let result: AllNullableTypes? = nilOrValue(listResponse[0]) + let result: Bool? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns passed in arguments of multiple types. - /// - /// Tests multiple-arity FlutterApi handling. - func sendMultipleNullableTypes( - aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, - aString aNullableStringArg: String?, - completion: @escaping (Result) -> Void - ) { + /// Returns the passed int, to test serialization and deserialization. + func echoNullable(_ anIntArg: Int64?, completion: @escaping (Result) -> Void) + { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypes\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableInt\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([aNullableBoolArg, aNullableIntArg, aNullableStringArg] as [Any?]) { - response in + channel.sendMessage([anIntArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2700,28 +5165,21 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) - } else if listResponse[0] == nil { - completion( - .failure( - PigeonError( - code: "null-error", - message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - let result = listResponse[0] as! AllNullableTypes + let result: Int64? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns the passed object, to test serialization and deserialization. + /// Returns the passed double, to test serialization and deserialization. func echoNullable( - _ everythingArg: AllNullableTypesWithoutRecursion?, - completion: @escaping (Result) -> Void + _ aDoubleArg: Double?, completion: @escaping (Result) -> Void ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypesWithoutRecursion\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableDouble\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([everythingArg] as [Any?]) { response in + channel.sendMessage([aDoubleArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2732,25 +5190,20 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) } else { - let result: AllNullableTypesWithoutRecursion? = nilOrValue(listResponse[0]) + let result: Double? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns passed in arguments of multiple types. - /// - /// Tests multiple-arity FlutterApi handling. - func sendMultipleNullableTypesWithoutRecursion( - aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, - aString aNullableStringArg: String?, - completion: @escaping (Result) -> Void + /// Returns the passed string, to test serialization and deserialization. + func echoNullable( + _ aStringArg: String?, completion: @escaping (Result) -> Void ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableString\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([aNullableBoolArg, aNullableIntArg, aNullableStringArg] as [Any?]) { - response in + channel.sendMessage([aStringArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2760,25 +5213,22 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) - } else if listResponse[0] == nil { - completion( - .failure( - PigeonError( - code: "null-error", - message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - let result = listResponse[0] as! AllNullableTypesWithoutRecursion + let result: String? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns the passed boolean, to test serialization and deserialization. - func echo(_ aBoolArg: Bool, completion: @escaping (Result) -> Void) { + /// Returns the passed byte list, to test serialization and deserialization. + func echoNullable( + _ listArg: FlutterStandardTypedData?, + completion: @escaping (Result) -> Void + ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoBool\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableUint8List\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([aBoolArg] as [Any?]) { response in + channel.sendMessage([listArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2788,25 +5238,21 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) - } else if listResponse[0] == nil { - completion( - .failure( - PigeonError( - code: "null-error", - message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - let result = listResponse[0] as! Bool + let result: FlutterStandardTypedData? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns the passed int, to test serialization and deserialization. - func echo(_ anIntArg: Int64, completion: @escaping (Result) -> Void) { + /// Returns the passed list, to test serialization and deserialization. + func echoNullable( + _ listArg: [Any?]?, completion: @escaping (Result<[Any?]?, PigeonError>) -> Void + ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoInt\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableList\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([anIntArg] as [Any?]) { response in + channel.sendMessage([listArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2816,26 +5262,22 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) - } else if listResponse[0] == nil { - completion( - .failure( - PigeonError( - code: "null-error", - message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - let result = - listResponse[0] is Int64 ? listResponse[0] as! Int64 : Int64(listResponse[0] as! Int32) + let result: [Any?]? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns the passed double, to test serialization and deserialization. - func echo(_ aDoubleArg: Double, completion: @escaping (Result) -> Void) { + /// Returns the passed list, to test serialization and deserialization. + func echoNullable( + enumList enumListArg: [AnEnum?]?, + completion: @escaping (Result<[AnEnum?]?, PigeonError>) -> Void + ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoDouble\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableEnumList\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([aDoubleArg] as [Any?]) { response in + channel.sendMessage([enumListArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2845,25 +5287,22 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) - } else if listResponse[0] == nil { - completion( - .failure( - PigeonError( - code: "null-error", - message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - let result = listResponse[0] as! Double + let result: [AnEnum?]? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns the passed string, to test serialization and deserialization. - func echo(_ aStringArg: String, completion: @escaping (Result) -> Void) { + /// Returns the passed list, to test serialization and deserialization. + func echoNullable( + classList classListArg: [AllNullableTypes?]?, + completion: @escaping (Result<[AllNullableTypes?]?, PigeonError>) -> Void + ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoString\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableClassList\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([aStringArg] as [Any?]) { response in + channel.sendMessage([classListArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2873,28 +5312,21 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) - } else if listResponse[0] == nil { - completion( - .failure( - PigeonError( - code: "null-error", - message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - let result = listResponse[0] as! String + let result: [AllNullableTypes?]? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns the passed byte list, to test serialization and deserialization. - func echo( - _ listArg: FlutterStandardTypedData, - completion: @escaping (Result) -> Void + /// Returns the passed list, to test serialization and deserialization. + func echoNullableNonNull( + enumList enumListArg: [AnEnum]?, completion: @escaping (Result<[AnEnum]?, PigeonError>) -> Void ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoUint8List\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullEnumList\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([listArg] as [Any?]) { response in + channel.sendMessage([enumListArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2904,25 +5336,22 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) - } else if listResponse[0] == nil { - completion( - .failure( - PigeonError( - code: "null-error", - message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - let result = listResponse[0] as! FlutterStandardTypedData + let result: [AnEnum]? = nilOrValue(listResponse[0]) completion(.success(result)) } } } /// Returns the passed list, to test serialization and deserialization. - func echo(_ listArg: [Any?], completion: @escaping (Result<[Any?], PigeonError>) -> Void) { + func echoNullableNonNull( + classList classListArg: [AllNullableTypes]?, + completion: @escaping (Result<[AllNullableTypes]?, PigeonError>) -> Void + ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoList\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullClassList\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([listArg] as [Any?]) { response in + channel.sendMessage([classListArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2932,27 +5361,22 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) - } else if listResponse[0] == nil { - completion( - .failure( - PigeonError( - code: "null-error", - message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - let result = listResponse[0] as! [Any?] + let result: [AllNullableTypes]? = nilOrValue(listResponse[0]) completion(.success(result)) } } } /// Returns the passed map, to test serialization and deserialization. - func echo( - _ aMapArg: [String?: Any?], completion: @escaping (Result<[String?: Any?], PigeonError>) -> Void + func echoNullable( + _ mapArg: [AnyHashable?: Any?]?, + completion: @escaping (Result<[AnyHashable?: Any?]?, PigeonError>) -> Void ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoMap\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableMap\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([aMapArg] as [Any?]) { response in + channel.sendMessage([mapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2962,25 +5386,22 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) - } else if listResponse[0] == nil { - completion( - .failure( - PigeonError( - code: "null-error", - message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - let result = listResponse[0] as! [String?: Any?] + let result: [AnyHashable?: Any?]? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns the passed enum to test serialization and deserialization. - func echo(_ anEnumArg: AnEnum, completion: @escaping (Result) -> Void) { + /// Returns the passed map, to test serialization and deserialization. + func echoNullable( + stringMap stringMapArg: [String?: String?]?, + completion: @escaping (Result<[String?: String?]?, PigeonError>) -> Void + ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnum\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableStringMap\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([anEnumArg] as [Any?]) { response in + channel.sendMessage([stringMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2990,25 +5411,22 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) - } else if listResponse[0] == nil { - completion( - .failure( - PigeonError( - code: "null-error", - message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - let result = listResponse[0] as! AnEnum + let result: [String?: String?]? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns the passed boolean, to test serialization and deserialization. - func echoNullable(_ aBoolArg: Bool?, completion: @escaping (Result) -> Void) { + /// Returns the passed map, to test serialization and deserialization. + func echoNullable( + intMap intMapArg: [Int64?: Int64?]?, + completion: @escaping (Result<[Int64?: Int64?]?, PigeonError>) -> Void + ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableBool\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableIntMap\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([aBoolArg] as [Any?]) { response in + channel.sendMessage([intMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -3019,19 +5437,21 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) } else { - let result: Bool? = nilOrValue(listResponse[0]) + let result: [Int64?: Int64?]? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns the passed int, to test serialization and deserialization. - func echoNullable(_ anIntArg: Int64?, completion: @escaping (Result) -> Void) - { + /// Returns the passed map, to test serialization and deserialization. + func echoNullable( + enumMap enumMapArg: [AnEnum?: AnEnum?]?, + completion: @escaping (Result<[AnEnum?: AnEnum?]?, PigeonError>) -> Void + ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableInt\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableEnumMap\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([anIntArg] as [Any?]) { response in + channel.sendMessage([enumMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -3042,24 +5462,21 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) } else { - let result: Int64? = - isNullish(listResponse[0]) - ? nil - : (listResponse[0] is Int64? - ? listResponse[0] as! Int64? : Int64(listResponse[0] as! Int32)) - completion(.success(result)) + let result: [AnEnum?: AnEnum?]? = listResponse[0] as? [AnEnum?: AnEnum?] + completion(.success(result!)) } } } - /// Returns the passed double, to test serialization and deserialization. + /// Returns the passed map, to test serialization and deserialization. func echoNullable( - _ aDoubleArg: Double?, completion: @escaping (Result) -> Void + classMap classMapArg: [Int64?: AllNullableTypes?]?, + completion: @escaping (Result<[Int64?: AllNullableTypes?]?, PigeonError>) -> Void ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableDouble\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableClassMap\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([aDoubleArg] as [Any?]) { response in + channel.sendMessage([classMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -3070,20 +5487,21 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) } else { - let result: Double? = nilOrValue(listResponse[0]) + let result: [Int64?: AllNullableTypes?]? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns the passed string, to test serialization and deserialization. - func echoNullable( - _ aStringArg: String?, completion: @escaping (Result) -> Void + /// Returns the passed map, to test serialization and deserialization. + func echoNullableNonNull( + stringMap stringMapArg: [String: String]?, + completion: @escaping (Result<[String: String]?, PigeonError>) -> Void ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableString\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullStringMap\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([aStringArg] as [Any?]) { response in + channel.sendMessage([stringMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -3094,21 +5512,21 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) } else { - let result: String? = nilOrValue(listResponse[0]) + let result: [String: String]? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns the passed byte list, to test serialization and deserialization. - func echoNullable( - _ listArg: FlutterStandardTypedData?, - completion: @escaping (Result) -> Void + /// Returns the passed map, to test serialization and deserialization. + func echoNullableNonNull( + intMap intMapArg: [Int64: Int64]?, + completion: @escaping (Result<[Int64: Int64]?, PigeonError>) -> Void ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableUint8List\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullIntMap\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([listArg] as [Any?]) { response in + channel.sendMessage([intMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -3119,20 +5537,21 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) } else { - let result: FlutterStandardTypedData? = nilOrValue(listResponse[0]) + let result: [Int64: Int64]? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns the passed list, to test serialization and deserialization. - func echoNullable( - _ listArg: [Any?]?, completion: @escaping (Result<[Any?]?, PigeonError>) -> Void + /// Returns the passed map, to test serialization and deserialization. + func echoNullableNonNull( + enumMap enumMapArg: [AnEnum: AnEnum]?, + completion: @escaping (Result<[AnEnum: AnEnum]?, PigeonError>) -> Void ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableList\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullEnumMap\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([listArg] as [Any?]) { response in + channel.sendMessage([enumMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -3143,21 +5562,21 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) } else { - let result: [Any?]? = nilOrValue(listResponse[0]) - completion(.success(result)) + let result: [AnEnum: AnEnum]? = listResponse[0] as? [AnEnum: AnEnum] + completion(.success(result!)) } } } /// Returns the passed map, to test serialization and deserialization. - func echoNullable( - _ aMapArg: [String?: Any?]?, - completion: @escaping (Result<[String?: Any?]?, PigeonError>) -> Void + func echoNullableNonNull( + classMap classMapArg: [Int64: AllNullableTypes]?, + completion: @escaping (Result<[Int64: AllNullableTypes]?, PigeonError>) -> Void ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableMap\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullClassMap\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([aMapArg] as [Any?]) { response in + channel.sendMessage([classMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -3168,7 +5587,7 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) } else { - let result: [String?: Any?]? = nilOrValue(listResponse[0]) + let result: [Int64: AllNullableTypes]? = nilOrValue(listResponse[0]) completion(.success(result)) } } @@ -3197,6 +5616,31 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { } } } + /// Returns the passed enum to test serialization and deserialization. + func echoNullable( + _ anotherEnumArg: AnotherEnum?, + completion: @escaping (Result) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAnotherNullableEnum\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([anotherEnumArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + let result: AnotherEnum? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } /// A no-op function taking no arguments and returning no value, to sanity /// test basic asynchronous calling. func noopAsync(completion: @escaping (Result) -> Void) { diff --git a/packages/pigeon/platform_tests/test_plugin/ios/Classes/ProxyApiTestClass.swift b/packages/pigeon/platform_tests/test_plugin/ios/Classes/ProxyApiTestClass.swift new file mode 100644 index 000000000000..04a14c4e69fe --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/ios/Classes/ProxyApiTestClass.swift @@ -0,0 +1,14 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import Foundation + +class ProxyApiTestClass: ProxyApiSuperClass, ProxyApiInterface {} + +open class ProxyApiSuperClass {} + +protocol ProxyApiInterface {} + +@available(iOS 15, *) +class ClassWithApiRequirement {} diff --git a/packages/pigeon/platform_tests/test_plugin/ios/Classes/ProxyApiTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/ios/Classes/ProxyApiTests.gen.swift new file mode 100644 index 000000000000..d3a699ca47a9 --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/ios/Classes/ProxyApiTests.gen.swift @@ -0,0 +1,4191 @@ +// 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, do not edit directly. +// See also: https://pub.dev/packages/pigeon + +import Foundation + +#if os(iOS) + import Flutter +#elseif os(macOS) + import FlutterMacOS +#else + #error("Unsupported platform.") +#endif + +/// Error class for passing custom error details to Dart side. +final class ProxyApiTestsError: Error { + let code: String + let message: String? + let details: Any? + + init(code: String, message: String?, details: Any?) { + self.code = code + self.message = message + self.details = details + } + + var localizedDescription: String { + return + "ProxyApiTestsError(code: \(code), message: \(message ?? ""), details: \(details ?? "")" + } +} + +private func wrapResult(_ result: Any?) -> [Any?] { + return [result] +} + +private func wrapError(_ error: Any) -> [Any?] { + if let pigeonError = error as? ProxyApiTestsError { + return [ + pigeonError.code, + pigeonError.message, + pigeonError.details, + ] + } + if let flutterError = error as? FlutterError { + return [ + flutterError.code, + flutterError.message, + flutterError.details, + ] + } + return [ + "\(error)", + "\(type(of: error))", + "Stacktrace: \(Thread.callStackSymbols)", + ] +} + +private func createConnectionError(withChannelName channelName: String) -> ProxyApiTestsError { + return ProxyApiTestsError( + code: "channel-error", message: "Unable to establish connection on channel: '\(channelName)'.", + details: "") +} + +private func isNullish(_ value: Any?) -> Bool { + return value is NSNull || value == nil +} + +private func nilOrValue(_ value: Any?) -> T? { + if value is NSNull { return nil } + return value as! T? +} +/// Handles the callback when an object is deallocated. +protocol ProxyApiTestsPigeonInternalFinalizerDelegate: AnyObject { + /// Invoked when the strong reference of an object is deallocated in an `InstanceManager`. + func onDeinit(identifier: Int64) +} + +// Attaches to an object to receive a callback when the object is deallocated. +internal final class ProxyApiTestsPigeonInternalFinalizer { + private static let associatedObjectKey = malloc(1)! + + private let identifier: Int64 + // Reference to the delegate is weak because the callback should be ignored if the + // `InstanceManager` is deallocated. + private weak var delegate: ProxyApiTestsPigeonInternalFinalizerDelegate? + + private init(identifier: Int64, delegate: ProxyApiTestsPigeonInternalFinalizerDelegate) { + self.identifier = identifier + self.delegate = delegate + } + + internal static func attach( + to instance: AnyObject, identifier: Int64, + delegate: ProxyApiTestsPigeonInternalFinalizerDelegate + ) { + let finalizer = ProxyApiTestsPigeonInternalFinalizer(identifier: identifier, delegate: delegate) + objc_setAssociatedObject(instance, associatedObjectKey, finalizer, .OBJC_ASSOCIATION_RETAIN) + } + + static func detach(from instance: AnyObject) { + objc_setAssociatedObject(instance, associatedObjectKey, nil, .OBJC_ASSOCIATION_ASSIGN) + } + + deinit { + delegate?.onDeinit(identifier: identifier) + } +} + +/// Maintains instances used to communicate with the corresponding objects in Dart. +/// +/// Objects stored in this container are represented by an object in Dart that is also stored in +/// an InstanceManager with the same identifier. +/// +/// When an instance is added with an identifier, either can be used to retrieve the other. +/// +/// Added instances are added as a weak reference and a strong reference. When the strong +/// reference is removed and the weak reference is deallocated,`ProxyApiTestsPigeonInternalFinalizerDelegate.onDeinit` +/// is called with the instance's identifier. However, if the strong reference is removed and then the identifier is +/// retrieved with the intention to pass the identifier to Dart (e.g. by calling `identifierWithStrongReference`), +/// the strong reference to the instance is re-added. The strong reference will then need to be removed manually +/// again. +/// +/// Accessing and inserting to an InstanceManager is thread safe. +final class ProxyApiTestsPigeonInstanceManager { + // Identifiers are locked to a specific range to avoid collisions with objects + // created simultaneously from Dart. + // Host uses identifiers >= 2^16 and Dart is expected to use values n where, + // 0 <= n < 2^16. + private static let minHostCreatedIdentifier: Int64 = 65536 + + private let lockQueue = DispatchQueue(label: "ProxyApiTestsPigeonInstanceManager") + private let identifiers: NSMapTable = NSMapTable( + keyOptions: [.weakMemory, .objectPointerPersonality], valueOptions: .strongMemory) + private let weakInstances: NSMapTable = NSMapTable( + keyOptions: .strongMemory, valueOptions: [.weakMemory, .objectPointerPersonality]) + private let strongInstances: NSMapTable = NSMapTable( + keyOptions: .strongMemory, valueOptions: [.strongMemory, .objectPointerPersonality]) + private let finalizerDelegate: ProxyApiTestsPigeonInternalFinalizerDelegate + private var nextIdentifier: Int64 = minHostCreatedIdentifier + + public init(finalizerDelegate: ProxyApiTestsPigeonInternalFinalizerDelegate) { + self.finalizerDelegate = finalizerDelegate + } + + /// Adds a new instance that was instantiated from Dart. + /// + /// The same instance can be added multiple times, but each identifier must be unique. This allows + /// two objects that are equivalent (e.g. conforms to `Equatable`) to both be added. + /// + /// - Parameters: + /// - instance: the instance to be stored + /// - identifier: the identifier to be paired with instance. This value must be >= 0 and unique + func addDartCreatedInstance(_ instance: AnyObject, withIdentifier identifier: Int64) { + lockQueue.async { + self.addInstance(instance, withIdentifier: identifier) + } + } + + /// Adds a new instance that was instantiated from the host platform. + /// + /// - Parameters: + /// - instance: the instance to be stored. This must be unique to all other added instances. + /// - Returns: the unique identifier (>= 0) stored with instance + func addHostCreatedInstance(_ instance: AnyObject) -> Int64 { + assert(!containsInstance(instance), "Instance of \(instance) has already been added.") + var identifier: Int64 = -1 + lockQueue.sync { + identifier = nextIdentifier + nextIdentifier += 1 + self.addInstance(instance, withIdentifier: identifier) + } + return identifier + } + + /// Removes `instanceIdentifier` and its associated strongly referenced instance, if present, from the manager. + /// + /// - Parameters: + /// - instanceIdentifier: the identifier paired to an instance. + /// - Returns: removed instance if the manager contains the given identifier, otherwise `nil` if + /// the manager doesn't contain the value + func removeInstance(withIdentifier instanceIdentifier: Int64) throws -> T? { + var instance: AnyObject? = nil + lockQueue.sync { + instance = strongInstances.object(forKey: NSNumber(value: instanceIdentifier)) + strongInstances.removeObject(forKey: NSNumber(value: instanceIdentifier)) + } + return instance as? T + } + + /// Retrieves the instance associated with identifier. + /// + /// - Parameters: + /// - instanceIdentifier: the identifier associated with an instance + /// - Returns: the instance associated with `instanceIdentifier` if the manager contains the value, otherwise + /// `nil` if the manager doesn't contain the value + func instance(forIdentifier instanceIdentifier: Int64) -> T? { + var instance: AnyObject? = nil + lockQueue.sync { + instance = weakInstances.object(forKey: NSNumber(value: instanceIdentifier)) + } + return instance as? T + } + + private func addInstance(_ instance: AnyObject, withIdentifier identifier: Int64) { + assert(identifier >= 0) + assert( + weakInstances.object(forKey: identifier as NSNumber) == nil, + "Identifier has already been added: \(identifier)") + identifiers.setObject(NSNumber(value: identifier), forKey: instance) + weakInstances.setObject(instance, forKey: NSNumber(value: identifier)) + strongInstances.setObject(instance, forKey: NSNumber(value: identifier)) + ProxyApiTestsPigeonInternalFinalizer.attach( + to: instance, identifier: identifier, delegate: finalizerDelegate) + } + + /// Retrieves the identifier paired with an instance. + /// + /// If the manager contains a strong reference to `instance`, it will return the identifier + /// associated with `instance`. If the manager contains only a weak reference to `instance`, a new + /// strong reference to `instance` will be added and will need to be removed again with `removeInstance`. + /// + /// If this method returns a nonnull identifier, this method also expects the Dart + /// `ProxyApiTestsPigeonInstanceManager` to have, or recreate, a weak reference to the Dart instance the + /// identifier is associated with. + /// + /// - Parameters: + /// - instance: an instance that may be stored in the manager + /// - Returns: the identifier associated with `instance` if the manager contains the value, otherwise + /// `nil` if the manager doesn't contain the value + func identifierWithStrongReference(forInstance instance: AnyObject) -> Int64? { + var identifier: Int64? = nil + lockQueue.sync { + if let existingIdentifier = identifiers.object(forKey: instance)?.int64Value { + strongInstances.setObject(instance, forKey: NSNumber(value: existingIdentifier)) + identifier = existingIdentifier + } + } + return identifier + } + + /// Whether this manager contains the given `instance`. + /// + /// - Parameters: + /// - instance: the instance whose presence in this manager is to be tested + /// - Returns: whether this manager contains the given `instance` + func containsInstance(_ instance: AnyObject) -> Bool { + var containsInstance = false + lockQueue.sync { + containsInstance = identifiers.object(forKey: instance) != nil + } + return containsInstance + } + + /// Removes all of the instances from this manager. + /// + /// The manager will be empty after this call returns. + func removeAllObjects() throws { + lockQueue.sync { + identifiers.removeAllObjects() + weakInstances.removeAllObjects() + strongInstances.removeAllObjects() + nextIdentifier = ProxyApiTestsPigeonInstanceManager.minHostCreatedIdentifier + } + } + + /// The number of instances stored as a strong reference. + /// + /// For debugging and testing purposes. + internal var strongInstanceCount: Int { + var count: Int = 0 + lockQueue.sync { + count = strongInstances.count + } + return count + } + + /// The number of instances stored as a weak reference. + /// + /// For debugging and testing purposes. NSMapTables that store keys or objects as weak + /// reference will be reclaimed non-deterministically. + internal var weakInstanceCount: Int { + var count: Int = 0 + lockQueue.sync { + count = weakInstances.count + } + return count + } +} + +private class ProxyApiTestsPigeonInstanceManagerApi { + /// The codec used for serializing messages. + var codec: FlutterStandardMessageCodec { ProxyApiTestsPigeonCodec.shared } + + /// Handles sending and receiving messages with Dart. + unowned let binaryMessenger: FlutterBinaryMessenger + + init(binaryMessenger: FlutterBinaryMessenger) { + self.binaryMessenger = binaryMessenger + } + + /// Sets up an instance of `ProxyApiTestsPigeonInstanceManagerApi` to handle messages through the `binaryMessenger`. + static func setUpMessageHandlers( + binaryMessenger: FlutterBinaryMessenger, instanceManager: ProxyApiTestsPigeonInstanceManager? + ) { + let codec = ProxyApiTestsPigeonCodec.shared + let removeStrongReferenceChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.PigeonInternalInstanceManager.removeStrongReference", + binaryMessenger: binaryMessenger, codec: codec) + if let instanceManager = instanceManager { + removeStrongReferenceChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let identifierArg = args[0] as! Int64 + do { + let _: AnyObject? = try instanceManager.removeInstance(withIdentifier: identifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + removeStrongReferenceChannel.setMessageHandler(nil) + } + let clearChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.PigeonInternalInstanceManager.clear", + binaryMessenger: binaryMessenger, codec: codec) + if let instanceManager = instanceManager { + clearChannel.setMessageHandler { _, reply in + do { + try instanceManager.removeAllObjects() + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + clearChannel.setMessageHandler(nil) + } + } + + /// Sends a message to the Dart `InstanceManager` to remove the strong reference of the instance associated with `identifier`. + func removeStrongReference( + identifier identifierArg: Int64, + completion: @escaping (Result) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.PigeonInternalInstanceManager.removeStrongReference" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([identifierArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} +protocol ProxyApiTestsPigeonProxyApiDelegate { + /// An implementation of [PigeonApiProxyApiTestClass] used to add a new Dart instance of + /// `ProxyApiTestClass` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiProxyApiTestClass(_ registrar: ProxyApiTestsPigeonProxyApiRegistrar) + -> PigeonApiProxyApiTestClass + /// An implementation of [PigeonApiProxyApiSuperClass] used to add a new Dart instance of + /// `ProxyApiSuperClass` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiProxyApiSuperClass(_ registrar: ProxyApiTestsPigeonProxyApiRegistrar) + -> PigeonApiProxyApiSuperClass + /// An implementation of [PigeonApiProxyApiInterface] used to add a new Dart instance of + /// `ProxyApiInterface` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiProxyApiInterface(_ registrar: ProxyApiTestsPigeonProxyApiRegistrar) + -> PigeonApiProxyApiInterface + /// An implementation of [PigeonApiClassWithApiRequirement] used to add a new Dart instance of + /// `ClassWithApiRequirement` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiClassWithApiRequirement(_ registrar: ProxyApiTestsPigeonProxyApiRegistrar) + -> PigeonApiClassWithApiRequirement +} + +extension ProxyApiTestsPigeonProxyApiDelegate { + func pigeonApiProxyApiInterface(_ registrar: ProxyApiTestsPigeonProxyApiRegistrar) + -> PigeonApiProxyApiInterface + { + return PigeonApiProxyApiInterface( + pigeonRegistrar: registrar, delegate: PigeonApiDelegateProxyApiInterface()) + } +} + +open class ProxyApiTestsPigeonProxyApiRegistrar { + let binaryMessenger: FlutterBinaryMessenger + let apiDelegate: ProxyApiTestsPigeonProxyApiDelegate + let instanceManager: ProxyApiTestsPigeonInstanceManager + /// Whether APIs should ignore calling to Dart. + public var ignoreCallsToDart = false + private var _codec: FlutterStandardMessageCodec? + var codec: FlutterStandardMessageCodec { + if _codec == nil { + _codec = FlutterStandardMessageCodec( + readerWriter: ProxyApiTestsPigeonInternalProxyApiCodecReaderWriter(pigeonRegistrar: self)) + } + return _codec! + } + + private class InstanceManagerApiFinalizerDelegate: ProxyApiTestsPigeonInternalFinalizerDelegate { + let api: ProxyApiTestsPigeonInstanceManagerApi + + init(_ api: ProxyApiTestsPigeonInstanceManagerApi) { + self.api = api + } + + public func onDeinit(identifier: Int64) { + api.removeStrongReference(identifier: identifier) { + _ in + } + } + } + + init(binaryMessenger: FlutterBinaryMessenger, apiDelegate: ProxyApiTestsPigeonProxyApiDelegate) { + self.binaryMessenger = binaryMessenger + self.apiDelegate = apiDelegate + self.instanceManager = ProxyApiTestsPigeonInstanceManager( + finalizerDelegate: InstanceManagerApiFinalizerDelegate( + ProxyApiTestsPigeonInstanceManagerApi(binaryMessenger: binaryMessenger))) + } + + func setUp() { + ProxyApiTestsPigeonInstanceManagerApi.setUpMessageHandlers( + binaryMessenger: binaryMessenger, instanceManager: instanceManager) + PigeonApiProxyApiTestClass.setUpMessageHandlers( + binaryMessenger: binaryMessenger, api: apiDelegate.pigeonApiProxyApiTestClass(self)) + PigeonApiProxyApiSuperClass.setUpMessageHandlers( + binaryMessenger: binaryMessenger, api: apiDelegate.pigeonApiProxyApiSuperClass(self)) + PigeonApiClassWithApiRequirement.setUpMessageHandlers( + binaryMessenger: binaryMessenger, api: apiDelegate.pigeonApiClassWithApiRequirement(self)) + } + func tearDown() { + ProxyApiTestsPigeonInstanceManagerApi.setUpMessageHandlers( + binaryMessenger: binaryMessenger, instanceManager: nil) + PigeonApiProxyApiTestClass.setUpMessageHandlers(binaryMessenger: binaryMessenger, api: nil) + PigeonApiProxyApiSuperClass.setUpMessageHandlers(binaryMessenger: binaryMessenger, api: nil) + PigeonApiClassWithApiRequirement.setUpMessageHandlers( + binaryMessenger: binaryMessenger, api: nil) + } +} +private class ProxyApiTestsPigeonInternalProxyApiCodecReaderWriter: FlutterStandardReaderWriter { + unowned let pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar + + private class ProxyApiTestsPigeonInternalProxyApiCodecReader: ProxyApiTestsPigeonCodecReader { + unowned let pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar + + init(data: Data, pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar) { + self.pigeonRegistrar = pigeonRegistrar + super.init(data: data) + } + + override func readValue(ofType type: UInt8) -> Any? { + switch type { + case 128: + let identifier = self.readValue() + let instance: AnyObject? = pigeonRegistrar.instanceManager.instance( + forIdentifier: identifier is Int64 ? identifier as! Int64 : Int64(identifier as! Int32)) + return instance + default: + return super.readValue(ofType: type) + } + } + } + + private class ProxyApiTestsPigeonInternalProxyApiCodecWriter: ProxyApiTestsPigeonCodecWriter { + unowned let pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar + + init(data: NSMutableData, pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar) { + self.pigeonRegistrar = pigeonRegistrar + super.init(data: data) + } + + override func writeValue(_ value: Any) { + if value is [Any] || value is Bool || value is Data || value is [AnyHashable: Any] + || value is Double || value is FlutterStandardTypedData || value is Int64 || value is String + || value is ProxyApiTestEnum + { + super.writeValue(value) + return + } + + if let instance = value as? ProxyApiTestClass { + pigeonRegistrar.apiDelegate.pigeonApiProxyApiTestClass(pigeonRegistrar).pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as? ProxyApiSuperClass { + pigeonRegistrar.apiDelegate.pigeonApiProxyApiSuperClass(pigeonRegistrar).pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as? ProxyApiInterface { + pigeonRegistrar.apiDelegate.pigeonApiProxyApiInterface(pigeonRegistrar).pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if #available(iOS 15.0.0, macOS 10.0.0, *), let instance = value as? ClassWithApiRequirement { + pigeonRegistrar.apiDelegate.pigeonApiClassWithApiRequirement(pigeonRegistrar) + .pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as AnyObject?, + pigeonRegistrar.instanceManager.containsInstance(instance) + { + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference(forInstance: instance)!) + } else { + print("Unsupported value: \(value) of \(type(of: value))") + assert(false, "Unsupported value for ProxyApiTestsPigeonInternalProxyApiCodecWriter") + } + + } + } + + init(pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar) { + self.pigeonRegistrar = pigeonRegistrar + } + + override func reader(with data: Data) -> FlutterStandardReader { + return ProxyApiTestsPigeonInternalProxyApiCodecReader( + data: data, pigeonRegistrar: pigeonRegistrar) + } + + override func writer(with data: NSMutableData) -> FlutterStandardWriter { + return ProxyApiTestsPigeonInternalProxyApiCodecWriter( + data: data, pigeonRegistrar: pigeonRegistrar) + } +} + +enum ProxyApiTestEnum: Int { + case one = 0 + case two = 1 + case three = 2 +} + +private class ProxyApiTestsPigeonCodecReader: FlutterStandardReader { + override func readValue(ofType type: UInt8) -> Any? { + switch type { + case 129: + let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?) + if let enumResultAsInt = enumResultAsInt { + return ProxyApiTestEnum(rawValue: enumResultAsInt) + } + return nil + default: + return super.readValue(ofType: type) + } + } +} + +private class ProxyApiTestsPigeonCodecWriter: FlutterStandardWriter { + override func writeValue(_ value: Any) { + if let value = value as? ProxyApiTestEnum { + super.writeByte(129) + super.writeValue(value.rawValue) + } else { + super.writeValue(value) + } + } +} + +private class ProxyApiTestsPigeonCodecReaderWriter: FlutterStandardReaderWriter { + override func reader(with data: Data) -> FlutterStandardReader { + return ProxyApiTestsPigeonCodecReader(data: data) + } + + override func writer(with data: NSMutableData) -> FlutterStandardWriter { + return ProxyApiTestsPigeonCodecWriter(data: data) + } +} + +class ProxyApiTestsPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable { + static let shared = ProxyApiTestsPigeonCodec(readerWriter: ProxyApiTestsPigeonCodecReaderWriter()) +} + +protocol PigeonApiDelegateProxyApiTestClass { + func pigeonDefaultConstructor( + pigeonApi: PigeonApiProxyApiTestClass, aBool: Bool, anInt: Int64, aDouble: Double, + aString: String, aUint8List: FlutterStandardTypedData, aList: [Any?], aMap: [String?: Any?], + anEnum: ProxyApiTestEnum, aProxyApi: ProxyApiSuperClass, aNullableBool: Bool?, + aNullableInt: Int64?, aNullableDouble: Double?, aNullableString: String?, + aNullableUint8List: FlutterStandardTypedData?, aNullableList: [Any?]?, + aNullableMap: [String?: Any?]?, aNullableEnum: ProxyApiTestEnum?, + aNullableProxyApi: ProxyApiSuperClass?, boolParam: Bool, intParam: Int64, doubleParam: Double, + stringParam: String, aUint8ListParam: FlutterStandardTypedData, listParam: [Any?], + mapParam: [String?: Any?], enumParam: ProxyApiTestEnum, proxyApiParam: ProxyApiSuperClass, + nullableBoolParam: Bool?, nullableIntParam: Int64?, nullableDoubleParam: Double?, + nullableStringParam: String?, nullableUint8ListParam: FlutterStandardTypedData?, + nullableListParam: [Any?]?, nullableMapParam: [String?: Any?]?, + nullableEnumParam: ProxyApiTestEnum?, nullableProxyApiParam: ProxyApiSuperClass? + ) throws -> ProxyApiTestClass + func attachedField(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> ProxyApiSuperClass + func staticAttachedField(pigeonApi: PigeonApiProxyApiTestClass) throws -> ProxyApiSuperClass + func aBool(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> Bool + func anInt(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> Int64 + func aDouble(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> Double + func aString(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> String + func aUint8List(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> FlutterStandardTypedData + func aList(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> [Any?] + func aMap(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> [String?: Any?] + func anEnum(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> ProxyApiTestEnum + func aProxyApi(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> ProxyApiSuperClass + func aNullableBool(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> Bool? + func aNullableInt(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> Int64? + func aNullableDouble(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> Double? + func aNullableString(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> String? + func aNullableUint8List(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> FlutterStandardTypedData? + func aNullableList(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> [Any?]? + func aNullableMap(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> [String?: Any?]? + func aNullableEnum(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> ProxyApiTestEnum? + func aNullableProxyApi(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> ProxyApiSuperClass? + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic calling. + func noop(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + /// Returns an error, to test error handling. + func throwError(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> Any? + /// Returns an error from a void function, to test error handling. + func throwErrorFromVoid(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws + /// Returns a Flutter error, to test error handling. + func throwFlutterError(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> Any? + /// Returns passed in int. + func echoInt( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anInt: Int64 + ) throws -> Int64 + /// Returns passed in double. + func echoDouble( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aDouble: Double + ) throws -> Double + /// Returns the passed in boolean. + func echoBool( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aBool: Bool + ) throws -> Bool + /// Returns the passed in string. + func echoString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aString: String + ) throws -> String + /// Returns the passed in Uint8List. + func echoUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aUint8List: FlutterStandardTypedData + ) throws -> FlutterStandardTypedData + /// Returns the passed in generic Object. + func echoObject( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anObject: Any + ) throws -> Any + /// Returns the passed list, to test serialization and deserialization. + func echoList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aList: [Any?] + ) throws -> [Any?] + /// Returns the passed list with ProxyApis, to test serialization and + /// deserialization. + func echoProxyApiList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aList: [ProxyApiTestClass] + ) throws -> [ProxyApiTestClass] + /// Returns the passed map, to test serialization and deserialization. + func echoMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aMap: [String?: Any?] + ) throws -> [String?: Any?] + /// Returns the passed map with ProxyApis, to test serialization and + /// deserialization. + func echoProxyApiMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aMap: [String: ProxyApiTestClass] + ) throws -> [String: ProxyApiTestClass] + /// Returns the passed enum to test serialization and deserialization. + func echoEnum( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum + ) throws -> ProxyApiTestEnum + /// Returns the passed ProxyApi to test serialization and deserialization. + func echoProxyApi( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aProxyApi: ProxyApiSuperClass + ) throws -> ProxyApiSuperClass + /// Returns passed in int. + func echoNullableInt( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aNullableInt: Int64? + ) throws -> Int64? + /// Returns passed in double. + func echoNullableDouble( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableDouble: Double? + ) throws -> Double? + /// Returns the passed in boolean. + func echoNullableBool( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aNullableBool: Bool? + ) throws -> Bool? + /// Returns the passed in string. + func echoNullableString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableString: String? + ) throws -> String? + /// Returns the passed in Uint8List. + func echoNullableUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableUint8List: FlutterStandardTypedData? + ) throws -> FlutterStandardTypedData? + /// Returns the passed in generic Object. + func echoNullableObject( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aNullableObject: Any? + ) throws -> Any? + /// Returns the passed list, to test serialization and deserialization. + func echoNullableList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aNullableList: [Any?]? + ) throws -> [Any?]? + /// Returns the passed map, to test serialization and deserialization. + func echoNullableMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableMap: [String?: Any?]? + ) throws -> [String?: Any?]? + func echoNullableEnum( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableEnum: ProxyApiTestEnum? + ) throws -> ProxyApiTestEnum? + /// Returns the passed ProxyApi to test serialization and deserialization. + func echoNullableProxyApi( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableProxyApi: ProxyApiSuperClass? + ) throws -> ProxyApiSuperClass? + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic asynchronous calling. + func noopAsync( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void) + /// Returns passed in int asynchronously. + func echoAsyncInt( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anInt: Int64, + completion: @escaping (Result) -> Void) + /// Returns passed in double asynchronously. + func echoAsyncDouble( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aDouble: Double, + completion: @escaping (Result) -> Void) + /// Returns the passed in boolean asynchronously. + func echoAsyncBool( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aBool: Bool, + completion: @escaping (Result) -> Void) + /// Returns the passed string asynchronously. + func echoAsyncString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aString: String, + completion: @escaping (Result) -> Void) + /// Returns the passed in Uint8List asynchronously. + func echoAsyncUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aUint8List: FlutterStandardTypedData, + completion: @escaping (Result) -> Void) + /// Returns the passed in generic Object asynchronously. + func echoAsyncObject( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anObject: Any, + completion: @escaping (Result) -> Void) + /// Returns the passed list, to test asynchronous serialization and deserialization. + func echoAsyncList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aList: [Any?], + completion: @escaping (Result<[Any?], Error>) -> Void) + /// Returns the passed map, to test asynchronous serialization and deserialization. + func echoAsyncMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aMap: [String?: Any?], + completion: @escaping (Result<[String?: Any?], Error>) -> Void) + /// Returns the passed enum, to test asynchronous serialization and deserialization. + func echoAsyncEnum( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum, completion: @escaping (Result) -> Void) + /// Responds with an error from an async function returning a value. + func throwAsyncError( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void) + /// Responds with an error from an async void function. + func throwAsyncErrorFromVoid( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void) + /// Responds with a Flutter error from an async function returning a value. + func throwAsyncFlutterError( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void) + /// Returns passed in int asynchronously. + func echoAsyncNullableInt( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anInt: Int64?, + completion: @escaping (Result) -> Void) + /// Returns passed in double asynchronously. + func echoAsyncNullableDouble( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aDouble: Double?, + completion: @escaping (Result) -> Void) + /// Returns the passed in boolean asynchronously. + func echoAsyncNullableBool( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aBool: Bool?, + completion: @escaping (Result) -> Void) + /// Returns the passed string asynchronously. + func echoAsyncNullableString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aString: String?, + completion: @escaping (Result) -> Void) + /// Returns the passed in Uint8List asynchronously. + func echoAsyncNullableUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aUint8List: FlutterStandardTypedData?, + completion: @escaping (Result) -> Void) + /// Returns the passed in generic Object asynchronously. + func echoAsyncNullableObject( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anObject: Any?, + completion: @escaping (Result) -> Void) + /// Returns the passed list, to test asynchronous serialization and deserialization. + func echoAsyncNullableList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aList: [Any?]?, + completion: @escaping (Result<[Any?]?, Error>) -> Void) + /// Returns the passed map, to test asynchronous serialization and deserialization. + func echoAsyncNullableMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aMap: [String?: Any?]?, completion: @escaping (Result<[String?: Any?]?, Error>) -> Void) + /// Returns the passed enum, to test asynchronous serialization and deserialization. + func echoAsyncNullableEnum( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum?, completion: @escaping (Result) -> Void) + func staticNoop(pigeonApi: PigeonApiProxyApiTestClass) throws + func echoStaticString(pigeonApi: PigeonApiProxyApiTestClass, aString: String) throws -> String + func staticAsyncNoop( + pigeonApi: PigeonApiProxyApiTestClass, completion: @escaping (Result) -> Void) + func callFlutterNoop( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void) + func callFlutterThrowError( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void) + func callFlutterThrowErrorFromVoid( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void) + func callFlutterEchoBool( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aBool: Bool, + completion: @escaping (Result) -> Void) + func callFlutterEchoInt( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anInt: Int64, + completion: @escaping (Result) -> Void) + func callFlutterEchoDouble( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aDouble: Double, + completion: @escaping (Result) -> Void) + func callFlutterEchoString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aString: String, + completion: @escaping (Result) -> Void) + func callFlutterEchoUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aUint8List: FlutterStandardTypedData, + completion: @escaping (Result) -> Void) + func callFlutterEchoList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aList: [Any?], + completion: @escaping (Result<[Any?], Error>) -> Void) + func callFlutterEchoProxyApiList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aList: [ProxyApiTestClass?], completion: @escaping (Result<[ProxyApiTestClass?], Error>) -> Void + ) + func callFlutterEchoMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aMap: [String?: Any?], + completion: @escaping (Result<[String?: Any?], Error>) -> Void) + func callFlutterEchoProxyApiMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aMap: [String?: ProxyApiTestClass?], + completion: @escaping (Result<[String?: ProxyApiTestClass?], Error>) -> Void) + func callFlutterEchoEnum( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum, completion: @escaping (Result) -> Void) + func callFlutterEchoProxyApi( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aProxyApi: ProxyApiSuperClass, completion: @escaping (Result) -> Void + ) + func callFlutterEchoNullableBool( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aBool: Bool?, + completion: @escaping (Result) -> Void) + func callFlutterEchoNullableInt( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anInt: Int64?, + completion: @escaping (Result) -> Void) + func callFlutterEchoNullableDouble( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aDouble: Double?, + completion: @escaping (Result) -> Void) + func callFlutterEchoNullableString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aString: String?, + completion: @escaping (Result) -> Void) + func callFlutterEchoNullableUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aUint8List: FlutterStandardTypedData?, + completion: @escaping (Result) -> Void) + func callFlutterEchoNullableList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aList: [Any?]?, + completion: @escaping (Result<[Any?]?, Error>) -> Void) + func callFlutterEchoNullableMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aMap: [String?: Any?]?, completion: @escaping (Result<[String?: Any?]?, Error>) -> Void) + func callFlutterEchoNullableEnum( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum?, completion: @escaping (Result) -> Void) + func callFlutterEchoNullableProxyApi( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aProxyApi: ProxyApiSuperClass?, + completion: @escaping (Result) -> Void) + func callFlutterNoopAsync( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void) + func callFlutterEchoAsyncString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aString: String, + completion: @escaping (Result) -> Void) +} + +protocol PigeonApiProtocolProxyApiTestClass { + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic calling. + func flutterNoop( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, + completion: @escaping (Result) -> Void) + /// Responds with an error from an async function returning a value. + func flutterThrowError( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, + completion: @escaping (Result) -> Void) + /// Responds with an error from an async void function. + func flutterThrowErrorFromVoid( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, + completion: @escaping (Result) -> Void) + /// Returns the passed boolean, to test serialization and deserialization. + func flutterEchoBool( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aBool aBoolArg: Bool, + completion: @escaping (Result) -> Void) + /// Returns the passed int, to test serialization and deserialization. + func flutterEchoInt( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, anInt anIntArg: Int64, + completion: @escaping (Result) -> Void) + /// Returns the passed double, to test serialization and deserialization. + func flutterEchoDouble( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aDouble aDoubleArg: Double, + completion: @escaping (Result) -> Void) + /// Returns the passed string, to test serialization and deserialization. + func flutterEchoString( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aString aStringArg: String, + completion: @escaping (Result) -> Void) + /// Returns the passed byte list, to test serialization and deserialization. + func flutterEchoUint8List( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aList aListArg: FlutterStandardTypedData, + completion: @escaping (Result) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func flutterEchoList( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aList aListArg: [Any?], + completion: @escaping (Result<[Any?], ProxyApiTestsError>) -> Void) + /// Returns the passed list with ProxyApis, to test serialization and + /// deserialization. + func flutterEchoProxyApiList( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aList aListArg: [ProxyApiTestClass?], + completion: @escaping (Result<[ProxyApiTestClass?], ProxyApiTestsError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func flutterEchoMap( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aMap aMapArg: [String?: Any?], + completion: @escaping (Result<[String?: Any?], ProxyApiTestsError>) -> Void) + /// Returns the passed map with ProxyApis, to test serialization and + /// deserialization. + func flutterEchoProxyApiMap( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, + aMap aMapArg: [String?: ProxyApiTestClass?], + completion: @escaping (Result<[String?: ProxyApiTestClass?], ProxyApiTestsError>) -> Void) + /// Returns the passed enum to test serialization and deserialization. + func flutterEchoEnum( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, anEnum anEnumArg: ProxyApiTestEnum, + completion: @escaping (Result) -> Void) + /// Returns the passed ProxyApi to test serialization and deserialization. + func flutterEchoProxyApi( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aProxyApi aProxyApiArg: ProxyApiSuperClass, + completion: @escaping (Result) -> Void) + /// Returns the passed boolean, to test serialization and deserialization. + func flutterEchoNullableBool( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aBool aBoolArg: Bool?, + completion: @escaping (Result) -> Void) + /// Returns the passed int, to test serialization and deserialization. + func flutterEchoNullableInt( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, anInt anIntArg: Int64?, + completion: @escaping (Result) -> Void) + /// Returns the passed double, to test serialization and deserialization. + func flutterEchoNullableDouble( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aDouble aDoubleArg: Double?, + completion: @escaping (Result) -> Void) + /// Returns the passed string, to test serialization and deserialization. + func flutterEchoNullableString( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aString aStringArg: String?, + completion: @escaping (Result) -> Void) + /// Returns the passed byte list, to test serialization and deserialization. + func flutterEchoNullableUint8List( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aList aListArg: FlutterStandardTypedData?, + completion: @escaping (Result) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func flutterEchoNullableList( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aList aListArg: [Any?]?, + completion: @escaping (Result<[Any?]?, ProxyApiTestsError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func flutterEchoNullableMap( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aMap aMapArg: [String?: Any?]?, + completion: @escaping (Result<[String?: Any?]?, ProxyApiTestsError>) -> Void) + /// Returns the passed enum to test serialization and deserialization. + func flutterEchoNullableEnum( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, anEnum anEnumArg: ProxyApiTestEnum?, + completion: @escaping (Result) -> Void) + /// Returns the passed ProxyApi to test serialization and deserialization. + func flutterEchoNullableProxyApi( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, + aProxyApi aProxyApiArg: ProxyApiSuperClass?, + completion: @escaping (Result) -> Void) + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic asynchronous calling. + func flutterNoopAsync( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, + completion: @escaping (Result) -> Void) + /// Returns the passed in generic Object asynchronously. + func flutterEchoAsyncString( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aString aStringArg: String, + completion: @escaping (Result) -> Void) +} + +final class PigeonApiProxyApiTestClass: PigeonApiProtocolProxyApiTestClass { + unowned let pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateProxyApiTestClass + ///An implementation of [ProxyApiSuperClass] used to access callback methods + var pigeonApiProxyApiSuperClass: PigeonApiProxyApiSuperClass { + return pigeonRegistrar.apiDelegate.pigeonApiProxyApiSuperClass(pigeonRegistrar) + } + + ///An implementation of [ProxyApiInterface] used to access callback methods + var pigeonApiProxyApiInterface: PigeonApiProxyApiInterface { + return pigeonRegistrar.apiDelegate.pigeonApiProxyApiInterface(pigeonRegistrar) + } + + init( + pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateProxyApiTestClass + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + static func setUpMessageHandlers( + binaryMessenger: FlutterBinaryMessenger, api: PigeonApiProxyApiTestClass? + ) { + let codec: FlutterStandardMessageCodec = + api != nil + ? FlutterStandardMessageCodec( + readerWriter: ProxyApiTestsPigeonInternalProxyApiCodecReaderWriter( + pigeonRegistrar: api!.pigeonRegistrar)) + : FlutterStandardMessageCodec.sharedInstance() + let pigeonDefaultConstructorChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.pigeon_defaultConstructor", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + pigeonDefaultConstructorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonIdentifierArg = args[0] as! Int64 + let aBoolArg = args[1] as! Bool + let anIntArg = args[2] as! Int64 + let aDoubleArg = args[3] as! Double + let aStringArg = args[4] as! String + let aUint8ListArg = args[5] as! FlutterStandardTypedData + let aListArg = args[6] as! [Any?] + let aMapArg = args[7] as! [String?: Any?] + let anEnumArg = args[8] as! ProxyApiTestEnum + let aProxyApiArg = args[9] as! ProxyApiSuperClass + let aNullableBoolArg: Bool? = nilOrValue(args[10]) + let aNullableIntArg: Int64? = nilOrValue(args[11]) + let aNullableDoubleArg: Double? = nilOrValue(args[12]) + let aNullableStringArg: String? = nilOrValue(args[13]) + let aNullableUint8ListArg: FlutterStandardTypedData? = nilOrValue(args[14]) + let aNullableListArg: [Any?]? = nilOrValue(args[15]) + let aNullableMapArg: [String?: Any?]? = nilOrValue(args[16]) + let aNullableEnumArg: ProxyApiTestEnum? = nilOrValue(args[17]) + let aNullableProxyApiArg: ProxyApiSuperClass? = nilOrValue(args[18]) + let boolParamArg = args[19] as! Bool + let intParamArg = args[20] as! Int64 + let doubleParamArg = args[21] as! Double + let stringParamArg = args[22] as! String + let aUint8ListParamArg = args[23] as! FlutterStandardTypedData + let listParamArg = args[24] as! [Any?] + let mapParamArg = args[25] as! [String?: Any?] + let enumParamArg = args[26] as! ProxyApiTestEnum + let proxyApiParamArg = args[27] as! ProxyApiSuperClass + let nullableBoolParamArg: Bool? = nilOrValue(args[28]) + let nullableIntParamArg: Int64? = nilOrValue(args[29]) + let nullableDoubleParamArg: Double? = nilOrValue(args[30]) + let nullableStringParamArg: String? = nilOrValue(args[31]) + let nullableUint8ListParamArg: FlutterStandardTypedData? = nilOrValue(args[32]) + let nullableListParamArg: [Any?]? = nilOrValue(args[33]) + let nullableMapParamArg: [String?: Any?]? = nilOrValue(args[34]) + let nullableEnumParamArg: ProxyApiTestEnum? = nilOrValue(args[35]) + let nullableProxyApiParamArg: ProxyApiSuperClass? = nilOrValue(args[36]) + do { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + try api.pigeonDelegate.pigeonDefaultConstructor( + pigeonApi: api, aBool: aBoolArg, anInt: anIntArg, aDouble: aDoubleArg, + aString: aStringArg, aUint8List: aUint8ListArg, aList: aListArg, aMap: aMapArg, + anEnum: anEnumArg, aProxyApi: aProxyApiArg, aNullableBool: aNullableBoolArg, + aNullableInt: aNullableIntArg, aNullableDouble: aNullableDoubleArg, + aNullableString: aNullableStringArg, aNullableUint8List: aNullableUint8ListArg, + aNullableList: aNullableListArg, aNullableMap: aNullableMapArg, + aNullableEnum: aNullableEnumArg, aNullableProxyApi: aNullableProxyApiArg, + boolParam: boolParamArg, intParam: intParamArg, doubleParam: doubleParamArg, + stringParam: stringParamArg, aUint8ListParam: aUint8ListParamArg, + listParam: listParamArg, mapParam: mapParamArg, enumParam: enumParamArg, + proxyApiParam: proxyApiParamArg, nullableBoolParam: nullableBoolParamArg, + nullableIntParam: nullableIntParamArg, nullableDoubleParam: nullableDoubleParamArg, + nullableStringParam: nullableStringParamArg, + nullableUint8ListParam: nullableUint8ListParamArg, + nullableListParam: nullableListParamArg, nullableMapParam: nullableMapParamArg, + nullableEnumParam: nullableEnumParamArg, + nullableProxyApiParam: nullableProxyApiParamArg), + withIdentifier: pigeonIdentifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + pigeonDefaultConstructorChannel.setMessageHandler(nil) + } + let attachedFieldChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.attachedField", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + attachedFieldChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let pigeonIdentifierArg = args[1] as! Int64 + do { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + try api.pigeonDelegate.attachedField(pigeonApi: api, pigeonInstance: pigeonInstanceArg), + withIdentifier: pigeonIdentifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + attachedFieldChannel.setMessageHandler(nil) + } + let staticAttachedFieldChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.staticAttachedField", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + staticAttachedFieldChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonIdentifierArg = args[0] as! Int64 + do { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + try api.pigeonDelegate.staticAttachedField(pigeonApi: api), + withIdentifier: pigeonIdentifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + staticAttachedFieldChannel.setMessageHandler(nil) + } + let noopChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.noop", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + noopChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + do { + try api.pigeonDelegate.noop(pigeonApi: api, pigeonInstance: pigeonInstanceArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + noopChannel.setMessageHandler(nil) + } + let throwErrorChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.throwError", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + throwErrorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + do { + let result = try api.pigeonDelegate.throwError( + pigeonApi: api, pigeonInstance: pigeonInstanceArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + throwErrorChannel.setMessageHandler(nil) + } + let throwErrorFromVoidChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.throwErrorFromVoid", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + throwErrorFromVoidChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + do { + try api.pigeonDelegate.throwErrorFromVoid( + pigeonApi: api, pigeonInstance: pigeonInstanceArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + throwErrorFromVoidChannel.setMessageHandler(nil) + } + let throwFlutterErrorChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.throwFlutterError", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + throwFlutterErrorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + do { + let result = try api.pigeonDelegate.throwFlutterError( + pigeonApi: api, pigeonInstance: pigeonInstanceArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + throwFlutterErrorChannel.setMessageHandler(nil) + } + let echoIntChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoInt", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoIntChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anIntArg = args[1] as! Int64 + do { + let result = try api.pigeonDelegate.echoInt( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anInt: anIntArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoIntChannel.setMessageHandler(nil) + } + let echoDoubleChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoDouble", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoDoubleChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aDoubleArg = args[1] as! Double + do { + let result = try api.pigeonDelegate.echoDouble( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aDouble: aDoubleArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoDoubleChannel.setMessageHandler(nil) + } + let echoBoolChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoBool", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoBoolChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aBoolArg = args[1] as! Bool + do { + let result = try api.pigeonDelegate.echoBool( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aBool: aBoolArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoBoolChannel.setMessageHandler(nil) + } + let echoStringChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoString", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aStringArg = args[1] as! String + do { + let result = try api.pigeonDelegate.echoString( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aString: aStringArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoStringChannel.setMessageHandler(nil) + } + let echoUint8ListChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoUint8List", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoUint8ListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aUint8ListArg = args[1] as! FlutterStandardTypedData + do { + let result = try api.pigeonDelegate.echoUint8List( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aUint8List: aUint8ListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoUint8ListChannel.setMessageHandler(nil) + } + let echoObjectChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoObject", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoObjectChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anObjectArg = args[1]! + do { + let result = try api.pigeonDelegate.echoObject( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anObject: anObjectArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoObjectChannel.setMessageHandler(nil) + } + let echoListChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoList", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aListArg = args[1] as! [Any?] + do { + let result = try api.pigeonDelegate.echoList( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aList: aListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoListChannel.setMessageHandler(nil) + } + let echoProxyApiListChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoProxyApiList", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoProxyApiListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aListArg = args[1] as! [ProxyApiTestClass] + do { + let result = try api.pigeonDelegate.echoProxyApiList( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aList: aListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoProxyApiListChannel.setMessageHandler(nil) + } + let echoMapChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoMap", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aMapArg = args[1] as! [String?: Any?] + do { + let result = try api.pigeonDelegate.echoMap( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aMap: aMapArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoMapChannel.setMessageHandler(nil) + } + let echoProxyApiMapChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoProxyApiMap", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoProxyApiMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aMapArg = args[1] as! [String: ProxyApiTestClass] + do { + let result = try api.pigeonDelegate.echoProxyApiMap( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aMap: aMapArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoProxyApiMapChannel.setMessageHandler(nil) + } + let echoEnumChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoEnum", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoEnumChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anEnumArg = args[1] as! ProxyApiTestEnum + do { + let result = try api.pigeonDelegate.echoEnum( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anEnum: anEnumArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoEnumChannel.setMessageHandler(nil) + } + let echoProxyApiChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoProxyApi", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoProxyApiChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aProxyApiArg = args[1] as! ProxyApiSuperClass + do { + let result = try api.pigeonDelegate.echoProxyApi( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aProxyApi: aProxyApiArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoProxyApiChannel.setMessageHandler(nil) + } + let echoNullableIntChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableInt", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoNullableIntChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aNullableIntArg: Int64? = nilOrValue(args[1]) + do { + let result = try api.pigeonDelegate.echoNullableInt( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aNullableInt: aNullableIntArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoNullableIntChannel.setMessageHandler(nil) + } + let echoNullableDoubleChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableDouble", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoNullableDoubleChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aNullableDoubleArg: Double? = nilOrValue(args[1]) + do { + let result = try api.pigeonDelegate.echoNullableDouble( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aNullableDouble: aNullableDoubleArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoNullableDoubleChannel.setMessageHandler(nil) + } + let echoNullableBoolChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableBool", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoNullableBoolChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aNullableBoolArg: Bool? = nilOrValue(args[1]) + do { + let result = try api.pigeonDelegate.echoNullableBool( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aNullableBool: aNullableBoolArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoNullableBoolChannel.setMessageHandler(nil) + } + let echoNullableStringChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableString", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoNullableStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aNullableStringArg: String? = nilOrValue(args[1]) + do { + let result = try api.pigeonDelegate.echoNullableString( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aNullableString: aNullableStringArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoNullableStringChannel.setMessageHandler(nil) + } + let echoNullableUint8ListChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableUint8List", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoNullableUint8ListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aNullableUint8ListArg: FlutterStandardTypedData? = nilOrValue(args[1]) + do { + let result = try api.pigeonDelegate.echoNullableUint8List( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, + aNullableUint8List: aNullableUint8ListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoNullableUint8ListChannel.setMessageHandler(nil) + } + let echoNullableObjectChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableObject", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoNullableObjectChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aNullableObjectArg: Any? = args[1] + do { + let result = try api.pigeonDelegate.echoNullableObject( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aNullableObject: aNullableObjectArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoNullableObjectChannel.setMessageHandler(nil) + } + let echoNullableListChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableList", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoNullableListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aNullableListArg: [Any?]? = nilOrValue(args[1]) + do { + let result = try api.pigeonDelegate.echoNullableList( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aNullableList: aNullableListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoNullableListChannel.setMessageHandler(nil) + } + let echoNullableMapChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableMap", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoNullableMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aNullableMapArg: [String?: Any?]? = nilOrValue(args[1]) + do { + let result = try api.pigeonDelegate.echoNullableMap( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aNullableMap: aNullableMapArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoNullableMapChannel.setMessageHandler(nil) + } + let echoNullableEnumChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableEnum", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoNullableEnumChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aNullableEnumArg: ProxyApiTestEnum? = nilOrValue(args[1]) + do { + let result = try api.pigeonDelegate.echoNullableEnum( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aNullableEnum: aNullableEnumArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoNullableEnumChannel.setMessageHandler(nil) + } + let echoNullableProxyApiChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableProxyApi", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoNullableProxyApiChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aNullableProxyApiArg: ProxyApiSuperClass? = nilOrValue(args[1]) + do { + let result = try api.pigeonDelegate.echoNullableProxyApi( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, + aNullableProxyApi: aNullableProxyApiArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoNullableProxyApiChannel.setMessageHandler(nil) + } + let noopAsyncChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.noopAsync", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + noopAsyncChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + api.pigeonDelegate.noopAsync(pigeonApi: api, pigeonInstance: pigeonInstanceArg) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + noopAsyncChannel.setMessageHandler(nil) + } + let echoAsyncIntChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncInt", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncIntChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anIntArg = args[1] as! Int64 + api.pigeonDelegate.echoAsyncInt( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anInt: anIntArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncIntChannel.setMessageHandler(nil) + } + let echoAsyncDoubleChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncDouble", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncDoubleChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aDoubleArg = args[1] as! Double + api.pigeonDelegate.echoAsyncDouble( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aDouble: aDoubleArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncDoubleChannel.setMessageHandler(nil) + } + let echoAsyncBoolChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncBool", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncBoolChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aBoolArg = args[1] as! Bool + api.pigeonDelegate.echoAsyncBool( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aBool: aBoolArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncBoolChannel.setMessageHandler(nil) + } + let echoAsyncStringChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncString", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aStringArg = args[1] as! String + api.pigeonDelegate.echoAsyncString( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aString: aStringArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncStringChannel.setMessageHandler(nil) + } + let echoAsyncUint8ListChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncUint8List", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncUint8ListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aUint8ListArg = args[1] as! FlutterStandardTypedData + api.pigeonDelegate.echoAsyncUint8List( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aUint8List: aUint8ListArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncUint8ListChannel.setMessageHandler(nil) + } + let echoAsyncObjectChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncObject", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncObjectChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anObjectArg = args[1]! + api.pigeonDelegate.echoAsyncObject( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anObject: anObjectArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncObjectChannel.setMessageHandler(nil) + } + let echoAsyncListChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncList", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aListArg = args[1] as! [Any?] + api.pigeonDelegate.echoAsyncList( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aList: aListArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncListChannel.setMessageHandler(nil) + } + let echoAsyncMapChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncMap", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aMapArg = args[1] as! [String?: Any?] + api.pigeonDelegate.echoAsyncMap( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aMap: aMapArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncMapChannel.setMessageHandler(nil) + } + let echoAsyncEnumChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncEnum", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncEnumChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anEnumArg = args[1] as! ProxyApiTestEnum + api.pigeonDelegate.echoAsyncEnum( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anEnum: anEnumArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncEnumChannel.setMessageHandler(nil) + } + let throwAsyncErrorChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.throwAsyncError", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + throwAsyncErrorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + api.pigeonDelegate.throwAsyncError(pigeonApi: api, pigeonInstance: pigeonInstanceArg) { + result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + throwAsyncErrorChannel.setMessageHandler(nil) + } + let throwAsyncErrorFromVoidChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.throwAsyncErrorFromVoid", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + throwAsyncErrorFromVoidChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + api.pigeonDelegate.throwAsyncErrorFromVoid( + pigeonApi: api, pigeonInstance: pigeonInstanceArg + ) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + throwAsyncErrorFromVoidChannel.setMessageHandler(nil) + } + let throwAsyncFlutterErrorChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.throwAsyncFlutterError", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + throwAsyncFlutterErrorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + api.pigeonDelegate.throwAsyncFlutterError(pigeonApi: api, pigeonInstance: pigeonInstanceArg) + { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + throwAsyncFlutterErrorChannel.setMessageHandler(nil) + } + let echoAsyncNullableIntChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableInt", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableIntChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anIntArg: Int64? = nilOrValue(args[1]) + api.pigeonDelegate.echoAsyncNullableInt( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anInt: anIntArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableIntChannel.setMessageHandler(nil) + } + let echoAsyncNullableDoubleChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableDouble", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableDoubleChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aDoubleArg: Double? = nilOrValue(args[1]) + api.pigeonDelegate.echoAsyncNullableDouble( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aDouble: aDoubleArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableDoubleChannel.setMessageHandler(nil) + } + let echoAsyncNullableBoolChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableBool", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableBoolChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aBoolArg: Bool? = nilOrValue(args[1]) + api.pigeonDelegate.echoAsyncNullableBool( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aBool: aBoolArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableBoolChannel.setMessageHandler(nil) + } + let echoAsyncNullableStringChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableString", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aStringArg: String? = nilOrValue(args[1]) + api.pigeonDelegate.echoAsyncNullableString( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aString: aStringArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableStringChannel.setMessageHandler(nil) + } + let echoAsyncNullableUint8ListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableUint8List", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableUint8ListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aUint8ListArg: FlutterStandardTypedData? = nilOrValue(args[1]) + api.pigeonDelegate.echoAsyncNullableUint8List( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aUint8List: aUint8ListArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableUint8ListChannel.setMessageHandler(nil) + } + let echoAsyncNullableObjectChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableObject", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableObjectChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anObjectArg: Any? = args[1] + api.pigeonDelegate.echoAsyncNullableObject( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anObject: anObjectArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableObjectChannel.setMessageHandler(nil) + } + let echoAsyncNullableListChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableList", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aListArg: [Any?]? = nilOrValue(args[1]) + api.pigeonDelegate.echoAsyncNullableList( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aList: aListArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableListChannel.setMessageHandler(nil) + } + let echoAsyncNullableMapChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableMap", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aMapArg: [String?: Any?]? = nilOrValue(args[1]) + api.pigeonDelegate.echoAsyncNullableMap( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aMap: aMapArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableMapChannel.setMessageHandler(nil) + } + let echoAsyncNullableEnumChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableEnum", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableEnumChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anEnumArg: ProxyApiTestEnum? = nilOrValue(args[1]) + api.pigeonDelegate.echoAsyncNullableEnum( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anEnum: anEnumArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableEnumChannel.setMessageHandler(nil) + } + let staticNoopChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.staticNoop", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + staticNoopChannel.setMessageHandler { _, reply in + do { + try api.pigeonDelegate.staticNoop(pigeonApi: api) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + staticNoopChannel.setMessageHandler(nil) + } + let echoStaticStringChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoStaticString", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoStaticStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aStringArg = args[0] as! String + do { + let result = try api.pigeonDelegate.echoStaticString(pigeonApi: api, aString: aStringArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoStaticStringChannel.setMessageHandler(nil) + } + let staticAsyncNoopChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.staticAsyncNoop", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + staticAsyncNoopChannel.setMessageHandler { _, reply in + api.pigeonDelegate.staticAsyncNoop(pigeonApi: api) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + staticAsyncNoopChannel.setMessageHandler(nil) + } + let callFlutterNoopChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterNoop", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterNoopChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + api.pigeonDelegate.callFlutterNoop(pigeonApi: api, pigeonInstance: pigeonInstanceArg) { + result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterNoopChannel.setMessageHandler(nil) + } + let callFlutterThrowErrorChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterThrowError", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterThrowErrorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + api.pigeonDelegate.callFlutterThrowError(pigeonApi: api, pigeonInstance: pigeonInstanceArg) + { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterThrowErrorChannel.setMessageHandler(nil) + } + let callFlutterThrowErrorFromVoidChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterThrowErrorFromVoid", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterThrowErrorFromVoidChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + api.pigeonDelegate.callFlutterThrowErrorFromVoid( + pigeonApi: api, pigeonInstance: pigeonInstanceArg + ) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterThrowErrorFromVoidChannel.setMessageHandler(nil) + } + let callFlutterEchoBoolChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoBool", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoBoolChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aBoolArg = args[1] as! Bool + api.pigeonDelegate.callFlutterEchoBool( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aBool: aBoolArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoBoolChannel.setMessageHandler(nil) + } + let callFlutterEchoIntChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoInt", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoIntChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anIntArg = args[1] as! Int64 + api.pigeonDelegate.callFlutterEchoInt( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anInt: anIntArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoIntChannel.setMessageHandler(nil) + } + let callFlutterEchoDoubleChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoDouble", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoDoubleChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aDoubleArg = args[1] as! Double + api.pigeonDelegate.callFlutterEchoDouble( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aDouble: aDoubleArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoDoubleChannel.setMessageHandler(nil) + } + let callFlutterEchoStringChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoString", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aStringArg = args[1] as! String + api.pigeonDelegate.callFlutterEchoString( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aString: aStringArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoStringChannel.setMessageHandler(nil) + } + let callFlutterEchoUint8ListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoUint8List", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoUint8ListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aUint8ListArg = args[1] as! FlutterStandardTypedData + api.pigeonDelegate.callFlutterEchoUint8List( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aUint8List: aUint8ListArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoUint8ListChannel.setMessageHandler(nil) + } + let callFlutterEchoListChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoList", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aListArg = args[1] as! [Any?] + api.pigeonDelegate.callFlutterEchoList( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aList: aListArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoListChannel.setMessageHandler(nil) + } + let callFlutterEchoProxyApiListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoProxyApiList", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoProxyApiListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aListArg = args[1] as! [ProxyApiTestClass?] + api.pigeonDelegate.callFlutterEchoProxyApiList( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aList: aListArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoProxyApiListChannel.setMessageHandler(nil) + } + let callFlutterEchoMapChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoMap", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aMapArg = args[1] as! [String?: Any?] + api.pigeonDelegate.callFlutterEchoMap( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aMap: aMapArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoMapChannel.setMessageHandler(nil) + } + let callFlutterEchoProxyApiMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoProxyApiMap", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoProxyApiMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aMapArg = args[1] as! [String?: ProxyApiTestClass?] + api.pigeonDelegate.callFlutterEchoProxyApiMap( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aMap: aMapArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoProxyApiMapChannel.setMessageHandler(nil) + } + let callFlutterEchoEnumChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoEnum", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoEnumChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anEnumArg = args[1] as! ProxyApiTestEnum + api.pigeonDelegate.callFlutterEchoEnum( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anEnum: anEnumArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoEnumChannel.setMessageHandler(nil) + } + let callFlutterEchoProxyApiChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoProxyApi", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoProxyApiChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aProxyApiArg = args[1] as! ProxyApiSuperClass + api.pigeonDelegate.callFlutterEchoProxyApi( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aProxyApi: aProxyApiArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoProxyApiChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableBoolChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableBool", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableBoolChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aBoolArg: Bool? = nilOrValue(args[1]) + api.pigeonDelegate.callFlutterEchoNullableBool( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aBool: aBoolArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableBoolChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableIntChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableInt", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableIntChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anIntArg: Int64? = nilOrValue(args[1]) + api.pigeonDelegate.callFlutterEchoNullableInt( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anInt: anIntArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableIntChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableDoubleChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableDouble", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableDoubleChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aDoubleArg: Double? = nilOrValue(args[1]) + api.pigeonDelegate.callFlutterEchoNullableDouble( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aDouble: aDoubleArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableDoubleChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableStringChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableString", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aStringArg: String? = nilOrValue(args[1]) + api.pigeonDelegate.callFlutterEchoNullableString( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aString: aStringArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableStringChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableUint8ListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableUint8List", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableUint8ListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aUint8ListArg: FlutterStandardTypedData? = nilOrValue(args[1]) + api.pigeonDelegate.callFlutterEchoNullableUint8List( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aUint8List: aUint8ListArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableUint8ListChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableList", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aListArg: [Any?]? = nilOrValue(args[1]) + api.pigeonDelegate.callFlutterEchoNullableList( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aList: aListArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableListChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableMap", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aMapArg: [String?: Any?]? = nilOrValue(args[1]) + api.pigeonDelegate.callFlutterEchoNullableMap( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aMap: aMapArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableEnumChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableEnum", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableEnumChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anEnumArg: ProxyApiTestEnum? = nilOrValue(args[1]) + api.pigeonDelegate.callFlutterEchoNullableEnum( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anEnum: anEnumArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableEnumChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableProxyApiChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableProxyApi", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableProxyApiChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aProxyApiArg: ProxyApiSuperClass? = nilOrValue(args[1]) + api.pigeonDelegate.callFlutterEchoNullableProxyApi( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aProxyApi: aProxyApiArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableProxyApiChannel.setMessageHandler(nil) + } + let callFlutterNoopAsyncChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterNoopAsync", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterNoopAsyncChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + api.pigeonDelegate.callFlutterNoopAsync(pigeonApi: api, pigeonInstance: pigeonInstanceArg) { + result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterNoopAsyncChannel.setMessageHandler(nil) + } + let callFlutterEchoAsyncStringChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoAsyncString", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoAsyncStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aStringArg = args[1] as! String + api.pigeonDelegate.callFlutterEchoAsyncString( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aString: aStringArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoAsyncStringChannel.setMessageHandler(nil) + } + } + + ///Creates a Dart instance of ProxyApiTestClass and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let aBoolArg = try! pigeonDelegate.aBool(pigeonApi: self, pigeonInstance: pigeonInstance) + let anIntArg = try! pigeonDelegate.anInt(pigeonApi: self, pigeonInstance: pigeonInstance) + let aDoubleArg = try! pigeonDelegate.aDouble(pigeonApi: self, pigeonInstance: pigeonInstance) + let aStringArg = try! pigeonDelegate.aString(pigeonApi: self, pigeonInstance: pigeonInstance) + let aUint8ListArg = try! pigeonDelegate.aUint8List( + pigeonApi: self, pigeonInstance: pigeonInstance) + let aListArg = try! pigeonDelegate.aList(pigeonApi: self, pigeonInstance: pigeonInstance) + let aMapArg = try! pigeonDelegate.aMap(pigeonApi: self, pigeonInstance: pigeonInstance) + let anEnumArg = try! pigeonDelegate.anEnum(pigeonApi: self, pigeonInstance: pigeonInstance) + let aProxyApiArg = try! pigeonDelegate.aProxyApi( + pigeonApi: self, pigeonInstance: pigeonInstance) + let aNullableBoolArg = try! pigeonDelegate.aNullableBool( + pigeonApi: self, pigeonInstance: pigeonInstance) + let aNullableIntArg = try! pigeonDelegate.aNullableInt( + pigeonApi: self, pigeonInstance: pigeonInstance) + let aNullableDoubleArg = try! pigeonDelegate.aNullableDouble( + pigeonApi: self, pigeonInstance: pigeonInstance) + let aNullableStringArg = try! pigeonDelegate.aNullableString( + pigeonApi: self, pigeonInstance: pigeonInstance) + let aNullableUint8ListArg = try! pigeonDelegate.aNullableUint8List( + pigeonApi: self, pigeonInstance: pigeonInstance) + let aNullableListArg = try! pigeonDelegate.aNullableList( + pigeonApi: self, pigeonInstance: pigeonInstance) + let aNullableMapArg = try! pigeonDelegate.aNullableMap( + pigeonApi: self, pigeonInstance: pigeonInstance) + let aNullableEnumArg = try! pigeonDelegate.aNullableEnum( + pigeonApi: self, pigeonInstance: pigeonInstance) + let aNullableProxyApiArg = try! pigeonDelegate.aNullableProxyApi( + pigeonApi: self, pigeonInstance: pigeonInstance) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage( + [ + pigeonIdentifierArg, aBoolArg, anIntArg, aDoubleArg, aStringArg, aUint8ListArg, aListArg, + aMapArg, anEnumArg, aProxyApiArg, aNullableBoolArg, aNullableIntArg, aNullableDoubleArg, + aNullableStringArg, aNullableUint8ListArg, aNullableListArg, aNullableMapArg, + aNullableEnumArg, aNullableProxyApiArg, + ] as [Any?] + ) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic calling. + func flutterNoop( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterNoop" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + + /// Responds with an error from an async function returning a value. + func flutterThrowError( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterThrowError" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + let result: Any? = listResponse[0] + completion(.success(result)) + } + } + } + + /// Responds with an error from an async void function. + func flutterThrowErrorFromVoid( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterThrowErrorFromVoid" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + + /// Returns the passed boolean, to test serialization and deserialization. + func flutterEchoBool( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aBool aBoolArg: Bool, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoBool" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aBoolArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + ProxyApiTestsError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! Bool + completion(.success(result)) + } + } + } + + /// Returns the passed int, to test serialization and deserialization. + func flutterEchoInt( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, anInt anIntArg: Int64, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoInt" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, anIntArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + ProxyApiTestsError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! Int64 + completion(.success(result)) + } + } + } + + /// Returns the passed double, to test serialization and deserialization. + func flutterEchoDouble( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aDouble aDoubleArg: Double, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoDouble" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aDoubleArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + ProxyApiTestsError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! Double + completion(.success(result)) + } + } + } + + /// Returns the passed string, to test serialization and deserialization. + func flutterEchoString( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aString aStringArg: String, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoString" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aStringArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + ProxyApiTestsError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! String + completion(.success(result)) + } + } + } + + /// Returns the passed byte list, to test serialization and deserialization. + func flutterEchoUint8List( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aList aListArg: FlutterStandardTypedData, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoUint8List" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aListArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + ProxyApiTestsError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! FlutterStandardTypedData + completion(.success(result)) + } + } + } + + /// Returns the passed list, to test serialization and deserialization. + func flutterEchoList( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aList aListArg: [Any?], + completion: @escaping (Result<[Any?], ProxyApiTestsError>) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoList" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aListArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + ProxyApiTestsError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [Any?] + completion(.success(result)) + } + } + } + + /// Returns the passed list with ProxyApis, to test serialization and + /// deserialization. + func flutterEchoProxyApiList( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aList aListArg: [ProxyApiTestClass?], + completion: @escaping (Result<[ProxyApiTestClass?], ProxyApiTestsError>) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoProxyApiList" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aListArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + ProxyApiTestsError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [ProxyApiTestClass?] + completion(.success(result)) + } + } + } + + /// Returns the passed map, to test serialization and deserialization. + func flutterEchoMap( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aMap aMapArg: [String?: Any?], + completion: @escaping (Result<[String?: Any?], ProxyApiTestsError>) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoMap" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aMapArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + ProxyApiTestsError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [String?: Any?] + completion(.success(result)) + } + } + } + + /// Returns the passed map with ProxyApis, to test serialization and + /// deserialization. + func flutterEchoProxyApiMap( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, + aMap aMapArg: [String?: ProxyApiTestClass?], + completion: @escaping (Result<[String?: ProxyApiTestClass?], ProxyApiTestsError>) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoProxyApiMap" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aMapArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + ProxyApiTestsError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [String?: ProxyApiTestClass?] + completion(.success(result)) + } + } + } + + /// Returns the passed enum to test serialization and deserialization. + func flutterEchoEnum( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, anEnum anEnumArg: ProxyApiTestEnum, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoEnum" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, anEnumArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + ProxyApiTestsError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! ProxyApiTestEnum + completion(.success(result)) + } + } + } + + /// Returns the passed ProxyApi to test serialization and deserialization. + func flutterEchoProxyApi( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aProxyApi aProxyApiArg: ProxyApiSuperClass, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoProxyApi" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aProxyApiArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + ProxyApiTestsError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! ProxyApiSuperClass + completion(.success(result)) + } + } + } + + /// Returns the passed boolean, to test serialization and deserialization. + func flutterEchoNullableBool( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aBool aBoolArg: Bool?, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableBool" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aBoolArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + let result: Bool? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } + + /// Returns the passed int, to test serialization and deserialization. + func flutterEchoNullableInt( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, anInt anIntArg: Int64?, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableInt" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, anIntArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + let result: Int64? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } + + /// Returns the passed double, to test serialization and deserialization. + func flutterEchoNullableDouble( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aDouble aDoubleArg: Double?, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableDouble" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aDoubleArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + let result: Double? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } + + /// Returns the passed string, to test serialization and deserialization. + func flutterEchoNullableString( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aString aStringArg: String?, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableString" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aStringArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + let result: String? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } + + /// Returns the passed byte list, to test serialization and deserialization. + func flutterEchoNullableUint8List( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aList aListArg: FlutterStandardTypedData?, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableUint8List" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aListArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + let result: FlutterStandardTypedData? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } + + /// Returns the passed list, to test serialization and deserialization. + func flutterEchoNullableList( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aList aListArg: [Any?]?, + completion: @escaping (Result<[Any?]?, ProxyApiTestsError>) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableList" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aListArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + let result: [Any?]? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } + + /// Returns the passed map, to test serialization and deserialization. + func flutterEchoNullableMap( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aMap aMapArg: [String?: Any?]?, + completion: @escaping (Result<[String?: Any?]?, ProxyApiTestsError>) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableMap" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aMapArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + let result: [String?: Any?]? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } + + /// Returns the passed enum to test serialization and deserialization. + func flutterEchoNullableEnum( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, anEnum anEnumArg: ProxyApiTestEnum?, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableEnum" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, anEnumArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + let result: ProxyApiTestEnum? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } + + /// Returns the passed ProxyApi to test serialization and deserialization. + func flutterEchoNullableProxyApi( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, + aProxyApi aProxyApiArg: ProxyApiSuperClass?, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableProxyApi" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aProxyApiArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + let result: ProxyApiSuperClass? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } + + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic asynchronous calling. + func flutterNoopAsync( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterNoopAsync" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + + /// Returns the passed in generic Object asynchronously. + func flutterEchoAsyncString( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aString aStringArg: String, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoAsyncString" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aStringArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + ProxyApiTestsError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! String + completion(.success(result)) + } + } + } + +} +protocol PigeonApiDelegateProxyApiSuperClass { + func pigeonDefaultConstructor(pigeonApi: PigeonApiProxyApiSuperClass) throws -> ProxyApiSuperClass + func aSuperMethod(pigeonApi: PigeonApiProxyApiSuperClass, pigeonInstance: ProxyApiSuperClass) + throws +} + +protocol PigeonApiProtocolProxyApiSuperClass { +} + +final class PigeonApiProxyApiSuperClass: PigeonApiProtocolProxyApiSuperClass { + unowned let pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateProxyApiSuperClass + init( + pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateProxyApiSuperClass + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + static func setUpMessageHandlers( + binaryMessenger: FlutterBinaryMessenger, api: PigeonApiProxyApiSuperClass? + ) { + let codec: FlutterStandardMessageCodec = + api != nil + ? FlutterStandardMessageCodec( + readerWriter: ProxyApiTestsPigeonInternalProxyApiCodecReaderWriter( + pigeonRegistrar: api!.pigeonRegistrar)) + : FlutterStandardMessageCodec.sharedInstance() + let pigeonDefaultConstructorChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiSuperClass.pigeon_defaultConstructor", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + pigeonDefaultConstructorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonIdentifierArg = args[0] as! Int64 + do { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + try api.pigeonDelegate.pigeonDefaultConstructor(pigeonApi: api), + withIdentifier: pigeonIdentifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + pigeonDefaultConstructorChannel.setMessageHandler(nil) + } + let aSuperMethodChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiSuperClass.aSuperMethod", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + aSuperMethodChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiSuperClass + do { + try api.pigeonDelegate.aSuperMethod(pigeonApi: api, pigeonInstance: pigeonInstanceArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + aSuperMethodChannel.setMessageHandler(nil) + } + } + + ///Creates a Dart instance of ProxyApiSuperClass and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: ProxyApiSuperClass, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiSuperClass.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonIdentifierArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} +open class PigeonApiDelegateProxyApiInterface { +} + +protocol PigeonApiProtocolProxyApiInterface { + func anInterfaceMethod( + pigeonInstance pigeonInstanceArg: ProxyApiInterface, + completion: @escaping (Result) -> Void) +} + +final class PigeonApiProxyApiInterface: PigeonApiProtocolProxyApiInterface { + unowned let pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateProxyApiInterface + init( + pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateProxyApiInterface + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + ///Creates a Dart instance of ProxyApiInterface and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: ProxyApiInterface, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiInterface.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonIdentifierArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + func anInterfaceMethod( + pigeonInstance pigeonInstanceArg: ProxyApiInterface, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiInterface.anInterfaceMethod" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + +} +protocol PigeonApiDelegateClassWithApiRequirement { + @available(iOS 15.0.0, macOS 10.0.0, *) + func pigeonDefaultConstructor(pigeonApi: PigeonApiClassWithApiRequirement) throws + -> ClassWithApiRequirement + @available(iOS 15.0.0, macOS 10.0.0, *) + func aMethod(pigeonApi: PigeonApiClassWithApiRequirement, pigeonInstance: ClassWithApiRequirement) + throws +} + +protocol PigeonApiProtocolClassWithApiRequirement { +} + +final class PigeonApiClassWithApiRequirement: PigeonApiProtocolClassWithApiRequirement { + unowned let pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateClassWithApiRequirement + init( + pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateClassWithApiRequirement + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + static func setUpMessageHandlers( + binaryMessenger: FlutterBinaryMessenger, api: PigeonApiClassWithApiRequirement? + ) { + let codec: FlutterStandardMessageCodec = + api != nil + ? FlutterStandardMessageCodec( + readerWriter: ProxyApiTestsPigeonInternalProxyApiCodecReaderWriter( + pigeonRegistrar: api!.pigeonRegistrar)) + : FlutterStandardMessageCodec.sharedInstance() + if #available(iOS 15.0.0, macOS 10.0.0, *) { + let pigeonDefaultConstructorChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ClassWithApiRequirement.pigeon_defaultConstructor", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + pigeonDefaultConstructorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonIdentifierArg = args[0] as! Int64 + do { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + try api.pigeonDelegate.pigeonDefaultConstructor(pigeonApi: api), + withIdentifier: pigeonIdentifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + pigeonDefaultConstructorChannel.setMessageHandler(nil) + } + } else { + let pigeonDefaultConstructorChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ClassWithApiRequirement.pigeon_defaultConstructor", + binaryMessenger: binaryMessenger, codec: codec) + if api != nil { + pigeonDefaultConstructorChannel.setMessageHandler { message, reply in + reply( + wrapError( + FlutterError( + code: "PigeonUnsupportedOperationError", + message: + "Call to pigeonDefaultConstructor requires @available(iOS 15.0.0, macOS 10.0.0, *).", + details: nil + ))) + } + } else { + pigeonDefaultConstructorChannel.setMessageHandler(nil) + } + } + if #available(iOS 15.0.0, macOS 10.0.0, *) { + let aMethodChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ClassWithApiRequirement.aMethod", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + aMethodChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ClassWithApiRequirement + do { + try api.pigeonDelegate.aMethod(pigeonApi: api, pigeonInstance: pigeonInstanceArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + aMethodChannel.setMessageHandler(nil) + } + } else { + let aMethodChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ClassWithApiRequirement.aMethod", + binaryMessenger: binaryMessenger, codec: codec) + if api != nil { + aMethodChannel.setMessageHandler { message, reply in + reply( + wrapError( + FlutterError( + code: "PigeonUnsupportedOperationError", + message: "Call to aMethod requires @available(iOS 15.0.0, macOS 10.0.0, *).", + details: nil + ))) + } + } else { + aMethodChannel.setMessageHandler(nil) + } + } + } + + ///Creates a Dart instance of ClassWithApiRequirement and attaches it to [pigeonInstance]. + @available(iOS 15.0.0, macOS 10.0.0, *) + func pigeonNewInstance( + pigeonInstance: ClassWithApiRequirement, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ClassWithApiRequirement.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonIdentifierArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} diff --git a/packages/pigeon/platform_tests/test_plugin/ios/Classes/TestPlugin.swift b/packages/pigeon/platform_tests/test_plugin/ios/Classes/TestPlugin.swift index 36e6a445b53b..b4238de3be91 100644 --- a/packages/pigeon/platform_tests/test_plugin/ios/Classes/TestPlugin.swift +++ b/packages/pigeon/platform_tests/test_plugin/ios/Classes/TestPlugin.swift @@ -12,12 +12,14 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { var flutterAPI: FlutterIntegrationCoreApi var flutterSmallApiOne: FlutterSmallApi var flutterSmallApiTwo: FlutterSmallApi + var proxyApiRegistrar: ProxyApiTestsPigeonProxyApiRegistrar? public static func register(with registrar: FlutterPluginRegistrar) { let plugin = TestPlugin(binaryMessenger: registrar.messenger()) HostIntegrationCoreApiSetup.setUp(binaryMessenger: registrar.messenger(), api: plugin) TestPluginWithSuffix.register(with: registrar, suffix: "suffixOne") TestPluginWithSuffix.register(with: registrar, suffix: "suffixTwo") + registrar.publish(plugin) } init(binaryMessenger: FlutterBinaryMessenger) { @@ -26,6 +28,14 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { binaryMessenger: binaryMessenger, messageChannelSuffix: "suffixOne") flutterSmallApiTwo = FlutterSmallApi( binaryMessenger: binaryMessenger, messageChannelSuffix: "suffixTwo") + proxyApiRegistrar = ProxyApiTestsPigeonProxyApiRegistrar( + binaryMessenger: binaryMessenger, apiDelegate: ProxyApiDelegate()) + proxyApiRegistrar!.setUp() + } + + public func detachFromEngine(for registrar: FlutterPluginRegistrar) { + proxyApiRegistrar!.tearDown() + proxyApiRegistrar = nil } // MARK: HostIntegrationCoreApi implementation @@ -87,8 +97,56 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { return list } - func echo(_ aMap: [String?: Any?]) throws -> [String?: Any?] { - return aMap + func echo(enumList: [AnEnum?]) throws -> [AnEnum?] { + return enumList + } + + func echo(classList: [AllNullableTypes?]) throws -> [AllNullableTypes?] { + return classList + } + + func echoNonNull(enumList: [AnEnum]) throws -> [AnEnum] { + return enumList + } + + func echoNonNull(classList: [AllNullableTypes]) throws -> [AllNullableTypes] { + return classList + } + + func echo(_ map: [AnyHashable?: Any?]) throws -> [AnyHashable?: Any?] { + return map + } + + func echo(stringMap: [String?: String?]) throws -> [String?: String?] { + return stringMap + } + + func echo(intMap: [Int64?: Int64?]) throws -> [Int64?: Int64?] { + return intMap + } + + func echo(enumMap: [AnEnum?: AnEnum?]) throws -> [AnEnum?: AnEnum?] { + return enumMap + } + + func echo(classMap: [Int64?: AllNullableTypes?]) throws -> [Int64?: AllNullableTypes?] { + return classMap + } + + func echoNonNull(stringMap: [String: String]) throws -> [String: String] { + return stringMap + } + + func echoNonNull(intMap: [Int64: Int64]) throws -> [Int64: Int64] { + return intMap + } + + func echoNonNull(enumMap: [AnEnum: AnEnum]) throws -> [AnEnum: AnEnum] { + return enumMap + } + + func echoNonNull(classMap: [Int64: AllNullableTypes]) throws -> [Int64: AllNullableTypes] { + return classMap } func echo(_ wrapper: AllClassesWrapper) throws -> AllClassesWrapper { @@ -99,12 +157,18 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { return anEnum } + func echo(_ anotherEnum: AnotherEnum) throws -> AnotherEnum { + return anotherEnum + } + func extractNestedNullableString(from wrapper: AllClassesWrapper) -> String? { return wrapper.allNullableTypes.aNullableString } func createNestedObject(with nullableString: String?) -> AllClassesWrapper { - return AllClassesWrapper(allNullableTypes: AllNullableTypes(aNullableString: nullableString)) + return AllClassesWrapper( + allNullableTypes: AllNullableTypes(aNullableString: nullableString), classList: [], + classMap: [:]) } func sendMultipleNullableTypes( @@ -163,14 +227,68 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { return aNullableList } - func echoNullable(_ aNullableMap: [String?: Any?]?) throws -> [String?: Any?]? { - return aNullableMap + func echoNullable(enumList: [AnEnum?]?) throws -> [AnEnum?]? { + return enumList + } + + func echoNullable(classList: [AllNullableTypes?]?) throws -> [AllNullableTypes?]? { + return classList + } + + func echoNullableNonNull(enumList: [AnEnum]?) throws -> [AnEnum]? { + return enumList + } + + func echoNullableNonNull(classList: [AllNullableTypes]?) throws -> [AllNullableTypes]? { + return classList + } + + func echoNullable(_ map: [AnyHashable?: Any?]?) throws -> [AnyHashable?: Any?]? { + return map + } + + func echoNullable(stringMap: [String?: String?]?) throws -> [String?: String?]? { + return stringMap + } + + func echoNullable(intMap: [Int64?: Int64?]?) throws -> [Int64?: Int64?]? { + return intMap + } + + func echoNullable(enumMap: [AnEnum?: AnEnum?]?) throws -> [AnEnum?: AnEnum?]? { + return enumMap + } + + func echoNullable(classMap: [Int64?: AllNullableTypes?]?) throws -> [Int64?: AllNullableTypes?]? { + return classMap + } + + func echoNullableNonNull(stringMap: [String: String]?) throws -> [String: String]? { + return stringMap + } + + func echoNullableNonNull(intMap: [Int64: Int64]?) throws -> [Int64: Int64]? { + return intMap + } + + func echoNullableNonNull(enumMap: [AnEnum: AnEnum]?) throws -> [AnEnum: AnEnum]? { + return enumMap + } + + func echoNullableNonNull(classMap: [Int64: AllNullableTypes]?) throws -> [Int64: + AllNullableTypes]? + { + return classMap } func echoNullable(_ anEnum: AnEnum?) throws -> AnEnum? { return anEnum } + func echoNullable(_ anotherEnum: AnotherEnum?) throws -> AnotherEnum? { + return anotherEnum + } + func echoOptional(_ aNullableInt: Int64?) throws -> Int64? { return aNullableInt } @@ -244,16 +362,58 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { completion(.success(list)) } + func echoAsync(enumList: [AnEnum?], completion: @escaping (Result<[AnEnum?], Error>) -> Void) { + completion(.success(enumList)) + } + + func echoAsync( + classList: [AllNullableTypes?], + completion: @escaping (Result<[AllNullableTypes?], Error>) -> Void + ) { + completion(.success(classList)) + } + + func echoAsync( + _ map: [AnyHashable?: Any?], completion: @escaping (Result<[AnyHashable?: Any?], Error>) -> Void + ) { + completion(.success(map)) + } + + func echoAsync( + stringMap: [String?: String?], completion: @escaping (Result<[String?: String?], Error>) -> Void + ) { + completion(.success(stringMap)) + } + + func echoAsync( + intMap: [Int64?: Int64?], completion: @escaping (Result<[Int64?: Int64?], Error>) -> Void + ) { + completion(.success(intMap)) + } + + func echoAsync( + enumMap: [AnEnum?: AnEnum?], completion: @escaping (Result<[AnEnum?: AnEnum?], Error>) -> Void + ) { + completion(.success(enumMap)) + } + func echoAsync( - _ aMap: [String?: Any?], completion: @escaping (Result<[String?: Any?], Error>) -> Void + classMap: [Int64?: AllNullableTypes?], + completion: @escaping (Result<[Int64?: AllNullableTypes?], Error>) -> Void ) { - completion(.success(aMap)) + completion(.success(classMap)) } func echoAsync(_ anEnum: AnEnum, completion: @escaping (Result) -> Void) { completion(.success(anEnum)) } + func echoAsync( + _ anotherEnum: AnotherEnum, completion: @escaping (Result) -> Void + ) { + completion(.success(anotherEnum)) + } + func echoAsyncNullable(_ anInt: Int64?, completion: @escaping (Result) -> Void) { completion(.success(anInt)) } @@ -288,16 +448,63 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { } func echoAsyncNullable( - _ aMap: [String?: Any?]?, completion: @escaping (Result<[String?: Any?]?, Error>) -> Void + enumList: [AnEnum?]?, completion: @escaping (Result<[AnEnum?]?, Error>) -> Void ) { - completion(.success(aMap)) + completion(.success(enumList)) } - func echoAsyncNullable(_ anEnum: AnEnum?, completion: @escaping (Result) -> Void) - { + func echoAsyncNullable( + classList: [AllNullableTypes?]?, + completion: @escaping (Result<[AllNullableTypes?]?, Error>) -> Void + ) { + completion(.success(classList)) + } + + func echoAsyncNullable( + _ map: [AnyHashable?: Any?]?, + completion: @escaping (Result<[AnyHashable?: Any?]?, Error>) -> Void + ) { + completion(.success(map)) + } + + func echoAsyncNullable( + stringMap: [String?: String?]?, + completion: @escaping (Result<[String?: String?]?, Error>) -> Void + ) { + completion(.success(stringMap)) + } + + func echoAsyncNullable( + intMap: [Int64?: Int64?]?, completion: @escaping (Result<[Int64?: Int64?]?, Error>) -> Void + ) { + completion(.success(intMap)) + } + + func echoAsyncNullable( + enumMap: [AnEnum?: AnEnum?]?, completion: @escaping (Result<[AnEnum?: AnEnum?]?, Error>) -> Void + ) { + completion(.success(enumMap)) + } + + func echoAsyncNullable( + classMap: [Int64?: AllNullableTypes?]?, + completion: @escaping (Result<[Int64?: AllNullableTypes?]?, Error>) -> Void + ) { + completion(.success(classMap)) + } + + func echoAsyncNullable( + _ anEnum: AnEnum?, completion: @escaping (Result) -> Void + ) { completion(.success(anEnum)) } + func echoAsyncNullable( + _ anotherEnum: AnotherEnum?, completion: @escaping (Result) -> Void + ) { + completion(.success(anotherEnum)) + } + func callFlutterNoop(completion: @escaping (Result) -> Void) { flutterAPI.noop { response in switch response { @@ -480,9 +687,168 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { } func callFlutterEcho( - _ aMap: [String?: Any?], completion: @escaping (Result<[String?: Any?], Error>) -> Void + enumList: [AnEnum?], completion: @escaping (Result<[AnEnum?], Error>) -> Void + ) { + flutterAPI.echo(enumList: enumList) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEcho( + classList: [AllNullableTypes?], + completion: @escaping (Result<[AllNullableTypes?], Error>) -> Void + ) { + flutterAPI.echo(classList: classList) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNonNull( + enumList: [AnEnum], completion: @escaping (Result<[AnEnum], Error>) -> Void + ) { + flutterAPI.echoNonNull(enumList: enumList) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNonNull( + classList: [AllNullableTypes], completion: @escaping (Result<[AllNullableTypes], Error>) -> Void + ) { + flutterAPI.echoNonNull(classList: classList) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEcho( + _ map: [AnyHashable?: Any?], completion: @escaping (Result<[AnyHashable?: Any?], Error>) -> Void + ) { + flutterAPI.echo(map) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEcho( + stringMap: [String?: String?], completion: @escaping (Result<[String?: String?], Error>) -> Void + ) { + flutterAPI.echo(stringMap: stringMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEcho( + intMap: [Int64?: Int64?], completion: @escaping (Result<[Int64?: Int64?], Error>) -> Void + ) { + flutterAPI.echo(intMap: intMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEcho( + enumMap: [AnEnum?: AnEnum?], completion: @escaping (Result<[AnEnum?: AnEnum?], Error>) -> Void + ) { + flutterAPI.echo(enumMap: enumMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEcho( + classMap: [Int64?: AllNullableTypes?], + completion: @escaping (Result<[Int64?: AllNullableTypes?], Error>) -> Void + ) { + flutterAPI.echo(classMap: classMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNonNull( + stringMap: [String: String], completion: @escaping (Result<[String: String], Error>) -> Void + ) { + flutterAPI.echoNonNull(stringMap: stringMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNonNull( + intMap: [Int64: Int64], completion: @escaping (Result<[Int64: Int64], Error>) -> Void + ) { + flutterAPI.echoNonNull(intMap: intMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNonNull( + enumMap: [AnEnum: AnEnum], completion: @escaping (Result<[AnEnum: AnEnum], Error>) -> Void + ) { + flutterAPI.echoNonNull(enumMap: enumMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNonNull( + classMap: [Int64: AllNullableTypes], + completion: @escaping (Result<[Int64: AllNullableTypes], Error>) -> Void ) { - flutterAPI.echo(aMap) { response in + flutterAPI.echoNonNull(classMap: classMap) { response in switch response { case .success(let res): completion(.success(res)) @@ -492,7 +858,9 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { } } - func callFlutterEcho(_ anEnum: AnEnum, completion: @escaping (Result) -> Void) { + func callFlutterEcho( + _ anEnum: AnEnum, completion: @escaping (Result) -> Void + ) { flutterAPI.echo(anEnum) { response in switch response { case .success(let res): @@ -503,6 +871,19 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { } } + func callFlutterEcho( + _ anotherEnum: AnotherEnum, completion: @escaping (Result) -> Void + ) { + flutterAPI.echo(anotherEnum) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + func callFlutterEchoNullable(_ aBool: Bool?, completion: @escaping (Result) -> Void) { flutterAPI.echoNullable(aBool) { response in @@ -582,9 +963,9 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { } func callFlutterEchoNullable( - _ aMap: [String?: Any?]?, completion: @escaping (Result<[String?: Any?]?, Error>) -> Void + enumList: [AnEnum?]?, completion: @escaping (Result<[AnEnum?]?, Error>) -> Void ) { - flutterAPI.echoNullable(aMap) { response in + flutterAPI.echoNullable(enumList: enumList) { response in switch response { case .success(let res): completion(.success(res)) @@ -594,10 +975,11 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { } } - func callFlutterNullableEcho( - _ anEnum: AnEnum?, completion: @escaping (Result) -> Void + func callFlutterEchoNullable( + classList: [AllNullableTypes?]?, + completion: @escaping (Result<[AllNullableTypes?]?, Error>) -> Void ) { - flutterAPI.echoNullable(anEnum) { response in + flutterAPI.echoNullable(classList: classList) { response in switch response { case .success(let res): completion(.success(res)) @@ -607,7 +989,181 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { } } - func callFlutterSmallApiEcho( + func callFlutterEchoNullableNonNull( + enumList: [AnEnum]?, completion: @escaping (Result<[AnEnum]?, Error>) -> Void + ) { + flutterAPI.echoNullableNonNull(enumList: enumList) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableNonNull( + classList: [AllNullableTypes]?, + completion: @escaping (Result<[AllNullableTypes]?, Error>) -> Void + ) { + flutterAPI.echoNullableNonNull(classList: classList) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullable( + _ map: [AnyHashable?: Any?]?, + completion: @escaping (Result<[AnyHashable?: Any?]?, Error>) -> Void + ) { + flutterAPI.echoNullable(map) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullable( + stringMap: [String?: String?]?, + completion: @escaping (Result<[String?: String?]?, Error>) -> Void + ) { + flutterAPI.echoNullable(stringMap: stringMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullable( + intMap: [Int64?: Int64?]?, completion: @escaping (Result<[Int64?: Int64?]?, Error>) -> Void + ) { + flutterAPI.echoNullable(intMap: intMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullable( + enumMap: [AnEnum?: AnEnum?]?, completion: @escaping (Result<[AnEnum?: AnEnum?]?, Error>) -> Void + ) { + flutterAPI.echoNullable(enumMap: enumMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullable( + classMap: [Int64?: AllNullableTypes?]?, + completion: @escaping (Result<[Int64?: AllNullableTypes?]?, Error>) -> Void + ) { + flutterAPI.echoNullable(classMap: classMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableNonNull( + stringMap: [String: String]?, completion: @escaping (Result<[String: String]?, Error>) -> Void + ) { + flutterAPI.echoNullableNonNull(stringMap: stringMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableNonNull( + intMap: [Int64: Int64]?, completion: @escaping (Result<[Int64: Int64]?, Error>) -> Void + ) { + flutterAPI.echoNullableNonNull(intMap: intMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableNonNull( + enumMap: [AnEnum: AnEnum]?, completion: @escaping (Result<[AnEnum: AnEnum]?, Error>) -> Void + ) { + flutterAPI.echoNullableNonNull(enumMap: enumMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableNonNull( + classMap: [Int64: AllNullableTypes]?, + completion: @escaping (Result<[Int64: AllNullableTypes]?, Error>) -> Void + ) { + flutterAPI.echoNullableNonNull(classMap: classMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullable( + _ anEnum: AnEnum?, completion: @escaping (Result) -> Void + ) { + flutterAPI.echoNullable(anEnum) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullable( + _ anotherEnum: AnotherEnum?, completion: @escaping (Result) -> Void + ) { + flutterAPI.echoNullable(anotherEnum) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterSmallApiEcho( _ aString: String, completion: @escaping (Result) -> Void ) { flutterSmallApiOne.echo(string: aString) { responseOne in @@ -635,6 +1191,10 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { } } } + + func testUnusedClassesGenerate() -> UnusedClass { + return UnusedClass() + } } public class TestPluginWithSuffix: HostSmallApi { @@ -653,3 +1213,902 @@ public class TestPluginWithSuffix: HostSmallApi { } } + +class ProxyApiDelegate: ProxyApiTestsPigeonProxyApiDelegate { + func pigeonApiProxyApiTestClass(_ registrar: ProxyApiTestsPigeonProxyApiRegistrar) + -> PigeonApiProxyApiTestClass + { + class ProxyApiTestClassDelegate: PigeonApiDelegateProxyApiTestClass { + func pigeonDefaultConstructor( + pigeonApi: PigeonApiProxyApiTestClass, aBool: Bool, anInt: Int64, aDouble: Double, + aString: String, aUint8List: FlutterStandardTypedData, aList: [Any?], aMap: [String?: Any?], + anEnum: ProxyApiTestEnum, aProxyApi: ProxyApiSuperClass, aNullableBool: Bool?, + aNullableInt: Int64?, aNullableDouble: Double?, aNullableString: String?, + aNullableUint8List: FlutterStandardTypedData?, aNullableList: [Any?]?, + aNullableMap: [String?: Any?]?, aNullableEnum: ProxyApiTestEnum?, + aNullableProxyApi: ProxyApiSuperClass?, boolParam: Bool, intParam: Int64, + doubleParam: Double, stringParam: String, aUint8ListParam: FlutterStandardTypedData, + listParam: [Any?], mapParam: [String?: Any?], enumParam: ProxyApiTestEnum, + proxyApiParam: ProxyApiSuperClass, nullableBoolParam: Bool?, nullableIntParam: Int64?, + nullableDoubleParam: Double?, nullableStringParam: String?, + nullableUint8ListParam: FlutterStandardTypedData?, nullableListParam: [Any?]?, + nullableMapParam: [String?: Any?]?, nullableEnumParam: ProxyApiTestEnum?, + nullableProxyApiParam: ProxyApiSuperClass? + ) throws -> ProxyApiTestClass { + return ProxyApiTestClass() + } + + func attachedField(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> ProxyApiSuperClass + { + return ProxyApiSuperClass() + } + + func staticAttachedField(pigeonApi: PigeonApiProxyApiTestClass) throws -> ProxyApiSuperClass { + return ProxyApiSuperClass() + } + + func aBool(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> Bool + { + return true + } + + func anInt(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> Int64 + { + return 0 + } + + func aDouble(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> Double + { + return 0.0 + } + + func aString(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> String + { + return "" + } + + func aUint8List(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> FlutterStandardTypedData + { + return FlutterStandardTypedData(bytes: Data()) + } + + func aList(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> [Any?] + { + return [] + } + + func aMap(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> [String?: Any?] + { + return [:] + } + + func anEnum(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> ProxyApiTestEnum + { + return ProxyApiTestEnum.one + } + + func aProxyApi(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> ProxyApiSuperClass + { + return ProxyApiSuperClass() + } + + func aNullableBool(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> Bool? + { + return nil + } + + func aNullableInt(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> Int64? + { + return nil + } + + func aNullableDouble(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> Double? + { + return nil + } + + func aNullableString(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> String? + { + return nil + } + + func aNullableUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass + ) throws -> FlutterStandardTypedData? { + return nil + } + + func aNullableList(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> [Any?]? + { + return nil + } + + func aNullableMap(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> [String?: Any?]? + { + return nil + } + + func aNullableEnum(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> ProxyApiTestEnum? + { + return nil + } + + func aNullableProxyApi( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass + ) throws -> ProxyApiSuperClass? { + return nil + } + + func noop(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws { + } + + func throwError(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> Any? + { + throw ProxyApiTestsError(code: "code", message: "message", details: "details") + } + + func throwErrorFromVoid( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass + ) throws { + throw ProxyApiTestsError(code: "code", message: "message", details: "details") + } + + func throwFlutterError( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass + ) throws -> Any? { + throw ProxyApiTestsError(code: "code", message: "message", details: "details") + } + + func echoInt( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anInt: Int64 + ) throws -> Int64 { + return anInt + } + + func echoDouble( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aDouble: Double + ) throws -> Double { + return aDouble + } + + func echoBool( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aBool: Bool + ) throws -> Bool { + return aBool + } + + func echoString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aString: String + ) throws -> String { + return aString + } + + func echoUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aUint8List: FlutterStandardTypedData + ) throws -> FlutterStandardTypedData { + return aUint8List + } + + func echoObject( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anObject: Any + ) throws -> Any { + return anObject + } + + func echoList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aList: [Any?] + ) throws -> [Any?] { + return aList + } + + func echoProxyApiList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aList: [ProxyApiTestClass] + ) throws -> [ProxyApiTestClass] { + return aList + } + + func echoMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aMap: [String?: Any?] + ) throws -> [String?: Any?] { + return aMap + } + + func echoProxyApiMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aMap: [String: ProxyApiTestClass] + ) throws -> [String: ProxyApiTestClass] { + return aMap + } + + func echoEnum( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum + ) throws -> ProxyApiTestEnum { + return anEnum + } + + func echoProxyApi( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aProxyApi: ProxyApiSuperClass + ) throws -> ProxyApiSuperClass { + return aProxyApi + } + + func echoNullableInt( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableInt: Int64? + ) throws -> Int64? { + return aNullableInt + } + + func echoNullableDouble( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableDouble: Double? + ) throws -> Double? { + return aNullableDouble + } + + func echoNullableBool( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableBool: Bool? + ) throws -> Bool? { + return aNullableBool + } + + func echoNullableString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableString: String? + ) throws -> String? { + return aNullableString + } + + func echoNullableUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableUint8List: FlutterStandardTypedData? + ) throws -> FlutterStandardTypedData? { + return aNullableUint8List + } + + func echoNullableObject( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableObject: Any? + ) throws -> Any? { + return aNullableObject + } + + func echoNullableList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableList: [Any?]? + ) throws -> [Any?]? { + return aNullableList + } + + func echoNullableMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableMap: [String?: Any?]? + ) throws -> [String?: Any?]? { + return aNullableMap + } + + func echoNullableEnum( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableEnum: ProxyApiTestEnum? + ) throws -> ProxyApiTestEnum? { + return aNullableEnum + } + + func echoNullableProxyApi( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableProxyApi: ProxyApiSuperClass? + ) throws -> ProxyApiSuperClass? { + return aNullableProxyApi + } + + func noopAsync( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + completion(.success(Void())) + } + + func echoAsyncInt( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anInt: Int64, + completion: @escaping (Result) -> Void + ) { + completion(.success(anInt)) + } + + func echoAsyncDouble( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aDouble: Double, + completion: @escaping (Result) -> Void + ) { + completion(.success(aDouble)) + } + + func echoAsyncBool( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aBool: Bool, + completion: @escaping (Result) -> Void + ) { + completion(.success(aBool)) + } + + func echoAsyncString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aString: String, + completion: @escaping (Result) -> Void + ) { + completion(.success(aString)) + } + + func echoAsyncUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aUint8List: FlutterStandardTypedData, + completion: @escaping (Result) -> Void + ) { + completion(.success(aUint8List)) + } + + func echoAsyncObject( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anObject: Any, + completion: @escaping (Result) -> Void + ) { + completion(.success(anObject)) + } + + func echoAsyncList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aList: [Any?], + completion: @escaping (Result<[Any?], Error>) -> Void + ) { + completion(.success(aList)) + } + + func echoAsyncMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aMap: [String?: Any?], completion: @escaping (Result<[String?: Any?], Error>) -> Void + ) { + completion(.success(aMap)) + } + + func echoAsyncEnum( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum, completion: @escaping (Result) -> Void + ) { + completion(.success(anEnum)) + } + + func throwAsyncError( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + completion( + .failure(ProxyApiTestsError(code: "code", message: "message", details: "details"))) + } + + func throwAsyncErrorFromVoid( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + completion( + .failure(ProxyApiTestsError(code: "code", message: "message", details: "details"))) + } + + func throwAsyncFlutterError( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + completion( + .failure(ProxyApiTestsError(code: "code", message: "message", details: "details"))) + } + + func echoAsyncNullableInt( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anInt: Int64?, + completion: @escaping (Result) -> Void + ) { + completion(.success(anInt)) + } + + func echoAsyncNullableDouble( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aDouble: Double?, + completion: @escaping (Result) -> Void + ) { + completion(.success(aDouble)) + } + + func echoAsyncNullableBool( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aBool: Bool?, + completion: @escaping (Result) -> Void + ) { + completion(.success(aBool)) + } + + func echoAsyncNullableString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aString: String?, + completion: @escaping (Result) -> Void + ) { + completion(.success(aString)) + } + + func echoAsyncNullableUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aUint8List: FlutterStandardTypedData?, + completion: @escaping (Result) -> Void + ) { + completion(.success(aUint8List)) + } + + func echoAsyncNullableObject( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anObject: Any?, + completion: @escaping (Result) -> Void + ) { + completion(.success(anObject)) + } + + func echoAsyncNullableList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aList: [Any?]?, + completion: @escaping (Result<[Any?]?, Error>) -> Void + ) { + completion(.success(aList)) + } + + func echoAsyncNullableMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aMap: [String?: Any?]?, completion: @escaping (Result<[String?: Any?]?, Error>) -> Void + ) { + completion(.success(aMap)) + } + + func echoAsyncNullableEnum( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum?, completion: @escaping (Result) -> Void + ) { + completion(.success(anEnum)) + } + + func staticNoop(pigeonApi: PigeonApiProxyApiTestClass) throws { + + } + + func echoStaticString(pigeonApi: PigeonApiProxyApiTestClass, aString: String) throws -> String + { + return aString + } + + func staticAsyncNoop( + pigeonApi: PigeonApiProxyApiTestClass, completion: @escaping (Result) -> Void + ) { + completion(.success(Void())) + } + + func callFlutterNoop( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterNoop(pigeonInstance: pigeonInstance) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterThrowError( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterThrowError(pigeonInstance: pigeonInstance) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterThrowErrorFromVoid( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterThrowErrorFromVoid(pigeonInstance: pigeonInstance) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoBool( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aBool: Bool, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoBool(pigeonInstance: pigeonInstance, aBool: aBool) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoInt( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anInt: Int64, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoInt(pigeonInstance: pigeonInstance, anInt: anInt) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoDouble( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aDouble: Double, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoDouble(pigeonInstance: pigeonInstance, aDouble: aDouble) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aString: String, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoString(pigeonInstance: pigeonInstance, aString: aString) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aUint8List: FlutterStandardTypedData, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoUint8List(pigeonInstance: pigeonInstance, aList: aUint8List) { + response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aList: [Any?], + completion: @escaping (Result<[Any?], Error>) -> Void + ) { + pigeonApi.flutterEchoList(pigeonInstance: pigeonInstance, aList: aList) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoProxyApiList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aList: [ProxyApiTestClass?], + completion: @escaping (Result<[ProxyApiTestClass?], Error>) -> Void + ) { + pigeonApi.flutterEchoProxyApiList(pigeonInstance: pigeonInstance, aList: aList) { + response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aMap: [String?: Any?], completion: @escaping (Result<[String?: Any?], Error>) -> Void + ) { + pigeonApi.flutterEchoMap(pigeonInstance: pigeonInstance, aMap: aMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoProxyApiMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aMap: [String?: ProxyApiTestClass?], + completion: @escaping (Result<[String?: ProxyApiTestClass?], Error>) -> Void + ) { + pigeonApi.flutterEchoProxyApiMap(pigeonInstance: pigeonInstance, aMap: aMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoEnum( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum, completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoEnum(pigeonInstance: pigeonInstance, anEnum: anEnum) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoProxyApi( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aProxyApi: ProxyApiSuperClass, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoProxyApi(pigeonInstance: pigeonInstance, aProxyApi: aProxyApi) { + response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableBool( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aBool: Bool?, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoNullableBool(pigeonInstance: pigeonInstance, aBool: aBool) { + response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableInt( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anInt: Int64?, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoNullableInt(pigeonInstance: pigeonInstance, anInt: anInt) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableDouble( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aDouble: Double?, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoNullableDouble(pigeonInstance: pigeonInstance, aDouble: aDouble) { + response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aString: String?, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoNullableString(pigeonInstance: pigeonInstance, aString: aString) { + response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aUint8List: FlutterStandardTypedData?, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoNullableUint8List(pigeonInstance: pigeonInstance, aList: aUint8List) { + response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aList: [Any?]?, + completion: @escaping (Result<[Any?]?, Error>) -> Void + ) { + pigeonApi.flutterEchoNullableList(pigeonInstance: pigeonInstance, aList: aList) { + response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aMap: [String?: Any?]?, completion: @escaping (Result<[String?: Any?]?, Error>) -> Void + ) { + pigeonApi.flutterEchoNullableMap(pigeonInstance: pigeonInstance, aMap: aMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableEnum( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum?, completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoNullableEnum(pigeonInstance: pigeonInstance, anEnum: anEnum) { + response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableProxyApi( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aProxyApi: ProxyApiSuperClass?, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoNullableProxyApi(pigeonInstance: pigeonInstance, aProxyApi: aProxyApi) + { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterNoopAsync( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterNoopAsync(pigeonInstance: pigeonInstance) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoAsyncString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aString: String, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoAsyncString(pigeonInstance: pigeonInstance, aString: aString) { + response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + } + return PigeonApiProxyApiTestClass( + pigeonRegistrar: registrar, delegate: ProxyApiTestClassDelegate()) + } + + func pigeonApiProxyApiSuperClass(_ registrar: ProxyApiTestsPigeonProxyApiRegistrar) + -> PigeonApiProxyApiSuperClass + { + class ProxyApiSuperClassDelegate: PigeonApiDelegateProxyApiSuperClass { + func pigeonDefaultConstructor(pigeonApi: PigeonApiProxyApiSuperClass) throws + -> ProxyApiSuperClass + { + return ProxyApiSuperClass() + } + + func aSuperMethod(pigeonApi: PigeonApiProxyApiSuperClass, pigeonInstance: ProxyApiSuperClass) + throws + {} + } + return PigeonApiProxyApiSuperClass( + pigeonRegistrar: registrar, delegate: ProxyApiSuperClassDelegate()) + } + + func pigeonApiClassWithApiRequirement(_ registrar: ProxyApiTestsPigeonProxyApiRegistrar) + -> PigeonApiClassWithApiRequirement + { + class ClassWithApiRequirementDelegate: PigeonApiDelegateClassWithApiRequirement { + @available(iOS 15, *) + func pigeonDefaultConstructor(pigeonApi: PigeonApiClassWithApiRequirement) throws + -> ClassWithApiRequirement + { + return ClassWithApiRequirement() + } + + @available(iOS 15, *) + func aMethod( + pigeonApi: PigeonApiClassWithApiRequirement, pigeonInstance: ClassWithApiRequirement + ) throws { + + } + } + + return PigeonApiClassWithApiRequirement( + pigeonRegistrar: registrar, delegate: ClassWithApiRequirementDelegate()) + } +} diff --git a/packages/pigeon/platform_tests/test_plugin/linux/CMakeLists.txt b/packages/pigeon/platform_tests/test_plugin/linux/CMakeLists.txt new file mode 100644 index 000000000000..3d2845f8d3e4 --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/linux/CMakeLists.txt @@ -0,0 +1,119 @@ +# The Flutter tooling requires that developers have CMake 3.10 or later +# installed. You should not increase this version, as doing so will cause +# the plugin to fail to compile for some customers of the plugin. +cmake_minimum_required(VERSION 3.10) + +# Project-level configuration. +set(PROJECT_NAME "test_plugin") +project(${PROJECT_NAME} LANGUAGES CXX) + +# This value is used when generating builds using this plugin, so it must +# not be changed. +set(PLUGIN_NAME "test_plugin_plugin") + +# Any new source files that you add to the plugin should be added here. +list(APPEND PLUGIN_SOURCES + "test_plugin.cc" + # Generated sources. + "pigeon/core_tests.gen.cc" + "pigeon/core_tests.gen.h" + "pigeon/enum.gen.cc" + "pigeon/enum.gen.h" + "pigeon/message.gen.cc" + "pigeon/message.gen.h" + "pigeon/multiple_arity.gen.cc" + "pigeon/multiple_arity.gen.h" + "pigeon/non_null_fields.gen.cc" + "pigeon/non_null_fields.gen.h" + "pigeon/null_fields.gen.cc" + "pigeon/null_fields.gen.h" + "pigeon/nullable_returns.gen.cc" + "pigeon/nullable_returns.gen.h" + "pigeon/primitive.gen.cc" + "pigeon/primitive.gen.h" +) + +# Define the plugin library target. Its name must not be changed (see comment +# on PLUGIN_NAME above). +add_library(${PLUGIN_NAME} SHARED + ${PLUGIN_SOURCES} +) + +# Apply a standard set of build settings that are configured in the +# application-level CMakeLists.txt. This can be removed for plugins that want +# full control over build settings. +apply_standard_settings(${PLUGIN_NAME}) + +# Symbols are hidden by default to reduce the chance of accidental conflicts +# between plugins. This should not be removed; any symbols that should be +# exported should be explicitly exported with the FLUTTER_PLUGIN_EXPORT macro. +set_target_properties(${PLUGIN_NAME} PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL) + +# Source include directories and library dependencies. Add any plugin-specific +# dependencies here. +target_include_directories(${PLUGIN_NAME} INTERFACE + "${CMAKE_CURRENT_SOURCE_DIR}/include") +target_link_libraries(${PLUGIN_NAME} PRIVATE flutter) +target_link_libraries(${PLUGIN_NAME} PRIVATE PkgConfig::GTK) + +# List of absolute paths to libraries that should be bundled with the plugin. +# This list could contain prebuilt libraries, or libraries created by an +# external build triggered from this build file. +set(test_plugin_bundled_libraries + "" + PARENT_SCOPE +) + +# === Tests === +# These unit tests can be run from a terminal after building the example. + +# Only enable test builds when building the example (which sets this variable) +# so that plugin clients aren't building the tests. +if (${include_${PROJECT_NAME}_tests}) +if(${CMAKE_VERSION} VERSION_LESS "3.11.0") +message("Unit tests require CMake 3.11.0 or later") +else() +set(TEST_RUNNER "${PROJECT_NAME}_test") +enable_testing() + +# Add the Google Test dependency. +include(FetchContent) +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/release-1.11.0.zip +) +# Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +# Disable install commands for gtest so it doesn't end up in the bundle. +set(INSTALL_GTEST OFF CACHE BOOL "Disable installation of googletest" FORCE) + +FetchContent_MakeAvailable(googletest) + +# The plugin's exported API is not very useful for unit testing, so build the +# sources directly into the test binary rather than using the shared library. +add_executable(${TEST_RUNNER} + # Tests. + test/multiple_arity_test.cc + test/non_null_fields_test.cc + test/nullable_returns_test.cc + test/null_fields_test.cc + test/primitive_test.cc + # Test utilities. + test/utils/fake_host_messenger.cc + test/utils/fake_host_messenger.h + ${PLUGIN_SOURCES} +) +apply_standard_settings(${TEST_RUNNER}) +target_include_directories(${TEST_RUNNER} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}") +target_link_libraries(${TEST_RUNNER} PRIVATE flutter) +target_link_libraries(${TEST_RUNNER} PRIVATE PkgConfig::GTK) +target_link_libraries(${TEST_RUNNER} PRIVATE gtest_main gmock) + +# Enable automatic test discovery. +include(GoogleTest) +gtest_discover_tests(${TEST_RUNNER}) + +endif() # CMake version check +endif() # include_${PROJECT_NAME}_tests \ No newline at end of file diff --git a/packages/pigeon/platform_tests/test_plugin/linux/include/test_plugin/test_plugin.h b/packages/pigeon/platform_tests/test_plugin/linux/include/test_plugin/test_plugin.h new file mode 100644 index 000000000000..9cb33f32e54e --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/linux/include/test_plugin/test_plugin.h @@ -0,0 +1,25 @@ +// 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. + +#ifndef FLUTTER_PLUGIN_TEST_PLUGIN_H_ +#define FLUTTER_PLUGIN_TEST_PLUGIN_H_ + +#include + +G_BEGIN_DECLS + +#ifdef FLUTTER_PLUGIN_IMPL +#define FLUTTER_PLUGIN_EXPORT __attribute__((visibility("default"))) +#else +#define FLUTTER_PLUGIN_EXPORT +#endif + +G_DECLARE_FINAL_TYPE(TestPlugin, test_plugin, TEST, PLUGIN, GObject) + +FLUTTER_PLUGIN_EXPORT void test_plugin_register_with_registrar( + FlPluginRegistrar* registrar); + +G_END_DECLS + +#endif // FLUTTER_PLUGIN_TEST_PLUGIN_H_ diff --git a/packages/pigeon/platform_tests/test_plugin/linux/pigeon/.gitignore b/packages/pigeon/platform_tests/test_plugin/linux/pigeon/.gitignore new file mode 100644 index 000000000000..3c556db82870 --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/linux/pigeon/.gitignore @@ -0,0 +1,6 @@ +# TODO(stuartmorgan): Remove this, so that review will show the effects of +# changes on generated files, once https://github.com/flutter/flutter/issues/115168 +# is done. +*.gen.h +*.gen.cc +!core_tests.gen* diff --git a/packages/pigeon/platform_tests/test_plugin/linux/pigeon/core_tests.gen.cc b/packages/pigeon/platform_tests/test_plugin/linux/pigeon/core_tests.gen.cc new file mode 100644 index 000000000000..5701f91c2355 --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/linux/pigeon/core_tests.gen.cc @@ -0,0 +1,33563 @@ +// 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, do not edit directly. +// See also: https://pub.dev/packages/pigeon + +#include "core_tests.gen.h" + +struct _CoreTestsPigeonTestUnusedClass { + GObject parent_instance; + + FlValue* a_field; +}; + +G_DEFINE_TYPE(CoreTestsPigeonTestUnusedClass, + core_tests_pigeon_test_unused_class, G_TYPE_OBJECT) + +static void core_tests_pigeon_test_unused_class_dispose(GObject* object) { + CoreTestsPigeonTestUnusedClass* self = + CORE_TESTS_PIGEON_TEST_UNUSED_CLASS(object); + g_clear_pointer(&self->a_field, fl_value_unref); + G_OBJECT_CLASS(core_tests_pigeon_test_unused_class_parent_class) + ->dispose(object); +} + +static void core_tests_pigeon_test_unused_class_init( + CoreTestsPigeonTestUnusedClass* self) {} + +static void core_tests_pigeon_test_unused_class_class_init( + CoreTestsPigeonTestUnusedClassClass* klass) { + G_OBJECT_CLASS(klass)->dispose = core_tests_pigeon_test_unused_class_dispose; +} + +CoreTestsPigeonTestUnusedClass* core_tests_pigeon_test_unused_class_new( + FlValue* a_field) { + CoreTestsPigeonTestUnusedClass* self = CORE_TESTS_PIGEON_TEST_UNUSED_CLASS( + g_object_new(core_tests_pigeon_test_unused_class_get_type(), nullptr)); + if (a_field != nullptr) { + self->a_field = fl_value_ref(a_field); + } else { + self->a_field = nullptr; + } + return self; +} + +FlValue* core_tests_pigeon_test_unused_class_get_a_field( + CoreTestsPigeonTestUnusedClass* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_UNUSED_CLASS(self), nullptr); + return self->a_field; +} + +static FlValue* core_tests_pigeon_test_unused_class_to_list( + CoreTestsPigeonTestUnusedClass* self) { + FlValue* values = fl_value_new_list(); + fl_value_append_take(values, self->a_field != nullptr + ? fl_value_ref(self->a_field) + : fl_value_new_null()); + return values; +} + +static CoreTestsPigeonTestUnusedClass* +core_tests_pigeon_test_unused_class_new_from_list(FlValue* values) { + FlValue* value0 = fl_value_get_list_value(values, 0); + FlValue* a_field = nullptr; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + a_field = value0; + } + return core_tests_pigeon_test_unused_class_new(a_field); +} + +struct _CoreTestsPigeonTestAllTypes { + GObject parent_instance; + + gboolean a_bool; + int64_t an_int; + int64_t an_int64; + double a_double; + uint8_t* a_byte_array; + size_t a_byte_array_length; + int32_t* a4_byte_array; + size_t a4_byte_array_length; + int64_t* a8_byte_array; + size_t a8_byte_array_length; + double* a_float_array; + size_t a_float_array_length; + CoreTestsPigeonTestAnEnum an_enum; + CoreTestsPigeonTestAnotherEnum another_enum; + gchar* a_string; + FlValue* an_object; + FlValue* list; + FlValue* string_list; + FlValue* int_list; + FlValue* double_list; + FlValue* bool_list; + FlValue* enum_list; + FlValue* object_list; + FlValue* list_list; + FlValue* map_list; + FlValue* map; + FlValue* string_map; + FlValue* int_map; + FlValue* enum_map; + FlValue* object_map; + FlValue* list_map; + FlValue* map_map; +}; + +G_DEFINE_TYPE(CoreTestsPigeonTestAllTypes, core_tests_pigeon_test_all_types, + G_TYPE_OBJECT) + +static void core_tests_pigeon_test_all_types_dispose(GObject* object) { + CoreTestsPigeonTestAllTypes* self = CORE_TESTS_PIGEON_TEST_ALL_TYPES(object); + g_clear_pointer(&self->a_string, g_free); + g_clear_pointer(&self->an_object, fl_value_unref); + g_clear_pointer(&self->list, fl_value_unref); + g_clear_pointer(&self->string_list, fl_value_unref); + g_clear_pointer(&self->int_list, fl_value_unref); + g_clear_pointer(&self->double_list, fl_value_unref); + g_clear_pointer(&self->bool_list, fl_value_unref); + g_clear_pointer(&self->enum_list, fl_value_unref); + g_clear_pointer(&self->object_list, fl_value_unref); + g_clear_pointer(&self->list_list, fl_value_unref); + g_clear_pointer(&self->map_list, fl_value_unref); + g_clear_pointer(&self->map, fl_value_unref); + g_clear_pointer(&self->string_map, fl_value_unref); + g_clear_pointer(&self->int_map, fl_value_unref); + g_clear_pointer(&self->enum_map, fl_value_unref); + g_clear_pointer(&self->object_map, fl_value_unref); + g_clear_pointer(&self->list_map, fl_value_unref); + g_clear_pointer(&self->map_map, fl_value_unref); + G_OBJECT_CLASS(core_tests_pigeon_test_all_types_parent_class) + ->dispose(object); +} + +static void core_tests_pigeon_test_all_types_init( + CoreTestsPigeonTestAllTypes* self) {} + +static void core_tests_pigeon_test_all_types_class_init( + CoreTestsPigeonTestAllTypesClass* klass) { + G_OBJECT_CLASS(klass)->dispose = core_tests_pigeon_test_all_types_dispose; +} + +CoreTestsPigeonTestAllTypes* core_tests_pigeon_test_all_types_new( + gboolean a_bool, int64_t an_int, int64_t an_int64, double a_double, + const uint8_t* a_byte_array, size_t a_byte_array_length, + const int32_t* a4_byte_array, size_t a4_byte_array_length, + const int64_t* a8_byte_array, size_t a8_byte_array_length, + const double* a_float_array, size_t a_float_array_length, + CoreTestsPigeonTestAnEnum an_enum, + CoreTestsPigeonTestAnotherEnum another_enum, const gchar* a_string, + FlValue* an_object, FlValue* list, FlValue* string_list, FlValue* int_list, + FlValue* double_list, FlValue* bool_list, FlValue* enum_list, + FlValue* object_list, FlValue* list_list, FlValue* map_list, FlValue* map, + FlValue* string_map, FlValue* int_map, FlValue* enum_map, + FlValue* object_map, FlValue* list_map, FlValue* map_map) { + CoreTestsPigeonTestAllTypes* self = CORE_TESTS_PIGEON_TEST_ALL_TYPES( + g_object_new(core_tests_pigeon_test_all_types_get_type(), nullptr)); + self->a_bool = a_bool; + self->an_int = an_int; + self->an_int64 = an_int64; + self->a_double = a_double; + self->a_byte_array = static_cast( + memcpy(malloc(a_byte_array_length), a_byte_array, a_byte_array_length)); + self->a_byte_array_length = a_byte_array_length; + self->a4_byte_array = static_cast( + memcpy(malloc(sizeof(int32_t) * a4_byte_array_length), a4_byte_array, + sizeof(int32_t) * a4_byte_array_length)); + self->a4_byte_array_length = a4_byte_array_length; + self->a8_byte_array = static_cast( + memcpy(malloc(sizeof(int64_t) * a8_byte_array_length), a8_byte_array, + sizeof(int64_t) * a8_byte_array_length)); + self->a8_byte_array_length = a8_byte_array_length; + self->a_float_array = static_cast( + memcpy(malloc(sizeof(double) * a_float_array_length), a_float_array, + sizeof(double) * a_float_array_length)); + self->a_float_array_length = a_float_array_length; + self->an_enum = an_enum; + self->another_enum = another_enum; + self->a_string = g_strdup(a_string); + self->an_object = fl_value_ref(an_object); + self->list = fl_value_ref(list); + self->string_list = fl_value_ref(string_list); + self->int_list = fl_value_ref(int_list); + self->double_list = fl_value_ref(double_list); + self->bool_list = fl_value_ref(bool_list); + self->enum_list = fl_value_ref(enum_list); + self->object_list = fl_value_ref(object_list); + self->list_list = fl_value_ref(list_list); + self->map_list = fl_value_ref(map_list); + self->map = fl_value_ref(map); + self->string_map = fl_value_ref(string_map); + self->int_map = fl_value_ref(int_map); + self->enum_map = fl_value_ref(enum_map); + self->object_map = fl_value_ref(object_map); + self->list_map = fl_value_ref(list_map); + self->map_map = fl_value_ref(map_map); + return self; +} + +gboolean core_tests_pigeon_test_all_types_get_a_bool( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), FALSE); + return self->a_bool; +} + +int64_t core_tests_pigeon_test_all_types_get_an_int( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), 0); + return self->an_int; +} + +int64_t core_tests_pigeon_test_all_types_get_an_int64( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), 0); + return self->an_int64; +} + +double core_tests_pigeon_test_all_types_get_a_double( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), 0.0); + return self->a_double; +} + +const uint8_t* core_tests_pigeon_test_all_types_get_a_byte_array( + CoreTestsPigeonTestAllTypes* self, size_t* length) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), nullptr); + *length = self->a_byte_array_length; + return self->a_byte_array; +} + +const int32_t* core_tests_pigeon_test_all_types_get_a4_byte_array( + CoreTestsPigeonTestAllTypes* self, size_t* length) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), nullptr); + *length = self->a4_byte_array_length; + return self->a4_byte_array; +} + +const int64_t* core_tests_pigeon_test_all_types_get_a8_byte_array( + CoreTestsPigeonTestAllTypes* self, size_t* length) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), nullptr); + *length = self->a8_byte_array_length; + return self->a8_byte_array; +} + +const double* core_tests_pigeon_test_all_types_get_a_float_array( + CoreTestsPigeonTestAllTypes* self, size_t* length) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), nullptr); + *length = self->a_float_array_length; + return self->a_float_array; +} + +CoreTestsPigeonTestAnEnum core_tests_pigeon_test_all_types_get_an_enum( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), + static_cast(0)); + return self->an_enum; +} + +CoreTestsPigeonTestAnotherEnum +core_tests_pigeon_test_all_types_get_another_enum( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), + static_cast(0)); + return self->another_enum; +} + +const gchar* core_tests_pigeon_test_all_types_get_a_string( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), nullptr); + return self->a_string; +} + +FlValue* core_tests_pigeon_test_all_types_get_an_object( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), nullptr); + return self->an_object; +} + +FlValue* core_tests_pigeon_test_all_types_get_list( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), nullptr); + return self->list; +} + +FlValue* core_tests_pigeon_test_all_types_get_string_list( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), nullptr); + return self->string_list; +} + +FlValue* core_tests_pigeon_test_all_types_get_int_list( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), nullptr); + return self->int_list; +} + +FlValue* core_tests_pigeon_test_all_types_get_double_list( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), nullptr); + return self->double_list; +} + +FlValue* core_tests_pigeon_test_all_types_get_bool_list( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), nullptr); + return self->bool_list; +} + +FlValue* core_tests_pigeon_test_all_types_get_enum_list( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), nullptr); + return self->enum_list; +} + +FlValue* core_tests_pigeon_test_all_types_get_object_list( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), nullptr); + return self->object_list; +} + +FlValue* core_tests_pigeon_test_all_types_get_list_list( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), nullptr); + return self->list_list; +} + +FlValue* core_tests_pigeon_test_all_types_get_map_list( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), nullptr); + return self->map_list; +} + +FlValue* core_tests_pigeon_test_all_types_get_map( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), nullptr); + return self->map; +} + +FlValue* core_tests_pigeon_test_all_types_get_string_map( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), nullptr); + return self->string_map; +} + +FlValue* core_tests_pigeon_test_all_types_get_int_map( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), nullptr); + return self->int_map; +} + +FlValue* core_tests_pigeon_test_all_types_get_enum_map( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), nullptr); + return self->enum_map; +} + +FlValue* core_tests_pigeon_test_all_types_get_object_map( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), nullptr); + return self->object_map; +} + +FlValue* core_tests_pigeon_test_all_types_get_list_map( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), nullptr); + return self->list_map; +} + +FlValue* core_tests_pigeon_test_all_types_get_map_map( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), nullptr); + return self->map_map; +} + +static FlValue* core_tests_pigeon_test_all_types_to_list( + CoreTestsPigeonTestAllTypes* self) { + FlValue* values = fl_value_new_list(); + fl_value_append_take(values, fl_value_new_bool(self->a_bool)); + fl_value_append_take(values, fl_value_new_int(self->an_int)); + fl_value_append_take(values, fl_value_new_int(self->an_int64)); + fl_value_append_take(values, fl_value_new_float(self->a_double)); + fl_value_append_take( + values, + fl_value_new_uint8_list(self->a_byte_array, self->a_byte_array_length)); + fl_value_append_take( + values, + fl_value_new_int32_list(self->a4_byte_array, self->a4_byte_array_length)); + fl_value_append_take( + values, + fl_value_new_int64_list(self->a8_byte_array, self->a8_byte_array_length)); + fl_value_append_take( + values, + fl_value_new_float_list(self->a_float_array, self->a_float_array_length)); + fl_value_append_take(values, + fl_value_new_custom(129, fl_value_new_int(self->an_enum), + (GDestroyNotify)fl_value_unref)); + fl_value_append_take( + values, fl_value_new_custom(130, fl_value_new_int(self->another_enum), + (GDestroyNotify)fl_value_unref)); + fl_value_append_take(values, fl_value_new_string(self->a_string)); + fl_value_append_take(values, fl_value_ref(self->an_object)); + fl_value_append_take(values, fl_value_ref(self->list)); + fl_value_append_take(values, fl_value_ref(self->string_list)); + fl_value_append_take(values, fl_value_ref(self->int_list)); + fl_value_append_take(values, fl_value_ref(self->double_list)); + fl_value_append_take(values, fl_value_ref(self->bool_list)); + fl_value_append_take(values, fl_value_ref(self->enum_list)); + fl_value_append_take(values, fl_value_ref(self->object_list)); + fl_value_append_take(values, fl_value_ref(self->list_list)); + fl_value_append_take(values, fl_value_ref(self->map_list)); + fl_value_append_take(values, fl_value_ref(self->map)); + fl_value_append_take(values, fl_value_ref(self->string_map)); + fl_value_append_take(values, fl_value_ref(self->int_map)); + fl_value_append_take(values, fl_value_ref(self->enum_map)); + fl_value_append_take(values, fl_value_ref(self->object_map)); + fl_value_append_take(values, fl_value_ref(self->list_map)); + fl_value_append_take(values, fl_value_ref(self->map_map)); + return values; +} + +static CoreTestsPigeonTestAllTypes* +core_tests_pigeon_test_all_types_new_from_list(FlValue* values) { + FlValue* value0 = fl_value_get_list_value(values, 0); + gboolean a_bool = fl_value_get_bool(value0); + FlValue* value1 = fl_value_get_list_value(values, 1); + int64_t an_int = fl_value_get_int(value1); + FlValue* value2 = fl_value_get_list_value(values, 2); + int64_t an_int64 = fl_value_get_int(value2); + FlValue* value3 = fl_value_get_list_value(values, 3); + double a_double = fl_value_get_float(value3); + FlValue* value4 = fl_value_get_list_value(values, 4); + const uint8_t* a_byte_array = fl_value_get_uint8_list(value4); + size_t a_byte_array_length = fl_value_get_length(value4); + FlValue* value5 = fl_value_get_list_value(values, 5); + const int32_t* a4_byte_array = fl_value_get_int32_list(value5); + size_t a4_byte_array_length = fl_value_get_length(value5); + FlValue* value6 = fl_value_get_list_value(values, 6); + const int64_t* a8_byte_array = fl_value_get_int64_list(value6); + size_t a8_byte_array_length = fl_value_get_length(value6); + FlValue* value7 = fl_value_get_list_value(values, 7); + const double* a_float_array = fl_value_get_float_list(value7); + size_t a_float_array_length = fl_value_get_length(value7); + FlValue* value8 = fl_value_get_list_value(values, 8); + CoreTestsPigeonTestAnEnum an_enum = static_cast( + fl_value_get_int(reinterpret_cast( + const_cast(fl_value_get_custom_value(value8))))); + FlValue* value9 = fl_value_get_list_value(values, 9); + CoreTestsPigeonTestAnotherEnum another_enum = + static_cast( + fl_value_get_int(reinterpret_cast( + const_cast(fl_value_get_custom_value(value9))))); + FlValue* value10 = fl_value_get_list_value(values, 10); + const gchar* a_string = fl_value_get_string(value10); + FlValue* value11 = fl_value_get_list_value(values, 11); + FlValue* an_object = value11; + FlValue* value12 = fl_value_get_list_value(values, 12); + FlValue* list = value12; + FlValue* value13 = fl_value_get_list_value(values, 13); + FlValue* string_list = value13; + FlValue* value14 = fl_value_get_list_value(values, 14); + FlValue* int_list = value14; + FlValue* value15 = fl_value_get_list_value(values, 15); + FlValue* double_list = value15; + FlValue* value16 = fl_value_get_list_value(values, 16); + FlValue* bool_list = value16; + FlValue* value17 = fl_value_get_list_value(values, 17); + FlValue* enum_list = value17; + FlValue* value18 = fl_value_get_list_value(values, 18); + FlValue* object_list = value18; + FlValue* value19 = fl_value_get_list_value(values, 19); + FlValue* list_list = value19; + FlValue* value20 = fl_value_get_list_value(values, 20); + FlValue* map_list = value20; + FlValue* value21 = fl_value_get_list_value(values, 21); + FlValue* map = value21; + FlValue* value22 = fl_value_get_list_value(values, 22); + FlValue* string_map = value22; + FlValue* value23 = fl_value_get_list_value(values, 23); + FlValue* int_map = value23; + FlValue* value24 = fl_value_get_list_value(values, 24); + FlValue* enum_map = value24; + FlValue* value25 = fl_value_get_list_value(values, 25); + FlValue* object_map = value25; + FlValue* value26 = fl_value_get_list_value(values, 26); + FlValue* list_map = value26; + FlValue* value27 = fl_value_get_list_value(values, 27); + FlValue* map_map = value27; + return core_tests_pigeon_test_all_types_new( + a_bool, an_int, an_int64, a_double, a_byte_array, a_byte_array_length, + a4_byte_array, a4_byte_array_length, a8_byte_array, a8_byte_array_length, + a_float_array, a_float_array_length, an_enum, another_enum, a_string, + an_object, list, string_list, int_list, double_list, bool_list, enum_list, + object_list, list_list, map_list, map, string_map, int_map, enum_map, + object_map, list_map, map_map); +} + +struct _CoreTestsPigeonTestAllNullableTypes { + GObject parent_instance; + + gboolean* a_nullable_bool; + int64_t* a_nullable_int; + int64_t* a_nullable_int64; + double* a_nullable_double; + uint8_t* a_nullable_byte_array; + size_t a_nullable_byte_array_length; + int32_t* a_nullable4_byte_array; + size_t a_nullable4_byte_array_length; + int64_t* a_nullable8_byte_array; + size_t a_nullable8_byte_array_length; + double* a_nullable_float_array; + size_t a_nullable_float_array_length; + CoreTestsPigeonTestAnEnum* a_nullable_enum; + CoreTestsPigeonTestAnotherEnum* another_nullable_enum; + gchar* a_nullable_string; + FlValue* a_nullable_object; + CoreTestsPigeonTestAllNullableTypes* all_nullable_types; + FlValue* list; + FlValue* string_list; + FlValue* int_list; + FlValue* double_list; + FlValue* bool_list; + FlValue* enum_list; + FlValue* object_list; + FlValue* list_list; + FlValue* map_list; + FlValue* recursive_class_list; + FlValue* map; + FlValue* string_map; + FlValue* int_map; + FlValue* enum_map; + FlValue* object_map; + FlValue* list_map; + FlValue* map_map; + FlValue* recursive_class_map; +}; + +G_DEFINE_TYPE(CoreTestsPigeonTestAllNullableTypes, + core_tests_pigeon_test_all_nullable_types, G_TYPE_OBJECT) + +static void core_tests_pigeon_test_all_nullable_types_dispose(GObject* object) { + CoreTestsPigeonTestAllNullableTypes* self = + CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES(object); + g_clear_pointer(&self->a_nullable_bool, g_free); + g_clear_pointer(&self->a_nullable_int, g_free); + g_clear_pointer(&self->a_nullable_int64, g_free); + g_clear_pointer(&self->a_nullable_double, g_free); + g_clear_pointer(&self->a_nullable_enum, g_free); + g_clear_pointer(&self->another_nullable_enum, g_free); + g_clear_pointer(&self->a_nullable_string, g_free); + g_clear_pointer(&self->a_nullable_object, fl_value_unref); + g_clear_object(&self->all_nullable_types); + g_clear_pointer(&self->list, fl_value_unref); + g_clear_pointer(&self->string_list, fl_value_unref); + g_clear_pointer(&self->int_list, fl_value_unref); + g_clear_pointer(&self->double_list, fl_value_unref); + g_clear_pointer(&self->bool_list, fl_value_unref); + g_clear_pointer(&self->enum_list, fl_value_unref); + g_clear_pointer(&self->object_list, fl_value_unref); + g_clear_pointer(&self->list_list, fl_value_unref); + g_clear_pointer(&self->map_list, fl_value_unref); + g_clear_pointer(&self->recursive_class_list, fl_value_unref); + g_clear_pointer(&self->map, fl_value_unref); + g_clear_pointer(&self->string_map, fl_value_unref); + g_clear_pointer(&self->int_map, fl_value_unref); + g_clear_pointer(&self->enum_map, fl_value_unref); + g_clear_pointer(&self->object_map, fl_value_unref); + g_clear_pointer(&self->list_map, fl_value_unref); + g_clear_pointer(&self->map_map, fl_value_unref); + g_clear_pointer(&self->recursive_class_map, fl_value_unref); + G_OBJECT_CLASS(core_tests_pigeon_test_all_nullable_types_parent_class) + ->dispose(object); +} + +static void core_tests_pigeon_test_all_nullable_types_init( + CoreTestsPigeonTestAllNullableTypes* self) {} + +static void core_tests_pigeon_test_all_nullable_types_class_init( + CoreTestsPigeonTestAllNullableTypesClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_all_nullable_types_dispose; +} + +CoreTestsPigeonTestAllNullableTypes* +core_tests_pigeon_test_all_nullable_types_new( + gboolean* a_nullable_bool, int64_t* a_nullable_int, + int64_t* a_nullable_int64, double* a_nullable_double, + const uint8_t* a_nullable_byte_array, size_t a_nullable_byte_array_length, + const int32_t* a_nullable4_byte_array, size_t a_nullable4_byte_array_length, + const int64_t* a_nullable8_byte_array, size_t a_nullable8_byte_array_length, + const double* a_nullable_float_array, size_t a_nullable_float_array_length, + CoreTestsPigeonTestAnEnum* a_nullable_enum, + CoreTestsPigeonTestAnotherEnum* another_nullable_enum, + const gchar* a_nullable_string, FlValue* a_nullable_object, + CoreTestsPigeonTestAllNullableTypes* all_nullable_types, FlValue* list, + FlValue* string_list, FlValue* int_list, FlValue* double_list, + FlValue* bool_list, FlValue* enum_list, FlValue* object_list, + FlValue* list_list, FlValue* map_list, FlValue* recursive_class_list, + FlValue* map, FlValue* string_map, FlValue* int_map, FlValue* enum_map, + FlValue* object_map, FlValue* list_map, FlValue* map_map, + FlValue* recursive_class_map) { + CoreTestsPigeonTestAllNullableTypes* self = + CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES(g_object_new( + core_tests_pigeon_test_all_nullable_types_get_type(), nullptr)); + if (a_nullable_bool != nullptr) { + self->a_nullable_bool = static_cast(malloc(sizeof(gboolean))); + *self->a_nullable_bool = *a_nullable_bool; + } else { + self->a_nullable_bool = nullptr; + } + if (a_nullable_int != nullptr) { + self->a_nullable_int = static_cast(malloc(sizeof(int64_t))); + *self->a_nullable_int = *a_nullable_int; + } else { + self->a_nullable_int = nullptr; + } + if (a_nullable_int64 != nullptr) { + self->a_nullable_int64 = static_cast(malloc(sizeof(int64_t))); + *self->a_nullable_int64 = *a_nullable_int64; + } else { + self->a_nullable_int64 = nullptr; + } + if (a_nullable_double != nullptr) { + self->a_nullable_double = static_cast(malloc(sizeof(double))); + *self->a_nullable_double = *a_nullable_double; + } else { + self->a_nullable_double = nullptr; + } + if (a_nullable_byte_array != nullptr) { + self->a_nullable_byte_array = static_cast( + memcpy(malloc(a_nullable_byte_array_length), a_nullable_byte_array, + a_nullable_byte_array_length)); + self->a_nullable_byte_array_length = a_nullable_byte_array_length; + } else { + self->a_nullable_byte_array = nullptr; + self->a_nullable_byte_array_length = 0; + } + if (a_nullable4_byte_array != nullptr) { + self->a_nullable4_byte_array = static_cast( + memcpy(malloc(sizeof(int32_t) * a_nullable4_byte_array_length), + a_nullable4_byte_array, + sizeof(int32_t) * a_nullable4_byte_array_length)); + self->a_nullable4_byte_array_length = a_nullable4_byte_array_length; + } else { + self->a_nullable4_byte_array = nullptr; + self->a_nullable4_byte_array_length = 0; + } + if (a_nullable8_byte_array != nullptr) { + self->a_nullable8_byte_array = static_cast( + memcpy(malloc(sizeof(int64_t) * a_nullable8_byte_array_length), + a_nullable8_byte_array, + sizeof(int64_t) * a_nullable8_byte_array_length)); + self->a_nullable8_byte_array_length = a_nullable8_byte_array_length; + } else { + self->a_nullable8_byte_array = nullptr; + self->a_nullable8_byte_array_length = 0; + } + if (a_nullable_float_array != nullptr) { + self->a_nullable_float_array = static_cast( + memcpy(malloc(sizeof(double) * a_nullable_float_array_length), + a_nullable_float_array, + sizeof(double) * a_nullable_float_array_length)); + self->a_nullable_float_array_length = a_nullable_float_array_length; + } else { + self->a_nullable_float_array = nullptr; + self->a_nullable_float_array_length = 0; + } + if (a_nullable_enum != nullptr) { + self->a_nullable_enum = static_cast( + malloc(sizeof(CoreTestsPigeonTestAnEnum))); + *self->a_nullable_enum = *a_nullable_enum; + } else { + self->a_nullable_enum = nullptr; + } + if (another_nullable_enum != nullptr) { + self->another_nullable_enum = static_cast( + malloc(sizeof(CoreTestsPigeonTestAnotherEnum))); + *self->another_nullable_enum = *another_nullable_enum; + } else { + self->another_nullable_enum = nullptr; + } + if (a_nullable_string != nullptr) { + self->a_nullable_string = g_strdup(a_nullable_string); + } else { + self->a_nullable_string = nullptr; + } + if (a_nullable_object != nullptr) { + self->a_nullable_object = fl_value_ref(a_nullable_object); + } else { + self->a_nullable_object = nullptr; + } + if (all_nullable_types != nullptr) { + self->all_nullable_types = CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES( + g_object_ref(all_nullable_types)); + } else { + self->all_nullable_types = nullptr; + } + if (list != nullptr) { + self->list = fl_value_ref(list); + } else { + self->list = nullptr; + } + if (string_list != nullptr) { + self->string_list = fl_value_ref(string_list); + } else { + self->string_list = nullptr; + } + if (int_list != nullptr) { + self->int_list = fl_value_ref(int_list); + } else { + self->int_list = nullptr; + } + if (double_list != nullptr) { + self->double_list = fl_value_ref(double_list); + } else { + self->double_list = nullptr; + } + if (bool_list != nullptr) { + self->bool_list = fl_value_ref(bool_list); + } else { + self->bool_list = nullptr; + } + if (enum_list != nullptr) { + self->enum_list = fl_value_ref(enum_list); + } else { + self->enum_list = nullptr; + } + if (object_list != nullptr) { + self->object_list = fl_value_ref(object_list); + } else { + self->object_list = nullptr; + } + if (list_list != nullptr) { + self->list_list = fl_value_ref(list_list); + } else { + self->list_list = nullptr; + } + if (map_list != nullptr) { + self->map_list = fl_value_ref(map_list); + } else { + self->map_list = nullptr; + } + if (recursive_class_list != nullptr) { + self->recursive_class_list = fl_value_ref(recursive_class_list); + } else { + self->recursive_class_list = nullptr; + } + if (map != nullptr) { + self->map = fl_value_ref(map); + } else { + self->map = nullptr; + } + if (string_map != nullptr) { + self->string_map = fl_value_ref(string_map); + } else { + self->string_map = nullptr; + } + if (int_map != nullptr) { + self->int_map = fl_value_ref(int_map); + } else { + self->int_map = nullptr; + } + if (enum_map != nullptr) { + self->enum_map = fl_value_ref(enum_map); + } else { + self->enum_map = nullptr; + } + if (object_map != nullptr) { + self->object_map = fl_value_ref(object_map); + } else { + self->object_map = nullptr; + } + if (list_map != nullptr) { + self->list_map = fl_value_ref(list_map); + } else { + self->list_map = nullptr; + } + if (map_map != nullptr) { + self->map_map = fl_value_ref(map_map); + } else { + self->map_map = nullptr; + } + if (recursive_class_map != nullptr) { + self->recursive_class_map = fl_value_ref(recursive_class_map); + } else { + self->recursive_class_map = nullptr; + } + return self; +} + +gboolean* core_tests_pigeon_test_all_nullable_types_get_a_nullable_bool( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->a_nullable_bool; +} + +int64_t* core_tests_pigeon_test_all_nullable_types_get_a_nullable_int( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->a_nullable_int; +} + +int64_t* core_tests_pigeon_test_all_nullable_types_get_a_nullable_int64( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->a_nullable_int64; +} + +double* core_tests_pigeon_test_all_nullable_types_get_a_nullable_double( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->a_nullable_double; +} + +const uint8_t* +core_tests_pigeon_test_all_nullable_types_get_a_nullable_byte_array( + CoreTestsPigeonTestAllNullableTypes* self, size_t* length) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + *length = self->a_nullable_byte_array_length; + return self->a_nullable_byte_array; +} + +const int32_t* +core_tests_pigeon_test_all_nullable_types_get_a_nullable4_byte_array( + CoreTestsPigeonTestAllNullableTypes* self, size_t* length) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + *length = self->a_nullable4_byte_array_length; + return self->a_nullable4_byte_array; +} + +const int64_t* +core_tests_pigeon_test_all_nullable_types_get_a_nullable8_byte_array( + CoreTestsPigeonTestAllNullableTypes* self, size_t* length) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + *length = self->a_nullable8_byte_array_length; + return self->a_nullable8_byte_array; +} + +const double* +core_tests_pigeon_test_all_nullable_types_get_a_nullable_float_array( + CoreTestsPigeonTestAllNullableTypes* self, size_t* length) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + *length = self->a_nullable_float_array_length; + return self->a_nullable_float_array; +} + +CoreTestsPigeonTestAnEnum* +core_tests_pigeon_test_all_nullable_types_get_a_nullable_enum( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->a_nullable_enum; +} + +CoreTestsPigeonTestAnotherEnum* +core_tests_pigeon_test_all_nullable_types_get_another_nullable_enum( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->another_nullable_enum; +} + +const gchar* core_tests_pigeon_test_all_nullable_types_get_a_nullable_string( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->a_nullable_string; +} + +FlValue* core_tests_pigeon_test_all_nullable_types_get_a_nullable_object( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->a_nullable_object; +} + +CoreTestsPigeonTestAllNullableTypes* +core_tests_pigeon_test_all_nullable_types_get_all_nullable_types( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->all_nullable_types; +} + +FlValue* core_tests_pigeon_test_all_nullable_types_get_list( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->list; +} + +FlValue* core_tests_pigeon_test_all_nullable_types_get_string_list( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->string_list; +} + +FlValue* core_tests_pigeon_test_all_nullable_types_get_int_list( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->int_list; +} + +FlValue* core_tests_pigeon_test_all_nullable_types_get_double_list( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->double_list; +} + +FlValue* core_tests_pigeon_test_all_nullable_types_get_bool_list( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->bool_list; +} + +FlValue* core_tests_pigeon_test_all_nullable_types_get_enum_list( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->enum_list; +} + +FlValue* core_tests_pigeon_test_all_nullable_types_get_object_list( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->object_list; +} + +FlValue* core_tests_pigeon_test_all_nullable_types_get_list_list( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->list_list; +} + +FlValue* core_tests_pigeon_test_all_nullable_types_get_map_list( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->map_list; +} + +FlValue* core_tests_pigeon_test_all_nullable_types_get_recursive_class_list( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->recursive_class_list; +} + +FlValue* core_tests_pigeon_test_all_nullable_types_get_map( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->map; +} + +FlValue* core_tests_pigeon_test_all_nullable_types_get_string_map( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->string_map; +} + +FlValue* core_tests_pigeon_test_all_nullable_types_get_int_map( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->int_map; +} + +FlValue* core_tests_pigeon_test_all_nullable_types_get_enum_map( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->enum_map; +} + +FlValue* core_tests_pigeon_test_all_nullable_types_get_object_map( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->object_map; +} + +FlValue* core_tests_pigeon_test_all_nullable_types_get_list_map( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->list_map; +} + +FlValue* core_tests_pigeon_test_all_nullable_types_get_map_map( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->map_map; +} + +FlValue* core_tests_pigeon_test_all_nullable_types_get_recursive_class_map( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + nullptr); + return self->recursive_class_map; +} + +static FlValue* core_tests_pigeon_test_all_nullable_types_to_list( + CoreTestsPigeonTestAllNullableTypes* self) { + FlValue* values = fl_value_new_list(); + fl_value_append_take(values, self->a_nullable_bool != nullptr + ? fl_value_new_bool(*self->a_nullable_bool) + : fl_value_new_null()); + fl_value_append_take(values, self->a_nullable_int != nullptr + ? fl_value_new_int(*self->a_nullable_int) + : fl_value_new_null()); + fl_value_append_take(values, self->a_nullable_int64 != nullptr + ? fl_value_new_int(*self->a_nullable_int64) + : fl_value_new_null()); + fl_value_append_take(values, + self->a_nullable_double != nullptr + ? fl_value_new_float(*self->a_nullable_double) + : fl_value_new_null()); + fl_value_append_take( + values, self->a_nullable_byte_array != nullptr + ? fl_value_new_uint8_list(self->a_nullable_byte_array, + self->a_nullable_byte_array_length) + : fl_value_new_null()); + fl_value_append_take( + values, self->a_nullable4_byte_array != nullptr + ? fl_value_new_int32_list(self->a_nullable4_byte_array, + self->a_nullable4_byte_array_length) + : fl_value_new_null()); + fl_value_append_take( + values, self->a_nullable8_byte_array != nullptr + ? fl_value_new_int64_list(self->a_nullable8_byte_array, + self->a_nullable8_byte_array_length) + : fl_value_new_null()); + fl_value_append_take( + values, self->a_nullable_float_array != nullptr + ? fl_value_new_float_list(self->a_nullable_float_array, + self->a_nullable_float_array_length) + : fl_value_new_null()); + fl_value_append_take( + values, + self->a_nullable_enum != nullptr + ? fl_value_new_custom(129, fl_value_new_int(*self->a_nullable_enum), + (GDestroyNotify)fl_value_unref) + : fl_value_new_null()); + fl_value_append_take( + values, self->another_nullable_enum != nullptr + ? fl_value_new_custom( + 130, fl_value_new_int(*self->another_nullable_enum), + (GDestroyNotify)fl_value_unref) + : fl_value_new_null()); + fl_value_append_take(values, + self->a_nullable_string != nullptr + ? fl_value_new_string(self->a_nullable_string) + : fl_value_new_null()); + fl_value_append_take(values, self->a_nullable_object != nullptr + ? fl_value_ref(self->a_nullable_object) + : fl_value_new_null()); + fl_value_append_take( + values, + self->all_nullable_types != nullptr + ? fl_value_new_custom_object(133, G_OBJECT(self->all_nullable_types)) + : fl_value_new_null()); + fl_value_append_take(values, self->list != nullptr ? fl_value_ref(self->list) + : fl_value_new_null()); + fl_value_append_take(values, self->string_list != nullptr + ? fl_value_ref(self->string_list) + : fl_value_new_null()); + fl_value_append_take(values, self->int_list != nullptr + ? fl_value_ref(self->int_list) + : fl_value_new_null()); + fl_value_append_take(values, self->double_list != nullptr + ? fl_value_ref(self->double_list) + : fl_value_new_null()); + fl_value_append_take(values, self->bool_list != nullptr + ? fl_value_ref(self->bool_list) + : fl_value_new_null()); + fl_value_append_take(values, self->enum_list != nullptr + ? fl_value_ref(self->enum_list) + : fl_value_new_null()); + fl_value_append_take(values, self->object_list != nullptr + ? fl_value_ref(self->object_list) + : fl_value_new_null()); + fl_value_append_take(values, self->list_list != nullptr + ? fl_value_ref(self->list_list) + : fl_value_new_null()); + fl_value_append_take(values, self->map_list != nullptr + ? fl_value_ref(self->map_list) + : fl_value_new_null()); + fl_value_append_take(values, self->recursive_class_list != nullptr + ? fl_value_ref(self->recursive_class_list) + : fl_value_new_null()); + fl_value_append_take(values, self->map != nullptr ? fl_value_ref(self->map) + : fl_value_new_null()); + fl_value_append_take(values, self->string_map != nullptr + ? fl_value_ref(self->string_map) + : fl_value_new_null()); + fl_value_append_take(values, self->int_map != nullptr + ? fl_value_ref(self->int_map) + : fl_value_new_null()); + fl_value_append_take(values, self->enum_map != nullptr + ? fl_value_ref(self->enum_map) + : fl_value_new_null()); + fl_value_append_take(values, self->object_map != nullptr + ? fl_value_ref(self->object_map) + : fl_value_new_null()); + fl_value_append_take(values, self->list_map != nullptr + ? fl_value_ref(self->list_map) + : fl_value_new_null()); + fl_value_append_take(values, self->map_map != nullptr + ? fl_value_ref(self->map_map) + : fl_value_new_null()); + fl_value_append_take(values, self->recursive_class_map != nullptr + ? fl_value_ref(self->recursive_class_map) + : fl_value_new_null()); + return values; +} + +static CoreTestsPigeonTestAllNullableTypes* +core_tests_pigeon_test_all_nullable_types_new_from_list(FlValue* values) { + FlValue* value0 = fl_value_get_list_value(values, 0); + gboolean* a_nullable_bool = nullptr; + gboolean a_nullable_bool_value; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + a_nullable_bool_value = fl_value_get_bool(value0); + a_nullable_bool = &a_nullable_bool_value; + } + FlValue* value1 = fl_value_get_list_value(values, 1); + int64_t* a_nullable_int = nullptr; + int64_t a_nullable_int_value; + if (fl_value_get_type(value1) != FL_VALUE_TYPE_NULL) { + a_nullable_int_value = fl_value_get_int(value1); + a_nullable_int = &a_nullable_int_value; + } + FlValue* value2 = fl_value_get_list_value(values, 2); + int64_t* a_nullable_int64 = nullptr; + int64_t a_nullable_int64_value; + if (fl_value_get_type(value2) != FL_VALUE_TYPE_NULL) { + a_nullable_int64_value = fl_value_get_int(value2); + a_nullable_int64 = &a_nullable_int64_value; + } + FlValue* value3 = fl_value_get_list_value(values, 3); + double* a_nullable_double = nullptr; + double a_nullable_double_value; + if (fl_value_get_type(value3) != FL_VALUE_TYPE_NULL) { + a_nullable_double_value = fl_value_get_float(value3); + a_nullable_double = &a_nullable_double_value; + } + FlValue* value4 = fl_value_get_list_value(values, 4); + const uint8_t* a_nullable_byte_array = nullptr; + size_t a_nullable_byte_array_length = 0; + if (fl_value_get_type(value4) != FL_VALUE_TYPE_NULL) { + a_nullable_byte_array = fl_value_get_uint8_list(value4); + a_nullable_byte_array_length = fl_value_get_length(value4); + } + FlValue* value5 = fl_value_get_list_value(values, 5); + const int32_t* a_nullable4_byte_array = nullptr; + size_t a_nullable4_byte_array_length = 0; + if (fl_value_get_type(value5) != FL_VALUE_TYPE_NULL) { + a_nullable4_byte_array = fl_value_get_int32_list(value5); + a_nullable4_byte_array_length = fl_value_get_length(value5); + } + FlValue* value6 = fl_value_get_list_value(values, 6); + const int64_t* a_nullable8_byte_array = nullptr; + size_t a_nullable8_byte_array_length = 0; + if (fl_value_get_type(value6) != FL_VALUE_TYPE_NULL) { + a_nullable8_byte_array = fl_value_get_int64_list(value6); + a_nullable8_byte_array_length = fl_value_get_length(value6); + } + FlValue* value7 = fl_value_get_list_value(values, 7); + const double* a_nullable_float_array = nullptr; + size_t a_nullable_float_array_length = 0; + if (fl_value_get_type(value7) != FL_VALUE_TYPE_NULL) { + a_nullable_float_array = fl_value_get_float_list(value7); + a_nullable_float_array_length = fl_value_get_length(value7); + } + FlValue* value8 = fl_value_get_list_value(values, 8); + CoreTestsPigeonTestAnEnum* a_nullable_enum = nullptr; + CoreTestsPigeonTestAnEnum a_nullable_enum_value; + if (fl_value_get_type(value8) != FL_VALUE_TYPE_NULL) { + a_nullable_enum_value = static_cast( + fl_value_get_int(reinterpret_cast( + const_cast(fl_value_get_custom_value(value8))))); + a_nullable_enum = &a_nullable_enum_value; + } + FlValue* value9 = fl_value_get_list_value(values, 9); + CoreTestsPigeonTestAnotherEnum* another_nullable_enum = nullptr; + CoreTestsPigeonTestAnotherEnum another_nullable_enum_value; + if (fl_value_get_type(value9) != FL_VALUE_TYPE_NULL) { + another_nullable_enum_value = static_cast( + fl_value_get_int(reinterpret_cast( + const_cast(fl_value_get_custom_value(value9))))); + another_nullable_enum = &another_nullable_enum_value; + } + FlValue* value10 = fl_value_get_list_value(values, 10); + const gchar* a_nullable_string = nullptr; + if (fl_value_get_type(value10) != FL_VALUE_TYPE_NULL) { + a_nullable_string = fl_value_get_string(value10); + } + FlValue* value11 = fl_value_get_list_value(values, 11); + FlValue* a_nullable_object = nullptr; + if (fl_value_get_type(value11) != FL_VALUE_TYPE_NULL) { + a_nullable_object = value11; + } + FlValue* value12 = fl_value_get_list_value(values, 12); + CoreTestsPigeonTestAllNullableTypes* all_nullable_types = nullptr; + if (fl_value_get_type(value12) != FL_VALUE_TYPE_NULL) { + all_nullable_types = CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES( + fl_value_get_custom_value_object(value12)); + } + FlValue* value13 = fl_value_get_list_value(values, 13); + FlValue* list = nullptr; + if (fl_value_get_type(value13) != FL_VALUE_TYPE_NULL) { + list = value13; + } + FlValue* value14 = fl_value_get_list_value(values, 14); + FlValue* string_list = nullptr; + if (fl_value_get_type(value14) != FL_VALUE_TYPE_NULL) { + string_list = value14; + } + FlValue* value15 = fl_value_get_list_value(values, 15); + FlValue* int_list = nullptr; + if (fl_value_get_type(value15) != FL_VALUE_TYPE_NULL) { + int_list = value15; + } + FlValue* value16 = fl_value_get_list_value(values, 16); + FlValue* double_list = nullptr; + if (fl_value_get_type(value16) != FL_VALUE_TYPE_NULL) { + double_list = value16; + } + FlValue* value17 = fl_value_get_list_value(values, 17); + FlValue* bool_list = nullptr; + if (fl_value_get_type(value17) != FL_VALUE_TYPE_NULL) { + bool_list = value17; + } + FlValue* value18 = fl_value_get_list_value(values, 18); + FlValue* enum_list = nullptr; + if (fl_value_get_type(value18) != FL_VALUE_TYPE_NULL) { + enum_list = value18; + } + FlValue* value19 = fl_value_get_list_value(values, 19); + FlValue* object_list = nullptr; + if (fl_value_get_type(value19) != FL_VALUE_TYPE_NULL) { + object_list = value19; + } + FlValue* value20 = fl_value_get_list_value(values, 20); + FlValue* list_list = nullptr; + if (fl_value_get_type(value20) != FL_VALUE_TYPE_NULL) { + list_list = value20; + } + FlValue* value21 = fl_value_get_list_value(values, 21); + FlValue* map_list = nullptr; + if (fl_value_get_type(value21) != FL_VALUE_TYPE_NULL) { + map_list = value21; + } + FlValue* value22 = fl_value_get_list_value(values, 22); + FlValue* recursive_class_list = nullptr; + if (fl_value_get_type(value22) != FL_VALUE_TYPE_NULL) { + recursive_class_list = value22; + } + FlValue* value23 = fl_value_get_list_value(values, 23); + FlValue* map = nullptr; + if (fl_value_get_type(value23) != FL_VALUE_TYPE_NULL) { + map = value23; + } + FlValue* value24 = fl_value_get_list_value(values, 24); + FlValue* string_map = nullptr; + if (fl_value_get_type(value24) != FL_VALUE_TYPE_NULL) { + string_map = value24; + } + FlValue* value25 = fl_value_get_list_value(values, 25); + FlValue* int_map = nullptr; + if (fl_value_get_type(value25) != FL_VALUE_TYPE_NULL) { + int_map = value25; + } + FlValue* value26 = fl_value_get_list_value(values, 26); + FlValue* enum_map = nullptr; + if (fl_value_get_type(value26) != FL_VALUE_TYPE_NULL) { + enum_map = value26; + } + FlValue* value27 = fl_value_get_list_value(values, 27); + FlValue* object_map = nullptr; + if (fl_value_get_type(value27) != FL_VALUE_TYPE_NULL) { + object_map = value27; + } + FlValue* value28 = fl_value_get_list_value(values, 28); + FlValue* list_map = nullptr; + if (fl_value_get_type(value28) != FL_VALUE_TYPE_NULL) { + list_map = value28; + } + FlValue* value29 = fl_value_get_list_value(values, 29); + FlValue* map_map = nullptr; + if (fl_value_get_type(value29) != FL_VALUE_TYPE_NULL) { + map_map = value29; + } + FlValue* value30 = fl_value_get_list_value(values, 30); + FlValue* recursive_class_map = nullptr; + if (fl_value_get_type(value30) != FL_VALUE_TYPE_NULL) { + recursive_class_map = value30; + } + return core_tests_pigeon_test_all_nullable_types_new( + a_nullable_bool, a_nullable_int, a_nullable_int64, a_nullable_double, + a_nullable_byte_array, a_nullable_byte_array_length, + a_nullable4_byte_array, a_nullable4_byte_array_length, + a_nullable8_byte_array, a_nullable8_byte_array_length, + a_nullable_float_array, a_nullable_float_array_length, a_nullable_enum, + another_nullable_enum, a_nullable_string, a_nullable_object, + all_nullable_types, list, string_list, int_list, double_list, bool_list, + enum_list, object_list, list_list, map_list, recursive_class_list, map, + string_map, int_map, enum_map, object_map, list_map, map_map, + recursive_class_map); +} + +struct _CoreTestsPigeonTestAllNullableTypesWithoutRecursion { + GObject parent_instance; + + gboolean* a_nullable_bool; + int64_t* a_nullable_int; + int64_t* a_nullable_int64; + double* a_nullable_double; + uint8_t* a_nullable_byte_array; + size_t a_nullable_byte_array_length; + int32_t* a_nullable4_byte_array; + size_t a_nullable4_byte_array_length; + int64_t* a_nullable8_byte_array; + size_t a_nullable8_byte_array_length; + double* a_nullable_float_array; + size_t a_nullable_float_array_length; + CoreTestsPigeonTestAnEnum* a_nullable_enum; + CoreTestsPigeonTestAnotherEnum* another_nullable_enum; + gchar* a_nullable_string; + FlValue* a_nullable_object; + FlValue* list; + FlValue* string_list; + FlValue* int_list; + FlValue* double_list; + FlValue* bool_list; + FlValue* enum_list; + FlValue* object_list; + FlValue* list_list; + FlValue* map_list; + FlValue* map; + FlValue* string_map; + FlValue* int_map; + FlValue* enum_map; + FlValue* object_map; + FlValue* list_map; + FlValue* map_map; +}; + +G_DEFINE_TYPE(CoreTestsPigeonTestAllNullableTypesWithoutRecursion, + core_tests_pigeon_test_all_nullable_types_without_recursion, + G_TYPE_OBJECT) + +static void core_tests_pigeon_test_all_nullable_types_without_recursion_dispose( + GObject* object) { + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self = + CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(object); + g_clear_pointer(&self->a_nullable_bool, g_free); + g_clear_pointer(&self->a_nullable_int, g_free); + g_clear_pointer(&self->a_nullable_int64, g_free); + g_clear_pointer(&self->a_nullable_double, g_free); + g_clear_pointer(&self->a_nullable_enum, g_free); + g_clear_pointer(&self->another_nullable_enum, g_free); + g_clear_pointer(&self->a_nullable_string, g_free); + g_clear_pointer(&self->a_nullable_object, fl_value_unref); + g_clear_pointer(&self->list, fl_value_unref); + g_clear_pointer(&self->string_list, fl_value_unref); + g_clear_pointer(&self->int_list, fl_value_unref); + g_clear_pointer(&self->double_list, fl_value_unref); + g_clear_pointer(&self->bool_list, fl_value_unref); + g_clear_pointer(&self->enum_list, fl_value_unref); + g_clear_pointer(&self->object_list, fl_value_unref); + g_clear_pointer(&self->list_list, fl_value_unref); + g_clear_pointer(&self->map_list, fl_value_unref); + g_clear_pointer(&self->map, fl_value_unref); + g_clear_pointer(&self->string_map, fl_value_unref); + g_clear_pointer(&self->int_map, fl_value_unref); + g_clear_pointer(&self->enum_map, fl_value_unref); + g_clear_pointer(&self->object_map, fl_value_unref); + g_clear_pointer(&self->list_map, fl_value_unref); + g_clear_pointer(&self->map_map, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_all_nullable_types_without_recursion_parent_class) + ->dispose(object); +} + +static void core_tests_pigeon_test_all_nullable_types_without_recursion_init( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) {} + +static void +core_tests_pigeon_test_all_nullable_types_without_recursion_class_init( + CoreTestsPigeonTestAllNullableTypesWithoutRecursionClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_all_nullable_types_without_recursion_dispose; +} + +CoreTestsPigeonTestAllNullableTypesWithoutRecursion* +core_tests_pigeon_test_all_nullable_types_without_recursion_new( + gboolean* a_nullable_bool, int64_t* a_nullable_int, + int64_t* a_nullable_int64, double* a_nullable_double, + const uint8_t* a_nullable_byte_array, size_t a_nullable_byte_array_length, + const int32_t* a_nullable4_byte_array, size_t a_nullable4_byte_array_length, + const int64_t* a_nullable8_byte_array, size_t a_nullable8_byte_array_length, + const double* a_nullable_float_array, size_t a_nullable_float_array_length, + CoreTestsPigeonTestAnEnum* a_nullable_enum, + CoreTestsPigeonTestAnotherEnum* another_nullable_enum, + const gchar* a_nullable_string, FlValue* a_nullable_object, FlValue* list, + FlValue* string_list, FlValue* int_list, FlValue* double_list, + FlValue* bool_list, FlValue* enum_list, FlValue* object_list, + FlValue* list_list, FlValue* map_list, FlValue* map, FlValue* string_map, + FlValue* int_map, FlValue* enum_map, FlValue* object_map, FlValue* list_map, + FlValue* map_map) { + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self = + CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(g_object_new( + core_tests_pigeon_test_all_nullable_types_without_recursion_get_type(), + nullptr)); + if (a_nullable_bool != nullptr) { + self->a_nullable_bool = static_cast(malloc(sizeof(gboolean))); + *self->a_nullable_bool = *a_nullable_bool; + } else { + self->a_nullable_bool = nullptr; + } + if (a_nullable_int != nullptr) { + self->a_nullable_int = static_cast(malloc(sizeof(int64_t))); + *self->a_nullable_int = *a_nullable_int; + } else { + self->a_nullable_int = nullptr; + } + if (a_nullable_int64 != nullptr) { + self->a_nullable_int64 = static_cast(malloc(sizeof(int64_t))); + *self->a_nullable_int64 = *a_nullable_int64; + } else { + self->a_nullable_int64 = nullptr; + } + if (a_nullable_double != nullptr) { + self->a_nullable_double = static_cast(malloc(sizeof(double))); + *self->a_nullable_double = *a_nullable_double; + } else { + self->a_nullable_double = nullptr; + } + if (a_nullable_byte_array != nullptr) { + self->a_nullable_byte_array = static_cast( + memcpy(malloc(a_nullable_byte_array_length), a_nullable_byte_array, + a_nullable_byte_array_length)); + self->a_nullable_byte_array_length = a_nullable_byte_array_length; + } else { + self->a_nullable_byte_array = nullptr; + self->a_nullable_byte_array_length = 0; + } + if (a_nullable4_byte_array != nullptr) { + self->a_nullable4_byte_array = static_cast( + memcpy(malloc(sizeof(int32_t) * a_nullable4_byte_array_length), + a_nullable4_byte_array, + sizeof(int32_t) * a_nullable4_byte_array_length)); + self->a_nullable4_byte_array_length = a_nullable4_byte_array_length; + } else { + self->a_nullable4_byte_array = nullptr; + self->a_nullable4_byte_array_length = 0; + } + if (a_nullable8_byte_array != nullptr) { + self->a_nullable8_byte_array = static_cast( + memcpy(malloc(sizeof(int64_t) * a_nullable8_byte_array_length), + a_nullable8_byte_array, + sizeof(int64_t) * a_nullable8_byte_array_length)); + self->a_nullable8_byte_array_length = a_nullable8_byte_array_length; + } else { + self->a_nullable8_byte_array = nullptr; + self->a_nullable8_byte_array_length = 0; + } + if (a_nullable_float_array != nullptr) { + self->a_nullable_float_array = static_cast( + memcpy(malloc(sizeof(double) * a_nullable_float_array_length), + a_nullable_float_array, + sizeof(double) * a_nullable_float_array_length)); + self->a_nullable_float_array_length = a_nullable_float_array_length; + } else { + self->a_nullable_float_array = nullptr; + self->a_nullable_float_array_length = 0; + } + if (a_nullable_enum != nullptr) { + self->a_nullable_enum = static_cast( + malloc(sizeof(CoreTestsPigeonTestAnEnum))); + *self->a_nullable_enum = *a_nullable_enum; + } else { + self->a_nullable_enum = nullptr; + } + if (another_nullable_enum != nullptr) { + self->another_nullable_enum = static_cast( + malloc(sizeof(CoreTestsPigeonTestAnotherEnum))); + *self->another_nullable_enum = *another_nullable_enum; + } else { + self->another_nullable_enum = nullptr; + } + if (a_nullable_string != nullptr) { + self->a_nullable_string = g_strdup(a_nullable_string); + } else { + self->a_nullable_string = nullptr; + } + if (a_nullable_object != nullptr) { + self->a_nullable_object = fl_value_ref(a_nullable_object); + } else { + self->a_nullable_object = nullptr; + } + if (list != nullptr) { + self->list = fl_value_ref(list); + } else { + self->list = nullptr; + } + if (string_list != nullptr) { + self->string_list = fl_value_ref(string_list); + } else { + self->string_list = nullptr; + } + if (int_list != nullptr) { + self->int_list = fl_value_ref(int_list); + } else { + self->int_list = nullptr; + } + if (double_list != nullptr) { + self->double_list = fl_value_ref(double_list); + } else { + self->double_list = nullptr; + } + if (bool_list != nullptr) { + self->bool_list = fl_value_ref(bool_list); + } else { + self->bool_list = nullptr; + } + if (enum_list != nullptr) { + self->enum_list = fl_value_ref(enum_list); + } else { + self->enum_list = nullptr; + } + if (object_list != nullptr) { + self->object_list = fl_value_ref(object_list); + } else { + self->object_list = nullptr; + } + if (list_list != nullptr) { + self->list_list = fl_value_ref(list_list); + } else { + self->list_list = nullptr; + } + if (map_list != nullptr) { + self->map_list = fl_value_ref(map_list); + } else { + self->map_list = nullptr; + } + if (map != nullptr) { + self->map = fl_value_ref(map); + } else { + self->map = nullptr; + } + if (string_map != nullptr) { + self->string_map = fl_value_ref(string_map); + } else { + self->string_map = nullptr; + } + if (int_map != nullptr) { + self->int_map = fl_value_ref(int_map); + } else { + self->int_map = nullptr; + } + if (enum_map != nullptr) { + self->enum_map = fl_value_ref(enum_map); + } else { + self->enum_map = nullptr; + } + if (object_map != nullptr) { + self->object_map = fl_value_ref(object_map); + } else { + self->object_map = nullptr; + } + if (list_map != nullptr) { + self->list_map = fl_value_ref(list_map); + } else { + self->list_map = nullptr; + } + if (map_map != nullptr) { + self->map_map = fl_value_ref(map_map); + } else { + self->map_map = nullptr; + } + return self; +} + +gboolean* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_bool( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + return self->a_nullable_bool; +} + +int64_t* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_int( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + return self->a_nullable_int; +} + +int64_t* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_int64( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + return self->a_nullable_int64; +} + +double* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_double( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + return self->a_nullable_double; +} + +const uint8_t* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_byte_array( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self, size_t* length) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + *length = self->a_nullable_byte_array_length; + return self->a_nullable_byte_array; +} + +const int32_t* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable4_byte_array( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self, size_t* length) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + *length = self->a_nullable4_byte_array_length; + return self->a_nullable4_byte_array; +} + +const int64_t* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable8_byte_array( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self, size_t* length) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + *length = self->a_nullable8_byte_array_length; + return self->a_nullable8_byte_array; +} + +const double* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_float_array( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self, size_t* length) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + *length = self->a_nullable_float_array_length; + return self->a_nullable_float_array; +} + +CoreTestsPigeonTestAnEnum* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_enum( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + return self->a_nullable_enum; +} + +CoreTestsPigeonTestAnotherEnum* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_another_nullable_enum( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + return self->another_nullable_enum; +} + +const gchar* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_string( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + return self->a_nullable_string; +} + +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_object( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + return self->a_nullable_object; +} + +FlValue* core_tests_pigeon_test_all_nullable_types_without_recursion_get_list( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + return self->list; +} + +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_string_list( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + return self->string_list; +} + +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_int_list( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + return self->int_list; +} + +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_double_list( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + return self->double_list; +} + +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_bool_list( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + return self->bool_list; +} + +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_enum_list( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + return self->enum_list; +} + +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_object_list( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + return self->object_list; +} + +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_list_list( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + return self->list_list; +} + +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_map_list( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + return self->map_list; +} + +FlValue* core_tests_pigeon_test_all_nullable_types_without_recursion_get_map( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + return self->map; +} + +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_string_map( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + return self->string_map; +} + +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_int_map( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + return self->int_map; +} + +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_enum_map( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + return self->enum_map; +} + +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_object_map( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + return self->object_map; +} + +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_list_map( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + return self->list_map; +} + +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_map_map( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + nullptr); + return self->map_map; +} + +static FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_to_list( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + FlValue* values = fl_value_new_list(); + fl_value_append_take(values, self->a_nullable_bool != nullptr + ? fl_value_new_bool(*self->a_nullable_bool) + : fl_value_new_null()); + fl_value_append_take(values, self->a_nullable_int != nullptr + ? fl_value_new_int(*self->a_nullable_int) + : fl_value_new_null()); + fl_value_append_take(values, self->a_nullable_int64 != nullptr + ? fl_value_new_int(*self->a_nullable_int64) + : fl_value_new_null()); + fl_value_append_take(values, + self->a_nullable_double != nullptr + ? fl_value_new_float(*self->a_nullable_double) + : fl_value_new_null()); + fl_value_append_take( + values, self->a_nullable_byte_array != nullptr + ? fl_value_new_uint8_list(self->a_nullable_byte_array, + self->a_nullable_byte_array_length) + : fl_value_new_null()); + fl_value_append_take( + values, self->a_nullable4_byte_array != nullptr + ? fl_value_new_int32_list(self->a_nullable4_byte_array, + self->a_nullable4_byte_array_length) + : fl_value_new_null()); + fl_value_append_take( + values, self->a_nullable8_byte_array != nullptr + ? fl_value_new_int64_list(self->a_nullable8_byte_array, + self->a_nullable8_byte_array_length) + : fl_value_new_null()); + fl_value_append_take( + values, self->a_nullable_float_array != nullptr + ? fl_value_new_float_list(self->a_nullable_float_array, + self->a_nullable_float_array_length) + : fl_value_new_null()); + fl_value_append_take( + values, + self->a_nullable_enum != nullptr + ? fl_value_new_custom(129, fl_value_new_int(*self->a_nullable_enum), + (GDestroyNotify)fl_value_unref) + : fl_value_new_null()); + fl_value_append_take( + values, self->another_nullable_enum != nullptr + ? fl_value_new_custom( + 130, fl_value_new_int(*self->another_nullable_enum), + (GDestroyNotify)fl_value_unref) + : fl_value_new_null()); + fl_value_append_take(values, + self->a_nullable_string != nullptr + ? fl_value_new_string(self->a_nullable_string) + : fl_value_new_null()); + fl_value_append_take(values, self->a_nullable_object != nullptr + ? fl_value_ref(self->a_nullable_object) + : fl_value_new_null()); + fl_value_append_take(values, self->list != nullptr ? fl_value_ref(self->list) + : fl_value_new_null()); + fl_value_append_take(values, self->string_list != nullptr + ? fl_value_ref(self->string_list) + : fl_value_new_null()); + fl_value_append_take(values, self->int_list != nullptr + ? fl_value_ref(self->int_list) + : fl_value_new_null()); + fl_value_append_take(values, self->double_list != nullptr + ? fl_value_ref(self->double_list) + : fl_value_new_null()); + fl_value_append_take(values, self->bool_list != nullptr + ? fl_value_ref(self->bool_list) + : fl_value_new_null()); + fl_value_append_take(values, self->enum_list != nullptr + ? fl_value_ref(self->enum_list) + : fl_value_new_null()); + fl_value_append_take(values, self->object_list != nullptr + ? fl_value_ref(self->object_list) + : fl_value_new_null()); + fl_value_append_take(values, self->list_list != nullptr + ? fl_value_ref(self->list_list) + : fl_value_new_null()); + fl_value_append_take(values, self->map_list != nullptr + ? fl_value_ref(self->map_list) + : fl_value_new_null()); + fl_value_append_take(values, self->map != nullptr ? fl_value_ref(self->map) + : fl_value_new_null()); + fl_value_append_take(values, self->string_map != nullptr + ? fl_value_ref(self->string_map) + : fl_value_new_null()); + fl_value_append_take(values, self->int_map != nullptr + ? fl_value_ref(self->int_map) + : fl_value_new_null()); + fl_value_append_take(values, self->enum_map != nullptr + ? fl_value_ref(self->enum_map) + : fl_value_new_null()); + fl_value_append_take(values, self->object_map != nullptr + ? fl_value_ref(self->object_map) + : fl_value_new_null()); + fl_value_append_take(values, self->list_map != nullptr + ? fl_value_ref(self->list_map) + : fl_value_new_null()); + fl_value_append_take(values, self->map_map != nullptr + ? fl_value_ref(self->map_map) + : fl_value_new_null()); + return values; +} + +static CoreTestsPigeonTestAllNullableTypesWithoutRecursion* +core_tests_pigeon_test_all_nullable_types_without_recursion_new_from_list( + FlValue* values) { + FlValue* value0 = fl_value_get_list_value(values, 0); + gboolean* a_nullable_bool = nullptr; + gboolean a_nullable_bool_value; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + a_nullable_bool_value = fl_value_get_bool(value0); + a_nullable_bool = &a_nullable_bool_value; + } + FlValue* value1 = fl_value_get_list_value(values, 1); + int64_t* a_nullable_int = nullptr; + int64_t a_nullable_int_value; + if (fl_value_get_type(value1) != FL_VALUE_TYPE_NULL) { + a_nullable_int_value = fl_value_get_int(value1); + a_nullable_int = &a_nullable_int_value; + } + FlValue* value2 = fl_value_get_list_value(values, 2); + int64_t* a_nullable_int64 = nullptr; + int64_t a_nullable_int64_value; + if (fl_value_get_type(value2) != FL_VALUE_TYPE_NULL) { + a_nullable_int64_value = fl_value_get_int(value2); + a_nullable_int64 = &a_nullable_int64_value; + } + FlValue* value3 = fl_value_get_list_value(values, 3); + double* a_nullable_double = nullptr; + double a_nullable_double_value; + if (fl_value_get_type(value3) != FL_VALUE_TYPE_NULL) { + a_nullable_double_value = fl_value_get_float(value3); + a_nullable_double = &a_nullable_double_value; + } + FlValue* value4 = fl_value_get_list_value(values, 4); + const uint8_t* a_nullable_byte_array = nullptr; + size_t a_nullable_byte_array_length = 0; + if (fl_value_get_type(value4) != FL_VALUE_TYPE_NULL) { + a_nullable_byte_array = fl_value_get_uint8_list(value4); + a_nullable_byte_array_length = fl_value_get_length(value4); + } + FlValue* value5 = fl_value_get_list_value(values, 5); + const int32_t* a_nullable4_byte_array = nullptr; + size_t a_nullable4_byte_array_length = 0; + if (fl_value_get_type(value5) != FL_VALUE_TYPE_NULL) { + a_nullable4_byte_array = fl_value_get_int32_list(value5); + a_nullable4_byte_array_length = fl_value_get_length(value5); + } + FlValue* value6 = fl_value_get_list_value(values, 6); + const int64_t* a_nullable8_byte_array = nullptr; + size_t a_nullable8_byte_array_length = 0; + if (fl_value_get_type(value6) != FL_VALUE_TYPE_NULL) { + a_nullable8_byte_array = fl_value_get_int64_list(value6); + a_nullable8_byte_array_length = fl_value_get_length(value6); + } + FlValue* value7 = fl_value_get_list_value(values, 7); + const double* a_nullable_float_array = nullptr; + size_t a_nullable_float_array_length = 0; + if (fl_value_get_type(value7) != FL_VALUE_TYPE_NULL) { + a_nullable_float_array = fl_value_get_float_list(value7); + a_nullable_float_array_length = fl_value_get_length(value7); + } + FlValue* value8 = fl_value_get_list_value(values, 8); + CoreTestsPigeonTestAnEnum* a_nullable_enum = nullptr; + CoreTestsPigeonTestAnEnum a_nullable_enum_value; + if (fl_value_get_type(value8) != FL_VALUE_TYPE_NULL) { + a_nullable_enum_value = static_cast( + fl_value_get_int(reinterpret_cast( + const_cast(fl_value_get_custom_value(value8))))); + a_nullable_enum = &a_nullable_enum_value; + } + FlValue* value9 = fl_value_get_list_value(values, 9); + CoreTestsPigeonTestAnotherEnum* another_nullable_enum = nullptr; + CoreTestsPigeonTestAnotherEnum another_nullable_enum_value; + if (fl_value_get_type(value9) != FL_VALUE_TYPE_NULL) { + another_nullable_enum_value = static_cast( + fl_value_get_int(reinterpret_cast( + const_cast(fl_value_get_custom_value(value9))))); + another_nullable_enum = &another_nullable_enum_value; + } + FlValue* value10 = fl_value_get_list_value(values, 10); + const gchar* a_nullable_string = nullptr; + if (fl_value_get_type(value10) != FL_VALUE_TYPE_NULL) { + a_nullable_string = fl_value_get_string(value10); + } + FlValue* value11 = fl_value_get_list_value(values, 11); + FlValue* a_nullable_object = nullptr; + if (fl_value_get_type(value11) != FL_VALUE_TYPE_NULL) { + a_nullable_object = value11; + } + FlValue* value12 = fl_value_get_list_value(values, 12); + FlValue* list = nullptr; + if (fl_value_get_type(value12) != FL_VALUE_TYPE_NULL) { + list = value12; + } + FlValue* value13 = fl_value_get_list_value(values, 13); + FlValue* string_list = nullptr; + if (fl_value_get_type(value13) != FL_VALUE_TYPE_NULL) { + string_list = value13; + } + FlValue* value14 = fl_value_get_list_value(values, 14); + FlValue* int_list = nullptr; + if (fl_value_get_type(value14) != FL_VALUE_TYPE_NULL) { + int_list = value14; + } + FlValue* value15 = fl_value_get_list_value(values, 15); + FlValue* double_list = nullptr; + if (fl_value_get_type(value15) != FL_VALUE_TYPE_NULL) { + double_list = value15; + } + FlValue* value16 = fl_value_get_list_value(values, 16); + FlValue* bool_list = nullptr; + if (fl_value_get_type(value16) != FL_VALUE_TYPE_NULL) { + bool_list = value16; + } + FlValue* value17 = fl_value_get_list_value(values, 17); + FlValue* enum_list = nullptr; + if (fl_value_get_type(value17) != FL_VALUE_TYPE_NULL) { + enum_list = value17; + } + FlValue* value18 = fl_value_get_list_value(values, 18); + FlValue* object_list = nullptr; + if (fl_value_get_type(value18) != FL_VALUE_TYPE_NULL) { + object_list = value18; + } + FlValue* value19 = fl_value_get_list_value(values, 19); + FlValue* list_list = nullptr; + if (fl_value_get_type(value19) != FL_VALUE_TYPE_NULL) { + list_list = value19; + } + FlValue* value20 = fl_value_get_list_value(values, 20); + FlValue* map_list = nullptr; + if (fl_value_get_type(value20) != FL_VALUE_TYPE_NULL) { + map_list = value20; + } + FlValue* value21 = fl_value_get_list_value(values, 21); + FlValue* map = nullptr; + if (fl_value_get_type(value21) != FL_VALUE_TYPE_NULL) { + map = value21; + } + FlValue* value22 = fl_value_get_list_value(values, 22); + FlValue* string_map = nullptr; + if (fl_value_get_type(value22) != FL_VALUE_TYPE_NULL) { + string_map = value22; + } + FlValue* value23 = fl_value_get_list_value(values, 23); + FlValue* int_map = nullptr; + if (fl_value_get_type(value23) != FL_VALUE_TYPE_NULL) { + int_map = value23; + } + FlValue* value24 = fl_value_get_list_value(values, 24); + FlValue* enum_map = nullptr; + if (fl_value_get_type(value24) != FL_VALUE_TYPE_NULL) { + enum_map = value24; + } + FlValue* value25 = fl_value_get_list_value(values, 25); + FlValue* object_map = nullptr; + if (fl_value_get_type(value25) != FL_VALUE_TYPE_NULL) { + object_map = value25; + } + FlValue* value26 = fl_value_get_list_value(values, 26); + FlValue* list_map = nullptr; + if (fl_value_get_type(value26) != FL_VALUE_TYPE_NULL) { + list_map = value26; + } + FlValue* value27 = fl_value_get_list_value(values, 27); + FlValue* map_map = nullptr; + if (fl_value_get_type(value27) != FL_VALUE_TYPE_NULL) { + map_map = value27; + } + return core_tests_pigeon_test_all_nullable_types_without_recursion_new( + a_nullable_bool, a_nullable_int, a_nullable_int64, a_nullable_double, + a_nullable_byte_array, a_nullable_byte_array_length, + a_nullable4_byte_array, a_nullable4_byte_array_length, + a_nullable8_byte_array, a_nullable8_byte_array_length, + a_nullable_float_array, a_nullable_float_array_length, a_nullable_enum, + another_nullable_enum, a_nullable_string, a_nullable_object, list, + string_list, int_list, double_list, bool_list, enum_list, object_list, + list_list, map_list, map, string_map, int_map, enum_map, object_map, + list_map, map_map); +} + +struct _CoreTestsPigeonTestAllClassesWrapper { + GObject parent_instance; + + CoreTestsPigeonTestAllNullableTypes* all_nullable_types; + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* + all_nullable_types_without_recursion; + CoreTestsPigeonTestAllTypes* all_types; + FlValue* class_list; + FlValue* nullable_class_list; + FlValue* class_map; + FlValue* nullable_class_map; +}; + +G_DEFINE_TYPE(CoreTestsPigeonTestAllClassesWrapper, + core_tests_pigeon_test_all_classes_wrapper, G_TYPE_OBJECT) + +static void core_tests_pigeon_test_all_classes_wrapper_dispose( + GObject* object) { + CoreTestsPigeonTestAllClassesWrapper* self = + CORE_TESTS_PIGEON_TEST_ALL_CLASSES_WRAPPER(object); + g_clear_object(&self->all_nullable_types); + g_clear_object(&self->all_nullable_types_without_recursion); + g_clear_object(&self->all_types); + g_clear_pointer(&self->class_list, fl_value_unref); + g_clear_pointer(&self->nullable_class_list, fl_value_unref); + g_clear_pointer(&self->class_map, fl_value_unref); + g_clear_pointer(&self->nullable_class_map, fl_value_unref); + G_OBJECT_CLASS(core_tests_pigeon_test_all_classes_wrapper_parent_class) + ->dispose(object); +} + +static void core_tests_pigeon_test_all_classes_wrapper_init( + CoreTestsPigeonTestAllClassesWrapper* self) {} + +static void core_tests_pigeon_test_all_classes_wrapper_class_init( + CoreTestsPigeonTestAllClassesWrapperClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_all_classes_wrapper_dispose; +} + +CoreTestsPigeonTestAllClassesWrapper* +core_tests_pigeon_test_all_classes_wrapper_new( + CoreTestsPigeonTestAllNullableTypes* all_nullable_types, + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* + all_nullable_types_without_recursion, + CoreTestsPigeonTestAllTypes* all_types, FlValue* class_list, + FlValue* nullable_class_list, FlValue* class_map, + FlValue* nullable_class_map) { + CoreTestsPigeonTestAllClassesWrapper* self = + CORE_TESTS_PIGEON_TEST_ALL_CLASSES_WRAPPER(g_object_new( + core_tests_pigeon_test_all_classes_wrapper_get_type(), nullptr)); + self->all_nullable_types = CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES( + g_object_ref(all_nullable_types)); + if (all_nullable_types_without_recursion != nullptr) { + self->all_nullable_types_without_recursion = + CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES_WITHOUT_RECURSION( + g_object_ref(all_nullable_types_without_recursion)); + } else { + self->all_nullable_types_without_recursion = nullptr; + } + if (all_types != nullptr) { + self->all_types = CORE_TESTS_PIGEON_TEST_ALL_TYPES(g_object_ref(all_types)); + } else { + self->all_types = nullptr; + } + self->class_list = fl_value_ref(class_list); + if (nullable_class_list != nullptr) { + self->nullable_class_list = fl_value_ref(nullable_class_list); + } else { + self->nullable_class_list = nullptr; + } + self->class_map = fl_value_ref(class_map); + if (nullable_class_map != nullptr) { + self->nullable_class_map = fl_value_ref(nullable_class_map); + } else { + self->nullable_class_map = nullptr; + } + return self; +} + +CoreTestsPigeonTestAllNullableTypes* +core_tests_pigeon_test_all_classes_wrapper_get_all_nullable_types( + CoreTestsPigeonTestAllClassesWrapper* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_CLASSES_WRAPPER(self), + nullptr); + return self->all_nullable_types; +} + +CoreTestsPigeonTestAllNullableTypesWithoutRecursion* +core_tests_pigeon_test_all_classes_wrapper_get_all_nullable_types_without_recursion( + CoreTestsPigeonTestAllClassesWrapper* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_CLASSES_WRAPPER(self), + nullptr); + return self->all_nullable_types_without_recursion; +} + +CoreTestsPigeonTestAllTypes* +core_tests_pigeon_test_all_classes_wrapper_get_all_types( + CoreTestsPigeonTestAllClassesWrapper* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_CLASSES_WRAPPER(self), + nullptr); + return self->all_types; +} + +FlValue* core_tests_pigeon_test_all_classes_wrapper_get_class_list( + CoreTestsPigeonTestAllClassesWrapper* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_CLASSES_WRAPPER(self), + nullptr); + return self->class_list; +} + +FlValue* core_tests_pigeon_test_all_classes_wrapper_get_nullable_class_list( + CoreTestsPigeonTestAllClassesWrapper* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_CLASSES_WRAPPER(self), + nullptr); + return self->nullable_class_list; +} + +FlValue* core_tests_pigeon_test_all_classes_wrapper_get_class_map( + CoreTestsPigeonTestAllClassesWrapper* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_CLASSES_WRAPPER(self), + nullptr); + return self->class_map; +} + +FlValue* core_tests_pigeon_test_all_classes_wrapper_get_nullable_class_map( + CoreTestsPigeonTestAllClassesWrapper* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_CLASSES_WRAPPER(self), + nullptr); + return self->nullable_class_map; +} + +static FlValue* core_tests_pigeon_test_all_classes_wrapper_to_list( + CoreTestsPigeonTestAllClassesWrapper* self) { + FlValue* values = fl_value_new_list(); + fl_value_append_take(values, fl_value_new_custom_object( + 133, G_OBJECT(self->all_nullable_types))); + fl_value_append_take( + values, + self->all_nullable_types_without_recursion != nullptr + ? fl_value_new_custom_object( + 134, G_OBJECT(self->all_nullable_types_without_recursion)) + : fl_value_new_null()); + fl_value_append_take( + values, self->all_types != nullptr + ? fl_value_new_custom_object(132, G_OBJECT(self->all_types)) + : fl_value_new_null()); + fl_value_append_take(values, fl_value_ref(self->class_list)); + fl_value_append_take(values, self->nullable_class_list != nullptr + ? fl_value_ref(self->nullable_class_list) + : fl_value_new_null()); + fl_value_append_take(values, fl_value_ref(self->class_map)); + fl_value_append_take(values, self->nullable_class_map != nullptr + ? fl_value_ref(self->nullable_class_map) + : fl_value_new_null()); + return values; +} + +static CoreTestsPigeonTestAllClassesWrapper* +core_tests_pigeon_test_all_classes_wrapper_new_from_list(FlValue* values) { + FlValue* value0 = fl_value_get_list_value(values, 0); + CoreTestsPigeonTestAllNullableTypes* all_nullable_types = + CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES( + fl_value_get_custom_value_object(value0)); + FlValue* value1 = fl_value_get_list_value(values, 1); + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* + all_nullable_types_without_recursion = nullptr; + if (fl_value_get_type(value1) != FL_VALUE_TYPE_NULL) { + all_nullable_types_without_recursion = + CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES_WITHOUT_RECURSION( + fl_value_get_custom_value_object(value1)); + } + FlValue* value2 = fl_value_get_list_value(values, 2); + CoreTestsPigeonTestAllTypes* all_types = nullptr; + if (fl_value_get_type(value2) != FL_VALUE_TYPE_NULL) { + all_types = CORE_TESTS_PIGEON_TEST_ALL_TYPES( + fl_value_get_custom_value_object(value2)); + } + FlValue* value3 = fl_value_get_list_value(values, 3); + FlValue* class_list = value3; + FlValue* value4 = fl_value_get_list_value(values, 4); + FlValue* nullable_class_list = nullptr; + if (fl_value_get_type(value4) != FL_VALUE_TYPE_NULL) { + nullable_class_list = value4; + } + FlValue* value5 = fl_value_get_list_value(values, 5); + FlValue* class_map = value5; + FlValue* value6 = fl_value_get_list_value(values, 6); + FlValue* nullable_class_map = nullptr; + if (fl_value_get_type(value6) != FL_VALUE_TYPE_NULL) { + nullable_class_map = value6; + } + return core_tests_pigeon_test_all_classes_wrapper_new( + all_nullable_types, all_nullable_types_without_recursion, all_types, + class_list, nullable_class_list, class_map, nullable_class_map); +} + +struct _CoreTestsPigeonTestTestMessage { + GObject parent_instance; + + FlValue* test_list; +}; + +G_DEFINE_TYPE(CoreTestsPigeonTestTestMessage, + core_tests_pigeon_test_test_message, G_TYPE_OBJECT) + +static void core_tests_pigeon_test_test_message_dispose(GObject* object) { + CoreTestsPigeonTestTestMessage* self = + CORE_TESTS_PIGEON_TEST_TEST_MESSAGE(object); + g_clear_pointer(&self->test_list, fl_value_unref); + G_OBJECT_CLASS(core_tests_pigeon_test_test_message_parent_class) + ->dispose(object); +} + +static void core_tests_pigeon_test_test_message_init( + CoreTestsPigeonTestTestMessage* self) {} + +static void core_tests_pigeon_test_test_message_class_init( + CoreTestsPigeonTestTestMessageClass* klass) { + G_OBJECT_CLASS(klass)->dispose = core_tests_pigeon_test_test_message_dispose; +} + +CoreTestsPigeonTestTestMessage* core_tests_pigeon_test_test_message_new( + FlValue* test_list) { + CoreTestsPigeonTestTestMessage* self = CORE_TESTS_PIGEON_TEST_TEST_MESSAGE( + g_object_new(core_tests_pigeon_test_test_message_get_type(), nullptr)); + if (test_list != nullptr) { + self->test_list = fl_value_ref(test_list); + } else { + self->test_list = nullptr; + } + return self; +} + +FlValue* core_tests_pigeon_test_test_message_get_test_list( + CoreTestsPigeonTestTestMessage* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_TEST_MESSAGE(self), nullptr); + return self->test_list; +} + +static FlValue* core_tests_pigeon_test_test_message_to_list( + CoreTestsPigeonTestTestMessage* self) { + FlValue* values = fl_value_new_list(); + fl_value_append_take(values, self->test_list != nullptr + ? fl_value_ref(self->test_list) + : fl_value_new_null()); + return values; +} + +static CoreTestsPigeonTestTestMessage* +core_tests_pigeon_test_test_message_new_from_list(FlValue* values) { + FlValue* value0 = fl_value_get_list_value(values, 0); + FlValue* test_list = nullptr; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + test_list = value0; + } + return core_tests_pigeon_test_test_message_new(test_list); +} + +G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestMessageCodec, + core_tests_pigeon_test_message_codec, + CORE_TESTS_PIGEON_TEST, MESSAGE_CODEC, + FlStandardMessageCodec) + +struct _CoreTestsPigeonTestMessageCodec { + FlStandardMessageCodec parent_instance; +}; + +G_DEFINE_TYPE(CoreTestsPigeonTestMessageCodec, + core_tests_pigeon_test_message_codec, + fl_standard_message_codec_get_type()) + +static gboolean +core_tests_pigeon_test_message_codec_write_core_tests_pigeon_test_an_enum( + FlStandardMessageCodec* codec, GByteArray* buffer, FlValue* value, + GError** error) { + uint8_t type = 129; + g_byte_array_append(buffer, &type, sizeof(uint8_t)); + return fl_standard_message_codec_write_value(codec, buffer, value, error); +} + +static gboolean +core_tests_pigeon_test_message_codec_write_core_tests_pigeon_test_another_enum( + FlStandardMessageCodec* codec, GByteArray* buffer, FlValue* value, + GError** error) { + uint8_t type = 130; + g_byte_array_append(buffer, &type, sizeof(uint8_t)); + return fl_standard_message_codec_write_value(codec, buffer, value, error); +} + +static gboolean +core_tests_pigeon_test_message_codec_write_core_tests_pigeon_test_unused_class( + FlStandardMessageCodec* codec, GByteArray* buffer, + CoreTestsPigeonTestUnusedClass* value, GError** error) { + uint8_t type = 131; + g_byte_array_append(buffer, &type, sizeof(uint8_t)); + g_autoptr(FlValue) values = + core_tests_pigeon_test_unused_class_to_list(value); + return fl_standard_message_codec_write_value(codec, buffer, values, error); +} + +static gboolean +core_tests_pigeon_test_message_codec_write_core_tests_pigeon_test_all_types( + FlStandardMessageCodec* codec, GByteArray* buffer, + CoreTestsPigeonTestAllTypes* value, GError** error) { + uint8_t type = 132; + g_byte_array_append(buffer, &type, sizeof(uint8_t)); + g_autoptr(FlValue) values = core_tests_pigeon_test_all_types_to_list(value); + return fl_standard_message_codec_write_value(codec, buffer, values, error); +} + +static gboolean +core_tests_pigeon_test_message_codec_write_core_tests_pigeon_test_all_nullable_types( + FlStandardMessageCodec* codec, GByteArray* buffer, + CoreTestsPigeonTestAllNullableTypes* value, GError** error) { + uint8_t type = 133; + g_byte_array_append(buffer, &type, sizeof(uint8_t)); + g_autoptr(FlValue) values = + core_tests_pigeon_test_all_nullable_types_to_list(value); + return fl_standard_message_codec_write_value(codec, buffer, values, error); +} + +static gboolean +core_tests_pigeon_test_message_codec_write_core_tests_pigeon_test_all_nullable_types_without_recursion( + FlStandardMessageCodec* codec, GByteArray* buffer, + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* value, + GError** error) { + uint8_t type = 134; + g_byte_array_append(buffer, &type, sizeof(uint8_t)); + g_autoptr(FlValue) values = + core_tests_pigeon_test_all_nullable_types_without_recursion_to_list( + value); + return fl_standard_message_codec_write_value(codec, buffer, values, error); +} + +static gboolean +core_tests_pigeon_test_message_codec_write_core_tests_pigeon_test_all_classes_wrapper( + FlStandardMessageCodec* codec, GByteArray* buffer, + CoreTestsPigeonTestAllClassesWrapper* value, GError** error) { + uint8_t type = 135; + g_byte_array_append(buffer, &type, sizeof(uint8_t)); + g_autoptr(FlValue) values = + core_tests_pigeon_test_all_classes_wrapper_to_list(value); + return fl_standard_message_codec_write_value(codec, buffer, values, error); +} + +static gboolean +core_tests_pigeon_test_message_codec_write_core_tests_pigeon_test_test_message( + FlStandardMessageCodec* codec, GByteArray* buffer, + CoreTestsPigeonTestTestMessage* value, GError** error) { + uint8_t type = 136; + g_byte_array_append(buffer, &type, sizeof(uint8_t)); + g_autoptr(FlValue) values = + core_tests_pigeon_test_test_message_to_list(value); + return fl_standard_message_codec_write_value(codec, buffer, values, error); +} + +static gboolean core_tests_pigeon_test_message_codec_write_value( + FlStandardMessageCodec* codec, GByteArray* buffer, FlValue* value, + GError** error) { + if (fl_value_get_type(value) == FL_VALUE_TYPE_CUSTOM) { + switch (fl_value_get_custom_type(value)) { + case 129: + return core_tests_pigeon_test_message_codec_write_core_tests_pigeon_test_an_enum( + codec, buffer, + reinterpret_cast( + const_cast(fl_value_get_custom_value(value))), + error); + case 130: + return core_tests_pigeon_test_message_codec_write_core_tests_pigeon_test_another_enum( + codec, buffer, + reinterpret_cast( + const_cast(fl_value_get_custom_value(value))), + error); + case 131: + return core_tests_pigeon_test_message_codec_write_core_tests_pigeon_test_unused_class( + codec, buffer, + CORE_TESTS_PIGEON_TEST_UNUSED_CLASS( + fl_value_get_custom_value_object(value)), + error); + case 132: + return core_tests_pigeon_test_message_codec_write_core_tests_pigeon_test_all_types( + codec, buffer, + CORE_TESTS_PIGEON_TEST_ALL_TYPES( + fl_value_get_custom_value_object(value)), + error); + case 133: + return core_tests_pigeon_test_message_codec_write_core_tests_pigeon_test_all_nullable_types( + codec, buffer, + CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES( + fl_value_get_custom_value_object(value)), + error); + case 134: + return core_tests_pigeon_test_message_codec_write_core_tests_pigeon_test_all_nullable_types_without_recursion( + codec, buffer, + CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES_WITHOUT_RECURSION( + fl_value_get_custom_value_object(value)), + error); + case 135: + return core_tests_pigeon_test_message_codec_write_core_tests_pigeon_test_all_classes_wrapper( + codec, buffer, + CORE_TESTS_PIGEON_TEST_ALL_CLASSES_WRAPPER( + fl_value_get_custom_value_object(value)), + error); + case 136: + return core_tests_pigeon_test_message_codec_write_core_tests_pigeon_test_test_message( + codec, buffer, + CORE_TESTS_PIGEON_TEST_TEST_MESSAGE( + fl_value_get_custom_value_object(value)), + error); + } + } + + return FL_STANDARD_MESSAGE_CODEC_CLASS( + core_tests_pigeon_test_message_codec_parent_class) + ->write_value(codec, buffer, value, error); +} + +static FlValue* +core_tests_pigeon_test_message_codec_read_core_tests_pigeon_test_an_enum( + FlStandardMessageCodec* codec, GBytes* buffer, size_t* offset, + GError** error) { + return fl_value_new_custom( + 129, fl_standard_message_codec_read_value(codec, buffer, offset, error), + (GDestroyNotify)fl_value_unref); +} + +static FlValue* +core_tests_pigeon_test_message_codec_read_core_tests_pigeon_test_another_enum( + FlStandardMessageCodec* codec, GBytes* buffer, size_t* offset, + GError** error) { + return fl_value_new_custom( + 130, fl_standard_message_codec_read_value(codec, buffer, offset, error), + (GDestroyNotify)fl_value_unref); +} + +static FlValue* +core_tests_pigeon_test_message_codec_read_core_tests_pigeon_test_unused_class( + FlStandardMessageCodec* codec, GBytes* buffer, size_t* offset, + GError** error) { + g_autoptr(FlValue) values = + fl_standard_message_codec_read_value(codec, buffer, offset, error); + if (values == nullptr) { + return nullptr; + } + + g_autoptr(CoreTestsPigeonTestUnusedClass) value = + core_tests_pigeon_test_unused_class_new_from_list(values); + if (value == nullptr) { + g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED, + "Invalid data received for MessageData"); + return nullptr; + } + + return fl_value_new_custom_object(131, G_OBJECT(value)); +} + +static FlValue* +core_tests_pigeon_test_message_codec_read_core_tests_pigeon_test_all_types( + FlStandardMessageCodec* codec, GBytes* buffer, size_t* offset, + GError** error) { + g_autoptr(FlValue) values = + fl_standard_message_codec_read_value(codec, buffer, offset, error); + if (values == nullptr) { + return nullptr; + } + + g_autoptr(CoreTestsPigeonTestAllTypes) value = + core_tests_pigeon_test_all_types_new_from_list(values); + if (value == nullptr) { + g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED, + "Invalid data received for MessageData"); + return nullptr; + } + + return fl_value_new_custom_object(132, G_OBJECT(value)); +} + +static FlValue* +core_tests_pigeon_test_message_codec_read_core_tests_pigeon_test_all_nullable_types( + FlStandardMessageCodec* codec, GBytes* buffer, size_t* offset, + GError** error) { + g_autoptr(FlValue) values = + fl_standard_message_codec_read_value(codec, buffer, offset, error); + if (values == nullptr) { + return nullptr; + } + + g_autoptr(CoreTestsPigeonTestAllNullableTypes) value = + core_tests_pigeon_test_all_nullable_types_new_from_list(values); + if (value == nullptr) { + g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED, + "Invalid data received for MessageData"); + return nullptr; + } + + return fl_value_new_custom_object(133, G_OBJECT(value)); +} + +static FlValue* +core_tests_pigeon_test_message_codec_read_core_tests_pigeon_test_all_nullable_types_without_recursion( + FlStandardMessageCodec* codec, GBytes* buffer, size_t* offset, + GError** error) { + g_autoptr(FlValue) values = + fl_standard_message_codec_read_value(codec, buffer, offset, error); + if (values == nullptr) { + return nullptr; + } + + g_autoptr(CoreTestsPigeonTestAllNullableTypesWithoutRecursion) value = + core_tests_pigeon_test_all_nullable_types_without_recursion_new_from_list( + values); + if (value == nullptr) { + g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED, + "Invalid data received for MessageData"); + return nullptr; + } + + return fl_value_new_custom_object(134, G_OBJECT(value)); +} + +static FlValue* +core_tests_pigeon_test_message_codec_read_core_tests_pigeon_test_all_classes_wrapper( + FlStandardMessageCodec* codec, GBytes* buffer, size_t* offset, + GError** error) { + g_autoptr(FlValue) values = + fl_standard_message_codec_read_value(codec, buffer, offset, error); + if (values == nullptr) { + return nullptr; + } + + g_autoptr(CoreTestsPigeonTestAllClassesWrapper) value = + core_tests_pigeon_test_all_classes_wrapper_new_from_list(values); + if (value == nullptr) { + g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED, + "Invalid data received for MessageData"); + return nullptr; + } + + return fl_value_new_custom_object(135, G_OBJECT(value)); +} + +static FlValue* +core_tests_pigeon_test_message_codec_read_core_tests_pigeon_test_test_message( + FlStandardMessageCodec* codec, GBytes* buffer, size_t* offset, + GError** error) { + g_autoptr(FlValue) values = + fl_standard_message_codec_read_value(codec, buffer, offset, error); + if (values == nullptr) { + return nullptr; + } + + g_autoptr(CoreTestsPigeonTestTestMessage) value = + core_tests_pigeon_test_test_message_new_from_list(values); + if (value == nullptr) { + g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED, + "Invalid data received for MessageData"); + return nullptr; + } + + return fl_value_new_custom_object(136, G_OBJECT(value)); +} + +static FlValue* core_tests_pigeon_test_message_codec_read_value_of_type( + FlStandardMessageCodec* codec, GBytes* buffer, size_t* offset, int type, + GError** error) { + switch (type) { + case 129: + return core_tests_pigeon_test_message_codec_read_core_tests_pigeon_test_an_enum( + codec, buffer, offset, error); + case 130: + return core_tests_pigeon_test_message_codec_read_core_tests_pigeon_test_another_enum( + codec, buffer, offset, error); + case 131: + return core_tests_pigeon_test_message_codec_read_core_tests_pigeon_test_unused_class( + codec, buffer, offset, error); + case 132: + return core_tests_pigeon_test_message_codec_read_core_tests_pigeon_test_all_types( + codec, buffer, offset, error); + case 133: + return core_tests_pigeon_test_message_codec_read_core_tests_pigeon_test_all_nullable_types( + codec, buffer, offset, error); + case 134: + return core_tests_pigeon_test_message_codec_read_core_tests_pigeon_test_all_nullable_types_without_recursion( + codec, buffer, offset, error); + case 135: + return core_tests_pigeon_test_message_codec_read_core_tests_pigeon_test_all_classes_wrapper( + codec, buffer, offset, error); + case 136: + return core_tests_pigeon_test_message_codec_read_core_tests_pigeon_test_test_message( + codec, buffer, offset, error); + default: + return FL_STANDARD_MESSAGE_CODEC_CLASS( + core_tests_pigeon_test_message_codec_parent_class) + ->read_value_of_type(codec, buffer, offset, type, error); + } +} + +static void core_tests_pigeon_test_message_codec_init( + CoreTestsPigeonTestMessageCodec* self) {} + +static void core_tests_pigeon_test_message_codec_class_init( + CoreTestsPigeonTestMessageCodecClass* klass) { + FL_STANDARD_MESSAGE_CODEC_CLASS(klass)->write_value = + core_tests_pigeon_test_message_codec_write_value; + FL_STANDARD_MESSAGE_CODEC_CLASS(klass)->read_value_of_type = + core_tests_pigeon_test_message_codec_read_value_of_type; +} + +static CoreTestsPigeonTestMessageCodec* +core_tests_pigeon_test_message_codec_new() { + CoreTestsPigeonTestMessageCodec* self = CORE_TESTS_PIGEON_TEST_MESSAGE_CODEC( + g_object_new(core_tests_pigeon_test_message_codec_get_type(), nullptr)); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle { + GObject parent_instance; + + FlBasicMessageChannel* channel; + FlBasicMessageChannelResponseHandle* response_handle; +}; + +G_DEFINE_TYPE(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle, + core_tests_pigeon_test_host_integration_core_api_response_handle, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_response_handle_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_RESPONSE_HANDLE(object); + g_clear_object(&self->channel); + g_clear_object(&self->response_handle); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_response_handle_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_response_handle_init( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_response_handle_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandleClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_response_handle_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* +core_tests_pigeon_test_host_integration_core_api_response_handle_new( + FlBasicMessageChannel* channel, + FlBasicMessageChannelResponseHandle* response_handle) { + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_RESPONSE_HANDLE(g_object_new( + core_tests_pigeon_test_host_integration_core_api_response_handle_get_type(), + nullptr)); + self->channel = FL_BASIC_MESSAGE_CHANNEL(g_object_ref(channel)); + self->response_handle = + FL_BASIC_MESSAGE_CHANNEL_RESPONSE_HANDLE(g_object_ref(response_handle)); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiNoopResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE(CoreTestsPigeonTestHostIntegrationCoreApiNoopResponse, + core_tests_pigeon_test_host_integration_core_api_noop_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_noop_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiNoopResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_NOOP_RESPONSE(object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_noop_response_parent_class) + ->dispose(object); +} + +static void core_tests_pigeon_test_host_integration_core_api_noop_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiNoopResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_noop_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiNoopResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_noop_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiNoopResponse* +core_tests_pigeon_test_host_integration_core_api_noop_response_new() { + CoreTestsPigeonTestHostIntegrationCoreApiNoopResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_NOOP_RESPONSE(g_object_new( + core_tests_pigeon_test_host_integration_core_api_noop_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiNoopResponse* +core_tests_pigeon_test_host_integration_core_api_noop_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiNoopResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_NOOP_RESPONSE(g_object_new( + core_tests_pigeon_test_host_integration_core_api_noop_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAllTypesResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllTypesResponse, + core_tests_pigeon_test_host_integration_core_api_echo_all_types_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_all_types_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllTypesResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ALL_TYPES_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_all_types_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_all_types_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllTypesResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_all_types_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllTypesResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_all_types_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoAllTypesResponse* +core_tests_pigeon_test_host_integration_core_api_echo_all_types_response_new( + CoreTestsPigeonTestAllTypes* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllTypesResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ALL_TYPES_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_all_types_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, + fl_value_new_custom_object(132, G_OBJECT(return_value))); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoAllTypesResponse* +core_tests_pigeon_test_host_integration_core_api_echo_all_types_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllTypesResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ALL_TYPES_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_all_types_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorResponse, + core_tests_pigeon_test_host_integration_core_api_throw_error_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_throw_error_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_THROW_ERROR_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_throw_error_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_throw_error_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_throw_error_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_throw_error_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorResponse* +core_tests_pigeon_test_host_integration_core_api_throw_error_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_THROW_ERROR_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_throw_error_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorResponse* +core_tests_pigeon_test_host_integration_core_api_throw_error_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_THROW_ERROR_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_throw_error_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorFromVoidResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorFromVoidResponse, + core_tests_pigeon_test_host_integration_core_api_throw_error_from_void_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_throw_error_from_void_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorFromVoidResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_THROW_ERROR_FROM_VOID_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_throw_error_from_void_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_throw_error_from_void_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorFromVoidResponse* self) { +} + +static void +core_tests_pigeon_test_host_integration_core_api_throw_error_from_void_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorFromVoidResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_throw_error_from_void_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorFromVoidResponse* +core_tests_pigeon_test_host_integration_core_api_throw_error_from_void_response_new() { + CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorFromVoidResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_THROW_ERROR_FROM_VOID_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_throw_error_from_void_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorFromVoidResponse* +core_tests_pigeon_test_host_integration_core_api_throw_error_from_void_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorFromVoidResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_THROW_ERROR_FROM_VOID_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_throw_error_from_void_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiThrowFlutterErrorResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiThrowFlutterErrorResponse, + core_tests_pigeon_test_host_integration_core_api_throw_flutter_error_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_throw_flutter_error_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiThrowFlutterErrorResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_THROW_FLUTTER_ERROR_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_throw_flutter_error_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_throw_flutter_error_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiThrowFlutterErrorResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_throw_flutter_error_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiThrowFlutterErrorResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_throw_flutter_error_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiThrowFlutterErrorResponse* +core_tests_pigeon_test_host_integration_core_api_throw_flutter_error_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiThrowFlutterErrorResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_THROW_FLUTTER_ERROR_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_throw_flutter_error_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiThrowFlutterErrorResponse* +core_tests_pigeon_test_host_integration_core_api_throw_flutter_error_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiThrowFlutterErrorResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_THROW_FLUTTER_ERROR_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_throw_flutter_error_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoIntResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoIntResponse, + core_tests_pigeon_test_host_integration_core_api_echo_int_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_int_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoIntResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_INT_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_int_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_int_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoIntResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_int_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoIntResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_int_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoIntResponse* +core_tests_pigeon_test_host_integration_core_api_echo_int_response_new( + int64_t return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoIntResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_INT_RESPONSE(g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_int_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_int(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoIntResponse* +core_tests_pigeon_test_host_integration_core_api_echo_int_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoIntResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_INT_RESPONSE(g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_int_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleResponse, + core_tests_pigeon_test_host_integration_core_api_echo_double_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_double_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_DOUBLE_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_double_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_double_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_double_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_double_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleResponse* +core_tests_pigeon_test_host_integration_core_api_echo_double_response_new( + double return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_DOUBLE_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_double_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_float(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleResponse* +core_tests_pigeon_test_host_integration_core_api_echo_double_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_DOUBLE_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_double_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponse, + core_tests_pigeon_test_host_integration_core_api_echo_bool_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_bool_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_BOOL_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_bool_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_bool_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_bool_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_bool_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponse* +core_tests_pigeon_test_host_integration_core_api_echo_bool_response_new( + gboolean return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_BOOL_RESPONSE(g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_bool_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_bool(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponse* +core_tests_pigeon_test_host_integration_core_api_echo_bool_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_BOOL_RESPONSE(g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_bool_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse, + core_tests_pigeon_test_host_integration_core_api_echo_string_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_string_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_STRING_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_string_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_string_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_string_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_string_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse* +core_tests_pigeon_test_host_integration_core_api_echo_string_response_new( + const gchar* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_string_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse* +core_tests_pigeon_test_host_integration_core_api_echo_string_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_string_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_UINT8_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_new( + const uint8_t* return_value, size_t return_value_length) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_UINT8_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take( + self->value, fl_value_new_uint8_list(return_value, return_value_length)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_UINT8_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse, + core_tests_pigeon_test_host_integration_core_api_echo_object_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_object_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_OBJECT_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_object_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_object_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_object_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_object_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse* +core_tests_pigeon_test_host_integration_core_api_echo_object_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_OBJECT_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_object_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse* +core_tests_pigeon_test_host_integration_core_api_echo_object_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_OBJECT_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_object_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_list_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_LIST_RESPONSE(g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_LIST_RESPONSE(g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_enum_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_enum_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ENUM_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_enum_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_enum_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumListResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_enum_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumListResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_enum_list_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_enum_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ENUM_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_enum_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_enum_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ENUM_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_enum_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoClassListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoClassListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_class_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_class_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoClassListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_CLASS_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_class_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_class_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoClassListResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_class_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoClassListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_class_list_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoClassListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_class_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoClassListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_CLASS_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_class_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoClassListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_class_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoClassListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_CLASS_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_class_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NON_NULL_ENUM_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumListResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_list_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NON_NULL_ENUM_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NON_NULL_ENUM_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NON_NULL_CLASS_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassListResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_list_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NON_NULL_CLASS_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NON_NULL_CLASS_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoMapResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoMapResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_map_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_MAP_RESPONSE(g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_MAP_RESPONSE(g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoStringMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_string_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_string_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_STRING_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_string_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_string_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringMapResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_string_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_string_map_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_string_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_STRING_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_string_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_string_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_STRING_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_string_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoIntMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoIntMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_int_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_int_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_INT_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_int_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_int_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoIntMapResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_int_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoIntMapResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_int_map_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_int_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_INT_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_int_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_int_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_INT_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_int_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_enum_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_enum_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ENUM_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_enum_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_enum_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumMapResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_enum_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumMapResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_enum_map_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_enum_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ENUM_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_enum_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_enum_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ENUM_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_enum_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoClassMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoClassMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_class_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_class_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_CLASS_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_class_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_class_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoClassMapResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_class_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoClassMapResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_class_map_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_class_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_CLASS_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_class_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_class_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_CLASS_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_class_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullStringMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullStringMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_non_null_string_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_non_null_string_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NON_NULL_STRING_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_non_null_string_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_non_null_string_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullStringMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_non_null_string_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullStringMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_non_null_string_map_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_non_null_string_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NON_NULL_STRING_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_non_null_string_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_non_null_string_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NON_NULL_STRING_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_non_null_string_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullIntMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullIntMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_non_null_int_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_non_null_int_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NON_NULL_INT_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_non_null_int_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_non_null_int_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullIntMapResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_non_null_int_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullIntMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_non_null_int_map_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_non_null_int_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NON_NULL_INT_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_non_null_int_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_non_null_int_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NON_NULL_INT_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_non_null_int_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NON_NULL_ENUM_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumMapResponse* self) { +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_map_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NON_NULL_ENUM_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NON_NULL_ENUM_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NON_NULL_CLASS_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_map_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NON_NULL_CLASS_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NON_NULL_CLASS_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoClassWrapperResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoClassWrapperResponse, + core_tests_pigeon_test_host_integration_core_api_echo_class_wrapper_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_class_wrapper_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoClassWrapperResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_CLASS_WRAPPER_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_class_wrapper_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_class_wrapper_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoClassWrapperResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_class_wrapper_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoClassWrapperResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_class_wrapper_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoClassWrapperResponse* +core_tests_pigeon_test_host_integration_core_api_echo_class_wrapper_response_new( + CoreTestsPigeonTestAllClassesWrapper* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoClassWrapperResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_CLASS_WRAPPER_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_class_wrapper_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, + fl_value_new_custom_object(135, G_OBJECT(return_value))); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoClassWrapperResponse* +core_tests_pigeon_test_host_integration_core_api_echo_class_wrapper_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoClassWrapperResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_CLASS_WRAPPER_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_class_wrapper_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumResponse, + core_tests_pigeon_test_host_integration_core_api_echo_enum_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_enum_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ENUM_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_enum_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_enum_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_enum_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_enum_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumResponse* +core_tests_pigeon_test_host_integration_core_api_echo_enum_response_new( + CoreTestsPigeonTestAnEnum return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ENUM_RESPONSE(g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_enum_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, + fl_value_new_custom(129, fl_value_new_int(return_value), + (GDestroyNotify)fl_value_unref)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumResponse* +core_tests_pigeon_test_host_integration_core_api_echo_enum_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ENUM_RESPONSE(g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_enum_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherEnumResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherEnumResponse, + core_tests_pigeon_test_host_integration_core_api_echo_another_enum_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_another_enum_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ANOTHER_ENUM_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_another_enum_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_another_enum_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherEnumResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_another_enum_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherEnumResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_another_enum_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherEnumResponse* +core_tests_pigeon_test_host_integration_core_api_echo_another_enum_response_new( + CoreTestsPigeonTestAnotherEnum return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ANOTHER_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_another_enum_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, + fl_value_new_custom(130, fl_value_new_int(return_value), + (GDestroyNotify)fl_value_unref)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherEnumResponse* +core_tests_pigeon_test_host_integration_core_api_echo_another_enum_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ANOTHER_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_another_enum_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedDefaultStringResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedDefaultStringResponse, + core_tests_pigeon_test_host_integration_core_api_echo_named_default_string_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_named_default_string_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedDefaultStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NAMED_DEFAULT_STRING_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_named_default_string_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_named_default_string_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedDefaultStringResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_named_default_string_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedDefaultStringResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_named_default_string_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedDefaultStringResponse* +core_tests_pigeon_test_host_integration_core_api_echo_named_default_string_response_new( + const gchar* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedDefaultStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NAMED_DEFAULT_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_named_default_string_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedDefaultStringResponse* +core_tests_pigeon_test_host_integration_core_api_echo_named_default_string_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedDefaultStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NAMED_DEFAULT_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_named_default_string_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalDefaultDoubleResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalDefaultDoubleResponse, + core_tests_pigeon_test_host_integration_core_api_echo_optional_default_double_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_optional_default_double_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalDefaultDoubleResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_OPTIONAL_DEFAULT_DOUBLE_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_optional_default_double_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_optional_default_double_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalDefaultDoubleResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_optional_default_double_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalDefaultDoubleResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_optional_default_double_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalDefaultDoubleResponse* +core_tests_pigeon_test_host_integration_core_api_echo_optional_default_double_response_new( + double return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalDefaultDoubleResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_OPTIONAL_DEFAULT_DOUBLE_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_optional_default_double_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_float(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalDefaultDoubleResponse* +core_tests_pigeon_test_host_integration_core_api_echo_optional_default_double_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalDefaultDoubleResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_OPTIONAL_DEFAULT_DOUBLE_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_optional_default_double_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoRequiredIntResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoRequiredIntResponse, + core_tests_pigeon_test_host_integration_core_api_echo_required_int_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_required_int_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoRequiredIntResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_REQUIRED_INT_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_required_int_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_required_int_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoRequiredIntResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_required_int_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoRequiredIntResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_required_int_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoRequiredIntResponse* +core_tests_pigeon_test_host_integration_core_api_echo_required_int_response_new( + int64_t return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoRequiredIntResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_REQUIRED_INT_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_required_int_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_int(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoRequiredIntResponse* +core_tests_pigeon_test_host_integration_core_api_echo_required_int_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoRequiredIntResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_REQUIRED_INT_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_required_int_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesResponse, + core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ALL_NULLABLE_TYPES_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesResponse* +core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_response_new( + CoreTestsPigeonTestAllNullableTypes* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ALL_NULLABLE_TYPES_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take( + self->value, return_value != nullptr + ? fl_value_new_custom_object(133, G_OBJECT(return_value)) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesResponse* +core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ALL_NULLABLE_TYPES_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse, + core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_without_recursion_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_without_recursion_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ALL_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_without_recursion_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_without_recursion_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_without_recursion_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_without_recursion_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* +core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_without_recursion_response_new( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ALL_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_without_recursion_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take( + self->value, return_value != nullptr + ? fl_value_new_custom_object(134, G_OBJECT(return_value)) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* +core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_without_recursion_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ALL_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_without_recursion_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiExtractNestedNullableStringResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiExtractNestedNullableStringResponse, + core_tests_pigeon_test_host_integration_core_api_extract_nested_nullable_string_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_extract_nested_nullable_string_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiExtractNestedNullableStringResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_EXTRACT_NESTED_NULLABLE_STRING_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_extract_nested_nullable_string_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_extract_nested_nullable_string_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiExtractNestedNullableStringResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_extract_nested_nullable_string_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiExtractNestedNullableStringResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_extract_nested_nullable_string_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiExtractNestedNullableStringResponse* +core_tests_pigeon_test_host_integration_core_api_extract_nested_nullable_string_response_new( + const gchar* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiExtractNestedNullableStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_EXTRACT_NESTED_NULLABLE_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_extract_nested_nullable_string_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_new_string(return_value) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiExtractNestedNullableStringResponse* +core_tests_pigeon_test_host_integration_core_api_extract_nested_nullable_string_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiExtractNestedNullableStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_EXTRACT_NESTED_NULLABLE_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_extract_nested_nullable_string_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCreateNestedNullableStringResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCreateNestedNullableStringResponse, + core_tests_pigeon_test_host_integration_core_api_create_nested_nullable_string_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_create_nested_nullable_string_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCreateNestedNullableStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CREATE_NESTED_NULLABLE_STRING_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_create_nested_nullable_string_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_create_nested_nullable_string_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCreateNestedNullableStringResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_create_nested_nullable_string_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCreateNestedNullableStringResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_create_nested_nullable_string_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiCreateNestedNullableStringResponse* +core_tests_pigeon_test_host_integration_core_api_create_nested_nullable_string_response_new( + CoreTestsPigeonTestAllClassesWrapper* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCreateNestedNullableStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CREATE_NESTED_NULLABLE_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_create_nested_nullable_string_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, + fl_value_new_custom_object(135, G_OBJECT(return_value))); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiCreateNestedNullableStringResponse* +core_tests_pigeon_test_host_integration_core_api_create_nested_nullable_string_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCreateNestedNullableStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CREATE_NESTED_NULLABLE_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_create_nested_nullable_string_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesResponse, + core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_SEND_MULTIPLE_NULLABLE_TYPES_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesResponse* +core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_response_new( + CoreTestsPigeonTestAllNullableTypes* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_SEND_MULTIPLE_NULLABLE_TYPES_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, + fl_value_new_custom_object(133, G_OBJECT(return_value))); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesResponse* +core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_SEND_MULTIPLE_NULLABLE_TYPES_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse, + core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_without_recursion_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_without_recursion_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_SEND_MULTIPLE_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_without_recursion_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_without_recursion_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_without_recursion_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_without_recursion_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* +core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_without_recursion_response_new( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_SEND_MULTIPLE_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_without_recursion_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, + fl_value_new_custom_object(134, G_OBJECT(return_value))); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* +core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_without_recursion_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_SEND_MULTIPLE_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_without_recursion_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_INT_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_response_new( + int64_t* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_INT_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_new_int(*return_value) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_INT_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableDoubleResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableDoubleResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_double_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_double_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableDoubleResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_DOUBLE_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_double_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_double_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableDoubleResponse* self) { +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_double_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableDoubleResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_nullable_double_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableDoubleResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_double_response_new( + double* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableDoubleResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_DOUBLE_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_double_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_new_float(*return_value) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableDoubleResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_double_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableDoubleResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_DOUBLE_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_double_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableBoolResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableBoolResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_bool_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_bool_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableBoolResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_BOOL_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_bool_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_bool_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableBoolResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_bool_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableBoolResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_nullable_bool_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableBoolResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_bool_response_new( + gboolean* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableBoolResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_BOOL_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_bool_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_new_bool(*return_value) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableBoolResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_bool_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableBoolResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_BOOL_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_bool_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_STRING_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringResponse* self) { +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_response_new( + const gchar* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_new_string(return_value) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableUint8ListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableUint8ListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_uint8_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_uint8_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableUint8ListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_UINT8_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_uint8_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_uint8_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableUint8ListResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_uint8_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableUint8ListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_nullable_uint8_list_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableUint8ListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_uint8_list_response_new( + const uint8_t* return_value, size_t return_value_length) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableUint8ListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_UINT8_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_uint8_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_new_uint8_list( + return_value, return_value_length) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableUint8ListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_uint8_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableUint8ListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_UINT8_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_uint8_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableObjectResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableObjectResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_object_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_object_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableObjectResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_OBJECT_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_object_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_object_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableObjectResponse* self) { +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_object_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableObjectResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_nullable_object_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableObjectResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_object_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableObjectResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_OBJECT_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_object_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableObjectResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_object_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableObjectResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_OBJECT_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_object_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableListResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_nullable_list_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumListResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_list_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_CLASS_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassListResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_list_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_CLASS_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_CLASS_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumListResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_ENUM_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumListResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_list_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_ENUM_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_ENUM_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassListResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_CLASS_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassListResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_list_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_CLASS_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_CLASS_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableMapResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_nullable_map_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_STRING_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_map_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_STRING_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_STRING_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_INT_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntMapResponse* self) { +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_map_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_INT_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_INT_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_map_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_CLASS_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_map_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_CLASS_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_CLASS_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullStringMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullStringMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_string_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_string_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullStringMapResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_STRING_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_string_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_string_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullStringMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_string_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullStringMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_string_map_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_string_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_STRING_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_string_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_string_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_STRING_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_string_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullIntMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullIntMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_int_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_int_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_INT_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_int_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_int_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullIntMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_int_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullIntMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_int_map_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_int_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_INT_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_int_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_int_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_INT_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_int_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_ENUM_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_map_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_ENUM_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_ENUM_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassMapResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_CLASS_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_map_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_CLASS_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_CLASS_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_response_new( + CoreTestsPigeonTestAnEnum* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take( + self->value, + return_value != nullptr + ? fl_value_new_custom(129, fl_value_new_int(*return_value), + (GDestroyNotify)fl_value_unref) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherNullableEnumResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherNullableEnumResponse, + core_tests_pigeon_test_host_integration_core_api_echo_another_nullable_enum_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_another_nullable_enum_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherNullableEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ANOTHER_NULLABLE_ENUM_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_another_nullable_enum_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_another_nullable_enum_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherNullableEnumResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_another_nullable_enum_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherNullableEnumResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_another_nullable_enum_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherNullableEnumResponse* +core_tests_pigeon_test_host_integration_core_api_echo_another_nullable_enum_response_new( + CoreTestsPigeonTestAnotherEnum* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherNullableEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ANOTHER_NULLABLE_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_another_nullable_enum_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take( + self->value, + return_value != nullptr + ? fl_value_new_custom(130, fl_value_new_int(*return_value), + (GDestroyNotify)fl_value_unref) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherNullableEnumResponse* +core_tests_pigeon_test_host_integration_core_api_echo_another_nullable_enum_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherNullableEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ANOTHER_NULLABLE_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_another_nullable_enum_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalNullableIntResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalNullableIntResponse, + core_tests_pigeon_test_host_integration_core_api_echo_optional_nullable_int_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_optional_nullable_int_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalNullableIntResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_OPTIONAL_NULLABLE_INT_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_optional_nullable_int_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_optional_nullable_int_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalNullableIntResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_optional_nullable_int_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalNullableIntResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_optional_nullable_int_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalNullableIntResponse* +core_tests_pigeon_test_host_integration_core_api_echo_optional_nullable_int_response_new( + int64_t* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalNullableIntResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_OPTIONAL_NULLABLE_INT_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_optional_nullable_int_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_new_int(*return_value) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalNullableIntResponse* +core_tests_pigeon_test_host_integration_core_api_echo_optional_nullable_int_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalNullableIntResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_OPTIONAL_NULLABLE_INT_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_optional_nullable_int_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedNullableStringResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedNullableStringResponse, + core_tests_pigeon_test_host_integration_core_api_echo_named_nullable_string_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_named_nullable_string_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedNullableStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NAMED_NULLABLE_STRING_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_named_nullable_string_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_named_nullable_string_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedNullableStringResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_named_nullable_string_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedNullableStringResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_named_nullable_string_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedNullableStringResponse* +core_tests_pigeon_test_host_integration_core_api_echo_named_nullable_string_response_new( + const gchar* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedNullableStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NAMED_NULLABLE_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_named_nullable_string_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_new_string(return_value) + : fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedNullableStringResponse* +core_tests_pigeon_test_host_integration_core_api_echo_named_nullable_string_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedNullableStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_NAMED_NULLABLE_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_named_nullable_string_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiNoopAsyncResponse, + core_tests_pigeon_test_host_integration_core_api_noop_async_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_NOOP_ASYNC_RESPONSE, + GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiNoopAsyncResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiNoopAsyncResponse, + core_tests_pigeon_test_host_integration_core_api_noop_async_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_noop_async_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiNoopAsyncResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_NOOP_ASYNC_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_noop_async_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_noop_async_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiNoopAsyncResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_noop_async_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiNoopAsyncResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_noop_async_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiNoopAsyncResponse* +core_tests_pigeon_test_host_integration_core_api_noop_async_response_new() { + CoreTestsPigeonTestHostIntegrationCoreApiNoopAsyncResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_NOOP_ASYNC_RESPONSE(g_object_new( + core_tests_pigeon_test_host_integration_core_api_noop_async_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiNoopAsyncResponse* +core_tests_pigeon_test_host_integration_core_api_noop_async_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiNoopAsyncResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_NOOP_ASYNC_RESPONSE(g_object_new( + core_tests_pigeon_test_host_integration_core_api_noop_async_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncIntResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_int_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_ASYNC_INT_RESPONSE, + GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncIntResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncIntResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_int_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_int_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncIntResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_INT_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_int_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_int_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncIntResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_int_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncIntResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_int_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncIntResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_int_response_new( + int64_t return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncIntResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_INT_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_int_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_int(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncIntResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_int_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncIntResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_INT_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_int_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncDoubleResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_double_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_DOUBLE_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncDoubleResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncDoubleResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_double_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_double_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncDoubleResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_DOUBLE_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_double_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_double_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncDoubleResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_double_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncDoubleResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_double_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncDoubleResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_double_response_new( + double return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncDoubleResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_DOUBLE_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_double_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_float(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncDoubleResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_double_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncDoubleResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_DOUBLE_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_double_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncBoolResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_bool_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_ASYNC_BOOL_RESPONSE, + GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncBoolResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncBoolResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_bool_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_bool_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncBoolResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_BOOL_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_bool_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_bool_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncBoolResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_bool_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncBoolResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_bool_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncBoolResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_bool_response_new( + gboolean return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncBoolResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_BOOL_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_bool_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_bool(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncBoolResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_bool_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncBoolResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_BOOL_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_bool_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncStringResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_string_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_STRING_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncStringResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncStringResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_string_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_string_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_STRING_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_string_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_string_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncStringResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_string_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncStringResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_string_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncStringResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_string_response_new( + const gchar* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_string_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncStringResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_string_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_string_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncUint8ListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_uint8_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_UINT8_LIST_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncUint8ListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncUint8ListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_uint8_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_uint8_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncUint8ListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_UINT8_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_uint8_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_uint8_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncUint8ListResponse* self) { +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_uint8_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncUint8ListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_uint8_list_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncUint8ListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_uint8_list_response_new( + const uint8_t* return_value, size_t return_value_length) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncUint8ListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_UINT8_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_uint8_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take( + self->value, fl_value_new_uint8_list(return_value, return_value_length)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncUint8ListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_uint8_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncUint8ListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_UINT8_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_uint8_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncObjectResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_object_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_OBJECT_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncObjectResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncObjectResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_object_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_object_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncObjectResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_OBJECT_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_object_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_object_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncObjectResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_object_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncObjectResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_object_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncObjectResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_object_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncObjectResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_OBJECT_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_object_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncObjectResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_object_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncObjectResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_OBJECT_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_object_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_list_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_ASYNC_LIST_RESPONSE, + GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncListResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_list_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_ENUM_LIST_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_enum_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_ENUM_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_enum_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumListResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_enum_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_list_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_enum_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_ENUM_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_enum_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_ENUM_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncClassListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_class_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_CLASS_LIST_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncClassListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncClassListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_class_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_class_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncClassListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_CLASS_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_class_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_class_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncClassListResponse* self) { +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_class_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncClassListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_class_list_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncClassListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_class_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncClassListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_CLASS_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_class_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncClassListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_class_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncClassListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_CLASS_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_class_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_map_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_ASYNC_MAP_RESPONSE, + GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncMapResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncMapResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncStringMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_string_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_STRING_MAP_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncStringMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncStringMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_string_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_string_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_STRING_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_string_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_string_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncStringMapResponse* self) { +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_string_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncStringMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_string_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_string_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_STRING_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_string_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_string_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_STRING_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_string_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncIntMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_int_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_INT_MAP_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncIntMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncIntMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_int_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_int_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_INT_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_int_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_int_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncIntMapResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_int_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncIntMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_int_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_int_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_INT_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_int_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_int_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_INT_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_int_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_ENUM_MAP_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_enum_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_ENUM_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_enum_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumMapResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_enum_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_enum_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_ENUM_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_enum_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_ENUM_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncClassMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_class_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_CLASS_MAP_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncClassMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncClassMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_class_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_class_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_CLASS_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_class_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_class_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncClassMapResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_class_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncClassMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_class_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_class_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_CLASS_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_class_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_class_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_CLASS_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_class_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_ASYNC_ENUM_RESPONSE, + GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_enum_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_ENUM_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_enum_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_enum_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_enum_response_new( + CoreTestsPigeonTestAnEnum return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, + fl_value_new_custom(129, fl_value_new_int(return_value), + (GDestroyNotify)fl_value_unref)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_enum_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherAsyncEnumResponse, + core_tests_pigeon_test_host_integration_core_api_echo_another_async_enum_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ANOTHER_ASYNC_ENUM_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherAsyncEnumResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherAsyncEnumResponse, + core_tests_pigeon_test_host_integration_core_api_echo_another_async_enum_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_another_async_enum_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherAsyncEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ANOTHER_ASYNC_ENUM_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_another_async_enum_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_another_async_enum_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherAsyncEnumResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_another_async_enum_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherAsyncEnumResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_another_async_enum_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherAsyncEnumResponse* +core_tests_pigeon_test_host_integration_core_api_echo_another_async_enum_response_new( + CoreTestsPigeonTestAnotherEnum return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherAsyncEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ANOTHER_ASYNC_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_another_async_enum_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, + fl_value_new_custom(130, fl_value_new_int(return_value), + (GDestroyNotify)fl_value_unref)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherAsyncEnumResponse* +core_tests_pigeon_test_host_integration_core_api_echo_another_async_enum_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherAsyncEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ANOTHER_ASYNC_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_another_async_enum_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncErrorResponse, + core_tests_pigeon_test_host_integration_core_api_throw_async_error_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_THROW_ASYNC_ERROR_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncErrorResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncErrorResponse, + core_tests_pigeon_test_host_integration_core_api_throw_async_error_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_throw_async_error_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncErrorResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_THROW_ASYNC_ERROR_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_throw_async_error_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_throw_async_error_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncErrorResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_throw_async_error_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncErrorResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_throw_async_error_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncErrorResponse* +core_tests_pigeon_test_host_integration_core_api_throw_async_error_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncErrorResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_THROW_ASYNC_ERROR_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_throw_async_error_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncErrorResponse* +core_tests_pigeon_test_host_integration_core_api_throw_async_error_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncErrorResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_THROW_ASYNC_ERROR_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_throw_async_error_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncErrorFromVoidResponse, + core_tests_pigeon_test_host_integration_core_api_throw_async_error_from_void_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_THROW_ASYNC_ERROR_FROM_VOID_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncErrorFromVoidResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncErrorFromVoidResponse, + core_tests_pigeon_test_host_integration_core_api_throw_async_error_from_void_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_throw_async_error_from_void_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncErrorFromVoidResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_THROW_ASYNC_ERROR_FROM_VOID_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_throw_async_error_from_void_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_throw_async_error_from_void_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncErrorFromVoidResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_throw_async_error_from_void_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncErrorFromVoidResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_throw_async_error_from_void_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncErrorFromVoidResponse* +core_tests_pigeon_test_host_integration_core_api_throw_async_error_from_void_response_new() { + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncErrorFromVoidResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_THROW_ASYNC_ERROR_FROM_VOID_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_throw_async_error_from_void_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncErrorFromVoidResponse* +core_tests_pigeon_test_host_integration_core_api_throw_async_error_from_void_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncErrorFromVoidResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_THROW_ASYNC_ERROR_FROM_VOID_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_throw_async_error_from_void_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncFlutterErrorResponse, + core_tests_pigeon_test_host_integration_core_api_throw_async_flutter_error_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_THROW_ASYNC_FLUTTER_ERROR_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncFlutterErrorResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncFlutterErrorResponse, + core_tests_pigeon_test_host_integration_core_api_throw_async_flutter_error_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_throw_async_flutter_error_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncFlutterErrorResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_THROW_ASYNC_FLUTTER_ERROR_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_throw_async_flutter_error_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_throw_async_flutter_error_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncFlutterErrorResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_throw_async_flutter_error_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncFlutterErrorResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_throw_async_flutter_error_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncFlutterErrorResponse* +core_tests_pigeon_test_host_integration_core_api_throw_async_flutter_error_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncFlutterErrorResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_THROW_ASYNC_FLUTTER_ERROR_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_throw_async_flutter_error_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncFlutterErrorResponse* +core_tests_pigeon_test_host_integration_core_api_throw_async_flutter_error_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncFlutterErrorResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_THROW_ASYNC_FLUTTER_ERROR_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_throw_async_flutter_error_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncAllTypesResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_all_types_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_ALL_TYPES_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncAllTypesResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncAllTypesResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_all_types_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_all_types_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncAllTypesResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_ALL_TYPES_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_all_types_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_all_types_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncAllTypesResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_all_types_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncAllTypesResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_all_types_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncAllTypesResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_all_types_response_new( + CoreTestsPigeonTestAllTypes* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncAllTypesResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_ALL_TYPES_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_all_types_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, + fl_value_new_custom_object(132, G_OBJECT(return_value))); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncAllTypesResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_all_types_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncAllTypesResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_ALL_TYPES_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_all_types_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableAllNullableTypesResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_ALL_NULLABLE_TYPES_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableAllNullableTypesResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableAllNullableTypesResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableAllNullableTypesResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_ALL_NULLABLE_TYPES_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableAllNullableTypesResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableAllNullableTypesResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableAllNullableTypesResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_response_new( + CoreTestsPigeonTestAllNullableTypes* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableAllNullableTypesResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_ALL_NULLABLE_TYPES_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take( + self->value, return_value != nullptr + ? fl_value_new_custom_object(133, G_OBJECT(return_value)) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableAllNullableTypesResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableAllNullableTypesResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_ALL_NULLABLE_TYPES_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableAllNullableTypesWithoutRecursionResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_without_recursion_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_ALL_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableAllNullableTypesWithoutRecursionResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableAllNullableTypesWithoutRecursionResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_without_recursion_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_without_recursion_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableAllNullableTypesWithoutRecursionResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_ALL_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_without_recursion_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_without_recursion_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableAllNullableTypesWithoutRecursionResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_without_recursion_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableAllNullableTypesWithoutRecursionResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_without_recursion_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableAllNullableTypesWithoutRecursionResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_without_recursion_response_new( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableAllNullableTypesWithoutRecursionResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_ALL_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_without_recursion_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take( + self->value, return_value != nullptr + ? fl_value_new_custom_object(134, G_OBJECT(return_value)) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableAllNullableTypesWithoutRecursionResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_without_recursion_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableAllNullableTypesWithoutRecursionResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_ALL_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_without_recursion_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableIntResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_INT_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableIntResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableIntResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableIntResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_INT_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableIntResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableIntResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableIntResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_response_new( + int64_t* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableIntResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_INT_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_new_int(*return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableIntResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableIntResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_INT_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableDoubleResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_double_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_DOUBLE_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableDoubleResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableDoubleResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_double_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_double_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableDoubleResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_DOUBLE_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_double_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_double_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableDoubleResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_double_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableDoubleResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_double_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableDoubleResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_double_response_new( + double* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableDoubleResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_DOUBLE_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_double_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_new_float(*return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableDoubleResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_double_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableDoubleResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_DOUBLE_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_double_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableBoolResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_bool_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_BOOL_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableBoolResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableBoolResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_bool_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_bool_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableBoolResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_BOOL_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_bool_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_bool_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableBoolResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_bool_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableBoolResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_bool_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableBoolResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_bool_response_new( + gboolean* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableBoolResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_BOOL_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_bool_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_new_bool(*return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableBoolResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_bool_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableBoolResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_BOOL_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_bool_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableStringResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_STRING_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableStringResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableStringResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_STRING_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableStringResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableStringResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableStringResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_response_new( + const gchar* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_new_string(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableStringResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableUint8ListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_uint8_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_UINT8_LIST_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableUint8ListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableUint8ListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_uint8_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_uint8_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableUint8ListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_UINT8_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_uint8_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_uint8_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableUint8ListResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_uint8_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableUint8ListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_uint8_list_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableUint8ListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_uint8_list_response_new( + const uint8_t* return_value, size_t return_value_length) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableUint8ListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_UINT8_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_uint8_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_new_uint8_list( + return_value, return_value_length) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableUint8ListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_uint8_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableUint8ListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_UINT8_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_uint8_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableObjectResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_object_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_OBJECT_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableObjectResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableObjectResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_object_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_object_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableObjectResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_OBJECT_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_object_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_object_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableObjectResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_object_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableObjectResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_object_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableObjectResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_object_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableObjectResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_OBJECT_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_object_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableObjectResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_object_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableObjectResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_OBJECT_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_object_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_LIST_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableListResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_list_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_ENUM_LIST_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_ENUM_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumListResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_list_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_ENUM_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_ENUM_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableClassListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_CLASS_LIST_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableClassListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableClassListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableClassListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_CLASS_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableClassListResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableClassListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_list_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableClassListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableClassListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_CLASS_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableClassListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableClassListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_CLASS_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_MAP_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableStringMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_STRING_MAP_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableStringMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableStringMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_STRING_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableStringMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableStringMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_STRING_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_STRING_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableIntMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_INT_MAP_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableIntMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableIntMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_INT_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableIntMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableIntMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_INT_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_INT_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_ENUM_MAP_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_ENUM_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_ENUM_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_ENUM_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableClassMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_CLASS_MAP_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableClassMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableClassMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_CLASS_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableClassMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableClassMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_CLASS_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_CLASS_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_ENUM_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumResponse, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_ENUM_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_response_new( + CoreTestsPigeonTestAnEnum* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take( + self->value, + return_value != nullptr + ? fl_value_new_custom(129, fl_value_new_int(*return_value), + (GDestroyNotify)fl_value_unref) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumResponse* +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ASYNC_NULLABLE_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherAsyncNullableEnumResponse, + core_tests_pigeon_test_host_integration_core_api_echo_another_async_nullable_enum_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ANOTHER_ASYNC_NULLABLE_ENUM_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherAsyncNullableEnumResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherAsyncNullableEnumResponse, + core_tests_pigeon_test_host_integration_core_api_echo_another_async_nullable_enum_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_another_async_nullable_enum_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherAsyncNullableEnumResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ANOTHER_ASYNC_NULLABLE_ENUM_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_another_async_nullable_enum_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_another_async_nullable_enum_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherAsyncNullableEnumResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_another_async_nullable_enum_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherAsyncNullableEnumResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_another_async_nullable_enum_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherAsyncNullableEnumResponse* +core_tests_pigeon_test_host_integration_core_api_echo_another_async_nullable_enum_response_new( + CoreTestsPigeonTestAnotherEnum* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherAsyncNullableEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ANOTHER_ASYNC_NULLABLE_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_another_async_nullable_enum_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take( + self->value, + return_value != nullptr + ? fl_value_new_custom(130, fl_value_new_int(*return_value), + (GDestroyNotify)fl_value_unref) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherAsyncNullableEnumResponse* +core_tests_pigeon_test_host_integration_core_api_echo_another_async_nullable_enum_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherAsyncNullableEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_ANOTHER_ASYNC_NULLABLE_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_another_async_nullable_enum_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterNoopResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_noop_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_NOOP_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterNoopResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterNoopResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_noop_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_noop_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterNoopResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_NOOP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_noop_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_noop_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterNoopResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_noop_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterNoopResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_noop_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterNoopResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_noop_response_new() { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterNoopResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_NOOP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_noop_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterNoopResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_noop_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterNoopResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_NOOP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_noop_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterThrowErrorResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_THROW_ERROR_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterThrowErrorResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterThrowErrorResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterThrowErrorResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_THROW_ERROR_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterThrowErrorResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterThrowErrorResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterThrowErrorResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterThrowErrorResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_THROW_ERROR_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterThrowErrorResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterThrowErrorResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_THROW_ERROR_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterThrowErrorFromVoidResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_from_void_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_THROW_ERROR_FROM_VOID_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterThrowErrorFromVoidResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterThrowErrorFromVoidResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_from_void_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_from_void_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterThrowErrorFromVoidResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_THROW_ERROR_FROM_VOID_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_from_void_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_from_void_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterThrowErrorFromVoidResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_from_void_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterThrowErrorFromVoidResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_from_void_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterThrowErrorFromVoidResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_from_void_response_new() { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterThrowErrorFromVoidResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_THROW_ERROR_FROM_VOID_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_from_void_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterThrowErrorFromVoidResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_from_void_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterThrowErrorFromVoidResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_THROW_ERROR_FROM_VOID_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_from_void_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllTypesResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_types_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ALL_TYPES_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllTypesResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllTypesResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_types_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_types_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllTypesResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ALL_TYPES_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_types_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_types_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllTypesResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_types_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllTypesResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_types_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllTypesResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_types_response_new( + CoreTestsPigeonTestAllTypes* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllTypesResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ALL_TYPES_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_types_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, + fl_value_new_custom_object(132, G_OBJECT(return_value))); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllTypesResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_types_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllTypesResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ALL_TYPES_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_types_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllNullableTypesResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ALL_NULLABLE_TYPES_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllNullableTypesResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllNullableTypesResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllNullableTypesResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ALL_NULLABLE_TYPES_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllNullableTypesResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllNullableTypesResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllNullableTypesResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_response_new( + CoreTestsPigeonTestAllNullableTypes* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllNullableTypesResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ALL_NULLABLE_TYPES_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take( + self->value, return_value != nullptr + ? fl_value_new_custom_object(133, G_OBJECT(return_value)) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllNullableTypesResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllNullableTypesResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ALL_NULLABLE_TYPES_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSendMultipleNullableTypesResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_SEND_MULTIPLE_NULLABLE_TYPES_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSendMultipleNullableTypesResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSendMultipleNullableTypesResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSendMultipleNullableTypesResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_SEND_MULTIPLE_NULLABLE_TYPES_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSendMultipleNullableTypesResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSendMultipleNullableTypesResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSendMultipleNullableTypesResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_response_new( + CoreTestsPigeonTestAllNullableTypes* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSendMultipleNullableTypesResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_SEND_MULTIPLE_NULLABLE_TYPES_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, + fl_value_new_custom_object(133, G_OBJECT(return_value))); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSendMultipleNullableTypesResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSendMultipleNullableTypesResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_SEND_MULTIPLE_NULLABLE_TYPES_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllNullableTypesWithoutRecursionResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_without_recursion_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ALL_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllNullableTypesWithoutRecursionResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllNullableTypesWithoutRecursionResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_without_recursion_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_without_recursion_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllNullableTypesWithoutRecursionResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ALL_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_without_recursion_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_without_recursion_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllNullableTypesWithoutRecursionResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_without_recursion_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllNullableTypesWithoutRecursionResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_without_recursion_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllNullableTypesWithoutRecursionResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_without_recursion_response_new( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllNullableTypesWithoutRecursionResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ALL_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_without_recursion_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take( + self->value, return_value != nullptr + ? fl_value_new_custom_object(134, G_OBJECT(return_value)) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllNullableTypesWithoutRecursionResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_without_recursion_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllNullableTypesWithoutRecursionResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ALL_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_without_recursion_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSendMultipleNullableTypesWithoutRecursionResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_without_recursion_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_SEND_MULTIPLE_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSendMultipleNullableTypesWithoutRecursionResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSendMultipleNullableTypesWithoutRecursionResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_without_recursion_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_without_recursion_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSendMultipleNullableTypesWithoutRecursionResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_SEND_MULTIPLE_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_without_recursion_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_without_recursion_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSendMultipleNullableTypesWithoutRecursionResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_without_recursion_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSendMultipleNullableTypesWithoutRecursionResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_without_recursion_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSendMultipleNullableTypesWithoutRecursionResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_without_recursion_response_new( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSendMultipleNullableTypesWithoutRecursionResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_SEND_MULTIPLE_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_without_recursion_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, + fl_value_new_custom_object(134, G_OBJECT(return_value))); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSendMultipleNullableTypesWithoutRecursionResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_without_recursion_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSendMultipleNullableTypesWithoutRecursionResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_SEND_MULTIPLE_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_without_recursion_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoBoolResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_bool_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_BOOL_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoBoolResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoBoolResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_bool_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_bool_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoBoolResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_BOOL_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_bool_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_bool_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoBoolResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_bool_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoBoolResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_bool_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoBoolResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_bool_response_new( + gboolean return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoBoolResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_BOOL_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_bool_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_bool(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoBoolResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_bool_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoBoolResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_BOOL_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_bool_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoIntResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_INT_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoIntResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoIntResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoIntResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_INT_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoIntResponse* self) { +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoIntResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoIntResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_response_new( + int64_t return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoIntResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_INT_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_int(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoIntResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoIntResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_INT_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoDoubleResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_double_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_DOUBLE_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoDoubleResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoDoubleResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_double_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_double_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoDoubleResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_DOUBLE_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_double_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_double_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoDoubleResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_double_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoDoubleResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_double_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoDoubleResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_double_response_new( + double return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoDoubleResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_DOUBLE_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_double_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_float(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoDoubleResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_double_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoDoubleResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_DOUBLE_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_double_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoStringResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_STRING_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoStringResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoStringResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_STRING_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoStringResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoStringResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoStringResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_response_new( + const gchar* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoStringResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoUint8ListResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_uint8_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_UINT8_LIST_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoUint8ListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoUint8ListResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_uint8_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_uint8_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoUint8ListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_UINT8_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_uint8_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_uint8_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoUint8ListResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_uint8_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoUint8ListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_uint8_list_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoUint8ListResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_uint8_list_response_new( + const uint8_t* return_value, size_t return_value_length) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoUint8ListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_UINT8_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_uint8_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take( + self->value, fl_value_new_uint8_list(return_value, return_value_length)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoUint8ListResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_uint8_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoUint8ListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_UINT8_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_uint8_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoListResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_LIST_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoListResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoListResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_list_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoListResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoListResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumListResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ENUM_LIST_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumListResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ENUM_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumListResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_list_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ENUM_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ENUM_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoClassListResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_CLASS_LIST_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoClassListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoClassListResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoClassListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_CLASS_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoClassListResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoClassListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_list_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoClassListResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoClassListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_CLASS_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoClassListResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoClassListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_CLASS_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullEnumListResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NON_NULL_ENUM_LIST_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullEnumListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullEnumListResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullEnumListResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NON_NULL_ENUM_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullEnumListResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullEnumListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_list_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullEnumListResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NON_NULL_ENUM_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullEnumListResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NON_NULL_ENUM_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullClassListResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NON_NULL_CLASS_LIST_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullClassListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullClassListResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullClassListResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NON_NULL_CLASS_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullClassListResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullClassListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_list_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullClassListResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullClassListResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NON_NULL_CLASS_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullClassListResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullClassListResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NON_NULL_CLASS_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_MAP_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoMapResponse* self) { +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoStringMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_STRING_MAP_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoStringMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoStringMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_STRING_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoStringMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoStringMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_STRING_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_STRING_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoIntMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_INT_MAP_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoIntMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoIntMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_INT_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoIntMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoIntMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_INT_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_INT_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ENUM_MAP_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ENUM_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ENUM_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ENUM_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoClassMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_CLASS_MAP_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoClassMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoClassMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_CLASS_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoClassMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoClassMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_CLASS_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_CLASS_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullStringMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_string_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NON_NULL_STRING_MAP_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullStringMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullStringMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_string_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_string_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullStringMapResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NON_NULL_STRING_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_string_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_string_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullStringMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_string_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullStringMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_string_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_string_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullStringMapResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NON_NULL_STRING_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_string_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_string_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullStringMapResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NON_NULL_STRING_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_string_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullIntMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_int_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NON_NULL_INT_MAP_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullIntMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullIntMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_int_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_int_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullIntMapResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NON_NULL_INT_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_int_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_int_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullIntMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_int_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullIntMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_int_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_int_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NON_NULL_INT_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_int_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_int_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NON_NULL_INT_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_int_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullEnumMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NON_NULL_ENUM_MAP_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullEnumMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullEnumMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullEnumMapResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NON_NULL_ENUM_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullEnumMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullEnumMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NON_NULL_ENUM_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NON_NULL_ENUM_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullClassMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NON_NULL_CLASS_MAP_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullClassMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullClassMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullClassMapResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NON_NULL_CLASS_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullClassMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullClassMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullClassMapResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NON_NULL_CLASS_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullClassMapResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NON_NULL_CLASS_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ENUM_RESPONSE, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ENUM_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_response_new( + CoreTestsPigeonTestAnEnum return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, + fl_value_new_custom(129, fl_value_new_int(return_value), + (GDestroyNotify)fl_value_unref)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAnotherEnumResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_enum_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ANOTHER_ENUM_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAnotherEnumResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAnotherEnumResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_enum_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_enum_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAnotherEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ANOTHER_ENUM_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_enum_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_enum_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAnotherEnumResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_enum_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAnotherEnumResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_enum_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAnotherEnumResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_enum_response_new( + CoreTestsPigeonTestAnotherEnum return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAnotherEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ANOTHER_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_enum_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, + fl_value_new_custom(130, fl_value_new_int(return_value), + (GDestroyNotify)fl_value_unref)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAnotherEnumResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_enum_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAnotherEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ANOTHER_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_enum_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableBoolResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_bool_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_BOOL_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableBoolResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableBoolResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_bool_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_bool_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableBoolResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_BOOL_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_bool_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_bool_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableBoolResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_bool_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableBoolResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_bool_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableBoolResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_bool_response_new( + gboolean* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableBoolResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_BOOL_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_bool_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_new_bool(*return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableBoolResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_bool_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableBoolResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_BOOL_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_bool_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableIntResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_INT_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableIntResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableIntResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableIntResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_INT_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableIntResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableIntResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableIntResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_response_new( + int64_t* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableIntResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_INT_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_new_int(*return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableIntResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableIntResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_INT_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableDoubleResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_double_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_DOUBLE_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableDoubleResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableDoubleResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_double_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_double_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableDoubleResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_DOUBLE_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_double_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_double_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableDoubleResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_double_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableDoubleResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_double_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableDoubleResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_double_response_new( + double* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableDoubleResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_DOUBLE_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_double_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_new_float(*return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableDoubleResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_double_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableDoubleResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_DOUBLE_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_double_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableStringResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_STRING_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableStringResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableStringResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableStringResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_STRING_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableStringResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableStringResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableStringResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_response_new( + const gchar* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_new_string(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableStringResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableUint8ListResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_uint8_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_UINT8_LIST_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableUint8ListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableUint8ListResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_uint8_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_uint8_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableUint8ListResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_UINT8_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_uint8_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_uint8_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableUint8ListResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_uint8_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableUint8ListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_uint8_list_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableUint8ListResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_uint8_list_response_new( + const uint8_t* return_value, size_t return_value_length) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableUint8ListResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_UINT8_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_uint8_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_new_uint8_list( + return_value, return_value_length) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableUint8ListResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_uint8_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableUint8ListResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_UINT8_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_uint8_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableListResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_LIST_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableListResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableListResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableListResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_list_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableListResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableListResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumListResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_ENUM_LIST_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumListResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumListResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_ENUM_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumListResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_list_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumListResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_ENUM_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumListResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_ENUM_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableClassListResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_CLASS_LIST_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableClassListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableClassListResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableClassListResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_CLASS_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableClassListResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableClassListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_list_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableClassListResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableClassListResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_CLASS_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableClassListResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableClassListResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_CLASS_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullEnumListResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_NON_NULL_ENUM_LIST_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullEnumListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullEnumListResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullEnumListResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_NON_NULL_ENUM_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullEnumListResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullEnumListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_list_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullEnumListResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_NON_NULL_ENUM_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullEnumListResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_NON_NULL_ENUM_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullClassListResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_NON_NULL_CLASS_LIST_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullClassListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullClassListResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullClassListResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_NON_NULL_CLASS_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullClassListResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullClassListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_list_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullClassListResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullClassListResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_NON_NULL_CLASS_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullClassListResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullClassListResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_NON_NULL_CLASS_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_MAP_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableStringMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_STRING_MAP_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableStringMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableStringMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableStringMapResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_STRING_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableStringMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableStringMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableStringMapResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_STRING_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableStringMapResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_STRING_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableIntMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_INT_MAP_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableIntMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableIntMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableIntMapResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_INT_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableIntMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableIntMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_INT_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_INT_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_ENUM_MAP_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumMapResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_ENUM_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumMapResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_ENUM_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumMapResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_ENUM_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableClassMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_CLASS_MAP_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableClassMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableClassMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableClassMapResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_CLASS_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableClassMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableClassMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableClassMapResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_CLASS_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableClassMapResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_CLASS_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullStringMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_string_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_NON_NULL_STRING_MAP_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullStringMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullStringMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_string_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_string_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullStringMapResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_NON_NULL_STRING_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_string_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_string_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullStringMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_string_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullStringMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_string_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_string_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullStringMapResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_NON_NULL_STRING_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_string_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_string_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullStringMapResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_NON_NULL_STRING_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_string_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullIntMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_int_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_NON_NULL_INT_MAP_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullIntMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullIntMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_int_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_int_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullIntMapResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_NON_NULL_INT_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_int_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_int_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullIntMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_int_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullIntMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_int_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_int_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullIntMapResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_NON_NULL_INT_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_int_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_int_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullIntMapResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_NON_NULL_INT_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_int_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullEnumMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_NON_NULL_ENUM_MAP_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullEnumMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullEnumMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullEnumMapResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_NON_NULL_ENUM_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullEnumMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullEnumMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullEnumMapResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_NON_NULL_ENUM_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullEnumMapResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_NON_NULL_ENUM_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullClassMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_NON_NULL_CLASS_MAP_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullClassMapResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullClassMapResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullClassMapResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_NON_NULL_CLASS_MAP_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_map_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullClassMapResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_map_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullClassMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_map_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_map_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullClassMapResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_NON_NULL_CLASS_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_ref(return_value) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullClassMapResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_NON_NULL_CLASS_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_map_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_ENUM_RESPONSE, GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_ENUM_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_response_new( + CoreTestsPigeonTestAnEnum* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take( + self->value, + return_value != nullptr + ? fl_value_new_custom(129, fl_value_new_int(*return_value), + (GDestroyNotify)fl_value_unref) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_NULLABLE_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAnotherNullableEnumResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_nullable_enum_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ANOTHER_NULLABLE_ENUM_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAnotherNullableEnumResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAnotherNullableEnumResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_nullable_enum_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_nullable_enum_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAnotherNullableEnumResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ANOTHER_NULLABLE_ENUM_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_nullable_enum_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_nullable_enum_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAnotherNullableEnumResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_nullable_enum_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAnotherNullableEnumResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_nullable_enum_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAnotherNullableEnumResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_nullable_enum_response_new( + CoreTestsPigeonTestAnotherEnum* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAnotherNullableEnumResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ANOTHER_NULLABLE_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_nullable_enum_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take( + self->value, + return_value != nullptr + ? fl_value_new_custom(130, fl_value_new_int(*return_value), + (GDestroyNotify)fl_value_unref) + : fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAnotherNullableEnumResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_nullable_enum_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAnotherNullableEnumResponse* + self = CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_ECHO_ANOTHER_NULLABLE_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_nullable_enum_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSmallApiEchoStringResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_small_api_echo_string_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CALL_FLUTTER_SMALL_API_ECHO_STRING_RESPONSE, + GObject) + +struct + _CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSmallApiEchoStringResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSmallApiEchoStringResponse, + core_tests_pigeon_test_host_integration_core_api_call_flutter_small_api_echo_string_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_small_api_echo_string_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSmallApiEchoStringResponse* + self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_SMALL_API_ECHO_STRING_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_call_flutter_small_api_echo_string_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_small_api_echo_string_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSmallApiEchoStringResponse* + self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_small_api_echo_string_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSmallApiEchoStringResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_call_flutter_small_api_echo_string_response_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSmallApiEchoStringResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_small_api_echo_string_response_new( + const gchar* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSmallApiEchoStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_SMALL_API_ECHO_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_small_api_echo_string_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(return_value)); + return self; +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSmallApiEchoStringResponse* +core_tests_pigeon_test_host_integration_core_api_call_flutter_small_api_echo_string_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSmallApiEchoStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_CALL_FLUTTER_SMALL_API_ECHO_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_call_flutter_small_api_echo_string_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestHostIntegrationCoreApi, + core_tests_pigeon_test_host_integration_core_api, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API, GObject) + +struct _CoreTestsPigeonTestHostIntegrationCoreApi { + GObject parent_instance; + + const CoreTestsPigeonTestHostIntegrationCoreApiVTable* vtable; + gpointer user_data; + GDestroyNotify user_data_free_func; +}; + +G_DEFINE_TYPE(CoreTestsPigeonTestHostIntegrationCoreApi, + core_tests_pigeon_test_host_integration_core_api, G_TYPE_OBJECT) + +static void core_tests_pigeon_test_host_integration_core_api_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(object); + if (self->user_data != nullptr) { + self->user_data_free_func(self->user_data); + } + self->user_data = nullptr; + G_OBJECT_CLASS(core_tests_pigeon_test_host_integration_core_api_parent_class) + ->dispose(object); +} + +static void core_tests_pigeon_test_host_integration_core_api_init( + CoreTestsPigeonTestHostIntegrationCoreApi* self) {} + +static void core_tests_pigeon_test_host_integration_core_api_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_dispose; +} + +static CoreTestsPigeonTestHostIntegrationCoreApi* +core_tests_pigeon_test_host_integration_core_api_new( + const CoreTestsPigeonTestHostIntegrationCoreApiVTable* vtable, + gpointer user_data, GDestroyNotify user_data_free_func) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(g_object_new( + core_tests_pigeon_test_host_integration_core_api_get_type(), + nullptr)); + self->vtable = vtable; + self->user_data = user_data; + self->user_data_free_func = user_data_free_func; + return self; +} + +static void core_tests_pigeon_test_host_integration_core_api_noop_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->noop == nullptr) { + return; + } + + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiNoopResponse) response = + self->vtable->noop(self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "noop"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "noop", error->message); + } +} + +static void core_tests_pigeon_test_host_integration_core_api_echo_all_types_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_all_types == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + CoreTestsPigeonTestAllTypes* everything = CORE_TESTS_PIGEON_TEST_ALL_TYPES( + fl_value_get_custom_value_object(value0)); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoAllTypesResponse) + response = self->vtable->echo_all_types(everything, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoAllTypes"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAllTypes", error->message); + } +} + +static void core_tests_pigeon_test_host_integration_core_api_throw_error_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->throw_error == nullptr) { + return; + } + + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorResponse) + response = self->vtable->throw_error(self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "throwError"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "throwError", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_throw_error_from_void_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->throw_error_from_void == nullptr) { + return; + } + + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorFromVoidResponse) + response = self->vtable->throw_error_from_void(self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "throwErrorFromVoid"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "throwErrorFromVoid", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_throw_flutter_error_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->throw_flutter_error == nullptr) { + return; + } + + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiThrowFlutterErrorResponse) + response = self->vtable->throw_flutter_error(self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "throwFlutterError"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "throwFlutterError", error->message); + } +} + +static void core_tests_pigeon_test_host_integration_core_api_echo_int_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_int == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + int64_t an_int = fl_value_get_int(value0); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoIntResponse) response = + self->vtable->echo_int(an_int, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoInt"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoInt", error->message); + } +} + +static void core_tests_pigeon_test_host_integration_core_api_echo_double_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_double == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + double a_double = fl_value_get_float(value0); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleResponse) + response = self->vtable->echo_double(a_double, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoDouble"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoDouble", error->message); + } +} + +static void core_tests_pigeon_test_host_integration_core_api_echo_bool_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_bool == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + gboolean a_bool = fl_value_get_bool(value0); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponse) + response = self->vtable->echo_bool(a_bool, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoBool"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoBool", error->message); + } +} + +static void core_tests_pigeon_test_host_integration_core_api_echo_string_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_string == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + const gchar* a_string = fl_value_get_string(value0); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse) + response = self->vtable->echo_string(a_string, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoString"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoString", error->message); + } +} + +static void core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_uint8_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + const uint8_t* a_uint8_list = fl_value_get_uint8_list(value0); + size_t a_uint8_list_length = fl_value_get_length(value0); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse) + response = self->vtable->echo_uint8_list( + a_uint8_list, a_uint8_list_length, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoUint8List"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoUint8List", error->message); + } +} + +static void core_tests_pigeon_test_host_integration_core_api_echo_object_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_object == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* an_object = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse) + response = self->vtable->echo_object(an_object, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoObject"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoObject", error->message); + } +} + +static void core_tests_pigeon_test_host_integration_core_api_echo_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* list = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse) + response = self->vtable->echo_list(list, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoList"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoList", error->message); + } +} + +static void core_tests_pigeon_test_host_integration_core_api_echo_enum_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_enum_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* enum_list = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumListResponse) + response = self->vtable->echo_enum_list(enum_list, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoEnumList"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoEnumList", error->message); + } +} + +static void core_tests_pigeon_test_host_integration_core_api_echo_class_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_class_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* class_list = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoClassListResponse) + response = self->vtable->echo_class_list(class_list, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoClassList"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoClassList", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_non_null_enum_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* enum_list = value0; + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumListResponse) + response = + self->vtable->echo_non_null_enum_list(enum_list, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNonNullEnumList"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNonNullEnumList", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_non_null_class_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* class_list = value0; + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassListResponse) + response = + self->vtable->echo_non_null_class_list(class_list, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNonNullClassList"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNonNullClassList", error->message); + } +} + +static void core_tests_pigeon_test_host_integration_core_api_echo_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoMapResponse) response = + self->vtable->echo_map(map, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoMap"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoMap", error->message); + } +} + +static void core_tests_pigeon_test_host_integration_core_api_echo_string_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_string_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* string_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoStringMapResponse) + response = self->vtable->echo_string_map(string_map, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoStringMap"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoStringMap", error->message); + } +} + +static void core_tests_pigeon_test_host_integration_core_api_echo_int_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_int_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* int_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoIntMapResponse) + response = self->vtable->echo_int_map(int_map, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoIntMap"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoIntMap", error->message); + } +} + +static void core_tests_pigeon_test_host_integration_core_api_echo_enum_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_enum_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* enum_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumMapResponse) + response = self->vtable->echo_enum_map(enum_map, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoEnumMap"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoEnumMap", error->message); + } +} + +static void core_tests_pigeon_test_host_integration_core_api_echo_class_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_class_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* class_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoClassMapResponse) + response = self->vtable->echo_class_map(class_map, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoClassMap"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoClassMap", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_non_null_string_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_non_null_string_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* string_map = value0; + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullStringMapResponse) + response = + self->vtable->echo_non_null_string_map(string_map, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNonNullStringMap"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNonNullStringMap", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_non_null_int_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_non_null_int_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* int_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullIntMapResponse) + response = self->vtable->echo_non_null_int_map(int_map, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNonNullIntMap"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNonNullIntMap", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_non_null_enum_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* enum_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumMapResponse) + response = + self->vtable->echo_non_null_enum_map(enum_map, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNonNullEnumMap"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNonNullEnumMap", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_non_null_class_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* class_map = value0; + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassMapResponse) + response = + self->vtable->echo_non_null_class_map(class_map, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNonNullClassMap"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNonNullClassMap", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_class_wrapper_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_class_wrapper == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + CoreTestsPigeonTestAllClassesWrapper* wrapper = + CORE_TESTS_PIGEON_TEST_ALL_CLASSES_WRAPPER( + fl_value_get_custom_value_object(value0)); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoClassWrapperResponse) + response = self->vtable->echo_class_wrapper(wrapper, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoClassWrapper"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoClassWrapper", error->message); + } +} + +static void core_tests_pigeon_test_host_integration_core_api_echo_enum_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_enum == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + CoreTestsPigeonTestAnEnum an_enum = static_cast( + fl_value_get_int(reinterpret_cast( + const_cast(fl_value_get_custom_value(value0))))); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumResponse) + response = self->vtable->echo_enum(an_enum, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoEnum"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoEnum", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_another_enum_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_another_enum == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + CoreTestsPigeonTestAnotherEnum another_enum = + static_cast( + fl_value_get_int(reinterpret_cast( + const_cast(fl_value_get_custom_value(value0))))); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherEnumResponse) + response = self->vtable->echo_another_enum(another_enum, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoAnotherEnum"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAnotherEnum", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_named_default_string_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_named_default_string == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + const gchar* a_string = fl_value_get_string(value0); + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedDefaultStringResponse) + response = + self->vtable->echo_named_default_string(a_string, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNamedDefaultString"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNamedDefaultString", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_optional_default_double_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_optional_default_double == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + double a_double = fl_value_get_float(value0); + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalDefaultDoubleResponse) + response = + self->vtable->echo_optional_default_double(a_double, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoOptionalDefaultDouble"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoOptionalDefaultDouble", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_required_int_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_required_int == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + int64_t an_int = fl_value_get_int(value0); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoRequiredIntResponse) + response = self->vtable->echo_required_int(an_int, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoRequiredInt"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoRequiredInt", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_all_nullable_types == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + CoreTestsPigeonTestAllNullableTypes* everything = + CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES( + fl_value_get_custom_value_object(value0)); + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesResponse) + response = + self->vtable->echo_all_nullable_types(everything, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoAllNullableTypes"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAllNullableTypes", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_without_recursion_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_all_nullable_types_without_recursion == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* everything = + CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES_WITHOUT_RECURSION( + fl_value_get_custom_value_object(value0)); + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse) + response = self->vtable->echo_all_nullable_types_without_recursion( + everything, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoAllNullableTypesWithoutRecursion"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAllNullableTypesWithoutRecursion", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_extract_nested_nullable_string_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->extract_nested_nullable_string == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + CoreTestsPigeonTestAllClassesWrapper* wrapper = + CORE_TESTS_PIGEON_TEST_ALL_CLASSES_WRAPPER( + fl_value_get_custom_value_object(value0)); + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiExtractNestedNullableStringResponse) + response = self->vtable->extract_nested_nullable_string(wrapper, + self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "extractNestedNullableString"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "extractNestedNullableString", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_create_nested_nullable_string_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->create_nested_nullable_string == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + const gchar* nullable_string = fl_value_get_string(value0); + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCreateNestedNullableStringResponse) + response = self->vtable->create_nested_nullable_string(nullable_string, + self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "createNestedNullableString"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "createNestedNullableString", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->send_multiple_nullable_types == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + gboolean* a_nullable_bool = nullptr; + gboolean a_nullable_bool_value; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + a_nullable_bool_value = fl_value_get_bool(value0); + a_nullable_bool = &a_nullable_bool_value; + } + FlValue* value1 = fl_value_get_list_value(message_, 1); + int64_t* a_nullable_int = nullptr; + int64_t a_nullable_int_value; + if (fl_value_get_type(value1) != FL_VALUE_TYPE_NULL) { + a_nullable_int_value = fl_value_get_int(value1); + a_nullable_int = &a_nullable_int_value; + } + FlValue* value2 = fl_value_get_list_value(message_, 2); + const gchar* a_nullable_string = fl_value_get_string(value2); + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesResponse) + response = self->vtable->send_multiple_nullable_types( + a_nullable_bool, a_nullable_int, a_nullable_string, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "sendMultipleNullableTypes"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "sendMultipleNullableTypes", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_without_recursion_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->send_multiple_nullable_types_without_recursion == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + gboolean* a_nullable_bool = nullptr; + gboolean a_nullable_bool_value; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + a_nullable_bool_value = fl_value_get_bool(value0); + a_nullable_bool = &a_nullable_bool_value; + } + FlValue* value1 = fl_value_get_list_value(message_, 1); + int64_t* a_nullable_int = nullptr; + int64_t a_nullable_int_value; + if (fl_value_get_type(value1) != FL_VALUE_TYPE_NULL) { + a_nullable_int_value = fl_value_get_int(value1); + a_nullable_int = &a_nullable_int_value; + } + FlValue* value2 = fl_value_get_list_value(message_, 2); + const gchar* a_nullable_string = fl_value_get_string(value2); + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse) + response = self->vtable->send_multiple_nullable_types_without_recursion( + a_nullable_bool, a_nullable_int, a_nullable_string, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "sendMultipleNullableTypesWithoutRecursion"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "sendMultipleNullableTypesWithoutRecursion", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_nullable_int == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + int64_t* a_nullable_int = nullptr; + int64_t a_nullable_int_value; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + a_nullable_int_value = fl_value_get_int(value0); + a_nullable_int = &a_nullable_int_value; + } + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntResponse) + response = + self->vtable->echo_nullable_int(a_nullable_int, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNullableInt"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNullableInt", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_double_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_nullable_double == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + double* a_nullable_double = nullptr; + double a_nullable_double_value; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + a_nullable_double_value = fl_value_get_float(value0); + a_nullable_double = &a_nullable_double_value; + } + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableDoubleResponse) + response = self->vtable->echo_nullable_double(a_nullable_double, + self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNullableDouble"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNullableDouble", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_bool_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_nullable_bool == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + gboolean* a_nullable_bool = nullptr; + gboolean a_nullable_bool_value; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + a_nullable_bool_value = fl_value_get_bool(value0); + a_nullable_bool = &a_nullable_bool_value; + } + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableBoolResponse) + response = + self->vtable->echo_nullable_bool(a_nullable_bool, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNullableBool"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNullableBool", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_nullable_string == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + const gchar* a_nullable_string = fl_value_get_string(value0); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringResponse) + response = self->vtable->echo_nullable_string(a_nullable_string, + self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNullableString"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNullableString", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_uint8_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_nullable_uint8_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + const uint8_t* a_nullable_uint8_list = fl_value_get_uint8_list(value0); + size_t a_nullable_uint8_list_length = fl_value_get_length(value0); + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableUint8ListResponse) + response = self->vtable->echo_nullable_uint8_list( + a_nullable_uint8_list, a_nullable_uint8_list_length, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNullableUint8List"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNullableUint8List", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_object_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_nullable_object == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* a_nullable_object = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableObjectResponse) + response = self->vtable->echo_nullable_object(a_nullable_object, + self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNullableObject"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNullableObject", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_nullable_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* a_nullable_list = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableListResponse) + response = + self->vtable->echo_nullable_list(a_nullable_list, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNullableList"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNullableList", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_nullable_enum_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* enum_list = value0; + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumListResponse) + response = + self->vtable->echo_nullable_enum_list(enum_list, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNullableEnumList"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNullableEnumList", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_nullable_class_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* class_list = value0; + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassListResponse) + response = + self->vtable->echo_nullable_class_list(class_list, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNullableClassList"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNullableClassList", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_nullable_non_null_enum_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* enum_list = value0; + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumListResponse) + response = self->vtable->echo_nullable_non_null_enum_list( + enum_list, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNullableNonNullEnumList"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNullableNonNullEnumList", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_nullable_non_null_class_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* class_list = value0; + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassListResponse) + response = self->vtable->echo_nullable_non_null_class_list( + class_list, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNullableNonNullClassList"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNullableNonNullClassList", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_nullable_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableMapResponse) + response = self->vtable->echo_nullable_map(map, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNullableMap"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNullableMap", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_nullable_string_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* string_map = value0; + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringMapResponse) + response = + self->vtable->echo_nullable_string_map(string_map, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNullableStringMap"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNullableStringMap", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_nullable_int_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* int_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntMapResponse) + response = self->vtable->echo_nullable_int_map(int_map, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNullableIntMap"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNullableIntMap", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_nullable_enum_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* enum_map = value0; + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumMapResponse) + response = + self->vtable->echo_nullable_enum_map(enum_map, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNullableEnumMap"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNullableEnumMap", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_nullable_class_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* class_map = value0; + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassMapResponse) + response = + self->vtable->echo_nullable_class_map(class_map, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNullableClassMap"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNullableClassMap", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_string_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_nullable_non_null_string_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* string_map = value0; + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullStringMapResponse) + response = self->vtable->echo_nullable_non_null_string_map( + string_map, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNullableNonNullStringMap"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNullableNonNullStringMap", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_int_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_nullable_non_null_int_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* int_map = value0; + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullIntMapResponse) + response = self->vtable->echo_nullable_non_null_int_map(int_map, + self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNullableNonNullIntMap"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNullableNonNullIntMap", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_nullable_non_null_enum_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* enum_map = value0; + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumMapResponse) + response = self->vtable->echo_nullable_non_null_enum_map(enum_map, + self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNullableNonNullEnumMap"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNullableNonNullEnumMap", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_nullable_non_null_class_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* class_map = value0; + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassMapResponse) + response = self->vtable->echo_nullable_non_null_class_map( + class_map, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNullableNonNullClassMap"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNullableNonNullClassMap", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_nullable_enum == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + CoreTestsPigeonTestAnEnum* an_enum = nullptr; + CoreTestsPigeonTestAnEnum an_enum_value; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + an_enum_value = static_cast( + fl_value_get_int(reinterpret_cast( + const_cast(fl_value_get_custom_value(value0))))); + an_enum = &an_enum_value; + } + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumResponse) + response = self->vtable->echo_nullable_enum(an_enum, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNullableEnum"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNullableEnum", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_another_nullable_enum_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_another_nullable_enum == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + CoreTestsPigeonTestAnotherEnum* another_enum = nullptr; + CoreTestsPigeonTestAnotherEnum another_enum_value; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + another_enum_value = static_cast( + fl_value_get_int(reinterpret_cast( + const_cast(fl_value_get_custom_value(value0))))); + another_enum = &another_enum_value; + } + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherNullableEnumResponse) + response = self->vtable->echo_another_nullable_enum(another_enum, + self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoAnotherNullableEnum"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAnotherNullableEnum", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_optional_nullable_int_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_optional_nullable_int == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + int64_t* a_nullable_int = nullptr; + int64_t a_nullable_int_value; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + a_nullable_int_value = fl_value_get_int(value0); + a_nullable_int = &a_nullable_int_value; + } + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalNullableIntResponse) + response = self->vtable->echo_optional_nullable_int(a_nullable_int, + self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoOptionalNullableInt"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoOptionalNullableInt", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_named_nullable_string_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_named_nullable_string == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + const gchar* a_nullable_string = fl_value_get_string(value0); + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedNullableStringResponse) + response = self->vtable->echo_named_nullable_string(a_nullable_string, + self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoNamedNullableString"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoNamedNullableString", error->message); + } +} + +static void core_tests_pigeon_test_host_integration_core_api_noop_async_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->noop_async == nullptr) { + return; + } + + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->noop_async(handle, self->user_data); +} + +static void core_tests_pigeon_test_host_integration_core_api_echo_async_int_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_async_int == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + int64_t an_int = fl_value_get_int(value0); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_int(an_int, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_double_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_async_double == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + double a_double = fl_value_get_float(value0); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_double(a_double, handle, self->user_data); +} + +static void core_tests_pigeon_test_host_integration_core_api_echo_async_bool_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_async_bool == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + gboolean a_bool = fl_value_get_bool(value0); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_bool(a_bool, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_string_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_async_string == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + const gchar* a_string = fl_value_get_string(value0); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_string(a_string, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_uint8_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_async_uint8_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + const uint8_t* a_uint8_list = fl_value_get_uint8_list(value0); + size_t a_uint8_list_length = fl_value_get_length(value0); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_uint8_list(a_uint8_list, a_uint8_list_length, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_object_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_async_object == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* an_object = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_object(an_object, handle, self->user_data); +} + +static void core_tests_pigeon_test_host_integration_core_api_echo_async_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_async_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* list = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_list(list, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_enum_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_async_enum_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* enum_list = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_enum_list(enum_list, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_class_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_async_class_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* class_list = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_class_list(class_list, handle, self->user_data); +} + +static void core_tests_pigeon_test_host_integration_core_api_echo_async_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_async_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_map(map, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_string_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_async_string_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* string_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_string_map(string_map, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_int_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_async_int_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* int_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_int_map(int_map, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_enum_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_async_enum_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* enum_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_enum_map(enum_map, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_class_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_async_class_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* class_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_class_map(class_map, handle, self->user_data); +} + +static void core_tests_pigeon_test_host_integration_core_api_echo_async_enum_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_async_enum == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + CoreTestsPigeonTestAnEnum an_enum = static_cast( + fl_value_get_int(reinterpret_cast( + const_cast(fl_value_get_custom_value(value0))))); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_enum(an_enum, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_another_async_enum_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_another_async_enum == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + CoreTestsPigeonTestAnotherEnum another_enum = + static_cast( + fl_value_get_int(reinterpret_cast( + const_cast(fl_value_get_custom_value(value0))))); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_another_async_enum(another_enum, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_throw_async_error_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->throw_async_error == nullptr) { + return; + } + + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->throw_async_error(handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_throw_async_error_from_void_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->throw_async_error_from_void == nullptr) { + return; + } + + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->throw_async_error_from_void(handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_throw_async_flutter_error_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->throw_async_flutter_error == nullptr) { + return; + } + + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->throw_async_flutter_error(handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_all_types_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_async_all_types == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + CoreTestsPigeonTestAllTypes* everything = CORE_TESTS_PIGEON_TEST_ALL_TYPES( + fl_value_get_custom_value_object(value0)); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_all_types(everything, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_async_nullable_all_nullable_types == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + CoreTestsPigeonTestAllNullableTypes* everything = + CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES( + fl_value_get_custom_value_object(value0)); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_nullable_all_nullable_types(everything, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_without_recursion_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_async_nullable_all_nullable_types_without_recursion == + nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* everything = + CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES_WITHOUT_RECURSION( + fl_value_get_custom_value_object(value0)); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_nullable_all_nullable_types_without_recursion( + everything, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_async_nullable_int == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + int64_t* an_int = nullptr; + int64_t an_int_value; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + an_int_value = fl_value_get_int(value0); + an_int = &an_int_value; + } + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_nullable_int(an_int, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_double_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_async_nullable_double == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + double* a_double = nullptr; + double a_double_value; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + a_double_value = fl_value_get_float(value0); + a_double = &a_double_value; + } + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_nullable_double(a_double, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_bool_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_async_nullable_bool == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + gboolean* a_bool = nullptr; + gboolean a_bool_value; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + a_bool_value = fl_value_get_bool(value0); + a_bool = &a_bool_value; + } + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_nullable_bool(a_bool, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_async_nullable_string == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + const gchar* a_string = fl_value_get_string(value0); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_nullable_string(a_string, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_uint8_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_async_nullable_uint8_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + const uint8_t* a_uint8_list = fl_value_get_uint8_list(value0); + size_t a_uint8_list_length = fl_value_get_length(value0); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_nullable_uint8_list( + a_uint8_list, a_uint8_list_length, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_object_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_async_nullable_object == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* an_object = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_nullable_object(an_object, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_async_nullable_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* list = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_nullable_list(list, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_async_nullable_enum_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* enum_list = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_nullable_enum_list(enum_list, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_async_nullable_class_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* class_list = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_nullable_class_list(class_list, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_async_nullable_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_nullable_map(map, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_async_nullable_string_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* string_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_nullable_string_map(string_map, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_async_nullable_int_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* int_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_nullable_int_map(int_map, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_async_nullable_enum_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* enum_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_nullable_enum_map(enum_map, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_async_nullable_class_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* class_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_nullable_class_map(class_map, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_async_nullable_enum == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + CoreTestsPigeonTestAnEnum* an_enum = nullptr; + CoreTestsPigeonTestAnEnum an_enum_value; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + an_enum_value = static_cast( + fl_value_get_int(reinterpret_cast( + const_cast(fl_value_get_custom_value(value0))))); + an_enum = &an_enum_value; + } + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_async_nullable_enum(an_enum, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_another_async_nullable_enum_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->echo_another_async_nullable_enum == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + CoreTestsPigeonTestAnotherEnum* another_enum = nullptr; + CoreTestsPigeonTestAnotherEnum another_enum_value; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + another_enum_value = static_cast( + fl_value_get_int(reinterpret_cast( + const_cast(fl_value_get_custom_value(value0))))); + another_enum = &another_enum_value; + } + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->echo_another_async_nullable_enum(another_enum, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_noop_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->call_flutter_noop == nullptr) { + return; + } + + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_noop(handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_throw_error == nullptr) { + return; + } + + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_throw_error(handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_from_void_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_throw_error_from_void == nullptr) { + return; + } + + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_throw_error_from_void(handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_types_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_all_types == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + CoreTestsPigeonTestAllTypes* everything = CORE_TESTS_PIGEON_TEST_ALL_TYPES( + fl_value_get_custom_value_object(value0)); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_all_types(everything, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_all_nullable_types == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + CoreTestsPigeonTestAllNullableTypes* everything = + CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES( + fl_value_get_custom_value_object(value0)); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_all_nullable_types(everything, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_send_multiple_nullable_types == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + gboolean* a_nullable_bool = nullptr; + gboolean a_nullable_bool_value; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + a_nullable_bool_value = fl_value_get_bool(value0); + a_nullable_bool = &a_nullable_bool_value; + } + FlValue* value1 = fl_value_get_list_value(message_, 1); + int64_t* a_nullable_int = nullptr; + int64_t a_nullable_int_value; + if (fl_value_get_type(value1) != FL_VALUE_TYPE_NULL) { + a_nullable_int_value = fl_value_get_int(value1); + a_nullable_int = &a_nullable_int_value; + } + FlValue* value2 = fl_value_get_list_value(message_, 2); + const gchar* a_nullable_string = fl_value_get_string(value2); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_send_multiple_nullable_types( + a_nullable_bool, a_nullable_int, a_nullable_string, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_without_recursion_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_all_nullable_types_without_recursion == + nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* everything = + CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES_WITHOUT_RECURSION( + fl_value_get_custom_value_object(value0)); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_all_nullable_types_without_recursion( + everything, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_without_recursion_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable + ->call_flutter_send_multiple_nullable_types_without_recursion == + nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + gboolean* a_nullable_bool = nullptr; + gboolean a_nullable_bool_value; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + a_nullable_bool_value = fl_value_get_bool(value0); + a_nullable_bool = &a_nullable_bool_value; + } + FlValue* value1 = fl_value_get_list_value(message_, 1); + int64_t* a_nullable_int = nullptr; + int64_t a_nullable_int_value; + if (fl_value_get_type(value1) != FL_VALUE_TYPE_NULL) { + a_nullable_int_value = fl_value_get_int(value1); + a_nullable_int = &a_nullable_int_value; + } + FlValue* value2 = fl_value_get_list_value(message_, 2); + const gchar* a_nullable_string = fl_value_get_string(value2); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_send_multiple_nullable_types_without_recursion( + a_nullable_bool, a_nullable_int, a_nullable_string, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_bool_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_bool == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + gboolean a_bool = fl_value_get_bool(value0); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_bool(a_bool, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_int == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + int64_t an_int = fl_value_get_int(value0); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_int(an_int, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_double_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_double == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + double a_double = fl_value_get_float(value0); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_double(a_double, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_string == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + const gchar* a_string = fl_value_get_string(value0); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_string(a_string, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_uint8_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_uint8_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + const uint8_t* list = fl_value_get_uint8_list(value0); + size_t list_length = fl_value_get_length(value0); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_uint8_list(list, list_length, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* list = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_list(list, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_enum_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* enum_list = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_enum_list(enum_list, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_class_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* class_list = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_class_list(class_list, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_non_null_enum_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* enum_list = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_non_null_enum_list(enum_list, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_non_null_class_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* class_list = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_non_null_class_list(class_list, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_map(map, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_string_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* string_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_string_map(string_map, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_int_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* int_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_int_map(int_map, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_enum_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* enum_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_enum_map(enum_map, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_class_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* class_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_class_map(class_map, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_string_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_non_null_string_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* string_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_non_null_string_map(string_map, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_int_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_non_null_int_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* int_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_non_null_int_map(int_map, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_non_null_enum_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* enum_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_non_null_enum_map(enum_map, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_non_null_class_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* class_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_non_null_class_map(class_map, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_enum == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + CoreTestsPigeonTestAnEnum an_enum = static_cast( + fl_value_get_int(reinterpret_cast( + const_cast(fl_value_get_custom_value(value0))))); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_enum(an_enum, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_enum_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_another_enum == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + CoreTestsPigeonTestAnotherEnum another_enum = + static_cast( + fl_value_get_int(reinterpret_cast( + const_cast(fl_value_get_custom_value(value0))))); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_another_enum(another_enum, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_bool_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_nullable_bool == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + gboolean* a_bool = nullptr; + gboolean a_bool_value; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + a_bool_value = fl_value_get_bool(value0); + a_bool = &a_bool_value; + } + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_nullable_bool(a_bool, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_nullable_int == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + int64_t* an_int = nullptr; + int64_t an_int_value; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + an_int_value = fl_value_get_int(value0); + an_int = &an_int_value; + } + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_nullable_int(an_int, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_double_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_nullable_double == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + double* a_double = nullptr; + double a_double_value; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + a_double_value = fl_value_get_float(value0); + a_double = &a_double_value; + } + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_nullable_double(a_double, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_nullable_string == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + const gchar* a_string = fl_value_get_string(value0); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_nullable_string(a_string, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_uint8_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_nullable_uint8_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + const uint8_t* list = fl_value_get_uint8_list(value0); + size_t list_length = fl_value_get_length(value0); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_nullable_uint8_list(list, list_length, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_nullable_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* list = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_nullable_list(list, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_nullable_enum_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* enum_list = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_nullable_enum_list(enum_list, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_nullable_class_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* class_list = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_nullable_class_list(class_list, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_nullable_non_null_enum_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* enum_list = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_nullable_non_null_enum_list(enum_list, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_nullable_non_null_class_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* class_list = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_nullable_non_null_class_list( + class_list, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_nullable_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_nullable_map(map, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_nullable_string_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* string_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_nullable_string_map(string_map, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_nullable_int_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* int_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_nullable_int_map(int_map, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_nullable_enum_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* enum_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_nullable_enum_map(enum_map, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_nullable_class_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* class_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_nullable_class_map(class_map, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_string_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_nullable_non_null_string_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* string_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_nullable_non_null_string_map( + string_map, handle, self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_int_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_nullable_non_null_int_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* int_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_nullable_non_null_int_map(int_map, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_nullable_non_null_enum_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* enum_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_nullable_non_null_enum_map(enum_map, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_map_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_nullable_non_null_class_map == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* class_map = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_nullable_non_null_class_map(class_map, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_nullable_enum == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + CoreTestsPigeonTestAnEnum* an_enum = nullptr; + CoreTestsPigeonTestAnEnum an_enum_value; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + an_enum_value = static_cast( + fl_value_get_int(reinterpret_cast( + const_cast(fl_value_get_custom_value(value0))))); + an_enum = &an_enum_value; + } + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_nullable_enum(an_enum, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_nullable_enum_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_echo_another_nullable_enum == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + CoreTestsPigeonTestAnotherEnum* another_enum = nullptr; + CoreTestsPigeonTestAnotherEnum another_enum_value; + if (fl_value_get_type(value0) != FL_VALUE_TYPE_NULL) { + another_enum_value = static_cast( + fl_value_get_int(reinterpret_cast( + const_cast(fl_value_get_custom_value(value0))))); + another_enum = &another_enum_value; + } + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_echo_another_nullable_enum(another_enum, handle, + self->user_data); +} + +static void +core_tests_pigeon_test_host_integration_core_api_call_flutter_small_api_echo_string_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || + self->vtable->call_flutter_small_api_echo_string == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + const gchar* a_string = fl_value_get_string(value0); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle) handle = + core_tests_pigeon_test_host_integration_core_api_response_handle_new( + channel, response_handle); + self->vtable->call_flutter_small_api_echo_string(a_string, handle, + self->user_data); +} + +void core_tests_pigeon_test_host_integration_core_api_set_method_handlers( + FlBinaryMessenger* messenger, const gchar* suffix, + const CoreTestsPigeonTestHostIntegrationCoreApiVTable* vtable, + gpointer user_data, GDestroyNotify user_data_free_func) { + g_autofree gchar* dot_suffix = + suffix != nullptr ? g_strdup_printf(".%s", suffix) : g_strdup(""); + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApi) api_data = + core_tests_pigeon_test_host_integration_core_api_new(vtable, user_data, + user_data_free_func); + + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + g_autofree gchar* noop_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.noop%" + "s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) noop_channel = fl_basic_message_channel_new( + messenger, noop_channel_name, FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + noop_channel, core_tests_pigeon_test_host_integration_core_api_noop_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_all_types_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAllTypes%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_all_types_channel = + fl_basic_message_channel_new(messenger, echo_all_types_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_all_types_channel, + core_tests_pigeon_test_host_integration_core_api_echo_all_types_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* throw_error_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "throwError%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) throw_error_channel = + fl_basic_message_channel_new(messenger, throw_error_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + throw_error_channel, + core_tests_pigeon_test_host_integration_core_api_throw_error_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* throw_error_from_void_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "throwErrorFromVoid%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) throw_error_from_void_channel = + fl_basic_message_channel_new(messenger, + throw_error_from_void_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + throw_error_from_void_channel, + core_tests_pigeon_test_host_integration_core_api_throw_error_from_void_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* throw_flutter_error_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "throwFlutterError%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) throw_flutter_error_channel = + fl_basic_message_channel_new(messenger, throw_flutter_error_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + throw_flutter_error_channel, + core_tests_pigeon_test_host_integration_core_api_throw_flutter_error_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_int_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoInt%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_int_channel = + fl_basic_message_channel_new(messenger, echo_int_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_int_channel, + core_tests_pigeon_test_host_integration_core_api_echo_int_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_double_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoDouble%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_double_channel = + fl_basic_message_channel_new(messenger, echo_double_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_double_channel, + core_tests_pigeon_test_host_integration_core_api_echo_double_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_bool_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoBool%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_bool_channel = + fl_basic_message_channel_new(messenger, echo_bool_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_bool_channel, + core_tests_pigeon_test_host_integration_core_api_echo_bool_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_string_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoString%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_string_channel = + fl_basic_message_channel_new(messenger, echo_string_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_string_channel, + core_tests_pigeon_test_host_integration_core_api_echo_string_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_uint8_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoUint8List%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_uint8_list_channel = + fl_basic_message_channel_new(messenger, echo_uint8_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_uint8_list_channel, + core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_object_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoObject%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_object_channel = + fl_basic_message_channel_new(messenger, echo_object_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_object_channel, + core_tests_pigeon_test_host_integration_core_api_echo_object_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_list_channel = + fl_basic_message_channel_new(messenger, echo_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_list_channel, + core_tests_pigeon_test_host_integration_core_api_echo_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_enum_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoEnumList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_enum_list_channel = + fl_basic_message_channel_new(messenger, echo_enum_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_enum_list_channel, + core_tests_pigeon_test_host_integration_core_api_echo_enum_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_class_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoClassList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_class_list_channel = + fl_basic_message_channel_new(messenger, echo_class_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_class_list_channel, + core_tests_pigeon_test_host_integration_core_api_echo_class_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_non_null_enum_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNonNullEnumList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_non_null_enum_list_channel = + fl_basic_message_channel_new(messenger, + echo_non_null_enum_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_non_null_enum_list_channel, + core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_non_null_class_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNonNullClassList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_non_null_class_list_channel = + fl_basic_message_channel_new(messenger, + echo_non_null_class_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_non_null_class_list_channel, + core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_map_channel = + fl_basic_message_channel_new(messenger, echo_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_string_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoStringMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_string_map_channel = + fl_basic_message_channel_new(messenger, echo_string_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_string_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_string_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_int_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoIntMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_int_map_channel = + fl_basic_message_channel_new(messenger, echo_int_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_int_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_int_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_enum_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoEnumMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_enum_map_channel = + fl_basic_message_channel_new(messenger, echo_enum_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_enum_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_enum_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_class_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoClassMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_class_map_channel = + fl_basic_message_channel_new(messenger, echo_class_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_class_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_class_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_non_null_string_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNonNullStringMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_non_null_string_map_channel = + fl_basic_message_channel_new(messenger, + echo_non_null_string_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_non_null_string_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_non_null_string_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_non_null_int_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNonNullIntMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_non_null_int_map_channel = + fl_basic_message_channel_new(messenger, + echo_non_null_int_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_non_null_int_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_non_null_int_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_non_null_enum_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNonNullEnumMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_non_null_enum_map_channel = + fl_basic_message_channel_new(messenger, + echo_non_null_enum_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_non_null_enum_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_non_null_class_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNonNullClassMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_non_null_class_map_channel = + fl_basic_message_channel_new(messenger, + echo_non_null_class_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_non_null_class_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_class_wrapper_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoClassWrapper%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_class_wrapper_channel = + fl_basic_message_channel_new(messenger, echo_class_wrapper_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_class_wrapper_channel, + core_tests_pigeon_test_host_integration_core_api_echo_class_wrapper_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_enum_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoEnum%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_enum_channel = + fl_basic_message_channel_new(messenger, echo_enum_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_enum_channel, + core_tests_pigeon_test_host_integration_core_api_echo_enum_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_another_enum_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAnotherEnum%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_another_enum_channel = + fl_basic_message_channel_new(messenger, echo_another_enum_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_another_enum_channel, + core_tests_pigeon_test_host_integration_core_api_echo_another_enum_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_named_default_string_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNamedDefaultString%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_named_default_string_channel = + fl_basic_message_channel_new(messenger, + echo_named_default_string_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_named_default_string_channel, + core_tests_pigeon_test_host_integration_core_api_echo_named_default_string_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_optional_default_double_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoOptionalDefaultDouble%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_optional_default_double_channel = + fl_basic_message_channel_new(messenger, + echo_optional_default_double_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_optional_default_double_channel, + core_tests_pigeon_test_host_integration_core_api_echo_optional_default_double_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_required_int_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoRequiredInt%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_required_int_channel = + fl_basic_message_channel_new(messenger, echo_required_int_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_required_int_channel, + core_tests_pigeon_test_host_integration_core_api_echo_required_int_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_all_nullable_types_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAllNullableTypes%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_all_nullable_types_channel = + fl_basic_message_channel_new(messenger, + echo_all_nullable_types_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_all_nullable_types_channel, + core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_all_nullable_types_without_recursion_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAllNullableTypesWithoutRecursion%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + echo_all_nullable_types_without_recursion_channel = + fl_basic_message_channel_new( + messenger, echo_all_nullable_types_without_recursion_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_all_nullable_types_without_recursion_channel, + core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_without_recursion_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* extract_nested_nullable_string_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "extractNestedNullableString%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) extract_nested_nullable_string_channel = + fl_basic_message_channel_new(messenger, + extract_nested_nullable_string_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + extract_nested_nullable_string_channel, + core_tests_pigeon_test_host_integration_core_api_extract_nested_nullable_string_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* create_nested_nullable_string_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "createNestedNullableString%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) create_nested_nullable_string_channel = + fl_basic_message_channel_new(messenger, + create_nested_nullable_string_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + create_nested_nullable_string_channel, + core_tests_pigeon_test_host_integration_core_api_create_nested_nullable_string_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* send_multiple_nullable_types_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "sendMultipleNullableTypes%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) send_multiple_nullable_types_channel = + fl_basic_message_channel_new(messenger, + send_multiple_nullable_types_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + send_multiple_nullable_types_channel, + core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* + send_multiple_nullable_types_without_recursion_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi." + "sendMultipleNullableTypesWithoutRecursion%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + send_multiple_nullable_types_without_recursion_channel = + fl_basic_message_channel_new( + messenger, + send_multiple_nullable_types_without_recursion_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + send_multiple_nullable_types_without_recursion_channel, + core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_without_recursion_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_nullable_int_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableInt%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_int_channel = + fl_basic_message_channel_new(messenger, echo_nullable_int_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_int_channel, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_nullable_double_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableDouble%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_double_channel = + fl_basic_message_channel_new(messenger, echo_nullable_double_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_double_channel, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_double_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_nullable_bool_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableBool%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_bool_channel = + fl_basic_message_channel_new(messenger, echo_nullable_bool_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_bool_channel, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_bool_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_nullable_string_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableString%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_string_channel = + fl_basic_message_channel_new(messenger, echo_nullable_string_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_string_channel, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_nullable_uint8_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableUint8List%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_uint8_list_channel = + fl_basic_message_channel_new(messenger, + echo_nullable_uint8_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_uint8_list_channel, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_uint8_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_nullable_object_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableObject%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_object_channel = + fl_basic_message_channel_new(messenger, echo_nullable_object_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_object_channel, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_object_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_nullable_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_list_channel = + fl_basic_message_channel_new(messenger, echo_nullable_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_list_channel, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_nullable_enum_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableEnumList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_enum_list_channel = + fl_basic_message_channel_new(messenger, + echo_nullable_enum_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_enum_list_channel, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_nullable_class_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableClassList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_class_list_channel = + fl_basic_message_channel_new(messenger, + echo_nullable_class_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_class_list_channel, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_nullable_non_null_enum_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableNonNullEnumList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_non_null_enum_list_channel = + fl_basic_message_channel_new( + messenger, echo_nullable_non_null_enum_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_non_null_enum_list_channel, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_nullable_non_null_class_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableNonNullClassList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_non_null_class_list_channel = + fl_basic_message_channel_new( + messenger, echo_nullable_non_null_class_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_non_null_class_list_channel, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_nullable_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_map_channel = + fl_basic_message_channel_new(messenger, echo_nullable_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_nullable_string_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableStringMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_string_map_channel = + fl_basic_message_channel_new(messenger, + echo_nullable_string_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_string_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_nullable_int_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableIntMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_int_map_channel = + fl_basic_message_channel_new(messenger, + echo_nullable_int_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_int_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_nullable_enum_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableEnumMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_enum_map_channel = + fl_basic_message_channel_new(messenger, + echo_nullable_enum_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_enum_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_nullable_class_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableClassMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_class_map_channel = + fl_basic_message_channel_new(messenger, + echo_nullable_class_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_class_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_nullable_non_null_string_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableNonNullStringMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_non_null_string_map_channel = + fl_basic_message_channel_new( + messenger, echo_nullable_non_null_string_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_non_null_string_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_string_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_nullable_non_null_int_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableNonNullIntMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_non_null_int_map_channel = + fl_basic_message_channel_new(messenger, + echo_nullable_non_null_int_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_non_null_int_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_int_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_nullable_non_null_enum_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableNonNullEnumMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_non_null_enum_map_channel = + fl_basic_message_channel_new(messenger, + echo_nullable_non_null_enum_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_non_null_enum_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_nullable_non_null_class_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableNonNullClassMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_non_null_class_map_channel = + fl_basic_message_channel_new( + messenger, echo_nullable_non_null_class_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_non_null_class_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_nullable_enum_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableEnum%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_enum_channel = + fl_basic_message_channel_new(messenger, echo_nullable_enum_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_enum_channel, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_another_nullable_enum_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAnotherNullableEnum%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_another_nullable_enum_channel = + fl_basic_message_channel_new(messenger, + echo_another_nullable_enum_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_another_nullable_enum_channel, + core_tests_pigeon_test_host_integration_core_api_echo_another_nullable_enum_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_optional_nullable_int_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoOptionalNullableInt%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_optional_nullable_int_channel = + fl_basic_message_channel_new(messenger, + echo_optional_nullable_int_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_optional_nullable_int_channel, + core_tests_pigeon_test_host_integration_core_api_echo_optional_nullable_int_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_named_nullable_string_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNamedNullableString%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_named_nullable_string_channel = + fl_basic_message_channel_new(messenger, + echo_named_nullable_string_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_named_nullable_string_channel, + core_tests_pigeon_test_host_integration_core_api_echo_named_nullable_string_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* noop_async_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "noopAsync%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) noop_async_channel = + fl_basic_message_channel_new(messenger, noop_async_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + noop_async_channel, + core_tests_pigeon_test_host_integration_core_api_noop_async_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_int_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncInt%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_int_channel = + fl_basic_message_channel_new(messenger, echo_async_int_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_int_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_int_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_double_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncDouble%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_double_channel = + fl_basic_message_channel_new(messenger, echo_async_double_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_double_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_double_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_bool_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncBool%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_bool_channel = + fl_basic_message_channel_new(messenger, echo_async_bool_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_bool_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_bool_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_string_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncString%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_string_channel = + fl_basic_message_channel_new(messenger, echo_async_string_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_string_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_string_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_uint8_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncUint8List%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_uint8_list_channel = + fl_basic_message_channel_new(messenger, + echo_async_uint8_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_uint8_list_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_uint8_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_object_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncObject%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_object_channel = + fl_basic_message_channel_new(messenger, echo_async_object_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_object_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_object_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_list_channel = + fl_basic_message_channel_new(messenger, echo_async_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_list_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_enum_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncEnumList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_enum_list_channel = + fl_basic_message_channel_new(messenger, echo_async_enum_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_enum_list_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_class_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncClassList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_class_list_channel = + fl_basic_message_channel_new(messenger, + echo_async_class_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_class_list_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_class_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_map_channel = + fl_basic_message_channel_new(messenger, echo_async_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_string_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncStringMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_string_map_channel = + fl_basic_message_channel_new(messenger, + echo_async_string_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_string_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_string_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_int_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncIntMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_int_map_channel = + fl_basic_message_channel_new(messenger, echo_async_int_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_int_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_int_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_enum_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncEnumMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_enum_map_channel = + fl_basic_message_channel_new(messenger, echo_async_enum_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_enum_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_class_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncClassMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_class_map_channel = + fl_basic_message_channel_new(messenger, echo_async_class_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_class_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_class_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_enum_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncEnum%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_enum_channel = + fl_basic_message_channel_new(messenger, echo_async_enum_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_enum_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_another_async_enum_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAnotherAsyncEnum%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_another_async_enum_channel = + fl_basic_message_channel_new(messenger, + echo_another_async_enum_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_another_async_enum_channel, + core_tests_pigeon_test_host_integration_core_api_echo_another_async_enum_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* throw_async_error_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "throwAsyncError%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) throw_async_error_channel = + fl_basic_message_channel_new(messenger, throw_async_error_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + throw_async_error_channel, + core_tests_pigeon_test_host_integration_core_api_throw_async_error_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* throw_async_error_from_void_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "throwAsyncErrorFromVoid%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) throw_async_error_from_void_channel = + fl_basic_message_channel_new(messenger, + throw_async_error_from_void_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + throw_async_error_from_void_channel, + core_tests_pigeon_test_host_integration_core_api_throw_async_error_from_void_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* throw_async_flutter_error_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "throwAsyncFlutterError%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) throw_async_flutter_error_channel = + fl_basic_message_channel_new(messenger, + throw_async_flutter_error_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + throw_async_flutter_error_channel, + core_tests_pigeon_test_host_integration_core_api_throw_async_flutter_error_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_all_types_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncAllTypes%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_all_types_channel = + fl_basic_message_channel_new(messenger, echo_async_all_types_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_all_types_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_all_types_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_nullable_all_nullable_types_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableAllNullableTypes%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + echo_async_nullable_all_nullable_types_channel = + fl_basic_message_channel_new( + messenger, echo_async_nullable_all_nullable_types_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_all_nullable_types_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* + echo_async_nullable_all_nullable_types_without_recursion_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi." + "echoAsyncNullableAllNullableTypesWithoutRecursion%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + echo_async_nullable_all_nullable_types_without_recursion_channel = + fl_basic_message_channel_new( + messenger, + echo_async_nullable_all_nullable_types_without_recursion_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_all_nullable_types_without_recursion_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_without_recursion_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_nullable_int_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableInt%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_int_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_int_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_int_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_nullable_double_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableDouble%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_double_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_double_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_double_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_double_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_nullable_bool_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableBool%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_bool_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_bool_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_bool_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_bool_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_nullable_string_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableString%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_string_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_string_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_string_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_nullable_uint8_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableUint8List%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_uint8_list_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_uint8_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_uint8_list_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_uint8_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_nullable_object_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableObject%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_object_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_object_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_object_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_object_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_nullable_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_list_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_list_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_nullable_enum_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableEnumList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_enum_list_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_enum_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_enum_list_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_nullable_class_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableClassList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_class_list_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_class_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_class_list_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_nullable_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_map_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_nullable_string_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableStringMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_string_map_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_string_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_string_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_nullable_int_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableIntMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_int_map_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_int_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_int_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_nullable_enum_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableEnumMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_enum_map_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_enum_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_enum_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_nullable_class_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableClassMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_class_map_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_class_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_class_map_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_async_nullable_enum_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableEnum%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_enum_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_enum_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_enum_channel, + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_another_async_nullable_enum_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAnotherAsyncNullableEnum%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_another_async_nullable_enum_channel = + fl_basic_message_channel_new( + messenger, echo_another_async_nullable_enum_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_another_async_nullable_enum_channel, + core_tests_pigeon_test_host_integration_core_api_echo_another_async_nullable_enum_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_noop_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterNoop%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_noop_channel = + fl_basic_message_channel_new(messenger, call_flutter_noop_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_noop_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_noop_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_throw_error_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterThrowError%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_throw_error_channel = + fl_basic_message_channel_new(messenger, + call_flutter_throw_error_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_throw_error_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_throw_error_from_void_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterThrowErrorFromVoid%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_throw_error_from_void_channel = + fl_basic_message_channel_new( + messenger, call_flutter_throw_error_from_void_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_throw_error_from_void_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_from_void_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_all_types_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoAllTypes%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_all_types_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_all_types_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_all_types_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_types_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_all_nullable_types_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoAllNullableTypes%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_all_nullable_types_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_all_nullable_types_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_all_nullable_types_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_send_multiple_nullable_types_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterSendMultipleNullableTypes%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_send_multiple_nullable_types_channel = + fl_basic_message_channel_new( + messenger, call_flutter_send_multiple_nullable_types_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_send_multiple_nullable_types_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* + call_flutter_echo_all_nullable_types_without_recursion_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi." + "callFlutterEchoAllNullableTypesWithoutRecursion%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_all_nullable_types_without_recursion_channel = + fl_basic_message_channel_new( + messenger, + call_flutter_echo_all_nullable_types_without_recursion_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_all_nullable_types_without_recursion_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_without_recursion_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* + call_flutter_send_multiple_nullable_types_without_recursion_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi." + "callFlutterSendMultipleNullableTypesWithoutRecursion%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_send_multiple_nullable_types_without_recursion_channel = + fl_basic_message_channel_new( + messenger, + call_flutter_send_multiple_nullable_types_without_recursion_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_send_multiple_nullable_types_without_recursion_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_without_recursion_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_bool_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoBool%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_bool_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_bool_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_bool_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_bool_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_int_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoInt%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_int_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_int_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_int_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_double_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoDouble%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_double_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_double_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_double_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_double_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_string_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoString%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_string_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_string_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_string_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_uint8_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoUint8List%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_uint8_list_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_uint8_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_uint8_list_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_uint8_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_list_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_list_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_enum_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoEnumList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_enum_list_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_enum_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_enum_list_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_class_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoClassList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_class_list_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_class_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_class_list_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_non_null_enum_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNonNullEnumList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_non_null_enum_list_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_non_null_enum_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_non_null_enum_list_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_non_null_class_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNonNullClassList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_non_null_class_list_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_non_null_class_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_non_null_class_list_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_map_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_map_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_string_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoStringMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_string_map_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_string_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_string_map_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_int_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoIntMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_int_map_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_int_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_int_map_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_enum_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoEnumMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_enum_map_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_enum_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_enum_map_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_class_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoClassMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_class_map_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_class_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_class_map_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_non_null_string_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNonNullStringMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_non_null_string_map_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_non_null_string_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_non_null_string_map_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_string_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_non_null_int_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNonNullIntMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_non_null_int_map_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_non_null_int_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_non_null_int_map_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_int_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_non_null_enum_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNonNullEnumMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_non_null_enum_map_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_non_null_enum_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_non_null_enum_map_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_non_null_class_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNonNullClassMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_non_null_class_map_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_non_null_class_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_non_null_class_map_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_enum_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoEnum%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_enum_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_enum_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_enum_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_another_enum_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoAnotherEnum%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_another_enum_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_another_enum_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_another_enum_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_enum_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_nullable_bool_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableBool%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_nullable_bool_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_nullable_bool_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_bool_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_bool_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_nullable_int_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableInt%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_nullable_int_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_nullable_int_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_int_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_nullable_double_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableDouble%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_nullable_double_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_nullable_double_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_double_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_double_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_nullable_string_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableString%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_nullable_string_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_nullable_string_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_string_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_nullable_uint8_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableUint8List%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_nullable_uint8_list_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_nullable_uint8_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_uint8_list_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_uint8_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_nullable_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_nullable_list_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_nullable_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_list_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_nullable_enum_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableEnumList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_nullable_enum_list_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_nullable_enum_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_enum_list_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_nullable_class_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableClassList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_nullable_class_list_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_nullable_class_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_class_list_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_nullable_non_null_enum_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableNonNullEnumList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_nullable_non_null_enum_list_channel = + fl_basic_message_channel_new( + messenger, + call_flutter_echo_nullable_non_null_enum_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_non_null_enum_list_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* + call_flutter_echo_nullable_non_null_class_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.callFlutterEchoNullableNonNullClassList%" + "s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_nullable_non_null_class_list_channel = + fl_basic_message_channel_new( + messenger, + call_flutter_echo_nullable_non_null_class_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_non_null_class_list_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_nullable_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_nullable_map_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_nullable_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_map_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_nullable_string_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableStringMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_nullable_string_map_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_nullable_string_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_string_map_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_nullable_int_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableIntMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_nullable_int_map_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_nullable_int_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_int_map_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_nullable_enum_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableEnumMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_nullable_enum_map_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_nullable_enum_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_enum_map_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_nullable_class_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableClassMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_nullable_class_map_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_nullable_class_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_class_map_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* + call_flutter_echo_nullable_non_null_string_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.callFlutterEchoNullableNonNullStringMap%" + "s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_nullable_non_null_string_map_channel = + fl_basic_message_channel_new( + messenger, + call_flutter_echo_nullable_non_null_string_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_non_null_string_map_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_string_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_nullable_non_null_int_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableNonNullIntMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_nullable_non_null_int_map_channel = + fl_basic_message_channel_new( + messenger, + call_flutter_echo_nullable_non_null_int_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_non_null_int_map_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_int_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_nullable_non_null_enum_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableNonNullEnumMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_nullable_non_null_enum_map_channel = + fl_basic_message_channel_new( + messenger, + call_flutter_echo_nullable_non_null_enum_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_non_null_enum_map_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_nullable_non_null_class_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableNonNullClassMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_nullable_non_null_class_map_channel = + fl_basic_message_channel_new( + messenger, + call_flutter_echo_nullable_non_null_class_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_non_null_class_map_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_map_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_nullable_enum_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableEnum%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_nullable_enum_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_nullable_enum_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_enum_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_echo_another_nullable_enum_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoAnotherNullableEnum%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_another_nullable_enum_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_another_nullable_enum_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_another_nullable_enum_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_nullable_enum_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* call_flutter_small_api_echo_string_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterSmallApiEchoString%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_small_api_echo_string_channel = + fl_basic_message_channel_new( + messenger, call_flutter_small_api_echo_string_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_small_api_echo_string_channel, + core_tests_pigeon_test_host_integration_core_api_call_flutter_small_api_echo_string_cb, + g_object_ref(api_data), g_object_unref); +} + +void core_tests_pigeon_test_host_integration_core_api_clear_method_handlers( + FlBinaryMessenger* messenger, const gchar* suffix) { + g_autofree gchar* dot_suffix = + suffix != nullptr ? g_strdup_printf(".%s", suffix) : g_strdup(""); + + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + g_autofree gchar* noop_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.noop%" + "s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) noop_channel = fl_basic_message_channel_new( + messenger, noop_channel_name, FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(noop_channel, nullptr, nullptr, + nullptr); + g_autofree gchar* echo_all_types_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAllTypes%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_all_types_channel = + fl_basic_message_channel_new(messenger, echo_all_types_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_all_types_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* throw_error_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "throwError%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) throw_error_channel = + fl_basic_message_channel_new(messenger, throw_error_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(throw_error_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* throw_error_from_void_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "throwErrorFromVoid%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) throw_error_from_void_channel = + fl_basic_message_channel_new(messenger, + throw_error_from_void_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(throw_error_from_void_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* throw_flutter_error_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "throwFlutterError%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) throw_flutter_error_channel = + fl_basic_message_channel_new(messenger, throw_flutter_error_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(throw_flutter_error_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_int_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoInt%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_int_channel = + fl_basic_message_channel_new(messenger, echo_int_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_int_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* echo_double_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoDouble%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_double_channel = + fl_basic_message_channel_new(messenger, echo_double_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_double_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* echo_bool_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoBool%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_bool_channel = + fl_basic_message_channel_new(messenger, echo_bool_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_bool_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* echo_string_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoString%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_string_channel = + fl_basic_message_channel_new(messenger, echo_string_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_string_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* echo_uint8_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoUint8List%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_uint8_list_channel = + fl_basic_message_channel_new(messenger, echo_uint8_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_uint8_list_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* echo_object_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoObject%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_object_channel = + fl_basic_message_channel_new(messenger, echo_object_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_object_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* echo_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_list_channel = + fl_basic_message_channel_new(messenger, echo_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_list_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* echo_enum_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoEnumList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_enum_list_channel = + fl_basic_message_channel_new(messenger, echo_enum_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_enum_list_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* echo_class_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoClassList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_class_list_channel = + fl_basic_message_channel_new(messenger, echo_class_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_class_list_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* echo_non_null_enum_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNonNullEnumList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_non_null_enum_list_channel = + fl_basic_message_channel_new(messenger, + echo_non_null_enum_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_non_null_enum_list_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_non_null_class_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNonNullClassList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_non_null_class_list_channel = + fl_basic_message_channel_new(messenger, + echo_non_null_class_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_non_null_class_list_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_map_channel = + fl_basic_message_channel_new(messenger, echo_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_map_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* echo_string_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoStringMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_string_map_channel = + fl_basic_message_channel_new(messenger, echo_string_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_string_map_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* echo_int_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoIntMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_int_map_channel = + fl_basic_message_channel_new(messenger, echo_int_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_int_map_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* echo_enum_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoEnumMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_enum_map_channel = + fl_basic_message_channel_new(messenger, echo_enum_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_enum_map_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* echo_class_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoClassMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_class_map_channel = + fl_basic_message_channel_new(messenger, echo_class_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_class_map_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* echo_non_null_string_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNonNullStringMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_non_null_string_map_channel = + fl_basic_message_channel_new(messenger, + echo_non_null_string_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_non_null_string_map_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_non_null_int_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNonNullIntMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_non_null_int_map_channel = + fl_basic_message_channel_new(messenger, + echo_non_null_int_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_non_null_int_map_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_non_null_enum_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNonNullEnumMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_non_null_enum_map_channel = + fl_basic_message_channel_new(messenger, + echo_non_null_enum_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_non_null_enum_map_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_non_null_class_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNonNullClassMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_non_null_class_map_channel = + fl_basic_message_channel_new(messenger, + echo_non_null_class_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_non_null_class_map_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_class_wrapper_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoClassWrapper%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_class_wrapper_channel = + fl_basic_message_channel_new(messenger, echo_class_wrapper_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_class_wrapper_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_enum_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoEnum%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_enum_channel = + fl_basic_message_channel_new(messenger, echo_enum_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_enum_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* echo_another_enum_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAnotherEnum%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_another_enum_channel = + fl_basic_message_channel_new(messenger, echo_another_enum_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_another_enum_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_named_default_string_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNamedDefaultString%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_named_default_string_channel = + fl_basic_message_channel_new(messenger, + echo_named_default_string_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_named_default_string_channel, nullptr, nullptr, nullptr); + g_autofree gchar* echo_optional_default_double_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoOptionalDefaultDouble%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_optional_default_double_channel = + fl_basic_message_channel_new(messenger, + echo_optional_default_double_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_optional_default_double_channel, nullptr, nullptr, nullptr); + g_autofree gchar* echo_required_int_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoRequiredInt%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_required_int_channel = + fl_basic_message_channel_new(messenger, echo_required_int_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_required_int_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_all_nullable_types_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAllNullableTypes%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_all_nullable_types_channel = + fl_basic_message_channel_new(messenger, + echo_all_nullable_types_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_all_nullable_types_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_all_nullable_types_without_recursion_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAllNullableTypesWithoutRecursion%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + echo_all_nullable_types_without_recursion_channel = + fl_basic_message_channel_new( + messenger, echo_all_nullable_types_without_recursion_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_all_nullable_types_without_recursion_channel, nullptr, nullptr, + nullptr); + g_autofree gchar* extract_nested_nullable_string_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "extractNestedNullableString%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) extract_nested_nullable_string_channel = + fl_basic_message_channel_new(messenger, + extract_nested_nullable_string_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + extract_nested_nullable_string_channel, nullptr, nullptr, nullptr); + g_autofree gchar* create_nested_nullable_string_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "createNestedNullableString%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) create_nested_nullable_string_channel = + fl_basic_message_channel_new(messenger, + create_nested_nullable_string_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + create_nested_nullable_string_channel, nullptr, nullptr, nullptr); + g_autofree gchar* send_multiple_nullable_types_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "sendMultipleNullableTypes%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) send_multiple_nullable_types_channel = + fl_basic_message_channel_new(messenger, + send_multiple_nullable_types_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + send_multiple_nullable_types_channel, nullptr, nullptr, nullptr); + g_autofree gchar* + send_multiple_nullable_types_without_recursion_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi." + "sendMultipleNullableTypesWithoutRecursion%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + send_multiple_nullable_types_without_recursion_channel = + fl_basic_message_channel_new( + messenger, + send_multiple_nullable_types_without_recursion_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + send_multiple_nullable_types_without_recursion_channel, nullptr, nullptr, + nullptr); + g_autofree gchar* echo_nullable_int_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableInt%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_int_channel = + fl_basic_message_channel_new(messenger, echo_nullable_int_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_nullable_int_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_nullable_double_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableDouble%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_double_channel = + fl_basic_message_channel_new(messenger, echo_nullable_double_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_nullable_double_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_nullable_bool_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableBool%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_bool_channel = + fl_basic_message_channel_new(messenger, echo_nullable_bool_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_nullable_bool_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_nullable_string_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableString%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_string_channel = + fl_basic_message_channel_new(messenger, echo_nullable_string_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_nullable_string_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_nullable_uint8_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableUint8List%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_uint8_list_channel = + fl_basic_message_channel_new(messenger, + echo_nullable_uint8_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_nullable_uint8_list_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_nullable_object_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableObject%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_object_channel = + fl_basic_message_channel_new(messenger, echo_nullable_object_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_nullable_object_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_nullable_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_list_channel = + fl_basic_message_channel_new(messenger, echo_nullable_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_nullable_list_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_nullable_enum_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableEnumList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_enum_list_channel = + fl_basic_message_channel_new(messenger, + echo_nullable_enum_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_nullable_enum_list_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_nullable_class_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableClassList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_class_list_channel = + fl_basic_message_channel_new(messenger, + echo_nullable_class_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_nullable_class_list_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_nullable_non_null_enum_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableNonNullEnumList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_non_null_enum_list_channel = + fl_basic_message_channel_new( + messenger, echo_nullable_non_null_enum_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_non_null_enum_list_channel, nullptr, nullptr, nullptr); + g_autofree gchar* echo_nullable_non_null_class_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableNonNullClassList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_non_null_class_list_channel = + fl_basic_message_channel_new( + messenger, echo_nullable_non_null_class_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_non_null_class_list_channel, nullptr, nullptr, nullptr); + g_autofree gchar* echo_nullable_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_map_channel = + fl_basic_message_channel_new(messenger, echo_nullable_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_nullable_map_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_nullable_string_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableStringMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_string_map_channel = + fl_basic_message_channel_new(messenger, + echo_nullable_string_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_nullable_string_map_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_nullable_int_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableIntMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_int_map_channel = + fl_basic_message_channel_new(messenger, + echo_nullable_int_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_nullable_int_map_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_nullable_enum_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableEnumMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_enum_map_channel = + fl_basic_message_channel_new(messenger, + echo_nullable_enum_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_nullable_enum_map_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_nullable_class_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableClassMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_class_map_channel = + fl_basic_message_channel_new(messenger, + echo_nullable_class_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_nullable_class_map_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_nullable_non_null_string_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableNonNullStringMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_non_null_string_map_channel = + fl_basic_message_channel_new( + messenger, echo_nullable_non_null_string_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_non_null_string_map_channel, nullptr, nullptr, nullptr); + g_autofree gchar* echo_nullable_non_null_int_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableNonNullIntMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_non_null_int_map_channel = + fl_basic_message_channel_new(messenger, + echo_nullable_non_null_int_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_non_null_int_map_channel, nullptr, nullptr, nullptr); + g_autofree gchar* echo_nullable_non_null_enum_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableNonNullEnumMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_non_null_enum_map_channel = + fl_basic_message_channel_new(messenger, + echo_nullable_non_null_enum_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_non_null_enum_map_channel, nullptr, nullptr, nullptr); + g_autofree gchar* echo_nullable_non_null_class_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableNonNullClassMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_non_null_class_map_channel = + fl_basic_message_channel_new( + messenger, echo_nullable_non_null_class_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_nullable_non_null_class_map_channel, nullptr, nullptr, nullptr); + g_autofree gchar* echo_nullable_enum_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableEnum%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_nullable_enum_channel = + fl_basic_message_channel_new(messenger, echo_nullable_enum_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_nullable_enum_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_another_nullable_enum_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAnotherNullableEnum%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_another_nullable_enum_channel = + fl_basic_message_channel_new(messenger, + echo_another_nullable_enum_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_another_nullable_enum_channel, nullptr, nullptr, nullptr); + g_autofree gchar* echo_optional_nullable_int_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoOptionalNullableInt%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_optional_nullable_int_channel = + fl_basic_message_channel_new(messenger, + echo_optional_nullable_int_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_optional_nullable_int_channel, nullptr, nullptr, nullptr); + g_autofree gchar* echo_named_nullable_string_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNamedNullableString%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_named_nullable_string_channel = + fl_basic_message_channel_new(messenger, + echo_named_nullable_string_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_named_nullable_string_channel, nullptr, nullptr, nullptr); + g_autofree gchar* noop_async_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "noopAsync%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) noop_async_channel = + fl_basic_message_channel_new(messenger, noop_async_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(noop_async_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* echo_async_int_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncInt%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_int_channel = + fl_basic_message_channel_new(messenger, echo_async_int_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_async_int_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* echo_async_double_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncDouble%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_double_channel = + fl_basic_message_channel_new(messenger, echo_async_double_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_async_double_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_bool_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncBool%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_bool_channel = + fl_basic_message_channel_new(messenger, echo_async_bool_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_async_bool_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* echo_async_string_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncString%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_string_channel = + fl_basic_message_channel_new(messenger, echo_async_string_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_async_string_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_uint8_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncUint8List%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_uint8_list_channel = + fl_basic_message_channel_new(messenger, + echo_async_uint8_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_async_uint8_list_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_object_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncObject%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_object_channel = + fl_basic_message_channel_new(messenger, echo_async_object_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_async_object_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_list_channel = + fl_basic_message_channel_new(messenger, echo_async_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_async_list_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* echo_async_enum_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncEnumList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_enum_list_channel = + fl_basic_message_channel_new(messenger, echo_async_enum_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_async_enum_list_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_class_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncClassList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_class_list_channel = + fl_basic_message_channel_new(messenger, + echo_async_class_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_async_class_list_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_map_channel = + fl_basic_message_channel_new(messenger, echo_async_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_async_map_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* echo_async_string_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncStringMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_string_map_channel = + fl_basic_message_channel_new(messenger, + echo_async_string_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_async_string_map_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_int_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncIntMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_int_map_channel = + fl_basic_message_channel_new(messenger, echo_async_int_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_async_int_map_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_enum_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncEnumMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_enum_map_channel = + fl_basic_message_channel_new(messenger, echo_async_enum_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_async_enum_map_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_class_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncClassMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_class_map_channel = + fl_basic_message_channel_new(messenger, echo_async_class_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_async_class_map_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_enum_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncEnum%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_enum_channel = + fl_basic_message_channel_new(messenger, echo_async_enum_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_async_enum_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* echo_another_async_enum_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAnotherAsyncEnum%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_another_async_enum_channel = + fl_basic_message_channel_new(messenger, + echo_another_async_enum_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_another_async_enum_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* throw_async_error_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "throwAsyncError%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) throw_async_error_channel = + fl_basic_message_channel_new(messenger, throw_async_error_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(throw_async_error_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* throw_async_error_from_void_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "throwAsyncErrorFromVoid%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) throw_async_error_from_void_channel = + fl_basic_message_channel_new(messenger, + throw_async_error_from_void_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + throw_async_error_from_void_channel, nullptr, nullptr, nullptr); + g_autofree gchar* throw_async_flutter_error_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "throwAsyncFlutterError%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) throw_async_flutter_error_channel = + fl_basic_message_channel_new(messenger, + throw_async_flutter_error_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + throw_async_flutter_error_channel, nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_all_types_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncAllTypes%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_all_types_channel = + fl_basic_message_channel_new(messenger, echo_async_all_types_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_async_all_types_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_nullable_all_nullable_types_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableAllNullableTypes%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + echo_async_nullable_all_nullable_types_channel = + fl_basic_message_channel_new( + messenger, echo_async_nullable_all_nullable_types_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_all_nullable_types_channel, nullptr, nullptr, + nullptr); + g_autofree gchar* + echo_async_nullable_all_nullable_types_without_recursion_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi." + "echoAsyncNullableAllNullableTypesWithoutRecursion%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + echo_async_nullable_all_nullable_types_without_recursion_channel = + fl_basic_message_channel_new( + messenger, + echo_async_nullable_all_nullable_types_without_recursion_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_all_nullable_types_without_recursion_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* echo_async_nullable_int_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableInt%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_int_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_int_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_async_nullable_int_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_nullable_double_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableDouble%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_double_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_double_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_double_channel, nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_nullable_bool_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableBool%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_bool_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_bool_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_async_nullable_bool_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_nullable_string_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableString%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_string_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_string_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_string_channel, nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_nullable_uint8_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableUint8List%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_uint8_list_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_uint8_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_uint8_list_channel, nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_nullable_object_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableObject%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_object_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_object_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_object_channel, nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_nullable_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_list_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_async_nullable_list_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_nullable_enum_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableEnumList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_enum_list_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_enum_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_enum_list_channel, nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_nullable_class_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableClassList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_class_list_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_class_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_class_list_channel, nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_nullable_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_map_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_async_nullable_map_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_nullable_string_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableStringMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_string_map_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_string_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_string_map_channel, nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_nullable_int_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableIntMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_int_map_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_int_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_int_map_channel, nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_nullable_enum_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableEnumMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_enum_map_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_enum_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_enum_map_channel, nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_nullable_class_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableClassMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_class_map_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_class_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_async_nullable_class_map_channel, nullptr, nullptr, nullptr); + g_autofree gchar* echo_async_nullable_enum_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableEnum%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_async_nullable_enum_channel = + fl_basic_message_channel_new(messenger, + echo_async_nullable_enum_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_async_nullable_enum_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_another_async_nullable_enum_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAnotherAsyncNullableEnum%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_another_async_nullable_enum_channel = + fl_basic_message_channel_new( + messenger, echo_another_async_nullable_enum_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_another_async_nullable_enum_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_noop_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterNoop%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_noop_channel = + fl_basic_message_channel_new(messenger, call_flutter_noop_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(call_flutter_noop_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_throw_error_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterThrowError%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_throw_error_channel = + fl_basic_message_channel_new(messenger, + call_flutter_throw_error_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(call_flutter_throw_error_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_throw_error_from_void_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterThrowErrorFromVoid%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_throw_error_from_void_channel = + fl_basic_message_channel_new( + messenger, call_flutter_throw_error_from_void_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_throw_error_from_void_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_all_types_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoAllTypes%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_all_types_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_all_types_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_all_types_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_all_nullable_types_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoAllNullableTypes%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_all_nullable_types_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_all_nullable_types_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_all_nullable_types_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_send_multiple_nullable_types_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterSendMultipleNullableTypes%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_send_multiple_nullable_types_channel = + fl_basic_message_channel_new( + messenger, call_flutter_send_multiple_nullable_types_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_send_multiple_nullable_types_channel, nullptr, nullptr, + nullptr); + g_autofree gchar* + call_flutter_echo_all_nullable_types_without_recursion_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi." + "callFlutterEchoAllNullableTypesWithoutRecursion%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_all_nullable_types_without_recursion_channel = + fl_basic_message_channel_new( + messenger, + call_flutter_echo_all_nullable_types_without_recursion_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_all_nullable_types_without_recursion_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* + call_flutter_send_multiple_nullable_types_without_recursion_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi." + "callFlutterSendMultipleNullableTypesWithoutRecursion%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_send_multiple_nullable_types_without_recursion_channel = + fl_basic_message_channel_new( + messenger, + call_flutter_send_multiple_nullable_types_without_recursion_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_send_multiple_nullable_types_without_recursion_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_bool_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoBool%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_bool_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_bool_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(call_flutter_echo_bool_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_int_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoInt%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_int_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_int_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(call_flutter_echo_int_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_double_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoDouble%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_double_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_double_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(call_flutter_echo_double_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_string_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoString%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_string_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_string_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(call_flutter_echo_string_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_uint8_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoUint8List%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_uint8_list_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_uint8_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_uint8_list_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_list_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(call_flutter_echo_list_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_enum_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoEnumList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_enum_list_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_enum_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_enum_list_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_class_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoClassList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_class_list_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_class_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_class_list_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_non_null_enum_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNonNullEnumList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_non_null_enum_list_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_non_null_enum_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_non_null_enum_list_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_non_null_class_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNonNullClassList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_non_null_class_list_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_non_null_class_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_non_null_class_list_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_map_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(call_flutter_echo_map_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_string_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoStringMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_string_map_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_string_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_string_map_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_int_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoIntMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_int_map_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_int_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_int_map_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_enum_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoEnumMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_enum_map_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_enum_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_enum_map_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_class_map_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoClassMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_class_map_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_class_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_class_map_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_non_null_string_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNonNullStringMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_non_null_string_map_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_non_null_string_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_non_null_string_map_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_non_null_int_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNonNullIntMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_non_null_int_map_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_non_null_int_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_non_null_int_map_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_non_null_enum_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNonNullEnumMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_non_null_enum_map_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_non_null_enum_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_non_null_enum_map_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_non_null_class_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNonNullClassMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_non_null_class_map_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_non_null_class_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_non_null_class_map_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_enum_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoEnum%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_enum_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_enum_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(call_flutter_echo_enum_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_another_enum_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoAnotherEnum%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_another_enum_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_another_enum_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_another_enum_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_nullable_bool_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableBool%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_nullable_bool_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_nullable_bool_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_bool_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_nullable_int_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableInt%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_nullable_int_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_nullable_int_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_int_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_nullable_double_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableDouble%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_nullable_double_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_nullable_double_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_double_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_nullable_string_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableString%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_nullable_string_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_nullable_string_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_string_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_nullable_uint8_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableUint8List%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_nullable_uint8_list_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_nullable_uint8_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_uint8_list_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_nullable_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_nullable_list_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_nullable_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_list_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_nullable_enum_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableEnumList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_nullable_enum_list_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_nullable_enum_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_enum_list_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_nullable_class_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableClassList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_nullable_class_list_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_nullable_class_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_class_list_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_nullable_non_null_enum_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableNonNullEnumList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_nullable_non_null_enum_list_channel = + fl_basic_message_channel_new( + messenger, + call_flutter_echo_nullable_non_null_enum_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_non_null_enum_list_channel, nullptr, nullptr, + nullptr); + g_autofree gchar* + call_flutter_echo_nullable_non_null_class_list_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.callFlutterEchoNullableNonNullClassList%" + "s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_nullable_non_null_class_list_channel = + fl_basic_message_channel_new( + messenger, + call_flutter_echo_nullable_non_null_class_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_non_null_class_list_channel, nullptr, nullptr, + nullptr); + g_autofree gchar* call_flutter_echo_nullable_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_nullable_map_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_nullable_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_map_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_nullable_string_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableStringMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_nullable_string_map_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_nullable_string_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_string_map_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_nullable_int_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableIntMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_nullable_int_map_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_nullable_int_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_int_map_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_nullable_enum_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableEnumMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_nullable_enum_map_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_nullable_enum_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_enum_map_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_nullable_class_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableClassMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_nullable_class_map_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_nullable_class_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_class_map_channel, nullptr, nullptr, nullptr); + g_autofree gchar* + call_flutter_echo_nullable_non_null_string_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.callFlutterEchoNullableNonNullStringMap%" + "s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_nullable_non_null_string_map_channel = + fl_basic_message_channel_new( + messenger, + call_flutter_echo_nullable_non_null_string_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_non_null_string_map_channel, nullptr, nullptr, + nullptr); + g_autofree gchar* call_flutter_echo_nullable_non_null_int_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableNonNullIntMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_nullable_non_null_int_map_channel = + fl_basic_message_channel_new( + messenger, + call_flutter_echo_nullable_non_null_int_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_non_null_int_map_channel, nullptr, nullptr, + nullptr); + g_autofree gchar* call_flutter_echo_nullable_non_null_enum_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableNonNullEnumMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_nullable_non_null_enum_map_channel = + fl_basic_message_channel_new( + messenger, + call_flutter_echo_nullable_non_null_enum_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_non_null_enum_map_channel, nullptr, nullptr, + nullptr); + g_autofree gchar* call_flutter_echo_nullable_non_null_class_map_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableNonNullClassMap%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_nullable_non_null_class_map_channel = + fl_basic_message_channel_new( + messenger, + call_flutter_echo_nullable_non_null_class_map_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_non_null_class_map_channel, nullptr, nullptr, + nullptr); + g_autofree gchar* call_flutter_echo_nullable_enum_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableEnum%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_echo_nullable_enum_channel = + fl_basic_message_channel_new(messenger, + call_flutter_echo_nullable_enum_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_nullable_enum_channel, nullptr, nullptr, nullptr); + g_autofree gchar* call_flutter_echo_another_nullable_enum_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoAnotherNullableEnum%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) + call_flutter_echo_another_nullable_enum_channel = + fl_basic_message_channel_new( + messenger, call_flutter_echo_another_nullable_enum_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_echo_another_nullable_enum_channel, nullptr, nullptr, + nullptr); + g_autofree gchar* call_flutter_small_api_echo_string_channel_name = + g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterSmallApiEchoString%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) call_flutter_small_api_echo_string_channel = + fl_basic_message_channel_new( + messenger, call_flutter_small_api_echo_string_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + call_flutter_small_api_echo_string_channel, nullptr, nullptr, nullptr); +} + +void core_tests_pigeon_test_host_integration_core_api_respond_noop_async( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiNoopAsyncResponse) response = + core_tests_pigeon_test_host_integration_core_api_noop_async_response_new(); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "noopAsync", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_noop_async( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiNoopAsyncResponse) response = + core_tests_pigeon_test_host_integration_core_api_noop_async_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "noopAsync", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_int( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + int64_t return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncIntResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_int_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncInt", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_int( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncIntResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_int_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncInt", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_double( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + double return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncDoubleResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_double_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncDouble", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_double( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncDoubleResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_double_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncDouble", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_bool( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gboolean return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncBoolResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_bool_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncBool", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_bool( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncBoolResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_bool_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncBool", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_string( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncStringResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_string_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncString", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_string( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncStringResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_string_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncString", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_uint8_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const uint8_t* return_value, size_t return_value_length) { + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncUint8ListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_uint8_list_response_new( + return_value, return_value_length); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncUint8List", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_uint8_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncUint8ListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_uint8_list_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncUint8List", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_object( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncObjectResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_object_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncObject", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_object( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncObjectResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_object_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncObject", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncListResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_list_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncListResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_list_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_enum_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumListResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_list_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncEnumList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_enum_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumListResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_list_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncEnumList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_class_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncClassListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_class_list_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncClassList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_class_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncClassListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_class_list_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncClassList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncMapResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncMapResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_string_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncStringMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_string_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncStringMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_string_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncStringMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_string_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncStringMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_int_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncIntMapResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_int_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncIntMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_int_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncIntMapResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_int_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncIntMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_enum_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumMapResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncEnumMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_enum_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumMapResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncEnumMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_class_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncClassMapResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_class_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncClassMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_class_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncClassMapResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_class_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncClassMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAnEnum return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncEnum", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncEnumResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_enum_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncEnum", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_another_async_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAnotherEnum return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherAsyncEnumResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_another_async_enum_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAnotherAsyncEnum", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_another_async_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherAsyncEnumResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_another_async_enum_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAnotherAsyncEnum", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_throw_async_error( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncErrorResponse) response = + core_tests_pigeon_test_host_integration_core_api_throw_async_error_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "throwAsyncError", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_throw_async_error( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncErrorResponse) response = + core_tests_pigeon_test_host_integration_core_api_throw_async_error_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "throwAsyncError", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_throw_async_error_from_void( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncErrorFromVoidResponse) + response = + core_tests_pigeon_test_host_integration_core_api_throw_async_error_from_void_response_new(); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "throwAsyncErrorFromVoid", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_throw_async_error_from_void( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncErrorFromVoidResponse) + response = + core_tests_pigeon_test_host_integration_core_api_throw_async_error_from_void_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "throwAsyncErrorFromVoid", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_throw_async_flutter_error( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncFlutterErrorResponse) + response = + core_tests_pigeon_test_host_integration_core_api_throw_async_flutter_error_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "throwAsyncFlutterError", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_throw_async_flutter_error( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiThrowAsyncFlutterErrorResponse) + response = + core_tests_pigeon_test_host_integration_core_api_throw_async_flutter_error_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "throwAsyncFlutterError", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_all_types( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAllTypes* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncAllTypesResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_all_types_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncAllTypes", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_all_types( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncAllTypesResponse) response = + core_tests_pigeon_test_host_integration_core_api_echo_async_all_types_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncAllTypes", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_all_nullable_types( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAllNullableTypes* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableAllNullableTypesResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableAllNullableTypes", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_all_nullable_types( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableAllNullableTypesResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableAllNullableTypes", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_all_nullable_types_without_recursion( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableAllNullableTypesWithoutRecursionResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_without_recursion_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableAllNullableTypesWithoutRecursion", + error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_all_nullable_types_without_recursion( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableAllNullableTypesWithoutRecursionResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_all_nullable_types_without_recursion_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableAllNullableTypesWithoutRecursion", + error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_int( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + int64_t* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableIntResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableInt", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_int( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableIntResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableInt", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_double( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + double* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableDoubleResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_double_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableDouble", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_double( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableDoubleResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_double_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableDouble", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_bool( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gboolean* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableBoolResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_bool_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableBool", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_bool( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableBoolResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_bool_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableBool", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_string( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableStringResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableString", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_string( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableStringResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableString", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_uint8_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const uint8_t* return_value, size_t return_value_length) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableUint8ListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_uint8_list_response_new( + return_value, return_value_length); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableUint8List", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_uint8_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableUint8ListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_uint8_list_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableUint8List", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_object( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableObjectResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_object_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableObject", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_object( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableObjectResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_object_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableObject", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_list_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_list_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_enum_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_list_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableEnumList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_enum_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_list_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableEnumList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_class_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableClassListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_list_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableClassList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_class_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableClassListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_list_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableClassList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_string_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableStringMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableStringMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_string_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableStringMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_string_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableStringMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_int_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableIntMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableIntMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_int_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableIntMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_int_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableIntMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_enum_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableEnumMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_enum_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableEnumMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_class_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableClassMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableClassMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_class_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableClassMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_class_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableClassMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAnEnum* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableEnum", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAsyncNullableEnumResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_async_nullable_enum_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAsyncNullableEnum", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_echo_another_async_nullable_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAnotherEnum* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherAsyncNullableEnumResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_another_async_nullable_enum_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAnotherAsyncNullableEnum", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_another_async_nullable_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherAsyncNullableEnumResponse) + response = + core_tests_pigeon_test_host_integration_core_api_echo_another_async_nullable_enum_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoAnotherAsyncNullableEnum", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_noop( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterNoopResponse) response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_noop_response_new(); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterNoop", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_noop( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterNoopResponse) response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_noop_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterNoop", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_throw_error( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterThrowErrorResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterThrowError", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_throw_error( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterThrowErrorResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterThrowError", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_throw_error_from_void( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterThrowErrorFromVoidResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_from_void_response_new(); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterThrowErrorFromVoid", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_throw_error_from_void( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterThrowErrorFromVoidResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_throw_error_from_void_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterThrowErrorFromVoid", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_all_types( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAllTypes* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllTypesResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_types_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoAllTypes", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_all_types( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllTypesResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_types_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoAllTypes", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_all_nullable_types( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAllNullableTypes* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllNullableTypesResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoAllNullableTypes", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_all_nullable_types( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllNullableTypesResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoAllNullableTypes", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_send_multiple_nullable_types( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAllNullableTypes* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSendMultipleNullableTypesResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterSendMultipleNullableTypes", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_send_multiple_nullable_types( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSendMultipleNullableTypesResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterSendMultipleNullableTypes", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_all_nullable_types_without_recursion( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllNullableTypesWithoutRecursionResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_without_recursion_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoAllNullableTypesWithoutRecursion", + error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_all_nullable_types_without_recursion( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAllNullableTypesWithoutRecursionResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_all_nullable_types_without_recursion_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoAllNullableTypesWithoutRecursion", + error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_send_multiple_nullable_types_without_recursion( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSendMultipleNullableTypesWithoutRecursionResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_without_recursion_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterSendMultipleNullableTypesWithoutRecursion", + error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_send_multiple_nullable_types_without_recursion( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSendMultipleNullableTypesWithoutRecursionResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_send_multiple_nullable_types_without_recursion_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterSendMultipleNullableTypesWithoutRecursion", + error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_bool( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gboolean return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoBoolResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_bool_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoBool", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoBoolResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_bool_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoBool", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_int( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + int64_t return_value) { + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoIntResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoInt", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_int( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoIntResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoInt", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_double( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + double return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoDoubleResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_double_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoDouble", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_double( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoDoubleResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_double_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoDouble", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_string( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoStringResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoString", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_string( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoStringResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoString", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_uint8_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const uint8_t* return_value, size_t return_value_length) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoUint8ListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_uint8_list_response_new( + return_value, return_value_length); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoUint8List", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_uint8_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoUint8ListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_uint8_list_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoUint8List", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_list_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_list_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_enum_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_list_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoEnumList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_enum_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_list_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoEnumList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_class_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoClassListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_list_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoClassList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_class_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoClassListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_list_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoClassList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_non_null_enum_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullEnumListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_list_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNonNullEnumList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_non_null_enum_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullEnumListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_list_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNonNullEnumList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_non_null_class_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullClassListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_list_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNonNullClassList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_non_null_class_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullClassListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_list_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNonNullClassList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_string_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoStringMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoStringMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_string_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoStringMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_string_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoStringMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_int_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoIntMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoIntMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_int_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoIntMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_int_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoIntMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_enum_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoEnumMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_enum_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoEnumMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_class_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoClassMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoClassMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_class_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoClassMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_class_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoClassMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_non_null_string_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullStringMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_string_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNonNullStringMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_non_null_string_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullStringMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_string_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNonNullStringMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_non_null_int_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullIntMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_int_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNonNullIntMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_non_null_int_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullIntMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_int_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNonNullIntMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_non_null_enum_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullEnumMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNonNullEnumMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_non_null_enum_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullEnumMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_enum_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNonNullEnumMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_non_null_class_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullClassMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNonNullClassMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_non_null_class_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNonNullClassMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_non_null_class_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNonNullClassMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAnEnum return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoEnum", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoEnumResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_enum_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoEnum", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_another_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAnotherEnum return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAnotherEnumResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_enum_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoAnotherEnum", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_another_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAnotherEnumResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_enum_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoAnotherEnum", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_bool( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gboolean* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableBoolResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_bool_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableBool", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_bool( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableBoolResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_bool_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableBool", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_int( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + int64_t* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableIntResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableInt", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_int( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableIntResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableInt", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_double( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + double* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableDoubleResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_double_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableDouble", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_double( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableDoubleResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_double_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableDouble", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_string( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableStringResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableString", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_string( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableStringResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableString", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_uint8_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const uint8_t* return_value, size_t return_value_length) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableUint8ListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_uint8_list_response_new( + return_value, return_value_length); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableUint8List", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_uint8_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableUint8ListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_uint8_list_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableUint8List", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_list_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_list_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_enum_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_list_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableEnumList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_enum_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_list_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableEnumList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_class_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableClassListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_list_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableClassList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_class_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableClassListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_list_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableClassList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_non_null_enum_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullEnumListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_list_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableNonNullEnumList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_non_null_enum_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullEnumListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_list_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableNonNullEnumList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_non_null_class_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullClassListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_list_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableNonNullClassList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_non_null_class_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullClassListResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_list_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableNonNullClassList", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_string_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableStringMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableStringMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_string_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableStringMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_string_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableStringMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_int_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableIntMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableIntMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_int_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableIntMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_int_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableIntMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_enum_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableEnumMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_enum_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableEnumMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_class_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableClassMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableClassMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_class_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableClassMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_class_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableClassMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_non_null_string_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullStringMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_string_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableNonNullStringMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_non_null_string_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullStringMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_string_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableNonNullStringMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_non_null_int_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullIntMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_int_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableNonNullIntMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_non_null_int_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullIntMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_int_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableNonNullIntMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_non_null_enum_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullEnumMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableNonNullEnumMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_non_null_enum_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullEnumMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_enum_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableNonNullEnumMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_non_null_class_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullClassMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_map_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableNonNullClassMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_non_null_class_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableNonNullClassMapResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_non_null_class_map_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableNonNullClassMap", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAnEnum* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableEnum", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoNullableEnumResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_nullable_enum_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoNullableEnum", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_another_nullable_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAnotherEnum* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAnotherNullableEnumResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_nullable_enum_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoAnotherNullableEnum", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_another_nullable_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterEchoAnotherNullableEnumResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_echo_another_nullable_enum_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterEchoAnotherNullableEnum", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_small_api_echo_string( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* return_value) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSmallApiEchoStringResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_small_api_echo_string_response_new( + return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterSmallApiEchoString", error->message); + } +} + +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_small_api_echo_string( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr( + CoreTestsPigeonTestHostIntegrationCoreApiCallFlutterSmallApiEchoStringResponse) + response = + core_tests_pigeon_test_host_integration_core_api_call_flutter_small_api_echo_string_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "callFlutterSmallApiEchoString", error->message); + } +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApi { + GObject parent_instance; + + FlBinaryMessenger* messenger; + gchar* suffix; +}; + +G_DEFINE_TYPE(CoreTestsPigeonTestFlutterIntegrationCoreApi, + core_tests_pigeon_test_flutter_integration_core_api, + G_TYPE_OBJECT) + +static void core_tests_pigeon_test_flutter_integration_core_api_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object); + g_clear_object(&self->messenger); + g_clear_pointer(&self->suffix, g_free); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_parent_class) + ->dispose(object); +} + +static void core_tests_pigeon_test_flutter_integration_core_api_init( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self) {} + +static void core_tests_pigeon_test_flutter_integration_core_api_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_dispose; +} + +CoreTestsPigeonTestFlutterIntegrationCoreApi* +core_tests_pigeon_test_flutter_integration_core_api_new( + FlBinaryMessenger* messenger, const gchar* suffix) { + CoreTestsPigeonTestFlutterIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_get_type(), + nullptr)); + self->messenger = FL_BINARY_MESSENGER(g_object_ref(messenger)); + self->suffix = + suffix != nullptr ? g_strdup_printf(".%s", suffix) : g_strdup(""); + return self; +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiNoopResponse { + GObject parent_instance; + + FlValue* error; +}; + +G_DEFINE_TYPE(CoreTestsPigeonTestFlutterIntegrationCoreApiNoopResponse, + core_tests_pigeon_test_flutter_integration_core_api_noop_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_noop_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_NOOP_RESPONSE(object); + g_clear_pointer(&self->error, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_noop_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_noop_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopResponse* self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_noop_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_noop_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiNoopResponse* +core_tests_pigeon_test_flutter_integration_core_api_noop_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_NOOP_RESPONSE(g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_noop_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_noop_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_NOOP_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_noop_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_NOOP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_noop_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_noop_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_NOOP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_noop_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_noop_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_NOOP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_noop_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +static void core_tests_pigeon_test_flutter_integration_core_api_noop_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_noop( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "noop%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_noop_cb, task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiNoopResponse* +core_tests_pigeon_test_flutter_integration_core_api_noop_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_noop_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse, + core_tests_pigeon_test_flutter_integration_core_api_throw_error_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_THROW_ERROR_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse* self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse* +core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_THROW_ERROR_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_THROW_ERROR_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_THROW_ERROR_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_THROW_ERROR_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_THROW_ERROR_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_THROW_ERROR_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_is_error( + self)); + if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) { + return nullptr; + } + return self->return_value; +} + +static void core_tests_pigeon_test_flutter_integration_core_api_throw_error_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_throw_error( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "throwError%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_throw_error_cb, task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse* +core_tests_pigeon_test_flutter_integration_core_api_throw_error_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorFromVoidResponse { + GObject parent_instance; + + FlValue* error; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorFromVoidResponse, + core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorFromVoidResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_THROW_ERROR_FROM_VOID_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorFromVoidResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorFromVoidResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorFromVoidResponse* +core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorFromVoidResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_THROW_ERROR_FROM_VOID_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorFromVoidResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_THROW_ERROR_FROM_VOID_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorFromVoidResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_THROW_ERROR_FROM_VOID_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorFromVoidResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_THROW_ERROR_FROM_VOID_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorFromVoidResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_THROW_ERROR_FROM_VOID_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "throwErrorFromVoid%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorFromVoidResponse* +core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_ALL_TYPES_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse* self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_ALL_TYPES_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ALL_TYPES_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ALL_TYPES_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ALL_TYPES_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ALL_TYPES_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +CoreTestsPigeonTestAllTypes* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ALL_TYPES_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_is_error( + self)); + return CORE_TESTS_PIGEON_TEST_ALL_TYPES( + fl_value_get_custom_value_object(self->return_value)); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_all_types( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, + CoreTestsPigeonTestAllTypes* everything, GCancellable* cancellable, + GAsyncReadyCallback callback, gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, + fl_value_new_custom_object(132, G_OBJECT(everything))); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoAllTypes%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_new( + response); +} + +struct + _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_ALL_NULLABLE_TYPES_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_ALL_NULLABLE_TYPES_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ALL_NULLABLE_TYPES_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ALL_NULLABLE_TYPES_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ALL_NULLABLE_TYPES_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ALL_NULLABLE_TYPES_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +CoreTestsPigeonTestAllNullableTypes* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ALL_NULLABLE_TYPES_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_is_error( + self)); + if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) { + return nullptr; + } + return CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES( + fl_value_get_custom_value_object(self->return_value)); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, + CoreTestsPigeonTestAllNullableTypes* everything, GCancellable* cancellable, + GAsyncReadyCallback callback, gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take( + args, everything != nullptr + ? fl_value_new_custom_object(133, G_OBJECT(everything)) + : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoAllNullableTypes%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_new( + response); +} + +struct + _CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse, + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse* + self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_SEND_MULTIPLE_NULLABLE_TYPES_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse* +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_SEND_MULTIPLE_NULLABLE_TYPES_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_SEND_MULTIPLE_NULLABLE_TYPES_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_SEND_MULTIPLE_NULLABLE_TYPES_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_SEND_MULTIPLE_NULLABLE_TYPES_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_SEND_MULTIPLE_NULLABLE_TYPES_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +CoreTestsPigeonTestAllNullableTypes* +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_SEND_MULTIPLE_NULLABLE_TYPES_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_is_error( + self)); + return CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES( + fl_value_get_custom_value_object(self->return_value)); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, + gboolean* a_nullable_bool, int64_t* a_nullable_int, + const gchar* a_nullable_string, GCancellable* cancellable, + GAsyncReadyCallback callback, gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, a_nullable_bool != nullptr + ? fl_value_new_bool(*a_nullable_bool) + : fl_value_new_null()); + fl_value_append_take(args, a_nullable_int != nullptr + ? fl_value_new_int(*a_nullable_int) + : fl_value_new_null()); + fl_value_append_take(args, a_nullable_string != nullptr + ? fl_value_new_string(a_nullable_string) + : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "sendMultipleNullableTypes%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse* +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_new( + response); +} + +struct + _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* + self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_ALL_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* + self = CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_ALL_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ALL_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ALL_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ALL_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ALL_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +CoreTestsPigeonTestAllNullableTypesWithoutRecursion* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ALL_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_is_error( + self)); + if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) { + return nullptr; + } + return CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES_WITHOUT_RECURSION( + fl_value_get_custom_value_object(self->return_value)); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* everything, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take( + args, everything != nullptr + ? fl_value_new_custom_object(134, G_OBJECT(everything)) + : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoAllNullableTypesWithoutRecursion%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_new( + response); +} + +struct + _CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse, + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* + self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_SEND_MULTIPLE_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* + self = CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_SEND_MULTIPLE_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_SEND_MULTIPLE_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_SEND_MULTIPLE_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_SEND_MULTIPLE_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_SEND_MULTIPLE_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +CoreTestsPigeonTestAllNullableTypesWithoutRecursion* +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_SEND_MULTIPLE_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_is_error( + self)); + return CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES_WITHOUT_RECURSION( + fl_value_get_custom_value_object(self->return_value)); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, + gboolean* a_nullable_bool, int64_t* a_nullable_int, + const gchar* a_nullable_string, GCancellable* cancellable, + GAsyncReadyCallback callback, gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, a_nullable_bool != nullptr + ? fl_value_new_bool(*a_nullable_bool) + : fl_value_new_null()); + fl_value_append_take(args, a_nullable_int != nullptr + ? fl_value_new_int(*a_nullable_int) + : fl_value_new_null()); + fl_value_append_take(args, a_nullable_string != nullptr + ? fl_value_new_string(a_nullable_string) + : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "sendMultipleNullableTypesWithoutRecursion%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_BOOL_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse* self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_BOOL_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_BOOL_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_BOOL_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_BOOL_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_BOOL_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_BOOL_RESPONSE( + self), + FALSE); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_is_error( + self)); + return fl_value_get_bool(self->return_value); +} + +static void core_tests_pigeon_test_flutter_integration_core_api_echo_bool_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_bool( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, gboolean a_bool, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, fl_value_new_bool(a_bool)); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoBool%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_bool_cb, task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_bool_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_int_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_INT_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse* self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_INT_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_INT_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_INT_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_INT_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_INT_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +int64_t +core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_INT_RESPONSE( + self), + 0); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_is_error( + self)); + return fl_value_get_int(self->return_value); +} + +static void core_tests_pigeon_test_flutter_integration_core_api_echo_int_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_int( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, int64_t an_int, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, fl_value_new_int(an_int)); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoInt%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_int_cb, task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_int_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_double_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_DOUBLE_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse* self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_DOUBLE_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_DOUBLE_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_DOUBLE_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_DOUBLE_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_DOUBLE_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +double +core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_DOUBLE_RESPONSE( + self), + 0.0); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_is_error( + self)); + return fl_value_get_float(self->return_value); +} + +static void core_tests_pigeon_test_flutter_integration_core_api_echo_double_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_double( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, double a_double, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, fl_value_new_float(a_double)); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoDouble%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_double_cb, task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_double_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_string_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_STRING_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse* self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_STRING_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_STRING_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_STRING_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_STRING_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_STRING_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_is_error( + self)); + return fl_value_get_string(self->return_value); +} + +static void core_tests_pigeon_test_flutter_integration_core_api_echo_string_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_string( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, const gchar* a_string, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, fl_value_new_string(a_string)); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoString%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_string_cb, task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_string_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_UINT8_LIST_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse* self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_UINT8_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_UINT8_LIST_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_UINT8_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_UINT8_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_UINT8_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +const uint8_t* +core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse* self, + size_t* return_value_length) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_UINT8_LIST_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_is_error( + self)); + if (return_value_length != nullptr) { + *return_value_length = fl_value_get_length(self->return_value); + } + return fl_value_get_uint8_list(self->return_value); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, const uint8_t* list, + size_t list_length, GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, fl_value_new_uint8_list(list, list_length)); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoUint8List%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_LIST_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse* self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_LIST_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_LIST_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_is_error( + self)); + return self->return_value; +} + +static void core_tests_pigeon_test_flutter_integration_core_api_echo_list_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_list( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* list, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, fl_value_ref(list)); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoList%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_list_cb, task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_list_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_ENUM_LIST_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse* self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_ENUM_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ENUM_LIST_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ENUM_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ENUM_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ENUM_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ENUM_LIST_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_is_error( + self)); + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* enum_list, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, fl_value_ref(enum_list)); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoEnumList%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_CLASS_LIST_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse* self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_CLASS_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_CLASS_LIST_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_CLASS_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_CLASS_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_CLASS_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_CLASS_LIST_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_is_error( + self)); + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_class_list( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* class_list, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, fl_value_ref(class_list)); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoClassList%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_new( + response); +} + +struct + _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_ENUM_LIST_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_ENUM_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_ENUM_LIST_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_ENUM_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_ENUM_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_ENUM_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_ENUM_LIST_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_is_error( + self)); + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* enum_list, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, fl_value_ref(enum_list)); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNonNullEnumList%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_new( + response); +} + +struct + _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_CLASS_LIST_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_CLASS_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_CLASS_LIST_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_CLASS_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_CLASS_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_CLASS_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_CLASS_LIST_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_is_error( + self)); + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* class_list, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, fl_value_ref(class_list)); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNonNullClassList%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_MAP_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse* self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_MAP_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_MAP_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_is_error( + self)); + return self->return_value; +} + +static void core_tests_pigeon_test_flutter_integration_core_api_echo_map_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, fl_value_ref(map)); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoMap%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_map_cb, task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_STRING_MAP_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse* self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_STRING_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_STRING_MAP_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_STRING_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_STRING_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_STRING_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_STRING_MAP_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_is_error( + self)); + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_string_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* string_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, fl_value_ref(string_map)); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoStringMap%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_INT_MAP_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse* self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_INT_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_INT_MAP_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_INT_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_INT_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_INT_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_INT_MAP_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_is_error( + self)); + return self->return_value; +} + +static void core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_int_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* int_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, fl_value_ref(int_map)); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoIntMap%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_ENUM_MAP_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse* self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_ENUM_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ENUM_MAP_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ENUM_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ENUM_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ENUM_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ENUM_MAP_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_is_error( + self)); + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* enum_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, fl_value_ref(enum_map)); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoEnumMap%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_CLASS_MAP_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse* self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_CLASS_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_CLASS_MAP_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_CLASS_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_CLASS_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_CLASS_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_CLASS_MAP_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_is_error( + self)); + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_class_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* class_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, fl_value_ref(class_map)); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoClassMap%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_new( + response); +} + +struct + _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_STRING_MAP_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_STRING_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_STRING_MAP_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_STRING_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_STRING_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_STRING_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_STRING_MAP_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_is_error( + self)); + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* string_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, fl_value_ref(string_map)); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNonNullStringMap%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_INT_MAP_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_INT_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_INT_MAP_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_INT_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_INT_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_INT_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_INT_MAP_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_is_error( + self)); + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* int_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, fl_value_ref(int_map)); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNonNullIntMap%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_ENUM_MAP_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_ENUM_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_ENUM_MAP_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_ENUM_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_ENUM_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_ENUM_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_ENUM_MAP_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_is_error( + self)); + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* enum_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, fl_value_ref(enum_map)); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNonNullEnumMap%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_new( + response); +} + +struct + _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_CLASS_MAP_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_CLASS_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_CLASS_MAP_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_CLASS_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_CLASS_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_CLASS_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_CLASS_MAP_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_is_error( + self)); + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* class_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, fl_value_ref(class_map)); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNonNullClassMap%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_ENUM_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse* self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ENUM_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ENUM_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ENUM_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ENUM_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +CoreTestsPigeonTestAnEnum +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ENUM_RESPONSE( + self), + static_cast(0)); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_is_error( + self)); + return static_cast( + fl_value_get_int(reinterpret_cast(const_cast( + fl_value_get_custom_value(self->return_value))))); +} + +static void core_tests_pigeon_test_flutter_integration_core_api_echo_enum_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_enum( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, + CoreTestsPigeonTestAnEnum an_enum, GCancellable* cancellable, + GAsyncReadyCallback callback, gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, + fl_value_new_custom(129, fl_value_new_int(an_enum), + (GDestroyNotify)fl_value_unref)); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoEnum%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_cb, task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_ANOTHER_ENUM_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse* self) { +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_ANOTHER_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ANOTHER_ENUM_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ANOTHER_ENUM_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ANOTHER_ENUM_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ANOTHER_ENUM_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +CoreTestsPigeonTestAnotherEnum +core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ANOTHER_ENUM_RESPONSE( + self), + static_cast(0)); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_is_error( + self)); + return static_cast( + fl_value_get_int(reinterpret_cast(const_cast( + fl_value_get_custom_value(self->return_value))))); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, + CoreTestsPigeonTestAnotherEnum another_enum, GCancellable* cancellable, + GAsyncReadyCallback callback, gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, + fl_value_new_custom(130, fl_value_new_int(another_enum), + (GDestroyNotify)fl_value_unref)); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoAnotherEnum%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; + gboolean return_value_; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_BOOL_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_BOOL_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_BOOL_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_BOOL_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_BOOL_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_BOOL_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +gboolean* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_BOOL_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_is_error( + self)); + if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) { + return nullptr; + } + self->return_value_ = fl_value_get_bool(self->return_value); + return &self->return_value_; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, gboolean* a_bool, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, a_bool != nullptr ? fl_value_new_bool(*a_bool) + : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNullableBool%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; + int64_t return_value_; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_INT_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse* self) { +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_INT_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_INT_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_INT_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_INT_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_INT_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +int64_t* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_INT_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_is_error( + self)); + if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) { + return nullptr; + } + self->return_value_ = fl_value_get_int(self->return_value); + return &self->return_value_; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, int64_t* an_int, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, an_int != nullptr ? fl_value_new_int(*an_int) + : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNullableInt%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; + double return_value_; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_DOUBLE_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_DOUBLE_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_DOUBLE_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_DOUBLE_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_DOUBLE_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_DOUBLE_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +double* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_DOUBLE_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_is_error( + self)); + if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) { + return nullptr; + } + self->return_value_ = fl_value_get_float(self->return_value); + return &self->return_value_; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, double* a_double, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, a_double != nullptr ? fl_value_new_float(*a_double) + : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNullableDouble%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_STRING_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_STRING_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_STRING_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_STRING_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_STRING_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_STRING_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_is_error( + self)); + if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) { + return nullptr; + } + return fl_value_get_string(self->return_value); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, const gchar* a_string, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, a_string != nullptr ? fl_value_new_string(a_string) + : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNullableString%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_new( + response); +} + +struct + _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_UINT8_LIST_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_UINT8_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_UINT8_LIST_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_UINT8_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_UINT8_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_UINT8_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +const uint8_t* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse* + self, + size_t* return_value_length) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_UINT8_LIST_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_is_error( + self)); + if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) { + return nullptr; + } + if (return_value_length != nullptr) { + *return_value_length = fl_value_get_length(self->return_value); + } + return fl_value_get_uint8_list(self->return_value); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, const uint8_t* list, + size_t list_length, GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, list != nullptr + ? fl_value_new_uint8_list(list, list_length) + : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNullableUint8List%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_LIST_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_LIST_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_LIST_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_is_error( + self)); + if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) { + return nullptr; + } + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* list, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take( + args, list != nullptr ? fl_value_ref(list) : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNullableList%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_new( + response); +} + +struct + _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_LIST_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_LIST_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_LIST_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_is_error( + self)); + if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) { + return nullptr; + } + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* enum_list, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, enum_list != nullptr ? fl_value_ref(enum_list) + : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNullableEnumList%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_new( + response); +} + +struct + _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_CLASS_LIST_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_CLASS_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_CLASS_LIST_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_CLASS_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_CLASS_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_CLASS_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_CLASS_LIST_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_is_error( + self)); + if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) { + return nullptr; + } + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* class_list, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, class_list != nullptr ? fl_value_ref(class_list) + : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNullableClassList%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_new( + response); +} + +struct + _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse* + self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_ENUM_LIST_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse* + self = CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_ENUM_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_ENUM_LIST_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_ENUM_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_ENUM_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_ENUM_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_ENUM_LIST_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_is_error( + self)); + if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) { + return nullptr; + } + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* enum_list, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, enum_list != nullptr ? fl_value_ref(enum_list) + : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNullableNonNullEnumList%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_new( + response); +} + +struct + _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse* + self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_CLASS_LIST_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse* + self = CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_CLASS_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_CLASS_LIST_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_CLASS_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_CLASS_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_CLASS_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_CLASS_LIST_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_is_error( + self)); + if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) { + return nullptr; + } + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* class_list, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, class_list != nullptr ? fl_value_ref(class_list) + : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNullableNonNullClassList%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_MAP_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse* self) { +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_MAP_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_MAP_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_is_error( + self)); + if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) { + return nullptr; + } + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take( + args, map != nullptr ? fl_value_ref(map) : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNullableMap%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_new( + response); +} + +struct + _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_STRING_MAP_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_STRING_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_STRING_MAP_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_STRING_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_STRING_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_STRING_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_STRING_MAP_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_is_error( + self)); + if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) { + return nullptr; + } + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* string_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, string_map != nullptr ? fl_value_ref(string_map) + : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNullableStringMap%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_INT_MAP_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_INT_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_INT_MAP_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_INT_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_INT_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_INT_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_INT_MAP_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_is_error( + self)); + if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) { + return nullptr; + } + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* int_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take( + args, int_map != nullptr ? fl_value_ref(int_map) : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNullableIntMap%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_new( + response); +} + +struct + _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_MAP_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_MAP_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_MAP_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_is_error( + self)); + if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) { + return nullptr; + } + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* enum_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take( + args, enum_map != nullptr ? fl_value_ref(enum_map) : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNullableEnumMap%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_new( + response); +} + +struct + _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_CLASS_MAP_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_CLASS_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_CLASS_MAP_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_CLASS_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_CLASS_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_CLASS_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_CLASS_MAP_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_is_error( + self)); + if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) { + return nullptr; + } + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* class_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, class_map != nullptr ? fl_value_ref(class_map) + : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNullableClassMap%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_new( + response); +} + +struct + _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse* + self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_STRING_MAP_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse* + self = CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_STRING_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_STRING_MAP_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_STRING_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_STRING_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_STRING_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_STRING_MAP_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_is_error( + self)); + if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) { + return nullptr; + } + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* string_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, string_map != nullptr ? fl_value_ref(string_map) + : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNullableNonNullStringMap%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_new( + response); +} + +struct + _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse* + self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_INT_MAP_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_INT_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_INT_MAP_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_INT_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_INT_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_INT_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_INT_MAP_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_is_error( + self)); + if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) { + return nullptr; + } + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* int_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take( + args, int_map != nullptr ? fl_value_ref(int_map) : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNullableNonNullIntMap%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_new( + response); +} + +struct + _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse* + self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_ENUM_MAP_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_ENUM_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_ENUM_MAP_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_ENUM_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_ENUM_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_ENUM_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_ENUM_MAP_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_is_error( + self)); + if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) { + return nullptr; + } + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* enum_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take( + args, enum_map != nullptr ? fl_value_ref(enum_map) : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNullableNonNullEnumMap%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_new( + response); +} + +struct + _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse* + self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_CLASS_MAP_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse* + self = CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_CLASS_MAP_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_CLASS_MAP_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_CLASS_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_CLASS_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_CLASS_MAP_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_CLASS_MAP_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_is_error( + self)); + if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) { + return nullptr; + } + return self->return_value; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, FlValue* class_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, class_map != nullptr ? fl_value_ref(class_map) + : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNullableNonNullClassMap%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; + CoreTestsPigeonTestAnEnum return_value_; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +CoreTestsPigeonTestAnEnum* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_is_error( + self)); + if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) { + return nullptr; + } + self->return_value_ = static_cast( + fl_value_get_int(reinterpret_cast(const_cast( + fl_value_get_custom_value(self->return_value))))); + return &self->return_value_; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, + CoreTestsPigeonTestAnEnum* an_enum, GCancellable* cancellable, + GAsyncReadyCallback callback, gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take( + args, an_enum != nullptr + ? fl_value_new_custom(129, fl_value_new_int(*an_enum), + (GDestroyNotify)fl_value_unref) + : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNullableEnum%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_new( + response); +} + +struct + _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; + CoreTestsPigeonTestAnotherEnum return_value_; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_ANOTHER_NULLABLE_ENUM_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse* + self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_ANOTHER_NULLABLE_ENUM_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ANOTHER_NULLABLE_ENUM_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ANOTHER_NULLABLE_ENUM_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ANOTHER_NULLABLE_ENUM_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ANOTHER_NULLABLE_ENUM_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +CoreTestsPigeonTestAnotherEnum* +core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse* + self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ANOTHER_NULLABLE_ENUM_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_is_error( + self)); + if (fl_value_get_type(self->return_value) == FL_VALUE_TYPE_NULL) { + return nullptr; + } + self->return_value_ = static_cast( + fl_value_get_int(reinterpret_cast(const_cast( + fl_value_get_custom_value(self->return_value))))); + return &self->return_value_; +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, + CoreTestsPigeonTestAnotherEnum* another_enum, GCancellable* cancellable, + GAsyncReadyCallback callback, gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take( + args, another_enum != nullptr + ? fl_value_new_custom(130, fl_value_new_int(*another_enum), + (GDestroyNotify)fl_value_unref) + : fl_value_new_null()); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoAnotherNullableEnum%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiNoopAsyncResponse { + GObject parent_instance; + + FlValue* error; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopAsyncResponse, + core_tests_pigeon_test_flutter_integration_core_api_noop_async_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_noop_async_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopAsyncResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_NOOP_ASYNC_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_noop_async_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_noop_async_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopAsyncResponse* self) {} + +static void +core_tests_pigeon_test_flutter_integration_core_api_noop_async_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopAsyncResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_noop_async_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiNoopAsyncResponse* +core_tests_pigeon_test_flutter_integration_core_api_noop_async_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopAsyncResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_NOOP_ASYNC_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_noop_async_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_noop_async_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopAsyncResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_NOOP_ASYNC_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_noop_async_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopAsyncResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_NOOP_ASYNC_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_noop_async_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_noop_async_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopAsyncResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_NOOP_ASYNC_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_noop_async_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_noop_async_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopAsyncResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_NOOP_ASYNC_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_noop_async_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +static void core_tests_pigeon_test_flutter_integration_core_api_noop_async_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_noop_async( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "noopAsync%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_noop_async_cb, task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiNoopAsyncResponse* +core_tests_pigeon_test_flutter_integration_core_api_noop_async_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_noop_async_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_ASYNC_STRING_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse* self) { +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_class_init( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_dispose; +} + +static CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API_ECHO_ASYNC_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ASYNC_STRING_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ASYNC_STRING_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ASYNC_STRING_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ASYNC_STRING_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_INTEGRATION_CORE_API_ECHO_ASYNC_STRING_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_is_error( + self)); + return fl_value_get_string(self->return_value); +} + +static void +core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_integration_core_api_echo_async_string( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, const gchar* a_string, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, fl_value_new_string(a_string)); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoAsyncString%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_cb, + task); +} + +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_new( + response); +} + +struct _CoreTestsPigeonTestHostTrivialApiNoopResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE(CoreTestsPigeonTestHostTrivialApiNoopResponse, + core_tests_pigeon_test_host_trivial_api_noop_response, + G_TYPE_OBJECT) + +static void core_tests_pigeon_test_host_trivial_api_noop_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostTrivialApiNoopResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_TRIVIAL_API_NOOP_RESPONSE(object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_trivial_api_noop_response_parent_class) + ->dispose(object); +} + +static void core_tests_pigeon_test_host_trivial_api_noop_response_init( + CoreTestsPigeonTestHostTrivialApiNoopResponse* self) {} + +static void core_tests_pigeon_test_host_trivial_api_noop_response_class_init( + CoreTestsPigeonTestHostTrivialApiNoopResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_trivial_api_noop_response_dispose; +} + +CoreTestsPigeonTestHostTrivialApiNoopResponse* +core_tests_pigeon_test_host_trivial_api_noop_response_new() { + CoreTestsPigeonTestHostTrivialApiNoopResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_TRIVIAL_API_NOOP_RESPONSE(g_object_new( + core_tests_pigeon_test_host_trivial_api_noop_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_null()); + return self; +} + +CoreTestsPigeonTestHostTrivialApiNoopResponse* +core_tests_pigeon_test_host_trivial_api_noop_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostTrivialApiNoopResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_TRIVIAL_API_NOOP_RESPONSE(g_object_new( + core_tests_pigeon_test_host_trivial_api_noop_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestHostTrivialApi, + core_tests_pigeon_test_host_trivial_api, + CORE_TESTS_PIGEON_TEST, HOST_TRIVIAL_API, GObject) + +struct _CoreTestsPigeonTestHostTrivialApi { + GObject parent_instance; + + const CoreTestsPigeonTestHostTrivialApiVTable* vtable; + gpointer user_data; + GDestroyNotify user_data_free_func; +}; + +G_DEFINE_TYPE(CoreTestsPigeonTestHostTrivialApi, + core_tests_pigeon_test_host_trivial_api, G_TYPE_OBJECT) + +static void core_tests_pigeon_test_host_trivial_api_dispose(GObject* object) { + CoreTestsPigeonTestHostTrivialApi* self = + CORE_TESTS_PIGEON_TEST_HOST_TRIVIAL_API(object); + if (self->user_data != nullptr) { + self->user_data_free_func(self->user_data); + } + self->user_data = nullptr; + G_OBJECT_CLASS(core_tests_pigeon_test_host_trivial_api_parent_class) + ->dispose(object); +} + +static void core_tests_pigeon_test_host_trivial_api_init( + CoreTestsPigeonTestHostTrivialApi* self) {} + +static void core_tests_pigeon_test_host_trivial_api_class_init( + CoreTestsPigeonTestHostTrivialApiClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_trivial_api_dispose; +} + +static CoreTestsPigeonTestHostTrivialApi* +core_tests_pigeon_test_host_trivial_api_new( + const CoreTestsPigeonTestHostTrivialApiVTable* vtable, gpointer user_data, + GDestroyNotify user_data_free_func) { + CoreTestsPigeonTestHostTrivialApi* self = + CORE_TESTS_PIGEON_TEST_HOST_TRIVIAL_API(g_object_new( + core_tests_pigeon_test_host_trivial_api_get_type(), nullptr)); + self->vtable = vtable; + self->user_data = user_data; + self->user_data_free_func = user_data_free_func; + return self; +} + +static void core_tests_pigeon_test_host_trivial_api_noop_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostTrivialApi* self = + CORE_TESTS_PIGEON_TEST_HOST_TRIVIAL_API(user_data); + + if (self->vtable == nullptr || self->vtable->noop == nullptr) { + return; + } + + g_autoptr(CoreTestsPigeonTestHostTrivialApiNoopResponse) response = + self->vtable->noop(self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostTrivialApi", "noop"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostTrivialApi", "noop", + error->message); + } +} + +void core_tests_pigeon_test_host_trivial_api_set_method_handlers( + FlBinaryMessenger* messenger, const gchar* suffix, + const CoreTestsPigeonTestHostTrivialApiVTable* vtable, gpointer user_data, + GDestroyNotify user_data_free_func) { + g_autofree gchar* dot_suffix = + suffix != nullptr ? g_strdup_printf(".%s", suffix) : g_strdup(""); + g_autoptr(CoreTestsPigeonTestHostTrivialApi) api_data = + core_tests_pigeon_test_host_trivial_api_new(vtable, user_data, + user_data_free_func); + + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + g_autofree gchar* noop_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostTrivialApi.noop%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) noop_channel = fl_basic_message_channel_new( + messenger, noop_channel_name, FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + noop_channel, core_tests_pigeon_test_host_trivial_api_noop_cb, + g_object_ref(api_data), g_object_unref); +} + +void core_tests_pigeon_test_host_trivial_api_clear_method_handlers( + FlBinaryMessenger* messenger, const gchar* suffix) { + g_autofree gchar* dot_suffix = + suffix != nullptr ? g_strdup_printf(".%s", suffix) : g_strdup(""); + + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + g_autofree gchar* noop_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostTrivialApi.noop%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) noop_channel = fl_basic_message_channel_new( + messenger, noop_channel_name, FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(noop_channel, nullptr, nullptr, + nullptr); +} + +struct _CoreTestsPigeonTestHostSmallApiResponseHandle { + GObject parent_instance; + + FlBasicMessageChannel* channel; + FlBasicMessageChannelResponseHandle* response_handle; +}; + +G_DEFINE_TYPE(CoreTestsPigeonTestHostSmallApiResponseHandle, + core_tests_pigeon_test_host_small_api_response_handle, + G_TYPE_OBJECT) + +static void core_tests_pigeon_test_host_small_api_response_handle_dispose( + GObject* object) { + CoreTestsPigeonTestHostSmallApiResponseHandle* self = + CORE_TESTS_PIGEON_TEST_HOST_SMALL_API_RESPONSE_HANDLE(object); + g_clear_object(&self->channel); + g_clear_object(&self->response_handle); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_small_api_response_handle_parent_class) + ->dispose(object); +} + +static void core_tests_pigeon_test_host_small_api_response_handle_init( + CoreTestsPigeonTestHostSmallApiResponseHandle* self) {} + +static void core_tests_pigeon_test_host_small_api_response_handle_class_init( + CoreTestsPigeonTestHostSmallApiResponseHandleClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_small_api_response_handle_dispose; +} + +static CoreTestsPigeonTestHostSmallApiResponseHandle* +core_tests_pigeon_test_host_small_api_response_handle_new( + FlBasicMessageChannel* channel, + FlBasicMessageChannelResponseHandle* response_handle) { + CoreTestsPigeonTestHostSmallApiResponseHandle* self = + CORE_TESTS_PIGEON_TEST_HOST_SMALL_API_RESPONSE_HANDLE(g_object_new( + core_tests_pigeon_test_host_small_api_response_handle_get_type(), + nullptr)); + self->channel = FL_BASIC_MESSAGE_CHANNEL(g_object_ref(channel)); + self->response_handle = + FL_BASIC_MESSAGE_CHANNEL_RESPONSE_HANDLE(g_object_ref(response_handle)); + return self; +} + +G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestHostSmallApiEchoResponse, + core_tests_pigeon_test_host_small_api_echo_response, + CORE_TESTS_PIGEON_TEST, HOST_SMALL_API_ECHO_RESPONSE, + GObject) + +struct _CoreTestsPigeonTestHostSmallApiEchoResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE(CoreTestsPigeonTestHostSmallApiEchoResponse, + core_tests_pigeon_test_host_small_api_echo_response, + G_TYPE_OBJECT) + +static void core_tests_pigeon_test_host_small_api_echo_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostSmallApiEchoResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_SMALL_API_ECHO_RESPONSE(object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_small_api_echo_response_parent_class) + ->dispose(object); +} + +static void core_tests_pigeon_test_host_small_api_echo_response_init( + CoreTestsPigeonTestHostSmallApiEchoResponse* self) {} + +static void core_tests_pigeon_test_host_small_api_echo_response_class_init( + CoreTestsPigeonTestHostSmallApiEchoResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_small_api_echo_response_dispose; +} + +static CoreTestsPigeonTestHostSmallApiEchoResponse* +core_tests_pigeon_test_host_small_api_echo_response_new( + const gchar* return_value) { + CoreTestsPigeonTestHostSmallApiEchoResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_SMALL_API_ECHO_RESPONSE(g_object_new( + core_tests_pigeon_test_host_small_api_echo_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(return_value)); + return self; +} + +static CoreTestsPigeonTestHostSmallApiEchoResponse* +core_tests_pigeon_test_host_small_api_echo_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostSmallApiEchoResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_SMALL_API_ECHO_RESPONSE(g_object_new( + core_tests_pigeon_test_host_small_api_echo_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestHostSmallApiVoidVoidResponse, + core_tests_pigeon_test_host_small_api_void_void_response, + CORE_TESTS_PIGEON_TEST, HOST_SMALL_API_VOID_VOID_RESPONSE, + GObject) + +struct _CoreTestsPigeonTestHostSmallApiVoidVoidResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE(CoreTestsPigeonTestHostSmallApiVoidVoidResponse, + core_tests_pigeon_test_host_small_api_void_void_response, + G_TYPE_OBJECT) + +static void core_tests_pigeon_test_host_small_api_void_void_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostSmallApiVoidVoidResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_SMALL_API_VOID_VOID_RESPONSE(object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_small_api_void_void_response_parent_class) + ->dispose(object); +} + +static void core_tests_pigeon_test_host_small_api_void_void_response_init( + CoreTestsPigeonTestHostSmallApiVoidVoidResponse* self) {} + +static void core_tests_pigeon_test_host_small_api_void_void_response_class_init( + CoreTestsPigeonTestHostSmallApiVoidVoidResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_small_api_void_void_response_dispose; +} + +static CoreTestsPigeonTestHostSmallApiVoidVoidResponse* +core_tests_pigeon_test_host_small_api_void_void_response_new() { + CoreTestsPigeonTestHostSmallApiVoidVoidResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_SMALL_API_VOID_VOID_RESPONSE(g_object_new( + core_tests_pigeon_test_host_small_api_void_void_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_null()); + return self; +} + +static CoreTestsPigeonTestHostSmallApiVoidVoidResponse* +core_tests_pigeon_test_host_small_api_void_void_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostSmallApiVoidVoidResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_SMALL_API_VOID_VOID_RESPONSE(g_object_new( + core_tests_pigeon_test_host_small_api_void_void_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestHostSmallApi, + core_tests_pigeon_test_host_small_api, + CORE_TESTS_PIGEON_TEST, HOST_SMALL_API, GObject) + +struct _CoreTestsPigeonTestHostSmallApi { + GObject parent_instance; + + const CoreTestsPigeonTestHostSmallApiVTable* vtable; + gpointer user_data; + GDestroyNotify user_data_free_func; +}; + +G_DEFINE_TYPE(CoreTestsPigeonTestHostSmallApi, + core_tests_pigeon_test_host_small_api, G_TYPE_OBJECT) + +static void core_tests_pigeon_test_host_small_api_dispose(GObject* object) { + CoreTestsPigeonTestHostSmallApi* self = + CORE_TESTS_PIGEON_TEST_HOST_SMALL_API(object); + if (self->user_data != nullptr) { + self->user_data_free_func(self->user_data); + } + self->user_data = nullptr; + G_OBJECT_CLASS(core_tests_pigeon_test_host_small_api_parent_class) + ->dispose(object); +} + +static void core_tests_pigeon_test_host_small_api_init( + CoreTestsPigeonTestHostSmallApi* self) {} + +static void core_tests_pigeon_test_host_small_api_class_init( + CoreTestsPigeonTestHostSmallApiClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_small_api_dispose; +} + +static CoreTestsPigeonTestHostSmallApi* +core_tests_pigeon_test_host_small_api_new( + const CoreTestsPigeonTestHostSmallApiVTable* vtable, gpointer user_data, + GDestroyNotify user_data_free_func) { + CoreTestsPigeonTestHostSmallApi* self = CORE_TESTS_PIGEON_TEST_HOST_SMALL_API( + g_object_new(core_tests_pigeon_test_host_small_api_get_type(), nullptr)); + self->vtable = vtable; + self->user_data = user_data; + self->user_data_free_func = user_data_free_func; + return self; +} + +static void core_tests_pigeon_test_host_small_api_echo_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostSmallApi* self = + CORE_TESTS_PIGEON_TEST_HOST_SMALL_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + const gchar* a_string = fl_value_get_string(value0); + g_autoptr(CoreTestsPigeonTestHostSmallApiResponseHandle) handle = + core_tests_pigeon_test_host_small_api_response_handle_new( + channel, response_handle); + self->vtable->echo(a_string, handle, self->user_data); +} + +static void core_tests_pigeon_test_host_small_api_void_void_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostSmallApi* self = + CORE_TESTS_PIGEON_TEST_HOST_SMALL_API(user_data); + + if (self->vtable == nullptr || self->vtable->void_void == nullptr) { + return; + } + + g_autoptr(CoreTestsPigeonTestHostSmallApiResponseHandle) handle = + core_tests_pigeon_test_host_small_api_response_handle_new( + channel, response_handle); + self->vtable->void_void(handle, self->user_data); +} + +void core_tests_pigeon_test_host_small_api_set_method_handlers( + FlBinaryMessenger* messenger, const gchar* suffix, + const CoreTestsPigeonTestHostSmallApiVTable* vtable, gpointer user_data, + GDestroyNotify user_data_free_func) { + g_autofree gchar* dot_suffix = + suffix != nullptr ? g_strdup_printf(".%s", suffix) : g_strdup(""); + g_autoptr(CoreTestsPigeonTestHostSmallApi) api_data = + core_tests_pigeon_test_host_small_api_new(vtable, user_data, + user_data_free_func); + + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + g_autofree gchar* echo_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostSmallApi.echo%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_channel = fl_basic_message_channel_new( + messenger, echo_channel_name, FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_channel, core_tests_pigeon_test_host_small_api_echo_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* void_void_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostSmallApi.voidVoid%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) void_void_channel = + fl_basic_message_channel_new(messenger, void_void_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + void_void_channel, core_tests_pigeon_test_host_small_api_void_void_cb, + g_object_ref(api_data), g_object_unref); +} + +void core_tests_pigeon_test_host_small_api_clear_method_handlers( + FlBinaryMessenger* messenger, const gchar* suffix) { + g_autofree gchar* dot_suffix = + suffix != nullptr ? g_strdup_printf(".%s", suffix) : g_strdup(""); + + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + g_autofree gchar* echo_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostSmallApi.echo%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_channel = fl_basic_message_channel_new( + messenger, echo_channel_name, FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_channel, nullptr, nullptr, + nullptr); + g_autofree gchar* void_void_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostSmallApi.voidVoid%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) void_void_channel = + fl_basic_message_channel_new(messenger, void_void_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(void_void_channel, nullptr, + nullptr, nullptr); +} + +void core_tests_pigeon_test_host_small_api_respond_echo( + CoreTestsPigeonTestHostSmallApiResponseHandle* response_handle, + const gchar* return_value) { + g_autoptr(CoreTestsPigeonTestHostSmallApiEchoResponse) response = + core_tests_pigeon_test_host_small_api_echo_response_new(return_value); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostSmallApi", "echo", + error->message); + } +} + +void core_tests_pigeon_test_host_small_api_respond_error_echo( + CoreTestsPigeonTestHostSmallApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr(CoreTestsPigeonTestHostSmallApiEchoResponse) response = + core_tests_pigeon_test_host_small_api_echo_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostSmallApi", "echo", + error->message); + } +} + +void core_tests_pigeon_test_host_small_api_respond_void_void( + CoreTestsPigeonTestHostSmallApiResponseHandle* response_handle) { + g_autoptr(CoreTestsPigeonTestHostSmallApiVoidVoidResponse) response = + core_tests_pigeon_test_host_small_api_void_void_response_new(); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostSmallApi", + "voidVoid", error->message); + } +} + +void core_tests_pigeon_test_host_small_api_respond_error_void_void( + CoreTestsPigeonTestHostSmallApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details) { + g_autoptr(CoreTestsPigeonTestHostSmallApiVoidVoidResponse) response = + core_tests_pigeon_test_host_small_api_void_void_response_new_error( + code, message, details); + g_autoptr(GError) error = nullptr; + if (!fl_basic_message_channel_respond(response_handle->channel, + response_handle->response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostSmallApi", + "voidVoid", error->message); + } +} + +struct _CoreTestsPigeonTestFlutterSmallApi { + GObject parent_instance; + + FlBinaryMessenger* messenger; + gchar* suffix; +}; + +G_DEFINE_TYPE(CoreTestsPigeonTestFlutterSmallApi, + core_tests_pigeon_test_flutter_small_api, G_TYPE_OBJECT) + +static void core_tests_pigeon_test_flutter_small_api_dispose(GObject* object) { + CoreTestsPigeonTestFlutterSmallApi* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_SMALL_API(object); + g_clear_object(&self->messenger); + g_clear_pointer(&self->suffix, g_free); + G_OBJECT_CLASS(core_tests_pigeon_test_flutter_small_api_parent_class) + ->dispose(object); +} + +static void core_tests_pigeon_test_flutter_small_api_init( + CoreTestsPigeonTestFlutterSmallApi* self) {} + +static void core_tests_pigeon_test_flutter_small_api_class_init( + CoreTestsPigeonTestFlutterSmallApiClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_small_api_dispose; +} + +CoreTestsPigeonTestFlutterSmallApi* +core_tests_pigeon_test_flutter_small_api_new(FlBinaryMessenger* messenger, + const gchar* suffix) { + CoreTestsPigeonTestFlutterSmallApi* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_SMALL_API(g_object_new( + core_tests_pigeon_test_flutter_small_api_get_type(), nullptr)); + self->messenger = FL_BINARY_MESSENGER(g_object_ref(messenger)); + self->suffix = + suffix != nullptr ? g_strdup_printf(".%s", suffix) : g_strdup(""); + return self; +} + +struct _CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse, + core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_SMALL_API_ECHO_WRAPPED_LIST_RESPONSE( + object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_init( + CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse* self) {} + +static void +core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_class_init( + CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_dispose; +} + +static CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse* +core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_SMALL_API_ECHO_WRAPPED_LIST_RESPONSE(g_object_new( + core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean +core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_is_error( + CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_SMALL_API_ECHO_WRAPPED_LIST_RESPONSE( + self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_get_error_code( + CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_SMALL_API_ECHO_WRAPPED_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_get_error_message( + CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_SMALL_API_ECHO_WRAPPED_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_get_error_details( + CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_SMALL_API_ECHO_WRAPPED_LIST_RESPONSE( + self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +CoreTestsPigeonTestTestMessage* +core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_get_return_value( + CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_SMALL_API_ECHO_WRAPPED_LIST_RESPONSE( + self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_is_error( + self)); + return CORE_TESTS_PIGEON_TEST_TEST_MESSAGE( + fl_value_get_custom_value_object(self->return_value)); +} + +static void core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_small_api_echo_wrapped_list( + CoreTestsPigeonTestFlutterSmallApi* self, + CoreTestsPigeonTestTestMessage* msg, GCancellable* cancellable, + GAsyncReadyCallback callback, gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, fl_value_new_custom_object(136, G_OBJECT(msg))); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterSmallApi." + "echoWrappedList%s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_cb, task); +} + +CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse* +core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_finish( + CoreTestsPigeonTestFlutterSmallApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_new( + response); +} + +struct _CoreTestsPigeonTestFlutterSmallApiEchoStringResponse { + GObject parent_instance; + + FlValue* error; + FlValue* return_value; +}; + +G_DEFINE_TYPE(CoreTestsPigeonTestFlutterSmallApiEchoStringResponse, + core_tests_pigeon_test_flutter_small_api_echo_string_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_flutter_small_api_echo_string_response_dispose( + GObject* object) { + CoreTestsPigeonTestFlutterSmallApiEchoStringResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_SMALL_API_ECHO_STRING_RESPONSE(object); + g_clear_pointer(&self->error, fl_value_unref); + g_clear_pointer(&self->return_value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_flutter_small_api_echo_string_response_parent_class) + ->dispose(object); +} + +static void core_tests_pigeon_test_flutter_small_api_echo_string_response_init( + CoreTestsPigeonTestFlutterSmallApiEchoStringResponse* self) {} + +static void +core_tests_pigeon_test_flutter_small_api_echo_string_response_class_init( + CoreTestsPigeonTestFlutterSmallApiEchoStringResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_flutter_small_api_echo_string_response_dispose; +} + +static CoreTestsPigeonTestFlutterSmallApiEchoStringResponse* +core_tests_pigeon_test_flutter_small_api_echo_string_response_new( + FlValue* response) { + CoreTestsPigeonTestFlutterSmallApiEchoStringResponse* self = + CORE_TESTS_PIGEON_TEST_FLUTTER_SMALL_API_ECHO_STRING_RESPONSE(g_object_new( + core_tests_pigeon_test_flutter_small_api_echo_string_response_get_type(), + nullptr)); + if (fl_value_get_length(response) > 1) { + self->error = fl_value_ref(response); + } else { + FlValue* value = fl_value_get_list_value(response, 0); + self->return_value = fl_value_ref(value); + } + return self; +} + +gboolean core_tests_pigeon_test_flutter_small_api_echo_string_response_is_error( + CoreTestsPigeonTestFlutterSmallApiEchoStringResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_SMALL_API_ECHO_STRING_RESPONSE(self), + FALSE); + return self->error != nullptr; +} + +const gchar* +core_tests_pigeon_test_flutter_small_api_echo_string_response_get_error_code( + CoreTestsPigeonTestFlutterSmallApiEchoStringResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_SMALL_API_ECHO_STRING_RESPONSE(self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_small_api_echo_string_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 0)); +} + +const gchar* +core_tests_pigeon_test_flutter_small_api_echo_string_response_get_error_message( + CoreTestsPigeonTestFlutterSmallApiEchoStringResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_SMALL_API_ECHO_STRING_RESPONSE(self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_small_api_echo_string_response_is_error( + self)); + return fl_value_get_string(fl_value_get_list_value(self->error, 1)); +} + +FlValue* +core_tests_pigeon_test_flutter_small_api_echo_string_response_get_error_details( + CoreTestsPigeonTestFlutterSmallApiEchoStringResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_SMALL_API_ECHO_STRING_RESPONSE(self), + nullptr); + g_assert( + core_tests_pigeon_test_flutter_small_api_echo_string_response_is_error( + self)); + return fl_value_get_list_value(self->error, 2); +} + +const gchar* +core_tests_pigeon_test_flutter_small_api_echo_string_response_get_return_value( + CoreTestsPigeonTestFlutterSmallApiEchoStringResponse* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_FLUTTER_SMALL_API_ECHO_STRING_RESPONSE(self), + nullptr); + g_assert( + !core_tests_pigeon_test_flutter_small_api_echo_string_response_is_error( + self)); + return fl_value_get_string(self->return_value); +} + +static void core_tests_pigeon_test_flutter_small_api_echo_string_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + GTask* task = G_TASK(user_data); + g_task_return_pointer(task, result, g_object_unref); +} + +void core_tests_pigeon_test_flutter_small_api_echo_string( + CoreTestsPigeonTestFlutterSmallApi* self, const gchar* a_string, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(FlValue) args = fl_value_new_list(); + fl_value_append_take(args, fl_value_new_string(a_string)); + g_autofree gchar* channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.FlutterSmallApi.echoString%" + "s", + self->suffix); + g_autoptr(CoreTestsPigeonTestMessageCodec) codec = + core_tests_pigeon_test_message_codec_new(); + FlBasicMessageChannel* channel = fl_basic_message_channel_new( + self->messenger, channel_name, FL_MESSAGE_CODEC(codec)); + GTask* task = g_task_new(self, cancellable, callback, user_data); + g_task_set_task_data(task, channel, g_object_unref); + fl_basic_message_channel_send( + channel, args, cancellable, + core_tests_pigeon_test_flutter_small_api_echo_string_cb, task); +} + +CoreTestsPigeonTestFlutterSmallApiEchoStringResponse* +core_tests_pigeon_test_flutter_small_api_echo_string_finish( + CoreTestsPigeonTestFlutterSmallApi* self, GAsyncResult* result, + GError** error) { + g_autoptr(GTask) task = G_TASK(result); + GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); + FlBasicMessageChannel* channel = + FL_BASIC_MESSAGE_CHANNEL(g_task_get_task_data(task)); + g_autoptr(FlValue) response = + fl_basic_message_channel_send_finish(channel, r, error); + if (response == nullptr) { + return nullptr; + } + return core_tests_pigeon_test_flutter_small_api_echo_string_response_new( + response); +} diff --git a/packages/pigeon/platform_tests/test_plugin/linux/pigeon/core_tests.gen.h b/packages/pigeon/platform_tests/test_plugin/linux/pigeon/core_tests.gen.h new file mode 100644 index 000000000000..6cb79ba18548 --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/linux/pigeon/core_tests.gen.h @@ -0,0 +1,12253 @@ +// 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, do not edit directly. +// See also: https://pub.dev/packages/pigeon + +#ifndef PIGEON_CORE_TESTS_GEN_H_ +#define PIGEON_CORE_TESTS_GEN_H_ + +#include + +G_BEGIN_DECLS + +/** + * CoreTestsPigeonTestAnEnum: + * PIGEON_INTEGRATION_TESTS_AN_ENUM_ONE: + * PIGEON_INTEGRATION_TESTS_AN_ENUM_TWO: + * PIGEON_INTEGRATION_TESTS_AN_ENUM_THREE: + * PIGEON_INTEGRATION_TESTS_AN_ENUM_FORTY_TWO: + * PIGEON_INTEGRATION_TESTS_AN_ENUM_FOUR_HUNDRED_TWENTY_TWO: + * + */ +typedef enum { + PIGEON_INTEGRATION_TESTS_AN_ENUM_ONE = 0, + PIGEON_INTEGRATION_TESTS_AN_ENUM_TWO = 1, + PIGEON_INTEGRATION_TESTS_AN_ENUM_THREE = 2, + PIGEON_INTEGRATION_TESTS_AN_ENUM_FORTY_TWO = 3, + PIGEON_INTEGRATION_TESTS_AN_ENUM_FOUR_HUNDRED_TWENTY_TWO = 4 +} CoreTestsPigeonTestAnEnum; + +/** + * CoreTestsPigeonTestAnotherEnum: + * PIGEON_INTEGRATION_TESTS_ANOTHER_ENUM_JUST_IN_CASE: + * + */ +typedef enum { + PIGEON_INTEGRATION_TESTS_ANOTHER_ENUM_JUST_IN_CASE = 0 +} CoreTestsPigeonTestAnotherEnum; + +/** + * CoreTestsPigeonTestUnusedClass: + * + */ + +G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestUnusedClass, + core_tests_pigeon_test_unused_class, + CORE_TESTS_PIGEON_TEST, UNUSED_CLASS, GObject) + +/** + * core_tests_pigeon_test_unused_class_new: + * a_field: field in this object. + * + * Creates a new #UnusedClass object. + * + * Returns: a new #CoreTestsPigeonTestUnusedClass + */ +CoreTestsPigeonTestUnusedClass* core_tests_pigeon_test_unused_class_new( + FlValue* a_field); + +/** + * core_tests_pigeon_test_unused_class_get_a_field + * @object: a #CoreTestsPigeonTestUnusedClass. + * + * Gets the value of the aField field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_unused_class_get_a_field( + CoreTestsPigeonTestUnusedClass* object); + +/** + * CoreTestsPigeonTestAllTypes: + * + * A class containing all supported types. + */ + +G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestAllTypes, + core_tests_pigeon_test_all_types, CORE_TESTS_PIGEON_TEST, + ALL_TYPES, GObject) + +/** + * core_tests_pigeon_test_all_types_new: + * a_bool: field in this object. + * an_int: field in this object. + * an_int64: field in this object. + * a_double: field in this object. + * a_byte_array: field in this object. + * a_byte_array_length: length of @a_byte_array. + * a4_byte_array: field in this object. + * a4_byte_array_length: length of @a4_byte_array. + * a8_byte_array: field in this object. + * a8_byte_array_length: length of @a8_byte_array. + * a_float_array: field in this object. + * a_float_array_length: length of @a_float_array. + * an_enum: field in this object. + * another_enum: field in this object. + * a_string: field in this object. + * an_object: field in this object. + * list: field in this object. + * string_list: field in this object. + * int_list: field in this object. + * double_list: field in this object. + * bool_list: field in this object. + * enum_list: field in this object. + * object_list: field in this object. + * list_list: field in this object. + * map_list: field in this object. + * map: field in this object. + * string_map: field in this object. + * int_map: field in this object. + * enum_map: field in this object. + * object_map: field in this object. + * list_map: field in this object. + * map_map: field in this object. + * + * Creates a new #AllTypes object. + * + * Returns: a new #CoreTestsPigeonTestAllTypes + */ +CoreTestsPigeonTestAllTypes* core_tests_pigeon_test_all_types_new( + gboolean a_bool, int64_t an_int, int64_t an_int64, double a_double, + const uint8_t* a_byte_array, size_t a_byte_array_length, + const int32_t* a4_byte_array, size_t a4_byte_array_length, + const int64_t* a8_byte_array, size_t a8_byte_array_length, + const double* a_float_array, size_t a_float_array_length, + CoreTestsPigeonTestAnEnum an_enum, + CoreTestsPigeonTestAnotherEnum another_enum, const gchar* a_string, + FlValue* an_object, FlValue* list, FlValue* string_list, FlValue* int_list, + FlValue* double_list, FlValue* bool_list, FlValue* enum_list, + FlValue* object_list, FlValue* list_list, FlValue* map_list, FlValue* map, + FlValue* string_map, FlValue* int_map, FlValue* enum_map, + FlValue* object_map, FlValue* list_map, FlValue* map_map); + +/** + * core_tests_pigeon_test_all_types_get_a_bool + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Gets the value of the aBool field of @object. + * + * Returns: the field value. + */ +gboolean core_tests_pigeon_test_all_types_get_a_bool( + CoreTestsPigeonTestAllTypes* object); + +/** + * core_tests_pigeon_test_all_types_get_an_int + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Gets the value of the anInt field of @object. + * + * Returns: the field value. + */ +int64_t core_tests_pigeon_test_all_types_get_an_int( + CoreTestsPigeonTestAllTypes* object); + +/** + * core_tests_pigeon_test_all_types_get_an_int64 + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Gets the value of the anInt64 field of @object. + * + * Returns: the field value. + */ +int64_t core_tests_pigeon_test_all_types_get_an_int64( + CoreTestsPigeonTestAllTypes* object); + +/** + * core_tests_pigeon_test_all_types_get_a_double + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Gets the value of the aDouble field of @object. + * + * Returns: the field value. + */ +double core_tests_pigeon_test_all_types_get_a_double( + CoreTestsPigeonTestAllTypes* object); + +/** + * core_tests_pigeon_test_all_types_get_a_byte_array + * @object: a #CoreTestsPigeonTestAllTypes. + * @length: location to write the length of this value. + * + * Gets the value of the aByteArray field of @object. + * + * Returns: the field value. + */ +const uint8_t* core_tests_pigeon_test_all_types_get_a_byte_array( + CoreTestsPigeonTestAllTypes* object, size_t* length); + +/** + * core_tests_pigeon_test_all_types_get_a4_byte_array + * @object: a #CoreTestsPigeonTestAllTypes. + * @length: location to write the length of this value. + * + * Gets the value of the a4ByteArray field of @object. + * + * Returns: the field value. + */ +const int32_t* core_tests_pigeon_test_all_types_get_a4_byte_array( + CoreTestsPigeonTestAllTypes* object, size_t* length); + +/** + * core_tests_pigeon_test_all_types_get_a8_byte_array + * @object: a #CoreTestsPigeonTestAllTypes. + * @length: location to write the length of this value. + * + * Gets the value of the a8ByteArray field of @object. + * + * Returns: the field value. + */ +const int64_t* core_tests_pigeon_test_all_types_get_a8_byte_array( + CoreTestsPigeonTestAllTypes* object, size_t* length); + +/** + * core_tests_pigeon_test_all_types_get_a_float_array + * @object: a #CoreTestsPigeonTestAllTypes. + * @length: location to write the length of this value. + * + * Gets the value of the aFloatArray field of @object. + * + * Returns: the field value. + */ +const double* core_tests_pigeon_test_all_types_get_a_float_array( + CoreTestsPigeonTestAllTypes* object, size_t* length); + +/** + * core_tests_pigeon_test_all_types_get_an_enum + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Gets the value of the anEnum field of @object. + * + * Returns: the field value. + */ +CoreTestsPigeonTestAnEnum core_tests_pigeon_test_all_types_get_an_enum( + CoreTestsPigeonTestAllTypes* object); + +/** + * core_tests_pigeon_test_all_types_get_another_enum + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Gets the value of the anotherEnum field of @object. + * + * Returns: the field value. + */ +CoreTestsPigeonTestAnotherEnum +core_tests_pigeon_test_all_types_get_another_enum( + CoreTestsPigeonTestAllTypes* object); + +/** + * core_tests_pigeon_test_all_types_get_a_string + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Gets the value of the aString field of @object. + * + * Returns: the field value. + */ +const gchar* core_tests_pigeon_test_all_types_get_a_string( + CoreTestsPigeonTestAllTypes* object); + +/** + * core_tests_pigeon_test_all_types_get_an_object + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Gets the value of the anObject field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_types_get_an_object( + CoreTestsPigeonTestAllTypes* object); + +/** + * core_tests_pigeon_test_all_types_get_list + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Gets the value of the list field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_types_get_list( + CoreTestsPigeonTestAllTypes* object); + +/** + * core_tests_pigeon_test_all_types_get_string_list + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Gets the value of the stringList field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_types_get_string_list( + CoreTestsPigeonTestAllTypes* object); + +/** + * core_tests_pigeon_test_all_types_get_int_list + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Gets the value of the intList field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_types_get_int_list( + CoreTestsPigeonTestAllTypes* object); + +/** + * core_tests_pigeon_test_all_types_get_double_list + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Gets the value of the doubleList field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_types_get_double_list( + CoreTestsPigeonTestAllTypes* object); + +/** + * core_tests_pigeon_test_all_types_get_bool_list + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Gets the value of the boolList field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_types_get_bool_list( + CoreTestsPigeonTestAllTypes* object); + +/** + * core_tests_pigeon_test_all_types_get_enum_list + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Gets the value of the enumList field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_types_get_enum_list( + CoreTestsPigeonTestAllTypes* object); + +/** + * core_tests_pigeon_test_all_types_get_object_list + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Gets the value of the objectList field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_types_get_object_list( + CoreTestsPigeonTestAllTypes* object); + +/** + * core_tests_pigeon_test_all_types_get_list_list + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Gets the value of the listList field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_types_get_list_list( + CoreTestsPigeonTestAllTypes* object); + +/** + * core_tests_pigeon_test_all_types_get_map_list + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Gets the value of the mapList field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_types_get_map_list( + CoreTestsPigeonTestAllTypes* object); + +/** + * core_tests_pigeon_test_all_types_get_map + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Gets the value of the map field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_types_get_map( + CoreTestsPigeonTestAllTypes* object); + +/** + * core_tests_pigeon_test_all_types_get_string_map + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Gets the value of the stringMap field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_types_get_string_map( + CoreTestsPigeonTestAllTypes* object); + +/** + * core_tests_pigeon_test_all_types_get_int_map + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Gets the value of the intMap field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_types_get_int_map( + CoreTestsPigeonTestAllTypes* object); + +/** + * core_tests_pigeon_test_all_types_get_enum_map + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Gets the value of the enumMap field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_types_get_enum_map( + CoreTestsPigeonTestAllTypes* object); + +/** + * core_tests_pigeon_test_all_types_get_object_map + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Gets the value of the objectMap field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_types_get_object_map( + CoreTestsPigeonTestAllTypes* object); + +/** + * core_tests_pigeon_test_all_types_get_list_map + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Gets the value of the listMap field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_types_get_list_map( + CoreTestsPigeonTestAllTypes* object); + +/** + * core_tests_pigeon_test_all_types_get_map_map + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Gets the value of the mapMap field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_types_get_map_map( + CoreTestsPigeonTestAllTypes* object); + +/** + * CoreTestsPigeonTestAllNullableTypes: + * + * A class containing all supported nullable types. + */ + +G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestAllNullableTypes, + core_tests_pigeon_test_all_nullable_types, + CORE_TESTS_PIGEON_TEST, ALL_NULLABLE_TYPES, GObject) + +/** + * core_tests_pigeon_test_all_nullable_types_new: + * a_nullable_bool: field in this object. + * a_nullable_int: field in this object. + * a_nullable_int64: field in this object. + * a_nullable_double: field in this object. + * a_nullable_byte_array: field in this object. + * a_nullable_byte_array_length: length of @a_nullable_byte_array. + * a_nullable4_byte_array: field in this object. + * a_nullable4_byte_array_length: length of @a_nullable4_byte_array. + * a_nullable8_byte_array: field in this object. + * a_nullable8_byte_array_length: length of @a_nullable8_byte_array. + * a_nullable_float_array: field in this object. + * a_nullable_float_array_length: length of @a_nullable_float_array. + * a_nullable_enum: field in this object. + * another_nullable_enum: field in this object. + * a_nullable_string: field in this object. + * a_nullable_object: field in this object. + * all_nullable_types: field in this object. + * list: field in this object. + * string_list: field in this object. + * int_list: field in this object. + * double_list: field in this object. + * bool_list: field in this object. + * enum_list: field in this object. + * object_list: field in this object. + * list_list: field in this object. + * map_list: field in this object. + * recursive_class_list: field in this object. + * map: field in this object. + * string_map: field in this object. + * int_map: field in this object. + * enum_map: field in this object. + * object_map: field in this object. + * list_map: field in this object. + * map_map: field in this object. + * recursive_class_map: field in this object. + * + * Creates a new #AllNullableTypes object. + * + * Returns: a new #CoreTestsPigeonTestAllNullableTypes + */ +CoreTestsPigeonTestAllNullableTypes* +core_tests_pigeon_test_all_nullable_types_new( + gboolean* a_nullable_bool, int64_t* a_nullable_int, + int64_t* a_nullable_int64, double* a_nullable_double, + const uint8_t* a_nullable_byte_array, size_t a_nullable_byte_array_length, + const int32_t* a_nullable4_byte_array, size_t a_nullable4_byte_array_length, + const int64_t* a_nullable8_byte_array, size_t a_nullable8_byte_array_length, + const double* a_nullable_float_array, size_t a_nullable_float_array_length, + CoreTestsPigeonTestAnEnum* a_nullable_enum, + CoreTestsPigeonTestAnotherEnum* another_nullable_enum, + const gchar* a_nullable_string, FlValue* a_nullable_object, + CoreTestsPigeonTestAllNullableTypes* all_nullable_types, FlValue* list, + FlValue* string_list, FlValue* int_list, FlValue* double_list, + FlValue* bool_list, FlValue* enum_list, FlValue* object_list, + FlValue* list_list, FlValue* map_list, FlValue* recursive_class_list, + FlValue* map, FlValue* string_map, FlValue* int_map, FlValue* enum_map, + FlValue* object_map, FlValue* list_map, FlValue* map_map, + FlValue* recursive_class_map); + +/** + * core_tests_pigeon_test_all_nullable_types_get_a_nullable_bool + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the aNullableBool field of @object. + * + * Returns: the field value. + */ +gboolean* core_tests_pigeon_test_all_nullable_types_get_a_nullable_bool( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_a_nullable_int + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the aNullableInt field of @object. + * + * Returns: the field value. + */ +int64_t* core_tests_pigeon_test_all_nullable_types_get_a_nullable_int( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_a_nullable_int64 + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the aNullableInt64 field of @object. + * + * Returns: the field value. + */ +int64_t* core_tests_pigeon_test_all_nullable_types_get_a_nullable_int64( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_a_nullable_double + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the aNullableDouble field of @object. + * + * Returns: the field value. + */ +double* core_tests_pigeon_test_all_nullable_types_get_a_nullable_double( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_a_nullable_byte_array + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * @length: location to write the length of this value. + * + * Gets the value of the aNullableByteArray field of @object. + * + * Returns: the field value. + */ +const uint8_t* +core_tests_pigeon_test_all_nullable_types_get_a_nullable_byte_array( + CoreTestsPigeonTestAllNullableTypes* object, size_t* length); + +/** + * core_tests_pigeon_test_all_nullable_types_get_a_nullable4_byte_array + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * @length: location to write the length of this value. + * + * Gets the value of the aNullable4ByteArray field of @object. + * + * Returns: the field value. + */ +const int32_t* +core_tests_pigeon_test_all_nullable_types_get_a_nullable4_byte_array( + CoreTestsPigeonTestAllNullableTypes* object, size_t* length); + +/** + * core_tests_pigeon_test_all_nullable_types_get_a_nullable8_byte_array + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * @length: location to write the length of this value. + * + * Gets the value of the aNullable8ByteArray field of @object. + * + * Returns: the field value. + */ +const int64_t* +core_tests_pigeon_test_all_nullable_types_get_a_nullable8_byte_array( + CoreTestsPigeonTestAllNullableTypes* object, size_t* length); + +/** + * core_tests_pigeon_test_all_nullable_types_get_a_nullable_float_array + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * @length: location to write the length of this value. + * + * Gets the value of the aNullableFloatArray field of @object. + * + * Returns: the field value. + */ +const double* +core_tests_pigeon_test_all_nullable_types_get_a_nullable_float_array( + CoreTestsPigeonTestAllNullableTypes* object, size_t* length); + +/** + * core_tests_pigeon_test_all_nullable_types_get_a_nullable_enum + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the aNullableEnum field of @object. + * + * Returns: the field value. + */ +CoreTestsPigeonTestAnEnum* +core_tests_pigeon_test_all_nullable_types_get_a_nullable_enum( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_another_nullable_enum + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the anotherNullableEnum field of @object. + * + * Returns: the field value. + */ +CoreTestsPigeonTestAnotherEnum* +core_tests_pigeon_test_all_nullable_types_get_another_nullable_enum( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_a_nullable_string + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the aNullableString field of @object. + * + * Returns: the field value. + */ +const gchar* core_tests_pigeon_test_all_nullable_types_get_a_nullable_string( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_a_nullable_object + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the aNullableObject field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_nullable_types_get_a_nullable_object( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_all_nullable_types + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the allNullableTypes field of @object. + * + * Returns: the field value. + */ +CoreTestsPigeonTestAllNullableTypes* +core_tests_pigeon_test_all_nullable_types_get_all_nullable_types( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_list + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the list field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_nullable_types_get_list( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_string_list + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the stringList field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_nullable_types_get_string_list( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_int_list + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the intList field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_nullable_types_get_int_list( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_double_list + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the doubleList field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_nullable_types_get_double_list( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_bool_list + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the boolList field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_nullable_types_get_bool_list( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_enum_list + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the enumList field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_nullable_types_get_enum_list( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_object_list + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the objectList field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_nullable_types_get_object_list( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_list_list + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the listList field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_nullable_types_get_list_list( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_map_list + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the mapList field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_nullable_types_get_map_list( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_recursive_class_list + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the recursiveClassList field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_nullable_types_get_recursive_class_list( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_map + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the map field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_nullable_types_get_map( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_string_map + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the stringMap field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_nullable_types_get_string_map( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_int_map + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the intMap field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_nullable_types_get_int_map( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_enum_map + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the enumMap field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_nullable_types_get_enum_map( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_object_map + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the objectMap field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_nullable_types_get_object_map( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_list_map + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the listMap field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_nullable_types_get_list_map( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_map_map + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the mapMap field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_nullable_types_get_map_map( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * core_tests_pigeon_test_all_nullable_types_get_recursive_class_map + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Gets the value of the recursiveClassMap field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_nullable_types_get_recursive_class_map( + CoreTestsPigeonTestAllNullableTypes* object); + +/** + * CoreTestsPigeonTestAllNullableTypesWithoutRecursion: + * + * The primary purpose for this class is to ensure coverage of Swift structs + * with nullable items, as the primary [AllNullableTypes] class is being used to + * test Swift classes. + */ + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion, + core_tests_pigeon_test_all_nullable_types_without_recursion, + CORE_TESTS_PIGEON_TEST, ALL_NULLABLE_TYPES_WITHOUT_RECURSION, GObject) + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_new: + * a_nullable_bool: field in this object. + * a_nullable_int: field in this object. + * a_nullable_int64: field in this object. + * a_nullable_double: field in this object. + * a_nullable_byte_array: field in this object. + * a_nullable_byte_array_length: length of @a_nullable_byte_array. + * a_nullable4_byte_array: field in this object. + * a_nullable4_byte_array_length: length of @a_nullable4_byte_array. + * a_nullable8_byte_array: field in this object. + * a_nullable8_byte_array_length: length of @a_nullable8_byte_array. + * a_nullable_float_array: field in this object. + * a_nullable_float_array_length: length of @a_nullable_float_array. + * a_nullable_enum: field in this object. + * another_nullable_enum: field in this object. + * a_nullable_string: field in this object. + * a_nullable_object: field in this object. + * list: field in this object. + * string_list: field in this object. + * int_list: field in this object. + * double_list: field in this object. + * bool_list: field in this object. + * enum_list: field in this object. + * object_list: field in this object. + * list_list: field in this object. + * map_list: field in this object. + * map: field in this object. + * string_map: field in this object. + * int_map: field in this object. + * enum_map: field in this object. + * object_map: field in this object. + * list_map: field in this object. + * map_map: field in this object. + * + * Creates a new #AllNullableTypesWithoutRecursion object. + * + * Returns: a new #CoreTestsPigeonTestAllNullableTypesWithoutRecursion + */ +CoreTestsPigeonTestAllNullableTypesWithoutRecursion* +core_tests_pigeon_test_all_nullable_types_without_recursion_new( + gboolean* a_nullable_bool, int64_t* a_nullable_int, + int64_t* a_nullable_int64, double* a_nullable_double, + const uint8_t* a_nullable_byte_array, size_t a_nullable_byte_array_length, + const int32_t* a_nullable4_byte_array, size_t a_nullable4_byte_array_length, + const int64_t* a_nullable8_byte_array, size_t a_nullable8_byte_array_length, + const double* a_nullable_float_array, size_t a_nullable_float_array_length, + CoreTestsPigeonTestAnEnum* a_nullable_enum, + CoreTestsPigeonTestAnotherEnum* another_nullable_enum, + const gchar* a_nullable_string, FlValue* a_nullable_object, FlValue* list, + FlValue* string_list, FlValue* int_list, FlValue* double_list, + FlValue* bool_list, FlValue* enum_list, FlValue* object_list, + FlValue* list_list, FlValue* map_list, FlValue* map, FlValue* string_map, + FlValue* int_map, FlValue* enum_map, FlValue* object_map, FlValue* list_map, + FlValue* map_map); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_bool + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Gets the value of the aNullableBool field of @object. + * + * Returns: the field value. + */ +gboolean* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_bool( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_int + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Gets the value of the aNullableInt field of @object. + * + * Returns: the field value. + */ +int64_t* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_int( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_int64 + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Gets the value of the aNullableInt64 field of @object. + * + * Returns: the field value. + */ +int64_t* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_int64( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_double + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Gets the value of the aNullableDouble field of @object. + * + * Returns: the field value. + */ +double* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_double( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_byte_array + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * @length: location to write the length of this value. + * + * Gets the value of the aNullableByteArray field of @object. + * + * Returns: the field value. + */ +const uint8_t* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_byte_array( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object, + size_t* length); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable4_byte_array + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * @length: location to write the length of this value. + * + * Gets the value of the aNullable4ByteArray field of @object. + * + * Returns: the field value. + */ +const int32_t* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable4_byte_array( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object, + size_t* length); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable8_byte_array + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * @length: location to write the length of this value. + * + * Gets the value of the aNullable8ByteArray field of @object. + * + * Returns: the field value. + */ +const int64_t* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable8_byte_array( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object, + size_t* length); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_float_array + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * @length: location to write the length of this value. + * + * Gets the value of the aNullableFloatArray field of @object. + * + * Returns: the field value. + */ +const double* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_float_array( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object, + size_t* length); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_enum + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Gets the value of the aNullableEnum field of @object. + * + * Returns: the field value. + */ +CoreTestsPigeonTestAnEnum* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_enum( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_another_nullable_enum + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Gets the value of the anotherNullableEnum field of @object. + * + * Returns: the field value. + */ +CoreTestsPigeonTestAnotherEnum* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_another_nullable_enum( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_string + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Gets the value of the aNullableString field of @object. + * + * Returns: the field value. + */ +const gchar* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_string( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_object + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Gets the value of the aNullableObject field of @object. + * + * Returns: the field value. + */ +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_a_nullable_object( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_list + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Gets the value of the list field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_nullable_types_without_recursion_get_list( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_string_list + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Gets the value of the stringList field of @object. + * + * Returns: the field value. + */ +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_string_list( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_int_list + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Gets the value of the intList field of @object. + * + * Returns: the field value. + */ +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_int_list( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_double_list + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Gets the value of the doubleList field of @object. + * + * Returns: the field value. + */ +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_double_list( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_bool_list + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Gets the value of the boolList field of @object. + * + * Returns: the field value. + */ +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_bool_list( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_enum_list + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Gets the value of the enumList field of @object. + * + * Returns: the field value. + */ +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_enum_list( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_object_list + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Gets the value of the objectList field of @object. + * + * Returns: the field value. + */ +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_object_list( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_list_list + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Gets the value of the listList field of @object. + * + * Returns: the field value. + */ +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_list_list( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_map_list + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Gets the value of the mapList field of @object. + * + * Returns: the field value. + */ +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_map_list( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_map + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Gets the value of the map field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_nullable_types_without_recursion_get_map( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_string_map + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Gets the value of the stringMap field of @object. + * + * Returns: the field value. + */ +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_string_map( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_int_map + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Gets the value of the intMap field of @object. + * + * Returns: the field value. + */ +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_int_map( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_enum_map + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Gets the value of the enumMap field of @object. + * + * Returns: the field value. + */ +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_enum_map( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_object_map + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Gets the value of the objectMap field of @object. + * + * Returns: the field value. + */ +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_object_map( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_list_map + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Gets the value of the listMap field of @object. + * + * Returns: the field value. + */ +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_list_map( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_get_map_map + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Gets the value of the mapMap field of @object. + * + * Returns: the field value. + */ +FlValue* +core_tests_pigeon_test_all_nullable_types_without_recursion_get_map_map( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + +/** + * CoreTestsPigeonTestAllClassesWrapper: + * + * A class for testing nested class handling. + * + * This is needed to test nested nullable and non-nullable classes, + * `AllNullableTypes` is non-nullable here as it is easier to instantiate + * than `AllTypes` when testing doesn't require both (ie. testing null classes). + */ + +G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestAllClassesWrapper, + core_tests_pigeon_test_all_classes_wrapper, + CORE_TESTS_PIGEON_TEST, ALL_CLASSES_WRAPPER, GObject) + +/** + * core_tests_pigeon_test_all_classes_wrapper_new: + * all_nullable_types: field in this object. + * all_nullable_types_without_recursion: field in this object. + * all_types: field in this object. + * class_list: field in this object. + * nullable_class_list: field in this object. + * class_map: field in this object. + * nullable_class_map: field in this object. + * + * Creates a new #AllClassesWrapper object. + * + * Returns: a new #CoreTestsPigeonTestAllClassesWrapper + */ +CoreTestsPigeonTestAllClassesWrapper* +core_tests_pigeon_test_all_classes_wrapper_new( + CoreTestsPigeonTestAllNullableTypes* all_nullable_types, + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* + all_nullable_types_without_recursion, + CoreTestsPigeonTestAllTypes* all_types, FlValue* class_list, + FlValue* nullable_class_list, FlValue* class_map, + FlValue* nullable_class_map); + +/** + * core_tests_pigeon_test_all_classes_wrapper_get_all_nullable_types + * @object: a #CoreTestsPigeonTestAllClassesWrapper. + * + * Gets the value of the allNullableTypes field of @object. + * + * Returns: the field value. + */ +CoreTestsPigeonTestAllNullableTypes* +core_tests_pigeon_test_all_classes_wrapper_get_all_nullable_types( + CoreTestsPigeonTestAllClassesWrapper* object); + +/** + * core_tests_pigeon_test_all_classes_wrapper_get_all_nullable_types_without_recursion + * @object: a #CoreTestsPigeonTestAllClassesWrapper. + * + * Gets the value of the allNullableTypesWithoutRecursion field of @object. + * + * Returns: the field value. + */ +CoreTestsPigeonTestAllNullableTypesWithoutRecursion* +core_tests_pigeon_test_all_classes_wrapper_get_all_nullable_types_without_recursion( + CoreTestsPigeonTestAllClassesWrapper* object); + +/** + * core_tests_pigeon_test_all_classes_wrapper_get_all_types + * @object: a #CoreTestsPigeonTestAllClassesWrapper. + * + * Gets the value of the allTypes field of @object. + * + * Returns: the field value. + */ +CoreTestsPigeonTestAllTypes* +core_tests_pigeon_test_all_classes_wrapper_get_all_types( + CoreTestsPigeonTestAllClassesWrapper* object); + +/** + * core_tests_pigeon_test_all_classes_wrapper_get_class_list + * @object: a #CoreTestsPigeonTestAllClassesWrapper. + * + * Gets the value of the classList field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_classes_wrapper_get_class_list( + CoreTestsPigeonTestAllClassesWrapper* object); + +/** + * core_tests_pigeon_test_all_classes_wrapper_get_nullable_class_list + * @object: a #CoreTestsPigeonTestAllClassesWrapper. + * + * Gets the value of the nullableClassList field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_classes_wrapper_get_nullable_class_list( + CoreTestsPigeonTestAllClassesWrapper* object); + +/** + * core_tests_pigeon_test_all_classes_wrapper_get_class_map + * @object: a #CoreTestsPigeonTestAllClassesWrapper. + * + * Gets the value of the classMap field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_classes_wrapper_get_class_map( + CoreTestsPigeonTestAllClassesWrapper* object); + +/** + * core_tests_pigeon_test_all_classes_wrapper_get_nullable_class_map + * @object: a #CoreTestsPigeonTestAllClassesWrapper. + * + * Gets the value of the nullableClassMap field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_all_classes_wrapper_get_nullable_class_map( + CoreTestsPigeonTestAllClassesWrapper* object); + +/** + * CoreTestsPigeonTestTestMessage: + * + * A data class containing a List, used in unit tests. + */ + +G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestTestMessage, + core_tests_pigeon_test_test_message, + CORE_TESTS_PIGEON_TEST, TEST_MESSAGE, GObject) + +/** + * core_tests_pigeon_test_test_message_new: + * test_list: field in this object. + * + * Creates a new #TestMessage object. + * + * Returns: a new #CoreTestsPigeonTestTestMessage + */ +CoreTestsPigeonTestTestMessage* core_tests_pigeon_test_test_message_new( + FlValue* test_list); + +/** + * core_tests_pigeon_test_test_message_get_test_list + * @object: a #CoreTestsPigeonTestTestMessage. + * + * Gets the value of the testList field of @object. + * + * Returns: the field value. + */ +FlValue* core_tests_pigeon_test_test_message_get_test_list( + CoreTestsPigeonTestTestMessage* object); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle, + core_tests_pigeon_test_host_integration_core_api_response_handle, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_RESPONSE_HANDLE, GObject) + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiNoopResponse, + core_tests_pigeon_test_host_integration_core_api_noop_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_NOOP_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_noop_response_new: + * + * Creates a new response to HostIntegrationCoreApi.noop. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiNoopResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiNoopResponse* +core_tests_pigeon_test_host_integration_core_api_noop_response_new(); + +/** + * core_tests_pigeon_test_host_integration_core_api_noop_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.noop. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiNoopResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiNoopResponse* +core_tests_pigeon_test_host_integration_core_api_noop_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllTypesResponse, + core_tests_pigeon_test_host_integration_core_api_echo_all_types_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_ALL_TYPES_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_all_types_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoAllTypes. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoAllTypesResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoAllTypesResponse* +core_tests_pigeon_test_host_integration_core_api_echo_all_types_response_new( + CoreTestsPigeonTestAllTypes* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_all_types_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoAllTypes. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoAllTypesResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoAllTypesResponse* +core_tests_pigeon_test_host_integration_core_api_echo_all_types_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorResponse, + core_tests_pigeon_test_host_integration_core_api_throw_error_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_THROW_ERROR_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_throw_error_response_new: + * + * Creates a new response to HostIntegrationCoreApi.throwError. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorResponse* +core_tests_pigeon_test_host_integration_core_api_throw_error_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_throw_error_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.throwError. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorResponse* +core_tests_pigeon_test_host_integration_core_api_throw_error_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorFromVoidResponse, + core_tests_pigeon_test_host_integration_core_api_throw_error_from_void_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_THROW_ERROR_FROM_VOID_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_throw_error_from_void_response_new: + * + * Creates a new response to HostIntegrationCoreApi.throwErrorFromVoid. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorFromVoidResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorFromVoidResponse* +core_tests_pigeon_test_host_integration_core_api_throw_error_from_void_response_new(); + +/** + * core_tests_pigeon_test_host_integration_core_api_throw_error_from_void_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.throwErrorFromVoid. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorFromVoidResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorFromVoidResponse* +core_tests_pigeon_test_host_integration_core_api_throw_error_from_void_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiThrowFlutterErrorResponse, + core_tests_pigeon_test_host_integration_core_api_throw_flutter_error_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_THROW_FLUTTER_ERROR_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_throw_flutter_error_response_new: + * + * Creates a new response to HostIntegrationCoreApi.throwFlutterError. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiThrowFlutterErrorResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiThrowFlutterErrorResponse* +core_tests_pigeon_test_host_integration_core_api_throw_flutter_error_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_throw_flutter_error_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.throwFlutterError. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiThrowFlutterErrorResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiThrowFlutterErrorResponse* +core_tests_pigeon_test_host_integration_core_api_throw_flutter_error_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoIntResponse, + core_tests_pigeon_test_host_integration_core_api_echo_int_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_INT_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_int_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoInt. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoIntResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoIntResponse* +core_tests_pigeon_test_host_integration_core_api_echo_int_response_new( + int64_t return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_int_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoInt. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoIntResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoIntResponse* +core_tests_pigeon_test_host_integration_core_api_echo_int_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleResponse, + core_tests_pigeon_test_host_integration_core_api_echo_double_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_DOUBLE_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_double_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoDouble. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleResponse* +core_tests_pigeon_test_host_integration_core_api_echo_double_response_new( + double return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_double_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoDouble. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleResponse* +core_tests_pigeon_test_host_integration_core_api_echo_double_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponse, + core_tests_pigeon_test_host_integration_core_api_echo_bool_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_BOOL_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_bool_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoBool. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponse* +core_tests_pigeon_test_host_integration_core_api_echo_bool_response_new( + gboolean return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_bool_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoBool. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponse* +core_tests_pigeon_test_host_integration_core_api_echo_bool_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse, + core_tests_pigeon_test_host_integration_core_api_echo_string_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_STRING_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_string_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoString. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse* +core_tests_pigeon_test_host_integration_core_api_echo_string_response_new( + const gchar* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_string_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoString. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse* +core_tests_pigeon_test_host_integration_core_api_echo_string_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_UINT8_LIST_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoUint8List. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_new( + const uint8_t* return_value, size_t return_value_length); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoUint8List. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse, + core_tests_pigeon_test_host_integration_core_api_echo_object_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_OBJECT_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_object_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoObject. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse* +core_tests_pigeon_test_host_integration_core_api_echo_object_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_object_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoObject. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse* +core_tests_pigeon_test_host_integration_core_api_echo_object_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_list_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_LIST_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_list_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoList. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_list_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_list_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoList. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_enum_list_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_ENUM_LIST_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_enum_list_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoEnumList. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_enum_list_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_enum_list_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoEnumList. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_enum_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoClassListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_class_list_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_CLASS_LIST_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_class_list_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoClassList. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoClassListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoClassListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_class_list_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_class_list_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoClassList. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoClassListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoClassListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_class_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NON_NULL_ENUM_LIST_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_list_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNonNullEnumList. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_list_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_list_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoNonNullEnumList. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NON_NULL_CLASS_LIST_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_list_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNonNullClassList. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_list_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_list_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoNonNullClassList. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_map_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_MAP_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_map_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoMap. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_map_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_map_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoMap. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_string_map_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_STRING_MAP_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_string_map_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoStringMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoStringMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_string_map_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_string_map_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoStringMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoStringMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_string_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoIntMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_int_map_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_INT_MAP_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_int_map_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoIntMap. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoIntMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_int_map_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_int_map_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoIntMap. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoIntMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_int_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_enum_map_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_ENUM_MAP_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_enum_map_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoEnumMap. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_enum_map_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_enum_map_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoEnumMap. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_enum_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoClassMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_class_map_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_CLASS_MAP_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_class_map_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoClassMap. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoClassMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_class_map_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_class_map_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoClassMap. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoClassMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_class_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullStringMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_non_null_string_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NON_NULL_STRING_MAP_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_non_null_string_map_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNonNullStringMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullStringMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_non_null_string_map_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_non_null_string_map_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoNonNullStringMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullStringMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_non_null_string_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullIntMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_non_null_int_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NON_NULL_INT_MAP_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_non_null_int_map_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNonNullIntMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullIntMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_non_null_int_map_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_non_null_int_map_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoNonNullIntMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullIntMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_non_null_int_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NON_NULL_ENUM_MAP_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_map_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNonNullEnumMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_map_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_map_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoNonNullEnumMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NON_NULL_CLASS_MAP_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_map_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNonNullClassMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_map_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_map_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoNonNullClassMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoClassWrapperResponse, + core_tests_pigeon_test_host_integration_core_api_echo_class_wrapper_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_CLASS_WRAPPER_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_class_wrapper_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoClassWrapper. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoClassWrapperResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoClassWrapperResponse* +core_tests_pigeon_test_host_integration_core_api_echo_class_wrapper_response_new( + CoreTestsPigeonTestAllClassesWrapper* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_class_wrapper_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoClassWrapper. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoClassWrapperResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoClassWrapperResponse* +core_tests_pigeon_test_host_integration_core_api_echo_class_wrapper_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumResponse, + core_tests_pigeon_test_host_integration_core_api_echo_enum_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_ENUM_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_enum_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoEnum. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumResponse* +core_tests_pigeon_test_host_integration_core_api_echo_enum_response_new( + CoreTestsPigeonTestAnEnum return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_enum_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoEnum. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumResponse* +core_tests_pigeon_test_host_integration_core_api_echo_enum_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherEnumResponse, + core_tests_pigeon_test_host_integration_core_api_echo_another_enum_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ANOTHER_ENUM_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_another_enum_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoAnotherEnum. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherEnumResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherEnumResponse* +core_tests_pigeon_test_host_integration_core_api_echo_another_enum_response_new( + CoreTestsPigeonTestAnotherEnum return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_another_enum_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoAnotherEnum. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherEnumResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherEnumResponse* +core_tests_pigeon_test_host_integration_core_api_echo_another_enum_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedDefaultStringResponse, + core_tests_pigeon_test_host_integration_core_api_echo_named_default_string_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NAMED_DEFAULT_STRING_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_named_default_string_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNamedDefaultString. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedDefaultStringResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedDefaultStringResponse* +core_tests_pigeon_test_host_integration_core_api_echo_named_default_string_response_new( + const gchar* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_named_default_string_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to + * HostIntegrationCoreApi.echoNamedDefaultString. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedDefaultStringResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedDefaultStringResponse* +core_tests_pigeon_test_host_integration_core_api_echo_named_default_string_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalDefaultDoubleResponse, + core_tests_pigeon_test_host_integration_core_api_echo_optional_default_double_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_OPTIONAL_DEFAULT_DOUBLE_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_optional_default_double_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoOptionalDefaultDouble. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalDefaultDoubleResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalDefaultDoubleResponse* +core_tests_pigeon_test_host_integration_core_api_echo_optional_default_double_response_new( + double return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_optional_default_double_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to + * HostIntegrationCoreApi.echoOptionalDefaultDouble. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalDefaultDoubleResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalDefaultDoubleResponse* +core_tests_pigeon_test_host_integration_core_api_echo_optional_default_double_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoRequiredIntResponse, + core_tests_pigeon_test_host_integration_core_api_echo_required_int_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_REQUIRED_INT_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_required_int_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoRequiredInt. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoRequiredIntResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoRequiredIntResponse* +core_tests_pigeon_test_host_integration_core_api_echo_required_int_response_new( + int64_t return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_required_int_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoRequiredInt. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoRequiredIntResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoRequiredIntResponse* +core_tests_pigeon_test_host_integration_core_api_echo_required_int_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesResponse, + core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ALL_NULLABLE_TYPES_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoAllNullableTypes. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesResponse* +core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_response_new( + CoreTestsPigeonTestAllNullableTypes* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoAllNullableTypes. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesResponse* +core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse, + core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_without_recursion_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ALL_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_without_recursion_response_new: + * + * Creates a new response to + * HostIntegrationCoreApi.echoAllNullableTypesWithoutRecursion. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* +core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_without_recursion_response_new( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_without_recursion_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to + * HostIntegrationCoreApi.echoAllNullableTypesWithoutRecursion. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* +core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_without_recursion_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiExtractNestedNullableStringResponse, + core_tests_pigeon_test_host_integration_core_api_extract_nested_nullable_string_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_EXTRACT_NESTED_NULLABLE_STRING_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_extract_nested_nullable_string_response_new: + * + * Creates a new response to HostIntegrationCoreApi.extractNestedNullableString. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiExtractNestedNullableStringResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiExtractNestedNullableStringResponse* +core_tests_pigeon_test_host_integration_core_api_extract_nested_nullable_string_response_new( + const gchar* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_extract_nested_nullable_string_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to + * HostIntegrationCoreApi.extractNestedNullableString. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiExtractNestedNullableStringResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiExtractNestedNullableStringResponse* +core_tests_pigeon_test_host_integration_core_api_extract_nested_nullable_string_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiCreateNestedNullableStringResponse, + core_tests_pigeon_test_host_integration_core_api_create_nested_nullable_string_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_CREATE_NESTED_NULLABLE_STRING_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_create_nested_nullable_string_response_new: + * + * Creates a new response to HostIntegrationCoreApi.createNestedNullableString. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiCreateNestedNullableStringResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiCreateNestedNullableStringResponse* +core_tests_pigeon_test_host_integration_core_api_create_nested_nullable_string_response_new( + CoreTestsPigeonTestAllClassesWrapper* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_create_nested_nullable_string_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to + * HostIntegrationCoreApi.createNestedNullableString. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiCreateNestedNullableStringResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiCreateNestedNullableStringResponse* +core_tests_pigeon_test_host_integration_core_api_create_nested_nullable_string_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesResponse, + core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_SEND_MULTIPLE_NULLABLE_TYPES_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_response_new: + * + * Creates a new response to HostIntegrationCoreApi.sendMultipleNullableTypes. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesResponse* +core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_response_new( + CoreTestsPigeonTestAllNullableTypes* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to + * HostIntegrationCoreApi.sendMultipleNullableTypes. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesResponse* +core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse, + core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_without_recursion_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_SEND_MULTIPLE_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_without_recursion_response_new: + * + * Creates a new response to + * HostIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* +core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_without_recursion_response_new( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_without_recursion_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to + * HostIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* +core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_without_recursion_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_INT_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNullableInt. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_response_new( + int64_t* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoNullableInt. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableDoubleResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_double_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_DOUBLE_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_double_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNullableDouble. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableDoubleResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableDoubleResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_double_response_new( + double* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_double_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoNullableDouble. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableDoubleResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableDoubleResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_double_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableBoolResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_bool_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_BOOL_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_bool_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNullableBool. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableBoolResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableBoolResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_bool_response_new( + gboolean* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_bool_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoNullableBool. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableBoolResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableBoolResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_bool_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_STRING_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNullableString. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_response_new( + const gchar* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoNullableString. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableUint8ListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_uint8_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_UINT8_LIST_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_uint8_list_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNullableUint8List. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableUint8ListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableUint8ListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_uint8_list_response_new( + const uint8_t* return_value, size_t return_value_length); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_uint8_list_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoNullableUint8List. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableUint8ListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableUint8ListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_uint8_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableObjectResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_object_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_OBJECT_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_object_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNullableObject. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableObjectResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableObjectResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_object_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_object_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoNullableObject. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableObjectResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableObjectResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_object_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_LIST_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_list_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNullableList. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_list_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_list_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoNullableList. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_LIST_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_list_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNullableEnumList. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_list_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_list_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoNullableEnumList. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_CLASS_LIST_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_list_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNullableClassList. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_list_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_list_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoNullableClassList. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_ENUM_LIST_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_list_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNullableNonNullEnumList. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_list_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_list_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to + * HostIntegrationCoreApi.echoNullableNonNullEnumList. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_list_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_CLASS_LIST_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_list_response_new: + * + * Creates a new response to + * HostIntegrationCoreApi.echoNullableNonNullClassList. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_list_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_list_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to + * HostIntegrationCoreApi.echoNullableNonNullClassList. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_MAP_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_map_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNullableMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_map_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_map_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoNullableMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_STRING_MAP_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_map_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNullableStringMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_map_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_map_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoNullableStringMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_INT_MAP_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_map_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNullableIntMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_map_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_map_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoNullableIntMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_MAP_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_map_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNullableEnumMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_map_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_map_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoNullableEnumMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_CLASS_MAP_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_map_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNullableClassMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_map_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_map_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoNullableClassMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullStringMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_string_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_STRING_MAP_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_string_map_response_new: + * + * Creates a new response to + * HostIntegrationCoreApi.echoNullableNonNullStringMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullStringMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_string_map_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_string_map_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to + * HostIntegrationCoreApi.echoNullableNonNullStringMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullStringMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullStringMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_string_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullIntMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_int_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_INT_MAP_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_int_map_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNullableNonNullIntMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullIntMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_int_map_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_int_map_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to + * HostIntegrationCoreApi.echoNullableNonNullIntMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullIntMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullIntMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_int_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_ENUM_MAP_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_map_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNullableNonNullEnumMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_map_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_map_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to + * HostIntegrationCoreApi.echoNullableNonNullEnumMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassMapResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_map_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_CLASS_MAP_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_map_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNullableNonNullClassMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_map_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_map_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to + * HostIntegrationCoreApi.echoNullableNonNullClassMap. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassMapResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassMapResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_map_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumResponse, + core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNullableEnum. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_response_new( + CoreTestsPigeonTestAnEnum* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoNullableEnum. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumResponse* +core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherNullableEnumResponse, + core_tests_pigeon_test_host_integration_core_api_echo_another_nullable_enum_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_ANOTHER_NULLABLE_ENUM_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_another_nullable_enum_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoAnotherNullableEnum. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherNullableEnumResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherNullableEnumResponse* +core_tests_pigeon_test_host_integration_core_api_echo_another_nullable_enum_response_new( + CoreTestsPigeonTestAnotherEnum* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_another_nullable_enum_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to + * HostIntegrationCoreApi.echoAnotherNullableEnum. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherNullableEnumResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherNullableEnumResponse* +core_tests_pigeon_test_host_integration_core_api_echo_another_nullable_enum_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalNullableIntResponse, + core_tests_pigeon_test_host_integration_core_api_echo_optional_nullable_int_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_OPTIONAL_NULLABLE_INT_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_optional_nullable_int_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoOptionalNullableInt. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalNullableIntResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalNullableIntResponse* +core_tests_pigeon_test_host_integration_core_api_echo_optional_nullable_int_response_new( + int64_t* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_optional_nullable_int_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to + * HostIntegrationCoreApi.echoOptionalNullableInt. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalNullableIntResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalNullableIntResponse* +core_tests_pigeon_test_host_integration_core_api_echo_optional_nullable_int_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedNullableStringResponse, + core_tests_pigeon_test_host_integration_core_api_echo_named_nullable_string_response, + CORE_TESTS_PIGEON_TEST, + HOST_INTEGRATION_CORE_API_ECHO_NAMED_NULLABLE_STRING_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_named_nullable_string_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoNamedNullableString. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedNullableStringResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedNullableStringResponse* +core_tests_pigeon_test_host_integration_core_api_echo_named_nullable_string_response_new( + const gchar* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_named_nullable_string_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to + * HostIntegrationCoreApi.echoNamedNullableString. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedNullableStringResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedNullableStringResponse* +core_tests_pigeon_test_host_integration_core_api_echo_named_nullable_string_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +/** + * CoreTestsPigeonTestHostIntegrationCoreApiVTable: + * + * Table of functions exposed by HostIntegrationCoreApi to be implemented by the + * API provider. + */ +typedef struct { + CoreTestsPigeonTestHostIntegrationCoreApiNoopResponse* (*noop)( + gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllTypesResponse* ( + *echo_all_types)(CoreTestsPigeonTestAllTypes* everything, + gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorResponse* (*throw_error)( + gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorFromVoidResponse* ( + *throw_error_from_void)(gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiThrowFlutterErrorResponse* ( + *throw_flutter_error)(gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoIntResponse* (*echo_int)( + int64_t an_int, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleResponse* (*echo_double)( + double a_double, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponse* (*echo_bool)( + gboolean a_bool, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse* (*echo_string)( + const gchar* a_string, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse* ( + *echo_uint8_list)(const uint8_t* a_uint8_list, size_t a_uint8_list_length, + gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse* (*echo_object)( + FlValue* an_object, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* (*echo_list)( + FlValue* list, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumListResponse* ( + *echo_enum_list)(FlValue* enum_list, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoClassListResponse* ( + *echo_class_list)(FlValue* class_list, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumListResponse* ( + *echo_non_null_enum_list)(FlValue* enum_list, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassListResponse* ( + *echo_non_null_class_list)(FlValue* class_list, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoMapResponse* (*echo_map)( + FlValue* map, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringMapResponse* ( + *echo_string_map)(FlValue* string_map, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoIntMapResponse* (*echo_int_map)( + FlValue* int_map, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumMapResponse* ( + *echo_enum_map)(FlValue* enum_map, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoClassMapResponse* ( + *echo_class_map)(FlValue* class_map, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullStringMapResponse* ( + *echo_non_null_string_map)(FlValue* string_map, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullIntMapResponse* ( + *echo_non_null_int_map)(FlValue* int_map, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumMapResponse* ( + *echo_non_null_enum_map)(FlValue* enum_map, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassMapResponse* ( + *echo_non_null_class_map)(FlValue* class_map, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoClassWrapperResponse* ( + *echo_class_wrapper)(CoreTestsPigeonTestAllClassesWrapper* wrapper, + gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumResponse* (*echo_enum)( + CoreTestsPigeonTestAnEnum an_enum, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherEnumResponse* ( + *echo_another_enum)(CoreTestsPigeonTestAnotherEnum another_enum, + gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedDefaultStringResponse* ( + *echo_named_default_string)(const gchar* a_string, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalDefaultDoubleResponse* ( + *echo_optional_default_double)(double a_double, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoRequiredIntResponse* ( + *echo_required_int)(int64_t an_int, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesResponse* ( + *echo_all_nullable_types)(CoreTestsPigeonTestAllNullableTypes* everything, + gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* ( + *echo_all_nullable_types_without_recursion)( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* everything, + gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiExtractNestedNullableStringResponse* ( + *extract_nested_nullable_string)( + CoreTestsPigeonTestAllClassesWrapper* wrapper, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiCreateNestedNullableStringResponse* ( + *create_nested_nullable_string)(const gchar* nullable_string, + gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesResponse* ( + *send_multiple_nullable_types)(gboolean* a_nullable_bool, + int64_t* a_nullable_int, + const gchar* a_nullable_string, + gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* ( + *send_multiple_nullable_types_without_recursion)( + gboolean* a_nullable_bool, int64_t* a_nullable_int, + const gchar* a_nullable_string, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntResponse* ( + *echo_nullable_int)(int64_t* a_nullable_int, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableDoubleResponse* ( + *echo_nullable_double)(double* a_nullable_double, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableBoolResponse* ( + *echo_nullable_bool)(gboolean* a_nullable_bool, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringResponse* ( + *echo_nullable_string)(const gchar* a_nullable_string, + gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableUint8ListResponse* ( + *echo_nullable_uint8_list)(const uint8_t* a_nullable_uint8_list, + size_t a_nullable_uint8_list_length, + gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableObjectResponse* ( + *echo_nullable_object)(FlValue* a_nullable_object, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableListResponse* ( + *echo_nullable_list)(FlValue* a_nullable_list, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumListResponse* ( + *echo_nullable_enum_list)(FlValue* enum_list, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassListResponse* ( + *echo_nullable_class_list)(FlValue* class_list, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumListResponse* ( + *echo_nullable_non_null_enum_list)(FlValue* enum_list, + gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassListResponse* ( + *echo_nullable_non_null_class_list)(FlValue* class_list, + gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableMapResponse* ( + *echo_nullable_map)(FlValue* map, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringMapResponse* ( + *echo_nullable_string_map)(FlValue* string_map, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntMapResponse* ( + *echo_nullable_int_map)(FlValue* int_map, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumMapResponse* ( + *echo_nullable_enum_map)(FlValue* enum_map, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassMapResponse* ( + *echo_nullable_class_map)(FlValue* class_map, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullStringMapResponse* ( + *echo_nullable_non_null_string_map)(FlValue* string_map, + gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullIntMapResponse* ( + *echo_nullable_non_null_int_map)(FlValue* int_map, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumMapResponse* ( + *echo_nullable_non_null_enum_map)(FlValue* enum_map, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassMapResponse* ( + *echo_nullable_non_null_class_map)(FlValue* class_map, + gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumResponse* ( + *echo_nullable_enum)(CoreTestsPigeonTestAnEnum* an_enum, + gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherNullableEnumResponse* ( + *echo_another_nullable_enum)(CoreTestsPigeonTestAnotherEnum* another_enum, + gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalNullableIntResponse* ( + *echo_optional_nullable_int)(int64_t* a_nullable_int, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedNullableStringResponse* ( + *echo_named_nullable_string)(const gchar* a_nullable_string, + gpointer user_data); + void (*noop_async)( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_int)( + int64_t an_int, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_double)( + double a_double, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_bool)( + gboolean a_bool, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_string)( + const gchar* a_string, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_uint8_list)( + const uint8_t* a_uint8_list, size_t a_uint8_list_length, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_object)( + FlValue* an_object, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_list)( + FlValue* list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_enum_list)( + FlValue* enum_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_class_list)( + FlValue* class_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_map)( + FlValue* map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_string_map)( + FlValue* string_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_int_map)( + FlValue* int_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_enum_map)( + FlValue* enum_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_class_map)( + FlValue* class_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_enum)( + CoreTestsPigeonTestAnEnum an_enum, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_another_async_enum)( + CoreTestsPigeonTestAnotherEnum another_enum, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*throw_async_error)( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*throw_async_error_from_void)( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*throw_async_flutter_error)( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_all_types)( + CoreTestsPigeonTestAllTypes* everything, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_nullable_all_nullable_types)( + CoreTestsPigeonTestAllNullableTypes* everything, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_nullable_all_nullable_types_without_recursion)( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* everything, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_nullable_int)( + int64_t* an_int, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_nullable_double)( + double* a_double, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_nullable_bool)( + gboolean* a_bool, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_nullable_string)( + const gchar* a_string, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_nullable_uint8_list)( + const uint8_t* a_uint8_list, size_t a_uint8_list_length, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_nullable_object)( + FlValue* an_object, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_nullable_list)( + FlValue* list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_nullable_enum_list)( + FlValue* enum_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_nullable_class_list)( + FlValue* class_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_nullable_map)( + FlValue* map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_nullable_string_map)( + FlValue* string_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_nullable_int_map)( + FlValue* int_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_nullable_enum_map)( + FlValue* enum_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_nullable_class_map)( + FlValue* class_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_async_nullable_enum)( + CoreTestsPigeonTestAnEnum* an_enum, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*echo_another_async_nullable_enum)( + CoreTestsPigeonTestAnotherEnum* another_enum, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_noop)( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_throw_error)( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_throw_error_from_void)( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_all_types)( + CoreTestsPigeonTestAllTypes* everything, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_all_nullable_types)( + CoreTestsPigeonTestAllNullableTypes* everything, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_send_multiple_nullable_types)( + gboolean* a_nullable_bool, int64_t* a_nullable_int, + const gchar* a_nullable_string, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_all_nullable_types_without_recursion)( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* everything, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_send_multiple_nullable_types_without_recursion)( + gboolean* a_nullable_bool, int64_t* a_nullable_int, + const gchar* a_nullable_string, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_bool)( + gboolean a_bool, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_int)( + int64_t an_int, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_double)( + double a_double, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_string)( + const gchar* a_string, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_uint8_list)( + const uint8_t* list, size_t list_length, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_list)( + FlValue* list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_enum_list)( + FlValue* enum_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_class_list)( + FlValue* class_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_non_null_enum_list)( + FlValue* enum_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_non_null_class_list)( + FlValue* class_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_map)( + FlValue* map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_string_map)( + FlValue* string_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_int_map)( + FlValue* int_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_enum_map)( + FlValue* enum_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_class_map)( + FlValue* class_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_non_null_string_map)( + FlValue* string_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_non_null_int_map)( + FlValue* int_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_non_null_enum_map)( + FlValue* enum_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_non_null_class_map)( + FlValue* class_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_enum)( + CoreTestsPigeonTestAnEnum an_enum, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_another_enum)( + CoreTestsPigeonTestAnotherEnum another_enum, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_nullable_bool)( + gboolean* a_bool, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_nullable_int)( + int64_t* an_int, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_nullable_double)( + double* a_double, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_nullable_string)( + const gchar* a_string, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_nullable_uint8_list)( + const uint8_t* list, size_t list_length, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_nullable_list)( + FlValue* list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_nullable_enum_list)( + FlValue* enum_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_nullable_class_list)( + FlValue* class_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_nullable_non_null_enum_list)( + FlValue* enum_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_nullable_non_null_class_list)( + FlValue* class_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_nullable_map)( + FlValue* map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_nullable_string_map)( + FlValue* string_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_nullable_int_map)( + FlValue* int_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_nullable_enum_map)( + FlValue* enum_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_nullable_class_map)( + FlValue* class_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_nullable_non_null_string_map)( + FlValue* string_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_nullable_non_null_int_map)( + FlValue* int_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_nullable_non_null_enum_map)( + FlValue* enum_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_nullable_non_null_class_map)( + FlValue* class_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_nullable_enum)( + CoreTestsPigeonTestAnEnum* an_enum, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_echo_another_nullable_enum)( + CoreTestsPigeonTestAnotherEnum* another_enum, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); + void (*call_flutter_small_api_echo_string)( + const gchar* a_string, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data); +} CoreTestsPigeonTestHostIntegrationCoreApiVTable; + +/** + * core_tests_pigeon_test_host_integration_core_api_set_method_handlers: + * + * @messenger: an #FlBinaryMessenger. + * @suffix: (allow-none): a suffix to add to the API or %NULL for none. + * @vtable: implementations of the methods in this API. + * @user_data: (closure): user data to pass to the functions in @vtable. + * @user_data_free_func: (allow-none): a function which gets called to free + * @user_data, or %NULL. + * + * Connects the method handlers in the HostIntegrationCoreApi API. + */ +void core_tests_pigeon_test_host_integration_core_api_set_method_handlers( + FlBinaryMessenger* messenger, const gchar* suffix, + const CoreTestsPigeonTestHostIntegrationCoreApiVTable* vtable, + gpointer user_data, GDestroyNotify user_data_free_func); + +/** + * core_tests_pigeon_test_host_integration_core_api_clear_method_handlers: + * + * @messenger: an #FlBinaryMessenger. + * @suffix: (allow-none): a suffix to add to the API or %NULL for none. + * + * Clears the method handlers in the HostIntegrationCoreApi API. + */ +void core_tests_pigeon_test_host_integration_core_api_clear_method_handlers( + FlBinaryMessenger* messenger, const gchar* suffix); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_noop_async: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * + * Responds to HostIntegrationCoreApi.noopAsync. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_noop_async( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_noop_async: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.noopAsync. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_noop_async( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_int: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncInt. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_int( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + int64_t return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_int: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncInt. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_int( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_double: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncDouble. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_double( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + double return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_double: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncDouble. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_double( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_bool: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncBool. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_bool( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gboolean return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_bool: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncBool. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_bool( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_string: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncString. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_string( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_string: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncString. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_string( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_uint8_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * @return_value_length: (allow-none): location to write length of @return_value + * or %NULL to ignore. + * + * Responds to HostIntegrationCoreApi.echoAsyncUint8List. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_uint8_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const uint8_t* return_value, size_t return_value_length); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_uint8_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncUint8List. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_uint8_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_object: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncObject. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_object( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_object: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncObject. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_object( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_enum_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncEnumList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_enum_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_enum_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncEnumList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_enum_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_class_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncClassList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_class_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_class_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncClassList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_class_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_string_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncStringMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_string_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_string_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncStringMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_string_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_int_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncIntMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_int_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_int_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncIntMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_int_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_enum_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncEnumMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_enum_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_enum_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncEnumMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_enum_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_class_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncClassMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_class_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_class_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncClassMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_class_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_enum: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncEnum. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAnEnum return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_enum: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncEnum. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_another_async_enum: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAnotherAsyncEnum. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_another_async_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAnotherEnum return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_another_async_enum: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAnotherAsyncEnum. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_another_async_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_throw_async_error: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.throwAsyncError. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_throw_async_error( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_throw_async_error: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.throwAsyncError. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_throw_async_error( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_throw_async_error_from_void: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * + * Responds to HostIntegrationCoreApi.throwAsyncErrorFromVoid. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_throw_async_error_from_void( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_throw_async_error_from_void: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.throwAsyncErrorFromVoid. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_throw_async_error_from_void( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_throw_async_flutter_error: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.throwAsyncFlutterError. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_throw_async_flutter_error( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_throw_async_flutter_error: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.throwAsyncFlutterError. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_throw_async_flutter_error( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_all_types: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncAllTypes. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_all_types( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAllTypes* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_all_types: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncAllTypes. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_all_types( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_all_nullable_types: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncNullableAllNullableTypes. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_all_nullable_types( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAllNullableTypes* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_all_nullable_types: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.echoAsyncNullableAllNullableTypes. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_all_nullable_types( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_all_nullable_types_without_recursion: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to + * HostIntegrationCoreApi.echoAsyncNullableAllNullableTypesWithoutRecursion. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_all_nullable_types_without_recursion( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_all_nullable_types_without_recursion: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.echoAsyncNullableAllNullableTypesWithoutRecursion. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_all_nullable_types_without_recursion( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_int: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncNullableInt. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_int( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + int64_t* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_int: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncNullableInt. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_int( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_double: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncNullableDouble. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_double( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + double* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_double: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncNullableDouble. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_double( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_bool: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncNullableBool. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_bool( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gboolean* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_bool: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncNullableBool. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_bool( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_string: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncNullableString. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_string( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_string: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncNullableString. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_string( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_uint8_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * @return_value_length: (allow-none): location to write length of @return_value + * or %NULL to ignore. + * + * Responds to HostIntegrationCoreApi.echoAsyncNullableUint8List. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_uint8_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const uint8_t* return_value, size_t return_value_length); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_uint8_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncNullableUint8List. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_uint8_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_object: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncNullableObject. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_object( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_object: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncNullableObject. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_object( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncNullableList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncNullableList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_enum_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncNullableEnumList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_enum_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_enum_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncNullableEnumList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_enum_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_class_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncNullableClassList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_class_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_class_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncNullableClassList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_class_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncNullableMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncNullableMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_string_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncNullableStringMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_string_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_string_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncNullableStringMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_string_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_int_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncNullableIntMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_int_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_int_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncNullableIntMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_int_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_enum_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncNullableEnumMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_enum_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_enum_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncNullableEnumMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_enum_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_class_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncNullableClassMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_class_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_class_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncNullableClassMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_class_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_enum: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAsyncNullableEnum. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAnEnum* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_enum: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.echoAsyncNullableEnum. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_async_nullable_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_echo_another_async_nullable_enum: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.echoAnotherAsyncNullableEnum. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_echo_another_async_nullable_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAnotherEnum* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_echo_another_async_nullable_enum: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.echoAnotherAsyncNullableEnum. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_echo_another_async_nullable_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_noop: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * + * Responds to HostIntegrationCoreApi.callFlutterNoop. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_noop( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_noop: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.callFlutterNoop. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_noop( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_throw_error: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterThrowError. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_throw_error( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_throw_error: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.callFlutterThrowError. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_throw_error( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_throw_error_from_void: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * + * Responds to HostIntegrationCoreApi.callFlutterThrowErrorFromVoid. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_throw_error_from_void( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_throw_error_from_void: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterThrowErrorFromVoid. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_throw_error_from_void( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_all_types: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoAllTypes. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_all_types( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAllTypes* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_all_types: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.callFlutterEchoAllTypes. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_all_types( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_all_nullable_types: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoAllNullableTypes. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_all_nullable_types( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAllNullableTypes* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_all_nullable_types: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterEchoAllNullableTypes. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_all_nullable_types( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_send_multiple_nullable_types: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterSendMultipleNullableTypes. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_send_multiple_nullable_types( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAllNullableTypes* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_send_multiple_nullable_types: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterSendMultipleNullableTypes. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_send_multiple_nullable_types( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_all_nullable_types_without_recursion: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to + * HostIntegrationCoreApi.callFlutterEchoAllNullableTypesWithoutRecursion. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_all_nullable_types_without_recursion( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_all_nullable_types_without_recursion: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterEchoAllNullableTypesWithoutRecursion. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_all_nullable_types_without_recursion( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_send_multiple_nullable_types_without_recursion: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to + * HostIntegrationCoreApi.callFlutterSendMultipleNullableTypesWithoutRecursion. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_send_multiple_nullable_types_without_recursion( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_send_multiple_nullable_types_without_recursion: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterSendMultipleNullableTypesWithoutRecursion. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_send_multiple_nullable_types_without_recursion( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_bool: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoBool. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_bool( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gboolean return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.callFlutterEchoBool. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_int: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoInt. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_int( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + int64_t return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_int: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.callFlutterEchoInt. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_int( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_double: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoDouble. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_double( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + double return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_double: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.callFlutterEchoDouble. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_double( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_string: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoString. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_string( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_string: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.callFlutterEchoString. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_string( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_uint8_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * @return_value_length: (allow-none): location to write length of @return_value + * or %NULL to ignore. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoUint8List. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_uint8_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const uint8_t* return_value, size_t return_value_length); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_uint8_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.callFlutterEchoUint8List. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_uint8_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.callFlutterEchoList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_enum_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoEnumList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_enum_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_enum_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.callFlutterEchoEnumList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_enum_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_class_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoClassList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_class_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_class_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.callFlutterEchoClassList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_class_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_non_null_enum_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNonNullEnumList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_non_null_enum_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_non_null_enum_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterEchoNonNullEnumList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_non_null_enum_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_non_null_class_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNonNullClassList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_non_null_class_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_non_null_class_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterEchoNonNullClassList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_non_null_class_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.callFlutterEchoMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_string_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoStringMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_string_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_string_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.callFlutterEchoStringMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_string_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_int_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoIntMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_int_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_int_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.callFlutterEchoIntMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_int_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_enum_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoEnumMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_enum_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_enum_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.callFlutterEchoEnumMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_enum_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_class_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoClassMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_class_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_class_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.callFlutterEchoClassMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_class_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_non_null_string_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNonNullStringMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_non_null_string_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_non_null_string_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterEchoNonNullStringMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_non_null_string_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_non_null_int_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNonNullIntMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_non_null_int_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_non_null_int_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterEchoNonNullIntMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_non_null_int_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_non_null_enum_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNonNullEnumMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_non_null_enum_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_non_null_enum_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterEchoNonNullEnumMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_non_null_enum_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_non_null_class_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNonNullClassMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_non_null_class_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_non_null_class_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterEchoNonNullClassMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_non_null_class_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_enum: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoEnum. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAnEnum return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_enum: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.callFlutterEchoEnum. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_another_enum: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoAnotherEnum. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_another_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAnotherEnum return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_another_enum: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.callFlutterEchoAnotherEnum. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_another_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_bool: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNullableBool. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_bool( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gboolean* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_bool: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.callFlutterEchoNullableBool. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_bool( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_int: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNullableInt. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_int( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + int64_t* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_int: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.callFlutterEchoNullableInt. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_int( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_double: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNullableDouble. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_double( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + double* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_double: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterEchoNullableDouble. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_double( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_string: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNullableString. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_string( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_string: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterEchoNullableString. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_string( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_uint8_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * @return_value_length: (allow-none): location to write length of @return_value + * or %NULL to ignore. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNullableUint8List. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_uint8_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const uint8_t* return_value, size_t return_value_length); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_uint8_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterEchoNullableUint8List. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_uint8_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNullableList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.callFlutterEchoNullableList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_enum_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNullableEnumList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_enum_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_enum_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterEchoNullableEnumList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_enum_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_class_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNullableClassList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_class_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_class_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterEchoNullableClassList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_class_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_non_null_enum_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNullableNonNullEnumList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_non_null_enum_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_non_null_enum_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterEchoNullableNonNullEnumList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_non_null_enum_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_non_null_class_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNullableNonNullClassList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_non_null_class_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_non_null_class_list: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterEchoNullableNonNullClassList. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_non_null_class_list( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNullableMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.callFlutterEchoNullableMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_string_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNullableStringMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_string_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_string_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterEchoNullableStringMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_string_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_int_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNullableIntMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_int_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_int_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterEchoNullableIntMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_int_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_enum_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNullableEnumMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_enum_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_enum_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterEchoNullableEnumMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_enum_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_class_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNullableClassMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_class_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_class_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterEchoNullableClassMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_class_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_non_null_string_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNullableNonNullStringMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_non_null_string_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_non_null_string_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterEchoNullableNonNullStringMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_non_null_string_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_non_null_int_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNullableNonNullIntMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_non_null_int_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_non_null_int_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterEchoNullableNonNullIntMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_non_null_int_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_non_null_enum_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNullableNonNullEnumMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_non_null_enum_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_non_null_enum_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterEchoNullableNonNullEnumMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_non_null_enum_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_non_null_class_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNullableNonNullClassMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_non_null_class_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_non_null_class_map: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterEchoNullableNonNullClassMap. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_non_null_class_map( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_enum: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoNullableEnum. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAnEnum* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_enum: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostIntegrationCoreApi.callFlutterEchoNullableEnum. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_another_nullable_enum: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterEchoAnotherNullableEnum. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_another_nullable_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + CoreTestsPigeonTestAnotherEnum* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_another_nullable_enum: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterEchoAnotherNullableEnum. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_another_nullable_enum( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_small_api_echo_string: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostIntegrationCoreApi.callFlutterSmallApiEchoString. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_small_api_echo_string( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_small_api_echo_string: + * @response_handle: a #CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to + * HostIntegrationCoreApi.callFlutterSmallApiEchoString. + */ +void core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_small_api_echo_string( + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopResponse, + core_tests_pigeon_test_flutter_integration_core_api_noop_response, + CORE_TESTS_PIGEON_TEST, FLUTTER_INTEGRATION_CORE_API_NOOP_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_noop_response_is_error: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiNoopResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.noop is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_noop_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_noop_response_get_error_code: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiNoopResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_noop_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_noop_response_get_error_message: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiNoopResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_noop_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_noop_response_get_error_details: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiNoopResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_noop_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopResponse* response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse, + core_tests_pigeon_test_flutter_integration_core_api_throw_error_response, + CORE_TESTS_PIGEON_TEST, FLUTTER_INTEGRATION_CORE_API_THROW_ERROR_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_is_error: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.throwError is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_get_error_code: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_get_error_message: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_get_error_details: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_get_return_value: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse. + * + * Get the return value for this response. + * + * Returns: (allow-none): a return value or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse* response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorFromVoidResponse, + core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_THROW_ERROR_FROM_VOID_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorFromVoidResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.throwErrorFromVoid is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorFromVoidResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorFromVoidResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorFromVoidResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorFromVoidResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorFromVoidResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorFromVoidResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorFromVoidResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_ALL_TYPES_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoAllTypes is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +CoreTestsPigeonTestAllTypes* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse* response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_ALL_NULLABLE_TYPES_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoAllNullableTypes is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse. + * + * Get the return value for this response. + * + * Returns: (allow-none): a return value or %NULL. + */ +CoreTestsPigeonTestAllNullableTypes* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse, + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_SEND_MULTIPLE_NULLABLE_TYPES_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.sendMultipleNullableTypes + * is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +CoreTestsPigeonTestAllNullableTypes* +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_ALL_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse. + * + * Checks if a response to + * FlutterIntegrationCoreApi.echoAllNullableTypesWithoutRecursion is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse. + * + * Get the return value for this response. + * + * Returns: (allow-none): a return value or %NULL. + */ +CoreTestsPigeonTestAllNullableTypesWithoutRecursion* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse, + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_SEND_MULTIPLE_NULLABLE_TYPES_WITHOUT_RECURSION_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse. + * + * Checks if a response to + * FlutterIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +CoreTestsPigeonTestAllNullableTypesWithoutRecursion* +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response, + CORE_TESTS_PIGEON_TEST, FLUTTER_INTEGRATION_CORE_API_ECHO_BOOL_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_is_error: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoBool is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_get_error_code: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_get_error_message: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_get_error_details: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_get_return_value: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse* response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_int_response, + CORE_TESTS_PIGEON_TEST, FLUTTER_INTEGRATION_CORE_API_ECHO_INT_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_is_error: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoInt is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_get_error_code: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_get_error_message: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_get_error_details: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_get_return_value: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +int64_t +core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse* response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_double_response, + CORE_TESTS_PIGEON_TEST, FLUTTER_INTEGRATION_CORE_API_ECHO_DOUBLE_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_is_error: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoDouble is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_get_error_code: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_get_error_message: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_get_error_details: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_get_return_value: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +double +core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse* response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_string_response, + CORE_TESTS_PIGEON_TEST, FLUTTER_INTEGRATION_CORE_API_ECHO_STRING_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_is_error: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoString is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_get_error_code: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_get_error_message: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_get_error_details: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_get_return_value: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse* response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_UINT8_LIST_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoUint8List is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse. + * @return_value_length: (allow-none): location to write length of the return + * value or %NULL to ignore. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +const uint8_t* +core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse* response, + size_t* return_value_length); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_list_response, + CORE_TESTS_PIGEON_TEST, FLUTTER_INTEGRATION_CORE_API_ECHO_LIST_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_is_error: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoList is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_get_error_code: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_get_error_message: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_get_error_details: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_get_return_value: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse* response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_ENUM_LIST_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoEnumList is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse* response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_CLASS_LIST_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoClassList is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_ENUM_LIST_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoNonNullEnumList is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_CLASS_LIST_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoNonNullClassList is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_map_response, + CORE_TESTS_PIGEON_TEST, FLUTTER_INTEGRATION_CORE_API_ECHO_MAP_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_is_error: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoMap is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_get_error_code: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_get_error_message: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_get_error_details: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_get_return_value: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse* response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_STRING_MAP_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoStringMap is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response, + CORE_TESTS_PIGEON_TEST, FLUTTER_INTEGRATION_CORE_API_ECHO_INT_MAP_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_is_error: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoIntMap is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_get_error_code: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_get_error_message: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_get_error_details: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_get_return_value: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse* response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response, + CORE_TESTS_PIGEON_TEST, FLUTTER_INTEGRATION_CORE_API_ECHO_ENUM_MAP_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoEnumMap is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse* response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_CLASS_MAP_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoClassMap is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse* response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_STRING_MAP_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoNonNullStringMap is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_INT_MAP_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoNonNullIntMap is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_ENUM_MAP_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoNonNullEnumMap is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NON_NULL_CLASS_MAP_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoNonNullClassMap is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response, + CORE_TESTS_PIGEON_TEST, FLUTTER_INTEGRATION_CORE_API_ECHO_ENUM_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_is_error: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoEnum is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_get_error_code: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_get_error_message: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_get_error_details: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_get_return_value: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +CoreTestsPigeonTestAnEnum +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse* response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_ANOTHER_ENUM_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoAnotherEnum is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +CoreTestsPigeonTestAnotherEnum +core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_BOOL_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoNullableBool is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse. + * + * Get the return value for this response. + * + * Returns: (allow-none): a return value or %NULL. + */ +gboolean* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_INT_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoNullableInt is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse. + * + * Get the return value for this response. + * + * Returns: (allow-none): a return value or %NULL. + */ +int64_t* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_DOUBLE_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoNullableDouble is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse. + * + * Get the return value for this response. + * + * Returns: (allow-none): a return value or %NULL. + */ +double* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_STRING_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoNullableString is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse. + * + * Get the return value for this response. + * + * Returns: (allow-none): a return value or %NULL. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_UINT8_LIST_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoNullableUint8List is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse. + * @return_value_length: (allow-none): location to write length of the return + * value or %NULL to ignore. + * + * Get the return value for this response. + * + * Returns: (allow-none): a return value or %NULL. + */ +const uint8_t* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse* + response, + size_t* return_value_length); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_LIST_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoNullableList is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse. + * + * Get the return value for this response. + * + * Returns: (allow-none): a return value or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_LIST_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoNullableEnumList is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse. + * + * Get the return value for this response. + * + * Returns: (allow-none): a return value or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_CLASS_LIST_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoNullableClassList is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse. + * + * Get the return value for this response. + * + * Returns: (allow-none): a return value or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_ENUM_LIST_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoNullableNonNullEnumList + * is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse. + * + * Get the return value for this response. + * + * Returns: (allow-none): a return value or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_CLASS_LIST_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse. + * + * Checks if a response to + * FlutterIntegrationCoreApi.echoNullableNonNullClassList is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse. + * + * Get the return value for this response. + * + * Returns: (allow-none): a return value or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_MAP_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoNullableMap is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse. + * + * Get the return value for this response. + * + * Returns: (allow-none): a return value or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_STRING_MAP_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoNullableStringMap is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse. + * + * Get the return value for this response. + * + * Returns: (allow-none): a return value or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_INT_MAP_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoNullableIntMap is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse. + * + * Get the return value for this response. + * + * Returns: (allow-none): a return value or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_MAP_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoNullableEnumMap is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse. + * + * Get the return value for this response. + * + * Returns: (allow-none): a return value or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_CLASS_MAP_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoNullableClassMap is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse. + * + * Get the return value for this response. + * + * Returns: (allow-none): a return value or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_STRING_MAP_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse. + * + * Checks if a response to + * FlutterIntegrationCoreApi.echoNullableNonNullStringMap is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse. + * + * Get the return value for this response. + * + * Returns: (allow-none): a return value or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_INT_MAP_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoNullableNonNullIntMap + * is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse. + * + * Get the return value for this response. + * + * Returns: (allow-none): a return value or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_ENUM_MAP_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoNullableNonNullEnumMap + * is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse. + * + * Get the return value for this response. + * + * Returns: (allow-none): a return value or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_NON_NULL_CLASS_MAP_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoNullableNonNullClassMap + * is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse. + * + * Get the return value for this response. + * + * Returns: (allow-none): a return value or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_NULLABLE_ENUM_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoNullableEnum is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse. + * + * Get the return value for this response. + * + * Returns: (allow-none): a return value or %NULL. + */ +CoreTestsPigeonTestAnEnum* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_ANOTHER_NULLABLE_ENUM_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoAnotherNullableEnum is + * an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse. + * + * Get the return value for this response. + * + * Returns: (allow-none): a return value or %NULL. + */ +CoreTestsPigeonTestAnotherEnum* +core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse* + response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopAsyncResponse, + core_tests_pigeon_test_flutter_integration_core_api_noop_async_response, + CORE_TESTS_PIGEON_TEST, FLUTTER_INTEGRATION_CORE_API_NOOP_ASYNC_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_noop_async_response_is_error: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiNoopAsyncResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.noopAsync is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_noop_async_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopAsyncResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_noop_async_response_get_error_code: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiNoopAsyncResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_noop_async_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopAsyncResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_noop_async_response_get_error_message: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiNoopAsyncResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_noop_async_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopAsyncResponse* response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_noop_async_response_get_error_details: + * @response: a #CoreTestsPigeonTestFlutterIntegrationCoreApiNoopAsyncResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_noop_async_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiNoopAsyncResponse* response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse, + core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response, + CORE_TESTS_PIGEON_TEST, + FLUTTER_INTEGRATION_CORE_API_ECHO_ASYNC_STRING_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_is_error: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse. + * + * Checks if a response to FlutterIntegrationCoreApi.echoAsyncString is an + * error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_is_error( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_get_error_code: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_get_error_code( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_get_error_message: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_get_error_message( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_get_error_details: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_get_error_details( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse* + response); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_get_return_value: + * @response: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +const gchar* +core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_response_get_return_value( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse* + response); + +/** + * CoreTestsPigeonTestFlutterIntegrationCoreApi: + * + * The core interface that the Dart platform_test code implements for host + * integration tests to call into. + */ + +G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestFlutterIntegrationCoreApi, + core_tests_pigeon_test_flutter_integration_core_api, + CORE_TESTS_PIGEON_TEST, FLUTTER_INTEGRATION_CORE_API, + GObject) + +/** + * core_tests_pigeon_test_flutter_integration_core_api_new: + * @messenger: an #FlBinaryMessenger. + * @suffix: (allow-none): a suffix to add to the API or %NULL for none. + * + * Creates a new object to access the FlutterIntegrationCoreApi API. + * + * Returns: a new #CoreTestsPigeonTestFlutterIntegrationCoreApi + */ +CoreTestsPigeonTestFlutterIntegrationCoreApi* +core_tests_pigeon_test_flutter_integration_core_api_new( + FlBinaryMessenger* messenger, const gchar* suffix); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_noop: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * A no-op function taking no arguments and returning no value, to sanity + * test basic calling. + */ +void core_tests_pigeon_test_flutter_integration_core_api_noop( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_noop_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a core_tests_pigeon_test_flutter_integration_core_api_noop() call. + * + * Returns: a #CoreTestsPigeonTestFlutterIntegrationCoreApiNoopResponse or %NULL + * on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiNoopResponse* +core_tests_pigeon_test_flutter_integration_core_api_noop_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_throw_error: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Responds with an error from an async function returning a value. + */ +void core_tests_pigeon_test_flutter_integration_core_api_throw_error( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_throw_error_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a core_tests_pigeon_test_flutter_integration_core_api_throw_error() + * call. + * + * Returns: a #CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse* +core_tests_pigeon_test_flutter_integration_core_api_throw_error_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Responds with an error from an async void function. + */ +void core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorFromVoidResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorFromVoidResponse* +core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_all_types: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @everything: parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed object, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_all_types( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, + CoreTestsPigeonTestAllTypes* everything, GCancellable* cancellable, + GAsyncReadyCallback callback, gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_all_types() call. + * + * Returns: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse + * or %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @everything: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed object, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, + CoreTestsPigeonTestAllNullableTypes* everything, GCancellable* cancellable, + GAsyncReadyCallback callback, gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @a_nullable_bool: (allow-none): parameter for this method. + * @a_nullable_int: (allow-none): parameter for this method. + * @a_nullable_string: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns passed in arguments of multiple types. + * + * Tests multiple-arity FlutterApi handling. + */ +void core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, + gboolean* a_nullable_bool, int64_t* a_nullable_int, + const gchar* a_nullable_string, GCancellable* cancellable, + GAsyncReadyCallback callback, gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse + * or %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse* +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @everything: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed object, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* everything, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse + * or %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @a_nullable_bool: (allow-none): parameter for this method. + * @a_nullable_int: (allow-none): parameter for this method. + * @a_nullable_string: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns passed in arguments of multiple types. + * + * Tests multiple-arity FlutterApi handling. + */ +void core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, + gboolean* a_nullable_bool, int64_t* a_nullable_int, + const gchar* a_nullable_string, GCancellable* cancellable, + GAsyncReadyCallback callback, gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse + * or %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* +core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_bool: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @a_bool: parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed boolean, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_bool( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, gboolean a_bool, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_bool_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a core_tests_pigeon_test_flutter_integration_core_api_echo_bool() + * call. + * + * Returns: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_bool_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_int: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @an_int: parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed int, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_int( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, int64_t an_int, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_int_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a core_tests_pigeon_test_flutter_integration_core_api_echo_int() + * call. + * + * Returns: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_int_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_double: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @a_double: parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed double, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_double( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, double a_double, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_double_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a core_tests_pigeon_test_flutter_integration_core_api_echo_double() + * call. + * + * Returns: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_double_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_string: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @a_string: parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed string, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_string( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, const gchar* a_string, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_string_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a core_tests_pigeon_test_flutter_integration_core_api_echo_string() + * call. + * + * Returns: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_string_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @list: parameter for this method. + * @list_length: length of list. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed byte list, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, const uint8_t* list, + size_t list_length, GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list() call. + * + * Returns: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse + * or %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_list: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @list: parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed list, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_list( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* list, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_list_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a core_tests_pigeon_test_flutter_integration_core_api_echo_list() + * call. + * + * Returns: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_list_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @enum_list: parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed list, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* enum_list, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list() call. + * + * Returns: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse + * or %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_class_list: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @class_list: parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed list, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_class_list( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* class_list, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_class_list() call. + * + * Returns: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse + * or %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @enum_list: parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed list, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* enum_list, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @class_list: parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed list, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* class_list, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_map: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @map: parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed map, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_map_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a core_tests_pigeon_test_flutter_integration_core_api_echo_map() + * call. + * + * Returns: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_string_map: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @string_map: parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed map, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_string_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* string_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_string_map() call. + * + * Returns: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse + * or %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_int_map: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @int_map: parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed map, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_int_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* int_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_int_map() call. + * + * Returns: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @enum_map: parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed map, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* enum_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map() call. + * + * Returns: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse + * or %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_class_map: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @class_map: parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed map, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_class_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* class_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_class_map() call. + * + * Returns: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse + * or %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @string_map: parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed map, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* string_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @int_map: parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed map, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* int_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @enum_map: parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed map, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* enum_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @class_map: parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed map, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* class_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_enum: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @an_enum: parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed enum to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_enum( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, + CoreTestsPigeonTestAnEnum an_enum, GCancellable* cancellable, + GAsyncReadyCallback callback, gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_enum_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a core_tests_pigeon_test_flutter_integration_core_api_echo_enum() + * call. + * + * Returns: a #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_enum_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @another_enum: parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed enum to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, + CoreTestsPigeonTestAnotherEnum another_enum, GCancellable* cancellable, + GAsyncReadyCallback callback, gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum() call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse or %NULL + * on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @a_bool: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed boolean, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, gboolean* a_bool, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @an_int: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed int, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, int64_t* an_int, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int() call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse or %NULL + * on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @a_double: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed double, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, double* a_double, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @a_string: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed string, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, const gchar* a_string, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @list: (allow-none): parameter for this method. + * @list_length: length of list. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed byte list, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, const uint8_t* list, + size_t list_length, GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @list: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed list, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* list, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @enum_list: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed list, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* enum_list, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @class_list: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed list, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* class_list, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @enum_list: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed list, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* enum_list, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse + * or %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @class_list: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed list, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* class_list, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse + * or %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @map: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed map, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map() call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse or %NULL + * on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @string_map: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed map, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* string_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @int_map: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed map, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* int_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @enum_map: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed map, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* enum_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @class_map: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed map, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* class_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @string_map: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed map, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* string_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse + * or %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @int_map: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed map, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* int_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse + * or %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @enum_map: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed map, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* enum_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse + * or %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @class_map: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed map, to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, FlValue* class_map, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse + * or %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @an_enum: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed enum to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, + CoreTestsPigeonTestAnEnum* an_enum, GCancellable* cancellable, + GAsyncReadyCallback callback, gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @another_enum: (allow-none): parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed enum to test serialization and deserialization. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, + CoreTestsPigeonTestAnotherEnum* another_enum, GCancellable* cancellable, + GAsyncReadyCallback callback, gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum() + * call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse + * or %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_noop_async: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * A no-op function taking no arguments and returning no value, to sanity + * test basic asynchronous calling. + */ +void core_tests_pigeon_test_flutter_integration_core_api_noop_async( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_noop_async_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a core_tests_pigeon_test_flutter_integration_core_api_noop_async() + * call. + * + * Returns: a #CoreTestsPigeonTestFlutterIntegrationCoreApiNoopAsyncResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiNoopAsyncResponse* +core_tests_pigeon_test_flutter_integration_core_api_noop_async_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_async_string: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @a_string: parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + * Returns the passed in generic Object asynchronously. + */ +void core_tests_pigeon_test_flutter_integration_core_api_echo_async_string( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, const gchar* a_string, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_finish: + * @api: a #CoreTestsPigeonTestFlutterIntegrationCoreApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a + * core_tests_pigeon_test_flutter_integration_core_api_echo_async_string() call. + * + * Returns: a + * #CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse or %NULL + * on error. + */ +CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAsyncStringResponse* +core_tests_pigeon_test_flutter_integration_core_api_echo_async_string_finish( + CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result, + GError** error); + +G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestHostTrivialApiNoopResponse, + core_tests_pigeon_test_host_trivial_api_noop_response, + CORE_TESTS_PIGEON_TEST, HOST_TRIVIAL_API_NOOP_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_trivial_api_noop_response_new: + * + * Creates a new response to HostTrivialApi.noop. + * + * Returns: a new #CoreTestsPigeonTestHostTrivialApiNoopResponse + */ +CoreTestsPigeonTestHostTrivialApiNoopResponse* +core_tests_pigeon_test_host_trivial_api_noop_response_new(); + +/** + * core_tests_pigeon_test_host_trivial_api_noop_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostTrivialApi.noop. + * + * Returns: a new #CoreTestsPigeonTestHostTrivialApiNoopResponse + */ +CoreTestsPigeonTestHostTrivialApiNoopResponse* +core_tests_pigeon_test_host_trivial_api_noop_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +/** + * CoreTestsPigeonTestHostTrivialApiVTable: + * + * Table of functions exposed by HostTrivialApi to be implemented by the API + * provider. + */ +typedef struct { + CoreTestsPigeonTestHostTrivialApiNoopResponse* (*noop)(gpointer user_data); +} CoreTestsPigeonTestHostTrivialApiVTable; + +/** + * core_tests_pigeon_test_host_trivial_api_set_method_handlers: + * + * @messenger: an #FlBinaryMessenger. + * @suffix: (allow-none): a suffix to add to the API or %NULL for none. + * @vtable: implementations of the methods in this API. + * @user_data: (closure): user data to pass to the functions in @vtable. + * @user_data_free_func: (allow-none): a function which gets called to free + * @user_data, or %NULL. + * + * Connects the method handlers in the HostTrivialApi API. + */ +void core_tests_pigeon_test_host_trivial_api_set_method_handlers( + FlBinaryMessenger* messenger, const gchar* suffix, + const CoreTestsPigeonTestHostTrivialApiVTable* vtable, gpointer user_data, + GDestroyNotify user_data_free_func); + +/** + * core_tests_pigeon_test_host_trivial_api_clear_method_handlers: + * + * @messenger: an #FlBinaryMessenger. + * @suffix: (allow-none): a suffix to add to the API or %NULL for none. + * + * Clears the method handlers in the HostTrivialApi API. + */ +void core_tests_pigeon_test_host_trivial_api_clear_method_handlers( + FlBinaryMessenger* messenger, const gchar* suffix); + +G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestHostSmallApiResponseHandle, + core_tests_pigeon_test_host_small_api_response_handle, + CORE_TESTS_PIGEON_TEST, HOST_SMALL_API_RESPONSE_HANDLE, + GObject) + +/** + * CoreTestsPigeonTestHostSmallApiVTable: + * + * Table of functions exposed by HostSmallApi to be implemented by the API + * provider. + */ +typedef struct { + void (*echo)(const gchar* a_string, + CoreTestsPigeonTestHostSmallApiResponseHandle* response_handle, + gpointer user_data); + void (*void_void)( + CoreTestsPigeonTestHostSmallApiResponseHandle* response_handle, + gpointer user_data); +} CoreTestsPigeonTestHostSmallApiVTable; + +/** + * core_tests_pigeon_test_host_small_api_set_method_handlers: + * + * @messenger: an #FlBinaryMessenger. + * @suffix: (allow-none): a suffix to add to the API or %NULL for none. + * @vtable: implementations of the methods in this API. + * @user_data: (closure): user data to pass to the functions in @vtable. + * @user_data_free_func: (allow-none): a function which gets called to free + * @user_data, or %NULL. + * + * Connects the method handlers in the HostSmallApi API. + */ +void core_tests_pigeon_test_host_small_api_set_method_handlers( + FlBinaryMessenger* messenger, const gchar* suffix, + const CoreTestsPigeonTestHostSmallApiVTable* vtable, gpointer user_data, + GDestroyNotify user_data_free_func); + +/** + * core_tests_pigeon_test_host_small_api_clear_method_handlers: + * + * @messenger: an #FlBinaryMessenger. + * @suffix: (allow-none): a suffix to add to the API or %NULL for none. + * + * Clears the method handlers in the HostSmallApi API. + */ +void core_tests_pigeon_test_host_small_api_clear_method_handlers( + FlBinaryMessenger* messenger, const gchar* suffix); + +/** + * core_tests_pigeon_test_host_small_api_respond_echo: + * @response_handle: a #CoreTestsPigeonTestHostSmallApiResponseHandle. + * @return_value: location to write the value returned by this method. + * + * Responds to HostSmallApi.echo. + */ +void core_tests_pigeon_test_host_small_api_respond_echo( + CoreTestsPigeonTestHostSmallApiResponseHandle* response_handle, + const gchar* return_value); + +/** + * core_tests_pigeon_test_host_small_api_respond_error_echo: + * @response_handle: a #CoreTestsPigeonTestHostSmallApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostSmallApi.echo. + */ +void core_tests_pigeon_test_host_small_api_respond_error_echo( + CoreTestsPigeonTestHostSmallApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +/** + * core_tests_pigeon_test_host_small_api_respond_void_void: + * @response_handle: a #CoreTestsPigeonTestHostSmallApiResponseHandle. + * + * Responds to HostSmallApi.voidVoid. + */ +void core_tests_pigeon_test_host_small_api_respond_void_void( + CoreTestsPigeonTestHostSmallApiResponseHandle* response_handle); + +/** + * core_tests_pigeon_test_host_small_api_respond_error_void_void: + * @response_handle: a #CoreTestsPigeonTestHostSmallApiResponseHandle. + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Responds with an error to HostSmallApi.voidVoid. + */ +void core_tests_pigeon_test_host_small_api_respond_error_void_void( + CoreTestsPigeonTestHostSmallApiResponseHandle* response_handle, + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse, + core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response, + CORE_TESTS_PIGEON_TEST, FLUTTER_SMALL_API_ECHO_WRAPPED_LIST_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_is_error: + * @response: a #CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse. + * + * Checks if a response to FlutterSmallApi.echoWrappedList is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean +core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_is_error( + CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse* response); + +/** + * core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_get_error_code: + * @response: a #CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_get_error_code( + CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse* response); + +/** + * core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_get_error_message: + * @response: a #CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_get_error_message( + CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse* response); + +/** + * core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_get_error_details: + * @response: a #CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_get_error_details( + CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse* response); + +/** + * core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_get_return_value: + * @response: a #CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +CoreTestsPigeonTestTestMessage* +core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_response_get_return_value( + CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse* response); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestFlutterSmallApiEchoStringResponse, + core_tests_pigeon_test_flutter_small_api_echo_string_response, + CORE_TESTS_PIGEON_TEST, FLUTTER_SMALL_API_ECHO_STRING_RESPONSE, GObject) + +/** + * core_tests_pigeon_test_flutter_small_api_echo_string_response_is_error: + * @response: a #CoreTestsPigeonTestFlutterSmallApiEchoStringResponse. + * + * Checks if a response to FlutterSmallApi.echoString is an error. + * + * Returns: a %TRUE if this response is an error. + */ +gboolean core_tests_pigeon_test_flutter_small_api_echo_string_response_is_error( + CoreTestsPigeonTestFlutterSmallApiEchoStringResponse* response); + +/** + * core_tests_pigeon_test_flutter_small_api_echo_string_response_get_error_code: + * @response: a #CoreTestsPigeonTestFlutterSmallApiEchoStringResponse. + * + * Get the error code for this response. + * + * Returns: an error code or %NULL if not an error. + */ +const gchar* +core_tests_pigeon_test_flutter_small_api_echo_string_response_get_error_code( + CoreTestsPigeonTestFlutterSmallApiEchoStringResponse* response); + +/** + * core_tests_pigeon_test_flutter_small_api_echo_string_response_get_error_message: + * @response: a #CoreTestsPigeonTestFlutterSmallApiEchoStringResponse. + * + * Get the error message for this response. + * + * Returns: an error message. + */ +const gchar* +core_tests_pigeon_test_flutter_small_api_echo_string_response_get_error_message( + CoreTestsPigeonTestFlutterSmallApiEchoStringResponse* response); + +/** + * core_tests_pigeon_test_flutter_small_api_echo_string_response_get_error_details: + * @response: a #CoreTestsPigeonTestFlutterSmallApiEchoStringResponse. + * + * Get the error details for this response. + * + * Returns: (allow-none): an error details or %NULL. + */ +FlValue* +core_tests_pigeon_test_flutter_small_api_echo_string_response_get_error_details( + CoreTestsPigeonTestFlutterSmallApiEchoStringResponse* response); + +/** + * core_tests_pigeon_test_flutter_small_api_echo_string_response_get_return_value: + * @response: a #CoreTestsPigeonTestFlutterSmallApiEchoStringResponse. + * + * Get the return value for this response. + * + * Returns: a return value. + */ +const gchar* +core_tests_pigeon_test_flutter_small_api_echo_string_response_get_return_value( + CoreTestsPigeonTestFlutterSmallApiEchoStringResponse* response); + +/** + * CoreTestsPigeonTestFlutterSmallApi: + * + * A simple API called in some unit tests. + */ + +G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestFlutterSmallApi, + core_tests_pigeon_test_flutter_small_api, + CORE_TESTS_PIGEON_TEST, FLUTTER_SMALL_API, GObject) + +/** + * core_tests_pigeon_test_flutter_small_api_new: + * @messenger: an #FlBinaryMessenger. + * @suffix: (allow-none): a suffix to add to the API or %NULL for none. + * + * Creates a new object to access the FlutterSmallApi API. + * + * Returns: a new #CoreTestsPigeonTestFlutterSmallApi + */ +CoreTestsPigeonTestFlutterSmallApi* +core_tests_pigeon_test_flutter_small_api_new(FlBinaryMessenger* messenger, + const gchar* suffix); + +/** + * core_tests_pigeon_test_flutter_small_api_echo_wrapped_list: + * @api: a #CoreTestsPigeonTestFlutterSmallApi. + * @msg: parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + */ +void core_tests_pigeon_test_flutter_small_api_echo_wrapped_list( + CoreTestsPigeonTestFlutterSmallApi* api, + CoreTestsPigeonTestTestMessage* msg, GCancellable* cancellable, + GAsyncReadyCallback callback, gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_finish: + * @api: a #CoreTestsPigeonTestFlutterSmallApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a core_tests_pigeon_test_flutter_small_api_echo_wrapped_list() + * call. + * + * Returns: a #CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse or + * %NULL on error. + */ +CoreTestsPigeonTestFlutterSmallApiEchoWrappedListResponse* +core_tests_pigeon_test_flutter_small_api_echo_wrapped_list_finish( + CoreTestsPigeonTestFlutterSmallApi* api, GAsyncResult* result, + GError** error); + +/** + * core_tests_pigeon_test_flutter_small_api_echo_string: + * @api: a #CoreTestsPigeonTestFlutterSmallApi. + * @a_string: parameter for this method. + * @cancellable: (allow-none): a #GCancellable or %NULL. + * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when + * the call is complete or %NULL to ignore the response. + * @user_data: (closure): user data to pass to @callback. + * + */ +void core_tests_pigeon_test_flutter_small_api_echo_string( + CoreTestsPigeonTestFlutterSmallApi* api, const gchar* a_string, + GCancellable* cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +/** + * core_tests_pigeon_test_flutter_small_api_echo_string_finish: + * @api: a #CoreTestsPigeonTestFlutterSmallApi. + * @result: a #GAsyncResult. + * @error: (allow-none): #GError location to store the error occurring, or %NULL + * to ignore. + * + * Completes a core_tests_pigeon_test_flutter_small_api_echo_string() call. + * + * Returns: a #CoreTestsPigeonTestFlutterSmallApiEchoStringResponse or %NULL on + * error. + */ +CoreTestsPigeonTestFlutterSmallApiEchoStringResponse* +core_tests_pigeon_test_flutter_small_api_echo_string_finish( + CoreTestsPigeonTestFlutterSmallApi* api, GAsyncResult* result, + GError** error); + +G_END_DECLS + +#endif // PIGEON_CORE_TESTS_GEN_H_ diff --git a/packages/pigeon/platform_tests/test_plugin/linux/test/multiple_arity_test.cc b/packages/pigeon/platform_tests/test_plugin/linux/test/multiple_arity_test.cc new file mode 100644 index 000000000000..4e9ab9a9a279 --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/linux/test/multiple_arity_test.cc @@ -0,0 +1,44 @@ +// 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. + +#include + +#include "pigeon/multiple_arity.gen.h" +#include "test/utils/fake_host_messenger.h" + +static MultipleArityPigeonTestMultipleArityHostApiSubtractResponse* subtract( + int64_t x, int64_t y, gpointer user_data) { + return multiple_arity_pigeon_test_multiple_arity_host_api_subtract_response_new( + x - y); +} + +static MultipleArityPigeonTestMultipleArityHostApiVTable vtable = { + .subtract = subtract}; + +static void subtract_reply_cb(FlValue* reply, gpointer user_data) { + int64_t* result = reinterpret_cast(user_data); + *result = fl_value_get_int(fl_value_get_list_value(reply, 0)); +} + +TEST(MultipleArity, HostSimple) { + g_autoptr(FlStandardMessageCodec) codec = fl_standard_message_codec_new(); + g_autoptr(FakeHostMessenger) messenger = + fake_host_messenger_new(FL_MESSAGE_CODEC(codec)); + multiple_arity_pigeon_test_multiple_arity_host_api_set_method_handlers( + FL_BINARY_MESSENGER(messenger), nullptr, &vtable, nullptr, nullptr); + + int64_t result = 0; + g_autoptr(FlValue) message = fl_value_new_list(); + fl_value_append_take(message, fl_value_new_int(30)); + fl_value_append_take(message, fl_value_new_int(10)); + fake_host_messenger_send_host_message( + messenger, + "dev.flutter.pigeon.pigeon_integration_tests.MultipleArityHostApi." + "subtract", + message, subtract_reply_cb, &result); + + EXPECT_EQ(result, 20); +} + +// TODO(stuartmorgan): Add a FlutterApi version of the test. diff --git a/packages/pigeon/platform_tests/test_plugin/linux/test/non_null_fields_test.cc b/packages/pigeon/platform_tests/test_plugin/linux/test/non_null_fields_test.cc new file mode 100644 index 000000000000..93c3938149aa --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/linux/test/non_null_fields_test.cc @@ -0,0 +1,17 @@ +// 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. + +#include + +#include "pigeon/non_null_fields.gen.h" + +TEST(NonNullFields, Build) { + g_autoptr(NonNullFieldsPigeonTestNonNullFieldSearchRequest) request = + non_null_fields_pigeon_test_non_null_field_search_request_new("hello"); + + EXPECT_STREQ( + non_null_fields_pigeon_test_non_null_field_search_request_get_query( + request), + "hello"); +} diff --git a/packages/pigeon/platform_tests/test_plugin/linux/test/null_fields_test.cc b/packages/pigeon/platform_tests/test_plugin/linux/test/null_fields_test.cc new file mode 100644 index 000000000000..fc0410f312ea --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/linux/test/null_fields_test.cc @@ -0,0 +1,63 @@ +// 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. + +#include + +#include "pigeon/null_fields.gen.h" + +TEST(NullFields, BuildWithValues) { + g_autoptr(NullFieldsPigeonTestNullFieldsSearchRequest) request = + null_fields_pigeon_test_null_fields_search_request_new("hello", 0); + + int64_t indicies_values[] = {1, 2, 3}; + g_autoptr(FlValue) indicies = fl_value_new_int64_list(indicies_values, 3); + NullFieldsPigeonTestNullFieldsSearchReplyType type = + PIGEON_INTEGRATION_TESTS_NULL_FIELDS_SEARCH_REPLY_TYPE_SUCCESS; + g_autoptr(NullFieldsPigeonTestNullFieldsSearchReply) reply = + null_fields_pigeon_test_null_fields_search_reply_new( + "result", "error", indicies, request, &type); + + EXPECT_STREQ( + null_fields_pigeon_test_null_fields_search_reply_get_result(reply), + "result"); + EXPECT_STREQ( + null_fields_pigeon_test_null_fields_search_reply_get_error(reply), + "error"); + EXPECT_EQ( + fl_value_get_length( + null_fields_pigeon_test_null_fields_search_reply_get_indices(reply)), + 3); + EXPECT_STREQ( + null_fields_pigeon_test_null_fields_search_request_get_query( + null_fields_pigeon_test_null_fields_search_reply_get_request(reply)), + "hello"); + EXPECT_EQ(*null_fields_pigeon_test_null_fields_search_reply_get_type_(reply), + PIGEON_INTEGRATION_TESTS_NULL_FIELDS_SEARCH_REPLY_TYPE_SUCCESS); +} + +TEST(NullFields, BuildRequestWithNulls) { + g_autoptr(NullFieldsPigeonTestNullFieldsSearchRequest) request = + null_fields_pigeon_test_null_fields_search_request_new(nullptr, 0); + + EXPECT_EQ( + null_fields_pigeon_test_null_fields_search_request_get_query(request), + nullptr); +} + +TEST(NullFields, BuildReplyWithNulls) { + g_autoptr(NullFieldsPigeonTestNullFieldsSearchReply) reply = + null_fields_pigeon_test_null_fields_search_reply_new( + nullptr, nullptr, nullptr, nullptr, nullptr); + + EXPECT_EQ(null_fields_pigeon_test_null_fields_search_reply_get_result(reply), + nullptr); + EXPECT_EQ(null_fields_pigeon_test_null_fields_search_reply_get_error(reply), + nullptr); + EXPECT_EQ(null_fields_pigeon_test_null_fields_search_reply_get_indices(reply), + nullptr); + EXPECT_EQ(null_fields_pigeon_test_null_fields_search_reply_get_request(reply), + nullptr); + EXPECT_EQ(null_fields_pigeon_test_null_fields_search_reply_get_type_(reply), + nullptr); +} diff --git a/packages/pigeon/platform_tests/test_plugin/linux/test/nullable_returns_test.cc b/packages/pigeon/platform_tests/test_plugin/linux/test/nullable_returns_test.cc new file mode 100644 index 000000000000..0dc2a346fad3 --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/linux/test/nullable_returns_test.cc @@ -0,0 +1,132 @@ +// 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. + +#include + +#include "pigeon/nullable_returns.gen.h" +#include "test/utils/fake_host_messenger.h" + +static NullableReturnsPigeonTestNullableArgHostApiDoitResponse* arg_doit( + int64_t* x, gpointer user_data) { + return nullable_returns_pigeon_test_nullable_arg_host_api_doit_response_new( + x == nullptr ? 42 : *x); +} + +static NullableReturnsPigeonTestNullableArgHostApiVTable arg_vtable = { + .doit = arg_doit}; + +static void arg_doit_reply_cb(FlValue* reply, gpointer user_data) { + int64_t* result = reinterpret_cast(user_data); + *result = fl_value_get_int(fl_value_get_list_value(reply, 0)); +} + +TEST(NullableReturns, HostNullableArgNull) { + g_autoptr(FlStandardMessageCodec) codec = fl_standard_message_codec_new(); + g_autoptr(FakeHostMessenger) messenger = + fake_host_messenger_new(FL_MESSAGE_CODEC(codec)); + nullable_returns_pigeon_test_nullable_arg_host_api_set_method_handlers( + FL_BINARY_MESSENGER(messenger), nullptr, &arg_vtable, nullptr, nullptr); + + int64_t result = 0; + g_autoptr(FlValue) message = fl_value_new_list(); + fl_value_append_take(message, fl_value_new_null()); + fake_host_messenger_send_host_message( + messenger, + "dev.flutter.pigeon.pigeon_integration_tests.NullableArgHostApi.doit", + message, arg_doit_reply_cb, &result); + + EXPECT_EQ(result, 42); +} + +TEST(NullableReturns, HostNullableArgNonNull) { + g_autoptr(FlStandardMessageCodec) codec = fl_standard_message_codec_new(); + g_autoptr(FakeHostMessenger) messenger = + fake_host_messenger_new(FL_MESSAGE_CODEC(codec)); + nullable_returns_pigeon_test_nullable_arg_host_api_set_method_handlers( + FL_BINARY_MESSENGER(messenger), nullptr, &arg_vtable, nullptr, nullptr); + + int64_t result = 0; + g_autoptr(FlValue) message = fl_value_new_list(); + fl_value_append_take(message, fl_value_new_int(7)); + fake_host_messenger_send_host_message( + messenger, + "dev.flutter.pigeon.pigeon_integration_tests.NullableArgHostApi.doit", + message, arg_doit_reply_cb, &result); + + EXPECT_EQ(result, 7); +} + +static NullableReturnsPigeonTestNullableReturnHostApiDoitResponse* +return_null_doit(gpointer user_data) { + return nullable_returns_pigeon_test_nullable_return_host_api_doit_response_new( + nullptr); +} + +static NullableReturnsPigeonTestNullableReturnHostApiVTable return_null_vtable = + {.doit = return_null_doit}; + +static NullableReturnsPigeonTestNullableReturnHostApiDoitResponse* +return_nonnull_doit(gpointer user_data) { + int64_t return_value = 42; + return nullable_returns_pigeon_test_nullable_return_host_api_doit_response_new( + &return_value); +} + +static NullableReturnsPigeonTestNullableReturnHostApiVTable + return_nonnull_vtable = {.doit = return_nonnull_doit}; + +static void return_doit_reply_cb(FlValue* reply, gpointer user_data) { + int64_t** result = reinterpret_cast(user_data); + FlValue* value = fl_value_get_list_value(reply, 0); + if (fl_value_get_type(value) == FL_VALUE_TYPE_NULL) { + *result = nullptr; + } else { + *result = reinterpret_cast(malloc(sizeof(int64_t))); + **result = fl_value_get_int(value); + } +} + +TEST(NullableReturns, HostNullableReturnNull) { + g_autoptr(FlStandardMessageCodec) codec = fl_standard_message_codec_new(); + g_autoptr(FakeHostMessenger) messenger = + fake_host_messenger_new(FL_MESSAGE_CODEC(codec)); + nullable_returns_pigeon_test_nullable_return_host_api_set_method_handlers( + FL_BINARY_MESSENGER(messenger), nullptr, &return_null_vtable, nullptr, + nullptr); + + // Initialize to a non-null value to ensure that it's actually set to null, + // rather than just never set. + int64_t result_ = 99; + int64_t* result = &result_; + g_autoptr(FlValue) message = fl_value_new_list(); + fl_value_append_take(message, fl_value_new_null()); + fake_host_messenger_send_host_message( + messenger, + "dev.flutter.pigeon.pigeon_integration_tests.NullableReturnHostApi.doit", + message, return_doit_reply_cb, &result); + + EXPECT_EQ(result, nullptr); +} + +TEST(NullableReturns, HostNullableReturnNonNull) { + g_autoptr(FlStandardMessageCodec) codec = fl_standard_message_codec_new(); + g_autoptr(FakeHostMessenger) messenger = + fake_host_messenger_new(FL_MESSAGE_CODEC(codec)); + nullable_returns_pigeon_test_nullable_return_host_api_set_method_handlers( + FL_BINARY_MESSENGER(messenger), nullptr, &return_nonnull_vtable, nullptr, + nullptr); + + g_autofree int64_t* result = nullptr; + g_autoptr(FlValue) message = fl_value_new_list(); + fl_value_append_take(message, fl_value_new_null()); + fake_host_messenger_send_host_message( + messenger, + "dev.flutter.pigeon.pigeon_integration_tests.NullableReturnHostApi.doit", + message, return_doit_reply_cb, &result); + + EXPECT_NE(result, nullptr); + EXPECT_EQ(*result, 42); +} + +// TODO(stuartmorgan): Add FlutterApi versions of the tests. diff --git a/packages/pigeon/platform_tests/test_plugin/linux/test/primitive_test.cc b/packages/pigeon/platform_tests/test_plugin/linux/test/primitive_test.cc new file mode 100644 index 000000000000..cfb67feb069d --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/linux/test/primitive_test.cc @@ -0,0 +1,216 @@ +// 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. + +#include + +#include "pigeon/primitive.gen.h" +#include "test/utils/fake_host_messenger.h" + +static PrimitivePigeonTestPrimitiveHostApiAnIntResponse* an_int( + int64_t value, gpointer user_data) { + return primitive_pigeon_test_primitive_host_api_an_int_response_new(value); +} + +static PrimitivePigeonTestPrimitiveHostApiABoolResponse* a_bool( + gboolean value, gpointer user_data) { + return primitive_pigeon_test_primitive_host_api_a_bool_response_new(value); +} + +static PrimitivePigeonTestPrimitiveHostApiAStringResponse* a_string( + const gchar* value, gpointer user_data) { + return primitive_pigeon_test_primitive_host_api_a_string_response_new(value); +} + +static PrimitivePigeonTestPrimitiveHostApiADoubleResponse* a_double( + double value, gpointer user_data) { + return primitive_pigeon_test_primitive_host_api_a_double_response_new(value); +} + +static PrimitivePigeonTestPrimitiveHostApiAMapResponse* a_map( + FlValue* value, gpointer user_data) { + return primitive_pigeon_test_primitive_host_api_a_map_response_new(value); +} + +static PrimitivePigeonTestPrimitiveHostApiAListResponse* a_list( + FlValue* value, gpointer user_data) { + return primitive_pigeon_test_primitive_host_api_a_list_response_new(value); +} + +static PrimitivePigeonTestPrimitiveHostApiAnInt32ListResponse* an_int32_list( + const int32_t* value, size_t value_length, gpointer user_data) { + return primitive_pigeon_test_primitive_host_api_an_int32_list_response_new( + value, value_length); +} + +static PrimitivePigeonTestPrimitiveHostApiABoolListResponse* a_bool_list( + FlValue* value, gpointer user_data) { + return primitive_pigeon_test_primitive_host_api_a_bool_list_response_new( + value); +} + +static PrimitivePigeonTestPrimitiveHostApiAStringIntMapResponse* +a_string_int_map(FlValue* value, gpointer user_data) { + return primitive_pigeon_test_primitive_host_api_a_string_int_map_response_new( + value); +} + +static PrimitivePigeonTestPrimitiveHostApiVTable vtable = { + .an_int = an_int, + .a_bool = a_bool, + .a_string = a_string, + .a_double = a_double, + .a_map = a_map, + .a_list = a_list, + .an_int32_list = an_int32_list, + .a_bool_list = a_bool_list, + .a_string_int_map = a_string_int_map}; + +static void an_int_reply_cb(FlValue* reply, gpointer user_data) { + int64_t* result = reinterpret_cast(user_data); + *result = fl_value_get_int(fl_value_get_list_value(reply, 0)); +} + +TEST(Primitive, HostInt) { + g_autoptr(FlStandardMessageCodec) codec = fl_standard_message_codec_new(); + g_autoptr(FakeHostMessenger) messenger = + fake_host_messenger_new(FL_MESSAGE_CODEC(codec)); + primitive_pigeon_test_primitive_host_api_set_method_handlers( + FL_BINARY_MESSENGER(messenger), nullptr, &vtable, nullptr, nullptr); + + int64_t result = 0; + g_autoptr(FlValue) message = fl_value_new_list(); + fl_value_append_take(message, fl_value_new_int(7)); + fake_host_messenger_send_host_message( + messenger, + "dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.anInt", + message, an_int_reply_cb, &result); + + EXPECT_EQ(result, 7); +} + +static void a_bool_reply_cb(FlValue* reply, gpointer user_data) { + gboolean* result = reinterpret_cast(user_data); + *result = fl_value_get_bool(fl_value_get_list_value(reply, 0)); +} + +TEST(Primitive, HostBool) { + g_autoptr(FlStandardMessageCodec) codec = fl_standard_message_codec_new(); + g_autoptr(FakeHostMessenger) messenger = + fake_host_messenger_new(FL_MESSAGE_CODEC(codec)); + primitive_pigeon_test_primitive_host_api_set_method_handlers( + FL_BINARY_MESSENGER(messenger), nullptr, &vtable, nullptr, nullptr); + + gboolean result = false; + g_autoptr(FlValue) message = fl_value_new_list(); + fl_value_append_take(message, fl_value_new_bool(TRUE)); + fake_host_messenger_send_host_message( + messenger, + "dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.aBool", + message, a_bool_reply_cb, &result); + + EXPECT_EQ(result, true); +} + +static void a_double_reply_cb(FlValue* reply, gpointer user_data) { + double* result = reinterpret_cast(user_data); + *result = fl_value_get_float(fl_value_get_list_value(reply, 0)); +} + +TEST(Primitive, HostDouble) { + g_autoptr(FlStandardMessageCodec) codec = fl_standard_message_codec_new(); + g_autoptr(FakeHostMessenger) messenger = + fake_host_messenger_new(FL_MESSAGE_CODEC(codec)); + primitive_pigeon_test_primitive_host_api_set_method_handlers( + FL_BINARY_MESSENGER(messenger), nullptr, &vtable, nullptr, nullptr); + + double result = 0.0; + g_autoptr(FlValue) message = fl_value_new_list(); + fl_value_append_take(message, fl_value_new_float(3.0)); + fake_host_messenger_send_host_message( + messenger, + "dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.aDouble", + message, a_double_reply_cb, &result); + + EXPECT_EQ(result, 3.0); +} + +static void a_string_reply_cb(FlValue* reply, gpointer user_data) { + gchar** result = reinterpret_cast(user_data); + *result = g_strdup(fl_value_get_string(fl_value_get_list_value(reply, 0))); +} + +TEST(Primitive, HostString) { + g_autoptr(FlStandardMessageCodec) codec = fl_standard_message_codec_new(); + g_autoptr(FakeHostMessenger) messenger = + fake_host_messenger_new(FL_MESSAGE_CODEC(codec)); + primitive_pigeon_test_primitive_host_api_set_method_handlers( + FL_BINARY_MESSENGER(messenger), nullptr, &vtable, nullptr, nullptr); + + g_autofree gchar* result = nullptr; + g_autoptr(FlValue) message = fl_value_new_list(); + fl_value_append_take(message, fl_value_new_string("hello")); + fake_host_messenger_send_host_message( + messenger, + "dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.aString", + message, a_string_reply_cb, &result); + + EXPECT_STREQ(result, "hello"); +} + +static void a_list_reply_cb(FlValue* reply, gpointer user_data) { + FlValue** result = reinterpret_cast(user_data); + *result = fl_value_ref(fl_value_get_list_value(reply, 0)); +} + +TEST(Primitive, HostList) { + g_autoptr(FlStandardMessageCodec) codec = fl_standard_message_codec_new(); + g_autoptr(FakeHostMessenger) messenger = + fake_host_messenger_new(FL_MESSAGE_CODEC(codec)); + primitive_pigeon_test_primitive_host_api_set_method_handlers( + FL_BINARY_MESSENGER(messenger), nullptr, &vtable, nullptr, nullptr); + + g_autoptr(FlValue) result = nullptr; + g_autoptr(FlValue) message = fl_value_new_list(); + g_autoptr(FlValue) list = fl_value_new_list(); + fl_value_append_take(list, fl_value_new_int(1)); + fl_value_append_take(list, fl_value_new_int(2)); + fl_value_append_take(list, fl_value_new_int(3)); + fl_value_append(message, list); + fake_host_messenger_send_host_message( + messenger, + "dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.aList", + message, a_list_reply_cb, &result); + + EXPECT_EQ(fl_value_get_length(result), 3); + EXPECT_EQ(fl_value_get_int(fl_value_get_list_value(result, 2)), 3); +} + +static void a_map_reply_cb(FlValue* reply, gpointer user_data) { + FlValue** result = reinterpret_cast(user_data); + *result = fl_value_ref(fl_value_get_list_value(reply, 0)); +} + +TEST(Primitive, HostMap) { + g_autoptr(FlStandardMessageCodec) codec = fl_standard_message_codec_new(); + g_autoptr(FakeHostMessenger) messenger = + fake_host_messenger_new(FL_MESSAGE_CODEC(codec)); + primitive_pigeon_test_primitive_host_api_set_method_handlers( + FL_BINARY_MESSENGER(messenger), nullptr, &vtable, nullptr, nullptr); + + g_autoptr(FlValue) result = nullptr; + g_autoptr(FlValue) message = fl_value_new_list(); + g_autoptr(FlValue) map = fl_value_new_map(); + fl_value_set_string_take(map, "foo", fl_value_new_string("bar")); + fl_value_append(message, map); + fake_host_messenger_send_host_message( + messenger, + "dev.flutter.pigeon.pigeon_integration_tests.PrimitiveHostApi.aMap", + message, a_map_reply_cb, &result); + + EXPECT_EQ(fl_value_get_length(result), 1); + EXPECT_STREQ(fl_value_get_string(fl_value_lookup_string(result, "foo")), + "bar"); +} + +// TODO(stuartmorgan): Add FlutterApi versions of the tests. diff --git a/packages/pigeon/platform_tests/test_plugin/linux/test/utils/fake_host_messenger.cc b/packages/pigeon/platform_tests/test_plugin/linux/test/utils/fake_host_messenger.cc new file mode 100644 index 000000000000..b78301cec7f0 --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/linux/test/utils/fake_host_messenger.cc @@ -0,0 +1,183 @@ +// 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. + +#include "fake_host_messenger.h" + +struct _FakeHostMessenger { + GObject parent_instance; + + FlMessageCodec* codec; + GHashTable* message_handlers; +}; + +G_DECLARE_FINAL_TYPE(FakeHostMessengerResponseHandle, + fake_host_messenger_response_handle, FAKE, + HOST_MESSENGER_RESPONSE_HANDLE, + FlBinaryMessengerResponseHandle) + +struct _FakeHostMessengerResponseHandle { + FlBinaryMessengerResponseHandle parent_instance; + + FakeHostMessengerReplyHandler reply_callback; + gpointer user_data; +}; + +static void fake_host_messenger_response_handle_class_init( + FakeHostMessengerResponseHandleClass* klass) {} + +static void fake_host_messenger_response_handle_init( + FakeHostMessengerResponseHandle* self) {} + +G_DEFINE_TYPE(FakeHostMessengerResponseHandle, + fake_host_messenger_response_handle, + fl_binary_messenger_response_handle_get_type()) + +FakeHostMessengerResponseHandle* fake_host_messenger_response_handle_new( + FakeHostMessengerReplyHandler reply_callback, gpointer user_data) { + FakeHostMessengerResponseHandle* self = FAKE_HOST_MESSENGER_RESPONSE_HANDLE( + g_object_new(fake_host_messenger_response_handle_get_type(), nullptr)); + + self->reply_callback = reply_callback; + self->user_data = user_data; + + return self; +} + +typedef struct { + FlBinaryMessengerMessageHandler message_handler; + gpointer message_handler_data; + GDestroyNotify message_handler_destroy_notify; +} MessageHandler; + +static MessageHandler* message_handler_new( + FlBinaryMessengerMessageHandler handler, gpointer user_data, + GDestroyNotify destroy_notify) { + MessageHandler* self = + static_cast(g_malloc0(sizeof(MessageHandler))); + self->message_handler = handler; + self->message_handler_data = user_data; + self->message_handler_destroy_notify = destroy_notify; + return self; +} + +static void message_handler_free(gpointer data) { + MessageHandler* self = static_cast(data); + if (self->message_handler_destroy_notify) { + self->message_handler_destroy_notify(self->message_handler_data); + } + + g_free(self); +} + +static void fake_host_messenger_binary_messenger_iface_init( + FlBinaryMessengerInterface* iface); + +G_DEFINE_TYPE_WITH_CODE( + FakeHostMessenger, fake_host_messenger, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(fl_binary_messenger_get_type(), + fake_host_messenger_binary_messenger_iface_init)) + +static void set_message_handler_on_channel( + FlBinaryMessenger* messenger, const gchar* channel, + FlBinaryMessengerMessageHandler handler, gpointer user_data, + GDestroyNotify destroy_notify) { + FakeHostMessenger* self = FAKE_HOST_MESSENGER(messenger); + g_hash_table_replace(self->message_handlers, g_strdup(channel), + message_handler_new(handler, user_data, destroy_notify)); +} + +static gboolean send_response(FlBinaryMessenger* messenger, + FlBinaryMessengerResponseHandle* response_handle, + GBytes* response, GError** error) { + FakeHostMessenger* self = FAKE_HOST_MESSENGER(messenger); + g_autoptr(FakeHostMessengerResponseHandle) r = + FAKE_HOST_MESSENGER_RESPONSE_HANDLE(response_handle); + g_autoptr(FlValue) reply = + fl_message_codec_decode_message(self->codec, response, error); + if (reply == nullptr) { + return FALSE; + } + + if (r->reply_callback != nullptr) { + r->reply_callback(reply, r->user_data); + } + + return TRUE; +} + +static void send_on_channel(FlBinaryMessenger* messenger, const gchar* channel, + GBytes* message, GCancellable* cancellable, + GAsyncReadyCallback callback, gpointer user_data) {} + +static GBytes* send_on_channel_finish(FlBinaryMessenger* messenger, + GAsyncResult* result, GError** error) { + return g_bytes_new(nullptr, 0); +} + +static void resize_channel(FlBinaryMessenger* messenger, const gchar* channel, + int64_t new_size) {} + +static void set_warns_on_channel_overflow(FlBinaryMessenger* messenger, + const gchar* channel, bool warns) {} + +static void fake_host_messenger_dispose(GObject* object) { + FakeHostMessenger* self = FAKE_HOST_MESSENGER(object); + + g_clear_pointer(&self->message_handlers, g_hash_table_unref); + g_clear_object(&self->codec); + + G_OBJECT_CLASS(fake_host_messenger_parent_class)->dispose(object); +} + +static void fake_host_messenger_class_init(FakeHostMessengerClass* klass) { + G_OBJECT_CLASS(klass)->dispose = fake_host_messenger_dispose; +} + +static void fake_host_messenger_binary_messenger_iface_init( + FlBinaryMessengerInterface* iface) { + iface->set_message_handler_on_channel = set_message_handler_on_channel; + iface->send_response = send_response; + iface->send_on_channel = send_on_channel; + iface->send_on_channel_finish = send_on_channel_finish; + iface->resize_channel = resize_channel; + iface->set_warns_on_channel_overflow = set_warns_on_channel_overflow; +} + +static void fake_host_messenger_init(FakeHostMessenger* self) { + self->message_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, message_handler_free); +} + +FakeHostMessenger* fake_host_messenger_new(FlMessageCodec* codec) { + FakeHostMessenger* self = FAKE_HOST_MESSENGER( + g_object_new(fake_host_messenger_get_type(), nullptr)); + + self->codec = FL_MESSAGE_CODEC(g_object_ref(codec)); + + return self; +} + +void fake_host_messenger_send_host_message( + FakeHostMessenger* self, const gchar* channel, FlValue* message, + FakeHostMessengerReplyHandler reply_callback, gpointer user_data) { + MessageHandler* handler = static_cast( + g_hash_table_lookup(self->message_handlers, channel)); + if (handler == nullptr) { + return; + } + + g_autoptr(GError) error = nullptr; + g_autoptr(GBytes) encoded_message = + fl_message_codec_encode_message(self->codec, message, &error); + if (encoded_message == nullptr) { + g_warning("Failed to encode message: %s", error->message); + return; + } + + FakeHostMessengerResponseHandle* response_handle = + fake_host_messenger_response_handle_new(reply_callback, user_data); + handler->message_handler(FL_BINARY_MESSENGER(self), channel, encoded_message, + FL_BINARY_MESSENGER_RESPONSE_HANDLE(response_handle), + handler->message_handler_data); +} diff --git a/packages/pigeon/platform_tests/test_plugin/linux/test/utils/fake_host_messenger.h b/packages/pigeon/platform_tests/test_plugin/linux/test/utils/fake_host_messenger.h new file mode 100644 index 000000000000..d8f1952781ac --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/linux/test/utils/fake_host_messenger.h @@ -0,0 +1,28 @@ +// 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. + +#ifndef PLATFORM_TESTS_TEST_PLUGIN_LINUX_TEST_UTILS_FAKE_HOST_MESSENGER_H_ +#define PLATFORM_TESTS_TEST_PLUGIN_LINUX_TEST_UTILS_FAKE_HOST_MESSENGER_H_ + +#include + +typedef void (*FakeHostMessengerReplyHandler)(FlValue* reply, + gpointer user_data); + +// A BinaryMessenger that allows tests to act as the engine to call host APIs. +G_DECLARE_FINAL_TYPE(FakeHostMessenger, fake_host_messenger, FAKE, + HOST_MESSENGER, GObject) + +FakeHostMessenger* fake_host_messenger_new(FlMessageCodec* codec); + +// Calls the registered handler for the given channel, and calls reply_handler +// with the response. +// +// This allows a test to simulate a message from the Dart side, exercising the +// encoding and decoding logic generated for a host API. +void fake_host_messenger_send_host_message( + FakeHostMessenger* messenger, const gchar* channel, FlValue* message, + FakeHostMessengerReplyHandler reply_callback, gpointer user_data); + +#endif // PLATFORM_TESTS_TEST_PLUGIN_LINUX_TEST_UTILS_FAKE_HOST_MESSENGER_H_ diff --git a/packages/pigeon/platform_tests/test_plugin/linux/test_plugin.cc b/packages/pigeon/platform_tests/test_plugin/linux/test_plugin.cc new file mode 100644 index 000000000000..14938e9980f0 --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/linux/test_plugin.cc @@ -0,0 +1,3432 @@ +// 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. + +#include "include/test_plugin/test_plugin.h" + +#include +#include +#include + +#include + +#include "pigeon/core_tests.gen.h" +#include "test_plugin_private.h" + +struct _TestPlugin { + GObject parent_instance; + + FlBinaryMessenger* messenger; + + CoreTestsPigeonTestFlutterIntegrationCoreApi* flutter_core_api; + + CoreTestsPigeonTestFlutterSmallApi* flutter_small_api_one; + CoreTestsPigeonTestFlutterSmallApi* flutter_small_api_two; + + GCancellable* cancellable; +}; + +G_DEFINE_TYPE(TestPlugin, test_plugin, G_TYPE_OBJECT) + +typedef struct { + TestPlugin* self; + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle; +} CallbackData; + +static CallbackData* callback_data_new( + TestPlugin* self, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle) { + CallbackData* data = g_new0(CallbackData, 1); + data->self = TEST_PLUGIN(g_object_ref(self)); + data->response_handle = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_RESPONSE_HANDLE( + g_object_ref(response_handle)); + return data; +} + +static void callback_data_free(CallbackData* data) { + g_object_unref(data->self); + g_object_unref(data->response_handle); + free(data); +} + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(CallbackData, callback_data_free) + +static CoreTestsPigeonTestHostIntegrationCoreApiNoopResponse* noop( + gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_noop_response_new(); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAllTypesResponse* +echo_all_types(CoreTestsPigeonTestAllTypes* everything, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_all_types_response_new( + everything); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorResponse* throw_error( + gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_throw_error_response_new_error( + "An error", "", nullptr); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiThrowErrorFromVoidResponse* +throw_error_from_void(gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_throw_error_from_void_response_new_error( + "An error", "", nullptr); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiThrowFlutterErrorResponse* +throw_flutter_error(gpointer user_data) { + g_autoptr(FlValue) details = fl_value_new_string("details"); + return core_tests_pigeon_test_host_integration_core_api_throw_flutter_error_response_new_error( + "code", "message", details); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoIntResponse* echo_int( + int64_t an_int, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_int_response_new( + an_int); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleResponse* echo_double( + double a_double, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_double_response_new( + a_double); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponse* echo_bool( + gboolean a_bool, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_bool_response_new( + a_bool); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse* echo_string( + const gchar* a_string, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_string_response_new( + a_string); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse* +echo_uint8_list(const uint8_t* a_uint8_list, size_t a_uint8_list_length, + gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_new( + a_uint8_list, a_uint8_list_length); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse* echo_object( + FlValue* an_object, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_object_response_new( + an_object); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* echo_list( + FlValue* a_list, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_list_response_new( + a_list); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumListResponse* +echo_enum_list(FlValue* enum_list, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_enum_list_response_new( + enum_list); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoClassListResponse* +echo_class_list(FlValue* class_list, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_class_list_response_new( + class_list); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumListResponse* +echo_non_null_enum_list(FlValue* enum_list, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_list_response_new( + enum_list); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassListResponse* +echo_non_null_class_list(FlValue* class_list, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_list_response_new( + class_list); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoMapResponse* echo_map( + FlValue* map, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_map_response_new( + map); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoStringMapResponse* +echo_string_map(FlValue* string_map, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_string_map_response_new( + string_map); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoIntMapResponse* +echo_int_map(FlValue* int_map, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_int_map_response_new( + int_map); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumMapResponse* +echo_enum_map(FlValue* _enum_map, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_enum_map_response_new( + _enum_map); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoClassMapResponse* +echo_class_map(FlValue* class_map, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_class_map_response_new( + class_map); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullStringMapResponse* +echo_non_null_string_map(FlValue* string_map, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_non_null_string_map_response_new( + string_map); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullIntMapResponse* +echo_non_null_int_map(FlValue* int_map, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_non_null_int_map_response_new( + int_map); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullEnumMapResponse* +echo_non_null_enum_map(FlValue* _enum_map, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_non_null_enum_map_response_new( + _enum_map); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNonNullClassMapResponse* +echo_non_null_class_map(FlValue* class_map, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_non_null_class_map_response_new( + class_map); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoClassWrapperResponse* +echo_class_wrapper(CoreTestsPigeonTestAllClassesWrapper* wrapper, + gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_class_wrapper_response_new( + wrapper); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumResponse* echo_enum( + + CoreTestsPigeonTestAnEnum an_enum, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_enum_response_new( + an_enum); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherEnumResponse* +echo_another_enum( + + CoreTestsPigeonTestAnotherEnum another_enum, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_another_enum_response_new( + another_enum); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedDefaultStringResponse* +echo_named_default_string(const gchar* a_string, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_named_default_string_response_new( + a_string); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalDefaultDoubleResponse* +echo_optional_default_double(double a_double, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_optional_default_double_response_new( + a_double); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoRequiredIntResponse* +echo_required_int(int64_t an_int, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_required_int_response_new( + an_int); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesResponse* +echo_all_nullable_types(CoreTestsPigeonTestAllNullableTypes* everything, + gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_response_new( + everything); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse* +echo_all_nullable_types_without_recursion( + + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* everything, + gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_all_nullable_types_without_recursion_response_new( + everything); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiExtractNestedNullableStringResponse* +extract_nested_nullable_string(CoreTestsPigeonTestAllClassesWrapper* wrapper, + gpointer user_data) { + CoreTestsPigeonTestAllNullableTypes* types = + core_tests_pigeon_test_all_classes_wrapper_get_all_nullable_types( + wrapper); + return core_tests_pigeon_test_host_integration_core_api_extract_nested_nullable_string_response_new( + core_tests_pigeon_test_all_nullable_types_get_a_nullable_string(types)); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiCreateNestedNullableStringResponse* +create_nested_nullable_string(const gchar* nullable_string, + gpointer user_data) { + g_autoptr(CoreTestsPigeonTestAllNullableTypes) types = + core_tests_pigeon_test_all_nullable_types_new( + nullptr, nullptr, nullptr, nullptr, nullptr, 0, nullptr, 0, nullptr, + 0, nullptr, 0, nullptr, nullptr, nullable_string, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr); + FlValue* classList = fl_value_new_list(); + FlValue* classMap = fl_value_new_map(); + g_autoptr(CoreTestsPigeonTestAllClassesWrapper) wrapper = + core_tests_pigeon_test_all_classes_wrapper_new( + types, nullptr, nullptr, classList, nullptr, classMap, nullptr); + return core_tests_pigeon_test_host_integration_core_api_create_nested_nullable_string_response_new( + wrapper); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesResponse* +send_multiple_nullable_types(gboolean* a_nullable_bool, int64_t* a_nullable_int, + const gchar* a_nullable_string, + gpointer user_data) { + g_autoptr(CoreTestsPigeonTestAllNullableTypes) types = + core_tests_pigeon_test_all_nullable_types_new( + a_nullable_bool, a_nullable_int, nullptr, nullptr, nullptr, 0, + nullptr, 0, nullptr, 0, nullptr, 0, nullptr, nullptr, + a_nullable_string, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr); + return core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_response_new( + types); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse* +send_multiple_nullable_types_without_recursion(gboolean* a_nullable_bool, + int64_t* a_nullable_int, + const gchar* a_nullable_string, + gpointer user_data) { + g_autoptr(CoreTestsPigeonTestAllNullableTypesWithoutRecursion) types = + core_tests_pigeon_test_all_nullable_types_without_recursion_new( + a_nullable_bool, a_nullable_int, nullptr, nullptr, nullptr, 0, + nullptr, 0, nullptr, 0, nullptr, 0, nullptr, nullptr, + a_nullable_string, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr); + return core_tests_pigeon_test_host_integration_core_api_send_multiple_nullable_types_without_recursion_response_new( + types); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntResponse* +echo_nullable_int(int64_t* a_nullable_int, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_response_new( + a_nullable_int); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableDoubleResponse* +echo_nullable_double(double* a_nullable_double, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_nullable_double_response_new( + a_nullable_double); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableBoolResponse* +echo_nullable_bool(gboolean* a_nullable_bool, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_nullable_bool_response_new( + a_nullable_bool); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringResponse* +echo_nullable_string(const gchar* a_nullable_string, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_response_new( + a_nullable_string); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableUint8ListResponse* +echo_nullable_uint8_list(const uint8_t* a_nullable_uint8_list, + size_t a_nullable_uint8_list_length, + gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_nullable_uint8_list_response_new( + a_nullable_uint8_list, a_nullable_uint8_list_length); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableObjectResponse* +echo_nullable_object(FlValue* a_nullable_object, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_nullable_object_response_new( + a_nullable_object); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableListResponse* +echo_nullable_list(FlValue* a_nullable_list, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_nullable_list_response_new( + a_nullable_list); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumListResponse* +echo_nullable_enum_list(FlValue* enum_list, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_list_response_new( + enum_list); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassListResponse* +echo_nullable_class_list(FlValue* class_list, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_list_response_new( + class_list); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumListResponse* +echo_nullable_non_null_enum_list(FlValue* enum_list, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_list_response_new( + enum_list); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassListResponse* +echo_nullable_non_null_class_list(FlValue* class_list, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_list_response_new( + class_list); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableMapResponse* +echo_nullable_map(FlValue* map, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_nullable_map_response_new( + map); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableStringMapResponse* +echo_nullable_string_map(FlValue* string_map, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_nullable_string_map_response_new( + string_map); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableIntMapResponse* +echo_nullable_int_map(FlValue* int_map, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_nullable_int_map_response_new( + int_map); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumMapResponse* +echo_nullable_enum_map(FlValue* enum_map, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_map_response_new( + enum_map); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableClassMapResponse* +echo_nullable_class_map(FlValue* class_map, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_nullable_class_map_response_new( + class_map); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullStringMapResponse* +echo_nullable_non_null_string_map(FlValue* string_map, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_string_map_response_new( + string_map); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullIntMapResponse* +echo_nullable_non_null_int_map(FlValue* int_map, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_int_map_response_new( + int_map); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullEnumMapResponse* +echo_nullable_non_null_enum_map(FlValue* enum_map, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_enum_map_response_new( + enum_map); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableNonNullClassMapResponse* +echo_nullable_non_null_class_map(FlValue* class_map, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_nullable_non_null_class_map_response_new( + class_map); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNullableEnumResponse* +echo_nullable_enum(CoreTestsPigeonTestAnEnum* an_enum, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_nullable_enum_response_new( + an_enum); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoAnotherNullableEnumResponse* +echo_another_nullable_enum(CoreTestsPigeonTestAnotherEnum* another_enum, + gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_another_nullable_enum_response_new( + another_enum); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoOptionalNullableIntResponse* +echo_optional_nullable_int(int64_t* a_nullable_int, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_optional_nullable_int_response_new( + a_nullable_int); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoNamedNullableStringResponse* +echo_named_nullable_string(const gchar* a_nullable_string, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_named_nullable_string_response_new( + a_nullable_string); +} + +static void noop_async( + + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_noop_async( + response_handle); +} + +static void echo_async_int( + int64_t an_int, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_int( + response_handle, an_int); +} + +static void echo_async_double( + double a_double, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_double( + response_handle, a_double); +} + +static void echo_async_bool( + gboolean a_bool, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_bool( + response_handle, a_bool); +} + +static void echo_async_string( + const gchar* a_string, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_string( + response_handle, a_string); +} + +static void echo_async_uint8_list( + const uint8_t* a_uint8_list, size_t a_uint8_list_length, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_uint8_list( + response_handle, a_uint8_list, a_uint8_list_length); +} + +static void echo_async_object( + FlValue* an_object, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_object( + response_handle, an_object); +} + +static void echo_async_list( + FlValue* a_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_list( + response_handle, a_list); +} + +static void echo_async_enum_list( + FlValue* enum_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_enum_list( + response_handle, enum_list); +} + +static void echo_async_class_list( + FlValue* class_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_class_list( + response_handle, class_list); +} + +static void echo_async_map( + FlValue* map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_map( + response_handle, map); +} + +static void echo_async_string_map( + FlValue* string_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_string_map( + response_handle, string_map); +} + +static void echo_async_int_map( + FlValue* int_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_int_map( + response_handle, int_map); +} + +static void echo_async_enum_map( + FlValue* enum_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_enum_map( + response_handle, enum_map); +} + +static void echo_async_class_map( + FlValue* class_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_class_map( + response_handle, class_map); +} + +static void echo_async_enum( + + CoreTestsPigeonTestAnEnum an_enum, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_enum( + response_handle, an_enum); +} + +static void echo_another_async_enum( + + CoreTestsPigeonTestAnotherEnum another_enum, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_another_async_enum( + response_handle, another_enum); +} + +static void throw_async_error( + + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + g_autoptr(FlValue) details = fl_value_new_string("details"); + core_tests_pigeon_test_host_integration_core_api_respond_error_throw_async_error( + response_handle, "code", "message", details); +} + +static void throw_async_error_from_void( + + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + g_autoptr(FlValue) details = fl_value_new_string("details"); + core_tests_pigeon_test_host_integration_core_api_respond_error_throw_async_error_from_void( + response_handle, "code", "message", details); +} + +static void throw_async_flutter_error( + + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + g_autoptr(FlValue) details = fl_value_new_string("details"); + core_tests_pigeon_test_host_integration_core_api_respond_error_throw_async_flutter_error( + response_handle, "code", "message", details); +} + +static void echo_async_all_types( + + CoreTestsPigeonTestAllTypes* everything, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_all_types( + response_handle, everything); +} + +static void echo_async_nullable_all_nullable_types( + + CoreTestsPigeonTestAllNullableTypes* everything, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_all_nullable_types( + response_handle, everything); +} + +static void echo_async_nullable_all_nullable_types_without_recursion( + + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* everything, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_all_nullable_types_without_recursion( + response_handle, everything); +} + +static void echo_async_nullable_int( + int64_t* an_int, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_int( + response_handle, an_int); +} + +static void echo_async_nullable_double( + double* a_double, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_double( + response_handle, a_double); +} + +static void echo_async_nullable_bool( + gboolean* a_bool, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_bool( + response_handle, a_bool); +} + +static void echo_async_nullable_string( + const gchar* a_string, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_string( + response_handle, a_string); +} + +static void echo_async_nullable_uint8_list( + const uint8_t* a_uint8_list, size_t a_uint8_list_length, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_uint8_list( + response_handle, a_uint8_list, a_uint8_list_length); +} + +static void echo_async_nullable_object( + FlValue* an_object, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_object( + response_handle, an_object); +} + +static void echo_async_nullable_list( + FlValue* a_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_list( + response_handle, a_list); +} + +static void echo_async_nullable_enum_list( + FlValue* enum_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_enum_list( + response_handle, enum_list); +} + +static void echo_async_nullable_class_list( + FlValue* class_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_class_list( + response_handle, class_list); +} + +static void echo_async_nullable_map( + FlValue* map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_map( + response_handle, map); +} + +static void echo_async_nullable_string_map( + FlValue* string_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_string_map( + response_handle, string_map); +} + +static void echo_async_nullable_int_map( + FlValue* int_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_int_map( + response_handle, int_map); +} + +static void echo_async_nullable_enum_map( + FlValue* enum_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_enum_map( + response_handle, enum_map); +} + +static void echo_async_nullable_class_map( + FlValue* class_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_class_map( + response_handle, class_map); +} + +static void echo_async_nullable_enum( + + CoreTestsPigeonTestAnEnum* an_enum, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_async_nullable_enum( + response_handle, an_enum); +} + +static void echo_another_async_nullable_enum( + + CoreTestsPigeonTestAnotherEnum* another_enum, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_integration_core_api_respond_echo_another_async_nullable_enum( + response_handle, another_enum); +} + +static void noop_cb(GObject* object, GAsyncResult* result, gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr(CoreTestsPigeonTestFlutterIntegrationCoreApiNoopResponse) response = + core_tests_pigeon_test_flutter_integration_core_api_noop_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), result, + &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_noop( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_noop_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_noop_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_noop_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_noop_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_noop( + data->response_handle); +} + +static void call_flutter_noop( + + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_noop( + self->flutter_core_api, nullptr, noop_cb, + callback_data_new(self, response_handle)); +} + +static void throw_error_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorResponse) response = + core_tests_pigeon_test_flutter_integration_core_api_throw_error_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), result, + &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_throw_error( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_throw_error( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_throw_error_response_get_return_value( + response)); +} + +static void call_flutter_throw_error( + + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_throw_error( + self->flutter_core_api, nullptr, throw_error_cb, + callback_data_new(self, response_handle)); +} + +static void throw_error_from_void_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiThrowErrorFromVoidResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_throw_error_from_void( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_throw_error_from_void( + data->response_handle); +} + +static void call_flutter_throw_error_from_void( + + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_throw_error_from_void( + self->flutter_core_api, nullptr, throw_error_from_void_cb, + callback_data_new(self, response_handle)); +} + +static void echo_all_types_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllTypesResponse) response = + core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), result, + &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_all_types( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_all_types( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_all_types_response_get_return_value( + response)); +} + +static void call_flutter_echo_all_types( + + CoreTestsPigeonTestAllTypes* everything, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_all_types( + self->flutter_core_api, everything, self->cancellable, echo_all_types_cb, + callback_data_new(self, response_handle)); +} + +static void echo_all_nullable_types_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_all_nullable_types( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_all_nullable_types( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_response_get_return_value( + response)); +} + +static void call_flutter_echo_all_nullable_types( + + CoreTestsPigeonTestAllNullableTypes* everything, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types( + self->flutter_core_api, everything, self->cancellable, + echo_all_nullable_types_cb, callback_data_new(self, response_handle)); +} + +static void send_multiple_nullable_types_cb(GObject* object, + GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_send_multiple_nullable_types( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_send_multiple_nullable_types( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_response_get_return_value( + response)); +} + +static void call_flutter_send_multiple_nullable_types( + gboolean* a_nullable_bool, int64_t* a_nullable_int, + const gchar* a_nullable_string, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types( + self->flutter_core_api, a_nullable_bool, a_nullable_int, + a_nullable_string, self->cancellable, send_multiple_nullable_types_cb, + callback_data_new(self, response_handle)); +} + +static void echo_all_nullable_types_without_recursion_cb(GObject* object, + GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAllNullableTypesWithoutRecursionResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_all_nullable_types_without_recursion( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_all_nullable_types_without_recursion( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion_response_get_return_value( + response)); +} + +static void call_flutter_echo_all_nullable_types_without_recursion( + + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* everything, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_all_nullable_types_without_recursion( + self->flutter_core_api, everything, self->cancellable, + echo_all_nullable_types_without_recursion_cb, + callback_data_new(self, response_handle)); +} + +static void send_multiple_nullable_types_without_recursion_cb( + GObject* object, GAsyncResult* result, gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiSendMultipleNullableTypesWithoutRecursionResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_send_multiple_nullable_types_without_recursion( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_send_multiple_nullable_types_without_recursion( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion_response_get_return_value( + response)); +} + +static void call_flutter_send_multiple_nullable_types_without_recursion( + gboolean* a_nullable_bool, int64_t* a_nullable_int, + const gchar* a_nullable_string, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_send_multiple_nullable_types_without_recursion( + self->flutter_core_api, a_nullable_bool, a_nullable_int, + a_nullable_string, self->cancellable, + send_multiple_nullable_types_without_recursion_cb, + callback_data_new(self, response_handle)); +} + +static void echo_bool_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr(CoreTestsPigeonTestFlutterIntegrationCoreApiEchoBoolResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_bool_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_bool_response_get_return_value( + response)); +} + +static void call_flutter_echo_bool( + gboolean a_bool, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_bool( + self->flutter_core_api, a_bool, self->cancellable, echo_bool_cb, + callback_data_new(self, response_handle)); +} + +static void echo_int_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr(CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_int_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_int( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_int( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_int_response_get_return_value( + response)); +} + +static void call_flutter_echo_int( + int64_t an_int, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_int( + self->flutter_core_api, an_int, self->cancellable, echo_int_cb, + callback_data_new(self, response_handle)); +} + +static void echo_double_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoDoubleResponse) response = + core_tests_pigeon_test_flutter_integration_core_api_echo_double_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), result, + &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_double( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_double( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_double_response_get_return_value( + response)); +} + +static void call_flutter_echo_double( + double a_double, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_double( + self->flutter_core_api, a_double, self->cancellable, echo_double_cb, + callback_data_new(self, response_handle)); +} + +static void echo_string_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringResponse) response = + core_tests_pigeon_test_flutter_integration_core_api_echo_string_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), result, + &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_string( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_string( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_string_response_get_return_value( + response)); +} + +static void call_flutter_echo_string( + const gchar* a_string, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_string( + self->flutter_core_api, a_string, self->cancellable, echo_string_cb, + callback_data_new(self, response_handle)); +} + +static void echo_uint8_list_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoUint8ListResponse) response = + core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), result, + &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_uint8_list( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_get_error_details( + response)); + return; + } + + size_t return_value_length; + const uint8_t* return_value = + core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list_response_get_return_value( + response, &return_value_length); + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_uint8_list( + data->response_handle, return_value, return_value_length); +} + +static void call_flutter_echo_uint8_list( + const uint8_t* a_list, size_t a_list_length, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_uint8_list( + self->flutter_core_api, a_list, a_list_length, self->cancellable, + echo_uint8_list_cb, callback_data_new(self, response_handle)); +} + +static void echo_list_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr(CoreTestsPigeonTestFlutterIntegrationCoreApiEchoListResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_list_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_list( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_list( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_list_response_get_return_value( + response)); +} + +static void call_flutter_echo_list( + FlValue* a_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_list( + self->flutter_core_api, a_list, self->cancellable, echo_list_cb, + callback_data_new(self, response_handle)); +} + +static void echo_enum_list_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumListResponse) response = + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), result, + &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_enum_list( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_enum_list( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list_response_get_return_value( + response)); +} + +static void call_flutter_echo_enum_list( + FlValue* enum_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_list( + self->flutter_core_api, enum_list, self->cancellable, echo_enum_list_cb, + callback_data_new(self, response_handle)); +} + +static void echo_class_list_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassListResponse) response = + core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), result, + &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_class_list( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_class_list( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_class_list_response_get_return_value( + response)); +} + +static void call_flutter_echo_class_list( + FlValue* class_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_class_list( + self->flutter_core_api, class_list, self->cancellable, echo_class_list_cb, + callback_data_new(self, response_handle)); +} + +static void echo_non_null_enum_list_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumListResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_non_null_enum_list( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_non_null_enum_list( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list_response_get_return_value( + response)); +} + +static void call_flutter_echo_non_null_enum_list( + FlValue* enum_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_list( + self->flutter_core_api, enum_list, self->cancellable, + echo_non_null_enum_list_cb, callback_data_new(self, response_handle)); +} + +static void echo_non_null_class_list_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassListResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_non_null_class_list( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_non_null_class_list( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list_response_get_return_value( + response)); +} + +static void call_flutter_echo_non_null_class_list( + FlValue* class_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_list( + self->flutter_core_api, class_list, self->cancellable, + echo_non_null_class_list_cb, callback_data_new(self, response_handle)); +} + +static void echo_map_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr(CoreTestsPigeonTestFlutterIntegrationCoreApiEchoMapResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_map_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_map( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_map( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_map_response_get_return_value( + response)); +} + +static void call_flutter_echo_map( + FlValue* map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_map( + self->flutter_core_api, map, self->cancellable, echo_map_cb, + callback_data_new(self, response_handle)); +} + +static void echo_string_map_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoStringMapResponse) response = + core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), result, + &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_string_map( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_string_map( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_string_map_response_get_return_value( + response)); +} + +static void call_flutter_echo_string_map( + FlValue* string_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_string_map( + self->flutter_core_api, string_map, self->cancellable, echo_string_map_cb, + callback_data_new(self, response_handle)); +} + +static void echo_int_map_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoIntMapResponse) response = + core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), result, + &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_int_map( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_int_map( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_int_map_response_get_return_value( + response)); +} + +static void call_flutter_echo_int_map( + FlValue* int_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_int_map( + self->flutter_core_api, int_map, self->cancellable, echo_int_map_cb, + callback_data_new(self, response_handle)); +} + +static void echo_enum_map_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumMapResponse) response = + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), result, + &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_enum_map( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_enum_map( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map_response_get_return_value( + response)); +} + +static void call_flutter_echo_enum_map( + FlValue* enum_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_map( + self->flutter_core_api, enum_map, self->cancellable, echo_enum_map_cb, + callback_data_new(self, response_handle)); +} + +static void echo_class_map_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoClassMapResponse) response = + core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), result, + &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_class_map( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_class_map( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_class_map_response_get_return_value( + response)); +} + +static void call_flutter_echo_class_map( + FlValue* class_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_class_map( + self->flutter_core_api, class_map, self->cancellable, echo_class_map_cb, + callback_data_new(self, response_handle)); +} + +static void echo_non_null_string_map_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullStringMapResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_non_null_string_map( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_non_null_string_map( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map_response_get_return_value( + response)); +} + +static void call_flutter_echo_non_null_string_map( + FlValue* string_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_string_map( + self->flutter_core_api, string_map, self->cancellable, + echo_non_null_string_map_cb, callback_data_new(self, response_handle)); +} + +static void echo_non_null_int_map_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullIntMapResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_non_null_int_map( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_non_null_int_map( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map_response_get_return_value( + response)); +} + +static void call_flutter_echo_non_null_int_map( + FlValue* int_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_int_map( + self->flutter_core_api, int_map, self->cancellable, + echo_non_null_int_map_cb, callback_data_new(self, response_handle)); +} + +static void echo_non_null_enum_map_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullEnumMapResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_non_null_enum_map( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_non_null_enum_map( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map_response_get_return_value( + response)); +} + +static void call_flutter_echo_non_null_enum_map( + FlValue* enum_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_enum_map( + self->flutter_core_api, enum_map, self->cancellable, + echo_non_null_enum_map_cb, callback_data_new(self, response_handle)); +} + +static void echo_non_null_class_map_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNonNullClassMapResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_non_null_class_map( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_non_null_class_map( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map_response_get_return_value( + response)); +} + +static void call_flutter_echo_non_null_class_map( + FlValue* class_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_non_null_class_map( + self->flutter_core_api, class_map, self->cancellable, + echo_non_null_class_map_cb, callback_data_new(self, response_handle)); +} + +static void echo_enum_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr(CoreTestsPigeonTestFlutterIntegrationCoreApiEchoEnumResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_enum( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_enum( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_enum_response_get_return_value( + response)); +} + +static void call_flutter_echo_enum( + + CoreTestsPigeonTestAnEnum an_enum, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_enum( + self->flutter_core_api, an_enum, self->cancellable, echo_enum_cb, + callback_data_new(self, response_handle)); +} + +static void echo_another_enum_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr(CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherEnumResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_another_enum( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_another_enum( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum_response_get_return_value( + response)); +} + +static void call_flutter_echo_another_enum( + + CoreTestsPigeonTestAnotherEnum another_enum, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_another_enum( + self->flutter_core_api, another_enum, self->cancellable, + echo_another_enum_cb, callback_data_new(self, response_handle)); +} + +static void echo_nullable_bool_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableBoolResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_bool( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool_response_get_return_value( + response)); +} + +static void call_flutter_echo_nullable_bool( + gboolean* a_bool, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_bool( + self->flutter_core_api, a_bool, self->cancellable, echo_nullable_bool_cb, + callback_data_new(self, response_handle)); +} + +static void echo_nullable_int_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr(CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_int( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_int( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_response_get_return_value( + response)); +} + +static void call_flutter_echo_nullable_int( + int64_t* an_int, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int( + self->flutter_core_api, an_int, self->cancellable, echo_nullable_int_cb, + callback_data_new(self, response_handle)); +} + +static void echo_nullable_double_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableDoubleResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_double( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_double( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double_response_get_return_value( + response)); +} + +static void call_flutter_echo_nullable_double( + double* a_double, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_double( + self->flutter_core_api, a_double, self->cancellable, + echo_nullable_double_cb, callback_data_new(self, response_handle)); +} + +static void echo_nullable_string_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_string( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_string( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_response_get_return_value( + response)); +} + +static void call_flutter_echo_nullable_string( + const gchar* a_string, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string( + self->flutter_core_api, a_string, self->cancellable, + echo_nullable_string_cb, callback_data_new(self, response_handle)); +} + +static void echo_nullable_uint8_list_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableUint8ListResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_uint8_list( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_get_error_details( + response)); + return; + } + + size_t return_value_length; + const uint8_t* return_value = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list_response_get_return_value( + response, &return_value_length); + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_uint8_list( + data->response_handle, return_value, return_value_length); +} + +static void call_flutter_echo_nullable_uint8_list( + const uint8_t* a_list, size_t a_list_length, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_uint8_list( + self->flutter_core_api, a_list, a_list_length, self->cancellable, + echo_nullable_uint8_list_cb, callback_data_new(self, response_handle)); +} + +static void echo_nullable_list_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableListResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_list( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_list( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list_response_get_return_value( + response)); +} + +static void call_flutter_echo_nullable_list( + FlValue* a_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_list( + self->flutter_core_api, a_list, self->cancellable, echo_nullable_list_cb, + callback_data_new(self, response_handle)); +} + +static void echo_nullable_enum_list_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumListResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_enum_list( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_enum_list( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list_response_get_return_value( + response)); +} + +static void call_flutter_echo_nullable_enum_list( + FlValue* enum_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_list( + self->flutter_core_api, enum_list, self->cancellable, + echo_nullable_enum_list_cb, callback_data_new(self, response_handle)); +} + +static void echo_nullable_class_list_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassListResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_class_list( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_class_list( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list_response_get_return_value( + response)); +} + +static void call_flutter_echo_nullable_class_list( + FlValue* class_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_list( + self->flutter_core_api, class_list, self->cancellable, + echo_nullable_class_list_cb, callback_data_new(self, response_handle)); +} + +static void echo_nullable_non_null_enum_list_cb(GObject* object, + GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumListResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_non_null_enum_list( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_non_null_enum_list( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list_response_get_return_value( + response)); +} + +static void call_flutter_echo_nullable_non_null_enum_list( + FlValue* enum_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_list( + self->flutter_core_api, enum_list, self->cancellable, + echo_nullable_non_null_enum_list_cb, + callback_data_new(self, response_handle)); +} + +static void echo_nullable_non_null_class_list_cb(GObject* object, + GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassListResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_non_null_class_list( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_non_null_class_list( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list_response_get_return_value( + response)); +} + +static void call_flutter_echo_nullable_non_null_class_list( + FlValue* class_list, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_list( + self->flutter_core_api, class_list, self->cancellable, + echo_nullable_non_null_class_list_cb, + callback_data_new(self, response_handle)); +} + +static void echo_nullable_map_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr(CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableMapResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_map( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_map( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map_response_get_return_value( + response)); +} + +static void call_flutter_echo_nullable_map( + FlValue* map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_map( + self->flutter_core_api, map, self->cancellable, echo_nullable_map_cb, + callback_data_new(self, response_handle)); +} + +static void echo_nullable_string_map_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableStringMapResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_string_map( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_string_map( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map_response_get_return_value( + response)); +} + +static void call_flutter_echo_nullable_string_map( + FlValue* string_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_string_map( + self->flutter_core_api, string_map, self->cancellable, + echo_nullable_string_map_cb, callback_data_new(self, response_handle)); +} + +static void echo_nullable_int_map_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableIntMapResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_int_map( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_int_map( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map_response_get_return_value( + response)); +} + +static void call_flutter_echo_nullable_int_map( + FlValue* int_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_int_map( + self->flutter_core_api, int_map, self->cancellable, + echo_nullable_int_map_cb, callback_data_new(self, response_handle)); +} + +static void echo_nullable_enum_map_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumMapResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_enum_map( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_enum_map( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map_response_get_return_value( + response)); +} + +static void call_flutter_echo_nullable_enum_map( + FlValue* enum_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_map( + self->flutter_core_api, enum_map, self->cancellable, + echo_nullable_enum_map_cb, callback_data_new(self, response_handle)); +} + +static void echo_nullable_class_map_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableClassMapResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_class_map( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_class_map( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map_response_get_return_value( + response)); +} + +static void call_flutter_echo_nullable_class_map( + FlValue* class_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_class_map( + self->flutter_core_api, class_map, self->cancellable, + echo_nullable_class_map_cb, callback_data_new(self, response_handle)); +} + +static void echo_nullable_non_null_string_map_cb(GObject* object, + GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullStringMapResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_non_null_string_map( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_non_null_string_map( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map_response_get_return_value( + response)); +} + +static void call_flutter_echo_nullable_non_null_string_map( + FlValue* string_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_string_map( + self->flutter_core_api, string_map, self->cancellable, + echo_nullable_non_null_string_map_cb, + callback_data_new(self, response_handle)); +} + +static void echo_nullable_non_null_int_map_cb(GObject* object, + GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullIntMapResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_non_null_int_map( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_non_null_int_map( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map_response_get_return_value( + response)); +} + +static void call_flutter_echo_nullable_non_null_int_map( + FlValue* int_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_int_map( + self->flutter_core_api, int_map, self->cancellable, + echo_nullable_non_null_int_map_cb, + callback_data_new(self, response_handle)); +} + +static void echo_nullable_non_null_enum_map_cb(GObject* object, + GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullEnumMapResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_non_null_enum_map( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_non_null_enum_map( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map_response_get_return_value( + response)); +} + +static void call_flutter_echo_nullable_non_null_enum_map( + FlValue* enum_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_enum_map( + self->flutter_core_api, enum_map, self->cancellable, + echo_nullable_non_null_enum_map_cb, + callback_data_new(self, response_handle)); +} + +static void echo_nullable_non_null_class_map_cb(GObject* object, + GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableNonNullClassMapResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_non_null_class_map( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_non_null_class_map( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map_response_get_return_value( + response)); +} + +static void call_flutter_echo_nullable_non_null_class_map( + FlValue* class_map, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_non_null_class_map( + self->flutter_core_api, class_map, self->cancellable, + echo_nullable_non_null_class_map_cb, + callback_data_new(self, response_handle)); +} + +static void echo_nullable_enum_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoNullableEnumResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_nullable_enum( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_nullable_enum( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum_response_get_return_value( + response)); +} + +static void call_flutter_echo_nullable_enum( + + CoreTestsPigeonTestAnEnum* an_enum, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_nullable_enum( + self->flutter_core_api, an_enum, self->cancellable, echo_nullable_enum_cb, + callback_data_new(self, response_handle)); +} + +static void echo_another_nullable_enum_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr( + CoreTestsPigeonTestFlutterIntegrationCoreApiEchoAnotherNullableEnumResponse) + response = + core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_INTEGRATION_CORE_API(object), + result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_another_nullable_enum( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_get_error_code( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_get_error_message( + response), + core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_echo_another_nullable_enum( + data->response_handle, + core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum_response_get_return_value( + response)); +} + +static void call_flutter_echo_another_nullable_enum( + + CoreTestsPigeonTestAnotherEnum* another_enum, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_integration_core_api_echo_another_nullable_enum( + self->flutter_core_api, another_enum, self->cancellable, + echo_another_nullable_enum_cb, callback_data_new(self, response_handle)); +} + +static void small_api_two_echo_string_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + + g_autoptr(GError) error = nullptr; + g_autoptr(CoreTestsPigeonTestFlutterSmallApiEchoStringResponse) response = + core_tests_pigeon_test_flutter_small_api_echo_string_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_SMALL_API(object), result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_small_api_echo_string( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_small_api_echo_string_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_small_api_echo_string_response_get_error_code( + response), + core_tests_pigeon_test_flutter_small_api_echo_string_response_get_error_message( + response), + core_tests_pigeon_test_flutter_small_api_echo_string_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_host_integration_core_api_respond_call_flutter_small_api_echo_string( + data->response_handle, + core_tests_pigeon_test_flutter_small_api_echo_string_response_get_return_value( + response)); +} + +static void small_api_one_echo_string_cb(GObject* object, GAsyncResult* result, + gpointer user_data) { + g_autoptr(CallbackData) data = static_cast(user_data); + TestPlugin* self = data->self; + + g_autoptr(GError) error = nullptr; + g_autoptr(CoreTestsPigeonTestFlutterSmallApiEchoStringResponse) response = + core_tests_pigeon_test_flutter_small_api_echo_string_finish( + CORE_TESTS_PIGEON_TEST_FLUTTER_SMALL_API(object), result, &error); + if (response == nullptr) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_small_api_echo_string( + data->response_handle, "Internal Error", error->message, nullptr); + return; + } + if (core_tests_pigeon_test_flutter_small_api_echo_string_response_is_error( + response)) { + core_tests_pigeon_test_host_integration_core_api_respond_error_call_flutter_echo_bool( + data->response_handle, + core_tests_pigeon_test_flutter_small_api_echo_string_response_get_error_code( + response), + core_tests_pigeon_test_flutter_small_api_echo_string_response_get_error_message( + response), + core_tests_pigeon_test_flutter_small_api_echo_string_response_get_error_details( + response)); + return; + } + + core_tests_pigeon_test_flutter_small_api_echo_string( + self->flutter_small_api_two, + core_tests_pigeon_test_flutter_small_api_echo_string_response_get_return_value( + response), + self->cancellable, small_api_two_echo_string_cb, g_steal_pointer(&data)); +} + +static void call_flutter_small_api_echo_string( + const gchar* a_string, + CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle* response_handle, + gpointer user_data) { + TestPlugin* self = TEST_PLUGIN(user_data); + + core_tests_pigeon_test_flutter_small_api_echo_string( + self->flutter_small_api_one, a_string, self->cancellable, + small_api_one_echo_string_cb, callback_data_new(self, response_handle)); +} + +CoreTestsPigeonTestUnusedClass* test_unused_class_generated() { + return core_tests_pigeon_test_unused_class_new(nullptr); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiVTable host_core_api_vtable = { + .noop = noop, + .echo_all_types = echo_all_types, + .throw_error = throw_error, + .throw_error_from_void = throw_error_from_void, + .throw_flutter_error = throw_flutter_error, + .echo_int = echo_int, + .echo_double = echo_double, + .echo_bool = echo_bool, + .echo_string = echo_string, + .echo_uint8_list = echo_uint8_list, + .echo_object = echo_object, + .echo_list = echo_list, + .echo_enum_list = echo_enum_list, + .echo_class_list = echo_class_list, + .echo_non_null_enum_list = echo_non_null_enum_list, + .echo_non_null_class_list = echo_non_null_class_list, + .echo_map = echo_map, + .echo_string_map = echo_string_map, + .echo_int_map = echo_int_map, + .echo_enum_map = echo_enum_map, + .echo_class_map = echo_class_map, + .echo_non_null_string_map = echo_non_null_string_map, + .echo_non_null_int_map = echo_non_null_int_map, + .echo_non_null_enum_map = echo_non_null_enum_map, + .echo_non_null_class_map = echo_non_null_class_map, + .echo_class_wrapper = echo_class_wrapper, + .echo_enum = echo_enum, + .echo_another_enum = echo_another_enum, + .echo_named_default_string = echo_named_default_string, + .echo_optional_default_double = echo_optional_default_double, + .echo_required_int = echo_required_int, + .echo_all_nullable_types = echo_all_nullable_types, + .echo_all_nullable_types_without_recursion = + echo_all_nullable_types_without_recursion, + .extract_nested_nullable_string = extract_nested_nullable_string, + .create_nested_nullable_string = create_nested_nullable_string, + .send_multiple_nullable_types = send_multiple_nullable_types, + .send_multiple_nullable_types_without_recursion = + send_multiple_nullable_types_without_recursion, + .echo_nullable_int = echo_nullable_int, + .echo_nullable_double = echo_nullable_double, + .echo_nullable_bool = echo_nullable_bool, + .echo_nullable_string = echo_nullable_string, + .echo_nullable_uint8_list = echo_nullable_uint8_list, + .echo_nullable_object = echo_nullable_object, + .echo_nullable_list = echo_nullable_list, + .echo_nullable_enum_list = echo_nullable_enum_list, + .echo_nullable_class_list = echo_nullable_class_list, + .echo_nullable_non_null_enum_list = echo_nullable_non_null_enum_list, + .echo_nullable_non_null_class_list = echo_nullable_non_null_class_list, + .echo_nullable_map = echo_nullable_map, + .echo_nullable_string_map = echo_nullable_string_map, + .echo_nullable_int_map = echo_nullable_int_map, + .echo_nullable_enum_map = echo_nullable_enum_map, + .echo_nullable_class_map = echo_nullable_class_map, + .echo_nullable_non_null_string_map = echo_nullable_non_null_string_map, + .echo_nullable_non_null_int_map = echo_nullable_non_null_int_map, + .echo_nullable_non_null_enum_map = echo_nullable_non_null_enum_map, + .echo_nullable_non_null_class_map = echo_nullable_non_null_class_map, + .echo_nullable_enum = echo_nullable_enum, + .echo_another_nullable_enum = echo_another_nullable_enum, + .echo_optional_nullable_int = echo_optional_nullable_int, + .echo_named_nullable_string = echo_named_nullable_string, + .noop_async = noop_async, + .echo_async_int = echo_async_int, + .echo_async_double = echo_async_double, + .echo_async_bool = echo_async_bool, + .echo_async_string = echo_async_string, + .echo_async_uint8_list = echo_async_uint8_list, + .echo_async_object = echo_async_object, + .echo_async_list = echo_async_list, + .echo_async_enum_list = echo_async_enum_list, + .echo_async_class_list = echo_async_class_list, + .echo_async_map = echo_async_map, + .echo_async_string_map = echo_async_string_map, + .echo_async_int_map = echo_async_int_map, + .echo_async_enum_map = echo_async_enum_map, + .echo_async_class_map = echo_async_class_map, + .echo_async_enum = echo_async_enum, + .echo_another_async_enum = echo_another_async_enum, + .throw_async_error = throw_async_error, + .throw_async_error_from_void = throw_async_error_from_void, + .throw_async_flutter_error = throw_async_flutter_error, + .echo_async_all_types = echo_async_all_types, + .echo_async_nullable_all_nullable_types = + echo_async_nullable_all_nullable_types, + .echo_async_nullable_all_nullable_types_without_recursion = + echo_async_nullable_all_nullable_types_without_recursion, + .echo_async_nullable_int = echo_async_nullable_int, + .echo_async_nullable_double = echo_async_nullable_double, + .echo_async_nullable_bool = echo_async_nullable_bool, + .echo_async_nullable_string = echo_async_nullable_string, + .echo_async_nullable_uint8_list = echo_async_nullable_uint8_list, + .echo_async_nullable_object = echo_async_nullable_object, + .echo_async_nullable_list = echo_async_nullable_list, + .echo_async_nullable_enum_list = echo_async_nullable_enum_list, + .echo_async_nullable_class_list = echo_async_nullable_class_list, + .echo_async_nullable_map = echo_async_nullable_map, + .echo_async_nullable_string_map = echo_async_nullable_string_map, + .echo_async_nullable_int_map = echo_async_nullable_int_map, + .echo_async_nullable_enum_map = echo_async_nullable_enum_map, + .echo_async_nullable_class_map = echo_async_nullable_class_map, + .echo_async_nullable_enum = echo_async_nullable_enum, + .echo_another_async_nullable_enum = echo_another_async_nullable_enum, + .call_flutter_noop = call_flutter_noop, + .call_flutter_throw_error = call_flutter_throw_error, + .call_flutter_throw_error_from_void = call_flutter_throw_error_from_void, + .call_flutter_echo_all_types = call_flutter_echo_all_types, + .call_flutter_echo_all_nullable_types = + call_flutter_echo_all_nullable_types, + .call_flutter_send_multiple_nullable_types = + call_flutter_send_multiple_nullable_types, + .call_flutter_echo_all_nullable_types_without_recursion = + call_flutter_echo_all_nullable_types_without_recursion, + .call_flutter_send_multiple_nullable_types_without_recursion = + call_flutter_send_multiple_nullable_types_without_recursion, + .call_flutter_echo_bool = call_flutter_echo_bool, + .call_flutter_echo_int = call_flutter_echo_int, + .call_flutter_echo_double = call_flutter_echo_double, + .call_flutter_echo_string = call_flutter_echo_string, + .call_flutter_echo_uint8_list = call_flutter_echo_uint8_list, + .call_flutter_echo_list = call_flutter_echo_list, + .call_flutter_echo_enum_list = call_flutter_echo_enum_list, + .call_flutter_echo_class_list = call_flutter_echo_class_list, + .call_flutter_echo_non_null_enum_list = + call_flutter_echo_non_null_enum_list, + .call_flutter_echo_non_null_class_list = + call_flutter_echo_non_null_class_list, + .call_flutter_echo_map = call_flutter_echo_map, + .call_flutter_echo_string_map = call_flutter_echo_string_map, + .call_flutter_echo_int_map = call_flutter_echo_int_map, + .call_flutter_echo_enum_map = call_flutter_echo_enum_map, + .call_flutter_echo_class_map = call_flutter_echo_class_map, + .call_flutter_echo_non_null_string_map = + call_flutter_echo_non_null_string_map, + .call_flutter_echo_non_null_int_map = call_flutter_echo_non_null_int_map, + .call_flutter_echo_non_null_enum_map = call_flutter_echo_non_null_enum_map, + .call_flutter_echo_non_null_class_map = + call_flutter_echo_non_null_class_map, + .call_flutter_echo_enum = call_flutter_echo_enum, + .call_flutter_echo_another_enum = call_flutter_echo_another_enum, + .call_flutter_echo_nullable_bool = call_flutter_echo_nullable_bool, + .call_flutter_echo_nullable_int = call_flutter_echo_nullable_int, + .call_flutter_echo_nullable_double = call_flutter_echo_nullable_double, + .call_flutter_echo_nullable_string = call_flutter_echo_nullable_string, + .call_flutter_echo_nullable_uint8_list = + call_flutter_echo_nullable_uint8_list, + .call_flutter_echo_nullable_list = call_flutter_echo_nullable_list, + .call_flutter_echo_nullable_enum_list = + call_flutter_echo_nullable_enum_list, + .call_flutter_echo_nullable_class_list = + call_flutter_echo_nullable_class_list, + .call_flutter_echo_nullable_non_null_enum_list = + call_flutter_echo_nullable_non_null_enum_list, + .call_flutter_echo_nullable_non_null_class_list = + call_flutter_echo_nullable_non_null_class_list, + .call_flutter_echo_nullable_map = call_flutter_echo_nullable_map, + .call_flutter_echo_nullable_string_map = + call_flutter_echo_nullable_string_map, + .call_flutter_echo_nullable_int_map = call_flutter_echo_nullable_int_map, + .call_flutter_echo_nullable_enum_map = call_flutter_echo_nullable_enum_map, + .call_flutter_echo_nullable_class_map = + call_flutter_echo_nullable_class_map, + .call_flutter_echo_nullable_non_null_string_map = + call_flutter_echo_nullable_non_null_string_map, + .call_flutter_echo_nullable_non_null_int_map = + call_flutter_echo_nullable_non_null_int_map, + .call_flutter_echo_nullable_non_null_enum_map = + call_flutter_echo_nullable_non_null_enum_map, + .call_flutter_echo_nullable_non_null_class_map = + call_flutter_echo_nullable_non_null_class_map, + .call_flutter_echo_nullable_enum = call_flutter_echo_nullable_enum, + .call_flutter_echo_another_nullable_enum = + call_flutter_echo_another_nullable_enum, + .call_flutter_small_api_echo_string = call_flutter_small_api_echo_string}; + +static void echo(const gchar* a_string, + CoreTestsPigeonTestHostSmallApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_small_api_respond_echo(response_handle, a_string); +} + +static void void_void( + CoreTestsPigeonTestHostSmallApiResponseHandle* response_handle, + gpointer user_data) { + core_tests_pigeon_test_host_small_api_respond_void_void(response_handle); +} + +static CoreTestsPigeonTestHostSmallApiVTable host_small_api_vtable = { + .echo = echo, .void_void = void_void}; + +static void test_plugin_dispose(GObject* object) { + TestPlugin* self = TEST_PLUGIN(object); + + g_cancellable_cancel(self->cancellable); + + core_tests_pigeon_test_host_integration_core_api_clear_method_handlers( + self->messenger, nullptr); + core_tests_pigeon_test_host_small_api_clear_method_handlers(self->messenger, + "suffixOne"); + core_tests_pigeon_test_host_small_api_clear_method_handlers(self->messenger, + "suffixTwo"); + + g_clear_object(&self->flutter_core_api); + g_clear_object(&self->flutter_small_api_one); + g_clear_object(&self->flutter_small_api_two); + g_clear_object(&self->cancellable); + + G_OBJECT_CLASS(test_plugin_parent_class)->dispose(object); +} + +static void test_plugin_class_init(TestPluginClass* klass) { + G_OBJECT_CLASS(klass)->dispose = test_plugin_dispose; +} + +static void test_plugin_init(TestPlugin* self) { + self->cancellable = g_cancellable_new(); +} + +static TestPlugin* test_plugin_new(FlBinaryMessenger* messenger) { + TestPlugin* self = TEST_PLUGIN(g_object_new(test_plugin_get_type(), nullptr)); + + self->messenger = messenger; + core_tests_pigeon_test_host_integration_core_api_set_method_handlers( + messenger, nullptr, &host_core_api_vtable, g_object_ref(self), + g_object_unref); + core_tests_pigeon_test_host_small_api_set_method_handlers( + messenger, "suffixOne", &host_small_api_vtable, g_object_ref(self), + g_object_unref); + core_tests_pigeon_test_host_small_api_set_method_handlers( + messenger, "suffixTwo", &host_small_api_vtable, g_object_ref(self), + g_object_unref); + self->flutter_core_api = + core_tests_pigeon_test_flutter_integration_core_api_new(messenger, + nullptr); + self->flutter_small_api_one = + core_tests_pigeon_test_flutter_small_api_new(messenger, "suffixOne"); + self->flutter_small_api_two = + core_tests_pigeon_test_flutter_small_api_new(messenger, "suffixTwo"); + + return self; +} + +void test_plugin_register_with_registrar(FlPluginRegistrar* registrar) { + g_autoptr(TestPlugin) plugin = + test_plugin_new(fl_plugin_registrar_get_messenger(registrar)); + (void)plugin; // unused variable + + g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new(); + g_autoptr(FlMethodChannel) channel = + fl_method_channel_new(fl_plugin_registrar_get_messenger(registrar), + "test_plugin", FL_METHOD_CODEC(codec)); + (void)channel; // unused variable +} diff --git a/packages/pigeon/platform_tests/test_plugin/linux/test_plugin_private.h b/packages/pigeon/platform_tests/test_plugin/linux/test_plugin_private.h new file mode 100644 index 000000000000..c4f53faa4bf6 --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/linux/test_plugin_private.h @@ -0,0 +1,14 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#include "include/test_plugin/test_plugin.h" + +// This file exposes some plugin internals for unit testing. See +// https://github.com/flutter/flutter/issues/88724 for current limitations +// in the unit-testable API. + +// Handles the getPlatformVersion method call. +FlMethodResponse* get_platform_version(); diff --git a/packages/pigeon/platform_tests/test_plugin/macos/Classes/.gitignore b/packages/pigeon/platform_tests/test_plugin/macos/Classes/.gitignore index 65eaa145c8ac..7a58c79195bb 100644 --- a/packages/pigeon/platform_tests/test_plugin/macos/Classes/.gitignore +++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/.gitignore @@ -2,4 +2,8 @@ # changes on generated files. This will need a way to avoid unnecessary churn, # such as a flag to suppress version stamp generation. *.gen.swift -!CoreTests.gen.swift \ No newline at end of file +!CoreTests.gen.swift +# Keeping this makes it easier to review changes to ProxyApi generation. +!ProxyApiTests.gen.swift +# Contains the class declartions for testing ProxyApis. +!ProxyApiTestClass.swift \ No newline at end of file diff --git a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift index 2b95f040b483..2b2001d6aa44 100644 --- a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift @@ -82,6 +82,29 @@ enum AnEnum: Int { case fourHundredTwentyTwo = 4 } +enum AnotherEnum: Int { + case justInCase = 0 +} + +/// Generated class from Pigeon that represents data sent in messages. +struct UnusedClass { + var aField: Any? = nil + + // swift-format-ignore: AlwaysUseLowerCamelCase + static func fromList(_ pigeonVar_list: [Any?]) -> UnusedClass? { + let aField: Any? = pigeonVar_list[0] + + return UnusedClass( + aField: aField + ) + } + func toList() -> [Any?] { + return [ + aField + ] + } +} + /// A class containing all supported types. /// /// Generated class from Pigeon that represents data sent in messages. @@ -95,36 +118,56 @@ struct AllTypes { var a8ByteArray: FlutterStandardTypedData var aFloatArray: FlutterStandardTypedData var anEnum: AnEnum + var anotherEnum: AnotherEnum var aString: String var anObject: Any var list: [Any?] - var stringList: [String?] - var intList: [Int64?] - var doubleList: [Double?] - var boolList: [Bool?] - var map: [AnyHashable: Any?] + var stringList: [String] + var intList: [Int64] + var doubleList: [Double] + var boolList: [Bool] + var enumList: [AnEnum] + var objectList: [Any] + var listList: [[Any?]] + var mapList: [[AnyHashable?: Any?]] + var map: [AnyHashable?: Any?] + var stringMap: [String: String] + var intMap: [Int64: Int64] + var enumMap: [AnEnum: AnEnum] + var objectMap: [AnyHashable: Any] + var listMap: [Int64: [Any?]] + var mapMap: [Int64: [AnyHashable?: Any?]] // swift-format-ignore: AlwaysUseLowerCamelCase - static func fromList(_ __pigeon_list: [Any?]) -> AllTypes? { - let aBool = __pigeon_list[0] as! Bool - let anInt = - __pigeon_list[1] is Int64 ? __pigeon_list[1] as! Int64 : Int64(__pigeon_list[1] as! Int32) - let anInt64 = - __pigeon_list[2] is Int64 ? __pigeon_list[2] as! Int64 : Int64(__pigeon_list[2] as! Int32) - let aDouble = __pigeon_list[3] as! Double - let aByteArray = __pigeon_list[4] as! FlutterStandardTypedData - let a4ByteArray = __pigeon_list[5] as! FlutterStandardTypedData - let a8ByteArray = __pigeon_list[6] as! FlutterStandardTypedData - let aFloatArray = __pigeon_list[7] as! FlutterStandardTypedData - let anEnum = __pigeon_list[8] as! AnEnum - let aString = __pigeon_list[9] as! String - let anObject = __pigeon_list[10]! - let list = __pigeon_list[11] as! [Any?] - let stringList = __pigeon_list[12] as! [String?] - let intList = __pigeon_list[13] as! [Int64?] - let doubleList = __pigeon_list[14] as! [Double?] - let boolList = __pigeon_list[15] as! [Bool?] - let map = __pigeon_list[16] as! [AnyHashable: Any?] + static func fromList(_ pigeonVar_list: [Any?]) -> AllTypes? { + let aBool = pigeonVar_list[0] as! Bool + let anInt = pigeonVar_list[1] as! Int64 + let anInt64 = pigeonVar_list[2] as! Int64 + let aDouble = pigeonVar_list[3] as! Double + let aByteArray = pigeonVar_list[4] as! FlutterStandardTypedData + let a4ByteArray = pigeonVar_list[5] as! FlutterStandardTypedData + let a8ByteArray = pigeonVar_list[6] as! FlutterStandardTypedData + let aFloatArray = pigeonVar_list[7] as! FlutterStandardTypedData + let anEnum = pigeonVar_list[8] as! AnEnum + let anotherEnum = pigeonVar_list[9] as! AnotherEnum + let aString = pigeonVar_list[10] as! String + let anObject = pigeonVar_list[11]! + let list = pigeonVar_list[12] as! [Any?] + let stringList = pigeonVar_list[13] as! [String] + let intList = pigeonVar_list[14] as! [Int64] + let doubleList = pigeonVar_list[15] as! [Double] + let boolList = pigeonVar_list[16] as! [Bool] + let enumList = pigeonVar_list[17] as! [AnEnum] + let objectList = pigeonVar_list[18] as! [Any] + let listList = pigeonVar_list[19] as! [[Any?]] + let mapList = pigeonVar_list[20] as! [[AnyHashable?: Any?]] + let map = pigeonVar_list[21] as! [AnyHashable?: Any?] + let stringMap = pigeonVar_list[22] as! [String: String] + let intMap = pigeonVar_list[23] as! [Int64: Int64] + let enumMap = pigeonVar_list[24] as? [AnEnum: AnEnum] + let objectMap = pigeonVar_list[25] as! [AnyHashable: Any] + let listMap = pigeonVar_list[26] as! [Int64: [Any?]] + let mapMap = pigeonVar_list[27] as! [Int64: [AnyHashable?: Any?]] return AllTypes( aBool: aBool, @@ -136,6 +179,7 @@ struct AllTypes { a8ByteArray: a8ByteArray, aFloatArray: aFloatArray, anEnum: anEnum, + anotherEnum: anotherEnum, aString: aString, anObject: anObject, list: list, @@ -143,7 +187,17 @@ struct AllTypes { intList: intList, doubleList: doubleList, boolList: boolList, - map: map + enumList: enumList, + objectList: objectList, + listList: listList, + mapList: mapList, + map: map, + stringMap: stringMap, + intMap: intMap, + enumMap: enumMap!, + objectMap: objectMap, + listMap: listMap, + mapMap: mapMap ) } func toList() -> [Any?] { @@ -157,6 +211,7 @@ struct AllTypes { a8ByteArray, aFloatArray, anEnum, + anotherEnum, aString, anObject, list, @@ -164,7 +219,17 @@ struct AllTypes { intList, doubleList, boolList, + enumList, + objectList, + listList, + mapList, map, + stringMap, + intMap, + enumMap, + objectMap, + listMap, + mapMap, ] } } @@ -182,10 +247,8 @@ class AllNullableTypes { aNullable4ByteArray: FlutterStandardTypedData? = nil, aNullable8ByteArray: FlutterStandardTypedData? = nil, aNullableFloatArray: FlutterStandardTypedData? = nil, - nullableNestedList: [[Bool?]?]? = nil, - nullableMapWithAnnotations: [String?: String?]? = nil, - nullableMapWithObject: [String?: Any?]? = nil, aNullableEnum: AnEnum? = nil, + anotherNullableEnum: AnotherEnum? = nil, aNullableString: String? = nil, aNullableObject: Any? = nil, allNullableTypes: AllNullableTypes? = nil, @@ -194,8 +257,19 @@ class AllNullableTypes { intList: [Int64?]? = nil, doubleList: [Double?]? = nil, boolList: [Bool?]? = nil, - nestedClassList: [AllNullableTypes?]? = nil, - map: [AnyHashable: Any?]? = nil + enumList: [AnEnum?]? = nil, + objectList: [Any?]? = nil, + listList: [[Any?]?]? = nil, + mapList: [[AnyHashable?: Any?]?]? = nil, + recursiveClassList: [AllNullableTypes?]? = nil, + map: [AnyHashable?: Any?]? = nil, + stringMap: [String?: String?]? = nil, + intMap: [Int64?: Int64?]? = nil, + enumMap: [AnEnum?: AnEnum?]? = nil, + objectMap: [AnyHashable?: Any?]? = nil, + listMap: [Int64?: [Any?]?]? = nil, + mapMap: [Int64?: [AnyHashable?: Any?]?]? = nil, + recursiveClassMap: [Int64?: AllNullableTypes?]? = nil ) { self.aNullableBool = aNullableBool self.aNullableInt = aNullableInt @@ -205,10 +279,8 @@ class AllNullableTypes { self.aNullable4ByteArray = aNullable4ByteArray self.aNullable8ByteArray = aNullable8ByteArray self.aNullableFloatArray = aNullableFloatArray - self.nullableNestedList = nullableNestedList - self.nullableMapWithAnnotations = nullableMapWithAnnotations - self.nullableMapWithObject = nullableMapWithObject self.aNullableEnum = aNullableEnum + self.anotherNullableEnum = anotherNullableEnum self.aNullableString = aNullableString self.aNullableObject = aNullableObject self.allNullableTypes = allNullableTypes @@ -217,8 +289,19 @@ class AllNullableTypes { self.intList = intList self.doubleList = doubleList self.boolList = boolList - self.nestedClassList = nestedClassList + self.enumList = enumList + self.objectList = objectList + self.listList = listList + self.mapList = mapList + self.recursiveClassList = recursiveClassList self.map = map + self.stringMap = stringMap + self.intMap = intMap + self.enumMap = enumMap + self.objectMap = objectMap + self.listMap = listMap + self.mapMap = mapMap + self.recursiveClassMap = recursiveClassMap } var aNullableBool: Bool? var aNullableInt: Int64? @@ -228,10 +311,8 @@ class AllNullableTypes { var aNullable4ByteArray: FlutterStandardTypedData? var aNullable8ByteArray: FlutterStandardTypedData? var aNullableFloatArray: FlutterStandardTypedData? - var nullableNestedList: [[Bool?]?]? - var nullableMapWithAnnotations: [String?: String?]? - var nullableMapWithObject: [String?: Any?]? var aNullableEnum: AnEnum? + var anotherNullableEnum: AnotherEnum? var aNullableString: String? var aNullableObject: Any? var allNullableTypes: AllNullableTypes? @@ -240,41 +321,53 @@ class AllNullableTypes { var intList: [Int64?]? var doubleList: [Double?]? var boolList: [Bool?]? - var nestedClassList: [AllNullableTypes?]? - var map: [AnyHashable: Any?]? + var enumList: [AnEnum?]? + var objectList: [Any?]? + var listList: [[Any?]?]? + var mapList: [[AnyHashable?: Any?]?]? + var recursiveClassList: [AllNullableTypes?]? + var map: [AnyHashable?: Any?]? + var stringMap: [String?: String?]? + var intMap: [Int64?: Int64?]? + var enumMap: [AnEnum?: AnEnum?]? + var objectMap: [AnyHashable?: Any?]? + var listMap: [Int64?: [Any?]?]? + var mapMap: [Int64?: [AnyHashable?: Any?]?]? + var recursiveClassMap: [Int64?: AllNullableTypes?]? // swift-format-ignore: AlwaysUseLowerCamelCase - static func fromList(_ __pigeon_list: [Any?]) -> AllNullableTypes? { - let aNullableBool: Bool? = nilOrValue(__pigeon_list[0]) - let aNullableInt: Int64? = - isNullish(__pigeon_list[1]) - ? nil - : (__pigeon_list[1] is Int64? - ? __pigeon_list[1] as! Int64? : Int64(__pigeon_list[1] as! Int32)) - let aNullableInt64: Int64? = - isNullish(__pigeon_list[2]) - ? nil - : (__pigeon_list[2] is Int64? - ? __pigeon_list[2] as! Int64? : Int64(__pigeon_list[2] as! Int32)) - let aNullableDouble: Double? = nilOrValue(__pigeon_list[3]) - let aNullableByteArray: FlutterStandardTypedData? = nilOrValue(__pigeon_list[4]) - let aNullable4ByteArray: FlutterStandardTypedData? = nilOrValue(__pigeon_list[5]) - let aNullable8ByteArray: FlutterStandardTypedData? = nilOrValue(__pigeon_list[6]) - let aNullableFloatArray: FlutterStandardTypedData? = nilOrValue(__pigeon_list[7]) - let nullableNestedList: [[Bool?]?]? = nilOrValue(__pigeon_list[8]) - let nullableMapWithAnnotations: [String?: String?]? = nilOrValue(__pigeon_list[9]) - let nullableMapWithObject: [String?: Any?]? = nilOrValue(__pigeon_list[10]) - let aNullableEnum: AnEnum? = nilOrValue(__pigeon_list[11]) - let aNullableString: String? = nilOrValue(__pigeon_list[12]) - let aNullableObject: Any? = __pigeon_list[13] - let allNullableTypes: AllNullableTypes? = nilOrValue(__pigeon_list[14]) - let list: [Any?]? = nilOrValue(__pigeon_list[15]) - let stringList: [String?]? = nilOrValue(__pigeon_list[16]) - let intList: [Int64?]? = nilOrValue(__pigeon_list[17]) - let doubleList: [Double?]? = nilOrValue(__pigeon_list[18]) - let boolList: [Bool?]? = nilOrValue(__pigeon_list[19]) - let nestedClassList: [AllNullableTypes?]? = nilOrValue(__pigeon_list[20]) - let map: [AnyHashable: Any?]? = nilOrValue(__pigeon_list[21]) + static func fromList(_ pigeonVar_list: [Any?]) -> AllNullableTypes? { + let aNullableBool: Bool? = nilOrValue(pigeonVar_list[0]) + let aNullableInt: Int64? = nilOrValue(pigeonVar_list[1]) + let aNullableInt64: Int64? = nilOrValue(pigeonVar_list[2]) + let aNullableDouble: Double? = nilOrValue(pigeonVar_list[3]) + let aNullableByteArray: FlutterStandardTypedData? = nilOrValue(pigeonVar_list[4]) + let aNullable4ByteArray: FlutterStandardTypedData? = nilOrValue(pigeonVar_list[5]) + let aNullable8ByteArray: FlutterStandardTypedData? = nilOrValue(pigeonVar_list[6]) + let aNullableFloatArray: FlutterStandardTypedData? = nilOrValue(pigeonVar_list[7]) + let aNullableEnum: AnEnum? = nilOrValue(pigeonVar_list[8]) + let anotherNullableEnum: AnotherEnum? = nilOrValue(pigeonVar_list[9]) + let aNullableString: String? = nilOrValue(pigeonVar_list[10]) + let aNullableObject: Any? = pigeonVar_list[11] + let allNullableTypes: AllNullableTypes? = nilOrValue(pigeonVar_list[12]) + let list: [Any?]? = nilOrValue(pigeonVar_list[13]) + let stringList: [String?]? = nilOrValue(pigeonVar_list[14]) + let intList: [Int64?]? = nilOrValue(pigeonVar_list[15]) + let doubleList: [Double?]? = nilOrValue(pigeonVar_list[16]) + let boolList: [Bool?]? = nilOrValue(pigeonVar_list[17]) + let enumList: [AnEnum?]? = nilOrValue(pigeonVar_list[18]) + let objectList: [Any?]? = nilOrValue(pigeonVar_list[19]) + let listList: [[Any?]?]? = nilOrValue(pigeonVar_list[20]) + let mapList: [[AnyHashable?: Any?]?]? = nilOrValue(pigeonVar_list[21]) + let recursiveClassList: [AllNullableTypes?]? = nilOrValue(pigeonVar_list[22]) + let map: [AnyHashable?: Any?]? = nilOrValue(pigeonVar_list[23]) + let stringMap: [String?: String?]? = nilOrValue(pigeonVar_list[24]) + let intMap: [Int64?: Int64?]? = nilOrValue(pigeonVar_list[25]) + let enumMap: [AnEnum?: AnEnum?]? = pigeonVar_list[26] as? [AnEnum?: AnEnum?] + let objectMap: [AnyHashable?: Any?]? = nilOrValue(pigeonVar_list[27]) + let listMap: [Int64?: [Any?]?]? = nilOrValue(pigeonVar_list[28]) + let mapMap: [Int64?: [AnyHashable?: Any?]?]? = nilOrValue(pigeonVar_list[29]) + let recursiveClassMap: [Int64?: AllNullableTypes?]? = nilOrValue(pigeonVar_list[30]) return AllNullableTypes( aNullableBool: aNullableBool, @@ -285,10 +378,8 @@ class AllNullableTypes { aNullable4ByteArray: aNullable4ByteArray, aNullable8ByteArray: aNullable8ByteArray, aNullableFloatArray: aNullableFloatArray, - nullableNestedList: nullableNestedList, - nullableMapWithAnnotations: nullableMapWithAnnotations, - nullableMapWithObject: nullableMapWithObject, aNullableEnum: aNullableEnum, + anotherNullableEnum: anotherNullableEnum, aNullableString: aNullableString, aNullableObject: aNullableObject, allNullableTypes: allNullableTypes, @@ -297,8 +388,19 @@ class AllNullableTypes { intList: intList, doubleList: doubleList, boolList: boolList, - nestedClassList: nestedClassList, - map: map + enumList: enumList, + objectList: objectList, + listList: listList, + mapList: mapList, + recursiveClassList: recursiveClassList, + map: map, + stringMap: stringMap, + intMap: intMap, + enumMap: enumMap, + objectMap: objectMap, + listMap: listMap, + mapMap: mapMap, + recursiveClassMap: recursiveClassMap ) } func toList() -> [Any?] { @@ -311,10 +413,8 @@ class AllNullableTypes { aNullable4ByteArray, aNullable8ByteArray, aNullableFloatArray, - nullableNestedList, - nullableMapWithAnnotations, - nullableMapWithObject, aNullableEnum, + anotherNullableEnum, aNullableString, aNullableObject, allNullableTypes, @@ -323,8 +423,19 @@ class AllNullableTypes { intList, doubleList, boolList, - nestedClassList, + enumList, + objectList, + listList, + mapList, + recursiveClassList, map, + stringMap, + intMap, + enumMap, + objectMap, + listMap, + mapMap, + recursiveClassMap, ] } } @@ -343,10 +454,8 @@ struct AllNullableTypesWithoutRecursion { var aNullable4ByteArray: FlutterStandardTypedData? = nil var aNullable8ByteArray: FlutterStandardTypedData? = nil var aNullableFloatArray: FlutterStandardTypedData? = nil - var nullableNestedList: [[Bool?]?]? = nil - var nullableMapWithAnnotations: [String?: String?]? = nil - var nullableMapWithObject: [String?: Any?]? = nil var aNullableEnum: AnEnum? = nil + var anotherNullableEnum: AnotherEnum? = nil var aNullableString: String? = nil var aNullableObject: Any? = nil var list: [Any?]? = nil @@ -354,38 +463,48 @@ struct AllNullableTypesWithoutRecursion { var intList: [Int64?]? = nil var doubleList: [Double?]? = nil var boolList: [Bool?]? = nil - var map: [AnyHashable: Any?]? = nil + var enumList: [AnEnum?]? = nil + var objectList: [Any?]? = nil + var listList: [[Any?]?]? = nil + var mapList: [[AnyHashable?: Any?]?]? = nil + var map: [AnyHashable?: Any?]? = nil + var stringMap: [String?: String?]? = nil + var intMap: [Int64?: Int64?]? = nil + var enumMap: [AnEnum?: AnEnum?]? = nil + var objectMap: [AnyHashable?: Any?]? = nil + var listMap: [Int64?: [Any?]?]? = nil + var mapMap: [Int64?: [AnyHashable?: Any?]?]? = nil // swift-format-ignore: AlwaysUseLowerCamelCase - static func fromList(_ __pigeon_list: [Any?]) -> AllNullableTypesWithoutRecursion? { - let aNullableBool: Bool? = nilOrValue(__pigeon_list[0]) - let aNullableInt: Int64? = - isNullish(__pigeon_list[1]) - ? nil - : (__pigeon_list[1] is Int64? - ? __pigeon_list[1] as! Int64? : Int64(__pigeon_list[1] as! Int32)) - let aNullableInt64: Int64? = - isNullish(__pigeon_list[2]) - ? nil - : (__pigeon_list[2] is Int64? - ? __pigeon_list[2] as! Int64? : Int64(__pigeon_list[2] as! Int32)) - let aNullableDouble: Double? = nilOrValue(__pigeon_list[3]) - let aNullableByteArray: FlutterStandardTypedData? = nilOrValue(__pigeon_list[4]) - let aNullable4ByteArray: FlutterStandardTypedData? = nilOrValue(__pigeon_list[5]) - let aNullable8ByteArray: FlutterStandardTypedData? = nilOrValue(__pigeon_list[6]) - let aNullableFloatArray: FlutterStandardTypedData? = nilOrValue(__pigeon_list[7]) - let nullableNestedList: [[Bool?]?]? = nilOrValue(__pigeon_list[8]) - let nullableMapWithAnnotations: [String?: String?]? = nilOrValue(__pigeon_list[9]) - let nullableMapWithObject: [String?: Any?]? = nilOrValue(__pigeon_list[10]) - let aNullableEnum: AnEnum? = nilOrValue(__pigeon_list[11]) - let aNullableString: String? = nilOrValue(__pigeon_list[12]) - let aNullableObject: Any? = __pigeon_list[13] - let list: [Any?]? = nilOrValue(__pigeon_list[14]) - let stringList: [String?]? = nilOrValue(__pigeon_list[15]) - let intList: [Int64?]? = nilOrValue(__pigeon_list[16]) - let doubleList: [Double?]? = nilOrValue(__pigeon_list[17]) - let boolList: [Bool?]? = nilOrValue(__pigeon_list[18]) - let map: [AnyHashable: Any?]? = nilOrValue(__pigeon_list[19]) + static func fromList(_ pigeonVar_list: [Any?]) -> AllNullableTypesWithoutRecursion? { + let aNullableBool: Bool? = nilOrValue(pigeonVar_list[0]) + let aNullableInt: Int64? = nilOrValue(pigeonVar_list[1]) + let aNullableInt64: Int64? = nilOrValue(pigeonVar_list[2]) + let aNullableDouble: Double? = nilOrValue(pigeonVar_list[3]) + let aNullableByteArray: FlutterStandardTypedData? = nilOrValue(pigeonVar_list[4]) + let aNullable4ByteArray: FlutterStandardTypedData? = nilOrValue(pigeonVar_list[5]) + let aNullable8ByteArray: FlutterStandardTypedData? = nilOrValue(pigeonVar_list[6]) + let aNullableFloatArray: FlutterStandardTypedData? = nilOrValue(pigeonVar_list[7]) + let aNullableEnum: AnEnum? = nilOrValue(pigeonVar_list[8]) + let anotherNullableEnum: AnotherEnum? = nilOrValue(pigeonVar_list[9]) + let aNullableString: String? = nilOrValue(pigeonVar_list[10]) + let aNullableObject: Any? = pigeonVar_list[11] + let list: [Any?]? = nilOrValue(pigeonVar_list[12]) + let stringList: [String?]? = nilOrValue(pigeonVar_list[13]) + let intList: [Int64?]? = nilOrValue(pigeonVar_list[14]) + let doubleList: [Double?]? = nilOrValue(pigeonVar_list[15]) + let boolList: [Bool?]? = nilOrValue(pigeonVar_list[16]) + let enumList: [AnEnum?]? = nilOrValue(pigeonVar_list[17]) + let objectList: [Any?]? = nilOrValue(pigeonVar_list[18]) + let listList: [[Any?]?]? = nilOrValue(pigeonVar_list[19]) + let mapList: [[AnyHashable?: Any?]?]? = nilOrValue(pigeonVar_list[20]) + let map: [AnyHashable?: Any?]? = nilOrValue(pigeonVar_list[21]) + let stringMap: [String?: String?]? = nilOrValue(pigeonVar_list[22]) + let intMap: [Int64?: Int64?]? = nilOrValue(pigeonVar_list[23]) + let enumMap: [AnEnum?: AnEnum?]? = pigeonVar_list[24] as? [AnEnum?: AnEnum?] + let objectMap: [AnyHashable?: Any?]? = nilOrValue(pigeonVar_list[25]) + let listMap: [Int64?: [Any?]?]? = nilOrValue(pigeonVar_list[26]) + let mapMap: [Int64?: [AnyHashable?: Any?]?]? = nilOrValue(pigeonVar_list[27]) return AllNullableTypesWithoutRecursion( aNullableBool: aNullableBool, @@ -396,10 +515,8 @@ struct AllNullableTypesWithoutRecursion { aNullable4ByteArray: aNullable4ByteArray, aNullable8ByteArray: aNullable8ByteArray, aNullableFloatArray: aNullableFloatArray, - nullableNestedList: nullableNestedList, - nullableMapWithAnnotations: nullableMapWithAnnotations, - nullableMapWithObject: nullableMapWithObject, aNullableEnum: aNullableEnum, + anotherNullableEnum: anotherNullableEnum, aNullableString: aNullableString, aNullableObject: aNullableObject, list: list, @@ -407,7 +524,17 @@ struct AllNullableTypesWithoutRecursion { intList: intList, doubleList: doubleList, boolList: boolList, - map: map + enumList: enumList, + objectList: objectList, + listList: listList, + mapList: mapList, + map: map, + stringMap: stringMap, + intMap: intMap, + enumMap: enumMap, + objectMap: objectMap, + listMap: listMap, + mapMap: mapMap ) } func toList() -> [Any?] { @@ -420,10 +547,8 @@ struct AllNullableTypesWithoutRecursion { aNullable4ByteArray, aNullable8ByteArray, aNullableFloatArray, - nullableNestedList, - nullableMapWithAnnotations, - nullableMapWithObject, aNullableEnum, + anotherNullableEnum, aNullableString, aNullableObject, list, @@ -431,7 +556,17 @@ struct AllNullableTypesWithoutRecursion { intList, doubleList, boolList, + enumList, + objectList, + listList, + mapList, map, + stringMap, + intMap, + enumMap, + objectMap, + listMap, + mapMap, ] } } @@ -447,18 +582,31 @@ struct AllClassesWrapper { var allNullableTypes: AllNullableTypes var allNullableTypesWithoutRecursion: AllNullableTypesWithoutRecursion? = nil var allTypes: AllTypes? = nil + var classList: [AllTypes?] + var nullableClassList: [AllNullableTypesWithoutRecursion?]? = nil + var classMap: [Int64?: AllTypes?] + var nullableClassMap: [Int64?: AllNullableTypesWithoutRecursion?]? = nil // swift-format-ignore: AlwaysUseLowerCamelCase - static func fromList(_ __pigeon_list: [Any?]) -> AllClassesWrapper? { - let allNullableTypes = __pigeon_list[0] as! AllNullableTypes + static func fromList(_ pigeonVar_list: [Any?]) -> AllClassesWrapper? { + let allNullableTypes = pigeonVar_list[0] as! AllNullableTypes let allNullableTypesWithoutRecursion: AllNullableTypesWithoutRecursion? = nilOrValue( - __pigeon_list[1]) - let allTypes: AllTypes? = nilOrValue(__pigeon_list[2]) + pigeonVar_list[1]) + let allTypes: AllTypes? = nilOrValue(pigeonVar_list[2]) + let classList = pigeonVar_list[3] as! [AllTypes?] + let nullableClassList: [AllNullableTypesWithoutRecursion?]? = nilOrValue(pigeonVar_list[4]) + let classMap = pigeonVar_list[5] as! [Int64?: AllTypes?] + let nullableClassMap: [Int64?: AllNullableTypesWithoutRecursion?]? = nilOrValue( + pigeonVar_list[6]) return AllClassesWrapper( allNullableTypes: allNullableTypes, allNullableTypesWithoutRecursion: allNullableTypesWithoutRecursion, - allTypes: allTypes + allTypes: allTypes, + classList: classList, + nullableClassList: nullableClassList, + classMap: classMap, + nullableClassMap: nullableClassMap ) } func toList() -> [Any?] { @@ -466,6 +614,10 @@ struct AllClassesWrapper { allNullableTypes, allNullableTypesWithoutRecursion, allTypes, + classList, + nullableClassList, + classMap, + nullableClassMap, ] } } @@ -477,8 +629,8 @@ struct TestMessage { var testList: [Any?]? = nil // swift-format-ignore: AlwaysUseLowerCamelCase - static func fromList(_ __pigeon_list: [Any?]) -> TestMessage? { - let testList: [Any?]? = nilOrValue(__pigeon_list[0]) + static func fromList(_ pigeonVar_list: [Any?]) -> TestMessage? { + let testList: [Any?]? = nilOrValue(pigeonVar_list[0]) return TestMessage( testList: testList @@ -490,26 +642,34 @@ struct TestMessage { ] } } + private class CoreTestsPigeonCodecReader: FlutterStandardReader { override func readValue(ofType type: UInt8) -> Any? { switch type { case 129: - return AllTypes.fromList(self.readValue() as! [Any?]) + let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?) + if let enumResultAsInt = enumResultAsInt { + return AnEnum(rawValue: enumResultAsInt) + } + return nil case 130: - return AllNullableTypes.fromList(self.readValue() as! [Any?]) + let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?) + if let enumResultAsInt = enumResultAsInt { + return AnotherEnum(rawValue: enumResultAsInt) + } + return nil case 131: - return AllNullableTypesWithoutRecursion.fromList(self.readValue() as! [Any?]) + return UnusedClass.fromList(self.readValue() as! [Any?]) case 132: - return AllClassesWrapper.fromList(self.readValue() as! [Any?]) + return AllTypes.fromList(self.readValue() as! [Any?]) case 133: - return TestMessage.fromList(self.readValue() as! [Any?]) + return AllNullableTypes.fromList(self.readValue() as! [Any?]) case 134: - var enumResult: AnEnum? = nil - let enumResultAsInt: Int? = nilOrValue(self.readValue() as? Int) - if let enumResultAsInt = enumResultAsInt { - enumResult = AnEnum(rawValue: enumResultAsInt) - } - return enumResult + return AllNullableTypesWithoutRecursion.fromList(self.readValue() as! [Any?]) + case 135: + return AllClassesWrapper.fromList(self.readValue() as! [Any?]) + case 136: + return TestMessage.fromList(self.readValue() as! [Any?]) default: return super.readValue(ofType: type) } @@ -518,24 +678,30 @@ private class CoreTestsPigeonCodecReader: FlutterStandardReader { private class CoreTestsPigeonCodecWriter: FlutterStandardWriter { override func writeValue(_ value: Any) { - if let value = value as? AllTypes { + if let value = value as? AnEnum { super.writeByte(129) + super.writeValue(value.rawValue) + } else if let value = value as? AnotherEnum { + super.writeByte(130) + super.writeValue(value.rawValue) + } else if let value = value as? UnusedClass { + super.writeByte(131) + super.writeValue(value.toList()) + } else if let value = value as? AllTypes { + super.writeByte(132) super.writeValue(value.toList()) } else if let value = value as? AllNullableTypes { - super.writeByte(130) + super.writeByte(133) super.writeValue(value.toList()) } else if let value = value as? AllNullableTypesWithoutRecursion { - super.writeByte(131) + super.writeByte(134) super.writeValue(value.toList()) } else if let value = value as? AllClassesWrapper { - super.writeByte(132) + super.writeByte(135) super.writeValue(value.toList()) } else if let value = value as? TestMessage { - super.writeByte(133) + super.writeByte(136) super.writeValue(value.toList()) - } else if let value = value as? AnEnum { - super.writeByte(134) - super.writeValue(value.rawValue) } else { super.writeValue(value) } @@ -586,12 +752,38 @@ protocol HostIntegrationCoreApi { func echo(_ anObject: Any) throws -> Any /// Returns the passed list, to test serialization and deserialization. func echo(_ list: [Any?]) throws -> [Any?] + /// Returns the passed list, to test serialization and deserialization. + func echo(enumList: [AnEnum?]) throws -> [AnEnum?] + /// Returns the passed list, to test serialization and deserialization. + func echo(classList: [AllNullableTypes?]) throws -> [AllNullableTypes?] + /// Returns the passed list, to test serialization and deserialization. + func echoNonNull(enumList: [AnEnum]) throws -> [AnEnum] + /// Returns the passed list, to test serialization and deserialization. + func echoNonNull(classList: [AllNullableTypes]) throws -> [AllNullableTypes] + /// Returns the passed map, to test serialization and deserialization. + func echo(_ map: [AnyHashable?: Any?]) throws -> [AnyHashable?: Any?] + /// Returns the passed map, to test serialization and deserialization. + func echo(stringMap: [String?: String?]) throws -> [String?: String?] + /// Returns the passed map, to test serialization and deserialization. + func echo(intMap: [Int64?: Int64?]) throws -> [Int64?: Int64?] + /// Returns the passed map, to test serialization and deserialization. + func echo(enumMap: [AnEnum?: AnEnum?]) throws -> [AnEnum?: AnEnum?] + /// Returns the passed map, to test serialization and deserialization. + func echo(classMap: [Int64?: AllNullableTypes?]) throws -> [Int64?: AllNullableTypes?] + /// Returns the passed map, to test serialization and deserialization. + func echoNonNull(stringMap: [String: String]) throws -> [String: String] + /// Returns the passed map, to test serialization and deserialization. + func echoNonNull(intMap: [Int64: Int64]) throws -> [Int64: Int64] /// Returns the passed map, to test serialization and deserialization. - func echo(_ aMap: [String?: Any?]) throws -> [String?: Any?] - /// Returns the passed map to test nested class serialization and deserialization. + func echoNonNull(enumMap: [AnEnum: AnEnum]) throws -> [AnEnum: AnEnum] + /// Returns the passed map, to test serialization and deserialization. + func echoNonNull(classMap: [Int64: AllNullableTypes]) throws -> [Int64: AllNullableTypes] + /// Returns the passed class to test nested class serialization and deserialization. func echo(_ wrapper: AllClassesWrapper) throws -> AllClassesWrapper /// Returns the passed enum to test serialization and deserialization. func echo(_ anEnum: AnEnum) throws -> AnEnum + /// Returns the passed enum to test serialization and deserialization. + func echo(_ anotherEnum: AnotherEnum) throws -> AnotherEnum /// Returns the default string. func echoNamedDefault(_ aString: String) throws -> String /// Returns passed in double. @@ -631,9 +823,35 @@ protocol HostIntegrationCoreApi { func echo(_ aNullableObject: Any?) throws -> Any? /// Returns the passed list, to test serialization and deserialization. func echoNullable(_ aNullableList: [Any?]?) throws -> [Any?]? + /// Returns the passed list, to test serialization and deserialization. + func echoNullable(enumList: [AnEnum?]?) throws -> [AnEnum?]? + /// Returns the passed list, to test serialization and deserialization. + func echoNullable(classList: [AllNullableTypes?]?) throws -> [AllNullableTypes?]? + /// Returns the passed list, to test serialization and deserialization. + func echoNullableNonNull(enumList: [AnEnum]?) throws -> [AnEnum]? + /// Returns the passed list, to test serialization and deserialization. + func echoNullableNonNull(classList: [AllNullableTypes]?) throws -> [AllNullableTypes]? + /// Returns the passed map, to test serialization and deserialization. + func echoNullable(_ map: [AnyHashable?: Any?]?) throws -> [AnyHashable?: Any?]? + /// Returns the passed map, to test serialization and deserialization. + func echoNullable(stringMap: [String?: String?]?) throws -> [String?: String?]? /// Returns the passed map, to test serialization and deserialization. - func echoNullable(_ aNullableMap: [String?: Any?]?) throws -> [String?: Any?]? + func echoNullable(intMap: [Int64?: Int64?]?) throws -> [Int64?: Int64?]? + /// Returns the passed map, to test serialization and deserialization. + func echoNullable(enumMap: [AnEnum?: AnEnum?]?) throws -> [AnEnum?: AnEnum?]? + /// Returns the passed map, to test serialization and deserialization. + func echoNullable(classMap: [Int64?: AllNullableTypes?]?) throws -> [Int64?: AllNullableTypes?]? + /// Returns the passed map, to test serialization and deserialization. + func echoNullableNonNull(stringMap: [String: String]?) throws -> [String: String]? + /// Returns the passed map, to test serialization and deserialization. + func echoNullableNonNull(intMap: [Int64: Int64]?) throws -> [Int64: Int64]? + /// Returns the passed map, to test serialization and deserialization. + func echoNullableNonNull(enumMap: [AnEnum: AnEnum]?) throws -> [AnEnum: AnEnum]? + /// Returns the passed map, to test serialization and deserialization. + func echoNullableNonNull(classMap: [Int64: AllNullableTypes]?) throws -> [Int64: + AllNullableTypes]? func echoNullable(_ anEnum: AnEnum?) throws -> AnEnum? + func echoNullable(_ anotherEnum: AnotherEnum?) throws -> AnotherEnum? /// Returns passed in int. func echoOptional(_ aNullableInt: Int64?) throws -> Int64? /// Returns the passed in string. @@ -657,11 +875,35 @@ protocol HostIntegrationCoreApi { func echoAsync(_ anObject: Any, completion: @escaping (Result) -> Void) /// Returns the passed list, to test asynchronous serialization and deserialization. func echoAsync(_ list: [Any?], completion: @escaping (Result<[Any?], Error>) -> Void) + /// Returns the passed list, to test asynchronous serialization and deserialization. + func echoAsync(enumList: [AnEnum?], completion: @escaping (Result<[AnEnum?], Error>) -> Void) + /// Returns the passed list, to test asynchronous serialization and deserialization. + func echoAsync( + classList: [AllNullableTypes?], + completion: @escaping (Result<[AllNullableTypes?], Error>) -> Void) + /// Returns the passed map, to test asynchronous serialization and deserialization. + func echoAsync( + _ map: [AnyHashable?: Any?], completion: @escaping (Result<[AnyHashable?: Any?], Error>) -> Void + ) + /// Returns the passed map, to test asynchronous serialization and deserialization. + func echoAsync( + stringMap: [String?: String?], completion: @escaping (Result<[String?: String?], Error>) -> Void + ) + /// Returns the passed map, to test asynchronous serialization and deserialization. + func echoAsync( + intMap: [Int64?: Int64?], completion: @escaping (Result<[Int64?: Int64?], Error>) -> Void) + /// Returns the passed map, to test asynchronous serialization and deserialization. + func echoAsync( + enumMap: [AnEnum?: AnEnum?], completion: @escaping (Result<[AnEnum?: AnEnum?], Error>) -> Void) /// Returns the passed map, to test asynchronous serialization and deserialization. func echoAsync( - _ aMap: [String?: Any?], completion: @escaping (Result<[String?: Any?], Error>) -> Void) + classMap: [Int64?: AllNullableTypes?], + completion: @escaping (Result<[Int64?: AllNullableTypes?], Error>) -> Void) /// Returns the passed enum, to test asynchronous serialization and deserialization. func echoAsync(_ anEnum: AnEnum, completion: @escaping (Result) -> Void) + /// Returns the passed enum, to test asynchronous serialization and deserialization. + func echoAsync( + _ anotherEnum: AnotherEnum, completion: @escaping (Result) -> Void) /// Responds with an error from an async function returning a value. func throwAsyncError(completion: @escaping (Result) -> Void) /// Responds with an error from an async void function. @@ -694,11 +936,37 @@ protocol HostIntegrationCoreApi { func echoAsyncNullable(_ anObject: Any?, completion: @escaping (Result) -> Void) /// Returns the passed list, to test asynchronous serialization and deserialization. func echoAsyncNullable(_ list: [Any?]?, completion: @escaping (Result<[Any?]?, Error>) -> Void) + /// Returns the passed list, to test asynchronous serialization and deserialization. + func echoAsyncNullable( + enumList: [AnEnum?]?, completion: @escaping (Result<[AnEnum?]?, Error>) -> Void) + /// Returns the passed list, to test asynchronous serialization and deserialization. + func echoAsyncNullable( + classList: [AllNullableTypes?]?, + completion: @escaping (Result<[AllNullableTypes?]?, Error>) -> Void) + /// Returns the passed map, to test asynchronous serialization and deserialization. + func echoAsyncNullable( + _ map: [AnyHashable?: Any?]?, + completion: @escaping (Result<[AnyHashable?: Any?]?, Error>) -> Void) + /// Returns the passed map, to test asynchronous serialization and deserialization. + func echoAsyncNullable( + stringMap: [String?: String?]?, + completion: @escaping (Result<[String?: String?]?, Error>) -> Void) + /// Returns the passed map, to test asynchronous serialization and deserialization. + func echoAsyncNullable( + intMap: [Int64?: Int64?]?, completion: @escaping (Result<[Int64?: Int64?]?, Error>) -> Void) + /// Returns the passed map, to test asynchronous serialization and deserialization. + func echoAsyncNullable( + enumMap: [AnEnum?: AnEnum?]?, completion: @escaping (Result<[AnEnum?: AnEnum?]?, Error>) -> Void + ) /// Returns the passed map, to test asynchronous serialization and deserialization. func echoAsyncNullable( - _ aMap: [String?: Any?]?, completion: @escaping (Result<[String?: Any?]?, Error>) -> Void) + classMap: [Int64?: AllNullableTypes?]?, + completion: @escaping (Result<[Int64?: AllNullableTypes?]?, Error>) -> Void) /// Returns the passed enum, to test asynchronous serialization and deserialization. func echoAsyncNullable(_ anEnum: AnEnum?, completion: @escaping (Result) -> Void) + /// Returns the passed enum, to test asynchronous serialization and deserialization. + func echoAsyncNullable( + _ anotherEnum: AnotherEnum?, completion: @escaping (Result) -> Void) func callFlutterNoop(completion: @escaping (Result) -> Void) func callFlutterThrowError(completion: @escaping (Result) -> Void) func callFlutterThrowErrorFromVoid(completion: @escaping (Result) -> Void) @@ -725,8 +993,40 @@ protocol HostIntegrationCoreApi { completion: @escaping (Result) -> Void) func callFlutterEcho(_ list: [Any?], completion: @escaping (Result<[Any?], Error>) -> Void) func callFlutterEcho( - _ aMap: [String?: Any?], completion: @escaping (Result<[String?: Any?], Error>) -> Void) + enumList: [AnEnum?], completion: @escaping (Result<[AnEnum?], Error>) -> Void) + func callFlutterEcho( + classList: [AllNullableTypes?], + completion: @escaping (Result<[AllNullableTypes?], Error>) -> Void) + func callFlutterEchoNonNull( + enumList: [AnEnum], completion: @escaping (Result<[AnEnum], Error>) -> Void) + func callFlutterEchoNonNull( + classList: [AllNullableTypes], completion: @escaping (Result<[AllNullableTypes], Error>) -> Void + ) + func callFlutterEcho( + _ map: [AnyHashable?: Any?], completion: @escaping (Result<[AnyHashable?: Any?], Error>) -> Void + ) + func callFlutterEcho( + stringMap: [String?: String?], completion: @escaping (Result<[String?: String?], Error>) -> Void + ) + func callFlutterEcho( + intMap: [Int64?: Int64?], completion: @escaping (Result<[Int64?: Int64?], Error>) -> Void) + func callFlutterEcho( + enumMap: [AnEnum?: AnEnum?], completion: @escaping (Result<[AnEnum?: AnEnum?], Error>) -> Void) + func callFlutterEcho( + classMap: [Int64?: AllNullableTypes?], + completion: @escaping (Result<[Int64?: AllNullableTypes?], Error>) -> Void) + func callFlutterEchoNonNull( + stringMap: [String: String], completion: @escaping (Result<[String: String], Error>) -> Void) + func callFlutterEchoNonNull( + intMap: [Int64: Int64], completion: @escaping (Result<[Int64: Int64], Error>) -> Void) + func callFlutterEchoNonNull( + enumMap: [AnEnum: AnEnum], completion: @escaping (Result<[AnEnum: AnEnum], Error>) -> Void) + func callFlutterEchoNonNull( + classMap: [Int64: AllNullableTypes], + completion: @escaping (Result<[Int64: AllNullableTypes], Error>) -> Void) func callFlutterEcho(_ anEnum: AnEnum, completion: @escaping (Result) -> Void) + func callFlutterEcho( + _ anotherEnum: AnotherEnum, completion: @escaping (Result) -> Void) func callFlutterEchoNullable(_ aBool: Bool?, completion: @escaping (Result) -> Void) func callFlutterEchoNullable( _ anInt: Int64?, completion: @escaping (Result) -> Void) @@ -740,9 +1040,42 @@ protocol HostIntegrationCoreApi { func callFlutterEchoNullable( _ list: [Any?]?, completion: @escaping (Result<[Any?]?, Error>) -> Void) func callFlutterEchoNullable( - _ aMap: [String?: Any?]?, completion: @escaping (Result<[String?: Any?]?, Error>) -> Void) - func callFlutterNullableEcho( + enumList: [AnEnum?]?, completion: @escaping (Result<[AnEnum?]?, Error>) -> Void) + func callFlutterEchoNullable( + classList: [AllNullableTypes?]?, + completion: @escaping (Result<[AllNullableTypes?]?, Error>) -> Void) + func callFlutterEchoNullableNonNull( + enumList: [AnEnum]?, completion: @escaping (Result<[AnEnum]?, Error>) -> Void) + func callFlutterEchoNullableNonNull( + classList: [AllNullableTypes]?, + completion: @escaping (Result<[AllNullableTypes]?, Error>) -> Void) + func callFlutterEchoNullable( + _ map: [AnyHashable?: Any?]?, + completion: @escaping (Result<[AnyHashable?: Any?]?, Error>) -> Void) + func callFlutterEchoNullable( + stringMap: [String?: String?]?, + completion: @escaping (Result<[String?: String?]?, Error>) -> Void) + func callFlutterEchoNullable( + intMap: [Int64?: Int64?]?, completion: @escaping (Result<[Int64?: Int64?]?, Error>) -> Void) + func callFlutterEchoNullable( + enumMap: [AnEnum?: AnEnum?]?, completion: @escaping (Result<[AnEnum?: AnEnum?]?, Error>) -> Void + ) + func callFlutterEchoNullable( + classMap: [Int64?: AllNullableTypes?]?, + completion: @escaping (Result<[Int64?: AllNullableTypes?]?, Error>) -> Void) + func callFlutterEchoNullableNonNull( + stringMap: [String: String]?, completion: @escaping (Result<[String: String]?, Error>) -> Void) + func callFlutterEchoNullableNonNull( + intMap: [Int64: Int64]?, completion: @escaping (Result<[Int64: Int64]?, Error>) -> Void) + func callFlutterEchoNullableNonNull( + enumMap: [AnEnum: AnEnum]?, completion: @escaping (Result<[AnEnum: AnEnum]?, Error>) -> Void) + func callFlutterEchoNullableNonNull( + classMap: [Int64: AllNullableTypes]?, + completion: @escaping (Result<[Int64: AllNullableTypes]?, Error>) -> Void) + func callFlutterEchoNullable( _ anEnum: AnEnum?, completion: @escaping (Result) -> Void) + func callFlutterEchoNullable( + _ anotherEnum: AnotherEnum?, completion: @escaping (Result) -> Void) func callFlutterSmallApiEcho( _ aString: String, completion: @escaping (Result) -> Void) } @@ -852,7 +1185,7 @@ class HostIntegrationCoreApiSetup { if let api = api { echoIntChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anIntArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + let anIntArg = args[0] as! Int64 do { let result = try api.echo(anIntArg) reply(wrapResult(result)) @@ -977,985 +1310,952 @@ class HostIntegrationCoreApiSetup { } else { echoListChannel.setMessageHandler(nil) } - /// Returns the passed map, to test serialization and deserialization. - let echoMapChannel = FlutterBasicMessageChannel( + /// Returns the passed list, to test serialization and deserialization. + let echoEnumListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoMap\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoEnumList\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoMapChannel.setMessageHandler { message, reply in + echoEnumListChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aMapArg = args[0] as! [String?: Any?] + let enumListArg = args[0] as! [AnEnum?] do { - let result = try api.echo(aMapArg) + let result = try api.echo(enumList: enumListArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoMapChannel.setMessageHandler(nil) + echoEnumListChannel.setMessageHandler(nil) } - /// Returns the passed map to test nested class serialization and deserialization. - let echoClassWrapperChannel = FlutterBasicMessageChannel( + /// Returns the passed list, to test serialization and deserialization. + let echoClassListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoClassWrapper\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoClassList\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoClassWrapperChannel.setMessageHandler { message, reply in + echoClassListChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let wrapperArg = args[0] as! AllClassesWrapper + let classListArg = args[0] as! [AllNullableTypes?] do { - let result = try api.echo(wrapperArg) + let result = try api.echo(classList: classListArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoClassWrapperChannel.setMessageHandler(nil) + echoClassListChannel.setMessageHandler(nil) } - /// Returns the passed enum to test serialization and deserialization. - let echoEnumChannel = FlutterBasicMessageChannel( + /// Returns the passed list, to test serialization and deserialization. + let echoNonNullEnumListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoEnum\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullEnumList\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoEnumChannel.setMessageHandler { message, reply in + echoNonNullEnumListChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anEnumArg = args[0] as! AnEnum + let enumListArg = args[0] as! [AnEnum] do { - let result = try api.echo(anEnumArg) + let result = try api.echoNonNull(enumList: enumListArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoEnumChannel.setMessageHandler(nil) + echoNonNullEnumListChannel.setMessageHandler(nil) } - /// Returns the default string. - let echoNamedDefaultStringChannel = FlutterBasicMessageChannel( + /// Returns the passed list, to test serialization and deserialization. + let echoNonNullClassListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNamedDefaultString\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullClassList\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoNamedDefaultStringChannel.setMessageHandler { message, reply in + echoNonNullClassListChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aStringArg = args[0] as! String + let classListArg = args[0] as! [AllNullableTypes] do { - let result = try api.echoNamedDefault(aStringArg) + let result = try api.echoNonNull(classList: classListArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoNamedDefaultStringChannel.setMessageHandler(nil) + echoNonNullClassListChannel.setMessageHandler(nil) } - /// Returns passed in double. - let echoOptionalDefaultDoubleChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoOptionalDefaultDouble\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoOptionalDefaultDoubleChannel.setMessageHandler { message, reply in + echoMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aDoubleArg = args[0] as! Double + let mapArg = args[0] as! [AnyHashable?: Any?] do { - let result = try api.echoOptionalDefault(aDoubleArg) + let result = try api.echo(mapArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoOptionalDefaultDoubleChannel.setMessageHandler(nil) + echoMapChannel.setMessageHandler(nil) } - /// Returns passed in int. - let echoRequiredIntChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoStringMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoRequiredInt\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoStringMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoRequiredIntChannel.setMessageHandler { message, reply in + echoStringMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anIntArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + let stringMapArg = args[0] as! [String?: String?] do { - let result = try api.echoRequired(anIntArg) + let result = try api.echo(stringMap: stringMapArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoRequiredIntChannel.setMessageHandler(nil) + echoStringMapChannel.setMessageHandler(nil) } - /// Returns the passed object, to test serialization and deserialization. - let echoAllNullableTypesChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoIntMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypes\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoIntMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAllNullableTypesChannel.setMessageHandler { message, reply in + echoIntMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let everythingArg: AllNullableTypes? = nilOrValue(args[0]) + let intMapArg = args[0] as! [Int64?: Int64?] do { - let result = try api.echo(everythingArg) + let result = try api.echo(intMap: intMapArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoAllNullableTypesChannel.setMessageHandler(nil) + echoIntMapChannel.setMessageHandler(nil) } - /// Returns the passed object, to test serialization and deserialization. - let echoAllNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoEnumMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypesWithoutRecursion\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoEnumMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAllNullableTypesWithoutRecursionChannel.setMessageHandler { message, reply in + echoEnumMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let everythingArg: AllNullableTypesWithoutRecursion? = nilOrValue(args[0]) + let enumMapArg = args[0] as? [AnEnum?: AnEnum?] do { - let result = try api.echo(everythingArg) + let result = try api.echo(enumMap: enumMapArg!) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoAllNullableTypesWithoutRecursionChannel.setMessageHandler(nil) + echoEnumMapChannel.setMessageHandler(nil) } - /// Returns the inner `aString` value from the wrapped object, to test - /// sending of nested objects. - let extractNestedNullableStringChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoClassMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.extractNestedNullableString\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoClassMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - extractNestedNullableStringChannel.setMessageHandler { message, reply in + echoClassMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let wrapperArg = args[0] as! AllClassesWrapper + let classMapArg = args[0] as! [Int64?: AllNullableTypes?] do { - let result = try api.extractNestedNullableString(from: wrapperArg) + let result = try api.echo(classMap: classMapArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - extractNestedNullableStringChannel.setMessageHandler(nil) + echoClassMapChannel.setMessageHandler(nil) } - /// Returns the inner `aString` value from the wrapped object, to test - /// sending of nested objects. - let createNestedNullableStringChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNonNullStringMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.createNestedNullableString\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullStringMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - createNestedNullableStringChannel.setMessageHandler { message, reply in + echoNonNullStringMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let nullableStringArg: String? = nilOrValue(args[0]) + let stringMapArg = args[0] as! [String: String] do { - let result = try api.createNestedObject(with: nullableStringArg) + let result = try api.echoNonNull(stringMap: stringMapArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - createNestedNullableStringChannel.setMessageHandler(nil) + echoNonNullStringMapChannel.setMessageHandler(nil) } - /// Returns passed in arguments of multiple types. - let sendMultipleNullableTypesChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNonNullIntMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypes\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullIntMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - sendMultipleNullableTypesChannel.setMessageHandler { message, reply in + echoNonNullIntMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableBoolArg: Bool? = nilOrValue(args[0]) - let aNullableIntArg: Int64? = - isNullish(args[1]) - ? nil : (args[1] is Int64? ? args[1] as! Int64? : Int64(args[1] as! Int32)) - let aNullableStringArg: String? = nilOrValue(args[2]) + let intMapArg = args[0] as! [Int64: Int64] do { - let result = try api.sendMultipleNullableTypes( - aBool: aNullableBoolArg, anInt: aNullableIntArg, aString: aNullableStringArg) + let result = try api.echoNonNull(intMap: intMapArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - sendMultipleNullableTypesChannel.setMessageHandler(nil) + echoNonNullIntMapChannel.setMessageHandler(nil) } - /// Returns passed in arguments of multiple types. - let sendMultipleNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNonNullEnumMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullEnumMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - sendMultipleNullableTypesWithoutRecursionChannel.setMessageHandler { message, reply in + echoNonNullEnumMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableBoolArg: Bool? = nilOrValue(args[0]) - let aNullableIntArg: Int64? = - isNullish(args[1]) - ? nil : (args[1] is Int64? ? args[1] as! Int64? : Int64(args[1] as! Int32)) - let aNullableStringArg: String? = nilOrValue(args[2]) + let enumMapArg = args[0] as? [AnEnum: AnEnum] do { - let result = try api.sendMultipleNullableTypesWithoutRecursion( - aBool: aNullableBoolArg, anInt: aNullableIntArg, aString: aNullableStringArg) + let result = try api.echoNonNull(enumMap: enumMapArg!) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - sendMultipleNullableTypesWithoutRecursionChannel.setMessageHandler(nil) + echoNonNullEnumMapChannel.setMessageHandler(nil) } - /// Returns passed in int. - let echoNullableIntChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNonNullClassMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableInt\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNonNullClassMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoNullableIntChannel.setMessageHandler { message, reply in + echoNonNullClassMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableIntArg: Int64? = - isNullish(args[0]) - ? nil : (args[0] is Int64? ? args[0] as! Int64? : Int64(args[0] as! Int32)) + let classMapArg = args[0] as! [Int64: AllNullableTypes] do { - let result = try api.echo(aNullableIntArg) + let result = try api.echoNonNull(classMap: classMapArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoNullableIntChannel.setMessageHandler(nil) + echoNonNullClassMapChannel.setMessageHandler(nil) } - /// Returns passed in double. - let echoNullableDoubleChannel = FlutterBasicMessageChannel( + /// Returns the passed class to test nested class serialization and deserialization. + let echoClassWrapperChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableDouble\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoClassWrapper\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoNullableDoubleChannel.setMessageHandler { message, reply in + echoClassWrapperChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableDoubleArg: Double? = nilOrValue(args[0]) + let wrapperArg = args[0] as! AllClassesWrapper do { - let result = try api.echo(aNullableDoubleArg) + let result = try api.echo(wrapperArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoNullableDoubleChannel.setMessageHandler(nil) + echoClassWrapperChannel.setMessageHandler(nil) } - /// Returns the passed in boolean. - let echoNullableBoolChannel = FlutterBasicMessageChannel( + /// Returns the passed enum to test serialization and deserialization. + let echoEnumChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableBool\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoEnum\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoNullableBoolChannel.setMessageHandler { message, reply in + echoEnumChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableBoolArg: Bool? = nilOrValue(args[0]) + let anEnumArg = args[0] as! AnEnum do { - let result = try api.echo(aNullableBoolArg) + let result = try api.echo(anEnumArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoNullableBoolChannel.setMessageHandler(nil) + echoEnumChannel.setMessageHandler(nil) } - /// Returns the passed in string. - let echoNullableStringChannel = FlutterBasicMessageChannel( + /// Returns the passed enum to test serialization and deserialization. + let echoAnotherEnumChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableString\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAnotherEnum\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoNullableStringChannel.setMessageHandler { message, reply in + echoAnotherEnumChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableStringArg: String? = nilOrValue(args[0]) + let anotherEnumArg = args[0] as! AnotherEnum do { - let result = try api.echo(aNullableStringArg) + let result = try api.echo(anotherEnumArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoNullableStringChannel.setMessageHandler(nil) + echoAnotherEnumChannel.setMessageHandler(nil) } - /// Returns the passed in Uint8List. - let echoNullableUint8ListChannel = FlutterBasicMessageChannel( + /// Returns the default string. + let echoNamedDefaultStringChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableUint8List\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNamedDefaultString\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoNullableUint8ListChannel.setMessageHandler { message, reply in + echoNamedDefaultStringChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableUint8ListArg: FlutterStandardTypedData? = nilOrValue(args[0]) + let aStringArg = args[0] as! String do { - let result = try api.echo(aNullableUint8ListArg) + let result = try api.echoNamedDefault(aStringArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoNullableUint8ListChannel.setMessageHandler(nil) + echoNamedDefaultStringChannel.setMessageHandler(nil) } - /// Returns the passed in generic Object. - let echoNullableObjectChannel = FlutterBasicMessageChannel( + /// Returns passed in double. + let echoOptionalDefaultDoubleChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableObject\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoOptionalDefaultDouble\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoNullableObjectChannel.setMessageHandler { message, reply in + echoOptionalDefaultDoubleChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableObjectArg: Any? = args[0] + let aDoubleArg = args[0] as! Double do { - let result = try api.echo(aNullableObjectArg) + let result = try api.echoOptionalDefault(aDoubleArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoNullableObjectChannel.setMessageHandler(nil) + echoOptionalDefaultDoubleChannel.setMessageHandler(nil) } - /// Returns the passed list, to test serialization and deserialization. - let echoNullableListChannel = FlutterBasicMessageChannel( + /// Returns passed in int. + let echoRequiredIntChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableList\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoRequiredInt\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoNullableListChannel.setMessageHandler { message, reply in + echoRequiredIntChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableListArg: [Any?]? = nilOrValue(args[0]) + let anIntArg = args[0] as! Int64 do { - let result = try api.echoNullable(aNullableListArg) + let result = try api.echoRequired(anIntArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoNullableListChannel.setMessageHandler(nil) + echoRequiredIntChannel.setMessageHandler(nil) } - /// Returns the passed map, to test serialization and deserialization. - let echoNullableMapChannel = FlutterBasicMessageChannel( + /// Returns the passed object, to test serialization and deserialization. + let echoAllNullableTypesChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableMap\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypes\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoNullableMapChannel.setMessageHandler { message, reply in + echoAllNullableTypesChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableMapArg: [String?: Any?]? = nilOrValue(args[0]) + let everythingArg: AllNullableTypes? = nilOrValue(args[0]) do { - let result = try api.echoNullable(aNullableMapArg) + let result = try api.echo(everythingArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoNullableMapChannel.setMessageHandler(nil) + echoAllNullableTypesChannel.setMessageHandler(nil) } - let echoNullableEnumChannel = FlutterBasicMessageChannel( + /// Returns the passed object, to test serialization and deserialization. + let echoAllNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableEnum\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypesWithoutRecursion\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoNullableEnumChannel.setMessageHandler { message, reply in + echoAllNullableTypesWithoutRecursionChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anEnumArg: AnEnum? = nilOrValue(args[0]) + let everythingArg: AllNullableTypesWithoutRecursion? = nilOrValue(args[0]) do { - let result = try api.echoNullable(anEnumArg) + let result = try api.echo(everythingArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoNullableEnumChannel.setMessageHandler(nil) + echoAllNullableTypesWithoutRecursionChannel.setMessageHandler(nil) } - /// Returns passed in int. - let echoOptionalNullableIntChannel = FlutterBasicMessageChannel( + /// Returns the inner `aString` value from the wrapped object, to test + /// sending of nested objects. + let extractNestedNullableStringChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoOptionalNullableInt\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.extractNestedNullableString\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoOptionalNullableIntChannel.setMessageHandler { message, reply in + extractNestedNullableStringChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableIntArg: Int64? = - isNullish(args[0]) - ? nil : (args[0] is Int64? ? args[0] as! Int64? : Int64(args[0] as! Int32)) + let wrapperArg = args[0] as! AllClassesWrapper do { - let result = try api.echoOptional(aNullableIntArg) + let result = try api.extractNestedNullableString(from: wrapperArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoOptionalNullableIntChannel.setMessageHandler(nil) + extractNestedNullableStringChannel.setMessageHandler(nil) } - /// Returns the passed in string. - let echoNamedNullableStringChannel = FlutterBasicMessageChannel( + /// Returns the inner `aString` value from the wrapped object, to test + /// sending of nested objects. + let createNestedNullableStringChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNamedNullableString\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.createNestedNullableString\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoNamedNullableStringChannel.setMessageHandler { message, reply in + createNestedNullableStringChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableStringArg: String? = nilOrValue(args[0]) + let nullableStringArg: String? = nilOrValue(args[0]) do { - let result = try api.echoNamed(aNullableStringArg) + let result = try api.createNestedObject(with: nullableStringArg) reply(wrapResult(result)) } catch { reply(wrapError(error)) } } } else { - echoNamedNullableStringChannel.setMessageHandler(nil) + createNestedNullableStringChannel.setMessageHandler(nil) } - /// A no-op function taking no arguments and returning no value, to sanity - /// test basic asynchronous calling. - let noopAsyncChannel = FlutterBasicMessageChannel( + /// Returns passed in arguments of multiple types. + let sendMultipleNullableTypesChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.noopAsync\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypes\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - noopAsyncChannel.setMessageHandler { _, reply in - api.noopAsync { result in - switch result { - case .success: - reply(wrapResult(nil)) - case .failure(let error): - reply(wrapError(error)) - } + sendMultipleNullableTypesChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aNullableBoolArg: Bool? = nilOrValue(args[0]) + let aNullableIntArg: Int64? = nilOrValue(args[1]) + let aNullableStringArg: String? = nilOrValue(args[2]) + do { + let result = try api.sendMultipleNullableTypes( + aBool: aNullableBoolArg, anInt: aNullableIntArg, aString: aNullableStringArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - noopAsyncChannel.setMessageHandler(nil) + sendMultipleNullableTypesChannel.setMessageHandler(nil) } - /// Returns passed in int asynchronously. - let echoAsyncIntChannel = FlutterBasicMessageChannel( + /// Returns passed in arguments of multiple types. + let sendMultipleNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncInt\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncIntChannel.setMessageHandler { message, reply in + sendMultipleNullableTypesWithoutRecursionChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anIntArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) - api.echoAsync(anIntArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let aNullableBoolArg: Bool? = nilOrValue(args[0]) + let aNullableIntArg: Int64? = nilOrValue(args[1]) + let aNullableStringArg: String? = nilOrValue(args[2]) + do { + let result = try api.sendMultipleNullableTypesWithoutRecursion( + aBool: aNullableBoolArg, anInt: aNullableIntArg, aString: aNullableStringArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncIntChannel.setMessageHandler(nil) + sendMultipleNullableTypesWithoutRecursionChannel.setMessageHandler(nil) } - /// Returns passed in double asynchronously. - let echoAsyncDoubleChannel = FlutterBasicMessageChannel( + /// Returns passed in int. + let echoNullableIntChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncDouble\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableInt\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncDoubleChannel.setMessageHandler { message, reply in + echoNullableIntChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aDoubleArg = args[0] as! Double - api.echoAsync(aDoubleArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let aNullableIntArg: Int64? = nilOrValue(args[0]) + do { + let result = try api.echo(aNullableIntArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncDoubleChannel.setMessageHandler(nil) + echoNullableIntChannel.setMessageHandler(nil) } - /// Returns the passed in boolean asynchronously. - let echoAsyncBoolChannel = FlutterBasicMessageChannel( + /// Returns passed in double. + let echoNullableDoubleChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncBool\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableDouble\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncBoolChannel.setMessageHandler { message, reply in + echoNullableDoubleChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aBoolArg = args[0] as! Bool - api.echoAsync(aBoolArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let aNullableDoubleArg: Double? = nilOrValue(args[0]) + do { + let result = try api.echo(aNullableDoubleArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncBoolChannel.setMessageHandler(nil) + echoNullableDoubleChannel.setMessageHandler(nil) } - /// Returns the passed string asynchronously. - let echoAsyncStringChannel = FlutterBasicMessageChannel( + /// Returns the passed in boolean. + let echoNullableBoolChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncString\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableBool\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncStringChannel.setMessageHandler { message, reply in + echoNullableBoolChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aStringArg = args[0] as! String - api.echoAsync(aStringArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let aNullableBoolArg: Bool? = nilOrValue(args[0]) + do { + let result = try api.echo(aNullableBoolArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncStringChannel.setMessageHandler(nil) + echoNullableBoolChannel.setMessageHandler(nil) } - /// Returns the passed in Uint8List asynchronously. - let echoAsyncUint8ListChannel = FlutterBasicMessageChannel( + /// Returns the passed in string. + let echoNullableStringChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncUint8List\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableString\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncUint8ListChannel.setMessageHandler { message, reply in + echoNullableStringChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aUint8ListArg = args[0] as! FlutterStandardTypedData - api.echoAsync(aUint8ListArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let aNullableStringArg: String? = nilOrValue(args[0]) + do { + let result = try api.echo(aNullableStringArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncUint8ListChannel.setMessageHandler(nil) + echoNullableStringChannel.setMessageHandler(nil) } - /// Returns the passed in generic Object asynchronously. - let echoAsyncObjectChannel = FlutterBasicMessageChannel( + /// Returns the passed in Uint8List. + let echoNullableUint8ListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncObject\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableUint8List\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncObjectChannel.setMessageHandler { message, reply in + echoNullableUint8ListChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anObjectArg = args[0]! - api.echoAsync(anObjectArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let aNullableUint8ListArg: FlutterStandardTypedData? = nilOrValue(args[0]) + do { + let result = try api.echo(aNullableUint8ListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncObjectChannel.setMessageHandler(nil) + echoNullableUint8ListChannel.setMessageHandler(nil) } - /// Returns the passed list, to test asynchronous serialization and deserialization. - let echoAsyncListChannel = FlutterBasicMessageChannel( + /// Returns the passed in generic Object. + let echoNullableObjectChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncList\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableObject\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncListChannel.setMessageHandler { message, reply in + echoNullableObjectChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let listArg = args[0] as! [Any?] - api.echoAsync(listArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let aNullableObjectArg: Any? = args[0] + do { + let result = try api.echo(aNullableObjectArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncListChannel.setMessageHandler(nil) + echoNullableObjectChannel.setMessageHandler(nil) } - /// Returns the passed map, to test asynchronous serialization and deserialization. - let echoAsyncMapChannel = FlutterBasicMessageChannel( + /// Returns the passed list, to test serialization and deserialization. + let echoNullableListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncMap\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableList\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncMapChannel.setMessageHandler { message, reply in + echoNullableListChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aMapArg = args[0] as! [String?: Any?] - api.echoAsync(aMapArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let aNullableListArg: [Any?]? = nilOrValue(args[0]) + do { + let result = try api.echoNullable(aNullableListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncMapChannel.setMessageHandler(nil) + echoNullableListChannel.setMessageHandler(nil) } - /// Returns the passed enum, to test asynchronous serialization and deserialization. - let echoAsyncEnumChannel = FlutterBasicMessageChannel( + /// Returns the passed list, to test serialization and deserialization. + let echoNullableEnumListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncEnum\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableEnumList\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncEnumChannel.setMessageHandler { message, reply in + echoNullableEnumListChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anEnumArg = args[0] as! AnEnum - api.echoAsync(anEnumArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let enumListArg: [AnEnum?]? = nilOrValue(args[0]) + do { + let result = try api.echoNullable(enumList: enumListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncEnumChannel.setMessageHandler(nil) + echoNullableEnumListChannel.setMessageHandler(nil) } - /// Responds with an error from an async function returning a value. - let throwAsyncErrorChannel = FlutterBasicMessageChannel( + /// Returns the passed list, to test serialization and deserialization. + let echoNullableClassListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncError\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableClassList\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - throwAsyncErrorChannel.setMessageHandler { _, reply in - api.throwAsyncError { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + echoNullableClassListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let classListArg: [AllNullableTypes?]? = nilOrValue(args[0]) + do { + let result = try api.echoNullable(classList: classListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - throwAsyncErrorChannel.setMessageHandler(nil) + echoNullableClassListChannel.setMessageHandler(nil) } - /// Responds with an error from an async void function. - let throwAsyncErrorFromVoidChannel = FlutterBasicMessageChannel( + /// Returns the passed list, to test serialization and deserialization. + let echoNullableNonNullEnumListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncErrorFromVoid\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullEnumList\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - throwAsyncErrorFromVoidChannel.setMessageHandler { _, reply in - api.throwAsyncErrorFromVoid { result in - switch result { - case .success: - reply(wrapResult(nil)) - case .failure(let error): - reply(wrapError(error)) - } + echoNullableNonNullEnumListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let enumListArg: [AnEnum]? = nilOrValue(args[0]) + do { + let result = try api.echoNullableNonNull(enumList: enumListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - throwAsyncErrorFromVoidChannel.setMessageHandler(nil) + echoNullableNonNullEnumListChannel.setMessageHandler(nil) } - /// Responds with a Flutter error from an async function returning a value. - let throwAsyncFlutterErrorChannel = FlutterBasicMessageChannel( + /// Returns the passed list, to test serialization and deserialization. + let echoNullableNonNullClassListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncFlutterError\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullClassList\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - throwAsyncFlutterErrorChannel.setMessageHandler { _, reply in - api.throwAsyncFlutterError { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + echoNullableNonNullClassListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let classListArg: [AllNullableTypes]? = nilOrValue(args[0]) + do { + let result = try api.echoNullableNonNull(classList: classListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - throwAsyncFlutterErrorChannel.setMessageHandler(nil) + echoNullableNonNullClassListChannel.setMessageHandler(nil) } - /// Returns the passed object, to test async serialization and deserialization. - let echoAsyncAllTypesChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNullableMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncAllTypes\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncAllTypesChannel.setMessageHandler { message, reply in + echoNullableMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let everythingArg = args[0] as! AllTypes - api.echoAsync(everythingArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let mapArg: [AnyHashable?: Any?]? = nilOrValue(args[0]) + do { + let result = try api.echoNullable(mapArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncAllTypesChannel.setMessageHandler(nil) + echoNullableMapChannel.setMessageHandler(nil) } - /// Returns the passed object, to test serialization and deserialization. - let echoAsyncNullableAllNullableTypesChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNullableStringMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypes\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableStringMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncNullableAllNullableTypesChannel.setMessageHandler { message, reply in + echoNullableStringMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let everythingArg: AllNullableTypes? = nilOrValue(args[0]) - api.echoAsync(everythingArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let stringMapArg: [String?: String?]? = nilOrValue(args[0]) + do { + let result = try api.echoNullable(stringMap: stringMapArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncNullableAllNullableTypesChannel.setMessageHandler(nil) + echoNullableStringMapChannel.setMessageHandler(nil) } - /// Returns the passed object, to test serialization and deserialization. - let echoAsyncNullableAllNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNullableIntMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypesWithoutRecursion\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableIntMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncNullableAllNullableTypesWithoutRecursionChannel.setMessageHandler { message, reply in + echoNullableIntMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let everythingArg: AllNullableTypesWithoutRecursion? = nilOrValue(args[0]) - api.echoAsync(everythingArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let intMapArg: [Int64?: Int64?]? = nilOrValue(args[0]) + do { + let result = try api.echoNullable(intMap: intMapArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncNullableAllNullableTypesWithoutRecursionChannel.setMessageHandler(nil) + echoNullableIntMapChannel.setMessageHandler(nil) } - /// Returns passed in int asynchronously. - let echoAsyncNullableIntChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNullableEnumMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableInt\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableEnumMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncNullableIntChannel.setMessageHandler { message, reply in + echoNullableEnumMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anIntArg: Int64? = - isNullish(args[0]) - ? nil : (args[0] is Int64? ? args[0] as! Int64? : Int64(args[0] as! Int32)) - api.echoAsyncNullable(anIntArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let enumMapArg: [AnEnum?: AnEnum?]? = args[0] as? [AnEnum?: AnEnum?] + do { + let result = try api.echoNullable(enumMap: enumMapArg!) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncNullableIntChannel.setMessageHandler(nil) + echoNullableEnumMapChannel.setMessageHandler(nil) } - /// Returns passed in double asynchronously. - let echoAsyncNullableDoubleChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNullableClassMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableDouble\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableClassMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncNullableDoubleChannel.setMessageHandler { message, reply in + echoNullableClassMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aDoubleArg: Double? = nilOrValue(args[0]) - api.echoAsyncNullable(aDoubleArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let classMapArg: [Int64?: AllNullableTypes?]? = nilOrValue(args[0]) + do { + let result = try api.echoNullable(classMap: classMapArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncNullableDoubleChannel.setMessageHandler(nil) + echoNullableClassMapChannel.setMessageHandler(nil) } - /// Returns the passed in boolean asynchronously. - let echoAsyncNullableBoolChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNullableNonNullStringMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableBool\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullStringMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncNullableBoolChannel.setMessageHandler { message, reply in + echoNullableNonNullStringMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aBoolArg: Bool? = nilOrValue(args[0]) - api.echoAsyncNullable(aBoolArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let stringMapArg: [String: String]? = nilOrValue(args[0]) + do { + let result = try api.echoNullableNonNull(stringMap: stringMapArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncNullableBoolChannel.setMessageHandler(nil) + echoNullableNonNullStringMapChannel.setMessageHandler(nil) } - /// Returns the passed string asynchronously. - let echoAsyncNullableStringChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNullableNonNullIntMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableString\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullIntMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncNullableStringChannel.setMessageHandler { message, reply in + echoNullableNonNullIntMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aStringArg: String? = nilOrValue(args[0]) - api.echoAsyncNullable(aStringArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let intMapArg: [Int64: Int64]? = nilOrValue(args[0]) + do { + let result = try api.echoNullableNonNull(intMap: intMapArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncNullableStringChannel.setMessageHandler(nil) + echoNullableNonNullIntMapChannel.setMessageHandler(nil) } - /// Returns the passed in Uint8List asynchronously. - let echoAsyncNullableUint8ListChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNullableNonNullEnumMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableUint8List\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullEnumMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncNullableUint8ListChannel.setMessageHandler { message, reply in + echoNullableNonNullEnumMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aUint8ListArg: FlutterStandardTypedData? = nilOrValue(args[0]) - api.echoAsyncNullable(aUint8ListArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let enumMapArg: [AnEnum: AnEnum]? = args[0] as? [AnEnum: AnEnum] + do { + let result = try api.echoNullableNonNull(enumMap: enumMapArg!) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncNullableUint8ListChannel.setMessageHandler(nil) + echoNullableNonNullEnumMapChannel.setMessageHandler(nil) } - /// Returns the passed in generic Object asynchronously. - let echoAsyncNullableObjectChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test serialization and deserialization. + let echoNullableNonNullClassMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableObject\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableNonNullClassMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncNullableObjectChannel.setMessageHandler { message, reply in + echoNullableNonNullClassMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anObjectArg: Any? = args[0] - api.echoAsyncNullable(anObjectArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let classMapArg: [Int64: AllNullableTypes]? = nilOrValue(args[0]) + do { + let result = try api.echoNullableNonNull(classMap: classMapArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncNullableObjectChannel.setMessageHandler(nil) + echoNullableNonNullClassMapChannel.setMessageHandler(nil) } - /// Returns the passed list, to test asynchronous serialization and deserialization. - let echoAsyncNullableListChannel = FlutterBasicMessageChannel( + let echoNullableEnumChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableList\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableEnum\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncNullableListChannel.setMessageHandler { message, reply in + echoNullableEnumChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let listArg: [Any?]? = nilOrValue(args[0]) - api.echoAsyncNullable(listArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let anEnumArg: AnEnum? = nilOrValue(args[0]) + do { + let result = try api.echoNullable(anEnumArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncNullableListChannel.setMessageHandler(nil) + echoNullableEnumChannel.setMessageHandler(nil) } - /// Returns the passed map, to test asynchronous serialization and deserialization. - let echoAsyncNullableMapChannel = FlutterBasicMessageChannel( + let echoAnotherNullableEnumChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableMap\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAnotherNullableEnum\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncNullableMapChannel.setMessageHandler { message, reply in + echoAnotherNullableEnumChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aMapArg: [String?: Any?]? = nilOrValue(args[0]) - api.echoAsyncNullable(aMapArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let anotherEnumArg: AnotherEnum? = nilOrValue(args[0]) + do { + let result = try api.echoNullable(anotherEnumArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncNullableMapChannel.setMessageHandler(nil) + echoAnotherNullableEnumChannel.setMessageHandler(nil) } - /// Returns the passed enum, to test asynchronous serialization and deserialization. - let echoAsyncNullableEnumChannel = FlutterBasicMessageChannel( + /// Returns passed in int. + let echoOptionalNullableIntChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableEnum\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoOptionalNullableInt\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - echoAsyncNullableEnumChannel.setMessageHandler { message, reply in + echoOptionalNullableIntChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anEnumArg: AnEnum? = nilOrValue(args[0]) - api.echoAsyncNullable(anEnumArg) { result in - switch result { - case .success(let res): - reply(wrapResult(res)) - case .failure(let error): - reply(wrapError(error)) - } + let aNullableIntArg: Int64? = nilOrValue(args[0]) + do { + let result = try api.echoOptional(aNullableIntArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) } } } else { - echoAsyncNullableEnumChannel.setMessageHandler(nil) + echoOptionalNullableIntChannel.setMessageHandler(nil) } - let callFlutterNoopChannel = FlutterBasicMessageChannel( + /// Returns the passed in string. + let echoNamedNullableStringChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterNoop\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNamedNullableString\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterNoopChannel.setMessageHandler { _, reply in - api.callFlutterNoop { result in + echoNamedNullableStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aNullableStringArg: String? = nilOrValue(args[0]) + do { + let result = try api.echoNamed(aNullableStringArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoNamedNullableStringChannel.setMessageHandler(nil) + } + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic asynchronous calling. + let noopAsyncChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.noopAsync\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + noopAsyncChannel.setMessageHandler { _, reply in + api.noopAsync { result in switch result { case .success: reply(wrapResult(nil)) @@ -1965,15 +2265,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterNoopChannel.setMessageHandler(nil) + noopAsyncChannel.setMessageHandler(nil) } - let callFlutterThrowErrorChannel = FlutterBasicMessageChannel( + /// Returns passed in int asynchronously. + let echoAsyncIntChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterThrowError\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncInt\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterThrowErrorChannel.setMessageHandler { _, reply in - api.callFlutterThrowError { result in + echoAsyncIntChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let anIntArg = args[0] as! Int64 + api.echoAsync(anIntArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -1983,35 +2286,39 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterThrowErrorChannel.setMessageHandler(nil) + echoAsyncIntChannel.setMessageHandler(nil) } - let callFlutterThrowErrorFromVoidChannel = FlutterBasicMessageChannel( + /// Returns passed in double asynchronously. + let echoAsyncDoubleChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterThrowErrorFromVoid\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncDouble\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterThrowErrorFromVoidChannel.setMessageHandler { _, reply in - api.callFlutterThrowErrorFromVoid { result in + echoAsyncDoubleChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aDoubleArg = args[0] as! Double + api.echoAsync(aDoubleArg) { result in switch result { - case .success: - reply(wrapResult(nil)) + case .success(let res): + reply(wrapResult(res)) case .failure(let error): reply(wrapError(error)) } } } } else { - callFlutterThrowErrorFromVoidChannel.setMessageHandler(nil) + echoAsyncDoubleChannel.setMessageHandler(nil) } - let callFlutterEchoAllTypesChannel = FlutterBasicMessageChannel( + /// Returns the passed in boolean asynchronously. + let echoAsyncBoolChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllTypes\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncBool\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoAllTypesChannel.setMessageHandler { message, reply in + echoAsyncBoolChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let everythingArg = args[0] as! AllTypes - api.callFlutterEcho(everythingArg) { result in + let aBoolArg = args[0] as! Bool + api.echoAsync(aBoolArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2021,17 +2328,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoAllTypesChannel.setMessageHandler(nil) + echoAsyncBoolChannel.setMessageHandler(nil) } - let callFlutterEchoAllNullableTypesChannel = FlutterBasicMessageChannel( + /// Returns the passed string asynchronously. + let echoAsyncStringChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypes\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncString\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoAllNullableTypesChannel.setMessageHandler { message, reply in + echoAsyncStringChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let everythingArg: AllNullableTypes? = nilOrValue(args[0]) - api.callFlutterEcho(everythingArg) { result in + let aStringArg = args[0] as! String + api.echoAsync(aStringArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2041,23 +2349,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoAllNullableTypesChannel.setMessageHandler(nil) + echoAsyncStringChannel.setMessageHandler(nil) } - let callFlutterSendMultipleNullableTypesChannel = FlutterBasicMessageChannel( + /// Returns the passed in Uint8List asynchronously. + let echoAsyncUint8ListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypes\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncUint8List\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterSendMultipleNullableTypesChannel.setMessageHandler { message, reply in + echoAsyncUint8ListChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableBoolArg: Bool? = nilOrValue(args[0]) - let aNullableIntArg: Int64? = - isNullish(args[1]) - ? nil : (args[1] is Int64? ? args[1] as! Int64? : Int64(args[1] as! Int32)) - let aNullableStringArg: String? = nilOrValue(args[2]) - api.callFlutterSendMultipleNullableTypes( - aBool: aNullableBoolArg, anInt: aNullableIntArg, aString: aNullableStringArg - ) { result in + let aUint8ListArg = args[0] as! FlutterStandardTypedData + api.echoAsync(aUint8ListArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2067,17 +2370,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterSendMultipleNullableTypesChannel.setMessageHandler(nil) + echoAsyncUint8ListChannel.setMessageHandler(nil) } - let callFlutterEchoAllNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( + /// Returns the passed in generic Object asynchronously. + let echoAsyncObjectChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypesWithoutRecursion\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncObject\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoAllNullableTypesWithoutRecursionChannel.setMessageHandler { message, reply in + echoAsyncObjectChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let everythingArg: AllNullableTypesWithoutRecursion? = nilOrValue(args[0]) - api.callFlutterEcho(everythingArg) { result in + let anObjectArg = args[0]! + api.echoAsync(anObjectArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2087,24 +2391,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoAllNullableTypesWithoutRecursionChannel.setMessageHandler(nil) + echoAsyncObjectChannel.setMessageHandler(nil) } - let callFlutterSendMultipleNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( + /// Returns the passed list, to test asynchronous serialization and deserialization. + let echoAsyncListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypesWithoutRecursion\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncList\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterSendMultipleNullableTypesWithoutRecursionChannel.setMessageHandler { - message, reply in + echoAsyncListChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aNullableBoolArg: Bool? = nilOrValue(args[0]) - let aNullableIntArg: Int64? = - isNullish(args[1]) - ? nil : (args[1] is Int64? ? args[1] as! Int64? : Int64(args[1] as! Int32)) - let aNullableStringArg: String? = nilOrValue(args[2]) - api.callFlutterSendMultipleNullableTypesWithoutRecursion( - aBool: aNullableBoolArg, anInt: aNullableIntArg, aString: aNullableStringArg - ) { result in + let listArg = args[0] as! [Any?] + api.echoAsync(listArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2114,17 +2412,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterSendMultipleNullableTypesWithoutRecursionChannel.setMessageHandler(nil) + echoAsyncListChannel.setMessageHandler(nil) } - let callFlutterEchoBoolChannel = FlutterBasicMessageChannel( + /// Returns the passed list, to test asynchronous serialization and deserialization. + let echoAsyncEnumListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoBool\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncEnumList\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoBoolChannel.setMessageHandler { message, reply in + echoAsyncEnumListChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aBoolArg = args[0] as! Bool - api.callFlutterEcho(aBoolArg) { result in + let enumListArg = args[0] as! [AnEnum?] + api.echoAsync(enumList: enumListArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2134,17 +2433,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoBoolChannel.setMessageHandler(nil) + echoAsyncEnumListChannel.setMessageHandler(nil) } - let callFlutterEchoIntChannel = FlutterBasicMessageChannel( + /// Returns the passed list, to test asynchronous serialization and deserialization. + let echoAsyncClassListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoInt\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncClassList\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoIntChannel.setMessageHandler { message, reply in + echoAsyncClassListChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anIntArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) - api.callFlutterEcho(anIntArg) { result in + let classListArg = args[0] as! [AllNullableTypes?] + api.echoAsync(classList: classListArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2154,17 +2454,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoIntChannel.setMessageHandler(nil) + echoAsyncClassListChannel.setMessageHandler(nil) } - let callFlutterEchoDoubleChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test asynchronous serialization and deserialization. + let echoAsyncMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoDouble\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoDoubleChannel.setMessageHandler { message, reply in + echoAsyncMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aDoubleArg = args[0] as! Double - api.callFlutterEcho(aDoubleArg) { result in + let mapArg = args[0] as! [AnyHashable?: Any?] + api.echoAsync(mapArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2174,17 +2475,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoDoubleChannel.setMessageHandler(nil) + echoAsyncMapChannel.setMessageHandler(nil) } - let callFlutterEchoStringChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test asynchronous serialization and deserialization. + let echoAsyncStringMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoString\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncStringMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoStringChannel.setMessageHandler { message, reply in + echoAsyncStringMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aStringArg = args[0] as! String - api.callFlutterEcho(aStringArg) { result in + let stringMapArg = args[0] as! [String?: String?] + api.echoAsync(stringMap: stringMapArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2194,17 +2496,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoStringChannel.setMessageHandler(nil) + echoAsyncStringMapChannel.setMessageHandler(nil) } - let callFlutterEchoUint8ListChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test asynchronous serialization and deserialization. + let echoAsyncIntMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoUint8List\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncIntMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoUint8ListChannel.setMessageHandler { message, reply in + echoAsyncIntMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let listArg = args[0] as! FlutterStandardTypedData - api.callFlutterEcho(listArg) { result in + let intMapArg = args[0] as! [Int64?: Int64?] + api.echoAsync(intMap: intMapArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2214,17 +2517,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoUint8ListChannel.setMessageHandler(nil) + echoAsyncIntMapChannel.setMessageHandler(nil) } - let callFlutterEchoListChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test asynchronous serialization and deserialization. + let echoAsyncEnumMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoList\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncEnumMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoListChannel.setMessageHandler { message, reply in + echoAsyncEnumMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let listArg = args[0] as! [Any?] - api.callFlutterEcho(listArg) { result in + let enumMapArg = args[0] as? [AnEnum?: AnEnum?] + api.echoAsync(enumMap: enumMapArg!) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2234,17 +2538,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoListChannel.setMessageHandler(nil) + echoAsyncEnumMapChannel.setMessageHandler(nil) } - let callFlutterEchoMapChannel = FlutterBasicMessageChannel( + /// Returns the passed map, to test asynchronous serialization and deserialization. + let echoAsyncClassMapChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoMap\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncClassMap\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoMapChannel.setMessageHandler { message, reply in + echoAsyncClassMapChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aMapArg = args[0] as! [String?: Any?] - api.callFlutterEcho(aMapArg) { result in + let classMapArg = args[0] as! [Int64?: AllNullableTypes?] + api.echoAsync(classMap: classMapArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2254,17 +2559,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoMapChannel.setMessageHandler(nil) + echoAsyncClassMapChannel.setMessageHandler(nil) } - let callFlutterEchoEnumChannel = FlutterBasicMessageChannel( + /// Returns the passed enum, to test asynchronous serialization and deserialization. + let echoAsyncEnumChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoEnum\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncEnum\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoEnumChannel.setMessageHandler { message, reply in + echoAsyncEnumChannel.setMessageHandler { message, reply in let args = message as! [Any?] let anEnumArg = args[0] as! AnEnum - api.callFlutterEcho(anEnumArg) { result in + api.echoAsync(anEnumArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2274,17 +2580,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoEnumChannel.setMessageHandler(nil) + echoAsyncEnumChannel.setMessageHandler(nil) } - let callFlutterEchoNullableBoolChannel = FlutterBasicMessageChannel( + /// Returns the passed enum, to test asynchronous serialization and deserialization. + let echoAnotherAsyncEnumChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableBool\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAnotherAsyncEnum\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoNullableBoolChannel.setMessageHandler { message, reply in + echoAnotherAsyncEnumChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aBoolArg: Bool? = nilOrValue(args[0]) - api.callFlutterEchoNullable(aBoolArg) { result in + let anotherEnumArg = args[0] as! AnotherEnum + api.echoAsync(anotherEnumArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2294,19 +2601,75 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoNullableBoolChannel.setMessageHandler(nil) + echoAnotherAsyncEnumChannel.setMessageHandler(nil) } - let callFlutterEchoNullableIntChannel = FlutterBasicMessageChannel( + /// Responds with an error from an async function returning a value. + let throwAsyncErrorChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableInt\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncError\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoNullableIntChannel.setMessageHandler { message, reply in + throwAsyncErrorChannel.setMessageHandler { _, reply in + api.throwAsyncError { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + throwAsyncErrorChannel.setMessageHandler(nil) + } + /// Responds with an error from an async void function. + let throwAsyncErrorFromVoidChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncErrorFromVoid\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + throwAsyncErrorFromVoidChannel.setMessageHandler { _, reply in + api.throwAsyncErrorFromVoid { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + throwAsyncErrorFromVoidChannel.setMessageHandler(nil) + } + /// Responds with a Flutter error from an async function returning a value. + let throwAsyncFlutterErrorChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.throwAsyncFlutterError\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + throwAsyncFlutterErrorChannel.setMessageHandler { _, reply in + api.throwAsyncFlutterError { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + throwAsyncFlutterErrorChannel.setMessageHandler(nil) + } + /// Returns the passed object, to test async serialization and deserialization. + let echoAsyncAllTypesChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncAllTypes\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncAllTypesChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anIntArg: Int64? = - isNullish(args[0]) - ? nil : (args[0] is Int64? ? args[0] as! Int64? : Int64(args[0] as! Int32)) - api.callFlutterEchoNullable(anIntArg) { result in + let everythingArg = args[0] as! AllTypes + api.echoAsync(everythingArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2316,17 +2679,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoNullableIntChannel.setMessageHandler(nil) + echoAsyncAllTypesChannel.setMessageHandler(nil) } - let callFlutterEchoNullableDoubleChannel = FlutterBasicMessageChannel( + /// Returns the passed object, to test serialization and deserialization. + let echoAsyncNullableAllNullableTypesChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableDouble\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypes\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoNullableDoubleChannel.setMessageHandler { message, reply in + echoAsyncNullableAllNullableTypesChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aDoubleArg: Double? = nilOrValue(args[0]) - api.callFlutterEchoNullable(aDoubleArg) { result in + let everythingArg: AllNullableTypes? = nilOrValue(args[0]) + api.echoAsync(everythingArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2336,17 +2700,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoNullableDoubleChannel.setMessageHandler(nil) + echoAsyncNullableAllNullableTypesChannel.setMessageHandler(nil) } - let callFlutterEchoNullableStringChannel = FlutterBasicMessageChannel( + /// Returns the passed object, to test serialization and deserialization. + let echoAsyncNullableAllNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableString\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypesWithoutRecursion\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoNullableStringChannel.setMessageHandler { message, reply in + echoAsyncNullableAllNullableTypesWithoutRecursionChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aStringArg: String? = nilOrValue(args[0]) - api.callFlutterEchoNullable(aStringArg) { result in + let everythingArg: AllNullableTypesWithoutRecursion? = nilOrValue(args[0]) + api.echoAsync(everythingArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2356,17 +2721,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoNullableStringChannel.setMessageHandler(nil) + echoAsyncNullableAllNullableTypesWithoutRecursionChannel.setMessageHandler(nil) } - let callFlutterEchoNullableUint8ListChannel = FlutterBasicMessageChannel( + /// Returns passed in int asynchronously. + let echoAsyncNullableIntChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableUint8List\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableInt\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoNullableUint8ListChannel.setMessageHandler { message, reply in + echoAsyncNullableIntChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let listArg: FlutterStandardTypedData? = nilOrValue(args[0]) - api.callFlutterEchoNullable(listArg) { result in + let anIntArg: Int64? = nilOrValue(args[0]) + api.echoAsyncNullable(anIntArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2376,17 +2742,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoNullableUint8ListChannel.setMessageHandler(nil) + echoAsyncNullableIntChannel.setMessageHandler(nil) } - let callFlutterEchoNullableListChannel = FlutterBasicMessageChannel( + /// Returns passed in double asynchronously. + let echoAsyncNullableDoubleChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableList\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableDouble\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoNullableListChannel.setMessageHandler { message, reply in + echoAsyncNullableDoubleChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let listArg: [Any?]? = nilOrValue(args[0]) - api.callFlutterEchoNullable(listArg) { result in + let aDoubleArg: Double? = nilOrValue(args[0]) + api.echoAsyncNullable(aDoubleArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2396,17 +2763,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoNullableListChannel.setMessageHandler(nil) + echoAsyncNullableDoubleChannel.setMessageHandler(nil) } - let callFlutterEchoNullableMapChannel = FlutterBasicMessageChannel( + /// Returns the passed in boolean asynchronously. + let echoAsyncNullableBoolChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableMap\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableBool\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoNullableMapChannel.setMessageHandler { message, reply in + echoAsyncNullableBoolChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aMapArg: [String?: Any?]? = nilOrValue(args[0]) - api.callFlutterEchoNullable(aMapArg) { result in + let aBoolArg: Bool? = nilOrValue(args[0]) + api.echoAsyncNullable(aBoolArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2416,17 +2784,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoNullableMapChannel.setMessageHandler(nil) + echoAsyncNullableBoolChannel.setMessageHandler(nil) } - let callFlutterEchoNullableEnumChannel = FlutterBasicMessageChannel( + /// Returns the passed string asynchronously. + let echoAsyncNullableStringChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableEnum\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableString\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterEchoNullableEnumChannel.setMessageHandler { message, reply in + echoAsyncNullableStringChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let anEnumArg: AnEnum? = nilOrValue(args[0]) - api.callFlutterNullableEcho(anEnumArg) { result in + let aStringArg: String? = nilOrValue(args[0]) + api.echoAsyncNullable(aStringArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2436,17 +2805,18 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterEchoNullableEnumChannel.setMessageHandler(nil) + echoAsyncNullableStringChannel.setMessageHandler(nil) } - let callFlutterSmallApiEchoStringChannel = FlutterBasicMessageChannel( + /// Returns the passed in Uint8List asynchronously. + let echoAsyncNullableUint8ListChannel = FlutterBasicMessageChannel( name: - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSmallApiEchoString\(channelSuffix)", + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableUint8List\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { - callFlutterSmallApiEchoStringChannel.setMessageHandler { message, reply in + echoAsyncNullableUint8ListChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let aStringArg = args[0] as! String - api.callFlutterSmallApiEcho(aStringArg) { result in + let aUint8ListArg: FlutterStandardTypedData? = nilOrValue(args[0]) + api.echoAsyncNullable(aUint8ListArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2456,115 +2826,2103 @@ class HostIntegrationCoreApiSetup { } } } else { - callFlutterSmallApiEchoStringChannel.setMessageHandler(nil) + echoAsyncNullableUint8ListChannel.setMessageHandler(nil) } - } -} -/// The core interface that the Dart platform_test code implements for host -/// integration tests to call into. -/// -/// Generated protocol from Pigeon that represents Flutter messages that can be called from Swift. -protocol FlutterIntegrationCoreApiProtocol { - /// A no-op function taking no arguments and returning no value, to sanity - /// test basic calling. - func noop(completion: @escaping (Result) -> Void) - /// Responds with an error from an async function returning a value. - func throwError(completion: @escaping (Result) -> Void) - /// Responds with an error from an async void function. - func throwErrorFromVoid(completion: @escaping (Result) -> Void) - /// Returns the passed object, to test serialization and deserialization. - func echo( - _ everythingArg: AllTypes, completion: @escaping (Result) -> Void) - /// Returns the passed object, to test serialization and deserialization. - func echoNullable( - _ everythingArg: AllNullableTypes?, - completion: @escaping (Result) -> Void) - /// Returns passed in arguments of multiple types. - /// - /// Tests multiple-arity FlutterApi handling. - func sendMultipleNullableTypes( - aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, - aString aNullableStringArg: String?, - completion: @escaping (Result) -> Void) - /// Returns the passed object, to test serialization and deserialization. - func echoNullable( - _ everythingArg: AllNullableTypesWithoutRecursion?, - completion: @escaping (Result) -> Void) - /// Returns passed in arguments of multiple types. - /// - /// Tests multiple-arity FlutterApi handling. - func sendMultipleNullableTypesWithoutRecursion( - aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, - aString aNullableStringArg: String?, - completion: @escaping (Result) -> Void) - /// Returns the passed boolean, to test serialization and deserialization. - func echo(_ aBoolArg: Bool, completion: @escaping (Result) -> Void) - /// Returns the passed int, to test serialization and deserialization. - func echo(_ anIntArg: Int64, completion: @escaping (Result) -> Void) - /// Returns the passed double, to test serialization and deserialization. - func echo(_ aDoubleArg: Double, completion: @escaping (Result) -> Void) - /// Returns the passed string, to test serialization and deserialization. - func echo(_ aStringArg: String, completion: @escaping (Result) -> Void) - /// Returns the passed byte list, to test serialization and deserialization. - func echo( - _ listArg: FlutterStandardTypedData, - completion: @escaping (Result) -> Void) + /// Returns the passed in generic Object asynchronously. + let echoAsyncNullableObjectChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableObject\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableObjectChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let anObjectArg: Any? = args[0] + api.echoAsyncNullable(anObjectArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableObjectChannel.setMessageHandler(nil) + } + /// Returns the passed list, to test asynchronous serialization and deserialization. + let echoAsyncNullableListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let listArg: [Any?]? = nilOrValue(args[0]) + api.echoAsyncNullable(listArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableListChannel.setMessageHandler(nil) + } + /// Returns the passed list, to test asynchronous serialization and deserialization. + let echoAsyncNullableEnumListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableEnumList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableEnumListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let enumListArg: [AnEnum?]? = nilOrValue(args[0]) + api.echoAsyncNullable(enumList: enumListArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableEnumListChannel.setMessageHandler(nil) + } + /// Returns the passed list, to test asynchronous serialization and deserialization. + let echoAsyncNullableClassListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableClassList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableClassListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let classListArg: [AllNullableTypes?]? = nilOrValue(args[0]) + api.echoAsyncNullable(classList: classListArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableClassListChannel.setMessageHandler(nil) + } + /// Returns the passed map, to test asynchronous serialization and deserialization. + let echoAsyncNullableMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let mapArg: [AnyHashable?: Any?]? = nilOrValue(args[0]) + api.echoAsyncNullable(mapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableMapChannel.setMessageHandler(nil) + } + /// Returns the passed map, to test asynchronous serialization and deserialization. + let echoAsyncNullableStringMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableStringMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableStringMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let stringMapArg: [String?: String?]? = nilOrValue(args[0]) + api.echoAsyncNullable(stringMap: stringMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableStringMapChannel.setMessageHandler(nil) + } + /// Returns the passed map, to test asynchronous serialization and deserialization. + let echoAsyncNullableIntMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableIntMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableIntMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let intMapArg: [Int64?: Int64?]? = nilOrValue(args[0]) + api.echoAsyncNullable(intMap: intMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableIntMapChannel.setMessageHandler(nil) + } + /// Returns the passed map, to test asynchronous serialization and deserialization. + let echoAsyncNullableEnumMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableEnumMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableEnumMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let enumMapArg: [AnEnum?: AnEnum?]? = args[0] as? [AnEnum?: AnEnum?] + api.echoAsyncNullable(enumMap: enumMapArg!) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableEnumMapChannel.setMessageHandler(nil) + } + /// Returns the passed map, to test asynchronous serialization and deserialization. + let echoAsyncNullableClassMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableClassMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableClassMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let classMapArg: [Int64?: AllNullableTypes?]? = nilOrValue(args[0]) + api.echoAsyncNullable(classMap: classMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableClassMapChannel.setMessageHandler(nil) + } + /// Returns the passed enum, to test asynchronous serialization and deserialization. + let echoAsyncNullableEnumChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableEnum\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableEnumChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let anEnumArg: AnEnum? = nilOrValue(args[0]) + api.echoAsyncNullable(anEnumArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableEnumChannel.setMessageHandler(nil) + } + /// Returns the passed enum, to test asynchronous serialization and deserialization. + let echoAnotherAsyncNullableEnumChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAnotherAsyncNullableEnum\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAnotherAsyncNullableEnumChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let anotherEnumArg: AnotherEnum? = nilOrValue(args[0]) + api.echoAsyncNullable(anotherEnumArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAnotherAsyncNullableEnumChannel.setMessageHandler(nil) + } + let callFlutterNoopChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterNoop\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterNoopChannel.setMessageHandler { _, reply in + api.callFlutterNoop { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterNoopChannel.setMessageHandler(nil) + } + let callFlutterThrowErrorChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterThrowError\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterThrowErrorChannel.setMessageHandler { _, reply in + api.callFlutterThrowError { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterThrowErrorChannel.setMessageHandler(nil) + } + let callFlutterThrowErrorFromVoidChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterThrowErrorFromVoid\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterThrowErrorFromVoidChannel.setMessageHandler { _, reply in + api.callFlutterThrowErrorFromVoid { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterThrowErrorFromVoidChannel.setMessageHandler(nil) + } + let callFlutterEchoAllTypesChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllTypes\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoAllTypesChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let everythingArg = args[0] as! AllTypes + api.callFlutterEcho(everythingArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoAllTypesChannel.setMessageHandler(nil) + } + let callFlutterEchoAllNullableTypesChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypes\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoAllNullableTypesChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let everythingArg: AllNullableTypes? = nilOrValue(args[0]) + api.callFlutterEcho(everythingArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoAllNullableTypesChannel.setMessageHandler(nil) + } + let callFlutterSendMultipleNullableTypesChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypes\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterSendMultipleNullableTypesChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aNullableBoolArg: Bool? = nilOrValue(args[0]) + let aNullableIntArg: Int64? = nilOrValue(args[1]) + let aNullableStringArg: String? = nilOrValue(args[2]) + api.callFlutterSendMultipleNullableTypes( + aBool: aNullableBoolArg, anInt: aNullableIntArg, aString: aNullableStringArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterSendMultipleNullableTypesChannel.setMessageHandler(nil) + } + let callFlutterEchoAllNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypesWithoutRecursion\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoAllNullableTypesWithoutRecursionChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let everythingArg: AllNullableTypesWithoutRecursion? = nilOrValue(args[0]) + api.callFlutterEcho(everythingArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoAllNullableTypesWithoutRecursionChannel.setMessageHandler(nil) + } + let callFlutterSendMultipleNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypesWithoutRecursion\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterSendMultipleNullableTypesWithoutRecursionChannel.setMessageHandler { + message, reply in + let args = message as! [Any?] + let aNullableBoolArg: Bool? = nilOrValue(args[0]) + let aNullableIntArg: Int64? = nilOrValue(args[1]) + let aNullableStringArg: String? = nilOrValue(args[2]) + api.callFlutterSendMultipleNullableTypesWithoutRecursion( + aBool: aNullableBoolArg, anInt: aNullableIntArg, aString: aNullableStringArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterSendMultipleNullableTypesWithoutRecursionChannel.setMessageHandler(nil) + } + let callFlutterEchoBoolChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoBool\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoBoolChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aBoolArg = args[0] as! Bool + api.callFlutterEcho(aBoolArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoBoolChannel.setMessageHandler(nil) + } + let callFlutterEchoIntChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoInt\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoIntChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let anIntArg = args[0] as! Int64 + api.callFlutterEcho(anIntArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoIntChannel.setMessageHandler(nil) + } + let callFlutterEchoDoubleChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoDouble\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoDoubleChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aDoubleArg = args[0] as! Double + api.callFlutterEcho(aDoubleArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoDoubleChannel.setMessageHandler(nil) + } + let callFlutterEchoStringChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoString\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aStringArg = args[0] as! String + api.callFlutterEcho(aStringArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoStringChannel.setMessageHandler(nil) + } + let callFlutterEchoUint8ListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoUint8List\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoUint8ListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let listArg = args[0] as! FlutterStandardTypedData + api.callFlutterEcho(listArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoUint8ListChannel.setMessageHandler(nil) + } + let callFlutterEchoListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let listArg = args[0] as! [Any?] + api.callFlutterEcho(listArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoListChannel.setMessageHandler(nil) + } + let callFlutterEchoEnumListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoEnumList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoEnumListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let enumListArg = args[0] as! [AnEnum?] + api.callFlutterEcho(enumList: enumListArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoEnumListChannel.setMessageHandler(nil) + } + let callFlutterEchoClassListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoClassList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoClassListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let classListArg = args[0] as! [AllNullableTypes?] + api.callFlutterEcho(classList: classListArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoClassListChannel.setMessageHandler(nil) + } + let callFlutterEchoNonNullEnumListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullEnumList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNonNullEnumListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let enumListArg = args[0] as! [AnEnum] + api.callFlutterEchoNonNull(enumList: enumListArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNonNullEnumListChannel.setMessageHandler(nil) + } + let callFlutterEchoNonNullClassListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullClassList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNonNullClassListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let classListArg = args[0] as! [AllNullableTypes] + api.callFlutterEchoNonNull(classList: classListArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNonNullClassListChannel.setMessageHandler(nil) + } + let callFlutterEchoMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let mapArg = args[0] as! [AnyHashable?: Any?] + api.callFlutterEcho(mapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoMapChannel.setMessageHandler(nil) + } + let callFlutterEchoStringMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoStringMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoStringMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let stringMapArg = args[0] as! [String?: String?] + api.callFlutterEcho(stringMap: stringMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoStringMapChannel.setMessageHandler(nil) + } + let callFlutterEchoIntMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoIntMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoIntMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let intMapArg = args[0] as! [Int64?: Int64?] + api.callFlutterEcho(intMap: intMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoIntMapChannel.setMessageHandler(nil) + } + let callFlutterEchoEnumMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoEnumMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoEnumMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let enumMapArg = args[0] as? [AnEnum?: AnEnum?] + api.callFlutterEcho(enumMap: enumMapArg!) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoEnumMapChannel.setMessageHandler(nil) + } + let callFlutterEchoClassMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoClassMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoClassMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let classMapArg = args[0] as! [Int64?: AllNullableTypes?] + api.callFlutterEcho(classMap: classMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoClassMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNonNullStringMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullStringMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNonNullStringMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let stringMapArg = args[0] as! [String: String] + api.callFlutterEchoNonNull(stringMap: stringMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNonNullStringMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNonNullIntMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullIntMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNonNullIntMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let intMapArg = args[0] as! [Int64: Int64] + api.callFlutterEchoNonNull(intMap: intMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNonNullIntMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNonNullEnumMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullEnumMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNonNullEnumMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let enumMapArg = args[0] as? [AnEnum: AnEnum] + api.callFlutterEchoNonNull(enumMap: enumMapArg!) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNonNullEnumMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNonNullClassMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNonNullClassMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNonNullClassMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let classMapArg = args[0] as! [Int64: AllNullableTypes] + api.callFlutterEchoNonNull(classMap: classMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNonNullClassMapChannel.setMessageHandler(nil) + } + let callFlutterEchoEnumChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoEnum\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoEnumChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let anEnumArg = args[0] as! AnEnum + api.callFlutterEcho(anEnumArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoEnumChannel.setMessageHandler(nil) + } + let callFlutterEchoAnotherEnumChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAnotherEnum\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoAnotherEnumChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let anotherEnumArg = args[0] as! AnotherEnum + api.callFlutterEcho(anotherEnumArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoAnotherEnumChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableBoolChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableBool\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableBoolChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aBoolArg: Bool? = nilOrValue(args[0]) + api.callFlutterEchoNullable(aBoolArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableBoolChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableIntChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableInt\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableIntChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let anIntArg: Int64? = nilOrValue(args[0]) + api.callFlutterEchoNullable(anIntArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableIntChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableDoubleChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableDouble\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableDoubleChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aDoubleArg: Double? = nilOrValue(args[0]) + api.callFlutterEchoNullable(aDoubleArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableDoubleChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableStringChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableString\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aStringArg: String? = nilOrValue(args[0]) + api.callFlutterEchoNullable(aStringArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableStringChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableUint8ListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableUint8List\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableUint8ListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let listArg: FlutterStandardTypedData? = nilOrValue(args[0]) + api.callFlutterEchoNullable(listArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableUint8ListChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let listArg: [Any?]? = nilOrValue(args[0]) + api.callFlutterEchoNullable(listArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableListChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableEnumListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableEnumList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableEnumListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let enumListArg: [AnEnum?]? = nilOrValue(args[0]) + api.callFlutterEchoNullable(enumList: enumListArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableEnumListChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableClassListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableClassList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableClassListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let classListArg: [AllNullableTypes?]? = nilOrValue(args[0]) + api.callFlutterEchoNullable(classList: classListArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableClassListChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableNonNullEnumListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullEnumList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableNonNullEnumListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let enumListArg: [AnEnum]? = nilOrValue(args[0]) + api.callFlutterEchoNullableNonNull(enumList: enumListArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableNonNullEnumListChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableNonNullClassListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullClassList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableNonNullClassListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let classListArg: [AllNullableTypes]? = nilOrValue(args[0]) + api.callFlutterEchoNullableNonNull(classList: classListArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableNonNullClassListChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let mapArg: [AnyHashable?: Any?]? = nilOrValue(args[0]) + api.callFlutterEchoNullable(mapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableStringMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableStringMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableStringMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let stringMapArg: [String?: String?]? = nilOrValue(args[0]) + api.callFlutterEchoNullable(stringMap: stringMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableStringMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableIntMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableIntMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableIntMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let intMapArg: [Int64?: Int64?]? = nilOrValue(args[0]) + api.callFlutterEchoNullable(intMap: intMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableIntMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableEnumMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableEnumMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableEnumMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let enumMapArg: [AnEnum?: AnEnum?]? = args[0] as? [AnEnum?: AnEnum?] + api.callFlutterEchoNullable(enumMap: enumMapArg!) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableEnumMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableClassMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableClassMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableClassMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let classMapArg: [Int64?: AllNullableTypes?]? = nilOrValue(args[0]) + api.callFlutterEchoNullable(classMap: classMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableClassMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableNonNullStringMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullStringMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableNonNullStringMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let stringMapArg: [String: String]? = nilOrValue(args[0]) + api.callFlutterEchoNullableNonNull(stringMap: stringMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableNonNullStringMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableNonNullIntMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullIntMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableNonNullIntMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let intMapArg: [Int64: Int64]? = nilOrValue(args[0]) + api.callFlutterEchoNullableNonNull(intMap: intMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableNonNullIntMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableNonNullEnumMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullEnumMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableNonNullEnumMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let enumMapArg: [AnEnum: AnEnum]? = args[0] as? [AnEnum: AnEnum] + api.callFlutterEchoNullableNonNull(enumMap: enumMapArg!) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableNonNullEnumMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableNonNullClassMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableNonNullClassMap\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableNonNullClassMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let classMapArg: [Int64: AllNullableTypes]? = nilOrValue(args[0]) + api.callFlutterEchoNullableNonNull(classMap: classMapArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableNonNullClassMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableEnumChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoNullableEnum\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableEnumChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let anEnumArg: AnEnum? = nilOrValue(args[0]) + api.callFlutterEchoNullable(anEnumArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableEnumChannel.setMessageHandler(nil) + } + let callFlutterEchoAnotherNullableEnumChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAnotherNullableEnum\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoAnotherNullableEnumChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let anotherEnumArg: AnotherEnum? = nilOrValue(args[0]) + api.callFlutterEchoNullable(anotherEnumArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoAnotherNullableEnumChannel.setMessageHandler(nil) + } + let callFlutterSmallApiEchoStringChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSmallApiEchoString\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterSmallApiEchoStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aStringArg = args[0] as! String + api.callFlutterSmallApiEcho(aStringArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterSmallApiEchoStringChannel.setMessageHandler(nil) + } + } +} +/// The core interface that the Dart platform_test code implements for host +/// integration tests to call into. +/// +/// Generated protocol from Pigeon that represents Flutter messages that can be called from Swift. +protocol FlutterIntegrationCoreApiProtocol { + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic calling. + func noop(completion: @escaping (Result) -> Void) + /// Responds with an error from an async function returning a value. + func throwError(completion: @escaping (Result) -> Void) + /// Responds with an error from an async void function. + func throwErrorFromVoid(completion: @escaping (Result) -> Void) + /// Returns the passed object, to test serialization and deserialization. + func echo( + _ everythingArg: AllTypes, completion: @escaping (Result) -> Void) + /// Returns the passed object, to test serialization and deserialization. + func echoNullable( + _ everythingArg: AllNullableTypes?, + completion: @escaping (Result) -> Void) + /// Returns passed in arguments of multiple types. + /// + /// Tests multiple-arity FlutterApi handling. + func sendMultipleNullableTypes( + aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, + aString aNullableStringArg: String?, + completion: @escaping (Result) -> Void) + /// Returns the passed object, to test serialization and deserialization. + func echoNullable( + _ everythingArg: AllNullableTypesWithoutRecursion?, + completion: @escaping (Result) -> Void) + /// Returns passed in arguments of multiple types. + /// + /// Tests multiple-arity FlutterApi handling. + func sendMultipleNullableTypesWithoutRecursion( + aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, + aString aNullableStringArg: String?, + completion: @escaping (Result) -> Void) + /// Returns the passed boolean, to test serialization and deserialization. + func echo(_ aBoolArg: Bool, completion: @escaping (Result) -> Void) + /// Returns the passed int, to test serialization and deserialization. + func echo(_ anIntArg: Int64, completion: @escaping (Result) -> Void) + /// Returns the passed double, to test serialization and deserialization. + func echo(_ aDoubleArg: Double, completion: @escaping (Result) -> Void) + /// Returns the passed string, to test serialization and deserialization. + func echo(_ aStringArg: String, completion: @escaping (Result) -> Void) + /// Returns the passed byte list, to test serialization and deserialization. + func echo( + _ listArg: FlutterStandardTypedData, + completion: @escaping (Result) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func echo(_ listArg: [Any?], completion: @escaping (Result<[Any?], PigeonError>) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func echo( + enumList enumListArg: [AnEnum?], completion: @escaping (Result<[AnEnum?], PigeonError>) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func echo( + classList classListArg: [AllNullableTypes?], + completion: @escaping (Result<[AllNullableTypes?], PigeonError>) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func echoNonNull( + enumList enumListArg: [AnEnum], completion: @escaping (Result<[AnEnum], PigeonError>) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func echoNonNull( + classList classListArg: [AllNullableTypes], + completion: @escaping (Result<[AllNullableTypes], PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echo( + _ mapArg: [AnyHashable?: Any?], + completion: @escaping (Result<[AnyHashable?: Any?], PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echo( + stringMap stringMapArg: [String?: String?], + completion: @escaping (Result<[String?: String?], PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echo( + intMap intMapArg: [Int64?: Int64?], + completion: @escaping (Result<[Int64?: Int64?], PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echo( + enumMap enumMapArg: [AnEnum?: AnEnum?], + completion: @escaping (Result<[AnEnum?: AnEnum?], PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echo( + classMap classMapArg: [Int64?: AllNullableTypes?], + completion: @escaping (Result<[Int64?: AllNullableTypes?], PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNonNull( + stringMap stringMapArg: [String: String], + completion: @escaping (Result<[String: String], PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNonNull( + intMap intMapArg: [Int64: Int64], + completion: @escaping (Result<[Int64: Int64], PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNonNull( + enumMap enumMapArg: [AnEnum: AnEnum], + completion: @escaping (Result<[AnEnum: AnEnum], PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNonNull( + classMap classMapArg: [Int64: AllNullableTypes], + completion: @escaping (Result<[Int64: AllNullableTypes], PigeonError>) -> Void) + /// Returns the passed enum to test serialization and deserialization. + func echo(_ anEnumArg: AnEnum, completion: @escaping (Result) -> Void) + /// Returns the passed enum to test serialization and deserialization. + func echo( + _ anotherEnumArg: AnotherEnum, completion: @escaping (Result) -> Void) + /// Returns the passed boolean, to test serialization and deserialization. + func echoNullable(_ aBoolArg: Bool?, completion: @escaping (Result) -> Void) + /// Returns the passed int, to test serialization and deserialization. + func echoNullable(_ anIntArg: Int64?, completion: @escaping (Result) -> Void) + /// Returns the passed double, to test serialization and deserialization. + func echoNullable( + _ aDoubleArg: Double?, completion: @escaping (Result) -> Void) + /// Returns the passed string, to test serialization and deserialization. + func echoNullable( + _ aStringArg: String?, completion: @escaping (Result) -> Void) + /// Returns the passed byte list, to test serialization and deserialization. + func echoNullable( + _ listArg: FlutterStandardTypedData?, + completion: @escaping (Result) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func echoNullable( + _ listArg: [Any?]?, completion: @escaping (Result<[Any?]?, PigeonError>) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func echoNullable( + enumList enumListArg: [AnEnum?]?, + completion: @escaping (Result<[AnEnum?]?, PigeonError>) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func echoNullable( + classList classListArg: [AllNullableTypes?]?, + completion: @escaping (Result<[AllNullableTypes?]?, PigeonError>) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func echoNullableNonNull( + enumList enumListArg: [AnEnum]?, completion: @escaping (Result<[AnEnum]?, PigeonError>) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func echoNullableNonNull( + classList classListArg: [AllNullableTypes]?, + completion: @escaping (Result<[AllNullableTypes]?, PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNullable( + _ mapArg: [AnyHashable?: Any?]?, + completion: @escaping (Result<[AnyHashable?: Any?]?, PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNullable( + stringMap stringMapArg: [String?: String?]?, + completion: @escaping (Result<[String?: String?]?, PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNullable( + intMap intMapArg: [Int64?: Int64?]?, + completion: @escaping (Result<[Int64?: Int64?]?, PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNullable( + enumMap enumMapArg: [AnEnum?: AnEnum?]?, + completion: @escaping (Result<[AnEnum?: AnEnum?]?, PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNullable( + classMap classMapArg: [Int64?: AllNullableTypes?]?, + completion: @escaping (Result<[Int64?: AllNullableTypes?]?, PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNullableNonNull( + stringMap stringMapArg: [String: String]?, + completion: @escaping (Result<[String: String]?, PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNullableNonNull( + intMap intMapArg: [Int64: Int64]?, + completion: @escaping (Result<[Int64: Int64]?, PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNullableNonNull( + enumMap enumMapArg: [AnEnum: AnEnum]?, + completion: @escaping (Result<[AnEnum: AnEnum]?, PigeonError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNullableNonNull( + classMap classMapArg: [Int64: AllNullableTypes]?, + completion: @escaping (Result<[Int64: AllNullableTypes]?, PigeonError>) -> Void) + /// Returns the passed enum to test serialization and deserialization. + func echoNullable( + _ anEnumArg: AnEnum?, completion: @escaping (Result) -> Void) + /// Returns the passed enum to test serialization and deserialization. + func echoNullable( + _ anotherEnumArg: AnotherEnum?, + completion: @escaping (Result) -> Void) + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic asynchronous calling. + func noopAsync(completion: @escaping (Result) -> Void) + /// Returns the passed in generic Object asynchronously. + func echoAsync(_ aStringArg: String, completion: @escaping (Result) -> Void) +} +class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { + private let binaryMessenger: FlutterBinaryMessenger + private let messageChannelSuffix: String + init(binaryMessenger: FlutterBinaryMessenger, messageChannelSuffix: String = "") { + self.binaryMessenger = binaryMessenger + self.messageChannelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : "" + } + var codec: CoreTestsPigeonCodec { + return CoreTestsPigeonCodec.shared + } + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic calling. + func noop(completion: @escaping (Result) -> Void) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.noop\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage(nil) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + /// Responds with an error from an async function returning a value. + func throwError(completion: @escaping (Result) -> Void) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwError\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage(nil) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + let result: Any? = listResponse[0] + completion(.success(result)) + } + } + } + /// Responds with an error from an async void function. + func throwErrorFromVoid(completion: @escaping (Result) -> Void) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwErrorFromVoid\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage(nil) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + /// Returns the passed object, to test serialization and deserialization. + func echo( + _ everythingArg: AllTypes, completion: @escaping (Result) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllTypes\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([everythingArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! AllTypes + completion(.success(result)) + } + } + } + /// Returns the passed object, to test serialization and deserialization. + func echoNullable( + _ everythingArg: AllNullableTypes?, + completion: @escaping (Result) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypes\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([everythingArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + let result: AllNullableTypes? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } + /// Returns passed in arguments of multiple types. + /// + /// Tests multiple-arity FlutterApi handling. + func sendMultipleNullableTypes( + aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, + aString aNullableStringArg: String?, + completion: @escaping (Result) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypes\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([aNullableBoolArg, aNullableIntArg, aNullableStringArg] as [Any?]) { + response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! AllNullableTypes + completion(.success(result)) + } + } + } + /// Returns the passed object, to test serialization and deserialization. + func echoNullable( + _ everythingArg: AllNullableTypesWithoutRecursion?, + completion: @escaping (Result) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypesWithoutRecursion\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([everythingArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + let result: AllNullableTypesWithoutRecursion? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } + /// Returns passed in arguments of multiple types. + /// + /// Tests multiple-arity FlutterApi handling. + func sendMultipleNullableTypesWithoutRecursion( + aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, + aString aNullableStringArg: String?, + completion: @escaping (Result) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([aNullableBoolArg, aNullableIntArg, aNullableStringArg] as [Any?]) { + response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! AllNullableTypesWithoutRecursion + completion(.success(result)) + } + } + } + /// Returns the passed boolean, to test serialization and deserialization. + func echo(_ aBoolArg: Bool, completion: @escaping (Result) -> Void) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoBool\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([aBoolArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! Bool + completion(.success(result)) + } + } + } + /// Returns the passed int, to test serialization and deserialization. + func echo(_ anIntArg: Int64, completion: @escaping (Result) -> Void) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoInt\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([anIntArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! Int64 + completion(.success(result)) + } + } + } + /// Returns the passed double, to test serialization and deserialization. + func echo(_ aDoubleArg: Double, completion: @escaping (Result) -> Void) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoDouble\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([aDoubleArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! Double + completion(.success(result)) + } + } + } + /// Returns the passed string, to test serialization and deserialization. + func echo(_ aStringArg: String, completion: @escaping (Result) -> Void) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoString\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([aStringArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! String + completion(.success(result)) + } + } + } + /// Returns the passed byte list, to test serialization and deserialization. + func echo( + _ listArg: FlutterStandardTypedData, + completion: @escaping (Result) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoUint8List\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([listArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! FlutterStandardTypedData + completion(.success(result)) + } + } + } /// Returns the passed list, to test serialization and deserialization. - func echo(_ listArg: [Any?], completion: @escaping (Result<[Any?], PigeonError>) -> Void) + func echo(_ listArg: [Any?], completion: @escaping (Result<[Any?], PigeonError>) -> Void) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoList\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([listArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [Any?] + completion(.success(result)) + } + } + } + /// Returns the passed list, to test serialization and deserialization. + func echo( + enumList enumListArg: [AnEnum?], completion: @escaping (Result<[AnEnum?], PigeonError>) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnumList\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([enumListArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [AnEnum?] + completion(.success(result)) + } + } + } + /// Returns the passed list, to test serialization and deserialization. + func echo( + classList classListArg: [AllNullableTypes?], + completion: @escaping (Result<[AllNullableTypes?], PigeonError>) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoClassList\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([classListArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [AllNullableTypes?] + completion(.success(result)) + } + } + } + /// Returns the passed list, to test serialization and deserialization. + func echoNonNull( + enumList enumListArg: [AnEnum], completion: @escaping (Result<[AnEnum], PigeonError>) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullEnumList\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([enumListArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [AnEnum] + completion(.success(result)) + } + } + } + /// Returns the passed list, to test serialization and deserialization. + func echoNonNull( + classList classListArg: [AllNullableTypes], + completion: @escaping (Result<[AllNullableTypes], PigeonError>) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullClassList\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([classListArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [AllNullableTypes] + completion(.success(result)) + } + } + } + /// Returns the passed map, to test serialization and deserialization. + func echo( + _ mapArg: [AnyHashable?: Any?], + completion: @escaping (Result<[AnyHashable?: Any?], PigeonError>) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoMap\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([mapArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [AnyHashable?: Any?] + completion(.success(result)) + } + } + } /// Returns the passed map, to test serialization and deserialization. func echo( - _ aMapArg: [String?: Any?], completion: @escaping (Result<[String?: Any?], PigeonError>) -> Void - ) - /// Returns the passed enum to test serialization and deserialization. - func echo(_ anEnumArg: AnEnum, completion: @escaping (Result) -> Void) - /// Returns the passed boolean, to test serialization and deserialization. - func echoNullable(_ aBoolArg: Bool?, completion: @escaping (Result) -> Void) - /// Returns the passed int, to test serialization and deserialization. - func echoNullable(_ anIntArg: Int64?, completion: @escaping (Result) -> Void) - /// Returns the passed double, to test serialization and deserialization. - func echoNullable( - _ aDoubleArg: Double?, completion: @escaping (Result) -> Void) - /// Returns the passed string, to test serialization and deserialization. - func echoNullable( - _ aStringArg: String?, completion: @escaping (Result) -> Void) - /// Returns the passed byte list, to test serialization and deserialization. - func echoNullable( - _ listArg: FlutterStandardTypedData?, - completion: @escaping (Result) -> Void) - /// Returns the passed list, to test serialization and deserialization. - func echoNullable( - _ listArg: [Any?]?, completion: @escaping (Result<[Any?]?, PigeonError>) -> Void) + stringMap stringMapArg: [String?: String?], + completion: @escaping (Result<[String?: String?], PigeonError>) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoStringMap\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([stringMapArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [String?: String?] + completion(.success(result)) + } + } + } /// Returns the passed map, to test serialization and deserialization. - func echoNullable( - _ aMapArg: [String?: Any?]?, - completion: @escaping (Result<[String?: Any?]?, PigeonError>) -> Void) - /// Returns the passed enum to test serialization and deserialization. - func echoNullable( - _ anEnumArg: AnEnum?, completion: @escaping (Result) -> Void) - /// A no-op function taking no arguments and returning no value, to sanity - /// test basic asynchronous calling. - func noopAsync(completion: @escaping (Result) -> Void) - /// Returns the passed in generic Object asynchronously. - func echoAsync(_ aStringArg: String, completion: @escaping (Result) -> Void) -} -class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { - private let binaryMessenger: FlutterBinaryMessenger - private let messageChannelSuffix: String - init(binaryMessenger: FlutterBinaryMessenger, messageChannelSuffix: String = "") { - self.binaryMessenger = binaryMessenger - self.messageChannelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : "" + func echo( + intMap intMapArg: [Int64?: Int64?], + completion: @escaping (Result<[Int64?: Int64?], PigeonError>) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoIntMap\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([intMapArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [Int64?: Int64?] + completion(.success(result)) + } + } } - var codec: CoreTestsPigeonCodec { - return CoreTestsPigeonCodec.shared + /// Returns the passed map, to test serialization and deserialization. + func echo( + enumMap enumMapArg: [AnEnum?: AnEnum?], + completion: @escaping (Result<[AnEnum?: AnEnum?], PigeonError>) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnumMap\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([enumMapArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as? [AnEnum?: AnEnum?] + completion(.success(result!)) + } + } } - /// A no-op function taking no arguments and returning no value, to sanity - /// test basic calling. - func noop(completion: @escaping (Result) -> Void) { + /// Returns the passed map, to test serialization and deserialization. + func echo( + classMap classMapArg: [Int64?: AllNullableTypes?], + completion: @escaping (Result<[Int64?: AllNullableTypes?], PigeonError>) -> Void + ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.noop\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoClassMap\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage(nil) { response in + channel.sendMessage([classMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2574,18 +4932,28 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - completion(.success(Void())) + let result = listResponse[0] as! [Int64?: AllNullableTypes?] + completion(.success(result)) } } } - /// Responds with an error from an async function returning a value. - func throwError(completion: @escaping (Result) -> Void) { + /// Returns the passed map, to test serialization and deserialization. + func echoNonNull( + stringMap stringMapArg: [String: String], + completion: @escaping (Result<[String: String], PigeonError>) -> Void + ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwError\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullStringMap\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage(nil) { response in + channel.sendMessage([stringMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2595,19 +4963,28 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - let result: Any? = listResponse[0] + let result = listResponse[0] as! [String: String] completion(.success(result)) } } } - /// Responds with an error from an async void function. - func throwErrorFromVoid(completion: @escaping (Result) -> Void) { + /// Returns the passed map, to test serialization and deserialization. + func echoNonNull( + intMap intMapArg: [Int64: Int64], + completion: @escaping (Result<[Int64: Int64], PigeonError>) -> Void + ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwErrorFromVoid\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullIntMap\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage(nil) { response in + channel.sendMessage([intMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2617,20 +4994,117 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - completion(.success(Void())) + let result = listResponse[0] as! [Int64: Int64] + completion(.success(result)) } } } - /// Returns the passed object, to test serialization and deserialization. + /// Returns the passed map, to test serialization and deserialization. + func echoNonNull( + enumMap enumMapArg: [AnEnum: AnEnum], + completion: @escaping (Result<[AnEnum: AnEnum], PigeonError>) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullEnumMap\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([enumMapArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as? [AnEnum: AnEnum] + completion(.success(result!)) + } + } + } + /// Returns the passed map, to test serialization and deserialization. + func echoNonNull( + classMap classMapArg: [Int64: AllNullableTypes], + completion: @escaping (Result<[Int64: AllNullableTypes], PigeonError>) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullClassMap\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([classMapArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [Int64: AllNullableTypes] + completion(.success(result)) + } + } + } + /// Returns the passed enum to test serialization and deserialization. + func echo(_ anEnumArg: AnEnum, completion: @escaping (Result) -> Void) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnum\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([anEnumArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + PigeonError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! AnEnum + completion(.success(result)) + } + } + } + /// Returns the passed enum to test serialization and deserialization. func echo( - _ everythingArg: AllTypes, completion: @escaping (Result) -> Void + _ anotherEnumArg: AnotherEnum, completion: @escaping (Result) -> Void ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllTypes\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAnotherEnum\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([everythingArg] as [Any?]) { response in + channel.sendMessage([anotherEnumArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2647,21 +5121,18 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { code: "null-error", message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - let result = listResponse[0] as! AllTypes + let result = listResponse[0] as! AnotherEnum completion(.success(result)) } } } - /// Returns the passed object, to test serialization and deserialization. - func echoNullable( - _ everythingArg: AllNullableTypes?, - completion: @escaping (Result) -> Void - ) { + /// Returns the passed boolean, to test serialization and deserialization. + func echoNullable(_ aBoolArg: Bool?, completion: @escaping (Result) -> Void) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypes\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableBool\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([everythingArg] as [Any?]) { response in + channel.sendMessage([aBoolArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2672,25 +5143,19 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) } else { - let result: AllNullableTypes? = nilOrValue(listResponse[0]) + let result: Bool? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns passed in arguments of multiple types. - /// - /// Tests multiple-arity FlutterApi handling. - func sendMultipleNullableTypes( - aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, - aString aNullableStringArg: String?, - completion: @escaping (Result) -> Void - ) { + /// Returns the passed int, to test serialization and deserialization. + func echoNullable(_ anIntArg: Int64?, completion: @escaping (Result) -> Void) + { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypes\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableInt\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([aNullableBoolArg, aNullableIntArg, aNullableStringArg] as [Any?]) { - response in + channel.sendMessage([anIntArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2700,28 +5165,21 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) - } else if listResponse[0] == nil { - completion( - .failure( - PigeonError( - code: "null-error", - message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - let result = listResponse[0] as! AllNullableTypes + let result: Int64? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns the passed object, to test serialization and deserialization. + /// Returns the passed double, to test serialization and deserialization. func echoNullable( - _ everythingArg: AllNullableTypesWithoutRecursion?, - completion: @escaping (Result) -> Void + _ aDoubleArg: Double?, completion: @escaping (Result) -> Void ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypesWithoutRecursion\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableDouble\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([everythingArg] as [Any?]) { response in + channel.sendMessage([aDoubleArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2732,25 +5190,20 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) } else { - let result: AllNullableTypesWithoutRecursion? = nilOrValue(listResponse[0]) + let result: Double? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns passed in arguments of multiple types. - /// - /// Tests multiple-arity FlutterApi handling. - func sendMultipleNullableTypesWithoutRecursion( - aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, - aString aNullableStringArg: String?, - completion: @escaping (Result) -> Void + /// Returns the passed string, to test serialization and deserialization. + func echoNullable( + _ aStringArg: String?, completion: @escaping (Result) -> Void ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableString\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([aNullableBoolArg, aNullableIntArg, aNullableStringArg] as [Any?]) { - response in + channel.sendMessage([aStringArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2760,25 +5213,22 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) - } else if listResponse[0] == nil { - completion( - .failure( - PigeonError( - code: "null-error", - message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - let result = listResponse[0] as! AllNullableTypesWithoutRecursion + let result: String? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns the passed boolean, to test serialization and deserialization. - func echo(_ aBoolArg: Bool, completion: @escaping (Result) -> Void) { + /// Returns the passed byte list, to test serialization and deserialization. + func echoNullable( + _ listArg: FlutterStandardTypedData?, + completion: @escaping (Result) -> Void + ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoBool\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableUint8List\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([aBoolArg] as [Any?]) { response in + channel.sendMessage([listArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2788,25 +5238,21 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) - } else if listResponse[0] == nil { - completion( - .failure( - PigeonError( - code: "null-error", - message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - let result = listResponse[0] as! Bool + let result: FlutterStandardTypedData? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns the passed int, to test serialization and deserialization. - func echo(_ anIntArg: Int64, completion: @escaping (Result) -> Void) { + /// Returns the passed list, to test serialization and deserialization. + func echoNullable( + _ listArg: [Any?]?, completion: @escaping (Result<[Any?]?, PigeonError>) -> Void + ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoInt\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableList\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([anIntArg] as [Any?]) { response in + channel.sendMessage([listArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2816,26 +5262,22 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) - } else if listResponse[0] == nil { - completion( - .failure( - PigeonError( - code: "null-error", - message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - let result = - listResponse[0] is Int64 ? listResponse[0] as! Int64 : Int64(listResponse[0] as! Int32) + let result: [Any?]? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns the passed double, to test serialization and deserialization. - func echo(_ aDoubleArg: Double, completion: @escaping (Result) -> Void) { + /// Returns the passed list, to test serialization and deserialization. + func echoNullable( + enumList enumListArg: [AnEnum?]?, + completion: @escaping (Result<[AnEnum?]?, PigeonError>) -> Void + ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoDouble\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableEnumList\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([aDoubleArg] as [Any?]) { response in + channel.sendMessage([enumListArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2845,25 +5287,22 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) - } else if listResponse[0] == nil { - completion( - .failure( - PigeonError( - code: "null-error", - message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - let result = listResponse[0] as! Double + let result: [AnEnum?]? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns the passed string, to test serialization and deserialization. - func echo(_ aStringArg: String, completion: @escaping (Result) -> Void) { + /// Returns the passed list, to test serialization and deserialization. + func echoNullable( + classList classListArg: [AllNullableTypes?]?, + completion: @escaping (Result<[AllNullableTypes?]?, PigeonError>) -> Void + ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoString\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableClassList\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([aStringArg] as [Any?]) { response in + channel.sendMessage([classListArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2873,28 +5312,21 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) - } else if listResponse[0] == nil { - completion( - .failure( - PigeonError( - code: "null-error", - message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - let result = listResponse[0] as! String + let result: [AllNullableTypes?]? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns the passed byte list, to test serialization and deserialization. - func echo( - _ listArg: FlutterStandardTypedData, - completion: @escaping (Result) -> Void + /// Returns the passed list, to test serialization and deserialization. + func echoNullableNonNull( + enumList enumListArg: [AnEnum]?, completion: @escaping (Result<[AnEnum]?, PigeonError>) -> Void ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoUint8List\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullEnumList\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([listArg] as [Any?]) { response in + channel.sendMessage([enumListArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2904,25 +5336,22 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) - } else if listResponse[0] == nil { - completion( - .failure( - PigeonError( - code: "null-error", - message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - let result = listResponse[0] as! FlutterStandardTypedData + let result: [AnEnum]? = nilOrValue(listResponse[0]) completion(.success(result)) } } } /// Returns the passed list, to test serialization and deserialization. - func echo(_ listArg: [Any?], completion: @escaping (Result<[Any?], PigeonError>) -> Void) { + func echoNullableNonNull( + classList classListArg: [AllNullableTypes]?, + completion: @escaping (Result<[AllNullableTypes]?, PigeonError>) -> Void + ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoList\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullClassList\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([listArg] as [Any?]) { response in + channel.sendMessage([classListArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2932,27 +5361,22 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) - } else if listResponse[0] == nil { - completion( - .failure( - PigeonError( - code: "null-error", - message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - let result = listResponse[0] as! [Any?] + let result: [AllNullableTypes]? = nilOrValue(listResponse[0]) completion(.success(result)) } } } /// Returns the passed map, to test serialization and deserialization. - func echo( - _ aMapArg: [String?: Any?], completion: @escaping (Result<[String?: Any?], PigeonError>) -> Void + func echoNullable( + _ mapArg: [AnyHashable?: Any?]?, + completion: @escaping (Result<[AnyHashable?: Any?]?, PigeonError>) -> Void ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoMap\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableMap\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([aMapArg] as [Any?]) { response in + channel.sendMessage([mapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2962,25 +5386,22 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) - } else if listResponse[0] == nil { - completion( - .failure( - PigeonError( - code: "null-error", - message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - let result = listResponse[0] as! [String?: Any?] + let result: [AnyHashable?: Any?]? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns the passed enum to test serialization and deserialization. - func echo(_ anEnumArg: AnEnum, completion: @escaping (Result) -> Void) { + /// Returns the passed map, to test serialization and deserialization. + func echoNullable( + stringMap stringMapArg: [String?: String?]?, + completion: @escaping (Result<[String?: String?]?, PigeonError>) -> Void + ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnum\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableStringMap\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([anEnumArg] as [Any?]) { response in + channel.sendMessage([stringMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -2990,25 +5411,22 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let message: String? = nilOrValue(listResponse[1]) let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) - } else if listResponse[0] == nil { - completion( - .failure( - PigeonError( - code: "null-error", - message: "Flutter api returned null value for non-null return value.", details: ""))) } else { - let result = listResponse[0] as! AnEnum + let result: [String?: String?]? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns the passed boolean, to test serialization and deserialization. - func echoNullable(_ aBoolArg: Bool?, completion: @escaping (Result) -> Void) { + /// Returns the passed map, to test serialization and deserialization. + func echoNullable( + intMap intMapArg: [Int64?: Int64?]?, + completion: @escaping (Result<[Int64?: Int64?]?, PigeonError>) -> Void + ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableBool\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableIntMap\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([aBoolArg] as [Any?]) { response in + channel.sendMessage([intMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -3019,19 +5437,21 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) } else { - let result: Bool? = nilOrValue(listResponse[0]) + let result: [Int64?: Int64?]? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns the passed int, to test serialization and deserialization. - func echoNullable(_ anIntArg: Int64?, completion: @escaping (Result) -> Void) - { + /// Returns the passed map, to test serialization and deserialization. + func echoNullable( + enumMap enumMapArg: [AnEnum?: AnEnum?]?, + completion: @escaping (Result<[AnEnum?: AnEnum?]?, PigeonError>) -> Void + ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableInt\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableEnumMap\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([anIntArg] as [Any?]) { response in + channel.sendMessage([enumMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -3042,24 +5462,21 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) } else { - let result: Int64? = - isNullish(listResponse[0]) - ? nil - : (listResponse[0] is Int64? - ? listResponse[0] as! Int64? : Int64(listResponse[0] as! Int32)) - completion(.success(result)) + let result: [AnEnum?: AnEnum?]? = listResponse[0] as? [AnEnum?: AnEnum?] + completion(.success(result!)) } } } - /// Returns the passed double, to test serialization and deserialization. + /// Returns the passed map, to test serialization and deserialization. func echoNullable( - _ aDoubleArg: Double?, completion: @escaping (Result) -> Void + classMap classMapArg: [Int64?: AllNullableTypes?]?, + completion: @escaping (Result<[Int64?: AllNullableTypes?]?, PigeonError>) -> Void ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableDouble\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableClassMap\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([aDoubleArg] as [Any?]) { response in + channel.sendMessage([classMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -3070,20 +5487,21 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) } else { - let result: Double? = nilOrValue(listResponse[0]) + let result: [Int64?: AllNullableTypes?]? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns the passed string, to test serialization and deserialization. - func echoNullable( - _ aStringArg: String?, completion: @escaping (Result) -> Void + /// Returns the passed map, to test serialization and deserialization. + func echoNullableNonNull( + stringMap stringMapArg: [String: String]?, + completion: @escaping (Result<[String: String]?, PigeonError>) -> Void ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableString\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullStringMap\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([aStringArg] as [Any?]) { response in + channel.sendMessage([stringMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -3094,21 +5512,21 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) } else { - let result: String? = nilOrValue(listResponse[0]) + let result: [String: String]? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns the passed byte list, to test serialization and deserialization. - func echoNullable( - _ listArg: FlutterStandardTypedData?, - completion: @escaping (Result) -> Void + /// Returns the passed map, to test serialization and deserialization. + func echoNullableNonNull( + intMap intMapArg: [Int64: Int64]?, + completion: @escaping (Result<[Int64: Int64]?, PigeonError>) -> Void ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableUint8List\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullIntMap\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([listArg] as [Any?]) { response in + channel.sendMessage([intMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -3119,20 +5537,21 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) } else { - let result: FlutterStandardTypedData? = nilOrValue(listResponse[0]) + let result: [Int64: Int64]? = nilOrValue(listResponse[0]) completion(.success(result)) } } } - /// Returns the passed list, to test serialization and deserialization. - func echoNullable( - _ listArg: [Any?]?, completion: @escaping (Result<[Any?]?, PigeonError>) -> Void + /// Returns the passed map, to test serialization and deserialization. + func echoNullableNonNull( + enumMap enumMapArg: [AnEnum: AnEnum]?, + completion: @escaping (Result<[AnEnum: AnEnum]?, PigeonError>) -> Void ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableList\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullEnumMap\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([listArg] as [Any?]) { response in + channel.sendMessage([enumMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -3143,21 +5562,21 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) } else { - let result: [Any?]? = nilOrValue(listResponse[0]) - completion(.success(result)) + let result: [AnEnum: AnEnum]? = listResponse[0] as? [AnEnum: AnEnum] + completion(.success(result!)) } } } /// Returns the passed map, to test serialization and deserialization. - func echoNullable( - _ aMapArg: [String?: Any?]?, - completion: @escaping (Result<[String?: Any?]?, PigeonError>) -> Void + func echoNullableNonNull( + classMap classMapArg: [Int64: AllNullableTypes]?, + completion: @escaping (Result<[Int64: AllNullableTypes]?, PigeonError>) -> Void ) { let channelName: String = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableMap\(messageChannelSuffix)" + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullClassMap\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel( name: channelName, binaryMessenger: binaryMessenger, codec: codec) - channel.sendMessage([aMapArg] as [Any?]) { response in + channel.sendMessage([classMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) return @@ -3168,7 +5587,7 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { let details: String? = nilOrValue(listResponse[2]) completion(.failure(PigeonError(code: code, message: message, details: details))) } else { - let result: [String?: Any?]? = nilOrValue(listResponse[0]) + let result: [Int64: AllNullableTypes]? = nilOrValue(listResponse[0]) completion(.success(result)) } } @@ -3197,6 +5616,31 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { } } } + /// Returns the passed enum to test serialization and deserialization. + func echoNullable( + _ anotherEnumArg: AnotherEnum?, + completion: @escaping (Result) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAnotherNullableEnum\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([anotherEnumArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + let result: AnotherEnum? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } /// A no-op function taking no arguments and returning no value, to sanity /// test basic asynchronous calling. func noopAsync(completion: @escaping (Result) -> Void) { diff --git a/packages/pigeon/platform_tests/test_plugin/macos/Classes/ProxyApiTestClass.swift b/packages/pigeon/platform_tests/test_plugin/macos/Classes/ProxyApiTestClass.swift new file mode 100644 index 000000000000..f6e7eed44cb4 --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/ProxyApiTestClass.swift @@ -0,0 +1,14 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import Foundation + +class ProxyApiTestClass: ProxyApiSuperClass, ProxyApiInterface {} + +open class ProxyApiSuperClass {} + +protocol ProxyApiInterface {} + +@available(macOS 10, *) +class ClassWithApiRequirement {} diff --git a/packages/pigeon/platform_tests/test_plugin/macos/Classes/ProxyApiTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/macos/Classes/ProxyApiTests.gen.swift new file mode 100644 index 000000000000..d3a699ca47a9 --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/ProxyApiTests.gen.swift @@ -0,0 +1,4191 @@ +// 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, do not edit directly. +// See also: https://pub.dev/packages/pigeon + +import Foundation + +#if os(iOS) + import Flutter +#elseif os(macOS) + import FlutterMacOS +#else + #error("Unsupported platform.") +#endif + +/// Error class for passing custom error details to Dart side. +final class ProxyApiTestsError: Error { + let code: String + let message: String? + let details: Any? + + init(code: String, message: String?, details: Any?) { + self.code = code + self.message = message + self.details = details + } + + var localizedDescription: String { + return + "ProxyApiTestsError(code: \(code), message: \(message ?? ""), details: \(details ?? "")" + } +} + +private func wrapResult(_ result: Any?) -> [Any?] { + return [result] +} + +private func wrapError(_ error: Any) -> [Any?] { + if let pigeonError = error as? ProxyApiTestsError { + return [ + pigeonError.code, + pigeonError.message, + pigeonError.details, + ] + } + if let flutterError = error as? FlutterError { + return [ + flutterError.code, + flutterError.message, + flutterError.details, + ] + } + return [ + "\(error)", + "\(type(of: error))", + "Stacktrace: \(Thread.callStackSymbols)", + ] +} + +private func createConnectionError(withChannelName channelName: String) -> ProxyApiTestsError { + return ProxyApiTestsError( + code: "channel-error", message: "Unable to establish connection on channel: '\(channelName)'.", + details: "") +} + +private func isNullish(_ value: Any?) -> Bool { + return value is NSNull || value == nil +} + +private func nilOrValue(_ value: Any?) -> T? { + if value is NSNull { return nil } + return value as! T? +} +/// Handles the callback when an object is deallocated. +protocol ProxyApiTestsPigeonInternalFinalizerDelegate: AnyObject { + /// Invoked when the strong reference of an object is deallocated in an `InstanceManager`. + func onDeinit(identifier: Int64) +} + +// Attaches to an object to receive a callback when the object is deallocated. +internal final class ProxyApiTestsPigeonInternalFinalizer { + private static let associatedObjectKey = malloc(1)! + + private let identifier: Int64 + // Reference to the delegate is weak because the callback should be ignored if the + // `InstanceManager` is deallocated. + private weak var delegate: ProxyApiTestsPigeonInternalFinalizerDelegate? + + private init(identifier: Int64, delegate: ProxyApiTestsPigeonInternalFinalizerDelegate) { + self.identifier = identifier + self.delegate = delegate + } + + internal static func attach( + to instance: AnyObject, identifier: Int64, + delegate: ProxyApiTestsPigeonInternalFinalizerDelegate + ) { + let finalizer = ProxyApiTestsPigeonInternalFinalizer(identifier: identifier, delegate: delegate) + objc_setAssociatedObject(instance, associatedObjectKey, finalizer, .OBJC_ASSOCIATION_RETAIN) + } + + static func detach(from instance: AnyObject) { + objc_setAssociatedObject(instance, associatedObjectKey, nil, .OBJC_ASSOCIATION_ASSIGN) + } + + deinit { + delegate?.onDeinit(identifier: identifier) + } +} + +/// Maintains instances used to communicate with the corresponding objects in Dart. +/// +/// Objects stored in this container are represented by an object in Dart that is also stored in +/// an InstanceManager with the same identifier. +/// +/// When an instance is added with an identifier, either can be used to retrieve the other. +/// +/// Added instances are added as a weak reference and a strong reference. When the strong +/// reference is removed and the weak reference is deallocated,`ProxyApiTestsPigeonInternalFinalizerDelegate.onDeinit` +/// is called with the instance's identifier. However, if the strong reference is removed and then the identifier is +/// retrieved with the intention to pass the identifier to Dart (e.g. by calling `identifierWithStrongReference`), +/// the strong reference to the instance is re-added. The strong reference will then need to be removed manually +/// again. +/// +/// Accessing and inserting to an InstanceManager is thread safe. +final class ProxyApiTestsPigeonInstanceManager { + // Identifiers are locked to a specific range to avoid collisions with objects + // created simultaneously from Dart. + // Host uses identifiers >= 2^16 and Dart is expected to use values n where, + // 0 <= n < 2^16. + private static let minHostCreatedIdentifier: Int64 = 65536 + + private let lockQueue = DispatchQueue(label: "ProxyApiTestsPigeonInstanceManager") + private let identifiers: NSMapTable = NSMapTable( + keyOptions: [.weakMemory, .objectPointerPersonality], valueOptions: .strongMemory) + private let weakInstances: NSMapTable = NSMapTable( + keyOptions: .strongMemory, valueOptions: [.weakMemory, .objectPointerPersonality]) + private let strongInstances: NSMapTable = NSMapTable( + keyOptions: .strongMemory, valueOptions: [.strongMemory, .objectPointerPersonality]) + private let finalizerDelegate: ProxyApiTestsPigeonInternalFinalizerDelegate + private var nextIdentifier: Int64 = minHostCreatedIdentifier + + public init(finalizerDelegate: ProxyApiTestsPigeonInternalFinalizerDelegate) { + self.finalizerDelegate = finalizerDelegate + } + + /// Adds a new instance that was instantiated from Dart. + /// + /// The same instance can be added multiple times, but each identifier must be unique. This allows + /// two objects that are equivalent (e.g. conforms to `Equatable`) to both be added. + /// + /// - Parameters: + /// - instance: the instance to be stored + /// - identifier: the identifier to be paired with instance. This value must be >= 0 and unique + func addDartCreatedInstance(_ instance: AnyObject, withIdentifier identifier: Int64) { + lockQueue.async { + self.addInstance(instance, withIdentifier: identifier) + } + } + + /// Adds a new instance that was instantiated from the host platform. + /// + /// - Parameters: + /// - instance: the instance to be stored. This must be unique to all other added instances. + /// - Returns: the unique identifier (>= 0) stored with instance + func addHostCreatedInstance(_ instance: AnyObject) -> Int64 { + assert(!containsInstance(instance), "Instance of \(instance) has already been added.") + var identifier: Int64 = -1 + lockQueue.sync { + identifier = nextIdentifier + nextIdentifier += 1 + self.addInstance(instance, withIdentifier: identifier) + } + return identifier + } + + /// Removes `instanceIdentifier` and its associated strongly referenced instance, if present, from the manager. + /// + /// - Parameters: + /// - instanceIdentifier: the identifier paired to an instance. + /// - Returns: removed instance if the manager contains the given identifier, otherwise `nil` if + /// the manager doesn't contain the value + func removeInstance(withIdentifier instanceIdentifier: Int64) throws -> T? { + var instance: AnyObject? = nil + lockQueue.sync { + instance = strongInstances.object(forKey: NSNumber(value: instanceIdentifier)) + strongInstances.removeObject(forKey: NSNumber(value: instanceIdentifier)) + } + return instance as? T + } + + /// Retrieves the instance associated with identifier. + /// + /// - Parameters: + /// - instanceIdentifier: the identifier associated with an instance + /// - Returns: the instance associated with `instanceIdentifier` if the manager contains the value, otherwise + /// `nil` if the manager doesn't contain the value + func instance(forIdentifier instanceIdentifier: Int64) -> T? { + var instance: AnyObject? = nil + lockQueue.sync { + instance = weakInstances.object(forKey: NSNumber(value: instanceIdentifier)) + } + return instance as? T + } + + private func addInstance(_ instance: AnyObject, withIdentifier identifier: Int64) { + assert(identifier >= 0) + assert( + weakInstances.object(forKey: identifier as NSNumber) == nil, + "Identifier has already been added: \(identifier)") + identifiers.setObject(NSNumber(value: identifier), forKey: instance) + weakInstances.setObject(instance, forKey: NSNumber(value: identifier)) + strongInstances.setObject(instance, forKey: NSNumber(value: identifier)) + ProxyApiTestsPigeonInternalFinalizer.attach( + to: instance, identifier: identifier, delegate: finalizerDelegate) + } + + /// Retrieves the identifier paired with an instance. + /// + /// If the manager contains a strong reference to `instance`, it will return the identifier + /// associated with `instance`. If the manager contains only a weak reference to `instance`, a new + /// strong reference to `instance` will be added and will need to be removed again with `removeInstance`. + /// + /// If this method returns a nonnull identifier, this method also expects the Dart + /// `ProxyApiTestsPigeonInstanceManager` to have, or recreate, a weak reference to the Dart instance the + /// identifier is associated with. + /// + /// - Parameters: + /// - instance: an instance that may be stored in the manager + /// - Returns: the identifier associated with `instance` if the manager contains the value, otherwise + /// `nil` if the manager doesn't contain the value + func identifierWithStrongReference(forInstance instance: AnyObject) -> Int64? { + var identifier: Int64? = nil + lockQueue.sync { + if let existingIdentifier = identifiers.object(forKey: instance)?.int64Value { + strongInstances.setObject(instance, forKey: NSNumber(value: existingIdentifier)) + identifier = existingIdentifier + } + } + return identifier + } + + /// Whether this manager contains the given `instance`. + /// + /// - Parameters: + /// - instance: the instance whose presence in this manager is to be tested + /// - Returns: whether this manager contains the given `instance` + func containsInstance(_ instance: AnyObject) -> Bool { + var containsInstance = false + lockQueue.sync { + containsInstance = identifiers.object(forKey: instance) != nil + } + return containsInstance + } + + /// Removes all of the instances from this manager. + /// + /// The manager will be empty after this call returns. + func removeAllObjects() throws { + lockQueue.sync { + identifiers.removeAllObjects() + weakInstances.removeAllObjects() + strongInstances.removeAllObjects() + nextIdentifier = ProxyApiTestsPigeonInstanceManager.minHostCreatedIdentifier + } + } + + /// The number of instances stored as a strong reference. + /// + /// For debugging and testing purposes. + internal var strongInstanceCount: Int { + var count: Int = 0 + lockQueue.sync { + count = strongInstances.count + } + return count + } + + /// The number of instances stored as a weak reference. + /// + /// For debugging and testing purposes. NSMapTables that store keys or objects as weak + /// reference will be reclaimed non-deterministically. + internal var weakInstanceCount: Int { + var count: Int = 0 + lockQueue.sync { + count = weakInstances.count + } + return count + } +} + +private class ProxyApiTestsPigeonInstanceManagerApi { + /// The codec used for serializing messages. + var codec: FlutterStandardMessageCodec { ProxyApiTestsPigeonCodec.shared } + + /// Handles sending and receiving messages with Dart. + unowned let binaryMessenger: FlutterBinaryMessenger + + init(binaryMessenger: FlutterBinaryMessenger) { + self.binaryMessenger = binaryMessenger + } + + /// Sets up an instance of `ProxyApiTestsPigeonInstanceManagerApi` to handle messages through the `binaryMessenger`. + static func setUpMessageHandlers( + binaryMessenger: FlutterBinaryMessenger, instanceManager: ProxyApiTestsPigeonInstanceManager? + ) { + let codec = ProxyApiTestsPigeonCodec.shared + let removeStrongReferenceChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.PigeonInternalInstanceManager.removeStrongReference", + binaryMessenger: binaryMessenger, codec: codec) + if let instanceManager = instanceManager { + removeStrongReferenceChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let identifierArg = args[0] as! Int64 + do { + let _: AnyObject? = try instanceManager.removeInstance(withIdentifier: identifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + removeStrongReferenceChannel.setMessageHandler(nil) + } + let clearChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.PigeonInternalInstanceManager.clear", + binaryMessenger: binaryMessenger, codec: codec) + if let instanceManager = instanceManager { + clearChannel.setMessageHandler { _, reply in + do { + try instanceManager.removeAllObjects() + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + clearChannel.setMessageHandler(nil) + } + } + + /// Sends a message to the Dart `InstanceManager` to remove the strong reference of the instance associated with `identifier`. + func removeStrongReference( + identifier identifierArg: Int64, + completion: @escaping (Result) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.PigeonInternalInstanceManager.removeStrongReference" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([identifierArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} +protocol ProxyApiTestsPigeonProxyApiDelegate { + /// An implementation of [PigeonApiProxyApiTestClass] used to add a new Dart instance of + /// `ProxyApiTestClass` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiProxyApiTestClass(_ registrar: ProxyApiTestsPigeonProxyApiRegistrar) + -> PigeonApiProxyApiTestClass + /// An implementation of [PigeonApiProxyApiSuperClass] used to add a new Dart instance of + /// `ProxyApiSuperClass` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiProxyApiSuperClass(_ registrar: ProxyApiTestsPigeonProxyApiRegistrar) + -> PigeonApiProxyApiSuperClass + /// An implementation of [PigeonApiProxyApiInterface] used to add a new Dart instance of + /// `ProxyApiInterface` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiProxyApiInterface(_ registrar: ProxyApiTestsPigeonProxyApiRegistrar) + -> PigeonApiProxyApiInterface + /// An implementation of [PigeonApiClassWithApiRequirement] used to add a new Dart instance of + /// `ClassWithApiRequirement` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiClassWithApiRequirement(_ registrar: ProxyApiTestsPigeonProxyApiRegistrar) + -> PigeonApiClassWithApiRequirement +} + +extension ProxyApiTestsPigeonProxyApiDelegate { + func pigeonApiProxyApiInterface(_ registrar: ProxyApiTestsPigeonProxyApiRegistrar) + -> PigeonApiProxyApiInterface + { + return PigeonApiProxyApiInterface( + pigeonRegistrar: registrar, delegate: PigeonApiDelegateProxyApiInterface()) + } +} + +open class ProxyApiTestsPigeonProxyApiRegistrar { + let binaryMessenger: FlutterBinaryMessenger + let apiDelegate: ProxyApiTestsPigeonProxyApiDelegate + let instanceManager: ProxyApiTestsPigeonInstanceManager + /// Whether APIs should ignore calling to Dart. + public var ignoreCallsToDart = false + private var _codec: FlutterStandardMessageCodec? + var codec: FlutterStandardMessageCodec { + if _codec == nil { + _codec = FlutterStandardMessageCodec( + readerWriter: ProxyApiTestsPigeonInternalProxyApiCodecReaderWriter(pigeonRegistrar: self)) + } + return _codec! + } + + private class InstanceManagerApiFinalizerDelegate: ProxyApiTestsPigeonInternalFinalizerDelegate { + let api: ProxyApiTestsPigeonInstanceManagerApi + + init(_ api: ProxyApiTestsPigeonInstanceManagerApi) { + self.api = api + } + + public func onDeinit(identifier: Int64) { + api.removeStrongReference(identifier: identifier) { + _ in + } + } + } + + init(binaryMessenger: FlutterBinaryMessenger, apiDelegate: ProxyApiTestsPigeonProxyApiDelegate) { + self.binaryMessenger = binaryMessenger + self.apiDelegate = apiDelegate + self.instanceManager = ProxyApiTestsPigeonInstanceManager( + finalizerDelegate: InstanceManagerApiFinalizerDelegate( + ProxyApiTestsPigeonInstanceManagerApi(binaryMessenger: binaryMessenger))) + } + + func setUp() { + ProxyApiTestsPigeonInstanceManagerApi.setUpMessageHandlers( + binaryMessenger: binaryMessenger, instanceManager: instanceManager) + PigeonApiProxyApiTestClass.setUpMessageHandlers( + binaryMessenger: binaryMessenger, api: apiDelegate.pigeonApiProxyApiTestClass(self)) + PigeonApiProxyApiSuperClass.setUpMessageHandlers( + binaryMessenger: binaryMessenger, api: apiDelegate.pigeonApiProxyApiSuperClass(self)) + PigeonApiClassWithApiRequirement.setUpMessageHandlers( + binaryMessenger: binaryMessenger, api: apiDelegate.pigeonApiClassWithApiRequirement(self)) + } + func tearDown() { + ProxyApiTestsPigeonInstanceManagerApi.setUpMessageHandlers( + binaryMessenger: binaryMessenger, instanceManager: nil) + PigeonApiProxyApiTestClass.setUpMessageHandlers(binaryMessenger: binaryMessenger, api: nil) + PigeonApiProxyApiSuperClass.setUpMessageHandlers(binaryMessenger: binaryMessenger, api: nil) + PigeonApiClassWithApiRequirement.setUpMessageHandlers( + binaryMessenger: binaryMessenger, api: nil) + } +} +private class ProxyApiTestsPigeonInternalProxyApiCodecReaderWriter: FlutterStandardReaderWriter { + unowned let pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar + + private class ProxyApiTestsPigeonInternalProxyApiCodecReader: ProxyApiTestsPigeonCodecReader { + unowned let pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar + + init(data: Data, pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar) { + self.pigeonRegistrar = pigeonRegistrar + super.init(data: data) + } + + override func readValue(ofType type: UInt8) -> Any? { + switch type { + case 128: + let identifier = self.readValue() + let instance: AnyObject? = pigeonRegistrar.instanceManager.instance( + forIdentifier: identifier is Int64 ? identifier as! Int64 : Int64(identifier as! Int32)) + return instance + default: + return super.readValue(ofType: type) + } + } + } + + private class ProxyApiTestsPigeonInternalProxyApiCodecWriter: ProxyApiTestsPigeonCodecWriter { + unowned let pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar + + init(data: NSMutableData, pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar) { + self.pigeonRegistrar = pigeonRegistrar + super.init(data: data) + } + + override func writeValue(_ value: Any) { + if value is [Any] || value is Bool || value is Data || value is [AnyHashable: Any] + || value is Double || value is FlutterStandardTypedData || value is Int64 || value is String + || value is ProxyApiTestEnum + { + super.writeValue(value) + return + } + + if let instance = value as? ProxyApiTestClass { + pigeonRegistrar.apiDelegate.pigeonApiProxyApiTestClass(pigeonRegistrar).pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as? ProxyApiSuperClass { + pigeonRegistrar.apiDelegate.pigeonApiProxyApiSuperClass(pigeonRegistrar).pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as? ProxyApiInterface { + pigeonRegistrar.apiDelegate.pigeonApiProxyApiInterface(pigeonRegistrar).pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if #available(iOS 15.0.0, macOS 10.0.0, *), let instance = value as? ClassWithApiRequirement { + pigeonRegistrar.apiDelegate.pigeonApiClassWithApiRequirement(pigeonRegistrar) + .pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + + if let instance = value as AnyObject?, + pigeonRegistrar.instanceManager.containsInstance(instance) + { + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference(forInstance: instance)!) + } else { + print("Unsupported value: \(value) of \(type(of: value))") + assert(false, "Unsupported value for ProxyApiTestsPigeonInternalProxyApiCodecWriter") + } + + } + } + + init(pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar) { + self.pigeonRegistrar = pigeonRegistrar + } + + override func reader(with data: Data) -> FlutterStandardReader { + return ProxyApiTestsPigeonInternalProxyApiCodecReader( + data: data, pigeonRegistrar: pigeonRegistrar) + } + + override func writer(with data: NSMutableData) -> FlutterStandardWriter { + return ProxyApiTestsPigeonInternalProxyApiCodecWriter( + data: data, pigeonRegistrar: pigeonRegistrar) + } +} + +enum ProxyApiTestEnum: Int { + case one = 0 + case two = 1 + case three = 2 +} + +private class ProxyApiTestsPigeonCodecReader: FlutterStandardReader { + override func readValue(ofType type: UInt8) -> Any? { + switch type { + case 129: + let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?) + if let enumResultAsInt = enumResultAsInt { + return ProxyApiTestEnum(rawValue: enumResultAsInt) + } + return nil + default: + return super.readValue(ofType: type) + } + } +} + +private class ProxyApiTestsPigeonCodecWriter: FlutterStandardWriter { + override func writeValue(_ value: Any) { + if let value = value as? ProxyApiTestEnum { + super.writeByte(129) + super.writeValue(value.rawValue) + } else { + super.writeValue(value) + } + } +} + +private class ProxyApiTestsPigeonCodecReaderWriter: FlutterStandardReaderWriter { + override func reader(with data: Data) -> FlutterStandardReader { + return ProxyApiTestsPigeonCodecReader(data: data) + } + + override func writer(with data: NSMutableData) -> FlutterStandardWriter { + return ProxyApiTestsPigeonCodecWriter(data: data) + } +} + +class ProxyApiTestsPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable { + static let shared = ProxyApiTestsPigeonCodec(readerWriter: ProxyApiTestsPigeonCodecReaderWriter()) +} + +protocol PigeonApiDelegateProxyApiTestClass { + func pigeonDefaultConstructor( + pigeonApi: PigeonApiProxyApiTestClass, aBool: Bool, anInt: Int64, aDouble: Double, + aString: String, aUint8List: FlutterStandardTypedData, aList: [Any?], aMap: [String?: Any?], + anEnum: ProxyApiTestEnum, aProxyApi: ProxyApiSuperClass, aNullableBool: Bool?, + aNullableInt: Int64?, aNullableDouble: Double?, aNullableString: String?, + aNullableUint8List: FlutterStandardTypedData?, aNullableList: [Any?]?, + aNullableMap: [String?: Any?]?, aNullableEnum: ProxyApiTestEnum?, + aNullableProxyApi: ProxyApiSuperClass?, boolParam: Bool, intParam: Int64, doubleParam: Double, + stringParam: String, aUint8ListParam: FlutterStandardTypedData, listParam: [Any?], + mapParam: [String?: Any?], enumParam: ProxyApiTestEnum, proxyApiParam: ProxyApiSuperClass, + nullableBoolParam: Bool?, nullableIntParam: Int64?, nullableDoubleParam: Double?, + nullableStringParam: String?, nullableUint8ListParam: FlutterStandardTypedData?, + nullableListParam: [Any?]?, nullableMapParam: [String?: Any?]?, + nullableEnumParam: ProxyApiTestEnum?, nullableProxyApiParam: ProxyApiSuperClass? + ) throws -> ProxyApiTestClass + func attachedField(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> ProxyApiSuperClass + func staticAttachedField(pigeonApi: PigeonApiProxyApiTestClass) throws -> ProxyApiSuperClass + func aBool(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> Bool + func anInt(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> Int64 + func aDouble(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> Double + func aString(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> String + func aUint8List(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> FlutterStandardTypedData + func aList(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> [Any?] + func aMap(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> [String?: Any?] + func anEnum(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> ProxyApiTestEnum + func aProxyApi(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> ProxyApiSuperClass + func aNullableBool(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> Bool? + func aNullableInt(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> Int64? + func aNullableDouble(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> Double? + func aNullableString(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> String? + func aNullableUint8List(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> FlutterStandardTypedData? + func aNullableList(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> [Any?]? + func aNullableMap(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> [String?: Any?]? + func aNullableEnum(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> ProxyApiTestEnum? + func aNullableProxyApi(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> ProxyApiSuperClass? + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic calling. + func noop(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + /// Returns an error, to test error handling. + func throwError(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> Any? + /// Returns an error from a void function, to test error handling. + func throwErrorFromVoid(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws + /// Returns a Flutter error, to test error handling. + func throwFlutterError(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> Any? + /// Returns passed in int. + func echoInt( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anInt: Int64 + ) throws -> Int64 + /// Returns passed in double. + func echoDouble( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aDouble: Double + ) throws -> Double + /// Returns the passed in boolean. + func echoBool( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aBool: Bool + ) throws -> Bool + /// Returns the passed in string. + func echoString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aString: String + ) throws -> String + /// Returns the passed in Uint8List. + func echoUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aUint8List: FlutterStandardTypedData + ) throws -> FlutterStandardTypedData + /// Returns the passed in generic Object. + func echoObject( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anObject: Any + ) throws -> Any + /// Returns the passed list, to test serialization and deserialization. + func echoList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aList: [Any?] + ) throws -> [Any?] + /// Returns the passed list with ProxyApis, to test serialization and + /// deserialization. + func echoProxyApiList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aList: [ProxyApiTestClass] + ) throws -> [ProxyApiTestClass] + /// Returns the passed map, to test serialization and deserialization. + func echoMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aMap: [String?: Any?] + ) throws -> [String?: Any?] + /// Returns the passed map with ProxyApis, to test serialization and + /// deserialization. + func echoProxyApiMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aMap: [String: ProxyApiTestClass] + ) throws -> [String: ProxyApiTestClass] + /// Returns the passed enum to test serialization and deserialization. + func echoEnum( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum + ) throws -> ProxyApiTestEnum + /// Returns the passed ProxyApi to test serialization and deserialization. + func echoProxyApi( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aProxyApi: ProxyApiSuperClass + ) throws -> ProxyApiSuperClass + /// Returns passed in int. + func echoNullableInt( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aNullableInt: Int64? + ) throws -> Int64? + /// Returns passed in double. + func echoNullableDouble( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableDouble: Double? + ) throws -> Double? + /// Returns the passed in boolean. + func echoNullableBool( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aNullableBool: Bool? + ) throws -> Bool? + /// Returns the passed in string. + func echoNullableString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableString: String? + ) throws -> String? + /// Returns the passed in Uint8List. + func echoNullableUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableUint8List: FlutterStandardTypedData? + ) throws -> FlutterStandardTypedData? + /// Returns the passed in generic Object. + func echoNullableObject( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aNullableObject: Any? + ) throws -> Any? + /// Returns the passed list, to test serialization and deserialization. + func echoNullableList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aNullableList: [Any?]? + ) throws -> [Any?]? + /// Returns the passed map, to test serialization and deserialization. + func echoNullableMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableMap: [String?: Any?]? + ) throws -> [String?: Any?]? + func echoNullableEnum( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableEnum: ProxyApiTestEnum? + ) throws -> ProxyApiTestEnum? + /// Returns the passed ProxyApi to test serialization and deserialization. + func echoNullableProxyApi( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableProxyApi: ProxyApiSuperClass? + ) throws -> ProxyApiSuperClass? + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic asynchronous calling. + func noopAsync( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void) + /// Returns passed in int asynchronously. + func echoAsyncInt( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anInt: Int64, + completion: @escaping (Result) -> Void) + /// Returns passed in double asynchronously. + func echoAsyncDouble( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aDouble: Double, + completion: @escaping (Result) -> Void) + /// Returns the passed in boolean asynchronously. + func echoAsyncBool( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aBool: Bool, + completion: @escaping (Result) -> Void) + /// Returns the passed string asynchronously. + func echoAsyncString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aString: String, + completion: @escaping (Result) -> Void) + /// Returns the passed in Uint8List asynchronously. + func echoAsyncUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aUint8List: FlutterStandardTypedData, + completion: @escaping (Result) -> Void) + /// Returns the passed in generic Object asynchronously. + func echoAsyncObject( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anObject: Any, + completion: @escaping (Result) -> Void) + /// Returns the passed list, to test asynchronous serialization and deserialization. + func echoAsyncList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aList: [Any?], + completion: @escaping (Result<[Any?], Error>) -> Void) + /// Returns the passed map, to test asynchronous serialization and deserialization. + func echoAsyncMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aMap: [String?: Any?], + completion: @escaping (Result<[String?: Any?], Error>) -> Void) + /// Returns the passed enum, to test asynchronous serialization and deserialization. + func echoAsyncEnum( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum, completion: @escaping (Result) -> Void) + /// Responds with an error from an async function returning a value. + func throwAsyncError( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void) + /// Responds with an error from an async void function. + func throwAsyncErrorFromVoid( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void) + /// Responds with a Flutter error from an async function returning a value. + func throwAsyncFlutterError( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void) + /// Returns passed in int asynchronously. + func echoAsyncNullableInt( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anInt: Int64?, + completion: @escaping (Result) -> Void) + /// Returns passed in double asynchronously. + func echoAsyncNullableDouble( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aDouble: Double?, + completion: @escaping (Result) -> Void) + /// Returns the passed in boolean asynchronously. + func echoAsyncNullableBool( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aBool: Bool?, + completion: @escaping (Result) -> Void) + /// Returns the passed string asynchronously. + func echoAsyncNullableString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aString: String?, + completion: @escaping (Result) -> Void) + /// Returns the passed in Uint8List asynchronously. + func echoAsyncNullableUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aUint8List: FlutterStandardTypedData?, + completion: @escaping (Result) -> Void) + /// Returns the passed in generic Object asynchronously. + func echoAsyncNullableObject( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anObject: Any?, + completion: @escaping (Result) -> Void) + /// Returns the passed list, to test asynchronous serialization and deserialization. + func echoAsyncNullableList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aList: [Any?]?, + completion: @escaping (Result<[Any?]?, Error>) -> Void) + /// Returns the passed map, to test asynchronous serialization and deserialization. + func echoAsyncNullableMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aMap: [String?: Any?]?, completion: @escaping (Result<[String?: Any?]?, Error>) -> Void) + /// Returns the passed enum, to test asynchronous serialization and deserialization. + func echoAsyncNullableEnum( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum?, completion: @escaping (Result) -> Void) + func staticNoop(pigeonApi: PigeonApiProxyApiTestClass) throws + func echoStaticString(pigeonApi: PigeonApiProxyApiTestClass, aString: String) throws -> String + func staticAsyncNoop( + pigeonApi: PigeonApiProxyApiTestClass, completion: @escaping (Result) -> Void) + func callFlutterNoop( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void) + func callFlutterThrowError( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void) + func callFlutterThrowErrorFromVoid( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void) + func callFlutterEchoBool( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aBool: Bool, + completion: @escaping (Result) -> Void) + func callFlutterEchoInt( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anInt: Int64, + completion: @escaping (Result) -> Void) + func callFlutterEchoDouble( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aDouble: Double, + completion: @escaping (Result) -> Void) + func callFlutterEchoString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aString: String, + completion: @escaping (Result) -> Void) + func callFlutterEchoUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aUint8List: FlutterStandardTypedData, + completion: @escaping (Result) -> Void) + func callFlutterEchoList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aList: [Any?], + completion: @escaping (Result<[Any?], Error>) -> Void) + func callFlutterEchoProxyApiList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aList: [ProxyApiTestClass?], completion: @escaping (Result<[ProxyApiTestClass?], Error>) -> Void + ) + func callFlutterEchoMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aMap: [String?: Any?], + completion: @escaping (Result<[String?: Any?], Error>) -> Void) + func callFlutterEchoProxyApiMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aMap: [String?: ProxyApiTestClass?], + completion: @escaping (Result<[String?: ProxyApiTestClass?], Error>) -> Void) + func callFlutterEchoEnum( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum, completion: @escaping (Result) -> Void) + func callFlutterEchoProxyApi( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aProxyApi: ProxyApiSuperClass, completion: @escaping (Result) -> Void + ) + func callFlutterEchoNullableBool( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aBool: Bool?, + completion: @escaping (Result) -> Void) + func callFlutterEchoNullableInt( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anInt: Int64?, + completion: @escaping (Result) -> Void) + func callFlutterEchoNullableDouble( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aDouble: Double?, + completion: @escaping (Result) -> Void) + func callFlutterEchoNullableString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aString: String?, + completion: @escaping (Result) -> Void) + func callFlutterEchoNullableUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aUint8List: FlutterStandardTypedData?, + completion: @escaping (Result) -> Void) + func callFlutterEchoNullableList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aList: [Any?]?, + completion: @escaping (Result<[Any?]?, Error>) -> Void) + func callFlutterEchoNullableMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aMap: [String?: Any?]?, completion: @escaping (Result<[String?: Any?]?, Error>) -> Void) + func callFlutterEchoNullableEnum( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum?, completion: @escaping (Result) -> Void) + func callFlutterEchoNullableProxyApi( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aProxyApi: ProxyApiSuperClass?, + completion: @escaping (Result) -> Void) + func callFlutterNoopAsync( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void) + func callFlutterEchoAsyncString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aString: String, + completion: @escaping (Result) -> Void) +} + +protocol PigeonApiProtocolProxyApiTestClass { + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic calling. + func flutterNoop( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, + completion: @escaping (Result) -> Void) + /// Responds with an error from an async function returning a value. + func flutterThrowError( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, + completion: @escaping (Result) -> Void) + /// Responds with an error from an async void function. + func flutterThrowErrorFromVoid( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, + completion: @escaping (Result) -> Void) + /// Returns the passed boolean, to test serialization and deserialization. + func flutterEchoBool( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aBool aBoolArg: Bool, + completion: @escaping (Result) -> Void) + /// Returns the passed int, to test serialization and deserialization. + func flutterEchoInt( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, anInt anIntArg: Int64, + completion: @escaping (Result) -> Void) + /// Returns the passed double, to test serialization and deserialization. + func flutterEchoDouble( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aDouble aDoubleArg: Double, + completion: @escaping (Result) -> Void) + /// Returns the passed string, to test serialization and deserialization. + func flutterEchoString( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aString aStringArg: String, + completion: @escaping (Result) -> Void) + /// Returns the passed byte list, to test serialization and deserialization. + func flutterEchoUint8List( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aList aListArg: FlutterStandardTypedData, + completion: @escaping (Result) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func flutterEchoList( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aList aListArg: [Any?], + completion: @escaping (Result<[Any?], ProxyApiTestsError>) -> Void) + /// Returns the passed list with ProxyApis, to test serialization and + /// deserialization. + func flutterEchoProxyApiList( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aList aListArg: [ProxyApiTestClass?], + completion: @escaping (Result<[ProxyApiTestClass?], ProxyApiTestsError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func flutterEchoMap( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aMap aMapArg: [String?: Any?], + completion: @escaping (Result<[String?: Any?], ProxyApiTestsError>) -> Void) + /// Returns the passed map with ProxyApis, to test serialization and + /// deserialization. + func flutterEchoProxyApiMap( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, + aMap aMapArg: [String?: ProxyApiTestClass?], + completion: @escaping (Result<[String?: ProxyApiTestClass?], ProxyApiTestsError>) -> Void) + /// Returns the passed enum to test serialization and deserialization. + func flutterEchoEnum( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, anEnum anEnumArg: ProxyApiTestEnum, + completion: @escaping (Result) -> Void) + /// Returns the passed ProxyApi to test serialization and deserialization. + func flutterEchoProxyApi( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aProxyApi aProxyApiArg: ProxyApiSuperClass, + completion: @escaping (Result) -> Void) + /// Returns the passed boolean, to test serialization and deserialization. + func flutterEchoNullableBool( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aBool aBoolArg: Bool?, + completion: @escaping (Result) -> Void) + /// Returns the passed int, to test serialization and deserialization. + func flutterEchoNullableInt( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, anInt anIntArg: Int64?, + completion: @escaping (Result) -> Void) + /// Returns the passed double, to test serialization and deserialization. + func flutterEchoNullableDouble( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aDouble aDoubleArg: Double?, + completion: @escaping (Result) -> Void) + /// Returns the passed string, to test serialization and deserialization. + func flutterEchoNullableString( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aString aStringArg: String?, + completion: @escaping (Result) -> Void) + /// Returns the passed byte list, to test serialization and deserialization. + func flutterEchoNullableUint8List( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aList aListArg: FlutterStandardTypedData?, + completion: @escaping (Result) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func flutterEchoNullableList( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aList aListArg: [Any?]?, + completion: @escaping (Result<[Any?]?, ProxyApiTestsError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func flutterEchoNullableMap( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aMap aMapArg: [String?: Any?]?, + completion: @escaping (Result<[String?: Any?]?, ProxyApiTestsError>) -> Void) + /// Returns the passed enum to test serialization and deserialization. + func flutterEchoNullableEnum( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, anEnum anEnumArg: ProxyApiTestEnum?, + completion: @escaping (Result) -> Void) + /// Returns the passed ProxyApi to test serialization and deserialization. + func flutterEchoNullableProxyApi( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, + aProxyApi aProxyApiArg: ProxyApiSuperClass?, + completion: @escaping (Result) -> Void) + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic asynchronous calling. + func flutterNoopAsync( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, + completion: @escaping (Result) -> Void) + /// Returns the passed in generic Object asynchronously. + func flutterEchoAsyncString( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aString aStringArg: String, + completion: @escaping (Result) -> Void) +} + +final class PigeonApiProxyApiTestClass: PigeonApiProtocolProxyApiTestClass { + unowned let pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateProxyApiTestClass + ///An implementation of [ProxyApiSuperClass] used to access callback methods + var pigeonApiProxyApiSuperClass: PigeonApiProxyApiSuperClass { + return pigeonRegistrar.apiDelegate.pigeonApiProxyApiSuperClass(pigeonRegistrar) + } + + ///An implementation of [ProxyApiInterface] used to access callback methods + var pigeonApiProxyApiInterface: PigeonApiProxyApiInterface { + return pigeonRegistrar.apiDelegate.pigeonApiProxyApiInterface(pigeonRegistrar) + } + + init( + pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateProxyApiTestClass + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + static func setUpMessageHandlers( + binaryMessenger: FlutterBinaryMessenger, api: PigeonApiProxyApiTestClass? + ) { + let codec: FlutterStandardMessageCodec = + api != nil + ? FlutterStandardMessageCodec( + readerWriter: ProxyApiTestsPigeonInternalProxyApiCodecReaderWriter( + pigeonRegistrar: api!.pigeonRegistrar)) + : FlutterStandardMessageCodec.sharedInstance() + let pigeonDefaultConstructorChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.pigeon_defaultConstructor", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + pigeonDefaultConstructorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonIdentifierArg = args[0] as! Int64 + let aBoolArg = args[1] as! Bool + let anIntArg = args[2] as! Int64 + let aDoubleArg = args[3] as! Double + let aStringArg = args[4] as! String + let aUint8ListArg = args[5] as! FlutterStandardTypedData + let aListArg = args[6] as! [Any?] + let aMapArg = args[7] as! [String?: Any?] + let anEnumArg = args[8] as! ProxyApiTestEnum + let aProxyApiArg = args[9] as! ProxyApiSuperClass + let aNullableBoolArg: Bool? = nilOrValue(args[10]) + let aNullableIntArg: Int64? = nilOrValue(args[11]) + let aNullableDoubleArg: Double? = nilOrValue(args[12]) + let aNullableStringArg: String? = nilOrValue(args[13]) + let aNullableUint8ListArg: FlutterStandardTypedData? = nilOrValue(args[14]) + let aNullableListArg: [Any?]? = nilOrValue(args[15]) + let aNullableMapArg: [String?: Any?]? = nilOrValue(args[16]) + let aNullableEnumArg: ProxyApiTestEnum? = nilOrValue(args[17]) + let aNullableProxyApiArg: ProxyApiSuperClass? = nilOrValue(args[18]) + let boolParamArg = args[19] as! Bool + let intParamArg = args[20] as! Int64 + let doubleParamArg = args[21] as! Double + let stringParamArg = args[22] as! String + let aUint8ListParamArg = args[23] as! FlutterStandardTypedData + let listParamArg = args[24] as! [Any?] + let mapParamArg = args[25] as! [String?: Any?] + let enumParamArg = args[26] as! ProxyApiTestEnum + let proxyApiParamArg = args[27] as! ProxyApiSuperClass + let nullableBoolParamArg: Bool? = nilOrValue(args[28]) + let nullableIntParamArg: Int64? = nilOrValue(args[29]) + let nullableDoubleParamArg: Double? = nilOrValue(args[30]) + let nullableStringParamArg: String? = nilOrValue(args[31]) + let nullableUint8ListParamArg: FlutterStandardTypedData? = nilOrValue(args[32]) + let nullableListParamArg: [Any?]? = nilOrValue(args[33]) + let nullableMapParamArg: [String?: Any?]? = nilOrValue(args[34]) + let nullableEnumParamArg: ProxyApiTestEnum? = nilOrValue(args[35]) + let nullableProxyApiParamArg: ProxyApiSuperClass? = nilOrValue(args[36]) + do { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + try api.pigeonDelegate.pigeonDefaultConstructor( + pigeonApi: api, aBool: aBoolArg, anInt: anIntArg, aDouble: aDoubleArg, + aString: aStringArg, aUint8List: aUint8ListArg, aList: aListArg, aMap: aMapArg, + anEnum: anEnumArg, aProxyApi: aProxyApiArg, aNullableBool: aNullableBoolArg, + aNullableInt: aNullableIntArg, aNullableDouble: aNullableDoubleArg, + aNullableString: aNullableStringArg, aNullableUint8List: aNullableUint8ListArg, + aNullableList: aNullableListArg, aNullableMap: aNullableMapArg, + aNullableEnum: aNullableEnumArg, aNullableProxyApi: aNullableProxyApiArg, + boolParam: boolParamArg, intParam: intParamArg, doubleParam: doubleParamArg, + stringParam: stringParamArg, aUint8ListParam: aUint8ListParamArg, + listParam: listParamArg, mapParam: mapParamArg, enumParam: enumParamArg, + proxyApiParam: proxyApiParamArg, nullableBoolParam: nullableBoolParamArg, + nullableIntParam: nullableIntParamArg, nullableDoubleParam: nullableDoubleParamArg, + nullableStringParam: nullableStringParamArg, + nullableUint8ListParam: nullableUint8ListParamArg, + nullableListParam: nullableListParamArg, nullableMapParam: nullableMapParamArg, + nullableEnumParam: nullableEnumParamArg, + nullableProxyApiParam: nullableProxyApiParamArg), + withIdentifier: pigeonIdentifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + pigeonDefaultConstructorChannel.setMessageHandler(nil) + } + let attachedFieldChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.attachedField", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + attachedFieldChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let pigeonIdentifierArg = args[1] as! Int64 + do { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + try api.pigeonDelegate.attachedField(pigeonApi: api, pigeonInstance: pigeonInstanceArg), + withIdentifier: pigeonIdentifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + attachedFieldChannel.setMessageHandler(nil) + } + let staticAttachedFieldChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.staticAttachedField", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + staticAttachedFieldChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonIdentifierArg = args[0] as! Int64 + do { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + try api.pigeonDelegate.staticAttachedField(pigeonApi: api), + withIdentifier: pigeonIdentifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + staticAttachedFieldChannel.setMessageHandler(nil) + } + let noopChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.noop", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + noopChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + do { + try api.pigeonDelegate.noop(pigeonApi: api, pigeonInstance: pigeonInstanceArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + noopChannel.setMessageHandler(nil) + } + let throwErrorChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.throwError", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + throwErrorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + do { + let result = try api.pigeonDelegate.throwError( + pigeonApi: api, pigeonInstance: pigeonInstanceArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + throwErrorChannel.setMessageHandler(nil) + } + let throwErrorFromVoidChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.throwErrorFromVoid", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + throwErrorFromVoidChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + do { + try api.pigeonDelegate.throwErrorFromVoid( + pigeonApi: api, pigeonInstance: pigeonInstanceArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + throwErrorFromVoidChannel.setMessageHandler(nil) + } + let throwFlutterErrorChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.throwFlutterError", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + throwFlutterErrorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + do { + let result = try api.pigeonDelegate.throwFlutterError( + pigeonApi: api, pigeonInstance: pigeonInstanceArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + throwFlutterErrorChannel.setMessageHandler(nil) + } + let echoIntChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoInt", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoIntChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anIntArg = args[1] as! Int64 + do { + let result = try api.pigeonDelegate.echoInt( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anInt: anIntArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoIntChannel.setMessageHandler(nil) + } + let echoDoubleChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoDouble", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoDoubleChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aDoubleArg = args[1] as! Double + do { + let result = try api.pigeonDelegate.echoDouble( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aDouble: aDoubleArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoDoubleChannel.setMessageHandler(nil) + } + let echoBoolChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoBool", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoBoolChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aBoolArg = args[1] as! Bool + do { + let result = try api.pigeonDelegate.echoBool( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aBool: aBoolArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoBoolChannel.setMessageHandler(nil) + } + let echoStringChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoString", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aStringArg = args[1] as! String + do { + let result = try api.pigeonDelegate.echoString( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aString: aStringArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoStringChannel.setMessageHandler(nil) + } + let echoUint8ListChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoUint8List", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoUint8ListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aUint8ListArg = args[1] as! FlutterStandardTypedData + do { + let result = try api.pigeonDelegate.echoUint8List( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aUint8List: aUint8ListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoUint8ListChannel.setMessageHandler(nil) + } + let echoObjectChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoObject", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoObjectChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anObjectArg = args[1]! + do { + let result = try api.pigeonDelegate.echoObject( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anObject: anObjectArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoObjectChannel.setMessageHandler(nil) + } + let echoListChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoList", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aListArg = args[1] as! [Any?] + do { + let result = try api.pigeonDelegate.echoList( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aList: aListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoListChannel.setMessageHandler(nil) + } + let echoProxyApiListChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoProxyApiList", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoProxyApiListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aListArg = args[1] as! [ProxyApiTestClass] + do { + let result = try api.pigeonDelegate.echoProxyApiList( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aList: aListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoProxyApiListChannel.setMessageHandler(nil) + } + let echoMapChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoMap", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aMapArg = args[1] as! [String?: Any?] + do { + let result = try api.pigeonDelegate.echoMap( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aMap: aMapArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoMapChannel.setMessageHandler(nil) + } + let echoProxyApiMapChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoProxyApiMap", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoProxyApiMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aMapArg = args[1] as! [String: ProxyApiTestClass] + do { + let result = try api.pigeonDelegate.echoProxyApiMap( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aMap: aMapArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoProxyApiMapChannel.setMessageHandler(nil) + } + let echoEnumChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoEnum", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoEnumChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anEnumArg = args[1] as! ProxyApiTestEnum + do { + let result = try api.pigeonDelegate.echoEnum( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anEnum: anEnumArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoEnumChannel.setMessageHandler(nil) + } + let echoProxyApiChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoProxyApi", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoProxyApiChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aProxyApiArg = args[1] as! ProxyApiSuperClass + do { + let result = try api.pigeonDelegate.echoProxyApi( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aProxyApi: aProxyApiArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoProxyApiChannel.setMessageHandler(nil) + } + let echoNullableIntChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableInt", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoNullableIntChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aNullableIntArg: Int64? = nilOrValue(args[1]) + do { + let result = try api.pigeonDelegate.echoNullableInt( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aNullableInt: aNullableIntArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoNullableIntChannel.setMessageHandler(nil) + } + let echoNullableDoubleChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableDouble", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoNullableDoubleChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aNullableDoubleArg: Double? = nilOrValue(args[1]) + do { + let result = try api.pigeonDelegate.echoNullableDouble( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aNullableDouble: aNullableDoubleArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoNullableDoubleChannel.setMessageHandler(nil) + } + let echoNullableBoolChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableBool", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoNullableBoolChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aNullableBoolArg: Bool? = nilOrValue(args[1]) + do { + let result = try api.pigeonDelegate.echoNullableBool( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aNullableBool: aNullableBoolArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoNullableBoolChannel.setMessageHandler(nil) + } + let echoNullableStringChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableString", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoNullableStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aNullableStringArg: String? = nilOrValue(args[1]) + do { + let result = try api.pigeonDelegate.echoNullableString( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aNullableString: aNullableStringArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoNullableStringChannel.setMessageHandler(nil) + } + let echoNullableUint8ListChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableUint8List", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoNullableUint8ListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aNullableUint8ListArg: FlutterStandardTypedData? = nilOrValue(args[1]) + do { + let result = try api.pigeonDelegate.echoNullableUint8List( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, + aNullableUint8List: aNullableUint8ListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoNullableUint8ListChannel.setMessageHandler(nil) + } + let echoNullableObjectChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableObject", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoNullableObjectChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aNullableObjectArg: Any? = args[1] + do { + let result = try api.pigeonDelegate.echoNullableObject( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aNullableObject: aNullableObjectArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoNullableObjectChannel.setMessageHandler(nil) + } + let echoNullableListChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableList", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoNullableListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aNullableListArg: [Any?]? = nilOrValue(args[1]) + do { + let result = try api.pigeonDelegate.echoNullableList( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aNullableList: aNullableListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoNullableListChannel.setMessageHandler(nil) + } + let echoNullableMapChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableMap", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoNullableMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aNullableMapArg: [String?: Any?]? = nilOrValue(args[1]) + do { + let result = try api.pigeonDelegate.echoNullableMap( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aNullableMap: aNullableMapArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoNullableMapChannel.setMessageHandler(nil) + } + let echoNullableEnumChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableEnum", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoNullableEnumChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aNullableEnumArg: ProxyApiTestEnum? = nilOrValue(args[1]) + do { + let result = try api.pigeonDelegate.echoNullableEnum( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aNullableEnum: aNullableEnumArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoNullableEnumChannel.setMessageHandler(nil) + } + let echoNullableProxyApiChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoNullableProxyApi", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoNullableProxyApiChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aNullableProxyApiArg: ProxyApiSuperClass? = nilOrValue(args[1]) + do { + let result = try api.pigeonDelegate.echoNullableProxyApi( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, + aNullableProxyApi: aNullableProxyApiArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoNullableProxyApiChannel.setMessageHandler(nil) + } + let noopAsyncChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.noopAsync", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + noopAsyncChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + api.pigeonDelegate.noopAsync(pigeonApi: api, pigeonInstance: pigeonInstanceArg) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + noopAsyncChannel.setMessageHandler(nil) + } + let echoAsyncIntChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncInt", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncIntChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anIntArg = args[1] as! Int64 + api.pigeonDelegate.echoAsyncInt( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anInt: anIntArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncIntChannel.setMessageHandler(nil) + } + let echoAsyncDoubleChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncDouble", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncDoubleChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aDoubleArg = args[1] as! Double + api.pigeonDelegate.echoAsyncDouble( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aDouble: aDoubleArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncDoubleChannel.setMessageHandler(nil) + } + let echoAsyncBoolChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncBool", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncBoolChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aBoolArg = args[1] as! Bool + api.pigeonDelegate.echoAsyncBool( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aBool: aBoolArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncBoolChannel.setMessageHandler(nil) + } + let echoAsyncStringChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncString", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aStringArg = args[1] as! String + api.pigeonDelegate.echoAsyncString( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aString: aStringArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncStringChannel.setMessageHandler(nil) + } + let echoAsyncUint8ListChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncUint8List", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncUint8ListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aUint8ListArg = args[1] as! FlutterStandardTypedData + api.pigeonDelegate.echoAsyncUint8List( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aUint8List: aUint8ListArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncUint8ListChannel.setMessageHandler(nil) + } + let echoAsyncObjectChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncObject", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncObjectChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anObjectArg = args[1]! + api.pigeonDelegate.echoAsyncObject( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anObject: anObjectArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncObjectChannel.setMessageHandler(nil) + } + let echoAsyncListChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncList", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aListArg = args[1] as! [Any?] + api.pigeonDelegate.echoAsyncList( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aList: aListArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncListChannel.setMessageHandler(nil) + } + let echoAsyncMapChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncMap", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aMapArg = args[1] as! [String?: Any?] + api.pigeonDelegate.echoAsyncMap( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aMap: aMapArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncMapChannel.setMessageHandler(nil) + } + let echoAsyncEnumChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncEnum", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncEnumChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anEnumArg = args[1] as! ProxyApiTestEnum + api.pigeonDelegate.echoAsyncEnum( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anEnum: anEnumArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncEnumChannel.setMessageHandler(nil) + } + let throwAsyncErrorChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.throwAsyncError", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + throwAsyncErrorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + api.pigeonDelegate.throwAsyncError(pigeonApi: api, pigeonInstance: pigeonInstanceArg) { + result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + throwAsyncErrorChannel.setMessageHandler(nil) + } + let throwAsyncErrorFromVoidChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.throwAsyncErrorFromVoid", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + throwAsyncErrorFromVoidChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + api.pigeonDelegate.throwAsyncErrorFromVoid( + pigeonApi: api, pigeonInstance: pigeonInstanceArg + ) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + throwAsyncErrorFromVoidChannel.setMessageHandler(nil) + } + let throwAsyncFlutterErrorChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.throwAsyncFlutterError", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + throwAsyncFlutterErrorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + api.pigeonDelegate.throwAsyncFlutterError(pigeonApi: api, pigeonInstance: pigeonInstanceArg) + { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + throwAsyncFlutterErrorChannel.setMessageHandler(nil) + } + let echoAsyncNullableIntChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableInt", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableIntChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anIntArg: Int64? = nilOrValue(args[1]) + api.pigeonDelegate.echoAsyncNullableInt( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anInt: anIntArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableIntChannel.setMessageHandler(nil) + } + let echoAsyncNullableDoubleChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableDouble", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableDoubleChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aDoubleArg: Double? = nilOrValue(args[1]) + api.pigeonDelegate.echoAsyncNullableDouble( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aDouble: aDoubleArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableDoubleChannel.setMessageHandler(nil) + } + let echoAsyncNullableBoolChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableBool", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableBoolChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aBoolArg: Bool? = nilOrValue(args[1]) + api.pigeonDelegate.echoAsyncNullableBool( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aBool: aBoolArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableBoolChannel.setMessageHandler(nil) + } + let echoAsyncNullableStringChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableString", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aStringArg: String? = nilOrValue(args[1]) + api.pigeonDelegate.echoAsyncNullableString( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aString: aStringArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableStringChannel.setMessageHandler(nil) + } + let echoAsyncNullableUint8ListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableUint8List", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableUint8ListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aUint8ListArg: FlutterStandardTypedData? = nilOrValue(args[1]) + api.pigeonDelegate.echoAsyncNullableUint8List( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aUint8List: aUint8ListArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableUint8ListChannel.setMessageHandler(nil) + } + let echoAsyncNullableObjectChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableObject", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableObjectChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anObjectArg: Any? = args[1] + api.pigeonDelegate.echoAsyncNullableObject( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anObject: anObjectArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableObjectChannel.setMessageHandler(nil) + } + let echoAsyncNullableListChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableList", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aListArg: [Any?]? = nilOrValue(args[1]) + api.pigeonDelegate.echoAsyncNullableList( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aList: aListArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableListChannel.setMessageHandler(nil) + } + let echoAsyncNullableMapChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableMap", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aMapArg: [String?: Any?]? = nilOrValue(args[1]) + api.pigeonDelegate.echoAsyncNullableMap( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aMap: aMapArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableMapChannel.setMessageHandler(nil) + } + let echoAsyncNullableEnumChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoAsyncNullableEnum", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableEnumChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anEnumArg: ProxyApiTestEnum? = nilOrValue(args[1]) + api.pigeonDelegate.echoAsyncNullableEnum( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anEnum: anEnumArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableEnumChannel.setMessageHandler(nil) + } + let staticNoopChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.staticNoop", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + staticNoopChannel.setMessageHandler { _, reply in + do { + try api.pigeonDelegate.staticNoop(pigeonApi: api) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + staticNoopChannel.setMessageHandler(nil) + } + let echoStaticStringChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.echoStaticString", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoStaticStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aStringArg = args[0] as! String + do { + let result = try api.pigeonDelegate.echoStaticString(pigeonApi: api, aString: aStringArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoStaticStringChannel.setMessageHandler(nil) + } + let staticAsyncNoopChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.staticAsyncNoop", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + staticAsyncNoopChannel.setMessageHandler { _, reply in + api.pigeonDelegate.staticAsyncNoop(pigeonApi: api) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + staticAsyncNoopChannel.setMessageHandler(nil) + } + let callFlutterNoopChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterNoop", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterNoopChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + api.pigeonDelegate.callFlutterNoop(pigeonApi: api, pigeonInstance: pigeonInstanceArg) { + result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterNoopChannel.setMessageHandler(nil) + } + let callFlutterThrowErrorChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterThrowError", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterThrowErrorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + api.pigeonDelegate.callFlutterThrowError(pigeonApi: api, pigeonInstance: pigeonInstanceArg) + { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterThrowErrorChannel.setMessageHandler(nil) + } + let callFlutterThrowErrorFromVoidChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterThrowErrorFromVoid", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterThrowErrorFromVoidChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + api.pigeonDelegate.callFlutterThrowErrorFromVoid( + pigeonApi: api, pigeonInstance: pigeonInstanceArg + ) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterThrowErrorFromVoidChannel.setMessageHandler(nil) + } + let callFlutterEchoBoolChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoBool", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoBoolChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aBoolArg = args[1] as! Bool + api.pigeonDelegate.callFlutterEchoBool( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aBool: aBoolArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoBoolChannel.setMessageHandler(nil) + } + let callFlutterEchoIntChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoInt", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoIntChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anIntArg = args[1] as! Int64 + api.pigeonDelegate.callFlutterEchoInt( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anInt: anIntArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoIntChannel.setMessageHandler(nil) + } + let callFlutterEchoDoubleChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoDouble", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoDoubleChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aDoubleArg = args[1] as! Double + api.pigeonDelegate.callFlutterEchoDouble( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aDouble: aDoubleArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoDoubleChannel.setMessageHandler(nil) + } + let callFlutterEchoStringChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoString", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aStringArg = args[1] as! String + api.pigeonDelegate.callFlutterEchoString( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aString: aStringArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoStringChannel.setMessageHandler(nil) + } + let callFlutterEchoUint8ListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoUint8List", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoUint8ListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aUint8ListArg = args[1] as! FlutterStandardTypedData + api.pigeonDelegate.callFlutterEchoUint8List( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aUint8List: aUint8ListArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoUint8ListChannel.setMessageHandler(nil) + } + let callFlutterEchoListChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoList", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aListArg = args[1] as! [Any?] + api.pigeonDelegate.callFlutterEchoList( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aList: aListArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoListChannel.setMessageHandler(nil) + } + let callFlutterEchoProxyApiListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoProxyApiList", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoProxyApiListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aListArg = args[1] as! [ProxyApiTestClass?] + api.pigeonDelegate.callFlutterEchoProxyApiList( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aList: aListArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoProxyApiListChannel.setMessageHandler(nil) + } + let callFlutterEchoMapChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoMap", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aMapArg = args[1] as! [String?: Any?] + api.pigeonDelegate.callFlutterEchoMap( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aMap: aMapArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoMapChannel.setMessageHandler(nil) + } + let callFlutterEchoProxyApiMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoProxyApiMap", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoProxyApiMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aMapArg = args[1] as! [String?: ProxyApiTestClass?] + api.pigeonDelegate.callFlutterEchoProxyApiMap( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aMap: aMapArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoProxyApiMapChannel.setMessageHandler(nil) + } + let callFlutterEchoEnumChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoEnum", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoEnumChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anEnumArg = args[1] as! ProxyApiTestEnum + api.pigeonDelegate.callFlutterEchoEnum( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anEnum: anEnumArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoEnumChannel.setMessageHandler(nil) + } + let callFlutterEchoProxyApiChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoProxyApi", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoProxyApiChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aProxyApiArg = args[1] as! ProxyApiSuperClass + api.pigeonDelegate.callFlutterEchoProxyApi( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aProxyApi: aProxyApiArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoProxyApiChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableBoolChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableBool", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableBoolChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aBoolArg: Bool? = nilOrValue(args[1]) + api.pigeonDelegate.callFlutterEchoNullableBool( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aBool: aBoolArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableBoolChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableIntChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableInt", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableIntChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anIntArg: Int64? = nilOrValue(args[1]) + api.pigeonDelegate.callFlutterEchoNullableInt( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anInt: anIntArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableIntChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableDoubleChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableDouble", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableDoubleChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aDoubleArg: Double? = nilOrValue(args[1]) + api.pigeonDelegate.callFlutterEchoNullableDouble( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aDouble: aDoubleArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableDoubleChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableStringChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableString", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aStringArg: String? = nilOrValue(args[1]) + api.pigeonDelegate.callFlutterEchoNullableString( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aString: aStringArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableStringChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableUint8ListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableUint8List", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableUint8ListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aUint8ListArg: FlutterStandardTypedData? = nilOrValue(args[1]) + api.pigeonDelegate.callFlutterEchoNullableUint8List( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aUint8List: aUint8ListArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableUint8ListChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableList", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aListArg: [Any?]? = nilOrValue(args[1]) + api.pigeonDelegate.callFlutterEchoNullableList( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aList: aListArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableListChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableMapChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableMap", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableMapChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aMapArg: [String?: Any?]? = nilOrValue(args[1]) + api.pigeonDelegate.callFlutterEchoNullableMap( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aMap: aMapArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableMapChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableEnumChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableEnum", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableEnumChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let anEnumArg: ProxyApiTestEnum? = nilOrValue(args[1]) + api.pigeonDelegate.callFlutterEchoNullableEnum( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, anEnum: anEnumArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableEnumChannel.setMessageHandler(nil) + } + let callFlutterEchoNullableProxyApiChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoNullableProxyApi", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoNullableProxyApiChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aProxyApiArg: ProxyApiSuperClass? = nilOrValue(args[1]) + api.pigeonDelegate.callFlutterEchoNullableProxyApi( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aProxyApi: aProxyApiArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoNullableProxyApiChannel.setMessageHandler(nil) + } + let callFlutterNoopAsyncChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterNoopAsync", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterNoopAsyncChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + api.pigeonDelegate.callFlutterNoopAsync(pigeonApi: api, pigeonInstance: pigeonInstanceArg) { + result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterNoopAsyncChannel.setMessageHandler(nil) + } + let callFlutterEchoAsyncStringChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.callFlutterEchoAsyncString", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoAsyncStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiTestClass + let aStringArg = args[1] as! String + api.pigeonDelegate.callFlutterEchoAsyncString( + pigeonApi: api, pigeonInstance: pigeonInstanceArg, aString: aStringArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoAsyncStringChannel.setMessageHandler(nil) + } + } + + ///Creates a Dart instance of ProxyApiTestClass and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let aBoolArg = try! pigeonDelegate.aBool(pigeonApi: self, pigeonInstance: pigeonInstance) + let anIntArg = try! pigeonDelegate.anInt(pigeonApi: self, pigeonInstance: pigeonInstance) + let aDoubleArg = try! pigeonDelegate.aDouble(pigeonApi: self, pigeonInstance: pigeonInstance) + let aStringArg = try! pigeonDelegate.aString(pigeonApi: self, pigeonInstance: pigeonInstance) + let aUint8ListArg = try! pigeonDelegate.aUint8List( + pigeonApi: self, pigeonInstance: pigeonInstance) + let aListArg = try! pigeonDelegate.aList(pigeonApi: self, pigeonInstance: pigeonInstance) + let aMapArg = try! pigeonDelegate.aMap(pigeonApi: self, pigeonInstance: pigeonInstance) + let anEnumArg = try! pigeonDelegate.anEnum(pigeonApi: self, pigeonInstance: pigeonInstance) + let aProxyApiArg = try! pigeonDelegate.aProxyApi( + pigeonApi: self, pigeonInstance: pigeonInstance) + let aNullableBoolArg = try! pigeonDelegate.aNullableBool( + pigeonApi: self, pigeonInstance: pigeonInstance) + let aNullableIntArg = try! pigeonDelegate.aNullableInt( + pigeonApi: self, pigeonInstance: pigeonInstance) + let aNullableDoubleArg = try! pigeonDelegate.aNullableDouble( + pigeonApi: self, pigeonInstance: pigeonInstance) + let aNullableStringArg = try! pigeonDelegate.aNullableString( + pigeonApi: self, pigeonInstance: pigeonInstance) + let aNullableUint8ListArg = try! pigeonDelegate.aNullableUint8List( + pigeonApi: self, pigeonInstance: pigeonInstance) + let aNullableListArg = try! pigeonDelegate.aNullableList( + pigeonApi: self, pigeonInstance: pigeonInstance) + let aNullableMapArg = try! pigeonDelegate.aNullableMap( + pigeonApi: self, pigeonInstance: pigeonInstance) + let aNullableEnumArg = try! pigeonDelegate.aNullableEnum( + pigeonApi: self, pigeonInstance: pigeonInstance) + let aNullableProxyApiArg = try! pigeonDelegate.aNullableProxyApi( + pigeonApi: self, pigeonInstance: pigeonInstance) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage( + [ + pigeonIdentifierArg, aBoolArg, anIntArg, aDoubleArg, aStringArg, aUint8ListArg, aListArg, + aMapArg, anEnumArg, aProxyApiArg, aNullableBoolArg, aNullableIntArg, aNullableDoubleArg, + aNullableStringArg, aNullableUint8ListArg, aNullableListArg, aNullableMapArg, + aNullableEnumArg, aNullableProxyApiArg, + ] as [Any?] + ) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic calling. + func flutterNoop( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterNoop" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + + /// Responds with an error from an async function returning a value. + func flutterThrowError( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterThrowError" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + let result: Any? = listResponse[0] + completion(.success(result)) + } + } + } + + /// Responds with an error from an async void function. + func flutterThrowErrorFromVoid( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterThrowErrorFromVoid" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + + /// Returns the passed boolean, to test serialization and deserialization. + func flutterEchoBool( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aBool aBoolArg: Bool, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoBool" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aBoolArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + ProxyApiTestsError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! Bool + completion(.success(result)) + } + } + } + + /// Returns the passed int, to test serialization and deserialization. + func flutterEchoInt( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, anInt anIntArg: Int64, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoInt" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, anIntArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + ProxyApiTestsError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! Int64 + completion(.success(result)) + } + } + } + + /// Returns the passed double, to test serialization and deserialization. + func flutterEchoDouble( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aDouble aDoubleArg: Double, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoDouble" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aDoubleArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + ProxyApiTestsError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! Double + completion(.success(result)) + } + } + } + + /// Returns the passed string, to test serialization and deserialization. + func flutterEchoString( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aString aStringArg: String, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoString" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aStringArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + ProxyApiTestsError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! String + completion(.success(result)) + } + } + } + + /// Returns the passed byte list, to test serialization and deserialization. + func flutterEchoUint8List( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aList aListArg: FlutterStandardTypedData, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoUint8List" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aListArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + ProxyApiTestsError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! FlutterStandardTypedData + completion(.success(result)) + } + } + } + + /// Returns the passed list, to test serialization and deserialization. + func flutterEchoList( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aList aListArg: [Any?], + completion: @escaping (Result<[Any?], ProxyApiTestsError>) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoList" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aListArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + ProxyApiTestsError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [Any?] + completion(.success(result)) + } + } + } + + /// Returns the passed list with ProxyApis, to test serialization and + /// deserialization. + func flutterEchoProxyApiList( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aList aListArg: [ProxyApiTestClass?], + completion: @escaping (Result<[ProxyApiTestClass?], ProxyApiTestsError>) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoProxyApiList" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aListArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + ProxyApiTestsError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [ProxyApiTestClass?] + completion(.success(result)) + } + } + } + + /// Returns the passed map, to test serialization and deserialization. + func flutterEchoMap( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aMap aMapArg: [String?: Any?], + completion: @escaping (Result<[String?: Any?], ProxyApiTestsError>) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoMap" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aMapArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + ProxyApiTestsError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [String?: Any?] + completion(.success(result)) + } + } + } + + /// Returns the passed map with ProxyApis, to test serialization and + /// deserialization. + func flutterEchoProxyApiMap( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, + aMap aMapArg: [String?: ProxyApiTestClass?], + completion: @escaping (Result<[String?: ProxyApiTestClass?], ProxyApiTestsError>) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoProxyApiMap" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aMapArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + ProxyApiTestsError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! [String?: ProxyApiTestClass?] + completion(.success(result)) + } + } + } + + /// Returns the passed enum to test serialization and deserialization. + func flutterEchoEnum( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, anEnum anEnumArg: ProxyApiTestEnum, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoEnum" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, anEnumArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + ProxyApiTestsError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! ProxyApiTestEnum + completion(.success(result)) + } + } + } + + /// Returns the passed ProxyApi to test serialization and deserialization. + func flutterEchoProxyApi( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aProxyApi aProxyApiArg: ProxyApiSuperClass, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoProxyApi" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aProxyApiArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + ProxyApiTestsError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! ProxyApiSuperClass + completion(.success(result)) + } + } + } + + /// Returns the passed boolean, to test serialization and deserialization. + func flutterEchoNullableBool( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aBool aBoolArg: Bool?, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableBool" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aBoolArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + let result: Bool? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } + + /// Returns the passed int, to test serialization and deserialization. + func flutterEchoNullableInt( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, anInt anIntArg: Int64?, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableInt" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, anIntArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + let result: Int64? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } + + /// Returns the passed double, to test serialization and deserialization. + func flutterEchoNullableDouble( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aDouble aDoubleArg: Double?, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableDouble" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aDoubleArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + let result: Double? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } + + /// Returns the passed string, to test serialization and deserialization. + func flutterEchoNullableString( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aString aStringArg: String?, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableString" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aStringArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + let result: String? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } + + /// Returns the passed byte list, to test serialization and deserialization. + func flutterEchoNullableUint8List( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aList aListArg: FlutterStandardTypedData?, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableUint8List" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aListArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + let result: FlutterStandardTypedData? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } + + /// Returns the passed list, to test serialization and deserialization. + func flutterEchoNullableList( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aList aListArg: [Any?]?, + completion: @escaping (Result<[Any?]?, ProxyApiTestsError>) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableList" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aListArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + let result: [Any?]? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } + + /// Returns the passed map, to test serialization and deserialization. + func flutterEchoNullableMap( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aMap aMapArg: [String?: Any?]?, + completion: @escaping (Result<[String?: Any?]?, ProxyApiTestsError>) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableMap" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aMapArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + let result: [String?: Any?]? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } + + /// Returns the passed enum to test serialization and deserialization. + func flutterEchoNullableEnum( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, anEnum anEnumArg: ProxyApiTestEnum?, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableEnum" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, anEnumArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + let result: ProxyApiTestEnum? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } + + /// Returns the passed ProxyApi to test serialization and deserialization. + func flutterEchoNullableProxyApi( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, + aProxyApi aProxyApiArg: ProxyApiSuperClass?, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableProxyApi" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aProxyApiArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + let result: ProxyApiSuperClass? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } + + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic asynchronous calling. + func flutterNoopAsync( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterNoopAsync" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + + /// Returns the passed in generic Object asynchronously. + func flutterEchoAsyncString( + pigeonInstance pigeonInstanceArg: ProxyApiTestClass, aString aStringArg: String, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoAsyncString" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg, aStringArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + ProxyApiTestsError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! String + completion(.success(result)) + } + } + } + +} +protocol PigeonApiDelegateProxyApiSuperClass { + func pigeonDefaultConstructor(pigeonApi: PigeonApiProxyApiSuperClass) throws -> ProxyApiSuperClass + func aSuperMethod(pigeonApi: PigeonApiProxyApiSuperClass, pigeonInstance: ProxyApiSuperClass) + throws +} + +protocol PigeonApiProtocolProxyApiSuperClass { +} + +final class PigeonApiProxyApiSuperClass: PigeonApiProtocolProxyApiSuperClass { + unowned let pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateProxyApiSuperClass + init( + pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateProxyApiSuperClass + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + static func setUpMessageHandlers( + binaryMessenger: FlutterBinaryMessenger, api: PigeonApiProxyApiSuperClass? + ) { + let codec: FlutterStandardMessageCodec = + api != nil + ? FlutterStandardMessageCodec( + readerWriter: ProxyApiTestsPigeonInternalProxyApiCodecReaderWriter( + pigeonRegistrar: api!.pigeonRegistrar)) + : FlutterStandardMessageCodec.sharedInstance() + let pigeonDefaultConstructorChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiSuperClass.pigeon_defaultConstructor", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + pigeonDefaultConstructorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonIdentifierArg = args[0] as! Int64 + do { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + try api.pigeonDelegate.pigeonDefaultConstructor(pigeonApi: api), + withIdentifier: pigeonIdentifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + pigeonDefaultConstructorChannel.setMessageHandler(nil) + } + let aSuperMethodChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiSuperClass.aSuperMethod", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + aSuperMethodChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ProxyApiSuperClass + do { + try api.pigeonDelegate.aSuperMethod(pigeonApi: api, pigeonInstance: pigeonInstanceArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + aSuperMethodChannel.setMessageHandler(nil) + } + } + + ///Creates a Dart instance of ProxyApiSuperClass and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: ProxyApiSuperClass, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiSuperClass.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonIdentifierArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} +open class PigeonApiDelegateProxyApiInterface { +} + +protocol PigeonApiProtocolProxyApiInterface { + func anInterfaceMethod( + pigeonInstance pigeonInstanceArg: ProxyApiInterface, + completion: @escaping (Result) -> Void) +} + +final class PigeonApiProxyApiInterface: PigeonApiProtocolProxyApiInterface { + unowned let pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateProxyApiInterface + init( + pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateProxyApiInterface + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + ///Creates a Dart instance of ProxyApiInterface and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: ProxyApiInterface, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiInterface.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonIdentifierArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + func anInterfaceMethod( + pigeonInstance pigeonInstanceArg: ProxyApiInterface, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ProxyApiInterface.anInterfaceMethod" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonInstanceArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } + +} +protocol PigeonApiDelegateClassWithApiRequirement { + @available(iOS 15.0.0, macOS 10.0.0, *) + func pigeonDefaultConstructor(pigeonApi: PigeonApiClassWithApiRequirement) throws + -> ClassWithApiRequirement + @available(iOS 15.0.0, macOS 10.0.0, *) + func aMethod(pigeonApi: PigeonApiClassWithApiRequirement, pigeonInstance: ClassWithApiRequirement) + throws +} + +protocol PigeonApiProtocolClassWithApiRequirement { +} + +final class PigeonApiClassWithApiRequirement: PigeonApiProtocolClassWithApiRequirement { + unowned let pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateClassWithApiRequirement + init( + pigeonRegistrar: ProxyApiTestsPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateClassWithApiRequirement + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + static func setUpMessageHandlers( + binaryMessenger: FlutterBinaryMessenger, api: PigeonApiClassWithApiRequirement? + ) { + let codec: FlutterStandardMessageCodec = + api != nil + ? FlutterStandardMessageCodec( + readerWriter: ProxyApiTestsPigeonInternalProxyApiCodecReaderWriter( + pigeonRegistrar: api!.pigeonRegistrar)) + : FlutterStandardMessageCodec.sharedInstance() + if #available(iOS 15.0.0, macOS 10.0.0, *) { + let pigeonDefaultConstructorChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ClassWithApiRequirement.pigeon_defaultConstructor", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + pigeonDefaultConstructorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonIdentifierArg = args[0] as! Int64 + do { + api.pigeonRegistrar.instanceManager.addDartCreatedInstance( + try api.pigeonDelegate.pigeonDefaultConstructor(pigeonApi: api), + withIdentifier: pigeonIdentifierArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + pigeonDefaultConstructorChannel.setMessageHandler(nil) + } + } else { + let pigeonDefaultConstructorChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.ClassWithApiRequirement.pigeon_defaultConstructor", + binaryMessenger: binaryMessenger, codec: codec) + if api != nil { + pigeonDefaultConstructorChannel.setMessageHandler { message, reply in + reply( + wrapError( + FlutterError( + code: "PigeonUnsupportedOperationError", + message: + "Call to pigeonDefaultConstructor requires @available(iOS 15.0.0, macOS 10.0.0, *).", + details: nil + ))) + } + } else { + pigeonDefaultConstructorChannel.setMessageHandler(nil) + } + } + if #available(iOS 15.0.0, macOS 10.0.0, *) { + let aMethodChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ClassWithApiRequirement.aMethod", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + aMethodChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let pigeonInstanceArg = args[0] as! ClassWithApiRequirement + do { + try api.pigeonDelegate.aMethod(pigeonApi: api, pigeonInstance: pigeonInstanceArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + aMethodChannel.setMessageHandler(nil) + } + } else { + let aMethodChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.pigeon_integration_tests.ClassWithApiRequirement.aMethod", + binaryMessenger: binaryMessenger, codec: codec) + if api != nil { + aMethodChannel.setMessageHandler { message, reply in + reply( + wrapError( + FlutterError( + code: "PigeonUnsupportedOperationError", + message: "Call to aMethod requires @available(iOS 15.0.0, macOS 10.0.0, *).", + details: nil + ))) + } + } else { + aMethodChannel.setMessageHandler(nil) + } + } + } + + ///Creates a Dart instance of ClassWithApiRequirement and attaches it to [pigeonInstance]. + @available(iOS 15.0.0, macOS 10.0.0, *) + func pigeonNewInstance( + pigeonInstance: ClassWithApiRequirement, + completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + ProxyApiTestsError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.ClassWithApiRequirement.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([pigeonIdentifierArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(ProxyApiTestsError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} diff --git a/packages/pigeon/platform_tests/test_plugin/macos/Classes/TestPlugin.swift b/packages/pigeon/platform_tests/test_plugin/macos/Classes/TestPlugin.swift index 5a6497366415..fb5c21dabf18 100644 --- a/packages/pigeon/platform_tests/test_plugin/macos/Classes/TestPlugin.swift +++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/TestPlugin.swift @@ -11,12 +11,14 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { var flutterAPI: FlutterIntegrationCoreApi var flutterSmallApiOne: FlutterSmallApi var flutterSmallApiTwo: FlutterSmallApi + var proxyApiRegistrar: ProxyApiTestsPigeonProxyApiRegistrar? public static func register(with registrar: FlutterPluginRegistrar) { let plugin = TestPlugin(binaryMessenger: registrar.messenger) HostIntegrationCoreApiSetup.setUp(binaryMessenger: registrar.messenger, api: plugin) TestPluginWithSuffix.register(with: registrar, suffix: "suffixOne") TestPluginWithSuffix.register(with: registrar, suffix: "suffixTwo") + registrar.publish(plugin) } init(binaryMessenger: FlutterBinaryMessenger) { @@ -25,6 +27,14 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { binaryMessenger: binaryMessenger, messageChannelSuffix: "suffixOne") flutterSmallApiTwo = FlutterSmallApi( binaryMessenger: binaryMessenger, messageChannelSuffix: "suffixTwo") + proxyApiRegistrar = ProxyApiTestsPigeonProxyApiRegistrar( + binaryMessenger: binaryMessenger, apiDelegate: ProxyApiDelegate()) + proxyApiRegistrar!.setUp() + } + + public func detachFromEngine(for registrar: FlutterPluginRegistrar) { + proxyApiRegistrar!.tearDown() + proxyApiRegistrar = nil } // MARK: HostIntegrationCoreApi implementation @@ -86,8 +96,56 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { return list } - func echo(_ aMap: [String?: Any?]) throws -> [String?: Any?] { - return aMap + func echo(enumList: [AnEnum?]) throws -> [AnEnum?] { + return enumList + } + + func echo(classList: [AllNullableTypes?]) throws -> [AllNullableTypes?] { + return classList + } + + func echoNonNull(enumList: [AnEnum]) throws -> [AnEnum] { + return enumList + } + + func echoNonNull(classList: [AllNullableTypes]) throws -> [AllNullableTypes] { + return classList + } + + func echo(_ map: [AnyHashable?: Any?]) throws -> [AnyHashable?: Any?] { + return map + } + + func echo(stringMap: [String?: String?]) throws -> [String?: String?] { + return stringMap + } + + func echo(intMap: [Int64?: Int64?]) throws -> [Int64?: Int64?] { + return intMap + } + + func echo(enumMap: [AnEnum?: AnEnum?]) throws -> [AnEnum?: AnEnum?] { + return enumMap + } + + func echo(classMap: [Int64?: AllNullableTypes?]) throws -> [Int64?: AllNullableTypes?] { + return classMap + } + + func echoNonNull(stringMap: [String: String]) throws -> [String: String] { + return stringMap + } + + func echoNonNull(intMap: [Int64: Int64]) throws -> [Int64: Int64] { + return intMap + } + + func echoNonNull(enumMap: [AnEnum: AnEnum]) throws -> [AnEnum: AnEnum] { + return enumMap + } + + func echoNonNull(classMap: [Int64: AllNullableTypes]) throws -> [Int64: AllNullableTypes] { + return classMap } func echo(_ wrapper: AllClassesWrapper) throws -> AllClassesWrapper { @@ -98,12 +156,18 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { return anEnum } + func echo(_ anotherEnum: AnotherEnum) throws -> AnotherEnum { + return anotherEnum + } + func extractNestedNullableString(from wrapper: AllClassesWrapper) -> String? { return wrapper.allNullableTypes.aNullableString } func createNestedObject(with nullableString: String?) -> AllClassesWrapper { - return AllClassesWrapper(allNullableTypes: AllNullableTypes(aNullableString: nullableString)) + return AllClassesWrapper( + allNullableTypes: AllNullableTypes(aNullableString: nullableString), classList: [], + classMap: [:]) } func sendMultipleNullableTypes( @@ -162,14 +226,68 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { return aNullableList } - func echoNullable(_ aNullableMap: [String?: Any?]?) throws -> [String?: Any?]? { - return aNullableMap + func echoNullable(enumList: [AnEnum?]?) throws -> [AnEnum?]? { + return enumList + } + + func echoNullable(classList: [AllNullableTypes?]?) throws -> [AllNullableTypes?]? { + return classList + } + + func echoNullableNonNull(enumList: [AnEnum]?) throws -> [AnEnum]? { + return enumList + } + + func echoNullableNonNull(classList: [AllNullableTypes]?) throws -> [AllNullableTypes]? { + return classList + } + + func echoNullable(_ map: [AnyHashable?: Any?]?) throws -> [AnyHashable?: Any?]? { + return map + } + + func echoNullable(stringMap: [String?: String?]?) throws -> [String?: String?]? { + return stringMap + } + + func echoNullable(intMap: [Int64?: Int64?]?) throws -> [Int64?: Int64?]? { + return intMap + } + + func echoNullable(enumMap: [AnEnum?: AnEnum?]?) throws -> [AnEnum?: AnEnum?]? { + return enumMap + } + + func echoNullable(classMap: [Int64?: AllNullableTypes?]?) throws -> [Int64?: AllNullableTypes?]? { + return classMap + } + + func echoNullableNonNull(stringMap: [String: String]?) throws -> [String: String]? { + return stringMap + } + + func echoNullableNonNull(intMap: [Int64: Int64]?) throws -> [Int64: Int64]? { + return intMap + } + + func echoNullableNonNull(enumMap: [AnEnum: AnEnum]?) throws -> [AnEnum: AnEnum]? { + return enumMap + } + + func echoNullableNonNull(classMap: [Int64: AllNullableTypes]?) throws -> [Int64: + AllNullableTypes]? + { + return classMap } func echoNullable(_ anEnum: AnEnum?) throws -> AnEnum? { return anEnum } + func echoNullable(_ anotherEnum: AnotherEnum?) throws -> AnotherEnum? { + return anotherEnum + } + func echoOptional(_ aNullableInt: Int64?) throws -> Int64? { return aNullableInt } @@ -243,16 +361,58 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { completion(.success(list)) } + func echoAsync(enumList: [AnEnum?], completion: @escaping (Result<[AnEnum?], Error>) -> Void) { + completion(.success(enumList)) + } + + func echoAsync( + classList: [AllNullableTypes?], + completion: @escaping (Result<[AllNullableTypes?], Error>) -> Void + ) { + completion(.success(classList)) + } + + func echoAsync( + _ map: [AnyHashable?: Any?], completion: @escaping (Result<[AnyHashable?: Any?], Error>) -> Void + ) { + completion(.success(map)) + } + + func echoAsync( + stringMap: [String?: String?], completion: @escaping (Result<[String?: String?], Error>) -> Void + ) { + completion(.success(stringMap)) + } + + func echoAsync( + intMap: [Int64?: Int64?], completion: @escaping (Result<[Int64?: Int64?], Error>) -> Void + ) { + completion(.success(intMap)) + } + + func echoAsync( + enumMap: [AnEnum?: AnEnum?], completion: @escaping (Result<[AnEnum?: AnEnum?], Error>) -> Void + ) { + completion(.success(enumMap)) + } + func echoAsync( - _ aMap: [String?: Any?], completion: @escaping (Result<[String?: Any?], Error>) -> Void + classMap: [Int64?: AllNullableTypes?], + completion: @escaping (Result<[Int64?: AllNullableTypes?], Error>) -> Void ) { - completion(.success(aMap)) + completion(.success(classMap)) } func echoAsync(_ anEnum: AnEnum, completion: @escaping (Result) -> Void) { completion(.success(anEnum)) } + func echoAsync( + _ anotherEnum: AnotherEnum, completion: @escaping (Result) -> Void + ) { + completion(.success(anotherEnum)) + } + func echoAsyncNullable(_ anInt: Int64?, completion: @escaping (Result) -> Void) { completion(.success(anInt)) } @@ -287,16 +447,63 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { } func echoAsyncNullable( - _ aMap: [String?: Any?]?, completion: @escaping (Result<[String?: Any?]?, Error>) -> Void + enumList: [AnEnum?]?, completion: @escaping (Result<[AnEnum?]?, Error>) -> Void ) { - completion(.success(aMap)) + completion(.success(enumList)) } - func echoAsyncNullable(_ anEnum: AnEnum?, completion: @escaping (Result) -> Void) - { + func echoAsyncNullable( + classList: [AllNullableTypes?]?, + completion: @escaping (Result<[AllNullableTypes?]?, Error>) -> Void + ) { + completion(.success(classList)) + } + + func echoAsyncNullable( + _ map: [AnyHashable?: Any?]?, + completion: @escaping (Result<[AnyHashable?: Any?]?, Error>) -> Void + ) { + completion(.success(map)) + } + + func echoAsyncNullable( + stringMap: [String?: String?]?, + completion: @escaping (Result<[String?: String?]?, Error>) -> Void + ) { + completion(.success(stringMap)) + } + + func echoAsyncNullable( + intMap: [Int64?: Int64?]?, completion: @escaping (Result<[Int64?: Int64?]?, Error>) -> Void + ) { + completion(.success(intMap)) + } + + func echoAsyncNullable( + enumMap: [AnEnum?: AnEnum?]?, completion: @escaping (Result<[AnEnum?: AnEnum?]?, Error>) -> Void + ) { + completion(.success(enumMap)) + } + + func echoAsyncNullable( + classMap: [Int64?: AllNullableTypes?]?, + completion: @escaping (Result<[Int64?: AllNullableTypes?]?, Error>) -> Void + ) { + completion(.success(classMap)) + } + + func echoAsyncNullable( + _ anEnum: AnEnum?, completion: @escaping (Result) -> Void + ) { completion(.success(anEnum)) } + func echoAsyncNullable( + _ anotherEnum: AnotherEnum?, completion: @escaping (Result) -> Void + ) { + completion(.success(anotherEnum)) + } + func callFlutterNoop(completion: @escaping (Result) -> Void) { flutterAPI.noop { response in switch response { @@ -479,9 +686,168 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { } func callFlutterEcho( - _ aMap: [String?: Any?], completion: @escaping (Result<[String?: Any?], Error>) -> Void + enumList: [AnEnum?], completion: @escaping (Result<[AnEnum?], Error>) -> Void + ) { + flutterAPI.echo(enumList: enumList) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEcho( + classList: [AllNullableTypes?], + completion: @escaping (Result<[AllNullableTypes?], Error>) -> Void + ) { + flutterAPI.echo(classList: classList) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNonNull( + enumList: [AnEnum], completion: @escaping (Result<[AnEnum], Error>) -> Void + ) { + flutterAPI.echoNonNull(enumList: enumList) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNonNull( + classList: [AllNullableTypes], completion: @escaping (Result<[AllNullableTypes], Error>) -> Void + ) { + flutterAPI.echoNonNull(classList: classList) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEcho( + _ map: [AnyHashable?: Any?], completion: @escaping (Result<[AnyHashable?: Any?], Error>) -> Void + ) { + flutterAPI.echo(map) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEcho( + stringMap: [String?: String?], completion: @escaping (Result<[String?: String?], Error>) -> Void + ) { + flutterAPI.echo(stringMap: stringMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEcho( + intMap: [Int64?: Int64?], completion: @escaping (Result<[Int64?: Int64?], Error>) -> Void + ) { + flutterAPI.echo(intMap: intMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEcho( + enumMap: [AnEnum?: AnEnum?], completion: @escaping (Result<[AnEnum?: AnEnum?], Error>) -> Void + ) { + flutterAPI.echo(enumMap: enumMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEcho( + classMap: [Int64?: AllNullableTypes?], + completion: @escaping (Result<[Int64?: AllNullableTypes?], Error>) -> Void + ) { + flutterAPI.echo(classMap: classMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNonNull( + stringMap: [String: String], completion: @escaping (Result<[String: String], Error>) -> Void + ) { + flutterAPI.echoNonNull(stringMap: stringMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNonNull( + intMap: [Int64: Int64], completion: @escaping (Result<[Int64: Int64], Error>) -> Void + ) { + flutterAPI.echoNonNull(intMap: intMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNonNull( + enumMap: [AnEnum: AnEnum], completion: @escaping (Result<[AnEnum: AnEnum], Error>) -> Void + ) { + flutterAPI.echoNonNull(enumMap: enumMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNonNull( + classMap: [Int64: AllNullableTypes], + completion: @escaping (Result<[Int64: AllNullableTypes], Error>) -> Void ) { - flutterAPI.echo(aMap) { response in + flutterAPI.echoNonNull(classMap: classMap) { response in switch response { case .success(let res): completion(.success(res)) @@ -491,7 +857,9 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { } } - func callFlutterEcho(_ anEnum: AnEnum, completion: @escaping (Result) -> Void) { + func callFlutterEcho( + _ anEnum: AnEnum, completion: @escaping (Result) -> Void + ) { flutterAPI.echo(anEnum) { response in switch response { case .success(let res): @@ -502,6 +870,19 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { } } + func callFlutterEcho( + _ anotherEnum: AnotherEnum, completion: @escaping (Result) -> Void + ) { + flutterAPI.echo(anotherEnum) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + func callFlutterEchoNullable(_ aBool: Bool?, completion: @escaping (Result) -> Void) { flutterAPI.echoNullable(aBool) { response in @@ -581,9 +962,9 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { } func callFlutterEchoNullable( - _ aMap: [String?: Any?]?, completion: @escaping (Result<[String?: Any?]?, Error>) -> Void + enumList: [AnEnum?]?, completion: @escaping (Result<[AnEnum?]?, Error>) -> Void ) { - flutterAPI.echoNullable(aMap) { response in + flutterAPI.echoNullable(enumList: enumList) { response in switch response { case .success(let res): completion(.success(res)) @@ -593,10 +974,11 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { } } - func callFlutterNullableEcho( - _ anEnum: AnEnum?, completion: @escaping (Result) -> Void + func callFlutterEchoNullable( + classList: [AllNullableTypes?]?, + completion: @escaping (Result<[AllNullableTypes?]?, Error>) -> Void ) { - flutterAPI.echoNullable(anEnum) { response in + flutterAPI.echoNullable(classList: classList) { response in switch response { case .success(let res): completion(.success(res)) @@ -606,7 +988,181 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { } } - func callFlutterSmallApiEcho( + func callFlutterEchoNullableNonNull( + enumList: [AnEnum]?, completion: @escaping (Result<[AnEnum]?, Error>) -> Void + ) { + flutterAPI.echoNullableNonNull(enumList: enumList) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableNonNull( + classList: [AllNullableTypes]?, + completion: @escaping (Result<[AllNullableTypes]?, Error>) -> Void + ) { + flutterAPI.echoNullableNonNull(classList: classList) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullable( + _ map: [AnyHashable?: Any?]?, + completion: @escaping (Result<[AnyHashable?: Any?]?, Error>) -> Void + ) { + flutterAPI.echoNullable(map) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullable( + stringMap: [String?: String?]?, + completion: @escaping (Result<[String?: String?]?, Error>) -> Void + ) { + flutterAPI.echoNullable(stringMap: stringMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullable( + intMap: [Int64?: Int64?]?, completion: @escaping (Result<[Int64?: Int64?]?, Error>) -> Void + ) { + flutterAPI.echoNullable(intMap: intMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullable( + enumMap: [AnEnum?: AnEnum?]?, completion: @escaping (Result<[AnEnum?: AnEnum?]?, Error>) -> Void + ) { + flutterAPI.echoNullable(enumMap: enumMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullable( + classMap: [Int64?: AllNullableTypes?]?, + completion: @escaping (Result<[Int64?: AllNullableTypes?]?, Error>) -> Void + ) { + flutterAPI.echoNullable(classMap: classMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableNonNull( + stringMap: [String: String]?, completion: @escaping (Result<[String: String]?, Error>) -> Void + ) { + flutterAPI.echoNullableNonNull(stringMap: stringMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableNonNull( + intMap: [Int64: Int64]?, completion: @escaping (Result<[Int64: Int64]?, Error>) -> Void + ) { + flutterAPI.echoNullableNonNull(intMap: intMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableNonNull( + enumMap: [AnEnum: AnEnum]?, completion: @escaping (Result<[AnEnum: AnEnum]?, Error>) -> Void + ) { + flutterAPI.echoNullableNonNull(enumMap: enumMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableNonNull( + classMap: [Int64: AllNullableTypes]?, + completion: @escaping (Result<[Int64: AllNullableTypes]?, Error>) -> Void + ) { + flutterAPI.echoNullableNonNull(classMap: classMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullable( + _ anEnum: AnEnum?, completion: @escaping (Result) -> Void + ) { + flutterAPI.echoNullable(anEnum) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullable( + _ anotherEnum: AnotherEnum?, completion: @escaping (Result) -> Void + ) { + flutterAPI.echoNullable(anotherEnum) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterSmallApiEcho( _ aString: String, completion: @escaping (Result) -> Void ) { flutterSmallApiOne.echo(string: aString) { responseOne in @@ -634,6 +1190,10 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { } } } + + func testUnusedClassesGenerate() -> UnusedClass { + return UnusedClass() + } } public class TestPluginWithSuffix: HostSmallApi { @@ -652,3 +1212,910 @@ public class TestPluginWithSuffix: HostSmallApi { } } + +class ProxyApiDelegate: ProxyApiTestsPigeonProxyApiDelegate { + func pigeonApiProxyApiTestClass(_ registrar: ProxyApiTestsPigeonProxyApiRegistrar) + -> PigeonApiProxyApiTestClass + { + class ProxyApiTestClassDelegate: PigeonApiDelegateProxyApiTestClass { + func pigeonDefaultConstructor( + pigeonApi: PigeonApiProxyApiTestClass, aBool: Bool, anInt: Int64, aDouble: Double, + aString: String, aUint8List: FlutterStandardTypedData, aList: [Any?], aMap: [String?: Any?], + anEnum: ProxyApiTestEnum, aProxyApi: ProxyApiSuperClass, aNullableBool: Bool?, + aNullableInt: Int64?, aNullableDouble: Double?, aNullableString: String?, + aNullableUint8List: FlutterStandardTypedData?, aNullableList: [Any?]?, + aNullableMap: [String?: Any?]?, aNullableEnum: ProxyApiTestEnum?, + aNullableProxyApi: ProxyApiSuperClass?, boolParam: Bool, intParam: Int64, + doubleParam: Double, stringParam: String, aUint8ListParam: FlutterStandardTypedData, + listParam: [Any?], mapParam: [String?: Any?], enumParam: ProxyApiTestEnum, + proxyApiParam: ProxyApiSuperClass, nullableBoolParam: Bool?, nullableIntParam: Int64?, + nullableDoubleParam: Double?, nullableStringParam: String?, + nullableUint8ListParam: FlutterStandardTypedData?, nullableListParam: [Any?]?, + nullableMapParam: [String?: Any?]?, nullableEnumParam: ProxyApiTestEnum?, + nullableProxyApiParam: ProxyApiSuperClass? + ) throws -> ProxyApiTestClass { + return ProxyApiTestClass() + } + + func attachedField(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> ProxyApiSuperClass + { + return ProxyApiSuperClass() + } + + func staticAttachedField(pigeonApi: PigeonApiProxyApiTestClass) throws -> ProxyApiSuperClass { + return ProxyApiSuperClass() + } + + func aBool(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> Bool + { + return true + } + + func anInt(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> Int64 + { + return 0 + } + + func aDouble(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> Double + { + return 0.0 + } + + func aString(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> String + { + return "" + } + + func aUint8List(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> FlutterStandardTypedData + { + return FlutterStandardTypedData(bytes: Data()) + } + + func aList(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> [Any?] + { + return [] + } + + func aMap(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> [String?: Any?] + { + return [:] + } + + func anEnum(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws + -> ProxyApiTestEnum + { + return ProxyApiTestEnum.one + } + + func aProxyApi(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> ProxyApiSuperClass + { + return ProxyApiSuperClass() + } + + func aNullableBool(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> Bool? + { + return nil + } + + func aNullableInt(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> Int64? + { + return nil + } + + func aNullableDouble(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> Double? + { + return nil + } + + func aNullableString(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> String? + { + return nil + } + + func aNullableUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass + ) throws -> FlutterStandardTypedData? { + return nil + } + + func aNullableList(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> [Any?]? + { + return nil + } + + func aNullableMap(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> [String?: Any?]? + { + return nil + } + + func aNullableEnum(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> ProxyApiTestEnum? + { + return nil + } + + func aNullableProxyApi( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass + ) throws -> ProxyApiSuperClass? { + return nil + } + + func noop(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) throws { + } + + func throwError(pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass) + throws -> Any? + { + throw ProxyApiTestsError(code: "code", message: "message", details: "details") + } + + func throwErrorFromVoid( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass + ) throws { + throw ProxyApiTestsError(code: "code", message: "message", details: "details") + } + + func throwFlutterError( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass + ) throws -> Any? { + throw ProxyApiTestsError(code: "code", message: "message", details: "details") + } + + func echoInt( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anInt: Int64 + ) throws -> Int64 { + return anInt + } + + func echoDouble( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aDouble: Double + ) throws -> Double { + return aDouble + } + + func echoBool( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aBool: Bool + ) throws -> Bool { + return aBool + } + + func echoString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aString: String + ) throws -> String { + return aString + } + + func echoUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aUint8List: FlutterStandardTypedData + ) throws -> FlutterStandardTypedData { + return aUint8List + } + + func echoObject( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anObject: Any + ) throws -> Any { + return anObject + } + + func echoList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aList: [Any?] + ) throws -> [Any?] { + return aList + } + + func echoProxyApiList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aList: [ProxyApiTestClass] + ) throws -> [ProxyApiTestClass] { + return aList + } + + func echoMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aMap: [String?: Any?] + ) throws -> [String?: Any?] { + return aMap + } + + func echoProxyApiMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aMap: [String: ProxyApiTestClass] + ) throws -> [String: ProxyApiTestClass] { + return aMap + } + + func echoEnum( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum + ) throws -> ProxyApiTestEnum { + return anEnum + } + + func echoProxyApi( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aProxyApi: ProxyApiSuperClass + ) throws -> ProxyApiSuperClass { + return aProxyApi + } + + func echoNullableInt( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableInt: Int64? + ) throws -> Int64? { + return aNullableInt + } + + func echoNullableDouble( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableDouble: Double? + ) throws -> Double? { + return aNullableDouble + } + + func echoNullableBool( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableBool: Bool? + ) throws -> Bool? { + return aNullableBool + } + + func echoNullableString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableString: String? + ) throws -> String? { + return aNullableString + } + + func echoNullableUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableUint8List: FlutterStandardTypedData? + ) throws -> FlutterStandardTypedData? { + return aNullableUint8List + } + + func echoNullableObject( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableObject: Any? + ) throws -> Any? { + return aNullableObject + } + + func echoNullableList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableList: [Any?]? + ) throws -> [Any?]? { + return aNullableList + } + + func echoNullableMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableMap: [String?: Any?]? + ) throws -> [String?: Any?]? { + return aNullableMap + } + + func echoNullableEnum( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableEnum: ProxyApiTestEnum? + ) throws -> ProxyApiTestEnum? { + return aNullableEnum + } + + func echoNullableProxyApi( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aNullableProxyApi: ProxyApiSuperClass? + ) throws -> ProxyApiSuperClass? { + return aNullableProxyApi + } + + func noopAsync( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + completion(.success(Void())) + } + + func echoAsyncInt( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anInt: Int64, + completion: @escaping (Result) -> Void + ) { + completion(.success(anInt)) + } + + func echoAsyncDouble( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aDouble: Double, + completion: @escaping (Result) -> Void + ) { + completion(.success(aDouble)) + } + + func echoAsyncBool( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aBool: Bool, + completion: @escaping (Result) -> Void + ) { + completion(.success(aBool)) + } + + func echoAsyncString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aString: String, + completion: @escaping (Result) -> Void + ) { + completion(.success(aString)) + } + + func echoAsyncUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aUint8List: FlutterStandardTypedData, + completion: @escaping (Result) -> Void + ) { + completion(.success(aUint8List)) + } + + func echoAsyncObject( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anObject: Any, + completion: @escaping (Result) -> Void + ) { + completion(.success(anObject)) + } + + func echoAsyncList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aList: [Any?], + completion: @escaping (Result<[Any?], Error>) -> Void + ) { + completion(.success(aList)) + } + + func echoAsyncMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aMap: [String?: Any?], completion: @escaping (Result<[String?: Any?], Error>) -> Void + ) { + completion(.success(aMap)) + } + + func echoAsyncEnum( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum, completion: @escaping (Result) -> Void + ) { + completion(.success(anEnum)) + } + + func throwAsyncError( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + completion( + .failure(ProxyApiTestsError(code: "code", message: "message", details: "details"))) + } + + func throwAsyncErrorFromVoid( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + completion( + .failure(ProxyApiTestsError(code: "code", message: "message", details: "details"))) + } + + func throwAsyncFlutterError( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + completion( + .failure(ProxyApiTestsError(code: "code", message: "message", details: "details"))) + } + + func echoAsyncNullableInt( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anInt: Int64?, + completion: @escaping (Result) -> Void + ) { + completion(.success(anInt)) + } + + func echoAsyncNullableDouble( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aDouble: Double?, + completion: @escaping (Result) -> Void + ) { + completion(.success(aDouble)) + } + + func echoAsyncNullableBool( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aBool: Bool?, + completion: @escaping (Result) -> Void + ) { + completion(.success(aBool)) + } + + func echoAsyncNullableString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aString: String?, + completion: @escaping (Result) -> Void + ) { + completion(.success(aString)) + } + + func echoAsyncNullableUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aUint8List: FlutterStandardTypedData?, + completion: @escaping (Result) -> Void + ) { + completion(.success(aUint8List)) + } + + func echoAsyncNullableObject( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anObject: Any?, + completion: @escaping (Result) -> Void + ) { + completion(.success(anObject)) + } + + func echoAsyncNullableList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aList: [Any?]?, + completion: @escaping (Result<[Any?]?, Error>) -> Void + ) { + completion(.success(aList)) + } + + func echoAsyncNullableMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aMap: [String?: Any?]?, completion: @escaping (Result<[String?: Any?]?, Error>) -> Void + ) { + completion(.success(aMap)) + } + + func echoAsyncNullableEnum( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum?, completion: @escaping (Result) -> Void + ) { + completion(.success(anEnum)) + } + + func staticNoop(pigeonApi: PigeonApiProxyApiTestClass) throws { + + } + + func echoStaticString(pigeonApi: PigeonApiProxyApiTestClass, aString: String) throws -> String + { + return aString + } + + func staticAsyncNoop( + pigeonApi: PigeonApiProxyApiTestClass, completion: @escaping (Result) -> Void + ) { + completion(.success(Void())) + } + + func callFlutterNoop( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterNoop(pigeonInstance: pigeonInstance) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterThrowError( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterThrowError(pigeonInstance: pigeonInstance) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterThrowErrorFromVoid( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterThrowErrorFromVoid(pigeonInstance: pigeonInstance) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoBool( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aBool: Bool, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoBool(pigeonInstance: pigeonInstance, aBool: aBool) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoInt( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anInt: Int64, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoInt(pigeonInstance: pigeonInstance, anInt: anInt) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoDouble( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aDouble: Double, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoDouble(pigeonInstance: pigeonInstance, aDouble: aDouble) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aString: String, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoString(pigeonInstance: pigeonInstance, aString: aString) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aUint8List: FlutterStandardTypedData, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoUint8List(pigeonInstance: pigeonInstance, aList: aUint8List) { + response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aList: [Any?], + completion: @escaping (Result<[Any?], Error>) -> Void + ) { + pigeonApi.flutterEchoList(pigeonInstance: pigeonInstance, aList: aList) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoProxyApiList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aList: [ProxyApiTestClass?], + completion: @escaping (Result<[ProxyApiTestClass?], Error>) -> Void + ) { + pigeonApi.flutterEchoProxyApiList(pigeonInstance: pigeonInstance, aList: aList) { + response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aMap: [String?: Any?], completion: @escaping (Result<[String?: Any?], Error>) -> Void + ) { + pigeonApi.flutterEchoMap(pigeonInstance: pigeonInstance, aMap: aMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoProxyApiMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aMap: [String?: ProxyApiTestClass?], + completion: @escaping (Result<[String?: ProxyApiTestClass?], Error>) -> Void + ) { + pigeonApi.flutterEchoProxyApiMap(pigeonInstance: pigeonInstance, aMap: aMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoEnum( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum, completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoEnum(pigeonInstance: pigeonInstance, anEnum: anEnum) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoProxyApi( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aProxyApi: ProxyApiSuperClass, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoProxyApi(pigeonInstance: pigeonInstance, aProxyApi: aProxyApi) { + response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableBool( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aBool: Bool?, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoNullableBool(pigeonInstance: pigeonInstance, aBool: aBool) { + response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableInt( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, anInt: Int64?, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoNullableInt(pigeonInstance: pigeonInstance, anInt: anInt) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableDouble( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aDouble: Double?, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoNullableDouble(pigeonInstance: pigeonInstance, aDouble: aDouble) { + response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aString: String?, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoNullableString(pigeonInstance: pigeonInstance, aString: aString) { + response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableUint8List( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aUint8List: FlutterStandardTypedData?, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoNullableUint8List(pigeonInstance: pigeonInstance, aList: aUint8List) { + response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableList( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aList: [Any?]?, + completion: @escaping (Result<[Any?]?, Error>) -> Void + ) { + pigeonApi.flutterEchoNullableList(pigeonInstance: pigeonInstance, aList: aList) { + response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableMap( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aMap: [String?: Any?]?, completion: @escaping (Result<[String?: Any?]?, Error>) -> Void + ) { + pigeonApi.flutterEchoNullableMap(pigeonInstance: pigeonInstance, aMap: aMap) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableEnum( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + anEnum: ProxyApiTestEnum?, completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoNullableEnum(pigeonInstance: pigeonInstance, anEnum: anEnum) { + response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoNullableProxyApi( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + aProxyApi: ProxyApiSuperClass?, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoNullableProxyApi(pigeonInstance: pigeonInstance, aProxyApi: aProxyApi) + { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterNoopAsync( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterNoopAsync(pigeonInstance: pigeonInstance) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func callFlutterEchoAsyncString( + pigeonApi: PigeonApiProxyApiTestClass, pigeonInstance: ProxyApiTestClass, aString: String, + completion: @escaping (Result) -> Void + ) { + pigeonApi.flutterEchoAsyncString(pigeonInstance: pigeonInstance, aString: aString) { + response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + } + return PigeonApiProxyApiTestClass( + pigeonRegistrar: registrar, delegate: ProxyApiTestClassDelegate()) + } + + func pigeonApiProxyApiSuperClass(_ registrar: ProxyApiTestsPigeonProxyApiRegistrar) + -> PigeonApiProxyApiSuperClass + { + class ProxyApiSuperClassDelegate: PigeonApiDelegateProxyApiSuperClass { + func pigeonDefaultConstructor(pigeonApi: PigeonApiProxyApiSuperClass) throws + -> ProxyApiSuperClass + { + return ProxyApiSuperClass() + } + + func aSuperMethod(pigeonApi: PigeonApiProxyApiSuperClass, pigeonInstance: ProxyApiSuperClass) + throws + {} + } + return PigeonApiProxyApiSuperClass( + pigeonRegistrar: registrar, delegate: ProxyApiSuperClassDelegate()) + } + + func pigeonApiProxyApiInterface(_ registrar: ProxyApiTestsPigeonProxyApiRegistrar) + -> PigeonApiProxyApiInterface + { + class ProxyApiInterfaceDelegate: PigeonApiDelegateProxyApiInterface {} + return PigeonApiProxyApiInterface( + pigeonRegistrar: registrar, delegate: ProxyApiInterfaceDelegate()) + } + + func pigeonApiClassWithApiRequirement(_ registrar: ProxyApiTestsPigeonProxyApiRegistrar) + -> PigeonApiClassWithApiRequirement + { + class ClassWithApiRequirementDelegate: PigeonApiDelegateClassWithApiRequirement { + @available(macOS 10, *) + func pigeonDefaultConstructor(pigeonApi: PigeonApiClassWithApiRequirement) throws + -> ClassWithApiRequirement + { + return ClassWithApiRequirement() + } + + @available(macOS 10, *) + func aMethod( + pigeonApi: PigeonApiClassWithApiRequirement, pigeonInstance: ClassWithApiRequirement + ) throws { + + } + } + + return PigeonApiClassWithApiRequirement( + pigeonRegistrar: registrar, delegate: ClassWithApiRequirementDelegate()) + } +} diff --git a/packages/pigeon/platform_tests/test_plugin/pubspec.yaml b/packages/pigeon/platform_tests/test_plugin/pubspec.yaml index a26b05c7eed3..2a06f09d03fc 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -15,6 +15,8 @@ flutter: pluginClass: TestPlugin ios: pluginClass: TestPlugin + linux: + pluginClass: TestPlugin macos: pluginClass: TestPlugin windows: diff --git a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp index c97dc064a96b..c47e3a16e2e2 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp +++ b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp @@ -32,6 +32,43 @@ FlutterError CreateConnectionError(const std::string channel_name) { EncodableValue("")); } +// UnusedClass + +UnusedClass::UnusedClass() {} + +UnusedClass::UnusedClass(const EncodableValue* a_field) + : a_field_(a_field ? std::optional(*a_field) + : std::nullopt) {} + +const EncodableValue* UnusedClass::a_field() const { + return a_field_ ? &(*a_field_) : nullptr; +} + +void UnusedClass::set_a_field(const EncodableValue* value_arg) { + a_field_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void UnusedClass::set_a_field(const EncodableValue& value_arg) { + a_field_ = value_arg; +} + +EncodableList UnusedClass::ToEncodableList() const { + EncodableList list; + list.reserve(1); + list.push_back(a_field_ ? *a_field_ : EncodableValue()); + return list; +} + +UnusedClass UnusedClass::FromEncodableList(const EncodableList& list) { + UnusedClass decoded; + auto& encodable_a_field = list[0]; + if (!encodable_a_field.IsNull()) { + decoded.set_a_field(encodable_a_field); + } + return decoded; +} + // AllTypes AllTypes::AllTypes(bool a_bool, int64_t an_int, int64_t an_int64, @@ -39,12 +76,19 @@ AllTypes::AllTypes(bool a_bool, int64_t an_int, int64_t an_int64, const std::vector& a4_byte_array, const std::vector& a8_byte_array, const std::vector& a_float_array, - const AnEnum& an_enum, const std::string& a_string, - const EncodableValue& an_object, const EncodableList& list, - const EncodableList& string_list, + const AnEnum& an_enum, const AnotherEnum& another_enum, + const std::string& a_string, const EncodableValue& an_object, + const EncodableList& list, const EncodableList& string_list, const EncodableList& int_list, const EncodableList& double_list, - const EncodableList& bool_list, const EncodableMap& map) + const EncodableList& bool_list, + const EncodableList& enum_list, + const EncodableList& object_list, + const EncodableList& list_list, + const EncodableList& map_list, const EncodableMap& map, + const EncodableMap& string_map, const EncodableMap& int_map, + const EncodableMap& enum_map, const EncodableMap& object_map, + const EncodableMap& list_map, const EncodableMap& map_map) : a_bool_(a_bool), an_int_(an_int), an_int64_(an_int64), @@ -54,6 +98,7 @@ AllTypes::AllTypes(bool a_bool, int64_t an_int, int64_t an_int64, a8_byte_array_(a8_byte_array), a_float_array_(a_float_array), an_enum_(an_enum), + another_enum_(another_enum), a_string_(a_string), an_object_(an_object), list_(list), @@ -61,7 +106,17 @@ AllTypes::AllTypes(bool a_bool, int64_t an_int, int64_t an_int64, int_list_(int_list), double_list_(double_list), bool_list_(bool_list), - map_(map) {} + enum_list_(enum_list), + object_list_(object_list), + list_list_(list_list), + map_list_(map_list), + map_(map), + string_map_(string_map), + int_map_(int_map), + enum_map_(enum_map), + object_map_(object_map), + list_map_(list_map), + map_map_(map_map) {} bool AllTypes::a_bool() const { return a_bool_; } @@ -115,6 +170,12 @@ const AnEnum& AllTypes::an_enum() const { return an_enum_; } void AllTypes::set_an_enum(const AnEnum& value_arg) { an_enum_ = value_arg; } +const AnotherEnum& AllTypes::another_enum() const { return another_enum_; } + +void AllTypes::set_another_enum(const AnotherEnum& value_arg) { + another_enum_ = value_arg; +} + const std::string& AllTypes::a_string() const { return a_string_; } void AllTypes::set_a_string(std::string_view value_arg) { @@ -155,13 +216,73 @@ void AllTypes::set_bool_list(const EncodableList& value_arg) { bool_list_ = value_arg; } +const EncodableList& AllTypes::enum_list() const { return enum_list_; } + +void AllTypes::set_enum_list(const EncodableList& value_arg) { + enum_list_ = value_arg; +} + +const EncodableList& AllTypes::object_list() const { return object_list_; } + +void AllTypes::set_object_list(const EncodableList& value_arg) { + object_list_ = value_arg; +} + +const EncodableList& AllTypes::list_list() const { return list_list_; } + +void AllTypes::set_list_list(const EncodableList& value_arg) { + list_list_ = value_arg; +} + +const EncodableList& AllTypes::map_list() const { return map_list_; } + +void AllTypes::set_map_list(const EncodableList& value_arg) { + map_list_ = value_arg; +} + const EncodableMap& AllTypes::map() const { return map_; } void AllTypes::set_map(const EncodableMap& value_arg) { map_ = value_arg; } +const EncodableMap& AllTypes::string_map() const { return string_map_; } + +void AllTypes::set_string_map(const EncodableMap& value_arg) { + string_map_ = value_arg; +} + +const EncodableMap& AllTypes::int_map() const { return int_map_; } + +void AllTypes::set_int_map(const EncodableMap& value_arg) { + int_map_ = value_arg; +} + +const EncodableMap& AllTypes::enum_map() const { return enum_map_; } + +void AllTypes::set_enum_map(const EncodableMap& value_arg) { + enum_map_ = value_arg; +} + +const EncodableMap& AllTypes::object_map() const { return object_map_; } + +void AllTypes::set_object_map(const EncodableMap& value_arg) { + object_map_ = value_arg; +} + +const EncodableMap& AllTypes::list_map() const { return list_map_; } + +void AllTypes::set_list_map(const EncodableMap& value_arg) { + list_map_ = value_arg; +} + +const EncodableMap& AllTypes::map_map() const { return map_map_; } + +void AllTypes::set_map_map(const EncodableMap& value_arg) { + map_map_ = value_arg; +} + EncodableList AllTypes::ToEncodableList() const { EncodableList list; - list.reserve(17); + list.reserve(28); list.push_back(EncodableValue(a_bool_)); list.push_back(EncodableValue(an_int_)); list.push_back(EncodableValue(an_int64_)); @@ -171,6 +292,7 @@ EncodableList AllTypes::ToEncodableList() const { list.push_back(EncodableValue(a8_byte_array_)); list.push_back(EncodableValue(a_float_array_)); list.push_back(CustomEncodableValue(an_enum_)); + list.push_back(CustomEncodableValue(another_enum_)); list.push_back(EncodableValue(a_string_)); list.push_back(an_object_); list.push_back(EncodableValue(list_)); @@ -178,22 +300,40 @@ EncodableList AllTypes::ToEncodableList() const { list.push_back(EncodableValue(int_list_)); list.push_back(EncodableValue(double_list_)); list.push_back(EncodableValue(bool_list_)); + list.push_back(EncodableValue(enum_list_)); + list.push_back(EncodableValue(object_list_)); + list.push_back(EncodableValue(list_list_)); + list.push_back(EncodableValue(map_list_)); list.push_back(EncodableValue(map_)); + list.push_back(EncodableValue(string_map_)); + list.push_back(EncodableValue(int_map_)); + list.push_back(EncodableValue(enum_map_)); + list.push_back(EncodableValue(object_map_)); + list.push_back(EncodableValue(list_map_)); + list.push_back(EncodableValue(map_map_)); return list; } AllTypes AllTypes::FromEncodableList(const EncodableList& list) { AllTypes decoded( - std::get(list[0]), list[1].LongValue(), list[2].LongValue(), - std::get(list[3]), std::get>(list[4]), + std::get(list[0]), std::get(list[1]), + std::get(list[2]), std::get(list[3]), + std::get>(list[4]), std::get>(list[5]), std::get>(list[6]), std::get>(list[7]), std::any_cast(std::get(list[8])), - std::get(list[9]), list[10], - std::get(list[11]), std::get(list[12]), - std::get(list[13]), std::get(list[14]), - std::get(list[15]), std::get(list[16])); + std::any_cast( + std::get(list[9])), + std::get(list[10]), list[11], + std::get(list[12]), std::get(list[13]), + std::get(list[14]), std::get(list[15]), + std::get(list[16]), std::get(list[17]), + std::get(list[18]), std::get(list[19]), + std::get(list[20]), std::get(list[21]), + std::get(list[22]), std::get(list[23]), + std::get(list[24]), std::get(list[25]), + std::get(list[26]), std::get(list[27])); return decoded; } @@ -208,15 +348,19 @@ AllNullableTypes::AllNullableTypes( const std::vector* a_nullable4_byte_array, const std::vector* a_nullable8_byte_array, const std::vector* a_nullable_float_array, - const EncodableList* nullable_nested_list, - const EncodableMap* nullable_map_with_annotations, - const EncodableMap* nullable_map_with_object, const AnEnum* a_nullable_enum, + const AnEnum* a_nullable_enum, const AnotherEnum* another_nullable_enum, const std::string* a_nullable_string, const EncodableValue* a_nullable_object, const AllNullableTypes* all_nullable_types, const EncodableList* list, const EncodableList* string_list, const EncodableList* int_list, const EncodableList* double_list, const EncodableList* bool_list, - const EncodableList* nested_class_list, const EncodableMap* map) + const EncodableList* enum_list, const EncodableList* object_list, + const EncodableList* list_list, const EncodableList* map_list, + const EncodableList* recursive_class_list, const EncodableMap* map, + const EncodableMap* string_map, const EncodableMap* int_map, + const EncodableMap* enum_map, const EncodableMap* object_map, + const EncodableMap* list_map, const EncodableMap* map_map, + const EncodableMap* recursive_class_map) : a_nullable_bool_(a_nullable_bool ? std::optional(*a_nullable_bool) : std::nullopt), a_nullable_int_(a_nullable_int ? std::optional(*a_nullable_int) @@ -243,19 +387,11 @@ AllNullableTypes::AllNullableTypes( a_nullable_float_array ? std::optional>(*a_nullable_float_array) : std::nullopt), - nullable_nested_list_(nullable_nested_list ? std::optional( - *nullable_nested_list) - : std::nullopt), - nullable_map_with_annotations_( - nullable_map_with_annotations - ? std::optional(*nullable_map_with_annotations) - : std::nullopt), - nullable_map_with_object_( - nullable_map_with_object - ? std::optional(*nullable_map_with_object) - : std::nullopt), a_nullable_enum_(a_nullable_enum ? std::optional(*a_nullable_enum) : std::nullopt), + another_nullable_enum_(another_nullable_enum ? std::optional( + *another_nullable_enum) + : std::nullopt), a_nullable_string_(a_nullable_string ? std::optional(*a_nullable_string) : std::nullopt), @@ -275,10 +411,31 @@ AllNullableTypes::AllNullableTypes( : std::nullopt), bool_list_(bool_list ? std::optional(*bool_list) : std::nullopt), - nested_class_list_(nested_class_list - ? std::optional(*nested_class_list) + enum_list_(enum_list ? std::optional(*enum_list) + : std::nullopt), + object_list_(object_list ? std::optional(*object_list) + : std::nullopt), + list_list_(list_list ? std::optional(*list_list) + : std::nullopt), + map_list_(map_list ? std::optional(*map_list) + : std::nullopt), + recursive_class_list_(recursive_class_list ? std::optional( + *recursive_class_list) + : std::nullopt), + map_(map ? std::optional(*map) : std::nullopt), + string_map_(string_map ? std::optional(*string_map) : std::nullopt), - map_(map ? std::optional(*map) : std::nullopt) {} + int_map_(int_map ? std::optional(*int_map) : std::nullopt), + enum_map_(enum_map ? std::optional(*enum_map) + : std::nullopt), + object_map_(object_map ? std::optional(*object_map) + : std::nullopt), + list_map_(list_map ? std::optional(*list_map) + : std::nullopt), + map_map_(map_map ? std::optional(*map_map) : std::nullopt), + recursive_class_map_(recursive_class_map ? std::optional( + *recursive_class_map) + : std::nullopt) {} AllNullableTypes::AllNullableTypes(const AllNullableTypes& other) : a_nullable_bool_(other.a_nullable_bool_ @@ -309,22 +466,13 @@ AllNullableTypes::AllNullableTypes(const AllNullableTypes& other) ? std::optional>( *other.a_nullable_float_array_) : std::nullopt), - nullable_nested_list_( - other.nullable_nested_list_ - ? std::optional(*other.nullable_nested_list_) - : std::nullopt), - nullable_map_with_annotations_( - other.nullable_map_with_annotations_ - ? std::optional( - *other.nullable_map_with_annotations_) - : std::nullopt), - nullable_map_with_object_( - other.nullable_map_with_object_ - ? std::optional(*other.nullable_map_with_object_) - : std::nullopt), a_nullable_enum_(other.a_nullable_enum_ ? std::optional(*other.a_nullable_enum_) : std::nullopt), + another_nullable_enum_( + other.another_nullable_enum_ + ? std::optional(*other.another_nullable_enum_) + : std::nullopt), a_nullable_string_( other.a_nullable_string_ ? std::optional(*other.a_nullable_string_) @@ -350,12 +498,41 @@ AllNullableTypes::AllNullableTypes(const AllNullableTypes& other) bool_list_(other.bool_list_ ? std::optional(*other.bool_list_) : std::nullopt), - nested_class_list_( - other.nested_class_list_ - ? std::optional(*other.nested_class_list_) + enum_list_(other.enum_list_ + ? std::optional(*other.enum_list_) + : std::nullopt), + object_list_(other.object_list_ + ? std::optional(*other.object_list_) + : std::nullopt), + list_list_(other.list_list_ + ? std::optional(*other.list_list_) + : std::nullopt), + map_list_(other.map_list_ ? std::optional(*other.map_list_) + : std::nullopt), + recursive_class_list_( + other.recursive_class_list_ + ? std::optional(*other.recursive_class_list_) : std::nullopt), map_(other.map_ ? std::optional(*other.map_) - : std::nullopt) {} + : std::nullopt), + string_map_(other.string_map_ + ? std::optional(*other.string_map_) + : std::nullopt), + int_map_(other.int_map_ ? std::optional(*other.int_map_) + : std::nullopt), + enum_map_(other.enum_map_ ? std::optional(*other.enum_map_) + : std::nullopt), + object_map_(other.object_map_ + ? std::optional(*other.object_map_) + : std::nullopt), + list_map_(other.list_map_ ? std::optional(*other.list_map_) + : std::nullopt), + map_map_(other.map_map_ ? std::optional(*other.map_map_) + : std::nullopt), + recursive_class_map_( + other.recursive_class_map_ + ? std::optional(*other.recursive_class_map_) + : std::nullopt) {} AllNullableTypes& AllNullableTypes::operator=(const AllNullableTypes& other) { a_nullable_bool_ = other.a_nullable_bool_; @@ -366,10 +543,8 @@ AllNullableTypes& AllNullableTypes::operator=(const AllNullableTypes& other) { a_nullable4_byte_array_ = other.a_nullable4_byte_array_; a_nullable8_byte_array_ = other.a_nullable8_byte_array_; a_nullable_float_array_ = other.a_nullable_float_array_; - nullable_nested_list_ = other.nullable_nested_list_; - nullable_map_with_annotations_ = other.nullable_map_with_annotations_; - nullable_map_with_object_ = other.nullable_map_with_object_; a_nullable_enum_ = other.a_nullable_enum_; + another_nullable_enum_ = other.another_nullable_enum_; a_nullable_string_ = other.a_nullable_string_; a_nullable_object_ = other.a_nullable_object_; all_nullable_types_ = @@ -381,8 +556,19 @@ AllNullableTypes& AllNullableTypes::operator=(const AllNullableTypes& other) { int_list_ = other.int_list_; double_list_ = other.double_list_; bool_list_ = other.bool_list_; - nested_class_list_ = other.nested_class_list_; + enum_list_ = other.enum_list_; + object_list_ = other.object_list_; + list_list_ = other.list_list_; + map_list_ = other.map_list_; + recursive_class_list_ = other.recursive_class_list_; map_ = other.map_; + string_map_ = other.string_map_; + int_map_ = other.int_map_; + enum_map_ = other.enum_map_; + object_map_ = other.object_map_; + list_map_ = other.list_map_; + map_map_ = other.map_map_; + recursive_class_map_ = other.recursive_class_map_; return *this; } @@ -500,52 +686,6 @@ void AllNullableTypes::set_a_nullable_float_array( a_nullable_float_array_ = value_arg; } -const EncodableList* AllNullableTypes::nullable_nested_list() const { - return nullable_nested_list_ ? &(*nullable_nested_list_) : nullptr; -} - -void AllNullableTypes::set_nullable_nested_list( - const EncodableList* value_arg) { - nullable_nested_list_ = - value_arg ? std::optional(*value_arg) : std::nullopt; -} - -void AllNullableTypes::set_nullable_nested_list( - const EncodableList& value_arg) { - nullable_nested_list_ = value_arg; -} - -const EncodableMap* AllNullableTypes::nullable_map_with_annotations() const { - return nullable_map_with_annotations_ ? &(*nullable_map_with_annotations_) - : nullptr; -} - -void AllNullableTypes::set_nullable_map_with_annotations( - const EncodableMap* value_arg) { - nullable_map_with_annotations_ = - value_arg ? std::optional(*value_arg) : std::nullopt; -} - -void AllNullableTypes::set_nullable_map_with_annotations( - const EncodableMap& value_arg) { - nullable_map_with_annotations_ = value_arg; -} - -const EncodableMap* AllNullableTypes::nullable_map_with_object() const { - return nullable_map_with_object_ ? &(*nullable_map_with_object_) : nullptr; -} - -void AllNullableTypes::set_nullable_map_with_object( - const EncodableMap* value_arg) { - nullable_map_with_object_ = - value_arg ? std::optional(*value_arg) : std::nullopt; -} - -void AllNullableTypes::set_nullable_map_with_object( - const EncodableMap& value_arg) { - nullable_map_with_object_ = value_arg; -} - const AnEnum* AllNullableTypes::a_nullable_enum() const { return a_nullable_enum_ ? &(*a_nullable_enum_) : nullptr; } @@ -559,6 +699,19 @@ void AllNullableTypes::set_a_nullable_enum(const AnEnum& value_arg) { a_nullable_enum_ = value_arg; } +const AnotherEnum* AllNullableTypes::another_nullable_enum() const { + return another_nullable_enum_ ? &(*another_nullable_enum_) : nullptr; +} + +void AllNullableTypes::set_another_nullable_enum(const AnotherEnum* value_arg) { + another_nullable_enum_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypes::set_another_nullable_enum(const AnotherEnum& value_arg) { + another_nullable_enum_ = value_arg; +} + const std::string* AllNullableTypes::a_nullable_string() const { return a_nullable_string_ ? &(*a_nullable_string_) : nullptr; } @@ -665,17 +818,71 @@ void AllNullableTypes::set_bool_list(const EncodableList& value_arg) { bool_list_ = value_arg; } -const EncodableList* AllNullableTypes::nested_class_list() const { - return nested_class_list_ ? &(*nested_class_list_) : nullptr; +const EncodableList* AllNullableTypes::enum_list() const { + return enum_list_ ? &(*enum_list_) : nullptr; +} + +void AllNullableTypes::set_enum_list(const EncodableList* value_arg) { + enum_list_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypes::set_enum_list(const EncodableList& value_arg) { + enum_list_ = value_arg; +} + +const EncodableList* AllNullableTypes::object_list() const { + return object_list_ ? &(*object_list_) : nullptr; +} + +void AllNullableTypes::set_object_list(const EncodableList* value_arg) { + object_list_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypes::set_object_list(const EncodableList& value_arg) { + object_list_ = value_arg; +} + +const EncodableList* AllNullableTypes::list_list() const { + return list_list_ ? &(*list_list_) : nullptr; +} + +void AllNullableTypes::set_list_list(const EncodableList* value_arg) { + list_list_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypes::set_list_list(const EncodableList& value_arg) { + list_list_ = value_arg; +} + +const EncodableList* AllNullableTypes::map_list() const { + return map_list_ ? &(*map_list_) : nullptr; +} + +void AllNullableTypes::set_map_list(const EncodableList* value_arg) { + map_list_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypes::set_map_list(const EncodableList& value_arg) { + map_list_ = value_arg; } -void AllNullableTypes::set_nested_class_list(const EncodableList* value_arg) { - nested_class_list_ = +const EncodableList* AllNullableTypes::recursive_class_list() const { + return recursive_class_list_ ? &(*recursive_class_list_) : nullptr; +} + +void AllNullableTypes::set_recursive_class_list( + const EncodableList* value_arg) { + recursive_class_list_ = value_arg ? std::optional(*value_arg) : std::nullopt; } -void AllNullableTypes::set_nested_class_list(const EncodableList& value_arg) { - nested_class_list_ = value_arg; +void AllNullableTypes::set_recursive_class_list( + const EncodableList& value_arg) { + recursive_class_list_ = value_arg; } const EncodableMap* AllNullableTypes::map() const { @@ -690,9 +897,98 @@ void AllNullableTypes::set_map(const EncodableMap& value_arg) { map_ = value_arg; } +const EncodableMap* AllNullableTypes::string_map() const { + return string_map_ ? &(*string_map_) : nullptr; +} + +void AllNullableTypes::set_string_map(const EncodableMap* value_arg) { + string_map_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypes::set_string_map(const EncodableMap& value_arg) { + string_map_ = value_arg; +} + +const EncodableMap* AllNullableTypes::int_map() const { + return int_map_ ? &(*int_map_) : nullptr; +} + +void AllNullableTypes::set_int_map(const EncodableMap* value_arg) { + int_map_ = value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypes::set_int_map(const EncodableMap& value_arg) { + int_map_ = value_arg; +} + +const EncodableMap* AllNullableTypes::enum_map() const { + return enum_map_ ? &(*enum_map_) : nullptr; +} + +void AllNullableTypes::set_enum_map(const EncodableMap* value_arg) { + enum_map_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypes::set_enum_map(const EncodableMap& value_arg) { + enum_map_ = value_arg; +} + +const EncodableMap* AllNullableTypes::object_map() const { + return object_map_ ? &(*object_map_) : nullptr; +} + +void AllNullableTypes::set_object_map(const EncodableMap* value_arg) { + object_map_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypes::set_object_map(const EncodableMap& value_arg) { + object_map_ = value_arg; +} + +const EncodableMap* AllNullableTypes::list_map() const { + return list_map_ ? &(*list_map_) : nullptr; +} + +void AllNullableTypes::set_list_map(const EncodableMap* value_arg) { + list_map_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypes::set_list_map(const EncodableMap& value_arg) { + list_map_ = value_arg; +} + +const EncodableMap* AllNullableTypes::map_map() const { + return map_map_ ? &(*map_map_) : nullptr; +} + +void AllNullableTypes::set_map_map(const EncodableMap* value_arg) { + map_map_ = value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypes::set_map_map(const EncodableMap& value_arg) { + map_map_ = value_arg; +} + +const EncodableMap* AllNullableTypes::recursive_class_map() const { + return recursive_class_map_ ? &(*recursive_class_map_) : nullptr; +} + +void AllNullableTypes::set_recursive_class_map(const EncodableMap* value_arg) { + recursive_class_map_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypes::set_recursive_class_map(const EncodableMap& value_arg) { + recursive_class_map_ = value_arg; +} + EncodableList AllNullableTypes::ToEncodableList() const { EncodableList list; - list.reserve(22); + list.reserve(31); list.push_back(a_nullable_bool_ ? EncodableValue(*a_nullable_bool_) : EncodableValue()); list.push_back(a_nullable_int_ ? EncodableValue(*a_nullable_int_) @@ -713,16 +1009,11 @@ EncodableList AllNullableTypes::ToEncodableList() const { list.push_back(a_nullable_float_array_ ? EncodableValue(*a_nullable_float_array_) : EncodableValue()); - list.push_back(nullable_nested_list_ ? EncodableValue(*nullable_nested_list_) - : EncodableValue()); - list.push_back(nullable_map_with_annotations_ - ? EncodableValue(*nullable_map_with_annotations_) - : EncodableValue()); - list.push_back(nullable_map_with_object_ - ? EncodableValue(*nullable_map_with_object_) - : EncodableValue()); list.push_back(a_nullable_enum_ ? CustomEncodableValue(*a_nullable_enum_) : EncodableValue()); + list.push_back(another_nullable_enum_ + ? CustomEncodableValue(*another_nullable_enum_) + : EncodableValue()); list.push_back(a_nullable_string_ ? EncodableValue(*a_nullable_string_) : EncodableValue()); list.push_back(a_nullable_object_ ? *a_nullable_object_ : EncodableValue()); @@ -736,9 +1027,22 @@ EncodableList AllNullableTypes::ToEncodableList() const { list.push_back(double_list_ ? EncodableValue(*double_list_) : EncodableValue()); list.push_back(bool_list_ ? EncodableValue(*bool_list_) : EncodableValue()); - list.push_back(nested_class_list_ ? EncodableValue(*nested_class_list_) - : EncodableValue()); + list.push_back(enum_list_ ? EncodableValue(*enum_list_) : EncodableValue()); + list.push_back(object_list_ ? EncodableValue(*object_list_) + : EncodableValue()); + list.push_back(list_list_ ? EncodableValue(*list_list_) : EncodableValue()); + list.push_back(map_list_ ? EncodableValue(*map_list_) : EncodableValue()); + list.push_back(recursive_class_list_ ? EncodableValue(*recursive_class_list_) + : EncodableValue()); list.push_back(map_ ? EncodableValue(*map_) : EncodableValue()); + list.push_back(string_map_ ? EncodableValue(*string_map_) : EncodableValue()); + list.push_back(int_map_ ? EncodableValue(*int_map_) : EncodableValue()); + list.push_back(enum_map_ ? EncodableValue(*enum_map_) : EncodableValue()); + list.push_back(object_map_ ? EncodableValue(*object_map_) : EncodableValue()); + list.push_back(list_map_ ? EncodableValue(*list_map_) : EncodableValue()); + list.push_back(map_map_ ? EncodableValue(*map_map_) : EncodableValue()); + list.push_back(recursive_class_map_ ? EncodableValue(*recursive_class_map_) + : EncodableValue()); return list; } @@ -751,11 +1055,11 @@ AllNullableTypes AllNullableTypes::FromEncodableList( } auto& encodable_a_nullable_int = list[1]; if (!encodable_a_nullable_int.IsNull()) { - decoded.set_a_nullable_int(encodable_a_nullable_int.LongValue()); + decoded.set_a_nullable_int(std::get(encodable_a_nullable_int)); } auto& encodable_a_nullable_int64 = list[2]; if (!encodable_a_nullable_int64.IsNull()) { - decoded.set_a_nullable_int64(encodable_a_nullable_int64.LongValue()); + decoded.set_a_nullable_int64(std::get(encodable_a_nullable_int64)); } auto& encodable_a_nullable_double = list[3]; if (!encodable_a_nullable_double.IsNull()) { @@ -782,69 +1086,104 @@ AllNullableTypes AllNullableTypes::FromEncodableList( decoded.set_a_nullable_float_array( std::get>(encodable_a_nullable_float_array)); } - auto& encodable_nullable_nested_list = list[8]; - if (!encodable_nullable_nested_list.IsNull()) { - decoded.set_nullable_nested_list( - std::get(encodable_nullable_nested_list)); - } - auto& encodable_nullable_map_with_annotations = list[9]; - if (!encodable_nullable_map_with_annotations.IsNull()) { - decoded.set_nullable_map_with_annotations( - std::get(encodable_nullable_map_with_annotations)); - } - auto& encodable_nullable_map_with_object = list[10]; - if (!encodable_nullable_map_with_object.IsNull()) { - decoded.set_nullable_map_with_object( - std::get(encodable_nullable_map_with_object)); - } - auto& encodable_a_nullable_enum = list[11]; + auto& encodable_a_nullable_enum = list[8]; if (!encodable_a_nullable_enum.IsNull()) { decoded.set_a_nullable_enum(std::any_cast( std::get(encodable_a_nullable_enum))); } - auto& encodable_a_nullable_string = list[12]; + auto& encodable_another_nullable_enum = list[9]; + if (!encodable_another_nullable_enum.IsNull()) { + decoded.set_another_nullable_enum(std::any_cast( + std::get(encodable_another_nullable_enum))); + } + auto& encodable_a_nullable_string = list[10]; if (!encodable_a_nullable_string.IsNull()) { decoded.set_a_nullable_string( std::get(encodable_a_nullable_string)); } - auto& encodable_a_nullable_object = list[13]; + auto& encodable_a_nullable_object = list[11]; if (!encodable_a_nullable_object.IsNull()) { decoded.set_a_nullable_object(encodable_a_nullable_object); } - auto& encodable_all_nullable_types = list[14]; + auto& encodable_all_nullable_types = list[12]; if (!encodable_all_nullable_types.IsNull()) { decoded.set_all_nullable_types(std::any_cast( std::get(encodable_all_nullable_types))); } - auto& encodable_list = list[15]; + auto& encodable_list = list[13]; if (!encodable_list.IsNull()) { decoded.set_list(std::get(encodable_list)); } - auto& encodable_string_list = list[16]; + auto& encodable_string_list = list[14]; if (!encodable_string_list.IsNull()) { decoded.set_string_list(std::get(encodable_string_list)); } - auto& encodable_int_list = list[17]; + auto& encodable_int_list = list[15]; if (!encodable_int_list.IsNull()) { decoded.set_int_list(std::get(encodable_int_list)); } - auto& encodable_double_list = list[18]; + auto& encodable_double_list = list[16]; if (!encodable_double_list.IsNull()) { decoded.set_double_list(std::get(encodable_double_list)); } - auto& encodable_bool_list = list[19]; + auto& encodable_bool_list = list[17]; if (!encodable_bool_list.IsNull()) { decoded.set_bool_list(std::get(encodable_bool_list)); } - auto& encodable_nested_class_list = list[20]; - if (!encodable_nested_class_list.IsNull()) { - decoded.set_nested_class_list( - std::get(encodable_nested_class_list)); + auto& encodable_enum_list = list[18]; + if (!encodable_enum_list.IsNull()) { + decoded.set_enum_list(std::get(encodable_enum_list)); } - auto& encodable_map = list[21]; + auto& encodable_object_list = list[19]; + if (!encodable_object_list.IsNull()) { + decoded.set_object_list(std::get(encodable_object_list)); + } + auto& encodable_list_list = list[20]; + if (!encodable_list_list.IsNull()) { + decoded.set_list_list(std::get(encodable_list_list)); + } + auto& encodable_map_list = list[21]; + if (!encodable_map_list.IsNull()) { + decoded.set_map_list(std::get(encodable_map_list)); + } + auto& encodable_recursive_class_list = list[22]; + if (!encodable_recursive_class_list.IsNull()) { + decoded.set_recursive_class_list( + std::get(encodable_recursive_class_list)); + } + auto& encodable_map = list[23]; if (!encodable_map.IsNull()) { decoded.set_map(std::get(encodable_map)); } + auto& encodable_string_map = list[24]; + if (!encodable_string_map.IsNull()) { + decoded.set_string_map(std::get(encodable_string_map)); + } + auto& encodable_int_map = list[25]; + if (!encodable_int_map.IsNull()) { + decoded.set_int_map(std::get(encodable_int_map)); + } + auto& encodable_enum_map = list[26]; + if (!encodable_enum_map.IsNull()) { + decoded.set_enum_map(std::get(encodable_enum_map)); + } + auto& encodable_object_map = list[27]; + if (!encodable_object_map.IsNull()) { + decoded.set_object_map(std::get(encodable_object_map)); + } + auto& encodable_list_map = list[28]; + if (!encodable_list_map.IsNull()) { + decoded.set_list_map(std::get(encodable_list_map)); + } + auto& encodable_map_map = list[29]; + if (!encodable_map_map.IsNull()) { + decoded.set_map_map(std::get(encodable_map_map)); + } + auto& encodable_recursive_class_map = list[30]; + if (!encodable_recursive_class_map.IsNull()) { + decoded.set_recursive_class_map( + std::get(encodable_recursive_class_map)); + } return decoded; } @@ -859,14 +1198,17 @@ AllNullableTypesWithoutRecursion::AllNullableTypesWithoutRecursion( const std::vector* a_nullable4_byte_array, const std::vector* a_nullable8_byte_array, const std::vector* a_nullable_float_array, - const EncodableList* nullable_nested_list, - const EncodableMap* nullable_map_with_annotations, - const EncodableMap* nullable_map_with_object, const AnEnum* a_nullable_enum, + const AnEnum* a_nullable_enum, const AnotherEnum* another_nullable_enum, const std::string* a_nullable_string, const EncodableValue* a_nullable_object, const EncodableList* list, const EncodableList* string_list, const EncodableList* int_list, const EncodableList* double_list, const EncodableList* bool_list, - const EncodableMap* map) + const EncodableList* enum_list, const EncodableList* object_list, + const EncodableList* list_list, const EncodableList* map_list, + const EncodableMap* map, const EncodableMap* string_map, + const EncodableMap* int_map, const EncodableMap* enum_map, + const EncodableMap* object_map, const EncodableMap* list_map, + const EncodableMap* map_map) : a_nullable_bool_(a_nullable_bool ? std::optional(*a_nullable_bool) : std::nullopt), a_nullable_int_(a_nullable_int ? std::optional(*a_nullable_int) @@ -893,19 +1235,11 @@ AllNullableTypesWithoutRecursion::AllNullableTypesWithoutRecursion( a_nullable_float_array ? std::optional>(*a_nullable_float_array) : std::nullopt), - nullable_nested_list_(nullable_nested_list ? std::optional( - *nullable_nested_list) - : std::nullopt), - nullable_map_with_annotations_( - nullable_map_with_annotations - ? std::optional(*nullable_map_with_annotations) - : std::nullopt), - nullable_map_with_object_( - nullable_map_with_object - ? std::optional(*nullable_map_with_object) - : std::nullopt), a_nullable_enum_(a_nullable_enum ? std::optional(*a_nullable_enum) : std::nullopt), + another_nullable_enum_(another_nullable_enum ? std::optional( + *another_nullable_enum) + : std::nullopt), a_nullable_string_(a_nullable_string ? std::optional(*a_nullable_string) : std::nullopt), @@ -921,7 +1255,26 @@ AllNullableTypesWithoutRecursion::AllNullableTypesWithoutRecursion( : std::nullopt), bool_list_(bool_list ? std::optional(*bool_list) : std::nullopt), - map_(map ? std::optional(*map) : std::nullopt) {} + enum_list_(enum_list ? std::optional(*enum_list) + : std::nullopt), + object_list_(object_list ? std::optional(*object_list) + : std::nullopt), + list_list_(list_list ? std::optional(*list_list) + : std::nullopt), + map_list_(map_list ? std::optional(*map_list) + : std::nullopt), + map_(map ? std::optional(*map) : std::nullopt), + string_map_(string_map ? std::optional(*string_map) + : std::nullopt), + int_map_(int_map ? std::optional(*int_map) : std::nullopt), + enum_map_(enum_map ? std::optional(*enum_map) + : std::nullopt), + object_map_(object_map ? std::optional(*object_map) + : std::nullopt), + list_map_(list_map ? std::optional(*list_map) + : std::nullopt), + map_map_(map_map ? std::optional(*map_map) : std::nullopt) { +} const bool* AllNullableTypesWithoutRecursion::a_nullable_bool() const { return a_nullable_bool_ ? &(*a_nullable_bool_) : nullptr; @@ -1045,55 +1398,6 @@ void AllNullableTypesWithoutRecursion::set_a_nullable_float_array( a_nullable_float_array_ = value_arg; } -const EncodableList* AllNullableTypesWithoutRecursion::nullable_nested_list() - const { - return nullable_nested_list_ ? &(*nullable_nested_list_) : nullptr; -} - -void AllNullableTypesWithoutRecursion::set_nullable_nested_list( - const EncodableList* value_arg) { - nullable_nested_list_ = - value_arg ? std::optional(*value_arg) : std::nullopt; -} - -void AllNullableTypesWithoutRecursion::set_nullable_nested_list( - const EncodableList& value_arg) { - nullable_nested_list_ = value_arg; -} - -const EncodableMap* -AllNullableTypesWithoutRecursion::nullable_map_with_annotations() const { - return nullable_map_with_annotations_ ? &(*nullable_map_with_annotations_) - : nullptr; -} - -void AllNullableTypesWithoutRecursion::set_nullable_map_with_annotations( - const EncodableMap* value_arg) { - nullable_map_with_annotations_ = - value_arg ? std::optional(*value_arg) : std::nullopt; -} - -void AllNullableTypesWithoutRecursion::set_nullable_map_with_annotations( - const EncodableMap& value_arg) { - nullable_map_with_annotations_ = value_arg; -} - -const EncodableMap* AllNullableTypesWithoutRecursion::nullable_map_with_object() - const { - return nullable_map_with_object_ ? &(*nullable_map_with_object_) : nullptr; -} - -void AllNullableTypesWithoutRecursion::set_nullable_map_with_object( - const EncodableMap* value_arg) { - nullable_map_with_object_ = - value_arg ? std::optional(*value_arg) : std::nullopt; -} - -void AllNullableTypesWithoutRecursion::set_nullable_map_with_object( - const EncodableMap& value_arg) { - nullable_map_with_object_ = value_arg; -} - const AnEnum* AllNullableTypesWithoutRecursion::a_nullable_enum() const { return a_nullable_enum_ ? &(*a_nullable_enum_) : nullptr; } @@ -1109,6 +1413,22 @@ void AllNullableTypesWithoutRecursion::set_a_nullable_enum( a_nullable_enum_ = value_arg; } +const AnotherEnum* AllNullableTypesWithoutRecursion::another_nullable_enum() + const { + return another_nullable_enum_ ? &(*another_nullable_enum_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_another_nullable_enum( + const AnotherEnum* value_arg) { + another_nullable_enum_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_another_nullable_enum( + const AnotherEnum& value_arg) { + another_nullable_enum_ = value_arg; +} + const std::string* AllNullableTypesWithoutRecursion::a_nullable_string() const { return a_nullable_string_ ? &(*a_nullable_string_) : nullptr; } @@ -1214,8 +1534,68 @@ void AllNullableTypesWithoutRecursion::set_bool_list( bool_list_ = value_arg; } -const EncodableMap* AllNullableTypesWithoutRecursion::map() const { - return map_ ? &(*map_) : nullptr; +const EncodableList* AllNullableTypesWithoutRecursion::enum_list() const { + return enum_list_ ? &(*enum_list_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_enum_list( + const EncodableList* value_arg) { + enum_list_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_enum_list( + const EncodableList& value_arg) { + enum_list_ = value_arg; +} + +const EncodableList* AllNullableTypesWithoutRecursion::object_list() const { + return object_list_ ? &(*object_list_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_object_list( + const EncodableList* value_arg) { + object_list_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_object_list( + const EncodableList& value_arg) { + object_list_ = value_arg; +} + +const EncodableList* AllNullableTypesWithoutRecursion::list_list() const { + return list_list_ ? &(*list_list_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_list_list( + const EncodableList* value_arg) { + list_list_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_list_list( + const EncodableList& value_arg) { + list_list_ = value_arg; +} + +const EncodableList* AllNullableTypesWithoutRecursion::map_list() const { + return map_list_ ? &(*map_list_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_map_list( + const EncodableList* value_arg) { + map_list_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_map_list( + const EncodableList& value_arg) { + map_list_ = value_arg; +} + +const EncodableMap* AllNullableTypesWithoutRecursion::map() const { + return map_ ? &(*map_) : nullptr; } void AllNullableTypesWithoutRecursion::set_map(const EncodableMap* value_arg) { @@ -1226,9 +1606,97 @@ void AllNullableTypesWithoutRecursion::set_map(const EncodableMap& value_arg) { map_ = value_arg; } +const EncodableMap* AllNullableTypesWithoutRecursion::string_map() const { + return string_map_ ? &(*string_map_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_string_map( + const EncodableMap* value_arg) { + string_map_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_string_map( + const EncodableMap& value_arg) { + string_map_ = value_arg; +} + +const EncodableMap* AllNullableTypesWithoutRecursion::int_map() const { + return int_map_ ? &(*int_map_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_int_map( + const EncodableMap* value_arg) { + int_map_ = value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_int_map( + const EncodableMap& value_arg) { + int_map_ = value_arg; +} + +const EncodableMap* AllNullableTypesWithoutRecursion::enum_map() const { + return enum_map_ ? &(*enum_map_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_enum_map( + const EncodableMap* value_arg) { + enum_map_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_enum_map( + const EncodableMap& value_arg) { + enum_map_ = value_arg; +} + +const EncodableMap* AllNullableTypesWithoutRecursion::object_map() const { + return object_map_ ? &(*object_map_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_object_map( + const EncodableMap* value_arg) { + object_map_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_object_map( + const EncodableMap& value_arg) { + object_map_ = value_arg; +} + +const EncodableMap* AllNullableTypesWithoutRecursion::list_map() const { + return list_map_ ? &(*list_map_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_list_map( + const EncodableMap* value_arg) { + list_map_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_list_map( + const EncodableMap& value_arg) { + list_map_ = value_arg; +} + +const EncodableMap* AllNullableTypesWithoutRecursion::map_map() const { + return map_map_ ? &(*map_map_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_map_map( + const EncodableMap* value_arg) { + map_map_ = value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_map_map( + const EncodableMap& value_arg) { + map_map_ = value_arg; +} + EncodableList AllNullableTypesWithoutRecursion::ToEncodableList() const { EncodableList list; - list.reserve(20); + list.reserve(28); list.push_back(a_nullable_bool_ ? EncodableValue(*a_nullable_bool_) : EncodableValue()); list.push_back(a_nullable_int_ ? EncodableValue(*a_nullable_int_) @@ -1249,16 +1717,11 @@ EncodableList AllNullableTypesWithoutRecursion::ToEncodableList() const { list.push_back(a_nullable_float_array_ ? EncodableValue(*a_nullable_float_array_) : EncodableValue()); - list.push_back(nullable_nested_list_ ? EncodableValue(*nullable_nested_list_) - : EncodableValue()); - list.push_back(nullable_map_with_annotations_ - ? EncodableValue(*nullable_map_with_annotations_) - : EncodableValue()); - list.push_back(nullable_map_with_object_ - ? EncodableValue(*nullable_map_with_object_) - : EncodableValue()); list.push_back(a_nullable_enum_ ? CustomEncodableValue(*a_nullable_enum_) : EncodableValue()); + list.push_back(another_nullable_enum_ + ? CustomEncodableValue(*another_nullable_enum_) + : EncodableValue()); list.push_back(a_nullable_string_ ? EncodableValue(*a_nullable_string_) : EncodableValue()); list.push_back(a_nullable_object_ ? *a_nullable_object_ : EncodableValue()); @@ -1269,7 +1732,18 @@ EncodableList AllNullableTypesWithoutRecursion::ToEncodableList() const { list.push_back(double_list_ ? EncodableValue(*double_list_) : EncodableValue()); list.push_back(bool_list_ ? EncodableValue(*bool_list_) : EncodableValue()); + list.push_back(enum_list_ ? EncodableValue(*enum_list_) : EncodableValue()); + list.push_back(object_list_ ? EncodableValue(*object_list_) + : EncodableValue()); + list.push_back(list_list_ ? EncodableValue(*list_list_) : EncodableValue()); + list.push_back(map_list_ ? EncodableValue(*map_list_) : EncodableValue()); list.push_back(map_ ? EncodableValue(*map_) : EncodableValue()); + list.push_back(string_map_ ? EncodableValue(*string_map_) : EncodableValue()); + list.push_back(int_map_ ? EncodableValue(*int_map_) : EncodableValue()); + list.push_back(enum_map_ ? EncodableValue(*enum_map_) : EncodableValue()); + list.push_back(object_map_ ? EncodableValue(*object_map_) : EncodableValue()); + list.push_back(list_map_ ? EncodableValue(*list_map_) : EncodableValue()); + list.push_back(map_map_ ? EncodableValue(*map_map_) : EncodableValue()); return list; } @@ -1282,11 +1756,11 @@ AllNullableTypesWithoutRecursion::FromEncodableList(const EncodableList& list) { } auto& encodable_a_nullable_int = list[1]; if (!encodable_a_nullable_int.IsNull()) { - decoded.set_a_nullable_int(encodable_a_nullable_int.LongValue()); + decoded.set_a_nullable_int(std::get(encodable_a_nullable_int)); } auto& encodable_a_nullable_int64 = list[2]; if (!encodable_a_nullable_int64.IsNull()) { - decoded.set_a_nullable_int64(encodable_a_nullable_int64.LongValue()); + decoded.set_a_nullable_int64(std::get(encodable_a_nullable_int64)); } auto& encodable_a_nullable_double = list[3]; if (!encodable_a_nullable_double.IsNull()) { @@ -1313,72 +1787,110 @@ AllNullableTypesWithoutRecursion::FromEncodableList(const EncodableList& list) { decoded.set_a_nullable_float_array( std::get>(encodable_a_nullable_float_array)); } - auto& encodable_nullable_nested_list = list[8]; - if (!encodable_nullable_nested_list.IsNull()) { - decoded.set_nullable_nested_list( - std::get(encodable_nullable_nested_list)); - } - auto& encodable_nullable_map_with_annotations = list[9]; - if (!encodable_nullable_map_with_annotations.IsNull()) { - decoded.set_nullable_map_with_annotations( - std::get(encodable_nullable_map_with_annotations)); - } - auto& encodable_nullable_map_with_object = list[10]; - if (!encodable_nullable_map_with_object.IsNull()) { - decoded.set_nullable_map_with_object( - std::get(encodable_nullable_map_with_object)); - } - auto& encodable_a_nullable_enum = list[11]; + auto& encodable_a_nullable_enum = list[8]; if (!encodable_a_nullable_enum.IsNull()) { decoded.set_a_nullable_enum(std::any_cast( std::get(encodable_a_nullable_enum))); } - auto& encodable_a_nullable_string = list[12]; + auto& encodable_another_nullable_enum = list[9]; + if (!encodable_another_nullable_enum.IsNull()) { + decoded.set_another_nullable_enum(std::any_cast( + std::get(encodable_another_nullable_enum))); + } + auto& encodable_a_nullable_string = list[10]; if (!encodable_a_nullable_string.IsNull()) { decoded.set_a_nullable_string( std::get(encodable_a_nullable_string)); } - auto& encodable_a_nullable_object = list[13]; + auto& encodable_a_nullable_object = list[11]; if (!encodable_a_nullable_object.IsNull()) { decoded.set_a_nullable_object(encodable_a_nullable_object); } - auto& encodable_list = list[14]; + auto& encodable_list = list[12]; if (!encodable_list.IsNull()) { decoded.set_list(std::get(encodable_list)); } - auto& encodable_string_list = list[15]; + auto& encodable_string_list = list[13]; if (!encodable_string_list.IsNull()) { decoded.set_string_list(std::get(encodable_string_list)); } - auto& encodable_int_list = list[16]; + auto& encodable_int_list = list[14]; if (!encodable_int_list.IsNull()) { decoded.set_int_list(std::get(encodable_int_list)); } - auto& encodable_double_list = list[17]; + auto& encodable_double_list = list[15]; if (!encodable_double_list.IsNull()) { decoded.set_double_list(std::get(encodable_double_list)); } - auto& encodable_bool_list = list[18]; + auto& encodable_bool_list = list[16]; if (!encodable_bool_list.IsNull()) { decoded.set_bool_list(std::get(encodable_bool_list)); } - auto& encodable_map = list[19]; + auto& encodable_enum_list = list[17]; + if (!encodable_enum_list.IsNull()) { + decoded.set_enum_list(std::get(encodable_enum_list)); + } + auto& encodable_object_list = list[18]; + if (!encodable_object_list.IsNull()) { + decoded.set_object_list(std::get(encodable_object_list)); + } + auto& encodable_list_list = list[19]; + if (!encodable_list_list.IsNull()) { + decoded.set_list_list(std::get(encodable_list_list)); + } + auto& encodable_map_list = list[20]; + if (!encodable_map_list.IsNull()) { + decoded.set_map_list(std::get(encodable_map_list)); + } + auto& encodable_map = list[21]; if (!encodable_map.IsNull()) { decoded.set_map(std::get(encodable_map)); } + auto& encodable_string_map = list[22]; + if (!encodable_string_map.IsNull()) { + decoded.set_string_map(std::get(encodable_string_map)); + } + auto& encodable_int_map = list[23]; + if (!encodable_int_map.IsNull()) { + decoded.set_int_map(std::get(encodable_int_map)); + } + auto& encodable_enum_map = list[24]; + if (!encodable_enum_map.IsNull()) { + decoded.set_enum_map(std::get(encodable_enum_map)); + } + auto& encodable_object_map = list[25]; + if (!encodable_object_map.IsNull()) { + decoded.set_object_map(std::get(encodable_object_map)); + } + auto& encodable_list_map = list[26]; + if (!encodable_list_map.IsNull()) { + decoded.set_list_map(std::get(encodable_list_map)); + } + auto& encodable_map_map = list[27]; + if (!encodable_map_map.IsNull()) { + decoded.set_map_map(std::get(encodable_map_map)); + } return decoded; } // AllClassesWrapper -AllClassesWrapper::AllClassesWrapper(const AllNullableTypes& all_nullable_types) +AllClassesWrapper::AllClassesWrapper(const AllNullableTypes& all_nullable_types, + const EncodableList& class_list, + const EncodableMap& class_map) : all_nullable_types_( - std::make_unique(all_nullable_types)) {} + std::make_unique(all_nullable_types)), + class_list_(class_list), + class_map_(class_map) {} AllClassesWrapper::AllClassesWrapper(const AllNullableTypes& all_nullable_types, const AllNullableTypesWithoutRecursion* all_nullable_types_without_recursion, - const AllTypes* all_types) + const AllTypes* all_types, + const EncodableList& class_list, + const EncodableList* nullable_class_list, + const EncodableMap& class_map, + const EncodableMap* nullable_class_map) : all_nullable_types_( std::make_unique(all_nullable_types)), all_nullable_types_without_recursion_( @@ -1386,8 +1898,15 @@ AllClassesWrapper::AllClassesWrapper(const AllNullableTypes& all_nullable_types, ? std::make_unique( *all_nullable_types_without_recursion) : nullptr), - all_types_(all_types ? std::make_unique(*all_types) : nullptr) { -} + all_types_(all_types ? std::make_unique(*all_types) : nullptr), + class_list_(class_list), + nullable_class_list_(nullable_class_list ? std::optional( + *nullable_class_list) + : std::nullopt), + class_map_(class_map), + nullable_class_map_(nullable_class_map + ? std::optional(*nullable_class_map) + : std::nullopt) {} AllClassesWrapper::AllClassesWrapper(const AllClassesWrapper& other) : all_nullable_types_( @@ -1399,7 +1918,17 @@ AllClassesWrapper::AllClassesWrapper(const AllClassesWrapper& other) : nullptr), all_types_(other.all_types_ ? std::make_unique(*other.all_types_) - : nullptr) {} + : nullptr), + class_list_(other.class_list_), + nullable_class_list_( + other.nullable_class_list_ + ? std::optional(*other.nullable_class_list_) + : std::nullopt), + class_map_(other.class_map_), + nullable_class_map_( + other.nullable_class_map_ + ? std::optional(*other.nullable_class_map_) + : std::nullopt) {} AllClassesWrapper& AllClassesWrapper::operator=( const AllClassesWrapper& other) { @@ -1412,6 +1941,10 @@ AllClassesWrapper& AllClassesWrapper::operator=( : nullptr; all_types_ = other.all_types_ ? std::make_unique(*other.all_types_) : nullptr; + class_list_ = other.class_list_; + nullable_class_list_ = other.nullable_class_list_; + class_map_ = other.class_map_; + nullable_class_map_ = other.nullable_class_map_; return *this; } @@ -1454,9 +1987,51 @@ void AllClassesWrapper::set_all_types(const AllTypes& value_arg) { all_types_ = std::make_unique(value_arg); } +const EncodableList& AllClassesWrapper::class_list() const { + return class_list_; +} + +void AllClassesWrapper::set_class_list(const EncodableList& value_arg) { + class_list_ = value_arg; +} + +const EncodableList* AllClassesWrapper::nullable_class_list() const { + return nullable_class_list_ ? &(*nullable_class_list_) : nullptr; +} + +void AllClassesWrapper::set_nullable_class_list( + const EncodableList* value_arg) { + nullable_class_list_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllClassesWrapper::set_nullable_class_list( + const EncodableList& value_arg) { + nullable_class_list_ = value_arg; +} + +const EncodableMap& AllClassesWrapper::class_map() const { return class_map_; } + +void AllClassesWrapper::set_class_map(const EncodableMap& value_arg) { + class_map_ = value_arg; +} + +const EncodableMap* AllClassesWrapper::nullable_class_map() const { + return nullable_class_map_ ? &(*nullable_class_map_) : nullptr; +} + +void AllClassesWrapper::set_nullable_class_map(const EncodableMap* value_arg) { + nullable_class_map_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllClassesWrapper::set_nullable_class_map(const EncodableMap& value_arg) { + nullable_class_map_ = value_arg; +} + EncodableList AllClassesWrapper::ToEncodableList() const { EncodableList list; - list.reserve(3); + list.reserve(7); list.push_back(CustomEncodableValue(*all_nullable_types_)); list.push_back( all_nullable_types_without_recursion_ @@ -1464,13 +2039,21 @@ EncodableList AllClassesWrapper::ToEncodableList() const { : EncodableValue()); list.push_back(all_types_ ? CustomEncodableValue(*all_types_) : EncodableValue()); + list.push_back(EncodableValue(class_list_)); + list.push_back(nullable_class_list_ ? EncodableValue(*nullable_class_list_) + : EncodableValue()); + list.push_back(EncodableValue(class_map_)); + list.push_back(nullable_class_map_ ? EncodableValue(*nullable_class_map_) + : EncodableValue()); return list; } AllClassesWrapper AllClassesWrapper::FromEncodableList( const EncodableList& list) { AllClassesWrapper decoded(std::any_cast( - std::get(list[0]))); + std::get(list[0])), + std::get(list[3]), + std::get(list[5])); auto& encodable_all_nullable_types_without_recursion = list[1]; if (!encodable_all_nullable_types_without_recursion.IsNull()) { decoded.set_all_nullable_types_without_recursion( @@ -1483,6 +2066,16 @@ AllClassesWrapper AllClassesWrapper::FromEncodableList( decoded.set_all_types(std::any_cast( std::get(encodable_all_types))); } + auto& encodable_nullable_class_list = list[4]; + if (!encodable_nullable_class_list.IsNull()) { + decoded.set_nullable_class_list( + std::get(encodable_nullable_class_list)); + } + auto& encodable_nullable_class_map = list[6]; + if (!encodable_nullable_class_map.IsNull()) { + decoded.set_nullable_class_map( + std::get(encodable_nullable_class_map)); + } return decoded; } @@ -1523,53 +2116,93 @@ TestMessage TestMessage::FromEncodableList(const EncodableList& list) { return decoded; } -PigeonCodecSerializer::PigeonCodecSerializer() {} +PigeonInternalCodecSerializer::PigeonInternalCodecSerializer() {} -EncodableValue PigeonCodecSerializer::ReadValueOfType( +EncodableValue PigeonInternalCodecSerializer::ReadValueOfType( uint8_t type, flutter::ByteStreamReader* stream) const { switch (type) { - case 129: + case 129: { + const auto& encodable_enum_arg = ReadValue(stream); + const int64_t enum_arg_value = + encodable_enum_arg.IsNull() ? 0 : encodable_enum_arg.LongValue(); + return encodable_enum_arg.IsNull() + ? EncodableValue() + : CustomEncodableValue(static_cast(enum_arg_value)); + } + case 130: { + const auto& encodable_enum_arg = ReadValue(stream); + const int64_t enum_arg_value = + encodable_enum_arg.IsNull() ? 0 : encodable_enum_arg.LongValue(); + return encodable_enum_arg.IsNull() + ? EncodableValue() + : CustomEncodableValue( + static_cast(enum_arg_value)); + } + case 131: { + return CustomEncodableValue(UnusedClass::FromEncodableList( + std::get(ReadValue(stream)))); + } + case 132: { return CustomEncodableValue(AllTypes::FromEncodableList( std::get(ReadValue(stream)))); - case 130: + } + case 133: { return CustomEncodableValue(AllNullableTypes::FromEncodableList( std::get(ReadValue(stream)))); - case 131: + } + case 134: { return CustomEncodableValue( AllNullableTypesWithoutRecursion::FromEncodableList( std::get(ReadValue(stream)))); - case 132: + } + case 135: { return CustomEncodableValue(AllClassesWrapper::FromEncodableList( std::get(ReadValue(stream)))); - case 133: + } + case 136: { return CustomEncodableValue(TestMessage::FromEncodableList( std::get(ReadValue(stream)))); - case 134: { - const auto& encodable_enum_arg = ReadValue(stream); - const int64_t enum_arg_value = - encodable_enum_arg.IsNull() ? 0 : encodable_enum_arg.LongValue(); - return encodable_enum_arg.IsNull() - ? EncodableValue() - : CustomEncodableValue(static_cast(enum_arg_value)); } default: return flutter::StandardCodecSerializer::ReadValueOfType(type, stream); } } -void PigeonCodecSerializer::WriteValue( +void PigeonInternalCodecSerializer::WriteValue( const EncodableValue& value, flutter::ByteStreamWriter* stream) const { if (const CustomEncodableValue* custom_value = std::get_if(&value)) { - if (custom_value->type() == typeid(AllTypes)) { + if (custom_value->type() == typeid(AnEnum)) { stream->WriteByte(129); + WriteValue(EncodableValue( + static_cast(std::any_cast(*custom_value))), + stream); + return; + } + if (custom_value->type() == typeid(AnotherEnum)) { + stream->WriteByte(130); + WriteValue(EncodableValue(static_cast( + std::any_cast(*custom_value))), + stream); + return; + } + if (custom_value->type() == typeid(UnusedClass)) { + stream->WriteByte(131); + WriteValue( + EncodableValue( + std::any_cast(*custom_value).ToEncodableList()), + stream); + return; + } + if (custom_value->type() == typeid(AllTypes)) { + stream->WriteByte(132); WriteValue(EncodableValue( std::any_cast(*custom_value).ToEncodableList()), stream); return; } if (custom_value->type() == typeid(AllNullableTypes)) { - stream->WriteByte(130); + stream->WriteByte(133); WriteValue( EncodableValue( std::any_cast(*custom_value).ToEncodableList()), @@ -1577,7 +2210,7 @@ void PigeonCodecSerializer::WriteValue( return; } if (custom_value->type() == typeid(AllNullableTypesWithoutRecursion)) { - stream->WriteByte(131); + stream->WriteByte(134); WriteValue(EncodableValue(std::any_cast( *custom_value) .ToEncodableList()), @@ -1585,27 +2218,20 @@ void PigeonCodecSerializer::WriteValue( return; } if (custom_value->type() == typeid(AllClassesWrapper)) { - stream->WriteByte(132); + stream->WriteByte(135); WriteValue(EncodableValue(std::any_cast(*custom_value) .ToEncodableList()), stream); return; } if (custom_value->type() == typeid(TestMessage)) { - stream->WriteByte(133); + stream->WriteByte(136); WriteValue( EncodableValue( std::any_cast(*custom_value).ToEncodableList()), stream); return; } - if (custom_value->type() == typeid(AnEnum)) { - stream->WriteByte(134); - WriteValue(EncodableValue( - static_cast(std::any_cast(*custom_value))), - stream); - return; - } } flutter::StandardCodecSerializer::WriteValue(value, stream); } @@ -1613,7 +2239,7 @@ void PigeonCodecSerializer::WriteValue( /// The codec used by HostIntegrationCoreApi. const flutter::StandardMessageCodec& HostIntegrationCoreApi::GetCodec() { return flutter::StandardMessageCodec::GetInstance( - &PigeonCodecSerializer::GetInstance()); + &PigeonInternalCodecSerializer::GetInstance()); } // Sets up an instance of `HostIntegrationCoreApi` to handle messages through @@ -2033,7 +2659,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.echoMap" + + "HostIntegrationCoreApi.echoEnumList" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -2042,14 +2668,14 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_map_arg = args.at(0); - if (encodable_a_map_arg.IsNull()) { - reply(WrapError("a_map_arg unexpectedly null.")); + const auto& encodable_enum_list_arg = args.at(0); + if (encodable_enum_list_arg.IsNull()) { + reply(WrapError("enum_list_arg unexpectedly null.")); return; } - const auto& a_map_arg = - std::get(encodable_a_map_arg); - ErrorOr output = api->EchoMap(a_map_arg); + const auto& enum_list_arg = + std::get(encodable_enum_list_arg); + ErrorOr output = api->EchoEnumList(enum_list_arg); if (output.has_error()) { reply(WrapError(output.error())); return; @@ -2068,7 +2694,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.echoClassWrapper" + + "HostIntegrationCoreApi.echoClassList" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -2077,22 +2703,21 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_wrapper_arg = args.at(0); - if (encodable_wrapper_arg.IsNull()) { - reply(WrapError("wrapper_arg unexpectedly null.")); + const auto& encodable_class_list_arg = args.at(0); + if (encodable_class_list_arg.IsNull()) { + reply(WrapError("class_list_arg unexpectedly null.")); return; } - const auto& wrapper_arg = std::any_cast( - std::get(encodable_wrapper_arg)); - ErrorOr output = - api->EchoClassWrapper(wrapper_arg); + const auto& class_list_arg = + std::get(encodable_class_list_arg); + ErrorOr output = + api->EchoClassList(class_list_arg); if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; - wrapped.push_back( - CustomEncodableValue(std::move(output).TakeValue())); + wrapped.push_back(EncodableValue(std::move(output).TakeValue())); reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); @@ -2105,7 +2730,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.echoEnum" + + "HostIntegrationCoreApi.echoNonNullEnumList" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -2114,21 +2739,21 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_an_enum_arg = args.at(0); - if (encodable_an_enum_arg.IsNull()) { - reply(WrapError("an_enum_arg unexpectedly null.")); + const auto& encodable_enum_list_arg = args.at(0); + if (encodable_enum_list_arg.IsNull()) { + reply(WrapError("enum_list_arg unexpectedly null.")); return; } - const auto& an_enum_arg = std::any_cast( - std::get(encodable_an_enum_arg)); - ErrorOr output = api->EchoEnum(an_enum_arg); + const auto& enum_list_arg = + std::get(encodable_enum_list_arg); + ErrorOr output = + api->EchoNonNullEnumList(enum_list_arg); if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; - wrapped.push_back( - CustomEncodableValue(std::move(output).TakeValue())); + wrapped.push_back(EncodableValue(std::move(output).TakeValue())); reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); @@ -2142,7 +2767,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, BasicMessageChannel<> channel( binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "echoNamedDefaultString" + + "echoNonNullClassList" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -2151,15 +2776,15 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_string_arg = args.at(0); - if (encodable_a_string_arg.IsNull()) { - reply(WrapError("a_string_arg unexpectedly null.")); + const auto& encodable_class_list_arg = args.at(0); + if (encodable_class_list_arg.IsNull()) { + reply(WrapError("class_list_arg unexpectedly null.")); return; } - const auto& a_string_arg = - std::get(encodable_a_string_arg); - ErrorOr output = - api->EchoNamedDefaultString(a_string_arg); + const auto& class_list_arg = + std::get(encodable_class_list_arg); + ErrorOr output = + api->EchoNonNullClassList(class_list_arg); if (output.has_error()) { reply(WrapError(output.error())); return; @@ -2176,27 +2801,24 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel( - binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "echoOptionalDefaultDouble" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.echoMap" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_double_arg = args.at(0); - if (encodable_a_double_arg.IsNull()) { - reply(WrapError("a_double_arg unexpectedly null.")); + const auto& encodable_map_arg = args.at(0); + if (encodable_map_arg.IsNull()) { + reply(WrapError("map_arg unexpectedly null.")); return; } - const auto& a_double_arg = - std::get(encodable_a_double_arg); - ErrorOr output = - api->EchoOptionalDefaultDouble(a_double_arg); + const auto& map_arg = std::get(encodable_map_arg); + ErrorOr output = api->EchoMap(map_arg); if (output.has_error()) { reply(WrapError(output.error())); return; @@ -2215,7 +2837,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.echoRequiredInt" + + "HostIntegrationCoreApi.echoStringMap" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -2224,13 +2846,14 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_an_int_arg = args.at(0); - if (encodable_an_int_arg.IsNull()) { - reply(WrapError("an_int_arg unexpectedly null.")); + const auto& encodable_string_map_arg = args.at(0); + if (encodable_string_map_arg.IsNull()) { + reply(WrapError("string_map_arg unexpectedly null.")); return; } - const int64_t an_int_arg = encodable_an_int_arg.LongValue(); - ErrorOr output = api->EchoRequiredInt(an_int_arg); + const auto& string_map_arg = + std::get(encodable_string_map_arg); + ErrorOr output = api->EchoStringMap(string_map_arg); if (output.has_error()) { reply(WrapError(output.error())); return; @@ -2247,39 +2870,31 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel( - binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "echoAllNullableTypes" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.echoIntMap" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_everything_arg = args.at(0); - const auto* everything_arg = - encodable_everything_arg.IsNull() - ? nullptr - : &(std::any_cast( - std::get( - encodable_everything_arg))); - ErrorOr> output = - api->EchoAllNullableTypes(everything_arg); + const auto& encodable_int_map_arg = args.at(0); + if (encodable_int_map_arg.IsNull()) { + reply(WrapError("int_map_arg unexpectedly null.")); + return; + } + const auto& int_map_arg = + std::get(encodable_int_map_arg); + ErrorOr output = api->EchoIntMap(int_map_arg); if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - CustomEncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } + wrapped.push_back(EncodableValue(std::move(output).TakeValue())); reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); @@ -2290,83 +2905,31 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel( - binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "echoAllNullableTypesWithoutRecursion" + - prepended_suffix, - &GetCodec()); - if (api != nullptr) { - channel.SetMessageHandler([api]( - const EncodableValue& message, - const flutter::MessageReply& - reply) { - try { - const auto& args = std::get(message); - const auto& encodable_everything_arg = args.at(0); - const auto* everything_arg = - encodable_everything_arg.IsNull() - ? nullptr - : &(std::any_cast( - std::get( - encodable_everything_arg))); - ErrorOr> output = - api->EchoAllNullableTypesWithoutRecursion(everything_arg); - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - CustomEncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } - reply(EncodableValue(std::move(wrapped))); - } catch (const std::exception& exception) { - reply(WrapError(exception.what())); - } - }); - } else { - channel.SetMessageHandler(nullptr); - } - } - { - BasicMessageChannel<> channel( - binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "extractNestedNullableString" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.echoEnumMap" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_wrapper_arg = args.at(0); - if (encodable_wrapper_arg.IsNull()) { - reply(WrapError("wrapper_arg unexpectedly null.")); + const auto& encodable_enum_map_arg = args.at(0); + if (encodable_enum_map_arg.IsNull()) { + reply(WrapError("enum_map_arg unexpectedly null.")); return; } - const auto& wrapper_arg = std::any_cast( - std::get(encodable_wrapper_arg)); - ErrorOr> output = - api->ExtractNestedNullableString(wrapper_arg); + const auto& enum_map_arg = + std::get(encodable_enum_map_arg); + ErrorOr output = api->EchoEnumMap(enum_map_arg); if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } + wrapped.push_back(EncodableValue(std::move(output).TakeValue())); reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); @@ -2377,30 +2940,31 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel( - binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "createNestedNullableString" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.echoClassMap" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_nullable_string_arg = args.at(0); - const auto* nullable_string_arg = - std::get_if(&encodable_nullable_string_arg); - ErrorOr output = - api->CreateNestedNullableString(nullable_string_arg); + const auto& encodable_class_map_arg = args.at(0); + if (encodable_class_map_arg.IsNull()) { + reply(WrapError("class_map_arg unexpectedly null.")); + return; + } + const auto& class_map_arg = + std::get(encodable_class_map_arg); + ErrorOr output = api->EchoClassMap(class_map_arg); if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; - wrapped.push_back( - CustomEncodableValue(std::move(output).TakeValue())); + wrapped.push_back(EncodableValue(std::move(output).TakeValue())); reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); @@ -2414,7 +2978,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, BasicMessageChannel<> channel( binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "sendMultipleNullableTypes" + + "echoNonNullStringMap" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -2423,31 +2987,21 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_nullable_bool_arg = args.at(0); - const auto* a_nullable_bool_arg = - std::get_if(&encodable_a_nullable_bool_arg); - const auto& encodable_a_nullable_int_arg = args.at(1); - const int64_t a_nullable_int_arg_value = - encodable_a_nullable_int_arg.IsNull() - ? 0 - : encodable_a_nullable_int_arg.LongValue(); - const auto* a_nullable_int_arg = - encodable_a_nullable_int_arg.IsNull() - ? nullptr - : &a_nullable_int_arg_value; - const auto& encodable_a_nullable_string_arg = args.at(2); - const auto* a_nullable_string_arg = - std::get_if(&encodable_a_nullable_string_arg); - ErrorOr output = api->SendMultipleNullableTypes( - a_nullable_bool_arg, a_nullable_int_arg, - a_nullable_string_arg); + const auto& encodable_string_map_arg = args.at(0); + if (encodable_string_map_arg.IsNull()) { + reply(WrapError("string_map_arg unexpectedly null.")); + return; + } + const auto& string_map_arg = + std::get(encodable_string_map_arg); + ErrorOr output = + api->EchoNonNullStringMap(string_map_arg); if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; - wrapped.push_back( - CustomEncodableValue(std::move(output).TakeValue())); + wrapped.push_back(EncodableValue(std::move(output).TakeValue())); reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); @@ -2458,44 +3012,32 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel( - binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "sendMultipleNullableTypesWithoutRecursion" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.echoNonNullIntMap" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_nullable_bool_arg = args.at(0); - const auto* a_nullable_bool_arg = - std::get_if(&encodable_a_nullable_bool_arg); - const auto& encodable_a_nullable_int_arg = args.at(1); - const int64_t a_nullable_int_arg_value = - encodable_a_nullable_int_arg.IsNull() - ? 0 - : encodable_a_nullable_int_arg.LongValue(); - const auto* a_nullable_int_arg = - encodable_a_nullable_int_arg.IsNull() - ? nullptr - : &a_nullable_int_arg_value; - const auto& encodable_a_nullable_string_arg = args.at(2); - const auto* a_nullable_string_arg = - std::get_if(&encodable_a_nullable_string_arg); - ErrorOr output = - api->SendMultipleNullableTypesWithoutRecursion( - a_nullable_bool_arg, a_nullable_int_arg, - a_nullable_string_arg); + const auto& encodable_int_map_arg = args.at(0); + if (encodable_int_map_arg.IsNull()) { + reply(WrapError("int_map_arg unexpectedly null.")); + return; + } + const auto& int_map_arg = + std::get(encodable_int_map_arg); + ErrorOr output = + api->EchoNonNullIntMap(int_map_arg); if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; - wrapped.push_back( - CustomEncodableValue(std::move(output).TakeValue())); + wrapped.push_back(EncodableValue(std::move(output).TakeValue())); reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); @@ -2508,7 +3050,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.echoNullableInt" + + "HostIntegrationCoreApi.echoNonNullEnumMap" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -2517,29 +3059,21 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_nullable_int_arg = args.at(0); - const int64_t a_nullable_int_arg_value = - encodable_a_nullable_int_arg.IsNull() - ? 0 - : encodable_a_nullable_int_arg.LongValue(); - const auto* a_nullable_int_arg = - encodable_a_nullable_int_arg.IsNull() - ? nullptr - : &a_nullable_int_arg_value; - ErrorOr> output = - api->EchoNullableInt(a_nullable_int_arg); + const auto& encodable_enum_map_arg = args.at(0); + if (encodable_enum_map_arg.IsNull()) { + reply(WrapError("enum_map_arg unexpectedly null.")); + return; + } + const auto& enum_map_arg = + std::get(encodable_enum_map_arg); + ErrorOr output = + api->EchoNonNullEnumMap(enum_map_arg); if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } + wrapped.push_back(EncodableValue(std::move(output).TakeValue())); reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); @@ -2552,7 +3086,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.echoNullableDouble" + + "HostIntegrationCoreApi.echoNonNullClassMap" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -2561,23 +3095,21 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_nullable_double_arg = args.at(0); - const auto* a_nullable_double_arg = - std::get_if(&encodable_a_nullable_double_arg); - ErrorOr> output = - api->EchoNullableDouble(a_nullable_double_arg); + const auto& encodable_class_map_arg = args.at(0); + if (encodable_class_map_arg.IsNull()) { + reply(WrapError("class_map_arg unexpectedly null.")); + return; + } + const auto& class_map_arg = + std::get(encodable_class_map_arg); + ErrorOr output = + api->EchoNonNullClassMap(class_map_arg); if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } + wrapped.push_back(EncodableValue(std::move(output).TakeValue())); reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); @@ -2590,7 +3122,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.echoNullableBool" + + "HostIntegrationCoreApi.echoClassWrapper" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -2599,23 +3131,22 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_nullable_bool_arg = args.at(0); - const auto* a_nullable_bool_arg = - std::get_if(&encodable_a_nullable_bool_arg); - ErrorOr> output = - api->EchoNullableBool(a_nullable_bool_arg); + const auto& encodable_wrapper_arg = args.at(0); + if (encodable_wrapper_arg.IsNull()) { + reply(WrapError("wrapper_arg unexpectedly null.")); + return; + } + const auto& wrapper_arg = std::any_cast( + std::get(encodable_wrapper_arg)); + ErrorOr output = + api->EchoClassWrapper(wrapper_arg); if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } + wrapped.push_back( + CustomEncodableValue(std::move(output).TakeValue())); reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); @@ -2628,7 +3159,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.echoNullableString" + + "HostIntegrationCoreApi.echoEnum" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -2637,23 +3168,21 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_nullable_string_arg = args.at(0); - const auto* a_nullable_string_arg = - std::get_if(&encodable_a_nullable_string_arg); - ErrorOr> output = - api->EchoNullableString(a_nullable_string_arg); + const auto& encodable_an_enum_arg = args.at(0); + if (encodable_an_enum_arg.IsNull()) { + reply(WrapError("an_enum_arg unexpectedly null.")); + return; + } + const auto& an_enum_arg = std::any_cast( + std::get(encodable_an_enum_arg)); + ErrorOr output = api->EchoEnum(an_enum_arg); if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } + wrapped.push_back( + CustomEncodableValue(std::move(output).TakeValue())); reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); @@ -2664,36 +3193,33 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel( - binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "echoNullableUint8List" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.echoAnotherEnum" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_nullable_uint8_list_arg = args.at(0); - const auto* a_nullable_uint8_list_arg = - std::get_if>( - &encodable_a_nullable_uint8_list_arg); - ErrorOr>> output = - api->EchoNullableUint8List(a_nullable_uint8_list_arg); + const auto& encodable_another_enum_arg = args.at(0); + if (encodable_another_enum_arg.IsNull()) { + reply(WrapError("another_enum_arg unexpectedly null.")); + return; + } + const auto& another_enum_arg = std::any_cast( + std::get(encodable_another_enum_arg)); + ErrorOr output = + api->EchoAnotherEnum(another_enum_arg); if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } + wrapped.push_back( + CustomEncodableValue(std::move(output).TakeValue())); reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); @@ -2704,34 +3230,33 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel(binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.echoNullableObject" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNamedDefaultString" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_nullable_object_arg = args.at(0); - const auto* a_nullable_object_arg = - &encodable_a_nullable_object_arg; - ErrorOr> output = - api->EchoNullableObject(a_nullable_object_arg); + const auto& encodable_a_string_arg = args.at(0); + if (encodable_a_string_arg.IsNull()) { + reply(WrapError("a_string_arg unexpectedly null.")); + return; + } + const auto& a_string_arg = + std::get(encodable_a_string_arg); + ErrorOr output = + api->EchoNamedDefaultString(a_string_arg); if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } + wrapped.push_back(EncodableValue(std::move(output).TakeValue())); reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); @@ -2742,34 +3267,33 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel(binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.echoNullableList" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoOptionalDefaultDouble" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_nullable_list_arg = args.at(0); - const auto* a_nullable_list_arg = - std::get_if(&encodable_a_nullable_list_arg); - ErrorOr> output = - api->EchoNullableList(a_nullable_list_arg); + const auto& encodable_a_double_arg = args.at(0); + if (encodable_a_double_arg.IsNull()) { + reply(WrapError("a_double_arg unexpectedly null.")); + return; + } + const auto& a_double_arg = + std::get(encodable_a_double_arg); + ErrorOr output = + api->EchoOptionalDefaultDouble(a_double_arg); if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } + wrapped.push_back(EncodableValue(std::move(output).TakeValue())); reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); @@ -2782,7 +3306,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.echoNullableMap" + + "HostIntegrationCoreApi.echoRequiredInt" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -2791,23 +3315,19 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_nullable_map_arg = args.at(0); - const auto* a_nullable_map_arg = - std::get_if(&encodable_a_nullable_map_arg); - ErrorOr> output = - api->EchoNullableMap(a_nullable_map_arg); + const auto& encodable_an_int_arg = args.at(0); + if (encodable_an_int_arg.IsNull()) { + reply(WrapError("an_int_arg unexpectedly null.")); + return; + } + const int64_t an_int_arg = encodable_an_int_arg.LongValue(); + ErrorOr output = api->EchoRequiredInt(an_int_arg); if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } + wrapped.push_back(EncodableValue(std::move(output).TakeValue())); reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); @@ -2818,27 +3338,27 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel(binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.echoNullableEnum" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAllNullableTypes" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_an_enum_arg = args.at(0); - AnEnum an_enum_arg_value; - const AnEnum* an_enum_arg = nullptr; - if (!encodable_an_enum_arg.IsNull()) { - an_enum_arg_value = std::any_cast( - std::get(encodable_an_enum_arg)); - an_enum_arg = &an_enum_arg_value; - } - ErrorOr> output = api->EchoNullableEnum( - an_enum_arg ? &(*an_enum_arg) : nullptr); + const auto& encodable_everything_arg = args.at(0); + const auto* everything_arg = + encodable_everything_arg.IsNull() + ? nullptr + : &(std::any_cast( + std::get( + encodable_everything_arg))); + ErrorOr> output = + api->EchoAllNullableTypes(everything_arg); if (output.has_error()) { reply(WrapError(output.error())); return; @@ -2864,7 +3384,51 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, BasicMessageChannel<> channel( binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "echoOptionalNullableInt" + + "echoAllNullableTypesWithoutRecursion" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler([api]( + const EncodableValue& message, + const flutter::MessageReply& + reply) { + try { + const auto& args = std::get(message); + const auto& encodable_everything_arg = args.at(0); + const auto* everything_arg = + encodable_everything_arg.IsNull() + ? nullptr + : &(std::any_cast( + std::get( + encodable_everything_arg))); + ErrorOr> output = + api->EchoAllNullableTypesWithoutRecursion(everything_arg); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + CustomEncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "extractNestedNullableString" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -2873,17 +3437,15 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_nullable_int_arg = args.at(0); - const int64_t a_nullable_int_arg_value = - encodable_a_nullable_int_arg.IsNull() - ? 0 - : encodable_a_nullable_int_arg.LongValue(); - const auto* a_nullable_int_arg = - encodable_a_nullable_int_arg.IsNull() - ? nullptr - : &a_nullable_int_arg_value; - ErrorOr> output = - api->EchoOptionalNullableInt(a_nullable_int_arg); + const auto& encodable_wrapper_arg = args.at(0); + if (encodable_wrapper_arg.IsNull()) { + reply(WrapError("wrapper_arg unexpectedly null.")); + return; + } + const auto& wrapper_arg = std::any_cast( + std::get(encodable_wrapper_arg)); + ErrorOr> output = + api->ExtractNestedNullableString(wrapper_arg); if (output.has_error()) { reply(WrapError(output.error())); return; @@ -2909,7 +3471,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, BasicMessageChannel<> channel( binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "echoNamedNullableString" + + "createNestedNullableString" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -2918,23 +3480,18 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_nullable_string_arg = args.at(0); - const auto* a_nullable_string_arg = - std::get_if(&encodable_a_nullable_string_arg); - ErrorOr> output = - api->EchoNamedNullableString(a_nullable_string_arg); + const auto& encodable_nullable_string_arg = args.at(0); + const auto* nullable_string_arg = + std::get_if(&encodable_nullable_string_arg); + ErrorOr output = + api->CreateNestedNullableString(nullable_string_arg); if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } + wrapped.push_back( + CustomEncodableValue(std::move(output).TakeValue())); reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); @@ -2945,25 +3502,38 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel(binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.noopAsync" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "sendMultipleNullableTypes" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { - api->NoopAsync([reply](std::optional&& output) { - if (output.has_value()) { - reply(WrapError(output.value())); - return; - } - EncodableList wrapped; - wrapped.push_back(EncodableValue()); - reply(EncodableValue(std::move(wrapped))); - }); + const auto& args = std::get(message); + const auto& encodable_a_nullable_bool_arg = args.at(0); + const auto* a_nullable_bool_arg = + std::get_if(&encodable_a_nullable_bool_arg); + const auto& encodable_a_nullable_int_arg = args.at(1); + const auto* a_nullable_int_arg = + std::get_if(&encodable_a_nullable_int_arg); + const auto& encodable_a_nullable_string_arg = args.at(2); + const auto* a_nullable_string_arg = + std::get_if(&encodable_a_nullable_string_arg); + ErrorOr output = api->SendMultipleNullableTypes( + a_nullable_bool_arg, a_nullable_int_arg, + a_nullable_string_arg); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + CustomEncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -2973,33 +3543,39 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel(binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.echoAsyncInt" + - prepended_suffix, - &GetCodec()); - if (api != nullptr) { - channel.SetMessageHandler( - [api](const EncodableValue& message, - const flutter::MessageReply& reply) { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "sendMultipleNullableTypesWithoutRecursion" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_an_int_arg = args.at(0); - if (encodable_an_int_arg.IsNull()) { - reply(WrapError("an_int_arg unexpectedly null.")); + const auto& encodable_a_nullable_bool_arg = args.at(0); + const auto* a_nullable_bool_arg = + std::get_if(&encodable_a_nullable_bool_arg); + const auto& encodable_a_nullable_int_arg = args.at(1); + const auto* a_nullable_int_arg = + std::get_if(&encodable_a_nullable_int_arg); + const auto& encodable_a_nullable_string_arg = args.at(2); + const auto* a_nullable_string_arg = + std::get_if(&encodable_a_nullable_string_arg); + ErrorOr output = + api->SendMultipleNullableTypesWithoutRecursion( + a_nullable_bool_arg, a_nullable_int_arg, + a_nullable_string_arg); + if (output.has_error()) { + reply(WrapError(output.error())); return; } - const int64_t an_int_arg = encodable_an_int_arg.LongValue(); - api->EchoAsyncInt(an_int_arg, [reply](ErrorOr&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - wrapped.push_back( - EncodableValue(std::move(output).TakeValue())); - reply(EncodableValue(std::move(wrapped))); - }); + EncodableList wrapped; + wrapped.push_back( + CustomEncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3011,7 +3587,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.echoAsyncDouble" + + "HostIntegrationCoreApi.echoNullableInt" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -3020,24 +3596,24 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_double_arg = args.at(0); - if (encodable_a_double_arg.IsNull()) { - reply(WrapError("a_double_arg unexpectedly null.")); + const auto& encodable_a_nullable_int_arg = args.at(0); + const auto* a_nullable_int_arg = + std::get_if(&encodable_a_nullable_int_arg); + ErrorOr> output = + api->EchoNullableInt(a_nullable_int_arg); + if (output.has_error()) { + reply(WrapError(output.error())); return; } - const auto& a_double_arg = - std::get(encodable_a_double_arg); - api->EchoAsyncDouble( - a_double_arg, [reply](ErrorOr&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - wrapped.push_back( - EncodableValue(std::move(output).TakeValue())); - reply(EncodableValue(std::move(wrapped))); - }); + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3049,7 +3625,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.echoAsyncBool" + + "HostIntegrationCoreApi.echoNullableDouble" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -3058,22 +3634,24 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_bool_arg = args.at(0); - if (encodable_a_bool_arg.IsNull()) { - reply(WrapError("a_bool_arg unexpectedly null.")); + const auto& encodable_a_nullable_double_arg = args.at(0); + const auto* a_nullable_double_arg = + std::get_if(&encodable_a_nullable_double_arg); + ErrorOr> output = + api->EchoNullableDouble(a_nullable_double_arg); + if (output.has_error()) { + reply(WrapError(output.error())); return; } - const auto& a_bool_arg = std::get(encodable_a_bool_arg); - api->EchoAsyncBool(a_bool_arg, [reply](ErrorOr&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { wrapped.push_back( - EncodableValue(std::move(output).TakeValue())); - reply(EncodableValue(std::move(wrapped))); - }); + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3085,7 +3663,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.echoAsyncString" + + "HostIntegrationCoreApi.echoNullableBool" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -3094,24 +3672,24 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_string_arg = args.at(0); - if (encodable_a_string_arg.IsNull()) { - reply(WrapError("a_string_arg unexpectedly null.")); + const auto& encodable_a_nullable_bool_arg = args.at(0); + const auto* a_nullable_bool_arg = + std::get_if(&encodable_a_nullable_bool_arg); + ErrorOr> output = + api->EchoNullableBool(a_nullable_bool_arg); + if (output.has_error()) { + reply(WrapError(output.error())); return; } - const auto& a_string_arg = - std::get(encodable_a_string_arg); - api->EchoAsyncString( - a_string_arg, [reply](ErrorOr&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - wrapped.push_back( - EncodableValue(std::move(output).TakeValue())); - reply(EncodableValue(std::move(wrapped))); - }); + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3123,7 +3701,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.echoAsyncUint8List" + + "HostIntegrationCoreApi.echoNullableString" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -3132,25 +3710,24 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_uint8_list_arg = args.at(0); - if (encodable_a_uint8_list_arg.IsNull()) { - reply(WrapError("a_uint8_list_arg unexpectedly null.")); + const auto& encodable_a_nullable_string_arg = args.at(0); + const auto* a_nullable_string_arg = + std::get_if(&encodable_a_nullable_string_arg); + ErrorOr> output = + api->EchoNullableString(a_nullable_string_arg); + if (output.has_error()) { + reply(WrapError(output.error())); return; } - const auto& a_uint8_list_arg = - std::get>(encodable_a_uint8_list_arg); - api->EchoAsyncUint8List( - a_uint8_list_arg, - [reply](ErrorOr>&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - wrapped.push_back( - EncodableValue(std::move(output).TakeValue())); - reply(EncodableValue(std::move(wrapped))); - }); + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3160,34 +3737,37 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel(binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.echoAsyncObject" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableUint8List" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_an_object_arg = args.at(0); - if (encodable_an_object_arg.IsNull()) { - reply(WrapError("an_object_arg unexpectedly null.")); + const auto& encodable_a_nullable_uint8_list_arg = args.at(0); + const auto* a_nullable_uint8_list_arg = + std::get_if>( + &encodable_a_nullable_uint8_list_arg); + ErrorOr>> output = + api->EchoNullableUint8List(a_nullable_uint8_list_arg); + if (output.has_error()) { + reply(WrapError(output.error())); return; } - const auto& an_object_arg = encodable_an_object_arg; - api->EchoAsyncObject( - an_object_arg, [reply](ErrorOr&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - wrapped.push_back( - EncodableValue(std::move(output).TakeValue())); - reply(EncodableValue(std::move(wrapped))); - }); + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3199,7 +3779,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.echoAsyncList" + + "HostIntegrationCoreApi.echoNullableObject" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -3208,24 +3788,24 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_list_arg = args.at(0); - if (encodable_list_arg.IsNull()) { - reply(WrapError("list_arg unexpectedly null.")); + const auto& encodable_a_nullable_object_arg = args.at(0); + const auto* a_nullable_object_arg = + &encodable_a_nullable_object_arg; + ErrorOr> output = + api->EchoNullableObject(a_nullable_object_arg); + if (output.has_error()) { + reply(WrapError(output.error())); return; } - const auto& list_arg = - std::get(encodable_list_arg); - api->EchoAsyncList( - list_arg, [reply](ErrorOr&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - wrapped.push_back( - EncodableValue(std::move(output).TakeValue())); - reply(EncodableValue(std::move(wrapped))); - }); + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3237,7 +3817,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.echoAsyncMap" + + "HostIntegrationCoreApi.echoNullableList" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -3246,24 +3826,24 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_map_arg = args.at(0); - if (encodable_a_map_arg.IsNull()) { - reply(WrapError("a_map_arg unexpectedly null.")); - return; - } - const auto& a_map_arg = - std::get(encodable_a_map_arg); - api->EchoAsyncMap( - a_map_arg, [reply](ErrorOr&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - wrapped.push_back( - EncodableValue(std::move(output).TakeValue())); - reply(EncodableValue(std::move(wrapped))); - }); + const auto& encodable_a_nullable_list_arg = args.at(0); + const auto* a_nullable_list_arg = + std::get_if(&encodable_a_nullable_list_arg); + ErrorOr> output = + api->EchoNullableList(a_nullable_list_arg); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3273,35 +3853,36 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel(binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.echoAsyncEnum" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableEnumList" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_an_enum_arg = args.at(0); - if (encodable_an_enum_arg.IsNull()) { - reply(WrapError("an_enum_arg unexpectedly null.")); + const auto& encodable_enum_list_arg = args.at(0); + const auto* enum_list_arg = + std::get_if(&encodable_enum_list_arg); + ErrorOr> output = + api->EchoNullableEnumList(enum_list_arg); + if (output.has_error()) { + reply(WrapError(output.error())); return; } - const auto& an_enum_arg = std::any_cast( - std::get(encodable_an_enum_arg)); - api->EchoAsyncEnum( - an_enum_arg, [reply](ErrorOr&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - wrapped.push_back( - CustomEncodableValue(std::move(output).TakeValue())); - reply(EncodableValue(std::move(wrapped))); - }); + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3311,32 +3892,36 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel(binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.throwAsyncError" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoNullableClassList" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { - api->ThrowAsyncError( - [reply](ErrorOr>&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } - reply(EncodableValue(std::move(wrapped))); - }); + const auto& args = std::get(message); + const auto& encodable_class_list_arg = args.at(0); + const auto* class_list_arg = + std::get_if(&encodable_class_list_arg); + ErrorOr> output = + api->EchoNullableClassList(class_list_arg); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3349,7 +3934,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, BasicMessageChannel<> channel( binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "throwAsyncErrorFromVoid" + + "echoNullableNonNullEnumList" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -3357,16 +3942,25 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { - api->ThrowAsyncErrorFromVoid( - [reply](std::optional&& output) { - if (output.has_value()) { - reply(WrapError(output.value())); - return; - } - EncodableList wrapped; - wrapped.push_back(EncodableValue()); - reply(EncodableValue(std::move(wrapped))); - }); + const auto& args = std::get(message); + const auto& encodable_enum_list_arg = args.at(0); + const auto* enum_list_arg = + std::get_if(&encodable_enum_list_arg); + ErrorOr> output = + api->EchoNullableNonNullEnumList(enum_list_arg); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3379,7 +3973,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, BasicMessageChannel<> channel( binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "throwAsyncFlutterError" + + "echoNullableNonNullClassList" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -3387,22 +3981,25 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { - api->ThrowAsyncFlutterError( - [reply](ErrorOr>&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } - reply(EncodableValue(std::move(wrapped))); - }); + const auto& args = std::get(message); + const auto& encodable_class_list_arg = args.at(0); + const auto* class_list_arg = + std::get_if(&encodable_class_list_arg); + ErrorOr> output = + api->EchoNullableNonNullClassList(class_list_arg); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3414,7 +4011,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.echoAsyncAllTypes" + + "HostIntegrationCoreApi.echoNullableMap" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -3423,24 +4020,24 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_everything_arg = args.at(0); - if (encodable_everything_arg.IsNull()) { - reply(WrapError("everything_arg unexpectedly null.")); + const auto& encodable_map_arg = args.at(0); + const auto* map_arg = + std::get_if(&encodable_map_arg); + ErrorOr> output = + api->EchoNullableMap(map_arg); + if (output.has_error()) { + reply(WrapError(output.error())); return; } - const auto& everything_arg = std::any_cast( - std::get(encodable_everything_arg)); - api->EchoAsyncAllTypes( - everything_arg, [reply](ErrorOr&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - wrapped.push_back( - CustomEncodableValue(std::move(output).TakeValue())); - reply(EncodableValue(std::move(wrapped))); - }); + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3453,7 +4050,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, BasicMessageChannel<> channel( binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "echoAsyncNullableAllNullableTypes" + + "echoNullableStringMap" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -3462,30 +4059,24 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_everything_arg = args.at(0); - const auto* everything_arg = - encodable_everything_arg.IsNull() - ? nullptr - : &(std::any_cast( - std::get( - encodable_everything_arg))); - api->EchoAsyncNullableAllNullableTypes( - everything_arg, - [reply](ErrorOr>&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back(CustomEncodableValue( - std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } - reply(EncodableValue(std::move(wrapped))); - }); + const auto& encodable_string_map_arg = args.at(0); + const auto* string_map_arg = + std::get_if(&encodable_string_map_arg); + ErrorOr> output = + api->EchoNullableStringMap(string_map_arg); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3495,89 +4086,35 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel( - binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "echoAsyncNullableAllNullableTypesWithoutRecursion" + - prepended_suffix, - &GetCodec()); - if (api != nullptr) { - channel.SetMessageHandler([api]( - const EncodableValue& message, - const flutter::MessageReply& - reply) { - try { - const auto& args = std::get(message); - const auto& encodable_everything_arg = args.at(0); - const auto* everything_arg = - encodable_everything_arg.IsNull() - ? nullptr - : &(std::any_cast( - std::get( - encodable_everything_arg))); - api->EchoAsyncNullableAllNullableTypesWithoutRecursion( - everything_arg, - [reply](ErrorOr>&& - output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - CustomEncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } - reply(EncodableValue(std::move(wrapped))); - }); - } catch (const std::exception& exception) { - reply(WrapError(exception.what())); - } - }); - } else { - channel.SetMessageHandler(nullptr); - } - } - { - BasicMessageChannel<> channel( - binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "echoAsyncNullableInt" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.echoNullableIntMap" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_an_int_arg = args.at(0); - const int64_t an_int_arg_value = - encodable_an_int_arg.IsNull() - ? 0 - : encodable_an_int_arg.LongValue(); - const auto* an_int_arg = - encodable_an_int_arg.IsNull() ? nullptr : &an_int_arg_value; - api->EchoAsyncNullableInt( - an_int_arg, - [reply](ErrorOr>&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } - reply(EncodableValue(std::move(wrapped))); - }); + const auto& encodable_int_map_arg = args.at(0); + const auto* int_map_arg = + std::get_if(&encodable_int_map_arg); + ErrorOr> output = + api->EchoNullableIntMap(int_map_arg); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3587,38 +4124,35 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel( - binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "echoAsyncNullableDouble" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.echoNullableEnumMap" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_double_arg = args.at(0); - const auto* a_double_arg = - std::get_if(&encodable_a_double_arg); - api->EchoAsyncNullableDouble( - a_double_arg, - [reply](ErrorOr>&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } - reply(EncodableValue(std::move(wrapped))); - }); + const auto& encodable_enum_map_arg = args.at(0); + const auto* enum_map_arg = + std::get_if(&encodable_enum_map_arg); + ErrorOr> output = + api->EchoNullableEnumMap(enum_map_arg); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3631,7 +4165,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, BasicMessageChannel<> channel( binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "echoAsyncNullableBool" + + "echoNullableClassMap" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -3640,24 +4174,24 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_bool_arg = args.at(0); - const auto* a_bool_arg = std::get_if(&encodable_a_bool_arg); - api->EchoAsyncNullableBool( - a_bool_arg, [reply](ErrorOr>&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } - reply(EncodableValue(std::move(wrapped))); - }); + const auto& encodable_class_map_arg = args.at(0); + const auto* class_map_arg = + std::get_if(&encodable_class_map_arg); + ErrorOr> output = + api->EchoNullableClassMap(class_map_arg); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3670,7 +4204,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, BasicMessageChannel<> channel( binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "echoAsyncNullableString" + + "echoNullableNonNullStringMap" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -3679,26 +4213,24 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_string_arg = args.at(0); - const auto* a_string_arg = - std::get_if(&encodable_a_string_arg); - api->EchoAsyncNullableString( - a_string_arg, - [reply](ErrorOr>&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } - reply(EncodableValue(std::move(wrapped))); - }); + const auto& encodable_string_map_arg = args.at(0); + const auto* string_map_arg = + std::get_if(&encodable_string_map_arg); + ErrorOr> output = + api->EchoNullableNonNullStringMap(string_map_arg); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3711,7 +4243,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, BasicMessageChannel<> channel( binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "echoAsyncNullableUint8List" + + "echoNullableNonNullIntMap" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -3720,27 +4252,24 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_uint8_list_arg = args.at(0); - const auto* a_uint8_list_arg = std::get_if>( - &encodable_a_uint8_list_arg); - api->EchoAsyncNullableUint8List( - a_uint8_list_arg, - [reply]( - ErrorOr>>&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } - reply(EncodableValue(std::move(wrapped))); - }); + const auto& encodable_int_map_arg = args.at(0); + const auto* int_map_arg = + std::get_if(&encodable_int_map_arg); + ErrorOr> output = + api->EchoNullableNonNullIntMap(int_map_arg); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3753,7 +4282,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, BasicMessageChannel<> channel( binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "echoAsyncNullableObject" + + "echoNullableNonNullEnumMap" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -3762,25 +4291,24 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_an_object_arg = args.at(0); - const auto* an_object_arg = &encodable_an_object_arg; - api->EchoAsyncNullableObject( - an_object_arg, - [reply](ErrorOr>&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } - reply(EncodableValue(std::move(wrapped))); - }); + const auto& encodable_enum_map_arg = args.at(0); + const auto* enum_map_arg = + std::get_if(&encodable_enum_map_arg); + ErrorOr> output = + api->EchoNullableNonNullEnumMap(enum_map_arg); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3793,7 +4321,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, BasicMessageChannel<> channel( binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "echoAsyncNullableList" + + "echoNullableNonNullClassMap" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -3802,26 +4330,24 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_list_arg = args.at(0); - const auto* list_arg = - std::get_if(&encodable_list_arg); - api->EchoAsyncNullableList( - list_arg, - [reply](ErrorOr>&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } - reply(EncodableValue(std::move(wrapped))); - }); + const auto& encodable_class_map_arg = args.at(0); + const auto* class_map_arg = + std::get_if(&encodable_class_map_arg); + ErrorOr> output = + api->EchoNullableNonNullClassMap(class_map_arg); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3831,38 +4357,40 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel( - binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "echoAsyncNullableMap" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.echoNullableEnum" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_map_arg = args.at(0); - const auto* a_map_arg = - std::get_if(&encodable_a_map_arg); - api->EchoAsyncNullableMap( - a_map_arg, - [reply](ErrorOr>&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } - reply(EncodableValue(std::move(wrapped))); - }); + const auto& encodable_an_enum_arg = args.at(0); + AnEnum an_enum_arg_value; + const AnEnum* an_enum_arg = nullptr; + if (!encodable_an_enum_arg.IsNull()) { + an_enum_arg_value = std::any_cast( + std::get(encodable_an_enum_arg)); + an_enum_arg = &an_enum_arg_value; + } + ErrorOr> output = api->EchoNullableEnum( + an_enum_arg ? &(*an_enum_arg) : nullptr); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + CustomEncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3875,7 +4403,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, BasicMessageChannel<> channel( binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "echoAsyncNullableEnum" + + "echoAnotherNullableEnum" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -3884,31 +4412,30 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_an_enum_arg = args.at(0); - AnEnum an_enum_arg_value; - const AnEnum* an_enum_arg = nullptr; - if (!encodable_an_enum_arg.IsNull()) { - an_enum_arg_value = std::any_cast( - std::get(encodable_an_enum_arg)); - an_enum_arg = &an_enum_arg_value; + const auto& encodable_another_enum_arg = args.at(0); + AnotherEnum another_enum_arg_value; + const AnotherEnum* another_enum_arg = nullptr; + if (!encodable_another_enum_arg.IsNull()) { + another_enum_arg_value = std::any_cast( + std::get(encodable_another_enum_arg)); + another_enum_arg = &another_enum_arg_value; } - api->EchoAsyncNullableEnum( - an_enum_arg ? &(*an_enum_arg) : nullptr, - [reply](ErrorOr>&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back(CustomEncodableValue( - std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } - reply(EncodableValue(std::move(wrapped))); - }); + ErrorOr> output = + api->EchoAnotherNullableEnum( + another_enum_arg ? &(*another_enum_arg) : nullptr); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + CustomEncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3918,26 +4445,36 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel(binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.callFlutterNoop" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoOptionalNullableInt" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { - api->CallFlutterNoop( - [reply](std::optional&& output) { - if (output.has_value()) { - reply(WrapError(output.value())); - return; - } - EncodableList wrapped; - wrapped.push_back(EncodableValue()); - reply(EncodableValue(std::move(wrapped))); - }); + const auto& args = std::get(message); + const auto& encodable_a_nullable_int_arg = args.at(0); + const auto* a_nullable_int_arg = + std::get_if(&encodable_a_nullable_int_arg); + ErrorOr> output = + api->EchoOptionalNullableInt(a_nullable_int_arg); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3950,7 +4487,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, BasicMessageChannel<> channel( binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "callFlutterThrowError" + + "echoNamedNullableString" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -3958,22 +4495,25 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { - api->CallFlutterThrowError( - [reply](ErrorOr>&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } - reply(EncodableValue(std::move(wrapped))); - }); + const auto& args = std::get(message); + const auto& encodable_a_nullable_string_arg = args.at(0); + const auto* a_nullable_string_arg = + std::get_if(&encodable_a_nullable_string_arg); + ErrorOr> output = + api->EchoNamedNullableString(a_nullable_string_arg); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -3983,27 +4523,25 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel( - binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "callFlutterThrowErrorFromVoid" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.noopAsync" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { - api->CallFlutterThrowErrorFromVoid( - [reply](std::optional&& output) { - if (output.has_value()) { - reply(WrapError(output.value())); - return; - } - EncodableList wrapped; - wrapped.push_back(EncodableValue()); - reply(EncodableValue(std::move(wrapped))); - }); + api->NoopAsync([reply](std::optional&& output) { + if (output.has_value()) { + reply(WrapError(output.value())); + return; + } + EncodableList wrapped; + wrapped.push_back(EncodableValue()); + reply(EncodableValue(std::move(wrapped))); + }); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -4013,81 +4551,33 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel( - binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "callFlutterEchoAllTypes" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.echoAsyncInt" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_everything_arg = args.at(0); - if (encodable_everything_arg.IsNull()) { - reply(WrapError("everything_arg unexpectedly null.")); + const auto& encodable_an_int_arg = args.at(0); + if (encodable_an_int_arg.IsNull()) { + reply(WrapError("an_int_arg unexpectedly null.")); return; } - const auto& everything_arg = std::any_cast( - std::get(encodable_everything_arg)); - api->CallFlutterEchoAllTypes( - everything_arg, [reply](ErrorOr&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - wrapped.push_back( - CustomEncodableValue(std::move(output).TakeValue())); - reply(EncodableValue(std::move(wrapped))); - }); - } catch (const std::exception& exception) { - reply(WrapError(exception.what())); - } - }); - } else { - channel.SetMessageHandler(nullptr); - } - } - { - BasicMessageChannel<> channel( - binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "callFlutterEchoAllNullableTypes" + - prepended_suffix, - &GetCodec()); - if (api != nullptr) { - channel.SetMessageHandler( - [api](const EncodableValue& message, - const flutter::MessageReply& reply) { - try { - const auto& args = std::get(message); - const auto& encodable_everything_arg = args.at(0); - const auto* everything_arg = - encodable_everything_arg.IsNull() - ? nullptr - : &(std::any_cast( - std::get( - encodable_everything_arg))); - api->CallFlutterEchoAllNullableTypes( - everything_arg, - [reply](ErrorOr>&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back(CustomEncodableValue( - std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } - reply(EncodableValue(std::move(wrapped))); - }); + const int64_t an_int_arg = encodable_an_int_arg.LongValue(); + api->EchoAsyncInt(an_int_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -4097,44 +4587,33 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel( - binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "callFlutterSendMultipleNullableTypes" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.echoAsyncDouble" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_nullable_bool_arg = args.at(0); - const auto* a_nullable_bool_arg = - std::get_if(&encodable_a_nullable_bool_arg); - const auto& encodable_a_nullable_int_arg = args.at(1); - const int64_t a_nullable_int_arg_value = - encodable_a_nullable_int_arg.IsNull() - ? 0 - : encodable_a_nullable_int_arg.LongValue(); - const auto* a_nullable_int_arg = - encodable_a_nullable_int_arg.IsNull() - ? nullptr - : &a_nullable_int_arg_value; - const auto& encodable_a_nullable_string_arg = args.at(2); - const auto* a_nullable_string_arg = - std::get_if(&encodable_a_nullable_string_arg); - api->CallFlutterSendMultipleNullableTypes( - a_nullable_bool_arg, a_nullable_int_arg, - a_nullable_string_arg, - [reply](ErrorOr&& output) { + const auto& encodable_a_double_arg = args.at(0); + if (encodable_a_double_arg.IsNull()) { + reply(WrapError("a_double_arg unexpectedly null.")); + return; + } + const auto& a_double_arg = + std::get(encodable_a_double_arg); + api->EchoAsyncDouble( + a_double_arg, [reply](ErrorOr&& output) { if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; wrapped.push_back( - CustomEncodableValue(std::move(output).TakeValue())); + EncodableValue(std::move(output).TakeValue())); reply(EncodableValue(std::move(wrapped))); }); } catch (const std::exception& exception) { @@ -4146,91 +4625,69 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel( - binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "callFlutterEchoAllNullableTypesWithoutRecursion" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.echoAsyncBool" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { - channel.SetMessageHandler([api]( - const EncodableValue& message, - const flutter::MessageReply& - reply) { - try { - const auto& args = std::get(message); - const auto& encodable_everything_arg = args.at(0); - const auto* everything_arg = - encodable_everything_arg.IsNull() - ? nullptr - : &(std::any_cast( - std::get( - encodable_everything_arg))); - api->CallFlutterEchoAllNullableTypesWithoutRecursion( - everything_arg, - [reply](ErrorOr>&& - output) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_a_bool_arg = args.at(0); + if (encodable_a_bool_arg.IsNull()) { + reply(WrapError("a_bool_arg unexpectedly null.")); + return; + } + const auto& a_bool_arg = std::get(encodable_a_bool_arg); + api->EchoAsyncBool(a_bool_arg, [reply](ErrorOr&& output) { if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - CustomEncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); reply(EncodableValue(std::move(wrapped))); }); - } catch (const std::exception& exception) { - reply(WrapError(exception.what())); - } - }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); } else { channel.SetMessageHandler(nullptr); } } { - BasicMessageChannel<> channel( - binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "callFlutterSendMultipleNullableTypesWithoutRecursion" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.echoAsyncString" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_nullable_bool_arg = args.at(0); - const auto* a_nullable_bool_arg = - std::get_if(&encodable_a_nullable_bool_arg); - const auto& encodable_a_nullable_int_arg = args.at(1); - const int64_t a_nullable_int_arg_value = - encodable_a_nullable_int_arg.IsNull() - ? 0 - : encodable_a_nullable_int_arg.LongValue(); - const auto* a_nullable_int_arg = - encodable_a_nullable_int_arg.IsNull() - ? nullptr - : &a_nullable_int_arg_value; - const auto& encodable_a_nullable_string_arg = args.at(2); - const auto* a_nullable_string_arg = - std::get_if(&encodable_a_nullable_string_arg); - api->CallFlutterSendMultipleNullableTypesWithoutRecursion( - a_nullable_bool_arg, a_nullable_int_arg, - a_nullable_string_arg, - [reply](ErrorOr&& output) { + const auto& encodable_a_string_arg = args.at(0); + if (encodable_a_string_arg.IsNull()) { + reply(WrapError("a_string_arg unexpectedly null.")); + return; + } + const auto& a_string_arg = + std::get(encodable_a_string_arg); + api->EchoAsyncString( + a_string_arg, [reply](ErrorOr&& output) { if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; wrapped.push_back( - CustomEncodableValue(std::move(output).TakeValue())); + EncodableValue(std::move(output).TakeValue())); reply(EncodableValue(std::move(wrapped))); }); } catch (const std::exception& exception) { @@ -4244,7 +4701,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.callFlutterEchoBool" + + "HostIntegrationCoreApi.echoAsyncUint8List" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -4253,14 +4710,16 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_bool_arg = args.at(0); - if (encodable_a_bool_arg.IsNull()) { - reply(WrapError("a_bool_arg unexpectedly null.")); + const auto& encodable_a_uint8_list_arg = args.at(0); + if (encodable_a_uint8_list_arg.IsNull()) { + reply(WrapError("a_uint8_list_arg unexpectedly null.")); return; } - const auto& a_bool_arg = std::get(encodable_a_bool_arg); - api->CallFlutterEchoBool( - a_bool_arg, [reply](ErrorOr&& output) { + const auto& a_uint8_list_arg = + std::get>(encodable_a_uint8_list_arg); + api->EchoAsyncUint8List( + a_uint8_list_arg, + [reply](ErrorOr>&& output) { if (output.has_error()) { reply(WrapError(output.error())); return; @@ -4281,7 +4740,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.callFlutterEchoInt" + + "HostIntegrationCoreApi.echoAsyncObject" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -4290,14 +4749,14 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_an_int_arg = args.at(0); - if (encodable_an_int_arg.IsNull()) { - reply(WrapError("an_int_arg unexpectedly null.")); + const auto& encodable_an_object_arg = args.at(0); + if (encodable_an_object_arg.IsNull()) { + reply(WrapError("an_object_arg unexpectedly null.")); return; } - const int64_t an_int_arg = encodable_an_int_arg.LongValue(); - api->CallFlutterEchoInt( - an_int_arg, [reply](ErrorOr&& output) { + const auto& an_object_arg = encodable_an_object_arg; + api->EchoAsyncObject( + an_object_arg, [reply](ErrorOr&& output) { if (output.has_error()) { reply(WrapError(output.error())); return; @@ -4316,27 +4775,26 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel( - binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "callFlutterEchoDouble" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.echoAsyncList" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_double_arg = args.at(0); - if (encodable_a_double_arg.IsNull()) { - reply(WrapError("a_double_arg unexpectedly null.")); + const auto& encodable_list_arg = args.at(0); + if (encodable_list_arg.IsNull()) { + reply(WrapError("list_arg unexpectedly null.")); return; } - const auto& a_double_arg = - std::get(encodable_a_double_arg); - api->CallFlutterEchoDouble( - a_double_arg, [reply](ErrorOr&& output) { + const auto& list_arg = + std::get(encodable_list_arg); + api->EchoAsyncList( + list_arg, [reply](ErrorOr&& output) { if (output.has_error()) { reply(WrapError(output.error())); return; @@ -4355,27 +4813,26 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel( - binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "callFlutterEchoString" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.echoAsyncEnumList" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_string_arg = args.at(0); - if (encodable_a_string_arg.IsNull()) { - reply(WrapError("a_string_arg unexpectedly null.")); + const auto& encodable_enum_list_arg = args.at(0); + if (encodable_enum_list_arg.IsNull()) { + reply(WrapError("enum_list_arg unexpectedly null.")); return; } - const auto& a_string_arg = - std::get(encodable_a_string_arg); - api->CallFlutterEchoString( - a_string_arg, [reply](ErrorOr&& output) { + const auto& enum_list_arg = + std::get(encodable_enum_list_arg); + api->EchoAsyncEnumList( + enum_list_arg, [reply](ErrorOr&& output) { if (output.has_error()) { reply(WrapError(output.error())); return; @@ -4394,27 +4851,26 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel( - binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "callFlutterEchoUint8List" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.echoAsyncClassList" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_list_arg = args.at(0); - if (encodable_list_arg.IsNull()) { - reply(WrapError("list_arg unexpectedly null.")); + const auto& encodable_class_list_arg = args.at(0); + if (encodable_class_list_arg.IsNull()) { + reply(WrapError("class_list_arg unexpectedly null.")); return; } - const auto& list_arg = - std::get>(encodable_list_arg); - api->CallFlutterEchoUint8List( - list_arg, [reply](ErrorOr>&& output) { + const auto& class_list_arg = + std::get(encodable_class_list_arg); + api->EchoAsyncClassList( + class_list_arg, [reply](ErrorOr&& output) { if (output.has_error()) { reply(WrapError(output.error())); return; @@ -4435,7 +4891,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.callFlutterEchoList" + + "HostIntegrationCoreApi.echoAsyncMap" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -4444,15 +4900,14 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_list_arg = args.at(0); - if (encodable_list_arg.IsNull()) { - reply(WrapError("list_arg unexpectedly null.")); + const auto& encodable_map_arg = args.at(0); + if (encodable_map_arg.IsNull()) { + reply(WrapError("map_arg unexpectedly null.")); return; } - const auto& list_arg = - std::get(encodable_list_arg); - api->CallFlutterEchoList( - list_arg, [reply](ErrorOr&& output) { + const auto& map_arg = std::get(encodable_map_arg); + api->EchoAsyncMap( + map_arg, [reply](ErrorOr&& output) { if (output.has_error()) { reply(WrapError(output.error())); return; @@ -4473,7 +4928,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.callFlutterEchoMap" + + "HostIntegrationCoreApi.echoAsyncStringMap" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -4482,15 +4937,15 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_map_arg = args.at(0); - if (encodable_a_map_arg.IsNull()) { - reply(WrapError("a_map_arg unexpectedly null.")); + const auto& encodable_string_map_arg = args.at(0); + if (encodable_string_map_arg.IsNull()) { + reply(WrapError("string_map_arg unexpectedly null.")); return; } - const auto& a_map_arg = - std::get(encodable_a_map_arg); - api->CallFlutterEchoMap( - a_map_arg, [reply](ErrorOr&& output) { + const auto& string_map_arg = + std::get(encodable_string_map_arg); + api->EchoAsyncStringMap( + string_map_arg, [reply](ErrorOr&& output) { if (output.has_error()) { reply(WrapError(output.error())); return; @@ -4511,7 +4966,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." - "HostIntegrationCoreApi.callFlutterEchoEnum" + + "HostIntegrationCoreApi.echoAsyncIntMap" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -4520,22 +4975,22 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_an_enum_arg = args.at(0); - if (encodable_an_enum_arg.IsNull()) { - reply(WrapError("an_enum_arg unexpectedly null.")); + const auto& encodable_int_map_arg = args.at(0); + if (encodable_int_map_arg.IsNull()) { + reply(WrapError("int_map_arg unexpectedly null.")); return; } - const auto& an_enum_arg = std::any_cast( - std::get(encodable_an_enum_arg)); - api->CallFlutterEchoEnum( - an_enum_arg, [reply](ErrorOr&& output) { + const auto& int_map_arg = + std::get(encodable_int_map_arg); + api->EchoAsyncIntMap( + int_map_arg, [reply](ErrorOr&& output) { if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; wrapped.push_back( - CustomEncodableValue(std::move(output).TakeValue())); + EncodableValue(std::move(output).TakeValue())); reply(EncodableValue(std::move(wrapped))); }); } catch (const std::exception& exception) { @@ -4547,34 +5002,33 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel( - binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "callFlutterEchoNullableBool" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.echoAsyncEnumMap" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_bool_arg = args.at(0); - const auto* a_bool_arg = std::get_if(&encodable_a_bool_arg); - api->CallFlutterEchoNullableBool( - a_bool_arg, [reply](ErrorOr>&& output) { + const auto& encodable_enum_map_arg = args.at(0); + if (encodable_enum_map_arg.IsNull()) { + reply(WrapError("enum_map_arg unexpectedly null.")); + return; + } + const auto& enum_map_arg = + std::get(encodable_enum_map_arg); + api->EchoAsyncEnumMap( + enum_map_arg, [reply](ErrorOr&& output) { if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); reply(EncodableValue(std::move(wrapped))); }); } catch (const std::exception& exception) { @@ -4586,40 +5040,33 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel( - binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "callFlutterEchoNullableInt" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.echoAsyncClassMap" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_an_int_arg = args.at(0); - const int64_t an_int_arg_value = - encodable_an_int_arg.IsNull() - ? 0 - : encodable_an_int_arg.LongValue(); - const auto* an_int_arg = - encodable_an_int_arg.IsNull() ? nullptr : &an_int_arg_value; - api->CallFlutterEchoNullableInt( - an_int_arg, - [reply](ErrorOr>&& output) { + const auto& encodable_class_map_arg = args.at(0); + if (encodable_class_map_arg.IsNull()) { + reply(WrapError("class_map_arg unexpectedly null.")); + return; + } + const auto& class_map_arg = + std::get(encodable_class_map_arg); + api->EchoAsyncClassMap( + class_map_arg, [reply](ErrorOr&& output) { if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); reply(EncodableValue(std::move(wrapped))); }); } catch (const std::exception& exception) { @@ -4631,36 +5078,33 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel( - binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "callFlutterEchoNullableDouble" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.echoAsyncEnum" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_double_arg = args.at(0); - const auto* a_double_arg = - std::get_if(&encodable_a_double_arg); - api->CallFlutterEchoNullableDouble( - a_double_arg, - [reply](ErrorOr>&& output) { + const auto& encodable_an_enum_arg = args.at(0); + if (encodable_an_enum_arg.IsNull()) { + reply(WrapError("an_enum_arg unexpectedly null.")); + return; + } + const auto& an_enum_arg = std::any_cast( + std::get(encodable_an_enum_arg)); + api->EchoAsyncEnum( + an_enum_arg, [reply](ErrorOr&& output) { if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } + wrapped.push_back( + CustomEncodableValue(std::move(output).TakeValue())); reply(EncodableValue(std::move(wrapped))); }); } catch (const std::exception& exception) { @@ -4675,7 +5119,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, BasicMessageChannel<> channel( binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "callFlutterEchoNullableString" + + "echoAnotherAsyncEnum" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -4684,12 +5128,45 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_string_arg = args.at(0); - const auto* a_string_arg = - std::get_if(&encodable_a_string_arg); - api->CallFlutterEchoNullableString( - a_string_arg, - [reply](ErrorOr>&& output) { + const auto& encodable_another_enum_arg = args.at(0); + if (encodable_another_enum_arg.IsNull()) { + reply(WrapError("another_enum_arg unexpectedly null.")); + return; + } + const auto& another_enum_arg = std::any_cast( + std::get(encodable_another_enum_arg)); + api->EchoAnotherAsyncEnum( + another_enum_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + CustomEncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.throwAsyncError" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + api->ThrowAsyncError( + [reply](ErrorOr>&& output) { if (output.has_error()) { reply(WrapError(output.error())); return; @@ -4716,7 +5193,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, BasicMessageChannel<> channel( binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "callFlutterEchoNullableUint8List" + + "throwAsyncErrorFromVoid" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -4724,26 +5201,14 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { - const auto& args = std::get(message); - const auto& encodable_list_arg = args.at(0); - const auto* list_arg = - std::get_if>(&encodable_list_arg); - api->CallFlutterEchoNullableUint8List( - list_arg, - [reply]( - ErrorOr>>&& output) { - if (output.has_error()) { - reply(WrapError(output.error())); + api->ThrowAsyncErrorFromVoid( + [reply](std::optional&& output) { + if (output.has_value()) { + reply(WrapError(output.value())); return; } EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } + wrapped.push_back(EncodableValue()); reply(EncodableValue(std::move(wrapped))); }); } catch (const std::exception& exception) { @@ -4758,7 +5223,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, BasicMessageChannel<> channel( binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "callFlutterEchoNullableList" + + "throwAsyncFlutterError" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -4766,13 +5231,8 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { - const auto& args = std::get(message); - const auto& encodable_list_arg = args.at(0); - const auto* list_arg = - std::get_if(&encodable_list_arg); - api->CallFlutterEchoNullableList( - list_arg, - [reply](ErrorOr>&& output) { + api->ThrowAsyncFlutterError( + [reply](ErrorOr>&& output) { if (output.has_error()) { reply(WrapError(output.error())); return; @@ -4796,36 +5256,33 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } } { - BasicMessageChannel<> channel( - binary_messenger, - "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "callFlutterEchoNullableMap" + - prepended_suffix, - &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.echoAsyncAllTypes" + + prepended_suffix, + &GetCodec()); if (api != nullptr) { channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_a_map_arg = args.at(0); - const auto* a_map_arg = - std::get_if(&encodable_a_map_arg); - api->CallFlutterEchoNullableMap( - a_map_arg, - [reply](ErrorOr>&& output) { + const auto& encodable_everything_arg = args.at(0); + if (encodable_everything_arg.IsNull()) { + reply(WrapError("everything_arg unexpectedly null.")); + return; + } + const auto& everything_arg = std::any_cast( + std::get(encodable_everything_arg)); + api->EchoAsyncAllTypes( + everything_arg, [reply](ErrorOr&& output) { if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; - auto output_optional = std::move(output).TakeValue(); - if (output_optional) { - wrapped.push_back( - EncodableValue(std::move(output_optional).value())); - } else { - wrapped.push_back(EncodableValue()); - } + wrapped.push_back( + CustomEncodableValue(std::move(output).TakeValue())); reply(EncodableValue(std::move(wrapped))); }); } catch (const std::exception& exception) { @@ -4840,7 +5297,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, BasicMessageChannel<> channel( binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "callFlutterEchoNullableEnum" + + "echoAsyncNullableAllNullableTypes" + prepended_suffix, &GetCodec()); if (api != nullptr) { @@ -4849,17 +5306,16 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const flutter::MessageReply& reply) { try { const auto& args = std::get(message); - const auto& encodable_an_enum_arg = args.at(0); - AnEnum an_enum_arg_value; - const AnEnum* an_enum_arg = nullptr; - if (!encodable_an_enum_arg.IsNull()) { - an_enum_arg_value = std::any_cast( - std::get(encodable_an_enum_arg)); - an_enum_arg = &an_enum_arg_value; - } - api->CallFlutterEchoNullableEnum( - an_enum_arg ? &(*an_enum_arg) : nullptr, - [reply](ErrorOr>&& output) { + const auto& encodable_everything_arg = args.at(0); + const auto* everything_arg = + encodable_everything_arg.IsNull() + ? nullptr + : &(std::any_cast( + std::get( + encodable_everything_arg))); + api->EchoAsyncNullableAllNullableTypes( + everything_arg, + [reply](ErrorOr>&& output) { if (output.has_error()) { reply(WrapError(output.error())); return; @@ -4886,31 +5342,243 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, BasicMessageChannel<> channel( binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." - "callFlutterSmallApiEchoString" + + "echoAsyncNullableAllNullableTypesWithoutRecursion" + prepended_suffix, &GetCodec()); if (api != nullptr) { - channel.SetMessageHandler( - [api](const EncodableValue& message, - const flutter::MessageReply& reply) { - try { - const auto& args = std::get(message); - const auto& encodable_a_string_arg = args.at(0); - if (encodable_a_string_arg.IsNull()) { - reply(WrapError("a_string_arg unexpectedly null.")); - return; - } - const auto& a_string_arg = - std::get(encodable_a_string_arg); - api->CallFlutterSmallApiEchoString( - a_string_arg, [reply](ErrorOr&& output) { + channel.SetMessageHandler([api]( + const EncodableValue& message, + const flutter::MessageReply& + reply) { + try { + const auto& args = std::get(message); + const auto& encodable_everything_arg = args.at(0); + const auto* everything_arg = + encodable_everything_arg.IsNull() + ? nullptr + : &(std::any_cast( + std::get( + encodable_everything_arg))); + api->EchoAsyncNullableAllNullableTypesWithoutRecursion( + everything_arg, + [reply](ErrorOr>&& + output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + CustomEncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableInt" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_an_int_arg = args.at(0); + const auto* an_int_arg = + std::get_if(&encodable_an_int_arg); + api->EchoAsyncNullableInt( + an_int_arg, + [reply](ErrorOr>&& output) { if (output.has_error()) { reply(WrapError(output.error())); return; } EncodableList wrapped; - wrapped.push_back( - EncodableValue(std::move(output).TakeValue())); + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableDouble" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_a_double_arg = args.at(0); + const auto* a_double_arg = + std::get_if(&encodable_a_double_arg); + api->EchoAsyncNullableDouble( + a_double_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableBool" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_a_bool_arg = args.at(0); + const auto* a_bool_arg = std::get_if(&encodable_a_bool_arg); + api->EchoAsyncNullableBool( + a_bool_arg, [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableString" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_a_string_arg = args.at(0); + const auto* a_string_arg = + std::get_if(&encodable_a_string_arg); + api->EchoAsyncNullableString( + a_string_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableUint8List" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_a_uint8_list_arg = args.at(0); + const auto* a_uint8_list_arg = std::get_if>( + &encodable_a_uint8_list_arg); + api->EchoAsyncNullableUint8List( + a_uint8_list_arg, + [reply]( + ErrorOr>>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } reply(EncodableValue(std::move(wrapped))); }); } catch (const std::exception& exception) { @@ -4921,49 +5589,3608 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, channel.SetMessageHandler(nullptr); } } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableObject" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_an_object_arg = args.at(0); + const auto* an_object_arg = &encodable_an_object_arg; + api->EchoAsyncNullableObject( + an_object_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableList" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_list_arg = args.at(0); + const auto* list_arg = + std::get_if(&encodable_list_arg); + api->EchoAsyncNullableList( + list_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableEnumList" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_enum_list_arg = args.at(0); + const auto* enum_list_arg = + std::get_if(&encodable_enum_list_arg); + api->EchoAsyncNullableEnumList( + enum_list_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableClassList" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_class_list_arg = args.at(0); + const auto* class_list_arg = + std::get_if(&encodable_class_list_arg); + api->EchoAsyncNullableClassList( + class_list_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableMap" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_map_arg = args.at(0); + const auto* map_arg = + std::get_if(&encodable_map_arg); + api->EchoAsyncNullableMap( + map_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableStringMap" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_string_map_arg = args.at(0); + const auto* string_map_arg = + std::get_if(&encodable_string_map_arg); + api->EchoAsyncNullableStringMap( + string_map_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableIntMap" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_int_map_arg = args.at(0); + const auto* int_map_arg = + std::get_if(&encodable_int_map_arg); + api->EchoAsyncNullableIntMap( + int_map_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableEnumMap" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_enum_map_arg = args.at(0); + const auto* enum_map_arg = + std::get_if(&encodable_enum_map_arg); + api->EchoAsyncNullableEnumMap( + enum_map_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableClassMap" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_class_map_arg = args.at(0); + const auto* class_map_arg = + std::get_if(&encodable_class_map_arg); + api->EchoAsyncNullableClassMap( + class_map_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableEnum" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_an_enum_arg = args.at(0); + AnEnum an_enum_arg_value; + const AnEnum* an_enum_arg = nullptr; + if (!encodable_an_enum_arg.IsNull()) { + an_enum_arg_value = std::any_cast( + std::get(encodable_an_enum_arg)); + an_enum_arg = &an_enum_arg_value; + } + api->EchoAsyncNullableEnum( + an_enum_arg ? &(*an_enum_arg) : nullptr, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back(CustomEncodableValue( + std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAnotherAsyncNullableEnum" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_another_enum_arg = args.at(0); + AnotherEnum another_enum_arg_value; + const AnotherEnum* another_enum_arg = nullptr; + if (!encodable_another_enum_arg.IsNull()) { + another_enum_arg_value = std::any_cast( + std::get(encodable_another_enum_arg)); + another_enum_arg = &another_enum_arg_value; + } + api->EchoAnotherAsyncNullableEnum( + another_enum_arg ? &(*another_enum_arg) : nullptr, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back(CustomEncodableValue( + std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.callFlutterNoop" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + api->CallFlutterNoop( + [reply](std::optional&& output) { + if (output.has_value()) { + reply(WrapError(output.value())); + return; + } + EncodableList wrapped; + wrapped.push_back(EncodableValue()); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterThrowError" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + api->CallFlutterThrowError( + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterThrowErrorFromVoid" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + api->CallFlutterThrowErrorFromVoid( + [reply](std::optional&& output) { + if (output.has_value()) { + reply(WrapError(output.value())); + return; + } + EncodableList wrapped; + wrapped.push_back(EncodableValue()); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoAllTypes" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_everything_arg = args.at(0); + if (encodable_everything_arg.IsNull()) { + reply(WrapError("everything_arg unexpectedly null.")); + return; + } + const auto& everything_arg = std::any_cast( + std::get(encodable_everything_arg)); + api->CallFlutterEchoAllTypes( + everything_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + CustomEncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoAllNullableTypes" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_everything_arg = args.at(0); + const auto* everything_arg = + encodable_everything_arg.IsNull() + ? nullptr + : &(std::any_cast( + std::get( + encodable_everything_arg))); + api->CallFlutterEchoAllNullableTypes( + everything_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back(CustomEncodableValue( + std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterSendMultipleNullableTypes" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_a_nullable_bool_arg = args.at(0); + const auto* a_nullable_bool_arg = + std::get_if(&encodable_a_nullable_bool_arg); + const auto& encodable_a_nullable_int_arg = args.at(1); + const auto* a_nullable_int_arg = + std::get_if(&encodable_a_nullable_int_arg); + const auto& encodable_a_nullable_string_arg = args.at(2); + const auto* a_nullable_string_arg = + std::get_if(&encodable_a_nullable_string_arg); + api->CallFlutterSendMultipleNullableTypes( + a_nullable_bool_arg, a_nullable_int_arg, + a_nullable_string_arg, + [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + CustomEncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoAllNullableTypesWithoutRecursion" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler([api]( + const EncodableValue& message, + const flutter::MessageReply& + reply) { + try { + const auto& args = std::get(message); + const auto& encodable_everything_arg = args.at(0); + const auto* everything_arg = + encodable_everything_arg.IsNull() + ? nullptr + : &(std::any_cast( + std::get( + encodable_everything_arg))); + api->CallFlutterEchoAllNullableTypesWithoutRecursion( + everything_arg, + [reply](ErrorOr>&& + output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + CustomEncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterSendMultipleNullableTypesWithoutRecursion" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_a_nullable_bool_arg = args.at(0); + const auto* a_nullable_bool_arg = + std::get_if(&encodable_a_nullable_bool_arg); + const auto& encodable_a_nullable_int_arg = args.at(1); + const auto* a_nullable_int_arg = + std::get_if(&encodable_a_nullable_int_arg); + const auto& encodable_a_nullable_string_arg = args.at(2); + const auto* a_nullable_string_arg = + std::get_if(&encodable_a_nullable_string_arg); + api->CallFlutterSendMultipleNullableTypesWithoutRecursion( + a_nullable_bool_arg, a_nullable_int_arg, + a_nullable_string_arg, + [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + CustomEncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.callFlutterEchoBool" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_a_bool_arg = args.at(0); + if (encodable_a_bool_arg.IsNull()) { + reply(WrapError("a_bool_arg unexpectedly null.")); + return; + } + const auto& a_bool_arg = std::get(encodable_a_bool_arg); + api->CallFlutterEchoBool( + a_bool_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.callFlutterEchoInt" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_an_int_arg = args.at(0); + if (encodable_an_int_arg.IsNull()) { + reply(WrapError("an_int_arg unexpectedly null.")); + return; + } + const int64_t an_int_arg = encodable_an_int_arg.LongValue(); + api->CallFlutterEchoInt( + an_int_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoDouble" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_a_double_arg = args.at(0); + if (encodable_a_double_arg.IsNull()) { + reply(WrapError("a_double_arg unexpectedly null.")); + return; + } + const auto& a_double_arg = + std::get(encodable_a_double_arg); + api->CallFlutterEchoDouble( + a_double_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoString" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_a_string_arg = args.at(0); + if (encodable_a_string_arg.IsNull()) { + reply(WrapError("a_string_arg unexpectedly null.")); + return; + } + const auto& a_string_arg = + std::get(encodable_a_string_arg); + api->CallFlutterEchoString( + a_string_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoUint8List" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_list_arg = args.at(0); + if (encodable_list_arg.IsNull()) { + reply(WrapError("list_arg unexpectedly null.")); + return; + } + const auto& list_arg = + std::get>(encodable_list_arg); + api->CallFlutterEchoUint8List( + list_arg, [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.callFlutterEchoList" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_list_arg = args.at(0); + if (encodable_list_arg.IsNull()) { + reply(WrapError("list_arg unexpectedly null.")); + return; + } + const auto& list_arg = + std::get(encodable_list_arg); + api->CallFlutterEchoList( + list_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoEnumList" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_enum_list_arg = args.at(0); + if (encodable_enum_list_arg.IsNull()) { + reply(WrapError("enum_list_arg unexpectedly null.")); + return; + } + const auto& enum_list_arg = + std::get(encodable_enum_list_arg); + api->CallFlutterEchoEnumList( + enum_list_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoClassList" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_class_list_arg = args.at(0); + if (encodable_class_list_arg.IsNull()) { + reply(WrapError("class_list_arg unexpectedly null.")); + return; + } + const auto& class_list_arg = + std::get(encodable_class_list_arg); + api->CallFlutterEchoClassList( + class_list_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNonNullEnumList" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_enum_list_arg = args.at(0); + if (encodable_enum_list_arg.IsNull()) { + reply(WrapError("enum_list_arg unexpectedly null.")); + return; + } + const auto& enum_list_arg = + std::get(encodable_enum_list_arg); + api->CallFlutterEchoNonNullEnumList( + enum_list_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNonNullClassList" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_class_list_arg = args.at(0); + if (encodable_class_list_arg.IsNull()) { + reply(WrapError("class_list_arg unexpectedly null.")); + return; + } + const auto& class_list_arg = + std::get(encodable_class_list_arg); + api->CallFlutterEchoNonNullClassList( + class_list_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.callFlutterEchoMap" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_map_arg = args.at(0); + if (encodable_map_arg.IsNull()) { + reply(WrapError("map_arg unexpectedly null.")); + return; + } + const auto& map_arg = std::get(encodable_map_arg); + api->CallFlutterEchoMap( + map_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoStringMap" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_string_map_arg = args.at(0); + if (encodable_string_map_arg.IsNull()) { + reply(WrapError("string_map_arg unexpectedly null.")); + return; + } + const auto& string_map_arg = + std::get(encodable_string_map_arg); + api->CallFlutterEchoStringMap( + string_map_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoIntMap" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_int_map_arg = args.at(0); + if (encodable_int_map_arg.IsNull()) { + reply(WrapError("int_map_arg unexpectedly null.")); + return; + } + const auto& int_map_arg = + std::get(encodable_int_map_arg); + api->CallFlutterEchoIntMap( + int_map_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoEnumMap" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_enum_map_arg = args.at(0); + if (encodable_enum_map_arg.IsNull()) { + reply(WrapError("enum_map_arg unexpectedly null.")); + return; + } + const auto& enum_map_arg = + std::get(encodable_enum_map_arg); + api->CallFlutterEchoEnumMap( + enum_map_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoClassMap" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_class_map_arg = args.at(0); + if (encodable_class_map_arg.IsNull()) { + reply(WrapError("class_map_arg unexpectedly null.")); + return; + } + const auto& class_map_arg = + std::get(encodable_class_map_arg); + api->CallFlutterEchoClassMap( + class_map_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNonNullStringMap" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_string_map_arg = args.at(0); + if (encodable_string_map_arg.IsNull()) { + reply(WrapError("string_map_arg unexpectedly null.")); + return; + } + const auto& string_map_arg = + std::get(encodable_string_map_arg); + api->CallFlutterEchoNonNullStringMap( + string_map_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNonNullIntMap" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_int_map_arg = args.at(0); + if (encodable_int_map_arg.IsNull()) { + reply(WrapError("int_map_arg unexpectedly null.")); + return; + } + const auto& int_map_arg = + std::get(encodable_int_map_arg); + api->CallFlutterEchoNonNullIntMap( + int_map_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNonNullEnumMap" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_enum_map_arg = args.at(0); + if (encodable_enum_map_arg.IsNull()) { + reply(WrapError("enum_map_arg unexpectedly null.")); + return; + } + const auto& enum_map_arg = + std::get(encodable_enum_map_arg); + api->CallFlutterEchoNonNullEnumMap( + enum_map_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNonNullClassMap" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_class_map_arg = args.at(0); + if (encodable_class_map_arg.IsNull()) { + reply(WrapError("class_map_arg unexpectedly null.")); + return; + } + const auto& class_map_arg = + std::get(encodable_class_map_arg); + api->CallFlutterEchoNonNullClassMap( + class_map_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.callFlutterEchoEnum" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_an_enum_arg = args.at(0); + if (encodable_an_enum_arg.IsNull()) { + reply(WrapError("an_enum_arg unexpectedly null.")); + return; + } + const auto& an_enum_arg = std::any_cast( + std::get(encodable_an_enum_arg)); + api->CallFlutterEchoEnum( + an_enum_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + CustomEncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoAnotherEnum" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_another_enum_arg = args.at(0); + if (encodable_another_enum_arg.IsNull()) { + reply(WrapError("another_enum_arg unexpectedly null.")); + return; + } + const auto& another_enum_arg = std::any_cast( + std::get(encodable_another_enum_arg)); + api->CallFlutterEchoAnotherEnum( + another_enum_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + CustomEncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableBool" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_a_bool_arg = args.at(0); + const auto* a_bool_arg = std::get_if(&encodable_a_bool_arg); + api->CallFlutterEchoNullableBool( + a_bool_arg, [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableInt" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_an_int_arg = args.at(0); + const auto* an_int_arg = + std::get_if(&encodable_an_int_arg); + api->CallFlutterEchoNullableInt( + an_int_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableDouble" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_a_double_arg = args.at(0); + const auto* a_double_arg = + std::get_if(&encodable_a_double_arg); + api->CallFlutterEchoNullableDouble( + a_double_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableString" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_a_string_arg = args.at(0); + const auto* a_string_arg = + std::get_if(&encodable_a_string_arg); + api->CallFlutterEchoNullableString( + a_string_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableUint8List" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_list_arg = args.at(0); + const auto* list_arg = + std::get_if>(&encodable_list_arg); + api->CallFlutterEchoNullableUint8List( + list_arg, + [reply]( + ErrorOr>>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableList" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_list_arg = args.at(0); + const auto* list_arg = + std::get_if(&encodable_list_arg); + api->CallFlutterEchoNullableList( + list_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableEnumList" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_enum_list_arg = args.at(0); + const auto* enum_list_arg = + std::get_if(&encodable_enum_list_arg); + api->CallFlutterEchoNullableEnumList( + enum_list_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableClassList" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_class_list_arg = args.at(0); + const auto* class_list_arg = + std::get_if(&encodable_class_list_arg); + api->CallFlutterEchoNullableClassList( + class_list_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableNonNullEnumList" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_enum_list_arg = args.at(0); + const auto* enum_list_arg = + std::get_if(&encodable_enum_list_arg); + api->CallFlutterEchoNullableNonNullEnumList( + enum_list_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableNonNullClassList" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_class_list_arg = args.at(0); + const auto* class_list_arg = + std::get_if(&encodable_class_list_arg); + api->CallFlutterEchoNullableNonNullClassList( + class_list_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableMap" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_map_arg = args.at(0); + const auto* map_arg = + std::get_if(&encodable_map_arg); + api->CallFlutterEchoNullableMap( + map_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableStringMap" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_string_map_arg = args.at(0); + const auto* string_map_arg = + std::get_if(&encodable_string_map_arg); + api->CallFlutterEchoNullableStringMap( + string_map_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableIntMap" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_int_map_arg = args.at(0); + const auto* int_map_arg = + std::get_if(&encodable_int_map_arg); + api->CallFlutterEchoNullableIntMap( + int_map_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableEnumMap" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_enum_map_arg = args.at(0); + const auto* enum_map_arg = + std::get_if(&encodable_enum_map_arg); + api->CallFlutterEchoNullableEnumMap( + enum_map_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableClassMap" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_class_map_arg = args.at(0); + const auto* class_map_arg = + std::get_if(&encodable_class_map_arg); + api->CallFlutterEchoNullableClassMap( + class_map_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableNonNullStringMap" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_string_map_arg = args.at(0); + const auto* string_map_arg = + std::get_if(&encodable_string_map_arg); + api->CallFlutterEchoNullableNonNullStringMap( + string_map_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableNonNullIntMap" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_int_map_arg = args.at(0); + const auto* int_map_arg = + std::get_if(&encodable_int_map_arg); + api->CallFlutterEchoNullableNonNullIntMap( + int_map_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableNonNullEnumMap" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_enum_map_arg = args.at(0); + const auto* enum_map_arg = + std::get_if(&encodable_enum_map_arg); + api->CallFlutterEchoNullableNonNullEnumMap( + enum_map_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableNonNullClassMap" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_class_map_arg = args.at(0); + const auto* class_map_arg = + std::get_if(&encodable_class_map_arg); + api->CallFlutterEchoNullableNonNullClassMap( + class_map_arg, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + EncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoNullableEnum" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_an_enum_arg = args.at(0); + AnEnum an_enum_arg_value; + const AnEnum* an_enum_arg = nullptr; + if (!encodable_an_enum_arg.IsNull()) { + an_enum_arg_value = std::any_cast( + std::get(encodable_an_enum_arg)); + an_enum_arg = &an_enum_arg_value; + } + api->CallFlutterEchoNullableEnum( + an_enum_arg ? &(*an_enum_arg) : nullptr, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back(CustomEncodableValue( + std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoAnotherNullableEnum" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_another_enum_arg = args.at(0); + AnotherEnum another_enum_arg_value; + const AnotherEnum* another_enum_arg = nullptr; + if (!encodable_another_enum_arg.IsNull()) { + another_enum_arg_value = std::any_cast( + std::get(encodable_another_enum_arg)); + another_enum_arg = &another_enum_arg_value; + } + api->CallFlutterEchoAnotherNullableEnum( + another_enum_arg ? &(*another_enum_arg) : nullptr, + [reply](ErrorOr>&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back(CustomEncodableValue( + std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterSmallApiEchoString" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_a_string_arg = args.at(0); + if (encodable_a_string_arg.IsNull()) { + reply(WrapError("a_string_arg unexpectedly null.")); + return; + } + const auto& a_string_arg = + std::get(encodable_a_string_arg); + api->CallFlutterSmallApiEchoString( + a_string_arg, [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } +} + +EncodableValue HostIntegrationCoreApi::WrapError( + std::string_view error_message) { + return EncodableValue( + EncodableList{EncodableValue(std::string(error_message)), + EncodableValue("Error"), EncodableValue()}); +} + +EncodableValue HostIntegrationCoreApi::WrapError(const FlutterError& error) { + return EncodableValue(EncodableList{EncodableValue(error.code()), + EncodableValue(error.message()), + error.details()}); +} + +// Generated class from Pigeon that represents Flutter messages that can be +// called from C++. +FlutterIntegrationCoreApi::FlutterIntegrationCoreApi( + flutter::BinaryMessenger* binary_messenger) + : binary_messenger_(binary_messenger), message_channel_suffix_("") {} + +FlutterIntegrationCoreApi::FlutterIntegrationCoreApi( + flutter::BinaryMessenger* binary_messenger, + const std::string& message_channel_suffix) + : binary_messenger_(binary_messenger), + message_channel_suffix_(message_channel_suffix.length() > 0 + ? std::string(".") + message_channel_suffix + : "") {} + +const flutter::StandardMessageCodec& FlutterIntegrationCoreApi::GetCodec() { + return flutter::StandardMessageCodec::GetInstance( + &PigeonInternalCodecSerializer::GetInstance()); +} + +void FlutterIntegrationCoreApi::Noop( + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "noop" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + on_success(); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::ThrowError( + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "throwError" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto* return_value = &list_return_value->at(0); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::ThrowErrorFromVoid( + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "throwErrorFromVoid" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + on_success(); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::EchoAllTypes( + const AllTypes& everything_arg, + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoAllTypes" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + CustomEncodableValue(everything_arg), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto& return_value = std::any_cast( + std::get(list_return_value->at(0))); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::EchoAllNullableTypes( + const AllNullableTypes* everything_arg, + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoAllNullableTypes" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + everything_arg ? CustomEncodableValue(*everything_arg) : EncodableValue(), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto* return_value = + list_return_value->at(0).IsNull() + ? nullptr + : &(std::any_cast( + std::get( + list_return_value->at(0)))); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::SendMultipleNullableTypes( + const bool* a_nullable_bool_arg, const int64_t* a_nullable_int_arg, + const std::string* a_nullable_string_arg, + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "sendMultipleNullableTypes" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + a_nullable_bool_arg ? EncodableValue(*a_nullable_bool_arg) + : EncodableValue(), + a_nullable_int_arg ? EncodableValue(*a_nullable_int_arg) + : EncodableValue(), + a_nullable_string_arg ? EncodableValue(*a_nullable_string_arg) + : EncodableValue(), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto& return_value = std::any_cast( + std::get(list_return_value->at(0))); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::EchoAllNullableTypesWithoutRecursion( + const AllNullableTypesWithoutRecursion* everything_arg, + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoAllNullableTypesWithoutRecursion" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + everything_arg ? CustomEncodableValue(*everything_arg) : EncodableValue(), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto* return_value = + list_return_value->at(0).IsNull() + ? nullptr + : &(std::any_cast( + std::get( + list_return_value->at(0)))); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::SendMultipleNullableTypesWithoutRecursion( + const bool* a_nullable_bool_arg, const int64_t* a_nullable_int_arg, + const std::string* a_nullable_string_arg, + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "sendMultipleNullableTypesWithoutRecursion" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + a_nullable_bool_arg ? EncodableValue(*a_nullable_bool_arg) + : EncodableValue(), + a_nullable_int_arg ? EncodableValue(*a_nullable_int_arg) + : EncodableValue(), + a_nullable_string_arg ? EncodableValue(*a_nullable_string_arg) + : EncodableValue(), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto& return_value = + std::any_cast( + std::get(list_return_value->at(0))); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::EchoBool( + bool a_bool_arg, std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoBool" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + EncodableValue(a_bool_arg), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto& return_value = std::get(list_return_value->at(0)); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::EchoInt( + int64_t an_int_arg, std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoInt" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + EncodableValue(an_int_arg), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const int64_t return_value = list_return_value->at(0).LongValue(); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::EchoDouble( + double a_double_arg, std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoDouble" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + EncodableValue(a_double_arg), + }); + channel.Send(encoded_api_arguments, [channel_name, + on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, + size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error(FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto& return_value = std::get(list_return_value->at(0)); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::EchoString( + const std::string& a_string_arg, + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoString" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + EncodableValue(a_string_arg), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto& return_value = + std::get(list_return_value->at(0)); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::EchoUint8List( + const std::vector& list_arg, + std::function&)>&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoUint8List" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + EncodableValue(list_arg), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto& return_value = + std::get>(list_return_value->at(0)); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::EchoList( + const EncodableList& list_arg, + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoList" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + EncodableValue(list_arg), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto& return_value = + std::get(list_return_value->at(0)); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::EchoEnumList( + const EncodableList& enum_list_arg, + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoEnumList" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + EncodableValue(enum_list_arg), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto& return_value = + std::get(list_return_value->at(0)); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::EchoClassList( + const EncodableList& class_list_arg, + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoClassList" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + EncodableValue(class_list_arg), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto& return_value = + std::get(list_return_value->at(0)); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::EchoNonNullEnumList( + const EncodableList& enum_list_arg, + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNonNullEnumList" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + EncodableValue(enum_list_arg), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto& return_value = + std::get(list_return_value->at(0)); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::EchoNonNullClassList( + const EncodableList& class_list_arg, + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNonNullClassList" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + EncodableValue(class_list_arg), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto& return_value = + std::get(list_return_value->at(0)); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::EchoMap( + const EncodableMap& map_arg, + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoMap" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + EncodableValue(map_arg), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto& return_value = + std::get(list_return_value->at(0)); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::EchoStringMap( + const EncodableMap& string_map_arg, + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoStringMap" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + EncodableValue(string_map_arg), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto& return_value = + std::get(list_return_value->at(0)); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::EchoIntMap( + const EncodableMap& int_map_arg, + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoIntMap" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + EncodableValue(int_map_arg), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto& return_value = + std::get(list_return_value->at(0)); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::EchoEnumMap( + const EncodableMap& enum_map_arg, + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoEnumMap" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + EncodableValue(enum_map_arg), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto& return_value = + std::get(list_return_value->at(0)); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::EchoClassMap( + const EncodableMap& class_map_arg, + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoClassMap" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + EncodableValue(class_map_arg), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto& return_value = + std::get(list_return_value->at(0)); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::EchoNonNullStringMap( + const EncodableMap& string_map_arg, + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNonNullStringMap" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + EncodableValue(string_map_arg), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto& return_value = + std::get(list_return_value->at(0)); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::EchoNonNullIntMap( + const EncodableMap& int_map_arg, + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNonNullIntMap" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + EncodableValue(int_map_arg), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto& return_value = + std::get(list_return_value->at(0)); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); } -EncodableValue HostIntegrationCoreApi::WrapError( - std::string_view error_message) { - return EncodableValue( - EncodableList{EncodableValue(std::string(error_message)), - EncodableValue("Error"), EncodableValue()}); +void FlutterIntegrationCoreApi::EchoNonNullEnumMap( + const EncodableMap& enum_map_arg, + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNonNullEnumMap" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + EncodableValue(enum_map_arg), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto& return_value = + std::get(list_return_value->at(0)); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); } -EncodableValue HostIntegrationCoreApi::WrapError(const FlutterError& error) { - return EncodableValue(EncodableList{EncodableValue(error.code()), - EncodableValue(error.message()), - error.details()}); +void FlutterIntegrationCoreApi::EchoNonNullClassMap( + const EncodableMap& class_map_arg, + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNonNullClassMap" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + EncodableValue(class_map_arg), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto& return_value = + std::get(list_return_value->at(0)); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); } -// Generated class from Pigeon that represents Flutter messages that can be -// called from C++. -FlutterIntegrationCoreApi::FlutterIntegrationCoreApi( - flutter::BinaryMessenger* binary_messenger) - : binary_messenger_(binary_messenger), message_channel_suffix_("") {} - -FlutterIntegrationCoreApi::FlutterIntegrationCoreApi( - flutter::BinaryMessenger* binary_messenger, - const std::string& message_channel_suffix) - : binary_messenger_(binary_messenger), - message_channel_suffix_(message_channel_suffix.length() > 0 - ? std::string(".") + message_channel_suffix - : "") {} - -const flutter::StandardMessageCodec& FlutterIntegrationCoreApi::GetCodec() { - return flutter::StandardMessageCodec::GetInstance( - &PigeonCodecSerializer::GetInstance()); +void FlutterIntegrationCoreApi::EchoEnum( + const AnEnum& an_enum_arg, std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoEnum" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + CustomEncodableValue(an_enum_arg), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto& return_value = std::any_cast( + std::get(list_return_value->at(0))); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); } -void FlutterIntegrationCoreApi::Noop( - std::function&& on_success, +void FlutterIntegrationCoreApi::EchoAnotherEnum( + const AnotherEnum& another_enum_arg, + std::function&& on_success, std::function&& on_error) { const std::string channel_name = "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - "noop" + + "echoAnotherEnum" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); - EncodableValue encoded_api_arguments = EncodableValue(); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + CustomEncodableValue(another_enum_arg), + }); channel.Send( encoded_api_arguments, [channel_name, on_success = std::move(on_success), on_error = std::move(on_error)]( @@ -4980,7 +9207,9 @@ void FlutterIntegrationCoreApi::Noop( std::get(list_return_value->at(1)), list_return_value->at(2))); } else { - on_success(); + const auto& return_value = std::any_cast( + std::get(list_return_value->at(0))); + on_success(return_value); } } else { on_error(CreateConnectionError(channel_name)); @@ -4988,15 +9217,53 @@ void FlutterIntegrationCoreApi::Noop( }); } -void FlutterIntegrationCoreApi::ThrowError( - std::function&& on_success, +void FlutterIntegrationCoreApi::EchoNullableBool( + const bool* a_bool_arg, std::function&& on_success, std::function&& on_error) { const std::string channel_name = "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - "throwError" + + "echoNullableBool" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); - EncodableValue encoded_api_arguments = EncodableValue(); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + a_bool_arg ? EncodableValue(*a_bool_arg) : EncodableValue(), + }); + channel.Send(encoded_api_arguments, [channel_name, + on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, + size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error(FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto* return_value = std::get_if(&list_return_value->at(0)); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::EchoNullableInt( + const int64_t* an_int_arg, std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoNullableInt" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + an_int_arg ? EncodableValue(*an_int_arg) : EncodableValue(), + }); channel.Send( encoded_api_arguments, [channel_name, on_success = std::move(on_success), on_error = std::move(on_error)]( @@ -5013,7 +9280,8 @@ void FlutterIntegrationCoreApi::ThrowError( std::get(list_return_value->at(1)), list_return_value->at(2))); } else { - const auto* return_value = &list_return_value->at(0); + const auto* return_value = + std::get_if(&list_return_value->at(0)); on_success(return_value); } } else { @@ -5022,15 +9290,17 @@ void FlutterIntegrationCoreApi::ThrowError( }); } -void FlutterIntegrationCoreApi::ThrowErrorFromVoid( - std::function&& on_success, +void FlutterIntegrationCoreApi::EchoNullableDouble( + const double* a_double_arg, std::function&& on_success, std::function&& on_error) { const std::string channel_name = "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - "throwErrorFromVoid" + + "echoNullableDouble" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); - EncodableValue encoded_api_arguments = EncodableValue(); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + a_double_arg ? EncodableValue(*a_double_arg) : EncodableValue(), + }); channel.Send( encoded_api_arguments, [channel_name, on_success = std::move(on_success), on_error = std::move(on_error)]( @@ -5047,7 +9317,9 @@ void FlutterIntegrationCoreApi::ThrowErrorFromVoid( std::get(list_return_value->at(1)), list_return_value->at(2))); } else { - on_success(); + const auto* return_value = + std::get_if(&list_return_value->at(0)); + on_success(return_value); } } else { on_error(CreateConnectionError(channel_name)); @@ -5055,17 +9327,17 @@ void FlutterIntegrationCoreApi::ThrowErrorFromVoid( }); } -void FlutterIntegrationCoreApi::EchoAllTypes( - const AllTypes& everything_arg, - std::function&& on_success, +void FlutterIntegrationCoreApi::EchoNullableString( + const std::string* a_string_arg, + std::function&& on_success, std::function&& on_error) { const std::string channel_name = "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - "echoAllTypes" + + "echoNullableString" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ - CustomEncodableValue(everything_arg), + a_string_arg ? EncodableValue(*a_string_arg) : EncodableValue(), }); channel.Send( encoded_api_arguments, [channel_name, on_success = std::move(on_success), @@ -5083,8 +9355,8 @@ void FlutterIntegrationCoreApi::EchoAllTypes( std::get(list_return_value->at(1)), list_return_value->at(2))); } else { - const auto& return_value = std::any_cast( - std::get(list_return_value->at(0))); + const auto* return_value = + std::get_if(&list_return_value->at(0)); on_success(return_value); } } else { @@ -5093,17 +9365,17 @@ void FlutterIntegrationCoreApi::EchoAllTypes( }); } -void FlutterIntegrationCoreApi::EchoAllNullableTypes( - const AllNullableTypes* everything_arg, - std::function&& on_success, +void FlutterIntegrationCoreApi::EchoNullableUint8List( + const std::vector* list_arg, + std::function*)>&& on_success, std::function&& on_error) { const std::string channel_name = "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - "echoAllNullableTypes" + + "echoNullableUint8List" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ - everything_arg ? CustomEncodableValue(*everything_arg) : EncodableValue(), + list_arg ? EncodableValue(*list_arg) : EncodableValue(), }); channel.Send( encoded_api_arguments, [channel_name, on_success = std::move(on_success), @@ -5122,11 +9394,7 @@ void FlutterIntegrationCoreApi::EchoAllNullableTypes( list_return_value->at(2))); } else { const auto* return_value = - list_return_value->at(0).IsNull() - ? nullptr - : &(std::any_cast( - std::get( - list_return_value->at(0)))); + std::get_if>(&list_return_value->at(0)); on_success(return_value); } } else { @@ -5135,23 +9403,17 @@ void FlutterIntegrationCoreApi::EchoAllNullableTypes( }); } -void FlutterIntegrationCoreApi::SendMultipleNullableTypes( - const bool* a_nullable_bool_arg, const int64_t* a_nullable_int_arg, - const std::string* a_nullable_string_arg, - std::function&& on_success, +void FlutterIntegrationCoreApi::EchoNullableList( + const EncodableList* list_arg, + std::function&& on_success, std::function&& on_error) { const std::string channel_name = "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - "sendMultipleNullableTypes" + + "echoNullableList" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ - a_nullable_bool_arg ? EncodableValue(*a_nullable_bool_arg) - : EncodableValue(), - a_nullable_int_arg ? EncodableValue(*a_nullable_int_arg) - : EncodableValue(), - a_nullable_string_arg ? EncodableValue(*a_nullable_string_arg) - : EncodableValue(), + list_arg ? EncodableValue(*list_arg) : EncodableValue(), }); channel.Send( encoded_api_arguments, [channel_name, on_success = std::move(on_success), @@ -5169,8 +9431,8 @@ void FlutterIntegrationCoreApi::SendMultipleNullableTypes( std::get(list_return_value->at(1)), list_return_value->at(2))); } else { - const auto& return_value = std::any_cast( - std::get(list_return_value->at(0))); + const auto* return_value = + std::get_if(&list_return_value->at(0)); on_success(return_value); } } else { @@ -5179,17 +9441,17 @@ void FlutterIntegrationCoreApi::SendMultipleNullableTypes( }); } -void FlutterIntegrationCoreApi::EchoAllNullableTypesWithoutRecursion( - const AllNullableTypesWithoutRecursion* everything_arg, - std::function&& on_success, +void FlutterIntegrationCoreApi::EchoNullableEnumList( + const EncodableList* enum_list_arg, + std::function&& on_success, std::function&& on_error) { const std::string channel_name = "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - "echoAllNullableTypesWithoutRecursion" + + "echoNullableEnumList" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ - everything_arg ? CustomEncodableValue(*everything_arg) : EncodableValue(), + enum_list_arg ? EncodableValue(*enum_list_arg) : EncodableValue(), }); channel.Send( encoded_api_arguments, [channel_name, on_success = std::move(on_success), @@ -5208,11 +9470,7 @@ void FlutterIntegrationCoreApi::EchoAllNullableTypesWithoutRecursion( list_return_value->at(2))); } else { const auto* return_value = - list_return_value->at(0).IsNull() - ? nullptr - : &(std::any_cast( - std::get( - list_return_value->at(0)))); + std::get_if(&list_return_value->at(0)); on_success(return_value); } } else { @@ -5221,23 +9479,17 @@ void FlutterIntegrationCoreApi::EchoAllNullableTypesWithoutRecursion( }); } -void FlutterIntegrationCoreApi::SendMultipleNullableTypesWithoutRecursion( - const bool* a_nullable_bool_arg, const int64_t* a_nullable_int_arg, - const std::string* a_nullable_string_arg, - std::function&& on_success, +void FlutterIntegrationCoreApi::EchoNullableClassList( + const EncodableList* class_list_arg, + std::function&& on_success, std::function&& on_error) { const std::string channel_name = "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - "sendMultipleNullableTypesWithoutRecursion" + + "echoNullableClassList" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ - a_nullable_bool_arg ? EncodableValue(*a_nullable_bool_arg) - : EncodableValue(), - a_nullable_int_arg ? EncodableValue(*a_nullable_int_arg) - : EncodableValue(), - a_nullable_string_arg ? EncodableValue(*a_nullable_string_arg) - : EncodableValue(), + class_list_arg ? EncodableValue(*class_list_arg) : EncodableValue(), }); channel.Send( encoded_api_arguments, [channel_name, on_success = std::move(on_success), @@ -5255,9 +9507,8 @@ void FlutterIntegrationCoreApi::SendMultipleNullableTypesWithoutRecursion( std::get(list_return_value->at(1)), list_return_value->at(2))); } else { - const auto& return_value = - std::any_cast( - std::get(list_return_value->at(0))); + const auto* return_value = + std::get_if(&list_return_value->at(0)); on_success(return_value); } } else { @@ -5266,16 +9517,17 @@ void FlutterIntegrationCoreApi::SendMultipleNullableTypesWithoutRecursion( }); } -void FlutterIntegrationCoreApi::EchoBool( - bool a_bool_arg, std::function&& on_success, +void FlutterIntegrationCoreApi::EchoNullableNonNullEnumList( + const EncodableList* enum_list_arg, + std::function&& on_success, std::function&& on_error) { const std::string channel_name = "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - "echoBool" + + "echoNullableNonNullEnumList" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ - EncodableValue(a_bool_arg), + enum_list_arg ? EncodableValue(*enum_list_arg) : EncodableValue(), }); channel.Send( encoded_api_arguments, [channel_name, on_success = std::move(on_success), @@ -5293,7 +9545,8 @@ void FlutterIntegrationCoreApi::EchoBool( std::get(list_return_value->at(1)), list_return_value->at(2))); } else { - const auto& return_value = std::get(list_return_value->at(0)); + const auto* return_value = + std::get_if(&list_return_value->at(0)); on_success(return_value); } } else { @@ -5302,16 +9555,17 @@ void FlutterIntegrationCoreApi::EchoBool( }); } -void FlutterIntegrationCoreApi::EchoInt( - int64_t an_int_arg, std::function&& on_success, +void FlutterIntegrationCoreApi::EchoNullableNonNullClassList( + const EncodableList* class_list_arg, + std::function&& on_success, std::function&& on_error) { const std::string channel_name = "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - "echoInt" + + "echoNullableNonNullClassList" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ - EncodableValue(an_int_arg), + class_list_arg ? EncodableValue(*class_list_arg) : EncodableValue(), }); channel.Send( encoded_api_arguments, [channel_name, on_success = std::move(on_success), @@ -5329,7 +9583,8 @@ void FlutterIntegrationCoreApi::EchoInt( std::get(list_return_value->at(1)), list_return_value->at(2))); } else { - const int64_t return_value = list_return_value->at(0).LongValue(); + const auto* return_value = + std::get_if(&list_return_value->at(0)); on_success(return_value); } } else { @@ -5338,53 +9593,17 @@ void FlutterIntegrationCoreApi::EchoInt( }); } -void FlutterIntegrationCoreApi::EchoDouble( - double a_double_arg, std::function&& on_success, - std::function&& on_error) { - const std::string channel_name = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - "echoDouble" + - message_channel_suffix_; - BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); - EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ - EncodableValue(a_double_arg), - }); - channel.Send(encoded_api_arguments, [channel_name, - on_success = std::move(on_success), - on_error = std::move(on_error)]( - const uint8_t* reply, - size_t reply_size) { - std::unique_ptr response = - GetCodec().DecodeMessage(reply, reply_size); - const auto& encodable_return_value = *response; - const auto* list_return_value = - std::get_if(&encodable_return_value); - if (list_return_value) { - if (list_return_value->size() > 1) { - on_error(FlutterError(std::get(list_return_value->at(0)), - std::get(list_return_value->at(1)), - list_return_value->at(2))); - } else { - const auto& return_value = std::get(list_return_value->at(0)); - on_success(return_value); - } - } else { - on_error(CreateConnectionError(channel_name)); - } - }); -} - -void FlutterIntegrationCoreApi::EchoString( - const std::string& a_string_arg, - std::function&& on_success, +void FlutterIntegrationCoreApi::EchoNullableMap( + const EncodableMap* map_arg, + std::function&& on_success, std::function&& on_error) { const std::string channel_name = "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - "echoString" + + "echoNullableMap" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ - EncodableValue(a_string_arg), + map_arg ? EncodableValue(*map_arg) : EncodableValue(), }); channel.Send( encoded_api_arguments, [channel_name, on_success = std::move(on_success), @@ -5402,8 +9621,8 @@ void FlutterIntegrationCoreApi::EchoString( std::get(list_return_value->at(1)), list_return_value->at(2))); } else { - const auto& return_value = - std::get(list_return_value->at(0)); + const auto* return_value = + std::get_if(&list_return_value->at(0)); on_success(return_value); } } else { @@ -5412,17 +9631,17 @@ void FlutterIntegrationCoreApi::EchoString( }); } -void FlutterIntegrationCoreApi::EchoUint8List( - const std::vector& list_arg, - std::function&)>&& on_success, +void FlutterIntegrationCoreApi::EchoNullableStringMap( + const EncodableMap* string_map_arg, + std::function&& on_success, std::function&& on_error) { const std::string channel_name = "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - "echoUint8List" + + "echoNullableStringMap" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ - EncodableValue(list_arg), + string_map_arg ? EncodableValue(*string_map_arg) : EncodableValue(), }); channel.Send( encoded_api_arguments, [channel_name, on_success = std::move(on_success), @@ -5440,8 +9659,8 @@ void FlutterIntegrationCoreApi::EchoUint8List( std::get(list_return_value->at(1)), list_return_value->at(2))); } else { - const auto& return_value = - std::get>(list_return_value->at(0)); + const auto* return_value = + std::get_if(&list_return_value->at(0)); on_success(return_value); } } else { @@ -5450,17 +9669,17 @@ void FlutterIntegrationCoreApi::EchoUint8List( }); } -void FlutterIntegrationCoreApi::EchoList( - const EncodableList& list_arg, - std::function&& on_success, +void FlutterIntegrationCoreApi::EchoNullableIntMap( + const EncodableMap* int_map_arg, + std::function&& on_success, std::function&& on_error) { const std::string channel_name = "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - "echoList" + + "echoNullableIntMap" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ - EncodableValue(list_arg), + int_map_arg ? EncodableValue(*int_map_arg) : EncodableValue(), }); channel.Send( encoded_api_arguments, [channel_name, on_success = std::move(on_success), @@ -5478,8 +9697,8 @@ void FlutterIntegrationCoreApi::EchoList( std::get(list_return_value->at(1)), list_return_value->at(2))); } else { - const auto& return_value = - std::get(list_return_value->at(0)); + const auto* return_value = + std::get_if(&list_return_value->at(0)); on_success(return_value); } } else { @@ -5488,17 +9707,17 @@ void FlutterIntegrationCoreApi::EchoList( }); } -void FlutterIntegrationCoreApi::EchoMap( - const EncodableMap& a_map_arg, - std::function&& on_success, +void FlutterIntegrationCoreApi::EchoNullableEnumMap( + const EncodableMap* enum_map_arg, + std::function&& on_success, std::function&& on_error) { const std::string channel_name = "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - "echoMap" + + "echoNullableEnumMap" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ - EncodableValue(a_map_arg), + enum_map_arg ? EncodableValue(*enum_map_arg) : EncodableValue(), }); channel.Send( encoded_api_arguments, [channel_name, on_success = std::move(on_success), @@ -5516,8 +9735,8 @@ void FlutterIntegrationCoreApi::EchoMap( std::get(list_return_value->at(1)), list_return_value->at(2))); } else { - const auto& return_value = - std::get(list_return_value->at(0)); + const auto* return_value = + std::get_if(&list_return_value->at(0)); on_success(return_value); } } else { @@ -5526,16 +9745,17 @@ void FlutterIntegrationCoreApi::EchoMap( }); } -void FlutterIntegrationCoreApi::EchoEnum( - const AnEnum& an_enum_arg, std::function&& on_success, +void FlutterIntegrationCoreApi::EchoNullableClassMap( + const EncodableMap* class_map_arg, + std::function&& on_success, std::function&& on_error) { const std::string channel_name = "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - "echoEnum" + + "echoNullableClassMap" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ - CustomEncodableValue(an_enum_arg), + class_map_arg ? EncodableValue(*class_map_arg) : EncodableValue(), }); channel.Send( encoded_api_arguments, [channel_name, on_success = std::move(on_success), @@ -5553,8 +9773,8 @@ void FlutterIntegrationCoreApi::EchoEnum( std::get(list_return_value->at(1)), list_return_value->at(2))); } else { - const auto& return_value = std::any_cast( - std::get(list_return_value->at(0))); + const auto* return_value = + std::get_if(&list_return_value->at(0)); on_success(return_value); } } else { @@ -5563,93 +9783,17 @@ void FlutterIntegrationCoreApi::EchoEnum( }); } -void FlutterIntegrationCoreApi::EchoNullableBool( - const bool* a_bool_arg, std::function&& on_success, - std::function&& on_error) { - const std::string channel_name = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - "echoNullableBool" + - message_channel_suffix_; - BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); - EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ - a_bool_arg ? EncodableValue(*a_bool_arg) : EncodableValue(), - }); - channel.Send(encoded_api_arguments, [channel_name, - on_success = std::move(on_success), - on_error = std::move(on_error)]( - const uint8_t* reply, - size_t reply_size) { - std::unique_ptr response = - GetCodec().DecodeMessage(reply, reply_size); - const auto& encodable_return_value = *response; - const auto* list_return_value = - std::get_if(&encodable_return_value); - if (list_return_value) { - if (list_return_value->size() > 1) { - on_error(FlutterError(std::get(list_return_value->at(0)), - std::get(list_return_value->at(1)), - list_return_value->at(2))); - } else { - const auto* return_value = std::get_if(&list_return_value->at(0)); - on_success(return_value); - } - } else { - on_error(CreateConnectionError(channel_name)); - } - }); -} - -void FlutterIntegrationCoreApi::EchoNullableInt( - const int64_t* an_int_arg, std::function&& on_success, - std::function&& on_error) { - const std::string channel_name = - "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - "echoNullableInt" + - message_channel_suffix_; - BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); - EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ - an_int_arg ? EncodableValue(*an_int_arg) : EncodableValue(), - }); - channel.Send(encoded_api_arguments, [channel_name, - on_success = std::move(on_success), - on_error = std::move(on_error)]( - const uint8_t* reply, - size_t reply_size) { - std::unique_ptr response = - GetCodec().DecodeMessage(reply, reply_size); - const auto& encodable_return_value = *response; - const auto* list_return_value = - std::get_if(&encodable_return_value); - if (list_return_value) { - if (list_return_value->size() > 1) { - on_error(FlutterError(std::get(list_return_value->at(0)), - std::get(list_return_value->at(1)), - list_return_value->at(2))); - } else { - const int64_t return_value_value = - list_return_value->at(0).IsNull() - ? 0 - : list_return_value->at(0).LongValue(); - const auto* return_value = - list_return_value->at(0).IsNull() ? nullptr : &return_value_value; - on_success(return_value); - } - } else { - on_error(CreateConnectionError(channel_name)); - } - }); -} - -void FlutterIntegrationCoreApi::EchoNullableDouble( - const double* a_double_arg, std::function&& on_success, +void FlutterIntegrationCoreApi::EchoNullableNonNullStringMap( + const EncodableMap* string_map_arg, + std::function&& on_success, std::function&& on_error) { const std::string channel_name = "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - "echoNullableDouble" + + "echoNullableNonNullStringMap" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ - a_double_arg ? EncodableValue(*a_double_arg) : EncodableValue(), + string_map_arg ? EncodableValue(*string_map_arg) : EncodableValue(), }); channel.Send( encoded_api_arguments, [channel_name, on_success = std::move(on_success), @@ -5668,7 +9812,7 @@ void FlutterIntegrationCoreApi::EchoNullableDouble( list_return_value->at(2))); } else { const auto* return_value = - std::get_if(&list_return_value->at(0)); + std::get_if(&list_return_value->at(0)); on_success(return_value); } } else { @@ -5677,17 +9821,17 @@ void FlutterIntegrationCoreApi::EchoNullableDouble( }); } -void FlutterIntegrationCoreApi::EchoNullableString( - const std::string* a_string_arg, - std::function&& on_success, +void FlutterIntegrationCoreApi::EchoNullableNonNullIntMap( + const EncodableMap* int_map_arg, + std::function&& on_success, std::function&& on_error) { const std::string channel_name = "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - "echoNullableString" + + "echoNullableNonNullIntMap" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ - a_string_arg ? EncodableValue(*a_string_arg) : EncodableValue(), + int_map_arg ? EncodableValue(*int_map_arg) : EncodableValue(), }); channel.Send( encoded_api_arguments, [channel_name, on_success = std::move(on_success), @@ -5706,7 +9850,7 @@ void FlutterIntegrationCoreApi::EchoNullableString( list_return_value->at(2))); } else { const auto* return_value = - std::get_if(&list_return_value->at(0)); + std::get_if(&list_return_value->at(0)); on_success(return_value); } } else { @@ -5715,17 +9859,17 @@ void FlutterIntegrationCoreApi::EchoNullableString( }); } -void FlutterIntegrationCoreApi::EchoNullableUint8List( - const std::vector* list_arg, - std::function*)>&& on_success, +void FlutterIntegrationCoreApi::EchoNullableNonNullEnumMap( + const EncodableMap* enum_map_arg, + std::function&& on_success, std::function&& on_error) { const std::string channel_name = "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - "echoNullableUint8List" + + "echoNullableNonNullEnumMap" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ - list_arg ? EncodableValue(*list_arg) : EncodableValue(), + enum_map_arg ? EncodableValue(*enum_map_arg) : EncodableValue(), }); channel.Send( encoded_api_arguments, [channel_name, on_success = std::move(on_success), @@ -5744,7 +9888,7 @@ void FlutterIntegrationCoreApi::EchoNullableUint8List( list_return_value->at(2))); } else { const auto* return_value = - std::get_if>(&list_return_value->at(0)); + std::get_if(&list_return_value->at(0)); on_success(return_value); } } else { @@ -5753,17 +9897,17 @@ void FlutterIntegrationCoreApi::EchoNullableUint8List( }); } -void FlutterIntegrationCoreApi::EchoNullableList( - const EncodableList* list_arg, - std::function&& on_success, +void FlutterIntegrationCoreApi::EchoNullableNonNullClassMap( + const EncodableMap* class_map_arg, + std::function&& on_success, std::function&& on_error) { const std::string channel_name = "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - "echoNullableList" + + "echoNullableNonNullClassMap" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ - list_arg ? EncodableValue(*list_arg) : EncodableValue(), + class_map_arg ? EncodableValue(*class_map_arg) : EncodableValue(), }); channel.Send( encoded_api_arguments, [channel_name, on_success = std::move(on_success), @@ -5782,7 +9926,7 @@ void FlutterIntegrationCoreApi::EchoNullableList( list_return_value->at(2))); } else { const auto* return_value = - std::get_if(&list_return_value->at(0)); + std::get_if(&list_return_value->at(0)); on_success(return_value); } } else { @@ -5791,17 +9935,16 @@ void FlutterIntegrationCoreApi::EchoNullableList( }); } -void FlutterIntegrationCoreApi::EchoNullableMap( - const EncodableMap* a_map_arg, - std::function&& on_success, +void FlutterIntegrationCoreApi::EchoNullableEnum( + const AnEnum* an_enum_arg, std::function&& on_success, std::function&& on_error) { const std::string channel_name = "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - "echoNullableMap" + + "echoNullableEnum" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ - a_map_arg ? EncodableValue(*a_map_arg) : EncodableValue(), + an_enum_arg ? CustomEncodableValue(*an_enum_arg) : EncodableValue(), }); channel.Send( encoded_api_arguments, [channel_name, on_success = std::move(on_success), @@ -5819,8 +9962,13 @@ void FlutterIntegrationCoreApi::EchoNullableMap( std::get(list_return_value->at(1)), list_return_value->at(2))); } else { - const auto* return_value = - std::get_if(&list_return_value->at(0)); + AnEnum return_value_value; + const AnEnum* return_value = nullptr; + if (!list_return_value->at(0).IsNull()) { + return_value_value = std::any_cast( + std::get(list_return_value->at(0))); + return_value = &return_value_value; + } on_success(return_value); } } else { @@ -5829,16 +9977,18 @@ void FlutterIntegrationCoreApi::EchoNullableMap( }); } -void FlutterIntegrationCoreApi::EchoNullableEnum( - const AnEnum* an_enum_arg, std::function&& on_success, +void FlutterIntegrationCoreApi::EchoAnotherNullableEnum( + const AnotherEnum* another_enum_arg, + std::function&& on_success, std::function&& on_error) { const std::string channel_name = "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." - "echoNullableEnum" + + "echoAnotherNullableEnum" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ - an_enum_arg ? CustomEncodableValue(*an_enum_arg) : EncodableValue(), + another_enum_arg ? CustomEncodableValue(*another_enum_arg) + : EncodableValue(), }); channel.Send( encoded_api_arguments, [channel_name, on_success = std::move(on_success), @@ -5856,10 +10006,10 @@ void FlutterIntegrationCoreApi::EchoNullableEnum( std::get(list_return_value->at(1)), list_return_value->at(2))); } else { - AnEnum return_value_value; - const AnEnum* return_value = nullptr; + AnotherEnum return_value_value; + const AnotherEnum* return_value = nullptr; if (!list_return_value->at(0).IsNull()) { - return_value_value = std::any_cast( + return_value_value = std::any_cast( std::get(list_return_value->at(0))); return_value = &return_value_value; } @@ -5945,7 +10095,7 @@ void FlutterIntegrationCoreApi::EchoAsyncString( /// The codec used by HostTrivialApi. const flutter::StandardMessageCodec& HostTrivialApi::GetCodec() { return flutter::StandardMessageCodec::GetInstance( - &PigeonCodecSerializer::GetInstance()); + &PigeonInternalCodecSerializer::GetInstance()); } // Sets up an instance of `HostTrivialApi` to handle messages through the @@ -6006,7 +10156,7 @@ EncodableValue HostTrivialApi::WrapError(const FlutterError& error) { /// The codec used by HostSmallApi. const flutter::StandardMessageCodec& HostSmallApi::GetCodec() { return flutter::StandardMessageCodec::GetInstance( - &PigeonCodecSerializer::GetInstance()); + &PigeonInternalCodecSerializer::GetInstance()); } // Sets up an instance of `HostSmallApi` to handle messages through the @@ -6116,7 +10266,7 @@ FlutterSmallApi::FlutterSmallApi(flutter::BinaryMessenger* binary_messenger, const flutter::StandardMessageCodec& FlutterSmallApi::GetCodec() { return flutter::StandardMessageCodec::GetInstance( - &PigeonCodecSerializer::GetInstance()); + &PigeonInternalCodecSerializer::GetInstance()); } void FlutterSmallApi::EchoWrappedList( diff --git a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h index ceed1b087273..7f19e1a19cba 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h +++ b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h @@ -66,11 +66,39 @@ class ErrorOr { }; enum class AnEnum { - one = 0, - two = 1, - three = 2, - fortyTwo = 3, - fourHundredTwentyTwo = 4 + kOne = 0, + kTwo = 1, + kThree = 2, + kFortyTwo = 3, + kFourHundredTwentyTwo = 4 +}; + +enum class AnotherEnum { kJustInCase = 0 }; + +// Generated class from Pigeon that represents data sent in messages. +class UnusedClass { + public: + // Constructs an object setting all non-nullable fields. + UnusedClass(); + + // Constructs an object setting all fields. + explicit UnusedClass(const flutter::EncodableValue* a_field); + + const flutter::EncodableValue* a_field() const; + void set_a_field(const flutter::EncodableValue* value_arg); + void set_a_field(const flutter::EncodableValue& value_arg); + + private: + static UnusedClass FromEncodableList(const flutter::EncodableList& list); + flutter::EncodableList ToEncodableList() const; + friend class HostIntegrationCoreApi; + friend class FlutterIntegrationCoreApi; + friend class HostTrivialApi; + friend class HostSmallApi; + friend class FlutterSmallApi; + friend class PigeonInternalCodecSerializer; + friend class CoreTestsTest; + std::optional a_field_; }; // A class containing all supported types. @@ -84,14 +112,25 @@ class AllTypes { const std::vector& a4_byte_array, const std::vector& a8_byte_array, const std::vector& a_float_array, - const AnEnum& an_enum, const std::string& a_string, + const AnEnum& an_enum, const AnotherEnum& another_enum, + const std::string& a_string, const flutter::EncodableValue& an_object, const flutter::EncodableList& list, const flutter::EncodableList& string_list, const flutter::EncodableList& int_list, const flutter::EncodableList& double_list, const flutter::EncodableList& bool_list, - const flutter::EncodableMap& map); + const flutter::EncodableList& enum_list, + const flutter::EncodableList& object_list, + const flutter::EncodableList& list_list, + const flutter::EncodableList& map_list, + const flutter::EncodableMap& map, + const flutter::EncodableMap& string_map, + const flutter::EncodableMap& int_map, + const flutter::EncodableMap& enum_map, + const flutter::EncodableMap& object_map, + const flutter::EncodableMap& list_map, + const flutter::EncodableMap& map_map); bool a_bool() const; void set_a_bool(bool value_arg); @@ -120,6 +159,9 @@ class AllTypes { const AnEnum& an_enum() const; void set_an_enum(const AnEnum& value_arg); + const AnotherEnum& another_enum() const; + void set_another_enum(const AnotherEnum& value_arg); + const std::string& a_string() const; void set_a_string(std::string_view value_arg); @@ -141,9 +183,39 @@ class AllTypes { const flutter::EncodableList& bool_list() const; void set_bool_list(const flutter::EncodableList& value_arg); + const flutter::EncodableList& enum_list() const; + void set_enum_list(const flutter::EncodableList& value_arg); + + const flutter::EncodableList& object_list() const; + void set_object_list(const flutter::EncodableList& value_arg); + + const flutter::EncodableList& list_list() const; + void set_list_list(const flutter::EncodableList& value_arg); + + const flutter::EncodableList& map_list() const; + void set_map_list(const flutter::EncodableList& value_arg); + const flutter::EncodableMap& map() const; void set_map(const flutter::EncodableMap& value_arg); + const flutter::EncodableMap& string_map() const; + void set_string_map(const flutter::EncodableMap& value_arg); + + const flutter::EncodableMap& int_map() const; + void set_int_map(const flutter::EncodableMap& value_arg); + + const flutter::EncodableMap& enum_map() const; + void set_enum_map(const flutter::EncodableMap& value_arg); + + const flutter::EncodableMap& object_map() const; + void set_object_map(const flutter::EncodableMap& value_arg); + + const flutter::EncodableMap& list_map() const; + void set_list_map(const flutter::EncodableMap& value_arg); + + const flutter::EncodableMap& map_map() const; + void set_map_map(const flutter::EncodableMap& value_arg); + private: static AllTypes FromEncodableList(const flutter::EncodableList& list); flutter::EncodableList ToEncodableList() const; @@ -153,7 +225,7 @@ class AllTypes { friend class HostTrivialApi; friend class HostSmallApi; friend class FlutterSmallApi; - friend class PigeonCodecSerializer; + friend class PigeonInternalCodecSerializer; friend class CoreTestsTest; bool a_bool_; int64_t an_int_; @@ -164,6 +236,7 @@ class AllTypes { std::vector a8_byte_array_; std::vector a_float_array_; AnEnum an_enum_; + AnotherEnum another_enum_; std::string a_string_; flutter::EncodableValue an_object_; flutter::EncodableList list_; @@ -171,7 +244,17 @@ class AllTypes { flutter::EncodableList int_list_; flutter::EncodableList double_list_; flutter::EncodableList bool_list_; + flutter::EncodableList enum_list_; + flutter::EncodableList object_list_; + flutter::EncodableList list_list_; + flutter::EncodableList map_list_; flutter::EncodableMap map_; + flutter::EncodableMap string_map_; + flutter::EncodableMap int_map_; + flutter::EncodableMap enum_map_; + flutter::EncodableMap object_map_; + flutter::EncodableMap list_map_; + flutter::EncodableMap map_map_; }; // A class containing all supported nullable types. @@ -190,10 +273,8 @@ class AllNullableTypes { const std::vector* a_nullable4_byte_array, const std::vector* a_nullable8_byte_array, const std::vector* a_nullable_float_array, - const flutter::EncodableList* nullable_nested_list, - const flutter::EncodableMap* nullable_map_with_annotations, - const flutter::EncodableMap* nullable_map_with_object, - const AnEnum* a_nullable_enum, const std::string* a_nullable_string, + const AnEnum* a_nullable_enum, const AnotherEnum* another_nullable_enum, + const std::string* a_nullable_string, const flutter::EncodableValue* a_nullable_object, const AllNullableTypes* all_nullable_types, const flutter::EncodableList* list, @@ -201,8 +282,18 @@ class AllNullableTypes { const flutter::EncodableList* int_list, const flutter::EncodableList* double_list, const flutter::EncodableList* bool_list, - const flutter::EncodableList* nested_class_list, - const flutter::EncodableMap* map); + const flutter::EncodableList* enum_list, + const flutter::EncodableList* object_list, + const flutter::EncodableList* list_list, + const flutter::EncodableList* map_list, + const flutter::EncodableList* recursive_class_list, + const flutter::EncodableMap* map, const flutter::EncodableMap* string_map, + const flutter::EncodableMap* int_map, + const flutter::EncodableMap* enum_map, + const flutter::EncodableMap* object_map, + const flutter::EncodableMap* list_map, + const flutter::EncodableMap* map_map, + const flutter::EncodableMap* recursive_class_map); ~AllNullableTypes() = default; AllNullableTypes(const AllNullableTypes& other); @@ -241,24 +332,14 @@ class AllNullableTypes { void set_a_nullable_float_array(const std::vector* value_arg); void set_a_nullable_float_array(const std::vector& value_arg); - const flutter::EncodableList* nullable_nested_list() const; - void set_nullable_nested_list(const flutter::EncodableList* value_arg); - void set_nullable_nested_list(const flutter::EncodableList& value_arg); - - const flutter::EncodableMap* nullable_map_with_annotations() const; - void set_nullable_map_with_annotations( - const flutter::EncodableMap* value_arg); - void set_nullable_map_with_annotations( - const flutter::EncodableMap& value_arg); - - const flutter::EncodableMap* nullable_map_with_object() const; - void set_nullable_map_with_object(const flutter::EncodableMap* value_arg); - void set_nullable_map_with_object(const flutter::EncodableMap& value_arg); - const AnEnum* a_nullable_enum() const; void set_a_nullable_enum(const AnEnum* value_arg); void set_a_nullable_enum(const AnEnum& value_arg); + const AnotherEnum* another_nullable_enum() const; + void set_another_nullable_enum(const AnotherEnum* value_arg); + void set_another_nullable_enum(const AnotherEnum& value_arg); + const std::string* a_nullable_string() const; void set_a_nullable_string(const std::string_view* value_arg); void set_a_nullable_string(std::string_view value_arg); @@ -291,14 +372,58 @@ class AllNullableTypes { void set_bool_list(const flutter::EncodableList* value_arg); void set_bool_list(const flutter::EncodableList& value_arg); - const flutter::EncodableList* nested_class_list() const; - void set_nested_class_list(const flutter::EncodableList* value_arg); - void set_nested_class_list(const flutter::EncodableList& value_arg); + const flutter::EncodableList* enum_list() const; + void set_enum_list(const flutter::EncodableList* value_arg); + void set_enum_list(const flutter::EncodableList& value_arg); + + const flutter::EncodableList* object_list() const; + void set_object_list(const flutter::EncodableList* value_arg); + void set_object_list(const flutter::EncodableList& value_arg); + + const flutter::EncodableList* list_list() const; + void set_list_list(const flutter::EncodableList* value_arg); + void set_list_list(const flutter::EncodableList& value_arg); + + const flutter::EncodableList* map_list() const; + void set_map_list(const flutter::EncodableList* value_arg); + void set_map_list(const flutter::EncodableList& value_arg); + + const flutter::EncodableList* recursive_class_list() const; + void set_recursive_class_list(const flutter::EncodableList* value_arg); + void set_recursive_class_list(const flutter::EncodableList& value_arg); const flutter::EncodableMap* map() const; void set_map(const flutter::EncodableMap* value_arg); void set_map(const flutter::EncodableMap& value_arg); + const flutter::EncodableMap* string_map() const; + void set_string_map(const flutter::EncodableMap* value_arg); + void set_string_map(const flutter::EncodableMap& value_arg); + + const flutter::EncodableMap* int_map() const; + void set_int_map(const flutter::EncodableMap* value_arg); + void set_int_map(const flutter::EncodableMap& value_arg); + + const flutter::EncodableMap* enum_map() const; + void set_enum_map(const flutter::EncodableMap* value_arg); + void set_enum_map(const flutter::EncodableMap& value_arg); + + const flutter::EncodableMap* object_map() const; + void set_object_map(const flutter::EncodableMap* value_arg); + void set_object_map(const flutter::EncodableMap& value_arg); + + const flutter::EncodableMap* list_map() const; + void set_list_map(const flutter::EncodableMap* value_arg); + void set_list_map(const flutter::EncodableMap& value_arg); + + const flutter::EncodableMap* map_map() const; + void set_map_map(const flutter::EncodableMap* value_arg); + void set_map_map(const flutter::EncodableMap& value_arg); + + const flutter::EncodableMap* recursive_class_map() const; + void set_recursive_class_map(const flutter::EncodableMap* value_arg); + void set_recursive_class_map(const flutter::EncodableMap& value_arg); + private: static AllNullableTypes FromEncodableList(const flutter::EncodableList& list); flutter::EncodableList ToEncodableList() const; @@ -308,7 +433,7 @@ class AllNullableTypes { friend class HostTrivialApi; friend class HostSmallApi; friend class FlutterSmallApi; - friend class PigeonCodecSerializer; + friend class PigeonInternalCodecSerializer; friend class CoreTestsTest; std::optional a_nullable_bool_; std::optional a_nullable_int_; @@ -318,10 +443,8 @@ class AllNullableTypes { std::optional> a_nullable4_byte_array_; std::optional> a_nullable8_byte_array_; std::optional> a_nullable_float_array_; - std::optional nullable_nested_list_; - std::optional nullable_map_with_annotations_; - std::optional nullable_map_with_object_; std::optional a_nullable_enum_; + std::optional another_nullable_enum_; std::optional a_nullable_string_; std::optional a_nullable_object_; std::unique_ptr all_nullable_types_; @@ -330,8 +453,19 @@ class AllNullableTypes { std::optional int_list_; std::optional double_list_; std::optional bool_list_; - std::optional nested_class_list_; + std::optional enum_list_; + std::optional object_list_; + std::optional list_list_; + std::optional map_list_; + std::optional recursive_class_list_; std::optional map_; + std::optional string_map_; + std::optional int_map_; + std::optional enum_map_; + std::optional object_map_; + std::optional list_map_; + std::optional map_map_; + std::optional recursive_class_map_; }; // The primary purpose for this class is to ensure coverage of Swift structs @@ -352,17 +486,24 @@ class AllNullableTypesWithoutRecursion { const std::vector* a_nullable4_byte_array, const std::vector* a_nullable8_byte_array, const std::vector* a_nullable_float_array, - const flutter::EncodableList* nullable_nested_list, - const flutter::EncodableMap* nullable_map_with_annotations, - const flutter::EncodableMap* nullable_map_with_object, - const AnEnum* a_nullable_enum, const std::string* a_nullable_string, + const AnEnum* a_nullable_enum, const AnotherEnum* another_nullable_enum, + const std::string* a_nullable_string, const flutter::EncodableValue* a_nullable_object, const flutter::EncodableList* list, const flutter::EncodableList* string_list, const flutter::EncodableList* int_list, const flutter::EncodableList* double_list, const flutter::EncodableList* bool_list, - const flutter::EncodableMap* map); + const flutter::EncodableList* enum_list, + const flutter::EncodableList* object_list, + const flutter::EncodableList* list_list, + const flutter::EncodableList* map_list, const flutter::EncodableMap* map, + const flutter::EncodableMap* string_map, + const flutter::EncodableMap* int_map, + const flutter::EncodableMap* enum_map, + const flutter::EncodableMap* object_map, + const flutter::EncodableMap* list_map, + const flutter::EncodableMap* map_map); const bool* a_nullable_bool() const; void set_a_nullable_bool(const bool* value_arg); @@ -396,24 +537,14 @@ class AllNullableTypesWithoutRecursion { void set_a_nullable_float_array(const std::vector* value_arg); void set_a_nullable_float_array(const std::vector& value_arg); - const flutter::EncodableList* nullable_nested_list() const; - void set_nullable_nested_list(const flutter::EncodableList* value_arg); - void set_nullable_nested_list(const flutter::EncodableList& value_arg); - - const flutter::EncodableMap* nullable_map_with_annotations() const; - void set_nullable_map_with_annotations( - const flutter::EncodableMap* value_arg); - void set_nullable_map_with_annotations( - const flutter::EncodableMap& value_arg); - - const flutter::EncodableMap* nullable_map_with_object() const; - void set_nullable_map_with_object(const flutter::EncodableMap* value_arg); - void set_nullable_map_with_object(const flutter::EncodableMap& value_arg); - const AnEnum* a_nullable_enum() const; void set_a_nullable_enum(const AnEnum* value_arg); void set_a_nullable_enum(const AnEnum& value_arg); + const AnotherEnum* another_nullable_enum() const; + void set_another_nullable_enum(const AnotherEnum* value_arg); + void set_another_nullable_enum(const AnotherEnum& value_arg); + const std::string* a_nullable_string() const; void set_a_nullable_string(const std::string_view* value_arg); void set_a_nullable_string(std::string_view value_arg); @@ -442,10 +573,50 @@ class AllNullableTypesWithoutRecursion { void set_bool_list(const flutter::EncodableList* value_arg); void set_bool_list(const flutter::EncodableList& value_arg); + const flutter::EncodableList* enum_list() const; + void set_enum_list(const flutter::EncodableList* value_arg); + void set_enum_list(const flutter::EncodableList& value_arg); + + const flutter::EncodableList* object_list() const; + void set_object_list(const flutter::EncodableList* value_arg); + void set_object_list(const flutter::EncodableList& value_arg); + + const flutter::EncodableList* list_list() const; + void set_list_list(const flutter::EncodableList* value_arg); + void set_list_list(const flutter::EncodableList& value_arg); + + const flutter::EncodableList* map_list() const; + void set_map_list(const flutter::EncodableList* value_arg); + void set_map_list(const flutter::EncodableList& value_arg); + const flutter::EncodableMap* map() const; void set_map(const flutter::EncodableMap* value_arg); void set_map(const flutter::EncodableMap& value_arg); + const flutter::EncodableMap* string_map() const; + void set_string_map(const flutter::EncodableMap* value_arg); + void set_string_map(const flutter::EncodableMap& value_arg); + + const flutter::EncodableMap* int_map() const; + void set_int_map(const flutter::EncodableMap* value_arg); + void set_int_map(const flutter::EncodableMap& value_arg); + + const flutter::EncodableMap* enum_map() const; + void set_enum_map(const flutter::EncodableMap* value_arg); + void set_enum_map(const flutter::EncodableMap& value_arg); + + const flutter::EncodableMap* object_map() const; + void set_object_map(const flutter::EncodableMap* value_arg); + void set_object_map(const flutter::EncodableMap& value_arg); + + const flutter::EncodableMap* list_map() const; + void set_list_map(const flutter::EncodableMap* value_arg); + void set_list_map(const flutter::EncodableMap& value_arg); + + const flutter::EncodableMap* map_map() const; + void set_map_map(const flutter::EncodableMap* value_arg); + void set_map_map(const flutter::EncodableMap& value_arg); + private: static AllNullableTypesWithoutRecursion FromEncodableList( const flutter::EncodableList& list); @@ -456,7 +627,7 @@ class AllNullableTypesWithoutRecursion { friend class HostTrivialApi; friend class HostSmallApi; friend class FlutterSmallApi; - friend class PigeonCodecSerializer; + friend class PigeonInternalCodecSerializer; friend class CoreTestsTest; std::optional a_nullable_bool_; std::optional a_nullable_int_; @@ -466,10 +637,8 @@ class AllNullableTypesWithoutRecursion { std::optional> a_nullable4_byte_array_; std::optional> a_nullable8_byte_array_; std::optional> a_nullable_float_array_; - std::optional nullable_nested_list_; - std::optional nullable_map_with_annotations_; - std::optional nullable_map_with_object_; std::optional a_nullable_enum_; + std::optional another_nullable_enum_; std::optional a_nullable_string_; std::optional a_nullable_object_; std::optional list_; @@ -477,7 +646,17 @@ class AllNullableTypesWithoutRecursion { std::optional int_list_; std::optional double_list_; std::optional bool_list_; + std::optional enum_list_; + std::optional object_list_; + std::optional list_list_; + std::optional map_list_; std::optional map_; + std::optional string_map_; + std::optional int_map_; + std::optional enum_map_; + std::optional object_map_; + std::optional list_map_; + std::optional map_map_; }; // A class for testing nested class handling. @@ -490,13 +669,19 @@ class AllNullableTypesWithoutRecursion { class AllClassesWrapper { public: // Constructs an object setting all non-nullable fields. - explicit AllClassesWrapper(const AllNullableTypes& all_nullable_types); + explicit AllClassesWrapper(const AllNullableTypes& all_nullable_types, + const flutter::EncodableList& class_list, + const flutter::EncodableMap& class_map); // Constructs an object setting all fields. explicit AllClassesWrapper(const AllNullableTypes& all_nullable_types, const AllNullableTypesWithoutRecursion* all_nullable_types_without_recursion, - const AllTypes* all_types); + const AllTypes* all_types, + const flutter::EncodableList& class_list, + const flutter::EncodableList* nullable_class_list, + const flutter::EncodableMap& class_map, + const flutter::EncodableMap* nullable_class_map); ~AllClassesWrapper() = default; AllClassesWrapper(const AllClassesWrapper& other); @@ -517,6 +702,20 @@ class AllClassesWrapper { void set_all_types(const AllTypes* value_arg); void set_all_types(const AllTypes& value_arg); + const flutter::EncodableList& class_list() const; + void set_class_list(const flutter::EncodableList& value_arg); + + const flutter::EncodableList* nullable_class_list() const; + void set_nullable_class_list(const flutter::EncodableList* value_arg); + void set_nullable_class_list(const flutter::EncodableList& value_arg); + + const flutter::EncodableMap& class_map() const; + void set_class_map(const flutter::EncodableMap& value_arg); + + const flutter::EncodableMap* nullable_class_map() const; + void set_nullable_class_map(const flutter::EncodableMap* value_arg); + void set_nullable_class_map(const flutter::EncodableMap& value_arg); + private: static AllClassesWrapper FromEncodableList( const flutter::EncodableList& list); @@ -526,12 +725,16 @@ class AllClassesWrapper { friend class HostTrivialApi; friend class HostSmallApi; friend class FlutterSmallApi; - friend class PigeonCodecSerializer; + friend class PigeonInternalCodecSerializer; friend class CoreTestsTest; std::unique_ptr all_nullable_types_; std::unique_ptr all_nullable_types_without_recursion_; std::unique_ptr all_types_; + flutter::EncodableList class_list_; + std::optional nullable_class_list_; + flutter::EncodableMap class_map_; + std::optional nullable_class_map_; }; // A data class containing a List, used in unit tests. @@ -557,16 +760,16 @@ class TestMessage { friend class HostTrivialApi; friend class HostSmallApi; friend class FlutterSmallApi; - friend class PigeonCodecSerializer; + friend class PigeonInternalCodecSerializer; friend class CoreTestsTest; std::optional test_list_; }; -class PigeonCodecSerializer : public flutter::StandardCodecSerializer { +class PigeonInternalCodecSerializer : public flutter::StandardCodecSerializer { public: - PigeonCodecSerializer(); - inline static PigeonCodecSerializer& GetInstance() { - static PigeonCodecSerializer sInstance; + PigeonInternalCodecSerializer(); + inline static PigeonInternalCodecSerializer& GetInstance() { + static PigeonInternalCodecSerializer sInstance; return sInstance; } @@ -617,15 +820,54 @@ class HostIntegrationCoreApi { // Returns the passed list, to test serialization and deserialization. virtual ErrorOr EchoList( const flutter::EncodableList& list) = 0; + // Returns the passed list, to test serialization and deserialization. + virtual ErrorOr EchoEnumList( + const flutter::EncodableList& enum_list) = 0; + // Returns the passed list, to test serialization and deserialization. + virtual ErrorOr EchoClassList( + const flutter::EncodableList& class_list) = 0; + // Returns the passed list, to test serialization and deserialization. + virtual ErrorOr EchoNonNullEnumList( + const flutter::EncodableList& enum_list) = 0; + // Returns the passed list, to test serialization and deserialization. + virtual ErrorOr EchoNonNullClassList( + const flutter::EncodableList& class_list) = 0; // Returns the passed map, to test serialization and deserialization. virtual ErrorOr EchoMap( - const flutter::EncodableMap& a_map) = 0; - // Returns the passed map to test nested class serialization and + const flutter::EncodableMap& map) = 0; + // Returns the passed map, to test serialization and deserialization. + virtual ErrorOr EchoStringMap( + const flutter::EncodableMap& string_map) = 0; + // Returns the passed map, to test serialization and deserialization. + virtual ErrorOr EchoIntMap( + const flutter::EncodableMap& int_map) = 0; + // Returns the passed map, to test serialization and deserialization. + virtual ErrorOr EchoEnumMap( + const flutter::EncodableMap& enum_map) = 0; + // Returns the passed map, to test serialization and deserialization. + virtual ErrorOr EchoClassMap( + const flutter::EncodableMap& class_map) = 0; + // Returns the passed map, to test serialization and deserialization. + virtual ErrorOr EchoNonNullStringMap( + const flutter::EncodableMap& string_map) = 0; + // Returns the passed map, to test serialization and deserialization. + virtual ErrorOr EchoNonNullIntMap( + const flutter::EncodableMap& int_map) = 0; + // Returns the passed map, to test serialization and deserialization. + virtual ErrorOr EchoNonNullEnumMap( + const flutter::EncodableMap& enum_map) = 0; + // Returns the passed map, to test serialization and deserialization. + virtual ErrorOr EchoNonNullClassMap( + const flutter::EncodableMap& class_map) = 0; + // Returns the passed class to test nested class serialization and // deserialization. virtual ErrorOr EchoClassWrapper( const AllClassesWrapper& wrapper) = 0; // Returns the passed enum to test serialization and deserialization. virtual ErrorOr EchoEnum(const AnEnum& an_enum) = 0; + // Returns the passed enum to test serialization and deserialization. + virtual ErrorOr EchoAnotherEnum( + const AnotherEnum& another_enum) = 0; // Returns the default string. virtual ErrorOr EchoNamedDefaultString( const std::string& a_string) = 0; @@ -678,11 +920,49 @@ class HostIntegrationCoreApi { // Returns the passed list, to test serialization and deserialization. virtual ErrorOr> EchoNullableList( const flutter::EncodableList* a_nullable_list) = 0; + // Returns the passed list, to test serialization and deserialization. + virtual ErrorOr> EchoNullableEnumList( + const flutter::EncodableList* enum_list) = 0; + // Returns the passed list, to test serialization and deserialization. + virtual ErrorOr> EchoNullableClassList( + const flutter::EncodableList* class_list) = 0; + // Returns the passed list, to test serialization and deserialization. + virtual ErrorOr> + EchoNullableNonNullEnumList(const flutter::EncodableList* enum_list) = 0; + // Returns the passed list, to test serialization and deserialization. + virtual ErrorOr> + EchoNullableNonNullClassList(const flutter::EncodableList* class_list) = 0; // Returns the passed map, to test serialization and deserialization. virtual ErrorOr> EchoNullableMap( - const flutter::EncodableMap* a_nullable_map) = 0; + const flutter::EncodableMap* map) = 0; + // Returns the passed map, to test serialization and deserialization. + virtual ErrorOr> EchoNullableStringMap( + const flutter::EncodableMap* string_map) = 0; + // Returns the passed map, to test serialization and deserialization. + virtual ErrorOr> EchoNullableIntMap( + const flutter::EncodableMap* int_map) = 0; + // Returns the passed map, to test serialization and deserialization. + virtual ErrorOr> EchoNullableEnumMap( + const flutter::EncodableMap* enum_map) = 0; + // Returns the passed map, to test serialization and deserialization. + virtual ErrorOr> EchoNullableClassMap( + const flutter::EncodableMap* class_map) = 0; + // Returns the passed map, to test serialization and deserialization. + virtual ErrorOr> + EchoNullableNonNullStringMap(const flutter::EncodableMap* string_map) = 0; + // Returns the passed map, to test serialization and deserialization. + virtual ErrorOr> + EchoNullableNonNullIntMap(const flutter::EncodableMap* int_map) = 0; + // Returns the passed map, to test serialization and deserialization. + virtual ErrorOr> + EchoNullableNonNullEnumMap(const flutter::EncodableMap* enum_map) = 0; + // Returns the passed map, to test serialization and deserialization. + virtual ErrorOr> + EchoNullableNonNullClassMap(const flutter::EncodableMap* class_map) = 0; virtual ErrorOr> EchoNullableEnum( const AnEnum* an_enum) = 0; + virtual ErrorOr> EchoAnotherNullableEnum( + const AnotherEnum* another_enum) = 0; // Returns passed in int. virtual ErrorOr> EchoOptionalNullableInt( const int64_t* a_nullable_int) = 0; @@ -719,16 +999,51 @@ class HostIntegrationCoreApi { virtual void EchoAsyncList( const flutter::EncodableList& list, std::function reply)> result) = 0; + // Returns the passed list, to test asynchronous serialization and + // deserialization. + virtual void EchoAsyncEnumList( + const flutter::EncodableList& enum_list, + std::function reply)> result) = 0; + // Returns the passed list, to test asynchronous serialization and + // deserialization. + virtual void EchoAsyncClassList( + const flutter::EncodableList& class_list, + std::function reply)> result) = 0; // Returns the passed map, to test asynchronous serialization and // deserialization. virtual void EchoAsyncMap( - const flutter::EncodableMap& a_map, + const flutter::EncodableMap& map, + std::function reply)> result) = 0; + // Returns the passed map, to test asynchronous serialization and + // deserialization. + virtual void EchoAsyncStringMap( + const flutter::EncodableMap& string_map, + std::function reply)> result) = 0; + // Returns the passed map, to test asynchronous serialization and + // deserialization. + virtual void EchoAsyncIntMap( + const flutter::EncodableMap& int_map, + std::function reply)> result) = 0; + // Returns the passed map, to test asynchronous serialization and + // deserialization. + virtual void EchoAsyncEnumMap( + const flutter::EncodableMap& enum_map, + std::function reply)> result) = 0; + // Returns the passed map, to test asynchronous serialization and + // deserialization. + virtual void EchoAsyncClassMap( + const flutter::EncodableMap& class_map, std::function reply)> result) = 0; // Returns the passed enum, to test asynchronous serialization and // deserialization. virtual void EchoAsyncEnum( const AnEnum& an_enum, std::function reply)> result) = 0; + // Returns the passed enum, to test asynchronous serialization and + // deserialization. + virtual void EchoAnotherAsyncEnum( + const AnotherEnum& another_enum, + std::function reply)> result) = 0; // Responds with an error from an async function returning a value. virtual void ThrowAsyncError( std::function> reply)> @@ -788,10 +1103,46 @@ class HostIntegrationCoreApi { const flutter::EncodableList* list, std::function> reply)> result) = 0; + // Returns the passed list, to test asynchronous serialization and + // deserialization. + virtual void EchoAsyncNullableEnumList( + const flutter::EncodableList* enum_list, + std::function> reply)> + result) = 0; + // Returns the passed list, to test asynchronous serialization and + // deserialization. + virtual void EchoAsyncNullableClassList( + const flutter::EncodableList* class_list, + std::function> reply)> + result) = 0; // Returns the passed map, to test asynchronous serialization and // deserialization. virtual void EchoAsyncNullableMap( - const flutter::EncodableMap* a_map, + const flutter::EncodableMap* map, + std::function> reply)> + result) = 0; + // Returns the passed map, to test asynchronous serialization and + // deserialization. + virtual void EchoAsyncNullableStringMap( + const flutter::EncodableMap* string_map, + std::function> reply)> + result) = 0; + // Returns the passed map, to test asynchronous serialization and + // deserialization. + virtual void EchoAsyncNullableIntMap( + const flutter::EncodableMap* int_map, + std::function> reply)> + result) = 0; + // Returns the passed map, to test asynchronous serialization and + // deserialization. + virtual void EchoAsyncNullableEnumMap( + const flutter::EncodableMap* enum_map, + std::function> reply)> + result) = 0; + // Returns the passed map, to test asynchronous serialization and + // deserialization. + virtual void EchoAsyncNullableClassMap( + const flutter::EncodableMap* class_map, std::function> reply)> result) = 0; // Returns the passed enum, to test asynchronous serialization and @@ -799,6 +1150,12 @@ class HostIntegrationCoreApi { virtual void EchoAsyncNullableEnum( const AnEnum* an_enum, std::function> reply)> result) = 0; + // Returns the passed enum, to test asynchronous serialization and + // deserialization. + virtual void EchoAnotherAsyncNullableEnum( + const AnotherEnum* another_enum, + std::function> reply)> + result) = 0; virtual void CallFlutterNoop( std::function reply)> result) = 0; virtual void CallFlutterThrowError( @@ -842,12 +1199,51 @@ class HostIntegrationCoreApi { virtual void CallFlutterEchoList( const flutter::EncodableList& list, std::function reply)> result) = 0; + virtual void CallFlutterEchoEnumList( + const flutter::EncodableList& enum_list, + std::function reply)> result) = 0; + virtual void CallFlutterEchoClassList( + const flutter::EncodableList& class_list, + std::function reply)> result) = 0; + virtual void CallFlutterEchoNonNullEnumList( + const flutter::EncodableList& enum_list, + std::function reply)> result) = 0; + virtual void CallFlutterEchoNonNullClassList( + const flutter::EncodableList& class_list, + std::function reply)> result) = 0; virtual void CallFlutterEchoMap( - const flutter::EncodableMap& a_map, + const flutter::EncodableMap& map, + std::function reply)> result) = 0; + virtual void CallFlutterEchoStringMap( + const flutter::EncodableMap& string_map, + std::function reply)> result) = 0; + virtual void CallFlutterEchoIntMap( + const flutter::EncodableMap& int_map, + std::function reply)> result) = 0; + virtual void CallFlutterEchoEnumMap( + const flutter::EncodableMap& enum_map, + std::function reply)> result) = 0; + virtual void CallFlutterEchoClassMap( + const flutter::EncodableMap& class_map, + std::function reply)> result) = 0; + virtual void CallFlutterEchoNonNullStringMap( + const flutter::EncodableMap& string_map, + std::function reply)> result) = 0; + virtual void CallFlutterEchoNonNullIntMap( + const flutter::EncodableMap& int_map, + std::function reply)> result) = 0; + virtual void CallFlutterEchoNonNullEnumMap( + const flutter::EncodableMap& enum_map, + std::function reply)> result) = 0; + virtual void CallFlutterEchoNonNullClassMap( + const flutter::EncodableMap& class_map, std::function reply)> result) = 0; virtual void CallFlutterEchoEnum( const AnEnum& an_enum, std::function reply)> result) = 0; + virtual void CallFlutterEchoAnotherEnum( + const AnotherEnum& another_enum, + std::function reply)> result) = 0; virtual void CallFlutterEchoNullableBool( const bool* a_bool, std::function> reply)> result) = 0; @@ -869,13 +1265,65 @@ class HostIntegrationCoreApi { const flutter::EncodableList* list, std::function> reply)> result) = 0; + virtual void CallFlutterEchoNullableEnumList( + const flutter::EncodableList* enum_list, + std::function> reply)> + result) = 0; + virtual void CallFlutterEchoNullableClassList( + const flutter::EncodableList* class_list, + std::function> reply)> + result) = 0; + virtual void CallFlutterEchoNullableNonNullEnumList( + const flutter::EncodableList* enum_list, + std::function> reply)> + result) = 0; + virtual void CallFlutterEchoNullableNonNullClassList( + const flutter::EncodableList* class_list, + std::function> reply)> + result) = 0; virtual void CallFlutterEchoNullableMap( - const flutter::EncodableMap* a_map, + const flutter::EncodableMap* map, + std::function> reply)> + result) = 0; + virtual void CallFlutterEchoNullableStringMap( + const flutter::EncodableMap* string_map, + std::function> reply)> + result) = 0; + virtual void CallFlutterEchoNullableIntMap( + const flutter::EncodableMap* int_map, + std::function> reply)> + result) = 0; + virtual void CallFlutterEchoNullableEnumMap( + const flutter::EncodableMap* enum_map, + std::function> reply)> + result) = 0; + virtual void CallFlutterEchoNullableClassMap( + const flutter::EncodableMap* class_map, + std::function> reply)> + result) = 0; + virtual void CallFlutterEchoNullableNonNullStringMap( + const flutter::EncodableMap* string_map, + std::function> reply)> + result) = 0; + virtual void CallFlutterEchoNullableNonNullIntMap( + const flutter::EncodableMap* int_map, + std::function> reply)> + result) = 0; + virtual void CallFlutterEchoNullableNonNullEnumMap( + const flutter::EncodableMap* enum_map, + std::function> reply)> + result) = 0; + virtual void CallFlutterEchoNullableNonNullClassMap( + const flutter::EncodableMap* class_map, std::function> reply)> result) = 0; virtual void CallFlutterEchoNullableEnum( const AnEnum* an_enum, std::function> reply)> result) = 0; + virtual void CallFlutterEchoAnotherNullableEnum( + const AnotherEnum* another_enum, + std::function> reply)> + result) = 0; virtual void CallFlutterSmallApiEchoString( const std::string& a_string, std::function reply)> result) = 0; @@ -969,14 +1417,78 @@ class FlutterIntegrationCoreApi { void EchoList(const flutter::EncodableList& list, std::function&& on_success, std::function&& on_error); + // Returns the passed list, to test serialization and deserialization. + void EchoEnumList( + const flutter::EncodableList& enum_list, + std::function&& on_success, + std::function&& on_error); + // Returns the passed list, to test serialization and deserialization. + void EchoClassList( + const flutter::EncodableList& class_list, + std::function&& on_success, + std::function&& on_error); + // Returns the passed list, to test serialization and deserialization. + void EchoNonNullEnumList( + const flutter::EncodableList& enum_list, + std::function&& on_success, + std::function&& on_error); + // Returns the passed list, to test serialization and deserialization. + void EchoNonNullClassList( + const flutter::EncodableList& class_list, + std::function&& on_success, + std::function&& on_error); // Returns the passed map, to test serialization and deserialization. - void EchoMap(const flutter::EncodableMap& a_map, + void EchoMap(const flutter::EncodableMap& map, std::function&& on_success, std::function&& on_error); + // Returns the passed map, to test serialization and deserialization. + void EchoStringMap( + const flutter::EncodableMap& string_map, + std::function&& on_success, + std::function&& on_error); + // Returns the passed map, to test serialization and deserialization. + void EchoIntMap( + const flutter::EncodableMap& int_map, + std::function&& on_success, + std::function&& on_error); + // Returns the passed map, to test serialization and deserialization. + void EchoEnumMap( + const flutter::EncodableMap& enum_map, + std::function&& on_success, + std::function&& on_error); + // Returns the passed map, to test serialization and deserialization. + void EchoClassMap( + const flutter::EncodableMap& class_map, + std::function&& on_success, + std::function&& on_error); + // Returns the passed map, to test serialization and deserialization. + void EchoNonNullStringMap( + const flutter::EncodableMap& string_map, + std::function&& on_success, + std::function&& on_error); + // Returns the passed map, to test serialization and deserialization. + void EchoNonNullIntMap( + const flutter::EncodableMap& int_map, + std::function&& on_success, + std::function&& on_error); + // Returns the passed map, to test serialization and deserialization. + void EchoNonNullEnumMap( + const flutter::EncodableMap& enum_map, + std::function&& on_success, + std::function&& on_error); + // Returns the passed map, to test serialization and deserialization. + void EchoNonNullClassMap( + const flutter::EncodableMap& class_map, + std::function&& on_success, + std::function&& on_error); // Returns the passed enum to test serialization and deserialization. void EchoEnum(const AnEnum& an_enum, std::function&& on_success, std::function&& on_error); + // Returns the passed enum to test serialization and deserialization. + void EchoAnotherEnum(const AnotherEnum& another_enum, + std::function&& on_success, + std::function&& on_error); // Returns the passed boolean, to test serialization and deserialization. void EchoNullableBool(const bool* a_bool, std::function&& on_success, @@ -1003,15 +1515,80 @@ class FlutterIntegrationCoreApi { const flutter::EncodableList* list, std::function&& on_success, std::function&& on_error); + // Returns the passed list, to test serialization and deserialization. + void EchoNullableEnumList( + const flutter::EncodableList* enum_list, + std::function&& on_success, + std::function&& on_error); + // Returns the passed list, to test serialization and deserialization. + void EchoNullableClassList( + const flutter::EncodableList* class_list, + std::function&& on_success, + std::function&& on_error); + // Returns the passed list, to test serialization and deserialization. + void EchoNullableNonNullEnumList( + const flutter::EncodableList* enum_list, + std::function&& on_success, + std::function&& on_error); + // Returns the passed list, to test serialization and deserialization. + void EchoNullableNonNullClassList( + const flutter::EncodableList* class_list, + std::function&& on_success, + std::function&& on_error); // Returns the passed map, to test serialization and deserialization. void EchoNullableMap( - const flutter::EncodableMap* a_map, + const flutter::EncodableMap* map, + std::function&& on_success, + std::function&& on_error); + // Returns the passed map, to test serialization and deserialization. + void EchoNullableStringMap( + const flutter::EncodableMap* string_map, + std::function&& on_success, + std::function&& on_error); + // Returns the passed map, to test serialization and deserialization. + void EchoNullableIntMap( + const flutter::EncodableMap* int_map, + std::function&& on_success, + std::function&& on_error); + // Returns the passed map, to test serialization and deserialization. + void EchoNullableEnumMap( + const flutter::EncodableMap* enum_map, + std::function&& on_success, + std::function&& on_error); + // Returns the passed map, to test serialization and deserialization. + void EchoNullableClassMap( + const flutter::EncodableMap* class_map, + std::function&& on_success, + std::function&& on_error); + // Returns the passed map, to test serialization and deserialization. + void EchoNullableNonNullStringMap( + const flutter::EncodableMap* string_map, + std::function&& on_success, + std::function&& on_error); + // Returns the passed map, to test serialization and deserialization. + void EchoNullableNonNullIntMap( + const flutter::EncodableMap* int_map, + std::function&& on_success, + std::function&& on_error); + // Returns the passed map, to test serialization and deserialization. + void EchoNullableNonNullEnumMap( + const flutter::EncodableMap* enum_map, + std::function&& on_success, + std::function&& on_error); + // Returns the passed map, to test serialization and deserialization. + void EchoNullableNonNullClassMap( + const flutter::EncodableMap* class_map, std::function&& on_success, std::function&& on_error); // Returns the passed enum to test serialization and deserialization. void EchoNullableEnum(const AnEnum* an_enum, std::function&& on_success, std::function&& on_error); + // Returns the passed enum to test serialization and deserialization. + void EchoAnotherNullableEnum( + const AnotherEnum* another_enum, + std::function&& on_success, + std::function&& on_error); // A no-op function taking no arguments and returning no value, to sanity // test basic asynchronous calling. void NoopAsync(std::function&& on_success, diff --git a/packages/pigeon/platform_tests/test_plugin/windows/test/null_fields_test.cpp b/packages/pigeon/platform_tests/test_plugin/windows/test/null_fields_test.cpp index e6a366248f08..8bbbf3edf9f6 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/test/null_fields_test.cpp +++ b/packages/pigeon/platform_tests/test_plugin/windows/test/null_fields_test.cpp @@ -66,13 +66,13 @@ TEST(NullFields, BuildWithValues) { reply.set_error("error"); reply.set_indices(EncodableList({1, 2, 3})); reply.set_request(request); - reply.set_type(NullFieldsSearchReplyType::success); + reply.set_type(NullFieldsSearchReplyType::kSuccess); EXPECT_EQ(*reply.result(), "result"); EXPECT_EQ(*reply.error(), "error"); EXPECT_EQ(reply.indices()->size(), 3); EXPECT_EQ(*reply.request()->query(), "hello"); - EXPECT_EQ(*reply.type(), NullFieldsSearchReplyType::success); + EXPECT_EQ(*reply.type(), NullFieldsSearchReplyType::kSuccess); } TEST(NullFields, BuildRequestWithNulls) { @@ -92,9 +92,10 @@ TEST(NullFields, BuildReplyWithNulls) { } TEST_F(NullFieldsTest, RequestFromListWithValues) { + int64_t one = 1; EncodableList list{ EncodableValue("hello"), - EncodableValue(1), + EncodableValue(one), }; NullFieldsSearchRequest request = RequestFromList(list); @@ -103,9 +104,10 @@ TEST_F(NullFieldsTest, RequestFromListWithValues) { } TEST_F(NullFieldsTest, RequestFromListWithNulls) { + int64_t one = 1; EncodableList list{ EncodableValue(), - EncodableValue(1), + EncodableValue(one), }; NullFieldsSearchRequest request = RequestFromList(list); @@ -121,7 +123,7 @@ TEST_F(NullFieldsTest, ReplyFromListWithValues) { EncodableValue("error"), EncodableValue(EncodableList({1, 2, 3})), CustomEncodableValue(request), - CustomEncodableValue(NullFieldsSearchReplyType::success), + CustomEncodableValue(NullFieldsSearchReplyType::kSuccess), }; NullFieldsSearchReply reply = ReplyFromList(list); @@ -130,7 +132,7 @@ TEST_F(NullFieldsTest, ReplyFromListWithValues) { EXPECT_EQ(reply.indices()->size(), 3); EXPECT_EQ(*reply.request()->query(), "hello"); EXPECT_EQ(reply.request()->identifier(), 1); - EXPECT_EQ(*reply.type(), NullFieldsSearchReplyType::success); + EXPECT_EQ(*reply.type(), NullFieldsSearchReplyType::kSuccess); } TEST_F(NullFieldsTest, ReplyFromListWithNulls) { @@ -178,7 +180,7 @@ TEST_F(NullFieldsTest, ReplyToMapWithValues) { reply.set_error("error"); reply.set_indices(EncodableList({1, 2, 3})); reply.set_request(request); - reply.set_type(NullFieldsSearchReplyType::success); + reply.set_type(NullFieldsSearchReplyType::kSuccess); const EncodableList list = ListFromReply(reply); diff --git a/packages/pigeon/platform_tests/test_plugin/windows/test/nullable_returns_test.cpp b/packages/pigeon/platform_tests/test_plugin/windows/test/nullable_returns_test.cpp index 89c0f3175ae6..6a3bed759b48 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/test/nullable_returns_test.cpp +++ b/packages/pigeon/platform_tests/test_plugin/windows/test/nullable_returns_test.cpp @@ -68,9 +68,10 @@ TEST(NullableReturns, HostNullableArgNonNull) { NullableArgHostApi::SetUp(&messenger, &api); int64_t result = 0; + int64_t seven = 7; messenger.SendHostMessage( "dev.flutter.pigeon.pigeon_integration_tests.NullableArgHostApi.doit", - EncodableValue(EncodableList({EncodableValue(7)})), + EncodableValue(EncodableList({EncodableValue(seven)})), [&result](const EncodableValue& reply) { result = GetResult(reply).LongValue(); }); diff --git a/packages/pigeon/platform_tests/test_plugin/windows/test/pigeon_test.cpp b/packages/pigeon/platform_tests/test_plugin/windows/test/pigeon_test.cpp index 427a62f06c6e..53e7f8ddadb3 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/test/pigeon_test.cpp +++ b/packages/pigeon/platform_tests/test_plugin/windows/test/pigeon_test.cpp @@ -137,7 +137,7 @@ TEST(PigeonTests, CallSearch) { Writer writer; flutter::EncodableList args; args.push_back(flutter::CustomEncodableValue(request)); - PigeonCodecSerializer::GetInstance().WriteValue(args, &writer); + PigeonInternalCodecSerializer::GetInstance().WriteValue(args, &writer); handler(writer.data_.data(), writer.data_.size(), reply); EXPECT_TRUE(did_call_reply); } diff --git a/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp b/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp index 0dd3e13ce192..c6f69c0a8c07 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp +++ b/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp @@ -21,6 +21,7 @@ using core_tests_pigeontest::AllNullableTypes; using core_tests_pigeontest::AllNullableTypesWithoutRecursion; using core_tests_pigeontest::AllTypes; using core_tests_pigeontest::AnEnum; +using core_tests_pigeontest::AnotherEnum; using core_tests_pigeontest::ErrorOr; using core_tests_pigeontest::FlutterError; using core_tests_pigeontest::FlutterIntegrationCoreApi; @@ -140,10 +141,67 @@ ErrorOr TestPlugin::EchoList(const EncodableList& a_list) { return a_list; } +ErrorOr TestPlugin::EchoEnumList( + const EncodableList& enum_list) { + return enum_list; +} + +ErrorOr TestPlugin::EchoClassList( + const EncodableList& class_list) { + return class_list; +} + +ErrorOr TestPlugin::EchoNonNullEnumList( + const EncodableList& enum_list) { + return enum_list; +} + +ErrorOr TestPlugin::EchoNonNullClassList( + const EncodableList& class_list) { + return class_list; +} + ErrorOr TestPlugin::EchoMap(const EncodableMap& a_map) { return a_map; } +ErrorOr TestPlugin::EchoStringMap( + const EncodableMap& string_map) { + return string_map; +} + +ErrorOr TestPlugin::EchoIntMap(const EncodableMap& int_map) { + return int_map; +} + +ErrorOr TestPlugin::EchoEnumMap(const EncodableMap& enum_map) { + return enum_map; +} + +ErrorOr TestPlugin::EchoClassMap(const EncodableMap& class_map) { + return class_map; +} + +ErrorOr TestPlugin::EchoNonNullStringMap( + const EncodableMap& string_map) { + return string_map; +} + +ErrorOr TestPlugin::EchoNonNullIntMap( + const EncodableMap& int_map) { + return int_map; +} + +ErrorOr TestPlugin::EchoNonNullEnumMap( + const EncodableMap& enum_map) { + return enum_map; +} + +ErrorOr TestPlugin::EchoNonNullClassMap( + const EncodableMap& class_map) { + return class_map; +} + ErrorOr TestPlugin::EchoClassWrapper( const AllClassesWrapper& wrapper) { return wrapper; @@ -151,6 +209,11 @@ ErrorOr TestPlugin::EchoClassWrapper( ErrorOr TestPlugin::EchoEnum(const AnEnum& an_enum) { return an_enum; } +ErrorOr TestPlugin::EchoAnotherEnum( + const AnotherEnum& another_enum) { + return another_enum; +} + ErrorOr TestPlugin::EchoNamedDefaultString( const std::string& a_string) { return a_string; @@ -181,7 +244,9 @@ ErrorOr TestPlugin::CreateNestedNullableString( } else { inner_object.set_a_nullable_string(nullptr); } - AllClassesWrapper wrapper(inner_object); + EncodableList classList; + EncodableMap classMap; + AllClassesWrapper wrapper(inner_object, classList, classMap); return wrapper; } @@ -276,12 +341,108 @@ ErrorOr> TestPlugin::EchoNullableList( return *a_nullable_list; }; +ErrorOr> TestPlugin::EchoNullableEnumList( + const EncodableList* enum_list) { + if (!enum_list) { + return std::nullopt; + } + return *enum_list; +}; + +ErrorOr> TestPlugin::EchoNullableClassList( + const EncodableList* class_list) { + if (!class_list) { + return std::nullopt; + } + return *class_list; +}; + +ErrorOr> TestPlugin::EchoNullableNonNullEnumList( + const EncodableList* enum_list) { + if (!enum_list) { + return std::nullopt; + } + return *enum_list; +}; + +ErrorOr> TestPlugin::EchoNullableNonNullClassList( + const EncodableList* class_list) { + if (!class_list) { + return std::nullopt; + } + return *class_list; +}; + ErrorOr> TestPlugin::EchoNullableMap( - const EncodableMap* a_nullable_map) { - if (!a_nullable_map) { + const EncodableMap* map) { + if (!map) { + return std::nullopt; + } + return *map; +}; + +ErrorOr> TestPlugin::EchoNullableStringMap( + const EncodableMap* string_map) { + if (!string_map) { + return std::nullopt; + } + return *string_map; +}; + +ErrorOr> TestPlugin::EchoNullableIntMap( + const EncodableMap* int_map) { + if (!int_map) { + return std::nullopt; + } + return *int_map; +}; + +ErrorOr> TestPlugin::EchoNullableEnumMap( + const EncodableMap* enum_map) { + if (!enum_map) { + return std::nullopt; + } + return *enum_map; +}; + +ErrorOr> TestPlugin::EchoNullableClassMap( + const EncodableMap* class_map) { + if (!class_map) { + return std::nullopt; + } + return *class_map; +}; + +ErrorOr> TestPlugin::EchoNullableNonNullStringMap( + const EncodableMap* string_map) { + if (!string_map) { + return std::nullopt; + } + return *string_map; +}; + +ErrorOr> TestPlugin::EchoNullableNonNullIntMap( + const EncodableMap* int_map) { + if (!int_map) { + return std::nullopt; + } + return *int_map; +}; + +ErrorOr> TestPlugin::EchoNullableNonNullEnumMap( + const EncodableMap* enum_map) { + if (!enum_map) { + return std::nullopt; + } + return *enum_map; +}; + +ErrorOr> TestPlugin::EchoNullableNonNullClassMap( + const EncodableMap* class_map) { + if (!class_map) { return std::nullopt; } - return *a_nullable_map; + return *class_map; }; ErrorOr> TestPlugin::EchoNullableEnum( @@ -292,6 +453,14 @@ ErrorOr> TestPlugin::EchoNullableEnum( return *an_enum; } +ErrorOr> TestPlugin::EchoAnotherNullableEnum( + const AnotherEnum* another_enum) { + if (!another_enum) { + return std::nullopt; + } + return *another_enum; +} + ErrorOr> TestPlugin::EchoOptionalNullableInt( const int64_t* a_nullable_int) { if (!a_nullable_int) { @@ -372,10 +541,46 @@ void TestPlugin::EchoAsyncList( result(a_list); } +void TestPlugin::EchoAsyncEnumList( + const EncodableList& enum_list, + std::function reply)> result) { + result(enum_list); +} + +void TestPlugin::EchoAsyncClassList( + const EncodableList& class_list, + std::function reply)> result) { + result(class_list); +} + void TestPlugin::EchoAsyncMap( - const EncodableMap& a_map, + const EncodableMap& map, + std::function reply)> result) { + result(map); +} + +void TestPlugin::EchoAsyncStringMap( + const EncodableMap& string_map, + std::function reply)> result) { + result(string_map); +} + +void TestPlugin::EchoAsyncIntMap( + const EncodableMap& int_map, std::function reply)> result) { - result(a_map); + result(int_map); +} + +void TestPlugin::EchoAsyncEnumMap( + const EncodableMap& enum_map, + std::function reply)> result) { + result(enum_map); +} + +void TestPlugin::EchoAsyncClassMap( + const EncodableMap& class_map, + std::function reply)> result) { + result(class_map); } void TestPlugin::EchoAsyncEnum( @@ -383,6 +588,12 @@ void TestPlugin::EchoAsyncEnum( result(an_enum); } +void TestPlugin::EchoAnotherAsyncEnum( + const AnotherEnum& another_enum, + std::function reply)> result) { + result(another_enum); +} + void TestPlugin::EchoAsyncNullableAllNullableTypes( const AllNullableTypes* everything, std::function> reply)> @@ -445,10 +656,46 @@ void TestPlugin::EchoAsyncNullableList( result(a_list ? std::optional(*a_list) : std::nullopt); } +void TestPlugin::EchoAsyncNullableEnumList( + const EncodableList* enum_list, + std::function> reply)> result) { + result(enum_list ? std::optional(*enum_list) : std::nullopt); +} + +void TestPlugin::EchoAsyncNullableClassList( + const EncodableList* class_list, + std::function> reply)> result) { + result(class_list ? std::optional(*class_list) : std::nullopt); +} + void TestPlugin::EchoAsyncNullableMap( - const EncodableMap* a_map, + const EncodableMap* map, + std::function> reply)> result) { + result(map ? std::optional(*map) : std::nullopt); +} + +void TestPlugin::EchoAsyncNullableStringMap( + const EncodableMap* string_map, + std::function> reply)> result) { + result(string_map ? std::optional(*string_map) : std::nullopt); +} + +void TestPlugin::EchoAsyncNullableIntMap( + const EncodableMap* int_map, + std::function> reply)> result) { + result(int_map ? std::optional(*int_map) : std::nullopt); +} + +void TestPlugin::EchoAsyncNullableEnumMap( + const EncodableMap* enum_map, + std::function> reply)> result) { + result(enum_map ? std::optional(*enum_map) : std::nullopt); +} + +void TestPlugin::EchoAsyncNullableClassMap( + const EncodableMap* class_map, std::function> reply)> result) { - result(a_map ? std::optional(*a_map) : std::nullopt); + result(class_map ? std::optional(*class_map) : std::nullopt); } void TestPlugin::EchoAsyncNullableEnum( @@ -457,6 +704,13 @@ void TestPlugin::EchoAsyncNullableEnum( result(an_enum ? std::optional(*an_enum) : std::nullopt); } +void TestPlugin::EchoAnotherAsyncNullableEnum( + const AnotherEnum* another_enum, + std::function> reply)> result) { + result(another_enum ? std::optional(*another_enum) + : std::nullopt); +} + void TestPlugin::CallFlutterNoop( std::function reply)> result) { flutter_api_->Noop([result]() { result(std::nullopt); }, @@ -580,11 +834,107 @@ void TestPlugin::CallFlutterEchoList( [result](const FlutterError& error) { result(error); }); } +void TestPlugin::CallFlutterEchoEnumList( + const EncodableList& enum_list, + std::function reply)> result) { + flutter_api_->EchoEnumList( + enum_list, [result](const EncodableList& echo) { result(echo); }, + [result](const FlutterError& error) { result(error); }); +} + +void TestPlugin::CallFlutterEchoClassList( + const EncodableList& class_list, + std::function reply)> result) { + flutter_api_->EchoClassList( + class_list, [result](const EncodableList& echo) { result(echo); }, + [result](const FlutterError& error) { result(error); }); +} + +void TestPlugin::CallFlutterEchoNonNullEnumList( + const EncodableList& enum_list, + std::function reply)> result) { + flutter_api_->EchoNonNullEnumList( + enum_list, [result](const EncodableList& echo) { result(echo); }, + [result](const FlutterError& error) { result(error); }); +} + +void TestPlugin::CallFlutterEchoNonNullClassList( + const EncodableList& class_list, + std::function reply)> result) { + flutter_api_->EchoNonNullClassList( + class_list, [result](const EncodableList& echo) { result(echo); }, + [result](const FlutterError& error) { result(error); }); +} + void TestPlugin::CallFlutterEchoMap( - const EncodableMap& a_map, + const EncodableMap& map, std::function reply)> result) { flutter_api_->EchoMap( - a_map, [result](const EncodableMap& echo) { result(echo); }, + map, [result](const EncodableMap& echo) { result(echo); }, + [result](const FlutterError& error) { result(error); }); +} + +void TestPlugin::CallFlutterEchoStringMap( + const EncodableMap& string_map, + std::function reply)> result) { + flutter_api_->EchoStringMap( + string_map, [result](const EncodableMap& echo) { result(echo); }, + [result](const FlutterError& error) { result(error); }); +} + +void TestPlugin::CallFlutterEchoIntMap( + const EncodableMap& int_map, + std::function reply)> result) { + flutter_api_->EchoIntMap( + int_map, [result](const EncodableMap& echo) { result(echo); }, + [result](const FlutterError& error) { result(error); }); +} + +void TestPlugin::CallFlutterEchoEnumMap( + const EncodableMap& enum_map, + std::function reply)> result) { + flutter_api_->EchoEnumMap( + enum_map, [result](const EncodableMap& echo) { result(echo); }, + [result](const FlutterError& error) { result(error); }); +} + +void TestPlugin::CallFlutterEchoClassMap( + const EncodableMap& class_map, + std::function reply)> result) { + flutter_api_->EchoClassMap( + class_map, [result](const EncodableMap& echo) { result(echo); }, + [result](const FlutterError& error) { result(error); }); +} + +void TestPlugin::CallFlutterEchoNonNullStringMap( + const EncodableMap& string_map, + std::function reply)> result) { + flutter_api_->EchoNonNullStringMap( + string_map, [result](const EncodableMap& echo) { result(echo); }, + [result](const FlutterError& error) { result(error); }); +} + +void TestPlugin::CallFlutterEchoNonNullIntMap( + const EncodableMap& int_map, + std::function reply)> result) { + flutter_api_->EchoNonNullIntMap( + int_map, [result](const EncodableMap& echo) { result(echo); }, + [result](const FlutterError& error) { result(error); }); +} + +void TestPlugin::CallFlutterEchoNonNullEnumMap( + const EncodableMap& enum_map, + std::function reply)> result) { + flutter_api_->EchoNonNullEnumMap( + enum_map, [result](const EncodableMap& echo) { result(echo); }, + [result](const FlutterError& error) { result(error); }); +} + +void TestPlugin::CallFlutterEchoNonNullClassMap( + const EncodableMap& class_map, + std::function reply)> result) { + flutter_api_->EchoNonNullClassMap( + class_map, [result](const EncodableMap& echo) { result(echo); }, [result](const FlutterError& error) { result(error); }); } @@ -595,6 +945,14 @@ void TestPlugin::CallFlutterEchoEnum( [result](const FlutterError& error) { result(error); }); } +void TestPlugin::CallFlutterEchoAnotherEnum( + const AnotherEnum& another_enum, + std::function reply)> result) { + flutter_api_->EchoAnotherEnum( + another_enum, [result](const AnotherEnum& echo) { result(echo); }, + [result](const FlutterError& error) { result(error); }); +} + void TestPlugin::CallFlutterEchoNullableBool( const bool* a_bool, std::function> reply)> result) { @@ -663,11 +1021,143 @@ void TestPlugin::CallFlutterEchoNullableList( [result](const FlutterError& error) { result(error); }); } +void TestPlugin::CallFlutterEchoNullableEnumList( + const EncodableList* enum_list, + std::function> reply)> result) { + flutter_api_->EchoNullableEnumList( + enum_list, + [result](const EncodableList* echo) { + result(echo ? std::optional(*echo) : std::nullopt); + }, + [result](const FlutterError& error) { result(error); }); +} + +void TestPlugin::CallFlutterEchoNullableClassList( + const EncodableList* class_list, + std::function> reply)> result) { + flutter_api_->EchoNullableClassList( + class_list, + [result](const EncodableList* echo) { + result(echo ? std::optional(*echo) : std::nullopt); + }, + [result](const FlutterError& error) { result(error); }); +} + +void TestPlugin::CallFlutterEchoNullableNonNullEnumList( + const EncodableList* enum_list, + std::function> reply)> result) { + flutter_api_->EchoNullableNonNullEnumList( + enum_list, + [result](const EncodableList* echo) { + result(echo ? std::optional(*echo) : std::nullopt); + }, + [result](const FlutterError& error) { result(error); }); +} + +void TestPlugin::CallFlutterEchoNullableNonNullClassList( + const EncodableList* class_list, + std::function> reply)> result) { + flutter_api_->EchoNullableNonNullClassList( + class_list, + [result](const EncodableList* echo) { + result(echo ? std::optional(*echo) : std::nullopt); + }, + [result](const FlutterError& error) { result(error); }); +} + void TestPlugin::CallFlutterEchoNullableMap( - const EncodableMap* a_map, + const EncodableMap* map, std::function> reply)> result) { flutter_api_->EchoNullableMap( - a_map, + map, + [result](const EncodableMap* echo) { + result(echo ? std::optional(*echo) : std::nullopt); + }, + [result](const FlutterError& error) { result(error); }); +} + +void TestPlugin::CallFlutterEchoNullableStringMap( + const EncodableMap* string_map, + std::function> reply)> result) { + flutter_api_->EchoNullableStringMap( + string_map, + [result](const EncodableMap* echo) { + result(echo ? std::optional(*echo) : std::nullopt); + }, + [result](const FlutterError& error) { result(error); }); +} + +void TestPlugin::CallFlutterEchoNullableIntMap( + const EncodableMap* int_map, + std::function> reply)> result) { + flutter_api_->EchoNullableIntMap( + int_map, + [result](const EncodableMap* echo) { + result(echo ? std::optional(*echo) : std::nullopt); + }, + [result](const FlutterError& error) { result(error); }); +} + +void TestPlugin::CallFlutterEchoNullableEnumMap( + const EncodableMap* enum_map, + std::function> reply)> result) { + flutter_api_->EchoNullableEnumMap( + enum_map, + [result](const EncodableMap* echo) { + result(echo ? std::optional(*echo) : std::nullopt); + }, + [result](const FlutterError& error) { result(error); }); +} + +void TestPlugin::CallFlutterEchoNullableClassMap( + const EncodableMap* class_map, + std::function> reply)> result) { + flutter_api_->EchoNullableClassMap( + class_map, + [result](const EncodableMap* echo) { + result(echo ? std::optional(*echo) : std::nullopt); + }, + [result](const FlutterError& error) { result(error); }); +} + +void TestPlugin::CallFlutterEchoNullableNonNullStringMap( + const EncodableMap* string_map, + std::function> reply)> result) { + flutter_api_->EchoNullableNonNullStringMap( + string_map, + [result](const EncodableMap* echo) { + result(echo ? std::optional(*echo) : std::nullopt); + }, + [result](const FlutterError& error) { result(error); }); +} + +void TestPlugin::CallFlutterEchoNullableNonNullIntMap( + const EncodableMap* int_map, + std::function> reply)> result) { + flutter_api_->EchoNullableNonNullIntMap( + int_map, + [result](const EncodableMap* echo) { + result(echo ? std::optional(*echo) : std::nullopt); + }, + [result](const FlutterError& error) { result(error); }); +} + +void TestPlugin::CallFlutterEchoNullableNonNullEnumMap( + const EncodableMap* enum_map, + std::function> reply)> result) { + flutter_api_->EchoNullableNonNullEnumMap( + enum_map, + [result](const EncodableMap* echo) { + result(echo ? std::optional(*echo) : std::nullopt); + }, + [result](const FlutterError& error) { result(error); }); +} + +void TestPlugin::CallFlutterEchoNullableNonNullClassMap( + const EncodableMap* class_map, + std::function> reply)> result) { + flutter_api_->EchoNullableNonNullClassMap( + class_map, [result](const EncodableMap* echo) { result(echo ? std::optional(*echo) : std::nullopt); }, @@ -685,6 +1175,17 @@ void TestPlugin::CallFlutterEchoNullableEnum( [result](const FlutterError& error) { result(error); }); } +void TestPlugin::CallFlutterEchoAnotherNullableEnum( + const AnotherEnum* another_enum, + std::function> reply)> result) { + flutter_api_->EchoAnotherNullableEnum( + another_enum, + [result](const AnotherEnum* echo) { + result(echo ? std::optional(*echo) : std::nullopt); + }, + [result](const FlutterError& error) { result(error); }); +} + void TestPlugin::CallFlutterSmallApiEchoString( const std::string& a_string, std::function reply)> result) { @@ -709,4 +1210,8 @@ void TestPlugin::CallFlutterSmallApiEchoString( [result](const FlutterError& error) { result(error); }); } +core_tests_pigeontest::UnusedClass TestPlugin::TestUnusedClassGenerates() { + return core_tests_pigeontest::UnusedClass(); +} + } // namespace test_plugin diff --git a/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.h b/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.h index 0123df09022b..cabbe665ed58 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.h +++ b/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.h @@ -81,13 +81,40 @@ class TestPlugin : public flutter::Plugin, const flutter::EncodableValue& an_object) override; core_tests_pigeontest::ErrorOr EchoList( const flutter::EncodableList& a_list) override; + core_tests_pigeontest::ErrorOr EchoEnumList( + const flutter::EncodableList& enum_list) override; + core_tests_pigeontest::ErrorOr EchoClassList( + const flutter::EncodableList& class_list) override; + core_tests_pigeontest::ErrorOr EchoNonNullEnumList( + const flutter::EncodableList& enum_list) override; + core_tests_pigeontest::ErrorOr EchoNonNullClassList( + const flutter::EncodableList& class_list) override; core_tests_pigeontest::ErrorOr EchoMap( - const flutter::EncodableMap& a_map) override; + const flutter::EncodableMap& map) override; + core_tests_pigeontest::ErrorOr EchoStringMap( + const flutter::EncodableMap& string_map) override; + core_tests_pigeontest::ErrorOr EchoIntMap( + const flutter::EncodableMap& int_map) override; + core_tests_pigeontest::ErrorOr EchoEnumMap( + const flutter::EncodableMap& enum_map) override; + core_tests_pigeontest::ErrorOr EchoClassMap( + const flutter::EncodableMap& class_map) override; + core_tests_pigeontest::ErrorOr EchoNonNullStringMap( + const flutter::EncodableMap& string_map) override; + core_tests_pigeontest::ErrorOr EchoNonNullIntMap( + const flutter::EncodableMap& int_map) override; + core_tests_pigeontest::ErrorOr EchoNonNullEnumMap( + const flutter::EncodableMap& enum_map) override; + core_tests_pigeontest::ErrorOr EchoNonNullClassMap( + const flutter::EncodableMap& class_map) override; core_tests_pigeontest::ErrorOr EchoClassWrapper( const core_tests_pigeontest::AllClassesWrapper& wrapper) override; core_tests_pigeontest::ErrorOr EchoEnum( const core_tests_pigeontest::AnEnum& an_enum) override; + core_tests_pigeontest::ErrorOr + EchoAnotherEnum( + const core_tests_pigeontest::AnotherEnum& another_enum) override; core_tests_pigeontest::ErrorOr EchoNamedDefaultString( const std::string& a_string) override; core_tests_pigeontest::ErrorOr EchoOptionalDefaultDouble( @@ -123,10 +150,40 @@ class TestPlugin : public flutter::Plugin, EchoNullableObject(const flutter::EncodableValue* a_nullable_object) override; core_tests_pigeontest::ErrorOr> EchoNullableList(const flutter::EncodableList* a_nullable_list) override; + core_tests_pigeontest::ErrorOr> + EchoNullableEnumList(const flutter::EncodableList* enum_list) override; + core_tests_pigeontest::ErrorOr> + EchoNullableClassList(const flutter::EncodableList* class_list) override; + core_tests_pigeontest::ErrorOr> + EchoNullableNonNullEnumList(const flutter::EncodableList* enum_list) override; + core_tests_pigeontest::ErrorOr> + EchoNullableNonNullClassList( + const flutter::EncodableList* class_list) override; + core_tests_pigeontest::ErrorOr> + EchoNullableMap(const flutter::EncodableMap* map) override; + core_tests_pigeontest::ErrorOr> + EchoNullableStringMap(const flutter::EncodableMap* string_map) override; + core_tests_pigeontest::ErrorOr> + EchoNullableIntMap(const flutter::EncodableMap* int_map) override; + core_tests_pigeontest::ErrorOr> + EchoNullableEnumMap(const flutter::EncodableMap* enum_map) override; + core_tests_pigeontest::ErrorOr> + EchoNullableClassMap(const flutter::EncodableMap* class_map) override; + core_tests_pigeontest::ErrorOr> + EchoNullableNonNullStringMap( + const flutter::EncodableMap* string_map) override; core_tests_pigeontest::ErrorOr> - EchoNullableMap(const flutter::EncodableMap* a_nullable_map) override; + EchoNullableNonNullIntMap(const flutter::EncodableMap* int_map) override; + core_tests_pigeontest::ErrorOr> + EchoNullableNonNullEnumMap(const flutter::EncodableMap* enum_map) override; + core_tests_pigeontest::ErrorOr> + EchoNullableNonNullClassMap(const flutter::EncodableMap* class_map) override; core_tests_pigeontest::ErrorOr> EchoNullableEnum(const core_tests_pigeontest::AnEnum* an_enum) override; + core_tests_pigeontest::ErrorOr< + std::optional> + EchoAnotherNullableEnum( + const core_tests_pigeontest::AnotherEnum* another_enum) override; core_tests_pigeontest::ErrorOr> EchoOptionalNullableInt(const int64_t* a_nullable_int) override; core_tests_pigeontest::ErrorOr> @@ -198,8 +255,38 @@ class TestPlugin : public flutter::Plugin, std::function< void(core_tests_pigeontest::ErrorOr reply)> result) override; + void EchoAsyncEnumList( + const flutter::EncodableList& enum_list, + std::function< + void(core_tests_pigeontest::ErrorOr reply)> + result) override; + void EchoAsyncClassList( + const flutter::EncodableList& class_list, + std::function< + void(core_tests_pigeontest::ErrorOr reply)> + result) override; void EchoAsyncMap( - const flutter::EncodableMap& a_map, + const flutter::EncodableMap& map, + std::function< + void(core_tests_pigeontest::ErrorOr reply)> + result) override; + void EchoAsyncStringMap( + const flutter::EncodableMap& string_map, + std::function< + void(core_tests_pigeontest::ErrorOr reply)> + result) override; + void EchoAsyncIntMap( + const flutter::EncodableMap& int_map, + std::function< + void(core_tests_pigeontest::ErrorOr reply)> + result) override; + void EchoAsyncEnumMap( + const flutter::EncodableMap& enum_map, + std::function< + void(core_tests_pigeontest::ErrorOr reply)> + result) override; + void EchoAsyncClassMap( + const flutter::EncodableMap& class_map, std::function< void(core_tests_pigeontest::ErrorOr reply)> result) override; @@ -208,6 +295,12 @@ class TestPlugin : public flutter::Plugin, std::function reply)> result) override; + void EchoAnotherAsyncEnum( + const core_tests_pigeontest::AnotherEnum& another_enum, + std::function + reply)> + result) override; void EchoAsyncNullableInt( const int64_t* an_int, std::function< @@ -246,8 +339,44 @@ class TestPlugin : public flutter::Plugin, core_tests_pigeontest::ErrorOr> reply)> result) override; + void EchoAsyncNullableEnumList( + const flutter::EncodableList* enum_list, + std::function> + reply)> + result) override; + void EchoAsyncNullableClassList( + const flutter::EncodableList* class_list, + std::function> + reply)> + result) override; void EchoAsyncNullableMap( - const flutter::EncodableMap* a_map, + const flutter::EncodableMap* map, + std::function> + reply)> + result) override; + void EchoAsyncNullableStringMap( + const flutter::EncodableMap* string_map, + std::function> + reply)> + result) override; + void EchoAsyncNullableIntMap( + const flutter::EncodableMap* int_map, + std::function> + reply)> + result) override; + void EchoAsyncNullableEnumMap( + const flutter::EncodableMap* enum_map, + std::function> + reply)> + result) override; + void EchoAsyncNullableClassMap( + const flutter::EncodableMap* class_map, std::function> reply)> @@ -258,6 +387,12 @@ class TestPlugin : public flutter::Plugin, std::optional> reply)> result) override; + void EchoAnotherAsyncNullableEnum( + const core_tests_pigeontest::AnotherEnum* another_enum, + std::function> + reply)> + result) override; void CallFlutterNoop( std::function< void(std::optional reply)> @@ -331,8 +466,68 @@ class TestPlugin : public flutter::Plugin, std::function< void(core_tests_pigeontest::ErrorOr reply)> result) override; + void CallFlutterEchoEnumList( + const flutter::EncodableList& enum_list, + std::function< + void(core_tests_pigeontest::ErrorOr reply)> + result) override; + void CallFlutterEchoClassList( + const flutter::EncodableList& class_list, + std::function< + void(core_tests_pigeontest::ErrorOr reply)> + result) override; + void CallFlutterEchoNonNullEnumList( + const flutter::EncodableList& enum_list, + std::function< + void(core_tests_pigeontest::ErrorOr reply)> + result) override; + void CallFlutterEchoNonNullClassList( + const flutter::EncodableList& class_list, + std::function< + void(core_tests_pigeontest::ErrorOr reply)> + result) override; void CallFlutterEchoMap( - const flutter::EncodableMap& a_map, + const flutter::EncodableMap& map, + std::function< + void(core_tests_pigeontest::ErrorOr reply)> + result) override; + void CallFlutterEchoStringMap( + const flutter::EncodableMap& string_map, + std::function< + void(core_tests_pigeontest::ErrorOr reply)> + result) override; + void CallFlutterEchoIntMap( + const flutter::EncodableMap& int_map, + std::function< + void(core_tests_pigeontest::ErrorOr reply)> + result) override; + void CallFlutterEchoEnumMap( + const flutter::EncodableMap& enum_map, + std::function< + void(core_tests_pigeontest::ErrorOr reply)> + result) override; + void CallFlutterEchoClassMap( + const flutter::EncodableMap& class_map, + std::function< + void(core_tests_pigeontest::ErrorOr reply)> + result) override; + void CallFlutterEchoNonNullStringMap( + const flutter::EncodableMap& string_map, + std::function< + void(core_tests_pigeontest::ErrorOr reply)> + result) override; + void CallFlutterEchoNonNullIntMap( + const flutter::EncodableMap& int_map, + std::function< + void(core_tests_pigeontest::ErrorOr reply)> + result) override; + void CallFlutterEchoNonNullEnumMap( + const flutter::EncodableMap& enum_map, + std::function< + void(core_tests_pigeontest::ErrorOr reply)> + result) override; + void CallFlutterEchoNonNullClassMap( + const flutter::EncodableMap& class_map, std::function< void(core_tests_pigeontest::ErrorOr reply)> result) override; @@ -341,6 +536,12 @@ class TestPlugin : public flutter::Plugin, std::function reply)> result) override; + void CallFlutterEchoAnotherEnum( + const core_tests_pigeontest::AnotherEnum& another_enum, + std::function + reply)> + result) override; void CallFlutterEchoNullableBool( const bool* a_bool, std::function< @@ -373,8 +574,80 @@ class TestPlugin : public flutter::Plugin, core_tests_pigeontest::ErrorOr> reply)> result) override; + void CallFlutterEchoNullableEnumList( + const flutter::EncodableList* enum_list, + std::function> + reply)> + result) override; + void CallFlutterEchoNullableClassList( + const flutter::EncodableList* class_list, + std::function> + reply)> + result) override; + void CallFlutterEchoNullableNonNullEnumList( + const flutter::EncodableList* enum_list, + std::function> + reply)> + result) override; + void CallFlutterEchoNullableNonNullClassList( + const flutter::EncodableList* class_list, + std::function> + reply)> + result) override; void CallFlutterEchoNullableMap( - const flutter::EncodableMap* a_map, + const flutter::EncodableMap* map, + std::function> + reply)> + result) override; + void CallFlutterEchoNullableStringMap( + const flutter::EncodableMap* string_map, + std::function> + reply)> + result) override; + void CallFlutterEchoNullableIntMap( + const flutter::EncodableMap* int_map, + std::function> + reply)> + result) override; + void CallFlutterEchoNullableEnumMap( + const flutter::EncodableMap* enum_map, + std::function> + reply)> + result) override; + void CallFlutterEchoNullableClassMap( + const flutter::EncodableMap* class_map, + std::function> + reply)> + result) override; + void CallFlutterEchoNullableNonNullStringMap( + const flutter::EncodableMap* string_map, + std::function> + reply)> + result) override; + void CallFlutterEchoNullableNonNullIntMap( + const flutter::EncodableMap* int_map, + std::function> + reply)> + result) override; + void CallFlutterEchoNullableNonNullEnumMap( + const flutter::EncodableMap* enum_map, + std::function> + reply)> + result) override; + void CallFlutterEchoNullableNonNullClassMap( + const flutter::EncodableMap* class_map, std::function> reply)> @@ -385,10 +658,17 @@ class TestPlugin : public flutter::Plugin, std::optional> reply)> result) override; + void CallFlutterEchoAnotherNullableEnum( + const core_tests_pigeontest::AnotherEnum* another_enum, + std::function> + reply)> + result) override; void CallFlutterSmallApiEchoString( const std::string& a_string, std::function reply)> result) override; + core_tests_pigeontest::UnusedClass TestUnusedClassGenerates(); private: std::unique_ptr diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index 413804a0691e..cddaae515813 100644 --- a/packages/pigeon/pubspec.yaml +++ b/packages/pigeon/pubspec.yaml @@ -2,10 +2,10 @@ name: pigeon description: Code generator tool to make communication between Flutter and the host platform type-safe and easier. repository: https://github.com/flutter/packages/tree/main/packages/pigeon issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+pigeon%22 -version: 20.0.1 # This must match the version in lib/generator_tools.dart +version: 22.6.0 # This must match the version in lib/generator_tools.dart environment: - sdk: ^3.2.0 + sdk: ^3.3.0 dependencies: analyzer: ">=5.13.0 <7.0.0" @@ -13,8 +13,10 @@ dependencies: code_builder: ^4.10.0 collection: ^1.15.0 dart_style: ^2.3.4 + graphs: ^2.3.1 meta: ^1.9.0 path: ^1.8.0 + pub_semver: ^2.1.4 yaml: ^3.1.1 dev_dependencies: diff --git a/packages/pigeon/test/cpp_generator_test.dart b/packages/pigeon/test/cpp_generator_test.dart index 80ffc0702243..65a8f7ed8fdf 100644 --- a/packages/pigeon/test/cpp_generator_test.dart +++ b/packages/pigeon/test/cpp_generator_test.dart @@ -101,6 +101,10 @@ void main() { }); test('naming follows style', () { + final Enum anEnum = Enum(name: 'AnEnum', members: [ + EnumMember(name: 'one'), + EnumMember(name: 'fortyTwo'), + ]); final Root root = Root(apis: [ AstHostApi(name: 'Api', methods: [ Method( @@ -137,9 +141,19 @@ void main() { baseName: 'bool', isNullable: false, ), - name: 'outputField') + name: 'outputField'), + NamedType( + type: TypeDeclaration( + baseName: anEnum.name, + isNullable: false, + associatedEnum: anEnum, + ), + name: 'code', + ) ]) - ], enums: []); + ], enums: [ + anEnum + ]); { final StringBuffer sink = StringBuffer(); const CppGenerator generator = CppGenerator(); @@ -161,6 +175,9 @@ void main() { // Instance variables should be adjusted. expect(code, contains('bool input_field_')); expect(code, contains('bool output_field_')); + // Enum values should be adjusted. + expect(code, contains('kOne')); + expect(code, contains('kFortyTwo')); } { final StringBuffer sink = StringBuffer(); @@ -1180,16 +1197,14 @@ void main() { code, contains( 'const auto* a_map_arg = std::get_if(&encodable_a_map_arg);')); - // Ints are complicated since there are two possible pointer types, but - // the parameter always needs an int64_t*. expect( code, contains( - 'const int64_t an_int_arg_value = encodable_an_int_arg.IsNull() ? 0 : encodable_an_int_arg.LongValue();')); + 'const auto* a_bool_arg = std::get_if(&encodable_a_bool_arg);')); expect( code, contains( - 'const auto* an_int_arg = encodable_an_int_arg.IsNull() ? nullptr : &an_int_arg_value;')); + 'const auto* an_int_arg = std::get_if(&encodable_an_int_arg);')); // Custom class types require an extra layer of extraction. expect( code, diff --git a/packages/pigeon/test/dart/proxy_api_test.dart b/packages/pigeon/test/dart/proxy_api_test.dart index a8b3a5a9eb0c..fd1d887189e3 100644 --- a/packages/pigeon/test/dart/proxy_api_test.dart +++ b/packages/pigeon/test/dart/proxy_api_test.dart @@ -81,17 +81,18 @@ void main() { // Instance Manager expect(code, contains(r'class PigeonInstanceManager')); - expect(code, contains(r'class _PigeonInstanceManagerApi')); + expect(code, contains(r'class _PigeonInternalInstanceManagerApi')); // Base Api class expect( code, - contains(r'abstract class PigeonProxyApiBaseClass'), + contains(r'abstract class PigeonInternalProxyApiBaseClass'), ); // Codec and class - expect(code, contains('class _PigeonProxyApiBaseCodec')); - expect(code, contains(r'class Api extends PigeonProxyApiBaseClass')); + expect(code, contains('class _PigeonInternalProxyApiBaseCodec')); + expect( + code, contains(r'class Api extends PigeonInternalProxyApiBaseClass')); // Constructors expect( @@ -146,7 +147,7 @@ void main() { final String code = sink.toString(); final String collapsedCode = _collapseNewlineAndIndentation(code); - expect(code, contains(r'class _PigeonInstanceManagerApi')); + expect(code, contains(r'class _PigeonInternalInstanceManagerApi')); expect( code, @@ -157,7 +158,7 @@ void main() { expect( code, contains( - 'dev.flutter.pigeon.$DEFAULT_PACKAGE_NAME.PigeonInstanceManagerApi.removeStrongReference', + 'dev.flutter.pigeon.$DEFAULT_PACKAGE_NAME.PigeonInternalInstanceManager.removeStrongReference', ), ); expect( @@ -171,7 +172,7 @@ void main() { expect( code, contains( - 'dev.flutter.pigeon.$DEFAULT_PACKAGE_NAME.PigeonInstanceManagerApi.clear', + 'dev.flutter.pigeon.$DEFAULT_PACKAGE_NAME.PigeonInternalInstanceManager.clear', ), ); }); @@ -252,7 +253,7 @@ void main() { expect( code, contains( - r'class Api extends PigeonProxyApiBaseClass implements Api2', + r'class Api extends PigeonInternalProxyApiBaseClass implements Api2', ), ); }); @@ -304,7 +305,7 @@ void main() { expect( code, contains( - r'class Api extends PigeonProxyApiBaseClass implements Api2, Api3', + r'class Api extends PigeonInternalProxyApiBaseClass implements Api2, Api3', ), ); }); @@ -359,7 +360,7 @@ void main() { expect( code, contains( - r'class Api extends PigeonProxyApiBaseClass implements Api2', + r'class Api extends PigeonInternalProxyApiBaseClass implements Api2', ), ); expect( @@ -409,13 +410,13 @@ void main() { expect( collapsedCode, contains( - r"const String __pigeon_channelName = 'dev.flutter.pigeon.test_package.Api.pigeon_defaultConstructor';", + r"const String pigeonVar_channelName = 'dev.flutter.pigeon.test_package.Api.pigeon_defaultConstructor';", ), ); expect( collapsedCode, contains( - r'__pigeon_channel .send([__pigeon_instanceIdentifier])', + r'pigeonVar_channel .send([pigeonVar_instanceIdentifier])', ), ); }); @@ -515,8 +516,8 @@ void main() { expect( collapsedCode, contains( - r'__pigeon_channel.send([ ' - r'__pigeon_instanceIdentifier, ' + r'pigeonVar_channel.send([ ' + r'pigeonVar_instanceIdentifier, ' r'validType, enumType, proxyApiType, ' r'nullableValidType, nullableEnumType, nullableProxyApiType ])', ), @@ -625,8 +626,8 @@ void main() { expect( collapsedCode, contains( - r'__pigeon_channel.send([ ' - r'__pigeon_instanceIdentifier, ' + r'pigeonVar_channel.send([ ' + r'pigeonVar_instanceIdentifier, ' r'validType, enumType, proxyApiType, ' r'nullableValidType, nullableEnumType, nullableProxyApiType ])', ), @@ -697,8 +698,8 @@ void main() { ); final String code = sink.toString(); expect(code, contains('class Api')); - expect(code, contains(r'late final Api2 aField = __pigeon_aField();')); - expect(code, contains(r'Api2 __pigeon_aField()')); + expect(code, contains(r'late final Api2 aField = pigeonVar_aField();')); + expect(code, contains(r'Api2 pigeonVar_aField()')); }); test('static attached field', () { @@ -743,8 +744,8 @@ void main() { final String code = sink.toString(); expect(code, contains('class Api')); expect( - code, contains(r'static final Api2 aField = __pigeon_aField();')); - expect(code, contains(r'static Api2 __pigeon_aField()')); + code, contains(r'static final Api2 aField = pigeonVar_aField();')); + expect(code, contains(r'static Api2 pigeonVar_aField()')); }); }); @@ -846,7 +847,7 @@ void main() { expect( collapsedCode, contains( - r'await __pigeon_channel.send([ this, validType, ' + r'await pigeonVar_channel.send([ this, validType, ' r'enumType, proxyApiType, nullableValidType, ' r'nullableEnumType, nullableProxyApiType ])', ), @@ -894,7 +895,7 @@ void main() { ); expect( collapsedCode, - contains(r'await __pigeon_channel.send(null)'), + contains(r'await pigeonVar_channel.send(null)'), ); }); }); diff --git a/packages/pigeon/test/dart_generator_test.dart b/packages/pigeon/test/dart_generator_test.dart index 944c6e334cef..4dca4b416844 100644 --- a/packages/pigeon/test/dart_generator_test.dart +++ b/packages/pigeon/test/dart_generator_test.dart @@ -167,7 +167,7 @@ void main() { final String code = sink.toString(); expect(code, contains('class Api')); expect(code, contains('Future add(int x, int y)')); - expect(code, contains('await __pigeon_channel.send([x, y])')); + expect(code, contains('await pigeonVar_channel.send([x, y])')); }); test('flutter multiple args', () { @@ -573,7 +573,7 @@ void main() { final String code = sink.toString(); expect(code, contains('enum Foo {')); expect(code, contains('Future bar(Foo? foo) async')); - expect(code, contains('__pigeon_channel.send([foo])')); + expect(code, contains('pigeonVar_channel.send([foo])')); }); test('flutter non-nullable enum argument with enum class', () { @@ -664,7 +664,7 @@ void main() { dartPackageName: DEFAULT_PACKAGE_NAME, ); final String code = sink.toString(); - expect(code, matches('__pigeon_channel.send[(]null[)]')); + expect(code, matches('pigeonVar_channel.send[(]null[)]')); }); test('mock dart handler', () { @@ -953,7 +953,7 @@ void main() { dartPackageName: DEFAULT_PACKAGE_NAME, ); final String code = sink.toString(); - expect(code, matches('__pigeon_channel.send[(]null[)]')); + expect(code, matches('pigeonVar_channel.send[(]null[)]')); }); Iterable makeIterable(String string) sync* { @@ -1142,7 +1142,7 @@ void main() { expect( code, contains( - 'return (__pigeon_replyList[0] as List?)!.cast();')); + 'return (pigeonVar_replyList[0] as List?)!.cast();')); }); test('flutter generics argument non void return', () { @@ -1217,7 +1217,7 @@ void main() { ); final String code = sink.toString(); expect(code, contains('Future doit()')); - expect(code, contains('return (__pigeon_replyList[0] as int?);')); + expect(code, contains('return (pigeonVar_replyList[0] as int?);')); }); test('return nullable collection host', () { @@ -1252,7 +1252,7 @@ void main() { expect( code, contains( - 'return (__pigeon_replyList[0] as List?)?.cast();')); + 'return (pigeonVar_replyList[0] as List?)?.cast();')); }); test('return nullable async host', () { @@ -1283,7 +1283,7 @@ void main() { ); final String code = sink.toString(); expect(code, contains('Future doit()')); - expect(code, contains('return (__pigeon_replyList[0] as int?);')); + expect(code, contains('return (pigeonVar_replyList[0] as int?);')); }); test('return nullable flutter', () { @@ -1732,7 +1732,7 @@ name: foobar ); final String code = sink.toString(); expect( - code, contains('throw _createConnectionError(__pigeon_channelName);')); + code, contains('throw _createConnectionError(pigeonVar_channelName);')); expect( code, contains( @@ -1771,4 +1771,35 @@ name: foobar final String mainCode = mainCodeSink.toString(); expect(mainCode, contains('List wrapResponse(')); }); + + test('writes custom int codec without custom types', () { + final Root root = Root( + apis: [ + AstHostApi(name: 'Api', methods: [ + Method( + name: 'doit', + location: ApiLocation.host, + returnType: const TypeDeclaration( + baseName: 'int', + isNullable: true, + ), + parameters: []) + ]) + ], + classes: [], + enums: [], + ); + final StringBuffer sink = StringBuffer(); + const DartGenerator generator = DartGenerator(); + generator.generate( + const DartOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + expect(code, contains('if (value is int) {')); + expect(code, contains('buffer.putUint8(4);')); + expect(code, contains('buffer.putInt64(value);')); + }); } diff --git a/packages/pigeon/test/generator_tools_test.dart b/packages/pigeon/test/generator_tools_test.dart index d7c49e37154f..2ed9239b0a25 100644 --- a/packages/pigeon/test/generator_tools_test.dart +++ b/packages/pigeon/test/generator_tools_test.dart @@ -387,4 +387,81 @@ void main() { expect(() => a.apisOfInterfaces(), throwsArgumentError); }); + + test('findHighestApiRequirement', () { + final TypeDeclaration typeWithoutMinApi = TypeDeclaration( + baseName: 'TypeWithoutMinApi', + isNullable: false, + associatedProxyApi: AstProxyApi( + name: 'TypeWithoutMinApi', + methods: [], + constructors: [], + fields: [], + ), + ); + + final TypeDeclaration typeWithMinApi = TypeDeclaration( + baseName: 'TypeWithMinApi', + isNullable: false, + associatedProxyApi: AstProxyApi( + name: 'TypeWithMinApi', + methods: [], + constructors: [], + fields: [], + ), + ); + + final TypeDeclaration typeWithHighestMinApi = TypeDeclaration( + baseName: 'TypeWithHighestMinApi', + isNullable: false, + associatedProxyApi: AstProxyApi( + name: 'TypeWithHighestMinApi', + methods: [], + constructors: [], + fields: [], + ), + ); + + final ({TypeDeclaration type, int version})? result = + findHighestApiRequirement( + [ + typeWithoutMinApi, + typeWithMinApi, + typeWithHighestMinApi, + ], + onGetApiRequirement: (TypeDeclaration type) { + if (type == typeWithMinApi) { + return 1; + } else if (type == typeWithHighestMinApi) { + return 2; + } + + return null; + }, + onCompare: (int one, int two) => one.compareTo(two), + ); + + expect(result?.type, typeWithHighestMinApi); + expect(result?.version, 2); + }); + + test('Indent.format trims indentation', () { + final StringBuffer buffer = StringBuffer(); + final Indent indent = Indent(buffer); + + indent.format( + ''' + void myMethod() { + + print('hello'); + }''', + ); + + expect(buffer.toString(), ''' +void myMethod() { + + print('hello'); +} +'''); + }); } diff --git a/packages/pigeon/test/gobject_generator_test.dart b/packages/pigeon/test/gobject_generator_test.dart new file mode 100644 index 000000000000..935e9b98c804 --- /dev/null +++ b/packages/pigeon/test/gobject_generator_test.dart @@ -0,0 +1,774 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:pigeon/ast.dart'; +import 'package:pigeon/generator_tools.dart'; +import 'package:pigeon/gobject_generator.dart'; +import 'package:test/test.dart'; + +const String DEFAULT_PACKAGE_NAME = 'test_package'; + +void main() { + test('gen one api', () { + final Class inputClass = Class(name: 'Input', fields: [ + NamedType( + type: const TypeDeclaration( + baseName: 'String', + isNullable: true, + ), + name: 'input') + ]); + final Class outputClass = Class(name: 'Output', fields: [ + NamedType( + type: const TypeDeclaration( + baseName: 'String', + isNullable: true, + ), + name: 'output') + ]); + final Root root = Root(apis: [ + AstHostApi(name: 'Api', methods: [ + Method( + name: 'doSomething', + parameters: [ + Parameter( + type: TypeDeclaration( + baseName: 'Input', + isNullable: false, + associatedClass: inputClass, + ), + name: 'input') + ], + location: ApiLocation.host, + returnType: TypeDeclaration( + baseName: 'Output', + isNullable: false, + associatedClass: outputClass, + ), + ) + ]) + ], classes: [ + inputClass, + outputClass + ], enums: []); + { + final StringBuffer sink = StringBuffer(); + const GObjectGenerator generator = GObjectGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const GObjectOptions(), + ); + generator.generate(generatorOptions, root, sink, + dartPackageName: DEFAULT_PACKAGE_NAME); + final String code = sink.toString(); + expect( + code, + contains( + 'G_DECLARE_FINAL_TYPE(TestPackageInput, test_package_input, TEST_PACKAGE, INPUT, GObject)')); + expect( + code, + contains( + 'G_DECLARE_FINAL_TYPE(TestPackageOutput, test_package_output, TEST_PACKAGE, OUTPUT, GObject)')); + } + { + final StringBuffer sink = StringBuffer(); + const GObjectGenerator generator = GObjectGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const GObjectOptions(), + ); + generator.generate(generatorOptions, root, sink, + dartPackageName: DEFAULT_PACKAGE_NAME); + final String code = sink.toString(); + expect( + code, + contains( + 'static void test_package_input_init(TestPackageInput* self) {')); + expect( + code, + contains( + 'static void test_package_output_init(TestPackageOutput* self) {')); + expect( + code, + contains( + 'static void test_package_api_init(TestPackageApi* self) {')); + } + }); + + test('naming follows style', () { + final Class inputClass = Class(name: 'Input', fields: [ + NamedType( + type: const TypeDeclaration( + baseName: 'bool', + isNullable: false, + ), + name: 'inputField') + ]); + final Class outputClass = Class(name: 'Output', fields: [ + NamedType( + type: const TypeDeclaration( + baseName: 'bool', + isNullable: false, + ), + name: 'outputField') + ]); + final Root root = Root(apis: [ + AstHostApi(name: 'Api', methods: [ + Method( + name: 'doSomething', + parameters: [ + Parameter( + type: TypeDeclaration( + baseName: 'Input', + isNullable: false, + associatedClass: inputClass, + ), + name: 'someInput') + ], + location: ApiLocation.host, + returnType: TypeDeclaration( + baseName: 'Output', + isNullable: false, + associatedClass: outputClass, + ), + ) + ]) + ], classes: [ + inputClass, + outputClass + ], enums: []); + { + final StringBuffer sink = StringBuffer(); + const GObjectGenerator generator = GObjectGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const GObjectOptions(), + ); + generator.generate(generatorOptions, root, sink, + dartPackageName: DEFAULT_PACKAGE_NAME); + final String code = sink.toString(); + expect( + code, + contains( + ' TestPackageApiDoSomethingResponse* (*do_something)(TestPackageInput* some_input, gpointer user_data);')); + expect( + code, + contains( + 'gboolean test_package_input_get_input_field(TestPackageInput* object);')); + expect( + code, + contains( + 'gboolean test_package_output_get_output_field(TestPackageOutput* object);')); + } + { + final StringBuffer sink = StringBuffer(); + const GObjectGenerator generator = GObjectGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const GObjectOptions(), + ); + generator.generate(generatorOptions, root, sink, + dartPackageName: DEFAULT_PACKAGE_NAME); + final String code = sink.toString(); + expect( + code, + contains( + 'gboolean test_package_input_get_input_field(TestPackageInput* self) {')); + expect( + code, + contains( + 'gboolean test_package_output_get_output_field(TestPackageOutput* self) {')); + } + }); + + test('Spaces before {', () { + final Class inputClass = Class(name: 'Input', fields: [ + NamedType( + type: const TypeDeclaration( + baseName: 'String', + isNullable: true, + ), + name: 'input') + ]); + final Class outputClass = Class(name: 'Output', fields: [ + NamedType( + type: const TypeDeclaration( + baseName: 'String', + isNullable: true, + ), + name: 'output') + ]); + final Root root = Root(apis: [ + AstHostApi(name: 'Api', methods: [ + Method( + name: 'doSomething', + location: ApiLocation.host, + parameters: [ + Parameter( + type: TypeDeclaration( + baseName: 'Input', + isNullable: false, + associatedClass: inputClass, + ), + name: 'input') + ], + returnType: TypeDeclaration( + baseName: 'Output', + isNullable: false, + associatedClass: outputClass, + ), + ) + ]) + ], classes: [ + inputClass, + outputClass + ], enums: []); + { + final StringBuffer sink = StringBuffer(); + const GObjectGenerator generator = GObjectGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const GObjectOptions(), + ); + generator.generate( + generatorOptions, + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + expect(code, isNot(contains('){'))); + expect(code, isNot(contains('const{'))); + } + { + final StringBuffer sink = StringBuffer(); + const GObjectGenerator generator = GObjectGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const GObjectOptions(), + ); + generator.generate( + generatorOptions, + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + expect(code, isNot(contains('){'))); + expect(code, isNot(contains('const{'))); + } + }); + + test('include blocks follow style', () { + final Root root = Root(apis: [ + AstHostApi(name: 'Api', methods: [ + Method( + name: 'doSomething', + location: ApiLocation.host, + parameters: [ + Parameter( + type: const TypeDeclaration( + baseName: 'String', + isNullable: true, + ), + name: 'input') + ], + returnType: const TypeDeclaration(baseName: 'int', isNullable: false), + ) + ]) + ], classes: [], enums: []); + { + final StringBuffer sink = StringBuffer(); + const GObjectGenerator generator = GObjectGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const GObjectOptions(), + ); + generator.generate( + generatorOptions, + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + expect(code, contains(''' +#include +''')); + } + { + final StringBuffer sink = StringBuffer(); + const GObjectGenerator generator = GObjectGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const GObjectOptions(headerIncludePath: 'a_header.h'), + ); + generator.generate( + generatorOptions, + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + expect(code, contains(''' +#include "a_header.h" +''')); + } + }); + + test('data classes handle non-nullable fields', () { + final Class nestedClass = Class(name: 'Nested', fields: [ + NamedType( + type: const TypeDeclaration( + baseName: 'bool', + isNullable: false, + ), + name: 'nestedValue'), + ]); + final Class inputClass = Class(name: 'Input', fields: [ + NamedType( + type: const TypeDeclaration( + baseName: 'bool', + isNullable: false, + ), + name: 'nonNullableBool'), + NamedType( + type: const TypeDeclaration( + baseName: 'int', + isNullable: false, + ), + name: 'nonNullableInt'), + NamedType( + type: const TypeDeclaration( + baseName: 'String', + isNullable: false, + ), + name: 'nonNullableString'), + NamedType( + type: TypeDeclaration( + baseName: 'Nested', + isNullable: false, + associatedClass: nestedClass, + ), + name: 'nonNullableNested'), + ]); + final Root root = Root(apis: [ + AstHostApi(name: 'Api', methods: [ + Method( + name: 'doSomething', + location: ApiLocation.host, + parameters: [ + Parameter( + type: TypeDeclaration( + baseName: 'Input', + isNullable: false, + associatedClass: inputClass, + ), + name: 'someInput') + ], + returnType: const TypeDeclaration.voidDeclaration(), + ) + ]) + ], classes: [ + nestedClass, + inputClass + ], enums: []); + { + final StringBuffer sink = StringBuffer(); + const GObjectGenerator generator = GObjectGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const GObjectOptions(), + ); + generator.generate( + generatorOptions, + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + + expect( + code, + contains( + 'TestPackageNested* test_package_nested_new(gboolean nested_value);')); + } + { + final StringBuffer sink = StringBuffer(); + const GObjectGenerator generator = GObjectGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const GObjectOptions(), + ); + generator.generate( + generatorOptions, + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + + expect( + code, + contains( + 'TestPackageNested* test_package_nested_new(gboolean nested_value) {')); + } + }); + + test('host non-nullable return types map correctly', () { + final Class returnDataClass = Class(name: 'ReturnData', fields: [ + NamedType( + type: const TypeDeclaration( + baseName: 'bool', + isNullable: false, + ), + name: 'aValue'), + ]); + final Root root = Root(apis: [ + AstHostApi(name: 'Api', methods: [ + Method( + name: 'returnBool', + location: ApiLocation.host, + parameters: [], + returnType: const TypeDeclaration( + baseName: 'bool', + isNullable: false, + ), + ), + Method( + name: 'returnInt', + location: ApiLocation.host, + parameters: [], + returnType: const TypeDeclaration( + baseName: 'int', + isNullable: false, + ), + ), + Method( + name: 'returnString', + location: ApiLocation.host, + parameters: [], + returnType: const TypeDeclaration( + baseName: 'String', + isNullable: false, + ), + ), + Method( + name: 'returnList', + location: ApiLocation.host, + parameters: [], + returnType: const TypeDeclaration( + baseName: 'List', + typeArguments: [ + TypeDeclaration( + baseName: 'String', + isNullable: true, + ) + ], + isNullable: false, + ), + ), + Method( + name: 'returnMap', + location: ApiLocation.host, + parameters: [], + returnType: const TypeDeclaration( + baseName: 'Map', + typeArguments: [ + TypeDeclaration( + baseName: 'String', + isNullable: true, + ), + TypeDeclaration( + baseName: 'String', + isNullable: true, + ) + ], + isNullable: false, + ), + ), + Method( + name: 'returnDataClass', + location: ApiLocation.host, + parameters: [], + returnType: TypeDeclaration( + baseName: 'ReturnData', + isNullable: false, + associatedClass: returnDataClass, + ), + ), + ]) + ], classes: [ + returnDataClass + ], enums: []); + { + final StringBuffer sink = StringBuffer(); + const GObjectGenerator generator = GObjectGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const GObjectOptions(), + ); + generator.generate( + generatorOptions, + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + expect( + code, + contains( + ' TestPackageApiReturnBoolResponse* (*return_bool)(gpointer user_data);')); + expect( + code, + contains( + ' TestPackageApiReturnIntResponse* (*return_int)(gpointer user_data);')); + expect( + code, + contains( + ' TestPackageApiReturnStringResponse* (*return_string)(gpointer user_data);')); + expect( + code, + contains( + ' TestPackageApiReturnListResponse* (*return_list)(gpointer user_data);')); + expect( + code, + contains( + ' TestPackageApiReturnMapResponse* (*return_map)(gpointer user_data);')); + expect( + code, + contains( + ' TestPackageApiReturnDataClassResponse* (*return_data_class)(gpointer user_data);')); + } + }); + + test('host non-nullable arguments map correctly', () { + final Class parameterObjectClass = + Class(name: 'ParameterObject', fields: [ + NamedType( + type: const TypeDeclaration( + baseName: 'bool', + isNullable: false, + ), + name: 'aValue'), + ]); + final Class objectClass = Class(name: 'Object', fields: []); + final Root root = Root(apis: [ + AstHostApi(name: 'Api', methods: [ + Method( + name: 'doSomething', + location: ApiLocation.host, + parameters: [ + Parameter( + name: 'aBool', + type: const TypeDeclaration( + baseName: 'bool', + isNullable: false, + )), + Parameter( + name: 'anInt', + type: const TypeDeclaration( + baseName: 'int', + isNullable: false, + )), + Parameter( + name: 'aString', + type: const TypeDeclaration( + baseName: 'String', + isNullable: false, + )), + Parameter( + name: 'aList', + type: TypeDeclaration( + baseName: 'List', + typeArguments: [ + TypeDeclaration( + baseName: 'Object', + isNullable: true, + associatedClass: objectClass, + ) + ], + isNullable: false, + )), + Parameter( + name: 'aMap', + type: TypeDeclaration( + baseName: 'Map', + typeArguments: [ + const TypeDeclaration(baseName: 'String', isNullable: true), + TypeDeclaration( + baseName: 'Object', + isNullable: true, + associatedClass: objectClass, + ), + ], + isNullable: false, + )), + Parameter( + name: 'anObject', + type: TypeDeclaration( + baseName: 'ParameterObject', + isNullable: false, + associatedClass: parameterObjectClass, + )), + Parameter( + name: 'aGenericObject', + type: TypeDeclaration( + baseName: 'Object', + isNullable: false, + associatedClass: objectClass, + )), + ], + returnType: const TypeDeclaration.voidDeclaration(), + ), + ]) + ], classes: [ + parameterObjectClass, + objectClass + ], enums: []); + { + final StringBuffer sink = StringBuffer(); + const GObjectGenerator generator = GObjectGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const GObjectOptions(), + ); + generator.generate( + generatorOptions, + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + expect( + code, + contains( + ' TestPackageApiDoSomethingResponse* (*do_something)(gboolean a_bool, int64_t an_int, const gchar* a_string, FlValue* a_list, FlValue* a_map, TestPackageParameterObject* an_object, TestPackageObject* a_generic_object, gpointer user_data);')); + } + { + final StringBuffer sink = StringBuffer(); + const GObjectGenerator generator = GObjectGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const GObjectOptions(), + ); + generator.generate( + generatorOptions, + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + expect( + code, + contains( + ' g_autoptr(TestPackageApiDoSomethingResponse) response = self->vtable->do_something(a_bool, an_int, a_string, a_list, a_map, an_object, a_generic_object, self->user_data);')); + } + }); + + test('transfers documentation comments', () { + final List comments = [ + ' api comment', + ' api method comment', + ' class comment', + ' class field comment', + ' enum comment', + ' enum member comment', + ]; + int count = 0; + + final List unspacedComments = ['////////']; + int unspacedCount = 0; + + final Root root = Root( + apis: [ + AstFlutterApi( + name: 'Api', + documentationComments: [comments[count++]], + methods: [ + Method( + name: 'method', + location: ApiLocation.flutter, + returnType: const TypeDeclaration.voidDeclaration(), + documentationComments: [comments[count++]], + parameters: [ + Parameter( + name: 'field', + type: const TypeDeclaration( + baseName: 'int', + isNullable: true, + ), + ), + ], + ) + ], + ) + ], + classes: [ + Class( + name: 'class', + documentationComments: [comments[count++]], + fields: [ + NamedType( + documentationComments: [comments[count++]], + type: const TypeDeclaration( + baseName: 'Map', + isNullable: true, + typeArguments: [ + TypeDeclaration(baseName: 'String', isNullable: true), + TypeDeclaration(baseName: 'int', isNullable: true), + ]), + name: 'field1'), + ], + ), + ], + enums: [ + Enum( + name: 'enum', + documentationComments: [ + comments[count++], + unspacedComments[unspacedCount++] + ], + members: [ + EnumMember( + name: 'one', + documentationComments: [comments[count++]], + ), + EnumMember(name: 'two'), + ], + ), + ], + ); + final StringBuffer sink = StringBuffer(); + const GObjectGenerator generator = GObjectGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const GObjectOptions(headerIncludePath: 'foo'), + ); + generator.generate( + generatorOptions, + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + for (final String comment in comments) { + expect(code, contains(' *$comment')); + } + expect(code, contains(' * ///')); + }); +} diff --git a/packages/pigeon/test/java_generator_test.dart b/packages/pigeon/test/java_generator_test.dart index 3982c25150ba..63a6e8330eab 100644 --- a/packages/pigeon/test/java_generator_test.dart +++ b/packages/pigeon/test/java_generator_test.dart @@ -85,7 +85,7 @@ void main() { expect(code, contains(' TWO_THREE_FOUR(1),')); expect(code, contains(' REMOTE_DB(2);')); expect(code, contains('final int index;')); - expect(code, contains('private Foobar(final int index) {')); + expect(code, contains('Foobar(final int index) {')); expect(code, contains(' this.index = index;')); }); @@ -118,7 +118,6 @@ void main() { ); final String code = sink.toString(); expect(code, contains('package com.google.foobar;')); - expect(code, contains('ArrayList toList()')); }); test('gen one host api', () { @@ -187,7 +186,6 @@ void main() { contains(RegExp( r'@NonNull\s*protected static ArrayList wrapError\(@NonNull Throwable exception\)'))); expect(code, isNot(contains('ArrayList '))); - expect(code, isNot(contains('ArrayList<>'))); }); test('all the simple datatypes header', () { @@ -736,7 +734,7 @@ void main() { expect(code, contains(' TWO_THREE_FOUR(1),')); expect(code, contains(' REMOTE_DB(2);')); expect(code, contains('final int index;')); - expect(code, contains('private Enum1(final int index) {')); + expect(code, contains('Enum1(final int index) {')); expect(code, contains(' this.index = index;')); expect(code, contains('toListResult.add(enum1);')); @@ -778,8 +776,10 @@ void main() { ); final String code = sink.toString(); expect(code, contains('public enum Foo')); - expect(code, - contains('return value == null ? null : Foo.values()[(int) value];')); + expect( + code, + contains( + 'return value == null ? null : Foo.values()[((Long) value).intValue()];')); expect( code, contains( @@ -1042,10 +1042,7 @@ void main() { ); final String code = sink.toString(); expect(code, contains('public void doit(@NonNull Result result)')); - expect( - code, - contains( - 'Long output = listReply.get(0) == null ? null : ((Number) listReply.get(0)).longValue();')); + expect(code, contains('Long output = (Long) listReply.get(0);')); }); test('host multiple args', () { @@ -1082,12 +1079,9 @@ void main() { expect(code, contains('Long add(@NonNull Long x, @NonNull Long y)')); expect(code, contains('ArrayList args = (ArrayList) message;')); - expect(code, contains('Number xArg = (Number) args.get(0)')); - expect(code, contains('Number yArg = (Number) args.get(1)')); - expect( - code, - contains( - 'Long output = api.add((xArg == null) ? null : xArg.longValue(), (yArg == null) ? null : yArg.longValue())')); + expect(code, contains('Long xArg = (Long) args.get(0)')); + expect(code, contains('Long yArg = (Long) args.get(1)')); + expect(code, contains('Long output = api.add(xArg, yArg)')); }); test('if host argType is Object not cast', () { @@ -1159,7 +1153,7 @@ void main() { expect( code, contains(RegExp( - r'channel.send\(\s*new ArrayList\(Arrays.asList\(xArg, yArg\)\),\s*channelReply ->'))); + r'channel.send\(\s*new ArrayList<>\(Arrays.asList\(xArg, yArg\)\),\s*channelReply ->'))); }); test('flutter single args', () { @@ -1191,7 +1185,7 @@ void main() { expect( code, contains(RegExp( - r'channel.send\(\s*new ArrayList\(Collections.singletonList\(xArg\)\),\s*channelReply ->'))); + r'channel.send\(\s*new ArrayList<>\(Collections.singletonList\(xArg\)\),\s*channelReply ->'))); }); test('return nullable host', () { diff --git a/packages/pigeon/test/kotlin/proxy_api_test.dart b/packages/pigeon/test/kotlin/proxy_api_test.dart new file mode 100644 index 000000000000..d6ddd35377bf --- /dev/null +++ b/packages/pigeon/test/kotlin/proxy_api_test.dart @@ -0,0 +1,944 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:pigeon/ast.dart'; +import 'package:pigeon/kotlin_generator.dart'; +import 'package:test/test.dart'; + +const String DEFAULT_PACKAGE_NAME = 'test_package'; + +void main() { + group('ProxyApi', () { + test('one api', () { + final Root root = Root( + apis: [ + AstProxyApi( + name: 'Api', + kotlinOptions: const KotlinProxyApiOptions( + fullClassName: 'my.library.Api', + ), + constructors: [ + Constructor( + name: 'name', + parameters: [ + Parameter( + type: const TypeDeclaration( + baseName: 'Input', + isNullable: false, + ), + name: 'input', + ), + ], + ), + ], + fields: [ + ApiField( + name: 'someField', + type: const TypeDeclaration( + baseName: 'int', + isNullable: false, + ), + ) + ], + methods: [ + Method( + name: 'doSomething', + location: ApiLocation.host, + parameters: [ + Parameter( + type: const TypeDeclaration( + baseName: 'Input', + isNullable: false, + ), + name: 'input', + ) + ], + returnType: const TypeDeclaration( + baseName: 'String', + isNullable: false, + ), + ), + Method( + name: 'doSomethingElse', + location: ApiLocation.flutter, + isRequired: false, + parameters: [ + Parameter( + type: const TypeDeclaration( + baseName: 'Input', + isNullable: false, + ), + name: 'input', + ), + ], + returnType: const TypeDeclaration( + baseName: 'String', + isNullable: false, + ), + ), + ], + ) + ], + classes: [], + enums: [], + ); + final StringBuffer sink = StringBuffer(); + const KotlinGenerator generator = KotlinGenerator(); + generator.generate( + const KotlinOptions(fileSpecificClassNameComponent: 'MyFile'), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + final String collapsedCode = _collapseNewlineAndIndentation(code); + + // Instance Manager + expect(code, contains(r'class MyFilePigeonInstanceManager')); + expect(code, contains(r'class MyFilePigeonInstanceManagerApi')); + + // API registrar + expect( + code, + contains( + 'abstract class MyFilePigeonProxyApiRegistrar(val binaryMessenger: BinaryMessenger)', + ), + ); + + // Codec + expect( + code, + contains( + 'private class MyFilePigeonProxyApiBaseCodec(val registrar: MyFilePigeonProxyApiRegistrar) : MyFilePigeonCodec()')); + + // Proxy API class + expect( + code, + contains( + r'abstract class PigeonApiApi(open val pigeonRegistrar: MyFilePigeonProxyApiRegistrar)', + ), + ); + + // Constructors + expect( + collapsedCode, + contains( + r'abstract fun name(someField: Long, input: Input)', + ), + ); + expect( + collapsedCode, + contains( + r'fun pigeon_newInstance(pigeon_instanceArg: my.library.Api, callback: (Result) -> Unit)', + ), + ); + + // Field + expect( + code, + contains( + 'abstract fun someField(pigeon_instance: my.library.Api): Long', + ), + ); + + // Dart -> Host method + expect( + collapsedCode, + contains('api.doSomething(pigeon_instanceArg, inputArg)'), + ); + + // Host -> Dart method + expect( + code, + contains( + r'fun setUpMessageHandlers(binaryMessenger: BinaryMessenger, api: PigeonApiApi?)', + ), + ); + expect( + code, + contains( + 'fun doSomethingElse(pigeon_instanceArg: my.library.Api, inputArg: Input, callback: (Result) -> Unit)', + ), + ); + }); + + group('inheritance', () { + test('extends', () { + final AstProxyApi api2 = AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [], + ); + final Root root = Root(apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [], + methods: [], + superClass: TypeDeclaration( + baseName: api2.name, + isNullable: false, + associatedProxyApi: api2, + ), + ), + api2, + ], classes: [], enums: []); + final StringBuffer sink = StringBuffer(); + const KotlinGenerator generator = KotlinGenerator(); + generator.generate( + const KotlinOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + final String collapsedCode = _collapseNewlineAndIndentation(code); + expect( + collapsedCode, + contains('fun pigeon_getPigeonApiApi2(): PigeonApiApi2'), + ); + }); + + test('implements', () { + final AstProxyApi api2 = AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [], + ); + final Root root = Root(apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [], + methods: [], + interfaces: { + TypeDeclaration( + baseName: api2.name, + isNullable: false, + associatedProxyApi: api2, + ) + }, + ), + api2, + ], classes: [], enums: []); + final StringBuffer sink = StringBuffer(); + const KotlinGenerator generator = KotlinGenerator(); + generator.generate( + const KotlinOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + expect(code, contains('fun pigeon_getPigeonApiApi2(): PigeonApiApi2')); + }); + + test('implements 2 ProxyApis', () { + final AstProxyApi api2 = AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [], + ); + final AstProxyApi api3 = AstProxyApi( + name: 'Api3', + constructors: [], + fields: [], + methods: [], + ); + final Root root = Root(apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [], + methods: [], + interfaces: { + TypeDeclaration( + baseName: api2.name, + isNullable: false, + associatedProxyApi: api2, + ), + TypeDeclaration( + baseName: api3.name, + isNullable: false, + associatedProxyApi: api3, + ), + }, + ), + api2, + api3, + ], classes: [], enums: []); + final StringBuffer sink = StringBuffer(); + const KotlinGenerator generator = KotlinGenerator(); + generator.generate( + const KotlinOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + expect(code, contains('fun pigeon_getPigeonApiApi2(): PigeonApiApi2')); + expect(code, contains('fun pigeon_getPigeonApiApi3(): PigeonApiApi3')); + }); + }); + + group('Constructors', () { + test('empty name and no params constructor', () { + final Root root = Root( + apis: [ + AstProxyApi(name: 'Api', constructors: [ + Constructor( + name: '', + parameters: [], + ) + ], fields: [], methods: []), + ], + classes: [], + enums: [], + ); + final StringBuffer sink = StringBuffer(); + const KotlinGenerator generator = KotlinGenerator(); + generator.generate( + const KotlinOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + final String collapsedCode = _collapseNewlineAndIndentation(code); + expect( + code, + contains( + 'abstract class PigeonApiApi(open val pigeonRegistrar: PigeonProxyApiRegistrar) ', + ), + ); + expect( + collapsedCode, + contains('abstract fun pigeon_defaultConstructor(): Api'), + ); + expect( + collapsedCode, + contains( + r'val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.test_package.Api.pigeon_defaultConstructor"', + ), + ); + expect( + collapsedCode, + contains( + r'api.pigeonRegistrar.instanceManager.addDartCreatedInstance(api.pigeon_defaultConstructor(', + ), + ); + }); + + test('multiple params constructor', () { + final Enum anEnum = Enum( + name: 'AnEnum', + members: [EnumMember(name: 'one')], + ); + final Root root = Root( + apis: [ + AstProxyApi(name: 'Api', constructors: [ + Constructor( + name: 'name', + parameters: [ + Parameter( + type: const TypeDeclaration( + isNullable: false, + baseName: 'int', + ), + name: 'validType', + ), + Parameter( + type: TypeDeclaration( + isNullable: false, + baseName: 'AnEnum', + associatedEnum: anEnum, + ), + name: 'enumType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: false, + baseName: 'Api2', + ), + name: 'proxyApiType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: true, + baseName: 'int', + ), + name: 'nullableValidType', + ), + Parameter( + type: TypeDeclaration( + isNullable: true, + baseName: 'AnEnum', + associatedEnum: anEnum, + ), + name: 'nullableEnumType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: true, + baseName: 'Api2', + ), + name: 'nullableProxyApiType', + ), + ], + ) + ], fields: [], methods: []), + AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [], + ), + ], + classes: [], + enums: [anEnum], + ); + final StringBuffer sink = StringBuffer(); + const KotlinGenerator generator = KotlinGenerator(); + generator.generate( + const KotlinOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + final String collapsedCode = _collapseNewlineAndIndentation(code); + expect( + code, + contains( + 'abstract class PigeonApiApi(open val pigeonRegistrar: PigeonProxyApiRegistrar) ', + ), + ); + expect( + collapsedCode, + contains( + 'abstract fun name(validType: Long, enumType: AnEnum, ' + 'proxyApiType: Api2, nullableValidType: Long?, ' + 'nullableEnumType: AnEnum?, nullableProxyApiType: Api2?): Api', + ), + ); + expect( + collapsedCode, + contains( + r'api.pigeonRegistrar.instanceManager.addDartCreatedInstance(api.name(' + r'validTypeArg,enumTypeArg,proxyApiTypeArg,nullableValidTypeArg,' + r'nullableEnumTypeArg,nullableProxyApiTypeArg), pigeon_identifierArg)', + ), + ); + }); + }); + + group('Fields', () { + test('constructor with fields', () { + final Enum anEnum = Enum( + name: 'AnEnum', + members: [EnumMember(name: 'one')], + ); + final Root root = Root( + apis: [ + AstProxyApi( + name: 'Api', + constructors: [ + Constructor( + name: 'name', + parameters: [], + ) + ], + fields: [ + ApiField( + type: const TypeDeclaration( + isNullable: false, + baseName: 'int', + ), + name: 'validType', + ), + ApiField( + type: TypeDeclaration( + isNullable: false, + baseName: 'AnEnum', + associatedEnum: anEnum, + ), + name: 'enumType', + ), + ApiField( + type: const TypeDeclaration( + isNullable: false, + baseName: 'Api2', + ), + name: 'proxyApiType', + ), + ApiField( + type: const TypeDeclaration( + isNullable: true, + baseName: 'int', + ), + name: 'nullableValidType', + ), + ApiField( + type: TypeDeclaration( + isNullable: true, + baseName: 'AnEnum', + associatedEnum: anEnum, + ), + name: 'nullableEnumType', + ), + ApiField( + type: const TypeDeclaration( + isNullable: true, + baseName: 'Api2', + ), + name: 'nullableProxyApiType', + ), + ], + methods: [], + ), + AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [], + ), + ], + classes: [], + enums: [anEnum], + ); + final StringBuffer sink = StringBuffer(); + const KotlinGenerator generator = KotlinGenerator(); + generator.generate( + const KotlinOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + final String collapsedCode = _collapseNewlineAndIndentation(code); + expect( + collapsedCode, + contains( + 'abstract fun name(validType: Long, enumType: AnEnum, ' + 'proxyApiType: Api2, nullableValidType: Long?, ' + 'nullableEnumType: AnEnum?, nullableProxyApiType: Api2?): Api', + ), + ); + expect( + collapsedCode, + contains( + r'api.pigeonRegistrar.instanceManager.addDartCreatedInstance(api.name(' + r'validTypeArg,enumTypeArg,proxyApiTypeArg,nullableValidTypeArg,' + r'nullableEnumTypeArg,nullableProxyApiTypeArg), pigeon_identifierArg)', + ), + ); + expect( + collapsedCode, + contains( + 'channel.send(listOf(pigeon_identifierArg, validTypeArg, ' + 'enumTypeArg, proxyApiTypeArg, nullableValidTypeArg, ' + 'nullableEnumTypeArg, nullableProxyApiTypeArg))', + ), + ); + expect( + code, + contains(r'abstract fun validType(pigeon_instance: Api): Long'), + ); + expect( + code, + contains(r'abstract fun enumType(pigeon_instance: Api): AnEnum'), + ); + expect( + code, + contains(r'abstract fun proxyApiType(pigeon_instance: Api): Api2'), + ); + expect( + code, + contains( + r'abstract fun nullableValidType(pigeon_instance: Api): Long?', + ), + ); + expect( + code, + contains( + r'abstract fun nullableEnumType(pigeon_instance: Api): AnEnum?', + ), + ); + expect( + code, + contains( + r'abstract fun nullableProxyApiType(pigeon_instance: Api): Api2?', + ), + ); + }); + + test('attached field', () { + final AstProxyApi api2 = AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [], + ); + final Root root = Root( + apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [ + ApiField( + name: 'aField', + isAttached: true, + type: TypeDeclaration( + baseName: 'Api2', + isNullable: false, + associatedProxyApi: api2, + ), + ), + ], + methods: [], + ), + api2, + ], + classes: [], + enums: [], + ); + final StringBuffer sink = StringBuffer(); + const KotlinGenerator generator = KotlinGenerator(); + generator.generate( + const KotlinOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + expect( + code, + contains(r'abstract fun aField(pigeon_instance: Api): Api2'), + ); + expect( + code, + contains( + r'api.pigeonRegistrar.instanceManager.addDartCreatedInstance(api.aField(pigeon_instanceArg), pigeon_identifierArg)', + ), + ); + }); + + test('static attached field', () { + final AstProxyApi api2 = AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [], + ); + final Root root = Root( + apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [ + ApiField( + name: 'aField', + isStatic: true, + isAttached: true, + type: TypeDeclaration( + baseName: 'Api2', + isNullable: false, + associatedProxyApi: api2, + ), + ), + ], + methods: [], + ), + api2, + ], + classes: [], + enums: [], + ); + final StringBuffer sink = StringBuffer(); + const KotlinGenerator generator = KotlinGenerator(); + generator.generate( + const KotlinOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + expect( + code, + contains(r'abstract fun aField(): Api2'), + ); + expect( + code, + contains( + r'api.pigeonRegistrar.instanceManager.addDartCreatedInstance(api.aField(), pigeon_identifierArg)', + ), + ); + }); + }); + + group('Host methods', () { + test('multiple params method', () { + final Enum anEnum = Enum( + name: 'AnEnum', + members: [EnumMember(name: 'one')], + ); + final Root root = Root( + apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [], + methods: [ + Method( + name: 'doSomething', + location: ApiLocation.host, + parameters: [ + Parameter( + type: const TypeDeclaration( + isNullable: false, + baseName: 'int', + ), + name: 'validType', + ), + Parameter( + type: TypeDeclaration( + isNullable: false, + baseName: 'AnEnum', + associatedEnum: anEnum, + ), + name: 'enumType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: false, + baseName: 'Api2', + ), + name: 'proxyApiType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: true, + baseName: 'int', + ), + name: 'nullableValidType', + ), + Parameter( + type: TypeDeclaration( + isNullable: true, + baseName: 'AnEnum', + associatedEnum: anEnum, + ), + name: 'nullableEnumType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: true, + baseName: 'Api2', + ), + name: 'nullableProxyApiType', + ), + ], + returnType: const TypeDeclaration.voidDeclaration(), + ), + ], + ), + AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [], + ), + ], + classes: [], + enums: [anEnum], + ); + final StringBuffer sink = StringBuffer(); + const KotlinGenerator generator = KotlinGenerator(); + generator.generate( + const KotlinOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + final String collapsedCode = _collapseNewlineAndIndentation(code); + expect( + collapsedCode, + contains( + 'abstract fun doSomething(pigeon_instance: Api, validType: Long, ' + 'enumType: AnEnum, proxyApiType: Api2, nullableValidType: Long?, ' + 'nullableEnumType: AnEnum?, nullableProxyApiType: Api2?)', + ), + ); + expect( + collapsedCode, + contains( + r'api.doSomething(pigeon_instanceArg, validTypeArg, enumTypeArg, ' + r'proxyApiTypeArg, nullableValidTypeArg, nullableEnumTypeArg, ' + r'nullableProxyApiTypeArg)', + ), + ); + }); + + test('static method', () { + final Root root = Root( + apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [], + methods: [ + Method( + name: 'doSomething', + location: ApiLocation.host, + isStatic: true, + parameters: [], + returnType: const TypeDeclaration.voidDeclaration(), + ), + ], + ), + ], + classes: [], + enums: [], + ); + final StringBuffer sink = StringBuffer(); + const KotlinGenerator generator = KotlinGenerator(); + generator.generate( + const KotlinOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + final String collapsedCode = _collapseNewlineAndIndentation(code); + expect(collapsedCode, contains('abstract fun doSomething()')); + expect(collapsedCode, contains(r'api.doSomething()')); + }); + }); + + group('Flutter methods', () { + test('multiple params flutter method', () { + final Enum anEnum = Enum( + name: 'AnEnum', + members: [EnumMember(name: 'one')], + ); + final Root root = Root(apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [], + methods: [ + Method( + name: 'doSomething', + location: ApiLocation.flutter, + parameters: [ + Parameter( + type: const TypeDeclaration( + isNullable: false, + baseName: 'int', + ), + name: 'validType', + ), + Parameter( + type: TypeDeclaration( + isNullable: false, + baseName: 'AnEnum', + associatedEnum: anEnum, + ), + name: 'enumType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: false, + baseName: 'Api2', + ), + name: 'proxyApiType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: true, + baseName: 'int', + ), + name: 'nullableValidType', + ), + Parameter( + type: TypeDeclaration( + isNullable: true, + baseName: 'AnEnum', + associatedEnum: anEnum, + ), + name: 'nullableEnumType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: true, + baseName: 'Api2', + ), + name: 'nullableProxyApiType', + ), + ], + returnType: const TypeDeclaration.voidDeclaration(), + ) + ]) + ], classes: [], enums: [ + anEnum + ]); + final StringBuffer sink = StringBuffer(); + const KotlinGenerator generator = KotlinGenerator(); + generator.generate( + const KotlinOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + final String collapsedCode = _collapseNewlineAndIndentation(code); + expect( + collapsedCode, + contains( + 'fun doSomething(pigeon_instanceArg: Api, validTypeArg: Long, ' + 'enumTypeArg: AnEnum, proxyApiTypeArg: Api2, nullableValidTypeArg: Long?, ' + 'nullableEnumTypeArg: AnEnum?, nullableProxyApiTypeArg: Api2?, ' + 'callback: (Result) -> Unit)', + ), + ); + expect( + collapsedCode, + contains( + r'channel.send(listOf(pigeon_instanceArg, validTypeArg, enumTypeArg, ' + r'proxyApiTypeArg, nullableValidTypeArg, nullableEnumTypeArg, ' + r'nullableProxyApiTypeArg))', + ), + ); + }); + }); + }); +} + +/// Replaces a new line and the indentation with a single white space +/// +/// This +/// +/// ```dart +/// void method( +/// int param1, +/// int param2, +/// ) +/// ``` +/// +/// converts to +/// +/// ```dart +/// void method( int param1, int param2, ) +/// ``` +String _collapseNewlineAndIndentation(String string) { + final StringBuffer result = StringBuffer(); + for (final String line in string.split('\n')) { + result.write('${line.trimLeft()} '); + } + return result.toString().trim(); +} diff --git a/packages/pigeon/test/kotlin_generator_test.dart b/packages/pigeon/test/kotlin_generator_test.dart index ea87f508ca17..549601b8851d 100644 --- a/packages/pigeon/test/kotlin_generator_test.dart +++ b/packages/pigeon/test/kotlin_generator_test.dart @@ -51,7 +51,7 @@ void main() { final String code = sink.toString(); expect(code, contains('data class Foobar (')); expect(code, contains('val field1: Long? = null')); - expect(code, contains('fun fromList(__pigeon_list: List): Foobar')); + expect(code, contains('fun fromList(pigeonVar_list: List): Foobar')); expect(code, contains('fun toList(): List')); }); @@ -132,10 +132,10 @@ void main() { expect(code, contains('data class Bar (')); expect(code, contains('val field1: Foo,')); expect(code, contains('val field2: String')); - expect(code, contains('fun fromList(__pigeon_list: List): Bar')); - expect(code, contains('Foo.ofRaw(it)')); - expect(code, contains('val field1 = __pigeon_list[0] as Foo')); - expect(code, contains('val field2 = __pigeon_list[1] as String\n')); + expect(code, contains('fun fromList(pigeonVar_list: List): Bar')); + expect(code, contains('Foo.ofRaw(it.toInt())')); + expect(code, contains('val field1 = pigeonVar_list[0] as Foo')); + expect(code, contains('val field2 = pigeonVar_list[1] as String\n')); expect(code, contains('fun toList(): List')); }); @@ -173,7 +173,7 @@ void main() { ); final String code = sink.toString(); expect(code, contains('enum class Foo(val raw: Int) {')); - expect(code, contains('Foo.ofRaw(it)')); + expect(code, contains('Foo.ofRaw(it.toInt())')); }); test('gen one host api', () { @@ -391,10 +391,6 @@ void main() { expect(code, contains('val aInt32List: IntArray')); expect(code, contains('val aInt64List: LongArray')); expect(code, contains('val aFloat64List: DoubleArray')); - expect( - code, - contains( - 'val aInt = __pigeon_list[1].let { num -> if (num is Int) num.toLong() else num as Long }')); expect(code, contains('val aNullableBool: Boolean? = null')); expect(code, contains('val aNullableInt: Long? = null')); expect(code, contains('val aNullableDouble: Double? = null')); @@ -403,10 +399,6 @@ void main() { expect(code, contains('val aNullableInt32List: IntArray? = null')); expect(code, contains('val aNullableInt64List: LongArray? = null')); expect(code, contains('val aNullableFloat64List: DoubleArray? = null')); - expect( - code, - contains( - 'val aNullableInt = __pigeon_list[9].let { num -> if (num is Int) num.toLong() else num as Long? }')); }); test('gen one flutter api', () { @@ -736,8 +728,8 @@ void main() { expect(code, contains('data class Outer')); expect(code, contains('data class Nested')); expect(code, contains('val nested: Nested? = null')); - expect(code, contains('fun fromList(__pigeon_list: List): Outer')); - expect(code, contains('val nested = __pigeon_list[0] as Nested?')); + expect(code, contains('fun fromList(pigeonVar_list: List): Outer')); + expect(code, contains('val nested = pigeonVar_list[0] as Nested?')); expect(code, contains('fun toList(): List')); }); @@ -1163,14 +1155,6 @@ void main() { final String code = sink.toString(); expect(code, contains('fun add(x: Long, y: Long): Long')); expect(code, contains('val args = message as List')); - expect( - code, - contains( - 'val xArg = args[0].let { num -> if (num is Int) num.toLong() else num as Long }')); - expect( - code, - contains( - 'val yArg = args[1].let { num -> if (num is Int) num.toLong() else num as Long }')); expect(code, contains('listOf(api.add(xArg, yArg))')); expect(code, contains('reply.reply(wrapped)')); }); @@ -1206,11 +1190,6 @@ void main() { ); final String code = sink.toString(); expect(code, contains('val channel = BasicMessageChannel')); - expect( - code, - contains( - 'val output = it[0].let { num -> if (num is Int) num.toLong() else num as Long }'), - ); expect(code, contains('callback(Result.success(output))')); expect( code, @@ -1311,10 +1290,7 @@ void main() { dartPackageName: DEFAULT_PACKAGE_NAME, ); final String code = sink.toString(); - expect( - code, - contains( - 'val fooArg = args[0].let { num -> if (num is Int) num.toLong() else num as Long? }')); + expect(code, contains('val fooArg = args[0]')); }); test('nullable argument flutter', () { diff --git a/packages/pigeon/test/objc_generator_test.dart b/packages/pigeon/test/objc_generator_test.dart index 84146be42dbb..734145e2c24b 100644 --- a/packages/pigeon/test/objc_generator_test.dart +++ b/packages/pigeon/test/objc_generator_test.dart @@ -248,7 +248,7 @@ void main() { contains( 'return enumAsNumber == nil ? nil : [[ACFooBox alloc] initWithValue:[enumAsNumber integerValue]];')); - expect(code, contains('ACFooBox * box = (ACFooBox *)value;')); + expect(code, contains('ACFooBox *box = (ACFooBox *)value;')); } }); diff --git a/packages/pigeon/test/pigeon_lib_test.dart b/packages/pigeon/test/pigeon_lib_test.dart index 8d56fa9d66f9..9e3fa213fc78 100644 --- a/packages/pigeon/test/pigeon_lib_test.dart +++ b/packages/pigeon/test/pigeon_lib_test.dart @@ -161,6 +161,10 @@ class Output1 { String? output; } +class Unused { + String? field; +} + @HostApi() abstract class Api1 { Output1 doit(Input1 input); @@ -169,7 +173,7 @@ abstract class Api1 { final ParseResults parseResult = parseSource(code); expect(parseResult.errors.length, equals(0)); final Root root = parseResult.root; - expect(root.classes.length, equals(2)); + expect(root.classes.length, equals(3)); expect(root.apis.length, equals(1)); expect(root.apis[0].name, equals('Api1')); expect(root.apis[0].methods.length, equals(1)); @@ -181,15 +185,19 @@ abstract class Api1 { Class? input; Class? output; + Class? unused; for (final Class classDefinition in root.classes) { if (classDefinition.name == 'Input1') { input = classDefinition; } else if (classDefinition.name == 'Output1') { output = classDefinition; + } else if (classDefinition.name == 'Unused') { + unused = classDefinition; } } expect(input, isNotNull); expect(output, isNotNull); + expect(unused, isNotNull); expect(input?.fields.length, equals(1)); expect(input?.fields[0].name, equals('input')); @@ -200,6 +208,11 @@ abstract class Api1 { expect(output?.fields[0].name, equals('output')); expect(output?.fields[0].type.baseName, equals('String')); expect(output?.fields[0].type.isNullable, isTrue); + + expect(unused?.fields.length, equals(1)); + expect(unused?.fields[0].name, equals('field')); + expect(unused?.fields[0].type.baseName, equals('String')); + expect(unused?.fields[0].type.isNullable, isTrue); }); test('invalid datatype', () { @@ -731,25 +744,6 @@ abstract class Api { expect(field.type.typeArguments[0].typeArguments[0].baseName, 'int'); }); - test('error nonnull type argument', () { - const String code = ''' -class Foo { - List list; -} - -@HostApi() -abstract class Api { - void doit(Foo foo); -} -'''; - final ParseResults parseResult = parseSource(code); - expect(parseResult.errors.length, equals(1)); - expect(parseResult.errors[0].message, - contains('Generic type parameters must be nullable')); - expect(parseResult.errors[0].message, contains('"list"')); - expect(parseResult.errors[0].lineNumber, 2); - }); - test('enums argument host', () { const String code = ''' enum Foo { diff --git a/packages/pigeon/test/swift/proxy_api_test.dart b/packages/pigeon/test/swift/proxy_api_test.dart new file mode 100644 index 000000000000..18df858f81e9 --- /dev/null +++ b/packages/pigeon/test/swift/proxy_api_test.dart @@ -0,0 +1,974 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:pigeon/ast.dart'; +import 'package:pigeon/swift_generator.dart'; +import 'package:test/test.dart'; + +const String DEFAULT_PACKAGE_NAME = 'test_package'; + +void main() { + group('ProxyApi', () { + test('one api', () { + final Root root = Root( + apis: [ + AstProxyApi( + name: 'Api', + swiftOptions: const SwiftProxyApiOptions( + name: 'MyLibraryApi', import: 'MyLibrary'), + constructors: [ + Constructor( + name: 'name', + parameters: [ + Parameter( + type: const TypeDeclaration( + baseName: 'Input', + isNullable: false, + ), + name: 'input', + ), + ], + ), + ], + fields: [ + ApiField( + name: 'someField', + type: const TypeDeclaration( + baseName: 'int', + isNullable: false, + ), + ) + ], + methods: [ + Method( + name: 'doSomething', + location: ApiLocation.host, + parameters: [ + Parameter( + type: const TypeDeclaration( + baseName: 'Input', + isNullable: false, + ), + name: 'input', + ) + ], + returnType: const TypeDeclaration( + baseName: 'String', + isNullable: false, + ), + ), + Method( + name: 'doSomethingElse', + location: ApiLocation.flutter, + isRequired: false, + parameters: [ + Parameter( + type: const TypeDeclaration( + baseName: 'Input', + isNullable: false, + ), + name: 'input', + ), + ], + returnType: const TypeDeclaration( + baseName: 'String', + isNullable: false, + ), + ), + ], + ) + ], + classes: [], + enums: [], + ); + final StringBuffer sink = StringBuffer(); + const SwiftGenerator generator = SwiftGenerator(); + generator.generate( + const SwiftOptions(fileSpecificClassNameComponent: 'MyFile'), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + final String collapsedCode = _collapseNewlineAndIndentation(code); + + // import + expect(code, contains('import MyLibrary')); + + // Instance Manager + expect( + code, + contains( + r'final class MyFilePigeonInstanceManager', + ), + ); + expect( + code, + contains( + r'private class MyFilePigeonInstanceManagerApi', + ), + ); + + // ProxyApi Delegate + expect(code, contains(r'protocol MyFilePigeonProxyApiDelegate')); + expect( + collapsedCode, + contains( + r'func pigeonApiApi(_ registrar: MyFilePigeonProxyApiRegistrar) -> PigeonApiApi'), + ); + + // API registrar + expect( + code, + contains('open class MyFilePigeonProxyApiRegistrar'), + ); + + // ReaderWriter + expect( + code, + contains( + 'private class MyFilePigeonInternalProxyApiCodecReaderWriter: FlutterStandardReaderWriter', + ), + ); + + // Delegate and class + expect(code, contains('protocol PigeonApiDelegateApi')); + expect(code, contains('protocol PigeonApiProtocolApi')); + expect( + code, + contains( + r'class PigeonApiApi: PigeonApiProtocolApi', + ), + ); + + // Constructors + expect( + collapsedCode, + contains( + r'func name(pigeonApi: PigeonApiApi, someField: Int64, input: Input) throws -> MyLibraryApi', + ), + ); + expect( + collapsedCode, + contains( + r'func pigeonNewInstance(pigeonInstance: MyLibraryApi, completion: @escaping (Result) -> Void) ', + ), + ); + + // Field + expect( + code, + contains( + 'func someField(pigeonApi: PigeonApiApi, pigeonInstance: MyLibraryApi) throws -> Int64', + ), + ); + + // Dart -> Host method + expect( + collapsedCode, + contains( + 'func doSomething(pigeonApi: PigeonApiApi, pigeonInstance: MyLibraryApi, input: Input) throws -> String', + ), + ); + + // Host -> Dart method + expect( + code, + contains( + r'static func setUpMessageHandlers(binaryMessenger: FlutterBinaryMessenger, api: PigeonApiApi?)', + ), + ); + expect( + code, + contains( + 'func doSomethingElse(pigeonInstance pigeonInstanceArg: MyLibraryApi, input inputArg: Input, completion: @escaping (Result) -> Void)', + ), + ); + }); + + group('inheritance', () { + test('extends', () { + final AstProxyApi api2 = AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [], + ); + final Root root = Root(apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [], + methods: [], + superClass: TypeDeclaration( + baseName: api2.name, + isNullable: false, + associatedProxyApi: api2, + ), + ), + api2, + ], classes: [], enums: []); + final StringBuffer sink = StringBuffer(); + const SwiftGenerator generator = SwiftGenerator(); + generator.generate( + const SwiftOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + expect( + code, + contains('var pigeonApiApi2: PigeonApiApi2'), + ); + }); + + test('implements', () { + final AstProxyApi api2 = AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [], + ); + final Root root = Root(apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [], + methods: [], + interfaces: { + TypeDeclaration( + baseName: api2.name, + isNullable: false, + associatedProxyApi: api2, + ) + }, + ), + api2, + ], classes: [], enums: []); + final StringBuffer sink = StringBuffer(); + const SwiftGenerator generator = SwiftGenerator(); + generator.generate( + const SwiftOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + expect(code, contains('var pigeonApiApi2: PigeonApiApi2')); + }); + + test('implements 2 ProxyApis', () { + final AstProxyApi api2 = AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [], + ); + final AstProxyApi api3 = AstProxyApi( + name: 'Api3', + constructors: [], + fields: [], + methods: [], + ); + final Root root = Root(apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [], + methods: [], + interfaces: { + TypeDeclaration( + baseName: api2.name, + isNullable: false, + associatedProxyApi: api2, + ), + TypeDeclaration( + baseName: api3.name, + isNullable: false, + associatedProxyApi: api3, + ), + }, + ), + api2, + api3, + ], classes: [], enums: []); + final StringBuffer sink = StringBuffer(); + const SwiftGenerator generator = SwiftGenerator(); + generator.generate( + const SwiftOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + expect(code, contains('var pigeonApiApi2: PigeonApiApi2')); + expect(code, contains('var pigeonApiApi3: PigeonApiApi3')); + }); + }); + + group('Constructors', () { + test('empty name and no params constructor', () { + final Root root = Root( + apis: [ + AstProxyApi(name: 'Api', constructors: [ + Constructor( + name: '', + parameters: [], + ) + ], fields: [], methods: []), + ], + classes: [], + enums: [], + ); + final StringBuffer sink = StringBuffer(); + const SwiftGenerator generator = SwiftGenerator(); + generator.generate( + const SwiftOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + final String collapsedCode = _collapseNewlineAndIndentation(code); + expect( + code, + contains('class PigeonApiApi: PigeonApiProtocolApi '), + ); + expect( + collapsedCode, + contains( + 'func pigeonDefaultConstructor(pigeonApi: PigeonApiApi) throws -> Api'), + ); + expect( + collapsedCode, + contains( + r'let pigeonDefaultConstructorChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.test_package.Api.pigeon_defaultConstructor", binaryMessenger: binaryMessenger, codec: codec)', + ), + ); + expect( + collapsedCode, + contains( + r'api.pigeonRegistrar.instanceManager.addDartCreatedInstance(', + ), + ); + }); + + test('multiple params constructor', () { + final Enum anEnum = Enum( + name: 'AnEnum', + members: [EnumMember(name: 'one')], + ); + final Root root = Root( + apis: [ + AstProxyApi(name: 'Api', constructors: [ + Constructor( + name: 'name', + parameters: [ + Parameter( + type: const TypeDeclaration( + isNullable: false, + baseName: 'int', + ), + name: 'validType', + ), + Parameter( + type: TypeDeclaration( + isNullable: false, + baseName: 'AnEnum', + associatedEnum: anEnum, + ), + name: 'enumType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: false, + baseName: 'Api2', + ), + name: 'proxyApiType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: true, + baseName: 'int', + ), + name: 'nullableValidType', + ), + Parameter( + type: TypeDeclaration( + isNullable: true, + baseName: 'AnEnum', + associatedEnum: anEnum, + ), + name: 'nullableEnumType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: true, + baseName: 'Api2', + ), + name: 'nullableProxyApiType', + ), + ], + ) + ], fields: [], methods: []), + AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [], + ), + ], + classes: [], + enums: [anEnum], + ); + final StringBuffer sink = StringBuffer(); + const SwiftGenerator generator = SwiftGenerator(); + generator.generate( + const SwiftOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + final String collapsedCode = _collapseNewlineAndIndentation(code); + expect( + code, + contains( + 'class PigeonApiApi: PigeonApiProtocolApi ', + ), + ); + expect( + collapsedCode, + contains( + 'func name(pigeonApi: PigeonApiApi, validType: Int64, enumType: AnEnum, proxyApiType: Api2, nullableValidType: Int64?, nullableEnumType: AnEnum?, nullableProxyApiType: Api2?) throws -> Api', + ), + ); + expect( + collapsedCode, + contains( + r'api.pigeonRegistrar.instanceManager.addDartCreatedInstance( ' + r'try api.pigeonDelegate.name(pigeonApi: api, validType: validTypeArg, enumType: enumTypeArg, proxyApiType: ' + r'proxyApiTypeArg, nullableValidType: nullableValidTypeArg, nullableEnumType: nullableEnumTypeArg, ' + r'nullableProxyApiType: nullableProxyApiTypeArg)', + ), + ); + }); + }); + + group('Fields', () { + test('constructor with fields', () { + final Enum anEnum = Enum( + name: 'AnEnum', + members: [EnumMember(name: 'one')], + ); + final Root root = Root( + apis: [ + AstProxyApi( + name: 'Api', + constructors: [ + Constructor( + name: 'name', + parameters: [], + ) + ], + fields: [ + ApiField( + type: const TypeDeclaration( + isNullable: false, + baseName: 'int', + ), + name: 'validType', + ), + ApiField( + type: TypeDeclaration( + isNullable: false, + baseName: 'AnEnum', + associatedEnum: anEnum, + ), + name: 'enumType', + ), + ApiField( + type: const TypeDeclaration( + isNullable: false, + baseName: 'Api2', + ), + name: 'proxyApiType', + ), + ApiField( + type: const TypeDeclaration( + isNullable: true, + baseName: 'int', + ), + name: 'nullableValidType', + ), + ApiField( + type: TypeDeclaration( + isNullable: true, + baseName: 'AnEnum', + associatedEnum: anEnum, + ), + name: 'nullableEnumType', + ), + ApiField( + type: const TypeDeclaration( + isNullable: true, + baseName: 'Api2', + ), + name: 'nullableProxyApiType', + ), + ], + methods: [], + ), + AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [], + ), + ], + classes: [], + enums: [anEnum], + ); + final StringBuffer sink = StringBuffer(); + const SwiftGenerator generator = SwiftGenerator(); + generator.generate( + const SwiftOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + final String collapsedCode = _collapseNewlineAndIndentation(code); + expect( + collapsedCode, + contains( + 'func name(pigeonApi: ' + 'PigeonApiApi, validType: Int64, enumType: AnEnum, proxyApiType: Api2, nullableValidType: Int64?, nullableEnumType: AnEnum?, ' + 'nullableProxyApiType: Api2?) throws -> Api func validType(pigeonApi: PigeonApiApi, pigeonInstance: Api) throws -> Int64 ', + ), + ); + expect( + collapsedCode, + contains( + r'api.pigeonRegistrar.instanceManager.addDartCreatedInstance( try api.pigeonDelegate.name(pigeonApi: api, ' + r'validType: validTypeArg, enumType: enumTypeArg, proxyApiType: proxyApiTypeArg, nullableValidType: nullableValidTypeArg, ' + r'nullableEnumType: nullableEnumTypeArg, nullableProxyApiType: nullableProxyApiTypeArg)', + ), + ); + expect( + collapsedCode, + contains( + 'channel.sendMessage([pigeonIdentifierArg, validTypeArg, enumTypeArg, ' + 'proxyApiTypeArg, nullableValidTypeArg, nullableEnumTypeArg, nullableProxyApiTypeArg] as [Any?])'), + ); + expect( + code, + contains( + r'func validType(pigeonApi: PigeonApiApi, pigeonInstance: Api) throws -> Int64'), + ); + expect( + code, + contains( + r'func enumType(pigeonApi: PigeonApiApi, pigeonInstance: Api) throws -> AnEnum'), + ); + expect( + code, + contains( + r'func proxyApiType(pigeonApi: PigeonApiApi, pigeonInstance: Api) throws -> Api2'), + ); + expect( + code, + contains( + r'func nullableValidType(pigeonApi: PigeonApiApi, pigeonInstance: Api) throws -> Int64?', + ), + ); + expect( + code, + contains( + r'func nullableEnumType(pigeonApi: PigeonApiApi, pigeonInstance: Api) throws -> AnEnum?', + ), + ); + expect( + code, + contains( + r'func nullableProxyApiType(pigeonApi: PigeonApiApi, pigeonInstance: Api) throws -> Api2?', + ), + ); + }); + + test('attached field', () { + final AstProxyApi api2 = AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [], + ); + final Root root = Root( + apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [ + ApiField( + name: 'aField', + isAttached: true, + type: TypeDeclaration( + baseName: 'Api2', + isNullable: false, + associatedProxyApi: api2, + ), + ), + ], + methods: [], + ), + api2, + ], + classes: [], + enums: [], + ); + final StringBuffer sink = StringBuffer(); + const SwiftGenerator generator = SwiftGenerator(); + generator.generate( + const SwiftOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + expect( + code, + contains( + r'func aField(pigeonApi: PigeonApiApi, pigeonInstance: Api) throws -> Api2'), + ); + expect( + code, + contains( + r'api.pigeonRegistrar.instanceManager.addDartCreatedInstance(try api.pigeonDelegate.aField(pigeonApi: api, pigeonInstance: pigeonInstanceArg), withIdentifier: pigeonIdentifierArg)', + ), + ); + }); + + test('static attached field', () { + final AstProxyApi api2 = AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [], + ); + final Root root = Root( + apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [ + ApiField( + name: 'aField', + isStatic: true, + isAttached: true, + type: TypeDeclaration( + baseName: 'Api2', + isNullable: false, + associatedProxyApi: api2, + ), + ), + ], + methods: [], + ), + api2, + ], + classes: [], + enums: [], + ); + final StringBuffer sink = StringBuffer(); + const SwiftGenerator generator = SwiftGenerator(); + generator.generate( + const SwiftOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + expect( + code, + contains(r'func aField(pigeonApi: PigeonApiApi) throws -> Api2'), + ); + expect( + code, + contains( + r'api.pigeonRegistrar.instanceManager.addDartCreatedInstance(try api.pigeonDelegate.aField(pigeonApi: api), withIdentifier: pigeonIdentifierArg)', + ), + ); + }); + }); + + group('Host methods', () { + test('multiple params method', () { + final Enum anEnum = Enum( + name: 'AnEnum', + members: [EnumMember(name: 'one')], + ); + final Root root = Root( + apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [], + methods: [ + Method( + name: 'doSomething', + location: ApiLocation.host, + parameters: [ + Parameter( + type: const TypeDeclaration( + isNullable: false, + baseName: 'int', + ), + name: 'validType', + ), + Parameter( + type: TypeDeclaration( + isNullable: false, + baseName: 'AnEnum', + associatedEnum: anEnum, + ), + name: 'enumType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: false, + baseName: 'Api2', + ), + name: 'proxyApiType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: true, + baseName: 'int', + ), + name: 'nullableValidType', + ), + Parameter( + type: TypeDeclaration( + isNullable: true, + baseName: 'AnEnum', + associatedEnum: anEnum, + ), + name: 'nullableEnumType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: true, + baseName: 'Api2', + ), + name: 'nullableProxyApiType', + ), + ], + returnType: const TypeDeclaration.voidDeclaration(), + ), + ], + ), + AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [], + ), + ], + classes: [], + enums: [anEnum], + ); + final StringBuffer sink = StringBuffer(); + const SwiftGenerator generator = SwiftGenerator(); + generator.generate( + const SwiftOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + final String collapsedCode = _collapseNewlineAndIndentation(code); + expect( + collapsedCode, + contains( + 'func doSomething(pigeonApi: ' + 'PigeonApiApi, pigeonInstance: Api, validType: Int64, enumType: AnEnum, proxyApiType: Api2, nullableValidType: Int64?, ' + 'nullableEnumType: AnEnum?, nullableProxyApiType: Api2?) throws', + ), + ); + expect( + collapsedCode, + contains( + r'try api.pigeonDelegate.doSomething(pigeonApi: ' + r'api, pigeonInstance: pigeonInstanceArg, validType: validTypeArg, enumType: enumTypeArg, proxyApiType: ' + r'proxyApiTypeArg, nullableValidType: nullableValidTypeArg, nullableEnumType: nullableEnumTypeArg, nullableProxyApiType: ' + r'nullableProxyApiTypeArg)', + ), + ); + }); + + test('static method', () { + final Root root = Root( + apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [], + methods: [ + Method( + name: 'doSomething', + location: ApiLocation.host, + isStatic: true, + parameters: [], + returnType: const TypeDeclaration.voidDeclaration(), + ), + ], + ), + ], + classes: [], + enums: [], + ); + final StringBuffer sink = StringBuffer(); + const SwiftGenerator generator = SwiftGenerator(); + generator.generate( + const SwiftOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + final String collapsedCode = _collapseNewlineAndIndentation(code); + expect( + collapsedCode, + contains('func doSomething(pigeonApi: PigeonApiApi) throws'), + ); + expect( + collapsedCode, + contains(r'try api.pigeonDelegate.doSomething(pigeonApi: api)'), + ); + }); + }); + + group('Flutter methods', () { + test('multiple params flutter method', () { + final Enum anEnum = Enum( + name: 'AnEnum', + members: [EnumMember(name: 'one')], + ); + final Root root = Root(apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [], + methods: [ + Method( + name: 'doSomething', + location: ApiLocation.flutter, + parameters: [ + Parameter( + type: const TypeDeclaration( + isNullable: false, + baseName: 'int', + ), + name: 'validType', + ), + Parameter( + type: TypeDeclaration( + isNullable: false, + baseName: 'AnEnum', + associatedEnum: anEnum, + ), + name: 'enumType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: false, + baseName: 'Api2', + ), + name: 'proxyApiType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: true, + baseName: 'int', + ), + name: 'nullableValidType', + ), + Parameter( + type: TypeDeclaration( + isNullable: true, + baseName: 'AnEnum', + associatedEnum: anEnum, + ), + name: 'nullableEnumType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: true, + baseName: 'Api2', + ), + name: 'nullableProxyApiType', + ), + ], + returnType: const TypeDeclaration.voidDeclaration(), + ) + ]) + ], classes: [], enums: [ + anEnum + ]); + final StringBuffer sink = StringBuffer(); + const SwiftGenerator generator = SwiftGenerator(); + generator.generate( + const SwiftOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + final String collapsedCode = _collapseNewlineAndIndentation(code); + expect( + collapsedCode, + contains( + 'func doSomething(pigeonInstance pigeonInstanceArg: Api, validType validTypeArg: Int64, enumType ' + 'enumTypeArg: AnEnum, proxyApiType proxyApiTypeArg: Api2, nullableValidType nullableValidTypeArg: Int64?, nullableEnumType ' + 'nullableEnumTypeArg: AnEnum?, nullableProxyApiType nullableProxyApiTypeArg: Api2?, ' + 'completion: @escaping (Result) -> Void)', + ), + ); + expect( + collapsedCode, + contains( + r'channel.sendMessage([pigeonInstanceArg, validTypeArg, ' + r'enumTypeArg, proxyApiTypeArg, nullableValidTypeArg, ' + r'nullableEnumTypeArg, nullableProxyApiTypeArg] as [Any?])', + ), + ); + }); + }); + }); +} + +/// Replaces a new line and the indentation with a single white space +/// +/// This +/// +/// ```dart +/// void method( +/// int param1, +/// int param2, +/// ) +/// ``` +/// +/// converts to +/// +/// ```dart +/// void method( int param1, int param2, ) +/// ``` +String _collapseNewlineAndIndentation(String string) { + final StringBuffer result = StringBuffer(); + for (final String line in string.split('\n')) { + result.write('${line.trimLeft()} '); + } + return result.toString().trim(); +} diff --git a/packages/pigeon/test/swift_generator_test.dart b/packages/pigeon/test/swift_generator_test.dart index 6ffe4f4d9d7a..b9f7de5d356a 100644 --- a/packages/pigeon/test/swift_generator_test.dart +++ b/packages/pigeon/test/swift_generator_test.dart @@ -51,7 +51,7 @@ void main() { expect(code, contains('struct Foobar')); expect(code, contains('var field1: Int64? = nil')); expect(code, - contains('static func fromList(_ __pigeon_list: [Any?]) -> Foobar?')); + contains('static func fromList(_ pigeonVar_list: [Any?]) -> Foobar?')); expect(code, contains('func toList() -> [Any?]')); expect(code, isNot(contains('if ('))); }); @@ -122,8 +122,8 @@ void main() { expect( code, contains( - 'let enumResultAsInt: Int? = nilOrValue(self.readValue() as? Int)')); - expect(code, contains('enumResult = Foo(rawValue: enumResultAsInt)')); + 'let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?)')); + expect(code, contains('return Foo(rawValue: enumResultAsInt)')); expect(code, contains('let fooArg = args[0] as! Foo')); expect(code, isNot(contains('if ('))); }); @@ -535,7 +535,7 @@ void main() { ); final String code = sink.toString(); expect(code, contains('struct Foobar')); - expect(code, contains('var field1: [AnyHashable: Any?]? = nil')); + expect(code, contains('var field1: [AnyHashable?: Any?]? = nil')); expect(code, isNot(contains('if ('))); }); @@ -582,9 +582,9 @@ void main() { expect(code, contains('struct Nested')); expect(code, contains('var nested: Nested? = nil')); expect(code, - contains('static func fromList(_ __pigeon_list: [Any?]) -> Outer?')); + contains('static func fromList(_ pigeonVar_list: [Any?]) -> Outer?')); expect( - code, contains('let nested: Nested? = nilOrValue(__pigeon_list[0])')); + code, contains('let nested: Nested? = nilOrValue(pigeonVar_list[0])')); expect(code, contains('func toList() -> [Any?]')); expect(code, isNot(contains('if ('))); // Single-element list serializations should not have a trailing comma. @@ -1006,14 +1006,8 @@ void main() { final String code = sink.toString(); expect(code, contains('func add(x: Int64, y: Int64) throws -> Int64')); expect(code, contains('let args = message as! [Any?]')); - expect( - code, - contains( - 'let xArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)')); - expect( - code, - contains( - 'let yArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)')); + expect(code, contains('let xArg = args[0] as! Int64')); + expect(code, contains('let yArg = args[1] as! Int64')); expect(code, contains('let result = try api.add(x: xArg, y: yArg)')); expect(code, contains('reply(wrapResult(result))')); }); @@ -1049,10 +1043,7 @@ void main() { ); final String code = sink.toString(); expect(code, contains('let channel = FlutterBasicMessageChannel')); - expect( - code, - contains( - 'let result = listResponse[0] is Int64 ? listResponse[0] as! Int64 : Int64(listResponse[0] as! Int32)')); + expect(code, contains('let result = listResponse[0] as! Int64')); expect(code, contains('completion(.success(result))')); expect( code, @@ -1157,10 +1148,7 @@ void main() { dartPackageName: DEFAULT_PACKAGE_NAME, ); final String code = sink.toString(); - expect( - code, - contains( - 'let fooArg: Int64? = isNullish(args[0]) ? nil : (args[0] is Int64? ? args[0] as! Int64? : Int64(args[0] as! Int32))')); + expect(code, contains('let fooArg: Int64? = nilOrValue(args[0])')); }); test('nullable argument flutter', () { diff --git a/packages/pigeon/tool/generate.dart b/packages/pigeon/tool/generate.dart index ecb465c13940..752e2ffadc24 100644 --- a/packages/pigeon/tool/generate.dart +++ b/packages/pigeon/tool/generate.dart @@ -23,6 +23,7 @@ const String _noFormatFlag = 'no-format'; const String _files = 'files'; const String _test = 'test'; const String _example = 'example'; +const String _overflowFiller = 'overflow'; const List _fileGroups = [_test, _example]; @@ -43,6 +44,13 @@ Future main(List args) async { ) ..addFlag(_helpFlag, negatable: false, abbr: 'h', help: 'Print this reference.') + ..addFlag( + _overflowFiller, + abbr: 'o', + help: + 'Injects 120 Enums into the pigeon ast, used for testing overflow utilities.', + hide: true, + ) ..addMultiOption(_files, help: 'Select specific groups of files to generate; $_test or $_example. Defaults to both.', @@ -59,13 +67,16 @@ ${parser.usage}'''); final String baseDir = p.dirname(p.dirname(Platform.script.toFilePath())); + final bool includeOverflow = argResults.wasParsed(_overflowFiller); + final List toGenerate = argResults.wasParsed(_files) ? argResults[_files] as List : _fileGroups; if (toGenerate.contains(_test)) { print('Generating platform_test/ output...'); - final int generateExitCode = await generateTestPigeons(baseDir: baseDir); + final int generateExitCode = await generateTestPigeons( + baseDir: baseDir, includeOverflow: includeOverflow); if (generateExitCode == 0) { print('Generation complete!'); } else { diff --git a/packages/pigeon/tool/run_tests.dart b/packages/pigeon/tool/run_tests.dart index ffcbe78887b0..e380efdd14b9 100644 --- a/packages/pigeon/tool/run_tests.dart +++ b/packages/pigeon/tool/run_tests.dart @@ -67,6 +67,7 @@ Future _validateGeneratedFiles( languagesToValidate = { GeneratorLanguage.cpp, GeneratorLanguage.dart, + GeneratorLanguage.gobject, GeneratorLanguage.java, GeneratorLanguage.kotlin, GeneratorLanguage.objc, @@ -140,6 +141,7 @@ Set _extensionsForLanguage(GeneratorLanguage language) { return switch (language) { GeneratorLanguage.cpp => {'cc', 'cpp', 'h'}, GeneratorLanguage.dart => {'dart'}, + GeneratorLanguage.gobject => {'cc', 'h'}, GeneratorLanguage.java => {'java'}, GeneratorLanguage.kotlin => {'kt'}, GeneratorLanguage.swift => {'swift'}, @@ -177,6 +179,8 @@ Future main(List args) async { androidKotlinUnitTests, androidJavaIntegrationTests, androidKotlinIntegrationTests, + linuxUnitTests, + linuxIntegrationTests, ]; const List macOSHostTests = [ iOSObjCUnitTests, @@ -234,5 +238,5 @@ Future main(List args) async { exit(2); } - await runTests(testsToRun); + await runTests(testsToRun, ciMode: true, includeOverflow: true); } diff --git a/packages/pigeon/tool/shared/generation.dart b/packages/pigeon/tool/shared/generation.dart index 8166e49d73f0..4cee0d4de568 100644 --- a/packages/pigeon/tool/shared/generation.dart +++ b/packages/pigeon/tool/shared/generation.dart @@ -13,6 +13,7 @@ import 'process_utils.dart'; enum GeneratorLanguage { cpp, dart, + gobject, java, kotlin, objc, @@ -54,7 +55,8 @@ Future generateExamplePigeons() async { ); } -Future generateTestPigeons({required String baseDir}) async { +Future generateTestPigeons( + {required String baseDir, bool includeOverflow = false}) async { // TODO(stuartmorgan): Make this dynamic rather than hard-coded. Or eliminate // it entirely; see https://github.com/flutter/flutter/issues/115169. const List inputs = [ @@ -89,7 +91,8 @@ Future generateTestPigeons({required String baseDir}) async { ? 'FlutterError' : '${pascalCaseName}Error'; - final bool swiftErrorUseDefaultErrorName = input == 'core_tests'; + final bool swiftErrorUseDefaultErrorName = + input == 'core_tests' || input == 'background_platform_channels'; final String? swiftErrorClassName = swiftErrorUseDefaultErrorName ? null : '${pascalCaseName}Error'; @@ -101,6 +104,8 @@ Future generateTestPigeons({required String baseDir}) async { dartTestOut: input == 'message' ? '$sharedDartOutputBase/test/test_message.gen.dart' : null, + dartPackageName: 'pigeon_integration_tests', + suppressVersion: true, // Android kotlinOut: skipLanguages.contains(GeneratorLanguage.kotlin) ? null @@ -113,6 +118,15 @@ Future generateTestPigeons({required String baseDir}) async { ? null : '$outputBase/ios/Classes/$pascalCaseName.gen.swift', swiftErrorClassName: swiftErrorClassName, + swiftIncludeErrorClass: input != 'core_tests', + // Linux + gobjectHeaderOut: skipLanguages.contains(GeneratorLanguage.gobject) + ? null + : '$outputBase/linux/pigeon/$input.gen.h', + gobjectSourceOut: skipLanguages.contains(GeneratorLanguage.gobject) + ? null + : '$outputBase/linux/pigeon/$input.gen.cc', + gobjectModule: '${pascalCaseName}PigeonTest', // Windows cppHeaderOut: skipLanguages.contains(GeneratorLanguage.cpp) ? null @@ -121,8 +135,7 @@ Future generateTestPigeons({required String baseDir}) async { ? null : '$outputBase/windows/pigeon/$input.gen.cpp', cppNamespace: '${input}_pigeontest', - suppressVersion: true, - dartPackageName: 'pigeon_integration_tests', + injectOverflowTypes: includeOverflow && input == 'core_tests', ); if (generateCode != 0) { return generateCode; @@ -137,8 +150,10 @@ Future generateTestPigeons({required String baseDir}) async { ? null : '$outputBase/macos/Classes/$pascalCaseName.gen.swift', swiftErrorClassName: swiftErrorClassName, + swiftIncludeErrorClass: input != 'core_tests', suppressVersion: true, dartPackageName: 'pigeon_integration_tests', + injectOverflowTypes: includeOverflow && input == 'core_tests', ); if (generateCode != 0) { return generateCode; @@ -165,6 +180,7 @@ Future generateTestPigeons({required String baseDir}) async { objcPrefix: input == 'core_tests' ? 'FLT' : '', suppressVersion: true, dartPackageName: 'pigeon_integration_tests', + injectOverflowTypes: includeOverflow && input == 'core_tests', ); if (generateCode != 0) { return generateCode; @@ -181,8 +197,10 @@ Future generateTestPigeons({required String baseDir}) async { objcSourceOut: skipLanguages.contains(GeneratorLanguage.objc) ? null : '$alternateOutputBase/macos/Classes/$pascalCaseName.gen.m', + objcPrefix: input == 'core_tests' ? 'FLT' : '', suppressVersion: true, dartPackageName: 'pigeon_integration_tests', + injectOverflowTypes: includeOverflow && input == 'core_tests', ); if (generateCode != 0) { return generateCode; @@ -197,6 +215,7 @@ Future runPigeon({ String? kotlinPackage, String? kotlinErrorClassName, bool kotlinIncludeErrorClass = true, + bool swiftIncludeErrorClass = true, String? swiftOut, String? swiftErrorClassName, String? cppHeaderOut, @@ -204,6 +223,9 @@ Future runPigeon({ String? cppNamespace, String? dartOut, String? dartTestOut, + String? gobjectHeaderOut, + String? gobjectSourceOut, + String? gobjectModule, String? javaOut, String? javaPackage, String? objcHeaderOut, @@ -213,6 +235,7 @@ Future runPigeon({ String copyrightHeader = './copyright_header.txt', String? basePath, String? dartPackageName, + bool injectOverflowTypes = false, }) async { // Temporarily suppress the version output via the global flag if requested. // This is done because having the version in all the generated test output @@ -226,33 +249,40 @@ Future runPigeon({ if (suppressVersion) { includeVersionInGeneratedWarning = false; } - final int result = await Pigeon.runWithOptions(PigeonOptions( - input: input, - copyrightHeader: copyrightHeader, - dartOut: dartOut, - dartTestOut: dartTestOut, - dartOptions: const DartOptions(), - cppHeaderOut: cppHeaderOut, - cppSourceOut: cppSourceOut, - cppOptions: CppOptions(namespace: cppNamespace), - javaOut: javaOut, - javaOptions: JavaOptions(package: javaPackage), - kotlinOut: kotlinOut, - kotlinOptions: KotlinOptions( - package: kotlinPackage, - errorClassName: kotlinErrorClassName, - includeErrorClass: kotlinIncludeErrorClass, + final int result = await Pigeon.runWithOptions( + PigeonOptions( + input: input, + copyrightHeader: copyrightHeader, + dartOut: dartOut, + dartTestOut: dartTestOut, + dartOptions: const DartOptions(), + cppHeaderOut: cppHeaderOut, + cppSourceOut: cppSourceOut, + cppOptions: CppOptions(namespace: cppNamespace), + gobjectHeaderOut: gobjectHeaderOut, + gobjectSourceOut: gobjectSourceOut, + gobjectOptions: GObjectOptions(module: gobjectModule), + javaOut: javaOut, + javaOptions: JavaOptions(package: javaPackage), + kotlinOut: kotlinOut, + kotlinOptions: KotlinOptions( + package: kotlinPackage, + errorClassName: kotlinErrorClassName, + includeErrorClass: kotlinIncludeErrorClass, + ), + objcHeaderOut: objcHeaderOut, + objcSourceOut: objcSourceOut, + objcOptions: ObjcOptions(prefix: objcPrefix), + swiftOut: swiftOut, + swiftOptions: SwiftOptions( + errorClassName: swiftErrorClassName, + includeErrorClass: swiftIncludeErrorClass, + ), + basePath: basePath, + dartPackageName: dartPackageName, ), - objcHeaderOut: objcHeaderOut, - objcSourceOut: objcSourceOut, - objcOptions: ObjcOptions(prefix: objcPrefix), - swiftOut: swiftOut, - swiftOptions: SwiftOptions( - errorClassName: swiftErrorClassName, - ), - basePath: basePath, - dartPackageName: dartPackageName, - )); + injectOverflowTypes: injectOverflowTypes, + ); includeVersionInGeneratedWarning = originalWarningSetting; return result; } @@ -267,6 +297,7 @@ Future formatAllFiles({ Set languages = const { GeneratorLanguage.cpp, GeneratorLanguage.dart, + GeneratorLanguage.gobject, GeneratorLanguage.java, GeneratorLanguage.kotlin, GeneratorLanguage.objc, @@ -282,6 +313,7 @@ Future formatAllFiles({ 'format', '--packages=pigeon', if (languages.contains(GeneratorLanguage.cpp) || + languages.contains(GeneratorLanguage.gobject) || languages.contains(GeneratorLanguage.objc)) '--clang-format' else diff --git a/packages/pigeon/tool/shared/native_project_runners.dart b/packages/pigeon/tool/shared/native_project_runners.dart index 06111e0257da..71ee6272232a 100644 --- a/packages/pigeon/tool/shared/native_project_runners.dart +++ b/packages/pigeon/tool/shared/native_project_runners.dart @@ -7,12 +7,15 @@ import 'process_utils.dart'; Future runFlutterCommand( String projectDirectory, - String command, [ - List commandArguments = const [], -]) { + String command, + List commandArguments, { + String? wrapperCommand, +}) { + final String flutterCommand = getFlutterCommand(); return runProcess( - getFlutterCommand(), + wrapperCommand ?? flutterCommand, [ + if (wrapperCommand != null) flutterCommand, command, ...commandArguments, ], diff --git a/packages/pigeon/tool/shared/test_runner.dart b/packages/pigeon/tool/shared/test_runner.dart index c2df4b58f063..cdb769fc0294 100644 --- a/packages/pigeon/tool/shared/test_runner.dart +++ b/packages/pigeon/tool/shared/test_runner.dart @@ -17,38 +17,79 @@ Future runTests( List testsToRun, { bool runFormat = false, bool runGeneration = true, + bool ciMode = false, + bool includeOverflow = false, }) async { final String baseDir = p.dirname(p.dirname(Platform.script.toFilePath())); if (runGeneration) { - // Pre-generate the necessary common output files. - // TODO(stuartmorgan): Consider making this conditional on the specific - // tests being run, as not all of them need these files. - print('# Generating platform_test/ output...'); - final int generateExitCode = await generateTestPigeons(baseDir: baseDir); - if (generateExitCode == 0) { - print('Generation complete!'); - } else { - print('Generation failed; see above for errors.'); - } + await _runGenerate(baseDir); } if (runFormat) { - print('Formatting generated output...'); - final int formatExitCode = - await formatAllFiles(repositoryRoot: p.dirname(p.dirname(baseDir))); - if (formatExitCode != 0) { - print('Formatting failed; see above for errors.'); - exit(formatExitCode); + await _runFormat(baseDir); + } + + await _runTests(testsToRun, ciMode: ciMode); + + if (includeOverflow) { + await _runGenerate(baseDir, includeOverflow: true); + + // TODO(tarrinneal): Remove linux filter once overflow class is added to gobject generator. + // https://github.com/flutter/flutter/issues/152916 + await _runTests(testsToRun + .where((String test) => + test.contains('integration') && !test.contains('linux')) + .toList()); + + if (!ciMode) { + await _runGenerate(baseDir); + } + + if (!ciMode && (runFormat || !runGeneration)) { + await _runFormat(baseDir); } } +} +// Pre-generate the necessary common output files. +Future _runGenerate(String baseDir, + {bool includeOverflow = false}) async { + // TODO(stuartmorgan): Consider making this conditional on the specific + // tests being run, as not all of them need these files. + print('# Generating platform_test/ output...'); + final int generateExitCode = await generateTestPigeons( + baseDir: baseDir, + includeOverflow: includeOverflow, + ); + if (generateExitCode == 0) { + print('Generation complete!'); + } else { + print('Generation failed; see above for errors.'); + } +} + +Future _runFormat(String baseDir) async { + print('Formatting generated output...'); + final int formatExitCode = + await formatAllFiles(repositoryRoot: p.dirname(p.dirname(baseDir))); + if (formatExitCode != 0) { + print('Formatting failed; see above for errors.'); + exit(formatExitCode); + } +} + +Future _runTests( + List testsToRun, { + bool ciMode = true, +}) async { for (final String test in testsToRun) { final TestInfo? info = testSuites[test]; if (info != null) { print('##############################'); print('# Running $test'); - final int testCode = await info.function(); + final int testCode = await info.function(ciMode: ciMode); if (testCode != 0) { + print('# Failed, exit code: $testCode'); exit(testCode); } print(''); diff --git a/packages/pigeon/tool/shared/test_suites.dart b/packages/pigeon/tool/shared/test_suites.dart index 8f9bb7a4cb40..c37c388d03f7 100644 --- a/packages/pigeon/tool/shared/test_suites.dart +++ b/packages/pigeon/tool/shared/test_suites.dart @@ -27,7 +27,7 @@ class TestInfo { const TestInfo({required this.function, this.description}); /// The function to run the test suite. - final Future Function() function; + final Future Function({bool ciMode}) function; /// A user-facing description of the test suite. final String? description; @@ -43,6 +43,8 @@ const String iOSObjCUnitTests = 'ios_objc_unittests'; const String iOSObjCIntegrationTests = 'ios_objc_integration_tests'; const String iOSSwiftUnitTests = 'ios_swift_unittests'; const String iOSSwiftIntegrationTests = 'ios_swift_integration_tests'; +const String linuxUnitTests = 'linux_unittests'; +const String linuxIntegrationTests = 'linux_integration_tests'; const String macOSObjCIntegrationTests = 'macos_objc_integration_tests'; const String macOSSwiftUnitTests = 'macos_swift_unittests'; const String macOSSwiftIntegrationTests = 'macos_swift_integration_tests'; @@ -91,6 +93,12 @@ const Map testSuites = { iOSSwiftIntegrationTests: TestInfo( function: _runIOSSwiftIntegrationTests, description: 'Integration tests on generated Swift code.'), + linuxUnitTests: TestInfo( + function: _runLinuxUnitTests, + description: 'Unit tests on generated Linux C code.'), + linuxIntegrationTests: TestInfo( + function: _runLinuxIntegrationTests, + description: 'Integration tests on generated Linux C code.'), macOSObjCIntegrationTests: TestInfo( function: _runMacOSObjCIntegrationTests, description: 'Integration tests on generated Objective-C code on macOS.'), @@ -105,16 +113,16 @@ const Map testSuites = { description: 'Tests running pigeon with various command-line options.'), }; -Future _runAndroidJavaUnitTests() async { +Future _runAndroidJavaUnitTests({bool ciMode = false}) async { return _runAndroidUnitTests(_alternateLanguageTestPluginRelativePath); } -Future _runAndroidJavaIntegrationTests() async { +Future _runAndroidJavaIntegrationTests({bool ciMode = false}) async { return _runMobileIntegrationTests( 'Android', _alternateLanguageTestPluginRelativePath); } -Future _runAndroidJavaLint() async { +Future _runAndroidJavaLint({bool ciMode = false}) async { const String examplePath = './$_alternateLanguageTestPluginRelativePath/example'; const String androidProjectPath = '$examplePath/android'; @@ -131,7 +139,7 @@ Future _runAndroidJavaLint() async { androidProjectPath, 'alternate_language_test_plugin:lintDebug'); } -Future _runAndroidKotlinUnitTests() async { +Future _runAndroidKotlinUnitTests({bool ciMode = false}) async { return _runAndroidUnitTests(_testPluginRelativePath); } @@ -149,7 +157,7 @@ Future _runAndroidUnitTests(String testPluginPath) async { return runGradleBuild(androidProjectPath, 'testDebugUnitTest'); } -Future _runAndroidKotlinIntegrationTests() async { +Future _runAndroidKotlinIntegrationTests({bool ciMode = false}) async { return _runMobileIntegrationTests('Android', _testPluginRelativePath); } @@ -170,7 +178,7 @@ Future _runMobileIntegrationTests( ); } -Future _runDartUnitTests() async { +Future _runDartUnitTests({bool ciMode = false}) async { int exitCode = await runProcess('dart', ['analyze', 'bin']); if (exitCode != 0) { return exitCode; @@ -196,7 +204,7 @@ Future _analyzeFlutterUnitTests(String flutterUnitTestsPath) async { } final int analyzeCode = - await runFlutterCommand(flutterUnitTestsPath, 'analyze'); + await runFlutterCommand(flutterUnitTestsPath, 'analyze', []); if (analyzeCode != 0) { return analyzeCode; } @@ -207,14 +215,15 @@ Future _analyzeFlutterUnitTests(String flutterUnitTestsPath) async { return 0; } -Future _runFlutterUnitTests() async { +Future _runFlutterUnitTests({bool ciMode = false}) async { const String flutterUnitTestsPath = 'platform_tests/shared_test_plugin_code'; final int analyzeCode = await _analyzeFlutterUnitTests(flutterUnitTestsPath); if (analyzeCode != 0) { return analyzeCode; } - final int testCode = await runFlutterCommand(flutterUnitTestsPath, 'test'); + final int testCode = + await runFlutterCommand(flutterUnitTestsPath, 'test', []); if (testCode != 0) { return testCode; } @@ -222,11 +231,11 @@ Future _runFlutterUnitTests() async { return 0; } -Future _runIOSObjCUnitTests() async { +Future _runIOSObjCUnitTests({bool ciMode = false}) async { return _runIOSPluginUnitTests(_alternateLanguageTestPluginRelativePath); } -Future _runIOSObjCIntegrationTests() async { +Future _runIOSObjCIntegrationTests({bool ciMode = false}) async { final String? device = await getDeviceForPlatform('ios'); if (device == null) { print('No iOS device available. Attach an iOS device or start ' @@ -243,7 +252,7 @@ Future _runIOSObjCIntegrationTests() async { ); } -Future _runMacOSObjCIntegrationTests() async { +Future _runMacOSObjCIntegrationTests({bool ciMode = false}) async { const String examplePath = './$_alternateLanguageTestPluginRelativePath/example'; return runFlutterCommand( @@ -253,7 +262,7 @@ Future _runMacOSObjCIntegrationTests() async { ); } -Future _runMacOSSwiftUnitTests() async { +Future _runMacOSSwiftUnitTests({bool ciMode = false}) async { const String examplePath = './$_testPluginRelativePath/example'; final int compileCode = await runFlutterBuild(examplePath, 'macos'); if (compileCode != 0) { @@ -270,7 +279,7 @@ Future _runMacOSSwiftUnitTests() async { ); } -Future _runMacOSSwiftIntegrationTests() async { +Future _runMacOSSwiftIntegrationTests({bool ciMode = false}) async { const String examplePath = './$_testPluginRelativePath/example'; return runFlutterCommand( examplePath, @@ -279,7 +288,7 @@ Future _runMacOSSwiftIntegrationTests() async { ); } -Future _runIOSSwiftUnitTests() async { +Future _runIOSSwiftUnitTests({bool ciMode = false}) async { return _runIOSPluginUnitTests(_testPluginRelativePath); } @@ -345,24 +354,60 @@ Future _deleteSimulator(String deviceName) async { ); } -Future _runIOSSwiftIntegrationTests() async { +Future _runIOSSwiftIntegrationTests({bool ciMode = false}) async { return _runMobileIntegrationTests('iOS', _testPluginRelativePath); } -Future _runWindowsUnitTests() async { +Future _runLinuxUnitTests({bool ciMode = false}) async { + const String examplePath = './$_testPluginRelativePath/example'; + final int compileCode = await runFlutterBuild(examplePath, 'linux'); + if (compileCode != 0) { + return compileCode; + } + + const String buildDirBase = '$examplePath/build/linux'; + const String buildRelativeBinaryPath = + 'debug/plugins/test_plugin/test_plugin_test'; + const String arm64Path = '$buildDirBase/arm64/$buildRelativeBinaryPath'; + const String x64Path = '$buildDirBase/x64/$buildRelativeBinaryPath'; + final String testBinary = File(arm64Path).existsSync() ? arm64Path : x64Path; + if (ciMode) { + // To avoid having all custom tests in the repo run under xvfb, xvfb-run is + // done here rather than at the CI config level. Ideally, Pigeon tests + // should be incorporated into the repo tooling's standard runs, at which + // point this won't be necessary. + return runProcess('xvfb-run', [testBinary]); + } else { + return runProcess(testBinary, []); + } +} + +Future _runLinuxIntegrationTests({bool ciMode = false}) async { + const String examplePath = './$_testPluginRelativePath/example'; + return runFlutterCommand( + examplePath, + 'test', + [_integrationTestFileRelativePath, '-d', 'linux'], + // To avoid having all custom tests in the repo run under xvfb, xvfb-run is + // done here rather than at the CI config level. Ideally, Pigeon tests + // should be incorporated into the repo tooling's standard runs, at which + // point this won't be necessary. + wrapperCommand: ciMode ? 'xvfb-run' : null, + ); +} + +Future _runWindowsUnitTests({bool ciMode = false}) async { const String examplePath = './$_testPluginRelativePath/example'; final int compileCode = await runFlutterBuild(examplePath, 'windows'); if (compileCode != 0) { return compileCode; } - // Depending on the Flutter version, the build output path is different. To - // handle both master and stable, and to future-proof against the changes + // Depending on the Flutter version, the build output path may be different. + // To handle both master and stable, and to future-proof against the changes // that will happen in https://github.com/flutter/flutter/issues/129807 // - Try arm64, to future-proof against arm64 support. - // - Try x64, to cover pre-arm64 support on arm64 hosts, as well as x64 hosts - // running newer versions of Flutter. - // - Fall back to the pre-arch path, to support running against stable. + // - Try x64, to cover pre-arm64 support on arm64 hosts, as well as x64 hosts. // TODO(stuartmorgan): Remove all this when these tests no longer need to // support a version of Flutter without // https://github.com/flutter/flutter/issues/129807, and just construct the @@ -372,17 +417,14 @@ Future _runWindowsUnitTests() async { 'plugins/test_plugin/Debug/test_plugin_test.exe'; const String arm64Path = '$buildDirBase/arm64/$buildRelativeBinaryPath'; const String x64Path = '$buildDirBase/x64/$buildRelativeBinaryPath'; - const String oldPath = '$buildDirBase/$buildRelativeBinaryPath'; if (File(arm64Path).existsSync()) { return runProcess(arm64Path, []); - } else if (File(x64Path).existsSync()) { - return runProcess(x64Path, []); } else { - return runProcess(oldPath, []); + return runProcess(x64Path, []); } } -Future _runWindowsIntegrationTests() async { +Future _runWindowsIntegrationTests({bool ciMode = false}) async { const String examplePath = './$_testPluginRelativePath/example'; return runFlutterCommand( examplePath, @@ -391,7 +433,7 @@ Future _runWindowsIntegrationTests() async { ); } -Future _runCommandLineTests() async { +Future _runCommandLineTests({bool ciMode = false}) async { final Directory tempDir = Directory.systemTemp.createTempSync('pigeon'); final String tempOutput = p.join(tempDir.path, 'pigeon_output'); const String pigeonScript = 'bin/pigeon.dart'; diff --git a/packages/pigeon/tool/test.dart b/packages/pigeon/tool/test.dart index 4c3eab669f1d..07c7dfdf61b0 100644 --- a/packages/pigeon/tool/test.dart +++ b/packages/pigeon/tool/test.dart @@ -23,6 +23,7 @@ const String _testFlag = 'test'; const String _noGen = 'no-generation'; const String _listFlag = 'list'; const String _format = 'format'; +const String _overflow = 'overflow'; Future main(List args) async { final ArgParser parser = ArgParser() @@ -31,6 +32,10 @@ Future main(List args) async { abbr: 'g', help: 'Skips the generation step.', negatable: false) ..addFlag(_format, abbr: 'f', help: 'Formats generated test files before running tests.') + ..addFlag(_overflow, + help: + 'Generates overflow files for integration tests, runs tests with and without overflow files.', + abbr: 'o') ..addFlag(_listFlag, negatable: false, abbr: 'l', help: 'List available tests.') ..addFlag('help', @@ -80,6 +85,10 @@ ${parser.usage}'''); iOSSwiftUnitTests, iOSSwiftIntegrationTests, ]; + const List linuxTests = [ + linuxUnitTests, + linuxIntegrationTests, + ]; const List macOSTests = [ macOSObjCIntegrationTests, macOSSwiftUnitTests, @@ -106,6 +115,7 @@ ${parser.usage}'''); testsToRun = [ ...dartTests, ...androidTests, + ...linuxTests, ]; } else { print('Unsupported host platform.'); @@ -117,5 +127,6 @@ ${parser.usage}'''); testsToRun, runGeneration: !argResults.wasParsed(_noGen), runFormat: argResults.wasParsed(_format), + includeOverflow: argResults.wasParsed(_overflow), ); } diff --git a/packages/plugin_platform_interface/CHANGELOG.md b/packages/plugin_platform_interface/CHANGELOG.md index 7f9f98650490..6db60355d829 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.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 2.1.8 diff --git a/packages/plugin_platform_interface/pubspec.yaml b/packages/plugin_platform_interface/pubspec.yaml index 0fee03aab35d..2285d41f9173 100644 --- a/packages/plugin_platform_interface/pubspec.yaml +++ b/packages/plugin_platform_interface/pubspec.yaml @@ -18,13 +18,13 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 2.1.8 environment: - sdk: ^3.2.0 + sdk: ^3.3.0 dependencies: meta: ^1.3.0 dev_dependencies: - mockito: 5.4.4 + mockito: ^5.4.4 test: ^1.16.0 topics: diff --git a/packages/pointer_interceptor/pointer_interceptor/CHANGELOG.md b/packages/pointer_interceptor/pointer_interceptor/CHANGELOG.md index 0a47b7de02e5..5affc8fbeff8 100644 --- a/packages/pointer_interceptor/pointer_interceptor/CHANGELOG.md +++ b/packages/pointer_interceptor/pointer_interceptor/CHANGELOG.md @@ -1,5 +1,10 @@ ## NEXT +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + +## 0.10.1+2 + +* Adds performance warning about using multiple pointer interceptors on iOS. * Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. ## 0.10.1+1 diff --git a/packages/pointer_interceptor/pointer_interceptor/README.md b/packages/pointer_interceptor/pointer_interceptor/README.md index a2033491ae27..ebeb90cc02d5 100644 --- a/packages/pointer_interceptor/pointer_interceptor/README.md +++ b/packages/pointer_interceptor/pointer_interceptor/README.md @@ -6,6 +6,8 @@ `PointerInterceptor` is a widget that prevents mouse events from being captured by an underlying [`HtmlElementView`](https://api.flutter.dev/flutter/widgets/HtmlElementView-class.html) in web, or an underlying [`PlatformView`](https://api.flutter.dev/flutter/widgets/PlatformViewLink-class.html) on iOS. +Using multiple `PointerInterceptor` instances on iOS can be slow and increases memory usage due to the performance overhead of the underlying platform view. + ## What is the problem? When overlaying Flutter widgets on top of `HtmlElementView`/`PlatformView` widgets that respond to mouse gestures (handle clicks, for example), the clicks will be consumed by the `HtmlElementView`/`PlatformView`, and not relayed to Flutter. diff --git a/packages/pointer_interceptor/pointer_interceptor/example/README.md b/packages/pointer_interceptor/pointer_interceptor/example/README.md index 9fddf8c0a09f..f51c5e23fca3 100644 --- a/packages/pointer_interceptor/pointer_interceptor/example/README.md +++ b/packages/pointer_interceptor/pointer_interceptor/example/README.md @@ -4,14 +4,11 @@ An example for the PointerInterceptor widget. ## Getting Started -`flutter run -d chrome` to run the sample. You can tweak some code in the `lib/main.dart`, but be careful, changes there can break integration tests! +Use `flutter run` to run the sample. -## Running tests +## Tests -`flutter drive --target integration_test/widget_test.dart --driver test_driver/integration_test.dart --show-web-server-device -d web-server --web-renderer=html` +Per-platform tests live in their respective implementation packages: -The command above will run the integration tests for this package. - -Make sure that you have `chromedriver` running in port `4444`. - -Read more on: [flutter.dev > Docs > Testing & debugging > Integration testing](https://flutter.dev/docs/testing/integration-tests). +* **Web**: See [`package:pointer_interceptor_web`](https://github.com/flutter/packages/tree/main/packages/pointer_interceptor/pointer_interceptor_web) +* **iOS**: See [`package:pointer_interceptor_ios`](https://github.com/flutter/packages/tree/main/packages/pointer_interceptor/pointer_interceptor_ios) diff --git a/packages/pointer_interceptor/pointer_interceptor/example/ios/Podfile b/packages/pointer_interceptor/pointer_interceptor/example/ios/Podfile index 279576f3884f..01d4aa611bb9 100644 --- a/packages/pointer_interceptor/pointer_interceptor/example/ios/Podfile +++ b/packages/pointer_interceptor/pointer_interceptor/example/ios/Podfile @@ -29,7 +29,6 @@ flutter_ios_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) end diff --git a/packages/pointer_interceptor/pointer_interceptor/example/pubspec.yaml b/packages/pointer_interceptor/pointer_interceptor/example/pubspec.yaml index 7c6591908ef1..1f4e8d771035 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/pointer_interceptor/pointer_interceptor/example/web/index.html b/packages/pointer_interceptor/pointer_interceptor/example/web/index.html index a53f5677b573..3b03b888324f 100644 --- a/packages/pointer_interceptor/pointer_interceptor/example/web/index.html +++ b/packages/pointer_interceptor/pointer_interceptor/example/web/index.html @@ -33,16 +33,6 @@ - - - + diff --git a/packages/pointer_interceptor/pointer_interceptor/pubspec.yaml b/packages/pointer_interceptor/pointer_interceptor/pubspec.yaml index 3e10acce31bb..e7021029913f 100644 --- a/packages/pointer_interceptor/pointer_interceptor/pubspec.yaml +++ b/packages/pointer_interceptor/pointer_interceptor/pubspec.yaml @@ -2,11 +2,11 @@ name: pointer_interceptor description: A widget to prevent clicks from being swallowed by underlying HtmlElementViews on the web. repository: https://github.com/flutter/packages/tree/main/packages/pointer_interceptor/pointer_interceptor issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+pointer_interceptor%22 -version: 0.10.1+1 +version: 0.10.1+2 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: diff --git a/packages/pointer_interceptor/pointer_interceptor_ios/CHANGELOG.md b/packages/pointer_interceptor/pointer_interceptor_ios/CHANGELOG.md index 3d0c2bad8c2b..714b5cd05fbc 100644 --- a/packages/pointer_interceptor/pointer_interceptor_ios/CHANGELOG.md +++ b/packages/pointer_interceptor/pointer_interceptor_ios/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + ## 0.10.1 * Adds Swift Package Manager compatibility. diff --git a/packages/pointer_interceptor/pointer_interceptor_ios/README.md b/packages/pointer_interceptor/pointer_interceptor_ios/README.md index ca30d6d9defa..9d0807c190d1 100644 --- a/packages/pointer_interceptor/pointer_interceptor_ios/README.md +++ b/packages/pointer_interceptor/pointer_interceptor_ios/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/pointer_interceptor -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin \ No newline at end of file +[2]: https://flutter.dev/to/endorsed-federated-plugin \ No newline at end of file diff --git a/packages/pointer_interceptor/pointer_interceptor_ios/example/ios/Podfile b/packages/pointer_interceptor/pointer_interceptor_ios/example/ios/Podfile index d97f17e223fb..e549ee22f3b0 100644 --- a/packages/pointer_interceptor/pointer_interceptor_ios/example/ios/Podfile +++ b/packages/pointer_interceptor/pointer_interceptor_ios/example/ios/Podfile @@ -29,7 +29,6 @@ flutter_ios_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) target 'RunnerTests' do diff --git a/packages/pointer_interceptor/pointer_interceptor_ios/example/pubspec.yaml b/packages/pointer_interceptor/pointer_interceptor_ios/example/pubspec.yaml index 275ed2297fcf..ffbda428f10e 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.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.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 d9d437939162..194337f8a021 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.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.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 1169176c40ff..4bafe7e9352d 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.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 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 c66c18ab9da7..6f5a475c3b63 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/pointer_interceptor/pointer_interceptor_web/CHANGELOG.md b/packages/pointer_interceptor/pointer_interceptor_web/CHANGELOG.md index 58a970e78f7d..3363eae7b76c 100644 --- a/packages/pointer_interceptor/pointer_interceptor_web/CHANGELOG.md +++ b/packages/pointer_interceptor/pointer_interceptor_web/CHANGELOG.md @@ -1,3 +1,11 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + +## 0.10.2+1 + +* Adds support for `web: ^1.0.0`. + ## 0.10.2 * Updates web code to package `web: ^0.5.0`. diff --git a/packages/pointer_interceptor/pointer_interceptor_web/README.md b/packages/pointer_interceptor/pointer_interceptor_web/README.md index 45db9bdcbc7d..063c9236a3ef 100644 --- a/packages/pointer_interceptor/pointer_interceptor_web/README.md +++ b/packages/pointer_interceptor/pointer_interceptor_web/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/pointer_interceptor -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin \ No newline at end of file +[2]: https://flutter.dev/to/endorsed-federated-plugin \ No newline at end of file diff --git a/packages/pointer_interceptor/pointer_interceptor_web/example/README.md b/packages/pointer_interceptor/pointer_interceptor_web/example/README.md index 96b8bb17dbff..400c039738ca 100644 --- a/packages/pointer_interceptor/pointer_interceptor_web/example/README.md +++ b/packages/pointer_interceptor/pointer_interceptor_web/example/README.md @@ -7,3 +7,32 @@ package. Unless you are making changes to this implementation package, this example is very unlikely to be relevant. + +## Getting Started + +`flutter run -d chrome` to run the sample. You can tweak some code in the `lib/main.dart`, but be careful, changes there can break integration tests! + +## Running tests + +You may use the [Flutter Plugin Tools](https://github.com/flutter/packages/blob/main/script/tool/README.md) +to run the integration tests of this package. + +See [How to Run Dart Integration Tests](https://github.com/flutter/packages/blob/main/script/tool/README.md#run-dart-integration-tests) +for the latest documentation. + +### Web-specific options + +Use the following options to build and drive the integration examples on the web: + +* `--web` as platform +* `--packages pointer_interceptor_web` as package +* `--run-chromedriver` to start a `chromedriver` session from `drive-examples`. + +### Chromedriver + +**Make sure that you have `chromedriver` in your `$PATH`.** + +You may download the appropriate version of `chromedriver` for your OS and +Chrome version from the +[Chrome for Testing availability](https://googlechromelabs.github.io/chrome-for-testing/) +website. diff --git a/packages/pointer_interceptor/pointer_interceptor_web/example/pubspec.yaml b/packages/pointer_interceptor/pointer_interceptor_web/example/pubspec.yaml index 06625c07fbb7..91379dc20dc5 100644 --- a/packages/pointer_interceptor/pointer_interceptor_web/example/pubspec.yaml +++ b/packages/pointer_interceptor/pointer_interceptor_web/example/pubspec.yaml @@ -3,8 +3,8 @@ description: "Demonstrates how to use the pointer_interceptor_web 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 @@ -13,7 +13,7 @@ dependencies: pointer_interceptor_platform_interface: ^0.10.0 pointer_interceptor_web: path: ../../pointer_interceptor_web - web: ^0.5.0 + web: ^1.0.0 dev_dependencies: flutter_test: diff --git a/packages/pointer_interceptor/pointer_interceptor_web/example/web/index.html b/packages/pointer_interceptor/pointer_interceptor_web/example/web/index.html index 2720a1eaad86..064d7a356f47 100644 --- a/packages/pointer_interceptor/pointer_interceptor_web/example/web/index.html +++ b/packages/pointer_interceptor/pointer_interceptor_web/example/web/index.html @@ -34,21 +34,8 @@ example - - - - + diff --git a/packages/pointer_interceptor/pointer_interceptor_web/pubspec.yaml b/packages/pointer_interceptor/pointer_interceptor_web/pubspec.yaml index 83e41de9e23e..1aff36ce8ae8 100644 --- a/packages/pointer_interceptor/pointer_interceptor_web/pubspec.yaml +++ b/packages/pointer_interceptor/pointer_interceptor_web/pubspec.yaml @@ -2,11 +2,11 @@ name: pointer_interceptor_web description: Web implementation of the pointer_interceptor plugin. repository: https://github.com/flutter/packages/tree/main/packages/pointer_interceptor/pointer_interceptor_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3Apointer_interceptor -version: 0.10.2 +version: 0.10.2+1 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: @@ -23,7 +23,7 @@ dependencies: sdk: flutter plugin_platform_interface: ^2.1.7 pointer_interceptor_platform_interface: ^0.10.0 - web: ^0.5.0 + web: ">=0.5.1 <2.0.0" dev_dependencies: flutter_test: diff --git a/packages/process/CHANGELOG.md b/packages/process/CHANGELOG.md index f2b826c4b7b4..603c5efc8aec 100644 --- a/packages/process/CHANGELOG.md +++ b/packages/process/CHANGELOG.md @@ -1,6 +1,7 @@ -## NEXT +## 5.0.3 -* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. +* Adds `missing_code_block_language_in_doc_comment` lint. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 5.0.2 diff --git a/packages/process/lib/src/interface/process_manager.dart b/packages/process/lib/src/interface/process_manager.dart index ba1e2a1099ca..d506cdc20f03 100644 --- a/packages/process/lib/src/interface/process_manager.dart +++ b/packages/process/lib/src/interface/process_manager.dart @@ -57,11 +57,13 @@ abstract class ProcessManager { /// The following code uses `start` to grep for `main` in the /// file `test.dart` on Linux. /// - /// ProcessManager mgr = new LocalProcessManager(); - /// mgr.start(['grep', '-i', 'main', 'test.dart']).then((process) { - /// stdout.addStream(process.stdout); - /// stderr.addStream(process.stderr); - /// }); + /// ```dart + /// ProcessManager mgr = new LocalProcessManager(); + /// mgr.start(['grep', '-i', 'main', 'test.dart']).then((process) { + /// stdout.addStream(process.stdout); + /// stderr.addStream(process.stderr); + /// }); + /// ``` /// /// If [mode] is [ProcessStartMode.normal] (the default) a child /// process will be started with `stdin`, `stdout` and `stderr` @@ -130,11 +132,13 @@ abstract class ProcessManager { /// The following code uses `run` to grep for `main` in the /// file `test.dart` on Linux. /// - /// ProcessManager mgr = new LocalProcessManager(); - /// mgr.run('grep', ['-i', 'main', 'test.dart']).then((result) { - /// stdout.write(result.stdout); - /// stderr.write(result.stderr); - /// }); + /// ```dart + /// ProcessManager mgr = new LocalProcessManager(); + /// mgr.run('grep', ['-i', 'main', 'test.dart']).then((result) { + /// stdout.write(result.stdout); + /// stderr.write(result.stderr); + /// }); + /// ``` Future run( List command, { String? workingDirectory, diff --git a/packages/process/pubspec.yaml b/packages/process/pubspec.yaml index b00f5870dd3a..4c5296dc7da8 100644 --- a/packages/process/pubspec.yaml +++ b/packages/process/pubspec.yaml @@ -2,10 +2,10 @@ name: process description: A pluggable, mockable process invocation abstraction for Dart. repository: https://github.com/flutter/packages/tree/main/packages/process issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+process%22 -version: 5.0.2 +version: 5.0.3 environment: - sdk: ^3.2.0 + sdk: ^3.3.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 c0249a26b076..fdd1b7dd7393 100644 --- a/packages/quick_actions/quick_actions/CHANGELOG.md +++ b/packages/quick_actions/quick_actions/CHANGELOG.md @@ -1,7 +1,11 @@ ## NEXT -* Add localizedSubtitle field for iOS -* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. +* Add localizedSubtitle field for iOS + +## 1.0.8 + +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Adds reference to `quick_actions_android` README in the Android section of the README. ## 1.0.7 diff --git a/packages/quick_actions/quick_actions/README.md b/packages/quick_actions/quick_actions/README.md index 6175f1fd9e65..563349daab0f 100644 --- a/packages/quick_actions/quick_actions/README.md +++ b/packages/quick_actions/quick_actions/README.md @@ -52,3 +52,6 @@ If the drawables used as icons are not referenced other than in your Dart code, you may need to [explicitly mark them to be kept](https://developer.android.com/studio/build/shrink-code#keep-resources) to ensure that they will be available for use in release builds. + +For more information on using this package on Android, see the +[`quick_actions_android` README](https://github.com/flutter/packages/blob/main/packages/quick_actions/quick_actions_android/README.md). diff --git a/packages/quick_actions/quick_actions/example/android/app/build.gradle b/packages/quick_actions/quick_actions/example/android/app/build.gradle index 132e1b9618a8..0aab20bd886e 100644 --- a/packages/quick_actions/quick_actions/example/android/app/build.gradle +++ b/packages/quick_actions/quick_actions/example/android/app/build.gradle @@ -31,7 +31,7 @@ android { defaultConfig { applicationId "io.flutter.plugins.quickactionsexample" - minSdkVersion 21 + minSdkVersion flutter.minSdkVersion targetSdkVersion 28 versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/packages/quick_actions/quick_actions/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/quick_actions/quick_actions/example/android/app/gradle/wrapper/gradle-wrapper.properties index 609ab8e6c8b5..d951fac2bf31 100644 --- a/packages/quick_actions/quick_actions/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ b/packages/quick_actions/quick_actions/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/packages/quick_actions/quick_actions/example/android/build.gradle b/packages/quick_actions/quick_actions/example/android/build.gradle index cec92de922cf..0bed8906c094 100644 --- a/packages/quick_actions/quick_actions/example/android/build.gradle +++ b/packages/quick_actions/quick_actions/example/android/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath 'com.android.tools.build:gradle:8.5.2' } } diff --git a/packages/quick_actions/quick_actions/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/quick_actions/quick_actions/example/android/gradle/wrapper/gradle-wrapper.properties index e1ca574ef017..3c85cfe057a1 100644 --- a/packages/quick_actions/quick_actions/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/quick_actions/quick_actions/example/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/quick_actions/quick_actions/example/pubspec.yaml b/packages/quick_actions/quick_actions/example/pubspec.yaml index 1dc4fe2b14e5..054234593e6d 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: @@ -28,7 +28,7 @@ dependency_overrides: path: ../../../quick_actions/quick_actions_ios dev_dependencies: - espresso: ^0.2.0 + espresso: ^0.4.0 flutter_test: sdk: flutter integration_test: diff --git a/packages/quick_actions/quick_actions/pubspec.yaml b/packages/quick_actions/quick_actions/pubspec.yaml index 7ac65066d3a8..2d94a0cebc92 100644 --- a/packages/quick_actions/quick_actions/pubspec.yaml +++ b/packages/quick_actions/quick_actions/pubspec.yaml @@ -3,11 +3,11 @@ description: Flutter plugin for creating shortcuts on home screen, also known as Quick Actions on iOS and App Shortcuts on Android. repository: https://github.com/flutter/packages/tree/main/packages/quick_actions/quick_actions issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+quick_actions%22 -version: 1.0.7 +version: 1.0.8 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -29,7 +29,7 @@ dev_dependencies: sdk: flutter integration_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 plugin_platform_interface: ^2.1.7 topics: diff --git a/packages/quick_actions/quick_actions_android/CHANGELOG.md b/packages/quick_actions/quick_actions_android/CHANGELOG.md index 5b155e4b82cb..4ea1b250ffbe 100644 --- a/packages/quick_actions/quick_actions_android/CHANGELOG.md +++ b/packages/quick_actions/quick_actions_android/CHANGELOG.md @@ -1,3 +1,21 @@ +## 1.0.18 + +* Updates Java compatibility version to 11. +* Updates minimum supported SDK version to Flutter 3.24/Dart 3.5. + +## 1.0.17 + +* Updates README to include more specific context on how to use launcher activities, including + a full explanation for https://github.com/flutter/flutter/issues/152883. + +## 1.0.16 + +* Updates README to include guidance on using the plugin with a launcher activity. + +## 1.0.15 + +* Updates lint checks to ignore NewerVersionAvailable. + ## 1.0.14 * Updates AGP version to 8.4.1. diff --git a/packages/quick_actions/quick_actions_android/README.md b/packages/quick_actions/quick_actions_android/README.md index e42c6a6e39b5..a952e3840adf 100644 --- a/packages/quick_actions/quick_actions_android/README.md +++ b/packages/quick_actions/quick_actions_android/README.md @@ -11,10 +11,76 @@ 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. +## Usage with launcher activities + +If you have an activity that launches a `FlutterActivity` (this is +`MainActivity.java`/`MainActivity.kt` by default), then you might need to +modify the launch configuration of that activity to have the back press +behavior and task back stack that you expect. Common use cases of having +such a launcher activity are in an add to app project or if your Flutter +project contains multiple Android activities. + +For example, consider the case where you have two different quick actions +shortcuts for your app and a launcher activity that launches the +`FlutterActivity`. If the launcher activity uses the [`singleTop`][4] launch +mode (as Flutter's default `MainActivity.java`/`MainActivity.kt` do by default) +and the user + +1. Launches your app from the first shortcut +2. Moves your app into the background by exiting the app +3. Re-launches your app from the second shortcut + +then the user will see what the first shortcut launched, not what the second +shortcut was supposed to launch. To fix this, you may set the launch mode of +the launcher activity to `singleInstance` (see [Android documentation][5] for +more information on this mode) in +`your_app/android/app/src/mainAndroidManifest.xml`: + +```xml + +``` + +See [this issue][6] for more context on this exact scenario and its solution. + +Depending on your use case, you may additionally need to set the proper launch +mode `Intent` flags in the `Intent` that launches the `FlutterActivity` to +achieve your expected back press behavior and task back stack. For example, +if `MainActivity.java` is the `FlutterActivity` that your launcher activity +launches: + +```java +public final class LauncherActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Intent mainActivityIntent = new Intent(this, MainActivity.class); + mainActivityIntent.putExtras(getIntent()); + + // Add any additional launch mode Intent flags you need: + mainActivityIntent.addFlags(...); + + startActivity(mainActivityIntent); + finish(); + } + + ... +} +``` + +See [Tasks and the back stack][5] for more documentation about the different +launch modes and related `Intent` flags that Android provides. + ## Contributing If you would like to contribute to the plugin, check out our [contribution guide][3]. [1]: https://pub.dev/packages/quick_actions -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin [3]: https://github.com/flutter/packages/blob/main/CONTRIBUTING.md +[4]: https://developer.android.com/reference/android/content/Intent?authuser=1#FLAG_ACTIVITY_SINGLE_TOP +[5]: https://developer.android.com/guide/components/activities/tasks-and-back-stack#TaskLaunchModes +[6]: https://github.com/flutter/flutter/issues/152883#issuecomment-2305906933 diff --git a/packages/quick_actions/quick_actions_android/android/build.gradle b/packages/quick_actions/quick_actions_android/android/build.gradle index d791101025e8..2fbf82af56c2 100644 --- a/packages/quick_actions/quick_actions_android/android/build.gradle +++ b/packages/quick_actions/quick_actions_android/android/build.gradle @@ -22,10 +22,7 @@ rootProject.allprojects { apply plugin: 'com.android.library' android { - // Conditional for compatibility with AGP <4.2. - if (project.android.hasProperty("namespace")) { - namespace 'io.flutter.plugins.quickactions' - } + namespace 'io.flutter.plugins.quickactions' compileSdk 34 defaultConfig { @@ -35,7 +32,7 @@ android { lintOptions { checkAllWarnings true warningsAsErrors true - disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency' + disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency', 'NewerVersionAvailable' } dependencies { @@ -44,8 +41,8 @@ android { } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } testOptions { diff --git a/packages/quick_actions/quick_actions_android/example/android/app/build.gradle b/packages/quick_actions/quick_actions_android/example/android/app/build.gradle index 82f0366b547f..db8734cdfb5a 100644 --- a/packages/quick_actions/quick_actions_android/example/android/app/build.gradle +++ b/packages/quick_actions/quick_actions_android/example/android/app/build.gradle @@ -33,8 +33,8 @@ android { defaultConfig { applicationId "io.flutter.plugins.quickactionsexample" - minSdkVersion 21 - targetSdkVersion 28 + minSdkVersion flutter.minSdkVersion + targetSdkVersion 34 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/packages/quick_actions/quick_actions_android/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/quick_actions/quick_actions_android/example/android/app/gradle/wrapper/gradle-wrapper.properties index 609ab8e6c8b5..d951fac2bf31 100644 --- a/packages/quick_actions/quick_actions_android/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ b/packages/quick_actions/quick_actions_android/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/packages/quick_actions/quick_actions_android/example/android/app/src/main/AndroidManifest.xml b/packages/quick_actions/quick_actions_android/example/android/app/src/main/AndroidManifest.xml index 20969735d866..ff8a4d06bf42 100644 --- a/packages/quick_actions/quick_actions_android/example/android/app/src/main/AndroidManifest.xml +++ b/packages/quick_actions/quick_actions_android/example/android/app/src/main/AndroidManifest.xml @@ -5,6 +5,7 @@ =3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" dependencies: flutter: @@ -18,7 +18,7 @@ dependencies: path: ../ dev_dependencies: - espresso: ^0.2.0 + espresso: ^0.4.0 flutter_test: sdk: flutter integration_test: diff --git a/packages/quick_actions/quick_actions_android/pubspec.yaml b/packages/quick_actions/quick_actions_android/pubspec.yaml index 71df57ff5c10..b07c4d7cdce9 100644 --- a/packages/quick_actions/quick_actions_android/pubspec.yaml +++ b/packages/quick_actions/quick_actions_android/pubspec.yaml @@ -2,11 +2,11 @@ name: quick_actions_android description: An implementation for the Android platform of the Flutter `quick_actions` plugin. repository: https://github.com/flutter/packages/tree/main/packages/quick_actions/quick_actions_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+in_app_purchase%22 -version: 1.0.14 +version: 1.0.18 environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" flutter: plugin: diff --git a/packages/quick_actions/quick_actions_ios/CHANGELOG.md b/packages/quick_actions/quick_actions_ios/CHANGELOG.md index d70aed3c26a5..f24f6475df76 100644 --- a/packages/quick_actions/quick_actions_ios/CHANGELOG.md +++ b/packages/quick_actions/quick_actions_ios/CHANGELOG.md @@ -1,5 +1,6 @@ ## NEXT +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. * Add localizedSubtitle field ## 1.1.1 diff --git a/packages/quick_actions/quick_actions_ios/README.md b/packages/quick_actions/quick_actions_ios/README.md index e679fa01b4a7..e81fc6a4de07 100644 --- a/packages/quick_actions/quick_actions_ios/README.md +++ b/packages/quick_actions/quick_actions_ios/README.md @@ -16,5 +16,5 @@ should add it to your `pubspec.yaml` as usual. If you would like to contribute to the plugin, check out our [contribution guide][3]. [1]: https://pub.dev/packages/quick_actions -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin [3]: https://github.com/flutter/packages/blob/main/CONTRIBUTING.md diff --git a/packages/quick_actions/quick_actions_ios/example/pubspec.yaml b/packages/quick_actions/quick_actions_ios/example/pubspec.yaml index 1365fabd777b..17bb780b8b9b 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.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/quick_actions/quick_actions_ios/pubspec.yaml b/packages/quick_actions/quick_actions_ios/pubspec.yaml index e7a82a9ef115..ac0c00e0dcd9 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.1.1 environment: - sdk: ^3.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.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 607ba275f8fa..934386e6e6b6 100644 --- a/packages/quick_actions/quick_actions_platform_interface/CHANGELOG.md +++ b/packages/quick_actions/quick_actions_platform_interface/CHANGELOG.md @@ -1,7 +1,7 @@ ## NEXT +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. * Add localizedSubtitle field for iOS -* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. ## 1.0.6 diff --git a/packages/quick_actions/quick_actions_platform_interface/pubspec.yaml b/packages/quick_actions/quick_actions_platform_interface/pubspec.yaml index 5fec80c454b5..c9c05c64702f 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.0.6 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: @@ -18,7 +18,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 topics: - quick-actions diff --git a/packages/rfw/CHANGELOG.md b/packages/rfw/CHANGELOG.md index 532a7277ebf0..e3fbedffe13d 100644 --- a/packages/rfw/CHANGELOG.md +++ b/packages/rfw/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.0.30 + +* Adds `missing_code_block_language_in_doc_comment` lint. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + ## 1.0.29 * Adds support for the `Slider` Material widget. diff --git a/packages/rfw/example/hello/android/.gitignore b/packages/rfw/example/hello/android/.gitignore index 6f568019d3c6..55afd919c659 100644 --- a/packages/rfw/example/hello/android/.gitignore +++ b/packages/rfw/example/hello/android/.gitignore @@ -7,7 +7,7 @@ gradle-wrapper.jar GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. -# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +# See https://flutter.dev/to/reference-keystore key.properties **/*.keystore **/*.jks diff --git a/packages/rfw/example/hello/android/app/build.gradle b/packages/rfw/example/hello/android/app/build.gradle index 100a64244e12..5f291d55b6b2 100644 --- a/packages/rfw/example/hello/android/app/build.gradle +++ b/packages/rfw/example/hello/android/app/build.gradle @@ -30,12 +30,12 @@ android { compileSdk flutter.compileSdkVersion compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '11' } sourceSets { diff --git a/packages/rfw/example/hello/android/build.gradle b/packages/rfw/example/hello/android/build.gradle index 8a2e9e183dd7..ab596dbe21c5 100644 --- a/packages/rfw/example/hello/android/build.gradle +++ b/packages/rfw/example/hello/android/build.gradle @@ -1,12 +1,12 @@ buildscript { - ext.kotlin_version = '1.7.10' + ext.kotlin_version = '1.9.0' repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath 'com.android.tools.build:gradle:8.1.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/packages/rfw/example/hello/android/gradle/wrapper/gradle-wrapper.properties b/packages/rfw/example/hello/android/gradle/wrapper/gradle-wrapper.properties index aeaff6f869f3..7aeeb11c6ee5 100644 --- a/packages/rfw/example/hello/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/rfw/example/hello/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/rfw/example/hello/pubspec.yaml b/packages/rfw/example/hello/pubspec.yaml index 8ee7d4e425ed..54a79fd6effe 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/rfw/example/hello/web/index.html b/packages/rfw/example/hello/web/index.html index f8a21fb04c41..cb7cb5692278 100644 --- a/packages/rfw/example/hello/web/index.html +++ b/packages/rfw/example/hello/web/index.html @@ -36,72 +36,6 @@ - - + diff --git a/packages/rfw/example/local/android/.gitignore b/packages/rfw/example/local/android/.gitignore index 6f568019d3c6..55afd919c659 100644 --- a/packages/rfw/example/local/android/.gitignore +++ b/packages/rfw/example/local/android/.gitignore @@ -7,7 +7,7 @@ gradle-wrapper.jar GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. -# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +# See https://flutter.dev/to/reference-keystore key.properties **/*.keystore **/*.jks diff --git a/packages/rfw/example/local/android/app/build.gradle b/packages/rfw/example/local/android/app/build.gradle index 5bbaeffa4b31..0482ab4b404f 100644 --- a/packages/rfw/example/local/android/app/build.gradle +++ b/packages/rfw/example/local/android/app/build.gradle @@ -30,12 +30,12 @@ android { compileSdk flutter.compileSdkVersion compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '11' } sourceSets { diff --git a/packages/rfw/example/local/android/build.gradle b/packages/rfw/example/local/android/build.gradle index 8a2e9e183dd7..aae66ee04e46 100644 --- a/packages/rfw/example/local/android/build.gradle +++ b/packages/rfw/example/local/android/build.gradle @@ -1,12 +1,12 @@ buildscript { - ext.kotlin_version = '1.7.10' + ext.kotlin_version = '1.9.0' repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath 'com.android.tools.build:gradle:8.5.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/packages/rfw/example/local/android/gradle/wrapper/gradle-wrapper.properties b/packages/rfw/example/local/android/gradle/wrapper/gradle-wrapper.properties index aeaff6f869f3..7aeeb11c6ee5 100644 --- a/packages/rfw/example/local/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/rfw/example/local/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/rfw/example/local/pubspec.yaml b/packages/rfw/example/local/pubspec.yaml index 3c2e0d455fe0..7d05f298d00c 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/rfw/example/local/web/index.html b/packages/rfw/example/local/web/index.html index 6872e672fc4f..aab27dd0cbb6 100644 --- a/packages/rfw/example/local/web/index.html +++ b/packages/rfw/example/local/web/index.html @@ -36,72 +36,6 @@ - - + diff --git a/packages/rfw/example/remote/android/.gitignore b/packages/rfw/example/remote/android/.gitignore index 6f568019d3c6..55afd919c659 100644 --- a/packages/rfw/example/remote/android/.gitignore +++ b/packages/rfw/example/remote/android/.gitignore @@ -7,7 +7,7 @@ gradle-wrapper.jar GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. -# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +# See https://flutter.dev/to/reference-keystore key.properties **/*.keystore **/*.jks diff --git a/packages/rfw/example/remote/android/app/build.gradle b/packages/rfw/example/remote/android/app/build.gradle index 8ece05d61c0c..c0ae2d992f75 100644 --- a/packages/rfw/example/remote/android/app/build.gradle +++ b/packages/rfw/example/remote/android/app/build.gradle @@ -30,12 +30,12 @@ android { compileSdk flutter.compileSdkVersion compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '11' } sourceSets { diff --git a/packages/rfw/example/remote/android/build.gradle b/packages/rfw/example/remote/android/build.gradle index 8a2e9e183dd7..13648db310e1 100644 --- a/packages/rfw/example/remote/android/build.gradle +++ b/packages/rfw/example/remote/android/build.gradle @@ -1,12 +1,12 @@ buildscript { - ext.kotlin_version = '1.7.10' + ext.kotlin_version = '1.9.0' repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath 'com.android.tools.build:gradle:8.5.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/packages/rfw/example/remote/android/gradle/wrapper/gradle-wrapper.properties b/packages/rfw/example/remote/android/gradle/wrapper/gradle-wrapper.properties index aeaff6f869f3..7aeeb11c6ee5 100644 --- a/packages/rfw/example/remote/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/rfw/example/remote/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/rfw/example/remote/ios/Podfile b/packages/rfw/example/remote/ios/Podfile index 279576f3884f..01d4aa611bb9 100644 --- a/packages/rfw/example/remote/ios/Podfile +++ b/packages/rfw/example/remote/ios/Podfile @@ -29,7 +29,6 @@ flutter_ios_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) end diff --git a/packages/rfw/example/remote/macos/Podfile b/packages/rfw/example/remote/macos/Podfile index 049abe295427..ae77cc1d4269 100644 --- a/packages/rfw/example/remote/macos/Podfile +++ b/packages/rfw/example/remote/macos/Podfile @@ -28,7 +28,6 @@ flutter_macos_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) end diff --git a/packages/rfw/example/remote/pubspec.yaml b/packages/rfw/example/remote/pubspec.yaml index 7da73e4d4a52..946a8d00ac21 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/rfw/example/remote/web/index.html b/packages/rfw/example/remote/web/index.html index 2bcc056677ae..b11392f8b6ce 100644 --- a/packages/rfw/example/remote/web/index.html +++ b/packages/rfw/example/remote/web/index.html @@ -36,72 +36,6 @@ - - + diff --git a/packages/rfw/example/wasm/macos/Podfile b/packages/rfw/example/wasm/macos/Podfile index 049abe295427..ae77cc1d4269 100644 --- a/packages/rfw/example/wasm/macos/Podfile +++ b/packages/rfw/example/wasm/macos/Podfile @@ -28,7 +28,6 @@ flutter_macos_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) end diff --git a/packages/rfw/example/wasm/pubspec.yaml b/packages/rfw/example/wasm/pubspec.yaml index 07a4c0a4b3ec..04ebcb5402d3 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/rfw/lib/src/dart/binary.dart b/packages/rfw/lib/src/dart/binary.dart index cd999377f207..181760b2e6f9 100644 --- a/packages/rfw/lib/src/dart/binary.dart +++ b/packages/rfw/lib/src/dart/binary.dart @@ -115,7 +115,9 @@ Uint8List encodeLibraryBlob(RemoteWidgetLibrary value) { /// /// For example, the string "Hello" would be encoded as: /// -/// 05 00 00 00 00 00 00 00 48 65 6C 6C 6F +/// ```none +/// 05 00 00 00 00 00 00 00 48 65 6C 6C 6F +/// ``` /// /// * Lists are encoded as an integer length, followed by that many values /// back to back. When lists are of specific types (e.g. lists of imports), @@ -124,15 +126,19 @@ Uint8List encodeLibraryBlob(RemoteWidgetLibrary value) { /// followed by the value (tagged lists). For example, a list of integers with /// the values 1 and 2 in that order would be encoded as: /// -/// 02 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 -/// 02 00 00 00 00 00 00 00 +/// ```none +/// 02 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 +/// 02 00 00 00 00 00 00 00 +/// ``` /// /// A list of arbitrary values that happens to contain one string "Hello" /// would be encoded as follows; 0x04 is the tag for "String" (the full list /// of tags is described below): /// -/// 01 00 00 00 00 00 00 00 04 05 00 00 00 00 00 00 -/// 00 48 65 6C 6C 6F +/// ```none +/// 01 00 00 00 00 00 00 00 04 05 00 00 00 00 00 00 +/// 00 48 65 6C 6C 6F +/// ``` /// /// A list of length zero is eight zero bytes with no additional payload. /// @@ -147,8 +153,10 @@ Uint8List encodeLibraryBlob(RemoteWidgetLibrary value) { /// strings, so they are untagged) is encoded as follows (0x02 is the tag for /// integers): /// -/// 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 -/// 61 02 0F 00 00 00 00 00 00 00 +/// ```none +/// 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 +/// 61 02 0F 00 00 00 00 00 00 00 +/// ``` /// /// Objects are encoded as follows: /// @@ -159,8 +167,10 @@ Uint8List encodeLibraryBlob(RemoteWidgetLibrary value) { /// one of the subparts of the imported library name. For example, `import /// a.b` is encoded as: /// -/// 02 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 -/// 61 01 00 00 00 00 00 00 00 62 +/// ```none +/// 02 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 +/// 61 01 00 00 00 00 00 00 00 62 +/// ``` /// /// * Widget declarations are encoded as a string giving the declaration name, /// an untagged map for the initial state, and finally the value that @@ -220,7 +230,7 @@ Uint8List encodeLibraryBlob(RemoteWidgetLibrary value) { /// /// For example, this switch: /// -/// ``` +/// ```none /// switch (args.a) { /// 0: 'z', /// 1: 'o', @@ -230,11 +240,13 @@ Uint8List encodeLibraryBlob(RemoteWidgetLibrary value) { /// /// ...is encoded as follows (including the tag for the switch itself): /// -/// 0F 0A 01 00 00 00 00 00 00 00 61 03 00 00 00 00 -/// 00 00 00 02 00 00 00 00 00 00 00 00 04 01 00 00 -/// 00 00 00 00 00 7A 02 01 00 00 00 00 00 00 00 04 -/// 01 00 00 00 00 00 00 00 6F 10 04 01 00 00 00 00 -/// 00 00 00 64 +/// ```none +/// 0F 0A 01 00 00 00 00 00 00 00 61 03 00 00 00 00 +/// 00 00 00 02 00 00 00 00 00 00 00 00 04 01 00 00 +/// 00 00 00 00 00 7A 02 01 00 00 00 00 00 00 00 04 +/// 01 00 00 00 00 00 00 00 6F 10 04 01 00 00 00 00 +/// 00 00 00 64 +/// ``` /// /// * Event handlers have the tag 0x0E, and are encoded as a string /// ([EventHandler.eventName]) and an untagged map diff --git a/packages/rfw/lib/src/dart/text.dart b/packages/rfw/lib/src/dart/text.dart index 4db42dcfbe0d..2dc82c0283b5 100644 --- a/packages/rfw/lib/src/dart/text.dart +++ b/packages/rfw/lib/src/dart/text.dart @@ -139,7 +139,7 @@ import 'model.dart'; /// The numbers represented must be in the range -9,223,372,036,854,775,808 to /// 9,223,372,036,854,775,807. /// -/// ``` +/// ```bnf /// double ::= "-"? digit+ ("." digit+)? (("e" | "E") "-"? digit+)? /// ``` /// @@ -224,13 +224,13 @@ DynamicMap parseDataFile(String file) { /// /// Imports have this form: /// -/// ``` +/// ```none /// import library.name; /// ``` /// /// For example: /// -/// ``` +/// ```none /// import core.widgets; /// ``` /// @@ -245,7 +245,7 @@ DynamicMap parseDataFile(String file) { /// /// To declare a widget named A in terms of a widget B, the following form is used: /// -/// ``` +/// ```none /// widget A = B(); /// ``` /// @@ -253,14 +253,14 @@ DynamicMap parseDataFile(String file) { /// /// If the widget A is to be stateful, a map is inserted before the equals sign: /// -/// ``` +/// ```none /// widget A { } = B(); /// ``` /// /// The map describes the default values of the state. For example, a button /// might have a "down" state, which is initially false: /// -/// ``` +/// ```none /// widget Button { down: false } = Container(); /// ``` /// @@ -277,7 +277,7 @@ DynamicMap parseDataFile(String file) { /// /// In this example, several constructor calls are nested together: /// -/// ``` +/// ```none /// widget Foo = Column( /// children: [ /// Container( @@ -306,7 +306,7 @@ DynamicMap parseDataFile(String file) { /// /// In this example several widget builders are nested together: /// -/// ``` +/// ```none /// widget Foo {text: 'this is cool'} = Builder( /// builder: (foo) => Builder( /// builder: (bar) => Builder( @@ -374,21 +374,21 @@ DynamicMap parseDataFile(String file) { /// /// For example, suppose one instantiated a widget Foo as follows: /// -/// ``` +/// ```none /// Foo(name: "Bobbins") /// ``` /// /// ...then in the definition of Foo, one might pass the value of this "name" /// argument to another widget, say a Text widget, as follows: /// -/// ``` +/// ```none /// widget Foo = Text(text: args.name); /// ``` /// /// The arguments can have structure. For example, if the argument passed to Foo /// was: /// -/// ``` +/// ```none /// Foo(show: { name: "Cracking the Cryptic", phrase: "Bobbins" }) /// ``` /// @@ -396,7 +396,7 @@ DynamicMap parseDataFile(String file) { /// would specify an argument reference consisting of the values "show" and /// "phrase", as in `args.show.phrase`. For example: /// -/// ``` +/// ```none /// widget Foo = Text(text: args.show.phrase); /// ``` /// @@ -410,7 +410,7 @@ DynamicMap parseDataFile(String file) { /// doubles, bools, and strings (see [DynamicContent]). For example, if the data /// model looks like this: /// -/// ``` +/// ```none /// { server: { cart: [ { name: "Apple"}, { name: "Banana"} ] } /// ``` /// @@ -418,7 +418,7 @@ DynamicMap parseDataFile(String file) { /// would specify a data model reference consisting of the values "server", /// "cart", 1, and "name", as in `data.server.cart.1.name`. For example: /// -/// ``` +/// ```none /// Text(text: data.server.cart.1.name) /// ``` /// @@ -433,7 +433,7 @@ DynamicMap parseDataFile(String file) { /// A widget that shows all the values from a list in a [ListView] might look /// like this: /// -/// ``` +/// ```none /// widget Items = ListView( /// children: [ /// ...for item in args.list: @@ -444,7 +444,7 @@ DynamicMap parseDataFile(String file) { /// /// Such a widget would be used like this: /// -/// ``` +/// ```none /// Items(list: [ "Hello", "World" ]) /// ``` /// @@ -461,7 +461,7 @@ DynamicMap parseDataFile(String file) { /// Loop references use the _ident_. In the example above, that is `item`. In /// more elaborate examples, it can include subreferences. For example: /// -/// ``` +/// ```none /// widget Items = ListView( /// children: [ /// Text(text: 'Products:'), @@ -474,7 +474,7 @@ DynamicMap parseDataFile(String file) { /// /// This might be used as follows: /// -/// ``` +/// ```none /// Items(products: [ /// { name: { abbreviation: "TI4", displayName: "Twilight Imperium IV" }, price: 120.0 }, /// { name: { abbreviation: "POK", displayName: "Prophecy of Kings" }, price: 100.0 }, @@ -490,7 +490,7 @@ DynamicMap parseDataFile(String file) { /// Here a button is described as having a "down" state whose first value is /// "false": /// -/// ``` +/// ```none /// widget Button { down: false } = Container( /// // ... /// ); @@ -503,7 +503,7 @@ DynamicMap parseDataFile(String file) { /// Here, the button's state is referenced (in a pretty nonsensical way; /// controlling whether its label wraps based on the value of the state): /// -/// ``` +/// ```none /// widget Button { down: false } = Container( /// child: Text(text: 'Hello World', softWrap: state.down), /// ); @@ -523,7 +523,7 @@ DynamicMap parseDataFile(String file) { /// /// The syntax for a switch uses the following form: /// -/// ``` +/// ```none /// switch value { /// case1: template1, /// case2: template2, @@ -546,7 +546,7 @@ DynamicMap parseDataFile(String file) { /// appeared pressed when the "down" state was true (but note that we still /// don't have anything to toggle that state!): /// -/// ``` +/// ```none /// widget Button { down: false } = Container( /// margin: switch state.down { /// false: [ 0.0, 0.0, 8.0, 8.0 ], @@ -565,7 +565,7 @@ DynamicMap parseDataFile(String file) { /// /// Signalling event handlers have a name and an arguments map: /// -/// ``` +/// ```none /// event "..." { } /// ``` /// @@ -575,7 +575,7 @@ DynamicMap parseDataFile(String file) { /// For example, the event handler in the following sequence sends the event /// called "hello" with a map containing just one key, "id", whose value is 1: /// -/// ``` +/// ```none /// Button( /// onPressed: event "hello" { id: 1 }, /// child: Text(text: "Greetings"), @@ -586,7 +586,7 @@ DynamicMap parseDataFile(String file) { /// to assign to that state. Such handlers are only meaningful within widgets /// that have state, as described above. They have this form: /// -/// ``` +/// ```none /// set state.foo.bar = value /// ``` /// @@ -595,7 +595,7 @@ DynamicMap parseDataFile(String file) { /// /// This lets us finish the earlier button: /// -/// ``` +/// ```none /// widget Button { down: false } = GestureDetector( /// onTapDown: set state.down = true, /// onTapUp: set state.down = false, @@ -2065,7 +2065,6 @@ Iterable<_Token> _tokenize(String file) sync* { default: // ignored, comment mode = _TokenizerMode.blockComment; - break; } } } diff --git a/packages/rfw/lib/src/flutter/material_widgets.dart b/packages/rfw/lib/src/flutter/material_widgets.dart index 16132b1ad3cd..55ef96e1e541 100644 --- a/packages/rfw/lib/src/flutter/material_widgets.dart +++ b/packages/rfw/lib/src/flutter/material_widgets.dart @@ -64,10 +64,16 @@ import 'runtime.dart'; /// be supported. As a result, the following `ButtonBar` parameters are no longer /// supported: /// +// TODO(kallentu): Remove ignore and fix when stable is bumped. +// https://github.com/flutter/flutter/issues/157620 +// ignore: missing_code_block_language_in_doc_comment /// * `buttonMinWidth` /// * `buttonHeight` /// * `buttonAlignedDropdown` /// +// TODO(kallentu): Remove ignore and fix when stable is bumped. +// https://github.com/flutter/flutter/issues/157620 +// ignore: missing_code_block_language_in_doc_comment /// It is recommended to use the [OverflowBar] widget. /// /// Some features are not supported: diff --git a/packages/rfw/pubspec.yaml b/packages/rfw/pubspec.yaml index 5f217590123e..76afa865e101 100644 --- a/packages/rfw/pubspec.yaml +++ b/packages/rfw/pubspec.yaml @@ -2,11 +2,11 @@ name: rfw description: "Remote Flutter widgets: a library for rendering declarative widget description files at runtime." repository: https://github.com/flutter/packages/tree/main/packages/rfw issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+rfw%22 -version: 1.0.29 +version: 1.0.30 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/rfw/test/argument_decoders_test.dart b/packages/rfw/test/argument_decoders_test.dart index 8564db5002dd..7da1e01aae71 100644 --- a/packages/rfw/test/argument_decoders_test.dart +++ b/packages/rfw/test/argument_decoders_test.dart @@ -376,7 +376,9 @@ void main() { await expectLater( find.byType(RemoteWidget), matchesGoldenFile('goldens/argument_decoders_test.containers.png'), - skip: !runGoldens, + // TODO(louisehsu): Unskip once golden file is updated. See + // https://github.com/flutter/flutter/issues/151995 + skip: !runGoldens || true, ); expect(find.byType(DecoratedBox), findsNWidgets(6)); const String matrix = kIsWeb ? '1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1' @@ -390,7 +392,7 @@ void main() { expect( (tester.widgetList(find.byType(DecoratedBox)).toList()[0].decoration as BoxDecoration).image.toString(), 'DecorationImage(NetworkImage("x-invalid://", scale: 1.0), ' - 'ColorFilter.mode(Color(0xff8811ff), BlendMode.xor), Alignment.center, scale 1.0, ' + 'ColorFilter.mode(${const Color(0xff8811ff)}, BlendMode.xor), Alignment.center, scale 1.0, ' 'opacity 1.0, FilterQuality.high)', ); diff --git a/packages/rfw/test/goldens/argument_decoders_test.containers.png b/packages/rfw/test/goldens/argument_decoders_test.containers.png index e8dc0c15a321..79f5619b2c12 100644 Binary files a/packages/rfw/test/goldens/argument_decoders_test.containers.png and b/packages/rfw/test/goldens/argument_decoders_test.containers.png differ diff --git a/packages/rfw/test/goldens/argument_decoders_test.text.png b/packages/rfw/test/goldens/argument_decoders_test.text.png index 8bd73041bf6e..48a3177fef2b 100644 Binary files a/packages/rfw/test/goldens/argument_decoders_test.text.png and b/packages/rfw/test/goldens/argument_decoders_test.text.png differ diff --git a/packages/rfw/test/goldens/material_test.button_bar_properties.overflow.png b/packages/rfw/test/goldens/material_test.button_bar_properties.overflow.png index fd7791a960ad..79071ea0d758 100644 Binary files a/packages/rfw/test/goldens/material_test.button_bar_properties.overflow.png and b/packages/rfw/test/goldens/material_test.button_bar_properties.overflow.png differ diff --git a/packages/rfw/test/goldens/material_test.button_bar_properties.png b/packages/rfw/test/goldens/material_test.button_bar_properties.png index f47d0f336669..14de2b3f2e8d 100644 Binary files a/packages/rfw/test/goldens/material_test.button_bar_properties.png and b/packages/rfw/test/goldens/material_test.button_bar_properties.png differ diff --git a/packages/rfw/test/goldens/material_test.drawer.png b/packages/rfw/test/goldens/material_test.drawer.png index 38444dad6a19..da58d124461c 100644 Binary files a/packages/rfw/test/goldens/material_test.drawer.png and b/packages/rfw/test/goldens/material_test.drawer.png differ diff --git a/packages/rfw/test/goldens/material_test.dropdown.png b/packages/rfw/test/goldens/material_test.dropdown.png index 80011c9f676d..7f4fa707e9b0 100644 Binary files a/packages/rfw/test/goldens/material_test.dropdown.png and b/packages/rfw/test/goldens/material_test.dropdown.png differ diff --git a/packages/rfw/test/goldens/material_test.ink_response_hover.png b/packages/rfw/test/goldens/material_test.ink_response_hover.png index 3156e657805b..9aefc7847806 100644 Binary files a/packages/rfw/test/goldens/material_test.ink_response_hover.png and b/packages/rfw/test/goldens/material_test.ink_response_hover.png differ diff --git a/packages/rfw/test/goldens/material_test.ink_response_tap.png b/packages/rfw/test/goldens/material_test.ink_response_tap.png index ea22b4cd4a30..53b307986e0c 100644 Binary files a/packages/rfw/test/goldens/material_test.ink_response_tap.png and b/packages/rfw/test/goldens/material_test.ink_response_tap.png differ diff --git a/packages/rfw/test/goldens/material_test.material_properties.png b/packages/rfw/test/goldens/material_test.material_properties.png index c7de8515b4c6..fd9fee4fd4ab 100644 Binary files a/packages/rfw/test/goldens/material_test.material_properties.png and b/packages/rfw/test/goldens/material_test.material_properties.png differ diff --git a/packages/rfw/test/goldens/material_test.overflow_bar_properties.png b/packages/rfw/test/goldens/material_test.overflow_bar_properties.png index fad2df99e9d1..1fabcca39cc1 100644 Binary files a/packages/rfw/test/goldens/material_test.overflow_bar_properties.png and b/packages/rfw/test/goldens/material_test.overflow_bar_properties.png differ diff --git a/packages/rfw/test/goldens/material_test.overflow_bar_resembles_button_bar.png b/packages/rfw/test/goldens/material_test.overflow_bar_resembles_button_bar.png index caba08310f0e..cbb7d1a07a0a 100644 Binary files a/packages/rfw/test/goldens/material_test.overflow_bar_resembles_button_bar.png and b/packages/rfw/test/goldens/material_test.overflow_bar_resembles_button_bar.png differ diff --git a/packages/rfw/test/goldens/material_test.scaffold.png b/packages/rfw/test/goldens/material_test.scaffold.png index c0e1c74778cd..044ea53ef9d8 100644 Binary files a/packages/rfw/test/goldens/material_test.scaffold.png and b/packages/rfw/test/goldens/material_test.scaffold.png differ diff --git a/packages/rfw/test/material_widgets_test.dart b/packages/rfw/test/material_widgets_test.dart index f6ad700ed480..648d7249d0fb 100644 --- a/packages/rfw/test/material_widgets_test.dart +++ b/packages/rfw/test/material_widgets_test.dart @@ -9,6 +9,8 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:rfw/formats.dart' show parseLibraryFile; import 'package:rfw/rfw.dart'; +import 'tolerant_comparator.dart' + if (dart.library.js_interop) 'tolerant_comparator_web.dart'; import 'utils.dart'; void main() { @@ -22,6 +24,13 @@ void main() { ..update(materialName, createMaterialWidgets()); } + setUpAll(() { + setUpTolerantComparator( + testPath: 'test/material_widget_test.dart', + precisionTolerance: 0.00002, + ); + }); + testWidgets('Material widgets', (WidgetTester tester) async { final Runtime runtime = setupRuntime(); final DynamicContent data = DynamicContent(); @@ -194,7 +203,9 @@ void main() { await expectLater( find.byType(RemoteWidget), matchesGoldenFile('goldens/material_test.scaffold.png'), - skip: !runGoldens, + // TODO(louisehsu): Unskip once golden file is updated. See + // https://github.com/flutter/flutter/issues/151995 + skip: !runGoldens || true, ); await tester.tap(find.byType(DropdownButton).first); @@ -202,8 +213,8 @@ void main() { await expectLater( find.byType(MaterialApp), matchesGoldenFile('goldens/material_test.dropdown.png'), - // TODO(bparrishMines): Unskip once golden file is updated. See - // https://github.com/flutter/flutter/issues/150127 + // TODO(louisehsu): Unskip once golden file is updated. See + // https://github.com/flutter/flutter/issues/151995 skip: !runGoldens || true, ); // Tap on the second item. @@ -291,7 +302,9 @@ void main() { await expectLater( find.byType(RemoteWidget), matchesGoldenFile('goldens/material_test.button_bar_properties.png'), - skip: !runGoldens, + // TODO(louisehsu): Unskip once golden file is updated. See + // https://github.com/flutter/flutter/issues/151995 + skip: !runGoldens || true, ); // Update the surface size for ButtonBar to overflow. @@ -363,7 +376,9 @@ void main() { find.byType(RemoteWidget), matchesGoldenFile( 'goldens/material_test.overflow_bar_resembles_button_bar.png'), - skip: !runGoldens, + // TODO(louisehsu): Unskip once golden file is updated. See + // https://github.com/flutter/flutter/issues/151995 + skip: !runGoldens || true, ); }); @@ -438,7 +453,9 @@ void main() { find.byType(RemoteWidget), matchesGoldenFile( 'goldens/material_test.overflow_bar_properties.overflow.png'), - skip: !runGoldens, + // TODO(louisehsu): Unskip once golden file is updated. See + // https://github.com/flutter/flutter/issues/151995 + skip: !runGoldens || true, ); }); @@ -568,8 +585,8 @@ void main() { await expectLater( find.byType(RemoteWidget), matchesGoldenFile('goldens/material_test.material_properties.png'), - // TODO(bparrishMines): Unskip once golden file is updated. See - // https://github.com/flutter/flutter/issues/150127 + // TODO(louisehsu): Unskip once golden file is updated. See + // https://github.com/flutter/flutter/issues/151995 skip: !runGoldens || true, ); diff --git a/packages/rfw/test/tolerant_comparator.dart b/packages/rfw/test/tolerant_comparator.dart new file mode 100644 index 000000000000..0c8cbee97c3a --- /dev/null +++ b/packages/rfw/test/tolerant_comparator.dart @@ -0,0 +1,56 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/foundation.dart'; +import 'package:flutter_test/flutter_test.dart'; + +/// Sets [_TolerantGoldenFileComparator] as the default golden file comparator +/// in tests. +void setUpTolerantComparator( + {required String testPath, required double precisionTolerance}) { + final GoldenFileComparator oldComparator = goldenFileComparator; + final _TolerantGoldenFileComparator newComparator = + _TolerantGoldenFileComparator(Uri.parse(testPath), + precisionTolerance: precisionTolerance); + + goldenFileComparator = newComparator; + + addTearDown(() => goldenFileComparator = oldComparator); +} + +class _TolerantGoldenFileComparator extends LocalFileComparator { + _TolerantGoldenFileComparator( + super.testFile, { + required double precisionTolerance, + }) : assert( + 0 <= precisionTolerance && precisionTolerance <= 1, + 'precisionTolerance must be between 0 and 1', + ), + _precisionTolerance = precisionTolerance; + + /// How much the golden image can differ from the test image. + /// + /// It is expected to be between 0 and 1. Where 0 is no difference (the same image) + /// and 1 is the maximum difference (completely different images). + final double _precisionTolerance; + + @override + Future compare(Uint8List imageBytes, Uri golden) async { + final ComparisonResult result = await GoldenFileComparator.compareLists( + imageBytes, + await getGoldenBytes(golden), + ); + + final bool passed = + result.passed || result.diffPercent <= _precisionTolerance; + if (passed) { + result.dispose(); + return true; + } + + final String error = await generateFailureOutput(result, golden, basedir); + result.dispose(); + throw FlutterError(error); + } +} diff --git a/packages/rfw/test/tolerant_comparator_web.dart b/packages/rfw/test/tolerant_comparator_web.dart new file mode 100644 index 000000000000..7de664968712 --- /dev/null +++ b/packages/rfw/test/tolerant_comparator_web.dart @@ -0,0 +1,6 @@ +// 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. + +void setUpTolerantComparator( + {required String testPath, required double precisionTolerance}) {} diff --git a/packages/rfw/test_coverage/pubspec.yaml b/packages/rfw/test_coverage/pubspec.yaml index 6c7624364f7e..bb29e27c7543 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.2.0 + sdk: ^3.3.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 80572617fd64..717cfdcd80d7 100644 --- a/packages/shared_preferences/shared_preferences/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences/CHANGELOG.md @@ -1,5 +1,15 @@ -## NEXT +## 2.3.2 +* Removes outdated testing information from README. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + +## 2.3.1 + +* Fixes `getStringList` bug with `List` cast exception. + +## 2.3.0 + +* Adds `SharedPreferencesAsync` and `SharedPreferencesWithCache` APIs. * Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. ## 2.2.3 diff --git a/packages/shared_preferences/shared_preferences/README.md b/packages/shared_preferences/shared_preferences/README.md index 735959662392..520de19323cc 100644 --- a/packages/shared_preferences/shared_preferences/README.md +++ b/packages/shared_preferences/shared_preferences/README.md @@ -16,11 +16,49 @@ Supported data types are `int`, `double`, `bool`, `String` and `List`. | **Support** | SDK 16+ | 12.0+ | Any | 10.14+ | Any | Any | ## Usage -To use this plugin, add `shared_preferences` as a [dependency in your pubspec.yaml file](https://flutter.dev/docs/development/platform-integration/platform-channels). -### Examples +## SharedPreferences vs SharedPreferencesAsync vs SharedPreferencesWithCache + +Starting with version 2.3.0 there are three available APIs that can be used in this package. +[SharedPreferences] is a legacy API that will be deprecated in the future. We highly encourage +any new users of the plugin to use the newer [SharedPreferencesAsync] or [SharedPreferencesWithCache] +APIs instead. + +Consider migrating existing code to one of the new APIs. See [below](#migrating-from-sharedpreferences-to-sharedpreferencesasyncwithcache) +for more information. + +### Cache and async or sync getters + +[SharedPreferences] and [SharedPreferencesWithCache] both use a local cache to store preferences. +This allows for synchronous get calls after the initial setup call fetches the preferences from the platform. +However, The cache can present issues as well: + +- If you are using `shared_preferences` from multiple isolates, since each + isolate has its own singleton and cache. +- If you are using `shared_preferences` in multiple engine instances (including + those created by plugins that create background contexts on mobile devices, + such as `firebase_messaging`). +- If you are modifying the underlying system preference store through something + other than the `shared_preferences` plugin, such as native code. + +This can be remedied by calling the `reload` method before using a getter as needed. +If most get calls need a reload, consider using [SharedPreferencesAsync] instead. + +[SharedPreferencesAsync] does not utilize a local cache which causes all calls to be asynchronous +calls to the host platforms storage solution. This can be less performant, but should always provide the +latest data stored on the native platform regardless of what process was used to store it. + +### Android platform storage + +The [SharedPreferences] API uses the native [Android Shared Preferences](https://developer.android.com/reference/android/content/SharedPreferences) tool to store data. + +The [SharedPreferencesAsync] and [SharedPreferencesWithCache] APIs use [DataStore Preferences](https://developer.android.com/topic/libraries/architecture/datastore) to store data. + +## Examples Here are small examples that show you how to use the API. +### SharedPreferences + #### Write data ```dart @@ -61,32 +99,67 @@ final List? items = prefs.getStringList('items'); await prefs.remove('counter'); ``` -### Multiple instances +### SharedPreferencesAsync + +```dart +final SharedPreferencesAsync asyncPrefs = SharedPreferencesAsync(); -In order to make preference lookup via the `get*` methods synchronous, -`shared_preferences` uses a cache on the Dart side, which is normally only -updated by the `set*` methods. Usually this is an implementation detail that -does not affect callers, but it can cause issues in a few cases: -- If you are using `shared_preferences` from multiple isolates, since each - isolate has its own `SharedPreferences` singleton and cache. -- If you are using `shared_preferences` in multiple engine instances (including - those created by plugins that create background contexts on mobile devices, - such as `firebase_messaging`). -- If you are modifying the underlying system preference store through something - other than the `shared_preferences` plugin, such as native code. +await asyncPrefs.setBool('repeat', true); +await asyncPrefs.setString('action', 'Start'); + +final bool? repeat = await asyncPrefs.getBool('repeat'); +final String? action = await asyncPrefs.getString('action'); + +await asyncPrefs.remove('repeat'); + +// Any time a filter option is included as a method parameter, strongly consider +// using it to avoid potentially unwanted side effects. +await asyncPrefs.clear(allowList: {'action', 'repeat'}); +``` -If you need to read a preference value that may have been changed by anything -other than the `SharedPreferences` instance you are reading it from, you should -call `reload()` on the instance before reading from it to update its cache with -any external changes. +### SharedPreferencesWithCache + +```dart +final SharedPreferencesWithCache prefsWithCache = + await SharedPreferencesWithCache.create( + cacheOptions: const SharedPreferencesWithCacheOptions( + // When an allowlist is included, any keys that aren't included cannot be used. + allowList: {'repeat', 'action'}, + ), +); + +await prefsWithCache.setBool('repeat', true); +await prefsWithCache.setString('action', 'Start'); + +final bool? repeat = prefsWithCache.getBool('repeat'); +final String? action = prefsWithCache.getString('action'); + +await prefsWithCache.remove('repeat'); + +// Since the filter options are set at creation, they aren't needed during clear. +await prefsWithCache.clear(); +``` -If this is problematic for your use case, you can thumbs up -[this issue](https://github.com/flutter/flutter/issues/123078) to express -interest in APIs that provide direct (asynchronous) access to the underlying -preference store, and/or subscribe to it for updates. ### Migration and Prefixes +#### Migrating from SharedPreferences to SharedPreferencesAsync/WithCache + +Currently, migration from the older [SharedPreferences] API to the newer +[SharedPreferencesAsync] or [SharedPreferencesWithCache] will need to be done manually. + +A simple form of this could be fetching all preferences with [SharedPreferences] and adding +them back using [SharedPreferencesAsync], then storing a preference indicating that the +migration has been done so that future runs don't repeat the migration. + +If a migration is not performed before moving to [SharedPreferencesAsync] or [SharedPreferencesWithCache], +most (if not all) data will be lost. Android preferences are stored in a new system, and all platforms +are likely to have some form of enforced prefix (see below) that would not transfer automatically. + +A tool to make this process easier can be tracked here: https://github.com/flutter/flutter/issues/150732 + +#### Adding, Removing, or changing prefixes on SharedPreferences + By default, the `SharedPreferences` plugin will only read (and write) preferences that begin with the prefix `flutter.`. This is all handled internally by the plugin and does not require manually adding this prefix. @@ -110,25 +183,13 @@ If you have been using `SharedPreferences` with the default prefix but wish to c to a new prefix, you will need to transform your current preferences manually to add the new prefix otherwise the old preferences will be inaccessible. -### Testing - -In tests, you can replace the standard `SharedPreferences` implementation with -a mock implementation with initial values. This implementation is in-memory -only, and will not persist values to the usual preference store. - - -```dart -final Map values = {'counter': 1}; -SharedPreferences.setMockInitialValues(values); -``` - ### Storage location by platform -| Platform | Location | -| :--- | :--- | -| Android | SharedPreferences | -| iOS | NSUserDefaults | -| Linux | In the XDG_DATA_HOME directory | -| macOS | NSUserDefaults | -| Web | LocalStorage | -| Windows | In the roaming AppData directory | +| Platform | SharedPreferences | SharedPreferencesAsync/WithCache | +| :--- | :--- | :--- | +| Android | SharedPreferences | DataStore Preferences | +| iOS | NSUserDefaults | NSUserDefaults | +| Linux | In the XDG_DATA_HOME directory | In the XDG_DATA_HOME directory | +| macOS | NSUserDefaults | NSUserDefaults | +| Web | LocalStorage | LocalStorage | +| Windows | In the roaming AppData directory | In the roaming AppData directory | diff --git a/packages/shared_preferences/shared_preferences/example/android/.gitignore b/packages/shared_preferences/shared_preferences/example/android/.gitignore index 0a741cb43d66..8e599af9f211 100644 --- a/packages/shared_preferences/shared_preferences/example/android/.gitignore +++ b/packages/shared_preferences/shared_preferences/example/android/.gitignore @@ -7,5 +7,5 @@ gradle-wrapper.jar GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. -# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +# See https://flutter.dev/to/reference-keystore key.properties diff --git a/packages/shared_preferences/shared_preferences/example/android/build.gradle b/packages/shared_preferences/shared_preferences/example/android/build.gradle index d13ef556e261..510b513a8157 100644 --- a/packages/shared_preferences/shared_preferences/example/android/build.gradle +++ b/packages/shared_preferences/shared_preferences/example/android/build.gradle @@ -1,12 +1,12 @@ buildscript { - ext.kotlin_version = '1.7.10' + ext.kotlin_version = '1.9.0' repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath 'com.android.tools.build:gradle:8.5.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/packages/shared_preferences/shared_preferences/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/shared_preferences/shared_preferences/example/android/gradle/wrapper/gradle-wrapper.properties index aeaff6f869f3..7aeeb11c6ee5 100644 --- a/packages/shared_preferences/shared_preferences/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/shared_preferences/shared_preferences/example/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart index 443ac6fc4a79..504ad899e187 100644 --- a/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart @@ -19,147 +19,661 @@ void main() { const bool testBool2 = false; const int testInt2 = 1337; const double testDouble2 = 2.71828; - const List testList2 = ['baz', 'quox']; - - late SharedPreferences preferences; - - void runAllTests() { - testWidgets('reading', (WidgetTester _) async { - expect(preferences.get('String'), isNull); - expect(preferences.get('bool'), isNull); - expect(preferences.get('int'), isNull); - expect(preferences.get('double'), isNull); - expect(preferences.get('List'), isNull); - expect(preferences.getString('String'), isNull); - expect(preferences.getBool('bool'), isNull); - expect(preferences.getInt('int'), isNull); - expect(preferences.getDouble('double'), isNull); - expect(preferences.getStringList('List'), isNull); - }); + const List testList2 = ['baz', 'qux']; - testWidgets('writing', (WidgetTester _) async { - await Future.wait(>[ - preferences.setString('String', testString2), - preferences.setBool('bool', testBool2), - preferences.setInt('int', testInt2), - preferences.setDouble('double', testDouble2), - preferences.setStringList('List', testList2) - ]); - expect(preferences.getString('String'), testString2); - expect(preferences.getBool('bool'), testBool2); - expect(preferences.getInt('int'), testInt2); - expect(preferences.getDouble('double'), testDouble2); - expect(preferences.getStringList('List'), testList2); - }); + group('shared_preferences', () { + late SharedPreferences preferences; - testWidgets('removing', (WidgetTester _) async { - const String key = 'testKey'; - await preferences.setString(key, testString); - await preferences.setBool(key, testBool); - await preferences.setInt(key, testInt); - await preferences.setDouble(key, testDouble); - await preferences.setStringList(key, testList); - await preferences.remove(key); - expect(preferences.get('testKey'), isNull); - }); + void runAllTests() { + testWidgets('set and get String', (WidgetTester _) async { + expect(preferences.get('String'), isNull); + await preferences.setString('String', testString2); + expect(preferences.getString('String'), testString2); + }); - testWidgets('clearing', (WidgetTester _) async { - await preferences.setString('String', testString); - await preferences.setBool('bool', testBool); - await preferences.setInt('int', testInt); - await preferences.setDouble('double', testDouble); - await preferences.setStringList('List', testList); - await preferences.clear(); - expect(preferences.getString('String'), null); - expect(preferences.getBool('bool'), null); - expect(preferences.getInt('int'), null); - expect(preferences.getDouble('double'), null); - expect(preferences.getStringList('List'), null); - }); + testWidgets('set and get Bool', (WidgetTester _) async { + expect(preferences.get('Bool'), isNull); + await preferences.setBool('Bool', testBool2); + expect(preferences.getBool('Bool'), testBool2); + }); - testWidgets('simultaneous writes', (WidgetTester _) async { - final List> writes = >[]; - const int writeCount = 100; - for (int i = 1; i <= writeCount; i++) { - writes.add(preferences.setInt('int', i)); - } - final List result = await Future.wait(writes, eagerError: true); - // All writes should succeed. - expect(result.where((bool element) => !element), isEmpty); - // The last write should win. - expect(preferences.getInt('int'), writeCount); - }); - } + testWidgets('set and get Int', (WidgetTester _) async { + expect(preferences.get('Int'), isNull); + await preferences.setInt('Int', testInt2); + expect(preferences.getInt('Int'), testInt2); + }); + + testWidgets('set and get Double', (WidgetTester _) async { + expect(preferences.get('Double'), isNull); + await preferences.setDouble('Double', testDouble2); + expect(preferences.getDouble('Double'), testDouble2); + }); - group('SharedPreferences', () { - setUp(() async { - preferences = await SharedPreferences.getInstance(); + testWidgets('set and get StringList', (WidgetTester _) async { + expect(preferences.get('StringList'), isNull); + await preferences.setStringList('StringList', testList2); + expect(preferences.getStringList('StringList'), testList2); + }); + + testWidgets('removing', (WidgetTester _) async { + const String key = 'testKey'; + await preferences.setString(key, testString); + await preferences.remove(key); + expect(preferences.get('testKey'), isNull); + }); + + testWidgets('clearing', (WidgetTester _) async { + await preferences.setString('String', testString); + await preferences.setBool('bool', testBool); + await preferences.setInt('int', testInt); + await preferences.setDouble('double', testDouble); + await preferences.setStringList('List', testList); + await preferences.clear(); + expect(preferences.getString('String'), null); + expect(preferences.getBool('bool'), null); + expect(preferences.getInt('int'), null); + expect(preferences.getDouble('double'), null); + expect(preferences.getStringList('List'), null); + }); + + testWidgets('simultaneous writes', (WidgetTester _) async { + final List> writes = >[]; + const int writeCount = 100; + for (int i = 1; i <= writeCount; i++) { + writes.add(preferences.setInt('int', i)); + } + final List result = await Future.wait(writes, eagerError: true); + // All writes should succeed. + expect(result.where((bool element) => !element), isEmpty); + // The last write should win. + expect(preferences.getInt('int'), writeCount); + }); + } + + group('SharedPreferences', () { + setUp(() async { + preferences = await SharedPreferences.getInstance(); + }); + + tearDown(() async { + await preferences.clear(); + SharedPreferences.resetStatic(); + }); + + runAllTests(); }); - tearDown(() async { - await preferences.clear(); - SharedPreferences.resetStatic(); + group('setPrefix', () { + setUp(() async { + SharedPreferences.resetStatic(); + SharedPreferences.setPrefix('prefix.'); + preferences = await SharedPreferences.getInstance(); + }); + + tearDown(() async { + await preferences.clear(); + SharedPreferences.resetStatic(); + }); + + runAllTests(); }); - runAllTests(); - }); + group('setNoPrefix', () { + setUp(() async { + SharedPreferences.resetStatic(); + SharedPreferences.setPrefix(''); + preferences = await SharedPreferences.getInstance(); + }); - group('setPrefix', () { - setUp(() async { - SharedPreferences.resetStatic(); - SharedPreferences.setPrefix('prefix.'); - preferences = await SharedPreferences.getInstance(); + tearDown(() async { + await preferences.clear(); + SharedPreferences.resetStatic(); + }); + + runAllTests(); }); - tearDown(() async { - await preferences.clear(); + testWidgets('allowList only gets allowed items', (WidgetTester _) async { + const String allowedString = 'stringKey'; + const String allowedBool = 'boolKey'; + const String notAllowedDouble = 'doubleKey'; + const String resultString = 'resultString'; + + const Set allowList = {allowedString, allowedBool}; + SharedPreferences.resetStatic(); - }); + SharedPreferences.setPrefix('', allowList: allowList); + + final SharedPreferences prefs = await SharedPreferences.getInstance(); + + await prefs.setString(allowedString, resultString); + await prefs.setBool(allowedBool, true); + await prefs.setDouble(notAllowedDouble, 3.14); + + await prefs.reload(); - runAllTests(); + final String? testString = prefs.getString(allowedString); + expect(testString, resultString); + + final bool? testBool = prefs.getBool(allowedBool); + expect(testBool, true); + + final double? testDouble = prefs.getDouble(notAllowedDouble); + expect(testDouble, null); + }); }); - group('setNoPrefix', () { - setUp(() async { - SharedPreferences.resetStatic(); - SharedPreferences.setPrefix(''); - preferences = await SharedPreferences.getInstance(); + group('shared_preferences_async', () { + 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']; + + group('Async', () { + Future getPreferences() async { + final SharedPreferencesAsync preferences = SharedPreferencesAsync(); + await preferences.clear(); + return preferences; + } + + testWidgets('set and get String', (WidgetTester _) async { + final SharedPreferencesAsync preferences = await getPreferences(); + + await preferences.setString(stringKey, testString); + expect(await preferences.getString(stringKey), testString); + }); + + testWidgets('set and get bool', (WidgetTester _) async { + final SharedPreferencesAsync preferences = await getPreferences(); + + await preferences.setBool(boolKey, testBool); + expect(await preferences.getBool(boolKey), testBool); + }); + + testWidgets('set and get int', (WidgetTester _) async { + final SharedPreferencesAsync preferences = await getPreferences(); + + await preferences.setInt(intKey, testInt); + expect(await preferences.getInt(intKey), testInt); + }); + + testWidgets('set and get double', (WidgetTester _) async { + final SharedPreferencesAsync preferences = await getPreferences(); + + await preferences.setDouble(doubleKey, testDouble); + expect(await preferences.getDouble(doubleKey), testDouble); + }); + + testWidgets('set and get StringList', (WidgetTester _) async { + final SharedPreferencesAsync preferences = await getPreferences(); + + await preferences.setStringList(listKey, testList); + expect(await preferences.getStringList(listKey), testList); + }); + + testWidgets('getStringList returns mutable list', (WidgetTester _) async { + final SharedPreferencesAsync preferences = await getPreferences(); + + await preferences.setStringList(listKey, testList); + final List? list = await preferences.getStringList(listKey); + list?.add('value'); + expect(list?.length, testList.length + 1); + }); + + testWidgets('getAll', (WidgetTester _) async { + final SharedPreferencesAsync preferences = await getPreferences(); + await Future.wait(>[ + preferences.setString(stringKey, testString), + preferences.setBool(boolKey, testBool), + preferences.setInt(intKey, testInt), + preferences.setDouble(doubleKey, testDouble), + preferences.setStringList(listKey, testList) + ]); + + final Map gotAll = await preferences.getAll(); + + 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('getAll with filter', (WidgetTester _) async { + final SharedPreferencesAsync preferences = await getPreferences(); + await Future.wait(>[ + preferences.setString(stringKey, testString), + preferences.setBool(boolKey, testBool), + preferences.setInt(intKey, testInt), + preferences.setDouble(doubleKey, testDouble), + preferences.setStringList(listKey, testList) + ]); + + final Map gotAll = + await preferences.getAll(allowList: {stringKey, boolKey}); + + expect(gotAll.length, 2); + expect(gotAll[stringKey], testString); + expect(gotAll[boolKey], testBool); + }); + + testWidgets('getKeys', (WidgetTester _) async { + final SharedPreferencesAsync preferences = await getPreferences(); + await Future.wait(>[ + preferences.setString(stringKey, testString), + preferences.setBool(boolKey, testBool), + preferences.setInt(intKey, testInt), + preferences.setDouble(doubleKey, testDouble), + preferences.setStringList(listKey, testList) + ]); + + final Set keys = await preferences.getKeys(); + + 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', (WidgetTester _) async { + final SharedPreferencesAsync preferences = await getPreferences(); + await Future.wait(>[ + preferences.setString(stringKey, testString), + preferences.setBool(boolKey, testBool), + preferences.setInt(intKey, testInt), + preferences.setDouble(doubleKey, testDouble), + preferences.setStringList(listKey, testList) + ]); + + final Set keys = + await preferences.getKeys(allowList: {stringKey, boolKey}); + + expect(keys.length, 2); + expect(keys, contains(stringKey)); + expect(keys, contains(boolKey)); + }); + + testWidgets('containsKey', (WidgetTester _) async { + final SharedPreferencesAsync preferences = await getPreferences(); + const String key = 'testKey'; + + expect(false, await preferences.containsKey(key)); + + await preferences.setString(key, 'test'); + expect(true, await preferences.containsKey(key)); + }); + + testWidgets('clear', (WidgetTester _) async { + final SharedPreferencesAsync preferences = await getPreferences(); + await Future.wait(>[ + preferences.setString(stringKey, testString), + preferences.setBool(boolKey, testBool), + preferences.setInt(intKey, testInt), + preferences.setDouble(doubleKey, testDouble), + preferences.setStringList(listKey, testList) + ]); + await preferences.clear(); + expect(await preferences.getString(stringKey), null); + expect(await preferences.getBool(boolKey), null); + expect(await preferences.getInt(intKey), null); + expect(await preferences.getDouble(doubleKey), null); + expect(await preferences.getStringList(listKey), null); + }); + + testWidgets('clear with filter', (WidgetTester _) async { + final SharedPreferencesAsync preferences = await getPreferences(); + await Future.wait(>[ + preferences.setString(stringKey, testString), + preferences.setBool(boolKey, testBool), + preferences.setInt(intKey, testInt), + preferences.setDouble(doubleKey, testDouble), + preferences.setStringList(listKey, testList) + ]); + await preferences.clear(allowList: {stringKey, boolKey}); + expect(await preferences.getString(stringKey), null); + expect(await preferences.getBool(boolKey), null); + expect(await preferences.getInt(intKey), testInt); + expect(await preferences.getDouble(doubleKey), testDouble); + expect(await preferences.getStringList(listKey), testList); + }); + + testWidgets('throws TypeError when returned getBool type is incorrect', + (WidgetTester _) async { + final SharedPreferencesAsync preferences = await getPreferences(); + await preferences.setString(stringKey, testString); + + expect(() async { + await preferences.getBool(stringKey); + }, throwsA(isA())); + }); + + testWidgets('throws TypeError when returned getString type is incorrect', + (WidgetTester _) async { + final SharedPreferencesAsync preferences = await getPreferences(); + await preferences.setInt(stringKey, testInt); + + expect(() async { + await preferences.getString(stringKey); + }, throwsA(isA())); + }); + + testWidgets('throws TypeError when returned getInt type is incorrect', + (WidgetTester _) async { + final SharedPreferencesAsync preferences = await getPreferences(); + await preferences.setString(stringKey, testString); + + expect(() async { + await preferences.getInt(stringKey); + }, throwsA(isA())); + }); + + testWidgets('throws TypeError when returned getDouble type is incorrect', + (WidgetTester _) async { + final SharedPreferencesAsync preferences = await getPreferences(); + await preferences.setString(stringKey, testString); + + expect(() async { + await preferences.getDouble(stringKey); + }, throwsA(isA())); + }); + + testWidgets( + 'throws TypeError when returned getStringList type is incorrect', + (WidgetTester _) async { + final SharedPreferencesAsync preferences = await getPreferences(); + await preferences.setString(stringKey, testString); + + expect(() async { + await preferences.getStringList(stringKey); + }, throwsA(isA())); + }); }); - tearDown(() async { - await preferences.clear(); - SharedPreferences.resetStatic(); + group('withCache', () { + Future< + ( + SharedPreferencesWithCache, + Map, + )> getPreferences() async { + final Map cache = {}; + final SharedPreferencesWithCache preferences = + await SharedPreferencesWithCache.create( + cache: cache, + cacheOptions: const SharedPreferencesWithCacheOptions(), + ); + await preferences.clear(); + return (preferences, cache); + } + + testWidgets('set and get String', (WidgetTester _) async { + final (SharedPreferencesWithCache preferences, _) = + await getPreferences(); + + await preferences.setString(stringKey, testString); + expect(preferences.getString(stringKey), testString); + }); + + testWidgets('set and get bool', (WidgetTester _) async { + final (SharedPreferencesWithCache preferences, _) = + await getPreferences(); + + await preferences.setBool(boolKey, testBool); + expect(preferences.getBool(boolKey), testBool); + }); + + testWidgets('set and get int', (WidgetTester _) async { + final (SharedPreferencesWithCache preferences, _) = + await getPreferences(); + + await preferences.setInt(intKey, testInt); + expect(preferences.getInt(intKey), testInt); + }); + + testWidgets('set and get double', (WidgetTester _) async { + final (SharedPreferencesWithCache preferences, _) = + await getPreferences(); + + await preferences.setDouble(doubleKey, testDouble); + expect(preferences.getDouble(doubleKey), testDouble); + }); + + testWidgets('set and get StringList', (WidgetTester _) async { + final (SharedPreferencesWithCache preferences, _) = + await getPreferences(); + + await preferences.setStringList(listKey, testList); + expect(preferences.getStringList(listKey), testList); + }); + + testWidgets('reloading', (WidgetTester _) async { + final ( + SharedPreferencesWithCache preferences, + Map cache + ) = await getPreferences(); + await preferences.clear(); + await preferences.setString(stringKey, testString); + expect(preferences.getString(stringKey), testString); + + cache.clear(); + expect(preferences.getString(stringKey), null); + + await preferences.reloadCache(); + expect(preferences.getString(stringKey), testString); + }); + + testWidgets('containsKey', (WidgetTester _) async { + final (SharedPreferencesWithCache preferences, _) = + await getPreferences(); + const String key = 'testKey'; + + expect(false, preferences.containsKey(key)); + + await preferences.setString(key, 'test'); + expect(true, preferences.containsKey(key)); + }); + + testWidgets('getKeys', (WidgetTester _) async { + final (SharedPreferencesWithCache preferences, _) = + await getPreferences(); + await Future.wait(>[ + preferences.setString(stringKey, testString), + preferences.setBool(boolKey, testBool), + preferences.setInt(intKey, testInt), + preferences.setDouble(doubleKey, testDouble), + preferences.setStringList(listKey, testList) + ]); + + final Set keys = preferences.keys; + + 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('clear', (WidgetTester _) async { + final (SharedPreferencesWithCache preferences, _) = + await getPreferences(); + await Future.wait(>[ + preferences.setString(stringKey, testString), + preferences.setBool(boolKey, testBool), + preferences.setInt(intKey, testInt), + preferences.setDouble(doubleKey, testDouble), + preferences.setStringList(listKey, testList) + ]); + await preferences.clear(); + expect(preferences.getString(stringKey), null); + expect(preferences.getBool(boolKey), null); + expect(preferences.getInt(intKey), null); + expect(preferences.getDouble(doubleKey), null); + expect(preferences.getStringList(listKey), null); + }); }); - runAllTests(); - }); + group('withCache with filter', () { + Future< + ( + SharedPreferencesWithCache, + Map, + )> getPreferences() async { + final Map cache = {}; + final SharedPreferencesWithCache preferences = + await SharedPreferencesWithCache.create( + cache: cache, + cacheOptions: const SharedPreferencesWithCacheOptions( + allowList: { + stringKey, + boolKey, + intKey, + doubleKey, + listKey, + }, + ), + ); + await preferences.clear(); + return (preferences, cache); + } + + testWidgets('throws ArgumentError if key is not included in filter', + (WidgetTester _) async { + final (SharedPreferencesWithCache preferences, _) = + await getPreferences(); + const String key = 'testKey'; + + expect(() async => preferences.setString(key, 'test'), + throwsArgumentError); + }); + + testWidgets('set and get String', (WidgetTester _) async { + final (SharedPreferencesWithCache preferences, _) = + await getPreferences(); - testWidgets('allowList only gets allowed items', (WidgetTester _) async { - const String allowedString = 'stringKey'; - const String allowedBool = 'boolKey'; - const String notAllowedDouble = 'doubleKey'; - const String resultString = 'resultString'; + await preferences.setString(stringKey, testString); + expect(preferences.getString(stringKey), testString); + }); - const Set allowList = {allowedString, allowedBool}; + testWidgets('set and get bool', (WidgetTester _) async { + final (SharedPreferencesWithCache preferences, _) = + await getPreferences(); - SharedPreferences.resetStatic(); - SharedPreferences.setPrefix('', allowList: allowList); + await preferences.setBool(boolKey, testBool); + expect(preferences.getBool(boolKey), testBool); + }); - final SharedPreferences prefs = await SharedPreferences.getInstance(); + testWidgets('set and get int', (WidgetTester _) async { + final (SharedPreferencesWithCache preferences, _) = + await getPreferences(); - await prefs.setString(allowedString, resultString); - await prefs.setBool(allowedBool, true); - await prefs.setDouble(notAllowedDouble, 3.14); + await preferences.setInt(intKey, testInt); + expect(preferences.getInt(intKey), testInt); + }); - await prefs.reload(); + testWidgets('set and get double', (WidgetTester _) async { + final (SharedPreferencesWithCache preferences, _) = + await getPreferences(); - final String? testString = prefs.getString(allowedString); - expect(testString, resultString); + await preferences.setDouble(doubleKey, testDouble); + expect(preferences.getDouble(doubleKey), testDouble); + }); - final bool? testBool = prefs.getBool(allowedBool); - expect(testBool, true); + testWidgets('set and get StringList', (WidgetTester _) async { + final (SharedPreferencesWithCache preferences, _) = + await getPreferences(); - final double? testDouble = prefs.getDouble(notAllowedDouble); - expect(testDouble, null); + await preferences.setStringList(listKey, testList); + expect(preferences.getStringList(listKey), testList); + }); + + testWidgets('get StringList handles List', + (WidgetTester _) async { + final ( + SharedPreferencesWithCache preferences, + Map cache + ) = await getPreferences(); + final List listObject = ['one', 'two']; + cache[listKey] = listObject; + expect(preferences.getStringList(listKey), listObject); + }); + + testWidgets('reloading', (WidgetTester _) async { + final ( + SharedPreferencesWithCache preferences, + Map cache + ) = await getPreferences(); + await preferences.clear(); + await preferences.setString(stringKey, testString); + expect(preferences.getString(stringKey), testString); + + cache.clear(); + expect(preferences.getString(stringKey), null); + + await preferences.reloadCache(); + expect(preferences.getString(stringKey), testString); + }); + + testWidgets('containsKey', (WidgetTester _) async { + final (SharedPreferencesWithCache preferences, _) = + await getPreferences(); + + expect(false, preferences.containsKey(stringKey)); + + await preferences.setString(stringKey, 'test'); + expect(true, preferences.containsKey(stringKey)); + }); + + testWidgets('getKeys', (WidgetTester _) async { + final (SharedPreferencesWithCache preferences, _) = + await getPreferences(); + await Future.wait(>[ + preferences.setString(stringKey, testString), + preferences.setBool(boolKey, testBool), + preferences.setInt(intKey, testInt), + preferences.setDouble(doubleKey, testDouble), + preferences.setStringList(listKey, testList) + ]); + + final Set keys = preferences.keys; + + 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('clear', (WidgetTester _) async { + final (SharedPreferencesWithCache preferences, _) = + await getPreferences(); + await Future.wait(>[ + preferences.setString(stringKey, testString), + preferences.setBool(boolKey, testBool), + preferences.setInt(intKey, testInt), + preferences.setDouble(doubleKey, testDouble), + preferences.setStringList(listKey, testList) + ]); + await preferences.clear(); + + expect(preferences.getString(stringKey), null); + expect(preferences.getBool(boolKey), null); + // The data for the next few tests is still stored on the platform, but not in the cache. + // This will cause the results to be null. + expect(preferences.getInt(intKey), null); + expect(preferences.getDouble(doubleKey), null); + expect(preferences.getStringList(listKey), null); + }); + }); }); } diff --git a/packages/shared_preferences/shared_preferences/example/lib/main.dart b/packages/shared_preferences/shared_preferences/example/lib/main.dart index 8f9dcd6d113a..003d8d911b53 100644 --- a/packages/shared_preferences/shared_preferences/example/lib/main.dart +++ b/packages/shared_preferences/shared_preferences/example/lib/main.dart @@ -19,7 +19,7 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return const MaterialApp( - title: 'SharedPreferences Demo', + title: 'SharedPreferencesWithCache Demo', home: SharedPreferencesDemo(), ); } @@ -33,33 +33,49 @@ class SharedPreferencesDemo extends StatefulWidget { } class SharedPreferencesDemoState extends State { - final Future _prefs = SharedPreferences.getInstance(); + final Future _prefs = + SharedPreferencesWithCache.create( + cacheOptions: const SharedPreferencesWithCacheOptions( + // This cache will only accept the key 'counter'. + allowList: {'counter'})); late Future _counter; + int _externalCounter = 0; Future _incrementCounter() async { - final SharedPreferences prefs = await _prefs; + final SharedPreferencesWithCache prefs = await _prefs; final int counter = (prefs.getInt('counter') ?? 0) + 1; setState(() { - _counter = prefs.setInt('counter', counter).then((bool success) { + _counter = prefs.setInt('counter', counter).then((_) { return counter; }); }); } + /// Gets external button presses that could occur in another instance, thread, + /// or via some native system. + Future _getExternalCounter() async { + final SharedPreferencesAsync prefs = SharedPreferencesAsync(); + setState(() async { + _externalCounter = (await prefs.getInt('externalCounter')) ?? 0; + }); + } + @override void initState() { super.initState(); - _counter = _prefs.then((SharedPreferences prefs) { + _counter = _prefs.then((SharedPreferencesWithCache prefs) { return prefs.getInt('counter') ?? 0; }); + + _getExternalCounter(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: const Text('SharedPreferences Demo'), + title: const Text('SharedPreferencesWithCache Demo'), ), body: Center( child: FutureBuilder( @@ -75,7 +91,7 @@ class SharedPreferencesDemoState extends State { return Text('Error: ${snapshot.error}'); } else { return Text( - 'Button tapped ${snapshot.data} time${snapshot.data == 1 ? '' : 's'}.\n\n' + 'Button tapped ${snapshot.data ?? 0 + _externalCounter} time${(snapshot.data ?? 0 + _externalCounter) == 1 ? '' : 's'}.\n\n' 'This should persist across restarts.', ); } diff --git a/packages/shared_preferences/shared_preferences/example/lib/readme_excerpts.dart b/packages/shared_preferences/shared_preferences/example/lib/readme_excerpts.dart index 058b6736cb35..032409d49014 100644 --- a/packages/shared_preferences/shared_preferences/example/lib/readme_excerpts.dart +++ b/packages/shared_preferences/shared_preferences/example/lib/readme_excerpts.dart @@ -41,6 +41,47 @@ Future readmeSnippets() async { // #enddocregion Clear } +Future readmeSnippetsAsync() async { + // #docregion Async + final SharedPreferencesAsync asyncPrefs = SharedPreferencesAsync(); + + await asyncPrefs.setBool('repeat', true); + await asyncPrefs.setString('action', 'Start'); + + final bool? repeat = await asyncPrefs.getBool('repeat'); + final String? action = await asyncPrefs.getString('action'); + + await asyncPrefs.remove('repeat'); + + // Any time a filter option is included as a method parameter, strongly consider + // using it to avoid potentially unwanted side effects. + await asyncPrefs.clear(allowList: {'action', 'repeat'}); + // #enddocregion Async +} + +Future readmeSnippetsWithCache() async { + // #docregion WithCache + final SharedPreferencesWithCache prefsWithCache = + await SharedPreferencesWithCache.create( + cacheOptions: const SharedPreferencesWithCacheOptions( + // When an allowlist is included, any keys that aren't included cannot be used. + allowList: {'repeat', 'action'}, + ), + ); + + await prefsWithCache.setBool('repeat', true); + await prefsWithCache.setString('action', 'Start'); + + final bool? repeat = prefsWithCache.getBool('repeat'); + final String? action = prefsWithCache.getString('action'); + + await prefsWithCache.remove('repeat'); + + // Since the filter options are set at creation, they aren't needed during clear. + await prefsWithCache.clear(); + // #enddocregion WithCache +} + // Uses test-only code. invalid_use_of_visible_for_testing_member is suppressed // for the whole file since otherwise there's no way to avoid it showing up in // the excerpt, and that is definitely not something people should be copying diff --git a/packages/shared_preferences/shared_preferences/example/macos/Podfile b/packages/shared_preferences/shared_preferences/example/macos/Podfile index 049abe295427..ae77cc1d4269 100644 --- a/packages/shared_preferences/shared_preferences/example/macos/Podfile +++ b/packages/shared_preferences/shared_preferences/example/macos/Podfile @@ -28,7 +28,6 @@ flutter_macos_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) end diff --git a/packages/shared_preferences/shared_preferences/example/pubspec.yaml b/packages/shared_preferences/shared_preferences/example/pubspec.yaml index d80cc7eacd50..cbf79d353af5 100644 --- a/packages/shared_preferences/shared_preferences/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the shared_preferences plugin. publish_to: none environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: @@ -16,6 +16,7 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ + shared_preferences_platform_interface: ^2.4.0 dev_dependencies: build_runner: ^2.1.10 diff --git a/packages/shared_preferences/shared_preferences/example/web/index.html b/packages/shared_preferences/shared_preferences/example/web/index.html index 7fb138cc90fa..956b11f49f7a 100644 --- a/packages/shared_preferences/shared_preferences/example/web/index.html +++ b/packages/shared_preferences/shared_preferences/example/web/index.html @@ -8,6 +8,6 @@ example - + diff --git a/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart b/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart index 7361758b99d3..7dd15ff2c52a 100644 --- a/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart +++ b/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart @@ -2,286 +2,5 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:async'; - -import 'package:flutter/foundation.dart' show visibleForTesting; -import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; -import 'package:shared_preferences_platform_interface/types.dart'; - -/// Wraps NSUserDefaults (on iOS) and SharedPreferences (on Android), providing -/// a persistent store for simple data. -/// -/// Data is persisted to disk asynchronously. -class SharedPreferences { - SharedPreferences._(this._preferenceCache); - - static String _prefix = 'flutter.'; - - static bool _prefixHasBeenChanged = false; - - static Set? _allowList; - - static Completer? _completer; - - static SharedPreferencesStorePlatform get _store => - SharedPreferencesStorePlatform.instance; - - /// Sets the prefix that is attached to all keys for all shared preferences. - /// - /// This changes the inputs when adding data to preferences as well as - /// setting the filter that determines what data will be returned - /// from the `getInstance` method. - /// - /// By default, the prefix is 'flutter.', which is compatible with the - /// previous behavior of this plugin. To use preferences with no prefix, - /// set [prefix] to ''. - /// - /// If [prefix] is set to '', you may encounter preferences that are - /// incompatible with shared_preferences. The optional parameter - /// [allowList] will cause the plugin to only return preferences that - /// are both contained in the list AND match the provided prefix. - /// - /// No migration of existing preferences is performed by this method. - /// If you set a different prefix, and have previously stored preferences, - /// you will need to handle any migration yourself. - /// - /// This cannot be called after `getInstance`. - static void setPrefix(String prefix, {Set? allowList}) { - if (_completer != null) { - throw StateError('setPrefix cannot be called after getInstance'); - } - _prefix = prefix; - _prefixHasBeenChanged = true; - _allowList = allowList; - } - - /// Resets class's static values to allow for testing of setPrefix flow. - @visibleForTesting - static void resetStatic() { - _completer = null; - _prefix = 'flutter.'; - _prefixHasBeenChanged = false; - _allowList = null; - } - - /// Loads and parses the [SharedPreferences] for this app from disk. - /// - /// Because this is reading from disk, it shouldn't be awaited in - /// performance-sensitive blocks. - static Future getInstance() async { - if (_completer == null) { - final Completer completer = - Completer(); - _completer = completer; - try { - final Map preferencesMap = - await _getSharedPreferencesMap(); - completer.complete(SharedPreferences._(preferencesMap)); - } catch (e) { - // If there's an error, explicitly return the future with an error. - // then set the completer to null so we can retry. - completer.completeError(e); - final Future sharedPrefsFuture = completer.future; - _completer = null; - return sharedPrefsFuture; - } - } - return _completer!.future; - } - - /// The cache that holds all preferences. - /// - /// It is instantiated to the current state of the SharedPreferences or - /// NSUserDefaults object and then kept in sync via setter methods in this - /// class. - /// - /// It is NOT guaranteed that this cache and the device prefs will remain - /// in sync since the setter method might fail for any reason. - final Map _preferenceCache; - - /// Returns all keys in the persistent storage. - Set getKeys() => Set.from(_preferenceCache.keys); - - /// Reads a value of any type from persistent storage. - Object? get(String key) => _preferenceCache[key]; - - /// Reads a value from persistent storage, throwing an exception if it's not a - /// bool. - bool? getBool(String key) => _preferenceCache[key] as bool?; - - /// Reads a value from persistent storage, throwing an exception if it's not - /// an int. - int? getInt(String key) => _preferenceCache[key] as int?; - - /// Reads a value from persistent storage, throwing an exception if it's not a - /// double. - double? getDouble(String key) => _preferenceCache[key] as double?; - - /// Reads a value from persistent storage, throwing an exception if it's not a - /// String. - String? getString(String key) => _preferenceCache[key] as String?; - - /// Returns true if the persistent storage contains the given [key]. - bool containsKey(String key) => _preferenceCache.containsKey(key); - - /// Reads a set of string values from persistent storage, throwing an - /// exception if it's not a string set. - List? getStringList(String key) { - List? list = _preferenceCache[key] as List?; - if (list != null && list is! List) { - list = list.cast().toList(); - _preferenceCache[key] = list; - } - // Make a copy of the list so that later mutations won't propagate - return list?.toList() as List?; - } - - /// Saves a boolean [value] to persistent storage in the background. - Future setBool(String key, bool value) => _setValue('Bool', key, value); - - /// Saves an integer [value] to persistent storage in the background. - Future setInt(String key, int value) => _setValue('Int', key, value); - - /// Saves a double [value] to persistent storage in the background. - /// - /// Android doesn't support storing doubles, so it will be stored as a float. - Future setDouble(String key, double value) => - _setValue('Double', key, value); - - /// Saves a string [value] to persistent storage in the background. - /// - /// Note: Due to limitations in Android's SharedPreferences, - /// values cannot start with any one of the following: - /// - /// - 'VGhpcyBpcyB0aGUgcHJlZml4IGZvciBhIGxpc3Qu' - /// - 'VGhpcyBpcyB0aGUgcHJlZml4IGZvciBCaWdJbnRlZ2Vy' - /// - 'VGhpcyBpcyB0aGUgcHJlZml4IGZvciBEb3VibGUu' - Future setString(String key, String value) => - _setValue('String', key, value); - - /// Saves a list of strings [value] to persistent storage in the background. - Future setStringList(String key, List value) => - _setValue('StringList', key, value); - - /// Removes an entry from persistent storage. - Future remove(String key) { - final String prefixedKey = '$_prefix$key'; - _preferenceCache.remove(key); - return _store.remove(prefixedKey); - } - - Future _setValue(String valueType, String key, Object value) { - ArgumentError.checkNotNull(value, 'value'); - final String prefixedKey = '$_prefix$key'; - if (value is List) { - // Make a copy of the list so that later mutations won't propagate - _preferenceCache[key] = value.toList(); - } else { - _preferenceCache[key] = value; - } - return _store.setValue(valueType, prefixedKey, value); - } - - /// Always returns true. - /// On iOS, synchronize is marked deprecated. On Android, we commit every set. - @Deprecated('This method is now a no-op, and should no longer be called.') - Future commit() async => true; - - /// Completes with true once the user preferences for the app has been cleared. - Future clear() { - _preferenceCache.clear(); - if (_prefixHasBeenChanged) { - try { - return _store.clearWithParameters( - ClearParameters( - filter: PreferencesFilter( - prefix: _prefix, - allowList: _allowList, - ), - ), - ); - } catch (e) { - // Catching and clarifying UnimplementedError to provide a more robust message. - if (e is UnimplementedError) { - throw UnimplementedError(''' -This implementation of Shared Preferences doesn't yet support the setPrefix method. -Either update the implementation to support setPrefix, or do not call setPrefix. - '''); - } else { - rethrow; - } - } - } - return _store.clear(); - } - - /// Fetches the latest values from the host platform. - /// - /// Use this method to observe modifications that were made in native code - /// (without using the plugin) while the app is running. - Future reload() async { - final Map preferences = - await SharedPreferences._getSharedPreferencesMap(); - _preferenceCache.clear(); - _preferenceCache.addAll(preferences); - } - - static Future> _getSharedPreferencesMap() async { - final Map fromSystem = {}; - if (_prefixHasBeenChanged) { - try { - fromSystem.addAll( - await _store.getAllWithParameters( - GetAllParameters( - filter: PreferencesFilter( - prefix: _prefix, - allowList: _allowList, - ), - ), - ), - ); - } catch (e) { - // Catching and clarifying UnimplementedError to provide a more robust message. - if (e is UnimplementedError) { - throw UnimplementedError(''' -This implementation of Shared Preferences doesn't yet support the setPrefix method. -Either update the implementation to support setPrefix, or do not call setPrefix. - '''); - } else { - rethrow; - } - } - } else { - fromSystem.addAll(await _store.getAll()); - } - - if (_prefix.isEmpty) { - return fromSystem; - } - // Strip the prefix from the returned preferences. - final Map preferencesMap = {}; - for (final String key in fromSystem.keys) { - assert(key.startsWith(_prefix)); - preferencesMap[key.substring(_prefix.length)] = fromSystem[key]!; - } - return preferencesMap; - } - - /// Initializes the shared preferences with mock values for testing. - /// - /// If the singleton instance has been initialized already, it is nullified. - @visibleForTesting - static void setMockInitialValues(Map values) { - final Map newValues = - values.map((String key, Object value) { - String newKey = key; - if (!key.startsWith(_prefix)) { - newKey = '$_prefix$key'; - } - return MapEntry(newKey, value); - }); - SharedPreferencesStorePlatform.instance = - InMemorySharedPreferencesStore.withData(newValues); - _completer = null; - } -} +export 'src/shared_preferences_async.dart'; +export 'src/shared_preferences_legacy.dart'; diff --git a/packages/shared_preferences/shared_preferences/lib/src/shared_preferences_async.dart b/packages/shared_preferences/shared_preferences/lib/src/shared_preferences_async.dart new file mode 100644 index 000000000000..516788542fd1 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/lib/src/shared_preferences_async.dart @@ -0,0 +1,403 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; +import 'package:shared_preferences_platform_interface/types.dart'; + +/// Provides a persistent store for simple data. +/// +/// Data is persisted to and fetched from the disk asynchronously. +/// If synchronous access to preferences in a locally cached version of preferences +/// is preferred, consider using [SharedPreferencesWithCache] instead. +@immutable +class SharedPreferencesAsync { + /// Creates a new instance with the given [options]. + SharedPreferencesAsync({ + SharedPreferencesOptions options = const SharedPreferencesOptions(), + }) : _options = options { + if (SharedPreferencesAsyncPlatform.instance == null) { + throw StateError( + 'The SharedPreferencesAsyncPlatform instance must be set.'); + } else { + _platform = SharedPreferencesAsyncPlatform.instance!; + } + } + + /// Options that determine the behavior of contained methods, usually + /// platform specific extensions of the [SharedPreferencesOptions] class. + final SharedPreferencesOptions _options; + + late final SharedPreferencesAsyncPlatform _platform; + + /// Returns all keys on the the platform that match provided [parameters]. + /// + /// If no restrictions are provided, fetches all keys stored on the platform. + /// + /// Ignores any keys whose values are types which are incompatible with shared_preferences. + Future> getKeys({Set? allowList}) async { + final GetPreferencesParameters parameters = GetPreferencesParameters( + filter: PreferencesFilters(allowList: allowList)); + return _platform.getKeys(parameters, _options); + } + + /// Returns all keys and values on the the platform that match provided [parameters]. + /// + /// If no restrictions are provided, fetches all entries stored on the platform. + /// + /// Ignores any entries of types which are incompatible with shared_preferences. + Future> getAll({Set? allowList}) async { + final GetPreferencesParameters parameters = GetPreferencesParameters( + filter: PreferencesFilters(allowList: allowList)); + return _platform.getPreferences(parameters, _options); + } + + /// Reads a value from the platform, throwing a [TypeError] if the value is + /// not a bool. + Future getBool(String key) async { + return _platform.getBool(key, _options); + } + + /// Reads a value from the platform, throwing a [TypeError] if the value is + /// not an int. + Future getInt(String key) async { + return _platform.getInt(key, _options); + } + + /// Reads a value from the platform, throwing a [TypeError] if the value is + /// not a double. + Future getDouble(String key) async { + return _platform.getDouble(key, _options); + } + + /// Reads a value from the platform, throwing a [TypeError] if the value is + /// not a String. + Future getString(String key) async { + return _platform.getString(key, _options); + } + + /// Reads a list of string values from the platform, throwing a [TypeError] + /// if the value not a List. + Future?> getStringList(String key) async { + return _platform.getStringList(key, _options); + } + + /// Returns true if the the platform contains the given [key]. + Future containsKey(String key) async { + return (await getKeys(allowList: {key})).isNotEmpty; + } + + /// Saves a boolean [value] to the platform. + Future setBool(String key, bool value) { + return _platform.setBool(key, value, _options); + } + + /// Saves an integer [value] to the platform. + Future setInt(String key, int value) { + return _platform.setInt(key, value, _options); + } + + /// Saves a double [value] to the platform. + /// + /// On platforms that do not support storing doubles, + /// the value will be stored as a float. + Future setDouble(String key, double value) { + return _platform.setDouble(key, value, _options); + } + + /// Saves a string [value] to the platform. + /// + /// Some platforms have special values that cannot be stored, please refer to + /// the README for more information. + Future setString(String key, String value) { + return _platform.setString(key, value, _options); + } + + /// Saves a list of strings [value] to the platform. + Future setStringList(String key, List value) { + return _platform.setStringList(key, value, _options); + } + + /// Removes an entry from the platform. + Future remove(String key) { + return _platform.clear( + ClearPreferencesParameters( + filter: PreferencesFilters(allowList: {key})), + _options); + } + + /// Clears all preferences from the platform. + /// + /// If no [parameters] are provided, and [SharedPreferencesAsync] has no filter, + /// all preferences will be removed. This may include values not set by this instance, + /// such as those stored by native code or by other packages using + /// shared_preferences internally, which may cause unintended side effects. + /// + /// It is highly recommended that an [allowList] be provided to this call. + Future clear({Set? allowList}) { + final ClearPreferencesParameters parameters = ClearPreferencesParameters( + filter: PreferencesFilters(allowList: allowList)); + return _platform.clear(parameters, _options); + } +} + +/// Options necessary to create a [SharedPreferencesWithCache]. +class SharedPreferencesWithCacheOptions { + /// Creates a new instance with the given options. + const SharedPreferencesWithCacheOptions({ + this.allowList, + }); + + /// Information about what data will be fetched during `get` and `init` + /// methods, what data can be `set`, as well as what data will be removed by `clear`. + /// + /// A `null` allowList will prevent filtering, allowing all items to be cached. + /// An empty allowList will prevent all caching as well as getting and setting. + /// + /// Setting an allowList is strongly recommended, to prevent getting and + /// caching unneeded or unexpected data. + final Set? allowList; +} + +/// Provides a persistent store for simple data. +/// +/// Cache provided to allow for synchronous gets. +/// +/// If preferences on the platform may be altered by other means than through +/// this instance, consider using [SharedPreferencesAsync] instead. You may also +/// refresh the cached data using [reloadCache] prior to a get request to prevent +/// missed changes that may have occurred since the cache was last updated. +@immutable +class SharedPreferencesWithCache { + /// Creates a new instance with the given options. + SharedPreferencesWithCache._create({ + required SharedPreferencesOptions sharedPreferencesOptions, + required SharedPreferencesWithCacheOptions cacheOptions, + Map? cache, + }) : _cacheOptions = cacheOptions, + _platformMethods = + SharedPreferencesAsync(options: sharedPreferencesOptions), + _cache = cache ?? {}; + + /// Creates a new instance with the given options and reloads the cache from + /// the platform data. + static Future create({ + SharedPreferencesOptions sharedPreferencesOptions = + const SharedPreferencesOptions(), + required SharedPreferencesWithCacheOptions cacheOptions, + Map? cache, + }) async { + final SharedPreferencesWithCache preferences = + SharedPreferencesWithCache._create( + sharedPreferencesOptions: sharedPreferencesOptions, + cacheOptions: cacheOptions, + cache: cache, + ); + + await preferences.reloadCache(); + + return preferences; + } + + /// Cache containing in-memory data. + final Map _cache; + + /// Options that define cache behavior. + final SharedPreferencesWithCacheOptions _cacheOptions; + + /// Async access directly to the platform. + /// + /// Methods called through [_platformMethods] will NOT update the cache. + final SharedPreferencesAsync _platformMethods; + + /// Updates cache with latest values from platform. + /// + /// This should be called before reading any values if the values may have + /// been changed by anything other than this cache instance, + /// such as from another isolate or native code that changes the underlying + /// preference storage directly. + Future reloadCache() async { + _cache.clear(); + _cache.addAll( + await _platformMethods.getAll(allowList: _cacheOptions.allowList)); + } + + /// Returns true if cache contains the given [key]. + /// + /// Throws an [ArgumentError] if [key] is not in this instance's filter. + bool containsKey(String key) { + if (!_isValidKey(key)) { + throw ArgumentError( + '$key is not included in the PreferencesFilter allowlist'); + } + return _cache.containsKey(key); + } + + /// Returns all keys in the cache. + Set get keys => _cache.keys.toSet(); + + /// Reads a value of any type from the cache. + /// + /// Throws an [ArgumentError] if [key] is not in this instance's filter. + Object? get(String key) { + if (!_isValidKey(key)) { + throw ArgumentError( + '$key is not included in the PreferencesFilter allowlist'); + } + return _cache[key]; + } + + /// Reads a value from the cache, throwing a [TypeError] if the value is not a + /// bool. + /// + /// Throws an [ArgumentError] if [key] is not in this instance's filter. + bool? getBool(String key) { + if (!_isValidKey(key)) { + throw ArgumentError( + '$key is not included in the PreferencesFilter allowlist'); + } + return get(key) as bool?; + } + + /// Reads a value from the cache, throwing a [TypeError] if the value is not + /// an int. + /// + /// Throws an [ArgumentError] if [key] is not in this instance's filter. + int? getInt(String key) { + if (!_isValidKey(key)) { + throw ArgumentError( + '$key is not included in the PreferencesFilter allowlist'); + } + return get(key) as int?; + } + + /// Reads a value from the cache, throwing a [TypeError] if the value is not a + /// double. + /// + /// Throws an [ArgumentError] if [key] is not in this instance's filter. + double? getDouble(String key) { + if (!_isValidKey(key)) { + throw ArgumentError( + '$key is not included in the PreferencesFilter allowlist'); + } + return get(key) as double?; + } + + /// Reads a value from the cache, throwing a [TypeError] if the value is not a + /// String. + /// + /// Throws an [ArgumentError] if [key] is not in this instance's filter. + String? getString(String key) { + if (!_isValidKey(key)) { + throw ArgumentError( + '$key is not included in the PreferencesFilter allowlist'); + } + return get(key) as String?; + } + + /// Reads a list of string values from the cache, throwing an + /// exception if it's not a string list. + /// + /// Throws an [ArgumentError] if [key] is not in this instance's filter. + List? getStringList(String key) { + if (!_isValidKey(key)) { + throw ArgumentError( + '$key is not included in the PreferencesFilter allowlist'); + } + // Make a copy of the list so that later mutations won't propagate + return (_cache[key] as List?)?.cast().toList(); + } + + /// Saves a boolean [value] to the cache and platform. + /// + /// Throws an [ArgumentError] if [key] is not in this instance's filter. + Future setBool(String key, bool value) async { + if (!_isValidKey(key)) { + throw ArgumentError( + '$key is not included in the PreferencesFilter allowlist'); + } + _cache[key] = value; + return _platformMethods.setBool(key, value); + } + + /// Saves an integer [value] to the cache and platform. + /// + /// Throws an [ArgumentError] if [key] is not in this instance's filter. + Future setInt(String key, int value) async { + if (!_isValidKey(key)) { + throw ArgumentError( + '$key is not included in the PreferencesFilter allowlist'); + } + _cache[key] = value; + return _platformMethods.setInt(key, value); + } + + /// Saves a double [value] to the cache and platform. + /// + /// On platforms that do not support storing doubles, + /// the value will be stored as a float instead. + /// + /// Throws an [ArgumentError] if [key] is not in this instance's filter. + Future setDouble(String key, double value) async { + if (!_isValidKey(key)) { + throw ArgumentError( + '$key is not included in the PreferencesFilter allowlist'); + } + _cache[key] = value; + return _platformMethods.setDouble(key, value); + } + + /// Saves a string [value] to the cache and platform. + /// + /// Note: Due to limitations on some platforms, + /// values cannot start with the following: + /// + /// - 'VGhpcyBpcyB0aGUgcHJlZml4IGZvciBhIGxpc3Qu' + /// + /// Throws an [ArgumentError] if [key] is not in this instance's filter. + Future setString(String key, String value) async { + if (!_isValidKey(key)) { + throw ArgumentError( + '$key is not included in the PreferencesFilter allowlist'); + } + _cache[key] = value; + return _platformMethods.setString(key, value); + } + + /// Saves a list of strings [value] to the cache and platform. + /// + /// Throws an [ArgumentError] if [key] is not in this instance's filter. + Future setStringList(String key, List value) async { + if (!_isValidKey(key)) { + throw ArgumentError( + '$key is not included in the PreferencesFilter allowlist'); + } + _cache[key] = value; + return _platformMethods.setStringList(key, value); + } + + /// Removes an entry from cache and platform. + /// + /// Throws an [ArgumentError] if [key] is not in this instance's filter. + Future remove(String key) async { + if (!_isValidKey(key)) { + throw ArgumentError( + '$key is not included in the PreferencesFilter allowlist'); + } + _cache.remove(key); + return _platformMethods.remove(key); + } + + /// Clears cache and platform preferences that match filter options. + Future clear() async { + _cache.clear(); + return _platformMethods.clear(allowList: _cacheOptions.allowList); + } + + bool _isValidKey(String key) { + return _cacheOptions.allowList?.contains(key) ?? true; + } +} diff --git a/packages/shared_preferences/shared_preferences/lib/src/shared_preferences_legacy.dart b/packages/shared_preferences/shared_preferences/lib/src/shared_preferences_legacy.dart new file mode 100644 index 000000000000..a7eccb169504 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/lib/src/shared_preferences_legacy.dart @@ -0,0 +1,286 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import 'package:flutter/foundation.dart' show visibleForTesting; +import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; +import 'package:shared_preferences_platform_interface/types.dart'; + +/// Wraps NSUserDefaults (on iOS) and SharedPreferences (on Android), providing +/// a persistent store for simple data. +/// +/// Data is persisted to disk asynchronously. +/// +/// This is a legacy API. For new code, consider [SharedPreferencesAsync] or [SharedPreferencesWithCache]. +class SharedPreferences { + SharedPreferences._(this._preferenceCache); + + static String _prefix = 'flutter.'; + + static bool _prefixHasBeenChanged = false; + + static Set? _allowList; + + static Completer? _completer; + + static SharedPreferencesStorePlatform get _store => + SharedPreferencesStorePlatform.instance; + + /// Sets the prefix that is attached to all keys for all shared preferences. + /// + /// This changes the inputs when adding data to preferences as well as + /// setting the filter that determines what data will be returned + /// from the `getInstance` method. + /// + /// By default, the prefix is 'flutter.', which is compatible with the + /// previous behavior of this plugin. To use preferences with no prefix, + /// set [prefix] to ''. + /// + /// If [prefix] is set to '', you may encounter preferences that are + /// incompatible with shared_preferences. The optional parameter + /// [allowList] will cause the plugin to only return preferences that + /// are both contained in the list AND match the provided prefix. + /// + /// No migration of existing preferences is performed by this method. + /// If you set a different prefix, and have previously stored preferences, + /// you will need to handle any migration yourself. + /// + /// This cannot be called after `getInstance`. + static void setPrefix(String prefix, {Set? allowList}) { + if (_completer != null) { + throw StateError('setPrefix cannot be called after getInstance'); + } + _prefix = prefix; + _prefixHasBeenChanged = true; + _allowList = allowList; + } + + /// Resets class's static values to allow for testing of setPrefix flow. + @visibleForTesting + static void resetStatic() { + _completer = null; + _prefix = 'flutter.'; + _prefixHasBeenChanged = false; + _allowList = null; + } + + /// Loads and parses the [SharedPreferences] for this app from disk. + /// + /// Because this is reading from disk, it shouldn't be awaited in + /// performance-sensitive blocks. + static Future getInstance() async { + if (_completer == null) { + final Completer completer = + Completer(); + _completer = completer; + try { + final Map preferencesMap = + await _getSharedPreferencesMap(); + completer.complete(SharedPreferences._(preferencesMap)); + } catch (e) { + // If there's an error, explicitly return the future with an error. + // then set the completer to null so we can retry. + completer.completeError(e); + final Future sharedPrefsFuture = completer.future; + _completer = null; + return sharedPrefsFuture; + } + } + return _completer!.future; + } + + /// The cache that holds all preferences. + /// + /// It is instantiated to the current state of the SharedPreferences or + /// NSUserDefaults object and then kept in sync via setter methods in this + /// class. + /// + /// It is NOT guaranteed that this cache and the device prefs will remain + /// in sync since the setter method might fail for any reason. + final Map _preferenceCache; + + /// Returns all keys in the persistent storage. + Set getKeys() => Set.from(_preferenceCache.keys); + + /// Reads a value of any type from persistent storage. + Object? get(String key) => _preferenceCache[key]; + + /// Reads a value from persistent storage, throwing an exception if it's not a + /// bool. + bool? getBool(String key) => _preferenceCache[key] as bool?; + + /// Reads a value from persistent storage, throwing an exception if it's not + /// an int. + int? getInt(String key) => _preferenceCache[key] as int?; + + /// Reads a value from persistent storage, throwing an exception if it's not a + /// double. + double? getDouble(String key) => _preferenceCache[key] as double?; + + /// Reads a value from persistent storage, throwing an exception if it's not a + /// String. + String? getString(String key) => _preferenceCache[key] as String?; + + /// Returns true if the persistent storage contains the given [key]. + bool containsKey(String key) => _preferenceCache.containsKey(key); + + /// Reads a set of string values from persistent storage, throwing an + /// exception if it's not a string list. + List? getStringList(String key) { + List? list = _preferenceCache[key] as List?; + list = list?.cast(); + // Make a copy of the list so that later mutations won't propagate + return list?.toList() as List?; + } + + /// Saves a boolean [value] to persistent storage in the background. + Future setBool(String key, bool value) => _setValue('Bool', key, value); + + /// Saves an integer [value] to persistent storage in the background. + Future setInt(String key, int value) => _setValue('Int', key, value); + + /// Saves a double [value] to persistent storage in the background. + /// + /// Android doesn't support storing doubles, so it will be stored as a float. + Future setDouble(String key, double value) => + _setValue('Double', key, value); + + /// Saves a string [value] to persistent storage in the background. + /// + /// Note: Due to limitations in Android's SharedPreferences, + /// values cannot start with any one of the following: + /// + /// - 'VGhpcyBpcyB0aGUgcHJlZml4IGZvciBhIGxpc3Qu' + /// - 'VGhpcyBpcyB0aGUgcHJlZml4IGZvciBCaWdJbnRlZ2Vy' + /// - 'VGhpcyBpcyB0aGUgcHJlZml4IGZvciBEb3VibGUu' + Future setString(String key, String value) => + _setValue('String', key, value); + + /// Saves a list of strings [value] to persistent storage in the background. + Future setStringList(String key, List value) => + _setValue('StringList', key, value); + + /// Removes an entry from persistent storage. + Future remove(String key) { + final String prefixedKey = '$_prefix$key'; + _preferenceCache.remove(key); + return _store.remove(prefixedKey); + } + + Future _setValue(String valueType, String key, Object value) { + ArgumentError.checkNotNull(value, 'value'); + final String prefixedKey = '$_prefix$key'; + if (value is List) { + // Make a copy of the list so that later mutations won't propagate + _preferenceCache[key] = value.toList(); + } else { + _preferenceCache[key] = value; + } + return _store.setValue(valueType, prefixedKey, value); + } + + /// Always returns true. + /// On iOS, synchronize is marked deprecated. On Android, we commit every set. + @Deprecated('This method is now a no-op, and should no longer be called.') + Future commit() async => true; + + /// Completes with true once the user preferences for the app has been cleared. + Future clear() { + _preferenceCache.clear(); + if (_prefixHasBeenChanged) { + try { + return _store.clearWithParameters( + ClearParameters( + filter: PreferencesFilter( + prefix: _prefix, + allowList: _allowList, + ), + ), + ); + } catch (e) { + // Catching and clarifying UnimplementedError to provide a more robust message. + if (e is UnimplementedError) { + throw UnimplementedError(''' +This implementation of Shared Preferences doesn't yet support the setPrefix method. +Either update the implementation to support setPrefix, or do not call setPrefix. + '''); + } else { + rethrow; + } + } + } + return _store.clear(); + } + + /// Fetches the latest values from the host platform. + /// + /// Use this method to observe modifications that were made in native code + /// (without using the plugin) while the app is running. + Future reload() async { + final Map preferences = + await SharedPreferences._getSharedPreferencesMap(); + _preferenceCache.clear(); + _preferenceCache.addAll(preferences); + } + + static Future> _getSharedPreferencesMap() async { + final Map fromSystem = {}; + if (_prefixHasBeenChanged) { + try { + fromSystem.addAll( + await _store.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter( + prefix: _prefix, + allowList: _allowList, + ), + ), + ), + ); + } catch (e) { + // Catching and clarifying UnimplementedError to provide a more robust message. + if (e is UnimplementedError) { + throw UnimplementedError(''' +This implementation of Shared Preferences doesn't yet support the setPrefix method. +Either update the implementation to support setPrefix, or do not call setPrefix. + '''); + } else { + rethrow; + } + } + } else { + fromSystem.addAll(await _store.getAll()); + } + + if (_prefix.isEmpty) { + return fromSystem; + } + // Strip the prefix from the returned preferences. + final Map preferencesMap = {}; + for (final String key in fromSystem.keys) { + assert(key.startsWith(_prefix)); + preferencesMap[key.substring(_prefix.length)] = fromSystem[key]!; + } + return preferencesMap; + } + + /// Initializes the shared preferences with mock values for testing. + /// + /// If the singleton instance has been initialized already, it is nullified. + @visibleForTesting + static void setMockInitialValues(Map values) { + final Map newValues = + values.map((String key, Object value) { + String newKey = key; + if (!key.startsWith(_prefix)) { + newKey = '$_prefix$key'; + } + return MapEntry(newKey, value); + }); + SharedPreferencesStorePlatform.instance = + InMemorySharedPreferencesStore.withData(newValues); + _completer = null; + } +} diff --git a/packages/shared_preferences/shared_preferences/pubspec.yaml b/packages/shared_preferences/shared_preferences/pubspec.yaml index c3775eb455bf..cbe53e8d2bef 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.2.3 +version: 2.3.2 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: @@ -28,12 +28,12 @@ flutter: dependencies: flutter: sdk: flutter - shared_preferences_android: ^2.1.0 - shared_preferences_foundation: ^2.3.5 - shared_preferences_linux: ^2.2.0 - shared_preferences_platform_interface: ^2.3.0 - shared_preferences_web: ^2.1.0 - shared_preferences_windows: ^2.2.0 + shared_preferences_android: ^2.3.0 + shared_preferences_foundation: ^2.5.0 + shared_preferences_linux: ^2.4.0 + shared_preferences_platform_interface: ^2.4.0 + shared_preferences_web: ^2.4.0 + shared_preferences_windows: ^2.4.0 dev_dependencies: flutter_test: diff --git a/packages/shared_preferences/shared_preferences/test/shared_preferences_async_test.dart b/packages/shared_preferences/shared_preferences/test/shared_preferences_async_test.dart new file mode 100755 index 000000000000..372b2a5f7992 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/test/shared_preferences_async_test.dart @@ -0,0 +1,919 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:shared_preferences_platform_interface/in_memory_shared_preferences_async.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; +import 'package:shared_preferences_platform_interface/types.dart'; + +void main() { + 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']; + + group('Async', () { + (SharedPreferencesAsync, FakeSharedPreferencesAsync) getPreferences() { + final FakeSharedPreferencesAsync store = FakeSharedPreferencesAsync(); + SharedPreferencesAsyncPlatform.instance = store; + final SharedPreferencesAsync preferences = SharedPreferencesAsync(); + return (preferences, store); + } + + test('set and get String', () async { + final ( + SharedPreferencesAsync preferences, + FakeSharedPreferencesAsync store, + ) = getPreferences(); + await preferences.setString(stringKey, testString); + expect( + store.log, + [ + isMethodCall('setString', arguments: [ + stringKey, + testString, + ]), + ], + ); + store.log.clear(); + expect(await preferences.getString(stringKey), testString); + expect( + store.log, + [ + isMethodCall('getString', arguments: [ + stringKey, + ]), + ], + ); + }); + + test('set and get bool', () async { + final ( + SharedPreferencesAsync preferences, + FakeSharedPreferencesAsync store + ) = getPreferences(); + await preferences.setBool(boolKey, testBool); + expect( + store.log, + [ + isMethodCall('setBool', arguments: [ + boolKey, + testBool, + ]), + ], + ); + store.log.clear(); + expect(await preferences.getBool(boolKey), testBool); + expect( + store.log, + [ + isMethodCall('getBool', arguments: [ + boolKey, + ]), + ], + ); + }); + + test('set and get int', () async { + final ( + SharedPreferencesAsync preferences, + FakeSharedPreferencesAsync store + ) = getPreferences(); + await preferences.setInt(intKey, testInt); + expect( + store.log, + [ + isMethodCall('setInt', arguments: [ + intKey, + testInt, + ]), + ], + ); + store.log.clear(); + + expect(await preferences.getInt(intKey), testInt); + expect( + store.log, + [ + isMethodCall('getInt', arguments: [ + intKey, + ]), + ], + ); + }); + + test('set and get double', () async { + final ( + SharedPreferencesAsync preferences, + FakeSharedPreferencesAsync store + ) = getPreferences(); + await preferences.setDouble(doubleKey, testDouble); + expect( + store.log, + [ + isMethodCall('setDouble', arguments: [ + doubleKey, + testDouble, + ]), + ], + ); + store.log.clear(); + expect(await preferences.getDouble(doubleKey), testDouble); + expect( + store.log, + [ + isMethodCall('getDouble', arguments: [ + doubleKey, + ]), + ], + ); + }); + + test('set and get StringList', () async { + final ( + SharedPreferencesAsync preferences, + FakeSharedPreferencesAsync store + ) = getPreferences(); + await preferences.setStringList(listKey, testList); + expect( + store.log, + [ + isMethodCall('setStringList', arguments: [ + listKey, + testList, + ]), + ], + ); + store.log.clear(); + expect(await preferences.getStringList(listKey), testList); + expect( + store.log, + [ + isMethodCall('getStringList', arguments: [ + listKey, + ]), + ], + ); + }); + + test('getAll', () async { + final (SharedPreferencesAsync preferences, _) = getPreferences(); + await Future.wait(>[ + preferences.setString(stringKey, testString), + preferences.setBool(boolKey, testBool), + preferences.setInt(intKey, testInt), + preferences.setDouble(doubleKey, testDouble), + preferences.setStringList(listKey, testList) + ]); + + final Map gotAll = await preferences.getAll(); + + 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('getAll with filter', () async { + final (SharedPreferencesAsync preferences, _) = getPreferences(); + await Future.wait(>[ + preferences.setString(stringKey, testString), + preferences.setBool(boolKey, testBool), + preferences.setInt(intKey, testInt), + preferences.setDouble(doubleKey, testDouble), + preferences.setStringList(listKey, testList) + ]); + + final Map gotAll = + await preferences.getAll(allowList: {stringKey, boolKey}); + + expect(gotAll.length, 2); + expect(gotAll[stringKey], testString); + expect(gotAll[boolKey], testBool); + }); + + test('remove', () async { + final ( + SharedPreferencesAsync preferences, + FakeSharedPreferencesAsync store + ) = getPreferences(); + const String key = 'testKey'; + await preferences.remove(key); + expect( + store.log, + List.filled( + 1, + isMethodCall( + 'clear', + arguments: [key], + ), + growable: true, + )); + }); + + test('getKeys', () async { + final (SharedPreferencesAsync preferences, _) = getPreferences(); + await Future.wait(>[ + preferences.setString(stringKey, testString), + preferences.setBool(boolKey, testBool), + preferences.setInt(intKey, testInt), + preferences.setDouble(doubleKey, testDouble), + preferences.setStringList(listKey, testList) + ]); + + final Set keys = await preferences.getKeys(); + + 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 (SharedPreferencesAsync preferences, _) = getPreferences(); + await Future.wait(>[ + preferences.setString(stringKey, testString), + preferences.setBool(boolKey, testBool), + preferences.setInt(intKey, testInt), + preferences.setDouble(doubleKey, testDouble), + preferences.setStringList(listKey, testList) + ]); + + final Set keys = + await preferences.getKeys(allowList: {stringKey, boolKey}); + + expect(keys.length, 2); + expect(keys, contains(stringKey)); + expect(keys, contains(boolKey)); + }); + + test('containsKey', () async { + final (SharedPreferencesAsync preferences, _) = getPreferences(); + const String key = 'testKey'; + + expect(false, await preferences.containsKey(key)); + + await preferences.setString(key, 'test'); + expect(true, await preferences.containsKey(key)); + }); + + test('clear', () async { + final ( + SharedPreferencesAsync preferences, + FakeSharedPreferencesAsync store + ) = getPreferences(); + await Future.wait(>[ + preferences.setString(stringKey, testString), + preferences.setBool(boolKey, testBool), + preferences.setInt(intKey, testInt), + preferences.setDouble(doubleKey, testDouble), + preferences.setStringList(listKey, testList) + ]); + store.log.clear(); + await preferences.clear(); + expect( + store.log, [isMethodCall('clear', arguments: [])]); + expect(await preferences.getString(stringKey), null); + expect(await preferences.getBool(boolKey), null); + expect(await preferences.getInt(intKey), null); + expect(await preferences.getDouble(doubleKey), null); + expect(await preferences.getStringList(listKey), null); + }); + + test('clear with filter', () async { + final ( + SharedPreferencesAsync preferences, + FakeSharedPreferencesAsync store + ) = getPreferences(); + await Future.wait(>[ + preferences.setString(stringKey, testString), + preferences.setBool(boolKey, testBool), + preferences.setInt(intKey, testInt), + preferences.setDouble(doubleKey, testDouble), + preferences.setStringList(listKey, testList) + ]); + store.log.clear(); + await preferences.clear(allowList: {stringKey, boolKey}); + expect(store.log, [ + isMethodCall('clear', arguments: [stringKey, boolKey]) + ]); + expect(await preferences.getString(stringKey), null); + expect(await preferences.getBool(boolKey), null); + expect(await preferences.getInt(intKey), testInt); + expect(await preferences.getDouble(doubleKey), testDouble); + expect(await preferences.getStringList(listKey), testList); + }); + }); + + group('withCache', () { + Future< + ( + SharedPreferencesWithCache, + FakeSharedPreferencesAsync, + Map, + )> getPreferences() async { + final Map cache = {}; + final FakeSharedPreferencesAsync store = FakeSharedPreferencesAsync(); + SharedPreferencesAsyncPlatform.instance = store; + final SharedPreferencesWithCache preferences = + await SharedPreferencesWithCache.create( + cache: cache, + cacheOptions: const SharedPreferencesWithCacheOptions(), + ); + store.log.clear(); + return (preferences, store, cache); + } + + test('set and get String', () async { + final ( + SharedPreferencesWithCache preferences, + FakeSharedPreferencesAsync store, + _, + ) = await getPreferences(); + await preferences.setString(stringKey, testString); + expect( + store.log, + [ + isMethodCall('setString', arguments: [ + stringKey, + testString, + ]), + ], + ); + store.log.clear(); + expect(preferences.getString(stringKey), testString); + expect( + store.log, + [], + ); + }); + + test('set and get bool', () async { + final ( + SharedPreferencesWithCache preferences, + FakeSharedPreferencesAsync store, + _, + ) = await getPreferences(); + await preferences.setBool(boolKey, testBool); + expect( + store.log, + [ + isMethodCall('setBool', arguments: [ + boolKey, + testBool, + ]), + ], + ); + store.log.clear(); + expect(preferences.getBool(boolKey), testBool); + expect( + store.log, + [], + ); + }); + + test('set and get int', () async { + final ( + SharedPreferencesWithCache preferences, + FakeSharedPreferencesAsync store, + _, + ) = await getPreferences(); + await preferences.setInt(intKey, testInt); + expect( + store.log, + [ + isMethodCall('setInt', arguments: [ + intKey, + testInt, + ]), + ], + ); + store.log.clear(); + + expect(preferences.getInt(intKey), testInt); + expect( + store.log, + [], + ); + }); + + test('set and get double', () async { + final ( + SharedPreferencesWithCache preferences, + FakeSharedPreferencesAsync store, + _, + ) = await getPreferences(); + await preferences.setDouble(doubleKey, testDouble); + expect( + store.log, + [ + isMethodCall('setDouble', arguments: [ + doubleKey, + testDouble, + ]), + ], + ); + store.log.clear(); + expect(preferences.getDouble(doubleKey), testDouble); + expect( + store.log, + [], + ); + }); + + test('set and get StringList', () async { + final ( + SharedPreferencesWithCache preferences, + FakeSharedPreferencesAsync store, + _, + ) = await getPreferences(); + await preferences.setStringList(listKey, testList); + expect( + store.log, + [ + isMethodCall('setStringList', arguments: [ + listKey, + testList, + ]), + ], + ); + store.log.clear(); + expect(preferences.getStringList(listKey), testList); + expect( + store.log, + [], + ); + }); + + test('reloading', () async { + final ( + SharedPreferencesWithCache preferences, + _, + Map cache, + ) = await getPreferences(); + await preferences.setString(stringKey, testString); + expect(preferences.getString(stringKey), testString); + + cache.clear(); + expect(preferences.getString(stringKey), null); + + await preferences.reloadCache(); + expect(preferences.getString(stringKey), testString); + }); + + test('containsKey', () async { + final ( + SharedPreferencesWithCache preferences, + _, + _, + ) = await getPreferences(); + const String key = 'testKey'; + + expect(false, preferences.containsKey(key)); + + await preferences.setString(key, 'test'); + expect(true, preferences.containsKey(key)); + }); + + test('getKeys', () async { + final ( + SharedPreferencesWithCache preferences, + _, + _, + ) = await getPreferences(); + await Future.wait(>[ + preferences.setString(stringKey, testString), + preferences.setBool(boolKey, testBool), + preferences.setInt(intKey, testInt), + preferences.setDouble(doubleKey, testDouble), + preferences.setStringList(listKey, testList) + ]); + + final Set keys = preferences.keys; + + 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('remove', () async { + final ( + SharedPreferencesWithCache preferences, + FakeSharedPreferencesAsync store, + _, + ) = await getPreferences(); + const String key = 'testKey'; + await preferences.remove(key); + expect( + store.log, + List.filled( + 1, + isMethodCall( + 'clear', + arguments: [key], + ), + growable: true, + )); + }); + + test('clear', () async { + final ( + SharedPreferencesWithCache preferences, + FakeSharedPreferencesAsync store, + _, + ) = await getPreferences(); + await Future.wait(>[ + preferences.setString(stringKey, testString), + preferences.setBool(boolKey, testBool), + preferences.setInt(intKey, testInt), + preferences.setDouble(doubleKey, testDouble), + preferences.setStringList(listKey, testList) + ]); + store.log.clear(); + await preferences.clear(); + expect( + store.log, [isMethodCall('clear', arguments: [])]); + expect(preferences.getString(stringKey), null); + expect(preferences.getBool(boolKey), null); + expect(preferences.getInt(intKey), null); + expect(preferences.getDouble(doubleKey), null); + expect(preferences.getStringList(listKey), null); + }); + }); + + group('withCache with filter', () { + Future< + ( + SharedPreferencesWithCache, + FakeSharedPreferencesAsync, + Map, + )> getPreferences() async { + final Map cache = {}; + final FakeSharedPreferencesAsync store = FakeSharedPreferencesAsync(); + SharedPreferencesAsyncPlatform.instance = store; + final SharedPreferencesWithCache preferences = + await SharedPreferencesWithCache.create( + cache: cache, + cacheOptions: + const SharedPreferencesWithCacheOptions(allowList: { + stringKey, + boolKey, + intKey, + doubleKey, + listKey, + }), + ); + store.log.clear(); + return (preferences, store, cache); + } + + test('set and get String', () async { + final ( + SharedPreferencesWithCache preferences, + FakeSharedPreferencesAsync store, + _, + ) = await getPreferences(); + await preferences.setString(stringKey, testString); + expect( + store.log, + [ + isMethodCall('setString', arguments: [ + stringKey, + testString, + ]), + ], + ); + store.log.clear(); + expect(preferences.getString(stringKey), testString); + expect( + store.log, + [], + ); + }); + + test('set and get bool', () async { + final ( + SharedPreferencesWithCache preferences, + FakeSharedPreferencesAsync store, + _, + ) = await getPreferences(); + await preferences.setBool(boolKey, testBool); + expect( + store.log, + [ + isMethodCall('setBool', arguments: [ + boolKey, + testBool, + ]), + ], + ); + store.log.clear(); + expect(preferences.getBool(boolKey), testBool); + expect( + store.log, + [], + ); + }); + + test('set and get int', () async { + final ( + SharedPreferencesWithCache preferences, + FakeSharedPreferencesAsync store, + _, + ) = await getPreferences(); + await preferences.setInt(intKey, testInt); + expect( + store.log, + [ + isMethodCall('setInt', arguments: [ + intKey, + testInt, + ]), + ], + ); + store.log.clear(); + + expect(preferences.getInt(intKey), testInt); + expect( + store.log, + [], + ); + }); + + test('set and get double', () async { + final ( + SharedPreferencesWithCache preferences, + FakeSharedPreferencesAsync store, + _, + ) = await getPreferences(); + await preferences.setDouble(doubleKey, testDouble); + expect( + store.log, + [ + isMethodCall('setDouble', arguments: [ + doubleKey, + testDouble, + ]), + ], + ); + store.log.clear(); + expect(preferences.getDouble(doubleKey), testDouble); + expect( + store.log, + [], + ); + }); + + test('set and get StringList', () async { + final ( + SharedPreferencesWithCache preferences, + FakeSharedPreferencesAsync store, + _, + ) = await getPreferences(); + await preferences.setStringList(listKey, testList); + expect( + store.log, + [ + isMethodCall('setStringList', arguments: [ + listKey, + testList, + ]), + ], + ); + store.log.clear(); + expect(preferences.getStringList(listKey), testList); + expect( + store.log, + [], + ); + }); + test('reloading', () async { + final ( + SharedPreferencesWithCache preferences, + _, + Map cache, + ) = await getPreferences(); + await preferences.setString(stringKey, testString); + expect(preferences.getString(stringKey), testString); + + cache.clear(); + expect(preferences.getString(stringKey), null); + + await preferences.reloadCache(); + expect(preferences.getString(stringKey), testString); + }); + + test('throws ArgumentError if key is not included in filter', () async { + final ( + SharedPreferencesWithCache preferences, + _, + _, + ) = await getPreferences(); + const String key = 'testKey'; + + expect( + () async => preferences.setString(key, 'test'), throwsArgumentError); + }); + + test('containsKey', () async { + final ( + SharedPreferencesWithCache preferences, + _, + _, + ) = await getPreferences(); + + expect(false, preferences.containsKey(stringKey)); + + await preferences.setString(stringKey, 'test'); + expect(true, preferences.containsKey(stringKey)); + }); + + test('getKeys', () async { + final ( + SharedPreferencesWithCache preferences, + _, + _, + ) = await getPreferences(); + await Future.wait(>[ + preferences.setString(stringKey, testString), + preferences.setBool(boolKey, testBool), + preferences.setInt(intKey, testInt), + preferences.setDouble(doubleKey, testDouble), + preferences.setStringList(listKey, testList) + ]); + + final Set keys = preferences.keys; + + 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('remove', () async { + final ( + SharedPreferencesWithCache preferences, + FakeSharedPreferencesAsync store, + _, + ) = await getPreferences(); + await preferences.remove(stringKey); + expect( + store.log, + List.filled( + 1, + isMethodCall( + 'clear', + arguments: [stringKey], + ), + growable: true, + )); + }); + + test('clear', () async { + final ( + SharedPreferencesWithCache preferences, + FakeSharedPreferencesAsync store, + _, + ) = await getPreferences(); + await Future.wait(>[ + preferences.setString(stringKey, testString), + preferences.setBool(boolKey, testBool), + preferences.setInt(intKey, testInt), + preferences.setDouble(doubleKey, testDouble), + preferences.setStringList(listKey, testList) + ]); + store.log.clear(); + await preferences.clear(); + expect(store.log, [ + isMethodCall('clear', arguments: [ + stringKey, + boolKey, + intKey, + doubleKey, + listKey, + ]) + ]); + + expect(preferences.getString(stringKey), null); + expect(preferences.getBool(boolKey), null); + // The cache will clear everything, even though the backend will still hold this data. + // Since the cache shouldn't ever be able to add data that isn't in the allowlist, + // this is expected behavior. + expect(preferences.getInt(intKey), null); + expect(preferences.getDouble(doubleKey), null); + expect(preferences.getStringList(listKey), null); + }); + }); +} + +base class FakeSharedPreferencesAsync extends SharedPreferencesAsyncPlatform { + final InMemorySharedPreferencesAsync backend = + InMemorySharedPreferencesAsync.empty(); + final List log = []; + + @override + Future clear( + ClearPreferencesParameters parameters, SharedPreferencesOptions options) { + log.add(MethodCall('clear', [...?parameters.filter.allowList])); + return backend.clear(parameters, options); + } + + @override + Future getBool(String key, SharedPreferencesOptions options) { + log.add(MethodCall('getBool', [key])); + return backend.getBool(key, options); + } + + @override + Future getDouble(String key, SharedPreferencesOptions options) { + log.add(MethodCall('getDouble', [key])); + return backend.getDouble(key, options); + } + + @override + Future getInt(String key, SharedPreferencesOptions options) { + log.add(MethodCall('getInt', [key])); + return backend.getInt(key, options); + } + + @override + Future> getKeys( + GetPreferencesParameters parameters, SharedPreferencesOptions options) { + log.add(MethodCall('getKeys', [...?parameters.filter.allowList])); + return backend.getKeys(parameters, options); + } + + @override + Future> getPreferences( + GetPreferencesParameters parameters, SharedPreferencesOptions options) { + log.add(MethodCall( + 'getPreferences', [...?parameters.filter.allowList])); + return backend.getPreferences(parameters, options); + } + + @override + Future getString(String key, SharedPreferencesOptions options) { + log.add(MethodCall('getString', [key])); + return backend.getString(key, options); + } + + @override + Future?> getStringList( + String key, SharedPreferencesOptions options) { + log.add(MethodCall('getStringList', [key])); + return backend.getStringList(key, options); + } + + @override + Future setBool( + String key, bool value, SharedPreferencesOptions options) { + log.add(MethodCall('setBool', [key, value])); + return backend.setBool(key, value, options); + } + + @override + Future setDouble( + String key, double value, SharedPreferencesOptions options) { + log.add(MethodCall('setDouble', [key, value])); + return backend.setDouble(key, value, options); + } + + @override + Future setInt(String key, int value, SharedPreferencesOptions options) { + log.add(MethodCall('setInt', [key, value])); + return backend.setInt(key, value, options); + } + + @override + Future setString( + String key, String value, SharedPreferencesOptions options) { + log.add(MethodCall('setString', [key, value])); + return backend.setString(key, value, options); + } + + @override + Future setStringList( + String key, List value, SharedPreferencesOptions options) { + log.add(MethodCall('setStringList', [key, value])); + return backend.setStringList(key, value, options); + } +} diff --git a/packages/shared_preferences/shared_preferences/test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences/test/shared_preferences_test.dart index f7f5ea355d1f..275b3ca7f7a7 100755 --- a/packages/shared_preferences/shared_preferences/test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences/test/shared_preferences_test.dart @@ -28,7 +28,7 @@ void main() { const bool testBool2 = false; const int testInt2 = 1337; const double testDouble2 = 2.71828; - const List testList2 = ['baz', 'quox']; + const List testList2 = ['baz', 'qux']; const Map testValues2 = { 'flutter.String': testString2, 'flutter.bool': testBool2, @@ -319,23 +319,25 @@ void main() { "Shared Preferences doesn't yet support the setPrefix method")); }); - test('non-Unimplemented errors pass through withParameters methods correctly', - () async { - final ThrowingSharedPreferencesStore localStore = - ThrowingSharedPreferencesStore(); - SharedPreferencesStorePlatform.instance = localStore; - SharedPreferences.resetStatic(); - SharedPreferences.setPrefix(''); - Object? err; - - try { - await SharedPreferences.getInstance(); - } catch (e) { - err = e; - } - expect(err, isA()); - expect(err.toString(), contains('State Error')); - }); + test( + 'non-Unimplemented errors pass through withParameters methods correctly', + () async { + final ThrowingSharedPreferencesStore localStore = + ThrowingSharedPreferencesStore(); + SharedPreferencesStorePlatform.instance = localStore; + SharedPreferences.resetStatic(); + SharedPreferences.setPrefix(''); + Object? err; + + try { + await SharedPreferences.getInstance(); + } catch (e) { + err = e; + } + expect(err, isA()); + expect(err.toString(), contains('State Error')); + }, + ); } class FakeSharedPreferencesStore extends SharedPreferencesStorePlatform { diff --git a/packages/shared_preferences/shared_preferences_android/CHANGELOG.md b/packages/shared_preferences/shared_preferences_android/CHANGELOG.md index aa4279ede837..8061930e0310 100644 --- a/packages/shared_preferences/shared_preferences_android/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_android/CHANGELOG.md @@ -1,3 +1,24 @@ +## 2.3.3 + +* Updates Java compatibility version to 11. +* Updates minimum supported SDK version to Flutter 3.24/Dart 3.5. + +## 2.3.2 + +* Bumps `com.android.tools.build:gradle` from 7.2.2 to 8.5.1. + +## 2.3.1 + +* Fixes `getStringList` returning immutable list. + +## 2.3.0 + +* Adds new `SharedPreferencesAsyncAndroid` API. + +## 2.2.4 + +* Updates lint checks to ignore NewerVersionAvailable. + ## 2.2.3 * Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. diff --git a/packages/shared_preferences/shared_preferences_android/README.md b/packages/shared_preferences/shared_preferences_android/README.md index 6d30be341c9c..d12b09c068a2 100644 --- a/packages/shared_preferences/shared_preferences_android/README.md +++ b/packages/shared_preferences/shared_preferences_android/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/shared_preferences -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[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 291be9625655..05eab6f253fb 100644 --- a/packages/shared_preferences/shared_preferences_android/android/build.gradle +++ b/packages/shared_preferences/shared_preferences_android/android/build.gradle @@ -2,13 +2,15 @@ group 'io.flutter.plugins.sharedpreferences' version '1.0-SNAPSHOT' buildscript { + ext.kotlin_version = '1.7.10' repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.2.2' + classpath 'com.android.tools.build:gradle:8.5.1' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } @@ -28,17 +30,23 @@ allprojects { } apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' android { - // Conditional for compatibility with AGP <4.2. - if (project.android.hasProperty("namespace")) { - namespace 'io.flutter.plugins.sharedpreferences' - } + namespace 'io.flutter.plugins.sharedpreferences' compileSdk 34 compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 + } + + kotlinOptions { + jvmTarget = '11' + } + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' } defaultConfig { @@ -48,11 +56,17 @@ android { lintOptions { checkAllWarnings true warningsAsErrors true - disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency' + disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency', 'NewerVersionAvailable' } dependencies { + implementation 'androidx.datastore:datastore:1.0.0' + implementation 'androidx.datastore:datastore-preferences:1.0.0' testImplementation 'junit:junit:4.13.2' + testImplementation 'androidx.test:core-ktx:1.5.0' + testImplementation 'androidx.test.ext:junit-ktx:1.1.5' + testImplementation 'org.robolectric:robolectric:4.12.1' testImplementation 'org.mockito:mockito-inline:5.2.0' + testImplementation 'io.mockk:mockk:1.13.12' } diff --git a/packages/shared_preferences/shared_preferences_android/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java b/packages/shared_preferences/shared_preferences_android/android/src/main/java/io/flutter/plugins/sharedpreferences/LegacySharedPreferencesPlugin.java similarity index 95% rename from packages/shared_preferences/shared_preferences_android/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java rename to packages/shared_preferences/shared_preferences_android/android/src/main/java/io/flutter/plugins/sharedpreferences/LegacySharedPreferencesPlugin.java index 6bfa4e285a6c..7d4dfd5d7e42 100644 --- a/packages/shared_preferences/shared_preferences_android/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java +++ b/packages/shared_preferences/shared_preferences_android/android/src/main/java/io/flutter/plugins/sharedpreferences/LegacySharedPreferencesPlugin.java @@ -27,8 +27,8 @@ import java.util.Map; import java.util.Set; -/** SharedPreferencesPlugin */ -public class SharedPreferencesPlugin implements FlutterPlugin, SharedPreferencesApi { +/** LegacySharedPreferencesPlugin */ +public class LegacySharedPreferencesPlugin implements FlutterPlugin, SharedPreferencesApi { private static final String TAG = "SharedPreferencesPlugin"; private static final String SHARED_PREFERENCES_NAME = "FlutterSharedPreferences"; private static final String LIST_IDENTIFIER = "VGhpcyBpcyB0aGUgcHJlZml4IGZvciBhIGxpc3Qu"; @@ -38,19 +38,19 @@ public class SharedPreferencesPlugin implements FlutterPlugin, SharedPreferences private SharedPreferences preferences; private SharedPreferencesListEncoder listEncoder; - public SharedPreferencesPlugin() { + public LegacySharedPreferencesPlugin() { this(new ListEncoder()); } @VisibleForTesting - SharedPreferencesPlugin(@NonNull SharedPreferencesListEncoder listEncoder) { + LegacySharedPreferencesPlugin(@NonNull SharedPreferencesListEncoder listEncoder) { this.listEncoder = listEncoder; } private void setUp(@NonNull BinaryMessenger messenger, @NonNull Context context) { preferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); try { - SharedPreferencesApi.setup(messenger, this); + SharedPreferencesApi.setUp(messenger, this); } catch (Exception ex) { Log.e(TAG, "Received exception while setting up SharedPreferencesPlugin", ex); } @@ -63,7 +63,7 @@ public void onAttachedToEngine(@NonNull FlutterPlugin.FlutterPluginBinding bindi @Override public void onDetachedFromEngine(@NonNull FlutterPlugin.FlutterPluginBinding binding) { - SharedPreferencesApi.setup(binding.getBinaryMessenger(), null); + SharedPreferencesApi.setUp(binding.getBinaryMessenger(), null); } @Override diff --git a/packages/shared_preferences/shared_preferences_android/android/src/main/java/io/flutter/plugins/sharedpreferences/Messages.java b/packages/shared_preferences/shared_preferences_android/android/src/main/java/io/flutter/plugins/sharedpreferences/Messages.java index 26fb7958fa96..4041ad9aa6f2 100644 --- a/packages/shared_preferences/shared_preferences_android/android/src/main/java/io/flutter/plugins/sharedpreferences/Messages.java +++ b/packages/shared_preferences/shared_preferences_android/android/src/main/java/io/flutter/plugins/sharedpreferences/Messages.java @@ -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 (v9.2.5), do not edit directly. +// Autogenerated from Pigeon (v16.0.4), do not edit directly. // See also: https://pub.dev/packages/pigeon package io.flutter.plugins.sharedpreferences; @@ -88,14 +88,14 @@ public interface SharedPreferencesApi { * Sets up an instance of `SharedPreferencesApi` to handle messages through the * `binaryMessenger`. */ - static void setup( + static void setUp( @NonNull BinaryMessenger binaryMessenger, @Nullable SharedPreferencesApi api) { { BinaryMessenger.TaskQueue taskQueue = binaryMessenger.makeBackgroundTaskQueue(); BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.SharedPreferencesApi.remove", + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesApi.remove", getCodec(), taskQueue); if (api != null) { @@ -122,7 +122,7 @@ static void setup( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.SharedPreferencesApi.setBool", + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesApi.setBool", getCodec(), taskQueue); if (api != null) { @@ -150,7 +150,7 @@ static void setup( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.SharedPreferencesApi.setString", + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesApi.setString", getCodec(), taskQueue); if (api != null) { @@ -178,7 +178,7 @@ static void setup( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.SharedPreferencesApi.setInt", + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesApi.setInt", getCodec(), taskQueue); if (api != null) { @@ -207,7 +207,7 @@ static void setup( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.SharedPreferencesApi.setDouble", + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesApi.setDouble", getCodec(), taskQueue); if (api != null) { @@ -235,7 +235,7 @@ static void setup( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.SharedPreferencesApi.setStringList", + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesApi.setStringList", getCodec(), taskQueue); if (api != null) { @@ -263,7 +263,7 @@ static void setup( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.SharedPreferencesApi.clear", + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesApi.clear", getCodec(), taskQueue); if (api != null) { @@ -291,7 +291,7 @@ static void setup( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.SharedPreferencesApi.getAll", + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesApi.getAll", getCodec(), taskQueue); if (api != null) { 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 new file mode 100644 index 000000000000..159253f4280e --- /dev/null +++ b/packages/shared_preferences/shared_preferences_android/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/MessagesAsync.g.kt @@ -0,0 +1,453 @@ +// 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. +// See also: https://pub.dev/packages/pigeon + +package io.flutter.plugins.sharedpreferences + +import android.util.Log +import io.flutter.plugin.common.BasicMessageChannel +import io.flutter.plugin.common.BinaryMessenger +import io.flutter.plugin.common.MessageCodec +import io.flutter.plugin.common.StandardMessageCodec +import java.io.ByteArrayOutputStream +import java.nio.ByteBuffer + +private fun wrapResult(result: Any?): List { + return listOf(result) +} + +private fun wrapError(exception: Throwable): List { + if (exception is SharedPreferencesError) { + return listOf(exception.code, exception.message, exception.details) + } else { + return listOf( + exception.javaClass.simpleName, + exception.toString(), + "Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception)) + } +} + +/** + * Error class for passing custom error details to Flutter via a thrown PlatformException. + * + * @property code The error code. + * @property message The error message. + * @property details The error details. Must be a datatype supported by the api codec. + */ +class SharedPreferencesError( + val code: String, + override val message: String? = null, + val details: Any? = null +) : Throwable() + +/** Generated class from Pigeon that represents data sent in messages. */ +data class SharedPreferencesPigeonOptions(val fileKey: String? = null) { + + companion object { + @Suppress("UNCHECKED_CAST") + fun fromList(list: List): SharedPreferencesPigeonOptions { + val fileKey = list[0] as String? + return SharedPreferencesPigeonOptions(fileKey) + } + } + + fun toList(): List { + return listOf( + fileKey, + ) + } +} + +@Suppress("UNCHECKED_CAST") +private object SharedPreferencesAsyncApiCodec : StandardMessageCodec() { + override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? { + return when (type) { + 128.toByte() -> { + return (readValue(buffer) as? List)?.let { + SharedPreferencesPigeonOptions.fromList(it) + } + } + else -> super.readValueOfType(type, buffer) + } + } + + override fun writeValue(stream: ByteArrayOutputStream, value: Any?) { + when (value) { + is SharedPreferencesPigeonOptions -> { + stream.write(128) + writeValue(stream, value.toList()) + } + else -> super.writeValue(stream, value) + } + } +} + +/** Generated interface from Pigeon that represents a handler of messages from Flutter. */ +interface SharedPreferencesAsyncApi { + /** Adds property to shared preferences data set of type bool. */ + fun setBool(key: String, value: Boolean, options: SharedPreferencesPigeonOptions) + /** Adds property to shared preferences data set of type String. */ + fun setString(key: String, value: String, options: SharedPreferencesPigeonOptions) + /** Adds property to shared preferences data set of type int. */ + fun setInt(key: String, value: Long, options: SharedPreferencesPigeonOptions) + /** Adds property to shared preferences data set of type double. */ + fun setDouble(key: String, value: Double, options: SharedPreferencesPigeonOptions) + /** Adds property to shared preferences data set of type List. */ + fun setStringList(key: String, value: List, options: SharedPreferencesPigeonOptions) + /** Gets individual String value stored with [key], if any. */ + fun getString(key: String, options: SharedPreferencesPigeonOptions): String? + /** Gets individual void value stored with [key], if any. */ + fun getBool(key: String, options: SharedPreferencesPigeonOptions): Boolean? + /** Gets individual double value stored with [key], if any. */ + fun getDouble(key: String, options: SharedPreferencesPigeonOptions): Double? + /** Gets individual int value stored with [key], if any. */ + fun getInt(key: String, options: SharedPreferencesPigeonOptions): Long? + /** Gets individual List value stored with [key], if any. */ + fun getStringList(key: String, options: SharedPreferencesPigeonOptions): List? + /** Removes all properties from shared preferences data set with matching prefix. */ + fun clear(allowList: List?, options: SharedPreferencesPigeonOptions) + /** Gets all properties from shared preferences data set with matching prefix. */ + fun getAll(allowList: List?, options: SharedPreferencesPigeonOptions): Map + /** Gets all properties from shared preferences data set with matching prefix. */ + fun getKeys(allowList: List?, options: SharedPreferencesPigeonOptions): List + + companion object { + /** The codec used by SharedPreferencesAsyncApi. */ + val codec: MessageCodec by lazy { SharedPreferencesAsyncApiCodec } + /** + * Sets up an instance of `SharedPreferencesAsyncApi` to handle messages through the + * `binaryMessenger`. + */ + @Suppress("UNCHECKED_CAST") + fun setUp(binaryMessenger: BinaryMessenger, api: SharedPreferencesAsyncApi?) { + run { + val taskQueue = binaryMessenger.makeBackgroundTaskQueue() + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setBool", + codec, + taskQueue) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + 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) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val taskQueue = binaryMessenger.makeBackgroundTaskQueue() + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setString", + codec, + taskQueue) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + 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) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val taskQueue = binaryMessenger.makeBackgroundTaskQueue() + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setInt", + 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 optionsArg = args[2] as SharedPreferencesPigeonOptions + var wrapped: List + try { + api.setInt(keyArg, valueArg, optionsArg) + wrapped = listOf(null) + } catch (exception: Throwable) { + wrapped = wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val taskQueue = binaryMessenger.makeBackgroundTaskQueue() + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setDouble", + codec, + taskQueue) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + 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) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val taskQueue = binaryMessenger.makeBackgroundTaskQueue() + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setStringList", + codec, + taskQueue) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + 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) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getString", + codec) + 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) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getBool", + codec) + 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) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getDouble", + codec) + 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) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getInt", + codec) + 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) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getStringList", + codec) + 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) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val taskQueue = binaryMessenger.makeBackgroundTaskQueue() + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.clear", + codec, + taskQueue) + if (api != null) { + channel.setMessageHandler { message, reply -> + 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) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val taskQueue = binaryMessenger.makeBackgroundTaskQueue() + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getAll", + codec, + taskQueue) + if (api != null) { + channel.setMessageHandler { message, reply -> + 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) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val taskQueue = binaryMessenger.makeBackgroundTaskQueue() + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getKeys", + codec, + taskQueue) + if (api != null) { + channel.setMessageHandler { message, reply -> + 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) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } + } +} 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 new file mode 100644 index 000000000000..cb42dec87d98 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_android/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.kt @@ -0,0 +1,274 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.sharedpreferences + +import android.content.Context +import android.util.Base64 +import android.util.Log +import androidx.annotation.VisibleForTesting +import androidx.datastore.core.DataStore +import androidx.datastore.preferences.core.Preferences +import androidx.datastore.preferences.core.booleanPreferencesKey +import androidx.datastore.preferences.core.doublePreferencesKey +import androidx.datastore.preferences.core.edit +import androidx.datastore.preferences.core.longPreferencesKey +import androidx.datastore.preferences.core.stringPreferencesKey +import androidx.datastore.preferences.preferencesDataStore +import io.flutter.embedding.engine.plugins.FlutterPlugin +import io.flutter.plugin.common.BinaryMessenger +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import java.io.ObjectInputStream +import java.io.ObjectOutputStream +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.runBlocking + +const val TAG = "SharedPreferencesPlugin" +const val SHARED_PREFERENCES_NAME = "FlutterSharedPreferences" +const val LIST_PREFIX = "VGhpcyBpcyB0aGUgcHJlZml4IGZvciBhIGxpc3Qu" + +private val Context.sharedPreferencesDataStore: DataStore by + preferencesDataStore(SHARED_PREFERENCES_NAME) + +/// SharedPreferencesPlugin +class SharedPreferencesPlugin() : FlutterPlugin, SharedPreferencesAsyncApi { + private lateinit var context: Context + + private var listEncoder = ListEncoder() as SharedPreferencesListEncoder + + @VisibleForTesting + constructor(listEncoder: SharedPreferencesListEncoder) : this() { + this.listEncoder = listEncoder + } + + private fun setUp(messenger: BinaryMessenger, context: Context) { + this.context = context + try { + SharedPreferencesAsyncApi.setUp(messenger, this) + } catch (ex: Exception) { + Log.e(TAG, "Received exception while setting up SharedPreferencesPlugin", ex) + } + } + + override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) { + setUp(binding.binaryMessenger, binding.applicationContext) + LegacySharedPreferencesPlugin().onAttachedToEngine(binding) + } + + override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { + SharedPreferencesAsyncApi.setUp(binding.binaryMessenger, null) + } + + /** Adds property to data store of type bool. */ + override fun setBool(key: String, value: Boolean, options: SharedPreferencesPigeonOptions) { + return runBlocking { + val boolKey = booleanPreferencesKey(key) + context.sharedPreferencesDataStore.edit { preferences -> preferences[boolKey] = value } + } + } + + /** Adds property to data store of type String. */ + override fun setString(key: String, value: String, options: SharedPreferencesPigeonOptions) { + return runBlocking { dataStoreSetString(key, value) } + } + + private suspend fun dataStoreSetString(key: String, value: String) { + val stringKey = stringPreferencesKey(key) + context.sharedPreferencesDataStore.edit { preferences -> preferences[stringKey] = value } + } + + /** 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 runBlocking { + val intKey = longPreferencesKey(key) + context.sharedPreferencesDataStore.edit { preferences -> preferences[intKey] = value } + } + } + + /** Adds property to data store of type double. */ + override fun setDouble(key: String, value: Double, options: SharedPreferencesPigeonOptions) { + return runBlocking { + val doubleKey = doublePreferencesKey(key) + context.sharedPreferencesDataStore.edit { preferences -> preferences[doubleKey] = value } + } + } + + /** 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 runBlocking { dataStoreSetString(key, valueString) } + } + + /** Removes all properties from data store. */ + override fun clear(allowList: List?, options: SharedPreferencesPigeonOptions) { + runBlocking { + context.sharedPreferencesDataStore.edit { preferences -> + allowList?.let { list -> + list.forEach { key -> + val preferencesKey = booleanPreferencesKey(key) + preferences.remove(preferencesKey) + } + } ?: preferences.clear() + } + } + } + + /** Gets all properties from data store. */ + override fun getAll( + allowList: List?, + options: SharedPreferencesPigeonOptions + ): Map { + return runBlocking { getPrefs(allowList) } + } + + /** Gets int (as long) at [key] from data store. */ + override fun getInt(key: String, options: SharedPreferencesPigeonOptions): Long? { + val value: Long? + runBlocking { + val preferencesKey = longPreferencesKey(key) + val preferenceFlow: Flow = + context.sharedPreferencesDataStore.data.map { preferences -> preferences[preferencesKey] } + + value = preferenceFlow.firstOrNull() + } + return value + } + + /** 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 = + context.sharedPreferencesDataStore.data.map { preferences -> preferences[preferencesKey] } + + value = preferenceFlow.firstOrNull() + } + return value + } + /** Gets double at [key] from data store. */ + override fun getDouble(key: String, options: SharedPreferencesPigeonOptions): Double? { + val value: Double? + runBlocking { + val preferencesKey = stringPreferencesKey(key) + val preferenceFlow: Flow = + context.sharedPreferencesDataStore.data.map { preferences -> + transformPref(preferences[preferencesKey] as Any?) as Double? + } + + value = preferenceFlow.firstOrNull() + } + return value + } + + /** Gets String at [key] from data store. */ + override fun getString(key: String, options: SharedPreferencesPigeonOptions): String? { + val value: String? + runBlocking { + val preferencesKey = stringPreferencesKey(key) + val preferenceFlow: Flow = + context.sharedPreferencesDataStore.data.map { preferences -> preferences[preferencesKey] } + + value = preferenceFlow.firstOrNull() + } + return value + } + + /** 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() + } + + /** Gets all properties from data store. */ + override fun getKeys( + allowList: List?, + options: SharedPreferencesPigeonOptions + ): List { + val prefs = runBlocking { getPrefs(allowList) } + return prefs.keys.toList() + } + + private suspend fun getPrefs(allowList: List?): Map { + val allowSet = allowList?.toSet() + val filteredMap = mutableMapOf() + + val keys = readAllKeys() + keys?.forEach() { key -> + val value = getValueByKey(key) + if (preferencesFilter(key.toString(), value, allowSet)) { + val transformedValue = transformPref(value) + if (transformedValue != null) { + filteredMap[key.toString()] = transformedValue + } + } + } + return filteredMap + } + + private suspend fun readAllKeys(): Set>? { + val keys = context.sharedPreferencesDataStore.data.map { it.asMap().keys } + return keys.firstOrNull() + } + + private suspend fun getValueByKey(key: Preferences.Key<*>): Any? { + val value = context.sharedPreferencesDataStore.data.map { it[key] } + return value.firstOrNull() + } + + /** + * 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 + } + + return allowList.contains(key) + } + + /** 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)) + } + } + return value + } + + /** Class that provides tools for encoding and decoding List to String and back. */ + class ListEncoder : SharedPreferencesListEncoder { + override fun encode(list: List): String { + try { + val byteStream = ByteArrayOutputStream() + val stream = ObjectOutputStream(byteStream) + stream.writeObject(list) + stream.flush() + return Base64.encodeToString(byteStream.toByteArray(), 0) + } catch (e: RuntimeException) { + throw RuntimeException(e) + } + } + + override fun decode(listString: String): List { + try { + val byteArray = Base64.decode(listString, 0) + val stream = ObjectInputStream(ByteArrayInputStream(byteArray)) + return (stream.readObject() as List<*>).filterIsInstance() + } catch (e: RuntimeException) { + throw RuntimeException(e) + } + } + } +} diff --git a/packages/shared_preferences/shared_preferences_android/android/src/test/java/io/flutter/plugins/sharedpreferences/SharedPreferencesTest.java b/packages/shared_preferences/shared_preferences_android/android/src/test/java/io/flutter/plugins/sharedpreferences/LegacySharedPreferencesTest.java similarity index 90% rename from packages/shared_preferences/shared_preferences_android/android/src/test/java/io/flutter/plugins/sharedpreferences/SharedPreferencesTest.java rename to packages/shared_preferences/shared_preferences_android/android/src/test/java/io/flutter/plugins/sharedpreferences/LegacySharedPreferencesTest.java index 19debfeff78e..08bbf2fe219f 100644 --- a/packages/shared_preferences/shared_preferences_android/android/src/test/java/io/flutter/plugins/sharedpreferences/SharedPreferencesTest.java +++ b/packages/shared_preferences/shared_preferences_android/android/src/test/java/io/flutter/plugins/sharedpreferences/LegacySharedPreferencesTest.java @@ -6,6 +6,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyString; @@ -15,6 +16,7 @@ import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.plugin.common.BinaryMessenger; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -24,9 +26,9 @@ import org.mockito.Mock; import org.mockito.Mockito; -public class SharedPreferencesTest { +public class LegacySharedPreferencesTest { - SharedPreferencesPlugin plugin; + LegacySharedPreferencesPlugin plugin; @Mock BinaryMessenger mockMessenger; @Mock FlutterPlugin.FlutterPluginBinding flutterPluginBinding; @@ -42,7 +44,7 @@ public void before() { Mockito.when(flutterPluginBinding.getApplicationContext()).thenReturn(context); Mockito.when(context.getSharedPreferences(anyString(), anyInt())).thenReturn(sharedPrefs); - plugin = new SharedPreferencesPlugin(new ListEncoder()); + plugin = new LegacySharedPreferencesPlugin(new ListEncoder()); plugin.onAttachedToEngine(flutterPluginBinding); } @@ -92,24 +94,24 @@ public void allowList() { addData(); - final List allowList = Arrays.asList("flutter.Language"); + final List allowList = Collections.singletonList("flutter.Language"); Map allData = plugin.getAll("flutter.", allowList); assertEquals(allData.size(), 1); assertEquals(allData.get("flutter.Language"), "Java"); - assertEquals(allData.get("flutter.Counter"), null); + assertNull(allData.get("flutter.Counter")); allData = plugin.getAll("", allowList); assertEquals(allData.size(), 1); assertEquals(allData.get("flutter.Language"), "Java"); - assertEquals(allData.get("flutter.Counter"), null); + assertNull(allData.get("flutter.Counter")); allData = plugin.getAll("prefix.", allowList); assertEquals(allData.size(), 0); - assertEquals(allData.get("flutter.Language"), null); + assertNull(allData.get("flutter.Language")); } @Test @@ -174,7 +176,7 @@ public void clearWithAllowList() { assertEquals(plugin.getAll("", null).size(), 15); - plugin.clear("flutter.", Arrays.asList("flutter.Language")); + plugin.clear("flutter.", Collections.singletonList("flutter.Language")); assertEquals(plugin.getAll("", null).size(), 14); } @@ -240,26 +242,25 @@ public static class FakeSharedPreferencesEditor implements SharedPreferences.Edi } @Override - public @NonNull SharedPreferences.Editor putBoolean( - @NonNull String key, @NonNull boolean value) { + public @NonNull SharedPreferences.Editor putBoolean(@NonNull String key, boolean value) { sharedPrefData.put(key, value); return this; } @Override - public @NonNull SharedPreferences.Editor putInt(@NonNull String key, @NonNull int value) { + public @NonNull SharedPreferences.Editor putInt(@NonNull String key, int value) { sharedPrefData.put(key, value); return this; } @Override - public @NonNull SharedPreferences.Editor putLong(@NonNull String key, @NonNull long value) { + public @NonNull SharedPreferences.Editor putLong(@NonNull String key, long value) { sharedPrefData.put(key, value); return this; } @Override - public @NonNull SharedPreferences.Editor putFloat(@NonNull String key, @NonNull float value) { + public @NonNull SharedPreferences.Editor putFloat(@NonNull String key, float value) { sharedPrefData.put(key, value); return this; } @@ -271,7 +272,7 @@ public static class FakeSharedPreferencesEditor implements SharedPreferences.Edi } @Override - public @NonNull boolean commit() { + public boolean commit() { return true; } @@ -303,27 +304,27 @@ private static class FakeSharedPreferences implements SharedPreferences { // All methods below are not implemented. @Override - public @NonNull boolean contains(@NonNull String key) { + public boolean contains(@NonNull String key) { throw new UnsupportedOperationException("This method is not implemented for testing"); } @Override - public @NonNull boolean getBoolean(@NonNull String key, @NonNull boolean defValue) { + public boolean getBoolean(@NonNull String key, boolean defValue) { throw new UnsupportedOperationException("This method is not implemented for testing"); } @Override - public @NonNull float getFloat(@NonNull String key, @NonNull float defValue) { + public float getFloat(@NonNull String key, float defValue) { throw new UnsupportedOperationException("This method is not implemented for testing"); } @Override - public @NonNull int getInt(@NonNull String key, @NonNull int defValue) { + public int getInt(@NonNull String key, int defValue) { throw new UnsupportedOperationException("This method is not implemented for testing"); } @Override - public @NonNull long getLong(@NonNull String key, @NonNull long defValue) { + public long getLong(@NonNull String key, long defValue) { throw new UnsupportedOperationException("This method is not implemented for testing"); } 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 new file mode 100644 index 000000000000..30dc92970dda --- /dev/null +++ b/packages/shared_preferences/shared_preferences_android/android/src/test/kotlin/io/flutter/plugins/sharedpreferences/SharedPreferencesTest.kt @@ -0,0 +1,174 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.sharedpreferences + +import android.content.Context +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.flutter.embedding.engine.plugins.FlutterPlugin +import io.flutter.plugin.common.BinaryMessenger +import io.mockk.every +import io.mockk.mockk +import org.junit.Assert +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +internal class SharedPreferencesTest { + private val stringKey = "testString" + + private val boolKey = "testBool" + + private val intKey = "testInt" + + private val doubleKey = "testDouble" + + private val listKey = "testList" + + private val testString = "hello world" + + private val testBool = true + + private val testInt = 42L + + private val testDouble = 3.14159 + + private val testList = listOf("foo", "bar") + + private val emptyOptions = SharedPreferencesPigeonOptions() + + private fun pluginSetup(): SharedPreferencesPlugin { + val testContext: Context = ApplicationProvider.getApplicationContext() + + val plugin = SharedPreferencesPlugin() + val binaryMessenger = mockk() + val flutterPluginBinding = mockk() + every { flutterPluginBinding.binaryMessenger } returns binaryMessenger + every { flutterPluginBinding.applicationContext } returns testContext + plugin.onAttachedToEngine(flutterPluginBinding) + return plugin + } + + @Test + fun testSetAndGetBool() { + val plugin = pluginSetup() + plugin.setBool(boolKey, testBool, emptyOptions) + Assert.assertEquals(plugin.getBool(boolKey, emptyOptions), testBool) + } + + @Test + fun testSetAndGetString() { + val plugin = pluginSetup() + plugin.setString(stringKey, testString, emptyOptions) + Assert.assertEquals(plugin.getString(stringKey, emptyOptions), testString) + } + + @Test + fun testSetAndGetInt() { + val plugin = pluginSetup() + plugin.setInt(intKey, testInt, emptyOptions) + Assert.assertEquals(plugin.getInt(intKey, emptyOptions), testInt) + } + + @Test + fun testSetAndGetDouble() { + val plugin = pluginSetup() + plugin.setDouble(doubleKey, testDouble, emptyOptions) + Assert.assertEquals(plugin.getDouble(doubleKey, emptyOptions), testDouble) + } + + @Test + fun testSetAndGetStringList() { + val plugin = pluginSetup() + plugin.setStringList(listKey, testList, emptyOptions) + Assert.assertEquals(plugin.getStringList(listKey, emptyOptions), 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) + 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)) + } + + @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) + + val all = plugin.getAll(null, emptyOptions) + + 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 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) + + plugin.clear(listOf(boolKey, stringKey), emptyOptions) + + 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 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) + + val all = plugin.getAll(listOf(boolKey, stringKey), emptyOptions) + + Assert.assertEquals(all[boolKey], testBool) + Assert.assertEquals(all[stringKey], testString) + Assert.assertNull(all[intKey]) + Assert.assertNull(all[doubleKey]) + Assert.assertNull(all[listKey]) + } +} diff --git a/packages/shared_preferences/shared_preferences_android/example/android/.gitignore b/packages/shared_preferences/shared_preferences_android/example/android/.gitignore index 0a741cb43d66..8e599af9f211 100644 --- a/packages/shared_preferences/shared_preferences_android/example/android/.gitignore +++ b/packages/shared_preferences/shared_preferences_android/example/android/.gitignore @@ -7,5 +7,5 @@ gradle-wrapper.jar GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. -# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +# See https://flutter.dev/to/reference-keystore key.properties 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 237a211a6ccf..b1b30a992781 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 @@ -36,7 +36,7 @@ android { defaultConfig { applicationId "io.flutter.plugins.sharedpreferencesexample" minSdkVersion flutter.minSdkVersion - targetSdkVersion 30 + targetSdkVersion 34 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -57,4 +57,5 @@ flutter { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation "androidx.datastore:datastore-preferences:1.0.0" } diff --git a/packages/shared_preferences/shared_preferences_android/example/android/app/src/androidTest/java/io/flutter/plugins/DartIntegrationTest.java b/packages/shared_preferences/shared_preferences_android/example/android/app/src/androidTest/java/io/flutter/plugins/DartIntegrationTest.java index 21923b546982..6f454ccfb974 100644 --- a/packages/shared_preferences/shared_preferences_android/example/android/app/src/androidTest/java/io/flutter/plugins/DartIntegrationTest.java +++ b/packages/shared_preferences/shared_preferences_android/example/android/app/src/androidTest/java/io/flutter/plugins/DartIntegrationTest.java @@ -14,7 +14,7 @@ * a native java unit test or a java class with a dart integration. * * See: https://github.com/flutter/flutter/blob/master/docs/ecosystem/testing/Plugin-Tests.md#enabling-android-ui-tests - * for more infomation. + * for more information. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) 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 fa56bc45d88c..4288e93f875d 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 @@ -5,6 +5,7 @@ android:icon="@mipmap/ic_launcher"> specialPrefixes = [ // Prefix for lists: 'VGhpcyBpcyB0aGUgcHJlZml4IGZvciBhIGxpc3Qu', - // Prefix for big integers: - 'VGhpcyBpcyB0aGUgcHJlZml4IGZvciBCaWdJbnRlZ2Vy', // Prefix for doubles: 'VGhpcyBpcyB0aGUgcHJlZml4IGZvciBEb3VibGUu', ]; @@ -495,4 +494,209 @@ 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); + }); + + testWidgets('set and get bool', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + await preferences.setBool(boolKey, testBool, emptyOptions); + expect(await preferences.getBool(boolKey, emptyOptions), testBool); + }); + + testWidgets('set and get int', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + await preferences.setInt(intKey, testInt, emptyOptions); + expect(await preferences.getInt(intKey, emptyOptions), testInt); + }); + + testWidgets('set and get double', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + expect(await preferences.getDouble(doubleKey, emptyOptions), testDouble); + }); + + testWidgets('set and get StringList', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + await preferences.setStringList(listKey, testList, emptyOptions); + expect(await preferences.getStringList(listKey, emptyOptions), testList); + }); + + testWidgets('getStringList returns mutable list', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + 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', (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()), + 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); + }); + + 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}), + ), + emptyOptions, + ); + + expect(gotAll.length, 2); + expect(gotAll[stringKey], testString); + expect(gotAll[boolKey], testBool); + }); + + 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()), + 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)); + }); + + 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}), + ), + emptyOptions, + ); + + expect(keys.length, 2); + expect(keys, contains(stringKey)); + expect(keys, contains(boolKey)); + }); + + 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()), + 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); + }); + + 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); + }); + }); } 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 69abfbd506df..5bf8d0609204 100644 --- a/packages/shared_preferences/shared_preferences_android/example/lib/main.dart +++ b/packages/shared_preferences/shared_preferences_android/example/lib/main.dart @@ -5,7 +5,8 @@ // ignore_for_file: public_member_api_docs import 'package:flutter/material.dart'; -import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; +import 'package:shared_preferences_android/shared_preferences_android.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; void main() { runApp(const MyApp()); @@ -31,32 +32,36 @@ class SharedPreferencesDemo extends StatefulWidget { } class SharedPreferencesDemoState extends State { - final SharedPreferencesStorePlatform _prefs = - SharedPreferencesStorePlatform.instance; + final SharedPreferencesAsyncPlatform _prefs = + SharedPreferencesAsyncPlatform.instance!; + final SharedPreferencesAsyncAndroidOptions options = + const SharedPreferencesAsyncAndroidOptions(); + static const String _counterKey = 'counter'; late Future _counter; - // Includes the prefix because this is using the platform interface directly, - // but the prefix (which the native code assumes is present) is added by the - // app-facing package. - static const String _prefKey = 'flutter.counter'; - Future _incrementCounter() async { - final Map values = await _prefs.getAll(); - final int counter = ((values[_prefKey] as int?) ?? 0) + 1; + final int? value = await _prefs.getInt(_counterKey, options); + final int counter = (value ?? 0) + 1; setState(() { - _counter = _prefs.setValue('Int', _prefKey, counter).then((bool success) { + _counter = _prefs.setInt(_counterKey, counter, options).then((_) { return counter; }); }); } + Future _getAndSetCounter() async { + setState(() { + _counter = _prefs.getInt(_counterKey, options).then((int? counter) { + return counter ?? 0; + }); + }); + } + @override void initState() { super.initState(); - _counter = _prefs.getAll().then((Map values) { - return (values[_prefKey] as int?) ?? 0; - }); + _getAndSetCounter(); } @override diff --git a/packages/shared_preferences/shared_preferences_android/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_android/example/pubspec.yaml index 0bdf69086286..5e40089c153a 100644 --- a/packages/shared_preferences/shared_preferences_android/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_android/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the shared_preferences plugin. publish_to: none environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" dependencies: flutter: @@ -16,7 +16,7 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - shared_preferences_platform_interface: ^2.3.0 + shared_preferences_platform_interface: ^2.4.0 dev_dependencies: flutter_test: diff --git a/packages/shared_preferences/shared_preferences_android/lib/shared_preferences_android.dart b/packages/shared_preferences/shared_preferences_android/lib/shared_preferences_android.dart index 352d36484e2d..3a614b8f3776 100644 --- a/packages/shared_preferences/shared_preferences_android/lib/shared_preferences_android.dart +++ b/packages/shared_preferences/shared_preferences_android/lib/shared_preferences_android.dart @@ -2,101 +2,5 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; -import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; -import 'package:shared_preferences_platform_interface/types.dart'; - -import 'src/messages.g.dart'; - -/// The Android implementation of [SharedPreferencesStorePlatform]. -/// -/// This class implements the `package:shared_preferences` functionality for Android. -class SharedPreferencesAndroid extends SharedPreferencesStorePlatform { - /// Creates a new plugin implementation instance. - SharedPreferencesAndroid({ - @visibleForTesting SharedPreferencesApi? api, - }) : _api = api ?? SharedPreferencesApi(); - - final SharedPreferencesApi _api; - - /// Registers this class as the default instance of [SharedPreferencesStorePlatform]. - static void registerWith() { - SharedPreferencesStorePlatform.instance = SharedPreferencesAndroid(); - } - - static const String _defaultPrefix = 'flutter.'; - - @override - Future remove(String key) async { - return _api.remove(key); - } - - @override - Future setValue(String valueType, String key, Object value) async { - switch (valueType) { - case 'String': - return _api.setString(key, value as String); - case 'Bool': - return _api.setBool(key, value as bool); - case 'Int': - return _api.setInt(key, value as int); - case 'Double': - return _api.setDouble(key, value as double); - case 'StringList': - return _api.setStringList(key, value as List); - } - // TODO(tarrinneal): change to ArgumentError across all platforms. - throw PlatformException( - code: 'InvalidOperation', - message: '"$valueType" is not a supported type.'); - } - - @override - Future clear() async { - return clearWithParameters( - ClearParameters( - filter: PreferencesFilter(prefix: _defaultPrefix), - ), - ); - } - - @override - Future clearWithPrefix(String prefix) async { - return clearWithParameters( - ClearParameters(filter: PreferencesFilter(prefix: prefix))); - } - - @override - Future clearWithParameters(ClearParameters parameters) async { - final PreferencesFilter filter = parameters.filter; - return _api.clear( - filter.prefix, - filter.allowList?.toList(), - ); - } - - @override - Future> getAll() async { - return getAllWithParameters( - GetAllParameters( - filter: PreferencesFilter(prefix: _defaultPrefix), - ), - ); - } - - @override - Future> getAllWithPrefix(String prefix) async { - return getAllWithParameters( - GetAllParameters(filter: PreferencesFilter(prefix: prefix))); - } - - @override - Future> getAllWithParameters( - GetAllParameters parameters) async { - final PreferencesFilter filter = parameters.filter; - final Map data = - await _api.getAll(filter.prefix, filter.allowList?.toList()); - return data.cast(); - } -} +export 'src/shared_preferences_android.dart'; +export 'src/shared_preferences_async_android.dart'; diff --git a/packages/shared_preferences/shared_preferences_android/lib/src/messages.g.dart b/packages/shared_preferences/shared_preferences_android/lib/src/messages.g.dart index 1e8430989739..3a0034796d39 100644 --- a/packages/shared_preferences/shared_preferences_android/lib/src/messages.g.dart +++ b/packages/shared_preferences/shared_preferences_android/lib/src/messages.g.dart @@ -1,9 +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 (v9.2.5), do not edit directly. +// Autogenerated from Pigeon (v16.0.4), 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 +// 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 import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; @@ -11,238 +11,263 @@ import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; import 'package:flutter/services.dart'; +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); +} + class SharedPreferencesApi { /// Constructor for [SharedPreferencesApi]. 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. SharedPreferencesApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; + : __pigeon_binaryMessenger = binaryMessenger; + final BinaryMessenger? __pigeon_binaryMessenger; - static const MessageCodec codec = StandardMessageCodec(); + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); /// Removes property from shared preferences data set. - Future remove(String arg_key) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.SharedPreferencesApi.remove', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_key]) as List?; - if (replyList == null) { + Future remove(String key) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesApi.remove'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([key]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else if (replyList[0] == null) { + } else if (__pigeon_replyList[0] == null) { throw PlatformException( code: 'null-error', message: 'Host platform returned null value for non-null return value.', ); } else { - return (replyList[0] as bool?)!; + return (__pigeon_replyList[0] as bool?)!; } } /// Adds property to shared preferences data set of type bool. - Future setBool(String arg_key, bool arg_value) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.SharedPreferencesApi.setBool', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_key, arg_value]) as List?; - if (replyList == null) { + Future setBool(String key, bool value) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesApi.setBool'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([key, value]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else if (replyList[0] == null) { + } else if (__pigeon_replyList[0] == null) { throw PlatformException( code: 'null-error', message: 'Host platform returned null value for non-null return value.', ); } else { - return (replyList[0] as bool?)!; + return (__pigeon_replyList[0] as bool?)!; } } /// Adds property to shared preferences data set of type String. - Future setString(String arg_key, String arg_value) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.SharedPreferencesApi.setString', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_key, arg_value]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future setString(String key, String value) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesApi.setString'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([key, value]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); - } else if (replyList[0] == null) { + } else if (__pigeon_replyList[0] == null) { throw PlatformException( code: 'null-error', message: 'Host platform returned null value for non-null return value.', ); } else { - return (replyList[0] as bool?)!; + return (__pigeon_replyList[0] as bool?)!; } } /// Adds property to shared preferences data set of type int. - Future setInt(String arg_key, int arg_value) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.SharedPreferencesApi.setInt', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_key, arg_value]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future setInt(String key, int value) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesApi.setInt'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([key, value]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); - } else if (replyList[0] == null) { + } else if (__pigeon_replyList[0] == null) { throw PlatformException( code: 'null-error', message: 'Host platform returned null value for non-null return value.', ); } else { - return (replyList[0] as bool?)!; + return (__pigeon_replyList[0] as bool?)!; } } /// Adds property to shared preferences data set of type double. - Future setDouble(String arg_key, double arg_value) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.SharedPreferencesApi.setDouble', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_key, arg_value]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future setDouble(String key, double value) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesApi.setDouble'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([key, value]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); - } else if (replyList[0] == null) { + } else if (__pigeon_replyList[0] == null) { throw PlatformException( code: 'null-error', message: 'Host platform returned null value for non-null return value.', ); } else { - return (replyList[0] as bool?)!; + return (__pigeon_replyList[0] as bool?)!; } } /// Adds property to shared preferences data set of type List. - Future setStringList(String arg_key, List arg_value) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.SharedPreferencesApi.setStringList', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_key, arg_value]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future setStringList(String key, List value) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesApi.setStringList'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([key, value]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); - } else if (replyList[0] == null) { + } else if (__pigeon_replyList[0] == null) { throw PlatformException( code: 'null-error', message: 'Host platform returned null value for non-null return value.', ); } else { - return (replyList[0] as bool?)!; + return (__pigeon_replyList[0] as bool?)!; } } /// Removes all properties from shared preferences data set with matching prefix. - Future clear(String arg_prefix, List? arg_allowList) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.SharedPreferencesApi.clear', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_prefix, arg_allowList]) as List?; - if (replyList == null) { + Future clear(String prefix, List? allowList) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesApi.clear'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([prefix, allowList]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else if (replyList[0] == null) { + } else if (__pigeon_replyList[0] == null) { throw PlatformException( code: 'null-error', message: 'Host platform returned null value for non-null return value.', ); } else { - return (replyList[0] as bool?)!; + return (__pigeon_replyList[0] as bool?)!; } } /// Gets all properties from shared preferences data set with matching prefix. Future> getAll( - String arg_prefix, List? arg_allowList) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.SharedPreferencesApi.getAll', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_prefix, arg_allowList]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + String prefix, List? allowList) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesApi.getAll'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([prefix, allowList]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); - } else if (replyList[0] == null) { + } else if (__pigeon_replyList[0] == null) { throw PlatformException( code: 'null-error', message: 'Host platform returned null value for non-null return value.', ); } else { - return (replyList[0] as Map?)!.cast(); + return (__pigeon_replyList[0] as Map?)! + .cast(); } } } 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 new file mode 100644 index 000000000000..d355cfd916dd --- /dev/null +++ b/packages/shared_preferences/shared_preferences_android/lib/src/messages_async.g.dart @@ -0,0 +1,424 @@ +// 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. +// 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 + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; + +import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/services.dart'; + +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); +} + +class SharedPreferencesPigeonOptions { + SharedPreferencesPigeonOptions({ + this.fileKey, + }); + + String? fileKey; + + Object encode() { + return [ + fileKey, + ]; + } + + static SharedPreferencesPigeonOptions decode(Object result) { + result as List; + return SharedPreferencesPigeonOptions( + fileKey: result[0] as String?, + ); + } +} + +class _SharedPreferencesAsyncApiCodec extends StandardMessageCodec { + const _SharedPreferencesAsyncApiCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is SharedPreferencesPigeonOptions) { + buffer.putUint8(128); + writeValue(buffer, value.encode()); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 128: + return SharedPreferencesPigeonOptions.decode(readValue(buffer)!); + default: + return super.readValueOfType(type, buffer); + } + } +} + +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; + + static const MessageCodec pigeonChannelCodec = + _SharedPreferencesAsyncApiCodec(); + + /// 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 = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([key, value, options]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } + + /// 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 = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([key, value, options]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } + + /// 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 = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([key, value, options]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } + + /// 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 = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([key, value, options]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } + + /// Adds property to shared preferences data set of type List. + 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 = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([key, value, options]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } + + /// 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 = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_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) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_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 = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_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) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_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 = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_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) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_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 = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_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) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as int?); + } + } + + /// Gets individual List value stored with [key], if any. + Future?> getStringList( + String key, SharedPreferencesPigeonOptions options) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getStringList'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_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) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_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 = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([allowList, options]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } + + /// 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 = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([allowList, options]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_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(); + } + } + + /// 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 = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([allowList, options]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_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(); + } + } +} diff --git a/packages/shared_preferences/shared_preferences_android/lib/src/shared_preferences_android.dart b/packages/shared_preferences/shared_preferences_android/lib/src/shared_preferences_android.dart new file mode 100644 index 000000000000..67cc0835635d --- /dev/null +++ b/packages/shared_preferences/shared_preferences_android/lib/src/shared_preferences_android.dart @@ -0,0 +1,105 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; +import 'package:shared_preferences_platform_interface/types.dart'; + +import 'messages.g.dart'; +import 'shared_preferences_async_android.dart'; + +/// The Android implementation of [SharedPreferencesStorePlatform]. +/// +/// This class implements the `package:shared_preferences` functionality for Android. +class SharedPreferencesAndroid extends SharedPreferencesStorePlatform { + /// Creates a new plugin implementation instance. + SharedPreferencesAndroid({ + @visibleForTesting SharedPreferencesApi? api, + }) : _api = api ?? SharedPreferencesApi(); + + final SharedPreferencesApi _api; + + /// Registers this class as the default instance of [SharedPreferencesStorePlatform]. + static void registerWith() { + SharedPreferencesStorePlatform.instance = SharedPreferencesAndroid(); + // A temporary work-around for having two plugins contained in a single package. + SharedPreferencesAsyncAndroid.registerWith(); + } + + static const String _defaultPrefix = 'flutter.'; + + @override + Future remove(String key) async { + return _api.remove(key); + } + + @override + Future setValue(String valueType, String key, Object value) async { + switch (valueType) { + case 'String': + return _api.setString(key, value as String); + case 'Bool': + return _api.setBool(key, value as bool); + case 'Int': + return _api.setInt(key, value as int); + case 'Double': + return _api.setDouble(key, value as double); + case 'StringList': + return _api.setStringList(key, value as List); + } + // TODO(tarrinneal): change to ArgumentError across all platforms. + throw PlatformException( + code: 'InvalidOperation', + message: '"$valueType" is not a supported type.'); + } + + @override + Future clear() async { + return clearWithParameters( + ClearParameters( + filter: PreferencesFilter(prefix: _defaultPrefix), + ), + ); + } + + @override + Future clearWithPrefix(String prefix) async { + return clearWithParameters( + ClearParameters(filter: PreferencesFilter(prefix: prefix))); + } + + @override + Future clearWithParameters(ClearParameters parameters) async { + final PreferencesFilter filter = parameters.filter; + return _api.clear( + filter.prefix, + filter.allowList?.toList(), + ); + } + + @override + Future> getAll() async { + return getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: _defaultPrefix), + ), + ); + } + + @override + Future> getAllWithPrefix(String prefix) async { + return getAllWithParameters( + GetAllParameters(filter: PreferencesFilter(prefix: prefix))); + } + + @override + Future> getAllWithParameters( + GetAllParameters parameters) async { + final PreferencesFilter filter = parameters.filter; + final Map data = + await _api.getAll(filter.prefix, filter.allowList?.toList()); + return data.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 new file mode 100644 index 000000000000..7b3f1cb7b352 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_android/lib/src/shared_preferences_async_android.dart @@ -0,0 +1,196 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; +import 'package:shared_preferences_platform_interface/types.dart'; + +import 'messages_async.g.dart'; + +const String _listPrefix = 'VGhpcyBpcyB0aGUgcHJlZml4IGZvciBhIGxpc3Qu'; + +/// The Android implementation of [SharedPreferencesAsyncPlatform]. +/// +/// This class implements the `package:shared_preferences` functionality for Android. +base class SharedPreferencesAsyncAndroid + extends SharedPreferencesAsyncPlatform { + /// Creates a new plugin implementation instance. + SharedPreferencesAsyncAndroid({ + @visibleForTesting SharedPreferencesAsyncApi? api, + }) : _api = api ?? SharedPreferencesAsyncApi(); + + final SharedPreferencesAsyncApi _api; + + /// Registers this class as the default instance of [SharedPreferencesAsyncPlatform]. + static void registerWith() { + SharedPreferencesAsyncPlatform.instance = SharedPreferencesAsyncAndroid(); + } + + /// Returns a SharedPreferencesPigeonOptions for sending to platform. + SharedPreferencesPigeonOptions _convertOptionsToPigeonOptions( + SharedPreferencesOptions options) { + return SharedPreferencesPigeonOptions(); + } + + @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( + filter.allowList?.toList(), + _convertOptionsToPigeonOptions(options), + )) + .cast() + .toSet(); + } + + @override + Future setString( + String key, + String value, + SharedPreferencesOptions options, + ) async { + if (value.startsWith(_listPrefix)) { + throw ArgumentError( + 'StorageError: This string cannot be stored as it clashes with special identifier prefixes'); + } + + return _api.setString(key, value, _convertOptionsToPigeonOptions(options)); + } + + @override + Future setInt( + String key, + int value, + SharedPreferencesOptions options, + ) async { + return _api.setInt(key, value, _convertOptionsToPigeonOptions(options)); + } + + @override + Future setDouble( + String key, + double value, + SharedPreferencesOptions options, + ) async { + return _api.setDouble(key, value, _convertOptionsToPigeonOptions(options)); + } + + @override + Future setBool( + String key, + bool value, + SharedPreferencesOptions options, + ) async { + return _api.setBool(key, value, _convertOptionsToPigeonOptions(options)); + } + + @override + Future setStringList( + String key, + List value, + SharedPreferencesOptions options, + ) async { + return _api.setStringList( + key, value, _convertOptionsToPigeonOptions(options)); + } + + @override + Future getString( + String key, + SharedPreferencesOptions options, + ) async { + return _convertKnownExceptions(() async => + _api.getString(key, _convertOptionsToPigeonOptions(options))); + } + + @override + Future getBool( + String key, + SharedPreferencesOptions options, + ) async { + return _convertKnownExceptions( + () async => _api.getBool(key, _convertOptionsToPigeonOptions(options))); + } + + @override + Future getDouble( + String key, + SharedPreferencesOptions options, + ) async { + return _convertKnownExceptions(() async => + _api.getDouble(key, _convertOptionsToPigeonOptions(options))); + } + + @override + Future getInt( + String key, + SharedPreferencesOptions options, + ) async { + return _convertKnownExceptions( + () async => _api.getInt(key, _convertOptionsToPigeonOptions(options))); + } + + @override + Future?> getStringList( + String key, + SharedPreferencesOptions options, + ) async { + // 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()); + } + + Future _convertKnownExceptions(Future Function() method) async { + try { + final T? value = await method(); + return value; + } on PlatformException catch (e) { + if (e.code == 'ClassCastException') { + throw TypeError(); + } else { + rethrow; + } + } + } + + @override + Future clear( + ClearPreferencesParameters parameters, + SharedPreferencesOptions options, + ) async { + final PreferencesFilters filter = parameters.filter; + return _api.clear( + filter.allowList?.toList(), + _convertOptionsToPigeonOptions(options), + ); + } + + @override + Future> getPreferences( + GetPreferencesParameters parameters, + SharedPreferencesOptions options, + ) async { + final PreferencesFilters filter = parameters.filter; + final Map data = await _api.getAll( + filter.allowList?.toList(), + _convertOptionsToPigeonOptions(options), + ); + return data.cast(); + } +} + +/// Options for the Android specific SharedPreferences plugin. +class SharedPreferencesAsyncAndroidOptions extends SharedPreferencesOptions { + /// Constructor for SharedPreferencesAsyncAndroidOptions. + const SharedPreferencesAsyncAndroidOptions(); +} diff --git a/packages/shared_preferences/shared_preferences_android/pigeons/messages_async.dart b/packages/shared_preferences/shared_preferences_android/pigeons/messages_async.dart new file mode 100644 index 000000000000..5334cc042f5f --- /dev/null +++ b/packages/shared_preferences/shared_preferences_android/pigeons/messages_async.dart @@ -0,0 +1,118 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:pigeon/pigeon.dart'; + +@ConfigurePigeon(PigeonOptions( + input: 'pigeons/messages_async.dart', + kotlinOut: + 'android/src/main/kotlin/io/flutter/plugins/sharedpreferences/MessagesAsync.g.kt', + kotlinOptions: KotlinOptions( + package: 'io.flutter.plugins.sharedpreferences', + errorClassName: 'SharedPreferencesError', + ), + dartOut: 'lib/src/messages_async.g.dart', + copyrightHeader: 'pigeons/copyright.txt', +)) +class SharedPreferencesPigeonOptions { + SharedPreferencesPigeonOptions({ + this.fileKey, + }); + String? fileKey; +} + +@HostApi(dartHostTestHandler: 'TestSharedPreferencesAsyncApi') +abstract class SharedPreferencesAsyncApi { + /// Adds property to shared preferences data set of type bool. + @TaskQueue(type: TaskQueueType.serialBackgroundThread) + void setBool(String key, bool value, SharedPreferencesPigeonOptions options); + + /// Adds property to shared preferences data set of type String. + @TaskQueue(type: TaskQueueType.serialBackgroundThread) + void setString( + String key, + String value, + SharedPreferencesPigeonOptions options, + ); + + /// Adds property to shared preferences data set of type int. + @TaskQueue(type: TaskQueueType.serialBackgroundThread) + void setInt( + String key, + int value, + SharedPreferencesPigeonOptions options, + ); + + /// Adds property to shared preferences data set of type double. + @TaskQueue(type: TaskQueueType.serialBackgroundThread) + void setDouble( + String key, + double value, + SharedPreferencesPigeonOptions options, + ); + + /// Adds property to shared preferences data set of type List. + @TaskQueue(type: TaskQueueType.serialBackgroundThread) + void setStringList( + String key, + List value, + SharedPreferencesPigeonOptions options, + ); + + /// Gets individual String value stored with [key], if any. + @TaskQueue(type: TaskQueueType.serialBackgroundThread) + String? getString( + String key, + SharedPreferencesPigeonOptions options, + ); + + /// Gets individual void value stored with [key], if any. + @TaskQueue(type: TaskQueueType.serialBackgroundThread) + bool? getBool( + String key, + SharedPreferencesPigeonOptions options, + ); + + /// Gets individual double value stored with [key], if any. + @TaskQueue(type: TaskQueueType.serialBackgroundThread) + double? getDouble( + String key, + SharedPreferencesPigeonOptions options, + ); + + /// Gets individual int value stored with [key], if any. + @TaskQueue(type: TaskQueueType.serialBackgroundThread) + int? getInt( + String key, + SharedPreferencesPigeonOptions options, + ); + + /// Gets individual List value stored with [key], if any. + @TaskQueue(type: TaskQueueType.serialBackgroundThread) + List? getStringList( + String key, + SharedPreferencesPigeonOptions options, + ); + + /// Removes all properties from shared preferences data set with matching prefix. + @TaskQueue(type: TaskQueueType.serialBackgroundThread) + void clear( + List? allowList, + SharedPreferencesPigeonOptions options, + ); + + /// Gets all properties from shared preferences data set with matching prefix. + @TaskQueue(type: TaskQueueType.serialBackgroundThread) + Map getAll( + List? allowList, + SharedPreferencesPigeonOptions options, + ); + + /// Gets all properties from shared preferences data set with matching prefix. + @TaskQueue(type: TaskQueueType.serialBackgroundThread) + List getKeys( + List? allowList, + SharedPreferencesPigeonOptions options, + ); +} diff --git a/packages/shared_preferences/shared_preferences_android/pubspec.yaml b/packages/shared_preferences/shared_preferences_android/pubspec.yaml index 201f30884c9b..d874a9b8b676 100644 --- a/packages/shared_preferences/shared_preferences_android/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_android/pubspec.yaml @@ -2,11 +2,11 @@ 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.2.3 +version: 2.3.3 environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" flutter: plugin: @@ -20,12 +20,12 @@ flutter: dependencies: flutter: sdk: flutter - shared_preferences_platform_interface: ^2.3.0 + shared_preferences_platform_interface: ^2.4.0 dev_dependencies: flutter_test: sdk: flutter - pigeon: ^9.2.3 + pigeon: ^16.0.4 topics: - persistence diff --git a/packages/shared_preferences/shared_preferences_android/test/shared_preferences_android_test.dart b/packages/shared_preferences/shared_preferences_android/test/shared_preferences_android_test.dart index 421ccfe7ea86..c30fa08d18d2 100644 --- a/packages/shared_preferences/shared_preferences_android/test/shared_preferences_android_test.dart +++ b/packages/shared_preferences/shared_preferences_android/test/shared_preferences_android_test.dart @@ -49,7 +49,7 @@ void main() { plugin = SharedPreferencesAndroid(api: api); }); - test('registerWith', () { + test('registerWith', () async { SharedPreferencesAndroid.registerWith(); expect(SharedPreferencesStorePlatform.instance, isA()); @@ -211,7 +211,7 @@ void main() { expect(api.items['flutter.StringList'], ['hi']); }); - test('setValue with unsupported type', () { + test('setValue with unsupported type', () async { expect(() async { await plugin.setValue('Map', 'flutter.key', {}); }, throwsA(isA())); 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 new file mode 100755 index 000000000000..45ee340a7cfe --- /dev/null +++ b/packages/shared_preferences/shared_preferences_android/test/shared_preferences_async_test.dart @@ -0,0 +1,300 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:shared_preferences_android/shared_preferences_android.dart'; +import 'package:shared_preferences_android/src/messages_async.g.dart'; +import 'package:shared_preferences_platform_interface/types.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + 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']; + + const SharedPreferencesAsyncAndroidOptions emptyOptions = + SharedPreferencesAsyncAndroidOptions(); + + SharedPreferencesAsyncAndroid getPreferences() { + final _FakeSharedPreferencesApi api = _FakeSharedPreferencesApi(); + final SharedPreferencesAsyncAndroid preferences = + SharedPreferencesAsyncAndroid(api: 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(); + + 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 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', () 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( + 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, + ); + + 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); + }); +} + +class _FakeSharedPreferencesApi implements SharedPreferencesAsyncApi { + final Map items = {}; + + @override + Future clear( + List? allowList, SharedPreferencesPigeonOptions options) async { + if (allowList != null) { + items.removeWhere((String key, _) => allowList.contains(key)); + } else { + items.clear(); + } + + return true; + } + + @override + Future> getAll( + List? allowList, SharedPreferencesPigeonOptions options) async { + final Map filteredItems = {...items}; + if (allowList != null) { + filteredItems.removeWhere((String key, _) => !allowList.contains(key)); + } + return filteredItems; + } + + @override + Future getBool( + String key, SharedPreferencesPigeonOptions options) async { + return items[key] as bool?; + } + + @override + Future getDouble( + String key, SharedPreferencesPigeonOptions options) async { + return items[key] as double?; + } + + @override + Future getInt( + String key, SharedPreferencesPigeonOptions options) async { + return items[key] as int?; + } + + @override + Future> getKeys( + List? allowList, SharedPreferencesPigeonOptions options) async { + final List filteredItems = items.keys.toList(); + if (allowList != null) { + filteredItems.removeWhere((String key) => !allowList.contains(key)); + } + return filteredItems; + } + + @override + Future getString( + String key, SharedPreferencesPigeonOptions options) async { + return items[key] as String?; + } + + @override + Future?> getStringList( + String key, SharedPreferencesPigeonOptions options) async { + return items[key] as List?; + } + + @override + Future setBool( + String key, bool value, SharedPreferencesPigeonOptions options) async { + items[key] = value; + return true; + } + + @override + Future setDouble( + String key, double value, SharedPreferencesPigeonOptions options) async { + items[key] = value; + return true; + } + + @override + Future setInt( + String key, int value, SharedPreferencesPigeonOptions options) async { + items[key] = value; + return true; + } + + @override + Future setString( + String key, String value, SharedPreferencesPigeonOptions options) async { + items[key] = value; + return true; + } + + @override + Future setStringList(String key, List value, + SharedPreferencesPigeonOptions options) async { + items[key] = value; + return true; + } +} diff --git a/packages/shared_preferences/shared_preferences_foundation/CHANGELOG.md b/packages/shared_preferences/shared_preferences_foundation/CHANGELOG.md index e487278c4986..42722fe4b182 100644 --- a/packages/shared_preferences/shared_preferences_foundation/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_foundation/CHANGELOG.md @@ -1,3 +1,20 @@ +## 2.5.3 + +* Updates Pigeon for non-nullable collection type support. + +## 2.5.2 + +* Fixes getting all preferences when suite name is used. + +## 2.5.1 + +* Fixes `getStringList` returning immutable list. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + +## 2.5.0 + +* Adds new `SharedPreferencesAsyncFoundation` API. + ## 2.4.0 * Adds Swift Package Manager compatibility. diff --git a/packages/shared_preferences/shared_preferences_foundation/README.md b/packages/shared_preferences/shared_preferences_foundation/README.md index 74dbc4ef0c04..c6da193df8fa 100644 --- a/packages/shared_preferences/shared_preferences_foundation/README.md +++ b/packages/shared_preferences/shared_preferences_foundation/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/shared_preferences -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/shared_preferences/shared_preferences_foundation/darwin/Tests/RunnerTests.swift b/packages/shared_preferences/shared_preferences_foundation/darwin/Tests/RunnerTests.swift index 42a1d00d835b..62cfd169b4a4 100644 --- a/packages/shared_preferences/shared_preferences_foundation/darwin/Tests/RunnerTests.swift +++ b/packages/shared_preferences/shared_preferences_foundation/darwin/Tests/RunnerTests.swift @@ -13,11 +13,17 @@ import XCTest #endif class RunnerTests: XCTestCase { + let testKey = "foo" + let testKeyTwo = "baz" + let testValue = "bar" + + // Legacy system tests. + let prefixes: [String] = ["aPrefix", ""] func testSetAndGet() throws { for aPrefix in prefixes { - let plugin = SharedPreferencesPlugin() + let plugin = LegacySharedPreferencesPlugin() plugin.setBool(key: "\(aPrefix)aBool", value: true) plugin.setDouble(key: "\(aPrefix)aDouble", value: 3.14) @@ -36,7 +42,7 @@ class RunnerTests: XCTestCase { func testGetWithAllowList() throws { for aPrefix in prefixes { - let plugin = SharedPreferencesPlugin() + let plugin = LegacySharedPreferencesPlugin() plugin.setBool(key: "\(aPrefix)aBool", value: true) plugin.setDouble(key: "\(aPrefix)aDouble", value: 3.14) @@ -55,8 +61,8 @@ class RunnerTests: XCTestCase { func testRemove() throws { for aPrefix in prefixes { - let plugin = SharedPreferencesPlugin() - let testKey = "\(aPrefix)foo" + let plugin = LegacySharedPreferencesPlugin() + let testKey = "\(aPrefix)\(testKey)" plugin.setValue(key: testKey, value: 42) // Make sure there is something to remove, so the test can't pass due to a set failure. @@ -73,8 +79,8 @@ class RunnerTests: XCTestCase { func testClearWithNoAllowlist() throws { for aPrefix in prefixes { - let plugin = SharedPreferencesPlugin() - let testKey = "\(aPrefix)foo" + let plugin = LegacySharedPreferencesPlugin() + let testKey = "\(aPrefix)\(testKey)" plugin.setValue(key: testKey, value: 42) // Make sure there is something to clear, so the test can't pass due to a set failure. @@ -91,19 +97,143 @@ class RunnerTests: XCTestCase { func testClearWithAllowlist() throws { for aPrefix in prefixes { - let plugin = SharedPreferencesPlugin() - let testKey = "\(aPrefix)foo" + let plugin = LegacySharedPreferencesPlugin() + let testKey = "\(aPrefix)\(testKey)" plugin.setValue(key: testKey, value: 42) // Make sure there is something to clear, so the test can't pass due to a set failure. let preRemovalValues = plugin.getAll(prefix: aPrefix, allowList: nil) XCTAssertEqual(preRemovalValues[testKey] as? Int, 42) - plugin.clear(prefix: aPrefix, allowList: ["\(aPrefix)notfoo"]) + plugin.clear(prefix: aPrefix, allowList: ["\(aPrefix)\(testKeyTwo)"]) let finalValues = plugin.getAll(prefix: aPrefix, allowList: nil) XCTAssertEqual(finalValues[testKey] as? Int, 42) } } + // Async system tests. + + let emptyOptions = SharedPreferencesPigeonOptions() + let optionsWithSuiteName = SharedPreferencesPigeonOptions( + suiteName: "group.example.sharedPreferencesFoundationExample") + + func testAsyncSetAndGet() throws { + let plugin = SharedPreferencesPlugin() + + try plugin.set(key: "aBool", value: true, options: emptyOptions) + try plugin.set(key: "aDouble", value: 3.14, options: emptyOptions) + try plugin.set(key: "anInt", value: 42, options: emptyOptions) + try plugin.set(key: "aString", value: "hello world", options: emptyOptions) + try plugin.set(key: "aStringList", value: ["hello", "world"], options: emptyOptions) + + XCTAssertEqual(((try plugin.getValue(key: "aBool", options: emptyOptions)) != nil), true) + XCTAssertEqual( + try plugin.getValue(key: "aDouble", options: emptyOptions) as! Double, 3.14, accuracy: 0.0001) + XCTAssertEqual(try plugin.getValue(key: "anInt", options: emptyOptions) as! Int, 42) + XCTAssertEqual( + try plugin.getValue(key: "aString", options: emptyOptions) as! String, "hello world") + XCTAssertEqual( + try plugin.getValue(key: "aStringList", options: emptyOptions) as! [String], + ["hello", "world"]) + } + + func testAsyncGetAll() throws { + let plugin = SharedPreferencesPlugin() + + try plugin.set(key: "aBool", value: true, options: emptyOptions) + try plugin.set(key: "aDouble", value: 3.14, options: emptyOptions) + try plugin.set(key: "anInt", value: 42, options: emptyOptions) + try plugin.set(key: "aString", value: "hello world", options: emptyOptions) + try plugin.set(key: "aStringList", value: ["hello", "world"], options: emptyOptions) + + let storedValues = try plugin.getAll(allowList: nil, options: emptyOptions) + XCTAssertEqual(storedValues["aBool"] as? Bool, true) + XCTAssertEqual(storedValues["aDouble"] as! Double, 3.14, accuracy: 0.0001) + XCTAssertEqual(storedValues["anInt"] as? Int, 42) + XCTAssertEqual(storedValues["aString"] as? String, "hello world") + XCTAssertEqual(storedValues["aStringList"] as? [String], ["hello", "world"]) + + } + + func testAsyncGetAllWithAndWithoutSuiteName() throws { + let plugin = SharedPreferencesPlugin() + + try plugin.set(key: "aKey", value: "hello world", options: emptyOptions) + try plugin.set(key: "aKeySuite", value: "hello world with suite", options: optionsWithSuiteName) + + let storedValues = try plugin.getAll(allowList: nil, options: emptyOptions) + XCTAssertEqual(storedValues["aKey"] as? String, "hello world") + + let storedValuesWithGroup = try plugin.getAll(allowList: nil, options: optionsWithSuiteName) + XCTAssertEqual(storedValuesWithGroup["aKeySuite"] as? String, "hello world with suite") + } + + func testAsyncGetAllWithAllowList() throws { + let plugin = SharedPreferencesPlugin() + + try plugin.set(key: "aBool", value: true, options: emptyOptions) + try plugin.set(key: "aDouble", value: 3.14, options: emptyOptions) + try plugin.set(key: "anInt", value: 42, options: emptyOptions) + try plugin.set(key: "aString", value: "hello world", options: emptyOptions) + try plugin.set(key: "aStringList", value: ["hello", "world"], options: emptyOptions) + + let storedValues = try plugin.getAll(allowList: ["aBool"], options: emptyOptions) + XCTAssertEqual(storedValues["aBool"] as? Bool, true) + XCTAssertNil(storedValues["aDouble"] ?? nil) + XCTAssertNil(storedValues["anInt"] ?? nil) + XCTAssertNil(storedValues["aString"] ?? nil) + XCTAssertNil(storedValues["aStringList"] ?? nil) + + } + + func testAsyncRemove() throws { + let plugin = SharedPreferencesPlugin() + try plugin.set(key: testKey, value: testValue, options: emptyOptions) + + // Make sure there is something to remove, so the test can't pass due to a set failure. + let preRemovalValue = try plugin.getValue(key: testKey, options: emptyOptions) as! String + XCTAssertEqual(preRemovalValue, testValue) + + // Then verify that removing it works. + try plugin.remove(key: testKey, options: emptyOptions) + + let finalValue = try plugin.getValue(key: testKey, options: emptyOptions) + XCTAssertNil(finalValue) + + } + + func testAsyncClearWithNoAllowlist() throws { + let plugin = SharedPreferencesPlugin() + try plugin.set(key: testKey, value: testValue, options: emptyOptions) + + // Make sure there is something to remove, so the test can't pass due to a set failure. + let preRemovalValue = try plugin.getValue(key: testKey, options: emptyOptions) as! String + XCTAssertEqual(preRemovalValue, testValue) + + // Then verify that clearing works. + try plugin.clear(allowList: nil, options: emptyOptions) + + let finalValue = try plugin.getValue(key: testKey, options: emptyOptions) + XCTAssertNil(finalValue) + + } + + func testAsyncClearWithAllowlist() throws { + let plugin = SharedPreferencesPlugin() + + try plugin.set(key: testKey, value: testValue, options: emptyOptions) + try plugin.set(key: testKeyTwo, value: testValue, options: emptyOptions) + + // Make sure there is something to clear, so the test can't pass due to a set failure. + let preRemovalValue = try plugin.getValue(key: testKey, options: emptyOptions) as! String + XCTAssertEqual(preRemovalValue, testValue) + + try plugin.clear(allowList: [testKey], options: emptyOptions) + + let finalValueNil = try plugin.getValue(key: testKey, options: emptyOptions) + XCTAssertNil(finalValueNil) + let finalValueNotNil = try plugin.getValue(key: testKeyTwo, options: emptyOptions) as! String + XCTAssertEqual(finalValueNotNil, testValue) + } } diff --git a/packages/shared_preferences/shared_preferences_foundation/darwin/shared_preferences_foundation/Sources/shared_preferences_foundation/SharedPreferencesPlugin.swift b/packages/shared_preferences/shared_preferences_foundation/darwin/shared_preferences_foundation/Sources/shared_preferences_foundation/SharedPreferencesPlugin.swift index b88562e8398d..5fdf2e9960f6 100644 --- a/packages/shared_preferences/shared_preferences_foundation/darwin/shared_preferences_foundation/Sources/shared_preferences_foundation/SharedPreferencesPlugin.swift +++ b/packages/shared_preferences/shared_preferences_foundation/darwin/shared_preferences_foundation/Sources/shared_preferences_foundation/SharedPreferencesPlugin.swift @@ -10,19 +10,22 @@ import Foundation import FlutterMacOS #endif -public class SharedPreferencesPlugin: NSObject, FlutterPlugin, UserDefaultsApi { +let argumentError: String = "Argument Error" + +public class LegacySharedPreferencesPlugin: NSObject, FlutterPlugin, LegacyUserDefaultsApi { + public static func register(with registrar: FlutterPluginRegistrar) { - let instance = SharedPreferencesPlugin() + let instance = LegacySharedPreferencesPlugin() // Workaround for https://github.com/flutter/flutter/issues/118103. #if os(iOS) let messenger = registrar.messenger() #else let messenger = registrar.messenger #endif - UserDefaultsApiSetup.setUp(binaryMessenger: messenger, api: instance) + LegacyUserDefaultsApiSetup.setUp(binaryMessenger: messenger, api: instance) } - func getAll(prefix: String, allowList: [String]?) -> [String?: Any?] { + func getAll(prefix: String, allowList: [String]?) -> [String: Any] { return getAllPrefs(prefix: prefix, allowList: allowList) } @@ -54,18 +57,138 @@ public class SharedPreferencesPlugin: NSObject, FlutterPlugin, UserDefaultsApi { /// If [allowList] is included, only items included will be returned. func getAllPrefs(prefix: String, allowList: [String]?) -> [String: Any] { var filteredPrefs: [String: Any] = [:] - var allowSet: Set? + + let prefs = try! SharedPreferencesPlugin.getAllPrefs( + allowList: allowList, options: SharedPreferencesPigeonOptions()) + + for (key, value) in prefs where (key.hasPrefix(prefix)) { + filteredPrefs[key] = value + } + + return filteredPrefs + } + +} + +public class SharedPreferencesPlugin: NSObject, FlutterPlugin, UserDefaultsApi { + + public static func register(with registrar: FlutterPluginRegistrar) { + let instance = SharedPreferencesPlugin() + // Workaround for https://github.com/flutter/flutter/issues/118103. + #if os(iOS) + let messenger = registrar.messenger() + #else + let messenger = registrar.messenger + #endif + UserDefaultsApiSetup.setUp(binaryMessenger: messenger, api: instance) + LegacySharedPreferencesPlugin.register(with: registrar) + } + + static private func getUserDefaults(options: SharedPreferencesPigeonOptions) throws + -> UserDefaults + { + #if os(iOS) + if !(options.suiteName?.starts(with: "group.") ?? true) { + throw FlutterError( + code: argumentError, + message: + "The provided Suite Name '\(options.suiteName!)' does not follow the predefined requirements", + details: "") as! Error + } + #endif + let prefs = UserDefaults(suiteName: options.suiteName) + + if prefs == nil { + throw FlutterError( + code: argumentError, + message: "The provided Suite Name '\(options.suiteName!)' does not exist", + details: "") as! Error + } + return prefs! + } + + func getKeys(allowList: [String]?, options: SharedPreferencesPigeonOptions) throws -> [String] { + return Array(try getAll(allowList: allowList, options: options).keys) + } + + func getAll(allowList: [String]?, options: SharedPreferencesPigeonOptions) throws -> [String: Any] + { + return try SharedPreferencesPlugin.getAllPrefs(allowList: allowList, options: options) + } + + func set(key: String, value: Any, options: SharedPreferencesPigeonOptions) throws { + try SharedPreferencesPlugin.getUserDefaults(options: options).set(value, forKey: key) + } + + func getValue(key: String, options: SharedPreferencesPigeonOptions) throws -> Any? { + let preference = try SharedPreferencesPlugin.getUserDefaults(options: options).object( + forKey: key) + return SharedPreferencesPlugin.isTypeCompatible(value: preference as Any) ? preference : nil + } + + func remove(key: String, options: SharedPreferencesPigeonOptions) throws { + try SharedPreferencesPlugin.getUserDefaults(options: options).removeObject(forKey: key) + } + + func clear(allowList: [String]?, options: SharedPreferencesPigeonOptions) throws { + let defaults = try SharedPreferencesPlugin.getUserDefaults(options: options) if let allowList = allowList { - allowSet = Set(allowList) + for (key) in allowList { + defaults.removeObject(forKey: key) + } + } else { + for key in defaults.dictionaryRepresentation().keys { + defaults.removeObject(forKey: key) + } } - if let appDomain = Bundle.main.bundleIdentifier, - let prefs = UserDefaults.standard.persistentDomain(forName: appDomain) + } + + /// Returns all preferences stored with specified prefix. + /// If [allowList] is included, only items included will be returned. + /// If no [allowList], returns supported types only. + static func getAllPrefs(allowList: [String]?, options: SharedPreferencesPigeonOptions) throws + -> [String: Any] + { + var filteredPrefs: [String: Any] = [:] + var compatiblePrefs: [String: Any] = [:] + let allowSet = allowList.map { Set($0) } + + // Since `getUserDefaults` is initialized with the suite name, it seems redundant to call + // `persistentDomain` with the suite name again. However, it is necessary because + // `dictionaryRepresentation` returns keys from the global domain. + // Also, Apple's docs on `persistentDomain` are incorrect, + // see: https://github.com/feedback-assistant/reports/issues/165 + if let appDomain = options.suiteName ?? Bundle.main.bundleIdentifier, + let prefs = try getUserDefaults(options: options).persistentDomain(forName: appDomain) { - for (key, value) in prefs - where (key.hasPrefix(prefix) && (allowSet == nil || allowSet!.contains(key))) { - filteredPrefs[key] = value + if let allowSet = allowSet { + filteredPrefs = prefs.filter { allowSet.contains($0.key) } + } else { + filteredPrefs = prefs } + compatiblePrefs = filteredPrefs.filter { isTypeCompatible(value: $0.value) } } - return filteredPrefs + return compatiblePrefs } + + static func isTypeCompatible(value: Any) -> Bool { + switch value { + case is Bool: + return true + case is Double: + return true + case is String: + return true + case is Int: + return true + case is [Any]: + if let value = value as? [Any] { + return value.allSatisfy(isTypeCompatible) + } + default: + return false + } + return false + } + } 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 cb247f9c8cba..275de0921d50 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 @@ -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 (v10.1.6), do not edit directly. +// Autogenerated from Pigeon (v22.4.1), do not edit directly. // See also: https://pub.dev/packages/pigeon import Foundation @@ -14,11 +14,36 @@ import Foundation #error("Unsupported platform.") #endif +/// Error class for passing custom error details to Dart side. +final class PigeonError: Error { + let code: String + let message: String? + let details: Any? + + init(code: String, message: String?, details: Any?) { + self.code = code + self.message = message + self.details = details + } + + var localizedDescription: String { + return + "PigeonError(code: \(code), message: \(message ?? ""), details: \(details ?? "")" + } +} + private func wrapResult(_ result: Any?) -> [Any?] { return [result] } private func wrapError(_ error: Any) -> [Any?] { + if let pigeonError = error as? PigeonError { + return [ + pigeonError.code, + pigeonError.message, + pigeonError.details, + ] + } if let flutterError = error as? FlutterError { return [ flutterError.code, @@ -33,28 +58,93 @@ private func wrapError(_ error: Any) -> [Any?] { ] } +private func isNullish(_ value: Any?) -> Bool { + return value is NSNull || value == nil +} + private func nilOrValue(_ value: Any?) -> T? { if value is NSNull { return nil } return value as! T? } + +/// Generated class from Pigeon that represents data sent in messages. +struct SharedPreferencesPigeonOptions { + var suiteName: String? = nil + + // swift-format-ignore: AlwaysUseLowerCamelCase + static func fromList(_ pigeonVar_list: [Any?]) -> SharedPreferencesPigeonOptions? { + let suiteName: String? = nilOrValue(pigeonVar_list[0]) + + return SharedPreferencesPigeonOptions( + suiteName: suiteName + ) + } + func toList() -> [Any?] { + return [ + suiteName + ] + } +} + +private class messagesPigeonCodecReader: FlutterStandardReader { + override func readValue(ofType type: UInt8) -> Any? { + switch type { + case 129: + return SharedPreferencesPigeonOptions.fromList(self.readValue() as! [Any?]) + default: + return super.readValue(ofType: type) + } + } +} + +private class messagesPigeonCodecWriter: FlutterStandardWriter { + override func writeValue(_ value: Any) { + if let value = value as? SharedPreferencesPigeonOptions { + super.writeByte(129) + super.writeValue(value.toList()) + } else { + super.writeValue(value) + } + } +} + +private class messagesPigeonCodecReaderWriter: FlutterStandardReaderWriter { + override func reader(with data: Data) -> FlutterStandardReader { + return messagesPigeonCodecReader(data: data) + } + + override func writer(with data: NSMutableData) -> FlutterStandardWriter { + return messagesPigeonCodecWriter(data: data) + } +} + +class messagesPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable { + static let shared = messagesPigeonCodec(readerWriter: messagesPigeonCodecReaderWriter()) +} + /// Generated protocol from Pigeon that represents a handler of messages from Flutter. -protocol UserDefaultsApi { +protocol LegacyUserDefaultsApi { func remove(key: String) throws func setBool(key: String, value: Bool) throws func setDouble(key: String, value: Double) throws func setValue(key: String, value: Any) throws - func getAll(prefix: String, allowList: [String]?) throws -> [String?: Any?] + func getAll(prefix: String, allowList: [String]?) throws -> [String: Any] func clear(prefix: String, allowList: [String]?) throws -> Bool } /// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. -class UserDefaultsApiSetup { - /// The codec used by UserDefaultsApi. - /// Sets up an instance of `UserDefaultsApi` to handle messages through the `binaryMessenger`. - static func setUp(binaryMessenger: FlutterBinaryMessenger, api: UserDefaultsApi?) { +class LegacyUserDefaultsApiSetup { + 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?, + messageChannelSuffix: String = "" + ) { + let channelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : "" let removeChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.remove", - binaryMessenger: binaryMessenger) + name: + "dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.remove\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) if let api = api { removeChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -70,8 +160,9 @@ class UserDefaultsApiSetup { removeChannel.setMessageHandler(nil) } let setBoolChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.setBool", - binaryMessenger: binaryMessenger) + name: + "dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.setBool\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) if let api = api { setBoolChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -88,8 +179,9 @@ class UserDefaultsApiSetup { setBoolChannel.setMessageHandler(nil) } let setDoubleChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.setDouble", - binaryMessenger: binaryMessenger) + name: + "dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.setDouble\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) if let api = api { setDoubleChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -106,8 +198,9 @@ class UserDefaultsApiSetup { setDoubleChannel.setMessageHandler(nil) } let setValueChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.setValue", - binaryMessenger: binaryMessenger) + name: + "dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.setValue\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) if let api = api { setValueChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -124,8 +217,9 @@ class UserDefaultsApiSetup { setValueChannel.setMessageHandler(nil) } let getAllChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.getAll", - binaryMessenger: binaryMessenger) + name: + "dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.getAll\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) if let api = api { getAllChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -142,8 +236,9 @@ class UserDefaultsApiSetup { getAllChannel.setMessageHandler(nil) } let clearChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.clear", - binaryMessenger: binaryMessenger) + name: + "dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.clear\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) if let api = api { clearChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -161,3 +256,128 @@ class UserDefaultsApiSetup { } } } +/// Generated protocol from Pigeon that represents a handler of messages from Flutter. +protocol UserDefaultsApi { + /// Adds property to shared preferences data set of type String. + func set(key: String, value: Any, options: SharedPreferencesPigeonOptions) throws + /// Removes all properties from shared preferences data set with matching prefix. + func clear(allowList: [String]?, options: SharedPreferencesPigeonOptions) throws + /// Gets all properties from shared preferences data set with matching prefix. + func getAll(allowList: [String]?, options: SharedPreferencesPigeonOptions) throws -> [String: Any] + /// Gets individual value stored with [key], if any. + func getValue(key: String, options: SharedPreferencesPigeonOptions) throws -> Any? + /// Gets all properties from shared preferences data set with matching prefix. + func getKeys(allowList: [String]?, options: SharedPreferencesPigeonOptions) throws -> [String] +} + +/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. +class UserDefaultsApiSetup { + 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?, + messageChannelSuffix: String = "" + ) { + let channelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : "" + /// Adds property to shared preferences data set of type String. + let setChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.set\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + setChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let keyArg = args[0] as! String + let valueArg = args[1]! + let optionsArg = args[2] as! SharedPreferencesPigeonOptions + do { + try api.set(key: keyArg, value: valueArg, options: optionsArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + setChannel.setMessageHandler(nil) + } + /// Removes all properties from shared preferences data set with matching prefix. + let clearChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.clear\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + clearChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let allowListArg: [String]? = nilOrValue(args[0]) + let optionsArg = args[1] as! SharedPreferencesPigeonOptions + do { + try api.clear(allowList: allowListArg, options: optionsArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + clearChannel.setMessageHandler(nil) + } + /// Gets all properties from shared preferences data set with matching prefix. + let getAllChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.getAll\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + getAllChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let allowListArg: [String]? = nilOrValue(args[0]) + let optionsArg = args[1] as! SharedPreferencesPigeonOptions + do { + let result = try api.getAll(allowList: allowListArg, options: optionsArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + getAllChannel.setMessageHandler(nil) + } + /// Gets individual value stored with [key], if any. + let getValueChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.getValue\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + getValueChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let keyArg = args[0] as! String + let optionsArg = args[1] as! SharedPreferencesPigeonOptions + do { + let result = try api.getValue(key: keyArg, options: optionsArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + getValueChannel.setMessageHandler(nil) + } + /// Gets all properties from shared preferences data set with matching prefix. + let getKeysChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.getKeys\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + getKeysChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let allowListArg: [String]? = nilOrValue(args[0]) + let optionsArg = args[1] as! SharedPreferencesPigeonOptions + do { + let result = try api.getKeys(allowList: allowListArg, options: optionsArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + getKeysChannel.setMessageHandler(nil) + } + } +} diff --git a/packages/shared_preferences/shared_preferences_foundation/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_foundation/example/integration_test/shared_preferences_test.dart index 49892ec18aaa..e40423d4da56 100644 --- a/packages/shared_preferences/shared_preferences_foundation/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences_foundation/example/integration_test/shared_preferences_test.dart @@ -4,13 +4,15 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; +import 'package:shared_preferences_foundation/shared_preferences_foundation.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; import 'package:shared_preferences_platform_interface/types.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - group('SharedPreferencesFoundation', () { + group('SharedPreferencesAsyncFoundation', () { const Map flutterTestValues = { 'flutter.String': 'hello world', 'flutter.Bool': true, @@ -481,4 +483,279 @@ void main() { expect(values['Int'], writeCount); }); }); + + group('shared_preferences_async', () { + final SharedPreferencesAsyncFoundationOptions emptyOptions = + SharedPreferencesAsyncFoundationOptions(); + final SharedPreferencesAsyncFoundationOptions optionsWithSuiteName = + SharedPreferencesAsyncFoundationOptions( + suiteName: 'group.example.sharedPreferencesFoundation'); + + 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); + await preferences.clear( + const ClearPreferencesParameters(filter: PreferencesFilters()), + optionsWithSuiteName); + 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); + }); + + testWidgets('set and get bool', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + await preferences.setBool(boolKey, testBool, emptyOptions); + expect(await preferences.getBool(boolKey, emptyOptions), testBool); + }); + + testWidgets('set and get int', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + await preferences.setInt(intKey, testInt, emptyOptions); + expect(await preferences.getInt(intKey, emptyOptions), testInt); + }); + + testWidgets('set and get double', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + expect(await preferences.getDouble(doubleKey, emptyOptions), testDouble); + }); + + testWidgets('set and get StringList', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + await preferences.setStringList(listKey, testList, emptyOptions); + expect(await preferences.getStringList(listKey, emptyOptions), testList); + }); + + testWidgets('getStringList returns mutable list', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + 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', (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()), + 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); + }); + + testWidgets('getPreferences with options', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + await Future.wait(>[ + preferences.setString(stringKey, testString, optionsWithSuiteName), + preferences.setBool(boolKey, testBool, emptyOptions), + preferences.setInt(intKey, testInt, optionsWithSuiteName), + preferences.setDouble(doubleKey, testDouble, emptyOptions), + preferences.setStringList(listKey, testList, optionsWithSuiteName) + ]); + + final Map preferencesWithEmptyOptions = + await preferences.getPreferences( + const GetPreferencesParameters(filter: PreferencesFilters()), + emptyOptions, + ); + + final Map preferencesWithSuiteName = + await preferences.getPreferences( + const GetPreferencesParameters(filter: PreferencesFilters()), + optionsWithSuiteName, + ); + + expect(preferencesWithEmptyOptions.length, 2); + expect(preferencesWithSuiteName.length, 3); + + expect(preferencesWithEmptyOptions[boolKey], testBool); + expect(preferencesWithEmptyOptions[doubleKey], testDouble); + + expect(preferencesWithSuiteName[stringKey], testString); + expect(preferencesWithSuiteName[intKey], testInt); + expect(preferencesWithSuiteName[listKey], testList); + }); + + 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}), + ), + emptyOptions, + ); + + expect(gotAll.length, 2); + expect(gotAll[stringKey], testString); + expect(gotAll[boolKey], testBool); + }); + + 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()), + 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)); + }); + + testWidgets('getKeys with options', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + await Future.wait(>[ + preferences.setString(stringKey, testString, optionsWithSuiteName), + preferences.setBool(boolKey, testBool, emptyOptions), + preferences.setInt(intKey, testInt, optionsWithSuiteName), + preferences.setDouble(doubleKey, testDouble, emptyOptions), + preferences.setStringList(listKey, testList, optionsWithSuiteName) + ]); + + final Set keysWithEmptyOptions = await preferences.getKeys( + const GetPreferencesParameters(filter: PreferencesFilters()), + emptyOptions, + ); + + final Set keysWithSuiteName = await preferences.getKeys( + const GetPreferencesParameters(filter: PreferencesFilters()), + optionsWithSuiteName, + ); + + expect(keysWithEmptyOptions.length, 2); + expect(keysWithSuiteName.length, 3); + + expect(keysWithEmptyOptions, contains(boolKey)); + expect(keysWithEmptyOptions, contains(doubleKey)); + + expect(keysWithSuiteName, contains(stringKey)); + expect(keysWithSuiteName, contains(intKey)); + expect(keysWithSuiteName, contains(listKey)); + }); + + 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}), + ), + emptyOptions, + ); + + expect(keys.length, 2); + expect(keys, contains(stringKey)); + expect(keys, contains(boolKey)); + }); + + 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()), + 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); + }); + + 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); + }); + }); } diff --git a/packages/shared_preferences/shared_preferences_foundation/example/ios/Podfile b/packages/shared_preferences/shared_preferences_foundation/example/ios/Podfile index d97f17e223fb..e549ee22f3b0 100644 --- a/packages/shared_preferences/shared_preferences_foundation/example/ios/Podfile +++ b/packages/shared_preferences/shared_preferences_foundation/example/ios/Podfile @@ -29,7 +29,6 @@ flutter_ios_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) target 'RunnerTests' do diff --git a/packages/shared_preferences/shared_preferences_foundation/example/lib/main.dart b/packages/shared_preferences/shared_preferences_foundation/example/lib/main.dart index e7cb57b7eb60..6623eb653f10 100644 --- a/packages/shared_preferences/shared_preferences_foundation/example/lib/main.dart +++ b/packages/shared_preferences/shared_preferences_foundation/example/lib/main.dart @@ -4,10 +4,9 @@ // ignore_for_file: public_member_api_docs -import 'dart:async'; - import 'package:flutter/material.dart'; -import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; +import 'package:shared_preferences_foundation/shared_preferences_foundation.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; void main() { runApp(const MyApp()); @@ -33,32 +32,36 @@ class SharedPreferencesDemo extends StatefulWidget { } class SharedPreferencesDemoState extends State { - final SharedPreferencesStorePlatform _prefs = - SharedPreferencesStorePlatform.instance; + final SharedPreferencesAsyncPlatform? _prefs = + SharedPreferencesAsyncPlatform.instance; + SharedPreferencesAsyncFoundationOptions options = + SharedPreferencesAsyncFoundationOptions(); + static const String _counterKey = 'counter'; late Future _counter; - // Includes the prefix because this is using the platform interface directly, - // but the prefix (which the native code assumes is present) is added by the - // app-facing package. - static const String _prefKey = 'flutter.counter'; - Future _incrementCounter() async { - final Map values = await _prefs.getAll(); - final int counter = ((values[_prefKey] as int?) ?? 0) + 1; + final int? value = await _prefs!.getInt(_counterKey, options); + final int counter = (value ?? 0) + 1; setState(() { - _counter = _prefs.setValue('Int', _prefKey, counter).then((bool success) { + _counter = _prefs.setInt(_counterKey, counter, options).then((_) { return counter; }); }); } + Future _getAndSetCounter() async { + setState(() { + _counter = _prefs!.getInt(_counterKey, options).then((int? counter) { + return counter ?? 0; + }); + }); + } + @override void initState() { super.initState(); - _counter = _prefs.getAll().then((Map values) { - return (values[_prefKey] as int?) ?? 0; - }); + _getAndSetCounter(); } @override diff --git a/packages/shared_preferences/shared_preferences_foundation/example/macos/Podfile b/packages/shared_preferences/shared_preferences_foundation/example/macos/Podfile index 47c1b18fedae..dd603efb9895 100644 --- a/packages/shared_preferences/shared_preferences_foundation/example/macos/Podfile +++ b/packages/shared_preferences/shared_preferences_foundation/example/macos/Podfile @@ -28,7 +28,6 @@ flutter_macos_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) diff --git a/packages/shared_preferences/shared_preferences_foundation/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_foundation/example/pubspec.yaml index 39df1eb0f461..ac1ef988c6d8 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.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: @@ -16,7 +16,7 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - shared_preferences_platform_interface: ^2.3.0 + shared_preferences_platform_interface: ^2.4.0 dev_dependencies: flutter_test: diff --git a/packages/shared_preferences/shared_preferences_foundation/lib/messages.g.dart b/packages/shared_preferences/shared_preferences_foundation/lib/messages.g.dart deleted file mode 100644 index 132d92ac2243..000000000000 --- a/packages/shared_preferences/shared_preferences_foundation/lib/messages.g.dart +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// Autogenerated from Pigeon (v10.1.6), 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 - -import 'dart:async'; -import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; - -import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; -import 'package:flutter/services.dart'; - -class UserDefaultsApi { - /// Constructor for [UserDefaultsApi]. 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. - UserDefaultsApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; - - static const MessageCodec codec = StandardMessageCodec(); - - Future remove(String arg_key) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.remove', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_key]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else { - return; - } - } - - Future setBool(String arg_key, bool arg_value) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.setBool', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_key, arg_value]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else { - return; - } - } - - Future setDouble(String arg_key, double arg_value) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.setDouble', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_key, arg_value]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else { - return; - } - } - - Future setValue(String arg_key, Object arg_value) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.setValue', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_key, arg_value]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else { - return; - } - } - - Future> getAll( - String arg_prefix, List? arg_allowList) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.getAll', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_prefix, arg_allowList]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else if (replyList[0] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (replyList[0] as Map?)!.cast(); - } - } - - Future clear(String arg_prefix, List? arg_allowList) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.clear', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_prefix, arg_allowList]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else if (replyList[0] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (replyList[0] as bool?)!; - } - } -} diff --git a/packages/shared_preferences/shared_preferences_foundation/lib/shared_preferences_foundation.dart b/packages/shared_preferences/shared_preferences_foundation/lib/shared_preferences_foundation.dart index 92699b7fbfa2..43234666b9ce 100644 --- a/packages/shared_preferences/shared_preferences_foundation/lib/shared_preferences_foundation.dart +++ b/packages/shared_preferences/shared_preferences_foundation/lib/shared_preferences_foundation.dart @@ -2,106 +2,5 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:flutter/services.dart'; -import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; -import 'package:shared_preferences_platform_interface/types.dart'; -import 'messages.g.dart'; - -typedef _Setter = Future Function(String key, Object value); - -/// iOS and macOS implementation of shared_preferences. -class SharedPreferencesFoundation extends SharedPreferencesStorePlatform { - final UserDefaultsApi _api = UserDefaultsApi(); - - static const String _defaultPrefix = 'flutter.'; - - late final Map _setters = { - 'Bool': (String key, Object value) { - return _api.setBool(key, value as bool); - }, - 'Double': (String key, Object value) { - return _api.setDouble(key, value as double); - }, - 'Int': (String key, Object value) { - return _api.setValue(key, value as int); - }, - 'String': (String key, Object value) { - return _api.setValue(key, value as String); - }, - 'StringList': (String key, Object value) { - return _api.setValue(key, value as List); - }, - }; - - /// Registers this class as the default instance of - /// [SharedPreferencesStorePlatform]. - static void registerWith() { - SharedPreferencesStorePlatform.instance = SharedPreferencesFoundation(); - } - - @override - Future clear() async { - return clearWithParameters( - ClearParameters( - filter: PreferencesFilter(prefix: _defaultPrefix), - ), - ); - } - - @override - Future clearWithPrefix(String prefix) async { - return clearWithParameters( - ClearParameters(filter: PreferencesFilter(prefix: prefix))); - } - - @override - Future clearWithParameters(ClearParameters parameters) async { - final PreferencesFilter filter = parameters.filter; - return _api.clear( - filter.prefix, - filter.allowList?.toList(), - ); - } - - @override - Future> getAll() async { - return getAllWithParameters( - GetAllParameters( - filter: PreferencesFilter(prefix: _defaultPrefix), - ), - ); - } - - @override - Future> getAllWithPrefix(String prefix) async { - return getAllWithParameters( - GetAllParameters(filter: PreferencesFilter(prefix: prefix))); - } - - @override - Future> getAllWithParameters( - GetAllParameters parameters) async { - final PreferencesFilter filter = parameters.filter; - final Map data = - await _api.getAll(filter.prefix, filter.allowList?.toList()); - return data.cast(); - } - - @override - Future remove(String key) async { - await _api.remove(key); - return true; - } - - @override - Future setValue(String valueType, String key, Object value) async { - final _Setter? setter = _setters[valueType]; - if (setter == null) { - throw PlatformException( - code: 'InvalidOperation', - message: '"$valueType" is not a supported type.'); - } - await setter(key, value); - return true; - } -} +export 'src/shared_preferences_async_foundation.dart'; +export 'src/shared_preferences_foundation.dart'; diff --git a/packages/shared_preferences/shared_preferences_foundation/lib/src/messages.g.dart b/packages/shared_preferences/shared_preferences_foundation/lib/src/messages.g.dart new file mode 100644 index 000000000000..50d77fcdc77a --- /dev/null +++ b/packages/shared_preferences/shared_preferences_foundation/lib/src/messages.g.dart @@ -0,0 +1,406 @@ +// 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 (v22.4.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 + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; + +import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/services.dart'; + +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); +} + +List wrapResponse( + {Object? result, PlatformException? error, bool empty = false}) { + if (empty) { + return []; + } + if (error == null) { + return [result]; + } + return [error.code, error.message, error.details]; +} + +class SharedPreferencesPigeonOptions { + SharedPreferencesPigeonOptions({ + this.suiteName, + }); + + String? suiteName; + + Object encode() { + return [ + suiteName, + ]; + } + + static SharedPreferencesPigeonOptions decode(Object result) { + result as List; + return SharedPreferencesPigeonOptions( + suiteName: result[0] as String?, + ); + } +} + +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + 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); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 129: + return SharedPreferencesPigeonOptions.decode(readValue(buffer)!); + default: + return super.readValueOfType(type, buffer); + } + } +} + +class LegacyUserDefaultsApi { + /// Constructor for [LegacyUserDefaultsApi]. 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. + LegacyUserDefaultsApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String pigeonVar_messageChannelSuffix; + + Future remove(String key) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.remove$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([key]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + Future setBool(String key, bool value) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.setBool$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([key, value]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + Future setDouble(String key, double value) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.setDouble$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([key, value]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + Future setValue(String key, Object value) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.setValue$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([key, value]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + Future> getAll( + String prefix, List? allowList) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.getAll$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([prefix, allowList]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as Map?)! + .cast(); + } + } + + Future clear(String prefix, List? allowList) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.clear$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([prefix, allowList]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as bool?)!; + } + } +} + +class UserDefaultsApi { + /// Constructor for [UserDefaultsApi]. 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. + UserDefaultsApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String pigeonVar_messageChannelSuffix; + + /// Adds property to shared preferences data set of type String. + Future set( + String key, Object value, SharedPreferencesPigeonOptions options) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.set$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([key, value, options]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Removes all properties from shared preferences data set with matching prefix. + Future clear( + List? allowList, SharedPreferencesPigeonOptions options) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.clear$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([allowList, options]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Gets all properties from shared preferences data set with matching prefix. + Future> getAll( + List? allowList, SharedPreferencesPigeonOptions options) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.getAll$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([allowList, options]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as Map?)! + .cast(); + } + } + + /// Gets individual value stored with [key], if any. + Future getValue( + String key, SharedPreferencesPigeonOptions options) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.getValue$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + 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: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return pigeonVar_replyList[0]; + } + } + + /// Gets all properties from shared preferences data set with matching prefix. + Future> getKeys( + List? allowList, SharedPreferencesPigeonOptions options) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.getKeys$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([allowList, options]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as List?)!.cast(); + } + } +} diff --git a/packages/shared_preferences/shared_preferences_foundation/lib/src/shared_preferences_async_foundation.dart b/packages/shared_preferences/shared_preferences_foundation/lib/src/shared_preferences_async_foundation.dart new file mode 100644 index 000000000000..d821f1cb378c --- /dev/null +++ b/packages/shared_preferences/shared_preferences_foundation/lib/src/shared_preferences_async_foundation.dart @@ -0,0 +1,233 @@ +// 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:io'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; +import 'package:shared_preferences_platform_interface/types.dart'; + +import './messages.g.dart'; + +const String _argumentErrorCode = 'Argument Error'; + +/// iOS and macOS implementation of shared_preferences. +base class SharedPreferencesAsyncFoundation + extends SharedPreferencesAsyncPlatform { + /// Creates a new plugin implementation instance. + SharedPreferencesAsyncFoundation({ + @visibleForTesting UserDefaultsApi? api, + }) : _api = api ?? UserDefaultsApi(); + + final UserDefaultsApi _api; + + /// Registers this class as the default instance of [SharedPreferencesAsyncPlatform]. + static void registerWith() { + SharedPreferencesAsyncPlatform.instance = + SharedPreferencesAsyncFoundation(); + } + + /// Returns a SharedPreferencesPigeonOptions for sending to platform. + SharedPreferencesPigeonOptions _convertOptionsToPigeonOptions( + SharedPreferencesOptions options) { + if (options is SharedPreferencesAsyncFoundationOptions) { + final String? suiteName = options.suiteName; + return SharedPreferencesPigeonOptions( + suiteName: suiteName, + ); + } + return SharedPreferencesPigeonOptions(); + } + + @override + Future> getKeys( + GetPreferencesParameters parameters, + SharedPreferencesOptions options, + ) async { + final PreferencesFilters filter = parameters.filter; + return (await _convertKnownExceptions>( + () async => _api.getKeys( + filter.allowList?.toList(), + _convertOptionsToPigeonOptions(options), + )))! + .toSet(); + } + + Future _setValue( + String key, + Object value, + SharedPreferencesOptions options, + ) async { + return _convertKnownExceptions(() async => + _api.set(key, value, _convertOptionsToPigeonOptions(options))); + } + + @override + Future setString( + String key, + String value, + SharedPreferencesOptions options, + ) async { + await _setValue(key, value, options); + } + + @override + Future setInt( + String key, + int value, + SharedPreferencesOptions options, + ) async { + await _setValue(key, value, options); + } + + @override + Future setStringList( + String key, + List value, + SharedPreferencesOptions options, + ) async { + await _setValue(key, value, options); + } + + @override + Future setBool( + String key, + bool value, + SharedPreferencesOptions options, + ) async { + await _api.set(key, value, _convertOptionsToPigeonOptions(options)); + } + + @override + Future setDouble( + String key, + double value, + SharedPreferencesOptions options, + ) async { + await _api.set(key, value, _convertOptionsToPigeonOptions(options)); + } + + @override + Future getString( + String key, + SharedPreferencesOptions options, + ) async { + return _convertKnownExceptions(() async => (await _api.getValue( + key, _convertOptionsToPigeonOptions(options))) as String?); + } + + @override + Future getBool( + String key, + SharedPreferencesOptions options, + ) async { + return _convertKnownExceptions(() async => await _api.getValue( + key, _convertOptionsToPigeonOptions(options)) as bool?); + } + + @override + Future getDouble( + String key, + SharedPreferencesOptions options, + ) async { + return _convertKnownExceptions(() async => await _api.getValue( + key, _convertOptionsToPigeonOptions(options)) as double?); + } + + @override + Future getInt( + String key, + SharedPreferencesOptions options, + ) async { + return _convertKnownExceptions(() async => await _api.getValue( + key, _convertOptionsToPigeonOptions(options)) as int?); + } + + @override + Future?> getStringList( + String key, + SharedPreferencesOptions options, + ) async { + // Since `getValue` is not strongly typed, the array type won't be set + // during deserialization, and needs to be manually cast. + return _convertKnownExceptions>(() async => + ((await _api.getValue(key, _convertOptionsToPigeonOptions(options))) + as List?) + ?.cast() + .toList()); + } + + @override + Future clear( + ClearPreferencesParameters parameters, + SharedPreferencesOptions options, + ) async { + final PreferencesFilters filter = parameters.filter; + return _convertKnownExceptions(() async => _api.clear( + filter.allowList?.toList(), + _convertOptionsToPigeonOptions(options), + )); + } + + @override + Future> getPreferences( + GetPreferencesParameters parameters, + SharedPreferencesOptions options, + ) async { + final PreferencesFilters filter = parameters.filter; + return (await _convertKnownExceptions>( + () async => _api.getAll( + filter.allowList?.toList(), + _convertOptionsToPigeonOptions(options), + )))!; + } + + Future _convertKnownExceptions(Future Function() method) async { + try { + final T? value = await method(); + return value; + } on PlatformException catch (e) { + if (e.code == _argumentErrorCode) { + throw ArgumentError( + 'shared_preferences_foundation argument error ${e.message ?? ''}'); + } else { + rethrow; + } + } + } +} + +/// Options for the Foundation specific SharedPreferences plugin. +@immutable +class SharedPreferencesAsyncFoundationOptions extends SharedPreferencesOptions { + /// Creates a new instance with the given options. + SharedPreferencesAsyncFoundationOptions({ + this.suiteName, + }) { + // Ensure that use of suite is compliant with required reason API category 1C8F.1; see + // https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api + if (Platform.isIOS && !(suiteName?.startsWith('group.') ?? true)) { + throw ArgumentError('iOS suite name must begin with "group."'); + } + } + + /// Name of Foundation suite to get/set to. + /// + /// On iOS this represents a container ID which must begin with `group.` + /// followed by a custom string in reverse DNS notation. + /// + /// If this option is not set, the default NSUserDefaults will be used. + final String? suiteName; + + /// Returns a new instance of [SharedPreferencesAsyncFoundationOptions] from an existing + /// [SharedPreferencesOptions]. + static SharedPreferencesAsyncFoundationOptions fromSharedPreferencesOptions( + SharedPreferencesOptions options) { + if (options is SharedPreferencesAsyncFoundationOptions) { + return options; + } + return SharedPreferencesAsyncFoundationOptions(); + } +} diff --git a/packages/shared_preferences/shared_preferences_foundation/lib/src/shared_preferences_foundation.dart b/packages/shared_preferences/shared_preferences_foundation/lib/src/shared_preferences_foundation.dart new file mode 100644 index 000000000000..3fccb90e73c6 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_foundation/lib/src/shared_preferences_foundation.dart @@ -0,0 +1,108 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/services.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; +import 'package:shared_preferences_platform_interface/types.dart'; +import './messages.g.dart'; +import 'shared_preferences_async_foundation.dart'; + +typedef _Setter = Future Function(String key, Object value); + +/// iOS and macOS implementation of shared_preferences. +class SharedPreferencesFoundation extends SharedPreferencesStorePlatform { + final LegacyUserDefaultsApi _api = LegacyUserDefaultsApi(); + + static const String _defaultPrefix = 'flutter.'; + + late final Map _setters = { + 'Bool': (String key, Object value) { + return _api.setBool(key, value as bool); + }, + 'Double': (String key, Object value) { + return _api.setDouble(key, value as double); + }, + 'Int': (String key, Object value) { + return _api.setValue(key, value as int); + }, + 'String': (String key, Object value) { + return _api.setValue(key, value as String); + }, + 'StringList': (String key, Object value) { + return _api.setValue(key, value as List); + }, + }; + + /// Registers this class as the default instance of + /// [SharedPreferencesStorePlatform]. + static void registerWith() { + SharedPreferencesStorePlatform.instance = SharedPreferencesFoundation(); + // A temporary work-around for having two plugins contained in a single package. + SharedPreferencesAsyncFoundation.registerWith(); + } + + @override + Future clear() async { + return clearWithParameters( + ClearParameters( + filter: PreferencesFilter(prefix: _defaultPrefix), + ), + ); + } + + @override + Future clearWithPrefix(String prefix) async { + return clearWithParameters( + ClearParameters(filter: PreferencesFilter(prefix: prefix))); + } + + @override + Future clearWithParameters(ClearParameters parameters) async { + final PreferencesFilter filter = parameters.filter; + return _api.clear( + filter.prefix, + filter.allowList?.toList(), + ); + } + + @override + Future> getAll() async { + return getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: _defaultPrefix), + ), + ); + } + + @override + Future> getAllWithPrefix(String prefix) async { + return getAllWithParameters( + GetAllParameters(filter: PreferencesFilter(prefix: prefix))); + } + + @override + Future> getAllWithParameters( + GetAllParameters parameters) async { + final PreferencesFilter filter = parameters.filter; + return _api.getAll(filter.prefix, filter.allowList?.toList()); + } + + @override + Future remove(String key) async { + await _api.remove(key); + return true; + } + + @override + Future setValue(String valueType, String key, Object value) async { + final _Setter? setter = _setters[valueType]; + if (setter == null) { + throw PlatformException( + code: 'InvalidOperation', + message: '"$valueType" is not a supported type.'); + } + await setter(key, value); + return true; + } +} diff --git a/packages/shared_preferences/shared_preferences_foundation/pigeons/messages.dart b/packages/shared_preferences/shared_preferences_foundation/pigeons/messages.dart index ad8060e34741..d740b1ebd0a2 100644 --- a/packages/shared_preferences/shared_preferences_foundation/pigeons/messages.dart +++ b/packages/shared_preferences/shared_preferences_foundation/pigeons/messages.dart @@ -5,22 +5,60 @@ import 'package:pigeon/pigeon.dart'; @ConfigurePigeon(PigeonOptions( - dartOut: 'lib/messages.g.dart', + dartOut: 'lib/src/messages.g.dart', dartTestOut: 'test/test_api.g.dart', swiftOut: 'darwin/shared_preferences_foundation/Sources/shared_preferences_foundation/messages.g.swift', copyrightHeader: 'pigeons/copyright_header.txt', )) @HostApi(dartHostTestHandler: 'TestUserDefaultsApi') -abstract class UserDefaultsApi { +abstract class LegacyUserDefaultsApi { void remove(String key); - // TODO(stuartmorgan): Give these setters better Swift signatures (_,forKey:) - // once https://github.com/flutter/flutter/issues/105932 is fixed. void setBool(String key, bool value); void setDouble(String key, double value); void setValue(String key, Object value); - // TODO(stuartmorgan): Make these non-nullable once - // https://github.com/flutter/flutter/issues/97848 is fixed. - Map getAll(String prefix, List? allowList); + Map getAll(String prefix, List? allowList); bool clear(String prefix, List? allowList); } + +class SharedPreferencesPigeonOptions { + SharedPreferencesPigeonOptions({ + this.suiteName, + }); + String? suiteName; +} + +@HostApi(dartHostTestHandler: 'TestSharedPreferencesAsyncApi') +abstract class UserDefaultsApi { + /// Adds property to shared preferences data set of type String. + @SwiftFunction('set(key:value:options:)') + void set( + String key, + Object value, + SharedPreferencesPigeonOptions options, + ); + + /// Removes all properties from shared preferences data set with matching prefix. + void clear( + List? allowList, + SharedPreferencesPigeonOptions options, + ); + + /// Gets all properties from shared preferences data set with matching prefix. + Map getAll( + List? allowList, + SharedPreferencesPigeonOptions options, + ); + + /// Gets individual value stored with [key], if any. + Object? getValue( + String key, + SharedPreferencesPigeonOptions options, + ); + + /// Gets all properties from shared preferences data set with matching prefix. + List getKeys( + List? allowList, + SharedPreferencesPigeonOptions options, + ); +} diff --git a/packages/shared_preferences/shared_preferences_foundation/pubspec.yaml b/packages/shared_preferences/shared_preferences_foundation/pubspec.yaml index 2e5d728e1422..50b73b1264bb 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.4.0 +version: 2.5.3 environment: - sdk: ^3.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -24,12 +24,12 @@ flutter: dependencies: flutter: sdk: flutter - shared_preferences_platform_interface: ^2.3.0 + shared_preferences_platform_interface: ^2.4.0 dev_dependencies: flutter_test: sdk: flutter - pigeon: ^10.1.6 + pigeon: ^22.4.1 topics: - persistence diff --git a/packages/shared_preferences/shared_preferences_foundation/test/shared_preferences_async_foundation_test.dart b/packages/shared_preferences/shared_preferences_foundation/test/shared_preferences_async_foundation_test.dart new file mode 100644 index 000000000000..584e35100c8b --- /dev/null +++ b/packages/shared_preferences/shared_preferences_foundation/test/shared_preferences_async_foundation_test.dart @@ -0,0 +1,256 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/src/services/binary_messenger.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:shared_preferences_foundation/shared_preferences_foundation.dart'; +import 'package:shared_preferences_foundation/src/messages.g.dart'; +import 'package:shared_preferences_platform_interface/types.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + 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']; + + final SharedPreferencesAsyncFoundationOptions emptyOptions = + SharedPreferencesAsyncFoundationOptions(); + + SharedPreferencesAsyncFoundation getPreferences() { + final _FakeSharedPreferencesApi api = _FakeSharedPreferencesApi(); + final SharedPreferencesAsyncFoundation preferences = + SharedPreferencesAsyncFoundation(api: api); + + return preferences; + } + + test('set and get String', () async { + final SharedPreferencesAsyncFoundation preferences = getPreferences(); + + await preferences.setString(stringKey, testString, emptyOptions); + expect(await preferences.getString(stringKey, emptyOptions), testString); + }); + + test('set and get bool', () async { + final SharedPreferencesAsyncFoundation preferences = getPreferences(); + + await preferences.setBool(boolKey, testBool, emptyOptions); + expect(await preferences.getBool(boolKey, emptyOptions), testBool); + }); + + test('set and get int', () async { + final SharedPreferencesAsyncFoundation preferences = getPreferences(); + + await preferences.setInt(intKey, testInt, emptyOptions); + expect(await preferences.getInt(intKey, emptyOptions), testInt); + }); + + test('set and get double', () async { + final SharedPreferencesAsyncFoundation preferences = getPreferences(); + + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + expect(await preferences.getDouble(doubleKey, emptyOptions), testDouble); + }); + + test('set and get StringList', () async { + final SharedPreferencesAsyncFoundation preferences = getPreferences(); + + await preferences.setStringList(listKey, testList, emptyOptions); + expect(await preferences.getStringList(listKey, emptyOptions), testList); + }); + + test('getPreferences', () async { + final SharedPreferencesAsyncFoundation 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( + 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 SharedPreferencesAsyncFoundation 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( + const GetPreferencesParameters( + filter: + PreferencesFilters(allowList: {stringKey, boolKey})), + emptyOptions); + + expect(gotAll.length, 2); + expect(gotAll[stringKey], testString); + expect(gotAll[boolKey], testBool); + }); + + test('getKeys', () async { + final SharedPreferencesAsyncFoundation 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 SharedPreferencesAsyncFoundation 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, + ); + + expect(keys.length, 2); + expect(keys, contains(stringKey)); + expect(keys, contains(boolKey)); + }); + + test('clear', () async { + final SharedPreferencesAsyncFoundation 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 SharedPreferencesAsyncFoundation 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); + }); +} + +class _FakeSharedPreferencesApi implements UserDefaultsApi { + final Map items = {}; + + @override + Future clear( + List? allowList, SharedPreferencesPigeonOptions options) async { + if (allowList != null) { + items.removeWhere((String key, _) => allowList.contains(key)); + } else { + items.clear(); + } + + return true; + } + + @override + Future> getAll( + List? allowList, SharedPreferencesPigeonOptions options) async { + final Map filteredItems = {...items}; + if (allowList != null) { + filteredItems.removeWhere((String key, _) => !allowList.contains(key)); + } + return filteredItems; + } + + @override + Future> getKeys( + List? allowList, SharedPreferencesPigeonOptions options) async { + final List filteredItems = items.keys.toList(); + if (allowList != null) { + filteredItems.removeWhere((String key) => !allowList.contains(key)); + } + return filteredItems; + } + + @override + Future set( + String key, Object value, SharedPreferencesPigeonOptions options) async { + items[key] = value; + } + + @override + Future getValue( + String key, SharedPreferencesPigeonOptions options) async { + return items[key]; + } + + @override + // ignore: non_constant_identifier_names + BinaryMessenger? get pigeonVar_binaryMessenger => null; + + @override + // ignore: non_constant_identifier_names + String get pigeonVar_messageChannelSuffix => ''; +} diff --git a/packages/shared_preferences/shared_preferences_foundation/test/shared_preferences_foundation_test.dart b/packages/shared_preferences/shared_preferences_foundation/test/shared_preferences_foundation_test.dart index 496cdd9b0f7a..3543e69b9bc5 100644 --- a/packages/shared_preferences/shared_preferences_foundation/test/shared_preferences_foundation_test.dart +++ b/packages/shared_preferences/shared_preferences_foundation/test/shared_preferences_foundation_test.dart @@ -4,7 +4,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:shared_preferences_foundation/shared_preferences_foundation.dart'; +import 'package:shared_preferences_foundation/src/shared_preferences_foundation.dart'; import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; import 'package:shared_preferences_platform_interface/types.dart'; @@ -14,7 +14,7 @@ class _MockSharedPreferencesApi implements TestUserDefaultsApi { final Map items = {}; @override - Map getAll( + Map getAll( String prefix, List? allowList, ) { @@ -22,11 +22,11 @@ class _MockSharedPreferencesApi implements TestUserDefaultsApi { if (allowList != null) { allowSet = Set.from(allowList); } - return { - for (final String key in items.keys) - if (key.startsWith(prefix) && - (allowSet == null || allowSet.contains(key))) - key: items[key] + return { + for (final MapEntry entry in items.entries) + if (entry.key.startsWith(prefix) && + (allowSet == null || allowSet.contains(entry.key))) + entry.key: entry.value }; } @@ -98,10 +98,10 @@ void main() { setUp(() { api = _MockSharedPreferencesApi(); - TestUserDefaultsApi.setup(api); + TestUserDefaultsApi.setUp(api); }); - test('registerWith', () { + test('registerWith', () async { SharedPreferencesFoundation.registerWith(); expect(SharedPreferencesStorePlatform.instance, isA()); @@ -261,7 +261,7 @@ void main() { expect(api.items['flutter.StringList'], ['hi']); }); - test('setValue with unsupported type', () { + test('setValue with unsupported type', () async { final SharedPreferencesFoundation plugin = SharedPreferencesFoundation(); expect(() async { await plugin.setValue('Map', 'flutter.key', {}); diff --git a/packages/shared_preferences/shared_preferences_foundation/test/test_api.g.dart b/packages/shared_preferences/shared_preferences_foundation/test/test_api.g.dart index 39f8b4fede5c..ebeabbc6d16f 100644 --- a/packages/shared_preferences/shared_preferences_foundation/test/test_api.g.dart +++ b/packages/shared_preferences/shared_preferences_foundation/test/test_api.g.dart @@ -1,9 +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 (v10.1.6), do not edit directly. +// Autogenerated from Pigeon (v22.4.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, unnecessary_import +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import, no_leading_underscores_for_local_identifiers // ignore_for_file: avoid_relative_lib_imports import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; @@ -11,12 +11,38 @@ import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:shared_preferences_foundation/messages.g.dart'; +import 'package:shared_preferences_foundation/src/messages.g.dart'; + +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + 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); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 129: + return SharedPreferencesPigeonOptions.decode(readValue(buffer)!); + default: + return super.readValueOfType(type, buffer); + } + } +} abstract class TestUserDefaultsApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec codec = StandardMessageCodec(); + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); void remove(String key); @@ -26,161 +52,434 @@ abstract class TestUserDefaultsApi { void setValue(String key, Object value); - Map getAll(String prefix, List? allowList); + Map getAll(String prefix, List? allowList); - bool clear(String prefix, List? allowList); + bool clear(String prefix, List? allowList); - static void setup(TestUserDefaultsApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + TestUserDefaultsApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.remove', - codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.remove$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.remove was null.'); + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.remove was null.'); final List args = (message as List?)!; final String? arg_key = (args[0] as String?); assert(arg_key != null, - 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.remove was null, expected non-null String.'); - api.remove(arg_key!); - return []; + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.remove was null, expected non-null String.'); + try { + api.remove(arg_key!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.setBool', - codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.setBool$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.setBool was null.'); + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.setBool was null.'); final List args = (message as List?)!; final String? arg_key = (args[0] as String?); assert(arg_key != null, - 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.setBool was null, expected non-null String.'); + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.setBool was null, expected non-null String.'); final bool? arg_value = (args[1] as bool?); assert(arg_value != null, - 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.setBool was null, expected non-null bool.'); - api.setBool(arg_key!, arg_value!); - return []; + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.setBool was null, expected non-null bool.'); + try { + api.setBool(arg_key!, arg_value!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.setDouble', - codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.setDouble$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.setDouble was null.'); + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.setDouble was null.'); final List args = (message as List?)!; final String? arg_key = (args[0] as String?); assert(arg_key != null, - 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.setDouble was null, expected non-null String.'); + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.setDouble was null, expected non-null String.'); final double? arg_value = (args[1] as double?); assert(arg_value != null, - 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.setDouble was null, expected non-null double.'); - api.setDouble(arg_key!, arg_value!); - return []; + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.setDouble was null, expected non-null double.'); + try { + api.setDouble(arg_key!, arg_value!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.setValue', - codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.setValue$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.setValue was null.'); + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.setValue was null.'); final List args = (message as List?)!; final String? arg_key = (args[0] as String?); assert(arg_key != null, - 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.setValue was null, expected non-null String.'); + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.setValue was null, expected non-null String.'); final Object? arg_value = (args[1] as Object?); assert(arg_value != null, - 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.setValue was null, expected non-null Object.'); - api.setValue(arg_key!, arg_value!); - return []; + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.setValue was null, expected non-null Object.'); + try { + api.setValue(arg_key!, arg_value!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.getAll', - codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.getAll$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.getAll was null.'); + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.getAll was null.'); final List args = (message as List?)!; final String? arg_prefix = (args[0] as String?); assert(arg_prefix != null, - 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.getAll was null, expected non-null String.'); - final List? arg_allowList = - (args[1] as List?)?.cast(); - final Map output = - api.getAll(arg_prefix!, arg_allowList); - return [output]; + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.getAll was null, expected non-null String.'); + final List? arg_allowList = + (args[1] as List?)?.cast(); + try { + final Map output = + api.getAll(arg_prefix!, arg_allowList); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.clear', - codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.clear$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.clear was null.'); + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.clear was null.'); final List args = (message as List?)!; final String? arg_prefix = (args[0] as String?); assert(arg_prefix != null, - 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.clear was null, expected non-null String.'); - final List? arg_allowList = - (args[1] as List?)?.cast(); - final bool output = api.clear(arg_prefix!, arg_allowList); - return [output]; + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.LegacyUserDefaultsApi.clear was null, expected non-null String.'); + final List? arg_allowList = + (args[1] as List?)?.cast(); + try { + final bool output = api.clear(arg_prefix!, arg_allowList); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } +} + +abstract class TestSharedPreferencesAsyncApi { + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + /// Adds property to shared preferences data set of type String. + void set(String key, Object value, SharedPreferencesPigeonOptions options); + + /// Removes all properties from shared preferences data set with matching prefix. + void clear(List? allowList, SharedPreferencesPigeonOptions options); + + /// Gets all properties from shared preferences data set with matching prefix. + Map getAll( + List? allowList, SharedPreferencesPigeonOptions options); + + /// Gets individual value stored with [key], if any. + Object? getValue(String key, SharedPreferencesPigeonOptions options); + + /// Gets all properties from shared preferences data set with matching prefix. + List getKeys( + List? allowList, SharedPreferencesPigeonOptions options); + + static void setUp( + TestSharedPreferencesAsyncApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.set$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.set was null.'); + final List args = (message as List?)!; + final String? arg_key = (args[0] as String?); + assert(arg_key != null, + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.set was null, expected non-null String.'); + final Object? arg_value = (args[1] as Object?); + assert(arg_value != null, + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.set was null, expected non-null Object.'); + final SharedPreferencesPigeonOptions? arg_options = + (args[2] as SharedPreferencesPigeonOptions?); + assert(arg_options != null, + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.set was null, expected non-null SharedPreferencesPigeonOptions.'); + try { + api.set(arg_key!, arg_value!, arg_options!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.clear$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.clear was null.'); + final List args = (message as List?)!; + final List? arg_allowList = + (args[0] as List?)?.cast(); + final SharedPreferencesPigeonOptions? arg_options = + (args[1] as SharedPreferencesPigeonOptions?); + assert(arg_options != null, + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.clear was null, expected non-null SharedPreferencesPigeonOptions.'); + try { + api.clear(arg_allowList, arg_options!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.getAll$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.getAll was null.'); + final List args = (message as List?)!; + final List? arg_allowList = + (args[0] as List?)?.cast(); + final SharedPreferencesPigeonOptions? arg_options = + (args[1] as SharedPreferencesPigeonOptions?); + assert(arg_options != null, + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.getAll was null, expected non-null SharedPreferencesPigeonOptions.'); + try { + final Map output = + api.getAll(arg_allowList, arg_options!); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.getValue$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.getValue was null.'); + final List args = (message as List?)!; + final String? arg_key = (args[0] as String?); + assert(arg_key != null, + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.getValue was null, expected non-null String.'); + final SharedPreferencesPigeonOptions? arg_options = + (args[1] as SharedPreferencesPigeonOptions?); + assert(arg_options != null, + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.getValue was null, expected non-null SharedPreferencesPigeonOptions.'); + try { + final Object? output = api.getValue(arg_key!, arg_options!); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.getKeys$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.getKeys was null.'); + final List args = (message as List?)!; + final List? arg_allowList = + (args[0] as List?)?.cast(); + final SharedPreferencesPigeonOptions? arg_options = + (args[1] as SharedPreferencesPigeonOptions?); + assert(arg_options != null, + 'Argument for dev.flutter.pigeon.shared_preferences_foundation.UserDefaultsApi.getKeys was null, expected non-null SharedPreferencesPigeonOptions.'); + try { + final List output = + api.getKeys(arg_allowList, arg_options!); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } diff --git a/packages/shared_preferences/shared_preferences_linux/CHANGELOG.md b/packages/shared_preferences/shared_preferences_linux/CHANGELOG.md index cabbb80908ee..43c46f51a84f 100644 --- a/packages/shared_preferences/shared_preferences_linux/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_linux/CHANGELOG.md @@ -1,5 +1,12 @@ -## NEXT +## 2.4.1 +* Fixes `getStringList` returning immutable list. +* Fixes `getStringList` cast error. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + +## 2.4.0 + +* Adds `SharedPreferencesAsyncLinux` API. * Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. ## 2.3.2 diff --git a/packages/shared_preferences/shared_preferences_linux/README.md b/packages/shared_preferences/shared_preferences_linux/README.md index a1bbd9d7ef52..0fe95555e308 100644 --- a/packages/shared_preferences/shared_preferences_linux/README.md +++ b/packages/shared_preferences/shared_preferences_linux/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/shared_preferences -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_test.dart index 5f06c87c3177..fdabea41342e 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_test.dart @@ -5,6 +5,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:shared_preferences_linux/shared_preferences_linux.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; import 'package:shared_preferences_platform_interface/types.dart'; void main() { @@ -336,4 +337,220 @@ void main() { }); }); }); + + group('shared_preferences_async', () { + const SharedPreferencesLinuxOptions emptyOptions = + SharedPreferencesLinuxOptions(); + + 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( + {bool clear = true}) async { + final SharedPreferencesAsyncPlatform preferences = + SharedPreferencesAsyncPlatform.instance!; + if (clear) { + 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); + }); + + testWidgets('set and get bool', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + await preferences.setBool(boolKey, testBool, emptyOptions); + expect(await preferences.getBool(boolKey, emptyOptions), testBool); + }); + + testWidgets('set and get int', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + await preferences.setInt(intKey, testInt, emptyOptions); + expect(await preferences.getInt(intKey, emptyOptions), testInt); + }); + + testWidgets('set and get double', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + expect(await preferences.getDouble(doubleKey, emptyOptions), testDouble); + }); + + testWidgets('set and get StringList', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + await preferences.setStringList(listKey, testList, emptyOptions); + expect(await preferences.getStringList(listKey, emptyOptions), testList); + }); + testWidgets('getStringList does not throw cast error', + (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + await preferences.setStringList(listKey, testList, emptyOptions); + await (preferences as SharedPreferencesAsyncLinux).reload(emptyOptions); + expect(await preferences.getStringList(listKey, emptyOptions), testList); + }); + + testWidgets('getStringList returns mutable list', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + 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', (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()), + 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); + }); + + 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}), + ), + emptyOptions, + ); + + expect(gotAll.length, 2); + expect(gotAll[stringKey], testString); + expect(gotAll[boolKey], testBool); + }); + + 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()), + 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)); + }); + + 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}), + ), + emptyOptions, + ); + + expect(keys.length, 2); + expect(keys, contains(stringKey)); + expect(keys, contains(boolKey)); + }); + + 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()), + 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); + }); + + 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); + }); + }); } diff --git a/packages/shared_preferences/shared_preferences_linux/example/lib/main.dart b/packages/shared_preferences/shared_preferences_linux/example/lib/main.dart index 050d2e50f640..b333716cb155 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/lib/main.dart +++ b/packages/shared_preferences/shared_preferences_linux/example/lib/main.dart @@ -4,10 +4,9 @@ // ignore_for_file: public_member_api_docs -import 'dart:async'; - import 'package:flutter/material.dart'; import 'package:shared_preferences_linux/shared_preferences_linux.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; void main() { runApp(const MyApp()); @@ -33,26 +32,36 @@ class SharedPreferencesDemo extends StatefulWidget { } class SharedPreferencesDemoState extends State { - final SharedPreferencesLinux prefs = SharedPreferencesLinux(); + final SharedPreferencesAsyncPlatform? _prefs = + SharedPreferencesAsyncPlatform.instance; + final SharedPreferencesLinuxOptions options = + const SharedPreferencesLinuxOptions(); + static const String _counterKey = 'counter'; late Future _counter; Future _incrementCounter() async { - final Map values = await prefs.getAll(); - final int counter = (values['counter'] as int? ?? 0) + 1; + final int? value = await _prefs!.getInt(_counterKey, options); + final int counter = (value ?? 0) + 1; setState(() { - _counter = prefs.setValue('Int', 'counter', counter).then((bool success) { + _counter = _prefs.setInt(_counterKey, counter, options).then((_) { return counter; }); }); } + Future _getAndSetCounter() async { + setState(() { + _counter = _prefs!.getInt(_counterKey, options).then((int? counter) { + return counter ?? 0; + }); + }); + } + @override void initState() { super.initState(); - _counter = prefs.getAll().then((Map values) { - return values['counter'] as int? ?? 0; - }); + _getAndSetCounter(); } @override diff --git a/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml index 060ea7da5f4a..35da7cfab3c9 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: @@ -16,7 +16,7 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - shared_preferences_platform_interface: ^2.3.0 + shared_preferences_platform_interface: ^2.4.0 dev_dependencies: flutter_test: diff --git a/packages/shared_preferences/shared_preferences_linux/lib/shared_preferences_linux.dart b/packages/shared_preferences/shared_preferences_linux/lib/shared_preferences_linux.dart index e9f93489b6ca..d4ede84ec2b9 100644 --- a/packages/shared_preferences/shared_preferences_linux/lib/shared_preferences_linux.dart +++ b/packages/shared_preferences/shared_preferences_linux/lib/shared_preferences_linux.dart @@ -10,9 +10,14 @@ import 'package:file/local.dart'; import 'package:flutter/foundation.dart' show debugPrint, visibleForTesting; import 'package:path/path.dart' as path; import 'package:path_provider_linux/path_provider_linux.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; import 'package:shared_preferences_platform_interface/types.dart'; +const String _defaultFileName = 'shared_preferences'; + +const String _defaultPrefix = 'flutter.'; + /// The Linux implementation of [SharedPreferencesStorePlatform]. /// /// This class implements the `package:shared_preferences` functionality for Linux. @@ -22,11 +27,11 @@ class SharedPreferencesLinux extends SharedPreferencesStorePlatform { @Deprecated('Use `SharedPreferencesStorePlatform.instance` instead.') static SharedPreferencesLinux instance = SharedPreferencesLinux(); - static const String _defaultPrefix = 'flutter.'; - /// Registers the Linux implementation. static void registerWith() { SharedPreferencesStorePlatform.instance = SharedPreferencesLinux(); + // A temporary work-around for having two plugins contained in a single package. + SharedPreferencesAsyncLinux.registerWith(); } /// Local copy of preferences @@ -40,57 +45,15 @@ class SharedPreferencesLinux extends SharedPreferencesStorePlatform { @visibleForTesting PathProviderLinux pathProvider = PathProviderLinux(); - /// Gets the file where the preferences are stored. - Future _getLocalDataFile() async { - final String? directory = await pathProvider.getApplicationSupportPath(); - if (directory == null) { - return null; - } - return fs.file(path.join(directory, 'shared_preferences.json')); - } - - /// Gets the preferences from the stored file and saves them in cache. - Future> _reload() async { - Map preferences = {}; - final File? localDataFile = await _getLocalDataFile(); - if (localDataFile != null && localDataFile.existsSync()) { - final String stringMap = localDataFile.readAsStringSync(); - if (stringMap.isNotEmpty) { - final Object? data = json.decode(stringMap); - if (data is Map) { - preferences = data.cast(); - } - } - } - _cachedPreferences = preferences; - return preferences; - } - /// Checks for cached preferences and returns them or loads preferences from /// file and returns and caches them. Future> _readPreferences() async { - return _cachedPreferences ?? await _reload(); - } - - /// Writes the cached preferences to disk. Returns [true] if the operation - /// succeeded. - Future _writePreferences(Map preferences) async { - try { - final File? localDataFile = await _getLocalDataFile(); - if (localDataFile == null) { - debugPrint('Unable to determine where to write preferences.'); - return false; - } - if (!localDataFile.existsSync()) { - localDataFile.createSync(recursive: true); - } - final String stringMap = json.encode(preferences); - localDataFile.writeAsStringSync(stringMap); - } catch (e) { - debugPrint('Error saving preferences to disk: $e'); - return false; - } - return true; + _cachedPreferences ??= await _reload( + _defaultFileName, + fs: fs, + pathProvider: pathProvider, + ); + return _cachedPreferences!; } @override @@ -111,11 +74,17 @@ class SharedPreferencesLinux extends SharedPreferencesStorePlatform { @override Future clearWithParameters(ClearParameters parameters) async { final PreferencesFilter filter = parameters.filter; + final Map preferences = await _readPreferences(); preferences.removeWhere((String key, _) => key.startsWith(filter.prefix) && (filter.allowList == null || filter.allowList!.contains(key))); - return _writePreferences(preferences); + return _writePreferences( + preferences, + _defaultFileName, + fs: fs, + pathProvider: pathProvider, + ); } @override @@ -148,13 +117,304 @@ class SharedPreferencesLinux extends SharedPreferencesStorePlatform { Future remove(String key) async { final Map preferences = await _readPreferences(); preferences.remove(key); - return _writePreferences(preferences); + return _writePreferences( + preferences, + _defaultFileName, + fs: fs, + pathProvider: pathProvider, + ); } @override Future setValue(String valueType, String key, Object value) async { final Map preferences = await _readPreferences(); preferences[key] = value; - return _writePreferences(preferences); + return _writePreferences( + preferences, + _defaultFileName, + fs: fs, + pathProvider: pathProvider, + ); + } +} + +/// The Linux implementation of [SharedPreferencesAsyncPlatform]. +/// +/// This class implements the `package:shared_preferences` functionality for Linux. +base class SharedPreferencesAsyncLinux extends SharedPreferencesAsyncPlatform { + /// Registers the Linux implementation. + static void registerWith() { + SharedPreferencesAsyncPlatform.instance = SharedPreferencesAsyncLinux(); + } + + /// Local copy of preferences + Map? _cachedPreferences; + + /// File system used to store to disk. Exposed for testing only. + @visibleForTesting + FileSystem fs = const LocalFileSystem(); + + /// The path_provider_linux instance used to find the support directory. + @visibleForTesting + PathProviderLinux pathProvider = PathProviderLinux(); + + @override + Future> getKeys( + GetPreferencesParameters parameters, + SharedPreferencesOptions options, + ) async { + return (await getPreferences(parameters, options)).keys.toSet(); + } + + @override + Future setString( + String key, + String value, + SharedPreferencesOptions options, + ) { + return _setValue(key, value, options); + } + + @override + Future setBool( + String key, + bool value, + SharedPreferencesOptions options, + ) { + return _setValue(key, value, options); + } + + @override + Future setDouble( + String key, + double value, + SharedPreferencesOptions options, + ) { + return _setValue(key, value, options); + } + + @override + Future setInt( + String key, + int value, + SharedPreferencesOptions options, + ) { + return _setValue(key, value, options); + } + + @override + Future setStringList( + String key, + List value, + SharedPreferencesOptions options, + ) { + return _setValue(key, value, options); + } + + @override + Future getString( + String key, + SharedPreferencesOptions options, + ) async { + final Map data = await _readAll({key}, options); + return data[key] as String?; + } + + @override + Future getBool( + String key, + SharedPreferencesOptions options, + ) async { + final Map data = await _readAll({key}, options); + return data[key] as bool?; + } + + @override + Future getDouble( + String key, + SharedPreferencesOptions options, + ) async { + final Map data = await _readAll({key}, options); + return data[key] as double?; + } + + @override + Future getInt( + String key, + SharedPreferencesOptions options, + ) async { + final Map data = await _readAll({key}, options); + return data[key] as int?; + } + + @override + Future?> getStringList( + String key, + SharedPreferencesOptions options, + ) async { + final Map data = await _readAll({key}, options); + return (data[key] as List?)?.cast().toList(); + } + + @override + Future clear(ClearPreferencesParameters parameters, + SharedPreferencesOptions options) async { + final SharedPreferencesLinuxOptions linuxOptions = + SharedPreferencesLinuxOptions.fromSharedPreferencesOptions(options); + final PreferencesFilters filter = parameters.filter; + final Map preferences = + await _readPreferences(linuxOptions.fileName); + preferences.removeWhere((String key, _) => + filter.allowList == null || filter.allowList!.contains(key)); + await _writePreferences( + preferences, + linuxOptions.fileName, + fs: fs, + pathProvider: pathProvider, + ); + } + + @override + Future> getPreferences( + GetPreferencesParameters parameters, + SharedPreferencesOptions options, + ) async { + return _readAll(parameters.filter.allowList, options); + } + + /// Reloads preferences from file. + @visibleForTesting + Future reload( + SharedPreferencesLinuxOptions options, + ) async { + _cachedPreferences = await _reload(options.fileName); + } + + Future> _readAll( + Set? allowList, + SharedPreferencesOptions options, + ) async { + final SharedPreferencesLinuxOptions linuxOptions = + SharedPreferencesLinuxOptions.fromSharedPreferencesOptions(options); + final Map prefs = + Map.from(await _readPreferences(linuxOptions.fileName)); + prefs.removeWhere((String key, _) => !(allowList?.contains(key) ?? true)); + return prefs; + } + + Future _setValue( + String key, Object value, SharedPreferencesOptions options) async { + final SharedPreferencesLinuxOptions linuxOptions = + SharedPreferencesLinuxOptions.fromSharedPreferencesOptions(options); + final Map preferences = + await _readPreferences(linuxOptions.fileName); + preferences[key] = value; + await _writePreferences( + preferences, + linuxOptions.fileName, + fs: fs, + pathProvider: pathProvider, + ); + } + + /// Checks for cached preferences and returns them or loads preferences from + /// file and returns and caches them. + Future> _readPreferences(String fileName) async { + _cachedPreferences ??= await _reload( + fileName, + fs: fs, + pathProvider: pathProvider, + ); + return _cachedPreferences!; + } +} + +/// Gets the file where the preferences are stored. +Future _getLocalDataFile( + String fileName, { + FileSystem fs = const LocalFileSystem(), + PathProviderLinux? pathProvider, +}) async { + pathProvider = pathProvider ?? PathProviderLinux(); + final String? directory = await pathProvider.getApplicationSupportPath(); + if (directory == null) { + return null; + } + final String fileLocation = path.join(directory, '$fileName.json'); + return fs.file(fileLocation); +} + +/// Gets the preferences from the stored file and saves them in cache. +Future> _reload( + String fileName, { + FileSystem fs = const LocalFileSystem(), + PathProviderLinux? pathProvider, +}) async { + Map preferences = {}; + final File? localDataFile = await _getLocalDataFile( + fileName, + fs: fs, + pathProvider: pathProvider, + ); + if (localDataFile != null && localDataFile.existsSync()) { + final String stringMap = localDataFile.readAsStringSync(); + if (stringMap.isNotEmpty) { + final Object? data = json.decode(stringMap); + if (data is Map) { + preferences = data.cast(); + } + } + } + return preferences; +} + +/// Writes the cached preferences to disk. Returns [true] if the operation +/// succeeded. +Future _writePreferences( + Map preferences, + String fileName, { + FileSystem fs = const LocalFileSystem(), + PathProviderLinux? pathProvider, +}) async { + try { + final File? localDataFile = await _getLocalDataFile( + fileName, + fs: fs, + pathProvider: pathProvider, + ); + if (localDataFile == null) { + debugPrint('Unable to determine where to write preferences.'); + return false; + } + if (!localDataFile.existsSync()) { + localDataFile.createSync(recursive: true); + } + final String stringMap = json.encode(preferences); + localDataFile.writeAsStringSync(stringMap); + } catch (e) { + debugPrint('Error saving preferences to disk: $e'); + return false; + } + return true; +} + +/// Linux specific SharedPreferences Options. +class SharedPreferencesLinuxOptions extends SharedPreferencesOptions { + /// Constructor for SharedPreferencesLinuxOptions. + const SharedPreferencesLinuxOptions({ + this.fileName = 'shared_preferences', + }); + + /// The name of the file to store preferences in. + final String fileName; + + /// Returns a new instance of [SharedPreferencesLinuxOptions] from an existing + /// [SharedPreferencesOptions]. + static SharedPreferencesLinuxOptions fromSharedPreferencesOptions( + SharedPreferencesOptions options) { + if (options is SharedPreferencesLinuxOptions) { + return options; + } + return const SharedPreferencesLinuxOptions(); } } diff --git a/packages/shared_preferences/shared_preferences_linux/pubspec.yaml b/packages/shared_preferences/shared_preferences_linux/pubspec.yaml index fab1ffeafd5c..c43a21bdb95f 100644 --- a/packages/shared_preferences/shared_preferences_linux/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_linux/pubspec.yaml @@ -2,11 +2,11 @@ name: shared_preferences_linux description: Linux implementation of the shared_preferences plugin repository: https://github.com/flutter/packages/tree/main/packages/shared_preferences/shared_preferences_linux issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22 -version: 2.3.2 +version: 2.4.1 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -22,7 +22,7 @@ dependencies: path: ^1.8.0 path_provider_linux: ^2.0.0 path_provider_platform_interface: ^2.0.0 - shared_preferences_platform_interface: ^2.3.0 + shared_preferences_platform_interface: ^2.4.0 dev_dependencies: flutter_test: diff --git a/packages/shared_preferences/shared_preferences_linux/test/fake_path_provider_linux.dart b/packages/shared_preferences/shared_preferences_linux/test/fake_path_provider_linux.dart new file mode 100644 index 000000000000..f726abe38563 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_linux/test/fake_path_provider_linux.dart @@ -0,0 +1,29 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +import 'package:flutter_test/flutter_test.dart'; +import 'package:path_provider_linux/path_provider_linux.dart'; +import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; + +/// Fake implementation of PathProviderLinux that returns hard-coded paths, +/// allowing tests to run on any platform. +/// +/// Note that this should only be used with an in-memory filesystem, as the +/// path it returns is a root path that does not actually exist on Linux. +class FakePathProviderLinux extends PathProviderPlatform + implements PathProviderLinux { + @override + Future getApplicationSupportPath() async => r'/appsupport'; + + @override + Future getTemporaryPath() async => null; + + @override + Future getLibraryPath() async => null; + + @override + Future getApplicationDocumentsPath() async => null; + + @override + Future getDownloadsPath() async => null; +} diff --git a/packages/shared_preferences/shared_preferences_linux/test/shared_preferences_linux_test.dart b/packages/shared_preferences/shared_preferences_linux/test/legacy_shared_preferences_linux_test.dart similarity index 90% rename from packages/shared_preferences/shared_preferences_linux/test/shared_preferences_linux_test.dart rename to packages/shared_preferences/shared_preferences_linux/test/legacy_shared_preferences_linux_test.dart index 185feb58c414..06faaa5c1e83 100644 --- a/packages/shared_preferences/shared_preferences_linux/test/shared_preferences_linux_test.dart +++ b/packages/shared_preferences/shared_preferences_linux/test/legacy_shared_preferences_linux_test.dart @@ -7,11 +7,12 @@ import 'package:file/memory.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:path/path.dart' as path; import 'package:path_provider_linux/path_provider_linux.dart'; -import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; import 'package:shared_preferences_linux/shared_preferences_linux.dart'; import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; import 'package:shared_preferences_platform_interface/types.dart'; +import 'fake_path_provider_linux.dart'; + void main() { late MemoryFileSystem fs; late PathProviderLinux pathProvider; @@ -75,7 +76,7 @@ void main() { return prefs; } - test('registered instance', () { + test('registered instance', () async { SharedPreferencesLinux.registerWith(); expect( SharedPreferencesStorePlatform.instance, isA()); @@ -254,26 +255,3 @@ void main() { expect(noValues, hasLength(0)); }); } - -/// Fake implementation of PathProviderLinux that returns hard-coded paths, -/// allowing tests to run on any platform. -/// -/// Note that this should only be used with an in-memory filesystem, as the -/// path it returns is a root path that does not actually exist on Linux. -class FakePathProviderLinux extends PathProviderPlatform - implements PathProviderLinux { - @override - Future getApplicationSupportPath() async => r'/appsupport'; - - @override - Future getTemporaryPath() async => null; - - @override - Future getLibraryPath() async => null; - - @override - Future getApplicationDocumentsPath() async => null; - - @override - Future getDownloadsPath() async => null; -} diff --git a/packages/shared_preferences/shared_preferences_linux/test/shared_preferences_linux_async_test.dart b/packages/shared_preferences/shared_preferences_linux/test/shared_preferences_linux_async_test.dart new file mode 100755 index 000000000000..d49bdc48eea8 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_linux/test/shared_preferences_linux_async_test.dart @@ -0,0 +1,203 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:file/memory.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:path_provider_linux/path_provider_linux.dart'; +import 'package:shared_preferences_linux/shared_preferences_linux.dart'; +import 'package:shared_preferences_platform_interface/types.dart'; + +import 'fake_path_provider_linux.dart'; + +void main() { + late MemoryFileSystem fs; + late PathProviderLinux pathProvider; + + SharedPreferencesAsyncLinux.registerWith(); + + 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']; + + const SharedPreferencesLinuxOptions emptyOptions = + SharedPreferencesLinuxOptions(); + + setUp(() { + fs = MemoryFileSystem.test(); + pathProvider = FakePathProviderLinux(); + }); + + SharedPreferencesAsyncLinux getPreferences() { + final SharedPreferencesAsyncLinux prefs = SharedPreferencesAsyncLinux(); + prefs.fs = fs; + prefs.pathProvider = pathProvider; + return prefs; + } + + test('set and get String', () async { + final SharedPreferencesAsyncLinux preferences = getPreferences(); + + await preferences.setString(stringKey, testString, emptyOptions); + expect(await preferences.getString(stringKey, emptyOptions), testString); + }); + + test('set and get bool', () async { + final SharedPreferencesAsyncLinux preferences = getPreferences(); + + await preferences.setBool(boolKey, testBool, emptyOptions); + expect(await preferences.getBool(boolKey, emptyOptions), testBool); + }); + + test('set and get int', () async { + final SharedPreferencesAsyncLinux preferences = getPreferences(); + + await preferences.setInt(intKey, testInt, emptyOptions); + expect(await preferences.getInt(intKey, emptyOptions), testInt); + }); + + test('set and get double', () async { + final SharedPreferencesAsyncLinux preferences = getPreferences(); + + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + expect(await preferences.getDouble(doubleKey, emptyOptions), testDouble); + }); + + test('set and get StringList', () async { + final SharedPreferencesAsyncLinux preferences = getPreferences(); + + await preferences.setStringList(listKey, testList, emptyOptions); + expect(await preferences.getStringList(listKey, emptyOptions), testList); + }); + + test('getPreferences', () async { + final SharedPreferencesAsyncLinux preferences = getPreferences(); + + await preferences.setString(stringKey, testString, emptyOptions); + await preferences.setBool(boolKey, testBool, emptyOptions); + await preferences.setInt(intKey, testInt, emptyOptions); + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + await 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', () async { + final SharedPreferencesAsyncLinux preferences = getPreferences(); + + await preferences.setString(stringKey, testString, emptyOptions); + await preferences.setBool(boolKey, testBool, emptyOptions); + await preferences.setInt(intKey, testInt, emptyOptions); + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + await 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', () async { + final SharedPreferencesAsyncLinux preferences = getPreferences(); + + await preferences.setString(stringKey, testString, emptyOptions); + await preferences.setBool(boolKey, testBool, emptyOptions); + await preferences.setInt(intKey, testInt, emptyOptions); + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + await 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 SharedPreferencesAsyncLinux preferences = getPreferences(); + + await preferences.setString(stringKey, testString, emptyOptions); + await preferences.setBool(boolKey, testBool, emptyOptions); + await preferences.setInt(intKey, testInt, emptyOptions); + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + await preferences.setStringList(listKey, testList, emptyOptions); + + 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)); + }); + + test('clear', () async { + final SharedPreferencesAsyncLinux preferences = getPreferences(); + + await preferences.setString(stringKey, testString, emptyOptions); + await preferences.setBool(boolKey, testBool, emptyOptions); + await preferences.setInt(intKey, testInt, emptyOptions); + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + await 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 SharedPreferencesAsyncLinux preferences = getPreferences(); + + await preferences.setString(stringKey, testString, emptyOptions); + await preferences.setBool(boolKey, testBool, emptyOptions); + await preferences.setInt(intKey, testInt, emptyOptions); + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + await 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); + }); +} diff --git a/packages/shared_preferences/shared_preferences_platform_interface/CHANGELOG.md b/packages/shared_preferences/shared_preferences_platform_interface/CHANGELOG.md index 3966f6525b94..b52c8c962bfc 100644 --- a/packages/shared_preferences/shared_preferences_platform_interface/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_platform_interface/CHANGELOG.md @@ -1,5 +1,14 @@ ## NEXT +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + +## 2.4.1 + +* Adds comments about unsupported types. + +## 2.4.0 + +* Adds `SharedPreferencesAsyncPlatform` API. * Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. ## 2.3.2 diff --git a/packages/shared_preferences/shared_preferences_platform_interface/README.md b/packages/shared_preferences/shared_preferences_platform_interface/README.md index 301ba68ea361..6716fe997c0b 100644 --- a/packages/shared_preferences/shared_preferences_platform_interface/README.md +++ b/packages/shared_preferences/shared_preferences_platform_interface/README.md @@ -9,9 +9,16 @@ same interface. # Usage To implement a new platform-specific implementation of `shared_preferences`, extend -[`SharedPreferencesPlatform`][2] with an implementation that performs the -platform-specific behavior, and when you register your plugin, set the default -`SharedPreferencesLoader` by calling the `SharedPreferencesPlatform.loader` setter. +[`SharedPreferencesPlatform`][2] and [`SharedPreferencesAsyncPlatform`][3] with +implementations that perform the platform-specific behaviors, and when you register +your plugin, set the default `SharedPreferencesStorePlatform` and +`SharedPreferencesAsyncPlatform` by calling the `SharedPreferencesPlatform.instance` +and `SharedPreferencesAsyncPlatform.instance` setters. + +Please note that the plugin tooling only registers the native and/or Dart classes +listed in your package's `pubspec.yaml`, so if you intend to implement more than +one class, you will need to manually register the second class +(as can be seen in the Android and iOS implementations). # Note on breaking changes @@ -23,3 +30,4 @@ on why a less-clean interface is preferable to a breaking change. [1]: ../shared_preferences [2]: lib/shared_preferences_platform_interface.dart +[3]: lib/shared_preferences_async_platform_interface.dart \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_platform_interface/lib/in_memory_shared_preferences_async.dart b/packages/shared_preferences/shared_preferences_platform_interface/lib/in_memory_shared_preferences_async.dart new file mode 100644 index 000000000000..5080241814b5 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_platform_interface/lib/in_memory_shared_preferences_async.dart @@ -0,0 +1,158 @@ +// 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 'shared_preferences_async_platform_interface.dart'; +import 'types.dart'; + +/// Stores data in memory. +/// +/// Data does not persist across application restarts. This is useful in unit tests. +base class InMemorySharedPreferencesAsync + extends SharedPreferencesAsyncPlatform { + /// Instantiates an empty in-memory preferences store. + InMemorySharedPreferencesAsync.empty() : _data = {}; + + /// Instantiates an in-memory preferences store containing a copy of [data]. + InMemorySharedPreferencesAsync.withData(Map data) + : _data = Map.from(data); + + final Map _data; + + @override + Future clear( + ClearPreferencesParameters parameters, + SharedPreferencesOptions options, + ) async { + final PreferencesFilters filter = parameters.filter; + if (filter.allowList != null) { + _data.removeWhere((String key, _) => filter.allowList!.contains(key)); + } else { + _data.clear(); + } + return true; + } + + @override + Future> getPreferences( + GetPreferencesParameters parameters, + SharedPreferencesOptions options, + ) async { + final PreferencesFilters filter = parameters.filter; + final Map preferences = Map.from(_data); + preferences.removeWhere((String key, _) => + filter.allowList != null && !filter.allowList!.contains(key)); + return preferences; + } + + Future _setValue( + String key, + Object value, + SharedPreferencesOptions options, + ) async { + _data[key] = value; + return true; + } + + @override + Future setString( + String key, + String value, + SharedPreferencesOptions options, + ) async { + return _setValue(key, value, options); + } + + @override + Future setInt( + String key, + int value, + SharedPreferencesOptions options, + ) async { + return _setValue(key, value, options); + } + + @override + Future setDouble( + String key, + double value, + SharedPreferencesOptions options, + ) async { + return _setValue(key, value, options); + } + + @override + Future setBool( + String key, + bool value, + SharedPreferencesOptions options, + ) async { + return _setValue(key, value, options); + } + + @override + Future setStringList( + String key, + List value, + SharedPreferencesOptions options, + ) async { + return _setValue(key, value, options); + } + + @override + Future getString( + String key, + SharedPreferencesOptions options, + ) async { + return _data[key] as String?; + } + + @override + Future getBool( + String key, + SharedPreferencesOptions options, + ) async { + return _data[key] as bool?; + } + + @override + Future getDouble( + String key, + SharedPreferencesOptions options, + ) async { + return _data[key] as double?; + } + + @override + Future getInt( + String key, + SharedPreferencesOptions options, + ) async { + return _data[key] as int?; + } + + @override + Future?> getStringList( + String key, + SharedPreferencesOptions options, + ) async { + final List? data = _data[key] as List?; + return data?.cast(); + } + + @override + Future> getKeys( + GetPreferencesParameters parameters, + SharedPreferencesOptions options, + ) async { + final Set keys = _data.keys.toSet(); + if (parameters.filter.allowList != null) { + keys.retainWhere( + (String element) => parameters.filter.allowList!.contains(element)); + } + + return keys; + } +} diff --git a/packages/shared_preferences/shared_preferences_platform_interface/lib/shared_preferences_async_platform_interface.dart b/packages/shared_preferences/shared_preferences_platform_interface/lib/shared_preferences_async_platform_interface.dart new file mode 100644 index 000000000000..577a9db6234d --- /dev/null +++ b/packages/shared_preferences/shared_preferences_platform_interface/lib/shared_preferences_async_platform_interface.dart @@ -0,0 +1,119 @@ +// 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 'types.dart'; + +/// The interface that implementations of shared_preferences_async must implement. +abstract base class SharedPreferencesAsyncPlatform { + /// Constructs a SharedPreferencesAsyncPlatform. + SharedPreferencesAsyncPlatform(); + + /// The instance of [SharedPreferencesAsyncPlatform] to use. + static SharedPreferencesAsyncPlatform? instance; + + /// Stores the String [value] associated with the [key]. + Future setString( + String key, + String value, + SharedPreferencesOptions options, + ); + + /// Stores the bool [value] associated with the [key]. + Future setBool( + String key, + bool value, + SharedPreferencesOptions options, + ); + + /// Stores the double [value] associated with the [key]. + Future setDouble( + String key, + double value, + SharedPreferencesOptions options, + ); + + /// Stores the int [value] associated with the [key]. + Future setInt( + String key, + int value, + SharedPreferencesOptions options, + ); + + /// Stores the List [value] associated with the [key]. + Future setStringList( + String key, + List value, + SharedPreferencesOptions options, + ); + + /// Retrieves the String [value] associated with the [key], if any. + /// + /// Throws a [TypeError] if the returned type is not a String. + /// May return null for unsupported types. + Future getString( + String key, + SharedPreferencesOptions options, + ); + + /// Retrieves the bool [value] associated with the [key], if any. + /// + /// Throws a [TypeError] if the returned type is not a bool. + /// May return null for unsupported types. + Future getBool( + String key, + SharedPreferencesOptions options, + ); + + /// Retrieves the double [value] associated with the [key], if any. + /// + /// Throws a [TypeError] if the returned type is not a double. + /// May return null for unsupported types. + Future getDouble( + String key, + SharedPreferencesOptions options, + ); + + /// Retrieves the int [value] associated with the [key], if any. + /// + /// Throws a [TypeError] if the returned type is not an int. + /// May return null for unsupported types. + Future getInt( + String key, + SharedPreferencesOptions options, + ); + + /// Retrieves the List [value] associated with the [key], if any. + /// + /// Throws a [TypeError] if the returned type is not a List. + /// May return null for unsupported types. + Future?> getStringList( + String key, + SharedPreferencesOptions options, + ); + + /// Removes all keys and values in the store that match the given [parameters]. + Future clear( + ClearPreferencesParameters parameters, + SharedPreferencesOptions options, + ); + + /// Returns all key/value pairs persisting in this store that match the given [parameters]. + /// + /// Does not return unsupported types, or lists containing unsupported types. + Future> getPreferences( + GetPreferencesParameters parameters, + SharedPreferencesOptions options, + ); + + /// Returns all keys persisting in this store that match the given [parameters]. + /// + /// Does not return keys for values that are unsupported types, or lists containing + /// unsupported types. + Future> getKeys( + GetPreferencesParameters parameters, + SharedPreferencesOptions options, + ); +} diff --git a/packages/shared_preferences/shared_preferences_platform_interface/lib/types.dart b/packages/shared_preferences/shared_preferences_platform_interface/lib/types.dart index f52f07194e2d..979361c17e84 100644 --- a/packages/shared_preferences/shared_preferences_platform_interface/lib/types.dart +++ b/packages/shared_preferences/shared_preferences_platform_interface/lib/types.dart @@ -2,9 +2,62 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -/// Filter options used to get and clear preferences. +// shared_preferences_async types. + +import 'package:flutter/foundation.dart'; + +/// Basic options for creating SharedPreferencesAsync classes. +/// +/// This class exists to provide extension to platform specific options as +/// there are currently no general options that are not platform specific. +@immutable +class SharedPreferencesOptions { + /// Constructor for SharedPreferencesOptions. + const SharedPreferencesOptions(); +} + +/// Filter options used to get and clear preferences on shared_preferences_async. +@immutable +class PreferencesFilters { + /// Creates a new instance with the given options. + const PreferencesFilters({ + this.allowList, + }); + + /// A list of preference keys that will limit getting and clearing to only + /// items included in this list. + /// + /// An empty set will create a filter that allows no items to be set/get. + final Set? allowList; +} + +/// Parameters for use in [get] methods on shared_preferences_async. +@immutable +class GetPreferencesParameters { + /// Creates a new instance with the given options. + const GetPreferencesParameters({required this.filter}); + + /// Filter to limit which preferences are returned. + final PreferencesFilters filter; +} + +/// Parameters for use in [clear] methods on shared_preferences_async. +@immutable +class ClearPreferencesParameters { + /// Creates a new instance with the given options. + const ClearPreferencesParameters({required this.filter}); + + /// Filter to limit which preferences are cleared. + final PreferencesFilters filter; +} + +////////////////////////////////// +// legacy_shared_preferences types. +////////////////////////////////// + +/// Filter options used to get and clear preferences on legacy_shared_preferences. class PreferencesFilter { - /// Constructor. + /// Creates a new instance with the given options. PreferencesFilter({ required this.prefix, this.allowList, @@ -19,18 +72,18 @@ class PreferencesFilter { Set? allowList; } -/// Parameters for use in [getAll] methods. +/// Parameters for use in [getAll] methods on legacy_shared_preferences. class GetAllParameters { - /// Constructor. + /// Creates a new instance with the given options. GetAllParameters({required this.filter}); /// Filter to limit which preferences are returned. PreferencesFilter filter; } -/// Parameters for use in [clear] methods. +/// Parameters for use in [clear] methods on legacy_shared_preferences. class ClearParameters { - /// Constructor. + /// Creates a new instance with the given options. ClearParameters({required this.filter}); /// Filter to limit which preferences are cleared. diff --git a/packages/shared_preferences/shared_preferences_platform_interface/pubspec.yaml b/packages/shared_preferences/shared_preferences_platform_interface/pubspec.yaml index c8c98325957c..6161a5882e1d 100644 --- a/packages/shared_preferences/shared_preferences_platform_interface/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_platform_interface/pubspec.yaml @@ -2,11 +2,11 @@ name: shared_preferences_platform_interface description: A common platform interface for the shared_preferences plugin. repository: https://github.com/flutter/packages/tree/main/packages/shared_preferences/shared_preferences_platform_interface issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22 -version: 2.3.2 +version: 2.4.1 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/shared_preferences/shared_preferences_platform_interface/test/method_channel_shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_platform_interface/test/deprecated_method_channel_shared_preferences_test.dart similarity index 100% rename from packages/shared_preferences/shared_preferences_platform_interface/test/method_channel_shared_preferences_test.dart rename to packages/shared_preferences/shared_preferences_platform_interface/test/deprecated_method_channel_shared_preferences_test.dart diff --git a/packages/shared_preferences/shared_preferences_web/CHANGELOG.md b/packages/shared_preferences/shared_preferences_web/CHANGELOG.md index 5cb8dc3b6120..a1c53c014650 100644 --- a/packages/shared_preferences/shared_preferences_web/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_web/CHANGELOG.md @@ -1,3 +1,16 @@ +## 2.4.2 + +* Fixes `getStringList` returning immutable list. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + +## 2.4.1 + +* Adds support for `web: ^1.0.0`. + +## 2.4.0 + +* Adds `SharedPreferencesAsyncWeb` API. + ## 2.3.0 * Updates web code to package `web: ^0.5.0`. diff --git a/packages/shared_preferences/shared_preferences_web/README.md b/packages/shared_preferences/shared_preferences_web/README.md index e9fd0d2caa71..3f45e52e872c 100644 --- a/packages/shared_preferences/shared_preferences_web/README.md +++ b/packages/shared_preferences/shared_preferences_web/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/shared_preferences -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/shared_preferences/shared_preferences_web/example/README.md b/packages/shared_preferences/shared_preferences_web/example/README.md index 4a01887de7fb..932e9f227cbe 100644 --- a/packages/shared_preferences/shared_preferences_web/example/README.md +++ b/packages/shared_preferences/shared_preferences_web/example/README.md @@ -15,5 +15,5 @@ This package uses `package:integration_test` to run its tests in a web browser. See [Plugin Tests > Web Tests](https://github.com/flutter/flutter/blob/master/docs/ecosystem/testing/Plugin-Tests.md#web-tests) in the Flutter documentation for instructions to set up and run the tests in this package. -Check [flutter.dev > Integration testing](https://flutter.dev/docs/testing/integration-tests) +Check [flutter.dev > Integration testing](https://docs.flutter.dev/testing/integration-tests) for more info. diff --git a/packages/shared_preferences/shared_preferences_web/example/integration_test/shared_preferences_web_test.dart b/packages/shared_preferences/shared_preferences_web/example/integration_test/shared_preferences_web_test.dart index 0238ba578a45..90ebbc5b899c 100644 --- a/packages/shared_preferences/shared_preferences_web/example/integration_test/shared_preferences_web_test.dart +++ b/packages/shared_preferences/shared_preferences_web/example/integration_test/shared_preferences_web_test.dart @@ -5,6 +5,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:shared_preferences_platform_interface/method_channel_shared_preferences.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; import 'package:shared_preferences_platform_interface/types.dart'; import 'package:shared_preferences_web/shared_preferences_web.dart'; @@ -17,357 +18,574 @@ void main() { setUp(() { html.window.localStorage.clear(); }); + group('shared_preferences_web', () { + testWidgets('registers itself', (WidgetTester tester) async { + SharedPreferencesStorePlatform.instance = + MethodChannelSharedPreferencesStore(); + expect(SharedPreferencesStorePlatform.instance, + isNot(isA())); + SharedPreferencesPlugin.registerWith(null); + expect(SharedPreferencesStorePlatform.instance, + isA()); + }); - testWidgets('registers itself', (WidgetTester tester) async { - SharedPreferencesStorePlatform.instance = - MethodChannelSharedPreferencesStore(); - expect(SharedPreferencesStorePlatform.instance, - isNot(isA())); - SharedPreferencesPlugin.registerWith(null); - expect(SharedPreferencesStorePlatform.instance, - isA()); - }); - - const Map flutterTestValues = { - 'flutter.String': 'hello world', - 'flutter.Bool': true, - 'flutter.Int': 42, - 'flutter.Double': 3.14159, - 'flutter.StringList': ['foo', 'bar'], - }; - - const Map prefixTestValues = { - 'prefix.String': 'hello world', - 'prefix.Bool': true, - 'prefix.Int': 42, - 'prefix.Double': 3.14159, - 'prefix.StringList': ['foo', 'bar'], - }; - - const Map nonPrefixTestValues = { - 'String': 'hello world', - 'Bool': true, - 'Int': 42, - 'Double': 3.14159, - 'StringList': ['foo', 'bar'], - }; - - final Map allTestValues = {}; - - allTestValues.addAll(flutterTestValues); - allTestValues.addAll(prefixTestValues); - allTestValues.addAll(nonPrefixTestValues); - - late SharedPreferencesStorePlatform preferences; - - setUp(() async { - preferences = SharedPreferencesStorePlatform.instance; - }); - - tearDown(() async { - await preferences.clearWithParameters( - ClearParameters( - filter: PreferencesFilter(prefix: ''), - ), - ); - }); - - testWidgets('reading', (WidgetTester _) async { - final Map values = await preferences.getAll(); - expect(values.length, 0); - }); - - Future addData() async { - await preferences.setValue('String', 'String', allTestValues['String']!); - await preferences.setValue('Bool', 'Bool', allTestValues['Bool']!); - await preferences.setValue('Int', 'Int', allTestValues['Int']!); - await preferences.setValue('Double', 'Double', allTestValues['Double']!); - await preferences.setValue( - 'StringList', 'StringList', allTestValues['StringList']!); - await preferences.setValue( - 'String', 'prefix.String', allTestValues['prefix.String']!); - await preferences.setValue( - 'Bool', 'prefix.Bool', allTestValues['prefix.Bool']!); - await preferences.setValue( - 'Int', 'prefix.Int', allTestValues['prefix.Int']!); - await preferences.setValue( - 'Double', 'prefix.Double', allTestValues['prefix.Double']!); - await preferences.setValue( - 'StringList', 'prefix.StringList', allTestValues['prefix.StringList']!); - await preferences.setValue( - 'String', 'flutter.String', allTestValues['flutter.String']!); - await preferences.setValue( - 'Bool', 'flutter.Bool', allTestValues['flutter.Bool']!); - await preferences.setValue( - 'Int', 'flutter.Int', allTestValues['flutter.Int']!); - await preferences.setValue( - 'Double', 'flutter.Double', allTestValues['flutter.Double']!); - await preferences.setValue('StringList', 'flutter.StringList', - allTestValues['flutter.StringList']!); - } - - testWidgets('keys', (WidgetTester _) async { - await addData(); - final Iterable keys = html.window.localStorage.keys; - final Iterable expectedKeys = allTestValues.keys; - - expect(keys, hasLength(expectedKeys.length)); - expect(keys, containsAll(expectedKeys)); - }); + const Map flutterTestValues = { + 'flutter.String': 'hello world', + 'flutter.Bool': true, + 'flutter.Int': 42, + 'flutter.Double': 3.14159, + 'flutter.StringList': ['foo', 'bar'], + }; + + const Map prefixTestValues = { + 'prefix.String': 'hello world', + 'prefix.Bool': true, + 'prefix.Int': 42, + 'prefix.Double': 3.14159, + 'prefix.StringList': ['foo', 'bar'], + }; + + const Map nonPrefixTestValues = { + 'String': 'hello world', + 'Bool': true, + 'Int': 42, + 'Double': 3.14159, + 'StringList': ['foo', 'bar'], + }; + + final Map allTestValues = {}; + + allTestValues.addAll(flutterTestValues); + allTestValues.addAll(prefixTestValues); + allTestValues.addAll(nonPrefixTestValues); + + late SharedPreferencesStorePlatform preferences; - testWidgets('clear', (WidgetTester _) async { - await addData(); - await preferences.clear(); - final Map values = await preferences.getAll(); - expect(values['flutter.String'], null); - expect(values['flutter.Bool'], null); - expect(values['flutter.Int'], null); - expect(values['flutter.Double'], null); - expect(values['flutter.StringList'], null); - }); - - group('withPrefix', () { setUp(() async { - await addData(); + preferences = SharedPreferencesStorePlatform.instance; }); - testWidgets('remove', (WidgetTester _) async { - const String key = 'flutter.String'; - await preferences.remove(key); - final Map values = - // ignore: deprecated_member_use - await preferences.getAllWithPrefix(''); - expect(values[key], isNull); + tearDown(() async { + await preferences.clearWithParameters( + ClearParameters( + filter: PreferencesFilter(prefix: ''), + ), + ); }); - testWidgets('get all with prefix', (WidgetTester _) async { - final Map values = - // ignore: deprecated_member_use - await preferences.getAllWithPrefix('prefix.'); - expect(values['prefix.String'], allTestValues['prefix.String']); - expect(values['prefix.Bool'], allTestValues['prefix.Bool']); - expect(values['prefix.Int'], allTestValues['prefix.Int']); - expect(values['prefix.Double'], allTestValues['prefix.Double']); - expect(values['prefix.StringList'], allTestValues['prefix.StringList']); + testWidgets('reading', (WidgetTester _) async { + final Map values = await preferences.getAll(); + expect(values.length, 0); }); - testWidgets('getAllWithNoPrefix', (WidgetTester _) async { - final Map values = - // ignore: deprecated_member_use - await preferences.getAllWithPrefix(''); - expect(values['String'], allTestValues['String']); - expect(values['Bool'], allTestValues['Bool']); - expect(values['Int'], allTestValues['Int']); - expect(values['Double'], allTestValues['Double']); - expect(values['StringList'], allTestValues['StringList']); - expect(values['flutter.String'], allTestValues['flutter.String']); - expect(values['flutter.Bool'], allTestValues['flutter.Bool']); - expect(values['flutter.Int'], allTestValues['flutter.Int']); - expect(values['flutter.Double'], allTestValues['flutter.Double']); - expect(values['flutter.StringList'], allTestValues['flutter.StringList']); - }); + Future addData() async { + await preferences.setValue('String', 'String', allTestValues['String']!); + await preferences.setValue('Bool', 'Bool', allTestValues['Bool']!); + await preferences.setValue('Int', 'Int', allTestValues['Int']!); + await preferences.setValue('Double', 'Double', allTestValues['Double']!); + await preferences.setValue( + 'StringList', 'StringList', allTestValues['StringList']!); + await preferences.setValue( + 'String', 'prefix.String', allTestValues['prefix.String']!); + await preferences.setValue( + 'Bool', 'prefix.Bool', allTestValues['prefix.Bool']!); + await preferences.setValue( + 'Int', 'prefix.Int', allTestValues['prefix.Int']!); + await preferences.setValue( + 'Double', 'prefix.Double', allTestValues['prefix.Double']!); + await preferences.setValue('StringList', 'prefix.StringList', + allTestValues['prefix.StringList']!); + await preferences.setValue( + 'String', 'flutter.String', allTestValues['flutter.String']!); + await preferences.setValue( + 'Bool', 'flutter.Bool', allTestValues['flutter.Bool']!); + await preferences.setValue( + 'Int', 'flutter.Int', allTestValues['flutter.Int']!); + await preferences.setValue( + 'Double', 'flutter.Double', allTestValues['flutter.Double']!); + await preferences.setValue('StringList', 'flutter.StringList', + allTestValues['flutter.StringList']!); + } + + testWidgets('keys', (WidgetTester _) async { + await addData(); + final Iterable keys = html.window.localStorage.keys; + final Iterable expectedKeys = allTestValues.keys; - testWidgets('clearWithPrefix', (WidgetTester _) async { - // ignore: deprecated_member_use - await preferences.clearWithPrefix('prefix.'); - Map values = - // ignore: deprecated_member_use - await preferences.getAllWithPrefix('prefix.'); - expect(values['prefix.String'], null); - expect(values['prefix.Bool'], null); - expect(values['prefix.Int'], null); - expect(values['prefix.Double'], null); - expect(values['prefix.StringList'], null); - // ignore: deprecated_member_use - values = await preferences.getAllWithPrefix('flutter.'); - expect(values['flutter.String'], allTestValues['flutter.String']); - expect(values['flutter.Bool'], allTestValues['flutter.Bool']); - expect(values['flutter.Int'], allTestValues['flutter.Int']); - expect(values['flutter.Double'], allTestValues['flutter.Double']); - expect(values['flutter.StringList'], allTestValues['flutter.StringList']); + expect(keys, hasLength(expectedKeys.length)); + expect(keys, containsAll(expectedKeys)); }); - testWidgets('clearWithNoPrefix', (WidgetTester _) async { - // ignore: deprecated_member_use - await preferences.clearWithPrefix(''); - final Map values = - // ignore: deprecated_member_use - await preferences.getAllWithPrefix(''); - expect(values['String'], null); - expect(values['Bool'], null); - expect(values['Int'], null); - expect(values['Double'], null); - expect(values['StringList'], null); + testWidgets('clear', (WidgetTester _) async { + await addData(); + await preferences.clear(); + final Map values = await preferences.getAll(); expect(values['flutter.String'], null); expect(values['flutter.Bool'], null); expect(values['flutter.Int'], null); expect(values['flutter.Double'], null); expect(values['flutter.StringList'], null); }); - }); - group('withParameters', () { - setUp(() async { - await addData(); + group('withPrefix', () { + setUp(() async { + await addData(); + }); + + testWidgets('remove', (WidgetTester _) async { + const String key = 'flutter.String'; + await preferences.remove(key); + final Map values = + // ignore: deprecated_member_use + await preferences.getAllWithPrefix(''); + expect(values[key], isNull); + }); + + testWidgets('get all with prefix', (WidgetTester _) async { + final Map values = + // ignore: deprecated_member_use + await preferences.getAllWithPrefix('prefix.'); + expect(values['prefix.String'], allTestValues['prefix.String']); + expect(values['prefix.Bool'], allTestValues['prefix.Bool']); + expect(values['prefix.Int'], allTestValues['prefix.Int']); + expect(values['prefix.Double'], allTestValues['prefix.Double']); + expect(values['prefix.StringList'], allTestValues['prefix.StringList']); + }); + + testWidgets('getAllWithNoPrefix', (WidgetTester _) async { + final Map values = + // ignore: deprecated_member_use + await preferences.getAllWithPrefix(''); + expect(values['String'], allTestValues['String']); + expect(values['Bool'], allTestValues['Bool']); + expect(values['Int'], allTestValues['Int']); + expect(values['Double'], allTestValues['Double']); + expect(values['StringList'], allTestValues['StringList']); + expect(values['flutter.String'], allTestValues['flutter.String']); + expect(values['flutter.Bool'], allTestValues['flutter.Bool']); + expect(values['flutter.Int'], allTestValues['flutter.Int']); + expect(values['flutter.Double'], allTestValues['flutter.Double']); + expect( + values['flutter.StringList'], allTestValues['flutter.StringList']); + }); + + testWidgets('clearWithPrefix', (WidgetTester _) async { + // ignore: deprecated_member_use + await preferences.clearWithPrefix('prefix.'); + Map values = + // ignore: deprecated_member_use + await preferences.getAllWithPrefix('prefix.'); + expect(values['prefix.String'], null); + expect(values['prefix.Bool'], null); + expect(values['prefix.Int'], null); + expect(values['prefix.Double'], null); + expect(values['prefix.StringList'], null); + // ignore: deprecated_member_use + values = await preferences.getAllWithPrefix('flutter.'); + expect(values['flutter.String'], allTestValues['flutter.String']); + expect(values['flutter.Bool'], allTestValues['flutter.Bool']); + expect(values['flutter.Int'], allTestValues['flutter.Int']); + expect(values['flutter.Double'], allTestValues['flutter.Double']); + expect( + values['flutter.StringList'], allTestValues['flutter.StringList']); + }); + + testWidgets('clearWithNoPrefix', (WidgetTester _) async { + // ignore: deprecated_member_use + await preferences.clearWithPrefix(''); + final Map values = + // ignore: deprecated_member_use + await preferences.getAllWithPrefix(''); + expect(values['String'], null); + expect(values['Bool'], null); + expect(values['Int'], null); + expect(values['Double'], null); + expect(values['StringList'], null); + expect(values['flutter.String'], null); + expect(values['flutter.Bool'], null); + expect(values['flutter.Int'], null); + expect(values['flutter.Double'], null); + expect(values['flutter.StringList'], null); + }); + }); + + group('withParameters', () { + setUp(() async { + await addData(); + }); + + testWidgets('remove', (WidgetTester _) async { + const String key = 'flutter.String'; + await preferences.remove(key); + final Map values = + await preferences.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: ''), + ), + ); + expect(values[key], isNull); + }); + + testWidgets('get all with prefix', (WidgetTester _) async { + final Map values = + await preferences.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: 'prefix.'), + ), + ); + expect(values['prefix.String'], allTestValues['prefix.String']); + expect(values['prefix.Bool'], allTestValues['prefix.Bool']); + expect(values['prefix.Int'], allTestValues['prefix.Int']); + expect(values['prefix.Double'], allTestValues['prefix.Double']); + expect(values['prefix.StringList'], allTestValues['prefix.StringList']); + }); + + testWidgets('get all with allow list', (WidgetTester _) async { + final Map values = + await preferences.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter( + prefix: 'prefix.', + allowList: {'prefix.String'}, + ), + ), + ); + expect(values['prefix.String'], allTestValues['prefix.String']); + expect(values['prefix.Bool'], null); + expect(values['prefix.Int'], null); + expect(values['prefix.Double'], null); + expect(values['prefix.StringList'], null); + }); + + testWidgets('getAllWithNoPrefix', (WidgetTester _) async { + final Map values = + await preferences.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: ''), + ), + ); + expect(values['String'], allTestValues['String']); + expect(values['Bool'], allTestValues['Bool']); + expect(values['Int'], allTestValues['Int']); + expect(values['Double'], allTestValues['Double']); + expect(values['StringList'], allTestValues['StringList']); + expect(values['flutter.String'], allTestValues['flutter.String']); + expect(values['flutter.Bool'], allTestValues['flutter.Bool']); + expect(values['flutter.Int'], allTestValues['flutter.Int']); + expect(values['flutter.Double'], allTestValues['flutter.Double']); + expect( + values['flutter.StringList'], allTestValues['flutter.StringList']); + }); + + testWidgets('clearWithParameters', (WidgetTester _) async { + await preferences.clearWithParameters( + ClearParameters( + filter: PreferencesFilter(prefix: 'prefix.'), + ), + ); + Map values = await preferences.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: 'prefix.'), + ), + ); + expect(values['prefix.String'], null); + expect(values['prefix.Bool'], null); + expect(values['prefix.Int'], null); + expect(values['prefix.Double'], null); + expect(values['prefix.StringList'], null); + values = await preferences.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: 'flutter.'), + ), + ); + expect(values['flutter.String'], allTestValues['flutter.String']); + expect(values['flutter.Bool'], allTestValues['flutter.Bool']); + expect(values['flutter.Int'], allTestValues['flutter.Int']); + expect(values['flutter.Double'], allTestValues['flutter.Double']); + expect( + values['flutter.StringList'], allTestValues['flutter.StringList']); + }); + + testWidgets('clearWithParameters with allow list', + (WidgetTester _) async { + await addData(); + await preferences.clearWithParameters( + ClearParameters( + filter: PreferencesFilter( + prefix: 'prefix.', + allowList: {'prefix.StringList'}, + ), + ), + ); + Map values = await preferences.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: 'prefix.'), + ), + ); + expect(values['prefix.String'], allTestValues['prefix.String']); + expect(values['prefix.Bool'], allTestValues['prefix.Bool']); + expect(values['prefix.Int'], allTestValues['prefix.Int']); + expect(values['prefix.Double'], allTestValues['prefix.Double']); + expect(values['prefix.StringList'], null); + values = await preferences.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: 'flutter.'), + ), + ); + expect(values['flutter.String'], allTestValues['flutter.String']); + expect(values['flutter.Bool'], allTestValues['flutter.Bool']); + expect(values['flutter.Int'], allTestValues['flutter.Int']); + expect(values['flutter.Double'], allTestValues['flutter.Double']); + expect( + values['flutter.StringList'], allTestValues['flutter.StringList']); + }); + + testWidgets('clearWithNoPrefix', (WidgetTester _) async { + await preferences.clearWithParameters( + ClearParameters( + filter: PreferencesFilter(prefix: ''), + ), + ); + final Map values = + await preferences.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: ''), + ), + ); + expect(values['String'], null); + expect(values['Bool'], null); + expect(values['Int'], null); + expect(values['Double'], null); + expect(values['StringList'], null); + expect(values['flutter.String'], null); + expect(values['flutter.Bool'], null); + expect(values['flutter.Int'], null); + expect(values['flutter.Double'], null); + expect(values['flutter.StringList'], null); + }); }); - testWidgets('remove', (WidgetTester _) async { - const String key = 'flutter.String'; - await preferences.remove(key); + testWidgets('simultaneous writes', (WidgetTester _) async { + final List> writes = >[]; + const int writeCount = 100; + for (int i = 1; i <= writeCount; i++) { + writes.add(preferences.setValue('Int', 'Int', i)); + } + final List result = await Future.wait(writes, eagerError: true); + // All writes should succeed. + expect(result.where((bool element) => !element), isEmpty); + // The last write should win. final Map values = await preferences.getAllWithParameters( GetAllParameters( filter: PreferencesFilter(prefix: ''), ), ); - expect(values[key], isNull); + expect(values['Int'], writeCount); }); + }); - testWidgets('get all with prefix', (WidgetTester _) async { - final Map values = await preferences.getAllWithParameters( - GetAllParameters( - filter: PreferencesFilter(prefix: 'prefix.'), - ), - ); - expect(values['prefix.String'], allTestValues['prefix.String']); - expect(values['prefix.Bool'], allTestValues['prefix.Bool']); - expect(values['prefix.Int'], allTestValues['prefix.Int']); - expect(values['prefix.Double'], allTestValues['prefix.Double']); - expect(values['prefix.StringList'], allTestValues['prefix.StringList']); + group('shared_preferences_async', () { + const SharedPreferencesWebOptions emptyOptions = + SharedPreferencesWebOptions(); + + 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); }); - testWidgets('get all with allow list', (WidgetTester _) async { - final Map values = await preferences.getAllWithParameters( - GetAllParameters( - filter: PreferencesFilter( - prefix: 'prefix.', - allowList: {'prefix.String'}, - ), - ), - ); - expect(values['prefix.String'], allTestValues['prefix.String']); - expect(values['prefix.Bool'], null); - expect(values['prefix.Int'], null); - expect(values['prefix.Double'], null); - expect(values['prefix.StringList'], null); + testWidgets('set and get bool', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + await preferences.setBool(boolKey, testBool, emptyOptions); + expect(await preferences.getBool(boolKey, emptyOptions), testBool); }); - testWidgets('getAllWithNoPrefix', (WidgetTester _) async { - final Map values = await preferences.getAllWithParameters( - GetAllParameters( - filter: PreferencesFilter(prefix: ''), - ), - ); - expect(values['String'], allTestValues['String']); - expect(values['Bool'], allTestValues['Bool']); - expect(values['Int'], allTestValues['Int']); - expect(values['Double'], allTestValues['Double']); - expect(values['StringList'], allTestValues['StringList']); - expect(values['flutter.String'], allTestValues['flutter.String']); - expect(values['flutter.Bool'], allTestValues['flutter.Bool']); - expect(values['flutter.Int'], allTestValues['flutter.Int']); - expect(values['flutter.Double'], allTestValues['flutter.Double']); - expect(values['flutter.StringList'], allTestValues['flutter.StringList']); + testWidgets('set and get int', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + await preferences.setInt(intKey, testInt, emptyOptions); + expect(await preferences.getInt(intKey, emptyOptions), testInt); }); - testWidgets('clearWithParameters', (WidgetTester _) async { - await preferences.clearWithParameters( - ClearParameters( - filter: PreferencesFilter(prefix: 'prefix.'), - ), - ); - Map values = await preferences.getAllWithParameters( - GetAllParameters( - filter: PreferencesFilter(prefix: 'prefix.'), - ), - ); - expect(values['prefix.String'], null); - expect(values['prefix.Bool'], null); - expect(values['prefix.Int'], null); - expect(values['prefix.Double'], null); - expect(values['prefix.StringList'], null); - values = await preferences.getAllWithParameters( - GetAllParameters( - filter: PreferencesFilter(prefix: 'flutter.'), - ), + testWidgets('set and get double', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + expect(await preferences.getDouble(doubleKey, emptyOptions), testDouble); + }); + + testWidgets('set and get StringList', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + await preferences.setStringList(listKey, testList, emptyOptions); + expect(await preferences.getStringList(listKey, emptyOptions), testList); + }); + + testWidgets('getStringList returns mutable list', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + 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', (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()), + emptyOptions, ); - expect(values['flutter.String'], allTestValues['flutter.String']); - expect(values['flutter.Bool'], allTestValues['flutter.Bool']); - expect(values['flutter.Int'], allTestValues['flutter.Int']); - expect(values['flutter.Double'], allTestValues['flutter.Double']); - expect(values['flutter.StringList'], allTestValues['flutter.StringList']); + + 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('clearWithParameters with allow list', (WidgetTester _) async { - await addData(); - await preferences.clearWithParameters( - ClearParameters( - filter: PreferencesFilter( - prefix: 'prefix.', - allowList: {'prefix.StringList'}, - ), + 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}), ), + emptyOptions, ); - Map values = await preferences.getAllWithParameters( - GetAllParameters( - filter: PreferencesFilter(prefix: 'prefix.'), - ), + + expect(gotAll.length, 2); + expect(gotAll[stringKey], testString); + expect(gotAll[boolKey], testBool); + }); + + 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()), + emptyOptions, ); - expect(values['prefix.String'], allTestValues['prefix.String']); - expect(values['prefix.Bool'], allTestValues['prefix.Bool']); - expect(values['prefix.Int'], allTestValues['prefix.Int']); - expect(values['prefix.Double'], allTestValues['prefix.Double']); - expect(values['prefix.StringList'], null); - values = await preferences.getAllWithParameters( - GetAllParameters( - filter: PreferencesFilter(prefix: 'flutter.'), + + 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', (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}), ), + emptyOptions, ); - expect(values['flutter.String'], allTestValues['flutter.String']); - expect(values['flutter.Bool'], allTestValues['flutter.Bool']); - expect(values['flutter.Int'], allTestValues['flutter.Int']); - expect(values['flutter.Double'], allTestValues['flutter.Double']); - expect(values['flutter.StringList'], allTestValues['flutter.StringList']); + + expect(keys.length, 2); + expect(keys, contains(stringKey)); + expect(keys, contains(boolKey)); }); - testWidgets('clearWithNoPrefix', (WidgetTester _) async { - await preferences.clearWithParameters( - ClearParameters( - filter: PreferencesFilter(prefix: ''), - ), + 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()), + emptyOptions, ); - final Map values = await preferences.getAllWithParameters( - GetAllParameters( - filter: PreferencesFilter(prefix: ''), + + 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', (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(values['String'], null); - expect(values['Bool'], null); - expect(values['Int'], null); - expect(values['Double'], null); - expect(values['StringList'], null); - expect(values['flutter.String'], null); - expect(values['flutter.Bool'], null); - expect(values['flutter.Int'], null); - expect(values['flutter.Double'], null); - expect(values['flutter.StringList'], null); + 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('simultaneous writes', (WidgetTester _) async { - final List> writes = >[]; - const int writeCount = 100; - for (int i = 1; i <= writeCount; i++) { - writes.add(preferences.setValue('Int', 'Int', i)); - } - final List result = await Future.wait(writes, eagerError: true); - // All writes should succeed. - expect(result.where((bool element) => !element), isEmpty); - // The last write should win. - final Map values = await preferences.getAllWithParameters( - GetAllParameters( - filter: PreferencesFilter(prefix: ''), - ), - ); - expect(values['Int'], writeCount); - }); } diff --git a/packages/shared_preferences/shared_preferences_web/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_web/example/pubspec.yaml index 44672c4e6425..5630c5376aef 100644 --- a/packages/shared_preferences/shared_preferences_web/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_web/example/pubspec.yaml @@ -2,16 +2,16 @@ name: shared_preferences_web_integration_tests publish_to: none environment: - sdk: ">=3.2.0 <4.0.0" - flutter: ">=3.16.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: sdk: flutter - shared_preferences_platform_interface: ^2.3.0 + shared_preferences_platform_interface: ^2.4.0 shared_preferences_web: path: ../ - web: ^0.5.0 + web: ^1.0.0 dev_dependencies: flutter_test: diff --git a/packages/shared_preferences/shared_preferences_web/example/web/index.html b/packages/shared_preferences/shared_preferences_web/example/web/index.html index 7fb138cc90fa..956b11f49f7a 100644 --- a/packages/shared_preferences/shared_preferences_web/example/web/index.html +++ b/packages/shared_preferences/shared_preferences_web/example/web/index.html @@ -8,6 +8,6 @@ example - + diff --git a/packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart b/packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart index b83c1a5fe37e..97160b5d150e 100644 --- a/packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart +++ b/packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart @@ -6,6 +6,7 @@ import 'dart:async'; import 'dart:convert' show json; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; import 'package:shared_preferences_platform_interface/types.dart'; import 'package:web/web.dart' as html; @@ -19,6 +20,7 @@ class SharedPreferencesPlugin extends SharedPreferencesStorePlatform { /// Registers this class as the default instance of [SharedPreferencesStorePlatform]. static void registerWith(Registrar? registrar) { SharedPreferencesStorePlatform.instance = SharedPreferencesPlugin(); + SharedPreferencesAsyncWeb.registerWith(registrar); } static const String _defaultPrefix = 'flutter.'; @@ -44,7 +46,7 @@ class SharedPreferencesPlugin extends SharedPreferencesStorePlatform { // IMPORTANT: Do not use html.window.localStorage.clear() as that will // remove _all_ local data, not just the keys prefixed with // _prefix - _getFilteredKeys(filter.prefix, allowList: filter.allowList) + _getPrefixedKeys(filter.prefix, allowList: filter.allowList) .forEach(remove); return true; } @@ -70,7 +72,7 @@ class SharedPreferencesPlugin extends SharedPreferencesStorePlatform { final PreferencesFilter filter = parameters.filter; final Map allData = {}; for (final String key - in _getFilteredKeys(filter.prefix, allowList: filter.allowList)) { + in _getPrefixedKeys(filter.prefix, allowList: filter.allowList)) { allData[key] = _decodeValue(html.window.localStorage.getItem(key)!); } return allData; @@ -88,28 +90,189 @@ class SharedPreferencesPlugin extends SharedPreferencesStorePlatform { return true; } - Iterable _getFilteredKeys( + Iterable _getPrefixedKeys( String prefix, { Set? allowList, }) { - return html.window.localStorage.keys.where((String key) => - key.startsWith(prefix) && (allowList?.contains(key) ?? true)); + return _getAllowedKeys(allowList: allowList) + .where((String key) => key.startsWith(prefix)); } +} - String _encodeValue(Object? value) { - return json.encode(value); +/// The web implementation of [SharedPreferencesAsyncPlatform]. +/// +/// This class implements the `package:shared_preferences` functionality for the web. +base class SharedPreferencesAsyncWeb extends SharedPreferencesAsyncPlatform { + /// Registers this class as the default instance of [SharedPreferencesAsyncPlatform]. + static void registerWith(Registrar? registrar) { + SharedPreferencesAsyncPlatform.instance = SharedPreferencesAsyncWeb(); } - Object _decodeValue(String encodedValue) { - final Object? decodedValue = json.decode(encodedValue); + @override + Future clear( + ClearPreferencesParameters parameters, + SharedPreferencesOptions options, + ) async { + final PreferencesFilters filter = parameters.filter; + _getAllowedKeys(allowList: filter.allowList) + .forEach((String key) => html.window.localStorage.removeItem(key)); + } - if (decodedValue is List) { - // JSON does not preserve generics. The encode/decode roundtrip is - // `List` => JSON => `List`. We have to explicitly - // restore the RTTI. - return decodedValue.cast(); + @override + Future> getPreferences( + GetPreferencesParameters parameters, + SharedPreferencesOptions options, + ) async { + return _readAllFromLocalStorage(parameters.filter.allowList, options); + } + + Future> _readAllFromLocalStorage( + Set? allowList, + SharedPreferencesOptions options, + ) async { + final Map allData = {}; + for (final String key in _getAllowedKeys(allowList: allowList)) { + allData[key] = _decodeValue(html.window.localStorage.getItem(key)!); } + return allData; + } + + @override + Future> getKeys(GetPreferencesParameters parameters, + SharedPreferencesOptions options) async { + return (await getPreferences(parameters, options)).keys.toSet(); + } + + @override + Future setString( + String key, + String value, + SharedPreferencesOptions options, + ) { + return _setValue(key, value, options); + } + + @override + Future setBool( + String key, + bool value, + SharedPreferencesOptions options, + ) { + return _setValue(key, value, options); + } - return decodedValue!; + @override + Future setDouble( + String key, + double value, + SharedPreferencesOptions options, + ) { + return _setValue(key, value, options); + } + + @override + Future setInt( + String key, + int value, + SharedPreferencesOptions options, + ) { + return _setValue(key, value, options); + } + + @override + Future setStringList( + String key, + List value, + SharedPreferencesOptions options, + ) { + return _setValue(key, value, options); } + + Future _setValue( + String key, + Object? value, + SharedPreferencesOptions options, + ) async { + html.window.localStorage.setItem(key, _encodeValue(value)); + } + + @override + Future getString( + String key, + SharedPreferencesOptions options, + ) async { + final Map data = + await _readAllFromLocalStorage({key}, options); + return data[key] as String?; + } + + @override + Future getBool( + String key, + SharedPreferencesOptions options, + ) async { + final Map data = + await _readAllFromLocalStorage({key}, options); + return data[key] as bool?; + } + + @override + Future getDouble( + String key, + SharedPreferencesOptions options, + ) async { + final Map data = + await _readAllFromLocalStorage({key}, options); + return data[key] as double?; + } + + @override + Future getInt( + String key, + SharedPreferencesOptions options, + ) async { + final Map data = + await _readAllFromLocalStorage({key}, options); + return data[key] as int?; + } + + @override + Future?> getStringList( + String key, + SharedPreferencesOptions options, + ) async { + final Map data = + await _readAllFromLocalStorage({key}, options); + return (data[key] as List?)?.toList(); + } +} + +Iterable _getAllowedKeys({ + Set? allowList, +}) { + return html.window.localStorage.keys + .where((String key) => allowList?.contains(key) ?? true); +} + +String _encodeValue(Object? value) { + return json.encode(value); +} + +Object _decodeValue(String encodedValue) { + final Object? decodedValue = json.decode(encodedValue); + + if (decodedValue is List) { + // JSON does not preserve generics. The encode/decode roundtrip is + // `List` => JSON => `List`. We have to explicitly + // restore the RTTI. + return decodedValue.cast(); + } + + return decodedValue!; +} + +/// Web specific SharedPreferences Options. +class SharedPreferencesWebOptions extends SharedPreferencesOptions { + /// Constructor for SharedPreferencesWebOptions. + const SharedPreferencesWebOptions(); } diff --git a/packages/shared_preferences/shared_preferences_web/pubspec.yaml b/packages/shared_preferences/shared_preferences_web/pubspec.yaml index 1278a54a3e51..a8592342dc23 100644 --- a/packages/shared_preferences/shared_preferences_web/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_web/pubspec.yaml @@ -2,11 +2,11 @@ name: shared_preferences_web description: Web platform implementation of shared_preferences repository: https://github.com/flutter/packages/tree/main/packages/shared_preferences/shared_preferences_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22 -version: 2.3.0 +version: 2.4.2 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: @@ -21,8 +21,8 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - shared_preferences_platform_interface: ^2.3.0 - web: ^0.5.0 + shared_preferences_platform_interface: ^2.4.0 + web: ">=0.5.1 <2.0.0" dev_dependencies: flutter_test: diff --git a/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md b/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md index 8137dbb765d6..d2cf5d62ace9 100644 --- a/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md @@ -1,5 +1,12 @@ -## NEXT +## 2.4.1 +* Fixes `getStringList` returning immutable list. +* Fixes `getStringList` cast error. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + +## 2.4.0 + +* Adds `SharedPreferencesAsyncWindows` API. * Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. ## 2.3.2 diff --git a/packages/shared_preferences/shared_preferences_windows/README.md b/packages/shared_preferences/shared_preferences_windows/README.md index de146eb12953..c1ac6a1ffe39 100644 --- a/packages/shared_preferences/shared_preferences_windows/README.md +++ b/packages/shared_preferences/shared_preferences_windows/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/shared_preferences -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/shared_preferences/shared_preferences_windows/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_windows/example/integration_test/shared_preferences_test.dart index bd30ddeab4a2..79192ad28ebc 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences_windows/example/integration_test/shared_preferences_test.dart @@ -4,6 +4,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; import 'package:shared_preferences_platform_interface/types.dart'; import 'package:shared_preferences_windows/shared_preferences_windows.dart'; @@ -336,4 +337,209 @@ void main() { }); }); }); + + group('shared_preferences_async', () { + const SharedPreferencesWindowsOptions emptyOptions = + SharedPreferencesWindowsOptions(); + + 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( + {bool clear = true}) async { + final SharedPreferencesAsyncPlatform preferences = + SharedPreferencesAsyncPlatform.instance!; + if (clear) { + 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); + }); + + testWidgets('set and get bool', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + await preferences.setBool(boolKey, testBool, emptyOptions); + expect(await preferences.getBool(boolKey, emptyOptions), testBool); + }); + + testWidgets('set and get int', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + await preferences.setInt(intKey, testInt, emptyOptions); + expect(await preferences.getInt(intKey, emptyOptions), testInt); + }); + + testWidgets('set and get double', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + expect(await preferences.getDouble(doubleKey, emptyOptions), testDouble); + }); + + testWidgets('set and get StringList', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + await preferences.setStringList(listKey, testList, emptyOptions); + expect(await preferences.getStringList(listKey, emptyOptions), testList); + }); + + testWidgets('getStringList does not throw cast error', + (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + await preferences.setStringList(listKey, testList, emptyOptions); + await (preferences as SharedPreferencesAsyncWindows).reload(emptyOptions); + expect(await preferences.getStringList(listKey, emptyOptions), testList); + }); + + testWidgets('getStringList returns mutable list', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + + 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', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + await preferences.setString(stringKey, testString, emptyOptions); + await preferences.setBool(boolKey, testBool, emptyOptions); + await preferences.setInt(intKey, testInt, emptyOptions); + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + await 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); + }); + + testWidgets('getPreferences with filter', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + await preferences.setString(stringKey, testString, emptyOptions); + await preferences.setBool(boolKey, testBool, emptyOptions); + await preferences.setInt(intKey, testInt, emptyOptions); + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + await 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); + }); + + testWidgets('getKeys', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + await preferences.setString(stringKey, testString, emptyOptions); + await preferences.setBool(boolKey, testBool, emptyOptions); + await preferences.setInt(intKey, testInt, emptyOptions); + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + await 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)); + }); + + testWidgets('getKeys with filter', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + await preferences.setString(stringKey, testString, emptyOptions); + await preferences.setBool(boolKey, testBool, emptyOptions); + await preferences.setInt(intKey, testInt, emptyOptions); + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + await preferences.setStringList(listKey, testList, emptyOptions); + + 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)); + }); + + testWidgets('clear', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + await preferences.setString(stringKey, testString, emptyOptions); + await preferences.setBool(boolKey, testBool, emptyOptions); + await preferences.setInt(intKey, testInt, emptyOptions); + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + await 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); + }); + + testWidgets('clear with filter', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + await preferences.setString(stringKey, testString, emptyOptions); + await preferences.setBool(boolKey, testBool, emptyOptions); + await preferences.setInt(intKey, testInt, emptyOptions); + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + await 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); + }); + }); } diff --git a/packages/shared_preferences/shared_preferences_windows/example/lib/main.dart b/packages/shared_preferences/shared_preferences_windows/example/lib/main.dart index 3c5312aab602..fc07e68eb86e 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/lib/main.dart +++ b/packages/shared_preferences/shared_preferences_windows/example/lib/main.dart @@ -4,9 +4,8 @@ // ignore_for_file: public_member_api_docs -import 'dart:async'; - import 'package:flutter/material.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; import 'package:shared_preferences_windows/shared_preferences_windows.dart'; void main() { @@ -33,26 +32,36 @@ class SharedPreferencesDemo extends StatefulWidget { } class SharedPreferencesDemoState extends State { - final SharedPreferencesWindows prefs = SharedPreferencesWindows(); + final SharedPreferencesAsyncPlatform? _prefs = + SharedPreferencesAsyncPlatform.instance; + final SharedPreferencesWindowsOptions options = + const SharedPreferencesWindowsOptions(); + static const String _counterKey = 'counter'; late Future _counter; Future _incrementCounter() async { - final Map values = await prefs.getAll(); - final int counter = (values['counter'] as int? ?? 0) + 1; + final int? value = await _prefs!.getInt(_counterKey, options); + final int counter = (value ?? 0) + 1; setState(() { - _counter = prefs.setValue('Int', 'counter', counter).then((bool success) { + _counter = _prefs.setInt(_counterKey, counter, options).then((_) { return counter; }); }); } + Future _getAndSetCounter() async { + setState(() { + _counter = _prefs!.getInt(_counterKey, options).then((int? counter) { + return counter ?? 0; + }); + }); + } + @override void initState() { super.initState(); - _counter = prefs.getAll().then((Map values) { - return values['counter'] as int? ?? 0; - }); + _getAndSetCounter(); } @override diff --git a/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml index 8331a914fbf4..dbbf7c7530ef 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml @@ -3,13 +3,13 @@ description: Demonstrates how to use the shared_preferences_windows plugin. publish_to: none environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: sdk: flutter - shared_preferences_platform_interface: ^2.3.0 + shared_preferences_platform_interface: ^2.4.0 shared_preferences_windows: # When depending on this package from a real application you should use: # shared_preferences_windows: ^x.y.z diff --git a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart index 097e0a6c63c8..5d72b9823b1a 100644 --- a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart +++ b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart @@ -10,9 +10,14 @@ import 'package:file/local.dart'; import 'package:flutter/foundation.dart' show debugPrint, visibleForTesting; import 'package:path/path.dart' as path; import 'package:path_provider_windows/path_provider_windows.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; import 'package:shared_preferences_platform_interface/types.dart'; +const String _defaultFileName = 'shared_preferences'; + +const String _defaultPrefix = 'flutter.'; + /// The Windows implementation of [SharedPreferencesStorePlatform]. /// /// This class implements the `package:shared_preferences` functionality for Windows. @@ -25,9 +30,12 @@ class SharedPreferencesWindows extends SharedPreferencesStorePlatform { /// Registers the Windows implementation. static void registerWith() { SharedPreferencesStorePlatform.instance = SharedPreferencesWindows(); + // A temporary work-around for having two plugins contained in a single package. + SharedPreferencesAsyncWindows.registerWith(); } - static const String _defaultPrefix = 'flutter.'; + /// Local copy of preferences + Map? _cachedPreferences; /// File system used to store to disk. Exposed for testing only. @visibleForTesting @@ -37,66 +45,15 @@ class SharedPreferencesWindows extends SharedPreferencesStorePlatform { @visibleForTesting PathProviderWindows pathProvider = PathProviderWindows(); - /// Local copy of preferences - Map? _cachedPreferences; - - /// Cached file for storing preferences. - File? _localDataFilePath; - - /// Gets the file where the preferences are stored. - Future _getLocalDataFile() async { - if (_localDataFilePath != null) { - return _localDataFilePath!; - } - final String? directory = await pathProvider.getApplicationSupportPath(); - if (directory == null) { - return null; - } - return _localDataFilePath = - fs.file(path.join(directory, 'shared_preferences.json')); - } - - /// Gets the preferences from the stored file. Once read, the preferences are - /// maintained in memory. - Future> _reload() async { - Map preferences = {}; - final File? localDataFile = await _getLocalDataFile(); - if (localDataFile != null && localDataFile.existsSync()) { - final String stringMap = localDataFile.readAsStringSync(); - if (stringMap.isNotEmpty) { - final Object? data = json.decode(stringMap); - if (data is Map) { - preferences = data.cast(); - } - } - } - _cachedPreferences = preferences; - return preferences; - } - + /// Checks for cached preferences and returns them or loads preferences from + /// file and returns and caches them. Future> _readPreferences() async { - return _cachedPreferences ?? await _reload(); - } - - /// Writes the cached preferences to disk. Returns [true] if the operation - /// succeeded. - Future _writePreferences(Map preferences) async { - try { - final File? localDataFile = await _getLocalDataFile(); - if (localDataFile == null) { - debugPrint('Unable to determine where to write preferences.'); - return false; - } - if (!localDataFile.existsSync()) { - localDataFile.createSync(recursive: true); - } - final String stringMap = json.encode(preferences); - localDataFile.writeAsStringSync(stringMap); - } catch (e) { - debugPrint('Error saving preferences to disk: $e'); - return false; - } - return true; + _cachedPreferences ??= await _readFromFile( + _defaultFileName, + fs: fs, + pathProvider: pathProvider, + ); + return _cachedPreferences!; } @override @@ -117,11 +74,17 @@ class SharedPreferencesWindows extends SharedPreferencesStorePlatform { @override Future clearWithParameters(ClearParameters parameters) async { final PreferencesFilter filter = parameters.filter; + final Map preferences = await _readPreferences(); preferences.removeWhere((String key, _) => key.startsWith(filter.prefix) && (filter.allowList == null || filter.allowList!.contains(key))); - return _writePreferences(preferences); + return _writePreferences( + preferences, + _defaultFileName, + fs: fs, + pathProvider: pathProvider, + ); } @override @@ -154,13 +117,305 @@ class SharedPreferencesWindows extends SharedPreferencesStorePlatform { Future remove(String key) async { final Map preferences = await _readPreferences(); preferences.remove(key); - return _writePreferences(preferences); + return _writePreferences( + preferences, + _defaultFileName, + fs: fs, + pathProvider: pathProvider, + ); } @override Future setValue(String valueType, String key, Object value) async { final Map preferences = await _readPreferences(); preferences[key] = value; - return _writePreferences(preferences); + return _writePreferences( + preferences, + _defaultFileName, + fs: fs, + pathProvider: pathProvider, + ); + } +} + +/// The Windows implementation of [SharedPreferencesAsyncPlatform]. +/// +/// This class implements the `package:shared_preferences` functionality for Windows. +base class SharedPreferencesAsyncWindows + extends SharedPreferencesAsyncPlatform { + /// Registers the Windows implementation. + static void registerWith() { + SharedPreferencesAsyncPlatform.instance = SharedPreferencesAsyncWindows(); + } + + /// Local copy of preferences + Map? _cachedPreferences; + + /// File system used to store to disk. Exposed for testing only. + @visibleForTesting + FileSystem fs = const LocalFileSystem(); + + /// The path_provider_windows instance used to find the support directory. + @visibleForTesting + PathProviderWindows pathProvider = PathProviderWindows(); + + @override + Future> getKeys( + GetPreferencesParameters parameters, + SharedPreferencesOptions options, + ) async { + return (await getPreferences(parameters, options)).keys.toSet(); + } + + @override + Future setString( + String key, + String value, + SharedPreferencesOptions options, + ) { + return _setValue(key, value, options); + } + + @override + Future setBool( + String key, + bool value, + SharedPreferencesOptions options, + ) { + return _setValue(key, value, options); + } + + @override + Future setDouble( + String key, + double value, + SharedPreferencesOptions options, + ) { + return _setValue(key, value, options); + } + + @override + Future setInt( + String key, + int value, + SharedPreferencesOptions options, + ) { + return _setValue(key, value, options); + } + + @override + Future setStringList( + String key, + List value, + SharedPreferencesOptions options, + ) { + return _setValue(key, value, options); + } + + @override + Future getString( + String key, + SharedPreferencesOptions options, + ) async { + final Map data = await _readAll({key}, options); + return data[key] as String?; + } + + @override + Future getBool( + String key, + SharedPreferencesOptions options, + ) async { + final Map data = await _readAll({key}, options); + return data[key] as bool?; + } + + @override + Future getDouble( + String key, + SharedPreferencesOptions options, + ) async { + final Map data = await _readAll({key}, options); + return data[key] as double?; + } + + @override + Future getInt( + String key, + SharedPreferencesOptions options, + ) async { + final Map data = await _readAll({key}, options); + return data[key] as int?; + } + + @override + Future?> getStringList( + String key, + SharedPreferencesOptions options, + ) async { + final Map data = await _readAll({key}, options); + return (data[key] as List?)?.cast().toList(); + } + + @override + Future clear(ClearPreferencesParameters parameters, + SharedPreferencesOptions options) async { + final SharedPreferencesWindowsOptions windowsOptions = + SharedPreferencesWindowsOptions.fromSharedPreferencesOptions(options); + final PreferencesFilters filter = parameters.filter; + final Map preferences = + await _readPreferences(windowsOptions.fileName); + preferences.removeWhere((String key, _) => + filter.allowList == null || filter.allowList!.contains(key)); + await _writePreferences( + preferences, + windowsOptions.fileName, + fs: fs, + pathProvider: pathProvider, + ); + } + + @override + Future> getPreferences( + GetPreferencesParameters parameters, + SharedPreferencesOptions options, + ) async { + return _readAll(parameters.filter.allowList, options); + } + + /// Reloads preferences from file. + @visibleForTesting + Future reload( + SharedPreferencesWindowsOptions options, + ) async { + _cachedPreferences = await _readFromFile(options.fileName); + } + + Future> _readAll( + Set? allowList, + SharedPreferencesOptions options, + ) async { + final SharedPreferencesWindowsOptions windowsOptions = + SharedPreferencesWindowsOptions.fromSharedPreferencesOptions(options); + final Map prefs = Map.from( + await _readPreferences(windowsOptions.fileName)); + prefs.removeWhere((String key, _) => !(allowList?.contains(key) ?? true)); + return prefs; + } + + Future _setValue( + String key, Object value, SharedPreferencesOptions options) async { + final SharedPreferencesWindowsOptions windowsOptions = + SharedPreferencesWindowsOptions.fromSharedPreferencesOptions(options); + final Map preferences = + await _readPreferences(windowsOptions.fileName); + preferences[key] = value; + await _writePreferences( + preferences, + windowsOptions.fileName, + fs: fs, + pathProvider: pathProvider, + ); + } + + /// Checks for cached preferences and returns them or loads preferences from + /// file and returns and caches them. + Future> _readPreferences(String fileName) async { + _cachedPreferences ??= await _readFromFile( + fileName, + fs: fs, + pathProvider: pathProvider, + ); + return _cachedPreferences!; + } +} + +/// Gets the file where the preferences are stored. +Future _getLocalDataFile( + String fileName, { + FileSystem fs = const LocalFileSystem(), + PathProviderWindows? pathProvider, +}) async { + pathProvider = pathProvider ?? PathProviderWindows(); + final String? directory = await pathProvider.getApplicationSupportPath(); + if (directory == null) { + return null; + } + final String fileLocation = path.join(directory, '$fileName.json'); + return fs.file(fileLocation); +} + +/// Gets the preferences from the stored file. +Future> _readFromFile( + String fileName, { + FileSystem fs = const LocalFileSystem(), + PathProviderWindows? pathProvider, +}) async { + Map preferences = {}; + final File? localDataFile = await _getLocalDataFile( + fileName, + fs: fs, + pathProvider: pathProvider, + ); + if (localDataFile != null && localDataFile.existsSync()) { + final String stringMap = localDataFile.readAsStringSync(); + if (stringMap.isNotEmpty) { + final Object? data = json.decode(stringMap); + if (data is Map) { + preferences = data.cast(); + } + } + } + return preferences; +} + +/// Writes the cached preferences to disk. Returns [true] if the operation +/// succeeded. +Future _writePreferences( + Map preferences, + String fileName, { + FileSystem fs = const LocalFileSystem(), + PathProviderWindows? pathProvider, +}) async { + try { + final File? localDataFile = await _getLocalDataFile( + fileName, + fs: fs, + pathProvider: pathProvider, + ); + if (localDataFile == null) { + debugPrint('Unable to determine where to write preferences.'); + return false; + } + if (!localDataFile.existsSync()) { + localDataFile.createSync(recursive: true); + } + final String stringMap = json.encode(preferences); + localDataFile.writeAsStringSync(stringMap); + } catch (e) { + debugPrint('Error saving preferences to disk: $e'); + return false; + } + return true; +} + +/// Windows specific SharedPreferences Options. +class SharedPreferencesWindowsOptions extends SharedPreferencesOptions { + /// Constructor for SharedPreferencesWindowsOptions. + const SharedPreferencesWindowsOptions({ + this.fileName = 'shared_preferences', // Same as current defaults. + }); + + /// The name of the file to store preferences in. + final String fileName; + + /// Returns a new instance of [SharedPreferencesWindowsOptions] from an existing + /// [SharedPreferencesOptions]. + static SharedPreferencesWindowsOptions fromSharedPreferencesOptions( + SharedPreferencesOptions options) { + if (options is SharedPreferencesWindowsOptions) { + return options; + } + return const SharedPreferencesWindowsOptions(); } } diff --git a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml index b8481f598309..59c3274488b4 100644 --- a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml @@ -2,11 +2,11 @@ name: shared_preferences_windows description: Windows implementation of shared_preferences repository: https://github.com/flutter/packages/tree/main/packages/shared_preferences/shared_preferences_windows issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22 -version: 2.3.2 +version: 2.4.1 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -22,7 +22,7 @@ dependencies: path: ^1.8.0 path_provider_platform_interface: ^2.0.0 path_provider_windows: ^2.0.0 - shared_preferences_platform_interface: ^2.3.0 + shared_preferences_platform_interface: ^2.4.0 dev_dependencies: flutter_test: diff --git a/packages/shared_preferences/shared_preferences_windows/test/fake_path_provider_windows.dart b/packages/shared_preferences/shared_preferences_windows/test/fake_path_provider_windows.dart new file mode 100644 index 000000000000..8b7b374118e9 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/test/fake_path_provider_windows.dart @@ -0,0 +1,36 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; +import 'package:path_provider_windows/path_provider_windows.dart'; + +/// Fake implementation of PathProviderWindows that returns hard-coded paths, +/// allowing tests to run on any platform. +/// +/// Note that this should only be used with an in-memory filesystem, as the +/// path it returns is a root path that does not actually exist on Windows. +class FakePathProviderWindows extends PathProviderPlatform + implements PathProviderWindows { + @override + late VersionInfoQuerier versionInfoQuerier; + + @override + Future getApplicationSupportPath() async => r'C:\appsupport'; + + @override + Future getTemporaryPath() async => null; + + @override + Future getLibraryPath() async => null; + + @override + Future getApplicationDocumentsPath() async => null; + + @override + Future getDownloadsPath() async => null; + + @override + Future getPath(String folderID) async => ''; +} diff --git a/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart b/packages/shared_preferences/shared_preferences_windows/test/legacy_shared_preferences_windows_test.dart similarity index 89% rename from packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart rename to packages/shared_preferences/shared_preferences_windows/test/legacy_shared_preferences_windows_test.dart index 499a74eeca3b..6a8de0aaf4e2 100644 --- a/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart +++ b/packages/shared_preferences/shared_preferences_windows/test/legacy_shared_preferences_windows_test.dart @@ -7,12 +7,13 @@ import 'dart:convert'; import 'package:file/memory.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:path/path.dart' as path; -import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; import 'package:path_provider_windows/path_provider_windows.dart'; import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; import 'package:shared_preferences_platform_interface/types.dart'; import 'package:shared_preferences_windows/shared_preferences_windows.dart'; +import 'fake_path_provider_windows.dart'; + void main() { late MemoryFileSystem fs; late PathProviderWindows pathProvider; @@ -76,7 +77,7 @@ void main() { return prefs; } - test('registered instance', () { + test('registered instance', () async { SharedPreferencesWindows.registerWith(); expect(SharedPreferencesStorePlatform.instance, isA()); @@ -255,32 +256,3 @@ void main() { expect(noValues, hasLength(0)); }); } - -/// Fake implementation of PathProviderWindows that returns hard-coded paths, -/// allowing tests to run on any platform. -/// -/// Note that this should only be used with an in-memory filesystem, as the -/// path it returns is a root path that does not actually exist on Windows. -class FakePathProviderWindows extends PathProviderPlatform - implements PathProviderWindows { - @override - late VersionInfoQuerier versionInfoQuerier; - - @override - Future getApplicationSupportPath() async => r'C:\appsupport'; - - @override - Future getTemporaryPath() async => null; - - @override - Future getLibraryPath() async => null; - - @override - Future getApplicationDocumentsPath() async => null; - - @override - Future getDownloadsPath() async => null; - - @override - Future getPath(String folderID) async => ''; -} diff --git a/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_async_test.dart b/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_async_test.dart new file mode 100755 index 000000000000..6846f1fa995d --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_async_test.dart @@ -0,0 +1,197 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:file/memory.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:path_provider_windows/path_provider_windows.dart'; +import 'package:shared_preferences_platform_interface/types.dart'; +import 'package:shared_preferences_windows/shared_preferences_windows.dart'; + +import 'fake_path_provider_windows.dart'; + +void main() { + late MemoryFileSystem fs; + late PathProviderWindows pathProvider; + + SharedPreferencesAsyncWindows.registerWith(); + + 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']; + + const SharedPreferencesWindowsOptions emptyOptions = + SharedPreferencesWindowsOptions(); + + setUp(() { + fs = MemoryFileSystem.test(); + pathProvider = FakePathProviderWindows(); + }); + + SharedPreferencesAsyncWindows getPreferences() { + final SharedPreferencesAsyncWindows prefs = SharedPreferencesAsyncWindows(); + prefs.fs = fs; + prefs.pathProvider = pathProvider; + return prefs; + } + + test('set and get String', () async { + final SharedPreferencesAsyncWindows preferences = getPreferences(); + + await preferences.setString(stringKey, testString, emptyOptions); + expect(await preferences.getString(stringKey, emptyOptions), testString); + }); + + test('set and get bool', () async { + final SharedPreferencesAsyncWindows preferences = getPreferences(); + + await preferences.setBool(boolKey, testBool, emptyOptions); + expect(await preferences.getBool(boolKey, emptyOptions), testBool); + }); + + test('set and get int', () async { + final SharedPreferencesAsyncWindows preferences = getPreferences(); + + await preferences.setInt(intKey, testInt, emptyOptions); + expect(await preferences.getInt(intKey, emptyOptions), testInt); + }); + + test('set and get double', () async { + final SharedPreferencesAsyncWindows preferences = getPreferences(); + + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + expect(await preferences.getDouble(doubleKey, emptyOptions), testDouble); + }); + + test('set and get StringList', () async { + final SharedPreferencesAsyncWindows preferences = getPreferences(); + + await preferences.setStringList(listKey, testList, emptyOptions); + expect(await preferences.getStringList(listKey, emptyOptions), testList); + }); + + test('getPreferences', () async { + final SharedPreferencesAsyncWindows preferences = getPreferences(); + await preferences.setString(stringKey, testString, emptyOptions); + await preferences.setBool(boolKey, testBool, emptyOptions); + await preferences.setInt(intKey, testInt, emptyOptions); + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + await 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', () async { + final SharedPreferencesAsyncWindows preferences = getPreferences(); + await preferences.setString(stringKey, testString, emptyOptions); + await preferences.setBool(boolKey, testBool, emptyOptions); + await preferences.setInt(intKey, testInt, emptyOptions); + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + await 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', () async { + final SharedPreferencesAsyncWindows preferences = getPreferences(); + await preferences.setString(stringKey, testString, emptyOptions); + await preferences.setBool(boolKey, testBool, emptyOptions); + await preferences.setInt(intKey, testInt, emptyOptions); + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + await 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 SharedPreferencesAsyncWindows preferences = getPreferences(); + await preferences.setString(stringKey, testString, emptyOptions); + await preferences.setBool(boolKey, testBool, emptyOptions); + await preferences.setInt(intKey, testInt, emptyOptions); + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + await preferences.setStringList(listKey, testList, emptyOptions); + + 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)); + }); + + test('clear', () async { + final SharedPreferencesAsyncWindows preferences = getPreferences(); + await preferences.setString(stringKey, testString, emptyOptions); + await preferences.setBool(boolKey, testBool, emptyOptions); + await preferences.setInt(intKey, testInt, emptyOptions); + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + await 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 SharedPreferencesAsyncWindows preferences = getPreferences(); + await preferences.setString(stringKey, testString, emptyOptions); + await preferences.setBool(boolKey, testBool, emptyOptions); + await preferences.setInt(intKey, testInt, emptyOptions); + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + await 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); + }); +} diff --git a/packages/standard_message_codec/CHANGELOG.md b/packages/standard_message_codec/CHANGELOG.md index a8b04ef3decb..9da834b04cba 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.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 0.0.1+4 diff --git a/packages/standard_message_codec/example/pubspec.yaml b/packages/standard_message_codec/example/pubspec.yaml index 41b8de76f7bf..40b4f7fc7f04 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.2.0 + sdk: ^3.3.0 dependencies: standard_message_codec: diff --git a/packages/standard_message_codec/pubspec.yaml b/packages/standard_message_codec/pubspec.yaml index 10e1df4c7c3a..f27690918b32 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.2.0 + sdk: ^3.3.0 dev_dependencies: test: ^1.16.0 diff --git a/packages/two_dimensional_scrollables/CHANGELOG.md b/packages/two_dimensional_scrollables/CHANGELOG.md index 0bcac837523c..31ecdfdcdb66 100644 --- a/packages/two_dimensional_scrollables/CHANGELOG.md +++ b/packages/two_dimensional_scrollables/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.3.3 + +* Fixes an issue where collapsing nodes in the TreeView didn't work correctly. + +## 0.3.2 + +* Fixes a bug where the TreeView would not update correctly when the animation duration is zero. + ## 0.3.1 * Adds generics to the callbacks and builders of TreeView. diff --git a/packages/two_dimensional_scrollables/example/android/.gitignore b/packages/two_dimensional_scrollables/example/android/.gitignore index 6f568019d3c6..55afd919c659 100644 --- a/packages/two_dimensional_scrollables/example/android/.gitignore +++ b/packages/two_dimensional_scrollables/example/android/.gitignore @@ -7,7 +7,7 @@ gradle-wrapper.jar GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. -# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +# See https://flutter.dev/to/reference-keystore key.properties **/*.keystore **/*.jks diff --git a/packages/two_dimensional_scrollables/example/android/app/build.gradle b/packages/two_dimensional_scrollables/example/android/app/build.gradle index 6648ebb4f24c..f186a680484c 100644 --- a/packages/two_dimensional_scrollables/example/android/app/build.gradle +++ b/packages/two_dimensional_scrollables/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,22 +22,18 @@ 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.packages.two_dimensional_scrollables.example' compileSdk flutter.compileSdkVersion ndkVersion flutter.ndkVersion compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '11' } sourceSets { @@ -67,7 +64,3 @@ android { flutter { source '../..' } - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" -} diff --git a/packages/two_dimensional_scrollables/example/android/build.gradle b/packages/two_dimensional_scrollables/example/android/build.gradle index d13ef556e261..b9db5700753a 100644 --- a/packages/two_dimensional_scrollables/example/android/build.gradle +++ b/packages/two_dimensional_scrollables/example/android/build.gradle @@ -1,16 +1,3 @@ -buildscript { - ext.kotlin_version = '1.7.10' - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' - 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/two_dimensional_scrollables/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/two_dimensional_scrollables/example/android/gradle/wrapper/gradle-wrapper.properties index e1ca574ef017..3c85cfe057a1 100644 --- a/packages/two_dimensional_scrollables/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/two_dimensional_scrollables/example/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/two_dimensional_scrollables/example/android/settings.gradle b/packages/two_dimensional_scrollables/example/android/settings.gradle index 1cb1f7a2391f..0667903d5724 100644 --- a/packages/two_dimensional_scrollables/example/android/settings.gradle +++ b/packages/two_dimensional_scrollables/example/android/settings.gradle @@ -1,24 +1,27 @@ -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.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" +} + +include ":app" diff --git a/packages/two_dimensional_scrollables/example/pubspec.yaml b/packages/two_dimensional_scrollables/example/pubspec.yaml index 864ffc566cff..c7786ae10c6f 100644 --- a/packages/two_dimensional_scrollables/example/pubspec.yaml +++ b/packages/two_dimensional_scrollables/example/pubspec.yaml @@ -16,7 +16,6 @@ dependencies: path: ../ dev_dependencies: - flutter_lints: ^2.0.0 flutter_test: sdk: flutter diff --git a/packages/two_dimensional_scrollables/example/web/index.html b/packages/two_dimensional_scrollables/example/web/index.html index 3574a82d337e..3ce79d627fea 100644 --- a/packages/two_dimensional_scrollables/example/web/index.html +++ b/packages/two_dimensional_scrollables/example/web/index.html @@ -34,29 +34,8 @@ example - - - - - + diff --git a/packages/two_dimensional_scrollables/lib/src/tree_view/tree.dart b/packages/two_dimensional_scrollables/lib/src/tree_view/tree.dart index ba6c4632c408..f9fc6c82e7eb 100644 --- a/packages/two_dimensional_scrollables/lib/src/tree_view/tree.dart +++ b/packages/two_dimensional_scrollables/lib/src/tree_view/tree.dart @@ -886,6 +886,15 @@ class _TreeViewState extends State> if (widget.onNodeToggle != null) { widget.onNodeToggle!(node); } + + // If animation is disabled or duration is zero, skip the animation + // and update the active nodes immediately. This ensures the tree + // is updated correctly when the node's children are no longer active. + if (widget.toggleAnimationStyle?.duration == Duration.zero) { + _unpackActiveNodes(); + return; + } + final AnimationController controller = _currentAnimationForParent[node]?.controller ?? AnimationController( @@ -902,6 +911,12 @@ class _TreeViewState extends State> _currentAnimationForParent[node]!.controller.dispose(); _currentAnimationForParent.remove(node); _updateActiveAnimations(); + // If the node is collapsing, we need to unpack the active + // nodes to remove the ones that were removed from the tree. + // This is only necessary if the node is collapsing. + if (!node._expanded) { + _unpackActiveNodes(); + } case AnimationStatus.forward: case AnimationStatus.reverse: } @@ -940,9 +955,7 @@ class _TreeViewState extends State> controller.forward(); case false: // Collapsing - controller.reverse().then((_) { - _unpackActiveNodes(); - }); + controller.reverse(); } }); } diff --git a/packages/two_dimensional_scrollables/pubspec.yaml b/packages/two_dimensional_scrollables/pubspec.yaml index 45845c7afe09..3cd575a8c76a 100644 --- a/packages/two_dimensional_scrollables/pubspec.yaml +++ b/packages/two_dimensional_scrollables/pubspec.yaml @@ -1,6 +1,6 @@ name: two_dimensional_scrollables description: Widgets that scroll using the two dimensional scrolling foundation. -version: 0.3.1 +version: 0.3.3 repository: https://github.com/flutter/packages/tree/main/packages/two_dimensional_scrollables issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+two_dimensional_scrollables%22+ @@ -13,7 +13,6 @@ dependencies: sdk: flutter dev_dependencies: - flutter_lints: ^2.0.0 flutter_test: sdk: flutter diff --git a/packages/two_dimensional_scrollables/test/tree_view/tree_test.dart b/packages/two_dimensional_scrollables/test/tree_view/tree_test.dart index a1790879fe9a..5e536402b85a 100644 --- a/packages/two_dimensional_scrollables/test/tree_view/tree_test.dart +++ b/packages/two_dimensional_scrollables/test/tree_view/tree_test.dart @@ -718,6 +718,170 @@ void main() { expect(treeView.treeNodeBuilder, isA>()); expect(treeView.treeRowBuilder, isA>()); }); + + testWidgets( + 'TreeViewNode should expand/collapse correctly when the animation duration is set to zero.', + (WidgetTester tester) async { + // Regression test for https://github.com/flutter/flutter/issues/154292 + final TreeViewController controller = TreeViewController(); + final List> tree = >[ + TreeViewNode('First'), + TreeViewNode( + 'Second', + children: >[ + TreeViewNode( + 'alpha', + children: >[ + TreeViewNode('uno'), + TreeViewNode('dos'), + TreeViewNode('tres'), + ], + ), + TreeViewNode('beta'), + TreeViewNode('kappa'), + ], + ), + TreeViewNode( + 'Third', + expanded: true, + children: >[ + TreeViewNode('gamma'), + TreeViewNode('delta'), + TreeViewNode('epsilon'), + ], + ), + TreeViewNode('Fourth'), + ]; + + await tester.pumpWidget(MaterialApp( + home: TreeView( + tree: tree, + controller: controller, + toggleAnimationStyle: AnimationStyle( + curve: Curves.easeInOut, + duration: Duration.zero, + ), + treeNodeBuilder: ( + BuildContext context, + TreeViewNode node, + AnimationStyle animationStyle, + ) { + final Widget child = GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () => controller.toggleNode(node), + child: TreeView.defaultTreeNodeBuilder( + context, + node, + animationStyle, + ), + ); + + return child; + }, + ), + )); + + expect(find.text('First'), findsOneWidget); + expect(find.text('Second'), findsOneWidget); + expect(find.text('Third'), findsOneWidget); + expect(find.text('Fourth'), findsOneWidget); + expect(find.text('alpha'), findsNothing); + expect(find.text('beta'), findsNothing); + expect(find.text('kappa'), findsNothing); + expect(find.text('gamma'), findsOneWidget); + expect(find.text('delta'), findsOneWidget); + expect(find.text('epsilon'), findsOneWidget); + expect(find.text('uno'), findsNothing); + expect(find.text('dos'), findsNothing); + expect(find.text('tres'), findsNothing); + + await tester.tap(find.text('Second')); + await tester.pumpAndSettle(); + + expect(find.text('alpha'), findsOneWidget); + + await tester.tap(find.text('alpha')); + await tester.pumpAndSettle(); + + expect(find.text('uno'), findsOneWidget); + expect(find.text('dos'), findsOneWidget); + expect(find.text('tres'), findsOneWidget); + + await tester.tap(find.text('alpha')); + await tester.pumpAndSettle(); + + expect(find.text('uno'), findsNothing); + expect(find.text('dos'), findsNothing); + expect(find.text('tres'), findsNothing); + }); + + testWidgets( + 'TreeViewNode should close all child nodes when collapsed, once the animation is completed', + (WidgetTester tester) async { + final TreeViewController controller = TreeViewController(); + final List> tree = >[ + TreeViewNode( + 'First', + expanded: true, + children: >[ + TreeViewNode( + 'alpha', + expanded: true, + children: >[ + TreeViewNode('uno'), + TreeViewNode('dos'), + TreeViewNode('tres'), + ], + ), + TreeViewNode('beta'), + TreeViewNode('kappa'), + ], + ), + ]; + + await tester.pumpWidget(MaterialApp( + home: TreeView( + tree: tree, + controller: controller, + toggleAnimationStyle: AnimationStyle( + curve: Curves.easeInOut, + duration: const Duration(milliseconds: 200), + ), + treeNodeBuilder: ( + BuildContext context, + TreeViewNode node, + AnimationStyle animationStyle, + ) { + final Widget child = GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () => controller.toggleNode(node), + child: TreeView.defaultTreeNodeBuilder( + context, + node, + animationStyle, + ), + ); + + return child; + }, + ), + )); + + expect(find.text('alpha'), findsOneWidget); + expect(find.text('uno'), findsOneWidget); + expect(find.text('dos'), findsOneWidget); + expect(find.text('tres'), findsOneWidget); + + // Using runAsync to handle collapse and animations properly. + await tester.runAsync(() async { + await tester.tap(find.text('alpha')); + await tester.pumpAndSettle(); + + expect(find.text('uno'), findsNothing); + expect(find.text('dos'), findsNothing); + expect(find.text('tres'), findsNothing); + }); + }); }); group('TreeViewport', () { diff --git a/packages/url_launcher/url_launcher/CHANGELOG.md b/packages/url_launcher/url_launcher/CHANGELOG.md index 9ef34c528aad..859646fbe7b3 100644 --- a/packages/url_launcher/url_launcher/CHANGELOG.md +++ b/packages/url_launcher/url_launcher/CHANGELOG.md @@ -1,3 +1,8 @@ +## 6.3.1 + +* Removes incorrect SMS instructions from README. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + ## 6.3.0 * Adds `BrowserConfiguration` parameter, to configure in-app browser views, such as Android Custom Tabs or SFSafariViewController. diff --git a/packages/url_launcher/url_launcher/README.md b/packages/url_launcher/url_launcher/README.md index f79c7ba6f221..301c0a068e1d 100644 --- a/packages/url_launcher/url_launcher/README.md +++ b/packages/url_launcher/url_launcher/README.md @@ -10,11 +10,7 @@ A Flutter plugin for launching a URL. |-------------|---------|-------|-------|--------|-----|-------------| | **Support** | SDK 16+ | 12.0+ | Any | 10.14+ | Any | Windows 10+ | -## Usage - -To use this plugin, add `url_launcher` as a [dependency in your pubspec.yaml file](https://flutter.dev/platform-plugins/). - -### Example +## Example ```dart @@ -174,19 +170,6 @@ String? encodeQueryParameters(Map params) { launchUrl(emailLaunchUri); ``` -Encoding for `sms` is slightly different: - - -```dart -final Uri smsLaunchUri = Uri( - scheme: 'sms', - path: '0118 999 881 999 119 7253', - queryParameters: { - 'body': Uri.encodeComponent('Example Subject & Symbols are allowed!'), - }, -); -``` - ### URLs not handled by `Uri` In rare cases, you may need to launch a URL that the host system considers diff --git a/packages/url_launcher/url_launcher/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/url_launcher/url_launcher/example/android/app/gradle/wrapper/gradle-wrapper.properties index 609ab8e6c8b5..d951fac2bf31 100644 --- a/packages/url_launcher/url_launcher/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ b/packages/url_launcher/url_launcher/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/packages/url_launcher/url_launcher/example/android/build.gradle b/packages/url_launcher/url_launcher/example/android/build.gradle index cec92de922cf..0bed8906c094 100644 --- a/packages/url_launcher/url_launcher/example/android/build.gradle +++ b/packages/url_launcher/url_launcher/example/android/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath 'com.android.tools.build:gradle:8.5.2' } } diff --git a/packages/url_launcher/url_launcher/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/url_launcher/url_launcher/example/android/gradle/wrapper/gradle-wrapper.properties index 067458b986d5..c677a74b9e70 100644 --- a/packages/url_launcher/url_launcher/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/url_launcher/url_launcher/example/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/url_launcher/url_launcher/example/lib/encoding.dart b/packages/url_launcher/url_launcher/example/lib/encoding.dart index 0875a8587269..f3bcc57cbda9 100644 --- a/packages/url_launcher/url_launcher/example/lib/encoding.dart +++ b/packages/url_launcher/url_launcher/example/lib/encoding.dart @@ -31,10 +31,6 @@ void main() => runApp( onPressed: _composeMail, child: Text('Compose an email'), ), - ElevatedButton( - onPressed: _composeSms, - child: Text('Compose a SMS'), - ), ], ), ), @@ -54,17 +50,3 @@ void _composeMail() { launchUrl(emailLaunchUri); // #enddocregion encode-query-parameters } - -void _composeSms() { -// #docregion sms - final Uri smsLaunchUri = Uri( - scheme: 'sms', - path: '0118 999 881 999 119 7253', - queryParameters: { - 'body': Uri.encodeComponent('Example Subject & Symbols are allowed!'), - }, - ); -// #enddocregion sms - - launchUrl(smsLaunchUri); -} diff --git a/packages/url_launcher/url_launcher/example/macos/Podfile b/packages/url_launcher/url_launcher/example/macos/Podfile index 049abe295427..ae77cc1d4269 100644 --- a/packages/url_launcher/url_launcher/example/macos/Podfile +++ b/packages/url_launcher/url_launcher/example/macos/Podfile @@ -28,7 +28,6 @@ flutter_macos_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) end diff --git a/packages/url_launcher/url_launcher/example/pubspec.yaml b/packages/url_launcher/url_launcher/example/pubspec.yaml index 50bfbc8c3b88..a20fb1f84d10 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: @@ -24,7 +24,7 @@ dev_dependencies: sdk: flutter integration_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 plugin_platform_interface: ^2.1.7 flutter: diff --git a/packages/url_launcher/url_launcher/example/web/index.html b/packages/url_launcher/url_launcher/example/web/index.html index c3d22621fc4f..67c90440179f 100644 --- a/packages/url_launcher/url_launcher/example/web/index.html +++ b/packages/url_launcher/url_launcher/example/web/index.html @@ -21,16 +21,6 @@ - - - + diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml index 06b2fab2aa2a..3b594e883fba 100644 --- a/packages/url_launcher/url_launcher/pubspec.yaml +++ b/packages/url_launcher/url_launcher/pubspec.yaml @@ -3,11 +3,11 @@ description: Flutter plugin for launching a URL. Supports web, phone, SMS, and email schemes. repository: https://github.com/flutter/packages/tree/main/packages/url_launcher/url_launcher issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22 -version: 6.3.0 +version: 6.3.1 environment: - sdk: ">=3.2.0 <4.0.0" - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -41,7 +41,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 plugin_platform_interface: ^2.1.7 test: ^1.16.3 diff --git a/packages/url_launcher/url_launcher_android/CHANGELOG.md b/packages/url_launcher/url_launcher_android/CHANGELOG.md index 73af3ff94af7..d3f55358146d 100644 --- a/packages/url_launcher/url_launcher_android/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_android/CHANGELOG.md @@ -1,3 +1,48 @@ +## 6.3.14 + +* Bumps androidx.annotation:annotation from 1.9.0 to 1.9.1. + +## 6.3.13 + +* Bumps androidx.annotation:annotation from 1.8.2 to 1.9.0. + +## 6.3.12 + +* Updates Java compatibility version to 11. + +## 6.3.11 + +* Updates Pigeon for non-nullable collection type support. + +## 6.3.10 + +* Removes dependency on org.jetbrains.kotlin:kotlin-bom. +* Updates minimum supported SDK version to Flutter 3.24/Dart 3.5. + +## 6.3.9 + +* Bumps androidx.annotation:annotation from 1.8.1 to 1.8.2. + +## 6.3.8 + +* Bumps androidx.browser:browser from 1.5.0 to 1.8.0. + +## 6.3.7 + +* Bumps androidx.annotation:annotation from 1.8.0 to 1.8.1. + +## 6.3.6 + +* Updates lint checks to ignore NewerVersionAvailable. + +## 6.3.5 + +* Bumps androidx.core:core from 1.10.1 to 1.13.1. + +## 6.3.4 + +* Updates Android Gradle Plugin to 8.5.1. + ## 6.3.3 * Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. diff --git a/packages/url_launcher/url_launcher_android/README.md b/packages/url_launcher/url_launcher_android/README.md index 0a1a3c752efa..801a541a346f 100644 --- a/packages/url_launcher/url_launcher_android/README.md +++ b/packages/url_launcher/url_launcher_android/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/url_launcher -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/url_launcher/url_launcher_android/android/build.gradle b/packages/url_launcher/url_launcher_android/android/build.gradle index 7604e9ac4b22..6c0f414ace6a 100644 --- a/packages/url_launcher/url_launcher_android/android/build.gradle +++ b/packages/url_launcher/url_launcher_android/android/build.gradle @@ -8,7 +8,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.3.0' + classpath 'com.android.tools.build:gradle:8.5.1' } } @@ -25,10 +25,7 @@ android { buildFeatures { buildConfig true } - // Conditional for compatibility with AGP <4.2. - if (project.android.hasProperty("namespace")) { - namespace 'io.flutter.plugins.urllauncher' - } + namespace 'io.flutter.plugins.urllauncher' compileSdk 34 defaultConfig { @@ -37,14 +34,14 @@ android { } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } lintOptions { checkAllWarnings true warningsAsErrors true - disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency' + disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency', 'NewerVersionAvailable' } @@ -64,15 +61,11 @@ android { dependencies { // Java language implementation - implementation "androidx.core:core:1.10.1" - implementation 'androidx.annotation:annotation:1.8.0' - implementation 'androidx.browser:browser:1.5.0' + implementation "androidx.core:core:1.13.1" + implementation 'androidx.annotation:annotation:1.9.1' + implementation 'androidx.browser:browser:1.8.0' testImplementation 'junit:junit:4.13.2' testImplementation 'org.mockito:mockito-core:5.1.1' testImplementation 'androidx.test:core:1.0.0' testImplementation 'org.robolectric:robolectric:4.10.3' - - // org.jetbrains.kotlin:kotlin-bom artifact purpose is to align kotlin stdlib and related code versions. - // See: https://youtrack.jetbrains.com/issue/KT-55297/kotlin-stdlib-should-declare-constraints-on-kotlin-stdlib-jdk8-and-kotlin-stdlib-jdk7 - implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.22")) } diff --git a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/Messages.java b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/Messages.java index ff79d6320936..2fa6e4576738 100644 --- a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/Messages.java +++ b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/Messages.java @@ -1,11 +1,14 @@ // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v10.1.6), do not edit directly. +// Autogenerated from Pigeon (v22.4.1), do not edit directly. // See also: https://pub.dev/packages/pigeon package io.flutter.plugins.urllauncher; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.CLASS; + import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -14,9 +17,12 @@ import io.flutter.plugin.common.MessageCodec; import io.flutter.plugin.common.StandardMessageCodec; import java.io.ByteArrayOutputStream; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Map; +import java.util.Objects; /** Generated class from Pigeon. */ @SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression", "serial"}) @@ -40,7 +46,7 @@ public FlutterError(@NonNull String code, @Nullable String message, @Nullable Ob @NonNull protected static ArrayList wrapError(@NonNull Throwable exception) { - ArrayList errorList = new ArrayList(3); + ArrayList errorList = new ArrayList<>(3); if (exception instanceof FlutterError) { FlutterError error = (FlutterError) exception; errorList.add(error.code); @@ -55,6 +61,10 @@ protected static ArrayList wrapError(@NonNull Throwable exception) { return errorList; } + @Target(METHOD) + @Retention(CLASS) + @interface CanIgnoreReturnValue {} + /** * Configuration options for an in-app WebView. * @@ -103,10 +113,30 @@ public void setHeaders(@NonNull Map setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ WebViewOptions() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + WebViewOptions that = (WebViewOptions) o; + return enableJavaScript.equals(that.enableJavaScript) + && enableDomStorage.equals(that.enableDomStorage) + && headers.equals(that.headers); + } + + @Override + public int hashCode() { + return Objects.hash(enableJavaScript, enableDomStorage, headers); + } + public static final class Builder { private @Nullable Boolean enableJavaScript; + @CanIgnoreReturnValue public @NonNull Builder setEnableJavaScript(@NonNull Boolean setterArg) { this.enableJavaScript = setterArg; return this; @@ -114,6 +144,7 @@ public static final class Builder { private @Nullable Boolean enableDomStorage; + @CanIgnoreReturnValue public @NonNull Builder setEnableDomStorage(@NonNull Boolean setterArg) { this.enableDomStorage = setterArg; return this; @@ -121,6 +152,7 @@ public static final class Builder { private @Nullable Map headers; + @CanIgnoreReturnValue public @NonNull Builder setHeaders(@NonNull Map setterArg) { this.headers = setterArg; return this; @@ -137,27 +169,32 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(3); + ArrayList toListResult = new ArrayList<>(3); toListResult.add(enableJavaScript); toListResult.add(enableDomStorage); toListResult.add(headers); return toListResult; } - static @NonNull WebViewOptions fromList(@NonNull ArrayList list) { + static @NonNull WebViewOptions fromList(@NonNull ArrayList pigeonVar_list) { WebViewOptions pigeonResult = new WebViewOptions(); - Object enableJavaScript = list.get(0); + Object enableJavaScript = pigeonVar_list.get(0); pigeonResult.setEnableJavaScript((Boolean) enableJavaScript); - Object enableDomStorage = list.get(1); + Object enableDomStorage = pigeonVar_list.get(1); pigeonResult.setEnableDomStorage((Boolean) enableDomStorage); - Object headers = list.get(2); + Object headers = pigeonVar_list.get(2); pigeonResult.setHeaders((Map) headers); return pigeonResult; } } - /** Generated class from Pigeon that represents data sent in messages. */ + /** + * Configuration options for in-app browser views. + * + *

Generated class from Pigeon that represents data sent in messages. + */ public static final class BrowserOptions { + /** Whether or not to show the webpage title. */ private @NonNull Boolean showTitle; public @NonNull Boolean getShowTitle() { @@ -174,10 +211,28 @@ public void setShowTitle(@NonNull Boolean setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ BrowserOptions() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + BrowserOptions that = (BrowserOptions) o; + return showTitle.equals(that.showTitle); + } + + @Override + public int hashCode() { + return Objects.hash(showTitle); + } + public static final class Builder { private @Nullable Boolean showTitle; + @CanIgnoreReturnValue public @NonNull Builder setShowTitle(@NonNull Boolean setterArg) { this.showTitle = setterArg; return this; @@ -192,31 +247,31 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(1); + ArrayList toListResult = new ArrayList<>(1); toListResult.add(showTitle); return toListResult; } - static @NonNull BrowserOptions fromList(@NonNull ArrayList list) { + static @NonNull BrowserOptions fromList(@NonNull ArrayList pigeonVar_list) { BrowserOptions pigeonResult = new BrowserOptions(); - Object showTitle = list.get(0); + Object showTitle = pigeonVar_list.get(0); pigeonResult.setShowTitle((Boolean) showTitle); return pigeonResult; } } - private static class UrlLauncherApiCodec extends StandardMessageCodec { - public static final UrlLauncherApiCodec INSTANCE = new UrlLauncherApiCodec(); + private static class PigeonCodec extends StandardMessageCodec { + public static final PigeonCodec INSTANCE = new PigeonCodec(); - private UrlLauncherApiCodec() {} + private PigeonCodec() {} @Override protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { switch (type) { - case (byte) 128: - return BrowserOptions.fromList((ArrayList) readValue(buffer)); case (byte) 129: return WebViewOptions.fromList((ArrayList) readValue(buffer)); + case (byte) 130: + return BrowserOptions.fromList((ArrayList) readValue(buffer)); default: return super.readValueOfType(type, buffer); } @@ -224,12 +279,12 @@ protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { @Override protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { - if (value instanceof BrowserOptions) { - stream.write(128); - writeValue(stream, ((BrowserOptions) value).toList()); - } else if (value instanceof WebViewOptions) { + if (value instanceof WebViewOptions) { stream.write(129); writeValue(stream, ((WebViewOptions) value).toList()); + } else if (value instanceof BrowserOptions) { + stream.write(130); + writeValue(stream, ((BrowserOptions) value).toList()); } else { super.writeValue(stream, value); } @@ -244,7 +299,9 @@ public interface UrlLauncherApi { /** Opens the URL externally, returning true if successful. */ @NonNull Boolean launchUrl(@NonNull String url, @NonNull Map headers); - /** Opens the URL in an in-app WebView, returning true if it opens successfully. */ + /** + * Opens the URL in an in-app Custom Tab or WebView, returning true if it opens successfully. + */ @NonNull Boolean openUrlInApp( @NonNull String url, @@ -259,28 +316,36 @@ Boolean openUrlInApp( /** The codec used by UrlLauncherApi. */ static @NonNull MessageCodec getCodec() { - return UrlLauncherApiCodec.INSTANCE; + return PigeonCodec.INSTANCE; } /** Sets up an instance of `UrlLauncherApi` to handle messages through the `binaryMessenger`. */ - static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLauncherApi api) { + static void setUp(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLauncherApi api) { + setUp(binaryMessenger, "", api); + } + + static void setUp( + @NonNull BinaryMessenger binaryMessenger, + @NonNull String messageChannelSuffix, + @Nullable UrlLauncherApi api) { + messageChannelSuffix = messageChannelSuffix.isEmpty() ? "" : "." + messageChannelSuffix; { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.canLaunchUrl", + "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.canLaunchUrl" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; String urlArg = (String) args.get(0); try { Boolean output = api.canLaunchUrl(urlArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -292,12 +357,13 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.launchUrl", + "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.launchUrl" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; String urlArg = (String) args.get(0); Map headersArg = (Map) args.get(1); @@ -305,8 +371,7 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche Boolean output = api.launchUrl(urlArg, headersArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -318,12 +383,13 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.openUrlInApp", + "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.openUrlInApp" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; String urlArg = (String) args.get(0); Boolean allowCustomTabArg = (Boolean) args.get(1); @@ -335,8 +401,7 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche urlArg, allowCustomTabArg, webViewOptionsArg, browserOptionsArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -348,18 +413,18 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.supportsCustomTabs", + "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.supportsCustomTabs" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { Boolean output = api.supportsCustomTabs(); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -371,18 +436,18 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.closeWebView", + "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.closeWebView" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { api.closeWebView(); wrapped.add(0, null); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); diff --git a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java index 34bf08f9f300..727741171591 100644 --- a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java +++ b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java @@ -23,7 +23,7 @@ public final class UrlLauncherPlugin implements FlutterPlugin, ActivityAware { @Override public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { urlLauncher = new UrlLauncher(binding.getApplicationContext()); - Messages.UrlLauncherApi.setup(binding.getBinaryMessenger(), urlLauncher); + Messages.UrlLauncherApi.setUp(binding.getBinaryMessenger(), urlLauncher); } @Override @@ -33,7 +33,7 @@ public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { return; } - Messages.UrlLauncherApi.setup(binding.getBinaryMessenger(), null); + Messages.UrlLauncherApi.setUp(binding.getBinaryMessenger(), null); urlLauncher = null; } diff --git a/packages/url_launcher/url_launcher_android/example/android/app/build.gradle b/packages/url_launcher/url_launcher_android/example/android/app/build.gradle index 60d78e27eb3d..6d392c2d7e89 100644 --- a/packages/url_launcher/url_launcher_android/example/android/app/build.gradle +++ b/packages/url_launcher/url_launcher_android/example/android/app/build.gradle @@ -32,7 +32,7 @@ android { defaultConfig { applicationId "io.flutter.plugins.urllauncherexample" minSdkVersion flutter.minSdkVersion - targetSdkVersion 30 + targetSdkVersion 34 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/packages/url_launcher/url_launcher_android/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/url_launcher/url_launcher_android/example/android/app/gradle/wrapper/gradle-wrapper.properties index 609ab8e6c8b5..d951fac2bf31 100644 --- a/packages/url_launcher/url_launcher_android/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ b/packages/url_launcher/url_launcher_android/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/packages/url_launcher/url_launcher_android/example/android/app/src/main/AndroidManifest.xml b/packages/url_launcher/url_launcher_android/example/android/app/src/main/AndroidManifest.xml index 918c29ee2dca..0551b442084a 100644 --- a/packages/url_launcher/url_launcher_android/example/android/app/src/main/AndroidManifest.xml +++ b/packages/url_launcher/url_launcher_android/example/android/app/src/main/AndroidManifest.xml @@ -24,7 +24,8 @@ android:label="url_launcher_example"> diff --git a/packages/url_launcher/url_launcher_android/example/android/build.gradle b/packages/url_launcher/url_launcher_android/example/android/build.gradle index 0c2fe43da28f..9507fa86d992 100644 --- a/packages/url_launcher/url_launcher_android/example/android/build.gradle +++ b/packages/url_launcher/url_launcher_android/example/android/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath 'com.android.tools.build:gradle:8.5.1' } } diff --git a/packages/url_launcher/url_launcher_android/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/url_launcher/url_launcher_android/example/android/gradle/wrapper/gradle-wrapper.properties index 067458b986d5..c677a74b9e70 100644 --- a/packages/url_launcher/url_launcher_android/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/url_launcher/url_launcher_android/example/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/url_launcher/url_launcher_android/example/pubspec.yaml b/packages/url_launcher/url_launcher_android/example/pubspec.yaml index 256861b72501..daec04ee36be 100644 --- a/packages/url_launcher/url_launcher_android/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_android/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the url_launcher plugin. publish_to: none environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" dependencies: flutter: @@ -23,7 +23,7 @@ dev_dependencies: sdk: flutter integration_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 plugin_platform_interface: ^2.1.7 flutter: diff --git a/packages/url_launcher/url_launcher_android/lib/src/messages.g.dart b/packages/url_launcher/url_launcher_android/lib/src/messages.g.dart index 546f969c8809..af74878f86c1 100644 --- a/packages/url_launcher/url_launcher_android/lib/src/messages.g.dart +++ b/packages/url_launcher/url_launcher_android/lib/src/messages.g.dart @@ -1,9 +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 (v10.1.6), do not edit directly. +// Autogenerated from Pigeon (v22.4.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 +// 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 import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; @@ -11,19 +11,26 @@ import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; import 'package:flutter/services.dart'; +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); +} + /// Configuration options for an in-app WebView. class WebViewOptions { WebViewOptions({ required this.enableJavaScript, required this.enableDomStorage, - required this.headers, + this.headers = const {}, }); bool enableJavaScript; bool enableDomStorage; - Map headers; + Map headers; Object encode() { return [ @@ -38,16 +45,18 @@ class WebViewOptions { return WebViewOptions( enableJavaScript: result[0]! as bool, enableDomStorage: result[1]! as bool, - headers: (result[2] as Map?)!.cast(), + headers: (result[2] as Map?)!.cast(), ); } } +/// Configuration options for in-app browser views. class BrowserOptions { BrowserOptions({ required this.showTitle, }); + /// Whether or not to show the webpage title. bool showTitle; Object encode() { @@ -64,16 +73,19 @@ class BrowserOptions { } } -class _UrlLauncherApiCodec extends StandardMessageCodec { - const _UrlLauncherApiCodec(); +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is BrowserOptions) { - buffer.putUint8(128); - writeValue(buffer, value.encode()); + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); } else if (value is WebViewOptions) { buffer.putUint8(129); writeValue(buffer, value.encode()); + } else if (value is BrowserOptions) { + buffer.putUint8(130); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -82,10 +94,10 @@ class _UrlLauncherApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: - return BrowserOptions.decode(readValue(buffer)!); case 129: return WebViewOptions.decode(readValue(buffer)!); + case 130: + return BrowserOptions.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -96,153 +108,158 @@ class UrlLauncherApi { /// Constructor for [UrlLauncherApi]. 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. - UrlLauncherApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; + UrlLauncherApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; - static const MessageCodec codec = _UrlLauncherApiCodec(); + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String pigeonVar_messageChannelSuffix; /// Returns true if the URL can definitely be launched. - Future canLaunchUrl(String arg_url) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.canLaunchUrl', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_url]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future canLaunchUrl(String url) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.canLaunchUrl$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([url]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 (replyList[0] as bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } /// Opens the URL externally, returning true if successful. - Future launchUrl( - String arg_url, Map arg_headers) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.launchUrl', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_url, arg_headers]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future launchUrl(String url, Map headers) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.launchUrl$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([url, headers]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 (replyList[0] as bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } - /// Opens the URL in an in-app WebView, returning true if it opens - /// successfully. - Future openUrlInApp( - String arg_url, - bool arg_allowCustomTab, - WebViewOptions arg_webViewOptions, - BrowserOptions arg_browserOptions) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.openUrlInApp', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send([ - arg_url, - arg_allowCustomTab, - arg_webViewOptions, - arg_browserOptions - ]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + /// Opens the URL in an in-app Custom Tab or WebView, returning true if it + /// opens successfully. + Future openUrlInApp(String url, bool allowCustomTab, + WebViewOptions webViewOptions, BrowserOptions browserOptions) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.openUrlInApp$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel.send( + [url, allowCustomTab, webViewOptions, browserOptions]) + as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 (replyList[0] as bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } Future supportsCustomTabs() async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.supportsCustomTabs', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send(null) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.supportsCustomTabs$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 (replyList[0] as bool?)!; + return (pigeonVar_replyList[0] as bool?)!; } } /// Closes the view opened by [openUrlInSafariViewController]. Future closeWebView() async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.closeWebView', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send(null) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.closeWebView$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; diff --git a/packages/url_launcher/url_launcher_android/lib/url_launcher_android.dart b/packages/url_launcher/url_launcher_android/lib/url_launcher_android.dart index 2c6d01c9b311..7a447d5203f3 100644 --- a/packages/url_launcher/url_launcher_android/lib/url_launcher_android.dart +++ b/packages/url_launcher/url_launcher_android/lib/url_launcher_android.dart @@ -89,11 +89,10 @@ class UrlLauncherAndroid extends UrlLauncherPlatform { case PreferredLaunchMode.platformDefault: // Intentionally treat any new values as platformDefault; see comment in // supportsMode. - // ignore: no_default_cases + // ignore: no_default_cases, unreachable_switch_default default: // By default, open web URLs in the application. inApp = url.startsWith('http:') || url.startsWith('https:'); - break; } final bool succeeded; diff --git a/packages/url_launcher/url_launcher_android/pigeons/messages.dart b/packages/url_launcher/url_launcher_android/pigeons/messages.dart index 6f39272c4f7f..f3a3795339d3 100644 --- a/packages/url_launcher/url_launcher_android/pigeons/messages.dart +++ b/packages/url_launcher/url_launcher_android/pigeons/messages.dart @@ -21,10 +21,7 @@ class WebViewOptions { final bool enableJavaScript; final bool enableDomStorage; - // TODO(stuartmorgan): Declare these as non-nullable generics once - // https://github.com/flutter/flutter/issues/97848 is fixed. In practice, - // the values will never be null, and the native implementation assumes that. - final Map headers; + final Map headers; } /// Configuration options for in-app browser views. diff --git a/packages/url_launcher/url_launcher_android/pubspec.yaml b/packages/url_launcher/url_launcher_android/pubspec.yaml index e3c65d4cd7a8..aa83cdb0e3cc 100644 --- a/packages/url_launcher/url_launcher_android/pubspec.yaml +++ b/packages/url_launcher/url_launcher_android/pubspec.yaml @@ -2,10 +2,10 @@ name: url_launcher_android description: Android implementation of the url_launcher plugin. repository: https://github.com/flutter/packages/tree/main/packages/url_launcher/url_launcher_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22 -version: 6.3.3 +version: 6.3.14 environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" flutter: plugin: @@ -24,8 +24,8 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - mockito: 5.4.4 - pigeon: ^10.0.0 + mockito: ^5.4.4 + pigeon: ^22.4.1 plugin_platform_interface: ^2.1.7 test: ^1.16.3 diff --git a/packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart b/packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart index 7b469246a5c1..63745ec74cb4 100644 --- a/packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart +++ b/packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart @@ -429,7 +429,7 @@ class _FakeUrlLauncherApi implements UrlLauncherApi { } @override - Future launchUrl(String url, Map headers) async { + Future launchUrl(String url, Map headers) async { passedWebViewOptions = WebViewOptions( enableJavaScript: false, enableDomStorage: false, @@ -478,4 +478,12 @@ class _FakeUrlLauncherApi implements UrlLauncherApi { return false; } } + + @override + // ignore: non_constant_identifier_names + BinaryMessenger? get pigeonVar_binaryMessenger => null; + + @override + // ignore: non_constant_identifier_names + String get pigeonVar_messageChannelSuffix => ''; } diff --git a/packages/url_launcher/url_launcher_ios/CHANGELOG.md b/packages/url_launcher/url_launcher_ios/CHANGELOG.md index 0c6d13e0941e..b0e3fa3f2dcd 100644 --- a/packages/url_launcher/url_launcher_ios/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_ios/CHANGELOG.md @@ -1,3 +1,11 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + +## 6.3.1 + +* Fixes a compile error when comforming UIApplication to Launcher in iOS 18 Beta 3. + ## 6.3.0 * Adds Swift Package Manager compatibility. diff --git a/packages/url_launcher/url_launcher_ios/README.md b/packages/url_launcher/url_launcher_ios/README.md index 8b8b4fd447ab..e76843293da9 100644 --- a/packages/url_launcher/url_launcher_ios/README.md +++ b/packages/url_launcher/url_launcher_ios/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/url_launcher -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/url_launcher/url_launcher_ios/example/pubspec.yaml b/packages/url_launcher/url_launcher_ios/example/pubspec.yaml index 2b746872a0c1..3e259987a104 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.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/url_launcher/url_launcher_ios/ios/url_launcher_ios/Sources/url_launcher_ios/Launcher.swift b/packages/url_launcher/url_launcher_ios/ios/url_launcher_ios/Sources/url_launcher_ios/Launcher.swift index 454dd53fbb9c..1f64b95c642d 100644 --- a/packages/url_launcher/url_launcher_ios/ios/url_launcher_ios/Sources/url_launcher_ios/Launcher.swift +++ b/packages/url_launcher/url_launcher_ios/ios/url_launcher_ios/Sources/url_launcher_ios/Launcher.swift @@ -18,5 +18,21 @@ protocol Launcher { completionHandler completion: ((Bool) -> Void)?) } -/// Launcher is intentionally a direct passthroguh to UIApplication. -extension UIApplication: Launcher {} +// TODO(hellohuanlin): This wrapper is a workaround for iOS 18 Beta 3 where completionHandler is annotated with @MainActor @Sendable, resulting in compile error when conforming UIApplication to Launcher. We should try again in newer betas. +/// A default URL launcher. +final class DefaultLauncher: Launcher { + func canOpenURL(_ url: URL) -> Bool { + return UIApplication.shared.canOpenURL(url) + } + + func open( + _ url: URL, + options: [UIApplication.OpenExternalURLOptionsKey: Any], + completionHandler completion: ((Bool) -> Void)? + ) { + UIApplication.shared.open( + url, + options: options, + completionHandler: completion) + } +} diff --git a/packages/url_launcher/url_launcher_ios/ios/url_launcher_ios/Sources/url_launcher_ios/URLLauncherPlugin.swift b/packages/url_launcher/url_launcher_ios/ios/url_launcher_ios/Sources/url_launcher_ios/URLLauncherPlugin.swift index 44718dee7323..9fdec7ee5ae3 100644 --- a/packages/url_launcher/url_launcher_ios/ios/url_launcher_ios/Sources/url_launcher_ios/URLLauncherPlugin.swift +++ b/packages/url_launcher/url_launcher_ios/ios/url_launcher_ios/Sources/url_launcher_ios/URLLauncherPlugin.swift @@ -22,7 +22,7 @@ public final class URLLauncherPlugin: NSObject, FlutterPlugin, UrlLauncherApi { UIApplication.shared.keyWindow?.rootViewController?.topViewController } - init(launcher: Launcher = UIApplication.shared) { + init(launcher: Launcher = DefaultLauncher()) { self.launcher = launcher } diff --git a/packages/url_launcher/url_launcher_ios/lib/url_launcher_ios.dart b/packages/url_launcher/url_launcher_ios/lib/url_launcher_ios.dart index 24b25acb3896..bb289abc5699 100644 --- a/packages/url_launcher/url_launcher_ios/lib/url_launcher_ios.dart +++ b/packages/url_launcher/url_launcher_ios/lib/url_launcher_ios.dart @@ -82,11 +82,10 @@ class UrlLauncherIOS extends UrlLauncherPlatform { // Intentionally treat any new values as platformDefault; support for any // new mode requires intentional opt-in, otherwise falling back is the // documented behavior. - // ignore: no_default_cases + // ignore: no_default_cases, unreachable_switch_default default: // By default, open web URLs in the application. inApp = url.startsWith('http:') || url.startsWith('https:'); - break; } if (inApp) { @@ -111,7 +110,7 @@ class UrlLauncherIOS extends UrlLauncherPlatform { // Default is a desired behavior here since support for new modes is // always opt-in, and the enum lives in a different package, so silently // adding "false" for new values is the correct behavior. - // ignore: no_default_cases + // ignore: no_default_cases, unreachable_switch_default default: return false; } diff --git a/packages/url_launcher/url_launcher_ios/pubspec.yaml b/packages/url_launcher/url_launcher_ios/pubspec.yaml index 65e9c2048351..684bd9e4242b 100644 --- a/packages/url_launcher/url_launcher_ios/pubspec.yaml +++ b/packages/url_launcher/url_launcher_ios/pubspec.yaml @@ -2,11 +2,11 @@ name: url_launcher_ios description: iOS implementation of the url_launcher plugin. repository: https://github.com/flutter/packages/tree/main/packages/url_launcher/url_launcher_ios issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22 -version: 6.3.0 +version: 6.3.1 environment: - sdk: ^3.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -25,7 +25,7 @@ dev_dependencies: build_runner: ^2.3.3 flutter_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 pigeon: ^11.0.1 plugin_platform_interface: ^2.1.7 test: ^1.16.3 diff --git a/packages/url_launcher/url_launcher_linux/CHANGELOG.md b/packages/url_launcher/url_launcher_linux/CHANGELOG.md index 769924459a21..9b5c7d9037f0 100644 --- a/packages/url_launcher/url_launcher_linux/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_linux/CHANGELOG.md @@ -1,6 +1,7 @@ -## NEXT +## 3.2.0 -* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. +* Updates platform channels to use Pigeon. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 3.1.1 diff --git a/packages/url_launcher/url_launcher_linux/README.md b/packages/url_launcher/url_launcher_linux/README.md index ad7e9dbf0d97..143e1f3645af 100644 --- a/packages/url_launcher/url_launcher_linux/README.md +++ b/packages/url_launcher/url_launcher_linux/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/url_launcher -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/url_launcher/url_launcher_linux/example/pubspec.yaml b/packages/url_launcher/url_launcher_linux/example/pubspec.yaml index eda0a3451e63..0a3b93f5c21b 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/url_launcher/url_launcher_linux/lib/src/messages.g.dart b/packages/url_launcher/url_launcher_linux/lib/src/messages.g.dart new file mode 100644 index 000000000000..ed74617c7e03 --- /dev/null +++ b/packages/url_launcher/url_launcher_linux/lib/src/messages.g.dart @@ -0,0 +1,94 @@ +// 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 (v21.1.0), 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 + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; + +import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/services.dart'; + +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); +} + +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); +} + +class UrlLauncherApi { + /// Constructor for [UrlLauncherApi]. 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. + UrlLauncherApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : __pigeon_binaryMessenger = binaryMessenger, + __pigeon_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? __pigeon_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String __pigeon_messageChannelSuffix; + + /// Returns true if the URL can definitely be launched. + Future canLaunchUrl(String url) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.url_launcher_linux.UrlLauncherApi.canLaunchUrl$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([url]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_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 bool?)!; + } + } + + /// Opens the URL externally, returning an error string on failure. + Future launchUrl(String url) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.url_launcher_linux.UrlLauncherApi.launchUrl$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([url]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as String?); + } + } +} diff --git a/packages/url_launcher/url_launcher_linux/lib/url_launcher_linux.dart b/packages/url_launcher/url_launcher_linux/lib/url_launcher_linux.dart index ed425a0357ae..b5c85043927f 100644 --- a/packages/url_launcher/url_launcher_linux/lib/url_launcher_linux.dart +++ b/packages/url_launcher/url_launcher_linux/lib/url_launcher_linux.dart @@ -4,26 +4,32 @@ import 'dart:async'; +import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:url_launcher_platform_interface/link.dart'; import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart'; -const MethodChannel _channel = - MethodChannel('plugins.flutter.io/url_launcher_linux'); +import 'src/messages.g.dart'; /// An implementation of [UrlLauncherPlatform] for Linux. class UrlLauncherLinux extends UrlLauncherPlatform { + /// Creates a new URL launcher instance. + UrlLauncherLinux({@visibleForTesting UrlLauncherApi? api}) + : _hostApi = api ?? UrlLauncherApi(); + /// Registers this class as the default instance of [UrlLauncherPlatform]. static void registerWith() { UrlLauncherPlatform.instance = UrlLauncherLinux(); } + final UrlLauncherApi _hostApi; + @override final LinkDelegate? linkDelegate = null; @override Future canLaunch(String url) async { - return (await _channel.invokeMethod('canLaunch', url)) ?? false; + return _hostApi.canLaunchUrl(url); } @override @@ -44,7 +50,15 @@ class UrlLauncherLinux extends UrlLauncherPlatform { @override Future launchUrl(String url, LaunchOptions options) async { - return (await _channel.invokeMethod('launch', url)) ?? false; + final String? error = await _hostApi.launchUrl(url); + if (error != null) { + // TODO(stuartmorgan): Standardize errors across the entire plugin, + // instead of using PlatformException. This preserves the pre-Pigeon + // behavior of the C code returning this error response. + throw PlatformException( + code: 'Launch Error', message: 'Failed to launch URL: $error'); + } + return true; } @override diff --git a/packages/url_launcher/url_launcher_linux/linux/CMakeLists.txt b/packages/url_launcher/url_launcher_linux/linux/CMakeLists.txt index 58e770653d83..a52bd5adcc13 100644 --- a/packages/url_launcher/url_launcher_linux/linux/CMakeLists.txt +++ b/packages/url_launcher/url_launcher_linux/linux/CMakeLists.txt @@ -7,6 +7,7 @@ cmake_policy(VERSION 3.10...3.24) set(PLUGIN_NAME "${PROJECT_NAME}_plugin") list(APPEND PLUGIN_SOURCES + "messages.g.cc" "url_launcher_plugin.cc" ) diff --git a/packages/url_launcher/url_launcher_linux/linux/messages.g.cc b/packages/url_launcher/url_launcher_linux/linux/messages.g.cc new file mode 100644 index 000000000000..6c047397fbcc --- /dev/null +++ b/packages/url_launcher/url_launcher_linux/linux/messages.g.cc @@ -0,0 +1,306 @@ +// 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 (v21.1.0), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +#include "messages.g.h" + +G_DECLARE_FINAL_TYPE(FulMessageCodec, ful_message_codec, FUL, MESSAGE_CODEC, + FlStandardMessageCodec) + +struct _FulMessageCodec { + FlStandardMessageCodec parent_instance; +}; + +G_DEFINE_TYPE(FulMessageCodec, ful_message_codec, + fl_standard_message_codec_get_type()) + +static gboolean ful_message_codec_write_value(FlStandardMessageCodec* codec, + GByteArray* buffer, + FlValue* value, GError** error) { + if (fl_value_get_type(value) == FL_VALUE_TYPE_CUSTOM) { + switch (fl_value_get_custom_type(value)) {} + } + + return FL_STANDARD_MESSAGE_CODEC_CLASS(ful_message_codec_parent_class) + ->write_value(codec, buffer, value, error); +} + +static FlValue* ful_message_codec_read_value_of_type( + FlStandardMessageCodec* codec, GBytes* buffer, size_t* offset, int type, + GError** error) { + switch (type) { + default: + return FL_STANDARD_MESSAGE_CODEC_CLASS(ful_message_codec_parent_class) + ->read_value_of_type(codec, buffer, offset, type, error); + } +} + +static void ful_message_codec_init(FulMessageCodec* self) {} + +static void ful_message_codec_class_init(FulMessageCodecClass* klass) { + FL_STANDARD_MESSAGE_CODEC_CLASS(klass)->write_value = + ful_message_codec_write_value; + FL_STANDARD_MESSAGE_CODEC_CLASS(klass)->read_value_of_type = + ful_message_codec_read_value_of_type; +} + +static FulMessageCodec* ful_message_codec_new() { + FulMessageCodec* self = + FUL_MESSAGE_CODEC(g_object_new(ful_message_codec_get_type(), nullptr)); + return self; +} + +struct _FulUrlLauncherApiCanLaunchUrlResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE(FulUrlLauncherApiCanLaunchUrlResponse, + ful_url_launcher_api_can_launch_url_response, G_TYPE_OBJECT) + +static void ful_url_launcher_api_can_launch_url_response_dispose( + GObject* object) { + FulUrlLauncherApiCanLaunchUrlResponse* self = + FUL_URL_LAUNCHER_API_CAN_LAUNCH_URL_RESPONSE(object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS(ful_url_launcher_api_can_launch_url_response_parent_class) + ->dispose(object); +} + +static void ful_url_launcher_api_can_launch_url_response_init( + FulUrlLauncherApiCanLaunchUrlResponse* self) {} + +static void ful_url_launcher_api_can_launch_url_response_class_init( + FulUrlLauncherApiCanLaunchUrlResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + ful_url_launcher_api_can_launch_url_response_dispose; +} + +FulUrlLauncherApiCanLaunchUrlResponse* +ful_url_launcher_api_can_launch_url_response_new(gboolean return_value) { + FulUrlLauncherApiCanLaunchUrlResponse* self = + FUL_URL_LAUNCHER_API_CAN_LAUNCH_URL_RESPONSE(g_object_new( + ful_url_launcher_api_can_launch_url_response_get_type(), nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_bool(return_value)); + return self; +} + +FulUrlLauncherApiCanLaunchUrlResponse* +ful_url_launcher_api_can_launch_url_response_new_error(const gchar* code, + const gchar* message, + FlValue* details) { + FulUrlLauncherApiCanLaunchUrlResponse* self = + FUL_URL_LAUNCHER_API_CAN_LAUNCH_URL_RESPONSE(g_object_new( + ful_url_launcher_api_can_launch_url_response_get_type(), nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _FulUrlLauncherApiLaunchUrlResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE(FulUrlLauncherApiLaunchUrlResponse, + ful_url_launcher_api_launch_url_response, G_TYPE_OBJECT) + +static void ful_url_launcher_api_launch_url_response_dispose(GObject* object) { + FulUrlLauncherApiLaunchUrlResponse* self = + FUL_URL_LAUNCHER_API_LAUNCH_URL_RESPONSE(object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS(ful_url_launcher_api_launch_url_response_parent_class) + ->dispose(object); +} + +static void ful_url_launcher_api_launch_url_response_init( + FulUrlLauncherApiLaunchUrlResponse* self) {} + +static void ful_url_launcher_api_launch_url_response_class_init( + FulUrlLauncherApiLaunchUrlResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + ful_url_launcher_api_launch_url_response_dispose; +} + +FulUrlLauncherApiLaunchUrlResponse* +ful_url_launcher_api_launch_url_response_new(const gchar* return_value) { + FulUrlLauncherApiLaunchUrlResponse* self = + FUL_URL_LAUNCHER_API_LAUNCH_URL_RESPONSE(g_object_new( + ful_url_launcher_api_launch_url_response_get_type(), nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, return_value != nullptr + ? fl_value_new_string(return_value) + : fl_value_new_null()); + return self; +} + +FulUrlLauncherApiLaunchUrlResponse* +ful_url_launcher_api_launch_url_response_new_error(const gchar* code, + const gchar* message, + FlValue* details) { + FulUrlLauncherApiLaunchUrlResponse* self = + FUL_URL_LAUNCHER_API_LAUNCH_URL_RESPONSE(g_object_new( + ful_url_launcher_api_launch_url_response_get_type(), nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +G_DECLARE_FINAL_TYPE(FulUrlLauncherApi, ful_url_launcher_api, FUL, + URL_LAUNCHER_API, GObject) + +struct _FulUrlLauncherApi { + GObject parent_instance; + + const FulUrlLauncherApiVTable* vtable; + gpointer user_data; + GDestroyNotify user_data_free_func; +}; + +G_DEFINE_TYPE(FulUrlLauncherApi, ful_url_launcher_api, G_TYPE_OBJECT) + +static void ful_url_launcher_api_dispose(GObject* object) { + FulUrlLauncherApi* self = FUL_URL_LAUNCHER_API(object); + if (self->user_data != nullptr) { + self->user_data_free_func(self->user_data); + } + self->user_data = nullptr; + G_OBJECT_CLASS(ful_url_launcher_api_parent_class)->dispose(object); +} + +static void ful_url_launcher_api_init(FulUrlLauncherApi* self) {} + +static void ful_url_launcher_api_class_init(FulUrlLauncherApiClass* klass) { + G_OBJECT_CLASS(klass)->dispose = ful_url_launcher_api_dispose; +} + +static FulUrlLauncherApi* ful_url_launcher_api_new( + const FulUrlLauncherApiVTable* vtable, gpointer user_data, + GDestroyNotify user_data_free_func) { + FulUrlLauncherApi* self = FUL_URL_LAUNCHER_API( + g_object_new(ful_url_launcher_api_get_type(), nullptr)); + self->vtable = vtable; + self->user_data = user_data; + self->user_data_free_func = user_data_free_func; + return self; +} + +static void ful_url_launcher_api_can_launch_url_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + FulUrlLauncherApi* self = FUL_URL_LAUNCHER_API(user_data); + + if (self->vtable == nullptr || self->vtable->can_launch_url == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + const gchar* url = fl_value_get_string(value0); + g_autoptr(FulUrlLauncherApiCanLaunchUrlResponse) response = + self->vtable->can_launch_url(url, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "UrlLauncherApi", + "canLaunchUrl"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "UrlLauncherApi", + "canLaunchUrl", error->message); + } +} + +static void ful_url_launcher_api_launch_url_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + FulUrlLauncherApi* self = FUL_URL_LAUNCHER_API(user_data); + + if (self->vtable == nullptr || self->vtable->launch_url == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + const gchar* url = fl_value_get_string(value0); + g_autoptr(FulUrlLauncherApiLaunchUrlResponse) response = + self->vtable->launch_url(url, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "UrlLauncherApi", "launchUrl"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "UrlLauncherApi", + "launchUrl", error->message); + } +} + +void ful_url_launcher_api_set_method_handlers( + FlBinaryMessenger* messenger, const gchar* suffix, + const FulUrlLauncherApiVTable* vtable, gpointer user_data, + GDestroyNotify user_data_free_func) { + g_autofree gchar* dot_suffix = + suffix != nullptr ? g_strdup_printf(".%s", suffix) : g_strdup(""); + g_autoptr(FulUrlLauncherApi) api_data = + ful_url_launcher_api_new(vtable, user_data, user_data_free_func); + + g_autoptr(FulMessageCodec) codec = ful_message_codec_new(); + g_autofree gchar* can_launch_url_channel_name = g_strdup_printf( + "dev.flutter.pigeon.url_launcher_linux.UrlLauncherApi.canLaunchUrl%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) can_launch_url_channel = + fl_basic_message_channel_new(messenger, can_launch_url_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + can_launch_url_channel, ful_url_launcher_api_can_launch_url_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* launch_url_channel_name = g_strdup_printf( + "dev.flutter.pigeon.url_launcher_linux.UrlLauncherApi.launchUrl%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) launch_url_channel = + fl_basic_message_channel_new(messenger, launch_url_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + launch_url_channel, ful_url_launcher_api_launch_url_cb, + g_object_ref(api_data), g_object_unref); +} + +void ful_url_launcher_api_clear_method_handlers(FlBinaryMessenger* messenger, + const gchar* suffix) { + g_autofree gchar* dot_suffix = + suffix != nullptr ? g_strdup_printf(".%s", suffix) : g_strdup(""); + + g_autoptr(FulMessageCodec) codec = ful_message_codec_new(); + g_autofree gchar* can_launch_url_channel_name = g_strdup_printf( + "dev.flutter.pigeon.url_launcher_linux.UrlLauncherApi.canLaunchUrl%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) can_launch_url_channel = + fl_basic_message_channel_new(messenger, can_launch_url_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(can_launch_url_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* launch_url_channel_name = g_strdup_printf( + "dev.flutter.pigeon.url_launcher_linux.UrlLauncherApi.launchUrl%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) launch_url_channel = + fl_basic_message_channel_new(messenger, launch_url_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(launch_url_channel, nullptr, + nullptr, nullptr); +} diff --git a/packages/url_launcher/url_launcher_linux/linux/messages.g.h b/packages/url_launcher/url_launcher_linux/linux/messages.g.h new file mode 100644 index 000000000000..bf6bcf678199 --- /dev/null +++ b/packages/url_launcher/url_launcher_linux/linux/messages.g.h @@ -0,0 +1,115 @@ +// 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 (v21.1.0), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +#ifndef PIGEON_MESSAGES_G_H_ +#define PIGEON_MESSAGES_G_H_ + +#include + +G_BEGIN_DECLS + +G_DECLARE_FINAL_TYPE(FulUrlLauncherApiCanLaunchUrlResponse, + ful_url_launcher_api_can_launch_url_response, FUL, + URL_LAUNCHER_API_CAN_LAUNCH_URL_RESPONSE, GObject) + +/** + * ful_url_launcher_api_can_launch_url_response_new: + * + * Creates a new response to UrlLauncherApi.canLaunchUrl. + * + * Returns: a new #FulUrlLauncherApiCanLaunchUrlResponse + */ +FulUrlLauncherApiCanLaunchUrlResponse* +ful_url_launcher_api_can_launch_url_response_new(gboolean return_value); + +/** + * ful_url_launcher_api_can_launch_url_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to UrlLauncherApi.canLaunchUrl. + * + * Returns: a new #FulUrlLauncherApiCanLaunchUrlResponse + */ +FulUrlLauncherApiCanLaunchUrlResponse* +ful_url_launcher_api_can_launch_url_response_new_error(const gchar* code, + const gchar* message, + FlValue* details); + +G_DECLARE_FINAL_TYPE(FulUrlLauncherApiLaunchUrlResponse, + ful_url_launcher_api_launch_url_response, FUL, + URL_LAUNCHER_API_LAUNCH_URL_RESPONSE, GObject) + +/** + * ful_url_launcher_api_launch_url_response_new: + * + * Creates a new response to UrlLauncherApi.launchUrl. + * + * Returns: a new #FulUrlLauncherApiLaunchUrlResponse + */ +FulUrlLauncherApiLaunchUrlResponse* +ful_url_launcher_api_launch_url_response_new(const gchar* return_value); + +/** + * ful_url_launcher_api_launch_url_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to UrlLauncherApi.launchUrl. + * + * Returns: a new #FulUrlLauncherApiLaunchUrlResponse + */ +FulUrlLauncherApiLaunchUrlResponse* +ful_url_launcher_api_launch_url_response_new_error(const gchar* code, + const gchar* message, + FlValue* details); + +/** + * FulUrlLauncherApiVTable: + * + * Table of functions exposed by UrlLauncherApi to be implemented by the API + * provider. + */ +typedef struct { + FulUrlLauncherApiCanLaunchUrlResponse* (*can_launch_url)(const gchar* url, + gpointer user_data); + FulUrlLauncherApiLaunchUrlResponse* (*launch_url)(const gchar* url, + gpointer user_data); +} FulUrlLauncherApiVTable; + +/** + * ful_url_launcher_api_set_method_handlers: + * + * @messenger: an #FlBinaryMessenger. + * @suffix: (allow-none): a suffix to add to the API or %NULL for none. + * @vtable: implementations of the methods in this API. + * @user_data: (closure): user data to pass to the functions in @vtable. + * @user_data_free_func: (allow-none): a function which gets called to free + * @user_data, or %NULL. + * + * Connects the method handlers in the UrlLauncherApi API. + */ +void ful_url_launcher_api_set_method_handlers( + FlBinaryMessenger* messenger, const gchar* suffix, + const FulUrlLauncherApiVTable* vtable, gpointer user_data, + GDestroyNotify user_data_free_func); + +/** + * ful_url_launcher_api_clear_method_handlers: + * + * @messenger: an #FlBinaryMessenger. + * @suffix: (allow-none): a suffix to add to the API or %NULL for none. + * + * Clears the method handlers in the UrlLauncherApi API. + */ +void ful_url_launcher_api_clear_method_handlers(FlBinaryMessenger* messenger, + const gchar* suffix); + +G_END_DECLS + +#endif // PIGEON_MESSAGES_G_H_ diff --git a/packages/url_launcher/url_launcher_linux/linux/test/url_launcher_linux_test.cc b/packages/url_launcher/url_launcher_linux/linux/test/url_launcher_linux_test.cc index 7d48008a6eb3..f5a5fdbfde28 100644 --- a/packages/url_launcher/url_launcher_linux/linux/test/url_launcher_linux_test.cc +++ b/packages/url_launcher/url_launcher_linux/linux/test/url_launcher_linux_test.cc @@ -11,65 +11,74 @@ #include "include/url_launcher_linux/url_launcher_plugin.h" #include "url_launcher_plugin_private.h" +// Re-declare the opaque struct as a temporary workaround for the lack of +// APIs for reading host API response objects. +// TODO(stuartmorgan): Remove this once the following is fixed: +// https://github.com/flutter/flutter/issues/152166. +struct _FulUrlLauncherApiCanLaunchUrlResponse { + GObject parent_instance; + + FlValue* value; +}; + namespace url_launcher_plugin { namespace test { TEST(UrlLauncherPlugin, CanLaunchSuccess) { - g_autoptr(FlValue) args = fl_value_new_string("https://flutter.dev"); - g_autoptr(FlMethodResponse) response = can_launch(nullptr, args); + g_autoptr(FulUrlLauncherApiCanLaunchUrlResponse) response = + handle_can_launch_url("https://flutter.dev", nullptr); ASSERT_NE(response, nullptr); - ASSERT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response)); + ASSERT_TRUE(fl_value_get_type(response->value) == FL_VALUE_TYPE_LIST); + ASSERT_TRUE(fl_value_get_length(response->value) == 1); g_autoptr(FlValue) expected = fl_value_new_bool(true); - EXPECT_TRUE(fl_value_equal(fl_method_success_response_get_result( - FL_METHOD_SUCCESS_RESPONSE(response)), - expected)); + EXPECT_TRUE( + fl_value_equal(fl_value_get_list_value(response->value, 0), expected)); } TEST(UrlLauncherPlugin, CanLaunchFailureUnhandled) { - g_autoptr(FlValue) args = fl_value_new_string("madeup:scheme"); - g_autoptr(FlMethodResponse) response = can_launch(nullptr, args); + g_autoptr(FulUrlLauncherApiCanLaunchUrlResponse) response = + handle_can_launch_url("madeup:scheme", nullptr); ASSERT_NE(response, nullptr); - ASSERT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response)); + ASSERT_TRUE(fl_value_get_type(response->value) == FL_VALUE_TYPE_LIST); + ASSERT_TRUE(fl_value_get_length(response->value) == 1); g_autoptr(FlValue) expected = fl_value_new_bool(false); - EXPECT_TRUE(fl_value_equal(fl_method_success_response_get_result( - FL_METHOD_SUCCESS_RESPONSE(response)), - expected)); + EXPECT_TRUE( + fl_value_equal(fl_value_get_list_value(response->value, 0), expected)); } TEST(UrlLauncherPlugin, CanLaunchFileSuccess) { - g_autoptr(FlValue) args = fl_value_new_string("file:///"); - g_autoptr(FlMethodResponse) response = can_launch(nullptr, args); + g_autoptr(FulUrlLauncherApiCanLaunchUrlResponse) response = + handle_can_launch_url("file:///", nullptr); ASSERT_NE(response, nullptr); - ASSERT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response)); + ASSERT_TRUE(fl_value_get_type(response->value) == FL_VALUE_TYPE_LIST); + ASSERT_TRUE(fl_value_get_length(response->value) == 1); g_autoptr(FlValue) expected = fl_value_new_bool(true); - EXPECT_TRUE(fl_value_equal(fl_method_success_response_get_result( - FL_METHOD_SUCCESS_RESPONSE(response)), - expected)); + EXPECT_TRUE( + fl_value_equal(fl_value_get_list_value(response->value, 0), expected)); } TEST(UrlLauncherPlugin, CanLaunchFailureInvalidFileExtension) { - g_autoptr(FlValue) args = - fl_value_new_string("file:///madeup.madeupextension"); - g_autoptr(FlMethodResponse) response = can_launch(nullptr, args); + g_autoptr(FulUrlLauncherApiCanLaunchUrlResponse) response = + handle_can_launch_url("file:///madeup.madeupextension", nullptr); ASSERT_NE(response, nullptr); - ASSERT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response)); + ASSERT_TRUE(fl_value_get_type(response->value) == FL_VALUE_TYPE_LIST); + ASSERT_TRUE(fl_value_get_length(response->value) == 1); g_autoptr(FlValue) expected = fl_value_new_bool(false); - EXPECT_TRUE(fl_value_equal(fl_method_success_response_get_result( - FL_METHOD_SUCCESS_RESPONSE(response)), - expected)); + EXPECT_TRUE( + fl_value_equal(fl_value_get_list_value(response->value, 0), expected)); } // For consistency with the established mobile implementations, // an invalid URL should return false, not an error. TEST(UrlLauncherPlugin, CanLaunchFailureInvalidUrl) { - g_autoptr(FlValue) args = fl_value_new_string(""); - g_autoptr(FlMethodResponse) response = can_launch(nullptr, args); + g_autoptr(FulUrlLauncherApiCanLaunchUrlResponse) response = + handle_can_launch_url("", nullptr); ASSERT_NE(response, nullptr); - ASSERT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response)); + ASSERT_TRUE(fl_value_get_type(response->value) == FL_VALUE_TYPE_LIST); + ASSERT_TRUE(fl_value_get_length(response->value) == 1); g_autoptr(FlValue) expected = fl_value_new_bool(false); - EXPECT_TRUE(fl_value_equal(fl_method_success_response_get_result( - FL_METHOD_SUCCESS_RESPONSE(response)), - expected)); + EXPECT_TRUE( + fl_value_equal(fl_value_get_list_value(response->value, 0), expected)); } } // namespace test diff --git a/packages/url_launcher/url_launcher_linux/linux/url_launcher_plugin.cc b/packages/url_launcher/url_launcher_linux/linux/url_launcher_plugin.cc index b12b394516ed..0b814f8bad5d 100644 --- a/packages/url_launcher/url_launcher_linux/linux/url_launcher_plugin.cc +++ b/packages/url_launcher/url_launcher_linux/linux/url_launcher_plugin.cc @@ -9,21 +9,13 @@ #include +#include "messages.g.h" #include "url_launcher_plugin_private.h" -// See url_launcher_channel.dart for documentation. -const char kChannelName[] = "plugins.flutter.io/url_launcher_linux"; -const char kLaunchError[] = "Launch Error"; -const char kCanLaunchMethod[] = "canLaunch"; -const char kLaunchMethod[] = "launch"; - struct _FlUrlLauncherPlugin { GObject parent_instance; FlPluginRegistrar* registrar; - - // Connection to Flutter engine. - FlMethodChannel* channel; }; G_DEFINE_TYPE(FlUrlLauncherPlugin, fl_url_launcher_plugin, g_object_get_type()) @@ -38,9 +30,9 @@ static gboolean can_launch_uri_with_file_resource(FlUrlLauncherPlugin* self, return app_info != nullptr; } -// Called to check if a URL can be launched. -FlMethodResponse* can_launch(FlUrlLauncherPlugin* self, FlValue* args) { - const gchar* url = fl_value_get_string(args); +FulUrlLauncherApiCanLaunchUrlResponse* handle_can_launch_url( + const gchar* url, gpointer user_data) { + FlUrlLauncherPlugin* self = FL_URL_LAUNCHER_PLUGIN(user_data); gboolean is_launchable = FALSE; g_autofree gchar* scheme = g_uri_parse_scheme(url); @@ -54,13 +46,13 @@ FlMethodResponse* can_launch(FlUrlLauncherPlugin* self, FlValue* args) { } } - g_autoptr(FlValue) result = fl_value_new_bool(is_launchable); - return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); + return ful_url_launcher_api_can_launch_url_response_new(is_launchable); } // Called when a URL should launch. -static FlMethodResponse* launch(FlUrlLauncherPlugin* self, FlValue* args) { - const gchar* url = fl_value_get_string(args); +static FulUrlLauncherApiLaunchUrlResponse* handle_launch_url( + const gchar* url, gpointer user_data) { + FlUrlLauncherPlugin* self = FL_URL_LAUNCHER_PLUGIN(user_data); FlView* view = fl_plugin_registrar_get_view(self->registrar); g_autoptr(GError) error = nullptr; @@ -72,42 +64,18 @@ static FlMethodResponse* launch(FlUrlLauncherPlugin* self, FlValue* args) { launched = g_app_info_launch_default_for_uri(url, nullptr, &error); } if (!launched) { - g_autofree gchar* message = - g_strdup_printf("Failed to launch URL: %s", error->message); - return FL_METHOD_RESPONSE( - fl_method_error_response_new(kLaunchError, message, nullptr)); + return ful_url_launcher_api_launch_url_response_new(error->message); } - g_autoptr(FlValue) result = fl_value_new_bool(TRUE); - return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); -} - -// Called when a method call is received from Flutter. -static void method_call_cb(FlMethodChannel* channel, FlMethodCall* method_call, - gpointer user_data) { - FlUrlLauncherPlugin* self = FL_URL_LAUNCHER_PLUGIN(user_data); - - const gchar* method = fl_method_call_get_name(method_call); - FlValue* args = fl_method_call_get_args(method_call); - - g_autoptr(FlMethodResponse) response = nullptr; - if (strcmp(method, kCanLaunchMethod) == 0) - response = can_launch(self, args); - else if (strcmp(method, kLaunchMethod) == 0) - response = launch(self, args); - else - response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new()); - - g_autoptr(GError) error = nullptr; - if (!fl_method_call_respond(method_call, response, &error)) - g_warning("Failed to send method call response: %s", error->message); + return ful_url_launcher_api_launch_url_response_new(nullptr); } static void fl_url_launcher_plugin_dispose(GObject* object) { FlUrlLauncherPlugin* self = FL_URL_LAUNCHER_PLUGIN(object); + ful_url_launcher_api_clear_method_handlers( + fl_plugin_registrar_get_messenger(self->registrar), nullptr); g_clear_object(&self->registrar); - g_clear_object(&self->channel); G_OBJECT_CLASS(fl_url_launcher_plugin_parent_class)->dispose(object); } @@ -122,12 +90,13 @@ FlUrlLauncherPlugin* fl_url_launcher_plugin_new(FlPluginRegistrar* registrar) { self->registrar = FL_PLUGIN_REGISTRAR(g_object_ref(registrar)); - g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new(); - self->channel = - fl_method_channel_new(fl_plugin_registrar_get_messenger(registrar), - kChannelName, FL_METHOD_CODEC(codec)); - fl_method_channel_set_method_call_handler(self->channel, method_call_cb, - g_object_ref(self), g_object_unref); + static FulUrlLauncherApiVTable api_vtable = { + .can_launch_url = handle_can_launch_url, + .launch_url = handle_launch_url, + }; + ful_url_launcher_api_set_method_handlers( + fl_plugin_registrar_get_messenger(registrar), nullptr, &api_vtable, + g_object_ref(self), g_object_unref); return self; } diff --git a/packages/url_launcher/url_launcher_linux/linux/url_launcher_plugin_private.h b/packages/url_launcher/url_launcher_linux/linux/url_launcher_plugin_private.h index cde5242a8f47..9284ea80962e 100644 --- a/packages/url_launcher/url_launcher_linux/linux/url_launcher_plugin_private.h +++ b/packages/url_launcher/url_launcher_linux/linux/url_launcher_plugin_private.h @@ -5,10 +5,8 @@ #include #include "include/url_launcher_linux/url_launcher_plugin.h" +#include "messages.g.h" -// TODO(stuartmorgan): Remove this private header and change the below back to -// a static function once https://github.com/flutter/flutter/issues/88724 -// is fixed, and test through the public API instead. - -// Handles the canLaunch method call. -FlMethodResponse* can_launch(FlUrlLauncherPlugin* self, FlValue* args); +// Called to check if a URL can be launched. +FulUrlLauncherApiCanLaunchUrlResponse* handle_can_launch_url( + const gchar* url, gpointer user_data); diff --git a/packages/url_launcher/url_launcher_linux/pigeons/copyright.txt b/packages/url_launcher/url_launcher_linux/pigeons/copyright.txt new file mode 100644 index 000000000000..1236b63caf3a --- /dev/null +++ b/packages/url_launcher/url_launcher_linux/pigeons/copyright.txt @@ -0,0 +1,3 @@ +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. diff --git a/packages/url_launcher/url_launcher_linux/pigeons/messages.dart b/packages/url_launcher/url_launcher_linux/pigeons/messages.dart new file mode 100644 index 000000000000..56d30d75833e --- /dev/null +++ b/packages/url_launcher/url_launcher_linux/pigeons/messages.dart @@ -0,0 +1,21 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:pigeon/pigeon.dart'; + +@ConfigurePigeon(PigeonOptions( + dartOut: 'lib/src/messages.g.dart', + gobjectHeaderOut: 'linux/messages.g.h', + gobjectSourceOut: 'linux/messages.g.cc', + gobjectOptions: GObjectOptions(module: 'Ful'), + copyrightHeader: 'pigeons/copyright.txt', +)) +@HostApi() +abstract class UrlLauncherApi { + /// Returns true if the URL can definitely be launched. + bool canLaunchUrl(String url); + + /// Opens the URL externally, returning an error string on failure. + String? launchUrl(String url); +} diff --git a/packages/url_launcher/url_launcher_linux/pubspec.yaml b/packages/url_launcher/url_launcher_linux/pubspec.yaml index cbc6013cd4e0..61ddf111c5be 100644 --- a/packages/url_launcher/url_launcher_linux/pubspec.yaml +++ b/packages/url_launcher/url_launcher_linux/pubspec.yaml @@ -2,11 +2,11 @@ name: url_launcher_linux description: Linux implementation of the url_launcher plugin. repository: https://github.com/flutter/packages/tree/main/packages/url_launcher/url_launcher_linux issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22 -version: 3.1.1 +version: 3.2.0 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -24,6 +24,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter + pigeon: ^21.1.0 test: ^1.16.3 topics: diff --git a/packages/url_launcher/url_launcher_linux/test/url_launcher_linux_test.dart b/packages/url_launcher/url_launcher_linux/test/url_launcher_linux_test.dart index 7a16d9fc0edc..bf2a70195542 100644 --- a/packages/url_launcher/url_launcher_linux/test/url_launcher_linux_test.dart +++ b/packages/url_launcher/url_launcher_linux/test/url_launcher_linux_test.dart @@ -4,71 +4,42 @@ import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:url_launcher_linux/src/messages.g.dart'; import 'package:url_launcher_linux/url_launcher_linux.dart'; import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart'; void main() { - TestWidgetsFlutterBinding.ensureInitialized(); - group('UrlLauncherLinux', () { - const MethodChannel channel = - MethodChannel('plugins.flutter.io/url_launcher_linux'); - final List log = []; - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - log.add(methodCall); - - // Return null explicitly instead of relying on the implicit null - // returned by the method channel if no return statement is specified. - return null; - }); - - tearDown(() { - log.clear(); - }); - test('registers instance', () { UrlLauncherLinux.registerWith(); expect(UrlLauncherPlatform.instance, isA()); }); - test('canLaunch', () async { - final UrlLauncherLinux launcher = UrlLauncherLinux(); - await launcher.canLaunch('http://example.com/'); - expect( - log, - [isMethodCall('canLaunch', arguments: 'http://example.com/')], - ); + test('canLaunch passes true', () async { + final _FakeUrlLauncherApi api = _FakeUrlLauncherApi(); + final UrlLauncherLinux launcher = UrlLauncherLinux(api: api); + + final bool canLaunch = await launcher.canLaunch('http://example.com/'); + + expect(canLaunch, true); }); - test('canLaunch should return false if platform returns null', () async { - final UrlLauncherLinux launcher = UrlLauncherLinux(); + test('canLaunch passes false', () async { + final _FakeUrlLauncherApi api = _FakeUrlLauncherApi(canLaunch: false); + final UrlLauncherLinux launcher = UrlLauncherLinux(api: api); + final bool canLaunch = await launcher.canLaunch('http://example.com/'); expect(canLaunch, false); }); test('launch', () async { - final UrlLauncherLinux launcher = UrlLauncherLinux(); - await launcher.launch( - 'http://example.com/', - useSafariVC: true, - useWebView: false, - enableJavaScript: false, - enableDomStorage: false, - universalLinksOnly: false, - headers: const {}, - ); - expect( - log, - [isMethodCall('launch', arguments: 'http://example.com/')], - ); - }); + final _FakeUrlLauncherApi api = _FakeUrlLauncherApi(); + final UrlLauncherLinux launcher = UrlLauncherLinux(api: api); + const String url = 'http://example.com/'; - test('launch should return false if platform returns null', () async { - final UrlLauncherLinux launcher = UrlLauncherLinux(); final bool launched = await launcher.launch( - 'http://example.com/', + url, useSafariVC: true, useWebView: false, enableJavaScript: false, @@ -77,25 +48,53 @@ void main() { headers: const {}, ); - expect(launched, false); + expect(launched, true); + expect(api.argument, url); + }); + + test('launch should throw if platform returns an error', () async { + final _FakeUrlLauncherApi api = _FakeUrlLauncherApi(error: 'An error'); + final UrlLauncherLinux launcher = UrlLauncherLinux(api: api); + + await expectLater( + launcher.launch( + 'http://example.com/', + useSafariVC: true, + useWebView: false, + enableJavaScript: false, + enableDomStorage: false, + universalLinksOnly: false, + headers: const {}, + ), + throwsA(isA() + .having((PlatformException e) => e.code, 'code', 'Launch Error') + .having((PlatformException e) => e.message, 'message', + contains('Failed to launch URL: An error')))); }); group('launchUrl', () { test('passes URL', () async { - final UrlLauncherLinux launcher = UrlLauncherLinux(); - await launcher.launchUrl('http://example.com/', const LaunchOptions()); - expect( - log, - [isMethodCall('launch', arguments: 'http://example.com/')], - ); + final _FakeUrlLauncherApi api = _FakeUrlLauncherApi(); + final UrlLauncherLinux launcher = UrlLauncherLinux(api: api); + const String url = 'http://example.com/'; + + final bool launched = + await launcher.launchUrl(url, const LaunchOptions()); + + expect(launched, true); + expect(api.argument, url); }); - test('returns false if platform returns null', () async { - final UrlLauncherLinux launcher = UrlLauncherLinux(); - final bool launched = await launcher.launchUrl( - 'http://example.com/', const LaunchOptions()); + test('throws if platform returns an error', () async { + final _FakeUrlLauncherApi api = _FakeUrlLauncherApi(error: 'An error'); + final UrlLauncherLinux launcher = UrlLauncherLinux(api: api); - expect(launched, false); + await expectLater( + launcher.launchUrl('http://example.com/', const LaunchOptions()), + throwsA(isA() + .having((PlatformException e) => e.code, 'code', 'Launch Error') + .having((PlatformException e) => e.message, 'message', + contains('Failed to launch URL: An error')))); }); }); @@ -141,3 +140,28 @@ void main() { }); }); } + +class _FakeUrlLauncherApi implements UrlLauncherApi { + _FakeUrlLauncherApi({this.canLaunch = true, this.error}); + + /// The value to return from canLaunch. + final bool canLaunch; + + /// The error to return from launchUrl, if any. + final String? error; + + /// The argument that was passed to an API call. + String? argument; + + @override + Future canLaunchUrl(String url) async { + argument = url; + return canLaunch; + } + + @override + Future launchUrl(String url) async { + argument = url; + return error; + } +} diff --git a/packages/url_launcher/url_launcher_macos/CHANGELOG.md b/packages/url_launcher/url_launcher_macos/CHANGELOG.md index f60deea990ff..2dcb75263873 100644 --- a/packages/url_launcher/url_launcher_macos/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_macos/CHANGELOG.md @@ -1,6 +1,7 @@ -## NEXT +## 3.2.1 -* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. +* Adds privacy manifest. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 3.2.0 diff --git a/packages/url_launcher/url_launcher_macos/README.md b/packages/url_launcher/url_launcher_macos/README.md index c164ddeecc45..adfcfcd8b0d0 100644 --- a/packages/url_launcher/url_launcher_macos/README.md +++ b/packages/url_launcher/url_launcher_macos/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/url_launcher -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/url_launcher/url_launcher_macos/example/macos/Podfile b/packages/url_launcher/url_launcher_macos/example/macos/Podfile index 47c1b18fedae..dd603efb9895 100644 --- a/packages/url_launcher/url_launcher_macos/example/macos/Podfile +++ b/packages/url_launcher/url_launcher_macos/example/macos/Podfile @@ -28,7 +28,6 @@ flutter_macos_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) diff --git a/packages/url_launcher/url_launcher_macos/example/pubspec.yaml b/packages/url_launcher/url_launcher_macos/example/pubspec.yaml index 6b3d81648ad8..4fa890968d27 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/url_launcher/url_launcher_macos/macos/url_launcher_macos.podspec b/packages/url_launcher/url_launcher_macos/macos/url_launcher_macos.podspec index de18c66e7d0d..a7f88852d2c4 100644 --- a/packages/url_launcher/url_launcher_macos/macos/url_launcher_macos.podspec +++ b/packages/url_launcher/url_launcher_macos/macos/url_launcher_macos.podspec @@ -13,6 +13,7 @@ Pod::Spec.new do |s| s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } s.source = { :http => 'https://github.com/flutter/packages/tree/main/packages/url_launcher/url_launcher_macos' } s.source_files = 'url_launcher_macos/Sources/url_launcher_macos/**/*.swift' + s.resource_bundles = {'url_launcher_macos_privacy' => ['url_launcher_macos/Sources/url_launcher_macos/Resources/PrivacyInfo.xcprivacy']} s.dependency 'FlutterMacOS' s.platform = :osx, '10.14' diff --git a/packages/url_launcher/url_launcher_macos/macos/url_launcher_macos/Sources/url_launcher_macos/Resources/.gitkeep b/packages/url_launcher/url_launcher_macos/macos/url_launcher_macos/Sources/url_launcher_macos/Resources/.gitkeep deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/packages/url_launcher/url_launcher_macos/macos/url_launcher_macos/Sources/url_launcher_macos/Resources/PrivacyInfo.xcprivacy b/packages/url_launcher/url_launcher_macos/macos/url_launcher_macos/Sources/url_launcher_macos/Resources/PrivacyInfo.xcprivacy new file mode 100644 index 000000000000..918d80be4306 --- /dev/null +++ b/packages/url_launcher/url_launcher_macos/macos/url_launcher_macos/Sources/url_launcher_macos/Resources/PrivacyInfo.xcprivacy @@ -0,0 +1,12 @@ + + + + + NSPrivacyTrackingDomains + + NSPrivacyCollectedDataTypes + + NSPrivacyTracking + + + diff --git a/packages/url_launcher/url_launcher_macos/pubspec.yaml b/packages/url_launcher/url_launcher_macos/pubspec.yaml index ab5a9250d409..d5e29fc0e9d5 100644 --- a/packages/url_launcher/url_launcher_macos/pubspec.yaml +++ b/packages/url_launcher/url_launcher_macos/pubspec.yaml @@ -2,11 +2,11 @@ name: url_launcher_macos description: macOS implementation of the url_launcher plugin. repository: https://github.com/flutter/packages/tree/main/packages/url_launcher/url_launcher_macos issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22 -version: 3.2.0 +version: 3.2.1 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.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 d4dd358a0ee2..680ce1a23db8 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.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 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 20b7b2d71313..b31502a3d6c5 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: @@ -18,7 +18,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 topics: - links diff --git a/packages/url_launcher/url_launcher_web/CHANGELOG.md b/packages/url_launcher/url_launcher_web/CHANGELOG.md index ca4d9d86cc66..b891293c005f 100644 --- a/packages/url_launcher/url_launcher_web/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_web/CHANGELOG.md @@ -1,3 +1,11 @@ +## 2.3.3 + +* Changes `launchUrl` so it always returns `true`, except for disallowed URL schemes. + +## 2.3.2 + +* Adds support for `web: ^1.0.0`. + ## 2.3.1 * Implements correct handling of keyboard events with Link. diff --git a/packages/url_launcher/url_launcher_web/README.md b/packages/url_launcher/url_launcher_web/README.md index f186d7a49bb8..6853a6ccc538 100644 --- a/packages/url_launcher/url_launcher_web/README.md +++ b/packages/url_launcher/url_launcher_web/README.md @@ -12,7 +12,7 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/url_launcher -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin ## Limitations on the Web platform @@ -30,4 +30,14 @@ In such cases, you can use the `webOnlyWindowName` parameter, setting it to `_self`, to open the URL within the current tab. Another approach is to ensure that the `uri` is synchronously ready. -Read more: MDN > [Transient activation](https://developer.mozilla.org/en-US/docs/Glossary/Transient_activation). \ No newline at end of file +Read more: MDN > [Transient activation](https://developer.mozilla.org/en-US/docs/Glossary/Transient_activation). + +### Method `launchUrl` always returns `true` for allowed schemes + +The `launchUrl` method always returns `true` on the web platform for allowed +schemes. This is because URLs are opened in a new window using the `noopener` +window feature. When the `noopener` feature is used, the browser does not +return any information that can be used to determine if the link was +successfully opened. + +Read more: MDN > [window.open](https://developer.mozilla.org/en-US/docs/Web/API/Window/open#noopener). \ No newline at end of file diff --git a/packages/url_launcher/url_launcher_web/example/README.md b/packages/url_launcher/url_launcher_web/example/README.md index 4a01887de7fb..932e9f227cbe 100644 --- a/packages/url_launcher/url_launcher_web/example/README.md +++ b/packages/url_launcher/url_launcher_web/example/README.md @@ -15,5 +15,5 @@ This package uses `package:integration_test` to run its tests in a web browser. See [Plugin Tests > Web Tests](https://github.com/flutter/flutter/blob/master/docs/ecosystem/testing/Plugin-Tests.md#web-tests) in the Flutter documentation for instructions to set up and run the tests in this package. -Check [flutter.dev > Integration testing](https://flutter.dev/docs/testing/integration-tests) +Check [flutter.dev > Integration testing](https://docs.flutter.dev/testing/integration-tests) for more info. diff --git a/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart index b75903873467..00b74cd6f59c 100644 --- a/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart +++ b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart @@ -120,6 +120,15 @@ void main() { (WidgetTester _) async { expect(plugin.launch('javascript:alert("1")'), completion(isFalse)); }); + + testWidgets('launching a unknown sceheme returns true', + (WidgetTester _) async { + expect( + plugin.launch( + 'foo:bar', + ), + completion(isTrue)); + }); }); group('openNewWindow', () { diff --git a/packages/url_launcher/url_launcher_web/example/pubspec.yaml b/packages/url_launcher/url_launcher_web/example/pubspec.yaml index c87511dd84b8..606f477b4a40 100644 --- a/packages/url_launcher/url_launcher_web/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/example/pubspec.yaml @@ -14,8 +14,8 @@ dev_dependencies: sdk: flutter integration_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 url_launcher_platform_interface: ^2.2.0 url_launcher_web: path: ../ - web: ^0.5.0 + web: ^1.0.0 diff --git a/packages/url_launcher/url_launcher_web/example/web/index.html b/packages/url_launcher/url_launcher_web/example/web/index.html index dc9f89762aec..7836d612c4e0 100644 --- a/packages/url_launcher/url_launcher_web/example/web/index.html +++ b/packages/url_launcher/url_launcher_web/example/web/index.html @@ -7,6 +7,6 @@ Browser Tests - + diff --git a/packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart b/packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart index 070852db4c3e..b3de107d4368 100644 --- a/packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart +++ b/packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart @@ -66,9 +66,12 @@ class UrlLauncherPlugin extends UrlLauncherPlatform { /// Opens the given [url] in the specified [webOnlyWindowName]. /// - /// Returns the newly created window. + /// Always returns `true`, except for disallowed schemes. Because `noopener` + /// is used as a window feature, it can not be detected if the window was + /// opened successfully. + /// See https://html.spec.whatwg.org/multipage/nav-history-apis.html#window-open-steps. @visibleForTesting - html.Window? openNewWindow(String url, {String? webOnlyWindowName}) { + bool openNewWindow(String url, {String? webOnlyWindowName}) { final String? scheme = _getUrlScheme(url); // Actively disallow opening some schemes, like javascript. // See https://github.com/flutter/flutter/issues/136657 @@ -76,15 +79,16 @@ class UrlLauncherPlugin extends UrlLauncherPlatform { if (kDebugMode) { print('Disallowed URL with scheme: $scheme'); } - return null; + return false; } // Some schemes need to be opened on the _top window context on Safari. // See https://github.com/flutter/flutter/issues/51461 final String target = webOnlyWindowName ?? ((_isSafari && _isSafariTargetTopScheme(scheme)) ? '_top' : ''); - // ignore: unsafe_html - return _window.open(url, target, 'noopener,noreferrer'); + _window.open(url, target, 'noopener,noreferrer'); + + return true; } @override @@ -109,7 +113,7 @@ class UrlLauncherPlugin extends UrlLauncherPlatform { @override Future launchUrl(String url, LaunchOptions options) async { final String? windowName = options.webOnlyWindowName; - return openNewWindow(url, webOnlyWindowName: windowName) != null; + return openNewWindow(url, webOnlyWindowName: windowName); } @override diff --git a/packages/url_launcher/url_launcher_web/pubspec.yaml b/packages/url_launcher/url_launcher_web/pubspec.yaml index 51f320a32a5e..3730a4dd90e4 100644 --- a/packages/url_launcher/url_launcher_web/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/pubspec.yaml @@ -2,7 +2,7 @@ name: url_launcher_web description: Web platform implementation of url_launcher repository: https://github.com/flutter/packages/tree/main/packages/url_launcher/url_launcher_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22 -version: 2.3.1 +version: 2.3.3 environment: sdk: ^3.3.0 @@ -22,7 +22,7 @@ dependencies: flutter_web_plugins: sdk: flutter url_launcher_platform_interface: ^2.2.0 - web: ^0.5.0 + web: ">=0.5.1 <2.0.0" dev_dependencies: flutter_test: diff --git a/packages/url_launcher/url_launcher_windows/CHANGELOG.md b/packages/url_launcher/url_launcher_windows/CHANGELOG.md index 978a224433d0..668ee6eff6ac 100644 --- a/packages/url_launcher/url_launcher_windows/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_windows/CHANGELOG.md @@ -1,5 +1,11 @@ -## NEXT +## 3.1.3 +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Fixes handling of `file:` URLs that contain UTF-8 encoded paths. + +## 3.1.2 + +* Updates to pigeon 21. * Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. ## 3.1.1 diff --git a/packages/url_launcher/url_launcher_windows/README.md b/packages/url_launcher/url_launcher_windows/README.md index 4f10def5c4a9..cc31e7e7cc98 100644 --- a/packages/url_launcher/url_launcher_windows/README.md +++ b/packages/url_launcher/url_launcher_windows/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/url_launcher -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/url_launcher/url_launcher_windows/example/pubspec.yaml b/packages/url_launcher/url_launcher_windows/example/pubspec.yaml index b6b6db363212..d76188c383ec 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/url_launcher/url_launcher_windows/lib/src/messages.g.dart b/packages/url_launcher/url_launcher_windows/lib/src/messages.g.dart index 2d84f683abac..f076f3ecc99c 100644 --- a/packages/url_launcher/url_launcher_windows/lib/src/messages.g.dart +++ b/packages/url_launcher/url_launcher_windows/lib/src/messages.g.dart @@ -1,9 +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 (v13.0.0), do not edit directly. +// Autogenerated from Pigeon (v21.0.0), 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 +// 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 import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; @@ -11,80 +11,87 @@ import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; import 'package:flutter/services.dart'; -List wrapResponse( - {Object? result, PlatformException? error, bool empty = false}) { - if (empty) { - return []; - } - if (error == null) { - return [result]; - } - return [error.code, error.message, error.details]; +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); +} + +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); } class UrlLauncherApi { /// Constructor for [UrlLauncherApi]. 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. - UrlLauncherApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; + UrlLauncherApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : __pigeon_binaryMessenger = binaryMessenger, + __pigeon_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? __pigeon_binaryMessenger; - static const MessageCodec codec = StandardMessageCodec(); + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - Future canLaunchUrl(String arg_url) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.url_launcher_windows.UrlLauncherApi.canLaunchUrl', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_url]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + final String __pigeon_messageChannelSuffix; + + Future canLaunchUrl(String url) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.url_launcher_windows.UrlLauncherApi.canLaunchUrl$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([url]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); - } else if (replyList[0] == null) { + } else if (__pigeon_replyList[0] == null) { throw PlatformException( code: 'null-error', message: 'Host platform returned null value for non-null return value.', ); } else { - return (replyList[0] as bool?)!; + return (__pigeon_replyList[0] as bool?)!; } } - Future launchUrl(String arg_url) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.url_launcher_windows.UrlLauncherApi.launchUrl', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_url]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future launchUrl(String url) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.url_launcher_windows.UrlLauncherApi.launchUrl$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([url]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); - } else if (replyList[0] == null) { + } else if (__pigeon_replyList[0] == null) { throw PlatformException( code: 'null-error', message: 'Host platform returned null value for non-null return value.', ); } else { - return (replyList[0] as bool?)!; + return (__pigeon_replyList[0] as bool?)!; } } } diff --git a/packages/url_launcher/url_launcher_windows/pubspec.yaml b/packages/url_launcher/url_launcher_windows/pubspec.yaml index 214806e482a6..629e9dc71963 100644 --- a/packages/url_launcher/url_launcher_windows/pubspec.yaml +++ b/packages/url_launcher/url_launcher_windows/pubspec.yaml @@ -2,11 +2,11 @@ name: url_launcher_windows description: Windows implementation of the url_launcher plugin. repository: https://github.com/flutter/packages/tree/main/packages/url_launcher/url_launcher_windows issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22 -version: 3.1.1 +version: 3.1.3 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -24,7 +24,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - pigeon: ^13.0.0 + pigeon: ^21.0.0 test: ^1.16.3 topics: diff --git a/packages/url_launcher/url_launcher_windows/windows/CMakeLists.txt b/packages/url_launcher/url_launcher_windows/windows/CMakeLists.txt index da39522c5625..2b07f3a75a0b 100644 --- a/packages/url_launcher/url_launcher_windows/windows/CMakeLists.txt +++ b/packages/url_launcher/url_launcher_windows/windows/CMakeLists.txt @@ -25,7 +25,7 @@ set_target_properties(${PLUGIN_NAME} PROPERTIES CXX_VISIBILITY_PRESET hidden) target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL) target_include_directories(${PLUGIN_NAME} INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include") -target_link_libraries(${PLUGIN_NAME} PRIVATE flutter flutter_wrapper_plugin) +target_link_libraries(${PLUGIN_NAME} PRIVATE flutter flutter_wrapper_plugin shlwapi.lib) # List of absolute paths to libraries that should be bundled with the plugin set(file_chooser_bundled_libraries @@ -62,7 +62,7 @@ add_executable(${TEST_RUNNER} ) apply_standard_settings(${TEST_RUNNER}) target_include_directories(${TEST_RUNNER} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}") -target_link_libraries(${TEST_RUNNER} PRIVATE flutter_wrapper_plugin) +target_link_libraries(${TEST_RUNNER} PRIVATE flutter_wrapper_plugin shlwapi.lib) target_link_libraries(${TEST_RUNNER} PRIVATE gtest_main gmock) # flutter_wrapper_plugin has link dependencies on the Flutter DLL. add_custom_command(TARGET ${TEST_RUNNER} POST_BUILD diff --git a/packages/url_launcher/url_launcher_windows/windows/messages.g.cpp b/packages/url_launcher/url_launcher_windows/windows/messages.g.cpp index 43c6254a2a44..babca59ffecb 100644 --- a/packages/url_launcher/url_launcher_windows/windows/messages.g.cpp +++ b/packages/url_launcher/url_launcher_windows/windows/messages.g.cpp @@ -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 (v13.0.0), do not edit directly. +// Autogenerated from Pigeon (v21.0.0), do not edit directly. // See also: https://pub.dev/packages/pigeon #undef _HAS_EXCEPTIONS @@ -24,23 +24,53 @@ using flutter::EncodableList; using flutter::EncodableMap; using flutter::EncodableValue; +FlutterError CreateConnectionError(const std::string channel_name) { + return FlutterError( + "channel-error", + "Unable to establish connection on channel: '" + channel_name + "'.", + EncodableValue("")); +} + +PigeonCodecSerializer::PigeonCodecSerializer() {} + +EncodableValue PigeonCodecSerializer::ReadValueOfType( + uint8_t type, flutter::ByteStreamReader* stream) const { + return flutter::StandardCodecSerializer::ReadValueOfType(type, stream); +} + +void PigeonCodecSerializer::WriteValue( + const EncodableValue& value, flutter::ByteStreamWriter* stream) const { + flutter::StandardCodecSerializer::WriteValue(value, stream); +} + /// The codec used by UrlLauncherApi. const flutter::StandardMessageCodec& UrlLauncherApi::GetCodec() { return flutter::StandardMessageCodec::GetInstance( - &flutter::StandardCodecSerializer::GetInstance()); + &PigeonCodecSerializer::GetInstance()); } // Sets up an instance of `UrlLauncherApi` to handle messages through the // `binary_messenger`. void UrlLauncherApi::SetUp(flutter::BinaryMessenger* binary_messenger, UrlLauncherApi* api) { + UrlLauncherApi::SetUp(binary_messenger, api, ""); +} + +void UrlLauncherApi::SetUp(flutter::BinaryMessenger* binary_messenger, + UrlLauncherApi* api, + const std::string& message_channel_suffix) { + const std::string prepended_suffix = + message_channel_suffix.length() > 0 + ? std::string(".") + message_channel_suffix + : ""; { - auto channel = std::make_unique>( + BasicMessageChannel<> channel( binary_messenger, - "dev.flutter.pigeon.url_launcher_windows.UrlLauncherApi.canLaunchUrl", + "dev.flutter.pigeon.url_launcher_windows.UrlLauncherApi.canLaunchUrl" + + prepended_suffix, &GetCodec()); if (api != nullptr) { - channel->SetMessageHandler( + channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { @@ -64,16 +94,17 @@ void UrlLauncherApi::SetUp(flutter::BinaryMessenger* binary_messenger, } }); } else { - channel->SetMessageHandler(nullptr); + channel.SetMessageHandler(nullptr); } } { - auto channel = std::make_unique>( + BasicMessageChannel<> channel( binary_messenger, - "dev.flutter.pigeon.url_launcher_windows.UrlLauncherApi.launchUrl", + "dev.flutter.pigeon.url_launcher_windows.UrlLauncherApi.launchUrl" + + prepended_suffix, &GetCodec()); if (api != nullptr) { - channel->SetMessageHandler( + channel.SetMessageHandler( [api](const EncodableValue& message, const flutter::MessageReply& reply) { try { @@ -97,7 +128,7 @@ void UrlLauncherApi::SetUp(flutter::BinaryMessenger* binary_messenger, } }); } else { - channel->SetMessageHandler(nullptr); + channel.SetMessageHandler(nullptr); } } } diff --git a/packages/url_launcher/url_launcher_windows/windows/messages.g.h b/packages/url_launcher/url_launcher_windows/windows/messages.g.h index f725b019aad0..c940969f9d25 100644 --- a/packages/url_launcher/url_launcher_windows/windows/messages.g.h +++ b/packages/url_launcher/url_launcher_windows/windows/messages.g.h @@ -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 (v13.0.0), do not edit directly. +// Autogenerated from Pigeon (v21.0.0), do not edit directly. // See also: https://pub.dev/packages/pigeon #ifndef PIGEON_MESSAGES_G_H_ @@ -58,6 +58,22 @@ class ErrorOr { std::variant v_; }; +class PigeonCodecSerializer : public flutter::StandardCodecSerializer { + public: + PigeonCodecSerializer(); + inline static PigeonCodecSerializer& GetInstance() { + static PigeonCodecSerializer sInstance; + return sInstance; + } + + void WriteValue(const flutter::EncodableValue& value, + flutter::ByteStreamWriter* stream) const override; + + protected: + flutter::EncodableValue ReadValueOfType( + uint8_t type, flutter::ByteStreamReader* stream) const override; +}; + // Generated interface from Pigeon that represents a handler of messages from // Flutter. class UrlLauncherApi { @@ -74,6 +90,9 @@ class UrlLauncherApi { // `binary_messenger`. static void SetUp(flutter::BinaryMessenger* binary_messenger, UrlLauncherApi* api); + static void SetUp(flutter::BinaryMessenger* binary_messenger, + UrlLauncherApi* api, + const std::string& message_channel_suffix); static flutter::EncodableValue WrapError(std::string_view error_message); static flutter::EncodableValue WrapError(const FlutterError& error); diff --git a/packages/url_launcher/url_launcher_windows/windows/test/url_launcher_windows_test.cpp b/packages/url_launcher/url_launcher_windows/windows/test/url_launcher_windows_test.cpp index 267295740006..db46e1a4a983 100644 --- a/packages/url_launcher/url_launcher_windows/windows/test/url_launcher_windows_test.cpp +++ b/packages/url_launcher/url_launcher_windows/windows/test/url_launcher_windows_test.cpp @@ -22,10 +22,12 @@ namespace { using flutter::EncodableMap; using flutter::EncodableValue; +using ::testing::_; using ::testing::DoAll; using ::testing::Pointee; using ::testing::Return; using ::testing::SetArgPointee; +using ::testing::StrEq; class MockSystemApis : public SystemApis { public: @@ -135,5 +137,28 @@ TEST(UrlLauncherPlugin, LaunchReportsError) { EXPECT_TRUE(result.has_error()); } +TEST(UrlLauncherPlugin, LaunchUTF8EncodedFileURLSuccess) { + std::unique_ptr system = std::make_unique(); + + // Return a success value (>32) from launching. + EXPECT_CALL( + *system, + ShellExecuteW( + _, StrEq(L"open"), + // 家の管理/スキャナ"), + StrEq( + L"file:///G:/\x5bb6\x306e\x7ba1\x7406/\x30b9\x30ad\x30e3\x30ca"), + _, _, _)) + .WillOnce(Return(reinterpret_cast(33))); + + UrlLauncherPlugin plugin(std::move(system)); + ErrorOr result = plugin.LaunchUrl( + "file:///G:/%E5%AE%B6%E3%81%AE%E7%AE%A1%E7%90%86/" + "%E3%82%B9%E3%82%AD%E3%83%A3%E3%83%8A"); + + ASSERT_FALSE(result.has_error()); + EXPECT_TRUE(result.value()); +} + } // namespace test } // namespace url_launcher_windows diff --git a/packages/url_launcher/url_launcher_windows/windows/url_launcher_plugin.cpp b/packages/url_launcher/url_launcher_windows/windows/url_launcher_plugin.cpp index c8e7b2f516cb..b737b4579b8b 100644 --- a/packages/url_launcher/url_launcher_windows/windows/url_launcher_plugin.cpp +++ b/packages/url_launcher/url_launcher_windows/windows/url_launcher_plugin.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -98,7 +99,19 @@ ErrorOr UrlLauncherPlugin::CanLaunchUrl(const std::string& url) { } ErrorOr UrlLauncherPlugin::LaunchUrl(const std::string& url) { - std::wstring url_wide = Utf16FromUtf8(url); + std::wstring url_wide; + if (url.find("file:") == 0) { + // ShellExecuteW does not process %-encoded UTF8 strings in file URLs. + DWORD unescaped_len = 0; + std::string unescaped_url = url; + if (FAILED(::UrlUnescapeA(unescaped_url.data(), /*pszUnescaped=*/nullptr, + &unescaped_len, URL_UNESCAPE_INPLACE))) { + return FlutterError("open_error", "Failed to unescape file URL"); + } + url_wide = Utf16FromUtf8(unescaped_url); + } else { + url_wide = Utf16FromUtf8(url); + } int status = static_cast(reinterpret_cast( system_apis_->ShellExecuteW(nullptr, TEXT("open"), url_wide.c_str(), diff --git a/packages/vector_graphics/.metadata b/packages/vector_graphics/.metadata new file mode 100644 index 000000000000..6281e523b245 --- /dev/null +++ b/packages/vector_graphics/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: a7790d8e3a6c1810b8ce77cc9339d8b30ff68019 + channel: unknown + +project_type: package diff --git a/packages/vector_graphics/AUTHORS b/packages/vector_graphics/AUTHORS new file mode 100644 index 000000000000..557dff97933b --- /dev/null +++ b/packages/vector_graphics/AUTHORS @@ -0,0 +1,6 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. diff --git a/packages/vector_graphics/CHANGELOG.md b/packages/vector_graphics/CHANGELOG.md new file mode 100644 index 000000000000..a51da2ef8737 --- /dev/null +++ b/packages/vector_graphics/CHANGELOG.md @@ -0,0 +1,140 @@ +## 1.1.14 + +* Relaxes dependency constraint on vector_graphics_codec. + +## 1.1.13 + +* Fix execution on the web with WebAssembly. + +## 1.1.12 + +* Transfers the package source from https://github.com/dnfield/vector_graphics + to https://github.com/flutter/packages. + +## 1.1.11+1 + +* Relax package:http constraint. + +## 1.1.11 + +* Use package:http to drop dependency on dart:html. + +## 1.1.10+1 + +* Add missing save before clip. + +## 1.1.10 + +* Add missing clip before saveLayer. + +## 1.1.9+2 + +* Fix case sensitivity on scientific notation parsing. + +## 1.1.9+1 + +* Fix publication error that did not have latest source code. + +## 1.1.9 + +* Fix handling of invalid XML `@id` attributes. +* Fix handling of self-referential `` elements. +* Add `--out-dir` option to compiler. +* Tweak warning message for unhandled eleemnts. + +## 1.1.8 + +* Fix bugs in transform parsing. + +## 1.1.7 + +* Support for matching the ambient text direction. + +## 1.1.6 + +* Fix bug in text position computation when transforms are involved. + +## 1.1.5+1 + +* Remove/update some invalid assertions related to image formats. + +## 1.1.5 + +* Support for decoding control points as IEEE 754-2008 half precision + floating point values. +* Migrate the test to extend DefaultWidgetsLocalizations. +* Added an error builder property to provide a fallback widget on exceptions. + +## 1.1.4 + +* Support more image formats and malformed MIME types. +* Fix inheritence for `fill-rule`s. + +## 1.1.3 + +* Further improvements to whitespace handling for text. + +## 1.1.2 + +* Fix handling and inheritence of `none`. + +## 1.1.1 + +* Multiple text positioning bug fixes. +* Preserve stroke-opacity when specified. + +## 1.1.0 + +* Fix a number of inheritence related bugs: + * Inheritence of properties specified on the root element now work. + * Opacity inheritence is more correct now. + * Inheritence of `use` elements is more correctly handled. +* Make `currentColor` non-null on SVG theme, and fix how it is applied. +* Remove the opacity peephole optimizer, which was incorrectly applying + optimizations in a few cases. A future release may add this back. +* Add clipBehavior to the widget. +* Fix patterns when multiple patterns are specified and applied within the + graphic. + +## 1.0.1+1 + +* Fix bug in asset loading from packages. + +## 1.0.1 + +* Fix handling of fill colors on use/group elements. + +## 1.0.0+1 + +* Fix issue in pattern decoding. +* Fix issue in matrix parsing for some combinations of matrices. + +## 1.0.0 + +* Stable release. +* Use `ImageCache` for images. +* Bug fixes for image rendering. +* Better support for synchronous usage in testing. +* Make clipping the viewbox optional. + +## 0.0.3 + +* Improvements to CLI utilities. +* Dispose unused objects. +* Improved support for HTML backend. +* Less aggressive rasterization strategy for flutter_svg compatibility. + +## 0.0.2 + +* Support for drawing images + +## 0.0.1 + +* Added `VectorGraphic` which consumes encoded vector graphics assets using + a `BytesLoader`. +* Added `AssetBytesLoader` and `NetworkBytesLoader` as example loader + implementations. + +## 0.0.0 + +* Create repository diff --git a/packages/vector_graphics/LICENSE b/packages/vector_graphics/LICENSE new file mode 100644 index 000000000000..c6823b81eb84 --- /dev/null +++ b/packages/vector_graphics/LICENSE @@ -0,0 +1,25 @@ +Copyright 2013 The Flutter Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/vector_graphics/README.md b/packages/vector_graphics/README.md new file mode 100644 index 000000000000..e7370543320a --- /dev/null +++ b/packages/vector_graphics/README.md @@ -0,0 +1,14 @@ +# vector_graphics + +A vector graphics rendering runtime for Flutter. This package is intended for +use with output from the `package:vector_graphics_compiler` and encoded via +a tightly coupled version of `package:vector_graphics_codec`. + +## Commemoration + +This package was originally authored by +[Dan Field](https://github.com/dnfield) and has been forked here +from [dnfield/vector_graphics](https://github.com/dnfield/vector_graphics). +Dan was a member of the Flutter team at Google from 2018 until his death +in 2024. Dan’s impact and contributions to Flutter were immeasurable, and we +honor his memory by continuing to publish and maintain this package. diff --git a/packages/vector_graphics/example/.gitignore b/packages/vector_graphics/example/.gitignore new file mode 100644 index 000000000000..15183f48bcb6 --- /dev/null +++ b/packages/vector_graphics/example/.gitignore @@ -0,0 +1,61 @@ +android/ +ios/ +macos/ +linux/ +windows/ +web/ +test/ +android/ +ios/ +macos/ +linux/ +windows/ +web/ +test/ +.metadata + +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/packages/vector_graphics/example/README.md b/packages/vector_graphics/example/README.md new file mode 100644 index 000000000000..92c5ae6a3e30 --- /dev/null +++ b/packages/vector_graphics/example/README.md @@ -0,0 +1,3 @@ +# example + +An example of using package:vector_graphics to draw vector assets \ No newline at end of file diff --git a/packages/vector_graphics/example/assets/tiger.bin b/packages/vector_graphics/example/assets/tiger.bin new file mode 100644 index 000000000000..9d8de7e545fc Binary files /dev/null and b/packages/vector_graphics/example/assets/tiger.bin differ diff --git a/packages/vector_graphics/example/lib/main.dart b/packages/vector_graphics/example/lib/main.dart new file mode 100644 index 000000000000..1237510ddb5a --- /dev/null +++ b/packages/vector_graphics/example/lib/main.dart @@ -0,0 +1,75 @@ +// 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:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:http/http.dart' as http; +import 'package:vector_graphics/vector_graphics.dart'; +import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; + +void main() { + runApp(const MyApp()); +} + +/// The main example app widget. +class MyApp extends StatelessWidget { + /// Creates a new [MyApp]. + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Vector Graphics Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: const Scaffold( + body: Center( + child: VectorGraphic( + loader: NetworkSvgLoader( + 'https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg', + ), + ), + ), + ), + ); + } +} + +/// A [BytesLoader] that converts a network URL into encoded SVG data. +class NetworkSvgLoader extends BytesLoader { + /// Creates a [NetworkSvgLoader] that loads an SVG from [url]. + const NetworkSvgLoader(this.url); + + /// The SVG URL. + final String url; + + @override + Future loadBytes(BuildContext? context) async { + return compute((String svgUrl) async { + final http.Response request = await http.get(Uri.parse(svgUrl)); + final TimelineTask task = TimelineTask()..start('encodeSvg'); + final Uint8List compiledBytes = encodeSvg( + xml: request.body, + debugName: svgUrl, + enableClippingOptimizer: false, + enableMaskingOptimizer: false, + enableOverdrawOptimizer: false, + ); + task.finish(); + // sendAndExit will make sure this isn't copied. + return compiledBytes.buffer.asByteData(); + }, url, debugLabel: 'Load Bytes'); + } + + @override + int get hashCode => url.hashCode; + + @override + bool operator ==(Object other) { + return other is NetworkSvgLoader && other.url == url; + } +} diff --git a/packages/vector_graphics/example/lib/svg_string.dart b/packages/vector_graphics/example/lib/svg_string.dart new file mode 100644 index 000000000000..6423b29e8a03 --- /dev/null +++ b/packages/vector_graphics/example/lib/svg_string.dart @@ -0,0 +1,169 @@ +// 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:convert'; +import 'dart:io'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:vector_graphics/vector_graphics.dart'; +import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; + +const String _flutterLogoString = ''' + + + + + + + + + + + + + + + +'''; + +void main() { + runApp(const MyApp()); +} + +/// The main example app widget. +class MyApp extends StatefulWidget { + /// Creates a new [MyApp]. + const MyApp({super.key}); + + @override + State createState() => _MyAppState(); +} + +class _MyAppState extends State { + final TextEditingController _controller = + TextEditingController(text: _flutterLogoString); + ByteData? _data; + Timer? _debounce; + int _svgLength = 0; + int _gzSvgLength = 0; + int _vgLength = 0; + int _gzVgLength = 0; + + void _reloadSvg(String text) { + if (_debounce?.isActive ?? false) { + _debounce?.cancel(); + } + _debounce = Timer(const Duration(milliseconds: 250), () { + compute((String svg) { + final Uint8List compiledBytes = encodeSvg( + xml: svg, + debugName: '', + enableClippingOptimizer: false, + enableMaskingOptimizer: false, + enableOverdrawOptimizer: false, + ); + return compiledBytes.buffer.asByteData(); + }, text, debugLabel: 'Load Bytes') + .then((ByteData data) { + if (!mounted) { + return; + } + setState(() { + // String is UTF-16. + _svgLength = text.length * 2; + _gzSvgLength = gzip.encode(utf8.encode(text)).length; + _vgLength = data.lengthInBytes; + _gzVgLength = gzip.encode(data.buffer.asUint8List()).length; + _data = data; + }); + }, onError: (Object error, StackTrace stack) { + debugPrint(error.toString()); + debugPrint(stack.toString()); + }); + }); + } + + @override + void initState() { + super.initState(); + _reloadSvg(_flutterLogoString); + } + + @override + void dispose() { + _debounce?.cancel(); + _debounce = null; + _data = null; + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Vector Graphics Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: Scaffold( + body: Center( + child: ListView( + children: [ + const SizedBox(height: 10), + if (_data == null) + const Placeholder() + else + VectorGraphic( + loader: RawBytesLoader( + _data!, + ), + ), + const Divider(), + Text('SVG size (compressed): $_svgLength ($_gzSvgLength). ' + 'VG size (compressed): $_vgLength ($_gzVgLength)'), + const Divider(), + Padding( + padding: const EdgeInsets.all(8.0), + child: TextField( + controller: _controller, + onChanged: _reloadSvg, + scrollPhysics: const NeverScrollableScrollPhysics(), + maxLines: null, + ), + ), + ], + ), + ), + ), + ); + } +} + +/// A [BytesLoader] that passes on existing bytes. +class RawBytesLoader extends BytesLoader { + /// Creates a [RawBytesLoader] that returns [data] directly. + const RawBytesLoader(this.data); + + /// The data to return. + final ByteData data; + + @override + Future loadBytes(BuildContext? context) async { + return data; + } + + @override + int get hashCode => data.hashCode; + + @override + bool operator ==(Object other) { + return other is RawBytesLoader && other.data == data; + } +} diff --git a/packages/vector_graphics/example/pubspec.yaml b/packages/vector_graphics/example/pubspec.yaml new file mode 100644 index 000000000000..b80875fbaa4c --- /dev/null +++ b/packages/vector_graphics/example/pubspec.yaml @@ -0,0 +1,37 @@ +name: example +description: An example of the vector_graphics package +publish_to: 'none' + +environment: + sdk: ^3.4.0 + +dependencies: + flutter: + sdk: flutter + http: ">=0.13.0 <2.0.0" + vector_graphics: any + vector_graphics_compiler: any + + +dev_dependencies: + flutter_test: + sdk: flutter + +flutter: + uses-material-design: true + +dependency_overrides: + vector_graphics: + path: ../ + vector_graphics_codec: + path: ../../vector_graphics_codec + vector_graphics_compiler: + path: ../../vector_graphics_compiler + +platforms: + android: + ios: + linux: + macos: + web: + windows: diff --git a/packages/vector_graphics/lib/src/_debug_io.dart b/packages/vector_graphics/lib/src/_debug_io.dart new file mode 100644 index 000000000000..c2aaa6d6c8df --- /dev/null +++ b/packages/vector_graphics/lib/src/_debug_io.dart @@ -0,0 +1,11 @@ +// 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:io'; + +/// Skip rasterization if "VECTOR_GRAPHICS_SKIP_RASTER" is "true". +bool get debugSkipRaster { + final String? skip = Platform.environment['VECTOR_GRAPHICS_SKIP_RASTER']; + return skip == 'true'; +} diff --git a/packages/vector_graphics/lib/src/_debug_web.dart b/packages/vector_graphics/lib/src/_debug_web.dart new file mode 100644 index 000000000000..2467bbea9362 --- /dev/null +++ b/packages/vector_graphics/lib/src/_debug_web.dart @@ -0,0 +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. + +/// Don't skip rasterization on web platform debug mode. +// TODO(jonahwilliams): determine how this will be enabled/disabled. +bool get debugSkipRaster { + return false; +} diff --git a/packages/vector_graphics/lib/src/debug.dart b/packages/vector_graphics/lib/src/debug.dart new file mode 100644 index 000000000000..fee0ef052535 --- /dev/null +++ b/packages/vector_graphics/lib/src/debug.dart @@ -0,0 +1,5 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +export '_debug_web.dart' if (dart.library.io) '_debug_io.dart'; diff --git a/packages/vector_graphics/lib/src/html_render_vector_graphics.dart b/packages/vector_graphics/lib/src/html_render_vector_graphics.dart new file mode 100644 index 000000000000..bb577fab9c0b --- /dev/null +++ b/packages/vector_graphics/lib/src/html_render_vector_graphics.dart @@ -0,0 +1,176 @@ +// 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:ui' as ui; + +import 'package:flutter/animation.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/rendering.dart'; + +import 'debug.dart'; +import 'listener.dart'; + +/// A render object which draws a vector graphic instance as a picture +/// for HTML compatibility. +class RenderWebVectorGraphic extends RenderBox { + /// Create a new [RenderWebVectorGraphic]. + RenderWebVectorGraphic( + this._pictureInfo, + this._assetKey, + this._colorFilter, + this._opacity, + ) { + _opacity?.addListener(_updateOpacity); + _updateOpacity(); + } + + /// A key that uniquely identifies the [pictureInfo] used for this vg. + Object get assetKey => _assetKey; + Object _assetKey; + set assetKey(Object value) { + if (value == assetKey) { + return; + } + _assetKey = value; + // Dont call mark needs paint here since a change in just the asset key + // isn't sufficient to force a re-draw. + } + + /// The [PictureInfo] which contains the vector graphic and size to draw. + PictureInfo get pictureInfo => _pictureInfo; + PictureInfo _pictureInfo; + set pictureInfo(PictureInfo value) { + if (identical(value, _pictureInfo)) { + return; + } + _pictureInfo = value; + markNeedsPaint(); + } + + /// An optional [ColorFilter] to apply to the rasterized vector graphic. + ColorFilter? get colorFilter => _colorFilter; + ColorFilter? _colorFilter; + set colorFilter(ColorFilter? value) { + if (colorFilter == value) { + return; + } + _colorFilter = value; + markNeedsPaint(); + } + + double _opacityValue = 1.0; + + /// An opacity to draw the rasterized vector graphic with. + Animation? get opacity => _opacity; + Animation? _opacity; + set opacity(Animation? value) { + if (value == opacity) { + return; + } + _opacity?.removeListener(_updateOpacity); + _opacity = value; + _opacity?.addListener(_updateOpacity); + markNeedsPaint(); + } + + void _updateOpacity() { + if (opacity == null) { + return; + } + final double newValue = opacity!.value; + if (newValue == _opacityValue) { + return; + } + _opacityValue = newValue; + markNeedsPaint(); + } + + @override + bool hitTestSelf(Offset position) => true; + + @override + bool get sizedByParent => true; + + @override + bool get alwaysNeedsCompositing => true; + + @override + Size computeDryLayout(BoxConstraints constraints) { + return constraints.smallest; + } + + @override + void attach(covariant PipelineOwner owner) { + _opacity?.addListener(_updateOpacity); + _updateOpacity(); + super.attach(owner); + } + + @override + void detach() { + _opacity?.removeListener(_updateOpacity); + super.detach(); + } + + @override + void dispose() { + _opacity?.removeListener(_updateOpacity); + _transformLayer.layer = null; + _opacityHandle.layer = null; + _filterLayer.layer = null; + super.dispose(); + } + + final LayerHandle _transformLayer = + LayerHandle(); + final LayerHandle _opacityHandle = LayerHandle(); + final LayerHandle _filterLayer = + LayerHandle(); + final Matrix4 _transform = Matrix4.identity(); + + @override + void paint(PaintingContext context, ui.Offset offset) { + assert(size == pictureInfo.size); + if (kDebugMode && debugSkipRaster) { + context.canvas + .drawRect(offset & size, Paint()..color = const Color(0xFFFF00FF)); + return; + } + + if (_opacityValue <= 0.0) { + return; + } + + // The HTML backend cannot correctly draw saveLayer opacity or color + // filters. Nor does it support toImageSync. + _transformLayer.layer = context.pushTransform( + true, + offset, + _transform, + (PaintingContext context, Offset offset) { + _opacityHandle.layer = context.pushOpacity( + offset, + (_opacityValue * 255).round(), + (PaintingContext context, Offset offset) { + if (colorFilter != null) { + _filterLayer.layer = context.pushColorFilter( + offset, + colorFilter!, + (PaintingContext context, Offset offset) { + context.canvas.drawPicture(pictureInfo.picture); + }, + oldLayer: _filterLayer.layer, + ); + } else { + _filterLayer.layer = null; + context.canvas.drawPicture(pictureInfo.picture); + } + }, + oldLayer: _opacityHandle.layer, + ); + }, + oldLayer: _transformLayer.layer, + ); + } +} diff --git a/packages/vector_graphics/lib/src/listener.dart b/packages/vector_graphics/lib/src/listener.dart new file mode 100644 index 000000000000..f266de4fb4a2 --- /dev/null +++ b/packages/vector_graphics/lib/src/listener.dart @@ -0,0 +1,850 @@ +// 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:typed_data'; +import 'dart:ui'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/painting.dart' + show + ImageInfo, + ImageStreamCompleter, + ImageStreamListener, + OneFrameImageStreamCompleter, + imageCache; +import 'package:vector_graphics_codec/vector_graphics_codec.dart'; + +import 'loader.dart'; + +const VectorGraphicsCodec _codec = VectorGraphicsCodec(); + +/// The deocded result of a vector graphics asset. +class PictureInfo { + /// Construct a new [PictureInfo]. + PictureInfo._(this.picture, this.size); + + /// A picture generated from a vector graphics image. + final Picture picture; + + /// The target size of the picture. + /// + /// This information should be used to scale and position + /// the picture based on the available space and alignment. + final Size size; +} + +/// Internal testing only. +@visibleForTesting +Locale? get debugLastLocale => _debugLastLocale; +Locale? _debugLastLocale; + +/// Internal testing only. +@visibleForTesting +TextDirection? get debugLastTextDirection => _debugLastTextDirection; +TextDirection? _debugLastTextDirection; + +/// Internal testing only. +@visibleForTesting +Iterable> get debugGetPendingDecodeTasks => + _pendingDecodes.values.map((Completer e) => e.future); +final Map> _pendingDecodes = + >{}; + +/// Decode a vector graphics binary asset into a [Picture]. +/// +/// Throws a [StateError] if the data is invalid. +Future decodeVectorGraphics( + ByteData data, { + required Locale? locale, + required TextDirection? textDirection, + required bool clipViewbox, + required BytesLoader loader, + VectorGraphicsErrorListener? onError, +}) { + try { + // We might be in a test that's using a fake async zone. Make sure that any + // real async work gets scheduled in the root zone so that it will not get + // blocked by microtasks in the fake async zone, but do not unnecessarily + // create zones outside of tests. + bool useZone = false; + assert(() { + _debugLastTextDirection = textDirection; + _debugLastLocale = locale; + useZone = Zone.current != Zone.root && + Zone.current.scheduleMicrotask != Zone.root.scheduleMicrotask; + return true; + }()); + + @pragma('vm:prefer-inline') + Future process() { + final FlutterVectorGraphicsListener listener = + FlutterVectorGraphicsListener( + id: loader.hashCode, + locale: locale, + textDirection: textDirection, + clipViewbox: clipViewbox, + onError: onError, + ); + DecodeResponse response = _codec.decode(data, listener); + if (response.complete) { + return SynchronousFuture(listener.toPicture()); + } + assert(() { + _pendingDecodes[loader] = Completer(); + return true; + }()); + return listener.waitForImageDecode().then((_) { + response = _codec.decode(data, listener, response: response); + assert(response.complete); + assert(() { + _pendingDecodes.remove(loader)?.complete(); + return true; + }()); + return listener.toPicture(); + }); + } + + if (!kDebugMode || !useZone) { + return process(); + } + + return Zone.current + .fork( + specification: ZoneSpecification( + scheduleMicrotask: + (Zone self, ZoneDelegate parent, Zone zone, void Function() f) { + Zone.root.scheduleMicrotask(f); + }, + createTimer: (Zone self, ZoneDelegate parent, Zone zone, + Duration duration, void Function() f) { + return Zone.root.createTimer(duration, f); + }, + createPeriodicTimer: (Zone self, ZoneDelegate parent, Zone zone, + Duration period, void Function(Timer timer) f) { + return Zone.root.createPeriodicTimer(period, f); + }, + ), + ) + .run>(process); + } catch (e, s) { + _pendingDecodes.remove(loader)?.completeError(e, s); + throw VectorGraphicsDecodeException._(loader, e); + } +} + +/// Pattern configuration to be used when creating ImageShader. +class _PatternConfig { + /// Constructs a [_PatternConfig]. + _PatternConfig(this._patternId, this._width, this._height, this._transform); + + /// This id will match any path or text element that has a non-null patternId. + /// This number will also be used to map path and text elements to the + /// correct [ImageShader]. + final int _patternId; + + /// This is the width of the pattern's viewbox in px. + /// Values must be > = 1. + final double _width; + + /// The is the height of the pattern's viewbox in px. + /// Values must be > = 1. + final double _height; + + /// This is the transform of the pattern that has been created from the children, + /// of the original [ResolvedPatternNode]. + final Float64List _transform; +} + +/// Pattern state that holds information about how to construct the pattern. +class _PatternState { + /// The canvas that the element should draw to for a given [PatternConfig]. + Canvas? canvas; + + /// The image shader created by the pattern. + ImageShader? shader; + + /// The recorder that will capture the newly created canvas. + PictureRecorder? recorder; +} + +/// Used by [FlutterVectorGraphicsListener] for testing purposes. +@visibleForTesting +abstract class PictureFactory { + /// Allows const subclasses. + const PictureFactory(); + + /// Create a picture recorder. + PictureRecorder createPictureRecorder(); + + /// Create a canvas from the recorder. + Canvas createCanvas(PictureRecorder recorder); +} + +class _DefaultPictureFactory implements PictureFactory { + const _DefaultPictureFactory(); + + @override + Canvas createCanvas(PictureRecorder recorder) => Canvas(recorder); + + @override + PictureRecorder createPictureRecorder() => PictureRecorder(); +} + +/// A listener implementation for the vector graphics codec that converts the +/// format into a [Picture]. +class FlutterVectorGraphicsListener extends VectorGraphicsCodecListener { + /// Create a new [FlutterVectorGraphicsListener]. + /// + /// The [locale] and [textDirection] are used to configure any text created + /// by the vector_graphic. + factory FlutterVectorGraphicsListener({ + int id = 0, + Locale? locale, + TextDirection? textDirection, + bool clipViewbox = true, + @visibleForTesting + PictureFactory pictureFactory = const _DefaultPictureFactory(), + VectorGraphicsErrorListener? onError, + }) { + final PictureRecorder recorder = pictureFactory.createPictureRecorder(); + return FlutterVectorGraphicsListener._( + id, + pictureFactory, + recorder, + pictureFactory.createCanvas(recorder), + locale, + textDirection, + clipViewbox, + onError: onError, + ); + } + + FlutterVectorGraphicsListener._( + this._id, + this._pictureFactory, + this._recorder, + this._canvas, + this._locale, + this._textDirection, + this._clipViewbox, { + this.onError, + }); + + final int _id; + + final PictureFactory _pictureFactory; + + final Locale? _locale; + final TextDirection? _textDirection; + final bool _clipViewbox; + + final PictureRecorder _recorder; + final Canvas _canvas; + + /// This variable will receive the Signature for the error + final VectorGraphicsErrorListener? onError; + + final List _paints = []; + final List _paths = []; + final List _shaders = []; + final List<_TextConfig> _textConfig = <_TextConfig>[]; + final List<_TextPosition> _textPositions = <_TextPosition>[]; + final List> _pendingImages = >[]; + final Map _images = {}; + final Map _patterns = {}; + Path? _currentPath; + Size _size = Size.zero; + bool _done = false; + + double? _accumulatedTextPositionX; + double _textPositionY = 0; + Float64List? _textTransform; + + _PatternConfig? _currentPattern; + + static final Paint _emptyPaint = Paint(); + static final Paint _grayscaleDstInPaint = Paint() + ..blendMode = BlendMode.dstIn + ..colorFilter = const ColorFilter.matrix([ + 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0.2126, 0.7152, 0.0722, 0, 0, + ]); //convert to grayscale (https://www.w3.org/Graphics/Color/sRGB) and use them as transparency + + /// Convert the vector graphics asset this listener decoded into a [Picture]. + /// + /// This method can only be called once for a given listener instance. + PictureInfo toPicture() { + assert(!_done); + _done = true; + try { + return PictureInfo._(_recorder.endRecording(), _size); + } finally { + for (final Image image in _images.values) { + image.dispose(); + } + _images.clear(); + for (final _PatternState pattern in _patterns.values) { + pattern.shader?.dispose(); + } + _patterns.clear(); + } + } + + /// Wait for all pending images to load. + Future waitForImageDecode() { + assert(_pendingImages.isNotEmpty); + return Future.wait(_pendingImages); + } + + @override + Future onDrawPath(int pathId, int? paintId, int? patternId) async { + final Path path = _paths[pathId]; + Paint? paint; + if (paintId != null) { + paint = _paints[paintId]; + } + if (patternId != null) { + if (paintId != null) { + paint!.shader = _patterns[patternId]!.shader; + } else { + final Paint newPaint = Paint(); + newPaint.shader = _patterns[patternId]!.shader; + paint = newPaint; + } + } + if (_currentPattern != null) { + _patterns[_currentPattern!._patternId]! + .canvas! + .drawPath(path, paint ?? _emptyPaint); + } else { + _canvas.drawPath(path, paint ?? _emptyPaint); + } + } + + @override + void onDrawVertices(Float32List vertices, Uint16List? indices, int? paintId) { + final Vertices vertexData = Vertices.raw( + VertexMode.triangles, + vertices, + indices: indices, + ); + Paint? paint; + if (paintId != null) { + paint = _paints[paintId]; + } + _canvas.drawVertices( + vertexData, + BlendMode.srcOver, + paint ?? _emptyPaint, + ); + vertexData.dispose(); + } + + @override + void onPaintObject({ + required int color, + required int? strokeCap, + required int? strokeJoin, + required int blendMode, + required double? strokeMiterLimit, + required double? strokeWidth, + required int paintStyle, + required int id, + required int? shaderId, + }) { + assert(_paints.length == id, 'Expect ID to be ${_paints.length}'); + final Paint paint = Paint()..color = Color(color); + if (blendMode != 0) { + paint.blendMode = BlendMode.values[blendMode]; + } + + if (shaderId != null) { + paint.shader = _shaders[shaderId]; + } + + if (paintStyle == 1) { + paint.style = PaintingStyle.stroke; + if (strokeCap != null && strokeCap != 0) { + paint.strokeCap = StrokeCap.values[strokeCap]; + } + if (strokeJoin != null && strokeJoin != 0) { + paint.strokeJoin = StrokeJoin.values[strokeJoin]; + } + if (strokeMiterLimit != null && strokeMiterLimit != 4.0) { + paint.strokeMiterLimit = strokeMiterLimit; + } + // SVG's default stroke width is 1.0. Flutter's default is 0.0. + if (strokeWidth != null && strokeWidth != 0.0) { + paint.strokeWidth = strokeWidth; + } + } + _paints.add(paint); + } + + @override + void onPathClose() { + _currentPath!.close(); + } + + @override + void onPathCubicTo( + double x1, double y1, double x2, double y2, double x3, double y3) { + _currentPath!.cubicTo(x1, y1, x2, y2, x3, y3); + } + + @override + void onPathFinished() { + _currentPath = null; + } + + @override + void onPathLineTo(double x, double y) { + _currentPath!.lineTo(x, y); + } + + @override + void onPathMoveTo(double x, double y) { + _currentPath!.moveTo(x, y); + } + + @override + void onPathStart(int id, int fillType) { + assert(_currentPath == null); + assert(_paths.length == id, 'Expected Id to be $id'); + + final Path path = Path(); + path.fillType = PathFillType.values[fillType]; + _paths.add(path); + _currentPath = path; + } + + @override + void onRestoreLayer() { + if (_currentPattern != null) { + final int patternId = _currentPattern!._patternId; + onPatternFinished(_currentPattern, _patterns[patternId]!.recorder, + _patterns[patternId]!.canvas!); + } else { + _canvas.restore(); + } + } + + @override + void onSaveLayer(int paintId) { + _canvas.saveLayer(null, _paints[paintId]); + } + + @override + void onMask() { + _canvas.saveLayer(null, _grayscaleDstInPaint); + } + + @override + void onClipPath(int pathId) { + _canvas.save(); + _canvas.clipPath(_paths[pathId]); + } + + @override + void onPatternStart(int patternId, double x, double y, double width, + double height, Float64List transform) { + assert(_currentPattern == null); + _currentPattern = _PatternConfig(patternId, width, height, transform); + final PictureRecorder recorder = _pictureFactory.createPictureRecorder(); + final Canvas newCanvas = _pictureFactory.createCanvas(recorder); + newCanvas.clipRect(Offset(x, y) & Size(width, height)); + _patterns[patternId] = _PatternState() + ..recorder = recorder + ..canvas = newCanvas; + } + + /// Creates ImageShader for active pattern. + // TODO(stuartmorgan): Fix this violation, which predates enabling the lint + // to catch it. + // ignore: library_private_types_in_public_api + void onPatternFinished(_PatternConfig? currentPattern, + PictureRecorder? patternRecorder, Canvas canvas) { + final FlutterVectorGraphicsListener patternListener = + FlutterVectorGraphicsListener._( + 0, + _pictureFactory, + patternRecorder!, + canvas, + _locale, + _textDirection, + _clipViewbox, + ); + + patternListener._size = + Size(currentPattern!._width, currentPattern._height); + + final PictureInfo pictureInfo = patternListener.toPicture(); + _currentPattern = null; + final Image image = pictureInfo.picture.toImageSync( + currentPattern._width.round(), currentPattern._height.round()); + + final ImageShader pattern = ImageShader( + image, + TileMode.repeated, + TileMode.repeated, + currentPattern._transform, + ); + + _patterns[currentPattern._patternId]!.shader = pattern; + image.dispose(); // kept alive by the shader. + } + + @override + void onLinearGradient( + double fromX, + double fromY, + double toX, + double toY, + Int32List colors, + Float32List? offsets, + int tileMode, + int id, + ) { + assert(_shaders.length == id); + + final Offset from = Offset(fromX, fromY); + final Offset to = Offset(toX, toY); + final List colorValues = [ + for (int i = 0; i < colors.length; i++) Color(colors[i]) + ]; + final Gradient gradient = Gradient.linear( + from, + to, + colorValues, + offsets, + TileMode.values[tileMode], + ); + _shaders.add(gradient); + } + + @override + void onRadialGradient( + double centerX, + double centerY, + double radius, + double? focalX, + double? focalY, + Int32List colors, + Float32List? offsets, + Float64List? transform, + int tileMode, + int id, + ) { + assert(_shaders.length == id); + + final Offset center = Offset(centerX, centerY); + final Offset? focal = focalX == null ? null : Offset(focalX, focalY!); + final List colorValues = [ + for (int i = 0; i < colors.length; i++) Color(colors[i]) + ]; + final bool hasFocal = focal != center && focal != null; + final Gradient gradient = Gradient.radial( + center, + radius, + colorValues, + offsets, + TileMode.values[tileMode], + transform, + hasFocal ? focal : null, + ); + _shaders.add(gradient); + } + + @override + void onSize(double width, double height) { + if (_clipViewbox) { + _canvas.clipRect(Offset.zero & Size(width, height)); + } + _size = Size(width, height); + } + + @override + void onTextConfig( + String text, + String? fontFamily, + double xAnchorMultiplier, + int fontWeight, + double fontSize, + int decoration, + int decorationStyle, + int decorationColor, + int id, + ) { + final List decorations = []; + if (decoration & kUnderlineMask != 0) { + decorations.add(TextDecoration.underline); + } + if (decoration & kOverlineMask != 0) { + decorations.add(TextDecoration.overline); + } + if (decoration & kLineThroughMask != 0) { + decorations.add(TextDecoration.lineThrough); + } + + _textConfig.add(_TextConfig( + text, + fontFamily, + xAnchorMultiplier, + FontWeight.values[fontWeight], + fontSize, + TextDecoration.combine(decorations), + TextDecorationStyle.values[decorationStyle], + Color(decorationColor), + )); + } + + @override + void onTextPosition( + int textPositionId, + double? x, + double? y, + double? dx, + double? dy, + bool reset, + Float64List? transform, + ) { + _textPositions.add(_TextPosition(x, y, dx, dy, reset, transform)); + } + + @override + void onUpdateTextPosition(int textPositionId) { + final _TextPosition position = _textPositions[textPositionId]; + if (position.reset) { + _accumulatedTextPositionX = 0; + _textPositionY = 0; + } + + if (position.x != null) { + _accumulatedTextPositionX = position.x; + } + if (position.y != null) { + _textPositionY = position.y ?? _textPositionY; + } + + if (position.dx != null) { + _accumulatedTextPositionX = + (_accumulatedTextPositionX ?? 0) + position.dx!; + } + if (position.dy != null) { + _textPositionY = _textPositionY + position.dy!; + } + + _textTransform = position.transform; + } + + @override + Future onDrawText( + int textId, + int? fillId, + int? strokeId, + int? patternId, + ) async { + final _TextConfig textConfig = _textConfig[textId]; + final double dx = _accumulatedTextPositionX ?? 0; + final double dy = _textPositionY; + double paragraphWidth = 0; + + void draw(int paintId) { + final Paint paint = _paints[paintId]; + if (patternId != null) { + paint.shader = _patterns[patternId]!.shader; + } + final ParagraphBuilder builder = ParagraphBuilder(ParagraphStyle( + textDirection: _textDirection, + )); + builder.pushStyle(TextStyle( + locale: _locale, + foreground: paint, + fontWeight: textConfig.fontWeight, + fontSize: textConfig.fontSize, + fontFamily: textConfig.fontFamily, + decoration: textConfig.decoration, + decorationStyle: textConfig.decorationStyle, + decorationColor: textConfig.decorationColor, + )); + + builder.addText(textConfig.text); + + final Paragraph paragraph = builder.build(); + paragraph.layout(const ParagraphConstraints( + width: double.infinity, + )); + paragraphWidth = paragraph.maxIntrinsicWidth; + + if (_textTransform != null) { + _canvas.save(); + _canvas.transform(_textTransform!); + } + _canvas.drawParagraph( + paragraph, + Offset( + dx - paragraph.maxIntrinsicWidth * textConfig.xAnchorMultiplier, + dy - paragraph.alphabeticBaseline, + ), + ); + paragraph.dispose(); + if (_textTransform != null) { + _canvas.restore(); + } + } + + if (fillId != null) { + draw(fillId); + } + if (strokeId != null) { + draw(strokeId); + } + _accumulatedTextPositionX = dx + paragraphWidth; + } + + int _createImageKey(int imageId, int format) { + return Object.hash(_id, imageId, format); + } + + @override + void onImage( + int imageId, + int format, + Uint8List data, { + VectorGraphicsErrorListener? onError, + }) { + final Completer completer = Completer(); + _pendingImages.add(completer.future); + final ImageStreamCompleter? cacheCompleter = + imageCache.putIfAbsent(_createImageKey(imageId, format), () { + return OneFrameImageStreamCompleter(ImmutableBuffer.fromUint8List(data) + .then((ImmutableBuffer buffer) async { + try { + final ImageDescriptor descriptor = + await ImageDescriptor.encoded(buffer); + final Codec codec = await descriptor.instantiateCodec(); + final FrameInfo info = await codec.getNextFrame(); + final Image image = info.image; + descriptor.dispose(); + codec.dispose(); + return ImageInfo(image: image); + } finally { + buffer.dispose(); + } + })); + }); + // an error occurred. + if (cacheCompleter == null) { + completer.completeError('Failed to load image'); + return; + } + late ImageStreamListener listener; + listener = ImageStreamListener( + (ImageInfo image, bool synchronousCall) { + cacheCompleter.removeListener(listener); + _images[imageId] = image.image; + completer.complete(); + }, + onError: (Object exception, StackTrace? stackTrace) { + if (!completer.isCompleted) { + completer.complete(); + } + cacheCompleter.removeListener(listener); + if (onError != null) { + onError(exception, stackTrace); + } else { + FlutterError.reportError(FlutterErrorDetails( + context: ErrorDescription('Failed to load image'), + library: 'image resource service', + exception: exception, + stack: stackTrace, + silent: true, + )); + } + }, + ); + cacheCompleter.addListener(listener); + } + + @override + void onDrawImage(int imageId, double x, double y, double width, double height, + Float64List? transform) { + final Image image = _images[imageId]!; + if (transform != null) { + _canvas.save(); + _canvas.transform(transform); + } + _canvas.drawImageRect( + image, + Rect.fromLTRB(0, 0, image.width.toDouble(), image.height.toDouble()), + Rect.fromLTWH(x, y, width, height), + Paint(), + ); + if (transform != null) { + _canvas.restore(); + } + } +} + +class _TextPosition { + const _TextPosition( + this.x, + this.y, + this.dx, + this.dy, + this.reset, + this.transform, + ); + + final double? x; + final double? y; + final double? dx; + final double? dy; + final bool reset; + final Float64List? transform; +} + +class _TextConfig { + const _TextConfig( + this.text, + this.fontFamily, + this.xAnchorMultiplier, + this.fontWeight, + this.fontSize, + this.decoration, + this.decorationStyle, + this.decorationColor, + ); + + final String text; + final String? fontFamily; + final double fontSize; + final double xAnchorMultiplier; + final FontWeight fontWeight; + final TextDecoration decoration; + final TextDecorationStyle decorationStyle; + final Color decorationColor; +} + +/// An exception thrown if decoding fails. +/// +/// The [originalException] is a detailed exception about what failed in +/// decoding. The [source] contains the object that was used to load the bytes. +class VectorGraphicsDecodeException implements Exception { + const VectorGraphicsDecodeException._(this.source, this.originalException); + + /// The object used to load the bytes for this + final BytesLoader source; + + /// The original exception thrown by the decoder, for example a [StateError] + /// indicating what specifically went wrong. + final Object originalException; + + @override + String toString() => + 'VectorGraphicsDecodeException: Failed to decode vector graphic from $source.\n\nAdditional error: $originalException'; +} diff --git a/packages/vector_graphics/lib/src/loader.dart b/packages/vector_graphics/lib/src/loader.dart new file mode 100644 index 000000000000..8f12e2967155 --- /dev/null +++ b/packages/vector_graphics/lib/src/loader.dart @@ -0,0 +1,177 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; +import 'package:http/http.dart' as http; + +/// An interface that can be implemented to support decoding vector graphic +/// binary assets from different byte sources. +/// +/// A bytes loader class should not be constructed directly in a build method, +/// if this is done the corresponding [VectorGraphic] widget may repeatedly +/// reload the bytes. +/// +/// Implementations must overide [toString] for debug reporting. +/// +/// See also: +/// * [AssetBytesLoader], for loading from the asset bundle. +/// * [NetworkBytesLoader], for loading network bytes. +@immutable +abstract class BytesLoader { + /// Const constructor to allow subtypes to be const. + const BytesLoader(); + + /// Load the byte data for a vector graphic binary asset. + Future loadBytes(BuildContext? context); + + /// Create an object that can be used to uniquely identify this asset + /// and loader combination. + /// + /// For most [BytesLoader] subclasses, this can safely return the same + /// instance. If the loader looks up additional dependencies using the + /// [context] argument of [loadBytes], then those objects should be + /// incorporated into a new cache key. + Object cacheKey(BuildContext? context) => this; +} + +/// Loads vector graphics data from an asset bundle. +/// +/// This loader does not cache bytes by default. The Flutter framework +/// implementations of [AssetBundle] also do not typically cache binary data. +/// +/// Callers that would benefit from caching should provide a custom +/// [AssetBundle] that caches data, or should create their own implementation +/// of an asset bytes loader. +class AssetBytesLoader extends BytesLoader { + /// A loader that retrieves bytes from an [AssetBundle]. + /// + /// See [AssetBytesLoader]. + const AssetBytesLoader( + this.assetName, { + this.packageName, + this.assetBundle, + }); + + /// The name of the asset to load. + final String assetName; + + /// The package name to load from, if any. + final String? packageName; + + /// The asset bundle to use. + /// + /// If unspecified, [DefaultAssetBundle.of] the current context will be used. + final AssetBundle? assetBundle; + + AssetBundle _resolveBundle(BuildContext? context) { + if (assetBundle != null) { + return assetBundle!; + } + if (context != null) { + return DefaultAssetBundle.of(context); + } + return rootBundle; + } + + @override + Future loadBytes(BuildContext? context) { + return _resolveBundle(context).load( + packageName == null ? assetName : 'packages/$packageName/$assetName', + ); + } + + @override + int get hashCode => Object.hash(assetName, packageName, assetBundle); + + @override + bool operator ==(Object other) { + return other is AssetBytesLoader && + other.assetName == assetName && + other.assetBundle == assetBundle && + other.packageName == packageName; + } + + @override + Object cacheKey(BuildContext? context) { + return _AssetByteLoaderCacheKey( + assetName, + packageName, + _resolveBundle(context), + ); + } + + @override + String toString() => + 'VectorGraphicAsset(${packageName != null ? '$packageName/' : ''}$assetName)'; +} + +// Replaces the cache key for [AssetBytesLoader] to account for the fact that +// different widgets may select a different asset bundle based on the return +// value of `DefaultAssetBundle.of(context)`. +@immutable +class _AssetByteLoaderCacheKey { + const _AssetByteLoaderCacheKey( + this.assetName, this.packageName, this.assetBundle); + + final String assetName; + final String? packageName; + + final AssetBundle assetBundle; + + @override + int get hashCode => Object.hash(assetName, packageName, assetBundle); + + @override + bool operator ==(Object other) { + return other is _AssetByteLoaderCacheKey && + other.assetName == assetName && + other.assetBundle == assetBundle && + other.packageName == packageName; + } + + @override + String toString() => + 'VectorGraphicAsset(${packageName != null ? '$packageName/' : ''}$assetName)'; +} + +/// A controller for loading vector graphics data from over the network. +/// +/// This loader does not cache bytes requested from the network. +class NetworkBytesLoader extends BytesLoader { + /// Creates a new loading context for network bytes. + const NetworkBytesLoader( + this.url, { + this.headers, + http.Client? httpClient, + }) : _httpClient = httpClient; + + /// The HTTP headers to use for the network request. + final Map? headers; + + /// The [Uri] of the resource to request. + final Uri url; + + final http.Client? _httpClient; + + @override + Future loadBytes(BuildContext? context) async { + final http.Client client = _httpClient ?? http.Client(); + final Uint8List bytes = (await client.get(url, headers: headers)).bodyBytes; + return bytes.buffer.asByteData(); + } + + @override + int get hashCode => Object.hash(url, headers); + + @override + bool operator ==(Object other) { + return other is NetworkBytesLoader && + other.headers == headers && + other.url == url; + } + + @override + String toString() => 'VectorGraphicNetwork($url)'; +} diff --git a/packages/vector_graphics/lib/src/render_object_selection.dart b/packages/vector_graphics/lib/src/render_object_selection.dart new file mode 100644 index 000000000000..d8e8c1ef1dba --- /dev/null +++ b/packages/vector_graphics/lib/src/render_object_selection.dart @@ -0,0 +1,37 @@ +// 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:ui' as ui; + +import 'package:flutter/foundation.dart'; + +bool? _cachedUseHtmlRenderObject; + +/// Whether or not the HTML compatibility render object should be used. +/// +/// This render object has worse performance and supports fewer features. +bool useHtmlRenderObject() { + if (!kIsWeb) { + return false; + } + + if (_cachedUseHtmlRenderObject != null) { + return _cachedUseHtmlRenderObject!; + } + + final ui.PictureRecorder recorder = ui.PictureRecorder(); + ui.Canvas(recorder); + final ui.Picture picture = recorder.endRecording(); + ui.Image? image; + try { + image = picture.toImageSync(1, 1); + _cachedUseHtmlRenderObject = false; + } on UnsupportedError catch (_) { + _cachedUseHtmlRenderObject = true; + } finally { + image?.dispose(); + picture.dispose(); + } + return _cachedUseHtmlRenderObject!; +} diff --git a/packages/vector_graphics/lib/src/render_vector_graphic.dart b/packages/vector_graphics/lib/src/render_vector_graphic.dart new file mode 100644 index 000000000000..a6b530469e5b --- /dev/null +++ b/packages/vector_graphics/lib/src/render_vector_graphic.dart @@ -0,0 +1,449 @@ +// 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:ui' as ui; + +import 'package:flutter/animation.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/rendering.dart'; + +import 'debug.dart'; +import 'listener.dart'; + +/// The cache key for a rasterized vector graphic. +@immutable +class RasterKey { + /// Create a new [RasterKey]. + const RasterKey(this.assetKey, this.width, this.height); + + /// An object that is used to identify the raster data this key will store. + /// + /// Typically this is the value returned from [BytesLoader.cacheKey]. + final Object assetKey; + + /// The height of this vector graphic raster, in physical pixels. + final int width; + + /// The width of this vector graphic raster, in physical pixels. + final int height; + + @override + bool operator ==(Object other) { + return other is RasterKey && + other.assetKey == assetKey && + other.width == width && + other.height == height; + } + + @override + int get hashCode => Object.hash(assetKey, width, height); +} + +/// The cache entry for a rasterized vector graphic. +class RasterData { + /// Create a new [RasterData]. + RasterData(this._image, this.count, this.key); + + /// The rasterized vector graphic. + ui.Image get image => _image!; + ui.Image? _image; + + /// The cache key used to identify this vector graphic. + final RasterKey key; + + /// The number of render objects currently using this + /// vector graphic raster data. + int count = 0; + + /// Dispose this raster data. + void dispose() { + _image?.dispose(); + _image = null; + } +} + +/// For testing only, clear all pending rasters. +@visibleForTesting +void debugClearRasteCaches() { + if (!kDebugMode) { + return; + } + RenderVectorGraphic._liveRasterCache.clear(); +} + +/// A render object which draws a vector graphic instance as a raster. +class RenderVectorGraphic extends RenderBox { + /// Create a new [RenderVectorGraphic]. + RenderVectorGraphic( + this._pictureInfo, + this._assetKey, + this._colorFilter, + this._devicePixelRatio, + this._opacity, + this._scale, + ) { + _opacity?.addListener(_updateOpacity); + _updateOpacity(); + } + + static final Map _liveRasterCache = + {}; + + /// A key that uniquely identifies the [pictureInfo] used for this vg. + Object get assetKey => _assetKey; + Object _assetKey; + set assetKey(Object value) { + if (value == assetKey) { + return; + } + _assetKey = value; + // Dont call mark needs paint here since a change in just the asset key + // isn't sufficient to force a re-draw. + } + + /// The [PictureInfo] which contains the vector graphic and size to draw. + PictureInfo get pictureInfo => _pictureInfo; + PictureInfo _pictureInfo; + set pictureInfo(PictureInfo value) { + if (identical(value, _pictureInfo)) { + return; + } + _pictureInfo = value; + markNeedsPaint(); + } + + /// An optional [ColorFilter] to apply to the rasterized vector graphic. + ColorFilter? get colorFilter => _colorFilter; + ColorFilter? _colorFilter; + set colorFilter(ColorFilter? value) { + if (colorFilter == value) { + return; + } + _colorFilter = value; + markNeedsPaint(); + } + + /// The device pixel ratio the vector graphic should be rasterized at. + double get devicePixelRatio => _devicePixelRatio; + double _devicePixelRatio; + set devicePixelRatio(double value) { + if (value == devicePixelRatio) { + return; + } + _devicePixelRatio = value; + markNeedsPaint(); + } + + double _opacityValue = 1.0; + + /// An opacity to draw the rasterized vector graphic with. + Animation? get opacity => _opacity; + Animation? _opacity; + set opacity(Animation? value) { + if (value == opacity) { + return; + } + _opacity?.removeListener(_updateOpacity); + _opacity = value; + _opacity?.addListener(_updateOpacity); + markNeedsPaint(); + } + + void _updateOpacity() { + if (opacity == null) { + return; + } + final double newValue = opacity!.value; + if (newValue == _opacityValue) { + return; + } + _opacityValue = newValue; + markNeedsPaint(); + } + + /// An additional ratio the picture will be transformed by. + /// + /// This value is used to ensure the computed raster does not + /// have extra pixelation from scaling in the case that a the [BoxFit] + /// value used in the [VectorGraphic] widget implies a scaling factor + /// greater than 1.0. + /// + /// For example, if the vector graphic widget is sized at 100x100, + /// the vector graphic itself has a size of 50x50, and [BoxFit.fill] + /// is used. This will compute a scale of 2.0, which will result in a + /// raster that is 100x100. + double get scale => _scale; + double _scale; + set scale(double value) { + assert(value != 0); + if (value == scale) { + return; + } + _scale = value; + markNeedsPaint(); + } + + @override + bool hitTestSelf(Offset position) => true; + + @override + bool get sizedByParent => true; + + @override + Size computeDryLayout(BoxConstraints constraints) { + return constraints.smallest; + } + + static RasterData _createRaster( + RasterKey key, double scaleFactor, PictureInfo info) { + final int scaledWidth = key.width; + final int scaledHeight = key.height; + // In order to scale a picture, it must be placed in a new picture + // with a transform applied. Surprisingly, the height and width + // arguments of Picture.toImage do not control the resolution that the + // picture is rendered at, instead it controls how much of the picture to + // capture in a raster. + final ui.PictureRecorder recorder = ui.PictureRecorder(); + final ui.Canvas canvas = ui.Canvas(recorder); + + canvas.scale(scaleFactor); + canvas.drawPicture(info.picture); + final ui.Picture rasterPicture = recorder.endRecording(); + + final ui.Image pending = + rasterPicture.toImageSync(scaledWidth, scaledHeight); + return RasterData(pending, 0, key); + } + + void _maybeReleaseRaster(RasterData? data) { + if (data == null) { + return; + } + data.count -= 1; + if (data.count == 0 && _liveRasterCache.containsKey(data.key)) { + _liveRasterCache.remove(data.key); + data.dispose(); + } + } + + // Re-create the raster for a given vector graphic if the target size + // is sufficiently different. Returns `null` if rasterData has been + // updated immediately. + void _maybeUpdateRaster() { + final int scaledWidth = + (pictureInfo.size.width * devicePixelRatio / scale).round(); + final int scaledHeight = + (pictureInfo.size.height * devicePixelRatio / scale).round(); + final RasterKey key = RasterKey(assetKey, scaledWidth, scaledHeight); + + // First check if the raster is available synchronously. This also handles + // a no-op change that would resolve to an identical picture. + if (_liveRasterCache.containsKey(key)) { + final RasterData data = _liveRasterCache[key]!; + if (data != _rasterData) { + _maybeReleaseRaster(_rasterData); + data.count += 1; + } + _rasterData = data; + return; + } + final RasterData data = + _createRaster(key, devicePixelRatio / scale, pictureInfo); + data.count += 1; + + assert(!_liveRasterCache.containsKey(key)); + assert(data.count == 1); + assert(!debugDisposed!); + + _liveRasterCache[key] = data; + _maybeReleaseRaster(_rasterData); + _rasterData = data; + } + + RasterData? _rasterData; + + @override + void attach(covariant PipelineOwner owner) { + _opacity?.addListener(_updateOpacity); + _updateOpacity(); + super.attach(owner); + } + + @override + void detach() { + _opacity?.removeListener(_updateOpacity); + super.detach(); + } + + @override + void dispose() { + _maybeReleaseRaster(_rasterData); + _opacity?.removeListener(_updateOpacity); + super.dispose(); + } + + @override + void paint(PaintingContext context, ui.Offset offset) { + assert(size == pictureInfo.size); + if (kDebugMode && debugSkipRaster) { + context.canvas + .drawRect(offset & size, Paint()..color = const Color(0xFFFF00FF)); + return; + } + + if (_opacityValue <= 0.0) { + return; + } + + _maybeUpdateRaster(); + final ui.Image image = _rasterData!.image; + final int width = _rasterData!.key.width; + final int height = _rasterData!.key.height; + + // Use `FilterQuality.low` to scale the image, which corresponds to + // bilinear interpolation. + final Paint colorPaint = Paint()..filterQuality = ui.FilterQuality.low; + if (colorFilter != null) { + colorPaint.colorFilter = colorFilter; + } + colorPaint.color = Color.fromRGBO(0, 0, 0, _opacityValue); + final Rect src = ui.Rect.fromLTWH( + 0, + 0, + width.toDouble(), + height.toDouble(), + ); + final Rect dst = ui.Rect.fromLTWH( + offset.dx, + offset.dy, + pictureInfo.size.width, + pictureInfo.size.height, + ); + + context.canvas.drawImageRect( + image, + src, + dst, + colorPaint, + ); + } +} + +/// A render object which draws a vector graphic instance as a picture. +class RenderPictureVectorGraphic extends RenderBox { + /// Create a new [RenderPictureVectorGraphic]. + RenderPictureVectorGraphic( + this._pictureInfo, + this._colorFilter, + this._opacity, + ) { + _opacity?.addListener(_updateOpacity); + _updateOpacity(); + } + + /// The [PictureInfo] which contains the vector graphic and size to draw. + PictureInfo get pictureInfo => _pictureInfo; + PictureInfo _pictureInfo; + set pictureInfo(PictureInfo value) { + if (identical(value, _pictureInfo)) { + return; + } + _pictureInfo = value; + markNeedsPaint(); + } + + /// An optional [ColorFilter] to apply to the rasterized vector graphic. + ColorFilter? get colorFilter => _colorFilter; + ColorFilter? _colorFilter; + set colorFilter(ColorFilter? value) { + if (colorFilter == value) { + return; + } + _colorFilter = value; + markNeedsPaint(); + } + + double _opacityValue = 1.0; + + /// An opacity to draw the rasterized vector graphic with. + Animation? get opacity => _opacity; + Animation? _opacity; + set opacity(Animation? value) { + if (value == opacity) { + return; + } + _opacity?.removeListener(_updateOpacity); + _opacity = value; + _opacity?.addListener(_updateOpacity); + markNeedsPaint(); + } + + void _updateOpacity() { + if (opacity == null) { + return; + } + final double newValue = opacity!.value; + if (newValue == _opacityValue) { + return; + } + _opacityValue = newValue; + markNeedsPaint(); + } + + @override + bool hitTestSelf(Offset position) => true; + + @override + bool get sizedByParent => true; + + @override + Size computeDryLayout(BoxConstraints constraints) { + return constraints.smallest; + } + + @override + void attach(covariant PipelineOwner owner) { + _opacity?.addListener(_updateOpacity); + _updateOpacity(); + super.attach(owner); + } + + @override + void detach() { + _opacity?.removeListener(_updateOpacity); + super.detach(); + } + + @override + void dispose() { + _opacity?.removeListener(_updateOpacity); + super.dispose(); + } + + @override + void paint(PaintingContext context, ui.Offset offset) { + assert(size == pictureInfo.size); + if (_opacityValue <= 0.0) { + return; + } + + final Paint colorPaint = Paint(); + if (colorFilter != null) { + colorPaint.colorFilter = colorFilter; + } + colorPaint.color = Color.fromRGBO(0, 0, 0, _opacityValue); + final int saveCount = context.canvas.getSaveCount(); + if (offset != Offset.zero) { + context.canvas.save(); + context.canvas.translate(offset.dx, offset.dy); + } + if (_opacityValue != 1.0 || colorFilter != null) { + context.canvas.save(); + context.canvas.clipRect(Offset.zero & size); + context.canvas.saveLayer(Offset.zero & size, colorPaint); + } + context.canvas.drawPicture(pictureInfo.picture); + context.canvas.restoreToCount(saveCount); + } +} diff --git a/packages/vector_graphics/lib/src/vector_graphics.dart b/packages/vector_graphics/lib/src/vector_graphics.dart new file mode 100644 index 000000000000..eb5eca76fd15 --- /dev/null +++ b/packages/vector_graphics/lib/src/vector_graphics.dart @@ -0,0 +1,708 @@ +// 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:math' as math; +import 'dart:ui' as ui; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:vector_graphics_codec/vector_graphics_codec.dart'; + +import 'html_render_vector_graphics.dart'; +import 'listener.dart'; +import 'loader.dart'; +import 'render_object_selection.dart'; +import 'render_vector_graphic.dart'; + +export 'listener.dart' show PictureInfo; +export 'loader.dart'; + +/// How the vector graphic will be rendered by the Flutter framework. +/// +/// This is ultimately a performance versus fidelity tradeoff. While the +/// raster strategy performs better than the picture strategy in most benchmarks, +/// it can be more difficult to use. Any parent transforms that are not +/// accounted by the application developer can cause the vector graphic to +/// appear pixelated. The picture strategy has no such trade-off, and roughly +/// corresponds to the previous behavior of flutter_svg +/// +/// Consider using the raster strategy for very large or complicated vector graphics +/// that are used as backdrops at fixed scales. The picture strategy makes a better +/// default choice for icon-like vector graphics or vector graphics that have +/// small dimensions. +enum RenderingStrategy { + /// Draw the vector graphic as a raster. + /// + /// This raster is reused from frame to frame which can significantly improve + /// performance if the vector graphic is complicated. + raster, + + /// Draw the vector graphic as a picture. + picture, +} + +/// The signature that [VectorGraphic.errorBuilder] uses to report exceptions. +typedef VectorGraphicsErrorWidget = Widget Function( + BuildContext context, + Object error, + StackTrace stackTrace, +); + +/// A vector graphic/flutter_svg compatibility shim. +VectorGraphic createCompatVectorGraphic({ + Key? key, + required BytesLoader loader, + double? width, + double? height, + BoxFit fit = BoxFit.contain, + AlignmentGeometry alignment = Alignment.center, + String? semanticsLabel, + bool excludeFromSemantics = false, + Clip clipBehavior = Clip.hardEdge, + WidgetBuilder? placeholderBuilder, + VectorGraphicsErrorWidget? errorBuilder, + ColorFilter? colorFilter, + Animation? opacity, + RenderingStrategy strategy = RenderingStrategy.picture, + bool clipViewbox = true, + bool matchTextDirection = false, +}) { + return VectorGraphic._( + key: key, + loader: loader, + width: width, + height: height, + fit: fit, + alignment: alignment, + semanticsLabel: semanticsLabel, + excludeFromSemantics: excludeFromSemantics, + clipBehavior: clipBehavior, + placeholderBuilder: placeholderBuilder, + errorBuilder: errorBuilder, + colorFilter: colorFilter, + opacity: opacity, + strategy: strategy, + clipViewbox: clipViewbox, + matchTextDirection: matchTextDirection, + ); +} + +/// A widget that displays a [VectorGraphicsCodec] encoded asset. +/// +/// This widget will ask the loader to load the bytes whenever its +/// dependencies change or it is configured with a new loader. A loader may +/// or may not choose to cache its responses, potentially resulting in multiple +/// disk or network accesses for the same bytes. +class VectorGraphic extends StatefulWidget { + /// A widget that displays a vector graphics created via a + /// [VectorGraphicsCodec]. + /// + /// If `matchTextDirection` is set to true, the picture will be flipped + /// horizontally in [TextDirection.rtl] contexts. + /// + /// The [semanticsLabel] can be used to identify the purpose of this picture for + /// screen reading software. + /// + /// If [excludeFromSemantics] is true, then [semanticLabel] will be ignored. + /// + /// See [VectorGraphic]. + const VectorGraphic({ + super.key, + required this.loader, + this.width, + this.height, + this.fit = BoxFit.contain, + this.alignment = Alignment.center, + this.semanticsLabel, + this.excludeFromSemantics = false, + this.clipBehavior = Clip.hardEdge, + this.placeholderBuilder, + this.errorBuilder, + this.colorFilter, + this.opacity, + this.clipViewbox = true, + this.matchTextDirection = false, + }) : strategy = RenderingStrategy.raster; + + /// A specialized constructor for flutter_svg interop. + const VectorGraphic._({ + super.key, + required this.loader, + this.width, + this.height, + this.fit = BoxFit.contain, + this.alignment = Alignment.center, + this.semanticsLabel, + this.excludeFromSemantics = false, + this.clipBehavior = Clip.hardEdge, + this.placeholderBuilder, + this.errorBuilder, + this.colorFilter, + this.opacity, + this.strategy = RenderingStrategy.picture, + this.clipViewbox = true, + this.matchTextDirection = false, + }); + + /// A delegate for fetching the raw bytes of the vector graphic. + /// + /// The [BytesLoader.loadBytes] method will be called with this + /// widget's [BuildContext] whenever dependencies change or the widget + /// configuration changes the loader. + final BytesLoader loader; + + /// If specified, the width to use for the vector graphic. If unspecified, + /// the vector graphic will take the width of its parent. + final double? width; + + /// If specified, the height to use for the vector graphic. If unspecified, + /// the vector graphic will take the height of its parent. + final double? height; + + /// How to inscribe the picture into the space allocated during layout. + /// The default is [BoxFit.contain]. + final BoxFit fit; + + /// How to align the picture within its parent widget. + /// + /// The alignment aligns the given position in the picture to the given position + /// in the layout bounds. For example, an [Alignment] alignment of (-1.0, + /// -1.0) aligns the image to the top-left corner of its layout bounds, while a + /// [Alignment] alignment of (1.0, 1.0) aligns the bottom right of the + /// picture with the bottom right corner of its layout bounds. Similarly, an + /// alignment of (0.0, 1.0) aligns the bottom middle of the image with the + /// middle of the bottom edge of its layout bounds. + /// + /// If the [alignment] is [TextDirection]-dependent (i.e. if it is a + /// [AlignmentDirectional]), then a [TextDirection] must be available + /// when the picture is painted. + /// + /// Defaults to [Alignment.center]. + /// + /// See also: + /// + /// * [Alignment], a class with convenient constants typically used to + /// specify an [AlignmentGeometry]. + /// * [AlignmentDirectional], like [Alignment] for specifying alignments + /// relative to text direction. + final AlignmentGeometry alignment; + + /// If true, will horizontally flip the picture in [TextDirection.rtl] contexts. + final bool matchTextDirection; + + /// The [Semantics] label for this picture. + /// + /// The value indicates the purpose of the picture, and will be read out by + /// screen readers. + final String? semanticsLabel; + + /// Whether to exclude this picture from semantics. + /// + /// Useful for pictures which do not contribute meaningful semantic information to an + /// application. + final bool excludeFromSemantics; + + /// The content will be clipped (or not) according to this option. + /// + /// See the enum [Clip] for details of all possible options and their common + /// use cases. + /// + /// Defaults to [Clip.hardEdge], and must not be null. + final Clip clipBehavior; + + /// The placeholder to use while fetching, decoding, and parsing the vector_graphics data. + final WidgetBuilder? placeholderBuilder; + + /// A callback that fires if some exception happens during data acquisition or decoding. + final VectorGraphicsErrorWidget? errorBuilder; + + /// If provided, a color filter to apply to the vector graphic when painting. + /// + /// For example, `ColorFilter.mode(Colors.red, BlendMode.srcIn)` to give the vector + /// graphic a solid red color. + /// + /// This is more efficient than using a [ColorFiltered] widget to wrap the vector + /// graphic, since this avoids creating a new composited layer. Composited layers + /// may double memory usage as the image is painted onto an offscreen render target. + /// + /// Example: + /// + /// ```dart + /// VectorGraphic(loader: _assetLoader, colorFilter: ColorFilter.mode(Colors.red, BlendMode.srcIn)); + /// ``` + final ColorFilter? colorFilter; + + /// If non-null, the value from the Animation is multiplied with the opacity + /// of each vector graphic pixel before painting onto the canvas. + /// + /// This is more efficient than using FadeTransition to change the opacity of an image, + /// since this avoids creating a new composited layer. Composited layers may double memory + /// usage as the image is painted onto an offscreen render target. + /// + /// This value does not apply to the widgets created by a [placeholderBuilder]. + /// + /// To provide a fixed opacity value, or to convert from a callback based API that + /// does not use animation objects, consider using an [AlwaysStoppedAnimation]. + /// + /// Example: + /// + /// ```dart + /// VectorGraphic(loader: _assetLoader, opacity: const AlwaysStoppedAnimation(0.33)); + /// ``` + final Animation? opacity; + + /// The rendering strategy used by the vector graphic. + /// + /// By default this is [RenderingStrategy.raster]. + final RenderingStrategy strategy; + + /// Whether the graphic should be clipped to its viewbox. + /// + /// If true, this adds a clip sized to the dimensions of the graphic before + /// drawing. This prevents the graphic from accidentally drawing outside of + /// its specified dimensions. Some graphics intentionally draw outside of + /// their specified dimensions and thus must not be clipped. + final bool clipViewbox; + + @override + State createState() => _VectorGraphicWidgetState(); +} + +class _PictureData { + _PictureData(this.pictureInfo, this.count, this.key); + + final PictureInfo pictureInfo; + _PictureKey key; + int count = 0; +} + +@immutable +class _PictureKey { + const _PictureKey( + this.cacheKey, this.locale, this.textDirection, this.clipViewbox); + + final Object cacheKey; + final Locale? locale; + final TextDirection? textDirection; + final bool clipViewbox; + + @override + int get hashCode => Object.hash(cacheKey, locale, textDirection, clipViewbox); + + @override + bool operator ==(Object other) => + other is _PictureKey && + other.cacheKey == cacheKey && + other.locale == locale && + other.textDirection == textDirection && + other.clipViewbox == clipViewbox; +} + +class _VectorGraphicWidgetState extends State { + _PictureData? _pictureInfo; + Object? _error; + StackTrace? _stackTrace; + Locale? locale; + TextDirection? textDirection; + + static final Map<_PictureKey, _PictureData> _livePictureCache = + <_PictureKey, _PictureData>{}; + static final Map<_PictureKey, Future<_PictureData>> _pendingPictures = + <_PictureKey, Future<_PictureData>>{}; + + @override + void didChangeDependencies() { + locale = Localizations.maybeLocaleOf(context); + textDirection = Directionality.maybeOf(context); + _loadAssetBytes(); + super.didChangeDependencies(); + } + + @override + void didUpdateWidget(covariant VectorGraphic oldWidget) { + if (oldWidget.loader != widget.loader) { + _loadAssetBytes(); + } + super.didUpdateWidget(oldWidget); + } + + @override + void dispose() { + _maybeReleasePicture(_pictureInfo); + _pictureInfo = null; + super.dispose(); + } + + void _maybeReleasePicture(_PictureData? data) { + if (data == null) { + return; + } + data.count -= 1; + if (data.count == 0 && _livePictureCache.containsKey(data.key)) { + _livePictureCache.remove(data.key); + data.pictureInfo.picture.dispose(); + } + } + + Future<_PictureData> _loadPicture( + BuildContext context, _PictureKey key, BytesLoader loader) { + if (_pendingPictures.containsKey(key)) { + return _pendingPictures[key]!; + } + final Future<_PictureData> result = + loader.loadBytes(context).then((ByteData data) { + return decodeVectorGraphics( + data, + locale: key.locale, + textDirection: key.textDirection, + clipViewbox: key.clipViewbox, + loader: loader, + onError: (Object error, StackTrace? stackTrace) { + return _handleError( + error, + stackTrace, + ); + }, + ); + }).then((PictureInfo pictureInfo) { + return _PictureData(pictureInfo, 0, key); + }); + _pendingPictures[key] = result; + result.whenComplete(() { + _pendingPictures.remove(key); + }); + return result; + } + + void _handleError(Object error, StackTrace? stackTrace) { + setState(() { + _error = error; + _stackTrace = stackTrace; + }); + } + + void _loadAssetBytes() { + // First check if we have an avilable picture and use this immediately. + final Object loaderKey = widget.loader.cacheKey(context); + final _PictureKey key = + _PictureKey(loaderKey, locale, textDirection, widget.clipViewbox); + final _PictureData? data = _livePictureCache[key]; + if (data != null) { + data.count += 1; + setState(() { + _maybeReleasePicture(_pictureInfo); + _pictureInfo = data; + }); + return; + } + // If not, then check if there is a pending load. + final BytesLoader loader = widget.loader; + _loadPicture(context, key, loader).then((_PictureData data) { + data.count += 1; + + // The widget may have changed, requesting a new vector graphic before + // this operation could complete. + if (!mounted || loader != widget.loader) { + _maybeReleasePicture(data); + return; + } + if (data.count == 1) { + _livePictureCache[key] = data; + } + setState(() { + _maybeReleasePicture(_pictureInfo); + _pictureInfo = data; + }); + }); + } + + static final bool _webRenderObject = useHtmlRenderObject(); + + @override + Widget build(BuildContext context) { + final PictureInfo? pictureInfo = _pictureInfo?.pictureInfo; + + Widget child; + if (pictureInfo != null) { + // If the caller did not specify a width or height, fall back to the + // size of the graphic. + // If the caller did specify a width or height, preserve the aspect ratio + // of the graphic and center it within that width and height. + double? width = widget.width; + double? height = widget.height; + + if (width == null && height == null) { + width = pictureInfo.size.width; + height = pictureInfo.size.height; + } else if (height != null && !pictureInfo.size.isEmpty) { + width = height / pictureInfo.size.height * pictureInfo.size.width; + } else if (width != null && !pictureInfo.size.isEmpty) { + height = width / pictureInfo.size.width * pictureInfo.size.height; + } + + assert(width != null && height != null); + + double scale = 1.0; + scale = math.min( + pictureInfo.size.width / width!, + pictureInfo.size.height / height!, + ); + + if (_webRenderObject) { + child = _RawWebVectorGraphicWidget( + pictureInfo: pictureInfo, + assetKey: _pictureInfo!.key, + colorFilter: widget.colorFilter, + opacity: widget.opacity, + ); + } else if (widget.strategy == RenderingStrategy.raster) { + child = _RawVectorGraphicWidget( + pictureInfo: pictureInfo, + assetKey: _pictureInfo!.key, + colorFilter: widget.colorFilter, + opacity: widget.opacity, + scale: scale, + ); + } else { + child = _RawPictureVectorGraphicWidget( + pictureInfo: pictureInfo, + assetKey: _pictureInfo!.key, + colorFilter: widget.colorFilter, + opacity: widget.opacity, + ); + } + + if (widget.matchTextDirection) { + final TextDirection direction = Directionality.of(context); + if (direction == TextDirection.rtl) { + child = Transform( + transform: Matrix4.identity() + ..translate(pictureInfo.size.width) + ..scale(-1.0, 1.0), + child: child, + ); + } + } + + child = SizedBox( + width: width, + height: height, + child: FittedBox( + fit: widget.fit, + alignment: widget.alignment, + clipBehavior: widget.clipBehavior, + child: SizedBox.fromSize( + size: pictureInfo.size, + child: child, + ), + ), + ); + } else if (_error != null && widget.errorBuilder != null) { + child = widget.errorBuilder!( + context, + _error!, + _stackTrace ?? StackTrace.empty, + ); + } else { + child = widget.placeholderBuilder?.call(context) ?? + SizedBox( + width: widget.width, + height: widget.height, + ); + } + + if (!widget.excludeFromSemantics) { + child = Semantics( + container: widget.semanticsLabel != null, + image: true, + label: widget.semanticsLabel ?? '', + child: child, + ); + } + return child; + } +} + +class _RawVectorGraphicWidget extends SingleChildRenderObjectWidget { + const _RawVectorGraphicWidget({ + required this.pictureInfo, + required this.colorFilter, + required this.opacity, + required this.scale, + required this.assetKey, + }); + + final PictureInfo pictureInfo; + final ColorFilter? colorFilter; + final double scale; + final Animation? opacity; + final Object assetKey; + + @override + RenderObject createRenderObject(BuildContext context) { + return RenderVectorGraphic( + pictureInfo, + assetKey, + colorFilter, + MediaQuery.maybeOf(context)?.devicePixelRatio ?? 1.0, + opacity, + scale, + ); + } + + @override + void updateRenderObject( + BuildContext context, + covariant RenderVectorGraphic renderObject, + ) { + renderObject + ..pictureInfo = pictureInfo + ..assetKey = assetKey + ..colorFilter = colorFilter + ..devicePixelRatio = MediaQuery.maybeOf(context)?.devicePixelRatio ?? 1.0 + ..opacity = opacity + ..scale = scale; + } +} + +class _RawWebVectorGraphicWidget extends SingleChildRenderObjectWidget { + const _RawWebVectorGraphicWidget({ + required this.pictureInfo, + required this.colorFilter, + required this.opacity, + required this.assetKey, + }); + + final PictureInfo pictureInfo; + final ColorFilter? colorFilter; + final Animation? opacity; + final Object assetKey; + + @override + RenderObject createRenderObject(BuildContext context) { + return RenderWebVectorGraphic( + pictureInfo, + assetKey, + colorFilter, + opacity, + ); + } + + @override + void updateRenderObject( + BuildContext context, + covariant RenderWebVectorGraphic renderObject, + ) { + renderObject + ..pictureInfo = pictureInfo + ..assetKey = assetKey + ..colorFilter = colorFilter + ..opacity = opacity; + } +} + +class _RawPictureVectorGraphicWidget extends SingleChildRenderObjectWidget { + const _RawPictureVectorGraphicWidget({ + required this.pictureInfo, + required this.colorFilter, + required this.opacity, + required this.assetKey, + }); + + final PictureInfo pictureInfo; + final ColorFilter? colorFilter; + final Animation? opacity; + final Object assetKey; + + @override + RenderObject createRenderObject(BuildContext context) { + return RenderPictureVectorGraphic( + pictureInfo, + colorFilter, + opacity, + ); + } + + @override + void updateRenderObject( + BuildContext context, + covariant RenderPictureVectorGraphic renderObject, + ) { + renderObject + ..pictureInfo = pictureInfo + ..colorFilter = colorFilter + ..opacity = opacity; + } +} + +/// Utility functionality for interaction with vector graphic assets. +class VectorGraphicUtilities { + const VectorGraphicUtilities._(); + + /// A future that completes when any in-flight vector graphic decodes have + /// completed. + /// + /// A vector graphic may require asynchronous work during decoding, for + /// example to decode an image that was embedded in the source graphic. This + /// method may be useful in golden image unit tests. + /// + /// ```dart + /// await tester.pumpWidget(MyWidgetThatHasVectorGraphics()); + /// await tester.runAsync(() => vg.waitForPendingDecodes()); + /// await expect( + /// find.byType(MyWidgetThatHasVectorGraphics), + /// matchesGoldenFile('golden_file.png'), + /// ); + /// ``` + /// + /// Without the `waitForPendingDecodes` call, the golden file would have the + /// placeholder for the [VectorGraphic] widgets, which defaults to a blank + /// sized box. + @visibleForTesting + Future waitForPendingDecodes() { + if (kDebugMode) { + // ignore: invalid_use_of_visible_for_testing_member + return Future.wait(debugGetPendingDecodeTasks); + } + throw UnsupportedError( + 'This method is only for use in tests in debug mode for tests.', + ); + } + + /// Load the [PictureInfo] from a given [loader]. + /// + /// It is the caller's responsibility to handle disposing the picture when + /// they are done with it. + Future loadPicture( + BytesLoader loader, + BuildContext? context, { + bool clipViewbox = true, + VectorGraphicsErrorListener? onError, + }) async { + TextDirection textDirection = TextDirection.ltr; + Locale locale = ui.PlatformDispatcher.instance.locale; + if (context != null) { + locale = Localizations.maybeLocaleOf(context) ?? locale; + textDirection = Directionality.maybeOf(context) ?? textDirection; + } + return loader.loadBytes(context).then((ByteData data) { + try { + return decodeVectorGraphics( + data, + locale: locale, + textDirection: textDirection, + loader: loader, + clipViewbox: clipViewbox, + onError: onError, + ); + } catch (e) { + debugPrint('Failed to decode $loader'); + rethrow; + } + }); + } +} + +/// The [VectorGraphicUtilities] instance. +const VectorGraphicUtilities vg = VectorGraphicUtilities._(); diff --git a/packages/vector_graphics/lib/vector_graphics.dart b/packages/vector_graphics/lib/vector_graphics.dart new file mode 100644 index 000000000000..f49df93d7475 --- /dev/null +++ b/packages/vector_graphics/lib/vector_graphics.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. + +export 'src/vector_graphics.dart' + show + AssetBytesLoader, + BytesLoader, + NetworkBytesLoader, + PictureInfo, + VectorGraphic, + VectorGraphicUtilities, + vg; diff --git a/packages/vector_graphics/lib/vector_graphics_compat.dart b/packages/vector_graphics/lib/vector_graphics_compat.dart new file mode 100644 index 000000000000..b3efc9f61459 --- /dev/null +++ b/packages/vector_graphics/lib/vector_graphics_compat.dart @@ -0,0 +1,15 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +export 'src/vector_graphics.dart' + show + AssetBytesLoader, + BytesLoader, + NetworkBytesLoader, + PictureInfo, + RenderingStrategy, + VectorGraphic, + VectorGraphicUtilities, + createCompatVectorGraphic, + vg; diff --git a/packages/vector_graphics/pubspec.yaml b/packages/vector_graphics/pubspec.yaml new file mode 100644 index 000000000000..2b74c23555ab --- /dev/null +++ b/packages/vector_graphics/pubspec.yaml @@ -0,0 +1,32 @@ +name: vector_graphics +description: A vector graphics rendering package for Flutter using a binary encoding. +repository: https://github.com/flutter/packages/tree/main/packages/vector_graphics +issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+vector_graphics%22 +version: 1.1.14 + +environment: + sdk: ^3.4.0 + flutter: ">=3.22.0" + +dependencies: + flutter: + sdk: flutter + http: ^1.0.0 + vector_graphics_codec: ^1.1.11+1 + +dev_dependencies: + flutter_test: + sdk: flutter + vector_graphics_compiler: ^1.1.11+1 + +platforms: + android: + ios: + linux: + macos: + web: + windows: + +topics: + - svg + - vector-graphics diff --git a/packages/vector_graphics/test/caching_test.dart b/packages/vector_graphics/test/caching_test.dart new file mode 100644 index 000000000000..0eb242e5a33a --- /dev/null +++ b/packages/vector_graphics/test/caching_test.dart @@ -0,0 +1,343 @@ +// 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:typed_data'; + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:vector_graphics/src/vector_graphics.dart'; +import 'package:vector_graphics_codec/vector_graphics_codec.dart'; + +const VectorGraphicsCodec codec = VectorGraphicsCodec(); + +void main() { + setUp(() { + imageCache.clear(); + imageCache.clearLiveImages(); + }); + + testWidgets( + 'Does not reload identical bytes when forced to re-create state object', + (WidgetTester tester) async { + final TestAssetBundle testBundle = TestAssetBundle(); + final GlobalKey key = GlobalKey(); + + await tester.pumpWidget(DefaultAssetBundle( + key: UniqueKey(), + bundle: testBundle, + child: VectorGraphic( + key: key, + loader: const AssetBytesLoader('foo.svg'), + ), + )); + + expect(testBundle.loadKeys.single, 'foo.svg'); + + await tester.pumpWidget(DefaultAssetBundle( + key: UniqueKey(), + bundle: testBundle, + child: VectorGraphic( + key: key, + loader: const AssetBytesLoader('foo.svg'), + ), + )); + + expect(testBundle.loadKeys, ['foo.svg']); + }); + + testWidgets('Only loads bytes once for a repeated vg', + (WidgetTester tester) async { + final TestAssetBundle testBundle = TestAssetBundle(); + + await tester.pumpWidget( + DefaultAssetBundle( + key: UniqueKey(), + bundle: testBundle, + child: Column( + children: [ + VectorGraphic( + key: GlobalKey(), + loader: const AssetBytesLoader('foo.svg'), + ), + VectorGraphic( + key: GlobalKey(), + loader: const AssetBytesLoader('foo.svg'), + ), + VectorGraphic( + key: GlobalKey(), + loader: const AssetBytesLoader('foo.svg'), + ), + ], + ), + ), + ); + + expect(testBundle.loadKeys.single, 'foo.svg'); + + await tester.pumpWidget(const SizedBox()); + + await tester.pumpWidget( + DefaultAssetBundle( + key: UniqueKey(), + bundle: testBundle, + child: Column( + children: [ + VectorGraphic( + key: GlobalKey(), + loader: const AssetBytesLoader('foo.svg'), + ), + VectorGraphic( + key: GlobalKey(), + loader: const AssetBytesLoader('foo.svg'), + ), + VectorGraphic( + key: GlobalKey(), + loader: const AssetBytesLoader('foo.svg'), + ), + ], + ), + ), + ); + + expect(testBundle.loadKeys, ['foo.svg', 'foo.svg']); + }); + + testWidgets('Does not cache bytes that come from different asset bundles', + (WidgetTester tester) async { + final TestAssetBundle testBundleA = TestAssetBundle(); + final TestAssetBundle testBundleB = TestAssetBundle(); + final GlobalKey key = GlobalKey(); + + await tester.pumpWidget(DefaultAssetBundle( + key: UniqueKey(), + bundle: testBundleA, + child: VectorGraphic( + key: key, + loader: const AssetBytesLoader('foo.svg'), + ), + )); + + expect(testBundleA.loadKeys.single, 'foo.svg'); + expect(testBundleB.loadKeys, isEmpty); + + await tester.pumpWidget(DefaultAssetBundle( + key: UniqueKey(), + bundle: testBundleB, + child: VectorGraphic( + key: key, + loader: const AssetBytesLoader('foo.svg'), + ), + )); + + expect(testBundleA.loadKeys.single, 'foo.svg'); + expect(testBundleB.loadKeys.single, 'foo.svg'); + }); + + testWidgets('reload bytes when locale changes', (WidgetTester tester) async { + final TestAssetBundle testBundle = TestAssetBundle(); + final GlobalKey key = GlobalKey(); + + await tester.pumpWidget( + Localizations( + delegates: >[ + TestLocalizationsDelegate() + ], + locale: const Locale('fr', 'CH'), + child: DefaultAssetBundle( + bundle: testBundle, + child: VectorGraphic( + key: key, + loader: const AssetBytesLoader('foo.svg'), + ), + ), + ), + ); + // async localization loading requires extra pump and settle. + await tester.pumpAndSettle(); + + expect(testBundle.loadKeys.single, 'foo.svg'); + + await tester.pumpWidget( + Localizations( + delegates: >[ + TestLocalizationsDelegate() + ], + locale: const Locale('ab', 'cd'), + child: DefaultAssetBundle( + bundle: testBundle, + child: VectorGraphic( + key: key, + loader: const AssetBytesLoader('foo.svg'), + ), + ), + ), + ); + // async localization loading requires extra pump and settle. + await tester.pumpAndSettle(); + + expect(testBundle.loadKeys, ['foo.svg', 'foo.svg']); + }); + + testWidgets('reload bytes when text direction changes', + (WidgetTester tester) async { + final TestAssetBundle testBundle = TestAssetBundle(); + final GlobalKey key = GlobalKey(); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: DefaultAssetBundle( + bundle: testBundle, + child: VectorGraphic( + key: key, + loader: const AssetBytesLoader('foo.svg'), + ), + ), + ), + ); + + expect(testBundle.loadKeys.single, 'foo.svg'); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.rtl, + child: DefaultAssetBundle( + bundle: testBundle, + child: VectorGraphic( + key: key, + loader: const AssetBytesLoader('foo.svg'), + ), + ), + ), + ); + + expect(testBundle.loadKeys, ['foo.svg', 'foo.svg']); + }); + + testWidgets( + 'Cache is purged immediately after last VectorGraphic removed from tree', + (WidgetTester tester) async { + final TestAssetBundle testBundle = TestAssetBundle(); + final GlobalKey key = GlobalKey(); + + await tester.pumpWidget(DefaultAssetBundle( + bundle: testBundle, + child: VectorGraphic( + key: key, + loader: const AssetBytesLoader('foo.svg'), + ), + )); + + expect(testBundle.loadKeys.single, 'foo.svg'); + + // Force VectorGraphic removed from tree. + await tester.pumpWidget(const SizedBox()); + + await tester.pumpWidget(DefaultAssetBundle( + bundle: testBundle, + child: VectorGraphic( + key: key, + loader: const AssetBytesLoader('foo.svg'), + ), + )); + + expect(testBundle.loadKeys, ['foo.svg', 'foo.svg']); + }); + + // For this test we evaluate an edge case where asset loading starts, but then a new + // asset is requested before the first can load. We want to ensure that first asset does + // not populate the cache in such a way that it gets "stuck". + testWidgets('Bytes loading that becomes stale does not populate the cache', + (WidgetTester tester) async { + final TestAssetBundle testBundle = TestAssetBundle(); + final GlobalKey key = GlobalKey(); + final ControlledAssetBytesLoader loader = + ControlledAssetBytesLoader('foo.svg'); + + await tester.pumpWidget(DefaultAssetBundle( + bundle: testBundle, + child: VectorGraphic( + key: key, + loader: loader, + ), + )); + + expect(testBundle.loadKeys, isEmpty); + + await tester.pumpWidget(DefaultAssetBundle( + bundle: testBundle, + child: VectorGraphic( + key: key, + loader: const AssetBytesLoader('bar.svg'), + ), + )); + + expect(testBundle.loadKeys, ['bar.svg']); + loader.completer.complete(); + await tester.pumpAndSettle(); + + expect(testBundle.loadKeys, ['bar.svg', 'foo.svg']); + + // Even though foo.svg was loaded above, it should have been immediately discarded since + // the vector graphic widget was no longer requesting it. Thus we should see it loaded + // a second time below. + await tester.pumpWidget(DefaultAssetBundle( + bundle: testBundle, + child: VectorGraphic( + key: key, + loader: const AssetBytesLoader('foo.svg'), + ), + )); + + expect(testBundle.loadKeys, ['bar.svg', 'foo.svg', 'foo.svg']); + }); +} + +class TestAssetBundle extends Fake implements AssetBundle { + final List loadKeys = []; + + @override + Future load(String key) async { + loadKeys.add(key); + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + codec.writeSize(buffer, 100, 200); + return buffer.done(); + } +} + +class ControlledAssetBytesLoader extends AssetBytesLoader { + ControlledAssetBytesLoader(super.assetName); + + final Completer completer = Completer(); + + @override + Future loadBytes(BuildContext? context) async { + await completer.future; + return super.loadBytes(context); + } +} + +class TestLocalizationsDelegate + extends LocalizationsDelegate { + @override + bool isSupported(Locale locale) { + return true; + } + + @override + Future load(Locale locale) async { + return TestWidgetsLocalizations(); + } + + @override + bool shouldReload(covariant LocalizationsDelegate old) { + return false; + } +} + +class TestWidgetsLocalizations extends DefaultWidgetsLocalizations { + @override + TextDirection get textDirection => TextDirection.ltr; +} diff --git a/packages/vector_graphics/test/debug_test.dart b/packages/vector_graphics/test/debug_test.dart new file mode 100644 index 000000000000..c9884548a8cf --- /dev/null +++ b/packages/vector_graphics/test/debug_test.dart @@ -0,0 +1,12 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:vector_graphics/src/debug.dart'; + +void main() { + test('debugSkipRaster is false by default', () { + expect(debugSkipRaster, false); + }); +} diff --git a/packages/vector_graphics/test/listener_test.dart b/packages/vector_graphics/test/listener_test.dart new file mode 100644 index 000000000000..cabf8051a11a --- /dev/null +++ b/packages/vector_graphics/test/listener_test.dart @@ -0,0 +1,170 @@ +// 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:convert' show base64; +import 'dart:typed_data'; +import 'dart:ui' as ui; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:vector_graphics/src/listener.dart'; +import 'package:vector_graphics/vector_graphics_compat.dart'; +import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; + +void main() { + WidgetsFlutterBinding.ensureInitialized(); + const String svgString = ''' + + + +'''; + + const String bluePngPixel = + 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPj/HwADBwIAMCbHYQAAAABJRU5ErkJggg=='; + + late ByteData vectorGraphicBuffer; + + setUpAll(() async { + final Uint8List bytes = encodeSvg( + xml: svgString, + debugName: 'test', + enableClippingOptimizer: false, + enableMaskingOptimizer: false, + enableOverdrawOptimizer: false, + ); + vectorGraphicBuffer = bytes.buffer.asByteData(); + }); + + setUp(() { + imageCache.clear(); + imageCache.clearLiveImages(); + }); + + test('decode without clip', () async { + final PictureInfo info = await decodeVectorGraphics( + vectorGraphicBuffer, + locale: ui.PlatformDispatcher.instance.locale, + textDirection: ui.TextDirection.ltr, + clipViewbox: true, + loader: const AssetBytesLoader('test'), + ); + final ui.Image image = info.picture.toImageSync(15, 15); + final Uint32List imageBytes = + (await image.toByteData())!.buffer.asUint32List(); + expect(imageBytes.first, 0xFF000000); + expect(imageBytes.last, 0x00000000); + }, skip: kIsWeb); + + test('decode with clip', () async { + final PictureInfo info = await decodeVectorGraphics( + vectorGraphicBuffer, + locale: ui.PlatformDispatcher.instance.locale, + textDirection: ui.TextDirection.ltr, + clipViewbox: false, + loader: const AssetBytesLoader('test'), + ); + final ui.Image image = info.picture.toImageSync(15, 15); + final Uint32List imageBytes = + (await image.toByteData())!.buffer.asUint32List(); + expect(imageBytes.first, 0xFF000000); + expect(imageBytes.last, 0xFF000000); + }, skip: kIsWeb); + + test('Scales image correctly', () async { + final TestPictureFactory factory = TestPictureFactory(); + final FlutterVectorGraphicsListener listener = + FlutterVectorGraphicsListener( + pictureFactory: factory, + ); + listener.onImage(0, 0, base64.decode(bluePngPixel)); + await listener.waitForImageDecode(); + listener.onDrawImage(0, 10, 10, 30, 30, null); + final Invocation drawRect = factory.fakeCanvases.first.invocations.single; + expect(drawRect.isMethod, true); + expect(drawRect.memberName, #drawImageRect); + expect( + drawRect.positionalArguments[1], + const ui.Rect.fromLTRB(0, 0, 1, 1), + ); + expect( + drawRect.positionalArguments[2], + const ui.Rect.fromLTRB(10, 10, 40, 40), + ); + }); + + test('Pattern start clips the new canvas', () async { + final TestPictureFactory factory = TestPictureFactory(); + final FlutterVectorGraphicsListener listener = + FlutterVectorGraphicsListener( + pictureFactory: factory, + ); + listener.onPatternStart(0, 0, 0, 100, 100, Matrix4.identity().storage); + final Invocation clipRect = factory.fakeCanvases.last.invocations.single; + expect(clipRect.isMethod, true); + expect(clipRect.memberName, #clipRect); + expect( + clipRect.positionalArguments.single, + const ui.Rect.fromLTRB(0, 0, 100, 100), + ); + }); + + test('Text position is respected', () async { + final TestPictureFactory factory = TestPictureFactory(); + final FlutterVectorGraphicsListener listener = + FlutterVectorGraphicsListener( + pictureFactory: factory, + ); + listener.onPaintObject( + color: const ui.Color(0xff000000).value, + strokeCap: null, + strokeJoin: null, + blendMode: BlendMode.srcIn.index, + strokeMiterLimit: null, + strokeWidth: null, + paintStyle: ui.PaintingStyle.fill.index, + id: 0, + shaderId: null, + ); + listener.onTextPosition(0, 10, 10, null, null, true, null); + listener.onUpdateTextPosition(0); + listener.onTextConfig('foo', null, 0, 0, 16, 0, 0, 0, 0); + await listener.onDrawText(0, 0, null, null); + await listener.onDrawText(0, 0, null, null); + + final Invocation drawParagraph0 = factory.fakeCanvases.last.invocations[0]; + final Invocation drawParagraph1 = factory.fakeCanvases.last.invocations[1]; + + expect(drawParagraph0.memberName, #drawParagraph); + // Only checking the X because Y seems to vary a bit by platform within + // acceptable range. X is what gets managed by the listener anyway. + expect((drawParagraph0.positionalArguments[1] as Offset).dx, 10); + + expect(drawParagraph1.memberName, #drawParagraph); + expect((drawParagraph1.positionalArguments[1] as Offset).dx, 58); + }); +} + +class TestPictureFactory implements PictureFactory { + final List fakeCanvases = []; + @override + ui.Canvas createCanvas(ui.PictureRecorder recorder) { + fakeCanvases.add(FakeCanvas()); + return fakeCanvases.last; + } + + @override + ui.PictureRecorder createPictureRecorder() => FakePictureRecorder(); +} + +class FakePictureRecorder extends Fake implements ui.PictureRecorder {} + +class FakeCanvas implements ui.Canvas { + final List invocations = []; + + @override + dynamic noSuchMethod(Invocation invocation) { + invocations.add(invocation); + } +} diff --git a/packages/vector_graphics/test/render_vector_graphics_test.dart b/packages/vector_graphics/test/render_vector_graphics_test.dart new file mode 100644 index 000000000000..bf5f12889ca9 --- /dev/null +++ b/packages/vector_graphics/test/render_vector_graphics_test.dart @@ -0,0 +1,560 @@ +// 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. + +// This Render Object is not used by the HTML renderer. +@TestOn('!chrome') +library; + +import 'dart:typed_data'; +import 'dart:ui' as ui; + +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:vector_graphics/src/listener.dart'; +import 'package:vector_graphics/src/render_vector_graphic.dart'; +import 'package:vector_graphics/vector_graphics.dart'; +import 'package:vector_graphics_codec/vector_graphics_codec.dart'; + +void main() { + late PictureInfo pictureInfo; + + tearDown(() { + // Since we don't always explicitly dispose render objects in unit tests, manually clear + // the rasters. + debugClearRasteCaches(); + }); + + setUpAll(() async { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + const VectorGraphicsCodec().writeSize(buffer, 50, 50); + + pictureInfo = await decodeVectorGraphics( + buffer.done(), + locale: const Locale('fr', 'CH'), + textDirection: TextDirection.ltr, + clipViewbox: true, + loader: TestBytesLoader(Uint8List(0).buffer.asByteData()), + ); + }); + + test('Rasterizes a picture to a draw image call', () async { + final RenderVectorGraphic renderVectorGraphic = RenderVectorGraphic( + pictureInfo, + 'test', + null, + 1.0, + null, + 1.0, + ); + renderVectorGraphic.layout(BoxConstraints.tight(const Size(50, 50))); + final FakePaintingContext context = FakePaintingContext(); + renderVectorGraphic.paint(context, Offset.zero); + + // When the rasterization is finished, it marks self as needing paint. + expect(renderVectorGraphic.debugNeedsPaint, true); + + renderVectorGraphic.paint(context, Offset.zero); + + expect(context.canvas.lastImage, isNotNull); + }); + + test('Multiple render objects with the same scale share a raster', () async { + final RenderVectorGraphic renderVectorGraphicA = RenderVectorGraphic( + pictureInfo, + 'test', + null, + 1.0, + null, + 1.0, + ); + final RenderVectorGraphic renderVectorGraphicB = RenderVectorGraphic( + pictureInfo, + 'test', + null, + 1.0, + null, + 1.0, + ); + renderVectorGraphicA.layout(BoxConstraints.tight(const Size(50, 50))); + renderVectorGraphicB.layout(BoxConstraints.tight(const Size(50, 50))); + final FakeHistoryPaintingContext context = FakeHistoryPaintingContext(); + + renderVectorGraphicA.paint(context, Offset.zero); + renderVectorGraphicB.paint(context, Offset.zero); + + // Same image is recycled. + expect(context.canvas.images, hasLength(2)); + expect(identical(context.canvas.images[0], context.canvas.images[1]), true); + }); + + test('disposing render object release raster', () async { + final RenderVectorGraphic renderVectorGraphicA = RenderVectorGraphic( + pictureInfo, + 'test', + null, + 1.0, + null, + 1.0, + ); + final RenderVectorGraphic renderVectorGraphicB = RenderVectorGraphic( + pictureInfo, + 'test', + null, + 1.0, + null, + 1.0, + ); + renderVectorGraphicA.layout(BoxConstraints.tight(const Size(50, 50))); + final FakeHistoryPaintingContext context = FakeHistoryPaintingContext(); + + renderVectorGraphicA.paint(context, Offset.zero); + + expect(context.canvas.images, hasLength(1)); + renderVectorGraphicA.dispose(); + + renderVectorGraphicB.layout(BoxConstraints.tight(const Size(50, 50))); + + renderVectorGraphicB.paint(context, Offset.zero); + expect(context.canvas.images, hasLength(2)); + expect( + identical(context.canvas.images[0], context.canvas.images[1]), false); + }); + + test( + 'Multiple render objects with the same scale share a raster, different load order', + () async { + final RenderVectorGraphic renderVectorGraphicA = RenderVectorGraphic( + pictureInfo, + 'test', + null, + 1.0, + null, + 1.0, + ); + final RenderVectorGraphic renderVectorGraphicB = RenderVectorGraphic( + pictureInfo, + 'test', + null, + 1.0, + null, + 1.0, + ); + renderVectorGraphicA.layout(BoxConstraints.tight(const Size(50, 50))); + final FakeHistoryPaintingContext context = FakeHistoryPaintingContext(); + + renderVectorGraphicA.paint(context, Offset.zero); + + expect(context.canvas.images, hasLength(1)); + + // Second rasterization immediately paints image. + renderVectorGraphicB.layout(BoxConstraints.tight(const Size(50, 50))); + renderVectorGraphicB.paint(context, Offset.zero); + + expect(context.canvas.images, hasLength(2)); + expect(identical(context.canvas.images[0], context.canvas.images[1]), true); + }); + + test('Changing color filter does not re-rasterize', () async { + final RenderVectorGraphic renderVectorGraphic = RenderVectorGraphic( + pictureInfo, + 'test', + null, + 1.0, + null, + 1.0, + ); + renderVectorGraphic.layout(BoxConstraints.tight(const Size(50, 50))); + final FakePaintingContext context = FakePaintingContext(); + renderVectorGraphic.paint(context, Offset.zero); + + final ui.Image firstImage = context.canvas.lastImage!; + + renderVectorGraphic.colorFilter = + const ui.ColorFilter.mode(Colors.red, ui.BlendMode.colorBurn); + renderVectorGraphic.paint(context, Offset.zero); + + expect(firstImage.debugDisposed, false); + + renderVectorGraphic.paint(context, Offset.zero); + + expect(context.canvas.lastImage, equals(firstImage)); + }); + + test('Changing device pixel ratio does re-rasterize and dispose old raster', + () async { + final RenderVectorGraphic renderVectorGraphic = RenderVectorGraphic( + pictureInfo, + 'test', + null, + 1.0, + null, + 1.0, + ); + renderVectorGraphic.layout(BoxConstraints.tight(const Size(50, 50))); + final FakePaintingContext context = FakePaintingContext(); + renderVectorGraphic.paint(context, Offset.zero); + + final ui.Image firstImage = context.canvas.lastImage!; + + renderVectorGraphic.devicePixelRatio = 2.0; + renderVectorGraphic.paint(context, Offset.zero); + + expect(firstImage.debugDisposed, true); + + renderVectorGraphic.paint(context, Offset.zero); + + expect(context.canvas.lastImage!.debugDisposed, false); + }); + + test('Changing scale does re-rasterize and dispose old raster', () async { + final RenderVectorGraphic renderVectorGraphic = RenderVectorGraphic( + pictureInfo, + 'test', + null, + 1.0, + null, + 1.0, + ); + renderVectorGraphic.layout(BoxConstraints.tight(const Size(50, 50))); + final FakePaintingContext context = FakePaintingContext(); + renderVectorGraphic.paint(context, Offset.zero); + + final ui.Image firstImage = context.canvas.lastImage!; + + renderVectorGraphic.scale = 2.0; + renderVectorGraphic.paint(context, Offset.zero); + + expect(firstImage.debugDisposed, true); + + renderVectorGraphic.paint(context, Offset.zero); + + expect(context.canvas.lastImage!.debugDisposed, false); + }); + + test('The raster size is increased by the inverse picture scale', () async { + final RenderVectorGraphic renderVectorGraphic = RenderVectorGraphic( + pictureInfo, + 'test', + null, + 1.0, + null, + 0.5, // twice as many pixels + ); + renderVectorGraphic.layout(BoxConstraints.tight(const Size(50, 50))); + final FakePaintingContext context = FakePaintingContext(); + renderVectorGraphic.paint(context, Offset.zero); + + // Dst rect is always size of RO. + expect(context.canvas.lastDst, const Rect.fromLTWH(0, 0, 50, 50)); + expect( + context.canvas.lastSrc, const Rect.fromLTWH(0, 0, 50 / 0.5, 50 / 0.5)); + }); + + test('The raster size is increased by the device pixel ratio', () async { + final RenderVectorGraphic renderVectorGraphic = RenderVectorGraphic( + pictureInfo, + 'test', + null, + 2.0, + null, + 1.0, + ); + renderVectorGraphic.layout(BoxConstraints.tight(const Size(50, 50))); + final FakePaintingContext context = FakePaintingContext(); + renderVectorGraphic.paint(context, Offset.zero); + + // Dst rect is always size of RO. + expect(context.canvas.lastDst, const Rect.fromLTWH(0, 0, 50, 50)); + expect(context.canvas.lastSrc, const Rect.fromLTWH(0, 0, 100, 100)); + }); + + test('The raster size is increased by the device pixel ratio and ratio', + () async { + final RenderVectorGraphic renderVectorGraphic = RenderVectorGraphic( + pictureInfo, + 'test', + null, + 2.0, + null, + 0.5, + ); + renderVectorGraphic.layout(BoxConstraints.tight(const Size(50, 50))); + final FakePaintingContext context = FakePaintingContext(); + renderVectorGraphic.paint(context, Offset.zero); + + // Dst rect is always size of RO. + expect(context.canvas.lastDst, const Rect.fromLTWH(0, 0, 50, 50)); + expect(context.canvas.lastSrc, const Rect.fromLTWH(0, 0, 200, 200)); + }); + + test('Changing size asserts if it is different from the picture size', + () async { + final RenderVectorGraphic renderVectorGraphic = RenderVectorGraphic( + pictureInfo, + 'test', + null, + 1.0, + null, + 1.0, + ); + renderVectorGraphic.layout(BoxConstraints.tight(const Size(50, 50))); + final FakePaintingContext context = FakePaintingContext(); + renderVectorGraphic.paint(context, Offset.zero); + + // change size. + renderVectorGraphic.layout(BoxConstraints.tight(const Size(1000, 1000))); + + expect(() => renderVectorGraphic.paint(context, Offset.zero), + throwsAssertionError); + }); + + test('Does not rasterize a picture when fully transparent', () async { + final FixedOpacityAnimation opacity = FixedOpacityAnimation(0.0); + final RenderVectorGraphic renderVectorGraphic = RenderVectorGraphic( + pictureInfo, + 'test', + null, + 1.0, + opacity, + 1.0, + ); + renderVectorGraphic.layout(BoxConstraints.tight(const Size(50, 50))); + final FakePaintingContext context = FakePaintingContext(); + renderVectorGraphic.paint(context, Offset.zero); + + opacity.value = 1.0; + opacity.notifyListeners(); + + // Changing opacity requires painting. + expect(renderVectorGraphic.debugNeedsPaint, true); + + renderVectorGraphic.paint(context, Offset.zero); + + // Rasterization is now complete. + expect(context.canvas.lastImage, isNotNull); + }); + + test('paints partially opaque picture', () async { + final FixedOpacityAnimation opacity = FixedOpacityAnimation(0.5); + final RenderVectorGraphic renderVectorGraphic = RenderVectorGraphic( + pictureInfo, + 'test', + null, + 1.0, + opacity, + 1.0, + ); + renderVectorGraphic.layout(BoxConstraints.tight(const Size(50, 50))); + final FakePaintingContext context = FakePaintingContext(); + renderVectorGraphic.paint(context, Offset.zero); + + expect(context.canvas.lastPaint?.color, const Color.fromRGBO(0, 0, 0, 0.5)); + }); + + test('Disposing render object disposes picture', () async { + final RenderVectorGraphic renderVectorGraphic = RenderVectorGraphic( + pictureInfo, + 'test', + null, + 1.0, + null, + 1.0, + ); + renderVectorGraphic.layout(BoxConstraints.tight(const Size(50, 50))); + final FakePaintingContext context = FakePaintingContext(); + renderVectorGraphic.paint(context, Offset.zero); + + final ui.Image lastImage = context.canvas.lastImage!; + + renderVectorGraphic.dispose(); + + expect(lastImage.debugDisposed, true); + }); + + test('Removes listeners on detach, dispose, adds then on attach', () async { + final FixedOpacityAnimation opacity = FixedOpacityAnimation(0.5); + final RenderVectorGraphic renderVectorGraphic = RenderVectorGraphic( + pictureInfo, + 'test', + null, + 1.0, + opacity, + 1.0, + ); + final PipelineOwner pipelineOwner = PipelineOwner(); + expect(opacity._listeners, hasLength(1)); + + renderVectorGraphic.attach(pipelineOwner); + expect(opacity._listeners, hasLength(1)); + + renderVectorGraphic.detach(); + expect(opacity._listeners, hasLength(0)); + + renderVectorGraphic.attach(pipelineOwner); + expect(opacity._listeners, hasLength(1)); + + renderVectorGraphic.dispose(); + expect(opacity._listeners, hasLength(0)); + }); + + test('RasterData.dispose is safe to call multiple times', () async { + final ui.PictureRecorder recorder = ui.PictureRecorder(); + ui.Canvas(recorder); + final ui.Image image = await recorder.endRecording().toImage(1, 1); + final RasterData data = RasterData(image, 1, const RasterKey('test', 1, 1)); + + data.dispose(); + + expect(data.dispose, returnsNormally); + }); + + test('Color filter applies clip', () async { + final RenderPictureVectorGraphic render = RenderPictureVectorGraphic( + pictureInfo, + const ui.ColorFilter.mode(Colors.green, ui.BlendMode.difference), + null, + ); + render.layout(BoxConstraints.tight(const Size(50, 50))); + final FakePaintingContext context = FakePaintingContext(); + render.paint(context, Offset.zero); + + expect(context.canvas.lastClipRect, + equals(const ui.Rect.fromLTRB(0, 0, 50, 50))); + expect(context.canvas.saveCount, 0); + expect(context.canvas.totalSaves, 1); + expect(context.canvas.totalSaveLayers, 1); + }); +} + +class FakeCanvas extends Fake implements Canvas { + ui.Image? lastImage; + Rect? lastSrc; + Rect? lastDst; + Paint? lastPaint; + Rect? lastClipRect; + int saveCount = 0; + int totalSaves = 0; + int totalSaveLayers = 0; + + @override + void drawImageRect(ui.Image image, Rect src, Rect dst, Paint paint) { + lastImage = image; + lastSrc = src; + lastDst = dst; + lastPaint = paint; + } + + @override + void drawPicture(ui.Picture picture) {} + + @override + int getSaveCount() { + return saveCount; + } + + @override + void restoreToCount(int count) { + saveCount = count; + } + + @override + void saveLayer(Rect? bounds, Paint paint) { + saveCount++; + totalSaveLayers++; + } + + @override + void save() { + saveCount++; + totalSaves++; + } + + @override + void restore() { + saveCount--; + } + + @override + void clipRect(ui.Rect rect, + {ui.ClipOp clipOp = ui.ClipOp.intersect, bool doAntiAlias = true}) { + lastClipRect = rect; + } +} + +class FakeHistoryCanvas extends Fake implements Canvas { + final List images = []; + + @override + void drawImageRect(ui.Image image, Rect src, Rect dst, Paint paint) { + images.add(image); + } +} + +class FakePaintingContext extends Fake implements PaintingContext { + @override + final FakeCanvas canvas = FakeCanvas(); +} + +class FakeHistoryPaintingContext extends Fake implements PaintingContext { + @override + final FakeHistoryCanvas canvas = FakeHistoryCanvas(); +} + +class FixedOpacityAnimation extends Animation { + FixedOpacityAnimation(this.value); + + final Set _listeners = {}; + + @override + void addListener(ui.VoidCallback listener) { + _listeners.add(listener); + } + + @override + void addStatusListener(AnimationStatusListener listener) { + throw UnsupportedError('addStatusListener'); + } + + @override + void removeListener(ui.VoidCallback listener) { + _listeners.remove(listener); + } + + @override + void removeStatusListener(AnimationStatusListener listener) { + throw UnsupportedError('removeStatusListener'); + } + + @override + AnimationStatus get status => AnimationStatus.forward; + + @override + double value = 1.0; + + void notifyListeners() { + for (final ui.VoidCallback listener in _listeners) { + listener(); + } + } +} + +class TestBytesLoader extends BytesLoader { + const TestBytesLoader(this.data); + + final ByteData data; + + @override + Future loadBytes(BuildContext? context) async { + return data; + } + + @override + int get hashCode => data.hashCode; + + @override + bool operator ==(Object other) { + return other is TestBytesLoader && other.data == data; + } +} diff --git a/packages/vector_graphics/test/vector_graphics_test.dart b/packages/vector_graphics/test/vector_graphics_test.dart new file mode 100644 index 000000000000..33da9600af7c --- /dev/null +++ b/packages/vector_graphics/test/vector_graphics_test.dart @@ -0,0 +1,721 @@ +// 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:convert' show base64Decode; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:vector_graphics/src/listener.dart'; +import 'package:vector_graphics/src/vector_graphics.dart'; +import 'package:vector_graphics_codec/vector_graphics_codec.dart'; + +const VectorGraphicsCodec codec = VectorGraphicsCodec(); + +void main() { + setUp(() { + imageCache.clear(); + imageCache.clearLiveImages(); + }); + + test('Can decode a message without a stroke and vertices', () { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + final FlutterVectorGraphicsListener listener = + FlutterVectorGraphicsListener(); + final int paintId = codec.writeStroke(buffer, 44, 1, 2, 3, 4.0, 6.0); + codec.writeDrawVertices( + buffer, + Float32List.fromList([ + 0.0, + 2.0, + 3.0, + 4.0, + 2.0, + 4.0, + ]), + null, + paintId); + + codec.decode(buffer.done(), listener); + + expect(listener.toPicture, returnsNormally); + }); + + test('Can decode a message with a fill and path', () { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + final FlutterVectorGraphicsListener listener = + FlutterVectorGraphicsListener(); + final int paintId = codec.writeFill(buffer, 23, 0); + final int pathId = codec.writePath( + buffer, + Uint8List.fromList([ + ControlPointTypes.moveTo, + ControlPointTypes.lineTo, + ControlPointTypes.close, + ]), + Float32List.fromList([ + 1, + 2, + 2, + 3, + ]), + 0, + ); + codec.writeDrawPath(buffer, pathId, paintId, null); + + codec.decode(buffer.done(), listener); + + expect(listener.toPicture, returnsNormally); + }); + + test('Asserts if toPicture is called more than once', () { + final FlutterVectorGraphicsListener listener = + FlutterVectorGraphicsListener(); + listener.toPicture(); + + expect(listener.toPicture, throwsAssertionError); + }); + + testWidgets( + 'Creates layout widgets when VectorGraphic is sized (0x0 graphic)', + (WidgetTester tester) async { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + await tester.pumpWidget(VectorGraphic( + loader: TestBytesLoader(buffer.done()), + width: 100, + height: 100, + )); + await tester.pumpAndSettle(); + + expect(find.byType(SizedBox), findsNWidgets(2)); + + final SizedBox sizedBox = + find.byType(SizedBox).evaluate().first.widget as SizedBox; + + expect(sizedBox.width, 100); + expect(sizedBox.height, 100); + }); + + testWidgets('Creates layout widgets when VectorGraphic is sized (1:1 ratio)', + (WidgetTester tester) async { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + const VectorGraphicsCodec().writeSize(buffer, 50, 50); + await tester.pumpWidget(VectorGraphic( + loader: TestBytesLoader(buffer.done()), + width: 100, + height: 100, + )); + await tester.pumpAndSettle(); + + expect(find.byType(SizedBox), findsNWidgets(2)); + + final SizedBox sizedBox = + find.byType(SizedBox).evaluate().first.widget as SizedBox; + + expect(sizedBox.width, 100); + expect(sizedBox.height, 100); + }); + + testWidgets('Creates layout widgets when VectorGraphic is sized (3:5 ratio)', + (WidgetTester tester) async { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + const VectorGraphicsCodec().writeSize(buffer, 30, 50); + await tester.pumpWidget(VectorGraphic( + loader: TestBytesLoader(buffer.done()), + width: 100, + height: 100, + )); + await tester.pumpAndSettle(); + + expect(find.byType(SizedBox), findsNWidgets(2)); + + final SizedBox sizedBox = + find.byType(SizedBox).evaluate().first.widget as SizedBox; + + expect(sizedBox.width, 60); + expect(sizedBox.height, 100); + }); + + testWidgets('Creates alignment widgets when VectorGraphic is aligned', + (WidgetTester tester) async { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + await tester.pumpWidget(VectorGraphic( + loader: TestBytesLoader(buffer.done()), + alignment: Alignment.centerLeft, + fit: BoxFit.fitHeight, + )); + await tester.pumpAndSettle(); + + expect(find.byType(FittedBox), findsOneWidget); + + final FittedBox fittedBox = + find.byType(FittedBox).evaluate().first.widget as FittedBox; + + expect(fittedBox.fit, BoxFit.fitHeight); + expect(fittedBox.alignment, Alignment.centerLeft); + expect(fittedBox.clipBehavior, Clip.hardEdge); + }); + + group('ClipBehavior', () { + testWidgets('Sets clipBehavior to hardEdge if not provided', + (WidgetTester tester) async { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + await tester.pumpWidget(VectorGraphic( + loader: TestBytesLoader(buffer.done()), + )); + await tester.pumpAndSettle(); + + expect(find.byType(FittedBox), findsOneWidget); + + final FittedBox fittedBox = + find.byType(FittedBox).evaluate().first.widget as FittedBox; + + expect(fittedBox.clipBehavior, Clip.hardEdge); + }); + + testWidgets('Passes clipBehavior to FittedBox if provided', + (WidgetTester tester) async { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + await tester.pumpWidget(VectorGraphic( + loader: TestBytesLoader(buffer.done()), + clipBehavior: Clip.none, + )); + await tester.pumpAndSettle(); + + expect(find.byType(FittedBox), findsOneWidget); + + final FittedBox fittedBox = + find.byType(FittedBox).evaluate().first.widget as FittedBox; + + expect(fittedBox.clipBehavior, Clip.none); + }); + }); + + testWidgets('Sizes VectorGraphic based on encoded viewbox information', + (WidgetTester tester) async { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + codec.writeSize(buffer, 100, 200); + + await tester.pumpWidget(VectorGraphic( + loader: TestBytesLoader(buffer.done()), + )); + await tester.pumpAndSettle(); + + expect(find.byType(SizedBox), findsNWidgets(2)); + + final SizedBox sizedBox = + find.byType(SizedBox).evaluate().last.widget as SizedBox; + + expect(sizedBox.width, 100); + expect(sizedBox.height, 200); + }); + + testWidgets('Reloads bytes when configuration changes', + (WidgetTester tester) async { + final TestAssetBundle testBundle = TestAssetBundle(); + final GlobalKey key = GlobalKey(); + + await tester.pumpWidget(DefaultAssetBundle( + bundle: testBundle, + child: VectorGraphic( + key: key, + loader: const AssetBytesLoader('foo.svg'), + ), + )); + + expect(testBundle.loadKeys.single, 'foo.svg'); + + await tester.pumpWidget(DefaultAssetBundle( + bundle: testBundle, + child: VectorGraphic( + key: key, + loader: const AssetBytesLoader('bar.svg'), + ), + )); + + expect(testBundle.loadKeys, ['foo.svg', 'bar.svg']); + }); + + testWidgets('Can update SVG picture', (WidgetTester tester) async { + final TestAssetBundle testBundle = TestAssetBundle(); + + await tester.pumpWidget( + DefaultAssetBundle( + bundle: testBundle, + child: const VectorGraphic( + loader: AssetBytesLoader('foo.svg'), + ), + ), + ); + await tester.pumpAndSettle(); + + expect(tester.layers, contains(isA())); + + await tester.pumpWidget( + DefaultAssetBundle( + bundle: testBundle, + child: const VectorGraphic( + loader: AssetBytesLoader('bar.svg'), + ), + ), + ); + await tester.pumpAndSettle(); + + expect(tester.layers, contains(isA())); + }); + + testWidgets('Can set locale and text direction', (WidgetTester tester) async { + final TestAssetBundle testBundle = TestAssetBundle(); + await tester.pumpWidget( + Localizations( + delegates: const >[ + DefaultWidgetsLocalizations.delegate + ], + locale: const Locale('fr', 'CH'), + child: Directionality( + textDirection: TextDirection.rtl, + child: DefaultAssetBundle( + bundle: testBundle, + child: const VectorGraphic( + loader: AssetBytesLoader('bar.svg'), + ), + ), + ), + ), + ); + await tester.pumpAndSettle(); + + expect(debugLastLocale, const Locale('fr', 'CH')); + expect(debugLastTextDirection, TextDirection.rtl); + + await tester.pumpWidget( + Localizations( + delegates: const >[ + DefaultWidgetsLocalizations.delegate + ], + locale: const Locale('ab', 'AB'), + child: Directionality( + textDirection: TextDirection.ltr, + child: DefaultAssetBundle( + bundle: testBundle, + child: const VectorGraphic( + loader: AssetBytesLoader('bar.svg'), + ), + ), + ), + ), + ); + await tester.pumpAndSettle(); + + expect(debugLastLocale, const Locale('ab', 'AB')); + expect(debugLastTextDirection, TextDirection.ltr); + }); + + testWidgets('Can exclude from semantics', (WidgetTester tester) async { + final TestAssetBundle testBundle = TestAssetBundle(); + + await tester.pumpWidget( + DefaultAssetBundle( + bundle: testBundle, + child: const VectorGraphic( + loader: AssetBytesLoader('foo.svg'), + excludeFromSemantics: true, + semanticsLabel: 'Foo', + ), + ), + ); + await tester.pumpAndSettle(); + + expect(find.bySemanticsLabel('Foo'), findsNothing); + }); + + testWidgets('Can add semantic label', (WidgetTester tester) async { + final TestAssetBundle testBundle = TestAssetBundle(); + + await tester.pumpWidget( + DefaultAssetBundle( + bundle: testBundle, + child: const Directionality( + textDirection: TextDirection.ltr, + child: VectorGraphic( + loader: AssetBytesLoader('foo.svg'), + semanticsLabel: 'Foo', + ), + ), + ), + ); + await tester.pumpAndSettle(); + + expect( + tester.getSemantics(find.bySemanticsLabel('Foo')), + matchesSemantics( + label: 'Foo', + isImage: true, + ), + ); + }); + + testWidgets('Default placeholder builder', (WidgetTester tester) async { + final TestAssetBundle testBundle = TestAssetBundle(); + + await tester.pumpWidget( + DefaultAssetBundle( + bundle: testBundle, + child: const Directionality( + textDirection: TextDirection.ltr, + child: VectorGraphic( + loader: AssetBytesLoader('foo.svg'), + semanticsLabel: 'Foo', + ), + ), + ), + ); + + expect(find.byType(SizedBox), findsOneWidget); + }); + + testWidgets('Custom placeholder builder', (WidgetTester tester) async { + final TestAssetBundle testBundle = TestAssetBundle(); + + await tester.pumpWidget( + DefaultAssetBundle( + bundle: testBundle, + child: Directionality( + textDirection: TextDirection.ltr, + child: VectorGraphic( + loader: const AssetBytesLoader('foo.svg'), + semanticsLabel: 'Foo', + placeholderBuilder: (BuildContext context) { + return Container(key: const ValueKey(23)); + }, + ), + ), + ), + ); + + expect(find.byKey(const ValueKey(23)), findsOneWidget); + }); + + testWidgets('Does not call setState after unmounting', + (WidgetTester tester) async { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + codec.writeSize(buffer, 100, 200); + final Completer completer = Completer(); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: VectorGraphic( + loader: DelayedBytesLoader(completer.future), + ), + ), + ); + await tester.pumpWidget(const Placeholder()); + completer.complete(buffer.done()); + }); + + testWidgets('Loads a picture with loadPicture', (WidgetTester tester) async { + final TestAssetBundle testBundle = TestAssetBundle(); + final Completer completer = Completer(); + await tester.pumpWidget( + Localizations( + delegates: const >[ + DefaultWidgetsLocalizations.delegate + ], + locale: const Locale('fr', 'CH'), + child: Directionality( + textDirection: TextDirection.rtl, + child: DefaultAssetBundle( + bundle: testBundle, + child: Builder(builder: (BuildContext context) { + vg + .loadPicture(const AssetBytesLoader('foo.svg'), context) + .then(completer.complete); + return const Center(); + }), + ), + ), + ), + ); + await tester.pumpAndSettle(); + + expect(await completer.future, isA()); + expect(debugLastLocale, const Locale('fr', 'CH')); + expect(debugLastTextDirection, TextDirection.rtl); + }); + + testWidgets('Loads a picture with loadPicture and null build context', + (WidgetTester tester) async { + final TestAssetBundle testBundle = TestAssetBundle(); + final Completer completer = Completer(); + await tester.pumpWidget( + Localizations( + delegates: const >[ + DefaultWidgetsLocalizations.delegate + ], + locale: const Locale('fr', 'CH'), + child: Directionality( + textDirection: TextDirection.rtl, + child: DefaultAssetBundle( + bundle: testBundle, + child: Builder(builder: (BuildContext context) { + vg + .loadPicture( + AssetBytesLoader('foo.svg', assetBundle: testBundle), + null) + .then(completer.complete); + return const Center(); + }), + ), + ), + ), + ); + await tester.pumpAndSettle(); + + expect(await completer.future, isA()); + expect(debugLastLocale, PlatformDispatcher.instance.locale); + expect(debugLastTextDirection, TextDirection.ltr); + }); + + testWidgets('Throws a helpful exception if decoding fails', + (WidgetTester tester) async { + final Uint8List data = Uint8List(256); + final TestBytesLoader loader = TestBytesLoader( + data.buffer.asByteData(), + '/foo/bar/whatever.vec', + ); + final GlobalKey key = GlobalKey(); + await tester.pumpWidget(Placeholder(key: key)); + + late final VectorGraphicsDecodeException exception; + try { + await vg.loadPicture(loader, key.currentContext); + } on VectorGraphicsDecodeException catch (e) { + exception = e; + } + + expect(exception.source, loader); + expect(exception.originalException, isA()); + expect(exception.toString(), contains(loader.toString())); + }); + + testWidgets( + 'Construct vector graphic with drawPicture strategy', + (WidgetTester tester) async { + final TestAssetBundle testBundle = TestAssetBundle(); + + await tester.pumpWidget( + DefaultAssetBundle( + bundle: testBundle, + child: Directionality( + textDirection: TextDirection.ltr, + child: createCompatVectorGraphic( + loader: const AssetBytesLoader('foo.svg'), + colorFilter: const ColorFilter.mode(Colors.red, BlendMode.srcIn), + opacity: const AlwaysStoppedAnimation(0.5), + ), + ), + ), + ); + await tester.pumpAndSettle(); + + expect(tester.layers.last, isA()); + // Opacity and color filter are drawn as savelayer + expect(tester.layers, isNot(contains(isA()))); + expect(tester.layers, isNot(contains(isA()))); + }, + skip: kIsWeb, + ); // picture rasterization works differently on HTML due to saveLayer bugs in HTML backend + + testWidgets('Can render VG with image', (WidgetTester tester) async { + const String bluePngPixel = + 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPj/HwADBwIAMCbHYQAAAABJRU5ErkJggg=='; + + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + const VectorGraphicsCodec codec = VectorGraphicsCodec(); + codec.writeSize(buffer, 100, 100); + + codec.writeDrawImage( + buffer, + codec.writeImage(buffer, 0, base64Decode(bluePngPixel)), + 0, + 0, + 100, + 100, + null, + ); + final UniqueKey key = UniqueKey(); + final TestBytesLoader loader = TestBytesLoader(buffer.done()); + // See listener.dart. + final int imageKey = Object.hash(loader.hashCode, 0, 0); + + expect(imageCache.currentSize, 0); + expect(imageCache.statusForKey(imageKey).untracked, true); + + await tester.pumpWidget(RepaintBoundary( + key: key, + child: VectorGraphic( + loader: loader, + width: 100, + height: 100, + ), + )); + + expect(imageCache.currentSize, 0); + expect(imageCache.statusForKey(imageKey).pending, true); + + // A blank image, because the image hasn't loaded yet. + await expectLater( + find.byKey(key), + matchesGoldenFile('vg_with_image_blank.png'), + ); + + expect(imageCache.currentSize, 1); + expect(imageCache.statusForKey(imageKey).live, false); + expect(imageCache.statusForKey(imageKey).keepAlive, true); + + await tester.runAsync(() => vg.waitForPendingDecodes()); + await tester.pump(); + + expect(imageCache.currentSize, 1); + expect(imageCache.statusForKey(imageKey).live, false); + expect(imageCache.statusForKey(imageKey).keepAlive, true); + + // A blue square, becuase the image is available now. + await expectLater( + find.byKey(key), + matchesGoldenFile('vg_with_image_blue.png'), + ); + }, skip: kIsWeb); + + test('AssetBytesLoader respects packages', () async { + final TestBundle bundle = TestBundle({ + 'foo': Uint8List(0).buffer.asByteData(), + 'packages/packageName/foo': Uint8List(1).buffer.asByteData(), + }); + final AssetBytesLoader loader = + AssetBytesLoader('foo', assetBundle: bundle); + final AssetBytesLoader packageLoader = AssetBytesLoader('foo', + assetBundle: bundle, packageName: 'packageName'); + expect((await loader.loadBytes(null)).lengthInBytes, 0); + expect((await packageLoader.loadBytes(null)).lengthInBytes, 1); + }); + + testWidgets('Respects text direction', (WidgetTester tester) async { + final TestAssetBundle testBundle = TestAssetBundle(); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.rtl, + child: DefaultAssetBundle( + bundle: testBundle, + child: const VectorGraphic( + loader: AssetBytesLoader('foo.svg'), + ), + ), + ), + ); + await tester.pumpAndSettle(); + + expect(find.byType(Transform), findsNothing); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.rtl, + child: DefaultAssetBundle( + bundle: testBundle, + child: const VectorGraphic( + loader: AssetBytesLoader('foo.svg'), + matchTextDirection: true, + ), + ), + ), + ); + await tester.pumpAndSettle(); + + final Matrix4 matrix = Matrix4.identity(); + final RenderObject transformObject = + find.byType(Transform).evaluate().first.renderObject!; + bool visited = false; + transformObject.visitChildren((RenderObject child) { + if (!visited) { + transformObject.applyPaintTransform(child, matrix); + } + visited = true; + }); + expect(visited, true); + expect(matrix.getTranslation().x, + 100); // Width specified in the TestAssetBundle. + expect(matrix.getTranslation().y, 0); + expect(matrix.row0.x, -1); + expect(matrix.row1.y, 1); + }); +} + +class TestBundle extends Fake implements AssetBundle { + TestBundle(this.map); + + final Map map; + + @override + Future load(String key) async { + return map[key]!; + } +} + +class TestAssetBundle extends Fake implements AssetBundle { + final List loadKeys = []; + + @override + Future load(String key) async { + loadKeys.add(key); + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + codec.writeSize(buffer, 100, 200); + return buffer.done(); + } +} + +class DelayedBytesLoader extends BytesLoader { + const DelayedBytesLoader(this.data); + + final Future data; + + @override + Future loadBytes(BuildContext? context) async { + return data; + } + + @override + int get hashCode => data.hashCode; + + @override + bool operator ==(Object other) { + return other is DelayedBytesLoader && other.data == data; + } +} + +class TestBytesLoader extends BytesLoader { + const TestBytesLoader(this.data, [this.source]); + + final ByteData data; + final String? source; + + @override + Future loadBytes(BuildContext? context) async { + return data; + } + + @override + int get hashCode => data.hashCode; + + @override + bool operator ==(Object other) { + return other is TestBytesLoader && other.data == data; + } + + @override + String toString() => 'TestBytesLoader: $source'; +} diff --git a/packages/vector_graphics/test/vg_with_image_blank.png b/packages/vector_graphics/test/vg_with_image_blank.png new file mode 100644 index 000000000000..6a97f2a7c43f Binary files /dev/null and b/packages/vector_graphics/test/vg_with_image_blank.png differ diff --git a/packages/vector_graphics/test/vg_with_image_blue.png b/packages/vector_graphics/test/vg_with_image_blue.png new file mode 100644 index 000000000000..455e97b9f65f Binary files /dev/null and b/packages/vector_graphics/test/vg_with_image_blue.png differ diff --git a/packages/vector_graphics_codec/.gitignore b/packages/vector_graphics_codec/.gitignore new file mode 100644 index 000000000000..3c8a157278c3 --- /dev/null +++ b/packages/vector_graphics_codec/.gitignore @@ -0,0 +1,6 @@ +# Files and directories created by pub. +.dart_tool/ +.packages + +# Conventional directory for build output. +build/ diff --git a/packages/vector_graphics_codec/AUTHORS b/packages/vector_graphics_codec/AUTHORS new file mode 100644 index 000000000000..557dff97933b --- /dev/null +++ b/packages/vector_graphics_codec/AUTHORS @@ -0,0 +1,6 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. diff --git a/packages/vector_graphics_codec/CHANGELOG.md b/packages/vector_graphics_codec/CHANGELOG.md new file mode 100644 index 000000000000..a4781180d587 --- /dev/null +++ b/packages/vector_graphics_codec/CHANGELOG.md @@ -0,0 +1,119 @@ +## 1.1.12 + +* Transfers the package source from https://github.com/dnfield/vector_graphics + to https://github.com/flutter/packages. + +## 1.1.11+1 + +* Relax package:http constraint. + +## 1.1.11 + +* Use package:http to drop dependency on dart:html. + +## 1.1.10+1 + +* Add missing save before clip. + +## 1.1.10 + +* Add missing clip before saveLayer. + +## 1.1.9+2 + +* Fix case sensitivity on scientific notation parsing. + +## 1.1.9+1 + +* Fix publication error that did not have latest source code. + +## 1.1.9 + +* Fix handling of invalid XML `@id` attributes. +* Fix handling of self-referential `` elements. +* Add `--out-dir` option to compiler. +* Tweak warning message for unhandled eleemnts. + +## 1.1.8 + +* Fix bugs in transform parsing. + +## 1.1.7 + +* Support for matching the ambient text direction. + +## 1.1.6 + +* Fix bug in text position computation when transforms are involved. + +## 1.1.5+1 + +* Remove/update some invalid assertions related to image formats. + +## 1.1.5 + +* Add support for encoding control points as IEEE 754-2008 half precision + floating point values. +* Increase minimum SDK to 2.17.0. +* Added an error builder property to provide a fallback widget on exceptions. + +## 1.1.4 + +* Support more image formats and malformed MIME types. +* Fix inheritence for `fill-rule`s. + +## 1.1.3 + +* Further improvements to whitespace handling for text. + +## 1.1.2 + +* Fix handling and inheritence of `none`. + +## 1.1.1 + +* Multiple text positioning bug fixes. +* Preserve stroke-opacity when specified. + +## 1.1.0 + +* Fix a number of inheritence related bugs: + * Inheritence of properties specified on the root element now work. + * Opacity inheritence is more correct now. + * Inheritence of `use` elements is more correctly handled. +* Make `currentColor` non-null on SVG theme, and fix how it is applied. +* Remove the opacity peephole optimizer, which was incorrectly applying + optimizations in a few cases. A future release may add this back. +* Add clipBehavior to the widget. +* Fix patterns when multiple patterns are specified and applied within the + graphic. + +## 1.0.1 + +* Fix handling of unspecified fill colors on use/group elements. + +## 1.0.0+1 + +* Fix issue in pattern decoding. +* Fix issue in matrix parsing for some combinations of matrices. + +## 1.0.0 + +* Initial stable release. + +## 0.0.3 + +* Pattern support. + +## 0.0.2 + +* Add support for encoding and decoding inline images. + +## 0.0.1 + +* Add [VectorGraphicsCodec], [VectorGraphicsCodecListener], and [VectorGraphicsBuffer] + types used to construct and decode a vector graphics binary asset. + +## 0.0.0 + +* Create repository. diff --git a/packages/vector_graphics_codec/LICENSE b/packages/vector_graphics_codec/LICENSE new file mode 100644 index 000000000000..c6823b81eb84 --- /dev/null +++ b/packages/vector_graphics_codec/LICENSE @@ -0,0 +1,25 @@ +Copyright 2013 The Flutter Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/vector_graphics_codec/README.md b/packages/vector_graphics_codec/README.md new file mode 100644 index 000000000000..64beff82f549 --- /dev/null +++ b/packages/vector_graphics_codec/README.md @@ -0,0 +1,19 @@ +# vector_graphics_codec + +An encoding library for `package:vector_graphics`. + +This package intentionally creates a tight coupling between +`package:vector_graphics_compiler` and `package:vector_graphics`. Its format has +no stability guarnatees from version to version. + +This codec is not meant to have any utility outside of its usage in +`vector_graphics` or the compiler. + +## Commemoration + +This package was originally authored by +[Dan Field](https://github.com/dnfield) and has been forked here +from [dnfield/vector_graphics](https://github.com/dnfield/vector_graphics). +Dan was a member of the Flutter team at Google from 2018 until his death +in 2024. Dan’s impact and contributions to Flutter were immeasurable, and we +honor his memory by continuing to publish and maintain this package. diff --git a/packages/vector_graphics_codec/lib/src/fp16.dart b/packages/vector_graphics_codec/lib/src/fp16.dart new file mode 100644 index 000000000000..86301c7e9d8d --- /dev/null +++ b/packages/vector_graphics_codec/lib/src/fp16.dart @@ -0,0 +1,126 @@ +// 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. + +// TODO(stuartmorgan): Fix the lack of documentation, and remove the +// public_member_api_docs ignore directive. See +// https://github.com/flutter/flutter/issues/157616 +// ignore_for_file: constant_identifier_names, public_member_api_docs + +/// Adapted from libcore/util/FP16.java from the Android SDK. +/// https://en.wikipedia.org/wiki/Half-precision_floating-point_format +library fp16; + +import 'dart:typed_data'; + +const int FP32_SIGN_SHIFT = 31; +const int FP32_EXPONENT_SHIFT = 23; +const int FP32_SHIFTED_EXPONENT_MASK = 0xff; +const int FP32_SIGNIFICAND_MASK = 0x7fffff; +const int FP32_EXPONENT_BIAS = 127; +const int FP32_QNAN_MASK = 0x400000; +const int FP32_DENORMAL_MAGIC = 126 << 23; +const int EXPONENT_BIAS = 15; +const int SIGN_SHIFT = 15; +const int EXPONENT_SHIFT = 10; +const int SIGN_MASK = 0x8000; +const int SHIFTED_EXPONENT_MASK = 0x1f; +const int SIGNIFICAND_MASK = 0x3ff; + +// ignore: non_constant_identifier_names +final ByteData FP32_DENORMAL_FLOAT = ByteData(4) + ..setUint32(0, FP32_DENORMAL_MAGIC); + +/// Convert the single precision floating point value stored in [byteData] into a half-precision floating point value. +/// +/// This value is stored in the same bytedata instance. +void toHalf(ByteData byteData) { + final int bits = byteData.getInt32(0); + final int s = bits >> FP32_SIGN_SHIFT; + int e = (bits >> FP32_EXPONENT_SHIFT) & FP32_SHIFTED_EXPONENT_MASK; + int m = bits & FP32_SIGNIFICAND_MASK; + int outE = 0; + int outM = 0; + + if (e == 0xff) { + // Infinite or NaN + outE = 0x1f; + outM = m != 0 ? 0x200 : 0; + } else { + e = e - FP32_EXPONENT_BIAS + EXPONENT_BIAS; + if (e >= 0x1f) { + // Overflow + outE = 0x1f; + } else if (e <= 0) { + // Underflow + if (e < -10) { + // The absolute fp32 value is less than MIN_VALUE, flush to +/-0 + } else { + // The fp32 value is a normalized float less than MIN_NORMAL, + // we convert to a denorm fp16 + m = m | 0x800000; + final int shift = 14 - e; + outM = m >> shift; + final int lowm = m & ((1 << shift) - 1); + final int hway = 1 << (shift - 1); + // if above halfway or exactly halfway and outM is odd + if (lowm + (outM & 1) > hway) { + // Round to nearest even + // Can overflow into exponent bit, which surprisingly is OK. + // This increment relies on the +outM in the return statement below + outM++; + } + } + } else { + outE = e; + outM = m >> 13; + // if above halfway or exactly halfway and outM is odd + if ((m & 0x1fff) + (outM & 0x1) > 0x1000) { + // Round to nearest even + // Can overflow into exponent bit, which surprisingly is OK. + // This increment relies on the +outM in the return statement below + outM++; + } + } + } + // The outM is added here as the +1 increments for outM above can + // cause an overflow in the exponent bit which is OK. + byteData.setUint16(0, (s << SIGN_SHIFT) | (outE << EXPONENT_SHIFT) + outM); +} + +/// Convert the single precision floating point value stored in [byteData] into a double +/// precision floating point value. +double toDouble(ByteData byteData) { + final int h = byteData.getUint16(0); + final int bits = h & 0xffff; + final int s = bits & SIGN_MASK; + final int e = (bits >> EXPONENT_SHIFT) & SHIFTED_EXPONENT_MASK; + final int m = bits & SIGNIFICAND_MASK; + int outE = 0; + int outM = 0; + if (e == 0) { + // Denormal or 0 + if (m != 0) { + // Convert denorm fp16 into normalized fp32 + byteData.setUint32(0, FP32_DENORMAL_MAGIC + m); + double o = byteData.getFloat32(0); + o -= FP32_DENORMAL_FLOAT.getFloat32(0); + return s == 0 ? o : -o; + } + } else { + outM = m << 13; + if (e == 0x1f) { + // Infinite or NaN + outE = 0xff; + if (outM != 0) { + // SNaNs are quieted + outM |= FP32_QNAN_MASK; + } + } else { + outE = e - EXPONENT_BIAS + FP32_EXPONENT_BIAS; + } + } + final int out = (s << 16) | (outE << FP32_EXPONENT_SHIFT) | outM; + byteData.setUint32(0, out); + return byteData.getFloat32(0); +} diff --git a/packages/vector_graphics_codec/lib/vector_graphics_codec.dart b/packages/vector_graphics_codec/lib/vector_graphics_codec.dart new file mode 100644 index 000000000000..5888860a4193 --- /dev/null +++ b/packages/vector_graphics_codec/lib/vector_graphics_codec.dart @@ -0,0 +1,1506 @@ +// 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:convert'; +import 'dart:typed_data'; + +import 'src/fp16.dart' as fp16; + +// TODO(stuartmorgan): Fix the lack of documentation, and remove this. See +// https://github.com/flutter/flutter/issues/157616 +// ignore_for_file: public_member_api_docs + +/// enumeration of the types of control points accepted by [VectorGraphicsCodec.writePath]. +abstract class ControlPointTypes { + const ControlPointTypes._(); + + static const int moveTo = 0; + static const int lineTo = 1; + static const int cubicTo = 2; + static const int close = 3; +} + +// See definitions in dart:ui's TextDecoration. + +/// The mask used to clear text decorations. +const int kNoTextDecorationMask = 0x0; + +/// The mask for an underline text decoration. +const int kUnderlineMask = 0x1; + +/// The mask constant for an overline text decoration. +const int kOverlineMask = 0x2; + +/// The mask constant for a line through or strike text decoration. +const int kLineThroughMask = 0x4; + +/// The signature for an error callback if an error occurs during image +/// decoding. +/// +/// See [VectorGraphicsCodecListener.onImage]. +typedef VectorGraphicsErrorListener = void Function( + Object error, + StackTrace? stackTrace, +); + +/// Enumeration of the types of image data accepted by [VectorGraphicsCodec.writeImage]. +/// +// Must match ImageFormat from vector_graphics_compiler. +abstract class ImageFormatTypes { + /// PNG format. + /// + /// A loss-less compression format for images. This format is well suited for + /// images with hard edges, such as screenshots or sprites, and images with + /// text. Transparency is supported. The PNG format supports images up to + /// 2,147,483,647 pixels in either dimension, though in practice available + /// memory provides a more immediate limitation on maximum image size. + /// + /// PNG images normally use the `.png` file extension and the `image/png` MIME + /// type. + /// + /// See also: + /// + /// * , the Wikipedia page on PNG. + /// * , the PNG standard. + static const int png = 0; + + /// A JPEG format image. + /// + /// This library does not support JPEG 2000. + static const int jpeg = 1; + + /// A WebP format image. + static const int webp = 2; + + /// A Graphics Interchange Format image. + static const int gif = 3; + + /// A Windows Bitmap format image. + static const int bmp = 4; + + static const List values = [png, jpeg, webp, gif, bmp]; +} + +class DecodeResponse { + // TODO(stuartmorgan): Fix this use of a private type in public API (likely + // the constructor should be private). + // ignore: library_private_types_in_public_api + const DecodeResponse(this.complete, this._buffer); + + final bool complete; + final _ReadBuffer? _buffer; +} + +/// The [VectorGraphicsCodec] provides support for both encoding and +/// decoding the vector_graphics binary format. +class VectorGraphicsCodec { + /// Create a new [VectorGraphicsCodec]. + /// + /// The codec is stateless and the const constructor should be preferred. + const VectorGraphicsCodec(); + + /// The maximum supported value for an id. + /// + /// The codec does not support encoding more than this many paths, paints, + /// or shaders in a single buffer. + /// + /// Vertices are written inline and not subject to this constraint. + static const int kMaxId = 65535; + + static const int _pathTag = 27; + static const int _fillPaintTag = 28; + static const int _strokePaintTag = 29; + static const int _drawPathTag = 30; + static const int _drawVerticesTag = 31; + static const int _saveLayerTag = 37; + static const int _restoreTag = 38; + static const int _linearGradientTag = 39; + static const int _radialGradientTag = 40; + static const int _sizeTag = 41; + static const int _clipPathTag = 42; + static const int _maskTag = 43; + static const int _drawTextTag = 44; + static const int _textConfigTag = 45; + static const int _imageConfigTag = 46; + static const int _drawImageTag = 47; + static const int _beginCommandsTag = 48; + static const int _patternTag = 49; + static const int _textPositionTag = 50; + static const int _updateTextPositionTag = 51; + static const int _pathTagHalfPrecision = 52; + + static const int _version = 1; + static const int _magicNumber = 0x00882d62; + + /// Decode the vector_graphics binary. + /// + /// Without a provided [VectorGraphicsCodecListener], this method will only + /// validate the basic structure of an object. decoders that wish to construct + /// a dart:ui Picture object should implement [VectorGraphicsCodecListener]. + /// + /// Throws a [StateError] If the message is invalid. + DecodeResponse decode(ByteData data, VectorGraphicsCodecListener? listener, + {DecodeResponse? response}) { + final _ReadBuffer buffer; + if (response == null) { + buffer = _ReadBuffer(data); + if (data.lengthInBytes < 5) { + throw StateError( + 'The provided data was not a vector_graphics binary asset.'); + } + final int magicNumber = buffer.getUint32(); + if (magicNumber != _magicNumber) { + throw StateError( + 'The provided data was not a vector_graphics binary asset.'); + } + final int version = buffer.getUint8(); + if (version != _version) { + throw StateError( + 'The provided data does not match the currently supported version.'); + } + } else { + buffer = response._buffer!; + } + + bool readImage = false; + while (buffer.hasRemaining) { + final int type = buffer.getUint8(); + switch (type) { + case _beginCommandsTag: + if (readImage) { + return DecodeResponse(false, buffer); + } + continue; + case _linearGradientTag: + _readLinearGradient(buffer, listener); + continue; + case _radialGradientTag: + _readRadialGradient(buffer, listener); + continue; + case _fillPaintTag: + _readFillPaint(buffer, listener); + continue; + case _strokePaintTag: + _readStrokePaint(buffer, listener); + continue; + case _pathTag: + _readPath(buffer, listener, half: false); + continue; + case _pathTagHalfPrecision: + _readPath(buffer, listener, half: true); + continue; + case _drawPathTag: + _readDrawPath(buffer, listener); + continue; + case _drawVerticesTag: + _readDrawVertices(buffer, listener); + continue; + case _restoreTag: + listener?.onRestoreLayer(); + continue; + case _saveLayerTag: + _readSaveLayer(buffer, listener); + continue; + case _sizeTag: + _readSize(buffer, listener); + continue; + case _clipPathTag: + _readClipPath(buffer, listener); + continue; + case _maskTag: + listener?.onMask(); + continue; + case _textConfigTag: + _readTextConfig(buffer, listener); + continue; + case _drawTextTag: + _readDrawText(buffer, listener); + continue; + case _imageConfigTag: + readImage = true; + _readImageConfig(buffer, listener); + continue; + case _drawImageTag: + _readDrawImage(buffer, listener); + continue; + case _patternTag: + _readPattern(buffer, listener); + continue; + case _textPositionTag: + _readTextPosition(buffer, listener); + continue; + case _updateTextPositionTag: + _readUpdateTextPosition(buffer, listener); + continue; + default: + throw StateError('Unknown type tag $type'); + } + } + return const DecodeResponse(true, null); + } + + /// Encode the dimensions of the vector graphic. + /// + /// This should be the first attribute encoded. + void writeSize( + VectorGraphicsBuffer buffer, + double width, + double height, + ) { + if (buffer._decodePhase.index != _CurrentSection.size.index) { + throw StateError('Size already written'); + } + buffer._decodePhase = _CurrentSection.images; + buffer._putUint8(_sizeTag); + buffer._putFloat32(width); + buffer._putFloat32(height); + } + + /// Encode a draw path command in the current buffer. + /// + /// Requires that [pathId] and [paintId] to already be encoded. + void writeDrawPath( + VectorGraphicsBuffer buffer, + int pathId, + int paintId, + int? patternId, + ) { + buffer._checkPhase(_CurrentSection.commands); + buffer._addCommandsTag(); + + buffer._putUint8(_drawPathTag); + buffer._putUint16(pathId); + buffer._putUint16(paintId); + buffer._putUint16(patternId ?? kMaxId); + } + + /// Encode a draw vertices command in the current buffer. + /// + /// The [indices] are the index buffer used and is optional. + void writeDrawVertices( + VectorGraphicsBuffer buffer, + Float32List vertices, + Uint16List? indices, + int? paintId, + ) { + buffer._checkPhase(_CurrentSection.commands); + buffer._addCommandsTag(); + + // Type Tag + // Vertex Length + // Vertex Buffer + // Index Length + // Index Buffer (If non zero) + // Paint Id. + buffer._putUint8(_drawVerticesTag); + buffer._putUint16(paintId ?? kMaxId); + buffer._putUint16(vertices.length); + buffer._putFloat32List(vertices); + if (indices != null) { + buffer._putUint16(indices.length); + buffer._putUint16List(indices); + } else { + buffer._putUint16(0); + } + } + + /// Encode a paint object used for a fill in the current buffer, returning + /// the identifier assigned to it. + /// + /// + /// [color] is the 32-bit ARBG color representation used by Flutter + /// internally. The [blendMode] fields should be the index of the + /// corresponding enumeration. + /// + /// This method is only used to write the paint used for fill commands. + /// To write a paint used for a stroke command, see [writeStroke]. + int writeFill( + VectorGraphicsBuffer buffer, + int color, + int blendMode, [ + int? shaderId, + ]) { + buffer._checkPhase(_CurrentSection.paints); + + final int paintId = buffer._nextPaintId++; + assert(paintId < kMaxId); + buffer._putUint8(_fillPaintTag); + buffer._putUint32(color); + buffer._putUint8(blendMode); + buffer._putUint16(paintId); + buffer._putUint16(shaderId ?? kMaxId); + return paintId; + } + + /// Write a linear gradient into the current buffer. + int writeLinearGradient( + VectorGraphicsBuffer buffer, { + required double fromX, + required double fromY, + required double toX, + required double toY, + required Int32List colors, + required Float32List? offsets, + required int tileMode, + }) { + buffer._checkPhase(_CurrentSection.shaders); + + final int shaderId = buffer._nextShaderId++; + assert(shaderId < kMaxId); + buffer._putUint8(_linearGradientTag); + buffer._putUint16(shaderId); + buffer._putFloat32(fromX); + buffer._putFloat32(fromY); + buffer._putFloat32(toX); + buffer._putFloat32(toY); + buffer._putUint16(colors.length); + buffer._putInt32List(colors); + if (offsets == null) { + buffer._putUint16(0); + } else { + buffer._putUint16(offsets.length); + buffer._putFloat32List(offsets); + } + buffer._putUint8(tileMode); + return shaderId; + } + + /// Write a radial gradient into the current buffer. + /// + /// [focalX] and [focalY] must be either both `null` or both `non-null`. + int writeRadialGradient( + VectorGraphicsBuffer buffer, { + required double centerX, + required double centerY, + required double radius, + required double? focalX, + required double? focalY, + required Int32List colors, + required Float32List? offsets, + required Float64List? transform, + required int tileMode, + }) { + assert((focalX == null && focalY == null) || + (focalX != null && focalY != null)); + assert(transform == null || transform.length == 16); + buffer._checkPhase(_CurrentSection.shaders); + + final int shaderId = buffer._nextShaderId++; + assert(shaderId < kMaxId); + buffer._putUint8(_radialGradientTag); + buffer._putUint16(shaderId); + buffer._putFloat32(centerX); + buffer._putFloat32(centerY); + buffer._putFloat32(radius); + + if (focalX != null) { + buffer._putUint8(1); + buffer._putFloat32(focalX); + buffer._putFloat32(focalY!); + } else { + buffer._putUint8(0); + } + buffer._putUint16(colors.length); + buffer._putInt32List(colors); + if (offsets != null) { + buffer._putUint16(offsets.length); + buffer._putFloat32List(offsets); + } else { + buffer._putUint16(0); + } + buffer._writeTransform(transform); + buffer._putUint8(tileMode); + return shaderId; + } + + /// Encode a paint object in the current buffer, returning the identifier + /// assigned to it. + /// + /// [color] is the 32-bit ARBG color representation used by Flutter + /// internally. The [strokeCap], [strokeJoin], [blendMode], [style] + /// fields should be the index of the corresponding enumeration. + /// + /// This method is only used to write the paint used for fill commands. + /// To write a paint used for a stroke command, see [writeStroke]. + int writeStroke( + VectorGraphicsBuffer buffer, + int color, + int strokeCap, + int strokeJoin, + int blendMode, + double strokeMiterLimit, + double strokeWidth, [ + int? shaderId, + ]) { + buffer._checkPhase(_CurrentSection.paints); + final int paintId = buffer._nextPaintId++; + assert(paintId < kMaxId); + buffer._putUint8(_strokePaintTag); + buffer._putUint32(color); + buffer._putUint8(strokeCap); + buffer._putUint8(strokeJoin); + buffer._putUint8(blendMode); + buffer._putFloat32(strokeMiterLimit); + buffer._putFloat32(strokeWidth); + buffer._putUint16(paintId); + buffer._putUint16(shaderId ?? kMaxId); + return paintId; + } + + void _readLinearGradient( + _ReadBuffer buffer, + VectorGraphicsCodecListener? listener, + ) { + final int id = buffer.getUint16(); + final double fromX = buffer.getFloat32(); + final double fromY = buffer.getFloat32(); + final double toX = buffer.getFloat32(); + final double toY = buffer.getFloat32(); + final int colorLength = buffer.getUint16(); + final Int32List colors = buffer.getInt32List(colorLength); + final int offsetLength = buffer.getUint16(); + final Float32List offsets = buffer.getFloat32List(offsetLength); + final int tileMode = buffer.getUint8(); + listener?.onLinearGradient( + fromX, + fromY, + toX, + toY, + colors, + offsets, + tileMode, + id, + ); + } + + void _readRadialGradient( + _ReadBuffer buffer, + VectorGraphicsCodecListener? listener, + ) { + final int id = buffer.getUint16(); + final double centerX = buffer.getFloat32(); + final double centerY = buffer.getFloat32(); + final double radius = buffer.getFloat32(); + final int hasFocal = buffer.getUint8(); + double? focalX; + double? focalY; + if (hasFocal == 1) { + focalX = buffer.getFloat32(); + focalY = buffer.getFloat32(); + } + final int colorsLength = buffer.getUint16(); + final Int32List colors = buffer.getInt32List(colorsLength); + final int offsetsLength = buffer.getUint16(); + final Float32List offsets = buffer.getFloat32List(offsetsLength); + final Float64List? transform = buffer.getTransform(); + final int tileMode = buffer.getUint8(); + listener?.onRadialGradient( + centerX, + centerY, + radius, + focalX, + focalY, + colors, + offsets, + transform, + tileMode, + id, + ); + } + + void _readFillPaint( + _ReadBuffer buffer, VectorGraphicsCodecListener? listener) { + final int color = buffer.getUint32(); + final int blendMode = buffer.getUint8(); + final int id = buffer.getUint16(); + final int shaderId = buffer.getUint16(); + + listener?.onPaintObject( + color: color, + strokeCap: null, + strokeJoin: null, + blendMode: blendMode, + strokeMiterLimit: null, + strokeWidth: null, + paintStyle: 0, // Fill + id: id, + shaderId: shaderId == kMaxId ? null : shaderId, + ); + } + + void _readStrokePaint( + _ReadBuffer buffer, VectorGraphicsCodecListener? listener) { + final int color = buffer.getUint32(); + final int strokeCap = buffer.getUint8(); + final int strokeJoin = buffer.getUint8(); + final int blendMode = buffer.getUint8(); + final double strokeMiterLimit = buffer.getFloat32(); + final double strokeWidth = buffer.getFloat32(); + final int id = buffer.getUint16(); + final int shaderId = buffer.getUint16(); + + listener?.onPaintObject( + color: color, + strokeCap: strokeCap, + strokeJoin: strokeJoin, + blendMode: blendMode, + strokeMiterLimit: strokeMiterLimit, + strokeWidth: strokeWidth, + paintStyle: 1, // Stroke + id: id, + shaderId: shaderId == kMaxId ? null : shaderId, + ); + } + + /// Saves a copy of the current transform and clip on the save stack, and then + /// creates a new group which subsequent calls will become a part of. When the + /// save stack is later popped, the group will be flattened into a layer and + /// have the given `paint`'s [Paint.blendMode] applied. + /// + /// See also: + /// * [Canvas.saveLayer] + void writeSaveLayer(VectorGraphicsBuffer buffer, int paint) { + buffer._checkPhase(_CurrentSection.commands); + buffer._addCommandsTag(); + + buffer._putUint8(_saveLayerTag); + buffer._putUint16(paint); + } + + /// Pops the current save stack, if there is anything to pop. + /// Otherwise, does nothing. + /// + /// See also: + /// * [Canvas.restore] + void writeRestoreLayer(VectorGraphicsBuffer buffer) { + buffer._checkPhase(_CurrentSection.commands); + buffer._addCommandsTag(); + buffer._putUint8(_restoreTag); + } + + /// Write the [text] contents given starting at [x], [y]. + int writeTextConfig({ + required VectorGraphicsBuffer buffer, + required String text, + required String? fontFamily, + required double xAnchorMultiplier, + required int fontWeight, + required double fontSize, + required int decoration, + required int decorationStyle, + required int decorationColor, + }) { + buffer._checkPhase(_CurrentSection.text); + + final int textId = buffer._nextTextId++; + assert(textId < kMaxId); + + buffer._putUint8(_textConfigTag); + buffer._putUint16(textId); + buffer._putFloat32(xAnchorMultiplier); + buffer._putFloat32(fontSize); + buffer._putUint8(fontWeight); + buffer._putUint8(decoration); + buffer._putUint8(decorationStyle); + buffer._putUint32(decorationColor); + + // font-family + if (fontFamily != null) { + // Newer versions of Dart will make this a Uint8List and not require the cast. + // ignore: unnecessary_cast + final Uint8List encoded = utf8.encode(fontFamily) as Uint8List; + buffer._putUint16(encoded.length); + buffer._putUint8List(encoded); + } else { + buffer._putUint16(0); + } + + // text-value + // Newer versions of Dart will make this a Uint8List and not require the cast. + // ignore: unnecessary_cast + final Uint8List encoded = utf8.encode(text) as Uint8List; + buffer._putUint16(encoded.length); + buffer._putUint8List(encoded); + + return textId; + } + + void writeDrawText( + VectorGraphicsBuffer buffer, + int textId, + int? fillId, + int? strokeId, + int? patternId, + ) { + assert(fillId != null || strokeId != null); + buffer._checkPhase(_CurrentSection.commands); + buffer._addCommandsTag(); + buffer._putUint8(_drawTextTag); + buffer._putUint16(textId); + buffer._putUint16(fillId ?? kMaxId); + buffer._putUint16(strokeId ?? kMaxId); + buffer._putUint16(patternId ?? kMaxId); + } + + void writeTextPosition( + VectorGraphicsBuffer buffer, + double? x, + double? y, + double? dx, + double? dy, + bool reset, + Float64List? transform, + ) { + buffer._checkPhase(_CurrentSection.textPositions); + final int id = buffer._nextTextPositionId++; + assert(id < kMaxId); + + buffer._putUint8(_textPositionTag); + buffer._putUint16(id); + + buffer._putFloat32(x ?? double.nan); + buffer._putFloat32(y ?? double.nan); + buffer._putFloat32(dx ?? double.nan); + buffer._putFloat32(dy ?? double.nan); + buffer._putUint8(reset ? 1 : 0); + buffer._writeTransform(transform); + } + + void writeUpdateTextPosition( + VectorGraphicsBuffer buffer, int textPositionId) { + buffer._checkPhase(_CurrentSection.commands); + buffer._addCommandsTag(); + buffer._putUint8(_updateTextPositionTag); + buffer._putUint16(textPositionId); + } + + void writeClipPath(VectorGraphicsBuffer buffer, int path) { + buffer._checkPhase(_CurrentSection.commands); + buffer._addCommandsTag(); + buffer._putUint8(_clipPathTag); + buffer._putUint16(path); + } + + void writeMask(VectorGraphicsBuffer buffer) { + buffer._checkPhase(_CurrentSection.commands); + buffer._addCommandsTag(); + buffer._putUint8(_maskTag); + } + + int writePattern( + VectorGraphicsBuffer buffer, + double x, + double y, + double width, + double height, + Float64List transform, + ) { + buffer._checkPhase(_CurrentSection.commands); + assert(buffer._nextPatternId < kMaxId); + final int id = buffer._nextPatternId; + buffer._nextPatternId += 1; + buffer._putUint8(_patternTag); + buffer._putUint16(id); + buffer._putFloat32(x); + buffer._putFloat32(y); + buffer._putFloat32(width); + buffer._putFloat32(height); + buffer._writeTransform(transform); + return id; + } + + /// Write a new path to the [buffer], returing the identifier + /// assigned to it. + /// + /// The [fillType] argument is either `1` for a fill or `0` for a stroke. + /// + /// [controlTypes] is a buffer of the types of control points in order. + /// [controlPoints] is a buffer of the control points in order. + /// + /// If [half] is true, control points will be written to the buffer using + /// half precision floating point values. This will reduce the binary + /// size at the cost of reduced precision. This option defaults to `false`. + int writePath( + VectorGraphicsBuffer buffer, + Uint8List controlTypes, + Float32List controlPoints, + int fillType, { + bool half = false, + }) { + buffer._checkPhase(_CurrentSection.paths); + assert(buffer._nextPathId < kMaxId); + + final int id = buffer._nextPathId; + buffer._nextPathId += 1; + + buffer._putUint8(half ? _pathTagHalfPrecision : _pathTag); + buffer._putUint8(fillType); + buffer._putUint16(id); + buffer._putUint32(controlTypes.length); + buffer._putUint8List(controlTypes); + buffer._putUint32(controlPoints.length); + if (half) { + buffer._putUint16List(_encodeToHalfPrecision(controlPoints)); + } else { + buffer._putFloat32List(controlPoints); + } + return id; + } + + Uint16List _encodeToHalfPrecision(Float32List list) { + final Uint16List output = Uint16List(list.length); + final ByteData buffer = ByteData(8); + for (int i = 0; i < list.length; i++) { + buffer.setFloat32(0, list[i]); + fp16.toHalf(buffer); + output[i] = buffer.getInt16(0); + } + return output; + } + + Float32List _decodeFromHalfPrecision(Uint16List list) { + final Float32List output = Float32List(list.length); + final ByteData buffer = ByteData(8); + for (int i = 0; i < list.length; i++) { + buffer.setUint16(0, list[i]); + output[i] = fp16.toDouble(buffer); + } + return output; + } + + /// Write an image to the [buffer], returning the identifier + /// assigned to it. + /// + /// The [data] argument should be the image data encoded according + /// to the [format] argument. Currently only PNG is supported. + int writeImage( + VectorGraphicsBuffer buffer, + int format, + Uint8List data, + ) { + buffer._checkPhase(_CurrentSection.images); + assert(buffer._nextImageId < kMaxId); + assert(ImageFormatTypes.values.contains(format)); + + final int id = buffer._nextImageId; + buffer._nextImageId += 1; + + buffer._putUint8(_imageConfigTag); + buffer._putUint16(id); + buffer._putUint8(format); + buffer._putUint32(data.length); + buffer._putUint8List(data); + return id; + } + + void writeDrawImage( + VectorGraphicsBuffer buffer, + int imageId, + double x, + double y, + double width, + double height, + Float64List? transform, + ) { + buffer._checkPhase(_CurrentSection.commands); + buffer._addCommandsTag(); + assert(width > 0 && height > 0); + + buffer._putUint8(_drawImageTag); + buffer._putUint16(imageId); + buffer._putFloat32(x); + buffer._putFloat32(y); + buffer._putFloat32(width); + buffer._putFloat32(height); + buffer._writeTransform(transform); + } + + void _readPath( + _ReadBuffer buffer, + VectorGraphicsCodecListener? listener, { + required bool half, + }) { + final int fillType = buffer.getUint8(); + final int id = buffer.getUint16(); + final int tagLength = buffer.getUint32(); + final Uint8List tags = buffer.getUint8List(tagLength); + final int pointLength = buffer.getUint32(); + final Float32List points; + if (half) { + points = _decodeFromHalfPrecision(buffer.getUint16List(pointLength)); + } else { + points = buffer.getFloat32List(pointLength); + } + listener?.onPathStart(id, fillType); + for (int i = 0, j = 0; i < tagLength; i += 1) { + switch (tags[i]) { + case ControlPointTypes.moveTo: + listener?.onPathMoveTo(points[j], points[j + 1]); + j += 2; + continue; + case ControlPointTypes.lineTo: + listener?.onPathLineTo(points[j], points[j + 1]); + j += 2; + continue; + case ControlPointTypes.cubicTo: + listener?.onPathCubicTo( + points[j], + points[j + 1], + points[j + 2], + points[j + 3], + points[j + 4], + points[j + 5], + ); + j += 6; + continue; + case ControlPointTypes.close: + listener?.onPathClose(); + continue; + default: + assert(false); + } + } + listener?.onPathFinished(); + } + + void _readDrawPath( + _ReadBuffer buffer, + VectorGraphicsCodecListener? listener, + ) { + final int pathId = buffer.getUint16(); + final int paintId = buffer.getUint16(); + int? patternId = buffer.getUint16(); + if (patternId == kMaxId) { + patternId = null; + } + listener?.onDrawPath(pathId, paintId, patternId); + } + + void _readDrawVertices( + _ReadBuffer buffer, + VectorGraphicsCodecListener? listener, + ) { + final int paintId = buffer.getUint16(); + final int verticesLength = buffer.getUint16(); + final Float32List vertices = buffer.getFloat32List(verticesLength); + final int indexLength = buffer.getUint16(); + Uint16List? indices; + if (indexLength != 0) { + indices = buffer.getUint16List(indexLength); + } + listener?.onDrawVertices( + vertices, indices, paintId != kMaxId ? paintId : null); + } + + void _readSaveLayer( + _ReadBuffer buffer, + VectorGraphicsCodecListener? listener, + ) { + final int paintId = buffer.getUint16(); + listener?.onSaveLayer(paintId); + } + + void _readClipPath( + _ReadBuffer buffer, + VectorGraphicsCodecListener? listener, + ) { + final int pathId = buffer.getUint16(); + listener?.onClipPath(pathId); + } + + void _readSize(_ReadBuffer buffer, VectorGraphicsCodecListener? listener) { + final double width = buffer.getFloat32(); + final double height = buffer.getFloat32(); + listener?.onSize(width, height); + } + + void _readTextPosition( + _ReadBuffer buffer, VectorGraphicsCodecListener? listener) { + final int id = buffer.getUint16(); + final double x = buffer.getFloat32(); + final double y = buffer.getFloat32(); + final double dx = buffer.getFloat32(); + final double dy = buffer.getFloat32(); + + final bool reset = buffer.getUint8() != 0; + final Float64List? transform = buffer.getTransform(); + + listener?.onTextPosition( + id, + x.isNaN ? null : x, + y.isNaN ? null : y, + dx.isNaN ? null : dx, + dy.isNaN ? null : dy, + reset, + transform, + ); + } + + void _readUpdateTextPosition( + _ReadBuffer buffer, + VectorGraphicsCodecListener? listener, + ) { + final int textPositionId = buffer.getUint16(); + listener?.onUpdateTextPosition(textPositionId); + } + + void _readTextConfig( + _ReadBuffer buffer, + VectorGraphicsCodecListener? listener, + ) { + final int id = buffer.getUint16(); + final double xAnchorMultiplier = buffer.getFloat32(); + final double fontSize = buffer.getFloat32(); + final int fontWeight = buffer.getUint8(); + final int decoration = buffer.getUint8(); + final int decorationStyle = buffer.getUint8(); + final int decorationColor = buffer.getUint32(); + String? fontFamily; + final int fontFamilyLength = buffer.getUint16(); + if (fontFamilyLength > 0) { + fontFamily = utf8.decode(buffer.getUint8List(fontFamilyLength)); + } + final int textLength = buffer.getUint16(); + final String text = utf8.decode(buffer.getUint8List(textLength)); + + listener?.onTextConfig( + text, + fontFamily, + xAnchorMultiplier, + fontWeight, + fontSize, + decoration, + decorationStyle, + decorationColor, + id, + ); + } + + void _readDrawText( + _ReadBuffer buffer, + VectorGraphicsCodecListener? listener, + ) { + final int textId = buffer.getUint16(); + int? fillId = buffer.getUint16(); + if (fillId == kMaxId) { + fillId = null; + } + int? strokeId = buffer.getUint16(); + if (strokeId == kMaxId) { + strokeId = null; + } + assert(fillId != null || strokeId != null); + int? patternId = buffer.getUint16(); + if (patternId == kMaxId) { + patternId = null; + } + listener?.onDrawText(textId, fillId, strokeId, patternId); + } + + void _readImageConfig( + _ReadBuffer buffer, VectorGraphicsCodecListener? listener) { + final int id = buffer.getUint16(); + final int format = buffer.getUint8(); + final int dataLength = buffer.getUint32(); + final Uint8List data = buffer.getUint8List(dataLength); + listener?.onImage(id, format, data); + } + + void _readDrawImage( + _ReadBuffer buffer, VectorGraphicsCodecListener? listener) { + final int id = buffer.getUint16(); + final double x = buffer.getFloat32(); + final double y = buffer.getFloat32(); + final double width = buffer.getFloat32(); + final double height = buffer.getFloat32(); + final Float64List? transformLength = buffer.getTransform(); + + listener?.onDrawImage(id, x, y, width, height, transformLength); + } + + void _readPattern(_ReadBuffer buffer, VectorGraphicsCodecListener? listener) { + final int patternId = buffer.getUint16(); + final double x = buffer.getFloat32(); + final double y = buffer.getFloat32(); + final double width = buffer.getFloat32(); + final double height = buffer.getFloat32(); + final Float64List? transform = buffer.getTransform(); + listener?.onPatternStart(patternId, x, y, width, height, transform!); + } +} + +/// Implement this listener class to support decoding of vector_graphics binary +/// assets. +abstract class VectorGraphicsCodecListener { + /// The size of the vector graphic has been decoded. + void onSize( + double width, + double height, + ); + + /// A paint object has been decoded. + /// + /// If the paint object is for a fill, then [strokeCap], [strokeJoin], + /// [strokeMiterLimit], and [strokeWidget] will be `null`. + void onPaintObject({ + required int color, + required int? strokeCap, + required int? strokeJoin, + required int blendMode, + required double? strokeMiterLimit, + required double? strokeWidth, + required int paintStyle, + required int id, + required int? shaderId, + }); + + /// A path object is being created, with the given [id] and [fillType]. + /// + /// All subsequent path commands will refer to this path, until + /// [onPathFinished] is invoked. + void onPathStart(int id, int fillType); + + /// A path object should move to (x, y). + void onPathMoveTo(double x, double y); + + /// A path object should line to (x, y). + void onPathLineTo(double x, double y); + + /// A path object will draw a cubic to (x1, y1), with control point 1 as + /// (x2, y2) and control point 2 as (x3, y3). + void onPathCubicTo( + double x1, double y1, double x2, double y2, double x3, double y3); + + /// The current path has been closed. + void onPathClose(); + + /// The current path is completed. + void onPathFinished(); + + /// Draw the given [pathId] with the given [paintId]. + /// + /// If the [paintId] is `null`, a default empty paint should be used instead. + void onDrawPath( + int pathId, + int? paintId, + int? patternId, + ); + + /// Draw the vertices with the given [vertices] and optionally index buffer + /// [indices]. + /// + /// If the [paintId] is `null`, a default empty paint should be used instead. + void onDrawVertices(Float32List vertices, Uint16List? indices, int? paintId); + + /// Save a new layer with the given [paintId]. + void onSaveLayer(int paintId); + + /// Apply the specified paths as clips to the current canvas. + void onClipPath(int pathId); + + /// Restore the save stack. + void onRestoreLayer(); + + /// Prepare to draw a new mask, until the next [onRestoreLayer] command. + void onMask(); + + /// A radial gradient shader has been parsed. + /// + /// [focalX] and [focalY] are either both `null` or `non-null`. + void onRadialGradient( + double centerX, + double centerY, + double radius, + double? focalX, + double? focalY, + Int32List colors, + Float32List? offsets, + Float64List? transform, + int tileMode, + int id, + ); + + /// A linear gradient shader has been parsed. + void onLinearGradient( + double fromX, + double fromY, + double toX, + double toY, + Int32List colors, + Float32List? offsets, + int tileMode, + int id, + ); + + /// A text configuration block has been decoded. + void onTextConfig( + String text, + String? fontFamily, + double xAnchorMultiplier, + int fontWeight, + double fontSize, + int decoration, + int decorationStyle, + int decorationColor, + int id, + ); + + /// A text block has been decoded. + void onDrawText( + int textId, + int? fillId, + int? strokeId, + int? patternId, + ); + + /// An encoded image has been decoded. + /// + /// The format is one of the values in [ImageFormatTypes]. + /// + /// If the [onError] callback is not null, it must be called if an error + /// occurs while attempting to decode the image [data]. + void onImage( + int imageId, + int format, + Uint8List data, { + VectorGraphicsErrorListener? onError, + }); + + /// An image should be drawn at the provided location. + void onDrawImage( + int imageId, + double x, + double y, + double width, + double height, + Float64List? transform, + ); + + /// A pattern has been decoded. + /// + /// All subsequent pattern commands will refer to this pattern, until + /// [onPatternFinished] is invoked. + void onPatternStart(int patternId, double x, double y, double width, + double height, Float64List transform); + + /// Record a new text position. + void onTextPosition( + int textPositionId, + double? x, + double? y, + double? dx, + double? dy, + bool reset, + Float64List? transform, + ); + + /// An instruction to update the current text position. + void onUpdateTextPosition(int textPositionId); +} + +enum _CurrentSection { + size, + images, + shaders, + paints, + paths, + textPositions, + text, + commands, +} + +/// Write-only buffer for incrementally building a [ByteData] instance. +/// +/// A [VectorGraphicsBuffer] instance can be used only once. Attempts to reuse will result +/// in [StateError]s being thrown. +/// +/// The byte order used is [Endian.little] throughout. +class VectorGraphicsBuffer { + /// Creates an interface for incrementally building a [ByteData] instance. + VectorGraphicsBuffer() + : _buffer = [], + _isDone = false, + _eightBytes = ByteData(8) { + _eightBytesAsList = _eightBytes.buffer.asUint8List(); + // Begin message with the magic number and current version. + _putUint32(VectorGraphicsCodec._magicNumber); + _putUint8(VectorGraphicsCodec._version); + } + + List _buffer; + bool _isDone; + final ByteData _eightBytes; + late Uint8List _eightBytesAsList; + static final Uint8List _zeroBuffer = Uint8List(8); + + /// The next paint id to be used. + int _nextPaintId = 0; + + /// The next path id to be used. + int _nextPathId = 0; + + /// The next shader id to be used. + int _nextShaderId = 0; + + /// The next text id to be used. + int _nextTextId = 0; + + /// The next text position id to be used. + int _nextTextPositionId = 0; + + /// The next image id to be used. + int _nextImageId = 0; + + /// The next pattern id to be used. + int _nextPatternId = 0; + + bool _addedCommandTag = false; + + /// The current decoding phase. + /// + /// Objects must be written in the correct order, the same as the + /// enum order. + _CurrentSection _decodePhase = _CurrentSection.size; + + /// Add a commands tag section if it is not already present. + void _addCommandsTag() { + if (_addedCommandTag) { + return; + } + _putUint8(VectorGraphicsCodec._beginCommandsTag); + _addedCommandTag = true; + } + + void _checkPhase(_CurrentSection expected) { + if (_decodePhase.index > expected.index) { + final String name = expected.name; + throw StateError('${name[0].toUpperCase()}${name.substring(1)} ' + 'must be encoded together (current phase is ${_decodePhase.name}).'); + } + _decodePhase = expected; + } + + void _writeTransform(Float64List? transform) { + if (transform != null) { + _putUint8(transform.length); + _putFloat64List(transform); + } else { + _putUint8(0); + } + } + + /// Write a Uint8 into the buffer. + void _putUint8(int byte) { + assert(!_isDone); + _buffer.add(byte); + } + + void _putUint16(int value) { + assert(!_isDone); + _eightBytes.setUint16(0, value, Endian.little); + _buffer.addAll(_eightBytesAsList.take(2)); + } + + /// Write a Uint32 into the buffer. + void _putUint32(int value) { + assert(!_isDone); + _eightBytes.setUint32(0, value, Endian.little); + _buffer.addAll(_eightBytesAsList.take(4)); + } + + /// Write an Int32List into the buffer. + void _putInt32List(Int32List list) { + assert(!_isDone); + _alignTo(4); + _buffer + .addAll(list.buffer.asUint8List(list.offsetInBytes, 4 * list.length)); + } + + /// Write an Float32 into the buffer. + void _putFloat32(double value) { + assert(!_isDone); + _eightBytes.setFloat32(0, value, Endian.little); + _buffer.addAll(_eightBytesAsList.take(4)); + } + + void _putUint8List(Uint8List list) { + assert(!_isDone); + _buffer.addAll(list.buffer.asUint8List(list.offsetInBytes, list.length)); + } + + void _putUint16List(Uint16List list) { + assert(!_isDone); + _alignTo(2); + _buffer + .addAll(list.buffer.asUint8List(list.offsetInBytes, 2 * list.length)); + } + + /// Write all the values from a [Float32List] into the buffer. + void _putFloat32List(Float32List list) { + assert(!_isDone); + _alignTo(4); + _buffer + .addAll(list.buffer.asUint8List(list.offsetInBytes, 4 * list.length)); + } + + void _putFloat64List(Float64List list) { + assert(!_isDone); + _alignTo(8); + _buffer + .addAll(list.buffer.asUint8List(list.offsetInBytes, 8 * list.length)); + } + + void _alignTo(int alignment) { + assert(!_isDone); + final int mod = _buffer.length % alignment; + if (mod != 0) { + _buffer.addAll(_zeroBuffer.take(alignment - mod)); + } + } + + /// Finalize and return the written [ByteData]. + ByteData done() { + if (_isDone) { + throw StateError( + 'done() must not be called more than once on the same VectorGraphicsBuffer.'); + } + final ByteData result = Uint8List.fromList(_buffer).buffer.asByteData(); + _buffer = []; + _isDone = true; + return result; + } +} + +/// Read-only buffer for reading sequentially from a [ByteData] instance. +/// +/// The byte order used is [Endian.little] throughout. +class _ReadBuffer { + /// Creates a [_ReadBuffer] for reading from the specified [data]. + _ReadBuffer(this.data); + + /// The underlying data being read. + final ByteData data; + + /// The position to read next. + int _position = 0; + + /// Whether the buffer has data remaining to read. + bool get hasRemaining => _position < data.lengthInBytes; + + /// Reads a Uint8 from the buffer. + int getUint8() { + return data.getUint8(_position++); + } + + /// Reads a Uint16 from the buffer. + int getUint16() { + final int value = data.getUint16(_position, Endian.little); + _position += 2; + return value; + } + + /// Reads a Uint32 from the buffer. + int getUint32() { + final int value = data.getUint32(_position, Endian.little); + _position += 4; + return value; + } + + /// Reads an Int32 from the buffer. + int getInt32() { + final int value = data.getInt32(_position, Endian.little); + _position += 4; + return value; + } + + /// Reads an Int64 from the buffer. + int getInt64() { + final int value = data.getInt64(_position, Endian.little); + _position += 8; + return value; + } + + /// Reads a Float32 from the buffer. + double getFloat32() { + final double value = data.getFloat32(_position, Endian.little); + _position += 4; + return value; + } + + /// Reads a Float64 from the buffer. + double getFloat64() { + _alignTo(8); + final double value = data.getFloat64(_position, Endian.little); + _position += 8; + return value; + } + + /// Reads the given number of Uint8s from the buffer. + Uint8List getUint8List(int length) { + final Uint8List list = + data.buffer.asUint8List(data.offsetInBytes + _position, length); + _position += length; + return list; + } + + Uint16List getUint16List(int length) { + _alignTo(2); + final Uint16List list = + data.buffer.asUint16List(data.offsetInBytes + _position, length); + _position += 2 * length; + return list; + } + + /// Reads the given number of Int32s from the buffer. + Int32List getInt32List(int length) { + _alignTo(4); + final Int32List list = + data.buffer.asInt32List(data.offsetInBytes + _position, length); + _position += 4 * length; + return list; + } + + /// Reads the given number of Int64s from the buffer. + Int64List getInt64List(int length) { + _alignTo(8); + final Int64List list = + data.buffer.asInt64List(data.offsetInBytes + _position, length); + _position += 8 * length; + return list; + } + + /// Reads the given number of Float32s from the buffer + Float32List getFloat32List(int length) { + _alignTo(4); + final Float32List list = + data.buffer.asFloat32List(data.offsetInBytes + _position, length); + _position += 4 * length; + return list; + } + + /// Reads the given number of Float64s from the buffer. + Float64List getFloat64List(int length) { + _alignTo(8); + final Float64List list = + data.buffer.asFloat64List(data.offsetInBytes + _position, length); + _position += 8 * length; + return list; + } + + void _alignTo(int alignment) { + final int mod = _position % alignment; + if (mod != 0) { + _position += alignment - mod; + } + } + + Float64List? getTransform() { + final int transformLength = getUint8(); + if (transformLength > 0) { + assert(transformLength == 16); + return getFloat64List(transformLength); + } + return null; + } +} diff --git a/packages/vector_graphics_codec/pubspec.yaml b/packages/vector_graphics_codec/pubspec.yaml new file mode 100644 index 000000000000..78af4cdae4a1 --- /dev/null +++ b/packages/vector_graphics_codec/pubspec.yaml @@ -0,0 +1,26 @@ +name: vector_graphics_codec +description: An encoding library for the binary format used in `package:vector_graphics` +repository: https://github.com/flutter/packages/tree/main/packages/vector_graphics_codec +issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+vector_graphics%22 +version: 1.1.12 + +environment: + sdk: ^3.4.0 + +dev_dependencies: + flutter_test: + sdk: flutter + meta: ^1.15.0 + test: ^1.25.0 + +platforms: + android: + ios: + linux: + macos: + web: + windows: + +topics: + - svg + - vector-graphics diff --git a/packages/vector_graphics_codec/test/fp16_test.dart b/packages/vector_graphics_codec/test/fp16_test.dart new file mode 100644 index 000000000000..3d9a3e06ebef --- /dev/null +++ b/packages/vector_graphics_codec/test/fp16_test.dart @@ -0,0 +1,70 @@ +// 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:typed_data'; + +import 'package:test/test.dart'; +import 'package:vector_graphics_codec/src/fp16.dart'; + +double convert(double value) { + final ByteData byteData = ByteData(8); + byteData.setFloat32(0, value); + toHalf(byteData); + return toDouble(byteData); +} + +void main() { + test('fp16 positive values', () { + final List> missed = >[]; + + /// Validate that all numbers between [min] and [max] can be converted within [tolerance]. + void checkRange( + {required double min, required double max, required double tolerance}) { + final ByteData byteData = ByteData(8); + for (double i = min; i < max; i += 1) { + byteData.setFloat32(0, i); + toHalf(byteData); + + final double result = toDouble(byteData); + if ((result - i).abs() > tolerance) { + missed.add([i, result]); + } + } + } + + // The first 2048 values can be represented within 1.0. + checkRange(min: 0, max: 2048, tolerance: 1.0); + + // 2048-4096 values can be represented within 2.0. + checkRange(min: 2048, max: 4096, tolerance: 2.0); + + // 4096 - 8192 can be represented within 4.0. + checkRange(min: 4096, max: 8192, tolerance: 4.0); + + // 8192 - 16384 can be represented within 8.0. + checkRange(min: 8192, max: 16384, tolerance: 8.0); + + // 16384 - 32768 can be represented within 16.0. + checkRange(min: 16384, max: 32768, tolerance: 16.0); + + // 32768 - 65519 can be represented within 32.0. + checkRange(min: 32768, max: 65519, tolerance: 16.0); + + expect(missed, isEmpty); + }); + + test('fp16 signed values', () { + expect(convert(-1.0), -1.0); + expect(convert(-100.0), -100.0); + expect(convert(-125.4375), -125.4375); + expect(convert(-12500.5), -12504.0); + }); + + test('fp16 sentinel values', () { + expect(convert(double.infinity), double.infinity); + expect(convert(65520), double.infinity); + expect(convert(double.nan), isNaN); + expect(convert(double.negativeInfinity), double.negativeInfinity); + }); +} diff --git a/packages/vector_graphics_codec/test/vector_graphics_codec_test.dart b/packages/vector_graphics_codec/test/vector_graphics_codec_test.dart new file mode 100644 index 000000000000..53b963806968 --- /dev/null +++ b/packages/vector_graphics_codec/test/vector_graphics_codec_test.dart @@ -0,0 +1,1691 @@ +// 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:typed_data'; + +import 'package:meta/meta.dart'; +import 'package:test/test.dart'; +import 'package:vector_graphics_codec/vector_graphics_codec.dart'; + +const VectorGraphicsCodec codec = VectorGraphicsCodec(); +final Float64List mat4 = Float64List.fromList( + [2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); + +void bufferContains(VectorGraphicsBuffer buffer, List expectedBytes) { + final Uint8List data = buffer.done().buffer.asUint8List(); + expect(data, equals(expectedBytes)); +} + +void main() { + test('Messages begin with a magic number and version', () { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + + bufferContains(buffer, [98, 45, 136, 0, 1]); + }); + + test('Messages without any contents cannot be decoded', () { + expect( + () => codec.decode(Uint8List(0).buffer.asByteData(), null), + throwsA(isA().having( + (StateError se) => se.message, + 'message', + contains( + 'The provided data was not a vector_graphics binary asset.')))); + }); + + test('Messages without a magic number cannot be decoded', () { + expect( + () => codec.decode(Uint8List(6).buffer.asByteData(), null), + throwsA(isA().having( + (StateError se) => se.message, + 'message', + contains( + 'The provided data was not a vector_graphics binary asset.')))); + }); + + test('Messages without an incompatible version cannot be decoded', () { + final Uint8List bytes = Uint8List(6); + bytes[0] = 98; + bytes[1] = 45; + bytes[2] = 136; + bytes[3] = 0; + bytes[4] = 6; // version 6. + + expect( + () => codec.decode(bytes.buffer.asByteData(), null), + throwsA(isA().having( + (StateError se) => se.message, + 'message', + contains( + 'he provided data does not match the currently supported version.')))); + }); + + test('Basic message encode and decode with filled path', () { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + final TestListener listener = TestListener(); + final int paintId = codec.writeFill(buffer, 23, 0); + final int pathId = codec.writePath( + buffer, + Uint8List.fromList([ + ControlPointTypes.moveTo, + ControlPointTypes.lineTo, + ControlPointTypes.close + ]), + Float32List.fromList([1, 2, 2, 3]), + 0, + ); + codec.writeDrawPath(buffer, pathId, paintId, null); + + codec.decode(buffer.done(), listener); + + expect(listener.commands, [ + OnPaintObject( + color: 23, + strokeCap: null, + strokeJoin: null, + blendMode: 0, + strokeMiterLimit: null, + strokeWidth: null, + paintStyle: 0, + id: paintId, + shaderId: null, + ), + OnPathStart(pathId, 0), + const OnPathMoveTo(1, 2), + const OnPathLineTo(2, 3), + const OnPathClose(), + const OnPathFinished(), + OnDrawPath(pathId, paintId, null), + ]); + }); + + test('Basic message encode and decode with shaded path', () { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + final TestListener listener = TestListener(); + final int shaderId = codec.writeLinearGradient( + buffer, + fromX: 0, + fromY: 0, + toX: 1, + toY: 1, + colors: Int32List.fromList([0, 1]), + offsets: Float32List.fromList([0, 1]), + tileMode: 1, + ); + final int fillId = codec.writeFill(buffer, 23, 0, shaderId); + final int strokeId = + codec.writeStroke(buffer, 44, 1, 2, 3, 4.0, 6.0, shaderId); + final int pathId = codec.writePath( + buffer, + Uint8List.fromList([ + ControlPointTypes.moveTo, + ControlPointTypes.lineTo, + ControlPointTypes.close + ]), + Float32List.fromList([1, 2, 2, 3]), + 0, + ); + codec.writeDrawPath(buffer, pathId, fillId, null); + codec.writeDrawPath(buffer, pathId, strokeId, null); + + codec.decode(buffer.done(), listener); + + expect(listener.commands, [ + OnLinearGradient( + fromX: 0, + fromY: 0, + toX: 1, + toY: 1, + colors: Int32List.fromList([0, 1]), + offsets: Float32List.fromList([0, 1]), + tileMode: 1, + id: shaderId, + ), + OnPaintObject( + color: 23, + strokeCap: null, + strokeJoin: null, + blendMode: 0, + strokeMiterLimit: null, + strokeWidth: null, + paintStyle: 0, + id: fillId, + shaderId: shaderId, + ), + OnPaintObject( + color: 44, + strokeCap: 1, + strokeJoin: 2, + blendMode: 3, + strokeMiterLimit: 4.0, + strokeWidth: 6.0, + paintStyle: 1, + id: strokeId, + shaderId: shaderId, + ), + OnPathStart(pathId, 0), + const OnPathMoveTo(1, 2), + const OnPathLineTo(2, 3), + const OnPathClose(), + const OnPathFinished(), + OnDrawPath(pathId, fillId, null), + OnDrawPath(pathId, strokeId, null), + ]); + }); + + test('Basic message encode and decode with stroked vertex', () { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + final TestListener listener = TestListener(); + final int paintId = codec.writeStroke(buffer, 44, 1, 2, 3, 4.0, 6.0); + codec.writeDrawVertices( + buffer, + Float32List.fromList([ + 0.0, + 2.0, + 3.0, + 4.0, + 2.0, + 4.0, + ]), + null, + paintId); + + codec.decode(buffer.done(), listener); + + expect(listener.commands, [ + OnPaintObject( + color: 44, + strokeCap: 1, + strokeJoin: 2, + blendMode: 3, + strokeMiterLimit: 4.0, + strokeWidth: 6.0, + paintStyle: 1, + id: paintId, + shaderId: null, + ), + OnDrawVertices(const [ + 0.0, + 2.0, + 3.0, + 4.0, + 2.0, + 4.0, + ], null, paintId), + ]); + }); + + test('Basic message encode and decode with stroked vertex and indexes', () { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + final TestListener listener = TestListener(); + final int paintId = codec.writeStroke(buffer, 44, 1, 2, 3, 4.0, 6.0); + codec.writeDrawVertices( + buffer, + Float32List.fromList([ + 0.0, + 2.0, + 3.0, + 4.0, + 2.0, + 4.0, + ]), + Uint16List.fromList([ + 0, + 1, + 2, + 3, + 4, + 5, + ]), + paintId, + ); + + codec.decode(buffer.done(), listener); + + expect(listener.commands, [ + OnPaintObject( + color: 44, + strokeCap: 1, + strokeJoin: 2, + blendMode: 3, + strokeMiterLimit: 4.0, + strokeWidth: 6.0, + paintStyle: 1, + id: paintId, + shaderId: null, + ), + OnDrawVertices(const [ + 0.0, + 2.0, + 3.0, + 4.0, + 2.0, + 4.0, + ], const [ + 0, + 1, + 2, + 3, + 4, + 5, + ], paintId), + ]); + }); + + test('Can encode opacity/save/restore layers', () { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + final TestListener listener = TestListener(); + final int paintId = codec.writeFill(buffer, 0xAA000000, 0); + + codec.writeSaveLayer(buffer, paintId); + codec.writeRestoreLayer(buffer); + codec.decode(buffer.done(), listener); + + expect(listener.commands, [ + OnPaintObject( + color: 0xAA000000, + strokeCap: null, + strokeJoin: null, + blendMode: 0, + strokeMiterLimit: null, + strokeWidth: null, + paintStyle: 0, + id: paintId, + shaderId: null, + ), + OnSaveLayer(paintId), + const OnRestoreLayer(), + ]); + }); + + test('Can encode a radial gradient', () { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + final TestListener listener = TestListener(); + + final int shaderId = codec.writeRadialGradient( + buffer, + centerX: 2.0, + centerY: 3.0, + radius: 5.0, + focalX: 1.0, + focalY: 1.0, + colors: Int32List.fromList([0xFFAABBAA]), + offsets: Float32List.fromList([2.2, 1.2]), + tileMode: 0, + transform: mat4, + ); + + codec.decode(buffer.done(), listener); + + expect(listener.commands, [ + OnRadialGradient( + centerX: 2.0, + centerY: 3.0, + radius: 5.0, + focalX: 1.0, + focalY: 1.0, + colors: Int32List.fromList([0xFFAABBAA]), + offsets: Float32List.fromList([2.2, 1.2]), + transform: mat4, + tileMode: 0, + id: shaderId, + ), + ]); + }); + + test('Can encode a radial gradient (no matrix)', () { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + final TestListener listener = TestListener(); + + final int shaderId = codec.writeRadialGradient( + buffer, + centerX: 2.0, + centerY: 3.0, + radius: 5.0, + focalX: 1.0, + focalY: 1.0, + colors: Int32List.fromList([0xFFAABBAA]), + offsets: Float32List.fromList([2.2, 1.2]), + tileMode: 0, + transform: null, + ); + + codec.decode(buffer.done(), listener); + + expect(listener.commands, [ + OnRadialGradient( + centerX: 2.0, + centerY: 3.0, + radius: 5.0, + focalX: 1.0, + focalY: 1.0, + colors: Int32List.fromList([0xFFAABBAA]), + offsets: Float32List.fromList([2.2, 1.2]), + transform: null, + tileMode: 0, + id: shaderId, + ), + ]); + }); + + test('Can encode a linear gradient', () { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + final TestListener listener = TestListener(); + + final int shaderId = codec.writeLinearGradient( + buffer, + fromX: 2.0, + fromY: 3.0, + toX: 1.0, + toY: 1.0, + colors: Int32List.fromList([0xFFAABBAA]), + offsets: Float32List.fromList([2.2, 1.2]), + tileMode: 0, + ); + + codec.decode(buffer.done(), listener); + + expect(listener.commands, [ + OnLinearGradient( + fromX: 2.0, + fromY: 3.0, + toX: 1.0, + toY: 1.0, + colors: Int32List.fromList([0xFFAABBAA]), + offsets: Float32List.fromList([2.2, 1.2]), + tileMode: 0, + id: shaderId, + ), + ]); + }); + + test('Can encode clips', () { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + final TestListener listener = TestListener(); + final int pathId = codec.writePath( + buffer, + Uint8List.fromList([ + ControlPointTypes.lineTo, + ControlPointTypes.lineTo, + ControlPointTypes.lineTo, + ControlPointTypes.close, + ]), + Float32List.fromList([0, 10, 20, 10, 20, 0]), + 0, + ); + + codec.writeClipPath(buffer, pathId); + codec.writeRestoreLayer(buffer); + codec.decode(buffer.done(), listener); + + expect(listener.commands, [ + OnPathStart(pathId, 0), + const OnPathLineTo(0, 10), + const OnPathLineTo(20, 10), + const OnPathLineTo(20, 0), + const OnPathClose(), + const OnPathFinished(), + OnClipPath(pathId), + const OnRestoreLayer(), + ]); + }); + + test('Can encode masks', () { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + final TestListener listener = TestListener(); + codec.writeMask(buffer); + codec.decode(buffer.done(), listener); + expect(listener.commands, [const OnMask()]); + }); + + test('Encodes a size', () { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + final TestListener listener = TestListener(); + + codec.writeSize(buffer, 20, 30); + codec.decode(buffer.done(), listener); + + expect(listener.commands, [const OnSize(20, 30)]); + }); + + test('Only supports a single size', () { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + + codec.writeSize(buffer, 20, 30); + expect(() => codec.writeSize(buffer, 1, 1), throwsStateError); + }); + + test('Encodes text', () { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + final TestListener listener = TestListener(); + + final int paintId = codec.writeFill(buffer, 0xFFAABBAA, 0); + final int textId = codec.writeTextConfig( + buffer: buffer, + text: 'Hello', + fontFamily: 'Roboto', + xAnchorMultiplier: 0, + fontWeight: 0, + fontSize: 16, + decoration: 0, + decorationStyle: 0, + decorationColor: 0, + ); + codec.writeDrawText(buffer, textId, paintId, null, null); + codec.decode(buffer.done(), listener); + + expect(listener.commands, [ + OnPaintObject( + color: 0xFFAABBAA, + strokeCap: null, + strokeJoin: null, + blendMode: 0, + strokeMiterLimit: null, + strokeWidth: null, + paintStyle: 0, + id: paintId, + shaderId: null, + ), + OnTextConfig('Hello', 0, 16, 'Roboto', 0, 0, 0, 0, textId), + OnDrawText(textId, paintId, null, null), + ]); + }); + + test('Encodes text with null font family', () { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + final TestListener listener = TestListener(); + + final int paintId = codec.writeFill(buffer, 0xFFAABBAA, 0); + final int textId = codec.writeTextConfig( + buffer: buffer, + text: 'Hello', + fontFamily: null, + xAnchorMultiplier: 0, + fontWeight: 0, + fontSize: 16, + decoration: 0, + decorationStyle: 0, + decorationColor: 0, + ); + codec.writeDrawText(buffer, textId, paintId, null, null); + codec.decode(buffer.done(), listener); + + expect(listener.commands, [ + OnPaintObject( + color: 0xFFAABBAA, + strokeCap: null, + strokeJoin: null, + blendMode: 0, + strokeMiterLimit: null, + strokeWidth: null, + paintStyle: 0, + id: paintId, + shaderId: null, + ), + OnTextConfig('Hello', 0, 16, null, 0, 0, 0, 0, textId), + OnDrawText(textId, paintId, null, null), + ]); + }); + + test('Encodes empty text', () { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + final TestListener listener = TestListener(); + + final int paintId = codec.writeFill(buffer, 0xFFAABBAA, 0); + final int textId = codec.writeTextConfig( + buffer: buffer, + text: '', + fontFamily: null, + xAnchorMultiplier: 0, + fontWeight: 0, + fontSize: 16, + decoration: 0, + decorationStyle: 0, + decorationColor: 0, + ); + codec.writeDrawText(buffer, textId, paintId, null, null); + codec.decode(buffer.done(), listener); + + expect(listener.commands, [ + OnPaintObject( + color: 0xFFAABBAA, + strokeCap: null, + strokeJoin: null, + blendMode: 0, + strokeMiterLimit: null, + strokeWidth: null, + paintStyle: 0, + id: paintId, + shaderId: null, + ), + OnTextConfig('', 0, 16, null, 0, 0, 0, 0, textId), + OnDrawText(textId, paintId, null, null), + ]); + }); + + test('Encodes text position', () { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + final TestListener listener = TestListener(); + + codec.writeTextPosition(buffer, 1, 2, 3, 4, true, mat4); + + codec.decode(buffer.done(), listener); + + expect(listener.commands, [ + OnTextPosition( + id: 0, + x: 1, + y: 2, + dx: 3, + dy: 4, + reset: true, + transform: mat4, + ), + ]); + }); + + test('Encodes image data without transform', () { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + final TestListener listener = TestListener(); + + final int id = + codec.writeImage(buffer, 0, Uint8List.fromList([0, 1, 3, 4, 5])); + codec.writeDrawImage(buffer, id, 1, 2, 100, 100, null); + final ByteData data = buffer.done(); + final DecodeResponse response = codec.decode(data, listener); + + expect(response.complete, false); + expect(listener.commands, [ + OnImage(id, 0, const [0, 1, 3, 4, 5]), + ]); + + final DecodeResponse nextResponse = + codec.decode(data, listener, response: response); + + expect(nextResponse.complete, true); + expect(listener.commands, [ + OnImage(id, 0, const [0, 1, 3, 4, 5]), + OnDrawImage(id, 1, 2, 100, 100, null), + ]); + }); + + test('Encodes image data with transform', () { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + final TestListener listener = TestListener(); + + final int id = + codec.writeImage(buffer, 0, Uint8List.fromList([0, 1, 3, 4, 5])); + codec.writeDrawImage(buffer, id, 1, 2, 100, 100, mat4); + final ByteData data = buffer.done(); + final DecodeResponse response = codec.decode(data, listener); + + expect(response.complete, false); + expect(listener.commands, [ + OnImage(id, 0, const [0, 1, 3, 4, 5]), + ]); + + final DecodeResponse nextResponse = + codec.decode(data, listener, response: response); + + expect(nextResponse.complete, true); + expect(listener.commands, [ + OnImage(id, 0, const [0, 1, 3, 4, 5]), + OnDrawImage(id, 1, 2, 100, 100, mat4), + ]); + }); + + test('Encodes image data with various formats', () { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + + for (final int format in ImageFormatTypes.values) { + expect( + codec.writeImage( + buffer, format, Uint8List.fromList([0, 1, 3, 4, 5])), + greaterThan(-1), + ); + } + }); + + test('Basic message encode and decode with shaded path and image', () { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + final TestListener listener = TestListener(); + + final int imageId = + codec.writeImage(buffer, 0, Uint8List.fromList([0, 1, 3, 4, 5])); + final int shaderId = codec.writeLinearGradient( + buffer, + fromX: 0, + fromY: 0, + toX: 1, + toY: 1, + colors: Int32List.fromList([0, 1]), + offsets: Float32List.fromList([0, 1]), + tileMode: 1, + ); + final int fillId = codec.writeFill(buffer, 23, 0, shaderId); + final int strokeId = + codec.writeStroke(buffer, 44, 1, 2, 3, 4.0, 6.0, shaderId); + final int pathId = codec.writePath( + buffer, + Uint8List.fromList([ + ControlPointTypes.moveTo, + ControlPointTypes.lineTo, + ControlPointTypes.close + ]), + Float32List.fromList([1, 2, 2, 3]), + 0, + ); + codec.writeDrawPath(buffer, pathId, fillId, null); + codec.writeDrawPath(buffer, pathId, strokeId, null); + codec.writeDrawImage(buffer, imageId, 1, 2, 100, 100, null); + + final ByteData data = buffer.done(); + + DecodeResponse response = codec.decode(data, listener); + + expect(response.complete, false); + expect(listener.commands, [ + OnImage( + imageId, + 0, + const [0, 1, 3, 4, 5], + ), + OnLinearGradient( + fromX: 0, + fromY: 0, + toX: 1, + toY: 1, + colors: Int32List.fromList([0, 1]), + offsets: Float32List.fromList([0, 1]), + tileMode: 1, + id: shaderId, + ), + OnPaintObject( + color: 23, + strokeCap: null, + strokeJoin: null, + blendMode: 0, + strokeMiterLimit: null, + strokeWidth: null, + paintStyle: 0, + id: fillId, + shaderId: shaderId, + ), + OnPaintObject( + color: 44, + strokeCap: 1, + strokeJoin: 2, + blendMode: 3, + strokeMiterLimit: 4.0, + strokeWidth: 6.0, + paintStyle: 1, + id: strokeId, + shaderId: shaderId, + ), + OnPathStart(pathId, 0), + const OnPathMoveTo(1, 2), + const OnPathLineTo(2, 3), + const OnPathClose(), + const OnPathFinished(), + ]); + + response = codec.decode(data, listener, response: response); + + expect(response.complete, true); + expect(listener.commands, [ + OnImage( + imageId, + 0, + const [0, 1, 3, 4, 5], + ), + OnLinearGradient( + fromX: 0, + fromY: 0, + toX: 1, + toY: 1, + colors: Int32List.fromList([0, 1]), + offsets: Float32List.fromList([0, 1]), + tileMode: 1, + id: shaderId, + ), + OnPaintObject( + color: 23, + strokeCap: null, + strokeJoin: null, + blendMode: 0, + strokeMiterLimit: null, + strokeWidth: null, + paintStyle: 0, + id: fillId, + shaderId: shaderId, + ), + OnPaintObject( + color: 44, + strokeCap: 1, + strokeJoin: 2, + blendMode: 3, + strokeMiterLimit: 4.0, + strokeWidth: 6.0, + paintStyle: 1, + id: strokeId, + shaderId: shaderId, + ), + OnPathStart(pathId, 0), + const OnPathMoveTo(1, 2), + const OnPathLineTo(2, 3), + const OnPathClose(), + const OnPathFinished(), + OnDrawPath(pathId, fillId, null), + OnDrawPath(pathId, strokeId, null), + OnDrawImage(imageId, 1, 2, 100, 100, null), + ]); + }); + + test('Basic message encode and decode with half precision path', () { + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + final TestListener listener = TestListener(); + + final int fillId = codec.writeFill(buffer, 23, 0); + final int strokeId = codec.writeStroke(buffer, 44, 1, 2, 3, 4.0, 6.0); + final int pathId = codec.writePath( + buffer, + Uint8List.fromList([ + ControlPointTypes.moveTo, + ControlPointTypes.lineTo, + ControlPointTypes.lineTo, + ControlPointTypes.close + ]), + Float32List.fromList([1.25, 24.5, 200.10, -32.4, -10000, 2500.2]), + 0, + half: true, + ); + codec.writeDrawPath(buffer, pathId, fillId, null); + codec.writeDrawPath(buffer, pathId, strokeId, null); + + final ByteData data = buffer.done(); + + final DecodeResponse response = codec.decode(data, listener); + + expect(response.complete, true); + expect(listener.commands, [ + OnPaintObject( + color: 23, + strokeCap: null, + strokeJoin: null, + blendMode: 0, + strokeMiterLimit: null, + strokeWidth: null, + paintStyle: 0, + id: fillId, + shaderId: null, + ), + OnPaintObject( + color: 44, + strokeCap: 1, + strokeJoin: 2, + blendMode: 3, + strokeMiterLimit: 4.0, + strokeWidth: 6.0, + paintStyle: 1, + id: strokeId, + shaderId: null, + ), + OnPathStart(pathId, 0), + const OnPathMoveTo(1.25, 24.5), + const OnPathLineTo(200.125, -32.40625), + const OnPathLineTo(-10000, 2500.0), + const OnPathClose(), + const OnPathFinished(), + const OnDrawPath(0, 0, null), + const OnDrawPath(0, 1, null), + ]); + }); +} + +class TestListener extends VectorGraphicsCodecListener { + final List commands = []; + + @override + void onDrawPath(int pathId, int? paintId, int? patternId) { + commands.add(OnDrawPath(pathId, paintId, patternId)); + } + + @override + void onDrawVertices(Float32List vertices, Uint16List? indices, int? paintId) { + commands.add(OnDrawVertices(vertices, indices, paintId)); + } + + @override + void onTextPosition(int textPositionId, double? x, double? y, double? dx, + double? dy, bool reset, Float64List? transform) { + commands.add(OnTextPosition( + id: textPositionId, + x: x, + y: y, + dx: dx, + dy: dy, + reset: reset, + transform: transform, + )); + } + + @override + void onUpdateTextPosition(int textPositionId) { + commands.add(OnUpdateTextPosition(textPositionId)); + } + + @override + void onPaintObject({ + required int color, + required int? strokeCap, + required int? strokeJoin, + required int blendMode, + required double? strokeMiterLimit, + required double? strokeWidth, + required int paintStyle, + required int id, + required int? shaderId, + }) { + commands.add( + OnPaintObject( + color: color, + strokeCap: strokeCap, + strokeJoin: strokeJoin, + blendMode: blendMode, + strokeMiterLimit: strokeMiterLimit, + strokeWidth: strokeWidth, + paintStyle: paintStyle, + id: id, + shaderId: shaderId, + ), + ); + } + + @override + void onPathClose() { + commands.add(const OnPathClose()); + } + + @override + void onPathCubicTo( + double x1, double y1, double x2, double y2, double x3, double y3) { + commands.add(OnPathCubicTo(x1, y1, x2, y2, x3, y3)); + } + + @override + void onPathFinished() { + commands.add(const OnPathFinished()); + } + + @override + void onPathLineTo(double x, double y) { + commands.add(OnPathLineTo(x, y)); + } + + @override + void onPathMoveTo(double x, double y) { + commands.add(OnPathMoveTo(x, y)); + } + + @override + void onPathStart(int id, int fillType) { + commands.add(OnPathStart(id, fillType)); + } + + @override + void onRestoreLayer() { + commands.add(const OnRestoreLayer()); + } + + @override + void onMask() { + commands.add(const OnMask()); + } + + @override + void onSaveLayer(int id) { + commands.add(OnSaveLayer(id)); + } + + @override + void onClipPath(int pathId) { + commands.add(OnClipPath(pathId)); + } + + @override + void onRadialGradient( + double centerX, + double centerY, + double radius, + double? focalX, + double? focalY, + Int32List colors, + Float32List? offsets, + Float64List? transform, + int tileMode, + int id, + ) { + commands.add( + OnRadialGradient( + centerX: centerX, + centerY: centerY, + radius: radius, + focalX: focalX, + focalY: focalY, + colors: colors, + offsets: offsets, + transform: transform, + tileMode: tileMode, + id: id, + ), + ); + } + + @override + void onLinearGradient( + double fromX, + double fromY, + double toX, + double toY, + Int32List colors, + Float32List? offsets, + int tileMode, + int id, + ) { + commands.add(OnLinearGradient( + fromX: fromX, + fromY: fromY, + toX: toX, + toY: toY, + colors: colors, + offsets: offsets, + tileMode: tileMode, + id: id, + )); + } + + @override + void onSize(double width, double height) { + commands.add(OnSize(width, height)); + } + + @override + void onTextConfig( + String text, + String? fontFamily, + double xAnchorMultiplier, + int fontWeight, + double fontSize, + int decoration, + int decorationStyle, + int decorationColor, + int id, + ) { + commands.add(OnTextConfig( + text, + xAnchorMultiplier, + fontSize, + fontFamily, + fontWeight, + decoration, + decorationStyle, + decorationColor, + id, + )); + } + + @override + void onDrawText(int textId, int? fillId, int? strokeId, int? patternId) { + commands.add(OnDrawText(textId, fillId, strokeId, patternId)); + } + + @override + void onImage( + int imageId, + int format, + Uint8List data, { + VectorGraphicsErrorListener? onError, + }) { + commands.add(OnImage( + imageId, + format, + data, + onError: onError, + )); + } + + @override + void onDrawImage( + int imageId, + double x, + double y, + double width, + double height, + Float64List? transform, + ) { + commands.add(OnDrawImage(imageId, x, y, width, height, transform)); + } + + @override + void onPatternStart(int patternId, double x, double y, double width, + double height, Float64List transform) { + commands.add(OnPatternStart(patternId, x, y, width, height, transform)); + } +} + +@immutable +@immutable +class OnTextPosition { + const OnTextPosition({ + required this.id, + this.x, + this.y, + this.dx, + this.dy, + required this.reset, + required this.transform, + }); + + final int id; + final double? x; + final double? y; + final double? dx; + final double? dy; + final bool reset; + final Float64List? transform; + + @override + int get hashCode => Object.hash( + id, + x, + y, + dx, + dy, + reset, + Object.hashAll(transform ?? []), + ); + + @override + bool operator ==(Object other) { + return other is OnTextPosition && + other.id == id && + other.x == x && + other.y == y && + other.dx == dx && + other.dy == dy && + _listEquals(other.transform, transform); + } +} + +@immutable +class OnMask { + const OnMask(); +} + +@immutable +@immutable +class OnLinearGradient { + const OnLinearGradient({ + required this.fromX, + required this.fromY, + required this.toX, + required this.toY, + required this.colors, + required this.offsets, + required this.tileMode, + required this.id, + }); + + final double fromX; + final double fromY; + final double toX; + final double toY; + final Int32List colors; + final Float32List? offsets; + final int tileMode; + final int id; + + @override + int get hashCode => Object.hash( + fromX, + fromY, + toX, + toY, + Object.hashAll(colors), + Object.hashAll(offsets ?? []), + tileMode, + id, + ); + + @override + bool operator ==(Object other) { + return other is OnLinearGradient && + other.fromX == fromX && + other.fromY == fromY && + other.toX == toX && + other.toY == toY && + _listEquals(other.colors, colors) && + _listEquals(other.offsets, offsets) && + other.tileMode == tileMode && + other.id == id; + } + + @override + String toString() { + return 'OnLinearGradient(' + 'fromX: $fromX, ' + 'toX: $toX, ' + 'fromY: $fromY, ' + 'toY: $toY, ' + 'colors: Int32List.fromList($colors), ' + 'offsets: Float32List.fromList($offsets), ' + 'tileMode: $tileMode, ' + 'id: $id)'; + } +} + +@immutable +class OnRadialGradient { + const OnRadialGradient({ + required this.centerX, + required this.centerY, + required this.radius, + required this.focalX, + required this.focalY, + required this.colors, + required this.offsets, + required this.transform, + required this.tileMode, + required this.id, + }); + + final double centerX; + final double centerY; + final double radius; + final double? focalX; + final double? focalY; + final Int32List colors; + final Float32List? offsets; + final Float64List? transform; + final int tileMode; + final int id; + + @override + int get hashCode => Object.hash( + centerX, + centerY, + radius, + focalX, + focalY, + Object.hashAll(colors), + Object.hashAll(offsets ?? []), + Object.hashAll(transform ?? []), + tileMode, + id, + ); + + @override + bool operator ==(Object other) { + return other is OnRadialGradient && + other.centerX == centerX && + other.centerY == centerY && + other.radius == radius && + other.focalX == focalX && + other.focalX == focalY && + _listEquals(other.colors, colors) && + _listEquals(other.offsets, offsets) && + _listEquals(other.transform, transform) && + other.tileMode == tileMode && + other.id == id; + } +} + +@immutable +class OnSaveLayer { + const OnSaveLayer(this.id); + + final int id; + + @override + int get hashCode => id.hashCode; + + @override + bool operator ==(Object other) => other is OnSaveLayer && other.id == id; +} + +@immutable +class OnClipPath { + const OnClipPath(this.id); + + final int id; + + @override + int get hashCode => id.hashCode; + + @override + bool operator ==(Object other) => other is OnClipPath && other.id == id; +} + +@immutable +class OnRestoreLayer { + const OnRestoreLayer(); +} + +@immutable +class OnDrawPath { + const OnDrawPath(this.pathId, this.paintId, this.patternId); + + final int pathId; + final int? paintId; + final int? patternId; + + @override + int get hashCode => Object.hash(pathId, paintId, patternId); + + @override + bool operator ==(Object other) => + other is OnDrawPath && + other.pathId == pathId && + other.paintId == paintId && + other.patternId == patternId; + + @override + String toString() => 'OnDrawPath($pathId, $paintId, $patternId)'; +} + +@immutable +class OnDrawVertices { + const OnDrawVertices(this.vertices, this.indices, this.paintId); + + final List vertices; + final List? indices; + final int? paintId; + + @override + int get hashCode => Object.hash(Object.hashAll(vertices), + Object.hashAll(indices ?? []), paintId); + + @override + bool operator ==(Object other) => + other is OnDrawVertices && + _listEquals(vertices, other.vertices) && + _listEquals(indices, other.indices) && + other.paintId == paintId; + + @override + String toString() => 'OnDrawVertices($vertices, $indices, $paintId)'; +} + +@immutable +class OnPaintObject { + const OnPaintObject({ + required this.color, + required this.strokeCap, + required this.strokeJoin, + required this.blendMode, + required this.strokeMiterLimit, + required this.strokeWidth, + required this.paintStyle, + required this.id, + required this.shaderId, + }); + + final int color; + final int? strokeCap; + final int? strokeJoin; + final int blendMode; + final double? strokeMiterLimit; + final double? strokeWidth; + final int paintStyle; + final int id; + final int? shaderId; + + @override + int get hashCode => Object.hash(color, strokeCap, strokeJoin, blendMode, + strokeMiterLimit, strokeWidth, paintStyle, id, shaderId); + + @override + bool operator ==(Object other) => + other is OnPaintObject && + other.color == color && + other.strokeCap == strokeCap && + other.strokeJoin == strokeJoin && + other.blendMode == blendMode && + other.strokeMiterLimit == strokeMiterLimit && + other.strokeWidth == strokeWidth && + other.paintStyle == paintStyle && + other.id == id && + other.shaderId == shaderId; + + @override + String toString() => + 'OnPaintObject(color: $color, strokeCap: $strokeCap, strokeJoin: $strokeJoin, ' + 'blendMode: $blendMode, strokeMiterLimit: $strokeMiterLimit, strokeWidth: $strokeWidth, ' + 'paintStyle: $paintStyle, id: $id, shaderId: $shaderId)'; +} + +@immutable +class OnPathClose { + const OnPathClose(); + + @override + int get hashCode => 44221; + + @override + bool operator ==(Object other) => other is OnPathClose; + + @override + String toString() => 'OnPathClose'; +} + +@immutable +class OnPathCubicTo { + const OnPathCubicTo(this.x1, this.y1, this.x2, this.y2, this.x3, this.y3); + + final double x1; + final double x2; + final double x3; + final double y1; + final double y2; + final double y3; + + @override + int get hashCode => Object.hash(x1, y1, x2, y2, x3, y3); + + @override + bool operator ==(Object other) => + other is OnPathCubicTo && + other.x1 == x1 && + other.y1 == y1 && + other.x2 == x2 && + other.y2 == y2 && + other.x3 == x3 && + other.y3 == y3; + + @override + String toString() => 'OnPathCubicTo($x1, $y1, $x2, $y2, $x3, $y3)'; +} + +@immutable +class OnPathFinished { + const OnPathFinished(); + + @override + int get hashCode => 1223; + + @override + bool operator ==(Object other) => other is OnPathFinished; + + @override + String toString() => 'OnPathFinished'; +} + +@immutable +class OnPathLineTo { + const OnPathLineTo(this.x, this.y); + + final double x; + final double y; + + @override + int get hashCode => Object.hash(x, y); + + @override + bool operator ==(Object other) => + other is OnPathLineTo && other.x == x && other.y == y; + + @override + String toString() => 'OnPathLineTo($x, $y)'; +} + +@immutable +class OnPathMoveTo { + const OnPathMoveTo(this.x, this.y); + + final double x; + final double y; + + @override + int get hashCode => Object.hash(x, y); + + @override + bool operator ==(Object other) => + other is OnPathMoveTo && other.x == x && other.y == y; + + @override + String toString() => 'OnPathMoveTo($x, $y)'; +} + +@immutable +class OnPathStart { + const OnPathStart(this.id, this.fillType); + + final int id; + final int fillType; + + @override + int get hashCode => Object.hash(id, fillType); + + @override + bool operator ==(Object other) => + other is OnPathStart && other.id == id && other.fillType == fillType; + + @override + String toString() => 'OnPathStart($id, $fillType)'; +} + +@immutable +class OnSize { + const OnSize(this.width, this.height); + + final double width; + final double height; + + @override + int get hashCode => Object.hash(width, height); + + @override + bool operator ==(Object other) => + other is OnSize && other.width == width && other.height == height; + + @override + String toString() => 'OnSize($width, $height)'; +} + +@immutable +class OnTextConfig { + const OnTextConfig( + this.text, + this.xAnchorMultiplier, + this.fontSize, + this.fontFamily, + this.fontWeight, + this.decoration, + this.decorationStyle, + this.decorationColor, + this.id, + ); + + final String text; + final double xAnchorMultiplier; + final double fontSize; + final String? fontFamily; + final int fontWeight; + final int decoration; + final int decorationStyle; + final int decorationColor; + final int id; + + @override + int get hashCode => Object.hash( + text, + xAnchorMultiplier, + fontSize, + fontFamily, + fontWeight, + decoration, + decorationStyle, + decorationColor, + id, + ); + + @override + bool operator ==(Object other) => + other is OnTextConfig && + other.text == text && + other.xAnchorMultiplier == xAnchorMultiplier && + other.fontSize == fontSize && + other.fontFamily == fontFamily && + other.fontWeight == fontWeight && + other.decoration == decoration && + other.decorationStyle == decorationStyle && + other.decorationColor == decorationColor && + other.id == id; + + @override + String toString() => + 'OnTextConfig($text, $fontSize, $fontFamily, $fontWeight, $decoration, $decorationStyle, $decorationColor, $id)'; +} + +@immutable +class OnDrawText { + const OnDrawText(this.textId, this.fillId, this.strokeId, this.patternId); + + final int textId; + final int? fillId; + final int? strokeId; + final int? patternId; + + @override + int get hashCode => Object.hash(textId, fillId, strokeId, patternId); + + @override + bool operator ==(Object other) => + other is OnDrawText && + other.textId == textId && + other.fillId == fillId && + other.strokeId == strokeId && + other.patternId == patternId; + + @override + String toString() => 'OnDrawText($textId, $fillId, $strokeId, $patternId)'; +} + +@immutable +class OnImage { + const OnImage(this.id, this.format, this.data, {this.onError}); + + final int id; + final int format; + final List data; + final VectorGraphicsErrorListener? onError; + + @override + int get hashCode => Object.hash(id, format, data, onError); + + @override + bool operator ==(Object other) => + other is OnImage && + other.id == id && + other.format == format && + other.onError == onError && + _listEquals(other.data, data); + + @override + String toString() => 'OnImage($id, $format, data:${data.length} bytes)'; +} + +@immutable +class OnDrawImage { + const OnDrawImage( + this.id, this.x, this.y, this.width, this.height, this.transform); + + final int id; + final double x; + final double y; + final double width; + final double height; + final Float64List? transform; + + @override + int get hashCode => Object.hash( + id, x, y, width, height, Object.hashAll(transform ?? const [])); + + @override + bool operator ==(Object other) { + return other is OnDrawImage && + other.id == id && + other.x == x && + other.y == y && + other.width == width && + other.height == height && + _listEquals(other.transform, transform); + } + + @override + String toString() => 'OnDrawImage($id, $x, $y, $width, $height, $transform)'; +} + +@immutable +class OnPatternStart { + const OnPatternStart( + this.patternId, this.x, this.y, this.width, this.height, this.transform); + + final int patternId; + final double x; + final double y; + final double width; + final double height; + final Float64List transform; + + @override + int get hashCode => + Object.hash(patternId, x, y, width, height, Object.hashAll(transform)); + + @override + bool operator ==(Object other) => + other is OnPatternStart && + other.patternId == patternId && + other.x == x && + other.y == y && + other.width == width && + other.height == height && + _listEquals(other.transform, transform); + + @override + String toString() => + 'OnPatternStart($patternId, $x, $y, $width, $height, $transform)'; +} + +bool _listEquals(List? left, List? right) { + if (left == null && right == null) { + return true; + } + if (left == null || right == null) { + return false; + } + if (left.length != right.length) { + return false; + } + for (int i = 0; i < left.length; i++) { + if (left[i] != right[i]) { + return false; + } + } + return true; +} + +@immutable +class OnUpdateTextPosition { + const OnUpdateTextPosition(this.id); + + final int id; + + @override + int get hashCode => id; + + @override + bool operator ==(Object other) => + other is OnUpdateTextPosition && other.id == id; +} diff --git a/packages/vector_graphics_compiler/.gitignore b/packages/vector_graphics_compiler/.gitignore new file mode 100644 index 000000000000..3c8a157278c3 --- /dev/null +++ b/packages/vector_graphics_compiler/.gitignore @@ -0,0 +1,6 @@ +# Files and directories created by pub. +.dart_tool/ +.packages + +# Conventional directory for build output. +build/ diff --git a/packages/vector_graphics_compiler/AUTHORS b/packages/vector_graphics_compiler/AUTHORS new file mode 100644 index 000000000000..557dff97933b --- /dev/null +++ b/packages/vector_graphics_compiler/AUTHORS @@ -0,0 +1,6 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. diff --git a/packages/vector_graphics_compiler/CHANGELOG.md b/packages/vector_graphics_compiler/CHANGELOG.md new file mode 100644 index 000000000000..adc696ab5efa --- /dev/null +++ b/packages/vector_graphics_compiler/CHANGELOG.md @@ -0,0 +1,128 @@ +## 1.1.14 + +* Makes the package WASM compatible. + +## 1.1.13 + +* Relaxes dependency constraint on vector_graphics_codec. + +## 1.1.12 + +* Transfers the package source from https://github.com/dnfield/vector_graphics + to https://github.com/flutter/packages. + +## 1.1.11+1 + +* Relax package:http constraint. + +## 1.1.11 + +* Use package:http to drop dependency on dart:html. + +## 1.1.10+1 + +* Add missing save before clip. + +## 1.1.10 + +* Add missing clip before saveLayer. + +## 1.1.9+2 + +* Fix case sensitivity on scientific notation parsing. + +## 1.1.9+1 + +* Fix publication error that did not have latest source code. + +## 1.1.9 + +* Fix handling of invalid XML `@id` attributes. +* Fix handling of self-referential `` elements. +* Add `--out-dir` option to compiler. +* Tweak warning message for unhandled eleemnts. + +## 1.1.8 + +* Fix bugs in transform parsing. + +## 1.1.7 + +* Support for matching the ambient text direction. + +## 1.1.6 + +* Fix bug in text position computation when transforms are involved. + +## 1.1.5+1 + +* Remove/update some invalid assertions related to image formats. + +## 1.1.5 + +* Support for encoding path control points as IEEE 754-2008 half precision + floating point values using the option `--use-half-precision-control-points`. +* Added an error builder property to provide a fallback widget on exceptions. + +## 1.1.4 + +* Support more image formats and malformed MIME types. +* Fix inheritence for `fill-rule`s. + +## 1.1.3 + +* Further improvements to whitespace handling for text. + +## 1.1.2 + +* Fix handling and inheritence of `none`. + +## 1.1.1 + +* Multiple text positioning bug fixes. +* Preserve stroke-opacity when specified. + +## 1.1.0 + +* Fix a number of inheritence related bugs: + * Inheritence of properties specified on the root element now work. + * Opacity inheritence is more correct now. + * Inheritence of `use` elements is more correctly handled. +* Make `currentColor` non-null on SVG theme, and fix how it is applied. +* Remove the opacity peephole optimizer, which was incorrectly applying + optimizations in a few cases. A future release may add this back. +* Add clipBehavior to the widget. +* Fix patterns when multiple patterns are specified and applied within the + graphic. + +## 1.0.1 + +* Fix handling of unspecified fill colors on use/group elements. + +## 1.0.0+1 + +* Fix issue in pattern decoding. +* Fix issue in matrix parsing for some combinations of matrices. + +## 1.0.0 + +* Initial stable release. +* Parsing is now synchronous, and is easier to work with in tests. +* Correctly handle images with `id`s and defined in `defs` blocks. +* Compile time color remapping support. + +## 0.0.3 + +* Better concurrency support +* Pattern support. +* Bug fixes around image handling. +* Bug fix for when optimizers are used on non-default fill types. +* Support for SVG theme related properties (currentColor, font-size, x-height). + +## 0.0.2 + +* Add optimizations for masks, clipping, and overdraw. + +## 0.0.1 + +* Create repository diff --git a/packages/vector_graphics_compiler/LICENSE b/packages/vector_graphics_compiler/LICENSE new file mode 100644 index 000000000000..c6823b81eb84 --- /dev/null +++ b/packages/vector_graphics_compiler/LICENSE @@ -0,0 +1,25 @@ +Copyright 2013 The Flutter Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/vector_graphics_compiler/README.md b/packages/vector_graphics_compiler/README.md new file mode 100644 index 000000000000..8997314b22ab --- /dev/null +++ b/packages/vector_graphics_compiler/README.md @@ -0,0 +1,39 @@ +# vector_graphics_compiler + +A compiler for `package:vector_graphics`. + +This package parses SVG files into a format that the vector_graphics runtime +can render. + +## Features + +Supported SVG features: + +- Groups, paths, and basic shapes are all supported. +- References, including out of order references. +- Linear and radial gradients, including radial gradients with focal points. +- Text +- Symbols +- Images +- Patterns + +Unsupported SVG features: + +- Filters +- Some text processing attributes + +Optimizations: + +- Opacity peepholing +- Transformation inlining (except for text and radial gradients) +- Group collapsing +- Mask and clip elimination + +## Commemoration + +This package was originally authored by +[Dan Field](https://github.com/dnfield) and has been forked here +from [dnfield/vector_graphics](https://github.com/dnfield/vector_graphics). +Dan was a member of the Flutter team at Google from 2018 until his death +in 2024. Dan’s impact and contributions to Flutter were immeasurable, and we +honor his memory by continuing to publish and maintain this package. diff --git a/packages/vector_graphics_compiler/bin/util/isolate_processor.dart b/packages/vector_graphics_compiler/bin/util/isolate_processor.dart new file mode 100644 index 000000000000..eae0eae999e3 --- /dev/null +++ b/packages/vector_graphics_compiler/bin/util/isolate_processor.dart @@ -0,0 +1,185 @@ +// 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: avoid_print + +import 'dart:async'; +import 'dart:io'; +import 'dart:isolate'; +import 'dart:typed_data'; + +import 'package:vector_graphics_compiler/src/debug_format.dart'; +import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; + +/// The isolate processor distributes SVG compilation across multiple isolates. +class IsolateProcessor { + /// Create a new [IsolateProcessor]. + IsolateProcessor(this._libpathops, this._libtessellator, int concurrency) + : _pool = Pool(concurrency); + + final String? _libpathops; + final String? _libtessellator; + final Pool _pool; + + int _total = 0; + int _current = 0; + + /// Process the provided input/output [Pair] objects into vector graphics. + /// + /// Returns whether all requests were successful. + Future process( + List pairs, { + SvgTheme theme = const SvgTheme(), + required bool maskingOptimizerEnabled, + required bool clippingOptimizerEnabled, + required bool overdrawOptimizerEnabled, + required bool tessellate, + required bool dumpDebug, + required bool useHalfPrecisionControlPoints, + }) async { + _total = pairs.length; + _current = 0; + bool failure = false; + await Future.wait(eagerError: true, >[ + for (final Pair pair in pairs) + _process( + pair, + theme: theme, + maskingOptimizerEnabled: maskingOptimizerEnabled, + clippingOptimizerEnabled: clippingOptimizerEnabled, + overdrawOptimizerEnabled: overdrawOptimizerEnabled, + tessellate: tessellate, + dumpDebug: dumpDebug, + useHalfPrecisionControlPoints: useHalfPrecisionControlPoints, + libpathops: _libpathops, + libtessellator: _libtessellator, + ).catchError((dynamic error, [StackTrace? stackTrace]) { + failure = true; + print('XXXXXXXXXXX ${pair.inputPath} XXXXXXXXXXXXX'); + print(error); + print(stackTrace); + }), + ]); + if (failure) { + print('Some targets failed.'); + } + return !failure; + } + + static void _loadPathOps(String? libpathops) { + if (libpathops != null && libpathops.isNotEmpty) { + initializeLibPathOps(libpathops); + } else if (!initializePathOpsFromFlutterCache()) { + throw StateError('Could not find libpathops binary'); + } + } + + static void _loadTessellator(String? libtessellator) { + if (libtessellator != null && libtessellator.isNotEmpty) { + initializeLibTesselator(libtessellator); + } else if (!initializeTessellatorFromFlutterCache()) { + throw StateError('Could not find libtessellator binary'); + } + } + + Future _process( + Pair pair, { + required bool maskingOptimizerEnabled, + required bool clippingOptimizerEnabled, + required bool overdrawOptimizerEnabled, + required bool tessellate, + required bool dumpDebug, + required bool useHalfPrecisionControlPoints, + required String? libpathops, + required String? libtessellator, + SvgTheme theme = const SvgTheme(), + }) async { + PoolHandle? resource; + try { + resource = await _pool.request(); + await Isolate.run(() { + if (maskingOptimizerEnabled || + clippingOptimizerEnabled || + overdrawOptimizerEnabled) { + _loadPathOps(libpathops); + } + if (tessellate) { + _loadTessellator(libtessellator); + } + + final Uint8List bytes = encodeSvg( + xml: File(pair.inputPath).readAsStringSync(), + debugName: pair.inputPath, + theme: theme, + enableMaskingOptimizer: maskingOptimizerEnabled, + enableClippingOptimizer: clippingOptimizerEnabled, + enableOverdrawOptimizer: overdrawOptimizerEnabled, + useHalfPrecisionControlPoints: useHalfPrecisionControlPoints, + ); + File(pair.outputPath).writeAsBytesSync(bytes); + if (dumpDebug) { + final Uint8List debugBytes = dumpToDebugFormat(bytes); + File('${pair.outputPath}.debug').writeAsBytesSync(debugBytes); + } + }); + _current++; + print('Progress: $_current/$_total'); + } finally { + resource?.release(); + } + } +} + +/// A combination of an input file and its output file. +class Pair { + /// Create a new [Pair]. + const Pair(this.inputPath, this.outputPath); + + /// The path the SVG should be read from. + final String inputPath; + + /// The path the vector graphic will be written to. + final String outputPath; +} + +class Pool { + Pool(this.concurrency); + + final int concurrency; + final List active = []; + final List> pending = >[]; + + Future request() async { + if (active.length < concurrency) { + final PoolHandle handle = PoolHandle(this); + active.add(handle); + return handle; + } + final Completer completer = Completer(); + pending.add(completer); + return completer.future; + } + + void _clearAndCheckPending(PoolHandle oldHandle) { + assert(active.contains(oldHandle)); + active.remove(oldHandle); + while (active.length < concurrency && pending.isNotEmpty) { + final Completer completer = pending.removeAt(0); + final PoolHandle handle = PoolHandle(this); + active.add(handle); + completer.complete(handle); + } + } +} + +class PoolHandle { + PoolHandle(this.pool); + + Pool? pool; + + void release() { + assert(pool != null); + pool?._clearAndCheckPending(this); + } +} diff --git a/packages/vector_graphics_compiler/bin/vector_graphics_compiler.dart b/packages/vector_graphics_compiler/bin/vector_graphics_compiler.dart new file mode 100644 index 000000000000..ff857b4eaf5b --- /dev/null +++ b/packages/vector_graphics_compiler/bin/vector_graphics_compiler.dart @@ -0,0 +1,208 @@ +// 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: avoid_print + +import 'dart:io'; + +import 'package:args/args.dart'; +import 'package:path/path.dart' as p; +import 'package:vector_graphics_compiler/src/svg/colors.dart'; +import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; + +import 'util/isolate_processor.dart'; + +final ArgParser argParser = ArgParser() + ..addOption( + 'current-color', + help: 'The value (in ARGB format or a named SVG color) of the ' + '"currentColor" attribute.', + valueHelp: '0xFF000000', + defaultsTo: '0xFF000000', + ) + ..addOption( + 'font-size', + help: 'The basis for font size based values (i.e. em, ex).', + valueHelp: '14', + defaultsTo: '14', + ) + ..addOption( + 'x-height', + help: 'The x-height or corpus size of the font. If unspecified, defaults ' + 'to half of font-size.', + valueHelp: '7', + ) + ..addOption( + 'libtessellator', + help: 'The path to a libtessellator dynamic library', + valueHelp: 'path/to/libtessellator.dylib', + hide: true, + ) + ..addOption( + 'libpathops', + help: 'The path to a libpathops dynamic library', + valueHelp: 'path/to/libpath_ops.dylib', + hide: true, + ) + ..addFlag( + 'tessellate', + help: 'Convert path fills into a tessellated shape. This will improve ' + 'raster times at the cost of slightly larger file sizes.', + ) + ..addFlag( + 'optimize-masks', + help: 'Allows for masking optimizer to be enabled or disabled', + defaultsTo: true, + ) + ..addFlag( + 'optimize-clips', + help: 'Allows for clipping optimizer to be enabled or disabled', + defaultsTo: true, + ) + ..addFlag( + 'optimize-overdraw', + help: 'Allows for overdraw optimizer to be enabled or disabled', + defaultsTo: true, + ) + ..addOption( + 'input-dir', + help: 'The path to a directory containing one or more SVGs. ' + 'Only includes files that end with .svg. ' + 'Cannot be combined with --input or --output.', + ) + ..addOption( + 'out-dir', + help: 'The output directory path ' + 'use it with --input-dir to specific the output dirictory', + ) + ..addOption( + 'input', + abbr: 'i', + help: 'The path to a file containing a single SVG', + ) + ..addOption('concurrency', + abbr: 'k', + help: 'The maximum number of SVG processing isolates to spawn at once. ' + 'If not provided, defaults to the number of cores.') + ..addFlag('dump-debug', + help: + 'Dump a human readable debugging format alongside the compiled asset', + hide: true) + ..addOption( + 'output', + abbr: 'o', + help: + 'The path to a file where the resulting vector_graphic will be written.\n' + 'If not provided, defaults to .vec', + ) + ..addFlag('use-half-precision-control-points', + help: + 'Convert path control points into IEEE 754-2008 half precision floating point values.\n' + 'This reduces file size at the cost of lost precision at larger values.'); + +void validateOptions(ArgResults results) { + if (results.wasParsed('input-dir') && + (results.wasParsed('input') || results.wasParsed('output'))) { + print( + '--input-dir cannot be combined with --input and/or --output options.'); + exit(1); + } + if (!results.wasParsed('input') && !results.wasParsed('input-dir')) { + print('One of --input or --input-dir must be specified.'); + exit(1); + } +} + +SvgTheme _parseTheme(ArgResults results) { + Color? currentColor = namedColors[results['current-color']]; + if (currentColor == null) { + final int? argbValue = int.tryParse(results['current-color'] as String); + currentColor = Color(argbValue ?? 0xFF000000); + } + return SvgTheme( + currentColor: currentColor, + fontSize: double.tryParse(results['font-size'] as String) ?? 14, + xHeight: results.wasParsed('x-height') + ? double.tryParse(results['x-height'] as String) + : null, + ); +} + +Future main(List args) async { + final ArgResults results; + try { + results = argParser.parse(args); + } on FormatException catch (err) { + print(err.message); + print(argParser.usage); + exit(1); + } + validateOptions(results); + + final List pairs = []; + if (results.wasParsed('input-dir')) { + final Directory directory = Directory(results['input-dir'] as String); + if (!directory.existsSync()) { + print('input-dir ${directory.path} does not exist.'); + exit(1); + } + for (final File file + in directory.listSync(recursive: true).whereType()) { + if (!file.path.endsWith('.svg')) { + continue; + } + + String outputPath = '${file.path}.vec'; + + // to specfic the output directory when parse multi svg + if (results.wasParsed('out-dir')) { + final Directory outDir = Directory(results['out-dir'] as String); + //to add the output dirctory if it exist + if (!outDir.existsSync()) { + outDir.createSync(); + } + outputPath = p.join(outDir.path, '${p.basename(file.path)}.vec'); + } + + pairs.add(Pair(file.path, outputPath)); + } + } else { + final String inputFilePath = results['input'] as String; + final String outputFilePath = + results['output'] as String? ?? '$inputFilePath.vec'; + pairs.add(Pair(inputFilePath, outputFilePath)); + } + + final bool maskingOptimizerEnabled = results['optimize-masks'] == true; + final bool clippingOptimizerEnabled = results['optimize-clips'] == true; + final bool overdrawOptimizerEnabled = results['optimize-overdraw'] == true; + final bool tessellate = results['tessellate'] == true; + final bool dumpDebug = results['dump-debug'] == true; + final bool useHalfPrecisionControlPoints = + results['use-half-precision-control-points'] == true; + final int concurrency; + if (results.wasParsed('concurrency')) { + concurrency = int.parse(results['concurrency'] as String); + } else { + concurrency = Platform.numberOfProcessors; + } + + final IsolateProcessor processor = IsolateProcessor( + results['libpathops'] as String?, + results['libtessellator'] as String?, + concurrency, + ); + if (!await processor.process( + pairs, + theme: _parseTheme(results), + maskingOptimizerEnabled: maskingOptimizerEnabled, + clippingOptimizerEnabled: clippingOptimizerEnabled, + overdrawOptimizerEnabled: overdrawOptimizerEnabled, + tessellate: tessellate, + dumpDebug: dumpDebug, + useHalfPrecisionControlPoints: useHalfPrecisionControlPoints, + )) { + exit(1); + } +} diff --git a/packages/vector_graphics_compiler/dart_test.yaml b/packages/vector_graphics_compiler/dart_test.yaml new file mode 100644 index 000000000000..91ec220b8e22 --- /dev/null +++ b/packages/vector_graphics_compiler/dart_test.yaml @@ -0,0 +1 @@ +test_on: vm diff --git a/packages/vector_graphics_compiler/lib/src/_initialize_path_ops_io.dart b/packages/vector_graphics_compiler/lib/src/_initialize_path_ops_io.dart new file mode 100644 index 000000000000..0e4dad963c74 --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/_initialize_path_ops_io.dart @@ -0,0 +1,47 @@ +// 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: avoid_print + +import 'dart:io'; +import 'svg/path_ops.dart'; + +/// Look up the location of the pathops from flutter's artifact cache. +bool initializePathOpsFromFlutterCache() { + final Directory cacheRoot; + if (Platform.resolvedExecutable.contains('flutter_tester')) { + cacheRoot = File(Platform.resolvedExecutable).parent.parent.parent.parent; + } else if (Platform.resolvedExecutable.contains('dart')) { + cacheRoot = File(Platform.resolvedExecutable).parent.parent.parent; + } else { + print('Unknown executable: ${Platform.resolvedExecutable}'); + return false; + } + + final String platform; + final String executable; + if (Platform.isWindows) { + platform = 'windows-x64'; + executable = 'path_ops.dll'; + } else if (Platform.isMacOS) { + platform = 'darwin-x64'; + executable = 'libpath_ops.dylib'; + } else if (Platform.isLinux) { + platform = 'linux-x64'; + executable = 'libpath_ops.so'; + } else { + print('path_ops not supported on ${Platform.localeName}'); + return false; + } + final String pathops = + '${cacheRoot.path}/artifacts/engine/$platform/$executable'; + if (!File(pathops).existsSync()) { + print('Could not locate libpathops at $pathops.'); + print('Ensure you are on a supported version of flutter and then run '); + print('"flutter precache".'); + return false; + } + initializeLibPathOps(pathops); + return true; +} diff --git a/packages/vector_graphics_compiler/lib/src/_initialize_path_ops_web.dart b/packages/vector_graphics_compiler/lib/src/_initialize_path_ops_web.dart new file mode 100644 index 000000000000..ba823d879b4f --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/_initialize_path_ops_web.dart @@ -0,0 +1,11 @@ +// 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: avoid_print + +/// Look up the location of the pathops from flutter's artifact cache. +bool initializePathOpsFromFlutterCache() { + print('PathOps not supported on web.'); + return false; +} diff --git a/packages/vector_graphics_compiler/lib/src/_initialize_tessellator_io.dart b/packages/vector_graphics_compiler/lib/src/_initialize_tessellator_io.dart new file mode 100644 index 000000000000..9c4fa596aa3f --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/_initialize_tessellator_io.dart @@ -0,0 +1,47 @@ +// 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: avoid_print + +import 'dart:io'; +import 'svg/tessellator.dart'; + +/// Look up the location of the tessellator from flutter's artifact cache. +bool initializeTessellatorFromFlutterCache() { + final Directory cacheRoot; + if (Platform.resolvedExecutable.contains('flutter_tester')) { + cacheRoot = File(Platform.resolvedExecutable).parent.parent.parent.parent; + } else if (Platform.resolvedExecutable.contains('dart')) { + cacheRoot = File(Platform.resolvedExecutable).parent.parent.parent; + } else { + print('Unknown executable: ${Platform.resolvedExecutable}'); + return false; + } + + final String platform; + final String executable; + if (Platform.isWindows) { + platform = 'windows-x64'; + executable = 'libtessellator.dll'; + } else if (Platform.isMacOS) { + platform = 'darwin-x64'; + executable = 'libtessellator.dylib'; + } else if (Platform.isLinux) { + platform = 'linux-x64'; + executable = 'libtessellator.so'; + } else { + print('Tesselation not supported on ${Platform.localeName}'); + return false; + } + final String tessellator = + '${cacheRoot.path}/artifacts/engine/$platform/$executable'; + if (!File(tessellator).existsSync()) { + print('Could not locate libtessellator at $tessellator.'); + print('Ensure you are on a supported version of flutter and then run '); + print('"flutter precache".'); + return false; + } + initializeLibTesselator(tessellator); + return true; +} diff --git a/packages/vector_graphics_compiler/lib/src/_initialize_tessellator_web.dart b/packages/vector_graphics_compiler/lib/src/_initialize_tessellator_web.dart new file mode 100644 index 000000000000..c232520d2ccc --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/_initialize_tessellator_web.dart @@ -0,0 +1,11 @@ +// 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: avoid_print + +/// Look up the location of the tessellator from flutter's artifact cache. +bool initializeTessellatorFromFlutterCache() { + print('Tesselation not supported on web'); + return false; +} diff --git a/packages/vector_graphics_compiler/lib/src/debug_format.dart b/packages/vector_graphics_compiler/lib/src/debug_format.dart new file mode 100644 index 000000000000..e065cfbdf7d7 --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/debug_format.dart @@ -0,0 +1,229 @@ +// 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:convert'; +import 'dart:typed_data'; + +import 'package:vector_graphics_codec/vector_graphics_codec.dart'; + +import 'paint.dart'; + +/// Write an unstable but human readable form of the vector graphics binary +/// package intended to be used for debugging and development. +Uint8List dumpToDebugFormat(Uint8List bytes) { + const VectorGraphicsCodec codec = VectorGraphicsCodec(); + final _DebugVectorGraphicsListener listener = _DebugVectorGraphicsListener(); + final DecodeResponse response = + codec.decode(bytes.buffer.asByteData(), listener); + if (!response.complete) { + codec.decode(bytes.buffer.asByteData(), listener, response: response); + } + // Newer versions of Dart will make this a Uint8List and not require the cast. + // ignore: unnecessary_cast + return utf8.encode(listener.buffer.toString()) as Uint8List; +} + +String _intToColor(int value) { + return 'Color(0x${(value & 0xFFFFFFFF).toRadixString(16).padLeft(8, '0')})'; +} + +class _DebugVectorGraphicsListener extends VectorGraphicsCodecListener { + final StringBuffer buffer = StringBuffer(); + + @override + void onClipPath(int pathId) { + buffer.writeln('DrawClip: id:$pathId'); + } + + @override + void onDrawImage(int imageId, double x, double y, double width, double height, + Float64List? transform) { + buffer.writeln( + 'DrawImage: id:$imageId (Rect.fromLTWH($x, $y, $width, $height), transform: $transform)'); + } + + @override + void onDrawPath(int pathId, int? paintId, int? patternId) { + final String patternContext = + patternId != null ? ', patternId:$patternId' : ''; + buffer.writeln('DrawPath: id:$pathId (paintId:$paintId$patternContext)'); + } + + @override + void onDrawText(int textId, int? fillId, int? strokeId, int? patternId) { + buffer.writeln( + 'DrawText: id:$textId (fill: $fillId, stroke: $strokeId, pattern: $patternId)'); + } + + @override + void onDrawVertices(Float32List vertices, Uint16List? indices, int? paintId) { + buffer.writeln('DrawVertices: $vertices ($indices, paintId: $paintId)'); + } + + @override + void onImage( + int imageId, + int format, + Uint8List data, { + VectorGraphicsErrorListener? onError, + }) { + buffer.writeln( + 'StoreImage: id:$imageId (format:$format, byteLength:${data.lengthInBytes}'); + } + + @override + void onLinearGradient(double fromX, double fromY, double toX, double toY, + Int32List colors, Float32List? offsets, int tileMode, int id) { + buffer.writeln( + 'StoreGradient: id:$id Linear(\n' + ' from: ($fromX, $fromY)\n' + ' to: ($toX, $toY)\n' + ' colors: [${colors.map(_intToColor).join(',')}]\n' + ' offsets: $offsets\n' + ' tileMode: ${TileMode.values[tileMode].name}', + ); + } + + @override + void onMask() { + buffer.writeln('BeginMask:'); + } + + @override + void onPaintObject({ + required int color, + required int? strokeCap, + required int? strokeJoin, + required int blendMode, + required double? strokeMiterLimit, + required double? strokeWidth, + required int paintStyle, + required int id, + required int? shaderId, + }) { + // Fill + if (paintStyle == 0) { + buffer.writeln( + 'StorePaint: id:$id Fill(${_intToColor(color)}, blendMode: ${BlendMode.values[blendMode].name}, shader: $shaderId)'); + } else { + buffer.writeln( + 'StorePaint: id:$id Stroke(${_intToColor(color)}, strokeCap: $strokeCap, $strokeJoin: $strokeJoin, ' + 'blendMode: ${BlendMode.values[blendMode].name}, strokeMiterLimit: $strokeMiterLimit, strokeWidth: $strokeWidth, shader: $shaderId)'); + } + } + + @override + void onPathClose() { + buffer.writeln(' close()'); + } + + @override + void onPathCubicTo( + double x1, double y1, double x2, double y2, double x3, double y3) { + buffer.writeln(' cubicTo(($x1, $y1), ($x2, $y2), ($x3, $y3)'); + } + + @override + void onPathFinished() { + buffer.writeln('EndPath:'); + } + + @override + void onPathLineTo(double x, double y) { + buffer.writeln(' lineTo($x, $y)'); + } + + @override + void onPathMoveTo(double x, double y) { + buffer.writeln(' moveTo($x, $y)'); + } + + @override + void onPathStart(int id, int fillType) { + buffer + .writeln('PathStart: id:$id ${fillType == 0 ? 'nonZero' : 'evenOdd'}'); + } + + @override + void onPatternStart(int patternId, double x, double y, double width, + double height, Float64List transform) { + buffer.writeln( + 'StorePattern: $patternId (Rect.fromLTWH($x, $y, $width, $height), transform: $transform)'); + } + + @override + void onRadialGradient( + double centerX, + double centerY, + double radius, + double? focalX, + double? focalY, + Int32List colors, + Float32List? offsets, + Float64List? transform, + int tileMode, + int id) { + final bool hasFocal = focalX != null; + buffer.writeln( + 'StoreGradient: id:$id Radial(\n' + 'center: ($centerX, $centerY)\n' + 'radius: $radius\n' + '${hasFocal ? 'focal: ($focalX, $focalY)\n' : ''}' + 'colors: [${colors.map(_intToColor).join(',')}]\n' + 'offsets: $offsets\n' + 'transform: $transform\n' + 'tileMode: ${TileMode.values[tileMode].name}', + ); + } + + @override + void onRestoreLayer() { + buffer.writeln('Restore:'); + } + + @override + void onSaveLayer(int paintId) { + buffer.writeln('SaveLayer: $paintId'); + } + + @override + void onSize(double width, double height) { + buffer.writeln('RecordSize: Size($width, $height)'); + } + + @override + void onTextConfig( + String text, + String? fontFamily, + double xAnchorMultiplier, + int fontWeight, + double fontSize, + int decoration, + int decorationStyle, + int decorationColor, + int id, + ) { + buffer.writeln( + 'RecordText: id:$id ($text, ($xAnchorMultiplier x-anchoring), weight: $fontWeight, size: $fontSize, decoration: $decoration, decorationStyle: $decorationStyle, decorationColor: 0x${decorationColor.toRadixString(16)}, family: $fontFamily)'); + } + + @override + void onTextPosition( + int id, + double? x, + double? y, + double? dx, + double? dy, + bool reset, + Float64List? transform, + ) { + buffer.writeln( + 'StoreTextPosition: id:$id (($x, $y) d($dx, $dy), reset: $reset, transform: $transform)'); + } + + @override + void onUpdateTextPosition(int id) { + buffer.writeln('UpdateTextPosition: id:$id'); + } +} diff --git a/packages/vector_graphics_compiler/lib/src/draw_command_builder.dart b/packages/vector_graphics_compiler/lib/src/draw_command_builder.dart new file mode 100644 index 000000000000..3d012129d1b1 --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/draw_command_builder.dart @@ -0,0 +1,164 @@ +// 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 'geometry/image.dart'; +import 'geometry/matrix.dart'; +import 'geometry/path.dart'; +import 'geometry/pattern.dart'; +import 'geometry/vertices.dart'; +import 'paint.dart'; +import 'svg/resolver.dart'; +import 'vector_instructions.dart'; + +/// An interface for building up a stack of vector commands. +class DrawCommandBuilder { + final Map _paints = {}; + final Map _paths = {}; + final Map _text = {}; + final Map _images = {}; + final Map _drawImages = {}; + final Map _vertices = {}; + final List _commands = []; + final Map _patterns = {}; + final Map _patternData = {}; + final Map _textPositions = {}; + + int _getOrGenerateId(T object, Map map) => + map.putIfAbsent(object, () => map.length); + + /// Add a vertices to the command stack. + void addVertices(IndexedVertices vertices, Paint paint) { + final int paintId = _getOrGenerateId(paint, _paints); + final int verticesId = _getOrGenerateId(vertices, _vertices); + _commands.add(DrawCommand( + DrawCommandType.vertices, + paintId: paintId, + objectId: verticesId, + )); + } + + /// Add a save layer to the command stack. + void addSaveLayer(Paint paint) { + final int paintId = _getOrGenerateId(paint, _paints); + _commands.add(DrawCommand( + DrawCommandType.saveLayer, + paintId: paintId, + )); + } + + /// Add a restore to the command stack. + void restore() { + _commands.add(const DrawCommand(DrawCommandType.restore)); + } + + /// Adds a clip to the command stack. + void addClip(Path path) { + final int pathId = _getOrGenerateId(path, _paths); + _commands.add(DrawCommand(DrawCommandType.clip, objectId: pathId)); + } + + /// Adds a mask to the command stack. + void addMask() { + _commands.add(const DrawCommand(DrawCommandType.mask)); + } + + /// Adds a pattern to the command stack. + void addPattern( + Object id, { + required double x, + required double y, + required double width, + required double height, + required AffineMatrix transform, + }) { + final int patternId = _getOrGenerateId(id, _patterns); + final int patternDataId = _getOrGenerateId( + PatternData(x, y, width, height, transform), + _patternData, + ); + _commands.add(DrawCommand( + DrawCommandType.pattern, + objectId: patternId, + patternDataId: patternDataId, + )); + } + + /// Updates the current text position to [position]. + void updateTextPosition(TextPosition position) { + final int positionId = _getOrGenerateId(position, _textPositions); + _commands.add(DrawCommand( + DrawCommandType.textPosition, + objectId: positionId, + )); + } + + /// Add a path to the current draw command stack + void addPath(Path path, Paint paint, String? debugString, Object? patternId) { + if (path.isEmpty) { + return; + } + final int pathId = _getOrGenerateId(path, _paths); + final int paintId = _getOrGenerateId(paint, _paints); + + _commands.add(DrawCommand(DrawCommandType.path, + objectId: pathId, + paintId: paintId, + debugString: debugString, + patternId: patternId != null ? _patterns[patternId] : null)); + } + + /// Adds a text to the current draw command stack. + void addText( + TextConfig textConfig, + Paint paint, + String? debugString, + Object? patternId, + ) { + final int paintId = _getOrGenerateId(paint, _paints); + final int styleId = _getOrGenerateId(textConfig, _text); + _commands.add(DrawCommand( + DrawCommandType.text, + objectId: styleId, + paintId: paintId, + debugString: debugString, + patternId: patternId != null ? _patterns[patternId] : null, + patternDataId: patternId != null ? _patternData[patternId] : null, + )); + } + + /// Add an image to the current draw command stack. + void addImage(ResolvedImageNode node, String? debugString) { + final ImageData imageData = ImageData(node.data, node.format.index); + final int imageId = _getOrGenerateId(imageData, _images); + final DrawImageData drawImageData = DrawImageData( + imageId, + node.rect, + node.transform, + ); + + final int drawImageId = _getOrGenerateId(drawImageData, _drawImages); + _commands.add(DrawCommand( + DrawCommandType.image, + objectId: drawImageId, + debugString: debugString, + )); + } + + /// Create a new [VectorInstructions] with the given width and height. + VectorInstructions toInstructions(double width, double height) { + return VectorInstructions( + width: width, + height: height, + paints: _paints.keys.toList(), + paths: _paths.keys.toList(), + text: _text.keys.toList(), + vertices: _vertices.keys.toList(), + images: _images.keys.toList(), + drawImages: _drawImages.keys.toList(), + commands: _commands, + patternData: _patternData.keys.toList(), + textPositions: _textPositions.keys.toList(), + ); + } +} diff --git a/packages/vector_graphics_compiler/lib/src/geometry/basic_types.dart b/packages/vector_graphics_compiler/lib/src/geometry/basic_types.dart new file mode 100644 index 000000000000..25820084fd91 --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/geometry/basic_types.dart @@ -0,0 +1,165 @@ +// 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:math' as math; +import 'package:meta/meta.dart'; + +import '../util.dart'; + +/// An immutable position in two-dimensional space. +/// +/// This class is roughly compatible with dart:ui's Offset. +@immutable +class Point { + /// Creates a point object with x,y coordinates. + const Point(this.x, this.y); + + /// The point at the origin of coordinate space. + static const Point zero = Point(0, 0); + + /// Linearly interpolate between two points. + /// + /// The [t] argument represents a position on the timeline, with 0.0 meaning + /// interpolation has not started and 1.0 meaning interpolation has finished. + /// + /// At the start the returned value equals [a], and at the end it equals [b]. As + /// the number advances from 0 to 1 it returns a value closer to a or b + /// respectively. + static Point lerp(Point a, Point b, double t) { + return Point( + lerpDouble(a.x, b.x, t), + lerpDouble(a.y, b.y, t), + ); + } + + /// The distance between points [a] and [b]. + static double distance(Point a, Point b) { + final double x = a.x - b.x; + final double y = a.y - b.y; + return math.sqrt((x * x) + (y * y)); + } + + /// The offset along the x-axis of this point. + final double x; + + /// The offset along the y-axis of this point. + final double y; + + @override + int get hashCode => Object.hash(x, y); + + @override + bool operator ==(Object other) { + return other is Point && other.x == x && other.y == y; + } + + /// Returns a point whose coordinates are the coordinates of the + /// left-hand-side operand (a Point) divided by the scalar right-hand-side + /// operand (a double). + Point operator /(double divisor) { + return Point(x / divisor, y / divisor); + } + + /// Returns a point whose coordinates are the coordinates of the + /// left-hand-side operand (a Point) multiplied by the scalar right-hand-side + /// operand (a double). + Point operator *(double multiplicand) { + return Point(x * multiplicand, y * multiplicand); + } + + /// Returns a point whose coordinates are the coordinates of the + /// left-hand-side operand (a Point) added to the right-hand-side + /// coordinates (a Point). + Point operator +(Point other) { + return Point(x + other.x, y + other.y); + } + + @override + String toString() => 'Point($x, $y)'; +} + +/// An immutable, 2D, axis-aligned, floating-point rectangle whose coordinates +/// are relative to a given origin. +@immutable +class Rect { + /// Creates a rectangle from the specified left, top, right, and bottom + /// positions. + const Rect.fromLTRB(this.left, this.top, this.right, this.bottom); + + /// Creates a rectangle from the specified left and top positions with width + /// and height dimensions. + const Rect.fromLTWH(double left, double top, double width, double height) + : this.fromLTRB(left, top, left + width, top + height); + + /// Creates a rectangle representing a circle with centerpoint `x,`y` and + /// radius `r`. + const Rect.fromCircle(double x, double y, double r) + : this.fromLTRB(x - r, y - r, x + r, y + r); + + /// A rectangle covering the entire coordinate space, equal to dart:ui's + /// definition. + static const Rect largest = Rect.fromLTRB(-1e9, -1e9, 1e9, 1e9); + + /// A rectangle with the top, left, right, and bottom edges all at zero. + static const Rect zero = Rect.fromLTRB(0, 0, 0, 0); + + /// The x-axis offset of left edge. + final double left; + + /// The y-axis offset of the top edge. + final double top; + + /// The x-axis offset of the right edge. + final double right; + + /// The y-axis offset of the bottom edge. + final double bottom; + + /// The width of the rectangle. + double get width => right - left; + + /// The height of the rectangle. + double get height => bottom - top; + + /// Creates the smallest rectangle that covers the edges of this and `other`. + Rect expanded(Rect other) { + return Rect.fromLTRB( + math.min(left, other.left), + math.min(top, other.top), + math.max(right, other.right), + math.max(bottom, other.bottom), + ); + } + + /// Whether or not the rect has any contents. + bool get isEmpty => width == 0 || height == 0; + + /// Whether or not [other] intersect this rectangle. + /// + /// This only works for sorted rectangles. + bool intersects(Rect other) { + assert(other.left <= other.right && other.top <= other.bottom); + assert(left <= right && top <= bottom); + if (isEmpty || other.isEmpty) { + return false; + } + return math.max(left, other.left) < math.min(right, other.right) && + math.max(top, other.top) < math.min(bottom, other.bottom); + } + + @override + int get hashCode => Object.hash(left, top, right, bottom); + + @override + bool operator ==(Object other) { + return other is Rect && + other.left == left && + other.top == top && + other.right == right && + other.bottom == bottom; + } + + @override + String toString() => 'Rect.fromLTRB($left, $top, $right, $bottom)'; +} diff --git a/packages/vector_graphics_compiler/lib/src/geometry/image.dart b/packages/vector_graphics_compiler/lib/src/geometry/image.dart new file mode 100644 index 000000000000..77e05171a85b --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/geometry/image.dart @@ -0,0 +1,43 @@ +// 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:typed_data'; + +import 'basic_types.dart'; +import 'matrix.dart'; + +/// The encoded image data and its format. +class ImageData { + /// Create a new [ImageData]. + const ImageData( + this.data, + this.format, + ); + + /// An encoded image. + final Uint8List data; + + /// The encoding format of the [data]. + final int format; +} + +/// A command to draw an image at a particular location. +class DrawImageData { + /// Create a new [DrawImageData]. + const DrawImageData( + this.id, + this.rect, + this.transform, + ); + + /// The corresponding encoding image to draw. + final int id; + + /// The x position of the image in pixels. + final Rect rect; + + /// An optional transform, if the position cannot be fully described + /// by [rect]. + final AffineMatrix? transform; +} diff --git a/packages/vector_graphics_compiler/lib/src/geometry/matrix.dart b/packages/vector_graphics_compiler/lib/src/geometry/matrix.dart new file mode 100644 index 000000000000..ff800343622e --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/geometry/matrix.dart @@ -0,0 +1,446 @@ +// 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:math' as math; +import 'dart:typed_data'; + +import 'package:meta/meta.dart'; +import '../../vector_graphics_compiler.dart'; + +import 'basic_types.dart'; + +/// An immutable affine matrix, a 3x3 column-major-order matrix in which the +/// last row is always set to the identity values, i.e. `0 0 1`. +@immutable +class AffineMatrix { + /// Creates an immutable affine matrix. To work with the identity matrix, use + /// the [identity] property. + const AffineMatrix( + this.a, + this.b, + this.c, + this.d, + this.e, + this.f, [ + double? m4_10, + ]) : _m4_10 = m4_10 ?? (1.0 * a); + + /// The identity affine matrix. + static const AffineMatrix identity = AffineMatrix(1, 0, 0, 1, 0, 0); + + /// The 0,0 position of the matrix. + final double a; + + /// The 0,1 position of the matrix. + final double b; + + /// The 1,0 position of the matrix. + final double c; + + /// The 1,1 position of the matrix. + final double d; + + /// The 2,0 position of the matrix. + final double e; + + /// The 1,2 position of the matrix. + final double f; + + /// Translations can affect this value, so we have to track it. + final double _m4_10; + + /// Calculates the scale for a stroke width based on the average of the x- and + /// y-axis scales of this matrix. + double? scaleStrokeWidth(double? width) { + if (width == null || (a == 1 && d == 1)) { + return width; + } + + final double xScale = math.sqrt(a * a + c * c); + final double yScale = math.sqrt(b * b + d * d); + + return (xScale + yScale) / 2 * width; + } + + /// Creates a new affine matrix rotated by `radians`. + AffineMatrix rotated(double radians) { + if (radians == 0) { + return this; + } + final double cosAngle = math.cos(radians); + final double sinAngle = math.sin(radians); + return AffineMatrix( + (a * cosAngle) + (c * sinAngle), + (b * cosAngle) + (d * sinAngle), + (a * -sinAngle) + (c * cosAngle), + (b * -sinAngle) + (d * cosAngle), + e, + f, + _m4_10, + ); + } + + /// Whether this matrix can be expressed be applied to a rect without any loss + /// of inforamtion. + /// + /// In other words, if this matrix is a simple translate and/or non-negative + /// scale with no rotation or skew, this property is true. Otherwise, it is + /// false. + bool get encodableInRect { + return a > 0 && b == 0 && c == 0 && d > 0 && _m4_10 == a; + } + + /// Creates a new affine matrix rotated by `x` and `y`. + /// + /// If `y` is not specified, it is defaulted to the same value as `x`. + AffineMatrix scaled(double x, [double? y]) { + y ??= x; + if (x == 1 && y == 1) { + return this; + } + return AffineMatrix( + a * x, + b * x, + c * y, + d * y, + e, + f, + _m4_10 * x, + ); + } + + /// Creates a new affine matrix, translated along the x and y axis. + AffineMatrix translated(double x, double y) { + return AffineMatrix( + a, + b, + c, + d, + (a * x) + (c * y) + e, + (b * x) + (d * y) + f, + _m4_10, + ); + } + + /// Creates a new affine matrix, skewed along the x axis. + AffineMatrix xSkewed(double x) { + return multiplied(AffineMatrix( + identity.a, + identity.b, + math.tan(x), + identity.d, + identity.e, + identity.f, + identity._m4_10, + )); + } + + /// Creates a new affine matrix, skewed along the y axis. + AffineMatrix ySkewed(double y) { + return multiplied(AffineMatrix( + identity.a, + math.tan(y), + identity.c, + identity.d, + identity.e, + identity.f, + identity._m4_10, + )); + } + + /// Creates a new affine matrix of this concatenated with `other`. + AffineMatrix multiplied(AffineMatrix other) { + return AffineMatrix( + (a * other.a) + (c * other.b), + (b * other.a) + (d * other.b), + (a * other.c) + (c * other.d), + (b * other.c) + (d * other.d), + (a * other.e) + (c * other.f) + e, + (b * other.e) + (d * other.f) + f, + _m4_10 * other._m4_10, + ); + } + + /// Maps `point` using the values of this matrix. + Point transformPoint(Point point) { + return Point( + (a * point.x) + (c * point.y) + e, + (b * point.x) + (d * point.y) + f, + ); + } + + /// Maps `rect` using the values of this matrix. + Rect transformRect(Rect rect) { + return _transformRect(toMatrix4(), rect); + } + + /// Creates a typed data representatino of this matrix suitable for use with + /// `package:vector_math_64` (and, by extension, Flutter/dart:ui). + Float64List toMatrix4() { + return Float64List.fromList([ + a, b, 0, 0, // + c, d, 0, 0, // + 0, 0, _m4_10, 0, // + e, f, 0, 1.0, // + ]); + } + + @override + int get hashCode => Object.hash(a, b, c, d, e, f, _m4_10); + + @override + bool operator ==(Object other) { + return other is AffineMatrix && + other.a == a && + other.b == b && + other.c == c && + other.d == d && + other.e == e && + other.f == f && + other._m4_10 == _m4_10; + } + + @override + String toString() => ''' +[ $a, $c, $e ] +[ $b, $d, $f ] +[ 0.0, 0.0, 1.0 ] // _m4_10 = $_m4_10 +'''; +} + +// transformRect implementation from package:flutter. + +/// Returns a rect that bounds the result of applying the given matrix as a +/// perspective transform to the given rect. +/// +/// This function assumes the given rect is in the plane with z equals 0.0. +/// The transformed rect is then projected back into the plane with z equals +/// 0.0 before computing its bounding rect. +Rect _transformRect(Float64List transform, Rect rect) { + final Float64List storage = transform; + final double x = rect.left; + final double y = rect.top; + final double w = rect.right - x; + final double h = rect.bottom - y; + + // We want to avoid turning a finite rect into an infinite one if we can. + assert(w.isFinite && h.isFinite, '($w, $h)'); + + // Transforming the 4 corners of a rectangle the straightforward way + // incurs the cost of transforming 4 points using vector math which + // involves 48 multiplications and 48 adds and then normalizing + // the points using 4 inversions of the homogeneous weight factor + // and then 12 multiplies. Once we have transformed all of the points + // we then need to turn them into a bounding box using 4 min/max + // operations each on 4 values yielding 12 total comparisons. + // + // On top of all of those operations, using the vector_math package to + // do the work for us involves allocating several objects in order to + // communicate the values back and forth - 4 allocating getters to extract + // the [Offset] objects for the corners of the [Rect], 4 conversions to + // a [Vector3] to use [Matrix4.perspectiveTransform()], and then 4 new + // [Offset] objects allocated to hold those results, yielding 8 [Offset] + // and 4 [Vector3] object allocations per rectangle transformed. + // + // But the math we really need to get our answer is actually much less + // than that. + // + // First, consider that a full point transform using the vector math + // package involves expanding it out into a vector3 with a Z coordinate + // of 0.0 and then performing 3 multiplies and 3 adds per coordinate: + // ``` + // xt = x*m00 + y*m10 + z*m20 + m30; + // yt = x*m01 + y*m11 + z*m21 + m31; + // zt = x*m02 + y*m12 + z*m22 + m32; + // wt = x*m03 + y*m13 + z*m23 + m33; + // ``` + // Immediately we see that we can get rid of the 3rd column of multiplies + // since we know that Z=0.0. We can also get rid of the 3rd row because + // we ignore the resulting Z coordinate. Finally we can get rid of the + // last row if we don't have a perspective transform since we can verify + // that the results are 1.0 for all points. This gets us down to 16 + // multiplies and 16 adds in the non-perspective case and 24 of each for + // the perspective case. (Plus the 12 comparisons to turn them back into + // a bounding box.) + // + // But we can do even better than that. + // + // Under optimal conditions of no perspective transformation, + // which is actually a very common condition, we can transform + // a rectangle in as little as 3 operations: + // + // (rx,ry) = transform of upper left corner of rectangle + // (wx,wy) = delta transform of the (w, 0) width relative vector + // (hx,hy) = delta transform of the (0, h) height relative vector + // + // A delta transform is a transform of all elements of the matrix except + // for the translation components. The translation components are added + // in at the end of each transform computation so they represent a + // constant offset for each point transformed. A delta transform of + // a horizontal or vertical vector involves a single multiplication due + // to the fact that it only has one non-zero coordinate and no addition + // of the translation component. + // + // In the absence of a perspective transform, the transformed + // rectangle will be mapped into a parallelogram with corners at: + // corner1 = (rx, ry) + // corner2 = corner1 + dTransformed width vector = (rx+wx, ry+wy) + // corner3 = corner1 + dTransformed height vector = (rx+hx, ry+hy) + // corner4 = corner1 + both dTransformed vectors = (rx+wx+hx, ry+wy+hy) + // In all, this method of transforming the rectangle requires only + // 8 multiplies and 12 additions (which we can reduce to 8 additions if + // we only need a bounding box, see below). + // + // In the presence of a perspective transform, the above conditions + // continue to hold with respect to the non-normalized coordinates so + // we can still save a lot of multiplications by computing the 4 + // non-normalized coordinates using relative additions before we normalize + // them and they lose their "pseudo-parallelogram" relationships. We still + // have to do the normalization divisions and min/max all 4 points to + // get the resulting transformed bounding box, but we save a lot of + // calculations over blindly transforming all 4 coordinates independently. + // In all, we need 12 multiplies and 22 additions to construct the + // non-normalized vectors and then 8 divisions (or 4 inversions and 8 + // multiplies) for normalization (plus the standard set of 12 comparisons + // for the min/max bounds operations). + // + // Back to the non-perspective case, the optimization that lets us get + // away with fewer additions if we only need a bounding box comes from + // analyzing the impact of the relative vectors on expanding the + // bounding box of the parallelogram. First, the bounding box always + // contains the transformed upper-left corner of the rectangle. Next, + // each relative vector either pushes on the left or right side of the + // bounding box and also either the top or bottom side, depending on + // whether it is positive or negative. Finally, you can consider the + // impact of each vector on the bounding box independently. If, say, + // wx and hx have the same sign, then the limiting point in the bounding + // box will be the one that involves adding both of them to the origin + // point. If they have opposite signs, then one will push one wall one + // way and the other will push the opposite wall the other way and when + // you combine both of them, the resulting "opposite corner" will + // actually be between the limits they established by pushing the walls + // away from each other, as below: + // ``` + // +---------(originx,originy)--------------+ + // | -----^---- | + // | ----- ---- | + // | ----- ---- | + // (+hx,+hy)< ---- | + // | ---- ---- | + // | ---- >(+wx,+wy) + // | ---- ----- | + // | ---- ----- | + // | ---- ----- | + // | v | + // +---------------(+wx+hx,+wy+hy)----------+ + // ``` + // In this diagram, consider that: + // ``` + // wx would be a positive number + // hx would be a negative number + // wy and hy would both be positive numbers + // ``` + // As a result, wx pushes out the right wall, hx pushes out the left wall, + // and both wy and hy push down the bottom wall of the bounding box. The + // wx,hx pair (of opposite signs) worked on opposite walls and the final + // opposite corner had an X coordinate between the limits they established. + // The wy,hy pair (of the same sign) both worked together to push the + // bottom wall down by their sum. + // + // This relationship allows us to simply start with the point computed by + // transforming the upper left corner of the rectangle, and then + // conditionally adding wx, wy, hx, and hy to either the left or top + // or right or bottom of the bounding box independently depending on sign. + // In that case we only need 4 comparisons and 4 additions total to + // compute the bounding box, combined with the 8 multiplications and + // 4 additions to compute the transformed point and relative vectors + // for a total of 8 multiplies, 8 adds, and 4 comparisons. + // + // An astute observer will note that we do need to do 2 subtractions at + // the top of the method to compute the width and height. Add those to + // all of the relative solutions listed above. The test for perspective + // also adds 3 compares to the affine case and up to 3 compares to the + // perspective case (depending on which test fails, the rest are omitted). + // + // The final tally: + // basic method = 60 mul + 48 add + 12 compare + // optimized perspective = 12 mul + 22 add + 15 compare + 2 sub + // optimized affine = 8 mul + 8 add + 7 compare + 2 sub + // + // Since compares are essentially subtractions and subtractions are + // the same cost as adds, we end up with: + // basic method = 60 mul + 60 add/sub/compare + // optimized perspective = 12 mul + 39 add/sub/compare + // optimized affine = 8 mul + 17 add/sub/compare + + final double wx = storage[0] * w; + final double hx = storage[4] * h; + final double rx = storage[0] * x + storage[4] * y + storage[12]; + + final double wy = storage[1] * w; + final double hy = storage[5] * h; + final double ry = storage[1] * x + storage[5] * y + storage[13]; + + if (storage[3] == 0.0 && storage[7] == 0.0 && storage[15] == 1.0) { + double left = rx; + double right = rx; + if (wx < 0) { + left += wx; + } else { + right += wx; + } + if (hx < 0) { + left += hx; + } else { + right += hx; + } + + double top = ry; + double bottom = ry; + if (wy < 0) { + top += wy; + } else { + bottom += wy; + } + if (hy < 0) { + top += hy; + } else { + bottom += hy; + } + + return Rect.fromLTRB(left, top, right, bottom); + } else { + final double ww = storage[3] * w; + final double hw = storage[7] * h; + final double rw = storage[3] * x + storage[7] * y + storage[15]; + + final double ulx = rx / rw; + final double uly = ry / rw; + final double urx = (rx + wx) / (rw + ww); + final double ury = (ry + wy) / (rw + ww); + final double llx = (rx + hx) / (rw + hw); + final double lly = (ry + hy) / (rw + hw); + final double lrx = (rx + wx + hx) / (rw + ww + hw); + final double lry = (ry + wy + hy) / (rw + ww + hw); + + return Rect.fromLTRB( + _min4(ulx, urx, llx, lrx), + _min4(uly, ury, lly, lry), + _max4(ulx, urx, llx, lrx), + _max4(uly, ury, lly, lry), + ); + } +} + +double _min4(double a, double b, double c, double d) { + final double e = (a < b) ? a : b; + final double f = (c < d) ? c : d; + return (e < f) ? e : f; +} + +double _max4(double a, double b, double c, double d) { + final double e = (a > b) ? a : b; + final double f = (c > d) ? c : d; + return (e > f) ? e : f; +} diff --git a/packages/vector_graphics_compiler/lib/src/geometry/path.dart b/packages/vector_graphics_compiler/lib/src/geometry/path.dart new file mode 100644 index 000000000000..4f5a5e2151f5 --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/geometry/path.dart @@ -0,0 +1,782 @@ +// 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:math' as math; + +import 'package:meta/meta.dart'; +import 'package:path_parsing/path_parsing.dart'; + +import '../util.dart'; +import 'basic_types.dart'; +import 'matrix.dart'; + +// This is a magic number used by impeller for radius approximation: +// https://github.com/flutter/impeller/blob/a2478aa4939a9a08c6c3810f72e0db42e7383a07/geometry/path_builder.cc#L9 +// See https://spencermortensen.com/articles/bezier-circle/ for more information. +const double _kArcApproximationMagic = 0.551915024494; + +/// Specifies the winding rule that decies how the interior of a [Path] is +/// calculated. +/// +/// This enum is used by the [Path.fillType] property. +/// +/// It is compatible with the same enum in `dart:ui`. +enum PathFillType { + /// The interior is defined by a non-zero sum of signed edge crossings. + /// + /// For a given point, the point is considered to be on the inside of the path + /// if a line drawn from the point to infinity crosses lines going clockwise + /// around the point a different number of times than it crosses lines going + /// counter-clockwise around that point. + nonZero, + + /// The interior is defined by an odd number of edge crossings. + /// + /// For a given point, the point is considered to be on the inside of the path + /// if a line drawn from the point to infinity crosses an odd number of lines. + evenOdd, +} + +/// The available types of path verbs. +/// +/// Used by [PathCommand.type]. +enum PathCommandType { + /// A path verb that picks up the pen to move it to another coordinate, + /// starting a new contour. + move, + + /// A path verb that draws a line from the current point to a specified + /// coordinate. + line, + + /// A path verb that draws a Bezier curve from the current point to a + /// specified point using two control points. + cubic, + + /// A path verb that draws a line from the current point to the starting + /// point of the current contour. + close, +} + +/// An abstract, immutable representation of a path verb and its associated +/// points. +/// +/// [Path] objects are collections of [PathCommand]s. To create a path object, +/// use a [PathBuilder]. To create a path object from an SVG path definition, +/// use [parseSvgPathData]. +@immutable +abstract class PathCommand { + const PathCommand._(this.type); + + /// The type of this path command. + final PathCommandType type; + + /// Returns a new path command transformed by `matrix`. + PathCommand transformed(AffineMatrix matrix); + + /// A representation of this path command for dart:ui. + String toFlutterString(); +} + +/// A straight line from the current point to x,y. +class LineToCommand extends PathCommand { + /// Creates a straight line command from the current point to x,y. + const LineToCommand(this.x, this.y) : super._(PathCommandType.line); + + /// The absolute offset of the destination point for this path from the x + /// axis. + final double x; + + /// The absolute offset of the destination point for this path from the y + /// axis. + final double y; + + @override + LineToCommand transformed(AffineMatrix matrix) { + final Point xy = matrix.transformPoint(Point(x, y)); + return LineToCommand(xy.x, xy.y); + } + + @override + int get hashCode => Object.hash(type, x, y); + + @override + bool operator ==(Object other) { + return other is LineToCommand && other.x == x && other.y == y; + } + + @override + String toFlutterString() => '..lineTo($x, $y)'; + + @override + String toString() => 'LineToCommand($x, $y)'; +} + +/// Moves the current point to x,y as if picking up the pen. +class MoveToCommand extends PathCommand { + /// Creates a new command that moves the current point to x,y without drawing. + const MoveToCommand(this.x, this.y) : super._(PathCommandType.move); + + /// The absolute offset of the destination point for this path from the x + /// axis. + final double x; + + /// The absolute offset of the destination point for this path from the y + /// axis. + final double y; + + @override + MoveToCommand transformed(AffineMatrix matrix) { + final Point xy = matrix.transformPoint(Point(x, y)); + return MoveToCommand(xy.x, xy.y); + } + + @override + int get hashCode => Object.hash(type, x, y); + + @override + bool operator ==(Object other) { + return other is MoveToCommand && other.x == x && other.y == y; + } + + @override + String toFlutterString() => '..moveTo($x, $y)'; + + @override + String toString() => 'MoveToCommand($x, $y)'; +} + +/// A command describing a cubic Bezier command from the current point to +/// x3,y3 using control points x1,y1 and x2,y2. +class CubicToCommand extends PathCommand { + /// Creates a new cubic Bezier command from the current point to x3,y3 using + /// control points x1,y1 and x2,y2. + const CubicToCommand(this.x1, this.y1, this.x2, this.y2, this.x3, this.y3) + : super._(PathCommandType.cubic); + + /// Creates a cubic command from the current point to [end] using [control1] + /// and [control2] as control points. + CubicToCommand.fromPoints(Point control1, Point control2, Point end) + : this(control1.x, control1.y, control2.x, control2.y, end.x, end.y); + + factory CubicToCommand._fromIterablePoints(Iterable points) { + final List list = points.toList(); + assert(list.length == 3); + return CubicToCommand.fromPoints(list[0], list[1], list[2]); + } + + /// The absolute offset of the first control point for this path from the x + /// axis. + final double x1; + + /// The absolute offset of the first control point for this path from the y + /// axis. + final double y1; + + /// A [Point] representation of [x1],[y1], the first control point. + Point get controlPoint1 => Point(x1, y1); + + /// The absolute offset of the second control point for this path from the x + /// axis. + final double x2; + + /// The absolute offset of the second control point for this path from the x + /// axis. + final double y2; + + /// A [Point] representation of [x2],[y2], the second control point. + Point get controlPoint2 => Point(x2, y2); + + /// The absolute offset of the destination point for this path from the x + /// axis. + final double x3; + + /// The absolute offset of the destination point for this path from the y + /// axis. + final double y3; + + /// A [Point] representation of [x3],[y3], the end point of the curve. + Point get endPoint => Point(x3, y3); + + /// Subdivides the cubic curve described by [start], [control1], [control2], + /// [end]. + /// + /// The returned list describes two cubics, where elements `0, 1, 2, 3` are + /// the start, cp1, cp2, and end points of the first cubic and `3, 4, 5, 6` + /// are the start, cp1, cp2, and end points of the second cubic. + static List subdivide( + Point start, + Point control1, + Point control2, + Point end, + double t, + ) { + final Point ab = Point.lerp(start, control1, t); + final Point bc = Point.lerp(control1, control2, t); + final Point cd = Point.lerp(control2, end, t); + final Point abc = Point.lerp(ab, bc, t); + final Point bcd = Point.lerp(bc, cd, t); + final Point abcd = Point.lerp(abc, bcd, t); + return [ + start, + ab, + abc, + abcd, + bcd, + cd, + end, + ]; + } + + /// Computes an approximation of the arc length of this cubic starting + /// from [start]. + double computeLength(Point start) { + // Mike Reed just made this up! The nerve of him. + // One difference from Skia is just setting a default tolerance of 3. This + // is good enough for a particular test SVG that has this curve: + // M65 33c0 17.673-14.326 32-32 32S1 50.673 1 33C1 15.327 15.326 1 33 1s32 14.327 32 32z + // Lower values end up getting the end points wrong when dashing a path. + const double tolerance = 1 / 2 * 3; + + double compute( + Point p1, + Point cp1, + Point cp2, + Point p2, + double distance, + ) { + // If it's "too curvy," cut it in half + if (Point.distance(cp1, Point.lerp(p1, p2, 1 / 3)) > tolerance || + Point.distance(cp2, Point.lerp(p1, p2, 2 / 3)) > tolerance) { + final List points = subdivide(p1, cp1, cp2, p2, .5); + distance = compute( + points[0], + points[1], + points[2], + points[3], + distance, + ); + distance = compute( + points[3], + points[4], + points[5], + points[6], + distance, + ); + } else { + // It's collinear enough to just treat as a line. + distance += Point.distance(p1, p2); + } + return distance; + } + + return compute(start, Point(x1, y1), Point(x2, y2), Point(x3, y3), 0); + } + + @override + CubicToCommand transformed(AffineMatrix matrix) { + final Point xy1 = matrix.transformPoint(Point(x1, y1)); + final Point xy2 = matrix.transformPoint(Point(x2, y2)); + final Point xy3 = matrix.transformPoint(Point(x3, y3)); + return CubicToCommand(xy1.x, xy1.y, xy2.x, xy2.y, xy3.x, xy3.y); + } + + @override + int get hashCode => Object.hash(type, x1, y1, x2, y2, x3, y3); + + @override + bool operator ==(Object other) { + return other is CubicToCommand && + other.x1 == x1 && + other.y1 == y1 && + other.x2 == x2 && + other.y2 == y2 && + other.x3 == x3 && + other.y3 == y3; + } + + @override + String toFlutterString() => '..cubicTo($x1, $y1, $x2, $y2, $x3, $y3)'; + + @override + String toString() => 'CubicToCommand($x1, $y1, $x2, $y2, $x3, $y3)'; +} + +/// A straight line from the current point to the current contour start point. +class CloseCommand extends PathCommand { + /// Creates a new straight line from the current point to the current contour + /// start point. + const CloseCommand() : super._(PathCommandType.close); + + @override + CloseCommand transformed(AffineMatrix matrix) { + return this; + } + + @override + int get hashCode => type.hashCode; + + @override + bool operator ==(Object other) { + return other is CloseCommand; + } + + @override + String toFlutterString() => '..close()'; + @override + String toString() => 'CloseCommand()'; +} + +/// Creates a new builder of [Path] objects. +class PathBuilder implements PathProxy { + /// Creates a new path builder for paths of the specified fill type. + /// + /// By default, will create non-zero filled paths. + PathBuilder([PathFillType? fillType]) + : fillType = fillType ?? PathFillType.nonZero; + + /// Creates a new mutable path builder object from an existing [Path]. + PathBuilder.fromPath(Path path) { + addPath(path); + fillType = path.fillType; + } + + final List _commands = []; + + @override + PathBuilder close() { + _commands.add(const CloseCommand()); + return this; + } + + @override + PathBuilder cubicTo( + double x1, + double y1, + double x2, + double y2, + double x3, + double y3, + ) { + _commands.add(CubicToCommand(x1, y1, x2, y2, x3, y3)); + return this; + } + + @override + PathBuilder lineTo(double x, double y) { + _commands.add(LineToCommand(x, y)); + return this; + } + + @override + PathBuilder moveTo(double x, double y) { + _commands.add(MoveToCommand(x, y)); + return this; + } + + /// Adds the commands of an existing path to the new path being created. + PathBuilder addPath(Path other) { + _commands.addAll(other._commands); + return this; + } + + /// Adds an oval command to new path. + PathBuilder addOval(Rect oval) { + final Point r = Point(oval.width * 0.5, oval.height * 0.5); + final Point c = Point( + oval.left + (oval.width * 0.5), + oval.top + (oval.height * 0.5), + ); + final Point m = Point( + _kArcApproximationMagic * r.x, + _kArcApproximationMagic * r.y, + ); + + moveTo(c.x, c.y - r.y); + + // Top right arc. + cubicTo(c.x + m.x, c.y - r.y, c.x + r.x, c.y - m.y, c.x + r.x, c.y); + + // Bottom right arc. + cubicTo(c.x + r.x, c.y + m.y, c.x + m.x, c.y + r.y, c.x, c.y + r.y); + + // Bottom left arc. + cubicTo(c.x - m.x, c.y + r.y, c.x - r.x, c.y + m.y, c.x - r.x, c.y); + + // Top left arc. + cubicTo(c.x - r.x, c.y - m.y, c.x - m.x, c.y - r.y, c.x, c.y - r.y); + + close(); + return this; + } + + /// Adds a rectangle to the new path. + PathBuilder addRect(Rect rect) { + moveTo(rect.left, rect.top); + lineTo(rect.right, rect.top); + lineTo(rect.right, rect.bottom); + lineTo(rect.left, rect.bottom); + close(); + return this; + } + + /// Adds a rounded rectangle to the new path. + PathBuilder addRRect(Rect rect, double rx, double ry) { + if (rx == 0 && ry == 0) { + return addRect(rect); + } + + final Point magicRadius = Point(rx, ry) * _kArcApproximationMagic; + + moveTo(rect.left + rx, rect.top); + + // Top line. + lineTo(rect.left + rect.width - rx, rect.top); + + // Top right arc. + // + cubicTo( + rect.left + rect.width - rx + magicRadius.x, + rect.top, + rect.left + rect.width, + rect.top + ry - magicRadius.y, + rect.left + rect.width, + rect.top + ry, + ); + + // Right line. + lineTo(rect.left + rect.width, rect.top + rect.height - ry); + + // Bottom right arc. + cubicTo( + rect.left + rect.width, + rect.top + rect.height - ry + magicRadius.y, + rect.left + rect.width - rx + magicRadius.x, + rect.top + rect.height, + rect.left + rect.width - rx, + rect.top + rect.height, + ); + + // Bottom line. + lineTo(rect.left + rx, rect.top + rect.height); + + // Bottom left arc. + cubicTo( + rect.left + rx - magicRadius.x, + rect.top + rect.height, + rect.left, + rect.top + rect.height - ry + magicRadius.y, + rect.left, + rect.top + rect.height - ry); + + // Left line. + lineTo(rect.left, rect.top + ry); + + // Top left arc. + cubicTo( + rect.left, + rect.top + ry - magicRadius.y, + rect.left + rx - magicRadius.x, + rect.top, + rect.left + rx, + rect.top, + ); + + close(); + return this; + } + + /// The fill type to use for the new path. + late PathFillType fillType; + + /// Creates a new [Path] object from the commands in this path. + /// + /// If `reset` is set to false, this builder can be used to create multiple + /// path objects with the same commands. By default, the builder will reset + /// to an initial state. + Path toPath({bool reset = true}) { + final Path path = Path( + commands: _commands, + fillType: fillType, + ); + + if (reset) { + _commands.clear(); + } + return path; + } +} + +/// An immutable collection of [PathCommand]s. +@immutable +class Path { + /// Creates a new immutable collection of [PathCommand]s. + Path({ + List commands = const [], + this.fillType = PathFillType.nonZero, + }) { + _commands.addAll(commands); + } + + /// Creates a copy of this path, replacing the current [fillType] with [type]. + Path withFillType(PathFillType type) { + if (type == fillType) { + return this; + } + return Path(fillType: type, commands: _commands); + } + + /// Whether this path has any commands. + bool get isEmpty => _commands.isEmpty; + + /// The commands this path contains. + Iterable get commands => _commands; + + final List _commands = []; + + /// The fill type of this path, defaulting to [PathFillType.nonZero]. + final PathFillType fillType; + + /// Creates a new path whose commands and points are transformed by `matrix`. + Path transformed(AffineMatrix matrix) { + final List commands = []; + for (final PathCommand command in _commands) { + commands.add(command.transformed(matrix)); + } + return Path( + commands: commands, + fillType: fillType, + ); + } + + @override + int get hashCode => Object.hash(Object.hashAll(_commands), fillType); + + @override + bool operator ==(Object other) { + return other is Path && + listEquals(_commands, other._commands) && + other.fillType == fillType; + } + + /// Creates a dashed version of this path. + /// + /// The interval list is read in a circular fashion, such that the first + /// interval is used to dash and the second to move. If the list is an odd + /// number of elements, it is effectively the same as if it were repeated + /// twice. + /// + /// Callers are responsible for not passing interval lists consisting entirely + /// of `0`. + Path dashed(List intervals) { + if (intervals.isEmpty) { + return this; + } + final _PathDasher dasher = _PathDasher(intervals); + return dasher.dash(this); + } + + /// Compute the bounding box for the given path segment. + Rect bounds() { + if (_commands.isEmpty) { + return Rect.zero; + } + double smallestX = double.maxFinite; + double smallestY = double.maxFinite; + double largestX = -double.maxFinite; + double largestY = -double.maxFinite; + for (final PathCommand command in _commands) { + switch (command.type) { + case PathCommandType.move: + final MoveToCommand move = command as MoveToCommand; + smallestX = math.min(move.x, smallestX); + smallestY = math.min(move.y, smallestY); + largestX = math.max(move.x, largestX); + largestY = math.max(move.y, largestY); + case PathCommandType.line: + final LineToCommand move = command as LineToCommand; + smallestX = math.min(move.x, smallestX); + smallestY = math.min(move.y, smallestY); + largestX = math.max(move.x, largestX); + largestY = math.max(move.y, largestY); + case PathCommandType.cubic: + final CubicToCommand cubic = command as CubicToCommand; + for (final List pair in >[ + [cubic.x1, cubic.y1], + [cubic.x2, cubic.y2], + [cubic.x3, cubic.y3], + ]) { + smallestX = math.min(pair[0], smallestX); + smallestY = math.min(pair[1], smallestY); + largestX = math.max(pair[0], largestX); + largestY = math.max(pair[1], largestY); + } + case PathCommandType.close: + break; + } + } + return Rect.fromLTRB(smallestX, smallestY, largestX, largestY); + } + + /// Returns a string that prints the dart:ui code to create this path. + String toFlutterString() { + final StringBuffer buffer = StringBuffer('Path()'); + if (fillType != PathFillType.nonZero) { + buffer.write('\n ..fillType = $fillType'); + } + for (final PathCommand command in commands) { + buffer.write('\n ${command.toFlutterString()}'); + } + buffer.write(';'); + return buffer.toString(); + } + + @override + String toString() { + final StringBuffer buffer = StringBuffer('Path('); + if (commands.isNotEmpty) { + buffer.write('\n commands: $commands,'); + } + if (fillType != PathFillType.nonZero) { + buffer.write('\n fillType: $fillType,'); + } + buffer.write('\n)'); + return buffer.toString(); + } +} + +/// Creates a new [Path] object from an SVG path data string. +Path parseSvgPathData(String svg, [PathFillType? type]) { + if (svg == '') { + return Path(fillType: type ?? PathFillType.nonZero); + } + + final SvgPathStringSource parser = SvgPathStringSource(svg); + final PathBuilder pathBuilder = PathBuilder(type); + final SvgPathNormalizer normalizer = SvgPathNormalizer(); + for (final PathSegmentData seg in parser.parseSegments()) { + normalizer.emitSegment(seg, pathBuilder); + } + return pathBuilder.toPath(); +} + +class _CircularIntervalList { + _CircularIntervalList(this._vals) + : assert(_vals.isNotEmpty), + assert(!_vals.every((double val) => val == 0)); + + final List _vals; + int _idx = 0; + + double get next { + if (_idx >= _vals.length) { + _idx = 0; + } + return _vals[_idx++]; + } +} + +class _PathDasher { + _PathDasher(List intervals) + : assert(!intervals.every((double interval) => interval == 0)), + _intervals = _CircularIntervalList(intervals); + + final _CircularIntervalList _intervals; + + late double length; + Point currentPoint = Point.zero; + Point currentSubpathPoint = Point.zero; + late bool draw; + + final List _dashedCommands = []; + + void _dashLineTo(Point target) { + double distance = Point.distance(currentPoint, target); + + if (distance <= 0 || length <= 0) { + return; + } + + while (distance >= length) { + final double t = length / distance; + currentPoint = Point.lerp(currentPoint, target, t); + length = _intervals.next; + + if (draw) { + _dashedCommands.add(LineToCommand(currentPoint.x, currentPoint.y)); + } else { + _dashedCommands.add(MoveToCommand(currentPoint.x, currentPoint.y)); + } + + distance = Point.distance(currentPoint, target); + draw = !draw; + } + if (distance > 0) { + length -= distance; + if (draw) { + _dashedCommands.add(LineToCommand(target.x, target.y)); + } + } + currentPoint = target; + } + + void _dashCubicTo(CubicToCommand cubic) { + double distance = cubic.computeLength(currentPoint); + while (distance >= length) { + final double t = length / distance; + final List dividedPoints = CubicToCommand.subdivide( + currentPoint, + cubic.controlPoint1, + cubic.controlPoint2, + cubic.endPoint, + t, + ); + currentPoint = dividedPoints[3]; + if (draw) { + _dashedCommands.add(CubicToCommand._fromIterablePoints( + dividedPoints.skip(1).take(3), + )); + } else { + _dashedCommands.add(MoveToCommand( + currentPoint.x, + currentPoint.y, + )); + } + cubic = CubicToCommand._fromIterablePoints( + dividedPoints.skip(4).take(3), + ); + length = _intervals.next; + distance = cubic.computeLength(currentPoint); + draw = !draw; + } + length -= distance; + currentPoint = cubic.endPoint; + if (draw) { + _dashedCommands.add(cubic); + } + } + + Path dash(Path path) { + length = _intervals.next; + draw = true; + for (final PathCommand command in path._commands) { + switch (command.type) { + case PathCommandType.move: + final MoveToCommand move = command as MoveToCommand; + currentPoint = Point(move.x, move.y); + currentSubpathPoint = currentPoint; + _dashedCommands.add(command); + case PathCommandType.line: + final LineToCommand line = command as LineToCommand; + _dashLineTo(Point(line.x, line.y)); + case PathCommandType.cubic: + _dashCubicTo(command as CubicToCommand); + case PathCommandType.close: + _dashLineTo(currentSubpathPoint); + currentPoint = currentSubpathPoint; + } + } + return Path(commands: _dashedCommands, fillType: path.fillType); + } +} diff --git a/packages/vector_graphics_compiler/lib/src/geometry/pattern.dart b/packages/vector_graphics_compiler/lib/src/geometry/pattern.dart new file mode 100644 index 000000000000..5aacb80b52ec --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/geometry/pattern.dart @@ -0,0 +1,44 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:meta/meta.dart'; + +import 'matrix.dart'; + +/// Pattern positioning and size information. +@immutable +class PatternData { + /// Constructs new [PatternData]. + const PatternData(this.x, this.y, this.width, this.height, this.transform); + + /// The x coordinate shift of the pattern tile in px. + final double x; + + /// The y coordinate shift of the pattern tile in px. + final double y; + + /// The width of the pattern's viewbox in px. + /// Values must be > = 1. + final double width; + + /// The height of the pattern's viewbox in px. + /// Values must be > = 1. + final double height; + + /// The transform of the pattern generated from its children. + final AffineMatrix transform; + + @override + int get hashCode => Object.hash(x, y, width, height, transform); + + @override + bool operator ==(Object other) { + return other is PatternData && + other.x == x && + other.y == y && + other.width == width && + other.height == height && + other.transform == transform; + } +} diff --git a/packages/vector_graphics_compiler/lib/src/geometry/vertices.dart b/packages/vector_graphics_compiler/lib/src/geometry/vertices.dart new file mode 100644 index 000000000000..e9c972c72799 --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/geometry/vertices.dart @@ -0,0 +1,83 @@ +// 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:typed_data'; + +import 'basic_types.dart'; + +/// A description of vertex points for drawing triangles. +class Vertices { + /// Creates a new collection of triangle vertices at the specified points. + const Vertices(this.vertexPoints); + + /// Creates a new collection of triangle vertices from the specified + /// [Float32List], interpreted as x,y pairs. + factory Vertices.fromFloat32List(Float32List vertices) { + if (vertices.length.isOdd) { + throw ArgumentError( + 'must be an even number of vertex points', + 'vertices', + ); + } + final List vertexPoints = []; + for (int index = 0; index < vertices.length; index += 2) { + vertexPoints.add(Point(vertices[index], vertices[index + 1])); + } + return Vertices(vertexPoints); + } + + /// A list of vertex points descibing this triangular mesh. + /// + /// The vertex points are assumed to be in VertexMode.triangle. + final List vertexPoints; + + /// Creates an optimized version of [vertexPoints] where the points are + /// deduplicated via an index buffer. + IndexedVertices createIndex() { + final Map pointMap = {}; + int index = 0; + final List indices = []; + for (final Point point in vertexPoints) { + indices.add(pointMap.putIfAbsent(point, () => index++)); + } + + Float32List pointsToFloat32List(List points) { + final Float32List vertices = Float32List(points.length * 2); + int vertexIndex = 0; + for (final Point point in points) { + vertices[vertexIndex++] = point.x; + vertices[vertexIndex++] = point.y; + } + return vertices; + } + + final List compressedPoints = pointMap.keys.toList(); + if (compressedPoints.length * 2 + indices.length > + vertexPoints.length * 2) { + return IndexedVertices(pointsToFloat32List(vertexPoints), null); + } + + return IndexedVertices( + pointsToFloat32List(compressedPoints), + Uint16List.fromList(indices), + ); + } +} + +/// An optimized version of [Vertices] that uses an index buffer to specify +/// reused vertex points. +class IndexedVertices { + /// Creates a indexed set of vertices. + /// + /// Consider using [Vertices.createIndex]. + const IndexedVertices(this.vertices, this.indices); + + /// The raw vertex points. + final Float32List vertices; + + /// The order to use vertices from [vertices]. + /// + /// May be null if [vertices] was not compressable. + final Uint16List? indices; +} diff --git a/packages/vector_graphics_compiler/lib/src/image/image_info.dart b/packages/vector_graphics_compiler/lib/src/image/image_info.dart new file mode 100644 index 000000000000..c4e422b8aa6f --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/image/image_info.dart @@ -0,0 +1,215 @@ +// 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:typed_data'; + +/// Image formats supported by Flutter. +enum ImageFormat { + /// A Portable Network Graphics format image. + png, + + /// A JPEG format image. + /// + /// This library does not support JPEG 2000. + jpeg, + + /// A WebP format image. + webp, + + /// A Graphics Interchange Format image. + gif, + + /// A Windows Bitmap format image. + bmp, +} + +/// Provides details about image format information for raw compressed bytes +/// of an image. +abstract class ImageSizeData { + /// Allows subclasses to be const. + const ImageSizeData({ + required this.format, + required this.width, + required this.height, + }) : assert(width >= 0), + assert(height >= 0); + + /// Creates an appropriate [ImageSizeData] for the source `bytes`, if possible. + /// + /// Only supports image formats supported by Flutter. + factory ImageSizeData.fromBytes(Uint8List bytes) { + if (bytes.isEmpty) { + throw ArgumentError('bytes was empty'); + } + if (PngImageSizeData.matches(bytes)) { + return PngImageSizeData._(bytes.buffer.asByteData()); + } + if (GifImageSizeData.matches(bytes)) { + return GifImageSizeData._(bytes.buffer.asByteData()); + } + if (JpegImageSizeData.matches(bytes)) { + return JpegImageSizeData._fromBytes(bytes.buffer.asByteData()); + } + if (WebPImageSizeData.matches(bytes)) { + return WebPImageSizeData._(bytes.buffer.asByteData()); + } + if (BmpImageSizeData.matches(bytes)) { + return BmpImageSizeData._(bytes.buffer.asByteData()); + } + throw ArgumentError('unknown image type'); + } + + /// The [ImageFormat] this instance represents. + final ImageFormat format; + + /// The width, in pixels, of the image. + /// + /// If the image is multi-frame, this is the width of the first frame. + final int width; + + /// The height, in pixels, of the image. + /// + /// If the image is multi-frame, this is the height of the first frame. + final int height; + + /// The esimated size of the image in bytes. + /// + /// The `withMipmapping` parameter controls whether to account for mipmapping + /// when decompressing the image. Flutter will use this when possible, at the + /// cost of slightly more memory usage. + int decodedSizeInBytes({bool withMipmapping = true}) { + if (withMipmapping) { + return (width * height * 4.3).ceil(); + } + return width * height * 4; + } +} + +/// The [ImageSizeData] for a PNG image. +class PngImageSizeData extends ImageSizeData { + PngImageSizeData._(ByteData data) + : super( + format: ImageFormat.png, + width: data.getUint32(16), + height: data.getUint32(20), + ); + + /// Returns true if `bytes` starts with the expected header for a PNG image. + static bool matches(Uint8List bytes) { + return bytes.lengthInBytes > 20 && + bytes[0] == 0x89 && + bytes[1] == 0x50 && + bytes[2] == 0x4E && + bytes[3] == 0x47 && + bytes[4] == 0x0D && + bytes[5] == 0x0A && + bytes[6] == 0x1A && + bytes[7] == 0x0A; + } +} + +/// The [ImageSizeData] for a GIF image. +class GifImageSizeData extends ImageSizeData { + GifImageSizeData._(ByteData data) + : super( + format: ImageFormat.gif, + width: data.getUint16(6, Endian.little), + height: data.getUint16(8, Endian.little), + ); + + /// Returns true if `bytes` starts with the expected header for a GIF image. + static bool matches(Uint8List bytes) { + return bytes.lengthInBytes > 8 && + bytes[0] == 0x47 && + bytes[1] == 0x49 && + bytes[2] == 0x46 && + bytes[3] == 0x38 && + (bytes[4] == 0x37 || bytes[4] == 0x39) // 7 or 9 + && + bytes[5] == 0x61; + } +} + +/// The [ImageSizeData] for a JPEG image. +/// +/// This library does not support JPEG2000 images. +class JpegImageSizeData extends ImageSizeData { + JpegImageSizeData._({required super.width, required super.height}) + : super( + format: ImageFormat.jpeg, + ); + + factory JpegImageSizeData._fromBytes(ByteData data) { + int index = 4; // Skip the first header bytes (already validated). + index += data.getUint16(index); + while (index < data.lengthInBytes) { + if (data.getUint8(index) != 0xFF) { + // Start of block + throw StateError('Invalid JPEG file'); + } + if (const [0xC0, 0xC1, 0xC2].contains(data.getUint8(index + 1))) { + // Start of frame 0 + return JpegImageSizeData._( + height: data.getUint16(index + 5), + width: data.getUint16(index + 7), + ); + } + index += 2; + index += data.getUint16(index); + } + throw StateError('Invalid JPEG'); + } + + /// Returns true if `bytes` starts with the expected header for a JPEG image. + static bool matches(Uint8List bytes) { + return bytes.lengthInBytes > 12 && + bytes[0] == 0xFF && + bytes[1] == 0xD8 && + bytes[2] == 0xFF; + } +} + +/// The [ImageSizeData] for a WebP image. +class WebPImageSizeData extends ImageSizeData { + WebPImageSizeData._(ByteData data) + : super( + format: ImageFormat.webp, + width: data.getUint16(26, Endian.little), + height: data.getUint16(28, Endian.little), + ); + + /// Returns true if `bytes` starts with the expected header for a WebP image. + static bool matches(Uint8List bytes) { + return bytes.lengthInBytes > 28 && + bytes[0] == 0x52 // R + && + bytes[1] == 0x49 // I + && + bytes[2] == 0x46 // F + && + bytes[3] == 0x46 // F + && + bytes[8] == 0x57 // W + && + bytes[9] == 0x45 // E + && + bytes[10] == 0x42 // B + && + bytes[11] == 0x50; // P + } +} + +/// The [ImageSizeData] for a BMP image. +class BmpImageSizeData extends ImageSizeData { + BmpImageSizeData._(ByteData data) + : super( + format: ImageFormat.bmp, + width: data.getInt32(18, Endian.little), + height: data.getInt32(22, Endian.little)); + + /// Returns true if `bytes` starts with the expected header for a WebP image. + static bool matches(Uint8List bytes) { + return bytes.lengthInBytes > 22 && bytes[0] == 0x42 && bytes[1] == 0x4D; + } +} diff --git a/packages/vector_graphics_compiler/lib/src/paint.dart b/packages/vector_graphics_compiler/lib/src/paint.dart new file mode 100644 index 000000000000..5085f47526a5 --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/paint.dart @@ -0,0 +1,1518 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:meta/meta.dart'; +import 'package:vector_graphics_codec/vector_graphics_codec.dart'; + +import 'geometry/basic_types.dart'; +import 'geometry/matrix.dart'; +import 'util.dart'; + +// The enumerations in this file must match the ordering and index valuing of +// the similarly named enumerations in dart:ui. + +/// An immutable representation of a 32 bit color. +@immutable +class Color { + /// Creates an immutable representation of a 32 bit color. + /// + /// The first 8 bits are the alpha value, the next 8 red, the next 8 green, + /// and the last 8 blue. + const Color(this.value); + + /// Creates an immutable representation of color from its red, green, blue, + /// and 0..1 opacity parts. + const Color.fromRGBO(int r, int g, int b, double opacity) + : value = ((((opacity * 0xff ~/ 1) & 0xff) << 24) | + ((r & 0xff) << 16) | + ((g & 0xff) << 8) | + ((b & 0xff) << 0)) & + 0xFFFFFFFF; + + /// Creates an immutable representation of color from its alpha, red, green, + /// and blue parts. + /// + /// Each part is represented by an integer from 0..255. + const Color.fromARGB(int a, int r, int g, int b) + : value = (((a & 0xff) << 24) | + ((r & 0xff) << 16) | + ((g & 0xff) << 8) | + ((b & 0xff) << 0)) & + 0xFFFFFFFF; + + /// Fully opaque black. + static const Color opaqueBlack = Color(0xFF000000); + + /// Creates a new color based on this color with the specified opacity, + /// unpremultiplied. + Color withOpacity(double opacity) { + return Color.fromRGBO(r, g, b, opacity); + } + + /// The raw 32 bit color value. + /// + /// The first 8 bits are the alpha value, the next 8 red, the next 8 green, + /// and the last 8 blue. + final int value; + + /// The red channel value from 0..255. + int get r => (0x00ff0000 & value) >> 16; + + /// The green channel value from 0..255. + int get g => (0x0000ff00 & value) >> 8; + + /// The blue channel value from 0..255. + int get b => (0x000000ff & value) >> 0; + + /// The opacity channel value from 0..255. + int get a => value >> 24; + + @override + String toString() => 'Color(0x${value.toRadixString(16).padLeft(8, '0')})'; + + @override + int get hashCode => value; + + @override + bool operator ==(Object other) { + return other is Color && other.value == value; + } +} + +/// A shading program to apply to a [Paint]. Implemented in [LinearGradient] and +/// [RadialGradient]. +@immutable +abstract class Gradient { + /// Allows subclasses to be const. + const Gradient._( + this.id, + this.colors, + this.offsets, + this.tileMode, + this.unitMode, + this.transform, + ); + + /// The reference identifier for this gradient. + final String id; + + /// The colors to blend from the start to end points. + final List? colors; + + /// The positions to apply [colors] to. Must be the same length as [colors]. + final List? offsets; + + /// Specifies the meaning of [from] and [to]. + final TileMode? tileMode; + + /// Whether the coordinates in this gradient should be transformed by the + /// space this object occupies or by the root bounds. + final GradientUnitMode? unitMode; + + /// The transform, if any, to apply to the gradient. + final AffineMatrix? transform; + + /// Apply the bounds and transform the shader. + Gradient applyBounds(Rect bounds, AffineMatrix transform); + + /// Creates a new gradient + Gradient applyProperties(Gradient ref); +} + +/// A [Gradient] that describes a linear gradient from [from] to [to]. +/// +/// If [offsets] is provided, `offsets[i]` is a number from 0.0 to 1.0 +/// that specifies where `offsets[i]` begins in the gradient. If [offsets] is +/// not provided, then only two stops, at 0.0 and 1.0, are implied (and +/// [colors] must therefore only have two entries). +/// +/// The behavior before [from] and after [to] is described by the [tileMode] +/// argument. For details, see the [TileMode] enum. +/// +/// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/tile_mode_clamp_linear.png) +/// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/tile_mode_decal_linear.png) +/// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/tile_mode_mirror_linear.png) +/// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/tile_mode_repeated_linear.png) +/// +/// If [transform] is provided, the gradient fill will be transformed by the +/// specified affine matrix relative to the local coordinate system. +class LinearGradient extends Gradient { + /// Creates a new linear gradient shader. + const LinearGradient({ + required String id, + required this.from, + required this.to, + List? colors, + List? offsets, + TileMode? tileMode, + GradientUnitMode? unitMode, + AffineMatrix? transform, + }) : super._(id, colors, offsets, tileMode, unitMode, transform); + + /// The start point of the gradient, as specified by [tileMode]. + final Point from; + + /// The end point of the gradient, as specified by [tileMode]. + final Point to; + + @override + LinearGradient applyBounds(Rect bounds, AffineMatrix transform) { + assert(offsets != null); + assert(colors != null); + AffineMatrix accumulatedTransform = this.transform ?? AffineMatrix.identity; + switch (unitMode ?? GradientUnitMode.objectBoundingBox) { + case GradientUnitMode.objectBoundingBox: + accumulatedTransform = transform + .translated(bounds.left, bounds.top) + .scaled(bounds.width, bounds.height) + .multiplied(accumulatedTransform); + case GradientUnitMode.userSpaceOnUse: + accumulatedTransform = transform.multiplied(accumulatedTransform); + case GradientUnitMode.transformed: + break; + } + + return LinearGradient( + id: id, + from: accumulatedTransform.transformPoint(from), + to: accumulatedTransform.transformPoint(to), + colors: colors, + offsets: offsets, + tileMode: tileMode ?? TileMode.clamp, + unitMode: GradientUnitMode.transformed, + ); + } + + @override + LinearGradient applyProperties(Gradient ref) { + return LinearGradient( + id: id, + from: from, + to: to, + colors: colors ?? ref.colors, + offsets: offsets ?? ref.offsets, + tileMode: tileMode ?? ref.tileMode, + unitMode: unitMode ?? ref.unitMode, + transform: transform ?? ref.transform, + ); + } + + @override + int get hashCode => Object.hash( + id, + from, + to, + Object.hashAll(colors ?? []), + Object.hashAll(offsets ?? []), + tileMode, + unitMode); + + @override + bool operator ==(Object other) { + return other is LinearGradient && + other.id == id && + other.from == from && + other.to == to && + listEquals(other.colors, colors) && + listEquals(other.offsets, offsets) && + other.tileMode == tileMode && + other.unitMode == unitMode; + } + + @override + String toString() { + return 'LinearGradient(' + "id: '$id', " + 'from: $from, ' + 'to: $to, ' + 'colors: $colors, ' + 'offsets: $offsets, ' + 'tileMode: $tileMode, ' + '${transform == null ? '' : 'Float64List.fromList(${transform!.toMatrix4()}), '}' + 'unitMode: $unitMode)'; + } +} + +/// Determines how to transform the points given for a gradient. +enum GradientUnitMode { + /// The gradient vector(s) are transformed by the space in the object + /// containing the gradient. + objectBoundingBox, + + /// The gradient vector(s) are transformed by the root bounds of the drawing. + userSpaceOnUse, + + /// The gradient vectors are already transformed. + transformed, +} + +/// Creates a radial gradient centered at [center] that ends at [radius] +/// distance from the center. +/// +/// If [offsets] is provided, `offsets[i]` is a number from 0.0 to 1.0 +/// that specifies where `colors[i]` begins in the gradient. If [offsets] is +/// not provided, then only two stops, at 0.0 and 1.0, are implied (and +/// [colors] must therefore only have two entries). +/// +/// The behavior before and after the radius is described by the [tileMode] +/// argument. For details, see the [TileMode] enum. +/// +/// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/tile_mode_clamp_radial.png) +/// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/tile_mode_decal_radial.png) +/// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/tile_mode_mirror_radial.png) +/// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/tile_mode_repeated_radial.png) +/// +/// If [transform] is provided, the gradient fill will be transformed by the +/// specified affine matrix relative to the local coordinate system. +/// +/// If [focalPoint] is provided and not equal to [center] and [focalRadius] +/// is provided and not equal to 0.0, the generated shader will be a two point +/// conical radial gradient, with [focalPoint] being the center of the focal +/// circle. If [focalPoint] is provided and not equal to [center], at least one +/// of the two offsets must not be equal to [Point.zero]. +class RadialGradient extends Gradient { + /// Creates a new radial gradient object with the specified properties. + /// + /// See [RadialGradient]. + const RadialGradient({ + required String id, + required this.center, + required this.radius, + List? colors, + List? offsets, + TileMode? tileMode, + AffineMatrix? transform, + this.focalPoint, + GradientUnitMode? unitMode, + }) : super._(id, colors, offsets, tileMode, unitMode, transform); + + /// The central point of the gradient. + final Point center; + + /// The colors to blend from the start to end points. + final double radius; + + /// If specified, creates a two-point conical gradient using [center] and the + /// [focalPoint]. + final Point? focalPoint; + + @override + RadialGradient applyBounds(Rect bounds, AffineMatrix transform) { + assert(offsets != null); + assert(colors != null); + AffineMatrix accumulatedTransform = this.transform ?? AffineMatrix.identity; + switch (unitMode ?? GradientUnitMode.objectBoundingBox) { + case GradientUnitMode.objectBoundingBox: + accumulatedTransform = transform + .translated(bounds.left, bounds.top) + .scaled(bounds.width, bounds.height) + .multiplied(accumulatedTransform); + case GradientUnitMode.userSpaceOnUse: + accumulatedTransform = transform.multiplied(accumulatedTransform); + case GradientUnitMode.transformed: + break; + } + + return RadialGradient( + id: id, + center: center, + radius: radius, + colors: colors, + offsets: offsets, + tileMode: tileMode ?? TileMode.clamp, + transform: accumulatedTransform, + focalPoint: focalPoint, + unitMode: GradientUnitMode.transformed, + ); + } + + @override + RadialGradient applyProperties(Gradient ref) { + return RadialGradient( + id: id, + center: center, + radius: radius, + focalPoint: focalPoint, + colors: colors ?? ref.colors, + offsets: offsets ?? ref.offsets, + transform: transform ?? ref.transform, + unitMode: unitMode ?? ref.unitMode, + tileMode: tileMode ?? ref.tileMode, + ); + } + + @override + int get hashCode => Object.hash( + id, + center, + radius, + Object.hashAll(colors ?? []), + Object.hashAll(offsets ?? []), + tileMode, + transform, + focalPoint, + unitMode); + + @override + bool operator ==(Object other) { + return other is RadialGradient && + other.id == id && + other.center == center && + other.radius == radius && + other.focalPoint == focalPoint && + listEquals(other.colors, colors) && + listEquals(other.offsets, offsets) && + other.transform == transform && + other.tileMode == tileMode && + other.unitMode == unitMode; + } + + @override + String toString() { + return 'RadialGradient(' + "id: '$id', " + 'center: $center, ' + 'radius: $radius, ' + 'colors: $colors, ' + 'offsets: $offsets, ' + 'tileMode: $tileMode, ' + '${transform == null ? '' : 'transform: Float64List.fromList(${transform!.toMatrix4()}) ,'}' + 'focalPoint: $focalPoint, ' + 'unitMode: $unitMode)'; + } +} + +/// An immutable collection of painting attributes. +/// +/// Null attribute values indicate that a value is expected to inherit from +/// parent or accept a child's painting value. +/// +/// Leaf nodes in a painting graph must have a non-null [fill] or a non-null +/// [stroke]. If both [stroke] and [fill] are not null, the expected painting +/// order is [fill] followed by [stroke]. +@immutable +class Paint { + /// Creates a new collection of painting attributes. + /// + /// See [Paint]. + const Paint({ + BlendMode? blendMode, + this.stroke, + this.fill, + }) : blendMode = blendMode ?? BlendMode.srcOver; + + /// The Porter-Duff algorithm to use when compositing this painting object + /// with any objects painted under it. + /// + /// Defaults to [BlendMode.srcOver]. + final BlendMode blendMode; + + /// The stroke properties, if any, to apply to shapes drawn with this paint. + /// + /// If both stroke and [fill] are non-null, the fill is painted first, + /// followed by stroke. + final Stroke? stroke; + + /// The fill properties, if any, to apply to shapes drawn with this paint. + /// + /// If both [stroke] and fill are non-null, the fill is painted first, + /// followed by stroke. + final Fill? fill; + + @override + int get hashCode => Object.hash(blendMode, stroke, fill); + + @override + bool operator ==(Object other) { + return other is Paint && + other.blendMode == blendMode && + other.stroke == stroke && + other.fill == fill; + } + + /// Apply the bounds to the given paint. + /// + /// May be a no-op if no properties of the paint are impacted by + /// the bounds. + Paint applyBounds(Rect bounds, AffineMatrix transform) { + final Gradient? shader = fill?.shader; + if (shader == null) { + return this; + } + final Gradient newShader = shader.applyBounds(bounds, transform); + return Paint( + blendMode: blendMode, + stroke: stroke, + fill: Fill( + color: fill!.color, + shader: newShader, + ), + ); + } + + @override + String toString() { + final StringBuffer buffer = StringBuffer('Paint(blendMode: $blendMode'); + const String leading = ', '; + if (stroke != null) { + buffer.write('${leading}stroke: $stroke'); + } + if (fill != null) { + buffer.write('${leading}fill: $fill'); + } + buffer.write(')'); + return buffer.toString(); + } +} + +/// An immutable collection of stroking properties for a [Paint]. +/// +/// See also [Paint.stroke]. +@immutable +class Stroke { + /// Creates a new collection of stroking properties. + const Stroke({ + Color? color, + this.shader, + this.cap, + this.join, + this.miterLimit, + this.width, + }) : color = color ?? Color.opaqueBlack; + + /// The color to use for this stroke. + /// + /// Defaults to [Color.opaqueBlack]. + /// + /// If [shader] is not null, only the opacity is used. + final Color color; + + /// The [Gradient] to use when stroking. + final Gradient? shader; + + /// The cap style to use for strokes. + /// + /// Defaults to [StrokeCap.butt]. + final StrokeCap? cap; + + /// The join style to use for strokes. + /// + /// Defaults to [StrokeJoin.miter]. + final StrokeJoin? join; + + /// The limit where stroke joins drawn with [StrokeJoin.miter] switch to being + /// drawn as [StrokeJoin.bevel]. + final double? miterLimit; + + /// The width of the stroke, if [style] is [PaintingStyle.stroke]. + final double? width; + + @override + int get hashCode => Object.hash( + PaintingStyle.stroke, color, shader, cap, join, miterLimit, width); + + @override + bool operator ==(Object other) { + return other is Stroke && + other.color == color && + other.shader == shader && + other.cap == cap && + other.join == join && + other.miterLimit == miterLimit && + other.width == width; + } + + @override + String toString() { + final StringBuffer buffer = StringBuffer('Stroke(color: $color'); + const String leading = ', '; + if (shader != null) { + buffer.write('${leading}shader: $shader'); + } + if (cap != null) { + buffer.write('${leading}cap: $cap'); + } + if (join != null) { + buffer.write('${leading}join: $join'); + } + if (miterLimit != null) { + buffer.write('${leading}miterLimit: $miterLimit'); + } + if (width != null) { + buffer.write('${leading}width: $width'); + } + buffer.write(')'); + return buffer.toString(); + } +} + +/// An immutable representation of filling attributes for a [Paint]. +/// +/// See also [Paint.fill]. +@immutable +class Fill { + /// Creates a new immutable set of drawing attributes for a [Paint]. + const Fill({ + Color? color, + this.shader, + }) : color = color ?? Color.opaqueBlack; + + /// The color to use for this stroke. + /// + /// Defaults to [Color.opaqueBlack]. + /// + /// If [shader] is not null, only the opacity is used. + final Color color; + + /// The [Gradient] to use when filling. + final Gradient? shader; + + @override + int get hashCode => Object.hash(PaintingStyle.fill, color, shader); + + @override + bool operator ==(Object other) { + return other is Fill && other.color == color && other.shader == shader; + } + + @override + String toString() { + final StringBuffer buffer = StringBuffer('Fill(color: $color'); + const String leading = ', '; + + if (shader != null) { + buffer.write('${leading}shader: $shader'); + } + buffer.write(')'); + return buffer.toString(); + } +} + +/// The Porter-Duff algorithm to use for blending. +/// +/// The values in this enum are expected to match exactly the values of the +/// similarly named enum from dart:ui. They must not be removed even if they +/// are unused. +enum BlendMode { + // This list comes from Skia's SkXfermode.h and the values (order) should be + // kept in sync. + // See: https://skia.org/docs/user/api/skpaint_overview/#SkXfermode + + /// Drop both the source and destination images, leaving nothing. + /// + /// This corresponds to the "clear" Porter-Duff operator. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_clear.png) + clear, + + /// Drop the destination image, only paint the source image. + /// + /// Conceptually, the destination is first cleared, then the source image is + /// painted. + /// + /// This corresponds to the "Copy" Porter-Duff operator. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_src.png) + src, + + /// Drop the source image, only paint the destination image. + /// + /// Conceptually, the source image is discarded, leaving the destination + /// untouched. + /// + /// This corresponds to the "Destination" Porter-Duff operator. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_dst.png) + dst, + + /// Composite the source image over the destination image. + /// + /// This is the default value. It represents the most intuitive case, where + /// shapes are painted on top of what is below, with transparent areas showing + /// the destination layer. + /// + /// This corresponds to the "Source over Destination" Porter-Duff operator, + /// also known as the Painter's Algorithm. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_srcOver.png) + srcOver, + + /// Composite the source image under the destination image. + /// + /// This is the opposite of [srcOver]. + /// + /// This corresponds to the "Destination over Source" Porter-Duff operator. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_dstOver.png) + /// + /// This is useful when the source image should have been painted before the + /// destination image, but could not be. + dstOver, + + /// Show the source image, but only where the two images overlap. The + /// destination image is not rendered, it is treated merely as a mask. The + /// color channels of the destination are ignored, only the opacity has an + /// effect. + /// + /// To show the destination image instead, consider [dstIn]. + /// + /// To reverse the semantic of the mask (only showing the source where the + /// destination is absent, rather than where it is present), consider + /// [srcOut]. + /// + /// This corresponds to the "Source in Destination" Porter-Duff operator. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_srcIn.png) + srcIn, + + /// Show the destination image, but only where the two images overlap. The + /// source image is not rendered, it is treated merely as a mask. The color + /// channels of the source are ignored, only the opacity has an effect. + /// + /// To show the source image instead, consider [srcIn]. + /// + /// To reverse the semantic of the mask (only showing the source where the + /// destination is present, rather than where it is absent), consider [dstOut]. + /// + /// This corresponds to the "Destination in Source" Porter-Duff operator. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_dstIn.png) + dstIn, + + /// Show the source image, but only where the two images do not overlap. The + /// destination image is not rendered, it is treated merely as a mask. The color + /// channels of the destination are ignored, only the opacity has an effect. + /// + /// To show the destination image instead, consider [dstOut]. + /// + /// To reverse the semantic of the mask (only showing the source where the + /// destination is present, rather than where it is absent), consider [srcIn]. + /// + /// This corresponds to the "Source out Destination" Porter-Duff operator. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_srcOut.png) + srcOut, + + /// Show the destination image, but only where the two images do not overlap. The + /// source image is not rendered, it is treated merely as a mask. The color + /// channels of the source are ignored, only the opacity has an effect. + /// + /// To show the source image instead, consider [srcOut]. + /// + /// To reverse the semantic of the mask (only showing the destination where the + /// source is present, rather than where it is absent), consider [dstIn]. + /// + /// This corresponds to the "Destination out Source" Porter-Duff operator. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_dstOut.png) + dstOut, + + /// Composite the source image over the destination image, but only where it + /// overlaps the destination. + /// + /// This corresponds to the "Source atop Destination" Porter-Duff operator. + /// + /// This is essentially the [srcOver] operator, but with the output's opacity + /// channel being set to that of the destination image instead of being a + /// combination of both image's opacity channels. + /// + /// For a variant with the destination on top instead of the source, see + /// [dstATop]. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_srcATop.png) + srcATop, + + /// Composite the destination image over the source image, but only where it + /// overlaps the source. + /// + /// This corresponds to the "Destination atop Source" Porter-Duff operator. + /// + /// This is essentially the [dstOver] operator, but with the output's opacity + /// channel being set to that of the source image instead of being a + /// combination of both image's opacity channels. + /// + /// For a variant with the source on top instead of the destination, see + /// [srcATop]. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_dstATop.png) + dstATop, + + /// Apply a bitwise `xor` operator to the source and destination images. This + /// leaves transparency where they would overlap. + /// + /// This corresponds to the "Source xor Destination" Porter-Duff operator. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_xor.png) + xor, + + /// Sum the components of the source and destination images. + /// + /// Transparency in a pixel of one of the images reduces the contribution of + /// that image to the corresponding output pixel, as if the color of that + /// pixel in that image was darker. + /// + /// This corresponds to the "Source plus Destination" Porter-Duff operator. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_plus.png) + plus, + + /// Multiply the color components of the source and destination images. + /// + /// This can only result in the same or darker colors (multiplying by white, + /// 1.0, results in no change; multiplying by black, 0.0, results in black). + /// + /// When compositing two opaque images, this has similar effect to overlapping + /// two transparencies on a projector. + /// + /// For a variant that also multiplies the alpha channel, consider [multiply]. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_modulate.png) + /// + /// See also: + /// + /// * [screen], which does a similar computation but inverted. + /// * [overlay], which combines [modulate] and [screen] to favor the + /// destination image. + /// * [hardLight], which combines [modulate] and [screen] to favor the + /// source image. + modulate, + + // Following blend modes are defined in the CSS Compositing standard. + + /// Multiply the inverse of the components of the source and destination + /// images, and inverse the result. + /// + /// Inverting the components means that a fully saturated channel (opaque + /// white) is treated as the value 0.0, and values normally treated as 0.0 + /// (black, transparent) are treated as 1.0. + /// + /// This is essentially the same as [modulate] blend mode, but with the values + /// of the colors inverted before the multiplication and the result being + /// inverted back before rendering. + /// + /// This can only result in the same or lighter colors (multiplying by black, + /// 1.0, results in no change; multiplying by white, 0.0, results in white). + /// Similarly, in the alpha channel, it can only result in more opaque colors. + /// + /// This has similar effect to two projectors displaying their images on the + /// same screen simultaneously. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_screen.png) + /// + /// See also: + /// + /// * [modulate], which does a similar computation but without inverting the + /// values. + /// * [overlay], which combines [modulate] and [screen] to favor the + /// destination image. + /// * [hardLight], which combines [modulate] and [screen] to favor the + /// source image. + screen, // The last coeff mode. + + /// Multiply the components of the source and destination images after + /// adjusting them to favor the destination. + /// + /// Specifically, if the destination value is smaller, this multiplies it with + /// the source value, whereas is the source value is smaller, it multiplies + /// the inverse of the source value with the inverse of the destination value, + /// then inverts the result. + /// + /// Inverting the components means that a fully saturated channel (opaque + /// white) is treated as the value 0.0, and values normally treated as 0.0 + /// (black, transparent) are treated as 1.0. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_overlay.png) + /// + /// See also: + /// + /// * [modulate], which always multiplies the values. + /// * [screen], which always multiplies the inverses of the values. + /// * [hardLight], which is similar to [overlay] but favors the source image + /// instead of the destination image. + overlay, + + /// Composite the source and destination image by choosing the lowest value + /// from each color channel. + /// + /// The opacity of the output image is computed in the same way as for + /// [srcOver]. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_darken.png) + darken, + + /// Composite the source and destination image by choosing the highest value + /// from each color channel. + /// + /// The opacity of the output image is computed in the same way as for + /// [srcOver]. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_lighten.png) + lighten, + + /// Divide the destination by the inverse of the source. + /// + /// Inverting the components means that a fully saturated channel (opaque + /// white) is treated as the value 0.0, and values normally treated as 0.0 + /// (black, transparent) are treated as 1.0. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_colorDodge.png) + colorDodge, + + /// Divide the inverse of the destination by the source, and inverse the result. + /// + /// Inverting the components means that a fully saturated channel (opaque + /// white) is treated as the value 0.0, and values normally treated as 0.0 + /// (black, transparent) are treated as 1.0. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_colorBurn.png) + colorBurn, + + /// Multiply the components of the source and destination images after + /// adjusting them to favor the source. + /// + /// Specifically, if the source value is smaller, this multiplies it with the + /// destination value, whereas is the destination value is smaller, it + /// multiplies the inverse of the destination value with the inverse of the + /// source value, then inverts the result. + /// + /// Inverting the components means that a fully saturated channel (opaque + /// white) is treated as the value 0.0, and values normally treated as 0.0 + /// (black, transparent) are treated as 1.0. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_hardLight.png) + /// + /// See also: + /// + /// * [modulate], which always multiplies the values. + /// * [screen], which always multiplies the inverses of the values. + /// * [overlay], which is similar to [hardLight] but favors the destination + /// image instead of the source image. + hardLight, + + /// Use [colorDodge] for source values below 0.5 and [colorBurn] for source + /// values above 0.5. + /// + /// This results in a similar but softer effect than [overlay]. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_softLight.png) + /// + /// See also: + /// + /// * [color], which is a more subtle tinting effect. + softLight, + + /// Subtract the smaller value from the bigger value for each channel. + /// + /// Compositing black has no effect; compositing white inverts the colors of + /// the other image. + /// + /// The opacity of the output image is computed in the same way as for + /// [srcOver]. + /// + /// The effect is similar to [exclusion] but harsher. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_difference.png) + difference, + + /// Subtract double the product of the two images from the sum of the two + /// images. + /// + /// Compositing black has no effect; compositing white inverts the colors of + /// the other image. + /// + /// The opacity of the output image is computed in the same way as for + /// [srcOver]. + /// + /// The effect is similar to [difference] but softer. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_exclusion.png) + exclusion, + + /// Multiply the components of the source and destination images, including + /// the alpha channel. + /// + /// This can only result in the same or darker colors (multiplying by white, + /// 1.0, results in no change; multiplying by black, 0.0, results in black). + /// + /// Since the alpha channel is also multiplied, a fully-transparent pixel + /// (opacity 0.0) in one image results in a fully transparent pixel in the + /// output. This is similar to [dstIn], but with the colors combined. + /// + /// For a variant that multiplies the colors but does not multiply the alpha + /// channel, consider [modulate]. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_multiply.png) + multiply, // The last separable mode. + + /// Take the hue of the source image, and the saturation and luminosity of the + /// destination image. + /// + /// The effect is to tint the destination image with the source image. + /// + /// The opacity of the output image is computed in the same way as for + /// [srcOver]. Regions that are entirely transparent in the source image take + /// their hue from the destination. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_hue.png) + /// + /// See also: + /// + /// * [color], which is a similar but stronger effect as it also applies the + /// saturation of the source image. + /// * [HSVColor], which allows colors to be expressed using Hue rather than + /// the red/green/blue channels of [Color]. + hue, + + /// Take the saturation of the source image, and the hue and luminosity of the + /// destination image. + /// + /// The opacity of the output image is computed in the same way as for + /// [srcOver]. Regions that are entirely transparent in the source image take + /// their saturation from the destination. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_hue.png) + /// + /// See also: + /// + /// * [color], which also applies the hue of the source image. + /// * [luminosity], which applies the luminosity of the source image to the + /// destination. + saturation, + + /// Take the hue and saturation of the source image, and the luminosity of the + /// destination image. + /// + /// The effect is to tint the destination image with the source image. + /// + /// The opacity of the output image is computed in the same way as for + /// [srcOver]. Regions that are entirely transparent in the source image take + /// their hue and saturation from the destination. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_color.png) + /// + /// See also: + /// + /// * [hue], which is a similar but weaker effect. + /// * [softLight], which is a similar tinting effect but also tints white. + /// * [saturation], which only applies the saturation of the source image. + color, + + /// Take the luminosity of the source image, and the hue and saturation of the + /// destination image. + /// + /// The opacity of the output image is computed in the same way as for + /// [srcOver]. Regions that are entirely transparent in the source image take + /// their luminosity from the destination. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_luminosity.png) + /// + /// See also: + /// + /// * [saturation], which applies the saturation of the source image to the + /// destination. + /// * [ImageFilter.blur], which can be used with [BackdropFilter] for a + /// related effect. + luminosity, +} + +/// Strategies for painting shapes and paths on a canvas. +/// +/// See [Paint.style]. +// These enum values must be kept in sync with SkPaint::Style. +enum PaintingStyle { + // This list comes from Skia's SkPaint.h and the values (order) should be kept + // in sync. + + /// Apply the [Paint] to the inside of the shape. For example, when + /// applied to the [Canvas.drawCircle] call, this results in a disc + /// of the given size being painted. + fill, + + /// Apply the [Paint] to the edge of the shape. For example, when + /// applied to the [Canvas.drawCircle] call, this results is a hoop + /// of the given size being painted. The line drawn on the edge will + /// be the width given by the [Paint.width] property. + stroke, +} + +/// Styles to use for line endings. +/// +/// See also: +/// +/// * [Paint.strokeCap] for how this value is used. +/// * [StrokeJoin] for the different kinds of line segment joins. +// These enum values must be kept in sync with SkPaint::Cap. +enum StrokeCap { + /// Begin and end contours with a flat edge and no extension. + /// + /// ![A butt cap ends line segments with a square end that stops at the end of + /// the line segment.](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/butt_cap.png) + /// + /// Compare to the [square] cap, which has the same shape, but extends past + /// the end of the line by half a stroke width. + butt, + + /// Begin and end contours with a semi-circle extension. + /// + /// ![A round cap adds a rounded end to the line segment that protrudes + /// by one half of the thickness of the line (which is the radius of the cap) + /// past the end of the segment.](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/round_cap.png) + /// + /// The cap is colored in the diagram above to highlight it: in normal use it + /// is the same color as the line. + round, + + /// Begin and end contours with a half square extension. This is + /// similar to extending each contour by half the stroke width (as + /// given by [Paint.width]). + /// + /// ![A square cap has a square end that effectively extends the line length + /// by half of the stroke width.](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/square_cap.png) + /// + /// The cap is colored in the diagram above to highlight it: in normal use it + /// is the same color as the line. + /// + /// Compare to the [butt] cap, which has the same shape, but doesn't extend + /// past the end of the line. + square, +} + +/// Styles to use for line segment joins. +/// +/// This only affects line joins for polygons drawn by [Canvas.drawPath] and +/// rectangles, not points drawn as lines with [Canvas.drawPoints]. +/// +/// See also: +/// +/// * [Paint.join] and [Paint.miterLimit] for how this value is +/// used. +/// * [StrokeCap] for the different kinds of line endings. +// These enum values must be kept in sync with SkPaint::Join. +enum StrokeJoin { + /// Joins between line segments form sharp corners. + /// + /// {@animation 300 300 https://flutter.github.io/assets-for-api-docs/assets/dart-ui/miter_4_join.mp4} + /// + /// The center of the line segment is colored in the diagram above to + /// highlight the join, but in normal usage the join is the same color as the + /// line. + /// + /// See also: + /// + /// * [Paint.join], used to set the line segment join style to this + /// value. + /// * [Paint.miterLimit], used to define when a miter is drawn instead + /// of a bevel when the join is set to this value. + miter, + + /// Joins between line segments are semi-circular. + /// + /// {@animation 300 300 https://flutter.github.io/assets-for-api-docs/assets/dart-ui/round_join.mp4} + /// + /// The center of the line segment is colored in the diagram above to + /// highlight the join, but in normal usage the join is the same color as the + /// line. + /// + /// See also: + /// + /// * [Paint.join], used to set the line segment join style to this + /// value. + round, + + /// Joins between line segments connect the corners of the butt ends of the + /// line segments to give a beveled appearance. + /// + /// {@animation 300 300 https://flutter.github.io/assets-for-api-docs/assets/dart-ui/bevel_join.mp4} + /// + /// The center of the line segment is colored in the diagram above to + /// highlight the join, but in normal usage the join is the same color as the + /// line. + /// + /// See also: + /// + /// * [Paint.join], used to set the line segment join style to this + /// value. + bevel, +} + +/// Defines what happens at the edge of a gradient or the sampling of a source image +/// in an [ImageFilter]. +/// +/// A gradient is defined along a finite inner area. In the case of a linear +/// gradient, it's between the parallel lines that are orthogonal to the line +/// drawn between two points. In the case of radial gradients, it's the disc +/// that covers the circle centered on a particular point up to a given radius. +/// +/// An image filter reads source samples from a source image and performs operations +/// on those samples to produce a result image. An image defines color samples only +/// for pixels within the bounds of the image but some filter operations, such as a blur +/// filter, read samples over a wide area to compute the output for a given pixel. Such +/// a filter would need to combine samples from inside the image with hypothetical +/// color values from outside the image. +/// +/// This enum is used to define how the gradient or image filter should treat the regions +/// outside that defined inner area. +/// +/// See also: +/// +/// * [painting.Gradient], the superclass for [LinearGradient] and +/// [RadialGradient], as used by [BoxDecoration] et al, which works in +/// relative coordinates and can create a [Shader] representing the gradient +/// for a particular [Rect] on demand. +/// * [dart:ui.Gradient], the low-level class used when dealing with the +/// [Paint.shader] property directly, with its [Gradient.linear] and +/// [Gradient.radial] constructors. +/// * [dart:ui.ImageFilter.blur], an ImageFilter that may sometimes need to +/// read samples from outside an image to combine with the pixels near the +/// edge of the image. +// These enum values must be kept in sync with SkTileMode. +enum TileMode { + /// Samples beyond the edge are clamped to the nearest color in the defined inner area. + /// + /// A gradient will paint all the regions outside the inner area with the + /// color at the end of the color stop list closest to that region. + /// + /// An image filter will substitute the nearest edge pixel for any samples taken from + /// outside its source image. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/tile_mode_clamp_linear.png) + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/tile_mode_clamp_radial.png) + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/tile_mode_clamp_sweep.png) + clamp, + + /// Samples beyond the edge are repeated from the far end of the defined area. + /// + /// For a gradient, this technique is as if the stop points from 0.0 to 1.0 were then + /// repeated from 1.0 to 2.0, 2.0 to 3.0, and so forth (and for linear gradients, similarly + /// from -1.0 to 0.0, -2.0 to -1.0, etc). + /// + /// An image filter will treat its source image as if it were tiled across the enlarged + /// sample space from which it reads, each tile in the same orientation as the base image. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/tile_mode_repeated_linear.png) + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/tile_mode_repeated_radial.png) + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/tile_mode_repeated_sweep.png) + repeated, + + /// Samples beyond the edge are mirrored back and forth across the defined area. + /// + /// For a gradient, this technique is as if the stop points from 0.0 to 1.0 were then + /// repeated backwards from 2.0 to 1.0, then forwards from 2.0 to 3.0, then backwards + /// again from 4.0 to 3.0, and so forth (and for linear gradients, similarly in the + /// negative direction). + /// + /// An image filter will treat its source image as tiled in an alternating forwards and + /// backwards or upwards and downwards direction across the sample space from which + /// it is reading. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/tile_mode_mirror_linear.png) + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/tile_mode_mirror_radial.png) + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/tile_mode_mirror_sweep.png) + mirror, + + /// Samples beyond the edge are treated as transparent black. + /// + /// A gradient will render transparency over any region that is outside the circle of a + /// radial gradient or outside the parallel lines that define the inner area of a linear + /// gradient. + /// + /// An image filter will substitute transparent black for any sample it must read from + /// outside its source image. + /// + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/tile_mode_decal_linear.png) + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/tile_mode_decal_radial.png) + /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/tile_mode_decal_sweep.png) + decal, +} + +/// A description of how to update the current text position. +/// +/// If [reset] is true, this update discards the previous current text position. +/// Otherwise, it appends to the previous text position. +@immutable +class TextPosition { + /// See [TextPosition]. + const TextPosition({ + this.x, + this.y, + this.dx, + this.dy, + this.reset = false, + this.transform, + }); + + /// The horizontal axis coordinate for the current text position. + /// + /// If null, use the current text position accumulated since the last [reset], + /// or 0 if this represents a reset. + final double? x; + + /// The horizontal axis coordinate to add to the current text position. + /// + /// If null, use the current text position accumulated since the last [reset], + /// or 0 if this represents a reset. + final double? dx; + + /// The vertical axis coordinate for the current text position. + /// + /// If null, use the current text position accumulated since the last [reset], + /// or 0 if this represents a reset. + final double? y; + + /// The vertical axis coordinate to add to the current text position. + /// + /// If null, use the current text position accumulated since the last [reset], + /// or 0 if this represents a reset. + final double? dy; + + /// If true, reset the current text position using [x] and [y]. + final bool reset; + + /// A transform applied to the rendered font. + /// + /// If `null` this implies no transform. + final AffineMatrix? transform; + + @override + int get hashCode => Object.hash(x, y, dx, dy, reset, transform); + + @override + bool operator ==(Object other) { + return other is TextPosition && + other.x == x && + other.y == y && + other.dx == dx && + other.dy == dy && + other.reset == reset && + other.transform == transform; + } + + @override + String toString() { + final StringBuffer buffer = StringBuffer(); + buffer.write('TextPosition(reset: $reset'); + if (x != null) { + buffer.write(', x: $x'); + } + if (y != null) { + buffer.write(', y: $y'); + } + if (dx != null) { + buffer.write(', dx: $dx'); + } + if (dy != null) { + buffer.write(', dy: $dy'); + } + if (transform != null) { + buffer.write(', transform: $transform'); + } + buffer.write(')'); + return buffer.toString(); + } +} + +/// Additional text specific configuration that is added to the encoding. +@immutable +class TextConfig { + /// Create a new [TextStyle] object. + const TextConfig( + this.text, + this.xAnchorMultiplier, + this.fontFamily, + this.fontWeight, + this.fontSize, + this.decoration, + this.decorationStyle, + this.decorationColor, + ); + + /// The text to be rendered. + final String text; + + /// A multiplier for text anchoring. + /// + /// This value should be multiplied by the length of the longest line in the + /// text and subtracted from x coordinate of the current [TextPosition]. + final double xAnchorMultiplier; + + /// The size of the font, only supported as absolute size. + final double fontSize; + + /// The name of the font family to select for rendering. + final String? fontFamily; + + /// The font weight, converted to a weight constant. + final FontWeight fontWeight; + + /// The decoration to apply to the text. + final TextDecoration decoration; + + /// The decoration style to apply to the text. + final TextDecorationStyle decorationStyle; + + /// The color to use for the decoration, if any. + final Color decorationColor; + + @override + int get hashCode => Object.hash( + text, + xAnchorMultiplier, + fontSize, + fontFamily, + fontWeight, + decoration, + decorationStyle, + decorationColor, + ); + + @override + bool operator ==(Object other) { + return other is TextConfig && + other.text == text && + other.xAnchorMultiplier == xAnchorMultiplier && + other.fontSize == fontSize && + other.fontFamily == fontFamily && + other.fontWeight == fontWeight && + other.decoration == decoration && + other.decorationStyle == decorationStyle && + other.decorationColor == decorationColor; + } + + @override + String toString() { + return 'TextConfig(' + "'$text', " + '$xAnchorMultiplier, ' + "'$fontFamily', " + '$fontWeight, ' + '$fontSize, ' + '$decoration, ' + '$decorationStyle, ' + '$decorationColor,)'; + } +} + +/// The value of the font weight. +/// +/// This matches the enum values defined in dart:ui. +enum FontWeight { + /// A font weight of 100, + w100, + + /// A font weight of 200, + w200, + + /// A font weight of 300, + w300, + + /// A font weight of 400, + w400, + + /// A font weight of 500, + w500, + + /// A font weight of 600, + w600, + + /// A font weight of 700, + w700, + + /// A font weight of 800, + w800, + + /// A font weight of 900, + w900, +} + +/// The style in which to draw a text decoration +/// +/// This matches the enum values defined in dart:ui. +enum TextDecorationStyle { + /// Draw a solid line + solid, + + /// Draw two lines + double, + + /// Draw a dotted line + dotted, + + /// Draw a dashed line + dashed, + + /// Draw a sinusoidal line + wavy +} + +/// A linear decoration to draw near the text. +/// +/// This matches the enum values defined in dart:ui. +@immutable +class TextDecoration { + const TextDecoration._(this.mask); + + /// Creates a decoration that paints the union of all the given decorations. + factory TextDecoration.combine(List decorations) { + int mask = 0; + for (final TextDecoration decoration in decorations) { + mask |= decoration.mask; + } + return TextDecoration._(mask); + } + + /// The raw mask for serialization. + final int mask; + + /// Whether this decoration will paint at least as much decoration as the given decoration. + bool contains(TextDecoration other) { + return (mask | other.mask) == mask; + } + + /// Do not draw a decoration + static const TextDecoration none = TextDecoration._(kNoTextDecorationMask); + + /// Draw a line underneath each line of text + static const TextDecoration underline = TextDecoration._(kUnderlineMask); + + /// Draw a line above each line of text + static const TextDecoration overline = TextDecoration._(kOverlineMask); + + /// Draw a line through each line of text + static const TextDecoration lineThrough = TextDecoration._(kLineThroughMask); + + @override + bool operator ==(Object other) { + return other is TextDecoration && other.mask == mask; + } + + @override + int get hashCode => mask.hashCode; + + @override + String toString() { + if (mask == 0) { + return 'TextDecoration.none'; + } + final List values = []; + if (mask & underline.mask != 0) { + values.add('underline'); + } + if (mask & overline.mask != 0) { + values.add('overline'); + } + if (mask & lineThrough.mask != 0) { + values.add('lineThrough'); + } + if (values.length == 1) { + return 'TextDecoration.${values[0]}'; + } + return 'TextDecoration.combine([${values.join(", ")}])'; + } +} + +/// The default font weight. +const FontWeight normalFontWeight = FontWeight.w400; + +/// A commonly used font weight that is heavier than normal. +const FontWeight boldFontWeight = FontWeight.w700; diff --git a/packages/vector_graphics_compiler/lib/src/svg/_path_ops_ffi.dart b/packages/vector_graphics_compiler/lib/src/svg/_path_ops_ffi.dart new file mode 100644 index 000000000000..fd1eb3bed3e1 --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/svg/_path_ops_ffi.dart @@ -0,0 +1,301 @@ +// 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: camel_case_types +import 'dart:ffi' as ffi; +import 'dart:typed_data'; + +import 'path_ops.dart'; + +// TODO(dnfield): Figure out where to put this. +// https://github.com/flutter/flutter/issues/99563 +final ffi.DynamicLibrary _dylib = ffi.DynamicLibrary.open(_dylibPath); +late final String _dylibPath; + +/// Creates a path object to operate on. +/// +/// First, build up the path contours with the [moveTo], [lineTo], [cubicTo], +/// and [close] methods. All methods expect absolute coordinates. +/// +/// Finally, use the [dispose] method to clean up native resources. After +/// [dispose] has been called, this class must not be used again. +class Path implements PathProxy { + /// Creates an empty path object with the specified fill type. + Path([FillType fillType = FillType.nonZero]) + : _path = _createPathFn(fillType.index); + + /// Creates a copy of this path. + factory Path.from(Path other) { + final Path result = Path(other.fillType); + other.replay(result); + return result; + } + + /// The [FillType] of this path. + FillType get fillType { + assert(_path != null); + return FillType.values[_getFillTypeFn(_path!)]; + } + + ffi.Pointer<_SkPath>? _path; + ffi.Pointer<_PathData>? _pathData; + + /// The number of points used by each [PathVerb]. + static const Map pointsPerVerb = { + PathVerb.moveTo: 2, + PathVerb.lineTo: 2, + PathVerb.cubicTo: 6, + PathVerb.close: 0, + }; + + /// Makes the appropriate calls using [verbs] and [points] to replay this path + /// on [proxy]. + /// + /// Calls [PathProxy.reset] first if [reset] is true. + void replay(PathProxy proxy, {bool reset = true}) { + if (reset) { + proxy.reset(); + } + int index = 0; + for (final PathVerb verb in verbs.toList()) { + switch (verb) { + case PathVerb.moveTo: + proxy.moveTo(points[index++], points[index++]); + case PathVerb.lineTo: + proxy.lineTo(points[index++], points[index++]); + case PathVerb.quadTo: + // TODO(dnfield): Avoid degree elevation? + // The binary format only supports cubics. Skia might have + // used a quad when combining paths somewhere though. + final double cpX = points[index++]; + final double cpY = points[index++]; + proxy.cubicTo( + cpX, + cpY, + cpX, + cpY, + points[index++], + points[index++], + ); + case PathVerb.cubicTo: + proxy.cubicTo( + points[index++], + points[index++], + points[index++], + points[index++], + points[index++], + points[index++], + ); + case PathVerb.close: + proxy.close(); + } + } + assert(index == points.length); + } + + /// The list of path verbs in this path. + /// + /// This may not match the verbs supplied by calls to [moveTo], [lineTo], + /// [cubicTo], and [close] after [applyOp] is invoked. + /// + /// This list determines the meaning of the [points] array. + + static const Map pathVerbDict = { + 0: PathVerb.moveTo, + 1: PathVerb.lineTo, + 2: PathVerb.quadTo, + 4: PathVerb.cubicTo, + 5: PathVerb.close + }; + + /// Retrieves PathVerbs. + Iterable get verbs { + _updatePathData(); + final int count = _pathData!.ref.verbCount; + return List.generate(count, (int index) { + return pathVerbDict[_pathData!.ref.verbs[index]]!; + }, growable: false); + } + + /// The list of points to use with [verbs]. + /// + /// Each verb uses a specific number of points, specified by the + /// [pointsPerVerb] map. + Float32List get points { + _updatePathData(); + return _pathData!.ref.points.asTypedList(_pathData!.ref.pointCount); + } + + void _updatePathData() { + assert(_path != null); + _pathData ??= _dataFn(_path!); + } + + void _resetPathData() { + if (_pathData != null) { + _destroyDataFn(_pathData!); + } + _pathData = null; + } + + @override + void moveTo(double x, double y) { + assert(_path != null); + _resetPathData(); + _moveToFn(_path!, x, y); + } + + @override + void lineTo(double x, double y) { + assert(_path != null); + _resetPathData(); + _lineToFn(_path!, x, y); + } + + @override + void cubicTo( + double x1, + double y1, + double x2, + double y2, + double x3, + double y3, + ) { + assert(_path != null); + _resetPathData(); + _cubicToFn(_path!, x1, y1, x2, y2, x3, y3); + } + + @override + void close() { + assert(_path != null); + _resetPathData(); + _closeFn(_path!, true); + } + + @override + void reset() { + assert(_path != null); + _resetPathData(); + _resetFn(_path!); + } + + /// Releases native resources. + /// + /// After calling dispose, this class must not be used again. + void dispose() { + assert(_path != null); + _resetPathData(); + _destroyFn(_path!); + _path = null; + } + + /// Applies the operation described by [op] to this path using [other]. + Path applyOp(Path other, PathOp op) { + assert(_path != null); + assert(other._path != null); + final Path result = Path.from(this); + _opFn(result._path!, other._path!, op.index); + return result; + } +} + +/// Whether or not PathOps should be used. +bool get isPathOpsInitialized => _isPathOpsInitialized; +bool _isPathOpsInitialized = false; + +/// Initialize the libpathops dynamic library. +void initializeLibPathOps(String path) { + _dylibPath = path; + _isPathOpsInitialized = true; +} + +base class _SkPath extends ffi.Opaque {} + +base class _PathData extends ffi.Struct { + external ffi.Pointer verbs; + + @ffi.Size() + external int verbCount; + + external ffi.Pointer points; + + @ffi.Size() + external int pointCount; +} + +typedef _CreatePathType = ffi.Pointer<_SkPath> Function(int); +typedef _create_path_type = ffi.Pointer<_SkPath> Function(ffi.Int); + +final _CreatePathType _createPathFn = + _dylib.lookupFunction<_create_path_type, _CreatePathType>( + 'CreatePath', +); + +typedef _MoveToType = void Function(ffi.Pointer<_SkPath>, double, double); +typedef _move_to_type = ffi.Void Function( + ffi.Pointer<_SkPath>, ffi.Float, ffi.Float); + +final _MoveToType _moveToFn = _dylib.lookupFunction<_move_to_type, _MoveToType>( + 'MoveTo', +); + +typedef _LineToType = void Function(ffi.Pointer<_SkPath>, double, double); +typedef _line_to_type = ffi.Void Function( + ffi.Pointer<_SkPath>, ffi.Float, ffi.Float); + +final _LineToType _lineToFn = _dylib.lookupFunction<_line_to_type, _LineToType>( + 'LineTo', +); + +typedef _CubicToType = void Function( + ffi.Pointer<_SkPath>, double, double, double, double, double, double); +typedef _cubic_to_type = ffi.Void Function(ffi.Pointer<_SkPath>, ffi.Float, + ffi.Float, ffi.Float, ffi.Float, ffi.Float, ffi.Float); + +final _CubicToType _cubicToFn = + _dylib.lookupFunction<_cubic_to_type, _CubicToType>('CubicTo'); + +typedef _CloseType = void Function(ffi.Pointer<_SkPath>, bool); +typedef _close_type = ffi.Void Function(ffi.Pointer<_SkPath>, ffi.Bool); + +final _CloseType _closeFn = + _dylib.lookupFunction<_close_type, _CloseType>('Close'); + +typedef _ResetType = void Function(ffi.Pointer<_SkPath>); +typedef _reset_type = ffi.Void Function(ffi.Pointer<_SkPath>); + +final _ResetType _resetFn = + _dylib.lookupFunction<_reset_type, _ResetType>('Reset'); + +typedef _DestroyType = void Function(ffi.Pointer<_SkPath>); +typedef _destroy_type = ffi.Void Function(ffi.Pointer<_SkPath>); + +final _DestroyType _destroyFn = + _dylib.lookupFunction<_destroy_type, _DestroyType>('DestroyPath'); + +typedef _OpType = void Function( + ffi.Pointer<_SkPath>, ffi.Pointer<_SkPath>, int); +typedef _op_type = ffi.Void Function( + ffi.Pointer<_SkPath>, ffi.Pointer<_SkPath>, ffi.Int); + +final _OpType _opFn = _dylib.lookupFunction<_op_type, _OpType>('Op'); + +typedef _PathDataType = ffi.Pointer<_PathData> Function(ffi.Pointer<_SkPath>); +typedef _path_data_type = ffi.Pointer<_PathData> Function(ffi.Pointer<_SkPath>); + +final _PathDataType _dataFn = + _dylib.lookupFunction<_path_data_type, _PathDataType>('Data'); + +typedef _DestroyDataType = void Function(ffi.Pointer<_PathData>); +typedef _destroy_data_type = ffi.Void Function(ffi.Pointer<_PathData>); + +final _DestroyDataType _destroyDataFn = + _dylib.lookupFunction<_destroy_data_type, _DestroyDataType>('DestroyData'); + +typedef _GetFillTypeType = int Function(ffi.Pointer<_SkPath>); +typedef _get_fill_type_type = ffi.Int32 Function(ffi.Pointer<_SkPath>); + +final _GetFillTypeType _getFillTypeFn = + _dylib.lookupFunction<_get_fill_type_type, _GetFillTypeType>('GetFillType'); diff --git a/packages/vector_graphics_compiler/lib/src/svg/_path_ops_unsupported.dart b/packages/vector_graphics_compiler/lib/src/svg/_path_ops_unsupported.dart new file mode 100644 index 000000000000..773c9425fcf9 --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/svg/_path_ops_unsupported.dart @@ -0,0 +1,88 @@ +// 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:typed_data'; + +import 'path_ops.dart'; + +/// Whether or not tesselation should be used. +bool get isPathOpsInitialized => false; + +/// Initialize the libpathops dynamic library. +void initializeLibPathOps(String path) {} + +/// Creates a path object to operate on. +class Path implements PathProxy { + /// Creates an empty path object with the specified fill type. + Path([this.fillType = FillType.nonZero]); + + /// Creates a copy of this path. + factory Path.from(Path other) { + final Path result = Path(other.fillType); + other.replay(result); + return result; + } + + /// The [FillType] of this path. + final FillType fillType; + + /// Makes the appropriate calls using [verbs] and [points] to replay this path + /// on [proxy]. + /// + /// Calls [PathProxy.reset] first if [reset] is true. + void replay(PathProxy proxy, {bool reset = true}) { + throw UnsupportedError('PathOps not supported on the web'); + } + + @override + void close() { + throw UnsupportedError('PathOps not supported on the web'); + } + + @override + void cubicTo( + double x1, double y1, double x2, double y2, double x3, double y3) { + throw UnsupportedError('PathOps not supported on the web'); + } + + @override + void lineTo(double x, double y) { + throw UnsupportedError('PathOps not supported on the web'); + } + + @override + void moveTo(double x, double y) { + throw UnsupportedError('PathOps not supported on the web'); + } + + @override + void reset() { + throw UnsupportedError('PathOps not supported on the web'); + } + + /// Applies the operation described by [op] to this path using [other]. + Path applyOp(Path other, PathOp op) { + throw UnsupportedError('PathOps not supported on the web'); + } + + /// Retrieves PathVerbs. + Iterable get verbs { + throw UnsupportedError('PathOps not supported on the web'); + } + + /// The list of points to use with [verbs]. + /// + /// Each verb uses a specific number of points, specified by the + /// [pointsPerVerb] map. + Float32List get points { + throw UnsupportedError('PathOps not supported on the web'); + } + + /// Releases native resources. + /// + /// After calling dispose, this class must not be used again. + void dispose() { + throw UnsupportedError('PathOps not supported on the web'); + } +} diff --git a/packages/vector_graphics_compiler/lib/src/svg/_tessellator_ffi.dart b/packages/vector_graphics_compiler/lib/src/svg/_tessellator_ffi.dart new file mode 100644 index 000000000000..4850e020a3de --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/svg/_tessellator_ffi.dart @@ -0,0 +1,367 @@ +// 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: camel_case_types +import 'dart:ffi' as ffi; +import 'dart:typed_data'; + +import '../geometry/path.dart'; +import '../geometry/vertices.dart'; +import '../paint.dart'; +import 'node.dart'; +import 'parser.dart'; +import 'resolver.dart'; +import 'tessellator.dart' as api; +import 'visitor.dart'; + +// TODO(dnfield): Figure out where to put this. +// https://github.com/flutter/flutter/issues/99563 +final ffi.DynamicLibrary _dylib = ffi.DynamicLibrary.open(_dylibPath); +late final String _dylibPath; + +/// Whether or not tesselation should be used. +bool get isTesselatorInitialized => _isTesselatorInitialized; +bool _isTesselatorInitialized = false; + +/// Initialize the libtesselator dynamic library. +/// +/// This method must be called before [VerticesBuilder] can be used or +/// constructed. +void initializeLibTesselator(String path) { + _dylibPath = path; + _isTesselatorInitialized = true; +} + +/// A visitor that replaces fill paths with tesselated vertices. +class Tessellator extends Visitor + with ErrorOnUnResolvedNode + implements api.Tessellator { + @override + Node visitEmptyNode(Node node, void data) { + return node; + } + + @override + Node visitParentNode(ParentNode parentNode, void data) { + return ParentNode(SvgAttributes.empty, children: [ + for (final Node child in parentNode.children) child.accept(this, data) + ]); + } + + @override + Node visitResolvedClipNode(ResolvedClipNode clipNode, void data) { + return ResolvedClipNode( + clips: clipNode.clips, + child: clipNode.child.accept(this, data), + ); + } + + @override + Node visitResolvedMaskNode(ResolvedMaskNode maskNode, void data) { + return ResolvedMaskNode( + child: maskNode.child.accept(this, data), + mask: maskNode.mask, + blendMode: maskNode.blendMode, + ); + } + + @override + Node visitResolvedTextPositionNode( + ResolvedTextPositionNode textPositionNode, void data) { + return ResolvedTextPositionNode( + textPositionNode.textPosition, + [ + for (final Node child in textPositionNode.children) + child.accept(this, data) + ], + ); + } + + @override + Node visitResolvedPath(ResolvedPathNode pathNode, void data) { + final Fill? fill = pathNode.paint.fill; + final Stroke? stroke = pathNode.paint.stroke; + if (fill == null && stroke != null) { + return pathNode; + } + + final List children = []; + if (fill != null) { + final VerticesBuilder builder = VerticesBuilder(); + for (final PathCommand command in pathNode.path.commands) { + switch (command.type) { + case PathCommandType.move: + final MoveToCommand move = command as MoveToCommand; + builder.moveTo(move.x, move.y); + case PathCommandType.line: + final LineToCommand line = command as LineToCommand; + builder.lineTo(line.x, line.y); + case PathCommandType.cubic: + final CubicToCommand cubic = command as CubicToCommand; + builder.cubicTo( + cubic.x1, + cubic.y1, + cubic.x2, + cubic.y2, + cubic.x3, + cubic.y3, + ); + case PathCommandType.close: + builder.close(); + } + } + final Float32List rawVertices = builder.tessellate( + fillType: pathNode.path.fillType, + ); + if (rawVertices.isNotEmpty) { + final Vertices vertices = Vertices.fromFloat32List(rawVertices); + final IndexedVertices indexedVertices = vertices.createIndex(); + children.add(ResolvedVerticesNode( + paint: Paint(blendMode: pathNode.paint.blendMode, fill: fill), + vertices: indexedVertices, + bounds: pathNode.bounds, + )); + } + } + if (stroke != null) { + children.add(ResolvedPathNode( + paint: Paint( + blendMode: pathNode.paint.blendMode, + stroke: stroke, + ), + bounds: pathNode.bounds, + path: pathNode.path)); + } + if (children.isEmpty) { + return Node.empty; + } + if (children.length > 1) { + return ParentNode(SvgAttributes.empty, children: children); + } + return children[0]; + } + + @override + Node visitResolvedText(ResolvedTextNode textNode, void data) { + return textNode; + } + + @override + Node visitSaveLayerNode(SaveLayerNode layerNode, void data) { + return SaveLayerNode(SvgAttributes.empty, + paint: layerNode.paint, + children: [ + for (final Node child in layerNode.children) child.accept(this, data), + ]); + } + + @override + Node visitViewportNode(ViewportNode viewportNode, void data) { + return ViewportNode( + SvgAttributes.empty, + width: viewportNode.width, + height: viewportNode.height, + transform: viewportNode.transform, + children: [ + for (final Node child in viewportNode.children) + child.accept(this, data), + ], + ); + } + + @override + Node visitResolvedVerticesNode(ResolvedVerticesNode verticesNode, void data) { + return verticesNode; + } + + @override + Node visitResolvedImageNode(ResolvedImageNode resolvedImageNode, void data) { + return resolvedImageNode; + } + + @override + Node visitResolvedPatternNode(ResolvedPatternNode patternNode, void data) { + return patternNode; + } +} + +/// Creates vertices from path commands. +/// +/// First, build up the path contours with the [moveTo], [lineTo], [cubicTo], +/// and [close] methods. All methods expect absolute coordinates. +/// +/// Then, use the [tessellate] method to create a [Float32List] of vertex pairs. +/// +/// Finally, use the [dispose] method to clean up native resources. After +/// [dispose] has been called, this class must not be used again. +class VerticesBuilder { + /// Create a new [VerticesBuilder]. + VerticesBuilder() : _builder = _createPathFn(); + + ffi.Pointer<_PathBuilder>? _builder; + final List> _vertices = >[]; + + /// Adds a move verb to the absolute coordinates x,y. + void moveTo(double x, double y) { + assert(_builder != null); + _moveToFn(_builder!, x, y); + } + + /// Adds a line verb to the absolute coordinates x,y. + void lineTo(double x, double y) { + assert(_builder != null); + _lineToFn(_builder!, x, y); + } + + /// Adds a cubic Bezier curve with x1,y1 as the first control point, x2,y2 as + /// the second control point, and end point x3,y3. + void cubicTo( + double x1, + double y1, + double x2, + double y2, + double x3, + double y3, + ) { + assert(_builder != null); + _cubicToFn(_builder!, x1, y1, x2, y2, x3, y3); + } + + /// Adds a close command to the start of the current contour. + void close() { + assert(_builder != null); + _closeFn(_builder!, true); + } + + /// Tessellates the path created by the previous method calls into a list of + /// vertices. + Float32List tessellate({ + PathFillType fillType = PathFillType.nonZero, + api.SmoothingApproximation smoothing = const api.SmoothingApproximation(), + }) { + assert(_vertices.isEmpty); + assert(_builder != null); + final ffi.Pointer<_Vertices> vertices = _tessellateFn( + _builder!, + fillType.index, + smoothing.scale, + smoothing.angleTolerance, + smoothing.cuspLimit, + ); + _vertices.add(vertices); + return vertices.ref.points.asTypedList(vertices.ref.size); + } + + /// Releases native resources. + /// + /// After calling dispose, this class must not be used again. + void dispose() { + assert(_builder != null); + _vertices.forEach(_destroyVerticesFn); + _destroyFn(_builder!); + _vertices.clear(); + _builder = null; + } +} + +base class _Vertices extends ffi.Struct { + external ffi.Pointer points; + + @ffi.Uint32() + external int size; +} + +base class _PathBuilder extends ffi.Opaque {} + +typedef _CreatePathBuilderType = ffi.Pointer<_PathBuilder> Function(); +typedef _create_path_builder_type = ffi.Pointer<_PathBuilder> Function(); + +final _CreatePathBuilderType _createPathFn = + _dylib.lookupFunction<_create_path_builder_type, _CreatePathBuilderType>( + 'CreatePathBuilder', +); + +typedef _MoveToType = void Function(ffi.Pointer<_PathBuilder>, double, double); +typedef _move_to_type = ffi.Void Function( + ffi.Pointer<_PathBuilder>, + ffi.Float, + ffi.Float, +); + +final _MoveToType _moveToFn = _dylib.lookupFunction<_move_to_type, _MoveToType>( + 'MoveTo', +); + +typedef _LineToType = void Function(ffi.Pointer<_PathBuilder>, double, double); +typedef _line_to_type = ffi.Void Function( + ffi.Pointer<_PathBuilder>, + ffi.Float, + ffi.Float, +); + +final _LineToType _lineToFn = _dylib.lookupFunction<_line_to_type, _LineToType>( + 'LineTo', +); + +typedef _CubicToType = void Function( + ffi.Pointer<_PathBuilder>, + double, + double, + double, + double, + double, + double, +); +typedef _cubic_to_type = ffi.Void Function( + ffi.Pointer<_PathBuilder>, + ffi.Float, + ffi.Float, + ffi.Float, + ffi.Float, + ffi.Float, + ffi.Float, +); + +final _CubicToType _cubicToFn = + _dylib.lookupFunction<_cubic_to_type, _CubicToType>('CubicTo'); + +typedef _CloseType = void Function(ffi.Pointer<_PathBuilder>, bool); +typedef _close_type = ffi.Void Function(ffi.Pointer<_PathBuilder>, ffi.Bool); + +final _CloseType _closeFn = + _dylib.lookupFunction<_close_type, _CloseType>('Close'); + +typedef _TessellateType = ffi.Pointer<_Vertices> Function( + ffi.Pointer<_PathBuilder>, + int, + double, + double, + double, +); +typedef _tessellate_type = ffi.Pointer<_Vertices> Function( + ffi.Pointer<_PathBuilder>, + ffi.Int, + ffi.Float, + ffi.Float, + ffi.Float, +); + +final _TessellateType _tessellateFn = + _dylib.lookupFunction<_tessellate_type, _TessellateType>('Tessellate'); + +typedef _DestroyType = void Function(ffi.Pointer<_PathBuilder>); +typedef _destroy_type = ffi.Void Function(ffi.Pointer<_PathBuilder>); + +final _DestroyType _destroyFn = + _dylib.lookupFunction<_destroy_type, _DestroyType>( + 'DestroyPathBuilder', +); + +typedef _DestroyVerticesType = void Function(ffi.Pointer<_Vertices>); +typedef _destroy_vertices_type = ffi.Void Function(ffi.Pointer<_Vertices>); + +final _DestroyVerticesType _destroyVerticesFn = + _dylib.lookupFunction<_destroy_vertices_type, _DestroyVerticesType>( + 'DestroyVertices', +); diff --git a/packages/vector_graphics_compiler/lib/src/svg/_tessellator_unsupported.dart b/packages/vector_graphics_compiler/lib/src/svg/_tessellator_unsupported.dart new file mode 100644 index 000000000000..cfee6dede511 --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/svg/_tessellator_unsupported.dart @@ -0,0 +1,83 @@ +// 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 'node.dart'; +import 'resolver.dart'; +import 'tessellator.dart' as api; +import 'visitor.dart'; + +/// Whether or not tesselation should be used. +bool get isTesselatorInitialized => false; + +/// Initialize the libtesselator dynamic library. +/// +/// This method must be called before [VerticesBuilder] can be used or +/// constructed. +void initializeLibTesselator(String path) {} + +/// A visitor that replaces fill paths with tesselated vertices. +class Tessellator extends Visitor + with ErrorOnUnResolvedNode + implements api.Tessellator { + @override + Node visitEmptyNode(Node node, void data) { + return node; + } + + @override + Node visitParentNode(ParentNode parentNode, void data) { + return parentNode; + } + + @override + Node visitResolvedClipNode(ResolvedClipNode clipNode, void data) { + return clipNode; + } + + @override + Node visitResolvedMaskNode(ResolvedMaskNode maskNode, void data) { + return maskNode; + } + + @override + Node visitResolvedPath(ResolvedPathNode pathNode, void data) { + return pathNode; + } + + @override + Node visitResolvedText(ResolvedTextNode textNode, void data) { + return textNode; + } + + @override + Node visitSaveLayerNode(SaveLayerNode layerNode, void data) { + return layerNode; + } + + @override + Node visitViewportNode(ViewportNode viewportNode, void data) { + return viewportNode; + } + + @override + Node visitResolvedVerticesNode(ResolvedVerticesNode verticesNode, void data) { + return verticesNode; + } + + @override + Node visitResolvedImageNode(ResolvedImageNode resolvedImageNode, void data) { + return resolvedImageNode; + } + + @override + Node visitResolvedPatternNode(ResolvedPatternNode patternNode, void data) { + return patternNode; + } + + @override + Node visitResolvedTextPositionNode( + ResolvedTextPositionNode textPositionNode, void data) { + return textPositionNode; + } +} diff --git a/packages/vector_graphics_compiler/lib/src/svg/clipping_optimizer.dart b/packages/vector_graphics_compiler/lib/src/svg/clipping_optimizer.dart new file mode 100644 index 000000000000..de827466f2f3 --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/svg/clipping_optimizer.dart @@ -0,0 +1,269 @@ +// 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 '../../vector_graphics_compiler.dart'; +import 'masking_optimizer.dart'; +import 'node.dart'; +import 'path_ops.dart' as path_ops; +import 'visitor.dart'; + +class _Result { + _Result(this.node); + + final Node node; + int childCount = 0; + List children = []; + Node parent = Node.empty; + bool deleteClipNode = true; +} + +/// Applies and removes trivial cases of clipping. +/// This will not optimize cases where 'stroke-width' is set, +/// there are multiple path nodes in ResolvedClipNode.clips +/// or cases where the intersection of the clip and the path +/// results in Path.commands being empty. +class ClippingOptimizer extends Visitor<_Result, Node> + with ErrorOnUnResolvedNode<_Result, Node> { + ///List of clips to apply. + final List clipsToApply = []; + + /// Applies visitor to given node. + Node apply(Node node) { + final Node newNode = node.accept(this, null).node; + return newNode; + } + + /// Applies clip to a path node, and returns resulting path node. + ResolvedPathNode applyClip(Node child, Path clipPath) { + final ResolvedPathNode pathNode = child as ResolvedPathNode; + final path_ops.Path clipPathOpsPath = toPathOpsPath(clipPath); + final path_ops.Path pathPathOpsPath = toPathOpsPath(pathNode.path); + final path_ops.Path intersection = + clipPathOpsPath.applyOp(pathPathOpsPath, path_ops.PathOp.intersect); + final Path newPath = toVectorGraphicsPath(intersection); + final ResolvedPathNode newPathNode = ResolvedPathNode( + paint: pathNode.paint, bounds: newPath.bounds(), path: newPath); + + clipPathOpsPath.dispose(); + pathPathOpsPath.dispose(); + intersection.dispose(); + + return newPathNode; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitEmptyNode(Node node, void data) { + final _Result result = _Result(node); + return result; + } + + /// Visits applies optimizer to all children of ResolvedClipNode. + // ignore: library_private_types_in_public_api + _Result visitChildren(Node node, _Result data) { + if (node is ResolvedClipNode) { + data = node.child.accept(this, data); + } + return data; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitParentNode(ParentNode parentNode, Node data) { + final List newChildren = []; + bool deleteClipNode = true; + + for (final Node child in parentNode.children) { + final _Result childResult = child.accept(this, parentNode); + newChildren.add(childResult.node); + if (!childResult.deleteClipNode) { + deleteClipNode = false; + } + } + + final ParentNode newParentNode = ParentNode(parentNode.attributes, + precalculatedTransform: parentNode.transform, children: newChildren); + + final _Result result = _Result(newParentNode); + + result.deleteClipNode = deleteClipNode; + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitMaskNode(MaskNode maskNode, Node data) { + final _Result result = _Result(maskNode); + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitPathNode(PathNode pathNode, Node data) { + final _Result result = _Result(pathNode); + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitResolvedMaskNode(ResolvedMaskNode maskNode, void data) { + final _Result childResult = maskNode.child.accept(this, maskNode); + final ResolvedMaskNode newMaskNode = ResolvedMaskNode( + child: childResult.node, + mask: maskNode.mask, + blendMode: maskNode.blendMode); + final _Result result = _Result(newMaskNode); + result.children.add(childResult.node); + result.childCount = 1; + + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitResolvedClipNode(ResolvedClipNode clipNode, Node data) { + _Result result = _Result(clipNode); + + Path? singleClipPath; + if (clipNode.clips.length == 1) { + singleClipPath = clipNode.clips.single; + } + + if (singleClipPath != null) { + clipsToApply.add(singleClipPath); + final _Result childResult = clipNode.child.accept(this, clipNode); + clipsToApply.removeLast(); + + if (childResult.deleteClipNode) { + result = _Result(childResult.node); + } else { + final ResolvedClipNode newClipNode = + ResolvedClipNode(child: childResult.node, clips: clipNode.clips); + result = _Result(newClipNode); + } + } else { + final _Result childResult = clipNode.child.accept(this, clipNode); + final ResolvedClipNode newClipNode = + ResolvedClipNode(child: childResult.node, clips: clipNode.clips); + result = _Result(newClipNode); + } + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitResolvedPath(ResolvedPathNode pathNode, Node data) { + _Result result = _Result(pathNode); + bool hasStrokeWidth = false; + bool deleteClipNode = true; + + if (pathNode.paint.stroke?.width != null) { + hasStrokeWidth = true; + result.deleteClipNode = false; + } + + if (clipsToApply.isNotEmpty && !hasStrokeWidth) { + ResolvedPathNode newPathNode = pathNode; + for (final Path clipPath in clipsToApply) { + final ResolvedPathNode intersection = applyClip(newPathNode, clipPath); + if (intersection.path.commands.isNotEmpty) { + newPathNode = intersection; + } else { + result = _Result(pathNode); + result.deleteClipNode = false; + deleteClipNode = false; + break; + } + } + result = _Result(newPathNode); + result.deleteClipNode = deleteClipNode; + } + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitResolvedText(ResolvedTextNode textNode, Node data) { + final _Result result = _Result(textNode); + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitResolvedVerticesNode( + ResolvedVerticesNode verticesNode, Node data) { + final _Result result = _Result(verticesNode); + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitSaveLayerNode(SaveLayerNode layerNode, Node data) { + final List newChildren = []; + for (final Node child in layerNode.children) { + final _Result childResult = child.accept(this, layerNode); + newChildren.add(childResult.node); + } + final SaveLayerNode newLayerNode = SaveLayerNode(layerNode.attributes, + paint: layerNode.paint, children: newChildren); + + final _Result result = _Result(newLayerNode); + result.children = newChildren; + result.childCount = newChildren.length; + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitViewportNode(ViewportNode viewportNode, void data) { + final List children = []; + for (final Node child in viewportNode.children) { + final _Result childNode = child.accept(this, viewportNode); + children.add(childNode.node); + } + + final ViewportNode node = ViewportNode( + viewportNode.attributes, + width: viewportNode.width, + height: viewportNode.height, + transform: viewportNode.transform, + children: children, + ); + + final _Result result = _Result(node); + result.children = children; + result.childCount = children.length; + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitResolvedImageNode( + ResolvedImageNode resolvedImageNode, Node data) { + final _Result result = _Result(resolvedImageNode); + result.deleteClipNode = false; + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitResolvedPatternNode(ResolvedPatternNode patternNode, Node data) { + return _Result(patternNode); + } + + @override + // ignore: library_private_types_in_public_api + _Result visitResolvedTextPositionNode( + ResolvedTextPositionNode textPositionNode, void data) { + return _Result( + ResolvedTextPositionNode( + textPositionNode.textPosition, + [ + for (final Node child in textPositionNode.children) + child.accept(this, data).node + ], + ), + ); + } +} diff --git a/packages/vector_graphics_compiler/lib/src/svg/color_mapper.dart b/packages/vector_graphics_compiler/lib/src/svg/color_mapper.dart new file mode 100644 index 000000000000..983cda18528a --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/svg/color_mapper.dart @@ -0,0 +1,18 @@ +// 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 '../paint.dart'; + +/// A class that transforms from one color to another during SVG parsing. +abstract class ColorMapper { + /// Returns a new color to use in place of [color] during SVG parsing. + /// + /// The SVG parser will call this method every time it parses a color + Color substitute( + String? id, + String elementName, + String attributeName, + Color color, + ); +} diff --git a/packages/vector_graphics_compiler/lib/src/svg/colors.dart b/packages/vector_graphics_compiler/lib/src/svg/colors.dart new file mode 100644 index 000000000000..69d3f025f3ca --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/svg/colors.dart @@ -0,0 +1,159 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import '../paint.dart'; + +/// Named colors from the SVG standard. +/// +/// https://www.w3.org/TR/SVG11/types.html#ColorKeywords +const Map namedColors = { + 'aliceblue': Color.fromARGB(255, 240, 248, 255), + 'antiquewhite': Color.fromARGB(255, 250, 235, 215), + 'aqua': Color.fromARGB(255, 0, 255, 255), + 'aquamarine': Color.fromARGB(255, 127, 255, 212), + 'azure': Color.fromARGB(255, 240, 255, 255), + 'beige': Color.fromARGB(255, 245, 245, 220), + 'bisque': Color.fromARGB(255, 255, 228, 196), + 'black': Color.opaqueBlack, + 'blanchedalmond': Color.fromARGB(255, 255, 235, 205), + 'blue': Color.fromARGB(255, 0, 0, 255), + 'blueviolet': Color.fromARGB(255, 138, 43, 226), + 'brown': Color.fromARGB(255, 165, 42, 42), + 'burlywood': Color.fromARGB(255, 222, 184, 135), + 'cadetblue': Color.fromARGB(255, 95, 158, 160), + 'chartreuse': Color.fromARGB(255, 127, 255, 0), + 'chocolate': Color.fromARGB(255, 210, 105, 30), + 'coral': Color.fromARGB(255, 255, 127, 80), + 'cornflowerblue': Color.fromARGB(255, 100, 149, 237), + 'cornsilk': Color.fromARGB(255, 255, 248, 220), + 'crimson': Color.fromARGB(255, 220, 20, 60), + 'cyan': Color.fromARGB(255, 0, 255, 255), + 'darkblue': Color.fromARGB(255, 0, 0, 139), + 'darkcyan': Color.fromARGB(255, 0, 139, 139), + 'darkgoldenrod': Color.fromARGB(255, 184, 134, 11), + 'darkgray': Color.fromARGB(255, 169, 169, 169), + 'darkgreen': Color.fromARGB(255, 0, 100, 0), + 'darkgrey': Color.fromARGB(255, 169, 169, 169), + 'darkkhaki': Color.fromARGB(255, 189, 183, 107), + 'darkmagenta': Color.fromARGB(255, 139, 0, 139), + 'darkolivegreen': Color.fromARGB(255, 85, 107, 47), + 'darkorange': Color.fromARGB(255, 255, 140, 0), + 'darkorchid': Color.fromARGB(255, 153, 50, 204), + 'darkred': Color.fromARGB(255, 139, 0, 0), + 'darksalmon': Color.fromARGB(255, 233, 150, 122), + 'darkseagreen': Color.fromARGB(255, 143, 188, 143), + 'darkslateblue': Color.fromARGB(255, 72, 61, 139), + 'darkslategray': Color.fromARGB(255, 47, 79, 79), + 'darkslategrey': Color.fromARGB(255, 47, 79, 79), + 'darkturquoise': Color.fromARGB(255, 0, 206, 209), + 'darkviolet': Color.fromARGB(255, 148, 0, 211), + 'deeppink': Color.fromARGB(255, 255, 20, 147), + 'deepskyblue': Color.fromARGB(255, 0, 191, 255), + 'dimgray': Color.fromARGB(255, 105, 105, 105), + 'dimgrey': Color.fromARGB(255, 105, 105, 105), + 'dodgerblue': Color.fromARGB(255, 30, 144, 255), + 'firebrick': Color.fromARGB(255, 178, 34, 34), + 'floralwhite': Color.fromARGB(255, 255, 250, 240), + 'forestgreen': Color.fromARGB(255, 34, 139, 34), + 'fuchsia': Color.fromARGB(255, 255, 0, 255), + 'gainsboro': Color.fromARGB(255, 220, 220, 220), + 'ghostwhite': Color.fromARGB(255, 248, 248, 255), + 'gold': Color.fromARGB(255, 255, 215, 0), + 'goldenrod': Color.fromARGB(255, 218, 165, 32), + 'gray': Color.fromARGB(255, 128, 128, 128), + 'grey': Color.fromARGB(255, 128, 128, 128), + 'green': Color.fromARGB(255, 0, 128, 0), + 'greenyellow': Color.fromARGB(255, 173, 255, 47), + 'honeydew': Color.fromARGB(255, 240, 255, 240), + 'hotpink': Color.fromARGB(255, 255, 105, 180), + 'indianred': Color.fromARGB(255, 205, 92, 92), + 'indigo': Color.fromARGB(255, 75, 0, 130), + 'ivory': Color.fromARGB(255, 255, 255, 240), + 'khaki': Color.fromARGB(255, 240, 230, 140), + 'lavender': Color.fromARGB(255, 230, 230, 250), + 'lavenderblush': Color.fromARGB(255, 255, 240, 245), + 'lawngreen': Color.fromARGB(255, 124, 252, 0), + 'lemonchiffon': Color.fromARGB(255, 255, 250, 205), + 'lightblue': Color.fromARGB(255, 173, 216, 230), + 'lightcoral': Color.fromARGB(255, 240, 128, 128), + 'lightcyan': Color.fromARGB(255, 224, 255, 255), + 'lightgoldenrodyellow': Color.fromARGB(255, 250, 250, 210), + 'lightgray': Color.fromARGB(255, 211, 211, 211), + 'lightgreen': Color.fromARGB(255, 144, 238, 144), + 'lightgrey': Color.fromARGB(255, 211, 211, 211), + 'lightpink': Color.fromARGB(255, 255, 182, 193), + 'lightsalmon': Color.fromARGB(255, 255, 160, 122), + 'lightseagreen': Color.fromARGB(255, 32, 178, 170), + 'lightskyblue': Color.fromARGB(255, 135, 206, 250), + 'lightslategray': Color.fromARGB(255, 119, 136, 153), + 'lightslategrey': Color.fromARGB(255, 119, 136, 153), + 'lightsteelblue': Color.fromARGB(255, 176, 196, 222), + 'lightyellow': Color.fromARGB(255, 255, 255, 224), + 'lime': Color.fromARGB(255, 0, 255, 0), + 'limegreen': Color.fromARGB(255, 50, 205, 50), + 'linen': Color.fromARGB(255, 250, 240, 230), + 'magenta': Color.fromARGB(255, 255, 0, 255), + 'maroon': Color.fromARGB(255, 128, 0, 0), + 'mediumaquamarine': Color.fromARGB(255, 102, 205, 170), + 'mediumblue': Color.fromARGB(255, 0, 0, 205), + 'mediumorchid': Color.fromARGB(255, 186, 85, 211), + 'mediumpurple': Color.fromARGB(255, 147, 112, 219), + 'mediumseagreen': Color.fromARGB(255, 60, 179, 113), + 'mediumslateblue': Color.fromARGB(255, 123, 104, 238), + 'mediumspringgreen': Color.fromARGB(255, 0, 250, 154), + 'mediumturquoise': Color.fromARGB(255, 72, 209, 204), + 'mediumvioletred': Color.fromARGB(255, 199, 21, 133), + 'midnightblue': Color.fromARGB(255, 25, 25, 112), + 'mintcream': Color.fromARGB(255, 245, 255, 250), + 'mistyrose': Color.fromARGB(255, 255, 228, 225), + 'moccasin': Color.fromARGB(255, 255, 228, 181), + 'navajowhite': Color.fromARGB(255, 255, 222, 173), + 'navy': Color.fromARGB(255, 0, 0, 128), + 'oldlace': Color.fromARGB(255, 253, 245, 230), + 'olive': Color.fromARGB(255, 128, 128, 0), + 'olivedrab': Color.fromARGB(255, 107, 142, 35), + 'orange': Color.fromARGB(255, 255, 165, 0), + 'orangered': Color.fromARGB(255, 255, 69, 0), + 'orchid': Color.fromARGB(255, 218, 112, 214), + 'palegoldenrod': Color.fromARGB(255, 238, 232, 170), + 'palegreen': Color.fromARGB(255, 152, 251, 152), + 'paleturquoise': Color.fromARGB(255, 175, 238, 238), + 'palevioletred': Color.fromARGB(255, 219, 112, 147), + 'papayawhip': Color.fromARGB(255, 255, 239, 213), + 'peachpuff': Color.fromARGB(255, 255, 218, 185), + 'peru': Color.fromARGB(255, 205, 133, 63), + 'pink': Color.fromARGB(255, 255, 192, 203), + 'plum': Color.fromARGB(255, 221, 160, 221), + 'powderblue': Color.fromARGB(255, 176, 224, 230), + 'purple': Color.fromARGB(255, 128, 0, 128), + 'red': Color.fromARGB(255, 255, 0, 0), + 'rosybrown': Color.fromARGB(255, 188, 143, 143), + 'royalblue': Color.fromARGB(255, 65, 105, 225), + 'saddlebrown': Color.fromARGB(255, 139, 69, 19), + 'salmon': Color.fromARGB(255, 250, 128, 114), + 'sandybrown': Color.fromARGB(255, 244, 164, 96), + 'seagreen': Color.fromARGB(255, 46, 139, 87), + 'seashell': Color.fromARGB(255, 255, 245, 238), + 'sienna': Color.fromARGB(255, 160, 82, 45), + 'silver': Color.fromARGB(255, 192, 192, 192), + 'skyblue': Color.fromARGB(255, 135, 206, 235), + 'slateblue': Color.fromARGB(255, 106, 90, 205), + 'slategray': Color.fromARGB(255, 112, 128, 144), + 'slategrey': Color.fromARGB(255, 112, 128, 144), + 'snow': Color.fromARGB(255, 255, 250, 250), + 'springgreen': Color.fromARGB(255, 0, 255, 127), + 'steelblue': Color.fromARGB(255, 70, 130, 180), + 'tan': Color.fromARGB(255, 210, 180, 140), + 'teal': Color.fromARGB(255, 0, 128, 128), + 'thistle': Color.fromARGB(255, 216, 191, 216), + 'tomato': Color.fromARGB(255, 255, 99, 71), + 'transparent': Color.fromARGB(0, 255, 255, 255), + 'turquoise': Color.fromARGB(255, 64, 224, 208), + 'violet': Color.fromARGB(255, 238, 130, 238), + 'wheat': Color.fromARGB(255, 245, 222, 179), + 'white': Color.fromARGB(255, 255, 255, 255), + 'whitesmoke': Color.fromARGB(255, 245, 245, 245), + 'yellow': Color.fromARGB(255, 255, 255, 0), + 'yellowgreen': Color.fromARGB(255, 154, 205, 50), +}; diff --git a/packages/vector_graphics_compiler/lib/src/svg/masking_optimizer.dart b/packages/vector_graphics_compiler/lib/src/svg/masking_optimizer.dart new file mode 100644 index 000000000000..ca24c29ca58e --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/svg/masking_optimizer.dart @@ -0,0 +1,359 @@ +// 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:typed_data'; + +import '../../vector_graphics_compiler.dart'; +import 'node.dart'; +import 'path_ops.dart' as path_ops; +import 'visitor.dart'; + +class _Result { + _Result(this.node, {this.deleteMaskNode = true}); + + final Node node; + final List children = []; + Node parent = Node.empty; + final bool deleteMaskNode; +} + +/// Converts a vector_graphics PathFillType to a path_ops FillType. +path_ops.FillType toPathOpsFillTyle(PathFillType fill) { + switch (fill) { + case PathFillType.evenOdd: + return path_ops.FillType.evenOdd; + + case PathFillType.nonZero: + return path_ops.FillType.nonZero; + } +} + +/// Converts a path_ops FillType to a vector_graphics PathFillType +PathFillType toVectorGraphicsFillType(path_ops.FillType fill) { + switch (fill) { + case path_ops.FillType.evenOdd: + return PathFillType.evenOdd; + + case path_ops.FillType.nonZero: + return PathFillType.nonZero; + } +} + +/// Converts vector_graphics Path to path_ops Path. +path_ops.Path toPathOpsPath(Path path) { + final path_ops.Path newPath = path_ops.Path(toPathOpsFillTyle(path.fillType)); + + for (final PathCommand command in path.commands) { + switch (command.type) { + case PathCommandType.line: + final LineToCommand lineToCommand = command as LineToCommand; + newPath.lineTo(lineToCommand.x, lineToCommand.y); + case PathCommandType.cubic: + final CubicToCommand cubicToCommand = command as CubicToCommand; + newPath.cubicTo(cubicToCommand.x1, cubicToCommand.y1, cubicToCommand.x2, + cubicToCommand.y2, cubicToCommand.x3, cubicToCommand.y3); + case PathCommandType.move: + final MoveToCommand moveToCommand = command as MoveToCommand; + newPath.moveTo(moveToCommand.x, moveToCommand.y); + case PathCommandType.close: + newPath.close(); + } + } + + return newPath; +} + +/// Converts path_ops Path to VectorGraphicsPath. +Path toVectorGraphicsPath(path_ops.Path path) { + final List newCommands = []; + + int index = 0; + final Float32List points = path.points; + for (final path_ops.PathVerb verb in path.verbs.toList()) { + switch (verb) { + case path_ops.PathVerb.moveTo: + newCommands.add(MoveToCommand(points[index++], points[index++])); + case path_ops.PathVerb.lineTo: + newCommands.add(LineToCommand(points[index++], points[index++])); + case path_ops.PathVerb.quadTo: + final double cpX = points[index++]; + final double cpY = points[index++]; + newCommands.add(CubicToCommand( + cpX, + cpY, + cpX, + cpY, + points[index++], + points[index++], + )); + case path_ops.PathVerb.cubicTo: + newCommands.add(CubicToCommand( + points[index++], + points[index++], + points[index++], + points[index++], + points[index++], + points[index++], + )); + case path_ops.PathVerb.close: + newCommands.add(const CloseCommand()); + } + } + + final Path newPath = Path( + commands: newCommands, fillType: toVectorGraphicsFillType(path.fillType)); + + return newPath; +} + +/// Gets the single child recursively, +/// returns null if there are 0 children or more than 1. +ResolvedPathNode? getSingleChild(Node node) { + if (node is ResolvedPathNode) { + return node; + } else if (node is ParentNode && node.children.length == 1) { + return getSingleChild(node.children.first); + } + return null; +} + +/// Simplifies masking operations into PathNodes. +/// Note this will not optimize cases where 'stroke-width' is set, +/// there are multiple path nodes in a mask or cases where +/// the intersection of the mask and the path results in +/// Path.commands being empty. +class MaskingOptimizer extends Visitor<_Result, Node> + with ErrorOnUnResolvedNode<_Result, Node> { + /// List of masks to add. + final List masksToApply = []; + + /// Applies visitor to given node. + Node apply(Node node) { + final Node newNode = node.accept(this, null).node; + return newNode; + } + + /// Applies mask to a path node, and returns resulting path node. + ResolvedPathNode applyMask( + ResolvedPathNode pathNode, ResolvedPathNode maskPathNode) { + final path_ops.Path maskPathOpsPath = toPathOpsPath(maskPathNode.path); + final path_ops.Path pathPathOpsPath = toPathOpsPath(pathNode.path); + final path_ops.Path intersection = + pathPathOpsPath.applyOp(maskPathOpsPath, path_ops.PathOp.intersect); + final Path newPath = toVectorGraphicsPath(intersection); + final ResolvedPathNode newPathNode = ResolvedPathNode( + paint: pathNode.paint, bounds: maskPathNode.bounds, path: newPath); + + maskPathOpsPath.dispose(); + pathPathOpsPath.dispose(); + intersection.dispose(); + + return newPathNode; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitEmptyNode(Node node, void data) { + final _Result result = _Result(node); + return result; + } + + /// Visits applies optimizer to all children of ResolvedMaskNode. + // ignore: library_private_types_in_public_api + _Result visitChildren(Node node, _Result data) { + if (node is ResolvedMaskNode) { + data = node.child.accept(this, data); + } + return data; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitParentNode(ParentNode parentNode, Node data) { + final List newChildren = []; + + for (final Node child in parentNode.children) { + final _Result childResult = child.accept(this, parentNode); + newChildren.add(childResult.node); + if (!childResult.deleteMaskNode) { + return _Result(parentNode, deleteMaskNode: false); + } + } + + final ParentNode newParentNode = ParentNode(parentNode.attributes, + precalculatedTransform: parentNode.transform, children: newChildren); + + final _Result result = _Result(newParentNode); + + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitMaskNode(MaskNode maskNode, Node data) { + final _Result result = _Result(maskNode); + + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitPathNode(PathNode pathNode, Node data) { + final _Result result = _Result(pathNode); + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitResolvedMaskNode(ResolvedMaskNode maskNode, void data) { + _Result result = _Result(maskNode); + final ResolvedPathNode? singleMaskPathNode = getSingleChild(maskNode.mask); + + if (singleMaskPathNode != null) { + masksToApply.add(singleMaskPathNode); + final _Result childResult = maskNode.child.accept(this, maskNode); + masksToApply.removeLast(); + + if (childResult.deleteMaskNode) { + result = _Result(childResult.node); + } else { + final ResolvedMaskNode newMaskNode = ResolvedMaskNode( + child: childResult.node, + mask: maskNode.mask, + blendMode: maskNode.blendMode); + result = _Result(newMaskNode); + } + } else { + final _Result childResult = maskNode.child.accept(this, maskNode); + final ResolvedMaskNode newMaskNode = ResolvedMaskNode( + child: childResult.node, + mask: maskNode.mask, + blendMode: maskNode.blendMode); + result = _Result(newMaskNode); + } + + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitResolvedClipNode(ResolvedClipNode clipNode, Node data) { + final _Result childResult = clipNode.child.accept(this, clipNode); + final ResolvedClipNode newClipNode = + ResolvedClipNode(clips: clipNode.clips, child: childResult.node); + final _Result result = _Result(newClipNode); + result.children.add(childResult.node); + + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitResolvedPath(ResolvedPathNode pathNode, Node data) { + _Result result = _Result(pathNode); + + if (pathNode.paint.stroke?.width != null) { + return _Result(pathNode, deleteMaskNode: false); + } + + if (masksToApply.isNotEmpty) { + ResolvedPathNode newPathNode = pathNode; + for (final ResolvedPathNode maskPathNode in masksToApply) { + final ResolvedPathNode intersection = + applyMask(newPathNode, maskPathNode); + if (intersection.path.commands.isNotEmpty) { + newPathNode = intersection; + } else { + return _Result(pathNode, deleteMaskNode: false); + } + } + result = _Result(newPathNode); + } + + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitResolvedText(ResolvedTextNode textNode, Node data) { + final _Result result = _Result(textNode); + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitResolvedVerticesNode( + ResolvedVerticesNode verticesNode, Node data) { + final _Result result = _Result(verticesNode); + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitSaveLayerNode(SaveLayerNode layerNode, Node data) { + final List newChildren = []; + for (final Node child in layerNode.children) { + final _Result childResult = child.accept(this, layerNode); + newChildren.add(childResult.node); + } + final SaveLayerNode newLayerNode = SaveLayerNode(layerNode.attributes, + paint: layerNode.paint, children: newChildren); + + final _Result result = _Result(newLayerNode); + result.children.addAll(newChildren); + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitViewportNode(ViewportNode viewportNode, void data) { + final List children = []; + for (final Node child in viewportNode.children) { + final _Result childNode = child.accept(this, viewportNode); + children.add(childNode.node); + } + + final ViewportNode node = ViewportNode( + viewportNode.attributes, + width: viewportNode.width, + height: viewportNode.height, + transform: viewportNode.transform, + children: children, + ); + + final _Result result = _Result(node); + result.children.addAll(children); + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitResolvedImageNode( + ResolvedImageNode resolvedImageNode, Node data) { + final _Result result = _Result(resolvedImageNode, deleteMaskNode: false); + + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitResolvedPatternNode(ResolvedPatternNode patternNode, Node data) { + return _Result(patternNode); + } + + @override + // ignore: library_private_types_in_public_api + _Result visitResolvedTextPositionNode( + ResolvedTextPositionNode textPositionNode, void data) { + return _Result( + ResolvedTextPositionNode( + textPositionNode.textPosition, + [ + for (final Node child in textPositionNode.children) + child.accept(this, data).node + ], + ), + ); + } +} diff --git a/packages/vector_graphics_compiler/lib/src/svg/node.dart b/packages/vector_graphics_compiler/lib/src/svg/node.dart new file mode 100644 index 000000000000..91638ec270a8 --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/svg/node.dart @@ -0,0 +1,651 @@ +// 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:typed_data'; + +import 'package:meta/meta.dart'; + +import '../geometry/basic_types.dart'; +import '../geometry/matrix.dart'; +import '../geometry/path.dart'; +import '../image/image_info.dart'; +import '../paint.dart'; +import 'parser.dart' show SvgAttributes; +import 'visitor.dart'; + +/// Signature of a method that resolves a string identifier to an object. +/// +/// Used by [ClipNode] and [MaskNode] to defer resolution of clips and masks. +typedef Resolver = T Function(String id); + +/// A node in a tree of graphics operations. +/// +/// Nodes describe painting attributes, clips, transformations, paths, and +/// vertices to draw in depth-first order. +abstract class Node { + /// Allows subclasses to be const. + const Node(); + + /// A node with no properties or operations, used for replacing `null` values + /// in the tree or nodes that cannot be resolved correctly. + static const Node empty = _EmptyNode(); + + /// Subclasses that have additional transformation information will + /// concatenate their transform to the supplied `currentTransform`. + AffineMatrix concatTransform(AffineMatrix currentTransform) { + return currentTransform; + } + + /// Calls `visitor` for each child node of this parent group. + /// + /// This call does not recursively call `visitChildren`. Callers must decide + /// whether to do BFS or DFS by calling `visitChildren` if the visited child + /// is a [ParentNode]. + void visitChildren(NodeCallback visitor); + + /// Accept a [Visitor] implementation. + S accept(Visitor visitor, V data); + + /// Creates a new compatible new node with attribute inheritence. + /// + /// If [replace] is true, treats the application of attributes as if this node + /// is the parent. Otherwise, treats the application of the attributes as if + /// the [newAttributes] are from the parent. + /// + /// By default, returns this. + Node applyAttributes(SvgAttributes newAttributes, {bool replace = false}) => + this; +} + +class _EmptyNode extends Node { + const _EmptyNode(); + + @override + S accept(Visitor visitor, V data) { + return visitor.visitEmptyNode(this, data); + } + + @override + void visitChildren(NodeCallback visitor) {} +} + +/// A node that contains a transform operation in the tree of graphics +/// operations. +abstract class TransformableNode extends Node { + /// Constructs a new tree node with [transform]. + TransformableNode(this.transform); + + /// The descendant child's transform + final AffineMatrix transform; + + @override + @mustCallSuper + AffineMatrix concatTransform(AffineMatrix currentTransform) { + if (transform == AffineMatrix.identity) { + return currentTransform; + } + return currentTransform.multiplied(transform); + } +} + +/// A node that has attributes in the tree of graphics operations. +abstract class AttributedNode extends TransformableNode { + /// Constructs a new tree node with [attributes]. + AttributedNode(this.attributes, {AffineMatrix? precalculatedTransform}) + : super(precalculatedTransform ?? attributes.transform); + + /// A collection of painting attributes. + /// + /// Painting attributes inherit down the tree. + final SvgAttributes attributes; +} + +/// A graphics node describing a viewport area, which has a [width] and [height] +/// for the viewable portion it describes. +/// +/// A viewport node is effectively a [ParentNode] with a width and height to +/// describe child coordinate space. It is typically used as the root of a tree, +/// but may also appear as a subtree root. +class ViewportNode extends ParentNode { + /// Creates a new viewport node. + /// + /// See [ViewportNode]. + ViewportNode( + super.attributes, { + required this.width, + required this.height, + required AffineMatrix transform, + super.children, + }) : super( + precalculatedTransform: transform, + ); + + /// The width of the viewport in pixels. + final double width; + + /// The height of the viewport in pixels. + final double height; + + /// The viewport rect described by [width] and [height]. + Rect get viewport => Rect.fromLTWH(0, 0, width, height); + + @override + S accept(Visitor visitor, V data) { + return visitor.visitViewportNode(this, data); + } +} + +/// The signature for a visitor callback to [ParentNode.visitChildren]. +typedef NodeCallback = void Function(Node child); + +/// A node that contains children, transformed by [transform]. +class ParentNode extends AttributedNode { + /// Creates a new [ParentNode]. + ParentNode( + super.attributes, { + super.precalculatedTransform, + List? children, + }) : _children = children ?? []; + + /// The child nodes of this node. + final List _children; + + /// The child nodes for the given parent node. + Iterable get children => _children; + + @override + void visitChildren(NodeCallback visitor) { + _children.forEach(visitor); + } + + /// Adds a child to this parent node. + /// + /// If `clips` is empty, the child is directly appended. Otherwise, a + /// [ClipNode] is inserted. + void addChild( + AttributedNode child, { + String? clipId, + String? maskId, + String? patternId, + required Resolver> clipResolver, + required Resolver maskResolver, + required Resolver patternResolver, + }) { + Node wrappedChild = child; + if (clipId != null) { + wrappedChild = ClipNode( + resolver: clipResolver, + clipId: clipId, + child: wrappedChild, + transform: child.attributes.transform, + ); + } + if (maskId != null) { + wrappedChild = MaskNode( + resolver: maskResolver, + maskId: maskId, + child: wrappedChild, + blendMode: child.attributes.blendMode, + transform: child.attributes.transform, + ); + } + if (patternId != null) { + wrappedChild = PatternNode( + resolver: patternResolver, + patternId: patternId, + child: wrappedChild, + transform: child.attributes.transform, + ); + } + _children.add(wrappedChild); + } + + @override + AttributedNode applyAttributes( + SvgAttributes newAttributes, { + bool replace = false, + }) { + return ParentNode( + attributes.applyParent(newAttributes), + precalculatedTransform: transform, + ).._children.addAll(_children); + } + + /// Create the paint required to draw a save layer, or `null` if none is + /// required. + Paint? createLayerPaint() { + final double? fillOpacity = attributes.fill?.opacity; + final bool needsLayer = (attributes.blendMode != null) || + (fillOpacity != null && fillOpacity != 1.0 && fillOpacity != 0.0); + + if (needsLayer) { + return Paint( + blendMode: attributes.blendMode, + fill: attributes.fill?.toFill(Rect.largest, transform) ?? + Fill( + color: Color.opaqueBlack.withOpacity(fillOpacity ?? 1.0), + ), + ); + } + return null; + } + + @override + S accept(Visitor visitor, V data) { + return visitor.visitParentNode(this, data); + } +} + +/// A node describing an update to the [TextPosition], including any applicable +/// transformation matrix. +class TextPositionNode extends ParentNode { + /// See [TextPositionNode]. + TextPositionNode(super.attributes, {required this.reset}); + + /// Whether this node represents a reset of the current text position or not. + final bool reset; + + /// Computes a [TextPosition] to encode for this node. + TextPosition computeTextPosition(Rect bounds, AffineMatrix transform) { + final AffineMatrix computedTransform = concatTransform(transform); + + double? x = attributes.x?.calculate(bounds.width); + double? y = attributes.y?.calculate(bounds.height); + double? dx = attributes.dx?.calculate(bounds.width); + double? dy = attributes.dy?.calculate(bounds.height); + + final bool hasXY = x != null && y != null; + final bool hasDxDy = dx != null && dy != null; + final bool consumeTransform = computedTransform == AffineMatrix.identity || + (computedTransform.encodableInRect && (hasXY || hasDxDy)); + + if (hasXY) { + final Point baseline = consumeTransform + ? computedTransform.transformPoint(Point(x, y)) + : Point(x, y); + x = baseline.x; + y = baseline.y; + } + + if (hasDxDy) { + final Point baseline = consumeTransform + ? computedTransform.transformPoint(Point(dx, dy)) + : Point(dx, dy); + dx = baseline.x; + dy = baseline.y; + } + + return TextPosition( + x: x, + y: y, + dx: dx, + dy: dy, + reset: reset, + transform: consumeTransform ? null : computedTransform, + ); + } + + @override + S accept(Visitor visitor, V data) { + return visitor.visitTextPositionNode(this, data); + } + + @override + AttributedNode applyAttributes( + SvgAttributes newAttributes, { + bool replace = false, + }) { + return TextPositionNode(attributes.applyParent(newAttributes), reset: reset) + .._children.addAll(_children); + } +} + +/// A parent node that applies a save layer to its children. +class SaveLayerNode extends ParentNode { + /// Create a new [SaveLayerNode] + SaveLayerNode( + super.attributes, { + required this.paint, + super.children, + }) : super(precalculatedTransform: AffineMatrix.identity); + + /// The paint to apply to the saved layer. + final Paint paint; + + @override + S accept(Visitor visitor, V data) { + return visitor.visitSaveLayerNode(this, data); + } +} + +/// A parent node that applies a clip to its children. +class ClipNode extends TransformableNode { + /// Creates a new clip node that applies clip paths to [child]. + ClipNode({ + required this.resolver, + required this.child, + required this.clipId, + required AffineMatrix transform, + }) : super(transform); + + /// Called by visitors to resolve [clipId] to a list of paths. + final Resolver> resolver; + + /// The clips to apply to the child node. + /// + /// Normally, there will only be one clip to apply. However, if multiple paths + /// with differeing [PathFillType]s are used, multiple clips must be + /// specified. + final String clipId; + + /// The child to clip. + final Node child; + + @override + void visitChildren(NodeCallback visitor) { + visitor(child); + } + + @override + S accept(Visitor visitor, V data) { + return visitor.visitClipNode(this, data); + } + + @override + Node applyAttributes(SvgAttributes newAttributes, {bool replace = false}) { + return ClipNode( + resolver: resolver, + clipId: clipId, + transform: transform, + child: child.applyAttributes(newAttributes, replace: replace), + ); + } +} + +/// A parent node that applies a mask to its child. +class MaskNode extends TransformableNode { + /// Creates a new mask node that applies [mask] to [child] using [blendMode]. + MaskNode({ + required this.child, + required this.maskId, + this.blendMode, + required this.resolver, + required AffineMatrix transform, + }) : super(transform); + + /// The mask to apply. + final String maskId; + + /// The child to mask. + final Node child; + + /// The blend mode to apply when saving a layer for the mask, if any. + final BlendMode? blendMode; + + /// Called by visitors to resolve [maskId] to an [AttributedNode]. + final Resolver resolver; + + @override + void visitChildren(NodeCallback visitor) { + visitor(child); + } + + @override + S accept(Visitor visitor, V data) { + return visitor.visitMaskNode(this, data); + } + + @override + Node applyAttributes(SvgAttributes newAttributes, {bool replace = false}) { + return MaskNode( + resolver: resolver, + maskId: maskId, + blendMode: blendMode, + transform: transform, + child: child.applyAttributes(newAttributes, replace: replace), + ); + } +} + +/// A leaf node in the graphics tree. +/// +/// Leaf nodes get added with all paint and transform accumulations from their +/// parents applied. +class PathNode extends AttributedNode { + /// Creates a new leaf node for the graphics tree with the specified [path] + /// and attributes + PathNode(this.path, super.attributes); + + /// The description of the geometry this leaf node draws. + final Path path; + + /// Compute the paint used by this Path. + Paint? computePaint(Rect bounds, AffineMatrix transform) { + final Stroke? stroke = attributes.stroke?.toStroke(bounds, transform); + final Fill? fill = attributes.fill?.toFill( + bounds, + transform, + defaultColor: Color.opaqueBlack, + ); + if (fill == null && stroke == null) { + return null; + } + return Paint( + blendMode: attributes.blendMode, + fill: fill, + stroke: stroke, + ); + } + + @override + AttributedNode applyAttributes( + SvgAttributes newAttributes, { + bool replace = false, + }) { + return PathNode( + path, + replace + ? newAttributes.applyParent(attributes, transformOverride: transform) + : attributes.applyParent(newAttributes), + ); + } + + @override + void visitChildren(NodeCallback visitor) {} + + @override + S accept(Visitor visitor, V data) { + return visitor.visitPathNode(this, data); + } +} + +/// A node that refers to another node, and supplies a [resolver] for visitors +/// to materialize the referenced node into the tree. +class DeferredNode extends AttributedNode { + /// Creates a new deferred node with [attributes] that will call [resolver] + /// with [refId] when visited. + DeferredNode( + super.attributes, { + required this.refId, + required this.resolver, + }); + + /// The reference id to pass to [resolver]. + final String refId; + + /// The callback that materializes an [AttributedNode] for [refId] when + /// visited. + final Resolver resolver; + + @override + AttributedNode applyAttributes( + SvgAttributes newAttributes, { + bool replace = false, + }) { + return DeferredNode( + replace + ? newAttributes.applyParent(attributes, transformOverride: transform) + : attributes.applyParent(newAttributes), + refId: refId, + resolver: resolver, + ); + } + + @override + void visitChildren(NodeCallback visitor) {} + + @override + S accept(Visitor visitor, V data) { + return visitor.visitDeferredNode(this, data); + } +} + +/// A leaf node in the tree that represents inline text. +/// +/// Leaf nodes get added with all paint and transform accumulations from their +/// parents applied. +class TextNode extends AttributedNode { + /// Create a new [TextNode] with the given [text]. + TextNode( + this.text, + super.attributes, + ); + + /// The text this node contains. + final String text; + + /// Compute the [Paint] that this text node uses. + Paint? computePaint(Rect bounds, AffineMatrix transform) { + final Fill? fill = attributes.fill + ?.toFill(bounds, transform, defaultColor: Color.opaqueBlack); + final Stroke? stroke = attributes.stroke?.toStroke(bounds, transform); + if (fill == null && stroke == null) { + return null; + } + return Paint( + blendMode: attributes.blendMode, + fill: fill, + stroke: stroke, + ); + } + + /// Compute the [TextConfig] that this text node uses. + TextConfig computeTextConfig(Rect bounds, AffineMatrix transform) { + // Don't concat the transform since it's repeated by the parent group + // the way the parser is set up. + return TextConfig( + text, + attributes.textAnchorMultiplier ?? 0, + attributes.fontFamily, + attributes.fontWeight ?? normalFontWeight, + attributes.fontSize ?? 16, // default in many browsers + attributes.textDecoration ?? TextDecoration.none, + attributes.textDecorationStyle ?? TextDecorationStyle.solid, + attributes.textDecorationColor ?? Color.opaqueBlack, + ); + } + + @override + AttributedNode applyAttributes( + SvgAttributes newAttributes, { + bool replace = false, + }) { + final SvgAttributes resolvedAttributes = replace + ? newAttributes.applyParent(attributes, transformOverride: transform) + : attributes.applyParent(newAttributes); + return TextNode( + text, + resolvedAttributes, + ); + } + + @override + void visitChildren(NodeCallback visitor) {} + + @override + S accept(Visitor visitor, V data) { + return visitor.visitTextNode(this, data); + } +} + +/// A leaf node in the tree that represents an image. +/// +/// Leaf nodes get added with all paint and transform accumulations from their +/// parents applied. +class ImageNode extends AttributedNode { + /// Create a new [ImageNode] with the given [text]. + ImageNode( + this.data, + this.format, + super.attributes, + ); + + /// The image data this node contains. + final Uint8List data; + + /// The format of [data]. + final ImageFormat format; + + @override + AttributedNode applyAttributes( + SvgAttributes newAttributes, { + bool replace = false, + }) { + return ImageNode( + data, + format, + replace + ? newAttributes.applyParent(attributes, transformOverride: transform) + : attributes.applyParent(newAttributes), + ); + } + + @override + void visitChildren(NodeCallback visitor) {} + + @override + S accept(Visitor visitor, V data) { + return visitor.visitImageNode(this, data); + } +} + +/// A leaf node in the tree that reprents an patterned-node. +class PatternNode extends TransformableNode { + /// Creates a new pattern node that aaples [pattern] to [child]. + PatternNode({ + required this.child, + required this.patternId, + required this.resolver, + required AffineMatrix transform, + }) : super(transform); + + /// A unique identifier for this pattern. + final String patternId; + + /// The child(ren) to apply the pattern to. + final Node child; + + /// Called by visitors to resolve [patternId] to an [AttributedNode]. + final Resolver resolver; + + @override + void visitChildren(NodeCallback visitor) { + visitor(child); + } + + @override + S accept(Visitor visitor, V data) { + return visitor.visitPatternNode(this, data); + } + + @override + Node applyAttributes(SvgAttributes newAttributes, {bool replace = false}) { + return PatternNode( + resolver: resolver, + patternId: patternId, + transform: transform, + child: child.applyAttributes(newAttributes, replace: replace), + ); + } +} diff --git a/packages/vector_graphics_compiler/lib/src/svg/numbers.dart b/packages/vector_graphics_compiler/lib/src/svg/numbers.dart new file mode 100644 index 000000000000..fbe7563bf868 --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/svg/numbers.dart @@ -0,0 +1,88 @@ +// 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:math' as math; + +import 'theme.dart'; + +/// Parses a [rawDouble] `String` to a `double`. +/// +/// The [rawDouble] might include a unit (`px`, `em` or `ex`) +/// which is stripped off when parsed to a `double`. +/// +/// Passing `null` will return `null`. +double? parseDouble(String? rawDouble, {bool tryParse = false}) { + assert(tryParse != null); // ignore: unnecessary_null_comparison + if (rawDouble == null) { + return null; + } + + rawDouble = rawDouble + .replaceFirst('rem', '') + .replaceFirst('em', '') + .replaceFirst('ex', '') + .replaceFirst('px', '') + .replaceFirst('pt', '') + .trim(); + + if (tryParse) { + return double.tryParse(rawDouble); + } + return double.parse(rawDouble); +} + +/// Convert [degrees] to radians. +double radians(double degrees) => degrees * math.pi / 180; + +/// The number of pixels per CSS inch. +const int kCssPixelsPerInch = 96; + +/// The number of points per CSS inch. +const int kCssPointsPerInch = 72; + +/// The multiplicand to convert from CSS points to pixels. +const double kPointsToPixelFactor = kCssPixelsPerInch / kCssPointsPerInch; + +/// Parses a `rawDouble` `String` to a `double` +/// taking into account absolute and relative units +/// (`px`, `em` or `ex`). +/// +/// Passing an `em` value will calculate the result +/// relative to the provided [fontSize]: +/// 1 em = 1 * `fontSize`. +/// +/// Passing an `ex` value will calculate the result +/// relative to the provided [xHeight]: +/// 1 ex = 1 * `xHeight`. +/// +/// The `rawDouble` might include a unit which is +/// stripped off when parsed to a `double`. +/// +/// Passing `null` will return `null`. +double? parseDoubleWithUnits( + String? rawDouble, { + bool tryParse = false, + required SvgTheme theme, +}) { + double unit = 1.0; + + // 1 rem unit is equal to the root font size. + // 1 em unit is equal to the current font size. + // 1 ex unit is equal to the current x-height. + if (rawDouble?.contains('pt') ?? false) { + unit = kPointsToPixelFactor; + } else if (rawDouble?.contains('rem') ?? false) { + unit = theme.fontSize; + } else if (rawDouble?.contains('em') ?? false) { + unit = theme.fontSize; + } else if (rawDouble?.contains('ex') ?? false) { + unit = theme.xHeight; + } + final double? value = parseDouble( + rawDouble, + tryParse: tryParse, + ); + + return value != null ? value * unit : null; +} diff --git a/packages/vector_graphics_compiler/lib/src/svg/overdraw_optimizer.dart b/packages/vector_graphics_compiler/lib/src/svg/overdraw_optimizer.dart new file mode 100644 index 000000000000..7856c8c5754b --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/svg/overdraw_optimizer.dart @@ -0,0 +1,371 @@ +// 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 '../../vector_graphics_compiler.dart'; +import 'masking_optimizer.dart'; +import 'node.dart'; +import 'parser.dart'; +import 'path_ops.dart' as path_ops; +import 'visitor.dart'; + +class _Result { + _Result(this.node); + + final Node node; + final List children = []; + Node parent = Node.empty; +} + +/// Removes unnecessary overlappping. +class OverdrawOptimizer extends Visitor<_Result, Node> + with ErrorOnUnResolvedNode<_Result, Node> { + /// Applies visitor to given node. + Node apply(Node node) { + final Node newNode = node.accept(this, null).node; + return newNode; + } + + /// Removes overlap between top and bottom path from bottom. + ResolvedPathNode removeOverlap( + ResolvedPathNode bottomPathNode, ResolvedPathNode topPathNode) { + final path_ops.Path topPathOpsPath = toPathOpsPath(topPathNode.path); + final path_ops.Path bottomPathOpsPath = toPathOpsPath(bottomPathNode.path); + final path_ops.Path intersection = + bottomPathOpsPath.applyOp(topPathOpsPath, path_ops.PathOp.intersect); + final path_ops.Path newBottomPath = + bottomPathOpsPath.applyOp(intersection, path_ops.PathOp.difference); + final Path newPath = toVectorGraphicsPath(newBottomPath); + final ResolvedPathNode newPathNode = ResolvedPathNode( + paint: bottomPathNode.paint, + bounds: bottomPathNode.bounds, + path: newPath); + + bottomPathOpsPath.dispose(); + topPathOpsPath.dispose(); + intersection.dispose(); + newBottomPath.dispose(); + + return newPathNode; + } + + /// Calculates the resulting [Color] when two semi-transparent + /// colors are stacked on top of eachother. + Color calculateOverlapColor(Color bottomColor, Color topColor) { + final double a0 = topColor.a / 255; + final double a1 = bottomColor.a / 255; + final int r0 = topColor.r; + final int b0 = topColor.b; + final int g0 = topColor.g; + final int r1 = bottomColor.r; + final int b1 = bottomColor.b; + final int g1 = bottomColor.g; + + final double a = (1 - a0) * a1 + a0; + final double r = ((1 - a0) * a1 * r1 + a0 * r0) / a; + final double g = ((1 - a0) * a1 * g1 + a0 * g0) / a; + final double b = ((1 - a0) * a1 * b1 + a0 * b0) / a; + + final Color overlapColor = + Color.fromARGB((a * 255).round(), r.round(), g.round(), b.round()); + return overlapColor; + } + + /// Resolves overlapping between top and bottom path on + /// nodes where opacity is not 1 or null. + List resolveOpacityOverlap( + ResolvedPathNode bottomPathNode, ResolvedPathNode topPathNode) { + final Color? bottomColor = bottomPathNode.paint.fill?.color; + final Color? topColor = topPathNode.paint.fill?.color; + if (bottomColor != null && topColor != null) { + final Color overlapColor = calculateOverlapColor(bottomColor, topColor); + final path_ops.Path topPathOpsPath = toPathOpsPath(topPathNode.path); + final path_ops.Path bottomPathOpsPath = + toPathOpsPath(bottomPathNode.path); + final path_ops.Path intersection = + bottomPathOpsPath.applyOp(topPathOpsPath, path_ops.PathOp.intersect); + final path_ops.Path newBottomPath = + bottomPathOpsPath.applyOp(intersection, path_ops.PathOp.difference); + final path_ops.Path newTopPath = + topPathOpsPath.applyOp(intersection, path_ops.PathOp.difference); + + final Path newBottomVGPath = toVectorGraphicsPath(newBottomPath); + final Path newTopVGPath = toVectorGraphicsPath(newTopPath); + final Path newOverlapVGPath = toVectorGraphicsPath(intersection); + + final ResolvedPathNode newBottomPathNode = ResolvedPathNode( + paint: bottomPathNode.paint, + bounds: bottomPathNode.bounds, + path: newBottomVGPath); + final ResolvedPathNode newTopPathNode = ResolvedPathNode( + paint: topPathNode.paint, + bounds: bottomPathNode.bounds, + path: newTopVGPath); + final ResolvedPathNode newOverlapPathNode = ResolvedPathNode( + paint: Paint( + blendMode: bottomPathNode.paint.blendMode, + stroke: bottomPathNode.paint.stroke, + fill: Fill( + color: overlapColor, + shader: bottomPathNode.paint.fill?.shader)), + bounds: bottomPathNode.bounds, + path: newOverlapVGPath); + + bottomPathOpsPath.dispose(); + topPathOpsPath.dispose(); + intersection.dispose(); + newBottomPath.dispose(); + + return [ + newBottomPathNode, + newTopPathNode, + newOverlapPathNode + ]; + } + return [bottomPathNode, topPathNode]; + } + + /// Determines if node is optimizable. + bool isOptimizable(Node node) { + return node is ResolvedPathNode && + node.paint.stroke?.width == null && + node.paint.stroke?.color == null && + node.paint.fill?.shader == null; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitEmptyNode(Node node, void data) { + final _Result result = _Result(node); + return result; + } + + /// Visits applies optimizer to all children of ParentNode. + // ignore: library_private_types_in_public_api + _Result visitChildren(Node node, _Result data) { + if (node is ParentNode) { + data = node.accept(this, data); + } + return data; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitParentNode(ParentNode parentNode, Node data) { + int pathNodeCount = 0; + final List> newChildList = >[]; + final List newChildren = []; + + for (final Node child in parentNode.children) { + if (child is ResolvedPathNode) { + pathNodeCount++; + } + newChildList.add([child]); + } + + int index = 0; + ResolvedPathNode? lastPathNode; + int? lastPathNodeIndex; + + /// If the group opacity is set the children path nodes + /// cannot be optimized. + if (!parentNode.attributes.hasOpacity) { + /// If there are not at least 2 path nodes, an optimization cannot be + /// performed since 2 nodes are required for an 'overlap' to occur. + if (pathNodeCount >= 2) { + for (Node child in parentNode.children) { + if (isOptimizable(child)) { + child = child as ResolvedPathNode; + + /// If there is no previous path node to calculate + /// the overlap with, the current optimizable child will + /// be assigned as the lastPathNode. + if (lastPathNode == null || lastPathNodeIndex == null) { + lastPathNode = child; + lastPathNodeIndex = index; + } else { + /// If it is the case that the current node, which is + /// the "top" path, is opaque, the removeOverlap function + /// will be used. + if (child.paint.fill?.color.a == 255) { + newChildList[lastPathNodeIndex] = [ + removeOverlap(lastPathNode, child) + ]; + lastPathNode = child; + lastPathNodeIndex = index; + } else { + /// If it is the case that the current node, which is + /// the "top" path, is semi-transparent, the + /// resolveOpacityOverlap function will be used. + /// Note: The "top" and "intersection" path nodes that + /// are returned will not be further optimized. + newChildList[lastPathNodeIndex] = resolveOpacityOverlap( + newChildList[lastPathNodeIndex].first as ResolvedPathNode, + child); + newChildList[index] = []; + lastPathNode = null; + lastPathNodeIndex = null; + } + } + // } else { + // // Conservatively bail out here. There's some child that isn't + // // optimizable, and there aren't sufficient checks to make sure + // // we can make sense of what's actually going on anymore. + // return _Result(parentNode); + } + index++; + } + index = 0; + + /// Here the 2-dimensional list of new children is flattened. + for (final List child in newChildList) { + if (child.isNotEmpty) { + if (child.first is ResolvedPathNode) { + newChildren.addAll(child); + } else { + newChildren.add(child.first.accept(this, parentNode).node); + } + } + } + } else { + /// If there's less than 2 path nodes, the parent node's direct children + /// cannot be optimized, but it may have grand children that can be optimized, + /// so accept will be called on the children. + for (final Node child in parentNode.children) { + newChildren.add(child.accept(this, parentNode).node); + } + } + } else { + /// If group opacity is set, the parent nodes children cannot be optimized. + return _Result(parentNode); + } + final _Result result = _Result(ParentNode(parentNode.attributes, + children: newChildren, precalculatedTransform: parentNode.transform)); + + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitMaskNode(MaskNode maskNode, Node data) { + return _Result(maskNode); + } + + @override + // ignore: library_private_types_in_public_api + _Result visitPathNode(PathNode pathNode, Node data) { + return _Result(pathNode); + } + + @override + // ignore: library_private_types_in_public_api + _Result visitResolvedMaskNode(ResolvedMaskNode maskNode, void data) { + final _Result childResult = maskNode.child.accept(this, maskNode); + final ResolvedMaskNode newMaskNode = ResolvedMaskNode( + child: childResult.node, + mask: maskNode.mask, + blendMode: maskNode.blendMode); + final _Result result = _Result(newMaskNode); + result.children.add(childResult.node); + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitResolvedClipNode(ResolvedClipNode clipNode, Node data) { + final _Result childResult = clipNode.child.accept(this, clipNode); + final ResolvedClipNode newClipNode = + ResolvedClipNode(clips: clipNode.clips, child: childResult.node); + final _Result result = _Result(newClipNode); + result.children.add(childResult.node); + + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitResolvedPath(ResolvedPathNode pathNode, Node data) { + return _Result(pathNode); + } + + @override + // ignore: library_private_types_in_public_api + _Result visitResolvedText(ResolvedTextNode textNode, Node data) { + return _Result(textNode); + } + + @override + // ignore: library_private_types_in_public_api + _Result visitResolvedVerticesNode( + ResolvedVerticesNode verticesNode, Node data) { + return _Result(verticesNode); + } + + @override + // ignore: library_private_types_in_public_api + _Result visitSaveLayerNode(SaveLayerNode layerNode, Node data) { + final List newChildren = []; + for (final Node child in layerNode.children) { + final _Result childResult = child.accept(this, layerNode); + newChildren.add(childResult.node); + } + final SaveLayerNode newLayerNode = SaveLayerNode(layerNode.attributes, + paint: layerNode.paint, children: newChildren); + + final _Result result = _Result(newLayerNode); + result.children.addAll(newChildren); + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitResolvedImageNode( + ResolvedImageNode resolvedImageNode, Node data) { + return _Result(resolvedImageNode); + } + + @override + // ignore: library_private_types_in_public_api + _Result visitViewportNode(ViewportNode viewportNode, void data) { + final List children = []; + + final ParentNode parentNode = ParentNode(SvgAttributes.empty, + children: viewportNode.children.toList()); + + final _Result childResult = parentNode.accept(this, viewportNode); + children.addAll((childResult.node as ParentNode).children); + + final ViewportNode node = ViewportNode( + viewportNode.attributes, + width: viewportNode.width, + height: viewportNode.height, + transform: viewportNode.transform, + children: children, + ); + + final _Result result = _Result(node); + result.children.addAll(children); + return result; + } + + @override + // ignore: library_private_types_in_public_api + _Result visitResolvedPatternNode(ResolvedPatternNode patternNode, Node data) { + return _Result(patternNode); + } + + @override + // ignore: library_private_types_in_public_api + _Result visitResolvedTextPositionNode( + ResolvedTextPositionNode textPositionNode, void data) { + return _Result( + ResolvedTextPositionNode( + textPositionNode.textPosition, + [ + for (final Node child in textPositionNode.children) + child.accept(this, data).node + ], + ), + ); + } +} diff --git a/packages/vector_graphics_compiler/lib/src/svg/parser.dart b/packages/vector_graphics_compiler/lib/src/svg/parser.dart new file mode 100644 index 000000000000..6cac8884d7fb --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/svg/parser.dart @@ -0,0 +1,2453 @@ +// 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: avoid_print + +import 'dart:collection'; +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:meta/meta.dart'; +import 'package:xml/xml_events.dart'; + +import '../geometry/basic_types.dart'; +import '../geometry/matrix.dart'; +import '../geometry/path.dart'; +import '../image/image_info.dart'; +import '../paint.dart'; +import '../vector_instructions.dart'; +import 'clipping_optimizer.dart'; +import 'color_mapper.dart'; +import 'colors.dart'; +import 'masking_optimizer.dart'; +import 'node.dart'; +import 'numbers.dart' as numbers show parseDoubleWithUnits; +import 'numbers.dart' hide parseDoubleWithUnits; +import 'overdraw_optimizer.dart'; +import 'parsers.dart'; +import 'path_ops.dart' as path_ops; +import 'resolver.dart'; +import 'tessellator.dart'; +import 'theme.dart'; +import 'visitor.dart'; + +final Set _unhandledElements = {'title', 'desc'}; + +typedef _ParseFunc = void Function( + SvgParser parserState, bool warningsAsErrors); +typedef _PathFunc = Path? Function(SvgParser parserState); + +final RegExp _whitespacePattern = RegExp(r'\s'); + +const Map _svgElementParsers = { + 'svg': _Elements.svg, + 'g': _Elements.g, + 'a': _Elements.g, // treat as group + 'use': _Elements.use, + 'symbol': _Elements.symbol, + 'mask': _Elements.symbol, // treat as symbol + 'pattern': _Elements.pattern, + 'radialGradient': _Elements.radialGradient, + 'linearGradient': _Elements.linearGradient, + 'clipPath': _Elements.clipPath, + 'image': _Elements.image, + 'text': _Elements.textOrTspan, + 'tspan': _Elements.textOrTspan, +}; + +const Map _svgPathFuncs = { + 'circle': _Paths.circle, + 'path': _Paths.path, + 'rect': _Paths.rect, + 'polygon': _Paths.polygon, + 'polyline': _Paths.polyline, + 'ellipse': _Paths.ellipse, + 'line': _Paths.line, +}; + +// ignore: avoid_classes_with_only_static_members +class _Elements { + static void svg(SvgParser parserState, bool warningsAsErrors) { + final _Viewport viewBox = parserState._parseViewBox(); + + // TODO(dnfield): Support nested SVG elements. https://github.com/dnfield/flutter_svg/issues/132 + if (parserState._root != null) { + const String errorMessage = 'Unsupported nested element.'; + if (warningsAsErrors) { + throw UnsupportedError(errorMessage); + } + parserState._parentDrawables.addLast( + _SvgGroupTuple( + 'svg', + ViewportNode( + parserState._currentAttributes, + width: viewBox.width, + height: viewBox.height, + transform: viewBox.transform, + ), + ), + ); + return; + } + parserState._root = ViewportNode( + parserState._currentAttributes, + width: viewBox.width, + height: viewBox.height, + transform: viewBox.transform, + ); + parserState.addGroup(parserState._currentStartElement!, parserState._root!); + return; + } + + static void g(SvgParser parserState, bool warningsAsErrors) { + if (parserState._currentStartElement?.isSelfClosing ?? false) { + return; + } + final ParentNode parent = parserState.currentGroup!; + + final ParentNode group = ParentNode(parserState._currentAttributes); + + parent.addChild( + group, + clipId: parserState._currentAttributes.clipPathId, + clipResolver: parserState._definitions.getClipPath, + maskId: parserState.attribute('mask'), + maskResolver: parserState._definitions.getDrawable, + patternId: parserState._definitions.getPattern(parserState), + patternResolver: parserState._definitions.getDrawable, + ); + parserState.addGroup(parserState._currentStartElement!, group); + return; + } + + static void textOrTspan(SvgParser parserState, bool warningsAsErrors) { + if (parserState._currentStartElement?.isSelfClosing ?? false) { + return; + } + final ParentNode parent = parserState.currentGroup!; + final XmlStartElementEvent element = parserState._currentStartElement!; + + final TextPositionNode group = TextPositionNode( + parserState._currentAttributes, + reset: element.localName == 'text', + ); + + parent.addChild( + group, + clipId: parserState._currentAttributes.clipPathId, + clipResolver: parserState._definitions.getClipPath, + maskId: parserState.attribute('mask'), + maskResolver: parserState._definitions.getDrawable, + patternId: parserState._definitions.getPattern(parserState), + patternResolver: parserState._definitions.getDrawable, + ); + parserState.addGroup(element, group); + return; + } + + static void symbol(SvgParser parserState, bool warningsAsErrors) { + final ParentNode group = ParentNode(parserState._currentAttributes); + parserState.addGroup(parserState._currentStartElement!, group); + return; + } + + static void pattern(SvgParser parserState, bool warningsAsErrors) { + final SvgAttributes attributes = parserState._currentAttributes; + final String rawWidth = parserState.attribute('width') ?? ''; + final String rawHeight = parserState.attribute('height') ?? ''; + + double? patternWidth = + parsePatternUnitToDouble(rawWidth, 'width', viewBox: parserState._root); + double? patternHeight = parsePatternUnitToDouble(rawHeight, 'height', + viewBox: parserState._root); + + if (patternWidth == null || patternHeight == null) { + final _Viewport viewBox = parserState._parseViewBox(); + patternWidth = viewBox.width; + patternHeight = viewBox.height; + } + + final String? rawX = attributes.raw['x']; + final String? rawY = attributes.raw['y']; + final String id = parserState.buildUrlIri(); + parserState.patternIds.add(id); + final SvgAttributes newAttributes = SvgAttributes._( + raw: attributes.raw, + id: attributes.id, + href: attributes.href, + transform: attributes.transform, + color: attributes.color, + stroke: attributes.stroke, + fill: attributes.fill, + fillRule: attributes.fillRule, + clipRule: attributes.clipRule, + clipPathId: attributes.clipPathId, + blendMode: attributes.blendMode, + fontFamily: attributes.fontFamily, + fontWeight: attributes.fontWeight, + fontSize: attributes.fontSize, + x: DoubleOrPercentage.fromString(rawX), + y: DoubleOrPercentage.fromString(rawY), + width: patternWidth, + height: patternHeight); + + final ParentNode group = ParentNode(newAttributes); + parserState.addGroup(parserState._currentStartElement!, group); + return; + } + + static void use(SvgParser parserState, bool warningsAsErrors) { + final ParentNode? parent = parserState.currentGroup; + final String? xlinkHref = parserState._currentAttributes.href; + if (xlinkHref == null || xlinkHref.isEmpty) { + return; + } + + final AffineMatrix transform = + (parseTransform(parserState.attribute('transform')) ?? + AffineMatrix.identity) + .translated( + parserState.parseDoubleWithUnits( + parserState.attribute('x', def: '0'), + )!, + parserState.parseDoubleWithUnits( + parserState.attribute('y', def: '0'), + )!, + ); + + final ParentNode group = ParentNode( + // parserState._currentAttributes, + SvgAttributes.empty, + precalculatedTransform: transform, + ); + + group.addChild( + DeferredNode( + parserState._currentAttributes, + refId: 'url($xlinkHref)', + resolver: parserState._definitions.getDrawable, + ), + clipResolver: parserState._definitions.getClipPath, + maskResolver: parserState._definitions.getDrawable, + patternResolver: parserState._definitions.getDrawable, + ); + if ('#${parserState._currentAttributes.id}' != xlinkHref) { + parserState.checkForIri(group); + } + parent!.addChild( + group, + clipId: parserState._currentAttributes.clipPathId, + clipResolver: parserState._definitions.getClipPath, + maskId: parserState.attribute('mask'), + maskResolver: parserState._definitions.getDrawable, + patternId: parserState._definitions.getPattern(parserState), + patternResolver: parserState._definitions.getDrawable, + ); + return; + } + + static void parseStops( + SvgParser parserState, + List colors, + List offsets, + ) { + for (final XmlEvent event in parserState._readSubtree()) { + if (event is XmlEndElementEvent) { + continue; + } + if (event is XmlStartElementEvent) { + final String rawOpacity = parserState.attribute( + 'stop-opacity', + def: '1', + )!; + final Color stopColor = parserState.parseColor( + parserState.attribute('stop-color'), + attributeName: 'stop-color', + id: parserState._currentAttributes.id) ?? + Color.opaqueBlack; + colors.add(stopColor.withOpacity(parseDouble(rawOpacity)!)); + + final String rawOffset = parserState.attribute( + 'offset', + def: '0%', + )!; + offsets.add(parseDecimalOrPercentage(rawOffset)); + } + } + return; + } + + static void radialGradient( + SvgParser parserState, + bool warningsAsErrors, + ) { + final GradientUnitMode? unitMode = parserState.parseGradientUnitMode(); + final String? rawCx = parserState.attribute('cx', def: '50%'); + final String? rawCy = parserState.attribute('cy', def: '50%'); + final String? rawR = parserState.attribute('r', def: '50%'); + final String? rawFx = parserState.attribute('fx', def: rawCx); + final String? rawFy = parserState.attribute('fy', def: rawCy); + final TileMode? spreadMethod = parserState.parseTileMode(); + final String id = parserState.buildUrlIri(); + final AffineMatrix? originalTransform = parseTransform( + parserState.attribute('gradientTransform'), + ); + + List? offsets; + List? colors; + + final bool defer = parserState._currentStartElement!.isSelfClosing; + if (!defer) { + offsets = []; + colors = []; + parseStops(parserState, colors, offsets); + } + + final double cx = parseDecimalOrPercentage(rawCx!); + final double cy = parseDecimalOrPercentage(rawCy!); + final double r = parseDecimalOrPercentage(rawR!); + final double fx = parseDecimalOrPercentage(rawFx!); + final double fy = parseDecimalOrPercentage(rawFy!); + + parserState._definitions.addGradient( + RadialGradient( + id: id, + center: Point(cx, cy), + radius: r, + focalPoint: (fx != cx || fy != cy) ? Point(fx, fy) : null, + colors: colors, + offsets: offsets, + unitMode: unitMode, + tileMode: spreadMethod, + transform: originalTransform, + ), + parserState._currentAttributes.href, + ); + return; + } + + static void linearGradient( + SvgParser parserState, + bool warningsAsErrors, + ) { + final GradientUnitMode? unitMode = parserState.parseGradientUnitMode(); + final String x1 = parserState.attribute('x1', def: '0%')!; + final String x2 = parserState.attribute('x2', def: '100%')!; + final String y1 = parserState.attribute('y1', def: '0%')!; + final String y2 = parserState.attribute('y2', def: '0%')!; + final String id = parserState.buildUrlIri(); + final AffineMatrix? originalTransform = parseTransform( + parserState.attribute('gradientTransform'), + ); + final TileMode? spreadMethod = parserState.parseTileMode(); + + List? offsets; + List? colors; + + final bool defer = parserState._currentStartElement!.isSelfClosing; + if (!defer) { + offsets = []; + colors = []; + parseStops(parserState, colors, offsets); + } + + final Point fromPoint = Point( + parseDecimalOrPercentage(x1), + parseDecimalOrPercentage(y1), + ); + final Point toPoint = Point( + parseDecimalOrPercentage(x2), + parseDecimalOrPercentage(y2), + ); + + parserState._definitions.addGradient( + LinearGradient( + id: id, + from: fromPoint, + to: toPoint, + colors: colors, + offsets: offsets, + tileMode: spreadMethod, + unitMode: unitMode, + transform: originalTransform, + ), + parserState._currentAttributes.href, + ); + + return; + } + + static void clipPath(SvgParser parserState, bool warningsAsErrors) { + final String id = parserState.buildUrlIri(); + final List pathNodes = []; + for (final XmlEvent event in parserState._readSubtree()) { + if (event is XmlEndElementEvent) { + continue; + } + if (event is XmlStartElementEvent) { + final _PathFunc? pathFn = _svgPathFuncs[event.name]; + + if (pathFn != null) { + final Path sourcePath = parserState.applyTransformIfNeeded( + pathFn(parserState)!, + parserState.currentGroup?.transform, + ); + pathNodes.add( + PathNode( + Path( + commands: sourcePath.commands.toList(), + fillType: parserState._currentAttributes.clipRule ?? + PathFillType.nonZero, + ), + parserState._currentAttributes, + ), + ); + } else if (event.name == 'use') { + final String? xlinkHref = parserState._currentAttributes.href; + pathNodes.add( + DeferredNode( + parserState._currentAttributes, + refId: 'url($xlinkHref)', + resolver: parserState._definitions.getDrawable, + ), + ); + } else { + final String errorMessage = + 'Unsupported clipPath child ${event.name}'; + if (warningsAsErrors) { + throw UnsupportedError(errorMessage); + } + } + } + } + parserState._definitions.addClipPath( + id, + pathNodes, + ); + return; + } + + static void image( + SvgParser parserState, + bool warningsAsErrors, + ) { + final String? xlinkHref = parserState._currentAttributes.href; + if (xlinkHref == null) { + return; + } + + if (xlinkHref.startsWith('data:')) { + const Map supportedMimeTypes = { + 'png': ImageFormat.png, + 'jpeg': ImageFormat.jpeg, + 'jpg': ImageFormat.jpeg, + 'webp': ImageFormat.webp, + 'gif': ImageFormat.gif, + 'bmp': ImageFormat.bmp, + }; + final int semiColonLocation = xlinkHref.indexOf(';') + 1; + final int commaLocation = xlinkHref.indexOf(',', semiColonLocation) + 1; + final String mimeType = xlinkHref + .substring(xlinkHref.indexOf('/') + 1, semiColonLocation - 1) + .replaceAll(_whitespacePattern, '') + .toLowerCase(); + + final ImageFormat? format = supportedMimeTypes[mimeType]; + if (format == null) { + if (warningsAsErrors) { + throw UnimplementedError( + 'Image data format not supported: $mimeType'); + } else { + print('Warning: Unsupported image format $mimeType'); + } + return; + } + + final Uint8List data = base64.decode(xlinkHref + .substring(commaLocation) + .replaceAll(_whitespacePattern, '')); + final ImageNode image = + ImageNode(data, format, parserState._currentAttributes); + parserState.currentGroup!.addChild( + image, + clipResolver: parserState._definitions.getClipPath, + maskResolver: parserState._definitions.getDrawable, + patternResolver: parserState._definitions.getDrawable, + ); + parserState.checkForIri(image); + return; + } + if (warningsAsErrors) { + throw UnimplementedError('Image data format not supported: $xlinkHref'); + } + return; + } +} + +// ignore: avoid_classes_with_only_static_members +class _Paths { + static Path circle(SvgParser parserState) { + final double cx = parserState.parseDoubleWithUnits( + parserState.attribute('cx', def: '0'), + )!; + final double cy = parserState.parseDoubleWithUnits( + parserState.attribute('cy', def: '0'), + )!; + final double r = parserState.parseDoubleWithUnits( + parserState.attribute('r', def: '0'), + )!; + final Rect oval = Rect.fromCircle(cx, cy, r); + return PathBuilder(parserState._currentAttributes.fillRule) + .addOval(oval) + .toPath(); + } + + static Path path(SvgParser parserState) { + final String d = parserState.attribute('d', def: '')!; + return parseSvgPathData(d, parserState._currentAttributes.fillRule); + } + + static Path rect(SvgParser parserState) { + final double x = parserState.parseDoubleWithUnits( + parserState.attribute('x', def: '0'), + )!; + final double y = parserState.parseDoubleWithUnits( + parserState.attribute('y', def: '0'), + )!; + final double w = parserState.parseDoubleWithUnits( + parserState.attribute('width', def: '0'), + )!; + final double h = parserState.parseDoubleWithUnits( + parserState.attribute('height', def: '0'), + )!; + String? rxRaw = parserState.attribute('rx'); + String? ryRaw = parserState.attribute('ry'); + rxRaw ??= ryRaw; + ryRaw ??= rxRaw; + + if (rxRaw != null && rxRaw != '') { + final double rx = parserState.parseDoubleWithUnits(rxRaw)!; + final double ry = parserState.parseDoubleWithUnits(ryRaw)!; + return PathBuilder(parserState._currentAttributes.fillRule) + .addRRect(Rect.fromLTWH(x, y, w, h), rx, ry) + .toPath(); + } + + return PathBuilder(parserState._currentAttributes.fillRule) + .addRect(Rect.fromLTWH(x, y, w, h)) + .toPath(); + } + + static Path? polygon(SvgParser parserState) { + return parsePathFromPoints(parserState, true); + } + + static Path? polyline(SvgParser parserState) { + return parsePathFromPoints(parserState, false); + } + + static Path? parsePathFromPoints(SvgParser parserState, bool close) { + final String points = parserState.attribute('points', def: '')!; + if (points == '') { + return null; + } + final String path = 'M$points${close ? 'z' : ''}'; + + return parseSvgPathData(path, parserState._currentAttributes.fillRule); + } + + static Path ellipse(SvgParser parserState) { + final double cx = parserState.parseDoubleWithUnits( + parserState.attribute('cx', def: '0'), + )!; + final double cy = parserState.parseDoubleWithUnits( + parserState.attribute('cy', def: '0'), + )!; + final double rx = parserState.parseDoubleWithUnits( + parserState.attribute('rx', def: '0'), + )!; + final double ry = parserState.parseDoubleWithUnits( + parserState.attribute('ry', def: '0'), + )!; + + final Rect r = Rect.fromLTWH(cx - rx, cy - ry, rx * 2, ry * 2); + return PathBuilder(parserState._currentAttributes.fillRule) + .addOval(r) + .toPath(); + } + + static Path line(SvgParser parserState) { + final double x1 = parserState.parseDoubleWithUnits( + parserState.attribute('x1', def: '0'), + )!; + final double x2 = parserState.parseDoubleWithUnits( + parserState.attribute('x2', def: '0'), + )!; + final double y1 = parserState.parseDoubleWithUnits( + parserState.attribute('y1', def: '0'), + )!; + final double y2 = parserState.parseDoubleWithUnits( + parserState.attribute('y2', def: '0'), + )!; + + return PathBuilder(parserState._currentAttributes.fillRule) + .moveTo(x1, y1) + .lineTo(x2, y2) + .toPath(); + } +} + +class _SvgGroupTuple { + _SvgGroupTuple(this.name, this.drawable); + + final String name; + final ParentNode drawable; +} + +/// Parse an SVG to the initial Node tree. +@visibleForTesting +Node parseToNodeTree(String source) { + return SvgParser(source, const SvgTheme(), null, true, null) + ._parseToNodeTree(); +} + +/// Reads an SVG XML string and via the [parse] method creates a set of +/// [VectorInstructions]. +class SvgParser { + /// Creates a new [SvgParser]. + SvgParser( + String xml, + this.theme, + this._key, + this._warningsAsErrors, + this._colorMapper, + ) : _eventIterator = parseEvents(xml).iterator; + + /// The theme used when parsing SVG elements. + final SvgTheme theme; + + final ColorMapper? _colorMapper; + + final Iterator _eventIterator; + final String? _key; + final bool _warningsAsErrors; + final _Resolver _definitions = _Resolver(); + final Queue<_SvgGroupTuple> _parentDrawables = ListQueue<_SvgGroupTuple>(10); + + /// Toggles whether [MaskingOptimizer] is enabled or disabled. + bool enableMaskingOptimizer = true; + + /// Toggles whether [ClippingOptimizer] is enabled or disabled. + bool enableClippingOptimizer = true; + + /// Toggles whether [OverdrawOptimizer] is enabled or disabled. + bool enableOverdrawOptimizer = true; + + /// List of known patternIds. + Set patternIds = {}; + + ViewportNode? _root; + SvgAttributes _currentAttributes = SvgAttributes.empty; + XmlStartElementEvent? _currentStartElement; + + /// The current depth of the reader in the XML hierarchy. + int depth = 0; + + void _discardSubtree() { + final int subtreeStartDepth = depth; + while (_eventIterator.moveNext()) { + final XmlEvent event = _eventIterator.current; + if (event is XmlStartElementEvent && !event.isSelfClosing) { + depth += 1; + } else if (event is XmlEndElementEvent) { + depth -= 1; + assert(depth >= 0); + } + _currentAttributes = SvgAttributes.empty; + _currentStartElement = null; + if (depth < subtreeStartDepth) { + return; + } + } + } + + XmlEndElementEvent? _lastEndElementEvent; + + Iterable _readSubtree() sync* { + final int subtreeStartDepth = depth; + while (_eventIterator.moveNext()) { + final XmlEvent event = _eventIterator.current; + bool isSelfClosing = false; + if (event is XmlStartElementEvent) { + final Map attributeMap = + _createAttributeMap(event.attributes); + if (!_isVisible(attributeMap)) { + if (!event.isSelfClosing) { + depth += 1; + _discardSubtree(); + } + continue; + } + _currentStartElement = event; + _currentAttributes = _createSvgAttributes( + attributeMap, + currentColor: depth == 0 ? theme.currentColor : null, + ); + depth += 1; + isSelfClosing = event.isSelfClosing; + } + yield event; + + if (isSelfClosing || event is XmlEndElementEvent) { + depth -= 1; + assert(depth >= 0); + _currentAttributes = SvgAttributes.empty; + _currentStartElement = null; + } + if (depth < subtreeStartDepth) { + return; + } + } + } + + static final RegExp _contiguousSpaceMatcher = RegExp(r' +'); + bool _lastTextEndedWithSpace = false; + void _appendText(String text) { + assert(_inTextOrTSpan); + + assert(_whitespacePattern.pattern == r'\s'); + final bool textHasNonWhitespace = text.trim() != ''; + + // Not from the spec, but seems like how Chrome behaves. + // - If `x` is specified, don't prepend whitespace. + // - If the last element was a tspan and we're dealing with some + // non-whitespace data, prepend a space. + // - If the last text wasn't whitespace and ended with whitespace, prepend + // a space. + final bool prependSpace = _currentAttributes.x == null && + (_lastEndElementEvent?.localName == 'tspan' && + textHasNonWhitespace) || + _lastTextEndedWithSpace; + + _lastTextEndedWithSpace = textHasNonWhitespace && + text.startsWith(_whitespacePattern, text.length - 1); + + // From the spec: + // First, it will remove all newline characters. + // Then it will convert all tab characters into space characters. + // Then, it will strip off all leading and trailing space characters. + // Then, all contiguous space characters will be consolidated. + text = text + .replaceAll('\n', '') + .replaceAll('\t', ' ') + .trim() + .replaceAll(_contiguousSpaceMatcher, ' '); + + if (text.isEmpty) { + return; + } + + currentGroup?.addChild( + TextNode( + prependSpace ? ' $text' : text, + _currentAttributes, + ), + // Do not supply pattern/clip/mask IDs, those are handled by the group + // text or tspan this text is part of. + clipResolver: _definitions.getClipPath, + maskResolver: _definitions.getDrawable, + patternResolver: _definitions.getDrawable, + ); + } + + bool get _inTextOrTSpan => + _parentDrawables.isNotEmpty && + (_parentDrawables.last.name == 'text' || + _parentDrawables.last.name == 'tspan'); + + void _parseTree() { + for (final XmlEvent event in _readSubtree()) { + if (event is XmlStartElementEvent) { + if (startElement(event)) { + continue; + } + final _ParseFunc? parseFunc = _svgElementParsers[event.name]; + if (parseFunc == null) { + if (!event.isSelfClosing) { + _discardSubtree(); + } + assert(() { + unhandledElement(event); + return true; + }()); + } else { + parseFunc(this, _warningsAsErrors); + } + } else if (event is XmlEndElementEvent) { + endElement(event); + } else if (_inTextOrTSpan) { + if (event is XmlCDATAEvent) { + _appendText(event.value); + } else if (event is XmlTextEvent) { + _appendText(event.value); + } + } + } + if (_root == null) { + throw StateError('Invalid SVG data'); + } + _definitions._seal(); + } + + /// Drive the XML reader to EOF and produce [VectorInstructions]. + VectorInstructions parse() { + _parseTree(); + + /// Resolve the tree + final ResolvingVisitor resolvingVisitor = ResolvingVisitor(); + final Tessellator tessellator = Tessellator(); + final MaskingOptimizer maskingOptimizer = MaskingOptimizer(); + final ClippingOptimizer clippingOptimizer = ClippingOptimizer(); + final OverdrawOptimizer overdrawOptimizer = OverdrawOptimizer(); + + Node newRoot = _root!.accept(resolvingVisitor, AffineMatrix.identity); + + // The order of these matters. The overdraw optimizer can do its best if + // masks and unnecessary clips have been eliminated. + if (enableMaskingOptimizer) { + if (path_ops.isPathOpsInitialized) { + newRoot = maskingOptimizer.apply(newRoot); + } else { + throw Exception('PathOps library was not initialized.'); + } + } + + if (enableClippingOptimizer) { + if (path_ops.isPathOpsInitialized) { + newRoot = clippingOptimizer.apply(newRoot); + } else { + throw Exception('PathOps library was not initialized.'); + } + } + + if (enableOverdrawOptimizer) { + if (path_ops.isPathOpsInitialized) { + newRoot = overdrawOptimizer.apply(newRoot); + } else { + throw Exception('PathOps library was not initialized.'); + } + } + + if (isTesselatorInitialized) { + newRoot = newRoot.accept(tessellator, null); + } + + /// Convert to vector instructions + final CommandBuilderVisitor commandVisitor = CommandBuilderVisitor(); + newRoot.accept(commandVisitor, null); + + return commandVisitor.toInstructions(); + } + + Node _parseToNodeTree() { + _parseTree(); + return _root!; + } + + /// Gets the attribute for the current position of the parser. + String? attribute(String name, {String? def}) => + _currentAttributes.raw[name] ?? def; + + /// The current group, if any, in the [Drawable] heirarchy. + ParentNode? get currentGroup { + assert(_parentDrawables.isNotEmpty); + return _parentDrawables.last.drawable; + } + + /// The root bounds of the drawable. + Rect get rootBounds { + assert(_root != null, 'Cannot get rootBounds with null root'); + return _root!.viewport; + } + + /// Whether this [DrawableStyleable] belongs in the [DrawableDefinitions] or not. + bool checkForIri(AttributedNode drawable) { + assert('#${_currentAttributes.id}' != _currentAttributes.href); + final String iri = buildUrlIri(); + if (iri != emptyUrlIri) { + _definitions.addDrawable(iri, drawable); + return true; + } + return false; + } + + /// Appends a group to the collection. + void addGroup(XmlStartElementEvent event, ParentNode drawable) { + _parentDrawables.addLast(_SvgGroupTuple(event.name, drawable)); + checkForIri(drawable); + } + + /// Updates the [VectorInstructions] with the current path and paint. + bool addShape(XmlStartElementEvent event) { + final _PathFunc? pathFunc = _svgPathFuncs[event.name]; + if (pathFunc == null) { + return false; + } + final ParentNode parent = _parentDrawables.last.drawable; + final Path path = pathFunc(this)!; + final PathNode drawable = PathNode(path, _currentAttributes); + checkForIri(drawable); + + parent.addChild( + drawable, + clipId: _currentAttributes.clipPathId, + clipResolver: _definitions.getClipPath, + maskId: attribute('mask'), + maskResolver: _definitions.getDrawable, + patternId: _definitions.getPattern(this), + patternResolver: _definitions.getDrawable, + ); + return true; + } + + /// Potentially handles a starting element, if it was a singular shape or a + /// `` element. + bool startElement(XmlStartElementEvent event) { + if (event.name == 'defs') { + if (!event.isSelfClosing) { + addGroup( + event, + ParentNode(_currentAttributes), + ); + return true; + } + } + return addShape(event); + } + + /// Handles the end of an XML element. + void endElement(XmlEndElementEvent event) { + while (event.name == _parentDrawables.last.name && + _parentDrawables.last.drawable is ClipNode) { + _parentDrawables.removeLast(); + } + if (event.name == _parentDrawables.last.name) { + _parentDrawables.removeLast(); + } + _lastEndElementEvent = event; + if (event.name == 'text') { + // reset state. + _lastTextEndedWithSpace = false; + } + } + + /// Prints an error for unhandled elements. + /// + /// Will only print an error once for unhandled/unexpected elements, except for + /// ``, ``, and `` elements. + void unhandledElement(XmlStartElementEvent event) { + final String errorMessage = + 'unhandled element <${event.name}/>; Picture key: $_key'; + if (_warningsAsErrors) { + // Throw error instead of log warning. + throw UnimplementedError(errorMessage); + } + if (_unhandledElements.add(event.name)) { + print(errorMessage); + } + } + + /// Parses a `rawDouble` `String` to a `double` + /// taking into account absolute and relative units + /// (`px`, `em` or `ex`). + /// + /// Passing an `em` value will calculate the result + /// relative to the provided [fontSize]: + /// 1 em = 1 * `fontSize`. + /// + /// Passing an `ex` value will calculate the result + /// relative to the provided [xHeight]: + /// 1 ex = 1 * `xHeight`. + /// + /// The `rawDouble` might include a unit which is + /// stripped off when parsed to a `double`. + /// + /// Passing `null` will return `null`. + double? parseDoubleWithUnits( + String? rawDouble, { + bool tryParse = false, + }) { + return numbers.parseDoubleWithUnits( + rawDouble, + tryParse: tryParse, + theme: theme, + ); + } + + static final Map _kTextSizeMap = { + 'xx-small': 10, + 'x-small': 12, + 'small': 14, + 'medium': 18, + 'large': 22, + 'x-large': 26, + 'xx-large': 32, + }; + + /// Parses a `font-size` attribute. + double? parseFontSize(String? raw) { + if (raw == null || raw == '') { + return null; + } + + double? ret = parseDoubleWithUnits( + raw, + tryParse: true, + ); + if (ret != null) { + return ret; + } + + raw = raw.toLowerCase().trim(); + ret = _kTextSizeMap[raw]; + if (ret != null) { + return ret; + } + + // TODO(dnfield): support 'larger' and 'smaller'. + // Rough idea for how to do this: this method returns a struct that contains + // either a double? fontSize or a double? multiplier. + // Larger multiplier: 1.2 + // Smaller multiplier: .8 + // When resolving the font size later, multiple the incoming size by the + // multiplier if specified. + // There was once an implementation of this which was definitely not + // correct but probably not used much either. + + throw StateError('Could not parse font-size: $raw'); + } + + /// Parses a `text-decoration` attribute value into a [TextDecoration]. + TextDecoration? parseTextDecoration(String? textDecoration) { + if (textDecoration == null) { + return null; + } + switch (textDecoration) { + case 'none': + return TextDecoration.none; + case 'underline': + return TextDecoration.underline; + case 'overline': + return TextDecoration.overline; + case 'line-through': + return TextDecoration.lineThrough; + } + throw UnsupportedError( + 'Attribute value for text-decoration="$textDecoration"' + ' is not supported'); + } + + /// Parses a `text-decoration-style` attribute value into a [TextDecorationStyle]. + TextDecorationStyle? parseTextDecorationStyle(String? textDecorationStyle) { + if (textDecorationStyle == null) { + return null; + } + switch (textDecorationStyle) { + case 'solid': + return TextDecorationStyle.solid; + case 'dashed': + return TextDecorationStyle.dashed; + case 'dotted': + return TextDecorationStyle.dotted; + case 'double': + return TextDecorationStyle.double; + case 'wavy': + return TextDecorationStyle.wavy; + } + throw UnsupportedError( + 'Attribute value for text-decoration-style="$textDecorationStyle"' + ' is not supported'); + } + + /// Parses a `text-anchor` attribute. + double? parseTextAnchor(String? raw) { + switch (raw) { + case 'end': + return 1; + case 'middle': + return .5; + case 'start': + return 0; + case 'inherit': + default: + return null; + } + } + + double _parseRawWidthHeight(String raw) { + if (raw == '100%' || raw == '') { + return double.infinity; + } + assert(() { + final RegExp notDigits = RegExp(r'[^\d\.]'); + if (!raw.endsWith('px') && + !raw.endsWith('em') && + !raw.endsWith('ex') && + raw.contains(notDigits)) { + print( + 'Warning: Flutter SVG only supports the following formats for `width` and `height` on the SVG root:\n' + ' width="100%"\n' + ' width="100em"\n' + ' width="100ex"\n' + ' width="100px"\n' + ' width="100" (where the number will be treated as pixels).\n' + 'The supplied value ($raw) will be discarded and treated as if it had not been specified.'); + } + return true; + }()); + return parseDoubleWithUnits(raw, tryParse: true) ?? double.infinity; + } + + /// Parses an SVG @viewBox attribute (e.g. 0 0 100 100) to a [Viewport]. + _Viewport _parseViewBox() { + final String viewBox = attribute('viewBox') ?? ''; + final String rawWidth = attribute('width') ?? ''; + final String rawHeight = attribute('height') ?? ''; + + if (viewBox == '' && rawWidth == '' && rawHeight == '') { + throw StateError('SVG did not specify dimensions\n\n' + 'The SVG library looks for a `viewBox` or `width` and `height` attribute ' + 'to determine the viewport boundary of the SVG. Note that these attributes, ' + 'as with all SVG attributes, are case sensitive.\n' + 'During processing, the following attributes were found:\n' + ' ${_currentAttributes.raw}'); + } + + if (viewBox == '') { + final double width = _parseRawWidthHeight(rawWidth); + final double height = _parseRawWidthHeight(rawHeight); + return _Viewport( + width, + height, + AffineMatrix.identity, + ); + } + + final List parts = viewBox.split(RegExp(r'[ ,]+')); + if (parts.length < 4) { + throw StateError('viewBox element must be 4 elements long'); + } + final double width = parseDouble(parts[2])!; + final double height = parseDouble(parts[3])!; + final double translateX = -parseDouble(parts[0])!; + final double translateY = -parseDouble(parts[1])!; + + return _Viewport( + width, + height, + AffineMatrix.identity.translated(translateX, translateY), + ); + } + + /// Builds an IRI in the form of `'url(#id)'`. + String buildUrlIri() => 'url(#${_currentAttributes.id})'; + + /// An empty IRI. + static const String emptyUrlIri = _Resolver.emptyUrlIri; + + /// Parses a `spreadMethod` attribute into a [TileMode]. + TileMode? parseTileMode() { + final String? spreadMethod = attribute('spreadMethod'); + switch (spreadMethod) { + case 'pad': + return TileMode.clamp; + case 'repeat': + return TileMode.repeated; + case 'reflect': + return TileMode.mirror; + } + return null; + } + + /// Parses the `@gradientUnits` attribute. + GradientUnitMode? parseGradientUnitMode() { + final String? gradientUnits = attribute('gradientUnits'); + switch (gradientUnits) { + case 'userSpaceOnUse': + return GradientUnitMode.userSpaceOnUse; + case 'objectBoundingBox': + return GradientUnitMode.objectBoundingBox; + } + return null; + } + + StrokeCap? _parseCap( + String? raw, + Stroke? definitionPaint, + ) { + switch (raw) { + case 'butt': + return StrokeCap.butt; + case 'round': + return StrokeCap.round; + case 'square': + return StrokeCap.square; + default: + return definitionPaint?.cap; + } + } + + StrokeJoin? _parseJoin( + String? raw, + Stroke? definitionPaint, + ) { + switch (raw) { + case 'miter': + return StrokeJoin.miter; + case 'bevel': + return StrokeJoin.bevel; + case 'round': + return StrokeJoin.round; + default: + return definitionPaint?.join; + } + } + + List? _parseDashArray(String? rawDashArray) { + if (rawDashArray == null || rawDashArray == '') { + return null; + } else if (rawDashArray == 'none') { + return const []; + } + + final List parts = rawDashArray.split(RegExp(r'[ ,]+')); + final List doubles = []; + bool atLeastOneNonZeroDash = false; + for (final String part in parts) { + final double dashOffset = parseDoubleWithUnits(part)!; + if (dashOffset != 0) { + atLeastOneNonZeroDash = true; + } + doubles.add(dashOffset); + } + if (doubles.isEmpty || !atLeastOneNonZeroDash) { + return null; + } + return doubles; + } + + double? _parseDashOffset(String? rawDashOffset) { + return parseDoubleWithUnits(rawDashOffset); + } + + /// Applies a transform to a path if the [attributes] contain a `transform`. + Path applyTransformIfNeeded(Path path, AffineMatrix? parentTransform) { + final AffineMatrix? transform = parseTransform(attribute('transform')); + + if (transform != null) { + return path.transformed(transform); + } else { + return path; + } + } + + /// Parses a `clipPath` element into a list of [Path]s. + List parseClipPath() { + final String? id = _currentAttributes.clipPathId; + if (id != null) { + return _definitions.getClipPath(id); + } + + return []; + } + + static const Map _blendModes = { + 'multiply': BlendMode.multiply, + 'screen': BlendMode.screen, + 'overlay': BlendMode.overlay, + 'darken': BlendMode.darken, + 'lighten': BlendMode.lighten, + 'color-dodge': BlendMode.colorDodge, + 'color-burn': BlendMode.colorBurn, + 'hard-light': BlendMode.hardLight, + 'soft-light': BlendMode.softLight, + 'difference': BlendMode.difference, + 'exclusion': BlendMode.exclusion, + 'hue': BlendMode.hue, + 'saturation': BlendMode.saturation, + 'color': BlendMode.color, + 'luminosity': BlendMode.luminosity, + }; + + /// Lookup the mask if the attribute is present. + Node? parseMask() { + final String? rawMaskAttribute = attribute('mask'); + if (rawMaskAttribute != null) { + return _definitions.getDrawable(rawMaskAttribute); + } + + return null; + } + + /// Lookup the pattern if the attribute is present. + Node? parsePattern() { + final String? rawPattern = attribute('fill'); + if (rawPattern != null) { + return _definitions.getDrawable(rawPattern); + } + return null; + } + + /// Parse the raw font weight string. + FontWeight? parseFontWeight(String? fontWeight) { + if (fontWeight == null) { + return null; + } + + switch (fontWeight) { + case 'normal': + return normalFontWeight; + case 'bold': + return boldFontWeight; + case '100': + return FontWeight.w100; + case '200': + return FontWeight.w200; + case '300': + return FontWeight.w300; + case '400': + return FontWeight.w400; + case '500': + return FontWeight.w500; + case '600': + return FontWeight.w600; + case '700': + return FontWeight.w700; + case '800': + return FontWeight.w800; + case '900': + return FontWeight.w900; + } + + throw StateError('Invalid "font-weight": $fontWeight'); + } + + /// Converts a SVG Color String (either a # prefixed color string or a named color) to a [Color]. + Color? parseColor( + String? colorString, { + Color? currentColor, + required String attributeName, + required String? id, + }) { + final Color? parsed = _parseColor(colorString, currentColor: currentColor); + if (parsed == null || _colorMapper == null) { + return parsed; + } + // Do not use _currentAttributes, since they may not be up to date when this + // is called. + return _colorMapper.substitute( + id, + _currentStartElement!.localName, + attributeName, + parsed, + ); + } + + Color? _parseColor(String? colorString, {Color? currentColor}) { + if (colorString == null || colorString.isEmpty) { + return null; + } + + if (colorString == 'none') { + return null; + } + + if (colorString.toLowerCase() == 'currentcolor') { + return currentColor ?? theme.currentColor; + } + + // handle hex colors e.g. #fff or #ffffff. This supports #RRGGBBAA + if (colorString[0] == '#') { + if (colorString.length == 4) { + final String r = colorString[1]; + final String g = colorString[2]; + final String b = colorString[3]; + colorString = '#$r$r$g$g$b$b'; + } + + if (colorString.length == 7 || colorString.length == 9) { + final int color = int.parse(colorString.substring(1, 7), radix: 16); + final int alpha = colorString.length == 9 + ? int.parse(colorString.substring(7, 9), radix: 16) + : 255; + return Color(color | alpha << 24); + } + } + + // handle rgba() colors e.g. rgba(255, 255, 255, 1.0) + if (colorString.toLowerCase().startsWith('rgba')) { + final List rawColorElements = colorString + .substring(colorString.indexOf('(') + 1, colorString.indexOf(')')) + .split(',') + .map((String rawColor) => rawColor.trim()) + .toList(); + + final double opacity = parseDouble(rawColorElements.removeLast())!; + + final List rgb = rawColorElements + .map((String rawColor) => int.parse(rawColor)) + .toList(); + + return Color.fromRGBO(rgb[0], rgb[1], rgb[2], opacity); + } + + // Conversion code from: https://github.com/MichaelFenwick/Color, thanks :) + if (colorString.toLowerCase().startsWith('hsl')) { + final List values = colorString + .substring(colorString.indexOf('(') + 1, colorString.indexOf(')')) + .split(',') + .map((String rawColor) { + rawColor = rawColor.trim(); + + if (rawColor.endsWith('%')) { + rawColor = rawColor.substring(0, rawColor.length - 1); + } + + if (rawColor.contains('.')) { + return (parseDouble(rawColor)! * 2.55).round(); + } + + return int.parse(rawColor); + }).toList(); + final double hue = values[0] / 360 % 1; + final double saturation = values[1] / 100; + final double luminance = values[2] / 100; + final int alpha = values.length > 3 ? values[3] : 255; + List rgb = [0, 0, 0]; + + if (hue < 1 / 6) { + rgb[0] = 1; + rgb[1] = hue * 6; + } else if (hue < 2 / 6) { + rgb[0] = 2 - hue * 6; + rgb[1] = 1; + } else if (hue < 3 / 6) { + rgb[1] = 1; + rgb[2] = hue * 6 - 2; + } else if (hue < 4 / 6) { + rgb[1] = 4 - hue * 6; + rgb[2] = 1; + } else if (hue < 5 / 6) { + rgb[0] = hue * 6 - 4; + rgb[2] = 1; + } else { + rgb[0] = 1; + rgb[2] = 6 - hue * 6; + } + + rgb = rgb + .map((double val) => val + (1 - saturation) * (0.5 - val)) + .toList(); + + if (luminance < 0.5) { + rgb = rgb.map((double val) => luminance * 2 * val).toList(); + } else { + rgb = rgb + .map((double val) => luminance * 2 * (1 - val) + 2 * val - 1) + .toList(); + } + + rgb = rgb.map((double val) => val * 255).toList(); + + return Color.fromARGB( + alpha, rgb[0].round(), rgb[1].round(), rgb[2].round()); + } + + // handle rgb() colors e.g. rgb(255, 255, 255) + if (colorString.toLowerCase().startsWith('rgb')) { + final List rgb = colorString + .substring(colorString.indexOf('(') + 1, colorString.indexOf(')')) + .split(',') + .map((String rawColor) { + rawColor = rawColor.trim(); + if (rawColor.endsWith('%')) { + rawColor = rawColor.substring(0, rawColor.length - 1); + return (parseDouble(rawColor)! * 2.55).round(); + } + return int.parse(rawColor); + }).toList(); + + // rgba() isn't really in the spec, but Firefox supported it at one point so why not. + final int a = rgb.length > 3 ? rgb[3] : 255; + return Color.fromARGB(a, rgb[0], rgb[1], rgb[2]); + } + + // handle named colors ('red', 'green', etc.). + final Color? namedColor = namedColors[colorString]; + if (namedColor != null) { + return namedColor; + } + + // This is an error, but browsers are permissive here, so we can be too. + // See for example https://github.com/dnfield/flutter_svg/issues/764 - a + // user may be working with a network based SVG that uses the string "null" + // which is not part of the specification. + return null; + } + + Map _createAttributeMap(List attributes) { + final Map attributeMap = {}; + + for (final XmlEventAttribute attribute in attributes) { + final String value = attribute.value.trim(); + if (attribute.localName == 'style') { + for (final String style in value.split(';')) { + if (style.isEmpty) { + continue; + } + final List styleParts = style.split(':'); + final String attributeValue = styleParts[1].trim(); + if (attributeValue == 'inherit') { + continue; + } + attributeMap[styleParts[0].trim()] = attributeValue; + } + } else if (value != 'inherit') { + attributeMap[attribute.localName] = value; + } + } + return attributeMap; + } + + SvgStrokeAttributes? _parseStrokeAttributes( + Map attributeMap, + double? uniformOpacity, + Color? currentColor, + String? id, + ) { + final String? rawStroke = attributeMap['stroke']; + + final String? rawStrokeOpacity = attributeMap['stroke-opacity']; + double? opacity; + if (rawStrokeOpacity != null) { + opacity = parseDouble(rawStrokeOpacity)!.clamp(0.0, 1.0); + } + if (uniformOpacity != null) { + if (opacity == null) { + opacity = uniformOpacity; + } else { + opacity *= uniformOpacity; + } + } + + final String? rawStrokeCap = attributeMap['stroke-linecap']; + final String? rawLineJoin = attributeMap['stroke-linejoin']; + final String? rawMiterLimit = attributeMap['stroke-miterlimit']; + final String? rawStrokeWidth = attributeMap['stroke-width']; + final String? rawStrokeDashArray = attributeMap['stroke-dasharray']; + final String? rawStrokeDashOffset = attributeMap['stroke-dashoffset']; + + final String? anyStrokeAttribute = rawStroke ?? + rawStrokeCap ?? + rawLineJoin ?? + rawMiterLimit ?? + rawStrokeWidth ?? + rawStrokeDashArray ?? + rawStrokeDashOffset; + + if (anyStrokeAttribute == null) { + return null; + } + + Color? strokeColor; + String? shaderId; + bool? hasPattern; + if (rawStroke?.startsWith('url') ?? false) { + shaderId = rawStroke; + strokeColor = const Color(0xFFFFFFFF); + if (patternIds.contains(rawStroke)) { + hasPattern = true; + } + } else { + strokeColor = parseColor(rawStroke, attributeName: 'stroke', id: id); + } + + final Color? color = strokeColor; + + return SvgStrokeAttributes._( + _definitions, + shaderId: shaderId, + color: rawStroke == 'none' + ? const ColorOrNone.none() + : ColorOrNone.color(color), + cap: _parseCap(rawStrokeCap, null), + join: _parseJoin(rawLineJoin, null), + miterLimit: parseDouble(rawMiterLimit), + width: parseDoubleWithUnits(rawStrokeWidth), + dashArray: _parseDashArray(rawStrokeDashArray), + dashOffset: _parseDashOffset(rawStrokeDashOffset), + hasPattern: hasPattern, + opacity: opacity, + ); + } + + SvgFillAttributes? _parseFillAttributes( + Map attributeMap, + double? uniformOpacity, + Color? currentColor, + String? id, + ) { + final String rawFill = attributeMap['fill'] ?? ''; + + final String? rawFillOpacity = attributeMap['fill-opacity']; + double? opacity; + if (rawFillOpacity != null) { + opacity = parseDouble(rawFillOpacity)!.clamp(0.0, 1.0); + } + if (uniformOpacity != null) { + if (opacity == null) { + opacity = uniformOpacity; + } else { + opacity *= uniformOpacity; + } + } + bool? hasPattern; + if (rawFill.startsWith('url')) { + if (patternIds.contains(rawFill)) { + hasPattern = true; + } + return SvgFillAttributes._( + _definitions, + color: const ColorOrNone.color(Color(0xFFFFFFFF)), + shaderId: rawFill, + hasPattern: hasPattern, + opacity: opacity, + ); + } + + Color? fillColor = parseColor(rawFill, attributeName: 'fill', id: id); + + if ((fillColor?.a ?? 255) != 255) { + opacity = fillColor!.a / 255; + fillColor = fillColor.withOpacity(1); + } + + return SvgFillAttributes._( + _definitions, + color: rawFill == 'none' + ? const ColorOrNone.none() + : ColorOrNone.color(fillColor), + opacity: opacity, + ); + } + + bool _isVisible(Map attributeMap) { + return attributeMap['display'] != 'none' && + attributeMap['visibility'] != 'hidden'; + } + + SvgAttributes _createSvgAttributes( + Map attributeMap, { + Color? currentColor, + }) { + final String? id = attributeMap['id']; + final double? opacity = + parseDouble(attributeMap['opacity'])?.clamp(0.0, 1.0); + final Color? color = + parseColor(attributeMap['color'], attributeName: 'color', id: id) ?? + currentColor; + + final String? rawX = attributeMap['x']; + final String? rawY = attributeMap['y']; + + final String? rawDx = attributeMap['dx']; + final String? rawDy = attributeMap['dy']; + + return SvgAttributes._( + raw: attributeMap, + id: id, + x: DoubleOrPercentage.fromString(rawX), + y: DoubleOrPercentage.fromString(rawY), + dx: DoubleOrPercentage.fromString(rawDx), + dy: DoubleOrPercentage.fromString(rawDy), + href: attributeMap['href'], + color: attributeMap['color']?.toLowerCase() == 'none' + ? const ColorOrNone.none() + : ColorOrNone.color(color), + stroke: _parseStrokeAttributes( + attributeMap, + opacity, + color, + id, + ), + fill: _parseFillAttributes( + attributeMap, + opacity, + color, + id, + ), + fillRule: parseRawFillRule(attributeMap['fill-rule']), + clipRule: parseRawFillRule(attributeMap['clip-rule']), + clipPathId: attributeMap['clip-path'], + blendMode: _blendModes[attributeMap['mix-blend-mode']], + transform: + parseTransform(attributeMap['transform']) ?? AffineMatrix.identity, + fontFamily: attributeMap['font-family'], + fontWeight: parseFontWeight(attributeMap['font-weight']), + fontSize: parseFontSize(attributeMap['font-size']), + textDecoration: parseTextDecoration(attributeMap['text-decoration']), + textDecorationStyle: + parseTextDecorationStyle(attributeMap['text-decoration-style']), + textDecorationColor: parseColor(attributeMap['text-decoration-color'], + attributeName: 'text-decoration-color', id: id), + textAnchorMultiplier: parseTextAnchor(attributeMap['text-anchor'])); + } +} + +/// A resolver is used by the parser and node tree to handle forward/backwards +/// references with identifiers. +class _Resolver { + /// A default empty identifier. + static const String emptyUrlIri = 'url(#)'; + final Map _drawables = {}; + final Map _shaders = {}; + final Map> _clips = >{}; + + bool _sealed = false; + + void _seal() { + assert(_deferredShaders.isEmpty); + _sealed = true; + } + + /// Retrieve the drawable defined by [ref]. + AttributedNode? getDrawable(String ref) { + assert(_sealed); + return _drawables[ref]; + } + + /// Retrieve the clip defined by [ref], or `null` if it is undefined. + List getClipPath(String ref) { + assert(_sealed); + final List? nodes = _clips[ref]; + if (nodes == null) { + return []; + } + + final List pathBuilders = []; + PathBuilder? currentPath; + void extractPathsFromNode(Node? target) { + if (target is PathNode) { + final PathBuilder nextPath = PathBuilder.fromPath(target.path); + nextPath.fillType = target.attributes.clipRule ?? PathFillType.nonZero; + if (currentPath != null && nextPath.fillType != currentPath!.fillType) { + currentPath = nextPath; + pathBuilders.add(currentPath!); + } else if (currentPath == null) { + currentPath = nextPath; + pathBuilders.add(currentPath!); + } else { + currentPath!.addPath(nextPath.toPath(reset: false)); + } + } else if (target is DeferredNode) { + extractPathsFromNode(target.resolver(target.refId)); + } else if (target is ParentNode) { + target.visitChildren(extractPathsFromNode); + } + } + + nodes.forEach(extractPathsFromNode); + + return pathBuilders + .map((PathBuilder builder) => builder.toPath()) + .toList(growable: false); + } + + /// Get the pattern id if one exists. + String? getPattern(SvgParser parserState) { + if (parserState.attribute('fill') != null) { + final String? fill = parserState.attribute('fill'); + if (fill!.startsWith('url') && parserState.patternIds.contains(fill)) { + return fill; + } + } + + if (parserState.attribute('stroke') != null) { + final String? stroke = parserState.attribute('stroke'); + if (stroke!.startsWith('url') && + parserState.patternIds.contains(stroke)) { + return stroke; + } + } + return null; + } + + /// Retrieve the [Gradeint] defined by [ref]. + T? getGradient(String ref) { + assert(_sealed); + return _shaders[ref] as T?; + } + + final Map> _deferredShaders = + >{}; + + /// Add a deferred [gradient] to the resolver, identified by [href]. + void addDeferredGradient(String ref, Gradient gradient) { + assert(!_sealed); + _deferredShaders.putIfAbsent(ref, () => []).add(gradient); + } + + /// Add the [gradient] to the resolver, identified by [href]. + void addGradient( + Gradient gradient, + String? href, + ) { + assert(!_sealed); + if (_shaders.containsKey(gradient.id)) { + return; + } + _shaders[gradient.id] = gradient; + if (href != null) { + href = 'url($href)'; + final Gradient? gradientRef = _shaders[href]; + if (gradientRef != null) { + // Gradient is defined after its reference. + _shaders[gradient.id] = gradient.applyProperties(gradientRef); + } else { + // Gradient is defined before its reference, check later when that + // reference has been parsed. + addDeferredGradient(href, gradient); + } + } else { + for (final Gradient deferred + in _deferredShaders.remove(gradient.id) ?? []) { + _shaders[deferred.id] = deferred.applyProperties(gradient); + } + } + } + + /// Add the clip defined by [pathNodes] to the resolver identifier by [ref]. + void addClipPath(String ref, List pathNodes) { + assert(!_sealed); + _clips.putIfAbsent(ref, () => pathNodes); + } + + /// Add the [drawable] to the resolver identifier by [ref]. + void addDrawable(String ref, AttributedNode drawable) { + assert(!_sealed); + _drawables.putIfAbsent(ref, () => drawable); + } +} + +class _Viewport { + const _Viewport(this.width, this.height, this.transform); + + final double width; + final double height; + final AffineMatrix transform; +} + +/// A collection of attributes for an SVG element. +class SvgAttributes { + /// Create a new [SvgAttributes] from the given properties. + const SvgAttributes._({ + required this.raw, + this.id, + this.href, + this.transform = AffineMatrix.identity, + this.color = const ColorOrNone.color(), + this.stroke, + this.fill, + this.fillRule, + this.clipRule, + this.clipPathId, + this.blendMode, + this.fontFamily, + this.fontWeight, + this.fontSize, + this.textDecoration, + this.textDecorationStyle, + this.textDecorationColor, + this.x, + this.dx, + this.textAnchorMultiplier, + this.y, + this.dy, + this.width, + this.height, + }); + + /// For use in tests to construct arbitrary attributes. + @visibleForTesting + const SvgAttributes.forTest({ + this.raw = const {}, + this.id, + this.href, + this.transform = AffineMatrix.identity, + this.color = const ColorOrNone.color(), + this.stroke, + this.fill, + this.fillRule, + this.clipRule, + this.clipPathId, + this.blendMode, + this.fontFamily, + this.fontWeight, + this.fontSize, + this.textDecoration, + this.textDecorationStyle, + this.textDecorationColor, + this.x, + this.dx, + this.textAnchorMultiplier, + this.y, + this.dy, + this.width, + this.height, + }); + + /// The empty set of properties. + static const SvgAttributes empty = SvgAttributes._(raw: {}); + + /// The raw attribute map. + final Map raw; + + /// Whether either the stroke or fill on this object has opacity. + bool get hasOpacity => (fill?.opacity ?? stroke?.opacity) != null; + + /// Generated from https://www.w3.org/TR/SVG11/single-page.html + /// + /// Using this: + /// ```javascript + /// let set = '{'; + /// document.querySelectorAll('.propdef') + /// .forEach((propdef) => { + /// const nameNode = propdef.querySelector('.propdef-title.prop-name'); + /// if (!nameNode) { + /// return; + /// } + /// const inherited = propdef.querySelector('tbody tr:nth-child(4) td:nth-child(2)').innerText.startsWith('yes'); + /// if (inherited) { + /// set += `'${nameNode.innerText.replaceAll(/[‘’]/g, '')}',`; + /// } + /// }); + /// set += '};'; + /// console.log(set); + /// ``` + static const Set _heritableProps = { + 'writing-mode', + 'glyph-orientation-vertical', + 'glyph-orientation-horizontal', + 'direction', + 'text-anchor', + 'font-family', + 'font-style', + 'font-variant', + 'font-weight', + 'font-stretch', + 'font-size', + 'font-size-adjust', + 'font', + 'kerning', + 'letter-spacing', + 'word-spacing', + 'fill', + 'fill-rule', + 'fill-opacity', + 'stroke', + 'stroke-width', + 'stroke-linecap', + 'stroke-linejoin', + 'stroke-miterlimit', + 'stroke-dasharray', + 'stroke-dashoffset', + 'stroke-opacity', + 'visibility', + 'marker-start', + 'marker', + 'color-interpolation', + 'color-interpolation-filters', + 'color-rendering', + 'shape-rendering', + 'text-rendering', + 'image-rendering', + 'color', + 'color-profile', + 'clip-rule', + 'pointer-events', + 'cursor', + }; + + /// The properties in [raw] that are heritable per the SVG 1.1 specification. + Iterable> get heritable { + return raw.entries.where((MapEntry entry) { + return _heritableProps.contains(entry.key); + }); + } + + /// The `@id` attribute. + final String? id; + + /// The `@href` attribute. + final String? href; + + /// The `@color` attribute, which provides an indirect current color. + /// + /// Does _not_ include the opacity value, which is specified on the [fill] or + /// [stroke]. + /// + /// https://www.w3.org/TR/SVG11/color.html#ColorProperty + final ColorOrNone color; + + /// The stroking properties of this element. + final SvgStrokeAttributes? stroke; + + /// The filling properties of this element. + final SvgFillAttributes? fill; + + /// The `@transform` attribute. + final AffineMatrix transform; + + /// The `@fill-rule` attribute. + final PathFillType? fillRule; + + /// The `@clip-rule` attribute. + final PathFillType? clipRule; + + /// The raw identifier for clip path(s) to apply. + final String? clipPathId; + + /// The `mix-blend-mode` attribute. + final BlendMode? blendMode; + + /// The `font-family` attribute, as a string. + final String? fontFamily; + + /// The font weight attribute. + final FontWeight? fontWeight; + + /// The `font-size` attribute. + final double? fontSize; + + /// The `text-decoration` attribute. + final TextDecoration? textDecoration; + + /// The `text-decoration-style` attribute. + final TextDecorationStyle? textDecorationStyle; + + /// The `text-decoration-color` attribute. + final Color? textDecorationColor; + + /// The `width` attribute. + final double? width; + + /// The `height` attribute. + final double? height; + + /// The x translation. + final DoubleOrPercentage? x; + + /// A multiplier for text-anchoring. + final double? textAnchorMultiplier; + + /// The y translation. + final DoubleOrPercentage? y; + + /// The relative x translation. + final DoubleOrPercentage? dx; + + /// The relative y translation. + final DoubleOrPercentage? dy; + + /// A copy of these attributes after absorbing a saveLayer. + /// + /// Specifically, this will null out `blendMode` and any opacity related + /// attributes, since those have been applied in a saveLayer call. + /// + /// The [raw] map preserves old values. + SvgAttributes forSaveLayer() { + return SvgAttributes._( + raw: raw, + id: id, + href: href, + transform: transform, + color: color, + stroke: stroke?.forSaveLayer(), + fill: fill?.forSaveLayer(), + fillRule: fillRule, + clipRule: clipRule, + clipPathId: clipPathId, + blendMode: blendMode, + fontFamily: fontFamily, + fontWeight: fontWeight, + fontSize: fontSize, + textDecoration: textDecoration, + textDecorationStyle: textDecorationStyle, + textDecorationColor: textDecorationColor, + x: x, + textAnchorMultiplier: textAnchorMultiplier, + y: y, + width: width, + height: height, + ); + } + + /// Creates a new set of attributes as if this inherited from `parent`. + /// + /// If `includePosition` is true, the `x`/`y` coordinates are also inherited. This + /// is intended to be used by text parsing. Defaults to `false`. + SvgAttributes applyParent( + SvgAttributes parent, { + bool includePosition = false, + AffineMatrix? transformOverride, + String? hrefOverride, + }) { + final Map newRaw = { + ...Map.fromEntries(parent.heritable), + if (includePosition && parent.raw.containsKey('x')) 'x': parent.raw['x']!, + if (includePosition && parent.raw.containsKey('y')) 'y': parent.raw['y']!, + ...raw, + }; + + return SvgAttributes._( + raw: newRaw, + id: newRaw['id'], + href: newRaw['href'], + transform: transformOverride ?? transform, + color: color._applyParent(parent.color), + stroke: stroke?.applyParent(parent.stroke) ?? parent.stroke, + fill: fill?.applyParent(parent.fill) ?? parent.fill, + fillRule: fillRule ?? parent.fillRule, + clipRule: clipRule ?? parent.clipRule, + clipPathId: clipPathId ?? parent.clipPathId, + blendMode: blendMode ?? parent.blendMode, + fontFamily: fontFamily ?? parent.fontFamily, + fontWeight: fontWeight ?? parent.fontWeight, + fontSize: fontSize ?? parent.fontSize, + textDecoration: textDecoration ?? parent.textDecoration, + textDecorationStyle: textDecorationStyle ?? parent.textDecorationStyle, + textDecorationColor: textDecorationColor ?? parent.textDecorationColor, + textAnchorMultiplier: textAnchorMultiplier ?? parent.textAnchorMultiplier, + height: height ?? parent.height, + width: width ?? parent.width, + x: x, + y: y, + dx: dx, + dy: dy, + ); + } +} + +/// A value that represents either an absolute pixel coordinate or a percentage +/// of a bounding dimension. +@immutable +class DoubleOrPercentage { + const DoubleOrPercentage._(this._value, this._isPercentage); + + /// Constructs a [DoubleOrPercentage] from a raw SVG attribute string. + static DoubleOrPercentage? fromString(String? raw) { + if (raw == null || raw == '') { + return null; + } + + if (isPercentage(raw)) { + return DoubleOrPercentage._(parsePercentage(raw), true); + } + return DoubleOrPercentage._(parseDouble(raw)!, false); + } + + final double _value; + final bool _isPercentage; + + /// Calculates the result of applying this dimension within [bound]. + /// + /// If this is a percentage, it will return a percentage of bound. Otherwise, + /// it returns the value of this. + double calculate(double bound) { + if (_isPercentage) { + return _value * bound; + } + return _value; + } + + @override + int get hashCode => Object.hash(_value, _isPercentage); + + @override + bool operator ==(Object other) { + return other is DoubleOrPercentage && + other._isPercentage == _isPercentage && + other._value == _value; + } +} + +/// SVG attributes specific to stroking. +class SvgStrokeAttributes { + const SvgStrokeAttributes._( + this._definitions, { + this.color = const ColorOrNone.color(), + this.shaderId, + this.join, + this.cap, + this.miterLimit, + this.width, + this.dashArray, + this.dashOffset, + this.hasPattern, + this.opacity, + }); + + final _Resolver? _definitions; + + /// The color to use for stroking. Does _not_ include the [opacity] value. Only + /// opacity is used if the [shaderId] is not null. + final ColorOrNone color; + + /// The literal reference to a shader defined elsewhere. + final String? shaderId; + + /// The join style to use for the stroke. + final StrokeJoin? join; + + /// The cap style to use for the stroke. + final StrokeCap? cap; + + /// The miter limit to use if the [join] is [StrokeJoin.miter]. + final double? miterLimit; + + /// The width of the stroke. + final double? width; + + /// The dashing array to use if the path is dashed. + final List? dashArray; + + /// The offset for [dashArray], if any. + final double? dashOffset; + + /// Indicates whether or not a pattern is used for stroke. + final bool? hasPattern; + + /// The opacity to apply to a default color, if [color] is null. + final double? opacity; + + /// A copy of these attributes after absorbing a saveLayer. + /// + /// Specifically, this will null out any opacity related + /// attributes, since those have been applied in a saveLayer call. + SvgStrokeAttributes forSaveLayer() { + return SvgStrokeAttributes._( + _definitions, + color: color, + shaderId: shaderId, + join: join, + cap: cap, + miterLimit: miterLimit, + width: width, + dashArray: dashArray, + dashOffset: dashOffset, + hasPattern: hasPattern, + ); + } + + /// Inherits attributes in this from parent. + SvgStrokeAttributes applyParent(SvgStrokeAttributes? parent) { + return SvgStrokeAttributes._( + _definitions, + color: color._applyParent(parent?.color), + shaderId: shaderId ?? parent?.shaderId, + join: join ?? parent?.join, + cap: cap ?? parent?.cap, + miterLimit: miterLimit ?? parent?.miterLimit, + width: width ?? parent?.width, + dashArray: dashArray ?? parent?.dashArray, + dashOffset: dashOffset ?? parent?.dashOffset, + hasPattern: hasPattern ?? parent?.hasPattern, + opacity: opacity ?? parent?.opacity, + ); + } + + /// Creates a stroking paint object from this set of attributes, using the + /// bounds and transform specified for shader computation. + /// + /// Returns null if this is [none]. + Stroke? toStroke(Rect shaderBounds, AffineMatrix transform) { + // A zero width stroke is a hairline in Flutter, but a nop in SVG. + if (color.isNone || + (color.color == null && hasPattern == null && shaderId == null || + width == 0)) { + return null; + } + + if (hasPattern ?? false) { + return Stroke( + join: join, + cap: cap, + miterLimit: miterLimit, + width: width, + ); + } + + if (_definitions == null) { + return null; + } + + Gradient? shader; + if (shaderId != null) { + shader = _definitions + .getGradient(shaderId!) + ?.applyBounds(shaderBounds, transform); + if (shader == null) { + return null; + } + } + + return Stroke( + color: color.color!.withOpacity(opacity ?? 1.0), + shader: shader, + join: join, + cap: cap, + miterLimit: miterLimit, + width: transform.scaleStrokeWidth(width), + ); + } +} + +/// SVG attributes specific to filling. +class SvgFillAttributes { + /// Create a new [SvgFillAttributes]; + const SvgFillAttributes._( + this._definitions, { + this.color = const ColorOrNone.color(), + this.shaderId, + this.hasPattern, + this.opacity, + }); + + final _Resolver? _definitions; + + /// The color to use for filling. Does _not_ include the [opacity] value. Only + /// opacity is used if the [shaderId] is not null. + final ColorOrNone color; + + /// The opacity to apply to a default color, if [color] is null. + final double? opacity; + + /// The literal reference to a shader defined elsewhere. + final String? shaderId; + + /// If there is a pattern a default fill will be returned. + final bool? hasPattern; + + /// A copy of these attributes after absorbing a saveLayer. + /// + /// Specifically, this will null out any opacity related + /// attributes, since those have been applied in a saveLayer call. + SvgFillAttributes forSaveLayer() { + return SvgFillAttributes._( + _definitions, + color: color, + shaderId: shaderId, + hasPattern: hasPattern, + ); + } + + /// Inherits attributes in this from parent. + SvgFillAttributes applyParent(SvgFillAttributes? parent) { + return SvgFillAttributes._( + _definitions, + color: color._applyParent(parent?.color), + shaderId: shaderId ?? parent?.shaderId, + hasPattern: hasPattern ?? parent?.hasPattern, + opacity: opacity ?? parent?.opacity, + ); + } + + /// Creates a [Fill] from this information with appropriate transforms and + /// bounds for shaders. + /// + /// Returns null if this is [none]. + Fill? toFill( + Rect shaderBounds, + AffineMatrix transform, { + Color? defaultColor, + }) { + if (color.isNone) { + return null; + } + final Color? resolvedColor = color.color?.withOpacity(opacity ?? 1.0) ?? + defaultColor?.withOpacity(opacity ?? 1.0); + if (resolvedColor == null) { + return null; + } + if (hasPattern ?? false) { + return Fill(color: resolvedColor); + } + + if (_definitions == null) { + return null; + } + Gradient? shader; + if (shaderId != null) { + shader = _definitions + .getGradient(shaderId!) + ?.applyBounds(shaderBounds, transform); + if (shader == null) { + return null; + } + } + + return Fill(color: resolvedColor, shader: shader); + } + + @override + String toString() { + return 'SvgFillAttributes(' + 'definitions: $_definitions, ' + 'color: $color, ' + 'shaderId: $shaderId, ' + 'hasPattern: $hasPattern, ' + 'oapctiy: $opacity)'; + } +} + +/// Represents a color for filling or stroking. +/// +/// If the [color] is not null, [isNone] is false. +/// +/// If the [color] is null and [isNone] is false, color should be inherited from +/// the parent or defaulted as per the SVG specification. +/// +/// If the [color] is null and [isNone] is true, inheritence should be cleared +/// and no painting should happen. +class ColorOrNone { + /// See [ColorOrNone]. + const ColorOrNone.none() + : isNone = true, + color = null; + + /// See [ColorOrNone]. + const ColorOrNone.color([this.color]) : isNone = false; + + /// Whether to paint anything. + final bool isNone; + + /// The color to use when painting. If null and [isNone] is false, inherit + /// from parent. + final Color? color; + + ColorOrNone _applyParent(ColorOrNone? parent) { + if (parent == null || isNone) { + return this; + } + + if (parent.isNone && color == null) { + return const ColorOrNone.none(); + } + + return ColorOrNone.color(color ?? parent.color); + } + + @override + String toString() => isNone ? '"none"' : (color?.toString() ?? 'null'); +} diff --git a/packages/vector_graphics_compiler/lib/src/svg/parsers.dart b/packages/vector_graphics_compiler/lib/src/svg/parsers.dart new file mode 100644 index 000000000000..6dcba4b2be86 --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/svg/parsers.dart @@ -0,0 +1,194 @@ +// 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:math'; + +import '../geometry/matrix.dart'; +import '../geometry/path.dart'; +import 'node.dart'; +import 'numbers.dart'; + +const String _transformCommandAtom = r' *,?([^(]+)\(([^)]*)\)'; +final RegExp _transformValidator = RegExp('^($_transformCommandAtom)*\$'); +final RegExp _transformCommand = RegExp(_transformCommandAtom); + +typedef _MatrixParser = AffineMatrix Function( + List params, AffineMatrix current); + +const Map _matrixParsers = { + 'matrix': _parseSvgMatrix, + 'translate': _parseSvgTranslate, + 'scale': _parseSvgScale, + 'rotate': _parseSvgRotate, + 'skewX': _parseSvgSkewX, + 'skewY': _parseSvgSkewY, +}; + +List _parseTransformParams(String params) { + final List result = []; + String current = ''; + for (int i = 0; i < params.length; i += 1) { + final String char = params[i]; + final bool isSeparator = char == ' ' || char == '-' || char == ','; + final bool isExponent = i > 0 && params[i - 1].toLowerCase() == 'e'; + if (isSeparator && !isExponent) { + if (current != '') { + result.add(parseDouble(current)!); + } + if (char == '-') { + current = '-'; + } else { + current = ''; + } + } else { + if (char == '.') { + if (current.contains('.')) { + result.add(parseDouble(current)!); + current = ''; + } + } + current += char; + } + } + if (current.isNotEmpty) { + result.add(parseDouble(current)!); + } + return result; +} + +/// Parses a SVG transform attribute into a [AffineMatrix]. +AffineMatrix? parseTransform(String? transform) { + if (transform == null || transform == '') { + return null; + } + + if (!_transformValidator.hasMatch(transform)) { + throw StateError('illegal or unsupported transform: $transform'); + } + final Iterable matches = + _transformCommand.allMatches(transform).toList().reversed; + AffineMatrix result = AffineMatrix.identity; + for (final Match m in matches) { + final String command = m.group(1)!.trim(); + final List params = _parseTransformParams(m.group(2)!.trim()); + + final _MatrixParser? transformer = _matrixParsers[command]; + if (transformer == null) { + throw StateError('Unsupported transform: $command'); + } + + result = transformer(params, result); + } + return result; +} + +AffineMatrix _parseSvgMatrix(List params, AffineMatrix current) { + assert(params.isNotEmpty); + assert(params.length == 6); + final double a = params[0]; + final double b = params[1]; + final double c = params[2]; + final double d = params[3]; + final double e = params[4]; + final double f = params[5]; + + return AffineMatrix(a, b, c, d, e, f).multiplied(current); +} + +AffineMatrix _parseSvgSkewX(List params, AffineMatrix current) { + assert(params.isNotEmpty); + return AffineMatrix(1.0, 0.0, tan(params.first), 1.0, 0.0, 0.0) + .multiplied(current); +} + +AffineMatrix _parseSvgSkewY(List params, AffineMatrix current) { + assert(params.isNotEmpty); + return AffineMatrix(1.0, tan(params.first), 0.0, 1.0, 0.0, 0.0) + .multiplied(current); +} + +AffineMatrix _parseSvgTranslate(List params, AffineMatrix current) { + assert(params.isNotEmpty); + assert(params.length <= 2); + final double y = params.length < 2 ? 0.0 : params[1]; + return AffineMatrix(1.0, 0.0, 0.0, 1.0, params.first, y).multiplied(current); +} + +AffineMatrix _parseSvgScale(List params, AffineMatrix current) { + assert(params.isNotEmpty); + assert(params.length <= 2); + final double x = params[0]; + final double y = params.length < 2 ? x : params[1]; + return AffineMatrix(x, 0.0, 0.0, y, 0.0, 0.0).multiplied(current); +} + +AffineMatrix _parseSvgRotate(List params, AffineMatrix current) { + assert(params.length <= 3); + final double a = radians(params[0]); + + final AffineMatrix rotate = AffineMatrix.identity.rotated(a); + + if (params.length > 1) { + final double x = params[1]; + final double y = params.length == 3 ? params[2] : x; + return AffineMatrix(1.0, 0.0, 0.0, 1.0, x, y) + .multiplied(rotate) + .translated(-x, -y) + .multiplied(current); + } else { + return rotate.multiplied(current); + } +} + +/// Parses a `fill-rule` attribute. +PathFillType? parseRawFillRule(String? rawFillRule) { + if (rawFillRule == 'inherit' || rawFillRule == null) { + return null; + } + + return rawFillRule != 'evenodd' ? PathFillType.nonZero : PathFillType.evenOdd; +} + +/// Parses strings in the form of '1.0' or '100%'. +double parseDecimalOrPercentage(String val, {double multiplier = 1.0}) { + if (isPercentage(val)) { + return parsePercentage(val, multiplier: multiplier); + } else { + return parseDouble(val)!; + } +} + +/// Parses values in the form of '100%'. +double parsePercentage(String val, {double multiplier = 1.0}) { + return parseDouble(val.substring(0, val.length - 1))! / 100 * multiplier; +} + +/// Whether a string should be treated as a percentage (i.e. if it ends with a `'%'`). +bool isPercentage(String? val) => val?.endsWith('%') ?? false; + +/// Parses value from the form '25%', 0.25 or 25.0 as a double. +/// Note: Percentage or decimals will be multiplied by the total +/// view box size, where as doubles will be returned as is. +double? parsePatternUnitToDouble(String rawValue, String mode, + {ViewportNode? viewBox}) { + double? value; + double? viewBoxValue; + if (viewBox != null) { + if (mode == 'width') { + viewBoxValue = viewBox.width; + } else if (mode == 'height') { + viewBoxValue = viewBox.height; + } + } + + if (rawValue.contains('%')) { + value = ((double.parse(rawValue.substring(0, rawValue.length - 1))) / 100) * + viewBoxValue!; + } else if (rawValue.startsWith('0.')) { + value = (double.parse(rawValue)) * viewBoxValue!; + } else if (rawValue.isNotEmpty) { + value = double.parse(rawValue); + } + return value; +} diff --git a/packages/vector_graphics_compiler/lib/src/svg/path_ops.dart b/packages/vector_graphics_compiler/lib/src/svg/path_ops.dart new file mode 100644 index 000000000000..9b0e67e6dd3a --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/svg/path_ops.dart @@ -0,0 +1,131 @@ +// 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. +// Copied from flutter/engine repository: https://github.com/flutter/engine/tree/main/tools/path_ops +// NOTE: For now, this copy and flutter/engine copy should be kept in sync. + +import '_path_ops_unsupported.dart' if (dart.library.ffi) '_path_ops_ffi.dart' + as impl; +export '_path_ops_unsupported.dart' if (dart.library.ffi) '_path_ops_ffi.dart'; + +// ignore_for_file: camel_case_types, non_constant_identifier_names + +/// Initialize the libpathops dynamic library. +void initializeLibPathOps(String path) => impl.initializeLibPathOps(path); + +/// Determines the winding rule that decides how the interior of a Path is +/// calculated. +/// +/// This enum is used by the [Path] constructor +// must match ordering in //third_party/skia/include/core/SkPathTypes.h +enum FillType { + /// The interior is defined by a non-zero sum of signed edge crossings. + nonZero, + + /// The interior is defined by an odd number of edge crossings. + evenOdd, +} + +/// A set of operations applied to two paths. +// Sync with //third_party/skia/include/pathops/SkPathOps.h +enum PathOp { + /// Subtracts the second path from the first. + difference, + + /// Creates a new path representing the intersection of the first and second. + intersect, + + /// Creates a new path representing the union of the first and second + /// (includive-or). + union, + + /// Creates a new path representing the exclusive-or of two paths. + xor, + + /// Creates a new path that subtracts the first path from the second.s + reversedDifference, +} + +/// The commands used in a [Path] object. +/// +/// This enumeration is a subset of the commands that SkPath supports. +// Sync with //third_party/skia/include/core/SkPathTypes.h +enum PathVerb { + /// Picks up the pen and moves it without drawing. Uses two point values. + moveTo, + + /// A straight line from the current point to the specified point. + lineTo, + + /// A quadratic bezier curve from the current point. + /// + /// The next two points are the control point. The next two points after + /// that are the target point. + quadTo, + + /// A cubic bezier curve from the current point. + /// + /// The next two points are used as the first control point. The next two + /// points form the second control point. The next two points form the + /// target point. + cubicTo, + + /// A straight line from the current point to the last [moveTo] point. + close, +} + +/// A proxy class for [Path.replay]. +/// +/// Allows implementations to easily inspect the contents of a [Path]. +abstract class PathProxy { + /// Picks up the pen and moves to absolute coordinates x,y. + void moveTo(double x, double y); + + /// Draws a straight line from the current point to absolute coordinates x,y. + void lineTo(double x, double y); + + /// Creates a cubic Bezier curve from the current point to point x3,y3 using + /// x1,y1 as the first control point and x2,y2 as the second. + void cubicTo( + double x1, double y1, double x2, double y2, double x3, double y3); + + /// Draws a straight line from the current point to the last [moveTo] point. + void close(); + + /// Called by [Path.replay] to indicate that a new path is being played. + void reset() {} +} + +/// A path proxy that can print the SVG path-data representation of this path. +class SvgPathProxy implements PathProxy { + final StringBuffer _buffer = StringBuffer(); + + @override + void reset() { + _buffer.clear(); + } + + @override + void close() { + _buffer.write('Z'); + } + + @override + void cubicTo( + double x1, double y1, double x2, double y2, double x3, double y3) { + _buffer.write('C$x1,$y1 $x2,$y2 $x3,$y3'); + } + + @override + void lineTo(double x, double y) { + _buffer.write('L$x,$y'); + } + + @override + void moveTo(double x, double y) { + _buffer.write('M$x,$y'); + } + + @override + String toString() => _buffer.toString(); +} diff --git a/packages/vector_graphics_compiler/lib/src/svg/resolver.dart b/packages/vector_graphics_compiler/lib/src/svg/resolver.dart new file mode 100644 index 000000000000..76f34b43c35e --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/svg/resolver.dart @@ -0,0 +1,567 @@ +// 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:typed_data'; +import '../geometry/basic_types.dart'; +import '../geometry/matrix.dart'; +import '../geometry/path.dart'; +import '../geometry/vertices.dart'; +import '../image/image_info.dart'; +import '../paint.dart'; +import 'node.dart'; +import 'parser.dart'; +import 'visitor.dart'; + +/// A visitor class that processes relative coordinates in the tree into a +/// single coordinate space, removing extra attributes, empty nodes, resolving +/// references/masks/clips. +class ResolvingVisitor extends Visitor { + late Rect _bounds; + + @override + Node visitClipNode(ClipNode clipNode, AffineMatrix data) { + final AffineMatrix childTransform = clipNode.concatTransform(data); + final List transformedClips = [ + for (final Path clip in clipNode.resolver(clipNode.clipId)) + clip.transformed(childTransform) + ]; + if (transformedClips.isEmpty) { + return clipNode.child.accept(this, data); + } + return ResolvedClipNode( + clips: transformedClips, + child: clipNode.child.accept(this, data), + ); + } + + @override + Node visitMaskNode(MaskNode maskNode, AffineMatrix data) { + final AttributedNode? resolvedMask = maskNode.resolver(maskNode.maskId); + if (resolvedMask == null) { + return maskNode.child.accept(this, data); + } + final Node child = maskNode.child.accept(this, data); + final AffineMatrix childTransform = maskNode.concatTransform(data); + final Node mask = resolvedMask.accept(this, childTransform); + + return ResolvedMaskNode( + child: child, + mask: mask, + blendMode: maskNode.blendMode, + ); + } + + @override + Node visitParentNode(ParentNode parentNode, AffineMatrix data) { + final AffineMatrix nextTransform = parentNode.concatTransform(data); + + final Paint? saveLayerPaint = parentNode.createLayerPaint(); + + final Node result; + if (saveLayerPaint == null) { + result = ParentNode( + SvgAttributes.empty, + precalculatedTransform: AffineMatrix.identity, + children: [ + for (final Node child in parentNode.children) + child + .applyAttributes(parentNode.attributes) + .accept(this, nextTransform), + ], + ); + } else { + result = SaveLayerNode( + SvgAttributes.empty, + paint: saveLayerPaint, + children: [ + for (final Node child in parentNode.children) + child + .applyAttributes(parentNode.attributes.forSaveLayer()) + .accept(this, nextTransform), + ], + ); + } + return result; + } + + @override + Node visitPathNode(PathNode pathNode, AffineMatrix data) { + final AffineMatrix transform = data.multiplied( + pathNode.attributes.transform, + ); + final Path transformedPath = pathNode.path + .transformed(transform) + .withFillType(pathNode.attributes.fillRule ?? pathNode.path.fillType); + final Rect originalBounds = pathNode.path.bounds(); + final Rect newBounds = transformedPath.bounds(); + final Paint? paint = pathNode.computePaint(originalBounds, transform); + if (paint != null) { + if (pathNode.attributes.stroke?.dashArray != null) { + final List children = []; + final ParentNode parent = ParentNode( + pathNode.attributes, + children: children, + ); + if (paint.fill != null) { + children.add(ResolvedPathNode( + paint: Paint(blendMode: paint.blendMode, fill: paint.fill), + bounds: newBounds, + path: transformedPath, + )); + } + if (paint.stroke != null) { + children.add(ResolvedPathNode( + paint: Paint(blendMode: paint.blendMode, stroke: paint.stroke), + bounds: newBounds, + path: transformedPath.dashed( + pathNode.attributes.stroke!.dashArray!, + ), + )); + } + return parent; + } + return ResolvedPathNode( + paint: paint, + bounds: newBounds, + path: transformedPath, + ); + } + return Node.empty; + } + + @override + Node visitTextPositionNode( + TextPositionNode textPositionNode, + AffineMatrix data, + ) { + final AffineMatrix nextTransform = textPositionNode.concatTransform(data); + + return ResolvedTextPositionNode( + textPositionNode.computeTextPosition(_bounds, data), + [ + for (final Node child in textPositionNode.children) + child + .applyAttributes(textPositionNode.attributes) + .accept(this, nextTransform), + ], + ); + } + + @override + Node visitTextNode(TextNode textNode, AffineMatrix data) { + final Paint? paint = textNode.computePaint(_bounds, data); + final TextConfig textConfig = textNode.computeTextConfig(_bounds, data); + + if (paint != null && textConfig.text.trim().isNotEmpty) { + return ResolvedTextNode( + textConfig: textConfig, + paint: paint, + ); + } + return Node.empty; + } + + @override + Node visitViewportNode(ViewportNode viewportNode, AffineMatrix data) { + _bounds = Rect.fromLTWH(0, 0, viewportNode.width, viewportNode.height); + final AffineMatrix transform = viewportNode.concatTransform(data); + return ViewportNode( + SvgAttributes.empty, + width: viewportNode.width, + height: viewportNode.height, + transform: AffineMatrix.identity, + children: [ + for (final Node child in viewportNode.children) + child + .applyAttributes(viewportNode.attributes) + .accept(this, transform), + ], + ); + } + + @override + Node visitDeferredNode(DeferredNode deferredNode, AffineMatrix data) { + final AttributedNode? resolvedNode = + deferredNode.resolver(deferredNode.refId); + if (resolvedNode == null) { + return Node.empty; + } + final Node concreteRef = resolvedNode.applyAttributes( + deferredNode.attributes, + replace: true, + ); + return concreteRef.accept(this, data); + } + + @override + Node visitEmptyNode(Node node, AffineMatrix data) => node; + + @override + Node visitResolvedText(ResolvedTextNode textNode, AffineMatrix data) { + assert(false); + return textNode; + } + + @override + Node visitResolvedTextPositionNode( + ResolvedTextPositionNode textPositionNode, AffineMatrix data) { + assert(false); + return textPositionNode; + } + + @override + Node visitResolvedPath(ResolvedPathNode pathNode, AffineMatrix data) { + assert(false); + return pathNode; + } + + @override + Node visitResolvedClipNode(ResolvedClipNode clipNode, AffineMatrix data) { + assert(false); + return clipNode; + } + + @override + Node visitResolvedMaskNode(ResolvedMaskNode maskNode, AffineMatrix data) { + assert(false); + return maskNode; + } + + @override + Node visitSaveLayerNode(SaveLayerNode layerNode, AffineMatrix data) { + assert(false); + return layerNode; + } + + @override + Node visitResolvedVerticesNode( + ResolvedVerticesNode verticesNode, AffineMatrix data) { + assert(false); + return verticesNode; + } + + @override + Node visitImageNode(ImageNode imageNode, AffineMatrix data) { + final AffineMatrix childTransform = imageNode.concatTransform(data); + + final SvgAttributes attributes = imageNode.attributes; + final double left = double.parse(attributes.raw['x'] ?? '0'); + final double top = double.parse(attributes.raw['y'] ?? '0'); + + double? width = double.tryParse(attributes.raw['width'] ?? ''); + double? height = double.tryParse(attributes.raw['height'] ?? ''); + if (width == null || height == null) { + final ImageSizeData data = ImageSizeData.fromBytes(imageNode.data); + width ??= data.width.toDouble(); + height ??= data.height.toDouble(); + } + final Rect rect = Rect.fromLTWH(left, top, width, height); + + // Determine if this image can be drawn without any transforms because + // it only has an offset and/or scale. + if (childTransform.encodableInRect) { + // trivial transform. + return ResolvedImageNode( + data: imageNode.data, + format: imageNode.format, + rect: childTransform.transformRect(rect), + transform: null, + ); + } + + // Non-trivial transform. + return ResolvedImageNode( + data: imageNode.data, + format: imageNode.format, + rect: rect, + transform: childTransform, + ); + } + + @override + Node visitResolvedImageNode( + ResolvedImageNode resolvedImageNode, AffineMatrix data) { + assert(false); + return resolvedImageNode; + } + + @override + Node visitPatternNode(PatternNode node, AffineMatrix data) { + final AttributedNode? resolvedPattern = node.resolver(node.patternId); + if (resolvedPattern == null) { + return node.child.accept(this, data); + } + final Node child = node.child.accept(this, data); + final AffineMatrix childTransform = node.concatTransform(data); + final Node pattern = resolvedPattern.accept(this, childTransform); + + return ResolvedPatternNode( + child: child, + pattern: pattern, + x: resolvedPattern.attributes.x?.calculate(0) ?? 0, + y: resolvedPattern.attributes.y?.calculate(0) ?? 0, + width: resolvedPattern.attributes.width!, + height: resolvedPattern.attributes.height!, + transform: data, + id: node.patternId, + ); + } + + @override + Node visitResolvedPatternNode( + ResolvedPatternNode patternNode, AffineMatrix data) { + assert(false); + return patternNode; + } +} + +/// A text position update that is final and has a fully known transform. +/// +/// Constructed from a [TextPositionNode] by a [ResolvingVisitor]. +class ResolvedTextPositionNode extends Node { + /// Create a new [ResolvedTextPositionNode]. + ResolvedTextPositionNode(this.textPosition, this.children); + + /// The resolved [TextPosition]. + final TextPosition textPosition; + + /// The children of this node. + final List children; + + @override + void visitChildren(NodeCallback visitor) { + children.forEach(visitor); + } + + @override + S accept(Visitor visitor, V data) { + return visitor.visitResolvedTextPositionNode(this, data); + } +} + +/// A block of text that has its position and final transfrom fully known. +/// +/// This should only be constructed from a [TextNode] in a [ResolvingVisitor]. +class ResolvedTextNode extends Node { + /// Create a new [ResolvedTextNode]. + ResolvedTextNode({ + required this.textConfig, + required this.paint, + }); + + /// The text configuration to draw this piece of text. + final TextConfig textConfig; + + /// The paint used to draw this piece of text. + final Paint paint; + + @override + S accept(Visitor visitor, V data) { + return visitor.visitResolvedText(this, data); + } + + @override + void visitChildren(NodeCallback visitor) {} +} + +/// A path node that has its bounds fully computed. +/// +/// This should only be constructed from a [PathNode] in a [ResolvingVisitor]. +class ResolvedPathNode extends Node { + /// Create a new [ResolvedPathNode]. + ResolvedPathNode({ + required this.paint, + required this.bounds, + required this.path, + }); + + /// The paint for the current path node. + final Paint paint; + + /// The bounds estimate for the current path. + final Rect bounds; + + /// The path to be drawn. + final Path path; + + @override + S accept(Visitor visitor, V data) { + return visitor.visitResolvedPath(this, data); + } + + @override + void visitChildren(NodeCallback visitor) {} +} + +/// A node that draws resolved vertices. +class ResolvedVerticesNode extends Node { + /// Create a new [ResolvedVerticesNode] + ResolvedVerticesNode({ + required this.paint, + required this.vertices, + required this.bounds, + }) : assert(paint.stroke == null); + + /// The paint (fill only) to draw on the given node. + final Paint paint; + + /// The vertices to be drawn. + final IndexedVertices vertices; + + /// The original bounds of the path that created this node. + final Rect bounds; + + @override + S accept(Visitor visitor, V data) { + return visitor.visitResolvedVerticesNode(this, data); + } + + @override + void visitChildren(NodeCallback visitor) {} +} + +/// A clip node where all paths are known and transformed in a single +/// coordinate space. +/// +/// This should only be constructed from a [ClipNode] in a [ResolvingVisitor]. +class ResolvedClipNode extends Node { + /// Create a new [ResolvedClipNode]. + ResolvedClipNode({ + required this.clips, + required this.child, + }); + + /// One or more clips to apply to rendered children. + final List clips; + + /// The child node. + final Node child; + + @override + S accept(Visitor visitor, V data) { + return visitor.visitResolvedClipNode(this, data); + } + + @override + void visitChildren(NodeCallback visitor) { + visitor(child); + } +} + +/// A mask node with child and mask fully resolved. +/// +/// This should only be constructed from a [MaskNode] in a [ResolvingVisitor]. +class ResolvedMaskNode extends Node { + /// Create a new [ResolvedMaskNode]. + ResolvedMaskNode({ + required this.child, + required this.mask, + required this.blendMode, + }); + + /// The child to apply as a mask. + final Node mask; + + /// The child of this mask layer. + final Node child; + + /// The blend mode to apply when saving a layer for the mask, if any. + final BlendMode? blendMode; + + @override + S accept(Visitor visitor, V data) { + return visitor.visitResolvedMaskNode(this, data); + } + + @override + void visitChildren(NodeCallback visitor) { + visitor(child); + } +} + +/// An image node that has a fully resolved position and data. +class ResolvedImageNode extends Node { + /// Create a new [ResolvedImageNode]. + const ResolvedImageNode({ + required this.data, + required this.format, + required this.rect, + required this.transform, + }); + + /// The image [data] encoded as a PNG. + final Uint8List data; + + /// The format of [data]. + final ImageFormat format; + + /// The region to draw the image to. + final Rect rect; + + /// An optional transform. + /// + /// This is set when the accumulated image transform causes the image rect + /// to not stay rectangular. + final AffineMatrix? transform; + + @override + S accept(Visitor visitor, V data) { + return visitor.visitResolvedImageNode(this, data); + } + + @override + void visitChildren(NodeCallback visitor) {} +} + +/// A pattern node that has a fully resolved position and data. +class ResolvedPatternNode extends Node { + /// Creates a new [ResolvedPatternNode]. + + ResolvedPatternNode({ + required this.child, + required this.pattern, + required this.width, + required this.x, + required this.y, + required this.height, + required this.transform, + required this.id, + }); + + /// The child to apply a pattern to. + final Node child; + + /// A node that represents the pattern. + final Node pattern; + + /// The x coordinate shift of the pattern tile. + final double x; + + /// The y coordinate shift of the pattern tile. + final double y; + + /// The width of the pattern's viewbox in px. + /// Values must be > = 1. + final double width; + + /// The height of the pattern's viewbox in px. + /// Values must be > = 1. + final double height; + + /// A unique identifier for the [pattern]. + final Object id; + + /// This is the transform of the pattern that has been created from the children. + AffineMatrix transform; + + @override + void visitChildren(NodeCallback visitor) { + visitor(child); + } + + @override + S accept(Visitor visitor, V data) { + return visitor.visitResolvedPatternNode(this, data); + } +} diff --git a/packages/vector_graphics_compiler/lib/src/svg/tessellator.dart b/packages/vector_graphics_compiler/lib/src/svg/tessellator.dart new file mode 100644 index 000000000000..feaea57e57e6 --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/svg/tessellator.dart @@ -0,0 +1,57 @@ +// 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 '_tessellator_unsupported.dart' + if (dart.library.ffi) '_tessellator_ffi.dart' as impl; +import 'node.dart'; +import 'visitor.dart'; + +/// Whether or not tesselation should be used. +bool get isTesselatorInitialized => impl.isTesselatorInitialized; + +/// Initialize the libtesselator dynamic library. +/// +/// This method must be called before [VerticesBuilder] can be used or +/// constructed. +void initializeLibTesselator(String path) => impl.initializeLibTesselator(path); + +/// Information about how to approximate points on a curved path segment. +/// +/// In particular, the values in this object control how many vertices to +/// generate when approximating curves, and what tolerances to use when +/// calculating the sharpness of curves. +/// +/// Used by [VerticesBuilder.tessellate]. +class SmoothingApproximation { + /// Creates a new smoothing approximation instance with default values. + const SmoothingApproximation({ + this.scale = 1.0, + this.angleTolerance = 0.0, + this.cuspLimit = 0.0, + }); + + /// The scaling coefficient to use when translating to screen coordinates. + /// + /// Values approaching 0.0 will generate smoother looking curves with a + /// greater number of vertices, and will be more expensive to calculate. + final double scale; + + /// The tolerance value in radians for calculating sharp angles. + /// + /// Values approaching 0.0 will provide more accurate approximation of sharp + /// turns. A 0.0 vlaue means angle conditions are not considered at all. + final double angleTolerance; + + /// An angle in radians at which to introduce bevel cuts. + /// + /// Values greater than zero will restirct the sharpness of bevel cuts on + /// turns. + final double cuspLimit; +} + +/// A visitor that replaces fill paths with tesselated vertices. +abstract class Tessellator extends Visitor { + /// Create a new [Tessellator] visitor. + factory Tessellator() = impl.Tessellator; +} diff --git a/packages/vector_graphics_compiler/lib/src/svg/theme.dart b/packages/vector_graphics_compiler/lib/src/svg/theme.dart new file mode 100644 index 000000000000..d82ed511ccce --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/svg/theme.dart @@ -0,0 +1,53 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:meta/meta.dart'; + +import '../paint.dart'; + +/// A theme used when decoding an SVG picture. +@immutable +class SvgTheme { + /// Instantiates an SVG theme with the [currentColor] + /// and [fontSize]. + /// + /// Defaults the [fontSize] to 14. + const SvgTheme({ + this.currentColor = Color.opaqueBlack, + this.fontSize = 14, + double? xHeight, + }) : xHeight = xHeight ?? fontSize / 2; + + /// The default color applied to SVG elements that inherit the color property. + /// See: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#currentcolor_keyword + final Color currentColor; + + /// The font size used when calculating em units of SVG elements. + /// See: https://www.w3.org/TR/SVG11/coords.html#Units + final double fontSize; + + /// The x-height (corpus size) of the font used when calculating ex units of SVG elements. + /// Defaults to [fontSize] / 2 if not provided. + /// See: https://www.w3.org/TR/SVG11/coords.html#Units, https://en.wikipedia.org/wiki/X-height + final double xHeight; + + @override + bool operator ==(Object other) { + if (other.runtimeType != runtimeType) { + return false; + } + + return other is SvgTheme && + currentColor == other.currentColor && + fontSize == other.fontSize && + xHeight == other.xHeight; + } + + @override + int get hashCode => Object.hash(currentColor, fontSize, xHeight); + + @override + String toString() => + 'SvgTheme(currentColor: $currentColor, fontSize: $fontSize, xHeight: $xHeight)'; +} diff --git a/packages/vector_graphics_compiler/lib/src/svg/visitor.dart b/packages/vector_graphics_compiler/lib/src/svg/visitor.dart new file mode 100644 index 000000000000..b92d3746a423 --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/svg/visitor.dart @@ -0,0 +1,242 @@ +// 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 '../draw_command_builder.dart'; +import '../geometry/path.dart'; +import '../paint.dart'; +import '../vector_instructions.dart'; +import 'node.dart'; +import 'resolver.dart'; + +/// A visitor implementation used to process the tree. +abstract class Visitor { + /// Const constructor so subclasses can be const. + const Visitor(); + + /// Visit a [ViewportNode]. + S visitViewportNode(ViewportNode viewportNode, V data); + + /// Visit a [MaskNode]. + S visitMaskNode(MaskNode maskNode, V data); + + /// Visit a [ClipNode]. + S visitClipNode(ClipNode clipNode, V data); + + /// Visit a [TextPositionNode]. + S visitTextPositionNode(TextPositionNode textPositionNode, V data); + + /// Visit a [TextNode]. + S visitTextNode(TextNode textNode, V data); + + /// VIsit an [ImageNode]. + S visitImageNode(ImageNode imageNode, V data); + + /// Visit a [PathNode]. + S visitPathNode(PathNode pathNode, V data); + + /// Visit a [ParentNode]. + S visitParentNode(ParentNode parentNode, V data); + + /// Visit a [DeferredNode]. + S visitDeferredNode(DeferredNode deferredNode, V data); + + /// Visit a [Node] that has no meaningful content. + S visitEmptyNode(Node node, V data); + + /// Visit a [PatternNode]. + S visitPatternNode(PatternNode node, V data); + + /// Visit a [ResolvedTextPositionNode]. + S visitResolvedTextPositionNode( + ResolvedTextPositionNode textPositionNode, V data); + + /// Visit a [ResolvedTextNode]. + S visitResolvedText(ResolvedTextNode textNode, V data); + + /// Visit a [ResolvedPathNode]. + S visitResolvedPath(ResolvedPathNode pathNode, V data); + + /// Visit a [ResolvedClipNode]. + S visitResolvedClipNode(ResolvedClipNode clipNode, V data); + + /// Visit a [ResolvedMaskNode]. + S visitResolvedMaskNode(ResolvedMaskNode maskNode, V data); + + /// Visit a [ResolvedImageNode]. + S visitResolvedImageNode(ResolvedImageNode resolvedImageNode, V data); + + /// Visit a [SaveLayerNode]. + S visitSaveLayerNode(SaveLayerNode layerNode, V data); + + /// Visit a [ResolvedVerticesNode]. + S visitResolvedVerticesNode(ResolvedVerticesNode verticesNode, V data); + + /// Visit a [ResolvedPatternNode]. + S visitResolvedPatternNode(ResolvedPatternNode patternNode, V data); +} + +/// A mixin that can be applied to a [Visitor] that makes visiting an +/// unreloved [Node] an error. +mixin ErrorOnUnResolvedNode on Visitor { + String get _message => 'Cannot visit unresolved nodes with $this'; + + @override + S visitDeferredNode(DeferredNode deferredNode, V data) { + throw UnsupportedError(_message); + } + + @override + S visitMaskNode(MaskNode maskNode, V data) { + throw UnsupportedError(_message); + } + + @override + S visitClipNode(ClipNode clipNode, V data) { + throw UnsupportedError(_message); + } + + @override + S visitTextPositionNode(TextPositionNode textPositionNode, V data) { + throw UnsupportedError(_message); + } + + @override + S visitTextNode(TextNode textNode, V data) { + throw UnsupportedError(_message); + } + + @override + S visitPathNode(PathNode pathNode, V data) { + throw UnsupportedError(_message); + } + + @override + S visitImageNode(ImageNode imageNode, V data) { + throw UnsupportedError(_message); + } + + @override + S visitPatternNode(PatternNode patternNode, V data) { + throw UnsupportedError(_message); + } +} + +/// A visitor that builds up a [VectorInstructions] for binary encoding. +class CommandBuilderVisitor extends Visitor + with ErrorOnUnResolvedNode { + final DrawCommandBuilder _builder = DrawCommandBuilder(); + late double _width; + late double _height; + + /// The current patternId. This will be `null` if + /// there is no current pattern. + Object? currentPatternId; + + /// Return the vector instructions encoded by the visitor given to this tree. + VectorInstructions toInstructions() { + return _builder.toInstructions(_width, _height); + } + + @override + void visitEmptyNode(Node node, void data) {} + + @override + void visitParentNode(ParentNode parentNode, void data) { + for (final Node child in parentNode.children) { + child.accept(this, data); + } + } + + @override + void visitPathNode(PathNode pathNode, void data) { + assert(false); + } + + @override + void visitResolvedClipNode(ResolvedClipNode clipNode, void data) { + for (final Path clip in clipNode.clips) { + _builder.addClip(clip); + clipNode.child.accept(this, data); + _builder.restore(); + } + } + + @override + void visitResolvedMaskNode(ResolvedMaskNode maskNode, void data) { + _builder.addSaveLayer(Paint( + blendMode: maskNode.blendMode, + fill: const Fill(), + )); + maskNode.child.accept(this, data); + _builder.addMask(); + maskNode.mask.accept(this, data); + _builder.restore(); + _builder.restore(); + } + + @override + void visitResolvedPath(ResolvedPathNode pathNode, void data) { + _builder.addPath(pathNode.path, pathNode.paint, null, currentPatternId); + } + + @override + void visitResolvedTextPositionNode( + ResolvedTextPositionNode textPositionNode, void data) { + _builder.updateTextPosition(textPositionNode.textPosition); + textPositionNode.visitChildren((Node child) { + child.accept(this, data); + }); + } + + @override + void visitResolvedText(ResolvedTextNode textNode, void data) { + _builder.addText( + textNode.textConfig, textNode.paint, null, currentPatternId); + } + + @override + void visitViewportNode(ViewportNode viewportNode, void data) { + _width = viewportNode.width; + _height = viewportNode.height; + for (final Node child in viewportNode.children) { + child.accept(this, data); + } + } + + @override + void visitSaveLayerNode(SaveLayerNode layerNode, void data) { + _builder.addSaveLayer(layerNode.paint); + for (final Node child in layerNode.children) { + child.accept(this, data); + } + _builder.restore(); + } + + @override + void visitResolvedVerticesNode(ResolvedVerticesNode verticesNode, void data) { + _builder.addVertices(verticesNode.vertices, verticesNode.paint); + } + + @override + void visitResolvedImageNode(ResolvedImageNode resolvedImageNode, void data) { + _builder.addImage(resolvedImageNode, null); + } + + @override + void visitResolvedPatternNode(ResolvedPatternNode patternNode, void data) { + _builder.addPattern( + patternNode.id, + x: patternNode.x, + y: patternNode.y, + width: patternNode.width, + height: patternNode.height, + transform: patternNode.transform, + ); + patternNode.pattern.accept(this, data); + _builder.restore(); + currentPatternId = patternNode.id; + patternNode.child.accept(this, data); + currentPatternId = null; + } +} diff --git a/packages/vector_graphics_compiler/lib/src/util.dart b/packages/vector_graphics_compiler/lib/src/util.dart new file mode 100644 index 000000000000..829016f7a92c --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/util.dart @@ -0,0 +1,36 @@ +// 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. + +/// A utility method for comparing lists for equality. +/// +/// This method assumes that [T] implements a meaningful equality operator. +/// Therefore, thi method should not be used to compare lists containing +/// nested lists. +bool listEquals(List? a, List? b) { + if (a == null) { + return b == null; + } + if (b == null || a.length != b.length) { + return false; + } + if (identical(a, b)) { + return true; + } + for (int index = 0; index < a.length; index += 1) { + if (a[index] != b[index]) { + return false; + } + } + return true; +} + +/// Linearly interpolates between two doubles by factor t. +@pragma('vm:prefer-inline') +double lerpDouble(double a, double b, double t) { + assert(a.isFinite); + assert(b.isFinite); + assert(t <= 1.0); + assert(t >= 0.0); + return (1 - t) * a + t * b; +} diff --git a/packages/vector_graphics_compiler/lib/src/vector_instructions.dart b/packages/vector_graphics_compiler/lib/src/vector_instructions.dart new file mode 100644 index 000000000000..edff5dfa2a52 --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/vector_instructions.dart @@ -0,0 +1,237 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:meta/meta.dart'; + +import 'geometry/image.dart'; +import 'geometry/path.dart'; +import 'geometry/pattern.dart'; +import 'geometry/vertices.dart'; +import 'paint.dart'; +import 'util.dart'; + +/// An immutable collection of vector instructions, with [width] and [height] +/// specifying the viewport coordinates. +@immutable +class VectorInstructions { + /// Creates a new set of [VectorInstructions]. + /// + /// The combined lengths of [paths] and [vertices] must be greater than 0. + const VectorInstructions({ + required this.width, + required this.height, + required this.paints, + this.paths = const [], + this.vertices = const [], + this.text = const [], + this.images = const [], + this.drawImages = const [], + this.patternData = const [], + this.textPositions = const [], + required this.commands, + }); + + /// The extent of the viewport on the x axis. + final double width; + + /// The extent of the viewport on the y axis. + final double height; + + /// The [Paint] objects used in [commands]. + final List paints; + + /// The [Path] objects, if any, used in [commands]. + final List paths; + + /// The [IndexedVertices] objects, if any, used in [commands]. + final List vertices; + + /// The [TextConfig] objects, if any, used in [commands]. + final List text; + + /// The [ImageData] objects, if any, used in [commands]. + final List images; + + /// The [DrawImageData] objects, if any, used in [commands]. + final List drawImages; + + /// The pattern data objects, if any used in [commands]. + final List patternData; + + /// A list of text position advances, if any, used in [commands]. + final List textPositions; + + /// The painting order list of drawing commands. + /// + /// If the command type is [DrawCommandType.path], this command specifies + /// drawing with [paths]. If it is [DrawCommandType.vertices], this command + /// specifies drawing with [vertices]. + /// + /// If drawing using vertices, the [Paint.stroke] property is ignored. + final List commands; + + @override + int get hashCode => Object.hash( + width, + height, + Object.hashAll(patternData), + Object.hashAll(paints), + Object.hashAll(paths), + Object.hashAll(vertices), + Object.hashAll(text), + Object.hashAll(commands), + Object.hashAll(images), + Object.hashAll(drawImages), + Object.hashAll(textPositions)); + + @override + bool operator ==(Object other) { + return other is VectorInstructions && + other.width == width && + other.height == height && + listEquals(other.patternData, patternData) && + listEquals(other.paints, paints) && + listEquals(other.paths, paths) && + listEquals(other.vertices, vertices) && + listEquals(other.text, text) && + listEquals(other.commands, commands) && + listEquals(other.images, images) && + listEquals(other.drawImages, drawImages) && + listEquals(other.textPositions, textPositions); + } + + @override + String toString() => 'VectorInstructions($width, $height)'; +} + +/// The drawing mode of a [DrawCommand]. +/// +/// See [DrawCommand.type] and [VectorInstructions.commands]. +enum DrawCommandType { + /// Specifies that this command draws a [Path]. + path, + + /// Specifies that this command draws an [IndexedVertices] object. + /// + /// In this case, any [Stroke] properties on the [Paint] are ignored. + vertices, + + /// Specifies that this command saves a layer. + /// + /// In this case, any [Stroke] properties on the [Paint] are ignored. + saveLayer, + + /// Specifies that this command restores a layer. + /// + /// In this case, both the objectId and paintId will be `null`. + restore, + + /// Specifies that this command adds a clip to the stack. + /// + /// In this case, the objectId will be for a path, and the paint id will be + /// `null`. + clip, + + /// Specifies that this command adds a mask to the stack. + /// + /// Implementations should save a layer using a grey scale color matrix. + mask, + + /// Specifies that this command draws text. + text, + + /// Specifies that this command draws an image. + image, + + /// Specifies that this command draws a pattern. + pattern, + + /// Specifies an adjustment to the current text position. + textPosition, +} + +/// A drawing command combining the index of a [Path] or an [IndexedVertices] +/// with a [Paint]. +/// +/// The type of object is specified by [type]. +/// +/// The debug string property is some identifier, possibly from the source SVG, +/// identifying an original source for this information. +@immutable +class DrawCommand { + /// Creates a new canvas drawing operation. + /// + /// See [DrawCommand]. + const DrawCommand( + this.type, { + this.objectId, + this.paintId, + this.debugString, + this.patternId, + this.patternDataId, + }); + + /// A string, possibly from the original source SVG file, identifying a source + /// for this command. + final String? debugString; + + /// Whether [objectId] points to a [Path] or a [IndexedVertices] object in + /// [VectorInstructions]. + final DrawCommandType type; + + /// The path or vertices object index in [VectorInstructions.paths] or + /// [VectorInstructions.vertices]. + /// + /// A value of `null` indicates that there is no object associated with + /// this command. + /// + /// Use [type] to determine which type of object this is. + final int? objectId; + + /// The index of a [Paint] for this object in [VectorInstructions.paints]. + /// + /// A value of `null` indicates that there is no paint object associated with + /// this command. + final int? paintId; + + /// The index of a pattern for this object in [VectorInstructions.patterns]. + final int? patternId; + + /// The index of a pattern configuration for this object in + /// [VectorInstructions.patternData]. + final int? patternDataId; + + @override + int get hashCode => Object.hash(type, objectId, paintId, debugString); + + @override + bool operator ==(Object other) { + return other is DrawCommand && + other.type == type && + other.objectId == objectId && + other.paintId == paintId; + } + + @override + String toString() { + final StringBuffer buffer = StringBuffer('DrawCommand($type'); + if (objectId != null) { + buffer.write(', objectId: $objectId'); + } + if (paintId != null) { + buffer.write(', paintId: $paintId'); + } + if (debugString != null) { + buffer.write(", debugString: '$debugString'"); + } + if (patternId != null) { + buffer.write(', patternId: $patternId'); + } + if (patternDataId != null) { + buffer.write(', patternDataId: $patternDataId'); + } + buffer.write(')'); + return buffer.toString(); + } +} diff --git a/packages/vector_graphics_compiler/lib/vector_graphics_compiler.dart b/packages/vector_graphics_compiler/lib/vector_graphics_compiler.dart new file mode 100644 index 000000000000..206041b7d264 --- /dev/null +++ b/packages/vector_graphics_compiler/lib/vector_graphics_compiler.dart @@ -0,0 +1,352 @@ +// 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:typed_data'; + +import 'package:vector_graphics_codec/vector_graphics_codec.dart'; + +import 'src/geometry/image.dart'; +import 'src/geometry/matrix.dart'; +import 'src/geometry/path.dart'; +import 'src/geometry/pattern.dart'; +import 'src/geometry/vertices.dart'; +import 'src/paint.dart'; +import 'src/svg/color_mapper.dart'; +import 'src/svg/parser.dart'; +import 'src/svg/theme.dart'; +import 'src/vector_instructions.dart'; + +export 'src/_initialize_path_ops_io.dart' + if (dart.library.js_interop) 'src/_initialize_path_ops_web.dart'; +export 'src/_initialize_tessellator_io.dart' + if (dart.library.js_interop) 'src/_initialize_tessellator_web.dart'; +export 'src/geometry/basic_types.dart'; +export 'src/geometry/matrix.dart'; +export 'src/geometry/path.dart'; +export 'src/geometry/vertices.dart'; +export 'src/paint.dart'; +export 'src/svg/color_mapper.dart'; +export 'src/svg/path_ops.dart' show initializeLibPathOps; +export 'src/svg/resolver.dart'; +export 'src/svg/tessellator.dart' show initializeLibTesselator; +export 'src/svg/theme.dart'; +export 'src/vector_instructions.dart'; + +/// Parses an SVG string into a [VectorInstructions] object, with all optional +/// optimizers disabled. +VectorInstructions parseWithoutOptimizers( + String xml, { + String key = '', + bool warningsAsErrors = false, + SvgTheme theme = const SvgTheme(), +}) { + return parse( + xml, + key: key, + warningsAsErrors: warningsAsErrors, + theme: theme, + enableClippingOptimizer: false, + enableMaskingOptimizer: false, + enableOverdrawOptimizer: false, + ); +} + +/// Parses an SVG string into a [VectorInstructions] object. +VectorInstructions parse( + String xml, { + String key = '', + bool warningsAsErrors = false, + SvgTheme theme = const SvgTheme(), + bool enableMaskingOptimizer = true, + bool enableClippingOptimizer = true, + bool enableOverdrawOptimizer = true, + ColorMapper? colorMapper, +}) { + final SvgParser parser = SvgParser( + xml, + theme, + key, + warningsAsErrors, + colorMapper, + ); + parser.enableMaskingOptimizer = enableMaskingOptimizer; + parser.enableClippingOptimizer = enableClippingOptimizer; + parser.enableOverdrawOptimizer = enableOverdrawOptimizer; + return parser.parse(); +} + +Float64List? _encodeMatrix(AffineMatrix? matrix) { + if (matrix == null || matrix == AffineMatrix.identity) { + return null; + } + return matrix.toMatrix4(); +} + +void _encodeShader( + Gradient? shader, + Map shaderIds, + VectorGraphicsCodec codec, + VectorGraphicsBuffer buffer, +) { + if (shader == null) { + return; + } + int shaderId; + if (shader is LinearGradient) { + shaderId = codec.writeLinearGradient( + buffer, + fromX: shader.from.x, + fromY: shader.from.y, + toX: shader.to.x, + toY: shader.to.y, + colors: Int32List.fromList( + [for (final Color color in shader.colors!) color.value]), + offsets: Float32List.fromList(shader.offsets!), + tileMode: shader.tileMode!.index, + ); + } else if (shader is RadialGradient) { + shaderId = codec.writeRadialGradient( + buffer, + centerX: shader.center.x, + centerY: shader.center.y, + radius: shader.radius, + focalX: shader.focalPoint?.x, + focalY: shader.focalPoint?.y, + colors: Int32List.fromList( + [for (final Color color in shader.colors!) color.value]), + offsets: Float32List.fromList(shader.offsets!), + tileMode: shader.tileMode!.index, + transform: _encodeMatrix(shader.transform), + ); + } else { + assert(false); + throw StateError('illegal shader type: $shader'); + } + shaderIds[shader] = shaderId; +} + +/// String input, String filename +/// Encode an SVG [input] string into a vector_graphics binary format. +Uint8List encodeSvg({ + required String xml, + required String debugName, + SvgTheme theme = const SvgTheme(), + bool enableMaskingOptimizer = true, + bool enableClippingOptimizer = true, + bool enableOverdrawOptimizer = true, + bool warningsAsErrors = false, + bool useHalfPrecisionControlPoints = false, + ColorMapper? colorMapper, +}) { + return _encodeInstructions( + parse( + xml, + key: debugName, + theme: theme, + enableMaskingOptimizer: enableMaskingOptimizer, + enableClippingOptimizer: enableClippingOptimizer, + enableOverdrawOptimizer: enableOverdrawOptimizer, + warningsAsErrors: warningsAsErrors, + colorMapper: colorMapper, + ), + useHalfPrecisionControlPoints, + ); +} + +Uint8List _encodeInstructions( + VectorInstructions instructions, + bool useHalfPrecisionControlPoints, +) { + const VectorGraphicsCodec codec = VectorGraphicsCodec(); + final VectorGraphicsBuffer buffer = VectorGraphicsBuffer(); + + codec.writeSize(buffer, instructions.width, instructions.height); + + final Map fillIds = {}; + final Map strokeIds = {}; + final Map shaderIds = {}; + + for (final ImageData data in instructions.images) { + codec.writeImage(buffer, data.format, data.data); + } + + for (final Paint paint in instructions.paints) { + _encodeShader(paint.fill?.shader, shaderIds, codec, buffer); + _encodeShader(paint.stroke?.shader, shaderIds, codec, buffer); + } + + int nextPaintId = 0; + for (final Paint paint in instructions.paints) { + final Fill? fill = paint.fill; + final Stroke? stroke = paint.stroke; + + if (fill != null) { + final int? shaderId = shaderIds[fill.shader]; + final int fillId = codec.writeFill( + buffer, + fill.color.value, + paint.blendMode.index, + shaderId, + ); + fillIds[nextPaintId] = fillId; + } + if (stroke != null) { + final int? shaderId = shaderIds[stroke.shader]; + final int strokeId = codec.writeStroke( + buffer, + stroke.color.value, + stroke.cap?.index ?? 0, + stroke.join?.index ?? 0, + paint.blendMode.index, + stroke.miterLimit ?? 4, + stroke.width ?? 1, + shaderId, + ); + strokeIds[nextPaintId] = strokeId; + } + nextPaintId += 1; + } + + final Map pathIds = {}; + int nextPathId = 0; + for (final Path path in instructions.paths) { + final List controlPointTypes = []; + final List controlPoints = []; + + for (final PathCommand command in path.commands) { + switch (command.type) { + case PathCommandType.move: + final MoveToCommand move = command as MoveToCommand; + controlPointTypes.add(ControlPointTypes.moveTo); + controlPoints.addAll([move.x, move.y]); + case PathCommandType.line: + final LineToCommand line = command as LineToCommand; + controlPointTypes.add(ControlPointTypes.lineTo); + controlPoints.addAll([line.x, line.y]); + case PathCommandType.cubic: + final CubicToCommand cubic = command as CubicToCommand; + controlPointTypes.add(ControlPointTypes.cubicTo); + controlPoints.addAll([ + cubic.x1, + cubic.y1, + cubic.x2, + cubic.y2, + cubic.x3, + cubic.y3, + ]); + case PathCommandType.close: + controlPointTypes.add(ControlPointTypes.close); + } + } + final int id = codec.writePath( + buffer, + Uint8List.fromList(controlPointTypes), + Float32List.fromList(controlPoints), + path.fillType.index, + half: useHalfPrecisionControlPoints, + ); + pathIds[nextPathId] = id; + nextPathId += 1; + } + + for (final TextPosition position in instructions.textPositions) { + codec.writeTextPosition( + buffer, + position.x, + position.y, + position.dx, + position.dy, + position.reset, + position.transform?.toMatrix4(), + ); + } + + for (final TextConfig textConfig in instructions.text) { + codec.writeTextConfig( + buffer: buffer, + text: textConfig.text, + fontFamily: textConfig.fontFamily, + xAnchorMultiplier: textConfig.xAnchorMultiplier, + fontWeight: textConfig.fontWeight.index, + fontSize: textConfig.fontSize, + decoration: textConfig.decoration.mask, + decorationStyle: textConfig.decorationStyle.index, + decorationColor: textConfig.decorationColor.value, + ); + } + + for (final DrawCommand command in instructions.commands) { + switch (command.type) { + case DrawCommandType.path: + if (fillIds.containsKey(command.paintId)) { + codec.writeDrawPath( + buffer, + pathIds[command.objectId]!, + fillIds[command.paintId]!, + command.patternId, + ); + } + if (strokeIds.containsKey(command.paintId)) { + codec.writeDrawPath( + buffer, + pathIds[command.objectId]!, + strokeIds[command.paintId]!, + command.patternId, + ); + } + case DrawCommandType.vertices: + final IndexedVertices vertices = + instructions.vertices[command.objectId!]; + final int fillId = fillIds[command.paintId]!; + codec.writeDrawVertices( + buffer, vertices.vertices, vertices.indices, fillId); + case DrawCommandType.saveLayer: + codec.writeSaveLayer(buffer, fillIds[command.paintId]!); + case DrawCommandType.restore: + codec.writeRestoreLayer(buffer); + case DrawCommandType.clip: + codec.writeClipPath(buffer, pathIds[command.objectId]!); + case DrawCommandType.mask: + codec.writeMask(buffer); + + case DrawCommandType.pattern: + final PatternData patternData = + instructions.patternData[command.patternDataId!]; + codec.writePattern( + buffer, + patternData.x, + patternData.y, + patternData.width, + patternData.height, + patternData.transform.toMatrix4(), + ); + + case DrawCommandType.textPosition: + codec.writeUpdateTextPosition(buffer, command.objectId!); + + case DrawCommandType.text: + codec.writeDrawText( + buffer, + command.objectId!, + fillIds[command.paintId], + strokeIds[command.paintId], + command.patternId, + ); + + case DrawCommandType.image: + final DrawImageData drawImageData = + instructions.drawImages[command.objectId!]; + codec.writeDrawImage( + buffer, + drawImageData.id, + drawImageData.rect.left, + drawImageData.rect.top, + drawImageData.rect.width, + drawImageData.rect.height, + drawImageData.transform?.toMatrix4(), + ); + } + } + return buffer.done().buffer.asUint8List(); +} diff --git a/packages/vector_graphics_compiler/pubspec.yaml b/packages/vector_graphics_compiler/pubspec.yaml new file mode 100644 index 000000000000..6c86d50b38af --- /dev/null +++ b/packages/vector_graphics_compiler/pubspec.yaml @@ -0,0 +1,47 @@ +name: vector_graphics_compiler +description: A compiler to convert SVGs to the binary format used by `package:vector_graphics`. +repository: https://github.com/flutter/packages/tree/main/packages/vector_graphics_compiler +issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+vector_graphics%22 +version: 1.1.14 + +executables: + vector_graphics_compiler: + +environment: + sdk: ^3.4.0 + +dependencies: + args: ^2.3.0 + meta: ^1.7.0 + path: ^1.8.0 + path_parsing: ^1.0.1 + vector_graphics_codec: ^1.1.11+1 + # This uses an exact upper range because it is an external dependency (see + # https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#dependencies + # for more information), and this mitigates transitive risk exposure to + # clients. To update this value: + # - Audit the package's source diffs between the current max version listed + # here and the target version. + # - Update the max version here to exactly the audited version. + xml: ">=6.3.0 <=6.5.0" + +dev_dependencies: + flutter: + sdk: flutter + flutter_test: + sdk: flutter + test: ^1.20.1 + vector_graphics: ^1.1.13 + vector_math: ^2.1.2 + +platforms: + android: + ios: + linux: + macos: + web: + windows: + +topics: + - svg + - vector-graphics diff --git a/packages/vector_graphics_compiler/test/basic_types_test.dart b/packages/vector_graphics_compiler/test/basic_types_test.dart new file mode 100644 index 000000000000..ea3d050c63b6 --- /dev/null +++ b/packages/vector_graphics_compiler/test/basic_types_test.dart @@ -0,0 +1,46 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; + +void main() { + test('Point tests', () { + expect(Point.zero.x, 0); + expect(Point.zero.y, 0); + + expect(const Point(5, 5) / 2, const Point(2.5, 2.5)); + expect(const Point(5, 5) * 2, const Point(10, 10)); + }); + + test('Point distance', () { + expect(Point.distance(Point.zero, Point.zero), 0); + expect(Point.distance(Point.zero, const Point(1, 0)), 1); + expect(Point.distance(Point.zero, const Point(0, 1)), 1); + expect(Point.distance(Point.zero, const Point(1, 1)), 1.4142135623730951); + }); + + test('Point lerp', () { + expect(Point.lerp(Point.zero, Point.zero, .3), Point.zero); + expect(Point.lerp(Point.zero, const Point(1, 0), .5), const Point(.5, 0)); + }); + + test('Rect tests', () { + expect(Rect.zero.left, 0); + expect(Rect.zero.top, 0); + expect(Rect.zero.right, 0); + expect(Rect.zero.bottom, 0); + + expect( + const Rect.fromLTRB(1, 2, 3, 4) + .expanded(const Rect.fromLTRB(0, 0, 10, 10)), + const Rect.fromLTRB(0, 0, 10, 10), + ); + + expect( + const Rect.fromCircle(10, 10, 5), + const Rect.fromLTWH(5, 5, 10, 10), + ); + }); +} diff --git a/packages/vector_graphics_compiler/test/cli_test.dart b/packages/vector_graphics_compiler/test/cli_test.dart new file mode 100644 index 000000000000..501790d858b1 --- /dev/null +++ b/packages/vector_graphics_compiler/test/cli_test.dart @@ -0,0 +1,139 @@ +// 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:io'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:path/path.dart' as p; + +import '../bin/util/isolate_processor.dart'; +import '../bin/vector_graphics_compiler.dart' as cli; + +void main() { + final File output = File('test_data/example.vec'); + final File outputDebug = File('test_data/example.vec.debug'); + + test('currentColor/font-size works', () async { + try { + await cli.main([ + '-i', + 'test_data/example.svg', + '-o', + output.path, + '--current-color', + 'red', + '--font-size', + '12', + '--dump-debug', + ]); + expect(output.existsSync(), true); + expect(outputDebug.existsSync(), true); + } finally { + if (output.existsSync()) { + output.deleteSync(); + } + if (outputDebug.existsSync()) { + outputDebug.deleteSync(); + } + } + }); + + test('Can run with isolate processor', () async { + try { + final IsolateProcessor processor = IsolateProcessor(null, null, 4); + final bool result = await processor.process( + [ + Pair('test_data/example.svg', output.path), + ], + maskingOptimizerEnabled: false, + clippingOptimizerEnabled: false, + overdrawOptimizerEnabled: false, + tessellate: false, + dumpDebug: false, + useHalfPrecisionControlPoints: false, + ); + expect(result, isTrue); + expect(output.existsSync(), isTrue); + } finally { + if (output.existsSync()) { + output.deleteSync(); + } + } + }); + + test('Can dump debug format with isolate processor', () async { + try { + final IsolateProcessor processor = IsolateProcessor(null, null, 4); + final bool result = await processor.process( + [ + Pair('test_data/example.svg', output.path), + ], + maskingOptimizerEnabled: false, + clippingOptimizerEnabled: false, + overdrawOptimizerEnabled: false, + tessellate: false, + dumpDebug: true, + useHalfPrecisionControlPoints: false, + ); + expect(result, isTrue); + expect(output.existsSync(), isTrue); + expect(outputDebug.existsSync(), isTrue); + } finally { + if (output.existsSync()) { + output.deleteSync(); + } + if (outputDebug.existsSync()) { + outputDebug.deleteSync(); + } + } + }); + + test('out-dir option works', () async { + const String inputTestDir = 'test_data'; + + const String outTestDir = 'output_vec'; + + try { + await cli.main([ + '--input-dir', + inputTestDir, + '--out-dir', + outTestDir, + ]); + + bool passed = false; + + final Directory inputDir = Directory(inputTestDir); + final Directory outDir = Directory(outTestDir); + + if (inputDir.existsSync() && outDir.existsSync()) { + final List inputTestFiles = inputDir + .listSync(recursive: true) + .whereType() + .where((File element) => element.path.endsWith('svg')) + .map((File e) => p.basenameWithoutExtension(e.path)) + .toList(); + + final List outTestFiles = outDir + .listSync(recursive: true) + .whereType() + .where((File element) => element.path.endsWith('vec')) + .map((File e) => + p.withoutExtension(p.basenameWithoutExtension(e.path))) + .toList(); + + if (listEquals(inputTestFiles, outTestFiles)) { + passed = true; + } + } + + expect(passed, true); + } finally { + if (Directory(outTestDir).existsSync()) { + Directory(outTestDir).deleteSync(recursive: true); + } + } + }); +} diff --git a/packages/vector_graphics_compiler/test/clipping_optimizer_test.dart b/packages/vector_graphics_compiler/test/clipping_optimizer_test.dart new file mode 100644 index 000000000000..811c84cf069b --- /dev/null +++ b/packages/vector_graphics_compiler/test/clipping_optimizer_test.dart @@ -0,0 +1,186 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:vector_graphics_compiler/src/svg/clipping_optimizer.dart'; +import 'package:vector_graphics_compiler/src/svg/node.dart'; +import 'package:vector_graphics_compiler/src/svg/parser.dart'; +import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; + +import 'test_svg_strings.dart'; + +Node parseAndResolve(String source) { + final Node node = parseToNodeTree(source); + final ResolvingVisitor visitor = ResolvingVisitor(); + return node.accept(visitor, AffineMatrix.identity); +} + +List queryChildren(Node node) { + final List children = []; + void visitor(Node child) { + if (child is T) { + children.add(child); + } + child.visitChildren(visitor); + } + + node.visitChildren(visitor); + return children; +} + +void main() { + setUpAll(() { + if (!initializePathOpsFromFlutterCache()) { + fail('error in setup'); + } + }); + + test('Only resolve ClipNode if .clips has one PathNode', () { + final Node node = parseAndResolve(''' + + + + + + + + +'''); + + final ClippingOptimizer visitor = ClippingOptimizer(); + final Node newNode = visitor.apply(node); + + final List clipNodesNew = + queryChildren(newNode); + + expect(clipNodesNew.length, 0); + }); + + test( + "Don't resolve a ClipNode if one of the PathNodes it's applied to has stroke.width set", + () async { + final Node node = parseAndResolve(''' + + + + + +'''); + + final ClippingOptimizer visitor = ClippingOptimizer(); + final Node newNode = visitor.apply(node); + + final List clipNodesNew = + queryChildren(newNode); + + expect(clipNodesNew.length, 1); + }); + + test("Don't resolve ClipNode if intersection of Clip and Path is empty", + () async { + final Node node = parseAndResolve(''' + + + + + + + + + +'''); + final ClippingOptimizer visitor = ClippingOptimizer(); + final Node newNode = visitor.apply(node); + + final List clipNodesNew = + queryChildren(newNode); + + expect(clipNodesNew.length, 1); + }); + + test('ParentNode and PathNode count should stay the same', () async { + final Node node = parseAndResolve(pathAndParent); + + final List pathNodesOld = + queryChildren(node); + final List parentNodesOld = queryChildren(node); + + final ClippingOptimizer visitor = ClippingOptimizer(); + final Node newNode = visitor.apply(node); + + final List pathNodesNew = + queryChildren(newNode); + final List parentNodesNew = queryChildren(newNode); + + expect(pathNodesOld.length, pathNodesNew.length); + expect(parentNodesOld.length, parentNodesNew.length); + }); + + test('Does not combine clips with multiple fill rules', () { + final VectorInstructions instructions = parse(multiClip); + expect(instructions.paths, [ + parseSvgPathData( + 'M 250,75 L 323,301 131,161 369,161 177,301 z', PathFillType.evenOdd), + PathBuilder().addOval(const Rect.fromCircle(400, 200, 150)).toPath(), + parseSvgPathData('M 250,75 L 323,301 131,161 369,161 177,301 z') + .transformed(AffineMatrix.identity.translated(250, 0)), + PathBuilder().addOval(const Rect.fromCircle(450, 300, 150)).toPath(), + ]); + expect(instructions.commands, const [ + DrawCommand(DrawCommandType.clip, objectId: 0), + DrawCommand(DrawCommandType.path, objectId: 1, paintId: 0), + DrawCommand(DrawCommandType.restore), + DrawCommand(DrawCommandType.clip, objectId: 2), + DrawCommand(DrawCommandType.path, objectId: 1, paintId: 0), + DrawCommand(DrawCommandType.restore), + DrawCommand(DrawCommandType.clip, objectId: 0), + DrawCommand(DrawCommandType.path, objectId: 3, paintId: 1), + DrawCommand(DrawCommandType.restore), + DrawCommand(DrawCommandType.clip, objectId: 2), + DrawCommand(DrawCommandType.path, objectId: 3, paintId: 1), + DrawCommand(DrawCommandType.restore), + ]); + }); + + test('Combines clips where possible', () { + final VectorInstructions instructions = + parse(basicClip, enableClippingOptimizer: false); + final VectorInstructions instructionsWithOptimizer = parse(basicClip); + + expect(instructionsWithOptimizer.paths, basicClipsForClippingOptimzer); + + expect(instructions.paths, [ + PathBuilder() + .addOval(const Rect.fromCircle(30, 30, 20)) + .addOval(const Rect.fromCircle(70, 70, 20)) + .toPath(), + PathBuilder().addRect(const Rect.fromLTWH(10, 10, 100, 100)).toPath(), + ]); + expect(instructions.commands, const [ + DrawCommand(DrawCommandType.clip, objectId: 0), + DrawCommand(DrawCommandType.path, objectId: 1, paintId: 0), + DrawCommand(DrawCommandType.restore), + ]); + }); + + test('Preserves fill type changes', () { + const String svg = ''' + + + + + + + + + +'''; + final VectorInstructions instructions = parse(svg); + + expect( + instructions.paths.single.fillType, + PathFillType.evenOdd, + ); + }); +} diff --git a/packages/vector_graphics_compiler/test/draw_command_builder_test.dart b/packages/vector_graphics_compiler/test/draw_command_builder_test.dart new file mode 100644 index 000000000000..13b24b301322 --- /dev/null +++ b/packages/vector_graphics_compiler/test/draw_command_builder_test.dart @@ -0,0 +1,15 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:vector_graphics_compiler/src/draw_command_builder.dart'; +import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; + +void main() { + test('DrawCommandBuilder does not emit empty paths', () { + final DrawCommandBuilder builder = DrawCommandBuilder(); + builder.addPath(Path(), const Paint(), null, null); + expect(builder.toInstructions(100, 100).commands, isEmpty); + }); +} diff --git a/packages/vector_graphics_compiler/test/end_to_end_test.dart b/packages/vector_graphics_compiler/test/end_to_end_test.dart new file mode 100644 index 000000000000..5f225a412a10 --- /dev/null +++ b/packages/vector_graphics_compiler/test/end_to_end_test.dart @@ -0,0 +1,1113 @@ +// 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:convert'; +import 'dart:typed_data'; + +import 'package:flutter/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:vector_graphics/vector_graphics.dart'; +import 'package:vector_graphics_codec/vector_graphics_codec.dart'; +import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; + +import 'test_svg_strings.dart'; + +class TestBytesLoader extends BytesLoader { + const TestBytesLoader(this.data); + + final ByteData data; + + @override + Future loadBytes(BuildContext? context) async { + return data; + } + + @override + int get hashCode => data.hashCode; + + @override + bool operator ==(Object other) { + return other is TestBytesLoader && other.data == data; + } +} + +void main() { + testWidgets('Can endcode and decode simple SVGs with no errors', + (WidgetTester tester) async { + for (final String svg in allSvgTestStrings) { + final Uint8List bytes = encodeSvg( + xml: svg, + debugName: 'test.svg', + warningsAsErrors: true, + enableClippingOptimizer: false, + enableMaskingOptimizer: false, + enableOverdrawOptimizer: false, + ); + + await tester.pumpWidget(Center( + child: VectorGraphic( + loader: TestBytesLoader(bytes.buffer.asByteData())))); + await tester.pumpAndSettle(); + + expect(tester.takeException(), isNull); + } + }); + + testWidgets('Errors on unsupported image mime type', + (WidgetTester tester) async { + const String svgInlineImage = r''' + + + +'''; + + expect( + () => encodeSvg( + xml: svgInlineImage, + debugName: 'test.svg', + warningsAsErrors: true, + enableClippingOptimizer: false, + enableMaskingOptimizer: false, + enableOverdrawOptimizer: false, + ), + throwsA(isA())); + }); + + test('encodeSvg encodes stroke shaders', () async { + const String svg = ''' + + + + + + + + + + + +'''; + + final Uint8List bytes = encodeSvg( + xml: svg, + debugName: 'test', + enableClippingOptimizer: false, + enableMaskingOptimizer: false, + enableOverdrawOptimizer: false, + ); + const VectorGraphicsCodec codec = VectorGraphicsCodec(); + final TestListener listener = TestListener(); + codec.decode(bytes.buffer.asByteData(), listener); + expect(listener.commands, [ + const OnSize(120, 120), + OnLinearGradient( + id: 0, + fromX: 69, + fromY: 59, + toX: 36, + toY: 84, + colors: Int32List.fromList([0xffffffff, 0xff000000]), + offsets: Float32List.fromList([0, 1]), + tileMode: 0, + ), + OnPaintObject( + color: 0xffffffff, + strokeCap: 1, + strokeJoin: 1, + blendMode: BlendMode.srcOver.index, + strokeMiterLimit: 4.0, + strokeWidth: 8, + paintStyle: 1, + id: 0, + shaderId: 0, + ), + const OnPathStart(0, 0), + const OnPathMoveTo(34, 76), + const OnPathLineTo(57, 76), + const OnPathFinished(), + const OnDrawPath(0, 0, null), + ]); + }); + + test('Encodes nested tspan for text', () async { + const String svg = ''' + + + + Plain text Roboto + + Plain text Verdana + + + Bold text Verdana + + + Stroked bold line + Line 3 + + +'''; + + final Uint8List bytes = encodeSvg( + xml: svg, + debugName: 'test', + enableClippingOptimizer: false, + enableMaskingOptimizer: false, + enableOverdrawOptimizer: false, + ); + const VectorGraphicsCodec codec = VectorGraphicsCodec(); + final TestListener listener = TestListener(); + codec.decode(bytes.buffer.asByteData(), listener); + expect(listener.commands, [ + const OnSize(1000, 300), + OnPaintObject( + color: 4278190335, + strokeCap: null, + strokeJoin: null, + blendMode: BlendMode.srcOver.index, + strokeMiterLimit: null, + strokeWidth: null, + paintStyle: 0, + id: 0, + shaderId: null, + ), + OnPaintObject( + color: 4278222848, + strokeCap: null, + strokeJoin: null, + blendMode: BlendMode.srcOver.index, + strokeMiterLimit: null, + strokeWidth: null, + paintStyle: 0, + id: 1, + shaderId: null, + ), + OnPaintObject( + color: 4294901760, + strokeCap: 0, + strokeJoin: 0, + blendMode: BlendMode.srcOver.index, + strokeMiterLimit: 4.0, + strokeWidth: 1.0, + paintStyle: 1, + id: 2, + shaderId: null, + ), + OnPaintObject( + color: 4278222848, + strokeCap: null, + strokeJoin: null, + blendMode: BlendMode.srcOver.index, + strokeMiterLimit: null, + strokeWidth: null, + paintStyle: 0, + id: 3, + shaderId: null, + ), + const OnTextConfig( + 'Plain text Roboto', 0, 55, 'Roboto', 3, 0, 0, 4278190080, 0), + const OnTextConfig( + 'Plain text Verdana', 0, 55, 'Verdana', 3, 0, 0, 4278190080, 1), + const OnTextConfig( + 'Bold text Verdana', 0, 55, 'Verdana', 6, 0, 0, 4278190080, 2), + const OnTextConfig( + 'Stroked bold line', 0, 55, 'Roboto', 8, 0, 0, 4278190080, 3), + const OnTextConfig(' Line 3', 0, 55, 'Roboto', 3, 0, 0, 4278190080, 4), + const OnDrawText(0, 0, null, null), + const OnDrawText(1, 0, null, null), + const OnDrawText(2, 0, null, null), + const OnDrawText(3, 1, 2, null), + const OnDrawText(4, 3, null, null), + ]); + }); + + test('Encodes image elids trivial translation transform', () async { + const String svg = ''' + + + + + +'''; + + final Uint8List bytes = encodeSvg( + xml: svg, + debugName: 'test', + enableClippingOptimizer: false, + enableMaskingOptimizer: false, + enableOverdrawOptimizer: false, + ); + const VectorGraphicsCodec codec = VectorGraphicsCodec(); + final TestListener listener = TestListener(); + final ByteData data = bytes.buffer.asByteData(); + final DecodeResponse response = codec.decode(data, listener); + codec.decode(data, listener, response: response); + + expect(listener.commands, [ + const OnSize(1000, 300), + OnImage(0, 0, base64.decode(kBase64ImageContents)), + const OnDrawImage(0, 3, 3, 50, 50, null), + ]); + }); + + test('Encodes image elids trivial scale transform', () async { + const String svg = ''' + + + + + +'''; + + final Uint8List bytes = encodeSvg( + xml: svg, + debugName: 'test', + enableClippingOptimizer: false, + enableMaskingOptimizer: false, + enableOverdrawOptimizer: false, + ); + const VectorGraphicsCodec codec = VectorGraphicsCodec(); + final TestListener listener = TestListener(); + final ByteData data = bytes.buffer.asByteData(); + final DecodeResponse response = codec.decode(data, listener); + codec.decode(data, listener, response: response); + + expect(listener.commands, [ + const OnSize(1000, 300), + OnImage(0, 0, base64.decode(kBase64ImageContents)), + const OnDrawImage(0, 0, 0, 100, 100, null), + ]); + }); + + test('Encodes image does not elide non-trivial transform', () async { + const String svg = ''' + + + + + +'''; + + final Uint8List bytes = encodeSvg( + xml: svg, + debugName: 'test', + enableClippingOptimizer: false, + enableMaskingOptimizer: false, + enableOverdrawOptimizer: false, + ); + const VectorGraphicsCodec codec = VectorGraphicsCodec(); + final TestListener listener = TestListener(); + final ByteData data = bytes.buffer.asByteData(); + final DecodeResponse response = codec.decode(data, listener); + codec.decode(data, listener, response: response); + + expect(listener.commands, [ + const OnSize(1000, 300), + OnImage(0, 0, base64.decode(kBase64ImageContents)), + const OnDrawImage(0, 0, 0, 50, 50, [ + 3.0, + 1.0, + 0.0, + 0.0, + -1.0, + 3.0, + 0.0, + 0.0, + 0.0, + 0.0, + 3.0, + 0.0, + 30.0, + 40.0, + 0.0, + 1.0, + ]), + ]); + }); +} + +class TestListener extends VectorGraphicsCodecListener { + final List commands = []; + + @override + void onTextPosition(int textPositionId, double? x, double? y, double? dx, + double? dy, bool reset, Float64List? transform) {} + + @override + void onUpdateTextPosition(int textPositionId) {} + + @override + void onDrawPath(int pathId, int? paintId, int? patternId) { + commands.add(OnDrawPath(pathId, paintId, patternId)); + } + + @override + void onDrawVertices(Float32List vertices, Uint16List? indices, int? paintId) { + commands.add(OnDrawVertices(vertices, indices, paintId)); + } + + @override + void onPaintObject({ + required int color, + required int? strokeCap, + required int? strokeJoin, + required int blendMode, + required double? strokeMiterLimit, + required double? strokeWidth, + required int paintStyle, + required int id, + required int? shaderId, + }) { + commands.add( + OnPaintObject( + color: color, + strokeCap: strokeCap, + strokeJoin: strokeJoin, + blendMode: blendMode, + strokeMiterLimit: strokeMiterLimit, + strokeWidth: strokeWidth, + paintStyle: paintStyle, + id: id, + shaderId: shaderId, + ), + ); + } + + @override + void onPathClose() { + commands.add(const OnPathClose()); + } + + @override + void onPathCubicTo( + double x1, double y1, double x2, double y2, double x3, double y3) { + commands.add(OnPathCubicTo(x1, y1, x2, y2, x3, y3)); + } + + @override + void onPathFinished() { + commands.add(const OnPathFinished()); + } + + @override + void onPathLineTo(double x, double y) { + commands.add(OnPathLineTo(x, y)); + } + + @override + void onPathMoveTo(double x, double y) { + commands.add(OnPathMoveTo(x, y)); + } + + @override + void onPathStart(int id, int fillType) { + commands.add(OnPathStart(id, fillType)); + } + + @override + void onRestoreLayer() { + commands.add(const OnRestoreLayer()); + } + + @override + void onMask() { + commands.add(const OnMask()); + } + + @override + void onSaveLayer(int id) { + commands.add(OnSaveLayer(id)); + } + + @override + void onClipPath(int pathId) { + commands.add(OnClipPath(pathId)); + } + + @override + void onRadialGradient( + double centerX, + double centerY, + double radius, + double? focalX, + double? focalY, + Int32List colors, + Float32List? offsets, + Float64List? transform, + int tileMode, + int id, + ) { + commands.add( + OnRadialGradient( + centerX: centerX, + centerY: centerY, + radius: radius, + focalX: focalX, + focalY: focalY, + colors: colors, + offsets: offsets, + transform: transform, + tileMode: tileMode, + id: id, + ), + ); + } + + @override + void onLinearGradient( + double fromX, + double fromY, + double toX, + double toY, + Int32List colors, + Float32List? offsets, + int tileMode, + int id, + ) { + commands.add(OnLinearGradient( + fromX: fromX, + fromY: fromY, + toX: toX, + toY: toY, + colors: colors, + offsets: offsets, + tileMode: tileMode, + id: id, + )); + } + + @override + void onSize(double width, double height) { + commands.add(OnSize(width, height)); + } + + @override + void onTextConfig( + String text, + String? fontFamily, + double xAnchorMultiplier, + int fontWeight, + double fontSize, + int decoration, + int decorationStyle, + int decorationColor, + int id, + ) { + commands.add(OnTextConfig( + text, + xAnchorMultiplier, + fontSize, + fontFamily, + fontWeight, + decoration, + decorationStyle, + decorationColor, + id, + )); + } + + @override + void onDrawText(int textId, int? fillId, int? strokeId, int? patternId) { + commands.add(OnDrawText(textId, fillId, strokeId, patternId)); + } + + @override + void onDrawImage( + int imageId, + double x, + double y, + double width, + double height, + Float64List? transform, + ) { + commands.add(OnDrawImage(imageId, x, y, width, height, transform)); + } + + @override + void onImage( + int imageId, + int format, + Uint8List data, { + VectorGraphicsErrorListener? onError, + }) { + commands.add(OnImage( + imageId, + format, + data, + onError: onError, + )); + } + + @override + void onPatternStart(int patternId, double x, double y, double width, + double height, Float64List transform) { + commands.add(OnPatternStart(patternId, x, y, width, height, transform)); + } +} + +@immutable +class OnMask { + const OnMask(); +} + +@immutable +class OnLinearGradient { + const OnLinearGradient({ + required this.fromX, + required this.fromY, + required this.toX, + required this.toY, + required this.colors, + required this.offsets, + required this.tileMode, + required this.id, + }); + + final double fromX; + final double fromY; + final double toX; + final double toY; + final Int32List colors; + final Float32List? offsets; + final int tileMode; + final int id; + + @override + int get hashCode => Object.hash( + fromX, + fromY, + toX, + toY, + Object.hashAll(colors), + Object.hashAll(offsets ?? []), + tileMode, + id, + ); + + @override + bool operator ==(Object other) { + return other is OnLinearGradient && + other.fromX == fromX && + other.fromY == fromY && + other.toX == toX && + other.toY == toY && + _listEquals(other.colors, colors) && + _listEquals(other.offsets, offsets) && + other.tileMode == tileMode && + other.id == id; + } + + @override + String toString() { + return 'OnLinearGradient(' + 'fromX: $fromX, ' + 'toX: $toX, ' + 'fromY: $fromY, ' + 'toY: $toY, ' + 'colors: Int32List.fromList($colors), ' + 'offsets: Float32List.fromList($offsets), ' + 'tileMode: $tileMode, ' + 'id: $id)'; + } +} + +@immutable +class OnRadialGradient { + const OnRadialGradient({ + required this.centerX, + required this.centerY, + required this.radius, + required this.focalX, + required this.focalY, + required this.colors, + required this.offsets, + required this.transform, + required this.tileMode, + required this.id, + }); + + final double centerX; + final double centerY; + final double radius; + final double? focalX; + final double? focalY; + final Int32List colors; + final Float32List? offsets; + final Float64List? transform; + final int tileMode; + final int id; + + @override + int get hashCode => Object.hash( + centerX, + centerY, + radius, + focalX, + focalY, + Object.hashAll(colors), + Object.hashAll(offsets ?? []), + Object.hashAll(transform ?? []), + tileMode, + id, + ); + + @override + bool operator ==(Object other) { + return other is OnRadialGradient && + other.centerX == centerX && + other.centerY == centerY && + other.radius == radius && + other.focalX == focalX && + other.focalX == focalY && + _listEquals(other.colors, colors) && + _listEquals(other.offsets, offsets) && + _listEquals(other.transform, transform) && + other.tileMode == tileMode && + other.id == id; + } +} + +@immutable +class OnSaveLayer { + const OnSaveLayer(this.id); + + final int id; + + @override + int get hashCode => id.hashCode; + + @override + bool operator ==(Object other) => other is OnSaveLayer && other.id == id; +} + +@immutable +class OnClipPath { + const OnClipPath(this.id); + + final int id; + + @override + int get hashCode => id.hashCode; + + @override + bool operator ==(Object other) => other is OnClipPath && other.id == id; +} + +@immutable +class OnRestoreLayer { + const OnRestoreLayer(); +} + +@immutable +class OnDrawPath { + const OnDrawPath(this.pathId, this.paintId, this.patternId); + + final int pathId; + final int? paintId; + final int? patternId; + + @override + int get hashCode => Object.hash(pathId, paintId, patternId); + + @override + bool operator ==(Object other) => + other is OnDrawPath && + other.pathId == pathId && + other.paintId == paintId && + other.patternId == patternId; + + @override + String toString() => 'OnDrawPath($pathId, $paintId, $patternId)'; +} + +@immutable +class OnDrawVertices { + const OnDrawVertices(this.vertices, this.indices, this.paintId); + + final List vertices; + final List? indices; + final int? paintId; + + @override + int get hashCode => Object.hash( + Object.hashAll(vertices), Object.hashAll(indices ?? []), paintId); + + @override + bool operator ==(Object other) => + other is OnDrawVertices && + _listEquals(vertices, other.vertices) && + _listEquals(indices, other.indices) && + other.paintId == paintId; + + @override + String toString() => 'OnDrawVertices($vertices, $indices, $paintId)'; +} + +@immutable +class OnPaintObject { + const OnPaintObject({ + required this.color, + required this.strokeCap, + required this.strokeJoin, + required this.blendMode, + required this.strokeMiterLimit, + required this.strokeWidth, + required this.paintStyle, + required this.id, + required this.shaderId, + }); + + final int color; + final int? strokeCap; + final int? strokeJoin; + final int blendMode; + final double? strokeMiterLimit; + final double? strokeWidth; + final int paintStyle; + final int id; + final int? shaderId; + + @override + int get hashCode => Object.hash(color, strokeCap, strokeJoin, blendMode, + strokeMiterLimit, strokeWidth, paintStyle, id, shaderId); + + @override + bool operator ==(Object other) => + other is OnPaintObject && + other.color == color && + other.strokeCap == strokeCap && + other.strokeJoin == strokeJoin && + other.blendMode == blendMode && + other.strokeMiterLimit == strokeMiterLimit && + other.strokeWidth == strokeWidth && + other.paintStyle == paintStyle && + other.id == id && + other.shaderId == shaderId; + + @override + String toString() => + 'OnPaintObject(color: $color, strokeCap: $strokeCap, strokeJoin: $strokeJoin, ' + 'blendMode: $blendMode, strokeMiterLimit: $strokeMiterLimit, strokeWidth: $strokeWidth, ' + 'paintStyle: $paintStyle, id: $id, shaderId: $shaderId)'; +} + +@immutable +class OnPathClose { + const OnPathClose(); + + @override + int get hashCode => 44221; + + @override + bool operator ==(Object other) => other is OnPathClose; + + @override + String toString() => 'OnPathClose'; +} + +@immutable +class OnPathCubicTo { + const OnPathCubicTo(this.x1, this.y1, this.x2, this.y2, this.x3, this.y3); + + final double x1; + final double x2; + final double x3; + final double y1; + final double y2; + final double y3; + + @override + int get hashCode => Object.hash(x1, y1, x2, y2, x3, y3); + + @override + bool operator ==(Object other) => + other is OnPathCubicTo && + other.x1 == x1 && + other.y1 == y1 && + other.x2 == x2 && + other.y2 == y2 && + other.x3 == x3 && + other.y3 == y3; + + @override + String toString() => 'OnPathCubicTo($x1, $y1, $x2, $y2, $x3, $y3)'; +} + +@immutable +class OnPathFinished { + const OnPathFinished(); + + @override + int get hashCode => 1223; + + @override + bool operator ==(Object other) => other is OnPathFinished; + + @override + String toString() => 'OnPathFinished'; +} + +@immutable +class OnPathLineTo { + const OnPathLineTo(this.x, this.y); + + final double x; + final double y; + + @override + int get hashCode => Object.hash(x, y); + + @override + bool operator ==(Object other) => + other is OnPathLineTo && other.x == x && other.y == y; + + @override + String toString() => 'OnPathLineTo($x, $y)'; +} + +@immutable +class OnPathMoveTo { + const OnPathMoveTo(this.x, this.y); + + final double x; + final double y; + + @override + int get hashCode => Object.hash(x, y); + + @override + bool operator ==(Object other) => + other is OnPathMoveTo && other.x == x && other.y == y; + + @override + String toString() => 'OnPathMoveTo($x, $y)'; +} + +@immutable +class OnPathStart { + const OnPathStart(this.id, this.fillType); + + final int id; + final int fillType; + + @override + int get hashCode => Object.hash(id, fillType); + + @override + bool operator ==(Object other) => + other is OnPathStart && other.id == id && other.fillType == fillType; + + @override + String toString() => 'OnPathStart($id, $fillType)'; +} + +@immutable +class OnSize { + const OnSize(this.width, this.height); + + final double width; + final double height; + + @override + int get hashCode => Object.hash(width, height); + + @override + bool operator ==(Object other) => + other is OnSize && other.width == width && other.height == height; + + @override + String toString() => 'OnSize($width, $height)'; +} + +@immutable +class OnTextConfig { + const OnTextConfig( + this.text, + this.xAnchorMultiplier, + this.fontSize, + this.fontFamily, + this.fontWeight, + this.decoration, + this.decorationStyle, + this.decorationColor, + this.id, + ); + + final String text; + final double xAnchorMultiplier; + final double fontSize; + final String? fontFamily; + final int fontWeight; + final int id; + final int decoration; + final int decorationStyle; + final int decorationColor; + + @override + int get hashCode => Object.hash( + text, + xAnchorMultiplier, + fontSize, + fontFamily, + fontWeight, + decoration, + decorationStyle, + decorationColor, + id, + ); + + @override + bool operator ==(Object other) => + other is OnTextConfig && + other.text == text && + other.xAnchorMultiplier == xAnchorMultiplier && + other.fontSize == fontSize && + other.fontFamily == fontFamily && + other.fontWeight == fontWeight && + other.decoration == decoration && + other.decorationStyle == decorationStyle && + other.decorationColor == decorationColor && + other.id == id; + + @override + String toString() => + 'OnTextConfig($text, (anchor: $xAnchorMultiplier), $fontSize, $fontFamily, $fontWeight, $decoration, $decorationStyle, $decorationColor, $id)'; +} + +@immutable +class OnDrawText { + const OnDrawText(this.textId, this.fillId, this.strokeId, this.patternId); + + final int textId; + final int? fillId; + final int? strokeId; + final int? patternId; + + @override + int get hashCode => Object.hash(textId, fillId, strokeId, patternId); + + @override + bool operator ==(Object other) => + other is OnDrawText && + other.textId == textId && + other.fillId == fillId && + other.strokeId == strokeId && + other.patternId == patternId; + + @override + String toString() => 'OnDrawText($textId, $fillId, $strokeId, $patternId)'; +} + +@immutable +class OnImage { + const OnImage(this.id, this.format, this.data, {this.onError}); + + final int id; + final int format; + final List data; + final VectorGraphicsErrorListener? onError; + + @override + int get hashCode => Object.hash(id, format, data, onError); + + @override + bool operator ==(Object other) => + other is OnImage && + other.id == id && + other.format == format && + other.onError == onError && + _listEquals(other.data, data); + + @override + String toString() => 'OnImage($id, $format, data:${data.length} bytes)'; +} + +@immutable +class OnDrawImage { + const OnDrawImage( + this.id, + this.x, + this.y, + this.width, + this.height, + this.transform, + ); + + final int id; + final double x; + final double y; + final double width; + final double height; + final List? transform; + + @override + int get hashCode => Object.hash(id, x, y, width, height); + + @override + bool operator ==(Object other) { + return other is OnDrawImage && + other.id == id && + other.x == x && + other.y == y && + other.width == width && + other.height == height && + _listEquals(other.transform, transform); + } + + @override + String toString() => 'OnDrawImage($id, $x, $y, $width, $height, $transform)'; +} + +@immutable +class OnPatternStart { + const OnPatternStart( + this.patternId, this.x, this.y, this.width, this.height, this.transform); + + final int patternId; + final double x; + final double y; + final double width; + final double height; + final Float64List transform; + + @override + int get hashCode => + Object.hash(patternId, x, y, width, height, Object.hashAll(transform)); + + @override + bool operator ==(Object other) => + other is OnPatternStart && + other.patternId == patternId && + other.x == x && + other.y == y && + other.width == width && + other.height == height && + _listEquals(other.transform, transform); + + @override + String toString() => + 'OnPatternStart($patternId, $x, $y, $width, $height, $transform)'; +} + +bool _listEquals(List? left, List? right) { + if (left == null && right == null) { + return true; + } + if (left == null || right == null) { + return false; + } + if (left.length != right.length) { + return false; + } + for (int i = 0; i < left.length; i++) { + if (left[i] != right[i]) { + return false; + } + } + return true; +} diff --git a/packages/vector_graphics_compiler/test/helpers.dart b/packages/vector_graphics_compiler/test/helpers.dart new file mode 100644 index 000000000000..c25e6b0832d6 --- /dev/null +++ b/packages/vector_graphics_compiler/test/helpers.dart @@ -0,0 +1,18 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:vector_graphics_compiler/src/svg/node.dart'; + +List queryChildren(Node node) { + final List children = []; + void visitor(Node child) { + if (child is T) { + children.add(child); + } + child.visitChildren(visitor); + } + + node.visitChildren(visitor); + return children; +} diff --git a/packages/vector_graphics_compiler/test/masking_optimizer_test.dart b/packages/vector_graphics_compiler/test/masking_optimizer_test.dart new file mode 100644 index 000000000000..fe9e4c4dd600 --- /dev/null +++ b/packages/vector_graphics_compiler/test/masking_optimizer_test.dart @@ -0,0 +1,299 @@ +// 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:core'; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:vector_graphics_compiler/src/svg/masking_optimizer.dart'; +import 'package:vector_graphics_compiler/src/svg/node.dart'; +import 'package:vector_graphics_compiler/src/svg/parser.dart'; +import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; + +import 'helpers.dart'; +import 'test_svg_strings.dart'; + +Node parseAndResolve(String source) { + final Node node = parseToNodeTree(source); + final ResolvingVisitor visitor = ResolvingVisitor(); + return node.accept(visitor, AffineMatrix.identity); +} + +const String xmlString = + ''''''; + +void main() { + setUpAll(() { + if (!initializePathOpsFromFlutterCache()) { + fail('error in setup'); + } + }); + + test('Only remove MaskNode if the mask is described by a singular PathNode', + () { + final Node node = parseAndResolve(''' + + + + + + + +'''); + + final MaskingOptimizer visitor = MaskingOptimizer(); + final Node newNode = visitor.apply(node); + + final List maskNodesNew = + queryChildren(newNode); + + expect(maskNodesNew.length, 0); + }); + + test("Don't remove MaskNode if the mask is described by multiple PathNodes", + () { + final Node node = parseAndResolve(''' + + + + + + + + +'''); + final MaskingOptimizer visitor = MaskingOptimizer(); + final Node newNode = visitor.apply(node); + + final List maskNodesNew = + queryChildren(newNode); + + expect(maskNodesNew.length, 1); + }); + + test( + "Don't resolve a MaskNode if one of PathNodes it's applied to has stroke.width set", + () { + final Node node = parseAndResolve(''' + + + + + + + + +'''); + + final MaskingOptimizer visitor = MaskingOptimizer(); + final Node newNode = visitor.apply(node); + + final List maskNodesNew = + queryChildren(newNode); + + expect(maskNodesNew.length, 1); + }); + + test("Don't remove MaskNode if intersection of Mask and Path is empty", () { + final Node node = parseAndResolve(''' + + + + + + +'''); + final MaskingOptimizer visitor = MaskingOptimizer(); + final Node newNode = visitor.apply(node); + + final List maskNodesNew = + queryChildren(newNode); + expect(maskNodesNew.length, 1); + }); + test('ParentNode and PathNode count should stay the same', () { + final Node node = parseAndResolve(xmlString); + + final List pathNodesOld = + queryChildren(node); + final List parentNodesOld = queryChildren(node); + + final MaskingOptimizer visitor = MaskingOptimizer(); + final Node newNode = visitor.apply(node); + + final List pathNodesNew = + queryChildren(newNode); + final List parentNodesNew = queryChildren(newNode); + + expect(pathNodesOld.length, pathNodesNew.length); + expect(parentNodesOld.length, parentNodesNew.length); + }); + + test('Masks on groups', () { + final VectorInstructions instructions = + parse(groupMask, enableMaskingOptimizer: false); + expect(instructions.paths, [ + parseSvgPathData( + 'M 17.438 8.438 C 17.748 8.438 18 8.69 18 9 L 18 16.313 C 17.99834725871 17.24440923535 17.24341005121 17.99889920517 16.312 18 L 1.688 18 C 0.75620021668 17.99889792932 0.00110207068 17.24379978332 0 16.312 L 0 9 C 0.01271270943 8.69855860173 0.26079065383 8.46072235233 0.5625 8.46072235233 C 0.86420934617 8.46072235233 1.11228729057 8.69855860173 1.125 9 L 1.125 16.313 C 1.125 16.622 1.377 16.875 1.688 16.875 L 16.312 16.875 C 16.622 16.875 16.875 16.622 16.875 16.312 L 16.875 9 C 16.875 8.69 17.127 8.437 17.438 8.437 Z M 9 0 C 9.169 0 9.316 0.079 9.418 0.196 L 9.423 0.192 L 13.361 4.692 C 13.443 4.795 13.5 4.921 13.5 5.062 C 13.5 5.373 13.248 5.625 12.937 5.625 C 12.77572417052 5.6238681172 12.62300981305 5.55226042805 12.519 5.429 L 12.514 5.433 L 9.563 2.06 L 9.563 11.812 C 9.56299999183 12.12293630838 9.31093630838 12.3749999852 9 12.3749999852 C 8.68906369162 12.3749999852 8.43700000817 12.12293630838 8.437 11.812 L 8.437 2.06 L 5.486 5.433 C 5.37775998399 5.5529360201 5.22453705399 5.62248401669 5.063 5.625 C 4.75206368585 5.625 4.5 5.37293631415 4.5 5.062 C 4.5 4.921 4.557 4.795 4.644 4.696 L 4.639 4.692 L 8.577 0.192 C 8.68524001601 0.0720639799 8.83846294601 0.00251598331 9 0 Z', + PathFillType.evenOdd) + .transformed(const AffineMatrix(0.00000000000000006123233995736766, 1, + -1, 0.00000000000000006123233995736766, 21, 3)), + parseSvgPathData( + 'M -3 -3 L 21 -3 L 21 21 L -3 21 Z', PathFillType.evenOdd) + .transformed(const AffineMatrix(1, 0, 0, 1, 3, 3)), + parseSvgPathData( + 'M 17.438 8.438 C 17.748 8.438 18 8.69 18 9 L 18 16.313 C 17.99834725871 17.24440923535 17.24341005121 17.99889920517 16.312 18 L 1.688 18 C 0.75620021668 17.99889792932 0.00110207068 17.24379978332 0 16.312 L 0 9 C 0.01271270943 8.69855860173 0.26079065383 8.46072235233 0.5625 8.46072235233 C 0.86420934617 8.46072235233 1.11228729057 8.69855860173 1.125 9 L 1.125 16.313 C 1.125 16.622 1.377 16.875 1.688 16.875 L 16.312 16.875 C 16.622 16.875 16.875 16.622 16.875 16.312 L 16.875 9 C 16.875 8.69 17.127 8.437 17.438 8.437 Z M 9 0 C 9.169 0 9.316 0.079 9.418 0.196 L 9.423 0.192 L 13.361 4.692 C 13.443 4.795 13.5 4.921 13.5 5.062 C 13.5 5.373 13.248 5.625 12.937 5.625 C 12.77572417052 5.6238681172 12.62300981305 5.55226042805 12.519 5.429 L 12.514 5.433 L 9.563 2.06 L 9.563 11.812 C 9.56299999183 12.12293630838 9.31093630838 12.3749999852 9 12.3749999852 C 8.68906369162 12.3749999852 8.43700000817 12.12293630838 8.437 11.812 L 8.437 2.06 L 5.486 5.433 C 5.37775998399 5.5529360201 5.22453705399 5.62248401669 5.063 5.625 C 4.75206368585 5.625 4.5 5.37293631415 4.5 5.062 C 4.5 4.921 4.557 4.795 4.644 4.696 L 4.639 4.692 L 8.577 0.192 C 8.68524001601 0.0720639799 8.83846294601 0.00251598331 9 0 Z', + PathFillType.evenOdd) + .transformed(const AffineMatrix(1, 0, 0, 1, 3, 3)), + ]); + + final VectorInstructions instructionsWithOptimizer = parse(groupMask); + expect(instructionsWithOptimizer.paths, groupMaskForMaskingOptimizer); + + expect(instructions.paints, const [ + Paint(fill: Fill(color: Color(0xff727272))), + Paint(fill: Fill()), + Paint(fill: Fill(color: Color(0xff8e93a1))), + Paint(fill: Fill(color: Color(0xffffffff))) + ]); + + expect(instructions.commands, const [ + DrawCommand(DrawCommandType.path, objectId: 0, paintId: 0), + DrawCommand(DrawCommandType.saveLayer, paintId: 1), + DrawCommand(DrawCommandType.path, objectId: 1, paintId: 2), + DrawCommand(DrawCommandType.mask), + DrawCommand(DrawCommandType.path, objectId: 2, paintId: 3), + DrawCommand(DrawCommandType.restore), + DrawCommand(DrawCommandType.restore) + ]); + }); + + test('Handles masks with blends and gradients correctly', () { + final VectorInstructions instructions = parse( + blendAndMask, + enableClippingOptimizer: false, + enableMaskingOptimizer: false, + enableOverdrawOptimizer: false, + ); + expect( + instructions.paths, + [ + PathBuilder().addOval(const Rect.fromCircle(50, 50, 50)).toPath(), + PathBuilder().addOval(const Rect.fromCircle(50, 50, 40)).toPath(), + ], + ); + + final VectorInstructions instructionsWithOptimizer = parse(blendAndMask); + expect(instructionsWithOptimizer.paths, blendsAndMasksForMaskingOptimizer); + + const LinearGradient gradient1 = LinearGradient( + id: 'url(#linearGradient-3)', + from: Point(46.9782516, 60.9121966), + to: Point(60.42279469999999, 90.6839734), + colors: [Color(0xffffffff), Color(0xff0000ff)], + offsets: [0.0, 1.0], + tileMode: TileMode.clamp, + unitMode: GradientUnitMode.transformed, + ); + const LinearGradient gradient2 = LinearGradient( + id: 'url(#linearGradient-3)', + from: Point(47.58260128, 58.72975728), + to: Point(58.338235759999996, 82.54717871999999), + colors: [Color(0xffffffff), Color(0xff0000ff)], + offsets: [0.0, 1.0], + tileMode: TileMode.clamp, + unitMode: GradientUnitMode.transformed, + ); + expect(instructions.paints, const [ + Paint(fill: Fill(color: Color(0xffadd8e6))), + Paint( + blendMode: BlendMode.multiply, + fill: Fill(), + ), + Paint( + blendMode: BlendMode.multiply, + fill: Fill(color: Color(0x98ffffff), shader: gradient1), + ), + Paint(fill: Fill(color: Color(0x98ffffff), shader: gradient2)), + ]); + + expect(instructions.commands, const [ + DrawCommand(DrawCommandType.path, objectId: 0, paintId: 0), + DrawCommand(DrawCommandType.saveLayer, paintId: 1), + DrawCommand(DrawCommandType.path, objectId: 0, paintId: 2), + DrawCommand(DrawCommandType.mask), + DrawCommand(DrawCommandType.path, objectId: 1, paintId: 3), + DrawCommand(DrawCommandType.restore), + DrawCommand(DrawCommandType.restore) + ]); + }); + + test('Does not partially apply mask to some children but not others', () { + final VectorInstructions instructions = parse(''' + + + + + + + + + +'''); + + expect(instructions.commands, const [ + DrawCommand(DrawCommandType.saveLayer, paintId: 0), + DrawCommand(DrawCommandType.path, objectId: 0, paintId: 1), + DrawCommand(DrawCommandType.path, objectId: 1, paintId: 2), + DrawCommand(DrawCommandType.mask), + DrawCommand(DrawCommandType.path, objectId: 2, paintId: 3), + DrawCommand(DrawCommandType.restore), + DrawCommand(DrawCommandType.restore), + ]); + + expect(instructions.paths, [ + Path( + commands: const [ + MoveToCommand(44.1855, 464.814), + LineToCommand(244.564, 464.814), + LineToCommand(244.564, 64.0564), + LineToCommand(44.1855, 64.0564), + LineToCommand(44.1855, 464.814), + CloseCommand(), + MoveToCommand(45.8428, 462.333), + LineToCommand(242.081, 462.333), + LineToCommand(242.081, 65.7158), + LineToCommand(45.8428, 65.7158), + LineToCommand(45.8428, 462.333), + CloseCommand() + ], + fillType: PathFillType.evenOdd, + ), + Path( + commands: const [ + MoveToCommand(103.803, 481.375), + LineToCommand(184.948, 481.375) + ], + ), + Path( + commands: const [ + MoveToCommand(21.5625, 0.0), + LineToCommand(267.1875, 0.0), + CubicToCommand(279.0881677156519, 0.0, 288.75, 9.661832284348126, + 288.75, 21.5625), + LineToCommand(288.75, 506.4375), + CubicToCommand(288.75, 518.3381677156518, 279.0881677156519, 528.0, + 267.1875, 528.0), + LineToCommand(21.5625, 528.0), + CubicToCommand( + 9.661832284348126, 528.0, 0.0, 518.3381677156518, 0.0, 506.4375), + LineToCommand(0.0, 21.5625), + CubicToCommand( + 0.0, 9.661832284348126, 9.661832284348126, 0.0, 21.5625, 0.0), + CloseCommand() + ], + ), + ]); + }); +} diff --git a/packages/vector_graphics_compiler/test/matrix_test.dart b/packages/vector_graphics_compiler/test/matrix_test.dart new file mode 100644 index 000000000000..3f2a6a10aea0 --- /dev/null +++ b/packages/vector_graphics_compiler/test/matrix_test.dart @@ -0,0 +1,178 @@ +// 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:math' as math; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:vector_graphics_compiler/src/svg/parsers.dart'; +import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; +import 'package:vector_math/vector_math_64.dart'; + +void main() { + test('scaleStrokeWidth', () { + expect(AffineMatrix.identity.scaleStrokeWidth(null), null); + expect(AffineMatrix.identity.scaleStrokeWidth(1), 1); + expect(AffineMatrix.identity.scaleStrokeWidth(2), 2); + expect(AffineMatrix.identity.rotated(1.2).scaleStrokeWidth(1), 1); + expect(AffineMatrix.identity.rotated(1.2).scaleStrokeWidth(2), 2); + + expect(AffineMatrix.identity.scaled(2.0).scaleStrokeWidth(1), 2); + expect(AffineMatrix.identity.scaled(2.0).scaleStrokeWidth(2), 4); + expect( + AffineMatrix.identity.scaled(2.0).rotated(1.2).scaleStrokeWidth(1), 2); + expect( + AffineMatrix.identity.scaled(2.0).rotated(1.2).scaleStrokeWidth(2), 4); + + expect(AffineMatrix.identity.scaled(2.0, 1.0).scaleStrokeWidth(1), 1.5); + expect(AffineMatrix.identity.scaled(2.0, 1.0).scaleStrokeWidth(2), 3); + expect( + AffineMatrix.identity.scaled(2.0, 1.0).rotated(1.2).scaleStrokeWidth(1), + 1.5); + expect( + AffineMatrix.identity.scaled(2.0, 1.0).rotated(1.2).scaleStrokeWidth(2), + 3); + }); + + test('Parse rotate and scale', () { + // Regression test for https://github.com/dnfield/flutter_svg/issues/801 + final AffineMatrix mat = parseTransform('rotate(-1 4 -12) scale(2)')!; + expect( + mat, + AffineMatrix.identity + .translated(4, -12) + .rotated(radians(-1)) + .translated(-4, 12) + .scaled(2), + ); + }); + + test('Identity matrix', () { + expect(AffineMatrix.identity.toMatrix4(), Matrix4.identity().storage); + }); + + test('Multiply', () { + const AffineMatrix matrix1 = AffineMatrix(2, 2, 3, 4, 5, 6); + const AffineMatrix matrix2 = AffineMatrix(7, 8, 9, 10, 11, 12); + + final Matrix4 matrix4_1 = Matrix4.fromFloat64List(matrix1.toMatrix4()); + final Matrix4 matrix4_2 = Matrix4.fromFloat64List(matrix2.toMatrix4()); + expect( + matrix1.multiplied(matrix2).toMatrix4(), + matrix4_1.multiplied(matrix4_2).storage, + ); + }); + + test('Scale', () { + const AffineMatrix matrix1 = AffineMatrix(2, 2, 3, 4, 5, 6); + + final Matrix4 matrix4_1 = Matrix4.fromFloat64List(matrix1.toMatrix4()); + expect( + matrix1.scaled(2, 3).toMatrix4(), + matrix4_1.scaled(2.0, 3.0).storage, + ); + + expect( + matrix1.scaled(2).toMatrix4(), + matrix4_1.scaled(2.0, 2.0).storage, + ); + }); + + test('Scale and multiply', () { + const AffineMatrix matrix1 = AffineMatrix(2, 2, 3, 4, 5, 6); + const AffineMatrix matrix2 = AffineMatrix(7, 8, 9, 10, 11, 12); + + final Matrix4 matrix4_1 = Matrix4.fromFloat64List(matrix1.toMatrix4()); + final Matrix4 matrix4_2 = Matrix4.fromFloat64List(matrix2.toMatrix4()); + expect( + matrix1.scaled(2, 3).multiplied(matrix2).toMatrix4(), + matrix4_1.scaled(2.0, 3.0).multiplied(matrix4_2).storage, + ); + }); + + test('Multiply handles the extra matrix4 scale value', () { + final AffineMatrix matrix1 = AffineMatrix.identity.scaled(2, 3); + final AffineMatrix matrix2 = AffineMatrix.identity.multiplied(matrix1); + + expect(matrix1, matrix2); + }); + + test('Translate', () { + const AffineMatrix matrix1 = AffineMatrix(2, 2, 3, 4, 5, 6); + + final Matrix4 matrix4_1 = Matrix4.fromFloat64List(matrix1.toMatrix4()); + matrix4_1.translate(2.0, 3.0); + expect( + matrix1.translated(2, 3).toMatrix4(), + matrix4_1.storage, + ); + }); + + test('Rotate', () { + const AffineMatrix matrix1 = AffineMatrix(2, 2, 3, 4, 5, 6); + + final Matrix4 matrix4_1 = Matrix4.fromFloat64List(matrix1.toMatrix4()) + ..rotateZ(31.0); + expect( + matrix1.rotated(31).toMatrix4(), + matrix4_1.storage, + ); + }); + + test('transformRect', () { + const double epsillon = .0000001; + const Rect rectangle20x20 = Rect.fromLTRB(10, 20, 30, 40); + + // Identity + expect( + AffineMatrix.identity.transformRect(rectangle20x20), + rectangle20x20, + ); + + // 2D Scaling + expect( + AffineMatrix.identity.scaled(2).transformRect(rectangle20x20), + const Rect.fromLTRB(20, 40, 60, 80), + ); + + // Rotation + final Rect rotatedRect = AffineMatrix.identity + .rotated(math.pi / 2.0) + .transformRect(rectangle20x20); + expect(rotatedRect.left + 40, lessThan(epsillon)); + expect(rotatedRect.top - 10, lessThan(epsillon)); + expect(rotatedRect.right + 20, lessThan(epsillon)); + expect(rotatedRect.bottom - 30, lessThan(epsillon)); + + // Translation + final Rect shiftedRect = + AffineMatrix.identity.translated(10, 20).transformRect(rectangle20x20); + + expect(shiftedRect.left, rectangle20x20.left + 10); + expect(shiftedRect.top, rectangle20x20.top + 20); + expect(shiftedRect.right, rectangle20x20.right + 10); + expect(shiftedRect.bottom, rectangle20x20.bottom + 20); + }); + + test('== and hashCode account for hidden field', () { + const AffineMatrix matrixA = AffineMatrix.identity; + const AffineMatrix matrixB = AffineMatrix(1, 0, 0, 1, 0, 0, 0); + + expect(matrixA != matrixB, true); + expect(matrixA.hashCode != matrixB.hashCode, true); + }); + + test('encodableInRect', () { + final AffineMatrix matrixA = AffineMatrix.identity.scaled(2, 3); + final AffineMatrix matrixB = AffineMatrix.identity.scaled(2, -2); + final AffineMatrix matrixC = AffineMatrix.identity.xSkewed(5); + final AffineMatrix matrixD = AffineMatrix.identity.ySkewed(5); + final AffineMatrix matrixE = AffineMatrix.identity.rotated(1.3); + + expect(matrixA.encodableInRect, true); + expect(matrixB.encodableInRect, false); + expect(matrixC.encodableInRect, false); + expect(matrixD.encodableInRect, false); + expect(matrixE.encodableInRect, false); + }); +} diff --git a/packages/vector_graphics_compiler/test/node_test.dart b/packages/vector_graphics_compiler/test/node_test.dart new file mode 100644 index 000000000000..072f4c8583ad --- /dev/null +++ b/packages/vector_graphics_compiler/test/node_test.dart @@ -0,0 +1,49 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:vector_graphics_compiler/src/svg/node.dart'; +import 'package:vector_graphics_compiler/src/svg/parser.dart'; +import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; + +void main() { + test('TextPosition uses computed transform', () { + final TextPositionNode node = TextPositionNode( + SvgAttributes.forTest( + x: DoubleOrPercentage.fromString('5'), + y: DoubleOrPercentage.fromString('3'), + dx: DoubleOrPercentage.fromString('2'), + dy: DoubleOrPercentage.fromString('1'), + transform: AffineMatrix.identity.translated(10, 10), + ), + reset: false, + ); + + final TextPosition position = node.computeTextPosition( + const Rect.fromLTWH(0, 0, 500, 500), + AffineMatrix.identity, + ); + + expect(position.x, 15); + expect(position.y, 13); + expect(position.dx, 12); + expect(position.dy, 11); + }); + + test('TextNode returns null for Paint if stroke and fill are missing', () { + final TextNode node = TextNode( + 'text', + SvgAttributes.empty, + ); + expect(node.computePaint(Rect.largest, AffineMatrix.identity), null); + }); + + test('PathNode returns null for Paint if stroke and fill are missing', () { + final PathNode node = PathNode( + Path(), + SvgAttributes.empty, + ); + expect(node.computePaint(Rect.largest, AffineMatrix.identity), null); + }); +} diff --git a/packages/vector_graphics_compiler/test/overdraw_optimizer_test.dart b/packages/vector_graphics_compiler/test/overdraw_optimizer_test.dart new file mode 100644 index 000000000000..61f9062aa3cb --- /dev/null +++ b/packages/vector_graphics_compiler/test/overdraw_optimizer_test.dart @@ -0,0 +1,599 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:vector_graphics_compiler/src/svg/node.dart'; +import 'package:vector_graphics_compiler/src/svg/overdraw_optimizer.dart'; +import 'package:vector_graphics_compiler/src/svg/parser.dart'; +import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; +import 'helpers.dart'; +import 'test_svg_strings.dart'; + +Node parseAndResolve(String source) { + final Node node = parseToNodeTree(source); + final ResolvingVisitor visitor = ResolvingVisitor(); + return node.accept(visitor, AffineMatrix.identity); +} + +void main() { + setUpAll(() { + if (!initializePathOpsFromFlutterCache()) { + fail('error in setup'); + } + }); + + test( + 'Basic case of two opaque shapes overlapping with a stroke (cannot be optimized yet)', + () { + final Node node = parseAndResolve(basicOverlapWithStroke); + final VectorInstructions instructions = parse(basicOverlapWithStroke); + + final List pathNodesOld = + queryChildren(node); + + final OverdrawOptimizer visitor = OverdrawOptimizer(); + final Node newNode = visitor.apply(node); + + final List pathNodesNew = + queryChildren(newNode); + + expect(pathNodesOld.length, pathNodesNew.length); + + expect(instructions.paints, const [ + Paint( + blendMode: BlendMode.srcOver, + stroke: Stroke(color: Color(0xff008000)), + fill: Fill(color: Color(0xffff0000))), + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0xff0000ff))) + ]); + + expect(instructions.paths, [ + Path( + commands: const [ + MoveToCommand(99.0, 221.5), + LineToCommand(692.0, 221.5), + LineToCommand(692.0, 316.5), + LineToCommand(99.0, 316.5), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(367.0, 41.50001), + LineToCommand(448.0, 41.50001), + LineToCommand(448.0, 527.49999), + LineToCommand(367.0, 527.49999), + CloseCommand() + ], + ) + ]); + }); + + test('Basic case of two opaque shapes overlapping', () { + final Node node = parseAndResolve(basicOverlap); + final VectorInstructions instructions = parse(basicOverlap); + + final List pathNodesOld = + queryChildren(node); + + final OverdrawOptimizer visitor = OverdrawOptimizer(); + final Node newNode = visitor.apply(node); + + final List pathNodesNew = + queryChildren(newNode); + + expect(pathNodesOld.length, pathNodesNew.length); + + expect(instructions.paints, const [ + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0xffff0000))), + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0xff0000ff))) + ]); + + expect(instructions.paths, [ + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(367.0, 221.5), + LineToCommand(99.0, 221.5), + LineToCommand(99.0, 316.5), + LineToCommand(367.0, 316.5), + LineToCommand(367.0, 221.5), + CloseCommand(), + MoveToCommand(448.0, 221.5), + LineToCommand(448.0, 316.5), + LineToCommand(692.0, 316.5), + LineToCommand(692.0, 221.5), + LineToCommand(448.0, 221.5), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(367.0, 41.50001), + LineToCommand(448.0, 41.50001), + LineToCommand(448.0, 527.49999), + LineToCommand(367.0, 527.49999), + CloseCommand() + ], + ) + ]); + }); + + test('Basic case of two shapes with opacity < 1.0 overlapping', () { + final Node node = parseAndResolve(opacityOverlap); + final VectorInstructions instructions = parse(opacityOverlap); + + final OverdrawOptimizer visitor = OverdrawOptimizer(); + final Node newNode = visitor.apply(node); + + final List pathNodesNew = + queryChildren(newNode); + + expect(pathNodesNew.length, 3); + + expect(instructions.paints, const [ + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0x7fff0000))), + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0x4c0000ff))), + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0xa58a0075))) + ]); + + expect(instructions.paths, [ + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(343.0, 240.5), + LineToCommand(88.0, 240.5), + LineToCommand(88.0, 366.5), + LineToCommand(343.0, 366.5), + LineToCommand(343.0, 240.5), + CloseCommand(), + MoveToCommand(484.0, 240.5), + LineToCommand(484.0, 366.5), + LineToCommand(711.0, 366.5), + LineToCommand(711.0, 240.5), + LineToCommand(484.0, 240.5), + CloseCommand() + ], + ), + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(484.0, 63.5), + LineToCommand(343.0, 63.5), + LineToCommand(343.0, 240.5), + LineToCommand(484.0, 240.5), + LineToCommand(484.0, 63.5), + CloseCommand(), + MoveToCommand(484.0, 366.5), + LineToCommand(343.0, 366.5), + LineToCommand(343.0, 565.5), + LineToCommand(484.0, 565.5), + LineToCommand(484.0, 366.5), + CloseCommand() + ], + ), + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(343.0, 240.5), + LineToCommand(484.0, 240.5), + LineToCommand(484.0, 366.5), + LineToCommand(343.0, 366.5), + CloseCommand() + ], + ) + ]); + }); + + test('Solid shape overlapping semi-transparent shape', () { + final Node node = parseAndResolve(solidOverTrasnparent); + final VectorInstructions instructions = parse(solidOverTrasnparent); + + final OverdrawOptimizer visitor = OverdrawOptimizer(); + final Node newNode = visitor.apply(node); + + final List pathNodesNew = + queryChildren(newNode); + + expect(pathNodesNew.length, 2); + + expect(instructions.paints, const [ + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0x7fff0000))), + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0xff0000ff))) + ]); + + expect(instructions.paths, [ + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(343.0, 240.5), + LineToCommand(88.0, 240.5), + LineToCommand(88.0, 366.5), + LineToCommand(343.0, 366.5), + LineToCommand(343.0, 240.5), + CloseCommand(), + MoveToCommand(484.0, 240.5), + LineToCommand(484.0, 366.5), + LineToCommand(711.0, 366.5), + LineToCommand(711.0, 240.5), + LineToCommand(484.0, 240.5), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(343.0, 63.5), + LineToCommand(484.0, 63.5), + LineToCommand(484.0, 565.50001), + LineToCommand(343.0, 565.50001), + CloseCommand() + ], + ) + ]); + }); + + test('Semi-transparent shape overlapping solid shape', () { + final Node node = parseAndResolve(transparentOverSolid); + final VectorInstructions instructions = parse(transparentOverSolid); + + final OverdrawOptimizer visitor = OverdrawOptimizer(); + final Node newNode = visitor.apply(node); + + final List pathNodesNew = + queryChildren(newNode); + + expect(pathNodesNew.length, 3); + + expect(instructions.paints, const [ + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0xffff0000))), + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0x7f0000ff))), + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0xff80007f))) + ]); + + expect(instructions.paths, [ + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(343.0, 240.5), + LineToCommand(88.0, 240.5), + LineToCommand(88.0, 366.5), + LineToCommand(343.0, 366.5), + LineToCommand(343.0, 240.5), + CloseCommand(), + MoveToCommand(484.0, 240.5), + LineToCommand(484.0, 366.5), + LineToCommand(711.0, 366.5), + LineToCommand(711.0, 240.5), + LineToCommand(484.0, 240.5), + CloseCommand() + ], + ), + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(484.0, 63.5), + LineToCommand(343.0, 63.5), + LineToCommand(343.0, 240.5), + LineToCommand(484.0, 240.5), + LineToCommand(484.0, 63.5), + CloseCommand(), + MoveToCommand(484.0, 366.5), + LineToCommand(343.0, 366.5), + LineToCommand(343.0, 565.5), + LineToCommand(484.0, 565.5), + LineToCommand(484.0, 366.5), + CloseCommand() + ], + ), + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(343.0, 240.5), + LineToCommand(484.0, 240.5), + LineToCommand(484.0, 366.5), + LineToCommand(343.0, 366.5), + CloseCommand() + ], + ) + ]); + }); + + test('Does not attempt to optimize overdraw when a mask is involved', () { + final Node node = parseAndResolve(''' + + + + + + + + + +'''); + + final Node result = OverdrawOptimizer().apply(node); + expect( + queryChildren(result), + queryChildren(node), + ); + }); + + test('Multiple opaque and semi-trasnparent shapes', () { + final Node node = parseAndResolve(complexOpacityTest); + final VectorInstructions instructions = parse(complexOpacityTest); + + final OverdrawOptimizer visitor = OverdrawOptimizer(); + final Node newNode = visitor.apply(node); + + final List pathNodesNew = + queryChildren(newNode); + + expect(pathNodesNew.length, 22); + + expect(instructions.paints, const [ + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0xff0000ff))), + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0xffff0000))), + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0xccff0000))), + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0x99ff0000))), + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0x66ff0000))), + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0x33ff0000))), + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0xff008000))), + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0xbfff0000))), + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0xbf008000))), + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0x7fff0000))), + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0x7f008000))), + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0x3fff0000))), + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0x3f008000))) + ]); + + expect(instructions.paths, [ + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(150.0, 100.0), + LineToCommand(100.0, 100.0), + LineToCommand(100.0, 250.0), + LineToCommand(1100.0, 250.0), + LineToCommand(1100.0, 100.0), + LineToCommand(250.0, 100.0), + CubicToCommand(250.0, 127.59574890136719, 227.5957489013672, 150.0, + 200.0, 150.0), + CubicToCommand(172.4042510986328, 150.0, 150.0, 127.59574890136719, + 150.0, 100.0), + CloseCommand() + ], + ), + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(200.0, 50.0), + CubicToCommand( + 227.5957489013672, 50.0, 250.0, 72.40425109863281, 250.0, 100.0), + CubicToCommand(250.0, 127.59574890136719, 227.5957489013672, 150.0, + 200.0, 150.0), + CubicToCommand(172.4042510986328, 150.0, 150.0, 127.59574890136719, + 150.0, 100.0), + CubicToCommand( + 150.0, 72.40425109863281, 172.4042510986328, 50.0, 200.0, 50.0), + CloseCommand() + ], + ), + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(400.0, 50.0), + CubicToCommand( + 427.59576416015625, 50.0, 450.0, 72.40425109863281, 450.0, 100.0), + CubicToCommand(450.0, 127.59574890136719, 427.59576416015625, 150.0, + 400.0, 150.0), + CubicToCommand(372.40423583984375, 150.0, 350.0, 127.59574890136719, + 350.0, 100.0), + CubicToCommand( + 350.0, 72.40425109863281, 372.40423583984375, 50.0, 400.0, 50.0), + CloseCommand() + ], + ), + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(600.0, 50.0), + CubicToCommand( + 627.5957641601562, 50.0, 650.0, 72.40425109863281, 650.0, 100.0), + CubicToCommand(650.0, 127.59574890136719, 627.5957641601562, 150.0, + 600.0, 150.0), + CubicToCommand(572.4042358398438, 150.0, 550.0, 127.59574890136719, + 550.0, 100.0), + CubicToCommand( + 550.0, 72.40425109863281, 572.4042358398438, 50.0, 600.0, 50.0), + CloseCommand() + ], + ), + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(800.0, 50.0), + CubicToCommand( + 827.5957641601562, 50.0, 850.0, 72.40425109863281, 850.0, 100.0), + CubicToCommand(850.0, 127.59574890136719, 827.5957641601562, 150.0, + 800.0, 150.0), + CubicToCommand(772.4042358398438, 150.0, 750.0, 127.59574890136719, + 750.0, 100.0), + CubicToCommand( + 750.0, 72.40425109863281, 772.4042358398438, 50.0, 800.0, 50.0), + CloseCommand() + ], + ), + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(1000.0, 50.0), + CubicToCommand( + 1027.595703125, 50.0, 1050.0, 72.40425109863281, 1050.0, 100.0), + CubicToCommand( + 1050.0, 127.59574890136719, 1027.595703125, 150.0, 1000.0, 150.0), + CubicToCommand(972.4042358398438, 150.0, 950.0, 127.59574890136719, + 950.0, 100.0), + CubicToCommand( + 950.0, 72.40425109863281, 972.4042358398438, 50.0, 1000.0, 50.0), + CloseCommand() + ], + ), + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(200.0000457763672, 203.1529998779297), + CubicToCommand(194.55233764648438, 201.1146697998047, + 188.6553192138672, 200.0, 182.5, 200.0), + CubicToCommand( + 154.9042510986328, 200.0, 132.5, 222.4042510986328, 132.5, 250.0), + CubicToCommand(132.5, 277.59576416015625, 154.9042510986328, 300.0, + 182.5, 300.0), + CubicToCommand(188.65528869628906, 300.0, 194.55230712890625, + 298.88531494140625, 200.0, 296.8470153808594), + CubicToCommand(181.02427673339844, 289.7470703125, 167.5, + 271.4404602050781, 167.5, 250.0), + CubicToCommand(167.5, 228.55953979492188, 181.02427673339844, + 210.2529296875, 200.0000457763672, 203.1529998779297), + CloseCommand() + ], + ), + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(217.5, 200.0), + CubicToCommand( + 245.0957489013672, 200.0, 267.5, 222.4042510986328, 267.5, 250.0), + CubicToCommand(267.5, 277.59576416015625, 245.0957489013672, 300.0, + 217.5, 300.0), + CubicToCommand(189.9042510986328, 300.0, 167.5, 277.59576416015625, + 167.5, 250.0), + CubicToCommand( + 167.5, 222.4042510986328, 189.9042510986328, 200.0, 217.5, 200.0), + CloseCommand() + ], + ), + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(382.5, 200.0), + CubicToCommand(410.09576416015625, 200.0, 432.5, 222.4042510986328, + 432.5, 250.0), + CubicToCommand(432.5, 277.59576416015625, 410.09576416015625, 300.0, + 382.5, 300.0), + CubicToCommand(354.90423583984375, 300.0, 332.5, 277.59576416015625, + 332.5, 250.0), + CubicToCommand(332.5, 222.4042510986328, 354.90423583984375, 200.0, + 382.5, 200.0), + CloseCommand() + ], + ), + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(417.5, 200.0), + CubicToCommand(445.09576416015625, 200.0, 467.5, 222.4042510986328, + 467.5, 250.0), + CubicToCommand(467.5, 277.59576416015625, 445.09576416015625, 300.0, + 417.5, 300.0), + CubicToCommand(389.90423583984375, 300.0, 367.5, 277.59576416015625, + 367.5, 250.0), + CubicToCommand(367.5, 222.4042510986328, 389.90423583984375, 200.0, + 417.5, 200.0), + CloseCommand() + ], + ), + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(582.5, 200.0), + CubicToCommand( + 610.0957641601562, 200.0, 632.5, 222.4042510986328, 632.5, 250.0), + CubicToCommand(632.5, 277.59576416015625, 610.0957641601562, 300.0, + 582.5, 300.0), + CubicToCommand(554.9042358398438, 300.0, 532.5, 277.59576416015625, + 532.5, 250.0), + CubicToCommand( + 532.5, 222.4042510986328, 554.9042358398438, 200.0, 582.5, 200.0), + CloseCommand() + ], + ), + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(617.5, 200.0), + CubicToCommand( + 645.0957641601562, 200.0, 667.5, 222.4042510986328, 667.5, 250.0), + CubicToCommand(667.5, 277.59576416015625, 645.0957641601562, 300.0, + 617.5, 300.0), + CubicToCommand(589.9042358398438, 300.0, 567.5, 277.59576416015625, + 567.5, 250.0), + CubicToCommand( + 567.5, 222.4042510986328, 589.9042358398438, 200.0, 617.5, 200.0), + CloseCommand() + ], + ), + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(817.5, 200.0), + CubicToCommand( + 845.0957641601562, 200.0, 867.5, 222.4042510986328, 867.5, 250.0), + CubicToCommand(867.5, 277.59576416015625, 845.0957641601562, 300.0, + 817.5, 300.0), + CubicToCommand(789.9042358398438, 300.0, 767.5, 277.59576416015625, + 767.5, 250.0), + CubicToCommand( + 767.5, 222.4042510986328, 789.9042358398438, 200.0, 817.5, 200.0), + CloseCommand() + ], + ), + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(782.5, 200.0), + CubicToCommand( + 810.0957641601562, 200.0, 832.5, 222.4042510986328, 832.5, 250.0), + CubicToCommand(832.5, 277.59576416015625, 810.0957641601562, 300.0, + 782.5, 300.0), + CubicToCommand(754.9042358398438, 300.0, 732.5, 277.59576416015625, + 732.5, 250.0), + CubicToCommand( + 732.5, 222.4042510986328, 754.9042358398438, 200.0, 782.5, 200.0), + CloseCommand() + ], + ), + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(982.5, 200.0), + CubicToCommand(1010.0957641601562, 200.0, 1032.5, 222.4042510986328, + 1032.5, 250.0), + CubicToCommand(1032.5, 277.59576416015625, 1010.0957641601562, 300.0, + 982.5, 300.0), + CubicToCommand(954.9042358398438, 300.0, 932.5, 277.59576416015625, + 932.5, 250.0), + CubicToCommand( + 932.5, 222.4042510986328, 954.9042358398438, 200.0, 982.5, 200.0), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(1017.5, 200.0), + CubicToCommand( + 1045.0957512247, 200.0, 1067.5, 222.4042487753, 1067.5, 250.0), + CubicToCommand( + 1067.5, 277.5957512247, 1045.0957512247, 300.0, 1017.5, 300.0), + CubicToCommand( + 989.9042487753, 300.0, 967.5, 277.5957512247, 967.5, 250.0), + CubicToCommand( + 967.5, 222.4042487753, 989.9042487753, 200.0, 1017.5, 200.0), + CloseCommand() + ], + ) + ]); + }); +} diff --git a/packages/vector_graphics_compiler/test/paint_test.dart b/packages/vector_graphics_compiler/test/paint_test.dart new file mode 100644 index 000000000000..6621269e39fb --- /dev/null +++ b/packages/vector_graphics_compiler/test/paint_test.dart @@ -0,0 +1,138 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; + +void main() { + test('Color tests', () { + expect( + const Color.fromRGBO(10, 15, 20, .1), + const Color.fromARGB(25, 10, 15, 20), + ); + + expect( + const Color.fromARGB(255, 10, 15, 20).withOpacity(.1), + const Color.fromARGB(25, 10, 15, 20), + ); + + const Color testColor = Color(0xFFABCDEF); + expect(testColor.r, 0xAB); + expect(testColor.g, 0xCD); + expect(testColor.b, 0xEF); + }); + + test('LinearGradient can be converted to local coordinates', () { + const LinearGradient gradient = LinearGradient( + id: 'test', + from: Point.zero, + to: Point(1, 1), + colors: [Color.opaqueBlack, Color(0xFFABCDEF)], + tileMode: TileMode.mirror, + offsets: [0.0, 1.0], + transform: AffineMatrix.identity, + ); + + final LinearGradient transformed = gradient.applyBounds( + const Rect.fromLTWH(5, 5, 100, 100), + AffineMatrix.identity, + ); + + expect(transformed.from, const Point(5, 5)); + expect(transformed.to, const Point(105, 105)); + }); + + test('LinearGradient applied bounds with userSpaceOnUse', () { + const LinearGradient gradient = LinearGradient( + id: 'test', + from: Point.zero, + to: Point(1, 1), + colors: [Color.opaqueBlack, Color(0xFFABCDEF)], + tileMode: TileMode.mirror, + offsets: [0.0, 1.0], + transform: AffineMatrix.identity, + unitMode: GradientUnitMode.userSpaceOnUse, + ); + + final LinearGradient transformed = gradient.applyBounds( + const Rect.fromLTWH(5, 5, 100, 100), + AffineMatrix.identity, + ); + + expect(transformed.from, Point.zero); + expect(transformed.to, const Point(1, 1)); + }); + + test('LinearGradient applied bounds with userSpaceOnUse and transformed', () { + final LinearGradient gradient = LinearGradient( + id: 'test', + from: Point.zero, + to: const Point(1, 1), + colors: const [Color.opaqueBlack, Color(0xFFABCDEF)], + tileMode: TileMode.mirror, + offsets: const [0.0, 1.0], + transform: AffineMatrix.identity.scaled(2), + unitMode: GradientUnitMode.userSpaceOnUse, + ); + + final LinearGradient transformed = gradient.applyBounds( + const Rect.fromLTWH(5, 5, 100, 100), + AffineMatrix.identity, + ); + + expect(transformed.from, Point.zero); + expect(transformed.to, const Point(2, 2)); + }); + + test('RadialGradient can be converted to local coordinates', () { + const RadialGradient gradient = RadialGradient( + id: 'test', + center: Point(0.5, 0.5), + radius: 10, + colors: [Color(0xFFFFFFAA), Color(0xFFABCDEF)], + tileMode: TileMode.clamp, + transform: AffineMatrix.identity, + focalPoint: Point(0.6, 0.6), + offsets: [.1, .9], + ); + + final RadialGradient transformed = gradient.applyBounds( + const Rect.fromLTWH(5, 5, 100, 100), + AffineMatrix.identity.translated(5, 5).scaled(100, 100), + ); + + expect(transformed.center, const Point(.5, .5)); + expect(transformed.focalPoint, const Point(.6, .6)); + expect( + transformed.transform, + AffineMatrix.identity + .translated(5, 5) + .scaled(100, 100) + .multiplied(AffineMatrix.identity.translated(5, 5).scaled(100, 100)), + ); + }); + + test('RadialGradient applied bounds with userSpaceOnUse', () { + const RadialGradient gradient = RadialGradient( + id: 'test', + center: Point(0.5, 0.5), + radius: 10, + colors: [Color(0xFFFFFFAA), Color(0xFFABCDEF)], + tileMode: TileMode.clamp, + transform: AffineMatrix.identity, + focalPoint: Point(0.6, 0.6), + offsets: [.1, .9], + unitMode: GradientUnitMode.userSpaceOnUse, + ); + + final RadialGradient transformed = gradient.applyBounds( + const Rect.fromLTWH(5, 5, 100, 100), + AffineMatrix.identity, + ); + + expect(transformed.center, const Point(0.5, 0.5)); + expect(transformed.focalPoint, const Point(0.6, 0.6)); + expect(transformed.transform, AffineMatrix.identity); + }); +} diff --git a/packages/vector_graphics_compiler/test/parser_test.dart b/packages/vector_graphics_compiler/test/parser_test.dart new file mode 100644 index 000000000000..24743c82f5fd --- /dev/null +++ b/packages/vector_graphics_compiler/test/parser_test.dart @@ -0,0 +1,7680 @@ +// 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:io'; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:vector_graphics_compiler/src/svg/numbers.dart'; +import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; +import 'test_svg_strings.dart'; + +void main() { + test('Reuse ID self-referentially', () { + final VectorInstructions instructions = parseWithoutOptimizers(''' + + + + + + + +'''); + + expect(instructions.paths.length, 1); + }); + + test('Self-referentially ID', () { + final VectorInstructions instructions = parseWithoutOptimizers(''' + + + + +'''); + + expect(instructions.paths.length, 0); + }); + + test('Text transform but no xy', () { + final VectorInstructions instructions = parseWithoutOptimizers(''' + + + 東急電鉄路線図 + Tōkyū Railways route map + + +'''); + + expect(instructions.text, const [ + TextConfig( + '東急電鉄路線図', + 0.0, + 'Arimo,Liberation Sans,HammersmithOne,Helvetica,Arial,sans-serif', + FontWeight.w600, + 40.0, + TextDecoration.none, + TextDecorationStyle.solid, + Color.opaqueBlack, + ), + TextConfig( + 'Tōkyū Railways route map', + 0.0, + 'Arimo,Liberation Sans,HammersmithOne,Helvetica,Arial,sans-serif', + FontWeight.w600, + 22.0, + TextDecoration.none, + TextDecorationStyle.solid, + Color.opaqueBlack, + ), + ]); + expect(instructions.textPositions, [ + TextPosition( + reset: true, transform: AffineMatrix.identity.translated(60, 45)), + TextPosition( + reset: true, transform: AffineMatrix.identity.translated(60, 75)), + ]); + }); + + test('Fill rule inheritence', () { + final VectorInstructions instructions = + parseWithoutOptimizers(inheritFillRule); + + expect(instructions.paints, const [ + Paint( + blendMode: BlendMode.srcOver, + stroke: Stroke(color: Color(0xffff0000)), + fill: Fill(color: Color.opaqueBlack), + ), + ]); + expect(instructions.paths, [ + Path( + commands: const [ + MoveToCommand(60.0, 10.0), + LineToCommand(31.0, 100.0), + LineToCommand(108.0, 45.0), + LineToCommand(12.0, 45.0), + LineToCommand(89.0, 100.0), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(160.0, 10.0), + LineToCommand(131.0, 100.0), + LineToCommand(208.0, 45.0), + LineToCommand(112.0, 45.0), + LineToCommand(189.0, 100.0), + CloseCommand() + ], + fillType: PathFillType.evenOdd, + ) + ]); + expect(instructions.commands, const [ + DrawCommand(DrawCommandType.path, objectId: 0, paintId: 0), + DrawCommand(DrawCommandType.path, objectId: 1, paintId: 0), + ]); + }); + + test('Text whitespace handling (number bubbles)', () { + final VectorInstructions instructions = + parseWithoutOptimizers(numberBubbles); + + expect( + instructions.textPositions, + const [ + TextPosition(reset: true), + TextPosition(x: 28.727, y: 12.0), + TextPosition(x: 52.727, y: 12.0), + TextPosition(x: 4.728, y: 12.0), + ], + ); + + expect(instructions.text, const [ + TextConfig( + '2', + 0.0, + 'AvenirNext-Medium, Avenir Next', + FontWeight.w400, + 11.0, + TextDecoration.none, + TextDecorationStyle.solid, + Color.opaqueBlack, + ), + TextConfig( + '3', + 0.0, + 'AvenirNext-Medium, Avenir Next', + FontWeight.w400, + 11.0, + TextDecoration.none, + TextDecorationStyle.solid, + Color.opaqueBlack, + ), + TextConfig( + '1', + 0.0, + 'AvenirNext-Medium, Avenir Next', + FontWeight.w400, + 11.0, + TextDecoration.none, + TextDecorationStyle.solid, + Color.opaqueBlack, + ), + ]); + }); + + test('None on fill', () { + const String svg = ''' + + + + + + + + + + + + + + + +'''; + + final VectorInstructions instructions = parseWithoutOptimizers(svg); + // Should _not_ contain a paint with an opaque black fill for the rect with class "frame-background". + expect(instructions.paints, const [ + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0xff22c55e))), + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0xfff59e0b))), + ]); + }); + + test('text spacing', () { + const String svg = ''' + + + + π( D² - d² )( N - N + u + ) + + + +'''; + + final VectorInstructions instructions = parseWithoutOptimizers(svg); + + expect(instructions.textPositions, const [ + TextPosition(reset: true, x: 35.081, y: 15.0), + TextPosition(y: 15.0), + ]); + + expect(instructions.text, const [ + TextConfig( + 'π( D² - d² )( N - N', + 0.0, + 'OpenSans-Italic, Open Sans', + FontWeight.w400, + 14.0, + TextDecoration.none, + TextDecorationStyle.solid, + Color.opaqueBlack, + ), + TextConfig( + ' u', + 0.0, + 'OpenSans-Italic, Open Sans', + FontWeight.w400, + 10.0, + TextDecoration.none, + TextDecorationStyle.solid, + Color.opaqueBlack, + ), + TextConfig( + ' )', + 0.0, + 'OpenSans-Italic, Open Sans', + FontWeight.w400, + 14.0, + TextDecoration.none, + TextDecorationStyle.solid, + Color.opaqueBlack, + ), + ]); + }); + + test('stroke-opacity', () { + const String strokeOpacitySvg = ''' + + + +'''; + + final VectorInstructions instructions = + parseWithoutOptimizers(strokeOpacitySvg); + + expect( + instructions.paints.single, + const Paint(stroke: Stroke(color: Color(0x7fff0000))), + ); + }); + + test('text attributes are preserved', () { + final VectorInstructions instructions = parseWithoutOptimizers(textTspan); + expect( + instructions.text, + const [ + TextConfig( + 'Some text', + 0.0, + 'Roboto-Regular, Roboto', + FontWeight.w400, + 16.0, + TextDecoration.none, + TextDecorationStyle.solid, + Color.opaqueBlack, + ), + TextConfig( + 'more text.', + 0.0, + 'Roboto-Regular, Roboto', + FontWeight.w400, + 16.0, + TextDecoration.none, + TextDecorationStyle.solid, + Color.opaqueBlack, + ), + TextConfig( + 'Even more text', + 0.0, + 'Roboto-Regular, Roboto', + FontWeight.w400, + 16.0, + TextDecoration.none, + TextDecorationStyle.solid, + Color.opaqueBlack, + ), + TextConfig( + 'text everywhere', + 0.0, + 'Roboto-Regular, Roboto', + FontWeight.w400, + 16.0, + TextDecoration.none, + TextDecorationStyle.solid, + Color.opaqueBlack, + ), + TextConfig( + 'so many lines', + 0.0, + 'Roboto-Regular, Roboto', + FontWeight.w400, + 16.0, + TextDecoration.none, + TextDecorationStyle.solid, + Color.opaqueBlack, + ), + ], + ); + }); + + test('currentColor', () { + const String currentColorSvg = ''' + + + +'''; + + final VectorInstructions blueInstructions = parseWithoutOptimizers( + currentColorSvg, + theme: const SvgTheme(currentColor: Color(0xFF0000FF)), + ); + final VectorInstructions redInstructions = parseWithoutOptimizers( + currentColorSvg, + theme: const SvgTheme(currentColor: Color(0xFFFF0000)), + ); + + expect( + blueInstructions.paints.single, + const Paint(fill: Fill(color: Color(0xFF0000FF))), + ); + + expect( + redInstructions.paints.single, + const Paint(fill: Fill(color: Color(0xFFFF0000))), + ); + }); + + test('Opacity with a save layer does not continue to inherit', () { + final VectorInstructions instructions = parseWithoutOptimizers(''' + + + + + + +'''); + + expect(instructions.paints, const [ + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0x06202124))), + // The paint for the saveLayer. + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color(0x0a000000))), + // The paint for the path drawn in the saveLayer - must not be the same as + // the saveLayer otherwise the path will be drawn almost completely transparent. + Paint(blendMode: BlendMode.srcOver, fill: Fill(color: Color.opaqueBlack)), + ]); + expect(instructions.commands, const [ + DrawCommand(DrawCommandType.path, objectId: 0, paintId: 0), + DrawCommand(DrawCommandType.saveLayer, paintId: 1), + DrawCommand(DrawCommandType.path, objectId: 1, paintId: 2), + DrawCommand(DrawCommandType.restore), + ]); + }); + + test('Opacity on a default fill', () { + final VectorInstructions instructions = parseWithoutOptimizers(''' + + + +'''); + + expect(instructions.paints.single.fill!.color, const Color(0x66000000)); + }); + + test('Stroke width with scaling', () { + final VectorInstructions instructions = parseWithoutOptimizers( + signWithScaledStroke, + ); + + expect(instructions.paints, const [ + Paint( + blendMode: BlendMode.srcOver, + stroke: Stroke( + color: Color(0xffffee44), join: StrokeJoin.round, width: 3.0)), + Paint( + blendMode: BlendMode.srcOver, + stroke: Stroke( + color: Color(0xff333333), join: StrokeJoin.round, width: 3.0), + fill: Fill(color: Color(0xffffee44))), + Paint( + blendMode: BlendMode.srcOver, + stroke: Stroke(color: Color(0xffccaa00), join: StrokeJoin.round), + fill: Fill(color: Color(0xffccaa00))), + Paint( + blendMode: BlendMode.srcOver, + stroke: Stroke(color: Color(0xff333333), join: StrokeJoin.round), + fill: Fill(color: Color(0xff555555))), + Paint( + blendMode: BlendMode.srcOver, + stroke: Stroke( + color: Color(0xff446699), join: StrokeJoin.round, width: 0.5)), + Paint( + blendMode: BlendMode.srcOver, + stroke: Stroke( + color: Color(0xffbbaa55), + join: StrokeJoin.round, + width: 0.49999999999999994)), + Paint( + blendMode: BlendMode.srcOver, + stroke: Stroke( + color: Color(0xff6688cc), + join: StrokeJoin.round, + width: 0.49999999999999994)), + Paint( + blendMode: BlendMode.srcOver, + stroke: Stroke( + color: Color(0xff333311), join: StrokeJoin.round, width: 0.5)), + Paint( + blendMode: BlendMode.srcOver, + stroke: Stroke( + color: Color(0xffffee44), join: StrokeJoin.round, width: 0.5), + fill: Fill(color: Color(0xff80a3cf))), + Paint( + blendMode: BlendMode.srcOver, + stroke: Stroke( + color: Color(0xffffee44), join: StrokeJoin.round, width: 0.5), + fill: Fill(color: Color(0xff668899))) + ]); + }); + + test('Use handles stroke and fill correctly', () { + final VectorInstructions instructions = parseWithoutOptimizers( + useStar, + ); + + // These kinds of paths are verified elsewhere, and the FP math can vary + // by platform. + expect(instructions.paths.length, 4); + + expect( + instructions.paints, + const [ + Paint( + blendMode: BlendMode.srcOver, + stroke: Stroke(color: Color.opaqueBlack, width: 12.0), + ), + Paint( + blendMode: BlendMode.srcOver, + stroke: Stroke(color: Color(0xff008000)), + fill: Fill(color: Color(0xffffbb44)), + ), + ], + ); + + expect( + instructions.commands, + const [ + DrawCommand(DrawCommandType.path, objectId: 0, paintId: 0), + DrawCommand(DrawCommandType.path, objectId: 1, paintId: 0), + DrawCommand(DrawCommandType.path, objectId: 2, paintId: 0), + DrawCommand(DrawCommandType.path, objectId: 3, paintId: 0), + DrawCommand(DrawCommandType.path, objectId: 0, paintId: 1), + DrawCommand(DrawCommandType.path, objectId: 1, paintId: 1), + DrawCommand(DrawCommandType.path, objectId: 2, paintId: 1), + DrawCommand(DrawCommandType.path, objectId: 3, paintId: 1), + ], + ); + }); + + test('Use preserves fill from shape', () { + final VectorInstructions instructions = parseWithoutOptimizers( + useColor, + ); + + expect( + instructions.paths, + [ + Path( + commands: const [ + MoveToCommand(60.0, 10.0), + LineToCommand(72.5, 27.5), + LineToCommand(47.5, 27.5), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(120.0, 10.0), + LineToCommand(132.5, 27.5), + LineToCommand(107.5, 27.5), + CloseCommand() + ], + ) + ], + ); + expect( + instructions.paints.single, + const Paint( + blendMode: BlendMode.srcOver, + fill: Fill(color: Color(0xffff0000)), + ), + ); + }); + + test('Image in defs', () { + final VectorInstructions instructions = parseWithoutOptimizers( + imageInDefs, + ); + expect(instructions.images.single.format, 0); + expect(instructions.images.single.data.length, 331); + expect(instructions.commands, const [ + DrawCommand(DrawCommandType.clip, objectId: 0), + DrawCommand(DrawCommandType.image, objectId: 0), + DrawCommand(DrawCommandType.restore) + ]); + }); + + test('Transformed clip', () { + final VectorInstructions instructions = parseWithoutOptimizers( + transformedClip, + ); + + expect(instructions.paths, [ + Path( + commands: const [ + MoveToCommand(0.0, 0.0), + LineToCommand(375.0, 0.0), + LineToCommand(375.0, 407.0), + LineToCommand(0.0, 407.0), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(360.0, 395.5), + LineToCommand(16.0, 395.5), + LineToCommand(188.0, 1.0), + LineToCommand(360.0, 395.5), + CloseCommand() + ], + ) + ]); + }); + + test('Zero width stroke', () { + final VectorInstructions instructions = parseWithoutOptimizers( + ''' + + +''', + ); + + expect(instructions.paints.single.stroke, null); + expect( + instructions.paints.single.fill, const Fill(color: Color(0xFFFFFFFF))); + }); + + test('text anchor', () { + final VectorInstructions instructions = parseWithoutOptimizers( + textAnchors, + ); + + expect(instructions.text, const [ + TextConfig( + 'Text anchor start', + 0.0, + 'Roboto', + FontWeight.w400, + 10.0, + TextDecoration.none, + TextDecorationStyle.solid, + Color.opaqueBlack, + ), + TextConfig( + 'Text anchor middle', + 0.5, + 'Roboto', + FontWeight.w400, + 10.0, + TextDecoration.none, + TextDecorationStyle.solid, + Color.opaqueBlack, + ), + TextConfig( + 'Text anchor end', + 1.0, + 'Roboto', + FontWeight.w400, + 10.0, + TextDecoration.none, + TextDecorationStyle.solid, + Color.opaqueBlack, + ) + ]); + }); + + test('text decorations', () { + final VectorInstructions instructions = parseWithoutOptimizers( + textDecorations, + ); + + expect(instructions.text, const [ + TextConfig( + 'Overline text', + 0, + 'Roboto', + FontWeight.w400, + 55.0, + TextDecoration.overline, + TextDecorationStyle.solid, + Color(0xffff0000), + ), + TextConfig( + 'Strike text', + 0, + 'Roboto', + FontWeight.w400, + 55.0, + TextDecoration.lineThrough, + TextDecorationStyle.solid, + Color(0xff008000), + ), + TextConfig( + 'Underline text', + 0, + 'Roboto', + FontWeight.w400, + 55.0, + TextDecoration.underline, + TextDecorationStyle.double, + Color(0xff008000), + ) + ]); + }); + + test('Stroke property set but does not draw stroke', () { + final VectorInstructions instructions = parseWithoutOptimizers( + strokePropertyButNoStroke, + ); + expect(instructions.paths.single.commands, const [ + MoveToCommand(10.0, 20.0), + LineToCommand(110.0, 20.0), + LineToCommand(110.0, 120.0), + LineToCommand(10.0, 120.0), + CloseCommand(), + ]); + expect( + instructions.paints.single, + const Paint(fill: Fill(color: Color(0xFFFF0000))), + ); + }); + + test('Clip with use', () { + final VectorInstructions instructions = parseWithoutOptimizers( + basicClip, + ); + final VectorInstructions instructions2 = parseWithoutOptimizers( + useClip, + ); + expect(instructions, instructions2); + }); + + test('stroke-dasharray="none"', () { + final VectorInstructions instructions = parseWithoutOptimizers( + ''' + + + +''', + ); + + expect(instructions.paints, const [ + Paint(fill: Fill(color: Color(0xffff0000))), + Paint(stroke: Stroke(color: Color.opaqueBlack, width: 2.0)), + ]); + + expect(instructions.paths, [ + Path( + commands: const [ + MoveToCommand(1.0, 20.0), + LineToCommand(20.0, 20.0), + LineToCommand(20.0, 39.0), + LineToCommand(30.0, 30.0), + LineToCommand(1.0, 26.0), + CloseCommand(), + ], + ), + ]); + }); + + test('Dashed path', () { + final VectorInstructions instructions = parseWithoutOptimizers( + ''' + + +''', + ); + + expect(instructions.paints, const [ + Paint(fill: Fill(color: Color(0xffff0000))), + Paint(stroke: Stroke(color: Color.opaqueBlack, width: 2.0)), + ]); + + expect(instructions.paths, [ + Path( + commands: const [ + MoveToCommand(1.0, 20.0), + LineToCommand(20.0, 20.0), + LineToCommand(20.0, 39.0), + LineToCommand(30.0, 30.0), + LineToCommand(1.0, 26.0), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(1.0, 20.0), + LineToCommand(6.0, 20.0), + MoveToCommand(9.0, 20.0), + LineToCommand(13.999999999999998, 20.0), + MoveToCommand(18.999999999999996, 20.0), + LineToCommand(20.0, 20.0), + LineToCommand(20.0, 24.0), + MoveToCommand(20.0, 27.000000000000004), + LineToCommand(20.0, 32.0), + MoveToCommand(20.0, 37.0), + LineToCommand(20.0, 39.0), + LineToCommand(22.229882438741498, 36.99310580513265), + MoveToCommand(24.459764877482996, 34.9862116102653), + LineToCommand(28.17623560871883, 31.641387952153053), + MoveToCommand(27.47750617803373, 29.65206981765983), + LineToCommand(22.524400531816358, 28.96888283197467), + MoveToCommand(19.55253714408593, 28.55897064056358), + LineToCommand(14.599431497868558, 27.875783654878425), + MoveToCommand(9.646325851651186, 27.19259666919327), + LineToCommand(4.693220205433812, 26.509409683508114), + MoveToCommand(1.7213568177033882, 26.09949749209702), + LineToCommand(1.0, 26.0), + LineToCommand(1.0, 21.72818638368261) + ], + ), + ]); + + expect(instructions.commands, const [ + DrawCommand(DrawCommandType.path, objectId: 0, paintId: 0), + DrawCommand(DrawCommandType.path, objectId: 1, paintId: 1), + ]); + }); + + test('text with transform', () { + final VectorInstructions instructions = parseWithoutOptimizers( + 'a', + ); + expect(instructions.paints.single, const Paint(fill: Fill())); + expect( + instructions.textPositions.single, + TextPosition( + reset: true, + transform: AffineMatrix.identity + .translated(-100, 50) + .rotated(radians(10)) + .translated(100, -50), + ), + ); + expect( + instructions.text.single, + const TextConfig( + 'a', + 0, + null, + normalFontWeight, + 16, + TextDecoration.none, + TextDecorationStyle.solid, + Color.opaqueBlack, + ), + ); + }); + + test('Missing references', () { + final VectorInstructions instructions = parseWithoutOptimizers( + missingRefs, + ); + expect( + instructions.paints.single, + const Paint(fill: Fill(color: Color(0xFFFF0000))), + ); + expect( + instructions.paths.single, + PathBuilder().addRect(const Rect.fromLTWH(5, 5, 100, 100)).toPath(), + ); + expect( + instructions.commands.single, + const DrawCommand(DrawCommandType.path, objectId: 0, paintId: 0), + ); + }); + + test('focal radial', () { + final VectorInstructions instructions = parseWithoutOptimizers( + focalRadial, + ); + + expect( + instructions.paints.single, + const Paint( + stroke: Stroke(color: Color.opaqueBlack), + fill: Fill( + color: Color(0xffffffff), + shader: RadialGradient( + id: 'url(#radial)', + center: Point(0.5, 0.5), + radius: 0.5, + colors: [ + Color(0xffff0000), + Color(0xff008000), + Color(0xff0000ff) + ], + offsets: [0.0, 0.5, 1.0], + tileMode: TileMode.clamp, + transform: AffineMatrix( + 120.0, + 0.0, + 0.0, + 120.0, + 10.0, + 10.0, + 120.0, + ), + focalPoint: Point(0.5, 0.15), + unitMode: GradientUnitMode.transformed, + ), + ), + ), + ); + expect( + instructions.paths.single, + PathBuilder().addRect(const Rect.fromLTWH(10, 10, 120, 120)).toPath(), + ); + }); + + test('Transformed userSpaceOnUse radial', () { + final VectorInstructions instructions = parseWithoutOptimizers( + xformUsosRadial, + ); + expect( + instructions.paints.single, + const Paint( + fill: Fill( + color: Color(0xffffffff), + shader: RadialGradient( + id: 'url(#paint0_radial)', + center: Point.zero, + radius: 1.0, + colors: [Color(0xcc47e9ff), Color(0x00414cbe)], + offsets: [0.0, 1.0], + tileMode: TileMode.clamp, + transform: AffineMatrix( + -433.0004488023628, + -350.99987486173313, + 350.99987486173313, + -433.0004488023628, + 432.9999999999999, + 547.0000000000001, + 557.396, + ), + unitMode: GradientUnitMode.transformed, + ), + ), + ), + ); + expect( + instructions.paths.single, + PathBuilder() + .addRect(const Rect.fromLTWH(667, 667, 667, 667)) + .toPath() + .transformed( + AffineMatrix.identity + .translated(667, 667) + .rotated(radians(180)) + .translated(-667, -667), + ), + ); + }); + + test('Transformed objectBoundingBox gradient onto transformed path', () { + final VectorInstructions instructions = parseWithoutOptimizers( + xformObbGradient, + ); + expect( + instructions.paints.single, + const Paint( + fill: Fill( + color: Color(0xffffffff), + shader: LinearGradient( + id: 'url(#paint1_linear)', + from: Point(405.5634918610405, 547.9898987322333), + to: Point(440.9188309203679, 866.1879502661797), + colors: [Color(0x7f0000ff), Color(0x19ff0000)], + offsets: [0.0, 1.0], + tileMode: TileMode.clamp, + unitMode: GradientUnitMode.transformed, + ), + ), + ), + ); + expect( + instructions.paths.single, + PathBuilder() + .addRect(const Rect.fromLTWH(300, 0, 500, 400)) + .toPath() + .transformed( + AffineMatrix.identity + .translated(0, 100) + .translated(250, 250) + .rotated(radians(45)) + .translated(-250, -250), + ), + ); + }, + // Currently skipped because the double values in Point are tested for + // exact equality, which makes this test fragile to host platform. + skip: Platform.isWindows); + + test('Opaque blend mode gets a save layer', () { + const String svg = ''' + + + + + + +'''; + final VectorInstructions instructions = parseWithoutOptimizers( + svg, + ); + expect(instructions.paints, const [ + Paint(fill: Fill(color: Color(0xffff0000))), + Paint(blendMode: BlendMode.screen, fill: Fill(color: Color.opaqueBlack)), + Paint(blendMode: BlendMode.screen, fill: Fill(color: Color(0xff008000))), + ]); + expect(instructions.commands, const [ + DrawCommand(DrawCommandType.path, objectId: 0, paintId: 0), + DrawCommand(DrawCommandType.saveLayer, paintId: 1), + DrawCommand(DrawCommandType.path, objectId: 1, paintId: 2), + DrawCommand(DrawCommandType.restore), + ]); + }); + + test('Stroke properties respected in toStroke', () { + const String svg = ''' + + + +'''; + final VectorInstructions instructions = parseWithoutOptimizers( + svg, + ); + expect( + instructions.paints.single, + const Paint( + stroke: Stroke( + color: Color(0xffff0000), + cap: StrokeCap.round, + join: StrokeJoin.round, + width: 2.7, + ), + ), + ); + }); + + test('gradients can handle inheriting unit mode', () { + final VectorInstructions instructions = parseWithoutOptimizers( + linearGradientThatInheritsUnitMode, + ); + expect(instructions.paints, const [ + Paint( + fill: Fill( + color: Color(0xffffffff), + shader: LinearGradient( + id: 'url(#a)', + from: Point(236.702, 9.99), + to: Point(337.966, 241.771), + colors: [ + Color(0xffffffff), + Color(0xb9c2c3c3), + Color(0x6a7d7e80), + Color(0x314b4c4e), + Color(0x0d2c2d30), + Color(0x00202124) + ], + offsets: [0.0, 0.229, 0.508, 0.739, 0.909, 1.0], + tileMode: TileMode.clamp, + unitMode: GradientUnitMode.transformed, + ), + ), + ), + Paint( + fill: Fill( + color: Color(0xffffffff), + shader: LinearGradient( + id: 'url(#d)', + from: Point(0.0, 50.243), + to: Point(0.0, 330.779), + colors: [ + Color(0xffffffff), + Color(0xb9c2c3c3), + Color(0x6a7d7e80), + Color(0x314b4c4e), + Color(0x0d2c2d30), + Color(0x00202124) + ], + offsets: [0.0, 0.229, 0.508, 0.739, 0.909, 1.0], + tileMode: TileMode.clamp, + unitMode: GradientUnitMode.transformed, + ), + ), + ) + ]); + }); + + test('group opacity results in save layer', () { + final VectorInstructions instructions = parseWithoutOptimizers( + groupOpacity, + ); + expect(instructions.paths, [ + PathBuilder().addOval(const Rect.fromCircle(80, 100, 50)).toPath(), + PathBuilder().addOval(const Rect.fromCircle(120, 100, 50)).toPath(), + ]); + expect(instructions.paints, const [ + Paint(fill: Fill(color: Color(0x7f000000))), + Paint(fill: Fill(color: Color(0x7fff0000))), + Paint(fill: Fill(color: Color(0x7f008000))), + ]); + expect(instructions.commands, const [ + DrawCommand(DrawCommandType.saveLayer, paintId: 0), + DrawCommand(DrawCommandType.path, objectId: 0, paintId: 1), + DrawCommand(DrawCommandType.path, objectId: 1, paintId: 2), + DrawCommand(DrawCommandType.restore), + ]); + }); + + test('xlink gradient Out of order', () { + final VectorInstructions instructions = parseWithoutOptimizers( + xlinkGradient, + ); + final VectorInstructions instructions2 = parseWithoutOptimizers( + xlinkGradientOoO, + ); + + expect(instructions.paints, instructions2.paints); + expect(instructions.paths, instructions2.paths); + expect(instructions.commands, instructions2.commands); + }); + + test('xlink use Out of order', () { + final VectorInstructions instructions = parseWithoutOptimizers( + simpleUseCircles, + ); + final VectorInstructions instructions2 = parseWithoutOptimizers( + simpleUseCirclesOoO, + ); + + // Use toSet to ignore ordering differences. + expect(instructions.paints.toSet(), instructions2.paints.toSet()); + expect(instructions.paths.toSet(), instructions2.paths.toSet()); + expect(instructions.commands.toSet(), instructions2.commands.toSet()); + }); + + test('xlink gradient with transform', () { + final VectorInstructions instructions = parseWithoutOptimizers( + xlinkGradient, + ); + expect(instructions.paths, [ + PathBuilder() + .addOval(const Rect.fromCircle(-83.533, 122.753, 74.461)) + .toPath() + .transformed( + const AffineMatrix(.63388, 0, 0, .63388, 100.15, -30.611)), + ]); + + expect(instructions.paints, const [ + Paint( + fill: Fill( + color: Color(0xffffffff), + shader: LinearGradient( + id: 'url(#b)', + from: Point(0.000763280000001032, 47.19967163999999), + to: Point(94.40007452, 47.19967163999999), + colors: [Color(0xff0f12cb), Color(0xfffded3a)], + offsets: [0.0, 1.0], + tileMode: TileMode.clamp, + unitMode: GradientUnitMode.transformed, + ), + ), + ) + ]); + + expect(instructions.commands, const [ + DrawCommand(DrawCommandType.path, objectId: 0, paintId: 0), + ]); + }); + + test('Out of order def', () { + final VectorInstructions instructions = parseWithoutOptimizers( + outOfOrderGradientDef, + ); + expect(instructions.paths, [ + parseSvgPathData( + 'M10 20c5.523 0 10-4.477 10-10S15.523 0 10 0 0 4.477 0 10s4.477 10 10 10z'), + ]); + expect(instructions.paints, const [ + Paint( + fill: Fill( + color: Color(0xffffffff), + shader: LinearGradient( + id: 'url(#paint0_linear)', + from: Point(10.0, 0.0), + to: Point(10.0, 19.852), + colors: [Color(0xff0000ff), Color(0xffffff00)], + offsets: [0.0, 1.0], + tileMode: TileMode.clamp, + unitMode: GradientUnitMode.transformed, + ), + ), + ) + ]); + + expect(instructions.commands, const [ + DrawCommand(DrawCommandType.path, objectId: 0, paintId: 0), + ]); + }); + + test('Handles masks correctly', () { + final VectorInstructions instructions = parseWithoutOptimizers( + basicMask, + ); + expect( + instructions.paths, + [ + parseSvgPathData('M-10,110 110,110 110,-10z'), + PathBuilder().addOval(const Rect.fromCircle(50, 50, 50)).toPath(), + PathBuilder().addRect(const Rect.fromLTWH(0, 0, 100, 100)).toPath(), + parseSvgPathData( + 'M10,35 A20,20,0,0,1,50,35 A20,20,0,0,1,90,35 Q90,65,50,95 Q10,65,10,35 Z'), + ].map((Path path) => + path.transformed(AffineMatrix.identity.translated(10, 10))), + ); + + expect(instructions.paints, const [ + Paint(fill: Fill(color: Color(0xffffa500))), + Paint(fill: Fill()), + Paint(fill: Fill(color: Color(0xffffffff))), + ]); + + expect(instructions.commands, const [ + DrawCommand(DrawCommandType.path, objectId: 0, paintId: 0), + DrawCommand(DrawCommandType.saveLayer, paintId: 1), + DrawCommand(DrawCommandType.path, objectId: 1, paintId: 1), + DrawCommand(DrawCommandType.mask), + DrawCommand(DrawCommandType.path, objectId: 2, paintId: 2), + DrawCommand(DrawCommandType.path, objectId: 3, paintId: 1), + DrawCommand(DrawCommandType.restore), + DrawCommand(DrawCommandType.restore), + ]); + }); + + test('Handles viewBox transformations correctly', () { + const String svg = ''' + + + +'''; + final VectorInstructions instructions = parseWithoutOptimizers( + svg, + ); + expect(instructions.paths, [ + PathBuilder() + .addRect(const Rect.fromLTWH(11, 36, 31, 20)) + .toPath() + .transformed(AffineMatrix.identity.translated(10, 12)), + ]); + }); + + test('Parses rrects correctly', () { + const String svg = ''' + + + +'''; + final VectorInstructions instructions = parseWithoutOptimizers( + svg, + ); + expect(instructions.paths, [ + PathBuilder() + .addRRect(const Rect.fromLTWH(11, 36, 31, 20), 2.5, 2.5) + .toPath() + ]); + }); + + test('Path with empty paint does not draw anything', () { + final VectorInstructions instructions = parseWithoutOptimizers( + ''' + + +''', + key: 'emptyPath', + warningsAsErrors: true, + ); + expect(instructions.commands.isEmpty, true); + }); + + test('Use circles test', () { + final VectorInstructions instructions = parseWithoutOptimizers( + simpleUseCircles, + key: 'useCircles', + warningsAsErrors: true, + ); + + expect( + instructions.paints, + const [ + Paint(fill: Fill()), + Paint(fill: Fill(color: Color(0xff0000ff))), + Paint( + stroke: Stroke(color: Color(0xff0000ff)), + fill: Fill(color: Color(0xffffffff)), + ), + ], + ); + + expect(instructions.paths, [ + Path( + commands: const [ + MoveToCommand(5.0, 1.0), + CubicToCommand( + 7.2076600979759995, 1.0, 9.0, 2.792339902024, 9.0, 5.0), + CubicToCommand( + 9.0, 7.2076600979759995, 7.2076600979759995, 9.0, 5.0, 9.0), + CubicToCommand( + 2.792339902024, 9.0, 1.0, 7.2076600979759995, 1.0, 5.0), + CubicToCommand(1.0, 2.792339902024, 2.792339902024, 1.0, 5.0, 1.0), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(15.0, 1.0), + CubicToCommand(17.207660097976, 1.0, 19.0, 2.792339902024, 19.0, 5.0), + CubicToCommand( + 19.0, 7.2076600979759995, 17.207660097976, 9.0, 15.0, 9.0), + CubicToCommand( + 12.792339902024, 9.0, 11.0, 7.2076600979759995, 11.0, 5.0), + CubicToCommand(11.0, 2.792339902024, 12.792339902024, 1.0, 15.0, 1.0), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(25.0, 1.0), + CubicToCommand(27.207660097976, 1.0, 29.0, 2.792339902024, 29.0, 5.0), + CubicToCommand( + 29.0, 7.2076600979759995, 27.207660097976, 9.0, 25.0, 9.0), + CubicToCommand( + 22.792339902024, 9.0, 21.0, 7.2076600979759995, 21.0, 5.0), + CubicToCommand(21.0, 2.792339902024, 22.792339902024, 1.0, 25.0, 1.0), + CloseCommand() + ], + ), + ]); + + expect( + instructions.commands, + const [ + DrawCommand(DrawCommandType.path, + objectId: 0, paintId: 0, debugString: 'myCircle'), + DrawCommand(DrawCommandType.path, + objectId: 1, paintId: 1, debugString: 'myCircle'), + DrawCommand(DrawCommandType.path, + objectId: 2, paintId: 2, debugString: 'myCircle') + ], + ); + }); + + test('Use circles test without href', () { + final VectorInstructions instructions = parseWithoutOptimizers( + simpleUseCirclesWithoutHref, + key: 'useCirclesWithoutHref', + warningsAsErrors: true, + ); + + expect(instructions.paints, const [ + Paint( + fill: Fill(color: Color.opaqueBlack), + ), + ]); + + expect(instructions.paths, [ + Path( + commands: const [ + MoveToCommand(5.0, 1.0), + CubicToCommand( + 7.2076600979759995, 1.0, 9.0, 2.792339902024, 9.0, 5.0), + CubicToCommand( + 9.0, 7.2076600979759995, 7.2076600979759995, 9.0, 5.0, 9.0), + CubicToCommand( + 2.792339902024, 9.0, 1.0, 7.2076600979759995, 1.0, 5.0), + CubicToCommand(1.0, 2.792339902024, 2.792339902024, 1.0, 5.0, 1.0), + CloseCommand() + ], + ), + ]); + + expect( + instructions.commands, + const [ + DrawCommand(DrawCommandType.path, + objectId: 0, paintId: 0, debugString: 'myCircle'), + ], + ); + }); + + test('Parses pattern used as fill and stroke', () { + final VectorInstructions instructions = parseWithoutOptimizers( + starPatternCircles, + warningsAsErrors: true, + ); + + expect(instructions.commands, const [ + DrawCommand(DrawCommandType.pattern, objectId: 0, patternDataId: 0), + DrawCommand(DrawCommandType.path, objectId: 0, paintId: 0), + DrawCommand(DrawCommandType.restore), + DrawCommand(DrawCommandType.path, objectId: 1, paintId: 1, patternId: 0), + DrawCommand(DrawCommandType.pattern, objectId: 0, patternDataId: 0), + DrawCommand(DrawCommandType.path, objectId: 0, paintId: 0), + DrawCommand(DrawCommandType.restore), + DrawCommand(DrawCommandType.path, objectId: 2, paintId: 2, patternId: 0) + ]); + }); + + test('Alternating pattern usage', () { + final VectorInstructions instructions = parseWithoutOptimizers( + alternatingPattern, + warningsAsErrors: true, + ); + + expect(instructions.commands, const [ + DrawCommand(DrawCommandType.pattern, objectId: 0, patternDataId: 0), + DrawCommand(DrawCommandType.path, objectId: 0, paintId: 0), + DrawCommand(DrawCommandType.restore), + DrawCommand(DrawCommandType.path, objectId: 1, paintId: 1, patternId: 0), + DrawCommand(DrawCommandType.pattern, objectId: 1, patternDataId: 0), + DrawCommand(DrawCommandType.path, objectId: 2, paintId: 2), + DrawCommand(DrawCommandType.restore), + DrawCommand(DrawCommandType.path, objectId: 3, paintId: 1, patternId: 1), + DrawCommand(DrawCommandType.pattern, objectId: 0, patternDataId: 0), + DrawCommand(DrawCommandType.path, objectId: 0, paintId: 0), + DrawCommand(DrawCommandType.restore), + DrawCommand(DrawCommandType.path, objectId: 4, paintId: 1, patternId: 0), + DrawCommand(DrawCommandType.pattern, objectId: 1, patternDataId: 0), + DrawCommand(DrawCommandType.path, objectId: 2, paintId: 2), + DrawCommand(DrawCommandType.restore), + DrawCommand(DrawCommandType.path, objectId: 5, paintId: 1, patternId: 1) + ]); + }); + + test('Parses text with pattern as fill', () { + const String textWithPattern = ''' + + + + + + + Text +'''; + + final VectorInstructions instructions = parseWithoutOptimizers( + textWithPattern, + warningsAsErrors: true, + ); + + expect(instructions.commands, const [ + DrawCommand(DrawCommandType.pattern, objectId: 0), + DrawCommand(DrawCommandType.path, objectId: 0, paintId: 0), + DrawCommand(DrawCommandType.restore), + DrawCommand(DrawCommandType.textPosition, objectId: 0), + DrawCommand(DrawCommandType.text, objectId: 0, paintId: 1, patternId: 0) + ]); + + expect( + instructions.text, + const [ + TextConfig( + 'Text', + 0.0, + null, + FontWeight.w400, + 200.0, + TextDecoration.none, + TextDecorationStyle.solid, + Color.opaqueBlack, + ) + ], + ); + }); + + test('Defaults image height/width when not specified', () { + // 1x1 PNG image from png-pixel.com. + const String svgStr = ''' + + +'''; + + final VectorInstructions instructions = parseWithoutOptimizers( + svgStr, + key: 'image', + warningsAsErrors: true, + ); + + expect(instructions.drawImages.first.rect, const Rect.fromLTWH(0, 0, 1, 1)); + }); + + test('Other image formats', () { + // 1x1 PNG image from png-pixel.com. Claiming that it's JPEG and using "img" + // instead of "image" to make sure parser doesn't barf. Chrome is ok with + // this kind of nonsense. How far we have strayed. + const String svgStr = ''' + + +'''; + + final VectorInstructions instructions = parseWithoutOptimizers( + svgStr, + key: 'image', + warningsAsErrors: true, + ); + + expect(instructions.images.first.format, 1); + }); + + test('Ghostscript Tiger - dedupes paints', () { + final VectorInstructions instructions = parseWithoutOptimizers( + ghostscriptTiger, + key: 'ghostscriptTiger', + warningsAsErrors: true, + ); + + expect(instructions.paints.toSet(), ghostScriptTigerPaints.toSet()); + expect(instructions.paths, ghostScriptTigerPaths); + expect( + instructions.commands, + const [ + DrawCommand(DrawCommandType.path, + objectId: 0, paintId: 0, debugString: 'path8'), + DrawCommand(DrawCommandType.path, + objectId: 1, paintId: 0, debugString: 'path12'), + DrawCommand(DrawCommandType.path, + objectId: 2, paintId: 0, debugString: 'path16'), + DrawCommand(DrawCommandType.path, + objectId: 3, paintId: 0, debugString: 'path20'), + DrawCommand(DrawCommandType.path, + objectId: 4, paintId: 0, debugString: 'path24'), + DrawCommand(DrawCommandType.path, + objectId: 5, paintId: 0, debugString: 'path28'), + DrawCommand(DrawCommandType.path, + objectId: 6, paintId: 0, debugString: 'path32'), + DrawCommand(DrawCommandType.path, + objectId: 7, paintId: 0, debugString: 'path36'), + DrawCommand(DrawCommandType.path, + objectId: 8, paintId: 0, debugString: 'path40'), + DrawCommand(DrawCommandType.path, + objectId: 9, paintId: 0, debugString: 'path44'), + DrawCommand(DrawCommandType.path, + objectId: 10, paintId: 0, debugString: 'path48'), + DrawCommand(DrawCommandType.path, + objectId: 11, paintId: 0, debugString: 'path52'), + DrawCommand(DrawCommandType.path, + objectId: 12, paintId: 1, debugString: 'path56'), + DrawCommand(DrawCommandType.path, + objectId: 13, paintId: 2, debugString: 'path60'), + DrawCommand(DrawCommandType.path, + objectId: 14, paintId: 3, debugString: 'path64'), + DrawCommand(DrawCommandType.path, + objectId: 15, paintId: 4, debugString: 'path68'), + DrawCommand(DrawCommandType.path, + objectId: 16, paintId: 5, debugString: 'path72'), + DrawCommand(DrawCommandType.path, + objectId: 17, paintId: 6, debugString: 'path76'), + DrawCommand(DrawCommandType.path, + objectId: 18, paintId: 7, debugString: 'path80'), + DrawCommand(DrawCommandType.path, + objectId: 19, paintId: 8, debugString: 'path84'), + DrawCommand(DrawCommandType.path, + objectId: 20, paintId: 9, debugString: 'path88'), + DrawCommand(DrawCommandType.path, + objectId: 21, paintId: 10, debugString: 'path92'), + DrawCommand(DrawCommandType.path, + objectId: 22, paintId: 11, debugString: 'path96'), + DrawCommand(DrawCommandType.path, + objectId: 23, paintId: 12, debugString: 'path100'), + DrawCommand(DrawCommandType.path, + objectId: 24, paintId: 13, debugString: 'path104'), + DrawCommand(DrawCommandType.path, + objectId: 25, paintId: 14, debugString: 'path108'), + DrawCommand(DrawCommandType.path, + objectId: 26, paintId: 15, debugString: 'path112'), + DrawCommand(DrawCommandType.path, + objectId: 27, paintId: 16, debugString: 'path116'), + DrawCommand(DrawCommandType.path, + objectId: 28, paintId: 15, debugString: 'path120'), + DrawCommand(DrawCommandType.path, + objectId: 29, paintId: 16, debugString: 'path124'), + DrawCommand(DrawCommandType.path, + objectId: 30, paintId: 16, debugString: 'path128'), + DrawCommand(DrawCommandType.path, + objectId: 31, paintId: 16, debugString: 'path132'), + DrawCommand(DrawCommandType.path, + objectId: 32, paintId: 16, debugString: 'path136'), + DrawCommand(DrawCommandType.path, + objectId: 33, paintId: 16, debugString: 'path140'), + DrawCommand(DrawCommandType.path, + objectId: 34, paintId: 16, debugString: 'path144'), + DrawCommand(DrawCommandType.path, + objectId: 35, paintId: 15, debugString: 'path148'), + DrawCommand(DrawCommandType.path, + objectId: 36, paintId: 17, debugString: 'path152'), + DrawCommand(DrawCommandType.path, + objectId: 37, paintId: 18, debugString: 'path156'), + DrawCommand(DrawCommandType.path, + objectId: 38, paintId: 19, debugString: 'path160'), + DrawCommand(DrawCommandType.path, + objectId: 39, paintId: 20, debugString: 'path164'), + DrawCommand(DrawCommandType.path, + objectId: 40, paintId: 21, debugString: 'path168'), + DrawCommand(DrawCommandType.path, + objectId: 41, paintId: 22, debugString: 'path172'), + DrawCommand(DrawCommandType.path, + objectId: 42, paintId: 23, debugString: 'path176'), + DrawCommand(DrawCommandType.path, + objectId: 43, paintId: 21, debugString: 'path180'), + DrawCommand(DrawCommandType.path, + objectId: 44, paintId: 21, debugString: 'path184'), + DrawCommand(DrawCommandType.path, + objectId: 45, paintId: 21, debugString: 'path188'), + DrawCommand(DrawCommandType.path, + objectId: 46, paintId: 21, debugString: 'path192'), + DrawCommand(DrawCommandType.path, + objectId: 47, paintId: 21, debugString: 'path196'), + DrawCommand(DrawCommandType.path, + objectId: 48, paintId: 21, debugString: 'path200'), + DrawCommand(DrawCommandType.path, + objectId: 49, paintId: 24, debugString: 'path204'), + DrawCommand(DrawCommandType.path, + objectId: 50, paintId: 24, debugString: 'path208'), + DrawCommand(DrawCommandType.path, + objectId: 51, paintId: 21, debugString: 'path212'), + DrawCommand(DrawCommandType.path, + objectId: 52, paintId: 24, debugString: 'path216'), + DrawCommand(DrawCommandType.path, + objectId: 53, paintId: 24, debugString: 'path220'), + DrawCommand(DrawCommandType.path, + objectId: 54, paintId: 25, debugString: 'path224'), + DrawCommand(DrawCommandType.path, + objectId: 55, paintId: 21, debugString: 'path228'), + DrawCommand(DrawCommandType.path, + objectId: 56, paintId: 21, debugString: 'path232'), + DrawCommand(DrawCommandType.path, + objectId: 57, paintId: 21, debugString: 'path236'), + DrawCommand(DrawCommandType.path, + objectId: 58, paintId: 15, debugString: 'path240'), + DrawCommand(DrawCommandType.path, + objectId: 59, paintId: 21, debugString: 'path244'), + DrawCommand(DrawCommandType.path, + objectId: 60, paintId: 21, debugString: 'path248'), + DrawCommand(DrawCommandType.path, + objectId: 61, paintId: 21, debugString: 'path252'), + DrawCommand(DrawCommandType.path, + objectId: 62, paintId: 21, debugString: 'path256'), + DrawCommand(DrawCommandType.path, + objectId: 63, paintId: 21, debugString: 'path260'), + DrawCommand(DrawCommandType.path, + objectId: 64, paintId: 26, debugString: 'path264'), + DrawCommand(DrawCommandType.path, + objectId: 65, paintId: 26, debugString: 'path268'), + DrawCommand(DrawCommandType.path, + objectId: 66, paintId: 3, debugString: 'path272'), + DrawCommand(DrawCommandType.path, + objectId: 67, paintId: 27, debugString: 'path276'), + DrawCommand(DrawCommandType.path, + objectId: 68, paintId: 28, debugString: 'path280'), + DrawCommand(DrawCommandType.path, + objectId: 69, paintId: 29, debugString: 'path284'), + DrawCommand(DrawCommandType.path, + objectId: 70, paintId: 30, debugString: 'path288'), + DrawCommand(DrawCommandType.path, + objectId: 71, paintId: 14, debugString: 'path292'), + DrawCommand(DrawCommandType.path, + objectId: 72, paintId: 16, debugString: 'path296'), + DrawCommand(DrawCommandType.path, + objectId: 73, paintId: 15, debugString: 'path300'), + DrawCommand(DrawCommandType.path, + objectId: 74, paintId: 31, debugString: 'path304'), + DrawCommand(DrawCommandType.path, + objectId: 75, paintId: 32, debugString: 'path308'), + DrawCommand(DrawCommandType.path, + objectId: 76, paintId: 14, debugString: 'path312'), + DrawCommand(DrawCommandType.path, + objectId: 77, paintId: 15, debugString: 'path316'), + DrawCommand(DrawCommandType.path, + objectId: 78, paintId: 3, debugString: 'path320'), + DrawCommand(DrawCommandType.path, + objectId: 79, paintId: 14, debugString: 'path324'), + DrawCommand(DrawCommandType.path, + objectId: 80, paintId: 33, debugString: 'path328'), + DrawCommand(DrawCommandType.path, + objectId: 81, paintId: 34, debugString: 'path332'), + DrawCommand(DrawCommandType.path, + objectId: 82, paintId: 35, debugString: 'path336'), + DrawCommand(DrawCommandType.path, + objectId: 83, paintId: 14, debugString: 'path340'), + DrawCommand(DrawCommandType.path, + objectId: 84, paintId: 16, debugString: 'path344'), + DrawCommand(DrawCommandType.path, + objectId: 85, paintId: 15, debugString: 'path348'), + DrawCommand(DrawCommandType.path, + objectId: 86, paintId: 31, debugString: 'path352'), + DrawCommand(DrawCommandType.path, + objectId: 87, paintId: 15, debugString: 'path356'), + DrawCommand(DrawCommandType.path, + objectId: 88, paintId: 15, debugString: 'path360'), + DrawCommand(DrawCommandType.path, + objectId: 89, paintId: 15, debugString: 'path364'), + DrawCommand(DrawCommandType.path, + objectId: 90, paintId: 36, debugString: 'path368'), + DrawCommand(DrawCommandType.path, + objectId: 91, paintId: 37, debugString: 'path372'), + DrawCommand(DrawCommandType.path, + objectId: 92, paintId: 38, debugString: 'path376'), + DrawCommand(DrawCommandType.path, + objectId: 93, paintId: 16, debugString: 'path380'), + DrawCommand(DrawCommandType.path, + objectId: 94, paintId: 14, debugString: 'path384'), + DrawCommand(DrawCommandType.path, + objectId: 95, paintId: 39, debugString: 'path388'), + DrawCommand(DrawCommandType.path, + objectId: 96, paintId: 16, debugString: 'path392'), + DrawCommand(DrawCommandType.path, + objectId: 97, paintId: 16, debugString: 'path396'), + DrawCommand(DrawCommandType.path, + objectId: 98, paintId: 16, debugString: 'path400'), + DrawCommand(DrawCommandType.path, + objectId: 99, paintId: 16, debugString: 'path404'), + DrawCommand(DrawCommandType.path, + objectId: 100, paintId: 16, debugString: 'path408'), + DrawCommand(DrawCommandType.path, + objectId: 101, paintId: 15, debugString: 'path412'), + DrawCommand(DrawCommandType.path, + objectId: 102, paintId: 15, debugString: 'path416'), + DrawCommand(DrawCommandType.path, + objectId: 103, paintId: 3, debugString: 'path420'), + DrawCommand(DrawCommandType.path, + objectId: 104, paintId: 3, debugString: 'path424'), + DrawCommand(DrawCommandType.path, + objectId: 105, paintId: 3, debugString: 'path428'), + DrawCommand(DrawCommandType.path, + objectId: 106, paintId: 3, debugString: 'path432'), + DrawCommand(DrawCommandType.path, + objectId: 107, paintId: 3, debugString: 'path436'), + DrawCommand(DrawCommandType.path, + objectId: 108, paintId: 3, debugString: 'path440'), + DrawCommand(DrawCommandType.path, + objectId: 109, paintId: 15, debugString: 'path444'), + DrawCommand(DrawCommandType.path, + objectId: 110, paintId: 40, debugString: 'path448'), + DrawCommand(DrawCommandType.path, + objectId: 111, paintId: 40, debugString: 'path452'), + DrawCommand(DrawCommandType.path, + objectId: 112, paintId: 40, debugString: 'path456'), + DrawCommand(DrawCommandType.path, + objectId: 113, paintId: 40, debugString: 'path460'), + DrawCommand(DrawCommandType.path, + objectId: 114, paintId: 15, debugString: 'path464'), + DrawCommand(DrawCommandType.path, + objectId: 115, paintId: 41, debugString: 'path468'), + DrawCommand(DrawCommandType.path, + objectId: 116, paintId: 31, debugString: 'path472'), + DrawCommand(DrawCommandType.path, + objectId: 117, paintId: 32, debugString: 'path476'), + DrawCommand(DrawCommandType.path, + objectId: 118, paintId: 15, debugString: 'path480'), + DrawCommand(DrawCommandType.path, + objectId: 119, paintId: 15, debugString: 'path484'), + DrawCommand(DrawCommandType.path, + objectId: 120, paintId: 15, debugString: 'path488'), + DrawCommand(DrawCommandType.path, + objectId: 121, paintId: 42, debugString: 'path492'), + DrawCommand(DrawCommandType.path, + objectId: 122, paintId: 43, debugString: 'path496'), + DrawCommand(DrawCommandType.path, + objectId: 123, paintId: 39, debugString: 'path500'), + DrawCommand(DrawCommandType.path, + objectId: 124, paintId: 14, debugString: 'path504'), + DrawCommand(DrawCommandType.path, + objectId: 125, paintId: 39, debugString: 'path508'), + DrawCommand(DrawCommandType.path, + objectId: 126, paintId: 15, debugString: 'path512'), + DrawCommand(DrawCommandType.path, + objectId: 127, paintId: 15, debugString: 'path516'), + DrawCommand(DrawCommandType.path, + objectId: 128, paintId: 15, debugString: 'path520'), + DrawCommand(DrawCommandType.path, + objectId: 129, paintId: 15, debugString: 'path524'), + DrawCommand(DrawCommandType.path, + objectId: 130, paintId: 15, debugString: 'path528'), + DrawCommand(DrawCommandType.path, + objectId: 131, paintId: 15, debugString: 'path532'), + DrawCommand(DrawCommandType.path, + objectId: 132, paintId: 15, debugString: 'path536'), + DrawCommand(DrawCommandType.path, + objectId: 133, paintId: 15, debugString: 'path540'), + DrawCommand(DrawCommandType.path, + objectId: 134, paintId: 15, debugString: 'path544'), + DrawCommand(DrawCommandType.path, + objectId: 135, paintId: 14, debugString: 'path548'), + DrawCommand(DrawCommandType.path, + objectId: 136, paintId: 14, debugString: 'path552'), + DrawCommand(DrawCommandType.path, + objectId: 137, paintId: 16, debugString: 'path556'), + DrawCommand(DrawCommandType.path, + objectId: 138, paintId: 15, debugString: 'path560'), + DrawCommand(DrawCommandType.path, + objectId: 139, paintId: 16, debugString: 'path564'), + DrawCommand(DrawCommandType.path, + objectId: 140, paintId: 15, debugString: 'path568'), + DrawCommand(DrawCommandType.path, + objectId: 141, paintId: 15, debugString: 'path572'), + DrawCommand(DrawCommandType.path, + objectId: 142, paintId: 15, debugString: 'path576'), + DrawCommand(DrawCommandType.path, + objectId: 143, paintId: 15, debugString: 'path580'), + DrawCommand(DrawCommandType.path, + objectId: 144, paintId: 15, debugString: 'path584'), + DrawCommand(DrawCommandType.path, + objectId: 145, paintId: 15, debugString: 'path588'), + DrawCommand(DrawCommandType.path, + objectId: 146, paintId: 15, debugString: 'path592'), + DrawCommand(DrawCommandType.path, + objectId: 147, paintId: 15, debugString: 'path596'), + DrawCommand(DrawCommandType.path, + objectId: 148, paintId: 15, debugString: 'path600'), + DrawCommand(DrawCommandType.path, + objectId: 149, paintId: 15, debugString: 'path604'), + DrawCommand(DrawCommandType.path, + objectId: 150, paintId: 15, debugString: 'path608'), + DrawCommand(DrawCommandType.path, + objectId: 151, paintId: 15, debugString: 'path612'), + DrawCommand(DrawCommandType.path, + objectId: 152, paintId: 15, debugString: 'path616'), + DrawCommand(DrawCommandType.path, + objectId: 153, paintId: 15, debugString: 'path620'), + DrawCommand(DrawCommandType.path, + objectId: 154, paintId: 15, debugString: 'path624'), + DrawCommand(DrawCommandType.path, + objectId: 155, paintId: 15, debugString: 'path628'), + DrawCommand(DrawCommandType.path, + objectId: 156, paintId: 15, debugString: 'path632'), + DrawCommand(DrawCommandType.path, + objectId: 157, paintId: 39, debugString: 'path636'), + DrawCommand(DrawCommandType.path, + objectId: 158, paintId: 39, debugString: 'path640'), + DrawCommand(DrawCommandType.path, + objectId: 159, paintId: 16, debugString: 'path644'), + DrawCommand(DrawCommandType.path, + objectId: 160, paintId: 15, debugString: 'path648'), + DrawCommand(DrawCommandType.path, + objectId: 161, paintId: 15, debugString: 'path652'), + DrawCommand(DrawCommandType.path, + objectId: 162, paintId: 44, debugString: 'path656'), + DrawCommand(DrawCommandType.path, + objectId: 163, paintId: 44, debugString: 'path660'), + DrawCommand(DrawCommandType.path, + objectId: 164, paintId: 44, debugString: 'path664'), + DrawCommand(DrawCommandType.path, + objectId: 165, paintId: 44, debugString: 'path668'), + DrawCommand(DrawCommandType.path, + objectId: 166, paintId: 44, debugString: 'path672'), + DrawCommand(DrawCommandType.path, + objectId: 167, paintId: 44, debugString: 'path676'), + DrawCommand(DrawCommandType.path, + objectId: 168, paintId: 44, debugString: 'path680'), + DrawCommand(DrawCommandType.path, + objectId: 169, paintId: 44, debugString: 'path684'), + DrawCommand(DrawCommandType.path, + objectId: 170, paintId: 16, debugString: 'path688'), + DrawCommand(DrawCommandType.path, + objectId: 171, paintId: 15, debugString: 'path692'), + DrawCommand(DrawCommandType.path, + objectId: 172, paintId: 15, debugString: 'path696'), + DrawCommand(DrawCommandType.path, + objectId: 173, paintId: 15, debugString: 'path700'), + DrawCommand(DrawCommandType.path, + objectId: 174, paintId: 15, debugString: 'path704'), + DrawCommand(DrawCommandType.path, + objectId: 175, paintId: 15, debugString: 'path708'), + DrawCommand(DrawCommandType.path, + objectId: 176, paintId: 15, debugString: 'path712'), + DrawCommand(DrawCommandType.path, + objectId: 177, paintId: 15, debugString: 'path716'), + DrawCommand(DrawCommandType.path, + objectId: 178, paintId: 15, debugString: 'path720'), + DrawCommand(DrawCommandType.path, + objectId: 179, paintId: 15, debugString: 'path724'), + DrawCommand(DrawCommandType.path, + objectId: 180, paintId: 15, debugString: 'path728'), + DrawCommand(DrawCommandType.path, + objectId: 181, paintId: 44, debugString: 'path732'), + DrawCommand(DrawCommandType.path, + objectId: 182, paintId: 15, debugString: 'path736'), + DrawCommand(DrawCommandType.path, + objectId: 183, paintId: 44, debugString: 'path740'), + DrawCommand(DrawCommandType.path, + objectId: 184, paintId: 44, debugString: 'path744'), + DrawCommand(DrawCommandType.path, + objectId: 185, paintId: 44, debugString: 'path748'), + DrawCommand(DrawCommandType.path, + objectId: 186, paintId: 44, debugString: 'path752'), + DrawCommand(DrawCommandType.path, + objectId: 187, paintId: 44, debugString: 'path756'), + DrawCommand(DrawCommandType.path, + objectId: 188, paintId: 44, debugString: 'path760'), + DrawCommand(DrawCommandType.path, + objectId: 189, paintId: 44, debugString: 'path764'), + DrawCommand(DrawCommandType.path, + objectId: 190, paintId: 44, debugString: 'path768'), + DrawCommand(DrawCommandType.path, + objectId: 191, paintId: 44, debugString: 'path772'), + DrawCommand(DrawCommandType.path, + objectId: 192, paintId: 44, debugString: 'path776'), + DrawCommand(DrawCommandType.path, + objectId: 193, paintId: 44, debugString: 'path780'), + DrawCommand(DrawCommandType.path, + objectId: 194, paintId: 44, debugString: 'path784'), + DrawCommand(DrawCommandType.path, + objectId: 195, paintId: 44, debugString: 'path788'), + DrawCommand(DrawCommandType.path, + objectId: 196, paintId: 44, debugString: 'path792'), + DrawCommand(DrawCommandType.path, + objectId: 197, paintId: 44, debugString: 'path796'), + DrawCommand(DrawCommandType.path, + objectId: 198, paintId: 44, debugString: 'path800'), + DrawCommand(DrawCommandType.path, + objectId: 199, paintId: 44, debugString: 'path804'), + DrawCommand(DrawCommandType.path, + objectId: 200, paintId: 44, debugString: 'path808'), + DrawCommand(DrawCommandType.path, + objectId: 201, paintId: 44, debugString: 'path812'), + DrawCommand(DrawCommandType.path, + objectId: 202, paintId: 44, debugString: 'path816'), + DrawCommand(DrawCommandType.path, + objectId: 203, paintId: 44, debugString: 'path820'), + DrawCommand(DrawCommandType.path, + objectId: 204, paintId: 44, debugString: 'path824'), + DrawCommand(DrawCommandType.path, + objectId: 205, paintId: 44, debugString: 'path828'), + DrawCommand(DrawCommandType.path, + objectId: 206, paintId: 44, debugString: 'path832'), + DrawCommand(DrawCommandType.path, + objectId: 207, paintId: 44, debugString: 'path836'), + DrawCommand(DrawCommandType.path, + objectId: 208, paintId: 15, debugString: 'path840'), + DrawCommand(DrawCommandType.path, + objectId: 209, paintId: 15, debugString: 'path844'), + DrawCommand(DrawCommandType.path, + objectId: 210, paintId: 15, debugString: 'path848'), + DrawCommand(DrawCommandType.path, + objectId: 211, paintId: 15, debugString: 'path852'), + DrawCommand(DrawCommandType.path, + objectId: 212, paintId: 15, debugString: 'path856'), + DrawCommand(DrawCommandType.path, + objectId: 213, paintId: 15, debugString: 'path860'), + DrawCommand(DrawCommandType.path, + objectId: 214, paintId: 16, debugString: 'path864'), + DrawCommand(DrawCommandType.path, + objectId: 215, paintId: 16, debugString: 'path868'), + DrawCommand(DrawCommandType.path, + objectId: 216, paintId: 16, debugString: 'path872'), + DrawCommand(DrawCommandType.path, + objectId: 217, paintId: 16, debugString: 'path876'), + DrawCommand(DrawCommandType.path, + objectId: 218, paintId: 16, debugString: 'path880'), + DrawCommand(DrawCommandType.path, + objectId: 219, paintId: 16, debugString: 'path884'), + DrawCommand(DrawCommandType.path, + objectId: 220, paintId: 16, debugString: 'path888'), + DrawCommand(DrawCommandType.path, + objectId: 221, paintId: 16, debugString: 'path892'), + DrawCommand(DrawCommandType.path, + objectId: 222, paintId: 16, debugString: 'path896'), + DrawCommand(DrawCommandType.path, + objectId: 223, paintId: 16, debugString: 'path900'), + DrawCommand(DrawCommandType.path, + objectId: 224, paintId: 16, debugString: 'path904'), + DrawCommand(DrawCommandType.path, + objectId: 225, paintId: 16, debugString: 'path908'), + DrawCommand(DrawCommandType.path, + objectId: 226, paintId: 16, debugString: 'path912'), + DrawCommand(DrawCommandType.path, + objectId: 227, paintId: 16, debugString: 'path916'), + DrawCommand(DrawCommandType.path, + objectId: 228, paintId: 16, debugString: 'path920'), + DrawCommand(DrawCommandType.path, + objectId: 229, paintId: 16, debugString: 'path924'), + DrawCommand(DrawCommandType.path, + objectId: 230, paintId: 16, debugString: 'path928'), + DrawCommand(DrawCommandType.path, + objectId: 231, paintId: 16, debugString: 'path932'), + DrawCommand(DrawCommandType.path, + objectId: 232, paintId: 16, debugString: 'path936'), + DrawCommand(DrawCommandType.path, + objectId: 233, paintId: 16, debugString: 'path940'), + DrawCommand(DrawCommandType.path, + objectId: 234, paintId: 16, debugString: 'path944'), + DrawCommand(DrawCommandType.path, + objectId: 235, paintId: 16, debugString: 'path948'), + DrawCommand(DrawCommandType.path, + objectId: 236, paintId: 45, debugString: 'path952'), + DrawCommand(DrawCommandType.path, + objectId: 237, paintId: 45, debugString: 'path956'), + DrawCommand(DrawCommandType.path, + objectId: 238, paintId: 45, debugString: 'path960'), + DrawCommand(DrawCommandType.path, + objectId: 239, paintId: 45, debugString: 'path964'), + ], + ); + }); +} + +const List ghostScriptTigerPaints = [ + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.303691181256463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.303691181256463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.303691181256463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.303691181256463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.303691181256463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.303691181256463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.303691181256463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.303691181256463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.303691181256463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.303691181256463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.303691181256463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.303691181256463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack), + fill: Fill(color: Color(0xffcc7226))), + Paint(fill: Fill(color: Color(0xffcc7226))), + Paint(fill: Fill(color: Color(0xffe87f3a))), + Paint(fill: Fill(color: Color(0xffea8c4d))), + Paint(fill: Fill(color: Color(0xffec9961))), + Paint(fill: Fill(color: Color(0xffeea575))), + Paint(fill: Fill(color: Color(0xfff1b288))), + Paint(fill: Fill(color: Color(0xfff3bf9c))), + Paint(fill: Fill(color: Color(0xfff5ccb0))), + Paint(fill: Fill(color: Color(0xfff8d8c4))), + Paint(fill: Fill(color: Color(0xfffae5d7))), + Paint(fill: Fill(color: Color(0xfffcf2eb))), + Paint(fill: Fill(color: Color(0xffffffff))), + Paint(fill: Fill()), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill()), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill()), + Paint(fill: Fill(color: Color(0xffe5668c))), + Paint(fill: Fill(color: Color(0xffb23259))), + Paint(fill: Fill(color: Color(0xffa5264c))), + Paint( + stroke: Stroke(color: Color.opaqueBlack), + fill: Fill(color: Color(0xffff727f))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.88282315), + fill: Fill(color: Color(0xffffffcc))), + Paint(fill: Fill(color: Color(0xffcc3f4c))), + Paint(stroke: Stroke(color: Color(0xffa51926), width: 3.5312926)), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.88282315), + fill: Fill(color: Color(0xffffffcc))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.88282315), + fill: Fill(color: Color(0xffffffcc))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.88282315), + fill: Fill(color: Color(0xffffffcc))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.88282315), + fill: Fill(color: Color(0xffffffcc))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.88282315), + fill: Fill(color: Color(0xffffffcc))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.88282315), + fill: Fill(color: Color(0xffffffcc))), + Paint(stroke: Stroke(color: Color(0xffa5264c), width: 3.5312926)), + Paint(stroke: Stroke(color: Color(0xffa5264c), width: 3.5312926)), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.88282315), + fill: Fill(color: Color(0xffffffcc))), + Paint(stroke: Stroke(color: Color(0xffa5264c), width: 3.5312926)), + Paint(stroke: Stroke(color: Color(0xffa5264c), width: 3.5312926)), + Paint(fill: Fill(color: Color(0xffb2b2b2))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.88282315), + fill: Fill(color: Color(0xffffffcc))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.88282315), + fill: Fill(color: Color(0xffffffcc))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.88282315), + fill: Fill(color: Color(0xffffffcc))), + Paint(fill: Fill()), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.88282315), + fill: Fill(color: Color(0xffffffcc))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.88282315), + fill: Fill(color: Color(0xffffffcc))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.88282315), + fill: Fill(color: Color(0xffffffcc))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.88282315), + fill: Fill(color: Color(0xffffffcc))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.88282315), + fill: Fill(color: Color(0xffffffcc))), + Paint(fill: Fill(color: Color(0xffe5e5b2))), + Paint(fill: Fill(color: Color(0xffe5e5b2))), + Paint(fill: Fill(color: Color(0xffcc7226))), + Paint(fill: Fill(color: Color(0xffea8e51))), + Paint(fill: Fill(color: Color(0xffefaa7c))), + Paint(fill: Fill(color: Color(0xfff4c6a8))), + Paint(fill: Fill(color: Color(0xfff9e2d3))), + Paint(fill: Fill(color: Color(0xffffffff))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill()), + Paint(fill: Fill(color: Color(0xff99cc32))), + Paint(fill: Fill(color: Color(0xff659900))), + Paint(fill: Fill(color: Color(0xffffffff))), + Paint(fill: Fill()), + Paint(fill: Fill(color: Color(0xffcc7226))), + Paint(fill: Fill(color: Color(0xffffffff))), + Paint(fill: Fill(color: Color(0xffeb955c))), + Paint(fill: Fill(color: Color(0xfff2b892))), + Paint(fill: Fill(color: Color(0xfff8dcc8))), + Paint(fill: Fill(color: Color(0xffffffff))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill()), + Paint(fill: Fill(color: Color(0xff99cc32))), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill(color: Color(0xff323232))), + Paint(fill: Fill(color: Color(0xff666666))), + Paint(fill: Fill(color: Color(0xff999999))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffffffff))), + Paint(fill: Fill(color: Color(0xff992600))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill(color: Color(0xffcc7226))), + Paint(fill: Fill(color: Color(0xffcc7226))), + Paint(fill: Fill(color: Color(0xffcc7226))), + Paint(fill: Fill(color: Color(0xffcc7226))), + Paint(fill: Fill(color: Color(0xffcc7226))), + Paint(fill: Fill(color: Color(0xffcc7226))), + Paint(fill: Fill()), + Paint(stroke: Stroke(color: Color(0xff4c0000), width: 3.5312926)), + Paint(stroke: Stroke(color: Color(0xff4c0000), width: 3.5312926)), + Paint(stroke: Stroke(color: Color(0xff4c0000), width: 3.5312926)), + Paint(stroke: Stroke(color: Color(0xff4c0000), width: 3.5312926)), + Paint(fill: Fill()), + Paint(fill: Fill(color: Color(0xff4c0000))), + Paint(fill: Fill(color: Color(0xff99cc32))), + Paint(fill: Fill(color: Color(0xff659900))), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill(color: Color(0xffe59999))), + Paint(fill: Fill(color: Color(0xffb26565))), + Paint(fill: Fill(color: Color(0xff992600))), + Paint(fill: Fill(color: Color(0xffffffff))), + Paint(fill: Fill(color: Color(0xff992600))), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill(color: Color(0xffffffff))), + Paint(fill: Fill(color: Color(0xffffffff))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill()), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill(color: Color(0xff992600))), + Paint(fill: Fill(color: Color(0xff992600))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint(fill: Fill()), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint( + stroke: Stroke(color: Color.opaqueBlack, width: 0.17656463), + fill: Fill(color: Color(0xffffffff))), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill()), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(fill: Fill(color: Color(0xffcccccc))), + Paint(stroke: Stroke(color: Color.opaqueBlack)), + Paint(stroke: Stroke(color: Color.opaqueBlack)), + Paint(stroke: Stroke(color: Color.opaqueBlack)), + Paint(stroke: Stroke(color: Color.opaqueBlack)) +]; + +final List ghostScriptTigerPaths = [ + Path( + commands: const [ + MoveToCommand(108.96861750999997, 403.8269183955), + CubicToCommand(108.96861750999997, 403.8269183955, 109.14518213999997, + 407.17105248769997, 107.67969571099997, 407.137505208), + CubicToCommand(106.231865745, 407.1039579283, 77.18698410999997, + 322.2205120558, 40.93826557099999, 326.1808567067), + CubicToCommand(40.93826557099999, 326.1808567067, 72.331456785, + 313.1980594628, 108.96861751, 403.8269183955), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(115.20134894899999, 398.4893696306), + CubicToCommand(115.20134894899999, 398.4893696306, 114.230243484, + 401.6957833114, 112.87069583299998, 401.1678550677), + CubicToCommand(111.511148182, 400.6416924703, 113.064916926, + 310.9362665525, 77.646052148, 302.3305064863), + CubicToCommand(77.646052148, 302.3305064863, 111.58177403399998, + 300.8049880831, 115.20134894899999, 398.4893696306), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(163.73190315079998, 473.225646217), + CubicToCommand(163.73190315079998, 473.225646217, 166.62050049759995, + 474.920666665, 165.79064673659997, 476.121306149), + CubicToCommand(164.95902732929994, 477.30428917, 78.14043311199995, + 454.70401653, 61.437419113999965, 487.121282598), + CubicToCommand(61.437419113999965, 487.121282598, 67.93499749799997, + 453.768223991, 163.73190315079998, 473.225646217), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(158.77220269409997, 491.25289494000003), + CubicToCommand(158.77220269409997, 491.25289494000003, 162.04924222689996, + 491.95915346000004, 161.63608099269996, 493.354014037), + CubicToCommand(161.22468540479997, 494.748874614, 71.69582411699997, + 500.646133256, 66.06341241999996, 536.665317776), + CubicToCommand(66.06341241999996, 536.665317776, 61.71992252199999, + 502.976786372, 158.7722026941, 491.25289494000003), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(151.33706612479997, 481.506527364), + CubicToCommand(151.33706612479997, 481.506527364, 154.47638524619998, + 482.67185392199997, 153.86547162639997, 483.99608864699997), + CubicToCommand(153.25455800659998, 485.32032337199996, 63.82104161899997, + 478.09883000499997, 52.99762979999997, 512.899718578), + CubicToCommand(52.99762979999997, 512.899718578, 53.61560600499996, + 478.928683766, 151.33706612479997, 481.506527364), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(132.43405683699996, 449.354108241), + CubicToCommand(132.43405683699996, 449.354108241, 134.74705348999998, + 451.79070013499995, 133.61703985799997, 452.708836211), + CubicToCommand(132.48702622599995, 453.62697228700006, 55.257657064, + 407.97442155420003, 30.27376191899998, 434.54033578400004), + CubicToCommand(30.27376191899998, 434.54033578400004, 45.705510581, + 404.26479867790005, 132.43405683699996, 449.354108241), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(119.12108373499998, 456.752166238), + CubicToCommand(119.12108373499998, 456.752166238, 121.68127086999999, + 458.906254724, 120.67485247899998, 459.94798604100004), + CubicToCommand(119.65077762499999, 460.989717358, 37.74244576799998, + 424.3737443886, 15.936713962999931, 453.59165936100004), + CubicToCommand(15.936713962999931, 453.59165936100004, 27.837170024999978, + 421.76941609610003, 119.12108373499996, 456.75216623800003), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(114.53040335499998, 463.956003142), + CubicToCommand(114.53040335499998, 463.956003142, 117.35543743499994, + 465.721649442, 116.49027074799997, 466.904632463), + CubicToCommand(115.62510406099997, 468.06995902100005, 29.496877546999997, + 442.96246863500005, 11.875727472999927, 474.86769727600006), + CubicToCommand(11.875727472999927, 474.86769727600006, 19.326754858999948, + 441.72651622500007, 114.53040335499995, 463.956003142), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(133.47578815399999, 465.03304738500003), + CubicToCommand(133.47578815399999, 465.03304738500003, 135.45331201, + 467.734486224, 134.21735959999998, 468.511370596), + CubicToCommand(132.98140718999997, 469.270598505, 62.231959948999986, + 414.09768292260003, 34.05224500100002, 437.241774623), + CubicToCommand(34.05224500100002, 437.241774623, 53.24482028199998, + 409.1962487938, 133.47578815399999, 465.03304738500003), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(98.55130434, 413.917587), + CubicToCommand(98.55130434, 413.917587, 99.61069211999998, 417.09575034, + 98.19817508000003, 417.4488796), + CubicToCommand(96.78565804000004, 417.80200886, 46.28817386000003, + 343.64486426, 12.387764900000036, 357.06377614), + CubicToCommand(12.387764900000036, 357.06377614, 39.22558866000003, + 336.2291498, 98.55130434, 413.917587), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(99.78725674999998, 426.2400325277), + CubicToCommand(99.78725674999998, 426.2400325277, 101.49993366099997, + 429.1162703504, 100.19335539899998, 429.7642625425), + CubicToCommand(98.886777137, 430.41402038089996, 33.59317696299996, + 368.8918407037, 3.382968769999991, 389.30624322430003), + CubicToCommand(3.382968769999991, 389.30624322430003, 25.100418260000026, + 363.1746779843, 99.78725674999998, 426.2400325277), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(99.57537919399996, 433.957672505), + CubicToCommand(99.57537919399996, 433.957672505, 101.55290304999997, + 436.659111344, 100.31695063999996, 437.435995716), + CubicToCommand(99.08099822999998, 438.19522362500004, 28.331550988999993, + 383.0223080426, 0.15183604099996728, 406.1611028041), + CubicToCommand(0.15183604099996728, 406.1611028041, 19.344411321999985, + 378.1208739138, 99.57537919399996, 433.957672505), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(95.67330087099995, 436.97692767800004), + CubicToCommand(96.55612402099996, 447.659087793, 98.30411385799997, + 459.259383984, 101.37633841999997, 464.76820044), + CubicToCommand(101.37633841999997, 464.76820044, 95.02001173999994, + 486.66221456, 110.55769917999996, 509.96874572), + CubicToCommand(110.55769917999996, 509.96874572, 109.85144065999995, + 522.68139908, 112.67647473999997, 528.33146724), + CubicToCommand(112.67647473999997, 528.33146724, 119.73905993999998, + 543.1628961600001, 128.21416217999996, 544.5754132), + CubicToCommand(135.06486982399997, 545.723083295, 150.47366508409996, + 551.143617436, 167.88470324839997, 553.615522256), + CubicToCommand(167.88470324839997, 553.615522256, 198.13375565999996, + 578.47582216, 192.48368749999997, 601.0760948), + CubicToCommand(192.48368749999997, 601.0760948, 191.77742897999997, + 630.03269412, 185.42110229999997, 632.8577282), + CubicToCommand(185.42110229999997, 632.8577282, 205.90259937999997, + 613.0824896400001, 188.95239489999997, 642.74534748), + LineToCommand(181.18355117999997, 675.93949792), + CubicToCommand(181.18355117999997, 675.93949792, 226.38409645999997, + 637.80153784, 198.84001417999997, 670.2894297600001), + LineToCommand(181.18355117999997, 716.1962335600001), + CubicToCommand(181.18355117999997, 716.1962335600001, 215.79021865999997, + 683.7083416400001, 203.07756529999997, 698.5397705600001), + LineToCommand(197.42749713999996, 714.0774580000001), + CubicToCommand(197.42749713999996, 714.0774580000001, 273.70341729999996, + 666.0518786400002, 219.32151125999997, 718.31500912), + CubicToCommand(219.32151125999997, 718.31500912, 233.44668165999997, + 711.9586824400001, 241.21552537999997, 716.90249208), + CubicToCommand(241.21552537999997, 716.90249208, 253.22192021999996, + 714.7837165200001, 251.80940317999995, 717.6087506), + CubicToCommand(251.80940317999995, 717.6087506, 215.08396014, + 735.9714721199999, 208.72763345999994, 768.45936404), + CubicToCommand(208.72763345999994, 768.45936404, 223.55906237999994, + 750.80290104, 217.90899421999995, 769.87188108), + LineToCommand(218.61525273999996, 790.35337816), + CubicToCommand(218.61525273999996, 790.35337816, 225.67783793999996, + 752.2154180800001, 224.97157941999996, 818.60371896), + CubicToCommand(224.97157941999996, 818.60371896, 258.87198837999995, + 786.82208556, 238.39049129999995, 823.5475286000001), + LineToCommand(238.39049129999995, 853.2103864400001), + CubicToCommand(238.39049129999995, 853.2103864400001, 265.22831505999994, + 824.2537871200001, 253.92817873999996, 846.85405976), + CubicToCommand(253.92817873999996, 846.85405976, 271.58464174, + 831.31637232, 264.52205654, 858.15419608), + CubicToCommand(264.52205654, 858.15419608, 263.1095395, 876.5169175999999, + 270.87838322, 856.74167904), + CubicToCommand(270.87838322, 856.74167904, 299.12872402, 802.71290226, + 288.53484621999996, 848.9728353200001), + CubicToCommand(288.53484621999996, 848.9728353200001, 287.12232917999995, + 882.87324428, 295.59743141999996, 856.74167904), + CubicToCommand(295.59743141999996, 856.74167904, 296.30368993999997, + 875.1044005599999, 312.5476359, 887.81705392), + CubicToCommand(312.5476359, 887.81705392, 310.42886033999997, + 798.12222188, 333.02913298, 861.68548868), + LineToCommand(340.09171818, 890.642088), + CubicToCommand(340.09171818, 890.642088, 345.03552781999997, 874.39814204, + 344.32926929999996, 865.21678128), + LineToCommand(358.45443969999997, 879.34195168), + CubicToCommand(358.45443969999997, 879.34195168, 385.29226345999996, + 839.08521604, 379.64219529999997, 862.3917471999999), + CubicToCommand(379.64219529999997, 862.3917471999999, 366.22328342, + 890.642088, 369.0483175, 899.11719024), + CubicToCommand(369.0483175, 899.11719024, 398.71117533999995, 837.672699, + 400.8299509, 834.84766492), + CubicToCommand(400.8299509, 834.84766492, 397.29865829999994, + 909.71106804, 416.36763834, 846.14780124), + CubicToCommand(416.36763834, 846.14780124, 426.25525761999995, + 867.33555684, 421.31144797999997, 875.1044005599999), + CubicToCommand(421.31144797999997, 875.1044005599999, 435.43661837999997, + 860.9792301599999, 434.02410133999996, 855.329162), + CubicToCommand(434.02410133999996, 855.329162, 442.14607431999997, + 840.85086234, 447.08988395999995, 864.8636520199999), + CubicToCommand(447.08988395999995, 864.8636520199999, 450.2680473, + 881.4607272399999, 453.09308138, 875.8106590799999), + CubicToCommand(453.09308138, 875.8106590799999, 460.15566658, + 918.1861702799999, 462.27444214, 877.92943464), + CubicToCommand(462.27444214, 877.92943464, 465.09947622, + 853.9166449599999, 452.38682286, 833.4351478799999), + CubicToCommand(452.38682286, 833.4351478799999, 453.7993399, + 827.7850797199999, 448.85553026, 820.7224945199999), + CubicToCommand(448.85553026, 820.7224945199999, 472.86831994, 858.8604546, + 460.15566658, 808.00984116), + CubicToCommand(460.15566658, 808.00984116, 479.93267078630004, + 822.13501156, 482.0514463463, 822.13501156), + CubicToCommand(482.0514463463, 822.13501156, 458.03689102, 781.1720174, + 473.57457846, 789.64711964), + CubicToCommand(473.57457846, 789.64711964, 464.39321770000004, + 771.28439812, 496.1766167463, 792.47215372), + CubicToCommand(496.1766167463, 792.47215372, 467.9245103, 764.22181292, + 499.00165082629997, 781.1720174000001), + CubicToCommand(499.00165082629997, 781.1720174000001, 513.12505558, + 792.47215372, 499.70790934629997, 774.81569072), + CubicToCommand(499.70790934629997, 774.81569072, 474.28083698, + 746.56534992, 513.12505558, 778.34698332), + CubicToCommand(513.12505558, 778.34698332, 533.60655266, 807.30358264, + 535.0190697, 812.24739228), + CubicToCommand(535.0190697, 812.24739228, 517.3626067, 760.69052032, + 509.59376298, 755.7467106800001), + CubicToCommand(509.59376298, 755.7467106800001, 524.4251919000001, + 691.47718536, 597.16981946, 719.02126764), + CubicToCommand(597.16981946, 719.02126764, 609.1762143000001, 749.390384, + 616.94505802, 716.90249208), + CubicToCommand(616.94505802, 716.90249208, 639.54533066, 705.60235576, + 659.3205692199999, 754.3341936400001), + CubicToCommand(659.3205692199999, 754.3341936400001, 666.38315442, + 730.32140396, 664.97063738, 725.3775943200001), + CubicToCommand(664.97063738, 725.3775943200001, 676.97703222, + 727.4963698800001, 675.56451518, 725.3775943200001), + CubicToCommand(675.56451518, 725.3775943200001, 698.87104634, + 733.14643804, 700.9898218999999, 731.7339210000001), + CubicToCommand(700.9898218999999, 731.7339210000001, 712.99621674, + 743.7403158400001, 713.70247526, 737.38398916), + CubicToCommand(713.70247526, 737.38398916, 729.9464212199999, + 742.3277988000001, 726.4151286199999, 735.97147212), + CubicToCommand(726.4151286199999, 735.97147212, 741.95281606, + 763.5155544000002, 742.6590745799999, 769.87188108), + LineToCommand(746.8966257, 745.15283288), + LineToCommand(750.4279182999999, 750.09664252), + CubicToCommand(750.4279182999999, 750.09664252, 753.2529523799999, + 736.67773064, 751.8404353399999, 734.55895508), + CubicToCommand(750.4279183, 732.44017952, 787.15336134, 746.56534992, + 795.6284635799999, 783.2907929600001), + LineToCommand(799.1597561799999, 798.12222188), + CubicToCommand(799.1597561799999, 798.12222188, 809.7536339799999, + 771.99065664, 806.9285998999999, 764.92807144), + CubicToCommand(806.9285998999999, 764.92807144, 816.1099606599998, + 766.3405884800001, 816.81621918, 774.1094322), + CubicToCommand(816.81621918, 774.1094322, 823.8788043799999, 733.14643804, + 815.40370214, 722.55256024), + CubicToCommand(815.40370214, 722.55256024, 823.1725458599999, 721.1400432, + 825.2913214199999, 727.4963698800001), + LineToCommand(825.2913214199999, 714.7837165200001), + CubicToCommand(825.2913214199999, 714.7837165200001, 838.0039747799999, + 716.1962335600001, 838.0039747799999, 711.9586824400001), + CubicToCommand(838.0039747799999, 711.9586824400001, 845.7728184999999, + 704.89609724, 849.3041110999999, 713.3711994800001), + CubicToCommand(849.3041110999999, 713.3711994800001, 827.4100969799999, + 651.22044972, 859.8979888999999, 685.1208586800001), + CubicToCommand(859.8979888999999, 685.1208586800001, 872.6106422599998, + 704.18983872, 866.2543155799999, 670.9956882800001), + CubicToCommand(859.8979889, 637.80153784, 852.8354036999999, 634.97650376, + 861.3105059399999, 634.27024524), + CubicToCommand(861.3105059399999, 634.27024524, 862.7230229799999, + 627.9139185600001, 859.19173038, 625.08888448), + CubicToCommand(855.6604377799999, 622.2638504, 861.3105059399999, + 625.08888448, 861.3105059399999, 625.08888448), + CubicToCommand(861.3105059399999, 625.08888448, 869.7856081799999, + 632.15146968, 860.60424742, 593.30725108), + CubicToCommand(860.60424742, 593.30725108, 871.9043837399998, + 596.13228516, 850.7166281399999, 544.5754132000001), + CubicToCommand(850.7166281399999, 544.5754132000001, 855.6604377799999, + 540.33786208, 848.5978525799999, 525.50643316), + CubicToCommand(848.5978525799999, 525.50643316, 862.7230229799999, + 533.2752768800001, 867.6668326199999, 530.4502428000001), + CubicToCommand(867.6668326199999, 530.4502428000001, 866.9605741, + 527.62520872, 861.3105059399999, 520.5626235200001), + CubicToCommand(861.3105059399999, 520.5626235200001, 823.1725458599999, + 423.8052062800001, 859.19173038, 462.6494248800001), + CubicToCommand(859.19173038, 462.6494248800001, 880.114639035, + 486.57393224500004, 868.8145027149999, 446.31719660500005), + CubicToCommand(868.8145027149999, 446.31719660500005, 852.7294649219999, + 403.92579458830005, 854.106669036, 396.3405780835001), + LineToCommand(95.6733008709999, 436.9769276780001), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(854.106669036, 396.6937073435), + CubicToCommand(855.201369742, 397.0132893238, 859.103448065, + 398.997875765, 861.31050594, 401.91119216000004), + CubicToCommand(861.31050594, 401.91119216000004, 873.31690078, + 420.98017219999997, 864.13554002, 388.49228028000005), + CubicToCommand(864.13554002, 388.49228028000005, 847.8915940600001, + 337.64166684, 863.4292815000001, 357.4169054), + CubicToCommand(863.4292815000001, 357.4169054, 874.0231593000001, + 370.12955876, 868.37309114, 346.11676908000004), + CubicToCommand(861.557696422, 317.11249730990005, 857.0729548200002, + 305.86003344, 857.0729548200002, 305.86003344), + CubicToCommand(857.0729548200002, 305.86003344, 877.5544519000002, + 314.33513568, 830.2351310600002, 244.41554220000003), + LineToCommand(845.7728185000002, 250.77186888000003), + CubicToCommand(845.7728185000002, 250.77186888000003, 811.1661510200001, + 180.85227540000002, 773.0281909400002, 171.67091464000003), + LineToCommand(758.9030205400002, 161.07703684), + CubicToCommand(758.9030205400002, 161.07703684, 826.7038384600002, + 93.98247744000003, 804.1035658200003, 29.006693600000034), + CubicToCommand(804.1035658200003, 29.006693600000034, 792.0971709800002, + 19.825332840000016, 775.1469665000002, 36.069278800000035), + CubicToCommand(775.1469665000002, 36.069278800000035, 763.8468301800002, + 44.54438104000002, 753.2529523800002, 41.719346960000024), + CubicToCommand(753.2529523800002, 41.719346960000024, 698.8710463400002, + 43.83812252000004, 695.3397537400002, 43.83812252000004), + CubicToCommand(691.8084611400002, 43.83812252000004, 630.3639699000003, + -21.843919839999984, 514.5375726200002, 9.231455040000014), + CubicToCommand(514.5375726200002, 9.231455040000014, 505.35621186000014, + 12.762747640000015, 497.5891337863002, 10.643972080000054), + CubicToCommand(497.5891337863002, 10.643972080000054, 465.09947622000016, + -17.60636871999995, 378.9359367800002, 22.650366920000067), + CubicToCommand(378.9359367800002, 22.650366920000067, 361.2794737800002, + 26.181659520000068, 358.4544397000002, 26.181659520000068), + CubicToCommand(355.62940562000017, 26.181659520000068, 350.6855959800002, + 26.181659520000068, 336.5604255800002, 37.481795840000075), + CubicToCommand(322.4352551800002, 48.78193216000008, 321.7289966600002, + 50.19444920000009, 318.1977040600002, 53.01948328000006), + CubicToCommand(318.1977040600002, 53.01948328000006, 289.2411047400002, + 72.79472184000008, 280.7660025000002, 74.20723888000006), + CubicToCommand(280.7660025000002, 74.20723888000006, 260.2845054200002, + 85.50737520000007, 252.51566170000018, 103.16383820000004), + LineToCommand(246.15933502000019, 105.28261376000006), + CubicToCommand(246.15933502000019, 105.28261376000006, 243.3343009400002, + 117.99526712000008, 242.62804242000018, 120.11404268000007), + CubicToCommand(242.62804242000018, 120.11404268000007, 234.1529401800002, + 126.47036936000006, 232.7404231400002, 136.3579886400001), + CubicToCommand(232.7404231400002, 136.3579886400001, 217.20273570000018, + 146.95186644000006, 217.90899422000018, 154.72071016000007), + CubicToCommand(217.90899422000018, 154.72071016000007, 215.0839601400002, + 163.90207092000009, 213.6714431000002, 172.37717316000007), + CubicToCommand(213.6714431000002, 172.37717316000007, 200.9587897400002, + 180.85227540000005, 202.3713067800002, 185.7960850400001), + CubicToCommand(202.3713067800002, 185.7960850400001, 188.9523949000002, + 210.51513324000007, 191.0711704600002, 222.52152808000008), + CubicToCommand(191.0711704600002, 222.52152808000008, 179.77103414000018, + 221.81526956000008, 174.82722450000017, 226.05282068000008), + CubicToCommand(174.82722450000017, 226.05282068000008, 173.4147074600002, + 234.5279229200001, 170.58967338000016, 235.23418144000007), + CubicToCommand(170.58967338000016, 235.23418144000007, 165.64586374000018, + 237.35295700000006, 169.88341486000016, 244.41554220000006), + CubicToCommand(169.88341486000016, 244.41554220000006, 167.05838078000016, + 249.35935184000007, 166.35212226000016, 252.18438592000007), + CubicToCommand(166.35212226000016, 252.18438592000007, 167.76463930000014, + 257.12819556000005, 159.99579558000016, 267.0158148400001), + CubicToCommand(159.99579558000016, 267.0158148400001, 148.69565926000016, + 300.20996528000006, 152.22695186000016, 309.3913260400001), + CubicToCommand(152.22695186000016, 309.3913260400001, 152.93321038000016, + 317.8664282800001, 147.98940074000015, 320.69146236000006), + CubicToCommand(147.98940074000015, 320.69146236000006, 141.63307406000015, + 319.98520384000005, 156.46450298000013, 341.17295944000006), + CubicToCommand(156.46450298000013, 341.17295944000006, 157.87702002000015, + 343.2917350000001, 152.22695186000013, 347.52928612000005), + CubicToCommand(152.22695186000013, 347.52928612000005, 121.85783550000014, + 353.8856128000001, 117.62028438000013, 382.84221212000006), + CubicToCommand(117.62028438000013, 382.84221212000006, 93.60749470000013, + 408.9737773600001, 93.60749470000013, 418.15513812000006), + CubicToCommand(93.60749470000013, 422.2249528415001, 94.08421920100014, + 427.78144174760007, 95.32017161100012, 435.9175398980001), + CubicToCommand(95.32017161100012, 435.9175398980001, 94.31375322000014, + 450.6430300400001, 143.04559110000014, 452.0555470800001), + CubicToCommand(191.7774289800001, 453.46806412000007, 854.1066690360002, + 396.6937073435, 854.1066690360002, 396.6937073435), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(120.79844771999998, 436.16473038000004), + CubicToCommand(76.65729022, 366.59826616, 102.08259694, 466.18071748, + 102.08259694, 466.18071748), + CubicToCommand(117.62028437999999, 526.9189502, 346.44804486, + 460.53064931999995, 346.44804486, 460.53064931999995), + CubicToCommand(346.44804486, 460.53064931999995, 644.4891403, + 406.85500179999997, 664.2643788600001, 399.7924166), + CubicToCommand(684.03961742, 392.72983139999997, 852.12914518, + 404.02996772, 852.12914518, 404.02996772), + LineToCommand(842.2415258999999, 374.36710988000004), + CubicToCommand(727.8276456599999, 292.44112156, 693.9272367, + 333.40411572000005, 669.91444702, 326.34153052), + CubicToCommand(645.9016573399999, 319.27894532000005, 650.13920846, + 336.2291498, 644.4891402999999, 337.64166684), + CubicToCommand(638.8390721399999, 339.05418388, 569.62573718, + 295.26615564, 558.3256008599999, 296.67867268000003), + CubicToCommand(547.0254645399999, 298.09118972, 502.28398729799994, + 256.1553244487, 528.66274302, 312.21636012), + CubicToCommand(556.9130838199999, 372.24833432, 425.54899909999995, + 381.42969508, 395.88614125999993, 361.65445652), + CubicToCommand(366.22328342, 341.87921796, 408.59879462, + 394.14234844000003, 408.59879462, 394.14234844000003), + CubicToCommand(441.08668653999996, 429.45527444000004, 380.34845382, + 399.7924166, 380.34845382, 399.7924166), + CubicToCommand(319.6102211, 377.19214396000007, 277.2347099, + 422.39268924000004, 271.58464173999994, 423.80520628), + CubicToCommand(265.93457357999995, 425.21772332, 257.45947133999994, + 430.86779148000005, 256.0469542999999, 419.56765516), + CubicToCommand(254.63443725999994, 408.26751884, 241.37443354699997, + 378.7794599837, 185.42110229999994, 425.21772332), + CubicToCommand(150.10817629999994, 454.5274519, 125.74225735999997, + 415.6832333, 125.74225735999997, 415.6832333), + LineToCommand(120.79844771999996, 436.16473038000004), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(560.6385975129999, 299.7614911198), + CubicToCommand(549.338461193, 301.1740081598, 504.544014562, + 259.25933064410003, 530.9757396729999, 315.2991785598), + CubicToCommand(560.285468253, 377.4499283198, 427.861995753, + 384.5125135198, 398.19913791299996, 364.7372749598), + CubicToCommand(368.53451442669996, 344.9620363998, 410.91179127299995, + 397.2251668798, 410.91179127299995, 397.2251668798), + CubicToCommand(443.39968319299993, 432.545155465, 382.65968482669996, + 402.87523503980003, 382.65968482669996, 402.87523503980003), + CubicToCommand(321.9214521067, 380.2749623998, 279.54594090669997, + 425.4755076798, 273.8958727467, 426.8880247198), + CubicToCommand(268.24580458669993, 428.3005417598, 259.7707023467, + 433.957672505, 258.35818530669997, 422.65047359979997), + CubicToCommand(256.94566826669995, 411.3503372798, 243.91696421899994, + 382.15714135559995, 187.73233330669996, 428.3005417598), + CubicToCommand(150.23706847989993, 458.92391118699993, 126.41320295399996, + 421.0455011131, 126.41320295399996, 421.0455011131), + LineToCommand(120.76313479399994, 438.901482145), + CubicToCommand(76.62197729399998, 368.6216968198, 103.23026703499997, + 471.583595158, 103.23026703499997, 471.583595158), + CubicToCommand(118.78561093799996, 532.321827878, 348.76104151299995, + 463.620530345, 348.76104151299995, 463.620530345), + CubicToCommand(348.76104151299995, 463.620530345, 646.802136953, + 409.9378202398, 666.5773755129999, 402.8752350398), + CubicToCommand(686.3526140729999, 395.8126498398, 852.906029552, + 406.98389397989996, 852.906029552, 406.98389397989996), + LineToCommand(843.142005513, 376.4223221732), + CubicToCommand(728.7281252729999, 294.4963338532, 696.240233353, + 336.4869341598, 672.2274436729999, 329.4243489598), + CubicToCommand(648.214653993, 322.3617637598, 652.452205113, + 339.31196823979997, 646.802136953, 340.7244852798), + CubicToCommand(641.1520687929999, 342.1370023198, 571.9387338329999, + 298.3489740798, 560.6385975129999, 299.7614911198), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(562.951594166, 302.8425439133), + CubicToCommand(551.651457846, 304.2550609533, 507.96936838399995, + 261.8283460106, 533.2887363259999, 318.3802313533), + CubicToCommand(561.892206386, 382.2983930596, 430.17322675969996, + 387.5953319596, 400.5103689197, 367.8200933996), + CubicToCommand(370.8475110797, 348.0448548396, 413.2230222797, + 400.3079853196, 413.2230222797, 400.3079853196), + CubicToCommand(445.7109141997, 435.617380027, 384.9726814797, + 405.95805347960004, 384.9726814797, 405.95805347960004), + CubicToCommand(324.2344487597, 383.3577808396, 281.85717191339995, + 428.5583261196, 276.20710375339996, 429.9708431596), + CubicToCommand(270.5570355934, 431.3833601996, 262.0819333534, + 437.029897067, 260.6694163134, 425.7332920396), + CubicToCommand(259.2568992734, 414.4331557196, 246.459494891, + 385.5348227275, 190.0435643134, 431.3833601996), + CubicToCommand(150.3641950135, 463.320370474, 127.084148548, + 426.4077689262, 127.084148548, 426.4077689262), + LineToCommand(120.727821868, 441.62057744699996), + CubicToCommand(78.70543992799998, 372.7639030396, 104.395593593, + 476.968816373, 104.395593593, 476.968816373), + CubicToCommand(119.93328103299999, 537.707049093, 351.07403816600004, + 466.692754907, 351.07403816600004, 466.692754907), + CubicToCommand(351.07403816600004, 466.692754907, 649.115133606, + 413.0206386796, 668.890372166, 405.9580534796), + CubicToCommand(688.6656107260001, 398.8954682796, 853.665257461, + 409.9378202398, 853.665257461, 409.9378202398), + LineToCommand(844.0424851260001, 378.4775344664), + CubicToCommand(729.628604886, 296.5515461464, 698.553230006, + 339.5679869533, 674.5404403260001, 332.5054017533), + CubicToCommand(650.527650646, 325.4428165533, 654.765201766, + 342.3930210333, 649.115133606, 343.8073037196), + CubicToCommand(643.465065446, 345.2198207596, 574.251730486, + 301.4300268733, 562.9515941660001, 302.8425439133), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(565.264590819, 305.9253623531), + CubicToCommand(553.964454499, 307.3378793931, 510.30002149999996, + 264.9058675115, 535.601732979, 321.4630497931), + CubicToCommand(565.264590819, 387.7736622359, 431.54160264219996, + 390.0495803166, 402.8215999264, 370.9011461931), + CubicToCommand(373.15874208639997, 351.1259076331, 415.5342532864, + 403.3890381131, 415.5342532864, 403.3890381131), + CubicToCommand(448.0221452064, 438.70726105200004, 387.28391248639997, + 409.03910627310006, 387.28391248639997, 409.03910627310006), + CubicToCommand(326.5456797664, 386.4388336331, 284.1701685664, + 431.644675852, 278.5201004064, 433.057192892), + CubicToCommand(272.8700322464, 434.469709932, 264.3949300064, + 440.11977809200005, 262.9824129664, 428.8143448331), + CubicToCommand(261.56989592639997, 417.5142085131, 249.00379120929995, + 388.91426974570004, 192.35479532009995, 434.469709932), + CubicToCommand(150.49308719339996, 467.716829761, 127.75509414199996, + 431.768271093, 127.75509414199996, 431.768271093), + LineToCommand(120.69250894199996, 444.35732921199997), + CubicToCommand(82.20141960199996, 379.3762484331, 105.54326368799997, + 482.354037588, 105.54326368799997, 482.354037588), + CubicToCommand(121.08095112799995, 543.092270308, 353.38703481899995, + 469.78263593199995, 353.38703481899995, 469.78263593199995), + CubicToCommand(353.38703481899995, 469.78263593199995, 651.428130259, + 416.1016914731, 671.2033688189999, 409.0391062731), + CubicToCommand(690.9786073789999, 401.9765210731, 854.4421418329999, + 412.8917464997, 854.4421418329999, 412.8917464997), + LineToCommand(844.9429647389999, 380.5327467596), + CubicToCommand(730.529084499, 298.60499279329997, 700.866226659, + 342.6508053931, 676.853436979, 335.5882201931), + CubicToCommand(652.840647299, 328.5256349931, 657.078198419, + 345.4758394731, 651.428130259, 346.8883565131), + CubicToCommand(645.778062099, 348.3008735531, 576.564727139, + 304.5128453131, 565.264590819, 305.9253623531), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(567.577587472, 309.0081807929), + CubicToCommand(556.2774511519999, 310.42069783290003, 513.495841303, + 267.5967124727, 537.914729632, 324.5458682329), + CubicToCommand(567.577587472, 393.75920319290003, 434.7956887731, + 393.75920319290003, 405.13283093309997, 373.9839646329), + CubicToCommand(375.46997309309995, 354.2087260729, 417.84548429309996, + 406.4718565529, 417.84548429309996, 406.4718565529), + CubicToCommand(450.3333762131, 441.779485614, 389.59514349309995, + 412.12192471289995, 389.59514349309995, 412.12192471289995), + CubicToCommand(328.85691077309997, 389.5216520729, 286.48139957309996, + 434.71690041399995, 280.8313314131, 436.12941745399996), + CubicToCommand(275.1812632531, 437.541934494, 266.7061610131, + 443.19200265399996, 265.29364397309996, 431.89186633399993), + CubicToCommand(263.88112693309995, 420.59702695289997, 251.5480875276, + 392.2919511176, 194.66779197309998, 437.541934494), + CubicToCommand(150.62197937329998, 472.11328904799996, 128.44369619899996, + 437.135835845, 128.44369619899996, 437.135835845), + LineToCommand(120.67485247899995, 447.076424514), + CubicToCommand(85.71505573899992, 385.6354645665999, 106.70859024599994, + 487.75691526599996, 106.70859024599994, 487.75691526599996), + CubicToCommand(122.24627768599996, 548.495147986, 355.700031472, + 472.8548604939999, 355.700031472, 472.8548604939999), + CubicToCommand(355.700031472, 472.8548604939999, 653.741126912, + 419.18450991289995, 673.516365472, 412.12192471289995), + CubicToCommand(693.2916040319999, 405.05933951289995, 855.219026205, + 415.84567275959995, 855.219026205, 415.84567275959995), + LineToCommand(845.843444352, 382.58619340649994), + CubicToCommand(731.429564112, 300.66020508649996, 703.179223312, + 345.7336238329, 679.166433632, 338.6710386328999), + CubicToCommand(655.153643952, 331.6084534329, 659.3911950720001, + 348.55865791289995, 653.741126912, 349.97117495289996), + CubicToCommand(648.091058752, 351.3836919928999, 578.877723792, + 307.59566375289995, 567.577587472, 309.00818079289996), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(569.890584125, 312.08923358640004), + CubicToCommand(558.5904478049999, 313.5017506264, 512.736613394, + 272.0955792451, 540.227726285, 327.6269210264), + CubicToCommand(574.128135245, 396.1339974664, 437.10691977979997, + 396.84025598640005, 407.4440619398, 377.0650174264), + CubicToCommand(377.7812040998, 357.2897788664, 420.1567152998, + 409.5529093464, 420.1567152998, 409.5529093464), + CubicToCommand(452.6446072198, 444.86936663899996, 391.9063744998, + 415.2029775064, 391.9063744998, 415.2029775064), + CubicToCommand(331.1681417798, 392.6027048664, 288.7926305798, + 437.806781439, 283.1425624198, 439.21929847900003), + CubicToCommand(277.49249425979997, 440.631815519, 269.0173920198, + 446.281883679, 267.6048749798, 434.981747359), + CubicToCommand(266.1923579398, 423.6780797464, 254.0906181996, + 395.66963248950003, 196.9790229798, 440.631815519), + CubicToCommand(150.75087155319997, 476.527404798, 129.114641793, + 442.485744134, 129.114641793, 442.485744134), + LineToCommand(120.63953955299999, 449.813176279), + CubicToCommand(88.85790615299999, 391.1901878264, 107.85626034100002, + 493.142136481, 107.85626034100002, 493.142136481), + CubicToCommand(123.39394778100001, 553.880369201, 358.013028125, + 475.944741519, 358.013028125, 475.944741519), + CubicToCommand(358.013028125, 475.944741519, 656.054123565, + 422.26556270640003, 675.829362125, 415.20297750640003), + CubicToCommand(695.6046006849999, 408.14039230640003, 855.978254114, + 418.79783337320004, 855.978254114, 418.79783337320004), + LineToCommand(846.743923965, 384.64140569970004), + CubicToCommand(732.330043725, 302.71541737970006, 705.492219965, + 348.8146766264, 681.479430285, 341.75209142640006), + CubicToCommand(657.4666406050001, 334.6895062264, 661.7041917250001, + 351.6397107064, 656.054123565, 353.05222774640004), + CubicToCommand(650.404055405, 354.46474478640005, 581.190720445, + 310.67671654640003, 569.890584125, 312.08923358640004), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(572.203580778, 315.1702863799), + CubicToCommand(560.903444458, 316.5828034199, 514.3786644529999, + 275.5138704819, 542.540722938, 330.7079738199), + CubicToCommand(578.559907458, 401.33559146619996, 439.41815078649995, + 399.92307442620006, 409.7552929465, 380.1478358662), + CubicToCommand(380.0924351065, 360.3725973062, 422.4679463065, + 412.63572778620005, 422.4679463065, 412.63572778620005), + CubicToCommand(454.95583822649996, 447.941591201, 394.2176055065, + 418.2857959462, 394.2176055065, 418.2857959462), + CubicToCommand(333.4793727865, 395.6855233062, 291.1038615865, + 440.879006001, 285.4537934265, 442.291523041), + CubicToCommand(279.8037252665, 443.704040081, 271.3286230265, + 449.354108241, 269.9161059865, 438.05397192099997), + CubicToCommand(268.5035889465, 426.7608981862, 256.6331488716, + 399.04731386139997, 199.29025398649998, 443.704040081), + CubicToCommand(150.87799808679998, 480.923864085, 129.785587387, + 447.85330888600004, 129.785587387, 447.85330888600004), + LineToCommand(120.60422662699997, 452.53227158100003), + CubicToCommand(92.353885827, 399.21681590620005, 109.02158689899997, + 498.545014159, 109.02158689899997, 498.545014159), + CubicToCommand(124.55927433899998, 559.283246879, 360.308368315, + 479.016966081, 360.308368315, 479.016966081), + CubicToCommand(360.308368315, 479.016966081, 658.349463755, + 425.34838114620004, 678.1247023149999, 418.2857959462), + CubicToCommand(697.899940875, 411.22321074620004, 856.7374820230001, + 421.7517596331, 856.7374820230001, 421.7517596331), + LineToCommand(847.626747115, 386.6966179929), + CubicToCommand(733.2128668749999, 304.7706296729, 707.7875601549999, + 351.8974950662, 683.774770475, 344.8349098662), + CubicToCommand(659.761980795, 337.7705590199, 663.999531915, + 354.72252914620003, 658.349463755, 356.1350461862), + CubicToCommand(652.6993955949999, 357.5475632262, 583.486060635, + 313.7577693399, 572.185924315, 315.1702863799), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(574.498920968, 318.2531048197), + CubicToCommand(563.198784648, 319.6656218597, 514.749450176, + 279.6295920072, 544.836063128, 333.7907922597), + CubicToCommand(583.680281728, 403.7103857397, 441.7293817932, + 403.0041272197, 412.0665239532, 383.22888865970003), + CubicToCommand(382.4036661132, 363.4536500997, 424.7791773132, + 415.7167805797, 424.7791773132, 415.7167805797), + CubicToCommand(457.2670692332, 451.031472226, 396.5288365132, + 421.3668487397, 396.5288365132, 421.3668487397), + CubicToCommand(335.79060379320003, 398.76657609970005, 293.41509259320003, + 443.96888702600006, 287.7650244332, 445.381404066), + CubicToCommand(282.1149562732, 446.793921106, 273.6398540332, + 452.443989266, 272.2273369932, 441.14385294600004), + CubicToCommand(270.8148199532, 429.8419509797, 259.1774451899, + 402.4267608796, 201.60148499320002, 446.793921106), + CubicToCommand(151.0068902667, 485.32032337199996, 130.456532981, + 453.22087363800006, 130.456532981, 453.22087363800006), + LineToCommand(120.56891370100001, 455.26902334600004), + CubicToCommand(95.14360698100003, 405.1229027797, 110.16925699400002, + 503.93023537399995, 110.16925699400002, 503.93023537399995), + CubicToCommand(125.70694443400001, 564.668468094, 362.621364968, + 482.10684710600003, 362.621364968, 482.10684710600003), + CubicToCommand(362.621364968, 482.10684710600003, 660.662460408, + 428.42943393970006, 680.437698968, 421.3668487397), + CubicToCommand(700.212937528, 414.30426353969995, 857.532022858, + 424.705685893, 857.532022858, 424.705685893), + LineToCommand(848.527226728, 388.75006463980003), + CubicToCommand(734.1133464879999, 306.8240763198, 710.100556808, + 354.97854785970003, 686.087767128, 347.91596265969997), + CubicToCommand(662.074977448, 340.8533774597, 666.3125285680001, + 357.8035819397, 660.662460408, 359.2160989797), + CubicToCommand(655.012392248, 360.6286160197, 585.799057288, + 316.8405877797, 574.498920968, 318.2531048197), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(576.811917621, 321.3359232595), + CubicToCommand(565.5117813009999, 322.7484402995, 517.062446829, + 282.7106448007, 547.149059781, 336.8736106995), + CubicToCommand(585.993278381, 406.7932041795, 444.04237844619996, + 406.0869456595, 414.37952060619995, 386.3117070995), + CubicToCommand(384.7166627662, 366.5364685395, 427.0921739662, + 418.79959901949996, 427.0921739662, 418.79959901949996), + CubicToCommand(459.5800658862, 454.103696788, 398.8418331662, + 424.4496671795, 398.8418331662, 424.4496671795), + CubicToCommand(338.10183479989996, 401.8493945395, 295.72632359989996, + 447.041111588, 290.07625543989997, 448.453628628), + CubicToCommand(284.4261872799, 449.86614566799994, 275.95108503989997, + 455.516213828, 274.53856799989995, 444.216077508), + CubicToCommand(273.12605095989994, 432.915941188, 261.72174150819995, + 405.80444225149995, 203.91271599989997, 449.86614566799994), + CubicToCommand(151.13578244659996, 489.71678265899993, 131.14513503799995, + 458.570781927, 131.14513503799995, 458.570781927), + LineToCommand(120.55125723799995, 457.98811864799995), + CubicToCommand(96.52081109499994, 411.3821189132, 111.33458355199997, + 509.333113052, 111.33458355199997, 509.333113052), + CubicToCommand(126.87227099199995, 570.071345772, 364.93436162099994, + 485.179071668, 364.93436162099994, 485.179071668), + CubicToCommand(364.93436162099994, 485.179071668, 662.975457061, + 431.51225237949996, 682.750695621, 424.44966717949995), + CubicToCommand(702.5259341809999, 417.38708197949995, 858.291250767, + 427.65961215289997, 858.291250767, 427.65961215289997), + LineToCommand(849.445362804, 390.80527693299996), + CubicToCommand(735.013826101, 308.87928861299997, 712.413553461, + 358.0613662994999, 688.400763781, 350.9987810995), + CubicToCommand(664.387974101, 343.9361958994999, 668.6255252210001, + 360.88640037949995, 662.975457061, 362.29891741949996), + CubicToCommand(657.325388901, 363.71143445949997, 588.1120539409999, + 319.92340621949995, 576.811917621, 321.33592325949996), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(579.1249142739999, 324.416976053), + CubicToCommand(567.824777954, 325.829493093, 520.064045539, + 285.41914622490003, 549.462056434, 339.954663493), + CubicToCommand(588.306275034, 411.993032533, 446.35360945289995, + 409.167998453, 416.69075161289993, 389.392759893), + CubicToCommand(387.0278937729, 369.617521333, 429.4034049729, + 421.880651813, 429.4034049729, 421.880651813), + CubicToCommand(461.89129689289996, 457.193577813, 401.1530641729, + 427.53071997300003, 401.1530641729, 427.53071997300003), + CubicToCommand(340.4148314529, 404.93044733299996, 298.0393202529, + 450.130992613, 292.38925209289994, 451.543509653), + CubicToCommand(286.73741828659996, 452.956026693, 278.26231604659995, + 458.60609485299995, 276.84979900659994, 447.30595853299997), + CubicToCommand(275.4372819665999, 436.005822213, 264.26427218019995, + 409.1821236234, 206.22394700659993, 452.956026693), + CubicToCommand(151.26467462649995, 494.113241946, 131.81608063199994, + 463.938346679, 131.81608063199994, 463.938346679), + LineToCommand(120.51594431199993, 460.72487041299996), + CubicToCommand(97.56254241199994, 418.34935921299996, 112.48225364699994, + 514.7183342669999, 112.48225364699994, 514.7183342669999), + CubicToCommand(128.01994108699995, 575.456566987, 367.2473582739999, + 488.26895269299996, 367.2473582739999, 488.26895269299996), + CubicToCommand(367.2473582739999, 488.26895269299996, 665.288453714, + 434.593305173, 685.0636922739999, 427.530719973), + CubicToCommand(704.8389308339999, 420.468134773, 859.0681351389999, + 430.6135384127999, 859.0681351389999, 430.6135384127999), + LineToCommand(850.328185954, 392.86048922619995), + CubicToCommand(735.914305714, 310.93273525989997, 714.7265501139999, + 361.14241909299994, 690.7137604339999, 354.07983389299994), + CubicToCommand(666.700970754, 347.01724869299994, 670.9385218739999, + 363.96745317299997, 665.288453714, 365.379970213), + CubicToCommand(659.6383855539999, 366.79248725299993, 590.4250505939999, + 323.004459013, 579.1249142739999, 324.416976053), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(581.437910927, 327.4980288465), + CubicToCommand(570.137774607, 328.9105458865, 524.283940196, + 287.5167340293, 551.775053087, 343.0357162865), + CubicToCommand(589.2067546469999, 418.60714357280006, 448.66484045959993, + 412.2508168928, 419.00198261959997, 392.4755783328), + CubicToCommand(389.33912477959996, 372.7003397728, 431.71463597959996, + 424.9634702528, 431.71463597959996, 424.9634702528), + CubicToCommand(464.2025278996, 460.283458838, 403.46429517959996, + 430.61353841280004, 403.46429517959996, 430.61353841280004), + CubicToCommand(342.7260624596, 408.0132657728, 300.35055125959997, + 453.22087363800006, 294.7004830996, 454.633390678), + CubicToCommand(289.05041493959993, 456.04590771799997, 280.5753126996, + 461.695975878, 279.16279565959996, 450.39583955800003), + CubicToCommand(277.75027861959995, 439.095703238, 266.80856849849994, + 412.56157064160004, 208.53694365959996, 456.04590771799997), + CubicToCommand(151.39180116009993, 498.509701233, 132.48702622599995, + 469.28825496800005, 132.48702622599995, 469.28825496800005), + LineToCommand(120.48063138599994, 463.46162217799997), + CubicToCommand(97.88035874599996, 422.49156543280003, 113.64758020499994, + 520.121211945, 113.64758020499994, 520.121211945), + CubicToCommand(129.18526764499993, 580.8594446650001, 369.56035492699993, + 491.358833718, 369.56035492699993, 491.358833718), + CubicToCommand(369.56035492699993, 491.358833718, 667.6014503669999, + 437.68318619800004, 687.3766889269999, 430.61353841280004), + CubicToCommand(707.151927487, 423.55095321280004, 859.8273630479999, + 433.56923031900004, 859.8273630479999, 433.56923031900004), + LineToCommand(851.2286655669999, 394.91393587310006), + CubicToCommand(736.814785327, 312.98794755310007, 717.0395467669999, + 364.22523753280007, 693.026757087, 357.16265233280006), + CubicToCommand(669.0139674069999, 350.0983014865001, 673.2515185269999, + 367.05027161280003, 667.6014503669999, 368.46278865280004), + CubicToCommand(661.9513822069998, 369.8753056928001, 592.7380472469999, + 326.08551180650005, 581.4379109269998, 327.49802884650006), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(120.44531845999998, 466.18071748), + CubicToCommand(97.84504582, 427.33649888, 114.79525029999996, + 525.50643316, 114.79525029999996, 525.50643316), + CubicToCommand(130.33293773999998, 586.24466588, 371.87335157999996, + 494.43105828, 371.87335157999996, 494.43105828), + CubicToCommand(371.87335157999996, 494.43105828, 669.91444702, + 440.75541076, 689.68968558, 433.69282555999996), + CubicToCommand(709.46492414, 426.63024036, 860.60424742, 436.51785964, + 860.60424742, 436.51785964), + LineToCommand(852.1291451799999, 396.96738252), + CubicToCommand(737.7152649399999, 315.04139419999996, 719.35254342, + 367.30452468, 695.3397537399999, 360.24193948), + CubicToCommand(671.3269640599999, 353.17935428, 675.56451518, + 370.12955875999995, 669.9144470199999, 371.54207579999996), + CubicToCommand(664.2643788599999, 372.95459284000003, 595.0510438999999, + 329.1665646, 583.7509075799999, 330.57908163999997), + CubicToCommand(572.45077126, 331.99159868, 527.9211715739999, + 289.95685721589996, 554.0880497399999, 346.11676908), + CubicToCommand(593.338366989, 430.3504571141, 446.8091461982999, + 412.5527424101, 421.3114479799999, 395.55486548), + CubicToCommand(391.6485901399999, 375.77962691999994, 434.0241013399999, + 428.0427573999999, 434.0241013399999, 428.0427573999999), + CubicToCommand(466.51199325999994, 463.3556834, 405.7737605399999, + 433.69282555999996, 405.7737605399999, 433.69282555999996), + CubicToCommand(345.0355278199999, 411.09255292, 302.6600166199999, + 456.2930981999999, 297.0099484599999, 457.70561523999993), + CubicToCommand(291.3598802999999, 459.11813227999994, 282.8847780599999, + 464.76820044, 281.4722610199999, 453.46806411999995), + CubicToCommand(280.0597439799999, 442.1679277999999, 269.3510991704999, + 415.93748636719994, 210.8464090199999, 459.11813227999994), + CubicToCommand(151.5206933399999, 502.90616051999996, 133.1579718199999, + 474.65581971999995, 133.1579718199999, 474.65581971999995), + LineToCommand(120.44531845999987, 466.18071747999994), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(193.89620453999999, 519.15010648), + CubicToCommand(193.89620453999999, 519.15010648, 181.18355117999997, + 539.63160356, 217.90899421999995, 562.93813472), + CubicToCommand(217.90899421999995, 562.93813472, 220.38089903999997, + 565.4100395400001, 188.59926563999997, 557.99432508), + CubicToCommand(188.59926563999997, 557.99432508, 177.65225857999997, + 554.46303248, 174.82722449999997, 536.10031096), + CubicToCommand(174.82722449999997, 536.10031096, 166.35212226, + 528.3314672399999, 157.87702001999997, 518.44384796), + CubicToCommand(149.40191778, 508.55622868, 193.89620453999999, + 519.15010648, 193.89620453999999, 519.15010648), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(441.08668653999996, 435.1053426), + CubicToCommand(441.08668653999996, 435.1053426, 472.33509475739993, + 482.459976366, 471.27923826999995, 490.89976568), + CubicToCommand(468.98389808, 509.2624872, 468.63076881999996, + 526.21269168, 474.28083698, 533.27527688), + CubicToCommand(479.9326707863, 540.33786208, 495.4703582263, + 598.9573192400001, 495.4703582263, 598.9573192400001), + CubicToCommand(495.4703582263, 598.9573192400001, 494.7640997063, + 601.0760948, 516.65634818, 533.9815354), + CubicToCommand(516.65634818, 533.9815354, 537.13784526, 505.7311946, + 501.82491926, 473.24330268), + CubicToCommand(501.82491926, 473.24330268, 439.67416949999995, + 422.39268924, 441.08668654, 435.1053426), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(229.20913054, 566.46942732), + CubicToCommand(229.20913054, 566.46942732, 248.98436909999998, + 579.18208068, 223.55906237999997, 634.27024524), + LineToCommand(234.85919869999998, 630.03269412), + CubicToCommand(234.85919869999998, 630.03269412, 233.44668165999997, + 649.80793268, 227.79661349999998, 654.0454838), + LineToCommand(240.50926685999997, 648.39541564), + CubicToCommand(240.50926685999997, 648.39541564, 248.98436909999998, + 662.52058604, 241.92178389999998, 670.9956882800001), + CubicToCommand(241.92178389999998, 670.9956882800001, 271.58464173999994, + 685.1208586800001, 270.1721247, 696.4209950000001), + CubicToCommand(270.1721247, 696.4209950000001, 281.47226101999996, + 682.2958246000001, 274.40967581999996, 670.9956882800001), + CubicToCommand(267.34709061999996, 659.69555196, 254.63443725999997, + 666.75813716, 256.0469543, 634.27024524), + LineToCommand(240.50926685999997, 639.9203134), + CubicToCommand(240.50926685999997, 639.9203134, 250.39688613999996, + 624.38262596, 250.39688613999996, 613.0824896400001), + LineToCommand(236.27171573999996, 617.32004076), + CubicToCommand(236.27171573999996, 617.32004076, 263.5844983547, + 570.389162106, 244.74681797999995, 567.88194436), + CubicToCommand(234.15294017999997, 566.46942732, 229.20913053999993, + 566.46942732, 229.20913053999993, 566.46942732), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(286.41607065999995, 596.13228516), + CubicToCommand(286.41607065999995, 596.13228516, 291.3598803, + 588.36344144, 286.41607065999995, 589.77595848), + CubicToCommand(281.47226101999996, 591.18847552, 226.38409645999997, + 617.32004076, 215.79021866, 634.27024524), + CubicToCommand(215.79021866, 634.27024524, 276.52845138, 591.18847552, + 286.41607066, 596.13228516), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(304.77879218, 610.25745556), + CubicToCommand(304.77879218, 610.25745556, 309.72260181999997, + 602.48861184, 304.77879218, 603.90112888), + CubicToCommand(299.83498254, 605.31364592, 244.74681797999997, + 631.44521116, 234.15294017999997, 648.39541564), + CubicToCommand(234.15294017999997, 648.39541564, 294.89117289999996, + 605.31364592, 304.77879218, 610.25745556), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(328.08532334, 583.4196318), + CubicToCommand(328.08532334, 583.4196318, 333.02913298, 575.65078808, + 328.08532334, 577.06330512), + CubicToCommand(323.14151369999996, 578.47582216, 268.05334913999997, + 604.6073874, 257.45947133999994, 621.55759188), + CubicToCommand(257.45947133999994, 621.55759188, 318.19770406, + 578.47582216, 328.08532333999995, 583.4196318), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(287.12232917999995, 660.40181048), + CubicToCommand(287.12232917999995, 660.40181048, 287.12232917999995, + 649.80793268, 282.17851953999997, 651.22044972), + CubicToCommand(277.2347099, 652.63296676, 213.67144309999998, + 683.7083416400001, 203.07756529999997, 700.65854612), + CubicToCommand(203.07756529999997, 700.65854612, 277.2347099, + 655.4580008400001, 287.12232917999995, 660.40181048), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(289.24110473999997, 641.3328304400001), + CubicToCommand(289.24110473999997, 641.3328304400001, 291.3598803, + 632.8577282, 286.41607065999995, 634.27024524), + CubicToCommand(282.88477806, 634.27024524, 236.27171574, + 654.7517423200001, 225.67783793999996, 671.7019468), + CubicToCommand(225.67783793999996, 671.7019468, 277.94096842, + 633.56398672, 289.24110473999997, 641.3328304400001), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(263.81579802, 725.37759432), + LineToCommand(246.15933501999996, 738.7965062), + CubicToCommand(246.15933501999996, 738.7965062, 264.52205654, + 725.37759432, 270.87838322, 727.4963698800001), + CubicToCommand(270.87838322, 727.4963698800001, 258.87198837999995, + 747.27160844, 257.45947133999994, 756.4529692), + CubicToCommand(257.45947133999994, 756.4529692, 275.82219286, + 733.85269656, 285.70981213999994, 734.55895508), + CubicToCommand(285.70981213999994, 734.55895508, 299.12872402, + 735.2652136, 299.12872402, 754.3341936400001), + CubicToCommand(299.12872402, 754.3341936400001, 309.01634329999996, + 735.97147212, 314.66641145999995, 736.67773064), + CubicToCommand(314.66641145999995, 736.67773064, 316.78518701999997, + 747.97786696, 314.66641145999995, 759.9842618), + CubicToCommand(314.66641145999995, 759.9842618, 321.72899665999995, + 746.56534992, 328.79158185999995, 749.390384), + CubicToCommand(328.79158185999995, 749.390384, 340.09171818, 745.8590914, + 338.67920114, 766.3405884800001), + CubicToCommand(338.67920114, 766.3405884800001, 338.67920114, 784.70331, + 337.26668409999996, 789.64711964), + CubicToCommand(337.26668409999996, 789.64711964, 347.15430338, + 743.0340573200001, 351.39185449999997, 742.3277988), + CubicToCommand(351.39185449999997, 742.3277988, 365.51702489999997, + 740.2090232400001, 373.99212714, 755.7467106800001), + CubicToCommand(373.99212714, 755.7467106800001, 366.92954194, 742.3277988, + 375.40464418, 745.8590914), + CubicToCommand(375.40464418, 745.8590914, 394.47362422, 748.68412548, + 400.12369237999997, 760.69052032), + CubicToCommand(400.12369237999997, 760.69052032, 388.11729754, + 739.50276472, 398.00491681999995, 745.1528328799999), + LineToCommand(412.13008721999995, 756.4529691999999), + CubicToCommand(412.13008721999995, 756.4529691999999, 426.96151613999996, + 793.8846707599998, 430.49280874, 796.7097048399999), + CubicToCommand(430.49280874, 796.7097048399999, 417.07389686, + 758.5717447599999, 419.89893093999996, 758.5717447599999), + CubicToCommand(419.89893093999996, 758.5717447599999, 416.36763834, + 737.3839891599999, 425.54899909999995, 763.5155543999999), + CubicToCommand(425.54899909999995, 763.5155543999999, 419.89893093999996, + 738.7965062, 429.78655022, 740.20902324), + CubicToCommand(439.67416949999995, 741.62154028, 447.44301321999995, + 759.2780032799999, 462.2744421399999, 755.0404521599999), + CubicToCommand(462.2744421399999, 755.0404521599999, 479.2264122662999, + 764.9280714399999, 482.75770486629995, 642.7453474799999), + LineToCommand(263.8175636663, 725.3775943199998), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(272.29090025999994, 561.52561768), + CubicToCommand(272.29090025999994, 561.52561768, 298.4224655, + 550.93173988, 369.04831749999994, 561.52561768), + CubicToCommand(369.04831749999994, 561.52561768, 381.76097086, + 562.2318762, 393.76736569999997, 546.69418876), + CubicToCommand(405.77376054, 531.15650132, 453.09308137999994, + 518.44384796, 464.3932177, 521.97514056), + LineToCommand(481.34518782629993, 533.27527688), + LineToCommand(482.75770486629995, 535.39405244), + CubicToCommand(482.75770486629995, 535.39405244, 504.64995333999997, + 553.75677396, 505.3562118599999, 567.17568584), + CubicToCommand(506.0624703799999, 580.5945977199999, 479.9326707862999, + 665.3456201199999, 462.98070065999997, 693.5959609199999), + CubicToCommand(446.03049618, 721.8463017199999, 429.0802917, + 743.7403158399999, 395.1798827399999, 739.50276472), + CubicToCommand(395.1798827399999, 739.50276472, 358.45443969999997, + 732.44017952, 313.25389441999994, 739.50276472), + CubicToCommand(313.25389441999994, 739.50276472, 261.69702245999997, + 736.6777306399999, 256.75321281999993, 722.5525602399999), + CubicToCommand(251.80940317999995, 708.4273898399999, 276.52845138, + 681.5895660799999, 276.52845138, 681.5895660799999), + CubicToCommand(276.52845138, 681.5895660799999, 284.2972951, + 666.7581371599999, 282.17851953999997, 641.33283044), + CubicToCommand(280.05974397999995, 615.90752372, 280.76600249999996, + 566.4694273199999, 272.29090025999994, 561.52561768), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(311.13511886, 565.05691028), + CubicToCommand(325.96654778, 597.5448022, 273.70341729999996, + 712.66494096, 273.70341729999996, 712.66494096), + CubicToCommand(270.1721247, 715.48997504, 296.05649945799996, + 726.172135155, 313.96015294, 721.8463017199999), + CubicToCommand(333.28691733979997, 717.184995488, 404.3612435, + 724.6713358, 404.3612435, 724.6713358), + CubicToCommand(446.03049618, 697.1272535200001, 468.63076881999996, + 618.7325578, 468.63076881999996, 618.7325578), + CubicToCommand(468.63076881999996, 618.7325578, 486.9952559863, + 576.3570466, 455.91811545999997, 570.7069784400001), + CubicToCommand(424.84274058, 565.05691028, 311.13511886, 565.05691028, + 311.13511886, 565.05691028), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(307.54909122469996, 619.61538095), + CubicToCommand(313.4216308185, 597.032764773, 316.2184145577, + 576.198138433, 311.13511886, 565.05691028), + CubicToCommand(311.13511886, 565.05691028, 421.31144797999997, + 576.3570466, 441.08668653999996, 539.63160356), + CubicToCommand(448.5747924983, 525.735967179, 474.6357318863, 579.8883392, + 473.92770771999994, 596.83854368), + CubicToCommand(473.92770771999994, 596.83854368, 362.69199082, + 622.2638504, 336.56042558, 602.48861184), + LineToCommand(307.54909122469996, 619.6153809499999), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(315.37266997999996, 648.39541564), + CubicToCommand(315.37266997999996, 648.39541564, 318.90396258, 661.108069, + 314.66641145999995, 668.1706542000001), + CubicToCommand(314.66641145999995, 668.1706542000001, 311.84137738, + 669.5831712400001, 309.72260181999997, 670.28942976), + CubicToCommand(309.72260181999997, 670.28942976, 311.84137738, + 676.64575644, 322.43525517999996, 679.4707905199999), + CubicToCommand(322.43525517999996, 679.4707905199999, 325.96654778, + 687.23963424, 330.20409889999996, 687.94589276), + CubicToCommand(334.44165002, 688.65215128, 342.91675225999995, + 698.53977056, 349.97933745999995, 696.4209950000001), + CubicToCommand(357.04192265999995, 694.30221944, 376.81716122, + 687.23963424, 376.81716122, 687.23963424), + CubicToCommand(376.81716122, 687.23963424, 386.70478049999997, + 681.58956608, 402.24246794, 687.94589276), + CubicToCommand(402.24246794, 687.94589276, 406.43587790249995, + 686.53337572, 407.18627757999997, 679.47079052), + CubicToCommand(408.06910072999995, 671.17225291, 413.54260425999996, + 664.6393616, 417.07389686, 661.108069), + CubicToCommand(420.60518945999996, 657.5767764, 437.55539394, + 634.97650376, 435.43661837999997, 634.27024524), + CubicToCommand(433.31784281999995, 633.5639867200001, 315.37266997999996, + 648.39541564, 315.37266997999996, 648.39541564), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(307.60382625999995, 562.93813472), + CubicToCommand(307.60382625999995, 562.93813472, 302.66001661999996, + 602.48861184, 308.31008477999995, 617.32004076), + CubicToCommand(313.96015294, 632.15146968, 312.5476359, 635.68276228, + 311.13511886, 642.7453474800001), + CubicToCommand(309.72260181999997, 649.80793268, 317.49144554, + 667.46439568, 327.37906482, 678.05827348), + LineToCommand(348.56682042, 680.88330756), + CubicToCommand(348.56682042, 680.88330756, 375.40464418, 674.52698088, + 391.64859013999995, 679.47079052), + CubicToCommand(391.64859013999995, 679.47079052, 407.52881296219994, + 681.836756562, 413.54260425999996, 655.4580008400001), + CubicToCommand(413.54260425999996, 655.4580008400001, 422.0177065, + 644.15786452, 434.73035985999996, 639.21405488), + CubicToCommand(447.44301322, 634.2702452400001, 460.15566658, + 560.8193591600001, 453.09308137999994, 546.6941887600001), + CubicToCommand(446.03049618, 532.5690183600001, 420.60518945999996, + 524.80017464, 392.35484865999996, 552.34425692), + CubicToCommand(364.10450785999996, 579.8883392, 360.57321526, + 550.22548136, 307.60382625999995, 562.93813472), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(310.42886033999997, 695.0084779599999), + CubicToCommand(310.42886033999997, 695.0084779599999, 309.01634329999996, + 691.47718536, 301.24749957999995, 690.77092684), + CubicToCommand(301.24749957999995, 690.77092684, 261.69702245999997, + 684.41460016, 246.86559353999996, 662.52058604), + CubicToCommand(246.86559353999996, 662.52058604, 234.85919869999998, + 652.6329667599999, 242.62804241999999, 673.11446384), + CubicToCommand(242.62804241999999, 673.11446384, 260.99076393999997, + 709.1336483599999, 272.99715877999995, 714.077458), + CubicToCommand(272.99715877999995, 714.077458, 301.95375809999996, + 721.1400432, 310.42886033999997, 695.0084779599999), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(451.57815685459997, 582.060084149), + CubicToCommand(452.7417177663, 568.093821916, 456.19002499019996, + 552.891607273, 453.09308138, 546.69418876), + CubicToCommand(441.7117253302, 523.935007953, 411.74341068030003, + 533.45184151, 392.35484866, 552.34425692), + CubicToCommand(364.10450786, 579.8883391999999, 360.57321526, + 550.22548136, 307.60382626, 562.93813472), + CubicToCommand(307.60382626, 562.93813472, 304.5227734665, + 587.5865570679999, 306.0059163585, 605.2783329939999), + CubicToCommand(306.0059163585, 605.2783329939999, 371.87335157999996, + 584.83214884, 373.28586862, 594.7197681199999), + CubicToCommand(373.28586862, 594.7197681199999, 376.1109027, 589.06969996, + 392.35484866, 589.06969996), + CubicToCommand(408.59879462, 589.06969996, 448.7531227746, 587.003893789, + 451.57815685459997, 582.060084149), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(375.40464418, 564.35065176), + CubicToCommand(375.40464418, 564.35065176, 383.87974641999995, 572.825754, + 377.52341974, 589.77595848), + CubicToCommand(377.52341974, 589.77595848, 352.09811301999997, + 618.02629928, 355.62940562, 642.74534748) + ], + ), + Path( + commands: const [ + MoveToCommand(290.65362178, 714.077458), + CubicToCommand(290.65362178, 714.077458, 282.88477806, 691.47718536, + 298.4224655, 703.4835802), + LineToCommand(304.77879218, 709.8399068800001), + CubicToCommand(302.66001661999996, 712.6649409600001, 292.77239734, + 719.7275261600001, 290.65362178, 714.077458), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(299.552479132, 716.19623356), + CubicToCommand(299.552479132, 716.19623356, 293.337404156, 698.116015448, + 305.76755410799996, 707.7211313199999), + LineToCommand(310.85261545199995, 712.8061926639999), + CubicToCommand(302.801268324, 715.0662199279999, 310.85261545199995, + 719.586274456, 299.552479132, 716.19623356), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(308.027581372, 716.19623356), + CubicToCommand(308.027581372, 716.19623356, 301.812506396, 698.116015448, + 314.24265634799997, 707.7211313199999), + LineToCommand(319.32771769199996, 712.8061926639999), + CubicToCommand(313.39514612399995, 715.0662199279999, 319.32771769199996, + 719.586274456, 308.027581372, 716.19623356), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(319.68084695199997, 716.5493628199999), + CubicToCommand(319.68084695199997, 716.5493628199999, 313.465771976, + 698.4691447079999, 325.89592192799995, 708.07426058), + CubicToCommand(325.89592192799995, 708.07426058, 333.63474966089996, + 712.1882164589999, 330.9827489183, 713.159321924), + CubicToCommand(325.754670224, 715.0662199279999, 330.9827489183, + 719.9394037159999, 319.68084695199997, 716.5493628199999), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(331.12223497599996, 716.408111116), + CubicToCommand(331.12223497599996, 716.408111116, 324.90716, + 698.327893004, 337.3390755983, 707.933008876), + LineToCommand(342.4241369423, 713.0180702199999), + CubicToCommand(340.7291164943, 715.2780974839999, 342.4241369423, + 719.798152012, 331.12223497599996, 716.408111116), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(342.91675225999995, 717.6087506), + CubicToCommand(342.91675225999995, 717.6087506, 334.44165002, + 695.7147364799999, 350.68559597999996, 707.0148728), + LineToCommand(357.04192265999995, 713.3711994800001), + CubicToCommand(354.9231471, 716.1962335600001, 357.04192265999995, + 721.84630172, 342.91675225999995, 717.6087506), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(292.77239734, 687.23963424), + CubicToCommand(292.77239734, 687.23963424, 316.07892849999996, + 682.2958246000001, 326.6728063, 687.94589276), + CubicToCommand(326.6728063, 687.94589276, 337.26668409999996, + 690.06466832, 339.38545966, 689.3584098), + CubicToCommand(341.50423522, 688.6521512800001, 347.15430338, + 687.94589276, 347.15430338, 687.94589276) + ], + ), + Path( + commands: const [ + MoveToCommand(352.80437154, 702.77732168), + CubicToCommand(352.80437154, 702.77732168, 373.99212714, 678.764532, + 395.17988274, 686.53337572), + CubicToCommand(407.5676571808, 691.071086711, 405.77376053999996, + 685.12085868, 407.18627757999997, 680.17704904), + CubicToCommand(408.59879462, 675.2332394, 408.95192388, 667.81752494, + 417.78015538, 662.52058604) + ], + ), + Path( + commands: const [ + MoveToCommand(383.1734879, 674.52698088), + CubicToCommand(383.1734879, 674.52698088, 376.1109027, 655.45800084, + 371.16709305999996, 678.05827348), + CubicToCommand(366.22328342, 700.65854612, 360.57321526, 707.0148728, + 357.74818117999996, 711.9586824400001), + CubicToCommand(357.74818117999996, 711.9586824400001, 357.74818117999996, + 721.1400432, 372.57961009999997, 720.43378468), + CubicToCommand(372.57961009999997, 720.43378468, 391.64859013999995, + 719.7275261600001, 392.35484866, 714.7837165200001), + CubicToCommand(393.06110718, 709.8399068800001, 390.2360731, 689.3584098, + 383.1734879, 674.52698088), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(407.8925361, 687.23963424), + CubicToCommand(407.8925361, 687.23963424, 414.24886277999997, + 683.0020831200001, 418.4864139, 685.1208586800001) + ], + ), + Path( + commands: const [ + MoveToCommand(419.36923705, 658.28303492), + CubicToCommand(419.36923705, 658.28303492, 424.48961132, 649.63136805, + 432.96471355999995, 648.21885101) + ], + ), + Path( + commands: const [ + MoveToCommand(279.35348546, 723.2588187599999), + CubicToCommand(279.35348546, 723.2588187599999, 311.13511886, + 728.90888692, 318.90396258, 726.0838528400001), + LineToCommand(319.6102211, 729.61514544), + LineToCommand(282.88477806, 727.4963698800001), + CubicToCommand(282.88477806, 727.4963698800001, 262.40328098, 717.6087506, + 279.35348545999994, 723.25881876), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(304.07253366, 558.7005836), + LineToCommand(338.67920114, 560.11310064), + CubicToCommand(338.67920114, 560.11310064, 351.39185449999997, + 614.4950066800001, 345.03552781999997, 627.9139185600001), + CubicToCommand(345.03552781999997, 627.9139185600001, 342.91675225999995, + 632.8577282000001, 337.97294261999997, 622.97010892), + CubicToCommand(337.97294261999997, 622.97010892, 305.4850507, + 565.05691028, 299.83498254, 561.5256176800001), + CubicToCommand(294.18491437999995, 557.9943250800001, 301.95375809999996, + 558.7005836000001, 304.07253366, 558.7005836000001), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(167.94120392999997, 553.9333385900001), + CubicToCommand(167.94120392999997, 553.9333385900001, 183.655456, + 556.9349373, 205.90259937999997, 561.5256176800001), + CubicToCommand(205.90259937999997, 561.5256176800001, 214.37770161999998, + 601.0760948000001, 220.02776977999997, 609.55119704), + CubicToCommand(225.67783793999996, 618.02629928, 219.32151125999997, + 618.0262992800001, 212.96518457999997, 613.0824896400001), + CubicToCommand(206.60885789999998, 608.13868, 180.47729265999996, + 583.4196318, 176.94600005999996, 575.6507880800001), + CubicToCommand(173.41470745999996, 567.88194436, 167.94120392999997, + 553.9333385900001, 167.94120392999997, 553.9333385900001), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(206.53999769429998, 561.914059866), + CubicToCommand(206.53999769429998, 561.914059866, 216.78074623429995, + 564.650811631, 218.56228335099996, 568.552889954), + CubicToCommand(220.34205482139998, 572.47262474, 216.43997649839997, + 578.281601067, 216.43997649839997, 578.281601067), + CubicToCommand(216.43997649839997, 578.281601067, 214.67433019839996, + 584.1258903199999, 212.55202334579997, 580.312094312), + CubicToCommand(210.42971649319998, 576.480641841, 205.3587803196, + 562.955791183, 206.53999769429998, 561.914059866), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(206.60885789999998, 561.52561768), + CubicToCommand(206.60885789999998, 561.52561768, 212.96518457999997, + 570.70697844, 219.32151125999997, 570.70697844), + CubicToCommand(225.67783794, 570.70697844, 226.35231482659998, + 569.983063457, 231.32790609999998, 571.0601077), + CubicToCommand(239.44987907999996, 572.825754, 238.74362055999998, + 569.2944613999999, 250.39688614, 571.41323696), + CubicToCommand(255.05819237199995, 572.2607471839999, 259.57824689999995, + 570.70697844, 264.52205654, 572.825754), + CubicToCommand(269.46586618, 574.94452956, 275.11593433999997, + 573.53201252, 277.2347099, 570.0007199199999), + CubicToCommand(279.35348545999994, 566.46942732, 287.82858769999996, + 559.05371286, 287.82858769999996, 559.05371286), + CubicToCommand(287.82858769999996, 559.05371286, 265.22831506, + 562.2318762, 260.28450541999996, 563.64439324), + CubicToCommand(260.28450541999996, 563.64439324, 220.73402829999998, + 565.7631687999999, 206.60885789999998, 561.52561768), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(285.35668288, 561.87874694), + CubicToCommand(285.35668288, 561.87874694, 273.968264245, + 568.0585089900001, 273.262005725, 572.29606011), + CubicToCommand(272.555747205, 576.53361123, 282.53164879999997, + 583.06650254, 282.53164879999997, 583.06650254), + CubicToCommand(282.53164879999997, 583.06650254, 287.387176125, + 591.18847552, 288.44656390499995, 586.9509244), + CubicToCommand(289.50595168499996, 582.71337328, 286.76919992, + 562.5850054599999, 285.35668288, 561.87874694), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(219.17143132449996, 571.519175738), + CubicToCommand(219.17143132449996, 571.519175738, 231.54331494859997, + 591.276757835, 231.92646019569997, 571.483862812), + CubicToCommand(231.92646019569997, 571.483862812, 232.9099251848, + 569.259148474, 229.80238769679997, 569.223835548), + CubicToCommand(219.07608642429994, 569.100240307, 221.76163444659997, + 561.843434014, 219.17143132449996, 571.519175738), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(231.84524046589996, 571.960587313), + CubicToCommand(231.84524046589996, 571.960587313, 245.83092480819997, + 591.71816941, 244.70797376139998, 571.801679146), + CubicToCommand(244.70797376139998, 571.801679146, 244.72033328549998, + 571.2190158669999, 241.62515532159998, 570.954168922), + CubicToCommand(233.24363233549997, 570.212597476, 233.85278030899997, + 562.2318762, 231.84524046589996, 571.960587313), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(244.58084722779998, 571.978243776), + CubicToCommand(244.58084722779998, 571.978243776, 258.6353917758, + 590.747063945, 257.4541744011, 573.673264224), + CubicToCommand(257.4541744011, 573.673264224, 257.6642863108, + 571.5015192750001, 254.7439073306, 570.971825385), + CubicToCommand(247.87201193099997, 569.718216512, 247.49946056169998, + 563.9975225000001, 244.58084722779998, 571.978243776), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(256.72143118659994, 572.11949548), + CubicToCommand(256.72143118659994, 572.11949548, 270.6700369566, + 592.530366708, 271.284481869, 575.262345894), + CubicToCommand(271.284481869, 575.262345894, 274.18720438619994, + 572.825754, 271.1043859464, 572.437311814), + CubicToCommand(260.831855773, 571.130733552, 262.24084152039995, + 563.273607517, 256.72143118659994, 572.11949548), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(192.85094193039998, 578.352226919), + LineToCommand(179.32962256499997, 575.65078808), + CubicToCommand(174.73894218499998, 566.82255658, 171.03108495499995, + 555.963831835, 171.03108495499995, 555.963831835), + CubicToCommand(171.03108495499995, 555.963831835, 182.24293895999995, + 557.729478135, 204.31351770999996, 562.6732877750001), + CubicToCommand(204.31351770999996, 562.6732877750001, 205.86022386879995, + 568.535233491, 208.45925522239997, 578.758325568), + LineToCommand(192.85094193039996, 578.352226919), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(307.73801537879996, 570.124315161), + CubicToCommand(304.79644864299996, 565.692542948, 302.47109246589997, + 562.602661923, 301.32342237089995, 561.87874694), + CubicToCommand(296.00353006899996, 558.559331896, 303.3186026899, + 559.2126210270001, 305.3120173626, 559.2126210270001), + LineToCommand(337.8952541828, 560.554512215), + CubicToCommand(337.8952541828, 560.554512215, 338.820452844, + 564.509559927, 340.02815491319996, 570.4951008840001), + CubicToCommand(340.02815491319996, 570.4951008840001, 322.21631503879996, + 566.9461518210001, 307.73801537879996, 570.124315161), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(402.383719644, 326.2020444623), + CubicToCommand(451.3292007263, 333.1940038103, 496.3884943023, + 270.2663696783, 499.4960317903, 253.173147848), + CubicToCommand(502.601803632, 236.081691664, 484.7352287223, 215.10581362, + 484.7352287223, 215.10581362), + CubicToCommand(487.06588183829996, 209.667623016, 478.5201537463, + 184.807323112, 469.1975412823, 168.4927513), + CubicToCommand(459.87492881829996, 152.178179488, 431.799387002, + 153.8979189842, 400.8299509, 152.178179488), + CubicToCommand(372.862113508, 150.624410744, 340.232969884, 191.79928246, + 337.902316768, 194.906819948), + CubicToCommand(335.571663652, 198.01435743599998, 346.44804486, + 265.6050634463, 348.778697976, 275.7045602823), + CubicToCommand(351.109351092, 285.8040571183, 346.44804486, + 332.4171194383, 346.44804486, 332.4171194383), + CubicToCommand(406.903774172, 316.3497381083, 353.440004208, + 319.2100851143, 402.38371964399994, 326.2020444623), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(339.1877072744, 196.0509587504), + CubicToCommand(336.89942966959995, 199.1019955568, 347.57805849199997, + 265.4638117423, 349.86633609679996, 275.3796813631), + CubicToCommand(352.1546137016, 285.2955509839, 347.57805849199997, + 331.0611030799, 347.57805849199997, 331.0611030799), + CubicToCommand(405.2652544056, 315.3821639359, 354.4428913064, + 318.0941966527, 402.4967210072, 324.9590294671), + CubicToCommand(450.5523163543, 331.8238622815, 494.7923500471, + 270.0403669519, 497.84338685349996, 253.2578988704), + CubicToCommand(500.8944236599, 236.4771964352, 483.35096202309995, + 215.882697992, 483.35096202309995, 215.882697992), + CubicToCommand(485.6392396279, 210.5433835808, 477.24888841029997, + 186.1350891296, 468.09577799109996, 170.117145896), + CubicToCommand(458.94266757189996, 154.0992026624, 431.3791631826, + 155.7889261715, 400.9712026039999, 154.0992026624), + CubicToCommand(373.51187134639997, 152.5736842592, 341.4759848792, + 192.999921944, 339.18770727439994, 196.0509587504), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(340.4730977808, 197.1950975528), + CubicToCommand(338.2271956872, 200.1896336776, 348.70807212399995, + 265.3225600383, 350.9539742176, 275.05480244390003), + CubicToCommand(353.1998763112, 284.78704484950003, 348.70807212399995, + 329.70508672150004, 348.70807212399995, 329.70508672150004), + CubicToCommand(404.15642852919996, 313.53176661350005, 355.44577840479997, + 316.97830819110004, 402.60972237039994, 323.7160144719), + CubicToCommand(449.7754319823, 330.4537207527, 493.19620579189996, + 269.8143642255, 496.19074191669995, 253.3426498928), + CubicToCommand(499.18527804149994, 236.87270120640002, 481.96669532389996, + 216.65958236400002, 481.96669532389996, 216.65958236400002), + CubicToCommand(484.2125974175, 211.4191441456, 475.97762307429997, + 187.4628551472, 466.99401469989994, 171.741540492), + CubicToCommand(458.01040632549996, 156.02022583680002, 430.95717371689994, + 157.6781677125, 401.11245430799994, 156.02022583680002), + CubicToCommand(374.16162918479995, 154.52295777440003, 342.71899987439997, + 194.20056142800001, 340.47309778079995, 197.1950975528), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(341.75848828719995, 198.3392363552), + CubicToCommand(339.5549617048, 201.27727179840002, 349.838085756, + 265.1813083343, 352.0416123384, 274.7299235247), + CubicToCommand(354.24513892079995, 284.2785387151, 349.838085756, + 328.3490703631, 349.838085756, 328.3490703631), + CubicToCommand(401.81165024279994, 312.3876278111, 356.4486655032, + 315.8624197295, 402.7227237336, 322.4729994767), + CubicToCommand(448.99854761029997, 329.0835792239, 491.60006153669997, + 269.5883614991, 494.5380969799, 253.4291665615), + CubicToCommand(497.4761324231, 237.26820597760002, 480.5824286247, + 217.436466736, 480.5824286247, 217.436466736), + CubicToCommand(482.7859552071, 212.2949047104, 474.70635773829997, + 188.79062116480003, 465.8922514087, 173.36593508800001), + CubicToCommand(457.0781450791, 157.9412490112, 430.5351842512, + 159.56740925350002, 401.253706012, 157.9412490112), + CubicToCommand(374.8113870232, 156.47223128960002, 343.9620148696, + 195.401200912, 341.7584882872, 198.3392363552), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(343.04387879359996, 199.4833751576), + CubicToCommand(340.8827277224, 202.36490991920002, 350.968099388, + 265.0400566303, 353.12925045919997, 274.4050446055), + CubicToCommand(355.29040153039995, 283.7700325807, 350.968099388, + 326.9930540047, 350.968099388, 326.9930540047), + CubicToCommand(400.1731304764, 311.2434890087, 357.4515526016, + 314.7465312679, 402.8357250968, 321.22998448149997), + CubicToCommand(448.2216632383, 327.71343769509997, 490.0039172815, + 269.3623587727, 492.8854520431, 253.51215193759998), + CubicToCommand(495.76698680469997, 237.66371074879999, 479.1981619255, + 218.21335110799998, 479.1981619255, 218.21335110799998), + CubicToCommand(481.3593129967, 213.1706652752, 473.43509240230003, + 190.1183871824, 464.7904881175, 174.990329684), + CubicToCommand(456.14588383269995, 159.86227218559998, 430.1131947855, + 161.45665079449998, 401.394957716, 159.86227218559998), + CubicToCommand(375.46114486159996, 158.4215048048, 345.2050298648, + 196.601840396, 343.0438787936, 199.4833751576), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(402.94872646, 319.98520384), + CubicToCommand(447.44301322, 326.34153052, 488.4077730263, 269.1345904, + 491.23280710629996, 253.59690296), + CubicToCommand(494.0578411862999, 238.05921552, 477.81389522629996, + 218.99023548, 477.81389522629996, 218.99023548), + CubicToCommand(479.9326707863, 214.04642583999998, 472.16206142, + 191.4461532, 463.68695918, 176.61472428), + CubicToCommand(455.21185693999996, 161.78329536, 429.69120531979996, + 163.34765798179998, 401.53620942, 161.78329536), + CubicToCommand(376.11090269999994, 160.37077832, 346.44804486, + 197.80247988, 344.32926929999996, 200.62751396), + CubicToCommand(342.21049373999995, 203.45254804, 352.09811301999997, + 264.89703928, 354.21688858, 274.07840004), + CubicToCommand(356.33566413999995, 283.2597608, 352.09811301999997, + 325.635272, 352.09811301999997, 325.635272), + CubicToCommand(397.12209366999997, 310.45071382000003, 358.45443969999997, + 313.62887716, 402.94872646, 319.98520384), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(484.87648042629996, 259.95322964), + CubicToCommand(484.87648042629996, 259.95322964, 435.78974764, + 273.37214152, 415.30825056, 270.54710744), + CubicToCommand(415.30825056, 270.54710744, 387.41103902, 258.89384186, + 371.87335157999996, 297.3849312), + CubicToCommand(371.87335157999996, 297.3849312, 365.51702489999997, + 310.09758456, 361.9857323, 313.62887716), + CubicToCommand(358.45443969999997, 317.16016976000003, 484.87648042629996, + 259.95322964, 484.87648042629996, 259.95322964), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(491.58593636629996, 256.06880778), + CubicToCommand(491.58593636629996, 256.06880778, 440.38042801999995, + 277.60969264, 422.72396502, 276.90343412), + CubicToCommand(422.72396502, 276.90343412, 393.76736569999997, + 268.78146114000003, 378.93593677999996, 294.55989712), + CubicToCommand(378.93593677999996, 294.55989712, 364.10450785999996, + 310.80384308, 358.45443969999997, 313.62887716), + CubicToCommand(358.45443969999997, 313.62887716, 357.74818117999996, + 316.45391124, 369.0483175, 309.39132604), + LineToCommand(387.41103902, 318.57268680000004), + CubicToCommand(387.41103902, 318.57268680000004, 413.54260425999996, + 335.52289128, 430.49280874, 307.27255048), + CubicToCommand(430.49280874, 307.27255048, 437.55539394, 287.49731192, + 437.55539394, 283.96601932000004), + CubicToCommand(437.55539394, 280.43472672, 474.9870955, + 270.54710744000005, 477.81389522629996, 269.84084892000004), + CubicToCommand(480.63892930629993, 269.13459040000004, 492.29219488629997, + 261.71887594000003, 491.58593636629996, 256.06880778000004), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(407.8925361, 319.4802289982), + CubicToCommand(395.7590147264, 319.4802289982, 380.97525825649996, + 312.6560060487, 380.97525825649996, 301.62248232), + CubicToCommand(380.97525825649996, 290.5907242376, 395.7590147264, + 279.5289501681, 407.8925361, 279.5289501681), + CubicToCommand(420.0295887662, 279.5289501681, 429.8677699498, + 288.47194867760004, 429.8677699498, 299.50370676), + CubicToCommand(429.8677699498, 310.5372304887, 420.02958876619994, + 319.4802289982, 407.8925361, 319.4802289982), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(401.4955995551, 290.02218612900003), + CubicToCommand(392.9392775853, 291.2969827576, 383.95390356459995, + 293.9507491465, 384.08103009819996, 293.5693695457), + CubicToCommand(386.8001254002, 285.413849286, 398.0314015145, + 279.5289501681, 407.8925361, 279.5289501681), + CubicToCommand(415.4777526048, 279.5289501681, 422.1660207892, + 283.0213985495, 426.114005916, 288.3359939125), + CubicToCommand(426.114005916, 288.3359939125, 416.7278301852, + 287.7533306335, 401.4955995551, 290.02218612900003), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(422.72396502, 289.61608748000003), + CubicToCommand(422.72396502, 289.61608748000003, 414.9551213, + 283.96601932, 414.9551213, 287.85044118), + CubicToCommand(414.9551213, 287.85044118, 421.31144797999997, 295.6192849, + 422.72396502, 289.61608748000003), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(405.06750202, 303.9637293138), + CubicToCommand(400.6551519163, 303.9637293138, 397.07795251249996, + 300.38652991000004, 397.07795251249996, 295.97241416), + CubicToCommand(397.07795251249996, 291.5600640563, 400.6551519163, + 287.9828646525, 405.06750202, 287.9828646525), + CubicToCommand(409.48161776999996, 287.9828646525, 413.0588171738, + 291.5600640563, 413.0588171738, 295.97241415999997), + CubicToCommand(413.0588171738, 300.38652991, 409.48161776999996, + 303.9637293138, 405.06750202, 303.9637293138), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(221.44028681999998, 280.43472672), + CubicToCommand(221.44028681999998, 280.43472672, 215.79021865999997, + 243.00302516, 220.02776977999997, 235.23418144000001), + CubicToCommand(220.02776977999997, 235.23418144000001, 239.09674981999999, + 217.57771844, 238.39049129999998, 211.22139176000002), + CubicToCommand(238.39049129999998, 211.22139176000002, 237.68423277999997, + 179.43975836, 235.56545721999998, 178.02724132), + CubicToCommand(233.44668165999997, 176.61472428, 220.02776977999997, + 166.02084648, 209.43389197999997, 177.32098280000002), + CubicToCommand(209.43389197999997, 177.32098280000002, 191.07117045999996, + 209.1026162, 192.48368749999997, 220.40275252), + LineToCommand(192.48368749999997, 223.93404512), + CubicToCommand(192.48368749999997, 223.93404512, 179.06477561999998, + 223.2277866, 176.23974153999998, 226.7590792), + CubicToCommand(176.23974153999998, 226.7590792, 174.12096597999997, + 235.94043996, 172.00219041999995, 236.64669848), + CubicToCommand(172.00219041999995, 236.64669848, 167.05838077999996, + 240.8842496, 170.58967337999997, 245.82805924000002), + CubicToCommand(170.58967337999997, 245.82805924000002, 167.05838077999996, + 250.06561036, 167.76463929999997, 257.12819556), + LineToCommand(181.18355117999997, 264.19078076), + CubicToCommand(181.18355117999997, 264.19078076, 184.71484377999997, + 289.61608748000003, 203.78382381999995, 298.79744824), + CubicToCommand(212.32248932679994, 302.9096384727, 217.90899421999995, + 291.02860452, 221.44028681999995, 280.43472672), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(219.67464051999997, 277.185937528), + CubicToCommand(219.67464051999997, 277.185937528, 214.58957917599997, + 243.497406124, 218.40337518399997, 236.505446776), + CubicToCommand(218.40337518399997, 236.505446776, 235.56545721999998, + 220.61463007600003, 234.92982455199996, 214.893936064), + CubicToCommand(234.92982455199996, 214.893936064, 234.29419188399999, + 186.290466004, 232.38729387999996, 185.019200668), + CubicToCommand(230.480395876, 183.747935332, 218.40337518399997, + 174.213445312, 208.86888516399998, 184.38356800000003), + CubicToCommand(208.86888516399998, 184.38356800000003, 192.342435796, + 212.98703806, 193.613701132, 223.157160748), + LineToCommand(193.613701132, 226.335324088), + CubicToCommand(193.613701132, 226.335324088, 181.53668043999997, + 225.69969142000002, 178.99414976799997, 228.87785476000002), + CubicToCommand(178.99414976799997, 228.87785476000002, 177.08725176399997, + 237.141079444, 175.18035375999997, 237.776712112), + CubicToCommand(175.18035375999997, 237.776712112, 170.73092508399998, + 241.59050812, 173.90908842399998, 246.039936796), + CubicToCommand(173.90908842399998, 246.039936796, 170.73092508399998, + 249.853732804, 171.36655775199998, 256.210059484), + LineToCommand(183.443578444, 262.566386164), + CubicToCommand(183.443578444, 262.566386164, 186.621741784, + 285.44916221200003, 203.78382381999998, 293.712386896), + CubicToCommand(211.46791651759997, 297.4114158945, 216.49647718, + 286.72042754800003, 219.67464051999997, 277.185937528), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(234.77091638499996, 179.775231157), + CubicToCommand(232.84636191799996, 178.256775339, 219.62167113099997, + 168.068996188, 209.292640276, 179.0866291), + CubicToCommand(209.292640276, 179.0866291, 191.388986794, 210.073721665, + 192.766190908, 221.091354577), + LineToCommand(192.766190908, 224.53436486200002), + CubicToCommand(192.766190908, 224.53436486200002, 179.682751825, + 223.845762805, 176.928343597, 227.28877309), + CubicToCommand(176.928343597, 227.28877309, 174.862537426, 236.240599831, + 172.796731255, 236.929201888), + CubicToCommand(172.796731255, 236.929201888, 167.976516856, 241.06081423, + 171.419527141, 245.881028629), + CubicToCommand(171.419527141, 245.881028629, 167.976516856, 250.012640971, + 168.665118913, 256.898661541), + LineToCommand(181.748557996, 263.784682111), + CubicToCommand(181.748557996, 263.784682111, 185.19156828099997, + 288.574356163, 203.78382381999998, 297.526182904), + CubicToCommand(212.10708047819998, 301.534200005, 217.55586495999998, + 289.951560277, 220.99887524499997, 279.622529422), + CubicToCommand(220.99887524499997, 279.622529422, 215.490058789, + 243.126620401, 219.62167113099997, 235.551997774), + CubicToCommand(219.62167113099997, 235.551997774, 238.21392666999998, + 218.33694634900002, 237.52532461299998, 212.139527836), + CubicToCommand(237.52532461299998, 212.139527836, 236.83672255599998, + 181.152435271, 234.77091638499996, 179.775231157), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(233.97637554999997, 181.523220994), + CubicToCommand(232.24604217599997, 179.898826398, 219.21557248199997, + 170.117145896, 209.15138857199997, 180.8522754), + CubicToCommand(209.15138857199997, 180.8522754, 191.706803128, + 211.04482713000002, 193.04869431599997, 221.779956634), + LineToCommand(193.04869431599997, 225.134684604), + CubicToCommand(193.04869431599997, 225.134684604, 180.30072802999996, + 224.46373901, 177.61694565399998, 227.81846698), + CubicToCommand(177.61694565399998, 227.81846698, 175.60410887199998, + 236.540759702, 173.59127208999996, 237.211705296), + CubicToCommand(173.59127208999996, 237.211705296, 168.89465293199999, + 241.23737886, 172.24938090199996, 245.933998018), + CubicToCommand(172.24938090199996, 245.933998018, 168.89465293199996, + 249.959671582, 169.56559852599997, 256.669127522), + LineToCommand(182.31356481199995, 263.378583462), + CubicToCommand(182.31356481199995, 263.378583462, 185.66829278199998, + 287.532624846, 203.78382381999995, 296.254917568), + CubicToCommand(211.89520292219996, 300.1605271836, 217.20273569999995, + 288.874516034, 220.55746366999995, 278.810332124), + CubicToCommand(220.55746366999995, 278.810332124, 215.18989891799998, + 243.250215642, 219.21557248199997, 235.869814108), + CubicToCommand(219.21557248199997, 235.869814108, 237.33110351999994, + 219.096174258, 236.66015792599995, 213.057663912), + CubicToCommand(236.66015792599995, 213.057663912, 235.98921233199997, + 182.86511218200002, 233.97637554999994, 181.52322099399998), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(233.18183471499998, 183.27121083100002), + CubicToCommand(231.645722434, 181.54087745700002, 218.80947383299997, + 172.165295604, 209.01013686799996, 182.6179217), + CubicToCommand(209.01013686799996, 182.6179217, 192.02461946199998, + 212.015932595, 193.331197724, 222.468558691), + LineToCommand(193.331197724, 225.735004346), + CubicToCommand(193.331197724, 225.735004346, 180.91870423499998, + 225.081715215, 178.30554771099997, 228.34816087000002), + CubicToCommand(178.30554771099997, 228.34816087000002, 176.34568031799998, + 236.840919573, 174.38581292499998, 237.49420870400002), + CubicToCommand(174.38581292499998, 237.49420870400002, 169.81278900799998, + 241.41394349, 173.079234663, 245.986967407), + CubicToCommand(173.079234663, 245.986967407, 169.81278900799998, + 249.906702193, 170.466078139, 256.439593503), + LineToCommand(182.87857162799997, 262.972484813), + CubicToCommand(182.87857162799997, 262.972484813, 186.14501728299996, + 286.490893529, 203.78382381999998, 294.983652232), + CubicToCommand(211.68155971989998, 298.7868543622, 216.84960644, + 287.797471791, 220.116052095, 277.998134826), + CubicToCommand(220.116052095, 277.998134826, 214.88973904699998, + 243.373810883, 218.80947383299997, 236.187630442), + CubicToCommand(218.80947383299997, 236.187630442, 236.44828037, + 219.85540216700002, 235.79499123899998, 213.975799988), + CubicToCommand(235.79499123899998, 213.975799988, 235.14170210799998, + 184.577789093, 233.18183471499998, 183.27121083100002), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(219.67464051999997, 277.009372898), + CubicToCommand(219.67464051999997, 277.009372898, 214.58957917599997, + 243.497406124, 218.40337518399997, 236.505446776), + CubicToCommand(218.40337518399997, 236.505446776, 235.56545721999998, + 220.614630076, 234.92982455199996, 214.893936064), + CubicToCommand(234.92982455199996, 214.893936064, 234.29419188399999, + 186.290466004, 232.38729387999996, 185.019200668), + CubicToCommand(231.04540269199998, 183.182928516, 218.40337518399997, + 174.213445312, 208.86888516399998, 184.38356800000003), + CubicToCommand(208.86888516399998, 184.38356800000003, 192.342435796, + 212.98703806, 193.613701132, 223.157160748), + LineToCommand(193.613701132, 226.335324088), + CubicToCommand(193.613701132, 226.335324088, 181.53668043999997, + 225.69969142000002, 178.99414976799997, 228.87785476000002), + CubicToCommand(178.99414976799997, 228.87785476000002, 177.08725176399997, + 237.141079444, 175.18035375999997, 237.776712112), + CubicToCommand(175.18035375999997, 237.776712112, 170.73092508399998, + 241.59050812, 173.90908842399998, 246.039936796), + CubicToCommand(173.90908842399998, 246.039936796, 170.73092508399998, + 249.853732804, 171.36655775199998, 256.210059484), + LineToCommand(183.443578444, 262.566386164), + CubicToCommand(183.443578444, 262.566386164, 186.621741784, + 285.44916221200003, 203.78382381999998, 293.712386896), + CubicToCommand(211.46791651759997, 297.4114158945, 216.49647718, + 286.543862918, 219.67464051999997, 277.009372898), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(214.20113698999995, 265.95642706), + CubicToCommand(214.20113698999995, 265.95642706, 176.06317690999995, + 247.9468348, 174.47409523999997, 246.53431776), + CubicToCommand(174.47409523999997, 246.53431776, 190.54147656999996, + 261.01261742, 191.95399360999997, 261.01261742), + CubicToCommand(193.36651065, 261.01261742, 214.20113698999998, + 265.95642706, 214.20113698999998, 265.95642706), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(184.00858526, 255.00942), + CubicToCommand(184.00858526, 255.00942, 216.49647718, 261.36574668000003, + 216.49647718, 269.1345904), + CubicToCommand(216.49647718, 274.2761524256, 216.06742512909997, + 297.9693601253, 206.60885789999998, 295.26615564), + CubicToCommand(191.77742897999997, 291.02860452, 198.13375565999996, + 265.6032978, 184.00858526, 255.00942), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(198.84001417999997, 261.71887594000003), + CubicToCommand(198.84001417999997, 261.71887594000003, 214.69198666139997, + 264.32143858620003, 216.49647717999997, 269.1345904), + CubicToCommand(217.55586495999995, 271.95962448, 218.72648845689997, + 286.6286139404, 209.08076271999997, 288.5566997), + CubicToCommand(201.04354076239994, 290.16520347930003, 197.10614951339997, + 272.118532647, 198.84001417999997, 261.71887594000003), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(350.67676774849997, 336.8453603587), + CubicToCommand(349.7992415374, 333.7696045041, 352.11400383669996, + 334.0009041694, 355.27627636, 333.05098646), + CubicToCommand(358.80756895999997, 331.99159868, 380.34845382, + 325.28214274, 381.76097086, 320.69146236), + CubicToCommand(383.1734879, 316.10078197999997, 406.48001905999996, + 323.86962570000003, 406.48001905999996, 323.86962570000003), + CubicToCommand(409.6581824, 325.28214274, 417.42702612, 329.87282312, + 417.42702612, 329.87282312), + CubicToCommand(425.90212836, 331.99159868, 437.55539394, 332.6978572, + 437.55539394, 332.6978572), + CubicToCommand(441.79294505999997, 334.4635035, 447.79614247999996, + 339.40731314, 447.79614247999996, 339.40731314), + CubicToCommand(473.57457846, 357.41690539999996, 495.4703582263, + 344.70425204, 495.4703582263, 344.70425204), + CubicToCommand(530.78151858, 333.05098646, 520.18764078, + 302.68187009999997, 520.18764078, 302.68187009999997), + CubicToCommand(514.89070188, 286.7910534, 520.54077004, + 280.78785597999996, 520.54077004, 280.78785597999996), + CubicToCommand(520.8938993, 274.07840003999996, 533.60655266, + 285.37853636, 533.60655266, 285.37853636), + CubicToCommand(538.19723304, 292.79425082, 539.60975008, + 301.62248231999996, 539.60975008, 301.62248231999996), + CubicToCommand(553.73492048, 321.39772087999995, 547.73172306, + 289.96921674, 547.73172306, 289.96921674), + CubicToCommand(548.08485232, 288.20357043999996, 543.14104268, + 281.84724375999997, 543.14104268, 279.7284682), + CubicToCommand(543.14104268, 277.60969264, 539.96287934, 271.60649522, + 539.96287934, 271.60649522), + CubicToCommand(534.66594044, 265.6032978, 538.90349156, 253.2437737, + 538.90349156, 253.2437737), + CubicToCommand(542.0816549, 228.87785476, 538.19723304, 232.0560181, + 538.19723304, 232.0560181), + CubicToCommand(536.07845748, 228.87785476, 519.83451152, 246.53431776, + 519.83451152, 246.53431776), + CubicToCommand(515.95008966, 252.53751517999999, 505.35621186000003, + 255.36254925999998, 505.35621186000003, 255.36254925999998), + CubicToCommand(500.4141678663, 258.5407126, 494.4109704463, 256.06880778, + 494.4109704463, 256.06880778), + CubicToCommand(489.8202900663, 255.36254925999998, 479.93267078630004, + 267.72207335999997, 479.93267078630004, 267.72207335999997), + CubicToCommand(484.87648042629996, 267.36894409999996, 489.1140315463, + 275.13778781999997, 493.35158266630003, 275.49091708), + CubicToCommand(497.58913378629995, 275.84404634, 500.76729712630004, + 271.25336596, 503.59056556, 270.19397818), + CubicToCommand(506.41559964, 269.1345904, 511.35940928, 279.37533894, + 511.35940928, 279.37533894), + CubicToCommand(512.0656678, 283.96601932, 502.17804852, 292.44112156, + 502.17804852, 292.44112156), + CubicToCommand(501.47179, 300.56309454, 498.6485215663, 297.73806046, + 498.6485215663, 297.73806046), + CubicToCommand(493.35158266630003, 296.67867268, 491.2328071063, + 303.38812862, 489.4671608063, 311.5101016), + CubicToCommand(487.7015145063, 319.63207458, 480.2858000463, 320.3383331, + 480.2858000463, 320.3383331), + CubicToCommand(477.4607659663, 333.40411572, 475.34022476, + 328.10717681999995, 475.34022476, 328.10717681999995), + CubicToCommand(474.9870955, 318.21955754, 464.39321770000004, + 328.46030608, 464.39321770000004, 328.46030608), + CubicToCommand(462.27444214, 331.99159868, 454.15246916, + 328.10717681999995, 454.15246916, 328.10717681999995), + CubicToCommand(442.14607432, 324.57588422, 446.38362544, 321.04459162, + 446.38362544, 321.04459162), + CubicToCommand(449.56178878, 317.16016976, 469.33702733999996, + 321.04459162, 469.33702733999996, 321.04459162), + CubicToCommand(473.2214492, 318.21955754, 459.0962788, 311.15697234, + 459.0962788, 311.15697234), + CubicToCommand(458.03689102, 307.97880899999996, 459.80253732, + 300.20996528, 459.80253732, 300.20996528), + CubicToCommand(461.92131288, 294.55989711999996, 473.92770772, + 284.67227784, 473.92770772, 284.67227784), + CubicToCommand(490.5265485863, 282.55350228, 485.58273894629997, + 279.72846819999995, 485.58273894629997, 279.72846819999995), + CubicToCommand(474.6357318863, 270.54710744, 464.39321770000004, + 283.96601932, 464.39321770000004, 283.96601932), + CubicToCommand(460.50879584, 294.91302637999996, 429.78655022, + 321.39772087999995, 429.78655022, 321.39772087999995), + CubicToCommand(421.31144798, 327.40091829999994, 425.90212836, + 315.39452345999996, 418.83954316, 321.39772087999995), + CubicToCommand(411.77695796, 327.40091829999994, 375.40464418, + 311.5101016, 375.40464418, 311.5101016), + CubicToCommand(354.9902416594, 309.4036855641, 350.16649596779996, + 337.19848961869997, 343.9355301751, 331.6896731627), + CubicToCommand(343.9355301751, 331.6896731627, 353.5018018285, + 346.7329796387, 350.67676774849997, 336.84536035869996), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(694.63349522, 43.13186400000001), + CubicToCommand(694.63349522, 43.13186400000001, 649.4329499400001, + 57.25703440000001, 644.4891402999999, 90.45118484), + CubicToCommand(644.4891402999999, 90.45118484, 640.2515891799999, + 130.70792047999998, 676.2707737, 161.78329536), + CubicToCommand(676.2707737, 161.78329536, 676.97703222, 173.08343168, + 680.50832482, 178.73349984), + CubicToCommand(680.50832482, 178.73349984, 677.6832907400001, + 187.20860208, 710.87744118, 173.7896902), + LineToCommand(758.9030205399999, 158.95826128), + CubicToCommand(758.9030205399999, 158.95826128, 770.20315686, + 154.72071016, 779.38451762, 139.18302272), + CubicToCommand(788.56587838, 123.64533528000001, 815.40370214, + 90.45118484000002, 809.04737546, 45.95689808000003), + CubicToCommand(809.04737546, 45.95689808000003, 811.1661510199999, + 26.18165952000001, 800.5722732199999, 25.475401000000005), + CubicToCommand(800.5722732199999, 25.475401000000005, 785.7408442999999, + 22.65036692000001, 773.02819094, 36.069278800000006), + CubicToCommand(773.02819094, 36.069278800000006, 761.0217960999998, + 41.719346960000024, 756.78424498, 41.01308843999999), + LineToCommand(694.63349522, 43.13186400000001), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(791.0730961259999, 41.383874163), + CubicToCommand(791.0730961259999, 41.383874163, 794.780953356, + 25.616652704000018, 786.235225264, 34.16238079600001), + CubicToCommand(786.235225264, 34.16238079600001, 773.8050753119999, + 44.261877631999994, 760.5980409879999, 44.261877631999994), + CubicToCommand(760.5980409879999, 44.261877631999994, 734.9608567119999, + 48.146299492000026, 727.192012992, 71.45283065200002), + CubicToCommand(727.192012992, 71.45283065200002, 720.2000536439999, + 118.84277734400001, 734.18397234, 128.94227418000003), + CubicToCommand(734.18397234, 128.94227418000003, 742.729700432, + 142.14930850400003, 755.1598503839999, 130.496042924), + CubicToCommand(767.590000336, 118.84277734399998, 794.9575179859999, + 65.467289695, 791.0730961259999, 41.383874163), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(790.4198069949999, 42.019506831), + CubicToCommand(790.4198069949999, 42.019506831, 794.1100077619999, + 26.570101706000003, 785.7231878369998, 34.97457809400001), + CubicToCommand(785.7231878369998, 34.97457809400001, 773.5049154409999, + 44.87985383700001, 760.5450715989999, 44.87985383700001), + CubicToCommand(760.5450715989999, 44.87985383700001, 735.366955361, + 48.69364984500001, 727.7393633449999, 71.57642589300002), + CubicToCommand(727.7393633449999, 71.57642589300002, 720.870999238, + 118.10826848320002, 734.6077274519998, 128.02413810400003), + CubicToCommand(734.6077274519998, 128.02413810400003, 742.9945473769999, + 140.99104453120003, 755.1951633099999, 129.54965650720004), + CubicToCommand(767.4134357059999, 118.10826848320002, 794.2336030029999, + 65.66151078800004, 790.4198069949999, 42.01950683100003), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(789.7488614009999, 42.655139499), + CubicToCommand(789.7488614009999, 42.655139499, 793.4214057049999, + 27.541207171000025, 785.193493947, 35.769118929), + CubicToCommand(785.193493947, 35.769118929, 773.222412033, + 45.497830042000004, 760.49210221, 45.497830042000004), + CubicToCommand(760.49210221, 45.497830042000004, 735.7730540099999, + 49.24100019800002, 728.2867136979999, 71.70002113400002), + CubicToCommand(728.2867136979999, 71.70002113400002, 721.559601295, + 117.3737596224, 735.0314825639999, 127.106002028), + CubicToCommand(735.0314825639999, 127.106002028, 743.2593943219999, + 139.8327805584, 755.2481326989998, 128.6032700904), + CubicToCommand(767.2192146129998, 117.3737596224, 793.492031557, + 65.85573188100003, 789.7488614009999, 42.655139499), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(789.0955722699999, 43.27311570399999), + CubicToCommand(789.0955722699999, 43.27311570399999, 792.7504601109999, + 28.49465617300001, 784.6638000569999, 36.581316227), + CubicToCommand(784.6638000569999, 36.581316227, 772.922252162, + 46.133462709999975, 760.421476358, 46.133462709999975), + CubicToCommand(760.421476358, 46.133462709999975, 736.196809122, + 49.80600701399999, 728.8517205139999, 71.84127283799998), + CubicToCommand(728.8517205139999, 71.84127283799998, 722.2305468889999, + 116.63925076159998, 735.455237676, 126.18786595199998), + CubicToCommand(735.455237676, 126.18786595199998, 743.5418977300001, + 138.6745165856, 755.283445625, 127.65688367359998), + CubicToCommand(767.042649983, 116.63925076159998, 792.768116574, + 66.04995297399998, 789.0955722699999, 43.27311570399999), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(788.442283139, 43.90874837199999), + CubicToCommand(788.442283139, 43.90874837199999, 792.079514517, + 29.465761638000004, 784.1517626299999, 37.375857061999994), + CubicToCommand(784.1517626299999, 37.375857061999994, 772.622092291, + 46.751438914999994, 760.3685069689999, 46.751438914999994), + CubicToCommand(760.3685069689999, 46.751438914999994, 736.6029077709999, + 50.353357367, 729.3990708669999, 71.96486807900001), + CubicToCommand(729.3990708669999, 71.96486807900001, 722.919148946, + 115.90474190079999, 735.8789927879999, 125.26972987599999), + CubicToCommand(735.8789927879999, 125.26972987599999, 743.8067446749999, + 137.51625261279997, 755.336415014, 126.71049725680001), + CubicToCommand(766.8484288899999, 115.90474190079999, 792.044201591, + 66.24417406700002, 788.442283139, 43.90874837199999), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(787.7713375449999, 44.54438103999999), + CubicToCommand(787.7713375449999, 44.54438103999999, 791.39091246, + 30.41921063999999, 783.6220687399999, 38.188054360000024), + CubicToCommand(783.6220687399999, 38.188054360000024, 772.3219324199999, + 47.36941512000001, 760.31553758, 47.36941512000001), + CubicToCommand(760.31553758, 47.36941512000001, 737.0090064199999, + 50.900707720000014, 729.9464212199999, 72.08846332000002), + CubicToCommand(729.9464212199999, 72.08846332000002, 723.5900945399999, + 115.17023304000003, 736.3027479, 124.35159380000002), + CubicToCommand(736.3027479, 124.35159380000002, 744.0715916199999, + 136.35798864, 755.37172794, 125.76411084), + CubicToCommand(766.6718642599999, 115.17023304, 791.302630145, + 66.43839516, 787.7713375449999, 44.54438103999999), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(414.24886277999997, 403.3237092), + CubicToCommand(414.24886277999997, 403.3237092, 378.22967825999996, + 369.42330024, 364.10450786, 368.0107832), + CubicToCommand(364.10450786, 368.0107832, 303.36627513999997, 360.948198, + 277.2347099, 392.72983139999997), + CubicToCommand(277.2347099, 392.72983139999997, 308.31008477999995, + 356.71064688, 357.04192265999995, 366.59826616), + CubicToCommand(357.04192265999995, 366.59826616, 318.90396258, + 358.82942244000003, 297.00994846, 364.4794906), + LineToCommand(250.39688614, 389.1985388), + LineToCommand(245.4530765, 397.67364104), + CubicToCommand(245.4530765, 397.67364104, 252.5156617, 371.5420758, + 285.00355362, 360.948198), + CubicToCommand(285.00355362, 360.948198, 325.26028926, 352.47309576, + 344.32926929999996, 360.948198), + CubicToCommand(344.32926929999996, 360.948198, 306.19130922, 348.94180316, + 288.53484621999996, 352.47309576), + CubicToCommand(288.53484621999996, 352.47309576, 234.85919869999998, + 348.23554464, 212.25892605999996, 394.84860696), + CubicToCommand(212.25892605999996, 394.84860696, 219.32151125999997, + 369.42330024, 245.45307649999998, 356.71064688), + CubicToCommand(245.45307649999998, 356.71064688, 269.46586618, + 341.17295944, 305.4850507, 346.11676908000004), + CubicToCommand(305.4850507, 346.11676908000004, 330.91035741999997, + 351.76683724000003, 340.09171818, 356.00438836), + CubicToCommand(349.27307894, 360.24193948000004, 347.15430338, + 355.29812984, 332.32287446, 346.8230276), + CubicToCommand(332.32287446, 346.8230276, 322.43525517999996, 329.1665646, + 297.71620698, 329.87282312), + CubicToCommand(297.71620698, 329.87282312, 222.14654534, 336.2291498, + 203.78382381999995, 357.4169054), + CubicToCommand(203.78382381999995, 357.4169054, 227.79661349999998, + 337.64166683999997, 246.15933501999996, 332.6978572), + CubicToCommand(246.15933501999996, 332.6978572, 285.70981213999994, + 318.5726868, 300.54124105999995, 319.98520384), + CubicToCommand(300.54124105999995, 319.98520384, 344.32926929999996, + 321.75085014, 357.74818117999996, 314.68826494), + CubicToCommand(357.74818117999996, 314.68826494, 337.97294261999997, + 323.51649643999997, 343.62301077999996, 329.1665646), + CubicToCommand(349.27307893999995, 334.81663276, 361.27947378, + 348.23554464, 361.27947378, 350.3543202), + CubicToCommand(361.27947378, 352.47309576, 404.00811423999994, + 391.49387899, 410.36444092, 399.26272271000005), + LineToCommand(414.24886277999997, 403.3237092), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(658.6143107, 745.8590914), + CubicToCommand(658.6143107, 745.8590914, 631.24679305, 681.41300145, + 609.1762143, 664.6393616), + CubicToCommand(609.1762143, 664.6393616, 655.0830181, 692.8897024, + 661.26278015, 724.6713358), + CubicToCommand(661.26278015, 724.6713358, 661.26278015, 742.3277988, + 658.6143107, 745.8590914), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(741.5996868, 759.10143865), + CubicToCommand(741.5996868, 759.10143865, 694.81005985, 661.99089215, + 662.1456033, 619.61538095), + CubicToCommand(662.1456033, 619.61538095, 738.95121735, 685.8271172, + 747.77944885, 732.61674415), + LineToCommand(748.662272, 742.3277988), + LineToCommand(743.3653331, 737.91368305), + CubicToCommand(743.3653331, 737.91368305, 742.4825099499999, 753.80449975, + 741.5996868, 759.10143865), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(841.35870275, 673.4675931), + CubicToCommand(841.35870275, 673.4675931, 731.005809, 568.41163825, + 728.35733955, 563.9975225000001), + CubicToCommand(728.35733955, 563.9975225000001, 835.1789407, 680.5301783, + 840.4758796, 693.77252555), + CubicToCommand(840.4758796, 693.77252555, 836.944587, 677.88170885, + 841.35870275, 673.4675931), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(508.5343752, 750.27320715), + CubicToCommand(508.5343752, 750.27320715, 542.96447805, 658.45959955, + 576.51175775, 698.1866413), + CubicToCommand(576.51175775, 698.1866413, 602.99645225, 715.8431043, + 602.1136291, 721.1400432), + CubicToCommand(602.1136291, 721.1400432, 595.0510439, 709.66334225, + 563.2694104999999, 710.5461654), + CubicToCommand(563.2694104999999, 710.5461654, 529.7221308, 705.2492265, + 508.5343752, 750.27320715), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(844.8899953499999, 525.1533039), + CubicToCommand(844.8899953499999, 525.1533039, 765.4359118499999, + 474.83238435, 752.1935646, 472.1839149), + CubicToCommand(731.341281797, 468.016989632, 839.59305645, 523.3876576, + 848.42128795, 541.92694375), + CubicToCommand(848.42128795, 541.92694375, 851.95258055, 537.512828, + 844.8899953499999, 525.1533039), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(578.80709794, 713.3711994800001), + CubicToCommand(578.80709794, 713.3711994800001, 614.82628246, + 709.8399068800001, 626.8326773, 697.8335120400001), + LineToCommand(634.6015210200001, 704.18983872), + LineToCommand(665.6768959, 636.3890208), + LineToCommand(672.03322258, 645.57038156), + CubicToCommand(672.03322258, 645.57038156, 697.4585293, 619.43881632, + 696.04601226, 605.31364592), + CubicToCommand(694.63349522, 591.18847552, 718.6462849, 615.90752372, + 718.6462849, 615.90752372), + CubicToCommand(718.6462849, 615.90752372, 717.23376786, 595.42602664, + 729.94642122, 607.4324214799999), + CubicToCommand(729.94642122, 607.4324214799999, 725.7088701, + 579.8883391999999, 740.54029902, 594.0135095999999), + CubicToCommand(740.54029902, 594.0135095999999, 721.9303870179999, + 540.761617192, 761.72805462, 586.24466588), + CubicToCommand(771.6156739, 597.5448021999999, 763.84683018, 585.53840736, + 763.84683018, 585.53840736), + CubicToCommand(763.84683018, 585.53840736, 717.94002638, + 500.78738495999994, 756.0779864599999, 526.2126916799999), + CubicToCommand(756.0779864599999, 526.2126916799999, 759.60927906, + 485.95595603999993, 757.4905034999999, 478.18711232), + CubicToCommand(755.37172794, 470.4182685999999, 751.84043534, + 430.86779147999994, 743.3653331, 421.68643072), + CubicToCommand(734.89023086, 412.5050699599999, 744.0715916199999, + 409.68003587999993, 753.9592109, 418.86139663999995), + CubicToCommand(753.9592109, 418.86139663999995, 734.18397234, + 376.48588543999995, 757.4905034999999, 397.67364103999995), + CubicToCommand(757.4905034999999, 397.67364103999995, 751.13417682, + 370.83581727999996, 743.3653331, 365.89200764), + CubicToCommand(743.3653331, 365.89200764, 733.47771382, + 335.52289127999995, 760.31553758, 354.59187131999994), + CubicToCommand(760.31553758, 354.59187131999994, 752.54669386, + 332.69785719999993, 746.8966257, 327.04778903999994), + CubicToCommand(746.8966257, 327.04778903999994, 726.4151286199999, + 278.31595115999994, 739.12778198, 286.79105339999995), + LineToCommand(746.8966257, 293.14738007999995), + CubicToCommand(746.8966257, 293.14738007999995, 734.89023086, + 268.42833188, 746.19036718, 276.1971755999999), + CubicToCommand(757.4905034999999, 283.96601931999993, 757.4905034999999, + 283.2597608, 757.4905034999999, 283.2597608), + CubicToCommand(757.4905034999999, 283.2597608, 720.05880194, + 224.64030363999996, 756.0779864599999, 255.71567851999995), + CubicToCommand(756.0779864599999, 255.71567851999995, 741.6703126519999, + 231.14141331659997, 735.59648938, 218.99023547999997), + CubicToCommand(735.59648938, 218.99023547999997, 702.4023389399999, + 182.97105095999996, 727.8276456599999, 194.27118727999994), + LineToCommand(736.3027479, 197.09622135999996), + CubicToCommand(736.3027479, 197.09622135999996, 720.76506046, + 179.43975835999993, 706.63989006, 176.61472427999996), + CubicToCommand(692.51471966, 173.78969019999994, 710.87744118, + 162.48955387999996, 722.1775775, 166.02084647999993), + CubicToCommand(733.47771382, 169.55213907999996, 761.0217961, + 182.97105095999996, 761.0217961, 182.97105095999996), + CubicToCommand(761.0217961, 182.97105095999996, 783.62206874, + 216.16520139999994, 790.68465394, 216.87145991999995), + CubicToCommand(790.68465394, 216.87145991999995, 755.37172794, + 203.45254803999995, 765.96560574, 217.57771843999996), + CubicToCommand(765.96560574, 217.57771843999996, 791.39091246, + 242.29676663999993, 778.6782591, 241.59050811999995), + CubicToCommand(778.6782591, 241.59050811999995, 768.0843812999999, + 254.30316147999994, 776.55948354, 269.8408489199999), + CubicToCommand(776.55948354, 269.8408489199999, 743.965652842, + 237.36884781669994, 770.20315686, 282.55350228), + LineToCommand(782.2095517, 311.5101015999999), + CubicToCommand(782.2095517, 311.5101015999999, 739.12778198, + 267.72207335999997, 758.9030205399999, 306.56629195999994), + CubicToCommand(758.9030205399999, 306.56629195999994, 789.2721369, + 348.23554463999994, 792.8034295, 348.94180315999995), + CubicToCommand(796.3347220999999, 349.64806167999996, 804.1035658199999, + 365.18574911999997, 804.1035658199999, 365.18574911999997), + LineToCommand(796.3347220999999, 361.65445651999994), + LineToCommand(805.51608286, 377.19214395999995), + CubicToCommand(805.51608286, 377.19214395999995, 785.7408442999999, + 356.00438835999995, 796.3347220999999, 379.31091951999997), + LineToCommand(806.22234138, 404.73622623999995), + CubicToCommand(806.22234138, 404.73622623999995, 770.20315686, + 365.89200764, 794.21594654, 418.15513811999995), + CubicToCommand(794.21594654, 418.15513811999995, 765.25934722, + 408.97377735999993, 780.79703466, 439.34289371999995), + CubicToCommand(780.79703466, 439.34289371999995, 777.97200058, + 467.59323451999995, 778.6782591, 476.77459527999997), + CubicToCommand(779.38451762, 485.95595603999993, 781.50329318, + 536.1003109599999, 773.73444946, 550.2254813599999), + CubicToCommand(765.9656057399999, 564.3506517599999, 784.3283272599999, + 598.2510607199999, 787.85961986, 605.3136459199999), + CubicToCommand(791.39091246, 612.3762311199999, 797.7472391399999, + 631.44521116, 782.2095517, 615.2012651999999), + CubicToCommand(766.6718642599999, 598.9573192399998, 774.44070798, + 608.8449385199999, 777.97200058, 624.3826259599999), + CubicToCommand(781.50329318, 639.9203133999998, 792.0971709800001, + 667.4643956799999, 790.68465394, 677.3520149599999), + CubicToCommand(790.68465394, 677.3520149599999, 788.56587838, + 679.4707905199998, 782.91581022, 673.1144638399999), + CubicToCommand(782.91581022, 673.1144638399999, 756.78424498, + 632.8577281999999, 759.6092790600001, 658.2830349199999), + CubicToCommand(759.6092790600001, 658.2830349199999, 757.4905035000002, + 672.4082053199999, 751.8404353400001, 687.9458927599999), + CubicToCommand(751.8404353400001, 687.9458927599999, 746.1903671800001, + 707.0148727999999, 746.1903671800001, 691.4771853599999), + CubicToCommand(746.1903671800001, 691.4771853599999, 740.54029902, + 661.8143275199999, 735.5964893800001, 675.2332393999999), + CubicToCommand(730.65267974, 688.65215128, 724.29635306, + 699.2460290799999, 719.3525434200001, 703.4835801999999), + CubicToCommand(714.4087337800001, 707.7211313199999, 705.2273730200001, + 667.4643956799999, 703.10859746, 685.8271171999999), + CubicToCommand(703.10859746, 685.8271171999999, 681.9208418600001, + 663.9331030799999, 673.44573962, 692.8897023999999), + LineToCommand(652.9642425400001, 721.8463017199998), + CubicToCommand(652.9642425400001, 721.8463017199998, 652.2579840200001, + 699.9522875999999, 650.1392084600002, 710.5461654), + CubicToCommand(650.1392084600002, 710.5461654, 597.1698194600001, + 721.1400431999999, 578.8070979400001, 713.37119948), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(518.06886522, 83.38859964), + CubicToCommand(518.06886522, 83.38859964, 497.58913378629995, 69.26342924, + 490.5265485863, 69.96968776), + CubicToCommand(483.46396338629995, 70.67594628000003, 539.25662082, + 54.432000320000014, 612.00124838, 103.16383820000001), + CubicToCommand(612.00124838, 103.16383820000001, 620.4763506200001, + 108.10764784, 626.8326773, 107.40138932000002), + CubicToCommand(626.8326773, 107.40138932000002, 632.4827454599999, + 111.63894044000003, 627.53893582, 117.99526712000002), + CubicToCommand(627.53893582, 117.99526712000002, 612.00124838, + 134.94547160000002, 631.77648694, 154.72071016), + CubicToCommand(631.77648694, 154.72071016, 664.2643788600001, 166.727105, + 654.37675958, 151.18941756), + CubicToCommand(654.37675958, 151.18941756, 673.44573962, 158.25200276, + 677.6832907400001, 165.31458796), + CubicToCommand(681.92084186, 172.37717316, 679.8020663, 165.31458796, + 679.8020663, 165.31458796), + LineToCommand(657.90805218, 143.42057384000003), + CubicToCommand(657.90805218, 143.42057384000003, 648.72669142, + 139.88928124000003, 643.78288178, 125.05785232000002), + CubicToCommand(638.83907214, 110.22642340000002, 634.6015210200001, + 92.56996040000001, 642.37036474, 86.91989224000002), + CubicToCommand(642.37036474, 86.91989224000002, 635.30777954, + 94.68873596000003, 636.72029658, 87.62615076000003), + CubicToCommand(638.13281362, 80.56356556000003, 644.4891403, + 74.20723888000003, 647.3141743799999, 73.50098036000003), + CubicToCommand(650.13920846, 72.79472184000002, 679.0958077800001, + 44.89751030000002, 691.1022026200001, 44.191251780000044), + CubicToCommand(691.1022026200001, 44.191251780000044, 674.85825666, + 46.663156600000065, 669.5613177600001, 44.89751030000005), + CubicToCommand(664.2643788600001, 43.131864000000064, 617.2981872800001, + 23.00349618000004, 606.7043094800001, 20.884720620000053), + CubicToCommand(606.7043094800001, 20.884720620000053, 577.0414516400001, + 9.231455040000071, 598.22920724, 12.762747640000072), + CubicToCommand(598.22920724, 12.762747640000072, 661.43934478, + 19.472203580000098, 693.57410744, 42.77873474000009), + CubicToCommand(693.57410744, 42.77873474000009, 680.86145408, + 27.947305820000054, 648.3735621600001, 15.587781720000066), + CubicToCommand(648.3735621600001, 15.587781720000066, 609.1762143000001, + -6.659361659999917, 547.02546454, 2.1688698400000703), + CubicToCommand(547.02546454, 2.1688698400000703, 515.5969604000001, + 7.81893800000006, 501.82491926000006, 10.997101340000086), + CubicToCommand(501.82491926000006, 10.997101340000086, 497.2360045263, + 9.937713560000077, 496.17661674630006, 9.231455040000071), + CubicToCommand(495.1172289663001, 8.525196520000065, 474.28083698000006, + -7.365620179999922, 425.54899910000006, 4.993903920000065), + CubicToCommand(425.54899910000006, 4.993903920000065, 395.5330120000001, + 13.115876900000046, 380.34845382000003, 21.590979140000087), + CubicToCommand(380.34845382000003, 21.590979140000087, 353.51063006000004, + 23.709754700000047, 347.15430338000004, 29.359822860000094), + CubicToCommand(347.15430338000004, 29.359822860000094, 314.31328220000006, + 55.13825884000008, 310.78198960000003, 56.55077588000009), + CubicToCommand(307.25069700000006, 57.96329292000013, 287.12232918000007, + 71.3822048000001, 285.70981214000005, 72.0884633200001), + CubicToCommand(285.70981214000005, 72.0884633200001, 329.14471112000007, + 60.43519774000009, 333.38226224000005, 56.197646620000086), + CubicToCommand(337.6198133600001, 51.96009550000008, 368.34205898000005, + 47.3694151200001, 372.5796101000001, 49.84131994000009), + CubicToCommand(376.81716122000006, 52.31322476000011, 391.64859014000007, + 51.2538369800001, 374.69838566000004, 52.31322476000011), + CubicToCommand(374.69838566000004, 52.31322476000011, 508.18124594000005, + 78.4447900000001, 509.59376298000006, 81.9760826000001), + CubicToCommand(511.0062800200001, 85.5073752000001, 518.06886522, + 83.38859964000011, 518.06886522, 83.38859964000011), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(644.13601104, 67.14465368), + CubicToCommand(644.13601104, 67.14465368, 626.12641878, 54.07887105999998, + 622.5951261800001, 54.07887105999998), + CubicToCommand(619.0638335799999, 54.07887105999998, 597.16981946, + 36.06927879999998, 589.754105, 36.775537319999984), + CubicToCommand(582.3383905400001, 37.48179583999999, 560.7975056800001, + 19.825332839999987, 512.4187970600001, 34.30363249999999), + CubicToCommand(512.4187970600001, 34.30363249999999, 511.35940928, + 30.77233989999999, 517.7157359600001, 29.35982285999998), + CubicToCommand(517.7157359600001, 29.35982285999998, 529.01587228, + 25.475401000000005, 529.7221308000001, 24.416013219999968), + CubicToCommand(529.7221308000001, 24.416013219999968, 565.38818606, + 17.000298759999993, 578.10083942, 23.356625439999988), + CubicToCommand(578.10083942, 23.356625439999988, 594.3447853800001, + 27.94730581999997, 605.2917924400001, 38.89431287999997), + CubicToCommand(605.2917924400001, 38.89431287999997, 625.067031, + 44.54438103999996, 630.7170991600001, 42.778734739999976), + CubicToCommand(630.7170991600001, 42.778734739999976, 646.2547866000001, + 46.66315659999998, 646.9610451200001, 49.84131993999998), + CubicToCommand(646.9610451200001, 49.84131993999998, 657.20179366, + 55.13825883999996, 654.02363032, 59.72893921999997), + CubicToCommand(654.02363032, 59.72893921999997, 654.7298888400001, + 62.55397329999997, 644.1360110400001, 67.14465367999998), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(622.118401679, 63.419139986999994), + CubicToCommand(623.5485751819999, 64.531497156, 625.349534408, + 64.708061786, 626.408922188, 66.138235289), + CubicToCommand(626.8326773, 66.685585642, 626.320639873, + 67.26824892100001, 625.7556330570001, 67.44481355100001), + CubicToCommand(623.9193609050001, 67.992163904, 622.047775827, + 66.98574551299998, 620.034939045, 68.02747682999998), + CubicToCommand(619.328680525, 68.398262553, 618.198666893, + 68.08044621900001, 617.2099049650001, 67.815599274), + CubicToCommand(614.331901496, 67.03871490199998, 611.100768767, + 66.98574551299998, 608.1168265199999, 68.20404145999998), + CubicToCommand(604.620846846, 66.208861141, 600.4539215780001, + 67.25059245799997, 596.7813772740001, 65.46728969499998), + CubicToCommand(596.675438496, 65.43197676899999, 596.28699631, + 66.03229651099997, 596.145744606, 65.99698358499998), + CubicToCommand(590.778179854, 63.96649033999998, 584.157006229, + 64.46087130399997, 579.86648572, 60.43519773999998), + CubicToCommand(575.575965211, 59.71128275699999, 571.426696406, + 58.89908545899996, 567.1361758969999, 57.69844597499997), + CubicToCommand(563.922699631, 56.79796636199998, 561.433138348, + 55.04997652499998, 558.572791342, 53.584490095999996), + CubicToCommand(556.136199448, 52.330881223000006, 553.576012313, + 51.41274514699998, 550.856917011, 50.74179955299999), + CubicToCommand(547.572814893, 49.94725871799997, 544.341682164, + 50.14147981099998, 541.004610657, 49.223343734999986), + CubicToCommand(540.828046027, 49.188030809, 540.49257323, + 49.78835055099998, 540.351321526, 49.75303762499999), + CubicToCommand(539.7863147099999, 49.55881653199998, 539.25662082, + 48.53474167799999, 538.956460949, 48.623023992999975), + CubicToCommand(535.990175165, 49.54116006899997, 533.359362178, + 47.82848315799998, 530.42838932, 48.428802899999994), + CubicToCommand(528.344926686, 46.27471441399999, 525.30801505, + 46.69846952599997, 522.571263285, 45.921585153999985), + CubicToCommand(517.3272937739999, 44.42078579899999, 511.7655079289999, + 46.66315659999998, 506.41559964, 44.89751029999999), + CubicToCommand(513.6724059329999, 41.64872110799996, 521.9532870799999, + 43.820466056999976, 529.1218110579999, 40.16557821599997), + CubicToCommand(533.2357669369999, 38.08211558199994, 537.932386095, + 40.02432651199996, 542.4700970859999, 38.682435323999954), + CubicToCommand(543.335263773, 38.417588378999966, 544.55355972, + 38.06445911899996, 545.25981824, 39.24744213999995), + CubicToCommand(545.5070087219999, 39.00025165799994, 545.8248250559999, + 38.59415300899994, 545.9307638339999, 38.629465934999956), + CubicToCommand(550.238940806, 40.67761564299997, 554.3352402219999, + 42.91998644399996, 558.7140430459999, 44.80922798499995), + CubicToCommand(559.3143627879999, 45.074074929999966, 560.26781179, + 44.65031981799996, 560.709223365, 45.02110554099997), + CubicToCommand(563.393005741, 47.157537563999966, 566.818359563, + 46.980972933999965, 569.2726079199999, 49.13506141999997), + CubicToCommand(572.27420663, 48.252238269999964, 575.434713507, + 48.92318386399995, 578.489281606, 47.810826694999975), + CubicToCommand(578.6305333099999, 47.775513768999986, 579.0366319589999, + 48.37583351099994, 579.089601348, 48.34052058499995), + CubicToCommand(581.1024381299999, 47.016285859999954, 583.132931375, + 47.49301036099996, 584.704356582, 48.02270425099994), + CubicToCommand(585.304676324, 48.234581806999955, 586.470002882, + 48.675993381999945, 587.017353235, 48.79958862299995), + CubicToCommand(588.994877091, 49.27631312399993, 590.5133329089999, + 50.123823347999945, 592.5967955429999, 50.45929614499994), + CubicToCommand(592.791016636, 50.49460907099993, 593.126489433, + 49.894289328999946, 593.2500846739999, 49.929602254999935), + CubicToCommand(595.22760853, 50.70648662699995, 597.063880682, + 50.61820431199996, 598.2292072399999, 52.66635401999994), + CubicToCommand(598.476397722, 52.419163537999935, 598.7589011299999, + 52.013064888999935, 598.900152834, 52.04837781499995), + CubicToCommand(600.7187685229999, 52.64869755699996, 601.866438618, + 53.99058874499994, 603.808649548, 54.41434385699995), + CubicToCommand(604.6561597719999, 54.59090848699995, 605.7508604779999, + 55.70326565599996, 606.757278869, 56.02108198999994), + CubicToCommand(610.9771735259999, 57.31000378899995, 614.243619181, + 60.01144262799997, 618.1103845779999, 61.58286783499997), + CubicToCommand(619.452275766, 62.13021818799996, 621.0060445099999, + 62.55397329999997, 622.1184016789999, 63.419139986999966), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(486.80986312479996, 38.29399313800002), + CubicToCommand(482.36396574139997, 35.257081502000005, 478.18291530299996, + 33.29721410900001, 473.8712070384, 30.13670723200002), + CubicToCommand(473.55162505809994, 29.90717321300002, 472.9159923901, + 30.207333084000027, 472.55933183749994, 29.995455528000008), + CubicToCommand(470.78132601339996, 28.91841128499999, 469.213432099, + 27.894336431000028, 467.4795674324, 26.658384021000046), + CubicToCommand(466.5278840767, 25.98743842700003, 465.0782884644, + 26.005094890000038, 464.181340144, 25.54602685200004), + CubicToCommand(459.6895359568, 23.268343125000058, 455.04765183409995, + 22.279581197000056, 450.62117656, 20.178462100000047), + CubicToCommand(451.8253473366, 19.04844846800009, 453.8064024852, + 19.48986004300008, 454.85872768, 18.059686540000087), + CubicToCommand(455.2030287085, 18.554067504000074, 455.62325252790004, + 19.04844846800009, 456.2465256718, 18.712975671000095), + CubicToCommand(459.2092801632, 17.12389400100008, 462.47572581820003, + 16.859047056000065, 465.434949017, 17.017955223000058), + CubicToCommand(468.4436103122, 17.17686339000008, 471.4805219482, + 17.706557280000055, 474.6145441307, 18.200938244000042), + CubicToCommand(475.1565975448, 18.27156409600002, 475.5079611585, + 19.189700172000045, 476.0782649134, 19.366264802000046), + CubicToCommand(480.0121248698, 20.53159136000002, 484.23025388049996, + 19.613455284000025, 487.9716583902, 21.096598176000015), + CubicToCommand(490.7808016535, 22.20895534500002, 493.5528663445, + 23.656785310999993, 495.7405021102, 25.899156112000014), + CubicToCommand(496.1854449778, 26.358224150000012, 495.6116099303, + 26.905574502999997, 495.1172289663, 27.24104730000002), + CubicToCommand(495.80229973070004, 27.04682620699998, 496.28432117060004, + 27.417611929999993, 496.48030790990003, 27.964962283000006), + CubicToCommand(496.62862219910005, 28.388717395000015, 496.62862219910005, + 28.91841128499999, 496.48030790990003, 29.342166397), + CubicToCommand(496.28255552430005, 29.889516750000013, 495.7899402066, + 30.066081379999986, 495.1295884904, 30.154363695), + CubicToCommand(492.6453241463, 30.489836491999995, 495.77404938990003, + 28.053244597999964, 494.53809697990005, 28.847785433000013), + CubicToCommand(492.29042924000004, 30.295615398999985, 493.60760137980003, + 32.767520219000005, 492.2921948863, 35.00989102), + CubicToCommand(491.79781392230007, 34.674418223, 491.3917152733, + 34.28597603699998, 491.5859363663, 33.597373979999986), + CubicToCommand(491.9990976005, 34.51551005599998, 490.93617852790004, + 35.027547483000006, 490.6395499495, 35.592554299), + CubicToCommand(489.959776124, 36.863819635, 488.37246010030003, + 39.37103738099998, 486.8098631248, 38.29399313799999), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(429.42988966739995, 51.271493443), + CubicToCommand(423.86104123719997, 49.876632865999994, 418.47582002219997, + 50.070853959000004, 413.15063078139997, 47.810826695), + CubicToCommand(413.03233247929995, 47.775513769000014, 412.6385933544, + 48.375833510999996, 412.5255919912, 48.34052058500001), + CubicToCommand(410.11371914539995, 47.28113280500003, 408.492855842, + 45.58611235700002, 406.59302042319996, 43.73218374200002), + CubicToCommand(404.9809853513, 42.160758535000014, 402.0535437859, + 42.84936059200001, 399.8041103997, 41.98419390500001), + CubicToCommand(399.2320409985, 41.77231634900002, 398.8736147996, + 40.871836736000034, 398.34215526329996, 40.80121088400003), + CubicToCommand(396.18983242359997, 40.51870747600003, 394.5530783035, + 38.84134349100003, 392.70797791999996, 37.83492509999999), + CubicToCommand(396.83252767679994, 36.42240806000001, 401.08950090609994, + 36.49303391199999, 405.43652209669995, 35.80443185499999), + CubicToCommand(405.6360401286, 35.769118929, 405.89205884209997, + 36.351782208, 406.12688979999996, 36.351782208), + CubicToCommand(406.36701769679996, 36.351782208, 406.59655171579993, + 35.945683559, 406.83314831999996, 35.71614954), + CubicToCommand(407.1774493485, 36.21053050399999, 407.7106745310999, + 36.79319378299999, 408.16444563019996, 36.334125744999994), + CubicToCommand(409.1320198026, 35.38067674299998, 410.11371914539995, + 35.71614954, 411.06716814739997, 35.78677539199998), + CubicToCommand(411.3214212145999, 35.80443185499999, 411.54212700209996, + 36.351782207999975, 411.77695795999995, 36.351782207999975), + CubicToCommand(412.01708585679995, 36.351782207999975, 412.24838552209997, + 35.78677539199998, 412.48321647999995, 35.78677539199998), + CubicToCommand(412.72334437679996, 35.78677539199998, 412.95464404209997, + 36.351782207999975, 413.18947499999996, 36.351782207999975), + CubicToCommand(413.42960289679996, 36.351782207999975, 413.65913691579993, + 35.945683558999974, 413.89573351999996, 35.716149539999975), + CubicToCommand(415.11756075959994, 37.09335365399997, 416.68015773509995, + 36.122248188999976, 418.13151899369996, 36.44006452299996), + CubicToCommand(419.9642598531, 36.82850670899998, 420.43568741519994, + 38.858999953999984, 422.33199154139993, 39.38869384399996), + CubicToCommand(430.65701384589994, 41.68403403399998, 437.96149258899993, + 45.48017357899997, 445.6650073958999, 49.17037434599999), + CubicToCommand(446.20706081, 49.417564827999996, 446.57784653299996, + 49.858976402999986, 446.38362543999995, 50.54757845999998), + CubicToCommand(446.8550530020999, 50.54757845999998, 447.40770029399994, + 50.38867029299999, 447.74317309099996, 50.61820431199999), + CubicToCommand(449.61122687639994, 51.92478257399998, 451.4492646747, + 52.87823157599999, 452.67992014579994, 54.82044250599998), + CubicToCommand(453.06129974659996, 55.42076224799999, 452.48040211389997, + 56.144677230999974, 452.06900652599995, 56.05639491599999), + CubicToCommand(444.24895906329994, 54.290748616, 437.17577998549996, + 53.213704372999985, 429.42988966739995, 51.271493443), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(404.9580319494, 129.3324820123), + CubicToCommand(402.14712303979996, 127.18015917260001, 401.11598560059997, + 123.5941315373, 399.12433657419996, 120.43009336770001), + CubicToCommand(398.746488266, 119.8297736257, 399.2302753522, + 119.27536068750001, 399.7899852293, 119.1182181668), + CubicToCommand(400.7787471573, 118.8374804051, 401.7374930982, + 119.68145933650001, 402.4596424349, 120.03811988910002), + CubicToCommand(405.54069522839995, 121.5601069997, 408.2509622989, + 123.75303970430002, 411.77695796, 123.99846454000001), + CubicToCommand(415.290594097, 127.94291837419999, 422.812247335, + 128.6226921997, 422.82460685909996, 134.59234234000002), + CubicToCommand(422.82637250539995, 136.10903251169998, 420.30502958899996, + 134.4881692083, 419.54580167999995, 136.00485938), + CubicToCommand(415.2182025987, 134.2339161411, 411.00007358799996, + 134.41577771, 406.797835394, 131.8255745879), + CubicToCommand(405.7084316269, 131.15286334759998, 406.29109490589997, + 130.3530255737, 404.9580319494, 129.33248201229998), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(356.33566413999995, 36.49303391199999), + CubicToCommand(356.57402639049997, 36.49303391199999, 368.9882855258, + 36.916789023999996, 368.9582695387, 37.11101011699998), + CubicToCommand(368.87881545519997, 37.65836046999999, 355.2303695562, + 39.51228908499999, 354.587674303, 39.21212921399999), + CubicToCommand(354.2981083098, 39.070877509999974, 341.03457330419997, + 43.36139801899998, 340.7979767, 43.13186399999998), + CubicToCommand(341.2711699084, 42.88467351799997, 355.8660022242, + 36.49303391199996, 356.33566414, 36.49303391199996), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(383.52661716, 53.72574180000001), + CubicToCommand(383.52661716, 53.72574180000001, 357.39505191999996, + 56.903905140000006, 349.6262082, 59.022680699999995), + CubicToCommand(341.85736448, 61.14145626000001, 309.01634329999996, + 74.56036814000001, 303.7194044, 78.09166074000001), + CubicToCommand(303.7194044, 78.09166074000001, 280.05974398, 87.62615076, + 250.04375688, 122.93907675999998), + CubicToCommand(250.04375688, 122.93907675999998, 263.46266876, + 116.93587933999999, 267.34709062, 111.99206969999997), + CubicToCommand(267.34709062, 111.99206969999997, 291.3598803, + 89.74492631999999, 291.00675104, 94.33560669999997), + CubicToCommand(291.00675104, 94.33560669999997, 312.5476359, + 79.15104851999999, 311.48824812, 83.03547037999996), + CubicToCommand(311.48824812, 83.03547037999996, 354.57001784, + 63.26023181999997, 351.03872523999996, 68.91029997999996), + CubicToCommand(351.03872523999996, 68.91029997999996, 389.17668532, + 60.78832699999998, 387.41103902, 64.31961959999998), + CubicToCommand(387.41103902, 64.31961959999998, 420.60518945999996, + 72.08846331999999, 415.66137982, 72.44159257999996), + CubicToCommand(415.66137982, 72.44159257999996, 405.42063128, + 74.56036813999998, 416.7207676, 80.91669481999998), + CubicToCommand(416.7207676, 80.91669481999998, 410.71757018, + 88.68553853999998, 401.18308016, 81.62295333999998), + CubicToCommand(391.64859013999995, 74.56036813999998, 396.94552904, + 78.44478999999998, 388.11729754, 80.21043629999997), + CubicToCommand(388.11729754, 80.21043629999997, 383.52661716, + 81.62295333999998, 375.40464418, 74.56036813999998), + CubicToCommand(375.40464418, 74.56036813999998, 365.51702489999997, + 66.43839516, 349.97933746, 72.79472183999997), + CubicToCommand(349.97933746, 72.79472183999997, 295.95056067999997, + 95.04186521999998, 292.41926808, 96.10125299999999), + CubicToCommand(292.41926808, 96.10125299999999, 286.0629414, + 101.04506263999997, 281.82539027999997, 107.40138931999999), + CubicToCommand(281.82539027999997, 107.40138931999999, 271.58464174, + 115.17023304, 266.28770283999995, 117.64213785999999), + CubicToCommand(266.28770283999995, 117.64213785999999, 243.6874302, + 138.12363494, 241.56865463999998, 140.59553975999998), + CubicToCommand(241.56865463999998, 140.59553975999998, 235.56545721999998, + 149.77690051999997, 234.15294017999997, 150.48315903999998), + CubicToCommand(234.15294017999997, 150.48315903999998, 245.45307649999995, + 143.77370309999998, 248.98436909999998, 140.24241049999998), + CubicToCommand(248.98436909999998, 140.24241049999998, 273.70341729999996, + 122.58594749999997, 283.23790732, 121.17343045999999), + CubicToCommand(283.23790732, 121.17343045999999, 291.00675104, + 115.87649155999998, 292.41926807999994, 113.40458673999998), + CubicToCommand(292.41926807999994, 113.40458673999998, 317.8445748, + 97.16064077999997, 325.26028926, 97.16064077999997), + CubicToCommand(325.26028926, 97.16064077999997, 341.50423521999994, + 106.34200153999998, 345.74178634, 93.98247743999997), + CubicToCommand(345.74178634, 93.98247743999997, 355.98253487999995, + 90.80431409999997, 365.87015415999997, 92.92308965999999), + CubicToCommand(365.87015415999997, 92.92308965999999, 371.52022231999996, + 88.33240928000001, 370.10770527999995, 84.44798742), + CubicToCommand(370.10770527999995, 84.44798742, 372.93273935999997, + 81.26982408, 374.69838566, 87.97928002), + CubicToCommand(374.69838566, 87.97928002, 380.70158308, 94.33560669999997, + 389.17668531999993, 90.80431409999997), + CubicToCommand(389.17668531999993, 90.80431409999997, 396.23927052, + 90.45118483999997, 392.70797791999996, 94.68873595999997), + CubicToCommand(392.70797791999996, 94.68873595999997, 384.93913419999996, + 101.39819189999997, 364.10450785999996, 101.75132115999997), + CubicToCommand(364.10450785999996, 101.75132115999997, 342.21049373999995, + 102.81070893999998, 313.25389441999994, 116.22962081999998), + CubicToCommand(313.25389441999994, 116.22962081999998, 260.63763467999996, + 134.59234234000002, 244.39368871999994, 152.95506386), + CubicToCommand(244.39368871999994, 152.95506386, 233.09355239999996, + 168.49275129999998, 223.55906237999997, 170.61152685999997), + CubicToCommand(223.55906237999997, 170.61152685999997, 213.31831383999997, + 172.02404389999998, 202.72443603999997, 185.08982651999997), + CubicToCommand(202.72443603999997, 185.08982651999997, 220.02776977999997, + 174.84907798, 235.91858647999996, 174.84907798), + CubicToCommand(235.91858647999996, 174.84907798, 242.98117167999996, + 170.61152686, 236.27171574, 176.96785354000002), + CubicToCommand(236.27171574, 176.96785354000002, 229.91538905999997, + 190.38676542000002, 232.74042313999996, 199.92125544), + CubicToCommand(232.74042313999996, 199.92125544, 231.68103535999995, + 209.1026162, 230.26851831999997, 211.92765028), + CubicToCommand(230.26851831999997, 211.92765028, 216.49647718, + 234.52792292, 216.49647718, 238.76547404000002), + CubicToCommand(216.49647718, 243.00302516, 218.61525274, 260.3063589, + 219.32151125999997, 261.36574668000003), + CubicToCommand(220.02776977999997, 262.42513446, 217.55586495999998, + 258.5407126, 224.26532089999998, 262.77826372), + CubicToCommand(230.97477683999998, 267.01581484, 235.91858648, + 269.84084892, 237.33110351999997, 274.78465856), + CubicToCommand(238.74362055999995, 279.7284682, 233.79981091999997, + 265.25016854, 233.44668165999997, 262.0720052), + CubicToCommand(233.09355239999996, 258.89384186, 225.67783793999996, + 246.1811885, 227.09035497999997, 241.94363738), + CubicToCommand(227.09035497999997, 241.94363738, 228.85600128, + 243.70928368, 230.26851831999994, 246.1811885), + CubicToCommand(230.26851831999994, 246.1811885, 229.20913053999996, + 245.12180072, 230.26851831999994, 238.76547404000002), + CubicToCommand(230.26851831999994, 238.76547404000002, 231.68103535999995, + 229.58411328, 234.15294017999997, 223.93404512), + CubicToCommand(236.624845, 218.28397696000002, 240.15613759999997, + 211.57452102000002, 240.86239611999997, 210.16200398), + CubicToCommand(241.56865463999998, 208.74948694, 241.56865463999998, + 198.5087384, 244.04055945999994, 203.09941878), + LineToCommand(250.04375687999993, 207.69009916), + CubicToCommand(250.04375687999993, 207.69009916, 245.09994723999995, + 203.09941878, 248.98436909999995, 199.21499692), + CubicToCommand(248.98436909999995, 199.21499692, 247.21872279999997, + 189.32737764, 250.39688613999994, 184.73669726000003), + CubicToCommand(250.39688613999994, 184.73669726000003, 262.7564102399999, + 169.90526834000002, 265.58144431999995, 168.13962204), + CubicToCommand(268.40647839999997, 166.37397574000002, 265.93457357999995, + 167.08023426, 265.93457357999995, 167.08023426), + CubicToCommand(265.93457357999995, 167.08023426, 276.52845138, + 159.6645198, 266.28770283999995, 162.48955388000002), + CubicToCommand(266.28770283999995, 162.48955388000002, 259.22511763999995, + 165.31458796, 253.92817873999996, 165.31458796), + CubicToCommand(253.92817873999996, 165.31458796, 240.50926685999997, + 168.84588056, 247.57185205999997, 161.4301661), + CubicToCommand(254.63443725999997, 154.01445164, 272.29090025999994, + 144.47996161999998, 279.00035619999994, 144.83309088000001), + LineToCommand(280.41287323999995, 147.65812496), + LineToCommand(300.18811179999994, 143.42057384000003), + LineToCommand(298.06933624, 144.83309088000001), + CubicToCommand(298.06933624, 144.83309088000001, 297.71620698, + 144.47996161999998, 305.13192144, 143.7737031), + CubicToCommand(312.54763589999993, 143.06744458000003, 322.78838443999996, + 145.5393494, 325.26028926, 142.36118606000002), + CubicToCommand(327.73219407999994, 139.18302272, 333.73539149999993, + 137.41737642, 333.02913298, 139.88928124), + CubicToCommand(332.32287446, 142.36118605999997, 331.9697452, + 145.89247866, 331.9697452, 145.89247866), + CubicToCommand(331.9697452, 145.89247866, 340.79797669999994, + 135.65173012, 339.73858892, 139.53615198), + CubicToCommand(338.67920114, 143.42057384, 324.20090147999997, + 152.6019346, 321.72899665999995, 163.54894166), + LineToCommand(340.09171818, 149.07064200000002), + LineToCommand(346.44804486, 143.7737031), + CubicToCommand(346.44804486, 143.7737031, 352.80437154, 147.65812496, + 353.1575008, 144.83309088000001), + CubicToCommand(353.51063006, 142.00805680000002, 361.63260303999994, + 131.76730826, 363.75137859999995, 132.12043752), + CubicToCommand(365.87015415999997, 132.47356678000003, 369.40144675999994, + 127.52975714000003, 369.04831749999994, 132.12043752), + CubicToCommand(368.69518824, 136.7111179, 382.11410012, 146.24560792, + 382.11410012, 146.24560792), + CubicToCommand(382.11410012, 146.24560792, 387.76416828, + 143.06744458000003, 390.2360731, 145.53934940000002), + CubicToCommand(392.70797791999996, 148.01125422, 400.12369237999997, + 110.57955266000002, 400.12369237999997, 110.57955266000002), + LineToCommand(444.26484988, 91.86370188000001), + LineToCommand(521.24702856, 85.86050446000002), + LineToCommand(491.23280710629996, 73.85410962), + LineToCommand(383.52661716, 53.72574180000001), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(415.66137982, 405.0893555), + CubicToCommand(415.66137982, 405.0893555, 389.17668532, 375.42649766, + 374.3452564, 370.83581728), + CubicToCommand(374.3452564, 370.83581728, 350.68559597999996, + 358.82942244000003, 307.250697, 372.60146358) + ], + ), + Path( + commands: const [ + MoveToCommand(368.69518824, 368.36391246), + CubicToCommand(368.69518824, 368.36391246, 324.20090147999997, + 354.23874206, 297.00994846, 361.65445652), + CubicToCommand(297.00994846, 361.65445652, 264.52205654, 365.18574912, + 249.69062762, 389.55166806) + ], + ), + Path( + commands: const [ + MoveToCommand(362.33886156, 366.24513690000003), + CubicToCommand(362.33886156, 366.24513690000003, 332.32287446, + 353.53248354, 306.19130922, 349.64806168), + CubicToCommand(306.19130922, 349.64806168, 276.88158064, 345.0573813, + 247.57185205999997, 357.77003466), + CubicToCommand(247.57185205999997, 357.77003466, 226.03096719999996, + 368.36391246, 216.49647717999997, 386.37350472) + ], + ), + Path( + commands: const [ + MoveToCommand(364.10450785999996, 366.95139542), + CubicToCommand(364.10450785999996, 366.95139542, 336.91355483999996, + 347.52928612, 335.14790854, 345.0573813), + CubicToCommand(335.14790854, 345.0573813, 322.78838443999996, 325.635272, + 299.83498254, 324.92901348), + CubicToCommand(299.83498254, 324.92901348, 262.05015172, 326.34153052, + 231.68103535999998, 340.46670092) + ], + ), + Path( + commands: const [ + MoveToCommand(361.8003394385, 351.0729382441), + CubicToCommand(364.5229660331, 353.656078781, 412.13008721999995, + 404.73622624, 412.13008721999995, 404.73622624), + CubicToCommand(474.28083698, 469.35888082, 424.84274058, 408.97377736, + 424.84274058, 408.97377736), + CubicToCommand(411.42382869999994, 400.49867512000003, 395.17988274, + 367.30452468, 395.17988274, 367.30452468), + CubicToCommand(393.06110717999996, 362.36071504, 419.89893093999996, + 380.01717804, 419.89893093999996, 380.01717804), + CubicToCommand(426.96151613999996, 381.42969508, 450.97430582, + 415.33010404000004, 450.97430582, 415.33010404000004), + CubicToCommand(438.96791098, 411.09255292, 447.44301322, 423.80520628, + 447.44301322, 423.80520628), + CubicToCommand(452.38682286, 427.33649888, 488.4077730263, 454.88058116, + 488.4077730263, 454.88058116), + CubicToCommand(494.76409970629993, 461.94316635999996, 501.82491926, + 464.76820044, 501.82491926, 464.76820044), + CubicToCommand(526.54396746, 455.58683967999997, 515.24383114, + 478.89337084, 515.24383114, 478.89337084), + CubicToCommand(519.4813822599999, 490.89976568, 529.36900154, 470.4182686, + 529.36900154, 470.4182686), + CubicToCommand(549.1442400999999, 440.75541076, 520.1876407799999, + 444.99296187999994, 520.1876407799999, 444.99296187999994), + CubicToCommand(467.21825177999995, 449.93677152, 455.21185693999996, + 421.68643072, 455.21185693999996, 421.68643072), + CubicToCommand(450.9743058199999, 417.44887959999994, 466.51199325999994, + 421.68643072, 466.51199325999994, 421.68643072), + CubicToCommand(481.34518782629993, 425.21772332, 453.79933989999995, + 399.79241659999997, 453.79933989999995, 399.79241659999997), + CubicToCommand(458.03689102, 399.79241659999997, 474.28083698, + 411.79881143999995, 474.28083698, 411.79881143999995), + CubicToCommand(492.64532414629997, 428.0427573999999, 496.17661674629994, + 424.51146479999994, 496.17661674629994, 424.51146479999994), + CubicToCommand(527.9564845, 408.97377736, 546.3192060199999, 422.39268924, + 546.3192060199999, 422.39268924), + CubicToCommand(549.8504986199999, 425.21772331999995, 539.96287934, + 437.22411816, 542.78791342, 446.40547891999995), + CubicToCommand(545.6129475, 455.5868396799999, 554.08804974, 477.4808538, + 554.08804974, 477.4808538), + CubicToCommand(549.8504986199999, 480.30588787999994, 550.55675714, + 499.37486791999993, 550.55675714, 499.37486791999993), + CubicToCommand(580.21961498, 540.3378620799999, 563.2694104999999, + 536.8065694799999, 563.2694104999999, 536.8065694799999), + CubicToCommand(535.7253282199999, 536.1003109599999, 561.8568934599999, + 549.5192228399999, 561.8568934599999, 549.5192228399999), + CubicToCommand(567.5069616199999, 553.0505154399999, 583.04464906, + 565.7631687999999, 583.04464906, 565.7631687999999), + CubicToCommand(578.1008394199998, 563.6443932399999, 575.2758053399999, + 572.825754, 575.2758053399999, 572.825754), + CubicToCommand(583.7509075799999, 579.8883391999999, 578.80709794, + 588.36344144, 578.80709794, 588.36344144), + CubicToCommand(568.2132201399999, 590.4822169999999, 566.09444458, + 597.5448021999999, 566.09444458, 597.5448021999999), + CubicToCommand(578.1008394199999, 611.6699725999999, 560.4443764199999, + 612.3762311199999, 560.4443764199999, 612.3762311199999), + CubicToCommand(566.8007031, 620.1450748399999, 558.3256008599999, + 641.33283044, 558.3256008599999, 641.33283044), + CubicToCommand(549.8504986199999, 641.33283044, 538.5503623, + 651.2204497199999, 538.5503623, 651.2204497199999), + CubicToCommand(542.78791342, 659.69555196, 524.4251919, 669.58317124, + 524.4251919, 669.58317124), + CubicToCommand(509.59376297999995, 672.4082053199999, 514.53757262, + 684.41460016, 514.53757262, 684.41460016), + CubicToCommand(500.4141678663, 695.0084779599999, 496.17661674629994, + 723.2588187599999, 496.17661674629994, 723.2588187599999), + CubicToCommand(494.76409970629993, 741.6215402799999, 490.52654858629995, + 747.2716084399999, 499.70790934629997, 743.7403158399999), + CubicToCommand(508.88750445999995, 740.20902324, 507.47498741999993, + 718.31500912, 507.47498741999993, 718.31500912), + CubicToCommand(499.00165082629997, 690.77092684, 574.5695468199999, + 662.52058604, 574.5695468199999, 662.52058604), + CubicToCommand(581.63213202, 659.69555196, 583.04464906, + 650.5141911999999, 583.04464906, 650.5141911999999), + CubicToCommand(586.5759416599999, 651.2204497199999, 602.1136291, + 664.6393615999999, 602.1136291, 664.6393615999999), + CubicToCommand(615.53254098, 684.41460016, 616.2387994999999, 668.1706542, + 616.2387994999999, 668.1706542), + CubicToCommand(618.3575750599999, 661.81432752, 615.53254098, + 651.2204497199999, 615.53254098, 651.2204497199999), + CubicToCommand(626.12641878, 613.08248964, 601.4073705799999, + 601.78235332, 601.4073705799999, 601.78235332), + CubicToCommand(583.75090758, 542.4566376399999, 608.46995578, + 557.28806656, 608.46995578, 557.28806656), + CubicToCommand(613.41376542, 567.17568584, 632.4827454599999, 576.3570466, + 632.4827454599999, 576.3570466), + LineToCommand(638.8390721399999, 572.11949548), + CubicToCommand(636.01403806, 563.64439324, 650.84546698, 553.05051544, + 650.84546698, 553.05051544), + CubicToCommand(655.78927662, 564.35065176, 666.38315442, 550.22548136, + 666.38315442, 550.22548136), + CubicToCommand(672.7394810999999, 507.14371164, 694.63349522, + 532.56901836, 694.63349522, 532.56901836), + CubicToCommand(701.69608042, 534.68779392, 703.81485598, 522.68139908, + 703.81485598, 522.68139908), + CubicToCommand(710.1711826599999, 504.31867755999997, 703.81485598, + 480.30588788, 703.81485598, 480.30588788), + CubicToCommand(710.1711826599999, 479.59962936, 727.12138714, + 490.19350715999997, 727.12138714, 490.19350715999997), + CubicToCommand(732.06519678, 483.83718048000003, 715.8212508199999, + 454.17432264, 722.88383602, 458.41187376), + CubicToCommand(729.9464212199999, 462.64942487999997, 737.71526494, + 465.47445896, 737.71526494, 465.47445896), + CubicToCommand(739.12778198, 461.94316635999996, 721.47131898, + 440.04915224, 721.47131898, 440.04915224), + CubicToCommand(713.70247526, 435.1053426, 704.5211145, 399.08615807999996, + 704.5211145, 399.08615807999996), + CubicToCommand(717.23376786, 405.44248475999996, 699.5773048599999, + 378.60466099999996, 699.5773048599999, 378.60466099999996), + CubicToCommand(699.5773048599999, 372.95459284, 710.1711826599999, + 353.17935428, 710.1711826599999, 353.17935428), + CubicToCommand(708.7586656199999, 341.17295944, 710.1711826599999, + 341.87921796, 710.1711826599999, 341.87921796), + CubicToCommand(715.1149923, 343.99799352, 729.2401626999999, 346.8230276, + 717.23376786, 335.52289127999995), + CubicToCommand(705.22737302, 324.22275496, 718.6462849, 315.74765272, + 718.6462849, 315.74765272), + CubicToCommand(726.4151286199999, 310.80384308, 702.4023389399999, + 311.5101016, 702.4023389399999, 311.5101016), + CubicToCommand(693.22097818, 303.74125788, 693.9272367, 296.67867268, + 693.9272367, 296.67867268), + CubicToCommand(708.0524071, 300.20996528, 682.62710038, + 274.78465855999997, 678.38954926, 268.42833188), + CubicToCommand(674.1519981399999, 262.0720052, 691.10220262, 252.89064444, + 691.10220262, 252.89064444), + CubicToCommand(714.4087337799999, 246.53431776, 693.9272366999999, + 240.8842496, 693.9272366999999, 240.8842496), + CubicToCommand(659.3205692199999, 241.59050811999998, 678.38954926, + 222.52152808, 678.38954926, 222.52152808), + CubicToCommand(688.9834270599999, 223.2277866, 686.1583929799999, + 218.99023548, 686.1583929799999, 218.99023548), + CubicToCommand(676.97703222, 216.87145992, 660.0268277399998, 205.5713236, + 660.0268277399998, 205.5713236), + CubicToCommand(652.9642425399999, 199.21499691999998, 659.3205692199999, + 200.62751396, 659.3205692199999, 200.62751396), + CubicToCommand(688.9834270599999, 202.74628952, 638.1328136199999, + 182.97105095999999, 638.1328136199999, 182.97105095999999), + CubicToCommand(652.2579840199999, 182.97105095999999, 620.47635062, + 164.60832943999998, 620.47635062, 164.60832943999998), + CubicToCommand(616.9450580199998, 161.78329535999998, 611.29498986, + 148.36438348000001, 611.29498986, 148.36438348000001), + CubicToCommand(600.7011120599999, 139.18302272, 592.22600982, + 127.17662788, 592.22600982, 127.17662788), + CubicToCommand(591.5197512999998, 119.40778415999998, 583.04464906, + 110.93268192, 583.04464906, 110.93268192), + CubicToCommand(562.5631519799999, 86.91989224, 552.6755327, + 87.62615075999997, 552.6755327, 87.62615075999997), + CubicToCommand(526.54396746, 81.26982408, 517.3626066999999, + 82.68234111999999, 517.3626066999999, 82.68234111999999), + LineToCommand(424.13648205999993, 90.45118484), + CubicToCommand(377.52341973999995, 113.05145747999998, 391.29546087999995, + 150.13002978, 391.29546087999995, 150.13002978), + CubicToCommand(402.59559719999993, 164.96145869999998, 418.83954315999995, + 158.25200275999998, 418.83954315999995, 158.25200275999998), + CubicToCommand(426.96151613999996, 147.3049957, 447.44301321999995, + 151.18941755999998, 447.44301321999995, 151.18941755999998), + CubicToCommand(483.46396338629995, 156.83948572, 478.87328300629997, + 150.48315904, 478.87328300629997, 150.48315904), + CubicToCommand(474.63573188629994, 142.36118606, 446.03049617999994, + 131.414179, 445.67736691999994, 130.35479121999998), + CubicToCommand(445.32423765999994, 129.29540343999997, 429.7865502199999, + 123.29220601999998, 429.7865502199999, 123.29220601999998), + CubicToCommand(424.48961131999994, 121.17343045999999, 416.72076759999993, + 104.92948449999997, 416.72076759999993, 104.92948449999997), + CubicToCommand(411.07069943999994, 98.92628707999998, 438.96791097999994, + 109.16703561999998, 438.96791097999994, 109.16703561999998), + CubicToCommand(436.8491354199999, 110.93268192, 449.91491804, + 117.99526712, 449.91491804, 117.99526712), + CubicToCommand(480.63892930629993, 116.22962081999998, 499.35478008629997, + 135.29860085999996, 499.35478008629997, 135.29860085999996), + CubicToCommand(518.42199448, 164.60832943999998, 518.7751237399999, + 150.13002977999997, 518.7751237399999, 150.13002977999997), + CubicToCommand(523.71893338, 133.53295455999998, 502.88430703999995, + 96.10125299999999, 502.88430703999995, 96.10125299999999), + CubicToCommand(503.59056555999996, 92.56996039999999, 518.0688652199999, + 104.22322597999997, 518.0688652199999, 104.22322597999997), + CubicToCommand(520.54077004, 100.69193337999997, 521.9532870799999, + 110.93268191999996, 521.9532870799999, 110.93268191999996), + CubicToCommand(522.3064163399999, 115.17023303999997, 529.0158722799999, + 129.29540343999997, 529.0158722799999, 129.29540343999997), + CubicToCommand(533.9596819199999, 152.24880534, 540.3160085999999, + 139.18302271999997, 540.3160085999999, 139.18302271999997), + LineToCommand(548.4379815799999, 155.78009793999996), + CubicToCommand(550.9098864, 160.37077831999997, 540.3160085999999, + 173.78969019999994, 540.3160085999999, 173.78969019999994), + CubicToCommand(539.96287934, 178.73349983999995, 541.37539638, + 178.38037057999998, 531.4877770999999, 191.79928245999997), + CubicToCommand(521.6001578199999, 205.21819433999997, 527.6033552399999, + 212.98703805999997, 527.6033552399999, 212.98703805999997), + CubicToCommand(525.13145042, 224.64030363999996, 540.66913786, + 223.93404511999995, 540.66913786, 223.93404511999995), + CubicToCommand(545.25981824, 227.81846697999995, 551.26301566, + 227.81846697999995, 551.26301566, 227.81846697999995), + CubicToCommand(554.4411789999999, 231.34975957999995, 558.67873012, + 230.29037179999995, 558.67873012, 230.29037179999995), + CubicToCommand(561.5037642, 223.58091585999995, 572.45077126, + 227.11220845999995, 572.45077126, 227.11220845999995), + CubicToCommand(574.92267608, 222.87465733999994, 589.4009757399999, + 222.16839881999996, 589.4009757399999, 222.16839881999996), + CubicToCommand(591.16662204, 217.57771843999996, 591.8728805599999, + 214.75268435999996, 597.87607798, 213.69329657999995), + CubicToCommand(603.8792754, 212.63390879999997, 560.44437642, + 136.71111789999998, 560.44437642, 136.71111789999998), + CubicToCommand(571.74451274, 135.29860085999996, 557.2662130799999, + 113.40458673999996, 557.2662130799999, 113.40458673999996), + CubicToCommand(553.38179122, 101.75132115999995, 573.51015904, + 127.52975713999994, 577.3945808999999, 130.00166195999998), + CubicToCommand(581.27900276, 132.47356677999997, 583.04464906, + 136.35798863999995, 580.21961498, 136.00485937999997), + CubicToCommand(577.3945808999999, 135.65173012, 574.21641756, + 139.53615197999997, 576.6883223799999, 139.88928123999997), + CubicToCommand(579.1602272, 140.24241049999998, 602.1136291, 166.727105, + 608.1168265199999, 184.73669725999997), + CubicToCommand(614.12002394, 202.74628951999995, 624.71390174, + 209.80887471999998, 635.6609088, 220.40275251999998), + CubicToCommand(646.6079158599999, 230.99663031999998, 645.19539882, + 273.72527077999996, 645.19539882, 273.72527077999996), + CubicToCommand(644.4891402999999, 289.26295822, 655.0830181, + 307.97880899999996, 655.0830181, 307.97880899999996), + CubicToCommand(658.6143107, 314.68826493999995, 651.1985962399999, + 346.8230276, 651.1985962399999, 346.8230276), + CubicToCommand(647.66730364, 350.70744945999996, 650.13920846, + 352.1199665, 650.13920846, 352.1199665), + CubicToCommand(651.90485476, 354.23874206, 663.9112496, + 377.54527321999996, 663.9112496, 377.54527321999996), + CubicToCommand(660.7330862599999, 377.19214395999995, 667.0894129400001, + 383.54847064, 667.0894129400001, 383.54847064), + CubicToCommand(676.2707737000001, 394.14234844, 664.9706373800001, + 388.84540954, 664.9706373800001, 388.84540954), + CubicToCommand(654.37675958, 386.02037545999997, 666.73628368, + 403.32370919999994, 666.73628368, 403.32370919999994), + CubicToCommand(668.8550592400001, 406.50187253999997, 652.96424254, + 398.37989956, 652.96424254, 398.37989956), + CubicToCommand(636.7202965800001, 397.32051178, 657.20179366, + 410.03316513999994, 657.20179366, 410.03316513999994), + CubicToCommand(672.3863518400001, 422.7458185, 652.2579840200001, + 414.97697478, 652.2579840200001, 414.97697478), + CubicToCommand(644.1360110400001, 411.79881144, 649.7860792, 423.80520628, + 649.7860792, 423.80520628), + CubicToCommand(655.43614736, 426.63024035999996, 685.8052637200001, + 438.98976445999995, 685.8052637200001, 438.98976445999995), + CubicToCommand(686.51152224, 445.69922039999994, 681.21458334, + 454.52745189999996, 681.21458334, 454.52745189999996), + CubicToCommand(681.9208418600001, 461.59003709999996, 678.03642, + 467.59323451999995, 678.03642, 467.59323451999995), + CubicToCommand(675.91764444, 482.07153417999996, 674.85825666, + 483.48405121999997, 674.85825666, 483.48405121999997), + CubicToCommand(667.4425422, 483.8371804799999, 654.37675958, + 508.20309941999994, 654.37675958, 508.20309941999994), + CubicToCommand(651.1985962399999, 512.7937797999999, 633.18900398, + 533.9815354, 633.18900398, 533.9815354), + CubicToCommand(629.65771138, 546.3410594999999, 597.87607798, + 533.6284061399999, 597.87607798, 533.6284061399999), + CubicToCommand(586.2228124000001, 539.63160356, 589.754105, + 533.6284061399999, 589.754105, 533.6284061399999), + CubicToCommand(589.0478464800001, 529.74398428, 597.52294872, + 519.15010648, 597.52294872, 519.15010648), + CubicToCommand(609.88247282, 514.5594261, 605.2917924400001, + 495.49044605999995, 605.2917924400001, 495.49044605999995), + CubicToCommand(612.35437764, 493.01854124, 592.57913908, 488.0747316, + 592.9322683400001, 485.95595604), + CubicToCommand(593.2853976, 483.8371804799999, 603.52614614, + 481.36527565999995, 603.52614614, 481.36527565999995), + CubicToCommand(617.65131654, 477.83398306, 609.88247282, 473.59643194, + 609.88247282, 473.59643194), + CubicToCommand(608.82308504, 466.53384673999994, 614.12002394, + 456.64622746, 614.12002394, 456.64622746), + CubicToCommand(634.6015210200001, 455.23371041999997, 614.12002394, + 426.63024036, 614.12002394, 426.63024036), + CubicToCommand(595.0510439, 413.21132848, 593.2853976, 402.97057994, + 593.2853976, 402.97057994), + CubicToCommand(615.53254098, 388.49228027999993, 601.0542413200001, + 366.59826616, 601.40737058, 360.24193948), + CubicToCommand(601.76049984, 353.8856128, 603.8792754000001, + 315.74765271999996, 603.8792754000001, 315.74765271999996), + CubicToCommand(600.3479828, 304.80064566, 595.0510439, 280.78785597999996, + 595.0510439, 280.78785597999996), + CubicToCommand(598.9354657599999, 271.60649521999994, 612.00124838, + 249.35935183999996, 612.00124838, 249.35935183999996), + CubicToCommand(616.94505802, 241.94363737999996, 632.4827454599999, + 233.46853513999997, 628.5983236, 228.17159623999996), + CubicToCommand(624.71390174, 222.87465733999997, 610.9418606, + 226.05282067999997, 610.9418606, 226.05282067999997), + CubicToCommand(597.16981946, 223.58091585999998, 598.22920724, + 232.76227661999997, 598.22920724, 232.76227661999997), + CubicToCommand(595.40417316, 234.52792291999998, 593.99165612, + 243.35615441999997, 593.99165612, 243.35615441999997), + CubicToCommand(592.7203907840001, 257.3630265179, 577.0414516400001, + 268.42833188, 577.0414516400001, 268.42833188), + CubicToCommand(557.26621308, 279.37533893999995, 573.5101590400001, + 286.43792413999995, 573.5101590400001, 286.43792413999995), + CubicToCommand(584.10403684, 298.09118972, 566.8007031, + 298.44431897999993, 566.8007031, 298.44431897999993), + CubicToCommand(547.3785938000001, 295.26615563999997, 561.85689346, + 313.27574789999994, 561.85689346, 313.27574789999994), + CubicToCommand(580.9258735000001, 335.87602053999996, 575.6289346000001, + 340.81983017999994, 575.6289346000001, 340.81983017999994), + CubicToCommand(557.61934234, 342.58547647999995, 579.86648572, + 358.82942244, 579.86648572, 358.82942244), + CubicToCommand(579.86648572, 358.82942244, 578.45396868, 355.29812984, + 578.8070979400001, 358.47629317999997), + CubicToCommand(579.1602272, 361.65445651999994, 584.4571661, + 369.07017097999994, 585.86968314, 372.60146358), + CubicToCommand(587.28220018, 376.13275618, 580.2196149800001, + 376.48588543999995, 580.2196149800001, 376.48588543999995), + CubicToCommand(581.2790027600001, 393.43608992, 554.0880497400001, + 386.02037545999997, 554.0880497400001, 386.02037545999997), + LineToCommand(551.2630156600001, 386.37350472), + CubicToCommand(548.43798158, 386.72663398, 528.6627430200001, + 385.31411693999996, 518.4219944800001, 381.42969508), + CubicToCommand(508.18124594000005, 377.54527322, 496.17661674630006, + 377.54527322, 496.17661674630006, 377.54527322), + CubicToCommand(496.17661674630006, 377.54527322, 489.11403154630005, + 380.72343656, 475.6933540200001, 380.3703073), + CubicToCommand(462.2744421400001, 380.01717804, 448.1492717400001, + 384.96098767999996, 448.1492717400001, 384.96098767999996), + CubicToCommand(440.38042802000007, 384.25472915999995, 455.5649862000001, + 376.48588543999995, 455.9181154600001, 376.8390147), + CubicToCommand(456.2712447200001, 377.19214395999995, 466.1588640000001, + 367.30452468, 452.0336936000001, 368.36391246), + CubicToCommand(413.5479011989001, 371.2507441605, 394.4736242200001, + 353.17935428, 394.4736242200001, 353.17935428), + CubicToCommand(390.94233162000006, 350.70744946, 386.3516512400001, + 345.76363982, 386.3516512400001, 345.76363982), + CubicToCommand(368.69518824000005, 342.23234721999995, 388.8235560600001, + 367.65765394, 388.8235560600001, 367.65765394), + CubicToCommand(390.94233162000006, 370.12955876, 388.47042680000004, + 371.89520505999997, 388.47042680000004, 371.89520505999997), + CubicToCommand(387.0579097600001, 369.07017098, 373.2858686200001, + 359.53568096, 373.2858686200001, 359.53568096), + CubicToCommand(368.3226368707001, 357.8177071101, 365.9160609638001, + 355.4623349459, 361.80033943850003, 351.0729382441), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(319.6102211, 330.57908164), + CubicToCommand(319.6102211, 330.57908164, 340.09171818, 340.46670092, + 344.68239855999997, 345.41051056), + CubicToCommand(349.27307893999995, 350.35432019999996, 373.99212714, + 370.48268802, 373.99212714, 370.48268802), + CubicToCommand(373.99212714, 370.48268802, 364.45763711999996, + 366.95139542, 359.86695674, 363.77323208), + CubicToCommand(355.27627636, 360.59506874, 336.20729631999995, + 346.11676908, 336.20729631999995, 346.11676908), + CubicToCommand(336.20729631999995, 346.11676908, 329.49784037999996, + 335.52289128, 319.6102211, 330.57908164), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(217.18684488329995, 275.4962140189), + CubicToCommand(217.78186768639998, 275.23489836650003, 216.85666902519998, + 270.4464656009, 216.49647718, 269.48771966), + CubicToCommand(214.6919866614, 264.6745678462, 198.84001417999997, + 262.0720052, 198.84001417999997, 262.0720052), + CubicToCommand(198.43921246989996, 264.4821123995, 198.34210192339998, + 267.30008389430003, 198.52926043119996, 270.1922125337), + CubicToCommand(198.52926043119996, 270.1922125337, 207.12442661959994, + 279.9368144634, 217.18684488329995, 275.4962140189), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(217.18684488329995, 275.1430847589), + CubicToCommand(216.39406969459998, 275.4220568743, 217.16036018879998, + 270.31580777470003, 216.84960643999997, 269.48771966), + CubicToCommand(215.04511592139997, 264.67456784620003, 198.84001417999997, + 261.89544057, 198.84001417999997, 261.89544057), + CubicToCommand(198.43921246989996, 264.3055477695, 198.34210192339998, + 267.1235192643, 198.52926043119996, 270.0156479037), + CubicToCommand(198.52926043119996, 270.0156479037, 206.06503883959996, + 279.0539913134, 217.18684488329995, 275.1430847589), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(209.43389197999997, 275.3955721798), + CubicToCommand(208.33036304249998, 275.3955721798, 207.43694601469997, + 273.3827353978, 207.43694601469997, 270.9002367), + CubicToCommand(207.43694601469997, 268.4195036485, 208.33036304249998, + 266.4066668665, 209.43389197999997, 266.4066668665), + CubicToCommand(210.53742091749996, 266.4066668665, 211.43260359159996, + 268.4195036485, 211.43260359159996, 270.9002367), + CubicToCommand(211.43260359159996, 273.3827353978, 210.53742091749996, + 275.3955721798, 209.43389197999997, 275.3955721798), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(209.43389197999997, 270.9002367), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(128.92042069999997, 448.52425447999997), + CubicToCommand(128.92042069999997, 448.52425447999997, 119.03280142, + 466.18071748, 162.82082966, 455.58683968), + CubicToCommand(162.82082966, 455.58683968, 187.53987786, 453.46806412, + 191.77742897999997, 449.230513), + CubicToCommand(193.89620453999999, 450.64303004, 208.6676014858, + 455.816373699, 213.67144309999998, 456.99935672000004), + CubicToCommand(225.67783793999996, 459.8243908, 240.50926685999997, + 442.16792780000003, 240.50926685999997, 442.16792780000003), + CubicToCommand(240.50926685999997, 442.16792780000003, 248.63123983999998, + 423.62864165, 253.57504947999996, 423.62864165), + CubicToCommand(258.51885911999995, 423.62864165, 252.86879095999996, + 426.45367573, 252.86879095999996, 426.45367573), + CubicToCommand(252.86879095999996, 426.45367573, 241.21552537999997, + 444.28670336, 241.92178389999995, 447.11173744), + CubicToCommand(241.92178389999995, 447.11173744, 232.74042313999996, + 482.42466344, 204.49008233999996, 483.83718048000003), + CubicToCommand(204.49008233999996, 483.83718048000003, 175.97489459499994, + 485.514544465, 178.35851709999994, 495.84357532), + CubicToCommand(178.35851709999994, 495.84357532, 193.89620453999996, + 491.6060242, 198.13375565999996, 495.84357532), + CubicToCommand(198.13375565999996, 495.84357532, 217.20273569999995, + 495.1373168, 203.07756529999995, 506.43745312), + LineToCommand(191.07117045999996, 526.9189502), + CubicToCommand(191.07117045999996, 526.9189502, 191.31836094199997, + 533.840283696, 173.41470745999996, 527.62520872), + CubicToCommand(156.11137371999996, 521.6220113, 137.92521682999995, + 498.84517403, 137.92521682999995, 498.84517403), + CubicToCommand(137.92521682999995, 498.84517403, 109.76315834499997, + 473.15502036500004, 128.92042069999997, 448.52425447999997), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(126.80164513999998, 455.58683968), + CubicToCommand(126.80164513999998, 455.58683968, 123.27035253999998, + 472.53704416, 188.24613637999997, 454.17432264), + LineToCommand(200.25253121999998, 455.58683968), + CubicToCommand(204.49008233999996, 456.99935672, 225.67783793999996, + 461.94316635999996, 229.20913053999996, 459.8243908), + CubicToCommand(229.20913053999996, 459.8243908, 216.49647717999994, + 483.83718048000003, 196.01498009999995, 481.0121464), + CubicToCommand(196.01498009999995, 481.0121464, 172.70844893999995, + 483.83718048000003, 173.41470745999996, 492.31228272), + CubicToCommand(173.41470745999996, 492.31228272, 180.47729265999996, + 505.02493608, 188.95239489999994, 509.2624872), + CubicToCommand(188.95239489999994, 509.2624872, 193.89620453999996, + 513.50003832, 193.18994601999995, 519.15010648), + CubicToCommand(192.48368749999997, 524.80017464, 187.53987785999996, + 527.62520872, 184.00858525999996, 529.03772576), + CubicToCommand(180.47729265999996, 530.4502428, 174.82722449999994, + 524.80017464, 172.00219041999995, 524.80017464), + CubicToCommand(169.17715633999998, 524.80017464, 154.34572741999997, + 513.5000383199999, 146.57688369999994, 505.02493608), + CubicToCommand(138.80803997999993, 496.54983384, 123.97661105999995, + 475.36207823999996, 124.68286957999993, 470.41826860000003), + CubicToCommand(125.38912809999994, 465.47445896, 126.80164513999995, + 455.58683968, 126.80164513999995, 455.58683968), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(132.45171329999997, 486.397367615), + CubicToCommand(137.04239367999998, 493.3716705, 142.69246183999996, + 500.78738496000005, 146.57688369999997, 505.0249360800001), + CubicToCommand(154.34572741999997, 513.50003832, 169.17715633999998, + 524.80017464, 172.00219041999998, 524.80017464), + CubicToCommand(174.8272245, 524.80017464, 180.47729266, 530.4502428, + 184.00858526, 529.0377257600001), + CubicToCommand(187.53987786, 527.62520872, 192.48368749999997, + 524.80017464, 193.18994601999998, 519.1501064800001), + CubicToCommand(193.89620453999999, 513.50003832, 188.95239489999997, + 509.26248720000007, 188.95239489999997, 509.26248720000007), + CubicToCommand(183.53892334419996, 506.5610483610001, 178.70105248219997, + 500.39894277400003, 175.91309697449998, 496.2849868950001), + CubicToCommand(175.91309697449998, 496.2849868950001, 176.23974153999998, + 500.78738496000005, 167.05838077999996, 499.37486792000004), + CubicToCommand(157.87702001999997, 497.96235088000003, 148.69565925999996, + 493.0185412400001, 145.87062517999996, 487.36847308000006), + CubicToCommand(143.04559109999997, 481.71840492, 138.80803997999996, + 477.4808538000001, 141.63307405999996, 483.83718048000003), + CubicToCommand(144.45810813999995, 490.19350716, 148.69565925999996, + 496.54983384, 151.52069333999995, 497.25609236), + CubicToCommand(154.34572741999995, 497.96235088000003, 153.63946889999994, + 500.08112644000005, 149.40191777999993, 499.37486792000004), + CubicToCommand(145.16436665999993, 498.66860940000004, 140.22055701999994, + 497.96235088000003, 132.45171329999994, 488.78099012), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(127.86103291999999, 449.230513), + CubicToCommand(127.86103291999999, 449.230513, 131.03919625999998, + 425.21772332, 133.15797182, 418.15513812), + CubicToCommand(133.15797182, 418.15513812, 131.74545478, 406.14874328, + 135.98300589999997, 398.73302882), + CubicToCommand(140.22055701999997, 391.31731436, 143.75184961999997, + 380.37030730000004, 149.04878852, 370.83581728), + CubicToCommand(154.34572741999997, 361.30132726000005, 154.69885667999998, + 354.23874206000005, 161.76144187999998, 351.41370798), + CubicToCommand(168.82402707999998, 348.5886739, 179.41790487999998, + 333.40411572000005, 184.36171452, 331.63846942000004), + CubicToCommand(189.30552415999998, 329.87282312, 188.95239489999997, + 331.28534016000003, 188.95239489999997, 331.28534016000003), + CubicToCommand(188.95239489999997, 331.28534016000003, 200.95878974, + 305.15377492, 224.97157941999996, 312.21636012), + CubicToCommand(224.97157941999996, 312.21636012, 196.36810935999998, + 307.27255048, 224.26532089999998, 290.67547526000004), + CubicToCommand(224.26532089999998, 290.67547526000004, 215.79021866, + 292.61768619000003, 221.61685144999996, 280.25816209000004), + CubicToCommand(225.50303895629997, 272.01612516160003, 224.61845015999998, + 283.96601932, 205.19634085999996, 304.80064566), + CubicToCommand(205.19634085999996, 304.80064566, 196.36810935999998, + 319.98520384, 187.1867486, 325.28214274000004), + CubicToCommand(178.00538783999997, 330.57908164, 156.81763223999997, + 342.93860574, 154.69885667999998, 349.64806168), + CubicToCommand(152.58008111999996, 356.35751762, 146.93001295999994, + 366.59826616000004, 143.39872035999994, 369.42330024), + CubicToCommand(139.86742775999997, 372.24833432, 134.92361811999996, + 379.66404878000003, 134.21735959999995, 385.6672462), + CubicToCommand(134.21735959999995, 385.6672462, 132.09858403999993, + 392.7298314, 129.62667921999997, 394.84860696000004), + CubicToCommand(127.15477439999998, 396.96738252, 126.80164513999998, + 402.61745068000005, 126.80164513999998, 406.1487432800001), + CubicToCommand(126.80164513999998, 409.68003588000005, 123.27035253999998, + 414.62384552000003, 123.62348179999998, 418.86139664000007), + CubicToCommand(123.62348179999998, 418.86139664000007, 125.03599883999996, + 452.40867634000006, 124.32974031999998, 455.9399689400001), + LineToCommand(127.86103291999999, 449.2305130000001), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(112.67647473999997, 457.35248598), + CubicToCommand(112.67647473999997, 457.35248598, 109.14518213999997, + 454.88058116, 101.37633841999997, 465.47445896), + CubicToCommand(101.37633841999997, 465.47445896, 114.26555640999996, + 523.74078686, 114.26555640999996, 526.21269168), + CubicToCommand(114.26555640999996, 526.21269168, 116.20776733999995, + 522.50483445, 113.91242714999996, 509.79218109), + CubicToCommand(111.61708695999997, 497.07952772999994, 110.02800528999995, + 474.65581971999995, 110.02800528999995, 474.65581971999995), + LineToCommand(112.67647473999995, 457.35248598), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(150.81443481999997, 350.3543202), + CubicToCommand(150.81443481999997, 350.3543202, 119.73905994, + 356.00438836, 120.44531845999998, 407.56126032), + LineToCommand(119.03280142, 451.34928856), + CubicToCommand(119.03280142, 451.34928856, 116.91402585999998, + 406.14874327999996, 114.79525029999996, 403.3237092), + CubicToCommand(112.67647473999997, 400.49867512000003, 119.73905993999998, + 380.72343656, 114.08899177999996, 391.31731436), + CubicToCommand(114.08899177999996, 391.31731436, 89.36994357999995, + 416.03636256000004, 103.49511397999996, 453.46806412), + CubicToCommand(103.49511397999996, 453.46806412, 106.14358342999998, + 459.29469690999997, 100.84664452999996, 451.17272393), + CubicToCommand(100.84664452999996, 451.17272393, 92.72467154999998, + 428.92558055000006, 94.66688247999997, 417.62544423), + CubicToCommand(94.66688247999997, 417.62544423, 95.02001173999994, + 413.74102237, 98.37473970999994, 408.79721273), + CubicToCommand(98.37473970999994, 408.79721273, 113.55929788999995, + 388.13915102, 118.32654289999996, 384.07816453), + CubicToCommand(118.32654289999996, 384.07816453, 121.50470623999993, + 358.65285781, 148.69565925999996, 349.47149705000004), + CubicToCommand(148.69565925999996, 349.47149705000004, 158.75984316999995, + 345.41051056000003, 150.81443481999997, 350.3543202), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(396.94552904, 233.46853514), + CubicToCommand(398.11085559799994, 232.8434963498, 398.09496478129995, + 231.13081943880002, 399.11903963529994, 230.8253626289), + CubicToCommand(401.14776723399996, 230.2179803017, 401.4373332272, + 228.3340356996, 402.35193801059995, 226.9497690004), + CubicToCommand(403.89334723049996, 224.62088153070002, 404.2341169664, + 221.9141457528, 405.261723113, 219.2815671195), + CubicToCommand(405.74197890659997, 218.0456147095, 405.7896513567, + 216.359422493, 405.2370040648, 215.194095935), + CubicToCommand(403.16413530859995, 210.8135274647, 401.924651606, + 206.489459676, 399.37858964139997, 202.2060017522), + CubicToCommand(398.90539643299996, 201.4114609172, 398.4427971024, + 200.009537755, 398.0879021961, 198.95368126760002), + CubicToCommand(397.2704079592, 196.5100267884, 395.0509905601, + 194.76027130510002, 393.5325347421, 192.4296181891), + CubicToCommand(393.02402860769996, 191.6509681708, 393.9509929152, + 190.01774534330002, 392.6867901644, 189.8694310541), + CubicToCommand(391.1030054333, 189.6840381926, 388.5445839446, + 188.6599633386, 388.1331883567, 190.4715164424), + CubicToCommand(387.0949883323, 195.03924342050001, 388.8800567416, + 199.4939690354, 390.58920236, 203.8056773), + CubicToCommand(389.2084669534, 205.02750453960002, 389.7981928176, + 206.6536647819, 390.0665710552, 208.007915494), + CubicToCommand(391.3201799282, 214.3748360518, 389.2049356608, + 220.2932824494, 387.8612788265, 226.4271376956), + CubicToCommand(387.82066896159995, 226.61076491080001, 388.4245199962, + 226.9603628782, 388.37508189979997, 227.0698329488), + CubicToCommand(386.21746212119996, 231.8123589106, 383.65374369359995, + 236.1293641141, 380.44203307389995, 240.3333679544), + CubicToCommand(379.10367317849995, 242.084889084, 377.5640296049, + 243.7022210948, 376.68650339379997, 245.5791031117), + CubicToCommand(376.0367455554, 246.9686667498, 375.316361865, + 248.6742810756, 375.75777344, 250.41873962), + CubicToCommand(369.69277839949996, 255.327236334, 365.72007422449997, + 262.1161463575, 361.10997173519996, 268.9068220273), + CubicToCommand(360.2942431446, 270.1074615113, 360.80804621789997, + 272.242127888, 361.78091732919995, 272.7170867427), + CubicToCommand(363.21638777109996, 273.4198139701, 364.9043456339, + 271.6117921589, 365.7341993949, 270.1180553891), + CubicToCommand(366.42103580559996, 268.8856342717, 367.04430894949996, + 267.7379641767, 367.91124128279995, 266.6026536058), + CubicToCommand(368.1460722407, 266.2936655033, 367.830021553, + 265.5538597036, 368.06838380349996, 265.3402165013), + CubicToCommand(372.71733051139995, 261.1962446352, 375.66419418609996, + 256.0123070984, 379.99532456, 251.83125666), + CubicToCommand(383.438334845, 251.2503590273, 386.1521332081, + 249.4882440199, 389.2384829405, 247.699644318), + CubicToCommand(389.78230200089996, 247.3835936303, 390.70750066209996, + 247.823239559, 391.21953808909996, 247.47893853050002), + CubicToCommand(394.314716053, 245.4007728354, 394.31118476039995, + 241.8059169686, 394.49834326819996, 238.4335325356), + CubicToCommand(394.5866255832, 236.8727012064, 394.932692258, + 234.5473450293, 396.94552904, 233.46853514), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(381.33545010169996, 225.5831587642), + CubicToCommand(381.55439024289996, 225.4472039991, 381.2807150664, + 224.70033561420001, 381.47317051309994, 224.3189560134), + CubicToCommand(381.75920521369994, 223.7468866122, 382.47076067259997, + 223.4149451078, 382.75679537319996, 222.8428757066), + CubicToCommand(382.9492508199, 222.4614961058, 382.66145047299995, + 221.7905505118, 382.90157836979995, 221.5398287372), + CubicToCommand(387.02083118769997, 217.2192922411, 387.47460228679995, + 211.8799778299, 385.64539271999996, 206.63071138), + CubicToCommand(387.4534145312, 205.536010674, 387.5611189555, + 203.3077650434, 386.81071927799997, 201.81226262730002), + CubicToCommand(385.3046229841, 198.81066391730002, 384.9638532482, + 195.41002914350003, 383.2423481057, 192.6856369026), + CubicToCommand(381.8262997731, 190.4450317479, 379.0401099117, + 188.2485677507, 376.61940883439996, 190.54920487959998), + CubicToCommand(375.87607174209995, 191.2554633996, 375.3092992798, + 192.6450270377, 375.80014895119996, 193.9021672033), + CubicToCommand(375.91315031439996, 194.18996755019998, 376.41635950989996, + 194.44775191, 376.3686870598, 194.5925349066), + CubicToCommand(376.1797629057, 195.1646043078, 375.2157200259, + 195.560109079, 375.20512614809996, 196.0403648726), + CubicToCommand(375.15215675909997, 198.6817717374, 373.46773018889996, + 201.3496632967, 374.58008735789997, 203.6962072294), + CubicToCommand(375.94316630149996, 206.5724450521, 377.3892306212, + 209.8512502312, 378.58280751999996, 212.98703806), + CubicToCommand(376.4039999858, 216.7231456308, 378.22791261369997, + 221.0472134195, 375.1327346498, 224.3613315246), + CubicToCommand(374.892606753, 224.6191158844, 374.9084975697, + 225.3006553562, 375.12390641829995, 225.6573159088), + CubicToCommand(375.6394751379, 226.5154200106, 376.35632753569996, + 227.2322724084, 377.21443163749996, 227.747841128), + CubicToCommand(377.5710921901, 227.9614843303, 378.1855371025, + 227.9650156229, 378.53866636249995, 227.7460754817), + CubicToCommand(379.55920992389997, 227.10691152110002, 380.2619371513, + 226.247041773, 381.33545010169996, 225.5831587642), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(492.23922549729997, 207.37757976490002), + CubicToCommand(494.69170820799997, 210.5416179345, 495.203745635, + 215.476599343, 491.58593636629996, 217.93084770000002), + CubicToCommand(492.55704183129995, 223.7733713067, 498.4737225826, + 220.279157279, 502.17804851999995, 219.34336474), + CubicToCommand(501.98382742699994, 218.6582939756, 502.38992607599994, + 218.05091164840002, 502.88430703999995, 218.04208341690003), + CubicToCommand(504.75589211799996, 218.0155987224, 505.9565316019999, + 216.19345174080001, 507.82811668, 216.51833066), + CubicToCommand(508.6050010519999, 213.7692193709, 511.48300452099994, + 212.52973566830002, 512.630674616, 210.09314377430002), + CubicToCommand(515.667586252, 203.5690806958, 514.625854935, + 196.02447405590001, 510.070487481, 190.2931861661), + CubicToCommand(509.7173582209999, 189.84471200590002, 510.08814394399997, + 188.9318728688, 509.876266388, 188.29270890819998), + CubicToCommand(508.53437519999994, 184.38886493889999, 504.897143822, + 183.8326863544, 501.47178999999994, 182.6179217), + CubicToCommand(499.39538995119995, 175.7760422875, 498.22829774689995, + 168.6587220522, 495.11722896629993, 162.13642462), + CubicToCommand(492.2674758380999, 161.695013045, 491.0350547206999, + 158.6245541293, 488.6743856175999, 157.3532887933), + CubicToCommand(486.32077909969996, 156.0837891036, 485.3178920012999, + 158.87174461130002, 485.39028349959995, 160.71861064109999), + CubicToCommand(485.40264302369997, 161.08056813259998, 486.20071515129996, + 161.4760729038, 485.90055528029995, 162.1205338033), + CubicToCommand(485.76636616149995, 162.4100997965, 485.30729812349995, + 162.6060865358, 485.30729812349995, 162.84268314), + CubicToCommand(485.3090637698, 163.08104539049998, 485.69927160209994, + 163.3123450558, 485.9358682062999, 163.54894165999997), + CubicToCommand(484.3150049028999, 164.996771626, 481.80249021799995, + 165.8389849111, 481.28162455949996, 167.86064992459998), + CubicToCommand(479.59719798929996, 174.4111976976, 484.14020591919996, + 179.92884238509998, 487.0853039476, 185.5806761914), + CubicToCommand(488.12880091089994, 187.5846847419, 486.8292852341, + 189.82882118919997, 485.48739404609995, 191.9617219196), + CubicToCommand(484.71404096669994, 193.1888460981, 484.9047307671, + 195.17872947819998, 485.39204914589993, 196.690122711), + CubicToCommand(486.7198151634999, 200.80584423629998, 489.52895842679993, + 203.876303152, 492.2392254972999, 207.37757976489996), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(426.6278089893, 239.84075263670002), + CubicToCommand(424.0022929412, 243.10896393800002, 417.9779077656, + 247.6449092827, 423.12829802269994, 251.0490753491), + CubicToCommand(423.47083340489996, 251.27684372180002, 424.12412253589997, + 251.283906307, 424.4295793458, 251.04730970280002), + CubicToCommand(427.99795051809997, 248.2840732433, 431.53454005699996, + 246.6896946344, 435.83565444379997, 245.66208848780002), + CubicToCommand(436.05459458499996, 245.6108847451, 436.5383816712, + 246.4354415672, 437.18990515589996, 246.15117251290002), + CubicToCommand(440.0378926378, 244.90992316400002, 443.5868417008, + 245.0123306494, 445.67736692, 242.64989590000002), + CubicToCommand(452.3285565321, 243.0454006712, 458.6230855916, + 241.0749394004, 464.6103921949, 238.76547404000002), + CubicToCommand(466.66030754919996, 237.9744644976, 468.90267835019995, + 236.9874682159, 471.02321955649995, 236.1011137733), + CubicToCommand(473.4527488653, 235.0841015045, 475.5785870105, + 233.4455817381, 477.54198569609997, 231.43097930980002), + CubicToCommand(477.77681665399996, 231.19085141300002, 478.4018554442, + 231.34975958, 478.87328300629997, 231.34975958), + CubicToCommand(478.80265715429994, 229.82600682310002, 480.50120889489995, + 229.601769743, 480.93732353099995, 228.5035377444), + CubicToCommand(481.09976299059997, 228.0939078028, 480.8349160456, + 227.394711868, 481.06974700349997, 227.2146159454), + CubicToCommand(484.8446987929, 224.3366124764, 486.4690933889, + 220.77353824300002, 484.4050528642, 216.57659698790002), + CubicToCommand(483.9018436687, 215.5560534265, 483.46219773999997, + 214.4648840131, 482.4628419342, 213.6244363743), + CubicToCommand(480.5471156987, 212.015932595, 478.6013734761, + 213.5237945352, 476.75274179999997, 212.98703806), + CubicToCommand(476.4720040383, 214.0958639364, 475.1848478856, + 213.7921727728, 474.5033084138, 214.1417707402), + CubicToCommand(472.9866182421, 214.9168894659, 470.6330117242, + 213.88398638040002, 469.1163215525, 214.6573394598), + CubicToCommand(466.7115112919, 215.88446363830002, 464.5203442336, + 216.182857863, 462.009595195, 216.8485065181), + CubicToCommand(461.4587135494, 216.9932895147, 460.08504072799997, + 216.8237874699, 459.80253732, 217.93084770000002), + CubicToCommand(459.5659407158, 217.6942510958, 459.30462506339995, + 217.2810898616, 459.1174665556, 217.3199340802), + CubicToCommand(455.7486134152, 218.019130015, 453.5238990772, + 218.39697832320002, 451.2267932409, 221.3844518628), + CubicToCommand(451.044931672, 221.6192828207, 450.2645160074, + 221.303232133, 449.9837782457, 221.5415943835), + CubicToCommand(448.2940547366, 222.9682365939, 447.5789679851, + 225.1470441281, 445.63499140880003, 226.3335584417), + CubicToCommand(445.2800965025, 226.5507329366, 444.6585890049, + 226.25410435819998, 444.3160536227, 226.4818727309), + CubicToCommand(443.1754461129, 227.2428662862, 442.5274539208, + 228.37464556449999, 441.3939089962, 229.1638894606), + CubicToCommand(440.81301136350004, 229.5682224633, 440.1067528435, + 228.9943874158, 440.1632535251, 228.542381963), + CubicToCommand(440.59583686860003, 225.1046686169, 441.7488039025, + 221.9494586788, 440.73355728, 218.63710622), + CubicToCommand(444.4008046451, 214.187677544, 448.8449363822, + 210.7464329053, 452.0336936, 205.92445286), + CubicToCommand(452.0601782945, 202.1000629742, 453.2820055341, + 198.3109860144, 453.0824875022, 194.6437386493), + CubicToCommand(453.0648310392, 194.30296891339998, 452.5563249048, + 193.00875017549998, 452.333853471, 192.39607090939998), + CubicToCommand(451.78297182539995, 190.88820896919998, 453.3826473732, + 189.0060300134, 451.892441896, 187.7277020922), + CubicToCommand(449.4134744908, 185.60362959329998, 447.1322594712, + 187.15033575209998, 445.67736692, 189.6805069), + CubicToCommand(442.4321090206, 190.36910895699998, 438.78428376479997, + 191.5927018429, 435.9980939034, 189.41389430869998), + CubicToCommand(434.2200880793, 188.0243306706, 433.1995445179, + 186.4246551228, 431.78879312419997, 184.56013263), + CubicToCommand(430.0496315187, 182.26126114739998, 430.6411230292, + 179.72579306059998, 430.7647182702, 176.9643222474), + CubicToCommand(430.775312148, 176.738319521, 430.2191335635, + 176.4981916242, 430.2191335635, 176.26159501999996), + CubicToCommand(430.2208992098, 176.0232327695, 430.6093413958, + 175.79193310419998, 430.845938, 175.55533649999998), + CubicToCommand(429.5993917122, 174.45004191619998, 429.1138389797, + 172.58198813079997, 427.3146454, 172.02404389999998), + CubicToCommand(427.8531675215, 170.0959581404, 426.65959062269997, + 168.53512681119997, 425.1217126954, 168.00190162859997), + CubicToCommand(421.5992483269, 166.78184003529998, 418.6382594818, + 170.1577557609, 415.2976566822, 170.28664794079998), + CubicToCommand(414.390114484, 170.32019522049995, 413.5655576619, + 168.4874543611, 412.4196532132, 167.91361931359998), + CubicToCommand(411.6568940116, 167.5322397128, 410.41387901639996, + 167.47397338489998, 409.7747150558, 167.94363530069998), + CubicToCommand(408.5599504014, 168.8335210359, 407.5199847307, + 169.0348047141, 406.1816248353, 169.3967622056), + CubicToCommand(403.3265747682, 170.16658399239998, 401.0700787968, + 172.0982010446, 398.4569222728, 173.60782863109998), + CubicToCommand(395.8349375173, 175.1209875102, 394.1487453008, + 177.65822124329998, 392.24184729679996, 179.98887435929998), + CubicToCommand(390.5803741285, 182.02289889689996, 390.3402462317, + 186.28516906509998, 392.8474639777, 187.16799221509996), + CubicToCommand(396.1015501086, 188.31566231009998, 398.4039528838, + 183.54312036119998, 401.8752135096, 184.11872105499998), + CubicToCommand(402.42609515519996, 184.20876901629998, 402.789818293, + 184.75788501559998, 402.5955972, 185.44295577999998), + CubicToCommand(403.28243361069997, 185.6354112267, 403.6673445041, + 185.231078224, 404.00811424, 184.73669725999997), + CubicToCommand(405.5230387654, 186.5358908397, 407.57825105859996, + 187.13091364279998, 409.234427288, 188.67232286269999), + CubicToCommand(410.94710419899997, 190.2684671179, 414.0299226388, + 189.53042696449998, 415.8220536333, 191.29077632559998), + CubicToCommand(418.52172682599996, 193.94277706819997, 417.5347305443, + 198.67647479849998, 420.95831871999997, 200.98064322), + CubicToCommand(419.9236499882, 203.29893681189998, 418.85190268409997, + 205.553667137, 418.2604111736, 208.0732444071), + CubicToCommand(417.762498917, 210.2026138449, 419.5175513392, + 212.316092466, 421.6557490085, 212.15541865269998), + CubicToCommand(423.87693205389996, 211.98944790049998, 424.3395313845, + 210.64932235879996, 425.19586984, 208.74948694), + CubicToCommand(425.6672974021, 209.2209145021, 426.49538551679996, + 209.74531145319997, 426.4229940185, 210.126691054), + CubicToCommand(425.6160936594, 214.34128877209997, 423.8027749093, + 217.86022184799998, 422.9941089039, 222.1525080033), + CubicToCommand(422.88993577220003, 222.71221788039998, 422.3514136507, + 223.06887843299998, 421.66457723999997, 222.87465734), + CubicToCommand(420.83825477159996, 230.20032383869997, 413.68385596400003, + 234.42728108089997, 409.1902861305, 240.01555162039998), + CubicToCommand(408.47873067160003, 240.90190606299998, 408.4716680864, + 243.10719829169997, 409.1938174231, 243.81875375059997), + CubicToCommand(411.671019182, 246.2677051687, 415.13168593, + 243.53801598889999, 418.13328464, 242.6498959), + CubicToCommand(418.5093673019, 240.5205264622, 420.0260574736, + 238.85728764759997, 422.37789834520004, 238.9561638404), + CubicToCommand(422.82990379800003, 238.97382030339998, 423.2448306785, + 238.0168400088, 423.8169000797, 237.7873059898), + CubicToCommand(424.4313449921, 237.54364680039998, 425.3176994347, + 237.93915157159998, 425.82267427650004, 237.58955360419998), + CubicToCommand(428.87547672920005, 235.47960627569998, 431.3615067196, + 233.5268014679, 434.430199989, 231.4274480172), + CubicToCommand(434.7692040786, 231.19614835189998, 435.3765864058, + 231.4768861136, 435.7579660066, 231.28619631319998), + CubicToCommand(436.3318010541, 231.00016161259998, 436.66197691220003, + 230.31685649449997, 437.23228066710004, 229.99021192899997), + CubicToCommand(437.8467255795, 229.637082669, 438.2740119841, + 230.149120096, 438.61478172, 230.64350105999998), + CubicToCommand(437.4741742102, 231.25971161869998, 437.46711162500003, + 232.94943512779997, 436.4395054784, 233.30609568039998), + CubicToCommand(435.0711295959, 233.77928888879998, 434.08060202160004, + 234.6850654407, 432.8905564154, 235.4743093368), + CubicToCommand(432.37498769580003, 235.81507907269997, 431.2114267841, + 235.37719879029999, 431.02779956890004, 235.69324947799998), + CubicToCommand(429.9719430815, 237.50833387439997, 427.88141786230005, + 238.28168695379998, 426.62780898930004, 239.8407526367), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(328.79158185999995, 152.6019346), + CubicToCommand(328.79158185999995, 152.6019346, 312.4805413406, + 147.5309984264, 292.77239734, 192.85867024), + CubicToCommand(292.77239734, 192.85867024, 288.53484621999996, 202.040031, + 284.2972951, 205.5713236), + CubicToCommand(280.05974397999995, 209.1026162, 260.28450541999996, + 215.45894288, 256.75321282, 222.52152808), + LineToCommand(238.39049129999998, 250.77186888), + CubicToCommand(238.39049129999998, 250.77186888, 264.52205654, + 222.52152808, 270.1721247, 218.28397696), + CubicToCommand(270.1721247, 218.28397696, 284.2972951, 203.45254804, + 278.64722694, 215.45894288), + CubicToCommand(278.64722694, 215.45894288, 253.92817873999996, + 234.52792292, 256.0469543, 250.77186888), + CubicToCommand(256.0469543, 250.77186888, 246.15933501999996, 276.1971756, + 244.74681797999997, 279.7284682), + CubicToCommand(244.74681797999997, 279.7284682, 272.99715877999995, + 223.2277866, 277.2347099, 221.10901103999998), + CubicToCommand(281.47226101999996, 218.99023547999997, 283.59103658, + 218.99023548, 281.47226101999996, 225.34656216), + CubicToCommand(279.35348545999994, 231.70288883999999, 278.64722694, + 260.65948815999997, 273.70341729999996, 264.19078076), + CubicToCommand(273.70341729999996, 264.19078076, 287.82858769999996, + 228.17159623999999, 286.41607065999995, 222.52152808), + CubicToCommand(286.41607065999995, 222.52152808, 292.06613882, + 216.16520139999997, 296.30368993999997, 225.34656216), + LineToCommand(294.18491437999995, 253.59690296), + LineToCommand(301.95375809999996, 274.78465855999997), + CubicToCommand(301.95375809999996, 274.78465855999997, 297.71620698, + 255.00941999999998, 300.54124105999995, 227.46533771999998), + CubicToCommand(300.54124105999995, 227.46533771999998, 297.00994846, + 209.10261619999997, 304.07253366, 218.99023547999997), + CubicToCommand(311.13511886, 228.87785476, 328.08532333999995, + 239.47173256, 328.08532333999995, 247.94683479999998), + CubicToCommand(328.08532333999995, 247.94683479999998, 318.90396258, + 216.87145991999998, 302.66001661999996, 208.39635768), + LineToCommand(295.59743141999996, 218.99023547999997), + LineToCommand(293.47865586, 215.45894288), + CubicToCommand(293.47865586, 215.45894288, 287.12232917999995, + 214.04642583999998, 294.89117289999996, 202.04003099999997), + CubicToCommand(302.66001661999996, 190.03363616, 301.95375809999996, + 188.62111911999997, 301.95375809999996, 188.62111911999997), + CubicToCommand(301.95375809999996, 188.62111911999997, 313.25389442, + 201.33377248, 316.07892849999996, 201.33377248), + CubicToCommand(316.07892849999996, 201.33377248, 339.38545966, + 187.9148606, 341.50423522, 230.99663031999998), + CubicToCommand(341.50423522, 230.99663031999998, 353.51063006, + 205.57132359999997, 337.26668409999996, 193.56492876), + CubicToCommand(337.26668409999996, 193.56492876, 311.13511886, + 190.03363616, 313.25389442, 180.8522754), + LineToCommand(325.96654778, 158.95826128), + CubicToCommand(332.32287446, 149.77690051999997, 329.49784037999996, + 154.72071015999998, 329.49784037999996, 154.72071015999998), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(293.47865586, 181.55853392), + LineToCommand(265.22831506, 190.73989468000002), + LineToCommand(252.51566169999998, 207.69009916000002), + CubicToCommand(252.51566169999998, 207.69009916000002, 282.88477806, + 190.03363616000001, 289.94736326, 187.9148606), + CubicToCommand(297.00994846, 185.79608503999998, 293.47865586, + 181.55853392, 293.47865586, 181.55853392), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(222.85280386, 192.85867024), + CubicToCommand(222.85280386, 192.85867024, 219.32151125999997, + 194.9774458, 218.61525274, 199.92125544), + CubicToCommand(217.90899421999998, 204.86506508, 213.67144309999998, + 205.5713236, 215.08396014, 210.51513324), + CubicToCommand(216.49647718, 215.45894288, 220.02776977999997, 219.696494, + 220.02776977999997, 212.6339088), + CubicToCommand(220.02776977999997, 205.5713236, 222.85280386, 202.040031, + 224.26532089999998, 199.92125544), + CubicToCommand(225.67783793999996, 197.80247988, 228.50287201999998, + 190.03363616000001, 222.85280386, 192.85867024), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(207.31511641999998, 300.9162238), + CubicToCommand(207.31511641999998, 300.9162238, 192.48368749999997, + 293.8536386, 186.83361933999998, 287.49731192), + CubicToCommand(181.18355118000002, 281.14098524, 181.9816233076, + 290.2623140258, 173.41470746000002, 289.61608748000003), + CubicToCommand(163.09097354390002, 288.8374374617, 164.93960522, + 260.65948816, 164.93960522, 260.65948816), + LineToCommand(157.87702002, 274.07840004), + CubicToCommand(157.87702002, 274.07840004, 155.75824446000001, + 299.50370676, 169.88341486000002, 295.26615564), + CubicToCommand(176.7817949541, 293.19681817640003, 179.06477562, + 295.97241415999997, 176.23974153999998, 297.3849312), + CubicToCommand(173.41470746, 298.79744824, 186.12736081999998, + 299.50370676, 181.18355118, 302.32874084), + CubicToCommand(176.23974153999998, 305.15377492, 201.66504826, + 295.97241415999997, 197.42749714, 314.33513568), + LineToCommand(207.31511641999998, 300.9162238), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(185.06797303999997, 326.34153052), + CubicToCommand(185.06797303999997, 326.34153052, 157.87702001999997, + 334.11037424, 151.52069333999998, 317.16016976), + CubicToCommand(151.52069333999998, 317.16016976, 143.04559109999997, + 321.39772088, 146.93001295999997, 326.69465978), + CubicToCommand(150.81443481999997, 331.99159868, 152.93321038, + 332.6978572, 152.93321038, 332.6978572), + CubicToCommand(152.93321038, 332.6978572, 162.4677004, 334.81663276, + 161.40831261999998, 336.22914979999996), + CubicToCommand(160.34892483999997, 337.64166683999997, 156.11137372, + 343.64486425999996, 156.11137372, 343.64486425999996), + CubicToCommand(156.11137372, 343.64486425999996, 174.12096598, + 333.05098646, 185.06797304, 326.34153052), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(588.34158796, 464.41507118), + CubicToCommand(587.582360051, 468.193554262, 584.63373073, + 469.60607130200003, 581.2790027599999, 470.77139786), + CubicToCommand(577.888961864, 469.076377412, 573.315937947, 463.602873882, + 569.9788664399999, 467.24010525999995), + CubicToCommand(569.149012679, 466.392595036, 567.7718085649999, + 466.286656258, 567.15383236, 465.1213297), + CubicToCommand(566.3416350619999, 463.53224803, 566.818359563, + 461.695975878, 566.2180398209999, 460.283458838), + CubicToCommand(565.2469343559999, 458.023431574, 564.0109819459999, + 455.622152606, 564.32879828, 453.11493485999995), + CubicToCommand(567.524618083, 451.861325987, 568.5663494, 448.488941554, + 567.7364956389999, 445.38140406599996), + CubicToCommand(567.612900398, 444.922336028, 566.853672489, 444.586863231, + 567.206801749, 443.968887026), + CubicToCommand(567.5422745459999, 443.38622374700003, 568.089624899, + 442.997781561, 568.5663494, 442.52105706), + CubicToCommand(568.336815381, 442.76824754200004, 568.0719684359999, + 443.17434619100004, 567.877747343, 443.13903326499997), + CubicToCommand(566.8007031, 442.944812172, 567.012580656, + 441.81479853999997, 567.242114675, 441.14385294600004), + CubicToCommand(568.283845992, 438.05397192099997, 571.8327950549999, + 437.59490388300003, 574.21641756, 439.69602298), + CubicToCommand(574.6754855979999, 438.70726105200004, 575.575965211, + 439.042733849, 576.33519312, 438.98976446), + CubicToCommand(576.246910805, 437.965689606, 576.970825788, 437.029897067, + 577.3239550479999, 436.288325621), + CubicToCommand(578.2420911239999, 434.363771154, 581.1024381299999, + 436.305982084, 582.5149551699999, 435.22893784100006), + CubicToCommand(584.421853174, 433.763451412, 586.293438252, 432.545155465, + 588.2003362559999, 433.604543245), + CubicToCommand(591.396156059, 435.387846008, 594.415411232, 437.524278031, + 596.5341867919999, 440.614159056), + CubicToCommand(597.5406051829999, 442.079645485, 597.964360295, + 444.339672749, 597.8584215169999, 446.034693197), + CubicToCommand(597.787795665, 447.182363292, 595.351203771, 446.546730624, + 594.750884029, 448.188781683), + CubicToCommand(593.603213934, 451.278662708, 596.852003126, + 452.19679878399995, 598.176237851, 454.56276482600003), + CubicToCommand(598.5293671109999, 455.180741031, 598.0702990729999, + 455.710434921, 597.505292257, 455.88699955100003), + CubicToCommand(596.781377274, 456.11653357, 595.40417316, + 455.78106077300004, 595.6337071789999, 456.575601608), + CubicToCommand(597.364040553, 462.208013305, 592.490856765, + 463.40865278900003, 588.34158796, 464.41507118), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(571.39138348, 499.02173866), + CubicToCommand(571.373727017, 495.949514098, 568.5486929369999, + 492.85963307299994, 570.6851249599999, 489.8403779), + CubicToCommand(570.9323154419999, 490.087568382, 571.161849461, + 490.476010568, 571.39138348, 490.476010568), + CubicToCommand(571.638573962, 490.476010568, 571.868107981, + 490.08756838200003, 572.097642, 489.8403779), + CubicToCommand(574.74611145, 493.760112686, 581.190720445, + 495.38450728199996, 580.943529963, 500.416599237), + CubicToCommand(580.8905605739999, 501.21114007200003, 578.98366257, + 502.83553466800004, 580.5727442399999, 503.9655483), + CubicToCommand(577.376924437, 506.34917080499997, 577.270985659, + 510.533752536, 575.6289345999999, 513.85316758), + CubicToCommand(573.4395331879999, 513.358786616, 571.3031011649999, + 512.705497485, 569.2726079199999, 511.73439202), + CubicToCommand(569.8905841249999, 509.12123549600005, 569.6963630319999, + 506.13729324900004, 571.1441929979999, 503.806640133), + CubicToCommand(571.9034209069999, 502.570687723, 571.39138348, + 500.66378971899996, 571.39138348, 499.02173866), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(277.94096842, 483.13092196), + CubicToCommand(277.94096842, 483.13092196, 248.17570309459998, + 501.03457544199995, 272.99715877999995, 473.94956119999995), + CubicToCommand(288.53484621999996, 456.99935672, 306.19130922, + 447.11173743999996, 306.19130922, 447.11173743999996), + CubicToCommand(306.19130922, 447.11173743999996, 324.55403074, + 439.34289372, 330.91035741999997, 437.22411816), + CubicToCommand(337.26668409999996, 435.1053426, 364.10450785999996, + 425.92398184, 369.75457601999994, 425.21772332), + CubicToCommand(375.40464418, 424.5114648, 392.35484866, + 417.44887959999994, 404.3612435, 424.5114648), + CubicToCommand(416.36763834, 431.57404999999994, 430.49280874, + 439.34289372, 430.49280874, 439.34289372), + CubicToCommand(430.49280874, 439.34289372, 401.53620942, 424.5114648, + 395.17988274, 428.74901592000003), + CubicToCommand(388.82355606, 432.98656704, 376.1109027, + 432.28030851999995, 365.51702489999997, 437.93037668), + CubicToCommand(365.51702489999997, 437.93037668, 339.38545966, + 445.6992204, 333.7353915, 449.230513), + CubicToCommand(328.08532333999995, 452.7618056, 309.72260181999997, + 473.24330268, 306.89756774, 471.83078564), + CubicToCommand(304.07253366, 470.41826860000003, 307.60382625999995, + 469.71201008, 309.72260181999997, 464.76820044), + CubicToCommand(311.84137738, 459.8243908, 308.31008477999995, + 456.99935672, 294.18491437999995, 468.29949304), + CubicToCommand(280.05974397999995, 479.59962936, 277.94096842, + 483.13092196, 277.94096842, 483.13092196), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(291.0155792715, 472.590013549), + CubicToCommand(291.0155792715, 472.590013549, 293.5051405545, + 449.565985797, 308.47428988589996, 452.514615118), + CubicToCommand(308.47428988589996, 452.514615118, 322.99849634969996, + 445.151870047, 327.80458557829996, 441.673546836), + CubicToCommand(327.80458557829996, 441.673546836, 342.175180814, + 438.67194812599996, 344.48817746699996, 437.57724742000005), + CubicToCommand(377.11555544469996, 422.21965590260004, 403.10410333439995, + 430.1986115323, 404.0699118605, 428.22108767630004), + CubicToCommand(405.0339547403, 426.24532946659997, 439.6847633778, + 438.81319983000003, 446.05698087449997, 446.01703673400004), + CubicToCommand(446.7473485778, 446.81157756900006, 427.99265357919995, + 436.147073917, 410.8694157618, 432.81000241000004), + CubicToCommand(396.2622239219, 429.9549523429, 358.1207325493, + 433.233757522, 338.86459400149994, 443.015438024), + CubicToCommand(333.6153275516, 445.681563937, 317.8216213981, + 455.88699955100003, 313.3527706128, 455.692778458), + CubicToCommand(308.8839198275, 455.498557365, 291.0155792715, + 472.590013549, 291.0155792715, 472.590013549), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(284.2972951, 517.7375894400001), + CubicToCommand(284.2972951, 517.7375894400001, 257.45947133999994, + 513.50003832, 287.12232917999995, 510.67500424), + CubicToCommand(287.12232917999995, 510.67500424, 318.90396258, + 507.14371164, 325.96654778, 497.96235088000003), + CubicToCommand(325.96654778, 497.96235088000003, 349.97933745999995, + 481.71840492000007, 354.9231471, 481.01214640000006), + CubicToCommand(359.86695674, 480.30588788000006, 412.83634573999996, + 467.59323452000007, 413.54260425999996, 463.3556834000001), + CubicToCommand(414.24886277999997, 459.11813228000005, 424.13648206, + 459.11813228000005, 426.96151613999996, 460.53064932000007), + CubicToCommand(429.78655022, 461.9431663600001, 428.37403317999997, + 464.0619419200001, 423.43022354, 465.47445896000005), + CubicToCommand(418.4864139, 466.88697600000006, 363.39824934, + 495.84357532000007, 352.09811301999997, 497.96235088000003), + CubicToCommand(340.7979767, 500.08112644000005, 320.31647962, + 513.50003832, 311.84137738, 515.6188138800001), + CubicToCommand(303.36627513999997, 517.7375894400001, 284.2972951, + 517.7375894400001, 284.2972951, 517.7375894400001), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(318.76271087599997, 504.67180682000003), + CubicToCommand(318.76271087599997, 504.67180682000003, 303.60993432939995, + 503.20632039099996, 318.7962581557, 501.776146888), + CubicToCommand(318.7962581557, 501.776146888, 334.3621959365, + 495.71998007900004, 337.9782395589, 491.02336092100006), + CubicToCommand(337.9782395589, 491.02336092100006, 350.2742003921, + 482.70716684800004, 352.80437154, 482.33638112500006), + CubicToCommand(355.3363083342, 481.98325186500006, 379.9847306822, + 475.46801701800007, 380.3466881737, 473.29627206900005), + CubicToCommand(380.7086456652, 471.12452712000004, 440.857152521, + 448.91269666600004, 448.661309167, 454.54510836300005), + CubicToCommand(453.8011055463, 458.252965593, 436.31944152999995, + 455.30433627200006, 419.3092050758, 463.09083645500004), + CubicToCommand(416.9167543393, 464.18553716100007, 357.1443301454, + 489.92866021500004, 351.3583072203, 491.02336092100006), + CubicToCommand(345.5722842952, 492.10040516400005, 335.0861109195, + 498.96876927100004, 330.7461523141, 500.06346997700007), + CubicToCommand(326.407959355, 501.14051422000006, 318.76271087599997, + 504.67180682000003, 318.76271087599997, 504.67180682000003), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(304.77879218, 508.55622868), + CubicToCommand(304.77879218, 508.55622868, 313.96015294, 507.84997016, + 311.84137738, 510.67500423999996), + CubicToCommand(309.72260181999997, 513.5000383199999, 305.4850507, + 512.08752128, 305.4850507, 512.08752128), + LineToCommand(304.77879218, 508.55622868), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(292.06613882, 511.38126276), + CubicToCommand(292.06613882, 511.38126276, 301.24749957999995, + 510.67500423999996, 299.12872402, 513.5000383199999), + CubicToCommand(297.00994846, 516.3250724, 292.77239734, 514.9125553599999, + 292.77239734, 514.9125553599999), + LineToCommand(292.06613882, 511.38126276), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(273.70341729999996, 514.20629684), + CubicToCommand(273.70341729999996, 514.20629684, 282.88477806, + 513.50003832, 280.76600249999996, 516.3250724), + CubicToCommand(278.64722694, 519.15010648, 274.40967581999996, + 517.7375894400001, 274.40967581999996, 517.7375894400001), + LineToCommand(273.70341729999996, 514.20629684), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(260.28450541999996, 515.61881388), + CubicToCommand(260.28450541999996, 515.61881388, 269.46586618, + 514.9125553599999, 267.34709061999996, 517.73758944), + CubicToCommand(265.22831506, 520.56262352, 260.99076393999997, + 519.15010648, 260.99076393999997, 519.15010648), + LineToCommand(260.28450541999996, 515.61881388), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(328.08532334, 445.6992204), + LineToCommand(333.7353915, 448.52425447999997), + CubicToCommand(331.61661594, 451.34928856, 325.96654778, 450.64303004, + 325.96654778, 450.64303004), + LineToCommand(328.08532334, 445.6992204), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(310.42886033999997, 455.58683968), + CubicToCommand(310.42886033999997, 455.58683968, 321.91615516779996, + 451.808356598, 317.49144554, 457.70561524000004), + CubicToCommand(315.37266997999996, 460.53064931999995, 311.13511886, + 459.11813228, 311.13511886, 459.11813228), + LineToCommand(310.42886033999997, 455.58683968), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(290.65362178, 464.06194192), + CubicToCommand(290.65362178, 464.06194192, 299.83498254, 463.3556834, + 297.71620698, 466.18071748), + CubicToCommand(295.59743141999996, 469.00575156, 291.3598803, + 467.59323452, 291.3598803, 467.59323452), + LineToCommand(290.65362178, 464.06194192), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(277.2347099, 474.65581972), + CubicToCommand(277.2347099, 474.65581972, 286.41607065999995, 473.9495612, + 284.2972951, 476.77459528), + CubicToCommand(282.17851953999997, 479.59962936, 277.94096842, + 478.18711232, 277.94096842, 478.18711232), + LineToCommand(277.2347099, 474.65581972), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(265.22831506, 483.13092196), + CubicToCommand(265.22831506, 483.13092196, 274.40967581999996, + 482.42466344, 272.29090026, 485.2496975199999), + CubicToCommand(270.1721247, 488.07473159999995, 265.93457358, + 486.66221456, 265.93457358, 486.66221456), + LineToCommand(265.22831506, 483.13092196), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(334.2333037566, 494.43105828), + CubicToCommand(334.2333037566, 494.43105828, 346.4533417989, + 493.495265741, 343.6336046578, 497.25609236), + CubicToCommand(340.8138675167, 500.999262516, 335.1726275882, + 499.127677438, 335.1726275882, 499.127677438), + LineToCommand(334.2333037566, 494.43105828), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(352.59602527659996, 485.95595604000005), + CubicToCommand(352.59602527659996, 485.95595604000005, 364.8160633189, + 485.020163501, 361.9963261778, 488.78099012), + CubicToCommand(359.17658903669997, 492.52416027600003, 353.53534910819997, + 490.652575198, 353.53534910819997, 490.652575198), + LineToCommand(352.59602527659996, 485.95595604000005), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(371.66500531659995, 478.18711232), + CubicToCommand(371.66500531659995, 478.18711232, 383.88504335889996, + 477.251319781, 381.06530621779996, 481.0121464), + CubicToCommand(378.24556907669995, 484.755316556, 372.60432914819995, + 482.883731478, 372.60432914819995, 482.883731478), + LineToCommand(371.66500531659995, 478.18711232), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(390.0277268366, 469.71201008), + CubicToCommand(390.0277268366, 469.71201008, 402.24776487889994, + 468.776217541, 399.4280277378, 472.53704416), + CubicToCommand(396.6082905967, 476.28021431599996, 390.96705066819993, + 474.408629238, 390.96705066819993, 474.408629238), + LineToCommand(390.0277268366, 469.71201008), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(341.2958889566, 437.93037668), + CubicToCommand(341.2958889566, 437.93037668, 353.5159269989, + 436.994584141, 350.6961898578, 440.75541076), + CubicToCommand(347.8764527167, 444.498580916, 340.8226957482, + 444.039512878, 340.8226957482, 444.039512878), + LineToCommand(341.2958889566, 437.93037668), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(358.95235195659995, 432.28030852), + CubicToCommand(358.95235195659995, 432.28030852, 371.1723899989, + 431.3374533958, 368.35265285779997, 435.1053426), + CubicToCommand(365.53291571669996, 438.848512756, 357.7729002282, + 438.389444718, 357.7729002282, 438.389444718), + LineToCommand(358.95235195659995, 432.28030852), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(318.90396258, 502.90616052), + CubicToCommand(318.90396258, 502.90616052, 328.08532334, 502.199902, + 325.96654778, 505.02493608), + CubicToCommand(323.84777221999997, 507.84997016, 319.6102211, + 506.43745312, 319.6102211, 506.43745312), + LineToCommand(318.90396258, 502.90616052), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(189.65865341999998, 327.75404756), + CubicToCommand(189.65865341999998, 327.75404756, 181.88980969999997, + 343.291735, 181.18355118, 348.94180316), + CubicToCommand(181.18355118, 348.94180316, 182.59606821999998, + 333.40411572000005, 184.71484378, 329.87282312), + CubicToCommand(186.83361933999998, 326.34153052, 189.65865341999998, + 327.75404756, 189.65865341999998, 327.75404756), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(157.17076149999997, 352.47309576), + CubicToCommand(157.17076149999997, 352.47309576, 151.52069333999998, + 377.89840248, 152.22695185999999, 382.84221212), + CubicToCommand(152.22695185999999, 382.84221212, 150.10817629999997, + 362.36071504, 150.81443481999997, 360.24193948000004), + CubicToCommand(151.52069334, 358.12316392, 157.17076149999997, + 352.47309576000004, 157.17076149999997, 352.47309576000004), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(193.89620453999999, 220.75588178), + LineToCommand(193.54307527999995, 226.40594994), + LineToCommand(189.65865341999995, 226.7590792), + CubicToCommand(189.65865341999995, 226.7590792, 214.73083087999998, + 249.00622258, 215.79021865999994, 262.42513446), + CubicToCommand(215.79021865999994, 262.42513446, 217.20273569999995, + 247.9468348, 193.89620453999996, 220.75588178), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(200.93053939919997, 222.9894243495), + CubicToCommand(200.16954584389998, 222.2549154887, 200.5562223836, + 220.93950899520001, 199.83583869319997, 220.48044095720002), + CubicToCommand(198.4074308365, 219.5693674664, 202.12764759059996, + 219.4687256273, 201.72508023419996, 218.2045228765), + CubicToCommand(201.0488377013, 216.0751534387, 201.37901355939997, + 216.0380748664, 201.16360471079997, 213.7851101876), + CubicToCommand(201.06296287169997, 212.7292537002, 202.1011628961, + 210.0101583982, 202.78093672159997, 209.2332740262), + CubicToCommand(205.33406127139995, 206.3164263386, 202.99634557019996, + 201.139551387, 205.89200550219996, 198.4010339757), + CubicToCommand(206.42876197739997, 197.890762195, 207.09264498619996, + 196.9161254374, 207.59585418169996, 196.17808528400002), + CubicToCommand(208.75941509339998, 194.4777678971, 210.84994031259998, + 193.6161325027, 212.52730429759998, 192.1541773663), + CubicToCommand(213.08877982099995, 191.6668589875, 212.73388491469996, + 190.20666949740001, 213.73853765939998, 190.36910895699998), + CubicToCommand(214.99920911759997, 190.57215828149998, 217.19037617589998, + 190.3426242625, 217.11092209239996, 191.8275328008), + CubicToCommand(216.91140406049996, 195.5707029568, 214.56486012779996, + 198.6076145928, 212.30483286379996, 201.5527126212), + CubicToCommand(213.10113934509997, 202.7957276164, 212.29247333969997, + 203.9169130169, 211.79102979049995, 204.90037800599998), + CubicToCommand(209.43389197999997, 209.52637131199998, 209.76759913069995, + 214.54257245029999, 209.46037667449997, 219.5570079423), + CubicToCommand(209.45154844299998, 219.7070878778, 208.90949502889998, + 219.8448082892, 208.92362019929996, 219.9383875431), + CubicToCommand(209.54689334319994, 224.06117165359998, 210.57803078239996, + 227.9438278673, 212.13003388009997, 231.87945347), + CubicToCommand(212.77626042589998, 233.521504529, 213.60787983319997, + 235.1017579675, 213.8727267782, 236.7385120876), + CubicToCommand(214.0687135175, 237.94974544939998, 214.25057508639998, + 239.4205288173, 213.53019139599996, 240.66530945879998), + CubicToCommand(217.12328161649998, 245.7680272658, 214.81205060979997, + 250.4487556071, 216.87609113449997, 256.6832526924), + CubicToCommand(217.24157991859997, 257.7867816299, 220.22905345819999, + 261.1662286481, 219.41155922129997, 260.8819595938), + CubicToCommand(214.97449006939996, 259.3440816665, 214.77673768379998, + 258.6413544391, 214.46421828869995, 257.31182277519997), + CubicToCommand(214.20643392889997, 256.2118251303, 213.6237706499, + 253.7805301752, 213.20531247679997, 252.7176111026), + CubicToCommand(213.09231111359998, 252.4280451094, 212.79038559629998, + 249.1015674802, 212.65266518489997, 248.88615863159998), + CubicToCommand(209.98124233299995, 244.680389145, 212.37899000839997, + 244.9911428938, 209.96005457739997, 240.8277489184), + CubicToCommand(207.43871166099996, 239.62710943439998, 205.73309733519994, + 237.6778359192, 203.75027654029998, 235.62615491859998), + CubicToCommand(203.4006785729, 235.2659630734, 205.41881229379996, + 233.9876351522, 205.09923031349996, 233.6115524903), + CubicToCommand(203.17114455389998, 231.3356344096, 201.13535436999996, + 229.9813836975, 201.72861152679997, 227.3452737716), + CubicToCommand(202.00228670329994, 226.1269778246, 202.24418024639996, + 224.26068968549998, 200.93053939919997, 222.98942434949998), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(194.60246306, 226.05282068), + CubicToCommand(194.60246306, 226.05282068, 195.30872158, 238.05921552, + 199.54627269999997, 240.8842496), + CubicToCommand(203.78382381999995, 243.70928368, 201.66504826, + 242.29676664000002, 196.01498009999997, 240.17799108), + CubicToCommand(190.36491193999998, 238.05921552, 192.48368749999997, + 236.64669848, 192.48368749999997, 236.64669848), + CubicToCommand(192.48368749999997, 236.64669848, 187.53987786, 237.352957, + 191.77742897999997, 240.8842496), + CubicToCommand(196.01498009999995, 244.4155422, 202.37130677999997, + 248.65309332, 199.54627269999997, 248.65309332), + CubicToCommand(196.72123861999998, 248.65309332, 183.30232673999998, + 241.59050812, 183.30232673999998, 236.64669848), + CubicToCommand(183.30232673999998, 231.70288884, 181.53668043999997, + 224.46373901, 181.53668043999997, 224.46373901), + CubicToCommand(181.53668043999997, 224.46373901, 183.47889136999996, + 223.05122197, 191.95399360999997, 223.2277866), + CubicToCommand(191.95399360999997, 223.2277866, 194.42589843, + 224.46373901, 194.60246306, 226.05282068000002), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(193.18994601999998, 258.89384186), + CubicToCommand(193.18994601999998, 258.89384186, 178.14663954399998, + 253.96592303670002, 145.51749592, 259.95322964), + CubicToCommand(145.51749592, 259.95322964, 161.4630476553, 256.2842166286, + 194.60246306, 260.3063589), + CubicToCommand(212.78861994999997, 262.513416775, 193.18994601999998, + 258.89384186, 193.18994601999998, 258.89384186), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(196.89427195739998, 258.7684809727), + CubicToCommand(196.89427195739998, 258.7684809727, 182.3347525676, + 252.5569372893, 149.30833852609996, 255.7015533496), + CubicToCommand(149.30833852609996, 255.7015533496, 165.51344026749996, + 253.4256352689, 198.17966246379996, 260.29753066850003), + CubicToCommand(216.10803499399998, 264.0689511653, 196.89427195739998, + 258.7684809727, 196.89427195739998, 258.7684809727), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(200.05124754179997, 258.9326860786), + CubicToCommand(200.05124754179997, 258.9326860786, 185.99317170119997, + 251.6564576763, 152.82550595569998, 252.3362315018), + CubicToCommand(152.82550595569998, 252.3362315018, 169.15420293809998, + 251.26978113660002, 201.2201053924, 260.553549382), + CubicToCommand(218.81653641819997, 265.6474389575, 200.05124754179997, + 258.9326860786, 200.05124754179997, 258.9326860786), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(202.29361834279996, 259.3264252035), + CubicToCommand(202.29361834279996, 259.3264252035, 190.24484799159998, + 251.7217865894, 160.4513323254, 249.783106952), + CubicToCommand(160.4513323254, 249.783106952, 175.1750568211, + 250.083266823, 203.21528571139999, 260.8696000697), + CubicToCommand(218.60465886219998, 266.7898121136, 202.29361834279996, + 259.3264252035, 202.29361834279996, 259.3264252035), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(405.844386392, 277.8939616943), + CubicToCommand(405.844386392, 277.8939616943, 404.20233533299995, + 279.0310379115, 404.5801836412, 276.9458096312), + CubicToCommand(404.95979759569997, 274.8605813509, 454.7651484261, + 251.6070195799, 461.1461941543, 252.04843115490002), + CubicToCommand(461.1461941543, 252.04843115490002, 407.73892487189994, + 275.3655561927, 405.844386392, 277.8939616943), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(399.8517828498, 279.02220968), + CubicToCommand(399.8517828498, 279.02220968, 398.30507669099995, + 280.2846467845, 398.5187198933, 278.1764651023), + CubicToCommand(398.73236309559996, 276.0682834201, 446.5584244237, + 248.9744409466, 452.9535953223, 248.9144089724), + CubicToCommand(452.9535953223, 248.9144089724, 401.5432720051999, + 276.3543181207, 399.8517828498, 279.02220968), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(394.04986910799994, 281.4499733425), + CubicToCommand(394.04986910799994, 281.4499733425, 392.58791397159996, + 282.8130522861, 392.66207111619997, 280.6942767261), + CubicToCommand(392.7362282608, 278.5772668124, 427.7260409879, + 251.2150461013, 445.05056248349996, 247.9062249351), + CubicToCommand(445.05056248349996, 247.9062249351, 413.21595969449993, + 262.2556324152, 394.04986910799994, 281.4499733425), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(388.9718703492, 284.7393723994), + CubicToCommand(388.9718703492, 284.7393723994, 387.6564638557, + 285.9647309316, 387.7235584151, 284.0595985739), + CubicToCommand(387.79065297449995, 282.1527005699, 419.2791890887, + 257.5272316238, 434.871611564, 254.550351962), + CubicToCommand(434.871611564, 254.550351962, 406.2222347002, + 267.4642890002, 388.9718703492, 284.7393723994), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(333.02913298, 545.9879302400001), + CubicToCommand(333.02913298, 545.9879302400001, 306.19130922, + 541.75037912, 335.85416705999995, 538.92534504), + CubicToCommand(335.85416705999995, 538.92534504, 367.63580046, + 535.39405244, 374.69838566, 526.21269168), + CubicToCommand(374.69838566, 526.21269168, 398.71117533999995, + 509.9687457200001, 403.65498498, 509.26248720000007), + CubicToCommand(408.59879462, 508.55622868, 437.55539394, + 502.19990200000007, 438.26165245999994, 497.96235088000003), + CubicToCommand(438.96791097999994, 493.72479976, 449.56178878, + 489.48724864, 452.38682285999994, 490.8997656800001), + CubicToCommand(455.21185693999996, 492.3122827200001, 455.21185693999996, + 508.55622868, 450.2680472999999, 509.9687457200001), + CubicToCommand(445.32423765999994, 511.38126276000014, 412.13008721999995, + 524.09391612, 400.8299509, 526.21269168), + CubicToCommand(389.52981457999994, 528.33146724, 369.04831749999994, + 541.75037912, 360.5732152599999, 543.8691546800001), + CubicToCommand(352.09811301999997, 545.9879302400001, 333.02913297999993, + 545.9879302400001, 333.02913297999993, 545.9879302400001), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(461.92131287999996, 479.95275862000005), + CubicToCommand(461.92131287999996, 479.95275862000005, 456.62437398, + 482.77779269999996, 454.50559841999996, 487.36847308), + CubicToCommand(454.50559841999996, 487.36847308, 443.2054621, + 506.08432386, 418.13328463999994, 511.73439202), + CubicToCommand(418.13328463999994, 511.73439202, 377.52341973999995, + 527.62520872, 363.75137859999995, 531.15650132), + CubicToCommand(363.75137859999995, 531.15650132, 340.09171817999993, + 539.98473282, 327.02593555999994, 538.57221578), + CubicToCommand(327.02593555999994, 538.57221578, 314.66641145999995, + 538.92534504, 325.61341852, 541.75037912), + CubicToCommand(325.61341852, 541.75037912, 361.27947377999993, + 538.21908652, 367.2826712, 535.04092318), + CubicToCommand(367.2826712, 535.04092318, 394.82675348, 525.85956242, + 400.12369237999997, 521.26888204), + CubicToCommand(405.42063127999995, 516.6782016599999, 437.55539394, + 507.84997016, 441.43981579999996, 504.31867755999997), + CubicToCommand(445.32423766, 500.78738496, 462.62757139999997, + 485.95595604, 461.92131287999996, 479.95275862), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(358.24609343659995, 535.588273533), + CubicToCommand(358.24609343659995, 535.588273533, 367.4786579393, + 535.182174884, 365.44286775539996, 537.918926649), + CubicToCommand(363.4070775715, 540.6556784139999, 359.0847754291, + 539.119566133, 359.0847754291, 539.119566133), + LineToCommand(358.24609343659995, 535.588273533), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(345.529908784, 537.971896038), + CubicToCommand(345.529908784, 537.971896038, 354.76070764039997, + 537.583453852, 352.7266831028, 540.320205617), + CubicToCommand(350.6908929189, 543.0569573820001, 346.36859077649996, + 541.503188638, 346.36859077649996, 541.503188638), + LineToCommand(345.529908784, 537.971896038), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(327.1159835213, 540.178953913), + CubicToCommand(327.1159835213, 540.178953913, 336.34854802399997, + 539.772855264, 334.31275784009995, 542.509607029), + CubicToCommand(332.2769676562, 545.246358794, 327.95466551379997, + 543.710246513, 327.95466551379997, 543.710246513), + LineToCommand(327.1159835213, 540.178953913), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(313.6370396671, 541.150059378), + CubicToCommand(313.6370396671, 541.150059378, 322.86960416979997, + 540.743960729, 320.83381398589995, 543.480712494), + CubicToCommand(318.798023802, 546.2174642589999, 314.47572165959997, + 544.663695515, 314.47572165959997, 544.663695515), + LineToCommand(313.6370396671, 541.1500593779999), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(387.4375237145, 522.522490913), + CubicToCommand(387.4375237145, 522.522490913, 399.72642196249996, + 521.992797023, 397.016154892, 525.630028401), + CubicToCommand(394.3076534678, 529.284916242, 388.5534121761, + 527.2191100709999, 388.5534121761, 527.2191100709999), + LineToCommand(387.4375237145, 522.522490913), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(405.650165299, 514.718334267), + CubicToCommand(405.650165299, 514.718334267, 416.1716516007, + 508.89170147699997, 415.22879647649995, 517.825871755), + CubicToCommand(414.7520719755, 522.3282698200001, 406.76605376059996, + 519.414953425, 406.76605376059996, 519.414953425), + LineToCommand(405.650165299, 514.718334267), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(421.7740473106, 509.73921170100004), + CubicToCommand(421.7740473106, 509.73921170100004, 434.41430917229997, + 503.2063203910001, 431.35267848809997, 512.8644056520001), + CubicToCommand(429.9790056667, 517.172582624, 422.88817012589993, + 514.453487322, 422.88817012589993, 514.453487322), + LineToCommand(421.77404731059994, 509.73921170100004), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(438.5724062088, 501.228796535), + CubicToCommand(438.5724062088, 501.228796535, 446.26885843049996, + 492.577129665, 448.1510373863, 504.33633402299995), + CubicToCommand(448.8678897841, 508.82107562499993, 439.68829467039996, + 505.925415693, 439.68829467039996, 505.925415693), + LineToCommand(438.5724062088, 501.228796535), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(372.28651281419997, 530.4502428), + CubicToCommand(372.28651281419997, 530.4502428, 381.51731167059995, + 530.0441441510001, 379.483287133, 532.780895916), + CubicToCommand(377.44749694909996, 535.517647681, 373.12342916039995, + 533.9815354, 373.12342916039995, 533.9815354), + LineToCommand(372.28651281419997, 530.4502428), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(435.14352109419997, 316.10607891890004), + CubicToCommand(435.14352109419997, 316.10607891890004, 433.8616618804, + 317.28023370840003, 433.8598962341, 315.3892265211), + CubicToCommand(433.8598962341, 313.4999849801, 464.7304561433, + 290.0804524569, 480.3440663742, 287.6367979777), + CubicToCommand(480.3440663742, 287.6367979777, 451.91892659049995, + 299.5178319304, 435.14352109419997, 316.10607891890004), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(440.38042801999995, 428.74901592000003), + CubicToCommand(440.38042801999995, 428.74901592000003, 479.22641226630003, + 468.29949304, 495.47035822629994, 474.65581972), + CubicToCommand(495.47035822629994, 474.65581972, 511.71253853999997, + 494.43105828, 504.64995333999997, 540.33786208), + CubicToCommand(504.64995333999997, 540.33786208, 499.00165082629997, + 553.75677396, 493.3515826663, 517.0313309200001), + CubicToCommand(493.3515826663, 517.0313309200001, 499.00165082629997, + 472.53704416000005, 479.2264122663, 500.78738496000005), + CubicToCommand(479.2264122663, 500.78738496000005, 464.3932177, + 483.30748659000005, 475.69335401999996, 483.8371804800001), + CubicToCommand(475.69335401999996, 483.8371804800001, 481.34518782629993, + 487.36847308000006, 482.05144634629994, 484.54343900000015), + CubicToCommand(482.75770486629995, 481.7184049200001, 468.63076881999996, + 457.7056152400001, 438.26165245999994, 432.2803085200001), + CubicToCommand(407.8925360999999, 406.85500180000014, 440.38042801999995, + 428.74901592000015, 440.38042801999995, 428.74901592000015), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(337.26668409999996, 497.25609236), + CubicToCommand(337.26668409999996, 497.25609236, 336.91355483999996, + 494.07792901999994, 340.09171818, 495.49044605999995), + CubicToCommand(343.26988151999996, 496.90296309999997, 509.59376297999995, + 507.84997016, 565.38818606, 550.22548136), + CubicToCommand(565.38818606, 550.22548136, 485.58273894629997, + 509.2624872, 337.26668409999996, 497.25609236), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(355.62940562, 489.48724864), + CubicToCommand(355.62940562, 489.48724864, 355.27627636, 486.3090853, + 358.45443969999997, 487.72160234), + CubicToCommand(361.63260304, 489.13411938, 602.8198876199999, + 487.36847308000006, 644.4891402999999, 544.5754132), + CubicToCommand(644.4891402999999, 544.5754132, 605.6449216999999, + 500.08112644000005, 355.62940562, 489.48724864), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(376.1109027, 482.42466344), + CubicToCommand(376.1109027, 482.42466344, 375.75777344, + 479.24650010000005, 378.93593677999996, 480.65901714000006), + CubicToCommand(382.11410012, 482.07153418000007, 688.2771685399999, + 459.11813228000005, 729.94642122, 516.3250724), + CubicToCommand(729.94642122, 516.3250724, 712.99621674, + 471.12452712000004, 376.1109027, 482.42466344), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(393.76736569999997, 473.9495612), + CubicToCommand(393.76736569999997, 473.9495612, 393.41423643999997, + 470.77139786, 396.59239978, 472.1839149), + CubicToCommand(399.77056312, 473.59643194, 615.53254098, 405.44248476, + 657.20179366, 462.64942487999997), + CubicToCommand(657.20179366, 462.64942487999997, 633.5421332399999, + 419.2145259, 393.76736569999997, 473.9495612), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(291.3598803, 514.20629684), + CubicToCommand(291.3598803, 514.20629684, 291.00675104, + 511.02813349999997, 294.18491437999995, 512.44065054), + CubicToCommand(297.36307772, 513.85316758, 328.79158186, + 517.7375894400001, 332.32287446, 586.2446658800001), + CubicToCommand(332.32287446, 586.2446658800001, 319.6102211, 512.08752128, + 291.3598803, 514.20629684), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(275.82219286, 517.03133092), + CubicToCommand(275.82219286, 517.03133092, 275.46906359999997, + 513.85316758, 278.64722694, 515.26568462), + CubicToCommand(281.82539027999997, 516.67820166, 306.89756774, + 508.55622868, 301.95375809999996, 577.06330512), + CubicToCommand(301.95375809999996, 577.06330512, 304.07253366, + 514.9125553599999, 275.82219286, 517.03133092), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(261.69702245999997, 517.7375894400001), + CubicToCommand(261.69702245999997, 517.7375894400001, 261.34389319999997, + 514.5594261, 264.52205654, 515.97194314), + CubicToCommand(267.70021987999996, 517.38446018, 294.89117289999996, + 518.4438479600001, 272.99715878, 557.9943250800001), + CubicToCommand(272.99715878, 557.9943250800001, 289.94736326, + 515.6188138800001, 261.69702245999997, 517.7375894400001), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(345.2579992538, 439.448832498), + CubicToCommand(345.2579992538, 439.448832498, 344.47405229659995, + 442.98012509800003, 347.2090384153, 440.84369307500003), + CubicToCommand(375.5794431637, 418.5471115986, 432.86054042829994, + 314.547013236, 531.1893828753, 304.59936198180003), + CubicToCommand(531.1893828753, 304.59936198180003, 463.5439418297, + 283.2173852888, 345.2668274853, 439.448832498), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(365.0332378138, 436.27066915800003), + CubicToCommand(365.0332378138, 436.27066915800003, 362.6266619069, + 434.169550061, 365.92488919529995, 433.07484935499997), + CubicToCommand(369.2231164837, 431.96249218599996, 567.7559177482999, + 303.953135436, 637.1281608753, 318.01827386179997), + CubicToCommand(637.1281608753, 318.01827386179997, 589.2614896823, + 304.75827014879997, 365.0420660453, 436.27066915800003), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(328.23540327549995, 447.058768051), + CubicToCommand(328.23540327549995, 447.058768051, 327.3366893088, + 449.883802131, 330.3577101281, 448.15346875700004), + CubicToCommand(346.2043856706, 439.11335970100004, 352.58719704509997, + 338.0989692317, 429.5287658602, 335.8830831252), + CubicToCommand(429.5287658602, 335.8830831252, 372.30240363089996, + 309.903363467, 328.2354032755, 447.058768051), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(293.0584320406, 466.516190277), + CubicToCommand(293.0584320406, 466.516190277, 291.1568309755, + 468.79387400400003, 294.60513819939996, 468.33480596600003), + CubicToCommand(312.6959501892, 465.986496387, 350.48960924069996, + 393.1218048786, 428.95316516639997, 402.08952243630006), + CubicToCommand(428.95316516639997, 402.08952243630006, 372.51251554059996, + 376.75956061650004, 293.0584320406, 466.5161902770001), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(312.90076516, 455.710434921), + CubicToCommand(312.90076516, 455.710434921, 311.46882601069996, + 458.305934982, 314.76881894539997, 457.19357781300005), + CubicToCommand(332.07038703909996, 451.419914412, 355.1721032283, + 372.6456047375, 433.8987404527, 366.3828573114), + CubicToCommand(433.8987404527, 366.3828573114, 373.6442948189, + 352.35832875050005, 312.90076516, 455.710434921), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(280.6282820886, 475.55629933299997), + CubicToCommand(280.6282820886, 475.55629933299997, 279.08687286869997, + 477.392571485, 281.8801253153, 477.039442225), + CubicToCommand(296.533223959, 475.132544221, 327.1459995084, + 416.106988412, 390.7022037232, 423.3708572902), + CubicToCommand(390.7022037232, 423.3708572902, 344.98432407729996, + 402.85404728419996, 280.6282820886, 475.55629933299997), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(267.21113585489996, 485.991268966), + CubicToCommand(267.21113585489996, 485.991268966, 265.43666132339996, + 487.845197581, 268.2458045867, 487.633320025), + CubicToCommand(275.60501836509997, 487.08596967200003, 329.70088970449996, + 428.678390068, 362.3088455729, 456.04590771799997), + CubicToCommand(362.3088455729, 456.04590771799997, 341.09460527839997, + 422.9912433357, 267.21113585489996, 485.991268966), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(389.9800543865, 429.6283077774), + CubicToCommand(389.9800543865, 429.6283077774, 387.8595131802, + 427.2358570409, 391.27074183179997, 426.5560832154), + CubicToCommand(394.6819704834, 425.8780750362, 607.7919476008, + 323.9773301243, 674.8158811487999, 346.6941354201), + CubicToCommand(674.8158811487999, 346.6941354201, 629.0150161268, + 327.49449755390003, 389.9818200328, 429.6283077774), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(330.91035741999997, 543.16289616), + CubicToCommand(330.91035741999997, 543.16289616, 330.55722815999997, + 539.98473282, 333.7353915, 541.39724986), + CubicToCommand(336.91355483999996, 542.8097669, 364.10450785999996, + 543.86915468, 342.21049374, 583.4196318), + CubicToCommand(342.21049374, 583.4196318, 359.16069822, 541.0441206, + 330.91035741999997, 543.16289616), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(349.27307894, 540.33786208), + CubicToCommand(349.27307894, 540.33786208, 348.91994968, 537.15969874, + 352.09811301999997, 538.57221578), + CubicToCommand(355.27627636, 539.98473282, 386.70478049999997, + 543.86915468, 390.2360731, 612.3762311199999), + CubicToCommand(390.2360731, 612.3762311199999, 377.52341974, 538.21908652, + 349.27307894, 540.3378620799999), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(361.27947378, 537.512828), + CubicToCommand(361.27947378, 537.512828, 360.92634452, 534.3346646599999, + 364.10450786, 535.7471817), + CubicToCommand(367.2826712, 537.1596987400001, 410.71757018, 543.16289616, + 452.38682286, 600.36983628), + CubicToCommand(452.38682286, 600.36983628, 389.52981458, 535.39405244, + 361.27947378, 537.512828), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(374.7425268175, 533.928566011), + CubicToCommand(374.7425268175, 533.928566011, 373.97093938439997, + 530.821028523, 377.3080108914, 531.809790451), + CubicToCommand(380.64508239839995, 532.7808959160001, 416.72429889259996, + 529.4261679460001, 483.99012598369995, 589.7759584800001), + CubicToCommand(483.99012598369995, 589.7759584800001, 402.4614080812, + 528.0842767580001, 374.7425268175, 533.928566011), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(393.1052483375, 526.159722291), + CubicToCommand(393.1052483375, 526.159722291, 392.33366090439995, + 523.052184803, 395.67073241139997, 524.040946731), + CubicToCommand(399.0078039184, 525.012052196, 460.5123271325999, + 532.957460546, 551.7927095499999, 594.71976812), + CubicToCommand(551.7927095499999, 594.71976812, 420.82412960119996, + 520.315433038, 393.1052483375, 526.159722291), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(321.72899665999995, 505.7311946), + CubicToCommand(321.72899665999995, 505.7311946, 321.3758674, 502.55303126, + 324.55403074, 503.9655483), + CubicToCommand(327.73219408, 505.37806534000003, 422.0177065, + 509.96874572, 475.69335401999996, 557.28806656), + CubicToCommand(475.69335401999996, 557.28806656, 414.07053250369995, + 513.553007709, 321.72899665999995, 505.7311946), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(304.07253366, 512.7937798), + CubicToCommand(304.07253366, 512.7937798, 303.7194044, 509.61561645999996, + 306.89756774, 511.02813349999997), + CubicToCommand(310.07573107999997, 512.44065054, 353.51063006, + 518.44384796, 395.17988274, 575.65078808), + CubicToCommand(395.17988274, 575.65078808, 332.32287446, 510.67500424, + 304.07253366, 512.7937798), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(412.3119487889, 518.020092848), + CubicToCommand(412.3119487889, 518.020092848, 411.3143586294, + 514.983181212, 414.71499340319997, 515.724752658), + CubicToCommand(418.11562817699996, 516.448667641, 480.036843918, + 519.856365, 575.5936216739999, 574.76796493), + CubicToCommand(575.5936216739999, 574.76796493, 438.46823307709997, + 514.02973221, 412.31194878889994, 518.020092848), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(427.14337770889995, 513.782541728), + CubicToCommand(427.14337770889995, 513.782541728, 426.1457875494, + 510.745630092, 429.5464223232, 511.487201538), + CubicToCommand(432.94705709699997, 512.211116521, 494.86827283799994, + 515.61881388, 590.4250505939999, 570.53041381), + CubicToCommand(590.4250505939999, 570.53041381, 454.3590497770999, + 509.08592257, 427.14337770889995, 513.782541728), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(444.0935821889, 504.954310228), + CubicToCommand(444.0935821889, 504.954310228, 443.0959920294, + 501.91739859200004, 446.4966268032, 502.658970038), + CubicToCommand(449.897261577, 503.382885021, 525.943647718, + 511.02813349999997, 684.3644963392001, 571.58980159), + CubicToCommand(684.3644963392001, 571.58980159, 471.32161378119997, + 500.25769106999996, 444.09534783519996, 504.95431022799994), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(247.57185205999997, 517.03133092), + CubicToCommand(247.57185205999997, 517.03133092, 256.75321282, + 516.3250724, 254.63443725999997, 519.15010648), + CubicToCommand(252.51566169999998, 521.97514056, 248.27811057999998, + 520.56262352, 248.27811057999998, 520.56262352), + LineToCommand(247.57185205999997, 517.03133092), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(301.95375809999996, 541.75037912), + CubicToCommand(301.95375809999996, 541.75037912, 311.13511886, + 541.0441206, 309.01634329999996, 543.86915468), + CubicToCommand(306.89756774, 546.69418876, 302.66001661999996, + 545.28167172, 302.66001661999996, 545.28167172), + LineToCommand(301.95375809999996, 541.75037912), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(286.41607065999995, 541.0441206), + CubicToCommand(286.41607065999995, 541.0441206, 295.59743141999996, + 540.33786208, 293.47865586, 543.16289616), + CubicToCommand(291.3598803, 545.98793024, 287.12232917999995, 544.5754132, + 287.12232917999995, 544.5754132), + LineToCommand(286.41607065999995, 541.0441206), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(118.02638302899996, 520.174181334), + CubicToCommand(118.02638302899996, 520.174181334, 126.94289684399996, + 522.50483445, 124.01192398599997, 524.482358306), + CubicToCommand(121.08095112799998, 526.459882162, 117.53200206499997, + 523.7407868600001, 117.53200206499997, 523.7407868600001), + LineToCommand(118.02638302899996, 520.174181334), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(121.55767562899996, 503.22397685400006), + CubicToCommand(121.55767562899996, 503.22397685400006, 130.47418944399996, + 505.55462997, 127.54321658599997, 507.532153826), + CubicToCommand(124.61224372799998, 509.5096776820001, 121.06329466499997, + 506.79058238000005, 121.06329466499997, 506.79058238000005), + LineToCommand(121.55767562899996, 503.22397685400006), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(108.84502226899997, 495.455133134), + CubicToCommand(108.84502226899997, 495.455133134, 117.76153608399997, + 497.78578625, 114.83056322599998, 499.763310106), + CubicToCommand(111.89959036799996, 501.740833962, 108.35064130499995, + 499.02173866000004, 108.35064130499995, 499.02173866000004), + LineToCommand(108.84502226899997, 495.455133134), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(249.69062762, 627.91391856), + LineToCommand(239.80300833999996, 631.44521116), + CubicToCommand(236.27171574, 631.44521116, 216.49647717999997, + 637.8015378399999, 206.60885789999998, 655.45800084), + CubicToCommand(206.60885789999998, 655.45800084, 228.50287201999998, + 638.5077963599999, 249.69062762, 627.91391856), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(404.5660584708, 791.501048255), + CubicToCommand(404.8150145991, 791.94245983, 404.9121251456, + 792.684031276, 405.42769386519996, 792.719344202), + CubicToCommand(406.5894891306, 792.789970054, 408.76653101849996, + 793.319663944, 408.545825231, 792.207306775), + CubicToCommand(407.0485571686, 784.597371222, 405.5053823024, 775.8750785, + 398.2079661445, 772.69691516), + CubicToCommand(397.0797181588, 772.202534196, 394.5336561942, + 772.926449179, 394.402998368, 774.4978743859999), + CubicToCommand(394.1787612879, 777.1816567619999, 393.97218067079996, + 779.5652792669999, 394.5177653775, 782.1431228649999), + CubicToCommand(395.04745926749996, 784.6679970739999, 398.8577239829, + 784.6679970739999, 400.47682163999997, 782.2314051799999), + CubicToCommand(402.1294665768, 785.1800345009999, 402.89222577839996, + 788.4464801559999, 404.5660584708, 791.5010482549999), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(385.00622875939996, 799.852555254), + CubicToCommand(386.3269321918, 802.342116537, 386.1026951117, + 805.6262186549999, 388.60108462619996, 806.6326370459999), + CubicToCommand(389.9076628882, 807.1446744729999, 393.17410854319996, + 805.4319975619999, 392.43606838979997, 803.525099558), + CubicToCommand(391.0200200572, 799.8878681799999, 390.3349492928, + 795.9328204679999, 387.88246658209994, 792.7370006649999), + CubicToCommand(387.5293373221, 792.2779326269999, 387.9530924341, + 791.3421400879998, 387.67058902609995, 790.7594768089999), + CubicToCommand(386.6217951239, 788.6053883229998, 384.60013011039996, + 787.2988100609999, 382.11410012, 787.8814733399998), + CubicToCommand(380.1454044955, 791.7658951999999, 382.1723664479, + 795.5267218189998, 384.8596801165, 798.545976992), + CubicToCommand(385.0998080133, 798.8108239369999, 384.8067107275, + 799.4817695309999, 385.00622875939996, 799.852555254), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(315.0831039868, 790.688850957), + CubicToCommand(314.8924141864, 790.017905363, 314.825319627, + 789.205708065, 315.11665126649996, 788.6407012489999), + CubicToCommand(316.0542094518, 786.82208556, 317.45436696769997, + 784.844561704, 316.8593441646, 783.0259460149999), + CubicToCommand(316.24489925219996, 781.1720173999998, 314.27443798139996, + 781.489833734, 313.1267678864, 782.4962521249998), + CubicToCommand(311.12275933589996, 784.2442419619999, 311.0362426672, + 787.4753746909998, 309.8161810739, 789.8766536589999), + CubicToCommand(309.4701143991, 790.5475992529999, 309.5601623604, + 791.5716741069998, 308.7815123421, 792.260276164), + CubicToCommand(307.9445959959, 793.0018476099999, 307.1677116239, + 795.685629986, 307.3372136687, 796.6920483769999), + CubicToCommand(307.43079292259995, 797.2570551929999, 307.1076796497, + 814.7369535629999, 307.4996531283, 814.2778855249999), + CubicToCommand(308.592588188, 812.9889637259998, 313.977809403, + 795.7915687639999, 314.09963899769997, 794.2201435569998), + CubicToCommand(314.20028083679995, 792.9312217579998, 315.49273392839996, + 792.1190244599999, 315.0831039868, 790.6888509569999), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(269.81546414739995, 778.70011258), + CubicToCommand(274.4661765016, 774.28599683, 279.3923296786, + 769.0596837820001, 278.611914014, 762.509136009), + CubicToCommand(278.4070990432, 760.778802635, 275.2730768607, + 761.714595174, 274.94290100259997, 763.1977380659999), + CubicToCommand(273.52685267, 769.6070341349999, 269.92669986429996, + 774.303653293, 265.39252016589995, 778.52354795), + CubicToCommand(261.5151608911, 782.143122865, 258.2275274805, + 793.337320407, 257.8126006, 794.2378000199999), + CubicToCommand(264.3401949711, 784.9505004819999, 268.32525867019996, + 780.1126296199999, 269.8154641474, 778.7001125799999), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(245.84858127119998, 768.176860632), + CubicToCommand(246.7720142861, 767.505915038, 246.23878910349998, + 766.640748351, 246.6219343506, 766.058085072), + CubicToCommand(248.30459527449997, 763.4802414740001, 250.60170111079998, + 761.290840062, 250.63348274419997, 758.2186155), + CubicToCommand(250.63877968309998, 757.724234536, 249.97136538169997, + 757.1768841830001, 249.37987387119998, 757.582982832), + CubicToCommand(248.89078984609995, 757.900799166, 248.28693881149997, + 758.130333185, 248.09624901109999, 758.359867204), + CubicToCommand(244.51198702209996, 762.685700639, 242.0400822021, + 767.3999762599999, 239.49225459119998, 772.3614423629999), + CubicToCommand(239.16914131829998, 772.997075031, 237.14924195109998, + 780.924826918, 237.70188924299998, 781.1190480109999), + CubicToCommand(238.12387870869998, 781.2779561779998, 241.1607903447, + 773.897554644, 241.53157606769997, 773.6856770879999), + CubicToCommand(243.76158734459995, 772.4850376039999, 243.78277510019996, + 769.6246905979999, 245.84858127119998, 768.176860632), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(275.3931408091, 802.677589334), + CubicToCommand(276.17708776629996, 801.141477053, 278.95974633509996, + 799.022701493, 278.7602283032, 797.451276286), + CubicToCommand(278.5518820398, 795.8092252270001, 279.3782045082, + 793.2666945550001, 277.7679350826, 794.484990502), + CubicToCommand(275.5485176835, 796.144698024, 269.4588035948, + 798.5283205290001, 268.9820790938, 808.7867255320001), + CubicToCommand(268.93617229, 809.793143923, 274.1872043862, + 805.0435553760001, 275.3931408091, 802.6775893340001), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(300.89437031999995, 772.3437859), + CubicToCommand(301.60062883999996, 771.1608028789999, 302.8507064204, + 772.008313103, 303.66113807209996, 771.531588602), + CubicToCommand(304.80527687449995, 770.878299471, 305.8840867638, + 769.889537543, 306.39965548339995, 768.741867448), + CubicToCommand(308.11233239439997, 764.9633843660001, 311.23576069909996, + 761.7499081000001, 311.48824812, 757.51235698), + CubicToCommand(308.8556694867, 755.0404521600001, 307.656795649, + 758.642370612, 306.54443848, 760.3373910600001), + CubicToCommand(304.2084884251, 757.4240746650001, 302.4446077714, + 760.7434897090001, 300.14926758139995, 761.6616257850001), + CubicToCommand(300.0256723404, 761.714595174, 299.6495896785, + 761.0966189690001, 299.51716620599996, 761.1495883580001), + CubicToCommand(297.4390005109, 761.92647273, 296.23836102689995, + 763.833370734, 294.47624601949997, 765.2105748480001), + CubicToCommand(294.1743205022, 765.440108867, 293.4592337507, + 765.1222925330001, 293.19968374459995, 765.369483015), + CubicToCommand(292.04848235699995, 766.4288707950001, 290.3305085071, + 767.011534074, 289.83612754309996, 768.212173558), + CubicToCommand(287.8762601501, 772.979418568, 282.3321307681, + 776.6872757980001, 279.0003562, 790.0002489), + CubicToCommand(279.6730674403, 791.606987033, 286.9669523056, + 778.276357468, 287.82682205369997, 777.040405058), + CubicToCommand(289.30290236049996, 774.921629498, 289.5112486239, + 779.971377916, 291.7642133027, 778.806051358), + CubicToCommand(291.854261264, 778.753081969, 292.18267147579996, + 779.176837081, 292.41926808, 779.4063711), + CubicToCommand(292.76180346219996, 778.911990136, 293.14671435559995, + 778.505891487, 293.83178511999995, 778.70011258), + CubicToCommand(293.83178511999995, 777.9938540600001, 293.5951885158, + 777.0050921320001, 293.95008342209996, 776.740245187), + CubicToCommand(296.1341878952, 775.0099118129999, 295.985873606, + 773.120670272, 297.36307772, 770.9312688599999), + CubicToCommand(298.17174372539995, 772.326129437, 300.04509444969995, + 771.0548641009999, 300.89437031999995, 772.3437859), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(406.48001905999996, 868.3949446199999), + CubicToCommand(406.48001905999996, 868.3949446199999, 419.54580167999995, + 832.3757601, 411.77695796, 812.6005215399999), + CubicToCommand(411.77695796, 812.6005215399999, 431.90532578, + 850.7384816199999, 423.7833528, 870.51372018), + CubicToCommand(423.7833528, 870.51372018, 423.07709428, 852.1509986599999, + 416.01450908, 843.32276716), + CubicToCommand(416.01450908, 843.32276716, 408.95192388, 865.9230398, + 406.48001905999996, 868.3949446199999), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(380.34845382, 863.80426424), + CubicToCommand(380.34845382, 863.80426424, 389.88294383999994, + 848.2665767999999, 375.75777344, 815.77868488), + CubicToCommand(375.75777344, 815.77868488, 374.3452564, 851.7978694, + 362.33886155999994, 871.2199787), + CubicToCommand(362.33886155999994, 871.2199787, 387.41103902, + 835.55392344, 380.34845382, 863.80426424), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(362.69199082, 860.27297164), + CubicToCommand(362.69199082, 860.27297164, 362.33886156, 824.96004564, + 363.04512007999995, 819.66310674), + CubicToCommand(363.04512007999995, 819.66310674, 356.33566413999995, + 848.9728353200001, 338.32607188, 865.9230398), + CubicToCommand(338.32607188, 865.9230398, 363.75137859999995, 844.7352842, + 362.69199082, 860.27297164), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(345.74178634, 803.77229004), + CubicToCommand(345.74178634, 803.77229004, 356.33566413999995, + 827.78507972, 338.67920114, 860.27297164), + CubicToCommand(338.67920114, 860.27297164, 349.97933745999995, + 838.73208678, 341.50423522, 826.37256268), + CubicToCommand(341.50423522, 826.37256268, 346.0949156, 820.3693652600001, + 345.74178634, 803.77229004), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(311.84137738, 859.5667131199999), + CubicToCommand(311.84137738, 859.5667131199999, 310.07573107999997, + 832.0226308399999, 313.25389442, 828.13820898), + CubicToCommand(313.25389442, 828.13820898, 313.60702368, 816.83807266, + 312.90076516, 815.07242636), + CubicToCommand(312.90076516, 815.07242636, 319.96335036, 804.1254193, + 320.31647962, 817.1912019199999), + CubicToCommand(320.31647962, 817.1912019199999, 322.78838443999996, + 830.96324306, 327.73219408, 839.0852160399999), + CubicToCommand(327.73219408, 839.0852160399999, 334.08852076, + 848.6197060599999, 333.7353915, 859.9198423799999), + CubicToCommand(333.7353915, 859.9198423799999, 316.07892849999996, + 806.5973241199999, 311.84137738, 859.5667131199999), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(305.4850507, 810.83487524), + CubicToCommand(305.4850507, 810.83487524, 293.83178511999995, + 829.90385528, 290.65362178, 863.45113498), + CubicToCommand(290.65362178, 863.45113498, 288.18171695999996, + 852.5041279200001, 294.89117289999996, 827.0788212), + CubicToCommand(294.89117289999996, 827.0788212, 302.30688735999996, + 799.88786818, 305.4850507, 810.83487524), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(266.99396135999996, 845.79467198), + CubicToCommand(266.99396135999996, 845.79467198, 275.82219286, + 836.2601819600001, 278.29409768, 827.43195046), + CubicToCommand(278.29409768, 827.43195046, 284.65042436, 799.53473892, + 273.35028803999995, 814.7192971000001), + CubicToCommand(273.35028803999995, 814.7192971000001, 273.70341729999996, + 828.8444675000001, 259.22511763999995, 841.91025012), + CubicToCommand(259.22511763999995, 841.91025012, 267.70021987999996, + 837.6726990000001, 266.99396135999996, 845.79467198), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(256.75321282, 836.9664404800001), + CubicToCommand(256.75321282, 836.9664404800001, 262.75641024, + 806.2441948600001, 264.16892728, 804.83167782), + CubicToCommand(264.16892728, 804.83167782, 267.34709061999996, + 798.8284804000001, 262.40328098, 804.47854856), + CubicToCommand(262.40328098, 804.47854856, 246.86559353999996, + 838.3789575200001, 239.80300833999996, 850.0322231000001), + CubicToCommand(239.80300833999996, 850.0322231000001, 253.92817873999996, + 833.7882771400001, 256.75321282, 836.9664404800001), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(246.51246427999996, 807.6567119), + CubicToCommand(246.51246427999996, 807.6567119, 266.99396135999996, + 768.10623478, 228.50287201999998, 813.6599093199999), + CubicToCommand(228.50287201999998, 813.6599093199999, 247.92498131999997, + 796.3565755799999, 246.51246428, 807.6567119), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(219.32151125999997, 781.87827592), + CubicToCommand(219.32151125999997, 781.87827592, 227.79661349999998, + 748.6841254799999, 232.38729387999996, 749.03725474), + LineToCommand(235.21232795999998, 751.86228882), + CubicToCommand(235.21232795999998, 751.86228882, 224.61845015999998, + 768.8124933, 225.67783794, 786.1158270399999), + CubicToCommand(225.67783794, 786.1158270399999, 224.61845015999998, + 769.1656225599999, 219.32151125999997, 781.87827592), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(802.51448415, 761.7499081), + CubicToCommand(802.51448415, 761.7499081, 781.32672855, 744.0934451, + 776.9126128, 737.91368305), + CubicToCommand(776.9126128, 737.91368305, 800.74883785, 770.5781396, + 800.74883785, 782.9376637), + CubicToCommand(800.74883785, 782.9376637, 805.1629536, 769.69531645, + 802.51448415, 761.7499081), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(812.2255388, 722.9056895), + CubicToCommand(812.2255388, 722.9056895, 775.1469665, 696.4209950000001, + 768.96720445, 683.17864775), + CubicToCommand(768.96720445, 683.17864775, 815.7568314, 735.2652136, + 815.7568314, 743.21062195), + CubicToCommand(815.7568314, 743.21062195, 816.6396545499999, + 727.3198052500001, 812.2255388, 722.9056895), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(842.2415258999999, 450.99615930000004), + CubicToCommand(842.2415258999999, 450.99615930000004, 821.0537703, + 436.87098890000004, 818.40530085, 440.4022815), + CubicToCommand(818.40530085, 440.4022815, 836.944587, 451.87898244999997, + 841.35870275, 466.886976), + CubicToCommand(841.35870275, 466.886976, 838.7102333, 450.99615930000004, + 842.2415258999999, 450.99615930000004), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(857.24951945, 593.13068645), + LineToCommand(826.3507092, 571.94293085), + CubicToCommand(826.3507092, 571.94293085, 859.8979889, 601.95891795, + 860.78081205, 609.0215031500001), + LineToCommand(857.24951945, 593.13068645), + CloseCommand() + ], + ), + Path( + commands: const [ + MoveToCommand(167.32322772499998, 553.4036447), + LineToCommand(206.16744632499996, 561.790464625) + ], + ), + Path( + commands: const [ + MoveToCommand(256.0469543, 839.4383452999999), + CubicToCommand(256.0469543, 839.4383452999999, 255.16413114999997, + 833.25858325, 239.27331445, 851.7978694) + ], + ), + Path( + commands: const [ + MoveToCommand(265.75800895, 848.2665767999999), + CubicToCommand(265.75800895, 848.2665767999999, 269.28930155, + 836.7898758499999, 257.8126006, 844.7352842) + ], + ), + Path( + commands: const [ + MoveToCommand(361.10290914999996, 863.27457035), + CubicToCommand(361.10290914999996, 863.27457035, 363.75137859999995, + 843.85246105, 343.44644615, 866.80586295) + ], + ), +]; diff --git a/packages/vector_graphics_compiler/test/parsers_test.dart b/packages/vector_graphics_compiler/test/parsers_test.dart new file mode 100644 index 000000000000..56c03891fe33 --- /dev/null +++ b/packages/vector_graphics_compiler/test/parsers_test.dart @@ -0,0 +1,226 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:vector_graphics_compiler/src/svg/node.dart'; +import 'package:vector_graphics_compiler/src/svg/numbers.dart'; +import 'package:vector_graphics_compiler/src/svg/parser.dart'; +import 'package:vector_graphics_compiler/src/svg/parsers.dart'; +import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; + +void main() { + test('Colors', () { + final SvgParser parser = SvgParser( + '', + const SvgTheme(), + 'test_key', + true, + null, + ); + expect(parser.parseColor('null', attributeName: 'foo', id: null), null); + expect(parser.parseColor('red', attributeName: 'foo', id: null), + const Color.fromARGB(255, 255, 0, 0)); + expect(parser.parseColor('#ABCDEF', attributeName: 'foo', id: null), + const Color.fromARGB(255, 0xAB, 0xCD, 0xEF)); + // RGBA in svg/css, ARGB in this library. + expect(parser.parseColor('#ABCDEF88', attributeName: 'foo', id: null), + const Color.fromARGB(0x88, 0xAB, 0xCD, 0xEF)); + }); + + test('Colors - mapped', () async { + final TestColorMapper mapper = TestColorMapper(); + final SvgParser parser = SvgParser( + '', + const SvgTheme(), + 'test_key', + true, + mapper, + ) + ..enableMaskingOptimizer = false + ..enableClippingOptimizer = false + ..enableOverdrawOptimizer = false; + final VectorInstructions instructions = parser.parse(); + + // TestMapper just always returns this color. + expect(instructions.paints.single.fill!.color, + const Color.fromARGB(255, 255, 0, 255)); + + // TestMapper should have gotten the ID/element name/attribute name from the rect. + expect(mapper.lastId, 'rect1'); + expect(mapper.lastElementName, 'rect'); + expect(mapper.lastAttributeName, 'fill'); + expect(mapper.lastColor, const Color.fromARGB(255, 255, 0, 0)); + }); + + test('Multiple matrix translates', () { + final AffineMatrix expected = AffineMatrix.identity + .translated(0.338957, 0.010104) + .translated(-0.5214, 0.125) + .translated(0.987, 0.789); + expect( + parseTransform( + 'translate(0.338957,0.010104), translate(-0.5214,0.125),translate(0.987,0.789)', + ), + expected, + ); + }); + + test('Transform has whitespace in params', () { + expect( + parseTransform('translate( 50 , 1160 )'), + AffineMatrix.identity.translated(50, 1160), + ); + }); + + test('Translate and scale matrix', () { + final AffineMatrix expected = AffineMatrix.identity + .translated(0.338957, 0.010104) + .scaled(0.869768, 1.000000); + expect( + parseTransform( + 'translate(0.338957,0.010104),scale(0.869768,1.000000)', + ), + expected, + ); + }); + + test('SVG Transform parser tests', () { + expect(() => parseTransform('invalid'), throwsStateError); + expect(() => parseTransform('transformunsupported(0,0)'), throwsStateError); + + expect( + parseTransform('skewX(60)'), + AffineMatrix.identity.xSkewed(60.0), + ); + expect( + parseTransform('skewY(60)'), + AffineMatrix.identity.ySkewed(60.0), + ); + expect( + parseTransform('translate(10,0.0)'), + AffineMatrix.identity.translated(10.0, 0.0), + ); + + expect( + parseTransform('scale(10)'), + AffineMatrix.identity.scaled(10.0, 10.0), + ); + expect( + parseTransform('scale(10, 15)'), + AffineMatrix.identity.scaled(10.0, 15.0), + ); + + expect( + parseTransform('rotate(20)'), + AffineMatrix.identity.rotated(radians(20.0)), + ); + expect( + parseTransform('rotate(20, 30)'), + AffineMatrix.identity + .translated(30.0, 30.0) + .rotated(radians(20.0)) + .translated(-30.0, -30.0), + ); + expect( + parseTransform('rotate(20, 30, 40)'), + AffineMatrix.identity + .translated(30.0, 40.0) + .rotated(radians(20.0)) + .translated(-30.0, -40.0), + ); + + expect( + parseTransform('matrix(1.5, 2.0, 3.0, 4.0, 5.0, 6.0)'), + const AffineMatrix(1.5, 2.0, 3.0, 4.0, 5.0, 6.0), + ); + + expect( + parseTransform('matrix(1.5, 2.0, 3.0, 4.0, 5.0, 6.0 )'), + const AffineMatrix(1.5, 2.0, 3.0, 4.0, 5.0, 6.0), + ); + + expect( + parseTransform('rotate(20)\n\tscale(10)'), + AffineMatrix.identity.rotated(radians(20.0)).scaled(10.0, 10.0), + ); + }); + + test('FillRule tests', () { + expect(parseRawFillRule(''), PathFillType.nonZero); + expect(parseRawFillRule(null), isNull); + expect(parseRawFillRule('inherit'), isNull); + expect(parseRawFillRule('nonzero'), PathFillType.nonZero); + expect(parseRawFillRule('evenodd'), PathFillType.evenOdd); + expect(parseRawFillRule('invalid'), PathFillType.nonZero); + }); + + test('Parses pattern units to double correctly', () { + final ViewportNode viewportNode = ViewportNode(SvgAttributes.empty, + width: 100, height: 1000, transform: AffineMatrix.identity); + expect(parsePatternUnitToDouble('25.0', 'width'), 25.0); + expect( + parsePatternUnitToDouble('0.25', 'width', viewBox: viewportNode), 25.0); + expect( + parsePatternUnitToDouble('25%', 'width', viewBox: viewportNode), 25.0); + expect(parsePatternUnitToDouble('25', 'width'), 25.0); + expect( + parsePatternUnitToDouble('0.1%', 'height', viewBox: viewportNode), 1.0); + }); + + test('Point conversion', () { + expect(parseDoubleWithUnits('1pt', theme: const SvgTheme()), 1 + 1 / 3); + }); + + test('Parse a transform with scientific notation', () { + expect( + parseTransform('translate(9e-6,6.5e-4)'), + AffineMatrix.identity.translated(9e-6, 6.5e-4), + ); + + expect( + parseTransform('translate(9E-6,6.5E-4)'), + AffineMatrix.identity.translated(9e-6, 6.5e-4), + ); + }); + + test('Parse a transform with a missing space', () { + expect( + parseTransform('translate(0-70)'), + AffineMatrix.identity.translated(0, -70), + ); + }); + + test('Parse a transform with doubled periods', () { + expect( + parseTransform('matrix(.70711-.70711.70711.70711-640.89 452.68)'), + const AffineMatrix( + 0.70711, -0.70711, // + 0.70711, 0.70711, // + -640.89, 452.68, // + 0.70711, // + ), + ); + }); +} + +class TestColorMapper extends ColorMapper { + String? lastId; + late String lastElementName; + late String lastAttributeName; + late Color lastColor; + + @override + Color substitute( + String? id, + String elementName, + String attributeName, + Color color, + ) { + lastId = id; + lastElementName = elementName; + lastAttributeName = attributeName; + lastColor = color; + return const Color.fromARGB(255, 255, 0, 255); + } +} diff --git a/packages/vector_graphics_compiler/test/path_ops_test.dart b/packages/vector_graphics_compiler/test/path_ops_test.dart new file mode 100644 index 000000000000..e2ae564360a5 --- /dev/null +++ b/packages/vector_graphics_compiler/test/path_ops_test.dart @@ -0,0 +1,160 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:vector_graphics_compiler/src/_initialize_path_ops_io.dart' + as vector_graphics; +import 'package:vector_graphics_compiler/src/svg/path_ops.dart'; + +void main() { + setUpAll(() { + if (!vector_graphics.initializePathOpsFromFlutterCache()) { + fail('error in setup'); + } + }); + test('Path tests', () { + final Path path = Path() + ..lineTo(10, 0) + ..lineTo(10, 10) + ..lineTo(0, 10) + ..close() + ..cubicTo(30, 30, 40, 40, 50, 50); + + expect(path.fillType, FillType.nonZero); + expect(path.verbs.toList(), [ + PathVerb.moveTo, // Skia inserts a moveTo here. + PathVerb.lineTo, + PathVerb.lineTo, + PathVerb.lineTo, + PathVerb.close, + PathVerb.moveTo, // Skia inserts a moveTo here. + PathVerb.cubicTo, + ]); + expect(path.points, + [0, 0, 10, 0, 10, 10, 0, 10, 0, 0, 30, 30, 40, 40, 50, 50]); + + final SvgPathProxy proxy = SvgPathProxy(); + path.replay(proxy); + expect(proxy.toString(), + 'M0.0,0.0L10.0,0.0L10.0,10.0L0.0,10.0ZM0.0,0.0C30.0,30.0 40.0,40.0 50.0,50.0'); + path.dispose(); + }); + + test('Ops test', () { + final Path cubics = Path() + ..moveTo(16, 128) + ..cubicTo(16, 66, 66, 16, 128, 16) + ..cubicTo(240, 66, 16, 66, 240, 128) + ..close(); + + final Path quad = Path() + ..moveTo(55, 16) + ..lineTo(200, 80) + ..lineTo(198, 230) + ..lineTo(15, 230) + ..close(); + + final Path intersection = cubics.applyOp(quad, PathOp.intersect); + + expect(intersection.verbs, [ + PathVerb.moveTo, + PathVerb.lineTo, + PathVerb.cubicTo, + PathVerb.lineTo, + PathVerb.cubicTo, + PathVerb.cubicTo, + PathVerb.lineTo, + PathVerb.lineTo, + PathVerb.close + ]); + expect(intersection.points, [ + 34.06542205810547, 128.0, // move + 48.90797424316406, 48.59233856201172, // line + 57.80497360229492, 39.73065185546875, 68.189697265625, 32.3614387512207, + 79.66168212890625, 26.885154724121094, // cubic + 151.7936248779297, 58.72270584106445, // line + 150.66123962402344, 59.74142837524414, 149.49365234375, + 60.752471923828125, 148.32867431640625, 61.76123809814453, // cubic + 132.3506317138672, 75.59684753417969, 116.86703491210938, + 89.0042953491211, 199.52090454101562, 115.93260192871094, // cubic + 199.36000061035156, 128.0, // line + 34.06542205810547, 128.0, // line + // close + ]); + cubics.dispose(); + quad.dispose(); + intersection.dispose(); + }); + + test('Quad', () { + final Path top = Path() + ..moveTo(87.998, 103.591) + ..lineTo(82.72, 103.591) + ..lineTo(82.72, 106.64999999999999) + ..lineTo(87.998, 106.64999999999999) + ..lineTo(87.998, 103.591) + ..close(); + + final Path bottom = Path() + ..moveTo(116.232, 154.452) + ..lineTo(19.031999999999996, 154.452) + ..cubicTo(18.671999999999997, 142.112, 21.361999999999995, + 132.59199999999998, 26.101999999999997, 125.372) + ..cubicTo(32.552, 115.55199999999999, 42.782, 110.012, 54.30199999999999, + 107.502) + ..cubicTo(56.931999185062395, 106.9278703703336, 59.593157782987156, + 106.50716022812718, 62.27200212186002, 106.24200362009655) + ..lineTo(62.291999999999994, 106.24199999999999) + ..cubicTo(67.10118331429277, 105.77278829340533, 71.940772522921, + 105.69920780785604, 76.76199850891219, 106.021997940542) + ..cubicTo(78.762, 106.142, 80.749, 106.32199999999999, 82.722, 106.562) + ..lineTo(83.362, 106.652) + ..cubicTo(84.112, 106.742, 84.85199999999999, 106.852, 85.592, 106.972) + ..cubicTo(86.852, 107.152, 88.102, 107.372, 89.342, 107.60199999999999) + ..cubicTo(89.542, 107.642, 89.732, 107.67199999999998, 89.922, + 107.71199999999999) + ..cubicTo(91.54899999999999, 108.02599999999998, 93.14, 108.502, 94.672, + 109.13199999999999) + ..cubicTo(98.35184786478965, 110.61003782601773, 101.5939983878398, + 113.00207032444644, 104.09199525642647, 116.08199471003054) + ..cubicTo(104.181, 116.17999999999999, 104.264, 116.28399999999999, + 104.342, 116.392) + ..cubicTo(104.512, 116.612, 104.682, 116.832, 104.842, 117.062) + ..cubicTo(105.102, 117.41199999999999, 105.352, 117.77199999999999, + 105.592, 118.142) + ..cubicTo(107.63018430068513, 121.33505319707416, 109.25008660688327, + 124.77650539945358, 110.41200699229772, 128.38200813032248) + ..cubicTo(112.762, 135.252, 114.50200000000001, 143.862, 116.232, 154.452) + ..close(); + + final Path intersect = bottom.applyOp(top, PathOp.intersect); + // current revision of Skia makes this result in a quad verb getting used. + final Path difference = bottom.applyOp(intersect, PathOp.difference); + + expect(difference.verbs.toList(), [ + PathVerb.moveTo, + PathVerb.lineTo, + PathVerb.cubicTo, + PathVerb.cubicTo, + PathVerb.quadTo, + PathVerb.cubicTo, + PathVerb.cubicTo, + PathVerb.cubicTo, + PathVerb.cubicTo, + PathVerb.cubicTo, + PathVerb.cubicTo, + PathVerb.cubicTo, + PathVerb.lineTo, + PathVerb.lineTo, + PathVerb.lineTo, + PathVerb.cubicTo, + PathVerb.cubicTo, + PathVerb.lineTo, + PathVerb.cubicTo, + PathVerb.cubicTo, + PathVerb.cubicTo, + PathVerb.close, + ]); + }); +} diff --git a/packages/vector_graphics_compiler/test/path_test.dart b/packages/vector_graphics_compiler/test/path_test.dart new file mode 100644 index 000000000000..127a309aa245 --- /dev/null +++ b/packages/vector_graphics_compiler/test/path_test.dart @@ -0,0 +1,645 @@ +// 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:math' as math; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; + +void main() { + test('SVG Path tests', () { + Path path = parseSvgPathData( + 'M22.1595 3.80852C19.6789 1.35254 16.3807 -4.80966e-07 12.8727 ' + '-4.80966e-07C9.36452 -4.80966e-07 6.06642 1.35254 3.58579 3.80852C1.77297 5.60333 ' + '0.53896 7.8599 0.0171889 10.3343C-0.0738999 10.7666 0.206109 11.1901 0.64265 ' + '11.2803C1.07908 11.3706 1.50711 11.0934 1.5982 10.661C2.05552 8.49195 3.13775 6.51338 4.72783 ' + '4.9391C9.21893 0.492838 16.5262 0.492728 21.0173 4.9391C25.5082 9.38548 25.5082 16.6202 ' + '21.0173 21.0667C16.5265 25.5132 9.21893 25.5133 4.72805 21.0669C3.17644 19.5307 2.10538 ' + '17.6035 1.63081 15.4937C1.53386 15.0627 1.10252 14.7908 0.66697 14.887C0.231645 14.983 ' + '-0.0427272 15.4103 0.0542205 15.8413C0.595668 18.2481 1.81686 20.4461 3.5859 ' + '22.1976C6.14623 24.7325 9.50955 26 12.8727 26C16.236 26 19.5991 24.7326 22.1595 22.1976C27.2802 ' + '17.1277 27.2802 8.87841 22.1595 3.80852Z'); + expect( + path.toFlutterString(), + 'Path()\n' + ' ..moveTo(22.1595, 3.80852)\n' + ' ..cubicTo(19.6789, 1.35254, 16.3807, -4.809659999999999e-7, 12.8727, -4.809659999999999e-7)\n' + ' ..cubicTo(9.36452, -4.809659999999999e-7, 6.06642, 1.35254, 3.5857900000000003, 3.80852)\n' + ' ..cubicTo(1.77297, 5.60333, 0.53896, 7.8599, 0.017188900000000007, 10.3343)\n' + ' ..cubicTo(-0.0738999, 10.7666, 0.20610900000000001, 11.1901, 0.6426500000000002, 11.2803)\n' + ' ..cubicTo(1.07908, 11.3706, 1.50711, 11.0934, 1.5982, 10.661)\n' + ' ..cubicTo(2.05552, 8.49195, 3.13775, 6.51338, 4.72783, 4.9391)\n' + ' ..cubicTo(9.21893, 0.49283800000000005, 16.5262, 0.49272800000000005, 21.0173, 4.9391)\n' + ' ..cubicTo(25.5082, 9.38548, 25.5082, 16.6202, 21.0173, 21.0667)\n' + ' ..cubicTo(16.5265, 25.5132, 9.21893, 25.5133, 4.72805, 21.0669)\n' + ' ..cubicTo(3.17644, 19.5307, 2.10538, 17.6035, 1.63081, 15.4937)\n' + ' ..cubicTo(1.53386, 15.0627, 1.10252, 14.7908, 0.6669700000000002, 14.887)\n' + ' ..cubicTo(0.23164500000000002, 14.983, -0.04272720000000001, 15.4103, 0.05422050000000001, 15.8413)\n' + ' ..cubicTo(0.5956680000000001, 18.2481, 1.8168600000000001, 20.4461, 3.5859, 22.1976)\n' + ' ..cubicTo(6.14623, 24.7325, 9.50955, 26.0, 12.8727, 26.0)\n' + ' ..cubicTo(16.236, 26.0, 19.5991, 24.7326, 22.1595, 22.1976)\n' + ' ..cubicTo(27.2802, 17.1277, 27.2802, 8.87841, 22.1595, 3.80852)\n' + ' ..close();', + ); + + path = parseSvgPathData('M10 10L20 20'); + + expect( + path.toFlutterString(), + 'Path()\n' + ' ..moveTo(10.0, 10.0)\n' + ' ..lineTo(20.0, 20.0);', + ); + }); + + test('addRect', () { + final PathBuilder builder = PathBuilder() + ..addRect(const Rect.fromLTRB(10, 10, 20, 20)); + + expect( + builder.toPath().toFlutterString(), + 'Path()\n' + ' ..moveTo(10.0, 10.0)\n' + ' ..lineTo(20.0, 10.0)\n' + ' ..lineTo(20.0, 20.0)\n' + ' ..lineTo(10.0, 20.0)\n' + ' ..close();', + ); + }); + + test('addOval', () { + final PathBuilder builder = PathBuilder() + ..addOval(const Rect.fromLTRB(10, 10, 20, 20)) + ..addOval(const Rect.fromLTRB(50, 50, 80, 70)); + expect( + builder.toPath().toFlutterString(), + 'Path()\n' + ' ..moveTo(15.0, 10.0)\n' + ' ..cubicTo(17.75957512247, 10.0, 20.0, 12.24042487753, 20.0, 15.0)\n' + ' ..cubicTo(20.0, 17.75957512247, 17.75957512247, 20.0, 15.0, 20.0)\n' + ' ..cubicTo(12.24042487753, 20.0, 10.0, 17.75957512247, 10.0, 15.0)\n' + ' ..cubicTo(10.0, 12.24042487753, 12.24042487753, 10.0, 15.0, 10.0)\n' + ' ..close()\n' + ' ..moveTo(65.0, 50.0)\n' + ' ..cubicTo(73.27872536741, 50.0, 80.0, 54.48084975506, 80.0, 60.0)\n' + ' ..cubicTo(80.0, 65.51915024494, 73.27872536741, 70.0, 65.0, 70.0)\n' + ' ..cubicTo(56.72127463259, 70.0, 50.0, 65.51915024494, 50.0, 60.0)\n' + ' ..cubicTo(50.0, 54.48084975506, 56.72127463259, 50.0, 65.0, 50.0)\n' + ' ..close();', + ); + }); + + test('addRRect', () { + final PathBuilder builder = PathBuilder() + ..addRRect(const Rect.fromLTRB(20, 20, 60, 60), 5, 5); + expect( + builder.toPath().toFlutterString(), + 'Path()\n' + ' ..moveTo(25.0, 20.0)\n' + ' ..lineTo(55.0, 20.0)\n' + ' ..cubicTo(57.75957512247, 20.0, 60.0, 22.24042487753, 60.0, 25.0)\n' + ' ..lineTo(60.0, 55.0)\n' + ' ..cubicTo(60.0, 57.75957512247, 57.75957512247, 60.0, 55.0, 60.0)\n' + ' ..lineTo(25.0, 60.0)\n' + ' ..cubicTo(22.24042487753, 60.0, 20.0, 57.75957512247, 20.0, 55.0)\n' + ' ..lineTo(20.0, 25.0)\n' + ' ..cubicTo(20.0, 22.24042487753, 22.24042487753, 20.0, 25.0, 20.0)\n' + ' ..close();', + ); + }); + + test('reset/no reset', () { + final PathBuilder builder = PathBuilder()..lineTo(10, 10); + + final Path a = builder.toPath(reset: false); + final Path b = builder.toPath(); + final Path c = builder.toPath(); + + expect(a, b); + expect(identical(a, b), false); + expect(a != c, true); + expect(c.isEmpty, true); + }); + + test('PathBuilder.fromPath', () { + final PathBuilder builder = PathBuilder()..lineTo(10, 10); + + final Path a = builder.toPath(); + + final PathBuilder builderA = PathBuilder.fromPath(a); + final Path b = builderA.toPath(); + + expect(a, b); + expect(identical(a, b), false); + }); + + test('transforms', () { + Path path = parseSvgPathData( + 'M22.1595 3.80852C19.6789 1.35254 16.3807 -4.80966e-07 12.8727 ' + '-4.80966e-07C9.36452 -4.80966e-07 6.06642 1.35254 3.58579 3.80852C1.77297 5.60333 ' + '0.53896 7.8599 0.0171889 10.3343C-0.0738999 10.7666 0.206109 11.1901 0.64265 ' + '11.2803C1.07908 11.3706 1.50711 11.0934 1.5982 10.661C2.05552 8.49195 3.13775 6.51338 4.72783 ' + '4.9391C9.21893 0.492838 16.5262 0.492728 21.0173 4.9391C25.5082 9.38548 25.5082 16.6202 ' + '21.0173 21.0667C16.5265 25.5132 9.21893 25.5133 4.72805 21.0669C3.17644 19.5307 2.10538 ' + '17.6035 1.63081 15.4937C1.53386 15.0627 1.10252 14.7908 0.66697 14.887C0.231645 14.983 ' + '-0.0427272 15.4103 0.0542205 15.8413C0.595668 18.2481 1.81686 20.4461 3.5859 ' + '22.1976C6.14623 24.7325 9.50955 26 12.8727 26C16.236 26 19.5991 24.7326 22.1595 22.1976C27.2802 ' + '17.1277 27.2802 8.87841 22.1595 3.80852Z'); + expect( + path.transformed(AffineMatrix.identity).toFlutterString(), + 'Path()\n' + ' ..moveTo(22.1595, 3.80852)\n' + ' ..cubicTo(19.6789, 1.35254, 16.3807, -4.809659999999999e-7, 12.8727, -4.809659999999999e-7)\n' + ' ..cubicTo(9.36452, -4.809659999999999e-7, 6.06642, 1.35254, 3.5857900000000003, 3.80852)\n' + ' ..cubicTo(1.77297, 5.60333, 0.53896, 7.8599, 0.017188900000000007, 10.3343)\n' + ' ..cubicTo(-0.0738999, 10.7666, 0.20610900000000001, 11.1901, 0.6426500000000002, 11.2803)\n' + ' ..cubicTo(1.07908, 11.3706, 1.50711, 11.0934, 1.5982, 10.661)\n' + ' ..cubicTo(2.05552, 8.49195, 3.13775, 6.51338, 4.72783, 4.9391)\n' + ' ..cubicTo(9.21893, 0.49283800000000005, 16.5262, 0.49272800000000005, 21.0173, 4.9391)\n' + ' ..cubicTo(25.5082, 9.38548, 25.5082, 16.6202, 21.0173, 21.0667)\n' + ' ..cubicTo(16.5265, 25.5132, 9.21893, 25.5133, 4.72805, 21.0669)\n' + ' ..cubicTo(3.17644, 19.5307, 2.10538, 17.6035, 1.63081, 15.4937)\n' + ' ..cubicTo(1.53386, 15.0627, 1.10252, 14.7908, 0.6669700000000002, 14.887)\n' + ' ..cubicTo(0.23164500000000002, 14.983, -0.04272720000000001, 15.4103, 0.05422050000000001, 15.8413)\n' + ' ..cubicTo(0.5956680000000001, 18.2481, 1.8168600000000001, 20.4461, 3.5859, 22.1976)\n' + ' ..cubicTo(6.14623, 24.7325, 9.50955, 26.0, 12.8727, 26.0)\n' + ' ..cubicTo(16.236, 26.0, 19.5991, 24.7326, 22.1595, 22.1976)\n' + ' ..cubicTo(27.2802, 17.1277, 27.2802, 8.87841, 22.1595, 3.80852)\n' + ' ..close();', + ); + + expect( + path + .transformed(AffineMatrix.identity.rotated(math.pi / 2)) + .toFlutterString(), + 'Path()\n' + ' ..moveTo(-3.808519999999999, 22.1595)\n' + ' ..cubicTo(-1.352539999999999, 19.6789, 4.809660010030285e-7, 16.3807, 4.809660007882255e-7, 12.8727)\n' + ' ..cubicTo(4.809660005734114e-7, 9.36452, -1.3525399999999996, 6.06642, -3.80852, 3.5857900000000007)\n' + ' ..cubicTo(-5.60333, 1.7729700000000004, -7.8599, 0.5389600000000004, -10.3343, 0.01718890000000064)\n' + ' ..cubicTo(-10.7666, -0.07389989999999934, -11.1901, 0.2061090000000007, -11.2803, 0.6426500000000008)\n' + ' ..cubicTo(-11.3706, 1.0790800000000007, -11.0934, 1.5071100000000006, -10.661, 1.5982000000000007)\n' + ' ..cubicTo(-8.49195, 2.0555200000000005, -6.51338, 3.1377500000000005, -4.9391, 4.72783)\n' + ' ..cubicTo(-0.4928379999999995, 9.21893, -0.49272799999999906, 16.5262, -4.939099999999999, 21.0173)\n' + ' ..cubicTo(-9.385479999999998, 25.5082, -16.6202, 25.5082, -21.0667, 21.0173)\n' + ' ..cubicTo(-25.5132, 16.5265, -25.5133, 9.218930000000002, -21.0669, 4.7280500000000005)\n' + ' ..cubicTo(-19.5307, 3.1764400000000013, -17.6035, 2.1053800000000007, -15.4937, 1.630810000000001)\n' + ' ..cubicTo(-15.0627, 1.533860000000001, -14.7908, 1.1025200000000008, -14.887, 0.6669700000000011)\n' + ' ..cubicTo(-14.983, 0.23164500000000093, -15.4103, -0.04272719999999906, -15.8413, 0.05422050000000098)\n' + ' ..cubicTo(-18.2481, 0.5956680000000012, -20.4461, 1.8168600000000015, -22.1976, 3.5859000000000014)\n' + ' ..cubicTo(-24.7325, 6.146230000000002, -26.0, 9.509550000000003, -26.0, 12.872700000000002)\n' + ' ..cubicTo(-26.0, 16.236, -24.7326, 19.5991, -22.1976, 22.1595)\n' + ' ..cubicTo(-17.1277, 27.2802, -8.878409999999999, 27.2802, -3.808519999999999, 22.1595)\n' + ' ..close();', + ); + + path = parseSvgPathData('M10 10L20 20'); + + expect( + path + .transformed(AffineMatrix.identity.translated(10, 10)) + .toFlutterString(), + 'Path()\n' + ' ..moveTo(20.0, 20.0)\n' + ' ..lineTo(30.0, 30.0);', + ); + }); + + test('Compute path bounds with rect', () { + final PathBuilder builder = PathBuilder() + ..addRect(const Rect.fromLTWH(5, 5, 95, 95)) + ..close(); + final Path path = builder.toPath(); + + expect(path.bounds(), const Rect.fromLTWH(5, 5, 95, 95)); + }); + + test('Compute path bounds with lines', () { + final PathBuilder builder = PathBuilder() + ..moveTo(0, 0) + ..lineTo(25, 0) + ..lineTo(25, 25) + ..lineTo(0, 25) + ..close(); + final Path path = builder.toPath(); + + expect(path.bounds(), const Rect.fromLTWH(0, 0, 25, 25)); + }); + + test('Compute path bounds with cubics', () { + final PathBuilder builder = PathBuilder() + ..moveTo(0, 0) + ..cubicTo(10, 10, 20, 20, -10, -10) + ..close(); + final Path path = builder.toPath(); + + expect(path.bounds(), const Rect.fromLTRB(-10.0, -10.0, 20.0, 20.0)); + }); + + test('Compute cubic bounds where R and B are negative', () { + const Rect circle = Rect.fromCircle(-83.533, -122.753, 74.461); + final Path path = PathBuilder().addOval(circle).toPath(); + expect(path.bounds(), circle); + }); + + test('Cubic length', () { + // Value is very close to what Skia says for same input. + const CubicToCommand command = + CubicToCommand(1.0, 15.327, 15.326, 1.0, 33.0, 1.0); + expect(command.computeLength(Point.zero), 38.16245134493276); + + // Trivially describes a line. + const CubicToCommand command2 = CubicToCommand(0, 0, 0, 10, 0, 10); + expect(command2.computeLength(Point.zero), 10); + }); + + test('Cubic splitting', () { + expect( + CubicToCommand.subdivide( + Point.zero, + const Point(1, 15), + const Point(15, 1), + const Point(33, 1), + .4, + ), + const [ + Point.zero, + Point(0.4, 6.0), + Point(2.88, 7.359999999999999), + Point(6.864, 6.832), + Point(12.84, 6.04), + Point(22.200000000000003, 1.0), + Point(33.0, 1.0) + ], + ); + }); + + test('Dashed path - cubic 1', () { + final Path cubic1 = parseSvgPathData( + 'M65 33c0 17.673-14.326 32-32 32S1 50.673 1 33C1 15.327 15.326 1 33 1s32 14.327 32 32z'); + + expect( + cubic1.dashed([2, 5.94]), + Path( + commands: const [ + MoveToCommand(65.0, 33.0), + CubicToCommand(65.0, 33.70763536030907, 64.97703198598045, + 34.40990628009675, 64.93180068504239, 35.106107839678536), + MoveToCommand(63.95590821783997, 41.138570321608114), + CubicToCommand( + 63.78388200211823, + 41.79470101955482, + 63.591548343963595, + 42.442608960532986, + 63.37961933238859, + 43.08158186093479), + MoveToCommand(60.9913809985287, 48.519833069956164), + CubicToCommand( + 60.668492690302394, + 49.100962858508964, + 60.32803245363184, + 49.6709842212665, + 59.97071797737027, + 50.22917927324997), + MoveToCommand(56.349259058467936, 54.88222449322346), + CubicToCommand( + 55.900015721696754, + 55.36139696181796, + 55.43619093879707, + 55.82673409716467, + 54.958492499076485, + 56.27752791653569), + MoveToCommand(50.36747808861274, 59.88172317266531), + CubicToCommand( + 49.82068927796797, + 60.23570903270937, + 49.26241388099913, + 60.57346570952925, + 48.6933336310888, + 60.894311283442455), + MoveToCommand(43.3292530683581, 63.29637356816345), + CubicToCommand( + 42.71018120276065, + 63.50737099626945, + 42.082572102791204, + 63.69992743387707, + 41.447080444962786, + 63.87338802556734), + MoveToCommand(35.630945421656286, 64.89340586107826), + CubicToCommand( + 34.97191375239566, + 64.94703220278787, + 34.30723211065745, + 64.98069119320479, + 33.637506242045006, + 64.99377692119126), + MoveToCommand(27.497686697670588, 64.52877424012252), + CubicToCommand( + 26.821431561562925, + 64.41158787290307, + 26.152455351357716, + 64.27317574141253, + 25.49146906822908, + 64.11424904112303), + MoveToCommand(19.829734138714148, 62.17288407887853), + CubicToCommand( + 19.22254029238493, + 61.89834087441918, + 18.625447859490016, + 61.60539834563903, + 18.03916772219419, + 61.29476756896835), + MoveToCommand(13.123453402340228, 58.08021292143201), + CubicToCommand( + 12.606563474017639, + 57.67001905040603, + 12.102648327670325, + 57.244183807034666, + 11.612423197029361, + 56.80342262050364), + MoveToCommand(7.634684007455509, 52.51189122452449), + CubicToCommand( + 7.236391480757161, + 51.99487385892312, + 6.853553118859099, + 51.46533727229267, + 6.486860221302153, + 50.923972953088025), + MoveToCommand(3.672998384894739, 45.82384400992106), + CubicToCommand( + 3.410525278026412, + 45.22442217885262, + 3.1658907799562406, + 44.61540918759221, + 2.9397661639663557, + 43.997476492863385), + MoveToCommand(1.4383854599561599, 38.30920094462239), + CubicToCommand( + 1.3301369848492222, + 37.660898732125794, + 1.2413788962838397, + 37.00599786367147, + 1.1727338823578792, + 36.34512119752162), + MoveToCommand(1.1140602215592654, 30.278918052611246), + CubicToCommand( + 1.1724789949662897, + 29.58512444526761, + 1.2530318675342023, + 28.897630742351822, + 1.355010329306275, + 28.21714564743783), + MoveToCommand(2.813895354454088, 22.352839675947116), + CubicToCommand( + 3.037366664760353, + 21.719242963796532, + 3.2802211823279825, + 21.094791779246986, + 3.5417468824172644, + 20.48019834161591), + MoveToCommand(6.34621623119101, 15.285435280579309), + CubicToCommand( + 6.714032665445101, + 14.73310174588461, + 7.098560403588749, + 14.192851911447924, + 7.499077458587648, + 13.665407961603714), + MoveToCommand(11.461835455942882, 9.332832232296191), + CubicToCommand( + 11.945763342108913, + 8.892180194722316, + 12.44325896152358, + 8.466169418310185, + 12.953622282985162, + 8.055500125561714), + MoveToCommand(17.807192192563488, 4.829368065777091), + CubicToCommand( + 18.384146248584546, + 4.517560722634985, + 18.971766599642926, + 4.22296045700293, + 19.5693656981362, + 3.946255004372108), + MoveToCommand(25.105444010192507, 1.9811251891028818), + CubicToCommand( + 25.74028000900354, + 1.8200561533454764, + 26.382686089997996, + 1.6779627249499476, + 27.032023265982627, + 1.5554840657280102), + MoveToCommand(32.94511841345392, 1.0000460546288212), + CubicToCommand(32.96340867914606, 1.000015355604456, + 32.981702545388494, 1.0, 33.0, 1.0), + CubicToCommand(33.6882562195718, 1.0, 34.37143533540402, + 1.0217263038461621, 35.04888905781622, 1.0645304446974477), + MoveToCommand(41.084875326577645, 2.030039591233501), + CubicToCommand( + 41.74147663234361, + 2.200961034160867, + 42.38987221052307, + 2.3922104375592332, + 43.029349965306906, + 2.6030755110223245), + MoveToCommand(48.472612206885536, 4.982395187695522), + CubicToCommand( + 49.05438116106162, + 5.304353344751444, + 49.62505841296779, + 5.643905011918012, + 50.18392615788486, + 6.000332188318815), + MoveToCommand(54.84351930781497, 9.614505510093846), + CubicToCommand( + 55.323479280858734, + 10.063008836851036, + 55.78961965045844, + 10.526114893814489, + 56.24123242758923, + 11.00311549848448), + MoveToCommand(59.853140416091875, 15.58850419596532), + CubicToCommand( + 60.20803756757811, + 16.134740492295958, + 60.54671980770702, + 16.69248333095327, + 60.868505145713, + 17.261050534801427), + MoveToCommand(63.27947749389385, 22.621402004854463), + CubicToCommand( + 63.49149442978085, + 23.240129771843495, + 63.68508101683114, + 23.867413675066253, + 63.859582179442924, + 24.50259845990592), + MoveToCommand(64.88908365060104, 30.31651883115104), + CubicToCommand( + 64.9437829347059, + 30.975372322751923, + 64.97852291408398, + 31.639891900169225, + 64.99269741829195, + 32.309471227309054), + ], + ), + ); + }); + + test('Dashed paths - cubic 2', () { + final Path cubic2 = parseSvgPathData( + 'M20 39c10.493 0 19-8.507 19-19S30.493 1 20 1 1 9.507 1 20s8.507 19 19 19z'); + + final Path dashed = cubic2.dashed([2, 6]); + expect( + dashed, + Path( + commands: const [ + MoveToCommand(20.0, 39.0), + CubicToCommand(20.707618776439247, 39.0, 21.4062056638081, + 38.96131204414812, 22.093760739330435, 38.88593605522049), + MoveToCommand(27.941787133378586, 37.26550076491443), + CubicToCommand( + 28.552828792067846, + 36.98395247399771, + 29.146376269127835, + 36.67092015975091, + 29.72035001637582, + 36.32848337035675), + MoveToCommand(34.28872657525249, 32.52332807494088), + CubicToCommand( + 34.72002359056755, + 32.03163198310322, + 35.12634784297375, + 31.51748652496024, + 35.50571809622244, + 30.9828729367606), + MoveToCommand(38.15063297069716, 25.634183986854904), + CubicToCommand( + 38.344405068145036, + 25.00930101075243, + 38.506794068808375, + 24.3706162148244, + 38.63595727148749, + 23.71997230027049), + MoveToCommand(38.854396196856676, 17.636338403239797), + CubicToCommand( + 38.76922952234208, + 16.950072134496082, + 38.647462472510895, + 16.275154057296998, + 38.49110936584479, + 15.613598490124222), + MoveToCommand(36.156993272025055, 9.997799228160478), + CubicToCommand( + 35.806275376209854, + 9.432491207486724, + 35.4267166755551, + 8.886947549472037, + 35.02037300554141, + 8.363224089597036), + MoveToCommand(30.714494314385455, 4.307279443052996), + CubicToCommand( + 30.170446598805572, + 3.9350931692753632, + 29.606060167556546, + 3.5904613343389835, + 29.023345848321203, + 3.2753947659266824), + MoveToCommand(23.398670360690218, 1.303142250295933), + CubicToCommand( + 22.75231244012423, + 1.1864084956688012, + 22.094586719261592, + 1.102371988982065, + 21.42726782093816, + 1.0528073530715703), + MoveToCommand(15.312878715409806, 1.5825736677487203), + CubicToCommand( + 14.645620930686587, + 1.7518831987472228, + 13.992442800092594, + 1.956503341694209, + 13.35545017026537, + 2.1943282499521333), + MoveToCommand(8.126992325034307, 5.1659142014116854), + CubicToCommand(7.612222375568647, 5.578470802327974, 7.11938698608979, + 6.017265988457743, 6.6505146434356375, 6.480271272963089), + MoveToCommand(3.144680725594728, 11.22271551538195), + CubicToCommand( + 2.841419027240009, + 11.803860948679425, + 2.5673312422713543, + 12.402645469100445, + 2.324360556848317, + 13.017125890485456), + MoveToCommand(1.0338820704843192, 18.855919027319942), + CubicToCommand(1.0114006643291984, 19.23440453004496, 1.0, + 19.61587149510607, 1.0, 20.0), + CubicToCommand(1.0, 20.30265471646772, 1.0070773712819083, + 20.603657186624655, 1.0210756343203329, 20.902850930945412), + MoveToCommand(2.285459600751064, 26.883674148689185), + CubicToCommand( + 2.530950502455319, + 27.514930621208894, + 2.809211392982629, + 28.12982234128287, + 3.118152746709571, + 28.7262597832877), + MoveToCommand(6.658084504103845, 33.527199707900266), + CubicToCommand( + 7.124854343878676, + 33.98761626048461, + 7.615335906786609, + 34.424054910109746, + 8.127531169442356, + 34.8345176333904), + MoveToCommand(13.322396345361739, 37.79329566146798), + CubicToCommand( + 13.93468962982282, + 38.02320534530446, + 14.561997661390594, + 38.22241500364579, + 15.202445231678627, + 38.38904942810554), + ], + ), + ); + }); + + test('Dashed path - lines/closes', () { + final Path path = parseSvgPathData('M1 20L20 20L20 39L30 30L1 26z'); + expect( + path.dashed([5, 3, 5, 5]), + Path( + commands: const [ + MoveToCommand(1.0, 20.0), + LineToCommand(6.0, 20.0), + MoveToCommand(9.0, 20.0), + LineToCommand(13.999999999999998, 20.0), + MoveToCommand(18.999999999999996, 20.0), + LineToCommand(20.0, 20.0), + LineToCommand(20.0, 24.0), + MoveToCommand(20.0, 27.000000000000004), + LineToCommand(20.0, 32.0), + MoveToCommand(20.0, 37.0), + LineToCommand(20.0, 39.0), + LineToCommand(22.229882438741498, 36.99310580513265), + MoveToCommand(24.459764877482996, 34.9862116102653), + LineToCommand(28.17623560871883, 31.641387952153053), + MoveToCommand(27.47750617803373, 29.65206981765983), + LineToCommand(22.524400531816358, 28.96888283197467), + MoveToCommand(19.55253714408593, 28.55897064056358), + LineToCommand(14.599431497868558, 27.875783654878425), + MoveToCommand(9.646325851651186, 27.19259666919327), + LineToCommand(4.693220205433812, 26.509409683508114), + MoveToCommand(1.7213568177033882, 26.09949749209702), + LineToCommand(1.0, 26.0), + LineToCommand(1.0, 21.72818638368261), + ], + ), + ); + }); +} diff --git a/packages/vector_graphics_compiler/test/resolver_test.dart b/packages/vector_graphics_compiler/test/resolver_test.dart new file mode 100644 index 000000000000..c8ea93b10f7c --- /dev/null +++ b/packages/vector_graphics_compiler/test/resolver_test.dart @@ -0,0 +1,172 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:vector_graphics_compiler/src/geometry/basic_types.dart'; +import 'package:vector_graphics_compiler/src/geometry/matrix.dart'; +import 'package:vector_graphics_compiler/src/geometry/path.dart'; +import 'package:vector_graphics_compiler/src/paint.dart'; +import 'package:vector_graphics_compiler/src/svg/node.dart'; +import 'package:vector_graphics_compiler/src/svg/parser.dart'; +import 'package:vector_graphics_compiler/src/svg/resolver.dart'; + +import 'helpers.dart'; + +void main() { + test('viewport node inheritence', () { + final Node node = parseToNodeTree(''' + + + +'''); + final Node resolvedNode = + node.accept(ResolvingVisitor(), AffineMatrix.identity); + final List nodes = + queryChildren(resolvedNode); + + expect(nodes.length, 2); + expect( + nodes.first.paint, + const Paint(fill: Fill(color: Color(0xFFFF0000))), + ); + expect( + nodes.last.paint, + const Paint(fill: Fill(color: Color(0xFFFF0000))), + ); + }); + + test('group opacity node inheritence', () { + final Node node = parseToNodeTree(''' + + + + + +'''); + final Node resolvedNode = + node.accept(ResolvingVisitor(), AffineMatrix.identity); + final List nodes = + queryChildren(resolvedNode); + final SaveLayerNode saveLayerNode = + queryChildren(resolvedNode).single; + + expect(saveLayerNode.paint.fill!.color, const Color(0x7FFF0000)); + + expect(nodes.length, 2); + + // Opacity is not inherited since it is applied in a saveLayer. + expect( + nodes.first.paint, + const Paint(fill: Fill(color: Color(0xFFFF0000))), + ); + expect( + nodes.last.paint, + const Paint(fill: Fill(color: Color(0xFFFF0000))), + ); + }); + + test( + 'Resolves PathNodes to ResolvedPathNodes by flattening the transform ' + 'and computing bounds', () async { + final Node node = parseToNodeTree(''' + + + + +'''); + final Node resolvedNode = + node.accept(ResolvingVisitor(), AffineMatrix.identity); + final List nodes = + queryChildren(resolvedNode); + + expect(nodes.length, 1); + + final ResolvedPathNode resolvedPathNode = nodes[0]; + + expect(resolvedPathNode.bounds, const Rect.fromLTWH(10, 10, 10, 10)); + expect( + resolvedPathNode.path, + Path( + commands: const [ + MoveToCommand(10.0, 10.0), + LineToCommand(20.0, 10.0), + LineToCommand(20.0, 20.0), + LineToCommand(10.0, 20.0), + CloseCommand(), + ], + ), + ); + }); + + test('Resolving Nodes replaces empty text with Node.zero', () async { + final Node node = parseToNodeTree(''' + + + '''); + final Node resolvedNode = + node.accept(ResolvingVisitor(), AffineMatrix.identity); + final List nodes = + queryChildren(resolvedNode); + + expect(nodes, isEmpty); + }); + + test('Resolving Nodes removes unresolved masks', () async { + final Node node = parseToNodeTree(''' + + + + +'''); + + final Node resolvedNode = + node.accept(ResolvingVisitor(), AffineMatrix.identity); + final List nodes = + queryChildren(resolvedNode); + + expect(nodes, isEmpty); + }); + + test('visitChildren on clips and masks', () { + final ResolvedClipNode clip = ResolvedClipNode( + clips: [], + child: Node.empty, + ); + + final ResolvedMaskNode mask = ResolvedMaskNode( + child: Node.empty, + mask: Node.empty, + blendMode: BlendMode.color, + ); + + int visitCount = 0; + clip.visitChildren((Node child) { + visitCount += 1; + expect(child, Node.empty); + }); + mask.visitChildren((Node child) { + visitCount += 1; + expect(child, Node.empty); + }); + + expect(visitCount, 2); + }); + + test('Image transform', () async { + final Node node = parseToNodeTree(''' + + +'''); + final Node resolvedNode = + node.accept(ResolvingVisitor(), AffineMatrix.identity); + final ResolvedImageNode imageNode = + queryChildren(resolvedNode).single; + expect( + imageNode.transform, + const AffineMatrix(1.0, 0.0, 0.0, -1.0, 50.0, 50.0), + ); + }); +} diff --git a/packages/vector_graphics_compiler/test/tessellator_test.dart b/packages/vector_graphics_compiler/test/tessellator_test.dart new file mode 100644 index 000000000000..46c000dba3b2 --- /dev/null +++ b/packages/vector_graphics_compiler/test/tessellator_test.dart @@ -0,0 +1,48 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:vector_graphics_compiler/src/svg/node.dart'; +import 'package:vector_graphics_compiler/src/svg/parser.dart'; +import 'package:vector_graphics_compiler/src/svg/tessellator.dart'; +import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; + +import 'helpers.dart'; + +void main() { + setUpAll(() { + if (!initializeTessellatorFromFlutterCache()) { + fail('error in setup'); + } + }); + + test('Can convert simple shape to indexed vertices', () async { + final Node node = parseToNodeTree(''' + + +'''); + Node resolvedNode = node.accept(ResolvingVisitor(), AffineMatrix.identity); + resolvedNode = resolvedNode.accept(Tessellator(), null); + + final ResolvedVerticesNode verticesNode = + queryChildren(resolvedNode).single; + + expect(verticesNode.bounds, const Rect.fromLTWH(0, 0, 10, 10)); + expect(verticesNode.vertices.vertices, [ + 0.0, + 10.0, + 10.0, + 0.0, + 10.0, + 10.0, + 10.0, + 0.0, + 0.0, + 10.0, + 0.0, + 0.0 + ]); + expect(verticesNode.vertices.indices, null); + }); +} diff --git a/packages/vector_graphics_compiler/test/test_svg_strings.dart b/packages/vector_graphics_compiler/test/test_svg_strings.dart new file mode 100644 index 000000000000..66f135a89514 --- /dev/null +++ b/packages/vector_graphics_compiler/test/test_svg_strings.dart @@ -0,0 +1,1493 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:vector_graphics_compiler/src/geometry/path.dart'; + +const List allSvgTestStrings = [ + ghostscriptTiger, + simpleUseCircles, + basicOpacity, + groupOpacity, + basicMask, + groupMask, + basicClip, + multiClip, + blendAndMask, + outOfOrderGradientDef, + xlinkGradient, + basicText, + pathAndParent, + svgInlineImage, + basicOverlap, + opacityOverlap, + solidOverTrasnparent, + transparentOverSolid, + complexOpacityTest, +]; + +const String kBase64ImageContents = + 'iVBORw0KGgoAAAANSUhEUgAAAkoAAACqCAYAAABS+GAyAAAACXBIWXMAAAsSAAALEgHS3X78AAAaD0lEQVR4nO3da4wd1WHA8TP3rnlVzW6gogIUdlVFQSRRvSlNv6VeolYJT6+JIahSxSJFEV8qjPqh/cb6W6UWsXyqGqVlLbVKAgbbqQqtmmA7PA1ts2552g71QhNjG5NdjF/43jvV3D1nPb5779w5Z86cOTPz/ykbDHsfs3PXe/975syZIAxDAXuefL/dePZIe3s7DDcNe9Cse37Y/Yc+/pAbqE8HQjy18bqRe+7+XLOjsXkAAJReg5fQHhVJHRFuCoISbHCKbSSSAAB1RihZEo+kSnxBRBIAAGKEXZCdr5EUZDi8FwTi6TuvJZIAAPXGiFJGlRxJWomku4kkAEDdEUoZFB1JeUyDIpIAALiAUDLESBIAANVHKBkgkgAAqAcmc2vqRtIH7ac6Ipwu1YYnIJIAAOiPESUNq5EUEkkAANQBI0opVTGSGkI8fQeRBADAQIwopUAkAQBQT4TSEEQSAAD1RSglIJIAAKg3QmkAIgkAABBKfRBJAABAEEprRZH0b0QSAAC1Jwili6lIahNJAADUnmAdpQuqGkm3E0kAABhjRKnEkRQmfI5IAgAgu9qHEiNJAAAg4T21vgZFUtJIje+IJAAA7KltKDGSBAAAUry31o+LSAodD0sRSQAA2Fe7UGIkCQAAaLzH1odPkWRrwIlIAgAgP7UJpbSRVKaJ3EQSAAD5qsWCkxcuSyKqc7gtEDtuu4ZIAgAgT5UfUapwJG0mkgAAyFelQ6k3kkJHB9byPOONSAIAwJ3KhpLJSJLv85OIJAAA3KpkKPl+uM0kyIgkAADcq1woDYokV4fd8kAkAQBQjEqFUpaRJFsZZXt+EpEEAEBxKhNKSZFU1tEkIgkAgGJVIpTKtARA2mQjkgAAKF7pQ2lYJKUZTfJtvIlIAgDAD6UOJd9GkmzMTyKSSieswccezRdlVnOfzNb9mwiAv0obSmkiybfRpGHPRSQBAOCXUoYSlyUBAAAulC6U0kaS6zPdshx2I5IAAPBTqULJ9kiSD4fdiCQAAPxVmlDSiaSyjCYRSQAA+K0UoZRHJBW9JACRBACA/7wPpTwmbruOpN7nI5IAACiHEZ+3UjeSirhUie5hNyIJgIdmhBATGps1L4Q47NmXobseF+t3IRVvQymvSCrykBuRBMBTUSht0Ni0PR6G0sOatyeUkIqXh97Ksk5SmtEkdRMiCQCA8vFuRMkkknwfTSKSEHNzCXfGkgfbAACF8CqUyhRJaUeTiCT00L1uGgCgQN4cesszkopCJAEAUG5ehFLekVTEaFJAJAEAUHqFH3orWySlEY0k3UokAQBQeoWOKJUxkoaNJhFJAABUR2GhRCQBAADfFRJKHG4DAABl4DyUynp2W9JoEpEEAEA1OZ3M7eLaba6TikgCAKC6nI0olTmSBo0mEUkAAFSbkxElnUgyPcxGJAEAANtyD6W8IynPQ21EEgAA9ZZrKKWNJN9GkZIQSQAA1EduoZQmkrKczZZ3JPUbTSKSAACol1xCaVgkZT3dn0gCAEBMyI8puSumEnbJkhBiQf55jxDisPyok2j/TMp9Npmwj9RHd/9YD6WkSPI9kASRBADw15gQ3ffWKfkxrrmlG+U/H5b/XJRBsFN+LFXwtZ+OfYymuP3G2J/3CyHmrYZSv0iytVgkkQQgJvqNcEZjh0S/Gc57tgPz/BpmDbZFx8yQ0Ys09siPQdujs29M6O6jfuYdjcpMyf1xn+XHHZcfURw8LoTYJYPJ5d8Vndch6Xum14x8bN2YjFsvhHjUWijFI8n2StpFrctNJAHemoj9VpzGXk9DKa+vQedxTdh6w04Kpby/BhuPvyfnUIre7LfIN2wXNsqPudhH3qNMuq/DsFCakn9PsgTSRawsOKkiqR2GViMpdBhJvaNJRBIAoCCTMggedxhJcaMyYKII3FKSb4IxORq222YkCRuhFI8kO5vkNpAEkQQA8MOYHMn5uRBigwdbFAXTo3IeU7/Jz76YlNu4MY/tyRRKtiPJdSAJIgkA4Ac1ivSgh6/Herltec8bM6H2m9VRpDjjULIZSUUEkiCSAAB+mJZv9kUcZktrVB4K9Gmun4qkNGezGTMKJVuRVFQgCSIJAOCHaJRmR95v9hbdJw9zjRW8HU4iSZiEko1IKjKQBJEEAPDDrBylKRt1KK6oWBqTI1tO4lIrlLJEUuhBIAkiCQDghxkHSyDkab3Gmka2zbo8TJl6HSWTSCo6iuJYTBIA4IkZiyNJy/JQ2B75T7Xu0YJcj0qN+sQvd2LrjLr1cmTH5STvCdcT3lOFUtpI8imM4ogkAIAnJi1F0i4ZKTsTbrOQ8Dl1aY+si4eqOUtzGR8nLdMV1eNBKWJBqUJSXQNuzUjV0FDqF0m+BlE/RBKAGrpZ80ue0zyU8dCQN+E0kla0XjD4GnZr3l738fvR3QdjFg5X7ZKLQGZdEVxd322LjI8sozSPxka08jQh407HttjXmsaYHHVbjcjEUIoi6dnuZUnsLSbpEpEEoKZ034x1L1OxkPP8lCUH81+KmF+TZQLyojzEZXu7l2QszcsP07k/8w4WpdQZ/TINyqWeiJwZGEpljqR+gSQcRtID+07feFY0/yz6cycMg4s3TgSD7heGg7ZcT9oHSfNsYXeLg3D0o48e+tvbr/3UxvYBQA1NZ1g5eq+8f57XXVOrb88bHo5bL0embFxsOItlGZRpR5CSRPt7rm8oEUnmHth35sbTovnm6vYEPV00IJPCpE+uvWHWm2gdPm2cPvMlIgkAjI1lWKhxm+PJ0jOx68zp2iLcXEh3kP0yKK1eqHjN8gBljaQokPyIpMaFSEp5v9TRUkAkBSdPffkfvz72ZoqbAgD622J4yM11JClR1N1vcL/RAi+iu1/OLbIaSaI3lMocSYNUJpIcP1Z32z5c/t1/+uMr37D8sABQJ2OG8bC34GurRbH0mMH9thSwEKWKpFxGslZDqYyRlDSKJEoQSVosPWjah2kf+XD9D26/+n/sPCt6XgLfP6Z4wQBrTEaTFg3O7spDtO17NR/X9ajSct7zt7qhVNZISuIskl41jyTXh9zS+vT/jk3+aNN1/23xIQGgjkxHk2YKnOfTy2RUy+VImPU5Sb0aZYukYaNIwnUkheWJpDS3+3Txg69s3/y5/SkfEgAw2IzBaNJjBV4apJ/Dcq6UjnFHI2LbXOyrlUNvof9rSKYJJFG1SLIozXOeOfj+Tdu/PZ73gmEAUBe6o0nLHpxe34/JNuUdSsuuDvE1oqC45Zrm5oYIdrh4Ql1pA0lUMZIcHnI7887i7+/408//l6WHA4C6m5QjKzqKPLU+icmoUt6h5GxfdUeUfIslFUc6yy+WIZK0ODzkdvqtw1/dcd8X/tPm5gNAzZnM03F1vTQTugs4juZ4Ysiyy321etabD7GkG0dKWSLJ5rwkWw/1yevv/sHO+2/4D3vPCAAwiIRtno4mKTtloOjIK5R2utxXF62jVEQsmYwexVUukhw+XhRJP/7Oja9Z3jQAqLu+V6EfwsYlN/Kmu415hpIza1bmdhFLWeNIqWQkOTrkRiQBQG50A2G5JKGke7JPHhfJdb6v1oSSyCmWbMWRQiSZ345IAoBc6QZCGSJJGITSaA6rdDs/M7tvKImMsRSPIptxpNQ1kmwgkgAgd7qh5NO6SUlMIsX2qJLzfTWS9EkZIpufPdLe3hHhpt7P2w6gNIIaR1LW0SQiyQtbS7CNua5yC9TABs0vcUvB13XL04Tlx3Y+opQYSiIWS88caW3vhGJNLLkSypGk20pw7TYiCQl8XEwOgD0mYaA78btMbIeS8zMDBx56i4vCJBrFiULF2Zb1XDXUVSR996VTX1SRFJYskgYhkgDAGdthgIKlCiXhOJZ6A8VlJJ1tjrwhDOOk6Ejqd1siCQCcsj15uezyOPPNqdShJHKOpXDACA6RZH5bIgkAnCt9GFhW+nDUCiVhOZYGxdHqxjmKpFt3n77lrbONN1qhP5GU9SGJJAAAstMOJZEhlsIUcaS4jKTjreCZMy0h3jvVEW2NkNGew6T52Ka3I5IAALDDKJREyljSCaM4V5F0296z34wiSS1zcLadPpa0B4ZyiKR+iCQAAOwxDiURi6VobaPeKDJ9s3cZSUfPhc/2rgWVJpZ8iaTe2xJJAADPlH5dtkyhJGQs3WZpzpLLw21RJA36fFIsEUkAAKRW+lAauuBkGmpRyn/JsCily0g6dj54ZtjtVCxd/xsN0QwMR8iIJABAsm1CiPkK7yPnK2nbZiWURMZY8i2SlHgsNQLNJyOSAADDHS7Rtd5qKfOhtziTw3Au5yTpRJJypi3E4qmO6GRd1Cj7TYkkAPCf7gjKFK+p36yGktCMJdcTt3XuE5+QflYnlogkAOmwgnM16V6LjO8Dz1kPJZEylnyPpF6pYolIApAeKzhXk+7k5SpfELcScgklMSSWfI2kYcsaDIwlzfUQiCQAqCyTs7yIZo/lFkpiQCz5HElprIklzdPhiCQAEnNTqmuv5lfG94LHcg0l0RNLPkaSyeKYKpbaGl+F7vMQSUDlTfASVxYTuivE2vIASdTSAeLCn3OTNpKyXCYkVGfDne6I8StW1lmy+VxEElB5USSN8zJXlm4obZSTunUngsOB3EeUlCiQqhJJylkZSzYvd0IkAbnwbQ7ItAfbgPyYrIvE94SnnIVS3tJEUpZr0A26b1IsEUmAN0Y9eylmPNgG5Cea0L1f89H5nvBUJUJpWCRlCSSR4r79YolIArzjyzyQCU4JrwXdUaUNzFXyU+lDKSmSbASS1tlwpzuiFRJJgAMmhzZ8Ofw268E2IH8m128rw/fGjJxLNVuXxTJLHUqDIilrIAnD+6+eDZdhTSUiCciND7+tR6NJ93mwHcjfgsHhtw2ez1WKwmhOHsp+WB5irHwwlTaUeiMptBhIWR7jXCd9LBFJQCa6a9Vs9OAHelVGk7jsRjpzBveZ93j/zvfM96tFMJUylOKRZCOObD6OSBlLRBKQmckKyEX+tj5VodGkKqwk7eJriMJiWfM+o4aH7fK2Rf6yMWibVTDNVW2NsNKF0q27T9/ywbnwWZthY+tx4gbFUr/tJpIAIybzlIoa0Rnz9M3PVBVGDlx9DSajShs9G32MovLRFLeLgulBIcT/ej4ypqVUofTNPWe+cfR88Iytx7MZW/30xlK/5yKSAGMmoTRe0GnYOyu2wGQVzs5y9TXMGYwqCTlC48OSAZOGf9cqcwZfaUIpiqTjn4p/tfFYeQdSnIqlVp8nJJKATKJh/kWDB3B9aGBeTtL1me5K0usrcHjF1WHYJXnYysTjBceSiiSTdchmq7LSeClCyVYkuQyk1ecM+58NRyQBVuw0eJBReT8XhwXmSzIvyeQNzbcFEnUn97uMvXmDM+CUxw0P32U1lSGS9lbpULP3oWQjkooIJCEjSTkXiyUiCbDG9IfxevkmkFcsjcnHL8vkbd0RJSFHSXyag2ISey4DJEtYPii/n1yFXTQatNswkpartsq496F0qhP8vel9iwok0RNJShRLr/xk37unn3vZ5IcSgLUWDEYSFBVLts9+mpKHBX0/3BZn8jPJt7OzTObRbHT4ph7t460Z7r9BPkaep+FPyed4OMNjzBqekeot70Pp61c3x68YCX6Z9va21lMyFQVSv0iKHN332vnjB37xO68G4p//6E/+YV1BmwhUTZY36yiWfm7pzWdCHtIz/U28SKbzvTYajszN5PBmahJKQh7a0j3DbEzeR3fu0WyGsBc5rls0Jf8e7c54eZ1tBR0mzJX3obT1y+va3VhqisRYKjKOVrchYQOiSFo6+ItuHLUawTf2NcSP73zgByMONw+oqizzPxT15jOvOcI0Jt/0d8pTogetM9PProxvmraZzPcScqRDvXEnHRqakGFxWMaJ7bMAFwxjT8Re/5kh8TEpQ+CwvI9JqExb+H5VwfRr+boN2+5+JuXrsSADKeth4v0ZJq17LQiT3t098vDr55vPHW29d7otrlVb5cuWD9uF8UiKC9rhM5cdPH7nidf+op3/ViInut+GQQ1eiFnNofutFtaMmZI/7G1Zlm8gapRiSf67OuV5TL7RmB5eW5b31zkjbm/Op1xPytG1rBb7jBZNDAgj238fdL/3BtnfZ85Tv9fJ9Hs3y9lkSRbl96k6lHpYfh0q/tX37aTl516Uj2kyT0z3Z+jNGUYPjZRmRCMaWTry+uL4m791XXTt2WtT3MUJ00jqjoA1g1vP3XD1rqu++lcbT7z2l8QSYC76wfmYnPRqw6h8Y8xrnlEeh56yUvO9sn7N4wWuGTUnRzWyRkCWw09pLGQ8q2wQte91RjazWpajZJVYCqCfUi04+b17P9/64oe/HL+8IX5V9LYkzUVSkiJJaQfitnM3/PaOz2x4pNQXKAY8MJvh0ItLWzMc5spb2a9Ft1SiOTIqlkwWo/TFcmwCeGWV7s05iqUvFRxLaY5WHn1lbSQNmkfVDsQdneuvfHr0a8QSkMGS/M3W5zeebZ7HiBqZK7O5kgSzkIExaWHOUhH2y0OqlT+Lu5RvzCqWrmiER1w+b5pRJCEjafngoXXxKhp2t7YQG1sTVz3VuPf7dZjDAuTF59/St5ZkfZnZkr5xK2UI5rjD8nt2lz+bNNQuuc2VPdwWV9oRjJVY+tX1LmIpbSBFjr786vnlAyuRFET/F6afqdYR4fTll4xsJ5aATHyLpWg77i/RYa2lChwSWijZGVgq7h7yfL8vy22s9JykXqU+1PN33TlL+cWSTiBFjr30auvjbiSFq/fXKqUolsLwrkvXNYklIBsVS0UfgtkfW6OmTFQslXlkaV4GapnMyUNxPo4u7Y0tj1ArpZ8T8z0ZS5cHdmNJd9WEYy/tay0fODiyMpIU3V8+QGxkKd3zhtFHFEtPEktAJmr+RxFzbtRv3pMlnsOhYtOntZ50RbH0lZKNjh2WIzY3exKqizI4p6q24nZalZg83D0Md8JOLOmOIkWOvbiv9fHbh0ZWeijs3j8QsdpKEUsykOL//i1iCchMXbn9Zkdv+MtyLtJERX7zViNLvh8SSrIgX49t/m5iX+ryOpsKilUVSBNVusCtidIsOJnGd394aOSNq65970wYXKN7X9PdcOyFfa2P3zk4EgYrPRMGagm1oPu/7sPKz638e7BmibWk1yAIgqfOnW/f3fnhd6rzQlWL7gKAThdKK8iE5sU7Dzv8TXVKTqi2fbHaRflmMqc5d2NSY0XlpYJHp8ZkdNpYp0jIfebqIq/KhJwrZuv1f8hhEKuVzadzXKdqWS5dMe/wZ5Xuz9AF1/OjKhVKQjOWsn7px194pfXxO4dGOuo/GMRSmv1PLAHWjckf0NMyVkwWGNwr30x21uEU6R7TsQ+daFqO7bMiRynUpWemDRbYXIxtf1Gv+6T8/p2SfzYNp/gK9HX8Pk6lcqEkUsSSjS/5+POvtJbfPjiigihUo0QpY6kT6i3eTywBuVO/2Sb9hrsgR794Q7lAjSAm7bc9HoyIJZmKXd6jn6XYa+/jPJ2x2OjksGsVqpEi5yMzZVXJUBIDYsnWl3rs+VdaJ99aiaSVABJasRTKSUz9DsMN0r1LILZ/2urcQywBAOBGZVeCjk/wNpmgPcjxn73cOvnmgRF12v/KpO2V/wvUc8gnC8ILn1tZljsUYaej9XwiPic8FJsvGWk8wQRvAADcqOyIkqJGlk539Cd4x0V76cO9L7dOvnVgdeL22tEiMXBkKRQrQ0JhI/p8+s7p9/IwsgQAgBuVDyWRMZbU3vlwz0urh9u6/z1lLEX/7DRWAkloBJIYcqiQWAIAIH+1CCVhEEvxvRJF0ifdw20ykIbEUnfUqNkQnYbQGj1afe6ULwmxBABAvmoTSiJlLPXujRO7X5JzksTFgbQmlgLRGWmsfGSYQaT7chBLAADkp1ahJBJiqd9eOPHcixePJIneWIrF0Ugj1ZpIg5jeVd5te6tNLAEAYFvtQknEYulUwsjSiZ++2P7kzXeaQqwdPeqsa4r2Jc1uHCkFRpJCLAEAYFktQyly018vNC+b/ML7/WLpxE9faJ9640BTqLWQRLASRlEgrWtcNCk76/4zuXvCXYglAAAsqm0oiQGxdOInL7RPvf5Os7t69rqmaF060o2k3jPWiggkkRxJCrEEAIAltQ6lyE1/s9C8bP1KLH3078+3T759qNm6bES0Lx1ZOaW/R1GBJNJFkkIsAQBgQe1DSciRpRMnl149dujd3wub/U9Zs7GfchxF6odYAgAgI0JJ+szXHml0xq/c2Q7EHfH/XmQgCfNIUtu9vd0JiSUAAAwRSjG/+YePNMLxK3e0hbjT1n5xHUl9tptYAgDAEKHUI4ql9vWf3dER4s4sj1PgKFI/xBIAAAYa7LSLnfzZn3dG3vv1poYQu0zuH7WKZ5EU2dxsBE807v1+hjXDAQCoH0aUBohGllrXX/lUKMLpNLfPuhtzCqRejCwBAKCBEaUBopGlc632XYEIdiTdLusIknAXSYKRJQAA9BBKCaKRl3Ot9reCIHi691a2AslhJKltJpYAAEiJQ28pRFFx6brm9jAM77Kxu7I8hOnr1Xu3IOAwHAAAwzCilEJ3ZOl8e3M0xyfrY/kQSfK/MbIEAMAQjChpiKLikpHGE1Fk6N7Xl0DqxcgSAACDMaKkIYqJT1ude6K4SHuvLPOQRM6RJBhZAgAgESNKBtKMLGXdq1leF8O7PtkJw28zsgQAwAWEkqFBsWRjb+Y9irTmfnKrAxEQSwAAxBBKGfTGUtlGkcI+W0wsAQBwAaGUURRLI83GE9FijlkeyYdIUoglAABWEEoWZImlAuYiJUaSQiwBAEAoWaMbS1n3e56RpBBLAIC6I5QsShNLZQiknud6UghBLAEAaol1lCyKYqLV7twzaAXvEkZS5G4hxI9YZwkAUDtCiP8H5/u1dCM1SvoAAAAASUVORK5CYII='; + +/// https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/svg.svg +const String useStar = ''' + + + + + + + + + + + +'''; + +const String useColor = ''' + + + + + + +'''; + +const String imageInDefs = ''' + + + + + + + + + + + +'''; + +const String transformedClip = ''' + + + + + + + + + + + + +'''; + +const String strokePropertyButNoStroke = ''' + + + +'''; + +/// https://developer.mozilla.org/en-US/docs/Web/SVG/Element/mask +const String basicMask = ''' + + + + + + + + + + + + + + +'''; + +const String groupMask = ''' + + + + + + + + + + + +'''; + +/// https://developer.mozilla.org/en-US/docs/Web/SVG/Element/clipPath +const String basicClip = ''' + + + + + + + + + + + +'''; + +/// Constructed example where clips cannot be trivially combined. +const String multiClip = ''' + + + + + + + + + + + + + +'''; + +/// Constructed example based on [basicClip] that has refs. +const String useClip = ''' + + + + + + + + + + + + +'''; + +/// https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/opacity +const String basicOpacity = ''' + + + + +'''; + +const String groupOpacity = ''' + + + + + + + + + +'''; + +/// https://commons.wikimedia.org/wiki/File:Ghostscript_Tiger.svg +const String ghostscriptTiger = ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +'''; + +/// https://developer.mozilla.org/en-US/docs/Web/SVG/Element/use +const String simpleUseCircles = ''' + + + + + +'''; + +const String simpleUseCirclesOoO = ''' + + + + + +'''; + +const String simpleUseCirclesWithoutHref = ''' + + + + + +'''; + +/// https://developer.mozilla.org/en-US/docs/Web/SVG/Element/text +const String basicText = ''' + + My + cat + is + Grumpy! + +'''; + +const String blendAndMask = ''' + + + + + + + + + + + + + +'''; + +const String outOfOrderGradientDef = ''' + + + + + + + + + +'''; + +const String xlinkGradient = ''' + + + + + + + + + + +'''; + +const String xlinkGradientOoO = ''' + + + + + + + + + + +'''; + +const String linearGradientThatInheritsUnitMode = ''' + + + + + + + + + + + + + + + +'''; + +const String xformObbGradient = ''' + + + + + + + + + +'''; + +const String xformUsosRadial = ''' + + + + + + + + + +'''; + +const String focalRadial = ''' + + + + + + + + + + + +'''; + +/// A constructed SVG with a bunch of missing references. +const String missingRefs = ''' + + + + +'''; + +/// An SVG string to test if path node and parent node count stays the same for [MaskingOptimizer] and [ClippingOptimizer] +const String pathAndParent = + ''' '''; + +const String svgInlineImage = ''' + + + +'''; + +const String basicOverlapWithStroke = ''' + + + + + + +'''; + +const String basicOverlap = ''' + + + + + + +'''; + +const String opacityOverlap = ''' + + + + + + +'''; + +const String transparentOverSolid = ''' + + + + + +'''; + +const String solidOverTrasnparent = ''' + + + + + +'''; + +const String complexOpacityTest = ''' + + + + + + + + + + + + + + + + + + +'''; + +const String alternatingPattern = ''' + + + + + + + + + + + + + +'''; + +const String starPatternCircles = ''' + + + + + + + + + +'''; + +const String textDecorations = ''' + + + Example text05 - Text decoration + + + Overline text + + + Strike text + + + Underline text + + +'''; + +const String textAnchors = ''' + + + Example text 06 - Text anchor + + + Text anchor start + + + Text anchor middle + + + Text anchor end + + +'''; + +/// Excpected groupMask result when [MaskingOptimizer] is applied +List groupMaskForMaskingOptimizer = [ + Path(fillType: PathFillType.evenOdd, commands: const [ + MoveToCommand(12.562000000000001, 20.438), + CubicToCommand(12.562000000000001, 20.748, 12.310000000000002, 21.0, + 12.000000000000002, 21.0), + LineToCommand(4.687000000000001, 21.0), + CubicToCommand(3.755590764649998, 20.998347258709998, 3.0011007948299984, + 20.24341005121, 3.0, 19.312), + LineToCommand(3.0, 4.6880000000000015), + CubicToCommand(3.0011020706799982, 3.7562002166800013, 3.75620021668, + 3.001102070680001, 4.687999999999999, 3.000000000000001), + LineToCommand(12.0, 3.0000000000000004), + CubicToCommand(12.30144139827, 3.0127127094300006, 12.53927764767, + 3.2607906538300004, 12.53927764767, 3.5625000000000004), + CubicToCommand(12.53927764767, 3.864209346170001, 12.30144139827, + 4.11228729057, 12.0, 4.125), + LineToCommand(4.687000000000001, 4.125000000000001), + CubicToCommand(4.378, 4.125000000000001, 4.125, 4.377000000000001, 4.125, + 4.6880000000000015), + LineToCommand(4.125, 19.312), + CubicToCommand(4.125, 19.622, 4.378, 19.875, 4.687999999999999, 19.875), + LineToCommand(12.000000000000002, 19.875), + CubicToCommand(12.310000000000002, 19.875, 12.563000000000002, 20.127, + 12.563000000000002, 20.438), + CloseCommand(), + MoveToCommand(21.0, 12.0), + CubicToCommand(21.0, 12.169, 20.921, 12.316, 20.804000000000002, 12.418), + LineToCommand(20.808, 12.423), + LineToCommand(16.308, 16.361), + CubicToCommand( + 16.205000000000002, 16.442999999999998, 16.079, 16.5, 15.938, 16.5), + CubicToCommand(15.627, 16.5, 15.375, 16.247999999999998, 15.375, 15.937), + CubicToCommand(15.376131882800001, 15.77572417052, 15.44773957195, + 15.62300981305, 15.571000000000002, 15.519), + LineToCommand(15.567, 15.514), + LineToCommand(18.94, 12.563), + LineToCommand(9.188, 12.563), + CubicToCommand(8.87706369162, 12.56299999183, 8.6250000148, 12.31093630838, + 8.6250000148, 12.0), + CubicToCommand(8.6250000148, 11.68906369162, 8.87706369162, 11.43700000817, + 9.188, 11.437), + LineToCommand(18.94, 11.437), + LineToCommand(15.567, 8.486), + CubicToCommand(15.447063979900001, 8.37775998399, 15.37751598331, + 8.22453705399, 15.375, 8.062999999999999), + CubicToCommand( + 15.375, 7.75206368585, 15.62706368585, 7.5, 15.937999999999999, 7.5), + CubicToCommand(16.079, 7.5, 16.205, 7.557, 16.304000000000002, 7.644), + LineToCommand(16.308, 7.639), + LineToCommand(20.808, 11.577), + CubicToCommand(20.9279360201, 11.68524001601, 20.997484016690002, + 11.83846294601, 21.0, 12.0), + CloseCommand() + ]), + Path(fillType: PathFillType.evenOdd, commands: const [ + MoveToCommand(12.418000221252441, 3.196000099182129), + CubicToCommand(12.315999984741211, 3.0789999961853027, 12.168999671936035, + 3.0, 12.0, 3.0), + CubicToCommand(11.838462829589844, 3.002516031265259, 11.685239791870117, + 3.07206392288208, 11.57699966430664, 3.191999912261963), + LineToCommand(7.638999938964844, 7.691999912261963), + LineToCommand(7.644000053405762, 7.696000099182129), + CubicToCommand(7.557000160217285, 7.795000076293945, 7.5, 7.921000003814697, + 7.5, 8.062000274658203), + CubicToCommand(7.5, 8.372936248779297, 7.752063751220703, 8.625, + 8.062999725341797, 8.625), + CubicToCommand(8.224536895751953, 8.62248420715332, 8.37775993347168, + 8.552935600280762, 8.486000061035156, 8.432999610900879), + LineToCommand(11.437000274658203, 5.059999942779541), + LineToCommand(11.437000274658203, 14.812000274658203), + CubicToCommand(11.437000274658203, 15.122936248779297, 11.689064025878906, + 15.375, 12.0, 15.375), + CubicToCommand(12.310935974121094, 15.375, 12.562999725341797, + 15.122936248779297, 12.562999725341797, 14.812000274658203), + LineToCommand(12.562999725341797, 5.059999942779541), + LineToCommand(15.513999938964844, 8.432999610900879), + LineToCommand(15.519000053405762, 8.428999900817871), + CubicToCommand(15.62300968170166, 8.552260398864746, 15.775724411010742, + 8.623867988586426, 15.937000274658203, 8.625), + CubicToCommand(16.24799919128418, 8.625, 16.5, 8.373000144958496, 16.5, + 8.062000274658203), + CubicToCommand(16.5, 7.921000003814697, 16.44300079345703, + 7.795000076293945, 16.361000061035156, 7.691999912261963), + LineToCommand(12.42300033569336, 3.191999912261963), + LineToCommand(12.418000221252441, 3.196000099182129), + CloseCommand(), + MoveToCommand(21.0, 12.0), + CubicToCommand(21.0, 11.6899995803833, 20.74799919128418, + 11.437999725341797, 20.437999725341797, 11.437999725341797), + LineToCommand(20.437999725341797, 11.437000274658203), + CubicToCommand(20.12700080871582, 11.437000274658203, 19.875, + 11.6899995803833, 19.875, 12.0), + LineToCommand(19.875, 19.312000274658203), + CubicToCommand(19.875, 19.621999740600586, 19.621999740600586, 19.875, + 19.312000274658203, 19.875), + LineToCommand(4.688000202178955, 19.875), + CubicToCommand(4.376999855041504, 19.875, 4.125, 19.621999740600586, 4.125, + 19.312999725341797), + LineToCommand(4.125, 12.0), + CubicToCommand(4.112287521362305, 11.698558807373047, 3.8642094135284424, + 11.460721969604492, 3.5625, 11.460721969604492), + CubicToCommand(3.2607905864715576, 11.460721969604492, 3.0127127170562744, + 11.698558807373047, 3.0, 12.0), + LineToCommand(3.0, 19.312000274658203), + CubicToCommand(3.0011019706726074, 20.243799209594727, 3.7562003135681152, + 20.998897552490234, 4.688000202178955, 21.0), + LineToCommand(19.312000274658203, 21.0), + CubicToCommand(20.243410110473633, 20.998899459838867, 20.99834632873535, + 20.244409561157227, 21.0, 19.312999725341797), + LineToCommand(21.0, 12.0), + CloseCommand() + ]) +]; + +/// Excpected groupMask result when [MaskingOptimizer] is applied +List blendsAndMasksForMaskingOptimizer = [ + Path( + commands: const [ + MoveToCommand(50.0, 0.0), + CubicToCommand(77.5957512247, 0.0, 100.0, 22.4042487753, 100.0, 50.0), + CubicToCommand(100.0, 77.5957512247, 77.5957512247, 100.0, 50.0, 100.0), + CubicToCommand(22.4042487753, 100.0, 0.0, 77.5957512247, 0.0, 50.0), + CubicToCommand(0.0, 22.4042487753, 22.4042487753, 0.0, 50.0, 0.0), + CloseCommand(), + ], + ), + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(90.0, 50.0), + CubicToCommand( + 90.0, 27.923398971557617, 72.07659912109375, 10.0, 50.0, 10.0), + CubicToCommand( + 27.923398971557617, 10.0, 10.0, 27.923398971557617, 10.0, 50.0), + CubicToCommand( + 10.0, 72.07659912109375, 27.923398971557617, 90.0, 50.0, 90.0), + CubicToCommand( + 72.07659912109375, 90.0, 90.0, 72.07659912109375, 90.0, 50.0), + CloseCommand(), + ], + ), +]; + +/// Expected basicClips result when [Clipping Optimizer] is applied + +List basicClipsForClippingOptimzer = [ + Path( + fillType: PathFillType.evenOdd, + commands: const [ + MoveToCommand(50.0, 30.0), + CubicToCommand( + 50.0, 18.961700439453125, 41.038299560546875, 10.0, 30.0, 10.0), + CubicToCommand( + 18.961700439453125, 10.0, 10.0, 18.961700439453125, 10.0, 30.0), + CubicToCommand( + 10.0, 41.038299560546875, 18.961700439453125, 50.0, 30.0, 50.0), + CubicToCommand( + 41.038299560546875, 50.0, 50.0, 41.038299560546875, 50.0, 30.0), + CloseCommand(), + MoveToCommand(90.0, 70.0), + CubicToCommand( + 90.0, 58.961700439453125, 81.03829956054688, 50.0, 70.0, 50.0), + CubicToCommand( + 58.961700439453125, 50.0, 50.0, 58.961700439453125, 50.0, 70.0), + CubicToCommand( + 50.0, 81.03829956054688, 58.961700439453125, 90.0, 70.0, 90.0), + CubicToCommand( + 81.03829956054688, 90.0, 90.0, 81.03829956054688, 90.0, 70.0), + CloseCommand() + ], + ), +]; + +/// https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/bzrfeed.svg +const String signWithScaledStroke = ''' + + + + + + + + + + + + + + + + + + + + + + +'''; + +const String textTspan = ''' + + + + Some text + more text. + + + Even more text + text everywhere + so many lines + + + +'''; + +const String numberBubbles = ''' + + + + + + + + 2 + + + 3 + + + 1 + + + +'''; + +/// Via https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill-rule +const String inheritFillRule = ''' + + + + + + + + +'''; diff --git a/packages/vector_graphics_compiler/test/theme_test.dart b/packages/vector_graphics_compiler/test/theme_test.dart new file mode 100644 index 000000000000..ce5a4b9e21e8 --- /dev/null +++ b/packages/vector_graphics_compiler/test/theme_test.dart @@ -0,0 +1,88 @@ +// 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: prefer_const_constructors + +import 'package:flutter_test/flutter_test.dart'; +import 'package:vector_graphics_compiler/src/paint.dart'; +import 'package:vector_graphics_compiler/src/svg/theme.dart'; + +void main() { + group('SvgTheme', () { + group('constructor', () { + test('sets currentColor', () { + const Color currentColor = Color(0xFFB0E3BE); + + expect( + SvgTheme( + currentColor: currentColor, + ).currentColor, + equals(currentColor), + ); + }); + + test('sets fontSize', () { + const double fontSize = 14.0; + + expect( + SvgTheme( + currentColor: Color(0xFFB0E3BE), + ).fontSize, + equals(fontSize), + ); + }); + + test( + 'sets fontSize to 14 ' + 'by default', () { + expect( + SvgTheme(), + equals( + SvgTheme(), + ), + ); + }); + + test('sets xHeight', () { + const double xHeight = 8.0; + + expect( + SvgTheme( + fontSize: 26.0, + xHeight: xHeight, + ).xHeight, + equals(xHeight), + ); + }); + + test( + 'sets xHeight as fontSize divided by 2 ' + 'by default', () { + const double fontSize = 16.0; + + expect( + SvgTheme( + fontSize: fontSize, + ).xHeight, + equals(fontSize / 2), + ); + }); + }); + + test('supports value equality', () { + expect( + SvgTheme( + currentColor: Color(0xFF6F2173), + xHeight: 6.0, + ), + equals( + SvgTheme( + currentColor: Color(0xFF6F2173), + xHeight: 6.0, + ), + ), + ); + }); + }); +} diff --git a/packages/vector_graphics_compiler/test/util_test.dart b/packages/vector_graphics_compiler/test/util_test.dart new file mode 100644 index 000000000000..662da242508c --- /dev/null +++ b/packages/vector_graphics_compiler/test/util_test.dart @@ -0,0 +1,23 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:vector_graphics_compiler/src/util.dart'; + +void main() { + test('listEquals', () { + final List listA = [1, 2, 3]; + final List listB = [1, 2, 3]; + final List listC = [1, 2]; + final List listD = [3, 2, 1]; + + expect(listEquals(null, null), isTrue); + expect(listEquals(listA, null), isFalse); + expect(listEquals(null, listB), isFalse); + expect(listEquals(listA, listA), isTrue); + expect(listEquals(listA, listB), isTrue); + expect(listEquals(listA, listC), isFalse); + expect(listEquals(listA, listD), isFalse); + }); +} diff --git a/packages/vector_graphics_compiler/test/vertices_test.dart b/packages/vector_graphics_compiler/test/vertices_test.dart new file mode 100644 index 000000000000..965c0250adcd --- /dev/null +++ b/packages/vector_graphics_compiler/test/vertices_test.dart @@ -0,0 +1,75 @@ +// 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:typed_data'; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; + +void main() { + test('Vertices.fromFloat32List', () { + final Vertices vertices = Vertices.fromFloat32List(Float32List.fromList( + [1, 2, 3, 4, 5, 6], + )); + + expect( + vertices.vertexPoints, + const [Point(1, 2), Point(3, 4), Point(5, 6)], + ); + + expect( + () => Vertices.fromFloat32List(Float32List.fromList([1])), + throwsA(isA()), + ); + }); + + test('IndexedVertices - creates valid index', () { + final Vertices vertices = Vertices.fromFloat32List(Float32List.fromList( + [ + 1, + 1, + 2, + 2, + 3, + 3, + 1, + 1, + 4, + 4, + 2, + 2, + 3, + 3, + 5, + 5, + 4, + 4, + 1, + 1, + 2, + 2, + 3, + 3 + ], + )); + + final IndexedVertices indexedVertices = vertices.createIndex(); + expect(indexedVertices.vertices.length, 10); + expect(indexedVertices.indices!.length, 12); + expect(indexedVertices.vertices, [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]); + expect( + indexedVertices.indices, [0, 1, 2, 0, 3, 1, 2, 4, 3, 0, 1, 2]); + }); + + test('IndexedVertices - does not index if index is larger', () { + final Float32List original = Float32List.fromList( + [1, 1, 2, 2, 3, 3, 1, 2, 4, 4, 2, 3, 3, 4, 5, 5, 4, 5], + ); + final Vertices vertices = Vertices.fromFloat32List(original); + + final IndexedVertices indexedVertices = vertices.createIndex(); + expect(indexedVertices.vertices, original); + expect(indexedVertices.indices, null); + }); +} diff --git a/packages/vector_graphics_compiler/test_data/example.svg b/packages/vector_graphics_compiler/test_data/example.svg new file mode 100644 index 000000000000..72aac66e1845 --- /dev/null +++ b/packages/vector_graphics_compiler/test_data/example.svg @@ -0,0 +1,4 @@ + + + diff --git a/packages/video_player/video_player/CHANGELOG.md b/packages/video_player/video_player/CHANGELOG.md index 7de2bc64061b..5e448be001b3 100644 --- a/packages/video_player/video_player/CHANGELOG.md +++ b/packages/video_player/video_player/CHANGELOG.md @@ -1,3 +1,20 @@ +## 2.9.2 + +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Throws a more descriptive `StateError` in the case where + `VideoPlayerController.initialize` receives more than one `initialized` event. + +## 2.9.1 + +* Updates minimum web implementation version to ensure support for + the new `webOptions` exposed in `2.9.0`. + +## 2.9.0 + +* Exports types: `VideoPlayerWebOptions` and `VideoPlayerWebOptionsControls` to + customize the `webOptions` field in `VideoPlayerOptions` objects. +* Forwards `webOptions` to the web implementation. + ## 2.8.7 * Ensures that `value.position` never reports a value larger than `value.duration`. diff --git a/packages/video_player/video_player/README.md b/packages/video_player/video_player/README.md index 55f4d2f614b3..094bdd666996 100644 --- a/packages/video_player/video_player/README.md +++ b/packages/video_player/video_player/README.md @@ -12,9 +12,7 @@ A Flutter plugin for iOS, Android and Web for playing back video on a Widget sur ![The example app running in iOS](https://github.com/flutter/packages/blob/main/packages/video_player/video_player/doc/demo_ipod.gif?raw=true) -## Installation - -First, add `video_player` as a [dependency in your pubspec.yaml file](https://flutter.dev/using-packages/). +## Setup ### iOS @@ -37,7 +35,7 @@ Android Manifest file, located in `/android/app/src/main/AndroidMa If you are using network-based videos, you will need to [add the `com.apple.security.network.client` -entitlement](https://docs.flutter.dev/platform-integration/macos/building#entitlements-and-the-app-sandbox) +entitlement](https://flutter.dev/to/macos-entitlements) ### Web diff --git a/packages/video_player/video_player/example/android/app/build.gradle b/packages/video_player/video_player/example/android/app/build.gradle index 097935b6b0bf..3a00131c2d07 100644 --- a/packages/video_player/video_player/example/android/app/build.gradle +++ b/packages/video_player/video_player/example/android/app/build.gradle @@ -29,13 +29,13 @@ android { compileSdk flutter.compileSdkVersion compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } defaultConfig { applicationId "io.flutter.plugins.videoplayerexample" - minSdkVersion 21 + minSdkVersion flutter.minSdkVersion targetSdkVersion 29 versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/packages/video_player/video_player/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/video_player/video_player/example/android/app/gradle/wrapper/gradle-wrapper.properties index 609ab8e6c8b5..d951fac2bf31 100644 --- a/packages/video_player/video_player/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ b/packages/video_player/video_player/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/packages/video_player/video_player/example/android/build.gradle b/packages/video_player/video_player/example/android/build.gradle index cec92de922cf..0bed8906c094 100644 --- a/packages/video_player/video_player/example/android/build.gradle +++ b/packages/video_player/video_player/example/android/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath 'com.android.tools.build:gradle:8.5.2' } } diff --git a/packages/video_player/video_player/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/video_player/video_player/example/android/gradle/wrapper/gradle-wrapper.properties index aeaff6f869f3..7aeeb11c6ee5 100644 --- a/packages/video_player/video_player/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/video_player/video_player/example/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/video_player/video_player/example/macos/Podfile b/packages/video_player/video_player/example/macos/Podfile index 049abe295427..ae77cc1d4269 100644 --- a/packages/video_player/video_player/example/macos/Podfile +++ b/packages/video_player/video_player/example/macos/Podfile @@ -28,7 +28,6 @@ flutter_macos_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) end diff --git a/packages/video_player/video_player/example/pubspec.yaml b/packages/video_player/video_player/example/pubspec.yaml index ae536f3bd643..25f812abeeee 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/video_player/video_player/example/web/index.html b/packages/video_player/video_player/example/web/index.html index 0df50f1192dc..8030c29471dd 100644 --- a/packages/video_player/video_player/example/web/index.html +++ b/packages/video_player/video_player/example/web/index.html @@ -8,6 +8,6 @@ video_player web example - + diff --git a/packages/video_player/video_player/lib/video_player.dart b/packages/video_player/video_player/lib/video_player.dart index 4d7f68e72729..b7ba8340fa66 100644 --- a/packages/video_player/video_player/lib/video_player.dart +++ b/packages/video_player/video_player/lib/video_player.dart @@ -14,7 +14,13 @@ import 'package:video_player_platform_interface/video_player_platform_interface. import 'src/closed_caption_file.dart'; export 'package:video_player_platform_interface/video_player_platform_interface.dart' - show DataSourceType, DurationRange, VideoFormat, VideoPlayerOptions; + show + DataSourceType, + DurationRange, + VideoFormat, + VideoPlayerOptions, + VideoPlayerWebOptions, + VideoPlayerWebOptionsControls; export 'src/closed_caption_file.dart'; @@ -436,6 +442,14 @@ class VideoPlayerController extends ValueNotifier { _creatingCompleter!.complete(null); final Completer initializingCompleter = Completer(); + // Apply the web-specific options + if (kIsWeb && videoPlayerOptions?.webOptions != null) { + await _videoPlayerPlatform.setWebOptions( + _textureId, + videoPlayerOptions!.webOptions!, + ); + } + void eventListener(VideoEvent event) { if (_isDisposed) { return; @@ -451,6 +465,16 @@ class VideoPlayerController extends ValueNotifier { errorDescription: null, isCompleted: false, ); + assert( + !initializingCompleter.isCompleted, + 'VideoPlayerController already initialized. This is typically a ' + 'sign that an implementation of the VideoPlayerPlatform ' + '(${_videoPlayerPlatform.runtimeType}) has a bug and is sending ' + 'more than one initialized event per instance.', + ); + if (initializingCompleter.isCompleted) { + throw StateError('VideoPlayerController already initialized'); + } initializingCompleter.complete(null); _applyLooping(); _applyVolume(); diff --git a/packages/video_player/video_player/pubspec.yaml b/packages/video_player/video_player/pubspec.yaml index 9ed1b6f7e292..6e8b92684d7c 100644 --- a/packages/video_player/video_player/pubspec.yaml +++ b/packages/video_player/video_player/pubspec.yaml @@ -3,11 +3,11 @@ description: Flutter plugin for displaying inline video with other Flutter widgets on Android, iOS, and web. repository: https://github.com/flutter/packages/tree/main/packages/video_player/video_player issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22 -version: 2.8.7 +version: 2.9.2 environment: - sdk: ">=3.2.3 <4.0.0" - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -27,8 +27,8 @@ dependencies: html: ^0.15.0 video_player_android: ^2.3.5 video_player_avfoundation: ^2.5.6 - video_player_platform_interface: ">=6.1.0 <7.0.0" - video_player_web: ^2.0.0 + video_player_platform_interface: ^6.2.0 + video_player_web: ^2.1.0 dev_dependencies: flutter_test: diff --git a/packages/video_player/video_player/test/video_player_initialization_test.dart b/packages/video_player/video_player/test/video_player_initialization_test.dart index 38cf71f67e80..5ecc7e4d69b8 100644 --- a/packages/video_player/video_player/test/video_player_initialization_test.dart +++ b/packages/video_player/video_player/test/video_player_initialization_test.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:flutter/foundation.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:video_player/video_player.dart'; import 'package:video_player_platform_interface/video_player_platform_interface.dart'; @@ -9,18 +10,51 @@ import 'package:video_player_platform_interface/video_player_platform_interface. import 'video_player_test.dart' show FakeVideoPlayerPlatform; void main() { - // This test needs to run first and therefore needs to be the only test - // in this file. - test('plugin initialized', () async { - TestWidgetsFlutterBinding.ensureInitialized(); - final FakeVideoPlayerPlatform fakeVideoPlayerPlatform = - FakeVideoPlayerPlatform(); - VideoPlayerPlatform.instance = fakeVideoPlayerPlatform; + TestWidgetsFlutterBinding.ensureInitialized(); + + late FakeVideoPlayerPlatform fakeVideoPlayerPlatform; + + setUp(() { + VideoPlayerPlatform.instance = + fakeVideoPlayerPlatform = FakeVideoPlayerPlatform(); + }); + test('plugin initialized', () async { final VideoPlayerController controller = VideoPlayerController.networkUrl( Uri.parse('https://127.0.0.1'), ); await controller.initialize(); expect(fakeVideoPlayerPlatform.calls.first, 'init'); }); + + test('web configuration is applied (web only)', () async { + const VideoPlayerWebOptions expected = VideoPlayerWebOptions( + allowContextMenu: false, + allowRemotePlayback: false, + controls: VideoPlayerWebOptionsControls.enabled(), + ); + + final VideoPlayerController controller = VideoPlayerController.networkUrl( + Uri.parse('https://127.0.0.1'), + videoPlayerOptions: VideoPlayerOptions( + webOptions: expected, + ), + ); + await controller.initialize(); + + expect( + () { + fakeVideoPlayerPlatform.calls.singleWhere( + (String call) => call == 'setWebOptions', + ); + }, + returnsNormally, + reason: 'setWebOptions must be called exactly once.', + ); + expect( + fakeVideoPlayerPlatform.webOptions[controller.textureId], + expected, + reason: 'web options must be passed to the platform', + ); + }, skip: !kIsWeb); } diff --git a/packages/video_player/video_player/test/video_player_test.dart b/packages/video_player/video_player/test/video_player_test.dart index c62615a06e40..f6eef2448119 100644 --- a/packages/video_player/video_player/test/video_player_test.dart +++ b/packages/video_player/video_player/test/video_player_test.dart @@ -1311,6 +1311,8 @@ class FakeVideoPlayerPlatform extends VideoPlayerPlatform { bool forceInitError = false; int nextTextureId = 0; final Map _positions = {}; + final Map webOptions = + {}; @override Future create(DataSource dataSource) async { @@ -1392,4 +1394,14 @@ class FakeVideoPlayerPlatform extends VideoPlayerPlatform { Widget buildView(int textureId) { return Texture(textureId: textureId); } + + @override + Future setWebOptions( + int textureId, VideoPlayerWebOptions options) async { + if (!kIsWeb) { + throw UnimplementedError('setWebOptions() is only available in the web.'); + } + calls.add('setWebOptions'); + webOptions[textureId] = options; + } } diff --git a/packages/video_player/video_player_android/AUTHORS b/packages/video_player/video_player_android/AUTHORS index fc16c35c4c25..07a1e9f7a118 100644 --- a/packages/video_player/video_player_android/AUTHORS +++ b/packages/video_player/video_player_android/AUTHORS @@ -65,3 +65,4 @@ Anton Borries Alex Li Rahul Raj <64.rahulraj@gmail.com> Márton Matuz +André Sousa diff --git a/packages/video_player/video_player_android/CHANGELOG.md b/packages/video_player/video_player_android/CHANGELOG.md index d3c63dae9d87..ef0db8cc5913 100644 --- a/packages/video_player/video_player_android/CHANGELOG.md +++ b/packages/video_player/video_player_android/CHANGELOG.md @@ -1,3 +1,108 @@ +## 2.7.16 + +* Updates internal Pigeon API to use newer features. + +## 2.7.15 + +* Changes the rotation correction calculation for Android API 29+ to use + the one that is reported by the video's format instead of the unapplied + rotation degrees that Exoplayer does not report on Android API 21+. +* Changes the rotation correction calculation for Android APIs 21-28 to 0 + because the Impeller backend used on those API versions correctly rotates + the video being played automatically. + +## 2.7.14 + +* Removes SSL workaround for API 19, which is no longer supported. + +## 2.7.13 + +* When `AndroidVideoPlayer` attempts to operate on a `textureId` that is not + active (i.e. it was previously disposed or never created), the resulting + platform exception is more informative than a "NullPointerException". + +## 2.7.12 + +* Fixes a [bug](https://github.com/flutter/flutter/issues/156451) where + additional harmless but annoying warnings in the form of native stack traces + would be printed when the app was backgrounded. There may be additional + warnings that are not yet fixed, but this should address the + most common case. + +## 2.7.11 + +* Fixes a [bug](https://github.com/flutter/flutter/issues/156158) where a + harmless but annoying warning in the form of a native stack trace would be + printed when a previously disposed video player received a trim memory event + (i.e. by backgrounding). + +## 2.7.10 + +* Fixes a [bug](https://github.com/flutter/flutter/issues/156158) where + disposing a video player (including implicitly by switching tabs or views + in a running app) would cause native stack traces. + +## 2.7.9 + +* Updates Java compatibility version to 11. + +## 2.7.8 + +* Updates Pigeon for non-nullable collection type support. + +## 2.7.7 + +* Removes the flag to treat warnings as errors in client builds. + +## 2.7.6 + +* Fixes a [bug](https://github.com/flutter/flutter/issues/154602) where + resuming a video player would cause a `Bad state: Future already completed`. + +## 2.7.5 + +* Add a deprecation suppression in advance of a new `SurfaceProducer` API. + +## 2.7.4 + +* Fixes a [bug](https://github.com/flutter/flutter/issues/154559) where + resuming (or using a plugin like `share_plus` that implicitly resumes the + activity where) a video player would cause a `DecoderInitializationException`. + +## 2.7.3 + +* Updates Media3-ExoPlayer to 1.4.1. + +## 2.7.2 + +* Updates minimum supported SDK version to Flutter 3.24/Dart 3.5. + +* Re-adds Impeller support. + +## 2.7.1 + +* Revert Impeller support. + +## 2.7.0 + +* Re-adds [support for Impeller](https://docs.flutter.dev/release/breaking-changes/android-surface-plugins). + +## 2.6.0 + +* Adds RTSP support. + +## 2.5.4 + +* Updates Media3-ExoPlayer to 1.4.0. + +## 2.5.3 + +* Updates lint checks to ignore NewerVersionAvailable. + +## 2.5.2 + +* Updates Android Gradle plugin to 8.5.0. + ## 2.5.1 * Removes additional references to the v1 Android embedding. diff --git a/packages/video_player/video_player_android/README.md b/packages/video_player/video_player_android/README.md index 1495f48e30e7..e33436b629df 100644 --- a/packages/video_player/video_player_android/README.md +++ b/packages/video_player/video_player_android/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/video_player -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/video_player/video_player_android/android/build.gradle b/packages/video_player/video_player_android/android/build.gradle index 77f504de422f..92decbdda718 100644 --- a/packages/video_player/video_player_android/android/build.gradle +++ b/packages/video_player/video_player_android/android/build.gradle @@ -1,6 +1,5 @@ group 'io.flutter.plugins.videoplayer' version '1.0-SNAPSHOT' -def args = ["-Xlint:deprecation","-Xlint:unchecked","-Werror"] buildscript { repositories { @@ -9,7 +8,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.2.1' + classpath 'com.android.tools.build:gradle:8.5.0' } } @@ -20,49 +19,49 @@ rootProject.allprojects { } } -project.getTasks().withType(JavaCompile){ - options.compilerArgs.addAll(args) -} - apply plugin: 'com.android.library' android { - // Conditional for compatibility with AGP <4.2. - if (project.android.hasProperty("namespace")) { - namespace 'io.flutter.plugins.videoplayer' - } + namespace 'io.flutter.plugins.videoplayer' compileSdk 34 defaultConfig { - minSdkVersion 19 + minSdkVersion 21 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } lintOptions { checkAllWarnings true warningsAsErrors true - disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency' + disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency', 'NewerVersionAvailable' } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } dependencies { - def exoplayer_version = "1.3.1" + def exoplayer_version = "1.4.1" implementation "androidx.media3:media3-exoplayer:${exoplayer_version}" implementation "androidx.media3:media3-exoplayer-hls:${exoplayer_version}" implementation "androidx.media3:media3-exoplayer-dash:${exoplayer_version}" + implementation "androidx.media3:media3-exoplayer-rtsp:${exoplayer_version}" implementation "androidx.media3:media3-exoplayer-smoothstreaming:${exoplayer_version}" testImplementation 'junit:junit:4.13.2' testImplementation 'androidx.test:core:1.3.0' testImplementation 'org.mockito:mockito-inline:5.0.0' testImplementation 'org.robolectric:robolectric:4.10.3' + testImplementation "androidx.media3:media3-test-utils:${exoplayer_version}" } testOptions { unitTests.includeAndroidResources = true unitTests.returnDefaultValues = true unitTests.all { + // The org.gradle.jvmargs property that may be set in gradle.properties does not impact + // the Java heap size when running the Android unit tests. The following property here + // sets the heap size to a size large enough to run the robolectric tests across + // multiple SDK levels. + jvmArgs "-Xmx1g" testLogging { events "passed", "skipped", "failed", "standardOut", "standardError" outputs.upToDateWhen {false} diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/CustomSSLSocketFactory.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/CustomSSLSocketFactory.java deleted file mode 100644 index 731bb9798f65..000000000000 --- a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/CustomSSLSocketFactory.java +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package io.flutter.plugins.videoplayer; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.Socket; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocket; -import javax.net.ssl.SSLSocketFactory; - -// SSLSocketFactory does not have nullability annotations. -@SuppressWarnings("UnknownNullness") -public class CustomSSLSocketFactory extends SSLSocketFactory { - private final SSLSocketFactory sslSocketFactory; - - public CustomSSLSocketFactory() throws KeyManagementException, NoSuchAlgorithmException { - SSLContext context = SSLContext.getInstance("TLS"); - context.init(null, null, null); - sslSocketFactory = context.getSocketFactory(); - } - - @Override - public String[] getDefaultCipherSuites() { - return sslSocketFactory.getDefaultCipherSuites(); - } - - @Override - public String[] getSupportedCipherSuites() { - return sslSocketFactory.getSupportedCipherSuites(); - } - - @Override - public Socket createSocket() throws IOException { - return enableProtocols(sslSocketFactory.createSocket()); - } - - @Override - public Socket createSocket(Socket s, String host, int port, boolean autoClose) - throws IOException { - return enableProtocols(sslSocketFactory.createSocket(s, host, port, autoClose)); - } - - @Override - public Socket createSocket(String host, int port) throws IOException { - return enableProtocols(sslSocketFactory.createSocket(host, port)); - } - - @Override - public Socket createSocket(String host, int port, InetAddress localHost, int localPort) - throws IOException { - return enableProtocols(sslSocketFactory.createSocket(host, port, localHost, localPort)); - } - - @Override - public Socket createSocket(InetAddress host, int port) throws IOException { - return enableProtocols(sslSocketFactory.createSocket(host, port)); - } - - @Override - public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) - throws IOException { - return enableProtocols(sslSocketFactory.createSocket(address, port, localAddress, localPort)); - } - - private Socket enableProtocols(Socket socket) { - if (socket instanceof SSLSocket) { - ((SSLSocket) socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"}); - } - return socket; - } -} diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerEventListener.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerEventListener.java index 0940cc8b3227..df6115fd5846 100644 --- a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerEventListener.java +++ b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerEventListener.java @@ -4,21 +4,56 @@ package io.flutter.plugins.videoplayer; +import android.os.Build; import androidx.annotation.NonNull; +import androidx.annotation.OptIn; +import androidx.media3.common.Format; import androidx.media3.common.PlaybackException; import androidx.media3.common.Player; import androidx.media3.common.VideoSize; import androidx.media3.exoplayer.ExoPlayer; +import java.util.Objects; final class ExoPlayerEventListener implements Player.Listener { private final ExoPlayer exoPlayer; private final VideoPlayerCallbacks events; private boolean isBuffering = false; - private boolean isInitialized = false; + private boolean isInitialized; + + private enum RotationDegrees { + ROTATE_0(0), + ROTATE_90(90), + ROTATE_180(180), + ROTATE_270(270); + + private final int degrees; + + RotationDegrees(int degrees) { + this.degrees = degrees; + } + + public static RotationDegrees fromDegrees(int degrees) { + for (RotationDegrees rotationDegrees : RotationDegrees.values()) { + if (rotationDegrees.degrees == degrees) { + return rotationDegrees; + } + } + throw new IllegalArgumentException("Invalid rotation degrees specified: " + degrees); + } + + public int getDegrees() { + return this.degrees; + } + } ExoPlayerEventListener(ExoPlayer exoPlayer, VideoPlayerCallbacks events) { + this(exoPlayer, events, false); + } + + ExoPlayerEventListener(ExoPlayer exoPlayer, VideoPlayerCallbacks events, boolean initialized) { this.exoPlayer = exoPlayer; this.events = events; + this.isInitialized = initialized; } private void setBuffering(boolean buffering) { @@ -44,23 +79,80 @@ private void sendInitialized() { int width = videoSize.width; int height = videoSize.height; if (width != 0 && height != 0) { - int rotationDegrees = videoSize.unappliedRotationDegrees; - // Switch the width/height if video was taken in portrait mode - if (rotationDegrees == 90 || rotationDegrees == 270) { + RotationDegrees reportedRotationCorrection = RotationDegrees.ROTATE_0; + + if (Build.VERSION.SDK_INT <= 21) { + // On API 21 and below, Exoplayer may not internally handle rotation correction + // and reports it through VideoSize.unappliedRotationDegrees. We may apply it to + // fix the case of upside-down playback. + try { + reportedRotationCorrection = + RotationDegrees.fromDegrees(videoSize.unappliedRotationDegrees); + rotationCorrection = + getRotationCorrectionFromUnappliedRotation(reportedRotationCorrection); + } catch (IllegalArgumentException e) { + // Unapplied rotation other than 0, 90, 180, 270 reported by VideoSize. Because this is unexpected, + // we apply no rotation correction. + reportedRotationCorrection = RotationDegrees.ROTATE_0; + rotationCorrection = 0; + } + } + // TODO(camsim99): Replace this with a call to `handlesCropAndRotation` when it is + // available in stable. https://github.com/flutter/flutter/issues/157198 + else if (Build.VERSION.SDK_INT < 29) { + // When the SurfaceTexture backend for Impeller is used, the preview should already + // be correctly rotated. + rotationCorrection = 0; + } else { + // The video's Format also provides a rotation correction that may be used to + // correct the rotation, so we try to use that to correct the video rotation + // when the ImageReader backend for Impeller is used. + rotationCorrection = getRotationCorrectionFromFormat(exoPlayer); + + try { + reportedRotationCorrection = RotationDegrees.fromDegrees(rotationCorrection); + } catch (IllegalArgumentException e) { + // Rotation correction other than 0, 90, 180, 270 reported by Format. Because this is unexpected, + // we apply no rotation correction. + reportedRotationCorrection = RotationDegrees.ROTATE_0; + rotationCorrection = 0; + } + } + + // Switch the width/height if video was taken in portrait mode and a rotation + // correction was detected. + if (reportedRotationCorrection == RotationDegrees.ROTATE_90 + || reportedRotationCorrection == RotationDegrees.ROTATE_270) { width = videoSize.height; height = videoSize.width; } - // Rotating the video with ExoPlayer does not seem to be possible with a Surface, - // so inform the Flutter code that the widget needs to be rotated to prevent - // upside-down playback for videos with rotationDegrees of 180 (other orientations work - // correctly without correction). - if (rotationDegrees == 180) { - rotationCorrection = rotationDegrees; - } } events.onInitialized(width, height, exoPlayer.getDuration(), rotationCorrection); } + private int getRotationCorrectionFromUnappliedRotation(RotationDegrees unappliedRotationDegrees) { + int rotationCorrection = 0; + + // Rotating the video with ExoPlayer does not seem to be possible with a Surface, + // so inform the Flutter code that the widget needs to be rotated to prevent + // upside-down playback for videos with unappliedRotationDegrees of 180 (other orientations + // work correctly without correction). + if (unappliedRotationDegrees == RotationDegrees.ROTATE_180) { + rotationCorrection = unappliedRotationDegrees.getDegrees(); + } + + return rotationCorrection; + } + + @OptIn(markerClass = androidx.media3.common.util.UnstableApi.class) + // A video's Format and its rotation degrees are unstable because they are not guaranteed + // the same implementation across API versions. It is possible that this logic may need + // revisiting should the implementation change across versions of the Exoplayer API. + private int getRotationCorrectionFromFormat(ExoPlayer exoPlayer) { + Format videoFormat = Objects.requireNonNull(exoPlayer.getVideoFormat()); + return videoFormat.rotationDegrees; + } + @Override public void onPlaybackStateChanged(final int playbackState) { switch (playbackState) { diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerState.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerState.java new file mode 100644 index 000000000000..cd55b54c1247 --- /dev/null +++ b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerState.java @@ -0,0 +1,69 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.videoplayer; + +import androidx.media3.common.PlaybackParameters; +import androidx.media3.exoplayer.ExoPlayer; + +/** + * Internal state representing an {@link ExoPlayer} instance at a snapshot in time. + * + *

During the Android application lifecycle, the underlying {@link android.view.Surface} being + * rendered to by the player can be destroyed when the application is in the background and memory + * is reclaimed. Upon resume, the player will need to be recreated, but start again at the + * previous point (and settings). + */ +final class ExoPlayerState { + /** + * Saves a representation of the current state of the player at the current point in time. + * + *

The inverse of this operation is {@link #restore(ExoPlayer)}. + * + * @param exoPlayer the active player instance. + * @return an opaque object representing the state. + */ + static ExoPlayerState save(ExoPlayer exoPlayer) { + return new ExoPlayerState( + /*position=*/ exoPlayer.getCurrentPosition(), + /*repeatMode=*/ exoPlayer.getRepeatMode(), + /*volume=*/ exoPlayer.getVolume(), + /*playbackParameters=*/ exoPlayer.getPlaybackParameters()); + } + + private ExoPlayerState( + long position, int repeatMode, float volume, PlaybackParameters playbackParameters) { + this.position = position; + this.repeatMode = repeatMode; + this.volume = volume; + this.playbackParameters = playbackParameters; + } + + /** Previous value of {@link ExoPlayer#getCurrentPosition()}. */ + private final long position; + + /** Previous value of {@link ExoPlayer#getRepeatMode()}. */ + private final int repeatMode; + + /** Previous value of {@link ExoPlayer#getVolume()}. */ + private final float volume; + + /** Previous value of {@link ExoPlayer#getPlaybackParameters()}. */ + private final PlaybackParameters playbackParameters; + + /** + * Restores the captured state onto the provided player. + * + *

This will typically be done after creating a new player, setting up a media source, and + * listening to events. + * + * @param exoPlayer the new player instance to reflect the state back to. + */ + void restore(ExoPlayer exoPlayer) { + exoPlayer.seekTo(position); + exoPlayer.setRepeatMode(repeatMode); + exoPlayer.setVolume(volume); + exoPlayer.setPlaybackParameters(playbackParameters); + } +} diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/HttpVideoAsset.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/HttpVideoAsset.java new file mode 100644 index 000000000000..f29efc3cab67 --- /dev/null +++ b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/HttpVideoAsset.java @@ -0,0 +1,97 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.videoplayer; + +import android.content.Context; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.OptIn; +import androidx.annotation.VisibleForTesting; +import androidx.media3.common.MediaItem; +import androidx.media3.common.MimeTypes; +import androidx.media3.common.util.UnstableApi; +import androidx.media3.datasource.DataSource; +import androidx.media3.datasource.DefaultDataSource; +import androidx.media3.datasource.DefaultHttpDataSource; +import androidx.media3.exoplayer.source.DefaultMediaSourceFactory; +import androidx.media3.exoplayer.source.MediaSource; +import java.util.Map; + +final class HttpVideoAsset extends VideoAsset { + private static final String DEFAULT_USER_AGENT = "ExoPlayer"; + private static final String HEADER_USER_AGENT = "User-Agent"; + + @NonNull private final StreamingFormat streamingFormat; + @NonNull private final Map httpHeaders; + + HttpVideoAsset( + @Nullable String assetUrl, + @NonNull StreamingFormat streamingFormat, + @NonNull Map httpHeaders) { + super(assetUrl); + this.streamingFormat = streamingFormat; + this.httpHeaders = httpHeaders; + } + + @NonNull + @Override + MediaItem getMediaItem() { + MediaItem.Builder builder = new MediaItem.Builder().setUri(assetUrl); + String mimeType = null; + switch (streamingFormat) { + case SMOOTH: + mimeType = MimeTypes.APPLICATION_SS; + break; + case DYNAMIC_ADAPTIVE: + mimeType = MimeTypes.APPLICATION_MPD; + break; + case HTTP_LIVE: + mimeType = MimeTypes.APPLICATION_M3U8; + break; + } + if (mimeType != null) { + builder.setMimeType(mimeType); + } + return builder.build(); + } + + @Override + MediaSource.Factory getMediaSourceFactory(Context context) { + return getMediaSourceFactory(context, new DefaultHttpDataSource.Factory()); + } + + /** + * Returns a configured media source factory, starting at the provided factory. + * + *

This method is provided for ease of testing without making real HTTP calls. + * + * @param context application context. + * @param initialFactory initial factory, to be configured. + * @return configured factory, or {@code null} if not needed for this asset type. + */ + @VisibleForTesting + MediaSource.Factory getMediaSourceFactory( + Context context, DefaultHttpDataSource.Factory initialFactory) { + String userAgent = DEFAULT_USER_AGENT; + if (!httpHeaders.isEmpty() && httpHeaders.containsKey(HEADER_USER_AGENT)) { + userAgent = httpHeaders.get(HEADER_USER_AGENT); + } + unstableUpdateDataSourceFactory(initialFactory, httpHeaders, userAgent); + DataSource.Factory dataSourceFactory = new DefaultDataSource.Factory(context, initialFactory); + return new DefaultMediaSourceFactory(context).setDataSourceFactory(dataSourceFactory); + } + + // TODO: Migrate to stable API, see https://github.com/flutter/flutter/issues/147039. + @OptIn(markerClass = UnstableApi.class) + private static void unstableUpdateDataSourceFactory( + @NonNull DefaultHttpDataSource.Factory factory, + @NonNull Map httpHeaders, + @Nullable String userAgent) { + factory.setUserAgent(userAgent).setAllowCrossProtocolRedirects(true); + if (!httpHeaders.isEmpty()) { + factory.setDefaultRequestProperties(httpHeaders); + } + } +} diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/LocalVideoAsset.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/LocalVideoAsset.java new file mode 100644 index 000000000000..3d1b3d850d29 --- /dev/null +++ b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/LocalVideoAsset.java @@ -0,0 +1,28 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.videoplayer; + +import android.content.Context; +import androidx.annotation.NonNull; +import androidx.media3.common.MediaItem; +import androidx.media3.exoplayer.source.DefaultMediaSourceFactory; +import androidx.media3.exoplayer.source.MediaSource; + +final class LocalVideoAsset extends VideoAsset { + LocalVideoAsset(@NonNull String assetUrl) { + super(assetUrl); + } + + @NonNull + @Override + MediaItem getMediaItem() { + return new MediaItem.Builder().setUri(assetUrl).build(); + } + + @Override + MediaSource.Factory getMediaSourceFactory(Context context) { + return new DefaultMediaSourceFactory(context); + } +} diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java index e0790af8b86d..870045518852 100644 --- a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java +++ b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java @@ -1,11 +1,14 @@ // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v9.2.5), do not edit directly. +// Autogenerated from Pigeon (v22.5.0), do not edit directly. // See also: https://pub.dev/packages/pigeon package io.flutter.plugins.videoplayer; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.CLASS; + import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -14,9 +17,12 @@ import io.flutter.plugin.common.MessageCodec; import io.flutter.plugin.common.StandardMessageCodec; import java.io.ByteArrayOutputStream; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Map; +import java.util.Objects; /** Generated class from Pigeon. */ @SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression", "serial"}) @@ -40,7 +46,7 @@ public FlutterError(@NonNull String code, @Nullable String message, @Nullable Ob @NonNull protected static ArrayList wrapError(@NonNull Throwable exception) { - ArrayList errorList = new ArrayList(3); + ArrayList errorList = new ArrayList<>(3); if (exception instanceof FlutterError) { FlutterError error = (FlutterError) exception; errorList.add(error.code); @@ -55,364 +61,9 @@ protected static ArrayList wrapError(@NonNull Throwable exception) { return errorList; } - /** Generated class from Pigeon that represents data sent in messages. */ - public static final class TextureMessage { - private @NonNull Long textureId; - - public @NonNull Long getTextureId() { - return textureId; - } - - public void setTextureId(@NonNull Long setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"textureId\" is null."); - } - this.textureId = setterArg; - } - - /** Constructor is non-public to enforce null safety; use Builder. */ - TextureMessage() {} - - public static final class Builder { - - private @Nullable Long textureId; - - public @NonNull Builder setTextureId(@NonNull Long setterArg) { - this.textureId = setterArg; - return this; - } - - public @NonNull TextureMessage build() { - TextureMessage pigeonReturn = new TextureMessage(); - pigeonReturn.setTextureId(textureId); - return pigeonReturn; - } - } - - @NonNull - ArrayList toList() { - ArrayList toListResult = new ArrayList(1); - toListResult.add(textureId); - return toListResult; - } - - static @NonNull TextureMessage fromList(@NonNull ArrayList list) { - TextureMessage pigeonResult = new TextureMessage(); - Object textureId = list.get(0); - pigeonResult.setTextureId( - (textureId == null) - ? null - : ((textureId instanceof Integer) ? (Integer) textureId : (Long) textureId)); - return pigeonResult; - } - } - - /** Generated class from Pigeon that represents data sent in messages. */ - public static final class LoopingMessage { - private @NonNull Long textureId; - - public @NonNull Long getTextureId() { - return textureId; - } - - public void setTextureId(@NonNull Long setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"textureId\" is null."); - } - this.textureId = setterArg; - } - - private @NonNull Boolean isLooping; - - public @NonNull Boolean getIsLooping() { - return isLooping; - } - - public void setIsLooping(@NonNull Boolean setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"isLooping\" is null."); - } - this.isLooping = setterArg; - } - - /** Constructor is non-public to enforce null safety; use Builder. */ - LoopingMessage() {} - - public static final class Builder { - - private @Nullable Long textureId; - - public @NonNull Builder setTextureId(@NonNull Long setterArg) { - this.textureId = setterArg; - return this; - } - - private @Nullable Boolean isLooping; - - public @NonNull Builder setIsLooping(@NonNull Boolean setterArg) { - this.isLooping = setterArg; - return this; - } - - public @NonNull LoopingMessage build() { - LoopingMessage pigeonReturn = new LoopingMessage(); - pigeonReturn.setTextureId(textureId); - pigeonReturn.setIsLooping(isLooping); - return pigeonReturn; - } - } - - @NonNull - ArrayList toList() { - ArrayList toListResult = new ArrayList(2); - toListResult.add(textureId); - toListResult.add(isLooping); - return toListResult; - } - - static @NonNull LoopingMessage fromList(@NonNull ArrayList list) { - LoopingMessage pigeonResult = new LoopingMessage(); - Object textureId = list.get(0); - pigeonResult.setTextureId( - (textureId == null) - ? null - : ((textureId instanceof Integer) ? (Integer) textureId : (Long) textureId)); - Object isLooping = list.get(1); - pigeonResult.setIsLooping((Boolean) isLooping); - return pigeonResult; - } - } - - /** Generated class from Pigeon that represents data sent in messages. */ - public static final class VolumeMessage { - private @NonNull Long textureId; - - public @NonNull Long getTextureId() { - return textureId; - } - - public void setTextureId(@NonNull Long setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"textureId\" is null."); - } - this.textureId = setterArg; - } - - private @NonNull Double volume; - - public @NonNull Double getVolume() { - return volume; - } - - public void setVolume(@NonNull Double setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"volume\" is null."); - } - this.volume = setterArg; - } - - /** Constructor is non-public to enforce null safety; use Builder. */ - VolumeMessage() {} - - public static final class Builder { - - private @Nullable Long textureId; - - public @NonNull Builder setTextureId(@NonNull Long setterArg) { - this.textureId = setterArg; - return this; - } - - private @Nullable Double volume; - - public @NonNull Builder setVolume(@NonNull Double setterArg) { - this.volume = setterArg; - return this; - } - - public @NonNull VolumeMessage build() { - VolumeMessage pigeonReturn = new VolumeMessage(); - pigeonReturn.setTextureId(textureId); - pigeonReturn.setVolume(volume); - return pigeonReturn; - } - } - - @NonNull - ArrayList toList() { - ArrayList toListResult = new ArrayList(2); - toListResult.add(textureId); - toListResult.add(volume); - return toListResult; - } - - static @NonNull VolumeMessage fromList(@NonNull ArrayList list) { - VolumeMessage pigeonResult = new VolumeMessage(); - Object textureId = list.get(0); - pigeonResult.setTextureId( - (textureId == null) - ? null - : ((textureId instanceof Integer) ? (Integer) textureId : (Long) textureId)); - Object volume = list.get(1); - pigeonResult.setVolume((Double) volume); - return pigeonResult; - } - } - - /** Generated class from Pigeon that represents data sent in messages. */ - public static final class PlaybackSpeedMessage { - private @NonNull Long textureId; - - public @NonNull Long getTextureId() { - return textureId; - } - - public void setTextureId(@NonNull Long setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"textureId\" is null."); - } - this.textureId = setterArg; - } - - private @NonNull Double speed; - - public @NonNull Double getSpeed() { - return speed; - } - - public void setSpeed(@NonNull Double setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"speed\" is null."); - } - this.speed = setterArg; - } - - /** Constructor is non-public to enforce null safety; use Builder. */ - PlaybackSpeedMessage() {} - - public static final class Builder { - - private @Nullable Long textureId; - - public @NonNull Builder setTextureId(@NonNull Long setterArg) { - this.textureId = setterArg; - return this; - } - - private @Nullable Double speed; - - public @NonNull Builder setSpeed(@NonNull Double setterArg) { - this.speed = setterArg; - return this; - } - - public @NonNull PlaybackSpeedMessage build() { - PlaybackSpeedMessage pigeonReturn = new PlaybackSpeedMessage(); - pigeonReturn.setTextureId(textureId); - pigeonReturn.setSpeed(speed); - return pigeonReturn; - } - } - - @NonNull - ArrayList toList() { - ArrayList toListResult = new ArrayList(2); - toListResult.add(textureId); - toListResult.add(speed); - return toListResult; - } - - static @NonNull PlaybackSpeedMessage fromList(@NonNull ArrayList list) { - PlaybackSpeedMessage pigeonResult = new PlaybackSpeedMessage(); - Object textureId = list.get(0); - pigeonResult.setTextureId( - (textureId == null) - ? null - : ((textureId instanceof Integer) ? (Integer) textureId : (Long) textureId)); - Object speed = list.get(1); - pigeonResult.setSpeed((Double) speed); - return pigeonResult; - } - } - - /** Generated class from Pigeon that represents data sent in messages. */ - public static final class PositionMessage { - private @NonNull Long textureId; - - public @NonNull Long getTextureId() { - return textureId; - } - - public void setTextureId(@NonNull Long setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"textureId\" is null."); - } - this.textureId = setterArg; - } - - private @NonNull Long position; - - public @NonNull Long getPosition() { - return position; - } - - public void setPosition(@NonNull Long setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"position\" is null."); - } - this.position = setterArg; - } - - /** Constructor is non-public to enforce null safety; use Builder. */ - PositionMessage() {} - - public static final class Builder { - - private @Nullable Long textureId; - - public @NonNull Builder setTextureId(@NonNull Long setterArg) { - this.textureId = setterArg; - return this; - } - - private @Nullable Long position; - - public @NonNull Builder setPosition(@NonNull Long setterArg) { - this.position = setterArg; - return this; - } - - public @NonNull PositionMessage build() { - PositionMessage pigeonReturn = new PositionMessage(); - pigeonReturn.setTextureId(textureId); - pigeonReturn.setPosition(position); - return pigeonReturn; - } - } - - @NonNull - ArrayList toList() { - ArrayList toListResult = new ArrayList(2); - toListResult.add(textureId); - toListResult.add(position); - return toListResult; - } - - static @NonNull PositionMessage fromList(@NonNull ArrayList list) { - PositionMessage pigeonResult = new PositionMessage(); - Object textureId = list.get(0); - pigeonResult.setTextureId( - (textureId == null) - ? null - : ((textureId instanceof Integer) ? (Integer) textureId : (Long) textureId)); - Object position = list.get(1); - pigeonResult.setPosition( - (position == null) - ? null - : ((position instanceof Integer) ? (Integer) position : (Long) position)); - return pigeonResult; - } - } + @Target(METHOD) + @Retention(CLASS) + @interface CanIgnoreReturnValue {} /** Generated class from Pigeon that represents data sent in messages. */ public static final class CreateMessage { @@ -472,10 +123,32 @@ public void setHttpHeaders(@NonNull Map setterArg) { /** Constructor is non-public to enforce null safety; use Builder. */ CreateMessage() {} + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CreateMessage that = (CreateMessage) o; + return Objects.equals(asset, that.asset) + && Objects.equals(uri, that.uri) + && Objects.equals(packageName, that.packageName) + && Objects.equals(formatHint, that.formatHint) + && httpHeaders.equals(that.httpHeaders); + } + + @Override + public int hashCode() { + return Objects.hash(asset, uri, packageName, formatHint, httpHeaders); + } + public static final class Builder { private @Nullable String asset; + @CanIgnoreReturnValue public @NonNull Builder setAsset(@Nullable String setterArg) { this.asset = setterArg; return this; @@ -483,6 +156,7 @@ public static final class Builder { private @Nullable String uri; + @CanIgnoreReturnValue public @NonNull Builder setUri(@Nullable String setterArg) { this.uri = setterArg; return this; @@ -490,6 +164,7 @@ public static final class Builder { private @Nullable String packageName; + @CanIgnoreReturnValue public @NonNull Builder setPackageName(@Nullable String setterArg) { this.packageName = setterArg; return this; @@ -497,6 +172,7 @@ public static final class Builder { private @Nullable String formatHint; + @CanIgnoreReturnValue public @NonNull Builder setFormatHint(@Nullable String setterArg) { this.formatHint = setterArg; return this; @@ -504,6 +180,7 @@ public static final class Builder { private @Nullable Map httpHeaders; + @CanIgnoreReturnValue public @NonNull Builder setHttpHeaders(@NonNull Map setterArg) { this.httpHeaders = setterArg; return this; @@ -522,7 +199,7 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(5); + ArrayList toListResult = new ArrayList<>(5); toListResult.add(asset); toListResult.add(uri); toListResult.add(packageName); @@ -531,93 +208,32 @@ ArrayList toList() { return toListResult; } - static @NonNull CreateMessage fromList(@NonNull ArrayList list) { + static @NonNull CreateMessage fromList(@NonNull ArrayList pigeonVar_list) { CreateMessage pigeonResult = new CreateMessage(); - Object asset = list.get(0); + Object asset = pigeonVar_list.get(0); pigeonResult.setAsset((String) asset); - Object uri = list.get(1); + Object uri = pigeonVar_list.get(1); pigeonResult.setUri((String) uri); - Object packageName = list.get(2); + Object packageName = pigeonVar_list.get(2); pigeonResult.setPackageName((String) packageName); - Object formatHint = list.get(3); + Object formatHint = pigeonVar_list.get(3); pigeonResult.setFormatHint((String) formatHint); - Object httpHeaders = list.get(4); + Object httpHeaders = pigeonVar_list.get(4); pigeonResult.setHttpHeaders((Map) httpHeaders); return pigeonResult; } } - /** Generated class from Pigeon that represents data sent in messages. */ - public static final class MixWithOthersMessage { - private @NonNull Boolean mixWithOthers; - - public @NonNull Boolean getMixWithOthers() { - return mixWithOthers; - } - - public void setMixWithOthers(@NonNull Boolean setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"mixWithOthers\" is null."); - } - this.mixWithOthers = setterArg; - } - - /** Constructor is non-public to enforce null safety; use Builder. */ - MixWithOthersMessage() {} - - public static final class Builder { - - private @Nullable Boolean mixWithOthers; - - public @NonNull Builder setMixWithOthers(@NonNull Boolean setterArg) { - this.mixWithOthers = setterArg; - return this; - } - - public @NonNull MixWithOthersMessage build() { - MixWithOthersMessage pigeonReturn = new MixWithOthersMessage(); - pigeonReturn.setMixWithOthers(mixWithOthers); - return pigeonReturn; - } - } - - @NonNull - ArrayList toList() { - ArrayList toListResult = new ArrayList(1); - toListResult.add(mixWithOthers); - return toListResult; - } - - static @NonNull MixWithOthersMessage fromList(@NonNull ArrayList list) { - MixWithOthersMessage pigeonResult = new MixWithOthersMessage(); - Object mixWithOthers = list.get(0); - pigeonResult.setMixWithOthers((Boolean) mixWithOthers); - return pigeonResult; - } - } - - private static class AndroidVideoPlayerApiCodec extends StandardMessageCodec { - public static final AndroidVideoPlayerApiCodec INSTANCE = new AndroidVideoPlayerApiCodec(); + private static class PigeonCodec extends StandardMessageCodec { + public static final PigeonCodec INSTANCE = new PigeonCodec(); - private AndroidVideoPlayerApiCodec() {} + private PigeonCodec() {} @Override protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { switch (type) { - case (byte) 128: - return CreateMessage.fromList((ArrayList) readValue(buffer)); case (byte) 129: - return LoopingMessage.fromList((ArrayList) readValue(buffer)); - case (byte) 130: - return MixWithOthersMessage.fromList((ArrayList) readValue(buffer)); - case (byte) 131: - return PlaybackSpeedMessage.fromList((ArrayList) readValue(buffer)); - case (byte) 132: - return PositionMessage.fromList((ArrayList) readValue(buffer)); - case (byte) 133: - return TextureMessage.fromList((ArrayList) readValue(buffer)); - case (byte) 134: - return VolumeMessage.fromList((ArrayList) readValue(buffer)); + return CreateMessage.fromList((ArrayList) readValue(buffer)); default: return super.readValueOfType(type, buffer); } @@ -626,26 +242,8 @@ protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { @Override protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { if (value instanceof CreateMessage) { - stream.write(128); - writeValue(stream, ((CreateMessage) value).toList()); - } else if (value instanceof LoopingMessage) { stream.write(129); - writeValue(stream, ((LoopingMessage) value).toList()); - } else if (value instanceof MixWithOthersMessage) { - stream.write(130); - writeValue(stream, ((MixWithOthersMessage) value).toList()); - } else if (value instanceof PlaybackSpeedMessage) { - stream.write(131); - writeValue(stream, ((PlaybackSpeedMessage) value).toList()); - } else if (value instanceof PositionMessage) { - stream.write(132); - writeValue(stream, ((PositionMessage) value).toList()); - } else if (value instanceof TextureMessage) { - stream.write(133); - writeValue(stream, ((TextureMessage) value).toList()); - } else if (value instanceof VolumeMessage) { - stream.write(134); - writeValue(stream, ((VolumeMessage) value).toList()); + writeValue(stream, ((CreateMessage) value).toList()); } else { super.writeValue(stream, value); } @@ -658,51 +256,61 @@ public interface AndroidVideoPlayerApi { void initialize(); @NonNull - TextureMessage create(@NonNull CreateMessage msg); + Long create(@NonNull CreateMessage msg); - void dispose(@NonNull TextureMessage msg); + void dispose(@NonNull Long textureId); - void setLooping(@NonNull LoopingMessage msg); + void setLooping(@NonNull Long textureId, @NonNull Boolean looping); - void setVolume(@NonNull VolumeMessage msg); + void setVolume(@NonNull Long textureId, @NonNull Double volume); - void setPlaybackSpeed(@NonNull PlaybackSpeedMessage msg); + void setPlaybackSpeed(@NonNull Long textureId, @NonNull Double speed); - void play(@NonNull TextureMessage msg); + void play(@NonNull Long textureId); @NonNull - PositionMessage position(@NonNull TextureMessage msg); + Long position(@NonNull Long textureId); - void seekTo(@NonNull PositionMessage msg); + void seekTo(@NonNull Long textureId, @NonNull Long position); - void pause(@NonNull TextureMessage msg); + void pause(@NonNull Long textureId); - void setMixWithOthers(@NonNull MixWithOthersMessage msg); + void setMixWithOthers(@NonNull Boolean mixWithOthers); /** The codec used by AndroidVideoPlayerApi. */ static @NonNull MessageCodec getCodec() { - return AndroidVideoPlayerApiCodec.INSTANCE; + return PigeonCodec.INSTANCE; } /** * Sets up an instance of `AndroidVideoPlayerApi` to handle messages through the * `binaryMessenger`. */ - static void setup( + static void setUp( @NonNull BinaryMessenger binaryMessenger, @Nullable AndroidVideoPlayerApi api) { + setUp(binaryMessenger, "", api); + } + + static void setUp( + @NonNull BinaryMessenger binaryMessenger, + @NonNull String messageChannelSuffix, + @Nullable AndroidVideoPlayerApi api) { + messageChannelSuffix = messageChannelSuffix.isEmpty() ? "" : "." + messageChannelSuffix; { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.AndroidVideoPlayerApi.initialize", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.initialize" + + messageChannelSuffix, + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); try { api.initialize(); wrapped.add(0, null); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -713,19 +321,21 @@ static void setup( { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.AndroidVideoPlayerApi.create", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.create" + + messageChannelSuffix, + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; CreateMessage msgArg = (CreateMessage) args.get(0); try { - TextureMessage output = api.create(msgArg); + Long output = api.create(msgArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -736,19 +346,21 @@ static void setup( { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.AndroidVideoPlayerApi.dispose", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.dispose" + + messageChannelSuffix, + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - TextureMessage msgArg = (TextureMessage) args.get(0); + Long textureIdArg = (Long) args.get(0); try { - api.dispose(msgArg); + api.dispose(textureIdArg); wrapped.add(0, null); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -759,19 +371,22 @@ static void setup( { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.AndroidVideoPlayerApi.setLooping", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.setLooping" + + messageChannelSuffix, + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - LoopingMessage msgArg = (LoopingMessage) args.get(0); + Long textureIdArg = (Long) args.get(0); + Boolean loopingArg = (Boolean) args.get(1); try { - api.setLooping(msgArg); + api.setLooping(textureIdArg, loopingArg); wrapped.add(0, null); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -782,19 +397,22 @@ static void setup( { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.AndroidVideoPlayerApi.setVolume", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.setVolume" + + messageChannelSuffix, + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - VolumeMessage msgArg = (VolumeMessage) args.get(0); + Long textureIdArg = (Long) args.get(0); + Double volumeArg = (Double) args.get(1); try { - api.setVolume(msgArg); + api.setVolume(textureIdArg, volumeArg); wrapped.add(0, null); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -806,20 +424,21 @@ static void setup( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.AndroidVideoPlayerApi.setPlaybackSpeed", + "dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.setPlaybackSpeed" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - PlaybackSpeedMessage msgArg = (PlaybackSpeedMessage) args.get(0); + Long textureIdArg = (Long) args.get(0); + Double speedArg = (Double) args.get(1); try { - api.setPlaybackSpeed(msgArg); + api.setPlaybackSpeed(textureIdArg, speedArg); wrapped.add(0, null); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -830,19 +449,21 @@ static void setup( { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.AndroidVideoPlayerApi.play", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.play" + + messageChannelSuffix, + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - TextureMessage msgArg = (TextureMessage) args.get(0); + Long textureIdArg = (Long) args.get(0); try { - api.play(msgArg); + api.play(textureIdArg); wrapped.add(0, null); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -853,19 +474,21 @@ static void setup( { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.AndroidVideoPlayerApi.position", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.position" + + messageChannelSuffix, + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - TextureMessage msgArg = (TextureMessage) args.get(0); + Long textureIdArg = (Long) args.get(0); try { - PositionMessage output = api.position(msgArg); + Long output = api.position(textureIdArg); wrapped.add(0, output); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -876,19 +499,22 @@ static void setup( { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.AndroidVideoPlayerApi.seekTo", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.seekTo" + + messageChannelSuffix, + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - PositionMessage msgArg = (PositionMessage) args.get(0); + Long textureIdArg = (Long) args.get(0); + Long positionArg = (Long) args.get(1); try { - api.seekTo(msgArg); + api.seekTo(textureIdArg, positionArg); wrapped.add(0, null); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -899,19 +525,21 @@ static void setup( { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.AndroidVideoPlayerApi.pause", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.pause" + + messageChannelSuffix, + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - TextureMessage msgArg = (TextureMessage) args.get(0); + Long textureIdArg = (Long) args.get(0); try { - api.pause(msgArg); + api.pause(textureIdArg); wrapped.add(0, null); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); @@ -923,20 +551,20 @@ static void setup( BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, - "dev.flutter.pigeon.AndroidVideoPlayerApi.setMixWithOthers", + "dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.setMixWithOthers" + + messageChannelSuffix, getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { - ArrayList wrapped = new ArrayList(); + ArrayList wrapped = new ArrayList<>(); ArrayList args = (ArrayList) message; - MixWithOthersMessage msgArg = (MixWithOthersMessage) args.get(0); + Boolean mixWithOthersArg = (Boolean) args.get(0); try { - api.setMixWithOthers(msgArg); + api.setMixWithOthers(mixWithOthersArg); wrapped.add(0, null); } catch (Throwable exception) { - ArrayList wrappedError = wrapError(exception); - wrapped = wrappedError; + wrapped = wrapError(exception); } reply.reply(wrapped); }); diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/RtspVideoAsset.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/RtspVideoAsset.java new file mode 100644 index 000000000000..1eb87c8bac0f --- /dev/null +++ b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/RtspVideoAsset.java @@ -0,0 +1,32 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.videoplayer; + +import android.content.Context; +import androidx.annotation.NonNull; +import androidx.annotation.OptIn; +import androidx.media3.common.MediaItem; +import androidx.media3.common.util.UnstableApi; +import androidx.media3.exoplayer.rtsp.RtspMediaSource; +import androidx.media3.exoplayer.source.MediaSource; + +final class RtspVideoAsset extends VideoAsset { + RtspVideoAsset(@NonNull String assetUrl) { + super(assetUrl); + } + + @NonNull + @Override + MediaItem getMediaItem() { + return new MediaItem.Builder().setUri(assetUrl).build(); + } + + // TODO: Migrate to stable API, see https://github.com/flutter/flutter/issues/147039. + @OptIn(markerClass = UnstableApi.class) + @Override + MediaSource.Factory getMediaSourceFactory(Context context) { + return new RtspMediaSource.Factory(); + } +} diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoAsset.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoAsset.java new file mode 100644 index 000000000000..3fab758e52f7 --- /dev/null +++ b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoAsset.java @@ -0,0 +1,97 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.videoplayer; + +import android.content.Context; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.media3.common.MediaItem; +import androidx.media3.exoplayer.source.MediaSource; +import java.util.HashMap; +import java.util.Map; + +/** A video to be played by {@link VideoPlayer}. */ +abstract class VideoAsset { + /** + * Returns an asset from a local {@code asset:///} URL, i.e. an on-device asset. + * + * @param assetUrl local asset, beginning in {@code asset:///}. + * @return the asset. + */ + @NonNull + static VideoAsset fromAssetUrl(@NonNull String assetUrl) { + if (!assetUrl.startsWith("asset:///")) { + throw new IllegalArgumentException("assetUrl must start with 'asset:///'"); + } + return new LocalVideoAsset(assetUrl); + } + + /** + * Returns an asset from a remote URL. + * + * @param remoteUrl remote asset, i.e. typically beginning with {@code https://} or similar. + * @param streamingFormat which streaming format, provided as a hint if able. + * @param httpHeaders HTTP headers to set for a request. + * @return the asset. + */ + @NonNull + static VideoAsset fromRemoteUrl( + @Nullable String remoteUrl, + @NonNull StreamingFormat streamingFormat, + @NonNull Map httpHeaders) { + return new HttpVideoAsset(remoteUrl, streamingFormat, new HashMap<>(httpHeaders)); + } + + /** + * Returns an asset from a RTSP URL. + * + * @param rtspUrl remote asset, beginning with {@code rtsp://}. + * @return the asset. + */ + @NonNull + static VideoAsset fromRtspUrl(@NonNull String rtspUrl) { + if (!rtspUrl.startsWith("rtsp://")) { + throw new IllegalArgumentException("rtspUrl must start with 'rtsp://'"); + } + return new RtspVideoAsset(rtspUrl); + } + + @Nullable protected final String assetUrl; + + protected VideoAsset(@Nullable String assetUrl) { + this.assetUrl = assetUrl; + } + + /** + * Returns the configured media item to be played. + * + * @return media item. + */ + @NonNull + abstract MediaItem getMediaItem(); + + /** + * Returns the configured media source factory, if needed for this asset type. + * + * @param context application context. + * @return configured factory, or {@code null} if not needed for this asset type. + */ + abstract MediaSource.Factory getMediaSourceFactory(Context context); + + /** Streaming formats that can be provided to the video player as a hint. */ + enum StreamingFormat { + /** Default, if the format is either not known or not another valid format. */ + UNKNOWN, + + /** Smooth Streaming. */ + SMOOTH, + + /** MPEG-DASH (Dynamic Adaptive over HTTP). */ + DYNAMIC_ADAPTIVE, + + /** HTTP Live Streaming (HLS). */ + HTTP_LIVE + } +} diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java index 7b3e44a1dcb5..c481df2d7796 100644 --- a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java +++ b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java @@ -8,109 +8,113 @@ import static androidx.media3.common.Player.REPEAT_MODE_OFF; import android.content.Context; -import android.view.Surface; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.annotation.OptIn; +import androidx.annotation.RestrictTo; import androidx.annotation.VisibleForTesting; import androidx.media3.common.AudioAttributes; import androidx.media3.common.C; import androidx.media3.common.MediaItem; -import androidx.media3.common.MimeTypes; import androidx.media3.common.PlaybackParameters; -import androidx.media3.common.util.UnstableApi; -import androidx.media3.datasource.DataSource; -import androidx.media3.datasource.DefaultDataSource; -import androidx.media3.datasource.DefaultHttpDataSource; import androidx.media3.exoplayer.ExoPlayer; -import androidx.media3.exoplayer.source.DefaultMediaSourceFactory; import io.flutter.view.TextureRegistry; -import java.util.Map; -final class VideoPlayer { - private static final String FORMAT_SS = "ss"; - private static final String FORMAT_DASH = "dash"; - private static final String FORMAT_HLS = "hls"; - private static final String FORMAT_OTHER = "other"; - - private ExoPlayer exoPlayer; - - private Surface surface; - - private final TextureRegistry.SurfaceTextureEntry textureEntry; - - private final VideoPlayerCallbacks videoPlayerEvents; - - private static final String USER_AGENT = "User-Agent"; - - private final VideoPlayerOptions options; - - private final DefaultHttpDataSource.Factory httpDataSourceFactory; - - VideoPlayer( - Context context, - VideoPlayerCallbacks events, - TextureRegistry.SurfaceTextureEntry textureEntry, - String dataSource, - String formatHint, - @NonNull Map httpHeaders, - VideoPlayerOptions options) { - this.videoPlayerEvents = events; - this.textureEntry = textureEntry; - this.options = options; - - MediaItem mediaItem = - new MediaItem.Builder() - .setUri(dataSource) - .setMimeType(mimeFromFormatHint(formatHint)) - .build(); - - httpDataSourceFactory = new DefaultHttpDataSource.Factory(); - configureHttpDataSourceFactory(httpHeaders); - - ExoPlayer exoPlayer = buildExoPlayer(context, httpDataSourceFactory); - - exoPlayer.setMediaItem(mediaItem); - exoPlayer.prepare(); - - setUpVideoPlayer(exoPlayer); +final class VideoPlayer implements TextureRegistry.SurfaceProducer.Callback { + @NonNull private final ExoPlayerProvider exoPlayerProvider; + @NonNull private final MediaItem mediaItem; + @NonNull private final TextureRegistry.SurfaceProducer surfaceProducer; + @NonNull private final VideoPlayerCallbacks videoPlayerEvents; + @NonNull private final VideoPlayerOptions options; + @NonNull private ExoPlayer exoPlayer; + @Nullable private ExoPlayerState savedStateDuring; + + /** + * Creates a video player. + * + * @param context application context. + * @param events event callbacks. + * @param surfaceProducer produces a texture to render to. + * @param asset asset to play. + * @param options options for playback. + * @return a video player instance. + */ + @NonNull + static VideoPlayer create( + @NonNull Context context, + @NonNull VideoPlayerCallbacks events, + @NonNull TextureRegistry.SurfaceProducer surfaceProducer, + @NonNull VideoAsset asset, + @NonNull VideoPlayerOptions options) { + return new VideoPlayer( + () -> { + ExoPlayer.Builder builder = + new ExoPlayer.Builder(context) + .setMediaSourceFactory(asset.getMediaSourceFactory(context)); + return builder.build(); + }, + events, + surfaceProducer, + asset.getMediaItem(), + options); + } + + /** A closure-compatible signature since {@link java.util.function.Supplier} is API level 24. */ + interface ExoPlayerProvider { + /** + * Returns a new {@link ExoPlayer}. + * + * @return new instance. + */ + ExoPlayer get(); } - // Constructor used to directly test members of this class. @VisibleForTesting VideoPlayer( - ExoPlayer exoPlayer, - VideoPlayerCallbacks events, - TextureRegistry.SurfaceTextureEntry textureEntry, - VideoPlayerOptions options, - DefaultHttpDataSource.Factory httpDataSourceFactory) { + @NonNull ExoPlayerProvider exoPlayerProvider, + @NonNull VideoPlayerCallbacks events, + @NonNull TextureRegistry.SurfaceProducer surfaceProducer, + @NonNull MediaItem mediaItem, + @NonNull VideoPlayerOptions options) { + this.exoPlayerProvider = exoPlayerProvider; this.videoPlayerEvents = events; - this.textureEntry = textureEntry; + this.surfaceProducer = surfaceProducer; + this.mediaItem = mediaItem; this.options = options; - this.httpDataSourceFactory = httpDataSourceFactory; - - setUpVideoPlayer(exoPlayer); + this.exoPlayer = createVideoPlayer(); + surfaceProducer.setCallback(this); + } + + @RestrictTo(RestrictTo.Scope.LIBRARY) + // TODO(matanlurey): https://github.com/flutter/flutter/issues/155131. + @SuppressWarnings({"deprecation", "removal"}) + public void onSurfaceCreated() { + if (savedStateDuring != null) { + exoPlayer = createVideoPlayer(); + savedStateDuring.restore(exoPlayer); + savedStateDuring = null; + } } - @VisibleForTesting - public void configureHttpDataSourceFactory(@NonNull Map httpHeaders) { - final boolean httpHeadersNotEmpty = !httpHeaders.isEmpty(); - final String userAgent = - httpHeadersNotEmpty && httpHeaders.containsKey(USER_AGENT) - ? httpHeaders.get(USER_AGENT) - : "ExoPlayer"; - - unstableUpdateDataSourceFactory( - httpDataSourceFactory, httpHeaders, userAgent, httpHeadersNotEmpty); + @RestrictTo(RestrictTo.Scope.LIBRARY) + public void onSurfaceDestroyed() { + // Intentionally do not call pause/stop here, because the surface has already been released + // at this point (see https://github.com/flutter/flutter/issues/156451). + savedStateDuring = ExoPlayerState.save(exoPlayer); + exoPlayer.release(); } - private void setUpVideoPlayer(ExoPlayer exoPlayer) { - this.exoPlayer = exoPlayer; + private ExoPlayer createVideoPlayer() { + ExoPlayer exoPlayer = exoPlayerProvider.get(); + exoPlayer.setMediaItem(mediaItem); + exoPlayer.prepare(); + + exoPlayer.setVideoSurface(surfaceProducer.getSurface()); - surface = new Surface(textureEntry.surfaceTexture()); - exoPlayer.setVideoSurface(surface); + boolean wasInitialized = savedStateDuring != null; + exoPlayer.addListener(new ExoPlayerEventListener(exoPlayer, videoPlayerEvents, wasInitialized)); setAudioAttributes(exoPlayer, options.mixWithOthers); - exoPlayer.addListener(new ExoPlayerEventListener(exoPlayer, videoPlayerEvents)); + + return exoPlayer; } void sendBufferingUpdate() { @@ -124,11 +128,11 @@ private static void setAudioAttributes(ExoPlayer exoPlayer, boolean isMixMode) { } void play() { - exoPlayer.setPlayWhenReady(true); + exoPlayer.play(); } void pause() { - exoPlayer.setPlayWhenReady(false); + exoPlayer.pause(); } void setLooping(boolean value) { @@ -157,54 +161,11 @@ long getPosition() { } void dispose() { - textureEntry.release(); - if (surface != null) { - surface.release(); - } - if (exoPlayer != null) { - exoPlayer.release(); - } - } + exoPlayer.release(); + surfaceProducer.release(); - @NonNull - private static ExoPlayer buildExoPlayer( - Context context, DataSource.Factory baseDataSourceFactory) { - DataSource.Factory dataSourceFactory = - new DefaultDataSource.Factory(context, baseDataSourceFactory); - DefaultMediaSourceFactory mediaSourceFactory = - new DefaultMediaSourceFactory(context).setDataSourceFactory(dataSourceFactory); - return new ExoPlayer.Builder(context).setMediaSourceFactory(mediaSourceFactory).build(); - } - - @Nullable - private static String mimeFromFormatHint(@Nullable String formatHint) { - if (formatHint == null) { - return null; - } - switch (formatHint) { - case FORMAT_SS: - return MimeTypes.APPLICATION_SS; - case FORMAT_DASH: - return MimeTypes.APPLICATION_MPD; - case FORMAT_HLS: - return MimeTypes.APPLICATION_M3U8; - case FORMAT_OTHER: - default: - return null; - } - } - - // TODO: migrate to stable API, see https://github.com/flutter/flutter/issues/147039 - @OptIn(markerClass = UnstableApi.class) - private static void unstableUpdateDataSourceFactory( - DefaultHttpDataSource.Factory factory, - @NonNull Map httpHeaders, - String userAgent, - boolean httpHeadersNotEmpty) { - factory.setUserAgent(userAgent).setAllowCrossProtocolRedirects(true); - - if (httpHeadersNotEmpty) { - factory.setDefaultRequestProperties(httpHeaders); - } + // TODO(matanlurey): Remove when embedder no longer calls-back once released. + // https://github.com/flutter/flutter/issues/156434. + surfaceProducer.setCallback(null); } } diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerEventCallbacks.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerEventCallbacks.java index 72bff5cd18eb..8b83aded168f 100644 --- a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerEventCallbacks.java +++ b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerEventCallbacks.java @@ -97,6 +97,7 @@ public void onError(@NonNull String code, @Nullable String message, @Nullable Ob @Override public void onIsPlayingStateUpdate(boolean isPlaying) { Map event = new HashMap<>(); + event.put("event", "isPlayingStateUpdate"); event.put("isPlaying", isPlaying); eventSink.success(event); } diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java index 2d8c4439595a..d248ad2f0be8 100644 --- a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java +++ b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java @@ -5,7 +5,6 @@ package io.flutter.plugins.videoplayer; import android.content.Context; -import android.os.Build; import android.util.LongSparseArray; import androidx.annotation.NonNull; import io.flutter.FlutterInjector; @@ -15,18 +14,7 @@ import io.flutter.plugin.common.EventChannel; import io.flutter.plugins.videoplayer.Messages.AndroidVideoPlayerApi; import io.flutter.plugins.videoplayer.Messages.CreateMessage; -import io.flutter.plugins.videoplayer.Messages.LoopingMessage; -import io.flutter.plugins.videoplayer.Messages.MixWithOthersMessage; -import io.flutter.plugins.videoplayer.Messages.PlaybackSpeedMessage; -import io.flutter.plugins.videoplayer.Messages.PositionMessage; -import io.flutter.plugins.videoplayer.Messages.TextureMessage; -import io.flutter.plugins.videoplayer.Messages.VolumeMessage; import io.flutter.view.TextureRegistry; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.util.HashMap; -import java.util.Map; -import javax.net.ssl.HttpsURLConnection; /** Android platform implementation of the VideoPlayerPlugin. */ public class VideoPlayerPlugin implements FlutterPlugin, AndroidVideoPlayerApi { @@ -40,19 +28,6 @@ public VideoPlayerPlugin() {} @Override public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { - if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { - try { - HttpsURLConnection.setDefaultSSLSocketFactory(new CustomSSLSocketFactory()); - } catch (KeyManagementException | NoSuchAlgorithmException e) { - Log.w( - TAG, - "Failed to enable TLSv1.1 and TLSv1.2 Protocols for API level 19 and below.\n" - + "For more information about Socket Security, please consult the following link:\n" - + "https://developer.android.com/reference/javax/net/ssl/SSLSocket", - e); - } - } - final FlutterInjector injector = FlutterInjector.instance(); this.flutterState = new FlutterState( @@ -90,18 +65,19 @@ public void onDestroy() { disposeAllPlayers(); } + @Override public void initialize() { disposeAllPlayers(); } - public @NonNull TextureMessage create(@NonNull CreateMessage arg) { - TextureRegistry.SurfaceTextureEntry handle = - flutterState.textureRegistry.createSurfaceTexture(); + @Override + public @NonNull Long create(@NonNull CreateMessage arg) { + TextureRegistry.SurfaceProducer handle = flutterState.textureRegistry.createSurfaceProducer(); EventChannel eventChannel = new EventChannel( flutterState.binaryMessenger, "flutter.io/videoPlayer/videoEvents" + handle.id()); - VideoPlayer player; + final VideoAsset videoAsset; if (arg.getAsset() != null) { String assetLookupKey; if (arg.getPackageName() != null) { @@ -110,82 +86,109 @@ public void initialize() { } else { assetLookupKey = flutterState.keyForAsset.get(arg.getAsset()); } - player = - new VideoPlayer( - flutterState.applicationContext, - VideoPlayerEventCallbacks.bindTo(eventChannel), - handle, - "asset:///" + assetLookupKey, - null, - new HashMap<>(), - options); + videoAsset = VideoAsset.fromAssetUrl("asset:///" + assetLookupKey); + } else if (arg.getUri().startsWith("rtsp://")) { + videoAsset = VideoAsset.fromRtspUrl(arg.getUri()); } else { - Map httpHeaders = arg.getHttpHeaders(); - player = - new VideoPlayer( - flutterState.applicationContext, - VideoPlayerEventCallbacks.bindTo(eventChannel), - handle, - arg.getUri(), - arg.getFormatHint(), - httpHeaders, - options); + VideoAsset.StreamingFormat streamingFormat = VideoAsset.StreamingFormat.UNKNOWN; + String formatHint = arg.getFormatHint(); + if (formatHint != null) { + switch (formatHint) { + case "ss": + streamingFormat = VideoAsset.StreamingFormat.SMOOTH; + break; + case "dash": + streamingFormat = VideoAsset.StreamingFormat.DYNAMIC_ADAPTIVE; + break; + case "hls": + streamingFormat = VideoAsset.StreamingFormat.HTTP_LIVE; + break; + } + } + videoAsset = VideoAsset.fromRemoteUrl(arg.getUri(), streamingFormat, arg.getHttpHeaders()); + } + videoPlayers.put( + handle.id(), + VideoPlayer.create( + flutterState.applicationContext, + VideoPlayerEventCallbacks.bindTo(eventChannel), + handle, + videoAsset, + options)); + + return handle.id(); + } + + @NonNull + private VideoPlayer getPlayer(long textureId) { + VideoPlayer player = videoPlayers.get(textureId); + + // Avoid a very ugly un-debuggable NPE that results in returning a null player. + if (player == null) { + String message = "No player found with textureId <" + textureId + ">"; + if (videoPlayers.size() == 0) { + message += " and no active players created by the plugin."; + } + throw new IllegalStateException(message); } - videoPlayers.put(handle.id(), player); - return new TextureMessage.Builder().setTextureId(handle.id()).build(); + return player; } - public void dispose(@NonNull TextureMessage arg) { - VideoPlayer player = videoPlayers.get(arg.getTextureId()); + @Override + public void dispose(@NonNull Long textureId) { + VideoPlayer player = getPlayer(textureId); player.dispose(); - videoPlayers.remove(arg.getTextureId()); + videoPlayers.remove(textureId); } - public void setLooping(@NonNull LoopingMessage arg) { - VideoPlayer player = videoPlayers.get(arg.getTextureId()); - player.setLooping(arg.getIsLooping()); + @Override + public void setLooping(@NonNull Long textureId, @NonNull Boolean looping) { + VideoPlayer player = getPlayer(textureId); + player.setLooping(looping); } - public void setVolume(@NonNull VolumeMessage arg) { - VideoPlayer player = videoPlayers.get(arg.getTextureId()); - player.setVolume(arg.getVolume()); + @Override + public void setVolume(@NonNull Long textureId, @NonNull Double volume) { + VideoPlayer player = getPlayer(textureId); + player.setVolume(volume); } - public void setPlaybackSpeed(@NonNull PlaybackSpeedMessage arg) { - VideoPlayer player = videoPlayers.get(arg.getTextureId()); - player.setPlaybackSpeed(arg.getSpeed()); + @Override + public void setPlaybackSpeed(@NonNull Long textureId, @NonNull Double speed) { + VideoPlayer player = getPlayer(textureId); + player.setPlaybackSpeed(speed); } - public void play(@NonNull TextureMessage arg) { - VideoPlayer player = videoPlayers.get(arg.getTextureId()); + @Override + public void play(@NonNull Long textureId) { + VideoPlayer player = getPlayer(textureId); player.play(); } - public @NonNull PositionMessage position(@NonNull TextureMessage arg) { - VideoPlayer player = videoPlayers.get(arg.getTextureId()); - PositionMessage result = - new PositionMessage.Builder() - .setPosition(player.getPosition()) - .setTextureId(arg.getTextureId()) - .build(); + @Override + public @NonNull Long position(@NonNull Long textureId) { + VideoPlayer player = getPlayer(textureId); + long position = player.getPosition(); player.sendBufferingUpdate(); - return result; + return position; } - public void seekTo(@NonNull PositionMessage arg) { - VideoPlayer player = videoPlayers.get(arg.getTextureId()); - player.seekTo(arg.getPosition().intValue()); + @Override + public void seekTo(@NonNull Long textureId, @NonNull Long position) { + VideoPlayer player = getPlayer(textureId); + player.seekTo(position.intValue()); } - public void pause(@NonNull TextureMessage arg) { - VideoPlayer player = videoPlayers.get(arg.getTextureId()); + @Override + public void pause(@NonNull Long textureId) { + VideoPlayer player = getPlayer(textureId); player.pause(); } @Override - public void setMixWithOthers(@NonNull MixWithOthersMessage arg) { - options.mixWithOthers = arg.getMixWithOthers(); + public void setMixWithOthers(@NonNull Boolean mixWithOthers) { + options.mixWithOthers = mixWithOthers; } private interface KeyForAssetFn { @@ -217,11 +220,11 @@ private static final class FlutterState { } void startListening(VideoPlayerPlugin methodCallHandler, BinaryMessenger messenger) { - AndroidVideoPlayerApi.setup(messenger, methodCallHandler); + AndroidVideoPlayerApi.setUp(messenger, methodCallHandler); } void stopListening(BinaryMessenger messenger) { - AndroidVideoPlayerApi.setup(messenger, null); + AndroidVideoPlayerApi.setUp(messenger, null); } } } diff --git a/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/ExoPlayerEventListenerTest.java b/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/ExoPlayerEventListenerTest.java new file mode 100644 index 000000000000..65dfb311c31c --- /dev/null +++ b/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/ExoPlayerEventListenerTest.java @@ -0,0 +1,256 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.videoplayer; + +import static org.mockito.ArgumentMatchers.contains; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import androidx.media3.common.Format; +import androidx.media3.common.PlaybackException; +import androidx.media3.common.Player; +import androidx.media3.common.VideoSize; +import androidx.media3.exoplayer.ExoPlayer; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +/** + * Unit tests for {@link ExoPlayerEventListener}. + * + *

This test suite narrowly verifies that the events emitted by the underlying {@link + * androidx.media3.exoplayer.ExoPlayer} instance are translated to the callback interface we expect + * ({@link VideoPlayerCallbacks} and/or interface with the player instance as expected. + */ +@RunWith(RobolectricTestRunner.class) +public final class ExoPlayerEventListenerTest { + @Mock private ExoPlayer mockExoPlayer; + @Mock private VideoPlayerCallbacks mockCallbacks; + private ExoPlayerEventListener eventListener; + + @Rule public MockitoRule initRule = MockitoJUnit.rule(); + + @Before + public void setUp() { + eventListener = new ExoPlayerEventListener(mockExoPlayer, mockCallbacks); + } + + @Test + @Config(maxSdk = 28) + public void onPlaybackStateChangedReadySendInitialized_belowAndroid29() { + VideoSize size = new VideoSize(800, 400, 0, 0); + when(mockExoPlayer.getVideoSize()).thenReturn(size); + when(mockExoPlayer.getDuration()).thenReturn(10L); + + eventListener.onPlaybackStateChanged(Player.STATE_READY); + verify(mockCallbacks).onInitialized(800, 400, 10L, 0); + } + + @Test + @Config(minSdk = 29) + public void + onPlaybackStateChangedReadySendInitializedWithRotationCorrectionAndWidthAndHeightSwap_aboveAndroid29() { + VideoSize size = new VideoSize(800, 400, 0, 0); + int rotationCorrection = 90; + Format videoFormat = new Format.Builder().setRotationDegrees(rotationCorrection).build(); + + when(mockExoPlayer.getVideoSize()).thenReturn(size); + when(mockExoPlayer.getDuration()).thenReturn(10L); + when(mockExoPlayer.getVideoFormat()).thenReturn(videoFormat); + + eventListener.onPlaybackStateChanged(Player.STATE_READY); + verify(mockCallbacks).onInitialized(400, 800, 10L, rotationCorrection); + } + + @Test + @Config(maxSdk = 21) + public void + onPlaybackStateChangedReadyInPortraitMode90DegreesSwapWidthAndHeight_belowAndroid21() { + VideoSize size = new VideoSize(800, 400, 90, 0); + when(mockExoPlayer.getVideoSize()).thenReturn(size); + when(mockExoPlayer.getDuration()).thenReturn(10L); + + eventListener.onPlaybackStateChanged(Player.STATE_READY); + verify(mockCallbacks).onInitialized(400, 800, 10L, 0); + } + + @Test + @Config(minSdk = 22, maxSdk = 28) + public void + onPlaybackStateChangedReadyInPortraitMode90DegreesDoesNotSwapWidthAndHeight_aboveAndroid21belowAndroid29() { + VideoSize size = new VideoSize(800, 400, 90, 0); + + when(mockExoPlayer.getVideoSize()).thenReturn(size); + when(mockExoPlayer.getDuration()).thenReturn(10L); + + eventListener.onPlaybackStateChanged(Player.STATE_READY); + verify(mockCallbacks).onInitialized(800, 400, 10L, 0); + } + + @Test + @Config(minSdk = 29) + public void + onPlaybackStateChangedReadyInPortraitMode90DegreesSwapWidthAndHeight_aboveAndroid29() { + VideoSize size = new VideoSize(800, 400, 0, 0); + int rotationCorrection = 90; + Format videoFormat = new Format.Builder().setRotationDegrees(rotationCorrection).build(); + + when(mockExoPlayer.getVideoSize()).thenReturn(size); + when(mockExoPlayer.getDuration()).thenReturn(10L); + when(mockExoPlayer.getVideoFormat()).thenReturn(videoFormat); + + eventListener.onPlaybackStateChanged(Player.STATE_READY); + verify(mockCallbacks).onInitialized(400, 800, 10L, 90); + } + + @Test + @Config(maxSdk = 21) + public void + onPlaybackStateChangedReadyInPortraitMode270DegreesSwapWidthAndHeight_belowAndroid21() { + VideoSize size = new VideoSize(800, 400, 270, 0); + when(mockExoPlayer.getVideoSize()).thenReturn(size); + when(mockExoPlayer.getDuration()).thenReturn(10L); + + eventListener.onPlaybackStateChanged(Player.STATE_READY); + verify(mockCallbacks).onInitialized(400, 800, 10L, 0); + } + + @Test + @Config(minSdk = 22, maxSdk = 28) + public void + onPlaybackStateChangedReadyInPortraitMode270DegreesDoesNotSwapWidthAndHeight_aboveAndroid21belowAndroid29() { + VideoSize size = new VideoSize(800, 400, 270, 0); + when(mockExoPlayer.getVideoSize()).thenReturn(size); + when(mockExoPlayer.getDuration()).thenReturn(10L); + + eventListener.onPlaybackStateChanged(Player.STATE_READY); + verify(mockCallbacks).onInitialized(800, 400, 10L, 0); + } + + @Test + @Config(minSdk = 29) + public void + onPlaybackStateChangedReadyInPortraitMode270DegreesSwapWidthAndHeight_aboveAndroid29() { + VideoSize size = new VideoSize(800, 400, 0, 0); + int rotationCorrection = 270; + Format videoFormat = new Format.Builder().setRotationDegrees(rotationCorrection).build(); + + when(mockExoPlayer.getVideoSize()).thenReturn(size); + when(mockExoPlayer.getDuration()).thenReturn(10L); + when(mockExoPlayer.getVideoFormat()).thenReturn(videoFormat); + + eventListener.onPlaybackStateChanged(Player.STATE_READY); + verify(mockCallbacks).onInitialized(400, 800, 10L, 270); + } + + @Test + @Config(maxSdk = 21) + public void onPlaybackStateChangedReadyFlipped180DegreesInformEventHandler_belowAndroid21() { + VideoSize size = new VideoSize(800, 400, 180, 0); + when(mockExoPlayer.getVideoSize()).thenReturn(size); + when(mockExoPlayer.getDuration()).thenReturn(10L); + + eventListener.onPlaybackStateChanged(Player.STATE_READY); + verify(mockCallbacks).onInitialized(800, 400, 10L, 180); + } + + @Test + public void onPlaybackStateChangedBufferingSendsBufferingStartAndUpdates() { + when(mockExoPlayer.getBufferedPosition()).thenReturn(10L); + eventListener.onPlaybackStateChanged(Player.STATE_BUFFERING); + + verify(mockCallbacks).onBufferingStart(); + verify(mockCallbacks).onBufferingUpdate(10L); + verifyNoMoreInteractions(mockCallbacks); + + // If it's invoked again, only the update event is called. + verify(mockCallbacks).onBufferingUpdate(10L); + verifyNoMoreInteractions(mockCallbacks); + } + + @Test + public void onPlaybackStateChangedEndedSendsOnCompleted() { + eventListener.onPlaybackStateChanged(Player.STATE_ENDED); + + verify(mockCallbacks).onCompleted(); + verifyNoMoreInteractions(mockCallbacks); + } + + @Test + public void onPlaybackStateChangedEndedAfterBufferingSendsBufferingEndAndOnCompleted() { + when(mockExoPlayer.getBufferedPosition()).thenReturn(10L); + eventListener.onPlaybackStateChanged(Player.STATE_BUFFERING); + verify(mockCallbacks).onBufferingStart(); + verify(mockCallbacks).onBufferingUpdate(10L); + + eventListener.onPlaybackStateChanged(Player.STATE_ENDED); + verify(mockCallbacks).onCompleted(); + verify(mockCallbacks).onBufferingEnd(); + + verifyNoMoreInteractions(mockCallbacks); + } + + @Test + public void onPlaybackStateChangedIdleDoNothing() { + eventListener.onPlaybackStateChanged(Player.STATE_IDLE); + + verifyNoInteractions(mockCallbacks); + } + + @Test + public void onPlaybackStateChangedIdleAfterBufferingSendsBufferingEnd() { + when(mockExoPlayer.getBufferedPosition()).thenReturn(10L); + eventListener.onPlaybackStateChanged(Player.STATE_BUFFERING); + verify(mockCallbacks).onBufferingStart(); + verify(mockCallbacks).onBufferingUpdate(10L); + + eventListener.onPlaybackStateChanged(Player.STATE_IDLE); + verify(mockCallbacks).onBufferingEnd(); + + verifyNoMoreInteractions(mockCallbacks); + } + + @Test + public void onErrorVideoErrorWhenBufferingInProgressAlsoEndBuffering() { + when(mockExoPlayer.getBufferedPosition()).thenReturn(10L); + eventListener.onPlaybackStateChanged(Player.STATE_BUFFERING); + verify(mockCallbacks).onBufferingStart(); + verify(mockCallbacks).onBufferingUpdate(10L); + + eventListener.onPlayerError( + new PlaybackException("BAD", null, PlaybackException.ERROR_CODE_AUDIO_TRACK_INIT_FAILED)); + verify(mockCallbacks).onBufferingEnd(); + verify(mockCallbacks).onError(eq("VideoError"), contains("BAD"), isNull()); + } + + @Test + public void onErrorBehindLiveWindowSeekToDefaultAndPrepare() { + eventListener.onPlayerError( + new PlaybackException("SORT_OF_OK", null, PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW)); + + verify(mockExoPlayer).seekToDefaultPosition(); + verify(mockExoPlayer).prepare(); + verifyNoInteractions(mockCallbacks); + } + + @Test + public void onIsPlayingChangedToggled() { + eventListener.onIsPlayingChanged(true); + verify(mockCallbacks).onIsPlayingStateUpdate(true); + + eventListener.onIsPlayingChanged(false); + verify(mockCallbacks).onIsPlayingStateUpdate(false); + } +} diff --git a/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/FakeVideoAsset.java b/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/FakeVideoAsset.java new file mode 100644 index 000000000000..1e3b856a6482 --- /dev/null +++ b/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/FakeVideoAsset.java @@ -0,0 +1,36 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.videoplayer; + +import android.content.Context; +import androidx.annotation.NonNull; +import androidx.media3.common.MediaItem; +import androidx.media3.exoplayer.source.MediaSource; +import androidx.media3.test.utils.FakeMediaSourceFactory; + +/** A fake implementation of the {@link VideoAsset} class. */ +final class FakeVideoAsset extends VideoAsset { + @NonNull private final MediaSource.Factory mediaSourceFactory; + + FakeVideoAsset(String assetUrl) { + this(assetUrl, new FakeMediaSourceFactory()); + } + + FakeVideoAsset(String assetUrl, @NonNull MediaSource.Factory mediaSourceFactory) { + super(assetUrl); + this.mediaSourceFactory = mediaSourceFactory; + } + + @NonNull + @Override + MediaItem getMediaItem() { + return new MediaItem.Builder().setUri(assetUrl).build(); + } + + @Override + MediaSource.Factory getMediaSourceFactory(Context context) { + return mediaSourceFactory; + } +} diff --git a/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/VideoAssetTest.java b/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/VideoAssetTest.java new file mode 100644 index 000000000000..6e95d0504c3d --- /dev/null +++ b/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/VideoAssetTest.java @@ -0,0 +1,154 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.videoplayer; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyMap; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.net.Uri; +import androidx.media3.common.MediaItem; +import androidx.media3.datasource.DefaultHttpDataSource; +import androidx.media3.exoplayer.source.MediaSource; +import androidx.test.core.app.ApplicationProvider; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; + +/** + * Unit tests for {@link VideoAsset}. + * + *

This test suite narrowly verifies that the {@link VideoAsset} factory methods, {@link + * VideoAsset#fromRemoteUrl(String, VideoAsset.StreamingFormat, Map)} and {@link + * VideoAsset#fromAssetUrl(String)} follow the contract they have documented. + * + *

In other tests of the player, a fake asset is likely to be used. + */ +@RunWith(RobolectricTestRunner.class) +public final class VideoAssetTest { + @Test + public void localVideoRequiresAssetUrl() { + assertThrows( + IllegalArgumentException.class, + () -> VideoAsset.fromAssetUrl("https://not.local/video.mp4")); + } + + @Test + public void localVideoCreatesMediaItem() { + VideoAsset asset = VideoAsset.fromAssetUrl("asset:///asset-key"); + MediaItem mediaItem = asset.getMediaItem(); + + assert mediaItem.localConfiguration != null; + assertEquals(mediaItem.localConfiguration.uri, Uri.parse("asset:///asset-key")); + } + + private static DefaultHttpDataSource.Factory mockHttpFactory() { + DefaultHttpDataSource.Factory httpFactory = mock(DefaultHttpDataSource.Factory.class); + when(httpFactory.setUserAgent(anyString())).thenReturn(httpFactory); + when(httpFactory.setAllowCrossProtocolRedirects(anyBoolean())).thenReturn(httpFactory); + when(httpFactory.setDefaultRequestProperties(anyMap())).thenReturn(httpFactory); + return httpFactory; + } + + @Test + public void remoteVideoByDefaultSetsUserAgentAndCrossProtocolRedirects() { + VideoAsset asset = + VideoAsset.fromRemoteUrl( + "https://flutter.dev/video.mp4", VideoAsset.StreamingFormat.UNKNOWN, new HashMap<>()); + + DefaultHttpDataSource.Factory mockFactory = mockHttpFactory(); + + // Cast to HttpVideoAsset to call a testing-only method to intercept calls. + ((HttpVideoAsset) asset) + .getMediaSourceFactory(ApplicationProvider.getApplicationContext(), mockFactory); + + verify(mockFactory).setUserAgent("ExoPlayer"); + verify(mockFactory).setAllowCrossProtocolRedirects(true); + verify(mockFactory, never()).setDefaultRequestProperties(anyMap()); + } + + @Test + public void remoteVideoOverridesUserAgentIfProvided() { + Map headers = new HashMap<>(); + headers.put("User-Agent", "FantasticalVideoBot"); + + VideoAsset asset = + VideoAsset.fromRemoteUrl( + "https://flutter.dev/video.mp4", VideoAsset.StreamingFormat.UNKNOWN, headers); + + DefaultHttpDataSource.Factory mockFactory = mockHttpFactory(); + + // Cast to HttpVideoAsset to call a testing-only method to intercept calls. + ((HttpVideoAsset) asset) + .getMediaSourceFactory(ApplicationProvider.getApplicationContext(), mockFactory); + + verify(mockFactory).setUserAgent("FantasticalVideoBot"); + verify(mockFactory).setAllowCrossProtocolRedirects(true); + verify(mockFactory).setDefaultRequestProperties(headers); + } + + // This tests that without using the overrides we get a working, non-mocked object. + // + // I guess you could also start a local HTTP server, and try fetching with it, YMMV. + @Test + public void remoteVideoGetMediaSourceFactoryInProductionReturnsRealMediaSource() { + VideoAsset asset = + VideoAsset.fromRemoteUrl( + "https://flutter.dev/video.mp4", VideoAsset.StreamingFormat.UNKNOWN, new HashMap<>()); + + MediaSource source = + asset + .getMediaSourceFactory(ApplicationProvider.getApplicationContext()) + .createMediaSource(asset.getMediaItem()); + assertEquals( + Uri.parse("https://flutter.dev/video.mp4"), + Objects.requireNonNull(source.getMediaItem().localConfiguration).uri); + } + + @Test + public void remoteVideoSetsAdditionalHttpHeadersIfProvided() { + Map headers = new HashMap<>(); + headers.put("X-Cache-Forever", "true"); + + VideoAsset asset = + VideoAsset.fromRemoteUrl( + "https://flutter.dev/video.mp4", VideoAsset.StreamingFormat.UNKNOWN, headers); + + DefaultHttpDataSource.Factory mockFactory = mockHttpFactory(); + + // Cast to HttpVideoAsset to call a testing-only method to intercept calls. + ((HttpVideoAsset) asset) + .getMediaSourceFactory(ApplicationProvider.getApplicationContext(), mockFactory); + + verify(mockFactory).setUserAgent("ExoPlayer"); + verify(mockFactory).setAllowCrossProtocolRedirects(true); + verify(mockFactory).setDefaultRequestProperties(headers); + } + + @Test + public void rtspVideoRequiresRtspUrl() { + assertThrows( + IllegalArgumentException.class, () -> VideoAsset.fromRtspUrl("https://not.rtsp/video.mp4")); + } + + @Test + public void rtspVideoCreatesMediaItem() { + VideoAsset asset = VideoAsset.fromRtspUrl("rtsp://test:pass@flutter.dev/stream"); + MediaItem mediaItem = asset.getMediaItem(); + + assert mediaItem.localConfiguration != null; + assertEquals( + mediaItem.localConfiguration.uri, Uri.parse("rtsp://test:pass@flutter.dev/stream")); + } +} diff --git a/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/VideoPlayerEventCallbacksTest.java b/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/VideoPlayerEventCallbacksTest.java new file mode 100644 index 000000000000..d955384bc94f --- /dev/null +++ b/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/VideoPlayerEventCallbacksTest.java @@ -0,0 +1,151 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.videoplayer; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.verify; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.robolectric.RobolectricTestRunner; + +/** + * Unit tests {@link VideoPlayerEventCallbacks}. + * + *

This test suite narrowly verifies that calling the provided event callbacks, such as + * {@link VideoPlayerEventCallbacks#onBufferingUpdate(long)}, produces the expected data as an + * encoded {@link Map}. + * + *

In other words, this tests that "the Java-side of the event channel works as expected". + */ +@RunWith(RobolectricTestRunner.class) +public final class VideoPlayerEventCallbacksTest { + private VideoPlayerEventCallbacks eventCallbacks; + + @Mock private QueuingEventSink mockEventSink; + + @Captor private ArgumentCaptor> eventCaptor; + + @Rule public MockitoRule initRule = MockitoJUnit.rule(); + + @Before + public void setUp() { + eventCallbacks = VideoPlayerEventCallbacks.withSink(mockEventSink); + } + + @Test + public void onInitializedSendsWidthHeightAndDuration() { + eventCallbacks.onInitialized(800, 400, 10L, 0); + + verify(mockEventSink).success(eventCaptor.capture()); + + Map actual = eventCaptor.getValue(); + Map expected = new HashMap<>(); + expected.put("event", "initialized"); + expected.put("duration", 10L); + expected.put("width", 800); + expected.put("height", 400); + + assertEquals(expected, actual); + } + + @Test + public void onInitializedIncludesRotationCorrectIfNonZero() { + eventCallbacks.onInitialized(800, 400, 10L, 180); + + verify(mockEventSink).success(eventCaptor.capture()); + + Map actual = eventCaptor.getValue(); + Map expected = new HashMap<>(); + expected.put("event", "initialized"); + expected.put("duration", 10L); + expected.put("width", 800); + expected.put("height", 400); + expected.put("rotationCorrection", 180); + + assertEquals(expected, actual); + } + + @Test + public void onBufferingStart() { + eventCallbacks.onBufferingStart(); + + verify(mockEventSink).success(eventCaptor.capture()); + + Map actual = eventCaptor.getValue(); + Map expected = new HashMap<>(); + expected.put("event", "bufferingStart"); + assertEquals(expected, actual); + } + + @Test + public void onBufferingUpdateProvidesAListWithASingleRange() { + eventCallbacks.onBufferingUpdate(10L); + + verify(mockEventSink).success(eventCaptor.capture()); + + Map actual = eventCaptor.getValue(); + Map expected = new HashMap<>(); + expected.put("event", "bufferingUpdate"); + expected.put("values", Collections.singletonList(Arrays.asList(0, 10L))); + assertEquals(expected, actual); + } + + @Test + public void onBufferingEnd() { + eventCallbacks.onBufferingEnd(); + + verify(mockEventSink).success(eventCaptor.capture()); + + Map actual = eventCaptor.getValue(); + Map expected = new HashMap<>(); + expected.put("event", "bufferingEnd"); + assertEquals(expected, actual); + } + + @Test + public void onCompleted() { + eventCallbacks.onCompleted(); + + verify(mockEventSink).success(eventCaptor.capture()); + + Map actual = eventCaptor.getValue(); + Map expected = new HashMap<>(); + expected.put("event", "completed"); + assertEquals(expected, actual); + } + + @Test + public void onError() { + eventCallbacks.onError("code", "message", "details"); + + verify(mockEventSink).error(eq("code"), eq("message"), eq("details")); + } + + @Test + public void onIsPlayingStateUpdate() { + eventCallbacks.onIsPlayingStateUpdate(true); + + verify(mockEventSink).success(eventCaptor.capture()); + + Map actual = eventCaptor.getValue(); + Map expected = new HashMap<>(); + expected.put("event", "isPlayingStateUpdate"); + expected.put("isPlaying", true); + assertEquals(expected, actual); + } +} diff --git a/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/VideoPlayerTest.java b/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/VideoPlayerTest.java index d854601ff3fa..4912803ce1d4 100644 --- a/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/VideoPlayerTest.java +++ b/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/VideoPlayerTest.java @@ -5,355 +5,308 @@ package io.flutter.plugins.videoplayer; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.*; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import android.graphics.SurfaceTexture; -import androidx.media3.common.PlaybackException; +import android.view.Surface; +import androidx.media3.common.AudioAttributes; +import androidx.media3.common.C; +import androidx.media3.common.PlaybackParameters; import androidx.media3.common.Player; import androidx.media3.common.VideoSize; -import androidx.media3.datasource.DefaultHttpDataSource; import androidx.media3.exoplayer.ExoPlayer; import io.flutter.view.TextureRegistry; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; -import org.mockito.MockitoAnnotations; -import org.mockito.stubbing.Answer; +import org.mockito.InOrder; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; import org.robolectric.RobolectricTestRunner; +/** + * Unit tests for {@link VideoPlayer}. + * + *

This test suite narrowly verifies that {@link VideoPlayer} interfaces with the {@link + * ExoPlayer} interface exactly as it did when the test suite was created. That is, if the + * behavior changes, this test will need to change. However, this suite should catch bugs related to + * "this is a safe refactor with no behavior changes". + * + *

It's hypothetically possible to write better tests using {@link + * androidx.media3.test.utils.FakeMediaSource}, but you really need a PhD in the Android media APIs + * in order to figure out how to set everything up so the player "works". + */ @RunWith(RobolectricTestRunner.class) -public class VideoPlayerTest { - private ExoPlayer fakeExoPlayer; - private TextureRegistry.SurfaceTextureEntry fakeSurfaceTextureEntry; - private VideoPlayerOptions fakeVideoPlayerOptions; - private QueuingEventSink fakeEventSink; - private DefaultHttpDataSource.Factory httpDataSourceFactorySpy; +public final class VideoPlayerTest { + private static final String FAKE_ASSET_URL = "https://flutter.dev/movie.mp4"; + private FakeVideoAsset fakeVideoAsset; - @Captor private ArgumentCaptor> eventCaptor; + @Mock private VideoPlayerCallbacks mockEvents; + @Mock private TextureRegistry.SurfaceProducer mockProducer; + @Mock private ExoPlayer mockExoPlayer; + @Captor private ArgumentCaptor attributesCaptor; + @Captor private ArgumentCaptor callbackCaptor; + @Captor private ArgumentCaptor listenerCaptor; - private AutoCloseable mocks; + @Rule public MockitoRule initRule = MockitoJUnit.rule(); @Before - public void before() { - mocks = MockitoAnnotations.openMocks(this); - - fakeExoPlayer = mock(ExoPlayer.class); - fakeSurfaceTextureEntry = mock(TextureRegistry.SurfaceTextureEntry.class); - SurfaceTexture fakeSurfaceTexture = mock(SurfaceTexture.class); - when(fakeSurfaceTextureEntry.surfaceTexture()).thenReturn(fakeSurfaceTexture); - fakeVideoPlayerOptions = mock(VideoPlayerOptions.class); - fakeEventSink = mock(QueuingEventSink.class); - httpDataSourceFactorySpy = spy(new DefaultHttpDataSource.Factory()); + public void setUp() { + fakeVideoAsset = new FakeVideoAsset(FAKE_ASSET_URL); + when(mockProducer.getSurface()).thenReturn(mock(Surface.class)); } - @After - public void after() throws Exception { - mocks.close(); + private VideoPlayer createVideoPlayer() { + return createVideoPlayer(new VideoPlayerOptions()); } - @Test - public void videoPlayer_buildsHttpDataSourceFactoryProperlyWhenHttpHeadersNull() { - VideoPlayer videoPlayer = - new VideoPlayer( - fakeExoPlayer, - VideoPlayerEventCallbacks.withSink(fakeEventSink), - fakeSurfaceTextureEntry, - fakeVideoPlayerOptions, - httpDataSourceFactorySpy); - - videoPlayer.configureHttpDataSourceFactory(new HashMap<>()); - - verify(httpDataSourceFactorySpy).setUserAgent("ExoPlayer"); - verify(httpDataSourceFactorySpy).setAllowCrossProtocolRedirects(true); - verify(httpDataSourceFactorySpy, never()).setDefaultRequestProperties(any()); + private VideoPlayer createVideoPlayer(VideoPlayerOptions options) { + return new VideoPlayer( + () -> mockExoPlayer, mockEvents, mockProducer, fakeVideoAsset.getMediaItem(), options); } @Test - public void - videoPlayer_buildsHttpDataSourceFactoryProperlyWhenHttpHeadersNonNullAndUserAgentSpecified() { - VideoPlayer videoPlayer = - new VideoPlayer( - fakeExoPlayer, - VideoPlayerEventCallbacks.withSink(fakeEventSink), - fakeSurfaceTextureEntry, - fakeVideoPlayerOptions, - httpDataSourceFactorySpy); - Map httpHeaders = - new HashMap() { - { - put("header", "value"); - put("User-Agent", "userAgent"); - } - }; - - videoPlayer.configureHttpDataSourceFactory(httpHeaders); - - verify(httpDataSourceFactorySpy).setUserAgent("userAgent"); - verify(httpDataSourceFactorySpy).setAllowCrossProtocolRedirects(true); - verify(httpDataSourceFactorySpy).setDefaultRequestProperties(httpHeaders); + public void loadsAndPreparesProvidedMediaEnablesAudioFocusByDefault() { + VideoPlayer videoPlayer = createVideoPlayer(); + + verify(mockExoPlayer).setMediaItem(fakeVideoAsset.getMediaItem()); + verify(mockExoPlayer).prepare(); + verify(mockProducer).getSurface(); + verify(mockExoPlayer).setVideoSurface(any()); + + verify(mockExoPlayer).setAudioAttributes(attributesCaptor.capture(), eq(true)); + assertEquals(attributesCaptor.getValue().contentType, C.AUDIO_CONTENT_TYPE_MOVIE); + + videoPlayer.dispose(); } @Test - public void - videoPlayer_buildsHttpDataSourceFactoryProperlyWhenHttpHeadersNonNullAndUserAgentNotSpecified() { - VideoPlayer videoPlayer = - new VideoPlayer( - fakeExoPlayer, - VideoPlayerEventCallbacks.withSink(fakeEventSink), - fakeSurfaceTextureEntry, - fakeVideoPlayerOptions, - httpDataSourceFactorySpy); - Map httpHeaders = - new HashMap() { - { - put("header", "value"); - } - }; - - videoPlayer.configureHttpDataSourceFactory(httpHeaders); - - verify(httpDataSourceFactorySpy).setUserAgent("ExoPlayer"); - verify(httpDataSourceFactorySpy).setAllowCrossProtocolRedirects(true); - verify(httpDataSourceFactorySpy).setDefaultRequestProperties(httpHeaders); - } + public void loadsAndPreparesProvidedMediaDisablesAudioFocusWhenMixModeSet() { + VideoPlayerOptions options = new VideoPlayerOptions(); + options.mixWithOthers = true; - private Player.Listener initVideoPlayerAndGetListener() { - ArgumentCaptor listenerCaptor = ArgumentCaptor.forClass(Player.Listener.class); - doNothing().when(fakeExoPlayer).addListener(listenerCaptor.capture()); + VideoPlayer videoPlayer = createVideoPlayer(options); - // Create a video player that will invoke fakeEventSink as a result of Player.Listener calls. - new VideoPlayer( - fakeExoPlayer, - VideoPlayerEventCallbacks.withSink(fakeEventSink), - fakeSurfaceTextureEntry, - fakeVideoPlayerOptions, - httpDataSourceFactorySpy); + verify(mockExoPlayer).setAudioAttributes(attributesCaptor.capture(), eq(false)); + assertEquals(attributesCaptor.getValue().contentType, C.AUDIO_CONTENT_TYPE_MOVIE); - return Objects.requireNonNull(listenerCaptor.getValue()); + videoPlayer.dispose(); } @Test - public void onPlaybackStateBufferingSendBufferedPositionUpdate() { - Player.Listener listener = initVideoPlayerAndGetListener(); - when(fakeExoPlayer.getBufferedPosition()).thenReturn(10L); + public void playsAndPausesProvidedMedia() { + VideoPlayer videoPlayer = createVideoPlayer(); - // Send Player.STATE_BUFFERING to trigger the "bufferingUpdate" event. - listener.onPlaybackStateChanged(Player.STATE_BUFFERING); + videoPlayer.play(); + verify(mockExoPlayer).play(); - verify(fakeEventSink, atLeast(1)).success(eventCaptor.capture()); - List> events = eventCaptor.getAllValues(); + videoPlayer.pause(); + verify(mockExoPlayer).pause(); - Map expected = new HashMap<>(); - expected.put("event", "bufferingUpdate"); + videoPlayer.dispose(); + } - List range = Arrays.asList(0, 10L); - expected.put("values", Collections.singletonList(range)); + @Test + public void sendsBufferingUpdatesOnDemand() { + VideoPlayer videoPlayer = createVideoPlayer(); - // We received potentially multiple events, find the one that is a "bufferingUpdate". - for (Map event : events) { - if (event.get("event") == "bufferingUpdate") { - assertEquals(expected, event); - return; - } - } + when(mockExoPlayer.getBufferedPosition()).thenReturn(10L); + videoPlayer.sendBufferingUpdate(); + verify(mockEvents).onBufferingUpdate(10L); - fail("No 'bufferingUpdate' event found: " + events); + videoPlayer.dispose(); } @Test - public void sendInitializedSendsExpectedEvent_90RotationDegrees() { - Player.Listener listener = initVideoPlayerAndGetListener(); - VideoSize testVideoSize = new VideoSize(100, 200, 90, 1f); + public void togglesLoopingEnablesAndDisablesRepeatMode() { + VideoPlayer videoPlayer = createVideoPlayer(); - when(fakeExoPlayer.getVideoSize()).thenReturn(testVideoSize); - when(fakeExoPlayer.getDuration()).thenReturn(10L); + videoPlayer.setLooping(true); + verify(mockExoPlayer).setRepeatMode(Player.REPEAT_MODE_ALL); - // Send Player.STATE_READY to trigger the "initialized" event. - listener.onPlaybackStateChanged(Player.STATE_READY); + videoPlayer.setLooping(false); + verify(mockExoPlayer).setRepeatMode(Player.REPEAT_MODE_OFF); - verify(fakeEventSink).success(eventCaptor.capture()); - HashMap actual = eventCaptor.getValue(); + videoPlayer.dispose(); + } + + @Test + public void setVolumeIsClampedBetween0and1() { + VideoPlayer videoPlayer = createVideoPlayer(); + + videoPlayer.setVolume(-1.0); + verify(mockExoPlayer).setVolume(0f); + + videoPlayer.setVolume(2.0); + verify(mockExoPlayer).setVolume(1f); - Map expected = new HashMap<>(); - expected.put("event", "initialized"); - expected.put("duration", 10L); - expected.put("width", 200); - expected.put("height", 100); + videoPlayer.setVolume(0.5); + verify(mockExoPlayer).setVolume(0.5f); - assertEquals(expected, actual); + videoPlayer.dispose(); } @Test - public void sendInitializedSendsExpectedEvent_270RotationDegrees() { - Player.Listener listener = initVideoPlayerAndGetListener(); - VideoSize testVideoSize = new VideoSize(100, 200, 270, 1f); + public void setPlaybackSpeedSetsPlaybackParametersWithValue() { + VideoPlayer videoPlayer = createVideoPlayer(); - when(fakeExoPlayer.getVideoSize()).thenReturn(testVideoSize); - when(fakeExoPlayer.getDuration()).thenReturn(10L); + videoPlayer.setPlaybackSpeed(2.5); + verify(mockExoPlayer).setPlaybackParameters(new PlaybackParameters(2.5f)); - // Send Player.STATE_READY to trigger the "initialized" event. - listener.onPlaybackStateChanged(Player.STATE_READY); + videoPlayer.dispose(); + } - verify(fakeEventSink).success(eventCaptor.capture()); - HashMap actual = eventCaptor.getValue(); + @Test + public void seekAndGetPosition() { + VideoPlayer videoPlayer = createVideoPlayer(); - Map expected = new HashMap<>(); - expected.put("event", "initialized"); - expected.put("duration", 10L); - expected.put("width", 200); - expected.put("height", 100); + videoPlayer.seekTo(10); + verify(mockExoPlayer).seekTo(10); - assertEquals(expected, actual); + when(mockExoPlayer.getCurrentPosition()).thenReturn(20L); + assertEquals(20L, videoPlayer.getPosition()); } @Test - public void sendInitializedSendsExpectedEvent_0RotationDegrees() { - Player.Listener listener = initVideoPlayerAndGetListener(); - VideoSize testVideoSize = new VideoSize(100, 200, 0, 1f); + public void onSurfaceProducerDestroyedAndRecreatedReleasesAndThenRecreatesAndResumesPlayer() { + VideoPlayer videoPlayer = createVideoPlayer(); - when(fakeExoPlayer.getVideoSize()).thenReturn(testVideoSize); - when(fakeExoPlayer.getDuration()).thenReturn(10L); + verify(mockProducer).setCallback(callbackCaptor.capture()); + verify(mockExoPlayer, never()).release(); - // Send Player.STATE_READY to trigger the "initialized" event. - listener.onPlaybackStateChanged(Player.STATE_READY); + when(mockExoPlayer.getCurrentPosition()).thenReturn(10L); + when(mockExoPlayer.getRepeatMode()).thenReturn(Player.REPEAT_MODE_ALL); + when(mockExoPlayer.getVolume()).thenReturn(0.5f); + when(mockExoPlayer.getPlaybackParameters()).thenReturn(new PlaybackParameters(2.5f)); - verify(fakeEventSink).success(eventCaptor.capture()); - HashMap actual = eventCaptor.getValue(); + TextureRegistry.SurfaceProducer.Callback producerLifecycle = callbackCaptor.getValue(); + producerLifecycle.onSurfaceDestroyed(); - Map expected = new HashMap<>(); - expected.put("event", "initialized"); - expected.put("duration", 10L); - expected.put("width", 100); - expected.put("height", 200); + verify(mockExoPlayer).release(); - assertEquals(expected, actual); + // Create a new mock exo player so that we get a new instance. + mockExoPlayer = mock(ExoPlayer.class); + simulateSurfaceCreation(producerLifecycle); + + verify(mockExoPlayer).seekTo(10L); + verify(mockExoPlayer).setRepeatMode(Player.REPEAT_MODE_ALL); + verify(mockExoPlayer).setVolume(0.5f); + verify(mockExoPlayer).setPlaybackParameters(new PlaybackParameters(2.5f)); + + videoPlayer.dispose(); } @Test - public void sendInitializedSendsExpectedEvent_180RotationDegrees() { - Player.Listener listener = initVideoPlayerAndGetListener(); - VideoSize testVideoSize = new VideoSize(100, 200, 180, 1f); + public void onSurfaceProducerDestroyedDoesNotStopOrPauseVideo() { + VideoPlayer videoPlayer = createVideoPlayer(); - when(fakeExoPlayer.getVideoSize()).thenReturn(testVideoSize); - when(fakeExoPlayer.getDuration()).thenReturn(10L); + verify(mockProducer).setCallback(callbackCaptor.capture()); + TextureRegistry.SurfaceProducer.Callback producerLifecycle = callbackCaptor.getValue(); + producerLifecycle.onSurfaceDestroyed(); - // Send Player.STATE_READY to trigger the "initialized" event. - listener.onPlaybackStateChanged(Player.STATE_READY); + verify(mockExoPlayer, never()).stop(); + verify(mockExoPlayer, never()).pause(); + verify(mockExoPlayer, never()).setPlayWhenReady(anyBoolean()); - verify(fakeEventSink).success(eventCaptor.capture()); - HashMap actual = eventCaptor.getValue(); + videoPlayer.dispose(); + } - Map expected = new HashMap<>(); - expected.put("event", "initialized"); - expected.put("duration", 10L); - expected.put("width", 100); - expected.put("height", 200); - expected.put("rotationCorrection", 180); + @Test + public void onDisposeSurfaceProducerCallbackIsDisconnected() { + // Regression test for https://github.com/flutter/flutter/issues/156158. + VideoPlayer videoPlayer = createVideoPlayer(); + verify(mockProducer).setCallback(any()); - assertEquals(expected, actual); + videoPlayer.dispose(); + verify(mockProducer).setCallback(null); } @Test - public void onIsPlayingChangedSendsExpectedEvent() { - VideoPlayer videoPlayer = - new VideoPlayer( - fakeExoPlayer, - VideoPlayerEventCallbacks.withSink(fakeEventSink), - fakeSurfaceTextureEntry, - fakeVideoPlayerOptions, - httpDataSourceFactorySpy); - - doAnswer( - (Answer) - invocation -> { - Map event = new HashMap<>(); - event.put("event", "isPlayingStateUpdate"); - event.put("isPlaying", invocation.getArguments()[0]); - fakeEventSink.success(event); - return null; - }) - .when(fakeExoPlayer) - .setPlayWhenReady(anyBoolean()); + public void onInitializedCalledWhenVideoPlayerInitiallyCreated() { + VideoPlayer videoPlayer = createVideoPlayer(); - videoPlayer.play(); + // Pretend we have a video, and capture the registered event listener. + when(mockExoPlayer.getVideoSize()).thenReturn(new VideoSize(300, 200)); + verify(mockExoPlayer).addListener(listenerCaptor.capture()); + Player.Listener listener = listenerCaptor.getValue(); - verify(fakeEventSink).success(eventCaptor.capture()); - HashMap event1 = eventCaptor.getValue(); + // Trigger an event that would trigger onInitialized. + listener.onPlaybackStateChanged(Player.STATE_READY); + verify(mockEvents).onInitialized(anyInt(), anyInt(), anyLong(), anyInt()); - assertEquals(event1.get("event"), "isPlayingStateUpdate"); - assertEquals(event1.get("isPlaying"), true); + videoPlayer.dispose(); + } - videoPlayer.pause(); + @Test + public void onSurfaceCreatedDoesNotSendInitializeEventAgain() { + // The VideoPlayer contract assumes that the event "initialized" is sent exactly once + // (duplicate events cause an error to be thrown at the shared Dart layer). This test verifies + // that the onInitialized event is sent exactly once per player. + // + // Regression test for https://github.com/flutter/flutter/issues/154602. + VideoPlayer videoPlayer = createVideoPlayer(); + when(mockExoPlayer.getVideoSize()).thenReturn(new VideoSize(300, 200)); + + // Capture the lifecycle events so we can simulate onSurfaceCreated/Destroyed. + verify(mockProducer).setCallback(callbackCaptor.capture()); + TextureRegistry.SurfaceProducer.Callback producerLifecycle = callbackCaptor.getValue(); + + // Trigger destroyed/created. + producerLifecycle.onSurfaceDestroyed(); + simulateSurfaceCreation(producerLifecycle); + + // Initial listener, and the new one from the resume. + verify(mockExoPlayer, times(2)).addListener(listenerCaptor.capture()); + Player.Listener listener = listenerCaptor.getValue(); + + // Now trigger that same event, which would happen in the case of a background/resume. + listener.onPlaybackStateChanged(Player.STATE_READY); - verify(fakeEventSink, times(2)).success(eventCaptor.capture()); - HashMap event2 = eventCaptor.getValue(); + // Was not called because it was a result of a background/resume. + verify(mockEvents, never()).onInitialized(anyInt(), anyInt(), anyLong(), anyInt()); - assertEquals(event2.get("event"), "isPlayingStateUpdate"); - assertEquals(event2.get("isPlaying"), false); + videoPlayer.dispose(); } @Test - public void behindLiveWindowErrorResetsPlayerToDefaultPosition() { - List listeners = new LinkedList<>(); - doAnswer(invocation -> listeners.add(invocation.getArgument(0))) - .when(fakeExoPlayer) - .addListener(any()); - - @SuppressWarnings("unused") - VideoPlayer unused = - new VideoPlayer( - fakeExoPlayer, - VideoPlayerEventCallbacks.withSink(fakeEventSink), - fakeSurfaceTextureEntry, - fakeVideoPlayerOptions, - httpDataSourceFactorySpy); - - PlaybackException exception = - new PlaybackException(null, null, PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW); - listeners.forEach(listener -> listener.onPlayerError(exception)); - - verify(fakeExoPlayer).seekToDefaultPosition(); - verify(fakeExoPlayer).prepare(); + public void onSurfaceCreatedWithoutDestroyDoesNotRecreate() { + // Initially create the video player, which creates the initial surface. + VideoPlayer videoPlayer = createVideoPlayer(); + verify(mockProducer).getSurface(); + + // Capture the lifecycle events so we can simulate onSurfaceCreated/Destroyed. + verify(mockProducer).setCallback(callbackCaptor.capture()); + TextureRegistry.SurfaceProducer.Callback producerLifecycle = callbackCaptor.getValue(); + + // Calling onSurfaceCreated does not do anything, since the surface was never destroyed. + simulateSurfaceCreation(producerLifecycle); + verifyNoMoreInteractions(mockProducer); + + videoPlayer.dispose(); } @Test - public void otherErrorsReportVideoErrorWithErrorString() { - List listeners = new LinkedList<>(); - doAnswer(invocation -> listeners.add(invocation.getArgument(0))) - .when(fakeExoPlayer) - .addListener(any()); - - @SuppressWarnings("unused") - VideoPlayer unused = - new VideoPlayer( - fakeExoPlayer, - VideoPlayerEventCallbacks.withSink(fakeEventSink), - fakeSurfaceTextureEntry, - fakeVideoPlayerOptions, - httpDataSourceFactorySpy); - - PlaybackException exception = - new PlaybackException( - "You did bad kid", null, PlaybackException.ERROR_CODE_DECODING_FAILED); - listeners.forEach(listener -> listener.onPlayerError(exception)); - - verify(fakeEventSink).error(eq("VideoError"), contains("You did bad kid"), any()); + public void disposeReleasesExoPlayerBeforeTexture() { + VideoPlayer videoPlayer = createVideoPlayer(); + + videoPlayer.dispose(); + + // Regression test for https://github.com/flutter/flutter/issues/156158. + // The player must be destroyed before the surface it is writing to. + InOrder inOrder = inOrder(mockExoPlayer, mockProducer); + inOrder.verify(mockExoPlayer).release(); + inOrder.verify(mockProducer).release(); + } + + // TODO(matanlurey): Replace with inline calls to onSurfaceAvailable once + // available on stable; see https://github.com/flutter/flutter/issues/155131. + // This separate method only exists to scope the suppression. + @SuppressWarnings({"deprecation", "removal"}) + void simulateSurfaceCreation(TextureRegistry.SurfaceProducer.Callback producerLifecycle) { + producerLifecycle.onSurfaceCreated(); } } diff --git a/packages/video_player/video_player_android/example/android/app/build.gradle b/packages/video_player/video_player_android/example/android/app/build.gradle index 697bde16c079..087b7bd4a243 100644 --- a/packages/video_player/video_player_android/example/android/app/build.gradle +++ b/packages/video_player/video_player_android/example/android/app/build.gradle @@ -29,14 +29,14 @@ android { compileSdk flutter.compileSdkVersion compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } defaultConfig { applicationId "io.flutter.plugins.videoplayerexample" - minSdkVersion 21 - targetSdkVersion 29 + minSdkVersion flutter.minSdkVersion + targetSdkVersion 34 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/packages/video_player/video_player_android/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/video_player/video_player_android/example/android/app/gradle/wrapper/gradle-wrapper.properties index 609ab8e6c8b5..d951fac2bf31 100644 --- a/packages/video_player/video_player_android/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ b/packages/video_player/video_player_android/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/packages/video_player/video_player_android/example/android/app/src/main/AndroidManifest.xml b/packages/video_player/video_player_android/example/android/app/src/main/AndroidManifest.xml index a2574c90d7d9..dd84f58c348e 100644 --- a/packages/video_player/video_player_android/example/android/app/src/main/AndroidManifest.xml +++ b/packages/video_player/video_player_android/example/android/app/src/main/AndroidManifest.xml @@ -7,7 +7,8 @@ android:networkSecurityConfig="@xml/network_security_config"> diff --git a/packages/video_player/video_player_android/example/android/build.gradle b/packages/video_player/video_player_android/example/android/build.gradle index d82420470065..658815b35e23 100644 --- a/packages/video_player/video_player_android/example/android/build.gradle +++ b/packages/video_player/video_player_android/example/android/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath 'com.android.tools.build:gradle:8.5.1' } } diff --git a/packages/video_player/video_player_android/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/video_player/video_player_android/example/android/gradle/wrapper/gradle-wrapper.properties index aeaff6f869f3..7aeeb11c6ee5 100644 --- a/packages/video_player/video_player_android/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/video_player/video_player_android/example/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/video_player/video_player_android/example/integration_test/video_player_test.dart b/packages/video_player/video_player_android/example/integration_test/video_player_test.dart index b1abb5aed21d..f347214b9e79 100644 --- a/packages/video_player/video_player_android/example/integration_test/video_player_test.dart +++ b/packages/video_player/video_player_android/example/integration_test/video_player_test.dart @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:async'; import 'dart:io'; import 'dart:typed_data'; @@ -11,16 +10,9 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:path_provider/path_provider.dart'; import 'package:video_player_android/video_player_android.dart'; -// TODO(stuartmorgan): Remove the use of MiniController in tests, as that is -// testing test code; tests should instead be written directly against the -// platform interface. (These tests were copied from the app-facing package -// during federation and minimally modified, which is why they currently use the -// controller.) -import 'package:video_player_example/mini_controller.dart'; import 'package:video_player_platform_interface/video_player_platform_interface.dart'; const Duration _playDuration = Duration(seconds: 1); - const String _videoAssetKey = 'assets/Butterfly-209.mp4'; // Returns the URL to load an asset from this example app as a network source. @@ -38,132 +30,140 @@ String getUrlForAssetAsNetworkSource(String assetKey) { void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + late AndroidVideoPlayer player; + + setUp(() async { + player = AndroidVideoPlayer(); + await player.init(); + }); - late MiniController controller; - tearDown(() async => controller.dispose()); + testWidgets('registers expected implementation', (_) async { + AndroidVideoPlayer.registerWith(); + expect(VideoPlayerPlatform.instance, isA()); + }); + + testWidgets('initializes at the start', (_) async { + final int textureId = (await player.create(DataSource( + sourceType: DataSourceType.asset, + asset: _videoAssetKey, + )))!; - group('asset videos', () { - setUp(() { - controller = MiniController.asset(_videoAssetKey); - }); + expect( + await _getDuration(player, textureId), + const Duration(seconds: 7, milliseconds: 540), + ); - testWidgets('registers expected implementation', - (WidgetTester tester) async { - AndroidVideoPlayer.registerWith(); - expect(VideoPlayerPlatform.instance, isA()); - }); + await player.dispose(textureId); + }); - testWidgets('can be initialized', (WidgetTester tester) async { - await controller.initialize(); + testWidgets('can be played', (WidgetTester tester) async { + final int textureId = (await player.create(DataSource( + sourceType: DataSourceType.asset, + asset: _videoAssetKey, + )))!; - expect(controller.value.isInitialized, true); - expect(await controller.position, Duration.zero); - expect(controller.value.duration, - const Duration(seconds: 7, milliseconds: 540)); - }); + await player.play(textureId); + await tester.pumpAndSettle(_playDuration); - testWidgets('can be played', (WidgetTester tester) async { - await controller.initialize(); + expect(await player.getPosition(textureId), greaterThan(Duration.zero)); + await player.dispose(textureId); + }); - await controller.play(); - await tester.pumpAndSettle(_playDuration); + testWidgets('can seek', (WidgetTester tester) async { + final int textureId = (await player.create(DataSource( + sourceType: DataSourceType.asset, + asset: _videoAssetKey, + )))!; - expect(await controller.position, greaterThan(Duration.zero)); - }); + await player.seekTo(textureId, const Duration(seconds: 3)); + await tester.pumpAndSettle(_playDuration); - testWidgets('can seek', (WidgetTester tester) async { - await controller.initialize(); + expect( + await player.getPosition(textureId), + greaterThanOrEqualTo(const Duration(seconds: 3)), + ); + await player.dispose(textureId); + }); - await controller.seekTo(const Duration(seconds: 3)); + testWidgets('can pause', (WidgetTester tester) async { + final int textureId = (await player.create(DataSource( + sourceType: DataSourceType.asset, + asset: _videoAssetKey, + )))!; - expect(await controller.position, const Duration(seconds: 3)); - }); + await player.play(textureId); + await tester.pumpAndSettle(_playDuration); - testWidgets('can be paused', (WidgetTester tester) async { - await controller.initialize(); + await player.pause(textureId); + await tester.pumpAndSettle(_playDuration); + final Duration pausedDuration = await player.getPosition(textureId); + await tester.pumpAndSettle(_playDuration); - // Play for a second, then pause, and then wait a second. - await controller.play(); - await tester.pumpAndSettle(_playDuration); - await controller.pause(); - await tester.pumpAndSettle(_playDuration); - final Duration pausedPosition = (await controller.position)!; - await tester.pumpAndSettle(_playDuration); + expect(await player.getPosition(textureId), pausedDuration); + await player.dispose(textureId); + }); - // Verify that we stopped playing after the pause. - expect(await controller.position, pausedPosition); - }); + testWidgets('can play a video from a file', (WidgetTester tester) async { + final Directory directory = await getTemporaryDirectory(); + final File file = File('${directory.path}/video.mp4'); + await file.writeAsBytes( + Uint8List.fromList( + (await rootBundle.load(_videoAssetKey)).buffer.asUint8List(), + ), + ); + + final int textureId = (await player.create(DataSource( + sourceType: DataSourceType.file, + uri: file.path, + )))!; + + await player.play(textureId); + await tester.pumpAndSettle(_playDuration); + + expect(await player.getPosition(textureId), greaterThan(Duration.zero)); + await directory.delete(recursive: true); + await player.dispose(textureId); }); - group('file-based videos', () { - setUp(() async { - // Load the data from the asset. - final String tempDir = (await getTemporaryDirectory()).path; - final ByteData bytes = await rootBundle.load(_videoAssetKey); + testWidgets('can play a video from network', (WidgetTester tester) async { + final int textureId = (await player.create(DataSource( + sourceType: DataSourceType.network, + uri: getUrlForAssetAsNetworkSource(_videoAssetKey), + )))!; - // Write it to a file to use as a source. - final String filename = _videoAssetKey.split('/').last; - final File file = File('$tempDir/$filename'); - await file.writeAsBytes(bytes.buffer.asInt8List()); + await player.play(textureId); + await player.seekTo(textureId, const Duration(seconds: 5)); + await tester.pumpAndSettle(_playDuration); + await player.pause(textureId); - controller = MiniController.file(file); - }); + expect(await player.getPosition(textureId), greaterThan(Duration.zero)); - testWidgets('test video player using static file() method as constructor', - (WidgetTester tester) async { - await controller.initialize(); + final DurationRange range = await _getBufferingRange(player, textureId); + expect(range.start, Duration.zero); + expect(range.end, greaterThan(Duration.zero)); - await controller.play(); - await tester.pumpAndSettle(_playDuration); + await player.dispose(textureId); + }); +} - expect(await controller.position, greaterThan(Duration.zero)); - }); +Future _getDuration( + AndroidVideoPlayer player, + int textureId, +) { + return player.videoEventsFor(textureId).firstWhere((VideoEvent event) { + return event.eventType == VideoEventType.initialized; + }).then((VideoEvent event) { + return event.duration!; }); +} - group('network videos', () { - setUp(() { - final String videoUrl = getUrlForAssetAsNetworkSource(_videoAssetKey); - controller = MiniController.network(videoUrl); - }); - - testWidgets('reports buffering status', (WidgetTester tester) async { - await controller.initialize(); - - final Completer started = Completer(); - final Completer ended = Completer(); - controller.addListener(() { - if (!started.isCompleted && controller.value.isBuffering) { - started.complete(); - } - if (started.isCompleted && - !controller.value.isBuffering && - !ended.isCompleted) { - ended.complete(); - } - }); - - await controller.play(); - await controller.seekTo(const Duration(seconds: 5)); - await tester.pumpAndSettle(_playDuration); - await controller.pause(); - - expect(await controller.position, greaterThan(Duration.zero)); - - await expectLater(started.future, completes); - await expectLater(ended.future, completes); - }); - - testWidgets('live stream duration != 0', (WidgetTester tester) async { - final MiniController livestreamController = MiniController.network( - 'https://flutter.github.io/assets-for-api-docs/assets/videos/hls/bee.m3u8', - ); - await livestreamController.initialize(); - - expect(livestreamController.value.isInitialized, true); - // Live streams should have either a positive duration or C.TIME_UNSET if the duration is unknown - // See https://exoplayer.dev/doc/reference/com/google/android/exoplayer2/Player.html#getDuration-- - expect(livestreamController.value.duration, - (Duration duration) => duration != Duration.zero); - }); +Future _getBufferingRange( + AndroidVideoPlayer player, + int textureId, +) { + return player.videoEventsFor(textureId).firstWhere((VideoEvent event) { + return event.eventType == VideoEventType.bufferingUpdate; + }).then((VideoEvent event) { + return event.buffered!.first; }); } diff --git a/packages/video_player/video_player_android/example/lib/main.dart b/packages/video_player/video_player_android/example/lib/main.dart index df28b39ac76b..79f4963bbfa7 100644 --- a/packages/video_player/video_player_android/example/lib/main.dart +++ b/packages/video_player/video_player_android/example/lib/main.dart @@ -20,7 +20,7 @@ class _App extends StatelessWidget { @override Widget build(BuildContext context) { return DefaultTabController( - length: 2, + length: 3, child: Scaffold( key: const ValueKey('home_page'), appBar: AppBar( @@ -28,10 +28,8 @@ class _App extends StatelessWidget { bottom: const TabBar( isScrollable: true, tabs: [ - Tab( - icon: Icon(Icons.cloud), - text: 'Remote', - ), + Tab(icon: Icon(Icons.cloud), text: 'Remote'), + Tab(icon: Icon(Icons.videocam), text: 'RTSP'), Tab(icon: Icon(Icons.insert_drive_file), text: 'Asset'), ], ), @@ -39,6 +37,7 @@ class _App extends StatelessWidget { body: TabBarView( children: [ _BumbleBeeRemoteVideo(), + _RtspRemoteVideo(), _ButterFlyAssetVideo(), ], ), @@ -63,8 +62,7 @@ class _ButterFlyAssetVideoState extends State<_ButterFlyAssetVideo> { _controller.addListener(() { setState(() {}); }); - _controller.initialize().then((_) => setState(() {})); - _controller.play(); + _controller.initialize().then((_) => _controller.play()); } @override @@ -156,6 +154,90 @@ class _BumbleBeeRemoteVideoState extends State<_BumbleBeeRemoteVideo> { } } +class _RtspRemoteVideo extends StatefulWidget { + @override + _RtspRemoteVideoState createState() => _RtspRemoteVideoState(); +} + +class _RtspRemoteVideoState extends State<_RtspRemoteVideo> { + MiniController? _controller; + + @override + void dispose() { + _controller?.dispose(); + super.dispose(); + } + + Future changeUrl(String url) async { + if (_controller != null) { + await _controller!.dispose(); + } + + setState(() { + _controller = MiniController.network(url); + }); + + _controller!.addListener(() { + setState(() {}); + }); + + return _controller!.initialize(); + } + + String? _validateRtspUrl(String? value) { + if (value == null || !value.startsWith('rtsp://')) { + return 'Enter a valid RTSP URL'; + } + return null; + } + + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + child: Column( + children: [ + Container(padding: const EdgeInsets.only(top: 20.0)), + const Text('With RTSP streaming'), + Padding( + padding: const EdgeInsets.all(20.0), + child: TextFormField( + autovalidateMode: AutovalidateMode.onUserInteraction, + decoration: const InputDecoration(label: Text('RTSP URL')), + validator: _validateRtspUrl, + textInputAction: TextInputAction.done, + onFieldSubmitted: (String value) { + if (_validateRtspUrl(value) == null) { + changeUrl(value); + } else { + setState(() { + _controller?.dispose(); + _controller = null; + }); + } + }, + ), + ), + if (_controller != null) + Container( + padding: const EdgeInsets.all(20), + child: AspectRatio( + aspectRatio: _controller!.value.aspectRatio, + child: Stack( + alignment: Alignment.bottomCenter, + children: [ + VideoPlayer(_controller!), + _ControlsOverlay(controller: _controller!), + VideoProgressIndicator(_controller!), + ], + ), + ), + ), + ], + ), + ); + } +} + class _ControlsOverlay extends StatelessWidget { const _ControlsOverlay({required this.controller}); diff --git a/packages/video_player/video_player_android/example/pubspec.yaml b/packages/video_player/video_player_android/example/pubspec.yaml index a6c57dc8d8bb..01ce43d2c534 100644 --- a/packages/video_player/video_player_android/example/pubspec.yaml +++ b/packages/video_player/video_player_android/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the video_player plugin. publish_to: none environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" dependencies: flutter: diff --git a/packages/video_player/video_player_android/lib/src/android_video_player.dart b/packages/video_player/video_player_android/lib/src/android_video_player.dart index 7d4a600397d4..45665631d932 100644 --- a/packages/video_player/video_player_android/lib/src/android_video_player.dart +++ b/packages/video_player/video_player_android/lib/src/android_video_player.dart @@ -27,7 +27,7 @@ class AndroidVideoPlayer extends VideoPlayerPlatform { @override Future dispose(int textureId) { - return _api.dispose(TextureMessage(textureId: textureId)); + return _api.dispose(textureId); } @override @@ -59,59 +59,45 @@ class AndroidVideoPlayer extends VideoPlayerPlatform { formatHint: formatHint, ); - final TextureMessage response = await _api.create(message); - return response.textureId; + return _api.create(message); } @override Future setLooping(int textureId, bool looping) { - return _api.setLooping(LoopingMessage( - textureId: textureId, - isLooping: looping, - )); + return _api.setLooping(textureId, looping); } @override Future play(int textureId) { - return _api.play(TextureMessage(textureId: textureId)); + return _api.play(textureId); } @override Future pause(int textureId) { - return _api.pause(TextureMessage(textureId: textureId)); + return _api.pause(textureId); } @override Future setVolume(int textureId, double volume) { - return _api.setVolume(VolumeMessage( - textureId: textureId, - volume: volume, - )); + return _api.setVolume(textureId, volume); } @override Future setPlaybackSpeed(int textureId, double speed) { assert(speed > 0); - return _api.setPlaybackSpeed(PlaybackSpeedMessage( - textureId: textureId, - speed: speed, - )); + return _api.setPlaybackSpeed(textureId, speed); } @override Future seekTo(int textureId, Duration position) { - return _api.seekTo(PositionMessage( - textureId: textureId, - position: position.inMilliseconds, - )); + return _api.seekTo(textureId, position.inMilliseconds); } @override Future getPosition(int textureId) async { - final PositionMessage response = - await _api.position(TextureMessage(textureId: textureId)); - return Duration(milliseconds: response.position); + final int position = await _api.position(textureId); + return Duration(milliseconds: position); } @override @@ -162,8 +148,7 @@ class AndroidVideoPlayer extends VideoPlayerPlatform { @override Future setMixWithOthers(bool mixWithOthers) { - return _api - .setMixWithOthers(MixWithOthersMessage(mixWithOthers: mixWithOthers)); + return _api.setMixWithOthers(mixWithOthers); } EventChannel _eventChannelFor(int textureId) { diff --git a/packages/video_player/video_player_android/lib/src/messages.g.dart b/packages/video_player/video_player_android/lib/src/messages.g.dart index 47ed6a295c83..e3190b389e4e 100644 --- a/packages/video_player/video_player_android/lib/src/messages.g.dart +++ b/packages/video_player/video_player_android/lib/src/messages.g.dart @@ -1,9 +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 (v9.2.5), do not edit directly. +// Autogenerated from Pigeon (v22.5.0), 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 +// 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 import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; @@ -11,129 +11,22 @@ import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; import 'package:flutter/services.dart'; -class TextureMessage { - TextureMessage({ - required this.textureId, - }); - - int textureId; - - Object encode() { - return [ - textureId, - ]; - } - - static TextureMessage decode(Object result) { - result as List; - return TextureMessage( - textureId: result[0]! as int, - ); - } -} - -class LoopingMessage { - LoopingMessage({ - required this.textureId, - required this.isLooping, - }); - - int textureId; - - bool isLooping; - - Object encode() { - return [ - textureId, - isLooping, - ]; - } - - static LoopingMessage decode(Object result) { - result as List; - return LoopingMessage( - textureId: result[0]! as int, - isLooping: result[1]! as bool, - ); - } +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); } -class VolumeMessage { - VolumeMessage({ - required this.textureId, - required this.volume, - }); - - int textureId; - - double volume; - - Object encode() { - return [ - textureId, - volume, - ]; - } - - static VolumeMessage decode(Object result) { - result as List; - return VolumeMessage( - textureId: result[0]! as int, - volume: result[1]! as double, - ); - } -} - -class PlaybackSpeedMessage { - PlaybackSpeedMessage({ - required this.textureId, - required this.speed, - }); - - int textureId; - - double speed; - - Object encode() { - return [ - textureId, - speed, - ]; - } - - static PlaybackSpeedMessage decode(Object result) { - result as List; - return PlaybackSpeedMessage( - textureId: result[0]! as int, - speed: result[1]! as double, - ); - } -} - -class PositionMessage { - PositionMessage({ - required this.textureId, - required this.position, - }); - - int textureId; - - int position; - - Object encode() { - return [ - textureId, - position, - ]; +List wrapResponse( + {Object? result, PlatformException? error, bool empty = false}) { + if (empty) { + return []; } - - static PositionMessage decode(Object result) { - result as List; - return PositionMessage( - textureId: result[0]! as int, - position: result[1]! as int, - ); + if (error == null) { + return [result]; } + return [error.code, error.message, error.details]; } class CreateMessage { @@ -153,7 +46,7 @@ class CreateMessage { String? formatHint; - Map httpHeaders; + Map httpHeaders; Object encode() { return [ @@ -173,57 +66,21 @@ class CreateMessage { packageName: result[2] as String?, formatHint: result[3] as String?, httpHeaders: - (result[4] as Map?)!.cast(), - ); - } -} - -class MixWithOthersMessage { - MixWithOthersMessage({ - required this.mixWithOthers, - }); - - bool mixWithOthers; - - Object encode() { - return [ - mixWithOthers, - ]; - } - - static MixWithOthersMessage decode(Object result) { - result as List; - return MixWithOthersMessage( - mixWithOthers: result[0]! as bool, + (result[4] as Map?)!.cast(), ); } } -class _AndroidVideoPlayerApiCodec extends StandardMessageCodec { - const _AndroidVideoPlayerApiCodec(); +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is CreateMessage) { - buffer.putUint8(128); - writeValue(buffer, value.encode()); - } else if (value is LoopingMessage) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is CreateMessage) { buffer.putUint8(129); writeValue(buffer, value.encode()); - } else if (value is MixWithOthersMessage) { - buffer.putUint8(130); - writeValue(buffer, value.encode()); - } else if (value is PlaybackSpeedMessage) { - buffer.putUint8(131); - writeValue(buffer, value.encode()); - } else if (value is PositionMessage) { - buffer.putUint8(132); - writeValue(buffer, value.encode()); - } else if (value is TextureMessage) { - buffer.putUint8(133); - writeValue(buffer, value.encode()); - } else if (value is VolumeMessage) { - buffer.putUint8(134); - writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -232,20 +89,8 @@ class _AndroidVideoPlayerApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: - return CreateMessage.decode(readValue(buffer)!); case 129: - return LoopingMessage.decode(readValue(buffer)!); - case 130: - return MixWithOthersMessage.decode(readValue(buffer)!); - case 131: - return PlaybackSpeedMessage.decode(readValue(buffer)!); - case 132: - return PositionMessage.decode(readValue(buffer)!); - case 133: - return TextureMessage.decode(readValue(buffer)!); - case 134: - return VolumeMessage.decode(readValue(buffer)!); + return CreateMessage.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -256,257 +101,285 @@ class AndroidVideoPlayerApi { /// Constructor for [AndroidVideoPlayerApi]. 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. - AndroidVideoPlayerApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; + AndroidVideoPlayerApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; - static const MessageCodec codec = _AndroidVideoPlayerApiCodec(); + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String pigeonVar_messageChannelSuffix; Future initialize() async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.AndroidVideoPlayerApi.initialize', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send(null) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.initialize$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; } } - Future create(CreateMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.AndroidVideoPlayerApi.create', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future create(CreateMessage msg) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.create$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([msg]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 (replyList[0] as TextureMessage?)!; + return (pigeonVar_replyList[0] as int?)!; } } - Future dispose(TextureMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.AndroidVideoPlayerApi.dispose', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future dispose(int textureId) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.dispose$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([textureId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; } } - Future setLooping(LoopingMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.AndroidVideoPlayerApi.setLooping', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future setLooping(int textureId, bool looping) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.setLooping$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([textureId, looping]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; } } - Future setVolume(VolumeMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.AndroidVideoPlayerApi.setVolume', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future setVolume(int textureId, double volume) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.setVolume$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([textureId, volume]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; } } - Future setPlaybackSpeed(PlaybackSpeedMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.AndroidVideoPlayerApi.setPlaybackSpeed', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future setPlaybackSpeed(int textureId, double speed) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.setPlaybackSpeed$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([textureId, speed]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; } } - Future play(TextureMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.AndroidVideoPlayerApi.play', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future play(int textureId) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.play$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([textureId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; } } - Future position(TextureMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.AndroidVideoPlayerApi.position', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future position(int textureId) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.position$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([textureId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (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 (replyList[0] as PositionMessage?)!; + return (pigeonVar_replyList[0] as int?)!; } } - Future seekTo(PositionMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.AndroidVideoPlayerApi.seekTo', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future seekTo(int textureId, int position) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.seekTo$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([textureId, position]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; } } - Future pause(TextureMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.AndroidVideoPlayerApi.pause', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future pause(int textureId) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.pause$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([textureId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; } } - Future setMixWithOthers(MixWithOthersMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.AndroidVideoPlayerApi.setMixWithOthers', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future setMixWithOthers(bool mixWithOthers) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.setMixWithOthers$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([mixWithOthers]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; diff --git a/packages/video_player/video_player_android/pigeons/messages.dart b/packages/video_player/video_player_android/pigeons/messages.dart index 90c9fbb61ea0..37bde3dcda5f 100644 --- a/packages/video_player/video_player_android/pigeons/messages.dart +++ b/packages/video_player/video_player_android/pigeons/messages.dart @@ -13,60 +13,26 @@ import 'package:pigeon/pigeon.dart'; ), copyrightHeader: 'pigeons/copyright.txt', )) -class TextureMessage { - TextureMessage(this.textureId); - int textureId; -} - -class LoopingMessage { - LoopingMessage(this.textureId, this.isLooping); - int textureId; - bool isLooping; -} - -class VolumeMessage { - VolumeMessage(this.textureId, this.volume); - int textureId; - double volume; -} - -class PlaybackSpeedMessage { - PlaybackSpeedMessage(this.textureId, this.speed); - int textureId; - double speed; -} - -class PositionMessage { - PositionMessage(this.textureId, this.position); - int textureId; - int position; -} - class CreateMessage { CreateMessage({required this.httpHeaders}); String? asset; String? uri; String? packageName; String? formatHint; - Map httpHeaders; -} - -class MixWithOthersMessage { - MixWithOthersMessage(this.mixWithOthers); - bool mixWithOthers; + Map httpHeaders; } @HostApi(dartHostTestHandler: 'TestHostVideoPlayerApi') abstract class AndroidVideoPlayerApi { void initialize(); - TextureMessage create(CreateMessage msg); - void dispose(TextureMessage msg); - void setLooping(LoopingMessage msg); - void setVolume(VolumeMessage msg); - void setPlaybackSpeed(PlaybackSpeedMessage msg); - void play(TextureMessage msg); - PositionMessage position(TextureMessage msg); - void seekTo(PositionMessage msg); - void pause(TextureMessage msg); - void setMixWithOthers(MixWithOthersMessage msg); + int create(CreateMessage msg); + void dispose(int textureId); + void setLooping(int textureId, bool looping); + void setVolume(int textureId, double volume); + void setPlaybackSpeed(int textureId, double speed); + void play(int textureId); + int position(int textureId); + void seekTo(int textureId, int position); + void pause(int textureId); + void setMixWithOthers(bool mixWithOthers); } diff --git a/packages/video_player/video_player_android/pubspec.yaml b/packages/video_player/video_player_android/pubspec.yaml index 2d234734d713..ababc4aca4ea 100644 --- a/packages/video_player/video_player_android/pubspec.yaml +++ b/packages/video_player/video_player_android/pubspec.yaml @@ -2,11 +2,11 @@ name: video_player_android description: Android implementation of the video_player plugin. repository: https://github.com/flutter/packages/tree/main/packages/video_player/video_player_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22 -version: 2.5.1 +version: 2.7.16 environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" flutter: plugin: @@ -25,7 +25,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - pigeon: ^9.2.5 + pigeon: ^22.4.2 topics: - video diff --git a/packages/video_player/video_player_android/test/android_video_player_test.dart b/packages/video_player/video_player_android/test/android_video_player_test.dart index 4ea1d4821001..2c99cb934d02 100644 --- a/packages/video_player/video_player_android/test/android_video_player_test.dart +++ b/packages/video_player/video_player_android/test/android_video_player_test.dart @@ -12,25 +12,25 @@ import 'test_api.g.dart'; class _ApiLogger implements TestHostVideoPlayerApi { final List log = []; - TextureMessage? textureMessage; - CreateMessage? createMessage; - PositionMessage? positionMessage; - LoopingMessage? loopingMessage; - VolumeMessage? volumeMessage; - PlaybackSpeedMessage? playbackSpeedMessage; - MixWithOthersMessage? mixWithOthersMessage; + int? passedTextureId; + CreateMessage? passedCreateMessage; + int? passedPosition; + bool? passedLooping; + double? passedVolume; + double? passedPlaybackSpeed; + bool? passedMixWithOthers; @override - TextureMessage create(CreateMessage arg) { + int create(CreateMessage arg) { log.add('create'); - createMessage = arg; - return TextureMessage(textureId: 3); + passedCreateMessage = arg; + return 3; } @override - void dispose(TextureMessage arg) { + void dispose(int textureId) { log.add('dispose'); - textureMessage = arg; + passedTextureId = textureId; } @override @@ -39,52 +39,56 @@ class _ApiLogger implements TestHostVideoPlayerApi { } @override - void pause(TextureMessage arg) { + void pause(int textureId) { log.add('pause'); - textureMessage = arg; + passedTextureId = textureId; } @override - void play(TextureMessage arg) { + void play(int textureId) { log.add('play'); - textureMessage = arg; + passedTextureId = textureId; } @override - void setMixWithOthers(MixWithOthersMessage arg) { + void setMixWithOthers(bool mixWithOthers) { log.add('setMixWithOthers'); - mixWithOthersMessage = arg; + passedMixWithOthers = mixWithOthers; } @override - PositionMessage position(TextureMessage arg) { + int position(int textureId) { log.add('position'); - textureMessage = arg; - return PositionMessage(textureId: arg.textureId, position: 234); + passedTextureId = textureId; + return 234; } @override - void seekTo(PositionMessage arg) { + void seekTo(int textureId, int position) { log.add('seekTo'); - positionMessage = arg; + passedTextureId = textureId; + passedPosition = position; } @override - void setLooping(LoopingMessage arg) { + void setLooping(int textureId, bool looping) { log.add('setLooping'); - loopingMessage = arg; + passedTextureId = textureId; + passedLooping = looping; } @override - void setVolume(VolumeMessage arg) { + void setVolume(int textureId, double volume) { log.add('setVolume'); - volumeMessage = arg; + passedTextureId = textureId; + passedVolume = volume; } @override - void setPlaybackSpeed(PlaybackSpeedMessage arg) { + void setPlaybackSpeed(int textureId, double speed) { log.add('setPlaybackSpeed'); - playbackSpeedMessage = arg; + passedTextureId = textureId; + passedPlaybackSpeed = speed; } } @@ -102,7 +106,7 @@ void main() { setUp(() { log = _ApiLogger(); - TestHostVideoPlayerApi.setup(log); + TestHostVideoPlayerApi.setUp(log); }); test('init', () async { @@ -116,7 +120,7 @@ void main() { test('dispose', () async { await player.dispose(1); expect(log.log.last, 'dispose'); - expect(log.textureMessage?.textureId, 1); + expect(log.passedTextureId, 1); }); test('create with asset', () async { @@ -126,8 +130,8 @@ void main() { package: 'somePackage', )); expect(log.log.last, 'create'); - expect(log.createMessage?.asset, 'someAsset'); - expect(log.createMessage?.packageName, 'somePackage'); + expect(log.passedCreateMessage?.asset, 'someAsset'); + expect(log.passedCreateMessage?.packageName, 'somePackage'); expect(textureId, 3); }); @@ -138,11 +142,11 @@ void main() { formatHint: VideoFormat.dash, )); expect(log.log.last, 'create'); - expect(log.createMessage?.asset, null); - expect(log.createMessage?.uri, 'someUri'); - expect(log.createMessage?.packageName, null); - expect(log.createMessage?.formatHint, 'dash'); - expect(log.createMessage?.httpHeaders, {}); + expect(log.passedCreateMessage?.asset, null); + expect(log.passedCreateMessage?.uri, 'someUri'); + expect(log.passedCreateMessage?.packageName, null); + expect(log.passedCreateMessage?.formatHint, 'dash'); + expect(log.passedCreateMessage?.httpHeaders, {}); expect(textureId, 3); }); @@ -153,11 +157,11 @@ void main() { httpHeaders: {'Authorization': 'Bearer token'}, )); expect(log.log.last, 'create'); - expect(log.createMessage?.asset, null); - expect(log.createMessage?.uri, 'someUri'); - expect(log.createMessage?.packageName, null); - expect(log.createMessage?.formatHint, null); - expect(log.createMessage?.httpHeaders, + expect(log.passedCreateMessage?.asset, null); + expect(log.passedCreateMessage?.uri, 'someUri'); + expect(log.passedCreateMessage?.packageName, null); + expect(log.passedCreateMessage?.formatHint, null); + expect(log.passedCreateMessage?.httpHeaders, {'Authorization': 'Bearer token'}); expect(textureId, 3); }); @@ -168,7 +172,7 @@ void main() { uri: 'someUri', )); expect(log.log.last, 'create'); - expect(log.createMessage?.uri, 'someUri'); + expect(log.passedCreateMessage?.uri, 'someUri'); expect(textureId, 3); }); @@ -179,65 +183,65 @@ void main() { httpHeaders: {'Authorization': 'Bearer token'}, )); expect(log.log.last, 'create'); - expect(log.createMessage?.uri, 'someUri'); - expect(log.createMessage?.httpHeaders, + expect(log.passedCreateMessage?.uri, 'someUri'); + expect(log.passedCreateMessage?.httpHeaders, {'Authorization': 'Bearer token'}); expect(textureId, 3); }); test('setLooping', () async { await player.setLooping(1, true); expect(log.log.last, 'setLooping'); - expect(log.loopingMessage?.textureId, 1); - expect(log.loopingMessage?.isLooping, true); + expect(log.passedTextureId, 1); + expect(log.passedLooping, true); }); test('play', () async { await player.play(1); expect(log.log.last, 'play'); - expect(log.textureMessage?.textureId, 1); + expect(log.passedTextureId, 1); }); test('pause', () async { await player.pause(1); expect(log.log.last, 'pause'); - expect(log.textureMessage?.textureId, 1); + expect(log.passedTextureId, 1); }); test('setMixWithOthers', () async { await player.setMixWithOthers(true); expect(log.log.last, 'setMixWithOthers'); - expect(log.mixWithOthersMessage?.mixWithOthers, true); + expect(log.passedMixWithOthers, true); await player.setMixWithOthers(false); expect(log.log.last, 'setMixWithOthers'); - expect(log.mixWithOthersMessage?.mixWithOthers, false); + expect(log.passedMixWithOthers, false); }); test('setVolume', () async { await player.setVolume(1, 0.7); expect(log.log.last, 'setVolume'); - expect(log.volumeMessage?.textureId, 1); - expect(log.volumeMessage?.volume, 0.7); + expect(log.passedTextureId, 1); + expect(log.passedVolume, 0.7); }); test('setPlaybackSpeed', () async { await player.setPlaybackSpeed(1, 1.5); expect(log.log.last, 'setPlaybackSpeed'); - expect(log.playbackSpeedMessage?.textureId, 1); - expect(log.playbackSpeedMessage?.speed, 1.5); + expect(log.passedTextureId, 1); + expect(log.passedPlaybackSpeed, 1.5); }); test('seekTo', () async { await player.seekTo(1, const Duration(milliseconds: 12345)); expect(log.log.last, 'seekTo'); - expect(log.positionMessage?.textureId, 1); - expect(log.positionMessage?.position, 12345); + expect(log.passedTextureId, 1); + expect(log.passedPosition, 12345); }); test('getPosition', () async { final Duration position = await player.getPosition(1); expect(log.log.last, 'position'); - expect(log.textureMessage?.textureId, 1); + expect(log.passedTextureId, 1); expect(position, const Duration(milliseconds: 234)); }); diff --git a/packages/video_player/video_player_android/test/test_api.g.dart b/packages/video_player/video_player_android/test/test_api.g.dart index bb68e71c2fb8..838dcfbc5a21 100644 --- a/packages/video_player/video_player_android/test/test_api.g.dart +++ b/packages/video_player/video_player_android/test/test_api.g.dart @@ -1,9 +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 (v9.2.5), do not edit directly. +// Autogenerated from Pigeon (v22.5.0), 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, unnecessary_import +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import, no_leading_underscores_for_local_identifiers // ignore_for_file: avoid_relative_lib_imports import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; @@ -13,31 +13,16 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:video_player_android/src/messages.g.dart'; -class _TestHostVideoPlayerApiCodec extends StandardMessageCodec { - const _TestHostVideoPlayerApiCodec(); +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is CreateMessage) { - buffer.putUint8(128); - writeValue(buffer, value.encode()); - } else if (value is LoopingMessage) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is CreateMessage) { buffer.putUint8(129); writeValue(buffer, value.encode()); - } else if (value is MixWithOthersMessage) { - buffer.putUint8(130); - writeValue(buffer, value.encode()); - } else if (value is PlaybackSpeedMessage) { - buffer.putUint8(131); - writeValue(buffer, value.encode()); - } else if (value is PositionMessage) { - buffer.putUint8(132); - writeValue(buffer, value.encode()); - } else if (value is TextureMessage) { - buffer.putUint8(133); - writeValue(buffer, value.encode()); - } else if (value is VolumeMessage) { - buffer.putUint8(134); - writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -46,20 +31,8 @@ class _TestHostVideoPlayerApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: - return CreateMessage.decode(readValue(buffer)!); case 129: - return LoopingMessage.decode(readValue(buffer)!); - case 130: - return MixWithOthersMessage.decode(readValue(buffer)!); - case 131: - return PlaybackSpeedMessage.decode(readValue(buffer)!); - case 132: - return PositionMessage.decode(readValue(buffer)!); - case 133: - return TextureMessage.decode(readValue(buffer)!); - case 134: - return VolumeMessage.decode(readValue(buffer)!); + return CreateMessage.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -69,268 +42,392 @@ class _TestHostVideoPlayerApiCodec extends StandardMessageCodec { abstract class TestHostVideoPlayerApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec codec = _TestHostVideoPlayerApiCodec(); + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); void initialize(); - TextureMessage create(CreateMessage msg); + int create(CreateMessage msg); - void dispose(TextureMessage msg); + void dispose(int textureId); - void setLooping(LoopingMessage msg); + void setLooping(int textureId, bool looping); - void setVolume(VolumeMessage msg); + void setVolume(int textureId, double volume); - void setPlaybackSpeed(PlaybackSpeedMessage msg); + void setPlaybackSpeed(int textureId, double speed); - void play(TextureMessage msg); + void play(int textureId); - PositionMessage position(TextureMessage msg); + int position(int textureId); - void seekTo(PositionMessage msg); + void seekTo(int textureId, int position); - void pause(TextureMessage msg); + void pause(int textureId); - void setMixWithOthers(MixWithOthersMessage msg); + void setMixWithOthers(bool mixWithOthers); - static void setup(TestHostVideoPlayerApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + TestHostVideoPlayerApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.AndroidVideoPlayerApi.initialize', codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.initialize$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { - // ignore message - api.initialize(); - return []; + try { + api.initialize(); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.AndroidVideoPlayerApi.create', codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.create$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.AndroidVideoPlayerApi.create was null.'); + 'Argument for dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.create was null.'); final List args = (message as List?)!; final CreateMessage? arg_msg = (args[0] as CreateMessage?); assert(arg_msg != null, - 'Argument for dev.flutter.pigeon.AndroidVideoPlayerApi.create was null, expected non-null CreateMessage.'); - final TextureMessage output = api.create(arg_msg!); - return [output]; + 'Argument for dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.create was null, expected non-null CreateMessage.'); + try { + final int output = api.create(arg_msg!); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.AndroidVideoPlayerApi.dispose', codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.dispose$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.AndroidVideoPlayerApi.dispose was null.'); + 'Argument for dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.dispose was null.'); final List args = (message as List?)!; - final TextureMessage? arg_msg = (args[0] as TextureMessage?); - assert(arg_msg != null, - 'Argument for dev.flutter.pigeon.AndroidVideoPlayerApi.dispose was null, expected non-null TextureMessage.'); - api.dispose(arg_msg!); - return []; + final int? arg_textureId = (args[0] as int?); + assert(arg_textureId != null, + 'Argument for dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.dispose was null, expected non-null int.'); + try { + api.dispose(arg_textureId!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.AndroidVideoPlayerApi.setLooping', codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.setLooping$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.AndroidVideoPlayerApi.setLooping was null.'); + 'Argument for dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.setLooping was null.'); final List args = (message as List?)!; - final LoopingMessage? arg_msg = (args[0] as LoopingMessage?); - assert(arg_msg != null, - 'Argument for dev.flutter.pigeon.AndroidVideoPlayerApi.setLooping was null, expected non-null LoopingMessage.'); - api.setLooping(arg_msg!); - return []; + final int? arg_textureId = (args[0] as int?); + assert(arg_textureId != null, + 'Argument for dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.setLooping was null, expected non-null int.'); + final bool? arg_looping = (args[1] as bool?); + assert(arg_looping != null, + 'Argument for dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.setLooping was null, expected non-null bool.'); + try { + api.setLooping(arg_textureId!, arg_looping!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.AndroidVideoPlayerApi.setVolume', codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.setVolume$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.AndroidVideoPlayerApi.setVolume was null.'); + 'Argument for dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.setVolume was null.'); final List args = (message as List?)!; - final VolumeMessage? arg_msg = (args[0] as VolumeMessage?); - assert(arg_msg != null, - 'Argument for dev.flutter.pigeon.AndroidVideoPlayerApi.setVolume was null, expected non-null VolumeMessage.'); - api.setVolume(arg_msg!); - return []; + final int? arg_textureId = (args[0] as int?); + assert(arg_textureId != null, + 'Argument for dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.setVolume was null, expected non-null int.'); + final double? arg_volume = (args[1] as double?); + assert(arg_volume != null, + 'Argument for dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.setVolume was null, expected non-null double.'); + try { + api.setVolume(arg_textureId!, arg_volume!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.AndroidVideoPlayerApi.setPlaybackSpeed', codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.setPlaybackSpeed$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.AndroidVideoPlayerApi.setPlaybackSpeed was null.'); + 'Argument for dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.setPlaybackSpeed was null.'); final List args = (message as List?)!; - final PlaybackSpeedMessage? arg_msg = - (args[0] as PlaybackSpeedMessage?); - assert(arg_msg != null, - 'Argument for dev.flutter.pigeon.AndroidVideoPlayerApi.setPlaybackSpeed was null, expected non-null PlaybackSpeedMessage.'); - api.setPlaybackSpeed(arg_msg!); - return []; + final int? arg_textureId = (args[0] as int?); + assert(arg_textureId != null, + 'Argument for dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.setPlaybackSpeed was null, expected non-null int.'); + final double? arg_speed = (args[1] as double?); + assert(arg_speed != null, + 'Argument for dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.setPlaybackSpeed was null, expected non-null double.'); + try { + api.setPlaybackSpeed(arg_textureId!, arg_speed!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.AndroidVideoPlayerApi.play', codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.play$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.AndroidVideoPlayerApi.play was null.'); + 'Argument for dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.play was null.'); final List args = (message as List?)!; - final TextureMessage? arg_msg = (args[0] as TextureMessage?); - assert(arg_msg != null, - 'Argument for dev.flutter.pigeon.AndroidVideoPlayerApi.play was null, expected non-null TextureMessage.'); - api.play(arg_msg!); - return []; + final int? arg_textureId = (args[0] as int?); + assert(arg_textureId != null, + 'Argument for dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.play was null, expected non-null int.'); + try { + api.play(arg_textureId!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.AndroidVideoPlayerApi.position', codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.position$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.AndroidVideoPlayerApi.position was null.'); + 'Argument for dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.position was null.'); final List args = (message as List?)!; - final TextureMessage? arg_msg = (args[0] as TextureMessage?); - assert(arg_msg != null, - 'Argument for dev.flutter.pigeon.AndroidVideoPlayerApi.position was null, expected non-null TextureMessage.'); - final PositionMessage output = api.position(arg_msg!); - return [output]; + final int? arg_textureId = (args[0] as int?); + assert(arg_textureId != null, + 'Argument for dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.position was null, expected non-null int.'); + try { + final int output = api.position(arg_textureId!); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.AndroidVideoPlayerApi.seekTo', codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.seekTo$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.AndroidVideoPlayerApi.seekTo was null.'); + 'Argument for dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.seekTo was null.'); final List args = (message as List?)!; - final PositionMessage? arg_msg = (args[0] as PositionMessage?); - assert(arg_msg != null, - 'Argument for dev.flutter.pigeon.AndroidVideoPlayerApi.seekTo was null, expected non-null PositionMessage.'); - api.seekTo(arg_msg!); - return []; + final int? arg_textureId = (args[0] as int?); + assert(arg_textureId != null, + 'Argument for dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.seekTo was null, expected non-null int.'); + final int? arg_position = (args[1] as int?); + assert(arg_position != null, + 'Argument for dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.seekTo was null, expected non-null int.'); + try { + api.seekTo(arg_textureId!, arg_position!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.AndroidVideoPlayerApi.pause', codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.pause$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.AndroidVideoPlayerApi.pause was null.'); + 'Argument for dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.pause was null.'); final List args = (message as List?)!; - final TextureMessage? arg_msg = (args[0] as TextureMessage?); - assert(arg_msg != null, - 'Argument for dev.flutter.pigeon.AndroidVideoPlayerApi.pause was null, expected non-null TextureMessage.'); - api.pause(arg_msg!); - return []; + final int? arg_textureId = (args[0] as int?); + assert(arg_textureId != null, + 'Argument for dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.pause was null, expected non-null int.'); + try { + api.pause(arg_textureId!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.AndroidVideoPlayerApi.setMixWithOthers', codec, + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.setMixWithOthers$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.AndroidVideoPlayerApi.setMixWithOthers was null.'); + 'Argument for dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.setMixWithOthers was null.'); final List args = (message as List?)!; - final MixWithOthersMessage? arg_msg = - (args[0] as MixWithOthersMessage?); - assert(arg_msg != null, - 'Argument for dev.flutter.pigeon.AndroidVideoPlayerApi.setMixWithOthers was null, expected non-null MixWithOthersMessage.'); - api.setMixWithOthers(arg_msg!); - return []; + final bool? arg_mixWithOthers = (args[0] as bool?); + assert(arg_mixWithOthers != null, + 'Argument for dev.flutter.pigeon.video_player_android.AndroidVideoPlayerApi.setMixWithOthers was null, expected non-null bool.'); + try { + api.setMixWithOthers(arg_mixWithOthers!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } }); } } diff --git a/packages/video_player/video_player_avfoundation/CHANGELOG.md b/packages/video_player/video_player_avfoundation/CHANGELOG.md index 4ea05f7f1a9e..84579777521a 100644 --- a/packages/video_player/video_player_avfoundation/CHANGELOG.md +++ b/packages/video_player/video_player_avfoundation/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.6.2 + +* Updates Pigeon for non-nullable collection type support. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. + ## 2.6.1 * Adds files to make include directory permanent. diff --git a/packages/video_player/video_player_avfoundation/README.md b/packages/video_player/video_player_avfoundation/README.md index 0e20e3a8c3ad..1325daf0acfa 100644 --- a/packages/video_player/video_player_avfoundation/README.md +++ b/packages/video_player/video_player_avfoundation/README.md @@ -12,4 +12,4 @@ However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/video_player -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/messages.g.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/messages.g.h index 368c4893c662..afb118f14cd0 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/messages.g.h +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/messages.g.h @@ -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 (v18.0.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.2), do not edit directly. // See also: https://pub.dev/packages/pigeon #import @@ -30,8 +30,8 @@ NS_ASSUME_NONNULL_BEGIN @property(nonatomic, copy) NSDictionary *httpHeaders; @end -/// The codec used by FVPAVFoundationVideoPlayerApi. -NSObject *FVPAVFoundationVideoPlayerApiGetCodec(void); +/// The codec used by all APIs. +NSObject *FVPGetMessagesCodec(void); @protocol FVPAVFoundationVideoPlayerApi - (void)initialize:(FlutterError *_Nullable *_Nonnull)error; diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/messages.g.m b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/messages.g.m index 1e2354d88289..9749b125a9ee 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/messages.g.m +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/messages.g.m @@ -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 (v18.0.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.2), do not edit directly. // See also: https://pub.dev/packages/pigeon #import "./include/video_player_avfoundation/messages.g.h" @@ -16,7 +16,7 @@ #error File requires ARC to be enabled. #endif -static NSArray *wrapResult(id result, FlutterError *error) { +static NSArray *wrapResult(id result, FlutterError *error) { if (error) { return @[ error.code ?: [NSNull null], error.message ?: [NSNull null], error.details ?: [NSNull null] @@ -25,15 +25,15 @@ return @[ result ?: [NSNull null] ]; } -static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) { +static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) { id result = array[key]; return (result == [NSNull null]) ? nil : result; } @interface FVPCreationOptions () -+ (FVPCreationOptions *)fromList:(NSArray *)list; -+ (nullable FVPCreationOptions *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; ++ (FVPCreationOptions *)fromList:(NSArray *)list; ++ (nullable FVPCreationOptions *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; @end @implementation FVPCreationOptions @@ -50,7 +50,7 @@ + (instancetype)makeWithAsset:(nullable NSString *)asset pigeonResult.httpHeaders = httpHeaders; return pigeonResult; } -+ (FVPCreationOptions *)fromList:(NSArray *)list { ++ (FVPCreationOptions *)fromList:(NSArray *)list { FVPCreationOptions *pigeonResult = [[FVPCreationOptions alloc] init]; pigeonResult.asset = GetNullableObjectAtIndex(list, 0); pigeonResult.uri = GetNullableObjectAtIndex(list, 1); @@ -59,10 +59,10 @@ + (FVPCreationOptions *)fromList:(NSArray *)list { pigeonResult.httpHeaders = GetNullableObjectAtIndex(list, 4); return pigeonResult; } -+ (nullable FVPCreationOptions *)nullableFromList:(NSArray *)list { ++ (nullable FVPCreationOptions *)nullableFromList:(NSArray *)list { return (list) ? [FVPCreationOptions fromList:list] : nil; } -- (NSArray *)toList { +- (NSArray *)toList { return @[ self.asset ?: [NSNull null], self.uri ?: [NSNull null], @@ -73,12 +73,12 @@ - (NSArray *)toList { } @end -@interface FVPAVFoundationVideoPlayerApiCodecReader : FlutterStandardReader +@interface FVPMessagesPigeonCodecReader : FlutterStandardReader @end -@implementation FVPAVFoundationVideoPlayerApiCodecReader +@implementation FVPMessagesPigeonCodecReader - (nullable id)readValueOfType:(UInt8)type { switch (type) { - case 128: + case 129: return [FVPCreationOptions fromList:[self readValue]]; default: return [super readValueOfType:type]; @@ -86,12 +86,12 @@ - (nullable id)readValueOfType:(UInt8)type { } @end -@interface FVPAVFoundationVideoPlayerApiCodecWriter : FlutterStandardWriter +@interface FVPMessagesPigeonCodecWriter : FlutterStandardWriter @end -@implementation FVPAVFoundationVideoPlayerApiCodecWriter +@implementation FVPMessagesPigeonCodecWriter - (void)writeValue:(id)value { if ([value isKindOfClass:[FVPCreationOptions class]]) { - [self writeByte:128]; + [self writeByte:129]; [self writeValue:[value toList]]; } else { [super writeValue:value]; @@ -99,28 +99,27 @@ - (void)writeValue:(id)value { } @end -@interface FVPAVFoundationVideoPlayerApiCodecReaderWriter : FlutterStandardReaderWriter +@interface FVPMessagesPigeonCodecReaderWriter : FlutterStandardReaderWriter @end -@implementation FVPAVFoundationVideoPlayerApiCodecReaderWriter +@implementation FVPMessagesPigeonCodecReaderWriter - (FlutterStandardWriter *)writerWithData:(NSMutableData *)data { - return [[FVPAVFoundationVideoPlayerApiCodecWriter alloc] initWithData:data]; + return [[FVPMessagesPigeonCodecWriter alloc] initWithData:data]; } - (FlutterStandardReader *)readerWithData:(NSData *)data { - return [[FVPAVFoundationVideoPlayerApiCodecReader alloc] initWithData:data]; + return [[FVPMessagesPigeonCodecReader alloc] initWithData:data]; } @end -NSObject *FVPAVFoundationVideoPlayerApiGetCodec(void) { +NSObject *FVPGetMessagesCodec(void) { static FlutterStandardMessageCodec *sSharedObject = nil; static dispatch_once_t sPred = 0; dispatch_once(&sPred, ^{ - FVPAVFoundationVideoPlayerApiCodecReaderWriter *readerWriter = - [[FVPAVFoundationVideoPlayerApiCodecReaderWriter alloc] init]; + FVPMessagesPigeonCodecReaderWriter *readerWriter = + [[FVPMessagesPigeonCodecReaderWriter alloc] init]; sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter]; }); return sSharedObject; } - void SetUpFVPAVFoundationVideoPlayerApi(id binaryMessenger, NSObject *api) { SetUpFVPAVFoundationVideoPlayerApiWithSuffix(binaryMessenger, api, @""); @@ -139,7 +138,7 @@ void SetUpFVPAVFoundationVideoPlayerApiWithSuffix(id bin @"AVFoundationVideoPlayerApi.initialize", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FVPAVFoundationVideoPlayerApiGetCodec()]; + codec:FVPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(initialize:)], @"FVPAVFoundationVideoPlayerApi api (%@) doesn't respond to @selector(initialize:)", @@ -160,14 +159,14 @@ void SetUpFVPAVFoundationVideoPlayerApiWithSuffix(id bin @"AVFoundationVideoPlayerApi.create", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FVPAVFoundationVideoPlayerApiGetCodec()]; + codec:FVPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(createWithOptions:error:)], @"FVPAVFoundationVideoPlayerApi api (%@) doesn't respond to " @"@selector(createWithOptions:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; FVPCreationOptions *arg_creationOptions = GetNullableObjectAtIndex(args, 0); FlutterError *error; NSNumber *output = [api createWithOptions:arg_creationOptions error:&error]; @@ -184,14 +183,14 @@ void SetUpFVPAVFoundationVideoPlayerApiWithSuffix(id bin @"AVFoundationVideoPlayerApi.dispose", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FVPAVFoundationVideoPlayerApiGetCodec()]; + codec:FVPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(disposePlayer:error:)], @"FVPAVFoundationVideoPlayerApi api (%@) doesn't respond to " @"@selector(disposePlayer:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; NSInteger arg_textureId = [GetNullableObjectAtIndex(args, 0) integerValue]; FlutterError *error; [api disposePlayer:arg_textureId error:&error]; @@ -208,14 +207,14 @@ void SetUpFVPAVFoundationVideoPlayerApiWithSuffix(id bin @"AVFoundationVideoPlayerApi.setLooping", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FVPAVFoundationVideoPlayerApiGetCodec()]; + codec:FVPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(setLooping:forPlayer:error:)], @"FVPAVFoundationVideoPlayerApi api (%@) doesn't respond to " @"@selector(setLooping:forPlayer:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; BOOL arg_isLooping = [GetNullableObjectAtIndex(args, 0) boolValue]; NSInteger arg_textureId = [GetNullableObjectAtIndex(args, 1) integerValue]; FlutterError *error; @@ -233,14 +232,14 @@ void SetUpFVPAVFoundationVideoPlayerApiWithSuffix(id bin @"AVFoundationVideoPlayerApi.setVolume", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FVPAVFoundationVideoPlayerApiGetCodec()]; + codec:FVPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(setVolume:forPlayer:error:)], @"FVPAVFoundationVideoPlayerApi api (%@) doesn't respond to " @"@selector(setVolume:forPlayer:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; double arg_volume = [GetNullableObjectAtIndex(args, 0) doubleValue]; NSInteger arg_textureId = [GetNullableObjectAtIndex(args, 1) integerValue]; FlutterError *error; @@ -258,14 +257,14 @@ void SetUpFVPAVFoundationVideoPlayerApiWithSuffix(id bin @"AVFoundationVideoPlayerApi.setPlaybackSpeed", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FVPAVFoundationVideoPlayerApiGetCodec()]; + codec:FVPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(setPlaybackSpeed:forPlayer:error:)], @"FVPAVFoundationVideoPlayerApi api (%@) doesn't respond to " @"@selector(setPlaybackSpeed:forPlayer:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; double arg_speed = [GetNullableObjectAtIndex(args, 0) doubleValue]; NSInteger arg_textureId = [GetNullableObjectAtIndex(args, 1) integerValue]; FlutterError *error; @@ -283,14 +282,14 @@ void SetUpFVPAVFoundationVideoPlayerApiWithSuffix(id bin @"AVFoundationVideoPlayerApi.play", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FVPAVFoundationVideoPlayerApiGetCodec()]; + codec:FVPGetMessagesCodec()]; if (api) { NSCAssert( [api respondsToSelector:@selector(playPlayer:error:)], @"FVPAVFoundationVideoPlayerApi api (%@) doesn't respond to @selector(playPlayer:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; NSInteger arg_textureId = [GetNullableObjectAtIndex(args, 0) integerValue]; FlutterError *error; [api playPlayer:arg_textureId error:&error]; @@ -307,14 +306,14 @@ void SetUpFVPAVFoundationVideoPlayerApiWithSuffix(id bin @"AVFoundationVideoPlayerApi.getPosition", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FVPAVFoundationVideoPlayerApiGetCodec()]; + codec:FVPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(positionForPlayer:error:)], @"FVPAVFoundationVideoPlayerApi api (%@) doesn't respond to " @"@selector(positionForPlayer:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; NSInteger arg_textureId = [GetNullableObjectAtIndex(args, 0) integerValue]; FlutterError *error; NSNumber *output = [api positionForPlayer:arg_textureId error:&error]; @@ -331,14 +330,14 @@ void SetUpFVPAVFoundationVideoPlayerApiWithSuffix(id bin @"AVFoundationVideoPlayerApi.seekTo", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FVPAVFoundationVideoPlayerApiGetCodec()]; + codec:FVPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(seekTo:forPlayer:completion:)], @"FVPAVFoundationVideoPlayerApi api (%@) doesn't respond to " @"@selector(seekTo:forPlayer:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; NSInteger arg_position = [GetNullableObjectAtIndex(args, 0) integerValue]; NSInteger arg_textureId = [GetNullableObjectAtIndex(args, 1) integerValue]; [api seekTo:arg_position @@ -358,14 +357,14 @@ void SetUpFVPAVFoundationVideoPlayerApiWithSuffix(id bin @"AVFoundationVideoPlayerApi.pause", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FVPAVFoundationVideoPlayerApiGetCodec()]; + codec:FVPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(pausePlayer:error:)], @"FVPAVFoundationVideoPlayerApi api (%@) doesn't respond to " @"@selector(pausePlayer:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; NSInteger arg_textureId = [GetNullableObjectAtIndex(args, 0) integerValue]; FlutterError *error; [api pausePlayer:arg_textureId error:&error]; @@ -382,14 +381,14 @@ void SetUpFVPAVFoundationVideoPlayerApiWithSuffix(id bin @"AVFoundationVideoPlayerApi.setMixWithOthers", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FVPAVFoundationVideoPlayerApiGetCodec()]; + codec:FVPGetMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(setMixWithOthers:error:)], @"FVPAVFoundationVideoPlayerApi api (%@) doesn't respond to " @"@selector(setMixWithOthers:error:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; + NSArray *args = message; BOOL arg_mixWithOthers = [GetNullableObjectAtIndex(args, 0) boolValue]; FlutterError *error; [api setMixWithOthers:arg_mixWithOthers error:&error]; diff --git a/packages/video_player/video_player_avfoundation/example/macos/Podfile b/packages/video_player/video_player_avfoundation/example/macos/Podfile index c795730db8ed..29c8eb3294cb 100644 --- a/packages/video_player/video_player_avfoundation/example/macos/Podfile +++ b/packages/video_player/video_player_avfoundation/example/macos/Podfile @@ -28,7 +28,6 @@ flutter_macos_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) target 'RunnerTests' do diff --git a/packages/video_player/video_player_avfoundation/example/pubspec.yaml b/packages/video_player/video_player_avfoundation/example/pubspec.yaml index 4b3bf0ee612d..ea24144202f9 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.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/video_player/video_player_avfoundation/lib/src/messages.g.dart b/packages/video_player/video_player_avfoundation/lib/src/messages.g.dart index f14e30cd5b6e..ea4a93fdaba1 100644 --- a/packages/video_player/video_player_avfoundation/lib/src/messages.g.dart +++ b/packages/video_player/video_player_avfoundation/lib/src/messages.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 (v18.0.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.2), 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 @@ -46,7 +46,7 @@ class CreationOptions { String? formatHint; - Map httpHeaders; + Map httpHeaders; Object encode() { return [ @@ -66,17 +66,20 @@ class CreationOptions { packageName: result[2] as String?, formatHint: result[3] as String?, httpHeaders: - (result[4] as Map?)!.cast(), + (result[4] as Map?)!.cast(), ); } } -class _AVFoundationVideoPlayerApiCodec extends StandardMessageCodec { - const _AVFoundationVideoPlayerApiCodec(); +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is CreationOptions) { - buffer.putUint8(128); + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is CreationOptions) { + buffer.putUint8(129); writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); @@ -86,7 +89,7 @@ class _AVFoundationVideoPlayerApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: + case 129: return CreationOptions.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -100,34 +103,33 @@ class AVFoundationVideoPlayerApi { /// BinaryMessenger will be used which routes to the host platform. AVFoundationVideoPlayerApi( {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : __pigeon_binaryMessenger = binaryMessenger, - __pigeon_messageChannelSuffix = + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; - final BinaryMessenger? __pigeon_binaryMessenger; + final BinaryMessenger? pigeonVar_binaryMessenger; - static const MessageCodec pigeonChannelCodec = - _AVFoundationVideoPlayerApiCodec(); + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - final String __pigeon_messageChannelSuffix; + final String pigeonVar_messageChannelSuffix; Future initialize() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.initialize$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.initialize$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(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) 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; @@ -135,52 +137,52 @@ class AVFoundationVideoPlayerApi { } Future create(CreationOptions creationOptions) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.create$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.create$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([creationOptions]) 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 int?)!; + return (pigeonVar_replyList[0] as int?)!; } } Future dispose(int textureId) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.dispose$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.dispose$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([textureId]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([textureId]) 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; @@ -188,23 +190,23 @@ class AVFoundationVideoPlayerApi { } Future setLooping(bool isLooping, int textureId) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.setLooping$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.setLooping$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([isLooping, textureId]) 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; @@ -212,23 +214,23 @@ class AVFoundationVideoPlayerApi { } Future setVolume(double volume, int textureId) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.setVolume$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.setVolume$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([volume, textureId]) 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; @@ -236,23 +238,23 @@ class AVFoundationVideoPlayerApi { } Future setPlaybackSpeed(double speed, int textureId) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.setPlaybackSpeed$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.setPlaybackSpeed$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([speed, textureId]) 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; @@ -260,23 +262,23 @@ class AVFoundationVideoPlayerApi { } Future play(int textureId) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.play$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.play$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([textureId]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([textureId]) 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; @@ -284,52 +286,52 @@ class AVFoundationVideoPlayerApi { } Future getPosition(int textureId) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.getPosition$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.getPosition$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([textureId]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([textureId]) 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 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 int?)!; + return (pigeonVar_replyList[0] as int?)!; } } Future seekTo(int position, int textureId) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.seekTo$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.seekTo$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([position, textureId]) 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; @@ -337,23 +339,23 @@ class AVFoundationVideoPlayerApi { } Future pause(int textureId) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.pause$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.pause$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([textureId]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([textureId]) 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; @@ -361,23 +363,23 @@ class AVFoundationVideoPlayerApi { } Future setMixWithOthers(bool mixWithOthers) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.setMixWithOthers$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.setMixWithOthers$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([mixWithOthers]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = await pigeonVar_channel + .send([mixWithOthers]) 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; diff --git a/packages/video_player/video_player_avfoundation/pigeons/messages.dart b/packages/video_player/video_player_avfoundation/pigeons/messages.dart index 8dbda80bd550..7a2d2957be16 100644 --- a/packages/video_player/video_player_avfoundation/pigeons/messages.dart +++ b/packages/video_player/video_player_avfoundation/pigeons/messages.dart @@ -23,12 +23,7 @@ class CreationOptions { String? uri; String? packageName; String? formatHint; - Map httpHeaders; -} - -class MixWithOthersMessage { - MixWithOthersMessage(this.mixWithOthers); - bool mixWithOthers; + Map httpHeaders; } @HostApi(dartHostTestHandler: 'TestHostVideoPlayerApi') diff --git a/packages/video_player/video_player_avfoundation/pubspec.yaml b/packages/video_player/video_player_avfoundation/pubspec.yaml index 674684ee789d..d309c02258d1 100644 --- a/packages/video_player/video_player_avfoundation/pubspec.yaml +++ b/packages/video_player/video_player_avfoundation/pubspec.yaml @@ -2,11 +2,11 @@ name: video_player_avfoundation description: iOS and macOS implementation of the video_player plugin. repository: https://github.com/flutter/packages/tree/main/packages/video_player/video_player_avfoundation issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22 -version: 2.6.1 +version: 2.6.2 environment: - sdk: ^3.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -29,7 +29,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - pigeon: ^18.0.0 + pigeon: ^22.4.2 topics: - video diff --git a/packages/video_player/video_player_avfoundation/test/test_api.g.dart b/packages/video_player/video_player_avfoundation/test/test_api.g.dart index 180e3037c664..6dbbb53d233e 100644 --- a/packages/video_player/video_player_avfoundation/test/test_api.g.dart +++ b/packages/video_player/video_player_avfoundation/test/test_api.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 (v18.0.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.2), 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, unnecessary_import, no_leading_underscores_for_local_identifiers // ignore_for_file: avoid_relative_lib_imports @@ -13,12 +13,15 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:video_player_avfoundation/src/messages.g.dart'; -class _TestHostVideoPlayerApiCodec extends StandardMessageCodec { - const _TestHostVideoPlayerApiCodec(); +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is CreationOptions) { - buffer.putUint8(128); + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is CreationOptions) { + buffer.putUint8(129); writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); @@ -28,7 +31,7 @@ class _TestHostVideoPlayerApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: + case 129: return CreationOptions.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -39,8 +42,7 @@ class _TestHostVideoPlayerApiCodec extends StandardMessageCodec { abstract class TestHostVideoPlayerApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec pigeonChannelCodec = - _TestHostVideoPlayerApiCodec(); + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); void initialize(); @@ -72,17 +74,18 @@ abstract class TestHostVideoPlayerApi { messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.initialize$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { try { api.initialize(); @@ -97,17 +100,18 @@ abstract class TestHostVideoPlayerApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.create$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.create was null.'); @@ -129,17 +133,18 @@ abstract class TestHostVideoPlayerApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.dispose$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.dispose was null.'); @@ -160,17 +165,18 @@ abstract class TestHostVideoPlayerApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.setLooping$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.setLooping was null.'); @@ -194,17 +200,18 @@ abstract class TestHostVideoPlayerApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.setVolume$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.setVolume was null.'); @@ -228,17 +235,18 @@ abstract class TestHostVideoPlayerApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.setPlaybackSpeed$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.setPlaybackSpeed was null.'); @@ -262,17 +270,18 @@ abstract class TestHostVideoPlayerApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.play$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.play was null.'); @@ -293,17 +302,18 @@ abstract class TestHostVideoPlayerApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.getPosition$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.getPosition was null.'); @@ -324,17 +334,18 @@ abstract class TestHostVideoPlayerApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.seekTo$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.seekTo was null.'); @@ -358,17 +369,18 @@ abstract class TestHostVideoPlayerApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.pause$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.pause was null.'); @@ -389,17 +401,18 @@ abstract class TestHostVideoPlayerApi { } } { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< Object?>( 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.setMixWithOthers$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, null); + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(__pigeon_channel, + .setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.setMixWithOthers was null.'); diff --git a/packages/video_player/video_player_platform_interface/CHANGELOG.md b/packages/video_player/video_player_platform_interface/CHANGELOG.md index ebde5659cf2c..471cde8298d4 100644 --- a/packages/video_player/video_player_platform_interface/CHANGELOG.md +++ b/packages/video_player/video_player_platform_interface/CHANGELOG.md @@ -1,6 +1,7 @@ -## NEXT +## 6.2.3 -* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Clarified that `VideoEventType.initialized` cannot be sent more than once. ## 6.2.2 diff --git a/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart b/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart index 46b992f58c61..d169c5f16d45 100644 --- a/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart +++ b/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart @@ -278,6 +278,8 @@ class VideoEvent { /// completed or to communicate buffering events or play state changed. enum VideoEventType { /// The video has been initialized. + /// + /// A maximum of one event of this type may be emitted per instance. initialized, /// The playback has ended. diff --git a/packages/video_player/video_player_platform_interface/pubspec.yaml b/packages/video_player/video_player_platform_interface/pubspec.yaml index acfdcdf68b05..7ed49e9e2d3d 100644 --- a/packages/video_player/video_player_platform_interface/pubspec.yaml +++ b/packages/video_player/video_player_platform_interface/pubspec.yaml @@ -4,11 +4,11 @@ repository: https://github.com/flutter/packages/tree/main/packages/video_player/ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22 # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 6.2.2 +version: 6.2.3 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/video_player/video_player_web/CHANGELOG.md b/packages/video_player/video_player_web/CHANGELOG.md index d0ef30ca738d..20635077c16c 100644 --- a/packages/video_player/video_player_web/CHANGELOG.md +++ b/packages/video_player/video_player_web/CHANGELOG.md @@ -1,3 +1,12 @@ +## 2.3.3 + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. +* Corrects the behavior of muting/unmuting videos in Chrome's Tap Emulation mode. + +## 2.3.2 + +* Adds support for `web: ^1.0.0`. + ## 2.3.1 * Fixes some `package:web` tweaks. diff --git a/packages/video_player/video_player_web/README.md b/packages/video_player/video_player_web/README.md index 1868a1052d8d..82e2c6abc280 100644 --- a/packages/video_player/video_player_web/README.md +++ b/packages/video_player/video_player_web/README.md @@ -4,7 +4,7 @@ The web implementation of [`video_player`][1]. ## Usage -This package is [endorsed](https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin), +This package is [endorsed](https://flutter.dev/to/endorsed-federated-plugin), which means you can simply use `video_player` normally. This package will be automatically included in your app when you do, so you do not need to add it to your `pubspec.yaml`. diff --git a/packages/video_player/video_player_web/example/README.md b/packages/video_player/video_player_web/example/README.md index 4a01887de7fb..932e9f227cbe 100644 --- a/packages/video_player/video_player_web/example/README.md +++ b/packages/video_player/video_player_web/example/README.md @@ -15,5 +15,5 @@ This package uses `package:integration_test` to run its tests in a web browser. See [Plugin Tests > Web Tests](https://github.com/flutter/flutter/blob/master/docs/ecosystem/testing/Plugin-Tests.md#web-tests) in the Flutter documentation for instructions to set up and run the tests in this package. -Check [flutter.dev > Integration testing](https://flutter.dev/docs/testing/integration-tests) +Check [flutter.dev > Integration testing](https://docs.flutter.dev/testing/integration-tests) for more info. diff --git a/packages/video_player/video_player_web/example/integration_test/video_player_test.dart b/packages/video_player/video_player_web/example/integration_test/video_player_test.dart index 51199ba79d2b..b78de966fe81 100644 --- a/packages/video_player/video_player_web/example/integration_test/video_player_test.dart +++ b/packages/video_player/video_player_web/example/integration_test/video_player_test.dart @@ -44,9 +44,14 @@ void main() { final VideoPlayer player = VideoPlayer(videoElement: video)..initialize(); player.setVolume(0); - - expect(video.volume, isZero, reason: 'Volume should be zero'); expect(video.muted, isTrue, reason: 'muted attribute should be true'); + // If the volume is set to zero, pressing unmute + // button may not restore the audio as expected. + expect(video.volume, greaterThan(0), + reason: 'Volume should not be set to zero when muted'); + player.setVolume(0.5); + expect(video.volume, 0.5, reason: 'Volume should be set to 0.5'); + expect(video.muted, isFalse, reason: 'Muted attribute should be false'); expect(() { player.setVolume(-0.0001); diff --git a/packages/video_player/video_player_web/example/pubspec.yaml b/packages/video_player/video_player_web/example/pubspec.yaml index 27aba7660bb8..56662e0764e2 100644 --- a/packages/video_player/video_player_web/example/pubspec.yaml +++ b/packages/video_player/video_player_web/example/pubspec.yaml @@ -2,8 +2,8 @@ name: video_player_for_web_integration_tests publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: @@ -11,7 +11,7 @@ dependencies: video_player_platform_interface: ^6.1.0 video_player_web: path: ../ - web: ^0.5.1 + web: ^1.0.0 dev_dependencies: flutter_test: diff --git a/packages/video_player/video_player_web/example/web/index.html b/packages/video_player/video_player_web/example/web/index.html index 7fb138cc90fa..956b11f49f7a 100644 --- a/packages/video_player/video_player_web/example/web/index.html +++ b/packages/video_player/video_player_web/example/web/index.html @@ -8,6 +8,6 @@ example - + diff --git a/packages/video_player/video_player_web/lib/src/video_player.dart b/packages/video_player/video_player_web/lib/src/video_player.dart index 72f4b7dc155b..6ef4ee1939e8 100644 --- a/packages/video_player/video_player_web/lib/src/video_player.dart +++ b/packages/video_player/video_player_web/lib/src/video_player.dart @@ -8,7 +8,6 @@ import 'dart:js_interop'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:video_player_platform_interface/video_player_platform_interface.dart'; -import 'package:web/helpers.dart'; import 'package:web/web.dart' as web; import 'duration_utils.dart'; @@ -179,8 +178,13 @@ class VideoPlayer { // TODO(ditman): Do we need to expose a "muted" API? // https://github.com/flutter/flutter/issues/60721 - _videoElement.muted = !(volume > 0.0); - _videoElement.volume = volume; + + // If the volume is set to 0.0, only change muted attribute, but don't adjust the volume. + _videoElement.muted = volume == 0.0; + // Set the volume only if it's greater than 0.0. + if (volume > 0.0) { + _videoElement.volume = volume; + } } /// Sets the playback `speed`. diff --git a/packages/video_player/video_player_web/pubspec.yaml b/packages/video_player/video_player_web/pubspec.yaml index 6b1e1887bca9..0985ee1297b5 100644 --- a/packages/video_player/video_player_web/pubspec.yaml +++ b/packages/video_player/video_player_web/pubspec.yaml @@ -2,11 +2,11 @@ name: video_player_web description: Web platform implementation of video_player. repository: https://github.com/flutter/packages/tree/main/packages/video_player/video_player_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22 -version: 2.3.1 +version: 2.3.3 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: @@ -22,7 +22,7 @@ dependencies: flutter_web_plugins: sdk: flutter video_player_platform_interface: ^6.2.0 - web: ^0.5.1 + web: ">=0.5.1 <2.0.0" dev_dependencies: flutter_test: diff --git a/packages/web_benchmarks/.gitignore b/packages/web_benchmarks/.gitignore new file mode 100644 index 000000000000..333c1e910a3e --- /dev/null +++ b/packages/web_benchmarks/.gitignore @@ -0,0 +1 @@ +logs/ diff --git a/packages/web_benchmarks/CHANGELOG.md b/packages/web_benchmarks/CHANGELOG.md index cd1b8af6892d..0c85d4399095 100644 --- a/packages/web_benchmarks/CHANGELOG.md +++ b/packages/web_benchmarks/CHANGELOG.md @@ -1,6 +1,39 @@ -## NEXT +## 3.1.1 + +* Adds `missing_code_block_language_in_doc_comment` lint. + +## 3.1.0 + +* Add `flutter_frame.total_time`, `flutter_frame.build_time`, and `flutter_frame.raster_time` +metrics to benchmark results. These values are derived from the Flutter `FrameTiming` API. +* Expose a new library `metrics.dart` that contains definitions for the benchmark metrics. +* Add p50, p90, and p95 metrics for benchmark scores. + +## 3.0.0 + +* **Breaking change:** removed the `initialPage` parameter from the `serveWebBenchmark` +method and `runBenchmarks` method. Replaced this parameter with `benchmarkPath`, which +allows for passing the combined value of the URL path segments, fragment, and query parameters. +* Restructure the `testing/test_app` to make the example benchmarks easier to follow. + +## 2.0.2 + +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates benchmark server to serve the app as `crossOriginIsolated`. This +allows us access to high precision timers and allows wasm benchmarks to run +properly as well. + +## 2.0.1 + +* Adds support for `web: ^1.0.0`. + +## 2.0.0 * Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. +* Adds support for running benchmarks with the wasm compilation target. +* **Breaking change** `CompilationOptions` unnamed constructor has been replaced with +two named constructors, `CompilationOptions.js` and `CompilationOptions.wasm` for +JavaScript and WebAssembly compilation respectively. ## 1.2.2 diff --git a/packages/web_benchmarks/README.md b/packages/web_benchmarks/README.md index ce98a22b194a..9b63bf815d4f 100644 --- a/packages/web_benchmarks/README.md +++ b/packages/web_benchmarks/README.md @@ -5,14 +5,14 @@ benchmarks in Chrome. # Writing a benchmark -An example benchmark can be found in [testing/web_benchmark_test.dart][1]. +An example benchmark can be found in [testing/test_app/benchmark/web_benchmark_test.dart][1]. A web benchmark is made of two parts: a client and a server. The client is code that runs in the browser together with the benchmark code. The server serves the app's code and assets. Additionally, the server communicates with the browser to extract the performance traces. -[1]: https://github.com/flutter/packages/blob/master/packages/web_benchmarks/testing/web_benchmarks_test.dart +[1]: https://github.com/flutter/packages/blob/master/packages/web_benchmarks/testing/test_app/benchmark/web_benchmarks_test.dart # Analyzing benchmark results diff --git a/packages/web_benchmarks/lib/client.dart b/packages/web_benchmarks/lib/client.dart index d800e97a7589..fc427473e0dd 100644 --- a/packages/web_benchmarks/lib/client.dart +++ b/packages/web_benchmarks/lib/client.dart @@ -10,8 +10,10 @@ import 'dart:math' as math; import 'package:web/web.dart'; import 'src/common.dart'; +import 'src/computations.dart'; import 'src/recorder.dart'; +export 'src/computations.dart'; export 'src/recorder.dart'; /// Signature for a function that creates a [Recorder]. @@ -25,6 +27,15 @@ late Map _benchmarks; final LocalBenchmarkServerClient _client = LocalBenchmarkServerClient(); +/// Adapts between web:0.5.1 and 1.0.0, so this package is compatible with both. +extension on HTMLElement { + @JS('innerHTML') + external set innerHTMLString(String value); + @JS('insertAdjacentHTML') + external void insertAdjacentHTMLString(String position, String string); + void appendHtml(String input) => insertAdjacentHTMLString('beforeend', input); +} + /// Starts a local benchmark client to run [benchmarks]. /// /// Usually used in combination with a benchmark server, which orders the @@ -32,9 +43,12 @@ final LocalBenchmarkServerClient _client = LocalBenchmarkServerClient(); /// /// When used without a server, prompts the user to select a benchmark to /// run next. +/// +/// [benchmarkPath] specifies the path for the URL that will be loaded in Chrome +/// when reloading the window for subsequent benchmark runs. Future runBenchmarks( Map benchmarks, { - String initialPage = defaultInitialPage, + String benchmarkPath = defaultInitialPath, }) async { // Set local benchmarks. _benchmarks = benchmarks; @@ -51,14 +65,15 @@ Future runBenchmarks( await _runBenchmark(nextBenchmark); final Uri currentUri = Uri.parse(window.location.href); - // Create a new URI with the current 'page' value set to [initialPage] to - // ensure the benchmark app is reloaded at the proper location. - final String newUri = Uri( - scheme: currentUri.scheme, - host: currentUri.host, - port: currentUri.port, - path: initialPage, - ).toString(); + // Create a new URI with the parsed value of [benchmarkPath] to ensure the + // benchmark app is reloaded with the proper configuration. + final String newUri = Uri.parse(benchmarkPath) + .replace( + scheme: currentUri.scheme, + host: currentUri.host, + port: currentUri.port, + ) + .toString(); // Reloading the window will trigger the next benchmark to run. await _client.printToConsole( @@ -152,7 +167,7 @@ void _fallbackToManual(String error) { void _printResultsToScreen(Profile profile) { final HTMLBodyElement body = document.body! as HTMLBodyElement; - body.innerHTML = '

${profile.name}

'; + body.innerHTMLString = '

${profile.name}

'; profile.scoreData.forEach((String scoreKey, Timeseries timeseries) { body.appendHtml('

$scoreKey

'); @@ -402,7 +417,3 @@ class LocalBenchmarkServerClient { return completer.future; } } - -extension on HTMLElement { - void appendHtml(String input) => insertAdjacentHTML('beforeend', input); -} diff --git a/packages/web_benchmarks/lib/metrics.dart b/packages/web_benchmarks/lib/metrics.dart new file mode 100644 index 000000000000..cfc5d9fcc294 --- /dev/null +++ b/packages/web_benchmarks/lib/metrics.dart @@ -0,0 +1,5 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +export 'src/metrics.dart'; diff --git a/packages/web_benchmarks/lib/server.dart b/packages/web_benchmarks/lib/server.dart index 1742ac507c92..8a52c9717c80 100644 --- a/packages/web_benchmarks/lib/server.dart +++ b/packages/web_benchmarks/lib/server.dart @@ -32,8 +32,6 @@ const int defaultChromeDebugPort = 10000; /// can be different (and typically is) from the production entry point of the /// app. /// -/// If [useCanvasKit] is true, builds the app in CanvasKit mode. -/// /// [benchmarkServerPort] is the port this benchmark server serves the app on. /// By default uses [defaultBenchmarkServerPort]. /// @@ -42,6 +40,16 @@ const int defaultChromeDebugPort = 10000; /// /// If [headless] is true, runs Chrome without UI. In particular, this is /// useful in environments (e.g. CI) that doesn't have a display. +/// +/// If [treeShakeIcons] is false, '--no-tree-shake-icons' will be passed as a +/// build argument when building the benchmark app. +/// +/// [compilationOptions] specify the compiler and renderer to use for the +/// benchmark app. This can either use dart2wasm & skwasm or +/// dart2js & canvaskit. +/// +/// [benchmarkPath] specifies the path for the URL that will be loaded upon +/// opening the benchmark app in Chrome. Future serveWebBenchmark({ required io.Directory benchmarkAppDirectory, required String entryPoint, @@ -49,8 +57,8 @@ Future serveWebBenchmark({ int chromeDebugPort = defaultChromeDebugPort, bool headless = true, bool treeShakeIcons = true, - String initialPage = defaultInitialPage, - CompilationOptions compilationOptions = const CompilationOptions(), + CompilationOptions compilationOptions = const CompilationOptions.js(), + String benchmarkPath = defaultInitialPath, }) async { // Reduce logging level. Otherwise, package:webkit_inspection_protocol is way too spammy. Logger.root.level = Level.INFO; @@ -59,10 +67,10 @@ Future serveWebBenchmark({ benchmarkAppDirectory: benchmarkAppDirectory, entryPoint: entryPoint, benchmarkServerPort: benchmarkServerPort, + benchmarkPath: benchmarkPath, chromeDebugPort: chromeDebugPort, headless: headless, compilationOptions: compilationOptions, treeShakeIcons: treeShakeIcons, - initialPage: initialPage, ).run(); } diff --git a/packages/web_benchmarks/lib/src/browser.dart b/packages/web_benchmarks/lib/src/browser.dart index 9c575b167b4a..272a41d7b2b2 100644 --- a/packages/web_benchmarks/lib/src/browser.dart +++ b/packages/web_benchmarks/lib/src/browser.dart @@ -481,7 +481,7 @@ class BlinkTraceEvent { /// /// Sample event encoded as JSON (the data is bogus, this just shows the format): /// - /// ``` + /// ```json /// { /// "name": "myName", /// "cat": "category,list", diff --git a/packages/web_benchmarks/lib/src/common.dart b/packages/web_benchmarks/lib/src/common.dart index 5c7c7259796a..a32f65c77da7 100644 --- a/packages/web_benchmarks/lib/src/common.dart +++ b/packages/web_benchmarks/lib/src/common.dart @@ -15,6 +15,6 @@ const int kMeasuredSampleCount = 100; /// all benchmarks have run and there are no more benchmarks to run. const String kEndOfBenchmarks = '__end_of_benchmarks__'; -/// The default initial page to load upon opening the benchmark app or reloading -/// it in Chrome. -const String defaultInitialPage = 'index.html'; +/// The default initial path for the URL that will be loaded upon opening the +/// benchmark app or reloading it in Chrome. +const String defaultInitialPath = 'index.html'; diff --git a/packages/web_benchmarks/lib/src/compilation_options.dart b/packages/web_benchmarks/lib/src/compilation_options.dart index 3a994703c63e..30a349c25201 100644 --- a/packages/web_benchmarks/lib/src/compilation_options.dart +++ b/packages/web_benchmarks/lib/src/compilation_options.dart @@ -7,11 +7,15 @@ /// This object holds metadata that is used to determine how the benchmark app /// should be built. class CompilationOptions { - /// Creates a [CompilationOptions] object. - const CompilationOptions({ + /// Creates a [CompilationOptions] object that compiles to JavaScript. + const CompilationOptions.js({ this.renderer = WebRenderer.canvaskit, - this.useWasm = false, - }); + }) : useWasm = false; + + /// Creates a [CompilationOptions] object that compiles to WebAssembly. + const CompilationOptions.wasm() + : useWasm = true, + renderer = WebRenderer.skwasm; /// The renderer to use for the build. final WebRenderer renderer; diff --git a/packages/web_benchmarks/lib/src/computations.dart b/packages/web_benchmarks/lib/src/computations.dart new file mode 100644 index 000000000000..99ffcfbc38da --- /dev/null +++ b/packages/web_benchmarks/lib/src/computations.dart @@ -0,0 +1,351 @@ +// 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:math' as math; + +import 'package:collection/collection.dart'; +import 'package:meta/meta.dart'; + +import 'common.dart'; +import 'metrics.dart'; + +/// Series of time recordings indexed in time order. +/// +/// It can calculate [average], [standardDeviation] and [noise]. If the amount +/// of data collected is higher than [_kMeasuredSampleCount], then these +/// calculations will only apply to the latest [_kMeasuredSampleCount] data +/// points. +class Timeseries { + /// Creates an empty timeseries. + /// + /// [name], [isReported], and [useCustomWarmUp] must not be null. + Timeseries(this.name, this.isReported, {this.useCustomWarmUp = false}) + : _warmUpFrameCount = useCustomWarmUp ? 0 : null; + + /// The label of this timeseries used for debugging and result inspection. + final String name; + + /// Whether this timeseries is reported to the benchmark dashboard. + /// + /// If `true` a new benchmark card is created for the timeseries and is + /// visible on the dashboard. + /// + /// If `false` the data is stored but it does not show up on the dashboard. + /// Use unreported metrics for metrics that are useful for manual inspection + /// but that are too fine-grained to be useful for tracking on the dashboard. + final bool isReported; + + /// Whether to delimit warm-up frames in a custom way. + final bool useCustomWarmUp; + + /// The number of frames ignored as warm-up frames, used only + /// when [useCustomWarmUp] is true. + int? _warmUpFrameCount; + + /// The number of frames ignored as warm-up frames. + int get warmUpFrameCount => + useCustomWarmUp ? _warmUpFrameCount! : count - kMeasuredSampleCount; + + /// List of all the values that have been recorded. + /// + /// This list has no limit. + final List _allValues = []; + + /// The total amount of data collected, including ones that were dropped + /// because of the sample size limit. + int get count => _allValues.length; + + /// Extracts useful statistics out of this timeseries. + /// + /// See [TimeseriesStats] for more details. + TimeseriesStats computeStats() { + final int finalWarmUpFrameCount = warmUpFrameCount; + + assert(finalWarmUpFrameCount >= 0 && finalWarmUpFrameCount < count); + + // The first few values we simply discard and never look at. They're from the warm-up phase. + final List warmUpValues = + _allValues.sublist(0, finalWarmUpFrameCount); + + // Values we analyze. + final List candidateValues = + _allValues.sublist(finalWarmUpFrameCount); + + // The average that includes outliers. + final double dirtyAverage = _computeAverage(name, candidateValues); + + // The standard deviation that includes outliers. + final double dirtyStandardDeviation = + _computeStandardDeviationForPopulation(name, candidateValues); + + // Any value that's higher than this is considered an outlier. + final double outlierCutOff = dirtyAverage + dirtyStandardDeviation; + + // Candidates with outliers removed. + final Iterable cleanValues = + candidateValues.where((double value) => value <= outlierCutOff); + + // Outlier candidates. + final Iterable outliers = + candidateValues.where((double value) => value > outlierCutOff); + + // Final statistics. + final double cleanAverage = _computeAverage(name, cleanValues); + final double standardDeviation = + _computeStandardDeviationForPopulation(name, cleanValues); + final double noise = + cleanAverage > 0.0 ? standardDeviation / cleanAverage : 0.0; + + // Compute outlier average. If there are no outliers the outlier average is + // the same as clean value average. In other words, in a perfect benchmark + // with no noise the difference between average and outlier average is zero, + // which the best possible outcome. Noise produces a positive difference + // between the two. + final double outlierAverage = + outliers.isNotEmpty ? _computeAverage(name, outliers) : cleanAverage; + + // Compute percentile values (e.g. p50, p90, p95). + final Map percentiles = computePercentiles( + name, + PercentileMetricComputation.percentilesAsDoubles, + candidateValues, + ); + + final List annotatedValues = [ + for (final double warmUpValue in warmUpValues) + AnnotatedSample( + magnitude: warmUpValue, + isOutlier: warmUpValue > outlierCutOff, + isWarmUpValue: true, + ), + for (final double candidate in candidateValues) + AnnotatedSample( + magnitude: candidate, + isOutlier: candidate > outlierCutOff, + isWarmUpValue: false, + ), + ]; + + return TimeseriesStats( + name: name, + average: cleanAverage, + outlierCutOff: outlierCutOff, + outlierAverage: outlierAverage, + standardDeviation: standardDeviation, + noise: noise, + percentiles: percentiles, + cleanSampleCount: cleanValues.length, + outlierSampleCount: outliers.length, + samples: annotatedValues, + ); + } + + /// Adds a value to this timeseries. + void add(double value, {required bool isWarmUpValue}) { + if (value < 0.0) { + throw StateError( + 'Timeseries $name: negative metric values are not supported. Got: $value', + ); + } + _allValues.add(value); + if (useCustomWarmUp && isWarmUpValue) { + _warmUpFrameCount = warmUpFrameCount + 1; + } + } +} + +/// Various statistics about a [Timeseries]. +/// +/// See the docs on the individual fields for more details. +@sealed +class TimeseriesStats { + /// Creates statistics for a time series. + const TimeseriesStats({ + required this.name, + required this.average, + required this.outlierCutOff, + required this.outlierAverage, + required this.standardDeviation, + required this.noise, + required this.percentiles, + required this.cleanSampleCount, + required this.outlierSampleCount, + required this.samples, + }); + + /// The label used to refer to the corresponding timeseries. + final String name; + + /// The average value of the measured samples without outliers. + final double average; + + /// The standard deviation in the measured samples without outliers. + final double standardDeviation; + + /// The noise as a multiple of the [average] value taken from clean samples. + /// + /// This value can be multiplied by 100.0 to get noise as a percentage of + /// the average. + /// + /// If [average] is zero, treats the result as perfect score, returns zero. + final double noise; + + /// The percentile values (p50, p90, p95, etc.) for the measured samples with + /// outliers. + /// + /// This [Map] is from percentile targets (e.g. 0.50 for p50, 0.90 for p90, + /// etc.) to the computed value for the [samples]. + final Map percentiles; + + /// The maximum value a sample can have without being considered an outlier. + /// + /// See [Timeseries.computeStats] for details on how this value is computed. + final double outlierCutOff; + + /// The average of outlier samples. + /// + /// This value can be used to judge how badly we jank, when we jank. + /// + /// Another useful metrics is the difference between [outlierAverage] and + /// [average]. The smaller the value the more predictable is the performance + /// of the corresponding benchmark. + final double outlierAverage; + + /// The number of measured samples after outlier are removed. + final int cleanSampleCount; + + /// The number of outliers. + final int outlierSampleCount; + + /// All collected samples, annotated with statistical information. + /// + /// See [AnnotatedSample] for more details. + final List samples; + + /// Outlier average divided by clean average. + /// + /// This is a measure of performance consistency. The higher this number the + /// worse is jank when it happens. Smaller is better, with 1.0 being the + /// perfect score. If [average] is zero, this value defaults to 1.0. + double get outlierRatio => average > 0.0 + ? outlierAverage / average + : 1.0; // this can only happen in perfect benchmark that reports only zeros + + @override + String toString() { + final StringBuffer buffer = StringBuffer(); + buffer.writeln( + '$name: (samples: $cleanSampleCount clean/$outlierSampleCount ' + 'outliers/${cleanSampleCount + outlierSampleCount} ' + 'measured/${samples.length} total)', + ); + buffer.writeln(' | average: $average μs'); + buffer.writeln(' | outlier average: $outlierAverage μs'); + buffer.writeln(' | outlier/clean ratio: ${outlierRatio}x'); + buffer.writeln(' | noise: ${_ratioToPercent(noise)}'); + for (final PercentileMetricComputation metric + in PercentileMetricComputation.values) { + buffer.writeln(' | ${metric.name}: ${metric.percentile} μs'); + } + return buffer.toString(); + } +} + +/// Annotates a single measurement with statistical information. +@sealed +class AnnotatedSample { + /// Creates an annotated measurement sample. + const AnnotatedSample({ + required this.magnitude, + required this.isOutlier, + required this.isWarmUpValue, + }); + + /// The non-negative raw result of the measurement. + final double magnitude; + + /// Whether this sample was considered an outlier. + final bool isOutlier; + + /// Whether this sample was taken during the warm-up phase. + /// + /// If this value is `true`, this sample does not participate in + /// statistical computations. However, the sample would still be + /// shown in the visualization of results so that the benchmark + /// can be inspected manually to make sure there's a predictable + /// warm-up regression slope. + final bool isWarmUpValue; +} + +/// Computes the arithmetic mean (or average) of given [values]. +double _computeAverage(String label, Iterable values) { + if (values.isEmpty) { + throw StateError( + '$label: attempted to compute an average of an empty value list.'); + } + + final double sum = values.reduce((double a, double b) => a + b); + return sum / values.length; +} + +/// Computes population standard deviation. +/// +/// Unlike sample standard deviation, which divides by N - 1, this divides by N. +/// +/// See also: +/// +/// * https://en.wikipedia.org/wiki/Standard_deviation +double _computeStandardDeviationForPopulation( + String label, Iterable population) { + if (population.isEmpty) { + throw StateError( + '$label: attempted to compute the standard deviation of empty population.'); + } + final double mean = _computeAverage(label, population); + final double sumOfSquaredDeltas = population.fold( + 0.0, + (double previous, double value) => previous += math.pow(value - mean, 2), + ); + return math.sqrt(sumOfSquaredDeltas / population.length); +} + +String _ratioToPercent(double value) { + return '${(value * 100).toStringAsFixed(2)}%'; +} + +/// Computes the percentile threshold in [values] for the given [percentiles]. +/// +/// Each value in [percentiles] should be between 0.0 and 1.0. +/// +/// Returns a [Map] of percentile values to the computed value from [values]. +Map computePercentiles( + String label, + List percentiles, + Iterable values, +) { + if (values.isEmpty) { + throw StateError( + '$label: attempted to compute a percentile of an empty value list.', + ); + } + for (final double percentile in percentiles) { + if (percentile < 0.0 || percentile > 1.0) { + throw StateError( + '$label: attempted to compute a percentile for an invalid ' + 'value: $percentile', + ); + } + } + + final List sorted = + values.sorted((double a, double b) => a.compareTo(b)); + final Map computed = {}; + for (final double percentile in percentiles) { + final int percentileIndex = + (sorted.length * percentile).round().clamp(0, sorted.length - 1); + computed[percentile] = sorted[percentileIndex]; + } + + return computed; +} diff --git a/packages/web_benchmarks/lib/src/metrics.dart b/packages/web_benchmarks/lib/src/metrics.dart new file mode 100644 index 000000000000..5145d73baffb --- /dev/null +++ b/packages/web_benchmarks/lib/src/metrics.dart @@ -0,0 +1,151 @@ +// 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. + +/// The names for the metrics collected by the benchmark recorder. +enum BenchmarkMetric { + /// The name for the benchmark metric that includes frame-related computations + /// prior to submitting layer and picture operations to the underlying + /// renderer, such as HTML and CanvasKit. + /// + /// During this phase we compute transforms, clips, and other information + /// needed for rendering. + prerollFrame('preroll_frame'), + + /// The name for the benchmark metric that includes submitting layer and + /// picture information to the renderer. + applyFrame('apply_frame'), + + /// The name for the benchmark metric that measures the time spent in + /// [PlatformDispatcher]'s onDrawFrame callback. + drawFrame('draw_frame'), + + /// The name for the benchmark metric that tracks the timespan between vsync + /// start and raster finish for a Flutter frame. + /// + /// This value corresponds to [FrameTiming.totalSpan] from the Flutter Engine. + flutterFrameTotalTime('flutter_frame.total_time'), + + /// The name for the benchmark metric that tracks the duration to build the + /// Flutter frame on the Dart UI thread. + /// + /// This value corresponds to [FrameTiming.buildDuration] from the Flutter + /// Engine. + flutterFrameBuildTime('flutter_frame.build_time'), + + /// The name for the benchmark metric that tracks the duration to rasterize + /// the Flutter frame on the Dart raster thread. + /// + /// This value corresponds to [FrameTiming.rasterDuration] from the Flutter + /// Engine. + flutterFrameRasterTime('flutter_frame.raster_time'); + + const BenchmarkMetric(this.label); + + /// The metric name used in the recorded benchmark data. + final String label; +} + +/// The name for the benchmark metric that records the 'averageTotalUIFrameTime' +/// from the Blink trace summary. +const String totalUiFrameAverage = 'totalUiFrame.average'; + +/// Describes the values computed for each [BenchmarkMetric]. +sealed class BenchmarkMetricComputation { + const BenchmarkMetricComputation(this.name); + + /// The name of each metric computation. + final String name; + + /// The name for the computed value tracking the average value of the measured + /// samples without outliers. + static const NamedMetricComputation average = + NamedMetricComputation._('average'); + + /// The name for the computed value tracking the average of outlier samples. + static const NamedMetricComputation outlierAverage = + NamedMetricComputation._('outlierAverage'); + + /// The name for the computed value tracking the outlier average divided by + /// the clean average. + static const NamedMetricComputation outlierRatio = + NamedMetricComputation._('outlierRatio'); + + /// The name for the computed value tracking the noise as a multiple of the + /// [average] value takes from clean samples. + static const NamedMetricComputation noise = NamedMetricComputation._('noise'); + + /// The name for the computed value tracking the 50th percentile value from + /// the samples with outliers. + static const PercentileMetricComputation p50 = + PercentileMetricComputation._('p50', 0.5); + + /// The name for the computed value tracking the 90th percentile value from + /// the samples with outliers. + static const PercentileMetricComputation p90 = + PercentileMetricComputation._('p90', 0.9); + + /// The name for the computed value tracking the 95th percentile value from + /// the samples with outliers. + static const PercentileMetricComputation p95 = + PercentileMetricComputation._('p95', 0.95); + + /// All of the computed vales for each [BenchmarkMetric]. + static const List values = + [ + average, + outlierAverage, + outlierRatio, + noise, + p50, + p90, + p95, + ]; +} + +/// A [BenchmarkMetricComputation] with a descriptive name. +final class NamedMetricComputation extends BenchmarkMetricComputation { + const NamedMetricComputation._(super.name); +} + +/// A [BenchmarkMetricComputation] describing a percentile (p50, p90, etc.). +final class PercentileMetricComputation extends BenchmarkMetricComputation { + const PercentileMetricComputation._(super.name, this.percentile) + : assert(percentile >= 0.0 && percentile <= 1.0); + + /// The percentile value as a double. + /// + /// This value must be between 0.0 and 1.0. + final double percentile; + + /// The percentile [BenchmarkMetricComputation]s computed for each benchmark + /// metric. + static const List values = + [ + BenchmarkMetricComputation.p50, + BenchmarkMetricComputation.p90, + BenchmarkMetricComputation.p95, + ]; + + /// The percentile values as doubles computed for each benchmark metric. + static List percentilesAsDoubles = PercentileMetricComputation.values + .map((PercentileMetricComputation value) => value.percentile) + .toList(); +} + +/// The list of expected benchmark metrics for the current compilation mode, as +/// determined by the value of [useWasm]. +List expectedBenchmarkMetrics({required bool useWasm}) { + return [ + // The skwasm renderer doesn't have preroll or apply frame steps in its + // rendering. + if (!useWasm) ...[ + BenchmarkMetric.prerollFrame, + BenchmarkMetric.applyFrame, + ], + BenchmarkMetric.drawFrame, + BenchmarkMetric.flutterFrameTotalTime, + BenchmarkMetric.flutterFrameBuildTime, + BenchmarkMetric.flutterFrameRasterTime, + ]; +} diff --git a/packages/web_benchmarks/lib/src/recorder.dart b/packages/web_benchmarks/lib/src/recorder.dart index 85d841f1f8cd..92a710dbc8bd 100644 --- a/packages/web_benchmarks/lib/src/recorder.dart +++ b/packages/web_benchmarks/lib/src/recorder.dart @@ -4,7 +4,6 @@ import 'dart:async'; import 'dart:js_interop'; -import 'dart:math' as math; import 'dart:ui'; import 'dart:ui_web' as ui_web; @@ -18,6 +17,8 @@ import 'package:meta/meta.dart'; import 'package:web/web.dart' as html; import 'common.dart'; +import 'computations.dart'; +import 'metrics.dart'; /// The number of samples from warm-up iterations. /// @@ -27,16 +28,6 @@ const int _kWarmUpSampleCount = 200; /// The total number of samples collected by a benchmark. const int kTotalSampleCount = _kWarmUpSampleCount + kMeasuredSampleCount; -/// A benchmark metric that includes frame-related computations prior to -/// submitting layer and picture operations to the underlying renderer, such as -/// HTML and CanvasKit. During this phase we compute transforms, clips, and -/// other information needed for rendering. -const String kProfilePrerollFrame = 'preroll_frame'; - -/// A benchmark metric that includes submitting layer and picture information -/// to the renderer. -const String kProfileApplyFrame = 'apply_frame'; - /// Measures the amount of time [action] takes. Duration timeAction(VoidCallback action) { final Stopwatch stopwatch = Stopwatch()..start(); @@ -143,7 +134,7 @@ abstract class Recorder { /// /// Example: /// -/// ``` +/// ```dart /// class BenchForLoop extends RawRecorder { /// BenchForLoop() : super(name: benchmarkName); /// @@ -194,7 +185,7 @@ abstract class RawRecorder extends Recorder { /// /// Example: /// -/// ``` +/// ```dart /// class BenchDrawCircle extends SceneBuilderRecorder { /// BenchDrawCircle() : super(name: benchmarkName); /// @@ -250,7 +241,7 @@ abstract class SceneBuilderRecorder extends Recorder { PlatformDispatcher.instance.onDrawFrame = () { final FlutterView? view = PlatformDispatcher.instance.implicitView; try { - _profile.record('drawFrameDuration', () { + _profile.record(BenchmarkMetric.drawFrame.label, () { final SceneBuilder sceneBuilder = SceneBuilder(); onDrawFrame(sceneBuilder); _profile.record('sceneBuildDuration', () { @@ -286,7 +277,7 @@ abstract class SceneBuilderRecorder extends Recorder { /// /// Example: /// -/// ``` +/// ```dart /// class BenchListView extends WidgetRecorder { /// BenchListView() : super(name: benchmarkName); /// @@ -390,8 +381,11 @@ abstract class WidgetRecorder extends Recorder implements FrameRecorder { @mustCallSuper void frameDidDraw() { endMeasureFrame(); - profile.addDataPoint('drawFrameDuration', _drawFrameStopwatch.elapsed, - reported: true); + profile.addDataPoint( + BenchmarkMetric.drawFrame.label, + _drawFrameStopwatch.elapsed, + reported: true, + ); if (shouldContinue()) { PlatformDispatcher.instance.scheduleFrame(); @@ -417,29 +411,54 @@ abstract class WidgetRecorder extends Recorder implements FrameRecorder { _RecordingWidgetsBinding.ensureInitialized(); final Widget widget = createWidget(); - registerEngineBenchmarkValueListener(kProfilePrerollFrame, (num value) { + registerEngineBenchmarkValueListener(BenchmarkMetric.prerollFrame.label, + (num value) { localProfile.addDataPoint( - kProfilePrerollFrame, + BenchmarkMetric.prerollFrame.label, Duration(microseconds: value.toInt()), reported: false, ); }); - registerEngineBenchmarkValueListener(kProfileApplyFrame, (num value) { + registerEngineBenchmarkValueListener(BenchmarkMetric.applyFrame.label, + (num value) { localProfile.addDataPoint( - kProfileApplyFrame, + BenchmarkMetric.applyFrame.label, Duration(microseconds: value.toInt()), reported: false, ); }); + late void Function(List frameTimings) frameTimingsCallback; + binding.addTimingsCallback( + frameTimingsCallback = (List frameTimings) { + for (final FrameTiming frameTiming in frameTimings) { + localProfile.addDataPoint( + BenchmarkMetric.flutterFrameTotalTime.label, + frameTiming.totalSpan, + reported: false, + ); + localProfile.addDataPoint( + BenchmarkMetric.flutterFrameBuildTime.label, + frameTiming.buildDuration, + reported: false, + ); + localProfile.addDataPoint( + BenchmarkMetric.flutterFrameRasterTime.label, + frameTiming.rasterDuration, + reported: false, + ); + } + }); + binding._beginRecording(this, widget); try { await _runCompleter.future; return localProfile; } finally { - stopListeningToEngineBenchmarkValues(kProfilePrerollFrame); - stopListeningToEngineBenchmarkValues(kProfileApplyFrame); + stopListeningToEngineBenchmarkValues(BenchmarkMetric.prerollFrame.label); + stopListeningToEngineBenchmarkValues(BenchmarkMetric.applyFrame.label); + binding.removeTimingsCallback(frameTimingsCallback); } } } @@ -508,8 +527,11 @@ abstract class WidgetBuildRecorder extends Recorder implements FrameRecorder { // Only record frames that show the widget. if (showWidget) { endMeasureFrame(); - profile.addDataPoint('drawFrameDuration', _drawFrameStopwatch.elapsed, - reported: true); + profile.addDataPoint( + BenchmarkMetric.drawFrame.label, + _drawFrameStopwatch.elapsed, + reported: true, + ); } if (shouldContinue()) { @@ -575,254 +597,6 @@ class _WidgetBuildRecorderHostState extends State<_WidgetBuildRecorderHost> { } } -/// Series of time recordings indexed in time order. -/// -/// It can calculate [average], [standardDeviation] and [noise]. If the amount -/// of data collected is higher than [_kMeasuredSampleCount], then these -/// calculations will only apply to the latest [_kMeasuredSampleCount] data -/// points. -class Timeseries { - /// Creates an empty timeseries. - /// - /// [name], [isReported], and [useCustomWarmUp] must not be null. - Timeseries(this.name, this.isReported, {this.useCustomWarmUp = false}) - : _warmUpFrameCount = useCustomWarmUp ? 0 : null; - - /// The label of this timeseries used for debugging and result inspection. - final String name; - - /// Whether this timeseries is reported to the benchmark dashboard. - /// - /// If `true` a new benchmark card is created for the timeseries and is - /// visible on the dashboard. - /// - /// If `false` the data is stored but it does not show up on the dashboard. - /// Use unreported metrics for metrics that are useful for manual inspection - /// but that are too fine-grained to be useful for tracking on the dashboard. - final bool isReported; - - /// Whether to delimit warm-up frames in a custom way. - final bool useCustomWarmUp; - - /// The number of frames ignored as warm-up frames, used only - /// when [useCustomWarmUp] is true. - int? _warmUpFrameCount; - - /// The number of frames ignored as warm-up frames. - int get warmUpFrameCount => - useCustomWarmUp ? _warmUpFrameCount! : count - kMeasuredSampleCount; - - /// List of all the values that have been recorded. - /// - /// This list has no limit. - final List _allValues = []; - - /// The total amount of data collected, including ones that were dropped - /// because of the sample size limit. - int get count => _allValues.length; - - /// Extracts useful statistics out of this timeseries. - /// - /// See [TimeseriesStats] for more details. - TimeseriesStats computeStats() { - final int finalWarmUpFrameCount = warmUpFrameCount; - - assert(finalWarmUpFrameCount >= 0 && finalWarmUpFrameCount < count); - - // The first few values we simply discard and never look at. They're from the warm-up phase. - final List warmUpValues = - _allValues.sublist(0, finalWarmUpFrameCount); - - // Values we analyze. - final List candidateValues = - _allValues.sublist(finalWarmUpFrameCount); - - // The average that includes outliers. - final double dirtyAverage = _computeAverage(name, candidateValues); - - // The standard deviation that includes outliers. - final double dirtyStandardDeviation = - _computeStandardDeviationForPopulation(name, candidateValues); - - // Any value that's higher than this is considered an outlier. - final double outlierCutOff = dirtyAverage + dirtyStandardDeviation; - - // Candidates with outliers removed. - final Iterable cleanValues = - candidateValues.where((double value) => value <= outlierCutOff); - - // Outlier candidates. - final Iterable outliers = - candidateValues.where((double value) => value > outlierCutOff); - - // Final statistics. - final double cleanAverage = _computeAverage(name, cleanValues); - final double standardDeviation = - _computeStandardDeviationForPopulation(name, cleanValues); - final double noise = - cleanAverage > 0.0 ? standardDeviation / cleanAverage : 0.0; - - // Compute outlier average. If there are no outliers the outlier average is - // the same as clean value average. In other words, in a perfect benchmark - // with no noise the difference between average and outlier average is zero, - // which the best possible outcome. Noise produces a positive difference - // between the two. - final double outlierAverage = - outliers.isNotEmpty ? _computeAverage(name, outliers) : cleanAverage; - - final List annotatedValues = [ - for (final double warmUpValue in warmUpValues) - AnnotatedSample( - magnitude: warmUpValue, - isOutlier: warmUpValue > outlierCutOff, - isWarmUpValue: true, - ), - for (final double candidate in candidateValues) - AnnotatedSample( - magnitude: candidate, - isOutlier: candidate > outlierCutOff, - isWarmUpValue: false, - ), - ]; - - return TimeseriesStats( - name: name, - average: cleanAverage, - outlierCutOff: outlierCutOff, - outlierAverage: outlierAverage, - standardDeviation: standardDeviation, - noise: noise, - cleanSampleCount: cleanValues.length, - outlierSampleCount: outliers.length, - samples: annotatedValues, - ); - } - - /// Adds a value to this timeseries. - void add(double value, {required bool isWarmUpValue}) { - if (value < 0.0) { - throw StateError( - 'Timeseries $name: negative metric values are not supported. Got: $value', - ); - } - _allValues.add(value); - if (useCustomWarmUp && isWarmUpValue) { - _warmUpFrameCount = warmUpFrameCount + 1; - } - } -} - -/// Various statistics about a [Timeseries]. -/// -/// See the docs on the individual fields for more details. -@sealed -class TimeseriesStats { - /// Creates statistics for a time series. - const TimeseriesStats({ - required this.name, - required this.average, - required this.outlierCutOff, - required this.outlierAverage, - required this.standardDeviation, - required this.noise, - required this.cleanSampleCount, - required this.outlierSampleCount, - required this.samples, - }); - - /// The label used to refer to the corresponding timeseries. - final String name; - - /// The average value of the measured samples without outliers. - final double average; - - /// The standard deviation in the measured samples without outliers. - final double standardDeviation; - - /// The noise as a multiple of the [average] value takes from clean samples. - /// - /// This value can be multiplied by 100.0 to get noise as a percentage of - /// the average. - /// - /// If [average] is zero, treats the result as perfect score, returns zero. - final double noise; - - /// The maximum value a sample can have without being considered an outlier. - /// - /// See [Timeseries.computeStats] for details on how this value is computed. - final double outlierCutOff; - - /// The average of outlier samples. - /// - /// This value can be used to judge how badly we jank, when we jank. - /// - /// Another useful metrics is the difference between [outlierAverage] and - /// [average]. The smaller the value the more predictable is the performance - /// of the corresponding benchmark. - final double outlierAverage; - - /// The number of measured samples after outlier are removed. - final int cleanSampleCount; - - /// The number of outliers. - final int outlierSampleCount; - - /// All collected samples, annotated with statistical information. - /// - /// See [AnnotatedSample] for more details. - final List samples; - - /// Outlier average divided by clean average. - /// - /// This is a measure of performance consistency. The higher this number the - /// worse is jank when it happens. Smaller is better, with 1.0 being the - /// perfect score. If [average] is zero, this value defaults to 1.0. - double get outlierRatio => average > 0.0 - ? outlierAverage / average - : 1.0; // this can only happen in perfect benchmark that reports only zeros - - @override - String toString() { - final StringBuffer buffer = StringBuffer(); - buffer.writeln( - '$name: (samples: $cleanSampleCount clean/$outlierSampleCount ' - 'outliers/${cleanSampleCount + outlierSampleCount} ' - 'measured/${samples.length} total)', - ); - buffer.writeln(' | average: $average μs'); - buffer.writeln(' | outlier average: $outlierAverage μs'); - buffer.writeln(' | outlier/clean ratio: ${outlierRatio}x'); - buffer.writeln(' | noise: ${_ratioToPercent(noise)}'); - return buffer.toString(); - } -} - -/// Annotates a single measurement with statistical information. -@sealed -class AnnotatedSample { - /// Creates an annotated measurement sample. - const AnnotatedSample({ - required this.magnitude, - required this.isOutlier, - required this.isWarmUpValue, - }); - - /// The non-negative raw result of the measurement. - final double magnitude; - - /// Whether this sample was considered an outlier. - final bool isOutlier; - - /// Whether this sample was taken during the warm-up phase. - /// - /// If this value is `true`, this sample does not participate in - /// statistical computations. However, the sample would still be - /// shown in the visualization of results so that the benchmark - /// can be inspected manually to make sure there's a predictable - /// warm-up regression slope. - final bool isWarmUpValue; -} - /// Base class for a profile collected from running a benchmark. class Profile { /// Creates an empty profile. @@ -920,18 +694,24 @@ class Profile { final Timeseries timeseries = scoreData[key]!; if (timeseries.isReported) { - scoreKeys.add('$key.average'); + scoreKeys.add('$key.${BenchmarkMetricComputation.average.name}'); // Report `outlierRatio` rather than `outlierAverage`, because // the absolute value of outliers is less interesting than the // ratio. - scoreKeys.add('$key.outlierRatio'); + scoreKeys.add('$key.${BenchmarkMetricComputation.outlierRatio.name}'); } final TimeseriesStats stats = timeseries.computeStats(); - json['$key.average'] = stats.average; - json['$key.outlierAverage'] = stats.outlierAverage; - json['$key.outlierRatio'] = stats.outlierRatio; - json['$key.noise'] = stats.noise; + json['$key.${BenchmarkMetricComputation.average.name}'] = stats.average; + json['$key.${BenchmarkMetricComputation.outlierAverage.name}'] = + stats.outlierAverage; + json['$key.${BenchmarkMetricComputation.outlierRatio.name}'] = + stats.outlierRatio; + json['$key.${BenchmarkMetricComputation.noise.name}'] = stats.noise; + for (final PercentileMetricComputation metric + in PercentileMetricComputation.values) { + json['$key.${metric.name}'] = stats.percentiles[metric.percentile]; + } } json.addAll(extraData); @@ -963,42 +743,6 @@ class Profile { } } -/// Computes the arithmetic mean (or average) of given [values]. -double _computeAverage(String label, Iterable values) { - if (values.isEmpty) { - throw StateError( - '$label: attempted to compute an average of an empty value list.'); - } - - final double sum = values.reduce((double a, double b) => a + b); - return sum / values.length; -} - -/// Computes population standard deviation. -/// -/// Unlike sample standard deviation, which divides by N - 1, this divides by N. -/// -/// See also: -/// -/// * https://en.wikipedia.org/wiki/Standard_deviation -double _computeStandardDeviationForPopulation( - String label, Iterable population) { - if (population.isEmpty) { - throw StateError( - '$label: attempted to compute the standard deviation of empty population.'); - } - final double mean = _computeAverage(label, population); - final double sumOfSquaredDeltas = population.fold( - 0.0, - (double previous, double value) => previous += math.pow(value - mean, 2), - ); - return math.sqrt(sumOfSquaredDeltas / population.length); -} - -String _ratioToPercent(double value) { - return '${(value * 100).toStringAsFixed(2)}%'; -} - /// Implemented by recorders that use [_RecordingWidgetsBinding] to receive /// frame life-cycle calls. abstract class FrameRecorder { diff --git a/packages/web_benchmarks/lib/src/runner.dart b/packages/web_benchmarks/lib/src/runner.dart index 8eeaeb0617ac..4e52a88f61ab 100644 --- a/packages/web_benchmarks/lib/src/runner.dart +++ b/packages/web_benchmarks/lib/src/runner.dart @@ -19,6 +19,7 @@ import 'benchmark_result.dart'; import 'browser.dart'; import 'common.dart'; import 'compilation_options.dart'; +import 'metrics.dart'; /// The default port number used by the local benchmark server. const int defaultBenchmarkServerPort = 9999; @@ -39,8 +40,6 @@ class BenchmarkServer { /// can be different (and typically is) from the production entry point of the /// app. /// - /// If [useCanvasKit] is true, builds the app in CanvasKit mode. - /// /// [benchmarkServerPort] is the port this benchmark server serves the app on. /// /// [chromeDebugPort] is the port Chrome uses for DevTool Protocol used to @@ -48,6 +47,16 @@ class BenchmarkServer { /// /// If [headless] is true, runs Chrome without UI. In particular, this is /// useful in environments (e.g. CI) that doesn't have a display. + /// + /// If [treeShakeIcons] is false, '--no-tree-shake-icons' will be passed as a + /// build argument when building the benchmark app. + /// + /// [compilationOptions] specify the compiler and renderer to use for the + /// benchmark app. This can either use dart2wasm & skwasm or + /// dart2js & canvaskit. + /// + /// [benchmarkPath] specifies the path for the URL that will be loaded upon + /// opening the benchmark app in Chrome. BenchmarkServer({ required this.benchmarkAppDirectory, required this.entryPoint, @@ -55,8 +64,8 @@ class BenchmarkServer { required this.chromeDebugPort, required this.headless, required this.treeShakeIcons, - this.compilationOptions = const CompilationOptions(), - this.initialPage = defaultInitialPage, + this.compilationOptions = const CompilationOptions.js(), + this.benchmarkPath = defaultInitialPath, }); final ProcessManager _processManager = const LocalProcessManager(); @@ -92,13 +101,25 @@ class BenchmarkServer { /// When false, '--no-tree-shake-icons' will be passed as a build argument. final bool treeShakeIcons; - /// The initial page to load upon opening the benchmark app in Chrome. + /// The initial path for the URL that will be loaded upon opening the + /// benchmark app in Chrome. /// - /// The default value is [defaultInitialPage]. - final String initialPage; + /// This path should contain the path segments, fragment, and/or query + /// parameters that are required for the benchmark. This value will be parsed + /// by `Uri.parse` and combined with the benchmark URI scheme ('http'), host + /// ('localhost'), and port [benchmarkServerPort] to create the URL for + /// loading in Chrome. See [_benchmarkAppUrl]. + /// + /// The default value is [defaultInitialPath]. + final String benchmarkPath; - String get _benchmarkAppUrl => - 'http://localhost:$benchmarkServerPort/$initialPage'; + String get _benchmarkAppUrl => Uri.parse(benchmarkPath) + .replace( + scheme: 'http', + host: 'localhost', + port: benchmarkServerPort, + ) + .toString(); /// Builds and serves the benchmark app, and collects benchmark results. Future run() async { @@ -119,10 +140,9 @@ class BenchmarkServer { 'web', if (compilationOptions.useWasm) ...[ '--wasm', - '--wasm-opt=debug', - '--omit-type-checks', - ], - '--web-renderer=${compilationOptions.renderer.name}', + '--no-strip-wasm', + ] else + '--web-renderer=${compilationOptions.renderer.name}', '--dart-define=FLUTTER_WEB_ENABLE_PROFILING=true', if (!treeShakeIcons) '--no-tree-shake-icons', '--profile', @@ -161,10 +181,27 @@ class BenchmarkServer { Cascade cascade = Cascade(); // Serves the static files built for the app (html, js, images, fonts, etc) - cascade = cascade.add(createStaticHandler( + final Handler buildFolderHandler = createStaticHandler( path.join(benchmarkAppDirectory.path, 'build', 'web'), defaultDocument: 'index.html', - )); + ); + + // We want our page to be crossOriginIsolated. This will allow us to run the + // skwasm renderer, which uses a SharedArrayBuffer, which requires the page + // to be crossOriginIsolated. But also, even in the non-skwasm case, running + // in crossOriginIsolated gives us access to more accurate timers which are + // useful for capturing good benchmarking data. + // See https://developer.mozilla.org/en-US/docs/Web/API/Performance_API/High_precision_timing#reduced_precision + cascade = cascade.add((Request request) async { + final Response response = await buildFolderHandler(request); + if (response.mimeType == 'text/html') { + return response.change(headers: { + 'Cross-Origin-Opener-Policy': 'same-origin', + 'Cross-Origin-Embedder-Policy': 'require-corp', + }); + } + return response; + }); // Serves the benchmark server API used by the benchmark app to coordinate // the running of benchmarks. @@ -188,11 +225,11 @@ class BenchmarkServer { if (latestPerformanceTrace != null) { final BlinkTraceSummary? traceSummary = BlinkTraceSummary.fromJson(latestPerformanceTrace!); - profile['totalUiFrame.average'] = + profile[totalUiFrameAverage] = traceSummary?.averageTotalUIFrameTime.inMicroseconds; profile['scoreKeys'] ??= []; // using dynamic for consistency with JSON - (profile['scoreKeys'] as List).add('totalUiFrame.average'); + (profile['scoreKeys'] as List).add(totalUiFrameAverage); latestPerformanceTrace = null; } collectedProfiles.add(profile); @@ -257,9 +294,20 @@ class BenchmarkServer { } }); - // If all previous handlers returned HTTP 404, this is the last handler - // that simply warns about the unrecognized path. - cascade = cascade.add((Request request) { + // If all previous handlers returned HTTP 404, this handler either serves + // the static handler at the default document (for GET requests only) or + // warns about the unrecognized path. + cascade = cascade.add((Request request) async { + if (request.method == 'GET') { + final Uri newRequestUri = request.requestedUri.replace(path: '/'); + final Request newRequest = Request( + request.method, + newRequestUri, + headers: request.headers, + ); + return await buildFolderHandler(newRequest); + } + io.stderr.writeln('Unrecognized URL path: ${request.requestedUri.path}'); return Response.notFound('Not found: ${request.requestedUri.path}'); }); diff --git a/packages/web_benchmarks/pubspec.yaml b/packages/web_benchmarks/pubspec.yaml index cbf15b25c1d3..1fdc26d8201a 100644 --- a/packages/web_benchmarks/pubspec.yaml +++ b/packages/web_benchmarks/pubspec.yaml @@ -2,7 +2,7 @@ name: web_benchmarks description: A benchmark harness for performance-testing Flutter apps in Chrome. repository: https://github.com/flutter/packages/tree/main/packages/web_benchmarks issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+web_benchmarks%22 -version: 1.2.2 +version: 3.1.1 environment: sdk: ^3.3.0 @@ -18,7 +18,7 @@ dependencies: process: ">=4.2.4 <6.0.0" shelf: ^1.2.0 shelf_static: ^1.1.0 - web: ^0.5.0 + web: ">=0.5.1 <2.0.0" webkit_inspection_protocol: ^1.0.0 dev_dependencies: diff --git a/packages/web_benchmarks/test/src/analysis_test.dart b/packages/web_benchmarks/test/src/analysis_test.dart index 852cb4c64083..c584f58085c8 100644 --- a/packages/web_benchmarks/test/src/analysis_test.dart +++ b/packages/web_benchmarks/test/src/analysis_test.dart @@ -2,10 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - import 'package:flutter_test/flutter_test.dart'; import 'package:web_benchmarks/analysis.dart'; diff --git a/packages/web_benchmarks/test/src/computations_test.dart b/packages/web_benchmarks/test/src/computations_test.dart new file mode 100644 index 000000000000..94fe44079431 --- /dev/null +++ b/packages/web_benchmarks/test/src/computations_test.dart @@ -0,0 +1,24 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:web_benchmarks/src/computations.dart'; + +void main() { + group('computations', () { + test('computePercentiles', () { + final Map computed = computePercentiles( + 'test', + [0.0, 0.5, 0.9, 0.95, 1.0], + List.generate(100, (int i) => i.toDouble()), + ); + expect(computed.length, 5); + expect(computed[0.0], 0.0); + expect(computed[0.5], 50.0); + expect(computed[0.9], 90.0); + expect(computed[0.95], 95.0); + expect(computed[1.0], 99.0); + }); + }); +} diff --git a/packages/web_benchmarks/testing/test_app/.gitignore b/packages/web_benchmarks/testing/test_app/.gitignore index 9f6b8e534c28..79c113f9b501 100644 --- a/packages/web_benchmarks/testing/test_app/.gitignore +++ b/packages/web_benchmarks/testing/test_app/.gitignore @@ -5,9 +5,12 @@ *.swp .DS_Store .atom/ +.build/ .buildlog/ .history .svn/ +.swiftpm/ +migrate_working_dir/ # IntelliJ related *.iml @@ -26,7 +29,6 @@ .dart_tool/ .flutter-plugins .flutter-plugins-dependencies -.packages .pub-cache/ .pub/ /build/ @@ -36,3 +38,8 @@ app.*.symbols # Obfuscation related app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/packages/web_benchmarks/testing/test_app/.metadata b/packages/web_benchmarks/testing/test_app/.metadata index 5e875f26787c..7dd91c1357be 100644 --- a/packages/web_benchmarks/testing/test_app/.metadata +++ b/packages/web_benchmarks/testing/test_app/.metadata @@ -4,7 +4,27 @@ # This file should be version controlled and should not be manually edited. version: - revision: d26268bb9e6d713a73d6148da7fa75936d442741 - channel: master + revision: "0cd170798c6462aec738d4c749ce3a5fff1c80cf" + channel: "master" project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 0cd170798c6462aec738d4c749ce3a5fff1c80cf + base_revision: 0cd170798c6462aec738d4c749ce3a5fff1c80cf + - platform: web + create_revision: 0cd170798c6462aec738d4c749ce3a5fff1c80cf + base_revision: 0cd170798c6462aec738d4c749ce3a5fff1c80cf + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/packages/web_benchmarks/testing/test_app/analysis_options.yaml b/packages/web_benchmarks/testing/test_app/analysis_options.yaml index 2597fd117946..ab086918a291 100644 --- a/packages/web_benchmarks/testing/test_app/analysis_options.yaml +++ b/packages/web_benchmarks/testing/test_app/analysis_options.yaml @@ -3,5 +3,4 @@ include: ../../../../analysis_options.yaml linter: rules: # This is test code. Do not enforce docs. - package_api_docs: false public_member_api_docs: false diff --git a/packages/web_benchmarks/testing/test_app/benchmark/test_infra/automator.dart b/packages/web_benchmarks/testing/test_app/benchmark/test_infra/automator.dart new file mode 100644 index 000000000000..9484a544144c --- /dev/null +++ b/packages/web_benchmarks/testing/test_app/benchmark/test_infra/automator.dart @@ -0,0 +1,146 @@ +// 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: avoid_print + +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:test_app/home_page.dart' show aboutPageKey, textKey; +import 'package:test_app/main.dart'; +import 'package:web/web.dart'; +import 'package:web_benchmarks/client.dart'; + +import 'common.dart'; + +/// A class that automates the test web app. +class Automator { + Automator({ + required this.benchmark, + required this.stopWarmingUpCallback, + required this.profile, + }); + + /// The current benchmark. + final BenchmarkName benchmark; + + /// A function to call when warm-up is finished. + /// + /// This function is intended to ask `Recorder` to mark the warm-up phase + /// as over. + final void Function() stopWarmingUpCallback; + + /// The profile collected for the running benchmark + final Profile profile; + + /// Whether the automation has ended. + bool finished = false; + + /// A widget controller for automation. + late LiveWidgetController controller; + + Widget createWidget() { + Future.delayed(const Duration(milliseconds: 400), automate); + return const MyApp(); + } + + Future automate() async { + await warmUp(); + + switch (benchmark) { + case BenchmarkName.appNavigate: + await _handleAppNavigate(); + case BenchmarkName.appScroll: + await _handleAppScroll(); + case BenchmarkName.appTap: + await _handleAppTap(); + case BenchmarkName.simpleCompilationCheck: + _handleSimpleCompilationCheck(); + case BenchmarkName.simpleBenchmarkPathCheck: + _handleSimpleBenchmarkPathCheck(); + } + + // At the end of the test, mark as finished. + finished = true; + } + + /// Warm up the animation. + Future warmUp() async { + // Let animation stop. + await animationStops(); + + // Set controller. + controller = LiveWidgetController(WidgetsBinding.instance); + + await controller.pumpAndSettle(); + + // When warm-up finishes, inform the recorder. + stopWarmingUpCallback(); + } + + Future _handleAppNavigate() async { + for (int i = 0; i < 10; ++i) { + print('Testing round $i...'); + await controller.tap(find.byKey(aboutPageKey)); + await animationStops(); + await controller.tap(find.byType(BackButton)); + await animationStops(); + } + } + + Future _handleAppScroll() async { + final ScrollableState scrollable = + Scrollable.of(find.byKey(textKey).evaluate().single); + await scrollable.position.animateTo( + 30000, + curve: Curves.linear, + duration: const Duration(seconds: 20), + ); + } + + Future _handleAppTap() async { + for (int i = 0; i < 10; ++i) { + print('Testing round $i...'); + await controller.tap(find.byIcon(Icons.add)); + await animationStops(); + } + } + + void _handleSimpleCompilationCheck() { + // Record whether we are in wasm mode or not. Ideally, we'd have a more + // first-class way to add metadata like this, but this will work for us to + // pass information about the environment back to the server for the + // purposes of our own tests. + profile.extraData['isWasm'] = kIsWasm ? 1 : 0; + } + + void _handleSimpleBenchmarkPathCheck() { + // Record whether the URL contains the expected path so we can verify the + // behavior of setting the `benchmarkPath` on the benchmark server. + final bool containsExpectedPath = + window.location.toString().contains(testBenchmarkPath); + profile.extraData['expectedUrl'] = containsExpectedPath ? 1 : 0; + } +} + +const Duration _animationCheckingInterval = Duration(milliseconds: 50); + +Future animationStops() async { + if (!WidgetsBinding.instance.hasScheduledFrame) { + return; + } + + final Completer stopped = Completer(); + + Timer.periodic(_animationCheckingInterval, (Timer timer) { + if (!WidgetsBinding.instance.hasScheduledFrame) { + stopped.complete(); + timer.cancel(); + } + }); + + await stopped.future; +} diff --git a/packages/web_benchmarks/testing/test_app/benchmark/test_infra/client/app_client.dart b/packages/web_benchmarks/testing/test_app/benchmark/test_infra/client/app_client.dart new file mode 100644 index 000000000000..2887ba9b7c20 --- /dev/null +++ b/packages/web_benchmarks/testing/test_app/benchmark/test_infra/client/app_client.dart @@ -0,0 +1,21 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:web_benchmarks/client.dart'; + +import '../common.dart'; +import '../recorder.dart'; + +Future main() async { + await runBenchmarks( + { + BenchmarkName.appNavigate.name: () => + TestAppRecorder(benchmark: BenchmarkName.appNavigate), + BenchmarkName.appScroll.name: () => + TestAppRecorder(benchmark: BenchmarkName.appScroll), + BenchmarkName.appTap.name: () => + TestAppRecorder(benchmark: BenchmarkName.appTap), + }, + ); +} diff --git a/packages/web_benchmarks/testing/test_app/benchmark/test_infra/client/simple_benchmark_path_client.dart b/packages/web_benchmarks/testing/test_app/benchmark/test_infra/client/simple_benchmark_path_client.dart new file mode 100644 index 000000000000..f8f54492c3e8 --- /dev/null +++ b/packages/web_benchmarks/testing/test_app/benchmark/test_infra/client/simple_benchmark_path_client.dart @@ -0,0 +1,19 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:web_benchmarks/client.dart'; + +import '../common.dart'; +import '../recorder.dart'; + +Future main() async { + await runBenchmarks( + { + BenchmarkName.simpleBenchmarkPathCheck.name: () => TestAppRecorder( + benchmark: BenchmarkName.simpleBenchmarkPathCheck, + ), + }, + benchmarkPath: testBenchmarkPath, + ); +} diff --git a/packages/web_benchmarks/testing/test_app/benchmark/test_infra/client/simple_compilation_client.dart b/packages/web_benchmarks/testing/test_app/benchmark/test_infra/client/simple_compilation_client.dart new file mode 100644 index 000000000000..301ca2111e71 --- /dev/null +++ b/packages/web_benchmarks/testing/test_app/benchmark/test_infra/client/simple_compilation_client.dart @@ -0,0 +1,18 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:web_benchmarks/client.dart'; + +import '../common.dart'; +import '../recorder.dart'; + +Future main() async { + await runBenchmarks( + { + BenchmarkName.simpleCompilationCheck.name: () => TestAppRecorder( + benchmark: BenchmarkName.simpleCompilationCheck, + ), + }, + ); +} diff --git a/packages/web_benchmarks/testing/test_app/benchmark/test_infra/common.dart b/packages/web_benchmarks/testing/test_app/benchmark/test_infra/common.dart new file mode 100644 index 000000000000..8045852f64d5 --- /dev/null +++ b/packages/web_benchmarks/testing/test_app/benchmark/test_infra/common.dart @@ -0,0 +1,15 @@ +// 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. + +/// The benchmark path to load in the URL when loading or reloading the +/// benchmark app in Chrome. +const String testBenchmarkPath = 'about'; + +enum BenchmarkName { + appNavigate, + appScroll, + appTap, + simpleBenchmarkPathCheck, + simpleCompilationCheck; +} diff --git a/packages/web_benchmarks/testing/test_app/benchmark/test_infra/recorder.dart b/packages/web_benchmarks/testing/test_app/benchmark/test_infra/recorder.dart new file mode 100644 index 000000000000..8b0abd0d125d --- /dev/null +++ b/packages/web_benchmarks/testing/test_app/benchmark/test_infra/recorder.dart @@ -0,0 +1,38 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:web_benchmarks/client.dart'; + +import 'automator.dart'; +import 'common.dart'; + +/// A recorder that measures frame building durations for the test app. +class TestAppRecorder extends WidgetRecorder { + TestAppRecorder({required this.benchmark}) + : super(name: benchmark.name, useCustomWarmUp: true); + + /// The name of the benchmark to be run. + /// + /// See `common.dart` for the list of the names of all benchmarks. + final BenchmarkName benchmark; + + Automator? _automator; + bool get _finished => _automator?.finished ?? false; + + /// Whether we should continue recording. + @override + bool shouldContinue() => !_finished || profile.shouldContinue(); + + /// Creates the [Automator] widget. + @override + Widget createWidget() { + _automator = Automator( + benchmark: benchmark, + stopWarmingUpCallback: profile.stopWarmingUp, + profile: profile, + ); + return _automator!.createWidget(); + } +} diff --git a/packages/web_benchmarks/testing/test_app/benchmark/web_benchmarks_test.dart b/packages/web_benchmarks/testing/test_app/benchmark/web_benchmarks_test.dart new file mode 100644 index 000000000000..6a2990846478 --- /dev/null +++ b/packages/web_benchmarks/testing/test_app/benchmark/web_benchmarks_test.dart @@ -0,0 +1,123 @@ +// 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:convert' show JsonEncoder; +import 'dart:io'; + +import 'package:test/test.dart'; + +import 'package:web_benchmarks/metrics.dart'; +import 'package:web_benchmarks/server.dart'; +import 'package:web_benchmarks/src/common.dart'; + +import 'test_infra/common.dart'; + +Future main() async { + test( + 'Can run a web benchmark', + () async { + await _runBenchmarks( + benchmarkNames: [ + BenchmarkName.appNavigate.name, + BenchmarkName.appScroll.name, + BenchmarkName.appTap.name, + ], + entryPoint: 'benchmark/test_infra/client/app_client.dart', + ); + }, + timeout: Timeout.none, + ); + + test( + 'Can run a web benchmark with an alternate benchmarkPath', + () async { + final BenchmarkResults results = await _runBenchmarks( + benchmarkNames: [BenchmarkName.simpleBenchmarkPathCheck.name], + entryPoint: + 'benchmark/test_infra/client/simple_benchmark_path_client.dart', + benchmarkPath: testBenchmarkPath, + ); + + final List? scores = + results.scores[BenchmarkName.simpleBenchmarkPathCheck.name]; + expect(scores, isNotNull); + + // The runner puts an `expectedUrl` metric in the results so that we can + // verify the initial page value that should be passed on initial load + // and on reloads. + final BenchmarkScore expectedUrlScore = scores! + .firstWhere((BenchmarkScore score) => score.metric == 'expectedUrl'); + expect(expectedUrlScore.value, 1); + }, + timeout: Timeout.none, + ); + + test( + 'Can run a web benchmark with wasm', + () async { + final BenchmarkResults results = await _runBenchmarks( + benchmarkNames: [BenchmarkName.simpleCompilationCheck.name], + entryPoint: + 'benchmark/test_infra/client/simple_compilation_client.dart', + compilationOptions: const CompilationOptions.wasm(), + ); + + // The runner puts an `isWasm` metric in the results so that we can verify + // we are running with the correct compiler and renderer. + final List? scores = + results.scores[BenchmarkName.simpleCompilationCheck.name]; + expect(scores, isNotNull); + + final BenchmarkScore isWasmScore = scores! + .firstWhere((BenchmarkScore score) => score.metric == 'isWasm'); + expect(isWasmScore.value, 1); + }, + timeout: Timeout.none, + ); +} + +Future _runBenchmarks({ + required List benchmarkNames, + required String entryPoint, + String benchmarkPath = defaultInitialPath, + CompilationOptions compilationOptions = const CompilationOptions.js(), +}) async { + final BenchmarkResults taskResult = await serveWebBenchmark( + benchmarkAppDirectory: Directory('testing/test_app'), + entryPoint: entryPoint, + treeShakeIcons: false, + benchmarkPath: benchmarkPath, + compilationOptions: compilationOptions, + ); + + final List expectedMetrics = + expectedBenchmarkMetrics(useWasm: compilationOptions.useWasm) + .map((BenchmarkMetric metric) => metric.label) + .toList(); + + for (final String benchmarkName in benchmarkNames) { + for (final String metricName in expectedMetrics) { + for (final BenchmarkMetricComputation computation + in BenchmarkMetricComputation.values) { + expect( + taskResult.scores[benchmarkName]!.where((BenchmarkScore score) => + score.metric == '$metricName.${computation.name}'), + hasLength(1), + reason: 'Expected to find a metric named ' + '$metricName.${computation.name}'); + } + } + expect( + taskResult.scores[benchmarkName]! + .where((BenchmarkScore score) => score.metric == totalUiFrameAverage), + hasLength(1), + ); + } + + expect( + const JsonEncoder.withIndent(' ').convert(taskResult.toJson()), + isA(), + ); + return taskResult; +} diff --git a/packages/web_benchmarks/testing/test_app/lib/about_page.dart b/packages/web_benchmarks/testing/test_app/lib/about_page.dart index 4147c33f8f13..23f85320eaf7 100644 --- a/packages/web_benchmarks/testing/test_app/lib/about_page.dart +++ b/packages/web_benchmarks/testing/test_app/lib/about_page.dart @@ -3,8 +3,7 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; - -const ValueKey backKey = ValueKey('backKey'); +import 'package:go_router/go_router.dart'; class AboutPage extends StatelessWidget { const AboutPage({super.key}); @@ -14,8 +13,7 @@ class AboutPage extends StatelessWidget { return Scaffold( appBar: AppBar( leading: BackButton( - key: backKey, - onPressed: () => Navigator.of(context).pop(), + onPressed: () => context.canPop() ? context.pop() : context.go('/'), ), ), body: Center( diff --git a/packages/web_benchmarks/testing/test_app/lib/benchmarks/runner.dart b/packages/web_benchmarks/testing/test_app/lib/benchmarks/runner.dart deleted file mode 100644 index 9a870dfca2e8..000000000000 --- a/packages/web_benchmarks/testing/test_app/lib/benchmarks/runner.dart +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// ignore_for_file: avoid_print - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:web_benchmarks/client.dart'; - -import '../about_page.dart' show backKey; -import '../home_page.dart' show aboutPageKey, textKey; -import '../main.dart'; - -/// A recorder that measures frame building durations. -abstract class AppRecorder extends WidgetRecorder { - AppRecorder({required this.benchmarkName}) : super(name: benchmarkName); - - final String benchmarkName; // ignore: unreachable_from_main - - Future automate(); - - @override - Widget createWidget() { - Future.delayed(const Duration(milliseconds: 400), automate); - return const MyApp(); - } - - Future animationStops() async { - while (WidgetsBinding.instance.hasScheduledFrame) { - await Future.delayed(const Duration(milliseconds: 200)); - } - } -} - -class ScrollRecorder extends AppRecorder { - ScrollRecorder() : super(benchmarkName: 'scroll'); - - @override - Future automate() async { - final ScrollableState scrollable = - Scrollable.of(find.byKey(textKey).evaluate().single); - await scrollable.position.animateTo( - 30000, - curve: Curves.linear, - duration: const Duration(seconds: 20), - ); - } -} - -class PageRecorder extends AppRecorder { - PageRecorder() : super(benchmarkName: 'page'); - - bool _completed = false; - - @override - bool shouldContinue() => profile.shouldContinue() || !_completed; - - @override - Future automate() async { - final LiveWidgetController controller = - LiveWidgetController(WidgetsBinding.instance); - for (int i = 0; i < 10; ++i) { - print('Testing round $i...'); - await controller.tap(find.byKey(aboutPageKey)); - await animationStops(); - await controller.tap(find.byKey(backKey)); - await animationStops(); - } - _completed = true; - } -} - -class TapRecorder extends AppRecorder { - TapRecorder() : super(benchmarkName: 'tap'); - - bool _completed = false; - - @override - bool shouldContinue() => profile.shouldContinue() || !_completed; - - @override - Future automate() async { - final LiveWidgetController controller = - LiveWidgetController(WidgetsBinding.instance); - for (int i = 0; i < 10; ++i) { - print('Testing round $i...'); - await controller.tap(find.byIcon(Icons.add)); - await animationStops(); - } - _completed = true; - } -} - -Future main() async { - await runBenchmarks({ - 'scroll': () => ScrollRecorder(), - 'page': () => PageRecorder(), - 'tap': () => TapRecorder(), - }); -} diff --git a/packages/web_benchmarks/testing/test_app/lib/benchmarks/runner_simple.dart b/packages/web_benchmarks/testing/test_app/lib/benchmarks/runner_simple.dart deleted file mode 100644 index 7b6c6ae694db..000000000000 --- a/packages/web_benchmarks/testing/test_app/lib/benchmarks/runner_simple.dart +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:flutter_test/flutter_test.dart'; -import 'package:web_benchmarks/client.dart'; - -import 'runner.dart'; - -class SimpleRecorder extends AppRecorder { - SimpleRecorder() : super(benchmarkName: 'simple'); - - @override - Future automate() async { - // Do nothing. - } -} - -Future main() async { - await runBenchmarks({ - 'simple': () => SimpleRecorder(), - }); -} diff --git a/packages/web_benchmarks/testing/test_app/lib/home_page.dart b/packages/web_benchmarks/testing/test_app/lib/home_page.dart index dee8c9d0eebd..c0f7a131aec3 100644 --- a/packages/web_benchmarks/testing/test_app/lib/home_page.dart +++ b/packages/web_benchmarks/testing/test_app/lib/home_page.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; const ValueKey textKey = ValueKey('textKey'); const ValueKey aboutPageKey = ValueKey('aboutPageKey'); @@ -33,8 +34,8 @@ class _HomePageState extends State { actions: [ IconButton( key: aboutPageKey, - icon: const Icon(Icons.alternate_email), - onPressed: () => Navigator.of(context).pushNamed('about'), + icon: const Icon(Icons.help_outline), + onPressed: () => context.go('/about'), ), ], ), diff --git a/packages/web_benchmarks/testing/test_app/lib/icon_page.dart b/packages/web_benchmarks/testing/test_app/lib/icon_page.dart deleted file mode 100644 index fd0da430ee0f..000000000000 --- a/packages/web_benchmarks/testing/test_app/lib/icon_page.dart +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class IconGeneratorPage extends StatefulWidget { - const IconGeneratorPage({super.key}); - - static int defaultIconCodePoint = int.parse('0xf03f'); - - @override - State createState() => _IconGeneratorPageState(); -} - -class _IconGeneratorPageState extends State { - int iconCodePoint = IconGeneratorPage.defaultIconCodePoint; - - @override - Widget build(BuildContext context) { - return Column( - children: [ - TextField( - onSubmitted: (String value) { - final int codePointAsInt = - int.tryParse(value) ?? IconGeneratorPage.defaultIconCodePoint; - setState(() { - iconCodePoint = codePointAsInt; - }); - }, - ), - const SizedBox(height: 24.0), - Icon(generateIcon(iconCodePoint)), - ], - ); - } - - // Unless '--no-tree-shake-icons' is passed to the flutter build command, - // the presence of this method will trigger an exception due to the use of - // non-constant invocations of [IconData]. - IconData generateIcon(int materialIconCodePoint) => IconData( - materialIconCodePoint, - fontFamily: 'MaterialIcons', - ); -} diff --git a/packages/web_benchmarks/testing/test_app/lib/main.dart b/packages/web_benchmarks/testing/test_app/lib/main.dart index e07fc56ec2ab..172abba32888 100644 --- a/packages/web_benchmarks/testing/test_app/lib/main.dart +++ b/packages/web_benchmarks/testing/test_app/lib/main.dart @@ -3,32 +3,44 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; +import 'package:flutter_web_plugins/url_strategy.dart'; +import 'package:go_router/go_router.dart'; import 'about_page.dart'; import 'home_page.dart'; -import 'icon_page.dart'; void main() { + usePathUrlStrategy(); runApp(const MyApp()); } +final GoRouter _router = GoRouter( + routes: [ + GoRoute( + path: '/', + builder: (_, __) => const HomePage(title: 'Flutter Demo Home Page'), + ), + GoRoute( + path: '/about', + builder: (_, __) => const AboutPage(), + ), + ], +); + class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { - return MaterialApp( + return MaterialApp.router( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), - initialRoute: 'home', - routes: { - 'home': (_) => const HomePage(title: 'Flutter Demo Home Page'), - 'about': (_) => const AboutPage(), - 'icon_generator': (_) => const IconGeneratorPage(), - }, + routerConfig: _router, + // This blocks the About page button. + debugShowCheckedModeBanner: false, ); } } diff --git a/packages/web_benchmarks/testing/test_app/pubspec.yaml b/packages/web_benchmarks/testing/test_app/pubspec.yaml index 0a69219b36b1..902f1e0ba9cb 100644 --- a/packages/web_benchmarks/testing/test_app/pubspec.yaml +++ b/packages/web_benchmarks/testing/test_app/pubspec.yaml @@ -6,13 +6,21 @@ publish_to: 'none' version: 1.0.0+1 environment: - sdk: ^3.2.0 + sdk: ^3.3.0 dependencies: flutter: sdk: flutter + flutter_web_plugins: + sdk: flutter + go_router: ^14.2.7 + +dev_dependencies: + flutter_lints: ^4.0.0 flutter_test: sdk: flutter + test: ^1.19.5 + web: ">=0.5.1 <2.0.0" web_benchmarks: path: ../../ diff --git a/packages/web_benchmarks/testing/test_app/web/icons/Icon-maskable-192.png b/packages/web_benchmarks/testing/test_app/web/icons/Icon-maskable-192.png new file mode 100644 index 000000000000..eb9b4d76e525 Binary files /dev/null and b/packages/web_benchmarks/testing/test_app/web/icons/Icon-maskable-192.png differ diff --git a/packages/web_benchmarks/testing/test_app/web/icons/Icon-maskable-512.png b/packages/web_benchmarks/testing/test_app/web/icons/Icon-maskable-512.png new file mode 100644 index 000000000000..d69c56691fbd Binary files /dev/null and b/packages/web_benchmarks/testing/test_app/web/icons/Icon-maskable-512.png differ diff --git a/packages/web_benchmarks/testing/test_app/web/index.html b/packages/web_benchmarks/testing/test_app/web/index.html index 0489be3063cd..cc7ef836e2f3 100644 --- a/packages/web_benchmarks/testing/test_app/web/index.html +++ b/packages/web_benchmarks/testing/test_app/web/index.html @@ -4,12 +4,27 @@ found in the LICENSE file. --> + + + - + @@ -21,16 +36,6 @@ - - - + diff --git a/packages/web_benchmarks/testing/test_app/web/manifest.json b/packages/web_benchmarks/testing/test_app/web/manifest.json index 13a236907762..8242090a0aa6 100644 --- a/packages/web_benchmarks/testing/test_app/web/manifest.json +++ b/packages/web_benchmarks/testing/test_app/web/manifest.json @@ -18,6 +18,18 @@ "src": "icons/Icon-512.png", "sizes": "512x512", "type": "image/png" + }, + { + "src": "icons/Icon-maskable-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "icons/Icon-maskable-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" } ] } diff --git a/packages/web_benchmarks/testing/web_benchmarks_test.dart b/packages/web_benchmarks/testing/web_benchmarks_test.dart deleted file mode 100644 index 6c91d4bda4f1..000000000000 --- a/packages/web_benchmarks/testing/web_benchmarks_test.dart +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:convert' show JsonEncoder; -import 'dart:io'; - -import 'package:test/test.dart'; - -import 'package:web_benchmarks/server.dart'; -import 'package:web_benchmarks/src/common.dart'; - -Future main() async { - test('Can run a web benchmark', () async { - await _runBenchmarks( - benchmarkNames: ['scroll', 'page', 'tap'], - entryPoint: 'lib/benchmarks/runner.dart', - ); - }, timeout: Timeout.none); - - test('Can run a web benchmark with an alternate initial page', () async { - await _runBenchmarks( - benchmarkNames: ['simple'], - entryPoint: 'lib/benchmarks/runner_simple.dart', - initialPage: 'index.html#about', - ); - }, timeout: Timeout.none); - - test( - 'Can run a web benchmark with wasm', - () async { - await _runBenchmarks( - benchmarkNames: ['simple'], - entryPoint: 'lib/benchmarks/runner_simple.dart', - compilationOptions: const CompilationOptions(useWasm: true), - ); - }, - skip: true, // https://github.com/flutter/flutter/issues/142809 - timeout: Timeout.none, - ); -} - -Future _runBenchmarks({ - required List benchmarkNames, - required String entryPoint, - String initialPage = defaultInitialPage, - CompilationOptions compilationOptions = const CompilationOptions(), -}) async { - final BenchmarkResults taskResult = await serveWebBenchmark( - benchmarkAppDirectory: Directory('testing/test_app'), - entryPoint: entryPoint, - treeShakeIcons: false, - initialPage: initialPage, - compilationOptions: compilationOptions, - ); - - for (final String benchmarkName in benchmarkNames) { - for (final String metricName in [ - 'preroll_frame', - 'apply_frame', - 'drawFrameDuration', - ]) { - for (final String valueName in [ - 'average', - 'outlierAverage', - 'outlierRatio', - 'noise', - ]) { - expect( - taskResult.scores[benchmarkName]!.where((BenchmarkScore score) => - score.metric == '$metricName.$valueName'), - hasLength(1), - ); - } - } - expect( - taskResult.scores[benchmarkName]!.where( - (BenchmarkScore score) => score.metric == 'totalUiFrame.average'), - hasLength(1), - ); - } - - expect( - const JsonEncoder.withIndent(' ').convert(taskResult.toJson()), - isA(), - ); -} diff --git a/packages/webview_flutter/webview_flutter/CHANGELOG.md b/packages/webview_flutter/webview_flutter/CHANGELOG.md index 34495364cf58..f52c4cbce1ce 100644 --- a/packages/webview_flutter/webview_flutter/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter/CHANGELOG.md @@ -1,3 +1,12 @@ +## 4.10.0 + +* Updates minimum supported `webview_flutter_android` from 3.16.0 to 4.0.0. + +## 4.9.0 + +* Adds endorsed macOS support. +* Updates minimum supported SDK version to Flutter 3.24/Dart 3.5. + ## 4.8.0 * Adds `onHttpError` callback to `NavigationDelegate` to catch HTTP error status codes. diff --git a/packages/webview_flutter/webview_flutter/README.md b/packages/webview_flutter/webview_flutter/README.md index 91c201a1584f..fbd6d50e2fd7 100644 --- a/packages/webview_flutter/webview_flutter/README.md +++ b/packages/webview_flutter/webview_flutter/README.md @@ -9,12 +9,11 @@ A Flutter plugin that provides a WebView widget. On iOS the WebView widget is backed by a [WKWebView](https://developer.apple.com/documentation/webkit/wkwebview). On Android the WebView widget is backed by a [WebView](https://developer.android.com/reference/android/webkit/WebView). -| | Android | iOS | -|-------------|----------------|-------| -| **Support** | SDK 19+ or 20+ | 12.0+ | +| | Android | iOS | macOS | +|-------------|---------|-------|--------| +| **Support** | SDK 21+ | 12.0+ | 10.14+ | ## Usage -Add `webview_flutter` as a [dependency in your pubspec.yaml file](https://pub.dev/packages/webview_flutter/install). You can now display a WebView by: @@ -24,7 +23,6 @@ You can now display a WebView by: ```dart controller = WebViewController() ..setJavaScriptMode(JavaScriptMode.unrestricted) - ..setBackgroundColor(const Color(0x00000000)) ..setNavigationDelegate( NavigationDelegate( onProgress: (int progress) { @@ -65,8 +63,8 @@ for more details. ### Android Platform Views This plugin uses -[Platform Views](https://flutter.dev/docs/development/platform-integration/platform-views) to embed -the Android’s WebView within the Flutter app. +[Platform Views](https://docs.flutter.dev/platform-integration/android/platform-views) to +embed the Android's WebView within the Flutter app. You should however make sure to set the correct `minSdkVersion` in `android/app/build.gradle` if it was previously lower than 19: @@ -87,7 +85,7 @@ To access platform-specific features, start by adding the platform implementatio app or package: * **Android**: [webview_flutter_android](https://pub.dev/packages/webview_flutter_android/install) -* **iOS**: [webview_flutter_wkwebview](https://pub.dev/packages/webview_flutter_wkwebview/install) +* **iOS/macOS**: [webview_flutter_wkwebview](https://pub.dev/packages/webview_flutter_wkwebview/install) Next, add the imports of the implementation packages to your app or package: @@ -95,7 +93,7 @@ Next, add the imports of the implementation packages to your app or package: ```dart // Import for Android features. import 'package:webview_flutter_android/webview_flutter_android.dart'; -// Import for iOS features. +// Import for iOS/macOS features. import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart'; ``` @@ -110,7 +108,7 @@ additional functionality provided by the platform and is followed by an example. 2. Call methods on a platform implementation of a class by using the `platform` field (e.g. `WebViewController.platform`, `WebViewWidget.platform`, etc.). -Below is an example of setting additional iOS and Android parameters on the `WebViewController`. +Below is an example of setting additional iOS/macOS and Android parameters on the `WebViewController`. ```dart @@ -138,12 +136,12 @@ See https://pub.dev/documentation/webview_flutter_android/latest/webview_flutter for more details on Android features. See https://pub.dev/documentation/webview_flutter_wkwebview/latest/webview_flutter_wkwebview/webview_flutter_wkwebview-library.html -for more details on iOS features. +for more details on iOS/macOS features. ### Enable Material Components for Android To use Material Components when the user interacts with input elements in the WebView, -follow the steps described in the [Enabling Material Components instructions](https://flutter.dev/docs/deployment/android#enabling-material-components). +follow the steps described in the [Enabling Material Components instructions](https://docs.flutter.dev/deployment/android#enable-material-components). ### Setting custom headers on POST requests diff --git a/packages/webview_flutter/webview_flutter/example/android/app/build.gradle b/packages/webview_flutter/webview_flutter/example/android/app/build.gradle index a30fd72bb1a3..391442b528bd 100644 --- a/packages/webview_flutter/webview_flutter/example/android/app/build.gradle +++ b/packages/webview_flutter/webview_flutter/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.webviewflutterexample' compileSdk flutter.compileSdkVersion @@ -32,8 +30,8 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "io.flutter.plugins.webviewflutterexample" - minSdkVersion 21 - targetSdkVersion 28 + minSdkVersion flutter.minSdkVersion + targetSdkVersion 35 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/packages/webview_flutter/webview_flutter/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/webview_flutter/webview_flutter/example/android/app/gradle/wrapper/gradle-wrapper.properties index 609ab8e6c8b5..d951fac2bf31 100644 --- a/packages/webview_flutter/webview_flutter/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ b/packages/webview_flutter/webview_flutter/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/packages/webview_flutter/webview_flutter/example/android/app/src/main/AndroidManifest.xml b/packages/webview_flutter/webview_flutter/example/android/app/src/main/AndroidManifest.xml index 580051edfeb3..484b588c8528 100644 --- a/packages/webview_flutter/webview_flutter/example/android/app/src/main/AndroidManifest.xml +++ b/packages/webview_flutter/webview_flutter/example/android/app/src/main/AndroidManifest.xml @@ -12,6 +12,7 @@ android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:launchMode="singleTop" + android:exported="true" android:name="io.flutter.embedding.android.FlutterActivity" android:theme="@style/LaunchTheme" android:windowSoftInputMode="adjustResize"> diff --git a/packages/webview_flutter/webview_flutter/example/android/build.gradle b/packages/webview_flutter/webview_flutter/example/android/build.gradle index cec92de922cf..b9db5700753a 100644 --- a/packages/webview_flutter/webview_flutter/example/android/build.gradle +++ b/packages/webview_flutter/webview_flutter/example/android/build.gradle @@ -1,14 +1,3 @@ -buildscript { - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' - } -} - 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/webview_flutter/webview_flutter/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/webview_flutter/webview_flutter/example/android/gradle/wrapper/gradle-wrapper.properties index aeaff6f869f3..7aeeb11c6ee5 100644 --- a/packages/webview_flutter/webview_flutter/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/webview_flutter/webview_flutter/example/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/webview_flutter/webview_flutter/example/android/settings.gradle b/packages/webview_flutter/webview_flutter/example/android/settings.gradle index 32735a3cfd4b..a989e8eb35b4 100644 --- a/packages/webview_flutter/webview_flutter/example/android/settings.gradle +++ b/packages/webview_flutter/webview_flutter/example/android/settings.gradle @@ -1,28 +1,27 @@ -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 flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") -def plugins = new Properties() -def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') -if (pluginsFile.exists()) { - pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } -} - -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.7.10" 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/webview_flutter/webview_flutter/example/integration_test/webview_flutter_test.dart b/packages/webview_flutter/webview_flutter/example/integration_test/webview_flutter_test.dart index 8460a602ab02..8a3477d4031b 100644 --- a/packages/webview_flutter/webview_flutter/example/integration_test/webview_flutter_test.dart +++ b/packages/webview_flutter/webview_flutter/example/integration_test/webview_flutter_test.dart @@ -22,7 +22,8 @@ import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart'; Future main() async { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - final HttpServer server = await HttpServer.bind(InternetAddress.anyIPv4, 0); + final HttpServer server = + await HttpServer.bind(InternetAddress.loopbackIPv4, 0); unawaited(server.forEach((HttpRequest request) { if (request.uri.path == '/hello.txt') { request.response.writeln('Hello, world.'); @@ -449,7 +450,10 @@ Future main() async { await controller.runJavaScriptReturningResult('isPaused();') as bool; expect(isPaused, true); }); - }); + }, + // OGG playback is not supported on macOS, so the test data would need + // to be changed to support macOS. + skip: Platform.isMacOS); testWidgets('getTitle', (WidgetTester tester) async { const String getTitleTest = ''' @@ -563,7 +567,10 @@ Future main() async { expect(recordedPosition?.x, X_SCROLL * 2); expect(recordedPosition?.y, Y_SCROLL * 2); }); - }); + }, + // Scroll position is currently not implemented for macOS. + // Flakes on iOS: https://github.com/flutter/flutter/issues/154826 + skip: Platform.isMacOS || Platform.isIOS); group('NavigationDelegate', () { const String blankPage = ''; @@ -578,7 +585,7 @@ Future main() async { await controller.setNavigationDelegate(NavigationDelegate( onPageFinished: (_) => pageLoaded.complete(), onNavigationRequest: (NavigationRequest navigationRequest) { - return (navigationRequest.url.contains('youtube.com')) + return navigationRequest.url.contains('youtube.com') ? NavigationDecision.prevent : NavigationDecision.navigate; }, @@ -648,7 +655,7 @@ Future main() async { await controller.setNavigationDelegate(NavigationDelegate( onPageFinished: (_) => pageLoaded.complete(), onNavigationRequest: (NavigationRequest navigationRequest) { - return (navigationRequest.url.contains('youtube.com')) + return navigationRequest.url.contains('youtube.com') ? NavigationDecision.prevent : NavigationDecision.navigate; })); @@ -943,7 +950,7 @@ Future main() async { 'localStorage.getItem("myCat");', ) as String; } catch (exception) { - if (defaultTargetPlatform == TargetPlatform.iOS && + if (_isWKWebView() && exception is ArgumentError && (exception.message as String).contains( 'Result of JavaScript execution returned a `null` value.')) { @@ -955,24 +962,29 @@ Future main() async { ); } -// JavaScript `null` evaluate to different string values on Android and iOS. +// JavaScript `null` evaluate to different string values per platform. // This utility method returns the string boolean value of the current platform. String _webViewNull() { - if (defaultTargetPlatform == TargetPlatform.iOS) { + if (_isWKWebView()) { return ''; } return 'null'; } -// JavaScript String evaluate to different string values on Android and iOS. +// JavaScript String evaluates to different strings depending on the platform. // This utility method returns the string boolean value of the current platform. String _webViewString(String value) { - if (defaultTargetPlatform == TargetPlatform.iOS) { + if (_isWKWebView()) { return value; } return '"$value"'; } +bool _isWKWebView() { + return defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS; +} + class ResizableWebView extends StatefulWidget { const ResizableWebView({ super.key, diff --git a/packages/webview_flutter/webview_flutter/example/integration_test/webview_flutter_test_legacy.dart b/packages/webview_flutter/webview_flutter/example/integration_test/webview_flutter_test_legacy.dart index fb037cffd36c..46349b202e64 100644 --- a/packages/webview_flutter/webview_flutter/example/integration_test/webview_flutter_test_legacy.dart +++ b/packages/webview_flutter/webview_flutter/example/integration_test/webview_flutter_test_legacy.dart @@ -20,7 +20,8 @@ import 'package:webview_flutter/src/webview_flutter_legacy.dart'; Future main() async { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - final HttpServer server = await HttpServer.bind(InternetAddress.anyIPv4, 0); + final HttpServer server = + await HttpServer.bind(InternetAddress.loopbackIPv4, 0); unawaited(server.forEach((HttpRequest request) { if (request.uri.path == '/hello.txt') { request.response.writeln('Hello, world.'); @@ -873,7 +874,7 @@ Future main() async { }, javascriptMode: JavascriptMode.unrestricted, navigationDelegate: (NavigationRequest request) { - return (request.url.contains('youtube.com')) + return request.url.contains('youtube.com') ? NavigationDecision.prevent : NavigationDecision.navigate; }, @@ -1003,7 +1004,7 @@ Future main() async { }, javascriptMode: JavascriptMode.unrestricted, navigationDelegate: (NavigationRequest request) { - return (request.url.contains('youtube.com')) + return request.url.contains('youtube.com') ? NavigationDecision.prevent : NavigationDecision.navigate; }, diff --git a/packages/webview_flutter/webview_flutter/example/lib/main.dart b/packages/webview_flutter/webview_flutter/example/lib/main.dart index d24ec11424f4..c73749d0622c 100644 --- a/packages/webview_flutter/webview_flutter/example/lib/main.dart +++ b/packages/webview_flutter/webview_flutter/example/lib/main.dart @@ -7,15 +7,15 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; -import 'dart:typed_data'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:path_provider/path_provider.dart'; import 'package:webview_flutter/webview_flutter.dart'; // #docregion platform_imports // Import for Android features. import 'package:webview_flutter_android/webview_flutter_android.dart'; -// Import for iOS features. +// Import for iOS/macOS features. import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart'; // #enddocregion platform_imports @@ -141,7 +141,6 @@ class _WebViewExampleState extends State { controller ..setJavaScriptMode(JavaScriptMode.unrestricted) - ..setBackgroundColor(const Color(0x00000000)) ..setNavigationDelegate( NavigationDelegate( onProgress: (int progress) { @@ -191,6 +190,11 @@ Page resource error: ) ..loadRequest(Uri.parse('https://flutter.dev')); + // setBackgroundColor is not currently supported on macOS. + if (kIsWeb || !Platform.isMacOS) { + controller.setBackgroundColor(const Color(0x80000000)); + } + // #docregion platform_features if (controller.platform is AndroidWebViewController) { AndroidWebViewController.enableDebugging(true); diff --git a/packages/webview_flutter/webview_flutter/example/lib/simple_example.dart b/packages/webview_flutter/webview_flutter/example/lib/simple_example.dart index 06a7bd31dd8c..9bfe41f3dd59 100644 --- a/packages/webview_flutter/webview_flutter/example/lib/simple_example.dart +++ b/packages/webview_flutter/webview_flutter/example/lib/simple_example.dart @@ -26,7 +26,6 @@ class _WebViewExampleState extends State { // #docregion webview_controller controller = WebViewController() ..setJavaScriptMode(JavaScriptMode.unrestricted) - ..setBackgroundColor(const Color(0x00000000)) ..setNavigationDelegate( NavigationDelegate( onProgress: (int progress) { diff --git a/packages/webview_flutter/webview_flutter/example/macos/.gitignore b/packages/webview_flutter/webview_flutter/example/macos/.gitignore new file mode 100644 index 000000000000..746adbb6b9e1 --- /dev/null +++ b/packages/webview_flutter/webview_flutter/example/macos/.gitignore @@ -0,0 +1,7 @@ +# Flutter-related +**/Flutter/ephemeral/ +**/Pods/ + +# Xcode-related +**/dgph +**/xcuserdata/ diff --git a/packages/webview_flutter/webview_flutter/example/macos/Flutter/Flutter-Debug.xcconfig b/packages/webview_flutter/webview_flutter/example/macos/Flutter/Flutter-Debug.xcconfig new file mode 100644 index 000000000000..4b81f9b2d200 --- /dev/null +++ b/packages/webview_flutter/webview_flutter/example/macos/Flutter/Flutter-Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/packages/webview_flutter/webview_flutter/example/macos/Flutter/Flutter-Release.xcconfig b/packages/webview_flutter/webview_flutter/example/macos/Flutter/Flutter-Release.xcconfig new file mode 100644 index 000000000000..5caa9d1579e4 --- /dev/null +++ b/packages/webview_flutter/webview_flutter/example/macos/Flutter/Flutter-Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/packages/webview_flutter/webview_flutter/example/macos/Podfile b/packages/webview_flutter/webview_flutter/example/macos/Podfile new file mode 100644 index 000000000000..ae77cc1d4269 --- /dev/null +++ b/packages/webview_flutter/webview_flutter/example/macos/Podfile @@ -0,0 +1,39 @@ +platform :osx, '10.14' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_macos_podfile_setup + +target 'Runner' do + use_frameworks! + + flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_macos_build_settings(target) + end +end diff --git a/packages/webview_flutter/webview_flutter/example/macos/Runner.xcodeproj/project.pbxproj b/packages/webview_flutter/webview_flutter/example/macos/Runner.xcodeproj/project.pbxproj new file mode 100644 index 000000000000..0c6904fdef97 --- /dev/null +++ b/packages/webview_flutter/webview_flutter/example/macos/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,650 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXAggregateTarget section */ + 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; + buildPhases = ( + 33CC111E2044C6BF0003C045 /* ShellScript */, + ); + dependencies = ( + ); + name = "Flutter Assemble"; + productName = FLX; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 2EB4149157BBD3A430F11F07 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8F0018C81FCBA5B69ABBF5D1 /* Pods_Runner.framework */; }; + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC111A2044C6BA0003C045; + remoteInfo = FLX; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 33CC110E2044A8840003C045 /* Bundle Framework */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Bundle Framework"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; + 33CC10ED2044A3C60003C045 /* webview_flutter_example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = webview_flutter_example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; + 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; + 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; + 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; + 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 5F8C8F28798E2C13759B0247 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; + 667DA8CACF6C1923CDF6309D /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; + 7AF549A34A225DB69555B81E /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 8F0018C81FCBA5B69ABBF5D1 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9161E5D15A39CAD8BDCA3648 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + EA616C3C53C91DA835A1F62D /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + F3B4A758F2F46A632FB5B88A /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + F927ED1AFD55FE3E39FF121E /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 33CC10EA2044A3C60003C045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 2EB4149157BBD3A430F11F07 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 33BA886A226E78AF003329D5 /* Configs */ = { + isa = PBXGroup; + children = ( + 33E5194F232828860026EE4D /* AppInfo.xcconfig */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, + ); + path = Configs; + sourceTree = ""; + }; + 33CC10E42044A3C60003C045 = { + isa = PBXGroup; + children = ( + 33FAB671232836740065AC1E /* Runner */, + 33CEB47122A05771004F2AC0 /* Flutter */, + 33CC10EE2044A3C60003C045 /* Products */, + D73912EC22F37F3D000D13A0 /* Frameworks */, + 394ADD5AAA21B9C50952CBB6 /* Pods */, + ); + sourceTree = ""; + }; + 33CC10EE2044A3C60003C045 /* Products */ = { + isa = PBXGroup; + children = ( + 33CC10ED2044A3C60003C045 /* webview_flutter_example.app */, + ); + name = Products; + sourceTree = ""; + }; + 33CC11242044D66E0003C045 /* Resources */ = { + isa = PBXGroup; + children = ( + 33CC10F22044A3C60003C045 /* Assets.xcassets */, + 33CC10F42044A3C60003C045 /* MainMenu.xib */, + 33CC10F72044A3C60003C045 /* Info.plist */, + ); + name = Resources; + path = ..; + sourceTree = ""; + }; + 33CEB47122A05771004F2AC0 /* Flutter */ = { + isa = PBXGroup; + children = ( + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, + ); + path = Flutter; + sourceTree = ""; + }; + 33FAB671232836740065AC1E /* Runner */ = { + isa = PBXGroup; + children = ( + 33CC10F02044A3C60003C045 /* AppDelegate.swift */, + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, + 33E51913231747F40026EE4D /* DebugProfile.entitlements */, + 33E51914231749380026EE4D /* Release.entitlements */, + 33CC11242044D66E0003C045 /* Resources */, + 33BA886A226E78AF003329D5 /* Configs */, + ); + path = Runner; + sourceTree = ""; + }; + 394ADD5AAA21B9C50952CBB6 /* Pods */ = { + isa = PBXGroup; + children = ( + 7AF549A34A225DB69555B81E /* Pods-Runner.debug.xcconfig */, + 9161E5D15A39CAD8BDCA3648 /* Pods-Runner.release.xcconfig */, + EA616C3C53C91DA835A1F62D /* Pods-Runner.profile.xcconfig */, + F927ED1AFD55FE3E39FF121E /* Pods-RunnerTests.debug.xcconfig */, + 5F8C8F28798E2C13759B0247 /* Pods-RunnerTests.release.xcconfig */, + 667DA8CACF6C1923CDF6309D /* Pods-RunnerTests.profile.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + D73912EC22F37F3D000D13A0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 8F0018C81FCBA5B69ABBF5D1 /* Pods_Runner.framework */, + F3B4A758F2F46A632FB5B88A /* Pods_RunnerTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 33CC10EC2044A3C60003C045 /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 25920929D4636EAA1B54D439 /* [CP] Check Pods Manifest.lock */, + 33CC10E92044A3C60003C045 /* Sources */, + 33CC10EA2044A3C60003C045 /* Frameworks */, + 33CC10EB2044A3C60003C045 /* Resources */, + 33CC110E2044A8840003C045 /* Bundle Framework */, + 3399D490228B24CF009A79C7 /* ShellScript */, + DE10F152618904A081E20590 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 33CC11202044C79F0003C045 /* PBXTargetDependency */, + ); + name = Runner; + productName = Runner; + productReference = 33CC10ED2044A3C60003C045 /* webview_flutter_example.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 33CC10E52044A3C60003C045 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 33CC10EC2044A3C60003C045 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1100; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 1; + }; + }; + }; + 33CC111A2044C6BA0003C045 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Manual; + }; + }; + }; + buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 33CC10E42044A3C60003C045; + productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 33CC10EC2044A3C60003C045 /* Runner */, + 33CC111A2044C6BA0003C045 /* Flutter Assemble */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 33CC10EB2044A3C60003C045 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 25920929D4636EAA1B54D439 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 3399D490228B24CF009A79C7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; + }; + 33CC111E2044C6BF0003C045 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + Flutter/ephemeral/FlutterInputs.xcfilelist, + ); + inputPaths = ( + Flutter/ephemeral/tripwire, + ); + outputFileListPaths = ( + Flutter/ephemeral/FlutterOutputs.xcfilelist, + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; + }; + DE10F152618904A081E20590 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 33CC10E92044A3C60003C045 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; + targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 33CC10F52044A3C60003C045 /* Base */, + ); + name = MainMenu.xib; + path = Runner; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 338D0CE9231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.14; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Profile; + }; + 338D0CEA231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Profile; + }; + 338D0CEB231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Profile; + }; + 33CC10F92044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.14; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 33CC10FA2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.14; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 33CC10FC2044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 33CC10FD2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 33CC111C2044C6BA0003C045 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 33CC111D2044C6BA0003C045 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10F92044A3C60003C045 /* Debug */, + 33CC10FA2044A3C60003C045 /* Release */, + 338D0CE9231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10FC2044A3C60003C045 /* Debug */, + 33CC10FD2044A3C60003C045 /* Release */, + 338D0CEA231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC111C2044C6BA0003C045 /* Debug */, + 33CC111D2044C6BA0003C045 /* Release */, + 338D0CEB231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 33CC10E52044A3C60003C045 /* Project object */; +} diff --git a/packages/webview_flutter/webview_flutter/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/webview_flutter/webview_flutter/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000000..18d981003d68 --- /dev/null +++ b/packages/webview_flutter/webview_flutter/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/webview_flutter/webview_flutter/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/webview_flutter/webview_flutter/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 000000000000..ebf28f20f4b2 --- /dev/null +++ b/packages/webview_flutter/webview_flutter/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/webview_flutter/webview_flutter/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/packages/webview_flutter/webview_flutter/example/macos/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000000..21a3cc14c74e --- /dev/null +++ b/packages/webview_flutter/webview_flutter/example/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/packages/webview_flutter/webview_flutter/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/webview_flutter/webview_flutter/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000000..18d981003d68 --- /dev/null +++ b/packages/webview_flutter/webview_flutter/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/webview_flutter/webview_flutter/example/macos/Runner/AppDelegate.swift b/packages/webview_flutter/webview_flutter/example/macos/Runner/AppDelegate.swift new file mode 100644 index 000000000000..689c0ecd5254 --- /dev/null +++ b/packages/webview_flutter/webview_flutter/example/macos/Runner/AppDelegate.swift @@ -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 Cocoa +import FlutterMacOS + +@main +class AppDelegate: FlutterAppDelegate { + override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } +} diff --git a/packages/webview_flutter/webview_flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/webview_flutter/webview_flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000000..a2ec33f19f11 --- /dev/null +++ b/packages/webview_flutter/webview_flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_16.png", + "scale" : "1x" + }, + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "2x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "1x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_64.png", + "scale" : "2x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_128.png", + "scale" : "1x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "2x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_1024.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/packages/webview_flutter/webview_flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/packages/webview_flutter/webview_flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png new file mode 100644 index 000000000000..82b6f9d9a33e Binary files /dev/null and b/packages/webview_flutter/webview_flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ diff --git a/packages/webview_flutter/webview_flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/packages/webview_flutter/webview_flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png new file mode 100644 index 000000000000..13b35eba55c6 Binary files /dev/null and b/packages/webview_flutter/webview_flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/packages/webview_flutter/webview_flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/packages/webview_flutter/webview_flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png new file mode 100644 index 000000000000..0a3f5fa40fb3 Binary files /dev/null and b/packages/webview_flutter/webview_flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ diff --git a/packages/webview_flutter/webview_flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/packages/webview_flutter/webview_flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png new file mode 100644 index 000000000000..bdb57226d5f2 Binary files /dev/null and b/packages/webview_flutter/webview_flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/packages/webview_flutter/webview_flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/packages/webview_flutter/webview_flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png new file mode 100644 index 000000000000..f083318e09ca Binary files /dev/null and b/packages/webview_flutter/webview_flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ diff --git a/packages/webview_flutter/webview_flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/packages/webview_flutter/webview_flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png new file mode 100644 index 000000000000..326c0e72c9d8 Binary files /dev/null and b/packages/webview_flutter/webview_flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/packages/webview_flutter/webview_flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/packages/webview_flutter/webview_flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png new file mode 100644 index 000000000000..2f1632cfddf3 Binary files /dev/null and b/packages/webview_flutter/webview_flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/packages/webview_flutter/webview_flutter/example/macos/Runner/Base.lproj/MainMenu.xib b/packages/webview_flutter/webview_flutter/example/macos/Runner/Base.lproj/MainMenu.xib new file mode 100644 index 000000000000..80e867a4e06b --- /dev/null +++ b/packages/webview_flutter/webview_flutter/example/macos/Runner/Base.lproj/MainMenu.xib @@ -0,0 +1,343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/webview_flutter/webview_flutter/example/macos/Runner/Configs/AppInfo.xcconfig b/packages/webview_flutter/webview_flutter/example/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 000000000000..aaf1573085ce --- /dev/null +++ b/packages/webview_flutter/webview_flutter/example/macos/Runner/Configs/AppInfo.xcconfig @@ -0,0 +1,14 @@ +// Application-level settings for the Runner target. +// +// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the +// future. If not, the values below would default to using the project name when this becomes a +// 'flutter create' template. + +// The application's name. By default this is also the title of the Flutter window. +PRODUCT_NAME = webview_flutter_example + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.webview_flutter_example + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2024 dev.flutter.plugins. All rights reserved. diff --git a/packages/webview_flutter/webview_flutter/example/macos/Runner/Configs/Debug.xcconfig b/packages/webview_flutter/webview_flutter/example/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 000000000000..36b0fd9464f4 --- /dev/null +++ b/packages/webview_flutter/webview_flutter/example/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/packages/webview_flutter/webview_flutter/example/macos/Runner/Configs/Release.xcconfig b/packages/webview_flutter/webview_flutter/example/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 000000000000..dff4f49561c8 --- /dev/null +++ b/packages/webview_flutter/webview_flutter/example/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/packages/webview_flutter/webview_flutter/example/macos/Runner/Configs/Warnings.xcconfig b/packages/webview_flutter/webview_flutter/example/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 000000000000..42bcbf4780b1 --- /dev/null +++ b/packages/webview_flutter/webview_flutter/example/macos/Runner/Configs/Warnings.xcconfig @@ -0,0 +1,13 @@ +WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings +GCC_WARN_UNDECLARED_SELECTOR = YES +CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES +CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_PRAGMA_PACK = YES +CLANG_WARN_STRICT_PROTOTYPES = YES +CLANG_WARN_COMMA = YES +GCC_WARN_STRICT_SELECTOR_MATCH = YES +CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES +GCC_WARN_SHADOW = YES +CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/packages/webview_flutter/webview_flutter/example/macos/Runner/DebugProfile.entitlements b/packages/webview_flutter/webview_flutter/example/macos/Runner/DebugProfile.entitlements new file mode 100644 index 000000000000..08c3ab17cc26 --- /dev/null +++ b/packages/webview_flutter/webview_flutter/example/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,14 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.cs.allow-jit + + com.apple.security.network.server + + com.apple.security.network.client + + + diff --git a/packages/webview_flutter/webview_flutter/example/macos/Runner/Info.plist b/packages/webview_flutter/webview_flutter/example/macos/Runner/Info.plist new file mode 100644 index 000000000000..4789daa6a443 --- /dev/null +++ b/packages/webview_flutter/webview_flutter/example/macos/Runner/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + $(PRODUCT_COPYRIGHT) + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/packages/webview_flutter/webview_flutter/example/macos/Runner/MainFlutterWindow.swift b/packages/webview_flutter/webview_flutter/example/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 000000000000..f21908966e95 --- /dev/null +++ b/packages/webview_flutter/webview_flutter/example/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,19 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + + super.awakeFromNib() + } +} diff --git a/packages/webview_flutter/webview_flutter/example/macos/Runner/Release.entitlements b/packages/webview_flutter/webview_flutter/example/macos/Runner/Release.entitlements new file mode 100644 index 000000000000..ee95ab7e582d --- /dev/null +++ b/packages/webview_flutter/webview_flutter/example/macos/Runner/Release.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.network.client + + + diff --git a/packages/webview_flutter/webview_flutter/example/pubspec.yaml b/packages/webview_flutter/webview_flutter/example/pubspec.yaml index 7c5eb72fa977..1eb34f957ea0 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.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: @@ -17,12 +17,12 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - webview_flutter_android: ^3.16.0 + webview_flutter_android: ^4.0.0 webview_flutter_wkwebview: ^3.13.0 dev_dependencies: build_runner: ^2.1.5 - espresso: ^0.2.0 + espresso: ^0.4.0 flutter_test: sdk: flutter integration_test: diff --git a/packages/webview_flutter/webview_flutter/pubspec.yaml b/packages/webview_flutter/webview_flutter/pubspec.yaml index c48857425b2a..837800d7feef 100644 --- a/packages/webview_flutter/webview_flutter/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter/pubspec.yaml @@ -1,12 +1,12 @@ name: webview_flutter -description: A Flutter plugin that provides a WebView widget on Android and iOS. +description: A Flutter plugin that provides a WebView widget backed by the system webview. repository: https://github.com/flutter/packages/tree/main/packages/webview_flutter/webview_flutter issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22 -version: 4.8.0 +version: 4.10.0 environment: - sdk: ^3.2.3 - flutter: ">=3.16.6" + sdk: ^3.5.0 + flutter: ">=3.24.0" flutter: plugin: @@ -15,19 +15,21 @@ flutter: default_package: webview_flutter_android ios: default_package: webview_flutter_wkwebview + macos: + default_package: webview_flutter_wkwebview dependencies: flutter: sdk: flutter - webview_flutter_android: ^3.16.0 + webview_flutter_android: ^4.0.0 webview_flutter_platform_interface: ^2.10.0 - webview_flutter_wkwebview: ^3.13.0 + webview_flutter_wkwebview: ^3.15.0 dev_dependencies: build_runner: ^2.1.5 flutter_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 plugin_platform_interface: ^2.1.7 topics: diff --git a/packages/webview_flutter/webview_flutter_android/CHANGELOG.md b/packages/webview_flutter/webview_flutter_android/CHANGELOG.md index 0e2f151dbe92..c660eb72f10e 100644 --- a/packages/webview_flutter/webview_flutter_android/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter_android/CHANGELOG.md @@ -1,3 +1,33 @@ +## 4.0.1 + +* Adds `missing_code_block_language_in_doc_comment` lint. + +## 4.0.0 + +* Bumps androidx.webkit:webkit from 1.12.0 to 1.12.1. +* **Breaking Change** Bumps Android `minSdkVersion` from 19 to 21. + +## 3.16.9 + +* Updates Java compatibility version to 11. +* Updates minimum supported SDK version to Flutter 3.24/Dart 3.5. + +## 3.16.8 + +* Bumps androidx.webkit:webkit from 1.11.0 to 1.12.0. + +## 3.16.7 + +* Bumps androidx.annotation:annotation from 1.8.1 to 1.8.2. + +## 3.16.6 + +* Bumps androidx.annotation:annotation from 1.7.1 to 1.8.1. + +## 3.16.5 + +* Updates lint checks to ignore NewerVersionAvailable. + ## 3.16.4 * Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. diff --git a/packages/webview_flutter/webview_flutter_android/README.md b/packages/webview_flutter/webview_flutter_android/README.md index 1db03b3afdda..3b3d73306fe2 100644 --- a/packages/webview_flutter/webview_flutter_android/README.md +++ b/packages/webview_flutter/webview_flutter_android/README.md @@ -30,7 +30,7 @@ See: This is the current default mode for versions <23. It ensures that the WebView will display and work as expected, at the cost of some performance. See: -* https://flutter.dev/docs/development/platform-integration/platform-views#performance +* https://docs.flutter.dev/platform-integration/android/platform-views#performance This can be configured for versions >=23 with `AndroidWebViewWidgetCreationParams.displayWithHybridComposition`. See https://pub.dev/packages/webview_flutter#platform-specific-features @@ -89,7 +89,7 @@ dart run build_runner build --delete-conflicting-outputs If you would like to contribute to the plugin, check out our [contribution guide][5]. [1]: https://pub.dev/packages/webview_flutter -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin [3]: https://pub.dev/packages/pigeon [4]: https://pub.dev/packages/mockito [5]: https://github.com/flutter/packages/blob/main/CONTRIBUTING.md diff --git a/packages/webview_flutter/webview_flutter_android/android/build.gradle b/packages/webview_flutter/webview_flutter_android/android/build.gradle index 9592d2dec0d3..7e5bcc82d8fe 100644 --- a/packages/webview_flutter/webview_flutter_android/android/build.gradle +++ b/packages/webview_flutter/webview_flutter_android/android/build.gradle @@ -22,34 +22,31 @@ rootProject.allprojects { apply plugin: 'com.android.library' android { - // Conditional for compatibility with AGP <4.2. - if (project.android.hasProperty("namespace")) { - namespace 'io.flutter.plugins.webviewflutter' - } + namespace 'io.flutter.plugins.webviewflutter' compileSdk 34 defaultConfig { - minSdkVersion 19 + minSdkVersion 21 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } lintOptions { checkAllWarnings true warningsAsErrors true - disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency' + disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency', 'NewerVersionAvailable' } dependencies { - implementation 'androidx.annotation:annotation:1.7.1' - implementation 'androidx.webkit:webkit:1.11.0' + implementation 'androidx.annotation:annotation:1.8.2' + implementation 'androidx.webkit:webkit:1.12.1' testImplementation 'junit:junit:4.13.2' testImplementation 'org.mockito:mockito-inline:5.1.0' testImplementation 'androidx.test:core:1.3.0' } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } testOptions { diff --git a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/FileChooserParamsFlutterApiImpl.java b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/FileChooserParamsFlutterApiImpl.java index 5ad5923d5f2c..d0f5b9c4d64a 100644 --- a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/FileChooserParamsFlutterApiImpl.java +++ b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/FileChooserParamsFlutterApiImpl.java @@ -4,10 +4,8 @@ package io.flutter.plugins.webviewflutter; -import android.os.Build; import android.webkit.WebChromeClient; import androidx.annotation.NonNull; -import androidx.annotation.RequiresApi; import io.flutter.plugin.common.BinaryMessenger; import java.util.Arrays; @@ -17,7 +15,6 @@ *

Passes arguments of callbacks methods from a {@link * android.webkit.WebChromeClient.FileChooserParams} to Dart. */ -@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public class FileChooserParamsFlutterApiImpl extends GeneratedAndroidWebView.FileChooserParamsFlutterApi { private final InstanceManager instanceManager; diff --git a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/PermissionRequestHostApiImpl.java b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/PermissionRequestHostApiImpl.java index e4faf449adc8..2a7e6ccb58a0 100644 --- a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/PermissionRequestHostApiImpl.java +++ b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/PermissionRequestHostApiImpl.java @@ -4,10 +4,8 @@ package io.flutter.plugins.webviewflutter; -import android.os.Build; import android.webkit.PermissionRequest; import androidx.annotation.NonNull; -import androidx.annotation.RequiresApi; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugins.webviewflutter.GeneratedAndroidWebView.PermissionRequestHostApi; import java.util.List; @@ -19,7 +17,6 @@ *

This class may handle instantiating and adding native object instances that are attached to a * Dart instance or handle method calls on the associated native class or an instance of the class. */ -@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public class PermissionRequestHostApiImpl implements PermissionRequestHostApi { // To ease adding additional methods, this value is added prematurely. @SuppressWarnings({"unused", "FieldCanBeLocal"}) diff --git a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebChromeClientFlutterApiImpl.java b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebChromeClientFlutterApiImpl.java index d5601670630c..45a1c98adae1 100644 --- a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebChromeClientFlutterApiImpl.java +++ b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebChromeClientFlutterApiImpl.java @@ -4,7 +4,6 @@ package io.flutter.plugins.webviewflutter; -import android.os.Build; import android.view.View; import android.webkit.ConsoleMessage; import android.webkit.GeolocationPermissions; @@ -12,7 +11,6 @@ import android.webkit.WebChromeClient; import android.webkit.WebView; import androidx.annotation.NonNull; -import androidx.annotation.RequiresApi; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugins.webviewflutter.GeneratedAndroidWebView.WebChromeClientFlutterApi; import java.util.List; @@ -75,7 +73,6 @@ public void onProgressChanged( } /** Passes arguments from {@link WebChromeClient#onShowFileChooser} to Dart. */ - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public void onShowFileChooser( @NonNull WebChromeClient webChromeClient, @NonNull WebView webView, @@ -123,7 +120,6 @@ public void onGeolocationPermissionsHidePrompt( * Sends a message to Dart to call `WebChromeClient.onPermissionRequest` on the Dart object * representing `instance`. */ - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public void onPermissionRequest( @NonNull WebChromeClient instance, @NonNull PermissionRequest request, diff --git a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebChromeClientHostApiImpl.java b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebChromeClientHostApiImpl.java index 3f230b7b794f..2edb012c5350 100644 --- a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebChromeClientHostApiImpl.java +++ b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebChromeClientHostApiImpl.java @@ -83,7 +83,6 @@ public void onGeolocationPermissionsHidePrompt() { flutterApi.onGeolocationPermissionsHidePrompt(this, reply -> {}); } - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @SuppressWarnings("LambdaLast") @Override public boolean onShowFileChooser( @@ -109,7 +108,6 @@ public boolean onShowFileChooser( return currentReturnValueForOnShowFileChooser; } - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @Override public void onPermissionRequest(@NonNull PermissionRequest request) { flutterApi.onPermissionRequest(this, request, reply -> {}); diff --git a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewClientFlutterApiImpl.java b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewClientFlutterApiImpl.java index 0bd280d705b2..b94238bcb4b5 100644 --- a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewClientFlutterApiImpl.java +++ b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewClientFlutterApiImpl.java @@ -51,7 +51,6 @@ static GeneratedAndroidWebView.WebResourceErrorData createWebResourceErrorData( .build(); } - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) static GeneratedAndroidWebView.WebResourceRequestData createWebResourceRequestData( WebResourceRequest request) { final GeneratedAndroidWebView.WebResourceRequestData.Builder requestData = @@ -71,7 +70,6 @@ static GeneratedAndroidWebView.WebResourceRequestData createWebResourceRequestDa return requestData.build(); } - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) static GeneratedAndroidWebView.WebResourceResponseData createWebResourceResponseData( WebResourceResponse response) { final GeneratedAndroidWebView.WebResourceResponseData.Builder responseData = @@ -122,7 +120,6 @@ public void onPageFinished( } /** Passes arguments from {@link WebViewClient#onReceivedHttpError} to Dart. */ - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public void onReceivedHttpError( @NonNull WebViewClient webViewClient, @NonNull WebView webView, @@ -167,7 +164,6 @@ public void onReceivedRequestError( * Passes arguments from {@link androidx.webkit.WebViewClientCompat#onReceivedError(WebView, * WebResourceRequest, WebResourceError)} to Dart. */ - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public void onReceivedRequestError( @NonNull WebViewClient webViewClient, @NonNull WebView webView, @@ -214,7 +210,6 @@ public void onReceivedError( * Passes arguments from {@link WebViewClient#shouldOverrideUrlLoading(WebView, * WebResourceRequest)} to Dart. */ - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public void requestLoading( @NonNull WebViewClient webViewClient, @NonNull WebView webView, diff --git a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewClientHostApiImpl.java b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewClientHostApiImpl.java index fdc448279982..a71b5efbcc4f 100644 --- a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewClientHostApiImpl.java +++ b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewClientHostApiImpl.java @@ -4,8 +4,6 @@ package io.flutter.plugins.webviewflutter; -import android.annotation.SuppressLint; -import android.annotation.TargetApi; import android.graphics.Bitmap; import android.os.Build; import android.view.KeyEvent; @@ -152,7 +150,6 @@ public void onPageFinished(@NonNull WebView view, @NonNull String url) { flutterApi.onPageFinished(this, view, url, reply -> {}); } - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @Override public void onReceivedHttpError( @NonNull WebView view, @@ -161,10 +158,6 @@ public void onReceivedHttpError( flutterApi.onReceivedHttpError(this, view, request, response, reply -> {}); } - // This method is only called when the WebViewFeature.RECEIVE_WEB_RESOURCE_ERROR feature is - // enabled. The deprecated method is called when a device doesn't support this. - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) - @SuppressLint("RequiresFeature") @Override public void onReceivedError( @NonNull WebView view, @@ -185,7 +178,6 @@ public void onReceivedError( this, view, (long) errorCode, description, failingUrl, reply -> {}); } - @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public boolean shouldOverrideUrlLoading( @NonNull WebView view, @NonNull WebResourceRequest request) { diff --git a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterPlugin.java b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterPlugin.java index 3c73a4e4c31b..80c574badf81 100644 --- a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterPlugin.java +++ b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterPlugin.java @@ -5,7 +5,6 @@ package io.flutter.plugins.webviewflutter; import android.content.Context; -import android.os.Build; import android.os.Handler; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -109,11 +108,8 @@ private void setUp( WebStorageHostApi.setup( binaryMessenger, new WebStorageHostApiImpl(instanceManager, new WebStorageHostApiImpl.WebStorageCreator())); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - PermissionRequestHostApi.setup( - binaryMessenger, new PermissionRequestHostApiImpl(binaryMessenger, instanceManager)); - } + PermissionRequestHostApi.setup( + binaryMessenger, new PermissionRequestHostApiImpl(binaryMessenger, instanceManager)); GeolocationPermissionsCallbackHostApi.setup( binaryMessenger, new GeolocationPermissionsCallbackHostApiImpl(binaryMessenger, instanceManager)); diff --git a/packages/webview_flutter/webview_flutter_android/example/android/app/build.gradle b/packages/webview_flutter/webview_flutter_android/example/android/app/build.gradle index 095cb635c40c..04c7917f0a3a 100644 --- a/packages/webview_flutter/webview_flutter_android/example/android/app/build.gradle +++ b/packages/webview_flutter/webview_flutter_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.webviewflutterexample' compileSdk flutter.compileSdkVersion @@ -32,8 +30,8 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "io.flutter.plugins.webviewflutterandroidexample" - minSdkVersion 21 - targetSdkVersion 28 + minSdkVersion flutter.minSdkVersion + targetSdkVersion 34 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/packages/webview_flutter/webview_flutter_android/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/webview_flutter/webview_flutter_android/example/android/app/gradle/wrapper/gradle-wrapper.properties index 609ab8e6c8b5..d951fac2bf31 100644 --- a/packages/webview_flutter/webview_flutter_android/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ b/packages/webview_flutter/webview_flutter_android/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/packages/webview_flutter/webview_flutter_android/example/android/app/src/main/AndroidManifest.xml b/packages/webview_flutter/webview_flutter_android/example/android/app/src/main/AndroidManifest.xml index 8a28579c3795..e61c40369fdf 100644 --- a/packages/webview_flutter/webview_flutter_android/example/android/app/src/main/AndroidManifest.xml +++ b/packages/webview_flutter/webview_flutter_android/example/android/app/src/main/AndroidManifest.xml @@ -1,7 +1,10 @@ - + @@ -10,7 +13,8 @@ android:value="2" /> plugins.load(reader) } -} - -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.7.10" 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/webview_flutter/webview_flutter_android/example/integration_test/webview_flutter_test.dart b/packages/webview_flutter/webview_flutter_android/example/integration_test/webview_flutter_test.dart index 4c22df1ff28c..d5ed471afd36 100644 --- a/packages/webview_flutter/webview_flutter_android/example/integration_test/webview_flutter_test.dart +++ b/packages/webview_flutter/webview_flutter_android/example/integration_test/webview_flutter_test.dart @@ -867,7 +867,7 @@ Future main() async { await delegate.setOnPageFinished((_) => pageLoaded.complete()); await delegate .setOnNavigationRequest((NavigationRequest navigationRequest) { - return (navigationRequest.url.contains('youtube.com')) + return navigationRequest.url.contains('youtube.com') ? NavigationDecision.prevent : NavigationDecision.navigate; }); @@ -1059,7 +1059,7 @@ Future main() async { await delegate.setOnPageFinished((_) => pageLoaded.complete()); await delegate .setOnNavigationRequest((NavigationRequest navigationRequest) { - return (navigationRequest.url.contains('youtube.com')) + return navigationRequest.url.contains('youtube.com') ? NavigationDecision.prevent : NavigationDecision.navigate; }); diff --git a/packages/webview_flutter/webview_flutter_android/example/integration_test/webview_flutter_test_legacy.dart b/packages/webview_flutter/webview_flutter_android/example/integration_test/webview_flutter_test_legacy.dart index 2e7f3d0b8dd7..51f71d7801b8 100644 --- a/packages/webview_flutter/webview_flutter_android/example/integration_test/webview_flutter_test_legacy.dart +++ b/packages/webview_flutter/webview_flutter_android/example/integration_test/webview_flutter_test_legacy.dart @@ -1126,7 +1126,7 @@ Future main() async { }, javascriptMode: JavascriptMode.unrestricted, navigationDelegate: (NavigationRequest request) { - return (request.url.contains('youtube.com')) + return request.url.contains('youtube.com') ? NavigationDecision.prevent : NavigationDecision.navigate; }, @@ -1251,7 +1251,7 @@ Future main() async { }, javascriptMode: JavascriptMode.unrestricted, navigationDelegate: (NavigationRequest request) { - return (request.url.contains('youtube.com')) + return request.url.contains('youtube.com') ? NavigationDecision.prevent : NavigationDecision.navigate; }, diff --git a/packages/webview_flutter/webview_flutter_android/example/pubspec.yaml b/packages/webview_flutter/webview_flutter_android/example/pubspec.yaml index a79d03efb4c4..c22d7dc70220 100644 --- a/packages/webview_flutter/webview_flutter_android/example/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_android/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the webview_flutter_android plugin. publish_to: none environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" dependencies: flutter: @@ -20,7 +20,7 @@ dependencies: webview_flutter_platform_interface: ^2.10.0 dev_dependencies: - espresso: ^0.2.0 + espresso: ^0.4.0 flutter_test: sdk: flutter integration_test: 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 d2b67145d2bc..3a410362af21 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 @@ -955,7 +955,7 @@ class AndroidWebViewWidgetCreationParams /// For most use cases, this flag should be set to false. Hybrid Composition /// can have performance costs but doesn't have the limitation of rendering to /// an Android SurfaceTexture. See - /// * https://flutter.dev/docs/development/platform-integration/platform-views#performance + /// * https://docs.flutter.dev/platform-integration/android/platform-views#performance /// * https://github.com/flutter/flutter/issues/104889 /// * https://github.com/flutter/flutter/issues/116954 /// diff --git a/packages/webview_flutter/webview_flutter_android/lib/src/weak_reference_utils.dart b/packages/webview_flutter/webview_flutter_android/lib/src/weak_reference_utils.dart index fc247f8b60f7..f12485ad6e71 100644 --- a/packages/webview_flutter/webview_flutter_android/lib/src/weak_reference_utils.dart +++ b/packages/webview_flutter/webview_flutter_android/lib/src/weak_reference_utils.dart @@ -5,7 +5,7 @@ /// Helper method for creating callbacks methods with a weak reference. /// /// Example: -/// ``` +/// ```dart /// final JavascriptChannelRegistry javascriptChannelRegistry = ... /// /// final WKScriptMessageHandler handler = WKScriptMessageHandler( diff --git a/packages/webview_flutter/webview_flutter_android/pubspec.yaml b/packages/webview_flutter/webview_flutter_android/pubspec.yaml index 5a283b9acfca..2b8bf262b1cd 100644 --- a/packages/webview_flutter/webview_flutter_android/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_android/pubspec.yaml @@ -2,11 +2,11 @@ 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: 3.16.4 +version: 4.0.1 environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" flutter: plugin: @@ -26,7 +26,7 @@ dev_dependencies: build_runner: ^2.1.4 flutter_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 pigeon: ^11.0.0 topics: diff --git a/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md b/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md index fbad8878042f..f6b57b5e1a5c 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.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 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 e5eb3c6b901e..c7cb7f96eba1 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: @@ -20,7 +20,7 @@ dev_dependencies: build_runner: ^2.1.8 flutter_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 topics: - html diff --git a/packages/webview_flutter/webview_flutter_web/CHANGELOG.md b/packages/webview_flutter/webview_flutter_web/CHANGELOG.md index 87645f14d734..abe9eee1f0c2 100644 --- a/packages/webview_flutter/webview_flutter_web/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter_web/CHANGELOG.md @@ -1,6 +1,22 @@ -## NEXT +## 0.2.3+3 -* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. +* Adds `missing_code_block_language_in_doc_comment` lint. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + +## 0.2.3+2 + +* Adds support for `web: ^1.0.0`. + +## 0.2.3+1 + +* Fixes DOM timing issue with Legacy Widget build method. + +## 0.2.3 + +* Migrates to `package:web` +* Updates `HttpRequestFactory.request` to use the Fetch API. +* Updates `index.html` in the example to use `flutter_bootstrap.js` +* Updates minimum supported SDK version to Flutter 3.16/Dart 3.3. ## 0.2.2+4 diff --git a/packages/webview_flutter/webview_flutter_web/example/integration_test/legacy/webview_flutter_test.dart b/packages/webview_flutter/webview_flutter_web/example/integration_test/legacy/webview_flutter_test.dart deleted file mode 100644 index affd7bbda224..000000000000 --- a/packages/webview_flutter/webview_flutter_web/example/integration_test/legacy/webview_flutter_test.dart +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:async'; -import 'dart:html' as html; -import 'dart:io'; - -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:integration_test/integration_test.dart'; -import 'package:webview_flutter_web_example/legacy/web_view.dart'; - -void main() async { - IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - - const String primaryPage = 'first.txt'; - const String secondaryPage = 'second.txt'; - final HttpServer server = - await HttpServer.bind(InternetAddress.loopbackIPv4, 0); - unawaited(server.forEach((HttpRequest request) { - if (request.uri.path == '/$primaryPage') { - request.response.writeln('Hello, world.'); - } - if (request.uri.path == '/$secondaryPage') { - request.response.writeln('Another page.'); - } else { - fail('unexpected request: ${request.method} ${request.uri}'); - } - request.response.close(); - })); - final String prefixUrl = 'http://localhost:${server.port}'; - final String primaryUrl = '$prefixUrl/$primaryPage'; - final String secondaryUrl = '$prefixUrl/$secondaryPage'; - - testWidgets('initialUrl', (WidgetTester tester) async { - final Completer controllerCompleter = - Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: WebView( - key: GlobalKey(), - initialUrl: primaryUrl, - onWebViewCreated: (WebViewController controller) { - controllerCompleter.complete(controller); - }, - ), - ), - ); - await controllerCompleter.future; - - // Assert an iframe has been rendered to the DOM with the correct src attribute. - final html.IFrameElement? element = - html.document.querySelector('iframe') as html.IFrameElement?; - expect(element, isNotNull); - expect(element!.src, primaryUrl); - }); - - testWidgets('loadUrl', (WidgetTester tester) async { - final Completer controllerCompleter = - Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: WebView( - key: GlobalKey(), - initialUrl: primaryUrl, - onWebViewCreated: (WebViewController controller) { - controllerCompleter.complete(controller); - }, - ), - ), - ); - final WebViewController controller = await controllerCompleter.future; - await controller.loadUrl(secondaryUrl); - - // Assert an iframe has been rendered to the DOM with the correct src attribute. - final html.IFrameElement? element = - html.document.querySelector('iframe') as html.IFrameElement?; - expect(element, isNotNull); - expect(element!.src, secondaryUrl); - }); -} diff --git a/packages/webview_flutter/webview_flutter_web/example/integration_test/legacy_webview_flutter_test_manual.dart b/packages/webview_flutter/webview_flutter_web/example/integration_test/legacy_webview_flutter_test_manual.dart new file mode 100644 index 000000000000..173de6bd6dc4 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_web/example/integration_test/legacy_webview_flutter_test_manual.dart @@ -0,0 +1,63 @@ +// 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. + +// This test flakes badly in headless mode! + +import 'dart:async'; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; +import 'package:web/web.dart' as web; +import 'package:webview_flutter_web_example/legacy/web_view.dart'; + +import 'wrapped_webview.dart'; + +void main() async { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + const String someUrl = 'about:blank'; + const String fakeUrl = 'https://www.flutter.dev/'; + + testWidgets('initialUrl', (WidgetTester tester) async { + final Completer controllerCompleter = + Completer(); + await tester.pumpWidget( + wrappedLegacyWebView(fakeUrl, (WebViewController controller) { + controllerCompleter.complete(controller); + }), + ); + await controllerCompleter.future; + // Pump 2 frames so the framework injects the platform view into the DOM. + await tester.pump(); + await tester.pump(const Duration(seconds: 5)); + + // Assert an iframe has been rendered to the DOM with the correct src attribute. + final web.HTMLIFrameElement? element = + web.document.querySelector('iframe') as web.HTMLIFrameElement?; + expect(element, isNotNull); + expect(element!.src, fakeUrl); + }); + + testWidgets('loadUrl', (WidgetTester tester) async { + final Completer controllerCompleter = + Completer(); + await tester.pumpWidget( + wrappedLegacyWebView(someUrl, (WebViewController controller) { + controllerCompleter.complete(controller); + }), + ); + + final WebViewController controller = await controllerCompleter.future; + await controller.loadUrl(fakeUrl); + // Pump 2 frames so the framework injects the platform view into the DOM. + await tester.pump(); + await tester.pump(const Duration(seconds: 5)); + + // Assert an iframe has been rendered to the DOM with the correct src attribute. + final web.HTMLIFrameElement? element = + web.document.querySelector('iframe') as web.HTMLIFrameElement?; + expect(element, isNotNull); + expect(element!.src, fakeUrl); + }); +} diff --git a/packages/webview_flutter/webview_flutter_web/example/integration_test/webview_flutter_test.dart b/packages/webview_flutter/webview_flutter_web/example/integration_test/webview_flutter_test.dart index 734ace71fa36..56fd4eee6229 100644 --- a/packages/webview_flutter/webview_flutter_web/example/integration_test/webview_flutter_test.dart +++ b/packages/webview_flutter/webview_flutter_web/example/integration_test/webview_flutter_test.dart @@ -2,82 +2,63 @@ // 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:html' as html; -import 'dart:io'; - -// FIX (dit): Remove these integration tests, or make them run. They currently never fail. -// (They won't run because they use `dart:io`. If you remove all `dart:io` bits from -// this file, they start failing with `fail()`, for example.) - -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; +import 'package:web/web.dart' as web; import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart'; import 'package:webview_flutter_web/webview_flutter_web.dart'; +import 'wrapped_webview.dart'; + Future main() async { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - final HttpServer server = await HttpServer.bind(InternetAddress.anyIPv4, 0); - unawaited(server.forEach((HttpRequest request) { - if (request.uri.path == '/hello.txt') { - request.response.writeln('Hello, world.'); - } else { - fail('unexpected request: ${request.method} ${request.uri}'); - } - request.response.close(); - })); - final String prefixUrl = 'http://${server.address.address}:${server.port}'; - final String primaryUrl = '$prefixUrl/hello.txt'; + const String fakeUrl = 'about:blank'; testWidgets('loadRequest', (WidgetTester tester) async { - final WebWebViewController controller = - WebWebViewController(const PlatformWebViewControllerCreationParams()); + final WebWebViewController controller = WebWebViewController( + const PlatformWebViewControllerCreationParams(), + ); await controller.loadRequest( - LoadRequestParams(uri: Uri.parse(primaryUrl)), + LoadRequestParams(uri: Uri.parse(fakeUrl)), ); await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: Builder(builder: (BuildContext context) { - return WebWebViewWidget( - PlatformWebViewWidgetCreationParams(controller: controller), - ).build(context); - }), - ), + wrappedWebView(controller), ); + // Pump 2 frames so the framework injects the platform view into the DOM. + // The duration of the second pump is set so the browser has some idle time + // to actually show the contents of the iFrame. + await tester.pump(); + await tester.pump(const Duration(seconds: 1)); - // Assert an iframe has been rendered to the DOM with the correct src attribute. - final html.IFrameElement? element = - html.document.querySelector('iframe') as html.IFrameElement?; + // Assert an iFrame has been rendered to the DOM with the correct src attribute. + final web.HTMLIFrameElement? element = + web.document.querySelector('iframe') as web.HTMLIFrameElement?; expect(element, isNotNull); - expect(element!.src, primaryUrl); + expect(element!.src, fakeUrl); }); testWidgets('loadHtmlString', (WidgetTester tester) async { - final WebWebViewController controller = - WebWebViewController(const PlatformWebViewControllerCreationParams()); + final WebWebViewController controller = WebWebViewController( + const PlatformWebViewControllerCreationParams(), + ); await controller.loadHtmlString( 'data:text/html;charset=utf-8,${Uri.encodeFull('test html')}', ); await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: Builder(builder: (BuildContext context) { - return WebWebViewWidget( - PlatformWebViewWidgetCreationParams(controller: controller), - ).build(context); - }), - ), + wrappedWebView(controller), ); + // Pump 2 frames so the framework injects the platform view into the DOM. + // The duration of the second pump is set so the browser has some idle time + // to actually show the contents of the iFrame. + await tester.pump(); + await tester.pump(const Duration(seconds: 1)); - // Assert an iframe has been rendered to the DOM with the correct src attribute. - final html.IFrameElement? element = - html.document.querySelector('iframe') as html.IFrameElement?; + // Assert an iFrame has been rendered to the DOM with the correct src attribute. + final web.HTMLIFrameElement? element = + web.document.querySelector('iframe') as web.HTMLIFrameElement?; expect(element, isNotNull); expect( element!.src, diff --git a/packages/webview_flutter/webview_flutter_web/example/integration_test/wrapped_webview.dart b/packages/webview_flutter/webview_flutter_web/example/integration_test/wrapped_webview.dart new file mode 100644 index 000000000000..0dc10cbf5c2d --- /dev/null +++ b/packages/webview_flutter/webview_flutter_web/example/integration_test/wrapped_webview.dart @@ -0,0 +1,51 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart'; +import 'package:webview_flutter_web/webview_flutter_web.dart'; +import 'package:webview_flutter_web_example/legacy/web_view.dart'; + +/// Returns the webview widget for a given [controller], wrapped so it works +/// in our integration tests. +Widget wrappedWebView(WebWebViewController controller) { + return _wrapped( + Builder( + builder: (BuildContext ctx) => PlatformWebViewWidget( + PlatformWebViewWidgetCreationParams(controller: controller), + ).build(ctx), + ), + ); +} + +/// Returns a (legacy) webview widget for an [url], that calls [onCreated] when +/// done, wrapped so it works in our integration tests. +Widget wrappedLegacyWebView(String url, WebViewCreatedCallback onCreated) { + return _wrapped( + WebView( + initialUrl: url, + onWebViewCreated: onCreated, + ), + ); +} + +// Wraps a [child] widget in the scaffolding this test needs. +Widget _wrapped(Widget child) { + return MaterialApp( + home: Scaffold( + body: Center( + child: Container( + decoration: BoxDecoration( + border: Border.all( + color: Colors.red, + ), + ), + width: 320, + height: 200, + child: child, + ), + ), + ), + ); +} diff --git a/packages/webview_flutter/webview_flutter_web/example/pubspec.yaml b/packages/webview_flutter/webview_flutter_web/example/pubspec.yaml index 23754739bf48..55e7e6553261 100644 --- a/packages/webview_flutter/webview_flutter_web/example/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_web/example/pubspec.yaml @@ -3,14 +3,15 @@ description: Demonstrates how to use the webview_flutter_web plugin. publish_to: none environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: sdk: flutter flutter_web_plugins: sdk: flutter + web: ^1.0.0 webview_flutter_platform_interface: ^2.0.0 webview_flutter_web: # When depending on this package from a real application you should use: diff --git a/packages/webview_flutter/webview_flutter_web/example/web/index.html b/packages/webview_flutter/webview_flutter_web/example/web/index.html index 8b8b5bf92f89..faf1f7e92cc0 100644 --- a/packages/webview_flutter/webview_flutter_web/example/web/index.html +++ b/packages/webview_flutter/webview_flutter_web/example/web/index.html @@ -3,6 +3,7 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> + - + https://developers.google.com/web/fundamentals/primers/service-workers --> + - + + \ No newline at end of file diff --git a/packages/webview_flutter/webview_flutter_web/lib/src/http_request_factory.dart b/packages/webview_flutter/webview_flutter_web/lib/src/http_request_factory.dart index 4bd92f0db1db..1500921201b8 100644 --- a/packages/webview_flutter/webview_flutter_web/lib/src/http_request_factory.dart +++ b/packages/webview_flutter/webview_flutter_web/lib/src/http_request_factory.dart @@ -2,7 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:html'; +import 'dart:async'; +import 'dart:js_interop'; +import 'dart:typed_data'; + +import 'package:web/web.dart' as web; /// Factory class for creating [HttpRequest] instances. class HttpRequestFactory { @@ -11,20 +15,16 @@ class HttpRequestFactory { /// Creates and sends a URL request for the specified [url]. /// + /// Returns an `Object` (so this class can be mocked by mockito), which can be + /// cast as [web.Response] from `package:web`. + /// /// By default `request` will perform an HTTP GET request, but a different /// method (`POST`, `PUT`, `DELETE`, etc) can be used by specifying the - /// [method] parameter. (See also [HttpRequest.postFormData] for `POST` - /// requests only. - /// - /// The Future is completed when the response is available. + /// [method] parameter. /// - /// If specified, `sendData` will send data in the form of a [ByteBuffer], - /// [Blob], [Document], [String], or [FormData] along with the HttpRequest. + /// The Future is completed when the [web.Response] is available. /// - /// If specified, [responseType] sets the desired response format for the - /// request. By default it is [String], but can also be 'arraybuffer', 'blob', - /// 'document', 'json', or 'text'. See also [HttpRequest.responseType] - /// for more information. + /// If specified, [sendData] will be sent as the `body` of the fetch. /// /// The [withCredentials] parameter specified that credentials such as a cookie /// (already) set in the header or @@ -39,43 +39,53 @@ class HttpRequestFactory { /// /// The following is equivalent to the [getString] sample above: /// - /// var name = Uri.encodeQueryComponent('John'); - /// var id = Uri.encodeQueryComponent('42'); - /// HttpRequest.request('users.json?name=$name&id=$id') - /// .then((HttpRequest resp) { - /// // Do something with the response. - /// }); + /// ```dart + /// var name = Uri.encodeQueryComponent('John'); + /// var id = Uri.encodeQueryComponent('42'); + /// HttpRequest.request('users.json?name=$name&id=$id') + /// .then((HttpRequest resp) { + /// // Do something with the response. + /// }); + /// ``` /// /// Here's an example of submitting an entire form with [FormData]. /// - /// var myForm = querySelector('form#myForm'); - /// var data = new FormData(myForm); - /// HttpRequest.request('/submit', method: 'POST', sendData: data) - /// .then((HttpRequest resp) { - /// // Do something with the response. - /// }); + /// ```dart + /// var myForm = querySelector('form#myForm'); + /// var data = new FormData(myForm); + /// HttpRequest.request('/submit', method: 'POST', sendData: data) + /// .then((HttpRequest resp) { + /// // Do something with the response. + /// }); + /// ``` /// - /// Note that requests for file:// URIs are only supported by Chrome extensions + /// Requests for `file://` URIs are only supported by Chrome extensions /// with appropriate permissions in their manifest. Requests to file:// URIs /// will also never fail- the Future will always complete successfully, even /// when the file cannot be found. /// /// See also: [authorization headers](http://en.wikipedia.org/wiki/Basic_access_authentication). - Future request(String url, - {String? method, - bool? withCredentials, - String? responseType, - String? mimeType, - Map? requestHeaders, - dynamic sendData, - void Function(ProgressEvent e)? onProgress}) { - return HttpRequest.request(url, - method: method, - withCredentials: withCredentials, - responseType: responseType, - mimeType: mimeType, - requestHeaders: requestHeaders, - sendData: sendData, - onProgress: onProgress); + Future request( + String url, { + String method = 'GET', + bool withCredentials = false, + String? mimeType, + Map? requestHeaders, + Uint8List? sendData, + }) async { + final Map headers = { + if (mimeType != null) 'content-type': mimeType, + ...?requestHeaders, + }; + return web.window + .fetch( + url.toJS, + web.RequestInit( + method: method, + body: sendData?.toJS, + credentials: withCredentials ? 'include' : 'same-origin', + headers: headers.jsify()! as web.HeadersInit, + )) + .toDart; } } diff --git a/packages/webview_flutter/webview_flutter_web/lib/src/web_webview_controller.dart b/packages/webview_flutter/webview_flutter_web/lib/src/web_webview_controller.dart index 79f28b858bfb..d18987223a11 100644 --- a/packages/webview_flutter/webview_flutter_web/lib/src/web_webview_controller.dart +++ b/packages/webview_flutter/webview_flutter_web/lib/src/web_webview_controller.dart @@ -3,10 +3,11 @@ // found in the LICENSE file. import 'dart:convert'; -import 'dart:html' as html; +import 'dart:js_interop'; import 'dart:ui_web' as ui_web; -import 'package:flutter/cupertino.dart'; +import 'package:flutter/widgets.dart'; +import 'package:web/web.dart' as web; import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart'; import 'content_type.dart'; @@ -38,7 +39,7 @@ class WebWebViewControllerCreationParams /// The underlying element used as the WebView. @visibleForTesting - final html.IFrameElement iFrame = html.IFrameElement() + final web.HTMLIFrameElement iFrame = web.HTMLIFrameElement() ..id = 'webView${_nextIFrameId++}' ..style.width = '100%' ..style.height = '100%' @@ -59,7 +60,6 @@ class WebWebViewController extends PlatformWebViewController { @override Future loadHtmlString(String html, {String? baseUrl}) async { - // ignore: unsafe_html _webWebViewParams.iFrame.src = Uri.dataFromString( html, mimeType: 'text/html', @@ -77,7 +77,6 @@ class WebWebViewController extends PlatformWebViewController { if (params.headers.isEmpty && (params.body == null || params.body!.isEmpty) && params.method == LoadRequestMethod.get) { - // ignore: unsafe_html _webWebViewParams.iFrame.src = params.uri.toString(); } else { await _updateIFrameFromXhr(params); @@ -86,22 +85,20 @@ class WebWebViewController extends PlatformWebViewController { /// Performs an AJAX request defined by [params]. Future _updateIFrameFromXhr(LoadRequestParams params) async { - final html.HttpRequest httpReq = + final web.Response response = await _webWebViewParams.httpRequestFactory.request( params.uri.toString(), method: params.method.serialize(), requestHeaders: params.headers, sendData: params.body, - ); + ) as web.Response; - final String header = - httpReq.getResponseHeader('content-type') ?? 'text/html'; + final String header = response.headers.get('content-type') ?? 'text/html'; final ContentType contentType = ContentType.parse(header); final Encoding encoding = Encoding.getByName(contentType.charset) ?? utf8; - // ignore: unsafe_html _webWebViewParams.iFrame.src = Uri.dataFromString( - httpReq.responseText ?? '', + (await response.text().toDart).toDart, mimeType: contentType.mimeType, encoding: encoding, ).toString(); diff --git a/packages/webview_flutter/webview_flutter_web/lib/src/webview_flutter_web_legacy.dart b/packages/webview_flutter/webview_flutter_web/lib/src/webview_flutter_web_legacy.dart index 1f83bf440be7..4471ce6fed66 100644 --- a/packages/webview_flutter/webview_flutter_web/lib/src/webview_flutter_web_legacy.dart +++ b/packages/webview_flutter/webview_flutter_web/lib/src/webview_flutter_web_legacy.dart @@ -4,32 +4,22 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:html'; -import 'dart:ui_web' as ui_web; +import 'dart:js_interop'; import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; +import 'package:web/web.dart' as web; // ignore: implementation_imports import 'package:webview_flutter_platform_interface/src/webview_flutter_platform_interface_legacy.dart'; + import 'http_request_factory.dart'; /// Builds an iframe based WebView. /// /// This is used as the default implementation for [WebView.platform] on web. class WebWebViewPlatform implements WebViewPlatform { - /// Constructs a new instance of [WebWebViewPlatform]. - WebWebViewPlatform() { - ui_web.platformViewRegistry.registerViewFactory( - 'webview-iframe', - (int viewId) => IFrameElement() - ..id = 'webview-$viewId' - ..width = '100%' - ..height = '100%' - ..style.border = 'none'); - } - @override Widget build({ required BuildContext context, @@ -39,21 +29,20 @@ class WebWebViewPlatform implements WebViewPlatform { WebViewPlatformCreatedCallback? onWebViewPlatformCreated, Set>? gestureRecognizers, }) { - return HtmlElementView( - viewType: 'webview-iframe', - onPlatformViewCreated: (int viewId) { - if (onWebViewPlatformCreated == null) { - return; + return HtmlElementView.fromTagName( + tagName: 'iframe', + onElementCreated: (Object iFrame) { + iFrame as web.HTMLIFrameElement; + iFrame.style.border = 'none'; + final String? initialUrl = creationParams.initialUrl; + if (initialUrl != null) { + iFrame.src = initialUrl; } - final IFrameElement element = - document.getElementById('webview-$viewId')! as IFrameElement; - if (creationParams.initialUrl != null) { - // ignore: unsafe_html - element.src = creationParams.initialUrl; + if (onWebViewPlatformCreated != null) { + onWebViewPlatformCreated( + WebWebViewPlatformController(iFrame), + ); } - onWebViewPlatformCreated(WebWebViewPlatformController( - element, - )); }, ); } @@ -70,7 +59,7 @@ class WebWebViewPlatformController implements WebViewPlatformController { /// Constructs a [WebWebViewPlatformController]. WebWebViewPlatformController(this._element); - final IFrameElement _element; + final web.HTMLIFrameElement _element; HttpRequestFactory _httpRequestFactory = const HttpRequestFactory(); /// Setter for setting the HttpRequestFactory, for testing purposes. @@ -137,7 +126,6 @@ class WebWebViewPlatformController implements WebViewPlatformController { @override Future loadUrl(String url, Map? headers) async { - // ignore: unsafe_html _element.src = url; } @@ -186,7 +174,6 @@ class WebWebViewPlatformController implements WebViewPlatformController { String html, { String? baseUrl, }) async { - // ignore: unsafe_html _element.src = Uri.dataFromString( html, mimeType: 'text/html', @@ -199,16 +186,17 @@ class WebWebViewPlatformController implements WebViewPlatformController { if (!request.uri.hasScheme) { throw ArgumentError('WebViewRequest#uri is required to have a scheme.'); } - final HttpRequest httpReq = await _httpRequestFactory.request( + final web.Response response = await _httpRequestFactory.request( request.uri.toString(), method: request.method.serialize(), requestHeaders: request.headers, - sendData: request.body); + sendData: request.body) as web.Response; + final String contentType = - httpReq.getResponseHeader('content-type') ?? 'text/html'; - // ignore: unsafe_html + response.headers.get('content-type') ?? 'text/html'; + _element.src = Uri.dataFromString( - httpReq.responseText ?? '', + (await response.text().toDart).toDart, mimeType: contentType, encoding: utf8, ).toString(); diff --git a/packages/webview_flutter/webview_flutter_web/pubspec.yaml b/packages/webview_flutter/webview_flutter_web/pubspec.yaml index 484c795b4a73..6ca56109b377 100644 --- a/packages/webview_flutter/webview_flutter_web/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_web/pubspec.yaml @@ -2,11 +2,11 @@ name: webview_flutter_web description: A Flutter plugin that provides a WebView widget on web. repository: https://github.com/flutter/packages/tree/main/packages/webview_flutter/webview_flutter_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22 -version: 0.2.2+4 +version: 0.2.3+3 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: @@ -21,13 +21,14 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter + web: ">=0.5.1 <2.0.0" webview_flutter_platform_interface: ^2.0.0 dev_dependencies: build_runner: ^2.1.5 flutter_test: sdk: flutter - mockito: 5.4.4 + mockito: ^5.4.4 topics: - html diff --git a/packages/webview_flutter/webview_flutter_web/test/legacy/webview_flutter_web_test.dart b/packages/webview_flutter/webview_flutter_web/test/legacy/webview_flutter_web_test.dart index 54e53bb11925..22e2a06e66ec 100644 --- a/packages/webview_flutter/webview_flutter_web/test/legacy/webview_flutter_web_test.dart +++ b/packages/webview_flutter/webview_flutter_web/test/legacy/webview_flutter_web_test.dart @@ -2,13 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:html'; +import 'dart:js_interop'; import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; +import 'package:web/web.dart' as web; import 'package:webview_flutter_platform_interface/src/webview_flutter_platform_interface_legacy.dart'; import 'package:webview_flutter_web/src/http_request_factory.dart'; import 'package:webview_flutter_web/src/webview_flutter_web_legacy.dart'; @@ -16,12 +17,10 @@ import 'package:webview_flutter_web/src/webview_flutter_web_legacy.dart'; import 'webview_flutter_web_test.mocks.dart'; @GenerateMocks([ - IFrameElement, BuildContext, CreationParams, WebViewPlatformCallbacksHandler, HttpRequestFactory, - HttpRequest, ]) void main() { TestWidgetsFlutterBinding.ensureInitialized(); @@ -45,54 +44,47 @@ void main() { group('WebWebViewPlatformController', () { test('loadUrl sets url on iframe src attribute', () { // Setup - final MockIFrameElement mockElement = MockIFrameElement(); + final web.HTMLIFrameElement fakeIFrame = web.HTMLIFrameElement(); final WebWebViewPlatformController controller = - WebWebViewPlatformController( - mockElement, - ); + WebWebViewPlatformController(fakeIFrame); // Run - controller.loadUrl('test url', null); + controller.loadUrl('http://example.com/', null); // Verify - verify(mockElement.src = 'test url'); + expect(fakeIFrame.src, 'http://example.com/'); }); group('loadHtmlString', () { test('loadHtmlString loads html into iframe', () { // Setup - final MockIFrameElement mockElement = MockIFrameElement(); + final web.HTMLIFrameElement fakeIFrame = web.HTMLIFrameElement(); final WebWebViewPlatformController controller = - WebWebViewPlatformController( - mockElement, - ); + WebWebViewPlatformController(fakeIFrame); // Run controller.loadHtmlString('test html'); // Verify - verify(mockElement.src = + expect(fakeIFrame.src, 'data:text/html;charset=utf-8,${Uri.encodeFull('test html')}'); }); test('loadHtmlString escapes "#" correctly', () { // Setup - final MockIFrameElement mockElement = MockIFrameElement(); + final web.HTMLIFrameElement fakeIFrame = web.HTMLIFrameElement(); final WebWebViewPlatformController controller = - WebWebViewPlatformController( - mockElement, - ); + WebWebViewPlatformController(fakeIFrame); // Run controller.loadHtmlString('#'); // Verify - verify(mockElement.src = argThat(contains('%23'))); + expect(fakeIFrame.src, contains('%23')); }); }); group('loadRequest', () { test('loadRequest throws ArgumentError on missing scheme', () { // Setup - final MockIFrameElement mockElement = MockIFrameElement(); + final web.HTMLIFrameElement fakeIFrame = web.HTMLIFrameElement(); final WebWebViewPlatformController controller = - WebWebViewPlatformController( - mockElement, - ); + WebWebViewPlatformController(fakeIFrame); + // Run & Verify expect( () async => controller.loadRequest( @@ -107,15 +99,18 @@ void main() { test('loadRequest makes request and loads response into iframe', () async { // Setup - final MockIFrameElement mockElement = MockIFrameElement(); + final web.HTMLIFrameElement fakeIFrame = web.HTMLIFrameElement(); final WebWebViewPlatformController controller = - WebWebViewPlatformController( - mockElement, - ); - final MockHttpRequest mockHttpRequest = MockHttpRequest(); - when(mockHttpRequest.getResponseHeader('content-type')) - .thenReturn('text/plain'); - when(mockHttpRequest.responseText).thenReturn('test data'); + WebWebViewPlatformController(fakeIFrame); + + final web.Response fakeResponse = web.Response( + 'test data'.toJS, + { + 'headers': { + 'content-type': 'text/plain', + }, + }.jsify()! as web.ResponseInit); + final MockHttpRequestFactory mockHttpRequestFactory = MockHttpRequestFactory(); when(mockHttpRequestFactory.request( @@ -123,8 +118,10 @@ void main() { method: anyNamed('method'), requestHeaders: anyNamed('requestHeaders'), sendData: anyNamed('sendData'), - )).thenAnswer((_) => Future.value(mockHttpRequest)); + )).thenAnswer((_) => Future.value(fakeResponse)); + controller.httpRequestFactory = mockHttpRequestFactory; + // Run await controller.loadRequest( WebViewRequest( @@ -140,21 +137,25 @@ void main() { requestHeaders: {'Foo': 'Bar'}, sendData: Uint8List.fromList('test body'.codeUnits), )); - verify(mockElement.src = + + expect(fakeIFrame.src, 'data:;charset=utf-8,${Uri.encodeFull('test data')}'); }); test('loadRequest escapes "#" correctly', () async { // Setup - final MockIFrameElement mockElement = MockIFrameElement(); + final web.HTMLIFrameElement fakeIFrame = web.HTMLIFrameElement(); final WebWebViewPlatformController controller = - WebWebViewPlatformController( - mockElement, - ); - final MockHttpRequest mockHttpRequest = MockHttpRequest(); - when(mockHttpRequest.getResponseHeader('content-type')) - .thenReturn('text/html'); - when(mockHttpRequest.responseText).thenReturn('#'); + WebWebViewPlatformController(fakeIFrame); + + final web.Response fakeResponse = web.Response( + '#'.toJS, + { + 'headers': { + 'content-type': 'text/html', + }, + }.jsify()! as web.ResponseInit); + final MockHttpRequestFactory mockHttpRequestFactory = MockHttpRequestFactory(); when(mockHttpRequestFactory.request( @@ -162,8 +163,10 @@ void main() { method: anyNamed('method'), requestHeaders: anyNamed('requestHeaders'), sendData: anyNamed('sendData'), - )).thenAnswer((_) => Future.value(mockHttpRequest)); + )).thenAnswer((_) => Future.value(fakeResponse)); + controller.httpRequestFactory = mockHttpRequestFactory; + // Run await controller.loadRequest( WebViewRequest( @@ -172,8 +175,8 @@ void main() { body: Uint8List.fromList('test body'.codeUnits), headers: {'Foo': 'Bar'}), ); - // Verify - verify(mockElement.src = argThat(contains('%23'))); + + expect(fakeIFrame.src, contains('%23')); }); }); }); diff --git a/packages/webview_flutter/webview_flutter_web/test/legacy/webview_flutter_web_test.mocks.dart b/packages/webview_flutter/webview_flutter_web/test/legacy/webview_flutter_web_test.mocks.dart index 08d5dfc7b356..896f9e397f0b 100644 --- a/packages/webview_flutter/webview_flutter_web/test/legacy/webview_flutter_web_test.mocks.dart +++ b/packages/webview_flutter/webview_flutter_web/test/legacy/webview_flutter_web_test.mocks.dart @@ -4,19 +4,17 @@ // ignore_for_file: no_leading_underscores_for_library_prefixes import 'dart:async' as _i7; -import 'dart:html' as _i2; -import 'dart:math' as _i3; +import 'dart:typed_data' as _i9; -import 'package:flutter/foundation.dart' as _i5; -import 'package:flutter/src/widgets/notification_listener.dart' as _i8; -import 'package:flutter/widgets.dart' as _i4; +import 'package:flutter/foundation.dart' as _i3; +import 'package:flutter/src/widgets/notification_listener.dart' as _i4; +import 'package:flutter/widgets.dart' as _i2; import 'package:mockito/mockito.dart' as _i1; -import 'package:mockito/src/dummies.dart' as _i6; import 'package:webview_flutter_platform_interface/src/legacy/platform_interface/webview_platform_callbacks_handler.dart' - as _i10; + as _i6; import 'package:webview_flutter_platform_interface/src/legacy/types/types.dart' - as _i9; -import 'package:webview_flutter_web/src/http_request_factory.dart' as _i11; + as _i5; +import 'package:webview_flutter_web/src/http_request_factory.dart' as _i8; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -31,2317 +29,79 @@ import 'package:webview_flutter_web/src/http_request_factory.dart' as _i11; // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class -class _FakeCssClassSet_0 extends _i1.SmartFake implements _i2.CssClassSet { - _FakeCssClassSet_0( +class _FakeWidget_0 extends _i1.SmartFake implements _i2.Widget { + _FakeWidget_0( Object parent, Invocation parentInvocation, ) : super( parent, parentInvocation, ); -} - -class _FakeRectangle_1 extends _i1.SmartFake - implements _i3.Rectangle { - _FakeRectangle_1( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeCssRect_2 extends _i1.SmartFake implements _i2.CssRect { - _FakeCssRect_2( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakePoint_3 extends _i1.SmartFake - implements _i3.Point { - _FakePoint_3( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeElementEvents_4 extends _i1.SmartFake implements _i2.ElementEvents { - _FakeElementEvents_4( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeCssStyleDeclaration_5 extends _i1.SmartFake - implements _i2.CssStyleDeclaration { - _FakeCssStyleDeclaration_5( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeElementStream_6 extends _i1.SmartFake - implements _i2.ElementStream { - _FakeElementStream_6( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeElementList_7 extends _i1.SmartFake - implements _i2.ElementList { - _FakeElementList_7( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeScrollState_8 extends _i1.SmartFake implements _i2.ScrollState { - _FakeScrollState_8( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeAnimation_9 extends _i1.SmartFake implements _i2.Animation { - _FakeAnimation_9( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeElement_10 extends _i1.SmartFake implements _i2.Element { - _FakeElement_10( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeShadowRoot_11 extends _i1.SmartFake implements _i2.ShadowRoot { - _FakeShadowRoot_11( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeDocumentFragment_12 extends _i1.SmartFake - implements _i2.DocumentFragment { - _FakeDocumentFragment_12( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeNode_13 extends _i1.SmartFake implements _i2.Node { - _FakeNode_13( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeWidget_14 extends _i1.SmartFake implements _i4.Widget { - _FakeWidget_14( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); - - @override - String toString({_i5.DiagnosticLevel? minLevel = _i5.DiagnosticLevel.info}) => - super.toString(); -} - -class _FakeInheritedWidget_15 extends _i1.SmartFake - implements _i4.InheritedWidget { - _FakeInheritedWidget_15( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); - - @override - String toString({_i5.DiagnosticLevel? minLevel = _i5.DiagnosticLevel.info}) => - super.toString(); -} - -class _FakeDiagnosticsNode_16 extends _i1.SmartFake - implements _i5.DiagnosticsNode { - _FakeDiagnosticsNode_16( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); - - @override - String toString({ - _i5.TextTreeConfiguration? parentConfiguration, - _i5.DiagnosticLevel? minLevel = _i5.DiagnosticLevel.info, - }) => - super.toString(); -} - -class _FakeHttpRequest_17 extends _i1.SmartFake implements _i2.HttpRequest { - _FakeHttpRequest_17( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeHttpRequestUpload_18 extends _i1.SmartFake - implements _i2.HttpRequestUpload { - _FakeHttpRequestUpload_18( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeEvents_19 extends _i1.SmartFake implements _i2.Events { - _FakeEvents_19( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -/// A class which mocks [IFrameElement]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockIFrameElement extends _i1.Mock implements _i2.IFrameElement { - MockIFrameElement() { - _i1.throwOnMissingStub(this); - } - - @override - set allow(String? value) => super.noSuchMethod( - Invocation.setter( - #allow, - value, - ), - returnValueForMissingStub: null, - ); - - @override - set allowFullscreen(bool? value) => super.noSuchMethod( - Invocation.setter( - #allowFullscreen, - value, - ), - returnValueForMissingStub: null, - ); - - @override - set allowPaymentRequest(bool? value) => super.noSuchMethod( - Invocation.setter( - #allowPaymentRequest, - value, - ), - returnValueForMissingStub: null, - ); - - @override - set csp(String? value) => super.noSuchMethod( - Invocation.setter( - #csp, - value, - ), - returnValueForMissingStub: null, - ); - - @override - set height(String? value) => super.noSuchMethod( - Invocation.setter( - #height, - value, - ), - returnValueForMissingStub: null, - ); - - @override - set name(String? value) => super.noSuchMethod( - Invocation.setter( - #name, - value, - ), - returnValueForMissingStub: null, - ); - - @override - set referrerPolicy(String? value) => super.noSuchMethod( - Invocation.setter( - #referrerPolicy, - value, - ), - returnValueForMissingStub: null, - ); - - @override - set src(String? value) => super.noSuchMethod( - Invocation.setter( - #src, - value, - ), - returnValueForMissingStub: null, - ); - - @override - set srcdoc(String? value) => super.noSuchMethod( - Invocation.setter( - #srcdoc, - value, - ), - returnValueForMissingStub: null, - ); - - @override - set width(String? value) => super.noSuchMethod( - Invocation.setter( - #width, - value, - ), - returnValueForMissingStub: null, - ); - - @override - set nonce(String? value) => super.noSuchMethod( - Invocation.setter( - #nonce, - value, - ), - returnValueForMissingStub: null, - ); - - @override - Map get attributes => (super.noSuchMethod( - Invocation.getter(#attributes), - returnValue: {}, - ) as Map); - - @override - set attributes(Map? value) => super.noSuchMethod( - Invocation.setter( - #attributes, - value, - ), - returnValueForMissingStub: null, - ); - - @override - List<_i2.Element> get children => (super.noSuchMethod( - Invocation.getter(#children), - returnValue: <_i2.Element>[], - ) as List<_i2.Element>); - - @override - set children(List<_i2.Element>? value) => super.noSuchMethod( - Invocation.setter( - #children, - value, - ), - returnValueForMissingStub: null, - ); - - @override - _i2.CssClassSet get classes => (super.noSuchMethod( - Invocation.getter(#classes), - returnValue: _FakeCssClassSet_0( - this, - Invocation.getter(#classes), - ), - ) as _i2.CssClassSet); - - @override - set classes(Iterable? value) => super.noSuchMethod( - Invocation.setter( - #classes, - value, - ), - returnValueForMissingStub: null, - ); - - @override - Map get dataset => (super.noSuchMethod( - Invocation.getter(#dataset), - returnValue: {}, - ) as Map); - - @override - set dataset(Map? value) => super.noSuchMethod( - Invocation.setter( - #dataset, - value, - ), - returnValueForMissingStub: null, - ); - - @override - _i3.Rectangle get client => (super.noSuchMethod( - Invocation.getter(#client), - returnValue: _FakeRectangle_1( - this, - Invocation.getter(#client), - ), - ) as _i3.Rectangle); - - @override - _i3.Rectangle get offset => (super.noSuchMethod( - Invocation.getter(#offset), - returnValue: _FakeRectangle_1( - this, - Invocation.getter(#offset), - ), - ) as _i3.Rectangle); - - @override - String get localName => (super.noSuchMethod( - Invocation.getter(#localName), - returnValue: _i6.dummyValue( - this, - Invocation.getter(#localName), - ), - ) as String); - - @override - _i2.CssRect get contentEdge => (super.noSuchMethod( - Invocation.getter(#contentEdge), - returnValue: _FakeCssRect_2( - this, - Invocation.getter(#contentEdge), - ), - ) as _i2.CssRect); - - @override - _i2.CssRect get paddingEdge => (super.noSuchMethod( - Invocation.getter(#paddingEdge), - returnValue: _FakeCssRect_2( - this, - Invocation.getter(#paddingEdge), - ), - ) as _i2.CssRect); - - @override - _i2.CssRect get borderEdge => (super.noSuchMethod( - Invocation.getter(#borderEdge), - returnValue: _FakeCssRect_2( - this, - Invocation.getter(#borderEdge), - ), - ) as _i2.CssRect); - - @override - _i2.CssRect get marginEdge => (super.noSuchMethod( - Invocation.getter(#marginEdge), - returnValue: _FakeCssRect_2( - this, - Invocation.getter(#marginEdge), - ), - ) as _i2.CssRect); - - @override - _i3.Point get documentOffset => (super.noSuchMethod( - Invocation.getter(#documentOffset), - returnValue: _FakePoint_3( - this, - Invocation.getter(#documentOffset), - ), - ) as _i3.Point); - - @override - set innerHtml(String? html) => super.noSuchMethod( - Invocation.setter( - #innerHtml, - html, - ), - returnValueForMissingStub: null, - ); - - @override - String get innerText => (super.noSuchMethod( - Invocation.getter(#innerText), - returnValue: _i6.dummyValue( - this, - Invocation.getter(#innerText), - ), - ) as String); - - @override - set innerText(String? value) => super.noSuchMethod( - Invocation.setter( - #innerText, - value, - ), - returnValueForMissingStub: null, - ); - - @override - _i2.ElementEvents get on => (super.noSuchMethod( - Invocation.getter(#on), - returnValue: _FakeElementEvents_4( - this, - Invocation.getter(#on), - ), - ) as _i2.ElementEvents); - - @override - int get offsetHeight => (super.noSuchMethod( - Invocation.getter(#offsetHeight), - returnValue: 0, - ) as int); - - @override - int get offsetLeft => (super.noSuchMethod( - Invocation.getter(#offsetLeft), - returnValue: 0, - ) as int); - - @override - int get offsetTop => (super.noSuchMethod( - Invocation.getter(#offsetTop), - returnValue: 0, - ) as int); - - @override - int get offsetWidth => (super.noSuchMethod( - Invocation.getter(#offsetWidth), - returnValue: 0, - ) as int); - - @override - int get scrollHeight => (super.noSuchMethod( - Invocation.getter(#scrollHeight), - returnValue: 0, - ) as int); - - @override - int get scrollLeft => (super.noSuchMethod( - Invocation.getter(#scrollLeft), - returnValue: 0, - ) as int); - - @override - set scrollLeft(int? value) => super.noSuchMethod( - Invocation.setter( - #scrollLeft, - value, - ), - returnValueForMissingStub: null, - ); - - @override - int get scrollTop => (super.noSuchMethod( - Invocation.getter(#scrollTop), - returnValue: 0, - ) as int); - - @override - set scrollTop(int? value) => super.noSuchMethod( - Invocation.setter( - #scrollTop, - value, - ), - returnValueForMissingStub: null, - ); - - @override - int get scrollWidth => (super.noSuchMethod( - Invocation.getter(#scrollWidth), - returnValue: 0, - ) as int); - - @override - String get contentEditable => (super.noSuchMethod( - Invocation.getter(#contentEditable), - returnValue: _i6.dummyValue( - this, - Invocation.getter(#contentEditable), - ), - ) as String); - - @override - set contentEditable(String? value) => super.noSuchMethod( - Invocation.setter( - #contentEditable, - value, - ), - returnValueForMissingStub: null, - ); - - @override - set dir(String? value) => super.noSuchMethod( - Invocation.setter( - #dir, - value, - ), - returnValueForMissingStub: null, - ); - - @override - bool get draggable => (super.noSuchMethod( - Invocation.getter(#draggable), - returnValue: false, - ) as bool); - - @override - set draggable(bool? value) => super.noSuchMethod( - Invocation.setter( - #draggable, - value, - ), - returnValueForMissingStub: null, - ); - - @override - bool get hidden => (super.noSuchMethod( - Invocation.getter(#hidden), - returnValue: false, - ) as bool); - - @override - set hidden(bool? value) => super.noSuchMethod( - Invocation.setter( - #hidden, - value, - ), - returnValueForMissingStub: null, - ); - - @override - set inert(bool? value) => super.noSuchMethod( - Invocation.setter( - #inert, - value, - ), - returnValueForMissingStub: null, - ); - - @override - set inputMode(String? value) => super.noSuchMethod( - Invocation.setter( - #inputMode, - value, - ), - returnValueForMissingStub: null, - ); - - @override - set lang(String? value) => super.noSuchMethod( - Invocation.setter( - #lang, - value, - ), - returnValueForMissingStub: null, - ); - - @override - set spellcheck(bool? value) => super.noSuchMethod( - Invocation.setter( - #spellcheck, - value, - ), - returnValueForMissingStub: null, - ); - - @override - _i2.CssStyleDeclaration get style => (super.noSuchMethod( - Invocation.getter(#style), - returnValue: _FakeCssStyleDeclaration_5( - this, - Invocation.getter(#style), - ), - ) as _i2.CssStyleDeclaration); - - @override - set tabIndex(int? value) => super.noSuchMethod( - Invocation.setter( - #tabIndex, - value, - ), - returnValueForMissingStub: null, - ); - - @override - set title(String? value) => super.noSuchMethod( - Invocation.setter( - #title, - value, - ), - returnValueForMissingStub: null, - ); - - @override - set translate(bool? value) => super.noSuchMethod( - Invocation.setter( - #translate, - value, - ), - returnValueForMissingStub: null, - ); - - @override - String get className => (super.noSuchMethod( - Invocation.getter(#className), - returnValue: _i6.dummyValue( - this, - Invocation.getter(#className), - ), - ) as String); - - @override - set className(String? value) => super.noSuchMethod( - Invocation.setter( - #className, - value, - ), - returnValueForMissingStub: null, - ); - - @override - int get clientHeight => (super.noSuchMethod( - Invocation.getter(#clientHeight), - returnValue: 0, - ) as int); - - @override - int get clientWidth => (super.noSuchMethod( - Invocation.getter(#clientWidth), - returnValue: 0, - ) as int); - - @override - String get id => (super.noSuchMethod( - Invocation.getter(#id), - returnValue: _i6.dummyValue( - this, - Invocation.getter(#id), - ), - ) as String); - - @override - set id(String? value) => super.noSuchMethod( - Invocation.setter( - #id, - value, - ), - returnValueForMissingStub: null, - ); - - @override - set slot(String? value) => super.noSuchMethod( - Invocation.setter( - #slot, - value, - ), - returnValueForMissingStub: null, - ); - - @override - String get tagName => (super.noSuchMethod( - Invocation.getter(#tagName), - returnValue: _i6.dummyValue( - this, - Invocation.getter(#tagName), - ), - ) as String); - - @override - _i2.ElementStream<_i2.Event> get onAbort => (super.noSuchMethod( - Invocation.getter(#onAbort), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onAbort), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onBeforeCopy => (super.noSuchMethod( - Invocation.getter(#onBeforeCopy), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onBeforeCopy), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onBeforeCut => (super.noSuchMethod( - Invocation.getter(#onBeforeCut), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onBeforeCut), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onBeforePaste => (super.noSuchMethod( - Invocation.getter(#onBeforePaste), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onBeforePaste), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onBlur => (super.noSuchMethod( - Invocation.getter(#onBlur), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onBlur), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onCanPlay => (super.noSuchMethod( - Invocation.getter(#onCanPlay), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onCanPlay), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onCanPlayThrough => (super.noSuchMethod( - Invocation.getter(#onCanPlayThrough), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onCanPlayThrough), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onChange => (super.noSuchMethod( - Invocation.getter(#onChange), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onChange), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.MouseEvent> get onClick => (super.noSuchMethod( - Invocation.getter(#onClick), - returnValue: _FakeElementStream_6<_i2.MouseEvent>( - this, - Invocation.getter(#onClick), - ), - ) as _i2.ElementStream<_i2.MouseEvent>); - - @override - _i2.ElementStream<_i2.MouseEvent> get onContextMenu => (super.noSuchMethod( - Invocation.getter(#onContextMenu), - returnValue: _FakeElementStream_6<_i2.MouseEvent>( - this, - Invocation.getter(#onContextMenu), - ), - ) as _i2.ElementStream<_i2.MouseEvent>); - - @override - _i2.ElementStream<_i2.ClipboardEvent> get onCopy => (super.noSuchMethod( - Invocation.getter(#onCopy), - returnValue: _FakeElementStream_6<_i2.ClipboardEvent>( - this, - Invocation.getter(#onCopy), - ), - ) as _i2.ElementStream<_i2.ClipboardEvent>); - - @override - _i2.ElementStream<_i2.ClipboardEvent> get onCut => (super.noSuchMethod( - Invocation.getter(#onCut), - returnValue: _FakeElementStream_6<_i2.ClipboardEvent>( - this, - Invocation.getter(#onCut), - ), - ) as _i2.ElementStream<_i2.ClipboardEvent>); - - @override - _i2.ElementStream<_i2.Event> get onDoubleClick => (super.noSuchMethod( - Invocation.getter(#onDoubleClick), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onDoubleClick), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.MouseEvent> get onDrag => (super.noSuchMethod( - Invocation.getter(#onDrag), - returnValue: _FakeElementStream_6<_i2.MouseEvent>( - this, - Invocation.getter(#onDrag), - ), - ) as _i2.ElementStream<_i2.MouseEvent>); - - @override - _i2.ElementStream<_i2.MouseEvent> get onDragEnd => (super.noSuchMethod( - Invocation.getter(#onDragEnd), - returnValue: _FakeElementStream_6<_i2.MouseEvent>( - this, - Invocation.getter(#onDragEnd), - ), - ) as _i2.ElementStream<_i2.MouseEvent>); - - @override - _i2.ElementStream<_i2.MouseEvent> get onDragEnter => (super.noSuchMethod( - Invocation.getter(#onDragEnter), - returnValue: _FakeElementStream_6<_i2.MouseEvent>( - this, - Invocation.getter(#onDragEnter), - ), - ) as _i2.ElementStream<_i2.MouseEvent>); - - @override - _i2.ElementStream<_i2.MouseEvent> get onDragLeave => (super.noSuchMethod( - Invocation.getter(#onDragLeave), - returnValue: _FakeElementStream_6<_i2.MouseEvent>( - this, - Invocation.getter(#onDragLeave), - ), - ) as _i2.ElementStream<_i2.MouseEvent>); - - @override - _i2.ElementStream<_i2.MouseEvent> get onDragOver => (super.noSuchMethod( - Invocation.getter(#onDragOver), - returnValue: _FakeElementStream_6<_i2.MouseEvent>( - this, - Invocation.getter(#onDragOver), - ), - ) as _i2.ElementStream<_i2.MouseEvent>); - - @override - _i2.ElementStream<_i2.MouseEvent> get onDragStart => (super.noSuchMethod( - Invocation.getter(#onDragStart), - returnValue: _FakeElementStream_6<_i2.MouseEvent>( - this, - Invocation.getter(#onDragStart), - ), - ) as _i2.ElementStream<_i2.MouseEvent>); - - @override - _i2.ElementStream<_i2.MouseEvent> get onDrop => (super.noSuchMethod( - Invocation.getter(#onDrop), - returnValue: _FakeElementStream_6<_i2.MouseEvent>( - this, - Invocation.getter(#onDrop), - ), - ) as _i2.ElementStream<_i2.MouseEvent>); - - @override - _i2.ElementStream<_i2.Event> get onDurationChange => (super.noSuchMethod( - Invocation.getter(#onDurationChange), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onDurationChange), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onEmptied => (super.noSuchMethod( - Invocation.getter(#onEmptied), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onEmptied), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onEnded => (super.noSuchMethod( - Invocation.getter(#onEnded), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onEnded), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onError => (super.noSuchMethod( - Invocation.getter(#onError), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onError), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onFocus => (super.noSuchMethod( - Invocation.getter(#onFocus), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onFocus), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onInput => (super.noSuchMethod( - Invocation.getter(#onInput), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onInput), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onInvalid => (super.noSuchMethod( - Invocation.getter(#onInvalid), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onInvalid), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.KeyboardEvent> get onKeyDown => (super.noSuchMethod( - Invocation.getter(#onKeyDown), - returnValue: _FakeElementStream_6<_i2.KeyboardEvent>( - this, - Invocation.getter(#onKeyDown), - ), - ) as _i2.ElementStream<_i2.KeyboardEvent>); - - @override - _i2.ElementStream<_i2.KeyboardEvent> get onKeyPress => (super.noSuchMethod( - Invocation.getter(#onKeyPress), - returnValue: _FakeElementStream_6<_i2.KeyboardEvent>( - this, - Invocation.getter(#onKeyPress), - ), - ) as _i2.ElementStream<_i2.KeyboardEvent>); - - @override - _i2.ElementStream<_i2.KeyboardEvent> get onKeyUp => (super.noSuchMethod( - Invocation.getter(#onKeyUp), - returnValue: _FakeElementStream_6<_i2.KeyboardEvent>( - this, - Invocation.getter(#onKeyUp), - ), - ) as _i2.ElementStream<_i2.KeyboardEvent>); - - @override - _i2.ElementStream<_i2.Event> get onLoad => (super.noSuchMethod( - Invocation.getter(#onLoad), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onLoad), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onLoadedData => (super.noSuchMethod( - Invocation.getter(#onLoadedData), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onLoadedData), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onLoadedMetadata => (super.noSuchMethod( - Invocation.getter(#onLoadedMetadata), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onLoadedMetadata), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.MouseEvent> get onMouseDown => (super.noSuchMethod( - Invocation.getter(#onMouseDown), - returnValue: _FakeElementStream_6<_i2.MouseEvent>( - this, - Invocation.getter(#onMouseDown), - ), - ) as _i2.ElementStream<_i2.MouseEvent>); - - @override - _i2.ElementStream<_i2.MouseEvent> get onMouseEnter => (super.noSuchMethod( - Invocation.getter(#onMouseEnter), - returnValue: _FakeElementStream_6<_i2.MouseEvent>( - this, - Invocation.getter(#onMouseEnter), - ), - ) as _i2.ElementStream<_i2.MouseEvent>); - - @override - _i2.ElementStream<_i2.MouseEvent> get onMouseLeave => (super.noSuchMethod( - Invocation.getter(#onMouseLeave), - returnValue: _FakeElementStream_6<_i2.MouseEvent>( - this, - Invocation.getter(#onMouseLeave), - ), - ) as _i2.ElementStream<_i2.MouseEvent>); - - @override - _i2.ElementStream<_i2.MouseEvent> get onMouseMove => (super.noSuchMethod( - Invocation.getter(#onMouseMove), - returnValue: _FakeElementStream_6<_i2.MouseEvent>( - this, - Invocation.getter(#onMouseMove), - ), - ) as _i2.ElementStream<_i2.MouseEvent>); - - @override - _i2.ElementStream<_i2.MouseEvent> get onMouseOut => (super.noSuchMethod( - Invocation.getter(#onMouseOut), - returnValue: _FakeElementStream_6<_i2.MouseEvent>( - this, - Invocation.getter(#onMouseOut), - ), - ) as _i2.ElementStream<_i2.MouseEvent>); - - @override - _i2.ElementStream<_i2.MouseEvent> get onMouseOver => (super.noSuchMethod( - Invocation.getter(#onMouseOver), - returnValue: _FakeElementStream_6<_i2.MouseEvent>( - this, - Invocation.getter(#onMouseOver), - ), - ) as _i2.ElementStream<_i2.MouseEvent>); - - @override - _i2.ElementStream<_i2.MouseEvent> get onMouseUp => (super.noSuchMethod( - Invocation.getter(#onMouseUp), - returnValue: _FakeElementStream_6<_i2.MouseEvent>( - this, - Invocation.getter(#onMouseUp), - ), - ) as _i2.ElementStream<_i2.MouseEvent>); - - @override - _i2.ElementStream<_i2.WheelEvent> get onMouseWheel => (super.noSuchMethod( - Invocation.getter(#onMouseWheel), - returnValue: _FakeElementStream_6<_i2.WheelEvent>( - this, - Invocation.getter(#onMouseWheel), - ), - ) as _i2.ElementStream<_i2.WheelEvent>); - - @override - _i2.ElementStream<_i2.ClipboardEvent> get onPaste => (super.noSuchMethod( - Invocation.getter(#onPaste), - returnValue: _FakeElementStream_6<_i2.ClipboardEvent>( - this, - Invocation.getter(#onPaste), - ), - ) as _i2.ElementStream<_i2.ClipboardEvent>); - - @override - _i2.ElementStream<_i2.Event> get onPause => (super.noSuchMethod( - Invocation.getter(#onPause), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onPause), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onPlay => (super.noSuchMethod( - Invocation.getter(#onPlay), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onPlay), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onPlaying => (super.noSuchMethod( - Invocation.getter(#onPlaying), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onPlaying), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onRateChange => (super.noSuchMethod( - Invocation.getter(#onRateChange), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onRateChange), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onReset => (super.noSuchMethod( - Invocation.getter(#onReset), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onReset), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onResize => (super.noSuchMethod( - Invocation.getter(#onResize), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onResize), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onScroll => (super.noSuchMethod( - Invocation.getter(#onScroll), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onScroll), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onSearch => (super.noSuchMethod( - Invocation.getter(#onSearch), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onSearch), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onSeeked => (super.noSuchMethod( - Invocation.getter(#onSeeked), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onSeeked), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onSeeking => (super.noSuchMethod( - Invocation.getter(#onSeeking), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onSeeking), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onSelect => (super.noSuchMethod( - Invocation.getter(#onSelect), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onSelect), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onSelectStart => (super.noSuchMethod( - Invocation.getter(#onSelectStart), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onSelectStart), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onStalled => (super.noSuchMethod( - Invocation.getter(#onStalled), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onStalled), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onSubmit => (super.noSuchMethod( - Invocation.getter(#onSubmit), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onSubmit), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onSuspend => (super.noSuchMethod( - Invocation.getter(#onSuspend), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onSuspend), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onTimeUpdate => (super.noSuchMethod( - Invocation.getter(#onTimeUpdate), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onTimeUpdate), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.TouchEvent> get onTouchCancel => (super.noSuchMethod( - Invocation.getter(#onTouchCancel), - returnValue: _FakeElementStream_6<_i2.TouchEvent>( - this, - Invocation.getter(#onTouchCancel), - ), - ) as _i2.ElementStream<_i2.TouchEvent>); - - @override - _i2.ElementStream<_i2.TouchEvent> get onTouchEnd => (super.noSuchMethod( - Invocation.getter(#onTouchEnd), - returnValue: _FakeElementStream_6<_i2.TouchEvent>( - this, - Invocation.getter(#onTouchEnd), - ), - ) as _i2.ElementStream<_i2.TouchEvent>); - - @override - _i2.ElementStream<_i2.TouchEvent> get onTouchEnter => (super.noSuchMethod( - Invocation.getter(#onTouchEnter), - returnValue: _FakeElementStream_6<_i2.TouchEvent>( - this, - Invocation.getter(#onTouchEnter), - ), - ) as _i2.ElementStream<_i2.TouchEvent>); - - @override - _i2.ElementStream<_i2.TouchEvent> get onTouchLeave => (super.noSuchMethod( - Invocation.getter(#onTouchLeave), - returnValue: _FakeElementStream_6<_i2.TouchEvent>( - this, - Invocation.getter(#onTouchLeave), - ), - ) as _i2.ElementStream<_i2.TouchEvent>); - - @override - _i2.ElementStream<_i2.TouchEvent> get onTouchMove => (super.noSuchMethod( - Invocation.getter(#onTouchMove), - returnValue: _FakeElementStream_6<_i2.TouchEvent>( - this, - Invocation.getter(#onTouchMove), - ), - ) as _i2.ElementStream<_i2.TouchEvent>); - - @override - _i2.ElementStream<_i2.TouchEvent> get onTouchStart => (super.noSuchMethod( - Invocation.getter(#onTouchStart), - returnValue: _FakeElementStream_6<_i2.TouchEvent>( - this, - Invocation.getter(#onTouchStart), - ), - ) as _i2.ElementStream<_i2.TouchEvent>); - - @override - _i2.ElementStream<_i2.TransitionEvent> get onTransitionEnd => - (super.noSuchMethod( - Invocation.getter(#onTransitionEnd), - returnValue: _FakeElementStream_6<_i2.TransitionEvent>( - this, - Invocation.getter(#onTransitionEnd), - ), - ) as _i2.ElementStream<_i2.TransitionEvent>); - - @override - _i2.ElementStream<_i2.Event> get onVolumeChange => (super.noSuchMethod( - Invocation.getter(#onVolumeChange), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onVolumeChange), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onWaiting => (super.noSuchMethod( - Invocation.getter(#onWaiting), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onWaiting), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onFullscreenChange => (super.noSuchMethod( - Invocation.getter(#onFullscreenChange), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onFullscreenChange), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.Event> get onFullscreenError => (super.noSuchMethod( - Invocation.getter(#onFullscreenError), - returnValue: _FakeElementStream_6<_i2.Event>( - this, - Invocation.getter(#onFullscreenError), - ), - ) as _i2.ElementStream<_i2.Event>); - - @override - _i2.ElementStream<_i2.WheelEvent> get onWheel => (super.noSuchMethod( - Invocation.getter(#onWheel), - returnValue: _FakeElementStream_6<_i2.WheelEvent>( - this, - Invocation.getter(#onWheel), - ), - ) as _i2.ElementStream<_i2.WheelEvent>); - - @override - List<_i2.Node> get nodes => (super.noSuchMethod( - Invocation.getter(#nodes), - returnValue: <_i2.Node>[], - ) as List<_i2.Node>); - - @override - set nodes(Iterable<_i2.Node>? value) => super.noSuchMethod( - Invocation.setter( - #nodes, - value, - ), - returnValueForMissingStub: null, - ); - - @override - List<_i2.Node> get childNodes => (super.noSuchMethod( - Invocation.getter(#childNodes), - returnValue: <_i2.Node>[], - ) as List<_i2.Node>); - - @override - int get nodeType => (super.noSuchMethod( - Invocation.getter(#nodeType), - returnValue: 0, - ) as int); - - @override - set text(String? value) => super.noSuchMethod( - Invocation.setter( - #text, - value, - ), - returnValueForMissingStub: null, - ); - - @override - String? getAttribute(String? name) => (super.noSuchMethod(Invocation.method( - #getAttribute, - [name], - )) as String?); - - @override - String? getAttributeNS( - String? namespaceURI, - String? name, - ) => - (super.noSuchMethod(Invocation.method( - #getAttributeNS, - [ - namespaceURI, - name, - ], - )) as String?); - - @override - bool hasAttribute(String? name) => (super.noSuchMethod( - Invocation.method( - #hasAttribute, - [name], - ), - returnValue: false, - ) as bool); - - @override - bool hasAttributeNS( - String? namespaceURI, - String? name, - ) => - (super.noSuchMethod( - Invocation.method( - #hasAttributeNS, - [ - namespaceURI, - name, - ], - ), - returnValue: false, - ) as bool); - - @override - void removeAttribute(String? name) => super.noSuchMethod( - Invocation.method( - #removeAttribute, - [name], - ), - returnValueForMissingStub: null, - ); - - @override - void removeAttributeNS( - String? namespaceURI, - String? name, - ) => - super.noSuchMethod( - Invocation.method( - #removeAttributeNS, - [ - namespaceURI, - name, - ], - ), - returnValueForMissingStub: null, - ); - - @override - void setAttribute( - String? name, - Object? value, - ) => - super.noSuchMethod( - Invocation.method( - #setAttribute, - [ - name, - value, - ], - ), - returnValueForMissingStub: null, - ); - - @override - void setAttributeNS( - String? namespaceURI, - String? name, - Object? value, - ) => - super.noSuchMethod( - Invocation.method( - #setAttributeNS, - [ - namespaceURI, - name, - value, - ], - ), - returnValueForMissingStub: null, - ); - - @override - _i2.ElementList querySelectorAll( - String? selectors) => - (super.noSuchMethod( - Invocation.method( - #querySelectorAll, - [selectors], - ), - returnValue: _FakeElementList_7( - this, - Invocation.method( - #querySelectorAll, - [selectors], - ), - ), - ) as _i2.ElementList); - - @override - _i7.Future<_i2.ScrollState> setApplyScroll(String? nativeScrollBehavior) => - (super.noSuchMethod( - Invocation.method( - #setApplyScroll, - [nativeScrollBehavior], - ), - returnValue: _i7.Future<_i2.ScrollState>.value(_FakeScrollState_8( - this, - Invocation.method( - #setApplyScroll, - [nativeScrollBehavior], - ), - )), - ) as _i7.Future<_i2.ScrollState>); - - @override - _i7.Future<_i2.ScrollState> setDistributeScroll( - String? nativeScrollBehavior) => - (super.noSuchMethod( - Invocation.method( - #setDistributeScroll, - [nativeScrollBehavior], - ), - returnValue: _i7.Future<_i2.ScrollState>.value(_FakeScrollState_8( - this, - Invocation.method( - #setDistributeScroll, - [nativeScrollBehavior], - ), - )), - ) as _i7.Future<_i2.ScrollState>); - - @override - Map getNamespacedAttributes(String? namespace) => - (super.noSuchMethod( - Invocation.method( - #getNamespacedAttributes, - [namespace], - ), - returnValue: {}, - ) as Map); - - @override - _i2.CssStyleDeclaration getComputedStyle([String? pseudoElement]) => - (super.noSuchMethod( - Invocation.method( - #getComputedStyle, - [pseudoElement], - ), - returnValue: _FakeCssStyleDeclaration_5( - this, - Invocation.method( - #getComputedStyle, - [pseudoElement], - ), - ), - ) as _i2.CssStyleDeclaration); - - @override - void appendText(String? text) => super.noSuchMethod( - Invocation.method( - #appendText, - [text], - ), - returnValueForMissingStub: null, - ); - - @override - void appendHtml( - String? text, { - _i2.NodeValidator? validator, - _i2.NodeTreeSanitizer? treeSanitizer, - }) => - super.noSuchMethod( - Invocation.method( - #appendHtml, - [text], - { - #validator: validator, - #treeSanitizer: treeSanitizer, - }, - ), - returnValueForMissingStub: null, - ); - - @override - void attached() => super.noSuchMethod( - Invocation.method( - #attached, - [], - ), - returnValueForMissingStub: null, - ); - - @override - void detached() => super.noSuchMethod( - Invocation.method( - #detached, - [], - ), - returnValueForMissingStub: null, - ); - - @override - void enteredView() => super.noSuchMethod( - Invocation.method( - #enteredView, - [], - ), - returnValueForMissingStub: null, - ); - - @override - List<_i3.Rectangle> getClientRects() => (super.noSuchMethod( - Invocation.method( - #getClientRects, - [], - ), - returnValue: <_i3.Rectangle>[], - ) as List<_i3.Rectangle>); - - @override - void leftView() => super.noSuchMethod( - Invocation.method( - #leftView, - [], - ), - returnValueForMissingStub: null, - ); - - @override - _i2.Animation animate( - Iterable>? frames, [ - dynamic timing, - ]) => - (super.noSuchMethod( - Invocation.method( - #animate, - [ - frames, - timing, - ], - ), - returnValue: _FakeAnimation_9( - this, - Invocation.method( - #animate, - [ - frames, - timing, - ], - ), - ), - ) as _i2.Animation); - - @override - void attributeChanged( - String? name, - String? oldValue, - String? newValue, - ) => - super.noSuchMethod( - Invocation.method( - #attributeChanged, - [ - name, - oldValue, - newValue, - ], - ), - returnValueForMissingStub: null, - ); - - @override - void scrollIntoView([_i2.ScrollAlignment? alignment]) => super.noSuchMethod( - Invocation.method( - #scrollIntoView, - [alignment], - ), - returnValueForMissingStub: null, - ); - - @override - void insertAdjacentText( - String? where, - String? text, - ) => - super.noSuchMethod( - Invocation.method( - #insertAdjacentText, - [ - where, - text, - ], - ), - returnValueForMissingStub: null, - ); - - @override - void insertAdjacentHtml( - String? where, - String? html, { - _i2.NodeValidator? validator, - _i2.NodeTreeSanitizer? treeSanitizer, - }) => - super.noSuchMethod( - Invocation.method( - #insertAdjacentHtml, - [ - where, - html, - ], - { - #validator: validator, - #treeSanitizer: treeSanitizer, - }, - ), - returnValueForMissingStub: null, - ); - - @override - _i2.Element insertAdjacentElement( - String? where, - _i2.Element? element, - ) => - (super.noSuchMethod( - Invocation.method( - #insertAdjacentElement, - [ - where, - element, - ], - ), - returnValue: _FakeElement_10( - this, - Invocation.method( - #insertAdjacentElement, - [ - where, - element, - ], - ), - ), - ) as _i2.Element); - - @override - bool matches(String? selectors) => (super.noSuchMethod( - Invocation.method( - #matches, - [selectors], - ), - returnValue: false, - ) as bool); - - @override - bool matchesWithAncestors(String? selectors) => (super.noSuchMethod( - Invocation.method( - #matchesWithAncestors, - [selectors], - ), - returnValue: false, - ) as bool); - - @override - _i2.ShadowRoot createShadowRoot() => (super.noSuchMethod( - Invocation.method( - #createShadowRoot, - [], - ), - returnValue: _FakeShadowRoot_11( - this, - Invocation.method( - #createShadowRoot, - [], - ), - ), - ) as _i2.ShadowRoot); - - @override - _i3.Point offsetTo(_i2.Element? parent) => (super.noSuchMethod( - Invocation.method( - #offsetTo, - [parent], - ), - returnValue: _FakePoint_3( - this, - Invocation.method( - #offsetTo, - [parent], - ), - ), - ) as _i3.Point); - - @override - _i2.DocumentFragment createFragment( - String? html, { - _i2.NodeValidator? validator, - _i2.NodeTreeSanitizer? treeSanitizer, - }) => - (super.noSuchMethod( - Invocation.method( - #createFragment, - [html], - { - #validator: validator, - #treeSanitizer: treeSanitizer, - }, - ), - returnValue: _FakeDocumentFragment_12( - this, - Invocation.method( - #createFragment, - [html], - { - #validator: validator, - #treeSanitizer: treeSanitizer, - }, - ), - ), - ) as _i2.DocumentFragment); - - @override - void setInnerHtml( - String? html, { - _i2.NodeValidator? validator, - _i2.NodeTreeSanitizer? treeSanitizer, - }) => - super.noSuchMethod( - Invocation.method( - #setInnerHtml, - [html], - { - #validator: validator, - #treeSanitizer: treeSanitizer, - }, - ), - returnValueForMissingStub: null, - ); - - @override - _i7.Future requestFullscreen([Map? options]) => - (super.noSuchMethod( - Invocation.method( - #requestFullscreen, - [options], - ), - returnValue: _i7.Future.value(), - returnValueForMissingStub: _i7.Future.value(), - ) as _i7.Future); - - @override - void blur() => super.noSuchMethod( - Invocation.method( - #blur, - [], - ), - returnValueForMissingStub: null, - ); - - @override - void click() => super.noSuchMethod( - Invocation.method( - #click, - [], - ), - returnValueForMissingStub: null, - ); - - @override - void focus() => super.noSuchMethod( - Invocation.method( - #focus, - [], - ), - returnValueForMissingStub: null, - ); - - @override - _i2.ShadowRoot attachShadow(Map? shadowRootInitDict) => - (super.noSuchMethod( - Invocation.method( - #attachShadow, - [shadowRootInitDict], - ), - returnValue: _FakeShadowRoot_11( - this, - Invocation.method( - #attachShadow, - [shadowRootInitDict], - ), - ), - ) as _i2.ShadowRoot); - - @override - _i2.Element? closest(String? selectors) => - (super.noSuchMethod(Invocation.method( - #closest, - [selectors], - )) as _i2.Element?); - - @override - List<_i2.Animation> getAnimations() => (super.noSuchMethod( - Invocation.method( - #getAnimations, - [], - ), - returnValue: <_i2.Animation>[], - ) as List<_i2.Animation>); - - @override - List getAttributeNames() => (super.noSuchMethod( - Invocation.method( - #getAttributeNames, - [], - ), - returnValue: [], - ) as List); - - @override - _i3.Rectangle getBoundingClientRect() => (super.noSuchMethod( - Invocation.method( - #getBoundingClientRect, - [], - ), - returnValue: _FakeRectangle_1( - this, - Invocation.method( - #getBoundingClientRect, - [], - ), - ), - ) as _i3.Rectangle); - - @override - List<_i2.Node> getDestinationInsertionPoints() => (super.noSuchMethod( - Invocation.method( - #getDestinationInsertionPoints, - [], - ), - returnValue: <_i2.Node>[], - ) as List<_i2.Node>); - - @override - List<_i2.Node> getElementsByClassName(String? classNames) => - (super.noSuchMethod( - Invocation.method( - #getElementsByClassName, - [classNames], - ), - returnValue: <_i2.Node>[], - ) as List<_i2.Node>); - - @override - bool hasPointerCapture(int? pointerId) => (super.noSuchMethod( - Invocation.method( - #hasPointerCapture, - [pointerId], - ), - returnValue: false, - ) as bool); - - @override - void releasePointerCapture(int? pointerId) => super.noSuchMethod( - Invocation.method( - #releasePointerCapture, - [pointerId], - ), - returnValueForMissingStub: null, - ); - - @override - void requestPointerLock() => super.noSuchMethod( - Invocation.method( - #requestPointerLock, - [], - ), - returnValueForMissingStub: null, - ); - - @override - void scroll([ - dynamic options_OR_x, - num? y, - ]) => - super.noSuchMethod( - Invocation.method( - #scroll, - [ - options_OR_x, - y, - ], - ), - returnValueForMissingStub: null, - ); - - @override - void scrollBy([ - dynamic options_OR_x, - num? y, - ]) => - super.noSuchMethod( - Invocation.method( - #scrollBy, - [ - options_OR_x, - y, - ], - ), - returnValueForMissingStub: null, - ); - - @override - void scrollIntoViewIfNeeded([bool? centerIfNeeded]) => super.noSuchMethod( - Invocation.method( - #scrollIntoViewIfNeeded, - [centerIfNeeded], - ), - returnValueForMissingStub: null, - ); - - @override - void scrollTo([ - dynamic options_OR_x, - num? y, - ]) => - super.noSuchMethod( - Invocation.method( - #scrollTo, - [ - options_OR_x, - y, - ], - ), - returnValueForMissingStub: null, - ); - - @override - void setPointerCapture(int? pointerId) => super.noSuchMethod( - Invocation.method( - #setPointerCapture, - [pointerId], - ), - returnValueForMissingStub: null, - ); - - @override - void after(Object? nodes) => super.noSuchMethod( - Invocation.method( - #after, - [nodes], - ), - returnValueForMissingStub: null, - ); - - @override - void before(Object? nodes) => super.noSuchMethod( - Invocation.method( - #before, - [nodes], - ), - returnValueForMissingStub: null, - ); - - @override - _i2.Element? querySelector(String? selectors) => - (super.noSuchMethod(Invocation.method( - #querySelector, - [selectors], - )) as _i2.Element?); - - @override - void remove() => super.noSuchMethod( - Invocation.method( - #remove, - [], - ), - returnValueForMissingStub: null, - ); - - @override - _i2.Node replaceWith(_i2.Node? otherNode) => (super.noSuchMethod( - Invocation.method( - #replaceWith, - [otherNode], - ), - returnValue: _FakeNode_13( - this, - Invocation.method( - #replaceWith, - [otherNode], - ), - ), - ) as _i2.Node); - - @override - void insertAllBefore( - Iterable<_i2.Node>? newNodes, - _i2.Node? child, - ) => - super.noSuchMethod( - Invocation.method( - #insertAllBefore, - [ - newNodes, - child, - ], - ), - returnValueForMissingStub: null, - ); - - @override - _i2.Node append(_i2.Node? node) => (super.noSuchMethod( - Invocation.method( - #append, - [node], - ), - returnValue: _FakeNode_13( - this, - Invocation.method( - #append, - [node], - ), - ), - ) as _i2.Node); - - @override - _i2.Node clone(bool? deep) => (super.noSuchMethod( - Invocation.method( - #clone, - [deep], - ), - returnValue: _FakeNode_13( - this, - Invocation.method( - #clone, - [deep], - ), - ), - ) as _i2.Node); - - @override - bool contains(_i2.Node? other) => (super.noSuchMethod( - Invocation.method( - #contains, - [other], - ), - returnValue: false, - ) as bool); @override - _i2.Node getRootNode([Map? options]) => (super.noSuchMethod( - Invocation.method( - #getRootNode, - [options], - ), - returnValue: _FakeNode_13( - this, - Invocation.method( - #getRootNode, - [options], - ), - ), - ) as _i2.Node); + String toString({_i3.DiagnosticLevel? minLevel = _i3.DiagnosticLevel.info}) => + super.toString(); +} - @override - bool hasChildNodes() => (super.noSuchMethod( - Invocation.method( - #hasChildNodes, - [], - ), - returnValue: false, - ) as bool); +class _FakeInheritedWidget_1 extends _i1.SmartFake + implements _i2.InheritedWidget { + _FakeInheritedWidget_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); @override - _i2.Node insertBefore( - _i2.Node? node, - _i2.Node? child, - ) => - (super.noSuchMethod( - Invocation.method( - #insertBefore, - [ - node, - child, - ], - ), - returnValue: _FakeNode_13( - this, - Invocation.method( - #insertBefore, - [ - node, - child, - ], - ), - ), - ) as _i2.Node); + String toString({_i3.DiagnosticLevel? minLevel = _i3.DiagnosticLevel.info}) => + super.toString(); +} - @override - void addEventListener( - String? type, - _i2.EventListener? listener, [ - bool? useCapture, - ]) => - super.noSuchMethod( - Invocation.method( - #addEventListener, - [ - type, - listener, - useCapture, - ], - ), - returnValueForMissingStub: null, - ); +class _FakeDiagnosticsNode_2 extends _i1.SmartFake + implements _i3.DiagnosticsNode { + _FakeDiagnosticsNode_2( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); @override - void removeEventListener( - String? type, - _i2.EventListener? listener, [ - bool? useCapture, - ]) => - super.noSuchMethod( - Invocation.method( - #removeEventListener, - [ - type, - listener, - useCapture, - ], - ), - returnValueForMissingStub: null, - ); + String toString({ + _i3.TextTreeConfiguration? parentConfiguration, + _i3.DiagnosticLevel? minLevel = _i3.DiagnosticLevel.info, + }) => + super.toString(); +} - @override - bool dispatchEvent(_i2.Event? event) => (super.noSuchMethod( - Invocation.method( - #dispatchEvent, - [event], - ), - returnValue: false, - ) as bool); +class _FakeObject_3 extends _i1.SmartFake implements Object { + _FakeObject_3( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); } /// A class which mocks [BuildContext]. /// /// See the documentation for Mockito's code generation for more information. -class MockBuildContext extends _i1.Mock implements _i4.BuildContext { +class MockBuildContext extends _i1.Mock implements _i2.BuildContext { MockBuildContext() { _i1.throwOnMissingStub(this); } @override - _i4.Widget get widget => (super.noSuchMethod( + _i2.Widget get widget => (super.noSuchMethod( Invocation.getter(#widget), - returnValue: _FakeWidget_14( + returnValue: _FakeWidget_0( this, Invocation.getter(#widget), ), - ) as _i4.Widget); + ) as _i2.Widget); @override bool get mounted => (super.noSuchMethod( @@ -2356,8 +116,8 @@ class MockBuildContext extends _i1.Mock implements _i4.BuildContext { ) as bool); @override - _i4.InheritedWidget dependOnInheritedElement( - _i4.InheritedElement? ancestor, { + _i2.InheritedWidget dependOnInheritedElement( + _i2.InheritedElement? ancestor, { Object? aspect, }) => (super.noSuchMethod( @@ -2366,7 +126,7 @@ class MockBuildContext extends _i1.Mock implements _i4.BuildContext { [ancestor], {#aspect: aspect}, ), - returnValue: _FakeInheritedWidget_15( + returnValue: _FakeInheritedWidget_1( this, Invocation.method( #dependOnInheritedElement, @@ -2374,10 +134,10 @@ class MockBuildContext extends _i1.Mock implements _i4.BuildContext { {#aspect: aspect}, ), ), - ) as _i4.InheritedWidget); + ) as _i2.InheritedWidget); @override - void visitAncestorElements(_i4.ConditionalElementVisitor? visitor) => + void visitAncestorElements(_i2.ConditionalElementVisitor? visitor) => super.noSuchMethod( Invocation.method( #visitAncestorElements, @@ -2387,7 +147,7 @@ class MockBuildContext extends _i1.Mock implements _i4.BuildContext { ); @override - void visitChildElements(_i4.ElementVisitor? visitor) => super.noSuchMethod( + void visitChildElements(_i2.ElementVisitor? visitor) => super.noSuchMethod( Invocation.method( #visitChildElements, [visitor], @@ -2396,7 +156,7 @@ class MockBuildContext extends _i1.Mock implements _i4.BuildContext { ); @override - void dispatchNotification(_i8.Notification? notification) => + void dispatchNotification(_i4.Notification? notification) => super.noSuchMethod( Invocation.method( #dispatchNotification, @@ -2406,9 +166,9 @@ class MockBuildContext extends _i1.Mock implements _i4.BuildContext { ); @override - _i5.DiagnosticsNode describeElement( + _i3.DiagnosticsNode describeElement( String? name, { - _i5.DiagnosticsTreeStyle? style = _i5.DiagnosticsTreeStyle.errorProperty, + _i3.DiagnosticsTreeStyle? style = _i3.DiagnosticsTreeStyle.errorProperty, }) => (super.noSuchMethod( Invocation.method( @@ -2416,7 +176,7 @@ class MockBuildContext extends _i1.Mock implements _i4.BuildContext { [name], {#style: style}, ), - returnValue: _FakeDiagnosticsNode_16( + returnValue: _FakeDiagnosticsNode_2( this, Invocation.method( #describeElement, @@ -2424,12 +184,12 @@ class MockBuildContext extends _i1.Mock implements _i4.BuildContext { {#style: style}, ), ), - ) as _i5.DiagnosticsNode); + ) as _i3.DiagnosticsNode); @override - _i5.DiagnosticsNode describeWidget( + _i3.DiagnosticsNode describeWidget( String? name, { - _i5.DiagnosticsTreeStyle? style = _i5.DiagnosticsTreeStyle.errorProperty, + _i3.DiagnosticsTreeStyle? style = _i3.DiagnosticsTreeStyle.errorProperty, }) => (super.noSuchMethod( Invocation.method( @@ -2437,7 +197,7 @@ class MockBuildContext extends _i1.Mock implements _i4.BuildContext { [name], {#style: style}, ), - returnValue: _FakeDiagnosticsNode_16( + returnValue: _FakeDiagnosticsNode_2( this, Invocation.method( #describeWidget, @@ -2445,10 +205,10 @@ class MockBuildContext extends _i1.Mock implements _i4.BuildContext { {#style: style}, ), ), - ) as _i5.DiagnosticsNode); + ) as _i3.DiagnosticsNode); @override - List<_i5.DiagnosticsNode> describeMissingAncestor( + List<_i3.DiagnosticsNode> describeMissingAncestor( {required Type? expectedAncestorType}) => (super.noSuchMethod( Invocation.method( @@ -2456,30 +216,30 @@ class MockBuildContext extends _i1.Mock implements _i4.BuildContext { [], {#expectedAncestorType: expectedAncestorType}, ), - returnValue: <_i5.DiagnosticsNode>[], - ) as List<_i5.DiagnosticsNode>); + returnValue: <_i3.DiagnosticsNode>[], + ) as List<_i3.DiagnosticsNode>); @override - _i5.DiagnosticsNode describeOwnershipChain(String? name) => + _i3.DiagnosticsNode describeOwnershipChain(String? name) => (super.noSuchMethod( Invocation.method( #describeOwnershipChain, [name], ), - returnValue: _FakeDiagnosticsNode_16( + returnValue: _FakeDiagnosticsNode_2( this, Invocation.method( #describeOwnershipChain, [name], ), ), - ) as _i5.DiagnosticsNode); + ) as _i3.DiagnosticsNode); } /// A class which mocks [CreationParams]. /// /// See the documentation for Mockito's code generation for more information. -class MockCreationParams extends _i1.Mock implements _i9.CreationParams { +class MockCreationParams extends _i1.Mock implements _i5.CreationParams { MockCreationParams() { _i1.throwOnMissingStub(this); } @@ -2491,25 +251,25 @@ class MockCreationParams extends _i1.Mock implements _i9.CreationParams { ) as Set); @override - _i9.AutoMediaPlaybackPolicy get autoMediaPlaybackPolicy => + _i5.AutoMediaPlaybackPolicy get autoMediaPlaybackPolicy => (super.noSuchMethod( Invocation.getter(#autoMediaPlaybackPolicy), returnValue: - _i9.AutoMediaPlaybackPolicy.require_user_action_for_all_media_types, - ) as _i9.AutoMediaPlaybackPolicy); + _i5.AutoMediaPlaybackPolicy.require_user_action_for_all_media_types, + ) as _i5.AutoMediaPlaybackPolicy); @override - List<_i9.WebViewCookie> get cookies => (super.noSuchMethod( + List<_i5.WebViewCookie> get cookies => (super.noSuchMethod( Invocation.getter(#cookies), - returnValue: <_i9.WebViewCookie>[], - ) as List<_i9.WebViewCookie>); + returnValue: <_i5.WebViewCookie>[], + ) as List<_i5.WebViewCookie>); } /// A class which mocks [WebViewPlatformCallbacksHandler]. /// /// See the documentation for Mockito's code generation for more information. class MockWebViewPlatformCallbacksHandler extends _i1.Mock - implements _i10.WebViewPlatformCallbacksHandler { + implements _i6.WebViewPlatformCallbacksHandler { MockWebViewPlatformCallbacksHandler() { _i1.throwOnMissingStub(this); } @@ -2559,7 +319,7 @@ class MockWebViewPlatformCallbacksHandler extends _i1.Mock ); @override - void onWebResourceError(_i9.WebResourceError? error) => super.noSuchMethod( + void onWebResourceError(_i5.WebResourceError? error) => super.noSuchMethod( Invocation.method( #onWebResourceError, [error], @@ -2572,21 +332,19 @@ class MockWebViewPlatformCallbacksHandler extends _i1.Mock /// /// See the documentation for Mockito's code generation for more information. class MockHttpRequestFactory extends _i1.Mock - implements _i11.HttpRequestFactory { + implements _i8.HttpRequestFactory { MockHttpRequestFactory() { _i1.throwOnMissingStub(this); } @override - _i7.Future<_i2.HttpRequest> request( + _i7.Future request( String? url, { - String? method, - bool? withCredentials, - String? responseType, + String? method = r'GET', + bool? withCredentials = false, String? mimeType, Map? requestHeaders, - dynamic sendData, - void Function(_i2.ProgressEvent)? onProgress, + _i9.Uint8List? sendData, }) => (super.noSuchMethod( Invocation.method( @@ -2595,14 +353,12 @@ class MockHttpRequestFactory extends _i1.Mock { #method: method, #withCredentials: withCredentials, - #responseType: responseType, #mimeType: mimeType, #requestHeaders: requestHeaders, #sendData: sendData, - #onProgress: onProgress, }, ), - returnValue: _i7.Future<_i2.HttpRequest>.value(_FakeHttpRequest_17( + returnValue: _i7.Future.value(_FakeObject_3( this, Invocation.method( #request, @@ -2610,270 +366,11 @@ class MockHttpRequestFactory extends _i1.Mock { #method: method, #withCredentials: withCredentials, - #responseType: responseType, #mimeType: mimeType, #requestHeaders: requestHeaders, #sendData: sendData, - #onProgress: onProgress, }, ), )), - ) as _i7.Future<_i2.HttpRequest>); -} - -/// A class which mocks [HttpRequest]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockHttpRequest extends _i1.Mock implements _i2.HttpRequest { - MockHttpRequest() { - _i1.throwOnMissingStub(this); - } - - @override - Map get responseHeaders => (super.noSuchMethod( - Invocation.getter(#responseHeaders), - returnValue: {}, - ) as Map); - - @override - int get readyState => (super.noSuchMethod( - Invocation.getter(#readyState), - returnValue: 0, - ) as int); - - @override - String get responseType => (super.noSuchMethod( - Invocation.getter(#responseType), - returnValue: _i6.dummyValue( - this, - Invocation.getter(#responseType), - ), - ) as String); - - @override - set responseType(String? value) => super.noSuchMethod( - Invocation.setter( - #responseType, - value, - ), - returnValueForMissingStub: null, - ); - - @override - set timeout(int? value) => super.noSuchMethod( - Invocation.setter( - #timeout, - value, - ), - returnValueForMissingStub: null, - ); - - @override - _i2.HttpRequestUpload get upload => (super.noSuchMethod( - Invocation.getter(#upload), - returnValue: _FakeHttpRequestUpload_18( - this, - Invocation.getter(#upload), - ), - ) as _i2.HttpRequestUpload); - - @override - set withCredentials(bool? value) => super.noSuchMethod( - Invocation.setter( - #withCredentials, - value, - ), - returnValueForMissingStub: null, - ); - - @override - _i7.Stream<_i2.Event> get onReadyStateChange => (super.noSuchMethod( - Invocation.getter(#onReadyStateChange), - returnValue: _i7.Stream<_i2.Event>.empty(), - ) as _i7.Stream<_i2.Event>); - - @override - _i7.Stream<_i2.ProgressEvent> get onAbort => (super.noSuchMethod( - Invocation.getter(#onAbort), - returnValue: _i7.Stream<_i2.ProgressEvent>.empty(), - ) as _i7.Stream<_i2.ProgressEvent>); - - @override - _i7.Stream<_i2.ProgressEvent> get onError => (super.noSuchMethod( - Invocation.getter(#onError), - returnValue: _i7.Stream<_i2.ProgressEvent>.empty(), - ) as _i7.Stream<_i2.ProgressEvent>); - - @override - _i7.Stream<_i2.ProgressEvent> get onLoad => (super.noSuchMethod( - Invocation.getter(#onLoad), - returnValue: _i7.Stream<_i2.ProgressEvent>.empty(), - ) as _i7.Stream<_i2.ProgressEvent>); - - @override - _i7.Stream<_i2.ProgressEvent> get onLoadEnd => (super.noSuchMethod( - Invocation.getter(#onLoadEnd), - returnValue: _i7.Stream<_i2.ProgressEvent>.empty(), - ) as _i7.Stream<_i2.ProgressEvent>); - - @override - _i7.Stream<_i2.ProgressEvent> get onLoadStart => (super.noSuchMethod( - Invocation.getter(#onLoadStart), - returnValue: _i7.Stream<_i2.ProgressEvent>.empty(), - ) as _i7.Stream<_i2.ProgressEvent>); - - @override - _i7.Stream<_i2.ProgressEvent> get onProgress => (super.noSuchMethod( - Invocation.getter(#onProgress), - returnValue: _i7.Stream<_i2.ProgressEvent>.empty(), - ) as _i7.Stream<_i2.ProgressEvent>); - - @override - _i7.Stream<_i2.ProgressEvent> get onTimeout => (super.noSuchMethod( - Invocation.getter(#onTimeout), - returnValue: _i7.Stream<_i2.ProgressEvent>.empty(), - ) as _i7.Stream<_i2.ProgressEvent>); - - @override - _i2.Events get on => (super.noSuchMethod( - Invocation.getter(#on), - returnValue: _FakeEvents_19( - this, - Invocation.getter(#on), - ), - ) as _i2.Events); - - @override - void open( - String? method, - String? url, { - bool? async, - String? user, - String? password, - }) => - super.noSuchMethod( - Invocation.method( - #open, - [ - method, - url, - ], - { - #async: async, - #user: user, - #password: password, - }, - ), - returnValueForMissingStub: null, - ); - - @override - void abort() => super.noSuchMethod( - Invocation.method( - #abort, - [], - ), - returnValueForMissingStub: null, - ); - - @override - String getAllResponseHeaders() => (super.noSuchMethod( - Invocation.method( - #getAllResponseHeaders, - [], - ), - returnValue: _i6.dummyValue( - this, - Invocation.method( - #getAllResponseHeaders, - [], - ), - ), - ) as String); - - @override - String? getResponseHeader(String? name) => - (super.noSuchMethod(Invocation.method( - #getResponseHeader, - [name], - )) as String?); - - @override - void overrideMimeType(String? mime) => super.noSuchMethod( - Invocation.method( - #overrideMimeType, - [mime], - ), - returnValueForMissingStub: null, - ); - - @override - void send([dynamic body_OR_data]) => super.noSuchMethod( - Invocation.method( - #send, - [body_OR_data], - ), - returnValueForMissingStub: null, - ); - - @override - void setRequestHeader( - String? name, - String? value, - ) => - super.noSuchMethod( - Invocation.method( - #setRequestHeader, - [ - name, - value, - ], - ), - returnValueForMissingStub: null, - ); - - @override - void addEventListener( - String? type, - _i2.EventListener? listener, [ - bool? useCapture, - ]) => - super.noSuchMethod( - Invocation.method( - #addEventListener, - [ - type, - listener, - useCapture, - ], - ), - returnValueForMissingStub: null, - ); - - @override - void removeEventListener( - String? type, - _i2.EventListener? listener, [ - bool? useCapture, - ]) => - super.noSuchMethod( - Invocation.method( - #removeEventListener, - [ - type, - listener, - useCapture, - ], - ), - returnValueForMissingStub: null, - ); - - @override - bool dispatchEvent(_i2.Event? event) => (super.noSuchMethod( - Invocation.method( - #dispatchEvent, - [event], - ), - returnValue: false, - ) as bool); + ) as _i7.Future); } diff --git a/packages/webview_flutter/webview_flutter_web/test/web_webview_controller_test.dart b/packages/webview_flutter/webview_flutter_web/test/web_webview_controller_test.dart index e07b8a873c4c..c7a7245279e2 100644 --- a/packages/webview_flutter/webview_flutter_web/test/web_webview_controller_test.dart +++ b/packages/webview_flutter/webview_flutter_web/test/web_webview_controller_test.dart @@ -3,20 +3,20 @@ // found in the LICENSE file. import 'dart:convert'; -import 'dart:html'; +import 'dart:js_interop'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; +import 'package:web/web.dart' as web; import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart'; import 'package:webview_flutter_web/webview_flutter_web.dart'; import 'web_webview_controller_test.mocks.dart'; @GenerateMocks([], customMocks: >[ - MockSpec(onMissingStub: OnMissingStub.returnDefault), MockSpec(onMissingStub: OnMissingStub.returnDefault), ]) void main() { @@ -105,17 +105,20 @@ void main() { httpRequestFactory: mockHttpRequestFactory, )); - final MockHttpRequest mockHttpRequest = MockHttpRequest(); - when(mockHttpRequest.getResponseHeader('content-type')) - .thenReturn('text/plain'); - when(mockHttpRequest.responseText).thenReturn('test data'); + final web.Response fakeResponse = web.Response( + 'test data'.toJS, + { + 'headers': { + 'content-type': 'text/plain', + }, + }.jsify()! as web.ResponseInit); when(mockHttpRequestFactory.request( any, method: anyNamed('method'), requestHeaders: anyNamed('requestHeaders'), sendData: anyNamed('sendData'), - )).thenAnswer((_) => Future.value(mockHttpRequest)); + )).thenAnswer((_) => Future.value(fakeResponse)); await controller.loadRequest(LoadRequestParams( uri: Uri.parse('https://flutter.dev'), @@ -147,18 +150,20 @@ void main() { final Encoding iso = Encoding.getByName('latin1')!; - final MockHttpRequest mockHttpRequest = MockHttpRequest(); - when(mockHttpRequest.responseText) - .thenReturn(String.fromCharCodes(iso.encode('España'))); - when(mockHttpRequest.getResponseHeader('content-type')) - .thenReturn('Text/HTmL; charset=latin1'); + final web.Response fakeResponse = web.Response( + String.fromCharCodes(iso.encode('España')).toJS, + { + 'headers': { + 'content-type': 'Text/HTmL; charset=latin1', + }, + }.jsify()! as web.ResponseInit); when(mockHttpRequestFactory.request( any, method: anyNamed('method'), requestHeaders: anyNamed('requestHeaders'), sendData: anyNamed('sendData'), - )).thenAnswer((_) => Future.value(mockHttpRequest)); + )).thenAnswer((_) => Future.value(fakeResponse)); await controller.loadRequest(LoadRequestParams( uri: Uri.parse('https://flutter.dev'), @@ -179,16 +184,20 @@ void main() { httpRequestFactory: mockHttpRequestFactory, )); - final MockHttpRequest mockHttpRequest = MockHttpRequest(); - when(mockHttpRequest.getResponseHeader('content-type')) - .thenReturn('text/html'); - when(mockHttpRequest.responseText).thenReturn('#'); + final web.Response fakeResponse = web.Response( + '#'.toJS, + { + 'headers': { + 'content-type': 'text/html', + }, + }.jsify()! as web.ResponseInit); + when(mockHttpRequestFactory.request( any, method: anyNamed('method'), requestHeaders: anyNamed('requestHeaders'), sendData: anyNamed('sendData'), - )).thenAnswer((_) => Future.value(mockHttpRequest)); + )).thenAnswer((_) => Future.value(fakeResponse)); await controller.loadRequest(LoadRequestParams( uri: Uri.parse('https://flutter.dev'), diff --git a/packages/webview_flutter/webview_flutter_web/test/web_webview_controller_test.mocks.dart b/packages/webview_flutter/webview_flutter_web/test/web_webview_controller_test.mocks.dart index 52e6e15aeb0f..87fe1defb11d 100644 --- a/packages/webview_flutter/webview_flutter_web/test/web_webview_controller_test.mocks.dart +++ b/packages/webview_flutter/webview_flutter_web/test/web_webview_controller_test.mocks.dart @@ -3,12 +3,11 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i4; -import 'dart:html' as _i2; +import 'dart:async' as _i3; +import 'dart:typed_data' as _i4; import 'package:mockito/mockito.dart' as _i1; -import 'package:mockito/src/dummies.dart' as _i3; -import 'package:webview_flutter_web/src/http_request_factory.dart' as _i5; +import 'package:webview_flutter_web/src/http_request_factory.dart' as _i2; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -23,9 +22,8 @@ import 'package:webview_flutter_web/src/http_request_factory.dart' as _i5; // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class -class _FakeHttpRequestUpload_0 extends _i1.SmartFake - implements _i2.HttpRequestUpload { - _FakeHttpRequestUpload_0( +class _FakeObject_0 extends _i1.SmartFake implements Object { + _FakeObject_0( Object parent, Invocation parentInvocation, ) : super( @@ -34,326 +32,19 @@ class _FakeHttpRequestUpload_0 extends _i1.SmartFake ); } -class _FakeEvents_1 extends _i1.SmartFake implements _i2.Events { - _FakeEvents_1( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeHttpRequest_2 extends _i1.SmartFake implements _i2.HttpRequest { - _FakeHttpRequest_2( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -/// A class which mocks [HttpRequest]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockHttpRequest extends _i1.Mock implements _i2.HttpRequest { - @override - Map get responseHeaders => (super.noSuchMethod( - Invocation.getter(#responseHeaders), - returnValue: {}, - returnValueForMissingStub: {}, - ) as Map); - - @override - int get readyState => (super.noSuchMethod( - Invocation.getter(#readyState), - returnValue: 0, - returnValueForMissingStub: 0, - ) as int); - - @override - String get responseType => (super.noSuchMethod( - Invocation.getter(#responseType), - returnValue: _i3.dummyValue( - this, - Invocation.getter(#responseType), - ), - returnValueForMissingStub: _i3.dummyValue( - this, - Invocation.getter(#responseType), - ), - ) as String); - - @override - set responseType(String? value) => super.noSuchMethod( - Invocation.setter( - #responseType, - value, - ), - returnValueForMissingStub: null, - ); - - @override - set timeout(int? value) => super.noSuchMethod( - Invocation.setter( - #timeout, - value, - ), - returnValueForMissingStub: null, - ); - - @override - _i2.HttpRequestUpload get upload => (super.noSuchMethod( - Invocation.getter(#upload), - returnValue: _FakeHttpRequestUpload_0( - this, - Invocation.getter(#upload), - ), - returnValueForMissingStub: _FakeHttpRequestUpload_0( - this, - Invocation.getter(#upload), - ), - ) as _i2.HttpRequestUpload); - - @override - set withCredentials(bool? value) => super.noSuchMethod( - Invocation.setter( - #withCredentials, - value, - ), - returnValueForMissingStub: null, - ); - - @override - _i4.Stream<_i2.Event> get onReadyStateChange => (super.noSuchMethod( - Invocation.getter(#onReadyStateChange), - returnValue: _i4.Stream<_i2.Event>.empty(), - returnValueForMissingStub: _i4.Stream<_i2.Event>.empty(), - ) as _i4.Stream<_i2.Event>); - - @override - _i4.Stream<_i2.ProgressEvent> get onAbort => (super.noSuchMethod( - Invocation.getter(#onAbort), - returnValue: _i4.Stream<_i2.ProgressEvent>.empty(), - returnValueForMissingStub: _i4.Stream<_i2.ProgressEvent>.empty(), - ) as _i4.Stream<_i2.ProgressEvent>); - - @override - _i4.Stream<_i2.ProgressEvent> get onError => (super.noSuchMethod( - Invocation.getter(#onError), - returnValue: _i4.Stream<_i2.ProgressEvent>.empty(), - returnValueForMissingStub: _i4.Stream<_i2.ProgressEvent>.empty(), - ) as _i4.Stream<_i2.ProgressEvent>); - - @override - _i4.Stream<_i2.ProgressEvent> get onLoad => (super.noSuchMethod( - Invocation.getter(#onLoad), - returnValue: _i4.Stream<_i2.ProgressEvent>.empty(), - returnValueForMissingStub: _i4.Stream<_i2.ProgressEvent>.empty(), - ) as _i4.Stream<_i2.ProgressEvent>); - - @override - _i4.Stream<_i2.ProgressEvent> get onLoadEnd => (super.noSuchMethod( - Invocation.getter(#onLoadEnd), - returnValue: _i4.Stream<_i2.ProgressEvent>.empty(), - returnValueForMissingStub: _i4.Stream<_i2.ProgressEvent>.empty(), - ) as _i4.Stream<_i2.ProgressEvent>); - - @override - _i4.Stream<_i2.ProgressEvent> get onLoadStart => (super.noSuchMethod( - Invocation.getter(#onLoadStart), - returnValue: _i4.Stream<_i2.ProgressEvent>.empty(), - returnValueForMissingStub: _i4.Stream<_i2.ProgressEvent>.empty(), - ) as _i4.Stream<_i2.ProgressEvent>); - - @override - _i4.Stream<_i2.ProgressEvent> get onProgress => (super.noSuchMethod( - Invocation.getter(#onProgress), - returnValue: _i4.Stream<_i2.ProgressEvent>.empty(), - returnValueForMissingStub: _i4.Stream<_i2.ProgressEvent>.empty(), - ) as _i4.Stream<_i2.ProgressEvent>); - - @override - _i4.Stream<_i2.ProgressEvent> get onTimeout => (super.noSuchMethod( - Invocation.getter(#onTimeout), - returnValue: _i4.Stream<_i2.ProgressEvent>.empty(), - returnValueForMissingStub: _i4.Stream<_i2.ProgressEvent>.empty(), - ) as _i4.Stream<_i2.ProgressEvent>); - - @override - _i2.Events get on => (super.noSuchMethod( - Invocation.getter(#on), - returnValue: _FakeEvents_1( - this, - Invocation.getter(#on), - ), - returnValueForMissingStub: _FakeEvents_1( - this, - Invocation.getter(#on), - ), - ) as _i2.Events); - - @override - void open( - String? method, - String? url, { - bool? async, - String? user, - String? password, - }) => - super.noSuchMethod( - Invocation.method( - #open, - [ - method, - url, - ], - { - #async: async, - #user: user, - #password: password, - }, - ), - returnValueForMissingStub: null, - ); - - @override - void abort() => super.noSuchMethod( - Invocation.method( - #abort, - [], - ), - returnValueForMissingStub: null, - ); - - @override - String getAllResponseHeaders() => (super.noSuchMethod( - Invocation.method( - #getAllResponseHeaders, - [], - ), - returnValue: _i3.dummyValue( - this, - Invocation.method( - #getAllResponseHeaders, - [], - ), - ), - returnValueForMissingStub: _i3.dummyValue( - this, - Invocation.method( - #getAllResponseHeaders, - [], - ), - ), - ) as String); - - @override - String? getResponseHeader(String? name) => (super.noSuchMethod( - Invocation.method( - #getResponseHeader, - [name], - ), - returnValueForMissingStub: null, - ) as String?); - - @override - void overrideMimeType(String? mime) => super.noSuchMethod( - Invocation.method( - #overrideMimeType, - [mime], - ), - returnValueForMissingStub: null, - ); - - @override - void send([dynamic body_OR_data]) => super.noSuchMethod( - Invocation.method( - #send, - [body_OR_data], - ), - returnValueForMissingStub: null, - ); - - @override - void setRequestHeader( - String? name, - String? value, - ) => - super.noSuchMethod( - Invocation.method( - #setRequestHeader, - [ - name, - value, - ], - ), - returnValueForMissingStub: null, - ); - - @override - void addEventListener( - String? type, - _i2.EventListener? listener, [ - bool? useCapture, - ]) => - super.noSuchMethod( - Invocation.method( - #addEventListener, - [ - type, - listener, - useCapture, - ], - ), - returnValueForMissingStub: null, - ); - - @override - void removeEventListener( - String? type, - _i2.EventListener? listener, [ - bool? useCapture, - ]) => - super.noSuchMethod( - Invocation.method( - #removeEventListener, - [ - type, - listener, - useCapture, - ], - ), - returnValueForMissingStub: null, - ); - - @override - bool dispatchEvent(_i2.Event? event) => (super.noSuchMethod( - Invocation.method( - #dispatchEvent, - [event], - ), - returnValue: false, - returnValueForMissingStub: false, - ) as bool); -} - /// A class which mocks [HttpRequestFactory]. /// /// See the documentation for Mockito's code generation for more information. class MockHttpRequestFactory extends _i1.Mock - implements _i5.HttpRequestFactory { + implements _i2.HttpRequestFactory { @override - _i4.Future<_i2.HttpRequest> request( + _i3.Future request( String? url, { - String? method, - bool? withCredentials, - String? responseType, + String? method = r'GET', + bool? withCredentials = false, String? mimeType, Map? requestHeaders, - dynamic sendData, - void Function(_i2.ProgressEvent)? onProgress, + _i4.Uint8List? sendData, }) => (super.noSuchMethod( Invocation.method( @@ -362,14 +53,12 @@ class MockHttpRequestFactory extends _i1.Mock { #method: method, #withCredentials: withCredentials, - #responseType: responseType, #mimeType: mimeType, #requestHeaders: requestHeaders, #sendData: sendData, - #onProgress: onProgress, }, ), - returnValue: _i4.Future<_i2.HttpRequest>.value(_FakeHttpRequest_2( + returnValue: _i3.Future.value(_FakeObject_0( this, Invocation.method( #request, @@ -377,16 +66,13 @@ class MockHttpRequestFactory extends _i1.Mock { #method: method, #withCredentials: withCredentials, - #responseType: responseType, #mimeType: mimeType, #requestHeaders: requestHeaders, #sendData: sendData, - #onProgress: onProgress, }, ), )), - returnValueForMissingStub: - _i4.Future<_i2.HttpRequest>.value(_FakeHttpRequest_2( + returnValueForMissingStub: _i3.Future.value(_FakeObject_0( this, Invocation.method( #request, @@ -394,13 +80,11 @@ class MockHttpRequestFactory extends _i1.Mock { #method: method, #withCredentials: withCredentials, - #responseType: responseType, #mimeType: mimeType, #requestHeaders: requestHeaders, #sendData: sendData, - #onProgress: onProgress, }, ), )), - ) as _i4.Future<_i2.HttpRequest>); + ) as _i3.Future); } diff --git a/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md b/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md index 14f55957ad96..134f22aad28b 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md @@ -1,3 +1,19 @@ +## 3.16.1 + +* Adds `missing_code_block_language_in_doc_comment` lint. + +## 3.16.0 + +* Supports NTLM for authentication. + +## 3.15.0 + +* Adds macOS support. + +## 3.14.0 + +* Adds Swift Package Manager compatibility. + ## 3.13.1 * Fixes `JSON.stringify()` cannot serialize cyclic structures. @@ -84,7 +100,7 @@ * Introduces `NSError.toString` for better diagnostics. -## 3.6.2 +## 3.6.2 * Fixes unawaited_futures violations. diff --git a/packages/webview_flutter/webview_flutter_wkwebview/README.md b/packages/webview_flutter/webview_flutter_wkwebview/README.md index 3cbec14339e7..58f50ca90fc4 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/README.md +++ b/packages/webview_flutter/webview_flutter_wkwebview/README.md @@ -45,7 +45,7 @@ dart run build_runner build --delete-conflicting-outputs If you would like to contribute to the plugin, check out our [contribution guide][5]. [1]: https://pub.dev/packages/webview_flutter -[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[2]: https://flutter.dev/to/endorsed-federated-plugin [3]: https://pub.dev/packages/pigeon [4]: https://pub.dev/packages/mockito [5]: https://github.com/flutter/packages/blob/main/CONTRIBUTING.md diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFDataConvertersTests.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFDataConvertersTests.m similarity index 95% rename from packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFDataConvertersTests.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFDataConvertersTests.m index a4ff58a47ea5..642c138d14ba 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFDataConvertersTests.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFDataConvertersTests.m @@ -2,10 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -@import Flutter; @import XCTest; @import webview_flutter_wkwebview; +#if TARGET_OS_OSX +@import FlutterMacOS; +#else +@import Flutter; +#endif + #import @interface FWFDataConvertersTests : XCTestCase @@ -61,8 +66,8 @@ - (void)testFWFWKNavigationActionDataFromNavigationAction { OCMStub([mockNavigationAction navigationType]).andReturn(WKNavigationTypeReload); - NSURLRequest *request = - [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.flutter.dev/"]]; + NSURL *testURL = [NSURL URLWithString:@"https://www.flutter.dev/"]; + NSURLRequest *request = [NSURLRequest requestWithURL:testURL]; OCMStub([mockNavigationAction request]).andReturn(request); WKFrameInfo *mockFrameInfo = OCMClassMock([WKFrameInfo class]); @@ -76,8 +81,8 @@ - (void)testFWFWKNavigationActionDataFromNavigationAction { } - (void)testFWFNSUrlRequestDataFromNSURLRequest { - NSMutableURLRequest *request = - [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://www.flutter.dev/"]]; + NSURL *testURL = [NSURL URLWithString:@"https://www.flutter.dev/"]; + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:testURL]; request.HTTPMethod = @"POST"; request.HTTPBody = [@"aString" dataUsingEncoding:NSUTF8StringEncoding]; request.allHTTPHeaderFields = @{@"a" : @"field"}; @@ -137,7 +142,7 @@ - (void)testFWFWKSecurityOriginDataFromWKSecurityOrigin { XCTAssertEqualObjects(data.protocol, @"protocol"); } -- (void)testFWFWKPermissionDecisionFromData API_AVAILABLE(ios(15.0)) { +- (void)testFWFWKPermissionDecisionFromData API_AVAILABLE(ios(15.0), macos(12)) { XCTAssertEqual(FWFNativeWKPermissionDecisionFromData( [FWFWKPermissionDecisionData makeWithValue:FWFWKPermissionDecisionDeny]), WKPermissionDecisionDeny); @@ -149,7 +154,7 @@ - (void)testFWFWKPermissionDecisionFromData API_AVAILABLE(ios(15.0)) { WKPermissionDecisionPrompt); } -- (void)testFWFWKMediaCaptureTypeDataFromWKMediaCaptureType API_AVAILABLE(ios(15.0)) { +- (void)testFWFWKMediaCaptureTypeDataFromWKMediaCaptureType API_AVAILABLE(ios(15.0), macos(12)) { XCTAssertEqual( FWFWKMediaCaptureTypeDataFromNativeWKMediaCaptureType(WKMediaCaptureTypeCamera).value, FWFWKMediaCaptureTypeCamera); diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFErrorTests.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFErrorTests.m similarity index 100% rename from packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFErrorTests.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFErrorTests.m diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFHTTPCookieStoreHostApiTests.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFHTTPCookieStoreHostApiTests.m similarity index 90% rename from packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFHTTPCookieStoreHostApiTests.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFHTTPCookieStoreHostApiTests.m index 478e4fedef01..eb1e6f250ff8 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFHTTPCookieStoreHostApiTests.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFHTTPCookieStoreHostApiTests.m @@ -2,10 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -@import Flutter; @import XCTest; @import webview_flutter_wkwebview; +#if TARGET_OS_OSX +@import FlutterMacOS; +#else +@import Flutter; +#endif + #import @interface FWFHTTPCookieStoreHostApiTests : XCTestCase @@ -47,9 +52,8 @@ - (void)testSetCookie { completion:^(FlutterError *error) { blockError = error; }]; - OCMVerify([mockHttpCookieStore - setCookie:[NSHTTPCookie cookieWithProperties:@{NSHTTPCookieName : @"hello"}] - completionHandler:OCMOCK_ANY]); + NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:@{NSHTTPCookieName : @"hello"}]; + OCMVerify([mockHttpCookieStore setCookie:cookie completionHandler:OCMOCK_ANY]); XCTAssertNil(blockError); } @end diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFInstanceManagerTests.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFInstanceManagerTests.m similarity index 96% rename from packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFInstanceManagerTests.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFInstanceManagerTests.m index 34ceb613f6f8..710dcb791b2a 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFInstanceManagerTests.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFInstanceManagerTests.m @@ -2,10 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import +@import XCTest; @import webview_flutter_wkwebview; +#if __has_include() @import webview_flutter_wkwebview.Test; +#endif @interface FWFInstanceManagerTests : XCTestCase @end diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFNavigationDelegateHostApiTests.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFNavigationDelegateHostApiTests.m similarity index 97% rename from packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFNavigationDelegateHostApiTests.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFNavigationDelegateHostApiTests.m index 829d27643bfb..4bd8337070b4 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFNavigationDelegateHostApiTests.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFNavigationDelegateHostApiTests.m @@ -2,10 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -@import Flutter; @import XCTest; @import webview_flutter_wkwebview; +#if TARGET_OS_OSX +@import FlutterMacOS; +#else +@import Flutter; +#endif + #import @interface FWFNavigationDelegateHostApiTests : XCTestCase @@ -117,8 +122,8 @@ - (void)testDecidePolicyForNavigationAction { [instanceManager addDartCreatedInstance:mockWebView withIdentifier:1]; WKNavigationAction *mockNavigationAction = OCMClassMock([WKNavigationAction class]); - OCMStub([mockNavigationAction request]) - .andReturn([NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.flutter.dev"]]); + NSURL *testURL = [NSURL URLWithString:@"https://www.flutter.dev"]; + OCMStub([mockNavigationAction request]).andReturn([NSURLRequest requestWithURL:testURL]); WKFrameInfo *mockFrameInfo = OCMClassMock([WKFrameInfo class]); OCMStub([mockFrameInfo isMainFrame]).andReturn(YES); @@ -258,10 +263,10 @@ - (void)testDidReceiveAuthenticationChallenge { NSURLCredential *__block callbackCredential; [mockDelegate webView:mockWebView didReceiveAuthenticationChallenge:mockChallenge - completionHandler:^(NSURLSessionAuthChallengeDisposition disposition, - NSURLCredential *credential) { - callbackDisposition = disposition; - callbackCredential = credential; + completionHandler:^(NSURLSessionAuthChallengeDisposition dispositionArg, + NSURLCredential *credentialArg) { + callbackDisposition = dispositionArg; + callbackCredential = credentialArg; }]; XCTAssertEqual(callbackDisposition, NSURLSessionAuthChallengeCancelAuthenticationChallenge); diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFObjectHostApiTests.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFObjectHostApiTests.m similarity index 92% rename from packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFObjectHostApiTests.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFObjectHostApiTests.m index 8c0b90850a82..4b4f576ffeef 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFObjectHostApiTests.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFObjectHostApiTests.m @@ -2,10 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -@import Flutter; @import XCTest; @import webview_flutter_wkwebview; +#if TARGET_OS_OSX +@import FlutterMacOS; +#else +@import Flutter; +#endif + #import @interface FWFObjectHostApiTests : XCTestCase @@ -139,8 +144,10 @@ - (void)testObserveValueForKeyPath { return value[0].value == FWFNSKeyValueChangeKeyEnumOldValue; }] changeValues:[OCMArg checkWithBlock:^BOOL(id value) { - FWFObjectOrIdentifier *object = (FWFObjectOrIdentifier *)value[0]; - return !object.isIdentifier && [@"key" isEqual:object.value]; + FWFObjectOrIdentifier *changeObject = + (FWFObjectOrIdentifier *)value[0]; + return !changeObject.isIdentifier && + [@"key" isEqual:changeObject.value]; }] completion:OCMOCK_ANY]); } @@ -173,8 +180,10 @@ - (void)testObserveValueForKeyPathWithIdentifier { return value[0].value == FWFNSKeyValueChangeKeyEnumOldValue; }] changeValues:[OCMArg checkWithBlock:^BOOL(id value) { - FWFObjectOrIdentifier *object = (FWFObjectOrIdentifier *)value[0]; - return object.isIdentifier && [@(2) isEqual:object.value]; + FWFObjectOrIdentifier *changeObject = + (FWFObjectOrIdentifier *)value[0]; + return changeObject.isIdentifier && + [@(2) isEqual:changeObject.value]; }] completion:OCMOCK_ANY]); } diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFPreferencesHostApiTests.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFPreferencesHostApiTests.m similarity index 96% rename from packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFPreferencesHostApiTests.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFPreferencesHostApiTests.m index dcbe75bf58fb..f0f919619788 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFPreferencesHostApiTests.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFPreferencesHostApiTests.m @@ -2,10 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -@import Flutter; @import XCTest; @import webview_flutter_wkwebview; +#if TARGET_OS_OSX +@import FlutterMacOS; +#else +@import Flutter; +#endif + #import @interface FWFPreferencesHostApiTests : XCTestCase diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFScriptMessageHandlerHostApiTests.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFScriptMessageHandlerHostApiTests.m similarity index 98% rename from packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFScriptMessageHandlerHostApiTests.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFScriptMessageHandlerHostApiTests.m index fb9958726286..30064b5dfaa0 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFScriptMessageHandlerHostApiTests.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFScriptMessageHandlerHostApiTests.m @@ -2,10 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -@import Flutter; @import XCTest; @import webview_flutter_wkwebview; +#if TARGET_OS_OSX +@import FlutterMacOS; +#else +@import Flutter; +#endif + #import @interface FWFScriptMessageHandlerHostApiTests : XCTestCase diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFScrollViewDelegateHostApiTests.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFScrollViewDelegateHostApiTests.m similarity index 96% rename from packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFScrollViewDelegateHostApiTests.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFScrollViewDelegateHostApiTests.m index 02e89aa6cec1..21a6f4e70201 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFScrollViewDelegateHostApiTests.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFScrollViewDelegateHostApiTests.m @@ -2,6 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "TargetConditionals.h" + +// The scroll view delegate does not exist on macOS. +#if !TARGET_OS_OSX + @import Flutter; @import XCTest; @import webview_flutter_wkwebview; @@ -80,3 +85,5 @@ - (void)testOnScrollViewDidScrollForDelegateWithIdentifier { completion:OCMOCK_ANY]); } @end + +#endif // !TARGET_OS_OSX diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFScrollViewHostApiTests.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFScrollViewHostApiTests.m similarity index 96% rename from packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFScrollViewHostApiTests.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFScrollViewHostApiTests.m index 306fc8f9dfc4..17512ce4b5c6 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFScrollViewHostApiTests.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFScrollViewHostApiTests.m @@ -2,6 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#import "TargetConditionals.h" + +// Scroll view APIs do not existing on macOS. +#if !TARGET_OS_OSX + @import Flutter; @import XCTest; @import webview_flutter_wkwebview; @@ -79,3 +84,5 @@ - (void)testSetDelegateForScrollView { XCTAssertNil(error); } @end + +#endif // !TARGET_OS_OSX diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFUIDelegateHostApiTests.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFUIDelegateHostApiTests.m similarity index 95% rename from packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFUIDelegateHostApiTests.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFUIDelegateHostApiTests.m index ac13eb5811be..792d65da669e 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFUIDelegateHostApiTests.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFUIDelegateHostApiTests.m @@ -2,10 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -@import Flutter; @import XCTest; @import webview_flutter_wkwebview; +#if __has_include() @import webview_flutter_wkwebview.Test; +#endif + +#if TARGET_OS_OSX +@import FlutterMacOS; +#else +@import Flutter; +#endif #import @@ -75,8 +82,8 @@ - (void)testOnCreateWebViewForDelegateWithIdentifier { .ignoringNonObjectArgs(); WKNavigationAction *mockNavigationAction = OCMClassMock([WKNavigationAction class]); - OCMStub([mockNavigationAction request]) - .andReturn([NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.flutter.dev"]]); + NSURL *testURL = [NSURL URLWithString:@"https://www.flutter.dev"]; + OCMStub([mockNavigationAction request]).andReturn([NSURLRequest requestWithURL:testURL]); WKFrameInfo *mockFrameInfo = OCMClassMock([WKFrameInfo class]); OCMStub([mockFrameInfo isMainFrame]).andReturn(YES); @@ -98,7 +105,7 @@ - (void)testOnCreateWebViewForDelegateWithIdentifier { completion:OCMOCK_ANY]); } -- (void)testRequestMediaCapturePermissionForOrigin API_AVAILABLE(ios(15.0)) { +- (void)testRequestMediaCapturePermissionForOrigin API_AVAILABLE(ios(15.0), macos(12)) { FWFInstanceManager *instanceManager = [[FWFInstanceManager alloc] init]; FWFUIDelegate *mockDelegate = [self mockDelegateWithManager:instanceManager identifier:0]; diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFUIViewHostApiTests.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFUIViewHostApiTests.m similarity index 95% rename from packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFUIViewHostApiTests.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFUIViewHostApiTests.m index d15937b1fe9c..4c2ceecfaa9e 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFUIViewHostApiTests.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFUIViewHostApiTests.m @@ -2,6 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#import "TargetConditionals.h" + +#if !TARGET_OS_OSX + @import Flutter; @import XCTest; @import webview_flutter_wkwebview; @@ -47,3 +51,5 @@ - (void)testSetOpaque { } @end + +#endif // !TARGET_OS_OSX diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFURLAuthenticationChallengeHostApiTests.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFURLAuthenticationChallengeHostApiTests.m similarity index 97% rename from packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFURLAuthenticationChallengeHostApiTests.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFURLAuthenticationChallengeHostApiTests.m index fc0edf9f4027..ff6fb663cf84 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFURLAuthenticationChallengeHostApiTests.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFURLAuthenticationChallengeHostApiTests.m @@ -2,10 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -@import Flutter; @import XCTest; @import webview_flutter_wkwebview; +#if TARGET_OS_OSX +@import FlutterMacOS; +#else +@import Flutter; +#endif + #import @interface FWFURLAuthenticationChallengeHostApiTests : XCTestCase diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFURLCredentialHostApiTests.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFURLCredentialHostApiTests.m similarity index 95% rename from packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFURLCredentialHostApiTests.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFURLCredentialHostApiTests.m index 7f3aa3426dad..bcc9f59e506c 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFURLCredentialHostApiTests.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFURLCredentialHostApiTests.m @@ -2,10 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -@import Flutter; @import XCTest; @import webview_flutter_wkwebview; +#if TARGET_OS_OSX +@import FlutterMacOS; +#else +@import Flutter; +#endif + #import @interface FWFURLCredentialHostApiTests : XCTestCase diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFURLProtectionSpaceHostApiTests.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFURLProtectionSpaceHostApiTests.m similarity index 97% rename from packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFURLProtectionSpaceHostApiTests.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFURLProtectionSpaceHostApiTests.m index c5a6cdf36cf1..be5738e919eb 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFURLProtectionSpaceHostApiTests.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFURLProtectionSpaceHostApiTests.m @@ -2,10 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -@import Flutter; @import XCTest; @import webview_flutter_wkwebview; +#if TARGET_OS_OSX +@import FlutterMacOS; +#else +@import Flutter; +#endif + #import @interface FWFURLProtectionSpaceHostApiTests : XCTestCase diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFURLTests.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFURLTests.m similarity index 96% rename from packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFURLTests.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFURLTests.m index 7e8d2ad0f129..a2e88197ca84 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFURLTests.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFURLTests.m @@ -2,10 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -@import Flutter; @import XCTest; @import webview_flutter_wkwebview; +#if TARGET_OS_OSX +@import FlutterMacOS; +#else +@import Flutter; +#endif + #import @interface FWFURLTests : XCTestCase diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFUserContentControllerHostApiTests.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFUserContentControllerHostApiTests.m similarity index 98% rename from packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFUserContentControllerHostApiTests.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFUserContentControllerHostApiTests.m index 38da70fd62a3..82ca3261d1a4 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFUserContentControllerHostApiTests.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFUserContentControllerHostApiTests.m @@ -2,10 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -@import Flutter; @import XCTest; @import webview_flutter_wkwebview; +#if TARGET_OS_OSX +@import FlutterMacOS; +#else +@import Flutter; +#endif + #import @interface FWFUserContentControllerHostApiTests : XCTestCase @@ -66,7 +71,7 @@ - (void)testRemoveScriptMessageHandler { XCTAssertNil(error); } -- (void)testRemoveAllScriptMessageHandlers API_AVAILABLE(ios(14.0)) { +- (void)testRemoveAllScriptMessageHandlers API_AVAILABLE(ios(14.0), macos(11)) { WKUserContentController *mockUserContentController = OCMClassMock([WKUserContentController class]); diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFWebViewConfigurationHostApiTests.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFWebViewConfigurationHostApiTests.m similarity index 96% rename from packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFWebViewConfigurationHostApiTests.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFWebViewConfigurationHostApiTests.m index 5670468c0439..585f4cd047c6 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFWebViewConfigurationHostApiTests.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFWebViewConfigurationHostApiTests.m @@ -2,10 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -@import Flutter; @import XCTest; @import webview_flutter_wkwebview; +#if TARGET_OS_OSX +@import FlutterMacOS; +#else +@import Flutter; +#endif + #import @interface FWFWebViewConfigurationHostApiTests : XCTestCase @@ -56,11 +61,14 @@ - (void)testSetAllowsInlineMediaPlayback { FlutterError *error; [hostAPI setAllowsInlineMediaPlaybackForConfigurationWithIdentifier:0 isAllowed:NO error:&error]; + // setAllowsInlineMediaPlayback does not existing on macOS; the call above should no-op for macOS. +#if !TARGET_OS_OSX OCMVerify([mockWebViewConfiguration setAllowsInlineMediaPlayback:NO]); +#endif XCTAssertNil(error); } -- (void)testSetLimitsNavigationsToAppBoundDomains API_AVAILABLE(ios(14.0)) { +- (void)testSetLimitsNavigationsToAppBoundDomains API_AVAILABLE(ios(14.0), macos(11)) { WKWebViewConfiguration *mockWebViewConfiguration = OCMClassMock([WKWebViewConfiguration class]); FWFInstanceManager *instanceManager = [[FWFInstanceManager alloc] init]; diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFWebViewFlutterWKWebViewExternalAPITests.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFWebViewFlutterWKWebViewExternalAPITests.m similarity index 91% rename from packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFWebViewFlutterWKWebViewExternalAPITests.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFWebViewFlutterWKWebViewExternalAPITests.m index 1452edeaa647..d4137c1997be 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFWebViewFlutterWKWebViewExternalAPITests.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFWebViewFlutterWKWebViewExternalAPITests.m @@ -2,8 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +@import XCTest; + +#if TARGET_OS_OSX +@import FlutterMacOS; +#else +@import Flutter; +#endif + #import -#import @import webview_flutter_wkwebview; diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFWebViewHostApiTests.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFWebViewHostApiTests.m similarity index 97% rename from packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFWebViewHostApiTests.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFWebViewHostApiTests.m index 568e5fe1ed1c..49d5a20dd57c 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFWebViewHostApiTests.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFWebViewHostApiTests.m @@ -2,13 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -@import Flutter; @import XCTest; @import webview_flutter_wkwebview; +#if TARGET_OS_OSX +@import FlutterMacOS; +#else +@import Flutter; +#endif + #import +// Only used in !OSX test code, and causes unused function error if not ifdef'd out. +#if !TARGET_OS_OSX static bool feq(CGFloat a, CGFloat b) { return fabs(b - a) < FLT_EPSILON; } +#endif @interface FWFWebViewHostApiTests : XCTestCase @end @@ -78,8 +86,8 @@ - (void)testLoadRequestWithInvalidUrl { XCTAssertEqualObjects(error.message, @"Failed instantiating an NSURLRequest."); XCTAssertEqualObjects(error.details, @"URL was: '%invalidUrl%'"); } else { - NSMutableURLRequest *request = - [NSMutableURLRequest requestWithURL:[NSURL URLWithString:badURLString]]; + NSURL *badURL = [NSURL URLWithString:badURLString]; + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:badURL]; OCMVerify([mockWebView loadRequest:request]); } } @@ -252,9 +260,9 @@ - (void)testLoadFlutterAsset { [hostAPI loadAssetForWebViewWithIdentifier:0 assetKey:@"assets/index.html" error:&error]; XCTAssertNil(error); - OCMVerify([mockWebView - loadFileURL:[NSURL URLWithString:@"webview_flutter/myFolder/assets/index.html"] - allowingReadAccessToURL:[NSURL URLWithString:@"webview_flutter/myFolder/assets/"]]); + NSURL *fileURL = [NSURL URLWithString:@"webview_flutter/myFolder/assets/index.html"]; + NSURL *directoryURL = [NSURL URLWithString:@"webview_flutter/myFolder/assets/"]; + OCMVerify([mockWebView loadFileURL:fileURL allowingReadAccessToURL:directoryURL]); } - (void)testCanGoForward { @@ -418,6 +426,8 @@ - (void)testEvaluateJavaScriptReturnsNSErrorData { XCTAssertEqualObjects(errorData.userInfo, @{NSLocalizedDescriptionKey : @"description"}); } +// Content inset APIs don't exist on macOS. +#if !TARGET_OS_OSX - (void)testWebViewContentInsetBehaviorShouldBeNever { FWFInstanceManager *instanceManager = [[FWFInstanceManager alloc] init]; FWFWebViewHostApiImpl *hostAPI = [[FWFWebViewHostApiImpl alloc] @@ -471,6 +481,7 @@ - (void)testContentInsetsSumAlwaysZeroAfterSetFrame { XCTAssertTrue(feq(webView.scrollView.contentInset.bottom, -insetToAdjust.bottom)); XCTAssertTrue(CGRectEqualToRect(webView.frame, CGRectMake(0, 0, 300, 100))); } +#endif // !TARGET_OS_OSX - (void)testSetInspectable API_AVAILABLE(ios(16.4), macos(13.3)) { FWFWebView *mockWebView = OCMClassMock([FWFWebView class]); diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFWebsiteDataStoreHostApiTests.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFWebsiteDataStoreHostApiTests.m similarity index 98% rename from packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFWebsiteDataStoreHostApiTests.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFWebsiteDataStoreHostApiTests.m index 880c81e59e95..bab732b88de2 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFWebsiteDataStoreHostApiTests.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFWebsiteDataStoreHostApiTests.m @@ -2,10 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -@import Flutter; @import XCTest; @import webview_flutter_wkwebview; +#if TARGET_OS_OSX +@import FlutterMacOS; +#else +@import Flutter; +#endif + #import @interface FWFWebsiteDataStoreHostApiTests : XCTestCase diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/webview_flutter_wkwebview.podspec b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview.podspec similarity index 63% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/webview_flutter_wkwebview.podspec rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview.podspec index a58992bf0bcc..af606661b6b5 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/webview_flutter_wkwebview.podspec +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview.podspec @@ -14,12 +14,13 @@ Downloaded by pub (not CocoaPods). s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } s.source = { :http => 'https://github.com/flutter/packages/tree/main/packages/webview_flutter/webview_flutter_wkwebview' } s.documentation_url = 'https://pub.dev/packages/webview_flutter' - s.source_files = 'Classes/**/*.{h,m}' - s.public_header_files = 'Classes/**/*.h' - s.module_map = 'Classes/FlutterWebView.modulemap' - s.dependency 'Flutter' - - s.platform = :ios, '12.0' + s.source_files = 'webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/**/*.{h,m}' + s.public_header_files = 'webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/**/*.h' + s.module_map = 'webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/FlutterWebView.modulemap' + s.ios.dependency 'Flutter' + s.osx.dependency 'FlutterMacOS' + s.ios.deployment_target = '12.0' + s.osx.deployment_target = '10.14' s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } - s.resource_bundles = {'webview_flutter_wkwebview_privacy' => ['Resources/PrivacyInfo.xcprivacy']} + s.resource_bundles = {'webview_flutter_wkwebview_privacy' => ['webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/Resources/PrivacyInfo.xcprivacy']} end diff --git a/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Package.swift b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Package.swift new file mode 100644 index 000000000000..127814584215 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Package.swift @@ -0,0 +1,32 @@ +// swift-tools-version: 5.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. + +import PackageDescription + +let package = Package( + name: "webview_flutter_wkwebview", + platforms: [ + .iOS("12.0"), + .macOS("10.14"), + ], + products: [ + .library(name: "webview-flutter-wkwebview", targets: ["webview_flutter_wkwebview"]) + ], + dependencies: [], + targets: [ + .target( + name: "webview_flutter_wkwebview", + dependencies: [], + exclude: ["include/FlutterWebView.modulemap", "include/webview-umbrella.h"], + resources: [ + .process("Resources") + ], + cSettings: [ + .headerSearchPath("include/webview_flutter_wkwebview") + ] + ) + ] +) diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FLTWebViewFlutterPlugin.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FLTWebViewFlutterPlugin.m similarity index 75% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FLTWebViewFlutterPlugin.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FLTWebViewFlutterPlugin.m index 8d2d0bf28eb2..ffa5da84c408 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FLTWebViewFlutterPlugin.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FLTWebViewFlutterPlugin.m @@ -2,24 +2,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FLTWebViewFlutterPlugin.h" -#import "FWFGeneratedWebKitApis.h" -#import "FWFHTTPCookieStoreHostApi.h" -#import "FWFInstanceManager.h" -#import "FWFNavigationDelegateHostApi.h" -#import "FWFObjectHostApi.h" -#import "FWFPreferencesHostApi.h" -#import "FWFScriptMessageHandlerHostApi.h" -#import "FWFScrollViewDelegateHostApi.h" -#import "FWFScrollViewHostApi.h" -#import "FWFUIDelegateHostApi.h" -#import "FWFUIViewHostApi.h" -#import "FWFURLCredentialHostApi.h" -#import "FWFURLHostApi.h" -#import "FWFUserContentControllerHostApi.h" -#import "FWFWebViewConfigurationHostApi.h" -#import "FWFWebViewHostApi.h" -#import "FWFWebsiteDataStoreHostApi.h" +#import "./include/webview_flutter_wkwebview/FLTWebViewFlutterPlugin.h" +#import "./include/webview_flutter_wkwebview/FWFGeneratedWebKitApis.h" +#import "./include/webview_flutter_wkwebview/FWFHTTPCookieStoreHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFInstanceManager.h" +#import "./include/webview_flutter_wkwebview/FWFNavigationDelegateHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFObjectHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFPreferencesHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFScriptMessageHandlerHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFScrollViewDelegateHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFScrollViewHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFUIDelegateHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFUIViewHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFURLCredentialHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFURLHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFUserContentControllerHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFWebViewConfigurationHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFWebViewHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFWebsiteDataStoreHostApi.h" @interface FWFWebViewFactory : NSObject @property(nonatomic, weak) FWFInstanceManager *instanceManager; @@ -36,10 +36,16 @@ - (instancetype)initWithManager:(FWFInstanceManager *)manager { return self; } +#pragma mark FlutterPlatformViewFactory + - (NSObject *)createArgsCodec { return [FlutterStandardMessageCodec sharedInstance]; } +// The FlutterPlatformViewFactory protocol is slightly different on iOS and +// macOS. +#if TARGET_OS_IOS + - (NSObject *)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id _Nullable)args { @@ -50,6 +56,17 @@ - (instancetype)initWithManager:(FWFInstanceManager *)manager { return webView; } +#else + +- (nonnull NSView *)createWithViewIdentifier:(int64_t)viewId arguments:(nullable id)args { + NSNumber *identifier = (NSNumber *)args; + FWFWebView *webView = + (FWFWebView *)[self.instanceManager instanceForIdentifier:identifier.longValue]; + return webView; +} + +#endif + @end @implementation FLTWebViewFlutterPlugin @@ -88,8 +105,10 @@ + (void)registerWithRegistrar:(NSObject *)registrar { SetUpFWFWKUIDelegateHostApi(registrar.messenger, [[FWFUIDelegateHostApiImpl alloc] initWithBinaryMessenger:registrar.messenger instanceManager:instanceManager]); +#if TARGET_OS_IOS SetUpFWFUIViewHostApi(registrar.messenger, [[FWFUIViewHostApiImpl alloc] initWithInstanceManager:instanceManager]); +#endif SetUpFWFWKUserContentControllerHostApi( registrar.messenger, [[FWFUserContentControllerHostApiImpl alloc] initWithInstanceManager:instanceManager]); @@ -106,10 +125,12 @@ + (void)registerWithRegistrar:(NSObject *)registrar { SetUpFWFNSUrlHostApi(registrar.messenger, [[FWFURLHostApiImpl alloc] initWithBinaryMessenger:registrar.messenger instanceManager:instanceManager]); +#if TARGET_OS_IOS SetUpFWFUIScrollViewDelegateHostApi( registrar.messenger, [[FWFScrollViewDelegateHostApiImpl alloc] initWithBinaryMessenger:registrar.messenger instanceManager:instanceManager]); +#endif SetUpFWFNSUrlCredentialHostApi( registrar.messenger, [[FWFURLCredentialHostApiImpl alloc] initWithBinaryMessenger:registrar.messenger diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFDataConverters.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFDataConverters.m similarity index 98% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFDataConverters.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFDataConverters.m index 51a5ada5030b..ba752f3a8e33 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFDataConverters.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFDataConverters.m @@ -2,9 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FWFDataConverters.h" +#import "./include/webview_flutter_wkwebview/FWFDataConverters.h" +#if TARGET_OS_OSX +#import +#else #import +#endif NSURLRequest *_Nullable FWFNativeNSURLRequestFromRequestData(FWFNSUrlRequestData *data) { NSURL *url = [NSURL URLWithString:data.url]; @@ -83,7 +87,7 @@ NSHTTPCookiePropertyKey _Nullable FWFNativeNSHTTPCookiePropertyKeyFromEnumData( case FWFNSHttpCookiePropertyKeyEnumPort: return NSHTTPCookiePort; case FWFNSHttpCookiePropertyKeyEnumSameSitePolicy: - if (@available(iOS 13.0, *)) { + if (@available(iOS 13.0, macOS 10.15, *)) { return NSHTTPCookieSameSitePolicy; } else { return nil; diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFGeneratedWebKitApis.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFGeneratedWebKitApis.m similarity index 73% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFGeneratedWebKitApis.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFGeneratedWebKitApis.m index 352f9b1c161d..0ceb9214ddec 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFGeneratedWebKitApis.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFGeneratedWebKitApis.m @@ -1,10 +1,10 @@ // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v13.0.0), do not edit directly. +// Autogenerated from Pigeon (v18.0.0), do not edit directly. // See also: https://pub.dev/packages/pigeon -#import "FWFGeneratedWebKitApis.h" +#import "./include/webview_flutter_wkwebview/FWFGeneratedWebKitApis.h" #if TARGET_OS_OSX #import @@ -16,6 +16,29 @@ #error File requires ARC to be enabled. #endif +static NSArray *wrapResult(id result, FlutterError *error) { + if (error) { + return @[ + error.code ?: [NSNull null], error.message ?: [NSNull null], error.details ?: [NSNull null] + ]; + } + return @[ result ?: [NSNull null] ]; +} + +static FlutterError *createConnectionError(NSString *channelName) { + return [FlutterError + errorWithCode:@"channel-error" + message:[NSString stringWithFormat:@"%@/%@/%@", + @"Unable to establish connection on channel: '", + channelName, @"'."] + details:@""]; +} + +static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) { + id result = array[key]; + return (result == [NSNull null]) ? nil : result; +} + /// Mirror of NSKeyValueObservingOptions. /// /// See @@ -202,19 +225,6 @@ - (instancetype)initWithValue:(FWFNSUrlCredentialPersistence)value { } @end -static NSArray *wrapResult(id result, FlutterError *error) { - if (error) { - return @[ - error.code ?: [NSNull null], error.message ?: [NSNull null], error.details ?: [NSNull null] - ]; - } - return @[ result ?: [NSNull null] ]; -} -static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) { - id result = array[key]; - return (result == [NSNull null]) ? nil : result; -} - @interface FWFNSKeyValueObservingOptionsEnumData () + (FWFNSKeyValueObservingOptionsEnumData *)fromList:(NSArray *)list; + (nullable FWFNSKeyValueObservingOptionsEnumData *)nullableFromList:(NSArray *)list; @@ -910,10 +920,22 @@ - (FlutterStandardReader *)readerWithData:(NSData *)data { void SetUpFWFWKWebsiteDataStoreHostApi(id binaryMessenger, NSObject *api) { + SetUpFWFWKWebsiteDataStoreHostApiWithSuffix(binaryMessenger, api, @""); +} + +void SetUpFWFWKWebsiteDataStoreHostApiWithSuffix(id binaryMessenger, + NSObject *api, + NSString *messageChannelSuffix) { + messageChannelSuffix = messageChannelSuffix.length > 0 + ? [NSString stringWithFormat:@".%@", messageChannelSuffix] + : @""; { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebsiteDataStoreHostApi." - @"createFromWebViewConfiguration" + initWithName:[NSString stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebsiteDataStoreHostApi.createFromWebViewConfiguration", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebsiteDataStoreHostApiGetCodec()]; if (api) { @@ -939,8 +961,11 @@ void SetUpFWFWKWebsiteDataStoreHostApi(id binaryMessenge } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebsiteDataStoreHostApi." - @"createDefaultDataStore" + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebsiteDataStoreHostApi.createDefaultDataStore", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebsiteDataStoreHostApiGetCodec()]; if (api) { @@ -961,8 +986,10 @@ void SetUpFWFWKWebsiteDataStoreHostApi(id binaryMessenge } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebsiteDataStoreHostApi." - @"removeDataOfTypes" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebsiteDataStoreHostApi.removeDataOfTypes", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebsiteDataStoreHostApiGetCodec()]; if (api) { @@ -999,10 +1026,21 @@ void SetUpFWFWKWebsiteDataStoreHostApi(id binaryMessenge void SetUpFWFUIViewHostApi(id binaryMessenger, NSObject *api) { + SetUpFWFUIViewHostApiWithSuffix(binaryMessenger, api, @""); +} + +void SetUpFWFUIViewHostApiWithSuffix(id binaryMessenger, + NSObject *api, + NSString *messageChannelSuffix) { + messageChannelSuffix = messageChannelSuffix.length > 0 + ? [NSString stringWithFormat:@".%@", messageChannelSuffix] + : @""; { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.UIViewHostApi.setBackgroundColor" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"UIViewHostApi.setBackgroundColor", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFUIViewHostApiGetCodec()]; if (api) { @@ -1025,7 +1063,10 @@ void SetUpFWFUIViewHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.UIViewHostApi.setOpaque" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"UIViewHostApi.setOpaque", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFUIViewHostApiGetCodec()]; if (api) { @@ -1054,10 +1095,21 @@ void SetUpFWFUIViewHostApi(id binaryMessenger, void SetUpFWFUIScrollViewHostApi(id binaryMessenger, NSObject *api) { + SetUpFWFUIScrollViewHostApiWithSuffix(binaryMessenger, api, @""); +} + +void SetUpFWFUIScrollViewHostApiWithSuffix(id binaryMessenger, + NSObject *api, + NSString *messageChannelSuffix) { + messageChannelSuffix = messageChannelSuffix.length > 0 + ? [NSString stringWithFormat:@".%@", messageChannelSuffix] + : @""; { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.createFromWebView" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"UIScrollViewHostApi.createFromWebView", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFUIScrollViewHostApiGetCodec()]; if (api) { @@ -1082,8 +1134,10 @@ void SetUpFWFUIScrollViewHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.getContentOffset" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"UIScrollViewHostApi.getContentOffset", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFUIScrollViewHostApiGetCodec()]; if (api) { @@ -1105,7 +1159,10 @@ void SetUpFWFUIScrollViewHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.scrollBy" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"UIScrollViewHostApi.scrollBy", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFUIScrollViewHostApiGetCodec()]; if (api) { @@ -1128,8 +1185,10 @@ void SetUpFWFUIScrollViewHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.setContentOffset" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"UIScrollViewHostApi.setContentOffset", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFUIScrollViewHostApiGetCodec()]; if (api) { @@ -1156,8 +1215,10 @@ void SetUpFWFUIScrollViewHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.setDelegate" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"UIScrollViewHostApi.setDelegate", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFUIScrollViewHostApiGetCodec()]; if (api) { @@ -1232,10 +1293,21 @@ - (FlutterStandardReader *)readerWithData:(NSData *)data { void SetUpFWFWKWebViewConfigurationHostApi(id binaryMessenger, NSObject *api) { + SetUpFWFWKWebViewConfigurationHostApiWithSuffix(binaryMessenger, api, @""); +} + +void SetUpFWFWKWebViewConfigurationHostApiWithSuffix( + id binaryMessenger, NSObject *api, + NSString *messageChannelSuffix) { + messageChannelSuffix = messageChannelSuffix.length > 0 + ? [NSString stringWithFormat:@".%@", messageChannelSuffix] + : @""; { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.create" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewConfigurationHostApi.create", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewConfigurationHostApiGetCodec()]; if (api) { @@ -1256,8 +1328,11 @@ void SetUpFWFWKWebViewConfigurationHostApi(id binaryMess } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview." - @"WKWebViewConfigurationHostApi.createFromWebView" + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewConfigurationHostApi.createFromWebView", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewConfigurationHostApiGetCodec()]; if (api) { @@ -1282,8 +1357,11 @@ void SetUpFWFWKWebViewConfigurationHostApi(id binaryMess } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview." - @"WKWebViewConfigurationHostApi.setAllowsInlineMediaPlayback" + initWithName:[NSString stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewConfigurationHostApi.setAllowsInlineMediaPlayback", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewConfigurationHostApiGetCodec()]; if (api) { @@ -1309,8 +1387,11 @@ void SetUpFWFWKWebViewConfigurationHostApi(id binaryMess } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview." - @"WKWebViewConfigurationHostApi.setLimitsNavigationsToAppBoundDomains" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewConfigurationHostApi." + @"setLimitsNavigationsToAppBoundDomains", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewConfigurationHostApiGetCodec()]; if (api) { @@ -1337,8 +1418,11 @@ void SetUpFWFWKWebViewConfigurationHostApi(id binaryMess } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview." - @"WKWebViewConfigurationHostApi.setMediaTypesRequiringUserActionForPlayback" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewConfigurationHostApi." + @"setMediaTypesRequiringUserActionForPlayback", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewConfigurationHostApiGetCodec()]; if (api) { @@ -1372,41 +1456,50 @@ void SetUpFWFWKWebViewConfigurationHostApi(id binaryMess @interface FWFWKWebViewConfigurationFlutterApi () @property(nonatomic, strong) NSObject *binaryMessenger; +@property(nonatomic, strong) NSString *messageChannelSuffix; @end @implementation FWFWKWebViewConfigurationFlutterApi - (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger { - self = [super init]; + return [self initWithBinaryMessenger:binaryMessenger messageChannelSuffix:@""]; +} +- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger + messageChannelSuffix:(nullable NSString *)messageChannelSuffix { + self = [self init]; if (self) { _binaryMessenger = binaryMessenger; + _messageChannelSuffix = [messageChannelSuffix length] == 0 + ? @"" + : [NSString stringWithFormat:@".%@", messageChannelSuffix]; } return self; } - (void)createWithIdentifier:(NSInteger)arg_identifier completion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationFlutterApi.create", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel - messageChannelWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationFlutterApi.create" + messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FWFWKWebViewConfigurationFlutterApiGetCodec()]; - [channel - sendMessage:@[ @(arg_identifier) ] - reply:^(NSArray *reply) { - if (reply != nil) { - if (reply.count > 1) { - completion([FlutterError errorWithCode:reply[0] - message:reply[1] - details:reply[2]]); - } else { - completion(nil); - } - } else { - completion([FlutterError errorWithCode:@"channel-error" - message:@"Unable to establish connection on channel." - details:@""]); - } - }]; + [channel sendMessage:@[ @(arg_identifier) ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; } @end @@ -1465,10 +1558,23 @@ - (FlutterStandardReader *)readerWithData:(NSData *)data { void SetUpFWFWKUserContentControllerHostApi(id binaryMessenger, NSObject *api) { + SetUpFWFWKUserContentControllerHostApiWithSuffix(binaryMessenger, api, @""); +} + +void SetUpFWFWKUserContentControllerHostApiWithSuffix( + id binaryMessenger, NSObject *api, + NSString *messageChannelSuffix) { + messageChannelSuffix = messageChannelSuffix.length > 0 + ? [NSString stringWithFormat:@".%@", messageChannelSuffix] + : @""; { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview." - @"WKUserContentControllerHostApi.createFromWebViewConfiguration" + initWithName:[NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKUserContentControllerHostApi.createFromWebViewConfiguration", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKUserContentControllerHostApiGetCodec()]; if (api) { @@ -1494,8 +1600,11 @@ void SetUpFWFWKUserContentControllerHostApi(id binaryMes } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview." - @"WKUserContentControllerHostApi.addScriptMessageHandler" + initWithName: + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKUserContentControllerHostApi.addScriptMessageHandler", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKUserContentControllerHostApiGetCodec()]; if (api) { @@ -1524,8 +1633,11 @@ void SetUpFWFWKUserContentControllerHostApi(id binaryMes } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview." - @"WKUserContentControllerHostApi.removeScriptMessageHandler" + initWithName:[NSString stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKUserContentControllerHostApi.removeScriptMessageHandler", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKUserContentControllerHostApiGetCodec()]; if (api) { @@ -1550,8 +1662,12 @@ void SetUpFWFWKUserContentControllerHostApi(id binaryMes } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview." - @"WKUserContentControllerHostApi.removeAllScriptMessageHandlers" + initWithName:[NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKUserContentControllerHostApi.removeAllScriptMessageHandlers", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKUserContentControllerHostApiGetCodec()]; if (api) { @@ -1573,8 +1689,10 @@ void SetUpFWFWKUserContentControllerHostApi(id binaryMes } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview." - @"WKUserContentControllerHostApi.addUserScript" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKUserContentControllerHostApi.addUserScript", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKUserContentControllerHostApiGetCodec()]; if (api) { @@ -1599,8 +1717,11 @@ void SetUpFWFWKUserContentControllerHostApi(id binaryMes } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview." - @"WKUserContentControllerHostApi.removeAllUserScripts" + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKUserContentControllerHostApi.removeAllUserScripts", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKUserContentControllerHostApiGetCodec()]; if (api) { @@ -1629,10 +1750,22 @@ void SetUpFWFWKUserContentControllerHostApi(id binaryMes void SetUpFWFWKPreferencesHostApi(id binaryMessenger, NSObject *api) { + SetUpFWFWKPreferencesHostApiWithSuffix(binaryMessenger, api, @""); +} + +void SetUpFWFWKPreferencesHostApiWithSuffix(id binaryMessenger, + NSObject *api, + NSString *messageChannelSuffix) { + messageChannelSuffix = messageChannelSuffix.length > 0 + ? [NSString stringWithFormat:@".%@", messageChannelSuffix] + : @""; { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.WKPreferencesHostApi." - @"createFromWebViewConfiguration" + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKPreferencesHostApi.createFromWebViewConfiguration", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKPreferencesHostApiGetCodec()]; if (api) { @@ -1658,8 +1791,10 @@ void SetUpFWFWKPreferencesHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.WKPreferencesHostApi." - @"setJavaScriptEnabled" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKPreferencesHostApi.setJavaScriptEnabled", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKPreferencesHostApiGetCodec()]; if (api) { @@ -1691,10 +1826,21 @@ void SetUpFWFWKPreferencesHostApi(id binaryMessenger, void SetUpFWFWKScriptMessageHandlerHostApi(id binaryMessenger, NSObject *api) { + SetUpFWFWKScriptMessageHandlerHostApiWithSuffix(binaryMessenger, api, @""); +} + +void SetUpFWFWKScriptMessageHandlerHostApiWithSuffix( + id binaryMessenger, NSObject *api, + NSString *messageChannelSuffix) { + messageChannelSuffix = messageChannelSuffix.length > 0 + ? [NSString stringWithFormat:@".%@", messageChannelSuffix] + : @""; { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.WKScriptMessageHandlerHostApi.create" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKScriptMessageHandlerHostApi.create", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKScriptMessageHandlerHostApiGetCodec()]; if (api) { @@ -1764,14 +1910,22 @@ - (FlutterStandardReader *)readerWithData:(NSData *)data { @interface FWFWKScriptMessageHandlerFlutterApi () @property(nonatomic, strong) NSObject *binaryMessenger; +@property(nonatomic, strong) NSString *messageChannelSuffix; @end @implementation FWFWKScriptMessageHandlerFlutterApi - (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger { - self = [super init]; + return [self initWithBinaryMessenger:binaryMessenger messageChannelSuffix:@""]; +} +- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger + messageChannelSuffix:(nullable NSString *)messageChannelSuffix { + self = [self init]; if (self) { _binaryMessenger = binaryMessenger; + _messageChannelSuffix = [messageChannelSuffix length] == 0 + ? @"" + : [NSString stringWithFormat:@".%@", messageChannelSuffix]; } return self; } @@ -1780,30 +1934,31 @@ - (instancetype)initWithBinaryMessenger:(NSObject *)bina userContentControllerIdentifier:(NSInteger)arg_userContentControllerIdentifier message:(FWFWKScriptMessageData *)arg_message completion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKScriptMessageHandlerFlutterApi.didReceiveScriptMessage", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel - messageChannelWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview." - @"WKScriptMessageHandlerFlutterApi.didReceiveScriptMessage" + messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FWFWKScriptMessageHandlerFlutterApiGetCodec()]; - [channel - sendMessage:@[ - @(arg_identifier), @(arg_userContentControllerIdentifier), arg_message ?: [NSNull null] - ] - reply:^(NSArray *reply) { - if (reply != nil) { - if (reply.count > 1) { - completion([FlutterError errorWithCode:reply[0] - message:reply[1] - details:reply[2]]); - } else { - completion(nil); - } - } else { - completion([FlutterError errorWithCode:@"channel-error" - message:@"Unable to establish connection on channel." - details:@""]); - } - }]; + [channel sendMessage:@[ + @(arg_identifier), @(arg_userContentControllerIdentifier), arg_message ?: [NSNull null] + ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; } @end @@ -1815,10 +1970,21 @@ - (instancetype)initWithBinaryMessenger:(NSObject *)bina void SetUpFWFWKNavigationDelegateHostApi(id binaryMessenger, NSObject *api) { + SetUpFWFWKNavigationDelegateHostApiWithSuffix(binaryMessenger, api, @""); +} + +void SetUpFWFWKNavigationDelegateHostApiWithSuffix(id binaryMessenger, + NSObject *api, + NSString *messageChannelSuffix) { + messageChannelSuffix = messageChannelSuffix.length > 0 + ? [NSString stringWithFormat:@".%@", messageChannelSuffix] + : @""; { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateHostApi.create" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKNavigationDelegateHostApi.create", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKNavigationDelegateHostApiGetCodec()]; if (api) { @@ -1923,14 +2089,22 @@ - (FlutterStandardReader *)readerWithData:(NSData *)data { @interface FWFWKNavigationDelegateFlutterApi () @property(nonatomic, strong) NSObject *binaryMessenger; +@property(nonatomic, strong) NSString *messageChannelSuffix; @end @implementation FWFWKNavigationDelegateFlutterApi - (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger { - self = [super init]; + return [self initWithBinaryMessenger:binaryMessenger messageChannelSuffix:@""]; +} +- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger + messageChannelSuffix:(nullable NSString *)messageChannelSuffix { + self = [self init]; if (self) { _binaryMessenger = binaryMessenger; + _messageChannelSuffix = [messageChannelSuffix length] == 0 + ? @"" + : [NSString stringWithFormat:@".%@", messageChannelSuffix]; } return self; } @@ -1938,56 +2112,58 @@ - (void)didFinishNavigationForDelegateWithIdentifier:(NSInteger)arg_identifier webViewIdentifier:(NSInteger)arg_webViewIdentifier URL:(nullable NSString *)arg_url completion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKNavigationDelegateFlutterApi.didFinishNavigation", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel - messageChannelWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview." - @"WKNavigationDelegateFlutterApi.didFinishNavigation" + messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FWFWKNavigationDelegateFlutterApiGetCodec()]; - [channel - sendMessage:@[ @(arg_identifier), @(arg_webViewIdentifier), arg_url ?: [NSNull null] ] - reply:^(NSArray *reply) { - if (reply != nil) { - if (reply.count > 1) { - completion([FlutterError errorWithCode:reply[0] - message:reply[1] - details:reply[2]]); - } else { - completion(nil); - } - } else { - completion([FlutterError errorWithCode:@"channel-error" - message:@"Unable to establish connection on channel." - details:@""]); - } - }]; + [channel sendMessage:@[ @(arg_identifier), @(arg_webViewIdentifier), arg_url ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; } - (void)didStartProvisionalNavigationForDelegateWithIdentifier:(NSInteger)arg_identifier webViewIdentifier:(NSInteger)arg_webViewIdentifier URL:(nullable NSString *)arg_url completion:(void (^)(FlutterError *_Nullable)) completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKNavigationDelegateFlutterApi.didStartProvisionalNavigation", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel - messageChannelWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview." - @"WKNavigationDelegateFlutterApi.didStartProvisionalNavigation" + messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FWFWKNavigationDelegateFlutterApiGetCodec()]; - [channel - sendMessage:@[ @(arg_identifier), @(arg_webViewIdentifier), arg_url ?: [NSNull null] ] - reply:^(NSArray *reply) { - if (reply != nil) { - if (reply.count > 1) { - completion([FlutterError errorWithCode:reply[0] - message:reply[1] - details:reply[2]]); - } else { - completion(nil); - } - } else { - completion([FlutterError errorWithCode:@"channel-error" - message:@"Unable to establish connection on channel." - details:@""]); - } - }]; + [channel sendMessage:@[ @(arg_identifier), @(arg_webViewIdentifier), arg_url ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; } - (void)decidePolicyForNavigationActionForDelegateWithIdentifier:(NSInteger)arg_identifier webViewIdentifier:(NSInteger)arg_webViewIdentifier @@ -1998,9 +2174,13 @@ - (void)decidePolicyForNavigationActionForDelegateWithIdentifier:(NSInteger)arg_ FWFWKNavigationActionPolicyEnumData *_Nullable, FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKNavigationDelegateFlutterApi.decidePolicyForNavigationAction", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel - messageChannelWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview." - @"WKNavigationDelegateFlutterApi.decidePolicyForNavigationAction" + messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FWFWKNavigationDelegateFlutterApiGetCodec()]; [channel sendMessage:@[ @@ -2018,10 +2198,7 @@ - (void)decidePolicyForNavigationActionForDelegateWithIdentifier:(NSInteger)arg_ completion(output, nil); } } else { - completion(nil, [FlutterError - errorWithCode:@"channel-error" - message:@"Unable to establish connection on channel." - details:@""]); + completion(nil, createConnectionError(channelName)); } }]; } @@ -2035,9 +2212,13 @@ - (void)decidePolicyForNavigationResponseForDelegateWithIdentifier:(NSInteger)ar *_Nullable, FlutterError *_Nullable)) completion { + NSString *channelName = [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKNavigationDelegateFlutterApi.decidePolicyForNavigationResponse", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel - messageChannelWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview." - @"WKNavigationDelegateFlutterApi.decidePolicyForNavigationResponse" + messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FWFWKNavigationDelegateFlutterApiGetCodec()]; [channel sendMessage:@[ @@ -2058,10 +2239,7 @@ - (void)decidePolicyForNavigationResponseForDelegateWithIdentifier:(NSInteger)ar completion(output, nil); } } else { - completion(nil, [FlutterError - errorWithCode:@"channel-error" - message:@"Unable to establish connection on channel." - details:@""]); + completion(nil, createConnectionError(channelName)); } }]; } @@ -2069,56 +2247,58 @@ - (void)didFailNavigationForDelegateWithIdentifier:(NSInteger)arg_identifier webViewIdentifier:(NSInteger)arg_webViewIdentifier error:(FWFNSErrorData *)arg_error completion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKNavigationDelegateFlutterApi.didFailNavigation", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel - messageChannelWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview." - @"WKNavigationDelegateFlutterApi.didFailNavigation" + messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FWFWKNavigationDelegateFlutterApiGetCodec()]; - [channel - sendMessage:@[ @(arg_identifier), @(arg_webViewIdentifier), arg_error ?: [NSNull null] ] - reply:^(NSArray *reply) { - if (reply != nil) { - if (reply.count > 1) { - completion([FlutterError errorWithCode:reply[0] - message:reply[1] - details:reply[2]]); - } else { - completion(nil); - } - } else { - completion([FlutterError errorWithCode:@"channel-error" - message:@"Unable to establish connection on channel." - details:@""]); - } - }]; + [channel sendMessage:@[ @(arg_identifier), @(arg_webViewIdentifier), arg_error ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; } - (void)didFailProvisionalNavigationForDelegateWithIdentifier:(NSInteger)arg_identifier webViewIdentifier:(NSInteger)arg_webViewIdentifier error:(FWFNSErrorData *)arg_error completion:(void (^)(FlutterError *_Nullable)) completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKNavigationDelegateFlutterApi.didFailProvisionalNavigation", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel - messageChannelWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview." - @"WKNavigationDelegateFlutterApi.didFailProvisionalNavigation" + messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FWFWKNavigationDelegateFlutterApiGetCodec()]; - [channel - sendMessage:@[ @(arg_identifier), @(arg_webViewIdentifier), arg_error ?: [NSNull null] ] - reply:^(NSArray *reply) { - if (reply != nil) { - if (reply.count > 1) { - completion([FlutterError errorWithCode:reply[0] - message:reply[1] - details:reply[2]]); - } else { - completion(nil); - } - } else { - completion([FlutterError errorWithCode:@"channel-error" - message:@"Unable to establish connection on channel." - details:@""]); - } - }]; + [channel sendMessage:@[ @(arg_identifier), @(arg_webViewIdentifier), arg_error ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; } - (void)webViewWebContentProcessDidTerminateForDelegateWithIdentifier:(NSInteger)arg_identifier webViewIdentifier: @@ -2126,28 +2306,29 @@ - (void)webViewWebContentProcessDidTerminateForDelegateWithIdentifier:(NSInteger completion: (void (^)(FlutterError *_Nullable)) completion { + NSString *channelName = [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKNavigationDelegateFlutterApi.webViewWebContentProcessDidTerminate", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel - messageChannelWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview." - @"WKNavigationDelegateFlutterApi.webViewWebContentProcessDidTerminate" + messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FWFWKNavigationDelegateFlutterApiGetCodec()]; - [channel - sendMessage:@[ @(arg_identifier), @(arg_webViewIdentifier) ] - reply:^(NSArray *reply) { - if (reply != nil) { - if (reply.count > 1) { - completion([FlutterError errorWithCode:reply[0] - message:reply[1] - details:reply[2]]); - } else { - completion(nil); - } - } else { - completion([FlutterError errorWithCode:@"channel-error" - message:@"Unable to establish connection on channel." - details:@""]); - } - }]; + [channel sendMessage:@[ @(arg_identifier), @(arg_webViewIdentifier) ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; } - (void) didReceiveAuthenticationChallengeForDelegateWithIdentifier:(NSInteger)arg_identifier @@ -2158,9 +2339,13 @@ - (void)webViewWebContentProcessDidTerminateForDelegateWithIdentifier:(NSInteger *_Nullable, FlutterError *_Nullable)) completion { + NSString *channelName = [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKNavigationDelegateFlutterApi.didReceiveAuthenticationChallenge", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel - messageChannelWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview." - @"WKNavigationDelegateFlutterApi.didReceiveAuthenticationChallenge" + messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FWFWKNavigationDelegateFlutterApiGetCodec()]; [channel sendMessage:@[ @(arg_identifier), @(arg_webViewIdentifier), @(arg_challengeIdentifier) ] @@ -2176,10 +2361,7 @@ - (void)webViewWebContentProcessDidTerminateForDelegateWithIdentifier:(NSInteger completion(output, nil); } } else { - completion(nil, [FlutterError - errorWithCode:@"channel-error" - message:@"Unable to establish connection on channel." - details:@""]); + completion(nil, createConnectionError(channelName)); } }]; } @@ -2235,9 +2417,21 @@ - (FlutterStandardReader *)readerWithData:(NSData *)data { void SetUpFWFNSObjectHostApi(id binaryMessenger, NSObject *api) { + SetUpFWFNSObjectHostApiWithSuffix(binaryMessenger, api, @""); +} + +void SetUpFWFNSObjectHostApiWithSuffix(id binaryMessenger, + NSObject *api, + NSString *messageChannelSuffix) { + messageChannelSuffix = messageChannelSuffix.length > 0 + ? [NSString stringWithFormat:@".%@", messageChannelSuffix] + : @""; { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectHostApi.dispose" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"NSObjectHostApi.dispose", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFNSObjectHostApiGetCodec()]; if (api) { @@ -2258,7 +2452,10 @@ void SetUpFWFNSObjectHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectHostApi.addObserver" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"NSObjectHostApi.addObserver", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFNSObjectHostApiGetCodec()]; if (api) { @@ -2290,8 +2487,10 @@ void SetUpFWFNSObjectHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectHostApi.removeObserver" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"NSObjectHostApi.removeObserver", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFNSObjectHostApiGetCodec()]; if (api) { @@ -2373,14 +2572,22 @@ - (FlutterStandardReader *)readerWithData:(NSData *)data { @interface FWFNSObjectFlutterApi () @property(nonatomic, strong) NSObject *binaryMessenger; +@property(nonatomic, strong) NSString *messageChannelSuffix; @end @implementation FWFNSObjectFlutterApi - (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger { - self = [super init]; + return [self initWithBinaryMessenger:binaryMessenger messageChannelSuffix:@""]; +} +- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger + messageChannelSuffix:(nullable NSString *)messageChannelSuffix { + self = [self init]; if (self) { _binaryMessenger = binaryMessenger; + _messageChannelSuffix = [messageChannelSuffix length] == 0 + ? @"" + : [NSString stringWithFormat:@".%@", messageChannelSuffix]; } return self; } @@ -2391,56 +2598,56 @@ - (void)observeValueForObjectWithIdentifier:(NSInteger)arg_identifier (NSArray *)arg_changeKeys changeValues:(NSArray *)arg_changeValues completion:(void (^)(FlutterError *_Nullable))completion { - FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel - messageChannelWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectFlutterApi.observeValue" - binaryMessenger:self.binaryMessenger - codec:FWFNSObjectFlutterApiGetCodec()]; - [channel - sendMessage:@[ - @(arg_identifier), arg_keyPath ?: [NSNull null], @(arg_objectIdentifier), - arg_changeKeys ?: [NSNull null], arg_changeValues ?: [NSNull null] - ] - reply:^(NSArray *reply) { - if (reply != nil) { - if (reply.count > 1) { - completion([FlutterError errorWithCode:reply[0] - message:reply[1] - details:reply[2]]); - } else { - completion(nil); - } - } else { - completion([FlutterError errorWithCode:@"channel-error" - message:@"Unable to establish connection on channel." - details:@""]); - } - }]; + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", @"dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectFlutterApi.observeValue", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FWFNSObjectFlutterApiGetCodec()]; + [channel sendMessage:@[ + @(arg_identifier), arg_keyPath ?: [NSNull null], @(arg_objectIdentifier), + arg_changeKeys ?: [NSNull null], arg_changeValues ?: [NSNull null] + ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; } - (void)disposeObjectWithIdentifier:(NSInteger)arg_identifier completion:(void (^)(FlutterError *_Nullable))completion { - FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel - messageChannelWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectFlutterApi.dispose" - binaryMessenger:self.binaryMessenger - codec:FWFNSObjectFlutterApiGetCodec()]; - [channel - sendMessage:@[ @(arg_identifier) ] - reply:^(NSArray *reply) { - if (reply != nil) { - if (reply.count > 1) { - completion([FlutterError errorWithCode:reply[0] - message:reply[1] - details:reply[2]]); - } else { - completion(nil); - } - } else { - completion([FlutterError errorWithCode:@"channel-error" - message:@"Unable to establish connection on channel." - details:@""]); - } - }]; + NSString *channelName = [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectFlutterApi.dispose", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FWFNSObjectFlutterApiGetCodec()]; + [channel sendMessage:@[ @(arg_identifier) ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; } @end @@ -2594,9 +2801,21 @@ - (FlutterStandardReader *)readerWithData:(NSData *)data { void SetUpFWFWKWebViewHostApi(id binaryMessenger, NSObject *api) { + SetUpFWFWKWebViewHostApiWithSuffix(binaryMessenger, api, @""); +} + +void SetUpFWFWKWebViewHostApiWithSuffix(id binaryMessenger, + NSObject *api, + NSString *messageChannelSuffix) { + messageChannelSuffix = messageChannelSuffix.length > 0 + ? [NSString stringWithFormat:@".%@", messageChannelSuffix] + : @""; { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.create" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewHostApi.create", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewHostApiGetCodec()]; if (api) { @@ -2621,8 +2840,10 @@ void SetUpFWFWKWebViewHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setUIDelegate" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewHostApi.setUIDelegate", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewHostApiGetCodec()]; if (api) { @@ -2647,8 +2868,10 @@ void SetUpFWFWKWebViewHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi." - @"setNavigationDelegate" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewHostApi.setNavigationDelegate", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewHostApiGetCodec()]; if (api) { @@ -2674,7 +2897,10 @@ void SetUpFWFWKWebViewHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.getUrl" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewHostApi.getUrl", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewHostApiGetCodec()]; if (api) { @@ -2695,8 +2921,10 @@ void SetUpFWFWKWebViewHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.getEstimatedProgress" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewHostApi.getEstimatedProgress", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewHostApiGetCodec()]; if (api) { @@ -2719,7 +2947,10 @@ void SetUpFWFWKWebViewHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.loadRequest" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewHostApi.loadRequest", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewHostApiGetCodec()]; if (api) { @@ -2742,8 +2973,10 @@ void SetUpFWFWKWebViewHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.loadHtmlString" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewHostApi.loadHtmlString", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewHostApiGetCodec()]; if (api) { @@ -2770,7 +3003,10 @@ void SetUpFWFWKWebViewHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.loadFileUrl" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewHostApi.loadFileUrl", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewHostApiGetCodec()]; if (api) { @@ -2797,8 +3033,10 @@ void SetUpFWFWKWebViewHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.loadFlutterAsset" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewHostApi.loadFlutterAsset", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewHostApiGetCodec()]; if (api) { @@ -2821,7 +3059,10 @@ void SetUpFWFWKWebViewHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.canGoBack" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewHostApi.canGoBack", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewHostApiGetCodec()]; if (api) { @@ -2842,8 +3083,10 @@ void SetUpFWFWKWebViewHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.canGoForward" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewHostApi.canGoForward", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewHostApiGetCodec()]; if (api) { @@ -2864,7 +3107,10 @@ void SetUpFWFWKWebViewHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.goBack" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewHostApi.goBack", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewHostApiGetCodec()]; if (api) { @@ -2885,7 +3131,10 @@ void SetUpFWFWKWebViewHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.goForward" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewHostApi.goForward", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewHostApiGetCodec()]; if (api) { @@ -2906,7 +3155,10 @@ void SetUpFWFWKWebViewHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.reload" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewHostApi.reload", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewHostApiGetCodec()]; if (api) { @@ -2927,7 +3179,10 @@ void SetUpFWFWKWebViewHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.getTitle" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewHostApi.getTitle", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewHostApiGetCodec()]; if (api) { @@ -2948,8 +3203,11 @@ void SetUpFWFWKWebViewHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi." - @"setAllowsBackForwardNavigationGestures" + initWithName:[NSString stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewHostApi.setAllowsBackForwardNavigationGestures", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewHostApiGetCodec()]; if (api) { @@ -2974,8 +3232,10 @@ void SetUpFWFWKWebViewHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setCustomUserAgent" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewHostApi.setCustomUserAgent", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewHostApiGetCodec()]; if (api) { @@ -3000,8 +3260,10 @@ void SetUpFWFWKWebViewHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.evaluateJavaScript" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewHostApi.evaluateJavaScript", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewHostApiGetCodec()]; if (api) { @@ -3028,8 +3290,10 @@ void SetUpFWFWKWebViewHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setInspectable" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewHostApi.setInspectable", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewHostApiGetCodec()]; if (api) { @@ -3054,8 +3318,10 @@ void SetUpFWFWKWebViewHostApi(id binaryMessenger, } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.getCustomUserAgent" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKWebViewHostApi.getCustomUserAgent", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKWebViewHostApiGetCodec()]; if (api) { @@ -3084,9 +3350,21 @@ void SetUpFWFWKWebViewHostApi(id binaryMessenger, void SetUpFWFWKUIDelegateHostApi(id binaryMessenger, NSObject *api) { + SetUpFWFWKUIDelegateHostApiWithSuffix(binaryMessenger, api, @""); +} + +void SetUpFWFWKUIDelegateHostApiWithSuffix(id binaryMessenger, + NSObject *api, + NSString *messageChannelSuffix) { + messageChannelSuffix = messageChannelSuffix.length > 0 + ? [NSString stringWithFormat:@".%@", messageChannelSuffix] + : @""; { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateHostApi.create" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKUIDelegateHostApi.create", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKUIDelegateHostApiGetCodec()]; if (api) { @@ -3181,14 +3459,22 @@ - (FlutterStandardReader *)readerWithData:(NSData *)data { @interface FWFWKUIDelegateFlutterApi () @property(nonatomic, strong) NSObject *binaryMessenger; +@property(nonatomic, strong) NSString *messageChannelSuffix; @end @implementation FWFWKUIDelegateFlutterApi - (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger { - self = [super init]; + return [self initWithBinaryMessenger:binaryMessenger messageChannelSuffix:@""]; +} +- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger + messageChannelSuffix:(nullable NSString *)messageChannelSuffix { + self = [self init]; if (self) { _binaryMessenger = binaryMessenger; + _messageChannelSuffix = [messageChannelSuffix length] == 0 + ? @"" + : [NSString stringWithFormat:@".%@", messageChannelSuffix]; } return self; } @@ -3197,31 +3483,32 @@ - (void)onCreateWebViewForDelegateWithIdentifier:(NSInteger)arg_identifier configurationIdentifier:(NSInteger)arg_configurationIdentifier navigationAction:(FWFWKNavigationActionData *)arg_navigationAction completion:(void (^)(FlutterError *_Nullable))completion { - FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel - messageChannelWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateFlutterApi.onCreateWebView" - binaryMessenger:self.binaryMessenger - codec:FWFWKUIDelegateFlutterApiGetCodec()]; - [channel - sendMessage:@[ - @(arg_identifier), @(arg_webViewIdentifier), @(arg_configurationIdentifier), - arg_navigationAction ?: [NSNull null] - ] - reply:^(NSArray *reply) { - if (reply != nil) { - if (reply.count > 1) { - completion([FlutterError errorWithCode:reply[0] - message:reply[1] - details:reply[2]]); - } else { - completion(nil); - } - } else { - completion([FlutterError errorWithCode:@"channel-error" - message:@"Unable to establish connection on channel." - details:@""]); - } - }]; + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateFlutterApi.onCreateWebView", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FWFWKUIDelegateFlutterApiGetCodec()]; + [channel sendMessage:@[ + @(arg_identifier), @(arg_webViewIdentifier), @(arg_configurationIdentifier), + arg_navigationAction ?: [NSNull null] + ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; } - (void)requestMediaCapturePermissionForDelegateWithIdentifier:(NSInteger)arg_identifier webViewIdentifier:(NSInteger)arg_webViewIdentifier @@ -3232,44 +3519,49 @@ - (void)requestMediaCapturePermissionForDelegateWithIdentifier:(NSInteger)arg_id (void (^)( FWFWKPermissionDecisionData *_Nullable, FlutterError *_Nullable))completion { - FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel - messageChannelWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateFlutterApi." - @"requestMediaCapturePermission" - binaryMessenger:self.binaryMessenger - codec:FWFWKUIDelegateFlutterApiGetCodec()]; - [channel - sendMessage:@[ - @(arg_identifier), @(arg_webViewIdentifier), arg_origin ?: [NSNull null], - arg_frame ?: [NSNull null], arg_type ?: [NSNull null] - ] - reply:^(NSArray *reply) { - if (reply != nil) { - if (reply.count > 1) { - completion(nil, [FlutterError errorWithCode:reply[0] - message:reply[1] - details:reply[2]]); - } else { - FWFWKPermissionDecisionData *output = reply[0] == [NSNull null] ? nil : reply[0]; - completion(output, nil); - } - } else { - completion(nil, - [FlutterError errorWithCode:@"channel-error" - message:@"Unable to establish connection on channel." - details:@""]); - } - }]; + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKUIDelegateFlutterApi.requestMediaCapturePermission", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FWFWKUIDelegateFlutterApiGetCodec()]; + [channel sendMessage:@[ + @(arg_identifier), @(arg_webViewIdentifier), arg_origin ?: [NSNull null], + arg_frame ?: [NSNull null], arg_type ?: [NSNull null] + ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + FWFWKPermissionDecisionData *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; } - (void)runJavaScriptAlertPanelForDelegateWithIdentifier:(NSInteger)arg_identifier message:(NSString *)arg_message frame:(FWFWKFrameInfoData *)arg_frame completion: (void (^)(FlutterError *_Nullable))completion { - FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel - messageChannelWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateFlutterApi." - @"runJavaScriptAlertPanel" - binaryMessenger:self.binaryMessenger - codec:FWFWKUIDelegateFlutterApiGetCodec()]; + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKUIDelegateFlutterApi.runJavaScriptAlertPanel", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FWFWKUIDelegateFlutterApiGetCodec()]; [channel sendMessage:@[ @(arg_identifier), arg_message ?: [NSNull null], arg_frame ?: [NSNull null] ] reply:^(NSArray *reply) { @@ -3282,9 +3574,7 @@ - (void)runJavaScriptAlertPanelForDelegateWithIdentifier:(NSInteger)arg_identifi completion(nil); } } else { - completion([FlutterError errorWithCode:@"channel-error" - message:@"Unable to establish connection on channel." - details:@""]); + completion(createConnectionError(channelName)); } }]; } @@ -3294,11 +3584,15 @@ - (void)runJavaScriptConfirmPanelForDelegateWithIdentifier:(NSInteger)arg_identi completion: (void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { - FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel - messageChannelWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateFlutterApi." - @"runJavaScriptConfirmPanel" - binaryMessenger:self.binaryMessenger - codec:FWFWKUIDelegateFlutterApiGetCodec()]; + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKUIDelegateFlutterApi.runJavaScriptConfirmPanel", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FWFWKUIDelegateFlutterApiGetCodec()]; [channel sendMessage:@[ @(arg_identifier), arg_message ?: [NSNull null], arg_frame ?: [NSNull null] ] reply:^(NSArray *reply) { @@ -3312,10 +3606,7 @@ - (void)runJavaScriptConfirmPanelForDelegateWithIdentifier:(NSInteger)arg_identi completion(output, nil); } } else { - completion(nil, - [FlutterError errorWithCode:@"channel-error" - message:@"Unable to establish connection on channel." - details:@""]); + completion(nil, createConnectionError(channelName)); } }]; } @@ -3326,11 +3617,15 @@ - (void)runJavaScriptTextInputPanelForDelegateWithIdentifier:(NSInteger)arg_iden completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable)) completion { - FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel - messageChannelWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateFlutterApi." - @"runJavaScriptTextInputPanel" - binaryMessenger:self.binaryMessenger - codec:FWFWKUIDelegateFlutterApiGetCodec()]; + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKUIDelegateFlutterApi.runJavaScriptTextInputPanel", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FWFWKUIDelegateFlutterApiGetCodec()]; [channel sendMessage:@[ @(arg_identifier), arg_prompt ?: [NSNull null], arg_defaultText ?: [NSNull null], arg_frame ?: [NSNull null] @@ -3346,10 +3641,7 @@ - (void)runJavaScriptTextInputPanelForDelegateWithIdentifier:(NSInteger)arg_iden completion(output, nil); } } else { - completion(nil, [FlutterError - errorWithCode:@"channel-error" - message:@"Unable to establish connection on channel." - details:@""]); + completion(nil, createConnectionError(channelName)); } }]; } @@ -3410,10 +3702,22 @@ - (FlutterStandardReader *)readerWithData:(NSData *)data { void SetUpFWFWKHttpCookieStoreHostApi(id binaryMessenger, NSObject *api) { + SetUpFWFWKHttpCookieStoreHostApiWithSuffix(binaryMessenger, api, @""); +} + +void SetUpFWFWKHttpCookieStoreHostApiWithSuffix(id binaryMessenger, + NSObject *api, + NSString *messageChannelSuffix) { + messageChannelSuffix = messageChannelSuffix.length > 0 + ? [NSString stringWithFormat:@".%@", messageChannelSuffix] + : @""; { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.WKHttpCookieStoreHostApi." - @"createFromWebsiteDataStore" + initWithName:[NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKHttpCookieStoreHostApi.createFromWebsiteDataStore", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKHttpCookieStoreHostApiGetCodec()]; if (api) { @@ -3438,8 +3742,10 @@ void SetUpFWFWKHttpCookieStoreHostApi(id binaryMessenger } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.WKHttpCookieStoreHostApi.setCookie" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"WKHttpCookieStoreHostApi.setCookie", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFWKHttpCookieStoreHostApiGetCodec()]; if (api) { @@ -3471,10 +3777,21 @@ void SetUpFWFWKHttpCookieStoreHostApi(id binaryMessenger void SetUpFWFNSUrlHostApi(id binaryMessenger, NSObject *api) { + SetUpFWFNSUrlHostApiWithSuffix(binaryMessenger, api, @""); +} + +void SetUpFWFNSUrlHostApiWithSuffix(id binaryMessenger, + NSObject *api, + NSString *messageChannelSuffix) { + messageChannelSuffix = messageChannelSuffix.length > 0 + ? [NSString stringWithFormat:@".%@", messageChannelSuffix] + : @""; { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlHostApi.getAbsoluteString" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"NSUrlHostApi.getAbsoluteString", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFNSUrlHostApiGetCodec()]; if (api) { @@ -3502,40 +3819,49 @@ void SetUpFWFNSUrlHostApi(id binaryMessenger, @interface FWFNSUrlFlutterApi () @property(nonatomic, strong) NSObject *binaryMessenger; +@property(nonatomic, strong) NSString *messageChannelSuffix; @end @implementation FWFNSUrlFlutterApi - (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger { - self = [super init]; + return [self initWithBinaryMessenger:binaryMessenger messageChannelSuffix:@""]; +} +- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger + messageChannelSuffix:(nullable NSString *)messageChannelSuffix { + self = [self init]; if (self) { _binaryMessenger = binaryMessenger; + _messageChannelSuffix = [messageChannelSuffix length] == 0 + ? @"" + : [NSString stringWithFormat:@".%@", messageChannelSuffix]; } return self; } - (void)createWithIdentifier:(NSInteger)arg_identifier completion:(void (^)(FlutterError *_Nullable))completion { - FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel - messageChannelWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlFlutterApi.create" - binaryMessenger:self.binaryMessenger - codec:FWFNSUrlFlutterApiGetCodec()]; - [channel - sendMessage:@[ @(arg_identifier) ] - reply:^(NSArray *reply) { - if (reply != nil) { - if (reply.count > 1) { - completion([FlutterError errorWithCode:reply[0] - message:reply[1] - details:reply[2]]); - } else { - completion(nil); - } - } else { - completion([FlutterError errorWithCode:@"channel-error" - message:@"Unable to establish connection on channel." - details:@""]); - } - }]; + NSString *channelName = [NSString + stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlFlutterApi.create", + _messageChannelSuffix]; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FWFNSUrlFlutterApiGetCodec()]; + [channel sendMessage:@[ @(arg_identifier) ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; } @end @@ -3547,10 +3873,21 @@ - (void)createWithIdentifier:(NSInteger)arg_identifier void SetUpFWFUIScrollViewDelegateHostApi(id binaryMessenger, NSObject *api) { + SetUpFWFUIScrollViewDelegateHostApiWithSuffix(binaryMessenger, api, @""); +} + +void SetUpFWFUIScrollViewDelegateHostApiWithSuffix(id binaryMessenger, + NSObject *api, + NSString *messageChannelSuffix) { + messageChannelSuffix = messageChannelSuffix.length > 0 + ? [NSString stringWithFormat:@".%@", messageChannelSuffix] + : @""; { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewDelegateHostApi.create" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"UIScrollViewDelegateHostApi.create", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFUIScrollViewDelegateHostApiGetCodec()]; if (api) { @@ -3578,14 +3915,22 @@ void SetUpFWFUIScrollViewDelegateHostApi(id binaryMessen @interface FWFUIScrollViewDelegateFlutterApi () @property(nonatomic, strong) NSObject *binaryMessenger; +@property(nonatomic, strong) NSString *messageChannelSuffix; @end @implementation FWFUIScrollViewDelegateFlutterApi - (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger { - self = [super init]; + return [self initWithBinaryMessenger:binaryMessenger messageChannelSuffix:@""]; +} +- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger + messageChannelSuffix:(nullable NSString *)messageChannelSuffix { + self = [self init]; if (self) { _binaryMessenger = binaryMessenger; + _messageChannelSuffix = [messageChannelSuffix length] == 0 + ? @"" + : [NSString stringWithFormat:@".%@", messageChannelSuffix]; } return self; } @@ -3594,28 +3939,29 @@ - (void)scrollViewDidScrollWithIdentifier:(NSInteger)arg_identifier x:(double)arg_x y:(double)arg_y completion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"UIScrollViewDelegateFlutterApi.scrollViewDidScroll", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel - messageChannelWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview." - @"UIScrollViewDelegateFlutterApi.scrollViewDidScroll" + messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FWFUIScrollViewDelegateFlutterApiGetCodec()]; - [channel - sendMessage:@[ @(arg_identifier), @(arg_uiScrollViewIdentifier), @(arg_x), @(arg_y) ] - reply:^(NSArray *reply) { - if (reply != nil) { - if (reply.count > 1) { - completion([FlutterError errorWithCode:reply[0] - message:reply[1] - details:reply[2]]); - } else { - completion(nil); - } - } else { - completion([FlutterError errorWithCode:@"channel-error" - message:@"Unable to establish connection on channel." - details:@""]); - } - }]; + [channel sendMessage:@[ @(arg_identifier), @(arg_uiScrollViewIdentifier), @(arg_x), @(arg_y) ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; } @end @@ -3627,11 +3973,22 @@ - (void)scrollViewDidScrollWithIdentifier:(NSInteger)arg_identifier void SetUpFWFNSUrlCredentialHostApi(id binaryMessenger, NSObject *api) { + SetUpFWFNSUrlCredentialHostApiWithSuffix(binaryMessenger, api, @""); +} + +void SetUpFWFNSUrlCredentialHostApiWithSuffix(id binaryMessenger, + NSObject *api, + NSString *messageChannelSuffix) { + messageChannelSuffix = messageChannelSuffix.length > 0 + ? [NSString stringWithFormat:@".%@", messageChannelSuffix] + : @""; /// Create a new native instance and add it to the `InstanceManager`. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlCredentialHostApi.createWithUser" + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"NSUrlCredentialHostApi.createWithUser", + messageChannelSuffix] binaryMessenger:binaryMessenger codec:FWFNSUrlCredentialHostApiGetCodec()]; if (api) { @@ -3668,14 +4025,22 @@ void SetUpFWFNSUrlCredentialHostApi(id binaryMessenger, @interface FWFNSUrlProtectionSpaceFlutterApi () @property(nonatomic, strong) NSObject *binaryMessenger; +@property(nonatomic, strong) NSString *messageChannelSuffix; @end @implementation FWFNSUrlProtectionSpaceFlutterApi - (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger { - self = [super init]; + return [self initWithBinaryMessenger:binaryMessenger messageChannelSuffix:@""]; +} +- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger + messageChannelSuffix:(nullable NSString *)messageChannelSuffix { + self = [self init]; if (self) { _binaryMessenger = binaryMessenger; + _messageChannelSuffix = [messageChannelSuffix length] == 0 + ? @"" + : [NSString stringWithFormat:@".%@", messageChannelSuffix]; } return self; } @@ -3684,31 +4049,32 @@ - (void)createWithIdentifier:(NSInteger)arg_identifier realm:(nullable NSString *)arg_realm authenticationMethod:(nullable NSString *)arg_authenticationMethod completion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = [NSString + stringWithFormat: + @"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlProtectionSpaceFlutterApi.create", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel - messageChannelWithName: - @"dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlProtectionSpaceFlutterApi.create" + messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FWFNSUrlProtectionSpaceFlutterApiGetCodec()]; - [channel - sendMessage:@[ - @(arg_identifier), arg_host ?: [NSNull null], arg_realm ?: [NSNull null], - arg_authenticationMethod ?: [NSNull null] - ] - reply:^(NSArray *reply) { - if (reply != nil) { - if (reply.count > 1) { - completion([FlutterError errorWithCode:reply[0] - message:reply[1] - details:reply[2]]); - } else { - completion(nil); - } - } else { - completion([FlutterError errorWithCode:@"channel-error" - message:@"Unable to establish connection on channel." - details:@""]); - } - }]; + [channel sendMessage:@[ + @(arg_identifier), arg_host ?: [NSNull null], arg_realm ?: [NSNull null], + arg_authenticationMethod ?: [NSNull null] + ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; } @end @@ -3720,41 +4086,50 @@ - (void)createWithIdentifier:(NSInteger)arg_identifier @interface FWFNSUrlAuthenticationChallengeFlutterApi () @property(nonatomic, strong) NSObject *binaryMessenger; +@property(nonatomic, strong) NSString *messageChannelSuffix; @end @implementation FWFNSUrlAuthenticationChallengeFlutterApi - (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger { - self = [super init]; + return [self initWithBinaryMessenger:binaryMessenger messageChannelSuffix:@""]; +} +- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger + messageChannelSuffix:(nullable NSString *)messageChannelSuffix { + self = [self init]; if (self) { _binaryMessenger = binaryMessenger; + _messageChannelSuffix = [messageChannelSuffix length] == 0 + ? @"" + : [NSString stringWithFormat:@".%@", messageChannelSuffix]; } return self; } - (void)createWithIdentifier:(NSInteger)arg_identifier protectionSpaceIdentifier:(NSInteger)arg_protectionSpaceIdentifier completion:(void (^)(FlutterError *_Nullable))completion { + NSString *channelName = + [NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"NSUrlAuthenticationChallengeFlutterApi.create", + _messageChannelSuffix]; FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel - messageChannelWithName:@"dev.flutter.pigeon.webview_flutter_wkwebview." - @"NSUrlAuthenticationChallengeFlutterApi.create" + messageChannelWithName:channelName binaryMessenger:self.binaryMessenger codec:FWFNSUrlAuthenticationChallengeFlutterApiGetCodec()]; - [channel - sendMessage:@[ @(arg_identifier), @(arg_protectionSpaceIdentifier) ] - reply:^(NSArray *reply) { - if (reply != nil) { - if (reply.count > 1) { - completion([FlutterError errorWithCode:reply[0] - message:reply[1] - details:reply[2]]); - } else { - completion(nil); - } - } else { - completion([FlutterError errorWithCode:@"channel-error" - message:@"Unable to establish connection on channel." - details:@""]); - } - }]; + [channel sendMessage:@[ @(arg_identifier), @(arg_protectionSpaceIdentifier) ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion([FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + completion(nil); + } + } else { + completion(createConnectionError(channelName)); + } + }]; } @end diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFHTTPCookieStoreHostApi.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFHTTPCookieStoreHostApi.m similarity index 89% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFHTTPCookieStoreHostApi.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFHTTPCookieStoreHostApi.m index 54703ff15b70..a2eb675286ac 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFHTTPCookieStoreHostApi.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFHTTPCookieStoreHostApi.m @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FWFHTTPCookieStoreHostApi.h" -#import "FWFDataConverters.h" -#import "FWFWebsiteDataStoreHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFHTTPCookieStoreHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFDataConverters.h" +#import "./include/webview_flutter_wkwebview/FWFWebsiteDataStoreHostApi.h" @interface FWFHTTPCookieStoreHostApiImpl () // InstanceManager must be weak to prevent a circular reference with the object it stores. diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFInstanceManager.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFInstanceManager.m similarity index 94% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFInstanceManager.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFInstanceManager.m index c2af8444a425..26182be6391a 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFInstanceManager.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFInstanceManager.m @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FWFInstanceManager.h" -#import "FWFInstanceManager_Test.h" +#import "./include/webview_flutter_wkwebview/FWFInstanceManager.h" +#import "./include/webview_flutter_wkwebview/FWFInstanceManager_Test.h" #import @@ -140,17 +140,17 @@ - (long)identifierWithStrongReferenceForInstance:(nonnull NSObject *)instance { NSNumber *__block identifierNumber = nil; dispatch_sync(_lockQueue, ^{ identifierNumber = [self.identifiers objectForKey:instance]; - if (identifierNumber) { + if (identifierNumber != nil) { [self.strongInstances setObject:instance forKey:identifierNumber]; } }); - return identifierNumber ? identifierNumber.longValue : NSNotFound; + return identifierNumber != nil ? identifierNumber.longValue : NSNotFound; } - (BOOL)containsInstance:(nonnull NSObject *)instance { BOOL __block containsInstance; dispatch_sync(_lockQueue, ^{ - containsInstance = [self.identifiers objectForKey:instance]; + containsInstance = [self.identifiers objectForKey:instance] != nil; }); return containsInstance; } diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFNavigationDelegateHostApi.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFNavigationDelegateHostApi.m similarity index 98% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFNavigationDelegateHostApi.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFNavigationDelegateHostApi.m index 2718702d4b93..d862de226207 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFNavigationDelegateHostApi.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFNavigationDelegateHostApi.m @@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FWFNavigationDelegateHostApi.h" -#import "FWFDataConverters.h" -#import "FWFURLAuthenticationChallengeHostApi.h" -#import "FWFWebViewConfigurationHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFNavigationDelegateHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFDataConverters.h" +#import "./include/webview_flutter_wkwebview/FWFURLAuthenticationChallengeHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFWebViewConfigurationHostApi.h" @interface FWFNavigationDelegateFlutterApiImpl () // BinaryMessenger must be weak to prevent a circular reference with the host API it @@ -276,7 +276,7 @@ - (void)webView:(WKWebView *)webView response.disposition); NSURLCredential *credential = - response.credentialIdentifier + response.credentialIdentifier != nil ? (NSURLCredential *)[self.navigationDelegateAPI .instanceManager instanceForIdentifier: diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFObjectHostApi.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFObjectHostApi.m similarity index 97% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFObjectHostApi.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFObjectHostApi.m index 098d291c6c2b..81e26a2f7d80 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFObjectHostApi.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFObjectHostApi.m @@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FWFObjectHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFObjectHostApi.h" #import -#import "FWFDataConverters.h" -#import "FWFURLHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFDataConverters.h" +#import "./include/webview_flutter_wkwebview/FWFURLHostApi.h" @interface FWFObjectFlutterApiImpl () // BinaryMessenger must be weak to prevent a circular reference with the host API it diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFPreferencesHostApi.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFPreferencesHostApi.m similarity index 83% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFPreferencesHostApi.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFPreferencesHostApi.m index 95078975f4d9..b2b442b3ffac 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFPreferencesHostApi.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFPreferencesHostApi.m @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FWFPreferencesHostApi.h" -#import "FWFWebViewConfigurationHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFPreferencesHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFWebViewConfigurationHostApi.h" @interface FWFPreferencesHostApiImpl () // InstanceManager must be weak to prevent a circular reference with the object it stores. @@ -39,6 +39,10 @@ - (void)createFromWebViewConfigurationWithIdentifier:(NSInteger)identifier - (void)setJavaScriptEnabledForPreferencesWithIdentifier:(NSInteger)identifier isEnabled:(BOOL)enabled error:(FlutterError *_Nullable *_Nonnull)error { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + // TODO(stuartmorgan): Replace with new API. See https://github.com/flutter/flutter/issues/125901 [[self preferencesForIdentifier:identifier] setJavaScriptEnabled:enabled]; +#pragma clang diagnostic pop } @end diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScriptMessageHandlerHostApi.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFScriptMessageHandlerHostApi.m similarity index 96% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScriptMessageHandlerHostApi.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFScriptMessageHandlerHostApi.m index 1e27c1208bd0..2b44e5e397f5 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScriptMessageHandlerHostApi.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFScriptMessageHandlerHostApi.m @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FWFScriptMessageHandlerHostApi.h" -#import "FWFDataConverters.h" +#import "./include/webview_flutter_wkwebview/FWFScriptMessageHandlerHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFDataConverters.h" @interface FWFScriptMessageHandlerFlutterApiImpl () // InstanceManager must be weak to prevent a circular reference with the object it stores. diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScrollViewDelegateHostApi.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFScrollViewDelegateHostApi.m similarity index 91% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScrollViewDelegateHostApi.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFScrollViewDelegateHostApi.m index f8d7630dc8ae..ec5e55587dc3 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScrollViewDelegateHostApi.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFScrollViewDelegateHostApi.m @@ -2,8 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FWFScrollViewDelegateHostApi.h" -#import "FWFWebViewHostApi.h" +// Using directory structure to remove platform-specific files doesn't work +// well with umbrella headers and module maps, so just no-op the file for +// other platforms instead. +#if TARGET_OS_IOS + +#import "./include/webview_flutter_wkwebview/FWFScrollViewDelegateHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFWebViewHostApi.h" @interface FWFScrollViewDelegateFlutterApiImpl () // BinaryMessenger must be weak to prevent a circular reference with the host API it @@ -88,3 +93,5 @@ - (void)createWithIdentifier:(NSInteger)identifier error:(FlutterError *_Nullabl [self.instanceManager addDartCreatedInstance:uiScrollViewDelegate withIdentifier:identifier]; } @end + +#endif diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScrollViewHostApi.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFScrollViewHostApi.m similarity index 83% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScrollViewHostApi.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFScrollViewHostApi.m index 9cefa330c047..b57ba2a539a4 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScrollViewHostApi.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFScrollViewHostApi.m @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FWFScrollViewHostApi.h" -#import "FWFScrollViewDelegateHostApi.h" -#import "FWFWebViewHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFScrollViewHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFScrollViewDelegateHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFWebViewHostApi.h" @interface FWFScrollViewHostApiImpl () // BinaryMessenger must be weak to prevent a circular reference with the host API it @@ -24,47 +24,65 @@ - (instancetype)initWithInstanceManager:(FWFInstanceManager *)instanceManager { return self; } +#if TARGET_OS_IOS - (UIScrollView *)scrollViewForIdentifier:(NSInteger)identifier { return (UIScrollView *)[self.instanceManager instanceForIdentifier:identifier]; } +#endif - (void)createFromWebViewWithIdentifier:(NSInteger)identifier webViewIdentifier:(NSInteger)webViewIdentifier error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { +#if TARGET_OS_IOS WKWebView *webView = (WKWebView *)[self.instanceManager instanceForIdentifier:webViewIdentifier]; [self.instanceManager addDartCreatedInstance:webView.scrollView withIdentifier:identifier]; +#else + *error = [FlutterError errorWithCode:@"UnavailableApi" + message:@"scrollView is unavailable on macOS" + details:nil]; +#endif } - (NSArray *) contentOffsetForScrollViewWithIdentifier:(NSInteger)identifier error:(FlutterError *_Nullable *_Nonnull)error { +#if TARGET_OS_IOS CGPoint point = [[self scrollViewForIdentifier:identifier] contentOffset]; return @[ @(point.x), @(point.y) ]; +#else + return @[ @(0), @(0) ]; +#endif } - (void)scrollByForScrollViewWithIdentifier:(NSInteger)identifier x:(double)x y:(double)y error:(FlutterError *_Nullable *_Nonnull)error { +#if TARGET_OS_IOS UIScrollView *scrollView = [self scrollViewForIdentifier:identifier]; CGPoint contentOffset = scrollView.contentOffset; [scrollView setContentOffset:CGPointMake(contentOffset.x + x, contentOffset.y + y)]; +#endif } - (void)setContentOffsetForScrollViewWithIdentifier:(NSInteger)identifier toX:(double)x y:(double)y error:(FlutterError *_Nullable *_Nonnull)error { +#if TARGET_OS_IOS [[self scrollViewForIdentifier:identifier] setContentOffset:CGPointMake(x, y)]; +#endif } - (void)setDelegateForScrollViewWithIdentifier:(NSInteger)identifier uiScrollViewDelegateIdentifier:(nullable NSNumber *)uiScrollViewDelegateIdentifier error:(FlutterError *_Nullable *_Nonnull)error { +#if TARGET_OS_IOS [[self scrollViewForIdentifier:identifier] setDelegate:uiScrollViewDelegateIdentifier ? (FWFScrollViewDelegate *)[self.instanceManager instanceForIdentifier:uiScrollViewDelegateIdentifier.longValue] : nil]; +#endif } @end diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUIDelegateHostApi.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFUIDelegateHostApi.m similarity index 98% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUIDelegateHostApi.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFUIDelegateHostApi.m index f9d78eaea06a..e38635a3d218 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUIDelegateHostApi.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFUIDelegateHostApi.m @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FWFUIDelegateHostApi.h" -#import "FWFDataConverters.h" +#import "./include/webview_flutter_wkwebview/FWFUIDelegateHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFDataConverters.h" @interface FWFUIDelegateFlutterApiImpl () // BinaryMessenger must be weak to prevent a circular reference with the host API it @@ -64,7 +64,7 @@ - (void)requestMediaCapturePermissionForDelegateWithIdentifier:(FWFUIDelegate *) type:(WKMediaCaptureType)type completion: (void (^)(WKPermissionDecision))completion - API_AVAILABLE(ios(15.0)) { + API_AVAILABLE(ios(15.0), macos(12)) { [self requestMediaCapturePermissionForDelegateWithIdentifier:[self identifierForDelegate:instance] webViewIdentifier: @@ -177,7 +177,7 @@ - (void)webView:(WKWebView *)webView initiatedByFrame:(WKFrameInfo *)frame type:(WKMediaCaptureType)type decisionHandler:(void (^)(WKPermissionDecision))decisionHandler - API_AVAILABLE(ios(15.0)) { + API_AVAILABLE(ios(15.0), macos(12)) { [self.UIDelegateAPI requestMediaCapturePermissionForDelegateWithIdentifier:self webView:webView diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUIViewHostApi.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFUIViewHostApi.m similarity index 86% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUIViewHostApi.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFUIViewHostApi.m index 3ee6f38faa80..0a2c0dcc36f8 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUIViewHostApi.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFUIViewHostApi.m @@ -2,7 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FWFUIViewHostApi.h" +// Using directory structure to remove platform-specific files doesn't work +// well with umbrella headers and module maps, so just no-op the file for +// other platforms instead. +#if TARGET_OS_IOS + +#import "./include/webview_flutter_wkwebview/FWFUIViewHostApi.h" @interface FWFUIViewHostApiImpl () // InstanceManager must be weak to prevent a circular reference with the object it stores. @@ -42,3 +47,5 @@ - (void)setOpaqueForViewWithIdentifier:(NSInteger)identifier [[self viewForIdentifier:identifier] setOpaque:opaque]; } @end + +#endif diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLAuthenticationChallengeHostApi.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFURLAuthenticationChallengeHostApi.m similarity index 93% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLAuthenticationChallengeHostApi.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFURLAuthenticationChallengeHostApi.m index 965952dfebeb..ac374b786c77 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLAuthenticationChallengeHostApi.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFURLAuthenticationChallengeHostApi.m @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FWFURLAuthenticationChallengeHostApi.h" -#import "FWFURLProtectionSpaceHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFURLAuthenticationChallengeHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFURLProtectionSpaceHostApi.h" @interface FWFURLAuthenticationChallengeFlutterApiImpl () // BinaryMessenger must be weak to prevent a circular reference with the host API it diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLCredentialHostApi.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFURLCredentialHostApi.m similarity index 97% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLCredentialHostApi.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFURLCredentialHostApi.m index 2b6955ff2875..7ac0647a8f98 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLCredentialHostApi.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFURLCredentialHostApi.m @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FWFURLCredentialHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFURLCredentialHostApi.h" @interface FWFURLCredentialHostApiImpl () // BinaryMessenger must be weak to prevent a circular reference with the host API it diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLHostApi.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFURLHostApi.m similarity index 97% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLHostApi.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFURLHostApi.m index c3101c7bfaaf..3ed6474efc27 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLHostApi.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFURLHostApi.m @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FWFURLHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFURLHostApi.h" @interface FWFURLHostApiImpl () // BinaryMessenger must be weak to prevent a circular reference with the host API it diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLProtectionSpaceHostApi.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFURLProtectionSpaceHostApi.m similarity index 94% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLProtectionSpaceHostApi.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFURLProtectionSpaceHostApi.m index fc2d16307013..f83889979dff 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLProtectionSpaceHostApi.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFURLProtectionSpaceHostApi.m @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FWFURLProtectionSpaceHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFURLProtectionSpaceHostApi.h" @interface FWFURLProtectionSpaceFlutterApiImpl () // InstanceManager must be weak to prevent a circular reference with the object it stores. diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUserContentControllerHostApi.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFUserContentControllerHostApi.m similarity index 92% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUserContentControllerHostApi.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFUserContentControllerHostApi.m index 074a54c9a8a9..1cd80344e7f3 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUserContentControllerHostApi.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFUserContentControllerHostApi.m @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FWFUserContentControllerHostApi.h" -#import "FWFDataConverters.h" -#import "FWFWebViewConfigurationHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFUserContentControllerHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFDataConverters.h" +#import "./include/webview_flutter_wkwebview/FWFWebViewConfigurationHostApi.h" @interface FWFUserContentControllerHostApiImpl () // InstanceManager must be weak to prevent a circular reference with the object it stores. @@ -55,12 +55,12 @@ - (void)removeAllScriptMessageHandlersForControllerWithIdentifier:(NSInteger)ide error: (FlutterError *_Nullable *_Nonnull) error { - if (@available(iOS 14.0, *)) { + if (@available(iOS 14.0, macOS 11, *)) { [[self userContentControllerForIdentifier:identifier] removeAllScriptMessageHandlers]; } else { *error = [FlutterError errorWithCode:@"FWFUnsupportedVersionError" - message:@"removeAllScriptMessageHandlers is only supported on versions 14+." + message:@"removeAllScriptMessageHandlers is only supported on iOS 14+ and macOS 11+." details:nil]; } } diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFWebViewConfigurationHostApi.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFWebViewConfigurationHostApi.m similarity index 89% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFWebViewConfigurationHostApi.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFWebViewConfigurationHostApi.m index ee4896c1d2a1..d97bf9bfe6ed 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFWebViewConfigurationHostApi.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFWebViewConfigurationHostApi.m @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FWFWebViewConfigurationHostApi.h" -#import "FWFDataConverters.h" -#import "FWFWebViewConfigurationHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFWebViewConfigurationHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFDataConverters.h" +#import "./include/webview_flutter_wkwebview/FWFWebViewConfigurationHostApi.h" @interface FWFWebViewConfigurationFlutterApiImpl () // InstanceManager must be weak to prevent a circular reference with the object it stores. @@ -95,21 +95,25 @@ - (void)setAllowsInlineMediaPlaybackForConfigurationWithIdentifier:(NSInteger)id error: (FlutterError *_Nullable *_Nonnull) error { +#if TARGET_OS_IOS [[self webViewConfigurationForIdentifier:identifier] setAllowsInlineMediaPlayback:allow]; +#endif + // No-op, rather than error out, on macOS, since it's not a meaningful option on macOS and it's + // easier for clients if it's just ignored. } - (void)setLimitsNavigationsToAppBoundDomainsForConfigurationWithIdentifier:(NSInteger)identifier isLimited:(BOOL)limit error:(FlutterError *_Nullable *_Nonnull)error { - if (@available(iOS 14, *)) { + if (@available(iOS 14, macOS 11, *)) { [[self webViewConfigurationForIdentifier:identifier] setLimitsNavigationsToAppBoundDomains:limit]; } else { - *error = [FlutterError - errorWithCode:@"FWFUnsupportedVersionError" - message:@"setLimitsNavigationsToAppBoundDomains is only supported on versions 14+." - details:nil]; + *error = [FlutterError errorWithCode:@"FWFUnsupportedVersionError" + message:@"setLimitsNavigationsToAppBoundDomains is only supported " + @"on iOS 14+ and macOS 11+." + details:nil]; } } diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFWebViewFlutterWKWebViewExternalAPI.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFWebViewFlutterWKWebViewExternalAPI.m similarity index 81% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFWebViewFlutterWKWebViewExternalAPI.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFWebViewFlutterWKWebViewExternalAPI.m index 4e5d6efeb129..8cf93183b8a9 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFWebViewFlutterWKWebViewExternalAPI.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFWebViewFlutterWKWebViewExternalAPI.m @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FWFWebViewFlutterWKWebViewExternalAPI.h" -#import "FWFInstanceManager.h" +#import "./include/webview_flutter_wkwebview/FWFWebViewFlutterWKWebViewExternalAPI.h" +#import "./include/webview_flutter_wkwebview/FWFInstanceManager.h" @implementation FWFWebViewFlutterWKWebViewExternalAPI + (nullable WKWebView *)webViewForIdentifier:(long)identifier diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFWebViewHostApi.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFWebViewHostApi.m similarity index 98% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFWebViewHostApi.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFWebViewHostApi.m index 7c2f3ede932d..2a937435c91f 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFWebViewHostApi.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFWebViewHostApi.m @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FWFWebViewHostApi.h" -#import "FWFDataConverters.h" +#import "./include/webview_flutter_wkwebview/FWFWebViewHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFDataConverters.h" @implementation FWFAssetManager - (NSString *)lookupKeyForAsset:(NSString *)asset { @@ -21,16 +21,19 @@ - (instancetype)initWithFrame:(CGRect)frame _objectApi = [[FWFObjectFlutterApiImpl alloc] initWithBinaryMessenger:binaryMessenger instanceManager:instanceManager]; +#if TARGET_OS_IOS self.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; if (@available(iOS 13.0, *)) { self.scrollView.automaticallyAdjustsScrollIndicatorInsets = NO; } +#endif } return self; } - (void)setFrame:(CGRect)frame { [super setFrame:frame]; +#if TARGET_OS_IOS // Prevents the contentInsets from being adjusted by iOS and gives control to Flutter. self.scrollView.contentInset = UIEdgeInsetsZero; @@ -42,6 +45,7 @@ - (void)setFrame:(CGRect)frame { UIEdgeInsets insetToAdjust = self.scrollView.adjustedContentInset; self.scrollView.contentInset = UIEdgeInsetsMake(-insetToAdjust.top, -insetToAdjust.left, -insetToAdjust.bottom, -insetToAdjust.right); +#endif } - (void)observeValueForKeyPath:(NSString *)keyPath @@ -57,9 +61,13 @@ - (void)observeValueForKeyPath:(NSString *)keyPath }]; } +#pragma mark FlutterPlatformView + +#if TARGET_OS_IOS - (nonnull UIView *)view { return self; } +#endif @end @interface FWFWebViewHostApiImpl () diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFWebsiteDataStoreHostApi.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFWebsiteDataStoreHostApi.m similarity index 93% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFWebsiteDataStoreHostApi.m rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFWebsiteDataStoreHostApi.m index f7252240957d..7e7ead760efa 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFWebsiteDataStoreHostApi.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFWebsiteDataStoreHostApi.m @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FWFWebsiteDataStoreHostApi.h" -#import "FWFDataConverters.h" -#import "FWFWebViewConfigurationHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFWebsiteDataStoreHostApi.h" +#import "./include/webview_flutter_wkwebview/FWFDataConverters.h" +#import "./include/webview_flutter_wkwebview/FWFWebViewConfigurationHostApi.h" @interface FWFWebsiteDataStoreHostApiImpl () // InstanceManager must be weak to prevent a circular reference with the object it stores. diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Resources/PrivacyInfo.xcprivacy b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/Resources/PrivacyInfo.xcprivacy similarity index 100% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Resources/PrivacyInfo.xcprivacy rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/Resources/PrivacyInfo.xcprivacy diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FlutterWebView.modulemap b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/FlutterWebView.modulemap similarity index 100% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FlutterWebView.modulemap rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/FlutterWebView.modulemap diff --git a/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview-umbrella.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview-umbrella.h new file mode 100644 index 000000000000..e553b0a288b6 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview-umbrella.h @@ -0,0 +1,27 @@ +// 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 +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FLTWebViewFlutterPlugin.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FLTWebViewFlutterPlugin.h similarity index 82% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FLTWebViewFlutterPlugin.h rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FLTWebViewFlutterPlugin.h index a1c035e40185..e57f238d9aab 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FLTWebViewFlutterPlugin.h +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FLTWebViewFlutterPlugin.h @@ -2,9 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import #import +#if TARGET_OS_OSX +#import +#else +#import +#endif + NS_ASSUME_NONNULL_BEGIN @interface FLTWebViewFlutterPlugin : NSObject diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFDataConverters.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFDataConverters.h similarity index 99% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFDataConverters.h rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFDataConverters.h index f97de9c8c19e..b007ff901b98 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFDataConverters.h +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFDataConverters.h @@ -175,7 +175,7 @@ extern FWFWKSecurityOriginData *FWFWKSecurityOriginDataFromNativeWKSecurityOrigi /// @param data The data object containing information to create a WKPermissionDecision. /// /// @return A WKPermissionDecision or -1 if data could not be converted. -API_AVAILABLE(ios(15.0)) +API_AVAILABLE(ios(15.0), macos(12)) extern WKPermissionDecision FWFNativeWKPermissionDecisionFromData( FWFWKPermissionDecisionData *data); @@ -184,7 +184,7 @@ extern WKPermissionDecision FWFNativeWKPermissionDecisionFromData( /// @param type The data object containing information to create a FWFWKMediaCaptureTypeData. /// /// @return A FWFWKMediaCaptureTypeData or nil if data could not be converted. -API_AVAILABLE(ios(15.0)) +API_AVAILABLE(ios(15.0), macos(12)) extern FWFWKMediaCaptureTypeData *FWFWKMediaCaptureTypeDataFromNativeWKMediaCaptureType( WKMediaCaptureType type); diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFGeneratedWebKitApis.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFGeneratedWebKitApis.h similarity index 92% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFGeneratedWebKitApis.h rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFGeneratedWebKitApis.h index 984cfc93cc33..dd5fdf97bbcf 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFGeneratedWebKitApis.h +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFGeneratedWebKitApis.h @@ -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 (v13.0.0), do not edit directly. +// Autogenerated from Pigeon (v18.0.0), do not edit directly. // See also: https://pub.dev/packages/pigeon #import @@ -601,6 +601,10 @@ extern void SetUpFWFWKWebsiteDataStoreHostApi( id binaryMessenger, NSObject *_Nullable api); +extern void SetUpFWFWKWebsiteDataStoreHostApiWithSuffix( + id binaryMessenger, + NSObject *_Nullable api, NSString *messageChannelSuffix); + /// The codec used by FWFUIViewHostApi. NSObject *FWFUIViewHostApiGetCodec(void); @@ -619,6 +623,10 @@ NSObject *FWFUIViewHostApiGetCodec(void); extern void SetUpFWFUIViewHostApi(id binaryMessenger, NSObject *_Nullable api); +extern void SetUpFWFUIViewHostApiWithSuffix(id binaryMessenger, + NSObject *_Nullable api, + NSString *messageChannelSuffix); + /// The codec used by FWFUIScrollViewHostApi. NSObject *FWFUIScrollViewHostApiGetCodec(void); @@ -649,6 +657,10 @@ NSObject *FWFUIScrollViewHostApiGetCodec(void); extern void SetUpFWFUIScrollViewHostApi(id binaryMessenger, NSObject *_Nullable api); +extern void SetUpFWFUIScrollViewHostApiWithSuffix(id binaryMessenger, + NSObject *_Nullable api, + NSString *messageChannelSuffix); + /// The codec used by FWFWKWebViewConfigurationHostApi. NSObject *FWFWKWebViewConfigurationHostApiGetCodec(void); @@ -684,6 +696,10 @@ extern void SetUpFWFWKWebViewConfigurationHostApi( id binaryMessenger, NSObject *_Nullable api); +extern void SetUpFWFWKWebViewConfigurationHostApiWithSuffix( + id binaryMessenger, + NSObject *_Nullable api, NSString *messageChannelSuffix); + /// The codec used by FWFWKWebViewConfigurationFlutterApi. NSObject *FWFWKWebViewConfigurationFlutterApiGetCodec(void); @@ -692,6 +708,8 @@ NSObject *FWFWKWebViewConfigurationFlutterApiGetCodec(void) /// See https://developer.apple.com/documentation/webkit/wkwebviewconfiguration?language=objc. @interface FWFWKWebViewConfigurationFlutterApi : NSObject - (instancetype)initWithBinaryMessenger:(id)binaryMessenger; +- (instancetype)initWithBinaryMessenger:(id)binaryMessenger + messageChannelSuffix:(nullable NSString *)messageChannelSuffix; - (void)createWithIdentifier:(NSInteger)identifier completion:(void (^)(FlutterError *_Nullable))completion; @end @@ -729,6 +747,10 @@ extern void SetUpFWFWKUserContentControllerHostApi( id binaryMessenger, NSObject *_Nullable api); +extern void SetUpFWFWKUserContentControllerHostApiWithSuffix( + id binaryMessenger, + NSObject *_Nullable api, NSString *messageChannelSuffix); + /// The codec used by FWFWKPreferencesHostApi. NSObject *FWFWKPreferencesHostApiGetCodec(void); @@ -747,6 +769,10 @@ NSObject *FWFWKPreferencesHostApiGetCodec(void); extern void SetUpFWFWKPreferencesHostApi(id binaryMessenger, NSObject *_Nullable api); +extern void SetUpFWFWKPreferencesHostApiWithSuffix(id binaryMessenger, + NSObject *_Nullable api, + NSString *messageChannelSuffix); + /// The codec used by FWFWKScriptMessageHandlerHostApi. NSObject *FWFWKScriptMessageHandlerHostApiGetCodec(void); @@ -761,6 +787,10 @@ extern void SetUpFWFWKScriptMessageHandlerHostApi( id binaryMessenger, NSObject *_Nullable api); +extern void SetUpFWFWKScriptMessageHandlerHostApiWithSuffix( + id binaryMessenger, + NSObject *_Nullable api, NSString *messageChannelSuffix); + /// The codec used by FWFWKScriptMessageHandlerFlutterApi. NSObject *FWFWKScriptMessageHandlerFlutterApiGetCodec(void); @@ -769,6 +799,8 @@ NSObject *FWFWKScriptMessageHandlerFlutterApiGetCodec(void) /// See https://developer.apple.com/documentation/webkit/wkscriptmessagehandler?language=objc. @interface FWFWKScriptMessageHandlerFlutterApi : NSObject - (instancetype)initWithBinaryMessenger:(id)binaryMessenger; +- (instancetype)initWithBinaryMessenger:(id)binaryMessenger + messageChannelSuffix:(nullable NSString *)messageChannelSuffix; - (void)didReceiveScriptMessageForHandlerWithIdentifier:(NSInteger)identifier userContentControllerIdentifier:(NSInteger)userContentControllerIdentifier message:(FWFWKScriptMessageData *)message @@ -790,6 +822,10 @@ extern void SetUpFWFWKNavigationDelegateHostApi( id binaryMessenger, NSObject *_Nullable api); +extern void SetUpFWFWKNavigationDelegateHostApiWithSuffix( + id binaryMessenger, + NSObject *_Nullable api, NSString *messageChannelSuffix); + /// The codec used by FWFWKNavigationDelegateFlutterApi. NSObject *FWFWKNavigationDelegateFlutterApiGetCodec(void); @@ -798,6 +834,8 @@ NSObject *FWFWKNavigationDelegateFlutterApiGetCodec(void); /// See https://developer.apple.com/documentation/webkit/wknavigationdelegate?language=objc. @interface FWFWKNavigationDelegateFlutterApi : NSObject - (instancetype)initWithBinaryMessenger:(id)binaryMessenger; +- (instancetype)initWithBinaryMessenger:(id)binaryMessenger + messageChannelSuffix:(nullable NSString *)messageChannelSuffix; - (void)didFinishNavigationForDelegateWithIdentifier:(NSInteger)identifier webViewIdentifier:(NSInteger)webViewIdentifier URL:(nullable NSString *)url @@ -873,6 +911,10 @@ NSObject *FWFNSObjectHostApiGetCodec(void); extern void SetUpFWFNSObjectHostApi(id binaryMessenger, NSObject *_Nullable api); +extern void SetUpFWFNSObjectHostApiWithSuffix(id binaryMessenger, + NSObject *_Nullable api, + NSString *messageChannelSuffix); + /// The codec used by FWFNSObjectFlutterApi. NSObject *FWFNSObjectFlutterApiGetCodec(void); @@ -881,6 +923,8 @@ NSObject *FWFNSObjectFlutterApiGetCodec(void); /// See https://developer.apple.com/documentation/objectivec/nsobject. @interface FWFNSObjectFlutterApi : NSObject - (instancetype)initWithBinaryMessenger:(id)binaryMessenger; +- (instancetype)initWithBinaryMessenger:(id)binaryMessenger + messageChannelSuffix:(nullable NSString *)messageChannelSuffix; - (void)observeValueForObjectWithIdentifier:(NSInteger)identifier keyPath:(NSString *)keyPath objectIdentifier:(NSInteger)objectIdentifier @@ -964,6 +1008,10 @@ NSObject *FWFWKWebViewHostApiGetCodec(void); extern void SetUpFWFWKWebViewHostApi(id binaryMessenger, NSObject *_Nullable api); +extern void SetUpFWFWKWebViewHostApiWithSuffix(id binaryMessenger, + NSObject *_Nullable api, + NSString *messageChannelSuffix); + /// The codec used by FWFWKUIDelegateHostApi. NSObject *FWFWKUIDelegateHostApiGetCodec(void); @@ -977,6 +1025,10 @@ NSObject *FWFWKUIDelegateHostApiGetCodec(void); extern void SetUpFWFWKUIDelegateHostApi(id binaryMessenger, NSObject *_Nullable api); +extern void SetUpFWFWKUIDelegateHostApiWithSuffix(id binaryMessenger, + NSObject *_Nullable api, + NSString *messageChannelSuffix); + /// The codec used by FWFWKUIDelegateFlutterApi. NSObject *FWFWKUIDelegateFlutterApiGetCodec(void); @@ -985,6 +1037,8 @@ NSObject *FWFWKUIDelegateFlutterApiGetCodec(void); /// See https://developer.apple.com/documentation/webkit/wkuidelegate?language=objc. @interface FWFWKUIDelegateFlutterApi : NSObject - (instancetype)initWithBinaryMessenger:(id)binaryMessenger; +- (instancetype)initWithBinaryMessenger:(id)binaryMessenger + messageChannelSuffix:(nullable NSString *)messageChannelSuffix; - (void)onCreateWebViewForDelegateWithIdentifier:(NSInteger)identifier webViewIdentifier:(NSInteger)webViewIdentifier configurationIdentifier:(NSInteger)configurationIdentifier @@ -1041,6 +1095,10 @@ NSObject *FWFWKHttpCookieStoreHostApiGetCodec(void); extern void SetUpFWFWKHttpCookieStoreHostApi(id binaryMessenger, NSObject *_Nullable api); +extern void SetUpFWFWKHttpCookieStoreHostApiWithSuffix( + id binaryMessenger, + NSObject *_Nullable api, NSString *messageChannelSuffix); + /// The codec used by FWFNSUrlHostApi. NSObject *FWFNSUrlHostApiGetCodec(void); @@ -1060,6 +1118,10 @@ NSObject *FWFNSUrlHostApiGetCodec(void); extern void SetUpFWFNSUrlHostApi(id binaryMessenger, NSObject *_Nullable api); +extern void SetUpFWFNSUrlHostApiWithSuffix(id binaryMessenger, + NSObject *_Nullable api, + NSString *messageChannelSuffix); + /// The codec used by FWFNSUrlFlutterApi. NSObject *FWFNSUrlFlutterApiGetCodec(void); @@ -1072,6 +1134,8 @@ NSObject *FWFNSUrlFlutterApiGetCodec(void); /// See https://developer.apple.com/documentation/foundation/nsurl?language=objc. @interface FWFNSUrlFlutterApi : NSObject - (instancetype)initWithBinaryMessenger:(id)binaryMessenger; +- (instancetype)initWithBinaryMessenger:(id)binaryMessenger + messageChannelSuffix:(nullable NSString *)messageChannelSuffix; - (void)createWithIdentifier:(NSInteger)identifier completion:(void (^)(FlutterError *_Nullable))completion; @end @@ -1094,6 +1158,10 @@ extern void SetUpFWFUIScrollViewDelegateHostApi( id binaryMessenger, NSObject *_Nullable api); +extern void SetUpFWFUIScrollViewDelegateHostApiWithSuffix( + id binaryMessenger, + NSObject *_Nullable api, NSString *messageChannelSuffix); + /// The codec used by FWFUIScrollViewDelegateFlutterApi. NSObject *FWFUIScrollViewDelegateFlutterApiGetCodec(void); @@ -1102,6 +1170,8 @@ NSObject *FWFUIScrollViewDelegateFlutterApiGetCodec(void); /// See https://developer.apple.com/documentation/uikit/uiscrollviewdelegate?language=objc. @interface FWFUIScrollViewDelegateFlutterApi : NSObject - (instancetype)initWithBinaryMessenger:(id)binaryMessenger; +- (instancetype)initWithBinaryMessenger:(id)binaryMessenger + messageChannelSuffix:(nullable NSString *)messageChannelSuffix; - (void)scrollViewDidScrollWithIdentifier:(NSInteger)identifier UIScrollViewIdentifier:(NSInteger)uiScrollViewIdentifier x:(double)x @@ -1131,6 +1201,10 @@ NSObject *FWFNSUrlCredentialHostApiGetCodec(void); extern void SetUpFWFNSUrlCredentialHostApi(id binaryMessenger, NSObject *_Nullable api); +extern void SetUpFWFNSUrlCredentialHostApiWithSuffix( + id binaryMessenger, NSObject *_Nullable api, + NSString *messageChannelSuffix); + /// The codec used by FWFNSUrlProtectionSpaceFlutterApi. NSObject *FWFNSUrlProtectionSpaceFlutterApiGetCodec(void); @@ -1143,6 +1217,8 @@ NSObject *FWFNSUrlProtectionSpaceFlutterApiGetCodec(void); /// See https://developer.apple.com/documentation/foundation/nsurlprotectionspace?language=objc. @interface FWFNSUrlProtectionSpaceFlutterApi : NSObject - (instancetype)initWithBinaryMessenger:(id)binaryMessenger; +- (instancetype)initWithBinaryMessenger:(id)binaryMessenger + messageChannelSuffix:(nullable NSString *)messageChannelSuffix; /// Create a new Dart instance and add it to the `InstanceManager`. - (void)createWithIdentifier:(NSInteger)identifier host:(nullable NSString *)host @@ -1164,6 +1240,8 @@ NSObject *FWFNSUrlAuthenticationChallengeFlutterApiGetCodec /// https://developer.apple.com/documentation/foundation/nsurlauthenticationchallenge?language=objc. @interface FWFNSUrlAuthenticationChallengeFlutterApi : NSObject - (instancetype)initWithBinaryMessenger:(id)binaryMessenger; +- (instancetype)initWithBinaryMessenger:(id)binaryMessenger + messageChannelSuffix:(nullable NSString *)messageChannelSuffix; /// Create a new Dart instance and add it to the `InstanceManager`. - (void)createWithIdentifier:(NSInteger)identifier protectionSpaceIdentifier:(NSInteger)protectionSpaceIdentifier diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFHTTPCookieStoreHostApi.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFHTTPCookieStoreHostApi.h similarity index 90% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFHTTPCookieStoreHostApi.h rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFHTTPCookieStoreHostApi.h index f1994b7705b5..bb2adfb19367 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFHTTPCookieStoreHostApi.h +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFHTTPCookieStoreHostApi.h @@ -2,9 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import #import +#if TARGET_OS_OSX +#import +#else +#import +#endif + #import "FWFGeneratedWebKitApis.h" #import "FWFInstanceManager.h" diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFInstanceManager.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFInstanceManager.h similarity index 100% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFInstanceManager.h rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFInstanceManager.h diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFInstanceManager_Test.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFInstanceManager_Test.h similarity index 100% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFInstanceManager_Test.h rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFInstanceManager_Test.h diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFNavigationDelegateHostApi.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFNavigationDelegateHostApi.h similarity index 95% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFNavigationDelegateHostApi.h rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFNavigationDelegateHostApi.h index fb4e076095d9..db1edee310e9 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFNavigationDelegateHostApi.h +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFNavigationDelegateHostApi.h @@ -2,10 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import #import #import +#if TARGET_OS_OSX +#import +#else +#import +#endif + #import "FWFGeneratedWebKitApis.h" #import "FWFInstanceManager.h" #import "FWFObjectHostApi.h" diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFObjectHostApi.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFObjectHostApi.h similarity index 95% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFObjectHostApi.h rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFObjectHostApi.h index 08080eb5bb8c..8bdc7f6a0c00 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFObjectHostApi.h +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFObjectHostApi.h @@ -2,7 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#if TARGET_OS_OSX +#import +#else #import +#endif #import "FWFGeneratedWebKitApis.h" #import "FWFInstanceManager.h" diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFPreferencesHostApi.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFPreferencesHostApi.h similarity index 90% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFPreferencesHostApi.h rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFPreferencesHostApi.h index 136dccaec8cb..de2b6dd63d52 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFPreferencesHostApi.h +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFPreferencesHostApi.h @@ -2,7 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#if TARGET_OS_OSX +#import +#else #import +#endif #import #import "FWFGeneratedWebKitApis.h" diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScriptMessageHandlerHostApi.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFScriptMessageHandlerHostApi.h similarity index 95% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScriptMessageHandlerHostApi.h rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFScriptMessageHandlerHostApi.h index 91e6aa01392f..2e79e40edc5d 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScriptMessageHandlerHostApi.h +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFScriptMessageHandlerHostApi.h @@ -2,9 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import #import +#if TARGET_OS_OSX +#import +#else +#import +#endif + #import "FWFGeneratedWebKitApis.h" #import "FWFInstanceManager.h" #import "FWFObjectHostApi.h" diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScrollViewDelegateHostApi.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFScrollViewDelegateHostApi.h similarity index 88% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScrollViewDelegateHostApi.h rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFScrollViewDelegateHostApi.h index ec2237c6a0dd..5608f79114cc 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScrollViewDelegateHostApi.h +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFScrollViewDelegateHostApi.h @@ -2,6 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// Using directory structure to remove platform-specific files doesn't work +// well with umbrella headers and module maps, so just no-op the file for +// other platforms instead. +#if TARGET_OS_IOS + #import #import #import "FWFObjectHostApi.h" @@ -38,3 +43,5 @@ NS_ASSUME_NONNULL_BEGIN @end NS_ASSUME_NONNULL_END + +#endif diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScrollViewHostApi.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFScrollViewHostApi.h similarity index 89% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScrollViewHostApi.h rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFScrollViewHostApi.h index 7d87e4d561f9..5c65e129c85c 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScrollViewHostApi.h +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFScrollViewHostApi.h @@ -2,9 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import #import +#if TARGET_OS_OSX +#import +#else +#import +#endif + #import "FWFGeneratedWebKitApis.h" #import "FWFInstanceManager.h" diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUIDelegateHostApi.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFUIDelegateHostApi.h similarity index 95% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUIDelegateHostApi.h rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFUIDelegateHostApi.h index fd685c7b4b97..f5b52a52acf6 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUIDelegateHostApi.h +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFUIDelegateHostApi.h @@ -2,9 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import #import +#if TARGET_OS_OSX +#import +#else +#import +#endif + #import "FWFGeneratedWebKitApis.h" #import "FWFInstanceManager.h" #import "FWFObjectHostApi.h" diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUIViewHostApi.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFUIViewHostApi.h similarity index 73% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUIViewHostApi.h rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFUIViewHostApi.h index f63119738a82..cecd2ec6d3a0 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUIViewHostApi.h +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFUIViewHostApi.h @@ -2,6 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// Using directory structure to remove platform-specific files doesn't work +// well with umbrella headers and module maps, so just no-op the file for +// other platforms instead. +#if TARGET_OS_IOS + #import #import "FWFGeneratedWebKitApis.h" @@ -17,3 +22,5 @@ NS_ASSUME_NONNULL_BEGIN @end NS_ASSUME_NONNULL_END + +#endif diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLAuthenticationChallengeHostApi.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFURLAuthenticationChallengeHostApi.h similarity index 94% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLAuthenticationChallengeHostApi.h rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFURLAuthenticationChallengeHostApi.h index 2a16ff486b6d..4bc572072b2e 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLAuthenticationChallengeHostApi.h +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFURLAuthenticationChallengeHostApi.h @@ -2,11 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import #import #import "FWFGeneratedWebKitApis.h" #import "FWFInstanceManager.h" +#if TARGET_OS_OSX +#import +#else +#import +#endif + NS_ASSUME_NONNULL_BEGIN /// Flutter API implementation for `NSURLAuthenticationChallenge`. diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLCredentialHostApi.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFURLCredentialHostApi.h similarity index 92% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLCredentialHostApi.h rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFURLCredentialHostApi.h index 3c119e552e09..3f731bdcc62b 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLCredentialHostApi.h +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFURLCredentialHostApi.h @@ -2,12 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import #import #import "FWFDataConverters.h" #import "FWFGeneratedWebKitApis.h" #import "FWFInstanceManager.h" +#if TARGET_OS_OSX +#import +#else +#import +#endif + NS_ASSUME_NONNULL_BEGIN /// Host API implementation for `NSURLCredential`. diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLHostApi.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFURLHostApi.h similarity index 95% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLHostApi.h rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFURLHostApi.h index 919dcc5b3cf2..9238f89590b4 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLHostApi.h +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFURLHostApi.h @@ -2,8 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import #import + +#if TARGET_OS_OSX +#import +#else +#import +#endif + #import "FWFGeneratedWebKitApis.h" #import "FWFInstanceManager.h" diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLProtectionSpaceHostApi.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFURLProtectionSpaceHostApi.h similarity index 94% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLProtectionSpaceHostApi.h rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFURLProtectionSpaceHostApi.h index a4f7c537f1b5..f87e09c573ee 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLProtectionSpaceHostApi.h +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFURLProtectionSpaceHostApi.h @@ -2,11 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import #import #import "FWFGeneratedWebKitApis.h" #import "FWFInstanceManager.h" +#if TARGET_OS_OSX +#import +#else +#import +#endif + NS_ASSUME_NONNULL_BEGIN /// Flutter API implementation for `NSURLProtectionSpace`. diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUserContentControllerHostApi.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFUserContentControllerHostApi.h similarity index 90% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUserContentControllerHostApi.h rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFUserContentControllerHostApi.h index 8ca3b69b6a39..0905d3c7543a 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUserContentControllerHostApi.h +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFUserContentControllerHostApi.h @@ -2,9 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import #import +#if TARGET_OS_OSX +#import +#else +#import +#endif + #import "FWFGeneratedWebKitApis.h" #import "FWFInstanceManager.h" diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFWebViewConfigurationHostApi.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFWebViewConfigurationHostApi.h similarity index 96% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFWebViewConfigurationHostApi.h rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFWebViewConfigurationHostApi.h index c11ce1f29567..a5dd32a153b2 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFWebViewConfigurationHostApi.h +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFWebViewConfigurationHostApi.h @@ -2,9 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import #import +#if TARGET_OS_OSX +#import +#else +#import +#endif + #import "FWFGeneratedWebKitApis.h" #import "FWFInstanceManager.h" #import "FWFObjectHostApi.h" diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFWebViewFlutterWKWebViewExternalAPI.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFWebViewFlutterWKWebViewExternalAPI.h similarity index 95% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFWebViewFlutterWKWebViewExternalAPI.h rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFWebViewFlutterWKWebViewExternalAPI.h index b316f333cdde..e4e6ff3a1dea 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFWebViewFlutterWKWebViewExternalAPI.h +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFWebViewFlutterWKWebViewExternalAPI.h @@ -2,10 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import #import #import +#if TARGET_OS_OSX +#import +#else +#import +#endif + NS_ASSUME_NONNULL_BEGIN /// App and package facing native API provided by the `webview_flutter_wkwebview` plugin. diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFWebViewHostApi.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFWebViewHostApi.h similarity index 85% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFWebViewHostApi.h rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFWebViewHostApi.h index 037ea11f8494..2f9f28bea6c2 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFWebViewHostApi.h +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFWebViewHostApi.h @@ -2,9 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import #import +#if TARGET_OS_OSX +#import +#else +#import +#endif + #import "FWFGeneratedWebKitApis.h" #import "FWFInstanceManager.h" #import "FWFObjectHostApi.h" @@ -19,7 +24,12 @@ NS_ASSUME_NONNULL_BEGIN @end /// Implementation of WKWebView that can be used as a FlutterPlatformView. -@interface FWFWebView : WKWebView +@interface FWFWebView : WKWebView +// The macOS platform view API doesn't have a FlutterPlatformView abstraction, +// and uses NSView directly. +#if TARGET_OS_IOS + +#endif @property(readonly, nonnull, nonatomic) FWFObjectFlutterApiImpl *objectApi; - (instancetype)initWithFrame:(CGRect)frame diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFWebsiteDataStoreHostApi.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFWebsiteDataStoreHostApi.h similarity index 90% rename from packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFWebsiteDataStoreHostApi.h rename to packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFWebsiteDataStoreHostApi.h index 256c3f9d41f6..a5969e5215bb 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFWebsiteDataStoreHostApi.h +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFWebsiteDataStoreHostApi.h @@ -2,9 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import #import +#if TARGET_OS_OSX +#import +#else +#import +#endif + #import "FWFGeneratedWebKitApis.h" #import "FWFInstanceManager.h" diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/integration_test/legacy/webview_flutter_test.dart b/packages/webview_flutter/webview_flutter_wkwebview/example/integration_test/legacy/webview_flutter_test.dart index d2d3ea8f6b2e..47c6876d13d9 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/integration_test/legacy/webview_flutter_test.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/integration_test/legacy/webview_flutter_test.dart @@ -22,10 +22,15 @@ import 'package:webview_flutter_wkwebview_example/legacy/navigation_decision.dar import 'package:webview_flutter_wkwebview_example/legacy/navigation_request.dart'; import 'package:webview_flutter_wkwebview_example/legacy/web_view.dart'; +// TODO(bparrishMines): Remove once https://github.com/flutter/flutter/issues/154676 +// is fixed. +const bool skipOnIosFor154676 = true; + Future main() async { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - final HttpServer server = await HttpServer.bind(InternetAddress.anyIPv4, 0); + final HttpServer server = + await HttpServer.bind(InternetAddress.loopbackIPv4, 0); unawaited(server.forEach((HttpRequest request) { if (request.uri.path == '/hello.txt') { request.response.writeln('Hello, world.'); @@ -537,7 +542,7 @@ Future main() async { final String fullScreen = await controller.runJavascriptReturningResult('isFullScreen();'); expect(fullScreen, _webviewBool(false)); - }); + }, skip: Platform.isMacOS || skipOnIosFor154676); testWidgets( 'Video plays full screen when allowsInlineMediaPlayback is false', @@ -587,8 +592,10 @@ Future main() async { final String fullScreen = await controller.runJavascriptReturningResult('isFullScreen();'); expect(fullScreen, _webviewBool(true)); - }); - }); + }, skip: Platform.isMacOS || skipOnIosFor154676); + }, + // allowsInlineMediaPlayback has no effect on macOS. + skip: Platform.isMacOS); group('Audio playback policy', () { late String audioTestBase64; @@ -755,7 +762,10 @@ Future main() async { isPaused = await controller.runJavascriptReturningResult('isPaused();'); expect(isPaused, _webviewBool(false)); }); - }); + }, + // OGG playback is not supported on macOS, so the test data would need + // to be changed to support macOS. + skip: Platform.isMacOS); testWidgets('getTitle', (WidgetTester tester) async { const String getTitleTest = ''' @@ -882,7 +892,10 @@ Future main() async { expect(scrollPosX, X_SCROLL * 2); expect(scrollPosY, Y_SCROLL * 2); }); - }); + }, + // Scroll position is currently not implemented for macOS. + // Flakes on iOS: https://github.com/flutter/flutter/issues/154826 + skip: Platform.isMacOS || Platform.isIOS); group('NavigationDelegate', () { const String blankPage = ''; @@ -905,7 +918,7 @@ Future main() async { }, javascriptMode: JavascriptMode.unrestricted, navigationDelegate: (NavigationRequest request) { - return (request.url.contains('youtube.com')) + return request.url.contains('youtube.com') ? NavigationDecision.prevent : NavigationDecision.navigate; }, @@ -1035,7 +1048,7 @@ Future main() async { }, javascriptMode: JavascriptMode.unrestricted, navigationDelegate: (NavigationRequest request) { - return (request.url.contains('youtube.com')) + return request.url.contains('youtube.com') ? NavigationDecision.prevent : NavigationDecision.navigate; }, diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/integration_test/webview_flutter_test.dart b/packages/webview_flutter/webview_flutter_wkwebview/example/integration_test/webview_flutter_test.dart index 4a179696b791..7ca004d40786 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/integration_test/webview_flutter_test.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/integration_test/webview_flutter_test.dart @@ -24,7 +24,8 @@ import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart'; Future main() async { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - final HttpServer server = await HttpServer.bind(InternetAddress.anyIPv4, 0); + final HttpServer server = + await HttpServer.bind(InternetAddress.loopbackIPv4, 0); unawaited(server.forEach((HttpRequest request) { if (request.uri.path == '/hello.txt') { request.response.writeln('Hello, world.'); @@ -554,7 +555,9 @@ Future main() async { final bool fullScreen = await controller .runJavaScriptReturningResult('isFullScreen();') as bool; expect(fullScreen, true); - }); + }, + // allowsInlineMediaPlayback has no effect on macOS. + skip: Platform.isMacOS); }); group('Audio playback policy', () { @@ -657,7 +660,10 @@ Future main() async { await controller.runJavaScriptReturningResult('isPaused();') as bool; expect(isPaused, true); }); - }); + }, + // OGG playback is not supported on macOS, so the test data would need + // to be changed to support macOS. + skip: Platform.isMacOS); testWidgets('getTitle', (WidgetTester tester) async { const String getTitleTest = ''' @@ -801,7 +807,10 @@ Future main() async { expect(recordedPosition?.x, X_SCROLL * 2); expect(recordedPosition?.y, Y_SCROLL * 2); }); - }); + }, + // Scroll position is currently not implemented for macOS. + // Flakes on iOS: https://github.com/flutter/flutter/issues/154826 + skip: Platform.isMacOS || Platform.isIOS); group('NavigationDelegate', () { const String blankPage = ''; @@ -821,7 +830,7 @@ Future main() async { unawaited(delegate.setOnPageFinished((_) => pageLoaded.complete())); unawaited( delegate.setOnNavigationRequest((NavigationRequest navigationRequest) { - return (navigationRequest.url.contains('youtube.com')) + return navigationRequest.url.contains('youtube.com') ? NavigationDecision.prevent : NavigationDecision.navigate; }), @@ -1078,7 +1087,7 @@ Future main() async { unawaited(delegate.setOnPageFinished((_) => pageLoaded.complete())); unawaited(delegate .setOnNavigationRequest((NavigationRequest navigationRequest) { - return (navigationRequest.url.contains('youtube.com')) + return navigationRequest.url.contains('youtube.com') ? NavigationDecision.prevent : NavigationDecision.navigate; })); diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Podfile b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Podfile index 5d4484c1e945..bcdae34190c9 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Podfile +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Podfile @@ -32,9 +32,6 @@ target 'Runner' do target 'RunnerTests' do inherit! :search_paths - - # Matches test_spec dependency. - pod 'OCMock', '3.5' end end diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj index 07faa3ad6343..e1dd7698669f 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj @@ -3,13 +3,14 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 60; objects = { /* Begin PBXBuildFile section */ 1096EF442A6BD9DB000CBDF7 /* FWFScrollViewDelegateHostApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1096EF432A6BD9DB000CBDF7 /* FWFScrollViewDelegateHostApiTests.m */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 4047B3FE2C3DEE8500A8BA05 /* OCMock in Frameworks */ = {isa = PBXBuildFile; productRef = 4047B3FD2C3DEE8500A8BA05 /* OCMock */; }; 8F4FF949299ADC2D000A6586 /* FWFWebViewFlutterWKWebViewExternalAPITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F4FF948299ADC2D000A6586 /* FWFWebViewFlutterWKWebViewExternalAPITests.m */; }; 8F4FF94B29AC223F000A6586 /* FWFURLTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F4FF94A29AC223F000A6586 /* FWFURLTests.m */; }; 8F562F902A56C02D00C2BED6 /* FWFURLCredentialHostApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F562F8F2A56C02D00C2BED6 /* FWFURLCredentialHostApiTests.m */; }; @@ -71,7 +72,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 1096EF432A6BD9DB000CBDF7 /* FWFScrollViewDelegateHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFScrollViewDelegateHostApiTests.m; sourceTree = ""; }; + 1096EF432A6BD9DB000CBDF7 /* FWFScrollViewDelegateHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FWFScrollViewDelegateHostApiTests.m; path = ../../darwin/Tests/FWFScrollViewDelegateHostApiTests.m; sourceTree = SOURCE_ROOT; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 17781D9462A1AEA7C99F8E45 /* libPods-RunnerTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RunnerTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -84,26 +85,26 @@ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 8F4FF948299ADC2D000A6586 /* FWFWebViewFlutterWKWebViewExternalAPITests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FWFWebViewFlutterWKWebViewExternalAPITests.m; sourceTree = ""; }; - 8F4FF94A29AC223F000A6586 /* FWFURLTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFURLTests.m; sourceTree = ""; }; - 8F562F8F2A56C02D00C2BED6 /* FWFURLCredentialHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFURLCredentialHostApiTests.m; sourceTree = ""; }; - 8F562F912A56C04F00C2BED6 /* FWFURLProtectionSpaceHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFURLProtectionSpaceHostApiTests.m; sourceTree = ""; }; - 8F562F932A56C07B00C2BED6 /* FWFURLAuthenticationChallengeHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFURLAuthenticationChallengeHostApiTests.m; sourceTree = ""; }; - 8F78EAA92A02CB9100C2E520 /* FWFErrorTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFErrorTests.m; sourceTree = ""; }; - 8FA6A87828062CD000A4B183 /* FWFInstanceManagerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFInstanceManagerTests.m; sourceTree = ""; }; - 8FB79B5228134C3100C101D3 /* FWFWebViewHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFWebViewHostApiTests.m; sourceTree = ""; }; - 8FB79B54281B24F600C101D3 /* FWFDataConvertersTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFDataConvertersTests.m; sourceTree = ""; }; - 8FB79B662820453400C101D3 /* FWFHTTPCookieStoreHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFHTTPCookieStoreHostApiTests.m; sourceTree = ""; }; - 8FB79B6828204E8700C101D3 /* FWFPreferencesHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFPreferencesHostApiTests.m; sourceTree = ""; }; - 8FB79B6A28204EE500C101D3 /* FWFWebsiteDataStoreHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFWebsiteDataStoreHostApiTests.m; sourceTree = ""; }; - 8FB79B6C2820533B00C101D3 /* FWFWebViewConfigurationHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFWebViewConfigurationHostApiTests.m; sourceTree = ""; }; - 8FB79B72282096B500C101D3 /* FWFScriptMessageHandlerHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFScriptMessageHandlerHostApiTests.m; sourceTree = ""; }; - 8FB79B7828209D1300C101D3 /* FWFUserContentControllerHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFUserContentControllerHostApiTests.m; sourceTree = ""; }; - 8FB79B822820A39300C101D3 /* FWFNavigationDelegateHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFNavigationDelegateHostApiTests.m; sourceTree = ""; }; - 8FB79B842820A3A400C101D3 /* FWFUIDelegateHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFUIDelegateHostApiTests.m; sourceTree = ""; }; - 8FB79B8E2820BAB300C101D3 /* FWFScrollViewHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFScrollViewHostApiTests.m; sourceTree = ""; }; - 8FB79B902820BAC700C101D3 /* FWFUIViewHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFUIViewHostApiTests.m; sourceTree = ""; }; - 8FB79B962821985200C101D3 /* FWFObjectHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFObjectHostApiTests.m; sourceTree = ""; }; + 8F4FF948299ADC2D000A6586 /* FWFWebViewFlutterWKWebViewExternalAPITests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FWFWebViewFlutterWKWebViewExternalAPITests.m; path = ../../darwin/Tests/FWFWebViewFlutterWKWebViewExternalAPITests.m; sourceTree = SOURCE_ROOT; }; + 8F4FF94A29AC223F000A6586 /* FWFURLTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FWFURLTests.m; path = ../../darwin/Tests/FWFURLTests.m; sourceTree = SOURCE_ROOT; }; + 8F562F8F2A56C02D00C2BED6 /* FWFURLCredentialHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FWFURLCredentialHostApiTests.m; path = ../../darwin/Tests/FWFURLCredentialHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 8F562F912A56C04F00C2BED6 /* FWFURLProtectionSpaceHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FWFURLProtectionSpaceHostApiTests.m; path = ../../darwin/Tests/FWFURLProtectionSpaceHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 8F562F932A56C07B00C2BED6 /* FWFURLAuthenticationChallengeHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FWFURLAuthenticationChallengeHostApiTests.m; path = ../../darwin/Tests/FWFURLAuthenticationChallengeHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 8F78EAA92A02CB9100C2E520 /* FWFErrorTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FWFErrorTests.m; path = ../../darwin/Tests/FWFErrorTests.m; sourceTree = SOURCE_ROOT; }; + 8FA6A87828062CD000A4B183 /* FWFInstanceManagerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FWFInstanceManagerTests.m; path = ../../darwin/Tests/FWFInstanceManagerTests.m; sourceTree = SOURCE_ROOT; }; + 8FB79B5228134C3100C101D3 /* FWFWebViewHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FWFWebViewHostApiTests.m; path = ../../darwin/Tests/FWFWebViewHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 8FB79B54281B24F600C101D3 /* FWFDataConvertersTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FWFDataConvertersTests.m; path = ../../darwin/Tests/FWFDataConvertersTests.m; sourceTree = SOURCE_ROOT; }; + 8FB79B662820453400C101D3 /* FWFHTTPCookieStoreHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FWFHTTPCookieStoreHostApiTests.m; path = ../../darwin/Tests/FWFHTTPCookieStoreHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 8FB79B6828204E8700C101D3 /* FWFPreferencesHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FWFPreferencesHostApiTests.m; path = ../../darwin/Tests/FWFPreferencesHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 8FB79B6A28204EE500C101D3 /* FWFWebsiteDataStoreHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FWFWebsiteDataStoreHostApiTests.m; path = ../../darwin/Tests/FWFWebsiteDataStoreHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 8FB79B6C2820533B00C101D3 /* FWFWebViewConfigurationHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FWFWebViewConfigurationHostApiTests.m; path = ../../darwin/Tests/FWFWebViewConfigurationHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 8FB79B72282096B500C101D3 /* FWFScriptMessageHandlerHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FWFScriptMessageHandlerHostApiTests.m; path = ../../darwin/Tests/FWFScriptMessageHandlerHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 8FB79B7828209D1300C101D3 /* FWFUserContentControllerHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FWFUserContentControllerHostApiTests.m; path = ../../darwin/Tests/FWFUserContentControllerHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 8FB79B822820A39300C101D3 /* FWFNavigationDelegateHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FWFNavigationDelegateHostApiTests.m; path = ../../darwin/Tests/FWFNavigationDelegateHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 8FB79B842820A3A400C101D3 /* FWFUIDelegateHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FWFUIDelegateHostApiTests.m; path = ../../darwin/Tests/FWFUIDelegateHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 8FB79B8E2820BAB300C101D3 /* FWFScrollViewHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FWFScrollViewHostApiTests.m; path = ../../darwin/Tests/FWFScrollViewHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 8FB79B902820BAC700C101D3 /* FWFUIViewHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FWFUIViewHostApiTests.m; path = ../../darwin/Tests/FWFUIViewHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 8FB79B962821985200C101D3 /* FWFObjectHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FWFObjectHostApiTests.m; path = ../../darwin/Tests/FWFObjectHostApiTests.m; sourceTree = SOURCE_ROOT; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -124,6 +125,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 4047B3FE2C3DEE8500A8BA05 /* OCMock in Frameworks */, D7587C3652F6906210B3AE88 /* libPods-RunnerTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -280,6 +282,9 @@ 68BDCAEF23C3F7CB00D9C032 /* PBXTargetDependency */, ); name = RunnerTests; + packageProductDependencies = ( + 4047B3FD2C3DEE8500A8BA05 /* OCMock */, + ); productName = webview_flutter_exampleTests; productReference = 68BDCAE923C3F7CB00D9C032 /* RunnerTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; @@ -358,6 +363,9 @@ Base, ); mainGroup = 97C146E51CF9000F007C117D; + packageReferences = ( + 4047B3FC2C3DEE8500A8BA05 /* XCRemoteSwiftPackageReference "ocmock" */, + ); productRefGroup = 97C146EF1CF9000F007C117D /* Products */; projectDirPath = ""; projectRoot = ""; @@ -421,10 +429,12 @@ ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/path_provider_foundation/path_provider_foundation_privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/webview_flutter_wkwebview/webview_flutter_wkwebview_privacy.bundle", ); name = "[CP] Copy Pods Resources"; outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/path_provider_foundation_privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/webview_flutter_wkwebview_privacy.bundle", ); runOnlyForDeploymentPostprocessing = 0; @@ -845,6 +855,25 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 4047B3FC2C3DEE8500A8BA05 /* XCRemoteSwiftPackageReference "ocmock" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/erikdoe/ocmock"; + requirement = { + kind = revision; + revision = fe1661a3efed11831a6452f4b1a0c5e6ddc08c3d; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 4047B3FD2C3DEE8500A8BA05 /* OCMock */ = { + isa = XCSwiftPackageProductDependency; + package = 4047B3FC2C3DEE8500A8BA05 /* XCRemoteSwiftPackageReference "ocmock" */; + productName = OCMock; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 97C146E61CF9000F007C117D /* Project object */; } diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index eb87ae849c45..65b8955c3c62 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -5,6 +5,24 @@ + + + + + + + + + + - - - - - - -

Click the following button to see the effect

-
+ alert(inputString); + } + + + + +

Click the following button to see the effect

+ - - -
- - + + + + + '''; class WebViewExample extends StatefulWidget { @@ -160,7 +160,6 @@ class _WebViewExampleState extends State { WebKitWebViewControllerCreationParams(allowsInlineMediaPlayback: true), ) ..setJavaScriptMode(JavaScriptMode.unrestricted) - ..setBackgroundColor(const Color(0x80000000)) ..setPlatformNavigationDelegate( PlatformNavigationDelegate( const PlatformNavigationDelegateCreationParams(), @@ -220,12 +219,19 @@ Page resource error: ) ..loadRequest(LoadRequestParams( uri: Uri.parse('https://flutter.dev'), - )) - ..setOnScrollPositionChange((ScrollPositionChange scrollPositionChange) { + )); + + // setBackgroundColor and setOnScrollPositionChange are not supported on + // macOS. + if (Platform.isIOS) { + _controller.setBackgroundColor(const Color(0x80000000)); + _controller.setOnScrollPositionChange( + (ScrollPositionChange scrollPositionChange) { debugPrint( 'Scroll position change to x = ${scrollPositionChange.x}, y = ${scrollPositionChange.y}', ); }); + } } @override diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/.gitignore b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/.gitignore new file mode 100644 index 000000000000..746adbb6b9e1 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/.gitignore @@ -0,0 +1,7 @@ +# Flutter-related +**/Flutter/ephemeral/ +**/Pods/ + +# Xcode-related +**/dgph +**/xcuserdata/ diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Flutter/Flutter-Debug.xcconfig b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Flutter/Flutter-Debug.xcconfig new file mode 100644 index 000000000000..4b81f9b2d200 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Flutter/Flutter-Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Flutter/Flutter-Release.xcconfig b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Flutter/Flutter-Release.xcconfig new file mode 100644 index 000000000000..5caa9d1579e4 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Flutter/Flutter-Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Podfile b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Podfile new file mode 100644 index 000000000000..29c8eb3294cb --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Podfile @@ -0,0 +1,42 @@ +platform :osx, '10.14' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_macos_podfile_setup + +target 'Runner' do + use_frameworks! + + flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) + target 'RunnerTests' do + inherit! :search_paths + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_macos_build_settings(target) + end +end diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner.xcodeproj/project.pbxproj b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner.xcodeproj/project.pbxproj new file mode 100644 index 000000000000..264cd2e6145f --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,902 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXAggregateTarget section */ + 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; + buildPhases = ( + 33CC111E2044C6BF0003C045 /* ShellScript */, + ); + dependencies = ( + ); + name = "Flutter Assemble"; + productName = FLX; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; + 337257E82C626C94005E6518 /* OCMock in Frameworks */ = {isa = PBXBuildFile; productRef = 337257E72C626C94005E6518 /* OCMock */; }; + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + 33CF716F2C090A5900FB3AA4 /* FWFURLProtectionSpaceHostApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33CF715A2C090A5800FB3AA4 /* FWFURLProtectionSpaceHostApiTests.m */; }; + 33CF71702C090A5900FB3AA4 /* FWFUIDelegateHostApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33CF715B2C090A5800FB3AA4 /* FWFUIDelegateHostApiTests.m */; }; + 33CF71712C090A5900FB3AA4 /* FWFErrorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33CF715C2C090A5800FB3AA4 /* FWFErrorTests.m */; }; + 33CF71722C090A5900FB3AA4 /* FWFUIViewHostApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33CF715D2C090A5800FB3AA4 /* FWFUIViewHostApiTests.m */; }; + 33CF71732C090A5900FB3AA4 /* FWFDataConvertersTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33CF715E2C090A5800FB3AA4 /* FWFDataConvertersTests.m */; }; + 33CF71742C090A5900FB3AA4 /* FWFURLCredentialHostApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33CF715F2C090A5800FB3AA4 /* FWFURLCredentialHostApiTests.m */; }; + 33CF71752C090A5900FB3AA4 /* FWFWebViewFlutterWKWebViewExternalAPITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33CF71602C090A5800FB3AA4 /* FWFWebViewFlutterWKWebViewExternalAPITests.m */; }; + 33CF71762C090A5900FB3AA4 /* FWFPreferencesHostApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33CF71612C090A5800FB3AA4 /* FWFPreferencesHostApiTests.m */; }; + 33CF71772C090A5900FB3AA4 /* FWFWebViewHostApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33CF71622C090A5800FB3AA4 /* FWFWebViewHostApiTests.m */; }; + 33CF71782C090A5900FB3AA4 /* FWFScrollViewHostApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33CF71632C090A5800FB3AA4 /* FWFScrollViewHostApiTests.m */; }; + 33CF71792C090A5900FB3AA4 /* FWFInstanceManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33CF71642C090A5800FB3AA4 /* FWFInstanceManagerTests.m */; }; + 33CF717A2C090A5900FB3AA4 /* FWFScrollViewDelegateHostApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33CF71652C090A5800FB3AA4 /* FWFScrollViewDelegateHostApiTests.m */; }; + 33CF717B2C090A5900FB3AA4 /* FWFUserContentControllerHostApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33CF71662C090A5800FB3AA4 /* FWFUserContentControllerHostApiTests.m */; }; + 33CF717C2C090A5900FB3AA4 /* FWFScriptMessageHandlerHostApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33CF71672C090A5800FB3AA4 /* FWFScriptMessageHandlerHostApiTests.m */; }; + 33CF717D2C090A5900FB3AA4 /* FWFURLAuthenticationChallengeHostApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33CF71682C090A5800FB3AA4 /* FWFURLAuthenticationChallengeHostApiTests.m */; }; + 33CF717E2C090A5900FB3AA4 /* FWFURLTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33CF71692C090A5800FB3AA4 /* FWFURLTests.m */; }; + 33CF717F2C090A5900FB3AA4 /* FWFWebViewConfigurationHostApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33CF716A2C090A5900FB3AA4 /* FWFWebViewConfigurationHostApiTests.m */; }; + 33CF71802C090A5900FB3AA4 /* FWFWebsiteDataStoreHostApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33CF716B2C090A5900FB3AA4 /* FWFWebsiteDataStoreHostApiTests.m */; }; + 33CF71812C090A5900FB3AA4 /* FWFHTTPCookieStoreHostApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33CF716C2C090A5900FB3AA4 /* FWFHTTPCookieStoreHostApiTests.m */; }; + 33CF71822C090A5900FB3AA4 /* FWFNavigationDelegateHostApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33CF716D2C090A5900FB3AA4 /* FWFNavigationDelegateHostApiTests.m */; }; + 33CF71832C090A5900FB3AA4 /* FWFObjectHostApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33CF716E2C090A5900FB3AA4 /* FWFObjectHostApiTests.m */; }; + 696987BFFD9F58717569B4E4 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2F0D686780FFBF662B127EB3 /* Pods_RunnerTests.framework */; }; + 94A776FC184B2E22F5BB8688 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4396B0510D22FC1052724D77 /* Pods_Runner.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC10EC2044A3C60003C045; + remoteInfo = Runner; + }; + 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC111A2044C6BA0003C045; + remoteInfo = FLX; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 33CC110E2044A8840003C045 /* Bundle Framework */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Bundle Framework"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 293218A8CB10C8BE4DB72BF6 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 2BB8CCF4A3B17FE9A00CF6B7 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 2F0D686780FFBF662B127EB3 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; + 33CC10ED2044A3C60003C045 /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; + 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; + 33CF715A2C090A5800FB3AA4 /* FWFURLProtectionSpaceHostApiTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FWFURLProtectionSpaceHostApiTests.m; path = ../../darwin/Tests/FWFURLProtectionSpaceHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 33CF715B2C090A5800FB3AA4 /* FWFUIDelegateHostApiTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FWFUIDelegateHostApiTests.m; path = ../../darwin/Tests/FWFUIDelegateHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 33CF715C2C090A5800FB3AA4 /* FWFErrorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FWFErrorTests.m; path = ../../darwin/Tests/FWFErrorTests.m; sourceTree = SOURCE_ROOT; }; + 33CF715D2C090A5800FB3AA4 /* FWFUIViewHostApiTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FWFUIViewHostApiTests.m; path = ../../darwin/Tests/FWFUIViewHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 33CF715E2C090A5800FB3AA4 /* FWFDataConvertersTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FWFDataConvertersTests.m; path = ../../darwin/Tests/FWFDataConvertersTests.m; sourceTree = SOURCE_ROOT; }; + 33CF715F2C090A5800FB3AA4 /* FWFURLCredentialHostApiTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FWFURLCredentialHostApiTests.m; path = ../../darwin/Tests/FWFURLCredentialHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 33CF71602C090A5800FB3AA4 /* FWFWebViewFlutterWKWebViewExternalAPITests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FWFWebViewFlutterWKWebViewExternalAPITests.m; path = ../../darwin/Tests/FWFWebViewFlutterWKWebViewExternalAPITests.m; sourceTree = SOURCE_ROOT; }; + 33CF71612C090A5800FB3AA4 /* FWFPreferencesHostApiTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FWFPreferencesHostApiTests.m; path = ../../darwin/Tests/FWFPreferencesHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 33CF71622C090A5800FB3AA4 /* FWFWebViewHostApiTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FWFWebViewHostApiTests.m; path = ../../darwin/Tests/FWFWebViewHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 33CF71632C090A5800FB3AA4 /* FWFScrollViewHostApiTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FWFScrollViewHostApiTests.m; path = ../../darwin/Tests/FWFScrollViewHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 33CF71642C090A5800FB3AA4 /* FWFInstanceManagerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FWFInstanceManagerTests.m; path = ../../darwin/Tests/FWFInstanceManagerTests.m; sourceTree = SOURCE_ROOT; }; + 33CF71652C090A5800FB3AA4 /* FWFScrollViewDelegateHostApiTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FWFScrollViewDelegateHostApiTests.m; path = ../../darwin/Tests/FWFScrollViewDelegateHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 33CF71662C090A5800FB3AA4 /* FWFUserContentControllerHostApiTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FWFUserContentControllerHostApiTests.m; path = ../../darwin/Tests/FWFUserContentControllerHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 33CF71672C090A5800FB3AA4 /* FWFScriptMessageHandlerHostApiTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FWFScriptMessageHandlerHostApiTests.m; path = ../../darwin/Tests/FWFScriptMessageHandlerHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 33CF71682C090A5800FB3AA4 /* FWFURLAuthenticationChallengeHostApiTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FWFURLAuthenticationChallengeHostApiTests.m; path = ../../darwin/Tests/FWFURLAuthenticationChallengeHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 33CF71692C090A5800FB3AA4 /* FWFURLTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FWFURLTests.m; path = ../../darwin/Tests/FWFURLTests.m; sourceTree = SOURCE_ROOT; }; + 33CF716A2C090A5900FB3AA4 /* FWFWebViewConfigurationHostApiTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FWFWebViewConfigurationHostApiTests.m; path = ../../darwin/Tests/FWFWebViewConfigurationHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 33CF716B2C090A5900FB3AA4 /* FWFWebsiteDataStoreHostApiTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FWFWebsiteDataStoreHostApiTests.m; path = ../../darwin/Tests/FWFWebsiteDataStoreHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 33CF716C2C090A5900FB3AA4 /* FWFHTTPCookieStoreHostApiTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FWFHTTPCookieStoreHostApiTests.m; path = ../../darwin/Tests/FWFHTTPCookieStoreHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 33CF716D2C090A5900FB3AA4 /* FWFNavigationDelegateHostApiTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FWFNavigationDelegateHostApiTests.m; path = ../../darwin/Tests/FWFNavigationDelegateHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 33CF716E2C090A5900FB3AA4 /* FWFObjectHostApiTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FWFObjectHostApiTests.m; path = ../../darwin/Tests/FWFObjectHostApiTests.m; sourceTree = SOURCE_ROOT; }; + 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; + 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; + 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 4396B0510D22FC1052724D77 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7A8789C38AC8A7893DF1757D /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 8E3B7819B86A3E8D5B2787F8 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + B29CEB47BBE7D438B12895F3 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; + BB0A609D94A71B55CFCFC007 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 331C80D2294CF70F00263BE5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 337257E82C626C94005E6518 /* OCMock in Frameworks */, + 696987BFFD9F58717569B4E4 /* Pods_RunnerTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10EA2044A3C60003C045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 94A776FC184B2E22F5BB8688 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 331C80D6294CF71000263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 33CF715E2C090A5800FB3AA4 /* FWFDataConvertersTests.m */, + 33CF715C2C090A5800FB3AA4 /* FWFErrorTests.m */, + 33CF716C2C090A5900FB3AA4 /* FWFHTTPCookieStoreHostApiTests.m */, + 33CF71642C090A5800FB3AA4 /* FWFInstanceManagerTests.m */, + 33CF716D2C090A5900FB3AA4 /* FWFNavigationDelegateHostApiTests.m */, + 33CF716E2C090A5900FB3AA4 /* FWFObjectHostApiTests.m */, + 33CF71612C090A5800FB3AA4 /* FWFPreferencesHostApiTests.m */, + 33CF71672C090A5800FB3AA4 /* FWFScriptMessageHandlerHostApiTests.m */, + 33CF71652C090A5800FB3AA4 /* FWFScrollViewDelegateHostApiTests.m */, + 33CF71632C090A5800FB3AA4 /* FWFScrollViewHostApiTests.m */, + 33CF715B2C090A5800FB3AA4 /* FWFUIDelegateHostApiTests.m */, + 33CF715D2C090A5800FB3AA4 /* FWFUIViewHostApiTests.m */, + 33CF71682C090A5800FB3AA4 /* FWFURLAuthenticationChallengeHostApiTests.m */, + 33CF715F2C090A5800FB3AA4 /* FWFURLCredentialHostApiTests.m */, + 33CF715A2C090A5800FB3AA4 /* FWFURLProtectionSpaceHostApiTests.m */, + 33CF71692C090A5800FB3AA4 /* FWFURLTests.m */, + 33CF71662C090A5800FB3AA4 /* FWFUserContentControllerHostApiTests.m */, + 33CF716B2C090A5900FB3AA4 /* FWFWebsiteDataStoreHostApiTests.m */, + 33CF716A2C090A5900FB3AA4 /* FWFWebViewConfigurationHostApiTests.m */, + 33CF71602C090A5800FB3AA4 /* FWFWebViewFlutterWKWebViewExternalAPITests.m */, + 33CF71622C090A5800FB3AA4 /* FWFWebViewHostApiTests.m */, + ); + path = RunnerTests; + sourceTree = ""; + }; + 33BA886A226E78AF003329D5 /* Configs */ = { + isa = PBXGroup; + children = ( + 33E5194F232828860026EE4D /* AppInfo.xcconfig */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, + ); + path = Configs; + sourceTree = ""; + }; + 33CC10E42044A3C60003C045 = { + isa = PBXGroup; + children = ( + 33FAB671232836740065AC1E /* Runner */, + 33CEB47122A05771004F2AC0 /* Flutter */, + 331C80D6294CF71000263BE5 /* RunnerTests */, + 33CC10EE2044A3C60003C045 /* Products */, + D73912EC22F37F3D000D13A0 /* Frameworks */, + 57E0600E4AC0FCC05F33A596 /* Pods */, + ); + sourceTree = ""; + }; + 33CC10EE2044A3C60003C045 /* Products */ = { + isa = PBXGroup; + children = ( + 33CC10ED2044A3C60003C045 /* example.app */, + 331C80D5294CF71000263BE5 /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 33CC11242044D66E0003C045 /* Resources */ = { + isa = PBXGroup; + children = ( + 33CC10F22044A3C60003C045 /* Assets.xcassets */, + 33CC10F42044A3C60003C045 /* MainMenu.xib */, + 33CC10F72044A3C60003C045 /* Info.plist */, + ); + name = Resources; + path = ..; + sourceTree = ""; + }; + 33CEB47122A05771004F2AC0 /* Flutter */ = { + isa = PBXGroup; + children = ( + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, + ); + path = Flutter; + sourceTree = ""; + }; + 33FAB671232836740065AC1E /* Runner */ = { + isa = PBXGroup; + children = ( + 33CC10F02044A3C60003C045 /* AppDelegate.swift */, + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, + 33E51913231747F40026EE4D /* DebugProfile.entitlements */, + 33E51914231749380026EE4D /* Release.entitlements */, + 33CC11242044D66E0003C045 /* Resources */, + 33BA886A226E78AF003329D5 /* Configs */, + ); + path = Runner; + sourceTree = ""; + }; + 57E0600E4AC0FCC05F33A596 /* Pods */ = { + isa = PBXGroup; + children = ( + 7A8789C38AC8A7893DF1757D /* Pods-Runner.debug.xcconfig */, + 293218A8CB10C8BE4DB72BF6 /* Pods-Runner.release.xcconfig */, + 2BB8CCF4A3B17FE9A00CF6B7 /* Pods-Runner.profile.xcconfig */, + BB0A609D94A71B55CFCFC007 /* Pods-RunnerTests.debug.xcconfig */, + 8E3B7819B86A3E8D5B2787F8 /* Pods-RunnerTests.release.xcconfig */, + B29CEB47BBE7D438B12895F3 /* Pods-RunnerTests.profile.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + D73912EC22F37F3D000D13A0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 4396B0510D22FC1052724D77 /* Pods_Runner.framework */, + 2F0D686780FFBF662B127EB3 /* Pods_RunnerTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 331C80D4294CF70F00263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + 5B369AB3CC6C4456A15F9A02 /* [CP] Check Pods Manifest.lock */, + 331C80D1294CF70F00263BE5 /* Sources */, + 331C80D2294CF70F00263BE5 /* Frameworks */, + 331C80D3294CF70F00263BE5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 331C80DA294CF71000263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + packageProductDependencies = ( + 337257E72C626C94005E6518 /* OCMock */, + ); + productName = RunnerTests; + productReference = 331C80D5294CF71000263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 33CC10EC2044A3C60003C045 /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 52BDF375441D3D4ACF9978EC /* [CP] Check Pods Manifest.lock */, + 33CC10E92044A3C60003C045 /* Sources */, + 33CC10EA2044A3C60003C045 /* Frameworks */, + 33CC10EB2044A3C60003C045 /* Resources */, + 33CC110E2044A8840003C045 /* Bundle Framework */, + 3399D490228B24CF009A79C7 /* ShellScript */, + AE091060DB78993007C49A9B /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 33CC11202044C79F0003C045 /* PBXTargetDependency */, + ); + name = Runner; + productName = Runner; + productReference = 33CC10ED2044A3C60003C045 /* example.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 33CC10E52044A3C60003C045 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 331C80D4294CF70F00263BE5 = { + CreatedOnToolsVersion = 14.0; + LastSwiftMigration = 1510; + TestTargetID = 33CC10EC2044A3C60003C045; + }; + 33CC10EC2044A3C60003C045 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1100; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 1; + }; + }; + }; + 33CC111A2044C6BA0003C045 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Manual; + }; + }; + }; + buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 33CC10E42044A3C60003C045; + packageReferences = ( + 337257E62C626C94005E6518 /* XCRemoteSwiftPackageReference "ocmock" */, + ); + productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 33CC10EC2044A3C60003C045 /* Runner */, + 331C80D4294CF70F00263BE5 /* RunnerTests */, + 33CC111A2044C6BA0003C045 /* Flutter Assemble */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 331C80D3294CF70F00263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10EB2044A3C60003C045 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3399D490228B24CF009A79C7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; + }; + 33CC111E2044C6BF0003C045 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + Flutter/ephemeral/FlutterInputs.xcfilelist, + ); + inputPaths = ( + Flutter/ephemeral/tripwire, + ); + outputFileListPaths = ( + Flutter/ephemeral/FlutterOutputs.xcfilelist, + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; + }; + 52BDF375441D3D4ACF9978EC /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 5B369AB3CC6C4456A15F9A02 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + AE091060DB78993007C49A9B /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 331C80D1294CF70F00263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CF71822C090A5900FB3AA4 /* FWFNavigationDelegateHostApiTests.m in Sources */, + 33CF71832C090A5900FB3AA4 /* FWFObjectHostApiTests.m in Sources */, + 33CF71762C090A5900FB3AA4 /* FWFPreferencesHostApiTests.m in Sources */, + 33CF717E2C090A5900FB3AA4 /* FWFURLTests.m in Sources */, + 33CF71702C090A5900FB3AA4 /* FWFUIDelegateHostApiTests.m in Sources */, + 33CF717C2C090A5900FB3AA4 /* FWFScriptMessageHandlerHostApiTests.m in Sources */, + 33CF716F2C090A5900FB3AA4 /* FWFURLProtectionSpaceHostApiTests.m in Sources */, + 33CF717A2C090A5900FB3AA4 /* FWFScrollViewDelegateHostApiTests.m in Sources */, + 33CF71782C090A5900FB3AA4 /* FWFScrollViewHostApiTests.m in Sources */, + 33CF71712C090A5900FB3AA4 /* FWFErrorTests.m in Sources */, + 33CF71812C090A5900FB3AA4 /* FWFHTTPCookieStoreHostApiTests.m in Sources */, + 33CF717F2C090A5900FB3AA4 /* FWFWebViewConfigurationHostApiTests.m in Sources */, + 33CF717B2C090A5900FB3AA4 /* FWFUserContentControllerHostApiTests.m in Sources */, + 33CF71802C090A5900FB3AA4 /* FWFWebsiteDataStoreHostApiTests.m in Sources */, + 33CF71752C090A5900FB3AA4 /* FWFWebViewFlutterWKWebViewExternalAPITests.m in Sources */, + 33CF717D2C090A5900FB3AA4 /* FWFURLAuthenticationChallengeHostApiTests.m in Sources */, + 33CF71772C090A5900FB3AA4 /* FWFWebViewHostApiTests.m in Sources */, + 33CF71742C090A5900FB3AA4 /* FWFURLCredentialHostApiTests.m in Sources */, + 33CF71732C090A5900FB3AA4 /* FWFDataConvertersTests.m in Sources */, + 33CF71792C090A5900FB3AA4 /* FWFInstanceManagerTests.m in Sources */, + 33CF71722C090A5900FB3AA4 /* FWFUIViewHostApiTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10E92044A3C60003C045 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 331C80DA294CF71000263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC10EC2044A3C60003C045 /* Runner */; + targetProxy = 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */; + }; + 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; + targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 33CC10F52044A3C60003C045 /* Base */, + ); + name = MainMenu.xib; + path = Runner; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 331C80DB294CF71000263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BB0A609D94A71B55CFCFC007 /* Pods-RunnerTests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.example.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/example.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/example"; + }; + name = Debug; + }; + 331C80DC294CF71000263BE5 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8E3B7819B86A3E8D5B2787F8 /* Pods-RunnerTests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.example.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/example.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/example"; + }; + name = Release; + }; + 331C80DD294CF71000263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B29CEB47BBE7D438B12895F3 /* Pods-RunnerTests.profile.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.example.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/example.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/example"; + }; + name = Profile; + }; + 338D0CE9231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.14; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Profile; + }; + 338D0CEA231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Profile; + }; + 338D0CEB231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Profile; + }; + 33CC10F92044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.14; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 33CC10FA2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.14; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 33CC10FC2044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 33CC10FD2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 33CC111C2044C6BA0003C045 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 33CC111D2044C6BA0003C045 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C80DB294CF71000263BE5 /* Debug */, + 331C80DC294CF71000263BE5 /* Release */, + 331C80DD294CF71000263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10F92044A3C60003C045 /* Debug */, + 33CC10FA2044A3C60003C045 /* Release */, + 338D0CE9231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10FC2044A3C60003C045 /* Debug */, + 33CC10FD2044A3C60003C045 /* Release */, + 338D0CEA231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC111C2044C6BA0003C045 /* Debug */, + 33CC111D2044C6BA0003C045 /* Release */, + 338D0CEB231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 337257E62C626C94005E6518 /* XCRemoteSwiftPackageReference "ocmock" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/erikdoe/ocmock"; + requirement = { + kind = revision; + revision = fe1661a3efed11831a6452f4b1a0c5e6ddc08c3d; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 337257E72C626C94005E6518 /* OCMock */ = { + isa = XCSwiftPackageProductDependency; + package = 337257E62C626C94005E6518 /* XCRemoteSwiftPackageReference "ocmock" */; + productName = OCMock; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = 33CC10E52044A3C60003C045 /* Project object */; +} diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000000..18d981003d68 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 000000000000..be6977d7622f --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000000..21a3cc14c74e --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000000..18d981003d68 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/AppDelegate.swift b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/AppDelegate.swift new file mode 100644 index 000000000000..689c0ecd5254 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/AppDelegate.swift @@ -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 Cocoa +import FlutterMacOS + +@main +class AppDelegate: FlutterAppDelegate { + override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } +} diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000000..a2ec33f19f11 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_16.png", + "scale" : "1x" + }, + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "2x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "1x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_64.png", + "scale" : "2x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_128.png", + "scale" : "1x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "2x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_1024.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png new file mode 100644 index 000000000000..82b6f9d9a33e Binary files /dev/null and b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png new file mode 100644 index 000000000000..13b35eba55c6 Binary files /dev/null and b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png new file mode 100644 index 000000000000..0a3f5fa40fb3 Binary files /dev/null and b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png new file mode 100644 index 000000000000..bdb57226d5f2 Binary files /dev/null and b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png new file mode 100644 index 000000000000..f083318e09ca Binary files /dev/null and b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png new file mode 100644 index 000000000000..326c0e72c9d8 Binary files /dev/null and b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png new file mode 100644 index 000000000000..2f1632cfddf3 Binary files /dev/null and b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Base.lproj/MainMenu.xib b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Base.lproj/MainMenu.xib new file mode 100644 index 000000000000..80e867a4e06b --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Base.lproj/MainMenu.xib @@ -0,0 +1,343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Configs/AppInfo.xcconfig b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 000000000000..e957f60d65b7 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Configs/AppInfo.xcconfig @@ -0,0 +1,14 @@ +// Application-level settings for the Runner target. +// +// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the +// future. If not, the values below would default to using the project name when this becomes a +// 'flutter create' template. + +// The application's name. By default this is also the title of the Flutter window. +PRODUCT_NAME = example + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.example + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2023 dev.flutter.plugins. All rights reserved. diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Configs/Debug.xcconfig b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 000000000000..36b0fd9464f4 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Configs/Release.xcconfig b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 000000000000..dff4f49561c8 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Configs/Warnings.xcconfig b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 000000000000..42bcbf4780b1 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Configs/Warnings.xcconfig @@ -0,0 +1,13 @@ +WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings +GCC_WARN_UNDECLARED_SELECTOR = YES +CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES +CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_PRAGMA_PACK = YES +CLANG_WARN_STRICT_PROTOTYPES = YES +CLANG_WARN_COMMA = YES +GCC_WARN_STRICT_SELECTOR_MATCH = YES +CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES +GCC_WARN_SHADOW = YES +CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/DebugProfile.entitlements b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/DebugProfile.entitlements new file mode 100644 index 000000000000..08c3ab17cc26 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,14 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.cs.allow-jit + + com.apple.security.network.server + + com.apple.security.network.client + + + diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Info.plist b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Info.plist new file mode 100644 index 000000000000..4789daa6a443 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + $(PRODUCT_COPYRIGHT) + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/MainFlutterWindow.swift b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 000000000000..f21908966e95 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,19 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + + super.awakeFromNib() + } +} diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Release.entitlements b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Release.entitlements new file mode 100644 index 000000000000..ee95ab7e582d --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/macos/Runner/Release.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.network.client + + + diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/pubspec.yaml b/packages/webview_flutter/webview_flutter_wkwebview/example/pubspec.yaml index d7f3d8ea3ae0..2212808e098e 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.2.3 - flutter: ">=3.16.6" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Assets/.gitkeep b/packages/webview_flutter/webview_flutter_wkwebview/ios/Assets/.gitkeep deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/webview-umbrella.h b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/webview-umbrella.h deleted file mode 100644 index 726b20c5ffa0..000000000000 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/webview-umbrella.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import - -#import "FLTWebViewFlutterPlugin.h" -#import "FWFDataConverters.h" -#import "FWFGeneratedWebKitApis.h" -#import "FWFHTTPCookieStoreHostApi.h" -#import "FWFInstanceManager.h" -#import "FWFNavigationDelegateHostApi.h" -#import "FWFObjectHostApi.h" -#import "FWFPreferencesHostApi.h" -#import "FWFScriptMessageHandlerHostApi.h" -#import "FWFScrollViewDelegateHostApi.h" -#import "FWFScrollViewHostApi.h" -#import "FWFUIDelegateHostApi.h" -#import "FWFUIViewHostApi.h" -#import "FWFURLAuthenticationChallengeHostApi.h" -#import "FWFURLCredentialHostApi.h" -#import "FWFURLHostApi.h" -#import "FWFURLProtectionSpaceHostApi.h" -#import "FWFUserContentControllerHostApi.h" -#import "FWFWebViewConfigurationHostApi.h" -#import "FWFWebViewFlutterWKWebViewExternalAPI.h" -#import "FWFWebViewHostApi.h" -#import "FWFWebsiteDataStoreHostApi.h" diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/common/weak_reference_utils.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/common/weak_reference_utils.dart index fc247f8b60f7..f12485ad6e71 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/common/weak_reference_utils.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/common/weak_reference_utils.dart @@ -5,7 +5,7 @@ /// Helper method for creating callbacks methods with a weak reference. /// /// Example: -/// ``` +/// ```dart /// final JavascriptChannelRegistry javascriptChannelRegistry = ... /// /// final WKScriptMessageHandler handler = WKScriptMessageHandler( diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/common/web_kit.g.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/common/web_kit.g.dart index 65f55dbbe3ff..bd0ac2c02945 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/common/web_kit.g.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/common/web_kit.g.dart @@ -1,9 +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 (v13.0.0), do not edit directly. +// Autogenerated from Pigeon (v18.0.0), 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 +// 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 import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; @@ -11,6 +11,13 @@ import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; import 'package:flutter/services.dart'; +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); +} + List wrapResponse( {Object? result, PlatformException? error, bool empty = false}) { if (empty) { @@ -859,54 +866,61 @@ class WKWebsiteDataStoreHostApi { /// Constructor for [WKWebsiteDataStoreHostApi]. 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. - WKWebsiteDataStoreHostApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; + WKWebsiteDataStoreHostApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : __pigeon_binaryMessenger = binaryMessenger, + __pigeon_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? __pigeon_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = + _WKWebsiteDataStoreHostApiCodec(); - static const MessageCodec codec = _WKWebsiteDataStoreHostApiCodec(); + final String __pigeon_messageChannelSuffix; Future createFromWebViewConfiguration( - int arg_identifier, int arg_configurationIdentifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebsiteDataStoreHostApi.createFromWebViewConfiguration', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_configurationIdentifier]) - as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + int identifier, int configurationIdentifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebsiteDataStoreHostApi.createFromWebViewConfiguration$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, configurationIdentifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; } } - Future createDefaultDataStore(int arg_identifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebsiteDataStoreHostApi.createDefaultDataStore', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future createDefaultDataStore(int identifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebsiteDataStoreHostApi.createDefaultDataStore$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([identifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; @@ -914,36 +928,38 @@ class WKWebsiteDataStoreHostApi { } Future removeDataOfTypes( - int arg_identifier, - List arg_dataTypes, - double arg_modificationTimeInSecondsSinceEpoch) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebsiteDataStoreHostApi.removeDataOfTypes', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send([ - arg_identifier, - arg_dataTypes, - arg_modificationTimeInSecondsSinceEpoch + int identifier, + List dataTypes, + double modificationTimeInSecondsSinceEpoch) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebsiteDataStoreHostApi.removeDataOfTypes$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([ + identifier, + dataTypes, + modificationTimeInSecondsSinceEpoch ]) as List?; - if (replyList == null) { + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else if (replyList[0] == null) { + } else if (__pigeon_replyList[0] == null) { throw PlatformException( code: 'null-error', message: 'Host platform returned null value for non-null return value.', ); } else { - return (replyList[0] as bool?)!; + return (__pigeon_replyList[0] as bool?)!; } } } @@ -955,52 +971,60 @@ class UIViewHostApi { /// Constructor for [UIViewHostApi]. 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. - UIViewHostApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; - - static const MessageCodec codec = StandardMessageCodec(); - - Future setBackgroundColor(int arg_identifier, int? arg_value) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.UIViewHostApi.setBackgroundColor', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_value]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + UIViewHostApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : __pigeon_binaryMessenger = binaryMessenger, + __pigeon_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? __pigeon_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); + + final String __pigeon_messageChannelSuffix; + + Future setBackgroundColor(int identifier, int? value) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.UIViewHostApi.setBackgroundColor$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, value]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; } } - Future setOpaque(int arg_identifier, bool arg_opaque) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.UIViewHostApi.setOpaque', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_opaque]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future setOpaque(int identifier, bool opaque) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.UIViewHostApi.setOpaque$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, opaque]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; @@ -1015,106 +1039,113 @@ class UIScrollViewHostApi { /// Constructor for [UIScrollViewHostApi]. 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. - UIScrollViewHostApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; - - static const MessageCodec codec = StandardMessageCodec(); - - Future createFromWebView( - int arg_identifier, int arg_webViewIdentifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.createFromWebView', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier, arg_webViewIdentifier]) - as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + UIScrollViewHostApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : __pigeon_binaryMessenger = binaryMessenger, + __pigeon_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? __pigeon_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); + + final String __pigeon_messageChannelSuffix; + + Future createFromWebView(int identifier, int webViewIdentifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.createFromWebView$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, webViewIdentifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; } } - Future> getContentOffset(int arg_identifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.getContentOffset', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future> getContentOffset(int identifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.getContentOffset$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([identifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); - } else if (replyList[0] == null) { + } else if (__pigeon_replyList[0] == null) { throw PlatformException( code: 'null-error', message: 'Host platform returned null value for non-null return value.', ); } else { - return (replyList[0] as List?)!.cast(); + return (__pigeon_replyList[0] as List?)!.cast(); } } - Future scrollBy(int arg_identifier, double arg_x, double arg_y) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.scrollBy', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_x, arg_y]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future scrollBy(int identifier, double x, double y) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.scrollBy$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, x, y]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; } } - Future setContentOffset( - int arg_identifier, double arg_x, double arg_y) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.setContentOffset', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_x, arg_y]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future setContentOffset(int identifier, double x, double y) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.setContentOffset$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, x, y]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; @@ -1122,24 +1153,25 @@ class UIScrollViewHostApi { } Future setDelegate( - int arg_identifier, int? arg_uiScrollViewDelegateIdentifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.setDelegate', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_uiScrollViewDelegateIdentifier]) + int identifier, int? uiScrollViewDelegateIdentifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.setDelegate$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, uiScrollViewDelegateIdentifier]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; @@ -1177,79 +1209,84 @@ class WKWebViewConfigurationHostApi { /// Constructor for [WKWebViewConfigurationHostApi]. 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. - WKWebViewConfigurationHostApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; - - static const MessageCodec codec = + WKWebViewConfigurationHostApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : __pigeon_binaryMessenger = binaryMessenger, + __pigeon_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? __pigeon_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _WKWebViewConfigurationHostApiCodec(); - Future create(int arg_identifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.create', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + final String __pigeon_messageChannelSuffix; + + Future create(int identifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.create$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([identifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; } } - Future createFromWebView( - int arg_identifier, int arg_webViewIdentifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.createFromWebView', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier, arg_webViewIdentifier]) - as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future createFromWebView(int identifier, int webViewIdentifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.createFromWebView$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, webViewIdentifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; } } - Future setAllowsInlineMediaPlayback( - int arg_identifier, bool arg_allow) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.setAllowsInlineMediaPlayback', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_allow]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future setAllowsInlineMediaPlayback(int identifier, bool allow) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.setAllowsInlineMediaPlayback$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, allow]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; @@ -1257,47 +1294,49 @@ class WKWebViewConfigurationHostApi { } Future setLimitsNavigationsToAppBoundDomains( - int arg_identifier, bool arg_limit) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.setLimitsNavigationsToAppBoundDomains', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_limit]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + int identifier, bool limit) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.setLimitsNavigationsToAppBoundDomains$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, limit]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; } } - Future setMediaTypesRequiringUserActionForPlayback(int arg_identifier, - List arg_types) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.setMediaTypesRequiringUserActionForPlayback', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_types]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future setMediaTypesRequiringUserActionForPlayback( + int identifier, List types) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.setMediaTypesRequiringUserActionForPlayback$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, types]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; @@ -1309,21 +1348,28 @@ class WKWebViewConfigurationHostApi { /// /// See https://developer.apple.com/documentation/webkit/wkwebviewconfiguration?language=objc. abstract class WKWebViewConfigurationFlutterApi { - static const MessageCodec codec = StandardMessageCodec(); + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); void create(int identifier); - static void setup(WKWebViewConfigurationFlutterApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + WKWebViewConfigurationFlutterApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationFlutterApi.create', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationFlutterApi.create$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMessageHandler(null); + __pigeon_channel.setMessageHandler(null); } else { - channel.setMessageHandler((Object? message) async { + __pigeon_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationFlutterApi.create was null.'); final List args = (message as List?)!; @@ -1380,32 +1426,37 @@ class WKUserContentControllerHostApi { /// Constructor for [WKUserContentControllerHostApi]. 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. - WKUserContentControllerHostApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; - - static const MessageCodec codec = + WKUserContentControllerHostApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : __pigeon_binaryMessenger = binaryMessenger, + __pigeon_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? __pigeon_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _WKUserContentControllerHostApiCodec(); + final String __pigeon_messageChannelSuffix; + Future createFromWebViewConfiguration( - int arg_identifier, int arg_configurationIdentifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.createFromWebViewConfiguration', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_configurationIdentifier]) - as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + int identifier, int configurationIdentifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.createFromWebViewConfiguration$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, configurationIdentifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; @@ -1413,71 +1464,72 @@ class WKUserContentControllerHostApi { } Future addScriptMessageHandler( - int arg_identifier, int arg_handlerIdentifier, String arg_name) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.addScriptMessageHandler', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_handlerIdentifier, arg_name]) - as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + int identifier, int handlerIdentifier, String name) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.addScriptMessageHandler$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, handlerIdentifier, name]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; } } - Future removeScriptMessageHandler( - int arg_identifier, String arg_name) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.removeScriptMessageHandler', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_name]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future removeScriptMessageHandler(int identifier, String name) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.removeScriptMessageHandler$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, name]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; } } - Future removeAllScriptMessageHandlers(int arg_identifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.removeAllScriptMessageHandlers', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future removeAllScriptMessageHandlers(int identifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.removeAllScriptMessageHandlers$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([identifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; @@ -1485,46 +1537,48 @@ class WKUserContentControllerHostApi { } Future addUserScript( - int arg_identifier, WKUserScriptData arg_userScript) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.addUserScript', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_userScript]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + int identifier, WKUserScriptData userScript) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.addUserScript$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, userScript]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; } } - Future removeAllUserScripts(int arg_identifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.removeAllUserScripts', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future removeAllUserScripts(int identifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.removeAllUserScripts$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([identifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; @@ -1539,55 +1593,61 @@ class WKPreferencesHostApi { /// Constructor for [WKPreferencesHostApi]. 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. - WKPreferencesHostApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; + WKPreferencesHostApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : __pigeon_binaryMessenger = binaryMessenger, + __pigeon_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? __pigeon_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); - static const MessageCodec codec = StandardMessageCodec(); + final String __pigeon_messageChannelSuffix; Future createFromWebViewConfiguration( - int arg_identifier, int arg_configurationIdentifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKPreferencesHostApi.createFromWebViewConfiguration', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_configurationIdentifier]) - as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + int identifier, int configurationIdentifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKPreferencesHostApi.createFromWebViewConfiguration$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, configurationIdentifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; } } - Future setJavaScriptEnabled( - int arg_identifier, bool arg_enabled) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKPreferencesHostApi.setJavaScriptEnabled', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_enabled]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future setJavaScriptEnabled(int identifier, bool enabled) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKPreferencesHostApi.setJavaScriptEnabled$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, enabled]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; @@ -1602,29 +1662,36 @@ class WKScriptMessageHandlerHostApi { /// Constructor for [WKScriptMessageHandlerHostApi]. 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. - WKScriptMessageHandlerHostApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; - - static const MessageCodec codec = StandardMessageCodec(); - - Future create(int arg_identifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKScriptMessageHandlerHostApi.create', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + WKScriptMessageHandlerHostApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : __pigeon_binaryMessenger = binaryMessenger, + __pigeon_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? __pigeon_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); + + final String __pigeon_messageChannelSuffix; + + Future create(int identifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKScriptMessageHandlerHostApi.create$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([identifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; @@ -1659,23 +1726,29 @@ class _WKScriptMessageHandlerFlutterApiCodec extends StandardMessageCodec { /// /// See https://developer.apple.com/documentation/webkit/wkscriptmessagehandler?language=objc. abstract class WKScriptMessageHandlerFlutterApi { - static const MessageCodec codec = + static const MessageCodec pigeonChannelCodec = _WKScriptMessageHandlerFlutterApiCodec(); void didReceiveScriptMessage(int identifier, int userContentControllerIdentifier, WKScriptMessageData message); - static void setup(WKScriptMessageHandlerFlutterApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + WKScriptMessageHandlerFlutterApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKScriptMessageHandlerFlutterApi.didReceiveScriptMessage', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKScriptMessageHandlerFlutterApi.didReceiveScriptMessage$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMessageHandler(null); + __pigeon_channel.setMessageHandler(null); } else { - channel.setMessageHandler((Object? message) async { + __pigeon_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKScriptMessageHandlerFlutterApi.didReceiveScriptMessage was null.'); final List args = (message as List?)!; @@ -1712,29 +1785,36 @@ class WKNavigationDelegateHostApi { /// Constructor for [WKNavigationDelegateHostApi]. 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. - WKNavigationDelegateHostApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; - - static const MessageCodec codec = StandardMessageCodec(); - - Future create(int arg_identifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateHostApi.create', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + WKNavigationDelegateHostApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : __pigeon_binaryMessenger = binaryMessenger, + __pigeon_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? __pigeon_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); + + final String __pigeon_messageChannelSuffix; + + Future create(int identifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateHostApi.create$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([identifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; @@ -1804,7 +1884,7 @@ class _WKNavigationDelegateFlutterApiCodec extends StandardMessageCodec { /// /// See https://developer.apple.com/documentation/webkit/wknavigationdelegate?language=objc. abstract class WKNavigationDelegateFlutterApi { - static const MessageCodec codec = + static const MessageCodec pigeonChannelCodec = _WKNavigationDelegateFlutterApiCodec(); void didFinishNavigation(int identifier, int webViewIdentifier, String? url); @@ -1834,17 +1914,23 @@ abstract class WKNavigationDelegateFlutterApi { Future didReceiveAuthenticationChallenge( int identifier, int webViewIdentifier, int challengeIdentifier); - static void setup(WKNavigationDelegateFlutterApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + WKNavigationDelegateFlutterApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateFlutterApi.didFinishNavigation', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateFlutterApi.didFinishNavigation$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMessageHandler(null); + __pigeon_channel.setMessageHandler(null); } else { - channel.setMessageHandler((Object? message) async { + __pigeon_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateFlutterApi.didFinishNavigation was null.'); final List args = (message as List?)!; @@ -1869,14 +1955,15 @@ abstract class WKNavigationDelegateFlutterApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateFlutterApi.didStartProvisionalNavigation', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateFlutterApi.didStartProvisionalNavigation$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMessageHandler(null); + __pigeon_channel.setMessageHandler(null); } else { - channel.setMessageHandler((Object? message) async { + __pigeon_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateFlutterApi.didStartProvisionalNavigation was null.'); final List args = (message as List?)!; @@ -1901,14 +1988,15 @@ abstract class WKNavigationDelegateFlutterApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateFlutterApi.decidePolicyForNavigationAction', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateFlutterApi.decidePolicyForNavigationAction$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMessageHandler(null); + __pigeon_channel.setMessageHandler(null); } else { - channel.setMessageHandler((Object? message) async { + __pigeon_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateFlutterApi.decidePolicyForNavigationAction was null.'); final List args = (message as List?)!; @@ -1937,14 +2025,15 @@ abstract class WKNavigationDelegateFlutterApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateFlutterApi.decidePolicyForNavigationResponse', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateFlutterApi.decidePolicyForNavigationResponse$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMessageHandler(null); + __pigeon_channel.setMessageHandler(null); } else { - channel.setMessageHandler((Object? message) async { + __pigeon_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateFlutterApi.decidePolicyForNavigationResponse was null.'); final List args = (message as List?)!; @@ -1973,14 +2062,15 @@ abstract class WKNavigationDelegateFlutterApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateFlutterApi.didFailNavigation', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateFlutterApi.didFailNavigation$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMessageHandler(null); + __pigeon_channel.setMessageHandler(null); } else { - channel.setMessageHandler((Object? message) async { + __pigeon_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateFlutterApi.didFailNavigation was null.'); final List args = (message as List?)!; @@ -2007,14 +2097,15 @@ abstract class WKNavigationDelegateFlutterApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateFlutterApi.didFailProvisionalNavigation', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateFlutterApi.didFailProvisionalNavigation$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMessageHandler(null); + __pigeon_channel.setMessageHandler(null); } else { - channel.setMessageHandler((Object? message) async { + __pigeon_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateFlutterApi.didFailProvisionalNavigation was null.'); final List args = (message as List?)!; @@ -2041,14 +2132,15 @@ abstract class WKNavigationDelegateFlutterApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateFlutterApi.webViewWebContentProcessDidTerminate', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateFlutterApi.webViewWebContentProcessDidTerminate$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMessageHandler(null); + __pigeon_channel.setMessageHandler(null); } else { - channel.setMessageHandler((Object? message) async { + __pigeon_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateFlutterApi.webViewWebContentProcessDidTerminate was null.'); final List args = (message as List?)!; @@ -2072,14 +2164,15 @@ abstract class WKNavigationDelegateFlutterApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateFlutterApi.didReceiveAuthenticationChallenge', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateFlutterApi.didReceiveAuthenticationChallenge$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMessageHandler(null); + __pigeon_channel.setMessageHandler(null); } else { - channel.setMessageHandler((Object? message) async { + __pigeon_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateFlutterApi.didReceiveAuthenticationChallenge was null.'); final List args = (message as List?)!; @@ -2139,85 +2232,88 @@ class NSObjectHostApi { /// Constructor for [NSObjectHostApi]. 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. - NSObjectHostApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; - - static const MessageCodec codec = _NSObjectHostApiCodec(); - - Future dispose(int arg_identifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectHostApi.dispose', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + NSObjectHostApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : __pigeon_binaryMessenger = binaryMessenger, + __pigeon_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? __pigeon_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = + _NSObjectHostApiCodec(); + + final String __pigeon_messageChannelSuffix; + + Future dispose(int identifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectHostApi.dispose$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([identifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; } } - Future addObserver( - int arg_identifier, - int arg_observerIdentifier, - String arg_keyPath, - List arg_options) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectHostApi.addObserver', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send([ - arg_identifier, - arg_observerIdentifier, - arg_keyPath, - arg_options - ]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future addObserver(int identifier, int observerIdentifier, + String keyPath, List options) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectHostApi.addObserver$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, observerIdentifier, keyPath, options]) + as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; } } - Future removeObserver(int arg_identifier, int arg_observerIdentifier, - String arg_keyPath) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectHostApi.removeObserver', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send( - [arg_identifier, arg_observerIdentifier, arg_keyPath]) + Future removeObserver( + int identifier, int observerIdentifier, String keyPath) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectHostApi.removeObserver$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, observerIdentifier, keyPath]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; @@ -2257,7 +2353,8 @@ class _NSObjectFlutterApiCodec extends StandardMessageCodec { /// /// See https://developer.apple.com/documentation/objectivec/nsobject. abstract class NSObjectFlutterApi { - static const MessageCodec codec = _NSObjectFlutterApiCodec(); + static const MessageCodec pigeonChannelCodec = + _NSObjectFlutterApiCodec(); void observeValue( int identifier, @@ -2268,17 +2365,23 @@ abstract class NSObjectFlutterApi { void dispose(int identifier); - static void setup(NSObjectFlutterApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + NSObjectFlutterApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectFlutterApi.observeValue', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectFlutterApi.observeValue$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMessageHandler(null); + __pigeon_channel.setMessageHandler(null); } else { - channel.setMessageHandler((Object? message) async { + __pigeon_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectFlutterApi.observeValue was null.'); final List args = (message as List?)!; @@ -2313,14 +2416,15 @@ abstract class NSObjectFlutterApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectFlutterApi.dispose', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectFlutterApi.dispose$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMessageHandler(null); + __pigeon_channel.setMessageHandler(null); } else { - channel.setMessageHandler((Object? message) async { + __pigeon_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectFlutterApi.dispose was null.'); final List args = (message as List?)!; @@ -2472,56 +2576,60 @@ class WKWebViewHostApi { /// Constructor for [WKWebViewHostApi]. 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. - WKWebViewHostApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; - - static const MessageCodec codec = _WKWebViewHostApiCodec(); - - Future create( - int arg_identifier, int arg_configurationIdentifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.create', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_configurationIdentifier]) - as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + WKWebViewHostApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : __pigeon_binaryMessenger = binaryMessenger, + __pigeon_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? __pigeon_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = + _WKWebViewHostApiCodec(); + + final String __pigeon_messageChannelSuffix; + + Future create(int identifier, int configurationIdentifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.create$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, configurationIdentifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; } } - Future setUIDelegate( - int arg_identifier, int? arg_uiDelegateIdentifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setUIDelegate', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier, arg_uiDelegateIdentifier]) - as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future setUIDelegate(int identifier, int? uiDelegateIdentifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setUIDelegate$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, uiDelegateIdentifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; @@ -2529,99 +2637,102 @@ class WKWebViewHostApi { } Future setNavigationDelegate( - int arg_identifier, int? arg_navigationDelegateIdentifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setNavigationDelegate', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_navigationDelegateIdentifier]) + int identifier, int? navigationDelegateIdentifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setNavigationDelegate$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, navigationDelegateIdentifier]) as List?; - if (replyList == null) { + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; } } - Future getUrl(int arg_identifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.getUrl', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future getUrl(int identifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.getUrl$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([identifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { - return (replyList[0] as String?); + return (__pigeon_replyList[0] as String?); } } - Future getEstimatedProgress(int arg_identifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.getEstimatedProgress', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future getEstimatedProgress(int identifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.getEstimatedProgress$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([identifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); - } else if (replyList[0] == null) { + } else if (__pigeon_replyList[0] == null) { throw PlatformException( code: 'null-error', message: 'Host platform returned null value for non-null return value.', ); } else { - return (replyList[0] as double?)!; + return (__pigeon_replyList[0] as double?)!; } } - Future loadRequest( - int arg_identifier, NSUrlRequestData arg_request) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.loadRequest', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_request]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future loadRequest(int identifier, NSUrlRequestData request) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.loadRequest$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, request]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; @@ -2629,24 +2740,24 @@ class WKWebViewHostApi { } Future loadHtmlString( - int arg_identifier, String arg_string, String? arg_baseUrl) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.loadHtmlString', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier, arg_string, arg_baseUrl]) - as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + int identifier, String string, String? baseUrl) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.loadHtmlString$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, string, baseUrl]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; @@ -2654,243 +2765,251 @@ class WKWebViewHostApi { } Future loadFileUrl( - int arg_identifier, String arg_url, String arg_readAccessUrl) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.loadFileUrl', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_url, arg_readAccessUrl]) - as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + int identifier, String url, String readAccessUrl) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.loadFileUrl$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, url, readAccessUrl]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; } } - Future loadFlutterAsset(int arg_identifier, String arg_key) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.loadFlutterAsset', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_key]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future loadFlutterAsset(int identifier, String key) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.loadFlutterAsset$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, key]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; } } - Future canGoBack(int arg_identifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.canGoBack', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future canGoBack(int identifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.canGoBack$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([identifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); - } else if (replyList[0] == null) { + } else if (__pigeon_replyList[0] == null) { throw PlatformException( code: 'null-error', message: 'Host platform returned null value for non-null return value.', ); } else { - return (replyList[0] as bool?)!; + return (__pigeon_replyList[0] as bool?)!; } } - Future canGoForward(int arg_identifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.canGoForward', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future canGoForward(int identifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.canGoForward$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([identifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); - } else if (replyList[0] == null) { + } else if (__pigeon_replyList[0] == null) { throw PlatformException( code: 'null-error', message: 'Host platform returned null value for non-null return value.', ); } else { - return (replyList[0] as bool?)!; + return (__pigeon_replyList[0] as bool?)!; } } - Future goBack(int arg_identifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.goBack', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future goBack(int identifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.goBack$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([identifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; } } - Future goForward(int arg_identifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.goForward', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future goForward(int identifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.goForward$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([identifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; } } - Future reload(int arg_identifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.reload', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future reload(int identifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.reload$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([identifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; } } - Future getTitle(int arg_identifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.getTitle', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future getTitle(int identifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.getTitle$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([identifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { - return (replyList[0] as String?); + return (__pigeon_replyList[0] as String?); } } Future setAllowsBackForwardNavigationGestures( - int arg_identifier, bool arg_allow) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setAllowsBackForwardNavigationGestures', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_allow]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + int identifier, bool allow) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setAllowsBackForwardNavigationGestures$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, allow]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; } } - Future setCustomUserAgent( - int arg_identifier, String? arg_userAgent) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setCustomUserAgent', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_userAgent]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future setCustomUserAgent(int identifier, String? userAgent) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setCustomUserAgent$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, userAgent]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; @@ -2898,73 +3017,75 @@ class WKWebViewHostApi { } Future evaluateJavaScript( - int arg_identifier, String arg_javaScriptString) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.evaluateJavaScript', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier, arg_javaScriptString]) - as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + int identifier, String javaScriptString) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.evaluateJavaScript$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, javaScriptString]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { - return replyList[0]; + return __pigeon_replyList[0]; } } - Future setInspectable(int arg_identifier, bool arg_inspectable) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setInspectable', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_inspectable]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future setInspectable(int identifier, bool inspectable) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setInspectable$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, inspectable]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; } } - Future getCustomUserAgent(int arg_identifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.getCustomUserAgent', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future getCustomUserAgent(int identifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.getCustomUserAgent$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([identifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { - return (replyList[0] as String?); + return (__pigeon_replyList[0] as String?); } } } @@ -2976,29 +3097,36 @@ class WKUIDelegateHostApi { /// Constructor for [WKUIDelegateHostApi]. 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. - WKUIDelegateHostApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; - - static const MessageCodec codec = StandardMessageCodec(); - - Future create(int arg_identifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateHostApi.create', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + WKUIDelegateHostApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : __pigeon_binaryMessenger = binaryMessenger, + __pigeon_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? __pigeon_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); + + final String __pigeon_messageChannelSuffix; + + Future create(int identifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateHostApi.create$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([identifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; @@ -3058,7 +3186,8 @@ class _WKUIDelegateFlutterApiCodec extends StandardMessageCodec { /// /// See https://developer.apple.com/documentation/webkit/wkuidelegate?language=objc. abstract class WKUIDelegateFlutterApi { - static const MessageCodec codec = _WKUIDelegateFlutterApiCodec(); + static const MessageCodec pigeonChannelCodec = + _WKUIDelegateFlutterApiCodec(); void onCreateWebView(int identifier, int webViewIdentifier, int configurationIdentifier, WKNavigationActionData navigationAction); @@ -3083,17 +3212,23 @@ abstract class WKUIDelegateFlutterApi { Future runJavaScriptTextInputPanel( int identifier, String prompt, String defaultText, WKFrameInfoData frame); - static void setup(WKUIDelegateFlutterApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + WKUIDelegateFlutterApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateFlutterApi.onCreateWebView', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateFlutterApi.onCreateWebView$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMessageHandler(null); + __pigeon_channel.setMessageHandler(null); } else { - channel.setMessageHandler((Object? message) async { + __pigeon_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateFlutterApi.onCreateWebView was null.'); final List args = (message as List?)!; @@ -3124,14 +3259,15 @@ abstract class WKUIDelegateFlutterApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateFlutterApi.requestMediaCapturePermission', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateFlutterApi.requestMediaCapturePermission$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMessageHandler(null); + __pigeon_channel.setMessageHandler(null); } else { - channel.setMessageHandler((Object? message) async { + __pigeon_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateFlutterApi.requestMediaCapturePermission was null.'); final List args = (message as List?)!; @@ -3167,14 +3303,15 @@ abstract class WKUIDelegateFlutterApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateFlutterApi.runJavaScriptAlertPanel', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateFlutterApi.runJavaScriptAlertPanel$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMessageHandler(null); + __pigeon_channel.setMessageHandler(null); } else { - channel.setMessageHandler((Object? message) async { + __pigeon_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateFlutterApi.runJavaScriptAlertPanel was null.'); final List args = (message as List?)!; @@ -3201,14 +3338,15 @@ abstract class WKUIDelegateFlutterApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateFlutterApi.runJavaScriptConfirmPanel', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateFlutterApi.runJavaScriptConfirmPanel$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMessageHandler(null); + __pigeon_channel.setMessageHandler(null); } else { - channel.setMessageHandler((Object? message) async { + __pigeon_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateFlutterApi.runJavaScriptConfirmPanel was null.'); final List args = (message as List?)!; @@ -3235,14 +3373,15 @@ abstract class WKUIDelegateFlutterApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateFlutterApi.runJavaScriptTextInputPanel', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateFlutterApi.runJavaScriptTextInputPanel$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMessageHandler(null); + __pigeon_channel.setMessageHandler(null); } else { - channel.setMessageHandler((Object? message) async { + __pigeon_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateFlutterApi.runJavaScriptTextInputPanel was null.'); final List args = (message as List?)!; @@ -3309,55 +3448,62 @@ class WKHttpCookieStoreHostApi { /// Constructor for [WKHttpCookieStoreHostApi]. 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. - WKHttpCookieStoreHostApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; + WKHttpCookieStoreHostApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : __pigeon_binaryMessenger = binaryMessenger, + __pigeon_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? __pigeon_binaryMessenger; - static const MessageCodec codec = _WKHttpCookieStoreHostApiCodec(); + static const MessageCodec pigeonChannelCodec = + _WKHttpCookieStoreHostApiCodec(); + + final String __pigeon_messageChannelSuffix; Future createFromWebsiteDataStore( - int arg_identifier, int arg_websiteDataStoreIdentifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKHttpCookieStoreHostApi.createFromWebsiteDataStore', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_websiteDataStoreIdentifier]) + int identifier, int websiteDataStoreIdentifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKHttpCookieStoreHostApi.createFromWebsiteDataStore$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, websiteDataStoreIdentifier]) as List?; - if (replyList == null) { + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; } } - Future setCookie( - int arg_identifier, NSHttpCookieData arg_cookie) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKHttpCookieStoreHostApi.setCookie', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel - .send([arg_identifier, arg_cookie]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future setCookie(int identifier, NSHttpCookieData cookie) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKHttpCookieStoreHostApi.setCookie$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, cookie]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; @@ -3376,32 +3522,39 @@ class NSUrlHostApi { /// Constructor for [NSUrlHostApi]. 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. - NSUrlHostApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; - - static const MessageCodec codec = StandardMessageCodec(); - - Future getAbsoluteString(int arg_identifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlHostApi.getAbsoluteString', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + NSUrlHostApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : __pigeon_binaryMessenger = binaryMessenger, + __pigeon_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? __pigeon_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); + + final String __pigeon_messageChannelSuffix; + + Future getAbsoluteString(int identifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlHostApi.getAbsoluteString$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([identifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { - return (replyList[0] as String?); + return (__pigeon_replyList[0] as String?); } } } @@ -3414,20 +3567,28 @@ class NSUrlHostApi { /// /// See https://developer.apple.com/documentation/foundation/nsurl?language=objc. abstract class NSUrlFlutterApi { - static const MessageCodec codec = StandardMessageCodec(); + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); void create(int identifier); - static void setup(NSUrlFlutterApi? api, {BinaryMessenger? binaryMessenger}) { + static void setUp( + NSUrlFlutterApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlFlutterApi.create', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlFlutterApi.create$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMessageHandler(null); + __pigeon_channel.setMessageHandler(null); } else { - channel.setMessageHandler((Object? message) async { + __pigeon_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlFlutterApi.create was null.'); final List args = (message as List?)!; @@ -3460,29 +3621,36 @@ class UIScrollViewDelegateHostApi { /// Constructor for [UIScrollViewDelegateHostApi]. 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. - UIScrollViewDelegateHostApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; - - static const MessageCodec codec = StandardMessageCodec(); - - Future create(int arg_identifier) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewDelegateHostApi.create', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_identifier]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + UIScrollViewDelegateHostApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : __pigeon_binaryMessenger = binaryMessenger, + __pigeon_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? __pigeon_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); + + final String __pigeon_messageChannelSuffix; + + Future create(int identifier) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewDelegateHostApi.create$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([identifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; @@ -3494,22 +3662,29 @@ class UIScrollViewDelegateHostApi { /// /// See https://developer.apple.com/documentation/uikit/uiscrollviewdelegate?language=objc. abstract class UIScrollViewDelegateFlutterApi { - static const MessageCodec codec = StandardMessageCodec(); + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); void scrollViewDidScroll( int identifier, int uiScrollViewIdentifier, double x, double y); - static void setup(UIScrollViewDelegateFlutterApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + UIScrollViewDelegateFlutterApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewDelegateFlutterApi.scrollViewDidScroll', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewDelegateFlutterApi.scrollViewDidScroll$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMessageHandler(null); + __pigeon_channel.setMessageHandler(null); } else { - channel.setMessageHandler((Object? message) async { + __pigeon_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewDelegateFlutterApi.scrollViewDidScroll was null.'); final List args = (message as List?)!; @@ -3552,35 +3727,39 @@ class NSUrlCredentialHostApi { /// Constructor for [NSUrlCredentialHostApi]. 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. - NSUrlCredentialHostApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; + NSUrlCredentialHostApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : __pigeon_binaryMessenger = binaryMessenger, + __pigeon_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? __pigeon_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); - static const MessageCodec codec = StandardMessageCodec(); + final String __pigeon_messageChannelSuffix; /// Create a new native instance and add it to the `InstanceManager`. - Future createWithUser(int arg_identifier, String arg_user, - String arg_password, NSUrlCredentialPersistence arg_persistence) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlCredentialHostApi.createWithUser', - codec, - binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send([ - arg_identifier, - arg_user, - arg_password, - arg_persistence.index - ]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { + Future createWithUser(int identifier, String user, String password, + NSUrlCredentialPersistence persistence) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlCredentialHostApi.createWithUser$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, user, password, persistence.index]) + as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], ); } else { return; @@ -3596,23 +3775,30 @@ class NSUrlCredentialHostApi { /// /// See https://developer.apple.com/documentation/foundation/nsurlprotectionspace?language=objc. abstract class NSUrlProtectionSpaceFlutterApi { - static const MessageCodec codec = StandardMessageCodec(); + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); /// Create a new Dart instance and add it to the `InstanceManager`. void create(int identifier, String? host, String? realm, String? authenticationMethod); - static void setup(NSUrlProtectionSpaceFlutterApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + NSUrlProtectionSpaceFlutterApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlProtectionSpaceFlutterApi.create', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlProtectionSpaceFlutterApi.create$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMessageHandler(null); + __pigeon_channel.setMessageHandler(null); } else { - channel.setMessageHandler((Object? message) async { + __pigeon_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlProtectionSpaceFlutterApi.create was null.'); final List args = (message as List?)!; @@ -3646,22 +3832,29 @@ abstract class NSUrlProtectionSpaceFlutterApi { /// /// See https://developer.apple.com/documentation/foundation/nsurlauthenticationchallenge?language=objc. abstract class NSUrlAuthenticationChallengeFlutterApi { - static const MessageCodec codec = StandardMessageCodec(); + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); /// Create a new Dart instance and add it to the `InstanceManager`. void create(int identifier, int protectionSpaceIdentifier); - static void setup(NSUrlAuthenticationChallengeFlutterApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + NSUrlAuthenticationChallengeFlutterApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlAuthenticationChallengeFlutterApi.create', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlAuthenticationChallengeFlutterApi.create$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMessageHandler(null); + __pigeon_channel.setMessageHandler(null); } else { - channel.setMessageHandler((Object? message) async { + __pigeon_channel.setMessageHandler((Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlAuthenticationChallengeFlutterApi.create was null.'); final List args = (message as List?)!; diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/foundation/foundation.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/foundation/foundation.dart index 1dabbd0c24a5..2df5c9efc6cd 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/foundation/foundation.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/foundation/foundation.dart @@ -505,6 +505,9 @@ class NSUrlAuthenticationMethod { /// Use HTTP digest authentication for this protection space. static const String httpDigest = 'NSURLAuthenticationMethodHTTPDigest'; + + /// Use NTLM authentication for this protection space. + static const String httpNtlm = 'NSURLAuthenticationMethodNTLM'; } /// A challenge from a server requiring authentication from the client. diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/foundation/foundation_api_impls.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/foundation/foundation_api_impls.dart index fd8dc58a6ccd..293ce29bbbec 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/foundation/foundation_api_impls.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/foundation/foundation_api_impls.dart @@ -100,16 +100,16 @@ class FoundationFlutterApis { /// Ensures all the Flutter APIs have been set up to receive calls from native code. void ensureSetUp() { if (!_hasBeenSetUp) { - NSObjectFlutterApi.setup( + NSObjectFlutterApi.setUp( object, binaryMessenger: _binaryMessenger, ); - NSUrlFlutterApi.setup(url, binaryMessenger: _binaryMessenger); - NSUrlProtectionSpaceFlutterApi.setup( + NSUrlFlutterApi.setUp(url, binaryMessenger: _binaryMessenger); + NSUrlProtectionSpaceFlutterApi.setUp( urlProtectionSpace, binaryMessenger: _binaryMessenger, ); - NSUrlAuthenticationChallengeFlutterApi.setup( + NSUrlAuthenticationChallengeFlutterApi.setUp( urlAuthenticationChallenge, binaryMessenger: _binaryMessenger, ); diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/legacy/web_kit_webview_widget.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/legacy/web_kit_webview_widget.dart index 6c984ec50bc8..7a3795096dec 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/legacy/web_kit_webview_widget.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/legacy/web_kit_webview_widget.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:io'; import 'dart:math'; import 'package:flutter/material.dart'; @@ -229,9 +230,16 @@ class WebKitWebViewPlatformController extends WebViewPlatformController { } if (params.backgroundColor != null) { - unawaited(webView.setOpaque(false)); - unawaited(webView.setBackgroundColor(Colors.transparent)); - unawaited(webView.scrollView.setBackgroundColor(params.backgroundColor)); + final WKWebView webView = this.webView; + if (webView is WKWebViewIOS) { + unawaited(webView.setOpaque(false)); + unawaited(webView.setBackgroundColor(Colors.transparent)); + unawaited( + webView.scrollView.setBackgroundColor(params.backgroundColor)); + } else { + // TODO(stuartmorgan): Investigate doing this via JS instead. + throw UnimplementedError('Background color is yet supported on macOS'); + } } if (params.initialUrl != null) { @@ -377,31 +385,51 @@ class WebKitWebViewPlatformController extends WebViewPlatformController { Future currentUrl() => webView.getUrl(); @override - Future scrollTo(int x, int y) { - return webView.scrollView.setContentOffset(Point( - x.toDouble(), - y.toDouble(), - )); + Future scrollTo(int x, int y) async { + final WKWebView webView = this.webView; + if (webView is WKWebViewIOS) { + return webView.scrollView.setContentOffset(Point( + x.toDouble(), + y.toDouble(), + )); + } else { + throw UnimplementedError('scrollTo is not supported on macOS'); + } } @override Future scrollBy(int x, int y) async { - await webView.scrollView.scrollBy(Point( - x.toDouble(), - y.toDouble(), - )); + final WKWebView webView = this.webView; + if (webView is WKWebViewIOS) { + await webView.scrollView.scrollBy(Point( + x.toDouble(), + y.toDouble(), + )); + } else { + throw UnimplementedError('scrollBy is not supported on macOS'); + } } @override Future getScrollX() async { - final Point offset = await webView.scrollView.getContentOffset(); - return offset.x.toInt(); + final WKWebView webView = this.webView; + if (webView is WKWebViewIOS) { + final Point offset = await webView.scrollView.getContentOffset(); + return offset.x.toInt(); + } else { + throw UnimplementedError('getScrollX is not supported on macOS'); + } } @override Future getScrollY() async { - final Point offset = await webView.scrollView.getContentOffset(); - return offset.y.toInt(); + final WKWebView webView = this.webView; + if (webView is WKWebViewIOS) { + final Point offset = await webView.scrollView.getContentOffset(); + return offset.y.toInt(); + } else { + throw UnimplementedError('getScrollY is not supported on macOS'); + } } @override @@ -640,7 +668,11 @@ class WebKitWebViewPlatformController extends WebViewPlatformController { @visibleForTesting class WebViewWidgetProxy { /// Constructs a [WebViewWidgetProxy]. - const WebViewWidgetProxy(); + const WebViewWidgetProxy({@visibleForTesting this.overriddenIsMacOS}); + + /// If set, replaces [Platform] checks when picking implementation classes. + @visibleForTesting + final bool? overriddenIsMacOS; /// Constructs a [WKWebView]. WKWebView createWebView( @@ -651,7 +683,11 @@ class WebViewWidgetProxy { Map change, )? observeValue, }) { - return WKWebView(configuration, observeValue: observeValue); + if (overriddenIsMacOS ?? Platform.isMacOS) { + return WKWebViewMacOS(configuration, observeValue: observeValue); + } else { + return WKWebViewIOS(configuration, observeValue: observeValue); + } } /// Constructs a [WKScriptMessageHandler]. diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/ui_kit/ui_kit.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/ui_kit/ui_kit.dart index b3f5ebe79f6e..fe5a0a3343b1 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/ui_kit/ui_kit.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/ui_kit/ui_kit.dart @@ -18,7 +18,7 @@ import 'ui_kit_api_impls.dart'; /// /// Wraps [UIScrollView](https://developer.apple.com/documentation/uikit/uiscrollview?language=objc). @immutable -class UIScrollView extends UIView { +class UIScrollView extends UIViewBase { /// Constructs a [UIScrollView] that is owned by [webView]. factory UIScrollView.fromWebView( WKWebView webView, { @@ -94,17 +94,36 @@ class UIScrollView extends UIView { } } +/// Methods that anything implementing a class that inherits from UIView on the +/// native side must implement. +/// +/// Classes without a multiple inheritence problem should extend UIViewBase +/// instead of implementing this directly. +abstract class UIView implements NSObject { + /// The view’s background color. + /// + /// The default value is null, which results in a transparent background color. + /// + /// Sets [UIView.backgroundColor](https://developer.apple.com/documentation/uikit/uiview/1622591-backgroundcolor?language=objc). + Future setBackgroundColor(Color? color); + + /// Determines whether the view is opaque. + /// + /// Sets [UIView.opaque](https://developer.apple.com/documentation/uikit/uiview?language=objc). + Future setOpaque(bool opaque); +} + /// Manages the content for a rectangular area on the screen. /// /// Wraps [UIView](https://developer.apple.com/documentation/uikit/uiview?language=objc). @immutable -class UIView extends NSObject { +class UIViewBase extends NSObject implements UIView { /// Constructs a [UIView] without creating the associated /// Objective-C object. /// /// This should only be used by subclasses created by this library or to /// create copies. - UIView.detached({ + UIViewBase.detached({ super.observeValue, super.binaryMessenger, super.instanceManager, @@ -116,25 +135,19 @@ class UIView extends NSObject { final UIViewHostApiImpl _viewApi; - /// The view’s background color. - /// - /// The default value is null, which results in a transparent background color. - /// - /// Sets [UIView.backgroundColor](https://developer.apple.com/documentation/uikit/uiview/1622591-backgroundcolor?language=objc). + @override Future setBackgroundColor(Color? color) { return _viewApi.setBackgroundColorForInstances(this, color); } - /// Determines whether the view is opaque. - /// - /// Sets [UIView.opaque](https://developer.apple.com/documentation/uikit/uiview?language=objc). + @override Future setOpaque(bool opaque) { return _viewApi.setOpaqueForInstances(this, opaque); } @override UIView copy() { - return UIView.detached( + return UIViewBase.detached( observeValue: observeValue, binaryMessenger: _viewApi.binaryMessenger, instanceManager: _viewApi.instanceManager, diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/web_kit/web_kit.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/web_kit/web_kit.dart index 11065ad0805f..d5dcf0fff309 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/web_kit/web_kit.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/web_kit/web_kit.dart @@ -8,6 +8,7 @@ import 'package:flutter/services.dart'; import '../common/instance_manager.dart'; import '../foundation/foundation.dart'; import '../ui_kit/ui_kit.dart'; +import '../ui_kit/ui_kit_api_impls.dart' show UIViewHostApiImpl; import 'web_kit_api_impls.dart'; export 'web_kit_api_impls.dart' @@ -1009,8 +1010,12 @@ class WKNavigationDelegate extends NSObject { /// Object that displays interactive web content, such as for an in-app browser. /// /// Wraps [WKWebView](https://developer.apple.com/documentation/webkit/wkwebview?language=objc). +/// +/// This is abstract, since iOS and macOS WKWebViews have different +/// implementation details; the concrete implementations are [WKWebViewIOS] and +/// [WKWebViewMacOS]. @immutable -class WKWebView extends UIView { +abstract class WKWebView extends NSObject { /// Constructs a [WKWebView]. /// /// [configuration] contains the configuration details for the web view. This @@ -1068,13 +1073,6 @@ class WKWebView extends UIView { instanceManager: _webViewApi.instanceManager, ); - /// The scrollable view associated with the web view. - late final UIScrollView scrollView = UIScrollView.fromWebView( - this, - binaryMessenger: _webViewApi.binaryMessenger, - instanceManager: _webViewApi.instanceManager, - ); - /// Used to integrate custom user interface elements into web view interactions. /// /// Sets [WKWebView.UIDelegate](https://developer.apple.com/documentation/webkit/wkwebview/1415009-uidelegate?language=objc). @@ -1163,6 +1161,13 @@ class WKWebView extends UIView { return _webViewApi.getTitleForInstances(this); } + /// The custom user agent string. + /// + /// Represents [WKWebView.customUserAgent](https://developer.apple.com/documentation/webkit/wkwebview/1414950-customuseragent?language=objc). + Future getCustomUserAgent() { + return _webViewApi.getCustomUserAgentForInstances(this); + } + /// Indicates whether horizontal swipe gestures trigger page navigation. /// /// The default value is false. @@ -1212,17 +1217,89 @@ class WKWebView extends UIView { inspectable, ); } +} - /// The custom user agent string. - /// - /// Represents [WKWebView.customUserAgent](https://developer.apple.com/documentation/webkit/wkwebview/1414950-customuseragent?language=objc). - Future getCustomUserAgent() { - return _webViewApi.getCustomUserAgentForInstances(this); +/// The iOS version of a WKWebView. +class WKWebViewIOS extends WKWebView implements UIView { + /// Constructs a new iOS WKWebView; see [WKWebView] for details. + WKWebViewIOS( + super.configuration, { + super.observeValue, + super.binaryMessenger, + super.instanceManager, + }) : _viewApi = UIViewHostApiImpl( + binaryMessenger: binaryMessenger, + instanceManager: instanceManager, + ), + super(); + + /// See [WKWebView.detached]. + WKWebViewIOS.detached({ + super.observeValue, + super.binaryMessenger, + super.instanceManager, + }) : _viewApi = UIViewHostApiImpl( + binaryMessenger: binaryMessenger, + instanceManager: instanceManager, + ), + super.detached(); + + /// The scrollable view associated with the web view. + late final UIScrollView scrollView = UIScrollView.fromWebView( + this, + binaryMessenger: _webViewApi.binaryMessenger, + instanceManager: _webViewApi.instanceManager, + ); + + @override + WKWebView copy() { + return WKWebViewIOS.detached( + observeValue: observeValue, + binaryMessenger: _webViewApi.binaryMessenger, + instanceManager: _webViewApi.instanceManager, + ); } + final UIViewHostApiImpl _viewApi; + + // UIView implementations. This is duplicated from the UIViewBase class since + // WKWebView can't inherit from UIView, so this is a workaround to multiple + // inheritance limitations. This is a way of dealing with the lack of + // preprocessor in Dart, which is how the native side has different base + // classes. If the amount of code here grows, this could become a mixin used + // by both UIViewBase and this class (at the cost of exposing the view API + // object, or adjusting files to allow it to stay private). + @override + Future setBackgroundColor(Color? color) { + return _viewApi.setBackgroundColorForInstances(this, color); + } + + @override + Future setOpaque(bool opaque) { + return _viewApi.setOpaqueForInstances(this, opaque); + } +} + +/// The macOS version of a WKWebView. +class WKWebViewMacOS extends WKWebView { + /// Constructs a new macOS WKWebView; see [WKWebView] for details. + WKWebViewMacOS( + super.configuration, { + super.observeValue, + super.binaryMessenger, + super.instanceManager, + }) : super(); + + /// See [WKWebView.detached]. + WKWebViewMacOS.detached({ + super.observeValue, + super.binaryMessenger, + super.instanceManager, + }) : super.detached(); + @override WKWebView copy() { - return WKWebView.detached( + return WKWebViewMacOS.detached( observeValue: observeValue, binaryMessenger: _webViewApi.binaryMessenger, instanceManager: _webViewApi.instanceManager, diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/web_kit/web_kit_api_impls.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/web_kit/web_kit_api_impls.dart index bdcc19eafd6b..1caa1ccc5b09 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/web_kit/web_kit_api_impls.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/web_kit/web_kit_api_impls.dart @@ -301,23 +301,23 @@ class WebKitFlutterApis { /// Ensures all the Flutter APIs have been set up to receive calls from native code. void ensureSetUp() { if (!_hasBeenSetUp) { - WKNavigationDelegateFlutterApi.setup( + WKNavigationDelegateFlutterApi.setUp( navigationDelegate, binaryMessenger: _binaryMessenger, ); - WKScriptMessageHandlerFlutterApi.setup( + WKScriptMessageHandlerFlutterApi.setUp( scriptMessageHandler, binaryMessenger: _binaryMessenger, ); - WKUIDelegateFlutterApi.setup( + WKUIDelegateFlutterApi.setUp( uiDelegate, binaryMessenger: _binaryMessenger, ); - WKWebViewConfigurationFlutterApi.setup( + WKWebViewConfigurationFlutterApi.setUp( webViewConfiguration, binaryMessenger: _binaryMessenger, ); - UIScrollViewDelegateFlutterApi.setup(uiScrollViewDelegate, + UIScrollViewDelegateFlutterApi.setUp(uiScrollViewDelegate, binaryMessenger: _binaryMessenger); _hasBeenSetUp = true; } diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/webkit_proxy.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/webkit_proxy.dart index ffd9b845eab6..82277babadee 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/webkit_proxy.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/webkit_proxy.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:io'; + import 'common/instance_manager.dart'; import 'foundation/foundation.dart'; import 'ui_kit/ui_kit.dart'; @@ -12,6 +14,24 @@ import 'web_kit/web_kit.dart'; WKWebsiteDataStore _defaultWebsiteDataStore() => WKWebsiteDataStore.defaultDataStore; +// This convenience method was added because Dart doesn't support constant +// function literals: https://github.com/dart-lang/language/issues/1048. +WKWebView _platformWebViewConstructor( + WKWebViewConfiguration configuration, { + void Function( + String keyPath, + NSObject object, + Map change, + )? observeValue, + InstanceManager? instanceManager, +}) { + return Platform.isIOS + ? WKWebViewIOS(configuration, + observeValue: observeValue, instanceManager: instanceManager) + : WKWebViewMacOS(configuration, + observeValue: observeValue, instanceManager: instanceManager); +} + /// Handles constructing objects and calling static methods for the WebKit /// native library. /// @@ -24,7 +44,7 @@ WKWebsiteDataStore _defaultWebsiteDataStore() => class WebKitProxy { /// Constructs a [WebKitProxy]. const WebKitProxy({ - this.createWebView = WKWebView.new, + this.createWebView = _platformWebViewConstructor, this.createWebViewConfiguration = WKWebViewConfiguration.new, this.createScriptMessageHandler = WKScriptMessageHandler.new, this.defaultWebsiteDataStore = _defaultWebsiteDataStore, diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/webkit_webview_controller.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/webkit_webview_controller.dart index c152f3262599..a1f149ecdd10 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/webkit_webview_controller.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/webkit_webview_controller.dart @@ -4,6 +4,7 @@ import 'dart:async'; import 'dart:convert'; +import 'dart:io'; import 'dart:math'; import 'package:flutter/material.dart'; @@ -490,24 +491,42 @@ class WebKitWebViewController extends PlatformWebViewController { @override Future scrollTo(int x, int y) { - return _webView.scrollView.setContentOffset(Point( - x.toDouble(), - y.toDouble(), - )); + final WKWebView webView = _webView; + if (webView is WKWebViewIOS) { + return webView.scrollView.setContentOffset(Point( + x.toDouble(), + y.toDouble(), + )); + } else { + // TODO(stuartmorgan): Investigate doing this via JS instead. + throw UnimplementedError('scrollTo is not implemented on macOS'); + } } @override Future scrollBy(int x, int y) { - return _webView.scrollView.scrollBy(Point( - x.toDouble(), - y.toDouble(), - )); + final WKWebView webView = _webView; + if (webView is WKWebViewIOS) { + return webView.scrollView.scrollBy(Point( + x.toDouble(), + y.toDouble(), + )); + } else { + // TODO(stuartmorgan): Investigate doing this via JS instead. + throw UnimplementedError('scrollBy is not implemented on macOS'); + } } @override Future getScrollPosition() async { - final Point offset = await _webView.scrollView.getContentOffset(); - return Offset(offset.x, offset.y); + final WKWebView webView = _webView; + if (webView is WKWebViewIOS) { + final Point offset = await webView.scrollView.getContentOffset(); + return Offset(offset.x, offset.y); + } else { + // TODO(stuartmorgan): Investigate doing this via JS instead. + throw UnimplementedError('scrollTo is not implemented on macOS'); + } } /// Whether horizontal swipe gestures trigger page navigation. @@ -517,12 +536,19 @@ class WebKitWebViewController extends PlatformWebViewController { @override Future setBackgroundColor(Color color) { - return Future.wait(>[ - _webView.setOpaque(false), - _webView.setBackgroundColor(Colors.transparent), - // This method must be called last. - _webView.scrollView.setBackgroundColor(color), - ]); + final WKWebView webView = _webView; + if (webView is WKWebViewIOS) { + return Future.wait(>[ + webView.setOpaque(false), + webView.setBackgroundColor(Colors.transparent), + // This method must be called last. + webView.scrollView.setBackgroundColor(color), + ]); + } else { + // TODO(stuartmorgan): Implement background color support. + throw UnimplementedError( + 'Background color is not yet supported on macOS.'); + } } @override @@ -614,7 +640,6 @@ class WebKitWebViewController extends PlatformWebViewController { case 'log': default: level = JavaScriptLogLevel.log; - break; } _onConsoleMessageCallback!( @@ -744,23 +769,30 @@ window.addEventListener("error", function(e) { Future setOnScrollPositionChange( void Function(ScrollPositionChange scrollPositionChange)? onScrollPositionChange) async { - _onScrollPositionChangeCallback = onScrollPositionChange; - - if (onScrollPositionChange != null) { - final WeakReference weakThis = - WeakReference(this); - _uiScrollViewDelegate = - _webKitParams.webKitProxy.createUIScrollViewDelegate( - scrollViewDidScroll: (UIScrollView uiScrollView, double x, double y) { - weakThis.target?._onScrollPositionChangeCallback?.call( - ScrollPositionChange(x, y), - ); - }, - ); - return _webView.scrollView.setDelegate(_uiScrollViewDelegate); + final WKWebView webView = _webView; + if (webView is WKWebViewIOS) { + _onScrollPositionChangeCallback = onScrollPositionChange; + + if (onScrollPositionChange != null) { + final WeakReference weakThis = + WeakReference(this); + _uiScrollViewDelegate = + _webKitParams.webKitProxy.createUIScrollViewDelegate( + scrollViewDidScroll: (UIScrollView uiScrollView, double x, double y) { + weakThis.target?._onScrollPositionChangeCallback?.call( + ScrollPositionChange(x, y), + ); + }, + ); + return webView.scrollView.setDelegate(_uiScrollViewDelegate); + } else { + _uiScrollViewDelegate = null; + return webView.scrollView.setDelegate(null); + } } else { - _uiScrollViewDelegate = null; - return _webView.scrollView.setDelegate(null); + // TODO(stuartmorgan): Investigate doing this via JS instead. + throw UnimplementedError( + 'setOnScrollPositionChange is not implemented on macOS'); } } @@ -917,20 +949,34 @@ class WebKitWebViewWidget extends PlatformWebViewWidget { @override Widget build(BuildContext context) { - return UiKitView( - // Setting a default key using `params` ensures the `UIKitView` recreates - // the PlatformView when changes are made. - key: _webKitParams.key ?? - ValueKey( - params as WebKitWebViewWidgetCreationParams), - viewType: 'plugins.flutter.io/webview', - onPlatformViewCreated: (_) {}, - layoutDirection: params.layoutDirection, - gestureRecognizers: params.gestureRecognizers, - creationParams: _webKitParams._instanceManager.getIdentifier( - (params.controller as WebKitWebViewController)._webView), - creationParamsCodec: const StandardMessageCodec(), - ); + // Setting a default key using `params` ensures the `UIKitView` recreates + // the PlatformView when changes are made. + final Key key = _webKitParams.key ?? + ValueKey( + params as WebKitWebViewWidgetCreationParams); + if (Platform.isMacOS) { + return AppKitView( + key: key, + viewType: 'plugins.flutter.io/webview', + onPlatformViewCreated: (_) {}, + layoutDirection: params.layoutDirection, + gestureRecognizers: params.gestureRecognizers, + creationParams: _webKitParams._instanceManager.getIdentifier( + (params.controller as WebKitWebViewController)._webView), + creationParamsCodec: const StandardMessageCodec(), + ); + } else { + return UiKitView( + key: key, + viewType: 'plugins.flutter.io/webview', + onPlatformViewCreated: (_) {}, + layoutDirection: params.layoutDirection, + gestureRecognizers: params.gestureRecognizers, + creationParams: _webKitParams._instanceManager.getIdentifier( + (params.controller as WebKitWebViewController)._webView), + creationParamsCodec: const StandardMessageCodec(), + ); + } } } @@ -1101,7 +1147,9 @@ class WebKitNavigationDelegate extends PlatformNavigationDelegate { ) completionHandler, ) { if (challenge.protectionSpace.authenticationMethod == - NSUrlAuthenticationMethod.httpBasic) { + NSUrlAuthenticationMethod.httpBasic || + challenge.protectionSpace.authenticationMethod == + NSUrlAuthenticationMethod.httpNtlm) { final void Function(HttpAuthRequest)? callback = weakThis.target?._onHttpAuthRequest; final String? host = challenge.protectionSpace.host; diff --git a/packages/webview_flutter/webview_flutter_wkwebview/pigeons/web_kit.dart b/packages/webview_flutter/webview_flutter_wkwebview/pigeons/web_kit.dart index e660db3ef898..a7d2fbd488d2 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/pigeons/web_kit.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/pigeons/web_kit.dart @@ -8,10 +8,13 @@ import 'package:pigeon/pigeon.dart'; PigeonOptions( dartOut: 'lib/src/common/web_kit.g.dart', dartTestOut: 'test/src/common/test_web_kit.g.dart', - objcHeaderOut: 'ios/Classes/FWFGeneratedWebKitApis.h', - objcSourceOut: 'ios/Classes/FWFGeneratedWebKitApis.m', + objcHeaderOut: + 'darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFGeneratedWebKitApis.h', + objcSourceOut: + 'darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFGeneratedWebKitApis.m', objcOptions: ObjcOptions( - headerIncludePath: 'ios/Classes/FWFGeneratedWebKitApis.h', + headerIncludePath: + './include/webview_flutter_wkwebview/FWFGeneratedWebKitApis.h', prefix: 'FWF', ), copyrightHeader: 'pigeons/copyright.txt', diff --git a/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml b/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml index 51d28e2191c6..b07e68045fe1 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml @@ -2,11 +2,11 @@ name: webview_flutter_wkwebview description: A Flutter plugin that provides a WebView widget based on Apple's WKWebView control. repository: https://github.com/flutter/packages/tree/main/packages/webview_flutter/webview_flutter_wkwebview issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22 -version: 3.13.1 +version: 3.16.1 environment: - sdk: ^3.2.3 - flutter: ">=3.16.6" + sdk: ^3.5.0 + flutter: ">=3.24.0" flutter: plugin: @@ -15,6 +15,11 @@ flutter: ios: pluginClass: FLTWebViewFlutterPlugin dartPluginClass: WebKitWebViewPlatform + sharedDarwinSource: true + macos: + pluginClass: FLTWebViewFlutterPlugin + dartPluginClass: WebKitWebViewPlatform + sharedDarwinSource: true dependencies: flutter: @@ -26,8 +31,8 @@ dev_dependencies: build_runner: ^2.1.5 flutter_test: sdk: flutter - mockito: 5.4.4 - pigeon: ^13.0.0 + mockito: ^5.4.4 + pigeon: ^18.0.0 topics: - html diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/legacy/web_kit_cookie_manager_test.mocks.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/legacy/web_kit_cookie_manager_test.mocks.dart index eb58b7eb11e2..fe13a87048e5 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/legacy/web_kit_cookie_manager_test.mocks.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/legacy/web_kit_cookie_manager_test.mocks.dart @@ -63,6 +63,7 @@ class MockWKHttpCookieStore extends _i1.Mock implements _i2.WKHttpCookieStore { returnValue: _i3.Future.value(), returnValueForMissingStub: _i3.Future.value(), ) as _i3.Future); + @override _i2.WKHttpCookieStore copy() => (super.noSuchMethod( Invocation.method( @@ -77,6 +78,7 @@ class MockWKHttpCookieStore extends _i1.Mock implements _i2.WKHttpCookieStore { ), ), ) as _i2.WKHttpCookieStore); + @override _i3.Future addObserver( _i4.NSObject? observer, { @@ -95,6 +97,7 @@ class MockWKHttpCookieStore extends _i1.Mock implements _i2.WKHttpCookieStore { returnValue: _i3.Future.value(), returnValueForMissingStub: _i3.Future.value(), ) as _i3.Future); + @override _i3.Future removeObserver( _i4.NSObject? observer, { @@ -129,6 +132,7 @@ class MockWKWebsiteDataStore extends _i1.Mock Invocation.getter(#httpCookieStore), ), ) as _i2.WKHttpCookieStore); + @override _i3.Future removeDataOfTypes( Set<_i2.WKWebsiteDataType>? dataTypes, @@ -144,6 +148,7 @@ class MockWKWebsiteDataStore extends _i1.Mock ), returnValue: _i3.Future.value(false), ) as _i3.Future); + @override _i2.WKWebsiteDataStore copy() => (super.noSuchMethod( Invocation.method( @@ -158,6 +163,7 @@ class MockWKWebsiteDataStore extends _i1.Mock ), ), ) as _i2.WKWebsiteDataStore); + @override _i3.Future addObserver( _i4.NSObject? observer, { @@ -176,6 +182,7 @@ class MockWKWebsiteDataStore extends _i1.Mock returnValue: _i3.Future.value(), returnValueForMissingStub: _i3.Future.value(), ) as _i3.Future); + @override _i3.Future removeObserver( _i4.NSObject? observer, { diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/legacy/web_kit_webview_widget_test.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/legacy/web_kit_webview_widget_test.dart index b5488a0e3931..ac2f19804ffd 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/legacy/web_kit_webview_widget_test.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/legacy/web_kit_webview_widget_test.dart @@ -23,7 +23,8 @@ import 'web_kit_webview_widget_test.mocks.dart'; WKNavigationDelegate, WKPreferences, WKScriptMessageHandler, - WKWebView, + WKWebViewIOS, + WKWebViewMacOS, WKWebViewConfiguration, WKWebsiteDataStore, WKUIDelegate, @@ -38,7 +39,7 @@ void main() { group('WebKitWebViewWidget', () { _WebViewMocks configureMocks() { final _WebViewMocks mocks = _WebViewMocks( - webView: MockWKWebView(), + webView: MockWKWebViewIOS(), webViewWidgetProxy: MockWebViewWidgetProxy(), userContentController: MockWKUserContentController(), preferences: MockWKPreferences(), @@ -1375,7 +1376,7 @@ class _WebViewMocks { required this.javascriptChannelRegistry, }); - final MockWKWebView webView; + final MockWKWebViewIOS webView; final MockWebViewWidgetProxy webViewWidgetProxy; final MockWKUserContentController userContentController; final MockWKPreferences preferences; diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/legacy/web_kit_webview_widget_test.mocks.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/legacy/web_kit_webview_widget_test.mocks.dart index a33d5ac58302..0c8876b9df03 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/legacy/web_kit_webview_widget_test.mocks.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/legacy/web_kit_webview_widget_test.mocks.dart @@ -174,6 +174,7 @@ class MockUIScrollView extends _i1.Mock implements _i3.UIScrollView { ), )), ) as _i5.Future<_i2.Point>); + @override _i5.Future scrollBy(_i2.Point? offset) => (super.noSuchMethod( Invocation.method( @@ -183,6 +184,7 @@ class MockUIScrollView extends _i1.Mock implements _i3.UIScrollView { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future setContentOffset(_i2.Point? offset) => (super.noSuchMethod( @@ -193,6 +195,7 @@ class MockUIScrollView extends _i1.Mock implements _i3.UIScrollView { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future setDelegate(_i3.UIScrollViewDelegate? delegate) => (super.noSuchMethod( @@ -203,6 +206,7 @@ class MockUIScrollView extends _i1.Mock implements _i3.UIScrollView { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i3.UIScrollView copy() => (super.noSuchMethod( Invocation.method( @@ -217,6 +221,7 @@ class MockUIScrollView extends _i1.Mock implements _i3.UIScrollView { ), ), ) as _i3.UIScrollView); + @override _i5.Future setBackgroundColor(_i6.Color? color) => (super.noSuchMethod( Invocation.method( @@ -226,6 +231,7 @@ class MockUIScrollView extends _i1.Mock implements _i3.UIScrollView { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future setOpaque(bool? opaque) => (super.noSuchMethod( Invocation.method( @@ -235,6 +241,7 @@ class MockUIScrollView extends _i1.Mock implements _i3.UIScrollView { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future addObserver( _i7.NSObject? observer, { @@ -253,6 +260,7 @@ class MockUIScrollView extends _i1.Mock implements _i3.UIScrollView { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future removeObserver( _i7.NSObject? observer, { @@ -293,6 +301,7 @@ class MockWKNavigationDelegate extends _i1.Mock ), ), ) as _i4.WKNavigationDelegate); + @override _i5.Future addObserver( _i7.NSObject? observer, { @@ -311,6 +320,7 @@ class MockWKNavigationDelegate extends _i1.Mock returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future removeObserver( _i7.NSObject? observer, { @@ -345,6 +355,7 @@ class MockWKPreferences extends _i1.Mock implements _i4.WKPreferences { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i4.WKPreferences copy() => (super.noSuchMethod( Invocation.method( @@ -359,6 +370,7 @@ class MockWKPreferences extends _i1.Mock implements _i4.WKPreferences { ), ), ) as _i4.WKPreferences); + @override _i5.Future addObserver( _i7.NSObject? observer, { @@ -377,6 +389,7 @@ class MockWKPreferences extends _i1.Mock implements _i4.WKPreferences { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future removeObserver( _i7.NSObject? observer, { @@ -417,6 +430,7 @@ class MockWKScriptMessageHandler extends _i1.Mock _i4.WKUserContentController, _i4.WKScriptMessage, )); + @override _i4.WKScriptMessageHandler copy() => (super.noSuchMethod( Invocation.method( @@ -431,6 +445,7 @@ class MockWKScriptMessageHandler extends _i1.Mock ), ), ) as _i4.WKScriptMessageHandler); + @override _i5.Future addObserver( _i7.NSObject? observer, { @@ -449,6 +464,7 @@ class MockWKScriptMessageHandler extends _i1.Mock returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future removeObserver( _i7.NSObject? observer, { @@ -465,15 +481,23 @@ class MockWKScriptMessageHandler extends _i1.Mock ) as _i5.Future); } -/// A class which mocks [WKWebView]. +/// A class which mocks [WKWebViewIOS]. /// /// See the documentation for Mockito's code generation for more information. -// ignore: must_be_immutable -class MockWKWebView extends _i1.Mock implements _i4.WKWebView { - MockWKWebView() { +class MockWKWebViewIOS extends _i1.Mock implements _i4.WKWebViewIOS { + MockWKWebViewIOS() { _i1.throwOnMissingStub(this); } + @override + _i3.UIScrollView get scrollView => (super.noSuchMethod( + Invocation.getter(#scrollView), + returnValue: _FakeUIScrollView_1( + this, + Invocation.getter(#scrollView), + ), + ) as _i3.UIScrollView); + @override _i4.WKWebViewConfiguration get configuration => (super.noSuchMethod( Invocation.getter(#configuration), @@ -482,14 +506,42 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { Invocation.getter(#configuration), ), ) as _i4.WKWebViewConfiguration); + @override - _i3.UIScrollView get scrollView => (super.noSuchMethod( - Invocation.getter(#scrollView), - returnValue: _FakeUIScrollView_1( + _i4.WKWebView copy() => (super.noSuchMethod( + Invocation.method( + #copy, + [], + ), + returnValue: _FakeWKWebView_6( this, - Invocation.getter(#scrollView), + Invocation.method( + #copy, + [], + ), ), - ) as _i3.UIScrollView); + ) as _i4.WKWebView); + + @override + _i5.Future setBackgroundColor(_i6.Color? color) => (super.noSuchMethod( + Invocation.method( + #setBackgroundColor, + [color], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + + @override + _i5.Future setOpaque(bool? opaque) => (super.noSuchMethod( + Invocation.method( + #setOpaque, + [opaque], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + @override _i5.Future setUIDelegate(_i4.WKUIDelegate? delegate) => (super.noSuchMethod( @@ -500,6 +552,7 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future setNavigationDelegate(_i4.WKNavigationDelegate? delegate) => (super.noSuchMethod( @@ -510,6 +563,7 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future getUrl() => (super.noSuchMethod( Invocation.method( @@ -518,6 +572,7 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { ), returnValue: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future getEstimatedProgress() => (super.noSuchMethod( Invocation.method( @@ -526,6 +581,7 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { ), returnValue: _i5.Future.value(0.0), ) as _i5.Future); + @override _i5.Future loadRequest(_i7.NSUrlRequest? request) => (super.noSuchMethod( @@ -536,6 +592,7 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future loadHtmlString( String? string, { @@ -550,6 +607,7 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future loadFileUrl( String? url, { @@ -564,6 +622,7 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future loadFlutterAsset(String? key) => (super.noSuchMethod( Invocation.method( @@ -573,6 +632,7 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future canGoBack() => (super.noSuchMethod( Invocation.method( @@ -581,6 +641,7 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { ), returnValue: _i5.Future.value(false), ) as _i5.Future); + @override _i5.Future canGoForward() => (super.noSuchMethod( Invocation.method( @@ -589,6 +650,7 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { ), returnValue: _i5.Future.value(false), ) as _i5.Future); + @override _i5.Future goBack() => (super.noSuchMethod( Invocation.method( @@ -598,6 +660,7 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future goForward() => (super.noSuchMethod( Invocation.method( @@ -607,6 +670,7 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future reload() => (super.noSuchMethod( Invocation.method( @@ -616,6 +680,7 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future getTitle() => (super.noSuchMethod( Invocation.method( @@ -624,6 +689,16 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { ), returnValue: _i5.Future.value(), ) as _i5.Future); + + @override + _i5.Future getCustomUserAgent() => (super.noSuchMethod( + Invocation.method( + #getCustomUserAgent, + [], + ), + returnValue: _i5.Future.value(), + ) as _i5.Future); + @override _i5.Future setAllowsBackForwardNavigationGestures(bool? allow) => (super.noSuchMethod( @@ -634,6 +709,7 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future setCustomUserAgent(String? userAgent) => (super.noSuchMethod( Invocation.method( @@ -643,6 +719,7 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future evaluateJavaScript(String? javaScriptString) => (super.noSuchMethod( @@ -652,6 +729,7 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { ), returnValue: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future setInspectable(bool? inspectable) => (super.noSuchMethod( Invocation.method( @@ -661,14 +739,59 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override - _i5.Future getCustomUserAgent() => (super.noSuchMethod( + _i5.Future addObserver( + _i7.NSObject? observer, { + required String? keyPath, + required Set<_i7.NSKeyValueObservingOptions>? options, + }) => + (super.noSuchMethod( Invocation.method( - #getCustomUserAgent, - [], + #addObserver, + [observer], + { + #keyPath: keyPath, + #options: options, + }, ), - returnValue: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + + @override + _i5.Future removeObserver( + _i7.NSObject? observer, { + required String? keyPath, + }) => + (super.noSuchMethod( + Invocation.method( + #removeObserver, + [observer], + {#keyPath: keyPath}, + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); +} + +/// A class which mocks [WKWebViewMacOS]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockWKWebViewMacOS extends _i1.Mock implements _i4.WKWebViewMacOS { + MockWKWebViewMacOS() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.WKWebViewConfiguration get configuration => (super.noSuchMethod( + Invocation.getter(#configuration), + returnValue: _FakeWKWebViewConfiguration_5( + this, + Invocation.getter(#configuration), + ), + ) as _i4.WKWebViewConfiguration); + @override _i4.WKWebView copy() => (super.noSuchMethod( Invocation.method( @@ -683,24 +806,205 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { ), ), ) as _i4.WKWebView); + @override - _i5.Future setBackgroundColor(_i6.Color? color) => (super.noSuchMethod( + _i5.Future setUIDelegate(_i4.WKUIDelegate? delegate) => + (super.noSuchMethod( Invocation.method( - #setBackgroundColor, - [color], + #setUIDelegate, + [delegate], ), returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override - _i5.Future setOpaque(bool? opaque) => (super.noSuchMethod( + _i5.Future setNavigationDelegate(_i4.WKNavigationDelegate? delegate) => + (super.noSuchMethod( Invocation.method( - #setOpaque, - [opaque], + #setNavigationDelegate, + [delegate], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + + @override + _i5.Future getUrl() => (super.noSuchMethod( + Invocation.method( + #getUrl, + [], + ), + returnValue: _i5.Future.value(), + ) as _i5.Future); + + @override + _i5.Future getEstimatedProgress() => (super.noSuchMethod( + Invocation.method( + #getEstimatedProgress, + [], + ), + returnValue: _i5.Future.value(0.0), + ) as _i5.Future); + + @override + _i5.Future loadRequest(_i7.NSUrlRequest? request) => + (super.noSuchMethod( + Invocation.method( + #loadRequest, + [request], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + + @override + _i5.Future loadHtmlString( + String? string, { + String? baseUrl, + }) => + (super.noSuchMethod( + Invocation.method( + #loadHtmlString, + [string], + {#baseUrl: baseUrl}, + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + + @override + _i5.Future loadFileUrl( + String? url, { + required String? readAccessUrl, + }) => + (super.noSuchMethod( + Invocation.method( + #loadFileUrl, + [url], + {#readAccessUrl: readAccessUrl}, + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + + @override + _i5.Future loadFlutterAsset(String? key) => (super.noSuchMethod( + Invocation.method( + #loadFlutterAsset, + [key], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + + @override + _i5.Future canGoBack() => (super.noSuchMethod( + Invocation.method( + #canGoBack, + [], + ), + returnValue: _i5.Future.value(false), + ) as _i5.Future); + + @override + _i5.Future canGoForward() => (super.noSuchMethod( + Invocation.method( + #canGoForward, + [], + ), + returnValue: _i5.Future.value(false), + ) as _i5.Future); + + @override + _i5.Future goBack() => (super.noSuchMethod( + Invocation.method( + #goBack, + [], ), returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + + @override + _i5.Future goForward() => (super.noSuchMethod( + Invocation.method( + #goForward, + [], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + + @override + _i5.Future reload() => (super.noSuchMethod( + Invocation.method( + #reload, + [], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + + @override + _i5.Future getTitle() => (super.noSuchMethod( + Invocation.method( + #getTitle, + [], + ), + returnValue: _i5.Future.value(), + ) as _i5.Future); + + @override + _i5.Future getCustomUserAgent() => (super.noSuchMethod( + Invocation.method( + #getCustomUserAgent, + [], + ), + returnValue: _i5.Future.value(), + ) as _i5.Future); + + @override + _i5.Future setAllowsBackForwardNavigationGestures(bool? allow) => + (super.noSuchMethod( + Invocation.method( + #setAllowsBackForwardNavigationGestures, + [allow], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + + @override + _i5.Future setCustomUserAgent(String? userAgent) => (super.noSuchMethod( + Invocation.method( + #setCustomUserAgent, + [userAgent], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + + @override + _i5.Future evaluateJavaScript(String? javaScriptString) => + (super.noSuchMethod( + Invocation.method( + #evaluateJavaScript, + [javaScriptString], + ), + returnValue: _i5.Future.value(), + ) as _i5.Future); + + @override + _i5.Future setInspectable(bool? inspectable) => (super.noSuchMethod( + Invocation.method( + #setInspectable, + [inspectable], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + @override _i5.Future addObserver( _i7.NSObject? observer, { @@ -719,6 +1023,7 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future removeObserver( _i7.NSObject? observer, { @@ -753,6 +1058,7 @@ class MockWKWebViewConfiguration extends _i1.Mock Invocation.getter(#userContentController), ), ) as _i4.WKUserContentController); + @override _i4.WKPreferences get preferences => (super.noSuchMethod( Invocation.getter(#preferences), @@ -761,6 +1067,7 @@ class MockWKWebViewConfiguration extends _i1.Mock Invocation.getter(#preferences), ), ) as _i4.WKPreferences); + @override _i4.WKWebsiteDataStore get websiteDataStore => (super.noSuchMethod( Invocation.getter(#websiteDataStore), @@ -769,6 +1076,7 @@ class MockWKWebViewConfiguration extends _i1.Mock Invocation.getter(#websiteDataStore), ), ) as _i4.WKWebsiteDataStore); + @override _i5.Future setAllowsInlineMediaPlayback(bool? allow) => (super.noSuchMethod( @@ -779,6 +1087,7 @@ class MockWKWebViewConfiguration extends _i1.Mock returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future setLimitsNavigationsToAppBoundDomains(bool? limit) => (super.noSuchMethod( @@ -789,6 +1098,7 @@ class MockWKWebViewConfiguration extends _i1.Mock returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future setMediaTypesRequiringUserActionForPlayback( Set<_i4.WKAudiovisualMediaType>? types) => @@ -800,6 +1110,7 @@ class MockWKWebViewConfiguration extends _i1.Mock returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i4.WKWebViewConfiguration copy() => (super.noSuchMethod( Invocation.method( @@ -814,6 +1125,7 @@ class MockWKWebViewConfiguration extends _i1.Mock ), ), ) as _i4.WKWebViewConfiguration); + @override _i5.Future addObserver( _i7.NSObject? observer, { @@ -832,6 +1144,7 @@ class MockWKWebViewConfiguration extends _i1.Mock returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future removeObserver( _i7.NSObject? observer, { @@ -866,6 +1179,7 @@ class MockWKWebsiteDataStore extends _i1.Mock Invocation.getter(#httpCookieStore), ), ) as _i4.WKHttpCookieStore); + @override _i5.Future removeDataOfTypes( Set<_i4.WKWebsiteDataType>? dataTypes, @@ -881,6 +1195,7 @@ class MockWKWebsiteDataStore extends _i1.Mock ), returnValue: _i5.Future.value(false), ) as _i5.Future); + @override _i4.WKWebsiteDataStore copy() => (super.noSuchMethod( Invocation.method( @@ -895,6 +1210,7 @@ class MockWKWebsiteDataStore extends _i1.Mock ), ), ) as _i4.WKWebsiteDataStore); + @override _i5.Future addObserver( _i7.NSObject? observer, { @@ -913,6 +1229,7 @@ class MockWKWebsiteDataStore extends _i1.Mock returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future removeObserver( _i7.NSObject? observer, { @@ -952,6 +1269,7 @@ class MockWKUIDelegate extends _i1.Mock implements _i4.WKUIDelegate { ), ), ) as _i4.WKUIDelegate); + @override _i5.Future addObserver( _i7.NSObject? observer, { @@ -970,6 +1288,7 @@ class MockWKUIDelegate extends _i1.Mock implements _i4.WKUIDelegate { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future removeObserver( _i7.NSObject? observer, { @@ -1012,6 +1331,7 @@ class MockWKUserContentController extends _i1.Mock returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future removeScriptMessageHandler(String? name) => (super.noSuchMethod( @@ -1022,6 +1342,7 @@ class MockWKUserContentController extends _i1.Mock returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future removeAllScriptMessageHandlers() => (super.noSuchMethod( Invocation.method( @@ -1031,6 +1352,7 @@ class MockWKUserContentController extends _i1.Mock returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future addUserScript(_i4.WKUserScript? userScript) => (super.noSuchMethod( @@ -1041,6 +1363,7 @@ class MockWKUserContentController extends _i1.Mock returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future removeAllUserScripts() => (super.noSuchMethod( Invocation.method( @@ -1050,6 +1373,7 @@ class MockWKUserContentController extends _i1.Mock returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i4.WKUserContentController copy() => (super.noSuchMethod( Invocation.method( @@ -1064,6 +1388,7 @@ class MockWKUserContentController extends _i1.Mock ), ), ) as _i4.WKUserContentController); + @override _i5.Future addObserver( _i7.NSObject? observer, { @@ -1082,6 +1407,7 @@ class MockWKUserContentController extends _i1.Mock returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future removeObserver( _i7.NSObject? observer, { @@ -1112,6 +1438,7 @@ class MockJavascriptChannelRegistry extends _i1.Mock Invocation.getter(#channels), returnValue: {}, ) as Map); + @override void onJavascriptChannelMessage( String? channel, @@ -1127,6 +1454,7 @@ class MockJavascriptChannelRegistry extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void updateJavascriptChannelsFromSet(Set<_i9.JavascriptChannel>? channels) => super.noSuchMethod( @@ -1163,6 +1491,7 @@ class MockWebViewPlatformCallbacksHandler extends _i1.Mock ), returnValue: _i5.Future.value(false), ) as _i5.FutureOr); + @override void onPageStarted(String? url) => super.noSuchMethod( Invocation.method( @@ -1171,6 +1500,7 @@ class MockWebViewPlatformCallbacksHandler extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void onPageFinished(String? url) => super.noSuchMethod( Invocation.method( @@ -1179,6 +1509,7 @@ class MockWebViewPlatformCallbacksHandler extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void onProgress(int? progress) => super.noSuchMethod( Invocation.method( @@ -1187,6 +1518,7 @@ class MockWebViewPlatformCallbacksHandler extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void onWebResourceError(_i10.WebResourceError? error) => super.noSuchMethod( Invocation.method( @@ -1230,6 +1562,7 @@ class MockWebViewWidgetProxy extends _i1.Mock ), ), ) as _i4.WKWebView); + @override _i4.WKScriptMessageHandler createScriptMessageHandler( {required void Function( @@ -1251,6 +1584,7 @@ class MockWebViewWidgetProxy extends _i1.Mock ), ), ) as _i4.WKScriptMessageHandler); + @override _i4.WKUIDelegate createUIDelgate( {void Function( @@ -1273,6 +1607,7 @@ class MockWebViewWidgetProxy extends _i1.Mock ), ), ) as _i4.WKUIDelegate); + @override _i4.WKNavigationDelegate createNavigationDelegate({ void Function( diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/src/common/test_web_kit.g.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/src/common/test_web_kit.g.dart index 982b50810e6e..0a9e645fecd0 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/src/common/test_web_kit.g.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/src/common/test_web_kit.g.dart @@ -1,9 +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 (v13.0.0), do not edit directly. +// Autogenerated from Pigeon (v18.0.0), 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, unnecessary_import +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import, no_leading_underscores_for_local_identifiers // ignore_for_file: avoid_relative_lib_imports import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; @@ -42,7 +42,7 @@ class _TestWKWebsiteDataStoreHostApiCodec extends StandardMessageCodec { abstract class TestWKWebsiteDataStoreHostApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec codec = + static const MessageCodec pigeonChannelCodec = _TestWKWebsiteDataStoreHostApiCodec(); void createFromWebViewConfiguration( @@ -55,19 +55,25 @@ abstract class TestWKWebsiteDataStoreHostApi { List dataTypes, double modificationTimeInSecondsSinceEpoch); - static void setup(TestWKWebsiteDataStoreHostApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + TestWKWebsiteDataStoreHostApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebsiteDataStoreHostApi.createFromWebViewConfiguration', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebsiteDataStoreHostApi.createFromWebViewConfiguration$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebsiteDataStoreHostApi.createFromWebViewConfiguration was null.'); @@ -92,16 +98,17 @@ abstract class TestWKWebsiteDataStoreHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebsiteDataStoreHostApi.createDefaultDataStore', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebsiteDataStoreHostApi.createDefaultDataStore$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebsiteDataStoreHostApi.createDefaultDataStore was null.'); @@ -122,16 +129,17 @@ abstract class TestWKWebsiteDataStoreHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebsiteDataStoreHostApi.removeDataOfTypes', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebsiteDataStoreHostApi.removeDataOfTypes$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebsiteDataStoreHostApi.removeDataOfTypes was null.'); @@ -169,25 +177,32 @@ abstract class TestWKWebsiteDataStoreHostApi { abstract class TestUIViewHostApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec codec = StandardMessageCodec(); + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); void setBackgroundColor(int identifier, int? value); void setOpaque(int identifier, bool opaque); - static void setup(TestUIViewHostApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + TestUIViewHostApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.UIViewHostApi.setBackgroundColor', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.UIViewHostApi.setBackgroundColor$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.UIViewHostApi.setBackgroundColor was null.'); @@ -209,16 +224,17 @@ abstract class TestUIViewHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.UIViewHostApi.setOpaque', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.UIViewHostApi.setOpaque$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.UIViewHostApi.setOpaque was null.'); @@ -250,7 +266,8 @@ abstract class TestUIViewHostApi { abstract class TestUIScrollViewHostApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec codec = StandardMessageCodec(); + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); void createFromWebView(int identifier, int webViewIdentifier); @@ -262,19 +279,25 @@ abstract class TestUIScrollViewHostApi { void setDelegate(int identifier, int? uiScrollViewDelegateIdentifier); - static void setup(TestUIScrollViewHostApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + TestUIScrollViewHostApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.createFromWebView', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.createFromWebView$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.createFromWebView was null.'); @@ -298,16 +321,17 @@ abstract class TestUIScrollViewHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.getContentOffset', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.getContentOffset$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.getContentOffset was null.'); @@ -328,16 +352,17 @@ abstract class TestUIScrollViewHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.scrollBy', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.scrollBy$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.scrollBy was null.'); @@ -364,16 +389,17 @@ abstract class TestUIScrollViewHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.setContentOffset', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.setContentOffset$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.setContentOffset was null.'); @@ -400,16 +426,17 @@ abstract class TestUIScrollViewHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.setDelegate', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.setDelegate$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.setDelegate was null.'); @@ -463,7 +490,7 @@ class _TestWKWebViewConfigurationHostApiCodec extends StandardMessageCodec { abstract class TestWKWebViewConfigurationHostApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec codec = + static const MessageCodec pigeonChannelCodec = _TestWKWebViewConfigurationHostApiCodec(); void create(int identifier); @@ -477,19 +504,25 @@ abstract class TestWKWebViewConfigurationHostApi { void setMediaTypesRequiringUserActionForPlayback( int identifier, List types); - static void setup(TestWKWebViewConfigurationHostApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + TestWKWebViewConfigurationHostApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.create', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.create$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.create was null.'); @@ -510,16 +543,17 @@ abstract class TestWKWebViewConfigurationHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.createFromWebView', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.createFromWebView$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.createFromWebView was null.'); @@ -543,16 +577,17 @@ abstract class TestWKWebViewConfigurationHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.setAllowsInlineMediaPlayback', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.setAllowsInlineMediaPlayback$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.setAllowsInlineMediaPlayback was null.'); @@ -576,16 +611,17 @@ abstract class TestWKWebViewConfigurationHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.setLimitsNavigationsToAppBoundDomains', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.setLimitsNavigationsToAppBoundDomains$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.setLimitsNavigationsToAppBoundDomains was null.'); @@ -610,16 +646,17 @@ abstract class TestWKWebViewConfigurationHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.setMediaTypesRequiringUserActionForPlayback', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.setMediaTypesRequiringUserActionForPlayback$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewConfigurationHostApi.setMediaTypesRequiringUserActionForPlayback was null.'); @@ -682,7 +719,7 @@ class _TestWKUserContentControllerHostApiCodec extends StandardMessageCodec { abstract class TestWKUserContentControllerHostApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec codec = + static const MessageCodec pigeonChannelCodec = _TestWKUserContentControllerHostApiCodec(); void createFromWebViewConfiguration( @@ -699,19 +736,25 @@ abstract class TestWKUserContentControllerHostApi { void removeAllUserScripts(int identifier); - static void setup(TestWKUserContentControllerHostApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + TestWKUserContentControllerHostApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.createFromWebViewConfiguration', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.createFromWebViewConfiguration$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.createFromWebViewConfiguration was null.'); @@ -736,16 +779,17 @@ abstract class TestWKUserContentControllerHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.addScriptMessageHandler', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.addScriptMessageHandler$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.addScriptMessageHandler was null.'); @@ -773,16 +817,17 @@ abstract class TestWKUserContentControllerHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.removeScriptMessageHandler', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.removeScriptMessageHandler$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.removeScriptMessageHandler was null.'); @@ -806,16 +851,17 @@ abstract class TestWKUserContentControllerHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.removeAllScriptMessageHandlers', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.removeAllScriptMessageHandlers$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.removeAllScriptMessageHandlers was null.'); @@ -836,16 +882,17 @@ abstract class TestWKUserContentControllerHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.addUserScript', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.addUserScript$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.addUserScript was null.'); @@ -870,16 +917,17 @@ abstract class TestWKUserContentControllerHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.removeAllUserScripts', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.removeAllUserScripts$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKUserContentControllerHostApi.removeAllUserScripts was null.'); @@ -908,26 +956,33 @@ abstract class TestWKUserContentControllerHostApi { abstract class TestWKPreferencesHostApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec codec = StandardMessageCodec(); + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); void createFromWebViewConfiguration( int identifier, int configurationIdentifier); void setJavaScriptEnabled(int identifier, bool enabled); - static void setup(TestWKPreferencesHostApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + TestWKPreferencesHostApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKPreferencesHostApi.createFromWebViewConfiguration', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKPreferencesHostApi.createFromWebViewConfiguration$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKPreferencesHostApi.createFromWebViewConfiguration was null.'); @@ -952,16 +1007,17 @@ abstract class TestWKPreferencesHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKPreferencesHostApi.setJavaScriptEnabled', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKPreferencesHostApi.setJavaScriptEnabled$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKPreferencesHostApi.setJavaScriptEnabled was null.'); @@ -993,23 +1049,30 @@ abstract class TestWKPreferencesHostApi { abstract class TestWKScriptMessageHandlerHostApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec codec = StandardMessageCodec(); + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); void create(int identifier); - static void setup(TestWKScriptMessageHandlerHostApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + TestWKScriptMessageHandlerHostApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKScriptMessageHandlerHostApi.create', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKScriptMessageHandlerHostApi.create$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKScriptMessageHandlerHostApi.create was null.'); @@ -1038,23 +1101,30 @@ abstract class TestWKScriptMessageHandlerHostApi { abstract class TestWKNavigationDelegateHostApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec codec = StandardMessageCodec(); + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); void create(int identifier); - static void setup(TestWKNavigationDelegateHostApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + TestWKNavigationDelegateHostApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateHostApi.create', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateHostApi.create$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKNavigationDelegateHostApi.create was null.'); @@ -1106,7 +1176,8 @@ class _TestNSObjectHostApiCodec extends StandardMessageCodec { abstract class TestNSObjectHostApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec codec = _TestNSObjectHostApiCodec(); + static const MessageCodec pigeonChannelCodec = + _TestNSObjectHostApiCodec(); void dispose(int identifier); @@ -1115,19 +1186,25 @@ abstract class TestNSObjectHostApi { void removeObserver(int identifier, int observerIdentifier, String keyPath); - static void setup(TestNSObjectHostApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + TestNSObjectHostApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectHostApi.dispose', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectHostApi.dispose$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectHostApi.dispose was null.'); @@ -1148,16 +1225,17 @@ abstract class TestNSObjectHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectHostApi.addObserver', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectHostApi.addObserver$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectHostApi.addObserver was null.'); @@ -1190,16 +1268,17 @@ abstract class TestNSObjectHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectHostApi.removeObserver', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectHostApi.removeObserver$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.NSObjectHostApi.removeObserver was null.'); @@ -1358,7 +1437,8 @@ class _TestWKWebViewHostApiCodec extends StandardMessageCodec { abstract class TestWKWebViewHostApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec codec = _TestWKWebViewHostApiCodec(); + static const MessageCodec pigeonChannelCodec = + _TestWKWebViewHostApiCodec(); void create(int identifier, int configurationIdentifier); @@ -1400,19 +1480,25 @@ abstract class TestWKWebViewHostApi { String? getCustomUserAgent(int identifier); - static void setup(TestWKWebViewHostApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + TestWKWebViewHostApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.create', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.create$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.create was null.'); @@ -1436,16 +1522,17 @@ abstract class TestWKWebViewHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setUIDelegate', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setUIDelegate$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setUIDelegate was null.'); @@ -1467,16 +1554,17 @@ abstract class TestWKWebViewHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setNavigationDelegate', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setNavigationDelegate$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setNavigationDelegate was null.'); @@ -1499,16 +1587,17 @@ abstract class TestWKWebViewHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.getUrl', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.getUrl$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.getUrl was null.'); @@ -1529,16 +1618,17 @@ abstract class TestWKWebViewHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.getEstimatedProgress', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.getEstimatedProgress$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.getEstimatedProgress was null.'); @@ -1559,16 +1649,17 @@ abstract class TestWKWebViewHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.loadRequest', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.loadRequest$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.loadRequest was null.'); @@ -1592,16 +1683,17 @@ abstract class TestWKWebViewHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.loadHtmlString', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.loadHtmlString$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.loadHtmlString was null.'); @@ -1626,16 +1718,17 @@ abstract class TestWKWebViewHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.loadFileUrl', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.loadFileUrl$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.loadFileUrl was null.'); @@ -1662,16 +1755,17 @@ abstract class TestWKWebViewHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.loadFlutterAsset', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.loadFlutterAsset$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.loadFlutterAsset was null.'); @@ -1695,16 +1789,17 @@ abstract class TestWKWebViewHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.canGoBack', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.canGoBack$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.canGoBack was null.'); @@ -1725,16 +1820,17 @@ abstract class TestWKWebViewHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.canGoForward', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.canGoForward$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.canGoForward was null.'); @@ -1755,16 +1851,17 @@ abstract class TestWKWebViewHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.goBack', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.goBack$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.goBack was null.'); @@ -1785,16 +1882,17 @@ abstract class TestWKWebViewHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.goForward', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.goForward$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.goForward was null.'); @@ -1815,16 +1913,17 @@ abstract class TestWKWebViewHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.reload', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.reload$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.reload was null.'); @@ -1845,16 +1944,17 @@ abstract class TestWKWebViewHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.getTitle', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.getTitle$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.getTitle was null.'); @@ -1875,16 +1975,17 @@ abstract class TestWKWebViewHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setAllowsBackForwardNavigationGestures', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setAllowsBackForwardNavigationGestures$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setAllowsBackForwardNavigationGestures was null.'); @@ -1909,16 +2010,17 @@ abstract class TestWKWebViewHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setCustomUserAgent', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setCustomUserAgent$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setCustomUserAgent was null.'); @@ -1940,16 +2042,17 @@ abstract class TestWKWebViewHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.evaluateJavaScript', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.evaluateJavaScript$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.evaluateJavaScript was null.'); @@ -1974,16 +2077,17 @@ abstract class TestWKWebViewHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setInspectable', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setInspectable$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.setInspectable was null.'); @@ -2007,16 +2111,17 @@ abstract class TestWKWebViewHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.getCustomUserAgent', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.getCustomUserAgent$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKWebViewHostApi.getCustomUserAgent was null.'); @@ -2045,23 +2150,30 @@ abstract class TestWKWebViewHostApi { abstract class TestWKUIDelegateHostApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec codec = StandardMessageCodec(); + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); void create(int identifier); - static void setup(TestWKUIDelegateHostApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + TestWKUIDelegateHostApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateHostApi.create', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateHostApi.create$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKUIDelegateHostApi.create was null.'); @@ -2118,7 +2230,7 @@ class _TestWKHttpCookieStoreHostApiCodec extends StandardMessageCodec { abstract class TestWKHttpCookieStoreHostApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec codec = + static const MessageCodec pigeonChannelCodec = _TestWKHttpCookieStoreHostApiCodec(); void createFromWebsiteDataStore( @@ -2126,19 +2238,25 @@ abstract class TestWKHttpCookieStoreHostApi { Future setCookie(int identifier, NSHttpCookieData cookie); - static void setup(TestWKHttpCookieStoreHostApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + TestWKHttpCookieStoreHostApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKHttpCookieStoreHostApi.createFromWebsiteDataStore', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKHttpCookieStoreHostApi.createFromWebsiteDataStore$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKHttpCookieStoreHostApi.createFromWebsiteDataStore was null.'); @@ -2163,16 +2281,17 @@ abstract class TestWKHttpCookieStoreHostApi { } } { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.WKHttpCookieStoreHostApi.setCookie', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.WKHttpCookieStoreHostApi.setCookie$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.WKHttpCookieStoreHostApi.setCookie was null.'); @@ -2208,22 +2327,30 @@ abstract class TestWKHttpCookieStoreHostApi { abstract class TestNSUrlHostApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec codec = StandardMessageCodec(); + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); String? getAbsoluteString(int identifier); - static void setup(TestNSUrlHostApi? api, {BinaryMessenger? binaryMessenger}) { + static void setUp( + TestNSUrlHostApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlHostApi.getAbsoluteString', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlHostApi.getAbsoluteString$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlHostApi.getAbsoluteString was null.'); @@ -2256,23 +2383,30 @@ abstract class TestNSUrlHostApi { abstract class TestUIScrollViewDelegateHostApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec codec = StandardMessageCodec(); + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); void create(int identifier); - static void setup(TestUIScrollViewDelegateHostApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + TestUIScrollViewDelegateHostApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewDelegateHostApi.create', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewDelegateHostApi.create$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewDelegateHostApi.create was null.'); @@ -2305,25 +2439,32 @@ abstract class TestUIScrollViewDelegateHostApi { abstract class TestNSUrlCredentialHostApi { static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; - static const MessageCodec codec = StandardMessageCodec(); + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); /// Create a new native instance and add it to the `InstanceManager`. void createWithUser(int identifier, String user, String password, NSUrlCredentialPersistence persistence); - static void setup(TestNSUrlCredentialHostApi? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + TestNSUrlCredentialHostApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlCredentialHostApi.createWithUser', - codec, + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlCredentialHostApi.createWithUser$messageChannelSuffix', + pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, null); + .setMockDecodedMessageHandler(__pigeon_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(channel, + .setMockDecodedMessageHandler(__pigeon_channel, (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlCredentialHostApi.createWithUser was null.'); diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/src/foundation/foundation_test.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/src/foundation/foundation_test.dart index 345c6fad6776..5eb821fdfcbc 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/src/foundation/foundation_test.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/src/foundation/foundation_test.dart @@ -37,14 +37,14 @@ void main() { setUp(() { mockPlatformHostApi = MockTestNSObjectHostApi(); - TestNSObjectHostApi.setup(mockPlatformHostApi); + TestNSObjectHostApi.setUp(mockPlatformHostApi); object = NSObject.detached(instanceManager: instanceManager); instanceManager.addDartCreatedInstance(object); }); tearDown(() { - TestNSObjectHostApi.setup(null); + TestNSObjectHostApi.setUp(null); }); test('addObserver', () async { @@ -222,11 +222,11 @@ void main() { group('NSUrl', () { // Ensure the test host api is removed after each test run. - tearDown(() => TestNSUrlHostApi.setup(null)); + tearDown(() => TestNSUrlHostApi.setUp(null)); test('getAbsoluteString', () async { final MockTestNSUrlHostApi mockApi = MockTestNSUrlHostApi(); - TestNSUrlHostApi.setup(mockApi); + TestNSUrlHostApi.setUp(mockApi); final NSUrl url = NSUrl.detached(instanceManager: instanceManager); instanceManager.addHostCreatedInstance(url, 0); @@ -249,13 +249,13 @@ void main() { group('NSUrlCredential', () { tearDown(() { - TestNSUrlCredentialHostApi.setup(null); + TestNSUrlCredentialHostApi.setUp(null); }); test('HostApi createWithUser', () { final MockTestNSUrlCredentialHostApi mockApi = MockTestNSUrlCredentialHostApi(); - TestNSUrlCredentialHostApi.setup(mockApi); + TestNSUrlCredentialHostApi.setUp(mockApi); final InstanceManager instanceManager = InstanceManager( onWeakReferenceRemoved: (_) {}, diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/src/foundation/foundation_test.mocks.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/src/foundation/foundation_test.mocks.dart index a34a190ac497..df4e12e6082f 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/src/foundation/foundation_test.mocks.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/src/foundation/foundation_test.mocks.dart @@ -38,6 +38,7 @@ class MockTestNSObjectHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void addObserver( int? identifier, @@ -57,6 +58,7 @@ class MockTestNSObjectHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void removeObserver( int? identifier, diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/src/ui_kit/ui_kit_test.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/src/ui_kit/ui_kit_test.dart index 576d0404693f..c6458b9d9335 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/src/ui_kit/ui_kit_test.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/src/ui_kit/ui_kit_test.dart @@ -42,13 +42,13 @@ void main() { setUp(() { mockPlatformHostApi = MockTestUIScrollViewHostApi(); - TestUIScrollViewHostApi.setup(mockPlatformHostApi); + TestUIScrollViewHostApi.setUp(mockPlatformHostApi); - TestWKWebViewConfigurationHostApi.setup( + TestWKWebViewConfigurationHostApi.setUp( MockTestWKWebViewConfigurationHostApi(), ); - TestWKWebViewHostApi.setup(MockTestWKWebViewHostApi()); - final WKWebView webView = WKWebView( + TestWKWebViewHostApi.setUp(MockTestWKWebViewHostApi()); + final WKWebView webView = WKWebViewIOS( WKWebViewConfiguration(instanceManager: instanceManager), instanceManager: instanceManager, ); @@ -61,9 +61,9 @@ void main() { }); tearDown(() { - TestUIScrollViewHostApi.setup(null); - TestWKWebViewConfigurationHostApi.setup(null); - TestWKWebViewHostApi.setup(null); + TestUIScrollViewHostApi.setUp(null); + TestWKWebViewConfigurationHostApi.setUp(null); + TestWKWebViewHostApi.setUp(null); }); test('getContentOffset', () async { @@ -105,12 +105,12 @@ void main() { group('UIScrollViewDelegate', () { // Ensure the test host api is removed after each test run. - tearDown(() => TestUIScrollViewDelegateHostApi.setup(null)); + tearDown(() => TestUIScrollViewDelegateHostApi.setUp(null)); test('Host API create', () { final MockTestUIScrollViewDelegateHostApi mockApi = MockTestUIScrollViewDelegateHostApi(); - TestUIScrollViewDelegateHostApi.setup(mockApi); + TestUIScrollViewDelegateHostApi.setUp(mockApi); UIScrollViewDelegate(instanceManager: instanceManager); verify(mockApi.create(0)); @@ -150,14 +150,14 @@ void main() { setUp(() { mockPlatformHostApi = MockTestUIViewHostApi(); - TestUIViewHostApi.setup(mockPlatformHostApi); + TestUIViewHostApi.setUp(mockPlatformHostApi); - view = UIView.detached(instanceManager: instanceManager); + view = UIViewBase.detached(instanceManager: instanceManager); viewInstanceId = instanceManager.addDartCreatedInstance(view); }); tearDown(() { - TestUIViewHostApi.setup(null); + TestUIViewHostApi.setUp(null); }); test('setBackgroundColor', () async { diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/src/ui_kit/ui_kit_test.mocks.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/src/ui_kit/ui_kit_test.mocks.dart index 54e91efb6a66..66bbc7275e69 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/src/ui_kit/ui_kit_test.mocks.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/src/ui_kit/ui_kit_test.mocks.dart @@ -40,6 +40,7 @@ class MockTestWKWebViewConfigurationHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void createFromWebView( int? identifier, @@ -55,6 +56,7 @@ class MockTestWKWebViewConfigurationHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void setAllowsInlineMediaPlayback( int? identifier, @@ -70,6 +72,7 @@ class MockTestWKWebViewConfigurationHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void setLimitsNavigationsToAppBoundDomains( int? identifier, @@ -85,6 +88,7 @@ class MockTestWKWebViewConfigurationHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void setMediaTypesRequiringUserActionForPlayback( int? identifier, @@ -126,6 +130,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void setUIDelegate( int? identifier, @@ -141,6 +146,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void setNavigationDelegate( int? identifier, @@ -156,11 +162,13 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override String? getUrl(int? identifier) => (super.noSuchMethod(Invocation.method( #getUrl, [identifier], )) as String?); + @override double getEstimatedProgress(int? identifier) => (super.noSuchMethod( Invocation.method( @@ -169,6 +177,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValue: 0.0, ) as double); + @override void loadRequest( int? identifier, @@ -184,6 +193,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void loadHtmlString( int? identifier, @@ -201,6 +211,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void loadFileUrl( int? identifier, @@ -218,6 +229,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void loadFlutterAsset( int? identifier, @@ -233,6 +245,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override bool canGoBack(int? identifier) => (super.noSuchMethod( Invocation.method( @@ -241,6 +254,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValue: false, ) as bool); + @override bool canGoForward(int? identifier) => (super.noSuchMethod( Invocation.method( @@ -249,6 +263,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValue: false, ) as bool); + @override void goBack(int? identifier) => super.noSuchMethod( Invocation.method( @@ -257,6 +272,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void goForward(int? identifier) => super.noSuchMethod( Invocation.method( @@ -265,6 +281,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void reload(int? identifier) => super.noSuchMethod( Invocation.method( @@ -273,11 +290,13 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override String? getTitle(int? identifier) => (super.noSuchMethod(Invocation.method( #getTitle, [identifier], )) as String?); + @override void setAllowsBackForwardNavigationGestures( int? identifier, @@ -293,6 +312,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void setCustomUserAgent( int? identifier, @@ -308,6 +328,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override _i4.Future evaluateJavaScript( int? identifier, @@ -323,6 +344,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValue: _i4.Future.value(), ) as _i4.Future); + @override void setInspectable( int? identifier, @@ -338,6 +360,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override String? getCustomUserAgent(int? identifier) => (super.noSuchMethod(Invocation.method( @@ -370,6 +393,7 @@ class MockTestUIScrollViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override List getContentOffset(int? identifier) => (super.noSuchMethod( Invocation.method( @@ -378,6 +402,7 @@ class MockTestUIScrollViewHostApi extends _i1.Mock ), returnValue: [], ) as List); + @override void scrollBy( int? identifier, @@ -395,6 +420,7 @@ class MockTestUIScrollViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void setContentOffset( int? identifier, @@ -412,6 +438,7 @@ class MockTestUIScrollViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void setDelegate( int? identifier, @@ -471,6 +498,7 @@ class MockTestUIViewHostApi extends _i1.Mock implements _i2.TestUIViewHostApi { ), returnValueForMissingStub: null, ); + @override void setOpaque( int? identifier, diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/src/web_kit/web_kit_test.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/src/web_kit/web_kit_test.dart index d838bf996146..2f89e32e181d 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/src/web_kit/web_kit_test.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/src/web_kit/web_kit_test.dart @@ -50,9 +50,9 @@ void main() { setUp(() { mockPlatformHostApi = MockTestWKWebsiteDataStoreHostApi(); - TestWKWebsiteDataStoreHostApi.setup(mockPlatformHostApi); + TestWKWebsiteDataStoreHostApi.setUp(mockPlatformHostApi); - TestWKWebViewConfigurationHostApi.setup( + TestWKWebViewConfigurationHostApi.setUp( MockTestWKWebViewConfigurationHostApi(), ); webViewConfiguration = WKWebViewConfiguration( @@ -66,8 +66,8 @@ void main() { }); tearDown(() { - TestWKWebsiteDataStoreHostApi.setup(null); - TestWKWebViewConfigurationHostApi.setup(null); + TestWKWebsiteDataStoreHostApi.setUp(null); + TestWKWebViewConfigurationHostApi.setUp(null); }); test('WKWebViewConfigurationFlutterApi.create', () { @@ -139,12 +139,12 @@ void main() { setUp(() { mockPlatformHostApi = MockTestWKHttpCookieStoreHostApi(); - TestWKHttpCookieStoreHostApi.setup(mockPlatformHostApi); + TestWKHttpCookieStoreHostApi.setUp(mockPlatformHostApi); - TestWKWebViewConfigurationHostApi.setup( + TestWKWebViewConfigurationHostApi.setUp( MockTestWKWebViewConfigurationHostApi(), ); - TestWKWebsiteDataStoreHostApi.setup( + TestWKWebsiteDataStoreHostApi.setUp( MockTestWKWebsiteDataStoreHostApi(), ); @@ -160,9 +160,9 @@ void main() { }); tearDown(() { - TestWKHttpCookieStoreHostApi.setup(null); - TestWKWebsiteDataStoreHostApi.setup(null); - TestWKWebViewConfigurationHostApi.setup(null); + TestWKHttpCookieStoreHostApi.setUp(null); + TestWKWebsiteDataStoreHostApi.setUp(null); + TestWKWebViewConfigurationHostApi.setUp(null); }); test('createFromWebsiteDataStore', () { @@ -200,7 +200,7 @@ void main() { setUp(() async { mockPlatformHostApi = MockTestWKScriptMessageHandlerHostApi(); - TestWKScriptMessageHandlerHostApi.setup(mockPlatformHostApi); + TestWKScriptMessageHandlerHostApi.setUp(mockPlatformHostApi); scriptMessageHandler = WKScriptMessageHandler( didReceiveScriptMessage: (_, __) {}, @@ -209,7 +209,7 @@ void main() { }); tearDown(() { - TestWKScriptMessageHandlerHostApi.setup(null); + TestWKScriptMessageHandlerHostApi.setUp(null); }); test('create', () async { @@ -264,9 +264,9 @@ void main() { setUp(() { mockPlatformHostApi = MockTestWKPreferencesHostApi(); - TestWKPreferencesHostApi.setup(mockPlatformHostApi); + TestWKPreferencesHostApi.setUp(mockPlatformHostApi); - TestWKWebViewConfigurationHostApi.setup( + TestWKWebViewConfigurationHostApi.setUp( MockTestWKWebViewConfigurationHostApi(), ); webViewConfiguration = WKWebViewConfiguration( @@ -280,8 +280,8 @@ void main() { }); tearDown(() { - TestWKPreferencesHostApi.setup(null); - TestWKWebViewConfigurationHostApi.setup(null); + TestWKPreferencesHostApi.setUp(null); + TestWKWebViewConfigurationHostApi.setUp(null); }); test('createFromWebViewConfiguration', () async { @@ -309,9 +309,9 @@ void main() { setUp(() { mockPlatformHostApi = MockTestWKUserContentControllerHostApi(); - TestWKUserContentControllerHostApi.setup(mockPlatformHostApi); + TestWKUserContentControllerHostApi.setUp(mockPlatformHostApi); - TestWKWebViewConfigurationHostApi.setup( + TestWKWebViewConfigurationHostApi.setUp( MockTestWKWebViewConfigurationHostApi(), ); webViewConfiguration = WKWebViewConfiguration( @@ -326,8 +326,8 @@ void main() { }); tearDown(() { - TestWKUserContentControllerHostApi.setup(null); - TestWKWebViewConfigurationHostApi.setup(null); + TestWKUserContentControllerHostApi.setUp(null); + TestWKWebViewConfigurationHostApi.setUp(null); }); test('createFromWebViewConfiguration', () async { @@ -338,7 +338,7 @@ void main() { }); test('addScriptMessageHandler', () async { - TestWKScriptMessageHandlerHostApi.setup( + TestWKScriptMessageHandlerHostApi.setUp( MockTestWKScriptMessageHandlerHostApi(), ); final WKScriptMessageHandler handler = WKScriptMessageHandler( @@ -397,7 +397,7 @@ void main() { setUp(() async { mockPlatformHostApi = MockTestWKWebViewConfigurationHostApi(); - TestWKWebViewConfigurationHostApi.setup(mockPlatformHostApi); + TestWKWebViewConfigurationHostApi.setUp(mockPlatformHostApi); webViewConfiguration = WKWebViewConfiguration( instanceManager: instanceManager, @@ -405,7 +405,7 @@ void main() { }); tearDown(() { - TestWKWebViewConfigurationHostApi.setup(null); + TestWKWebViewConfigurationHostApi.setUp(null); }); test('create', () async { @@ -417,8 +417,8 @@ void main() { }); test('createFromWebView', () async { - TestWKWebViewHostApi.setup(MockTestWKWebViewHostApi()); - final WKWebView webView = WKWebView( + TestWKWebViewHostApi.setUp(MockTestWKWebViewHostApi()); + final WKWebView webView = WKWebViewIOS( webViewConfiguration, instanceManager: instanceManager, ); @@ -479,13 +479,13 @@ void main() { setUp(() async { mockPlatformHostApi = MockTestWKNavigationDelegateHostApi(); - TestWKNavigationDelegateHostApi.setup(mockPlatformHostApi); + TestWKNavigationDelegateHostApi.setUp(mockPlatformHostApi); - TestWKWebViewConfigurationHostApi.setup( + TestWKWebViewConfigurationHostApi.setUp( MockTestWKWebViewConfigurationHostApi(), ); - TestWKWebViewHostApi.setup(MockTestWKWebViewHostApi()); - webView = WKWebView( + TestWKWebViewHostApi.setUp(MockTestWKWebViewHostApi()); + webView = WKWebViewIOS( WKWebViewConfiguration(instanceManager: instanceManager), instanceManager: instanceManager, ); @@ -496,9 +496,9 @@ void main() { }); tearDown(() { - TestWKNavigationDelegateHostApi.setup(null); - TestWKWebViewConfigurationHostApi.setup(null); - TestWKWebViewHostApi.setup(null); + TestWKNavigationDelegateHostApi.setUp(null); + TestWKWebViewConfigurationHostApi.setUp(null); + TestWKWebViewHostApi.setUp(null); }); test('create', () async { @@ -785,15 +785,15 @@ void main() { setUp(() { mockPlatformHostApi = MockTestWKWebViewHostApi(); - TestWKWebViewHostApi.setup(mockPlatformHostApi); + TestWKWebViewHostApi.setUp(mockPlatformHostApi); - TestWKWebViewConfigurationHostApi.setup( + TestWKWebViewConfigurationHostApi.setUp( MockTestWKWebViewConfigurationHostApi()); webViewConfiguration = WKWebViewConfiguration( instanceManager: instanceManager, ); - webView = WKWebView( + webView = WKWebViewIOS( webViewConfiguration, instanceManager: instanceManager, ); @@ -801,8 +801,8 @@ void main() { }); tearDown(() { - TestWKWebViewHostApi.setup(null); - TestWKWebViewConfigurationHostApi.setup(null); + TestWKWebViewHostApi.setUp(null); + TestWKWebViewConfigurationHostApi.setUp(null); }); test('create', () async { @@ -815,7 +815,7 @@ void main() { }); test('setUIDelegate', () async { - TestWKUIDelegateHostApi.setup(MockTestWKUIDelegateHostApi()); + TestWKUIDelegateHostApi.setUp(MockTestWKUIDelegateHostApi()); final WKUIDelegate uiDelegate = WKUIDelegate( instanceManager: instanceManager, ); @@ -826,11 +826,11 @@ void main() { instanceManager.getIdentifier(uiDelegate), )); - TestWKUIDelegateHostApi.setup(null); + TestWKUIDelegateHostApi.setUp(null); }); test('setNavigationDelegate', () async { - TestWKNavigationDelegateHostApi.setup( + TestWKNavigationDelegateHostApi.setUp( MockTestWKNavigationDelegateHostApi(), ); final WKNavigationDelegate navigationDelegate = WKNavigationDelegate( @@ -843,7 +843,7 @@ void main() { instanceManager.getIdentifier(navigationDelegate), )); - TestWKNavigationDelegateHostApi.setup(null); + TestWKNavigationDelegateHostApi.setUp(null); }); test('getUrl', () { @@ -979,13 +979,13 @@ void main() { setUp(() async { mockPlatformHostApi = MockTestWKUIDelegateHostApi(); - TestWKUIDelegateHostApi.setup(mockPlatformHostApi); + TestWKUIDelegateHostApi.setUp(mockPlatformHostApi); uiDelegate = WKUIDelegate(instanceManager: instanceManager); }); tearDown(() { - TestWKUIDelegateHostApi.setup(null); + TestWKUIDelegateHostApi.setUp(null); }); test('create', () async { @@ -1017,7 +1017,7 @@ void main() { }, ); - final WKWebView webView = WKWebView.detached( + final WKWebView webView = WKWebViewIOS.detached( instanceManager: instanceManager, ); instanceManager.addHostCreatedInstance(webView, 2); @@ -1090,7 +1090,7 @@ void main() { instanceManager: instanceManager, ); - final WKWebView webView = WKWebView.detached( + final WKWebView webView = WKWebViewIOS.detached( instanceManager: instanceManager, ); const int webViewIdentifier = 42; diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/src/web_kit/web_kit_test.mocks.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/src/web_kit/web_kit_test.mocks.dart index 99aedf1659f7..d9a0ed01d50d 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/src/web_kit/web_kit_test.mocks.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/src/web_kit/web_kit_test.mocks.dart @@ -47,6 +47,7 @@ class MockTestWKHttpCookieStoreHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override _i3.Future setCookie( int? identifier, @@ -108,6 +109,7 @@ class MockTestWKPreferencesHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void setJavaScriptEnabled( int? identifier, @@ -187,6 +189,7 @@ class MockTestWKUserContentControllerHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void addScriptMessageHandler( int? identifier, @@ -204,6 +207,7 @@ class MockTestWKUserContentControllerHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void removeScriptMessageHandler( int? identifier, @@ -219,6 +223,7 @@ class MockTestWKUserContentControllerHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void removeAllScriptMessageHandlers(int? identifier) => super.noSuchMethod( Invocation.method( @@ -227,6 +232,7 @@ class MockTestWKUserContentControllerHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void addUserScript( int? identifier, @@ -242,6 +248,7 @@ class MockTestWKUserContentControllerHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void removeAllUserScripts(int? identifier) => super.noSuchMethod( Invocation.method( @@ -269,6 +276,7 @@ class MockTestWKWebViewConfigurationHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void createFromWebView( int? identifier, @@ -284,6 +292,7 @@ class MockTestWKWebViewConfigurationHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void setAllowsInlineMediaPlayback( int? identifier, @@ -299,6 +308,7 @@ class MockTestWKWebViewConfigurationHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void setLimitsNavigationsToAppBoundDomains( int? identifier, @@ -314,6 +324,7 @@ class MockTestWKWebViewConfigurationHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void setMediaTypesRequiringUserActionForPlayback( int? identifier, @@ -355,6 +366,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void setUIDelegate( int? identifier, @@ -370,6 +382,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void setNavigationDelegate( int? identifier, @@ -385,11 +398,13 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override String? getUrl(int? identifier) => (super.noSuchMethod(Invocation.method( #getUrl, [identifier], )) as String?); + @override double getEstimatedProgress(int? identifier) => (super.noSuchMethod( Invocation.method( @@ -398,6 +413,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValue: 0.0, ) as double); + @override void loadRequest( int? identifier, @@ -413,6 +429,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void loadHtmlString( int? identifier, @@ -430,6 +447,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void loadFileUrl( int? identifier, @@ -447,6 +465,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void loadFlutterAsset( int? identifier, @@ -462,6 +481,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override bool canGoBack(int? identifier) => (super.noSuchMethod( Invocation.method( @@ -470,6 +490,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValue: false, ) as bool); + @override bool canGoForward(int? identifier) => (super.noSuchMethod( Invocation.method( @@ -478,6 +499,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValue: false, ) as bool); + @override void goBack(int? identifier) => super.noSuchMethod( Invocation.method( @@ -486,6 +508,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void goForward(int? identifier) => super.noSuchMethod( Invocation.method( @@ -494,6 +517,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void reload(int? identifier) => super.noSuchMethod( Invocation.method( @@ -502,11 +526,13 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override String? getTitle(int? identifier) => (super.noSuchMethod(Invocation.method( #getTitle, [identifier], )) as String?); + @override void setAllowsBackForwardNavigationGestures( int? identifier, @@ -522,6 +548,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void setCustomUserAgent( int? identifier, @@ -537,6 +564,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override _i3.Future evaluateJavaScript( int? identifier, @@ -552,6 +580,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValue: _i3.Future.value(), ) as _i3.Future); + @override void setInspectable( int? identifier, @@ -567,6 +596,7 @@ class MockTestWKWebViewHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override String? getCustomUserAgent(int? identifier) => (super.noSuchMethod(Invocation.method( @@ -599,6 +629,7 @@ class MockTestWKWebsiteDataStoreHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void createDefaultDataStore(int? identifier) => super.noSuchMethod( Invocation.method( @@ -607,6 +638,7 @@ class MockTestWKWebsiteDataStoreHostApi extends _i1.Mock ), returnValueForMissingStub: null, ); + @override _i3.Future removeDataOfTypes( int? identifier, diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_navigation_delegate_test.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_navigation_delegate_test.dart index da8675886f7e..8a1ba88ee26d 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_navigation_delegate_test.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_navigation_delegate_test.dart @@ -42,7 +42,7 @@ void main() { webKitDelegate.setOnPageFinished((String url) => callbackUrl = url); CapturingNavigationDelegate.lastCreatedDelegate.didFinishNavigation!( - WKWebView.detached(), + WKWebViewIOS.detached(), 'https://www.google.com', ); @@ -64,7 +64,7 @@ void main() { CapturingNavigationDelegate .lastCreatedDelegate.didStartProvisionalNavigation!( - WKWebView.detached(), + WKWebViewIOS.detached(), 'https://www.google.com', ); @@ -90,7 +90,7 @@ void main() { CapturingNavigationDelegate .lastCreatedDelegate.decidePolicyForNavigationResponse!( - WKWebView.detached(), + WKWebViewIOS.detached(), const WKNavigationResponse( response: NSHttpUrlResponse(statusCode: 401), forMainFrame: true), ); @@ -117,7 +117,7 @@ void main() { CapturingNavigationDelegate .lastCreatedDelegate.decidePolicyForNavigationResponse!( - WKWebView.detached(), + WKWebViewIOS.detached(), const WKNavigationResponse( response: NSHttpUrlResponse(statusCode: 399), forMainFrame: true), ); @@ -143,7 +143,7 @@ void main() { webKitDelegate.setOnWebResourceError(onWebResourceError); CapturingNavigationDelegate.lastCreatedDelegate.didFailNavigation!( - WKWebView.detached(), + WKWebViewIOS.detached(), const NSError( code: WKErrorCode.webViewInvalidated, domain: 'domain', @@ -182,7 +182,7 @@ void main() { CapturingNavigationDelegate .lastCreatedDelegate.didFailProvisionalNavigation!( - WKWebView.detached(), + WKWebViewIOS.detached(), const NSError( code: WKErrorCode.webViewInvalidated, domain: 'domain', @@ -221,7 +221,7 @@ void main() { CapturingNavigationDelegate .lastCreatedDelegate.webViewWebContentProcessDidTerminate!( - WKWebView.detached(), + WKWebViewIOS.detached(), ); expect(callbackError.description, ''); @@ -256,7 +256,7 @@ void main() { expect( CapturingNavigationDelegate .lastCreatedDelegate.decidePolicyForNavigationAction!( - WKWebView.detached(), + WKWebViewIOS.detached(), const WKNavigationAction( request: NSUrlRequest(url: 'https://www.google.com'), targetFrame: WKFrameInfo( @@ -295,7 +295,7 @@ void main() { CapturingNavigationDelegate .lastCreatedDelegate.didReceiveAuthenticationChallenge!( - WKWebView.detached(), + WKWebViewIOS.detached(), NSUrlAuthenticationChallenge.detached( protectionSpace: NSUrlProtectionSpace.detached( host: expectedHost, @@ -309,6 +309,44 @@ void main() { expect(callbackHost, expectedHost); expect(callbackRealm, expectedRealm); }); + + test('onHttpNtlmAuthRequest emits host and realm', () { + final WebKitNavigationDelegate iosNavigationDelegate = + WebKitNavigationDelegate( + const WebKitNavigationDelegateCreationParams( + webKitProxy: WebKitProxy( + createNavigationDelegate: CapturingNavigationDelegate.new, + ), + ), + ); + + String? callbackHost; + String? callbackRealm; + + iosNavigationDelegate.setOnHttpAuthRequest((HttpAuthRequest request) { + callbackHost = request.host; + callbackRealm = request.realm; + }); + + const String expectedHost = 'expectedHost'; + const String expectedRealm = 'expectedRealm'; + + CapturingNavigationDelegate + .lastCreatedDelegate.didReceiveAuthenticationChallenge!( + WKWebViewIOS.detached(), + NSUrlAuthenticationChallenge.detached( + protectionSpace: NSUrlProtectionSpace.detached( + host: expectedHost, + realm: expectedRealm, + authenticationMethod: NSUrlAuthenticationMethod.httpNtlm, + ), + ), + (NSUrlSessionAuthChallengeDisposition disposition, + NSUrlCredential? credential) {}); + + expect(callbackHost, expectedHost); + expect(callbackRealm, expectedRealm); + }); }); } diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_controller_test.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_controller_test.dart index b5f731f97357..d7aab4b54266 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_controller_test.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_controller_test.dart @@ -27,7 +27,7 @@ import 'webkit_webview_controller_test.mocks.dart'; WKPreferences, WKUserContentController, WKWebsiteDataStore, - WKWebView, + WKWebViewIOS, WKWebViewConfiguration, WKScriptMessageHandler, ]) @@ -42,7 +42,7 @@ void main() { WKUIDelegate? uiDelegate, MockWKUserContentController? mockUserContentController, MockWKWebsiteDataStore? mockWebsiteDataStore, - MockWKWebView Function( + MockWKWebViewIOS Function( WKWebViewConfiguration configuration, { void Function( String keyPath, @@ -55,7 +55,7 @@ void main() { }) { final MockWKWebViewConfiguration nonNullMockWebViewConfiguration = mockWebViewConfiguration ?? MockWKWebViewConfiguration(); - late final MockWKWebView nonNullMockWebView; + late final MockWKWebViewIOS nonNullMockWebView; final PlatformWebViewControllerCreationParams controllerCreationParams = WebKitWebViewControllerCreationParams( @@ -73,7 +73,7 @@ void main() { InstanceManager? instanceManager, }) { nonNullMockWebView = createMockWebView == null - ? MockWKWebView() + ? MockWKWebViewIOS() : createMockWebView( nonNullMockWebViewConfiguration, observeValue: observeValue, @@ -275,7 +275,7 @@ void main() { }); test('loadFile', () async { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final WebKitWebViewController controller = createControllerWithMocks( createMockWebView: (_, {dynamic observeValue}) => mockWebView, @@ -289,7 +289,7 @@ void main() { }); test('loadFlutterAsset', () async { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final WebKitWebViewController controller = createControllerWithMocks( createMockWebView: (_, {dynamic observeValue}) => mockWebView, @@ -300,7 +300,7 @@ void main() { }); test('loadHtmlString', () async { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final WebKitWebViewController controller = createControllerWithMocks( createMockWebView: (_, {dynamic observeValue}) => mockWebView, @@ -317,7 +317,7 @@ void main() { group('loadRequest', () { test('Throws ArgumentError for empty scheme', () async { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final WebKitWebViewController controller = createControllerWithMocks( createMockWebView: (_, {dynamic observeValue}) => mockWebView, @@ -332,7 +332,7 @@ void main() { }); test('GET without headers', () async { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final WebKitWebViewController controller = createControllerWithMocks( createMockWebView: (_, {dynamic observeValue}) => mockWebView, @@ -351,7 +351,7 @@ void main() { }); test('GET with headers', () async { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final WebKitWebViewController controller = createControllerWithMocks( createMockWebView: (_, {dynamic observeValue}) => mockWebView, @@ -373,7 +373,7 @@ void main() { }); test('POST without body', () async { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final WebKitWebViewController controller = createControllerWithMocks( createMockWebView: (_, {dynamic observeValue}) => mockWebView, @@ -392,7 +392,7 @@ void main() { }); test('POST with body', () async { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final WebKitWebViewController controller = createControllerWithMocks( createMockWebView: (_, {dynamic observeValue}) => mockWebView, @@ -417,7 +417,7 @@ void main() { }); test('canGoBack', () { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final WebKitWebViewController controller = createControllerWithMocks( createMockWebView: (_, {dynamic observeValue}) => mockWebView, @@ -430,7 +430,7 @@ void main() { }); test('canGoForward', () { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final WebKitWebViewController controller = createControllerWithMocks( createMockWebView: (_, {dynamic observeValue}) => mockWebView, @@ -443,7 +443,7 @@ void main() { }); test('goBack', () async { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final WebKitWebViewController controller = createControllerWithMocks( createMockWebView: (_, {dynamic observeValue}) => mockWebView, @@ -454,7 +454,7 @@ void main() { }); test('goForward', () async { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final WebKitWebViewController controller = createControllerWithMocks( createMockWebView: (_, {dynamic observeValue}) => mockWebView, @@ -465,7 +465,7 @@ void main() { }); test('reload', () async { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final WebKitWebViewController controller = createControllerWithMocks( createMockWebView: (_, {dynamic observeValue}) => mockWebView, @@ -476,7 +476,7 @@ void main() { }); test('setAllowsBackForwardNavigationGestures', () async { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final WebKitWebViewController controller = createControllerWithMocks( createMockWebView: (_, {dynamic observeValue}) => mockWebView, @@ -487,7 +487,7 @@ void main() { }); test('runJavaScriptReturningResult', () { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final WebKitWebViewController controller = createControllerWithMocks( createMockWebView: (_, {dynamic observeValue}) => mockWebView, @@ -504,7 +504,7 @@ void main() { }); test('runJavaScriptReturningResult throws error on null return value', () { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final WebKitWebViewController controller = createControllerWithMocks( createMockWebView: (_, {dynamic observeValue}) => mockWebView, @@ -520,7 +520,7 @@ void main() { }); test('runJavaScript', () { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final WebKitWebViewController controller = createControllerWithMocks( createMockWebView: (_, {dynamic observeValue}) => mockWebView, @@ -537,7 +537,7 @@ void main() { test('runJavaScript ignores exception with unsupported javaScript type', () { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final WebKitWebViewController controller = createControllerWithMocks( createMockWebView: (_, {dynamic observeValue}) => mockWebView, @@ -558,7 +558,7 @@ void main() { }); test('getTitle', () async { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final WebKitWebViewController controller = createControllerWithMocks( createMockWebView: (_, {dynamic observeValue}) => mockWebView, @@ -570,7 +570,7 @@ void main() { }); test('currentUrl', () { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final WebKitWebViewController controller = createControllerWithMocks( createMockWebView: (_, {dynamic observeValue}) => mockWebView, @@ -646,7 +646,7 @@ void main() { }); test('setBackgroundColor', () async { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final MockUIScrollView mockScrollView = MockUIScrollView(); final WebKitWebViewController controller = createControllerWithMocks( @@ -665,7 +665,7 @@ void main() { }); test('userAgent', () async { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final WebKitWebViewController controller = createControllerWithMocks( createMockWebView: (_, {dynamic observeValue}) => mockWebView, @@ -910,7 +910,7 @@ void main() { }); test('getUserAgent', () { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final WebKitWebViewController controller = createControllerWithMocks( createMockWebView: (_, {dynamic observeValue}) => mockWebView, @@ -925,7 +925,7 @@ void main() { }); test('setPlatformNavigationDelegate', () { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final WebKitWebViewController controller = createControllerWithMocks( createMockWebView: (_, {dynamic observeValue}) => mockWebView, @@ -951,7 +951,7 @@ void main() { }); test('setPlatformNavigationDelegate onProgress', () async { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); late final void Function( String keyPath, @@ -1017,7 +1017,7 @@ void main() { // CapturingUIDelegate.lastCreatedDelegate. createControllerWithMocks(); - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); const NSUrlRequest request = NSUrlRequest(url: 'https://www.google.com'); CapturingUIDelegate.lastCreatedDelegate.onCreateWebView!( @@ -1038,7 +1038,7 @@ void main() { test( 'setPlatformNavigationDelegate onProgress can be changed by the WebKitNavigationDelegate', () async { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); late final void Function( String keyPath, @@ -1090,7 +1090,7 @@ void main() { }); test('setPlatformNavigationDelegate onUrlChange', () async { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); late final void Function( String keyPath, @@ -1154,7 +1154,7 @@ void main() { }); test('setPlatformNavigationDelegate onUrlChange to null NSUrl', () async { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); late final void Function( String keyPath, @@ -1207,8 +1207,8 @@ void main() { final InstanceManager instanceManager = InstanceManager( onWeakReferenceRemoved: (_) {}, ); - final MockWKWebView mockWebView = MockWKWebView(); - when(mockWebView.copy()).thenReturn(MockWKWebView()); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); + when(mockWebView.copy()).thenReturn(MockWKWebViewIOS()); instanceManager.addHostCreatedInstance(mockWebView, 0); final WebKitWebViewController controller = createControllerWithMocks( @@ -1244,7 +1244,7 @@ void main() { final WKPermissionDecision decision = await onPermissionRequestCallback( CapturingUIDelegate.lastCreatedDelegate, - WKWebView.detached(), + WKWebViewIOS.detached(), const WKSecurityOrigin(host: '', port: 0, protocol: ''), const WKFrameInfo( isMainFrame: false, @@ -1337,7 +1337,7 @@ void main() { }); test('inspectable', () async { - final MockWKWebView mockWebView = MockWKWebView(); + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); final WebKitWebViewController controller = createControllerWithMocks( createMockWebView: (_, {dynamic observeValue}) => mockWebView, diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_controller_test.mocks.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_controller_test.mocks.dart index 932c567fb1e5..0c4924df62dc 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_controller_test.mocks.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_controller_test.mocks.dart @@ -159,6 +159,7 @@ class MockNSUrl extends _i1.Mock implements _i2.NSUrl { ), returnValue: _i6.Future.value(), ) as _i6.Future); + @override _i2.NSObject copy() => (super.noSuchMethod( Invocation.method( @@ -173,6 +174,7 @@ class MockNSUrl extends _i1.Mock implements _i2.NSUrl { ), ), ) as _i2.NSObject); + @override _i6.Future addObserver( _i2.NSObject? observer, { @@ -191,6 +193,7 @@ class MockNSUrl extends _i1.Mock implements _i2.NSUrl { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future removeObserver( _i2.NSObject? observer, { @@ -230,6 +233,7 @@ class MockUIScrollView extends _i1.Mock implements _i4.UIScrollView { ), )), ) as _i6.Future<_i3.Point>); + @override _i6.Future scrollBy(_i3.Point? offset) => (super.noSuchMethod( Invocation.method( @@ -239,6 +243,7 @@ class MockUIScrollView extends _i1.Mock implements _i4.UIScrollView { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future setContentOffset(_i3.Point? offset) => (super.noSuchMethod( @@ -249,6 +254,7 @@ class MockUIScrollView extends _i1.Mock implements _i4.UIScrollView { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future setDelegate(_i4.UIScrollViewDelegate? delegate) => (super.noSuchMethod( @@ -259,6 +265,7 @@ class MockUIScrollView extends _i1.Mock implements _i4.UIScrollView { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i4.UIScrollView copy() => (super.noSuchMethod( Invocation.method( @@ -273,6 +280,7 @@ class MockUIScrollView extends _i1.Mock implements _i4.UIScrollView { ), ), ) as _i4.UIScrollView); + @override _i6.Future setBackgroundColor(_i7.Color? color) => (super.noSuchMethod( Invocation.method( @@ -282,6 +290,7 @@ class MockUIScrollView extends _i1.Mock implements _i4.UIScrollView { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future setOpaque(bool? opaque) => (super.noSuchMethod( Invocation.method( @@ -291,6 +300,7 @@ class MockUIScrollView extends _i1.Mock implements _i4.UIScrollView { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future addObserver( _i2.NSObject? observer, { @@ -309,6 +319,7 @@ class MockUIScrollView extends _i1.Mock implements _i4.UIScrollView { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future removeObserver( _i2.NSObject? observer, { @@ -349,6 +360,7 @@ class MockUIScrollViewDelegate extends _i1.Mock ), ), ) as _i4.UIScrollViewDelegate); + @override _i6.Future addObserver( _i2.NSObject? observer, { @@ -367,6 +379,7 @@ class MockUIScrollViewDelegate extends _i1.Mock returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future removeObserver( _i2.NSObject? observer, { @@ -401,6 +414,7 @@ class MockWKPreferences extends _i1.Mock implements _i5.WKPreferences { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i5.WKPreferences copy() => (super.noSuchMethod( Invocation.method( @@ -415,6 +429,7 @@ class MockWKPreferences extends _i1.Mock implements _i5.WKPreferences { ), ), ) as _i5.WKPreferences); + @override _i6.Future addObserver( _i2.NSObject? observer, { @@ -433,6 +448,7 @@ class MockWKPreferences extends _i1.Mock implements _i5.WKPreferences { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future removeObserver( _i2.NSObject? observer, { @@ -475,6 +491,7 @@ class MockWKUserContentController extends _i1.Mock returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future removeScriptMessageHandler(String? name) => (super.noSuchMethod( @@ -485,6 +502,7 @@ class MockWKUserContentController extends _i1.Mock returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future removeAllScriptMessageHandlers() => (super.noSuchMethod( Invocation.method( @@ -494,6 +512,7 @@ class MockWKUserContentController extends _i1.Mock returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future addUserScript(_i5.WKUserScript? userScript) => (super.noSuchMethod( @@ -504,6 +523,7 @@ class MockWKUserContentController extends _i1.Mock returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future removeAllUserScripts() => (super.noSuchMethod( Invocation.method( @@ -513,6 +533,7 @@ class MockWKUserContentController extends _i1.Mock returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i5.WKUserContentController copy() => (super.noSuchMethod( Invocation.method( @@ -527,6 +548,7 @@ class MockWKUserContentController extends _i1.Mock ), ), ) as _i5.WKUserContentController); + @override _i6.Future addObserver( _i2.NSObject? observer, { @@ -545,6 +567,7 @@ class MockWKUserContentController extends _i1.Mock returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future removeObserver( _i2.NSObject? observer, { @@ -579,6 +602,7 @@ class MockWKWebsiteDataStore extends _i1.Mock Invocation.getter(#httpCookieStore), ), ) as _i5.WKHttpCookieStore); + @override _i6.Future removeDataOfTypes( Set<_i5.WKWebsiteDataType>? dataTypes, @@ -594,6 +618,7 @@ class MockWKWebsiteDataStore extends _i1.Mock ), returnValue: _i6.Future.value(false), ) as _i6.Future); + @override _i5.WKWebsiteDataStore copy() => (super.noSuchMethod( Invocation.method( @@ -608,6 +633,7 @@ class MockWKWebsiteDataStore extends _i1.Mock ), ), ) as _i5.WKWebsiteDataStore); + @override _i6.Future addObserver( _i2.NSObject? observer, { @@ -626,6 +652,7 @@ class MockWKWebsiteDataStore extends _i1.Mock returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future removeObserver( _i2.NSObject? observer, { @@ -642,15 +669,23 @@ class MockWKWebsiteDataStore extends _i1.Mock ) as _i6.Future); } -/// A class which mocks [WKWebView]. +/// A class which mocks [WKWebViewIOS]. /// /// See the documentation for Mockito's code generation for more information. -// ignore: must_be_immutable -class MockWKWebView extends _i1.Mock implements _i5.WKWebView { - MockWKWebView() { +class MockWKWebViewIOS extends _i1.Mock implements _i5.WKWebViewIOS { + MockWKWebViewIOS() { _i1.throwOnMissingStub(this); } + @override + _i4.UIScrollView get scrollView => (super.noSuchMethod( + Invocation.getter(#scrollView), + returnValue: _FakeUIScrollView_2( + this, + Invocation.getter(#scrollView), + ), + ) as _i4.UIScrollView); + @override _i5.WKWebViewConfiguration get configuration => (super.noSuchMethod( Invocation.getter(#configuration), @@ -659,14 +694,42 @@ class MockWKWebView extends _i1.Mock implements _i5.WKWebView { Invocation.getter(#configuration), ), ) as _i5.WKWebViewConfiguration); + @override - _i4.UIScrollView get scrollView => (super.noSuchMethod( - Invocation.getter(#scrollView), - returnValue: _FakeUIScrollView_2( + _i5.WKWebView copy() => (super.noSuchMethod( + Invocation.method( + #copy, + [], + ), + returnValue: _FakeWKWebView_9( this, - Invocation.getter(#scrollView), + Invocation.method( + #copy, + [], + ), ), - ) as _i4.UIScrollView); + ) as _i5.WKWebView); + + @override + _i6.Future setBackgroundColor(_i7.Color? color) => (super.noSuchMethod( + Invocation.method( + #setBackgroundColor, + [color], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future setOpaque(bool? opaque) => (super.noSuchMethod( + Invocation.method( + #setOpaque, + [opaque], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + @override _i6.Future setUIDelegate(_i5.WKUIDelegate? delegate) => (super.noSuchMethod( @@ -677,6 +740,7 @@ class MockWKWebView extends _i1.Mock implements _i5.WKWebView { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future setNavigationDelegate(_i5.WKNavigationDelegate? delegate) => (super.noSuchMethod( @@ -687,6 +751,7 @@ class MockWKWebView extends _i1.Mock implements _i5.WKWebView { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future getUrl() => (super.noSuchMethod( Invocation.method( @@ -695,6 +760,7 @@ class MockWKWebView extends _i1.Mock implements _i5.WKWebView { ), returnValue: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future getEstimatedProgress() => (super.noSuchMethod( Invocation.method( @@ -703,6 +769,7 @@ class MockWKWebView extends _i1.Mock implements _i5.WKWebView { ), returnValue: _i6.Future.value(0.0), ) as _i6.Future); + @override _i6.Future loadRequest(_i2.NSUrlRequest? request) => (super.noSuchMethod( @@ -713,6 +780,7 @@ class MockWKWebView extends _i1.Mock implements _i5.WKWebView { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future loadHtmlString( String? string, { @@ -727,6 +795,7 @@ class MockWKWebView extends _i1.Mock implements _i5.WKWebView { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future loadFileUrl( String? url, { @@ -741,6 +810,7 @@ class MockWKWebView extends _i1.Mock implements _i5.WKWebView { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future loadFlutterAsset(String? key) => (super.noSuchMethod( Invocation.method( @@ -750,6 +820,7 @@ class MockWKWebView extends _i1.Mock implements _i5.WKWebView { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future canGoBack() => (super.noSuchMethod( Invocation.method( @@ -758,6 +829,7 @@ class MockWKWebView extends _i1.Mock implements _i5.WKWebView { ), returnValue: _i6.Future.value(false), ) as _i6.Future); + @override _i6.Future canGoForward() => (super.noSuchMethod( Invocation.method( @@ -766,6 +838,7 @@ class MockWKWebView extends _i1.Mock implements _i5.WKWebView { ), returnValue: _i6.Future.value(false), ) as _i6.Future); + @override _i6.Future goBack() => (super.noSuchMethod( Invocation.method( @@ -775,6 +848,7 @@ class MockWKWebView extends _i1.Mock implements _i5.WKWebView { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future goForward() => (super.noSuchMethod( Invocation.method( @@ -784,6 +858,7 @@ class MockWKWebView extends _i1.Mock implements _i5.WKWebView { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future reload() => (super.noSuchMethod( Invocation.method( @@ -793,6 +868,7 @@ class MockWKWebView extends _i1.Mock implements _i5.WKWebView { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future getTitle() => (super.noSuchMethod( Invocation.method( @@ -801,6 +877,16 @@ class MockWKWebView extends _i1.Mock implements _i5.WKWebView { ), returnValue: _i6.Future.value(), ) as _i6.Future); + + @override + _i6.Future getCustomUserAgent() => (super.noSuchMethod( + Invocation.method( + #getCustomUserAgent, + [], + ), + returnValue: _i6.Future.value(), + ) as _i6.Future); + @override _i6.Future setAllowsBackForwardNavigationGestures(bool? allow) => (super.noSuchMethod( @@ -811,6 +897,7 @@ class MockWKWebView extends _i1.Mock implements _i5.WKWebView { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future setCustomUserAgent(String? userAgent) => (super.noSuchMethod( Invocation.method( @@ -820,6 +907,7 @@ class MockWKWebView extends _i1.Mock implements _i5.WKWebView { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future evaluateJavaScript(String? javaScriptString) => (super.noSuchMethod( @@ -829,6 +917,7 @@ class MockWKWebView extends _i1.Mock implements _i5.WKWebView { ), returnValue: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future setInspectable(bool? inspectable) => (super.noSuchMethod( Invocation.method( @@ -838,46 +927,7 @@ class MockWKWebView extends _i1.Mock implements _i5.WKWebView { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); - @override - _i6.Future getCustomUserAgent() => (super.noSuchMethod( - Invocation.method( - #getCustomUserAgent, - [], - ), - returnValue: _i6.Future.value(), - ) as _i6.Future); - @override - _i5.WKWebView copy() => (super.noSuchMethod( - Invocation.method( - #copy, - [], - ), - returnValue: _FakeWKWebView_9( - this, - Invocation.method( - #copy, - [], - ), - ), - ) as _i5.WKWebView); - @override - _i6.Future setBackgroundColor(_i7.Color? color) => (super.noSuchMethod( - Invocation.method( - #setBackgroundColor, - [color], - ), - returnValue: _i6.Future.value(), - returnValueForMissingStub: _i6.Future.value(), - ) as _i6.Future); - @override - _i6.Future setOpaque(bool? opaque) => (super.noSuchMethod( - Invocation.method( - #setOpaque, - [opaque], - ), - returnValue: _i6.Future.value(), - returnValueForMissingStub: _i6.Future.value(), - ) as _i6.Future); + @override _i6.Future addObserver( _i2.NSObject? observer, { @@ -896,6 +946,7 @@ class MockWKWebView extends _i1.Mock implements _i5.WKWebView { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future removeObserver( _i2.NSObject? observer, { @@ -930,6 +981,7 @@ class MockWKWebViewConfiguration extends _i1.Mock Invocation.getter(#userContentController), ), ) as _i5.WKUserContentController); + @override _i5.WKPreferences get preferences => (super.noSuchMethod( Invocation.getter(#preferences), @@ -938,6 +990,7 @@ class MockWKWebViewConfiguration extends _i1.Mock Invocation.getter(#preferences), ), ) as _i5.WKPreferences); + @override _i5.WKWebsiteDataStore get websiteDataStore => (super.noSuchMethod( Invocation.getter(#websiteDataStore), @@ -946,6 +999,7 @@ class MockWKWebViewConfiguration extends _i1.Mock Invocation.getter(#websiteDataStore), ), ) as _i5.WKWebsiteDataStore); + @override _i6.Future setAllowsInlineMediaPlayback(bool? allow) => (super.noSuchMethod( @@ -956,6 +1010,7 @@ class MockWKWebViewConfiguration extends _i1.Mock returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future setLimitsNavigationsToAppBoundDomains(bool? limit) => (super.noSuchMethod( @@ -966,6 +1021,7 @@ class MockWKWebViewConfiguration extends _i1.Mock returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future setMediaTypesRequiringUserActionForPlayback( Set<_i5.WKAudiovisualMediaType>? types) => @@ -977,6 +1033,7 @@ class MockWKWebViewConfiguration extends _i1.Mock returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i5.WKWebViewConfiguration copy() => (super.noSuchMethod( Invocation.method( @@ -991,6 +1048,7 @@ class MockWKWebViewConfiguration extends _i1.Mock ), ), ) as _i5.WKWebViewConfiguration); + @override _i6.Future addObserver( _i2.NSObject? observer, { @@ -1009,6 +1067,7 @@ class MockWKWebViewConfiguration extends _i1.Mock returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future removeObserver( _i2.NSObject? observer, { @@ -1049,6 +1108,7 @@ class MockWKScriptMessageHandler extends _i1.Mock _i5.WKUserContentController, _i5.WKScriptMessage, )); + @override _i5.WKScriptMessageHandler copy() => (super.noSuchMethod( Invocation.method( @@ -1063,6 +1123,7 @@ class MockWKScriptMessageHandler extends _i1.Mock ), ), ) as _i5.WKScriptMessageHandler); + @override _i6.Future addObserver( _i2.NSObject? observer, { @@ -1081,6 +1142,7 @@ class MockWKScriptMessageHandler extends _i1.Mock returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future removeObserver( _i2.NSObject? observer, { diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_cookie_manager_test.mocks.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_cookie_manager_test.mocks.dart index d9d21dab8db5..bda15f7cec78 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_cookie_manager_test.mocks.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_cookie_manager_test.mocks.dart @@ -63,6 +63,7 @@ class MockWKWebsiteDataStore extends _i1.Mock Invocation.getter(#httpCookieStore), ), ) as _i2.WKHttpCookieStore); + @override _i3.Future removeDataOfTypes( Set<_i2.WKWebsiteDataType>? dataTypes, @@ -78,6 +79,7 @@ class MockWKWebsiteDataStore extends _i1.Mock ), returnValue: _i3.Future.value(false), ) as _i3.Future); + @override _i2.WKWebsiteDataStore copy() => (super.noSuchMethod( Invocation.method( @@ -92,6 +94,7 @@ class MockWKWebsiteDataStore extends _i1.Mock ), ), ) as _i2.WKWebsiteDataStore); + @override _i3.Future addObserver( _i4.NSObject? observer, { @@ -110,6 +113,7 @@ class MockWKWebsiteDataStore extends _i1.Mock returnValue: _i3.Future.value(), returnValueForMissingStub: _i3.Future.value(), ) as _i3.Future); + @override _i3.Future removeObserver( _i4.NSObject? observer, { @@ -144,6 +148,7 @@ class MockWKHttpCookieStore extends _i1.Mock implements _i2.WKHttpCookieStore { returnValue: _i3.Future.value(), returnValueForMissingStub: _i3.Future.value(), ) as _i3.Future); + @override _i2.WKHttpCookieStore copy() => (super.noSuchMethod( Invocation.method( @@ -158,6 +163,7 @@ class MockWKHttpCookieStore extends _i1.Mock implements _i2.WKHttpCookieStore { ), ), ) as _i2.WKHttpCookieStore); + @override _i3.Future addObserver( _i4.NSObject? observer, { @@ -176,6 +182,7 @@ class MockWKHttpCookieStore extends _i1.Mock implements _i2.WKHttpCookieStore { returnValue: _i3.Future.value(), returnValueForMissingStub: _i3.Future.value(), ) as _i3.Future); + @override _i3.Future removeObserver( _i4.NSObject? observer, { diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_widget_test.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_widget_test.dart index ff7da8715218..3a17047c3edb 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_widget_test.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_widget_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; @@ -41,7 +43,8 @@ void main() { Builder(builder: (BuildContext context) => widget.build(context)), ); - expect(find.byType(UiKitView), findsOneWidget); + expect(find.byType(Platform.isMacOS ? AppKitView : UiKitView), + findsOneWidget); expect(find.byKey(const Key('keyValue')), findsOneWidget); }); @@ -187,7 +190,7 @@ WebKitWebViewController createTestWebViewController( )? observeValue, InstanceManager? instanceManager, }) { - final WKWebView webView = WKWebView.detached( + final WKWebView webView = WKWebViewIOS.detached( instanceManager: testInstanceManager, ); testInstanceManager.addDartCreatedInstance(webView); diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_widget_test.mocks.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_widget_test.mocks.dart index 8c511d9f8025..2aff8e964b60 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_widget_test.mocks.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_widget_test.mocks.dart @@ -99,6 +99,7 @@ class MockWKUIDelegate extends _i1.Mock implements _i2.WKUIDelegate { ), ), ) as _i2.WKUIDelegate); + @override _i3.Future addObserver( _i4.NSObject? observer, { @@ -117,6 +118,7 @@ class MockWKUIDelegate extends _i1.Mock implements _i2.WKUIDelegate { returnValue: _i3.Future.value(), returnValueForMissingStub: _i3.Future.value(), ) as _i3.Future); + @override _i3.Future removeObserver( _i4.NSObject? observer, { @@ -151,6 +153,7 @@ class MockWKWebViewConfiguration extends _i1.Mock Invocation.getter(#userContentController), ), ) as _i2.WKUserContentController); + @override _i2.WKPreferences get preferences => (super.noSuchMethod( Invocation.getter(#preferences), @@ -159,6 +162,7 @@ class MockWKWebViewConfiguration extends _i1.Mock Invocation.getter(#preferences), ), ) as _i2.WKPreferences); + @override _i2.WKWebsiteDataStore get websiteDataStore => (super.noSuchMethod( Invocation.getter(#websiteDataStore), @@ -167,6 +171,7 @@ class MockWKWebViewConfiguration extends _i1.Mock Invocation.getter(#websiteDataStore), ), ) as _i2.WKWebsiteDataStore); + @override _i3.Future setAllowsInlineMediaPlayback(bool? allow) => (super.noSuchMethod( @@ -177,6 +182,7 @@ class MockWKWebViewConfiguration extends _i1.Mock returnValue: _i3.Future.value(), returnValueForMissingStub: _i3.Future.value(), ) as _i3.Future); + @override _i3.Future setLimitsNavigationsToAppBoundDomains(bool? limit) => (super.noSuchMethod( @@ -187,6 +193,7 @@ class MockWKWebViewConfiguration extends _i1.Mock returnValue: _i3.Future.value(), returnValueForMissingStub: _i3.Future.value(), ) as _i3.Future); + @override _i3.Future setMediaTypesRequiringUserActionForPlayback( Set<_i2.WKAudiovisualMediaType>? types) => @@ -198,6 +205,7 @@ class MockWKWebViewConfiguration extends _i1.Mock returnValue: _i3.Future.value(), returnValueForMissingStub: _i3.Future.value(), ) as _i3.Future); + @override _i2.WKWebViewConfiguration copy() => (super.noSuchMethod( Invocation.method( @@ -212,6 +220,7 @@ class MockWKWebViewConfiguration extends _i1.Mock ), ), ) as _i2.WKWebViewConfiguration); + @override _i3.Future addObserver( _i4.NSObject? observer, { @@ -230,6 +239,7 @@ class MockWKWebViewConfiguration extends _i1.Mock returnValue: _i3.Future.value(), returnValueForMissingStub: _i3.Future.value(), ) as _i3.Future); + @override _i3.Future removeObserver( _i4.NSObject? observer, { diff --git a/packages/xdg_directories/CHANGELOG.md b/packages/xdg_directories/CHANGELOG.md index e4ab09dbf141..caad99371e95 100644 --- a/packages/xdg_directories/CHANGELOG.md +++ b/packages/xdg_directories/CHANGELOG.md @@ -1,6 +1,7 @@ -## NEXT +## 1.1.0 -* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Adds `stateHome` property for `XDG_STATE_HOME`. ## 1.0.4 diff --git a/packages/xdg_directories/example/lib/main.dart b/packages/xdg_directories/example/lib/main.dart index fb3695d62436..32ac09c8901c 100644 --- a/packages/xdg_directories/example/lib/main.dart +++ b/packages/xdg_directories/example/lib/main.dart @@ -67,6 +67,7 @@ class _MyHomePageState extends State { 'Config Directories: \n${configDirs.map((Directory directory) => directory.path).toList().join('\n')}\n'), Text('Cache Home: \n${cacheHome.path}\n'), Text('Runtime Directory: \n${runtimeDir?.path}\n'), + Text('State Home: \n${stateHome.path}\n'), const SizedBox( height: 100, ), diff --git a/packages/xdg_directories/example/pubspec.yaml b/packages/xdg_directories/example/pubspec.yaml index d189615d2f89..6371986d179c 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.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: diff --git a/packages/xdg_directories/lib/xdg_directories.dart b/packages/xdg_directories/lib/xdg_directories.dart index 60448a0ddc2f..4c9330ea7bc7 100644 --- a/packages/xdg_directories/lib/xdg_directories.dart +++ b/packages/xdg_directories/lib/xdg_directories.dart @@ -174,6 +174,13 @@ Directory get dataHome => /// Throws [StateError] if the HOME environment variable is not set. Directory? get runtimeDir => _directoryFromEnvironment('XDG_RUNTIME_DIR'); +/// The base directory relative to which user-specific state data should be +/// written. (Corresponds to `$XDG_STATE_HOME`). +/// +/// Throws [StateError] if the HOME environment variable is not set. +Directory get stateHome => + _directoryFromEnvironmentWithFallback('XDG_STATE_HOME', '.local/state'); + /// Gets the xdg user directory named by `dirName`. /// /// Use [getUserDirectoryNames] to find out the list of available names. diff --git a/packages/xdg_directories/pubspec.yaml b/packages/xdg_directories/pubspec.yaml index 1fd5edc4de01..732bf2cd3f44 100644 --- a/packages/xdg_directories/pubspec.yaml +++ b/packages/xdg_directories/pubspec.yaml @@ -2,10 +2,10 @@ name: xdg_directories description: A Dart package for reading XDG directory configuration information on Linux. repository: https://github.com/flutter/packages/tree/main/packages/xdg_directories issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+xdg_directories%22 -version: 1.0.4 +version: 1.1.0 environment: - sdk: ^3.2.0 + sdk: ^3.3.0 platforms: linux: diff --git a/packages/xdg_directories/test/xdg_directories_test.dart b/packages/xdg_directories/test/xdg_directories_test.dart index 9c99afdaf8d9..f84e3374d790 100644 --- a/packages/xdg_directories/test/xdg_directories_test.dart +++ b/packages/xdg_directories/test/xdg_directories_test.dart @@ -38,10 +38,12 @@ void main() { '${testPath('usr/local/test_share')}:${testPath('usr/test_share')}'; fakeEnv['XDG_DATA_HOME'] = testPath('.local/test_share'); fakeEnv['XDG_RUNTIME_DIR'] = testPath('.local/test_runtime'); + fakeEnv['XDG_STATE_HOME'] = testPath('.local/test_state'); Directory(fakeEnv['XDG_CONFIG_HOME']!).createSync(recursive: true); Directory(fakeEnv['XDG_CACHE_HOME']!).createSync(recursive: true); Directory(fakeEnv['XDG_DATA_HOME']!).createSync(recursive: true); Directory(fakeEnv['XDG_RUNTIME_DIR']!).createSync(recursive: true); + Directory(fakeEnv['XDG_STATE_HOME']!).createSync(recursive: true); File(path.join(fakeEnv['XDG_CONFIG_HOME']!, 'user-dirs.dirs')) .writeAsStringSync(r''' XDG_DESKTOP_DIR="$HOME/Desktop" @@ -73,6 +75,7 @@ XDG_VIDEOS_DIR="$HOME/Videos" expect(xdg.cacheHome.path, equals(testPath('.cache'))); expect(xdg.configHome.path, equals(testPath('.config'))); expect(xdg.dataHome.path, equals(testPath('.local/share'))); + expect(xdg.stateHome.path, equals(testPath('.local/state'))); expect(xdg.runtimeDir, isNull); expectDirList(xdg.configDirs, ['/etc/xdg']); @@ -85,6 +88,7 @@ XDG_VIDEOS_DIR="$HOME/Videos" expect(xdg.dataHome.path, equals(testPath('.local/test_share'))); expect(xdg.runtimeDir, isNotNull); expect(xdg.runtimeDir!.path, equals(testPath('.local/test_runtime'))); + expect(xdg.stateHome.path, equals(testPath('.local/test_state'))); expectDirList(xdg.configDirs, [testPath('etc/test_xdg')]); expectDirList(xdg.dataDirs, [ diff --git a/script/configs/allowed_pinned_deps.yaml b/script/configs/allowed_pinned_deps.yaml index 1bc4d26f1b4a..a224cca3a5ab 100644 --- a/script/configs/allowed_pinned_deps.yaml +++ b/script/configs/allowed_pinned_deps.yaml @@ -1,4 +1,6 @@ # The list of external dependencies that are allowed as pinned dependencies. +# A pin can be either an exact version, or a range with an explicit, inclusive +# max version, which must a version that already exists, not a future version. # See https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#Dependencies # # All entries here should have an explanation for why they are here. @@ -16,11 +18,8 @@ # https://github.com/flutter/flutter/issues/130897 - provider -## Allowed by default - -# Dart-owned -- dart_style -- mockito - -# Google-owned -- file_testing +# Used by vector_graphics_compiler, as a production, user-facing dependency. +# This is allowed only with pinned dependencies, so that any changes can be +# audited before passing them on to clients as transitive updates, to mitigated +# the risk of the package being compromised. +- xml diff --git a/script/configs/allowed_unpinned_deps.yaml b/script/configs/allowed_unpinned_deps.yaml index 974385ac1465..9aa33fd59f8e 100644 --- a/script/configs/allowed_unpinned_deps.yaml +++ b/script/configs/allowed_unpinned_deps.yaml @@ -6,6 +6,12 @@ ## Explicit allowances +# Temporary allowance to allow importing packages in parallel; remove once +# https://github.com/flutter/packages/pull/7941 has landed. +- vector_graphics +- vector_graphics_codec +- vector_graphics_compiler + # Owned by individual Flutter Team members. # Ideally we would not do this, since there's no clear plan for what # would happen if the individuals left the Flutter Team, and the @@ -13,7 +19,6 @@ # cautious about adding to this list. - build_verify - google_maps -- win32 ## Allowed by default @@ -33,19 +38,23 @@ - fake_async - ffi - gcloud +- graphs - html - http - intl - io - js - json_serializable +- leak_tracker_flutter_testing - lints - logging - markdown - meta - mime +- mockito - path - platform +- pub_semver - shelf - shelf_static - source_gen @@ -60,6 +69,7 @@ - _discoveryapis_commons - adaptive_navigation - file +- file_testing - googleapis - googleapis_auth - json_annotation diff --git a/script/configs/exclude_all_packages_app.yaml b/script/configs/exclude_all_packages_app.yaml index 040087f10f5e..ca15045d59d9 100644 --- a/script/configs/exclude_all_packages_app.yaml +++ b/script/configs/exclude_all_packages_app.yaml @@ -9,5 +9,5 @@ # NOTE: camera_android is semi-excluded via special casing in the repo tools. # See create_all_packages_app_command.dart. -# This is a permament entry, as it should never be a direct app dependency. +# This is a permanent entry, as it should never be a direct app dependency. - plugin_platform_interface diff --git a/script/configs/exclude_all_packages_app_wasm.yaml b/script/configs/exclude_all_packages_app_wasm.yaml new file mode 100644 index 000000000000..8a02d4e47996 --- /dev/null +++ b/script/configs/exclude_all_packages_app_wasm.yaml @@ -0,0 +1,8 @@ +# This list should be kept as short as possible, and things should remain here +# only as long as necessary, since in general the goal is for all of the latest +# versions of packages to be mutually compatible, and compilable with Wasm. + +# This is only used for wasm compilation. Once all packages in the repo have +# been migrated, remove this file and use `exclude_all_packages_app.yaml` only. + +[] # Needed so the contents of this file are an empty array, not `null`! diff --git a/script/configs/exclude_integration_web.yaml b/script/configs/exclude_integration_web.yaml index 59b7d8fae145..8dbdd61b8d43 100644 --- a/script/configs/exclude_integration_web.yaml +++ b/script/configs/exclude_integration_web.yaml @@ -1,4 +1,4 @@ # Currently missing: https://github.com/flutter/flutter/issues/82211 - file_selector # Waiting on https://github.com/flutter/flutter/issues/145149 -- google_maps_flutter +- google_maps_flutter/google_maps_flutter diff --git a/script/configs/exclude_xcode_deprecation.yaml b/script/configs/exclude_xcode_deprecation.yaml new file mode 100644 index 000000000000..416839c8e381 --- /dev/null +++ b/script/configs/exclude_xcode_deprecation.yaml @@ -0,0 +1,2 @@ +# TODO(louisehsu): Remove deprecation check when StoreKit 2 is adopted. https://github.com/flutter/flutter/issues/116383 +- in_app_purchase_storekit diff --git a/script/configs/temp_exclude_excerpt.yaml b/script/configs/temp_exclude_excerpt.yaml index dbaa5d71535d..47b9639ffe72 100644 --- a/script/configs/temp_exclude_excerpt.yaml +++ b/script/configs/temp_exclude_excerpt.yaml @@ -6,8 +6,8 @@ # TODO(stuartmorgan): Remove everything from this list. See # https://github.com/flutter/flutter/issues/102679 - espresso -- go_router_builder +- flutter_svg +- flutter_svg_test - in_app_purchase/in_app_purchase -- palette_generator - pointer_interceptor - quick_actions/quick_actions diff --git a/script/tool/README.md b/script/tool/README.md index 551836e95341..b8f00c9459cc 100644 --- a/script/tool/README.md +++ b/script/tool/README.md @@ -47,6 +47,8 @@ anywhere within a package). dart run script/tool/bin/flutter_plugin_tools.dart format --packages package_name ``` +The `flutter/packages` repository uses clang version `15.0.0` . Newer versions of clang may format code differently. + ### Run the Dart Static Analyzer ```sh diff --git a/script/tool/lib/src/build_examples_command.dart b/script/tool/lib/src/build_examples_command.dart index d8d1613e06d1..d961201f7160 100644 --- a/script/tool/lib/src/build_examples_command.dart +++ b/script/tool/lib/src/build_examples_command.dart @@ -61,7 +61,7 @@ class BuildExamplesCommand extends PackageLoopingCommand { defaultsTo: '', help: 'Enables the given Dart SDK experiments.', ); - argParser.addFlag(_swiftPackageManagerFlag); + argParser.addFlag(_swiftPackageManagerFlag, defaultsTo: null); } // Maps the switch this command uses to identify a platform to information @@ -115,13 +115,22 @@ class BuildExamplesCommand extends PackageLoopingCommand { 'single key "$_pluginToolsConfigGlobalKey" containing a list of build ' 'arguments.'; - /// Returns true if `--swift-package-manager` flag was passed along with - /// either `--ios` or `--macos`. - bool get usingSwiftPackageManager { + /// Returns whether the Swift Package Manager feature should be enabled, + /// disabled, or left to the release channel's default value. + bool? get _swiftPackageManagerFeatureConfig { final List platformFlags = _platforms.keys.toList(); - return getBoolArg(_swiftPackageManagerFlag) && - (platformFlags.contains(platformIOS) || - platformFlags.contains(platformMacOS)); + if (!platformFlags.contains(platformIOS) && + !platformFlags.contains(platformMacOS)) { + return null; + } + + // TODO(loic-sharma): Allow enabling on stable once Swift Package Manager + // feature is available on stable. + if (platform.environment['CHANNEL'] != 'master') { + return null; + } + + return getNullableBoolArg(_swiftPackageManagerFlag); } @override @@ -135,15 +144,21 @@ class BuildExamplesCommand extends PackageLoopingCommand { throw ToolExit(_exitNoPlatformFlags); } - // TODO(vashworth): Enable on stable once Swift Package Manager feature is - // available on stable. - if (usingSwiftPackageManager && - platform.environment['CHANNEL'] != 'stable') { - await processRunner.runAndStream( - flutterCommand, - ['config', '--enable-swift-package-manager'], - exitOnError: true, - ); + switch (_swiftPackageManagerFeatureConfig) { + case true: + await processRunner.runAndStream( + flutterCommand, + ['config', '--enable-swift-package-manager'], + exitOnError: true, + ); + case false: + await processRunner.runAndStream( + flutterCommand, + ['config', '--no-enable-swift-package-manager'], + exitOnError: true, + ); + case null: + break; } } diff --git a/script/tool/lib/src/common/core.dart b/script/tool/lib/src/common/core.dart index 63208d23f7e4..9fef751ab56d 100644 --- a/script/tool/lib/src/common/core.dart +++ b/script/tool/lib/src/common/core.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'package:file/file.dart'; +import 'package:platform/platform.dart'; import 'package:pub_semver/pub_semver.dart'; /// The signature for a print handler for commands that allow overriding the @@ -37,6 +38,9 @@ const String kEnableExperiment = 'enable-experiment'; /// land (e.g., dependency overrides in federated plugin combination PRs). const String kDoNotLandWarning = 'DO NOT MERGE'; +/// Key for enabling web WASM compilation +const String kWebWasmFlag = 'wasm'; + /// Target platforms supported by Flutter. // ignore: public_member_api_docs enum FlutterPlatform { android, ios, linux, macos, web, windows } @@ -79,6 +83,8 @@ final Map _dartSdkForFlutterSdk = { Version(3, 19, 0): Version(3, 3, 0), Version(3, 19, 6): Version(3, 3, 4), Version(3, 22, 0): Version(3, 4, 0), + Version(3, 22, 3): Version(3, 4, 4), + Version(3, 24, 0): Version(3, 5, 0), }; /// Returns the version of the Dart SDK that shipped with the given Flutter @@ -92,7 +98,7 @@ bool isPackage(FileSystemEntity entity) { return false; } // According to - // https://dart.dev/guides/libraries/create-library-packages#what-makes-a-library-package + // https://dart.dev/guides/libraries/create-packages#what-makes-a-library-package // a package must also have a `lib/` directory, but in practice that's not // always true. Some special cases (espresso, flutter_template_images, etc.) // don't have any source, so this deliberately doesn't check that there's a @@ -122,3 +128,13 @@ const int exitCommandFoundErrors = 1; /// A exit code for [ToolExit] for a failure to run due to invalid arguments. const int exitInvalidArguments = 2; + +/// The directory to which to write logs and other artifacts, if set in CI. +Directory? ciLogsDirectory(Platform platform, FileSystem fileSystem) { + final String? logsDirectoryPath = platform.environment['FLUTTER_LOGS_DIR']; + Directory? logsDirectory; + if (logsDirectoryPath != null) { + logsDirectory = fileSystem.directory(logsDirectoryPath); + } + return logsDirectory; +} diff --git a/script/tool/lib/src/common/package_command.dart b/script/tool/lib/src/common/package_command.dart index 94a808afc17b..8b3b02626fe6 100644 --- a/script/tool/lib/src/common/package_command.dart +++ b/script/tool/lib/src/common/package_command.dart @@ -230,6 +230,11 @@ abstract class PackageCommand extends Command { return (argResults![key] as bool?) ?? false; } + /// Convenience accessor for boolean arguments. + bool? getNullableBoolArg(String key) { + return argResults![key] as bool?; + } + /// Convenience accessor for String arguments. String getStringArg(String key) { return (argResults![key] as String?) ?? ''; @@ -657,22 +662,30 @@ abstract class PackageCommand extends Command { } String? _getCurrentDirectoryPackageName() { - // Ensure that the current directory is within the packages directory. - final Directory absolutePackagesDir = packagesDir.absolute; + final Set absolutePackagesDirs = { + packagesDir.absolute, + thirdPartyPackagesDir.absolute, + }; + bool isATopLevelPackagesDir(Directory directory) => + absolutePackagesDirs.any((Directory d) => d.path == directory.path); + Directory currentDir = packagesDir.fileSystem.currentDirectory.absolute; - if (!currentDir.path.startsWith(absolutePackagesDir.path) || - currentDir.path == packagesDir.path) { + // Ensure that the current directory is within one of the top-level packages + // directories. + if (isATopLevelPackagesDir(currentDir) || + !absolutePackagesDirs + .any((Directory d) => currentDir.path.startsWith(d.path))) { return null; } - // If the current directory is a direct subdirectory of the packages + // If the current directory is a direct subdirectory of a packages // directory, then that's the target. - if (currentDir.parent.path == absolutePackagesDir.path) { + if (isATopLevelPackagesDir(currentDir.parent)) { return currentDir.basename; } // Otherwise, walk up until a package is found... while (!isPackage(currentDir)) { currentDir = currentDir.parent; - if (currentDir.path == absolutePackagesDir.path) { + if (isATopLevelPackagesDir(currentDir)) { return null; } } diff --git a/script/tool/lib/src/common/package_state_utils.dart b/script/tool/lib/src/common/package_state_utils.dart index 316251d4f01a..3d985cf9caf6 100644 --- a/script/tool/lib/src/common/package_state_utils.dart +++ b/script/tool/lib/src/common/package_state_utils.dart @@ -226,6 +226,7 @@ bool _isExampleBuildFile(List pathComponents) { pathComponents.contains('Podfile') || pathComponents.contains('CMakeLists.txt') || pathComponents.contains('.pluginToolsConfig.yaml') || + pathComponents.contains('settings.gradle') || pathComponents.contains('pubspec.yaml'); } diff --git a/script/tool/lib/src/common/repository_package.dart b/script/tool/lib/src/common/repository_package.dart index 175417271ace..2a18c2e6e2b5 100644 --- a/script/tool/lib/src/common/repository_package.dart +++ b/script/tool/lib/src/common/repository_package.dart @@ -66,6 +66,14 @@ class RepositoryPackage { /// The test directory containing the package's Dart tests. Directory get testDirectory => directory.childDirectory('test'); + /// The path to the script that is run by the `custom-test` command. + File get customTestScript => + directory.childDirectory('tool').childFile('run_tests.dart'); + + /// The path to the script that is run before publishing. + File get prePublishScript => + directory.childDirectory('tool').childFile('pre_publish.dart'); + /// Returns the directory containing support for [platform]. Directory platformDirectory(FlutterPlatform platform) { late final String directoryName; diff --git a/script/tool/lib/src/common/xcode.dart b/script/tool/lib/src/common/xcode.dart index 4a4bf03ba549..7ba23fc000d3 100644 --- a/script/tool/lib/src/common/xcode.dart +++ b/script/tool/lib/src/common/xcode.dart @@ -6,7 +6,9 @@ import 'dart:convert'; import 'dart:io' as io; import 'package:file/file.dart'; +import 'package:platform/platform.dart'; +import 'core.dart'; import 'output_utils.dart'; import 'process_runner.dart'; @@ -33,36 +35,81 @@ class Xcode { /// Runs an `xcodebuild` in [directory] with the given parameters. Future runXcodeBuild( Directory exampleDirectory, - String platform, { + String targetPlatform, { List actions = const ['build'], required String workspace, required String scheme, String? configuration, List extraFlags = const [], - }) { - File? disabledSandboxEntitlementFile; - if (actions.contains('test') && platform.toLowerCase() == 'macos') { - disabledSandboxEntitlementFile = _createDisabledSandboxEntitlementFile( - exampleDirectory.childDirectory(platform.toLowerCase()), - configuration ?? 'Debug', - ); - } - final List args = [ - _xcodeBuildCommand, - ...actions, - ...['-workspace', workspace], - ...['-scheme', scheme], - if (configuration != null) ...['-configuration', configuration], - ...extraFlags, - if (disabledSandboxEntitlementFile != null) - 'CODE_SIGN_ENTITLEMENTS=${disabledSandboxEntitlementFile.path}', - ]; - final String completeTestCommand = '$_xcRunCommand ${args.join(' ')}'; - if (log) { - print(completeTestCommand); + required Platform hostPlatform, + }) async { + final FileSystem fileSystem = exampleDirectory.fileSystem; + String? resultBundlePath; + final Directory? logsDirectory = ciLogsDirectory(hostPlatform, fileSystem); + Directory? resultBundleTemp; + try { + if (logsDirectory != null) { + resultBundleTemp = + fileSystem.systemTempDirectory.createTempSync('flutter_xcresult.'); + resultBundlePath = resultBundleTemp.childDirectory('result').path; + } + File? disabledSandboxEntitlementFile; + if (actions.contains('test') && targetPlatform.toLowerCase() == 'macos') { + disabledSandboxEntitlementFile = _createDisabledSandboxEntitlementFile( + exampleDirectory.childDirectory(targetPlatform.toLowerCase()), + configuration ?? 'Debug', + ); + } + final List args = [ + _xcodeBuildCommand, + ...actions, + ...['-workspace', workspace], + ...['-scheme', scheme], + if (resultBundlePath != null) ...[ + '-resultBundlePath', + resultBundlePath + ], + if (configuration != null) ...['-configuration', configuration], + ...extraFlags, + if (disabledSandboxEntitlementFile != null) + 'CODE_SIGN_ENTITLEMENTS=${disabledSandboxEntitlementFile.path}', + ]; + final String completeTestCommand = '$_xcRunCommand ${args.join(' ')}'; + if (log) { + print(completeTestCommand); + } + final int resultExit = await processRunner + .runAndStream(_xcRunCommand, args, workingDir: exampleDirectory); + + if (resultExit != 0 && resultBundleTemp != null) { + final Directory xcresultBundle = + resultBundleTemp.childDirectory('result.xcresult'); + if (logsDirectory != null) { + if (xcresultBundle.existsSync()) { + // Zip the test results to the artifacts directory for upload. + final File zipPath = logsDirectory.childFile( + 'xcodebuild-${DateTime.now().toLocal().toIso8601String()}.zip'); + await processRunner.run( + 'zip', + [ + '-r', + '-9', + '-q', + zipPath.path, + xcresultBundle.basename, + ], + workingDir: resultBundleTemp, + ); + } else { + print( + 'xcresult bundle ${xcresultBundle.path} does not exist, skipping upload'); + } + } + } + return resultExit; + } finally { + resultBundleTemp?.deleteSync(recursive: true); } - return processRunner.runAndStream(_xcRunCommand, args, - workingDir: exampleDirectory); } /// Returns true if [project], which should be an .xcodeproj directory, diff --git a/script/tool/lib/src/create_all_packages_app_command.dart b/script/tool/lib/src/create_all_packages_app_command.dart index ee1804fc1420..ab6b5637dd7b 100644 --- a/script/tool/lib/src/create_all_packages_app_command.dart +++ b/script/tool/lib/src/create_all_packages_app_command.dart @@ -217,7 +217,13 @@ class CreateAllPackagesAppCommand extends PackageCommand { final File gradleFile = app .platformDirectory(FlutterPlatform.android) .childDirectory('app') - .childFile('build.gradle'); + .listSync() + .whereType() + .firstWhere( + (File file) => file.basename.startsWith('build.gradle'), + ); + + final bool gradleFileIsKotlin = gradleFile.basename.endsWith('kts'); // Ensure that there is a dependencies section, so the dependencies addition // below will work. @@ -229,18 +235,18 @@ dependencies {} '''); } - const String lifecycleDependency = - " implementation 'androidx.lifecycle:lifecycle-runtime:2.2.0-rc01'"; + final String lifecycleDependency = gradleFileIsKotlin + ? ' implementation("androidx.lifecycle:lifecycle-runtime:2.2.0-rc01")' + : " implementation 'androidx.lifecycle:lifecycle-runtime:2.2.0-rc01'"; _adjustFile( gradleFile, replacements: >{ - // minSdkVersion 21 is required by camera_android. - 'minSdkVersion': ['minSdkVersion 21'], - 'compileSdkVersion': ['compileSdk 34'], - }, - additions: >{ - 'defaultConfig {': [' multiDexEnabled true'], + if (gradleFileIsKotlin) + 'compileSdk': ['compileSdk = 34'] + else ...>{ + 'compileSdkVersion': ['compileSdk 34'], + } }, regexReplacements: >{ // Tests for https://github.com/flutter/flutter/issues/43383 @@ -273,7 +279,7 @@ dependencies {} final VersionConstraint dartSdkConstraint = originalPubspec.environment?[dartSdkKey] ?? VersionConstraint.compatibleWith( - Version.parse('2.12.0'), + Version.parse('3.0.0'), ); final Map pluginDeps = @@ -297,15 +303,15 @@ dependencies {} // An application cannot depend directly on multiple federated // implementations of the same plugin for the same platform, which means the // app cannot directly depend on both camera_android and - // camera_android_androidx. Since camera_android is endorsed, it will be - // included transitively already, so exclude it from the direct dependency - // list to allow including camera_android_androidx to ensure that they don't - // conflict at build time (if they did, it would be impossible to use - // camera_android_androidx while camera_android is endorsed). + // camera_android_androidx. Since camera_android_androidx is endorsed, it + // will be included transitively already, so exclude it from the direct + // dependency list to allow including camera_android to ensure that they + // don't conflict at build time (if they did, it would be impossible to use + // camera_android while camera_android_androidx is endorsed). // This is special-cased here, rather than being done via the normal // exclusion config file mechanism, because it still needs to be in the // depenedency overrides list to ensure that the version from path is used. - pubspec.dependencies.remove('camera_android'); + pubspec.dependencies.remove('camera_android_camerax'); app.pubspecFile.writeAsStringSync(_pubspecToString(pubspec)); } diff --git a/script/tool/lib/src/custom_test_command.dart b/script/tool/lib/src/custom_test_command.dart index 4042cd14a262..35f74d0809e4 100644 --- a/script/tool/lib/src/custom_test_command.dart +++ b/script/tool/lib/src/custom_test_command.dart @@ -8,7 +8,6 @@ import 'common/package_looping_command.dart'; import 'common/pub_utils.dart'; import 'common/repository_package.dart'; -const String _scriptName = 'run_tests.dart'; const String _legacyScriptName = 'run_tests.sh'; /// A command to run custom, package-local tests on packages. @@ -32,13 +31,14 @@ class CustomTestCommand extends PackageLoopingCommand { @override final String description = 'Runs package-specific custom tests defined in ' - "a package's tool/$_scriptName file.\n\n" + "a package's custom test script.\n\n" 'This command requires "dart" to be in your path.'; @override Future runForPackage(RepositoryPackage package) async { - final File script = - package.directory.childDirectory('tool').childFile(_scriptName); + final File script = package.customTestScript; + final String relativeScriptPath = + getRelativePosixPath(script, from: package.directory); final File legacyScript = package.directory.childFile(_legacyScriptName); String? customSkipReason; bool ranTests = false; @@ -52,7 +52,7 @@ class CustomTestCommand extends PackageLoopingCommand { } final int testExitCode = await processRunner.runAndStream( - 'dart', ['run', 'tool/$_scriptName'], + 'dart', ['run', relativeScriptPath], workingDir: package.directory); if (testExitCode != 0) { return PackageResult.fail(); @@ -64,7 +64,7 @@ class CustomTestCommand extends PackageLoopingCommand { if (legacyScript.existsSync()) { if (platform.isWindows) { customSkipReason = '$_legacyScriptName is not supported on Windows. ' - 'Please migrate to $_scriptName.'; + 'Please migrate to $relativeScriptPath.'; } else { final int exitCode = await processRunner.runAndStream( legacyScript.path, [], @@ -77,7 +77,8 @@ class CustomTestCommand extends PackageLoopingCommand { } if (!ranTests) { - return PackageResult.skip(customSkipReason ?? 'No custom tests'); + return PackageResult.skip( + customSkipReason ?? 'No $relativeScriptPath file'); } return PackageResult.success(); diff --git a/script/tool/lib/src/dart_test_command.dart b/script/tool/lib/src/dart_test_command.dart index 1c188ff38ad9..224fbd010ac6 100644 --- a/script/tool/lib/src/dart_test_command.dart +++ b/script/tool/lib/src/dart_test_command.dart @@ -11,6 +11,15 @@ import 'common/plugin_utils.dart'; import 'common/pub_utils.dart'; import 'common/repository_package.dart'; +const int _exitUnknownTestPlatform = 3; + +enum _TestPlatform { + // Must run in the command-line VM. + vm, + // Must run in a browser. + browser, +} + /// A command to run Dart unit tests for packages. class DartTestCommand extends PackageLoopingCommand { /// Creates an instance of the test command. @@ -76,7 +85,7 @@ class DartTestCommand extends PackageLoopingCommand { return PackageResult.skip( "Non-web plugin tests don't need web testing."); } - if (_requiresVM(package)) { + if (_testOnTarget(package) == _TestPlatform.vm) { // This explict skip is necessary because trying to run tests in a mode // that the package has opted out of returns a non-zero exit code. return PackageResult.skip('Package has opted out of non-vm testing.'); @@ -85,7 +94,8 @@ class DartTestCommand extends PackageLoopingCommand { if (isWebOnlyPluginImplementation) { return PackageResult.skip("Web plugin tests don't need vm testing."); } - if (_requiresNonVM(package)) { + final _TestPlatform? target = _testOnTarget(package); + if (target != null && _testOnTarget(package) != _TestPlatform.vm) { // This explict skip is necessary because trying to run tests in a mode // that the package has opted out of returns a non-zero exit code. return PackageResult.skip('Package has opted out of vm testing.'); @@ -98,11 +108,12 @@ class DartTestCommand extends PackageLoopingCommand { platform = 'chrome'; } - // All the web tests assume the html renderer currently. - final String? webRenderer = (platform == 'chrome') ? 'html' : null; + // All the web tests assume the canvaskit renderer currently. + final String? webRenderer = (platform == 'chrome') ? 'canvaskit' : null; bool passed; if (package.requiresFlutter()) { - passed = await _runFlutterTests(package, platform: platform, webRenderer: webRenderer); + passed = await _runFlutterTests(package, + platform: platform, webRenderer: webRenderer); } else { passed = await _runDartTests(package, platform: platform); } @@ -156,34 +167,39 @@ class DartTestCommand extends PackageLoopingCommand { return exitCode == 0; } - bool _requiresVM(RepositoryPackage package) { - final File testConfig = package.directory.childFile('dart_test.yaml'); - if (!testConfig.existsSync()) { - return false; - } - // test_on lines can be very complex, but in pratice the packages in this - // repo currently only need the ability to require vm or not, so that - // simple directive is all that is currently supported. - final RegExp vmRequrimentRegex = RegExp(r'^test_on:\s*vm$'); - return testConfig - .readAsLinesSync() - .any((String line) => vmRequrimentRegex.hasMatch(line)); - } - - bool _requiresNonVM(RepositoryPackage package) { + /// Returns the required test environment, or null if none is specified. + /// + /// Throws if the target is not recognized. + _TestPlatform? _testOnTarget(RepositoryPackage package) { final File testConfig = package.directory.childFile('dart_test.yaml'); if (!testConfig.existsSync()) { - return false; + return null; } - // test_on lines can be very complex, but in pratice the packages in this - // repo currently only need the ability to require vm or not, so a simple - // one-target directive is all that's supported currently. Making it - // deliberately strict avoids the possibility of accidentally skipping vm - // coverage due to a complex expression that's not handled correctly. - final RegExp testOnRegex = RegExp(r'^test_on:\s*([a-z])*\s*$'); - return testConfig.readAsLinesSync().any((String line) { + final RegExp testOnRegex = RegExp(r'^test_on:\s*([a-z].*[a-z])\s*$'); + for (final String line in testConfig.readAsLinesSync()) { final RegExpMatch? match = testOnRegex.firstMatch(line); - return match != null && match.group(1) != 'vm'; - }); + if (match != null) { + final String targetFilter = match.group(1)!; + // test_on lines can be very complex, but in pratice the packages in + // this repo currently only need the ability to require vm or not, so a + // simple one-target directive is all that's supported currently. + // Making it deliberately strict avoids the possibility of accidentally + // skipping vm coverage due to a complex expression that's not handled + // correctly. + switch (targetFilter) { + case 'vm': + return _TestPlatform.vm; + case 'browser': + return _TestPlatform.browser; + default: + printError('Unknown "test_on" value: "$targetFilter"\n' + "If this value needs to be supported for this package's tests, " + 'please update the repository tooling to support more test_on ' + 'modes.'); + throw ToolExit(_exitUnknownTestPlatform); + } + } + } + return null; } } diff --git a/script/tool/lib/src/drive_examples_command.dart b/script/tool/lib/src/drive_examples_command.dart index f3baa5c7cee6..8ae124856021 100644 --- a/script/tool/lib/src/drive_examples_command.dart +++ b/script/tool/lib/src/drive_examples_command.dart @@ -13,10 +13,10 @@ import 'common/package_looping_command.dart'; import 'common/plugin_utils.dart'; import 'common/repository_package.dart'; -const int _exitNoPlatformFlags = 2; +const int _exitInvalidArgs = 2; const int _exitNoAvailableDevice = 3; -// From https://docs.flutter.dev/testing/integration-tests#running-in-a-browser +// From https://flutter.dev/to/integration-test-on-web const int _chromeDriverPort = 4444; /// A command to run the integration tests for a package's example applications. @@ -40,6 +40,8 @@ class DriveExamplesCommand extends PackageLoopingCommand { help: 'Runs the web implementation of the examples'); argParser.addFlag(platformWindows, help: 'Runs the Windows implementation of the examples'); + argParser.addFlag(kWebWasmFlag, + help: 'Compile to WebAssembly rather than JavaScript'); argParser.addOption( kEnableExperiment, defaultsTo: '', @@ -84,7 +86,7 @@ class DriveExamplesCommand extends PackageLoopingCommand { printError( 'Exactly one of ${platformSwitches.map((String platform) => '--$platform').join(', ')} ' 'must be specified.'); - throw ToolExit(_exitNoPlatformFlags); + throw ToolExit(_exitInvalidArgs); } String? androidDevice; @@ -107,19 +109,32 @@ class DriveExamplesCommand extends PackageLoopingCommand { iOSDevice = devices.first; } + final bool useWasm = getBoolArg(kWebWasmFlag); + final bool hasPlatformWeb = getBoolArg(platformWeb); + if (useWasm && !hasPlatformWeb) { + printError('--wasm is only supported on the web platform'); + throw ToolExit(_exitInvalidArgs); + } + _targetDeviceFlags = >{ if (getBoolArg(platformAndroid)) platformAndroid: ['-d', androidDevice!], if (getBoolArg(platformIOS)) platformIOS: ['-d', iOSDevice!], if (getBoolArg(platformLinux)) platformLinux: ['-d', 'linux'], if (getBoolArg(platformMacOS)) platformMacOS: ['-d', 'macos'], - if (getBoolArg(platformWeb)) + if (hasPlatformWeb) platformWeb: [ '-d', 'web-server', '--web-port=7357', '--browser-name=chrome', - '--web-renderer=html', + if (useWasm) + '--wasm' + // TODO(dit): Clean this up, https://github.com/flutter/flutter/issues/151869 + else if (platform.environment['CHANNEL']?.toLowerCase() == 'master') + '--web-renderer=canvaskit' + else + '--web-renderer=html', if (platform.environment.containsKey('CHROME_EXECUTABLE')) '--chrome-binary=${platform.environment['CHROME_EXECUTABLE']}', ], @@ -213,8 +228,12 @@ class DriveExamplesCommand extends PackageLoopingCommand { } for (final File driver in drivers) { final List failingTargets = await _driveTests( - example, driver, testTargets, - deviceFlags: deviceFlags); + example, + driver, + testTargets, + deviceFlags: deviceFlags, + exampleName: exampleName, + ); for (final File failingTarget in failingTargets) { errors.add( getRelativePosixPath(failingTarget, from: package.directory)); @@ -361,10 +380,16 @@ class DriveExamplesCommand extends PackageLoopingCommand { File driver, List targets, { required List deviceFlags, + required String exampleName, }) async { final List failures = []; final String enableExperiment = getStringArg(kEnableExperiment); + final String screenshotBasename = + '${exampleName.replaceAll(platform.pathSeparator, '_')}-drive'; + final Directory? screenshotDirectory = + ciLogsDirectory(platform, driver.fileSystem) + ?.childDirectory(screenshotBasename); for (final File target in targets) { final int exitCode = await processRunner.runAndStream( @@ -374,6 +399,8 @@ class DriveExamplesCommand extends PackageLoopingCommand { ...deviceFlags, if (enableExperiment.isNotEmpty) '--enable-experiment=$enableExperiment', + if (screenshotDirectory != null) + '--screenshot=${screenshotDirectory.path}', '--driver', getRelativePosixPath(driver, from: example.directory), '--target', @@ -401,6 +428,8 @@ class DriveExamplesCommand extends PackageLoopingCommand { required List testFiles, }) async { final String enableExperiment = getStringArg(kEnableExperiment); + final Directory? logsDirectory = + ciLogsDirectory(platform, testFiles.first.fileSystem); // Workaround for https://github.com/flutter/flutter/issues/135673 // Once that is fixed on stable, this logic can be removed and the command @@ -423,6 +452,7 @@ class DriveExamplesCommand extends PackageLoopingCommand { ...deviceFlags, if (enableExperiment.isNotEmpty) '--enable-experiment=$enableExperiment', + if (logsDirectory != null) '--debug-logs-dir=${logsDirectory.path}', target, ], workingDir: example.directory); diff --git a/script/tool/lib/src/fetch_deps_command.dart b/script/tool/lib/src/fetch_deps_command.dart index f9bdd1beae7f..61a82487c0f1 100644 --- a/script/tool/lib/src/fetch_deps_command.dart +++ b/script/tool/lib/src/fetch_deps_command.dart @@ -87,10 +87,8 @@ class FetchDepsCommand extends PackageLoopingCommand { flutterCommand, [ 'precache', - if (precacheIOS) - '--ios', - if (precacheMacOS) - '--macos', + if (precacheIOS) '--ios', + if (precacheMacOS) '--macos', ], ); if (precacheExitCode != 0) { diff --git a/script/tool/lib/src/format_command.dart b/script/tool/lib/src/format_command.dart index 3091cf2e11f3..b5e6086b5b30 100644 --- a/script/tool/lib/src/format_command.dart +++ b/script/tool/lib/src/format_command.dart @@ -47,7 +47,7 @@ class FormatCommand extends PackageCommand { super.processRunner, super.platform, }) { - argParser.addFlag('fail-on-change', hide: true); + argParser.addFlag(_failonChangeArg, hide: true); argParser.addFlag(_dartArg, help: 'Format Dart files', defaultsTo: true); argParser.addFlag(_clangFormatArg, help: 'Format with "clang-format"', defaultsTo: true); @@ -66,6 +66,7 @@ class FormatCommand extends PackageCommand { static const String _dartArg = 'dart'; static const String _clangFormatArg = 'clang-format'; + static const String _failonChangeArg = 'fail-on-change'; static const String _kotlinArg = 'kotlin'; static const String _javaArg = 'java'; static const String _swiftArg = 'swift'; @@ -109,7 +110,7 @@ class FormatCommand extends PackageCommand { await _formatAndLintSwift(files); } - if (getBoolArg('fail-on-change')) { + if (getBoolArg(_failonChangeArg)) { final bool modified = await _didModifyAnything(); if (modified) { throw ToolExit(exitCommandFoundErrors); @@ -120,8 +121,13 @@ class FormatCommand extends PackageCommand { Future _didModifyAnything() async { final io.ProcessResult modifiedFiles = await processRunner.run( 'git', - ['ls-files', '--modified'], - workingDir: packagesDir, + [ + 'ls-files', + '--modified', + packagesDir.path, + thirdPartyPackagesDir.path + ], + workingDir: packagesDir.parent, logOnError: true, ); if (modifiedFiles.exitCode != 0) { @@ -146,8 +152,8 @@ class FormatCommand extends PackageCommand { final io.ProcessResult diff = await processRunner.run( 'git', - ['diff'], - workingDir: packagesDir, + ['diff', packagesDir.path, thirdPartyPackagesDir.path], + workingDir: packagesDir.parent, logOnError: true, ); if (diff.exitCode != 0) { diff --git a/script/tool/lib/src/gradle_check_command.dart b/script/tool/lib/src/gradle_check_command.dart index 38977d91c984..ab6545054c31 100644 --- a/script/tool/lib/src/gradle_check_command.dart +++ b/script/tool/lib/src/gradle_check_command.dart @@ -202,7 +202,6 @@ class GradleCheckCommand extends PackageLoopingCommand { /// configuration that enables artifact hub env variable. @visibleForTesting static String exampleRootSettingsArtifactHubString = ''' -// See $artifactHubDocumentationString for more info. buildscript { repositories { maven { @@ -216,6 +215,18 @@ buildscript { apply plugin: "com.google.cloud.artifactregistry.gradle-plugin" '''; + /// String printed as a valid example of settings.gradle repository + /// configuration that enables artifact hub env variable. + /// GP stands for the gradle plugin method of flutter tooling inclusion. + @visibleForTesting + static String exampleSettingsArtifactHubStringGP = ''' +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + // ...other plugins + id "com.google.cloud.artifactregistry.gradle-plugin" version "2.2.1" +} + '''; + /// Validates that [gradleLines] reads and uses a artifiact hub repository /// when ARTIFACT_HUB_REPOSITORY is set. /// @@ -228,6 +239,10 @@ apply plugin: "com.google.cloud.artifactregistry.gradle-plugin" r'classpath.*gradle\.plugin\.com\.google\.cloud\.artifactregistry:artifactregistry-gradle-plugin'); final RegExp artifactRegistryPluginApplyRegex = RegExp( r'apply.*plugin.*com\.google\.cloud\.artifactregistry\.gradle-plugin'); + final RegExp artifactRegistryPluginApplyRegexGP = RegExp( + r'id.*com\.google\.cloud\.artifactregistry\.gradle-plugin.*version.*\b\d+\.\d+\.\d+\b'); + final RegExp artifactRegistryPluginApplyDeclarativeRegex = + RegExp(r'\bpluginManagement\b'); final bool documentationPresent = gradleLines .any((String line) => documentationPresentRegex.hasMatch(line)); @@ -235,17 +250,36 @@ apply plugin: "com.google.cloud.artifactregistry.gradle-plugin" .any((String line) => artifactRegistryDefinitionRegex.hasMatch(line)); final bool artifactRegistryPluginApplied = gradleLines .any((String line) => artifactRegistryPluginApplyRegex.hasMatch(line)); + final bool declarativeArtifactRegistryApplied = gradleLines.any( + (String line) => artifactRegistryPluginApplyRegexGP.hasMatch(line)); + final bool declarativePluginBlockApplied = gradleLines.any((String line) => + artifactRegistryPluginApplyDeclarativeRegex.hasMatch(line)); - if (!(documentationPresent && - artifactRegistryDefined && - artifactRegistryPluginApplied)) { - printError('Failed Artifact Hub validation. Include the following in ' - 'example root settings.gradle:\n$exampleRootSettingsArtifactHubString'); - } + final bool imperativeArtifactRegistryApplied = + artifactRegistryDefined && artifactRegistryPluginApplied; + + final bool validArtifactConfiguration = documentationPresent && + (imperativeArtifactRegistryApplied || + declarativeArtifactRegistryApplied); - return documentationPresent && - artifactRegistryDefined && - artifactRegistryPluginApplied; + if (!validArtifactConfiguration) { + printError('Failed Artifact Hub validation.'); + if (!documentationPresent) { + printError( + 'The link to the Artifact Hub documentation is missing. Include the following in ' + 'example root settings.gradle:\n// See $artifactHubDocumentationString for more info.'); + } + if (artifactRegistryDefined || + artifactRegistryPluginApplied || + !declarativePluginBlockApplied) { + printError('Include the following in ' + 'example root settings.gradle:\n$exampleRootSettingsArtifactHubString'); + } else if (!declarativeArtifactRegistryApplied) { + printError('Include the following in ' + 'example root settings.gradle:\n$exampleSettingsArtifactHubStringGP'); + } + } + return validArtifactConfiguration; } /// Validates the top-level build.gradle for an example app (e.g., @@ -298,31 +332,13 @@ apply plugin: "com.google.cloud.artifactregistry.gradle-plugin" final RegExpMatch? namespaceMatch = namespaceRegex.firstMatch(gradleContents); - // For plugins, make sure the namespace is conditionalized so that it - // doesn't break client apps using AGP 4.1 and earlier (which don't have - // a namespace property, and will fail to build if it's set). - const String namespaceConditional = - 'if (project.android.hasProperty("namespace"))'; - String exampleSetNamespace = "namespace 'dev.flutter.foo'"; - if (!isExample) { - exampleSetNamespace = ''' -$namespaceConditional { - $exampleSetNamespace -}'''; - } - // Wrap the namespace command in an `android` block, adding the indentation - // to make it line up correctly. - final String exampleAndroidNamespaceBlock = ''' - android { - ${exampleSetNamespace.split('\n').join('\n ')} - } -'''; - if (namespaceMatch == null) { - final String errorMessage = ''' + const String errorMessage = ''' build.gradle must set a "namespace": -$exampleAndroidNamespaceBlock + android { + namespace 'dev.flutter.foo' + } The value must match the "package" attribute in AndroidManifest.xml, if one is present. For more information, see: @@ -333,18 +349,6 @@ https://developer.android.com/build/publish-library/prep-lib-release#choose-name '$indentation${errorMessage.split('\n').join('\n$indentation')}'); return false; } else { - if (!isExample && !gradleContents.contains(namespaceConditional)) { - final String errorMessage = ''' -build.gradle for a plugin must conditionalize "namespace": - -$exampleAndroidNamespaceBlock -'''; - - printError( - '$indentation${errorMessage.split('\n').join('\n$indentation')}'); - return false; - } - return _validateNamespaceMatchesManifest(package, isExample: isExample, namespace: namespaceMatch.group(1)!); } @@ -398,15 +402,15 @@ build.gradle must set an explicit Java compatibility version. This can be done either via "sourceCompatibility"/"targetCompatibility": android { compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } } or "toolchain": java { toolchain { - languageVersion = JavaLanguageVersion.of(8) + languageVersion = JavaLanguageVersion.of(11) } } diff --git a/script/tool/lib/src/license_check_command.dart b/script/tool/lib/src/license_check_command.dart index 5f01cca7b967..5c401b091827 100644 --- a/script/tool/lib/src/license_check_command.dart +++ b/script/tool/lib/src/license_check_command.dart @@ -42,6 +42,15 @@ const Set _ignoredFullBasenameList = { 'resource.h', // Generated by VS. }; +// Third-party packages where the code doesn't have file-level annotation, just +// the package-level LICENSE file. Each entry must be a directory relative to +// third_party/packages, as that is the only directory where this is allowed. +const Set _unannotatedFileThirdPartyDirectories = { + 'path_parsing', + 'flutter_svg', + 'flutter_svg_test', +}; + // Copyright and license regexes for third-party code. // // These are intentionally very simple, since there is very little third-party @@ -69,6 +78,16 @@ final List _thirdPartyLicenseBlockRegexes = [ r'// Use of this source code is governed by a BSD-style license that can be\n' r'// found in the LICENSE file\.\n', ), + // packages/third_party/path_parsing. + RegExp( + r'Copyright \(c\) 2018 Dan Field\n\n' + r'Permission is hereby granted, free of charge, to any person obtaining a copy\n' + r'of this software and associated documentation files \(the "Software"\), to deal\n' + r'in the Software without restriction, including without limitation the rights\n' + r'to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n' + r'copies of the Software, and to permit persons to whom the Software is\n' + r'furnished to do so, subject to the following conditions:', + ), ]; // The exact format of the BSD license that our license files should contain. @@ -217,10 +236,26 @@ class LicenseCheckCommand extends PackageCommand { for (final File file in codeFiles) { print('Checking ${file.path}'); + // Some third-party directories have code that doesn't annotate each file, + // so for those check the LICENSE file instead. This is done even though + // it's redundant to re-check it for each file because it ensures that we + // are still validating every file individually, rather than having a + // codepath where whole directories of files are ignored, which would have + // a much worse failure mode. + String content; + if (_unannotatedFileThirdPartyDirectories.any( + (String dir) => file.path.contains('/third_party/packages/$dir/'))) { + Directory packageDir = file.parent; + while (packageDir.parent.basename != 'packages') { + packageDir = packageDir.parent; + } + content = await packageDir.childFile('LICENSE').readAsString(); + } else { + content = await file.readAsString(); + } // On Windows, git may auto-convert line endings on checkout; this should // still pass since they will be converted back on commit. - final String content = - (await file.readAsString()).replaceAll('\r\n', '\n'); + content = content.replaceAll('\r\n', '\n'); final String firstParyLicense = firstPartyLicenseBlockByExtension[p.extension(file.path)] ?? diff --git a/script/tool/lib/src/make_deps_path_based_command.dart b/script/tool/lib/src/make_deps_path_based_command.dart index b3682ea6f132..1f096069d5a1 100644 --- a/script/tool/lib/src/make_deps_path_based_command.dart +++ b/script/tool/lib/src/make_deps_path_based_command.dart @@ -153,9 +153,9 @@ class MakeDepsPathBasedCommand extends PackageCommand { return targets; } - /// If [pubspecFile] has any dependencies on packages in [localDependencies], - /// adds dependency_overrides entries to redirect them to the local version - /// using path-based dependencies. + /// If [pubspecFile] has any non-path dependencies on packages in + /// [localDependencies], adds dependency_overrides entries to redirect them to + /// the local version using path-based dependencies. /// /// Returns true if any overrides were added. /// @@ -183,11 +183,13 @@ class MakeDepsPathBasedCommand extends PackageCommand { final Pubspec pubspec = Pubspec.parse(pubspecContents); final Iterable combinedDependencies = [ // Filter out any dependencies with version constraint that wouldn't allow - // the target if published. + // the target if published, and anything that is already path-based. ...>[ ...pubspec.dependencies.entries, ...pubspec.devDependencies.entries, ] + .where((MapEntry element) => + element.value is! PathDependency) .where((MapEntry element) => allowsVersion(element.value, versions[element.key])) .map((MapEntry entry) => entry.key), @@ -205,10 +207,10 @@ class MakeDepsPathBasedCommand extends PackageCommand { } // Find the relative path to the common base. - final String commonBasePath = packagesDir.path; + final String repoRootPath = packagesDir.parent.path; final int packageDepth = path - .split(path.relative(package.directory.absolute.path, - from: commonBasePath)) + .split( + path.relative(package.directory.absolute.path, from: repoRootPath)) .length; final List relativeBasePathComponents = List.filled(packageDepth, '..'); @@ -223,9 +225,8 @@ class MakeDepsPathBasedCommand extends PackageCommand { } for (final String packageName in packagesToOverride) { // Find the relative path from the common base to the local package. - final List repoRelativePathComponents = path.split(path.relative( - localDependencies[packageName]!.path, - from: commonBasePath)); + final List repoRelativePathComponents = path.split(path + .relative(localDependencies[packageName]!.path, from: repoRootPath)); editablePubspec.update([ dependencyOverridesKey, packageName @@ -301,7 +302,7 @@ $dependencyOverridesKey: if (!package.pubspecFile.existsSync()) { final String directoryName = p.posix.joinAll(path.split(path.relative( package.directory.absolute.path, - from: packagesDir.path))); + from: packagesDir.parent.path))); print(' Skipping $directoryName; deleted.'); continue; } diff --git a/script/tool/lib/src/native_test_command.dart b/script/tool/lib/src/native_test_command.dart index 53bf41298d8f..47fd57998765 100644 --- a/script/tool/lib/src/native_test_command.dart +++ b/script/tool/lib/src/native_test_command.dart @@ -367,10 +367,21 @@ this command. 'notAnnotation=io.flutter.plugins.DartIntegrationTest'; print('Running integration tests...'); + // Explicitly request all ABIs, as Flutter would if being called + // without a specific target (see + // https://github.com/flutter/flutter/pull/154476) to ensure it can + // run on any architecture emulator. + const List abis = [ + 'android-arm', + 'android-arm64', + 'android-x64', + 'android-x86' + ]; final int exitCode = await project.runCommand( 'app:connectedAndroidTest', arguments: [ '-Pandroid.testInstrumentationRunnerArguments.$filter', + '-Ptarget-platform=${abis.join(',')}', ], ); if (exitCode != 0) { @@ -420,7 +431,7 @@ this command. /// usually at "example/{ios,macos}/Runner.xcworkspace". Future<_PlatformResult> _runXcodeTests( RepositoryPackage plugin, - String platform, + String targetPlatform, _TestMode mode, { List extraFlags = const [], }) async { @@ -445,7 +456,7 @@ this command. final String? targetToCheck = testTarget ?? (mode.unit ? unitTestTarget : null); final Directory xcodeProject = example.directory - .childDirectory(platform.toLowerCase()) + .childDirectory(targetPlatform.toLowerCase()) .childDirectory('Runner.xcodeproj'); if (targetToCheck != null) { final bool? hasTarget = @@ -462,16 +473,17 @@ this command. } } - _printRunningExampleTestsMessage(example, platform); + _printRunningExampleTestsMessage(example, targetPlatform); final int exitCode = await _xcode.runXcodeBuild( example.directory, - platform, + targetPlatform, // Clean before testing to remove cached swiftmodules from previous // runs, which can cause conflicts. actions: ['clean', 'test'], - workspace: '${platform.toLowerCase()}/Runner.xcworkspace', + workspace: '${targetPlatform.toLowerCase()}/Runner.xcworkspace', scheme: 'Runner', configuration: 'Debug', + hostPlatform: platform, extraFlags: [ if (testTarget != null) '-only-testing:$testTarget', ...extraFlags, @@ -483,9 +495,10 @@ this command. const int xcodebuildNoTestExitCode = 66; switch (exitCode) { case xcodebuildNoTestExitCode: - _printNoExampleTestsMessage(example, platform); + _printNoExampleTestsMessage(example, targetPlatform); case 0: - printSuccess('Successfully ran $platform xctest for $exampleName'); + printSuccess( + 'Successfully ran $targetPlatform xctest for $exampleName'); // If this is the first test, assume success until something fails. if (overallResult == RunState.skipped) { overallResult = RunState.succeeded; @@ -500,7 +513,6 @@ this command. if (exampleHasUnitTests) { ranUnitTests = true; } - break; } } diff --git a/script/tool/lib/src/podspec_check_command.dart b/script/tool/lib/src/podspec_check_command.dart index 4f1b5e0dfa55..e13a6cb02cac 100644 --- a/script/tool/lib/src/podspec_check_command.dart +++ b/script/tool/lib/src/podspec_check_command.dart @@ -95,7 +95,8 @@ class PodspecCheckCommand extends PackageLoopingCommand { } } - if (pluginSupportsPlatform(platformIOS, package) && + if ((pluginSupportsPlatform(platformIOS, package) || + pluginSupportsPlatform(platformMacOS, package)) && !podspecs.any(_hasPrivacyManifest)) { printError('No PrivacyInfo.xcprivacy file specified. Please ensure that ' 'a privacy manifest is included in the build using ' @@ -151,7 +152,6 @@ class PodspecCheckCommand extends PackageLoopingCommand { podspecPath, '--configuration=Debug', // Release targets unsupported arm64 simulators. Use Debug to only build against targeted x86_64 simulator devices. '--skip-tests', - '--use-modular-headers', // Flutter sets use_modular_headers! in its templates. if (libraryLint) '--use-libraries' ]; diff --git a/script/tool/lib/src/publish_check_command.dart b/script/tool/lib/src/publish_check_command.dart index ab7acedb8ee6..4dcaa7cf9303 100644 --- a/script/tool/lib/src/publish_check_command.dart +++ b/script/tool/lib/src/publish_check_command.dart @@ -6,6 +6,7 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io' as io; +import 'package:file/file.dart'; import 'package:http/http.dart' as http; import 'package:pub_semver/pub_semver.dart'; @@ -73,10 +74,20 @@ class PublishCheckCommand extends PackageLoopingCommand { @override Future runForPackage(RepositoryPackage package) async { - _PublishCheckResult? result = await _passesPublishCheck(package); - if (result == null) { + if (_isMarkedAsUnpublishable(package)) { return PackageResult.skip('Package is marked as unpublishable.'); } + + // The pre-publish hook must be run first if it exists, since passing the + // publish check may rely on its execution. + final bool prePublishHookPassesOrNoops = + await _validatePrePublishHook(package); + // Given that, don't run publish check if the pre-publish hook fails. + _PublishCheckResult result = prePublishHookPassesOrNoops + ? await _passesPublishCheck(package) + : _PublishCheckResult.error; + + // But do continue with other checks to find all problems at once. if (!_passesAuthorsCheck(package)) { _printImportantStatusMessage( 'No AUTHORS file found. Packages must include an AUTHORS file.', @@ -196,17 +207,22 @@ class PublishCheckCommand extends PackageLoopingCommand { 'Packages with an SDK constraint on a pre-release of the Dart SDK should themselves be published as a pre-release version.'); } + /// Returns true if the package has been explicitly marked as not for + /// publishing. + bool _isMarkedAsUnpublishable(RepositoryPackage package) { + final Pubspec? pubspec = _tryParsePubspec(package); + return pubspec?.publishTo == 'none'; + } + /// Returns the result of the publish check, or null if the package is marked /// as unpublishable. - Future<_PublishCheckResult?> _passesPublishCheck( + Future<_PublishCheckResult> _passesPublishCheck( RepositoryPackage package) async { final String packageName = package.directory.basename; final Pubspec? pubspec = _tryParsePubspec(package); if (pubspec == null) { print('No valid pubspec found.'); return _PublishCheckResult.error; - } else if (pubspec.publishTo == 'none') { - return null; } final Version? version = pubspec.version; @@ -268,6 +284,33 @@ HTTP response: ${pubVersionFinderResponse.httpResponse.body} return package.authorsFile.existsSync(); } + Future _validatePrePublishHook(RepositoryPackage package) async { + final File script = package.prePublishScript; + if (!script.existsSync()) { + // If there's no custom step, then it can't block publishing. + return true; + } + final String relativeScriptPath = + getRelativePosixPath(script, from: package.directory); + print('Running pre-publish hook $relativeScriptPath...'); + + // Ensure that dependencies are available. + if (!await runPubGet(package, processRunner, platform)) { + _printImportantStatusMessage('Failed to get depenedencies', + isError: true); + return false; + } + + final int exitCode = await processRunner.runAndStream( + 'dart', ['run', relativeScriptPath], + workingDir: package.directory); + if (exitCode != 0) { + _printImportantStatusMessage('Pre-publish script failed.', isError: true); + return false; + } + return true; + } + void _printImportantStatusMessage(String message, {required bool isError}) { final String statusMessage = '${isError ? 'ERROR' : 'SUCCESS'}: $message'; if (getBoolArg(_machineFlag)) { diff --git a/script/tool/lib/src/publish_command.dart b/script/tool/lib/src/publish_command.dart index b678e36b7aba..fbe654644e56 100644 --- a/script/tool/lib/src/publish_command.dart +++ b/script/tool/lib/src/publish_command.dart @@ -21,6 +21,7 @@ import 'common/git_version_finder.dart'; import 'common/output_utils.dart'; import 'common/package_command.dart'; import 'common/package_looping_command.dart'; +import 'common/pub_utils.dart'; import 'common/pub_version_finder.dart'; import 'common/repository_package.dart'; @@ -201,6 +202,10 @@ class PublishCommand extends PackageLoopingCommand { return checkResult; } + if (!await _runPrePublishScript(package)) { + return PackageResult.fail(['pre-publish failed']); + } + if (!await _checkGitStatus(package)) { return PackageResult.fail(['uncommitted changes']); } @@ -375,6 +380,31 @@ Safe to ignore if the package is deleted in this commit. return getRemoteUrlResult.stdout as String?; } + Future _runPrePublishScript(RepositoryPackage package) async { + final File script = package.prePublishScript; + if (!script.existsSync()) { + return true; + } + final String relativeScriptPath = + getRelativePosixPath(script, from: package.directory); + print('Running pre-publish hook $relativeScriptPath...'); + + // Ensure that dependencies are available. + if (!await runPubGet(package, processRunner, platform)) { + printError('Failed to get depenedencies'); + return false; + } + + final int exitCode = await processRunner.runAndStream( + 'dart', ['run', relativeScriptPath], + workingDir: package.directory); + if (exitCode != 0) { + printError('Pre-publish script failed.'); + return false; + } + return true; + } + Future _publish(RepositoryPackage package) async { print('Publishing...'); print('Running `pub publish ${_publishFlags.join(' ')}` in ' diff --git a/script/tool/lib/src/pubspec_check_command.dart b/script/tool/lib/src/pubspec_check_command.dart index 34aa3813a41c..66ac470d8235 100644 --- a/script/tool/lib/src/pubspec_check_command.dart +++ b/script/tool/lib/src/pubspec_check_command.dart @@ -569,8 +569,10 @@ class PubspecCheckCommand extends PackageLoopingCommand { 'test', }; // Non-published packages like pigeon subpackages are allowed to violate - // the dev only dependencies rule. - if (pubspec.publishTo != 'none') { + // the dev only dependencies rule, as are packages that end in `_test` (as + // they are assumed to be intended to be used as dev_dependencies by + // clients). + if (pubspec.publishTo != 'none' && !pubspec.name.endsWith('_test')) { pubspec.dependencies.forEach((String name, Dependency dependency) { if (devOnlyDependencies.contains(name)) { misplacedDevDependencies.add(name); @@ -612,7 +614,8 @@ Please move them to dev_dependencies. if (constraint is VersionRange && constraint.min != null && constraint.max != null && - constraint.min == constraint.max) { + constraint.includeMin && + constraint.includeMax) { return true; } } diff --git a/script/tool/lib/src/update_excerpts_command.dart b/script/tool/lib/src/update_excerpts_command.dart index 4b4147182b10..5c081ff57a73 100644 --- a/script/tool/lib/src/update_excerpts_command.dart +++ b/script/tool/lib/src/update_excerpts_command.dart @@ -149,7 +149,6 @@ class UpdateExcerptsCommand extends PackageLoopingCommand { language = 'groovy'; default: language = extension.substring(1); - break; } final String section = match.namedGroup('section')!; final String plaster = match.namedGroup('plaster') ?? '···'; diff --git a/script/tool/lib/src/update_release_info_command.dart b/script/tool/lib/src/update_release_info_command.dart index 29ff14389b2f..c35759668b6b 100644 --- a/script/tool/lib/src/update_release_info_command.dart +++ b/script/tool/lib/src/update_release_info_command.dart @@ -250,7 +250,7 @@ class UpdateReleaseInfoCommand extends PackageLoopingCommand { /// any missing periods. /// /// E.g., 'A line\nAnother line.' will become: - /// ``` + /// ```none /// [ '* A line.', '* Another line.' ] /// ``` Iterable _changelogAdditionsAsList({String listMarker = '*'}) { diff --git a/script/tool/lib/src/version_check_command.dart b/script/tool/lib/src/version_check_command.dart index 58ad880cbae5..267dd79fbf3e 100644 --- a/script/tool/lib/src/version_check_command.dart +++ b/script/tool/lib/src/version_check_command.dart @@ -392,6 +392,7 @@ ${indentation}HTTP response: ${pubVersionFinderResponse.httpResponse.body} } // Remove all leading mark down syntax from the version line. String? versionString = firstLineWithText?.split(' ').last; + String? leadingMarkdown = firstLineWithText?.split(' ').first; final String badNextErrorMessage = '${indentation}When bumping the version ' 'for release, the NEXT section should be incorporated into the new ' @@ -413,15 +414,18 @@ ${indentation}HTTP response: ${pubVersionFinderResponse.httpResponse.body} // CHANGELOG. That means the next version entry in the CHANGELOG should // pass the normal validation. versionString = null; + leadingMarkdown = null; while (iterator.moveNext()) { if (iterator.current.trim().startsWith('## ')) { versionString = iterator.current.trim().split(' ').last; + leadingMarkdown = iterator.current.trim().split(' ').first; break; } } } - if (versionString == null) { + final bool validLeadingMarkdown = leadingMarkdown == '##'; + if (versionString == null || !validLeadingMarkdown) { printError('${indentation}Unable to find a version in CHANGELOG.md'); print('${indentation}The current version should be on a line starting ' 'with "## ", either on the first non-empty line or after a "## NEXT" ' diff --git a/script/tool/lib/src/xcode_analyze_command.dart b/script/tool/lib/src/xcode_analyze_command.dart index 707a3f08b6d6..ba4b3fb5e95b 100644 --- a/script/tool/lib/src/xcode_analyze_command.dart +++ b/script/tool/lib/src/xcode_analyze_command.dart @@ -97,10 +97,10 @@ class XcodeAnalyzeCommand extends PackageLoopingCommand { multiplePlatformsRequested ? failures : []); } - /// Analyzes [plugin] for [platform], returning true if it passed analysis. + /// Analyzes [plugin] for [targetPlatform], returning true if it passed analysis. Future _analyzePlugin( RepositoryPackage plugin, - String platform, { + String targetPlatform, { List extraFlags = const [], }) async { bool passing = true; @@ -108,25 +108,26 @@ class XcodeAnalyzeCommand extends PackageLoopingCommand { // Running tests and static analyzer. final String examplePath = getRelativePosixPath(example.directory, from: plugin.directory.parent); - print('Running $platform tests and analyzer for $examplePath...'); + print('Running $targetPlatform tests and analyzer for $examplePath...'); final int exitCode = await _xcode.runXcodeBuild( example.directory, - platform, + targetPlatform, // Clean before analyzing to remove cached swiftmodules from previous // runs, which can cause conflicts. actions: ['clean', 'analyze'], - workspace: '${platform.toLowerCase()}/Runner.xcworkspace', + workspace: '${targetPlatform.toLowerCase()}/Runner.xcworkspace', scheme: 'Runner', configuration: 'Debug', + hostPlatform: platform, extraFlags: [ ...extraFlags, 'GCC_TREAT_WARNINGS_AS_ERRORS=YES', ], ); if (exitCode == 0) { - printSuccess('$examplePath ($platform) passed analysis.'); + printSuccess('$examplePath ($targetPlatform) passed analysis.'); } else { - printError('$examplePath ($platform) failed analysis.'); + printError('$examplePath ($targetPlatform) failed analysis.'); passing = false; } } diff --git a/script/tool/pubspec.yaml b/script/tool/pubspec.yaml index fef6bc94e7df..ee24eb90d4fe 100644 --- a/script/tool/pubspec.yaml +++ b/script/tool/pubspec.yaml @@ -6,29 +6,28 @@ publish_to: none dependencies: args: ^2.1.0 - async: ^2.6.1 - collection: ^1.15.0 + async: ^2.10.0 + collection: ^1.17.0 colorize: ^3.0.0 - file: ^6.1.0 - # Pin git to 2.0.x until dart >=2.18 is legacy - git: '>=2.0.0 <2.1.0' - http: '>=0.13.3 <2.0.0' + file: ^7.0.1 + git: ^2.0.0 + http: ^1.0.0 http_multi_server: ^3.0.1 - meta: ^1.3.0 - path: ^1.8.0 - platform: ^3.0.0 + meta: ^1.10.0 + path: ^1.8.3 + platform: ^3.0.2 pub_semver: ^2.0.0 - pubspec_parse: ^1.0.0 + pubspec_parse: ^1.2.2 quiver: ^3.0.1 - test: ^1.17.3 - uuid: ^3.0.4 + test: ^1.24.0 + uuid: ^4.5.1 yaml: ^3.1.0 yaml_edit: ^2.0.2 dev_dependencies: - build_runner: ^2.0.3 - matcher: ^0.12.10 - mockito: '>=5.3.2 <=5.5.0' + build_runner: ^2.2.1 + matcher: ^0.12.15 + mockito: ^5.4.4 environment: - sdk: '>=3.0.0 <4.0.0' + sdk: ^3.1.0 diff --git a/script/tool/test/build_examples_command_test.dart b/script/tool/test/build_examples_command_test.dart index 0c99bfb9ba30..e2f78fcdc5b4 100644 --- a/script/tool/test/build_examples_command_test.dart +++ b/script/tool/test/build_examples_command_test.dart @@ -164,6 +164,53 @@ void main() { ])); }); + test('building for iOS with CocoaPods on master channel', () async { + mockPlatform.isMacOS = true; + mockPlatform.environment['CHANNEL'] = 'master'; + + final RepositoryPackage plugin = createFakePlugin('plugin', packagesDir, + platformSupport: { + platformIOS: const PlatformDetails(PlatformSupport.inline), + }); + + final Directory pluginExampleDirectory = getExampleDir(plugin); + + final List output = await runCapturingPrint(runner, [ + 'build-examples', + '--ios', + '--enable-experiment=exp1', + '--no-swift-package-manager', + ]); + + expect( + output, + containsAllInOrder([ + '\nBUILDING plugin/example for iOS', + ]), + ); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + getFlutterCommand(mockPlatform), + const ['config', '--no-enable-swift-package-manager'], + null, + ), + ProcessCall( + getFlutterCommand(mockPlatform), + const [ + 'build', + 'ios', + '--no-codesign', + '--enable-experiment=exp1' + ], + pluginExampleDirectory.path, + ), + ]), + ); + }); + test('building for iOS with Swift Package Manager on master channel', () async { mockPlatform.isMacOS = true; @@ -212,6 +259,50 @@ void main() { ); }); + test( + 'building for iOS with CocoaPods on stable channel does not disable SPM', + () async { + mockPlatform.isMacOS = true; + mockPlatform.environment['CHANNEL'] = 'stable'; + + final RepositoryPackage plugin = createFakePlugin('plugin', packagesDir, + platformSupport: { + platformIOS: const PlatformDetails(PlatformSupport.inline), + }); + + final Directory pluginExampleDirectory = getExampleDir(plugin); + + final List output = await runCapturingPrint(runner, [ + 'build-examples', + '--ios', + '--enable-experiment=exp1', + '--no-swift-package-manager', + ]); + + expect( + output, + containsAllInOrder([ + '\nBUILDING plugin/example for iOS', + ]), + ); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + getFlutterCommand(mockPlatform), + const [ + 'build', + 'ios', + '--no-codesign', + '--enable-experiment=exp1' + ], + pluginExampleDirectory.path, + ), + ]), + ); + }); + test( 'building for iOS with Swift Package Manager on stable channel does not enable SPM', () async { @@ -353,6 +444,47 @@ void main() { ])); }); + test('building for macOS with CocoaPods on master channel', () async { + mockPlatform.isMacOS = true; + mockPlatform.environment['CHANNEL'] = 'master'; + + final RepositoryPackage plugin = createFakePlugin('plugin', packagesDir, + platformSupport: { + platformMacOS: const PlatformDetails(PlatformSupport.inline), + }); + + final Directory pluginExampleDirectory = getExampleDir(plugin); + + final List output = await runCapturingPrint(runner, + ['build-examples', '--macos', '--no-swift-package-manager']); + + expect( + output, + containsAllInOrder([ + '\nBUILDING plugin/example for macOS', + ]), + ); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + getFlutterCommand(mockPlatform), + const ['config', '--no-enable-swift-package-manager'], + null, + ), + ProcessCall( + getFlutterCommand(mockPlatform), + const [ + 'build', + 'macos', + ], + pluginExampleDirectory.path, + ), + ]), + ); + }); + test('building for macOS with Swift Package Manager on master channel', () async { mockPlatform.isMacOS = true; @@ -395,6 +527,44 @@ void main() { ); }); + test( + 'building for macOS with CocoaPods on stable channel does not disable SPM', + () async { + mockPlatform.isMacOS = true; + mockPlatform.environment['CHANNEL'] = 'stable'; + + final RepositoryPackage plugin = createFakePlugin('plugin', packagesDir, + platformSupport: { + platformMacOS: const PlatformDetails(PlatformSupport.inline), + }); + + final Directory pluginExampleDirectory = getExampleDir(plugin); + + final List output = await runCapturingPrint(runner, + ['build-examples', '--macos', '--no-swift-package-manager']); + + expect( + output, + containsAllInOrder([ + '\nBUILDING plugin/example for macOS', + ]), + ); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + getFlutterCommand(mockPlatform), + const [ + 'build', + 'macos', + ], + pluginExampleDirectory.path, + ), + ]), + ); + }); + test( 'building for macOS with Swift Package Manager on stable channel does not enable SPM', () async { diff --git a/script/tool/test/common/package_command_test.dart b/script/tool/test/common/package_command_test.dart index f80db4181d34..112388642f90 100644 --- a/script/tool/test/common/package_command_test.dart +++ b/script/tool/test/common/package_command_test.dart @@ -455,6 +455,19 @@ packages/plugin1/plugin1/plugin1.dart expect(command.plugins, unorderedEquals([package.path])); }); + test('runs on a package when run from the third_party/packages directory', + () async { + final RepositoryPackage package = + createFakePlugin('a_package', thirdPartyPackagesDir); + createFakePlugin('another_package', thirdPartyPackagesDir); + fileSystem.currentDirectory = package.directory; + + await runCapturingPrint( + runner, ['sample', '--current-package']); + + expect(command.plugins, unorderedEquals([package.path])); + }); + test('runs only app-facing package of a federated plugin', () async { const String pluginName = 'foo'; final Directory groupDir = packagesDir.childDirectory(pluginName); diff --git a/script/tool/test/common/package_command_test.mocks.dart b/script/tool/test/common/package_command_test.mocks.dart index 6c923c7ca268..1ac9d406f1e7 100644 --- a/script/tool/test/common/package_command_test.mocks.dart +++ b/script/tool/test/common/package_command_test.mocks.dart @@ -244,12 +244,16 @@ class MockGitDir extends _i1.Mock implements _i4.GitDir { _i6.Future<_i10.ProcessResult> runCommand( Iterable? args, { bool? throwOnError = true, + bool? echoOutput = false, }) => (super.noSuchMethod( Invocation.method( #runCommand, [args], - {#throwOnError: throwOnError}, + { + #throwOnError: throwOnError, + #echoOutput: echoOutput, + }, ), returnValue: _i6.Future<_i10.ProcessResult>.value( _i5.dummyValue<_i10.ProcessResult>( @@ -257,7 +261,10 @@ class MockGitDir extends _i1.Mock implements _i4.GitDir { Invocation.method( #runCommand, [args], - {#throwOnError: throwOnError}, + { + #throwOnError: throwOnError, + #echoOutput: echoOutput, + }, ), )), ) as _i6.Future<_i10.ProcessResult>); @@ -274,7 +281,7 @@ class MockGitDir extends _i1.Mock implements _i4.GitDir { @override _i6.Future<_i2.Commit?> updateBranch( String? branchName, - _i6.Future Function(_i10.Directory)? populater, + _i6.Future Function(_i10.Directory)? populater, String? commitMessage, ) => (super.noSuchMethod( diff --git a/script/tool/test/common/xcode_test.dart b/script/tool/test/common/xcode_test.dart index 8fd415160015..4d27372890fb 100644 --- a/script/tool/test/common/xcode_test.dart +++ b/script/tool/test/common/xcode_test.dart @@ -165,6 +165,7 @@ void main() { 'ios', workspace: 'A.xcworkspace', scheme: 'AScheme', + hostPlatform: MockPlatform(), ); expect(exitCode, 0); @@ -193,6 +194,7 @@ void main() { workspace: 'A.xcworkspace', scheme: 'AScheme', configuration: 'Debug', + hostPlatform: MockPlatform(), extraFlags: ['-a', '-b', 'c=d']); expect(exitCode, 0); @@ -230,6 +232,7 @@ void main() { 'ios', workspace: 'A.xcworkspace', scheme: 'AScheme', + hostPlatform: MockPlatform(), ); expect(exitCode, 1); @@ -264,6 +267,7 @@ void main() { 'macos', workspace: 'A.xcworkspace', scheme: 'AScheme', + hostPlatform: MockPlatform(), actions: ['test'], ); diff --git a/script/tool/test/create_all_packages_app_command_test.dart b/script/tool/test/create_all_packages_app_command_test.dart index 4e9c00599af4..bed615f12b6f 100644 --- a/script/tool/test/create_all_packages_app_command_test.dart +++ b/script/tool/test/create_all_packages_app_command_test.dart @@ -222,7 +222,7 @@ project 'Runner', { }); test( - 'pubspec special-cases camera_android to remove it from deps but not overrides', + 'pubspec special-cases camera_android_camerax to remove it from deps but not overrides', () async { writeFakeFlutterCreateOutput(testRoot); final Directory cameraDir = packagesDir.childDirectory('camera'); @@ -241,16 +241,16 @@ project 'Runner', { expect(cameraDependency, isA()); expect((cameraDependency! as PathDependency).path, endsWith('/packages/camera/camera')); - expect(cameraCameraXDependency, isA()); - expect((cameraCameraXDependency! as PathDependency).path, - endsWith('/packages/camera/camera_android_camerax')); - expect(cameraAndroidDependency, null); - - final Dependency? cameraAndroidOverride = - pubspec.dependencyOverrides['camera_android']; - expect(cameraAndroidOverride, isA()); - expect((cameraAndroidOverride! as PathDependency).path, + expect(cameraAndroidDependency, isA()); + expect((cameraAndroidDependency! as PathDependency).path, endsWith('/packages/camera/camera_android')); + expect(cameraCameraXDependency, null); + + final Dependency? cameraCameraXOverride = + pubspec.dependencyOverrides['camera_android_camerax']; + expect(cameraCameraXOverride, isA()); + expect((cameraCameraXOverride! as PathDependency).path, + endsWith('/packages/camera/camera_android_camerax')); }); test('legacy files are copied when requested', () async { @@ -342,7 +342,6 @@ android { buildGradle, containsAll([ contains('This is the legacy file'), - contains('minSdkVersion 21'), contains('compileSdk 34'), ])); }); @@ -376,9 +375,7 @@ android { expect( buildGradle, containsAll([ - contains('minSdkVersion 21'), contains('compileSdk 34'), - contains('multiDexEnabled true'), contains('androidx.lifecycle:lifecycle-runtime'), ])); }); diff --git a/script/tool/test/dart_test_command_test.dart b/script/tool/test/dart_test_command_test.dart index d56bb44b0fb1..29e1959e38e1 100644 --- a/script/tool/test/dart_test_command_test.dart +++ b/script/tool/test/dart_test_command_test.dart @@ -249,6 +249,68 @@ void main() { ); }); + test('throws for an unrecognized test_on type', () async { + final RepositoryPackage package = createFakePackage( + 'a_package', + packagesDir, + extraFiles: ['test/empty_test.dart'], + ); + package.directory.childFile('dart_test.yaml').writeAsStringSync(''' +test_on: unknown +'''); + + Error? commandError; + final List output = await runCapturingPrint( + runner, ['dart-test', '--platform=vm'], + errorHandler: (Error e) { + commandError = e; + }); + + expect(commandError, isA()); + + expect( + output, + containsAllInOrder( + [ + contains('Unknown "test_on" value: "unknown"\n' + "If this value needs to be supported for this package's " + 'tests, please update the repository tooling to support more ' + 'test_on modes.'), + ], + )); + }); + + test('throws for an valid but complex test_on directive', () async { + final RepositoryPackage package = createFakePackage( + 'a_package', + packagesDir, + extraFiles: ['test/empty_test.dart'], + ); + package.directory.childFile('dart_test.yaml').writeAsStringSync(''' +test_on: vm && browser +'''); + + Error? commandError; + final List output = await runCapturingPrint( + runner, ['dart-test', '--platform=vm'], + errorHandler: (Error e) { + commandError = e; + }); + + expect(commandError, isA()); + + expect( + output, + containsAllInOrder( + [ + contains('Unknown "test_on" value: "vm && browser"\n' + "If this value needs to be supported for this package's " + 'tests, please update the repository tooling to support more ' + 'test_on modes.'), + ], + )); + }); + test('runs in Chrome when requested for Flutter package', () async { final RepositoryPackage package = createFakePackage( 'a_package', @@ -265,7 +327,12 @@ void main() { orderedEquals([ ProcessCall( getFlutterCommand(mockPlatform), - const ['test', '--color', '--platform=chrome', '--web-renderer=html'], + const [ + 'test', + '--color', + '--platform=chrome', + '--web-renderer=canvaskit', + ], package.path), ]), ); @@ -289,7 +356,12 @@ void main() { orderedEquals([ ProcessCall( getFlutterCommand(mockPlatform), - const ['test', '--color', '--platform=chrome', '--web-renderer=html'], + const [ + 'test', + '--color', + '--platform=chrome', + '--web-renderer=canvaskit', + ], plugin.path), ]), ); @@ -314,7 +386,12 @@ void main() { orderedEquals([ ProcessCall( getFlutterCommand(mockPlatform), - const ['test', '--color', '--platform=chrome', '--web-renderer=html'], + const [ + 'test', + '--color', + '--platform=chrome', + '--web-renderer=canvaskit', + ], plugin.path), ]), ); @@ -339,7 +416,12 @@ void main() { orderedEquals([ ProcessCall( getFlutterCommand(mockPlatform), - const ['test', '--color', '--platform=chrome', '--web-renderer=html'], + const [ + 'test', + '--color', + '--platform=chrome', + '--web-renderer=canvaskit', + ], plugin.path), ]), ); @@ -409,7 +491,12 @@ void main() { orderedEquals([ ProcessCall( getFlutterCommand(mockPlatform), - const ['test', '--color', '--platform=chrome', '--web-renderer=html'], + const [ + 'test', + '--color', + '--platform=chrome', + '--web-renderer=canvaskit', + ], plugin.path), ]), ); @@ -459,6 +546,30 @@ test_on: vm ); }); + test('does not skip running vm in vm mode', () async { + final RepositoryPackage package = createFakePackage( + 'a_package', + packagesDir, + extraFiles: ['test/empty_test.dart'], + ); + package.directory.childFile('dart_test.yaml').writeAsStringSync(''' +test_on: vm +'''); + + final List output = await runCapturingPrint( + runner, ['dart-test', '--platform=vm']); + + expect( + output, + isNot(containsAllInOrder([ + contains('Package has opted out'), + ]))); + expect( + processRunner.recordedCalls, + isNotEmpty, + ); + }); + test('skips running in vm mode if package opts out', () async { final RepositoryPackage package = createFakePackage( 'a_package', @@ -483,6 +594,30 @@ test_on: browser ); }); + test('does not skip running browser in browser mode', () async { + final RepositoryPackage package = createFakePackage( + 'a_package', + packagesDir, + extraFiles: ['test/empty_test.dart'], + ); + package.directory.childFile('dart_test.yaml').writeAsStringSync(''' +test_on: browser +'''); + + final List output = await runCapturingPrint( + runner, ['dart-test', '--platform=browser']); + + expect( + output, + isNot(containsAllInOrder([ + contains('Package has opted out'), + ]))); + expect( + processRunner.recordedCalls, + isNotEmpty, + ); + }); + test('tries to run for a test_on that the tool does not recognize', () async { final RepositoryPackage package = createFakePackage( diff --git a/script/tool/test/drive_examples_command_test.dart b/script/tool/test/drive_examples_command_test.dart index 92d4921a0b35..a1d48865bc4a 100644 --- a/script/tool/test/drive_examples_command_test.dart +++ b/script/tool/test/drive_examples_command_test.dart @@ -38,6 +38,10 @@ void main() { runner = CommandRunner( 'drive_examples_command', 'Test for drive_example_command'); runner.addCommand(command); + + // TODO(dit): Clean this up, https://github.com/flutter/flutter/issues/151869 + mockPlatform.environment['CHANNEL'] = 'master'; + mockPlatform.environment['FLUTTER_LOGS_DIR'] = '/path/to/logs'; }); void setMockFlutterDevicesOutput({ @@ -86,6 +90,24 @@ void main() { ); }); + test('fails if wasm flag is present but not web platform', () async { + setMockFlutterDevicesOutput(); + Error? commandError; + final List output = await runCapturingPrint( + runner, ['drive-examples', '--android', '--wasm'], + errorHandler: (Error e) { + commandError = e; + }); + + expect(commandError, isA()); + expect( + output, + containsAllInOrder([ + contains('--wasm is only supported on the web platform'), + ]), + ); + }); + test('fails if multiple platforms are provided', () async { setMockFlutterDevicesOutput(); Error? commandError; @@ -297,6 +319,57 @@ void main() { ]), ); + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall(getFlutterCommand(mockPlatform), + const ['devices', '--machine'], null), + ProcessCall( + getFlutterCommand(mockPlatform), + const [ + 'test', + '-d', + _fakeIOSDevice, + '--debug-logs-dir=/path/to/logs', + 'integration_test', + ], + pluginExampleDirectory.path), + ])); + }); + + test('handles missing CI debug logs directory', () async { + mockPlatform.environment.remove('FLUTTER_LOGS_DIR'); + + final RepositoryPackage plugin = createFakePlugin( + 'plugin', + packagesDir, + extraFiles: [ + 'example/integration_test/bar_test.dart', + 'example/integration_test/foo_test.dart', + 'example/integration_test/ignore_me.dart', + 'example/android/android.java', + 'example/ios/ios.m', + ], + platformSupport: { + platformAndroid: const PlatformDetails(PlatformSupport.inline), + platformIOS: const PlatformDetails(PlatformSupport.inline), + }, + ); + + final Directory pluginExampleDirectory = getExampleDir(plugin); + + setMockFlutterDevicesOutput(); + final List output = + await runCapturingPrint(runner, ['drive-examples', '--ios']); + + expect( + output, + containsAllInOrder([ + contains('Running for plugin'), + contains('No issues found!'), + ]), + ); + expect( processRunner.recordedCalls, orderedEquals([ @@ -375,6 +448,7 @@ void main() { 'test', '-d', 'linux', + '--debug-logs-dir=/path/to/logs', 'integration_test', ], pluginExampleDirectory.path), @@ -442,6 +516,7 @@ void main() { 'test', '-d', 'macos', + '--debug-logs-dir=/path/to/logs', 'integration_test', ], pluginExampleDirectory.path), @@ -489,6 +564,7 @@ void main() { 'test', '-d', 'macos', + '--debug-logs-dir=/path/to/logs', 'integration_test/first_test.dart', ], pluginExampleDirectory.path), @@ -498,6 +574,7 @@ void main() { 'test', '-d', 'macos', + '--debug-logs-dir=/path/to/logs', 'integration_test/second_test.dart', ], pluginExampleDirectory.path), @@ -544,6 +621,7 @@ void main() { 'test', '-d', 'linux', + '--debug-logs-dir=/path/to/logs', 'integration_test/first_test.dart', ], pluginExampleDirectory.path), @@ -553,6 +631,7 @@ void main() { 'test', '-d', 'linux', + '--debug-logs-dir=/path/to/logs', 'integration_test/second_test.dart', ], pluginExampleDirectory.path), @@ -599,6 +678,7 @@ void main() { 'test', '-d', 'windows', + '--debug-logs-dir=/path/to/logs', 'integration_test/first_test.dart', ], pluginExampleDirectory.path), @@ -608,6 +688,7 @@ void main() { 'test', '-d', 'windows', + '--debug-logs-dir=/path/to/logs', 'integration_test/second_test.dart', ], pluginExampleDirectory.path), @@ -667,6 +748,113 @@ void main() { ]), ); + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + getFlutterCommand(mockPlatform), + const [ + 'drive', + '-d', + 'web-server', + '--web-port=7357', + '--browser-name=chrome', + '--web-renderer=canvaskit', + '--screenshot=/path/to/logs/plugin_example-drive', + '--driver', + 'test_driver/integration_test.dart', + '--target', + 'integration_test/plugin_test.dart', + ], + pluginExampleDirectory.path), + ])); + }); + + test('drives a web plugin compiled to WASM', () async { + final RepositoryPackage plugin = createFakePlugin( + 'plugin', + packagesDir, + extraFiles: [ + 'example/integration_test/plugin_test.dart', + 'example/test_driver/integration_test.dart', + 'example/web/index.html', + ], + platformSupport: { + platformWeb: const PlatformDetails(PlatformSupport.inline), + }, + ); + + final Directory pluginExampleDirectory = getExampleDir(plugin); + + final List output = await runCapturingPrint(runner, [ + 'drive-examples', + '--web', + '--wasm', + ]); + + expect( + output, + containsAllInOrder([ + contains('Running for plugin'), + contains('No issues found!'), + ]), + ); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + getFlutterCommand(mockPlatform), + const [ + 'drive', + '-d', + 'web-server', + '--web-port=7357', + '--browser-name=chrome', + '--wasm', + '--screenshot=/path/to/logs/plugin_example-drive', + '--driver', + 'test_driver/integration_test.dart', + '--target', + 'integration_test/plugin_test.dart', + ], + pluginExampleDirectory.path), + ])); + }); + + // TODO(dit): Clean this up, https://github.com/flutter/flutter/issues/151869 + test('drives a web plugin (html renderer in stable)', () async { + // Override the platform to simulate CHANNEL: stable + mockPlatform.environment['CHANNEL'] = 'stable'; + + final RepositoryPackage plugin = createFakePlugin( + 'plugin', + packagesDir, + extraFiles: [ + 'example/integration_test/plugin_test.dart', + 'example/test_driver/integration_test.dart', + 'example/web/index.html', + ], + platformSupport: { + platformWeb: const PlatformDetails(PlatformSupport.inline), + }, + ); + + final Directory pluginExampleDirectory = getExampleDir(plugin); + + final List output = await runCapturingPrint(runner, [ + 'drive-examples', + '--web', + ]); + + expect( + output, + containsAllInOrder([ + contains('Running for plugin'), + contains('No issues found!'), + ]), + ); + expect( processRunner.recordedCalls, orderedEquals([ @@ -679,6 +867,7 @@ void main() { '--web-port=7357', '--browser-name=chrome', '--web-renderer=html', + '--screenshot=/path/to/logs/plugin_example-drive', '--driver', 'test_driver/integration_test.dart', '--target', @@ -727,7 +916,8 @@ void main() { 'web-server', '--web-port=7357', '--browser-name=chrome', - '--web-renderer=html', + '--web-renderer=canvaskit', + '--screenshot=/path/to/logs/plugin_example-drive', '--driver', 'test_driver/integration_test.dart', '--target', @@ -779,8 +969,9 @@ void main() { 'web-server', '--web-port=7357', '--browser-name=chrome', - '--web-renderer=html', + '--web-renderer=canvaskit', '--chrome-binary=/path/to/chrome', + '--screenshot=/path/to/logs/plugin_example-drive', '--driver', 'test_driver/integration_test.dart', '--target', @@ -851,6 +1042,7 @@ void main() { 'test', '-d', 'windows', + '--debug-logs-dir=/path/to/logs', 'integration_test', ], pluginExampleDirectory.path), @@ -897,6 +1089,7 @@ void main() { 'test', '-d', _fakeAndroidDevice, + '--debug-logs-dir=/path/to/logs', 'integration_test', ], pluginExampleDirectory.path), @@ -943,6 +1136,7 @@ void main() { 'test', '-d', _fakeAndroidDevice, + '--debug-logs-dir=/path/to/logs', 'integration_test', ], pluginExampleDirectory.path), @@ -1071,6 +1265,7 @@ void main() { '-d', _fakeIOSDevice, '--enable-experiment=exp1', + '--debug-logs-dir=/path/to/logs', 'integration_test', ], pluginExampleDirectory.path), @@ -1226,7 +1421,8 @@ void main() { 'web-server', '--web-port=7357', '--browser-name=chrome', - '--web-renderer=html', + '--web-renderer=canvaskit', + '--screenshot=/path/to/logs/plugin_example-drive', '--driver', 'test_driver/integration_test.dart', '--target', @@ -1241,7 +1437,8 @@ void main() { 'web-server', '--web-port=7357', '--browser-name=chrome', - '--web-renderer=html', + '--web-renderer=canvaskit', + '--screenshot=/path/to/logs/plugin_example-drive', '--driver', 'test_driver/integration_test.dart', '--target', @@ -1299,6 +1496,7 @@ void main() { 'test', '-d', _fakeIOSDevice, + '--debug-logs-dir=/path/to/logs', 'integration_test', ], pluginExampleDirectory.path), @@ -1339,7 +1537,53 @@ void main() { 'web-server', '--web-port=7357', '--browser-name=chrome', - '--web-renderer=html', + '--web-renderer=canvaskit', + '--screenshot=/path/to/logs/a_package_example-drive', + '--driver', + 'test_driver/integration_test.dart', + '--target', + 'integration_test/foo_test.dart' + ], + exampleDirectory.path), + ])); + }); + + test('drive handles missing CI screenshot directory', () async { + mockPlatform.environment.remove('FLUTTER_LOGS_DIR'); + + final RepositoryPackage package = + createFakePackage('a_package', packagesDir, extraFiles: [ + 'example/integration_test/foo_test.dart', + 'example/test_driver/integration_test.dart', + 'example/web/index.html', + ]); + final Directory exampleDirectory = getExampleDir(package); + + final List output = await runCapturingPrint(runner, [ + 'drive-examples', + '--web', + ]); + + expect( + output, + containsAllInOrder([ + contains('Running for a_package'), + contains('No issues found!'), + ]), + ); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + getFlutterCommand(mockPlatform), + const [ + 'drive', + '-d', + 'web-server', + '--web-port=7357', + '--browser-name=chrome', + '--web-renderer=canvaskit', '--driver', 'test_driver/integration_test.dart', '--target', @@ -1419,7 +1663,8 @@ void main() { 'web-server', '--web-port=7357', '--browser-name=chrome', - '--web-renderer=html', + '--web-renderer=canvaskit', + '--screenshot=/path/to/logs/a_package_example_with_web-drive', '--driver', 'test_driver/integration_test.dart', '--target', diff --git a/script/tool/test/format_command_test.dart b/script/tool/test/format_command_test.dart index d05aa14c2de8..33f5104ce136 100644 --- a/script/tool/test/format_command_test.dart +++ b/script/tool/test/format_command_test.dart @@ -814,6 +814,25 @@ void main() { 'https://github.com/flutter/packages/blob/main/script/tool/README.md#format-code'), contains('patch -p1 <[ + ProcessCall( + 'git', + [ + 'ls-files', + '--modified', + packagesDir.path, + thirdPartyDir.path + ], + packagesDir.parent.path, + ), + ])); }); test('fails if git ls-files fails', () async { diff --git a/script/tool/test/gradle_check_command_test.dart b/script/tool/test/gradle_check_command_test.dart index 2e1b7146a41a..457f3f40b02b 100644 --- a/script/tool/test/gradle_check_command_test.dart +++ b/script/tool/test/gradle_check_command_test.dart @@ -41,7 +41,6 @@ void main() { bool includeTargetCompat = false, bool commentSourceLanguage = false, bool includeNamespace = true, - bool conditionalizeNamespace = true, bool commentNamespace = false, bool warningsConfigured = true, }) { @@ -54,7 +53,7 @@ void main() { lintOptions { checkAllWarnings true warningsAsErrors true - disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency' + disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency', 'NewerVersionAvailable' baseline file("lint-baseline.xml") } '''; @@ -67,18 +66,11 @@ java { '''; final String sourceCompat = - '${commentSourceLanguage ? '// ' : ''}sourceCompatibility JavaVersion.VERSION_1_8'; + '${commentSourceLanguage ? '// ' : ''}sourceCompatibility JavaVersion.VERSION_11'; final String targetCompat = - '${commentSourceLanguage ? '// ' : ''}targetCompatibility JavaVersion.VERSION_1_8'; - String namespace = + '${commentSourceLanguage ? '// ' : ''}targetCompatibility JavaVersion.VERSION_11'; + final String namespace = " ${commentNamespace ? '// ' : ''}namespace '$_defaultFakeNamespace'"; - if (conditionalizeNamespace) { - namespace = ''' - if (project.android.hasProperty("namespace")) { - $namespace - } -'''; - } buildGradle.writeAsStringSync(''' group 'dev.flutter.plugins.fake' @@ -182,6 +174,7 @@ ${warningsConfigured ? warningConfig : ''} void writeFakeExampleTopLevelSettingsGradle( RepositoryPackage package, { bool includeArtifactHub = true, + bool includeArtifactDocumentation = true, }) { final File settingsGradle = package .platformDirectory(FlutterPlatform.android) @@ -204,10 +197,58 @@ plugins.each { name, path -> include ":\$name" project(":\$name").projectDir = pluginDirectory } +${includeArtifactDocumentation ? '// See ${GradleCheckCommand.artifactHubDocumentationString} for more info.' : ''} ${includeArtifactHub ? GradleCheckCommand.exampleRootSettingsArtifactHubString : ''} '''); } + /// Writes a fake android/build.gradle file for an example [package] with the + /// given options. + void writeFakeExampleSettingsGradle( + RepositoryPackage package, { + bool includeArtifactHub = true, + bool includeArtifactDocumentation = true, + }) { + final File settingsGradle = package + .platformDirectory(FlutterPlatform.android) + .childFile('settings.gradle'); + settingsGradle.createSync(recursive: true); + + /// String printed as a valid example of settings.gradle repository + /// configuration without the artifact hub env variable. + /// GP stands for the gradle plugin method of flutter tooling inclusion. + const String exampleSettingsWithoutArtifactHubStringGP = ''' +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + // ...other plugins +} + '''; + + settingsGradle.writeAsStringSync(''' +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 + }() + + includeBuild("\$flutterSdkPath/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +${includeArtifactDocumentation ? '// See ${GradleCheckCommand.artifactHubDocumentationString} for more info.' : ''} +${includeArtifactHub ? GradleCheckCommand.exampleSettingsArtifactHubStringGP : exampleSettingsWithoutArtifactHubStringGP} +include ":app" +'''); + } + /// Writes a fake android/app/build.gradle file for an example [package] with /// the given options. void writeFakeExampleAppBuildGradle( @@ -266,6 +307,7 @@ dependencies { String? kotlinVersion, bool includeBuildArtifactHub = true, bool includeSettingsArtifactHub = true, + bool includeSettingsDocumentationArtifactHub = true, }) { writeFakeExampleTopLevelBuildGradle( package, @@ -279,6 +321,34 @@ dependencies { writeFakeExampleTopLevelSettingsGradle( package, includeArtifactHub: includeSettingsArtifactHub, + includeArtifactDocumentation: includeSettingsDocumentationArtifactHub, + ); + } + + void writeFakeExampleBuildGradleGP( + RepositoryPackage package, { + required String pluginName, + bool includeNamespace = true, + bool commentNamespace = false, + bool warningsConfigured = true, + String? kotlinVersion, + required bool includeBuildArtifactHub, + required bool includeSettingsArtifactHub, + required bool includeSettingsDocumentationArtifactHub, + }) { + writeFakeExampleTopLevelBuildGradle( + package, + pluginName: pluginName, + warningsConfigured: warningsConfigured, + kotlinVersion: kotlinVersion, + includeArtifactHub: includeBuildArtifactHub, + ); + writeFakeExampleAppBuildGradle(package, + includeNamespace: includeNamespace, commentNamespace: commentNamespace); + writeFakeExampleSettingsGradle( + package, + includeArtifactHub: includeSettingsArtifactHub, + includeArtifactDocumentation: includeSettingsDocumentationArtifactHub, ); } @@ -490,28 +560,6 @@ dependencies { ); }); - test('fails when plugin namespace is not conditional', () async { - final RepositoryPackage package = - createFakePlugin('a_plugin', packagesDir, examples: []); - writeFakePluginBuildGradle(package, - includeLanguageVersion: true, conditionalizeNamespace: false); - writeFakeManifest(package); - - Error? commandError; - final List output = await runCapturingPrint( - runner, ['gradle-check'], errorHandler: (Error e) { - commandError = e; - }); - - expect(commandError, isA()); - expect( - output, - containsAllInOrder([ - contains('build.gradle for a plugin must conditionalize "namespace"'), - ]), - ); - }); - test('fails when namespace is missing', () async { final RepositoryPackage package = createFakePlugin('a_plugin', packagesDir, examples: []); @@ -700,14 +748,14 @@ dependencies { writeFakePluginBuildGradle(package, includeLanguageVersion: true); writeFakeManifest(package); final RepositoryPackage example = package.getExamples().first; - writeFakeExampleBuildGradles( - example, - pluginName: packageName, - // ignore: avoid_redundant_argument_values - includeBuildArtifactHub: true, - // ignore: avoid_redundant_argument_values - includeSettingsArtifactHub: true, - ); + writeFakeExampleBuildGradles(example, + pluginName: packageName, + // ignore: avoid_redundant_argument_values + includeBuildArtifactHub: true, + // ignore: avoid_redundant_argument_values + includeSettingsArtifactHub: true, + // ignore: avoid_redundant_argument_values + includeSettingsDocumentationArtifactHub: true); writeFakeManifest(example, isApp: true); final List output = @@ -819,6 +867,71 @@ dependencies { isNot(contains(GradleCheckCommand.exampleRootGradleArtifactHubString)), ); }); + + test('prints error for declarative method of applying gradle plugins', + () async { + const String packageName = 'a_package'; + final RepositoryPackage package = + createFakePackage('a_package', packagesDir); + writeFakePluginBuildGradle(package, includeLanguageVersion: true); + writeFakeManifest(package); + final RepositoryPackage example = package.getExamples().first; + writeFakeExampleBuildGradleGP(example, + pluginName: packageName, + includeBuildArtifactHub: true, + includeSettingsArtifactHub: false, + includeSettingsDocumentationArtifactHub: true); + writeFakeManifest(example, isApp: true); + + Error? commandError; + final List output = await runCapturingPrint( + runner, ['gradle-check'], errorHandler: (Error e) { + commandError = e; + }); + + expect(commandError, isA()); + expect( + output, + containsAllInOrder([ + contains(GradleCheckCommand.exampleSettingsArtifactHubStringGP), + ]), + ); + expect( + output, + isNot( + contains(GradleCheckCommand.exampleRootSettingsArtifactHubString)), + ); + }); + + test('error message is printed when documentation link is missing', + () async { + const String packageName = 'a_package'; + final RepositoryPackage package = + createFakePackage('a_package', packagesDir); + writeFakePluginBuildGradle(package, includeLanguageVersion: true); + writeFakeManifest(package); + final RepositoryPackage example = package.getExamples().first; + writeFakeExampleBuildGradleGP(example, + pluginName: packageName, + includeBuildArtifactHub: true, + includeSettingsArtifactHub: true, + includeSettingsDocumentationArtifactHub: false); + writeFakeManifest(example, isApp: true); + + Error? commandError; + final List output = await runCapturingPrint( + runner, ['gradle-check'], errorHandler: (Error e) { + commandError = e; + }); + + expect(commandError, isA()); + expect( + output, + containsAllInOrder([ + contains(GradleCheckCommand.artifactHubDocumentationString), + ]), + ); + }); }); group('Kotlin version check', () { diff --git a/script/tool/test/make_deps_path_based_command_test.dart b/script/tool/test/make_deps_path_based_command_test.dart index 25b0aba2831e..532d56f89716 100644 --- a/script/tool/test/make_deps_path_based_command_test.dart +++ b/script/tool/test/make_deps_path_based_command_test.dart @@ -64,6 +64,21 @@ void main() { package.pubspecFile.writeAsStringSync(lines.join('\n')); } + /// Adds dummy 'dependencies:' entries for each package in [dependencies] + /// to [package], using a path-based dependency. + void addPathDependencies( + RepositoryPackage package, Iterable dependencies, + {required String relativePathBase}) { + final List lines = package.pubspecFile.readAsLinesSync(); + final int dependenciesStartIndex = lines.indexOf('dependencies:'); + assert(dependenciesStartIndex != -1); + lines.insertAll(dependenciesStartIndex + 1, [ + for (final String dependency in dependencies) + ' $dependency: { path: $relativePathBase$dependency }', + ]); + package.pubspecFile.writeAsStringSync(lines.join('\n')); + } + /// Adds a 'dev_dependencies:' section with entries for each package in /// [dependencies] to [package]. void addDevDependenciesSection( @@ -172,15 +187,15 @@ ${devDependencies.map((String dep) => ' $dep: $constraint').join('\n')} final Map simplePackageOverrides = getDependencyOverrides(simplePackage); expect(simplePackageOverrides.length, 2); - expect(simplePackageOverrides['bar'], '../bar/bar'); + expect(simplePackageOverrides['bar'], '../../packages/bar/bar'); expect(simplePackageOverrides['bar_platform_interface'], - '../bar/bar_platform_interface'); + '../../packages/bar/bar_platform_interface'); final Map appFacingPackageOverrides = getDependencyOverrides(pluginAppFacing); expect(appFacingPackageOverrides.length, 1); expect(appFacingPackageOverrides['bar_platform_interface'], - '../../bar/bar_platform_interface'); + '../../../packages/bar/bar_platform_interface'); }); test('rewrites "dev_dependencies" references', () async { @@ -205,7 +220,7 @@ ${devDependencies.map((String dep) => ' $dep: $constraint').join('\n')} final Map overrides = getDependencyOverrides(builderPackage); expect(overrides.length, 1); - expect(overrides['foo'], '../foo'); + expect(overrides['foo'], '../../packages/foo'); }); test('rewrites examples when rewriting the main package', () async { @@ -230,7 +245,8 @@ ${devDependencies.map((String dep) => ' $dep: $constraint').join('\n')} final Map exampleOverrides = getDependencyOverrides(pluginAppFacing.getExamples().first); expect(exampleOverrides.length, 1); - expect(exampleOverrides['bar_android'], '../../../bar/bar_android'); + expect(exampleOverrides['bar_android'], + '../../../../packages/bar/bar_android'); }); test('example overrides include both local and main-package dependencies', @@ -258,8 +274,24 @@ ${devDependencies.map((String dep) => ' $dep: $constraint').join('\n')} final Map exampleOverrides = getDependencyOverrides(pluginAppFacing.getExamples().first); expect(exampleOverrides.length, 2); - expect(exampleOverrides['another_package'], '../../../another_package'); - expect(exampleOverrides['bar_android'], '../../../bar/bar_android'); + expect(exampleOverrides['another_package'], + '../../../../packages/another_package'); + expect(exampleOverrides['bar_android'], + '../../../../packages/bar/bar_android'); + }); + + test('does not rewrite path-based dependencies that are already path based', + () async { + final RepositoryPackage package = createFakePlugin('foo', packagesDir); + final RepositoryPackage example = package.getExamples().first; + addPathDependencies(example, ['foo'], relativePathBase: '../'); + + await runCapturingPrint( + runner, ['make-deps-path-based', '--target-dependencies=foo']); + + final Map exampleOverrides = + getDependencyOverrides(example); + expect(exampleOverrides.length, 0); }); test( @@ -317,6 +349,32 @@ ${devDependencies.map((String dep) => ' $dep: $constraint').join('\n')} expect(simplePackageOverrides['bar'], '../../third_party/packages/bar'); }); + test('handles third_party target package references in third_party', + () async { + createFakePackage('bar', thirdPartyPackagesDir, isFlutter: true); + final RepositoryPackage otherThirdPartyPackge = + createFakePlugin('foo', thirdPartyPackagesDir); + + addDependencies(otherThirdPartyPackge, [ + 'bar', + ]); + + final List output = await runCapturingPrint( + runner, ['make-deps-path-based', '--target-dependencies=bar']); + + expect( + output, + containsAll([ + 'Rewriting references to: bar...', + ' Modified third_party/packages/foo/pubspec.yaml', + ])); + + final Map simplePackageOverrides = + getDependencyOverrides(otherThirdPartyPackge); + expect(simplePackageOverrides.length, 1); + expect(simplePackageOverrides['bar'], '../../../third_party/packages/bar'); + }); + // This test case ensures that running CI using this command on an interim // PR that itself used this command won't fail on the rewrite step. test('running a second time no-ops without failing', () async { @@ -420,7 +478,7 @@ ${devDependencies.map((String dep) => ' $dep: $constraint').join('\n')} expect( output, containsAllInOrder([ - contains('Skipping foo; deleted.'), + contains('Skipping packages/foo; deleted.'), contains('No target dependencies'), ]), ); diff --git a/script/tool/test/mocks.dart b/script/tool/test/mocks.dart index 3ce9512ad018..2c84ecedd12c 100644 --- a/script/tool/test/mocks.dart +++ b/script/tool/test/mocks.dart @@ -33,6 +33,9 @@ class MockPlatform extends Mock implements Platform { @override Map environment = {}; + + @override + String get pathSeparator => isWindows ? r'\' : '/'; } class MockProcess extends Mock implements io.Process { diff --git a/script/tool/test/native_test_command_test.dart b/script/tool/test/native_test_command_test.dart index cd3569739e22..02cd5c2c43ea 100644 --- a/script/tool/test/native_test_command_test.dart +++ b/script/tool/test/native_test_command_test.dart @@ -20,6 +20,9 @@ import 'package:test/test.dart'; import 'mocks.dart'; import 'util.dart'; +const String _allAbiFlag = + '-Ptarget-platform=android-arm,android-arm64,android-x64,android-x86'; + const String _androidIntegrationTestFilter = '-Pandroid.testInstrumentationRunnerArguments.' 'notAnnotation=io.flutter.plugins.DartIntegrationTest'; @@ -563,6 +566,7 @@ void main() { const [ 'app:connectedAndroidTest', _androidIntegrationTestFilter, + _allAbiFlag, ], androidFolder.path, ), @@ -697,6 +701,7 @@ public class FlutterActivityTest { const [ 'app:connectedAndroidTest', _androidIntegrationTestFilter, + _allAbiFlag, ], androidFolder.path, ), @@ -734,6 +739,7 @@ public class FlutterActivityTest { const [ 'app:connectedAndroidTest', _androidIntegrationTestFilter, + _allAbiFlag, ], androidFolder.path, ), @@ -1469,12 +1475,12 @@ public class FlutterActivityTest { processRunner.mockProcessesForExecutable['xcrun'] = [ getMockXcodebuildListProcess( ['RunnerTests', 'RunnerUITests']), // iOS list - FakeProcessInfo( - MockProcess(), ['xcodebuild', 'clean', 'test']), // iOS run + FakeProcessInfo(MockProcess(), + ['xcodebuild', 'clean', 'test']), // iOS run getMockXcodebuildListProcess( ['RunnerTests', 'RunnerUITests']), // macOS list - FakeProcessInfo( - MockProcess(), ['xcodebuild', 'clean', 'test']), // macOS run + FakeProcessInfo(MockProcess(), + ['xcodebuild', 'clean', 'test']), // macOS run ]; final List output = await runCapturingPrint(runner, [ diff --git a/script/tool/test/podspec_check_command_test.dart b/script/tool/test/podspec_check_command_test.dart index e416a488fc74..fe20e992ab87 100644 --- a/script/tool/test/podspec_check_command_test.dart +++ b/script/tool/test/podspec_check_command_test.dart @@ -156,7 +156,6 @@ void main() { .path, '--configuration=Debug', '--skip-tests', - '--use-modular-headers', '--use-libraries' ], packagesDir.path), @@ -171,7 +170,6 @@ void main() { .path, '--configuration=Debug', '--skip-tests', - '--use-modular-headers', ], packagesDir.path), ]), @@ -212,7 +210,6 @@ void main() { .path, '--configuration=Debug', '--skip-tests', - '--use-modular-headers', '--use-libraries' ], packagesDir.path), @@ -227,7 +224,6 @@ void main() { .path, '--configuration=Debug', '--skip-tests', - '--use-modular-headers', ], packagesDir.path), ]), @@ -605,5 +601,49 @@ void main() { [contains('Ran for 1 package(s)')], )); }); + + test('fails when a macOS plugin is missing a privacy manifest', () async { + final RepositoryPackage plugin = createFakePlugin( + 'plugin1', + packagesDir, + platformSupport: { + Platform.macOS: const PlatformDetails(PlatformSupport.inline), + }, + ); + _writeFakePodspec(plugin, 'macos'); + + Error? commandError; + final List output = await runCapturingPrint( + runner, ['podspec-check'], errorHandler: (Error e) { + commandError = e; + }); + + expect(commandError, isA()); + expect( + output, + containsAllInOrder( + [contains('No PrivacyInfo.xcprivacy file specified.')], + )); + }); + + test('passes when a macOS plugin has a privacy manifest', () async { + final RepositoryPackage plugin = createFakePlugin( + 'plugin1', + packagesDir, + platformSupport: { + Platform.macOS: const PlatformDetails(PlatformSupport.inline), + }, + ); + _writeFakePodspec(plugin, 'macos', includePrivacyManifest: true); + + final List output = + await runCapturingPrint(runner, ['podspec-check']); + + expect( + output, + containsAllInOrder( + [contains('Ran for 1 package(s)')], + )); + }); }); } diff --git a/script/tool/test/publish_check_command_test.dart b/script/tool/test/publish_check_command_test.dart index 767da10ad497..0869888f0589 100644 --- a/script/tool/test/publish_check_command_test.dart +++ b/script/tool/test/publish_check_command_test.dart @@ -319,6 +319,22 @@ void main() { )); }); + test('skips packages that are marked as not for publishing', () async { + createFakePackage('a_package', packagesDir, + version: '0.1.0', publishTo: 'none'); + + final List output = + await runCapturingPrint(runner, ['publish-check']); + + expect( + output, + containsAllInOrder([ + contains('SKIPPING: Package is marked as unpublishable.'), + ]), + ); + expect(processRunner.recordedCalls, isEmpty); + }); + test( 'runs validation even for packages that are already published and reports success', () async { @@ -369,6 +385,125 @@ void main() { )); }); + group('pre-publish script', () { + test('runs if present', () async { + final RepositoryPackage package = + createFakePackage('a_package', packagesDir, examples: []); + package.prePublishScript.createSync(recursive: true); + + final List output = await runCapturingPrint(runner, [ + 'publish-check', + ]); + + expect( + output, + containsAllInOrder([ + contains('Running pre-publish hook tool/pre_publish.dart...'), + ]), + ); + expect( + processRunner.recordedCalls, + containsAllInOrder([ + ProcessCall( + 'dart', + const [ + 'pub', + 'get', + ], + package.directory.path), + ProcessCall( + 'dart', + const [ + 'run', + 'tool/pre_publish.dart', + ], + package.directory.path), + ])); + }); + + test('runs before publish --dry-run', () async { + final RepositoryPackage package = + createFakePackage('a_package', packagesDir, examples: []); + package.prePublishScript.createSync(recursive: true); + + final List output = await runCapturingPrint(runner, [ + 'publish-check', + ]); + + expect( + output, + containsAllInOrder([ + contains('Running pre-publish hook tool/pre_publish.dart...'), + ]), + ); + expect( + processRunner.recordedCalls, + containsAllInOrder([ + ProcessCall( + 'dart', + const [ + 'run', + 'tool/pre_publish.dart', + ], + package.directory.path), + ProcessCall( + 'flutter', + const [ + 'pub', + 'publish', + '--', + '--dry-run', + ], + package.directory.path), + ])); + }); + + test('causes command failure if it fails', () async { + final RepositoryPackage package = createFakePackage( + 'a_package', packagesDir, + isFlutter: true, examples: []); + package.prePublishScript.createSync(recursive: true); + + processRunner.mockProcessesForExecutable['dart'] = [ + FakeProcessInfo(MockProcess(exitCode: 1), + ['run']), // run tool/pre_publish.dart + ]; + + Error? commandError; + final List output = await runCapturingPrint(runner, [ + 'publish-check', + ], errorHandler: (Error e) { + commandError = e; + }); + + expect(commandError, isA()); + expect( + output, + containsAllInOrder([ + contains('Pre-publish script failed.'), + ]), + ); + expect( + processRunner.recordedCalls, + containsAllInOrder([ + ProcessCall( + getFlutterCommand(mockPlatform), + const [ + 'pub', + 'get', + ], + package.directory.path), + ProcessCall( + 'dart', + const [ + 'run', + 'tool/pre_publish.dart', + ], + package.directory.path), + ])); + }); + }); + test( '--machine: Log JSON with status:no-publish and correct human message, if there are no packages need to be published. ', () async { diff --git a/script/tool/test/publish_command_test.dart b/script/tool/test/publish_command_test.dart index 1f3c0958b92d..068ccb56569a 100644 --- a/script/tool/test/publish_command_test.dart +++ b/script/tool/test/publish_command_test.dart @@ -141,6 +141,91 @@ void main() { }); }); + group('pre-publish script', () { + test('runs if present', () async { + final RepositoryPackage package = + createFakePackage('foo', packagesDir, examples: []); + package.prePublishScript.createSync(recursive: true); + + final List output = + await runCapturingPrint(commandRunner, [ + 'publish', + '--packages=foo', + ]); + + expect( + output, + containsAllInOrder([ + contains('Running pre-publish hook tool/pre_publish.dart...'), + ]), + ); + expect( + processRunner.recordedCalls, + containsAllInOrder([ + ProcessCall( + 'dart', + const [ + 'pub', + 'get', + ], + package.directory.path), + ProcessCall( + 'dart', + const [ + 'run', + 'tool/pre_publish.dart', + ], + package.directory.path), + ])); + }); + + test('causes command failure if it fails', () async { + final RepositoryPackage package = createFakePackage('foo', packagesDir, + isFlutter: true, examples: []); + package.prePublishScript.createSync(recursive: true); + + processRunner.mockProcessesForExecutable['dart'] = [ + FakeProcessInfo(MockProcess(exitCode: 1), + ['run']), // run tool/pre_publish.dart + ]; + + Error? commandError; + final List output = + await runCapturingPrint(commandRunner, [ + 'publish', + '--packages=foo', + ], errorHandler: (Error e) { + commandError = e; + }); + + expect(commandError, isA()); + expect( + output, + containsAllInOrder([ + contains('Pre-publish script failed.'), + ]), + ); + expect( + processRunner.recordedCalls, + containsAllInOrder([ + ProcessCall( + getFlutterCommand(platform), + const [ + 'pub', + 'get', + ], + package.directory.path), + ProcessCall( + 'dart', + const [ + 'run', + 'tool/pre_publish.dart', + ], + package.directory.path), + ])); + }); + }); + group('Publishes package', () { test('while showing all output from pub publish to the user', () async { createFakePlugin('plugin1', packagesDir, examples: []); diff --git a/script/tool/test/pubspec_check_command_test.dart b/script/tool/test/pubspec_check_command_test.dart index 2cf27027c7c7..6fec0be36210 100644 --- a/script/tool/test/pubspec_check_command_test.dart +++ b/script/tool/test/pubspec_check_command_test.dart @@ -1674,7 +1674,8 @@ ${_topicsSection()} ); }); - test('passes when a pinned dependency is on the pinned allow list', + test( + 'passes when an exactly-pinned dependency is on the pinned allow list', () async { final RepositoryPackage package = createFakePackage('a_package', packagesDir); @@ -1701,6 +1702,34 @@ ${_topicsSection()} ); }); + test( + 'passes when an explicit-range-pinned dependency is on the pinned allow list', + () async { + final RepositoryPackage package = + createFakePackage('a_package', packagesDir); + + package.pubspecFile.writeAsStringSync(''' +${_headerSection('a_package')} +${_environmentSection()} +${_dependenciesSection(['allow_pinned: ">=1.0.0 <=1.3.1"'])} +${_topicsSection()} +'''); + + final List output = await runCapturingPrint(runner, [ + 'pubspec-check', + '--allow-pinned-dependencies', + 'allow_pinned' + ]); + + expect( + output, + containsAllInOrder([ + contains('Running for a_package...'), + contains('No issues found!'), + ]), + ); + }); + test('fails when an allowed-when-pinned dependency is unpinned', () async { final RepositoryPackage package = diff --git a/script/tool/test/readme_check_command_test.dart b/script/tool/test/readme_check_command_test.dart index ab6756e7477c..1cecedd88d0a 100644 --- a/script/tool/test/readme_check_command_test.dart +++ b/script/tool/test/readme_check_command_test.dart @@ -119,7 +119,7 @@ a specialized package that includes platform-specific implementation code for Android and/or iOS. For help getting started with Flutter development, view the -[online documentation](https://flutter.dev/docs), which offers tutorials, +[online documentation](https://docs.flutter.dev), which offers tutorials, samples, guidance on mobile development, and a full API reference. '''); diff --git a/script/tool/test/util.dart b/script/tool/test/util.dart index c7bdd129fb73..150508dbd161 100644 --- a/script/tool/test/util.dart +++ b/script/tool/test/util.dart @@ -313,7 +313,6 @@ String _pluginPlatformSection( ]); default: assert(false, 'Unrecognized platform: $platform'); - break; } entry = '${lines.join('\n')}\n'; } diff --git a/script/tool/test/version_check_command_test.dart b/script/tool/test/version_check_command_test.dart index 01c71467a6d2..aea2a5fd08cd 100644 --- a/script/tool/test/version_check_command_test.dart +++ b/script/tool/test/version_check_command_test.dart @@ -641,6 +641,41 @@ void main() { ); }); + test('fails gracefully if the first entry uses the wrong style', () async { + final RepositoryPackage plugin = + createFakePlugin('plugin', packagesDir, version: '1.0.0'); + + const String changelog = ''' +# 1.0.0 +* Some changes for a later release. +## 0.9.0 +* Some earlier changes. +'''; + plugin.changelogFile.writeAsStringSync(changelog); + processRunner.mockProcessesForExecutable['git-show'] = [ + FakeProcessInfo(MockProcess(stdout: 'version: 1.0.0')), + ]; + + Error? commandError; + final List output = await runCapturingPrint(runner, [ + 'version-check', + '--base-sha=main', + ], errorHandler: (Error e) { + commandError = e; + }); + + expect(commandError, isA()); + expect( + output, + containsAllInOrder([ + contains('Unable to find a version in CHANGELOG.md'), + contains('The current version should be on a line starting with ' + '"## ", either on the first non-empty line or after a "## NEXT" ' + 'section.'), + ]), + ); + }); + test( 'fails gracefully if the version headers are not found due to using the wrong style', () async { diff --git a/third_party/packages/cupertino_icons/CHANGELOG.md b/third_party/packages/cupertino_icons/CHANGELOG.md index 5d70d6c77efe..447d622436e4 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.16/Dart 3.2. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 1.0.8 diff --git a/third_party/packages/cupertino_icons/pubspec.yaml b/third_party/packages/cupertino_icons/pubspec.yaml index 1832255e1ba8..76e5962fd4e1 100644 --- a/third_party/packages/cupertino_icons/pubspec.yaml +++ b/third_party/packages/cupertino_icons/pubspec.yaml @@ -6,13 +6,15 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 1.0.8 environment: - sdk: ^3.2.0 + sdk: ^3.3.0 dev_dependencies: + collection: ^1.18.0 flutter: sdk: flutter flutter_test: sdk: flutter + path: ^1.9.0 flutter: fonts: diff --git a/third_party/packages/cupertino_icons/test/cupertino_icons_golden_test.dart b/third_party/packages/cupertino_icons/test/cupertino_icons_golden_test.dart new file mode 100644 index 000000000000..8ddf57cb5c54 --- /dev/null +++ b/third_party/packages/cupertino_icons/test/cupertino_icons_golden_test.dart @@ -0,0 +1,99 @@ +// 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:io' show File, Platform; + +import 'package:collection/collection.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:path/path.dart' as path; + +import 'icons_list.dart'; + +// The EM of the font is 512. Keep this a power of 2 for fixed-point arithmetic. +const double iconSize = 128.0; +const int iconsPerRow = 5; +const int iconsPerCol = 5; +const int iconsPerImage = iconsPerRow * iconsPerCol; + +void main() async { + // Do not run on web since this test uses dart:io. + // The golden test runs on Linux only to avoid platform rendering differences. + if (kIsWeb || !Platform.isLinux) { + return; + } + final bool isMainChannel = !Platform.environment.containsKey('CHANNEL') || + Platform.environment['CHANNEL'] == 'main' || + Platform.environment['CHANNEL'] == 'master'; + // Only test against main to avoid rendering differences between flutter channels. + if (!isMainChannel) { + return; + } + // Load font. + final String effectiveFontFamily = const TextStyle( + fontFamily: CupertinoIcons.iconFont, + package: CupertinoIcons.iconFontPackage) + .fontFamily!; + final FontLoader fontLoader = FontLoader(effectiveFontFamily); + final String filePath = path.canonicalize('assets/CupertinoIcons.ttf'); + final File file = File(filePath); + fontLoader + .addFont(file.readAsBytes().then((Uint8List v) => v.buffer.asByteData())); + await fontLoader.load(); + + assert(icons.isNotEmpty); + for (int index = 0; index < icons.length;) { + final int groupEndCodePoint = + (icons[index].codePoint ~/ iconsPerImage + 1) * iconsPerImage; + final int next = icons.indexWhere( + (IconData icon) => icon.codePoint >= groupEndCodePoint, index); + final int nextIndex = next < 0 ? icons.length : next; + registerTestForIconGroup(icons.slice(index, nextIndex)); + index = nextIndex; + } +} + +// Generating goldens for each glyph is very slow. Group the sorted icons +// into codepoint-aligned groups (each of which has a max capacity of +// iconsPerRow * iconsPerCol), so the goldens are easier to review when +// symbols are added or removed. +void registerTestForIconGroup(List iconGroup) { + assert(iconGroup.isNotEmpty); + String hexCodePoint(int codePoint) => + codePoint.toRadixString(16).toUpperCase().padLeft(4, '0'); + final int groupStartCodePoint = + (iconGroup.first.codePoint ~/ iconsPerImage) * iconsPerImage; + final String range = + 'U+${hexCodePoint(groupStartCodePoint)}-${hexCodePoint(groupStartCodePoint + iconsPerImage - 1)}'; + + testWidgets('font golden test: $range', (WidgetTester tester) async { + addTearDown(tester.view.reset); + const Size canvasSize = + Size(iconSize * iconsPerRow, iconSize * iconsPerCol); + tester.view.physicalSize = canvasSize * tester.view.devicePixelRatio; + + const Widget fillerBox = SizedBox.square(dimension: iconSize); + final List children = List.filled(iconsPerImage, fillerBox); + for (final IconData icon in iconGroup) { + children[icon.codePoint - groupStartCodePoint] = + Icon(icon, size: iconSize); + } + + final Widget widget = Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: SizedBox( + height: iconSize * iconsPerCol, + width: iconSize * iconsPerRow, + child: RepaintBoundary(child: Wrap(children: children)), + ), + ), + ); + await tester.pumpWidget(widget); + await expectLater( + find.byType(Wrap), matchesGoldenFile('goldens/glyph_$range.png')); + }); +} diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F104-F11C.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F104-F11C.png new file mode 100644 index 000000000000..e5927df0546e Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F104-F11C.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F217-F22F.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F217-F22F.png new file mode 100644 index 000000000000..f5a0f89d8d98 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F217-F22F.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F2AD-F2C5.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F2AD-F2C5.png new file mode 100644 index 000000000000..5126404ba592 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F2AD-F2C5.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F2C6-F2DE.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F2C6-F2DE.png new file mode 100644 index 000000000000..c60178699ea1 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F2C6-F2DE.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F2DF-F2F7.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F2DF-F2F7.png new file mode 100644 index 000000000000..d0cb8e8e650f Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F2DF-F2F7.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F35C-F374.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F35C-F374.png new file mode 100644 index 000000000000..44f1a07f82da Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F35C-F374.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F375-F38D.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F375-F38D.png new file mode 100644 index 000000000000..7ae1156164ea Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F375-F38D.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F3A7-F3BF.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F3A7-F3BF.png new file mode 100644 index 000000000000..6dde064a9309 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F3A7-F3BF.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F3C0-F3D8.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F3C0-F3D8.png new file mode 100644 index 000000000000..90f09269d51d Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F3C0-F3D8.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F3D9-F3F1.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F3D9-F3F1.png new file mode 100644 index 000000000000..f46b2aff49ae Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F3D9-F3F1.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F3F2-F40A.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F3F2-F40A.png new file mode 100644 index 000000000000..74f9ab98a6d1 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F3F2-F40A.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F40B-F423.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F40B-F423.png new file mode 100644 index 000000000000..3c194729bb2d Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F40B-F423.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F424-F43C.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F424-F43C.png new file mode 100644 index 000000000000..be248a1d932b Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F424-F43C.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F43D-F455.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F43D-F455.png new file mode 100644 index 000000000000..80e8a035945f Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F43D-F455.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F456-F46E.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F456-F46E.png new file mode 100644 index 000000000000..1eafb9c376dc Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F456-F46E.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F46F-F487.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F46F-F487.png new file mode 100644 index 000000000000..4b5d27e3a48f Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F46F-F487.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F488-F4A0.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F488-F4A0.png new file mode 100644 index 000000000000..0ed83f9115a7 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F488-F4A0.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F4A1-F4B9.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F4A1-F4B9.png new file mode 100644 index 000000000000..ae57a04060ad Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F4A1-F4B9.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F4BA-F4D2.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F4BA-F4D2.png new file mode 100644 index 000000000000..be1ff5d04915 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F4BA-F4D2.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F4D3-F4EB.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F4D3-F4EB.png new file mode 100644 index 000000000000..f1ba65338e6a Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F4D3-F4EB.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F4EC-F504.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F4EC-F504.png new file mode 100644 index 000000000000..b02c941040fb Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F4EC-F504.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F505-F51D.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F505-F51D.png new file mode 100644 index 000000000000..f840f8ed73e7 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F505-F51D.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F51E-F536.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F51E-F536.png new file mode 100644 index 000000000000..9edb30fae98b Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F51E-F536.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F537-F54F.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F537-F54F.png new file mode 100644 index 000000000000..bd98f77307ed Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F537-F54F.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F550-F568.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F550-F568.png new file mode 100644 index 000000000000..9d335d1fadf6 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F550-F568.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F569-F581.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F569-F581.png new file mode 100644 index 000000000000..e46f813e6398 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F569-F581.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F582-F59A.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F582-F59A.png new file mode 100644 index 000000000000..fe797949b595 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F582-F59A.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F59B-F5B3.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F59B-F5B3.png new file mode 100644 index 000000000000..4d3e3c29e1dd Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F59B-F5B3.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F5B4-F5CC.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F5B4-F5CC.png new file mode 100644 index 000000000000..f20bb4f74f2a Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F5B4-F5CC.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F5CD-F5E5.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F5CD-F5E5.png new file mode 100644 index 000000000000..d57fd95c738d Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F5CD-F5E5.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F5E6-F5FE.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F5E6-F5FE.png new file mode 100644 index 000000000000..e8438113aacf Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F5E6-F5FE.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F5FF-F617.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F5FF-F617.png new file mode 100644 index 000000000000..0391b2dfed90 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F5FF-F617.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F618-F630.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F618-F630.png new file mode 100644 index 000000000000..730785a2e053 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F618-F630.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F631-F649.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F631-F649.png new file mode 100644 index 000000000000..4a20fe7055a9 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F631-F649.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F64A-F662.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F64A-F662.png new file mode 100644 index 000000000000..bbc565cd096d Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F64A-F662.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F663-F67B.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F663-F67B.png new file mode 100644 index 000000000000..d135aea368a2 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F663-F67B.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F67C-F694.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F67C-F694.png new file mode 100644 index 000000000000..eb89c1897413 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F67C-F694.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F695-F6AD.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F695-F6AD.png new file mode 100644 index 000000000000..c051159994f4 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F695-F6AD.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F6AE-F6C6.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F6AE-F6C6.png new file mode 100644 index 000000000000..e24047ef0039 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F6AE-F6C6.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F6C7-F6DF.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F6C7-F6DF.png new file mode 100644 index 000000000000..2326f02f878e Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F6C7-F6DF.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F6E0-F6F8.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F6E0-F6F8.png new file mode 100644 index 000000000000..cd561db61fca Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F6E0-F6F8.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F6F9-F711.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F6F9-F711.png new file mode 100644 index 000000000000..b91e6259f726 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F6F9-F711.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F712-F72A.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F712-F72A.png new file mode 100644 index 000000000000..c05928e842ec Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F712-F72A.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F72B-F743.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F72B-F743.png new file mode 100644 index 000000000000..4a5b57e90665 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F72B-F743.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F744-F75C.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F744-F75C.png new file mode 100644 index 000000000000..159c2e700363 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F744-F75C.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F75D-F775.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F75D-F775.png new file mode 100644 index 000000000000..d0159de9ea06 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F75D-F775.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F776-F78E.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F776-F78E.png new file mode 100644 index 000000000000..c4b0d0c7fa1b Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F776-F78E.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F78F-F7A7.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F78F-F7A7.png new file mode 100644 index 000000000000..43d48d13aad0 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F78F-F7A7.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F7A8-F7C0.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F7A8-F7C0.png new file mode 100644 index 000000000000..0038ddc2d8fe Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F7A8-F7C0.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F7C1-F7D9.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F7C1-F7D9.png new file mode 100644 index 000000000000..52ee286a66eb Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F7C1-F7D9.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F7DA-F7F2.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F7DA-F7F2.png new file mode 100644 index 000000000000..e7ee9f1349c8 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F7DA-F7F2.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F7F3-F80B.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F7F3-F80B.png new file mode 100644 index 000000000000..116f98b887c3 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F7F3-F80B.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F80C-F824.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F80C-F824.png new file mode 100644 index 000000000000..d1358391d28b Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F80C-F824.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F825-F83D.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F825-F83D.png new file mode 100644 index 000000000000..0aeade09a74f Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F825-F83D.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F83E-F856.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F83E-F856.png new file mode 100644 index 000000000000..17b8766d4d2d Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F83E-F856.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F857-F86F.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F857-F86F.png new file mode 100644 index 000000000000..acd7909e4d5b Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F857-F86F.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F870-F888.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F870-F888.png new file mode 100644 index 000000000000..789ebe880926 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F870-F888.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F889-F8A1.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F889-F8A1.png new file mode 100644 index 000000000000..0324a7f6ea2b Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F889-F8A1.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F8A2-F8BA.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F8A2-F8BA.png new file mode 100644 index 000000000000..34fcb8cb210d Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F8A2-F8BA.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F8BB-F8D3.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F8BB-F8D3.png new file mode 100644 index 000000000000..98cfb2311b36 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F8BB-F8D3.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F8D4-F8EC.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F8D4-F8EC.png new file mode 100644 index 000000000000..5b21aa2dc823 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F8D4-F8EC.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F8ED-F905.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F8ED-F905.png new file mode 100644 index 000000000000..adaa706c08a6 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F8ED-F905.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F906-F91E.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F906-F91E.png new file mode 100644 index 000000000000..44dd153e8348 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F906-F91E.png differ diff --git a/third_party/packages/cupertino_icons/test/goldens/glyph_U+F91F-F937.png b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F91F-F937.png new file mode 100644 index 000000000000..e73a44de0240 Binary files /dev/null and b/third_party/packages/cupertino_icons/test/goldens/glyph_U+F91F-F937.png differ diff --git a/third_party/packages/cupertino_icons/test/icons_list.dart b/third_party/packages/cupertino_icons/test/icons_list.dart new file mode 100644 index 000000000000..fb4753bb10de --- /dev/null +++ b/third_party/packages/cupertino_icons/test/icons_list.dart @@ -0,0 +1,1340 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/cupertino.dart'; + +int _compare(IconData a, IconData b) => a.codePoint.compareTo(b.codePoint); + +/// The full list of [IconData] constants defined in the [CupertinoIcons] class, +/// sorted by their code points in ascending order. +/// +/// After making changes to the font, if the change requires code change in the +/// [CupertinoIcons] class (adding new icons, for example), consider updating +/// this list. +/// +/// This list cannot be mutated by tests. +final List icons = List.unmodifiable([ + CupertinoIcons.left_chevron, + CupertinoIcons.right_chevron, + CupertinoIcons.share, + CupertinoIcons.share_solid, + CupertinoIcons.book, + CupertinoIcons.book_solid, + CupertinoIcons.bookmark, + CupertinoIcons.bookmark_solid, + CupertinoIcons.info, + CupertinoIcons.reply, + CupertinoIcons.conversation_bubble, + CupertinoIcons.profile_circled, + CupertinoIcons.plus_circled, + CupertinoIcons.minus_circled, + CupertinoIcons.flag, + CupertinoIcons.search, + CupertinoIcons.check_mark, + CupertinoIcons.check_mark_circled, + CupertinoIcons.check_mark_circled_solid, + CupertinoIcons.circle, + CupertinoIcons.circle_filled, + CupertinoIcons.back, + CupertinoIcons.forward, + CupertinoIcons.home, + CupertinoIcons.shopping_cart, + CupertinoIcons.ellipsis, + CupertinoIcons.phone, + CupertinoIcons.phone_solid, + CupertinoIcons.down_arrow, + CupertinoIcons.up_arrow, + CupertinoIcons.battery_charging, + CupertinoIcons.battery_empty, + CupertinoIcons.battery_full, + CupertinoIcons.battery_75_percent, + CupertinoIcons.battery_25_percent, + CupertinoIcons.bluetooth, + CupertinoIcons.restart, + CupertinoIcons.reply_all, + CupertinoIcons.reply_thick_solid, + CupertinoIcons.share_up, + CupertinoIcons.shuffle, + CupertinoIcons.shuffle_medium, + CupertinoIcons.shuffle_thick, + CupertinoIcons.photo_camera, + CupertinoIcons.photo_camera_solid, + CupertinoIcons.video_camera, + CupertinoIcons.video_camera_solid, + CupertinoIcons.switch_camera, + CupertinoIcons.switch_camera_solid, + CupertinoIcons.collections, + CupertinoIcons.collections_solid, + CupertinoIcons.folder, + CupertinoIcons.folder_solid, + CupertinoIcons.folder_open, + CupertinoIcons.delete, + CupertinoIcons.delete_solid, + CupertinoIcons.delete_simple, + CupertinoIcons.pen, + CupertinoIcons.pencil, + CupertinoIcons.create, + CupertinoIcons.create_solid, + CupertinoIcons.refresh, + CupertinoIcons.refresh_circled, + CupertinoIcons.refresh_circled_solid, + CupertinoIcons.refresh_thin, + CupertinoIcons.refresh_thick, + CupertinoIcons.refresh_bold, + CupertinoIcons.clear_thick, + CupertinoIcons.clear_thick_circled, + CupertinoIcons.clear, + CupertinoIcons.clear_circled, + CupertinoIcons.clear_circled_solid, + CupertinoIcons.add, + CupertinoIcons.add_circled, + CupertinoIcons.add_circled_solid, + CupertinoIcons.gear, + CupertinoIcons.gear_solid, + CupertinoIcons.gear_big, + CupertinoIcons.settings, + CupertinoIcons.settings_solid, + CupertinoIcons.music_note, + CupertinoIcons.double_music_note, + CupertinoIcons.play_arrow, + CupertinoIcons.play_arrow_solid, + CupertinoIcons.pause, + CupertinoIcons.pause_solid, + CupertinoIcons.loop, + CupertinoIcons.loop_thick, + CupertinoIcons.volume_down, + CupertinoIcons.volume_mute, + CupertinoIcons.volume_off, + CupertinoIcons.volume_up, + CupertinoIcons.fullscreen, + CupertinoIcons.fullscreen_exit, + CupertinoIcons.mic_off, + CupertinoIcons.mic, + CupertinoIcons.mic_solid, + CupertinoIcons.clock, + CupertinoIcons.clock_solid, + CupertinoIcons.time, + CupertinoIcons.time_solid, + CupertinoIcons.padlock, + CupertinoIcons.padlock_solid, + CupertinoIcons.eye, + CupertinoIcons.eye_solid, + CupertinoIcons.person, + CupertinoIcons.person_solid, + CupertinoIcons.person_add, + CupertinoIcons.person_add_solid, + CupertinoIcons.group, + CupertinoIcons.group_solid, + CupertinoIcons.mail, + CupertinoIcons.mail_solid, + CupertinoIcons.location, + CupertinoIcons.location_solid, + CupertinoIcons.tag, + CupertinoIcons.tag_solid, + CupertinoIcons.tags, + CupertinoIcons.tags_solid, + CupertinoIcons.bus, + CupertinoIcons.car, + CupertinoIcons.car_detailed, + CupertinoIcons.train_style_one, + CupertinoIcons.train_style_two, + CupertinoIcons.paw, + CupertinoIcons.paw_solid, + CupertinoIcons.game_controller, + CupertinoIcons.game_controller_solid, + CupertinoIcons.lab_flask, + CupertinoIcons.lab_flask_solid, + CupertinoIcons.heart, + CupertinoIcons.heart_solid, + CupertinoIcons.bell, + CupertinoIcons.bell_solid, + CupertinoIcons.news, + CupertinoIcons.news_solid, + CupertinoIcons.brightness, + CupertinoIcons.brightness_solid, + CupertinoIcons.airplane, + CupertinoIcons.alarm, + CupertinoIcons.alarm_fill, + CupertinoIcons.alt, + CupertinoIcons.ant, + CupertinoIcons.ant_circle, + CupertinoIcons.ant_circle_fill, + CupertinoIcons.ant_fill, + CupertinoIcons.antenna_radiowaves_left_right, + CupertinoIcons.app, + CupertinoIcons.app_badge, + CupertinoIcons.app_badge_fill, + CupertinoIcons.app_fill, + CupertinoIcons.archivebox, + CupertinoIcons.archivebox_fill, + CupertinoIcons.arrow_2_circlepath, + CupertinoIcons.arrow_2_circlepath_circle, + CupertinoIcons.arrow_2_circlepath_circle_fill, + CupertinoIcons.arrow_2_squarepath, + CupertinoIcons.arrow_3_trianglepath, + CupertinoIcons.arrow_branch, + CupertinoIcons.arrow_clockwise, + CupertinoIcons.arrow_clockwise_circle, + CupertinoIcons.arrow_clockwise_circle_fill, + CupertinoIcons.arrow_counterclockwise, + CupertinoIcons.arrow_counterclockwise_circle, + CupertinoIcons.arrow_counterclockwise_circle_fill, + CupertinoIcons.arrow_down, + CupertinoIcons.arrow_down_circle, + CupertinoIcons.arrow_down_circle_fill, + CupertinoIcons.arrow_down_doc, + CupertinoIcons.arrow_down_doc_fill, + CupertinoIcons.arrow_down_left, + CupertinoIcons.arrow_down_left_circle, + CupertinoIcons.arrow_down_left_circle_fill, + CupertinoIcons.arrow_down_left_square, + CupertinoIcons.arrow_down_left_square_fill, + CupertinoIcons.arrow_down_right, + CupertinoIcons.arrow_down_right_arrow_up_left, + CupertinoIcons.arrow_down_right_circle, + CupertinoIcons.arrow_down_right_circle_fill, + CupertinoIcons.arrow_down_right_square, + CupertinoIcons.arrow_down_right_square_fill, + CupertinoIcons.arrow_down_square, + CupertinoIcons.arrow_down_square_fill, + CupertinoIcons.arrow_down_to_line, + CupertinoIcons.arrow_down_to_line_alt, + CupertinoIcons.arrow_left, + CupertinoIcons.arrow_left_circle, + CupertinoIcons.arrow_left_circle_fill, + CupertinoIcons.arrow_left_right, + CupertinoIcons.arrow_left_right_circle, + CupertinoIcons.arrow_left_right_circle_fill, + CupertinoIcons.arrow_left_right_square, + CupertinoIcons.arrow_left_right_square_fill, + CupertinoIcons.arrow_left_square, + CupertinoIcons.arrow_left_square_fill, + CupertinoIcons.arrow_left_to_line, + CupertinoIcons.arrow_left_to_line_alt, + CupertinoIcons.arrow_merge, + CupertinoIcons.arrow_right, + CupertinoIcons.arrow_right_arrow_left, + CupertinoIcons.arrow_right_arrow_left_circle, + CupertinoIcons.arrow_right_arrow_left_circle_fill, + CupertinoIcons.arrow_right_arrow_left_square, + CupertinoIcons.arrow_right_arrow_left_square_fill, + CupertinoIcons.arrow_right_circle, + CupertinoIcons.arrow_right_circle_fill, + CupertinoIcons.arrow_right_square, + CupertinoIcons.arrow_right_square_fill, + CupertinoIcons.arrow_right_to_line, + CupertinoIcons.arrow_right_to_line_alt, + CupertinoIcons.arrow_swap, + CupertinoIcons.arrow_turn_down_left, + CupertinoIcons.arrow_turn_down_right, + CupertinoIcons.arrow_turn_left_down, + CupertinoIcons.arrow_turn_left_up, + CupertinoIcons.arrow_turn_right_down, + CupertinoIcons.arrow_turn_right_up, + CupertinoIcons.arrow_turn_up_left, + CupertinoIcons.arrow_turn_up_right, + CupertinoIcons.arrow_up, + CupertinoIcons.arrow_up_arrow_down, + CupertinoIcons.arrow_up_arrow_down_circle, + CupertinoIcons.arrow_up_arrow_down_circle_fill, + CupertinoIcons.arrow_up_arrow_down_square, + CupertinoIcons.arrow_up_arrow_down_square_fill, + CupertinoIcons.arrow_up_bin, + CupertinoIcons.arrow_up_bin_fill, + CupertinoIcons.arrow_up_circle, + CupertinoIcons.arrow_up_circle_fill, + CupertinoIcons.arrow_up_doc, + CupertinoIcons.arrow_up_doc_fill, + CupertinoIcons.arrow_up_down, + CupertinoIcons.arrow_up_down_circle, + CupertinoIcons.arrow_up_down_circle_fill, + CupertinoIcons.arrow_up_down_square, + CupertinoIcons.arrow_up_down_square_fill, + CupertinoIcons.arrow_up_left, + CupertinoIcons.arrow_up_left_arrow_down_right, + CupertinoIcons.arrow_up_left_circle, + CupertinoIcons.arrow_up_left_circle_fill, + CupertinoIcons.arrow_up_left_square, + CupertinoIcons.arrow_up_left_square_fill, + CupertinoIcons.arrow_up_right, + CupertinoIcons.arrow_up_right_circle, + CupertinoIcons.arrow_up_right_circle_fill, + CupertinoIcons.arrow_up_right_diamond, + CupertinoIcons.arrow_up_right_diamond_fill, + CupertinoIcons.arrow_up_right_square, + CupertinoIcons.arrow_up_right_square_fill, + CupertinoIcons.arrow_up_square, + CupertinoIcons.arrow_up_square_fill, + CupertinoIcons.arrow_up_to_line, + CupertinoIcons.arrow_up_to_line_alt, + CupertinoIcons.arrow_uturn_down, + CupertinoIcons.arrow_uturn_down_circle, + CupertinoIcons.arrow_uturn_down_circle_fill, + CupertinoIcons.arrow_uturn_down_square, + CupertinoIcons.arrow_uturn_down_square_fill, + CupertinoIcons.arrow_uturn_left, + CupertinoIcons.arrow_uturn_left_circle, + CupertinoIcons.arrow_uturn_left_circle_fill, + CupertinoIcons.arrow_uturn_left_square, + CupertinoIcons.arrow_uturn_left_square_fill, + CupertinoIcons.arrow_uturn_right, + CupertinoIcons.arrow_uturn_right_circle, + CupertinoIcons.arrow_uturn_right_circle_fill, + CupertinoIcons.arrow_uturn_right_square, + CupertinoIcons.arrow_uturn_right_square_fill, + CupertinoIcons.arrow_uturn_up, + CupertinoIcons.arrow_uturn_up_circle, + CupertinoIcons.arrow_uturn_up_circle_fill, + CupertinoIcons.arrow_uturn_up_square, + CupertinoIcons.arrow_uturn_up_square_fill, + CupertinoIcons.arrowshape_turn_up_left, + CupertinoIcons.arrowshape_turn_up_left_2, + CupertinoIcons.arrowshape_turn_up_left_2_fill, + CupertinoIcons.arrowshape_turn_up_left_circle, + CupertinoIcons.arrowshape_turn_up_left_circle_fill, + CupertinoIcons.arrowshape_turn_up_left_fill, + CupertinoIcons.arrowshape_turn_up_right, + CupertinoIcons.arrowshape_turn_up_right_circle, + CupertinoIcons.arrowshape_turn_up_right_circle_fill, + CupertinoIcons.arrowshape_turn_up_right_fill, + CupertinoIcons.arrowtriangle_down, + CupertinoIcons.arrowtriangle_down_circle, + CupertinoIcons.arrowtriangle_down_circle_fill, + CupertinoIcons.arrowtriangle_down_fill, + CupertinoIcons.arrowtriangle_down_square, + CupertinoIcons.arrowtriangle_down_square_fill, + CupertinoIcons.arrowtriangle_left, + CupertinoIcons.arrowtriangle_left_circle, + CupertinoIcons.arrowtriangle_left_circle_fill, + CupertinoIcons.arrowtriangle_left_fill, + CupertinoIcons.arrowtriangle_left_square, + CupertinoIcons.arrowtriangle_left_square_fill, + CupertinoIcons.arrowtriangle_right, + CupertinoIcons.arrowtriangle_right_circle, + CupertinoIcons.arrowtriangle_right_circle_fill, + CupertinoIcons.arrowtriangle_right_fill, + CupertinoIcons.arrowtriangle_right_square, + CupertinoIcons.arrowtriangle_right_square_fill, + CupertinoIcons.arrowtriangle_up, + CupertinoIcons.arrowtriangle_up_circle, + CupertinoIcons.arrowtriangle_up_circle_fill, + CupertinoIcons.arrowtriangle_up_fill, + CupertinoIcons.arrowtriangle_up_square, + CupertinoIcons.arrowtriangle_up_square_fill, + CupertinoIcons.asterisk_circle, + CupertinoIcons.asterisk_circle_fill, + CupertinoIcons.at, + CupertinoIcons.at_badge_minus, + CupertinoIcons.at_badge_plus, + CupertinoIcons.at_circle, + CupertinoIcons.at_circle_fill, + CupertinoIcons.backward, + CupertinoIcons.backward_end, + CupertinoIcons.backward_end_alt, + CupertinoIcons.backward_end_alt_fill, + CupertinoIcons.backward_end_fill, + CupertinoIcons.backward_fill, + CupertinoIcons.badge_plus_radiowaves_right, + CupertinoIcons.bag, + CupertinoIcons.bag_badge_minus, + CupertinoIcons.bag_badge_plus, + CupertinoIcons.bag_fill, + CupertinoIcons.bag_fill_badge_minus, + CupertinoIcons.bag_fill_badge_plus, + CupertinoIcons.bandage, + CupertinoIcons.bandage_fill, + CupertinoIcons.barcode, + CupertinoIcons.barcode_viewfinder, + CupertinoIcons.bars, + CupertinoIcons.battery_0, + CupertinoIcons.battery_100, + CupertinoIcons.battery_25, + CupertinoIcons.bed_double, + CupertinoIcons.bed_double_fill, + CupertinoIcons.bell_circle, + CupertinoIcons.bell_circle_fill, + CupertinoIcons.bell_fill, + CupertinoIcons.bell_slash, + CupertinoIcons.bell_slash_fill, + CupertinoIcons.bin_xmark, + CupertinoIcons.bin_xmark_fill, + CupertinoIcons.bitcoin, + CupertinoIcons.bitcoin_circle, + CupertinoIcons.bitcoin_circle_fill, + CupertinoIcons.bold, + CupertinoIcons.bold_italic_underline, + CupertinoIcons.bold_underline, + CupertinoIcons.bolt, + CupertinoIcons.bolt_badge_a, + CupertinoIcons.bolt_badge_a_fill, + CupertinoIcons.bolt_circle, + CupertinoIcons.bolt_circle_fill, + CupertinoIcons.bolt_fill, + CupertinoIcons.bolt_horizontal, + CupertinoIcons.bolt_horizontal_circle, + CupertinoIcons.bolt_horizontal_circle_fill, + CupertinoIcons.bolt_horizontal_fill, + CupertinoIcons.bolt_slash, + CupertinoIcons.bolt_slash_fill, + CupertinoIcons.book_circle, + CupertinoIcons.book_circle_fill, + CupertinoIcons.book_fill, + CupertinoIcons.bookmark_fill, + CupertinoIcons.briefcase, + CupertinoIcons.briefcase_fill, + CupertinoIcons.bubble_left, + CupertinoIcons.bubble_left_bubble_right, + CupertinoIcons.bubble_left_bubble_right_fill, + CupertinoIcons.bubble_left_fill, + CupertinoIcons.bubble_middle_bottom, + CupertinoIcons.bubble_middle_bottom_fill, + CupertinoIcons.bubble_middle_top, + CupertinoIcons.bubble_middle_top_fill, + CupertinoIcons.bubble_right, + CupertinoIcons.bubble_right_fill, + CupertinoIcons.building_2_fill, + CupertinoIcons.burn, + CupertinoIcons.burst, + CupertinoIcons.burst_fill, + CupertinoIcons.calendar, + CupertinoIcons.calendar_badge_minus, + CupertinoIcons.calendar_badge_plus, + CupertinoIcons.calendar_circle, + CupertinoIcons.calendar_circle_fill, + CupertinoIcons.calendar_today, + CupertinoIcons.camera, + CupertinoIcons.camera_circle, + CupertinoIcons.camera_circle_fill, + CupertinoIcons.camera_fill, + CupertinoIcons.camera_on_rectangle, + CupertinoIcons.camera_on_rectangle_fill, + CupertinoIcons.camera_rotate, + CupertinoIcons.camera_rotate_fill, + CupertinoIcons.camera_viewfinder, + CupertinoIcons.capslock, + CupertinoIcons.capslock_fill, + CupertinoIcons.capsule, + CupertinoIcons.capsule_fill, + CupertinoIcons.captions_bubble, + CupertinoIcons.captions_bubble_fill, + CupertinoIcons.car_fill, + CupertinoIcons.cart, + CupertinoIcons.cart_badge_minus, + CupertinoIcons.cart_badge_plus, + CupertinoIcons.cart_fill, + CupertinoIcons.cart_fill_badge_minus, + CupertinoIcons.cart_fill_badge_plus, + CupertinoIcons.chart_bar, + CupertinoIcons.chart_bar_alt_fill, + CupertinoIcons.chart_bar_circle, + CupertinoIcons.chart_bar_circle_fill, + CupertinoIcons.chart_bar_fill, + CupertinoIcons.chart_bar_square, + CupertinoIcons.chart_bar_square_fill, + CupertinoIcons.chart_pie, + CupertinoIcons.chart_pie_fill, + CupertinoIcons.chat_bubble, + CupertinoIcons.chat_bubble_2, + CupertinoIcons.chat_bubble_2_fill, + CupertinoIcons.chat_bubble_fill, + CupertinoIcons.chat_bubble_text, + CupertinoIcons.chat_bubble_text_fill, + CupertinoIcons.checkmark, + CupertinoIcons.checkmark_alt, + CupertinoIcons.checkmark_alt_circle, + CupertinoIcons.checkmark_alt_circle_fill, + CupertinoIcons.checkmark_circle, + CupertinoIcons.checkmark_circle_fill, + CupertinoIcons.checkmark_rectangle, + CupertinoIcons.checkmark_rectangle_fill, + CupertinoIcons.checkmark_seal, + CupertinoIcons.checkmark_seal_fill, + CupertinoIcons.checkmark_shield, + CupertinoIcons.checkmark_shield_fill, + CupertinoIcons.checkmark_square, + CupertinoIcons.checkmark_square_fill, + CupertinoIcons.chevron_back, + CupertinoIcons.chevron_compact_down, + CupertinoIcons.chevron_compact_left, + CupertinoIcons.chevron_compact_right, + CupertinoIcons.chevron_compact_up, + CupertinoIcons.chevron_down, + CupertinoIcons.chevron_down_circle, + CupertinoIcons.chevron_down_circle_fill, + CupertinoIcons.chevron_down_square, + CupertinoIcons.chevron_down_square_fill, + CupertinoIcons.chevron_forward, + CupertinoIcons.chevron_left, + CupertinoIcons.chevron_left_2, + CupertinoIcons.chevron_left_circle, + CupertinoIcons.chevron_left_circle_fill, + CupertinoIcons.chevron_left_slash_chevron_right, + CupertinoIcons.chevron_left_square, + CupertinoIcons.chevron_left_square_fill, + CupertinoIcons.chevron_right, + CupertinoIcons.chevron_right_2, + CupertinoIcons.chevron_right_circle, + CupertinoIcons.chevron_right_circle_fill, + CupertinoIcons.chevron_right_square, + CupertinoIcons.chevron_right_square_fill, + CupertinoIcons.chevron_up, + CupertinoIcons.chevron_up_chevron_down, + CupertinoIcons.chevron_up_circle, + CupertinoIcons.chevron_up_circle_fill, + CupertinoIcons.chevron_up_square, + CupertinoIcons.chevron_up_square_fill, + CupertinoIcons.circle_bottomthird_split, + CupertinoIcons.circle_fill, + CupertinoIcons.circle_grid_3x3, + CupertinoIcons.circle_grid_3x3_fill, + CupertinoIcons.circle_grid_hex, + CupertinoIcons.circle_grid_hex_fill, + CupertinoIcons.circle_lefthalf_fill, + CupertinoIcons.circle_righthalf_fill, + CupertinoIcons.clear_fill, + CupertinoIcons.clock_fill, + CupertinoIcons.cloud, + CupertinoIcons.cloud_bolt, + CupertinoIcons.cloud_bolt_fill, + CupertinoIcons.cloud_bolt_rain, + CupertinoIcons.cloud_bolt_rain_fill, + CupertinoIcons.cloud_download, + CupertinoIcons.cloud_download_fill, + CupertinoIcons.cloud_drizzle, + CupertinoIcons.cloud_drizzle_fill, + CupertinoIcons.cloud_fill, + CupertinoIcons.cloud_fog, + CupertinoIcons.cloud_fog_fill, + CupertinoIcons.cloud_hail, + CupertinoIcons.cloud_hail_fill, + CupertinoIcons.cloud_heavyrain, + CupertinoIcons.cloud_heavyrain_fill, + CupertinoIcons.cloud_moon, + CupertinoIcons.cloud_moon_bolt, + CupertinoIcons.cloud_moon_bolt_fill, + CupertinoIcons.cloud_moon_fill, + CupertinoIcons.cloud_moon_rain, + CupertinoIcons.cloud_moon_rain_fill, + CupertinoIcons.cloud_rain, + CupertinoIcons.cloud_rain_fill, + CupertinoIcons.cloud_sleet, + CupertinoIcons.cloud_sleet_fill, + CupertinoIcons.cloud_snow, + CupertinoIcons.cloud_snow_fill, + CupertinoIcons.cloud_sun, + CupertinoIcons.cloud_sun_bolt, + CupertinoIcons.cloud_sun_bolt_fill, + CupertinoIcons.cloud_sun_fill, + CupertinoIcons.cloud_sun_rain, + CupertinoIcons.cloud_sun_rain_fill, + CupertinoIcons.cloud_upload, + CupertinoIcons.cloud_upload_fill, + CupertinoIcons.color_filter, + CupertinoIcons.color_filter_fill, + CupertinoIcons.command, + CupertinoIcons.compass, + CupertinoIcons.compass_fill, + CupertinoIcons.control, + CupertinoIcons.creditcard, + CupertinoIcons.creditcard_fill, + CupertinoIcons.crop, + CupertinoIcons.crop_rotate, + CupertinoIcons.cube, + CupertinoIcons.cube_box, + CupertinoIcons.cube_box_fill, + CupertinoIcons.cube_fill, + CupertinoIcons.cursor_rays, + CupertinoIcons.decrease_indent, + CupertinoIcons.decrease_quotelevel, + CupertinoIcons.delete_left, + CupertinoIcons.delete_left_fill, + CupertinoIcons.delete_right, + CupertinoIcons.delete_right_fill, + CupertinoIcons.desktopcomputer, + CupertinoIcons.device_desktop, + CupertinoIcons.device_laptop, + CupertinoIcons.device_phone_landscape, + CupertinoIcons.device_phone_portrait, + CupertinoIcons.dial, + CupertinoIcons.dial_fill, + CupertinoIcons.divide, + CupertinoIcons.divide_circle, + CupertinoIcons.divide_circle_fill, + CupertinoIcons.divide_square, + CupertinoIcons.divide_square_fill, + CupertinoIcons.doc, + CupertinoIcons.doc_append, + CupertinoIcons.doc_chart, + CupertinoIcons.doc_chart_fill, + CupertinoIcons.doc_checkmark, + CupertinoIcons.doc_checkmark_fill, + CupertinoIcons.doc_circle, + CupertinoIcons.doc_circle_fill, + CupertinoIcons.doc_fill, + CupertinoIcons.doc_on_clipboard, + CupertinoIcons.doc_on_clipboard_fill, + CupertinoIcons.doc_on_doc, + CupertinoIcons.doc_on_doc_fill, + CupertinoIcons.doc_person, + CupertinoIcons.doc_person_fill, + CupertinoIcons.doc_plaintext, + CupertinoIcons.doc_richtext, + CupertinoIcons.doc_text, + CupertinoIcons.doc_text_fill, + CupertinoIcons.doc_text_search, + CupertinoIcons.doc_text_viewfinder, + CupertinoIcons.dot_radiowaves_left_right, + CupertinoIcons.dot_radiowaves_right, + CupertinoIcons.dot_square, + CupertinoIcons.dot_square_fill, + CupertinoIcons.download_circle, + CupertinoIcons.download_circle_fill, + CupertinoIcons.drop, + CupertinoIcons.drop_fill, + CupertinoIcons.drop_triangle, + CupertinoIcons.drop_triangle_fill, + CupertinoIcons.ear, + CupertinoIcons.eject, + CupertinoIcons.eject_fill, + CupertinoIcons.ellipses_bubble, + CupertinoIcons.ellipses_bubble_fill, + CupertinoIcons.ellipsis_circle, + CupertinoIcons.ellipsis_circle_fill, + CupertinoIcons.ellipsis_vertical, + CupertinoIcons.ellipsis_vertical_circle, + CupertinoIcons.ellipsis_vertical_circle_fill, + CupertinoIcons.envelope, + CupertinoIcons.envelope_badge, + CupertinoIcons.envelope_badge_fill, + CupertinoIcons.envelope_circle, + CupertinoIcons.envelope_circle_fill, + CupertinoIcons.envelope_fill, + CupertinoIcons.envelope_open, + CupertinoIcons.envelope_open_fill, + CupertinoIcons.equal, + CupertinoIcons.equal_circle, + CupertinoIcons.equal_circle_fill, + CupertinoIcons.equal_square, + CupertinoIcons.equal_square_fill, + CupertinoIcons.escape, + CupertinoIcons.exclamationmark, + CupertinoIcons.exclamationmark_bubble, + CupertinoIcons.exclamationmark_bubble_fill, + CupertinoIcons.exclamationmark_circle, + CupertinoIcons.exclamationmark_circle_fill, + CupertinoIcons.exclamationmark_octagon, + CupertinoIcons.exclamationmark_octagon_fill, + CupertinoIcons.exclamationmark_shield, + CupertinoIcons.exclamationmark_shield_fill, + CupertinoIcons.exclamationmark_square, + CupertinoIcons.exclamationmark_square_fill, + CupertinoIcons.exclamationmark_triangle, + CupertinoIcons.exclamationmark_triangle_fill, + CupertinoIcons.eye_fill, + CupertinoIcons.eye_slash, + CupertinoIcons.eye_slash_fill, + CupertinoIcons.eyedropper, + CupertinoIcons.eyedropper_full, + CupertinoIcons.eyedropper_halffull, + CupertinoIcons.eyeglasses, + CupertinoIcons.f_cursive, + CupertinoIcons.f_cursive_circle, + CupertinoIcons.f_cursive_circle_fill, + CupertinoIcons.film, + CupertinoIcons.film_fill, + CupertinoIcons.flag_circle, + CupertinoIcons.flag_circle_fill, + CupertinoIcons.flag_fill, + CupertinoIcons.flag_slash, + CupertinoIcons.flag_slash_fill, + CupertinoIcons.flame, + CupertinoIcons.flame_fill, + CupertinoIcons.floppy_disk, + CupertinoIcons.flowchart, + CupertinoIcons.flowchart_fill, + CupertinoIcons.folder_badge_minus, + CupertinoIcons.folder_badge_person_crop, + CupertinoIcons.folder_badge_plus, + CupertinoIcons.folder_circle, + CupertinoIcons.folder_circle_fill, + CupertinoIcons.folder_fill, + CupertinoIcons.folder_fill_badge_minus, + CupertinoIcons.folder_fill_badge_person_crop, + CupertinoIcons.folder_fill_badge_plus, + CupertinoIcons.forward_end, + CupertinoIcons.forward_end_alt, + CupertinoIcons.forward_end_alt_fill, + CupertinoIcons.forward_end_fill, + CupertinoIcons.forward_fill, + CupertinoIcons.function, + CupertinoIcons.fx, + CupertinoIcons.gamecontroller, + CupertinoIcons.gamecontroller_alt_fill, + CupertinoIcons.gamecontroller_fill, + CupertinoIcons.gauge, + CupertinoIcons.gauge_badge_minus, + CupertinoIcons.gauge_badge_plus, + CupertinoIcons.gear_alt, + CupertinoIcons.gear_alt_fill, + CupertinoIcons.gift, + CupertinoIcons.gift_alt, + CupertinoIcons.gift_alt_fill, + CupertinoIcons.gift_fill, + CupertinoIcons.globe, + CupertinoIcons.gobackward, + CupertinoIcons.gobackward_10, + CupertinoIcons.gobackward_15, + CupertinoIcons.gobackward_30, + CupertinoIcons.gobackward_45, + CupertinoIcons.gobackward_60, + CupertinoIcons.gobackward_75, + CupertinoIcons.gobackward_90, + CupertinoIcons.gobackward_minus, + CupertinoIcons.goforward, + CupertinoIcons.goforward_10, + CupertinoIcons.goforward_15, + CupertinoIcons.goforward_30, + CupertinoIcons.goforward_45, + CupertinoIcons.goforward_60, + CupertinoIcons.goforward_75, + CupertinoIcons.goforward_90, + CupertinoIcons.goforward_plus, + CupertinoIcons.graph_circle, + CupertinoIcons.graph_circle_fill, + CupertinoIcons.graph_square, + CupertinoIcons.graph_square_fill, + CupertinoIcons.greaterthan, + CupertinoIcons.greaterthan_circle, + CupertinoIcons.greaterthan_circle_fill, + CupertinoIcons.greaterthan_square, + CupertinoIcons.greaterthan_square_fill, + CupertinoIcons.grid, + CupertinoIcons.grid_circle, + CupertinoIcons.grid_circle_fill, + CupertinoIcons.guitars, + CupertinoIcons.hammer, + CupertinoIcons.hammer_fill, + CupertinoIcons.hand_draw, + CupertinoIcons.hand_draw_fill, + CupertinoIcons.hand_point_left, + CupertinoIcons.hand_point_left_fill, + CupertinoIcons.hand_point_right, + CupertinoIcons.hand_point_right_fill, + CupertinoIcons.hand_raised, + CupertinoIcons.hand_raised_fill, + CupertinoIcons.hand_raised_slash, + CupertinoIcons.hand_raised_slash_fill, + CupertinoIcons.hand_thumbsdown, + CupertinoIcons.hand_thumbsdown_fill, + CupertinoIcons.hand_thumbsup, + CupertinoIcons.hand_thumbsup_fill, + CupertinoIcons.hare, + CupertinoIcons.hare_fill, + CupertinoIcons.headphones, + CupertinoIcons.heart_circle, + CupertinoIcons.heart_circle_fill, + CupertinoIcons.heart_fill, + CupertinoIcons.heart_slash, + CupertinoIcons.heart_slash_circle, + CupertinoIcons.heart_slash_circle_fill, + CupertinoIcons.heart_slash_fill, + CupertinoIcons.helm, + CupertinoIcons.hexagon, + CupertinoIcons.hexagon_fill, + CupertinoIcons.hifispeaker, + CupertinoIcons.hifispeaker_fill, + CupertinoIcons.hourglass, + CupertinoIcons.hourglass_bottomhalf_fill, + CupertinoIcons.hourglass_tophalf_fill, + CupertinoIcons.house, + CupertinoIcons.house_alt, + CupertinoIcons.house_alt_fill, + CupertinoIcons.house_fill, + CupertinoIcons.hurricane, + CupertinoIcons.increase_indent, + CupertinoIcons.increase_quotelevel, + CupertinoIcons.infinite, + CupertinoIcons.info_circle, + CupertinoIcons.info_circle_fill, + CupertinoIcons.italic, + CupertinoIcons.keyboard, + CupertinoIcons.keyboard_chevron_compact_down, + CupertinoIcons.largecircle_fill_circle, + CupertinoIcons.lasso, + CupertinoIcons.layers, + CupertinoIcons.layers_alt, + CupertinoIcons.layers_alt_fill, + CupertinoIcons.layers_fill, + CupertinoIcons.leaf_arrow_circlepath, + CupertinoIcons.lessthan, + CupertinoIcons.lessthan_circle, + CupertinoIcons.lessthan_circle_fill, + CupertinoIcons.lessthan_square, + CupertinoIcons.lessthan_square_fill, + CupertinoIcons.light_max, + CupertinoIcons.light_min, + CupertinoIcons.lightbulb, + CupertinoIcons.lightbulb_fill, + CupertinoIcons.lightbulb_slash, + CupertinoIcons.lightbulb_slash_fill, + CupertinoIcons.line_horizontal_3, + CupertinoIcons.line_horizontal_3_decrease, + CupertinoIcons.line_horizontal_3_decrease_circle, + CupertinoIcons.line_horizontal_3_decrease_circle_fill, + CupertinoIcons.link, + CupertinoIcons.link_circle, + CupertinoIcons.link_circle_fill, + CupertinoIcons.list_bullet, + CupertinoIcons.list_bullet_below_rectangle, + CupertinoIcons.list_bullet_indent, + CupertinoIcons.list_dash, + CupertinoIcons.list_number, + CupertinoIcons.list_number_rtl, + CupertinoIcons.location_circle, + CupertinoIcons.location_circle_fill, + CupertinoIcons.location_fill, + CupertinoIcons.location_north, + CupertinoIcons.location_north_fill, + CupertinoIcons.location_north_line, + CupertinoIcons.location_north_line_fill, + CupertinoIcons.location_slash, + CupertinoIcons.location_slash_fill, + CupertinoIcons.lock, + CupertinoIcons.lock_circle, + CupertinoIcons.lock_circle_fill, + CupertinoIcons.lock_fill, + CupertinoIcons.lock_open, + CupertinoIcons.lock_open_fill, + CupertinoIcons.lock_rotation, + CupertinoIcons.lock_rotation_open, + CupertinoIcons.lock_shield, + CupertinoIcons.lock_shield_fill, + CupertinoIcons.lock_slash, + CupertinoIcons.lock_slash_fill, + CupertinoIcons.macwindow, + CupertinoIcons.map, + CupertinoIcons.map_fill, + CupertinoIcons.map_pin, + CupertinoIcons.map_pin_ellipse, + CupertinoIcons.map_pin_slash, + CupertinoIcons.memories, + CupertinoIcons.memories_badge_minus, + CupertinoIcons.memories_badge_plus, + CupertinoIcons.metronome, + CupertinoIcons.mic_circle, + CupertinoIcons.mic_circle_fill, + CupertinoIcons.mic_fill, + CupertinoIcons.mic_slash, + CupertinoIcons.mic_slash_fill, + CupertinoIcons.minus, + CupertinoIcons.minus_circle, + CupertinoIcons.minus_circle_fill, + CupertinoIcons.minus_rectangle, + CupertinoIcons.minus_rectangle_fill, + CupertinoIcons.minus_slash_plus, + CupertinoIcons.minus_square, + CupertinoIcons.minus_square_fill, + CupertinoIcons.money_dollar, + CupertinoIcons.money_dollar_circle, + CupertinoIcons.money_dollar_circle_fill, + CupertinoIcons.money_euro, + CupertinoIcons.money_euro_circle, + CupertinoIcons.money_euro_circle_fill, + CupertinoIcons.money_pound, + CupertinoIcons.money_pound_circle, + CupertinoIcons.money_pound_circle_fill, + CupertinoIcons.money_rubl, + CupertinoIcons.money_rubl_circle, + CupertinoIcons.money_rubl_circle_fill, + CupertinoIcons.money_yen, + CupertinoIcons.money_yen_circle, + CupertinoIcons.money_yen_circle_fill, + CupertinoIcons.moon, + CupertinoIcons.moon_circle, + CupertinoIcons.moon_circle_fill, + CupertinoIcons.moon_fill, + CupertinoIcons.moon_stars, + CupertinoIcons.moon_stars_fill, + CupertinoIcons.moon_zzz, + CupertinoIcons.moon_zzz_fill, + CupertinoIcons.move, + CupertinoIcons.multiply, + CupertinoIcons.multiply_circle, + CupertinoIcons.multiply_circle_fill, + CupertinoIcons.multiply_square, + CupertinoIcons.multiply_square_fill, + CupertinoIcons.music_albums, + CupertinoIcons.music_albums_fill, + CupertinoIcons.music_house, + CupertinoIcons.music_house_fill, + CupertinoIcons.music_mic, + CupertinoIcons.music_note_2, + CupertinoIcons.music_note_list, + CupertinoIcons.nosign, + CupertinoIcons.number, + CupertinoIcons.number_circle, + CupertinoIcons.number_circle_fill, + CupertinoIcons.number_square, + CupertinoIcons.number_square_fill, + CupertinoIcons.option, + CupertinoIcons.paintbrush, + CupertinoIcons.paintbrush_fill, + CupertinoIcons.pano, + CupertinoIcons.pano_fill, + CupertinoIcons.paperclip, + CupertinoIcons.paperplane, + CupertinoIcons.paperplane_fill, + CupertinoIcons.paragraph, + CupertinoIcons.pause_circle, + CupertinoIcons.pause_circle_fill, + CupertinoIcons.pause_fill, + CupertinoIcons.pause_rectangle, + CupertinoIcons.pause_rectangle_fill, + CupertinoIcons.pencil_circle, + CupertinoIcons.pencil_circle_fill, + CupertinoIcons.pencil_ellipsis_rectangle, + CupertinoIcons.pencil_outline, + CupertinoIcons.pencil_slash, + CupertinoIcons.percent, + CupertinoIcons.person_2, + CupertinoIcons.person_2_alt, + CupertinoIcons.person_2_fill, + CupertinoIcons.person_2_square_stack, + CupertinoIcons.person_2_square_stack_fill, + CupertinoIcons.person_3, + CupertinoIcons.person_3_fill, + CupertinoIcons.person_alt, + CupertinoIcons.person_alt_circle, + CupertinoIcons.person_alt_circle_fill, + CupertinoIcons.person_badge_minus, + CupertinoIcons.person_badge_minus_fill, + CupertinoIcons.person_badge_plus, + CupertinoIcons.person_badge_plus_fill, + CupertinoIcons.person_circle, + CupertinoIcons.person_circle_fill, + CupertinoIcons.person_crop_circle, + CupertinoIcons.person_crop_circle_badge_checkmark, + CupertinoIcons.person_crop_circle_badge_exclam, + CupertinoIcons.person_crop_circle_badge_minus, + CupertinoIcons.person_crop_circle_badge_plus, + CupertinoIcons.person_crop_circle_badge_xmark, + CupertinoIcons.person_crop_circle_fill, + CupertinoIcons.person_crop_circle_fill_badge_checkmark, + CupertinoIcons.person_crop_circle_fill_badge_exclam, + CupertinoIcons.person_crop_circle_fill_badge_minus, + CupertinoIcons.person_crop_circle_fill_badge_plus, + CupertinoIcons.person_crop_circle_fill_badge_xmark, + CupertinoIcons.person_crop_rectangle, + CupertinoIcons.person_crop_rectangle_fill, + CupertinoIcons.person_crop_square, + CupertinoIcons.person_crop_square_fill, + CupertinoIcons.person_fill, + CupertinoIcons.personalhotspot, + CupertinoIcons.perspective, + CupertinoIcons.phone_arrow_down_left, + CupertinoIcons.phone_arrow_right, + CupertinoIcons.phone_arrow_up_right, + CupertinoIcons.phone_badge_plus, + CupertinoIcons.phone_circle, + CupertinoIcons.phone_circle_fill, + CupertinoIcons.phone_down, + CupertinoIcons.phone_down_circle, + CupertinoIcons.phone_down_circle_fill, + CupertinoIcons.phone_down_fill, + CupertinoIcons.phone_fill, + CupertinoIcons.phone_fill_arrow_down_left, + CupertinoIcons.phone_fill_arrow_right, + CupertinoIcons.phone_fill_arrow_up_right, + CupertinoIcons.phone_fill_badge_plus, + CupertinoIcons.photo, + CupertinoIcons.photo_fill, + CupertinoIcons.photo_fill_on_rectangle_fill, + CupertinoIcons.photo_on_rectangle, + CupertinoIcons.piano, + CupertinoIcons.pin, + CupertinoIcons.pin_fill, + CupertinoIcons.pin_slash, + CupertinoIcons.pin_slash_fill, + CupertinoIcons.placemark, + CupertinoIcons.placemark_fill, + CupertinoIcons.play, + CupertinoIcons.play_circle, + CupertinoIcons.play_circle_fill, + CupertinoIcons.play_fill, + CupertinoIcons.play_rectangle, + CupertinoIcons.play_rectangle_fill, + CupertinoIcons.playpause, + CupertinoIcons.playpause_fill, + CupertinoIcons.plus, + CupertinoIcons.plus_app, + CupertinoIcons.plus_app_fill, + CupertinoIcons.plus_bubble, + CupertinoIcons.plus_bubble_fill, + CupertinoIcons.plus_circle, + CupertinoIcons.plus_circle_fill, + CupertinoIcons.plus_rectangle, + CupertinoIcons.plus_rectangle_fill, + CupertinoIcons.plus_rectangle_fill_on_rectangle_fill, + CupertinoIcons.plus_rectangle_on_rectangle, + CupertinoIcons.plus_slash_minus, + CupertinoIcons.plus_square, + CupertinoIcons.plus_square_fill, + CupertinoIcons.plus_square_fill_on_square_fill, + CupertinoIcons.plus_square_on_square, + CupertinoIcons.plusminus, + CupertinoIcons.plusminus_circle, + CupertinoIcons.plusminus_circle_fill, + CupertinoIcons.power, + CupertinoIcons.printer, + CupertinoIcons.printer_fill, + CupertinoIcons.projective, + CupertinoIcons.purchased, + CupertinoIcons.purchased_circle, + CupertinoIcons.purchased_circle_fill, + CupertinoIcons.qrcode, + CupertinoIcons.qrcode_viewfinder, + CupertinoIcons.question, + CupertinoIcons.question_circle, + CupertinoIcons.question_circle_fill, + CupertinoIcons.question_diamond, + CupertinoIcons.question_diamond_fill, + CupertinoIcons.question_square, + CupertinoIcons.question_square_fill, + CupertinoIcons.quote_bubble, + CupertinoIcons.quote_bubble_fill, + CupertinoIcons.radiowaves_left, + CupertinoIcons.radiowaves_right, + CupertinoIcons.rays, + CupertinoIcons.recordingtape, + CupertinoIcons.rectangle, + CupertinoIcons.rectangle_3_offgrid, + CupertinoIcons.rectangle_3_offgrid_fill, + CupertinoIcons.rectangle_arrow_up_right_arrow_down_left, + CupertinoIcons.rectangle_arrow_up_right_arrow_down_left_slash, + CupertinoIcons.rectangle_badge_checkmark, + CupertinoIcons.rectangle_badge_xmark, + CupertinoIcons.rectangle_compress_vertical, + CupertinoIcons.rectangle_dock, + CupertinoIcons.rectangle_expand_vertical, + CupertinoIcons.rectangle_fill, + CupertinoIcons.rectangle_fill_badge_checkmark, + CupertinoIcons.rectangle_fill_badge_xmark, + CupertinoIcons.rectangle_fill_on_rectangle_angled_fill, + CupertinoIcons.rectangle_fill_on_rectangle_fill, + CupertinoIcons.rectangle_grid_1x2, + CupertinoIcons.rectangle_grid_1x2_fill, + CupertinoIcons.rectangle_grid_2x2, + CupertinoIcons.rectangle_grid_2x2_fill, + CupertinoIcons.rectangle_grid_3x2, + CupertinoIcons.rectangle_grid_3x2_fill, + CupertinoIcons.rectangle_on_rectangle, + CupertinoIcons.rectangle_on_rectangle_angled, + CupertinoIcons.rectangle_paperclip, + CupertinoIcons.rectangle_split_3x1, + CupertinoIcons.rectangle_split_3x1_fill, + CupertinoIcons.rectangle_split_3x3, + CupertinoIcons.rectangle_split_3x3_fill, + CupertinoIcons.rectangle_stack, + CupertinoIcons.rectangle_stack_badge_minus, + CupertinoIcons.rectangle_stack_badge_person_crop, + CupertinoIcons.rectangle_stack_badge_plus, + CupertinoIcons.rectangle_stack_fill, + CupertinoIcons.rectangle_stack_fill_badge_minus, + CupertinoIcons.rectangle_stack_fill_badge_person_crop, + CupertinoIcons.rectangle_stack_fill_badge_plus, + CupertinoIcons.rectangle_stack_person_crop, + CupertinoIcons.rectangle_stack_person_crop_fill, + CupertinoIcons.repeat, + CupertinoIcons.repeat_1, + CupertinoIcons.resize, + CupertinoIcons.resize_h, + CupertinoIcons.resize_v, + CupertinoIcons.return_icon, + CupertinoIcons.rhombus, + CupertinoIcons.rhombus_fill, + CupertinoIcons.rocket, + CupertinoIcons.rocket_fill, + CupertinoIcons.rosette, + CupertinoIcons.rotate_left, + CupertinoIcons.rotate_left_fill, + CupertinoIcons.rotate_right, + CupertinoIcons.rotate_right_fill, + CupertinoIcons.scissors, + CupertinoIcons.scissors_alt, + CupertinoIcons.scope, + CupertinoIcons.scribble, + CupertinoIcons.search_circle, + CupertinoIcons.search_circle_fill, + CupertinoIcons.selection_pin_in_out, + CupertinoIcons.shield, + CupertinoIcons.shield_fill, + CupertinoIcons.shield_lefthalf_fill, + CupertinoIcons.shield_slash, + CupertinoIcons.shield_slash_fill, + CupertinoIcons.shift, + CupertinoIcons.shift_fill, + CupertinoIcons.sidebar_left, + CupertinoIcons.sidebar_right, + CupertinoIcons.signature, + CupertinoIcons.skew, + CupertinoIcons.slash_circle, + CupertinoIcons.slash_circle_fill, + CupertinoIcons.slider_horizontal_3, + CupertinoIcons.slider_horizontal_below_rectangle, + CupertinoIcons.slowmo, + CupertinoIcons.smallcircle_circle, + CupertinoIcons.smallcircle_circle_fill, + CupertinoIcons.smallcircle_fill_circle, + CupertinoIcons.smallcircle_fill_circle_fill, + CupertinoIcons.smiley, + CupertinoIcons.smiley_fill, + CupertinoIcons.smoke, + CupertinoIcons.smoke_fill, + CupertinoIcons.snow, + CupertinoIcons.sort_down, + CupertinoIcons.sort_down_circle, + CupertinoIcons.sort_down_circle_fill, + CupertinoIcons.sort_up, + CupertinoIcons.sort_up_circle, + CupertinoIcons.sort_up_circle_fill, + CupertinoIcons.sparkles, + CupertinoIcons.speaker, + CupertinoIcons.speaker_1, + CupertinoIcons.speaker_1_fill, + CupertinoIcons.speaker_2, + CupertinoIcons.speaker_2_fill, + CupertinoIcons.speaker_3, + CupertinoIcons.speaker_3_fill, + CupertinoIcons.speaker_fill, + CupertinoIcons.speaker_slash, + CupertinoIcons.speaker_slash_fill, + CupertinoIcons.speaker_slash_fill_rtl, + CupertinoIcons.speaker_slash_rtl, + CupertinoIcons.speaker_zzz, + CupertinoIcons.speaker_zzz_fill, + CupertinoIcons.speaker_zzz_fill_rtl, + CupertinoIcons.speaker_zzz_rtl, + CupertinoIcons.speedometer, + CupertinoIcons.sportscourt, + CupertinoIcons.sportscourt_fill, + CupertinoIcons.square, + CupertinoIcons.square_arrow_down, + CupertinoIcons.square_arrow_down_fill, + CupertinoIcons.square_arrow_down_on_square, + CupertinoIcons.square_arrow_down_on_square_fill, + CupertinoIcons.square_arrow_left, + CupertinoIcons.square_arrow_left_fill, + CupertinoIcons.square_arrow_right, + CupertinoIcons.square_arrow_right_fill, + CupertinoIcons.square_arrow_up, + CupertinoIcons.square_arrow_up_fill, + CupertinoIcons.square_arrow_up_on_square, + CupertinoIcons.square_arrow_up_on_square_fill, + CupertinoIcons.square_favorites, + CupertinoIcons.square_favorites_alt, + CupertinoIcons.square_favorites_alt_fill, + CupertinoIcons.square_favorites_fill, + CupertinoIcons.square_fill, + CupertinoIcons.square_fill_line_vertical_square, + CupertinoIcons.square_fill_line_vertical_square_fill, + CupertinoIcons.square_fill_on_circle_fill, + CupertinoIcons.square_fill_on_square_fill, + CupertinoIcons.square_grid_2x2, + CupertinoIcons.square_grid_2x2_fill, + CupertinoIcons.square_grid_3x2, + CupertinoIcons.square_grid_3x2_fill, + CupertinoIcons.square_grid_4x3_fill, + CupertinoIcons.square_lefthalf_fill, + CupertinoIcons.square_line_vertical_square, + CupertinoIcons.square_line_vertical_square_fill, + CupertinoIcons.square_list, + CupertinoIcons.square_list_fill, + CupertinoIcons.square_on_circle, + CupertinoIcons.square_on_square, + CupertinoIcons.square_pencil, + CupertinoIcons.square_pencil_fill, + CupertinoIcons.square_righthalf_fill, + CupertinoIcons.square_split_1x2, + CupertinoIcons.square_split_1x2_fill, + CupertinoIcons.square_split_2x1, + CupertinoIcons.square_split_2x1_fill, + CupertinoIcons.square_split_2x2, + CupertinoIcons.square_split_2x2_fill, + CupertinoIcons.square_stack, + CupertinoIcons.square_stack_3d_down_dottedline, + CupertinoIcons.square_stack_3d_down_right, + CupertinoIcons.square_stack_3d_down_right_fill, + CupertinoIcons.square_stack_3d_up, + CupertinoIcons.square_stack_3d_up_fill, + CupertinoIcons.square_stack_3d_up_slash, + CupertinoIcons.square_stack_3d_up_slash_fill, + CupertinoIcons.square_stack_fill, + CupertinoIcons.squares_below_rectangle, + CupertinoIcons.star, + CupertinoIcons.star_circle, + CupertinoIcons.star_circle_fill, + CupertinoIcons.star_fill, + CupertinoIcons.star_lefthalf_fill, + CupertinoIcons.star_slash, + CupertinoIcons.star_slash_fill, + CupertinoIcons.staroflife, + CupertinoIcons.staroflife_fill, + CupertinoIcons.stop, + CupertinoIcons.stop_circle, + CupertinoIcons.stop_circle_fill, + CupertinoIcons.stop_fill, + CupertinoIcons.stopwatch, + CupertinoIcons.stopwatch_fill, + CupertinoIcons.strikethrough, + CupertinoIcons.suit_club, + CupertinoIcons.suit_club_fill, + CupertinoIcons.suit_diamond, + CupertinoIcons.suit_diamond_fill, + CupertinoIcons.suit_heart, + CupertinoIcons.suit_heart_fill, + CupertinoIcons.suit_spade, + CupertinoIcons.suit_spade_fill, + CupertinoIcons.sum, + CupertinoIcons.sun_dust, + CupertinoIcons.sun_dust_fill, + CupertinoIcons.sun_haze, + CupertinoIcons.sun_haze_fill, + CupertinoIcons.sun_max, + CupertinoIcons.sun_max_fill, + CupertinoIcons.sun_min, + CupertinoIcons.sun_min_fill, + CupertinoIcons.sunrise, + CupertinoIcons.sunrise_fill, + CupertinoIcons.sunset, + CupertinoIcons.sunset_fill, + CupertinoIcons.t_bubble, + CupertinoIcons.t_bubble_fill, + CupertinoIcons.table, + CupertinoIcons.table_badge_more, + CupertinoIcons.table_badge_more_fill, + CupertinoIcons.table_fill, + CupertinoIcons.tag_circle, + CupertinoIcons.tag_circle_fill, + CupertinoIcons.tag_fill, + CupertinoIcons.text_aligncenter, + CupertinoIcons.text_alignleft, + CupertinoIcons.text_alignright, + CupertinoIcons.text_append, + CupertinoIcons.text_badge_checkmark, + CupertinoIcons.text_badge_minus, + CupertinoIcons.text_badge_plus, + CupertinoIcons.text_badge_star, + CupertinoIcons.text_badge_xmark, + CupertinoIcons.text_bubble, + CupertinoIcons.text_bubble_fill, + CupertinoIcons.text_cursor, + CupertinoIcons.text_insert, + CupertinoIcons.text_justify, + CupertinoIcons.text_justifyleft, + CupertinoIcons.text_justifyright, + CupertinoIcons.text_quote, + CupertinoIcons.textbox, + CupertinoIcons.textformat, + CupertinoIcons.textformat_123, + CupertinoIcons.textformat_abc, + CupertinoIcons.textformat_abc_dottedunderline, + CupertinoIcons.textformat_alt, + CupertinoIcons.textformat_size, + CupertinoIcons.textformat_subscript, + CupertinoIcons.textformat_superscript, + CupertinoIcons.thermometer, + CupertinoIcons.thermometer_snowflake, + CupertinoIcons.thermometer_sun, + CupertinoIcons.ticket, + CupertinoIcons.ticket_fill, + CupertinoIcons.tickets, + CupertinoIcons.tickets_fill, + CupertinoIcons.timelapse, + CupertinoIcons.timer, + CupertinoIcons.timer_fill, + CupertinoIcons.today, + CupertinoIcons.today_fill, + CupertinoIcons.tornado, + CupertinoIcons.tortoise, + CupertinoIcons.tortoise_fill, + CupertinoIcons.tram_fill, + CupertinoIcons.trash, + CupertinoIcons.trash_circle, + CupertinoIcons.trash_circle_fill, + CupertinoIcons.trash_fill, + CupertinoIcons.trash_slash, + CupertinoIcons.trash_slash_fill, + CupertinoIcons.tray, + CupertinoIcons.tray_2, + CupertinoIcons.tray_2_fill, + CupertinoIcons.tray_arrow_down, + CupertinoIcons.tray_arrow_down_fill, + CupertinoIcons.tray_arrow_up, + CupertinoIcons.tray_arrow_up_fill, + CupertinoIcons.tray_fill, + CupertinoIcons.tray_full, + CupertinoIcons.tray_full_fill, + CupertinoIcons.tree, + CupertinoIcons.triangle, + CupertinoIcons.triangle_fill, + CupertinoIcons.triangle_lefthalf_fill, + CupertinoIcons.triangle_righthalf_fill, + CupertinoIcons.tropicalstorm, + CupertinoIcons.tuningfork, + CupertinoIcons.tv, + CupertinoIcons.tv_circle, + CupertinoIcons.tv_circle_fill, + CupertinoIcons.tv_fill, + CupertinoIcons.tv_music_note, + CupertinoIcons.tv_music_note_fill, + CupertinoIcons.uiwindow_split_2x1, + CupertinoIcons.umbrella, + CupertinoIcons.umbrella_fill, + CupertinoIcons.underline, + CupertinoIcons.upload_circle, + CupertinoIcons.upload_circle_fill, + CupertinoIcons.videocam, + CupertinoIcons.videocam_circle, + CupertinoIcons.videocam_circle_fill, + CupertinoIcons.videocam_fill, + CupertinoIcons.view_2d, + CupertinoIcons.view_3d, + CupertinoIcons.viewfinder, + CupertinoIcons.viewfinder_circle, + CupertinoIcons.viewfinder_circle_fill, + CupertinoIcons.wand_rays, + CupertinoIcons.wand_rays_inverse, + CupertinoIcons.wand_stars, + CupertinoIcons.wand_stars_inverse, + CupertinoIcons.waveform, + CupertinoIcons.waveform_circle, + CupertinoIcons.waveform_circle_fill, + CupertinoIcons.waveform_path, + CupertinoIcons.waveform_path_badge_minus, + CupertinoIcons.waveform_path_badge_plus, + CupertinoIcons.waveform_path_ecg, + CupertinoIcons.wifi, + CupertinoIcons.wifi_exclamationmark, + CupertinoIcons.wifi_slash, + CupertinoIcons.wind, + CupertinoIcons.wind_snow, + CupertinoIcons.wrench, + CupertinoIcons.wrench_fill, + CupertinoIcons.xmark, + CupertinoIcons.xmark_circle, + CupertinoIcons.xmark_circle_fill, + CupertinoIcons.xmark_octagon, + CupertinoIcons.xmark_octagon_fill, + CupertinoIcons.xmark_rectangle, + CupertinoIcons.xmark_rectangle_fill, + CupertinoIcons.xmark_seal, + CupertinoIcons.xmark_seal_fill, + CupertinoIcons.xmark_shield, + CupertinoIcons.xmark_shield_fill, + CupertinoIcons.xmark_square, + CupertinoIcons.xmark_square_fill, + CupertinoIcons.zoom_in, + CupertinoIcons.zoom_out, + CupertinoIcons.zzz +]..sort(_compare)); diff --git a/third_party/packages/flutter_svg/CHANGELOG.md b/third_party/packages/flutter_svg/CHANGELOG.md new file mode 100644 index 000000000000..1adca859374c --- /dev/null +++ b/third_party/packages/flutter_svg/CHANGELOG.md @@ -0,0 +1,706 @@ +## 2.0.14 + +* Makes the package WASM compatible. + +## 2.0.13 + +* Relaxes the dependency constraints on vector_graphics, vector_graphics_codec, + and vector_graphics_compiler. + +## 2.0.12 + +* Adds `missing_code_block_language_in_doc_comment` lint. + +## 2.0.11 + +* Transfers the package source from https://github.com/dnfield/flutter_svg + to https://github.com/flutter/packages. + +## 2.0.10+1 + +* Relax http dependency. + +## 2.0.10 + +* Use package:http for network requests, and allow injection of the client. +* Bump vector_graphics dependency. + +## 2.0.9 + +* Adds back `SvgPicture(theme:)` parameter with a deprecation. Although this + parameter was inherently broken, removing it would require a major semver + bump, which would cause consumers to miss out on important fixes. + +## 2.0.8 + +* Adds back `DefaultSvgTheme`. +* Bump vector_graphics to 1.1.9+1 +* Adds debugFillProperties +* Fix bug for cache keys. + +## 2.0.7 + +* Fix broken `matchTextDirection`. + +## 2.0.6 + +* Fix test-only issues with latest Flutter stable (3.10). +* Roll vector_graphics to higher minimum version. + +## 2.0.5 + +* Allow malformed UTF-8 in loaders. +* Make the cache respect the SvgTheme and ColorMapper, if present. + +## 2.0.4 + +* Newer version of vector_graphics. +* Caching bug fix. +* Reintroduce clipBehavior. + +## 2.0.3 + +* Require newer version of vector_graphics. +* Fix bug in cache that incorrectly fired assert. + +## 2.0.2 + +* Require newer version of vector_graphics with multiple fixes around + inheritence, patterns, and currentColor handling. + +## 2.0.1 + +* Disable Isolate parsing in debug mode. +* Fix internal Color representation leakage from `package:vector_graphics_compiler`. + +## 2.0.0+1 + +* Fix bug in asset loading from packages. + +## 2.0.0 + +* Use parsing backend from `vector_graphics_compiler`. + * Out of order defs now supported. + * Patterns supported. + * Many optimizations added. + * **REGRESSION**: Lost support for `dx` and `dy` on `text`. See + https://github.com/dnfield/vector_graphics/issues/44 if this is important to + you. +* Parse SVG data in background isolate by default. +* Use widgets/rendering strategy from `vector_graphics`. +* Much less caching. +* More tests work without special handling - most of parsing is now sync, + and the loaders know how to avoid using `compute` in tests. For SVGs that + contain images, `vg.waitForPendingDecodes` is available. + +**DEPRECATIONS** + +* The `VectorDrawable` classes have gone away. +* The `AvdPicture` and related classes/parser have gone away. +* The `PictureCache` and `PictureStream` classes have gone away. +* The `PicturePovider` class exists only for access to a no-op cache. +* Several static members on `SvgPicture` and the `svg` utility class have gone + away. +* The `color` and `colorBlendMode` properties have been removed. Instead, use + the `colorFilter` property. + +## 1.1.6 + +* Fix transforms on image tags, clipPaths. +* Avoid painting zero-width strokes. + +## 1.1.5 + +* More permissive about color strings. + +## 1.1.4 + +* Handle default image width/height properly. + +## 1.1.3 + +* Handle `pt` values. + +## 1.1.2 + +* Update path parsing/drawing dependencies to fix arc parsing bug. + +## 1.1.1+1 + +* Fix regression introduced in 1.1.1 +* Update fix for fill/stroke inheritence when currentColor is specified in the + SVG but not in the theme. + +## 1.1.1 + +* Fix a bug introduced in 1.1.0 related to fill/stroke inheritence. +* Explicit dev_dependency on flutter_lints +* Avoid deprecated API from Flutter. + +## 1.1.0 + +* Respect stroke* properties when a paint definition is used for a stroke. +* Respect stroke* properties from groups with no `@stroke` property. +* Bump package versions. + +## 1.0.3+1 + +* Fix bugs in picture disposal. + +## 1.0.3 + +* Use `longestLine` rather than `minIntrinsicWidth` to place text. +* Avoid unnecessary painting when a picture doesn't actually change in + [RenderPicture]. + +## 1.0.2 + +* Avoid cache invalidation when `currentColor` or font based units are not used. +* Support `rem` units. + +## 1.0.1 + +* Fix bug with incorrect fills in some cases of `` elements. +* Analysis cleanup of Dart code. +* Fix bug where self-closing `` tags could alter rendering. +* Fix bug where an invalid `@stroke-dasharray` could cause an infinite loop. +* Fix bugs related to nested `` elements in ``. +* Remove unnecessary `sync*` related code. + +## 1.0.0 + +* New widget/RenderObject implementation to avoid rebuilds/paints when + near or overlapping an animating widget. Also should improve raster + cacheability. +* Correctly list web as a supported platform. +* Support for em/ex units. +* Stable 1.0.0 release. + +## 0.23.0+1 + +* Missing commit that reduced breakages introduced in 0.23.0 + +## 0.23.0 + +* Support for currentColor +* Some API breaks around PictureProvider to support currentColor +* Support for `xml:space` +* Support for `text-decoration` +* Support for `font-style` + +## 0.22.1 + +* Pick up performance improvements in path_parsing 0.2.1 +* Performance improvements in XML parsing of SVGs. + +## 0.22.0 + +* Expose `PictureCache` on `PictureProvider`, and deprecate + `PictureProvider.cacheCount` and `PictureProvider.clearCache`. This is + intended to allow users to set a maximum cache size, which was previously + impossible. + +## 0.21.0+1 + +* Fix alignment/sizing issues introduced in 0.21.0 + +## 0.21.0 + +* Stable nullsafe release. + +## 0.21.0-nullsafety.1 + +* Fix bug introduced when width and height are both null on the widget. +* Use more efficient method for XML attribute parsing. + +## 0.21.0-nullsafety.0 + +* Fix sizing when both width and height are null. This is potentially breaking. +* Bump versions to stable nullsafe when possible +* Update README with links to alternative implementations of SVG in Flutter. +* Attempt to report file source/key when errors happen. +* Add missing platforms to example project, update Android embedding. +* Minor fixes for future error handling to respect new Dart rules/expectations. + +## 0.20.0-nullsafety.4 + +* Adds option `warningsAsErrors` that throws errors when detecting unsupported + SVG elements. + +## 0.20.0-nullsafety.3 + +* Fix broken image for pub. + +## 0.20.0-nullsafety.2 + +* Fix bug where HTTP headers were not passed along to the HTTP client. + +## 0.20.0-nullsafety.1 + +* Remove unnecessary package:collection dependency + +## 0.20.0-nullsafety.0 + +* Initial release with null safety +* Remove dead code +* Fix up incorrect `catchError` usages + +## 0.19.2+1 + +* Fix a bug where color filters were applied when they should not be. + +## 0.19.2 + +* Allow for opt-in/out of color filter caching behavior, undeprecate color + filtering on the providers, and allow for a global override. + +## 0.19.1 + +* Fix color filtering when BlendMode.color is used. + +## 0.19.0 + +* Avoid unnecessary cache invalidation of SVGs drawn with color changes by: + * Deprecate color filter related options on PictureProvider classes. + * Make ColorFilter a property on SvgPicture + * Use the ColorFiltered widget for filtered SVGs. +* Fix RTL rendering bug + +## 0.18.1 + +* Bump the path_drawing dependency to 0.4.1+1 +* Expose clipBehavior from FittedBox +* Expose SVG ids in `Drawable*` classes. +* Change type of `alignment` to `AlignmentGeometry` on `SvgPicture`. +* Fixed bug in transform parsing + +## 0.18.0 + +* Drop DiagnosticbleMixin usage. +* Bump XML dependency to ^4.1.0 and resolve deprecated API usages. +* Await futures in tests. + +## 0.17.4 + +* Allow `precachePicture` to take `null` for a `BuildContext`. +* Provide a clearer error message when nested `` elements are used. + +## 0.17.3+1 + +* Fixed regression in v0.17.3 for shape elements with no explicit fill but + explicit opacity. + +## 0.17.3 + +* Be more permissive about whitespace in transform attributes. +* Stop defaulting color to black when not present, fixing issue with colors + carried over from `use` elements. + +## 0.17.2 + +* Bumped minimum Flutter version to 1.6.7 to pick up DiagnosticableMixin. +* Allow more variations of whitespace in base64 encoded image data. + +## 0.17.1 + +* Fix for issue with `use` elements refering to groups or other `use` elements + not correctly applying styles. + +## 0.17.0 + +* Make ColorFiltering apply to whole layer instead of per paint operation. +* **BREAKING** Remove `colorFilter` parameter from `VectorDrawable.draw`. +* Fix color filtering for text. + +## 0.16.1 + +* Support `image` tags in `defs`. +* Make `DrawableRasterImage` implement `DrawableStyleable`. + +## 0.16.0 + +* Move `transform` out of `DrawableStyle` and onto `DrawableStyleable`. Shapes + already worked this way, and the transform logic was handled in a confusingly + different way than all the other style attributes. +* Support `` elements having `id`s. +* Properly apply transforms to referenced use eleemnts. + +## 0.15.0 + +* Respect transformations on `` tags. +* Be more tolerant of malformed base64 data, similar to browsers (specifically, + having spaces present in the data). ## 0.14.4 +* Apply masks in the correct order when blend modes are involved in shapes. + +## 0.14.4 + +* Support for masks on groups. +* Update example project to Android X. + +## 0.14.3 + +* Support for the `mix-blend-mode` attribute. + +## 0.14.2 + +* Format, open up obtainKey for testing. + +## 0.14.1 + +* Support for HSL colors (thanks to [@christianalfoni](https://github.com/christianalfoni)) + +## 0.14.0 + +* Added support for masks (thanks to [@krispypen](https://github.com/krispypen)) +* Allow for clearing of the picture cache + +## 0.13.1 + +* Fix case where color filters were incorrectly getting created. + +## 0.13.0+2 + +* Same fix for group opacity/saveLayer as in 0.12.4+2 + +## 0.13.0+1 + +* Bump path_drawing dependency, which includes bug fixes in parsing. + +## 0.13.0 + +* Updated SDK constraint to support new error message formats +* Updated error message formats +* Misc. updates for new SDK features + +## 0.12.4+2 + +* Changed version constraint to prevent pulling down from wrong flutter version. +* Fixed group opacity/saveLayer bug. + +## 0.12.4+1 + +* Bump dep on path_drawing which contains bugfixes for parsing. + +## 0.12.4 + +* Fixed `opacity` handling, particularly for groups. Previously, opacities were + averaged together, which resulted in incorrect compositing (particularly if + overlapping shapes were drawn within a group). Now, a new layer is created + with the opacity applied to the whole. This may cause some performance + degredation, but is more correct. +* Allow font-size to be specified in `px` (with an explicit postfix). +* Add `excludeFromSemantics` property for purely decorative SVGs. The default + value is false. + +## 0.12.3 + +* Fixed bug with stream completer unregistration. +* Fixed bug with text transforms in new parsing. +* Fixed bug with RGBA parsing for opacity + +## 0.12.2 + +* Fixed bug with AVD parsing from strings. + +## 0.12.1 + +* Support for `display="none"` and `visibility="hidden"`. + +## 0.12.0 + +* **BREAKING** Avoid scaling based on devicePixelRatio. This turned out to be a + mistake, and caused rendering inconsistencies across devices. It was + particularly harmful on devices where the ratio was less than 1.0. +* Add `precachePicture` method to allow for pre-caching of SVG assets. Similar + in functionality to `precacheImage` in the Flutter framework. Also added + improvements to error handling in the various related routines. + +## 0.11.0+1 + +* Format source code +* Remove unintentionally committed pubspec.lock + +## 0.11.0 + +* Rewrote parsing logic to unpin dart-xml dependency, and bumped Dart XML + dependency. +* Fix bug where unsupported elements could impact drawing. Unhandled elements + that have children will now be completely ignored. This is technically a + breaking change, as previously a child of an unsupported element could have + been drawn if it was supported. Fixes [#126](https://github.com/dnfield/flutter_svg/issues/126). + +## 0.10.4 + +* Fix bug in transform logic [#122](https://github.com/dnfield/flutter_svg/issues/122) +* Avoid defaulting to the rootBundle, using th DefaultAssetBundle instead when + resolving pictures [#118](https://github.com/dnfield/flutter_svg/pull/118) + +## 0.10.3 + +* Pin dart-xml to 3.2.5, as 3.3.0 is a breaking change (next release will + address this). +* Support `px` postfixes on many double literals. + +## 0.10.2 + +* Added a `semanticsLabel` property to `SvgPicture`. +* Updated tests to support async changes in Flutter's `Picture.toImage` method. + * This is breaking for tests - tests will now require a more recent version of + Flutter to run. It should not break consumers though. + +## 0.10.1 + +This is technically a breaking release, but it also includes important fixes for +v0.10.0. Rather than splitting the breaking parts out in to v0.11.0 so soon +after the release of v0.10.0, I'm including some more breaking changes here. +This will not normally be done. + +* Fix bug that caused `` elements that weren't self-closing to parse + improperly. +* Many documentation updates/improvements. +* Added support for gradients that use `xlink:href` +* **BREAKING**: Changed some of the methods on `DrawableDefinitionServer` to + support gradients better. +* **BREAKING**: Removed the `PaintServer` typedef, since this was only serving + gradients and we need to have more control there for `xlink:href` support. + +## 0.10.0+1 + +* Fix bug that caused an empty `` element prevent rendering. + +## 0.10.0 + +* Rewrite parsing to be more space efficient. +* Refactor parsing to enable more output possibilities. +* Create a dedicated SVG parsing class (SvgParser). +* Updates to text - better support for nested text/tspans. +* Miscellaneous bug fixes. +* Testing improvements. + +## 0.9.0+1 + +* Fix inheritance issues with `text-anchor`. +* Fix a few inconsistencies in text anchor processing/positioning. + +## 0.9.0 + +* **BREAKING** Improvements to text positioning. Thanks to @krispypen! + +## 0.8.3 + +* Implement support for `clipPath` outside of `defs` eleemnts. +* Implement support for `use` in a `clipPath`. +* Recommend `usvg` rather than `svgcleaner` per author's recommendation. + +## 0.8.2 + +* Make `DrawableNoop` implement `DrawableStyleable` to avoid crashing with + certain unhandled elements. +* Improve error reporting for certain `Flutter Logo which can be rendered by this package! + + +Draw SVG files using Flutter. + +## Getting Started + +Basic usage (to create an SVG rendering widget from an asset): + +```dart +final String assetName = 'assets/image.svg'; +final Widget svg = SvgPicture.asset( + assetName, + semanticsLabel: 'Acme Logo' +); +``` + +You can color/tint the image like so: + +```dart +final String assetName = 'assets/up_arrow.svg'; +final Widget svgIcon = SvgPicture.asset( + assetName, + colorFilter: ColorFilter.mode(Colors.red, BlendMode.srcIn), + semanticsLabel: 'A red up arrow' +); +``` + +The default placeholder is an empty box (`LimitedBox`) - although if a `height` +or `width` is specified on the `SvgPicture`, a `SizedBox` will be used instead +(which ensures better layout experience). There is currently no way to show an +Error visually, however errors will get properly logged to the console in debug +mode. + +You can also specify a placeholder widget. The placeholder will display during +parsing/loading (normally only relevant for network access). + +```dart +// Will print error messages to the console. +final String assetName = 'assets/image_that_does_not_exist.svg'; +final Widget svg = SvgPicture.asset( + assetName, +); + +final Widget networkSvg = SvgPicture.network( + 'https://site-that-takes-a-while.com/image.svg', + semanticsLabel: 'A shark?!', + placeholderBuilder: (BuildContext context) => Container( + padding: const EdgeInsets.all(30.0), + child: const CircularProgressIndicator()), +); +``` + +If you'd like to render the SVG to some other canvas, you can do something like: + +```dart +import 'package:flutter_svg/flutter_svg.dart'; +final String rawSvg = '''...'''; +final PictureInfo pictureInfo = await vg.loadPicture(SvgStringLoader(rawSvg), null); + +// You can draw the picture to a canvas: +canvas.drawPicture(pictureInfo.picture); + +// Or convert the picture to an image: +final ui.Image image = pictureInfo.picture.toImage(...); + +pictureInfo.picture.dispose(); +``` + +The `SvgPicture` helps to automate this logic, and it provides some convenience +wrappers for getting assets from multiple sources. Unlike the `vector_graphics` +package, this package _does not render the data to an `Image` at any point_. +This carries a performance penalty for some common use cases, but also allows +for more flexibility around scaling. + +## Precompiling and Optimizing SVGs + +The vector_graphics backend supports SVG compilation which produces a binary +format that is faster to parse and can optimize SVGs to reduce the amount of +clipping, masking, and overdraw. The SVG compilation is provided by +[`package:vector_graphics_compiler`](https://pub.dev/packages/vector_graphics_compiler). + +```sh +dart run vector_graphics_compiler -i assets/foo.svg -o assets/foo.svg.vec +``` + +The output `foo.svg.vec` can be loaded using the default constructor of +`SvgPicture`. + +```dart +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:vector_graphics/vector_graphics.dart'; + +final Widget svg = SvgPicture( + const AssetBytesLoader('assets/foo.svg.vec') +); +``` + +### Check SVG compatibility + +An SVG can be tested for compatibility with the vector graphics backend by +running the compiler locally to see if any errors are thrown. + +```sh +dart run vector_graphics_compiler -i $SVG_FILE -o $TEMPORARY_OUTPUT_TO_BE_DELETED --no-optimize-masks --no-optimize-clips --no-optimize-overdraw --no-tessellate +``` + +## Recommended Adobe Illustrator SVG Configuration +- In Styling: choose Presentation Attributes instead of Inline CSS because CSS is not fully supported. +- In Images: choose Embded not Linked to other file to get a single svg with no dependency to other files. +- In Objects IDs: choose layer names to add every layer name to svg tags or you can use minimal,it is optional. +![Export configuration](https://user-images.githubusercontent.com/2842459/62599914-91de9c00-b8fe-11e9-8fb7-4af57d5100f7.png) + +## SVG sample attribution + +SVGs in `/assets/w3samples` pulled from [W3 sample files](https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/) + +SVGs in `/assets/deborah_ufw` provided by @deborah-ufw + +SVGs in `/assets/simple` are pulled from trivial examples or generated to test +basic functionality - some of them come directly from the SVG 1.1 spec. Some +have also come or been adapted from issues raised in this repository. + +SVGs in `/assets/wikimedia` are pulled from [Wikimedia Commons](https://commons.wikimedia.org/wiki/Main_Page) + +Android Drawables in `/assets/android_vd` are pulled from Android Documentation +and examples. + +The Flutter Logo created based on the Flutter Logo Widget © Google. + +The Dart logo is from +[dartlang.org](https://github.com/dart-lang/site-shared/blob/master/src/_assets/images/dart/logo%2Btext/horizontal/original.svg) +© Google + +SVGs in `/assets/noto-emoji` are from [Google i18n noto-emoji](https://github.com/googlei18n/noto-emoji), +licensed under the Apache license. + +Please submit SVGs that can't render properly (e.g. that don't render here the +way they do in chrome), as long as they're not using anything "probably out of +scope" (above). + +## Commemoration + +This package was originally authored by +[Dan Field](https://github.com/dnfield) and has been forked here +from [dnfield/flutter_svg](https://github.com/dnfield/flutter_svg). +Dan was a member of the Flutter team at Google from 2018 until his death +in 2024. Dan’s impact and contributions to Flutter were immeasurable, and we +honor his memory by continuing to publish and maintain this package. diff --git a/third_party/packages/flutter_svg/dart_test.yaml b/third_party/packages/flutter_svg/dart_test.yaml new file mode 100644 index 000000000000..5abc3e45f992 --- /dev/null +++ b/third_party/packages/flutter_svg/dart_test.yaml @@ -0,0 +1,4 @@ +# _TolerantComparator uses methods that don't compile on web. +# TODO(stuartmorgan): Restructure to allow other tests to run; see +# https://github.com/flutter/flutter/issues/157741 +test_on: vm diff --git a/third_party/packages/flutter_svg/example/.gitignore b/third_party/packages/flutter_svg/example/.gitignore new file mode 100644 index 000000000000..b2845c378966 --- /dev/null +++ b/third_party/packages/flutter_svg/example/.gitignore @@ -0,0 +1,13 @@ +.DS_Store +.dart_tool/ + +.packages +.pub/ + +build/ + +.flutter-plugins + +flutter_export_environment.sh + +flutter_*.log diff --git a/third_party/packages/flutter_svg/example/.metadata b/third_party/packages/flutter_svg/example/.metadata new file mode 100644 index 000000000000..7ac78721d199 --- /dev/null +++ b/third_party/packages/flutter_svg/example/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 1725a26e2950a3d98e2af8c98759e11a47b2f90e + channel: master + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 1725a26e2950a3d98e2af8c98759e11a47b2f90e + base_revision: 1725a26e2950a3d98e2af8c98759e11a47b2f90e + - platform: macos + create_revision: 1725a26e2950a3d98e2af8c98759e11a47b2f90e + base_revision: 1725a26e2950a3d98e2af8c98759e11a47b2f90e + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/third_party/packages/flutter_svg/example/README.md b/third_party/packages/flutter_svg/example/README.md new file mode 100644 index 000000000000..3870e32cfbfa --- /dev/null +++ b/third_party/packages/flutter_svg/example/README.md @@ -0,0 +1,7 @@ +# example + +An example of using `flutter_svg` to render an SVG image. + +## Benchmarking + +`flutter drive --profile --endless-trace-buffer --target test_driver/bench.dart` diff --git a/third_party/packages/flutter_svg/example/android/.gitignore b/third_party/packages/flutter_svg/example/android/.gitignore new file mode 100644 index 000000000000..0a741cb43d66 --- /dev/null +++ b/third_party/packages/flutter_svg/example/android/.gitignore @@ -0,0 +1,11 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties diff --git a/third_party/packages/flutter_svg/example/android/app/build.gradle b/third_party/packages/flutter_svg/example/android/app/build.gradle new file mode 100644 index 000000000000..0a6e4fe90bb3 --- /dev/null +++ b/third_party/packages/flutter_svg/example/android/app/build.gradle @@ -0,0 +1,69 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + namespace 'io.flutter.plugins.fluttersvgexample' + compileSdkVersion flutter.compileSdkVersion + + compileOptions { + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 + } + + kotlinOptions { + jvmTarget = '11' + } + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "io.flutter.plugins.fluttersvgexample" + minSdkVersion flutter.minSdkVersion + targetSdkVersion 34 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" +} diff --git a/third_party/packages/flutter_svg/example/android/app/src/debug/AndroidManifest.xml b/third_party/packages/flutter_svg/example/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 000000000000..f880684a6a9c --- /dev/null +++ b/third_party/packages/flutter_svg/example/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,6 @@ + + + + diff --git a/third_party/packages/flutter_svg/example/android/app/src/main/AndroidManifest.xml b/third_party/packages/flutter_svg/example/android/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000000..da83c1e12897 --- /dev/null +++ b/third_party/packages/flutter_svg/example/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/android/app/src/main/kotlin/io/flutter/plugins/fluttersvgexample/MainActivity.kt b/third_party/packages/flutter_svg/example/android/app/src/main/kotlin/io/flutter/plugins/fluttersvgexample/MainActivity.kt new file mode 100644 index 000000000000..ed8683298b61 --- /dev/null +++ b/third_party/packages/flutter_svg/example/android/app/src/main/kotlin/io/flutter/plugins/fluttersvgexample/MainActivity.kt @@ -0,0 +1,5 @@ +package io.flutter.plugins.fluttersvgexample + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity : FlutterActivity() {} diff --git a/third_party/packages/flutter_svg/example/android/app/src/main/res/drawable-v21/launch_background.xml b/third_party/packages/flutter_svg/example/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 000000000000..f74085f3f6a2 --- /dev/null +++ b/third_party/packages/flutter_svg/example/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/android/app/src/main/res/drawable/launch_background.xml b/third_party/packages/flutter_svg/example/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 000000000000..304732f88420 --- /dev/null +++ b/third_party/packages/flutter_svg/example/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000000..db77bb4b7b09 Binary files /dev/null and b/third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000000..17987b79bb8a Binary files /dev/null and b/third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000000..09d4391482be Binary files /dev/null and b/third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000000..d5f1c8d34e7a Binary files /dev/null and b/third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000000..4d6372eebdb2 Binary files /dev/null and b/third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/third_party/packages/flutter_svg/example/android/app/src/main/res/values-night/styles.xml b/third_party/packages/flutter_svg/example/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 000000000000..449a9f930826 --- /dev/null +++ b/third_party/packages/flutter_svg/example/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/third_party/packages/flutter_svg/example/android/app/src/main/res/values/styles.xml b/third_party/packages/flutter_svg/example/android/app/src/main/res/values/styles.xml new file mode 100644 index 000000000000..d74aa35c2826 --- /dev/null +++ b/third_party/packages/flutter_svg/example/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/third_party/packages/flutter_svg/example/android/app/src/profile/AndroidManifest.xml b/third_party/packages/flutter_svg/example/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 000000000000..f880684a6a9c --- /dev/null +++ b/third_party/packages/flutter_svg/example/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,6 @@ + + + + diff --git a/third_party/packages/flutter_svg/example/android/build.gradle b/third_party/packages/flutter_svg/example/android/build.gradle new file mode 100644 index 000000000000..571f15900e8f --- /dev/null +++ b/third_party/packages/flutter_svg/example/android/build.gradle @@ -0,0 +1,38 @@ +buildscript { + ext.kotlin_version = '1.9.0' + repositories { + google() + jcenter() + } + + 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. + def artifactRepoKey = 'ARTIFACT_HUB_REPOSITORY' + if (System.getenv().containsKey(artifactRepoKey)) { + println "Using artifact hub" + maven { url System.getenv(artifactRepoKey) } + } + + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +tasks.register("clean", Delete) { + delete rootProject.buildDir +} diff --git a/third_party/packages/flutter_svg/example/android/gradle.properties b/third_party/packages/flutter_svg/example/android/gradle.properties new file mode 100644 index 000000000000..94adc3a3f97a --- /dev/null +++ b/third_party/packages/flutter_svg/example/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx1536M +android.useAndroidX=true +android.enableJetifier=true diff --git a/packages/image_picker/image_picker_android/android/gradle/wrapper/gradle-wrapper.properties b/third_party/packages/flutter_svg/example/android/gradle/wrapper/gradle-wrapper.properties similarity index 80% rename from packages/image_picker/image_picker_android/android/gradle/wrapper/gradle-wrapper.properties rename to third_party/packages/flutter_svg/example/android/gradle/wrapper/gradle-wrapper.properties index 068cdb2dc260..7aeeb11c6ee5 100644 --- a/packages/image_picker/image_picker_android/android/gradle/wrapper/gradle-wrapper.properties +++ b/third_party/packages/flutter_svg/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/third_party/packages/flutter_svg/example/android/settings.gradle b/third_party/packages/flutter_svg/example/android/settings.gradle new file mode 100644 index 000000000000..f246a74091be --- /dev/null +++ b/third_party/packages/flutter_svg/example/android/settings.gradle @@ -0,0 +1,24 @@ +include ':app' + +def localPropertiesFile = new File(rootProject.projectDir, "local.properties") +def properties = new Properties() + +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" + } +} +apply plugin: "com.google.cloud.artifactregistry.gradle-plugin" diff --git a/third_party/packages/flutter_svg/example/assets/android_vd/battery_charging.xml b/third_party/packages/flutter_svg/example/assets/android_vd/battery_charging.xml new file mode 100644 index 000000000000..61628a7602aa --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/android_vd/battery_charging.xml @@ -0,0 +1,22 @@ + + + + + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/dart.svg b/third_party/packages/flutter_svg/example/assets/dart.svg new file mode 100644 index 000000000000..261e2bbf97da --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/dart.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-action-expander.svg b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-action-expander.svg new file mode 100644 index 000000000000..3cbd1068517c --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-action-expander.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-camera.svg b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-camera.svg new file mode 100644 index 000000000000..b49e595b6c94 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-camera.svg @@ -0,0 +1,21 @@ + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-gif-button.svg b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-gif-button.svg new file mode 100644 index 000000000000..2340bf1acfb6 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-gif-button.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-gif.svg b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-gif.svg new file mode 100644 index 000000000000..cf9e9cab65be --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-gif.svg @@ -0,0 +1,30 @@ + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-image.svg b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-image.svg new file mode 100644 index 000000000000..ed41cff77c18 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-image.svg @@ -0,0 +1,19 @@ + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-mention.svg b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-mention.svg new file mode 100644 index 000000000000..085a7d41b8b8 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-mention.svg @@ -0,0 +1,22 @@ + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-pause-button.svg b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-pause-button.svg new file mode 100644 index 000000000000..90deeee9a5af --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-pause-button.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-play-button.svg b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-play-button.svg new file mode 100644 index 000000000000..40799c91370e --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-play-button.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-send-circle.svg b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-send-circle.svg new file mode 100644 index 000000000000..ab58e6b145fd --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-send-circle.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/deborah_ufw/numeric_25.svg b/third_party/packages/flutter_svg/example/assets/deborah_ufw/numeric_25.svg new file mode 100644 index 000000000000..ea6f38c2b3d8 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/deborah_ufw/numeric_25.svg @@ -0,0 +1,19 @@ + + + +icon-font/25/numeric_25 +Created with Sketch. + + + + diff --git a/third_party/packages/flutter_svg/example/assets/flutter_logo.svg b/third_party/packages/flutter_svg/example/assets/flutter_logo.svg new file mode 100644 index 000000000000..ec3d9144f352 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/flutter_logo.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/noto-emoji/emoji_u1f600.svg b/third_party/packages/flutter_svg/example/assets/noto-emoji/emoji_u1f600.svg new file mode 100644 index 000000000000..9916423433b1 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/noto-emoji/emoji_u1f600.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/simple/blend_and_mask.svg b/third_party/packages/flutter_svg/example/assets/simple/blend_and_mask.svg new file mode 100644 index 000000000000..b914058f3967 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/blend_and_mask.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/blend_mode_devil.svg b/third_party/packages/flutter_svg/example/assets/simple/blend_mode_devil.svg new file mode 100644 index 000000000000..913bdf5df820 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/blend_mode_devil.svg @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3Asset 23 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/clip_path.svg b/third_party/packages/flutter_svg/example/assets/simple/clip_path.svg new file mode 100644 index 000000000000..214d353b44f1 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/clip_path.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/clip_path_2.svg b/third_party/packages/flutter_svg/example/assets/simple/clip_path_2.svg new file mode 100644 index 000000000000..69e4f3fca3c0 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/clip_path_2.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/clip_path_3.svg b/third_party/packages/flutter_svg/example/assets/simple/clip_path_3.svg new file mode 100644 index 000000000000..93218c16db06 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/clip_path_3.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/clip_path_transform.svg b/third_party/packages/flutter_svg/example/assets/simple/clip_path_transform.svg new file mode 100644 index 000000000000..80a791eb12a7 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/clip_path_transform.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/simple/dash_path.svg b/third_party/packages/flutter_svg/example/assets/simple/dash_path.svg new file mode 100644 index 000000000000..70f58f828251 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/dash_path.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/simple/dash_zero.svg b/third_party/packages/flutter_svg/example/assets/simple/dash_zero.svg new file mode 100644 index 000000000000..b4c5925544d9 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/dash_zero.svg @@ -0,0 +1,3 @@ + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/ellipse.svg b/third_party/packages/flutter_svg/example/assets/simple/ellipse.svg new file mode 100644 index 000000000000..2ad80bdac7b5 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/ellipse.svg @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/simple/empty_defs.svg b/third_party/packages/flutter_svg/example/assets/simple/empty_defs.svg new file mode 100644 index 000000000000..18e04804cc66 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/empty_defs.svg @@ -0,0 +1,13 @@ + + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/simple/empty_group.svg b/third_party/packages/flutter_svg/example/assets/simple/empty_group.svg new file mode 100644 index 000000000000..af423cf01068 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/empty_group.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/equation.svg b/third_party/packages/flutter_svg/example/assets/simple/equation.svg new file mode 100644 index 000000000000..4aa4df5f0675 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/equation.svg @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/fill-rule-inherit.svg b/third_party/packages/flutter_svg/example/assets/simple/fill-rule-inherit.svg new file mode 100644 index 000000000000..cedebd1a5c4e --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/fill-rule-inherit.svg @@ -0,0 +1,4 @@ + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/simple/fill_inheritence_test.svg b/third_party/packages/flutter_svg/example/assets/simple/fill_inheritence_test.svg new file mode 100644 index 000000000000..93a8222771c6 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/fill_inheritence_test.svg @@ -0,0 +1,4 @@ + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/group_composite_opacity.svg b/third_party/packages/flutter_svg/example/assets/simple/group_composite_opacity.svg new file mode 100644 index 000000000000..9a87ce3c29ed --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/group_composite_opacity.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/group_fill_opacity.svg b/third_party/packages/flutter_svg/example/assets/simple/group_fill_opacity.svg new file mode 100644 index 000000000000..44216e06c1c3 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/group_fill_opacity.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/simple/group_in_defs.svg b/third_party/packages/flutter_svg/example/assets/simple/group_in_defs.svg new file mode 100644 index 000000000000..243c4b3ea47d --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/group_in_defs.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/group_mask.svg b/third_party/packages/flutter_svg/example/assets/simple/group_mask.svg new file mode 100644 index 000000000000..0d97150a2504 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/group_mask.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/group_opacity.svg b/third_party/packages/flutter_svg/example/assets/simple/group_opacity.svg new file mode 100644 index 000000000000..85e75db327fb --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/group_opacity.svg @@ -0,0 +1,46 @@ + + + + Example opacity01 - opacity property + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/group_opacity_transform.svg b/third_party/packages/flutter_svg/example/assets/simple/group_opacity_transform.svg new file mode 100644 index 000000000000..050226d65ad4 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/group_opacity_transform.svg @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/hidden.svg b/third_party/packages/flutter_svg/example/assets/simple/hidden.svg new file mode 100644 index 000000000000..e53744f7b5d1 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/hidden.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/href-fill.svg b/third_party/packages/flutter_svg/example/assets/simple/href-fill.svg new file mode 100644 index 000000000000..4e0817155d79 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/href-fill.svg @@ -0,0 +1,16 @@ + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/image.svg b/third_party/packages/flutter_svg/example/assets/simple/image.svg new file mode 100644 index 000000000000..fb8249c83623 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/image.svg @@ -0,0 +1,8 @@ + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/image_def.svg b/third_party/packages/flutter_svg/example/assets/simple/image_def.svg new file mode 100644 index 000000000000..35b2bbe82790 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/image_def.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/image_transform_before_translate.svg b/third_party/packages/flutter_svg/example/assets/simple/image_transform_before_translate.svg new file mode 100644 index 000000000000..f74b1a25893b --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/image_transform_before_translate.svg @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/simple/implicit_fill_with_opacity.svg b/third_party/packages/flutter_svg/example/assets/simple/implicit_fill_with_opacity.svg new file mode 100644 index 000000000000..309055e3c3fd --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/implicit_fill_with_opacity.svg @@ -0,0 +1,4 @@ + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/invalid_dash_array.svg b/third_party/packages/flutter_svg/example/assets/simple/invalid_dash_array.svg new file mode 100644 index 000000000000..24b0b96cf0c5 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/invalid_dash_array.svg @@ -0,0 +1,3 @@ +a + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/simple/linear_gradient.svg b/third_party/packages/flutter_svg/example/assets/simple/linear_gradient.svg new file mode 100644 index 000000000000..71de9c64894e --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/linear_gradient.svg @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/simple/linear_gradient_2.svg b/third_party/packages/flutter_svg/example/assets/simple/linear_gradient_2.svg new file mode 100644 index 000000000000..54c92ead9c37 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/linear_gradient_2.svg @@ -0,0 +1,24 @@ + + + + Example lingrad01 - fill a rectangle using a + linear gradient paint server + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/simple/linear_gradient_absolute_user_space_translate.svg b/third_party/packages/flutter_svg/example/assets/simple/linear_gradient_absolute_user_space_translate.svg new file mode 100644 index 000000000000..14245d72b257 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/linear_gradient_absolute_user_space_translate.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/linear_gradient_percentage_bounding_translate.svg b/third_party/packages/flutter_svg/example/assets/simple/linear_gradient_percentage_bounding_translate.svg new file mode 100644 index 000000000000..272eae3fb1db --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/linear_gradient_percentage_bounding_translate.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/linear_gradient_percentage_user_space_translate.svg b/third_party/packages/flutter_svg/example/assets/simple/linear_gradient_percentage_user_space_translate.svg new file mode 100644 index 000000000000..cd8a97a8e2f1 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/linear_gradient_percentage_user_space_translate.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/linear_gradient_xlink.svg b/third_party/packages/flutter_svg/example/assets/simple/linear_gradient_xlink.svg new file mode 100644 index 000000000000..b20f1dd1be51 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/linear_gradient_xlink.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/male.svg b/third_party/packages/flutter_svg/example/assets/simple/male.svg new file mode 100644 index 000000000000..5dc9f18ff316 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/male.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/simple/mask.svg b/third_party/packages/flutter_svg/example/assets/simple/mask.svg new file mode 100644 index 000000000000..c2e447f926e5 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/mask.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/mask_with_gradient.svg b/third_party/packages/flutter_svg/example/assets/simple/mask_with_gradient.svg new file mode 100644 index 000000000000..8524a1349963 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/mask_with_gradient.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/mask_with_use.svg b/third_party/packages/flutter_svg/example/assets/simple/mask_with_use.svg new file mode 100644 index 000000000000..ee5e01fa39a3 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/mask_with_use.svg @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/simple/mask_with_use2.svg b/third_party/packages/flutter_svg/example/assets/simple/mask_with_use2.svg new file mode 100644 index 000000000000..9a12ee155786 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/mask_with_use2.svg @@ -0,0 +1,15 @@ + + + + + + + + +   + +   + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/nested_group.svg b/third_party/packages/flutter_svg/example/assets/simple/nested_group.svg new file mode 100644 index 000000000000..e0677f87089e --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/nested_group.svg @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/simple/opacity_on_path.svg b/third_party/packages/flutter_svg/example/assets/simple/opacity_on_path.svg new file mode 100644 index 000000000000..481dd35233f8 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/opacity_on_path.svg @@ -0,0 +1,4 @@ + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/radial_gradient.svg b/third_party/packages/flutter_svg/example/assets/simple/radial_gradient.svg new file mode 100644 index 000000000000..c7de1853734e --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/radial_gradient.svg @@ -0,0 +1,23 @@ + + + + Example radgrad01 - fill a rectangle by referencing a + radial gradient paint server + + + + + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/radial_gradient_absolute_user_space_translate.svg b/third_party/packages/flutter_svg/example/assets/simple/radial_gradient_absolute_user_space_translate.svg new file mode 100644 index 000000000000..9b31aaa99d41 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/radial_gradient_absolute_user_space_translate.svg @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/radial_gradient_focal.svg b/third_party/packages/flutter_svg/example/assets/simple/radial_gradient_focal.svg new file mode 100644 index 000000000000..862c829f50b3 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/radial_gradient_focal.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/simple/radial_gradient_percentage_bounding_translate.svg b/third_party/packages/flutter_svg/example/assets/simple/radial_gradient_percentage_bounding_translate.svg new file mode 100644 index 000000000000..91279aa96eb1 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/radial_gradient_percentage_bounding_translate.svg @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/radial_gradient_percentage_user_space_translate.svg b/third_party/packages/flutter_svg/example/assets/simple/radial_gradient_percentage_user_space_translate.svg new file mode 100644 index 000000000000..7d8827bc4036 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/radial_gradient_percentage_user_space_translate.svg @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/radial_gradient_xlink.svg b/third_party/packages/flutter_svg/example/assets/simple/radial_gradient_xlink.svg new file mode 100644 index 000000000000..ea3f3cd0ba1e --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/radial_gradient_xlink.svg @@ -0,0 +1,24 @@ + + + + Example radgrad01 - fill a rectangle by referencing a + radial gradient paint server + + + + + + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/radial_ref_linear_gradient.svg b/third_party/packages/flutter_svg/example/assets/simple/radial_ref_linear_gradient.svg new file mode 100644 index 000000000000..cb3ad4142a05 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/radial_ref_linear_gradient.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/rect_rrect.svg b/third_party/packages/flutter_svg/example/assets/simple/rect_rrect.svg new file mode 100644 index 000000000000..24ce5bcbb0eb --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/rect_rrect.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/rect_rrect_no_ry.svg b/third_party/packages/flutter_svg/example/assets/simple/rect_rrect_no_ry.svg new file mode 100644 index 000000000000..59734736b771 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/rect_rrect_no_ry.svg @@ -0,0 +1,3 @@ + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/stroke_inherit_circles.svg b/third_party/packages/flutter_svg/example/assets/simple/stroke_inherit_circles.svg new file mode 100644 index 000000000000..804bfad35d6d --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/stroke_inherit_circles.svg @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/simple/style_attr.svg b/third_party/packages/flutter_svg/example/assets/simple/style_attr.svg new file mode 100644 index 000000000000..1c42fd79dd0f --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/style_attr.svg @@ -0,0 +1,6 @@ + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/text.svg b/third_party/packages/flutter_svg/example/assets/simple/text.svg new file mode 100644 index 000000000000..ac5bb68b079a --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/text.svg @@ -0,0 +1,16 @@ + + + + Example text01 - 'Hello, out there' in blue + + + Hello, out there + + + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/simple/text_2.svg b/third_party/packages/flutter_svg/example/assets/simple/text_2.svg new file mode 100644 index 000000000000..077e16e4678b --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/text_2.svg @@ -0,0 +1,28 @@ + + + + Example text01 + + + Plain text Roboto + + Plain text Verdana + + + Bold text Verdana + + + + + + Stroked bold line + Line 3 + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/simple/text_3.svg b/third_party/packages/flutter_svg/example/assets/simple/text_3.svg new file mode 100644 index 000000000000..38fee3d76840 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/text_3.svg @@ -0,0 +1,11 @@ + + + + + + + platform + flutter|dart vm + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/simple/text_4.svg b/third_party/packages/flutter_svg/example/assets/simple/text_4.svg new file mode 100644 index 000000000000..4348492e7d44 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/text_4.svg @@ -0,0 +1,22 @@ + + + + Example text04 - Font style + + + Normal text + + Italic text + + + Oblique text + + + Italic bold text + diff --git a/third_party/packages/flutter_svg/example/assets/simple/text_5.svg b/third_party/packages/flutter_svg/example/assets/simple/text_5.svg new file mode 100644 index 000000000000..63f711fb196a --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/text_5.svg @@ -0,0 +1,21 @@ + + + Example text05 - Text decoration + + + Overline text + + + Strike text + + + Underline text + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/text_6.svg b/third_party/packages/flutter_svg/example/assets/simple/text_6.svg new file mode 100644 index 000000000000..f1bd9d00f4c8 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/text_6.svg @@ -0,0 +1,18 @@ + + + Example text 06 - Text anchor + + + Text anchor start + + + Text anchor middle + + + Text anchor end + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/use_circles.svg b/third_party/packages/flutter_svg/example/assets/simple/use_circles.svg new file mode 100644 index 000000000000..56b1e49614cf --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/use_circles.svg @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/simple/use_circles_def.svg b/third_party/packages/flutter_svg/example/assets/simple/use_circles_def.svg new file mode 100644 index 000000000000..3df93330803a --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/use_circles_def.svg @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/simple/use_emc2.svg b/third_party/packages/flutter_svg/example/assets/simple/use_emc2.svg new file mode 100644 index 000000000000..8a3982f780e9 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/use_emc2.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/use_fill.svg b/third_party/packages/flutter_svg/example/assets/simple/use_fill.svg new file mode 100644 index 000000000000..5f87895642ea --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/use_fill.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/use_fill_test.svg b/third_party/packages/flutter_svg/example/assets/simple/use_fill_test.svg new file mode 100644 index 000000000000..3bf0fe96a3e1 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/use_fill_test.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/simple/use_opacity_grid.svg b/third_party/packages/flutter_svg/example/assets/simple/use_opacity_grid.svg new file mode 100644 index 000000000000..cee08c158a81 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/use_opacity_grid.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/simple/width_height_viewbox.svg b/third_party/packages/flutter_svg/example/assets/simple/width_height_viewbox.svg new file mode 100644 index 000000000000..99658b912dc3 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/width_height_viewbox.svg @@ -0,0 +1,15 @@ + + + Close + Created with Sketch. + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/simple/zero_width_strokes.svg b/third_party/packages/flutter_svg/example/assets/simple/zero_width_strokes.svg new file mode 100644 index 000000000000..36e37d8d7b95 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/simple/zero_width_strokes.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/svg_currentcolor.svg b/third_party/packages/flutter_svg/example/assets/svg_currentcolor.svg new file mode 100644 index 000000000000..850efed2c235 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/svg_currentcolor.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/text_transform.svg b/third_party/packages/flutter_svg/example/assets/text_transform.svg new file mode 100644 index 000000000000..8ca73425908d --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/text_transform.svg @@ -0,0 +1,8 @@ + + + + + A + + + diff --git a/third_party/packages/flutter_svg/example/assets/w3samples/aa.svg b/third_party/packages/flutter_svg/example/assets/w3samples/aa.svg new file mode 100644 index 000000000000..2f2d26b165a7 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/w3samples/aa.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/w3samples/alphachannel.svg b/third_party/packages/flutter_svg/example/assets/w3samples/alphachannel.svg new file mode 100644 index 000000000000..be7bf45d07ee --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/w3samples/alphachannel.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/wikimedia/Firefox_Logo_2017.svg b/third_party/packages/flutter_svg/example/assets/wikimedia/Firefox_Logo_2017.svg new file mode 100644 index 000000000000..87caae6a7913 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/wikimedia/Firefox_Logo_2017.svg @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + firefox-logo + + + + + + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/wikimedia/Flag_of_the_United_States.svg b/third_party/packages/flutter_svg/example/assets/wikimedia/Flag_of_the_United_States.svg new file mode 100644 index 000000000000..05de0d229a7d --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/wikimedia/Flag_of_the_United_States.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/assets/wikimedia/Ghostscript_Tiger.svg b/third_party/packages/flutter_svg/example/assets/wikimedia/Ghostscript_Tiger.svg new file mode 100644 index 000000000000..679edec2eb3f --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/wikimedia/Ghostscript_Tiger.svg @@ -0,0 +1,725 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/assets/wikimedia/chess_knight.svg b/third_party/packages/flutter_svg/example/assets/wikimedia/chess_knight.svg new file mode 100644 index 000000000000..72b429e0b060 --- /dev/null +++ b/third_party/packages/flutter_svg/example/assets/wikimedia/chess_knight.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/ios/.gitignore b/third_party/packages/flutter_svg/example/ios/.gitignore new file mode 100644 index 000000000000..79cc4da802e9 --- /dev/null +++ b/third_party/packages/flutter_svg/example/ios/.gitignore @@ -0,0 +1,45 @@ +.idea/ +.vagrant/ +.sconsign.dblite +.svn/ + +.DS_Store +*.swp +profile + +DerivedData/ +build/ +GeneratedPluginRegistrant.h +GeneratedPluginRegistrant.m + +.generated/ + +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 + +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 + +xcuserdata + +*.moved-aside + +*.pyc +*sync/ +Icon? +.tags* + +/Flutter/app.flx +/Flutter/app.zip +/Flutter/flutter_assets/ +/Flutter/App.framework +/Flutter/Flutter.framework +/Flutter/Generated.xcconfig +/ServiceDefinitions.json + +Pods/ +.symlinks/ diff --git a/third_party/packages/flutter_svg/example/ios/Flutter/AppFrameworkInfo.plist b/third_party/packages/flutter_svg/example/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 000000000000..9367d483e44e --- /dev/null +++ b/third_party/packages/flutter_svg/example/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/third_party/packages/flutter_svg/example/ios/Flutter/Debug.xcconfig b/third_party/packages/flutter_svg/example/ios/Flutter/Debug.xcconfig new file mode 100644 index 000000000000..592ceee85b89 --- /dev/null +++ b/third_party/packages/flutter_svg/example/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/third_party/packages/flutter_svg/example/ios/Flutter/Release.xcconfig b/third_party/packages/flutter_svg/example/ios/Flutter/Release.xcconfig new file mode 100644 index 000000000000..592ceee85b89 --- /dev/null +++ b/third_party/packages/flutter_svg/example/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/project.pbxproj b/third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 000000000000..790b4027d54b --- /dev/null +++ b/third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,493 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + DevelopmentTeam = S8QB4VV633; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 24247ED7217E8F7400BE4BD8 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 24247ED8217E8F7400BE4BD8 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.fluttersvgexample; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.fluttersvgexample; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.fluttersvgexample; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 24247ED7217E8F7400BE4BD8 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 24247ED8217E8F7400BE4BD8 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000000..1d526a16ed0f --- /dev/null +++ b/third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000000..18d981003d68 --- /dev/null +++ b/third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 000000000000..f9b0d7c5ea15 --- /dev/null +++ b/third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 000000000000..1263ac84b105 --- /dev/null +++ b/third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/third_party/packages/flutter_svg/example/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000000..1d526a16ed0f --- /dev/null +++ b/third_party/packages/flutter_svg/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/third_party/packages/flutter_svg/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/third_party/packages/flutter_svg/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000000..18d981003d68 --- /dev/null +++ b/third_party/packages/flutter_svg/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/third_party/packages/flutter_svg/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/third_party/packages/flutter_svg/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 000000000000..f9b0d7c5ea15 --- /dev/null +++ b/third_party/packages/flutter_svg/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/third_party/packages/flutter_svg/example/ios/Runner/AppDelegate.h b/third_party/packages/flutter_svg/example/ios/Runner/AppDelegate.h new file mode 100644 index 000000000000..36e21bbf9cf4 --- /dev/null +++ b/third_party/packages/flutter_svg/example/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/third_party/packages/flutter_svg/example/ios/Runner/AppDelegate.m b/third_party/packages/flutter_svg/example/ios/Runner/AppDelegate.m new file mode 100644 index 000000000000..59a72e90be12 --- /dev/null +++ b/third_party/packages/flutter_svg/example/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/third_party/packages/flutter_svg/example/ios/Runner/AppDelegate.swift b/third_party/packages/flutter_svg/example/ios/Runner/AppDelegate.swift new file mode 100644 index 000000000000..9074fee9290d --- /dev/null +++ b/third_party/packages/flutter_svg/example/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import Flutter +import UIKit + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000000..d36b1fab2d9d --- /dev/null +++ b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 000000000000..3d43d11e66f4 Binary files /dev/null and b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 000000000000..28c6bf03016f Binary files /dev/null and b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 000000000000..2ccbfd967d96 Binary files /dev/null and b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 000000000000..f091b6b0bca8 Binary files /dev/null and b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 000000000000..4cde12118dda Binary files /dev/null and b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 000000000000..d0ef06e7edb8 Binary files /dev/null and b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 000000000000..dcdc2306c285 Binary files /dev/null and b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 000000000000..2ccbfd967d96 Binary files /dev/null and b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 000000000000..c8f9ed8f5cee Binary files /dev/null and b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 000000000000..a6d6b8609df0 Binary files /dev/null and b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 000000000000..a6d6b8609df0 Binary files /dev/null and b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 000000000000..75b2d164a5a9 Binary files /dev/null and b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 000000000000..c4df70d39da7 Binary files /dev/null and b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 000000000000..6a84f41e14e2 Binary files /dev/null and b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 000000000000..d0e1f5853602 Binary files /dev/null and b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 000000000000..0bedcf2fd467 --- /dev/null +++ b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 000000000000..9da19eacad3b Binary files /dev/null and b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 000000000000..9da19eacad3b Binary files /dev/null and b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 000000000000..9da19eacad3b Binary files /dev/null and b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 000000000000..89c2725b70f1 --- /dev/null +++ b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/third_party/packages/flutter_svg/example/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 000000000000..f2e259c7c939 --- /dev/null +++ b/third_party/packages/flutter_svg/example/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Base.lproj/Main.storyboard b/third_party/packages/flutter_svg/example/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 000000000000..f3c28516fb38 --- /dev/null +++ b/third_party/packages/flutter_svg/example/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Info.plist b/third_party/packages/flutter_svg/example/ios/Runner/Info.plist new file mode 100644 index 000000000000..0513117f1d0b --- /dev/null +++ b/third_party/packages/flutter_svg/example/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + example + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/third_party/packages/flutter_svg/example/ios/Runner/Runner-Bridging-Header.h b/third_party/packages/flutter_svg/example/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 000000000000..7335fdf9000c --- /dev/null +++ b/third_party/packages/flutter_svg/example/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" \ No newline at end of file diff --git a/third_party/packages/flutter_svg/example/ios/Runner/main.m b/third_party/packages/flutter_svg/example/ios/Runner/main.m new file mode 100644 index 000000000000..31030600ecf9 --- /dev/null +++ b/third_party/packages/flutter_svg/example/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char *argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/third_party/packages/flutter_svg/example/lib/grid.dart b/third_party/packages/flutter_svg/example/lib/grid.dart new file mode 100644 index 000000000000..163893f50560 --- /dev/null +++ b/third_party/packages/flutter_svg/example/lib/grid.dart @@ -0,0 +1,163 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +const List _assetNames = [ + // 'assets/notfound.svg', // uncomment to test an asset that doesn't exist. + 'assets/flutter_logo.svg', + 'assets/dart.svg', + 'assets/simple/clip_path_3.svg', + 'assets/simple/clip_path_2.svg', + 'assets/simple/clip_path.svg', + 'assets/simple/fill-rule-inherit.svg', + 'assets/simple/group_fill_opacity.svg', + 'assets/simple/group_opacity.svg', + 'assets/simple/text.svg', + 'assets/simple/text_2.svg', + 'assets/simple/text_5.svg', + 'assets/simple/linear_gradient.svg', + 'assets/simple/linear_gradient_2.svg', + 'assets/simple/male.svg', + 'assets/simple/radial_gradient.svg', + 'assets/simple/rect_rrect.svg', + 'assets/simple/rect_rrect_no_ry.svg', + 'assets/simple/style_attr.svg', + 'assets/w3samples/aa.svg', + 'assets/w3samples/alphachannel.svg', + 'assets/simple/ellipse.svg', + 'assets/simple/dash_path.svg', + 'assets/simple/nested_group.svg', + 'assets/simple/stroke_inherit_circles.svg', + 'assets/simple/use_circles.svg', + 'assets/simple/use_opacity_grid.svg', + 'assets/wikimedia/chess_knight.svg', + 'assets/wikimedia/Ghostscript_Tiger.svg', + 'assets/wikimedia/Firefox_Logo_2017.svg', +]; + +/// Assets treated as "icons" - using a color filter to render differently. +const List iconNames = [ + 'assets/deborah_ufw/new-action-expander.svg', + 'assets/deborah_ufw/new-camera.svg', + 'assets/deborah_ufw/new-gif-button.svg', + 'assets/deborah_ufw/new-gif.svg', + 'assets/deborah_ufw/new-image.svg', + 'assets/deborah_ufw/new-mention.svg', + 'assets/deborah_ufw/new-pause-button.svg', + 'assets/deborah_ufw/new-play-button.svg', + 'assets/deborah_ufw/new-send-circle.svg', + 'assets/deborah_ufw/numeric_25.svg', +]; + +/// Assets to test network access. +const List uriNames = [ + 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', + 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg', + 'https://upload.wikimedia.org/wikipedia/commons/b/b4/Chess_ndd45.svg', +]; + +void main() { + runApp(_MyApp()); +} + +class _MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: const _MyHomePage(title: 'Flutter SVG Demo'), + ); + } +} + +class _MyHomePage extends StatefulWidget { + const _MyHomePage({required this.title}); + final String title; + + @override + _MyHomePageState createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State<_MyHomePage> { + final List _painters = []; + late double _dimension; + + @override + void initState() { + super.initState(); + _dimension = 203.0; + for (final String assetName in _assetNames) { + _painters.add( + SvgPicture.asset(assetName), + ); + } + + for (int i = 0; i < iconNames.length; i++) { + _painters.add( + Directionality( + textDirection: TextDirection.ltr, + child: SvgPicture.asset( + iconNames[i], + colorFilter: ColorFilter.mode( + Colors.blueGrey[(i + 1) * 100] ?? Colors.blueGrey, + BlendMode.srcIn, + ), + matchTextDirection: true, + ), + ), + ); + } + + for (final String uriName in uriNames) { + _painters.add( + SvgPicture.network( + uriName, + placeholderBuilder: (BuildContext context) => Container( + padding: const EdgeInsets.all(30.0), + child: const CircularProgressIndicator(), + ), + ), + ); + } + // Shows an example of an SVG image that will fetch a raster image from a URL. + _painters.add(SvgPicture.string(''' + + +''')); + } + + @override + Widget build(BuildContext context) { + if (_dimension > MediaQuery.of(context).size.width - 10.0) { + _dimension = MediaQuery.of(context).size.width - 10.0; + } + return Scaffold( + appBar: AppBar( + title: Text(widget.title), + ), + body: Column(children: [ + Slider( + min: 5.0, + max: MediaQuery.of(context).size.width - 10.0, + value: _dimension, + onChanged: (double val) { + setState(() => _dimension = val); + }, + ), + Expanded( + child: GridView.extent( + // shrinkWrap: true, + maxCrossAxisExtent: _dimension, + padding: const EdgeInsets.all(4.0), + mainAxisSpacing: 4.0, + crossAxisSpacing: 4.0, + children: _painters.toList(), + ), + ), + ]), + ); + } +} diff --git a/third_party/packages/flutter_svg/example/lib/main.dart b/third_party/packages/flutter_svg/example/lib/main.dart new file mode 100644 index 000000000000..358ec07d3aa9 --- /dev/null +++ b/third_party/packages/flutter_svg/example/lib/main.dart @@ -0,0 +1,40 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +/// The SVG to display in the example. +const String svgString = ''' + + + + + + + + + + + + + + + + + + + + +'''; + +void main() { + runApp(MaterialApp( + home: Scaffold( + body: Center( + child: SvgPicture.string( + svgString, + width: 500, + height: 500, + ), + ), + ), + )); +} diff --git a/third_party/packages/flutter_svg/example/linux/.gitignore b/third_party/packages/flutter_svg/example/linux/.gitignore new file mode 100644 index 000000000000..d3896c98444f --- /dev/null +++ b/third_party/packages/flutter_svg/example/linux/.gitignore @@ -0,0 +1 @@ +flutter/ephemeral diff --git a/third_party/packages/flutter_svg/example/linux/CMakeLists.txt b/third_party/packages/flutter_svg/example/linux/CMakeLists.txt new file mode 100644 index 000000000000..ca1e5db9e8cd --- /dev/null +++ b/third_party/packages/flutter_svg/example/linux/CMakeLists.txt @@ -0,0 +1,107 @@ +cmake_minimum_required(VERSION 3.10) +project(runner LANGUAGES CXX) + +set(BINARY_NAME "example") +set(APPLICATION_ID "io.flutter.plugins.fluttersvgexample") + +cmake_policy(SET CMP0063 NEW) + +set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") + +# Configure build options. +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") +endif() + +# Compilation settings that should be applied to most targets. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_14) + target_compile_options(${TARGET} PRIVATE -Wall -Werror) + target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") + target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") +endfunction() + +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") + +# Flutter library and tool build rules. +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) + +add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") + +# Application build +add_executable(${BINARY_NAME} + "main.cc" + "my_application.cc" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" +) +apply_standard_settings(${BINARY_NAME}) +target_link_libraries(${BINARY_NAME} PRIVATE flutter) +target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) +add_dependencies(${BINARY_NAME} flutter_assemble) + +# Only the install-generated bundle's copy of the executable will launch +# correctly, since the resources must in the right relative locations. To avoid +# people trying to run the unbundled copy, put it in a subdirectory instead of +# the default top-level location. +set_target_properties(${BINARY_NAME} + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" +) + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + +# === Installation === +# By default, "installing" just makes a relocatable bundle in the build +# directory. +set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") + +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +# Start with a clean build bundle directory every time. +install(CODE " + file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") + " COMPONENT Runtime) + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +if(PLUGIN_BUNDLED_LIBRARIES) + install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") + install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() diff --git a/third_party/packages/flutter_svg/example/linux/flutter/CMakeLists.txt b/third_party/packages/flutter_svg/example/linux/flutter/CMakeLists.txt new file mode 100644 index 000000000000..a1da1b9e5320 --- /dev/null +++ b/third_party/packages/flutter_svg/example/linux/flutter/CMakeLists.txt @@ -0,0 +1,91 @@ +cmake_minimum_required(VERSION 3.10) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. + +# Serves the same purpose as list(TRANSFORM ... PREPEND ...), +# which isn't available in 3.10. +function(list_prepend LIST_NAME PREFIX) + set(NEW_LIST "") + foreach(element ${${LIST_NAME}}) + list(APPEND NEW_LIST "${PREFIX}${element}") + endforeach(element) + set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) +endfunction() + +# === Flutter Library === +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) +pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) +pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) +pkg_check_modules(BLKID REQUIRED IMPORTED_TARGET blkid) +pkg_check_modules(LZMA REQUIRED IMPORTED_TARGET liblzma) + +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "fl_basic_message_channel.h" + "fl_binary_codec.h" + "fl_binary_messenger.h" + "fl_dart_project.h" + "fl_engine.h" + "fl_json_message_codec.h" + "fl_json_method_codec.h" + "fl_message_codec.h" + "fl_method_call.h" + "fl_method_channel.h" + "fl_method_codec.h" + "fl_method_response.h" + "fl_plugin_registrar.h" + "fl_plugin_registry.h" + "fl_standard_message_codec.h" + "fl_standard_method_codec.h" + "fl_string_codec.h" + "fl_value.h" + "fl_view.h" + "flutter_linux.h" +) +list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") +target_link_libraries(flutter INTERFACE + PkgConfig::GTK + PkgConfig::GLIB + PkgConfig::GIO + PkgConfig::BLKID + PkgConfig::LZMA +) +add_dependencies(flutter flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CMAKE_CURRENT_BINARY_DIR}/_phony_ + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" + linux-x64 ${CMAKE_BUILD_TYPE} + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} +) diff --git a/third_party/packages/flutter_svg/example/linux/flutter/generated_plugins.cmake b/third_party/packages/flutter_svg/example/linux/flutter/generated_plugins.cmake new file mode 100644 index 000000000000..2e1de87a7eb6 --- /dev/null +++ b/third_party/packages/flutter_svg/example/linux/flutter/generated_plugins.cmake @@ -0,0 +1,23 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/third_party/packages/flutter_svg/example/linux/main.cc b/third_party/packages/flutter_svg/example/linux/main.cc new file mode 100644 index 000000000000..e7c5c5437037 --- /dev/null +++ b/third_party/packages/flutter_svg/example/linux/main.cc @@ -0,0 +1,6 @@ +#include "my_application.h" + +int main(int argc, char** argv) { + g_autoptr(MyApplication) app = my_application_new(); + return g_application_run(G_APPLICATION(app), argc, argv); +} diff --git a/third_party/packages/flutter_svg/example/linux/my_application.cc b/third_party/packages/flutter_svg/example/linux/my_application.cc new file mode 100644 index 000000000000..0413c783293a --- /dev/null +++ b/third_party/packages/flutter_svg/example/linux/my_application.cc @@ -0,0 +1,107 @@ +#include "my_application.h" + +#include +#ifdef GDK_WINDOWING_X11 +#include +#endif + +#include "flutter/generated_plugin_registrant.h" + +struct _MyApplication { + GtkApplication parent_instance; + char** dart_entrypoint_arguments; +}; + +G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) + +// Implements GApplication::activate. +static void my_application_activate(GApplication* application) { + MyApplication* self = MY_APPLICATION(application); + GtkWindow* window = + GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); + + // Use a header bar when running in GNOME as this is the common style used + // by applications and is the setup most users will be using (e.g. Ubuntu + // desktop). + // If running on X and not using GNOME then just use a traditional title bar + // in case the window manager does more exotic layout, e.g. tiling. + // If running on Wayland assume the header bar will work (may need changing + // if future cases occur). + gboolean use_header_bar = TRUE; +#ifdef GDK_WINDOWING_X11 + GdkScreen* screen = gtk_window_get_screen(window); + if (GDK_IS_X11_SCREEN(screen)) { + const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); + if (g_strcmp0(wm_name, "GNOME Shell") != 0) { + use_header_bar = FALSE; + } + } +#endif + if (use_header_bar) { + GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); + gtk_widget_show(GTK_WIDGET(header_bar)); + gtk_header_bar_set_title(header_bar, "example"); + gtk_header_bar_set_show_close_button(header_bar, TRUE); + gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); + } else { + gtk_window_set_title(window, "example"); + } + + gtk_window_set_default_size(window, 1280, 720); + gtk_widget_show(GTK_WIDGET(window)); + + g_autoptr(FlDartProject) project = fl_dart_project_new(); + fl_dart_project_set_dart_entrypoint_arguments( + project, self->dart_entrypoint_arguments); + + FlView* view = fl_view_new(project); + gtk_widget_show(GTK_WIDGET(view)); + gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); + + fl_register_plugins(FL_PLUGIN_REGISTRY(view)); + + gtk_widget_grab_focus(GTK_WIDGET(view)); +} + +// Implements GApplication::local_command_line. +static gboolean my_application_local_command_line(GApplication* application, + gchar*** arguments, + int* exit_status) { + MyApplication* self = MY_APPLICATION(application); + // Strip out the first argument as it is the binary name. + self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); + + g_autoptr(GError) error = nullptr; + if (!g_application_register(application, nullptr, &error)) { + g_warning("Failed to register: %s", error->message); + *exit_status = 1; + return TRUE; + } + + g_application_activate(application); + *exit_status = 0; + + return TRUE; +} + +// Implements GObject::dispose. +static void my_application_dispose(GObject* object) { + MyApplication* self = MY_APPLICATION(object); + g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); + G_OBJECT_CLASS(my_application_parent_class)->dispose(object); +} + +static void my_application_class_init(MyApplicationClass* klass) { + G_APPLICATION_CLASS(klass)->activate = my_application_activate; + G_APPLICATION_CLASS(klass)->local_command_line = + my_application_local_command_line; + G_OBJECT_CLASS(klass)->dispose = my_application_dispose; +} + +static void my_application_init(MyApplication* self) {} + +MyApplication* my_application_new() { + return MY_APPLICATION(g_object_new(my_application_get_type(), + "application-id", APPLICATION_ID, "flags", + G_APPLICATION_NON_UNIQUE, nullptr)); +} diff --git a/third_party/packages/flutter_svg/example/linux/my_application.h b/third_party/packages/flutter_svg/example/linux/my_application.h new file mode 100644 index 000000000000..72271d5e4170 --- /dev/null +++ b/third_party/packages/flutter_svg/example/linux/my_application.h @@ -0,0 +1,18 @@ +#ifndef FLUTTER_MY_APPLICATION_H_ +#define FLUTTER_MY_APPLICATION_H_ + +#include + +G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, + GtkApplication) + +/** + * my_application_new: + * + * Creates a new Flutter-based application. + * + * Returns: a new #MyApplication. + */ +MyApplication* my_application_new(); + +#endif // FLUTTER_MY_APPLICATION_H_ diff --git a/third_party/packages/flutter_svg/example/macos/.gitignore b/third_party/packages/flutter_svg/example/macos/.gitignore new file mode 100644 index 000000000000..746adbb6b9e1 --- /dev/null +++ b/third_party/packages/flutter_svg/example/macos/.gitignore @@ -0,0 +1,7 @@ +# Flutter-related +**/Flutter/ephemeral/ +**/Pods/ + +# Xcode-related +**/dgph +**/xcuserdata/ diff --git a/third_party/packages/flutter_svg/example/macos/Flutter/Flutter-Debug.xcconfig b/third_party/packages/flutter_svg/example/macos/Flutter/Flutter-Debug.xcconfig new file mode 100644 index 000000000000..c2efd0b608ba --- /dev/null +++ b/third_party/packages/flutter_svg/example/macos/Flutter/Flutter-Debug.xcconfig @@ -0,0 +1 @@ +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/third_party/packages/flutter_svg/example/macos/Flutter/Flutter-Release.xcconfig b/third_party/packages/flutter_svg/example/macos/Flutter/Flutter-Release.xcconfig new file mode 100644 index 000000000000..c2efd0b608ba --- /dev/null +++ b/third_party/packages/flutter_svg/example/macos/Flutter/Flutter-Release.xcconfig @@ -0,0 +1 @@ +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/third_party/packages/flutter_svg/example/macos/Runner.xcodeproj/project.pbxproj b/third_party/packages/flutter_svg/example/macos/Runner.xcodeproj/project.pbxproj new file mode 100644 index 000000000000..d9333e4704c4 --- /dev/null +++ b/third_party/packages/flutter_svg/example/macos/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,573 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXAggregateTarget section */ + 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; + buildPhases = ( + 33CC111E2044C6BF0003C045 /* ShellScript */, + ); + dependencies = ( + ); + name = "Flutter Assemble"; + productName = FLX; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC111A2044C6BA0003C045; + remoteInfo = FLX; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 33CC110E2044A8840003C045 /* Bundle Framework */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Bundle Framework"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; + 33CC10ED2044A3C60003C045 /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "example.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; + 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; + 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; + 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; + 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 33CC10EA2044A3C60003C045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 33BA886A226E78AF003329D5 /* Configs */ = { + isa = PBXGroup; + children = ( + 33E5194F232828860026EE4D /* AppInfo.xcconfig */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, + ); + path = Configs; + sourceTree = ""; + }; + 33CC10E42044A3C60003C045 = { + isa = PBXGroup; + children = ( + 33FAB671232836740065AC1E /* Runner */, + 33CEB47122A05771004F2AC0 /* Flutter */, + 33CC10EE2044A3C60003C045 /* Products */, + D73912EC22F37F3D000D13A0 /* Frameworks */, + ); + sourceTree = ""; + }; + 33CC10EE2044A3C60003C045 /* Products */ = { + isa = PBXGroup; + children = ( + 33CC10ED2044A3C60003C045 /* example.app */, + ); + name = Products; + sourceTree = ""; + }; + 33CC11242044D66E0003C045 /* Resources */ = { + isa = PBXGroup; + children = ( + 33CC10F22044A3C60003C045 /* Assets.xcassets */, + 33CC10F42044A3C60003C045 /* MainMenu.xib */, + 33CC10F72044A3C60003C045 /* Info.plist */, + ); + name = Resources; + path = ..; + sourceTree = ""; + }; + 33CEB47122A05771004F2AC0 /* Flutter */ = { + isa = PBXGroup; + children = ( + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, + ); + path = Flutter; + sourceTree = ""; + }; + 33FAB671232836740065AC1E /* Runner */ = { + isa = PBXGroup; + children = ( + 33CC10F02044A3C60003C045 /* AppDelegate.swift */, + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, + 33E51913231747F40026EE4D /* DebugProfile.entitlements */, + 33E51914231749380026EE4D /* Release.entitlements */, + 33CC11242044D66E0003C045 /* Resources */, + 33BA886A226E78AF003329D5 /* Configs */, + ); + path = Runner; + sourceTree = ""; + }; + D73912EC22F37F3D000D13A0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 33CC10EC2044A3C60003C045 /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 33CC10E92044A3C60003C045 /* Sources */, + 33CC10EA2044A3C60003C045 /* Frameworks */, + 33CC10EB2044A3C60003C045 /* Resources */, + 33CC110E2044A8840003C045 /* Bundle Framework */, + 3399D490228B24CF009A79C7 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + 33CC11202044C79F0003C045 /* PBXTargetDependency */, + ); + name = Runner; + productName = Runner; + productReference = 33CC10ED2044A3C60003C045 /* example.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 33CC10E52044A3C60003C045 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 1300; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 33CC10EC2044A3C60003C045 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1100; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 1; + }; + }; + }; + 33CC111A2044C6BA0003C045 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Manual; + }; + }; + }; + buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 33CC10E42044A3C60003C045; + productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 33CC10EC2044A3C60003C045 /* Runner */, + 33CC111A2044C6BA0003C045 /* Flutter Assemble */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 33CC10EB2044A3C60003C045 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3399D490228B24CF009A79C7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; + }; + 33CC111E2044C6BF0003C045 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + Flutter/ephemeral/FlutterInputs.xcfilelist, + ); + inputPaths = ( + Flutter/ephemeral/tripwire, + ); + outputFileListPaths = ( + Flutter/ephemeral/FlutterOutputs.xcfilelist, + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 33CC10E92044A3C60003C045 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; + targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 33CC10F52044A3C60003C045 /* Base */, + ); + name = MainMenu.xib; + path = Runner; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 338D0CE9231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.14; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Profile; + }; + 338D0CEA231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Profile; + }; + 338D0CEB231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Profile; + }; + 33CC10F92044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.14; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 33CC10FA2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.14; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 33CC10FC2044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 33CC10FD2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 33CC111C2044C6BA0003C045 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 33CC111D2044C6BA0003C045 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10F92044A3C60003C045 /* Debug */, + 33CC10FA2044A3C60003C045 /* Release */, + 338D0CE9231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10FC2044A3C60003C045 /* Debug */, + 33CC10FD2044A3C60003C045 /* Release */, + 338D0CEA231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC111C2044C6BA0003C045 /* Debug */, + 33CC111D2044C6BA0003C045 /* Release */, + 338D0CEB231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 33CC10E52044A3C60003C045 /* Project object */; +} diff --git a/third_party/packages/flutter_svg/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/third_party/packages/flutter_svg/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000000..18d981003d68 --- /dev/null +++ b/third_party/packages/flutter_svg/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/third_party/packages/flutter_svg/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/third_party/packages/flutter_svg/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 000000000000..fb7259e17785 --- /dev/null +++ b/third_party/packages/flutter_svg/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/third_party/packages/flutter_svg/example/macos/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000000..1d526a16ed0f --- /dev/null +++ b/third_party/packages/flutter_svg/example/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/third_party/packages/flutter_svg/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/third_party/packages/flutter_svg/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000000..18d981003d68 --- /dev/null +++ b/third_party/packages/flutter_svg/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/third_party/packages/flutter_svg/example/macos/Runner/AppDelegate.swift b/third_party/packages/flutter_svg/example/macos/Runner/AppDelegate.swift new file mode 100644 index 000000000000..d53ef6437726 --- /dev/null +++ b/third_party/packages/flutter_svg/example/macos/Runner/AppDelegate.swift @@ -0,0 +1,9 @@ +import Cocoa +import FlutterMacOS + +@NSApplicationMain +class AppDelegate: FlutterAppDelegate { + override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } +} diff --git a/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000000..a2ec33f19f11 --- /dev/null +++ b/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_16.png", + "scale" : "1x" + }, + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "2x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "1x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_64.png", + "scale" : "2x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_128.png", + "scale" : "1x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "2x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_1024.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png new file mode 100644 index 000000000000..82b6f9d9a33e Binary files /dev/null and b/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ diff --git a/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png new file mode 100644 index 000000000000..13b35eba55c6 Binary files /dev/null and b/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png new file mode 100644 index 000000000000..0a3f5fa40fb3 Binary files /dev/null and b/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ diff --git a/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png new file mode 100644 index 000000000000..bdb57226d5f2 Binary files /dev/null and b/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png new file mode 100644 index 000000000000..f083318e09ca Binary files /dev/null and b/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ diff --git a/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png new file mode 100644 index 000000000000..326c0e72c9d8 Binary files /dev/null and b/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png new file mode 100644 index 000000000000..2f1632cfddf3 Binary files /dev/null and b/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/third_party/packages/flutter_svg/example/macos/Runner/Base.lproj/MainMenu.xib b/third_party/packages/flutter_svg/example/macos/Runner/Base.lproj/MainMenu.xib new file mode 100644 index 000000000000..80e867a4e06b --- /dev/null +++ b/third_party/packages/flutter_svg/example/macos/Runner/Base.lproj/MainMenu.xib @@ -0,0 +1,343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/macos/Runner/Configs/AppInfo.xcconfig b/third_party/packages/flutter_svg/example/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 000000000000..960a68fd8688 --- /dev/null +++ b/third_party/packages/flutter_svg/example/macos/Runner/Configs/AppInfo.xcconfig @@ -0,0 +1,14 @@ +// Application-level settings for the Runner target. +// +// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the +// future. If not, the values below would default to using the project name when this becomes a +// 'flutter create' template. + +// The application's name. By default this is also the title of the Flutter window. +PRODUCT_NAME = example + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.fluttersvgexample + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2022 com.example. All rights reserved. diff --git a/third_party/packages/flutter_svg/example/macos/Runner/Configs/Debug.xcconfig b/third_party/packages/flutter_svg/example/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 000000000000..36b0fd9464f4 --- /dev/null +++ b/third_party/packages/flutter_svg/example/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/third_party/packages/flutter_svg/example/macos/Runner/Configs/Release.xcconfig b/third_party/packages/flutter_svg/example/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 000000000000..dff4f49561c8 --- /dev/null +++ b/third_party/packages/flutter_svg/example/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/third_party/packages/flutter_svg/example/macos/Runner/Configs/Warnings.xcconfig b/third_party/packages/flutter_svg/example/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 000000000000..42bcbf4780b1 --- /dev/null +++ b/third_party/packages/flutter_svg/example/macos/Runner/Configs/Warnings.xcconfig @@ -0,0 +1,13 @@ +WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings +GCC_WARN_UNDECLARED_SELECTOR = YES +CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES +CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_PRAGMA_PACK = YES +CLANG_WARN_STRICT_PROTOTYPES = YES +CLANG_WARN_COMMA = YES +GCC_WARN_STRICT_SELECTOR_MATCH = YES +CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES +GCC_WARN_SHADOW = YES +CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/third_party/packages/flutter_svg/example/macos/Runner/DebugProfile.entitlements b/third_party/packages/flutter_svg/example/macos/Runner/DebugProfile.entitlements new file mode 100644 index 000000000000..dddb8a30c851 --- /dev/null +++ b/third_party/packages/flutter_svg/example/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,12 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.cs.allow-jit + + com.apple.security.network.server + + + diff --git a/third_party/packages/flutter_svg/example/macos/Runner/Info.plist b/third_party/packages/flutter_svg/example/macos/Runner/Info.plist new file mode 100644 index 000000000000..4789daa6a443 --- /dev/null +++ b/third_party/packages/flutter_svg/example/macos/Runner/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + $(PRODUCT_COPYRIGHT) + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/third_party/packages/flutter_svg/example/macos/Runner/MainFlutterWindow.swift b/third_party/packages/flutter_svg/example/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 000000000000..2722837ec918 --- /dev/null +++ b/third_party/packages/flutter_svg/example/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,15 @@ +import Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController.init() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + + super.awakeFromNib() + } +} diff --git a/third_party/packages/flutter_svg/example/macos/Runner/Release.entitlements b/third_party/packages/flutter_svg/example/macos/Runner/Release.entitlements new file mode 100644 index 000000000000..852fa1a4728a --- /dev/null +++ b/third_party/packages/flutter_svg/example/macos/Runner/Release.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.app-sandbox + + + diff --git a/third_party/packages/flutter_svg/example/pubspec.yaml b/third_party/packages/flutter_svg/example/pubspec.yaml new file mode 100644 index 000000000000..65f4afd93998 --- /dev/null +++ b/third_party/packages/flutter_svg/example/pubspec.yaml @@ -0,0 +1,27 @@ +name: flutter_svg_example +description: An SVG samnple app. +publish_to: none + +environment: + sdk: ^3.4.0 + flutter: ">=3.22.0" + +dependencies: + flutter: + sdk: flutter + flutter_driver: + sdk: flutter + flutter_svg: + path: ../ + +# The following section is specific to Flutter. +flutter: + uses-material-design: true + + assets: + - assets/ + - assets/w3samples/ + - assets/deborah_ufw/ + - assets/simple/ + - assets/wikimedia/ + - assets/android_vd/ diff --git a/third_party/packages/flutter_svg/example/test_driver/bench.dart b/third_party/packages/flutter_svg/example/test_driver/bench.dart new file mode 100644 index 000000000000..7854092ac4a9 --- /dev/null +++ b/third_party/packages/flutter_svg/example/test_driver/bench.dart @@ -0,0 +1,7 @@ +import 'package:flutter_driver/driver_extension.dart'; +import 'package:flutter_svg_example/main.dart' as app; + +void main() { + enableFlutterDriverExtension(); + app.main(); +} diff --git a/third_party/packages/flutter_svg/example/test_driver/bench_test.dart b/third_party/packages/flutter_svg/example/test_driver/bench_test.dart new file mode 100644 index 000000000000..b23125b7fff9 --- /dev/null +++ b/third_party/packages/flutter_svg/example/test_driver/bench_test.dart @@ -0,0 +1,28 @@ +import 'package:flutter_driver/flutter_driver.dart'; + +Future main() async { + final SerializableFinder view = find.byType('GridView'); + + final FlutterDriver driver = await FlutterDriver.connect(); + try { + await driver.waitUntilFirstFrameRasterized(); + await Future.delayed(const Duration(milliseconds: 1000)); + await driver.forceGC(); + await driver.clearTimeline(); + await Future.delayed(const Duration(milliseconds: 1000)); + + final Timeline timeline = await driver.traceAction(() async { + await driver.scroll( + view, + 0, + -3400, + const Duration(seconds: 10), + timeout: const Duration(seconds: 15), + ); + }); + final TimelineSummary summary = TimelineSummary.summarize(timeline); + await summary.writeTimelineToFile('bench', pretty: true); + } finally { + await driver.close(); + } +} diff --git a/third_party/packages/flutter_svg/example/test_driver/repaint.dart b/third_party/packages/flutter_svg/example/test_driver/repaint.dart new file mode 100644 index 000000000000..45891f37b476 --- /dev/null +++ b/third_party/packages/flutter_svg/example/test_driver/repaint.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_driver/driver_extension.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +void main() { + enableFlutterDriverExtension(); + runApp( + Directionality( + textDirection: TextDirection.ltr, + child: Stack( + alignment: Alignment.center, + children: [ + SvgPicture.asset('assets/wikimedia/Ghostscript_Tiger.svg'), + const CircularProgressIndicator(), + ], + ), + ), + ); +} diff --git a/third_party/packages/flutter_svg/example/test_driver/repaint_test.dart b/third_party/packages/flutter_svg/example/test_driver/repaint_test.dart new file mode 100644 index 000000000000..99bc518ef313 --- /dev/null +++ b/third_party/packages/flutter_svg/example/test_driver/repaint_test.dart @@ -0,0 +1,21 @@ +import 'package:flutter_driver/flutter_driver.dart'; + +Future main() async { + final FlutterDriver driver = await FlutterDriver.connect(); + try { + await driver.waitUntilFirstFrameRasterized(); + await Future.delayed(const Duration(milliseconds: 1000)); + await driver.forceGC(); + await driver.clearTimeline(); + await Future.delayed(const Duration(milliseconds: 1000)); + + final Timeline timeline = await driver.traceAction(() async { + // animate + await Future.delayed(const Duration(seconds: 10)); + }); + final TimelineSummary summary = TimelineSummary.summarize(timeline); + await summary.writeTimelineToFile('repaint', pretty: true); + } finally { + await driver.close(); + } +} diff --git a/third_party/packages/flutter_svg/example/web/favicon.png b/third_party/packages/flutter_svg/example/web/favicon.png new file mode 100644 index 000000000000..8aaa46ac1ae2 Binary files /dev/null and b/third_party/packages/flutter_svg/example/web/favicon.png differ diff --git a/third_party/packages/flutter_svg/example/web/icons/Icon-192.png b/third_party/packages/flutter_svg/example/web/icons/Icon-192.png new file mode 100644 index 000000000000..b749bfef0747 Binary files /dev/null and b/third_party/packages/flutter_svg/example/web/icons/Icon-192.png differ diff --git a/third_party/packages/flutter_svg/example/web/icons/Icon-512.png b/third_party/packages/flutter_svg/example/web/icons/Icon-512.png new file mode 100644 index 000000000000..88cfd48dff11 Binary files /dev/null and b/third_party/packages/flutter_svg/example/web/icons/Icon-512.png differ diff --git a/third_party/packages/flutter_svg/example/web/icons/Icon-maskable-192.png b/third_party/packages/flutter_svg/example/web/icons/Icon-maskable-192.png new file mode 100644 index 000000000000..eb9b4d76e525 Binary files /dev/null and b/third_party/packages/flutter_svg/example/web/icons/Icon-maskable-192.png differ diff --git a/third_party/packages/flutter_svg/example/web/icons/Icon-maskable-512.png b/third_party/packages/flutter_svg/example/web/icons/Icon-maskable-512.png new file mode 100644 index 000000000000..d69c56691fbd Binary files /dev/null and b/third_party/packages/flutter_svg/example/web/icons/Icon-maskable-512.png differ diff --git a/third_party/packages/flutter_svg/example/web/index.html b/third_party/packages/flutter_svg/example/web/index.html new file mode 100644 index 000000000000..9b7a438f823a --- /dev/null +++ b/third_party/packages/flutter_svg/example/web/index.html @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + example + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/web/manifest.json b/third_party/packages/flutter_svg/example/web/manifest.json new file mode 100644 index 000000000000..c63800102369 --- /dev/null +++ b/third_party/packages/flutter_svg/example/web/manifest.json @@ -0,0 +1,23 @@ +{ + "name": "example", + "short_name": "example", + "start_url": ".", + "display": "minimal-ui", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + } + ] +} diff --git a/third_party/packages/flutter_svg/example/windows/.gitignore b/third_party/packages/flutter_svg/example/windows/.gitignore new file mode 100644 index 000000000000..d492d0d98c8f --- /dev/null +++ b/third_party/packages/flutter_svg/example/windows/.gitignore @@ -0,0 +1,17 @@ +flutter/ephemeral/ + +# Visual Studio user-specific files. +*.suo +*.user +*.userosscache +*.sln.docstates + +# Visual Studio build-related files. +x64/ +x86/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ diff --git a/third_party/packages/flutter_svg/example/windows/CMakeLists.txt b/third_party/packages/flutter_svg/example/windows/CMakeLists.txt new file mode 100644 index 000000000000..abf90408efb4 --- /dev/null +++ b/third_party/packages/flutter_svg/example/windows/CMakeLists.txt @@ -0,0 +1,95 @@ +cmake_minimum_required(VERSION 3.15) +project(example LANGUAGES CXX) + +set(BINARY_NAME "example") + +cmake_policy(SET CMP0063 NEW) + +set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") + +# Configure build options. +get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(IS_MULTICONFIG) + set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" + CACHE STRING "" FORCE) +else() + if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") + endif() +endif() + +set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") +set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") +set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") +set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") + +# Use Unicode for all projects. +add_definitions(-DUNICODE -D_UNICODE) + +# Compilation settings that should be applied to most targets. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_17) + target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") + target_compile_options(${TARGET} PRIVATE /EHsc) + target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") + target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") +endfunction() + +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") + +# Flutter library and tool build rules. +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# Application build +add_subdirectory("runner") + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# Support files are copied into place next to the executable, so that it can +# run in place. This is done instead of making a separate bundle (as on Linux) +# so that building and running from within Visual Studio will work. +set(BUILD_BUNDLE_DIR "$") +# Make the "install" step default, as it's required to run. +set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +if(PLUGIN_BUNDLED_LIBRARIES) + install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + CONFIGURATIONS Profile;Release + COMPONENT Runtime) diff --git a/third_party/packages/flutter_svg/example/windows/flutter/CMakeLists.txt b/third_party/packages/flutter_svg/example/windows/flutter/CMakeLists.txt new file mode 100644 index 000000000000..b02c5485c957 --- /dev/null +++ b/third_party/packages/flutter_svg/example/windows/flutter/CMakeLists.txt @@ -0,0 +1,103 @@ +cmake_minimum_required(VERSION 3.15) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. +set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") + +# === Flutter Library === +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "flutter_export.h" + "flutter_windows.h" + "flutter_messenger.h" + "flutter_plugin_registrar.h" + "flutter_texture_registrar.h" +) +list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") +add_dependencies(flutter flutter_assemble) + +# === Wrapper === +list(APPEND CPP_WRAPPER_SOURCES_CORE + "core_implementations.cc" + "standard_codec.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_PLUGIN + "plugin_registrar.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_APP + "flutter_engine.cc" + "flutter_view_controller.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") + +# Wrapper sources needed for a plugin. +add_library(flutter_wrapper_plugin STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} +) +apply_standard_settings(flutter_wrapper_plugin) +set_target_properties(flutter_wrapper_plugin PROPERTIES + POSITION_INDEPENDENT_CODE ON) +set_target_properties(flutter_wrapper_plugin PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) +target_include_directories(flutter_wrapper_plugin PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_plugin flutter_assemble) + +# Wrapper sources needed for the runner. +add_library(flutter_wrapper_app STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_APP} +) +apply_standard_settings(flutter_wrapper_app) +target_link_libraries(flutter_wrapper_app PUBLIC flutter) +target_include_directories(flutter_wrapper_app PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_app flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") +set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} + ${PHONY_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" + windows-x64 $ + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} +) diff --git a/third_party/packages/flutter_svg/example/windows/flutter/generated_plugins.cmake b/third_party/packages/flutter_svg/example/windows/flutter/generated_plugins.cmake new file mode 100644 index 000000000000..b93c4c30c167 --- /dev/null +++ b/third_party/packages/flutter_svg/example/windows/flutter/generated_plugins.cmake @@ -0,0 +1,23 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/third_party/packages/flutter_svg/example/windows/runner/CMakeLists.txt b/third_party/packages/flutter_svg/example/windows/runner/CMakeLists.txt new file mode 100644 index 000000000000..977e38b5d1d2 --- /dev/null +++ b/third_party/packages/flutter_svg/example/windows/runner/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.15) +project(runner LANGUAGES CXX) + +add_executable(${BINARY_NAME} WIN32 + "flutter_window.cpp" + "main.cpp" + "run_loop.cpp" + "utils.cpp" + "win32_window.cpp" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" + "Runner.rc" + "runner.exe.manifest" +) +apply_standard_settings(${BINARY_NAME}) +target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") +target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) +target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") +add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/third_party/packages/flutter_svg/example/windows/runner/Runner.rc b/third_party/packages/flutter_svg/example/windows/runner/Runner.rc new file mode 100644 index 000000000000..51812dcd4878 --- /dev/null +++ b/third_party/packages/flutter_svg/example/windows/runner/Runner.rc @@ -0,0 +1,121 @@ +// Microsoft Visual C++ generated resource script. +// +#pragma code_page(65001) +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_APP_ICON ICON "resources\\app_icon.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +#ifdef FLUTTER_BUILD_NUMBER +#define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER +#else +#define VERSION_AS_NUMBER 1,0,0 +#endif + +#ifdef FLUTTER_BUILD_NAME +#define VERSION_AS_STRING #FLUTTER_BUILD_NAME +#else +#define VERSION_AS_STRING "1.0.0" +#endif + +VS_VERSION_INFO VERSIONINFO + FILEVERSION VERSION_AS_NUMBER + PRODUCTVERSION VERSION_AS_NUMBER + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "com.example" "\0" + VALUE "FileDescription", "A new Flutter project." "\0" + VALUE "FileVersion", VERSION_AS_STRING "\0" + VALUE "InternalName", "example" "\0" + VALUE "LegalCopyright", "Copyright (C) 2021 com.example. All rights reserved." "\0" + VALUE "OriginalFilename", "example.exe" "\0" + VALUE "ProductName", "example" "\0" + VALUE "ProductVersion", VERSION_AS_STRING "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/third_party/packages/flutter_svg/example/windows/runner/flutter_window.cpp b/third_party/packages/flutter_svg/example/windows/runner/flutter_window.cpp new file mode 100644 index 000000000000..c422723045ca --- /dev/null +++ b/third_party/packages/flutter_svg/example/windows/runner/flutter_window.cpp @@ -0,0 +1,64 @@ +#include "flutter_window.h" + +#include + +#include "flutter/generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(RunLoop* run_loop, + const flutter::DartProject& project) + : run_loop_(run_loop), project_(project) {} + +FlutterWindow::~FlutterWindow() {} + +bool FlutterWindow::OnCreate() { + if (!Win32Window::OnCreate()) { + return false; + } + + RECT frame = GetClientArea(); + + // The size here must match the window dimensions to avoid unnecessary surface + // creation / destruction in the startup path. + flutter_controller_ = std::make_unique( + frame.right - frame.left, frame.bottom - frame.top, project_); + // Ensure that basic setup of the controller was successful. + if (!flutter_controller_->engine() || !flutter_controller_->view()) { + return false; + } + RegisterPlugins(flutter_controller_->engine()); + run_loop_->RegisterFlutterInstance(flutter_controller_->engine()); + SetChildContent(flutter_controller_->view()->GetNativeWindow()); + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_controller_) { + run_loop_->UnregisterFlutterInstance(flutter_controller_->engine()); + flutter_controller_ = nullptr; + } + + Win32Window::OnDestroy(); +} + +LRESULT +FlutterWindow::MessageHandler(HWND hwnd, UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + // Give Flutter, including plugins, an opporutunity to handle window messages. + if (flutter_controller_) { + std::optional result = + flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, + lparam); + if (result) { + return *result; + } + } + + switch (message) { + case WM_FONTCHANGE: + flutter_controller_->engine()->ReloadSystemFonts(); + break; + } + + return Win32Window::MessageHandler(hwnd, message, wparam, lparam); +} diff --git a/third_party/packages/flutter_svg/example/windows/runner/flutter_window.h b/third_party/packages/flutter_svg/example/windows/runner/flutter_window.h new file mode 100644 index 000000000000..b663ddd50125 --- /dev/null +++ b/third_party/packages/flutter_svg/example/windows/runner/flutter_window.h @@ -0,0 +1,39 @@ +#ifndef RUNNER_FLUTTER_WINDOW_H_ +#define RUNNER_FLUTTER_WINDOW_H_ + +#include +#include + +#include + +#include "run_loop.h" +#include "win32_window.h" + +// A window that does nothing but host a Flutter view. +class FlutterWindow : public Win32Window { + public: + // Creates a new FlutterWindow driven by the |run_loop|, hosting a + // Flutter view running |project|. + explicit FlutterWindow(RunLoop* run_loop, + const flutter::DartProject& project); + virtual ~FlutterWindow(); + + protected: + // Win32Window: + bool OnCreate() override; + void OnDestroy() override; + LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, + LPARAM const lparam) noexcept override; + + private: + // The run loop driving events for this window. + RunLoop* run_loop_; + + // The project to run. + flutter::DartProject project_; + + // The Flutter instance hosted by this window. + std::unique_ptr flutter_controller_; +}; + +#endif // RUNNER_FLUTTER_WINDOW_H_ diff --git a/third_party/packages/flutter_svg/example/windows/runner/main.cpp b/third_party/packages/flutter_svg/example/windows/runner/main.cpp new file mode 100644 index 000000000000..0d8a552154f3 --- /dev/null +++ b/third_party/packages/flutter_svg/example/windows/runner/main.cpp @@ -0,0 +1,41 @@ +#include +#include +#include + +#include "flutter_window.h" +#include "run_loop.h" +#include "utils.h" + +int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, + _In_ wchar_t* command_line, _In_ int show_command) { + // Attach to console when present (e.g., 'flutter run') or create a + // new console when running with a debugger. + if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { + CreateAndAttachConsole(); + } + + // Initialize COM, so that it is available for use in the library and/or + // plugins. + ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + + RunLoop run_loop; + + flutter::DartProject project(L"data"); + + std::vector command_line_arguments = GetCommandLineArguments(); + + project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + + FlutterWindow window(&run_loop, project); + Win32Window::Point origin(10, 10); + Win32Window::Size size(1280, 720); + if (!window.CreateAndShow(L"example", origin, size)) { + return EXIT_FAILURE; + } + window.SetQuitOnClose(true); + + run_loop.Run(); + + ::CoUninitialize(); + return EXIT_SUCCESS; +} diff --git a/third_party/packages/flutter_svg/example/windows/runner/resource.h b/third_party/packages/flutter_svg/example/windows/runner/resource.h new file mode 100644 index 000000000000..d5d958dc4257 --- /dev/null +++ b/third_party/packages/flutter_svg/example/windows/runner/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Runner.rc +// +#define IDI_APP_ICON 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/third_party/packages/flutter_svg/example/windows/runner/resources/app_icon.ico b/third_party/packages/flutter_svg/example/windows/runner/resources/app_icon.ico new file mode 100644 index 000000000000..c04e20caf637 Binary files /dev/null and b/third_party/packages/flutter_svg/example/windows/runner/resources/app_icon.ico differ diff --git a/third_party/packages/flutter_svg/example/windows/runner/run_loop.cpp b/third_party/packages/flutter_svg/example/windows/runner/run_loop.cpp new file mode 100644 index 000000000000..2d6636ab6bc6 --- /dev/null +++ b/third_party/packages/flutter_svg/example/windows/runner/run_loop.cpp @@ -0,0 +1,66 @@ +#include "run_loop.h" + +#include + +#include + +RunLoop::RunLoop() {} + +RunLoop::~RunLoop() {} + +void RunLoop::Run() { + bool keep_running = true; + TimePoint next_flutter_event_time = TimePoint::clock::now(); + while (keep_running) { + std::chrono::nanoseconds wait_duration = + std::max(std::chrono::nanoseconds(0), + next_flutter_event_time - TimePoint::clock::now()); + ::MsgWaitForMultipleObjects( + 0, nullptr, FALSE, static_cast(wait_duration.count() / 1000), + QS_ALLINPUT); + bool processed_events = false; + MSG message; + // All pending Windows messages must be processed; MsgWaitForMultipleObjects + // won't return again for items left in the queue after PeekMessage. + while (::PeekMessage(&message, nullptr, 0, 0, PM_REMOVE)) { + processed_events = true; + if (message.message == WM_QUIT) { + keep_running = false; + break; + } + ::TranslateMessage(&message); + ::DispatchMessage(&message); + // Allow Flutter to process messages each time a Windows message is + // processed, to prevent starvation. + next_flutter_event_time = + std::min(next_flutter_event_time, ProcessFlutterMessages()); + } + // If the PeekMessage loop didn't run, process Flutter messages. + if (!processed_events) { + next_flutter_event_time = + std::min(next_flutter_event_time, ProcessFlutterMessages()); + } + } +} + +void RunLoop::RegisterFlutterInstance( + flutter::FlutterEngine* flutter_instance) { + flutter_instances_.insert(flutter_instance); +} + +void RunLoop::UnregisterFlutterInstance( + flutter::FlutterEngine* flutter_instance) { + flutter_instances_.erase(flutter_instance); +} + +RunLoop::TimePoint RunLoop::ProcessFlutterMessages() { + TimePoint next_event_time = TimePoint::max(); + for (auto instance : flutter_instances_) { + std::chrono::nanoseconds wait_duration = instance->ProcessMessages(); + if (wait_duration != std::chrono::nanoseconds::max()) { + next_event_time = + std::min(next_event_time, TimePoint::clock::now() + wait_duration); + } + } + return next_event_time; +} diff --git a/third_party/packages/flutter_svg/example/windows/runner/run_loop.h b/third_party/packages/flutter_svg/example/windows/runner/run_loop.h new file mode 100644 index 000000000000..5f2c4a9ad7d3 --- /dev/null +++ b/third_party/packages/flutter_svg/example/windows/runner/run_loop.h @@ -0,0 +1,38 @@ +#ifndef RUNNER_RUN_LOOP_H_ +#define RUNNER_RUN_LOOP_H_ + +#include + +#include +#include + +// A runloop that will service events for Flutter instances as well +// as native messages. +class RunLoop { + public: + RunLoop(); + ~RunLoop(); + + // Prevent copying + RunLoop(RunLoop const&) = delete; + RunLoop& operator=(RunLoop const&) = delete; + + // Runs the run loop until the application quits. + void Run(); + + // Registers the given Flutter instance for event servicing. + void RegisterFlutterInstance(flutter::FlutterEngine* flutter_instance); + + // Unregisters the given Flutter instance from event servicing. + void UnregisterFlutterInstance(flutter::FlutterEngine* flutter_instance); + + private: + using TimePoint = std::chrono::steady_clock::time_point; + + // Processes all currently pending messages for registered Flutter instances. + TimePoint ProcessFlutterMessages(); + + std::set flutter_instances_; +}; + +#endif // RUNNER_RUN_LOOP_H_ diff --git a/third_party/packages/flutter_svg/example/windows/runner/runner.exe.manifest b/third_party/packages/flutter_svg/example/windows/runner/runner.exe.manifest new file mode 100644 index 000000000000..c977c4a42589 --- /dev/null +++ b/third_party/packages/flutter_svg/example/windows/runner/runner.exe.manifest @@ -0,0 +1,20 @@ + + + + + PerMonitorV2 + + + + + + + + + + + + + + + diff --git a/third_party/packages/flutter_svg/example/windows/runner/utils.cpp b/third_party/packages/flutter_svg/example/windows/runner/utils.cpp new file mode 100644 index 000000000000..afa363b236e3 --- /dev/null +++ b/third_party/packages/flutter_svg/example/windows/runner/utils.cpp @@ -0,0 +1,63 @@ +#include "utils.h" + +#include +#include +#include +#include + +#include + +void CreateAndAttachConsole() { + if (::AllocConsole()) { + FILE* unused; + if (freopen_s(&unused, "CONOUT$", "w", stdout)) { + _dup2(_fileno(stdout), 1); + } + if (freopen_s(&unused, "CONOUT$", "w", stderr)) { + _dup2(_fileno(stdout), 2); + } + std::ios::sync_with_stdio(); + FlutterDesktopResyncOutputStreams(); + } +} + +std::vector GetCommandLineArguments() { + // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. + int argc; + wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); + if (argv == nullptr) { + return std::vector(); + } + + std::vector command_line_arguments; + + // Skip the first argument as it's the binary name. + for (int i = 1; i < argc; i++) { + command_line_arguments.push_back(Utf8FromUtf16(argv[i])); + } + + ::LocalFree(argv); + + return command_line_arguments; +} + +std::string Utf8FromUtf16(const wchar_t* utf16_string) { + if (utf16_string == nullptr) { + return std::string(); + } + int target_length = + ::WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, -1, + nullptr, 0, nullptr, nullptr); + if (target_length == 0) { + return std::string(); + } + std::string utf8_string; + utf8_string.resize(target_length); + int converted_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, -1, utf8_string.data(), + target_length, nullptr, nullptr); + if (converted_length == 0) { + return std::string(); + } + return utf8_string; +} diff --git a/third_party/packages/flutter_svg/example/windows/runner/utils.h b/third_party/packages/flutter_svg/example/windows/runner/utils.h new file mode 100644 index 000000000000..3879d5475579 --- /dev/null +++ b/third_party/packages/flutter_svg/example/windows/runner/utils.h @@ -0,0 +1,19 @@ +#ifndef RUNNER_UTILS_H_ +#define RUNNER_UTILS_H_ + +#include +#include + +// Creates a console for the process, and redirects stdout and stderr to +// it for both the runner and the Flutter library. +void CreateAndAttachConsole(); + +// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string +// encoded in UTF-8. Returns an empty std::string on failure. +std::string Utf8FromUtf16(const wchar_t* utf16_string); + +// Gets the command line arguments passed in as a std::vector, +// encoded in UTF-8. Returns an empty std::vector on failure. +std::vector GetCommandLineArguments(); + +#endif // RUNNER_UTILS_H_ diff --git a/third_party/packages/flutter_svg/example/windows/runner/win32_window.cpp b/third_party/packages/flutter_svg/example/windows/runner/win32_window.cpp new file mode 100644 index 000000000000..44091b3f3c91 --- /dev/null +++ b/third_party/packages/flutter_svg/example/windows/runner/win32_window.cpp @@ -0,0 +1,237 @@ +#include "win32_window.h" + +#include + +#include "resource.h" + +namespace { + +constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; + +// The number of Win32Window objects that currently exist. +static int g_active_window_count = 0; + +using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); + +// Scale helper to convert logical scaler values to physical using passed in +// scale factor +int Scale(int source, double scale_factor) { + return static_cast(source * scale_factor); +} + +// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. +// This API is only needed for PerMonitor V1 awareness mode. +void EnableFullDpiSupportIfAvailable(HWND hwnd) { + HMODULE user32_module = LoadLibraryA("User32.dll"); + if (!user32_module) { + return; + } + auto enable_non_client_dpi_scaling = + reinterpret_cast( + GetProcAddress(user32_module, "EnableNonClientDpiScaling")); + if (enable_non_client_dpi_scaling != nullptr) { + enable_non_client_dpi_scaling(hwnd); + FreeLibrary(user32_module); + } +} + +} // namespace + +// Manages the Win32Window's window class registration. +class WindowClassRegistrar { + public: + ~WindowClassRegistrar() = default; + + // Returns the singleton registar instance. + static WindowClassRegistrar* GetInstance() { + if (!instance_) { + instance_ = new WindowClassRegistrar(); + } + return instance_; + } + + // Returns the name of the window class, registering the class if it hasn't + // previously been registered. + const wchar_t* GetWindowClass(); + + // Unregisters the window class. Should only be called if there are no + // instances of the window. + void UnregisterWindowClass(); + + private: + WindowClassRegistrar() = default; + + static WindowClassRegistrar* instance_; + + bool class_registered_ = false; +}; + +WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; + +const wchar_t* WindowClassRegistrar::GetWindowClass() { + if (!class_registered_) { + WNDCLASS window_class{}; + window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); + window_class.lpszClassName = kWindowClassName; + window_class.style = CS_HREDRAW | CS_VREDRAW; + window_class.cbClsExtra = 0; + window_class.cbWndExtra = 0; + window_class.hInstance = GetModuleHandle(nullptr); + window_class.hIcon = + LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); + window_class.hbrBackground = 0; + window_class.lpszMenuName = nullptr; + window_class.lpfnWndProc = Win32Window::WndProc; + RegisterClass(&window_class); + class_registered_ = true; + } + return kWindowClassName; +} + +void WindowClassRegistrar::UnregisterWindowClass() { + UnregisterClass(kWindowClassName, nullptr); + class_registered_ = false; +} + +Win32Window::Win32Window() { ++g_active_window_count; } + +Win32Window::~Win32Window() { + --g_active_window_count; + Destroy(); +} + +bool Win32Window::CreateAndShow(const std::wstring& title, const Point& origin, + const Size& size) { + Destroy(); + + const wchar_t* window_class = + WindowClassRegistrar::GetInstance()->GetWindowClass(); + + const POINT target_point = {static_cast(origin.x), + static_cast(origin.y)}; + HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); + UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); + double scale_factor = dpi / 96.0; + + HWND window = CreateWindow( + window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE, + Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), + Scale(size.width, scale_factor), Scale(size.height, scale_factor), + nullptr, nullptr, GetModuleHandle(nullptr), this); + + if (!window) { + return false; + } + + return OnCreate(); +} + +// static +LRESULT CALLBACK Win32Window::WndProc(HWND const window, UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + if (message == WM_NCCREATE) { + auto window_struct = reinterpret_cast(lparam); + SetWindowLongPtr(window, GWLP_USERDATA, + reinterpret_cast(window_struct->lpCreateParams)); + + auto that = static_cast(window_struct->lpCreateParams); + EnableFullDpiSupportIfAvailable(window); + that->window_handle_ = window; + } else if (Win32Window* that = GetThisFromHandle(window)) { + return that->MessageHandler(window, message, wparam, lparam); + } + + return DefWindowProc(window, message, wparam, lparam); +} + +LRESULT +Win32Window::MessageHandler(HWND hwnd, UINT const message, WPARAM const wparam, + LPARAM const lparam) noexcept { + switch (message) { + case WM_DESTROY: + window_handle_ = nullptr; + Destroy(); + if (quit_on_close_) { + PostQuitMessage(0); + } + return 0; + + case WM_DPICHANGED: { + auto newRectSize = reinterpret_cast(lparam); + LONG newWidth = newRectSize->right - newRectSize->left; + LONG newHeight = newRectSize->bottom - newRectSize->top; + + SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, + newHeight, SWP_NOZORDER | SWP_NOACTIVATE); + + return 0; + } + case WM_SIZE: { + RECT rect = GetClientArea(); + if (child_content_ != nullptr) { + // Size and position the child window. + MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, + rect.bottom - rect.top, TRUE); + } + return 0; + } + + case WM_ACTIVATE: + if (child_content_ != nullptr) { + SetFocus(child_content_); + } + return 0; + } + + return DefWindowProc(window_handle_, message, wparam, lparam); +} + +void Win32Window::Destroy() { + OnDestroy(); + + if (window_handle_) { + DestroyWindow(window_handle_); + window_handle_ = nullptr; + } + if (g_active_window_count == 0) { + WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); + } +} + +Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { + return reinterpret_cast( + GetWindowLongPtr(window, GWLP_USERDATA)); +} + +void Win32Window::SetChildContent(HWND content) { + child_content_ = content; + SetParent(content, window_handle_); + RECT frame = GetClientArea(); + + MoveWindow(content, frame.left, frame.top, frame.right - frame.left, + frame.bottom - frame.top, true); + + SetFocus(child_content_); +} + +RECT Win32Window::GetClientArea() { + RECT frame; + GetClientRect(window_handle_, &frame); + return frame; +} + +HWND Win32Window::GetHandle() { return window_handle_; } + +void Win32Window::SetQuitOnClose(bool quit_on_close) { + quit_on_close_ = quit_on_close; +} + +bool Win32Window::OnCreate() { + // No-op; provided for subclasses. + return true; +} + +void Win32Window::OnDestroy() { + // No-op; provided for subclasses. +} diff --git a/third_party/packages/flutter_svg/example/windows/runner/win32_window.h b/third_party/packages/flutter_svg/example/windows/runner/win32_window.h new file mode 100644 index 000000000000..4ae64a12b465 --- /dev/null +++ b/third_party/packages/flutter_svg/example/windows/runner/win32_window.h @@ -0,0 +1,95 @@ +#ifndef RUNNER_WIN32_WINDOW_H_ +#define RUNNER_WIN32_WINDOW_H_ + +#include + +#include +#include +#include + +// A class abstraction for a high DPI-aware Win32 Window. Intended to be +// inherited from by classes that wish to specialize with custom +// rendering and input handling +class Win32Window { + public: + struct Point { + unsigned int x; + unsigned int y; + Point(unsigned int x, unsigned int y) : x(x), y(y) {} + }; + + struct Size { + unsigned int width; + unsigned int height; + Size(unsigned int width, unsigned int height) + : width(width), height(height) {} + }; + + Win32Window(); + virtual ~Win32Window(); + + // Creates and shows a win32 window with |title| and position and size using + // |origin| and |size|. New windows are created on the default monitor. Window + // sizes are specified to the OS in physical pixels, hence to ensure a + // consistent size to will treat the width height passed in to this function + // as logical pixels and scale to appropriate for the default monitor. Returns + // true if the window was created successfully. + bool CreateAndShow(const std::wstring& title, const Point& origin, + const Size& size); + + // Release OS resources associated with window. + void Destroy(); + + // Inserts |content| into the window tree. + void SetChildContent(HWND content); + + // Returns the backing Window handle to enable clients to set icon and other + // window properties. Returns nullptr if the window has been destroyed. + HWND GetHandle(); + + // If true, closing this window will quit the application. + void SetQuitOnClose(bool quit_on_close); + + // Return a RECT representing the bounds of the current client area. + RECT GetClientArea(); + + protected: + // Processes and route salient window messages for mouse handling, + // size change and DPI. Delegates handling of these to member overloads that + // inheriting classes can handle. + virtual LRESULT MessageHandler(HWND window, UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Called when CreateAndShow is called, allowing subclass window-related + // setup. Subclasses should return false if setup fails. + virtual bool OnCreate(); + + // Called when Destroy is called. + virtual void OnDestroy(); + + private: + friend class WindowClassRegistrar; + + // OS callback called by message pump. Handles the WM_NCCREATE message which + // is passed when the non-client area is being created and enables automatic + // non-client DPI scaling so that the non-client area automatically + // responsponds to changes in DPI. All other messages are handled by + // MessageHandler. + static LRESULT CALLBACK WndProc(HWND const window, UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Retrieves a class instance pointer for |window| + static Win32Window* GetThisFromHandle(HWND const window) noexcept; + + bool quit_on_close_ = false; + + // window handle for top level window. + HWND window_handle_ = nullptr; + + // window handle for hosted content. + HWND child_content_ = nullptr; +}; + +#endif // RUNNER_WIN32_WINDOW_H_ diff --git a/third_party/packages/flutter_svg/lib/flutter_svg.dart b/third_party/packages/flutter_svg/lib/flutter_svg.dart new file mode 100644 index 000000000000..eb6d4b5ab9e8 --- /dev/null +++ b/third_party/packages/flutter_svg/lib/flutter_svg.dart @@ -0,0 +1 @@ +export 'svg.dart'; diff --git a/third_party/packages/flutter_svg/lib/src/cache.dart b/third_party/packages/flutter_svg/lib/src/cache.dart new file mode 100644 index 000000000000..3b1f5b14e883 --- /dev/null +++ b/third_party/packages/flutter_svg/lib/src/cache.dart @@ -0,0 +1,113 @@ +import 'package:flutter/foundation.dart'; +import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; + +/// The cache for decoded SVGs. +class Cache { + final Map> _pending = >{}; + final Map _cache = {}; + + /// Maximum number of entries to store in the cache. + /// + /// Once this many entries have been cached, the least-recently-used entry is + /// evicted when adding a new entry. + int get maximumSize => _maximumSize; + int _maximumSize = 100; + + /// Changes the maximum cache size. + /// + /// If the new size is smaller than the current number of elements, the + /// extraneous elements are evicted immediately. Setting this to zero and then + /// returning it to its original value will therefore immediately clear the + /// cache. + set maximumSize(int value) { + assert(value != null); // ignore: unnecessary_null_comparison + assert(value >= 0); + if (value == maximumSize) { + return; + } + _maximumSize = value; + if (maximumSize == 0) { + clear(); + } else { + while (_cache.length > maximumSize) { + _cache.remove(_cache.keys.first); + } + } + } + + /// Evicts all entries from the cache. + /// + /// This is useful if, for instance, the root asset bundle has been updated + /// and therefore new images must be obtained. + void clear() { + _cache.clear(); + } + + /// Evicts a single entry from the cache, returning true if successful. + bool evict(Object key) { + return _cache.remove(key) != null; + } + + /// Evicts a single entry from the cache if the `oldData` and `newData` are + /// incompatible. + /// + /// For example, if the theme has changed the current color and the picture + /// uses current color, [evict] will be called. + bool maybeEvict(Object key, SvgTheme oldData, SvgTheme newData) { + return evict(key); + } + + /// Returns the previously cached [PictureStream] for the given key, if available; + /// if not, calls the given callback to obtain it first. In either case, the + /// key is moved to the "most recently used" position. + /// + /// The arguments must not be null. The `loader` cannot return null. + Future putIfAbsent( + Object key, + Future Function() loader, + ) { + assert(key != null); // ignore: unnecessary_null_comparison + assert(loader != null); // ignore: unnecessary_null_comparison + Future? pendingResult = _pending[key]; + if (pendingResult != null) { + return pendingResult; + } + + ByteData? result = _cache[key]; + if (result != null) { + // Remove the provider from the list so that we can put it back in below + // and thus move it to the end of the list. + _cache.remove(key); + } else { + pendingResult = loader(); + _pending[key] = pendingResult; + pendingResult.then((ByteData data) { + _pending.remove(key); + _add(key, data); + result = data; // in case it was a synchronous future. + }); + } + if (result != null) { + _add(key, result!); + return SynchronousFuture(result!); + } + assert(_cache.length <= maximumSize); + return pendingResult!; + } + + void _add(Object key, ByteData result) { + if (maximumSize > 0) { + if (_cache.containsKey(key)) { + _cache.remove(key); // update LRU. + } else if (_cache.length == maximumSize && maximumSize > 0) { + _cache.remove(_cache.keys.first); + } + assert(_cache.length < maximumSize); + _cache[key] = result; + } + assert(_cache.length <= maximumSize); + } + + /// The number of entries in the cache. + int get count => _cache.length; +} diff --git a/third_party/packages/flutter_svg/lib/src/default_theme.dart b/third_party/packages/flutter_svg/lib/src/default_theme.dart new file mode 100644 index 000000000000..d824695d7c34 --- /dev/null +++ b/third_party/packages/flutter_svg/lib/src/default_theme.dart @@ -0,0 +1,42 @@ +import 'package:flutter/widgets.dart'; + +import 'loaders.dart'; + +/// The SVG theme to apply to descendant [SvgPicture] widgets +/// which don't have explicit theme values. +class DefaultSvgTheme extends InheritedTheme { + /// Creates a default SVG theme for the given subtree + /// using the provided [theme]. + const DefaultSvgTheme({ + super.key, + required super.child, + required this.theme, + }); + + /// The SVG theme to apply. + final SvgTheme theme; + + /// The closest instance of this class that encloses the given context. + /// + /// Typical usage is as follows: + /// + /// ```dart + /// DefaultSvgTheme theme = DefaultSvgTheme.of(context); + /// ``` + static DefaultSvgTheme? of(BuildContext context) { + return context.dependOnInheritedWidgetOfExactType(); + } + + @override + bool updateShouldNotify(DefaultSvgTheme oldWidget) { + return theme != oldWidget.theme; + } + + @override + Widget wrap(BuildContext context, Widget child) { + return DefaultSvgTheme( + theme: theme, + child: child, + ); + } +} diff --git a/third_party/packages/flutter_svg/lib/src/loaders.dart b/third_party/packages/flutter_svg/lib/src/loaders.dart new file mode 100644 index 000000000000..2996cc11f64f --- /dev/null +++ b/third_party/packages/flutter_svg/lib/src/loaders.dart @@ -0,0 +1,462 @@ +import 'dart:convert' show utf8; + +import 'package:flutter/foundation.dart' hide compute; +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; +import 'package:http/http.dart' as http; +import 'package:vector_graphics/vector_graphics.dart'; +import 'package:vector_graphics_compiler/vector_graphics_compiler.dart' as vg; + +import '../svg.dart' show svg; +import 'default_theme.dart'; +import 'utilities/compute.dart'; +import 'utilities/file.dart'; + +/// A theme used when decoding an SVG picture. +@immutable +class SvgTheme { + /// Instantiates an SVG theme with the [currentColor] + /// and [fontSize]. + /// + /// Defaults the [fontSize] to 14. + // WARNING WARNING WARNING + // If this codebase ever decides to default the font size to something off the + // BuildContext, caching logic will have to be updated. The font size can + // temporarily and unexpectedly change during route transitions in common + // patterns used in `MaterialApp`. This busts caching and destroys + // performance. + const SvgTheme({ + this.currentColor = const Color(0xFF000000), + this.fontSize = 14, + double? xHeight, + }) : xHeight = xHeight ?? fontSize / 2; + + /// The default color applied to SVG elements that inherit the color property. + /// See: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#currentcolor_keyword + final Color currentColor; + + /// The font size used when calculating em units of SVG elements. + /// See: https://www.w3.org/TR/SVG11/coords.html#Units + final double fontSize; + + /// The x-height (corpus size) of the font used when calculating ex units of SVG elements. + /// Defaults to [fontSize] / 2 if not provided. + /// See: https://www.w3.org/TR/SVG11/coords.html#Units, https://en.wikipedia.org/wiki/X-height + final double xHeight; + + /// Creates a [vg.SvgTheme] from this. + vg.SvgTheme toVgTheme() { + return vg.SvgTheme( + currentColor: vg.Color(currentColor.value), + fontSize: fontSize, + xHeight: xHeight, + ); + } + + @override + bool operator ==(Object other) { + if (other.runtimeType != runtimeType) { + return false; + } + + return other is SvgTheme && + currentColor == other.currentColor && + fontSize == other.fontSize && + xHeight == other.xHeight; + } + + @override + int get hashCode => Object.hash(currentColor, fontSize, xHeight); + + @override + String toString() => + 'SvgTheme(currentColor: $currentColor, fontSize: $fontSize, xHeight: $xHeight)'; +} + +/// A class that transforms from one color to another during SVG parsing. +/// +/// This object must be immutable so that it is suitable for use in the +/// [svg.cache]. +@immutable +abstract class ColorMapper { + /// Allows const constructors on subclasses. + const ColorMapper(); + + /// Returns a new color to use in place of [color] during SVG parsing. + /// + /// The SVG parser will call this method every time it parses a color + Color substitute( + String? id, + String elementName, + String attributeName, + Color color, + ); +} + +class _DelegateVgColorMapper extends vg.ColorMapper { + _DelegateVgColorMapper(this.colorMapper); + + final ColorMapper colorMapper; + + @override + vg.Color substitute( + String? id, String elementName, String attributeName, vg.Color color) { + final Color substituteColor = colorMapper.substitute( + id, elementName, attributeName, Color(color.value)); + return vg.Color(substituteColor.value); + } +} + +/// A [BytesLoader] that parses a SVG data in an isolate and creates a +/// vector_graphics binary representation. +@immutable +abstract class SvgLoader extends BytesLoader { + /// See class doc. + const SvgLoader({ + this.theme, + this.colorMapper, + }); + + /// The theme to determine currentColor and font sizing attributes. + final SvgTheme? theme; + + /// The [ColorMapper] used to transform colors from the SVG, if any. + final ColorMapper? colorMapper; + + /// Will be called in [compute] with the result of [prepareMessage]. + @protected + String provideSvg(T? message); + + /// Will be called + @protected + Future prepareMessage(BuildContext? context) => + SynchronousFuture(null); + + /// Returns the svg theme. + @visibleForTesting + @protected + SvgTheme getTheme(BuildContext? context) { + if (theme != null) { + return theme!; + } + if (context != null) { + final SvgTheme? defaultTheme = DefaultSvgTheme.of(context)?.theme; + if (defaultTheme != null) { + return defaultTheme; + } + } + return const SvgTheme(); + } + + Future _load(BuildContext? context) { + final SvgTheme theme = getTheme(context); + return prepareMessage(context).then((T? message) { + return compute((T? message) { + return vg + .encodeSvg( + xml: provideSvg(message), + theme: theme.toVgTheme(), + colorMapper: colorMapper == null + ? null + : _DelegateVgColorMapper(colorMapper!), + debugName: 'Svg loader', + enableClippingOptimizer: false, + enableMaskingOptimizer: false, + enableOverdrawOptimizer: false, + ) + .buffer + .asByteData(); + }, message, debugLabel: 'Load Bytes'); + }); + } + + /// This method intentionally avoids using `await` to avoid unnecessary event + /// loop turns. This is meant to to help tests in particular. + @override + Future loadBytes(BuildContext? context) { + return svg.cache.putIfAbsent(cacheKey(context), () => _load(context)); + } + + @override + SvgCacheKey cacheKey(BuildContext? context) { + final SvgTheme theme = getTheme(context); + return SvgCacheKey(keyData: this, theme: theme, colorMapper: colorMapper); + } +} + +/// A [SvgTheme] aware cache key. +/// +/// The theme must be part of the cache key to ensure that otherwise similar +/// SVGs get cached separately. +@immutable +class SvgCacheKey { + /// See [SvgCacheKey]. + const SvgCacheKey({ + required this.keyData, + required this.colorMapper, + this.theme, + }); + + /// The theme for this cached SVG. + final SvgTheme? theme; + + /// The other key data for the SVG. + /// + /// For most loaders, using the loader object itself is suitable. + final Object keyData; + + /// The color mapper for the SVG, if any. + final ColorMapper? colorMapper; + + @override + int get hashCode => Object.hash(theme, keyData, colorMapper); + + @override + bool operator ==(Object other) { + return other is SvgCacheKey && + other.theme == theme && + other.keyData == keyData && + other.colorMapper == colorMapper; + } +} + +/// A [BytesLoader] that parses an SVG string in an isolate and creates a +/// vector_graphics binary representation. +class SvgStringLoader extends SvgLoader { + /// See class doc. + const SvgStringLoader( + this._svg, { + super.theme, + super.colorMapper, + }); + + final String _svg; + + @override + String provideSvg(void message) { + return _svg; + } + + @override + int get hashCode => Object.hash(_svg, theme, colorMapper); + + @override + bool operator ==(Object other) { + return other is SvgStringLoader && + other._svg == _svg && + other.theme == theme && + other.colorMapper == colorMapper; + } +} + +/// A [BytesLoader] that decodes and parses a UTF-8 encoded SVG string from a +/// [Uint8List] in an isolate and creates a vector_graphics binary +/// representation. +class SvgBytesLoader extends SvgLoader { + /// See class doc. + const SvgBytesLoader( + this.bytes, { + super.theme, + super.colorMapper, + }); + + /// The UTF-8 encoded XML bytes. + final Uint8List bytes; + + @override + String provideSvg(void message) => utf8.decode(bytes, allowMalformed: true); + + @override + int get hashCode => Object.hash(bytes, theme, colorMapper); + + @override + bool operator ==(Object other) { + return other is SvgBytesLoader && + other.bytes == bytes && + other.theme == theme && + other.colorMapper == colorMapper; + } +} + +/// A [BytesLoader] that decodes SVG data from a file in an isolate and creates +/// a vector_graphics binary representation. +class SvgFileLoader extends SvgLoader { + /// See class doc. + const SvgFileLoader( + this.file, { + super.theme, + super.colorMapper, + }); + + /// The file containing the SVG data to decode and render. + final File file; + + @override + String provideSvg(void message) { + final Uint8List bytes = file.readAsBytesSync(); + return utf8.decode(bytes, allowMalformed: true); + } + + @override + int get hashCode => Object.hash(file, theme, colorMapper); + + @override + bool operator ==(Object other) { + return other is SvgFileLoader && + other.file == file && + other.theme == theme && + other.colorMapper == colorMapper; + } +} + +// Replaces the cache key for [AssetBytesLoader] to account for the fact that +// different widgets may select a different asset bundle based on the return +// value of `DefaultAssetBundle.of(context)`. +@immutable +class _AssetByteLoaderCacheKey { + const _AssetByteLoaderCacheKey( + this.assetName, + this.packageName, + this.assetBundle, + ); + + final String assetName; + final String? packageName; + + final AssetBundle assetBundle; + + @override + int get hashCode => Object.hash(assetName, packageName, assetBundle); + + @override + bool operator ==(Object other) { + return other is _AssetByteLoaderCacheKey && + other.assetName == assetName && + other.assetBundle == assetBundle && + other.packageName == packageName; + } + + @override + String toString() => + 'VectorGraphicAsset(${packageName != null ? '$packageName/' : ''}$assetName)'; +} + +/// A [BytesLoader] that decodes and parses an SVG asset in an isolate and +/// creates a vector_graphics binary representation. +class SvgAssetLoader extends SvgLoader { + /// See class doc. + const SvgAssetLoader( + this.assetName, { + this.packageName, + this.assetBundle, + super.theme, + super.colorMapper, + }); + + /// The name of the asset, e.g. foo.svg. + final String assetName; + + /// The package containing the asset. + final String? packageName; + + /// The asset bundle to use, or [DefaultAssetBundle] if null. + final AssetBundle? assetBundle; + + AssetBundle _resolveBundle(BuildContext? context) { + if (assetBundle != null) { + return assetBundle!; + } + if (context != null) { + return DefaultAssetBundle.of(context); + } + return rootBundle; + } + + @override + Future prepareMessage(BuildContext? context) { + return _resolveBundle(context).load( + packageName == null ? assetName : 'packages/$packageName/$assetName', + ); + } + + @override + String provideSvg(ByteData? message) => + utf8.decode(message!.buffer.asUint8List(), allowMalformed: true); + + @override + SvgCacheKey cacheKey(BuildContext? context) { + final SvgTheme theme = getTheme(context); + return SvgCacheKey( + theme: theme, + colorMapper: colorMapper, + keyData: _AssetByteLoaderCacheKey( + assetName, + packageName, + _resolveBundle(context), + ), + ); + } + + @override + int get hashCode => + Object.hash(assetName, packageName, assetBundle, theme, colorMapper); + + @override + bool operator ==(Object other) { + return other is SvgAssetLoader && + other.assetName == assetName && + other.packageName == packageName && + other.assetBundle == assetBundle && + other.theme == theme && + other.colorMapper == colorMapper; + } + + @override + String toString() => 'SvgAssetLoader($assetName)'; +} + +/// A [BytesLoader] that decodes and parses a UTF-8 encoded SVG string the +/// network in an isolate and creates a vector_graphics binary representation. +class SvgNetworkLoader extends SvgLoader { + /// See class doc. + const SvgNetworkLoader( + this.url, { + this.headers, + super.theme, + super.colorMapper, + http.Client? httpClient, + }) : _httpClient = httpClient; + + /// The [Uri] encoded resource address. + final String url; + + /// Optional HTTP headers to send as part of the request. + final Map? headers; + + final http.Client? _httpClient; + + @override + Future prepareMessage(BuildContext? context) async { + final http.Client client = _httpClient ?? http.Client(); + return (await client.get(Uri.parse(url), headers: headers)).bodyBytes; + } + + @override + String provideSvg(Uint8List? message) => + utf8.decode(message!, allowMalformed: true); + + @override + int get hashCode => Object.hash(url, headers, theme, colorMapper); + + @override + bool operator ==(Object other) { + return other is SvgNetworkLoader && + other.url == url && + other.headers == headers && + other.theme == theme && + other.colorMapper == colorMapper; + } + + @override + String toString() => 'SvgNetworkLoader($url)'; +} diff --git a/third_party/packages/flutter_svg/lib/src/utilities/_file_io.dart b/third_party/packages/flutter_svg/lib/src/utilities/_file_io.dart new file mode 100644 index 000000000000..3da0f6adbf79 --- /dev/null +++ b/third_party/packages/flutter_svg/lib/src/utilities/_file_io.dart @@ -0,0 +1 @@ +export 'dart:io' show File; diff --git a/third_party/packages/flutter_svg/lib/src/utilities/_file_none.dart b/third_party/packages/flutter_svg/lib/src/utilities/_file_none.dart new file mode 100644 index 000000000000..6f6fcf5cd636 --- /dev/null +++ b/third_party/packages/flutter_svg/lib/src/utilities/_file_none.dart @@ -0,0 +1,16 @@ +import 'dart:typed_data'; + +/// Fake File for Web +abstract class File { + /// Get the path of the file. + String get path; + + /// Reads the entire file contents as a list of bytes. + /// + /// Returns a `Future` that completes with the list of bytes that + /// is the contents of the file. + Future readAsBytes(); + + /// Reads the entire file contents as a list of bytes synchronously. + Uint8List readAsBytesSync(); +} diff --git a/third_party/packages/flutter_svg/lib/src/utilities/compute.dart b/third_party/packages/flutter_svg/lib/src/utilities/compute.dart new file mode 100644 index 000000000000..7b8eab69d0f6 --- /dev/null +++ b/third_party/packages/flutter_svg/lib/src/utilities/compute.dart @@ -0,0 +1,23 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart' as foundation; + +Future _testCompute( + foundation.ComputeCallback callback, Q message, + {String? debugLabel}) { + if (foundation.kDebugMode) { + final Type? bindingType = foundation.BindingBase.debugBindingType(); + if (bindingType.toString() == 'AutomatedTestWidgetsFlutterBinding') {} + } + final FutureOr result = callback(message); + if (result is Future) { + return result; + } + return foundation.SynchronousFuture(result); +} + +/// A compute implementation that does not spawn isolates in tests. +const foundation.ComputeImpl compute = + (foundation.kDebugMode || foundation.kIsWeb) + ? _testCompute + : foundation.compute; diff --git a/third_party/packages/flutter_svg/lib/src/utilities/file.dart b/third_party/packages/flutter_svg/lib/src/utilities/file.dart new file mode 100644 index 000000000000..16555b6fabb3 --- /dev/null +++ b/third_party/packages/flutter_svg/lib/src/utilities/file.dart @@ -0,0 +1 @@ +export '_file_io.dart' if (dart.library.js_interop) '_file_none.dart'; diff --git a/third_party/packages/flutter_svg/lib/src/utilities/numbers.dart b/third_party/packages/flutter_svg/lib/src/utilities/numbers.dart new file mode 100644 index 000000000000..23e2b4061242 --- /dev/null +++ b/third_party/packages/flutter_svg/lib/src/utilities/numbers.dart @@ -0,0 +1,25 @@ +/// Parses a [rawDouble] `String` to a `double`. +/// +/// The [rawDouble] might include a unit (`px`, `em` or `ex`) +/// which is stripped off when parsed to a `double`. +/// +/// Passing `null` will return `null`. +double? parseDouble(String? rawDouble, {bool tryParse = false}) { + assert(tryParse != null); // ignore: unnecessary_null_comparison + if (rawDouble == null) { + return null; + } + + rawDouble = rawDouble + .replaceFirst('rem', '') + .replaceFirst('em', '') + .replaceFirst('ex', '') + .replaceFirst('px', '') + .replaceFirst('pt', '') + .trim(); + + if (tryParse) { + return double.tryParse(rawDouble); + } + return double.parse(rawDouble); +} diff --git a/third_party/packages/flutter_svg/lib/svg.dart b/third_party/packages/flutter_svg/lib/svg.dart new file mode 100644 index 000000000000..0efcbdaa1eef --- /dev/null +++ b/third_party/packages/flutter_svg/lib/svg.dart @@ -0,0 +1,569 @@ +import 'dart:ui' as ui; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:http/http.dart' as http; +import 'package:vector_graphics/vector_graphics_compat.dart'; + +import 'src/cache.dart'; +import 'src/loaders.dart'; +import 'src/utilities/file.dart'; + +export 'package:vector_graphics/vector_graphics.dart' + show BytesLoader, PictureInfo, VectorGraphicUtilities, vg; + +export 'src/cache.dart'; +export 'src/default_theme.dart'; +export 'src/loaders.dart'; + +/// Instance for [Svg]'s utility methods, which can produce a [DrawableRoot] +/// or [PictureInfo] from [String] or [Uint8List]. +final Svg svg = Svg._(); + +/// A utility class for decoding SVG data to a [DrawableRoot] or a [PictureInfo]. +/// +/// These methods are used by [SvgPicture], but can also be directly used e.g. +/// to create a [DrawableRoot] you manipulate or render to your own [Canvas]. +/// Access to this class is provided by the exported [svg] member. +class Svg { + Svg._(); + + /// A global override flag for [SvgPicture.cacheColorFilter]. + /// + /// If this is null, the value in [SvgPicture.cacheColorFilter] is used. If it + /// is not null, it will override that value. + @Deprecated('This no longer does anything.') + bool? cacheColorFilterOverride; + + /// The cache instance for decoded SVGs. + final Cache cache = Cache(); +} + +// ignore: avoid_classes_with_only_static_members +/// Deprecated class, will be removed, does not do anything. +@Deprecated('This feature does not do anything anymore.') +class PictureProvider { + /// Deprecated, use [svg.cache] instead. + @Deprecated('Use svg.cache instead.') + static Cache get cache => svg.cache; +} + +/// A widget that will parse SVG data for rendering on screen. +class SvgPicture extends StatelessWidget { + /// Instantiates a widget that renders an SVG picture using the `pictureProvider`. + /// + /// Either the [width] and [height] arguments should be specified, or the + /// widget should be placed in a context that sets tight layout constraints. + /// Otherwise, the image dimensions will change as the image is loaded, which + /// will result in ugly layout changes. + /// + /// If `matchTextDirection` is set to true, the picture will be flipped + /// horizontally in [TextDirection.rtl] contexts. + /// + /// The `allowDrawingOutsideOfViewBox` parameter should be used with caution - + /// if set to true, it will not clip the canvas used internally to the view box, + /// meaning the picture may draw beyond the intended area and lead to undefined + /// behavior or additional memory overhead. + /// + /// A custom `placeholderBuilder` can be specified for cases where decoding or + /// acquiring data may take a noticeably long time, e.g. for a network picture. + /// + /// The `semanticsLabel` can be used to identify the purpose of this picture for + /// screen reading software. + /// + /// If [excludeFromSemantics] is true, then [semanticsLabel] will be ignored. + const SvgPicture( + this.bytesLoader, { + super.key, + this.width, + this.height, + this.fit = BoxFit.contain, + this.alignment = Alignment.center, + this.matchTextDirection = false, + this.allowDrawingOutsideViewBox = false, + this.placeholderBuilder, + this.colorFilter, + this.semanticsLabel, + this.excludeFromSemantics = false, + this.clipBehavior = Clip.hardEdge, + @Deprecated( + 'No code should use this parameter. It never was implemented properly. ' + 'The SVG theme must be set on the bytesLoader.') + SvgTheme? theme, + @Deprecated('This no longer does anything.') bool cacheColorFilter = false, + }); + + /// Instantiates a widget that renders an SVG picture from an [AssetBundle]. + /// + /// The key will be derived from the `assetName`, `package`, and `bundle` + /// arguments. The `package` argument must be non-null when displaying an SVG + /// from a package and null otherwise. See the `Assets in packages` section for + /// details. + /// + /// Either the [width] and [height] arguments should be specified, or the + /// widget should be placed in a context that sets tight layout constraints. + /// Otherwise, the image dimensions will change as the image is loaded, which + /// will result in ugly layout changes. + /// + /// If `matchTextDirection` is set to true, the picture will be flipped + /// horizontally in [TextDirection.rtl] contexts. + /// + /// The `allowDrawingOutsideOfViewBox` parameter should be used with caution - + /// if set to true, it will not clip the canvas used internally to the view box, + /// meaning the picture may draw beyond the intended area and lead to undefined + /// behavior or additional memory overhead. + /// + /// A custom `placeholderBuilder` can be specified for cases where decoding or + /// acquiring data may take a noticeably long time. + /// + /// The `color` and `colorBlendMode` arguments, if specified, will be used to set a + /// [ColorFilter] on any [Paint]s created for this drawing. + /// + /// The `theme` argument, if provided, will override the default theme + /// used when parsing SVG elements. + /// + /// ## Assets in packages + /// + /// To create the widget with an asset from a package, the [package] argument + /// must be provided. For instance, suppose a package called `my_icons` has + /// `icons/heart.svg` . + /// + /// Then to display the image, use: + /// + /// ```dart + /// SvgPicture.asset('icons/heart.svg', package: 'my_icons') + /// ``` + /// + /// Assets used by the package itself should also be displayed using the + /// [package] argument as above. + /// + /// If the desired asset is specified in the `pubspec.yaml` of the package, it + /// is bundled automatically with the app. In particular, assets used by the + /// package itself must be specified in its `pubspec.yaml`. + /// + /// A package can also choose to have assets in its 'lib/' folder that are not + /// specified in its `pubspec.yaml`. In this case for those images to be + /// bundled, the app has to specify which ones to include. For instance a + /// package named `fancy_backgrounds` could have: + /// + /// ```none + /// lib/backgrounds/background1.svg + /// lib/backgrounds/background2.svg + /// lib/backgrounds/background3.svg + ///``` + /// + /// To include, say the first image, the `pubspec.yaml` of the app should + /// specify it in the assets section: + /// + /// ```yaml + /// assets: + /// - packages/fancy_backgrounds/backgrounds/background1.svg + /// ``` + /// + /// The `lib/` is implied, so it should not be included in the asset path. + /// + /// + /// See also: + /// + /// * , an introduction to assets in + /// Flutter. + /// + /// If [excludeFromSemantics] is true, then [semanticsLabel] will be ignored. + SvgPicture.asset( + String assetName, { + super.key, + this.matchTextDirection = false, + AssetBundle? bundle, + String? package, + this.width, + this.height, + this.fit = BoxFit.contain, + this.alignment = Alignment.center, + this.allowDrawingOutsideViewBox = false, + this.placeholderBuilder, + this.semanticsLabel, + this.excludeFromSemantics = false, + this.clipBehavior = Clip.hardEdge, + SvgTheme? theme, + ui.ColorFilter? colorFilter, + @Deprecated('Use colorFilter instead.') ui.Color? color, + @Deprecated('Use colorFilter instead.') + ui.BlendMode colorBlendMode = ui.BlendMode.srcIn, + @Deprecated('This no longer does anything.') bool cacheColorFilter = false, + }) : bytesLoader = SvgAssetLoader( + assetName, + packageName: package, + assetBundle: bundle, + theme: theme, + ), + colorFilter = colorFilter ?? _getColorFilter(color, colorBlendMode); + + /// Creates a widget that displays an SVG obtained from the network. + /// + /// The [url] argument must not be null. + /// + /// Either the [width] and [height] arguments should be specified, or the + /// widget should be placed in a context that sets tight layout constraints. + /// Otherwise, the image dimensions will change as the image is loaded, which + /// will result in ugly layout changes. + /// + /// If `matchTextDirection` is set to true, the picture will be flipped + /// horizontally in [TextDirection.rtl] contexts. + /// + /// The `allowDrawingOutsideOfViewBox` parameter should be used with caution - + /// if set to true, it will not clip the canvas used internally to the view box, + /// meaning the picture may draw beyond the intended area and lead to undefined + /// behavior or additional memory overhead. + /// + /// A custom `placeholderBuilder` can be specified for cases where decoding or + /// acquiring data may take a noticeably long time, such as high latency scenarios. + /// + /// The `color` and `colorBlendMode` arguments, if specified, will be used to set a + /// [ColorFilter] on any [Paint]s created for this drawing. + /// + /// The `theme` argument, if provided, will override the default theme + /// used when parsing SVG elements. + /// + /// All network images are cached regardless of HTTP headers. + /// + /// An optional `headers` argument can be used to send custom HTTP headers + /// with the image request. + /// + /// If [excludeFromSemantics] is true, then [semanticsLabel] will be ignored. + SvgPicture.network( + String url, { + super.key, + Map? headers, + this.width, + this.height, + this.fit = BoxFit.contain, + this.alignment = Alignment.center, + this.matchTextDirection = false, + this.allowDrawingOutsideViewBox = false, + this.placeholderBuilder, + ui.ColorFilter? colorFilter, + @Deprecated('Use colorFilter instead.') ui.Color? color, + @Deprecated('Use colorFilter instead.') + ui.BlendMode colorBlendMode = ui.BlendMode.srcIn, + this.semanticsLabel, + this.excludeFromSemantics = false, + this.clipBehavior = Clip.hardEdge, + @Deprecated('This no longer does anything.') bool cacheColorFilter = false, + SvgTheme? theme, + http.Client? httpClient, + }) : bytesLoader = SvgNetworkLoader( + url, + headers: headers, + theme: theme, + httpClient: httpClient, + ), + colorFilter = colorFilter ?? _getColorFilter(color, colorBlendMode); + + /// Creates a widget that displays an SVG obtained from a [File]. + /// + /// The [file] argument must not be null. + /// + /// Either the [width] and [height] arguments should be specified, or the + /// widget should be placed in a context that sets tight layout constraints. + /// Otherwise, the image dimensions will change as the image is loaded, which + /// will result in ugly layout changes. + /// + /// If `matchTextDirection` is set to true, the picture will be flipped + /// horizontally in [TextDirection.rtl] contexts. + /// + /// The `allowDrawingOutsideOfViewBox` parameter should be used with caution - + /// if set to true, it will not clip the canvas used internally to the view box, + /// meaning the picture may draw beyond the intended area and lead to undefined + /// behavior or additional memory overhead. + /// + /// A custom `placeholderBuilder` can be specified for cases where decoding or + /// acquiring data may take a noticeably long time. + /// + /// The `color` and `colorBlendMode` arguments, if specified, will be used to set a + /// [ColorFilter] on any [Paint]s created for this drawing. + /// + /// The `theme` argument, if provided, will override the default theme + /// used when parsing SVG elements. + /// + /// On Android, this may require the + /// `android.permission.READ_EXTERNAL_STORAGE` permission. + /// + /// If [excludeFromSemantics] is true, then [semanticsLabel] will be ignored. + SvgPicture.file( + File file, { + super.key, + this.width, + this.height, + this.fit = BoxFit.contain, + this.alignment = Alignment.center, + this.matchTextDirection = false, + this.allowDrawingOutsideViewBox = false, + this.placeholderBuilder, + ui.ColorFilter? colorFilter, + @Deprecated('Use colorFilter instead.') ui.Color? color, + @Deprecated('Use colorFilter instead.') + ui.BlendMode colorBlendMode = ui.BlendMode.srcIn, + this.semanticsLabel, + this.excludeFromSemantics = false, + this.clipBehavior = Clip.hardEdge, + SvgTheme? theme, + @Deprecated('This no longer does anything.') bool cacheColorFilter = false, + }) : bytesLoader = SvgFileLoader(file, theme: theme), + colorFilter = colorFilter ?? _getColorFilter(color, colorBlendMode); + + /// Creates a widget that displays an SVG obtained from a [Uint8List]. + /// + /// The [bytes] argument must not be null. + /// + /// Either the [width] and [height] arguments should be specified, or the + /// widget should be placed in a context that sets tight layout constraints. + /// Otherwise, the image dimensions will change as the image is loaded, which + /// will result in ugly layout changes. + /// + /// If `matchTextDirection` is set to true, the picture will be flipped + /// horizontally in [TextDirection.rtl] contexts. + /// + /// The `allowDrawingOutsideOfViewBox` parameter should be used with caution - + /// if set to true, it will not clip the canvas used internally to the view box, + /// meaning the picture may draw beyond the intended area and lead to undefined + /// behavior or additional memory overhead. + /// + /// A custom `placeholderBuilder` can be specified for cases where decoding or + /// acquiring data may take a noticeably long time. + /// + /// The `color` and `colorBlendMode` arguments, if specified, will be used to set a + /// [ColorFilter] on any [Paint]s created for this drawing. + /// + /// The `theme` argument, if provided, will override the default theme + /// used when parsing SVG elements. + /// + /// If [excludeFromSemantics] is true, then [semanticsLabel] will be ignored. + SvgPicture.memory( + Uint8List bytes, { + super.key, + this.width, + this.height, + this.fit = BoxFit.contain, + this.alignment = Alignment.center, + this.matchTextDirection = false, + this.allowDrawingOutsideViewBox = false, + this.placeholderBuilder, + ui.ColorFilter? colorFilter, + @Deprecated('Use colorFilter instead.') ui.Color? color, + @Deprecated('Use colorFilter instead.') + ui.BlendMode colorBlendMode = ui.BlendMode.srcIn, + this.semanticsLabel, + this.excludeFromSemantics = false, + this.clipBehavior = Clip.hardEdge, + SvgTheme? theme, + @Deprecated('This no longer does anything.') bool cacheColorFilter = false, + }) : bytesLoader = SvgBytesLoader(bytes, theme: theme), + colorFilter = colorFilter ?? _getColorFilter(color, colorBlendMode); + + /// Creates a widget that displays an SVG obtained from a [String]. + /// + /// The [string] argument must not be null. + /// + /// Either the [width] and [height] arguments should be specified, or the + /// widget should be placed in a context that sets tight layout constraints. + /// Otherwise, the image dimensions will change as the image is loaded, which + /// will result in ugly layout changes. + /// + /// If `matchTextDirection` is set to true, the picture will be flipped + /// horizontally in [TextDirection.rtl] contexts. + /// + /// The `allowDrawingOutsideOfViewBox` parameter should be used with caution - + /// if set to true, it will not clip the canvas used internally to the view box, + /// meaning the picture may draw beyond the intended area and lead to undefined + /// behavior or additional memory overhead. + /// + /// A custom `placeholderBuilder` can be specified for cases where decoding or + /// acquiring data may take a noticeably long time. + /// + /// The `color` and `colorBlendMode` arguments, if specified, will be used to set a + /// [ColorFilter] on any [Paint]s created for this drawing. + /// + /// The `theme` argument, if provided, will override the default theme + /// used when parsing SVG elements. + /// + /// If [excludeFromSemantics] is true, then [semanticsLabel] will be ignored. + SvgPicture.string( + String string, { + super.key, + this.width, + this.height, + this.fit = BoxFit.contain, + this.alignment = Alignment.center, + this.matchTextDirection = false, + this.allowDrawingOutsideViewBox = false, + this.placeholderBuilder, + ui.ColorFilter? colorFilter, + @Deprecated('Use colorFilter instead.') ui.Color? color, + @Deprecated('Use colorFilter instead.') + ui.BlendMode colorBlendMode = ui.BlendMode.srcIn, + this.semanticsLabel, + this.excludeFromSemantics = false, + this.clipBehavior = Clip.hardEdge, + SvgTheme? theme, + @Deprecated('This no longer does anything.') bool cacheColorFilter = false, + }) : bytesLoader = SvgStringLoader(string, theme: theme), + colorFilter = colorFilter ?? _getColorFilter(color, colorBlendMode); + + static ColorFilter? _getColorFilter( + ui.Color? color, ui.BlendMode colorBlendMode) => + color == null ? null : ui.ColorFilter.mode(color, colorBlendMode); + + /// The default placeholder for a SVG that may take time to parse or + /// retrieve, e.g. from a network location. + static WidgetBuilder defaultPlaceholderBuilder = + (BuildContext ctx) => const LimitedBox(); + + /// If specified, the width to use for the SVG. If unspecified, the SVG + /// will take the width of its parent. + final double? width; + + /// If specified, the height to use for the SVG. If unspecified, the SVG + /// will take the height of its parent. + final double? height; + + /// How to inscribe the picture into the space allocated during layout. + /// The default is [BoxFit.contain]. + final BoxFit fit; + + /// How to align the picture within its parent widget. + /// + /// The alignment aligns the given position in the picture to the given position + /// in the layout bounds. For example, an [Alignment] alignment of (-1.0, + /// -1.0) aligns the image to the top-left corner of its layout bounds, while a + /// [Alignment] alignment of (1.0, 1.0) aligns the bottom right of the + /// picture with the bottom right corner of its layout bounds. Similarly, an + /// alignment of (0.0, 1.0) aligns the bottom middle of the image with the + /// middle of the bottom edge of its layout bounds. + /// + /// If the [alignment] is [TextDirection]-dependent (i.e. if it is a + /// [AlignmentDirectional]), then a [TextDirection] must be available + /// when the picture is painted. + /// + /// Defaults to [Alignment.center]. + /// + /// See also: + /// + /// * [Alignment], a class with convenient constants typically used to + /// specify an [AlignmentGeometry]. + /// * [AlignmentDirectional], like [Alignment] for specifying alignments + /// relative to text direction. + final AlignmentGeometry alignment; + + /// The [BytesLoader] used to resolve the SVG. + final BytesLoader bytesLoader; + + /// The placeholder to use while fetching, decoding, and parsing the SVG data. + final WidgetBuilder? placeholderBuilder; + + /// If true, will horizontally flip the picture in [TextDirection.rtl] contexts. + final bool matchTextDirection; + + /// If true, will allow the SVG to be drawn outside of the clip boundary of its + /// viewBox. + final bool allowDrawingOutsideViewBox; + + /// The [Semantics.label] for this picture. + /// + /// The value indicates the purpose of the picture, and will be + /// read out by screen readers. + final String? semanticsLabel; + + /// Whether to exclude this picture from semantics. + /// + /// Useful for pictures which do not contribute meaningful information to an + /// application. + final bool excludeFromSemantics; + + /// The content will be clipped (or not) according to this option. + /// + /// See the enum [Clip] for details of all possible options and their common + /// use cases. + /// + /// Defaults to [Clip.hardEdge], and must not be null. + final Clip clipBehavior; + + /// The color filter, if any, to apply to this widget. + final ColorFilter? colorFilter; + + @override + Widget build(BuildContext context) { + return createCompatVectorGraphic( + loader: bytesLoader, + width: width, + height: height, + fit: fit, + alignment: alignment, + semanticsLabel: semanticsLabel, + excludeFromSemantics: excludeFromSemantics, + clipBehavior: clipBehavior, + colorFilter: colorFilter, + placeholderBuilder: placeholderBuilder, + clipViewbox: !allowDrawingOutsideViewBox, + matchTextDirection: matchTextDirection, + ); + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + + properties + ..add(StringProperty( + 'bytesLoader', + bytesLoader.toString(), + showName: false, + )) + ..add(DoubleProperty('width', width, defaultValue: null)) + ..add(DoubleProperty('height', height, defaultValue: null)) + ..add(DiagnosticsProperty( + 'alignment', + alignment, + defaultValue: Alignment.center, + )) + ..add(DiagnosticsProperty( + 'allowDrawingOutsideViewBox', + allowDrawingOutsideViewBox, + defaultValue: false, + )) + ..add(EnumProperty( + 'clipBehavior', + clipBehavior, + defaultValue: BoxFit.contain, + )) + ..add(StringProperty( + 'colorFilter', + colorFilter.toString(), + defaultValue: null, + )) + ..add(EnumProperty( + 'fit', + fit, + defaultValue: BoxFit.contain, + )) + ..add(DiagnosticsProperty( + 'placeholderBuilder', + placeholderBuilder, + defaultValue: null, + )) + ..add(DiagnosticsProperty( + 'matchTextDirection', + matchTextDirection, + defaultValue: false, + )) + ..add(DiagnosticsProperty( + 'excludeFromSemantics', + excludeFromSemantics, + defaultValue: false, + )) + ..add(StringProperty( + 'semanticsLabel', + semanticsLabel, + defaultValue: null, + )); + } +} diff --git a/third_party/packages/flutter_svg/pubspec.yaml b/third_party/packages/flutter_svg/pubspec.yaml new file mode 100644 index 000000000000..e18e014e9596 --- /dev/null +++ b/third_party/packages/flutter_svg/pubspec.yaml @@ -0,0 +1,25 @@ +name: flutter_svg +description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. +repository: https://github.com/flutter/packages/tree/main/third_party/packages/flutter_svg +issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_svg%22 +version: 2.0.14 + +environment: + sdk: ^3.4.0 + flutter: ">=3.22.0" + +dependencies: + flutter: + sdk: flutter + http: ^1.0.0 + vector_graphics: ^1.1.13 + vector_graphics_codec: ^1.1.11+1 + vector_graphics_compiler: ^1.1.14 + +dev_dependencies: + flutter_test: + sdk: flutter + +topics: + - svg + - vector-graphics diff --git a/third_party/packages/flutter_svg/test/.gitignore b/third_party/packages/flutter_svg/test/.gitignore new file mode 100644 index 000000000000..ba9e40375e3e --- /dev/null +++ b/third_party/packages/flutter_svg/test/.gitignore @@ -0,0 +1,2 @@ +# Golden test diffs. +/failures/** diff --git a/third_party/packages/flutter_svg/test/cache_test.dart b/third_party/packages/flutter_svg/test/cache_test.dart new file mode 100644 index 000000000000..4f05d37021d9 --- /dev/null +++ b/third_party/packages/flutter_svg/test/cache_test.dart @@ -0,0 +1,129 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter_svg/src/cache.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + test('Sanity', () async { + final Cache cache = Cache(); + expect(cache.maximumSize, 100); + expect(cache.count, 0); + final Completer completer = Completer(); + final Future put = cache.putIfAbsent(1, () => completer.future); + expect(put, completer.future); + expect(cache.count, 0); + completer.complete(ByteData(1)); + expect(cache.count, 0); + await null; + expect(cache.count, 1); + cache.clear(); + expect(cache.count, 0); + // Not bothering to check result since it's from the same completer. + unawaited(cache.putIfAbsent(1, () => completer.future)); + expect(cache.count, 0); + await null; + expect(cache.count, 1); + expect(cache.evict(1), true); + expect(cache.count, 0); + expect(cache.evict(1), false); + }); + + test('LRU', () async { + final Cache cache = Cache(); + cache.maximumSize = 2; + final Completer completerA = Completer() + ..complete(ByteData(1)); + final Completer completerB = Completer() + ..complete(ByteData(2)); + final Completer completerC = Completer() + ..complete(ByteData(3)); + + expect(cache.count, 0); + + await cache.putIfAbsent(1, () => completerA.future); + expect(cache.count, 1); + + await cache.putIfAbsent(2, () => completerB.future); + expect(cache.count, 2); + + await cache.putIfAbsent(3, () => completerC.future); + expect(cache.count, 2); + + expect(cache.evict(1), false); + expect(cache.evict(2), true); + expect(cache.evict(3), true); + + await cache.putIfAbsent(1, () => completerA.future); + expect(cache.count, 1); + + await cache.putIfAbsent(2, () => completerB.future); + expect(cache.count, 2); + + await cache.putIfAbsent(1, () => completerA.future); + expect(cache.count, 2); + + await cache.putIfAbsent(3, () => completerC.future); + expect(cache.count, 2); + + expect(cache.evict(1), true); + expect(cache.evict(2), false); + expect(cache.evict(3), true); + }); + + test('Adding beyond max with synchronous futures', () async { + final Cache cache = Cache(); + cache.maximumSize = 2; + final Future completerA = + SynchronousFuture(ByteData(1)); + final Future completerB = + SynchronousFuture(ByteData(2)); + final Future completerC = + SynchronousFuture(ByteData(3)); + + expect(cache.count, 0); + + unawaited(cache.putIfAbsent(1, () => completerA)); + expect(cache.count, 1); + + unawaited(cache.putIfAbsent(2, () => completerB)); + expect(cache.count, 2); + + unawaited(cache.putIfAbsent(2, () => completerB)); + expect(cache.count, 2); + + unawaited(cache.putIfAbsent(3, () => completerC)); + expect(cache.count, 2); + + unawaited(cache.putIfAbsent(2, () => completerB)); + expect(cache.count, 2); + }); + + test('Futures completing late/together', () async { + final Cache cache = Cache(); + cache.maximumSize = 2; + final Completer completerA = Completer(); + final Completer completerB = Completer(); + final Completer completerC = Completer(); + + expect(cache.count, 0); + + unawaited(cache.putIfAbsent(1, () => completerA.future)); + unawaited(cache.putIfAbsent(2, () => completerB.future)); + completerA.complete(ByteData(1)); + completerB.complete(ByteData(1)); + + expect(cache.count, 0); + await null; + expect(cache.count, 2); + + unawaited(cache.putIfAbsent(3, () => completerC.future)); + expect(cache.count, 2); + + completerC.complete(ByteData(1)); + expect(cache.count, 2); + + await null; + expect(cache.count, 2); + }); +} diff --git a/third_party/packages/flutter_svg/test/default_theme_test.dart b/third_party/packages/flutter_svg/test/default_theme_test.dart new file mode 100644 index 000000000000..62966ad2b418 --- /dev/null +++ b/third_party/packages/flutter_svg/test/default_theme_test.dart @@ -0,0 +1,189 @@ +import 'package:flutter/widgets.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('DefaultSvgTheme', () { + testWidgets('changes propagate to SvgPicture', (WidgetTester tester) async { + const SvgTheme svgTheme = SvgTheme( + currentColor: Color(0xFF733821), + xHeight: 6.0, + ); + + final SvgPicture svgPictureWidget = SvgPicture.string(''' + + +'''); + + await tester.pumpWidget(DefaultSvgTheme( + theme: svgTheme, + child: svgPictureWidget, + )); + + SvgPicture svgPicture = tester.firstWidget(find.byType(SvgPicture)); + expect(svgPicture, isNotNull); + BuildContext context = tester.element(find.byType(SvgPicture)); + expect( + (svgPicture.bytesLoader as SvgStringLoader).getTheme(context), + equals(svgTheme), + ); + + const SvgTheme anotherSvgTheme = SvgTheme( + currentColor: Color(0xFF05290E), + fontSize: 12.0, + xHeight: 7.0, + ); + + await tester.pumpWidget(DefaultSvgTheme( + theme: anotherSvgTheme, + child: svgPictureWidget, + )); + context = tester.element(find.byType(SvgPicture)); + + svgPicture = tester.firstWidget(find.byType(SvgPicture)); + expect(svgPicture, isNotNull); + expect( + (svgPicture.bytesLoader as SvgStringLoader).getTheme(context), + equals(anotherSvgTheme), + ); + }); + + testWidgets( + "currentColor from the widget's theme takes precedence over " + 'the theme from DefaultSvgTheme', (WidgetTester tester) async { + const SvgTheme svgTheme = SvgTheme( + currentColor: Color(0xFF733821), + ); + + final SvgPicture svgPictureWidget = SvgPicture.string( + ''' + + +''', + theme: const SvgTheme( + currentColor: Color(0xFF05290E), + ), + ); + + await tester.pumpWidget(DefaultSvgTheme( + theme: svgTheme, + child: svgPictureWidget, + )); + final BuildContext context = tester.element(find.byType(SvgPicture)); + final SvgPicture svgPicture = tester.firstWidget(find.byType(SvgPicture)); + expect(svgPicture, isNotNull); + expect( + (svgPicture.bytesLoader as SvgStringLoader) + .getTheme(context) + .currentColor, + equals(const Color(0xFF05290E)), + ); + }); + + testWidgets( + "fontSize from the widget's theme takes precedence over " + 'the theme from DefaultSvgTheme', (WidgetTester tester) async { + const SvgTheme svgTheme = SvgTheme(); + + final SvgPicture svgPictureWidget = SvgPicture.string( + ''' + + +''', + theme: const SvgTheme( + fontSize: 12.0, + ), + ); + + await tester.pumpWidget(DefaultSvgTheme( + theme: svgTheme, + child: svgPictureWidget, + )); + + final SvgPicture svgPicture = tester.firstWidget(find.byType(SvgPicture)); + final BuildContext context = tester.element(find.byType(SvgPicture)); + + expect(svgPicture, isNotNull); + expect( + (svgPicture.bytesLoader as SvgStringLoader).getTheme(context).fontSize, + equals(12.0), + ); + }); + + testWidgets( + 'fontSize defaults to 14 ' + "if no widget's theme, DefaultSvgTheme or DefaultTextStyle is provided", + (WidgetTester tester) async { + final SvgPicture svgPictureWidget = SvgPicture.string( + ''' + + +''', + ); + + await tester.pumpWidget(svgPictureWidget); + + final SvgPicture svgPicture = tester.firstWidget(find.byType(SvgPicture)); + final BuildContext context = tester.element(find.byType(SvgPicture)); + expect(svgPicture, isNotNull); + expect( + (svgPicture.bytesLoader as SvgStringLoader).getTheme(context).fontSize, + equals(14.0), + ); + }); + + testWidgets( + "xHeight from the widget's theme takes precedence over " + 'the theme from DefaultSvgTheme', (WidgetTester tester) async { + const SvgTheme svgTheme = SvgTheme( + xHeight: 6.5, + ); + + final SvgPicture svgPictureWidget = SvgPicture.string( + ''' + + +''', + theme: const SvgTheme( + fontSize: 12.0, + xHeight: 7.0, + ), + ); + + await tester.pumpWidget(DefaultSvgTheme( + theme: svgTheme, + child: svgPictureWidget, + )); + + final SvgPicture svgPicture = tester.firstWidget(find.byType(SvgPicture)); + final BuildContext context = tester.element(find.byType(SvgPicture)); + expect(svgPicture, isNotNull); + expect( + (svgPicture.bytesLoader as SvgStringLoader).getTheme(context).xHeight, + equals(7.0), + ); + }); + + testWidgets( + 'xHeight defaults to the font size divided by 2 (7.0) ' + "if no widget's theme or DefaultSvgTheme is provided", + (WidgetTester tester) async { + final SvgPicture svgPictureWidget = SvgPicture.string( + ''' + + +''', + ); + + await tester.pumpWidget(svgPictureWidget); + + final SvgPicture svgPicture = tester.firstWidget(find.byType(SvgPicture)); + final BuildContext context = tester.element(find.byType(SvgPicture)); + expect(svgPicture, isNotNull); + expect( + (svgPicture.bytesLoader as SvgStringLoader).getTheme(context).xHeight, + equals(7.0), + ); + }); + }); +} diff --git a/third_party/packages/flutter_svg/test/golden_widget/circle.em_ex.png b/third_party/packages/flutter_svg/test/golden_widget/circle.em_ex.png new file mode 100644 index 000000000000..9c72bdcbea28 Binary files /dev/null and b/third_party/packages/flutter_svg/test/golden_widget/circle.em_ex.png differ diff --git a/third_party/packages/flutter_svg/test/golden_widget/circle.em_ex2.png b/third_party/packages/flutter_svg/test/golden_widget/circle.em_ex2.png new file mode 100644 index 000000000000..9c72bdcbea28 Binary files /dev/null and b/third_party/packages/flutter_svg/test/golden_widget/circle.em_ex2.png differ diff --git a/third_party/packages/flutter_svg/test/golden_widget/columns_and_rows.png b/third_party/packages/flutter_svg/test/golden_widget/columns_and_rows.png new file mode 100644 index 000000000000..105dbecb5468 Binary files /dev/null and b/third_party/packages/flutter_svg/test/golden_widget/columns_and_rows.png differ diff --git a/third_party/packages/flutter_svg/test/golden_widget/ellipse.em_ex.png b/third_party/packages/flutter_svg/test/golden_widget/ellipse.em_ex.png new file mode 100644 index 000000000000..3244264aae23 Binary files /dev/null and b/third_party/packages/flutter_svg/test/golden_widget/ellipse.em_ex.png differ diff --git a/third_party/packages/flutter_svg/test/golden_widget/ellipse.em_ex2.png b/third_party/packages/flutter_svg/test/golden_widget/ellipse.em_ex2.png new file mode 100644 index 000000000000..3244264aae23 Binary files /dev/null and b/third_party/packages/flutter_svg/test/golden_widget/ellipse.em_ex2.png differ diff --git a/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.asset.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.asset.png new file mode 100644 index 000000000000..c73024a3e846 Binary files /dev/null and b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.asset.png differ diff --git a/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.memory.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.memory.png new file mode 100644 index 000000000000..c73024a3e846 Binary files /dev/null and b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.memory.png differ diff --git a/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.natural.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.natural.png new file mode 100644 index 000000000000..510026df7d61 Binary files /dev/null and b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.natural.png differ diff --git a/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.network.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.network.png new file mode 100644 index 000000000000..c73024a3e846 Binary files /dev/null and b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.network.png differ diff --git a/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.color_filter.blendmode_color.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.color_filter.blendmode_color.png new file mode 100644 index 000000000000..d8219b1ed22c Binary files /dev/null and b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.color_filter.blendmode_color.png differ diff --git a/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.color_filter.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.color_filter.png new file mode 100644 index 000000000000..3138a2bce82d Binary files /dev/null and b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.color_filter.png differ diff --git a/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.ltr.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.ltr.png new file mode 100644 index 000000000000..13f1aa453c9e Binary files /dev/null and b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.ltr.png differ diff --git a/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.png new file mode 100644 index 000000000000..c73024a3e846 Binary files /dev/null and b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.png differ diff --git a/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.rtl.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.rtl.png new file mode 100644 index 000000000000..626ffb7fd585 Binary files /dev/null and b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.rtl.png differ diff --git a/third_party/packages/flutter_svg/test/golden_widget/image_blue.png b/third_party/packages/flutter_svg/test/golden_widget/image_blue.png new file mode 100644 index 000000000000..1561f73cf184 Binary files /dev/null and b/third_party/packages/flutter_svg/test/golden_widget/image_blue.png differ diff --git a/third_party/packages/flutter_svg/test/golden_widget/image_red.png b/third_party/packages/flutter_svg/test/golden_widget/image_red.png new file mode 100644 index 000000000000..83e239b7a8ac Binary files /dev/null and b/third_party/packages/flutter_svg/test/golden_widget/image_red.png differ diff --git a/third_party/packages/flutter_svg/test/golden_widget/line.em_ex.png b/third_party/packages/flutter_svg/test/golden_widget/line.em_ex.png new file mode 100644 index 000000000000..38147f6bcf70 Binary files /dev/null and b/third_party/packages/flutter_svg/test/golden_widget/line.em_ex.png differ diff --git a/third_party/packages/flutter_svg/test/golden_widget/line.em_ex2.png b/third_party/packages/flutter_svg/test/golden_widget/line.em_ex2.png new file mode 100644 index 000000000000..38147f6bcf70 Binary files /dev/null and b/third_party/packages/flutter_svg/test/golden_widget/line.em_ex2.png differ diff --git a/third_party/packages/flutter_svg/test/golden_widget/rect.em_ex.png b/third_party/packages/flutter_svg/test/golden_widget/rect.em_ex.png new file mode 100644 index 000000000000..03519b9cd0df Binary files /dev/null and b/third_party/packages/flutter_svg/test/golden_widget/rect.em_ex.png differ diff --git a/third_party/packages/flutter_svg/test/golden_widget/rect.em_ex2.png b/third_party/packages/flutter_svg/test/golden_widget/rect.em_ex2.png new file mode 100644 index 000000000000..03519b9cd0df Binary files /dev/null and b/third_party/packages/flutter_svg/test/golden_widget/rect.em_ex2.png differ diff --git a/third_party/packages/flutter_svg/test/golden_widget/stick_figure.withclipping.png b/third_party/packages/flutter_svg/test/golden_widget/stick_figure.withclipping.png new file mode 100644 index 000000000000..e6039db89e74 Binary files /dev/null and b/third_party/packages/flutter_svg/test/golden_widget/stick_figure.withclipping.png differ diff --git a/third_party/packages/flutter_svg/test/golden_widget/text_color_filter.png b/third_party/packages/flutter_svg/test/golden_widget/text_color_filter.png new file mode 100644 index 000000000000..f7f4360c7c53 Binary files /dev/null and b/third_party/packages/flutter_svg/test/golden_widget/text_color_filter.png differ diff --git a/third_party/packages/flutter_svg/test/golden_widget/two_of_same.png b/third_party/packages/flutter_svg/test/golden_widget/two_of_same.png new file mode 100644 index 000000000000..e2d6c13fdf38 Binary files /dev/null and b/third_party/packages/flutter_svg/test/golden_widget/two_of_same.png differ diff --git a/third_party/packages/flutter_svg/test/loaders_test.dart b/third_party/packages/flutter_svg/test/loaders_test.dart new file mode 100644 index 000000000000..591b3b01e708 --- /dev/null +++ b/third_party/packages/flutter_svg/test/loaders_test.dart @@ -0,0 +1,98 @@ +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + setUp(() { + svg.cache.clear(); + svg.cache.maximumSize = 100; + }); + + test('ColorMapper updates the cache', () async { + const TestLoader loaderA = TestLoader(); + const TestLoader loaderB = TestLoader(colorMapper: _TestColorMapper()); + final ByteData bytesA = await loaderA.loadBytes(null); + final ByteData bytesB = await loaderB.loadBytes(null); + expect(identical(bytesA, bytesB), false); + expect(svg.cache.count, 2); + }); + + test('SvgTheme updates the cache', () async { + const TestLoader loaderA = + TestLoader(theme: SvgTheme(currentColor: Color(0xFFABCDEF))); + const TestLoader loaderB = + TestLoader(theme: SvgTheme(currentColor: Color(0xFFFEDCBA))); + final ByteData bytesA = await loaderA.loadBytes(null); + final ByteData bytesB = await loaderB.loadBytes(null); + expect(identical(bytesA, bytesB), false); + expect(svg.cache.count, 2); + }); + + test('Uses the cache', () async { + const TestLoader loader = TestLoader(); + final ByteData bytes = await loader.loadBytes(null); + final ByteData bytes2 = await loader.loadBytes(null); + expect(identical(bytes, bytes2), true); + expect(svg.cache.count, 1); + }); + + test('Empty cache', () async { + svg.cache.maximumSize = 0; + const TestLoader loader = TestLoader(); + final ByteData bytes = await loader.loadBytes(null); + final ByteData bytes2 = await loader.loadBytes(null); + expect(identical(bytes, bytes2), false); + svg.cache.maximumSize = 100; + }); + + test('AssetLoader respects packages', () async { + final TestBundle bundle = TestBundle({ + 'foo': Uint8List(0).buffer.asByteData(), + 'packages/packageName/foo': Uint8List(1).buffer.asByteData(), + }); + final SvgAssetLoader loader = SvgAssetLoader('foo', assetBundle: bundle); + final SvgAssetLoader packageLoader = + SvgAssetLoader('foo', assetBundle: bundle, packageName: 'packageName'); + expect((await loader.prepareMessage(null))!.lengthInBytes, 0); + expect((await packageLoader.prepareMessage(null))!.lengthInBytes, 1); + }); +} + +class TestBundle extends Fake implements AssetBundle { + TestBundle(this.map); + + final Map map; + + @override + Future load(String key) async { + return map[key]!; + } +} + +class TestLoader extends SvgLoader { + const TestLoader({this.keyName = 'A', super.theme, super.colorMapper}); + + final String keyName; + + @override + String provideSvg(void message) { + return ''; + } + + @override + SvgCacheKey cacheKey(BuildContext? context) { + return SvgCacheKey( + theme: theme, colorMapper: colorMapper, keyData: keyName); + } +} + +class _TestColorMapper extends ColorMapper { + const _TestColorMapper(); + + @override + Color substitute( + String? id, String elementName, String attributeName, Color color) { + return color; + } +} diff --git a/third_party/packages/flutter_svg/test/no_width_height_test.dart b/third_party/packages/flutter_svg/test/no_width_height_test.dart new file mode 100644 index 000000000000..61ab76de5f9c --- /dev/null +++ b/third_party/packages/flutter_svg/test/no_width_height_test.dart @@ -0,0 +1,107 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +import 'package:flutter_test/flutter_test.dart'; + +void main() { + testWidgets('Spacing without width or height', (WidgetTester tester) async { + await tester.pumpWidget( + const Directionality( + textDirection: TextDirection.ltr, + child: RepaintBoundary( + child: ColumnsAndRows(), + ), + ), + ); + await tester.pumpAndSettle(); + + await expectLater( + find.byType(RepaintBoundary), + matchesGoldenFile('golden_widget/columns_and_rows.png'), + skip: 'This golden needs updating', + ); + }, skip: !isLinux); +} + +class ColumnsAndRows extends StatelessWidget { + const ColumnsAndRows({super.key}); + + @override + Widget build(BuildContext context) { + return const Column( + children: [ + Row(children: [ + ImageWithText(), + ]), + Row( + children: [ + ImageWithText(), + ImageWithText(), + ], + ), + Row( + children: [ + ImageWithText(), + ImageWithText(), + ImageWithText(), + ImageWithText(), + ], + ), + Row( + children: [ + ImageWithText(), + ImageWithText(), + ImageWithText(), + ImageWithText(), + ImageWithText(), + ImageWithText(), + ], + ), + Row( + children: [ + ImageWithText(), + ImageWithText(), + ImageWithText(), + ImageWithText(), + ImageWithText(), + ImageWithText(), + ImageWithText(), + ImageWithText(), + ], + ), + ], + ); + } +} + +class ImageWithText extends StatelessWidget { + const ImageWithText({super.key}); + + @override + Widget build(BuildContext context) { + final Widget image = SvgPicture.string(circleSvg); + final Widget imageContainer = ColoredBox( + color: Colors.amber, + child: image, + ); + const Widget text = Text('Hello'); + final Widget column = Column( + children: [ + imageContainer, + text, + ], + ); + return Expanded( + child: column, + ); + } +} + +const String circleSvg = ''' + + + + + + +'''; diff --git a/third_party/packages/flutter_svg/test/widget_svg_test.dart b/third_party/packages/flutter_svg/test/widget_svg_test.dart new file mode 100644 index 000000000000..d857cc757700 --- /dev/null +++ b/third_party/packages/flutter_svg/test/widget_svg_test.dart @@ -0,0 +1,850 @@ +import 'dart:convert'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:http/http.dart' as http; + +class _TolerantComparator extends LocalFileComparator { + _TolerantComparator(super.testFile); + + @override + Future compare(Uint8List imageBytes, Uri golden) async { + final ComparisonResult result = await GoldenFileComparator.compareLists( + imageBytes, + await getGoldenBytes(golden), + ); + if (!result.passed) { + final String error = await generateFailureOutput(result, golden, basedir); + if (result.diffPercent >= .06) { + throw FlutterError(error); + } else { + // ignore: avoid_print + print( + 'Warning - golden differed less than .06% (${result.diffPercent}%), ' + 'ignoring failure but producing output\n' + '$error'); + } + } + return true; + } +} + +Future _checkWidgetAndGolden(Key key, String filename) async { + final Finder widgetFinder = find.byKey(key); + expect(widgetFinder, findsOneWidget); + await expectLater(widgetFinder, matchesGoldenFile('golden_widget/$filename')); +} + +void main() { + final MediaQueryData mediaQueryData = + MediaQueryData.fromView(PlatformDispatcher.instance.implicitView!); + + setUpAll(() { + final LocalFileComparator oldComparator = + goldenFileComparator as LocalFileComparator; + final _TolerantComparator newComparator = + _TolerantComparator(Uri.parse('${oldComparator.basedir}test')); + expect(oldComparator.basedir, newComparator.basedir); + goldenFileComparator = newComparator; + }); + + testWidgets( + 'SvgPicture does not use a color filtering widget when no color specified', + (WidgetTester tester) async { + await tester.pumpWidget( + SvgPicture.string( + svgStr, + width: 100.0, + height: 100.0, + ), + ); + await tester.pumpAndSettle(); + + expect(find.byType(ColorFiltered), findsNothing); + }); + + testWidgets('SvgPicture can work with a FittedBox', + (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + await tester.pumpWidget( + MediaQuery( + data: const MediaQueryData(size: Size(100, 100)), + child: Row( + key: key, + textDirection: TextDirection.ltr, + children: [ + Flexible( + child: FittedBox( + fit: BoxFit.fitWidth, + child: SvgPicture.string( + svgStr, + width: 20.0, + height: 14.0, + ), + ), + ), + ], + ), + ), + ); + await tester.pumpAndSettle(); + final Finder widgetFinder = find.byKey(key); + expect(widgetFinder, findsOneWidget); + }); + + testWidgets('SvgPicture.string', (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + await tester.pumpWidget( + MediaQuery( + data: mediaQueryData, + child: RepaintBoundary( + key: key, + child: SvgPicture.string( + svgStr, + width: 100.0, + height: 100.0, + ), + ), + ), + ); + + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'flutter_logo.string.png'); + }); + + testWidgets('SvgPicture natural size', (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + await tester.pumpWidget( + MediaQuery( + data: mediaQueryData, + child: Center( + key: key, + child: SvgPicture.string( + svgStr, + ), + ), + ), + ); + + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'flutter_logo.natural.png'); + }); + + testWidgets('SvgPicture clipped', (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + await tester.pumpWidget( + MediaQuery( + data: mediaQueryData, + child: Center( + key: key, + child: SvgPicture.string( + stickFigureSvgStr, + ), + ), + ), + ); + + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'stick_figure.withclipping.png'); + }); + + testWidgets('SvgPicture.string ltr', (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + await tester.pumpWidget( + MediaQuery( + data: mediaQueryData, + child: RepaintBoundary( + key: key, + child: Directionality( + textDirection: TextDirection.ltr, + child: Row( + children: [ + Expanded( + child: Container( + color: const Color(0xFF0D47A1), + height: 100.0, + ), + ), + SvgPicture.string( + svgStr, + matchTextDirection: true, + height: 100.0, + width: 100.0, + ), + Expanded( + child: Container( + color: const Color(0xFF42A5F5), + height: 100.0, + ), + ), + ], + ), + ), + ), + ), + ); + + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'flutter_logo.string.ltr.png'); + }); + + testWidgets('SvgPicture.string rtl', (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + await tester.pumpWidget( + MediaQuery( + data: mediaQueryData, + child: RepaintBoundary( + key: key, + child: Directionality( + textDirection: TextDirection.rtl, + child: Row( + children: [ + Expanded( + child: Container( + color: const Color(0xFF0D47A1), + height: 100.0, + ), + ), + SvgPicture.string( + svgStr, + matchTextDirection: true, + height: 100.0, + width: 100.0, + ), + Expanded( + child: Container( + color: const Color(0xFF42A5F5), + height: 100.0, + ), + ), + ], + ), + ), + ), + ), + ); + + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'flutter_logo.string.rtl.png'); + }); + + testWidgets('SvgPicture.memory', (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + await tester.pumpWidget( + MediaQuery( + data: mediaQueryData, + child: RepaintBoundary( + key: key, + child: SvgPicture.memory( + svgBytes, + ), + ), + ), + ); + await tester.pumpAndSettle(); + + await _checkWidgetAndGolden(key, 'flutter_logo.memory.png'); + }); + + testWidgets('SvgPicture.asset', (WidgetTester tester) async { + final FakeAssetBundle fakeAsset = FakeAssetBundle(); + final GlobalKey key = GlobalKey(); + await tester.pumpWidget( + MediaQuery( + data: mediaQueryData, + child: RepaintBoundary( + key: key, + child: SvgPicture.asset( + 'test.svg', + bundle: fakeAsset, + ), + ), + ), + ); + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'flutter_logo.asset.png'); + }); + + testWidgets('SvgPicture.asset DefaultAssetBundle', + (WidgetTester tester) async { + final FakeAssetBundle fakeAsset = FakeAssetBundle(); + final GlobalKey key = GlobalKey(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: MediaQuery( + data: mediaQueryData, + child: DefaultAssetBundle( + bundle: fakeAsset, + child: RepaintBoundary( + key: key, + child: SvgPicture.asset( + 'test.svg', + semanticsLabel: 'Test SVG', + ), + ), + ), + ), + ), + ); + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'flutter_logo.asset.png'); + }); + + testWidgets('SvgPicture.network', (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + await tester.pumpWidget( + MediaQuery( + data: mediaQueryData, + child: RepaintBoundary( + key: key, + child: SvgPicture.network( + 'test.svg', + httpClient: FakeHttpClient(), + ), + ), + ), + ); + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'flutter_logo.network.png'); + }); + + testWidgets('SvgPicture.network with headers', (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + final FakeHttpClient client = FakeHttpClient(); + await tester.pumpWidget( + MediaQuery( + data: mediaQueryData, + child: RepaintBoundary( + key: key, + child: SvgPicture.network( + 'test.svg', + headers: const {'a': 'b'}, + httpClient: client, + ), + ), + ), + ); + await tester.pumpAndSettle(); + expect(client.headers['a'], 'b'); + }); + + testWidgets('SvgPicture can be created without a MediaQuery', + (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + await tester.pumpWidget( + RepaintBoundary( + key: key, + child: SvgPicture.string( + svgStr, + width: 100.0, + height: 100.0, + ), + ), + ); + + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'flutter_logo.string.png'); + }); + + testWidgets('SvgPicture.network HTTP exception', (WidgetTester tester) async { + expect(() async { + final http.Client client = FakeHttpClient(400); + await tester.pumpWidget( + MediaQuery( + data: mediaQueryData, + child: SvgPicture.network( + 'notFound.svg', + httpClient: client, + ), + ), + ); + }, isNotNull); + }); + + testWidgets('SvgPicture semantics', (WidgetTester tester) async { + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: RepaintBoundary( + child: SvgPicture.string( + svgStr, + semanticsLabel: 'Flutter Logo', + width: 100.0, + height: 100.0, + ), + ), + ), + ); + + await tester.pumpAndSettle(); + + expect(find.byType(Semantics), findsOneWidget); + expect(find.bySemanticsLabel('Flutter Logo'), findsOneWidget); + }); + + testWidgets('SvgPicture semantics - no label', (WidgetTester tester) async { + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: RepaintBoundary( + child: SvgPicture.string( + svgStr, + width: 100.0, + height: 100.0, + ), + ), + ), + ); + + await tester.pumpAndSettle(); + + expect(find.byType(Semantics), findsOneWidget); + }); + + testWidgets('SvgPicture semantics - exclude', (WidgetTester tester) async { + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: RepaintBoundary( + child: SvgPicture.string( + svgStr, + excludeFromSemantics: true, + width: 100.0, + height: 100.0, + ), + ), + ), + ); + + await tester.pumpAndSettle(); + + expect(find.byType(Semantics), findsNothing); + }); + + testWidgets('SvgPicture colorFilter - flutter logo', + (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + await tester.pumpWidget( + RepaintBoundary( + key: key, + child: SvgPicture.string( + svgStr, + width: 100.0, + height: 100.0, + colorFilter: const ColorFilter.mode( + Color(0xFF990000), + BlendMode.srcIn, + ), + ), + ), + ); + + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'flutter_logo.string.color_filter.png'); + }); + + testWidgets('SvgPicture colorFilter with text', (WidgetTester tester) async { + const String svgData = ''' + + + + + + + 2 + + + 1 + + +'''; + final GlobalKey key = GlobalKey(); + await tester.pumpWidget( + RepaintBoundary( + key: key, + child: SvgPicture.string( + svgData, + width: 100.0, + height: 100.0, + colorFilter: const ColorFilter.mode( + Color(0xFF990000), + BlendMode.srcIn, + ), + ), + ), + ); + + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'text_color_filter.png'); + }); + + testWidgets('Can take AlignmentDirectional', (WidgetTester tester) async { + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: SvgPicture.string( + svgStr, + alignment: AlignmentDirectional.bottomEnd, + ), + )); + expect(find.byType(SvgPicture), findsOneWidget); + }); + + group('SvgPicture respects em units', () { + testWidgets('circle (cx, cy, r)', (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + + const String svgStr = ''' + + + +'''; + + await tester.pumpWidget( + RepaintBoundary( + key: key, + child: SvgPicture.string( + svgStr, + theme: const SvgTheme(fontSize: 600), + ), + ), + ); + + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'circle.em_ex.png'); + }); + + testWidgets('rect (x, y, width, height, rx, ry)', + (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + + const String svgStr = ''' + + + +'''; + + await tester.pumpWidget( + RepaintBoundary( + key: key, + child: SvgPicture.string( + svgStr, + theme: const SvgTheme(fontSize: 100), + ), + ), + ); + + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'rect.em_ex.png'); + }); + + testWidgets('ellipse (cx, cy, rx, ry)', (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + + const String svgStr = ''' + + + +'''; + + await tester.pumpWidget( + RepaintBoundary( + key: key, + child: SvgPicture.string( + svgStr, + theme: const SvgTheme(fontSize: 100), + ), + ), + ); + + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'ellipse.em_ex.png'); + }); + + testWidgets('line (x1, y1, x2, y2)', (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + + const String svgStr = ''' + + + + +'''; + + await tester.pumpWidget( + RepaintBoundary( + key: key, + child: SvgPicture.string( + svgStr, + theme: const SvgTheme(fontSize: 100), + ), + ), + ); + + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'line.em_ex.png'); + }); + }); + + group('SvgPicture respects ex units', () { + testWidgets('circle (cx, cy, r)', (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + + const String svgStr = ''' + + + +'''; + + await tester.pumpWidget( + RepaintBoundary( + key: key, + child: SvgPicture.string( + svgStr, + theme: const SvgTheme( + fontSize: 1500, + xHeight: 600, + ), + ), + ), + ); + + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'circle.em_ex2.png'); + }); + + testWidgets('rect (x, y, width, height, rx, ry)', + (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + + const String svgStr = ''' + + + +'''; + + await tester.pumpWidget( + RepaintBoundary( + key: key, + child: SvgPicture.string( + svgStr, + theme: const SvgTheme( + fontSize: 300, + xHeight: 100, + ), + ), + ), + ); + + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'rect.em_ex2.png'); + }); + + testWidgets('ellipse (cx, cy, rx, ry)', (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + + const String svgStr = ''' + + + +'''; + + await tester.pumpWidget( + RepaintBoundary( + key: key, + child: SvgPicture.string( + svgStr, + theme: const SvgTheme( + fontSize: 300, + xHeight: 100, + ), + ), + ), + ); + + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'ellipse.em_ex2.png'); + }); + + testWidgets('line (x1, y1, x2, y2)', (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + + const String svgStr = ''' + + + + +'''; + + await tester.pumpWidget( + RepaintBoundary( + key: key, + child: SvgPicture.string( + svgStr, + theme: const SvgTheme( + fontSize: 300, + xHeight: 100, + ), + ), + ), + ); + + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'line.em_ex2.png'); + }); + }); + + testWidgets('SvgPicture - two of the same', (WidgetTester tester) async { + // Regression test to make sure the same SVG can render twice in the same + // view. If layers are incorrectly reused, this will fail. + await tester.pumpWidget(RepaintBoundary( + child: Directionality( + textDirection: TextDirection.ltr, + child: Row( + children: [ + SvgPicture.string(simpleSvg), + SvgPicture.string(simpleSvg), + ], + ), + ))); + await tester.pumpAndSettle(); + + await expectLater( + find.byType(RepaintBoundary), + matchesGoldenFile('golden_widget/two_of_same.png'), + ); + }); + + // This tests https://github.com/dnfield/flutter_svg/issues/990 + // Where embedded images were being incorrectly cached. + testWidgets('SvgPicture - with cached images', (WidgetTester tester) async { + // Simple red and blue 10x10 squares. + // Borrowed from https://gist.github.com/ondrek/7413434?permalink_comment_id=4674255#gistcomment-4674255 + final Map images = { + 'red': + 'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAFUlEQVR42mP8z8BQz0AEYBxVSF+FABJADveWkH6oAAAAAElFTkSuQmCC', + 'blue': + 'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAFUlEQVR42mNkYPhfz0AEYBxVSF+FAP5FDvcfRYWgAAAAAElFTkSuQmCC', + }; + + // We keep pumping widgets into the same tester, to ensure the same cache + // is used on each iteration. + for (final String key in images.keys) { + final String image = images[key]!; + final String svgStr = ''' + + +'''; + + // First try with SvgPicture.string + await tester.pumpWidget(RepaintBoundary( + child: SvgPicture.string(svgStr), + )); + await tester.runAsync(() => vg.waitForPendingDecodes()); + await tester.pumpAndSettle(); + + Finder widgetFinder = find.byType(SvgPicture); + expect(widgetFinder, findsOneWidget); + await expectLater( + widgetFinder, matchesGoldenFile('golden_widget/image_$key.png')); + + // Then with SvgPicture.memory + await tester.pumpWidget(RepaintBoundary( + // ignore: unnecessary_cast + child: SvgPicture.memory(utf8.encode(svgStr) as Uint8List), + )); + await tester.runAsync(() => vg.waitForPendingDecodes()); + await tester.pumpAndSettle(); + + widgetFinder = find.byType(SvgPicture); + expect(widgetFinder, findsOneWidget); + await expectLater( + widgetFinder, matchesGoldenFile('golden_widget/image_$key.png')); + } + }); +} + +class FakeAssetBundle extends Fake implements AssetBundle { + @override + Future loadString(String key, {bool cache = true}) async { + return svgStr; + } + + @override + Future load(String key) async { + return Uint8List.fromList(utf8.encode(svgStr)).buffer.asByteData(); + } +} + +class FakeHttpClient extends Fake implements http.Client { + FakeHttpClient([this.statusCode = 200]); + + final int statusCode; + + final Map headers = {}; + + @override + Future get(Uri url, {Map? headers}) async { + if (headers != null) { + this.headers.addAll(headers); + } + return http.Response(svgStr, statusCode); + } +} + +const String simpleSvg = ''' + + + +'''; + +const String svgStr = ''' + + + + + + + + + + + + + + + + + + + + +'''; + +const String stickFigureSvgStr = ''' + + + + svg/stick_figure + Created with Sketch. + + + + + + + + + + + + + +'''; + +final Uint8List svgBytes = Uint8List.fromList(utf8.encode(svgStr)); diff --git a/third_party/packages/flutter_svg_test/CHANGELOG.md b/third_party/packages/flutter_svg_test/CHANGELOG.md new file mode 100644 index 000000000000..c8758dc1c947 --- /dev/null +++ b/third_party/packages/flutter_svg_test/CHANGELOG.md @@ -0,0 +1,12 @@ +## 1.0.2 + +* Transfers the package source from https://github.com/dnfield/flutter_svg + to https://github.com/flutter/packages. + +## 1.0.1 + +- Updates HTTP handling. + +## 1.0.0 + +- Initial release diff --git a/third_party/packages/flutter_svg_test/LICENSE b/third_party/packages/flutter_svg_test/LICENSE new file mode 100644 index 000000000000..89a79eb0214e --- /dev/null +++ b/third_party/packages/flutter_svg_test/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018 Dan Field + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/third_party/packages/flutter_svg_test/METADATA b/third_party/packages/flutter_svg_test/METADATA new file mode 100644 index 000000000000..69dec36a7ae1 --- /dev/null +++ b/third_party/packages/flutter_svg_test/METADATA @@ -0,0 +1,15 @@ +name: "flutter_svg_test" +description: + "A testing library which makes it easy to test flutter_svg." + +third_party { + identifier { + type: "Git" + value: "https://github.com/dnfield/flutter_svg/" + primary_source: true + version: "2f7c8ca1a1c1aaedc37e77cf1560cbb0e00baa9a" + } + version: "2f7c8ca1a1c1aaedc37e77cf1560cbb0e00baa9a" + last_upgrade_date { year: 2024 month: 10 day: 28 } + license_type: NOTICE +} \ No newline at end of file diff --git a/third_party/packages/flutter_svg_test/README.md b/third_party/packages/flutter_svg_test/README.md new file mode 100644 index 000000000000..fbad0fcdba69 --- /dev/null +++ b/third_party/packages/flutter_svg_test/README.md @@ -0,0 +1,53 @@ +# flutter_svg_test + +### Testing + +This package provides a set of functions to find images generated by +[**flutter_svg** ](https://github.com/dnfield/flutter_svg/tree/master/packages/flutter_svg) +in widget tests. + +The methods find elements with the `SvgPicture` type and compare either the `BytesLoader` or the +configuration of the `BytesLoader` with the giving test attribute. + +### Example + +#### Find by BytesLoader + +The following example shows how you can find svgs with the matching `SvgAssetLoader`. + + ```dart +testWidgets('Finds svg', (WidgetTester widgetTester) async { + + final SvgPicture asset = SvgPicture.asset('/test/path/my.svg'); + + await widgetTester.pumpWidget(asset); + + expect(find.svg(asset.bytesLoader), findsOneWidget); +}); +``` + +#### Find by svg path + +Sometimes it is more convenient instead of instantiate the whole `BytesLoader` to +compare only specific attributes. + +The following example shows how you can find svgs with the specified attribute. + + ```dart +testWidgets('asset svg with path', (WidgetTester widgetTester) async { + const String svgPath = 'test/flutter_logo.svg'; + + await widgetTester.pumpWidget(SvgPicture.asset(svgPath)); + + expect(find.svgAssetWithPath(svgPath), findsOneWidget); +}); + ``` + +## Commemoration + +This package was originally authored by +[Dan Field](https://github.com/dnfield) and has been forked here +from [dnfield/flutter_svg](https://github.com/dnfield/flutter_svg). +Dan was a member of the Flutter team at Google from 2018 until his death +in 2024. Dan’s impact and contributions to Flutter were immeasurable, and we +honor his memory by continuing to publish and maintain this package. diff --git a/third_party/packages/flutter_svg_test/dart_test.yaml b/third_party/packages/flutter_svg_test/dart_test.yaml new file mode 100644 index 000000000000..5abc3e45f992 --- /dev/null +++ b/third_party/packages/flutter_svg_test/dart_test.yaml @@ -0,0 +1,4 @@ +# _TolerantComparator uses methods that don't compile on web. +# TODO(stuartmorgan): Restructure to allow other tests to run; see +# https://github.com/flutter/flutter/issues/157741 +test_on: vm diff --git a/third_party/packages/flutter_svg_test/lib/flutter_svg_test.dart b/third_party/packages/flutter_svg_test/lib/flutter_svg_test.dart new file mode 100644 index 000000000000..a2200ef51114 --- /dev/null +++ b/third_party/packages/flutter_svg_test/lib/flutter_svg_test.dart @@ -0,0 +1,170 @@ +import 'dart:typed_data'; + +import 'package:flutter/widgets.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:flutter_test/flutter_test.dart'; + +/// Extension on common finder to have native feeling +extension CommonFinderExt on CommonFinders { + /// Finds [SvgPicture] widgets containing `svg` equal to the `svg` argument. + /// + /// ## Sample code + /// ```dart + /// expect(find.svg(SvgPicture.asset('assets/asset_name.svg')), findsOneWidget); + /// ``` + /// + /// If the `skipOffstage` argument is true (the default), then this skips + /// nodes that are [Offstage] or that are from inactive [Route]s. + Finder svg(BytesLoader svg, {bool skipOffstage = true}) { + return _SvgFinder(svg, skipOffstage: skipOffstage); + } + + /// Finds widgets created by [SvgPicture.asset] with the [path] argument. + /// ## Sample code + /// ```dart + /// expect(svgAssetWithPath('assets/asset_name.svg'), findsOneWidget); + /// ``` + /// This will match [SvgPicture.asset] with the [path] 'assets/asset_name.svg'. + /// If the `skipOffstage` argument is true (the default), then this skips + /// nodes that are [Offstage] or that are from inactive [Route]s. + Finder svgAssetWithPath(String path, {bool skipOffstage = true}) { + return _SvgAssetWithPathFinder(svgPath: path, skipOffstage: skipOffstage); + } + + /// Finds widgets created by [SvgPicture.network] with the [url] argument. + /// ## Sample code + /// ```dart + /// expect(find.svgNetworkWithUrl('https://svg.dart'), findsOneWidget); + /// ``` + /// This will match [SvgPicture.network] with the [url] https://svg.dart'. + /// If the `skipOffstage` argument is true (the default), then this skips + /// nodes that are [Offstage] or that are from inactive [Route]s. + Finder svgNetworkWithUrl(String url, {bool skipOffstage = true}) { + return _SvgNetworkWithUrlFinder(url: url, skipOffstage: skipOffstage); + } + + /// Finds widgets created by [SvgPicture.memory] with the [bytes] argument. + /// ## Sample code + /// ```dart + /// const Uint8List svgBytes = [1, 2, 3, 4]; + /// expect(find.svgMemoryWithBytes(svgBytes), findsOneWidget); + /// ``` + /// This will match [SvgPicture.memory] with the [bytes] [1,2,3,4]. + /// If the `skipOffstage` argument is true (the default), then this skips + /// nodes that are [Offstage] or that are from inactive [Route]s. + Finder svgMemoryWithBytes(Uint8List bytes, {bool skipOffstage = true}) { + return _SvgMemoryWithBytesFinder(bytes: bytes, skipOffstage: skipOffstage); + } + + /// Finds widgets created by [SvgPicture.file] with the [path] argument. + /// ## Sample code + /// ```dart + /// expect(find.svgFileWithPath('test/flutter_logo.svg'), findsOneWidget); + /// ``` + /// This will match [SvgPicture.file] with the [path] 'test/flutter_logo.svg'. + /// If the `skipOffstage` argument is true (the default), then this skips + /// nodes that are [Offstage] or that are from inactive [Route]s. + Finder svgFileWithPath(String path, {bool skipOffstage = true}) { + return _SvgFileWithPathFinder(path: path, skipOffstage: skipOffstage); + } +} + +class _SvgFinder extends MatchFinder { + _SvgFinder(this._svg, {super.skipOffstage}); + + final BytesLoader _svg; + + @override + String get description => "svg: '$_svg'"; + + @override + bool matches(Element candidate) { + return _getBytesLoader( + candidate, + (BytesLoader loader) => loader == _svg, + ); + } +} + +class _SvgAssetWithPathFinder extends MatchFinder { + _SvgAssetWithPathFinder({required String svgPath, super.skipOffstage}) + : _svgPath = svgPath; + final String _svgPath; + + @override + String get description => "Path: '$_svgPath' and created by SvgPicture.asset"; + + @override + bool matches(Element candidate) { + return _getBytesLoader( + candidate, + (SvgAssetLoader loader) => loader.assetName == _svgPath, + ); + } +} + +class _SvgNetworkWithUrlFinder extends MatchFinder { + _SvgNetworkWithUrlFinder({required String url, super.skipOffstage}) + : _url = url; + final String _url; + + @override + String get description => "Url: '$_url' and created by SvgPicture.network"; + + @override + bool matches(Element candidate) { + return _getBytesLoader( + candidate, + (SvgNetworkLoader loader) => loader.url == _url, + ); + } +} + +class _SvgFileWithPathFinder extends MatchFinder { + _SvgFileWithPathFinder({required String path, super.skipOffstage}) + : _path = path; + final String _path; + + @override + String get description => "Path: '$_path' and created by SvgPicture.file"; + + @override + bool matches(Element candidate) { + return _getBytesLoader( + candidate, + (SvgFileLoader loader) => loader.file.path == _path, + ); + } +} + +class _SvgMemoryWithBytesFinder extends MatchFinder { + _SvgMemoryWithBytesFinder({required Uint8List bytes, super.skipOffstage}) + : _bytes = bytes; + final Uint8List _bytes; + + @override + String get description => "Bytes: '$_bytes' and created by SvgPicture.memory"; + + @override + bool matches(Element candidate) { + return _getBytesLoader( + candidate, + (SvgBytesLoader loader) => loader.bytes == _bytes, + ); + } +} + +bool _getBytesLoader( + Element candidate, + bool Function(T loader) matcher, +) { + bool result = false; + final Widget widget = candidate.widget; + if (widget is SvgPicture) { + final BytesLoader bytesLoader = widget.bytesLoader; + if (bytesLoader is T) { + result = matcher(bytesLoader as T); + } + } + return result; +} diff --git a/third_party/packages/flutter_svg_test/pubspec.yaml b/third_party/packages/flutter_svg_test/pubspec.yaml new file mode 100644 index 000000000000..49bb06bc7c3c --- /dev/null +++ b/third_party/packages/flutter_svg_test/pubspec.yaml @@ -0,0 +1,23 @@ +name: flutter_svg_test +description: A testing library which makes it easy to test flutter_svg. Built to be used with the flutter_svg package. +repository: https://github.com/flutter/packages/tree/main/third_party/packages/flutter_svg_test +issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_svg%22 +version: 1.0.2 + +environment: + sdk: ^3.4.0 + flutter: ">=3.22.0" + +dependencies: + flutter: + sdk: flutter + flutter_svg: ^2.0.10 + flutter_test: + sdk: flutter + +dev_dependencies: + http: ^1.0.0 + +topics: + - svg + - vector-graphics diff --git a/third_party/packages/flutter_svg_test/test/flutter_logo.svg b/third_party/packages/flutter_svg_test/test/flutter_logo.svg new file mode 100644 index 000000000000..ec3d9144f352 --- /dev/null +++ b/third_party/packages/flutter_svg_test/test/flutter_logo.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg_test/test/flutter_svg_test_test.dart b/third_party/packages/flutter_svg_test/test/flutter_svg_test_test.dart new file mode 100644 index 000000000000..d00ce7a4d508 --- /dev/null +++ b/third_party/packages/flutter_svg_test/test/flutter_svg_test_test.dart @@ -0,0 +1,123 @@ +import 'dart:convert'; +import 'dart:io'; +import 'dart:typed_data'; + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter_svg_test/flutter_svg_test.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:http/http.dart' as http; + +void main() { + group('finds', () { + group('with bytesLoader', () { + testWidgets('asset svg', (WidgetTester widgetTester) async { + final SvgPicture asset = SvgPicture.asset('test/flutter_logo.svg'); + await widgetTester.pumpWidget( + DefaultAssetBundle( + bundle: _FakeAssetBundle(), + child: asset, + ), + ); + + expect(find.svg(asset.bytesLoader), findsOneWidget); + }); + + testWidgets('network svg', (WidgetTester widgetTester) async { + final http.Client fakeClient = _FakeHttpClient(); + final SvgPicture asset = SvgPicture.network( + 'svg.dart', + httpClient: fakeClient, + ); + await widgetTester.pumpWidget(asset); + + expect(find.svg(asset.bytesLoader), findsOneWidget); + }); + + testWidgets('string svg', (WidgetTester widgetTester) async { + final SvgPicture asset = SvgPicture.string(_svgStr); + await widgetTester.pumpWidget(asset); + + expect(find.svg(asset.bytesLoader), findsOneWidget); + }); + + testWidgets('file svg', (WidgetTester widgetTester) async { + final File file = File('test/flutter_logo.svg'); + final SvgPicture asset = SvgPicture.file(file); + await widgetTester.pumpWidget(asset); + + expect(find.svg(asset.bytesLoader), findsOneWidget); + }); + + testWidgets('memory svg', (WidgetTester widgetTester) async { + final SvgPicture asset = SvgPicture.memory(_svgBytes); + await widgetTester.pumpWidget(asset); + + expect(find.svg(asset.bytesLoader), findsOneWidget); + }); + }); + + testWidgets('asset svg with path', (WidgetTester widgetTester) async { + const String svgPath = 'test/flutter_logo.svg'; + await widgetTester.pumpWidget( + DefaultAssetBundle( + bundle: _FakeAssetBundle(), + child: SvgPicture.asset(svgPath), + ), + ); + + expect(find.svgAssetWithPath(svgPath), findsOneWidget); + }); + + testWidgets('network svg with url', (WidgetTester widgetTester) async { + const String svgUri = 'svg.dart'; + await widgetTester.pumpWidget(SvgPicture.network(svgUri)); + + expect(find.svgNetworkWithUrl(svgUri), findsOneWidget); + }); + + testWidgets('file svg wit path', (WidgetTester widgetTester) async { + const String svgPath = 'test/flutter_logo.svg'; + + await widgetTester.pumpWidget(SvgPicture.file(File(svgPath))); + + expect(find.svgFileWithPath(svgPath), findsOneWidget); + }); + + testWidgets('memory svg with bytes', (WidgetTester widgetTester) async { + final Uint8List svgBytes = _svgBytes; + await widgetTester.pumpWidget(SvgPicture.memory(svgBytes)); + + expect(find.svgMemoryWithBytes(svgBytes), findsOneWidget); + }); + }); +} + +class _FakeAssetBundle extends Fake implements AssetBundle { + @override + Future loadString(String key, {bool cache = true}) async { + return _svgStr; + } + + @override + Future load(String key) async { + return Uint8List.fromList(utf8.encode(_svgStr)).buffer.asByteData(); + } +} + +class _FakeHttpClient extends Fake implements http.Client { + @override + Future get(Uri url, {Map? headers}) async { + return http.Response(_svgStr, 200); + } +} + +// Ignore this because the minimum flutter sdk needs this cast. +// ignore: unnecessary_cast +final Uint8List _svgBytes = utf8.encode(_svgStr) as Uint8List; + +const String _svgStr = ''' + + + +'''; diff --git a/third_party/packages/path_parsing/.gitignore b/third_party/packages/path_parsing/.gitignore new file mode 100644 index 000000000000..43b5f446e6ea --- /dev/null +++ b/third_party/packages/path_parsing/.gitignore @@ -0,0 +1,10 @@ +.DS_Store +.dart_tool/ + +.packages +.pub/ +.idea/ + +build/ + +.flutter-plugins diff --git a/third_party/packages/path_parsing/CHANGELOG.md b/third_party/packages/path_parsing/CHANGELOG.md new file mode 100644 index 000000000000..976dbd012355 --- /dev/null +++ b/third_party/packages/path_parsing/CHANGELOG.md @@ -0,0 +1,56 @@ +## 1.1.0 + +* Deprecates top-level utility functions `blendPoints` and `reflectedPoint` and + some members in `PathSegmentData`. + +## 1.0.3 + +* Updates README.md. + +## 1.0.2 + +* Transfers the package source from https://github.com/dnfield/dart_path_parsing + to https://github.com/flutter/packages. + +## 1.0.1 + +* Fix [bug in arc decomposition](https://github.com/dnfield/flutter_svg/issues/742). +* Minor code cleanup for analysis warnings. + +## 1.0.0 + +* Stable release. + +## 0.2.1 + +* Performance improvements to parsing. + +## 0.2.0 + +* Stable nullsafe release + +## 0.2.0-nullsafety.0 + +* Nullsafety migration. + +## 0.1.4 + +* Fix implementation of `_PathOffset`'s `==` operator. + +## 0.1.3 + +* Fix a bug in decompose cubic curve - avoid trying to call `toInt()` on `double.infinity` +* Bump test dependency. + +## 0.1.2 + +* Fix bug with smooth curve commands +* Add deep testing + +## 0.1.1 + +* Fix link to homepage in pubspec, add example + +## 0.1.0 + +* Initial release, based on the 0.2.4 release of path_drawing diff --git a/third_party/packages/path_parsing/LICENSE b/third_party/packages/path_parsing/LICENSE new file mode 100644 index 000000000000..246fd7b208c9 --- /dev/null +++ b/third_party/packages/path_parsing/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018 Dan Field + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/third_party/packages/path_parsing/METADATA b/third_party/packages/path_parsing/METADATA new file mode 100644 index 000000000000..6b54af3ce828 --- /dev/null +++ b/third_party/packages/path_parsing/METADATA @@ -0,0 +1,15 @@ +name: "path_parsing" +description: + "A pure Dart parsing library for SVG paths." + +third_party { + identifier { + type: "Git" + value: "https://github.com/dnfield/dart_path_parsing/" + primary_source: true + version: "6785396f6c5528c720adb14833b196e529e78998" + } + version: "6785396f6c5528c720adb14833b196e529e78998" + last_upgrade_date { year: 2024 month: 10 day: 24 } + license_type: NOTICE +} diff --git a/third_party/packages/path_parsing/README.md b/third_party/packages/path_parsing/README.md new file mode 100644 index 000000000000..59412881a04e --- /dev/null +++ b/third_party/packages/path_parsing/README.md @@ -0,0 +1,14 @@ +# path_parsing + +Split from the Flutter path drawing library to create a pure Dart parsing +library for SVG paths and code generation (without dependencies on Flutter +runtime). + +## Commemoration + +This package was originally authored by +[Dan Field](https://github.com/dnfield) and has been forked here from +[dnfield/dart_path_parsing](https://github.com/dnfield/dart_path_parsing). +Dan was a member of the Flutter team at Google from 2018 until his death +in 2024. Dan’s impact and contributions to Flutter were immeasurable, and +we honor his memory by continuing to publish and maintain this package. diff --git a/third_party/packages/path_parsing/example/main.dart b/third_party/packages/path_parsing/example/main.dart new file mode 100644 index 000000000000..1d378235a46e --- /dev/null +++ b/third_party/packages/path_parsing/example/main.dart @@ -0,0 +1,51 @@ +// ignore_for_file: avoid_print + +import 'package:path_parsing/path_parsing.dart'; + +/// A [PathProxy] that dumps Flutter `Path` commands to the console. +class PathPrinter extends PathProxy { + @override + void close() { + print('Path.close();'); + } + + @override + void cubicTo( + double x1, + double y1, + double x2, + double y2, + double x3, + double y3, + ) { + print('Path.cubicTo($x1, $y1, $x2, $y2, $x3, $y3);'); + } + + @override + void lineTo(double x, double y) { + print('Path.lineTo($x, $y);'); + } + + @override + void moveTo(double x, double y) { + print('Path.moveTo($x, $y);'); + } +} + +void main() { + const String pathData = + 'M22.1595 3.80852C19.6789 1.35254 16.3807 -4.80966e-07 12.8727 ' + '-4.80966e-07C9.36452 -4.80966e-07 6.06642 1.35254 3.58579 ' + '3.80852C1.77297 5.60333 0.53896 7.8599 0.0171889 10.3343C-0.0738999 ' + '10.7666 0.206109 11.1901 0.64265 11.2803C1.07908 11.3706 1.50711 11.0934 ' + '1.5982 10.661C2.05552 8.49195 3.13775 6.51338 4.72783 4.9391C9.21893 ' + '0.492838 16.5262 0.492728 21.0173 4.9391C25.5082 9.38548 25.5082 16.6202 ' + '21.0173 21.0667C16.5265 25.5132 9.21893 25.5133 4.72805 21.0669C3.17644 ' + '19.5307 2.10538 17.6035 1.63081 15.4937C1.53386 15.0627 1.10252 14.7908 ' + '0.66697 14.887C0.231645 14.983 -0.0427272 15.4103 0.0542205 ' + '15.8413C0.595668 18.2481 1.81686 20.4461 3.5859 22.1976C6.14623 ' + '24.7325 9.50955 26 12.8727 26C16.236 26 19.5991 24.7326 22.1595 ' + '22.1976C27.2802 17.1277 27.2802 8.87841 22.1595 3.80852Z'; + + writeSvgPathDataToPath(pathData, PathPrinter()); +} diff --git a/third_party/packages/path_parsing/example/pubspec.yaml b/third_party/packages/path_parsing/example/pubspec.yaml new file mode 100644 index 000000000000..dd9a6eef8dcb --- /dev/null +++ b/third_party/packages/path_parsing/example/pubspec.yaml @@ -0,0 +1,9 @@ +name: path_parsing_example +publish_to: none + +environment: + sdk: ^3.3.0 + +dependencies: + path_parsing: + path: ../ diff --git a/third_party/packages/path_parsing/lib/path_parsing.dart b/third_party/packages/path_parsing/lib/path_parsing.dart new file mode 100644 index 000000000000..dd0ef045b241 --- /dev/null +++ b/third_party/packages/path_parsing/lib/path_parsing.dart @@ -0,0 +1 @@ +export 'src/path_parsing.dart'; diff --git a/third_party/packages/path_parsing/lib/src/path_parsing.dart b/third_party/packages/path_parsing/lib/src/path_parsing.dart new file mode 100644 index 000000000000..f7cb0f27b76a --- /dev/null +++ b/third_party/packages/path_parsing/lib/src/path_parsing.dart @@ -0,0 +1,788 @@ +// This code has been "translated" largely from the Chromium/blink source +// for SVG path parsing. +// The following files can be cross referenced to the classes and methods here: +// * https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/core/svg/svg_parser_utilities.cc +// * https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/core/svg/svg_parser_utilities.h +// * https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/core/svg/svg_path_string_source.cc +// * https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/core/svg/svg_path_string_source.h +// * https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/core/svg/svg_path_parser.cc +// * https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/core/svg/svg_path_parser.h +// * https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/core/html/parser/html_parser_idioms.h (IsHTMLSpace) +// * https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/core/svg/svg_path_parser_test.cc + +// TODO(stuartmorgan): Remove public_member_api_docs, adding documentation for +// all public members. +// TODO(stuartmorgan): Remove library_private_types_in_public_api and do a +// breaking change to not use _PathOffset in public APIs. +// ignore_for_file: public_member_api_docs, library_private_types_in_public_api + +import 'dart:math' as math show atan2, cos, max, pi, pow, sin, sqrt, tan; + +import 'package:meta/meta.dart'; +import 'package:vector_math/vector_math.dart' show Matrix4, radians; + +import './path_segment_type.dart'; + +/// Parse `svg`, emitting the segment data to `path`. +void writeSvgPathDataToPath(String? svg, PathProxy path) { + if (svg == null || svg == '') { + return; + } + + final SvgPathStringSource parser = SvgPathStringSource(svg); + final SvgPathNormalizer normalizer = SvgPathNormalizer(); + for (final PathSegmentData seg in parser.parseSegments()) { + normalizer.emitSegment(seg, path); + } +} + +/// A receiver for normalized [PathSegmentData]. +abstract class PathProxy { + void moveTo(double x, double y); + void lineTo(double x, double y); + void cubicTo( + double x1, + double y1, + double x2, + double y2, + double x3, + double y3, + ); + void close(); +} + +/// Provides a minimal implementation of a [Point] or [Offset]. +// Takes care of a few things Point doesn't, without requiring Flutter as dependency +@immutable +class _PathOffset { + const _PathOffset(this.dx, this.dy) + : assert(dx != null), // ignore: unnecessary_null_comparison + assert(dy != null); // ignore: unnecessary_null_comparison + + static _PathOffset get zero => const _PathOffset(0.0, 0.0); + final double dx; + final double dy; + + double get direction => math.atan2(dy, dx); + + _PathOffset translate(double translateX, double translateY) => + _PathOffset(dx + translateX, dy + translateY); + + _PathOffset operator +(_PathOffset other) => + _PathOffset(dx + other.dx, dy + other.dy); + _PathOffset operator -(_PathOffset other) => + _PathOffset(dx - other.dx, dy - other.dy); + + _PathOffset operator *(double operand) => + _PathOffset(dx * operand, dy * operand); + + @override + String toString() => 'PathOffset{$dx,$dy}'; + + @override + bool operator ==(Object other) { + return other is _PathOffset && other.dx == dx && other.dy == dy; + } + + // TODO(dnfield): Use a real hashing function - but this should at least be better than the default. + @override + int get hashCode => (((17 * 23) ^ dx.hashCode) * 23) ^ dy.hashCode; +} + +const double _twoPiFloat = math.pi * 2.0; +const double _piOverTwoFloat = math.pi / 2.0; + +class SvgPathStringSource { + SvgPathStringSource(this._string) + : assert(_string != null), // ignore: unnecessary_null_comparison + _previousCommand = SvgPathSegType.unknown, + _idx = 0, + _length = _string.length { + _skipOptionalSvgSpaces(); + } + + final String _string; + + SvgPathSegType _previousCommand; + int _idx; + final int _length; + + bool _isHtmlSpace(int character) { + // Histogram from Apple's page load test combined with some ad hoc browsing + // some other test suites. + // + // 82%: 216330 non-space characters, all > U+0020 + // 11%: 30017 plain space characters, U+0020 + // 5%: 12099 newline characters, U+000A + // 2%: 5346 tab characters, U+0009 + // + // No other characters seen. No U+000C or U+000D, and no other control + // characters. Accordingly, we check for non-spaces first, then space, then + // newline, then tab, then the other characters. + + return character <= AsciiConstants.space && + (character == AsciiConstants.space || + character == AsciiConstants.slashN || + character == AsciiConstants.slashT || + character == AsciiConstants.slashR || + character == AsciiConstants.slashF); + } + + /// Increments _idx to the first non-space character. + /// + /// Returns the code unit of the first non-space, or -1 if at end of string. + int _skipOptionalSvgSpaces() { + while (true) { + if (_idx >= _length) { + return -1; + } + + final int c = _string.codeUnitAt(_idx); + if (!_isHtmlSpace(c)) { + return c; + } + + _idx++; + } + } + + void _skipOptionalSvgSpacesOrDelimiter( + [int delimiter = AsciiConstants.comma]) { + final int c = _skipOptionalSvgSpaces(); + if (c == delimiter) { + _idx++; + _skipOptionalSvgSpaces(); + } + } + + static bool _isNumberStart(int lookahead) { + return (lookahead >= AsciiConstants.number0 && + lookahead <= AsciiConstants.number9) || + lookahead == AsciiConstants.plus || + lookahead == AsciiConstants.minus || + lookahead == AsciiConstants.period; + } + + SvgPathSegType _maybeImplicitCommand( + int lookahead, + SvgPathSegType nextCommand, + ) { + // Check if the current lookahead may start a number - in which case it + // could be the start of an implicit command. The 'close' command does not + // have any parameters though and hence can't have an implicit + // 'continuation'. + if (!_isNumberStart(lookahead) || + _previousCommand == SvgPathSegType.close) { + return nextCommand; + } + // Implicit continuations of moveto command translate to linetos. + if (_previousCommand == SvgPathSegType.moveToAbs) { + return SvgPathSegType.lineToAbs; + } + if (_previousCommand == SvgPathSegType.moveToRel) { + return SvgPathSegType.lineToRel; + } + return _previousCommand; + } + + bool _isValidRange(double x) => + -double.maxFinite <= x && x <= double.maxFinite; + + bool _isValidExponent(double x) => -37 <= x && x <= 38; + + /// Reads a code unit and advances the index. + /// + /// Returns -1 if at end of string. + @pragma('vm:prefer-inline') + int _readCodeUnit() { + if (_idx >= _length) { + return -1; + } + return _string.codeUnitAt(_idx++); + } + + // We use this generic parseNumber function to allow the Path parsing code to + // work at a higher precision internally, without any unnecessary runtime cost + // or code complexity. + double _parseNumber() { + _skipOptionalSvgSpaces(); + + // Read the sign. + int sign = 1; + int c = _readCodeUnit(); + if (c == AsciiConstants.plus) { + c = _readCodeUnit(); + } else if (c == AsciiConstants.minus) { + sign = -1; + c = _readCodeUnit(); + } + + if ((c < AsciiConstants.number0 || c > AsciiConstants.number9) && + c != AsciiConstants.period) { + throw StateError('First character of a number must be one of [0-9+-.].'); + } + + // Read the integer part, build left-to-right. + double integer = 0.0; + while (AsciiConstants.number0 <= c && c <= AsciiConstants.number9) { + integer = integer * 10 + (c - AsciiConstants.number0); + c = _readCodeUnit(); + } + + // Bail out early if this overflows. + if (!_isValidRange(integer)) { + throw StateError('Numeric overflow'); + } + + double decimal = 0.0; + if (c == AsciiConstants.period) { + // read the decimals + c = _readCodeUnit(); + + // There must be a least one digit following the . + if (c < AsciiConstants.number0 || c > AsciiConstants.number9) { + throw StateError('There must be at least one digit following the .'); + } + + double frac = 1.0; + while (AsciiConstants.number0 <= c && c <= AsciiConstants.number9) { + frac *= 0.1; + decimal += (c - AsciiConstants.number0) * frac; + c = _readCodeUnit(); + } + } + + double number = integer + decimal; + number *= sign; + + // read the exponent part + if (_idx < _length && + (c == AsciiConstants.lowerE || c == AsciiConstants.upperE) && + (_string.codeUnitAt(_idx) != AsciiConstants.lowerX && + _string.codeUnitAt(_idx) != AsciiConstants.lowerM)) { + c = _readCodeUnit(); + + // read the sign of the exponent + bool exponentIsNegative = false; + if (c == AsciiConstants.plus) { + c = _readCodeUnit(); + } else if (c == AsciiConstants.minus) { + c = _readCodeUnit(); + exponentIsNegative = true; + } + + // There must be an exponent + if (c < AsciiConstants.number0 || c > AsciiConstants.number9) { + throw StateError('Missing exponent'); + } + + double exponent = 0.0; + while (c >= AsciiConstants.number0 && c <= AsciiConstants.number9) { + exponent *= 10.0; + exponent += c - AsciiConstants.number0; + c = _readCodeUnit(); + } + if (exponentIsNegative) { + exponent = -exponent; + } + // Make sure exponent is valid. + if (!_isValidExponent(exponent)) { + throw StateError('Invalid exponent $exponent'); + } + if (exponent != 0) { + number *= math.pow(10.0, exponent); + } + } + + // Don't return Infinity() or NaN(). + if (!_isValidRange(number)) { + throw StateError('Numeric overflow'); + } + + // At this stage, c contains an unprocessed character, and _idx has + // already been incremented. + + // If c == -1, the input was already at the end of the string, so no + // further processing needs to occur. + if (c != -1) { + --_idx; // Put the unprocessed character back. + + // if (mode & kAllowTrailingWhitespace) + _skipOptionalSvgSpacesOrDelimiter(); + } + return number; + } + + bool _parseArcFlag() { + if (!hasMoreData) { + throw StateError('Expected more data'); + } + final int flagChar = _string.codeUnitAt(_idx++); + _skipOptionalSvgSpacesOrDelimiter(); + + if (flagChar == AsciiConstants.number0) { + return false; + } else if (flagChar == AsciiConstants.number1) { + return true; + } else { + throw StateError('Invalid flag value'); + } + } + + bool get hasMoreData => _idx < _length; + + Iterable parseSegments() sync* { + while (hasMoreData) { + yield parseSegment(); + } + } + + PathSegmentData parseSegment() { + assert(hasMoreData); + final PathSegmentData segment = PathSegmentData(); + final int lookahead = _string.codeUnitAt(_idx); + SvgPathSegType command = AsciiConstants.mapLetterToSegmentType(lookahead); + if (_previousCommand == SvgPathSegType.unknown) { + // First command has to be a moveto. + if (command != SvgPathSegType.moveToRel && + command != SvgPathSegType.moveToAbs) { + throw StateError('Expected to find moveTo command'); + } + // Consume command letter. + _idx++; + } else if (command == SvgPathSegType.unknown) { + // Possibly an implicit command. + assert(_previousCommand != SvgPathSegType.unknown); + command = _maybeImplicitCommand(lookahead, command); + if (command == SvgPathSegType.unknown) { + throw StateError('Expected a path command'); + } + } else { + // Valid explicit command. + _idx++; + } + + segment.command = _previousCommand = command; + + switch (segment.command) { + case SvgPathSegType.cubicToRel: + case SvgPathSegType.cubicToAbs: + segment.point1 = _PathOffset(_parseNumber(), _parseNumber()); + continue cubic_smooth; + case SvgPathSegType.smoothCubicToRel: + cubic_smooth: + case SvgPathSegType.smoothCubicToAbs: + segment.point2 = _PathOffset(_parseNumber(), _parseNumber()); + continue quad_smooth; + case SvgPathSegType.moveToRel: + case SvgPathSegType.moveToAbs: + case SvgPathSegType.lineToRel: + case SvgPathSegType.lineToAbs: + case SvgPathSegType.smoothQuadToRel: + quad_smooth: + case SvgPathSegType.smoothQuadToAbs: + segment.targetPoint = _PathOffset(_parseNumber(), _parseNumber()); + case SvgPathSegType.lineToHorizontalRel: + case SvgPathSegType.lineToHorizontalAbs: + segment.targetPoint = + _PathOffset(_parseNumber(), segment.targetPoint.dy); + case SvgPathSegType.lineToVerticalRel: + case SvgPathSegType.lineToVerticalAbs: + segment.targetPoint = + _PathOffset(segment.targetPoint.dx, _parseNumber()); + case SvgPathSegType.close: + _skipOptionalSvgSpaces(); + case SvgPathSegType.quadToRel: + case SvgPathSegType.quadToAbs: + segment.point1 = _PathOffset(_parseNumber(), _parseNumber()); + segment.targetPoint = _PathOffset(_parseNumber(), _parseNumber()); + case SvgPathSegType.arcToRel: + case SvgPathSegType.arcToAbs: + segment.point1 = _PathOffset(_parseNumber(), _parseNumber()); + segment.arcAngle = _parseNumber(); + segment.arcLarge = _parseArcFlag(); + segment.arcSweep = _parseArcFlag(); + segment.targetPoint = _PathOffset(_parseNumber(), _parseNumber()); + case SvgPathSegType.unknown: + throw StateError('Unknown segment command'); + } + + return segment; + } +} + +@Deprecated('Utility function that should not be public.') +// TODO(kevmoo): Remove this in the next release https://github.com/flutter/flutter/issues/157940 +_PathOffset reflectedPoint( + _PathOffset reflectedIn, _PathOffset pointToReflect) { + return _PathOffset(2 * reflectedIn.dx - pointToReflect.dx, + 2 * reflectedIn.dy - pointToReflect.dy); +} + +const double _kOneOverThree = 1.0 / 3.0; + +/// Blend the points with a ratio (1/3):(2/3). +@Deprecated('Utility function that should not be public.') +// TODO(kevmoo): Remove this in the next release https://github.com/flutter/flutter/issues/157940 +_PathOffset blendPoints(_PathOffset p1, _PathOffset p2) { + return _PathOffset((p1.dx + 2 * p2.dx) * _kOneOverThree, + (p1.dy + 2 * p2.dy) * _kOneOverThree); +} + +bool isCubicCommand(SvgPathSegType command) { + return command == SvgPathSegType.cubicToAbs || + command == SvgPathSegType.cubicToRel || + command == SvgPathSegType.smoothCubicToAbs || + command == SvgPathSegType.smoothCubicToRel; +} + +bool isQuadraticCommand(SvgPathSegType command) { + return command == SvgPathSegType.quadToAbs || + command == SvgPathSegType.quadToRel || + command == SvgPathSegType.smoothQuadToAbs || + command == SvgPathSegType.smoothQuadToRel; +} + +// TODO(dnfield): This can probably be cleaned up a bit. Some of this was designed in such a way to pack data/optimize for C++ +// There are probably better/clearer ways to do it for Dart. +class PathSegmentData { + PathSegmentData() + : command = SvgPathSegType.unknown, + arcSweep = false, + arcLarge = false; + + @Deprecated('Utility member that should not be public.') + // TODO(kevmoo): Remove this in the next release https://github.com/flutter/flutter/issues/157940 + _PathOffset get arcRadii => point1; + + /// Angle in degrees. + double get arcAngle => point2.dx; + + /// In degrees. + set arcAngle(double angle) => point2 = _PathOffset(angle, point2.dy); + + double get r1 => arcRadii.dx; + double get r2 => arcRadii.dy; + + bool get largeArcFlag => arcLarge; + bool get sweepFlag => arcSweep; + + double get x => targetPoint.dx; + double get y => targetPoint.dy; + + double get x1 => point1.dx; + double get y1 => point1.dy; + + double get x2 => point2.dx; + double get y2 => point2.dy; + + SvgPathSegType command; + + @Deprecated('Utility member that should not be public.') + // TODO(kevmoo): Remove this in the next release https://github.com/flutter/flutter/issues/157940 + _PathOffset targetPoint = _PathOffset.zero; + + @Deprecated('Utility member that should not be public.') + // TODO(kevmoo): Remove this in the next release https://github.com/flutter/flutter/issues/157940 + _PathOffset point1 = _PathOffset.zero; + + @Deprecated('Utility member that should not be public.') + // TODO(kevmoo): Remove this in the next release https://github.com/flutter/flutter/issues/157940 + _PathOffset point2 = _PathOffset.zero; + bool arcSweep; + bool arcLarge; + + @override + String toString() { + return 'PathSegmentData{$command $targetPoint $point1 $point2 $arcSweep $arcLarge}'; + } +} + +class SvgPathNormalizer { + _PathOffset _currentPoint = _PathOffset.zero; + _PathOffset _subPathPoint = _PathOffset.zero; + _PathOffset _controlPoint = _PathOffset.zero; + SvgPathSegType _lastCommand = SvgPathSegType.unknown; + + void emitSegment(PathSegmentData segment, PathProxy path) { + final PathSegmentData normSeg = segment; + assert(_currentPoint != null); // ignore: unnecessary_null_comparison + // Convert relative points to absolute points. + switch (segment.command) { + case SvgPathSegType.quadToRel: + normSeg.point1 += _currentPoint; + normSeg.targetPoint += _currentPoint; + case SvgPathSegType.cubicToRel: + normSeg.point1 += _currentPoint; + continue smooth_rel; + smooth_rel: + case SvgPathSegType.smoothCubicToRel: + normSeg.point2 += _currentPoint; + continue arc_rel; + case SvgPathSegType.moveToRel: + case SvgPathSegType.lineToRel: + case SvgPathSegType.lineToHorizontalRel: + case SvgPathSegType.lineToVerticalRel: + case SvgPathSegType.smoothQuadToRel: + arc_rel: + case SvgPathSegType.arcToRel: + normSeg.targetPoint += _currentPoint; + case SvgPathSegType.lineToHorizontalAbs: + normSeg.targetPoint = + _PathOffset(normSeg.targetPoint.dx, _currentPoint.dy); + case SvgPathSegType.lineToVerticalAbs: + normSeg.targetPoint = + _PathOffset(_currentPoint.dx, normSeg.targetPoint.dy); + case SvgPathSegType.close: + // Reset m_currentPoint for the next path. + normSeg.targetPoint = _subPathPoint; + // This switch is intentionally non-exhaustive. + // ignore: no_default_cases + default: + break; + } + + // Update command verb, handle smooth segments and convert quadratic curve + // segments to cubics. + switch (segment.command) { + case SvgPathSegType.moveToRel: + case SvgPathSegType.moveToAbs: + _subPathPoint = normSeg.targetPoint; + // normSeg.command = SvgPathSegType.moveToAbs; + path.moveTo(normSeg.targetPoint.dx, normSeg.targetPoint.dy); + case SvgPathSegType.lineToRel: + case SvgPathSegType.lineToAbs: + case SvgPathSegType.lineToHorizontalRel: + case SvgPathSegType.lineToHorizontalAbs: + case SvgPathSegType.lineToVerticalRel: + case SvgPathSegType.lineToVerticalAbs: + // normSeg.command = SvgPathSegType.lineToAbs; + path.lineTo(normSeg.targetPoint.dx, normSeg.targetPoint.dy); + case SvgPathSegType.close: + // normSeg.command = SvgPathSegType.close; + path.close(); + case SvgPathSegType.smoothCubicToRel: + case SvgPathSegType.smoothCubicToAbs: + if (!isCubicCommand(_lastCommand)) { + normSeg.point1 = _currentPoint; + } else { + normSeg.point1 = reflectedPoint( + _currentPoint, + _controlPoint, + ); + } + continue cubic_abs2; + case SvgPathSegType.cubicToRel: + cubic_abs2: + case SvgPathSegType.cubicToAbs: + _controlPoint = normSeg.point2; + // normSeg.command = SvgPathSegType.cubicToAbs; + path.cubicTo( + normSeg.point1.dx, + normSeg.point1.dy, + normSeg.point2.dx, + normSeg.point2.dy, + normSeg.targetPoint.dx, + normSeg.targetPoint.dy, + ); + case SvgPathSegType.smoothQuadToRel: + case SvgPathSegType.smoothQuadToAbs: + if (!isQuadraticCommand(_lastCommand)) { + normSeg.point1 = _currentPoint; + } else { + normSeg.point1 = reflectedPoint( + _currentPoint, + _controlPoint, + ); + } + continue quad_abs2; + case SvgPathSegType.quadToRel: + quad_abs2: + case SvgPathSegType.quadToAbs: + // Save the unmodified control point. + _controlPoint = normSeg.point1; + normSeg.point1 = blendPoints(_currentPoint, _controlPoint); + normSeg.point2 = blendPoints( + normSeg.targetPoint, + _controlPoint, + ); + // normSeg.command = SvgPathSegType.cubicToAbs; + path.cubicTo( + normSeg.point1.dx, + normSeg.point1.dy, + normSeg.point2.dx, + normSeg.point2.dy, + normSeg.targetPoint.dx, + normSeg.targetPoint.dy, + ); + case SvgPathSegType.arcToRel: + case SvgPathSegType.arcToAbs: + if (!_decomposeArcToCubic(_currentPoint, normSeg, path)) { + // On failure, emit a line segment to the target point. + // normSeg.command = SvgPathSegType.lineToAbs; + path.lineTo(normSeg.targetPoint.dx, normSeg.targetPoint.dy); + // } else { + // // decomposeArcToCubic() has already emitted the normalized + // // segments, so set command to PathSegArcAbs, to skip any further + // // emit. + // // normSeg.command = SvgPathSegType.arcToAbs; + } + // This switch is intentionally non-exhaustive. + // ignore: no_default_cases + default: + throw StateError('Invalid command type in path'); + } + + _currentPoint = normSeg.targetPoint; + + if (!isCubicCommand(segment.command) && + !isQuadraticCommand(segment.command)) { + _controlPoint = _currentPoint; + } + + _lastCommand = segment.command; + } + +// This works by converting the SVG arc to "simple" beziers. +// Partly adapted from Niko's code in kdelibs/kdecore/svgicons. +// See also SVG implementation notes: +// http://www.w3.org/TR/SVG/implnote.html#ArcConversionEndpointToCenter + bool _decomposeArcToCubic( + _PathOffset currentPoint, + PathSegmentData arcSegment, + PathProxy path, + ) { + // If rx = 0 or ry = 0 then this arc is treated as a straight line segment (a + // "lineto") joining the endpoints. + // http://www.w3.org/TR/SVG/implnote.html#ArcOutOfRangeParameters + double rx = arcSegment.arcRadii.dx.abs(); + double ry = arcSegment.arcRadii.dy.abs(); + if (rx == 0 || ry == 0) { + return false; + } + + // If the current point and target point for the arc are identical, it should + // be treated as a zero length path. This ensures continuity in animations. + if (arcSegment.targetPoint == currentPoint) { + return false; + } + + final double angle = radians(arcSegment.arcAngle); + + final _PathOffset midPointDistance = + (currentPoint - arcSegment.targetPoint) * 0.5; + + final Matrix4 pointTransform = Matrix4.identity(); + pointTransform.rotateZ(-angle); + + final _PathOffset transformedMidPoint = _mapPoint( + pointTransform, + _PathOffset( + midPointDistance.dx, + midPointDistance.dy, + ), + ); + + final double squareRx = rx * rx; + final double squareRy = ry * ry; + final double squareX = transformedMidPoint.dx * transformedMidPoint.dx; + final double squareY = transformedMidPoint.dy * transformedMidPoint.dy; + + // Check if the radii are big enough to draw the arc, scale radii if not. + // http://www.w3.org/TR/SVG/implnote.html#ArcCorrectionOutOfRangeRadii + final double radiiScale = squareX / squareRx + squareY / squareRy; + if (radiiScale > 1.0) { + rx *= math.sqrt(radiiScale); + ry *= math.sqrt(radiiScale); + } + pointTransform.setIdentity(); + + pointTransform.scale(1.0 / rx, 1.0 / ry); + pointTransform.rotateZ(-angle); + + _PathOffset point1 = _mapPoint(pointTransform, currentPoint); + _PathOffset point2 = _mapPoint(pointTransform, arcSegment.targetPoint); + _PathOffset delta = point2 - point1; + + final double d = delta.dx * delta.dx + delta.dy * delta.dy; + final double scaleFactorSquared = math.max(1.0 / d - 0.25, 0.0); + double scaleFactor = math.sqrt(scaleFactorSquared); + if (!scaleFactor.isFinite) { + scaleFactor = 0.0; + } + + if (arcSegment.arcSweep == arcSegment.arcLarge) { + scaleFactor = -scaleFactor; + } + + delta = delta * scaleFactor; + final _PathOffset centerPoint = + ((point1 + point2) * 0.5).translate(-delta.dy, delta.dx); + + final double theta1 = (point1 - centerPoint).direction; + final double theta2 = (point2 - centerPoint).direction; + + double thetaArc = theta2 - theta1; + + if (thetaArc < 0.0 && arcSegment.arcSweep) { + thetaArc += _twoPiFloat; + } else if (thetaArc > 0.0 && !arcSegment.arcSweep) { + thetaArc -= _twoPiFloat; + } + + pointTransform.setIdentity(); + pointTransform.rotateZ(angle); + pointTransform.scale(rx, ry); + + // Some results of atan2 on some platform implementations are not exact + // enough. So that we get more cubic curves than expected here. Adding 0.001f + // reduces the count of segments to the correct count. + final int segments = (thetaArc / (_piOverTwoFloat + 0.001)).abs().ceil(); + for (int i = 0; i < segments; ++i) { + final double startTheta = theta1 + i * thetaArc / segments; + final double endTheta = theta1 + (i + 1) * thetaArc / segments; + + final double t = (8.0 / 6.0) * math.tan(0.25 * (endTheta - startTheta)); + if (!t.isFinite) { + return false; + } + final double sinStartTheta = math.sin(startTheta); + final double cosStartTheta = math.cos(startTheta); + final double sinEndTheta = math.sin(endTheta); + final double cosEndTheta = math.cos(endTheta); + + point1 = _PathOffset( + cosStartTheta - t * sinStartTheta, + sinStartTheta + t * cosStartTheta, + ).translate(centerPoint.dx, centerPoint.dy); + final _PathOffset targetPoint = _PathOffset( + cosEndTheta, + sinEndTheta, + ).translate(centerPoint.dx, centerPoint.dy); + point2 = targetPoint.translate(t * sinEndTheta, -t * cosEndTheta); + + final PathSegmentData cubicSegment = PathSegmentData(); + cubicSegment.command = SvgPathSegType.cubicToAbs; + cubicSegment.point1 = _mapPoint(pointTransform, point1); + cubicSegment.point2 = _mapPoint(pointTransform, point2); + cubicSegment.targetPoint = _mapPoint(pointTransform, targetPoint); + + path.cubicTo(cubicSegment.x1, cubicSegment.y1, cubicSegment.x2, + cubicSegment.y2, cubicSegment.x, cubicSegment.y); + //consumer_->EmitSegment(cubicSegment); + } + return true; + } + + _PathOffset _mapPoint(Matrix4 transform, _PathOffset point) { + // a, b, 0.0, 0.0, c, d, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, e, f, 0.0, 1.0 + return _PathOffset( + transform.storage[0] * point.dx + + transform.storage[4] * point.dy + + transform.storage[12], + transform.storage[1] * point.dx + + transform.storage[5] * point.dy + + transform.storage[13], + ); + } +} diff --git a/third_party/packages/path_parsing/lib/src/path_segment_type.dart b/third_party/packages/path_parsing/lib/src/path_segment_type.dart new file mode 100644 index 000000000000..0c2c097cb6d4 --- /dev/null +++ b/third_party/packages/path_parsing/lib/src/path_segment_type.dart @@ -0,0 +1,234 @@ +/// SvgPathSegType enumerates the various path segment commands. +/// +/// [AsciiConstants] houses the ASCII numeric values of these commands +enum SvgPathSegType { + /// Indicates initial state or error + unknown, + + /// Z or z + close, + + /// M + moveToAbs, + + /// m + moveToRel, + + /// L + lineToAbs, + + /// l + lineToRel, + + /// C + cubicToAbs, + + /// c + cubicToRel, + + /// Q + quadToAbs, + + /// q + quadToRel, + + /// A + arcToAbs, + + /// a + arcToRel, + + /// H + lineToHorizontalAbs, + + /// h + lineToHorizontalRel, + + /// V + lineToVerticalAbs, + + /// v + lineToVerticalRel, + + /// S + smoothCubicToAbs, + + /// s + smoothCubicToRel, + + /// T + smoothQuadToAbs, + + /// t + smoothQuadToRel +} + +/// Character constants used internally. Note that this parser does not +/// properly support non-ascii characters in the path, but it does support +/// unicode encoding. +/// +/// Only contains values that are used by the parser (does not contain the full +/// ASCII set). +class AsciiConstants { + const AsciiConstants._(); + + /// Returns the segment type corresponding to the letter constant [lookahead]. + static SvgPathSegType mapLetterToSegmentType(int lookahead) { + return AsciiConstants.letterToSegmentType[lookahead] ?? + SvgPathSegType.unknown; + } + + /// Map to go from ASCII constant to [SvgPathSegType] + static const Map letterToSegmentType = + { + upperZ: SvgPathSegType.close, + lowerZ: SvgPathSegType.close, + upperM: SvgPathSegType.moveToAbs, + lowerM: SvgPathSegType.moveToRel, + upperL: SvgPathSegType.lineToAbs, + lowerL: SvgPathSegType.lineToRel, + upperC: SvgPathSegType.cubicToAbs, + lowerC: SvgPathSegType.cubicToRel, + upperQ: SvgPathSegType.quadToAbs, + lowerQ: SvgPathSegType.quadToRel, + upperA: SvgPathSegType.arcToAbs, + lowerA: SvgPathSegType.arcToRel, + upperH: SvgPathSegType.lineToHorizontalAbs, + lowerH: SvgPathSegType.lineToHorizontalRel, + upperV: SvgPathSegType.lineToVerticalAbs, + lowerV: SvgPathSegType.lineToVerticalRel, + upperS: SvgPathSegType.smoothCubicToAbs, + lowerS: SvgPathSegType.smoothCubicToRel, + upperT: SvgPathSegType.smoothQuadToAbs, + lowerT: SvgPathSegType.smoothQuadToRel, + }; + + /// `\t` (horizontal tab). + static const int slashT = 9; + + /// `\n` (newline). + static const int slashN = 10; + + /// `\f` (form feed). + static const int slashF = 12; + + /// `\r` (carriage return). + static const int slashR = 13; + + /// ` ` (space). + static const int space = 32; + + /// `+` (plus). + static const int plus = 43; + + /// `,` (comma). + static const int comma = 44; + + /// `-` (minus). + static const int minus = 45; + + /// `.` (period). + static const int period = 46; + + /// 0 (the number zero). + static const int number0 = 48; + + /// 1 (the number one). + static const int number1 = 49; + + /// 2 (the number two). + static const int number2 = 50; + + /// 3 (the number three). + static const int number3 = 51; + + /// 4 (the number four). + static const int number4 = 52; + + /// 5 (the number five). + static const int number5 = 53; + + /// 6 (the number six). + static const int number6 = 54; + + /// 7 (the number seven). + static const int number7 = 55; + + /// 8 (the number eight). + static const int number8 = 56; + + /// 9 (the number nine). + static const int number9 = 57; + + /// A + static const int upperA = 65; + + /// C + static const int upperC = 67; + + /// E + static const int upperE = 69; + + /// H + static const int upperH = 72; + + /// L + static const int upperL = 76; + + /// M + static const int upperM = 77; + + /// Q + static const int upperQ = 81; + + /// S + static const int upperS = 83; + + /// T + static const int upperT = 84; + + /// V + static const int upperV = 86; + + /// Z + static const int upperZ = 90; + + /// a + static const int lowerA = 97; + + /// c + static const int lowerC = 99; + + /// e + static const int lowerE = 101; + + /// h + static const int lowerH = 104; + + /// l + static const int lowerL = 108; + + /// m + static const int lowerM = 109; + + /// q + static const int lowerQ = 113; + + /// s + static const int lowerS = 115; + + /// t + static const int lowerT = 116; + + /// v + static const int lowerV = 118; + + /// x + static const int lowerX = 120; + + /// z + static const int lowerZ = 122; + + /// `~` (tilde) + static const int tilde = 126; +} diff --git a/third_party/packages/path_parsing/pubspec.yaml b/third_party/packages/path_parsing/pubspec.yaml new file mode 100644 index 000000000000..ae99c4dffc07 --- /dev/null +++ b/third_party/packages/path_parsing/pubspec.yaml @@ -0,0 +1,21 @@ +name: path_parsing +description: > + A Dart library to help with SVG Path parsing and code generation. Used by Flutter SVG. +repository: https://github.com/flutter/packages/tree/main/third_party/packages/path_parsing +issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+path_parsing%22 +version: 1.1.0 + +environment: + sdk: ^3.3.0 + +dependencies: + meta: ^1.3.0 + vector_math: ^2.1.0 + +dev_dependencies: + path: ^1.8.0 + test: ^1.16.0 + +topics: + - svg + - vector-graphics diff --git a/third_party/packages/path_parsing/test/parse_path_deep_test.dart b/third_party/packages/path_parsing/test/parse_path_deep_test.dart new file mode 100644 index 000000000000..8839f068f3e3 --- /dev/null +++ b/third_party/packages/path_parsing/test/parse_path_deep_test.dart @@ -0,0 +1,71 @@ +import 'package:path_parsing/path_parsing.dart'; +import 'package:test/test.dart'; + +class DeepTestPathProxy extends PathProxy { + DeepTestPathProxy(this.expectedCommands); + + final List expectedCommands; + final List actualCommands = []; + + @override + void close() { + actualCommands.add('close()'); + } + + @override + void cubicTo( + double x1, + double y1, + double x2, + double y2, + double x3, + double y3, + ) { + actualCommands.add( + 'cubicTo(${x1.toStringAsFixed(4)}, ${y1.toStringAsFixed(4)}, ${x2.toStringAsFixed(4)}, ${y2.toStringAsFixed(4)}, ${x3.toStringAsFixed(4)}, ${y3.toStringAsFixed(4)})'); + } + + @override + void lineTo(double x, double y) { + actualCommands + .add('lineTo(${x.toStringAsFixed(4)}, ${y.toStringAsFixed(4)})'); + } + + @override + void moveTo(double x, double y) { + actualCommands + .add('moveTo(${x.toStringAsFixed(4)}, ${y.toStringAsFixed(4)})'); + } + + void validate() { + expect(expectedCommands, orderedEquals(actualCommands)); + } +} + +void main() { + void assertValidPath(String input, List commands) { + final DeepTestPathProxy proxy = DeepTestPathProxy(commands); + writeSvgPathDataToPath(input, proxy); + proxy.validate(); + } + + test('Deep path validation', () { + assertValidPath('M20,30 Q40,5 60,30 T100,30', [ + 'moveTo(20.0000, 30.0000)', + 'cubicTo(33.3333, 13.3333, 46.6667, 13.3333, 60.0000, 30.0000)', + 'cubicTo(73.3333, 46.6667, 86.6667, 46.6667, 100.0000, 30.0000)' + ]); + + assertValidPath( + 'M5.5 5.5a.5 1.5 30 1 1-.866-.5.5 1.5 30 1 1 .866.5z', [ + 'moveTo(5.5000, 5.5000)', + 'cubicTo(5.2319, 5.9667, 4.9001, 6.3513, 4.6307, 6.5077)', + 'cubicTo(4.3612, 6.6640, 4.1953, 6.5683, 4.1960, 6.2567)', + 'cubicTo(4.1967, 5.9451, 4.3638, 5.4655, 4.6340, 5.0000)', + 'cubicTo(4.9021, 4.5333, 5.2339, 4.1487, 5.5033, 3.9923)', + 'cubicTo(5.7728, 3.8360, 5.9387, 3.9317, 5.9380, 4.2433)', + 'cubicTo(5.9373, 4.5549, 5.7702, 5.0345, 5.5000, 5.5000)', + 'close()' + ]); + }); +} diff --git a/third_party/packages/path_parsing/test/parse_path_test.dart b/third_party/packages/path_parsing/test/parse_path_test.dart new file mode 100644 index 000000000000..0f8a5117e2aa --- /dev/null +++ b/third_party/packages/path_parsing/test/parse_path_test.dart @@ -0,0 +1,248 @@ +// Test paths taken from: +// * https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/core/svg/svg_path_parser_test.cc + +import 'package:path_parsing/path_parsing.dart'; +import 'package:path_parsing/src/path_segment_type.dart'; +import 'package:test/test.dart'; + +// TODO(dnfield): a bunch of better tests could be written to track that commands are actually called with expected values/order +// For now we just want to know that something gets emitted and no exceptions are thrown (that's all the legacy tests really did anyway). +class TestPathProxy extends PathProxy { + bool called = false; + @override + void close() { + called = true; + } + + @override + void cubicTo( + double x1, + double y1, + double x2, + double y2, + double x3, + double y3, + ) { + called = true; + } + + @override + void lineTo(double x, double y) { + called = true; + } + + @override + void moveTo(double x, double y) { + called = true; + } +} + +void main() { + void assertValidPath(String input) { + final TestPathProxy proxy = TestPathProxy(); + // these shouldn't throw or assert + writeSvgPathDataToPath(input, proxy); + expect(proxy.called, true); + } + + void assertInvalidPath(String input) { + expect( + () => writeSvgPathDataToPath(input, TestPathProxy()), throwsStateError); + } + + test('Valid Paths', () { + assertValidPath('M1,2'); + assertValidPath('m1,2'); + assertValidPath('M100,200 m3,4'); + assertValidPath('M100,200 L3,4'); + assertValidPath('M100,200 l3,4'); + assertValidPath('M100,200 H3'); + assertValidPath('M100,200 h3'); + assertValidPath('M100,200 V3'); + assertValidPath('M100,200 v3'); + assertValidPath('M100,200 Z'); + assertValidPath('M100,200 z'); + assertValidPath('M100,200 C3,4,5,6,7,8'); + assertValidPath('M100,200 c3,4,5,6,7,8'); + assertValidPath('M100,200 S3,4,5,6'); + assertValidPath('M100,200 s3,4,5,6'); + assertValidPath('M100,200 Q3,4,5,6'); + assertValidPath('M100,200 q3,4,5,6'); + assertValidPath('M100,200 T3,4'); + assertValidPath('M100,200 t3,4'); + assertValidPath('M100,200 A3,4,5,0,0,6,7'); + assertValidPath('M100,200 A3,4,5,1,0,6,7'); + assertValidPath('M100,200 A3,4,5,0,1,6,7'); + assertValidPath('M100,200 A3,4,5,1,1,6,7'); + assertValidPath('M100,200 a3,4,5,0,0,6,7'); + assertValidPath('M100,200 a3,4,5,0,1,6,7'); + assertValidPath('M100,200 a3,4,5,1,0,6,7'); + assertValidPath('M100,200 a3,4,5,1,1,6,7'); + assertValidPath('M100,200 a3,4,5,006,7'); + assertValidPath('M100,200 a3,4,5,016,7'); + assertValidPath('M100,200 a3,4,5,106,7'); + assertValidPath('M100,200 a3,4,5,116,7'); + assertValidPath(''' +M19.0281,19.40466 20.7195,19.40466 20.7195,15.71439 24.11486,15.71439 24.11486,14.36762 20.7195,14.36762 +20.7195,11.68641 24.74134,11.68641 24.74134,10.34618 19.0281,10.34618 z'''); + + assertValidPath( + 'M100,200 a0,4,5,0,0,10,0 a4,0,5,0,0,0,10 a0,0,5,0,0,-10,0 z'); + + assertValidPath('M1,2,3,4'); + assertValidPath('m100,200,3,4'); + + assertValidPath('M 100-200'); + assertValidPath('M 0.6.5'); + + assertValidPath(' M1,2'); + assertValidPath(' M1,2'); + assertValidPath('\tM1,2'); + assertValidPath('\nM1,2'); + assertValidPath('\rM1,2'); + assertValidPath('M1,2 '); + assertValidPath('M1,2\t'); + assertValidPath('M1,2\n'); + assertValidPath('M1,2\r'); + // assertValidPath(''); + // assertValidPath(' '); + assertValidPath('M.1 .2 L.3 .4 .5 .6'); + assertValidPath('M1,1h2,3'); + assertValidPath('M1,1H2,3'); + assertValidPath('M1,1v2,3'); + assertValidPath('M1,1V2,3'); + assertValidPath('M1,1c2,3 4,5 6,7 8,9 10,11 12,13'); + assertValidPath('M1,1C2,3 4,5 6,7 8,9 10,11 12,13'); + assertValidPath('M1,1s2,3 4,5 6,7 8,9'); + assertValidPath('M1,1S2,3 4,5 6,7 8,9'); + assertValidPath('M1,1q2,3 4,5 6,7 8,9'); + assertValidPath('M1,1Q2,3 4,5 6,7 8,9'); + assertValidPath('M1,1t2,3 4,5'); + assertValidPath('M1,1T2,3 4,5'); + assertValidPath('M1,1a2,3,4,0,0,5,6 7,8,9,0,0,10,11'); + assertValidPath('M1,1A2,3,4,0,0,5,6 7,8,9,0,0,10,11'); + assertValidPath( + 'M22.1595 3.80852C19.6789 1.35254 16.3807 -4.80966e-07 12.8727 ' + '-4.80966e-07C9.36452 -4.80966e-07 6.06642 1.35254 3.58579 3.80852C1.77297 5.60333 ' + '0.53896 7.8599 0.0171889 10.3343C-0.0738999 10.7666 0.206109 11.1901 0.64265 ' + '11.2803C1.07908 11.3706 1.50711 11.0934 1.5982 10.661C2.05552 8.49195 3.13775 6.51338 4.72783 ' + '4.9391C9.21893 0.492838 16.5262 0.492728 21.0173 4.9391C25.5082 9.38548 25.5082 16.6202 ' + '21.0173 21.0667C16.5265 25.5132 9.21893 25.5133 4.72805 21.0669C3.17644 19.5307 2.10538 ' + '17.6035 1.63081 15.4937C1.53386 15.0627 1.10252 14.7908 0.66697 14.887C0.231645 14.983 ' + '-0.0427272 15.4103 0.0542205 15.8413C0.595668 18.2481 1.81686 20.4461 3.5859 ' + '22.1976C6.14623 24.7325 9.50955 26 12.8727 26C16.236 26 19.5991 24.7326 22.1595 22.1976C27.2802 ' + '17.1277 27.2802 8.87841 22.1595 3.80852Z'); + assertValidPath( + 'm18 11.8a.41.41 0 0 1 .24.08l.59.43h.05.72a.4.4 0 0 1 .39.28l.22.69a.08.08 0 ' + '0 0 0 0l.58.43a.41.41 0 0 1 .15.45l-.22.68a.09.09 0 0 0 0 .07l.22.68a.4.4 0 0 1 ' + '-.15.46l-.58.42a.1.1 0 0 0 0 0l-.22.68a.41.41 0 0 1 -.38.29h-.79l-.58.43a.41.41 0 ' + '0 1 -.24.08.46.46 0 0 1 -.24-.08l-.58-.43h-.06-.72a.41.41 0 0 1 -.39-.28l-.22-.68a.1.1 ' + '0 0 0 0 0l-.58-.43a.42.42 0 0 1 -.15-.46l.23-.67v-.02l-.29-.68a.43.43 0 0 1 ' + '.15-.46l.58-.42a.1.1 0 0 0 0-.05l.27-.69a.42.42 0 0 1 .39-.28h.78l.58-.43a.43.43 0 ' + '0 1 .25-.09m0-1a1.37 1.37 0 0 0 -.83.27l-.34.25h-.43a1.42 1.42 0 0 0 -1.34 ' + '1l-.13.4-.35.25a1.42 1.42 0 0 0 -.51 1.58l.13.4-.13.4a1.39 1.39 0 0 0 .52 ' + '1.59l.34.25.13.4a1.41 1.41 0 0 0 1.34 1h.43l.34.26a1.44 1.44 0 0 0 .83.27 1.38 1.38 0 0 0 ' + '.83-.28l.35-.24h.43a1.4 1.4 0 0 0 1.33-1l.13-.4.35-.26a1.39 1.39 0 0 0 ' + '.51-1.57l-.13-.4.13-.41a1.4 1.4 0 0 0 -.51-1.56l-.35-.25-.13-.41a1.4 1.4 0 0 0 ' + '-1.34-1h-.42l-.34-.26a1.43 1.43 0 0 0 -.84-.28z'); + }); + + test('Malformed Paths', () { + assertInvalidPath('M100,200 a3,4,5,2,1,6,7'); + assertInvalidPath('M100,200 a3,4,5,1,2,6,7'); + + assertInvalidPath('\vM1,2'); + assertInvalidPath('xM1,2'); + assertInvalidPath('M1,2\v'); + assertInvalidPath('M1,2x'); + assertInvalidPath('M1,2 L40,0#90'); + + assertInvalidPath('x'); + assertInvalidPath('L1,2'); + + assertInvalidPath('M'); + assertInvalidPath('M0'); + + assertInvalidPath('M1,1Z0'); + assertInvalidPath('M1,1z0'); + + assertInvalidPath('M1,1c2,3 4,5 6,7 8'); + assertInvalidPath('M1,1C2,3 4,5 6,7 8'); + assertInvalidPath('M1,1s2,3 4,5 6'); + assertInvalidPath('M1,1S2,3 4,5 6'); + assertInvalidPath('M1,1q2,3 4,5 6'); + assertInvalidPath('M1,1Q2,3 4,5 6'); + assertInvalidPath('M1,1t2,3 4'); + assertInvalidPath('M1,1T2,3 4'); + assertInvalidPath('M1,1a2,3,4,0,0,5,6 7'); + assertInvalidPath('M1,1A2,3,4,0,0,5,6 7'); + }); + + test('Missing commands/numbers/flags', () { + // Missing initial moveto. + assertInvalidPath(' 10 10'); + assertInvalidPath('L 10 10'); + // Invalid command letter. + assertInvalidPath('M 10 10 #'); + assertInvalidPath('M 10 10 E 100 100'); + // Invalid number. + assertInvalidPath('M 10 10 L100 '); + assertInvalidPath('M 10 10 L100 #'); + assertInvalidPath('M 10 10 L100#100'); + assertInvalidPath('M0,0 A#,10 0 0,0 20,20'); + assertInvalidPath('M0,0 A10,# 0 0,0 20,20'); + assertInvalidPath('M0,0 A10,10 # 0,0 20,20'); + assertInvalidPath('M0,0 A10,10 0 0,0 #,20'); + assertInvalidPath('M0,0 A10,10 0 0,0 20,#'); + // Invalid arc-flag. + assertInvalidPath('M0,0 A10,10 0 #,0 20,20'); + assertInvalidPath('M0,0 A10,10 0 0,# 20,20'); + assertInvalidPath('M0,0 A10,10 0 0,2 20,20'); + }); + + test('Check character constants', () { + expect(AsciiConstants.slashT, '\t'.codeUnitAt(0)); + expect(AsciiConstants.slashN, '\n'.codeUnitAt(0)); + expect(AsciiConstants.slashF, '\f'.codeUnitAt(0)); + expect(AsciiConstants.slashR, '\r'.codeUnitAt(0)); + expect(AsciiConstants.space, ' '.codeUnitAt(0)); + expect(AsciiConstants.period, '.'.codeUnitAt(0)); + expect(AsciiConstants.plus, '+'.codeUnitAt(0)); + expect(AsciiConstants.comma, ','.codeUnitAt(0)); + expect(AsciiConstants.minus, '-'.codeUnitAt(0)); + expect(AsciiConstants.number0, '0'.codeUnitAt(0)); + expect(AsciiConstants.number1, '1'.codeUnitAt(0)); + expect(AsciiConstants.number2, '2'.codeUnitAt(0)); + expect(AsciiConstants.number3, '3'.codeUnitAt(0)); + expect(AsciiConstants.number4, '4'.codeUnitAt(0)); + expect(AsciiConstants.number5, '5'.codeUnitAt(0)); + expect(AsciiConstants.number6, '6'.codeUnitAt(0)); + expect(AsciiConstants.number7, '7'.codeUnitAt(0)); + expect(AsciiConstants.number8, '8'.codeUnitAt(0)); + expect(AsciiConstants.number9, '9'.codeUnitAt(0)); + expect(AsciiConstants.upperA, 'A'.codeUnitAt(0)); + expect(AsciiConstants.upperC, 'C'.codeUnitAt(0)); + expect(AsciiConstants.upperE, 'E'.codeUnitAt(0)); + expect(AsciiConstants.upperH, 'H'.codeUnitAt(0)); + expect(AsciiConstants.upperL, 'L'.codeUnitAt(0)); + expect(AsciiConstants.upperM, 'M'.codeUnitAt(0)); + expect(AsciiConstants.upperQ, 'Q'.codeUnitAt(0)); + expect(AsciiConstants.upperS, 'S'.codeUnitAt(0)); + expect(AsciiConstants.upperT, 'T'.codeUnitAt(0)); + expect(AsciiConstants.upperV, 'V'.codeUnitAt(0)); + expect(AsciiConstants.upperZ, 'Z'.codeUnitAt(0)); + expect(AsciiConstants.lowerA, 'a'.codeUnitAt(0)); + expect(AsciiConstants.lowerC, 'c'.codeUnitAt(0)); + expect(AsciiConstants.lowerE, 'e'.codeUnitAt(0)); + expect(AsciiConstants.lowerH, 'h'.codeUnitAt(0)); + expect(AsciiConstants.lowerL, 'l'.codeUnitAt(0)); + expect(AsciiConstants.lowerM, 'm'.codeUnitAt(0)); + expect(AsciiConstants.lowerQ, 'q'.codeUnitAt(0)); + expect(AsciiConstants.lowerS, 's'.codeUnitAt(0)); + expect(AsciiConstants.lowerT, 't'.codeUnitAt(0)); + expect(AsciiConstants.lowerV, 'v'.codeUnitAt(0)); + expect(AsciiConstants.lowerX, 'x'.codeUnitAt(0)); + expect(AsciiConstants.lowerZ, 'z'.codeUnitAt(0)); + expect(AsciiConstants.tilde, '~'.codeUnitAt(0)); + }); +}